forest/state_migration/nv22/
miner.rs1use crate::state_migration::common::{ActorMigration, ActorMigrationInput, ActorMigrationOutput};
15use crate::utils::db::CborStoreExt as _;
16use ahash::HashMap;
17use cid::Cid;
18use fil_actor_miner_state::v12::State as MinerStateOld;
19use fil_actors_shared::v12::Array as ArrayOld;
20use fvm_ipld_blockstore::Blockstore;
21use fvm_shared4::ActorID;
22use fvm_shared4::clock::ChainEpoch;
23use fvm_shared4::deal::DealID;
24use fvm_shared4::sector::{SectorID, SectorNumber};
25use parking_lot::RwLock;
26use std::sync::Arc;
27
28#[derive(Default)]
29pub struct ProviderSectors {
30 pub deal_to_sector: RwLock<HashMap<DealID, SectorID>>,
31 pub miner_to_sector_to_deals: RwLock<HashMap<ActorID, HashMap<SectorNumber, Vec<DealID>>>>,
32}
33
34pub struct MinerMigrator {
35 upgrade_epoch: ChainEpoch,
36 provider_sectors: Arc<ProviderSectors>,
37 out_cid: Cid,
38}
39
40pub(in crate::state_migration) fn miner_migrator<BS: Blockstore>(
41 upgrade_epoch: ChainEpoch,
42 provider_sectors: Arc<ProviderSectors>,
43 out_cid: Cid,
44) -> anyhow::Result<Arc<dyn ActorMigration<BS> + Send + Sync>> {
45 Ok(Arc::new(MinerMigrator {
46 upgrade_epoch,
47 provider_sectors,
48 out_cid,
49 }))
50}
51
52impl<BS: Blockstore> ActorMigration<BS> for MinerMigrator {
53 fn migrate_state(
54 &self,
55 store: &BS,
56 input: ActorMigrationInput,
57 ) -> anyhow::Result<Option<ActorMigrationOutput>> {
58 let miner_id = input.address.id()?;
59 let in_state: MinerStateOld = store.get_cbor_required(&input.head)?;
60
61 let in_sectors = ArrayOld::<fil_actor_miner_state::v12::SectorOnChainInfo, BS>::load(
62 &in_state.sectors,
63 store,
64 )?;
65
66 in_sectors.for_each(|i, sector| {
67 if sector.deal_ids.is_empty() || sector.expiration < self.upgrade_epoch {
68 return Ok(());
69 }
70
71 let mut sectors = self.provider_sectors.deal_to_sector.write();
72 for deal_id in sector.deal_ids.iter() {
73 sectors.insert(
74 *deal_id,
75 SectorID {
76 miner: miner_id,
77 number: i,
78 },
79 );
80 }
81 drop(sectors);
82
83 let mut sector_deals = self.provider_sectors.miner_to_sector_to_deals.write();
84 sector_deals
85 .entry(miner_id)
86 .or_default()
87 .insert(i, sector.deal_ids.clone());
88
89 Ok(())
90 })?;
91
92 Ok(Some(ActorMigrationOutput {
93 new_code_cid: self.out_cid,
94 new_head: input.head,
95 }))
96 }
97}