Skip to main content

forest/state_migration/nv24/
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 `NV24` 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::{SystemStateOld, power, system, verifier::Verifier};
22use crate::state_migration::common::{StateMigration, migrators::nil_migrator};
23
24impl<BS: Blockstore> StateMigration<BS> {
25    pub fn add_nv24_migrations(
26        &mut self,
27        store: &Arc<BS>,
28        state: &Cid,
29        new_manifest: &BuiltinActorManifest,
30        chain_config: &ChainConfig,
31    ) -> anyhow::Result<()> {
32        let state_tree = StateTree::new_from_root(store.clone(), state)?;
33        let system_actor = state_tree.get_required_actor(&Address::SYSTEM_ACTOR)?;
34        let system_actor_state = store.get_cbor_required::<SystemStateOld>(&system_actor.state)?;
35
36        let current_manifest_data = system_actor_state.builtin_actors;
37
38        let current_manifest =
39            BuiltinActorManifest::load_v1_actor_list(store, &current_manifest_data)?;
40
41        for (name, code) in current_manifest.builtin_actors() {
42            let new_code = new_manifest.get(name)?;
43            self.add_migrator(code, nil_migrator(new_code))
44        }
45
46        self.add_migrator(
47            current_manifest.get_system(),
48            system::system_migrator(new_manifest),
49        );
50
51        let tuktuk_epoch = chain_config
52            .height_infos
53            .get(&Height::TukTuk)
54            .context("no height info for network version NV24")?
55            .epoch;
56        self.add_migrator(
57            current_manifest.get(BuiltinActor::Power)?,
58            power::power_migrator(
59                new_manifest.get(BuiltinActor::Power)?,
60                tuktuk_epoch,
61                chain_config.fip0081_ramp_duration_epochs,
62            ),
63        );
64
65        Ok(())
66    }
67}
68
69/// Runs the migration for `NV24`. Returns the new state root.
70#[allow(dead_code)]
71pub fn run_migration<DB>(
72    chain_config: &ChainConfig,
73    blockstore: &Arc<DB>,
74    state: &Cid,
75    epoch: ChainEpoch,
76) -> anyhow::Result<Cid>
77where
78    DB: Blockstore + Send + Sync,
79{
80    let new_manifest_cid = chain_config
81        .height_infos
82        .get(&Height::TukTuk)
83        .context("no height info for network version NV24")?
84        .bundle
85        .as_ref()
86        .context("no bundle for network version NV24")?;
87
88    blockstore.get(new_manifest_cid)?.context(format!(
89        "manifest for network version NV24 not found in blockstore: {new_manifest_cid}"
90    ))?;
91
92    // Add migration specification verification
93    let verifier = Arc::new(Verifier::default());
94
95    let new_manifest = BuiltinActorManifest::load_manifest(blockstore, new_manifest_cid)?;
96    let mut migration = StateMigration::<DB>::new(Some(verifier));
97    migration.add_nv24_migrations(blockstore, state, &new_manifest, chain_config)?;
98
99    let actors_in = StateTree::new_from_root(blockstore.clone(), state)?;
100    let actors_out = StateTree::new(blockstore.clone(), StateTreeVersion::V5)?;
101    let new_state = migration.migrate_state_tree(blockstore, epoch, actors_in, actors_out)?;
102
103    Ok(new_state)
104}