-
Notifications
You must be signed in to change notification settings - Fork 41
Expand file tree
/
Copy pathv3_14_0_state.rs
More file actions
155 lines (147 loc) · 7.42 KB
/
Copy pathv3_14_0_state.rs
File metadata and controls
155 lines (147 loc) · 7.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
//! ## Overview
//! This module stores the previous contract state—the one you want to migrate from.
//! The goal is to describe the data layout _exactly_ as it existed before.
//!
//! ## Guideline
//! In theory, you could copy-paste every struct from the specific commit you're migrating from.
//! However, this approach (a) requires manual effort from a developer and (b) increases the binary size.
//! A better approach: only copy the structures that have changed and import the rest from the existing codebase.
use borsh::{BorshDeserialize, BorshSerialize};
use near_mpc_contract_interface::types::VerifyForeignTransactionRequest;
use near_sdk::{
AccountId, env,
store::{IterableMap, Lazy, LookupMap},
};
use crate::{
SupportedForeignChainsByNode,
config::Config,
foreign_chains_metadata::ForeignChainsMetadata,
node_migrations::NodeMigrations,
primitives::{
ckd::CKDRequest,
signature::{SignatureRequest, YieldIndex},
},
state::ProtocolContractState,
storage_keys::StorageKey,
tee::{tee_state::TeeState, verifier_votes::TeeVerifierVotes},
update::ProposedUpdates,
};
/// Shadow of the `3.14.0` [`Config`]: the deployed layout predates this release's
/// `attestation_storage_fee_millinear`, so migrating `3.14.0` state deserializes the old
/// field set and defaults the new one.
#[derive(Debug, BorshSerialize, BorshDeserialize)]
struct OldConfig {
key_event_timeout_blocks: u64,
tee_upgrade_deadline_duration_seconds: u64,
contract_upgrade_deposit_tera_gas: u64,
sign_call_gas_attachment_requirement_tera_gas: u64,
ckd_call_gas_attachment_requirement_tera_gas: u64,
return_signature_and_clean_state_on_success_call_tera_gas: u64,
return_ck_and_clean_state_on_success_call_tera_gas: u64,
fail_on_timeout_tera_gas: u64,
fail_attestation_submission_tera_gas: u64,
clean_tee_status_tera_gas: u64,
clean_invalid_attestations_tera_gas: u64,
cleanup_orphaned_node_migrations_tera_gas: u64,
remove_non_participant_update_votes_tera_gas: u64,
clean_foreign_chain_data_tera_gas: u64,
remove_non_participant_tee_verifier_votes_tera_gas: u64,
verifier_tera_gas: u64,
resolve_verification_tera_gas: u64,
launcher_hash_unused_ttl_seconds: u64,
}
impl From<OldConfig> for Config {
fn from(old: OldConfig) -> Self {
// Carry the deployed values; the attestation-storage fee is new in this release, so
// it takes its default.
Config {
key_event_timeout_blocks: old.key_event_timeout_blocks,
tee_upgrade_deadline_duration_seconds: old.tee_upgrade_deadline_duration_seconds,
contract_upgrade_deposit_tera_gas: old.contract_upgrade_deposit_tera_gas,
sign_call_gas_attachment_requirement_tera_gas: old
.sign_call_gas_attachment_requirement_tera_gas,
ckd_call_gas_attachment_requirement_tera_gas: old
.ckd_call_gas_attachment_requirement_tera_gas,
return_signature_and_clean_state_on_success_call_tera_gas: old
.return_signature_and_clean_state_on_success_call_tera_gas,
return_ck_and_clean_state_on_success_call_tera_gas: old
.return_ck_and_clean_state_on_success_call_tera_gas,
fail_on_timeout_tera_gas: old.fail_on_timeout_tera_gas,
fail_attestation_submission_tera_gas: old.fail_attestation_submission_tera_gas,
clean_tee_status_tera_gas: old.clean_tee_status_tera_gas,
clean_invalid_attestations_tera_gas: old.clean_invalid_attestations_tera_gas,
cleanup_orphaned_node_migrations_tera_gas: old
.cleanup_orphaned_node_migrations_tera_gas,
remove_non_participant_update_votes_tera_gas: old
.remove_non_participant_update_votes_tera_gas,
clean_foreign_chain_data_tera_gas: old.clean_foreign_chain_data_tera_gas,
remove_non_participant_tee_verifier_votes_tera_gas: old
.remove_non_participant_tee_verifier_votes_tera_gas,
verifier_tera_gas: old.verifier_tera_gas,
resolve_verification_tera_gas: old.resolve_verification_tera_gas,
launcher_hash_unused_ttl_seconds: old.launcher_hash_unused_ttl_seconds,
..Default::default()
}
}
}
/// Keep this module in sync with [`crate::MpcContract`]: the moment a field's borsh
/// layout diverges, shadow the old type here (see this module's history for examples) so
/// state written by the `3.14.0` contract still deserializes during migration.
#[derive(Debug, BorshSerialize, BorshDeserialize)]
pub struct MpcContract {
protocol_state: ProtocolContractState,
pending_signature_requests: LookupMap<SignatureRequest, Vec<YieldIndex>>,
pending_ckd_requests: LookupMap<CKDRequest, Vec<YieldIndex>>,
/// The deployed `3.14.0` keys predate `expected_payload_hash`, so this type parameter
/// does not describe their borsh layout — do not read entries through this map. Not
/// shadowed because `LookupMap`'s own borsh form is just the storage prefix: the type
/// parameters never touch the state deserialization this struct exists for, and the
/// migration discards the map unread.
pending_verify_foreign_tx_requests: LookupMap<VerifyForeignTransactionRequest, Vec<YieldIndex>>,
proposed_updates: ProposedUpdates,
node_foreign_chain_support: SupportedForeignChainsByNode,
config: OldConfig,
tee_state: TeeState,
accept_requests: bool,
node_migrations: NodeMigrations,
metrics: Metrics,
foreign_chains: Lazy<ForeignChainsMetadata>,
tee_verifier_account_id: Option<AccountId>,
tee_verifier_votes: TeeVerifierVotes,
}
impl From<MpcContract> for crate::MpcContract {
fn from(old: MpcContract) -> Self {
if !matches!(old.protocol_state, ProtocolContractState::Running(_)) {
env::panic_str("Contract must be in running state when migrating.");
}
crate::MpcContract {
protocol_state: old.protocol_state,
pending_signature_requests: old.pending_signature_requests,
pending_ckd_requests: old.pending_ckd_requests,
// `VerifyForeignTransactionRequest` gained `expected_payload_hash`, changing the
// borsh key encoding, so entries pending at upgrade time are abandoned; their
// yielded promises time out on chain as if never responded to. The abandoned V2 entries
// are no longer addressable, so their storage staking is never reclaimed
// (bounded by the number of requests in flight at upgrade time).
pending_verify_foreign_tx_requests: LookupMap::new(
crate::storage_keys::StorageKey::PendingVerifyForeignTxRequestsV3,
),
proposed_updates: old.proposed_updates,
node_foreign_chain_support: old.node_foreign_chain_support,
config: old.config.into(),
tee_state: old.tee_state,
accept_requests: old.accept_requests,
node_migrations: old.node_migrations,
foreign_chains: old.foreign_chains,
tee_verifier_account_id: old.tee_verifier_account_id,
tee_verifier_votes: old.tee_verifier_votes,
available_attestation_grants: IterableMap::new(StorageKey::AttestationGrants),
}
}
}
/// Unused signature counters, dropped by the migration.
#[derive(Debug, BorshSerialize, BorshDeserialize)]
struct Metrics {
sign_with_v1_payload_count: u64,
sign_with_v2_payload_count: u64,
}