Skip to content

Commit

Permalink
fix(miner)!: remove DEAL_WEIGHT_MULTIPLIER and its input to QAP calc
Browse files Browse the repository at this point in the history
  • Loading branch information
rvagg committed Aug 19, 2024
1 parent 4d89bcf commit b4d5c60
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 21 deletions.
1 change: 1 addition & 0 deletions builtin/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ var TotalFilecoin = big.Mul(big.NewIntUnsigned(2_000_000_000), TokenPrecision)
var QualityBaseMultiplier = big.NewInt(10)

// Quality multiplier for unverified deals in a sector
// DEPRECATED: This is no longer used, but is kept here for reference.
var DealWeightMultiplier = big.NewInt(10)

// Quality multiplier for verified deals in a sector
Expand Down
36 changes: 15 additions & 21 deletions builtin/v15/miner/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,30 +141,24 @@ const MinSectorExpiration = 180 * builtin.EpochsInDay // PARAM_SPEC
// the associated seal proof's maximum lifetime.
const MaxSectorExpirationExtension = 1278 * builtin.EpochsInDay // PARAM_SPEC

// 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.
// Sectors full of VerifiedDeals will have a SectorQuality of VerifiedDealWeightMultiplier/QualityBaseMultiplier.
// Sectors full of Deals will have a SectorQuality of DealWeightMultiplier/QualityBaseMultiplier.
// Sectors with neither will have a SectorQuality of QualityBaseMultiplier/QualityBaseMultiplier.
// SectorQuality of a sector is a weighted average of multipliers based on their proportions.
func QualityForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, verifiedWeight abi.DealWeight) abi.SectorQuality {
// QualityForWeight calculates the quality of a sector with the given size, duration, and verified weight.
// 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 without VerifiedDeals will have a BigInt of QualityBaseMultiplier/QualityBaseMultiplier.
// BigInt of a sector is a weighted average of multipliers based on their proportions.
func QualityForWeight(size abi.SectorSize, duration abi.ChainEpoch, verifiedWeight abi.DealWeight) abi.SectorQuality {
// sectorSpaceTime = size * duration
sectorSpaceTime := big.Mul(big.NewIntUnsigned(uint64(size)), big.NewInt(int64(duration)))
// totalDealSpaceTime = dealWeight + verifiedWeight
totalDealSpaceTime := big.Add(dealWeight, verifiedWeight)

// Base - all size * duration of non-deals
// weightedBaseSpaceTime = (sectorSpaceTime - totalDealSpaceTime) * QualityBaseMultiplier
weightedBaseSpaceTime := big.Mul(big.Sub(sectorSpaceTime, totalDealSpaceTime), builtin.QualityBaseMultiplier)
// Deal - all deal size * deal duration * 10
// weightedDealSpaceTime = dealWeight * DealWeightMultiplier
weightedDealSpaceTime := big.Mul(dealWeight, builtin.DealWeightMultiplier)
// Base - all size * duration of non-verified deals
// weightedBaseSpaceTime = (sectorSpaceTime - verifiedWeight) * QualityBaseMultiplier
weightedBaseSpaceTime := big.Mul(big.Sub(sectorSpaceTime, verifiedWeight), builtin.QualityBaseMultiplier)
// Verified - all verified deal size * verified deal duration * 100
// weightedVerifiedSpaceTime = verifiedWeight * VerifiedDealWeightMultiplier
weightedVerifiedSpaceTime := big.Mul(verifiedWeight, builtin.VerifiedDealWeightMultiplier)
// Sum - sum of all spacetime
// weightedSumSpaceTime = weightedBaseSpaceTime + weightedDealSpaceTime + weightedVerifiedSpaceTime
weightedSumSpaceTime := big.Sum(weightedBaseSpaceTime, weightedDealSpaceTime, weightedVerifiedSpaceTime)
// weightedSumSpaceTime = weightedBaseSpaceTime + weightedVerifiedSpaceTime
weightedSumSpaceTime := big.Sum(weightedBaseSpaceTime, weightedVerifiedSpaceTime)
// scaledUpWeightedSumSpaceTime = weightedSumSpaceTime * 2^20
scaledUpWeightedSumSpaceTime := big.Lsh(weightedSumSpaceTime, builtin.SectorQualityPrecision)

Expand All @@ -173,15 +167,15 @@ func QualityForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight,
}

// The power for a sector size, committed duration, and weight.
func QAPowerForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, verifiedWeight abi.DealWeight) abi.StoragePower {
quality := QualityForWeight(size, duration, dealWeight, verifiedWeight)
func QAPowerForWeight(size abi.SectorSize, duration abi.ChainEpoch, verifiedWeight abi.DealWeight) abi.StoragePower {
quality := QualityForWeight(size, duration, verifiedWeight)
return big.Rsh(big.Mul(big.NewIntUnsigned(uint64(size)), quality), builtin.SectorQualityPrecision)
}

// The quality-adjusted power for a sector.
func QAPowerForSector(size abi.SectorSize, sector *SectorOnChainInfo) abi.StoragePower {
duration := sector.Expiration - sector.PowerBaseEpoch
return QAPowerForWeight(size, duration, sector.DealWeight, sector.VerifiedDealWeight)
return QAPowerForWeight(size, duration, sector.VerifiedDealWeight)
}

const MaxAggregatedSectors = 819
Expand Down
95 changes: 95 additions & 0 deletions builtin/v15/miner/policy_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package miner_test

import (
"testing"

abi "github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/builtin"
"github.com/filecoin-project/go-state-types/builtin/v15/miner"
"github.com/stretchr/testify/require"
)

/* Rust version:
#[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 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,
SectorSize::_8MiB,
SectorSize::_512MiB,
SectorSize::_32GiB,
SectorSize::_64GiB,
];
let duration_range: Vec<ChainEpoch> = vec![
ChainEpoch::from(1),
ChainEpoch::from(10),
ChainEpoch::from(1000),
1000 * EPOCHS_IN_DAY,
];
for size in size_range {
for duration in &duration_range {
let sector_weight = weight(size, *duration);
assert_eq!(empty_quality, quality_for_weight(size, *duration, &BigInt::zero()));
assert_eq!(verified_quality, quality_for_weight(size, *duration, &sector_weight));
assert_eq!(
half_verified_quality,
quality_for_weight(
size,
*duration,
&sector_weight.checked_div(&BigInt::from(2)).unwrap()
)
);
}
}
}
*/

func TestQualityForWeight(t *testing.T) {
emptyQuality := big.NewInt(1 << builtin.SectorQualityPrecision)
verifiedQuality := big.Mul(emptyQuality, big.Div(builtin.VerifiedDealWeightMultiplier, builtin.QualityBaseMultiplier))
halfVerifiedQuality := big.Add(big.Div(emptyQuality, big.NewInt(2)), big.Div(verifiedQuality, big.NewInt(2)))

sizeRange := []abi.SectorSize{
abi.SectorSize(2 << 10),
abi.SectorSize(8 << 20),
abi.SectorSize(512 << 20),
abi.SectorSize(32 << 30),
abi.SectorSize(64 << 30),
}
durationRange := []abi.ChainEpoch{
abi.ChainEpoch(1),
abi.ChainEpoch(10),
abi.ChainEpoch(1000),
1000 * builtin.EpochsInDay,
}

for _, size := range sizeRange {
for _, duration := range durationRange {
sectorWeight := big.NewInt(int64(size) * int64(duration))
require.Equal(t, emptyQuality, miner.QualityForWeight(size, duration, big.Zero()))
require.Equal(t, verifiedQuality, miner.QualityForWeight(size, duration, sectorWeight))
require.Equal(t, halfVerifiedQuality, miner.QualityForWeight(size, duration, big.Div(sectorWeight, big.NewInt(2))))
}
}
}

/*
fn weight(size: SectorSize, duration: ChainEpoch) -> BigInt {
BigInt::from(size as u64) * BigInt::from(duration)
}
fn weight_with_size_as_bigint(size: BigInt, duration: ChainEpoch) -> BigInt {
size * BigInt::from(duration)
}
*/

0 comments on commit b4d5c60

Please sign in to comment.