Skip to content

Commit

Permalink
feat(miner): externalise SectorOnChainInfo from AMT
Browse files Browse the repository at this point in the history
  • Loading branch information
rvagg committed Jan 22, 2025
1 parent 6967a23 commit 9f0fa96
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 28 deletions.
65 changes: 51 additions & 14 deletions actors/miner/src/sectors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,21 @@ use fil_actors_runtime::{actor_error, ActorDowncast, ActorError, Array, AsActorE
use fvm_ipld_amt::Error as AmtError;
use fvm_ipld_bitfield::BitField;
use fvm_ipld_blockstore::Blockstore;
use fvm_ipld_encoding::CborStore;
use fvm_shared::error::ExitCode;
use fvm_shared::sector::SectorNumber;
use multihash_codetable::Code;

use super::SectorOnChainInfo;

pub struct Sectors<'db, BS> {
pub amt: Array<'db, SectorOnChainInfo, BS>,
pub amt: Array<'db, Cid, BS>,
store: &'db BS,
}

impl<'db, BS: Blockstore> Sectors<'db, BS> {
pub fn load(store: &'db BS, root: &Cid) -> Result<Self, AmtError> {
Ok(Self { amt: Array::load(root, store)? })
Ok(Self { amt: Array::load(root, store)?, store })
}

pub fn load_sector(
Expand All @@ -30,7 +33,7 @@ impl<'db, BS: Blockstore> Sectors<'db, BS> {
) -> Result<Vec<SectorOnChainInfo>, ActorError> {
let mut sector_infos: Vec<SectorOnChainInfo> = Vec::new();
for sector_number in sector_numbers.iter() {
let sector_on_chain = self
let c = self
.amt
.get(sector_number)
.map_err(|e| {
Expand All @@ -41,6 +44,16 @@ impl<'db, BS: Blockstore> Sectors<'db, BS> {
})?
.cloned()
.ok_or_else(|| actor_error!(not_found; "sector not found: {}", sector_number))?;
let sector_on_chain = self
.store
.get_cbor::<SectorOnChainInfo>(&c)
.map_err(|e| {
e.downcast_default(
ExitCode::USR_ILLEGAL_STATE,
format!("failed to load sector {}", sector_number),
)
})?
.ok_or_else(|| actor_error!(not_found; "sector not found: {}", sector_number))?;
sector_infos.push(sector_on_chain);
}
Ok(sector_infos)
Expand All @@ -50,26 +63,50 @@ impl<'db, BS: Blockstore> Sectors<'db, BS> {
&self,
sector_number: SectorNumber,
) -> Result<Option<SectorOnChainInfo>, ActorError> {
Ok(self
.amt
.get(sector_number)
.with_context_code(ExitCode::USR_ILLEGAL_STATE, || {
format!("failed to get sector {}", sector_number)
})?
.cloned())
match self.amt.get(sector_number).with_context_code(ExitCode::USR_ILLEGAL_STATE, || {
format!("failed to get sector {}", sector_number)
})? {
Some(c) => match self.store.get_cbor::<SectorOnChainInfo>(c) {
Ok(Some(sector_info)) => Ok(Some(sector_info)),
Ok(None) => Ok(None),
Err(e) => Err(e.downcast_default(
ExitCode::USR_ILLEGAL_STATE,
format!("failed to load sector {}", sector_number),
)),
},
None => Ok(None),
}
}

pub fn for_each<F>(&self, mut f: F) -> anyhow::Result<()>
where
F: FnMut(SectorNumber, &SectorOnChainInfo) -> anyhow::Result<()>,
{
self.amt.for_each(|i, c| {
let sector_number = i as SectorNumber;
let sector_info = self
.store
.get_cbor::<SectorOnChainInfo>(c)
.map_err(|e| anyhow!(e.to_string()))?
.ok_or_else(|| anyhow!("sector info not found for sector {}", sector_number))?;
f(sector_number, &sector_info)
})?;
Ok(())
}

pub fn store(&mut self, infos: Vec<SectorOnChainInfo>) -> anyhow::Result<()> {
for info in infos {
let sector_number = info.sector_number;

if sector_number > MAX_SECTOR_NUMBER {
return Err(anyhow!("sector number {} out of range", info.sector_number));
}

self.amt.set(sector_number, info).map_err(|e| {
e.downcast_wrap(format!("failed to store sector {}", sector_number))
})?;
match self.store.put_cbor(&info, Code::Blake2b256) {
Ok(c) => self.amt.set(sector_number, c).map_err(|e| {
e.downcast_wrap(format!("failed to store sector {}", sector_number))
})?,
Err(e) => return Err(anyhow!("failed to store sector {}: {}", sector_number, e)),
}
}

Ok(())
Expand Down
18 changes: 7 additions & 11 deletions actors/miner/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ pub struct State {
///
/// Sectors are removed from this AMT when the partition to which the
/// sector belongs is compacted.
pub sectors: Cid, // Array, AMT[SectorNumber]SectorOnChainInfo (sparse)
pub sectors: Cid, // Array, AMT[SectorNumber]*SectorOnChainInfo (sparse)

/// The first epoch in this miner's current proving period. This is the first epoch in which a PoSt for a
/// partition at the miner's first deadline may arrive. Alternatively, it is after the last epoch at which
Expand Down Expand Up @@ -141,15 +141,11 @@ impl State {
"failed to construct empty precommits array",
)
})?;
let empty_sectors_array =
Array::<SectorOnChainInfo, BS>::new_with_bit_width(store, SECTORS_AMT_BITWIDTH)
.flush()
.map_err(|e| {
e.downcast_default(
ExitCode::USR_ILLEGAL_STATE,
"failed to construct sectors array",
)
})?;
let empty_sectors_array = Array::<Cid, BS>::new_with_bit_width(store, SECTORS_AMT_BITWIDTH)
.flush()
.map_err(|e| {
e.downcast_default(ExitCode::USR_ILLEGAL_STATE, "failed to construct sectors array")
})?;
let empty_bitfield = store.put_cbor(&BitField::new(), Code::Blake2b256).map_err(|e| {
e.downcast_default(ExitCode::USR_ILLEGAL_STATE, "failed to construct empty bitfield")
})?;
Expand Down Expand Up @@ -422,7 +418,7 @@ impl State {
F: FnMut(&SectorOnChainInfo) -> anyhow::Result<()>,
{
let sectors = Sectors::load(store, &self.sectors)?;
sectors.amt.for_each(|_, v| f(v))?;
sectors.for_each(|_, v| f(v))?;
Ok(())
}

Expand Down
2 changes: 1 addition & 1 deletion actors/miner/src/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ pub fn check_state_invariants<BS: Blockstore>(
let mut all_sectors: BTreeMap<SectorNumber, SectorOnChainInfo> = BTreeMap::new();
match Sectors::load(&store, &state.sectors) {
Ok(sectors) => {
let ret = sectors.amt.for_each(|sector_number, sector| {
let ret = sectors.for_each(|sector_number, sector| {
all_sectors.insert(sector_number, sector.clone());
acc.require(
allocated_sectors.contains(&sector_number),
Expand Down
2 changes: 0 additions & 2 deletions actors/miner/tests/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2174,7 +2174,6 @@ impl ActorHarness {
let skipped_proven = &to_skip - &part.unproven;
let mut skipped_proven_sector_infos = Vec::new();
sector_arr
.amt
.for_each(|i, sector| {
if skipped_proven.get(i) {
skipped_proven_sector_infos.push(sector.clone());
Expand All @@ -2188,7 +2187,6 @@ impl ActorHarness {
let new_proven = &part.unproven - &to_skip;
let mut new_proven_infos = Vec::new();
sector_arr
.amt
.for_each(|i, sector| {
if new_proven.get(i) {
new_proven_infos.push(sector.clone());
Expand Down

0 comments on commit 9f0fa96

Please sign in to comment.