Skip to content

Commit d3bb3d4

Browse files
committed
feat(miner): externalise SectorOnChainInfo from AMT
1 parent 6967a23 commit d3bb3d4

File tree

4 files changed

+57
-20
lines changed

4 files changed

+57
-20
lines changed

actors/miner/src/sectors.rs

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,21 @@ use fil_actors_runtime::{actor_error, ActorDowncast, ActorError, Array, AsActorE
1010
use fvm_ipld_amt::Error as AmtError;
1111
use fvm_ipld_bitfield::BitField;
1212
use fvm_ipld_blockstore::Blockstore;
13+
use fvm_ipld_encoding::CborStore;
1314
use fvm_shared::error::ExitCode;
1415
use fvm_shared::sector::SectorNumber;
16+
use multihash_codetable::Code;
1517

1618
use super::SectorOnChainInfo;
1719

1820
pub struct Sectors<'db, BS> {
19-
pub amt: Array<'db, SectorOnChainInfo, BS>,
21+
pub amt: Array<'db, Cid, BS>,
22+
store: &'db BS,
2023
}
2124

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

2730
pub fn load_sector(
@@ -30,7 +33,7 @@ impl<'db, BS: Blockstore> Sectors<'db, BS> {
3033
) -> Result<Vec<SectorOnChainInfo>, ActorError> {
3134
let mut sector_infos: Vec<SectorOnChainInfo> = Vec::new();
3235
for sector_number in sector_numbers.iter() {
33-
let sector_on_chain = self
36+
let c = self
3437
.amt
3538
.get(sector_number)
3639
.map_err(|e| {
@@ -41,6 +44,16 @@ impl<'db, BS: Blockstore> Sectors<'db, BS> {
4144
})?
4245
.cloned()
4346
.ok_or_else(|| actor_error!(not_found; "sector not found: {}", sector_number))?;
47+
let sector_on_chain = self
48+
.store
49+
.get_cbor::<SectorOnChainInfo>(&c)
50+
.map_err(|e| {
51+
e.downcast_default(
52+
ExitCode::USR_ILLEGAL_STATE,
53+
format!("failed to load sector {}", sector_number),
54+
)
55+
})?
56+
.ok_or_else(|| actor_error!(not_found; "sector not found: {}", sector_number))?;
4457
sector_infos.push(sector_on_chain);
4558
}
4659
Ok(sector_infos)
@@ -50,26 +63,52 @@ impl<'db, BS: Blockstore> Sectors<'db, BS> {
5063
&self,
5164
sector_number: SectorNumber,
5265
) -> Result<Option<SectorOnChainInfo>, ActorError> {
53-
Ok(self
54-
.amt
55-
.get(sector_number)
56-
.with_context_code(ExitCode::USR_ILLEGAL_STATE, || {
57-
format!("failed to get sector {}", sector_number)
58-
})?
59-
.cloned())
66+
match self.amt.get(sector_number).with_context_code(ExitCode::USR_ILLEGAL_STATE, || {
67+
format!("failed to get sector {}", sector_number)
68+
})? {
69+
Some(c) => match self.store.get_cbor::<SectorOnChainInfo>(c) {
70+
Ok(Some(sector_info)) => Ok(Some(sector_info)),
71+
Ok(None) => Ok(None),
72+
Err(e) => Err(e.downcast_default(
73+
ExitCode::USR_ILLEGAL_STATE,
74+
format!("failed to load sector {}", sector_number),
75+
)),
76+
},
77+
None => Ok(None),
78+
}
79+
}
80+
81+
pub fn for_each<F>(&self, mut f: F) -> anyhow::Result<()>
82+
where
83+
F: FnMut(SectorNumber, &SectorOnChainInfo) -> anyhow::Result<()>,
84+
{
85+
self.amt.for_each(|i, c| {
86+
let sector_number = i as SectorNumber;
87+
let sector_info = self
88+
.store
89+
.get_cbor::<SectorOnChainInfo>(c)
90+
.map_err(|e| anyhow!(e.to_string()))?
91+
.ok_or_else(|| {
92+
anyhow!("sector info not found for sector {}", sector_number)
93+
})?;
94+
f(sector_number, &sector_info)
95+
})?;
96+
Ok(())
6097
}
6198

6299
pub fn store(&mut self, infos: Vec<SectorOnChainInfo>) -> anyhow::Result<()> {
63100
for info in infos {
64101
let sector_number = info.sector_number;
65-
66102
if sector_number > MAX_SECTOR_NUMBER {
67103
return Err(anyhow!("sector number {} out of range", info.sector_number));
68104
}
69105

70-
self.amt.set(sector_number, info).map_err(|e| {
71-
e.downcast_wrap(format!("failed to store sector {}", sector_number))
72-
})?;
106+
match self.store.put_cbor(&info, Code::Blake2b256) {
107+
Ok(c) => self.amt.set(sector_number, c).map_err(|e| {
108+
e.downcast_wrap(format!("failed to store sector {}", sector_number))
109+
})?,
110+
Err(e) => return Err(anyhow!("failed to store sector {}: {}", sector_number, e)),
111+
}
73112
}
74113

75114
Ok(())

actors/miner/src/state.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ pub struct State {
8686
///
8787
/// Sectors are removed from this AMT when the partition to which the
8888
/// sector belongs is compacted.
89-
pub sectors: Cid, // Array, AMT[SectorNumber]SectorOnChainInfo (sparse)
89+
pub sectors: Cid, // Array, AMT[SectorNumber]*SectorOnChainInfo (sparse)
9090

9191
/// The first epoch in this miner's current proving period. This is the first epoch in which a PoSt for a
9292
/// partition at the miner's first deadline may arrive. Alternatively, it is after the last epoch at which
@@ -142,7 +142,7 @@ impl State {
142142
)
143143
})?;
144144
let empty_sectors_array =
145-
Array::<SectorOnChainInfo, BS>::new_with_bit_width(store, SECTORS_AMT_BITWIDTH)
145+
Array::<Cid, BS>::new_with_bit_width(store, SECTORS_AMT_BITWIDTH)
146146
.flush()
147147
.map_err(|e| {
148148
e.downcast_default(
@@ -422,7 +422,7 @@ impl State {
422422
F: FnMut(&SectorOnChainInfo) -> anyhow::Result<()>,
423423
{
424424
let sectors = Sectors::load(store, &self.sectors)?;
425-
sectors.amt.for_each(|_, v| f(v))?;
425+
sectors.for_each(|_, v| f(v))?;
426426
Ok(())
427427
}
428428

actors/miner/src/testing.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ pub fn check_state_invariants<BS: Blockstore>(
6767
let mut all_sectors: BTreeMap<SectorNumber, SectorOnChainInfo> = BTreeMap::new();
6868
match Sectors::load(&store, &state.sectors) {
6969
Ok(sectors) => {
70-
let ret = sectors.amt.for_each(|sector_number, sector| {
70+
let ret = sectors.for_each(|sector_number, sector| {
7171
all_sectors.insert(sector_number, sector.clone());
7272
acc.require(
7373
allocated_sectors.contains(&sector_number),

actors/miner/tests/util.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2174,7 +2174,6 @@ impl ActorHarness {
21742174
let skipped_proven = &to_skip - &part.unproven;
21752175
let mut skipped_proven_sector_infos = Vec::new();
21762176
sector_arr
2177-
.amt
21782177
.for_each(|i, sector| {
21792178
if skipped_proven.get(i) {
21802179
skipped_proven_sector_infos.push(sector.clone());
@@ -2188,7 +2187,6 @@ impl ActorHarness {
21882187
let new_proven = &part.unproven - &to_skip;
21892188
let mut new_proven_infos = Vec::new();
21902189
sector_arr
2191-
.amt
21922190
.for_each(|i, sector| {
21932191
if new_proven.get(i) {
21942192
new_proven_infos.push(sector.clone());

0 commit comments

Comments
 (0)