From 3006fda86d26deb4acc1983c8db399d71b20cb8c Mon Sep 17 00:00:00 2001 From: Hubert Bugaj Date: Mon, 5 Feb 2024 15:10:07 +0100 Subject: [PATCH 1/7] dragon state migration --- Cargo.lock | 175 +++++++--- Cargo.toml | 24 +- src/networks/actors_bundle.rs | 1 + src/networks/calibnet/mod.rs | 10 + src/networks/devnet/mod.rs | 12 +- src/networks/mod.rs | 2 + src/rpc/state_api.rs | 3 +- src/shim/version.rs | 1 + src/state_migration/mod.rs | 2 + src/state_migration/nv21/mod.rs | 5 +- src/state_migration/nv22/market.rs | 444 ++++++++++++++++++++++++++ src/state_migration/nv22/migration.rs | 156 +++++++++ src/state_migration/nv22/miner.rs | 389 ++++++++++++++++++++++ src/state_migration/nv22/mod.rs | 24 ++ 14 files changed, 1194 insertions(+), 54 deletions(-) create mode 100644 src/state_migration/nv22/market.rs create mode 100644 src/state_migration/nv22/migration.rs create mode 100644 src/state_migration/nv22/miner.rs create mode 100644 src/state_migration/nv22/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 67aec7663c27..2bfeb42a6e59 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2738,11 +2738,11 @@ checksum = "1676f435fc1dadde4d03e43f5d62b259e1ce5f40bd4ffb21db2b42ebe59c1382" [[package]] name = "fil_actor_account_state" -version = "9.4.0" +version = "10.0.0-dev.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fbac6eee8519336b3d91c595d9779e59a9eb25498722df907732a451e537602" +checksum = "b524f4c732b747da0d956d27aa739dc411f5c5f60c1f426b6e5e7d41297e6623" dependencies = [ - "frc42_macros", + "frc42_macros 3.0.0", "fvm_ipld_encoding", "fvm_shared 2.6.0", "fvm_shared 3.6.0", @@ -2754,9 +2754,9 @@ dependencies = [ [[package]] name = "fil_actor_cron_state" -version = "9.4.0" +version = "10.0.0-dev.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d9f0a936390d99738a6f1d9745e33e714bc925e5d35847f46c540181019534c" +checksum = "85163a77783b30e1e8f50acbfa9ce9f9a59b4cfc466e16b267a5391f8090c0eb" dependencies = [ "fvm_ipld_encoding", "fvm_shared 2.6.0", @@ -2769,12 +2769,14 @@ dependencies = [ [[package]] name = "fil_actor_datacap_state" -version = "9.4.0" +version = "10.0.0-dev.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3ef0bdf23cfe3f7ef97653247b11153447d781ac1f17388f90892ffb60a4eeb" +checksum = "e60906336423291085765840056fad664db0a97b27187109c7b45cec101defb2" dependencies = [ "fil_actors_shared", - "frc42_macros", + "frc42_macros 3.0.0", + "frc46_token", + "fvm_ipld_blockstore", "fvm_ipld_encoding", "fvm_shared 2.6.0", "fvm_shared 3.6.0", @@ -2787,13 +2789,13 @@ dependencies = [ [[package]] name = "fil_actor_evm_state" -version = "9.4.0" +version = "10.0.0-dev.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bd7b2edf69071d56319ae7d19dd57165f64df3ac9a77e296727866219973878" +checksum = "60796616a43ccb5eacb61dcd4c7a2f2ef8a7e62eaec9476a55a30c05ebbff82c" dependencies = [ "cid", "fil_actors_shared", - "frc42_macros", + "frc42_macros 3.0.0", "fvm_ipld_encoding", "fvm_shared 3.6.0", "fvm_shared 4.1.2", @@ -2807,14 +2809,14 @@ dependencies = [ [[package]] name = "fil_actor_init_state" -version = "9.4.0" +version = "10.0.0-dev.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6107f9cad8a978a15d62eacc9647ac10e52a91586fa877aa1d1cd12468b0681" +checksum = "4ce9244cbb893e46d586238f71fe6624d16e0c45cc3ea1e5ef7fee63e43be468" dependencies = [ "anyhow", "cid", "fil_actors_shared", - "frc42_macros", + "frc42_macros 3.0.0", "fvm_ipld_blockstore", "fvm_ipld_encoding", "fvm_ipld_hamt 0.9.0", @@ -2828,9 +2830,9 @@ dependencies = [ [[package]] name = "fil_actor_interface" -version = "9.4.0" +version = "10.0.0-dev.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186533fd65b63999b1738700b9bea5f7ea3ee61efc5ad0b8d2af08f35237314a" +checksum = "24446965e985aaeb427328ae73315740f682bd2a131378cfe774a57ebceee10c" dependencies = [ "anyhow", "cid", @@ -2866,15 +2868,15 @@ dependencies = [ [[package]] name = "fil_actor_market_state" -version = "9.4.0" +version = "10.0.0-dev.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c906b7f9f6dbf931076466969d93e67bc33090b13e4fedf73aff5be4846f5e" +checksum = "d1928a79eff1e7c8f6b12f3c9458132978913ff42827fff605a45f07dffacfc8" dependencies = [ "anyhow", "cid", "fil_actor_verifreg_state", "fil_actors_shared", - "frc42_macros", + "frc42_macros 3.0.0", "fvm_ipld_bitfield", "fvm_ipld_blockstore", "fvm_ipld_encoding", @@ -2891,16 +2893,16 @@ dependencies = [ [[package]] name = "fil_actor_miner_state" -version = "9.4.0" +version = "10.0.0-dev.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4819dcd358141977de9d35830929dcde157ae240e291de40cf62ac336f92c6d7" +checksum = "a3c7aca092651c9f4a1cc9b2d1bd1103acce1fbaaf486a8f4bcb633f9f486644" dependencies = [ "anyhow", "bitflags 2.4.2", "cid", "fil_actor_verifreg_state", "fil_actors_shared", - "frc42_macros", + "frc42_macros 3.0.0", "fvm_ipld_amt", "fvm_ipld_bitfield", "fvm_ipld_blockstore", @@ -2921,14 +2923,14 @@ dependencies = [ [[package]] name = "fil_actor_multisig_state" -version = "9.4.0" +version = "10.0.0-dev.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "204fe308f5d55ad834f57f36fdf0eba8703db92bf60dc24f1417dee1dda6b473" +checksum = "a938f4914894f033656f12827a2ac2c6a218d3358ee52133a348b675924031dd" dependencies = [ "anyhow", "cid", "fil_actors_shared", - "frc42_macros", + "frc42_macros 3.0.0", "fvm_ipld_blockstore", "fvm_ipld_encoding", "fvm_ipld_hamt 0.9.0", @@ -2944,14 +2946,14 @@ dependencies = [ [[package]] name = "fil_actor_power_state" -version = "9.4.0" +version = "10.0.0-dev.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a8cdc9c1e3cec390d758bc81faeb3d9b0c4e7974ff9eb247ded8ba3401eea92" +checksum = "fab1f29798dac7b2a0bac54e9c41abb30de73d480902d596e0db961dfe7d5c4f" dependencies = [ "anyhow", "cid", "fil_actors_shared", - "frc42_macros", + "frc42_macros 3.0.0", "fvm_ipld_blockstore", "fvm_ipld_encoding", "fvm_ipld_hamt 0.9.0", @@ -2967,9 +2969,9 @@ dependencies = [ [[package]] name = "fil_actor_reward_state" -version = "9.4.0" +version = "10.0.0-dev.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27b57db0a6f8777e373c1c8e1fcccdb5a50b7bc436095c1cbfa84cdbdb11d03" +checksum = "0cc1d9cd98fffa70097e4ab65e9dfc2027639d2c43ad0d9e2647e594426ca3e2" dependencies = [ "fvm_ipld_encoding", "fvm_shared 2.6.0", @@ -2983,11 +2985,13 @@ dependencies = [ [[package]] name = "fil_actor_system_state" -version = "9.4.0" +version = "10.0.0-dev.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5266c8d23d81980dfcda733e2e8e32d87c51bb392714f58aa835e6bad82e8234" +checksum = "a05e9a431925b3552bb56890ce28d8bfd8b363f0e01c1e5a9b134614ad84327b" dependencies = [ "cid", + "fil_actors_shared", + "fvm_ipld_blockstore", "fvm_ipld_encoding", "fvm_shared 2.6.0", "fvm_shared 4.1.2", @@ -2998,19 +3002,20 @@ dependencies = [ [[package]] name = "fil_actor_verifreg_state" -version = "9.4.0" +version = "10.0.0-dev.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f205cc8195bd298016d995a560e636ebaf550c5d3239de189860bc6f9ab2014" +checksum = "bc142f12cabce5c349dad96c0895f8e9ab709f5d88a0a41cc00474428174df6c" dependencies = [ "anyhow", "cid", "fil_actors_shared", - "frc42_macros", + "frc42_macros 3.0.0", "fvm_ipld_blockstore", "fvm_ipld_encoding", "fvm_shared 2.6.0", "fvm_shared 3.6.0", "fvm_shared 4.1.2", + "log", "num-derive", "num-traits", "serde", @@ -3018,9 +3023,9 @@ dependencies = [ [[package]] name = "fil_actors_shared" -version = "9.4.0" +version = "10.0.0-dev.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c0151e5842dba148031583452e40be7d5738ac7182f08bce183b4f6844224d1" +checksum = "57922235170b02269e034ee9b8ab4e09943a56de6a411b9eb5d9b2cae889f8fe" dependencies = [ "anyhow", "cid", @@ -3041,6 +3046,7 @@ dependencies = [ "num-derive", "num-traits", "paste", + "regex", "serde", "serde_repr", "sha2 0.10.8", @@ -3419,6 +3425,19 @@ dependencies = [ "thiserror", ] +[[package]] +name = "frc42_dispatch" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a1704e27193af21e58435974ff20f2be25cc59338afb89920abdb540ad3182b" +dependencies = [ + "frc42_hasher 4.0.0", + "frc42_macros 4.0.0", + "fvm_ipld_encoding", + "fvm_shared 4.1.2", + "thiserror", +] + [[package]] name = "frc42_hasher" version = "3.0.0" @@ -3428,6 +3447,17 @@ dependencies = [ "thiserror", ] +[[package]] +name = "frc42_hasher" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63f58bb50d36d90f5d0fee8391d6e1ed1a2b15ab8da6417dc42d7c78b587479d" +dependencies = [ + "fvm_sdk", + "fvm_shared 4.1.2", + "thiserror", +] + [[package]] name = "frc42_macros" version = "3.0.0" @@ -3435,12 +3465,46 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f50cd62b077775194bde67eef8076b31f915b9c099f3a7fd1a760363d65f145" dependencies = [ "blake2b_simd", - "frc42_hasher", + "frc42_hasher 3.0.0", "proc-macro2", "quote", "syn 1.0.109", ] +[[package]] +name = "frc42_macros" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a9ce38a981bab5e0d3c0835baa86f83066afe9afaf0aec23cee421f6d8c628e" +dependencies = [ + "blake2b_simd", + "frc42_hasher 4.0.0", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "frc46_token" +version = "10.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24f4829f83aef107908f00e225027fb4d74c064b747e6f0c4dc5e77ad843cc86" +dependencies = [ + "cid", + "frc42_dispatch", + "fvm_actor_utils", + "fvm_ipld_blockstore", + "fvm_ipld_encoding", + "fvm_ipld_hamt 0.9.0", + "fvm_sdk", + "fvm_shared 4.1.2", + "integer-encoding", + "num-traits", + "serde", + "serde_tuple", + "thiserror", +] + [[package]] name = "fs2" version = "0.4.3" @@ -3756,6 +3820,25 @@ dependencies = [ "wasmprinter", ] +[[package]] +name = "fvm_actor_utils" +version = "10.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1786030c99fd87853ec122697a1bb227f6eac67a4d96a5c27335ecb9dc3c21ec" +dependencies = [ + "anyhow", + "cid", + "frc42_dispatch", + "fvm_ipld_blockstore", + "fvm_ipld_encoding", + "fvm_sdk", + "fvm_shared 4.1.2", + "num-traits", + "serde", + "serde_tuple", + "thiserror", +] + [[package]] name = "fvm_ipld_amt" version = "0.6.2" @@ -3852,6 +3935,22 @@ dependencies = [ "thiserror", ] +[[package]] +name = "fvm_sdk" +version = "4.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e58331aefe4b5592c59abfd4d94c62b23ea61d1e121202fbc2fb6abd2fcb165" +dependencies = [ + "byteorder", + "cid", + "fvm_ipld_encoding", + "fvm_shared 4.1.2", + "lazy_static", + "log", + "num-traits", + "thiserror", +] + [[package]] name = "fvm_shared" version = "2.6.0" diff --git a/Cargo.toml b/Cargo.toml index 99d90b00ba9d..c571b871d553 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,18 +52,18 @@ dialoguer = "0.11" digest = "0.10.5" directories = "5" ethereum-types = "0.14.1" -fil_actor_account_state = { version = "9.4.0" } -fil_actor_cron_state = { version = "9.4.0" } -fil_actor_datacap_state = { version = "9.4.0" } -fil_actor_init_state = { version = "9.4.0" } -fil_actor_interface = { version = "9.4.0" } -fil_actor_market_state = { version = "9.4.0" } -fil_actor_miner_state = { version = "9.4.0" } -fil_actor_power_state = { version = "9.4.0" } -fil_actor_reward_state = { version = "9.4.0" } -fil_actor_system_state = { version = "9.4.0" } -fil_actor_verifreg_state = { version = "9.4.0" } -fil_actors_shared = { version = "9.4.0", features = ["json"] } +fil_actor_account_state = { version = "10.0.0-dev.1" } +fil_actor_cron_state = { version = "10.0.0-dev.1" } +fil_actor_datacap_state = { version = "10.0.0-dev.1" } +fil_actor_init_state = { version = "10.0.0-dev.1" } +fil_actor_interface = { version = "10.0.0-dev.1" } +fil_actor_market_state = { version = "10.0.0-dev.1" } +fil_actor_miner_state = { version = "10.0.0-dev.1" } +fil_actor_power_state = { version = "10.0.0-dev.1" } +fil_actor_reward_state = { version = "10.0.0-dev.1" } +fil_actor_system_state = { version = "10.0.0-dev.1" } +fil_actor_verifreg_state = { version = "10.0.0-dev.1" } +fil_actors_shared = { version = "10.0.0-dev.1", features = ["json"] } filecoin-proofs-api = { version = "16.0", default-features = false } flume = "0.11" fs_extra = "1.2" diff --git a/src/networks/actors_bundle.rs b/src/networks/actors_bundle.rs index 2b707e0281aa..9cb05c5007ca 100644 --- a/src/networks/actors_bundle.rs +++ b/src/networks/actors_bundle.rs @@ -75,6 +75,7 @@ pub static ACTOR_BUNDLES: Lazy> = Lazy::new(|| { "bafy2bzacebzz376j5kizfck56366kdz5aut6ktqrvqbi3efa2d4l2o2m653ts" @ "v10.0.0" for "devnet", "bafy2bzaceay35go4xbjb45km6o46e5bib3bi46panhovcbedrynzwmm3drr4i" @ "v11.0.0" for "devnet", "bafy2bzaceasjdukhhyjbegpli247vbf5h64f7uvxhhebdihuqsj2mwisdwa6o" @ "v12.0.0" for "devnet", + "bafy2bzacedok4fxofxdwkv42whkkukf3g4jwevui4kk5bw7b5unx4t3tjlrya" @ "v13.0.0-rc.2" for "devnet", "bafy2bzaceb6j6666h36xnhksu3ww4kxb6e25niayfgkdnifaqi6m6ooc66i6i" @ "v9.0.3" for "mainnet", "bafy2bzacecsuyf7mmvrhkx2evng5gnz5canlnz2fdlzu2lvcgptiq2pzuovos" @ "v10.0.0" for "mainnet", "bafy2bzacecnhaiwcrpyjvzl4uv4q3jzoif26okl3m66q3cijp3dfwlcxwztwo" @ "v11.0.0" for "mainnet", diff --git a/src/networks/calibnet/mod.rs b/src/networks/calibnet/mod.rs index be823f7c9050..0790aa6dbc82 100644 --- a/src/networks/calibnet/mod.rs +++ b/src/networks/calibnet/mod.rs @@ -191,6 +191,16 @@ pub static HEIGHT_INFOS: Lazy> = Lazy::new(|| { ), }, ), + ( + Height::Dragon, + HeightInfo { + epoch: 1_413_574, + bundle: Some( + Cid::try_from("bafy2bzaceap46ftyyuhninmzelt2ev6kus5itrggszrk5wuhzf2khm47dtrfa") + .unwrap(), + ), + }, + ), ]) }); diff --git a/src/networks/devnet/mod.rs b/src/networks/devnet/mod.rs index 24c4937a3131..223d5f11709e 100644 --- a/src/networks/devnet/mod.rs +++ b/src/networks/devnet/mod.rs @@ -58,13 +58,23 @@ pub static HEIGHT_INFOS: Lazy> = Lazy::new(|| { ( Height::Watermelon, HeightInfo { - epoch: get_upgrade_height_from_env("FOREST_WATERMELON_HEIGHT").unwrap_or(200), + epoch: get_upgrade_height_from_env("FOREST_WATERMELON_HEIGHT").unwrap_or(10), bundle: Some( Cid::try_from("bafy2bzaceasjdukhhyjbegpli247vbf5h64f7uvxhhebdihuqsj2mwisdwa6o") .unwrap(), ), }, ), + ( + Height::Dragon, + HeightInfo { + epoch: get_upgrade_height_from_env("FOREST_DRAGON_HEIGHT").unwrap_or(20), + bundle: Some( + Cid::try_from("bafy2bzacedok4fxofxdwkv42whkkukf3g4jwevui4kk5bw7b5unx4t3tjlrya") + .unwrap(), + ), + }, + ), ]) }); diff --git a/src/networks/mod.rs b/src/networks/mod.rs index 2a5e859c2f0c..1d529bff99e0 100644 --- a/src/networks/mod.rs +++ b/src/networks/mod.rs @@ -126,6 +126,7 @@ pub enum Height { Watermelon, WatermelonFix, WatermelonFix2, + Dragon, } impl Default for Height { @@ -161,6 +162,7 @@ impl From for NetworkVersion { Height::Watermelon => NetworkVersion::V21, Height::WatermelonFix => NetworkVersion::V21, Height::WatermelonFix2 => NetworkVersion::V21, + Height::Dragon => NetworkVersion::V22, } } } diff --git a/src/rpc/state_api.rs b/src/rpc/state_api.rs index 1a2ce3abe48d..c02a8cd6b93a 100644 --- a/src/rpc/state_api.rs +++ b/src/rpc/state_api.rs @@ -217,11 +217,12 @@ pub async fn state_market_deals( sector_start_epoch: -1, last_updated_epoch: -1, slash_epoch: -1, + verified_claim: 0, }); out.insert( deal_id.to_string(), MarketDeal { - proposal: d, + proposal: d?, state: s, }, ); diff --git a/src/shim/version.rs b/src/shim/version.rs index 3fadee4faf32..2d2eed1f10e9 100644 --- a/src/shim/version.rs +++ b/src/shim/version.rs @@ -56,6 +56,7 @@ impl NetworkVersion { pub const V19: Self = Self(NetworkVersion_latest::new(19)); pub const V20: Self = Self(NetworkVersion_latest::new(20)); pub const V21: Self = Self(NetworkVersion_latest::new(21)); + pub const V22: Self = Self(NetworkVersion_latest::new(22)); } impl Deref for NetworkVersion { diff --git a/src/state_migration/mod.rs b/src/state_migration/mod.rs index ca6141208d1e..b1580114ef64 100644 --- a/src/state_migration/mod.rs +++ b/src/state_migration/mod.rs @@ -21,6 +21,7 @@ mod nv19; mod nv21; mod nv21fix; mod nv21fix2; +mod nv22; mod type_migrations; type RunMigration = fn(&ChainConfig, &Arc, &Cid, ChainEpoch) -> anyhow::Result; @@ -63,6 +64,7 @@ where (Height::Hygge, nv18::run_migration::), (Height::Lightning, nv19::run_migration::), (Height::Watermelon, nv21::run_migration::), + (Height::Dragon, nv22::run_migration::), ] } }; diff --git a/src/state_migration/nv21/mod.rs b/src/state_migration/nv21/mod.rs index 858e2e11302a..58105870106c 100644 --- a/src/state_migration/nv21/mod.rs +++ b/src/state_migration/nv21/mod.rs @@ -1,14 +1,15 @@ // Copyright 2019-2024 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT -//! This module contains the migration logic for the `NV21` upgrade. +//! This module contains the migration logic for the `NV22` upgrade. //! The corresponding Go implementation can be found here: +//! TODO !!! //! mod migration; mod miner; -/// Run migration for `NV21`. This should be the only exported method in this +/// Run migration for `NV22`. This should be the only exported method in this /// module. pub use migration::run_migration; diff --git a/src/state_migration/nv22/market.rs b/src/state_migration/nv22/market.rs new file mode 100644 index 000000000000..74a26eee9992 --- /dev/null +++ b/src/state_migration/nv22/market.rs @@ -0,0 +1,444 @@ +// Copyright 2019-2023 ChainSafe Systems +// SPDX-License-Identifier: Apache-2.0, MIT + +//! This module contains the migration logic for the `NV22` upgrade for the +//! Market actor. +use std::sync::Arc; + +use crate::shim::econ::TokenAmount; +use crate::{shim::address::Address, utils::db::CborStoreExt}; +use ahash::HashMap; +use anyhow::Context; +use cid::Cid; +use fil_actor_market_state::v12::{ + DealArray as DealArrayOld, DealState as DealStateOld, State as MarketStateOld, +}; +use fil_actor_market_state::v13::{ + DealState as DealStateNew, ProviderSectorsMap as ProviderSectorsMapNew, SectorDealIDs, + SectorDealsMap, State as MarketStateNew, PROVIDER_SECTORS_CONFIG, SECTOR_DEALS_CONFIG, +}; +use fil_actors_shared::fvm_ipld_amt; +use fil_actors_shared::v12::Array as ArrayOld; +use fil_actors_shared::v13::Array as ArrayNew; +use fvm_ipld_blockstore::Blockstore; +use fvm_ipld_encoding::CborStore; +use fvm_shared4::deal::DealID; +use fvm_shared4::sector::SectorNumber; +use fvm_shared4::ActorID; + +use crate::state_migration::common::{ActorMigration, ActorMigrationInput, ActorMigrationOutput}; + +use super::miner::ProviderSectors; + +pub struct MarketMigrator { + provider_sectors: Arc, + out_cid: Cid, +} +pub(in crate::state_migration) fn market_migrator( + provider_sectors: Arc, + out_cid: Cid, +) -> anyhow::Result + Send + Sync>> { + Ok(Arc::new(MarketMigrator { + provider_sectors, + out_cid, + })) +} + +impl ActorMigration for MarketMigrator { + fn migrate_state( + &self, + store: &BS, + input: ActorMigrationInput, + ) -> anyhow::Result> { + let in_state: MarketStateOld = store + .get_cbor(&input.head)? + .context("failed to load state")?; + + let (provider_sectors, new_states) = self.migrate_provider_sectors_and_states::( + store, + input, + &in_state.states, + &in_state.proposals, + )?; + + let out_state = MarketStateNew { + proposals: in_state.proposals, + states: new_states, + pending_proposals: in_state.pending_proposals, + escrow_table: in_state.escrow_table, + locked_table: in_state.locked_table, + next_id: in_state.next_id, + deal_ops_by_epoch: in_state.deal_ops_by_epoch, + last_cron: in_state.last_cron, + total_client_locked_collateral: TokenAmount::from( + in_state.total_client_locked_collateral, + ) + .into(), + total_provider_locked_collateral: TokenAmount::from( + in_state.total_provider_locked_collateral, + ) + .into(), + total_client_storage_fee: TokenAmount::from(in_state.total_client_storage_fee).into(), + pending_deal_allocation_ids: in_state.pending_deal_allocation_ids, + provider_sectors, + }; + + let new_head = store.put_cbor_default(&out_state)?; + + Ok(Some(ActorMigrationOutput { + new_code_cid: self.out_cid, + new_head, + })) + } +} + +impl MarketMigrator { + fn migrate_provider_sectors_and_states( + &self, + store: &impl Blockstore, + input: ActorMigrationInput, + states: &Cid, + proposals: &Cid, + ) -> anyhow::Result<(Cid, Cid)> { + let prev_in_states = input + .cache + .get(&market_prev_deal_states_in_key(&input.address)); + + let prev_in_proposals = input + .cache + .get(&market_prev_deal_proposals_in_key(&input.address)); + + let prev_out_states = input + .cache + .get(&market_prev_deal_states_out_key(&input.address)); + + let prev_out_provider_sectors = input + .cache + .get(&market_prev_provider_sectors_out_key(&input.address)); + + let (provider_sectors_root, new_state_array_root) = if let ( + Some(prev_in_states), + Some(prev_in_proposals), + Some(prev_out_states), + Some(prev_out_provider_sectors), + ) = ( + prev_in_states, + prev_in_proposals, + prev_out_states, + prev_out_provider_sectors, + ) { + self.migrate_provider_sectors_and_states_with_diff::( + store, + &prev_in_states, + &prev_in_proposals, + &prev_out_states, + &prev_out_provider_sectors, + states, + )? + } else { + self.migrate_provider_sectors_and_states_with_scratch(store, states)? + }; + + input + .cache + .insert(market_prev_deal_states_in_key(&input.address), *states); + + input.cache.insert( + market_prev_deal_proposals_in_key(&input.address), + *proposals, + ); + + input.cache.insert( + market_prev_deal_states_out_key(&input.address), + new_state_array_root, + ); + + input.cache.insert( + market_prev_provider_sectors_out_key(&input.address), + provider_sectors_root, + ); + + Ok((provider_sectors_root, new_state_array_root)) + } + + fn migrate_provider_sectors_and_states_with_diff( + &self, + store: &impl Blockstore, + prev_in_states_cid: &Cid, + prev_in_proposals_cid: &Cid, + prev_out_states_cid: &Cid, + prev_out_provider_sectors_cid: &Cid, + in_states_cid: &Cid, + ) -> anyhow::Result<(Cid, Cid)> { + let prev_in_states = ArrayOld::::load(prev_in_states_cid, store)?; + let in_states = ArrayOld::::load(in_states_cid, store)?; + + let mut prev_out_states = ArrayOld::::load(prev_out_states_cid, store)?; + + let mut prev_out_provider_sectors = ProviderSectorsMapNew::load( + store, + prev_out_provider_sectors_cid, + PROVIDER_SECTORS_CONFIG, + "provider sectors", + )?; + + let proposals_array = DealArrayOld::load(prev_in_proposals_cid, store)?; + + // changesets to be applied to `prev_out_provider_sectors` + let mut provider_sectors: HashMap>> = + HashMap::default(); + let mut provider_sectors_remove: HashMap>> = + HashMap::default(); + + let mut add_provider_sector_entry = |deal| -> anyhow::Result { + let deal_to_sector = self.provider_sectors.deal_to_sector.read(); + let sector_id = deal_to_sector + .get(&deal) + .context(format!("deal {deal} not found in provider sectors"))?; + + provider_sectors + .entry(sector_id.miner) + .or_default() + .entry(sector_id.number) + .or_default() + .push(deal); + + Ok(sector_id.number) + }; + + let mut remove_provider_sector_entry = + |deal, mut new_state_prev_state: DealStateNew| -> anyhow::Result { + let sector_number = new_state_prev_state.sector_number; + let proposal = proposals_array.get(deal)?.context("proposal not found")?; + + let provider_id = proposal.provider.id()? as ActorID; + new_state_prev_state.sector_number = 0; + provider_sectors_remove + .entry(provider_id) + .or_default() + .entry(sector_number) + .or_default() + .push(deal); + + Ok(new_state_prev_state) + }; + + let diffs = fvm_ipld_amt::diff(&prev_in_states, &in_states)?; + for change in diffs { + let deal = change.key; + + use fvm_ipld_amt::ChangeType::*; + match change.change_type() { + Add => { + let old_state = change.after.context("missing after state")?; + let sector_number = if old_state.slash_epoch != -1 { + add_provider_sector_entry(deal)? + } else { + 0 + }; + let new_state = DealStateNew { + sector_number, + last_updated_epoch: old_state.last_updated_epoch, + sector_start_epoch: old_state.sector_start_epoch, + slash_epoch: old_state.slash_epoch, + }; + + prev_out_states.set(deal, new_state)?; + } + Remove => { + let prev_out_state = prev_out_states.get(deal)?.context("deal not found")?; + if prev_out_state.slash_epoch != 1 { + // Comment from Go implementation: + // > if the previous OUT state was not slashed then it has a provider sector entry that needs to be removed + remove_provider_sector_entry(deal, *prev_out_state)?; + } + + prev_out_states.delete(deal)?; + } + Modify => { + let prev_old_state = change.before.context("missing before state")?; + let old_state = change.after.context("missing after state")?; + + let mut new_state = *prev_out_states.get(deal)?.context("deal not found")?; + new_state.slash_epoch = old_state.slash_epoch; + new_state.last_updated_epoch = old_state.last_updated_epoch; + new_state.sector_start_epoch = old_state.sector_start_epoch; + + let new_state = + if prev_old_state.slash_epoch != -1 && old_state.slash_epoch != -1 { + remove_provider_sector_entry(deal, new_state)? + } else { + new_state + }; + + prev_out_states.set(deal, new_state)?; + } + } + } + + // process prevOutProviderSectors, first removes, then adds + + for (provider_id, sectors) in provider_sectors_remove.iter() { + let actor_sectors = prev_out_provider_sectors.get(provider_id)?; + + // From Go implementation: + // > this is fine, all sectors of this miner were already not present + // > in ProviderSectors. Sadly because the default value of a non-present + // > sector number in deal state is 0, we can't tell if a sector was + // > removed or if it was never there to begin with, which is why we + // > may occasionally end up here. + let actor_sectors = if let Some(actor_sectors) = actor_sectors { + actor_sectors + } else { + continue; + }; + + let mut actor_sectors = + SectorDealsMap::load(store, actor_sectors, SECTOR_DEALS_CONFIG, "sector deals")?; + + for (sector, deals) in sectors.iter() { + let sector_deals = actor_sectors.get(sector)?; + let sector_deals = if let Some(sector_deals) = sector_deals { + sector_deals + } else { + continue; + }; + + let mut sector_deals = sector_deals.clone(); + for deal in deals.iter() { + if let Some(idx) = sector_deals.deals.iter().position(|d| d == deal) { + sector_deals.deals.remove(idx); + } + } + + if sector_deals.deals.is_empty() { + actor_sectors.delete(sector)?; + } else { + actor_sectors.set(sector, sector_deals)?; + } + } + + if !actor_sectors.is_empty() { + let new_actor_sectors_root = actor_sectors.flush()?; + prev_out_provider_sectors.set(provider_id, new_actor_sectors_root)?; + } else { + prev_out_provider_sectors.delete(provider_id)?; + } + } + + for (provider_id, sectors) in provider_sectors.iter() { + let actor_sectors_root = prev_out_provider_sectors.get(provider_id)?; + let mut actor_sectors = if let Some(actor_sectors_root) = actor_sectors_root { + SectorDealsMap::load( + store, + actor_sectors_root, + SECTOR_DEALS_CONFIG, + "sector deals", + )? + } else { + SectorDealsMap::empty(store, SECTOR_DEALS_CONFIG, "sector deals") + }; + + for (sector, deals) in sectors.iter() { + actor_sectors.set( + sector, + SectorDealIDs { + deals: deals.clone(), + }, + )?; + } + + let new_actor_sectors_root = actor_sectors.flush()?; + prev_out_provider_sectors.set(provider_id, new_actor_sectors_root)?; + } + + let out_provider_sectors_root = prev_out_provider_sectors.flush()?; + let out_states = prev_out_states.flush()?; + + Ok((out_provider_sectors_root, out_states)) + } + + fn migrate_provider_sectors_and_states_with_scratch( + &self, + store: &impl Blockstore, + states: &Cid, + ) -> anyhow::Result<(Cid, Cid)> { + let old_state_array = ArrayOld::::load(states, store)?; + let mut new_state_array = ArrayNew::::new(store); + + let mut provider_sectors: HashMap>> = + HashMap::default(); + + // https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0076.md#migration + // FIP-0076: For each deal state object in the market actor state that has a terminated epoch set to -1 + old_state_array.for_each(|deal_id, old_state| { + let sector_number = if old_state.slash_epoch == -1 { + // find the corresponding deal proposal object and extract the provider's actor ID; + if let Some(sector_id) = self.provider_sectors.deal_to_sector.read().get(&deal_id) { + provider_sectors + .entry(sector_id.miner) + .or_default() + .entry(sector_id.number) + .or_default() + .push(deal_id); + // set the new deal state object's sector number to the sector ID found + sector_id.number + } else { + 0 + } + } else { + 0 + }; + + let new_state = DealStateNew { + sector_number, + last_updated_epoch: old_state.last_updated_epoch, + sector_start_epoch: old_state.sector_start_epoch, + slash_epoch: old_state.slash_epoch, + }; + new_state_array.set(deal_id, new_state)?; + + Ok(()) + })?; + + let new_state_array_root = new_state_array.flush()?; + let mut out_provider_sectors = + ProviderSectorsMapNew::empty(store, PROVIDER_SECTORS_CONFIG, "provider sectors"); + + for (miner, sectors) in provider_sectors.iter() { + let mut actor_sectors = + SectorDealsMap::empty(store, SECTOR_DEALS_CONFIG, "sector deals"); + + for (sector, deals) in sectors.iter() { + actor_sectors.set( + sector, + SectorDealIDs { + deals: deals.clone(), + }, + )?; + } + + out_provider_sectors.set(miner, actor_sectors.flush()?)?; + } + + let out_provider_sectors_root = out_provider_sectors.flush()?; + + Ok((out_provider_sectors_root, new_state_array_root)) + } +} + +fn market_prev_deal_states_in_key(addr: &Address) -> String { + format!("prev_deal_states_in_{addr}") +} + +fn market_prev_deal_proposals_in_key(addr: &Address) -> String { + format!("prev_deal_proposals_in_{addr}") +} + +fn market_prev_deal_states_out_key(addr: &Address) -> String { + format!("prev_deal_states_out_{addr}") +} + +fn market_prev_provider_sectors_out_key(addr: &Address) -> String { + format!("prev_provider_sectors_out_{addr}") +} diff --git a/src/state_migration/nv22/migration.rs b/src/state_migration/nv22/migration.rs new file mode 100644 index 000000000000..14f6a22a28ba --- /dev/null +++ b/src/state_migration/nv22/migration.rs @@ -0,0 +1,156 @@ +// Copyright 2019-2023 ChainSafe Systems +// SPDX-License-Identifier: Apache-2.0, MIT +// +//! This module contains the migration logic for the `NV22` upgrade. State migration logic +//! comes from the +//! [FIP-0076](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0076.md#migration). + +use std::sync::Arc; + +use crate::make_butterfly_policy; +use crate::networks::{ChainConfig, Height, NetworkChain}; +use crate::shim::{ + address::Address, + clock::ChainEpoch, + machine::{BuiltinActor, BuiltinActorManifest}, + sector::{RegisteredPoStProofV3, RegisteredSealProofV3}, + state_tree::{StateTree, StateTreeVersion}, +}; +use anyhow::Context; +use cid::Cid; +use fil_actors_shared::v12::runtime::ProofSet; +use fvm_ipld_blockstore::Blockstore; +use fvm_ipld_encoding::CborStore; + +use super::{market, miner, system, verifier::Verifier, SystemStateOld}; +use crate::state_migration::common::{migrators::nil_migrator, StateMigration}; + +impl StateMigration { + pub fn add_nv22_migrations( + &mut self, + store: &Arc, + state: &Cid, + new_manifest: &BuiltinActorManifest, + chain_config: &ChainConfig, + ) -> anyhow::Result<()> { + let state_tree = StateTree::new_from_root(store.clone(), state)?; + let system_actor = state_tree + .get_actor(&Address::new_id(0))? + .context("failed to get system actor")?; + + let system_actor_state = store + .get_cbor::(&system_actor.state)? + .context("system actor state not found")?; + + let current_manifest_data = system_actor_state.builtin_actors; + + let current_manifest = + BuiltinActorManifest::load_v1_actor_list(store, ¤t_manifest_data)?; + + for (name, code) in current_manifest.builtin_actors() { + let new_code = new_manifest.get(name)?; + self.add_migrator(code, nil_migrator(new_code)) + } + + let (policy_old, policy_new) = match &chain_config.network { + NetworkChain::Mainnet => ( + fil_actors_shared::v12::runtime::Policy::mainnet(), + fil_actors_shared::v13::runtime::Policy::mainnet(), + ), + NetworkChain::Calibnet => ( + fil_actors_shared::v12::runtime::Policy::calibnet(), + fil_actors_shared::v13::runtime::Policy::calibnet(), + ), + NetworkChain::Butterflynet => { + (make_butterfly_policy!(v12), make_butterfly_policy!(v13)) + } + NetworkChain::Devnet(_) => { + let mut policy_old = fil_actors_shared::v12::runtime::Policy::mainnet(); + policy_old.minimum_consensus_power = 2048.into(); + policy_old.minimum_verified_allocation_size = 256.into(); + policy_old.pre_commit_challenge_delay = 10; + + let mut proofs = ProofSet::default_seal_proofs(); + proofs.insert(RegisteredSealProofV3::StackedDRG2KiBV1); + proofs.insert(RegisteredSealProofV3::StackedDRG8MiBV1); + policy_old.valid_pre_commit_proof_type = proofs; + + let mut proofs = ProofSet::default_post_proofs(); + proofs.insert(RegisteredPoStProofV3::StackedDRGWindow2KiBV1); + proofs.insert(RegisteredPoStProofV3::StackedDRGWindow8MiBV1); + policy_old.valid_post_proof_type = proofs; + + ( + policy_old, + fil_actors_shared::v13::runtime::Policy::devnet(), + ) + } + }; + let miner_old_code = current_manifest.get(BuiltinActor::Miner)?; + let miner_new_code = new_manifest.get(BuiltinActor::Miner)?; + + let market_old_code = current_manifest.get(BuiltinActor::Market)?; + let market_new_code = new_manifest.get(BuiltinActor::Market)?; + + let provider_sectors = Arc::new(miner::ProviderSectors::default()); + + self.add_migrator( + miner_old_code, + miner::miner_migrator( + provider_sectors.clone(), + &policy_old, + &policy_new, + store, + miner_new_code, + )?, + ); + + self.add_migrator( + market_old_code, + market::market_migrator(provider_sectors.clone(), market_new_code)?, + ); + + self.add_migrator( + current_manifest.get_system(), + system::system_migrator(new_manifest), + ); + + Ok(()) + } +} + +/// Runs the migration for `NV22`. Returns the new state root. +pub fn run_migration( + chain_config: &ChainConfig, + blockstore: &Arc, + state: &Cid, + epoch: ChainEpoch, +) -> anyhow::Result +where + DB: Blockstore + Send + Sync, +{ + let new_manifest_cid = chain_config + .height_infos + .get(&Height::Dragon) + .context("no height info for network version NV22")? + .bundle + .as_ref() + .context("no bundle for network version NV22")?; + + blockstore.get(new_manifest_cid)?.context(format!( + "manifest for network version NV22 not found in blockstore: {new_manifest_cid}" + ))?; + + // Add migration specification verification + let verifier = Arc::new(Verifier::default()); + + let new_manifest = BuiltinActorManifest::load_manifest(blockstore, new_manifest_cid)?; + let mut migration = StateMigration::::new(Some(verifier)); + migration.add_nv22_migrations(blockstore, state, &new_manifest, chain_config)?; + + let actors_in = StateTree::new_from_root(blockstore.clone(), state)?; + let actors_out = StateTree::new(blockstore.clone(), StateTreeVersion::V5)?; + let new_state = migration.migrate_state_tree(blockstore, epoch, actors_in, actors_out)?; + + Ok(new_state) +} diff --git a/src/state_migration/nv22/miner.rs b/src/state_migration/nv22/miner.rs new file mode 100644 index 000000000000..d000b31593b3 --- /dev/null +++ b/src/state_migration/nv22/miner.rs @@ -0,0 +1,389 @@ +// Copyright 2019-2023 ChainSafe Systems +// SPDX-License-Identifier: Apache-2.0, MIT + +//! This module contains the migration logic for the `NV22` upgrade for the +//! Miner actor. + +use std::sync::Arc; + +use crate::shim::econ::TokenAmount; +use crate::{ + shim::address::Address, state_migration::common::MigrationCache, utils::db::CborStoreExt, +}; +use ahash::HashMap; +use anyhow::{bail, Context}; +use cid::Cid; +use fil_actor_miner_state::{v12::State as MinerStateOld, v13::State as MinerStateNew}; +use fil_actors_shared::fvm_ipld_amt; +use fil_actors_shared::v12::{runtime::Policy as PolicyOld, Array as ArrayOld}; +use fil_actors_shared::v13::{runtime::Policy as PolicyNew, Array as ArrayNew}; +use fvm_ipld_blockstore::Blockstore; +use fvm_ipld_encoding::CborStore; +use fvm_shared4::deal::DealID; +use fvm_shared4::sector::SectorID; +use parking_lot::RwLock; +use tracing::error; + +use crate::state_migration::common::{ + ActorMigration, ActorMigrationInput, ActorMigrationOutput, TypeMigration, TypeMigrator, +}; + +#[derive(Default)] +pub struct ProviderSectors { + pub deal_to_sector: RwLock>, +} + +pub struct MinerMigrator { + provider_sectors: Arc, + policy_new: PolicyNew, + out_cid: Cid, +} + +pub(in crate::state_migration) fn miner_migrator( + provider_sectors: Arc, + policy_old: &PolicyOld, + policy_new: &PolicyNew, + store: &Arc, + out_cid: Cid, +) -> anyhow::Result + Send + Sync>> { + Ok(Arc::new(MinerMigrator { + provider_sectors, + policy_new: policy_new.clone(), + out_cid, + })) +} + +impl ActorMigration for MinerMigrator { + fn migrate_state( + &self, + store: &BS, + input: ActorMigrationInput, + ) -> anyhow::Result> { + let miner_id = input.address.id()?; + let in_state: MinerStateOld = store + .get_cbor(&input.head)? + .context("Miner actor: could not read v12 state")?; + + let in_sectors = ArrayOld::::load( + &in_state.sectors, + store, + )?; + + if let Some(prev_sectors_cid) = input.cache.get(&miner_prev_sectors_in_key(&input.address)) + { + let prev_sectors = ArrayOld::::load( + &prev_sectors_cid, + store, + )?; + let diffs = fvm_ipld_amt::diff(&prev_sectors, &in_sectors)?; + + for change in diffs.iter() { + let sector_number = change.key; + match change.change_type() { + fvm_ipld_amt::ChangeType::Add => { + let sector = in_sectors + .get(sector_number)? + .context("Failed to get sector")?; + + if sector.deal_ids.is_empty() { + continue; + } + + let mut sectors = self.provider_sectors.deal_to_sector.write(); + for deal_id in §or.deal_ids { + sectors.insert( + *deal_id, + SectorID { + miner: miner_id, + number: sector_number, + }, + ); + } + } + fvm_ipld_amt::ChangeType::Modify => { + // OhSnap deals + let sector_old = change.before.as_ref().context("Failed to get sector")?; + let sector_new = change.after.as_ref().context("Failed to get sector")?; + + if sector_old.deal_ids.len() != sector_new.deal_ids.len() { + if !sector_old.deal_ids.is_empty() { + error!("old sector: {sector_old:?}, new_sector {sector_new:?}"); + bail!("This is not supported, and should not happen"); + } + + let mut sectors = self.provider_sectors.deal_to_sector.write(); + for deal_id in §or_new.deal_ids { + sectors.insert( + *deal_id, + SectorID { + miner: miner_id, + number: sector_number, + }, + ); + } + } + } + fvm_ipld_amt::ChangeType::Remove => { + // Comment from the Go implementation + // > nothing to do here, market removes deals based on activation/slash status, and can tell what + // > mappings to remove because non-slashed deals already had them + } + }; + } + } else { + // there is no cached migration, so we iterate over all sectors and collect the deal + // ids. + in_sectors.for_each(|_, sector| { + if sector.deal_ids.is_empty() { + return Ok(()); + } + + let mut sectors = self.provider_sectors.deal_to_sector.write(); + for (sector_number, deal_id) in sector.deal_ids.iter().enumerate() { + sectors.insert( + *deal_id, + SectorID { + miner: miner_id, + number: sector_number as u64, + }, + ); + } + + Ok(()) + })?; + } + + input + .cache + .insert(miner_prev_sectors_in_key(&input.address), in_state.sectors); + + Ok(Some(ActorMigrationOutput { + new_code_cid: self.out_cid, + new_head: input.head, + })) + } +} + +fn miner_prev_sectors_in_key(address: &Address) -> String { + format!("prevSectorsIn-{}", address) +} + +//#[cfg(test)] +//mod tests { +// use super::*; +// use crate::networks::{ChainConfig, Height}; +// use crate::shim::{ +// econ::TokenAmount, +// machine::{BuiltinActor, BuiltinActorManifest}, +// state_tree::{ActorState, StateTree, StateTreeVersion}, +// }; +// use cid::multihash::MultihashDigest; +// use fvm_ipld_encoding::IPLD_RAW; +// use fvm_shared2::bigint::Zero; +// +// #[test] +// fn test_nv21_miner_migration() { +// let store = Arc::new(crate::db::MemoryDB::default()); +// let (mut state_tree_old, manifest_old) = make_input_tree(&store); +// let system_actor_old = state_tree_old +// .get_actor(&fil_actor_interface::system::ADDRESS.into()) +// .unwrap() +// .unwrap(); +// let system_state_old: fil_actor_system_state::v11::State = +// store.get_cbor(&system_actor_old.state).unwrap().unwrap(); +// let manifest_data_cid_old = system_state_old.builtin_actors; +// assert_eq!(manifest_data_cid_old, manifest_old.source_cid()); +// +// let addr_id = 10000; +// let addr = Address::new_id(addr_id); +// let worker_id = addr_id + 100; +// +// // base stuff to create miners +// let miner_cid_old = manifest_old.get(BuiltinActor::Miner).unwrap(); +// let mut miner_state1 = make_base_miner_state(&store, addr_id, worker_id); +// let mut deadline = DeadlineOld::new(&store).unwrap(); +// let mut sectors_snapshot = +// ArrayOld::::new_with_bit_width( +// &store, +// fil_actor_miner_state::v11::SECTORS_AMT_BITWIDTH, +// ); +// sectors_snapshot +// .set( +// 0, +// fil_actor_miner_state::v11::SectorOnChainInfo { +// simple_qa_power: true, +// ..Default::default() +// }, +// ) +// .unwrap(); +// sectors_snapshot +// .set( +// 1, +// fil_actor_miner_state::v11::SectorOnChainInfo { +// simple_qa_power: false, +// ..Default::default() +// }, +// ) +// .unwrap(); +// deadline.sectors_snapshot = sectors_snapshot.flush().unwrap(); +// let deadline_cid = store.put_cbor_default(&deadline).unwrap(); +// let deadlines = DeadlinesOld::new( +// &fil_actors_shared::v11::runtime::Policy::calibnet(), +// deadline_cid, +// ); +// miner_state1.deadlines = store.put_cbor_default(&deadlines).unwrap(); +// +// let miner1_state_cid = store.put_cbor_default(&miner_state1).unwrap(); +// let miner1 = ActorState::new(miner_cid_old, miner1_state_cid, Zero::zero(), 0, None); +// state_tree_old.set_actor(&addr, miner1).unwrap(); +// let tree_root = state_tree_old.flush().unwrap(); +// +// let (new_manifest_cid, _new_manifest) = make_test_manifest(&store, "fil/12/"); +// +// let mut chain_config = ChainConfig::devnet(); +// if let Some(bundle) = &mut chain_config.height_infos[Height::Watermelon as usize].bundle { +// *bundle = new_manifest_cid; +// } +// let new_state_cid = +// super::super::run_migration(&chain_config, &store, &tree_root, 200).unwrap(); +// +// let new_state_cid2 = +// super::super::run_migration(&chain_config, &store, &tree_root, 200).unwrap(); +// +// assert_eq!(new_state_cid, new_state_cid2); +// +// let new_state_tree = StateTree::new_from_root(store.clone(), &new_state_cid).unwrap(); +// let new_miner_state_cid = new_state_tree.get_actor(&addr).unwrap().unwrap().state; +// let new_miner_state: fil_actor_miner_state::v12::State = +// store.get_cbor(&new_miner_state_cid).unwrap().unwrap(); +// let deadlines: fil_actor_miner_state::v12::Deadlines = +// store.get_cbor(&new_miner_state.deadlines).unwrap().unwrap(); +// deadlines +// .for_each(&store, |_, deadline| { +// let sectors_snapshots = +// ArrayNew::::load( +// &deadline.sectors_snapshot, +// &store, +// ) +// .unwrap(); +// assert_eq!( +// sectors_snapshots.get(0).unwrap().unwrap().flags, +// fil_actor_miner_state::v12::SectorOnChainInfoFlags::SIMPLE_QA_POWER +// ); +// assert!(!sectors_snapshots +// .get(1) +// .unwrap() +// .unwrap() +// .flags +// .contains(fil_actor_miner_state::v12::SectorOnChainInfoFlags::SIMPLE_QA_POWER)); +// Ok(()) +// }) +// .unwrap(); +// } +// +// fn make_input_tree(store: &Arc) -> (StateTree, BuiltinActorManifest) { +// let mut tree = StateTree::new(store.clone(), StateTreeVersion::V5).unwrap(); +// +// let (_manifest_cid, manifest) = make_test_manifest(&store, "fil/11/"); +// let system_cid = manifest.get_system(); +// let system_state = fil_actor_system_state::v11::State { +// builtin_actors: manifest.source_cid(), +// }; +// let system_state_cid = store.put_cbor_default(&system_state).unwrap(); +// init_actor( +// &mut tree, +// system_state_cid, +// system_cid, +// &fil_actor_interface::system::ADDRESS.into(), +// Zero::zero(), +// ); +// +// let init_cid = manifest.get_init(); +// let init_state = +// fil_actor_init_state::v11::State::new(&store, "migrationtest".into()).unwrap(); +// let init_state_cid = store.put_cbor_default(&init_state).unwrap(); +// init_actor( +// &mut tree, +// init_state_cid, +// init_cid, +// &fil_actor_interface::init::ADDRESS.into(), +// Zero::zero(), +// ); +// +// tree.flush().unwrap(); +// +// (tree, manifest) +// } +// +// fn init_actor( +// tree: &mut StateTree, +// state: Cid, +// code: Cid, +// addr: &Address, +// balance: TokenAmount, +// ) { +// let actor = ActorState::new(code, state, balance, 0, None); +// tree.set_actor(addr, actor).unwrap(); +// } +// +// fn make_test_manifest(store: &BS, prefix: &str) -> (Cid, BuiltinActorManifest) { +// let mut manifest_data = vec![]; +// for name in [ +// "account", +// "cron", +// "init", +// "storagemarket", +// "storageminer", +// "multisig", +// "paymentchannel", +// "storagepower", +// "reward", +// "system", +// "verifiedregistry", +// "datacap", +// ] { +// let hash = cid::multihash::Code::Identity.digest(format!("{prefix}{name}").as_bytes()); +// let code_cid = Cid::new_v1(IPLD_RAW, hash); +// manifest_data.push((name, code_cid)); +// } +// +// let manifest_cid = store +// .put_cbor_default(&(1, store.put_cbor_default(&manifest_data).unwrap())) +// .unwrap(); +// let manifest = BuiltinActorManifest::load_manifest(store, &manifest_cid).unwrap(); +// +// (manifest_cid, manifest) +// } +// +// fn make_base_miner_state( +// store: &BS, +// owner: fvm_shared3::ActorID, +// worker: fvm_shared3::ActorID, +// ) -> fil_actor_miner_state::v11::State { +// let control_addresses = vec![]; +// let peer_id = vec![]; +// let multi_address = vec![]; +// let window_post_proof_type = +// fvm_shared3::sector::RegisteredPoStProof::StackedDRGWindow2KiBV1; +// let miner_info = fil_actor_miner_state::v11::MinerInfo::new( +// owner, +// worker, +// control_addresses, +// peer_id, +// multi_address, +// window_post_proof_type, +// ) +// .unwrap(); +// +// let miner_info_cid = store.put_cbor_default(&miner_info).unwrap(); +// +// fil_actor_miner_state::v11::State::new( +// &fil_actors_shared::v11::runtime::Policy::calibnet(), +// store, +// miner_info_cid, +// 0, +// 0, +// ) +// .unwrap() +// } +//} diff --git a/src/state_migration/nv22/mod.rs b/src/state_migration/nv22/mod.rs new file mode 100644 index 000000000000..7cb1956a3955 --- /dev/null +++ b/src/state_migration/nv22/mod.rs @@ -0,0 +1,24 @@ +// Copyright 2019-2023 ChainSafe Systems +// SPDX-License-Identifier: Apache-2.0, MIT + +//! This module contains the migration logic for the `NV22` upgrade. +//! The corresponding Go implementation can be found here: +//! + +mod market; +mod migration; +mod miner; + +/// Run migration for `NV22`. This should be the only exported method in this +/// module. +pub use migration::run_migration; + +use crate::{define_system_states, impl_system, impl_verifier}; + +define_system_states!( + fil_actor_system_state::v12::State, + fil_actor_system_state::v13::State +); + +impl_system!(); +impl_verifier!(); From b1130accdd9bd9e956dcfca29e566a656ac1a76e Mon Sep 17 00:00:00 2001 From: Hubert Bugaj Date: Thu, 29 Feb 2024 13:37:48 +0100 Subject: [PATCH 2/7] plumbing --- Cargo.lock | 57 ++- Cargo.toml | 24 +- scripts/devnet/.env | 20 +- scripts/devnet/lotus.dockerfile | 2 +- src/networks/actors_bundle.rs | 2 + src/networks/calibnet/mod.rs | 8 +- src/networks/devnet/mod.rs | 4 +- src/networks/mainnet/mod.rs | 12 +- src/state_migration/common/mod.rs | 6 + src/state_migration/common/state_migration.rs | 69 +++- src/state_migration/mod.rs | 2 + src/state_migration/nv22/market.rs | 354 +++-------------- src/state_migration/nv22/migration.rs | 62 +-- src/state_migration/nv22/miner.rs | 375 ++---------------- src/state_migration/nv22/mod.rs | 2 +- 15 files changed, 249 insertions(+), 750 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2bfeb42a6e59..f1626285d21c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2738,9 +2738,9 @@ checksum = "1676f435fc1dadde4d03e43f5d62b259e1ce5f40bd4ffb21db2b42ebe59c1382" [[package]] name = "fil_actor_account_state" -version = "10.0.0-dev.1" +version = "10.0.0-dev.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b524f4c732b747da0d956d27aa739dc411f5c5f60c1f426b6e5e7d41297e6623" +checksum = "0b8d8a278388a502cbe22c7359eaa393eac4451f5accbd977eaee52a28275aaf" dependencies = [ "frc42_macros 3.0.0", "fvm_ipld_encoding", @@ -2754,9 +2754,9 @@ dependencies = [ [[package]] name = "fil_actor_cron_state" -version = "10.0.0-dev.1" +version = "10.0.0-dev.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85163a77783b30e1e8f50acbfa9ce9f9a59b4cfc466e16b267a5391f8090c0eb" +checksum = "6a0601edd6fe61bbcf574371c5502768d7716a55d233234b5e4c1e5693b3c055" dependencies = [ "fvm_ipld_encoding", "fvm_shared 2.6.0", @@ -2769,9 +2769,9 @@ dependencies = [ [[package]] name = "fil_actor_datacap_state" -version = "10.0.0-dev.1" +version = "10.0.0-dev.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e60906336423291085765840056fad664db0a97b27187109c7b45cec101defb2" +checksum = "a3cf2aa6bc17e28a599555d216c2e095aad55cdf0a2e0f66dbd705bf913db5f4" dependencies = [ "fil_actors_shared", "frc42_macros 3.0.0", @@ -2789,9 +2789,9 @@ dependencies = [ [[package]] name = "fil_actor_evm_state" -version = "10.0.0-dev.1" +version = "10.0.0-dev.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60796616a43ccb5eacb61dcd4c7a2f2ef8a7e62eaec9476a55a30c05ebbff82c" +checksum = "58b746a3dad083daf72be0f2757efa82849b3a45601b8e70362d81b5e73fa235" dependencies = [ "cid", "fil_actors_shared", @@ -2809,9 +2809,9 @@ dependencies = [ [[package]] name = "fil_actor_init_state" -version = "10.0.0-dev.1" +version = "10.0.0-dev.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ce9244cbb893e46d586238f71fe6624d16e0c45cc3ea1e5ef7fee63e43be468" +checksum = "84f37e7340dc021d20ef5ea36dfb52f173262d10184b1c924106c328427c5197" dependencies = [ "anyhow", "cid", @@ -2830,9 +2830,9 @@ dependencies = [ [[package]] name = "fil_actor_interface" -version = "10.0.0-dev.1" +version = "10.0.0-dev.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24446965e985aaeb427328ae73315740f682bd2a131378cfe774a57ebceee10c" +checksum = "27f5867b4ba96b9c5ff93ed10cfd6b313a5e59862d32599680c6d93daf325049" dependencies = [ "anyhow", "cid", @@ -2868,9 +2868,9 @@ dependencies = [ [[package]] name = "fil_actor_market_state" -version = "10.0.0-dev.1" +version = "10.0.0-dev.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1928a79eff1e7c8f6b12f3c9458132978913ff42827fff605a45f07dffacfc8" +checksum = "f0bc8c9746c93f9b6ac90240ca74f0b060bc78751b16c36f07618913854c0270" dependencies = [ "anyhow", "cid", @@ -2893,9 +2893,9 @@ dependencies = [ [[package]] name = "fil_actor_miner_state" -version = "10.0.0-dev.1" +version = "10.0.0-dev.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3c7aca092651c9f4a1cc9b2d1bd1103acce1fbaaf486a8f4bcb633f9f486644" +checksum = "722f6e09d9114e4b10c5c22299200f34b0b2a82693735b64cb98b13bab9ebca4" dependencies = [ "anyhow", "bitflags 2.4.2", @@ -2923,9 +2923,9 @@ dependencies = [ [[package]] name = "fil_actor_multisig_state" -version = "10.0.0-dev.1" +version = "10.0.0-dev.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a938f4914894f033656f12827a2ac2c6a218d3358ee52133a348b675924031dd" +checksum = "34878068dd52157eb581aa7533cf9a9bfe6f771eeed7b2299a97220b96880701" dependencies = [ "anyhow", "cid", @@ -2946,9 +2946,9 @@ dependencies = [ [[package]] name = "fil_actor_power_state" -version = "10.0.0-dev.1" +version = "10.0.0-dev.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fab1f29798dac7b2a0bac54e9c41abb30de73d480902d596e0db961dfe7d5c4f" +checksum = "7cc4e0b040fea3f81cb0ae1c829ce50024045d75021b582dcb1965f85bc59926" dependencies = [ "anyhow", "cid", @@ -2969,9 +2969,9 @@ dependencies = [ [[package]] name = "fil_actor_reward_state" -version = "10.0.0-dev.1" +version = "10.0.0-dev.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc1d9cd98fffa70097e4ab65e9dfc2027639d2c43ad0d9e2647e594426ca3e2" +checksum = "cdd400b1ef2e5ac539dec5b94d7861747009fdf34fcdfc8e92666d2d5adb852f" dependencies = [ "fvm_ipld_encoding", "fvm_shared 2.6.0", @@ -2985,9 +2985,9 @@ dependencies = [ [[package]] name = "fil_actor_system_state" -version = "10.0.0-dev.1" +version = "10.0.0-dev.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a05e9a431925b3552bb56890ce28d8bfd8b363f0e01c1e5a9b134614ad84327b" +checksum = "70369b47e9e11da6f7cc09edc7b3ec773e706113b83286af0cc2ca5377d6369c" dependencies = [ "cid", "fil_actors_shared", @@ -3002,9 +3002,9 @@ dependencies = [ [[package]] name = "fil_actor_verifreg_state" -version = "10.0.0-dev.1" +version = "10.0.0-dev.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc142f12cabce5c349dad96c0895f8e9ab709f5d88a0a41cc00474428174df6c" +checksum = "32259ec6139952b11abbb0a558128cccee44c58a460e1bcb9449e62ac6e9f25f" dependencies = [ "anyhow", "cid", @@ -3015,7 +3015,6 @@ dependencies = [ "fvm_shared 2.6.0", "fvm_shared 3.6.0", "fvm_shared 4.1.2", - "log", "num-derive", "num-traits", "serde", @@ -3023,9 +3022,9 @@ dependencies = [ [[package]] name = "fil_actors_shared" -version = "10.0.0-dev.1" +version = "10.0.0-dev.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57922235170b02269e034ee9b8ab4e09943a56de6a411b9eb5d9b2cae889f8fe" +checksum = "1e8194ff60ad006523bd2b4799c90ff69c2e3e5c719124e310568ac93437bfce" dependencies = [ "anyhow", "cid", diff --git a/Cargo.toml b/Cargo.toml index c571b871d553..4c7655879e03 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,18 +52,18 @@ dialoguer = "0.11" digest = "0.10.5" directories = "5" ethereum-types = "0.14.1" -fil_actor_account_state = { version = "10.0.0-dev.1" } -fil_actor_cron_state = { version = "10.0.0-dev.1" } -fil_actor_datacap_state = { version = "10.0.0-dev.1" } -fil_actor_init_state = { version = "10.0.0-dev.1" } -fil_actor_interface = { version = "10.0.0-dev.1" } -fil_actor_market_state = { version = "10.0.0-dev.1" } -fil_actor_miner_state = { version = "10.0.0-dev.1" } -fil_actor_power_state = { version = "10.0.0-dev.1" } -fil_actor_reward_state = { version = "10.0.0-dev.1" } -fil_actor_system_state = { version = "10.0.0-dev.1" } -fil_actor_verifreg_state = { version = "10.0.0-dev.1" } -fil_actors_shared = { version = "10.0.0-dev.1", features = ["json"] } +fil_actor_account_state = { version = "10.0.0-dev.2" } +fil_actor_cron_state = { version = "10.0.0-dev.2" } +fil_actor_datacap_state = { version = "10.0.0-dev.2" } +fil_actor_init_state = { version = "10.0.0-dev.2" } +fil_actor_interface = { version = "10.0.0-dev.2" } +fil_actor_market_state = { version = "10.0.0-dev.2" } +fil_actor_miner_state = { version = "10.0.0-dev.2" } +fil_actor_power_state = { version = "10.0.0-dev.2" } +fil_actor_reward_state = { version = "10.0.0-dev.2" } +fil_actor_system_state = { version = "10.0.0-dev.2" } +fil_actor_verifreg_state = { version = "10.0.0-dev.2" } +fil_actors_shared = { version = "10.0.0-dev.2", features = ["json"] } filecoin-proofs-api = { version = "16.0", default-features = false } flume = "0.11" fs_extra = "1.2" diff --git a/scripts/devnet/.env b/scripts/devnet/.env index 290c497fb5d6..3426aee7ac22 100644 --- a/scripts/devnet/.env +++ b/scripts/devnet/.env @@ -1,4 +1,4 @@ -LOTUS_IMAGE=ghcr.io/chainsafe/lotus-devnet:2024-02-29-a2919fe +LOTUS_IMAGE=lotus-devnet FOREST_DATA_DIR=/forest_data LOTUS_DATA_DIR=/lotus_data FIL_PROOFS_PARAMETER_CACHE=/var/tmp/filecoin-proof-parameters @@ -6,12 +6,12 @@ LOTUS_RPC_PORT=1234 LOTUS_P2P_PORT=1235 MINER_RPC_PORT=2345 FOREST_RPC_PORT=3456 -GENESIS_NETWORK_VERSION=18 -SHARK_HEIGHT=-10 -HYGGE_HEIGHT=-9 -LIGHTNING_HEIGHT=3 -THUNDER_HEIGHT=6 -WATERMELON_HEIGHT=9 -DRAGON_HEIGHT=1000 -DRAND_QUICKNET_HEIGHT=12 -TARGET_HEIGHT=15 +GENESIS_NETWORK_VERSION=21 +SHARK_HEIGHT=-20 +HYGGE_HEIGHT=-22 +LIGHTNING_HEIGHT=-23 +THUNDER_HEIGHT=-24 +WATERMELON_HEIGHT=-1 +DRAGON_HEIGHT=20 +DRAND_QUICKNET_HEIGHT=140 +TARGET_HEIGHT=200 diff --git a/scripts/devnet/lotus.dockerfile b/scripts/devnet/lotus.dockerfile index b4326c1f0d87..26f4112b4b71 100644 --- a/scripts/devnet/lotus.dockerfile +++ b/scripts/devnet/lotus.dockerfile @@ -5,7 +5,7 @@ RUN apt-get update && apt-get install -y ca-certificates build-essential clang o WORKDIR /lotus -RUN git clone --depth 1 --branch v1.25.2 https://github.com/filecoin-project/lotus.git . +RUN git clone --depth 1 --branch asr/migration-nv22 https://github.com/filecoin-project/lotus.git . RUN CGO_CFLAGS_ALLOW="-D__BLST_PORTABLE__" \ CGO_CFLAGS="-D__BLST_PORTABLE__" \ diff --git a/src/networks/actors_bundle.rs b/src/networks/actors_bundle.rs index 9cb05c5007ca..38aa39784f25 100644 --- a/src/networks/actors_bundle.rs +++ b/src/networks/actors_bundle.rs @@ -69,6 +69,7 @@ pub static ACTOR_BUNDLES: Lazy> = Lazy::new(|| { "bafy2bzacedrunxfqta5skb7q7x32lnp4efz2oq7fn226ffm7fu5iqs62jkmvs" @ "v12.0.0-rc.1" for "calibrationnet", "bafy2bzacebl4w5ptfvuw6746w7ev562idkbf5ppq72e6zub22435ws2rukzru" @ "v12.0.0-rc.2" for "calibrationnet", "bafy2bzacednzb3pkrfnbfhmoqtb3bc6dgvxszpqklf3qcc7qzcage4ewzxsca" @ "v12.0.0" for "calibrationnet", + "bafy2bzaceap46ftyyuhninmzelt2ev6kus5itrggszrk5wuhzf2khm47dtrfa" @ "v13.0.0-rc.2" for "calibrationnet", "bafy2bzaceaiy4dsxxus5xp5n5i4tjzkb7sc54mjz7qnk2efhgmsrobjesxnza" @ "v11.0.0" for "butterflynet", "bafy2bzacectxvbk77ntedhztd6sszp2btrtvsmy7lp2ypnrk6yl74zb34t2cq" @ "v12.0.0" for "butterflynet", "bafy2bzacedozk3jh2j4nobqotkbofodq4chbrabioxbfrygpldgoxs3zwgggk" @ "v9.0.3" for "devnet", @@ -80,6 +81,7 @@ pub static ACTOR_BUNDLES: Lazy> = Lazy::new(|| { "bafy2bzacecsuyf7mmvrhkx2evng5gnz5canlnz2fdlzu2lvcgptiq2pzuovos" @ "v10.0.0" for "mainnet", "bafy2bzacecnhaiwcrpyjvzl4uv4q3jzoif26okl3m66q3cijp3dfwlcxwztwo" @ "v11.0.0" for "mainnet", "bafy2bzaceapkgfggvxyllnmuogtwasmsv5qi2qzhc2aybockd6kag2g5lzaio" @ "v12.0.0" for "mainnet", + "bafy2bzacea6f5icdp6t6fs5sexjxmo3q5d2qu4g4ghq6s5eaob6svnmhvltmw" @ "v13.0.0-rc.2" for "mainnet", ]) }); diff --git a/src/networks/calibnet/mod.rs b/src/networks/calibnet/mod.rs index 0790aa6dbc82..c226c8b9c10a 100644 --- a/src/networks/calibnet/mod.rs +++ b/src/networks/calibnet/mod.rs @@ -7,7 +7,10 @@ use libp2p::Multiaddr; use once_cell::sync::Lazy; use std::str::FromStr; -use super::{drand::DRAND_MAINNET, parse_bootstrap_peers, DrandPoint, Height, HeightInfo}; +use super::{ + drand::DRAND_MAINNET, get_upgrade_height_from_env, parse_bootstrap_peers, DrandPoint, Height, + HeightInfo, +}; /// Default genesis car file bytes. pub const DEFAULT_GENESIS: &[u8] = include_bytes!("genesis.car"); @@ -191,10 +194,11 @@ pub static HEIGHT_INFOS: Lazy> = Lazy::new(|| { ), }, ), + // TODO: This shouldn't be modifiable outside of testing ( Height::Dragon, HeightInfo { - epoch: 1_413_574, + epoch: get_upgrade_height_from_env("FOREST_DRAGON_HEIGHT").unwrap_or(1_427_974), bundle: Some( Cid::try_from("bafy2bzaceap46ftyyuhninmzelt2ev6kus5itrggszrk5wuhzf2khm47dtrfa") .unwrap(), diff --git a/src/networks/devnet/mod.rs b/src/networks/devnet/mod.rs index 223d5f11709e..59dc0665e4b1 100644 --- a/src/networks/devnet/mod.rs +++ b/src/networks/devnet/mod.rs @@ -51,14 +51,14 @@ pub static HEIGHT_INFOS: Lazy> = Lazy::new(|| { ( Height::Thunder, HeightInfo { - epoch: get_upgrade_height_from_env("FOREST_THUNDER_HEIGHT").unwrap_or(-1), + epoch: get_upgrade_height_from_env("FOREST_THUNDER_HEIGHT").unwrap_or(-23), bundle: None, }, ), ( Height::Watermelon, HeightInfo { - epoch: get_upgrade_height_from_env("FOREST_WATERMELON_HEIGHT").unwrap_or(10), + epoch: get_upgrade_height_from_env("FOREST_WATERMELON_HEIGHT").unwrap_or(-1), bundle: Some( Cid::try_from("bafy2bzaceasjdukhhyjbegpli247vbf5h64f7uvxhhebdihuqsj2mwisdwa6o") .unwrap(), diff --git a/src/networks/mainnet/mod.rs b/src/networks/mainnet/mod.rs index 4c5443f0b5bb..d479e13383e4 100644 --- a/src/networks/mainnet/mod.rs +++ b/src/networks/mainnet/mod.rs @@ -10,7 +10,7 @@ use std::str::FromStr; use super::{ drand::{DRAND_INCENTINET, DRAND_MAINNET, DRAND_QUICKNET}, - parse_bootstrap_peers, DrandPoint, Height, HeightInfo, + get_upgrade_height_from_env, parse_bootstrap_peers, DrandPoint, Height, HeightInfo, }; const SMOKE_HEIGHT: ChainEpoch = 51000; @@ -202,6 +202,16 @@ pub static HEIGHT_INFOS: Lazy> = Lazy::new(|| { ), }, ), + ( + Height::Dragon, + HeightInfo { + epoch: get_upgrade_height_from_env("FOREST_DRAGON_HEIGHT").unwrap_or(i64::MAX), + bundle: Some( + Cid::try_from("bafy2bzacea6f5icdp6t6fs5sexjxmo3q5d2qu4g4ghq6s5eaob6svnmhvltmw") + .unwrap(), + ), + }, + ), ]) }); diff --git a/src/state_migration/common/mod.rs b/src/state_migration/common/mod.rs index 9fa23061c09b..d7240dbc3c89 100644 --- a/src/state_migration/common/mod.rs +++ b/src/state_migration/common/mod.rs @@ -85,6 +85,12 @@ pub(in crate::state_migration) trait ActorMigration { store: &BS, input: ActorMigrationInput, ) -> anyhow::Result>; + + /// Some migration jobs might need to be deferred to be executed after the regular state migration. + /// These may require some metadata collected during other migrations. + fn is_deferred(&self) -> bool { + false + } } /// Trait that defines the interface for actor migration job to be executed after the state migration. diff --git a/src/state_migration/common/state_migration.rs b/src/state_migration/common/state_migration.rs index 007014eeb908..373aad41f4e1 100644 --- a/src/state_migration/common/state_migration.rs +++ b/src/state_migration/common/state_migration.rs @@ -3,12 +3,14 @@ use std::num::NonZeroUsize; use std::sync::atomic::AtomicU64; +use std::sync::Arc; use crate::cid_collections::CidHashMap; use crate::shim::{clock::ChainEpoch, state_tree::StateTree}; use crate::state_migration::common::MigrationCache; use cid::Cid; use fvm_ipld_blockstore::Blockstore; +use parking_lot::Mutex; use super::PostMigrationCheckArc; use super::{verifier::MigrationVerifier, Migrator, PostMigratorArc}; @@ -78,18 +80,29 @@ impl StateMigration { } let cache = MigrationCache::new(NonZeroUsize::new(10_000).expect("infallible")); + let num_threads = std::env::var("FOREST_STATE_MIGRATION_THREADS") + .ok() + .and_then(|s| s.parse().ok()) + // At least 3 are required to not deadlock the migration. Don't use all CPU, + // otherwise the migration will starve the rest of the system. + .unwrap_or_else(|| 3.max(num_cpus::get() / 2)); + let pool = rayon::ThreadPoolBuilder::new() .thread_name(|id| format!("state migration thread: {id}")) - .num_threads(3) // minimum needed, more doesn't increase performance in any way + .num_threads(num_threads) .build()?; - let (state_tx, state_rx) = crossbeam_channel::bounded(1); - let (job_tx, job_rx) = crossbeam_channel::bounded(1); + let (state_tx, state_rx) = crossbeam_channel::bounded(30); + let (job_tx, job_rx) = crossbeam_channel::bounded(30); let job_counter = AtomicU64::new(0); + let cache_clone = cache.clone(); + + let actors_in = Arc::new(Mutex::new(actors_in)); + let actors_in_clone = actors_in.clone(); pool.scope(|s| { s.spawn(move |_| { - actors_in + actors_in.lock() .for_each(|addr, state| { state_tx .send((addr, state.clone())) @@ -103,7 +116,12 @@ impl StateMigration { while let Ok((address, state)) = state_rx.recv() { let job_tx = job_tx.clone(); let migrator = self.migrations.get(&state.code).cloned().unwrap_or_else(|| panic!("migration failed with state code: {}", state.code)); - let cache_clone = cache.clone(); + + // Deferred migrations should be done at a later time. + if migrator.is_deferred() { + continue; + } + let cache_clone = cache_clone.clone(); scope.spawn(move |_| { let job = MigrationJob { address, @@ -146,6 +164,47 @@ impl StateMigration { } }); + // This is okay to execute even if there are no deferred migrations, as the iteration is + // very cheap; ~200ms on mainnet. The alternative is to collect the deferred migrations + // into a separate collection, which would increase the memory footprint of the migration. + tracing::info!("Processing deferred migrations"); + let mut job_counter = 0; + actors_in_clone.lock().for_each(|address, state| { + job_counter += 1; + let migrator = self + .migrations + .get(&state.code) + .cloned() + .unwrap_or_else(|| panic!("migration failed with state code: {}", state.code)); + + if !migrator.is_deferred() { + return Ok(()); + } + + let job = MigrationJob { + address, + actor_state: state.clone(), + actor_migration: migrator, + }; + let job_output = job.run(store, prior_epoch, cache.clone())?; + if let Some(MigrationJobOutput { + address, + actor_state, + }) = job_output + { + actors_out + .set_actor(&address, actor_state) + .unwrap_or_else(|e| { + panic!( + "Failed setting new actor state at given address: {address}, Reason: {e}" + ) + }); + } + + Ok(()) + })?; + tracing::info!("Processed {job_counter} deferred migrations"); + // execute post migration actions, e.g., create new actors for post_migrator in self.post_migrators.iter() { post_migrator.post_migrate_state(store, &mut actors_out)?; diff --git a/src/state_migration/mod.rs b/src/state_migration/mod.rs index b1580114ef64..2946537d205e 100644 --- a/src/state_migration/mod.rs +++ b/src/state_migration/mod.rs @@ -43,6 +43,7 @@ where (Height::Hygge, nv18::run_migration::), (Height::Lightning, nv19::run_migration::), (Height::Watermelon, nv21::run_migration::), + (Height::Dragon, nv22::run_migration::), ] } NetworkChain::Calibnet => { @@ -53,6 +54,7 @@ where (Height::Watermelon, nv21::run_migration::), (Height::WatermelonFix, nv21fix::run_migration::), (Height::WatermelonFix2, nv21fix2::run_migration::), + (Height::Dragon, nv22::run_migration::), ] } NetworkChain::Butterflynet => { diff --git a/src/state_migration/nv22/market.rs b/src/state_migration/nv22/market.rs index 74a26eee9992..ea3dcb80a0d7 100644 --- a/src/state_migration/nv22/market.rs +++ b/src/state_migration/nv22/market.rs @@ -1,4 +1,4 @@ -// Copyright 2019-2023 ChainSafe Systems +// Copyright 2019-2024 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT //! This module contains the migration logic for the `NV22` upgrade for the @@ -6,39 +6,40 @@ use std::sync::Arc; use crate::shim::econ::TokenAmount; -use crate::{shim::address::Address, utils::db::CborStoreExt}; -use ahash::HashMap; +use crate::utils::db::CborStoreExt; use anyhow::Context; use cid::Cid; use fil_actor_market_state::v12::{ - DealArray as DealArrayOld, DealState as DealStateOld, State as MarketStateOld, + DealProposal, DealState as DealStateOld, State as MarketStateOld, }; use fil_actor_market_state::v13::{ DealState as DealStateNew, ProviderSectorsMap as ProviderSectorsMapNew, SectorDealIDs, SectorDealsMap, State as MarketStateNew, PROVIDER_SECTORS_CONFIG, SECTOR_DEALS_CONFIG, + STATES_AMT_BITWIDTH, }; -use fil_actors_shared::fvm_ipld_amt; + use fil_actors_shared::v12::Array as ArrayOld; use fil_actors_shared::v13::Array as ArrayNew; use fvm_ipld_blockstore::Blockstore; use fvm_ipld_encoding::CborStore; -use fvm_shared4::deal::DealID; -use fvm_shared4::sector::SectorNumber; -use fvm_shared4::ActorID; +use fvm_shared4::clock::ChainEpoch; use crate::state_migration::common::{ActorMigration, ActorMigrationInput, ActorMigrationOutput}; use super::miner::ProviderSectors; pub struct MarketMigrator { + upgrade_epoch: ChainEpoch, provider_sectors: Arc, out_cid: Cid, } pub(in crate::state_migration) fn market_migrator( + upgrade_epoch: ChainEpoch, provider_sectors: Arc, out_cid: Cid, ) -> anyhow::Result + Send + Sync>> { Ok(Arc::new(MarketMigrator { + upgrade_epoch, provider_sectors, out_cid, })) @@ -54,12 +55,8 @@ impl ActorMigration for MarketMigrator { .get_cbor(&input.head)? .context("failed to load state")?; - let (provider_sectors, new_states) = self.migrate_provider_sectors_and_states::( - store, - input, - &in_state.states, - &in_state.proposals, - )?; + let (provider_sectors, new_states) = + self.migrate_provider_sectors_and_states(store, &in_state.states, &in_state.proposals)?; let out_state = MarketStateNew { proposals: in_state.proposals, @@ -90,305 +87,64 @@ impl ActorMigration for MarketMigrator { new_head, })) } + + fn is_deferred(&self) -> bool { + true + } } impl MarketMigrator { - fn migrate_provider_sectors_and_states( + fn migrate_provider_sectors_and_states( &self, store: &impl Blockstore, - input: ActorMigrationInput, states: &Cid, proposals: &Cid, ) -> anyhow::Result<(Cid, Cid)> { - let prev_in_states = input - .cache - .get(&market_prev_deal_states_in_key(&input.address)); - - let prev_in_proposals = input - .cache - .get(&market_prev_deal_proposals_in_key(&input.address)); - - let prev_out_states = input - .cache - .get(&market_prev_deal_states_out_key(&input.address)); - - let prev_out_provider_sectors = input - .cache - .get(&market_prev_provider_sectors_out_key(&input.address)); - - let (provider_sectors_root, new_state_array_root) = if let ( - Some(prev_in_states), - Some(prev_in_proposals), - Some(prev_out_states), - Some(prev_out_provider_sectors), - ) = ( - prev_in_states, - prev_in_proposals, - prev_out_states, - prev_out_provider_sectors, - ) { - self.migrate_provider_sectors_and_states_with_diff::( - store, - &prev_in_states, - &prev_in_proposals, - &prev_out_states, - &prev_out_provider_sectors, - states, - )? - } else { - self.migrate_provider_sectors_and_states_with_scratch(store, states)? - }; - - input - .cache - .insert(market_prev_deal_states_in_key(&input.address), *states); - - input.cache.insert( - market_prev_deal_proposals_in_key(&input.address), - *proposals, - ); - - input.cache.insert( - market_prev_deal_states_out_key(&input.address), - new_state_array_root, - ); - - input.cache.insert( - market_prev_provider_sectors_out_key(&input.address), - provider_sectors_root, - ); + //dbg!("running market migration"); + let (provider_sectors_root, new_state_array_root) = + self.migrate_provider_sectors_and_states_with_scratch(store, states, proposals)?; Ok((provider_sectors_root, new_state_array_root)) } - fn migrate_provider_sectors_and_states_with_diff( - &self, - store: &impl Blockstore, - prev_in_states_cid: &Cid, - prev_in_proposals_cid: &Cid, - prev_out_states_cid: &Cid, - prev_out_provider_sectors_cid: &Cid, - in_states_cid: &Cid, - ) -> anyhow::Result<(Cid, Cid)> { - let prev_in_states = ArrayOld::::load(prev_in_states_cid, store)?; - let in_states = ArrayOld::::load(in_states_cid, store)?; - - let mut prev_out_states = ArrayOld::::load(prev_out_states_cid, store)?; - - let mut prev_out_provider_sectors = ProviderSectorsMapNew::load( - store, - prev_out_provider_sectors_cid, - PROVIDER_SECTORS_CONFIG, - "provider sectors", - )?; - - let proposals_array = DealArrayOld::load(prev_in_proposals_cid, store)?; - - // changesets to be applied to `prev_out_provider_sectors` - let mut provider_sectors: HashMap>> = - HashMap::default(); - let mut provider_sectors_remove: HashMap>> = - HashMap::default(); - - let mut add_provider_sector_entry = |deal| -> anyhow::Result { - let deal_to_sector = self.provider_sectors.deal_to_sector.read(); - let sector_id = deal_to_sector - .get(&deal) - .context(format!("deal {deal} not found in provider sectors"))?; - - provider_sectors - .entry(sector_id.miner) - .or_default() - .entry(sector_id.number) - .or_default() - .push(deal); - - Ok(sector_id.number) - }; - - let mut remove_provider_sector_entry = - |deal, mut new_state_prev_state: DealStateNew| -> anyhow::Result { - let sector_number = new_state_prev_state.sector_number; - let proposal = proposals_array.get(deal)?.context("proposal not found")?; - - let provider_id = proposal.provider.id()? as ActorID; - new_state_prev_state.sector_number = 0; - provider_sectors_remove - .entry(provider_id) - .or_default() - .entry(sector_number) - .or_default() - .push(deal); - - Ok(new_state_prev_state) - }; - - let diffs = fvm_ipld_amt::diff(&prev_in_states, &in_states)?; - for change in diffs { - let deal = change.key; - - use fvm_ipld_amt::ChangeType::*; - match change.change_type() { - Add => { - let old_state = change.after.context("missing after state")?; - let sector_number = if old_state.slash_epoch != -1 { - add_provider_sector_entry(deal)? - } else { - 0 - }; - let new_state = DealStateNew { - sector_number, - last_updated_epoch: old_state.last_updated_epoch, - sector_start_epoch: old_state.sector_start_epoch, - slash_epoch: old_state.slash_epoch, - }; - - prev_out_states.set(deal, new_state)?; - } - Remove => { - let prev_out_state = prev_out_states.get(deal)?.context("deal not found")?; - if prev_out_state.slash_epoch != 1 { - // Comment from Go implementation: - // > if the previous OUT state was not slashed then it has a provider sector entry that needs to be removed - remove_provider_sector_entry(deal, *prev_out_state)?; - } - - prev_out_states.delete(deal)?; - } - Modify => { - let prev_old_state = change.before.context("missing before state")?; - let old_state = change.after.context("missing after state")?; - - let mut new_state = *prev_out_states.get(deal)?.context("deal not found")?; - new_state.slash_epoch = old_state.slash_epoch; - new_state.last_updated_epoch = old_state.last_updated_epoch; - new_state.sector_start_epoch = old_state.sector_start_epoch; - - let new_state = - if prev_old_state.slash_epoch != -1 && old_state.slash_epoch != -1 { - remove_provider_sector_entry(deal, new_state)? - } else { - new_state - }; - - prev_out_states.set(deal, new_state)?; - } - } - } - - // process prevOutProviderSectors, first removes, then adds - - for (provider_id, sectors) in provider_sectors_remove.iter() { - let actor_sectors = prev_out_provider_sectors.get(provider_id)?; - - // From Go implementation: - // > this is fine, all sectors of this miner were already not present - // > in ProviderSectors. Sadly because the default value of a non-present - // > sector number in deal state is 0, we can't tell if a sector was - // > removed or if it was never there to begin with, which is why we - // > may occasionally end up here. - let actor_sectors = if let Some(actor_sectors) = actor_sectors { - actor_sectors - } else { - continue; - }; - - let mut actor_sectors = - SectorDealsMap::load(store, actor_sectors, SECTOR_DEALS_CONFIG, "sector deals")?; - - for (sector, deals) in sectors.iter() { - let sector_deals = actor_sectors.get(sector)?; - let sector_deals = if let Some(sector_deals) = sector_deals { - sector_deals - } else { - continue; - }; - - let mut sector_deals = sector_deals.clone(); - for deal in deals.iter() { - if let Some(idx) = sector_deals.deals.iter().position(|d| d == deal) { - sector_deals.deals.remove(idx); - } - } - - if sector_deals.deals.is_empty() { - actor_sectors.delete(sector)?; - } else { - actor_sectors.set(sector, sector_deals)?; - } - } - - if !actor_sectors.is_empty() { - let new_actor_sectors_root = actor_sectors.flush()?; - prev_out_provider_sectors.set(provider_id, new_actor_sectors_root)?; - } else { - prev_out_provider_sectors.delete(provider_id)?; - } - } - - for (provider_id, sectors) in provider_sectors.iter() { - let actor_sectors_root = prev_out_provider_sectors.get(provider_id)?; - let mut actor_sectors = if let Some(actor_sectors_root) = actor_sectors_root { - SectorDealsMap::load( - store, - actor_sectors_root, - SECTOR_DEALS_CONFIG, - "sector deals", - )? - } else { - SectorDealsMap::empty(store, SECTOR_DEALS_CONFIG, "sector deals") - }; - - for (sector, deals) in sectors.iter() { - actor_sectors.set( - sector, - SectorDealIDs { - deals: deals.clone(), - }, - )?; - } - - let new_actor_sectors_root = actor_sectors.flush()?; - prev_out_provider_sectors.set(provider_id, new_actor_sectors_root)?; - } - - let out_provider_sectors_root = prev_out_provider_sectors.flush()?; - let out_states = prev_out_states.flush()?; - - Ok((out_provider_sectors_root, out_states)) - } - + /// This method implements the migration logic as outlined in the [FIP-0076](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0076.md#migration) + // > For each deal state object in the market actor state that has a terminated epoch set to -1: + // > * find the corresponding deal proposal object and extract the provider's actor ID; + // > * in the provider's miner state, find the ID of the sector with the corresponding deal ID in sector metadata; + // > * if such a sector cannot be found, assert that the deal's end epoch has passed and use sector ID 0 [1]; + // > * set the new deal state object's sector number to the sector ID found; + // > * add the deal ID to the ProviderSectors mapping for the provider's actor ID and sector number. + // > For each deal state object in the market actor state that has a terminated epoch set to any other value: + // > * set the deal state object's sector number to 0. fn migrate_provider_sectors_and_states_with_scratch( &self, store: &impl Blockstore, states: &Cid, + proposals: &Cid, ) -> anyhow::Result<(Cid, Cid)> { let old_state_array = ArrayOld::::load(states, store)?; - let mut new_state_array = ArrayNew::::new(store); + let mut new_state_array = + ArrayNew::::new_with_bit_width(store, STATES_AMT_BITWIDTH); - let mut provider_sectors: HashMap>> = - HashMap::default(); + let proposals_array = ArrayOld::::load(proposals, store)?; - // https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0076.md#migration - // FIP-0076: For each deal state object in the market actor state that has a terminated epoch set to -1 old_state_array.for_each(|deal_id, old_state| { - let sector_number = if old_state.slash_epoch == -1 { - // find the corresponding deal proposal object and extract the provider's actor ID; - if let Some(sector_id) = self.provider_sectors.deal_to_sector.read().get(&deal_id) { - provider_sectors - .entry(sector_id.miner) - .or_default() - .entry(sector_id.number) - .or_default() - .push(deal_id); - // set the new deal state object's sector number to the sector ID found - sector_id.number + let proposal = proposals_array + .get(deal_id)? + .context("deal proposal not found")?; + + let sector_number = + if old_state.slash_epoch == -1 && proposal.end_epoch >= self.upgrade_epoch { + // find the corresponding deal proposal object and extract the provider's actor ID; + self.provider_sectors + .deal_to_sector + .read() + .get(&deal_id) + .map(|sector_id| sector_id.number) + .unwrap_or(0) } else { 0 - } - } else { - 0 - }; + }; let new_state = DealStateNew { sector_number, @@ -405,7 +161,7 @@ impl MarketMigrator { let mut out_provider_sectors = ProviderSectorsMapNew::empty(store, PROVIDER_SECTORS_CONFIG, "provider sectors"); - for (miner, sectors) in provider_sectors.iter() { + for (miner, sectors) in self.provider_sectors.miner_to_sector_to_deals.read().iter() { let mut actor_sectors = SectorDealsMap::empty(store, SECTOR_DEALS_CONFIG, "sector deals"); @@ -426,19 +182,3 @@ impl MarketMigrator { Ok((out_provider_sectors_root, new_state_array_root)) } } - -fn market_prev_deal_states_in_key(addr: &Address) -> String { - format!("prev_deal_states_in_{addr}") -} - -fn market_prev_deal_proposals_in_key(addr: &Address) -> String { - format!("prev_deal_proposals_in_{addr}") -} - -fn market_prev_deal_states_out_key(addr: &Address) -> String { - format!("prev_deal_states_out_{addr}") -} - -fn market_prev_provider_sectors_out_key(addr: &Address) -> String { - format!("prev_provider_sectors_out_{addr}") -} diff --git a/src/state_migration/nv22/migration.rs b/src/state_migration/nv22/migration.rs index 14f6a22a28ba..f42f348b814d 100644 --- a/src/state_migration/nv22/migration.rs +++ b/src/state_migration/nv22/migration.rs @@ -1,4 +1,4 @@ -// Copyright 2019-2023 ChainSafe Systems +// Copyright 2019-2024 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT // //! This module contains the migration logic for the `NV22` upgrade. State migration logic @@ -7,18 +7,16 @@ use std::sync::Arc; -use crate::make_butterfly_policy; -use crate::networks::{ChainConfig, Height, NetworkChain}; +use crate::networks::{ChainConfig, Height}; use crate::shim::{ address::Address, clock::ChainEpoch, machine::{BuiltinActor, BuiltinActorManifest}, - sector::{RegisteredPoStProofV3, RegisteredSealProofV3}, state_tree::{StateTree, StateTreeVersion}, }; use anyhow::Context; use cid::Cid; -use fil_actors_shared::v12::runtime::ProofSet; + use fvm_ipld_blockstore::Blockstore; use fvm_ipld_encoding::CborStore; @@ -31,8 +29,16 @@ impl StateMigration { store: &Arc, state: &Cid, new_manifest: &BuiltinActorManifest, - chain_config: &ChainConfig, + _chain_config: &ChainConfig, ) -> anyhow::Result<()> { + // TODO: Use the correct epoch for the upgrade once it's fixed in Lotus + //let upgrade_epoch = chain_config + // .height_infos + // .get(&Height::Dragon) + // .context("no height info for network version NV22")? + // .epoch; + let upgrade_epoch = 3654004; + let state_tree = StateTree::new_from_root(store.clone(), state)?; let system_actor = state_tree .get_actor(&Address::new_id(0))? @@ -52,40 +58,6 @@ impl StateMigration { self.add_migrator(code, nil_migrator(new_code)) } - let (policy_old, policy_new) = match &chain_config.network { - NetworkChain::Mainnet => ( - fil_actors_shared::v12::runtime::Policy::mainnet(), - fil_actors_shared::v13::runtime::Policy::mainnet(), - ), - NetworkChain::Calibnet => ( - fil_actors_shared::v12::runtime::Policy::calibnet(), - fil_actors_shared::v13::runtime::Policy::calibnet(), - ), - NetworkChain::Butterflynet => { - (make_butterfly_policy!(v12), make_butterfly_policy!(v13)) - } - NetworkChain::Devnet(_) => { - let mut policy_old = fil_actors_shared::v12::runtime::Policy::mainnet(); - policy_old.minimum_consensus_power = 2048.into(); - policy_old.minimum_verified_allocation_size = 256.into(); - policy_old.pre_commit_challenge_delay = 10; - - let mut proofs = ProofSet::default_seal_proofs(); - proofs.insert(RegisteredSealProofV3::StackedDRG2KiBV1); - proofs.insert(RegisteredSealProofV3::StackedDRG8MiBV1); - policy_old.valid_pre_commit_proof_type = proofs; - - let mut proofs = ProofSet::default_post_proofs(); - proofs.insert(RegisteredPoStProofV3::StackedDRGWindow2KiBV1); - proofs.insert(RegisteredPoStProofV3::StackedDRGWindow8MiBV1); - policy_old.valid_post_proof_type = proofs; - - ( - policy_old, - fil_actors_shared::v13::runtime::Policy::devnet(), - ) - } - }; let miner_old_code = current_manifest.get(BuiltinActor::Miner)?; let miner_new_code = new_manifest.get(BuiltinActor::Miner)?; @@ -96,18 +68,12 @@ impl StateMigration { self.add_migrator( miner_old_code, - miner::miner_migrator( - provider_sectors.clone(), - &policy_old, - &policy_new, - store, - miner_new_code, - )?, + miner::miner_migrator(upgrade_epoch, provider_sectors.clone(), miner_new_code)?, ); self.add_migrator( market_old_code, - market::market_migrator(provider_sectors.clone(), market_new_code)?, + market::market_migrator(upgrade_epoch, provider_sectors.clone(), market_new_code)?, ); self.add_migrator( diff --git a/src/state_migration/nv22/miner.rs b/src/state_migration/nv22/miner.rs index d000b31593b3..3ff1ecdcdc8a 100644 --- a/src/state_migration/nv22/miner.rs +++ b/src/state_migration/nv22/miner.rs @@ -1,54 +1,51 @@ -// Copyright 2019-2023 ChainSafe Systems +// Copyright 2019-2024 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT //! This module contains the migration logic for the `NV22` upgrade for the -//! Miner actor. - -use std::sync::Arc; - -use crate::shim::econ::TokenAmount; -use crate::{ - shim::address::Address, state_migration::common::MigrationCache, utils::db::CborStoreExt, -}; +//! Miner actor. While the `NV22` upgrade does not change the state of the +//! Miner actor, it does change the state of the Market actor, which requires +//! metadata from the Miner actor. +//! +//! As per [FIP-0076](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0076.md#backwards-compatibility) +//! > This proposal requires a state migration to the market actor to add the new ProviderSectors mapping, +//! > and to add a sector number to and remove allocation ID from each DealState. Computing this mapping +//! > requires reading all sector metadata from the miner actor. + +use crate::state_migration::common::{ActorMigration, ActorMigrationInput, ActorMigrationOutput}; use ahash::HashMap; -use anyhow::{bail, Context}; +use anyhow::Context; use cid::Cid; -use fil_actor_miner_state::{v12::State as MinerStateOld, v13::State as MinerStateNew}; -use fil_actors_shared::fvm_ipld_amt; -use fil_actors_shared::v12::{runtime::Policy as PolicyOld, Array as ArrayOld}; -use fil_actors_shared::v13::{runtime::Policy as PolicyNew, Array as ArrayNew}; +use fil_actor_miner_state::v12::State as MinerStateOld; +use fil_actors_shared::v12::Array as ArrayOld; use fvm_ipld_blockstore::Blockstore; use fvm_ipld_encoding::CborStore; +use fvm_shared4::clock::ChainEpoch; use fvm_shared4::deal::DealID; -use fvm_shared4::sector::SectorID; +use fvm_shared4::sector::{SectorID, SectorNumber}; +use fvm_shared4::ActorID; use parking_lot::RwLock; -use tracing::error; - -use crate::state_migration::common::{ - ActorMigration, ActorMigrationInput, ActorMigrationOutput, TypeMigration, TypeMigrator, -}; +use std::sync::Arc; #[derive(Default)] pub struct ProviderSectors { pub deal_to_sector: RwLock>, + pub miner_to_sector_to_deals: RwLock>>>, } pub struct MinerMigrator { + upgrade_epoch: ChainEpoch, provider_sectors: Arc, - policy_new: PolicyNew, out_cid: Cid, } pub(in crate::state_migration) fn miner_migrator( + upgrade_epoch: ChainEpoch, provider_sectors: Arc, - policy_old: &PolicyOld, - policy_new: &PolicyNew, - store: &Arc, out_cid: Cid, ) -> anyhow::Result + Send + Sync>> { Ok(Arc::new(MinerMigrator { + upgrade_epoch, provider_sectors, - policy_new: policy_new.clone(), out_cid, })) } @@ -69,93 +66,31 @@ impl ActorMigration for MinerMigrator { store, )?; - if let Some(prev_sectors_cid) = input.cache.get(&miner_prev_sectors_in_key(&input.address)) - { - let prev_sectors = ArrayOld::::load( - &prev_sectors_cid, - store, - )?; - let diffs = fvm_ipld_amt::diff(&prev_sectors, &in_sectors)?; - - for change in diffs.iter() { - let sector_number = change.key; - match change.change_type() { - fvm_ipld_amt::ChangeType::Add => { - let sector = in_sectors - .get(sector_number)? - .context("Failed to get sector")?; - - if sector.deal_ids.is_empty() { - continue; - } - - let mut sectors = self.provider_sectors.deal_to_sector.write(); - for deal_id in §or.deal_ids { - sectors.insert( - *deal_id, - SectorID { - miner: miner_id, - number: sector_number, - }, - ); - } - } - fvm_ipld_amt::ChangeType::Modify => { - // OhSnap deals - let sector_old = change.before.as_ref().context("Failed to get sector")?; - let sector_new = change.after.as_ref().context("Failed to get sector")?; - - if sector_old.deal_ids.len() != sector_new.deal_ids.len() { - if !sector_old.deal_ids.is_empty() { - error!("old sector: {sector_old:?}, new_sector {sector_new:?}"); - bail!("This is not supported, and should not happen"); - } - - let mut sectors = self.provider_sectors.deal_to_sector.write(); - for deal_id in §or_new.deal_ids { - sectors.insert( - *deal_id, - SectorID { - miner: miner_id, - number: sector_number, - }, - ); - } - } - } - fvm_ipld_amt::ChangeType::Remove => { - // Comment from the Go implementation - // > nothing to do here, market removes deals based on activation/slash status, and can tell what - // > mappings to remove because non-slashed deals already had them - } - }; + in_sectors.for_each(|i, sector| { + if sector.deal_ids.is_empty() || sector.expiration < self.upgrade_epoch { + return Ok(()); } - } else { - // there is no cached migration, so we iterate over all sectors and collect the deal - // ids. - in_sectors.for_each(|_, sector| { - if sector.deal_ids.is_empty() { - return Ok(()); - } - let mut sectors = self.provider_sectors.deal_to_sector.write(); - for (sector_number, deal_id) in sector.deal_ids.iter().enumerate() { - sectors.insert( - *deal_id, - SectorID { - miner: miner_id, - number: sector_number as u64, - }, - ); - } + let mut sectors = self.provider_sectors.deal_to_sector.write(); + for deal_id in sector.deal_ids.iter() { + sectors.insert( + *deal_id, + SectorID { + miner: miner_id, + number: i, + }, + ); + } + drop(sectors); - Ok(()) - })?; - } + let mut sector_deals = self.provider_sectors.miner_to_sector_to_deals.write(); + sector_deals + .entry(miner_id) + .or_default() + .insert(i, sector.deal_ids.clone()); - input - .cache - .insert(miner_prev_sectors_in_key(&input.address), in_state.sectors); + Ok(()) + })?; Ok(Some(ActorMigrationOutput { new_code_cid: self.out_cid, @@ -163,227 +98,3 @@ impl ActorMigration for MinerMigrator { })) } } - -fn miner_prev_sectors_in_key(address: &Address) -> String { - format!("prevSectorsIn-{}", address) -} - -//#[cfg(test)] -//mod tests { -// use super::*; -// use crate::networks::{ChainConfig, Height}; -// use crate::shim::{ -// econ::TokenAmount, -// machine::{BuiltinActor, BuiltinActorManifest}, -// state_tree::{ActorState, StateTree, StateTreeVersion}, -// }; -// use cid::multihash::MultihashDigest; -// use fvm_ipld_encoding::IPLD_RAW; -// use fvm_shared2::bigint::Zero; -// -// #[test] -// fn test_nv21_miner_migration() { -// let store = Arc::new(crate::db::MemoryDB::default()); -// let (mut state_tree_old, manifest_old) = make_input_tree(&store); -// let system_actor_old = state_tree_old -// .get_actor(&fil_actor_interface::system::ADDRESS.into()) -// .unwrap() -// .unwrap(); -// let system_state_old: fil_actor_system_state::v11::State = -// store.get_cbor(&system_actor_old.state).unwrap().unwrap(); -// let manifest_data_cid_old = system_state_old.builtin_actors; -// assert_eq!(manifest_data_cid_old, manifest_old.source_cid()); -// -// let addr_id = 10000; -// let addr = Address::new_id(addr_id); -// let worker_id = addr_id + 100; -// -// // base stuff to create miners -// let miner_cid_old = manifest_old.get(BuiltinActor::Miner).unwrap(); -// let mut miner_state1 = make_base_miner_state(&store, addr_id, worker_id); -// let mut deadline = DeadlineOld::new(&store).unwrap(); -// let mut sectors_snapshot = -// ArrayOld::::new_with_bit_width( -// &store, -// fil_actor_miner_state::v11::SECTORS_AMT_BITWIDTH, -// ); -// sectors_snapshot -// .set( -// 0, -// fil_actor_miner_state::v11::SectorOnChainInfo { -// simple_qa_power: true, -// ..Default::default() -// }, -// ) -// .unwrap(); -// sectors_snapshot -// .set( -// 1, -// fil_actor_miner_state::v11::SectorOnChainInfo { -// simple_qa_power: false, -// ..Default::default() -// }, -// ) -// .unwrap(); -// deadline.sectors_snapshot = sectors_snapshot.flush().unwrap(); -// let deadline_cid = store.put_cbor_default(&deadline).unwrap(); -// let deadlines = DeadlinesOld::new( -// &fil_actors_shared::v11::runtime::Policy::calibnet(), -// deadline_cid, -// ); -// miner_state1.deadlines = store.put_cbor_default(&deadlines).unwrap(); -// -// let miner1_state_cid = store.put_cbor_default(&miner_state1).unwrap(); -// let miner1 = ActorState::new(miner_cid_old, miner1_state_cid, Zero::zero(), 0, None); -// state_tree_old.set_actor(&addr, miner1).unwrap(); -// let tree_root = state_tree_old.flush().unwrap(); -// -// let (new_manifest_cid, _new_manifest) = make_test_manifest(&store, "fil/12/"); -// -// let mut chain_config = ChainConfig::devnet(); -// if let Some(bundle) = &mut chain_config.height_infos[Height::Watermelon as usize].bundle { -// *bundle = new_manifest_cid; -// } -// let new_state_cid = -// super::super::run_migration(&chain_config, &store, &tree_root, 200).unwrap(); -// -// let new_state_cid2 = -// super::super::run_migration(&chain_config, &store, &tree_root, 200).unwrap(); -// -// assert_eq!(new_state_cid, new_state_cid2); -// -// let new_state_tree = StateTree::new_from_root(store.clone(), &new_state_cid).unwrap(); -// let new_miner_state_cid = new_state_tree.get_actor(&addr).unwrap().unwrap().state; -// let new_miner_state: fil_actor_miner_state::v12::State = -// store.get_cbor(&new_miner_state_cid).unwrap().unwrap(); -// let deadlines: fil_actor_miner_state::v12::Deadlines = -// store.get_cbor(&new_miner_state.deadlines).unwrap().unwrap(); -// deadlines -// .for_each(&store, |_, deadline| { -// let sectors_snapshots = -// ArrayNew::::load( -// &deadline.sectors_snapshot, -// &store, -// ) -// .unwrap(); -// assert_eq!( -// sectors_snapshots.get(0).unwrap().unwrap().flags, -// fil_actor_miner_state::v12::SectorOnChainInfoFlags::SIMPLE_QA_POWER -// ); -// assert!(!sectors_snapshots -// .get(1) -// .unwrap() -// .unwrap() -// .flags -// .contains(fil_actor_miner_state::v12::SectorOnChainInfoFlags::SIMPLE_QA_POWER)); -// Ok(()) -// }) -// .unwrap(); -// } -// -// fn make_input_tree(store: &Arc) -> (StateTree, BuiltinActorManifest) { -// let mut tree = StateTree::new(store.clone(), StateTreeVersion::V5).unwrap(); -// -// let (_manifest_cid, manifest) = make_test_manifest(&store, "fil/11/"); -// let system_cid = manifest.get_system(); -// let system_state = fil_actor_system_state::v11::State { -// builtin_actors: manifest.source_cid(), -// }; -// let system_state_cid = store.put_cbor_default(&system_state).unwrap(); -// init_actor( -// &mut tree, -// system_state_cid, -// system_cid, -// &fil_actor_interface::system::ADDRESS.into(), -// Zero::zero(), -// ); -// -// let init_cid = manifest.get_init(); -// let init_state = -// fil_actor_init_state::v11::State::new(&store, "migrationtest".into()).unwrap(); -// let init_state_cid = store.put_cbor_default(&init_state).unwrap(); -// init_actor( -// &mut tree, -// init_state_cid, -// init_cid, -// &fil_actor_interface::init::ADDRESS.into(), -// Zero::zero(), -// ); -// -// tree.flush().unwrap(); -// -// (tree, manifest) -// } -// -// fn init_actor( -// tree: &mut StateTree, -// state: Cid, -// code: Cid, -// addr: &Address, -// balance: TokenAmount, -// ) { -// let actor = ActorState::new(code, state, balance, 0, None); -// tree.set_actor(addr, actor).unwrap(); -// } -// -// fn make_test_manifest(store: &BS, prefix: &str) -> (Cid, BuiltinActorManifest) { -// let mut manifest_data = vec![]; -// for name in [ -// "account", -// "cron", -// "init", -// "storagemarket", -// "storageminer", -// "multisig", -// "paymentchannel", -// "storagepower", -// "reward", -// "system", -// "verifiedregistry", -// "datacap", -// ] { -// let hash = cid::multihash::Code::Identity.digest(format!("{prefix}{name}").as_bytes()); -// let code_cid = Cid::new_v1(IPLD_RAW, hash); -// manifest_data.push((name, code_cid)); -// } -// -// let manifest_cid = store -// .put_cbor_default(&(1, store.put_cbor_default(&manifest_data).unwrap())) -// .unwrap(); -// let manifest = BuiltinActorManifest::load_manifest(store, &manifest_cid).unwrap(); -// -// (manifest_cid, manifest) -// } -// -// fn make_base_miner_state( -// store: &BS, -// owner: fvm_shared3::ActorID, -// worker: fvm_shared3::ActorID, -// ) -> fil_actor_miner_state::v11::State { -// let control_addresses = vec![]; -// let peer_id = vec![]; -// let multi_address = vec![]; -// let window_post_proof_type = -// fvm_shared3::sector::RegisteredPoStProof::StackedDRGWindow2KiBV1; -// let miner_info = fil_actor_miner_state::v11::MinerInfo::new( -// owner, -// worker, -// control_addresses, -// peer_id, -// multi_address, -// window_post_proof_type, -// ) -// .unwrap(); -// -// let miner_info_cid = store.put_cbor_default(&miner_info).unwrap(); -// -// fil_actor_miner_state::v11::State::new( -// &fil_actors_shared::v11::runtime::Policy::calibnet(), -// store, -// miner_info_cid, -// 0, -// 0, -// ) -// .unwrap() -// } -//} diff --git a/src/state_migration/nv22/mod.rs b/src/state_migration/nv22/mod.rs index 7cb1956a3955..2289a0659ce9 100644 --- a/src/state_migration/nv22/mod.rs +++ b/src/state_migration/nv22/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2019-2023 ChainSafe Systems +// Copyright 2019-2024 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT //! This module contains the migration logic for the `NV22` upgrade. From cf5324670654b7bc8dd23be61e2ecd1cc96c137c Mon Sep 17 00:00:00 2001 From: Hubert Bugaj Date: Tue, 5 Mar 2024 17:42:15 +0100 Subject: [PATCH 3/7] new bundle --- Cargo.lock | 104 +++++++++++--------------- Cargo.toml | 25 ++++--- scripts/devnet/lotus.dockerfile | 2 +- src/networks/actors_bundle.rs | 2 +- src/networks/devnet/mod.rs | 2 +- src/state_migration/nv17/datacap.rs | 4 +- src/state_migration/nv22/migration.rs | 14 ++-- 7 files changed, 66 insertions(+), 87 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f1626285d21c..f91fe0c0700d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2738,11 +2738,11 @@ checksum = "1676f435fc1dadde4d03e43f5d62b259e1ce5f40bd4ffb21db2b42ebe59c1382" [[package]] name = "fil_actor_account_state" -version = "10.0.0-dev.2" +version = "10.0.0-dev.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b8d8a278388a502cbe22c7359eaa393eac4451f5accbd977eaee52a28275aaf" +checksum = "c94732b4360fa5796fe0f0524b62d4b7f9081c0001e45e44e1969511ad237a68" dependencies = [ - "frc42_macros 3.0.0", + "frc42_macros", "fvm_ipld_encoding", "fvm_shared 2.6.0", "fvm_shared 3.6.0", @@ -2754,9 +2754,9 @@ dependencies = [ [[package]] name = "fil_actor_cron_state" -version = "10.0.0-dev.2" +version = "10.0.0-dev.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a0601edd6fe61bbcf574371c5502768d7716a55d233234b5e4c1e5693b3c055" +checksum = "29941aeb04a17810b8d2104e0f0e4fa10001393e7a1d3523631196d7922fbc2f" dependencies = [ "fvm_ipld_encoding", "fvm_shared 2.6.0", @@ -2769,12 +2769,12 @@ dependencies = [ [[package]] name = "fil_actor_datacap_state" -version = "10.0.0-dev.2" +version = "10.0.0-dev.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3cf2aa6bc17e28a599555d216c2e095aad55cdf0a2e0f66dbd705bf913db5f4" +checksum = "091aa98dfbb933274389c5be9348590e168548b15b886bd2eafbff7c13ecef23" dependencies = [ "fil_actors_shared", - "frc42_macros 3.0.0", + "frc42_macros", "frc46_token", "fvm_ipld_blockstore", "fvm_ipld_encoding", @@ -2789,13 +2789,13 @@ dependencies = [ [[package]] name = "fil_actor_evm_state" -version = "10.0.0-dev.2" +version = "10.0.0-dev.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58b746a3dad083daf72be0f2757efa82849b3a45601b8e70362d81b5e73fa235" +checksum = "539689549dd7c11fa9139a8adce2568fcbcab1383edf152e5cba45061df6d3d2" dependencies = [ "cid", "fil_actors_shared", - "frc42_macros 3.0.0", + "frc42_macros", "fvm_ipld_encoding", "fvm_shared 3.6.0", "fvm_shared 4.1.2", @@ -2809,14 +2809,14 @@ dependencies = [ [[package]] name = "fil_actor_init_state" -version = "10.0.0-dev.2" +version = "10.0.0-dev.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84f37e7340dc021d20ef5ea36dfb52f173262d10184b1c924106c328427c5197" +checksum = "ed980044e180910897862014dc237448f44c7f7600470a9357458b8c7d1ea0bc" dependencies = [ "anyhow", "cid", "fil_actors_shared", - "frc42_macros 3.0.0", + "frc42_macros", "fvm_ipld_blockstore", "fvm_ipld_encoding", "fvm_ipld_hamt 0.9.0", @@ -2830,9 +2830,9 @@ dependencies = [ [[package]] name = "fil_actor_interface" -version = "10.0.0-dev.2" +version = "10.0.0-dev.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27f5867b4ba96b9c5ff93ed10cfd6b313a5e59862d32599680c6d93daf325049" +checksum = "ab089bd0e43f98c8bdccdec814e14c74c631b73ee832f16d313bbb8ba9cecc1e" dependencies = [ "anyhow", "cid", @@ -2868,15 +2868,15 @@ dependencies = [ [[package]] name = "fil_actor_market_state" -version = "10.0.0-dev.2" +version = "10.0.0-dev.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0bc8c9746c93f9b6ac90240ca74f0b060bc78751b16c36f07618913854c0270" +checksum = "f0c76cad842778e6aa42e9defdcdea0553072ff6f0c0aa41242fd00f265b8d9d" dependencies = [ "anyhow", "cid", "fil_actor_verifreg_state", "fil_actors_shared", - "frc42_macros 3.0.0", + "frc42_macros", "fvm_ipld_bitfield", "fvm_ipld_blockstore", "fvm_ipld_encoding", @@ -2893,16 +2893,16 @@ dependencies = [ [[package]] name = "fil_actor_miner_state" -version = "10.0.0-dev.2" +version = "10.0.0-dev.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "722f6e09d9114e4b10c5c22299200f34b0b2a82693735b64cb98b13bab9ebca4" +checksum = "7022542811937e9b5d722586f0b17037561ef7cd3f0c35ce4c849a20da7c744d" dependencies = [ "anyhow", "bitflags 2.4.2", "cid", "fil_actor_verifreg_state", "fil_actors_shared", - "frc42_macros 3.0.0", + "frc42_macros", "fvm_ipld_amt", "fvm_ipld_bitfield", "fvm_ipld_blockstore", @@ -2923,14 +2923,14 @@ dependencies = [ [[package]] name = "fil_actor_multisig_state" -version = "10.0.0-dev.2" +version = "10.0.0-dev.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34878068dd52157eb581aa7533cf9a9bfe6f771eeed7b2299a97220b96880701" +checksum = "b8738df800e7cb4d350717ebc20d74fffaf26c9298108e03e5458a4690760797" dependencies = [ "anyhow", "cid", "fil_actors_shared", - "frc42_macros 3.0.0", + "frc42_macros", "fvm_ipld_blockstore", "fvm_ipld_encoding", "fvm_ipld_hamt 0.9.0", @@ -2946,14 +2946,14 @@ dependencies = [ [[package]] name = "fil_actor_power_state" -version = "10.0.0-dev.2" +version = "10.0.0-dev.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cc4e0b040fea3f81cb0ae1c829ce50024045d75021b582dcb1965f85bc59926" +checksum = "7a1996681dae26388ae9a30fb9fcefebda66e56b470b78a887b9b995cbb9a8f7" dependencies = [ "anyhow", "cid", "fil_actors_shared", - "frc42_macros 3.0.0", + "frc42_macros", "fvm_ipld_blockstore", "fvm_ipld_encoding", "fvm_ipld_hamt 0.9.0", @@ -2969,9 +2969,9 @@ dependencies = [ [[package]] name = "fil_actor_reward_state" -version = "10.0.0-dev.2" +version = "10.0.0-dev.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdd400b1ef2e5ac539dec5b94d7861747009fdf34fcdfc8e92666d2d5adb852f" +checksum = "8dc9c0958524a3413cf72974b715fbae5bf57407f914ef1ca129624b4fcd7a58" dependencies = [ "fvm_ipld_encoding", "fvm_shared 2.6.0", @@ -2985,9 +2985,9 @@ dependencies = [ [[package]] name = "fil_actor_system_state" -version = "10.0.0-dev.2" +version = "10.0.0-dev.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70369b47e9e11da6f7cc09edc7b3ec773e706113b83286af0cc2ca5377d6369c" +checksum = "1b6cdcc5a6a21fb639853cb828fe2625aa1e792439db1161681f866ecbbc594e" dependencies = [ "cid", "fil_actors_shared", @@ -3002,14 +3002,14 @@ dependencies = [ [[package]] name = "fil_actor_verifreg_state" -version = "10.0.0-dev.2" +version = "10.0.0-dev.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32259ec6139952b11abbb0a558128cccee44c58a460e1bcb9449e62ac6e9f25f" +checksum = "62e9394839dd721f7cdbbafd82747ec9daa4b6229e1bc1c7f014366216fc3a60" dependencies = [ "anyhow", "cid", "fil_actors_shared", - "frc42_macros 3.0.0", + "frc42_macros", "fvm_ipld_blockstore", "fvm_ipld_encoding", "fvm_shared 2.6.0", @@ -3022,13 +3022,14 @@ dependencies = [ [[package]] name = "fil_actors_shared" -version = "10.0.0-dev.2" +version = "10.0.0-dev.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e8194ff60ad006523bd2b4799c90ff69c2e3e5c719124e310568ac93437bfce" +checksum = "fa8b5e64f9b025625f7f667dc90e729d350fddae0f464c119b2d7436a79800f2" dependencies = [ "anyhow", "cid", "filecoin-proofs-api", + "frc46_token", "fvm_ipld_amt", "fvm_ipld_bitfield", "fvm_ipld_blockstore", @@ -3267,6 +3268,7 @@ dependencies = [ "fil_actors_shared", "filecoin-proofs-api", "flume 0.11.0", + "frc46_token", "fs_extra", "futures", "fvm 2.7.0", @@ -3430,22 +3432,13 @@ version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a1704e27193af21e58435974ff20f2be25cc59338afb89920abdb540ad3182b" dependencies = [ - "frc42_hasher 4.0.0", - "frc42_macros 4.0.0", + "frc42_hasher", + "frc42_macros", "fvm_ipld_encoding", "fvm_shared 4.1.2", "thiserror", ] -[[package]] -name = "frc42_hasher" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08a35e7214108f81cefc17b0466be01279f384faf913918a12dbc8528bb758a4" -dependencies = [ - "thiserror", -] - [[package]] name = "frc42_hasher" version = "4.0.0" @@ -3457,19 +3450,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "frc42_macros" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f50cd62b077775194bde67eef8076b31f915b9c099f3a7fd1a760363d65f145" -dependencies = [ - "blake2b_simd", - "frc42_hasher 3.0.0", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "frc42_macros" version = "4.0.0" @@ -3477,7 +3457,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a9ce38a981bab5e0d3c0835baa86f83066afe9afaf0aec23cee421f6d8c628e" dependencies = [ "blake2b_simd", - "frc42_hasher 4.0.0", + "frc42_hasher", "proc-macro2", "quote", "syn 1.0.109", diff --git a/Cargo.toml b/Cargo.toml index 4c7655879e03..436ea298b622 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,18 +52,19 @@ dialoguer = "0.11" digest = "0.10.5" directories = "5" ethereum-types = "0.14.1" -fil_actor_account_state = { version = "10.0.0-dev.2" } -fil_actor_cron_state = { version = "10.0.0-dev.2" } -fil_actor_datacap_state = { version = "10.0.0-dev.2" } -fil_actor_init_state = { version = "10.0.0-dev.2" } -fil_actor_interface = { version = "10.0.0-dev.2" } -fil_actor_market_state = { version = "10.0.0-dev.2" } -fil_actor_miner_state = { version = "10.0.0-dev.2" } -fil_actor_power_state = { version = "10.0.0-dev.2" } -fil_actor_reward_state = { version = "10.0.0-dev.2" } -fil_actor_system_state = { version = "10.0.0-dev.2" } -fil_actor_verifreg_state = { version = "10.0.0-dev.2" } -fil_actors_shared = { version = "10.0.0-dev.2", features = ["json"] } +frc46_token = "10.0.0" +fil_actor_account_state = { version = "10.0.0-dev.4" } +fil_actor_cron_state = { version = "10.0.0-dev.4" } +fil_actor_datacap_state = { version = "10.0.0-dev.4" } +fil_actor_init_state = { version = "10.0.0-dev.4" } +fil_actor_interface = { version = "10.0.0-dev.4" } +fil_actor_market_state = { version = "10.0.0-dev.4" } +fil_actor_miner_state = { version = "10.0.0-dev.4" } +fil_actor_power_state = { version = "10.0.0-dev.4" } +fil_actor_reward_state = { version = "10.0.0-dev.4" } +fil_actor_system_state = { version = "10.0.0-dev.4" } +fil_actor_verifreg_state = { version = "10.0.0-dev.4" } +fil_actors_shared = { version = "10.0.0-dev.4", features = ["json"] } filecoin-proofs-api = { version = "16.0", default-features = false } flume = "0.11" fs_extra = "1.2" diff --git a/scripts/devnet/lotus.dockerfile b/scripts/devnet/lotus.dockerfile index 26f4112b4b71..33d6b393c717 100644 --- a/scripts/devnet/lotus.dockerfile +++ b/scripts/devnet/lotus.dockerfile @@ -5,7 +5,7 @@ RUN apt-get update && apt-get install -y ca-certificates build-essential clang o WORKDIR /lotus -RUN git clone --depth 1 --branch asr/migration-nv22 https://github.com/filecoin-project/lotus.git . +RUN git clone --depth 1 --branch release/v1.26.0 https://github.com/filecoin-project/lotus.git . RUN CGO_CFLAGS_ALLOW="-D__BLST_PORTABLE__" \ CGO_CFLAGS="-D__BLST_PORTABLE__" \ diff --git a/src/networks/actors_bundle.rs b/src/networks/actors_bundle.rs index 38aa39784f25..678ebd5f652a 100644 --- a/src/networks/actors_bundle.rs +++ b/src/networks/actors_bundle.rs @@ -76,7 +76,7 @@ pub static ACTOR_BUNDLES: Lazy> = Lazy::new(|| { "bafy2bzacebzz376j5kizfck56366kdz5aut6ktqrvqbi3efa2d4l2o2m653ts" @ "v10.0.0" for "devnet", "bafy2bzaceay35go4xbjb45km6o46e5bib3bi46panhovcbedrynzwmm3drr4i" @ "v11.0.0" for "devnet", "bafy2bzaceasjdukhhyjbegpli247vbf5h64f7uvxhhebdihuqsj2mwisdwa6o" @ "v12.0.0" for "devnet", - "bafy2bzacedok4fxofxdwkv42whkkukf3g4jwevui4kk5bw7b5unx4t3tjlrya" @ "v13.0.0-rc.2" for "devnet", + "bafy2bzaceap34qfq4emg4fp3xd7bxtzt7pvkaj37kunqm2ccvttchtlljw7d4" @ "v13.0.0-rc.3" for "devnet", "bafy2bzaceb6j6666h36xnhksu3ww4kxb6e25niayfgkdnifaqi6m6ooc66i6i" @ "v9.0.3" for "mainnet", "bafy2bzacecsuyf7mmvrhkx2evng5gnz5canlnz2fdlzu2lvcgptiq2pzuovos" @ "v10.0.0" for "mainnet", "bafy2bzacecnhaiwcrpyjvzl4uv4q3jzoif26okl3m66q3cijp3dfwlcxwztwo" @ "v11.0.0" for "mainnet", diff --git a/src/networks/devnet/mod.rs b/src/networks/devnet/mod.rs index 59dc0665e4b1..107833f57bf5 100644 --- a/src/networks/devnet/mod.rs +++ b/src/networks/devnet/mod.rs @@ -70,7 +70,7 @@ pub static HEIGHT_INFOS: Lazy> = Lazy::new(|| { HeightInfo { epoch: get_upgrade_height_from_env("FOREST_DRAGON_HEIGHT").unwrap_or(20), bundle: Some( - Cid::try_from("bafy2bzacedok4fxofxdwkv42whkkukf3g4jwevui4kk5bw7b5unx4t3tjlrya") + Cid::try_from("bafy2bzaceap34qfq4emg4fp3xd7bxtzt7pvkaj37kunqm2ccvttchtlljw7d4") .unwrap(), ), }, diff --git a/src/state_migration/nv17/datacap.rs b/src/state_migration/nv17/datacap.rs index 01f4ecf1dd92..fc56e316ca25 100644 --- a/src/state_migration/nv17/datacap.rs +++ b/src/state_migration/nv17/datacap.rs @@ -14,6 +14,7 @@ use crate::state_migration::common::PostMigrator; use crate::utils::db::CborStoreExt; use cid::Cid; use fil_actors_shared::fvm_ipld_hamt::BytesKey; +use frc46_token::token::state::TokenState; use fvm_ipld_blockstore::Blockstore; use num_traits::Zero; use once_cell::sync::Lazy; @@ -73,8 +74,7 @@ impl PostMigrator for DataCapPostMigrator { verifreg_balance.into(), )?; - let mut token = - fil_actors_shared::frc46_token::TokenState::new_with_bit_width(&store, HAMT_BIT_WIDTH)?; + let mut token = TokenState::new(store)?; token.supply = TokenAmount::from_atto(token_supply).into(); token.balances = balances_map.flush()?; token.allowances = allowances_map.flush()?; diff --git a/src/state_migration/nv22/migration.rs b/src/state_migration/nv22/migration.rs index f42f348b814d..7a6591336814 100644 --- a/src/state_migration/nv22/migration.rs +++ b/src/state_migration/nv22/migration.rs @@ -29,15 +29,13 @@ impl StateMigration { store: &Arc, state: &Cid, new_manifest: &BuiltinActorManifest, - _chain_config: &ChainConfig, + chain_config: &ChainConfig, ) -> anyhow::Result<()> { - // TODO: Use the correct epoch for the upgrade once it's fixed in Lotus - //let upgrade_epoch = chain_config - // .height_infos - // .get(&Height::Dragon) - // .context("no height info for network version NV22")? - // .epoch; - let upgrade_epoch = 3654004; + let upgrade_epoch = chain_config + .height_infos + .get(&Height::Dragon) + .context("no height info for network version NV22")? + .epoch; let state_tree = StateTree::new_from_root(store.clone(), state)?; let system_actor = state_tree From 515753f9bd506ca345135dde2ab6b7bed3fee245 Mon Sep 17 00:00:00 2001 From: Hubert Date: Thu, 7 Mar 2024 12:17:02 +0100 Subject: [PATCH 4/7] Butterflynet nv22 (#4028) --- build/bootstrap/butterflynet | 4 ++-- src/networks/actors_bundle.rs | 2 +- src/networks/butterflynet/mod.rs | 38 +++++++++++++++++++++----------- src/networks/mod.rs | 2 +- src/state_migration/mod.rs | 2 +- 5 files changed, 30 insertions(+), 18 deletions(-) diff --git a/build/bootstrap/butterflynet b/build/bootstrap/butterflynet index 0646d83fcecc..26378350f6cf 100644 --- a/build/bootstrap/butterflynet +++ b/build/bootstrap/butterflynet @@ -1,2 +1,2 @@ -/dns4/bootstrap-0.butterfly.fildev.network/tcp/1347/p2p/12D3KooWFbgk3NSUv7u3kYqLUfVi5ycmzkVoCMA6DFWNJScazsh1 -/dns4/bootstrap-1.butterfly.fildev.network/tcp/1347/p2p/12D3KooWLsnUi7HD2camXmvhmfHke53krsbFfFf5eHh6g2G3m2Nt +/dns4/bootstrap-0.butterfly.fildev.network/tcp/1347/p2p/12D3KooWQDmegAZg23vAgxoGzRsYb8Ma4oW2p759QrGyC9Y6Bszu +/dns4/bootstrap-1.butterfly.fildev.network/tcp/1347/p2p/12D3KooWNi7kCgFSNDKMuKu1ng8LCZtB1rWVy4yZG8UDWyUdLaDM diff --git a/src/networks/actors_bundle.rs b/src/networks/actors_bundle.rs index 678ebd5f652a..feaebe03b793 100644 --- a/src/networks/actors_bundle.rs +++ b/src/networks/actors_bundle.rs @@ -70,8 +70,8 @@ pub static ACTOR_BUNDLES: Lazy> = Lazy::new(|| { "bafy2bzacebl4w5ptfvuw6746w7ev562idkbf5ppq72e6zub22435ws2rukzru" @ "v12.0.0-rc.2" for "calibrationnet", "bafy2bzacednzb3pkrfnbfhmoqtb3bc6dgvxszpqklf3qcc7qzcage4ewzxsca" @ "v12.0.0" for "calibrationnet", "bafy2bzaceap46ftyyuhninmzelt2ev6kus5itrggszrk5wuhzf2khm47dtrfa" @ "v13.0.0-rc.2" for "calibrationnet", - "bafy2bzaceaiy4dsxxus5xp5n5i4tjzkb7sc54mjz7qnk2efhgmsrobjesxnza" @ "v11.0.0" for "butterflynet", "bafy2bzacectxvbk77ntedhztd6sszp2btrtvsmy7lp2ypnrk6yl74zb34t2cq" @ "v12.0.0" for "butterflynet", + "bafy2bzaceaqx5xa4cwso24rjiu2ketjlztrqlac6dkyol7tlyuhzrle3zfbos" @ "v13.0.0-rc.3" for "butterflynet", "bafy2bzacedozk3jh2j4nobqotkbofodq4chbrabioxbfrygpldgoxs3zwgggk" @ "v9.0.3" for "devnet", "bafy2bzacebzz376j5kizfck56366kdz5aut6ktqrvqbi3efa2d4l2o2m653ts" @ "v10.0.0" for "devnet", "bafy2bzaceay35go4xbjb45km6o46e5bib3bi46panhovcbedrynzwmm3drr4i" @ "v11.0.0" for "devnet", diff --git a/src/networks/butterflynet/mod.rs b/src/networks/butterflynet/mod.rs index ee5f7476ad36..2978b777efe5 100644 --- a/src/networks/butterflynet/mod.rs +++ b/src/networks/butterflynet/mod.rs @@ -10,7 +10,10 @@ use url::Url; use crate::{db::SettingsStore, utils::net::http_get}; -use super::{drand::DRAND_MAINNET, parse_bootstrap_peers, DrandPoint, Height, HeightInfo}; +use super::{ + drand::{DRAND_MAINNET, DRAND_QUICKNET}, + get_upgrade_height_from_env, parse_bootstrap_peers, DrandPoint, Height, HeightInfo, +}; /// Fetches the genesis CAR from the local database or downloads it if it does not exist. /// The result bytes may be compressed. @@ -32,7 +35,7 @@ pub async fn fetch_genesis(db: &DB) -> anyhow::Result /// Genesis CID pub static GENESIS_CID: Lazy = Lazy::new(|| { - Cid::from_str("bafy2bzacecl7vdlut572ia64cskp3onngc5ii6co2vsdoshc6ehcx7bful5oo").unwrap() + Cid::from_str("bafy2bzaceca7iggnglnsntfmtqvpsmolzvbuyzhpoq55wzubq65jasnkqxuh6").unwrap() }); /// Compressed genesis file. It is compressed with zstd and cuts the download size by 80% (from 10 MB to 2 MB). @@ -47,7 +50,7 @@ static GENESIS_URL: Lazy = Lazy::new(|| { /// The genesis file does not live on the `master` branch, currently on a draft PR. /// `` static GENESIS_URL_ALT: Lazy = Lazy::new(|| { - "https://github.com/filecoin-project/lotus/raw/3e379c9997bf152639a593d3efee49b88fee27ec/build/genesis/butterflynet.car".parse().expect("hard-coded URL must parse") + "https://github.com/filecoin-project/lotus/raw/3331a7e52c97e5723fc0c613271a616bb3ccdb39/build/genesis/butterflynet.car".parse().expect("hard-coded URL must parse") }); pub(crate) const MINIMUM_CONSENSUS_POWER: i64 = 2 << 30; @@ -65,21 +68,21 @@ pub const ETH_CHAIN_ID: u64 = 3141592; pub static HEIGHT_INFOS: Lazy> = Lazy::new(|| { HashMap::from_iter([ ( - Height::Thunder, + Height::Watermelon, HeightInfo { epoch: -1, bundle: Some( - Cid::try_from("bafy2bzaceaiy4dsxxus5xp5n5i4tjzkb7sc54mjz7qnk2efhgmsrobjesxnza") + Cid::try_from("bafy2bzacectxvbk77ntedhztd6sszp2btrtvsmy7lp2ypnrk6yl74zb34t2cq") .unwrap(), ), }, ), ( - Height::Watermelon, + Height::Dragon, HeightInfo { - epoch: 400, + epoch: 2600, bundle: Some( - Cid::try_from("bafy2bzacectxvbk77ntedhztd6sszp2btrtvsmy7lp2ypnrk6yl74zb34t2cq") + Cid::try_from("bafy2bzaceaqx5xa4cwso24rjiu2ketjlztrqlac6dkyol7tlyuhzrle3zfbos") .unwrap(), ), }, @@ -87,11 +90,18 @@ pub static HEIGHT_INFOS: Lazy> = Lazy::new(|| { ]) }); -pub(super) static DRAND_SCHEDULE: Lazy<[DrandPoint<'static>; 1]> = Lazy::new(|| { - [DrandPoint { - height: 0, - config: &DRAND_MAINNET, - }] +pub(super) static DRAND_SCHEDULE: Lazy<[DrandPoint<'static>; 2]> = Lazy::new(|| { + [ + DrandPoint { + height: 0, + config: &DRAND_MAINNET, + }, + DrandPoint { + height: get_upgrade_height_from_env("FOREST_DRAND_QUICKNET_HEIGHT") + .unwrap_or(HEIGHT_INFOS.get(&Height::Dragon).unwrap().epoch + 120), + config: &DRAND_QUICKNET, + }, + ] }); /// Creates a new butterfly policy with the given version. @@ -161,10 +171,12 @@ mod tests { let v10 = make_butterfly_policy!(v10); let v11 = make_butterfly_policy!(v11); let v12 = make_butterfly_policy!(v12); + let v13 = make_butterfly_policy!(v13); // basic sanity checks assert_eq!(v10.minimum_consensus_power, MINIMUM_CONSENSUS_POWER.into()); assert_eq!(v11.minimum_consensus_power, MINIMUM_CONSENSUS_POWER.into()); assert_eq!(v12.minimum_consensus_power, MINIMUM_CONSENSUS_POWER.into()); + assert_eq!(v13.minimum_consensus_power, MINIMUM_CONSENSUS_POWER.into()); } } diff --git a/src/networks/mod.rs b/src/networks/mod.rs index 1d529bff99e0..8719b592ccc0 100644 --- a/src/networks/mod.rs +++ b/src/networks/mod.rs @@ -64,7 +64,7 @@ impl Display for NetworkChain { match self { NetworkChain::Mainnet => write!(f, "mainnet"), NetworkChain::Calibnet => write!(f, "calibnet"), - NetworkChain::Butterflynet => write!(f, "Butterflynet"), + NetworkChain::Butterflynet => write!(f, "butterflynet"), NetworkChain::Devnet(name) => write!(f, "{name}"), } } diff --git a/src/state_migration/mod.rs b/src/state_migration/mod.rs index 2946537d205e..363ec1b68fc9 100644 --- a/src/state_migration/mod.rs +++ b/src/state_migration/mod.rs @@ -58,7 +58,7 @@ where ] } NetworkChain::Butterflynet => { - vec![(Height::Watermelon, nv21::run_migration::)] + vec![(Height::Dragon, nv22::run_migration::)] } NetworkChain::Devnet(_) => { vec![ From 46a0d0449ce1f275ea0ca9f3da3bf56dc5b13cdd Mon Sep 17 00:00:00 2001 From: Hubert Bugaj Date: Thu, 7 Mar 2024 12:28:20 +0100 Subject: [PATCH 5/7] fix bitwidth nv17 bug --- src/state_migration/nv17/datacap.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/state_migration/nv17/datacap.rs b/src/state_migration/nv17/datacap.rs index fc56e316ca25..cfeedd37b046 100644 --- a/src/state_migration/nv17/datacap.rs +++ b/src/state_migration/nv17/datacap.rs @@ -74,7 +74,7 @@ impl PostMigrator for DataCapPostMigrator { verifreg_balance.into(), )?; - let mut token = TokenState::new(store)?; + let mut token = TokenState::new_with_bit_width(store, HAMT_BIT_WIDTH)?; token.supply = TokenAmount::from_atto(token_supply).into(); token.balances = balances_map.flush()?; token.allowances = allowances_map.flush()?; From 0754f352649aec28f0fa6439478de704de462ebe Mon Sep 17 00:00:00 2001 From: Hubert Bugaj Date: Thu, 7 Mar 2024 13:53:13 +0100 Subject: [PATCH 6/7] self-review --- CHANGELOG.md | 3 +++ Cargo.toml | 2 +- scripts/devnet/.env | 20 ++++++++++---------- scripts/devnet/lotus.dockerfile | 2 +- src/networks/actors_bundle.rs | 4 ++-- src/networks/butterflynet/mod.rs | 2 +- src/networks/calibnet/mod.rs | 26 ++++++++++++++++---------- src/networks/devnet/mod.rs | 3 --- src/networks/mainnet/mod.rs | 9 +++++---- src/state_migration/nv21/mod.rs | 5 ++--- src/state_migration/nv22/miner.rs | 4 ++-- 11 files changed, 43 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a121854096c..4ddf0b02d15b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,9 @@ `Filecoin.NetAgentVersion` and `--agent` flag to the `forest-cli net peers` subcommand, that will list the agent version of the connected peers. +- [#3995](https://github.com/ChainSafe/forest/pull/3955) Added support for the + NV22 _Dragon_ network upgrade, together with the required state migration. + ### Changed ### Removed diff --git a/Cargo.toml b/Cargo.toml index 436ea298b622..406c1caf0000 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,7 +52,6 @@ dialoguer = "0.11" digest = "0.10.5" directories = "5" ethereum-types = "0.14.1" -frc46_token = "10.0.0" fil_actor_account_state = { version = "10.0.0-dev.4" } fil_actor_cron_state = { version = "10.0.0-dev.4" } fil_actor_datacap_state = { version = "10.0.0-dev.4" } @@ -67,6 +66,7 @@ fil_actor_verifreg_state = { version = "10.0.0-dev.4" } fil_actors_shared = { version = "10.0.0-dev.4", features = ["json"] } filecoin-proofs-api = { version = "16.0", default-features = false } flume = "0.11" +frc46_token = "10.0.0" fs_extra = "1.2" futures = "0.3" fvm2 = { package = "fvm", version = "~2.7", default-features = false } diff --git a/scripts/devnet/.env b/scripts/devnet/.env index 3426aee7ac22..e4d2fc77dbbd 100644 --- a/scripts/devnet/.env +++ b/scripts/devnet/.env @@ -1,4 +1,4 @@ -LOTUS_IMAGE=lotus-devnet +LOTUS_IMAGE=ghcr.io/chainsafe/lotus-devnet:2024-03-07-b74be0f FOREST_DATA_DIR=/forest_data LOTUS_DATA_DIR=/lotus_data FIL_PROOFS_PARAMETER_CACHE=/var/tmp/filecoin-proof-parameters @@ -6,12 +6,12 @@ LOTUS_RPC_PORT=1234 LOTUS_P2P_PORT=1235 MINER_RPC_PORT=2345 FOREST_RPC_PORT=3456 -GENESIS_NETWORK_VERSION=21 -SHARK_HEIGHT=-20 -HYGGE_HEIGHT=-22 -LIGHTNING_HEIGHT=-23 -THUNDER_HEIGHT=-24 -WATERMELON_HEIGHT=-1 -DRAGON_HEIGHT=20 -DRAND_QUICKNET_HEIGHT=140 -TARGET_HEIGHT=200 +GENESIS_NETWORK_VERSION=18 +SHARK_HEIGHT=-10 +HYGGE_HEIGHT=-9 +LIGHTNING_HEIGHT=3 +THUNDER_HEIGHT=6 +WATERMELON_HEIGHT=9 +DRAGON_HEIGHT=12 +DRAND_QUICKNET_HEIGHT=15 +TARGET_HEIGHT=20 diff --git a/scripts/devnet/lotus.dockerfile b/scripts/devnet/lotus.dockerfile index 33d6b393c717..bf7f730533e8 100644 --- a/scripts/devnet/lotus.dockerfile +++ b/scripts/devnet/lotus.dockerfile @@ -5,7 +5,7 @@ RUN apt-get update && apt-get install -y ca-certificates build-essential clang o WORKDIR /lotus -RUN git clone --depth 1 --branch release/v1.26.0 https://github.com/filecoin-project/lotus.git . +RUN git clone --depth 1 --branch v1.26.0-rc2 https://github.com/filecoin-project/lotus.git . RUN CGO_CFLAGS_ALLOW="-D__BLST_PORTABLE__" \ CGO_CFLAGS="-D__BLST_PORTABLE__" \ diff --git a/src/networks/actors_bundle.rs b/src/networks/actors_bundle.rs index feaebe03b793..8cd2eb370f85 100644 --- a/src/networks/actors_bundle.rs +++ b/src/networks/actors_bundle.rs @@ -69,7 +69,7 @@ pub static ACTOR_BUNDLES: Lazy> = Lazy::new(|| { "bafy2bzacedrunxfqta5skb7q7x32lnp4efz2oq7fn226ffm7fu5iqs62jkmvs" @ "v12.0.0-rc.1" for "calibrationnet", "bafy2bzacebl4w5ptfvuw6746w7ev562idkbf5ppq72e6zub22435ws2rukzru" @ "v12.0.0-rc.2" for "calibrationnet", "bafy2bzacednzb3pkrfnbfhmoqtb3bc6dgvxszpqklf3qcc7qzcage4ewzxsca" @ "v12.0.0" for "calibrationnet", - "bafy2bzaceap46ftyyuhninmzelt2ev6kus5itrggszrk5wuhzf2khm47dtrfa" @ "v13.0.0-rc.2" for "calibrationnet", + "bafy2bzacea4firkyvt2zzdwqjrws5pyeluaesh6uaid246tommayr4337xpmi" @ "v13.0.0-rc.3" for "calibrationnet", "bafy2bzacectxvbk77ntedhztd6sszp2btrtvsmy7lp2ypnrk6yl74zb34t2cq" @ "v12.0.0" for "butterflynet", "bafy2bzaceaqx5xa4cwso24rjiu2ketjlztrqlac6dkyol7tlyuhzrle3zfbos" @ "v13.0.0-rc.3" for "butterflynet", "bafy2bzacedozk3jh2j4nobqotkbofodq4chbrabioxbfrygpldgoxs3zwgggk" @ "v9.0.3" for "devnet", @@ -81,7 +81,7 @@ pub static ACTOR_BUNDLES: Lazy> = Lazy::new(|| { "bafy2bzacecsuyf7mmvrhkx2evng5gnz5canlnz2fdlzu2lvcgptiq2pzuovos" @ "v10.0.0" for "mainnet", "bafy2bzacecnhaiwcrpyjvzl4uv4q3jzoif26okl3m66q3cijp3dfwlcxwztwo" @ "v11.0.0" for "mainnet", "bafy2bzaceapkgfggvxyllnmuogtwasmsv5qi2qzhc2aybockd6kag2g5lzaio" @ "v12.0.0" for "mainnet", - "bafy2bzacea6f5icdp6t6fs5sexjxmo3q5d2qu4g4ghq6s5eaob6svnmhvltmw" @ "v13.0.0-rc.2" for "mainnet", + "bafy2bzacecoplaet2m4kzueqgutjxpl76bhmuiq5hmo3ueighbnxas3rj4dvy" @ "v13.0.0-rc.3" for "mainnet", ]) }); diff --git a/src/networks/butterflynet/mod.rs b/src/networks/butterflynet/mod.rs index 2978b777efe5..3b08ca09048a 100644 --- a/src/networks/butterflynet/mod.rs +++ b/src/networks/butterflynet/mod.rs @@ -35,7 +35,7 @@ pub async fn fetch_genesis(db: &DB) -> anyhow::Result /// Genesis CID pub static GENESIS_CID: Lazy = Lazy::new(|| { - Cid::from_str("bafy2bzaceca7iggnglnsntfmtqvpsmolzvbuyzhpoq55wzubq65jasnkqxuh6").unwrap() + Cid::from_str("bafy2bzacedz4owzn3irngak4cdv3xndfxyy4qi5hcv7p724anbnt27l7dctoq").unwrap() }); /// Compressed genesis file. It is compressed with zstd and cuts the download size by 80% (from 10 MB to 2 MB). diff --git a/src/networks/calibnet/mod.rs b/src/networks/calibnet/mod.rs index c226c8b9c10a..723198849eed 100644 --- a/src/networks/calibnet/mod.rs +++ b/src/networks/calibnet/mod.rs @@ -8,8 +8,8 @@ use once_cell::sync::Lazy; use std::str::FromStr; use super::{ - drand::DRAND_MAINNET, get_upgrade_height_from_env, parse_bootstrap_peers, DrandPoint, Height, - HeightInfo, + drand::{DRAND_MAINNET, DRAND_QUICKNET}, + get_upgrade_height_from_env, parse_bootstrap_peers, DrandPoint, Height, HeightInfo, }; /// Default genesis car file bytes. @@ -194,13 +194,12 @@ pub static HEIGHT_INFOS: Lazy> = Lazy::new(|| { ), }, ), - // TODO: This shouldn't be modifiable outside of testing ( Height::Dragon, HeightInfo { - epoch: get_upgrade_height_from_env("FOREST_DRAGON_HEIGHT").unwrap_or(1_427_974), + epoch: 1_427_974, bundle: Some( - Cid::try_from("bafy2bzaceap46ftyyuhninmzelt2ev6kus5itrggszrk5wuhzf2khm47dtrfa") + Cid::try_from("bafy2bzacea4firkyvt2zzdwqjrws5pyeluaesh6uaid246tommayr4337xpmi") .unwrap(), ), }, @@ -208,11 +207,18 @@ pub static HEIGHT_INFOS: Lazy> = Lazy::new(|| { ]) }); -pub(super) static DRAND_SCHEDULE: Lazy<[DrandPoint<'static>; 1]> = Lazy::new(|| { - [DrandPoint { - height: 0, - config: &DRAND_MAINNET, - }] +pub(super) static DRAND_SCHEDULE: Lazy<[DrandPoint<'static>; 2]> = Lazy::new(|| { + [ + DrandPoint { + height: 0, + config: &DRAND_MAINNET, + }, + DrandPoint { + height: get_upgrade_height_from_env("FOREST_DRAND_QUICKNET_HEIGHT") + .unwrap_or(HEIGHT_INFOS.get(&Height::Dragon).unwrap().epoch + 120), + config: &DRAND_QUICKNET, + }, + ] }); #[cfg(test)] diff --git a/src/networks/devnet/mod.rs b/src/networks/devnet/mod.rs index 107833f57bf5..beb222378231 100644 --- a/src/networks/devnet/mod.rs +++ b/src/networks/devnet/mod.rs @@ -85,9 +85,6 @@ pub(super) static DRAND_SCHEDULE: Lazy<[DrandPoint<'static>; 2]> = Lazy::new(|| config: &DRAND_MAINNET, }, DrandPoint { - // height is TBD. - // likely to be `get_upgrade_epoch_by_height(HEIGHT_INFOS.iter(), Height::Pineapple).unwrap()`. - // remember to remove `#[allow(dead_code)]` from `get_upgrade_epoch_by_height` height: get_upgrade_height_from_env("FOREST_DRAND_QUICKNET_HEIGHT").unwrap_or(i64::MAX), config: &DRAND_QUICKNET, }, diff --git a/src/networks/mainnet/mod.rs b/src/networks/mainnet/mod.rs index d479e13383e4..2024adec1510 100644 --- a/src/networks/mainnet/mod.rs +++ b/src/networks/mainnet/mod.rs @@ -205,9 +205,10 @@ pub static HEIGHT_INFOS: Lazy> = Lazy::new(|| { ( Height::Dragon, HeightInfo { - epoch: get_upgrade_height_from_env("FOREST_DRAGON_HEIGHT").unwrap_or(i64::MAX), + // 2024-04-02T14:00:00Z - Epoch will be updated in final release + epoch: i64::MAX, bundle: Some( - Cid::try_from("bafy2bzacea6f5icdp6t6fs5sexjxmo3q5d2qu4g4ghq6s5eaob6svnmhvltmw") + Cid::try_from("bafy2bzacecoplaet2m4kzueqgutjxpl76bhmuiq5hmo3ueighbnxas3rj4dvy") .unwrap(), ), }, @@ -226,8 +227,8 @@ pub(super) static DRAND_SCHEDULE: Lazy<[DrandPoint<'static>; 3]> = Lazy::new(|| config: &DRAND_MAINNET, }, DrandPoint { - // height is TBD - height: i64::MAX, + height: get_upgrade_height_from_env("FOREST_DRAND_QUICKNET_HEIGHT") + .unwrap_or(HEIGHT_INFOS.get(&Height::Dragon).unwrap().epoch + 120), config: &DRAND_QUICKNET, }, ] diff --git a/src/state_migration/nv21/mod.rs b/src/state_migration/nv21/mod.rs index 58105870106c..858e2e11302a 100644 --- a/src/state_migration/nv21/mod.rs +++ b/src/state_migration/nv21/mod.rs @@ -1,15 +1,14 @@ // Copyright 2019-2024 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT -//! This module contains the migration logic for the `NV22` upgrade. +//! This module contains the migration logic for the `NV21` upgrade. //! The corresponding Go implementation can be found here: -//! TODO !!! //! mod migration; mod miner; -/// Run migration for `NV22`. This should be the only exported method in this +/// Run migration for `NV21`. This should be the only exported method in this /// module. pub use migration::run_migration; diff --git a/src/state_migration/nv22/miner.rs b/src/state_migration/nv22/miner.rs index 3ff1ecdcdc8a..0214fc47c5e3 100644 --- a/src/state_migration/nv22/miner.rs +++ b/src/state_migration/nv22/miner.rs @@ -7,8 +7,8 @@ //! metadata from the Miner actor. //! //! As per [FIP-0076](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0076.md#backwards-compatibility) -//! > This proposal requires a state migration to the market actor to add the new ProviderSectors mapping, -//! > and to add a sector number to and remove allocation ID from each DealState. Computing this mapping +//! > This proposal requires a state migration to the market actor to add the new `ProviderSectors` mapping, +//! > and to add a sector number to and remove allocation ID from each `DealState`. Computing this mapping //! > requires reading all sector metadata from the miner actor. use crate::state_migration::common::{ActorMigration, ActorMigrationInput, ActorMigrationOutput}; From d88ca42ba6731831ad48e56004cbd18f5db2dd14 Mon Sep 17 00:00:00 2001 From: Hubert Bugaj Date: Thu, 7 Mar 2024 15:06:22 +0100 Subject: [PATCH 7/7] force at least 3 threads for migrations + test fix --- src/networks/mainnet/mod.rs | 4 ++-- src/state_migration/common/state_migration.rs | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/networks/mainnet/mod.rs b/src/networks/mainnet/mod.rs index 2024adec1510..169014a32bad 100644 --- a/src/networks/mainnet/mod.rs +++ b/src/networks/mainnet/mod.rs @@ -227,8 +227,8 @@ pub(super) static DRAND_SCHEDULE: Lazy<[DrandPoint<'static>; 3]> = Lazy::new(|| config: &DRAND_MAINNET, }, DrandPoint { - height: get_upgrade_height_from_env("FOREST_DRAND_QUICKNET_HEIGHT") - .unwrap_or(HEIGHT_INFOS.get(&Height::Dragon).unwrap().epoch + 120), + // 2024-04-02T14:00:00Z - Epoch will be updated in final release + height: get_upgrade_height_from_env("FOREST_DRAND_QUICKNET_HEIGHT").unwrap_or(i64::MAX), config: &DRAND_QUICKNET, }, ] diff --git a/src/state_migration/common/state_migration.rs b/src/state_migration/common/state_migration.rs index 373aad41f4e1..38f5c8091a98 100644 --- a/src/state_migration/common/state_migration.rs +++ b/src/state_migration/common/state_migration.rs @@ -83,9 +83,10 @@ impl StateMigration { let num_threads = std::env::var("FOREST_STATE_MIGRATION_THREADS") .ok() .and_then(|s| s.parse().ok()) - // At least 3 are required to not deadlock the migration. Don't use all CPU, - // otherwise the migration will starve the rest of the system. - .unwrap_or_else(|| 3.max(num_cpus::get() / 2)); + // Don't use all CPU, otherwise the migration will starve the rest of the system. + .unwrap_or_else(|| num_cpus::get() / 2) + // At least 3 are required to not deadlock the migration. + .max(3); let pool = rayon::ThreadPoolBuilder::new() .thread_name(|id| format!("state migration thread: {id}"))