Skip to content

Commit 9f0fa96

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

File tree

4 files changed

+59
-28
lines changed

4 files changed

+59
-28
lines changed

Diff for: actors/miner/src/sectors.rs

+51-14
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,50 @@ 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(|| anyhow!("sector info not found for sector {}", sector_number))?;
92+
f(sector_number, &sector_info)
93+
})?;
94+
Ok(())
6095
}
6196

6297
pub fn store(&mut self, infos: Vec<SectorOnChainInfo>) -> anyhow::Result<()> {
6398
for info in infos {
6499
let sector_number = info.sector_number;
65-
66100
if sector_number > MAX_SECTOR_NUMBER {
67101
return Err(anyhow!("sector number {} out of range", info.sector_number));
68102
}
69103

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

75112
Ok(())

Diff for: actors/miner/src/state.rs

+7-11
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
@@ -141,15 +141,11 @@ impl State {
141141
"failed to construct empty precommits array",
142142
)
143143
})?;
144-
let empty_sectors_array =
145-
Array::<SectorOnChainInfo, BS>::new_with_bit_width(store, SECTORS_AMT_BITWIDTH)
146-
.flush()
147-
.map_err(|e| {
148-
e.downcast_default(
149-
ExitCode::USR_ILLEGAL_STATE,
150-
"failed to construct sectors array",
151-
)
152-
})?;
144+
let empty_sectors_array = Array::<Cid, BS>::new_with_bit_width(store, SECTORS_AMT_BITWIDTH)
145+
.flush()
146+
.map_err(|e| {
147+
e.downcast_default(ExitCode::USR_ILLEGAL_STATE, "failed to construct sectors array")
148+
})?;
153149
let empty_bitfield = store.put_cbor(&BitField::new(), Code::Blake2b256).map_err(|e| {
154150
e.downcast_default(ExitCode::USR_ILLEGAL_STATE, "failed to construct empty bitfield")
155151
})?;
@@ -422,7 +418,7 @@ impl State {
422418
F: FnMut(&SectorOnChainInfo) -> anyhow::Result<()>,
423419
{
424420
let sectors = Sectors::load(store, &self.sectors)?;
425-
sectors.amt.for_each(|_, v| f(v))?;
421+
sectors.for_each(|_, v| f(v))?;
426422
Ok(())
427423
}
428424

Diff for: actors/miner/src/testing.rs

+1-1
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),

Diff for: actors/miner/tests/util.rs

-2
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)