Skip to content
This repository has been archived by the owner on Jun 6, 2023. It is now read-only.

Commit

Permalink
fip8 update
Browse files Browse the repository at this point in the history
  • Loading branch information
anorth committed Sep 24, 2020
1 parent 9b6e750 commit e630995
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 27 deletions.
8 changes: 6 additions & 2 deletions actors/builtin/miner/miner_actor.go
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@ func (a Actor) SubmitWindowedPoSt(rt Runtime, params *SubmitWindowedPoStParams)
// the end-of-deadline cron.
undeclaredPenaltyTarget = big.Sub(undeclaredPenaltyTarget, PledgePenaltyForDeclaredFault(
rewardStats.ThisEpochRewardSmoothed, pwrTotal.QualityAdjPowerSmoothed, undeclaredPenaltyPower.QA,
networkVersion,
))
}

Expand All @@ -422,6 +423,7 @@ func (a Actor) SubmitWindowedPoSt(rt Runtime, params *SubmitWindowedPoStParams)
} else {
declaredPenaltyTarget = PledgePenaltyForDeclaredFault(
rewardStats.ThisEpochRewardSmoothed, pwrTotal.QualityAdjPowerSmoothed, postResult.RecoveredPower.QA,
networkVersion,
)
}

Expand Down Expand Up @@ -1666,7 +1668,8 @@ func handleProvingDeadline(rt Runtime) {
penaltyTarget := PledgePenaltyForUndeclaredFault(epochReward.ThisEpochRewardSmoothed, pwrTotal.QualityAdjPowerSmoothed,
penalizePowerTotal, rt.NetworkVersion())
// Subtract the "ongoing" fault fee from the amount charged now, since it will be added on just below.
penaltyTarget = big.Sub(penaltyTarget, PledgePenaltyForDeclaredFault(epochReward.ThisEpochRewardSmoothed, pwrTotal.QualityAdjPowerSmoothed, penalizePowerTotal))
penaltyTarget = big.Sub(penaltyTarget, PledgePenaltyForDeclaredFault(epochReward.ThisEpochRewardSmoothed,
pwrTotal.QualityAdjPowerSmoothed, penalizePowerTotal, networkVersion))
penaltyFromVesting, penaltyFromBalance, err := st.PenalizeFundsInPriorityOrder(store, currEpoch, penaltyTarget, unlockedBalance)
builtin.RequireNoErr(rt, err, exitcode.ErrIllegalState, "failed to unlock penalty")
unlockedBalance = big.Sub(unlockedBalance, penaltyFromBalance)
Expand All @@ -1682,7 +1685,8 @@ func handleProvingDeadline(rt Runtime) {
// From network version 3, this *excludes* any power that was just faulted from missing a PoSt.
ongoingFaultyPower = previouslyFaultyPower
}
penaltyTarget := PledgePenaltyForDeclaredFault(epochReward.ThisEpochRewardSmoothed, pwrTotal.QualityAdjPowerSmoothed, ongoingFaultyPower)
penaltyTarget := PledgePenaltyForDeclaredFault(epochReward.ThisEpochRewardSmoothed,
pwrTotal.QualityAdjPowerSmoothed, ongoingFaultyPower, networkVersion)
penaltyFromVesting, penaltyFromBalance, err := st.PenalizeFundsInPriorityOrder(store, currEpoch, penaltyTarget, unlockedBalance)
builtin.RequireNoErr(rt, err, exitcode.ErrIllegalState, "failed to unlock penalty")
unlockedBalance = big.Sub(unlockedBalance, penaltyFromBalance) //nolint:ineffassign
Expand Down
10 changes: 5 additions & 5 deletions actors/builtin/miner/miner_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func TestFaultFeeInvariants(t *testing.T) {
t.Run("Undeclared faults are more expensive than declared faults", func(t *testing.T) {
faultySectorPower := abi.NewStoragePower(1 << 50)

ff := PledgePenaltyForDeclaredFault(rewardEstimate, powerEstimate, faultySectorPower)
ff := PledgePenaltyForDeclaredFault(rewardEstimate, powerEstimate, faultySectorPower, nv)
sp := PledgePenaltyForUndeclaredFault(rewardEstimate, powerEstimate, faultySectorPower, nv)
assert.True(t, sp.GreaterThan(ff))
})
Expand Down Expand Up @@ -163,11 +163,11 @@ func TestFaultFeeInvariants(t *testing.T) {
totalFaultPower := big.Add(big.Add(faultySectorAPower, faultySectorBPower), faultySectorCPower)

// Declared faults
ffA := PledgePenaltyForDeclaredFault(rewardEstimate, powerEstimate, faultySectorAPower)
ffB := PledgePenaltyForDeclaredFault(rewardEstimate, powerEstimate, faultySectorBPower)
ffC := PledgePenaltyForDeclaredFault(rewardEstimate, powerEstimate, faultySectorCPower)
ffA := PledgePenaltyForDeclaredFault(rewardEstimate, powerEstimate, faultySectorAPower, nv)
ffB := PledgePenaltyForDeclaredFault(rewardEstimate, powerEstimate, faultySectorBPower, nv)
ffC := PledgePenaltyForDeclaredFault(rewardEstimate, powerEstimate, faultySectorCPower, nv)

ffAll := PledgePenaltyForDeclaredFault(rewardEstimate, powerEstimate, totalFaultPower)
ffAll := PledgePenaltyForDeclaredFault(rewardEstimate, powerEstimate, totalFaultPower, nv)

// Because we can introduce rounding error between 1 and zero for every penalty calculation
// we can at best expect n calculations of 1 power to be within n of 1 calculation of n powers.
Expand Down
23 changes: 12 additions & 11 deletions actors/builtin/miner/miner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -929,7 +929,7 @@ func TestWindowPost(t *testing.T) {
// Now submit PoSt
// Power should return for recovered sector.
// Recovery should be charged ongoing fee.
recoveryFee := actor.declaredFaultPenalty(infos)
recoveryFee := actor.declaredFaultPenalty(infos, rt.NetworkVersion())
cfg := &poStConfig{
expectedRawPowerDelta: pwr.Raw,
expectedQAPowerDelta: pwr.QA,
Expand Down Expand Up @@ -981,7 +981,7 @@ func TestWindowPost(t *testing.T) {
// Fee for skipped fault is undeclared fault fee, but it is split into the ongoing fault fee
// which is charged at next cron and the rest which is charged during submit PoSt.
undeclaredFee := actor.undeclaredFaultPenalty(infos[:1], rt.NetworkVersion())
declaredFee := actor.declaredFaultPenalty(infos[:1])
declaredFee := actor.declaredFaultPenalty(infos[:1], rt.NetworkVersion())
faultFee := big.Sub(undeclaredFee, declaredFee)

pwr := miner.PowerForSectors(actor.sectorSize, infos[:1])
Expand All @@ -1005,7 +1005,7 @@ func TestWindowPost(t *testing.T) {

// skip second fault
undeclaredFee = actor.undeclaredFaultPenalty(infos[1:], rt.NetworkVersion())
declaredFee = actor.declaredFaultPenalty(infos[1:])
declaredFee = actor.declaredFaultPenalty(infos[1:], rt.NetworkVersion())
faultFee = big.Sub(undeclaredFee, declaredFee)
pwr = miner.PowerForSectors(actor.sectorSize, infos[1:])

Expand All @@ -1020,7 +1020,7 @@ func TestWindowPost(t *testing.T) {
actor.submitWindowPoSt(rt, dlinfo, partitions, infos, cfg)

// expect ongoing fault from both sectors
advanceDeadline(rt, actor, &cronConfig{ongoingFaultsPenalty: actor.declaredFaultPenalty(infos)})
advanceDeadline(rt, actor, &cronConfig{ongoingFaultsPenalty: actor.declaredFaultPenalty(infos, rt.NetworkVersion())})
})

t.Run("skipped all sectors in a deadline may be skipped", func(t *testing.T) {
Expand Down Expand Up @@ -1051,7 +1051,7 @@ func TestWindowPost(t *testing.T) {
// Fee for skipped fault is undeclared fault fee, but it is split into the ongoing fault fee
// which is charged at next cron and the rest which is charged during submit PoSt.
undeclaredFee := actor.undeclaredFaultPenalty(infos, rt.NetworkVersion())
declaredFee := actor.declaredFaultPenalty(infos)
declaredFee := actor.declaredFaultPenalty(infos, rt.NetworkVersion())
faultFee := big.Sub(undeclaredFee, declaredFee)

pwr := miner.PowerForSectors(actor.sectorSize, infos)
Expand Down Expand Up @@ -1105,7 +1105,7 @@ func TestWindowPost(t *testing.T) {
// Now submit PoSt and skip recovered sector
// No power should be returned
// Retracted recovery will be charged difference between undeclared and ongoing fault fees
ongoingFee := actor.declaredFaultPenalty(infos)
ongoingFee := actor.declaredFaultPenalty(infos, rt.NetworkVersion())
recoveryFee := big.Sub(actor.undeclaredFaultPenalty(infos, rt.NetworkVersion()), ongoingFee)
cfg := &poStConfig{
expectedRawPowerDelta: big.Zero(),
Expand Down Expand Up @@ -1313,11 +1313,12 @@ func TestDeadlineCron(t *testing.T) {
retractedPwr := miner.PowerForSectors(actor.sectorSize, allSectors[1:])
retractedPenalty := miner.PledgePenaltyForUndeclaredFault(actor.epochRewardSmooth, actor.epochQAPowerSmooth, retractedPwr.QA, rt.NetworkVersion())
// subtract ongoing penalty, because it's charged below (this prevents round-off mismatches)
retractedPenalty = big.Sub(retractedPenalty, miner.PledgePenaltyForDeclaredFault(actor.epochRewardSmooth, actor.epochQAPowerSmooth, retractedPwr.QA))
retractedPenalty = big.Sub(retractedPenalty,
miner.PledgePenaltyForDeclaredFault(actor.epochRewardSmooth, actor.epochQAPowerSmooth, retractedPwr.QA, rt.NetworkVersion()))

// Un-recovered faults are charged as ongoing faults
ongoingPwr := miner.PowerForSectors(actor.sectorSize, allSectors)
ongoingPenalty := miner.PledgePenaltyForDeclaredFault(actor.epochRewardSmooth, actor.epochQAPowerSmooth, ongoingPwr.QA)
ongoingPenalty := miner.PledgePenaltyForDeclaredFault(actor.epochRewardSmooth, actor.epochQAPowerSmooth, ongoingPwr.QA, rt.NetworkVersion())

advanceDeadline(rt, actor, &cronConfig{
detectedFaultsPenalty: retractedPenalty,
Expand Down Expand Up @@ -1413,7 +1414,7 @@ func TestDeclareFaults(t *testing.T) {

// faults are charged at ongoing rate and no additional power is removed
ongoingPwr := miner.PowerForSectors(actor.sectorSize, allSectors)
ongoingPenalty := miner.PledgePenaltyForDeclaredFault(actor.epochRewardSmooth, actor.epochQAPowerSmooth, ongoingPwr.QA)
ongoingPenalty := miner.PledgePenaltyForDeclaredFault(actor.epochRewardSmooth, actor.epochQAPowerSmooth, ongoingPwr.QA, rt.NetworkVersion())

advanceDeadline(rt, actor, &cronConfig{
ongoingFaultsPenalty: ongoingPenalty,
Expand Down Expand Up @@ -3193,9 +3194,9 @@ func (h *actorHarness) withdrawFunds(rt *mock.Runtime, amount abi.TokenAmount) {
rt.Verify()
}

func (h *actorHarness) declaredFaultPenalty(sectors []*miner.SectorOnChainInfo) abi.TokenAmount {
func (h *actorHarness) declaredFaultPenalty(sectors []*miner.SectorOnChainInfo, nv network.Version) abi.TokenAmount {
_, qa := powerForSectors(h.sectorSize, sectors)
return miner.PledgePenaltyForDeclaredFault(h.epochRewardSmooth, h.epochQAPowerSmooth, qa)
return miner.PledgePenaltyForDeclaredFault(h.epochRewardSmooth, h.epochQAPowerSmooth, qa, nv)
}

func (h *actorHarness) undeclaredFaultPenalty(sectors []*miner.SectorOnChainInfo, nv network.Version) abi.TokenAmount {
Expand Down
21 changes: 12 additions & 9 deletions actors/builtin/miner/monies.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,19 @@ var SpaceRaceInitialPledgeMaxPerByte = big.Div(big.NewInt(1e18), big.NewInt(32 <

// FF = BR(t, DeclaredFaultProjectionPeriod)
// projection period of 2.14 days: 2880 * 2.14 = 6163.2. Rounded to nearest epoch 6163
var DeclaredFaultFactorNum = 214
var DeclaredFaultFactorNumV0 = 214
var DeclaredFaultFactorNumV3 = 315
var DeclaredFaultFactorDenom = 100
var DeclaredFaultProjectionPeriod = abi.ChainEpoch((builtin.EpochsInDay * DeclaredFaultFactorNum) / DeclaredFaultFactorDenom)
var DeclaredFaultProjectionPeriodV0 = abi.ChainEpoch((builtin.EpochsInDay * DeclaredFaultFactorNumV0) / DeclaredFaultFactorDenom)
var DeclaredFaultProjectionPeriodV3 = abi.ChainEpoch((builtin.EpochsInDay * DeclaredFaultFactorNumV3) / DeclaredFaultFactorDenom)

// SP = BR(t, UndeclaredFaultProjectionPeriod)
var UndeclaredFaultFactorNumV0 = 50
var UndeclaredFaultFactorNumV1 = 35
var UndeclaredFaultFactorNumV3 = 15
var UndeclaredFaultFactorDenom = 10

var UndeclaredFaultProjectionPeriodV0 = abi.ChainEpoch((builtin.EpochsInDay * UndeclaredFaultFactorNumV0) / UndeclaredFaultFactorDenom)
var UndeclaredFaultProjectionPeriodV1 = abi.ChainEpoch((builtin.EpochsInDay * UndeclaredFaultFactorNumV1) / UndeclaredFaultFactorDenom)
var UndeclaredFaultProjectionPeriodV3 = abi.ChainEpoch((builtin.EpochsInDay * UndeclaredFaultFactorNumV3) / UndeclaredFaultFactorDenom)

// Maximum number of days of BR a terminated sector can be penalized
const TerminationLifetimeCap = abi.ChainEpoch(70)
Expand All @@ -62,18 +62,21 @@ func ExpectedRewardForPower(rewardEstimate, networkQAPowerEstimate *smoothing.Fi
// This is the FF(t) penalty for a sector expected to be in the fault state either because the fault was declared or because
// it has been previously detected by the network.
// FF(t) = DeclaredFaultFactor * BR(t)
func PledgePenaltyForDeclaredFault(rewardEstimate, networkQAPowerEstimate *smoothing.FilterEstimate, qaSectorPower abi.StoragePower) abi.TokenAmount {
return ExpectedRewardForPower(rewardEstimate, networkQAPowerEstimate, qaSectorPower, DeclaredFaultProjectionPeriod)
func PledgePenaltyForDeclaredFault(rewardEstimate, networkQAPowerEstimate *smoothing.FilterEstimate, qaSectorPower abi.StoragePower,
networkVersion network.Version) abi.TokenAmount {
projectionPeriod := DeclaredFaultProjectionPeriodV0
if networkVersion >= network.Version3 {
projectionPeriod = DeclaredFaultProjectionPeriodV3
}
return ExpectedRewardForPower(rewardEstimate, networkQAPowerEstimate, qaSectorPower, projectionPeriod)
}

// This is the SP(t) penalty for a newly faulty sector that has not been declared.
// SP(t) = UndeclaredFaultFactor * BR(t)
func PledgePenaltyForUndeclaredFault(rewardEstimate, networkQAPowerEstimate *smoothing.FilterEstimate, qaSectorPower abi.StoragePower,
networkVersion network.Version) abi.TokenAmount {
projectionPeriod := UndeclaredFaultProjectionPeriodV0
if networkVersion >= network.Version3 {
projectionPeriod = UndeclaredFaultProjectionPeriodV3
} else if networkVersion >= network.Version1 {
if networkVersion >= network.Version1 {
projectionPeriod = UndeclaredFaultProjectionPeriodV1
}
return ExpectedRewardForPower(rewardEstimate, networkQAPowerEstimate, qaSectorPower, projectionPeriod)
Expand Down

0 comments on commit e630995

Please sign in to comment.