forest/state_migration/nv22fix/
migration.rs1use super::{SystemStateOld, system, verifier::Verifier};
8use crate::networks::{ChainConfig, Height, NetworkChain};
9use crate::prelude::*;
10use crate::shim::{
11 address::Address,
12 clock::ChainEpoch,
13 machine::{BuiltinActor, BuiltinActorManifest},
14 state_tree::{StateTree, StateTreeVersion},
15};
16use crate::state_migration::common::PostMigrationCheck;
17use crate::state_migration::common::{StateMigration, migrators::nil_migrator};
18use crate::utils::db::CborStoreExt as _;
19use anyhow::bail;
20
21impl<BS: Blockstore + ShallowClone> StateMigration<BS> {
22 pub fn add_nv22fix_migrations(
23 &mut self,
24 store: &BS,
25 state: &Cid,
26 new_manifest: &BuiltinActorManifest,
27 ) -> anyhow::Result<()> {
28 let state_tree = StateTree::new_from_root(store, state)?;
29 let system_actor = state_tree.get_required_actor(&Address::new_id(0))?;
30
31 let system_actor_state = store.get_cbor_required::<SystemStateOld>(&system_actor.state)?;
32
33 let current_manifest_data = system_actor_state.builtin_actors;
34
35 let current_manifest =
36 BuiltinActorManifest::load_v1_actor_list(store, ¤t_manifest_data)?;
37
38 for (name, code) in current_manifest.builtin_actors() {
39 let new_code = new_manifest.get(name)?;
40 self.add_migrator(code, nil_migrator(new_code))
41 }
42
43 self.add_migrator(
44 current_manifest.get_system(),
45 system::system_migrator(new_manifest),
46 );
47
48 Ok(())
49 }
50}
51
52struct PostMigrationVerifier {
53 state_pre: Cid,
54}
55
56impl<BS: Blockstore + ShallowClone> PostMigrationCheck<BS> for PostMigrationVerifier {
57 fn post_migrate_check(&self, store: &BS, actors_out: &StateTree<BS>) -> anyhow::Result<()> {
58 let actors_in = StateTree::new_from_root(store, &self.state_pre)?;
59 let system_actor = actors_in.get_required_actor(&Address::new_id(0))?;
60
61 let system_actor_state = store.get_cbor_required::<SystemStateOld>(&system_actor.state)?;
62
63 let current_manifest_data = system_actor_state.builtin_actors;
64
65 let current_manifest =
66 BuiltinActorManifest::load_v1_actor_list(store, ¤t_manifest_data)?;
67
68 actors_in.for_each(|address, actor_in| {
69 let actor_out = actors_out.get_required_actor(&address)?;
70
71 if actor_in.sequence != actor_out.sequence {
72 bail!(
73 "actor {address} sequence mismatch: pre-migration: {}, post-migration: {}",
74 actor_in.sequence,
75 actor_out.sequence
76 );
77 }
78
79 if actor_in.balance != actor_out.balance {
80 bail!(
81 "actor {address} balance mismatch: pre-migration: {}, post-migration: {}",
82 actor_in.balance,
83 actor_out.balance
84 );
85 }
86
87 if actor_in.state != actor_out.state && actor_in.code != current_manifest.get_system() {
88 bail!(
89 "actor {address} state mismatch: pre-migration: {}, post-migration: {}",
90 actor_in.state,
91 actor_out.state
92 );
93 }
94
95 if actor_in.code != current_manifest.get(BuiltinActor::VerifiedRegistry)?
96 && actor_in.code != actor_out.code
97 {
98 bail!(
99 "actor {address} code mismatch: pre-migration: {}, post-migration: {}",
100 actor_in.code,
101 actor_out.code
102 );
103 }
104
105 Ok(())
106 })?;
107
108 Ok(())
109 }
110}
111
112pub fn run_migration<DB>(
114 chain_config: &ChainConfig,
115 blockstore: &DB,
116 state: &Cid,
117 epoch: ChainEpoch,
118) -> anyhow::Result<Cid>
119where
120 DB: Blockstore + ShallowClone + Send + Sync,
121{
122 assert_eq!(
123 chain_config.network,
124 NetworkChain::Calibnet,
125 "NV22fix only supported on Calibnet"
126 );
127
128 let new_manifest_cid = chain_config
129 .height_infos
130 .get(&Height::DragonFix)
131 .context("no height info for network version NV22")?
132 .bundle
133 .as_ref()
134 .context("no bundle for network version NV22")?;
135
136 blockstore.get(new_manifest_cid)?.context(format!(
137 "manifest for network version NV22fix not found in blockstore: {new_manifest_cid}"
138 ))?;
139
140 let verifier = Arc::new(Verifier::default());
142
143 let new_manifest = BuiltinActorManifest::load_manifest(blockstore, new_manifest_cid)?;
144 let mut migration = StateMigration::<DB>::new(Some(verifier));
145 migration.add_nv22fix_migrations(blockstore, state, &new_manifest)?;
146 migration.add_post_migration_check(Arc::new(PostMigrationVerifier { state_pre: *state }));
147
148 let actors_in = StateTree::new_from_root(blockstore, state)?;
149 let actors_out = StateTree::new(blockstore, StateTreeVersion::V5)?;
150 let new_state = migration.migrate_state_tree(blockstore, epoch, actors_in, actors_out)?;
151
152 Ok(new_state)
153}