Skip to content

Commit

Permalink
Move QuantSpec into the miner actor (#1521)
Browse files Browse the repository at this point in the history
Unfortunately, I had to duplicate a little bit of code in the market
actor, but I think it's better to do that than to put this mostly miner
specific logic in, e.g., the runtime.
  • Loading branch information
Stebalien authored Feb 9, 2024
1 parent d14c201 commit 76abc47
Show file tree
Hide file tree
Showing 22 changed files with 120 additions and 49 deletions.
17 changes: 14 additions & 3 deletions actors/market/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use fvm_ipld_encoding::{RawBytes, DAG_CBOR};
use fvm_ipld_hamt::BytesKey;
use fvm_shared::address::Address;
use fvm_shared::bigint::BigInt;
use fvm_shared::clock::{ChainEpoch, QuantSpec, EPOCH_UNDEFINED};
use fvm_shared::clock::{ChainEpoch, EPOCH_UNDEFINED};
use fvm_shared::deal::DealID;
use fvm_shared::econ::TokenAmount;
use fvm_shared::error::ExitCode;
Expand Down Expand Up @@ -1550,8 +1550,19 @@ fn balance_of(rt: &impl Runtime, owner: &Address) -> Result<TokenAmount, ActorEr
// Calculates the first update epoch for a deal ID that is no sooner than `earliest`.
// An ID is processed as a fixed offset within each `interval` of epochs.
pub fn next_update_epoch(id: DealID, interval: i64, earliest: ChainEpoch) -> ChainEpoch {
let q = QuantSpec { unit: interval, offset: id as i64 % interval };
q.quantize_up(earliest)
// Same logic as QuantSpec from the miner actor, but duplicated here to avoid unnecessary
// dependencies.
let offset = id as i64 % interval;
let remainder = (earliest - offset) % interval;
let quotient = (earliest - offset) / interval;

// Don't round if epoch falls on a quantization epoch or when negative (negative truncating
// division rounds up).
if remainder == 0 || earliest - offset < 0 {
interval * quotient + offset
} else {
interval * (quotient + 1) + offset
}
}

////////////////////////////////////////////////////////////////////////////////
Expand Down
4 changes: 3 additions & 1 deletion actors/miner/src/bitfield_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ use fil_actors_runtime::{ActorDowncast, Array};
use fvm_ipld_amt::Error as AmtError;
use fvm_ipld_bitfield::BitField;
use fvm_ipld_blockstore::Blockstore;
use fvm_shared::clock::{ChainEpoch, QuantSpec};
use fvm_shared::clock::ChainEpoch;
use itertools::Itertools;

use super::QuantSpec;

/// Wrapper for working with an AMT[ChainEpoch]*Bitfield functioning as a queue, bucketed by epoch.
/// Keys in the queue are quantized (upwards), modulo some offset, to reduce the cardinality of keys.
pub struct BitFieldQueue<'db, BS> {
Expand Down
4 changes: 3 additions & 1 deletion actors/miner/src/deadline_info.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
// Copyright 2019-2022 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

use fvm_shared::clock::{ChainEpoch, QuantSpec};
use fvm_shared::clock::ChainEpoch;
use serde::{Deserialize, Serialize};

use crate::QuantSpec;

/// Deadline calculations with respect to a current epoch.
/// "Deadline" refers to the window during which proofs may be submitted.
/// Windows are non-overlapping ranges [Open, Close), but the challenge epoch for a window occurs
Expand Down
4 changes: 2 additions & 2 deletions actors/miner/src/deadline_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ use fvm_ipld_bitfield::BitField;
use fvm_ipld_blockstore::Blockstore;
use fvm_ipld_encoding::tuple::*;
use fvm_ipld_encoding::CborStore;
use fvm_shared::clock::{ChainEpoch, QuantSpec};
use fvm_shared::clock::ChainEpoch;
use fvm_shared::econ::TokenAmount;
use fvm_shared::error::ExitCode;
use fvm_shared::sector::{PoStProof, SectorSize};
use num_traits::{Signed, Zero};

use super::{
BitFieldQueue, ExpirationSet, Partition, PartitionSectorMap, PoStPartition, PowerPair,
SectorOnChainInfo, Sectors, TerminationResult,
QuantSpec, SectorOnChainInfo, Sectors, TerminationResult,
};
use crate::SECTORS_AMT_BITWIDTH;

Expand Down
4 changes: 2 additions & 2 deletions actors/miner/src/deadlines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ use fil_actors_runtime::runtime::Policy;
use fil_actors_runtime::Array;

use fvm_ipld_blockstore::Blockstore;
use fvm_shared::clock::{ChainEpoch, QuantSpec};
use fvm_shared::clock::ChainEpoch;
use fvm_shared::sector::SectorNumber;

use super::{DeadlineInfo, Deadlines, Partition};
use super::{DeadlineInfo, Deadlines, Partition, QuantSpec};

pub fn new_deadline_info(
policy: &Policy,
Expand Down
4 changes: 2 additions & 2 deletions actors/miner/src/expiration_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ use fvm_ipld_bitfield::BitField;
use fvm_ipld_blockstore::Blockstore;
use fvm_ipld_encoding::tuple::*;

use fvm_shared::clock::{ChainEpoch, QuantSpec};
use fvm_shared::clock::ChainEpoch;
use fvm_shared::econ::TokenAmount;
use fvm_shared::sector::{SectorNumber, SectorSize};
use num_traits::{Signed, Zero};

use super::{power_for_sector, PowerPair, SectorOnChainInfo};
use super::{power_for_sector, PowerPair, QuantSpec, SectorOnChainInfo};

/// An internal limit on the cardinality of a bitfield in a queue entry.
/// This must be at least large enough to support the maximum number of sectors in a partition.
Expand Down
3 changes: 2 additions & 1 deletion actors/miner/src/expiration_queue/tests.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// Copyright 2019-2022 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

use crate::NO_QUANTIZATION;

use super::*;
use fil_actors_runtime::DealWeight;
use fvm_shared::clock::NO_QUANTIZATION;
use fvm_shared::sector::StoragePower;

#[test]
Expand Down
4 changes: 3 additions & 1 deletion actors/miner/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use fvm_ipld_encoding::ipld_block::IpldBlock;
use fvm_ipld_encoding::{from_slice, BytesDe, CborStore, RawBytes};
use fvm_shared::address::{Address, Payload, Protocol};
use fvm_shared::bigint::{BigInt, Integer};
use fvm_shared::clock::{ChainEpoch, QuantSpec};
use fvm_shared::clock::ChainEpoch;
use fvm_shared::deal::DealID;
use fvm_shared::econ::TokenAmount;
use fvm_shared::error::*;
Expand Down Expand Up @@ -59,6 +59,7 @@ use crate::ext::market::NO_ALLOCATION_ID;
pub use monies::*;
pub use partition_state::*;
pub use policy::*;
pub use quantize::*;
pub use sector_map::*;
pub use sectors::*;
pub use state::*;
Expand Down Expand Up @@ -90,6 +91,7 @@ mod monies;
mod notifications;
mod partition_state;
mod policy;
mod quantize;
mod sector_map;
mod sectors;
mod state;
Expand Down
5 changes: 3 additions & 2 deletions actors/miner/src/partition_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,16 @@ use fvm_ipld_bitfield::BitField;
use fvm_ipld_blockstore::Blockstore;
use fvm_ipld_encoding::tuple::*;
use fvm_shared::bigint::bigint_ser;
use fvm_shared::clock::{ChainEpoch, QuantSpec, NO_QUANTIZATION};
use fvm_shared::clock::ChainEpoch;
use fvm_shared::econ::TokenAmount;
use fvm_shared::error::ExitCode;
use fvm_shared::sector::{SectorSize, StoragePower};
use num_traits::{Signed, Zero};

use super::{
power_for_sectors, select_sectors, validate_partition_contains_sectors, BitFieldQueue,
ExpirationQueue, ExpirationSet, SectorOnChainInfo, Sectors, TerminationResult,
ExpirationQueue, ExpirationSet, QuantSpec, SectorOnChainInfo, Sectors, TerminationResult,
NO_QUANTIZATION,
};

// Bitwidth of AMTs determined empirically from mutation patterns and projections of mainnet data.
Expand Down
53 changes: 53 additions & 0 deletions actors/miner/src/quantize.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright 2021-2023 Protocol Labs
// Copyright 2019-2022 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

use fvm_shared::clock::ChainEpoch;

/// Constant defining the [QuantSpec] which performs no quantization.
pub const NO_QUANTIZATION: QuantSpec = QuantSpec { unit: 1, offset: 0 };

/// A spec for epoch quantization.
#[derive(Copy, Clone)]
pub struct QuantSpec {
/// The unit of quantization
pub unit: ChainEpoch,
/// The offset from zero from which to base the modulus
pub offset: ChainEpoch,
}

impl QuantSpec {
/// Rounds `epoch` to the nearest exact multiple of the quantization unit offset by
/// `offset % unit`, rounding up.
///
/// This function is equivalent to `unit * ceil(epoch - (offset % unit) / unit) + (offsetSeed % unit)`
/// with the variables/operations over real numbers instead of ints.
///
/// Precondition: `unit >= 0`
pub fn quantize_up(&self, epoch: ChainEpoch) -> ChainEpoch {
let offset = self.offset % self.unit;

let remainder = (epoch - offset) % self.unit;
let quotient = (epoch - offset) / self.unit;

// Don't round if epoch falls on a quantization epoch
if remainder == 0
// Negative truncating division rounds up
|| epoch - offset < 0
{
self.unit * quotient + offset
} else {
self.unit * (quotient + 1) + offset
}
}

pub fn quantize_down(&self, epoch: ChainEpoch) -> ChainEpoch {
let next = self.quantize_up(epoch);
// QuantizeDown == QuantizeUp iff epoch is a fixed point of QuantizeUp
if epoch == next {
next
} else {
next - self.unit
}
}
}
4 changes: 2 additions & 2 deletions actors/miner/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use fvm_ipld_encoding::{strict_bytes, BytesDe, CborStore};
use fvm_ipld_hamt::Error as HamtError;
use fvm_shared::address::Address;

use fvm_shared::clock::{ChainEpoch, QuantSpec, EPOCH_UNDEFINED};
use fvm_shared::clock::{ChainEpoch, EPOCH_UNDEFINED};
use fvm_shared::econ::TokenAmount;
use fvm_shared::error::ExitCode;
use fvm_shared::sector::{RegisteredPoStProof, SectorNumber, SectorSize};
Expand All @@ -37,7 +37,7 @@ use super::types::*;
use super::{
assign_deadlines, deadline_is_mutable, new_deadline_info_from_offset_and_epoch,
quant_spec_for_deadline, BitFieldQueue, Deadline, DeadlineInfo, DeadlineSectorMap, Deadlines,
PowerPair, Sectors, TerminationResult, VestingFunds,
PowerPair, QuantSpec, Sectors, TerminationResult, VestingFunds,
};

const PRECOMMIT_EXPIRY_AMT_BITWIDTH: u32 = 6;
Expand Down
5 changes: 3 additions & 2 deletions actors/miner/src/testing.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::{
power_for_sectors, BitFieldQueue, Deadline, ExpirationQueue, MinerInfo, Partition, PowerPair,
SectorOnChainInfo, SectorOnChainInfoFlags, SectorPreCommitOnChainInfo, Sectors, State,
QuantSpec, SectorOnChainInfo, SectorOnChainInfoFlags, SectorPreCommitOnChainInfo, Sectors,
State, NO_QUANTIZATION,
};
use fil_actors_runtime::runtime::Policy;
use fil_actors_runtime::{
Expand All @@ -10,7 +11,7 @@ use fvm_ipld_bitfield::BitField;
use fvm_ipld_blockstore::Blockstore;
use fvm_ipld_encoding::CborStore;
use fvm_shared::address::Protocol;
use fvm_shared::clock::{ChainEpoch, QuantSpec, NO_QUANTIZATION};
use fvm_shared::clock::ChainEpoch;
use fvm_shared::econ::TokenAmount;
use fvm_shared::sector::{RegisteredPoStProof, SectorNumber, SectorSize};
use num_traits::Zero;
Expand Down
4 changes: 2 additions & 2 deletions actors/miner/src/vesting_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
use std::{iter, mem};

use fvm_ipld_encoding::tuple::*;
use fvm_shared::clock::{ChainEpoch, QuantSpec};
use fvm_shared::clock::ChainEpoch;
use fvm_shared::econ::TokenAmount;
use itertools::{EitherOrBoth, Itertools};
use num_traits::Zero;

use super::VestSpec;
use super::{QuantSpec, VestSpec};

// Represents miner funds that will vest at the given epoch.
#[derive(Debug, Serialize_tuple, Deserialize_tuple)]
Expand Down
9 changes: 4 additions & 5 deletions actors/miner/tests/apply_rewards.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use fil_actor_miner::locked_reward_from_reward;
use fil_actor_miner::ApplyRewardParams;
use fil_actor_miner::REWARD_VESTING_SPEC;
use fil_actor_miner::{Actor, Method};
use fil_actor_miner::{
locked_reward_from_reward, Actor, ApplyRewardParams, Method, QuantSpec, REWARD_VESTING_SPEC,
};
use fil_actor_power::Method as PowerMethod;
use fil_actors_runtime::runtime::Runtime;
use fil_actors_runtime::runtime::RuntimePolicy;
Expand All @@ -11,7 +10,7 @@ use fil_actors_runtime::REWARD_ACTOR_ADDR;
use fil_actors_runtime::STORAGE_POWER_ACTOR_ADDR;

use fvm_shared::bigint::Zero;
use fvm_shared::clock::{ChainEpoch, QuantSpec};
use fvm_shared::clock::ChainEpoch;
use fvm_shared::econ::TokenAmount;
use fvm_shared::error::ExitCode;
use fvm_shared::METHOD_SEND;
Expand Down
6 changes: 3 additions & 3 deletions actors/miner/tests/deadline_cron.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use fil_actor_miner::testing::{check_deadline_state_invariants, DeadlineStateSummary};
use fil_actor_miner::{
pledge_penalty_for_continued_fault, power_for_sectors, Deadline, PowerPair, SectorOnChainInfo,
REWARD_VESTING_SPEC,
pledge_penalty_for_continued_fault, power_for_sectors, Deadline, PowerPair, QuantSpec,
SectorOnChainInfo, REWARD_VESTING_SPEC,
};
use fil_actors_runtime::runtime::RuntimePolicy;
use fil_actors_runtime::test_utils::MockRuntime;
use fil_actors_runtime::{MessageAccumulator, EPOCHS_IN_DAY};
use fvm_ipld_bitfield::BitField;
use fvm_shared::bigint::Zero;
use fvm_shared::clock::{ChainEpoch, QuantSpec};
use fvm_shared::clock::ChainEpoch;
use fvm_shared::econ::TokenAmount;
use fvm_shared::sector::SectorSize;
use std::ops::Neg;
Expand Down
6 changes: 3 additions & 3 deletions actors/miner/tests/deadline_state_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use std::collections::HashMap;

use fil_actor_miner::testing::{check_deadline_state_invariants, DeadlineStateSummary};
use fil_actor_miner::{
power_for_sectors, Deadline, PartitionSectorMap, PoStPartition, PowerPair, SectorOnChainInfo,
TerminationResult,
power_for_sectors, Deadline, PartitionSectorMap, PoStPartition, PowerPair, QuantSpec,
SectorOnChainInfo, TerminationResult,
};
use fil_actors_runtime::runtime::{Policy, Runtime};
use fil_actors_runtime::test_utils::MockRuntime;
Expand All @@ -12,7 +12,7 @@ use fil_actors_runtime::MessageAccumulator;
use fvm_ipld_bitfield::BitField;
use fvm_ipld_blockstore::Blockstore;
use fvm_shared::clock::ChainEpoch;
use fvm_shared::{clock::QuantSpec, error::ExitCode, sector::SectorSize};
use fvm_shared::{error::ExitCode, sector::SectorSize};

mod util;
use crate::util::*;
Expand Down
5 changes: 3 additions & 2 deletions actors/miner/tests/expiration_queue.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use fil_actor_miner::{
power_for_sectors, ExpirationQueue, ExpirationSet, PowerPair, SectorOnChainInfo,
power_for_sectors, ExpirationQueue, ExpirationSet, PowerPair, QuantSpec, SectorOnChainInfo,
NO_QUANTIZATION,
};
use fil_actors_runtime::test_blockstores::MemoryBlockstore;
use fil_actors_runtime::{
Expand All @@ -9,7 +10,7 @@ use fil_actors_runtime::{
use fvm_ipld_amt::Amt;
use fvm_ipld_bitfield::{BitField, MaybeBitField};
use fvm_shared::bigint::Zero;
use fvm_shared::clock::{ChainEpoch, QuantSpec, NO_QUANTIZATION};
use fvm_shared::clock::ChainEpoch;
use fvm_shared::econ::TokenAmount;
use fvm_shared::sector::{SectorNumber, SectorSize, StoragePower};
use std::convert::TryInto;
Expand Down
4 changes: 2 additions & 2 deletions actors/miner/tests/miner_actor_test_bitfield_queue.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use fil_actor_miner::BitFieldQueue;
use fil_actor_miner::{BitFieldQueue, QuantSpec, NO_QUANTIZATION};
use fil_actors_runtime::test_blockstores::MemoryBlockstore;
use fil_actors_runtime::test_utils::MockRuntime;
use fvm_ipld_amt::Amt;
use fvm_ipld_bitfield::BitField;
use fvm_ipld_bitfield::MaybeBitField;
use fvm_shared::clock::{ChainEpoch, QuantSpec, NO_QUANTIZATION};
use fvm_shared::clock::ChainEpoch;
use std::iter::FromIterator;

mod util;
Expand Down
4 changes: 2 additions & 2 deletions actors/miner/tests/miner_actor_test_partitions.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use fil_actor_miner::{
power_for_sectors, testing::PartitionStateSummary, BitFieldQueue, ExpirationQueue, Partition,
PowerPair, SectorOnChainInfo,
PowerPair, QuantSpec, SectorOnChainInfo,
};
use fil_actors_runtime::runtime::Policy;
use fil_actors_runtime::test_blockstores::MemoryBlockstore;
use fil_actors_runtime::test_utils::*;
use fil_actors_runtime::MessageAccumulator;
use fvm_ipld_bitfield::BitField;
use fvm_ipld_encoding::RawBytes;
use fvm_shared::clock::{ChainEpoch, QuantSpec};
use fvm_shared::clock::ChainEpoch;
use fvm_shared::econ::TokenAmount;
use fvm_shared::sector::{RegisteredSealProof, SectorSize};

Expand Down
2 changes: 1 addition & 1 deletion actors/miner/tests/record_skipped_faults.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use fil_actor_miner::power_for_sectors;
use fil_actor_miner::select_sectors;
use fil_actor_miner::testing::PartitionStateSummary;
use fil_actor_miner::Partition;
use fil_actor_miner::QuantSpec;
use fil_actor_miner::SectorOnChainInfo;
use fil_actors_runtime::runtime::Policy;
use fil_actors_runtime::ActorError;
Expand All @@ -10,7 +11,6 @@ use fvm_ipld_bitfield::BitField;

use fil_actors_runtime::test_blockstores::MemoryBlockstore;
use fvm_shared::clock::ChainEpoch;
use fvm_shared::clock::QuantSpec;
use fvm_shared::error::ExitCode;
use fvm_shared::sector::SectorSize;
use std::ops::Neg;
Expand Down
Loading

0 comments on commit 76abc47

Please sign in to comment.