Skip to main content

forest/state_migration/nv25/
migration.rs

1// Copyright 2019-2026 ChainSafe Systems
2// SPDX-License-Identifier: Apache-2.0, MIT
3//
4//! This module contains the migration logic for the `NV25` upgrade.
5
6use std::sync::Arc;
7
8use crate::networks::{ChainConfig, Height};
9use crate::shim::{
10    address::Address,
11    clock::ChainEpoch,
12    machine::{BuiltinActor, BuiltinActorManifest},
13    state_tree::{StateTree, StateTreeVersion},
14};
15use crate::utils::db::CborStoreExt as _;
16use anyhow::Context as _;
17use cid::Cid;
18
19use fvm_ipld_blockstore::Blockstore;
20
21use super::evm::EvmMigrator;
22use super::miner::MinerMigrator;
23use super::{SystemStateOld, system, verifier::Verifier};
24use crate::state_migration::common::{StateMigration, migrators::nil_migrator};
25
26impl<BS: Blockstore> StateMigration<BS> {
27    pub fn add_nv25_migrations(
28        &mut self,
29        store: &Arc<BS>,
30        state: &Cid,
31        new_manifest: &BuiltinActorManifest,
32    ) -> anyhow::Result<()> {
33        let state_tree = StateTree::new_from_root(store.clone(), state)?;
34        let system_actor = state_tree.get_required_actor(&Address::SYSTEM_ACTOR)?;
35        let system_actor_state = store.get_cbor_required::<SystemStateOld>(&system_actor.state)?;
36
37        let current_manifest_data = system_actor_state.builtin_actors;
38
39        let current_manifest =
40            BuiltinActorManifest::load_v1_actor_list(store, &current_manifest_data)?;
41
42        for (name, code) in current_manifest.builtin_actors() {
43            let new_code = new_manifest.get(name)?;
44            self.add_migrator(code, nil_migrator(new_code))
45        }
46
47        self.add_migrator(
48            current_manifest.get_system(),
49            system::system_migrator(new_manifest),
50        );
51        self.add_migrator(
52            current_manifest.get(BuiltinActor::EVM)?,
53            Arc::new(EvmMigrator {
54                new_code_cid: new_manifest.get(BuiltinActor::EVM)?,
55            }),
56        );
57        self.add_migrator(
58            current_manifest.get(BuiltinActor::Miner)?,
59            Arc::new(MinerMigrator {
60                new_code_cid: new_manifest.get(BuiltinActor::Miner)?,
61            }),
62        );
63
64        Ok(())
65    }
66}
67
68/// Runs the migration for `NV25`. Returns the new state root.
69pub fn run_migration<DB>(
70    chain_config: &ChainConfig,
71    blockstore: &Arc<DB>,
72    state: &Cid,
73    epoch: ChainEpoch,
74) -> anyhow::Result<Cid>
75where
76    DB: Blockstore + Send + Sync,
77{
78    let new_manifest_cid = chain_config
79        .height_infos
80        .get(&Height::Teep)
81        .context("no height info for network version NV25")?
82        .bundle
83        .as_ref()
84        .context("no bundle for network version NV25")?;
85
86    blockstore.get(new_manifest_cid)?.context(format!(
87        "manifest for network version NV25 not found in blockstore: {new_manifest_cid}"
88    ))?;
89
90    // Add migration specification verification
91    let verifier = Arc::new(Verifier::default());
92
93    let new_manifest = BuiltinActorManifest::load_manifest(blockstore, new_manifest_cid)?;
94    let mut migration = StateMigration::<DB>::new(Some(verifier));
95    migration.add_nv25_migrations(blockstore, state, &new_manifest)?;
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}