Skip to content

Commit

Permalink
network-agnostic state migration
Browse files Browse the repository at this point in the history
  • Loading branch information
LesnyRumcajs committed Apr 6, 2023
1 parent 1ebdfd1 commit cc7716b
Show file tree
Hide file tree
Showing 8 changed files with 137 additions and 179 deletions.
2 changes: 1 addition & 1 deletion utils/genesis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ where
tokio::spawn(async move { store.buffered_write(rx, BUFFER_CAPCITY_BYTES).await });
let mut car_reader = CarReader::new(reader).await?;
while let Some(block) = car_reader.next_block().await? {
println!("Importing block: {}", block.cid);
debug!("Importing block: {}", block.cid);
tx.send_async((block.cid, block.data)).await?;
}
drop(tx);
Expand Down
2 changes: 1 addition & 1 deletion vm/state_migration/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ use forest_shim::{
};
use fvm_ipld_blockstore::Blockstore;
use fvm_shared::{clock::ChainEpoch, econ::TokenAmount};
pub use nv18::migration::run_migration as run_nv18_migration;
use parking_lot::Mutex;

mod nv18;
pub use nv18::migration::run_migration as run_nv18_migration;

pub type Migrator<BS> = Arc<dyn ActorMigration<BS> + Send + Sync>;

Expand Down
26 changes: 22 additions & 4 deletions vm/state_migration/src/nv18/eam.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,28 @@
// Copyright 2019-2023 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

use forest_shim::state_tree::ActorState;
use forest_shim::{
address::Address,
machine::Manifest,
state_tree::{ActorState, StateTree},
};
use forest_utils::db::BlockstoreExt;
use fvm_ipld_blockstore::Blockstore;

use super::calibnet;
pub fn create_eam_actor<BS: Blockstore + Clone + Send + Sync>(
store: &BS,
actors_out: &mut StateTree<BS>,
) -> anyhow::Result<()> {
let sys_actor = actors_out
.get_actor(&Address::SYSTEM_ACTOR)?
.ok_or_else(|| anyhow::anyhow!("Couldn't get sys actor state"))?;
let sys_state: fil_actor_system_v10::State = store
.get_obj(&sys_actor.state)?
.ok_or_else(|| anyhow::anyhow!("Couldn't get statev10"))?;

pub fn create_eam_actor() -> ActorState {
ActorState::new_empty(*calibnet::v10::EAM, None)
let manifest = Manifest::load(&store, &sys_state.builtin_actors, 1)?;

let eam_actor = ActorState::new_empty(*manifest.get_eam_code(), None);
actors_out.set_actor(&Address::ETHEREUM_ACCOUNT_MANAGER_ACTOR, eam_actor)?;
Ok(())
}
51 changes: 51 additions & 0 deletions vm/state_migration/src/nv18/eth_account.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright 2019-2023 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

use anyhow::anyhow;
use forest_shim::{
address::Address,
machine::Manifest,
state_tree::{ActorState, StateTree},
};
use forest_utils::db::BlockstoreExt;
use fvm_ipld_blockstore::Blockstore;

pub fn create_eth_account_actor<BS: Blockstore + Clone + Send + Sync>(
store: &BS,
actors_out: &mut StateTree<BS>,
) -> anyhow::Result<()> {
let init_actor = actors_out
.get_actor(&Address::INIT_ACTOR)?
.ok_or_else(|| anyhow::anyhow!("Couldn't get init actor state"))?;
let init_state: fil_actor_init_v10::State = store
.get_obj(&init_actor.state)?
.ok_or_else(|| anyhow::anyhow!("Couldn't get statev10"))?;

let eth_zero_addr =
Address::new_delegated(Address::ETHEREUM_ACCOUNT_MANAGER_ACTOR.id()?, &[0; 20])?;
let eth_zero_addr_id = init_state
.resolve_address(&store, &eth_zero_addr.into())?
.ok_or_else(|| anyhow!("failed to get eth zero actor"))?;

let system_actor = actors_out
.get_actor(&Address::new_id(0))?
.ok_or_else(|| anyhow!("failed to get system actor"))?;

let system_actor_state = store
.get_obj::<fil_actor_system_v10::State>(&system_actor.state)?
.ok_or_else(|| anyhow!("failed to get system actor state"))?;

let manifest_data = system_actor_state.builtin_actors;
let new_manifest = Manifest::load(&store, &manifest_data, 1)?;

let eth_account_actor = ActorState::new(
*new_manifest.get_ethaccount_code(),
fil_actors_runtime_v10::runtime::EMPTY_ARR_CID,
Default::default(),
0,
Some(eth_zero_addr),
);

actors_out.set_actor(&eth_zero_addr_id.into(), eth_account_actor)?;
Ok(())
}
47 changes: 3 additions & 44 deletions vm/state_migration/src/nv18/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,13 @@ use anyhow::anyhow;
use cid::Cid;
use forest_networks::ChainConfig;
use forest_shim::{
address::Address,
clock::ChainEpoch,
state_tree::{ActorState, StateTree, StateTreeVersion},
state_tree::{StateTree, StateTreeVersion},
version::NetworkVersion,
};
use forest_utils::db::BlockstoreExt;
use fvm_ipld_blockstore::Blockstore;
use fvm_ipld_encoding::CborStore;

use super::{calibnet, eam::create_eam_actor, verifier::Verifier};
use super::{eam::create_eam_actor, eth_account::create_eth_account_actor, verifier::Verifier};
use crate::{PostMigrationAction, StateMigration};

pub fn run_migration<DB>(
Expand All @@ -28,57 +25,19 @@ pub fn run_migration<DB>(
where
DB: 'static + Blockstore + Clone + Send + Sync,
{
let state_tree = StateTree::new_from_root(blockstore, state)?;

let new_manifest_cid = chain_config
.manifests
.get(&NetworkVersion::V18)
.ok_or_else(|| anyhow!("no manifest for network version NV18"))?;

let (_, new_manifest_data): (u32, Cid) = state_tree
.store()
.get_cbor(new_manifest_cid)?
.ok_or_else(|| anyhow!("could not find old state migration manifest"))?;

let verifier = Arc::new(Verifier::default());
let create_eam_actor = |_store: &DB, actors_out: &mut StateTree<DB>| {
let eam_actor = create_eam_actor();
actors_out.set_actor(&Address::ETHEREUM_ACCOUNT_MANAGER_ACTOR, eam_actor)?;
Ok(())
};
let create_eth_account_actor = |store: &DB, actors_out: &mut StateTree<DB>| {
let init_actor = actors_out
.get_actor(&Address::INIT_ACTOR)?
.ok_or_else(|| anyhow::anyhow!("Couldn't get init actor state"))?;
let init_state: fil_actor_init_v10::State = store
.get_obj(&init_actor.state)?
.ok_or_else(|| anyhow::anyhow!("Couldn't get statev10"))?;

let eth_zero_addr =
Address::new_delegated(Address::ETHEREUM_ACCOUNT_MANAGER_ACTOR.id()?, &[0; 20])?;
let eth_zero_addr_id = init_state
.resolve_address(&store, &eth_zero_addr.into())?
.ok_or_else(|| anyhow!("failed to get eth zero actor"))?;

let eth_account_actor = ActorState::new(
*calibnet::v10::ETH_ACCOUNT,
fil_actors_runtime_v10::runtime::EMPTY_ARR_CID,
Default::default(),
0,
Some(eth_zero_addr),
);

actors_out.set_actor(&eth_zero_addr_id.into(), eth_account_actor)?;
Ok(())
};
let post_migration_actions = [create_eam_actor, create_eth_account_actor]
.into_iter()
.map(|action| Arc::new(action) as PostMigrationAction<DB>)
.collect();

let mut migration = StateMigration::<DB>::new(Some(verifier), post_migration_actions);
migration.add_nil_migrations();
migration.add_nv_18_migrations();
migration.add_nv18_migrations(blockstore.clone(), state, new_manifest_cid)?;

let actors_in = StateTree::new_from_root(blockstore.clone(), state)?;
let actors_out = StateTree::new(blockstore.clone(), StateTreeVersion::V5)?;
Expand Down
158 changes: 42 additions & 116 deletions vm/state_migration/src/nv18/mod.rs
Original file line number Diff line number Diff line change
@@ -1,139 +1,65 @@
// Copyright 2019-2023 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT
pub mod eam;
pub mod eth_account;
mod init;
pub mod migration;
mod system;
pub mod verifier;

use anyhow::{anyhow, bail};
use cid::Cid;
use fil_actor_system_v9::State as SystemStateV9;
use forest_shim::{
address::Address,
machine::{Manifest, ManifestV2},
state_tree::StateTree,
};
use forest_utils::db::BlockstoreExt;
use fvm_ipld_blockstore::Blockstore;
use fvm_ipld_encoding::CborStore;

use crate::{nil_migrator, StateMigration};

macro_rules! make_actors {
($($name:ident, $value: expr),+) => {
use cid::Cid;
use lazy_static::lazy_static;
lazy_static! {
$(
pub static ref $name: Cid = Cid::try_from($value).unwrap();
)+
}
};
}
impl<BS: Blockstore + Clone + Send + Sync> StateMigration<BS> {
pub fn add_nv18_migrations(
&mut self,
store: BS,
state: &Cid,
new_manifest: &Cid,
) -> anyhow::Result<()> {
let state_tree = StateTree::new_from_root(store.clone(), state)?;
let system_actor = state_tree
.get_actor(&Address::new_id(0))?
.ok_or_else(|| anyhow!("system actor not found"))?;

pub mod calibnet {
pub mod v9 {
make_actors!(
ACCOUNT,
"bafk2bzaceavfgpiw6whqigmskk74z4blm22nwjfnzxb4unlqz2e4wg3c5ujpw",
CRON,
"bafk2bzaceb7hxmudhvkizszbmmf2ur2qfnfxfkok3xmbrlifylx6huw4bb3s4",
DATACAP,
"bafk2bzaceanmwcfjfj65xy275rrfqqgoblnuqirdg6zwhc6qhbfhpphomvceu",
INIT,
"bafk2bzaceczqxpivlxifdo5ohr2rx5ny4uyvssm6tkf7am357xm47x472yxu2",
MULTISIG,
"bafk2bzacec6gmi7ucukr3bk67akaxwngohw3lsg3obvdazhmfhdzflkszk3tg",
PAYMENT_CHANNEL,
"bafk2bzacec4kg3bfjtssvv2b4wizlbdk3pdtrg5aknzgeb3a6rmksgurpynca",
REWARD,
"bafk2bzacebpptqhcw6mcwdj576dgpryapdd2zfexxvqzlh3aoc24mabwgmcss",
STORAGE_MARKET,
"bafk2bzacebkfcnc27d3agm2bhzzbvvtbqahmvy2b2nf5xyj4aoxehow3bules",
STORAGE_MINER,
"bafk2bzacebz4na3nq4gmumghegtkaofrv4nffiihd7sxntrryfneusqkuqodm",
STORAGE_POWER,
"bafk2bzaceburxajojmywawjudovqvigmos4dlu4ifdikogumhso2ca2ccaleo",
SYSTEM,
"bafk2bzaceaue3nzucbom3tcclgyaahy3iwvbqejsxrohiquakvvsjgbw3shac",
VERIFIED_REGISTRY,
"bafk2bzacebh7dj6j7yi5vadh7lgqjtq42qi2uq4n6zy2g5vjeathacwn2tscu"
);
}
let system_actor_state = store
.get_obj::<SystemStateV9>(&system_actor.state)?
.ok_or_else(|| anyhow!("system actor state not found"))?;
let current_manifest_data = system_actor_state.builtin_actors;
let current_manifest = ManifestV2::load(&store, &current_manifest_data, 1)?;

pub mod v10 {
make_actors!(
ACCOUNT,
"bafk2bzacebhfuz3sv7duvk653544xsxhdn4lsmy7ol7k6gdgancyctvmd7lnq",
CRON,
"bafk2bzacecw2yjb6ysieffa7lk7xd32b3n4ssowvafolt7eq52lp6lk4lkhji",
DATACAP,
"bafk2bzaceaot6tv6p4cat3cg5fknq22htosw3p5rwyijmdsraatwqyc4qyero",
EAM,
"bafk2bzacec5untyj6cefdsfm47wckozw6wt6svqqh5dzh63nu4f6dvf26fkco",
ETH_ACCOUNT,
"bafk2bzacebiyrhz32xwxi6xql67aaq5nrzeelzas472kuwjqmdmgwotpkj35e",
EVM,
"bafk2bzaceblpgzid4qjfavuiht6uwvq2lznshklk2qmf5akm3dzx2fczdqdxc",
INIT,
"bafk2bzacedhxbcglnonzruxf2jpczara73eh735wf2kznatx2u4gsuhgqwffq",
MULTISIG,
"bafk2bzacebv5gdlte2pyovmz6s37me6x2rixaa6a33w6lgqdohmycl23snvwm",
PAYMENT_CHANNEL,
"bafk2bzacea7ngq44gedftjlar3j3ql3dmd7e7xkkb6squgxinfncybfmppmlc",
PLACEHOLDER,
"bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro",
REWARD,
"bafk2bzacea3yo22x4dsh4axioshrdp42eoeugef3tqtmtwz5untyvth7uc73o",
STORAGE_MARKET,
"bafk2bzacecclsfboql3iraf3e66pzuh3h7qp3vgmfurqz26qh5g5nrexjgknc",
STORAGE_MINER,
"bafk2bzacedu4chbl36rilas45py4vhqtuj6o7aa5stlvnwef3kshgwcsmha6y",
STORAGE_POWER,
"bafk2bzacedu3c67spbf2dmwo77ymkjel6i2o5gpzyksgu2iuwu2xvcnxgfdjg",
SYSTEM,
"bafk2bzacea4mtukm5zazygkdbgdf26cpnwwif5n2no7s6tknpxlwy6fpq3mug",
VERIFIED_REGISTRY,
"bafk2bzacec67wuchq64k7kgrujguukjvdlsl24pgighqdx5vgjhyk6bycrwnc",
_MANIFEST,
"bafy2bzaced25ta3j6ygs34roprilbtb3f6mxifyfnm7z7ndquaruxzdq3y7lo"
);
}
}
let (version, new_manifest_data): (u32, Cid) = store
.get_cbor(new_manifest)?
.ok_or_else(|| anyhow!("new manifest not found"))?;
let new_manifest = Manifest::load(&store, &new_manifest_data, version)?;

impl<BS: Blockstore + Clone + Send + Sync> StateMigration<BS> {
// Initializes the migrations map with Nil migrators for network version 18
// upgrade
pub fn add_nil_migrations(&mut self) {
let nil_migrations = [
(*calibnet::v9::ACCOUNT, *calibnet::v10::ACCOUNT),
(*calibnet::v9::CRON, *calibnet::v10::CRON),
(*calibnet::v9::DATACAP, *calibnet::v10::DATACAP),
(*calibnet::v9::MULTISIG, *calibnet::v10::MULTISIG),
(
*calibnet::v9::PAYMENT_CHANNEL,
*calibnet::v10::PAYMENT_CHANNEL,
),
(*calibnet::v9::REWARD, *calibnet::v10::REWARD),
(
*calibnet::v9::STORAGE_MARKET,
*calibnet::v10::STORAGE_MARKET,
),
(*calibnet::v9::STORAGE_POWER, *calibnet::v10::STORAGE_POWER),
(*calibnet::v9::STORAGE_MINER, *calibnet::v10::STORAGE_MINER),
(
*calibnet::v9::VERIFIED_REGISTRY,
*calibnet::v10::VERIFIED_REGISTRY,
),
];
current_manifest.builtin_actor_codes().for_each(|code| {
let id = current_manifest.id_by_code(code);
let new_code = new_manifest.code_by_id(id).unwrap();
self.add_migrator(*code, nil_migrator(*new_code));
});

self.migrations.extend(
nil_migrations
.into_iter()
.map(|(from, to)| (from, nil_migrator(to))),
self.add_migrator(
*current_manifest.get_init_code(),
init::init_migrator(*new_manifest.get_init_code()),
);
}

pub fn add_nv_18_migrations(&mut self) {
self.add_migrator(
*calibnet::v9::INIT,
init::init_migrator(*calibnet::v10::INIT),
*current_manifest.get_system_code(),
system::system_migrator(new_manifest_data, *new_manifest.get_system_code()),
);

self.add_migrator(
*calibnet::v9::SYSTEM,
system::system_migrator(*calibnet::v10::SYSTEM),
)
Ok(())
}
}
Loading

0 comments on commit cc7716b

Please sign in to comment.