Skip to main content

forest/state_migration/nv19/
migration.rs

1// Copyright 2019-2026 ChainSafe Systems
2// SPDX-License-Identifier: Apache-2.0, MIT
3
4use std::sync::Arc;
5
6use crate::networks::{ChainConfig, Height};
7use crate::shim::{
8    address::Address,
9    clock::ChainEpoch,
10    machine::{BuiltinActor, BuiltinActorManifest},
11    state_tree::{StateTree, StateTreeVersion},
12};
13use anyhow::anyhow;
14use cid::Cid;
15use fvm_ipld_blockstore::Blockstore;
16use fvm_ipld_encoding::CborStore as _;
17
18use super::{SystemStateOld, miner, power, system, verifier::Verifier};
19use crate::state_migration::common::{StateMigration, migrators::nil_migrator};
20
21impl<BS: Blockstore> StateMigration<BS> {
22    pub fn add_nv19_migrations(
23        &mut self,
24        store: &Arc<BS>,
25        state: &Cid,
26        new_manifest: &Cid,
27    ) -> anyhow::Result<()> {
28        let state_tree = StateTree::new_from_root(store.clone(), state)?;
29        let system_actor = state_tree
30            .get_actor(&Address::new_id(0))?
31            .ok_or_else(|| anyhow!("system actor not found"))?;
32
33        let system_actor_state = store
34            .get_cbor::<SystemStateOld>(&system_actor.state)?
35            .ok_or_else(|| anyhow!("system actor state not found"))?;
36
37        let current_manifest =
38            BuiltinActorManifest::load_v1_actor_list(store, &system_actor_state.builtin_actors)?;
39
40        let new_manifest = BuiltinActorManifest::load_manifest(store, new_manifest)?;
41
42        for (actor, cid) in current_manifest.builtin_actors() {
43            let new_cid = new_manifest.get(actor)?;
44            self.add_migrator(cid, nil_migrator(new_cid));
45        }
46
47        self.add_migrator(
48            current_manifest.get(BuiltinActor::Miner)?,
49            miner::miner_migrator(new_manifest.get(BuiltinActor::Miner)?),
50        );
51
52        self.add_migrator(
53            current_manifest.get(BuiltinActor::Power)?,
54            power::power_migrator(new_manifest.get(BuiltinActor::Power)?),
55        );
56
57        self.add_migrator(
58            current_manifest.get_system(),
59            system::system_migrator(&new_manifest),
60        );
61
62        Ok(())
63    }
64}
65
66/// Runs the migration for `NV19`. Returns the new state root.
67pub fn run_migration<DB>(
68    chain_config: &ChainConfig,
69    blockstore: &Arc<DB>,
70    state: &Cid,
71    epoch: ChainEpoch,
72) -> anyhow::Result<Cid>
73where
74    DB: Blockstore + Send + Sync,
75{
76    let new_manifest_cid = chain_config
77        .height_infos
78        .get(&Height::Lightning)
79        .ok_or_else(|| anyhow!("no height info for network version NV19"))?
80        .bundle
81        .as_ref()
82        .ok_or_else(|| anyhow!("no bundle info for network version NV19"))?;
83
84    blockstore.get(new_manifest_cid)?.ok_or_else(|| {
85        anyhow!(
86            "manifest for network version NV19 not found in blockstore: {}",
87            new_manifest_cid
88        )
89    })?;
90
91    // Add migration specification verification
92    let verifier = Arc::new(Verifier::default());
93
94    let mut migration = StateMigration::<DB>::new(Some(verifier));
95    migration.add_nv19_migrations(blockstore, state, new_manifest_cid)?;
96
97    let actors_in = StateTree::new_from_root(blockstore.clone(), state)?;
98    let actors_out = StateTree::new(blockstore.clone(), StateTreeVersion::V5)?;
99    let new_state = migration.migrate_state_tree(blockstore, epoch, actors_in, actors_out)?;
100
101    Ok(new_state)
102}