Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V3 HAMT and AMT for Actors #1005

Merged
merged 19 commits into from
Feb 10, 2021
6 changes: 2 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion utils/bigint/src/bigint_ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use std::borrow::Cow;
pub struct BigIntSer<'a>(#[serde(with = "self")] pub &'a BigInt);

/// Wrapper for deserializing as BigInt from bytes.
#[derive(Deserialize, Serialize, Clone, Default)]
#[derive(Deserialize, Serialize, Clone, Default, PartialEq)]
#[serde(transparent)]
pub struct BigIntDe(#[serde(with = "self")] pub BigInt);

Expand Down
4 changes: 2 additions & 2 deletions vm/actor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ cid = { package = "forest_cid", version = "0.3", features = ["cbor"] }
serde = { version = "1.0", features = ["derive"] }
lazy_static = "1.4.0"
ipld_blockstore = "0.1"
ipld_hamt = { version = "1.0", features = ["go-interop"] }
ipld_amt = { features = ["go-interop"], version = "0.2" }
ipld_hamt = { path = "../../ipld/hamt" }
austinabell marked this conversation as resolved.
Show resolved Hide resolved
ipld_amt = { path = "../../ipld/amt", features = ["go-interop"]}
forest_ipld = "0.1.1"
unsigned-varint = "0.6"
integer-encoding = { version = "3.0", default-features = false }
Expand Down
65 changes: 35 additions & 30 deletions vm/actor/src/builtin/market/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ impl Actor {
msm.deal_proposals
.as_mut()
.unwrap()
.set(id, deal.proposal.clone())
.set(id as usize, deal.proposal.clone())
.map_err(|e| {
e.downcast_default(ExitCode::ErrIllegalState, "failed to set deal")
})?;
Expand Down Expand Up @@ -450,7 +450,7 @@ impl Actor {
.deal_states
.as_ref()
.unwrap()
.get(deal_id)
.get(deal_id as usize)
.map_err(|e| {
e.downcast_default(
ExitCode::ErrIllegalState,
Expand All @@ -466,7 +466,7 @@ impl Actor {
.deal_proposals
.as_ref()
.unwrap()
.get(deal_id)
.get(deal_id as usize)
.map_err(|e| {
e.downcast_default(
ExitCode::ErrIllegalState,
Expand Down Expand Up @@ -500,7 +500,7 @@ impl Actor {
.as_mut()
.unwrap()
.set(
deal_id,
deal_id as usize,
DealState {
sector_start_epoch: curr_epoch,
last_updated_epoch: EPOCH_UNDEFINED,
Expand Down Expand Up @@ -548,9 +548,14 @@ impl Actor {
})?;

for id in params.deal_ids {
let deal = msm.deal_proposals.as_ref().unwrap().get(id).map_err(|e| {
e.downcast_default(ExitCode::ErrIllegalState, "failed to get deal proposal")
})?;
let deal = msm
.deal_proposals
.as_ref()
.unwrap()
.get(id as usize)
.map_err(|e| {
e.downcast_default(ExitCode::ErrIllegalState, "failed to get deal proposal")
})?;
// deal could have terminated and hence deleted before the sector is terminated.
// we should simply continue instead of aborting execution here if a deal is not found.
if deal.is_none() {
Expand All @@ -572,7 +577,7 @@ impl Actor {
.deal_states
.as_ref()
.unwrap()
.get(id)
.get(id as usize)
.map_err(|e| {
e.downcast_default(ExitCode::ErrIllegalState, "failed to get deal state")
})?
Expand All @@ -590,7 +595,7 @@ impl Actor {
msm.deal_states
.as_mut()
.unwrap()
.set(id, state)
.set(id as usize, state)
.map_err(|e| {
e.downcast_default(
ExitCode::ErrIllegalState,
Expand Down Expand Up @@ -626,7 +631,7 @@ impl Actor {
let mut pieces: Vec<PieceInfo> = Vec::with_capacity(params.deal_ids.len());
for deal_id in params.deal_ids {
let deal = proposals
.get(deal_id)
.get(deal_id as usize)
.map_err(|e| {
e.downcast_default(
ExitCode::ErrIllegalState,
Expand Down Expand Up @@ -702,7 +707,7 @@ impl Actor {
.deal_proposals
.as_ref()
.unwrap()
.get(deal_id)
.get(deal_id as usize)
.map_err(|e| {
e.downcast_default(
ExitCode::ErrIllegalState,
Expand All @@ -724,7 +729,7 @@ impl Actor {
.deal_states
.as_ref()
.unwrap()
.get(deal_id)
.get(deal_id as usize)
.map_err(|e| {
e.downcast_default(
ExitCode::ErrIllegalState,
Expand Down Expand Up @@ -755,14 +760,14 @@ impl Actor {
.deal_proposals
.as_mut()
.unwrap()
.delete(deal_id)
.delete(deal_id as usize)
.map_err(|e| {
e.downcast_default(
ExitCode::ErrIllegalState,
"failed to delete deal",
)
})?;
if !deleted {
if deleted.is_none() {
return Err(actor_error!(ErrIllegalState;
"failed to delete deal proposal: does not exist"));
}
Expand Down Expand Up @@ -825,30 +830,30 @@ impl Actor {
.deal_proposals
.as_mut()
.unwrap()
.delete(deal_id)
.delete(deal_id as usize)
.map_err(|e| {
e.downcast_default(
ExitCode::ErrIllegalState,
"failed to delete deal proposal",
)
})?;
if !deleted {
if deleted.is_none() {
return Err(actor_error!(ErrIllegalState;
"failed to delete deal proposal: does not exist"));
}

let deleted =
msm.deal_states
.as_mut()
.unwrap()
.delete(deal_id)
.map_err(|e| {
e.downcast_default(
ExitCode::ErrIllegalState,
"failed to delete deal state",
)
})?;
if !deleted {
let deleted = msm
.deal_states
.as_mut()
.unwrap()
.delete(deal_id as usize)
.map_err(|e| {
e.downcast_default(
ExitCode::ErrIllegalState,
"failed to delete deal state",
)
})?;
if deleted.is_none() {
return Err(actor_error!(ErrIllegalState;
"failed to delete deal state: does not exist"));
}
Expand All @@ -862,7 +867,7 @@ impl Actor {
msm.deal_states
.as_mut()
.unwrap()
.set(deal_id, state)
.set(deal_id as usize, state)
.map_err(|e| {
e.downcast_default(
ExitCode::ErrIllegalState,
Expand Down Expand Up @@ -983,7 +988,7 @@ where
.into());
}
let proposal = proposals
.get(*deal_id)?
.get(*deal_id as usize)?
.ok_or_else(|| actor_error!(ErrNotFound, "no such deal {}", deal_id))?;

validate_deal_can_activate(&proposal, miner_addr, sector_expiry, curr_epoch)
Expand Down
22 changes: 11 additions & 11 deletions vm/actor/src/builtin/miner/bitfield_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ impl<'db, BS: BlockStore> BitFieldQueue<'db, BS> {

let bitfield = self
.amt
.get(epoch as u64)
.get(epoch as usize)
.map_err(|e| e.downcast_wrap(format!("failed to lookup queue epoch {}", epoch)))?
.cloned()
.unwrap_or_default();

self.amt
.set(epoch as u64, &bitfield | values)
.set(epoch as usize, &bitfield | values)
.map_err(|e| e.downcast_wrap(format!("failed to set queue epoch {}", epoch)))?;

Ok(())
Expand All @@ -56,12 +56,12 @@ impl<'db, BS: BlockStore> BitFieldQueue<'db, BS> {
pub fn add_to_queue_values(
&mut self,
epoch: ChainEpoch,
values: &[u64],
values: &[usize],
) -> Result<(), Box<dyn StdError>> {
if values.is_empty() {
Ok(())
} else {
self.add_to_queue(epoch, &values.iter().map(|&i| i as usize).collect())
self.add_to_queue(epoch, &values.iter().copied().collect())
}
}

Expand All @@ -70,7 +70,7 @@ impl<'db, BS: BlockStore> BitFieldQueue<'db, BS> {
///
/// See the docs on `BitField::cut` to better understand what it does.
pub fn cut(&mut self, to_cut: &BitField) -> Result<(), Box<dyn StdError>> {
let mut epochs_to_remove = Vec::<u64>::new();
let mut epochs_to_remove = Vec::<usize>::new();

self.amt
.for_each_mut(|epoch, bitfield| {
Expand All @@ -87,20 +87,20 @@ impl<'db, BS: BlockStore> BitFieldQueue<'db, BS> {
.map_err(|e| e.downcast_wrap("failed to cut from bitfield queue"))?;

self.amt
.batch_delete(epochs_to_remove)
.batch_delete(epochs_to_remove, true)
.map_err(|e| e.downcast_wrap("failed to remove empty epochs from bitfield queue"))?;

Ok(())
}

pub fn add_many_to_queue_values(
&mut self,
values: &HashMap<ChainEpoch, Vec<u64>>,
values: &HashMap<ChainEpoch, Vec<usize>>,
) -> Result<(), Box<dyn StdError>> {
// Update each epoch in-order to be deterministic.
// Pre-quantize to reduce the number of updates.

let mut quantized_values = HashMap::<ChainEpoch, Vec<u64>>::with_capacity(values.len());
let mut quantized_values = HashMap::<ChainEpoch, Vec<usize>>::with_capacity(values.len());
let mut updated_epochs = Vec::<ChainEpoch>::with_capacity(values.len());

for (&raw_epoch, entries) in values {
Expand All @@ -122,15 +122,15 @@ impl<'db, BS: BlockStore> BitFieldQueue<'db, BS> {
/// Modified return value indicates whether this structure has been changed by the call.
pub fn pop_until(&mut self, until: ChainEpoch) -> Result<(BitField, bool), Box<dyn StdError>> {
let mut popped_values = BitField::new();
let mut popped_keys = Vec::<u64>::new();
let mut popped_keys = Vec::<usize>::new();

self.amt.for_each_while(|epoch, bitfield| {
if epoch as ChainEpoch > until {
// break
return Ok(false);
}

popped_keys.push(epoch as u64);
popped_keys.push(epoch as usize);
popped_values |= bitfield;
Ok(true)
})?;
Expand All @@ -140,7 +140,7 @@ impl<'db, BS: BlockStore> BitFieldQueue<'db, BS> {
return Ok((BitField::new(), false));
}

self.amt.batch_delete(popped_keys)?;
self.amt.batch_delete(popped_keys, true)?;
Ok((popped_values, true))
}
}
Loading