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

fix(miner)!: remove DEAL_WEIGHT_MULTIPLIER and its input to QAP calc #1574

Merged
merged 1 commit into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 4 additions & 18 deletions actors/miner/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3892,12 +3892,8 @@ fn extend_simple_qap_sector(

// We only bother updating the expected_day_reward, expected_storage_pledge, and replaced_day_reward
// for verified deals, as it can increase power.
let qa_pow = qa_power_for_weight(
sector_size,
new_duration,
&new_sector.deal_weight,
&new_sector.verified_deal_weight,
);
let qa_pow =
qa_power_for_weight(sector_size, new_duration, &new_sector.verified_deal_weight);
new_sector.expected_day_reward = expected_reward_for_power(
&reward_stats.this_epoch_reward_smoothed,
&power_stats.quality_adj_power_smoothed,
Expand Down Expand Up @@ -4283,12 +4279,7 @@ fn update_existing_sector_info(
new_sector_info.verified_deal_weight = activated_data.verified_space.clone() * duration;

// compute initial pledge
let qa_pow = qa_power_for_weight(
sector_size,
duration,
&new_sector_info.deal_weight,
&new_sector_info.verified_deal_weight,
);
let qa_pow = qa_power_for_weight(sector_size, duration, &new_sector_info.verified_deal_weight);

new_sector_info.replaced_day_reward =
max(&sector_info.expected_day_reward, &sector_info.replaced_day_reward).clone();
Expand Down Expand Up @@ -5530,12 +5521,7 @@ fn activate_new_sector_infos(
let deal_weight = &deal_spaces.unverified_space * duration;
let verified_deal_weight = &deal_spaces.verified_space * duration;

let power = qa_power_for_weight(
info.sector_size,
duration,
&deal_weight,
&verified_deal_weight,
);
let power = qa_power_for_weight(info.sector_size, duration, &verified_deal_weight);

let day_reward = expected_reward_for_power(
&pledge_inputs.epoch_reward,
Expand Down
23 changes: 7 additions & 16 deletions actors/miner/src/policy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ lazy_static! {
/// Quality multiplier for committed capacity (no deals) in a sector
pub static ref QUALITY_BASE_MULTIPLIER: BigInt = BigInt::from(10);

/// Quality multiplier for unverified deals in a sector
pub static ref DEAL_WEIGHT_MULTIPLIER: BigInt = BigInt::from(10);

/// Quality multiplier for verified deals in a sector
pub static ref VERIFIED_DEAL_WEIGHT_MULTIPLIER: BigInt = BigInt::from(100);

Expand Down Expand Up @@ -119,27 +116,22 @@ pub fn seal_proof_sector_maximum_lifetime(proof: RegisteredSealProof) -> Option<
/// minimum number of epochs past the current epoch a sector may be set to expire
pub const MIN_SECTOR_EXPIRATION: i64 = 180 * EPOCHS_IN_DAY;

/// DealWeight and VerifiedDealWeight are spacetime occupied by regular deals and verified deals in a sector.
/// Sum of DealWeight and VerifiedDealWeight should be less than or equal to total SpaceTime of a sector.
/// VerifiedDealWeight is spacetime occupied by verified pieces in a sector.
/// VerifiedDealWeight should be less than or equal to total SpaceTime of a sector.
/// Sectors full of VerifiedDeals will have a BigInt of VerifiedDealWeightMultiplier/QualityBaseMultiplier.
/// Sectors full of Deals will have a BigInt of DealWeightMultiplier/QualityBaseMultiplier.
/// Sectors with neither will have a BigInt of QualityBaseMultiplier/QualityBaseMultiplier.
/// Sectors without VerifiedDeals will have a BigInt of QualityBaseMultiplier/QualityBaseMultiplier.
/// BigInt of a sector is a weighted average of multipliers based on their proportions.
pub fn quality_for_weight(
size: SectorSize,
duration: ChainEpoch,
deal_weight: &DealWeight,
verified_weight: &DealWeight,
) -> BigInt {
let sector_space_time = BigInt::from(size as u64) * BigInt::from(duration);
let total_deal_space_time = deal_weight + verified_weight;

let weighted_base_space_time =
(&sector_space_time - total_deal_space_time) * &*QUALITY_BASE_MULTIPLIER;
let weighted_deal_space_time = deal_weight * &*DEAL_WEIGHT_MULTIPLIER;
(&sector_space_time - verified_weight) * &*QUALITY_BASE_MULTIPLIER;
let weighted_verified_space_time = verified_weight * &*VERIFIED_DEAL_WEIGHT_MULTIPLIER;
let weighted_sum_space_time =
weighted_base_space_time + weighted_deal_space_time + weighted_verified_space_time;
let weighted_sum_space_time = weighted_base_space_time + weighted_verified_space_time;
let scaled_up_weighted_sum_space_time: BigInt =
weighted_sum_space_time << SECTOR_QUALITY_PRECISION;

Expand All @@ -158,17 +150,16 @@ pub fn qa_power_max(size: SectorSize) -> StoragePower {
pub fn qa_power_for_weight(
size: SectorSize,
duration: ChainEpoch,
deal_weight: &DealWeight,
verified_weight: &DealWeight,
) -> StoragePower {
let quality = quality_for_weight(size, duration, deal_weight, verified_weight);
let quality = quality_for_weight(size, duration, verified_weight);
(BigInt::from(size as u64) * quality) >> SECTOR_QUALITY_PRECISION
}

/// Returns the quality-adjusted power for a sector.
pub fn qa_power_for_sector(size: SectorSize, sector: &SectorOnChainInfo) -> StoragePower {
let duration = sector.expiration - sector.power_base_epoch;
qa_power_for_weight(size, duration, &sector.deal_weight, &sector.verified_deal_weight)
qa_power_for_weight(size, duration, &sector.verified_deal_weight)
}

pub fn raw_power_for_sector(size: SectorSize) -> StoragePower {
Expand Down
1 change: 0 additions & 1 deletion actors/miner/tests/aggregate_prove_commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ fn valid_precommits_then_aggregate_provecommit() {
let qa_power = qa_power_for_weight(
actor.sector_size,
expiration - *rt.epoch.borrow(),
&deal_weight,
&verified_deal_weight,
);
assert_eq!(expected_power, qa_power);
Expand Down
108 changes: 76 additions & 32 deletions actors/miner/tests/policy_test.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
use fil_actor_miner::{qa_power_for_weight, quality_for_weight};
use fil_actor_miner::{
DEAL_WEIGHT_MULTIPLIER, QUALITY_BASE_MULTIPLIER, SECTOR_QUALITY_PRECISION,
VERIFIED_DEAL_WEIGHT_MULTIPLIER,
QUALITY_BASE_MULTIPLIER, SECTOR_QUALITY_PRECISION, VERIFIED_DEAL_WEIGHT_MULTIPLIER,
};
use fil_actors_runtime::DealWeight;
use fil_actors_runtime::{EPOCHS_IN_DAY, SECONDS_IN_DAY};
use fvm_shared::bigint::{BigInt, Zero};
use fvm_shared::bigint::{BigInt, Integer, Zero};
use fvm_shared::clock::ChainEpoch;
use fvm_shared::sector::SectorSize;

#[test]
fn quality_is_independent_of_size_and_duration() {
// Quality of space with no deals. This doesn't depend on either the sector size or duration.
let empty_quality = BigInt::from(1 << SECTOR_QUALITY_PRECISION);
// Quality space filled with non-verified deals.
let deal_quality =
&empty_quality * (DEAL_WEIGHT_MULTIPLIER.clone() / QUALITY_BASE_MULTIPLIER.clone());
// Quality space filled with verified deals.
let verified_quality = &empty_quality
* (VERIFIED_DEAL_WEIGHT_MULTIPLIER.clone() / QUALITY_BASE_MULTIPLIER.clone());
// Quality space half filled with verified deals.
let half_verified_quality =
&empty_quality / BigInt::from(2) + &verified_quality / BigInt::from(2);

let size_range: Vec<SectorSize> = vec![
SectorSize::_2KiB,
Expand All @@ -32,21 +32,50 @@ fn quality_is_independent_of_size_and_duration() {
ChainEpoch::from(1000),
1000 * EPOCHS_IN_DAY,
];
let zero = &BigInt::zero();

for size in size_range {
for duration in &duration_range {
let sector_weight = weight(size, *duration);
let full_weight = weight(size, *duration);
let half_weight = &full_weight.checked_div(&BigInt::from(2)).unwrap();

assert_eq!(empty_quality, quality_for_weight(size, *duration, zero));
assert_eq!(verified_quality, quality_for_weight(size, *duration, &full_weight));
assert_eq!(half_verified_quality, quality_for_weight(size, *duration, half_weight));

// test against old form that takes a deal_weight argument
assert_eq!(empty_quality, original_quality_for_weight(size, *duration, zero, zero));
assert_eq!(
empty_quality,
original_quality_for_weight(size, *duration, &full_weight, zero)
);
assert_eq!(
empty_quality,
quality_for_weight(size, *duration, &BigInt::zero(), &BigInt::zero()),
original_quality_for_weight(size, *duration, half_weight, zero)
);
assert_eq!(
verified_quality,
original_quality_for_weight(size, *duration, zero, &full_weight)
);
assert_eq!(
deal_quality,
quality_for_weight(size, *duration, &sector_weight, &BigInt::zero()),
verified_quality,
original_quality_for_weight(size, *duration, half_weight, &full_weight)
);
assert_eq!(
verified_quality,
quality_for_weight(size, *duration, &BigInt::zero(), &sector_weight),
original_quality_for_weight(size, *duration, &full_weight, &full_weight)
);
assert_eq!(
half_verified_quality,
original_quality_for_weight(size, *duration, zero, half_weight)
);
assert_eq!(
half_verified_quality,
original_quality_for_weight(size, *duration, half_weight, half_weight)
);
assert_eq!(
half_verified_quality,
original_quality_for_weight(size, *duration, &full_weight, half_weight)
);
}
}
Expand Down Expand Up @@ -86,7 +115,7 @@ fn quality_scales_with_verified_weight_proportion() {
let expected_quality = (eq + vq) / &sector_weight;
assert_eq!(
expected_quality,
quality_for_weight(sector_size, sector_duration, &BigInt::zero(), &verified_weight),
quality_for_weight(sector_size, sector_duration, &verified_weight),
);
}
}
Expand All @@ -109,10 +138,7 @@ fn empty_sector_has_power_equal_to_size() {
for size in size_range {
for duration in &duration_range {
let expected_power = BigInt::from(size as i64);
assert_eq!(
expected_power,
qa_power_for_weight(size, *duration, &BigInt::zero(), &BigInt::zero())
);
assert_eq!(expected_power, qa_power_for_weight(size, *duration, &BigInt::zero()));
}
}
}
Expand All @@ -138,10 +164,7 @@ fn verified_sector_has_power_a_multiple_of_size() {
for duration in &duration_range {
let verified_weight = weight(size, *duration);
let expected_power = size as i64 * &verified_multiplier;
assert_eq!(
expected_power,
qa_power_for_weight(size, *duration, &BigInt::zero(), &verified_weight)
);
assert_eq!(expected_power, qa_power_for_weight(size, *duration, &verified_weight));
}
}
}
Expand Down Expand Up @@ -186,12 +209,7 @@ fn verified_weight_adds_proportional_power() {
let ep = empty_weight * &fully_empty_power;
let vp = &verified_weight * &fully_verified_power;
let expected_power = (ep + vp) / &sector_weight;
let power = qa_power_for_weight(
sector_size,
sector_duration,
&BigInt::zero(),
&verified_weight,
);
let power = qa_power_for_weight(sector_size, sector_duration, &verified_weight);
let power_error = expected_power - power;
assert!(power_error <= max_error);
}
Expand All @@ -209,16 +227,16 @@ fn demonstrate_standard_sectors() {

assert_eq!(
BigInt::from(sector_size as u64),
qa_power_for_weight(sector_size, sector_duration, &BigInt::zero(), &BigInt::zero())
qa_power_for_weight(sector_size, sector_duration, &BigInt::zero())
);
assert_eq!(
&vmul * sector_size as u64,
qa_power_for_weight(sector_size, sector_duration, &BigInt::zero(), &sector_weight)
qa_power_for_weight(sector_size, sector_duration, &sector_weight)
);
let half_verified_power = ((sector_size as u64) / 2) + (&vmul * (sector_size as u64) / 2);
assert_eq!(
half_verified_power,
qa_power_for_weight(sector_size, sector_duration, &BigInt::zero(), &(sector_weight / 2))
qa_power_for_weight(sector_size, sector_duration, &(sector_weight / 2))
);

// 64GiB
Expand All @@ -227,16 +245,16 @@ fn demonstrate_standard_sectors() {

assert_eq!(
BigInt::from(sector_size as u64),
qa_power_for_weight(sector_size, sector_duration, &BigInt::zero(), &BigInt::zero())
qa_power_for_weight(sector_size, sector_duration, &BigInt::zero())
);
assert_eq!(
&vmul * sector_size as u64,
qa_power_for_weight(sector_size, sector_duration, &BigInt::zero(), &sector_weight)
qa_power_for_weight(sector_size, sector_duration, &sector_weight)
);
let half_verified_power = ((sector_size as u64) / 2) + (&vmul * (sector_size as u64) / 2);
assert_eq!(
half_verified_power,
qa_power_for_weight(sector_size, sector_duration, &BigInt::zero(), &(sector_weight / 2))
qa_power_for_weight(sector_size, sector_duration, &(sector_weight / 2))
);
}

Expand All @@ -247,3 +265,29 @@ fn weight(size: SectorSize, duration: ChainEpoch) -> BigInt {
fn weight_with_size_as_bigint(size: BigInt, duration: ChainEpoch) -> BigInt {
size * BigInt::from(duration)
}

// Original form of quality_for_weight prior to removing the deal weight multiplier; retained here
// for testing purposes. Since the deal weight multipler has remained fixed at the same value as
// the quality base multiplier (10) it has never had an effect on the result.
fn original_quality_for_weight(
size: SectorSize,
duration: ChainEpoch,
deal_weight: &DealWeight,
verified_weight: &DealWeight,
) -> BigInt {
let sector_space_time = BigInt::from(size as u64) * BigInt::from(duration);
let total_deal_space_time = deal_weight + verified_weight;

let weighted_base_space_time =
(&sector_space_time - total_deal_space_time) * &*QUALITY_BASE_MULTIPLIER;
let weighted_deal_space_time = deal_weight * BigInt::from(10);
let weighted_verified_space_time = verified_weight * &*VERIFIED_DEAL_WEIGHT_MULTIPLIER;
let weighted_sum_space_time =
weighted_base_space_time + weighted_deal_space_time + weighted_verified_space_time;
let scaled_up_weighted_sum_space_time: BigInt =
weighted_sum_space_time << SECTOR_QUALITY_PRECISION;

scaled_up_weighted_sum_space_time
.div_floor(&sector_space_time)
.div_floor(&QUALITY_BASE_MULTIPLIER)
}
19 changes: 5 additions & 14 deletions actors/miner/tests/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1203,19 +1203,12 @@ impl ActorHarness {
let mut expected_raw_power = BigInt::from(0);

for pc in valid_pcs {
let deal_space = cfg.deal_space(pc.info.sector_number);
let verified_deal_space = cfg.verified_deal_space(pc.info.sector_number);

let duration = pc.info.expiration - *rt.epoch.borrow();
let deal_weight = deal_space * duration;
let verified_deal_weight = verified_deal_space * duration;
if duration >= rt.policy.min_sector_expiration {
let qa_power_delta = qa_power_for_weight(
self.sector_size,
duration,
&deal_weight,
&verified_deal_weight,
);
let qa_power_delta =
qa_power_for_weight(self.sector_size, duration, &verified_deal_weight);
expected_qa_power += &qa_power_delta;
expected_raw_power += self.sector_size as u64;
expected_pledge += self.initial_pledge_for_power(rt, &qa_power_delta);
Expand Down Expand Up @@ -1382,8 +1375,7 @@ impl ActorHarness {
deal_size += piece.size.0 * duration as u64;
}
}
let qa_power_delta =
qa_power_for_weight(self.sector_size, duration, &deal_size, &verified_size);
let qa_power_delta = qa_power_for_weight(self.sector_size, duration, &verified_size);
expected_qa_power += &qa_power_delta;
expected_pledge += self.initial_pledge_for_power(rt, &qa_power_delta);
}
Expand Down Expand Up @@ -1596,9 +1588,8 @@ impl ActorHarness {
}
}

let qa_power_delta =
qa_power_for_weight(self.sector_size, duration, &deal_size, &verified_size)
- qa_power_for_sector(self.sector_size, &sector);
let qa_power_delta = qa_power_for_weight(self.sector_size, duration, &verified_size)
- qa_power_for_sector(self.sector_size, &sector);
expected_qa_power += &qa_power_delta;
expected_pledge += self.initial_pledge_for_power(rt, &qa_power_delta);
}
Expand Down
Loading