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

Commit

Permalink
Final test fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Stebalien committed Aug 13, 2020
1 parent 075f5eb commit 10a1e29
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 37 deletions.
105 changes: 69 additions & 36 deletions actors/builtin/miner/miner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ func TestCommitments(t *testing.T) {
oldIPReqs := st.InitialPledgeRequirement
st.InitialPledgeRequirement = big.Add(rt.Balance(), abi.NewTokenAmount(1e18))
rt.ReplaceState(st)
rt.ExpectAbortContainsMessage(exitcode.ErrInsufficientFunds, "does not cover pledge requirements", func () {
rt.ExpectAbortContainsMessage(exitcode.ErrInsufficientFunds, "does not cover pledge requirements", func() {
actor.preCommitSector(rt, actor.makePreCommit(102, challengeEpoch, expiration, nil))
})
// reset state back to normal
Expand Down Expand Up @@ -826,6 +826,7 @@ func TestWindowPost(t *testing.T) {
actor.constructAndVerify(rt)
store := rt.AdtStore()
sector := actor.commitAndProveSectors(rt, 1, defaultSectorExpiration, nil)[0]
power := miner.PowerForSector(actor.sectorSize, sector)

st := getState(rt)
dlIdx, pIdx, err := st.FindSector(store, sector.SectorNumber)
Expand All @@ -841,7 +842,10 @@ func TestWindowPost(t *testing.T) {
partitions := []miner.PoStPartition{
{Index: pIdx, Skipped: bitfield.New()},
}
actor.submitWindowPoSt(rt, dlinfo, partitions, []*miner.SectorOnChainInfo{sector}, nil)
actor.submitWindowPoSt(rt, dlinfo, partitions, []*miner.SectorOnChainInfo{sector}, &poStConfig{
expectedPowerDelta: power,
expectedPenalty: big.Zero(),
})

// Verify proof recorded
deadline := actor.getDeadline(rt, dlIdx)
Expand All @@ -856,6 +860,7 @@ func TestWindowPost(t *testing.T) {
actor.constructAndVerify(rt)
store := rt.AdtStore()
sector := actor.commitAndProveSectors(rt, 1, defaultSectorExpiration, nil)[0]
power := miner.PowerForSector(actor.sectorSize, sector)

st := getState(rt)
dlIdx, pIdx, err := st.FindSector(store, sector.SectorNumber)
Expand All @@ -871,7 +876,10 @@ func TestWindowPost(t *testing.T) {
partitions := []miner.PoStPartition{
{Index: pIdx, Skipped: bitfield.New()},
}
actor.submitWindowPoSt(rt, dlinfo, partitions, []*miner.SectorOnChainInfo{sector}, nil)
actor.submitWindowPoSt(rt, dlinfo, partitions, []*miner.SectorOnChainInfo{sector}, &poStConfig{
expectedPowerDelta: power,
expectedPenalty: big.Zero(),
})

// Submit a duplicate proof for the same partition, which should be ignored.
// The skipped fault declared here has no effect.
Expand Down Expand Up @@ -941,9 +949,8 @@ func TestWindowPost(t *testing.T) {
// Recovery should be charged ongoing fee.
recoveryFee := actor.declaredFaultPenalty(infos)
cfg := &poStConfig{
expectedRawPowerDelta: pwr.Raw,
expectedQAPowerDelta: pwr.QA,
expectedPenalty: recoveryFee,
expectedPowerDelta: miner.NewPowerPair(pwr.Raw, pwr.QA),
expectedPenalty: recoveryFee,
}
partitions := []miner.PoStPartition{
{Index: pIdx, Skipped: bitfield.New()},
Expand Down Expand Up @@ -987,18 +994,18 @@ func TestWindowPost(t *testing.T) {
}

// Now submit PoSt with a skipped fault for first sector
// First sector should be penalized as an undeclared fault and its power should be removed
// First sector should be penalized as an undeclared fault and its power should not be activated.
// 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])
declaredFee := actor.declaredFaultPenalty(infos[:1])
faultFee := big.Sub(undeclaredFee, declaredFee)

pwr := miner.PowerForSectors(actor.sectorSize, infos[:1])
// only activate power for second sector.
powerActive := miner.PowerForSectors(actor.sectorSize, infos[1:])
cfg := &poStConfig{
expectedRawPowerDelta: pwr.Raw.Neg(),
expectedQAPowerDelta: pwr.QA.Neg(),
expectedPenalty: faultFee,
expectedPowerDelta: powerActive,
expectedPenalty: faultFee,
}
partitions := []miner.PoStPartition{
{Index: pIdx, Skipped: bf(uint64(infos[0].SectorNumber))},
Expand All @@ -1017,12 +1024,11 @@ func TestWindowPost(t *testing.T) {
undeclaredFee = actor.undeclaredFaultPenalty(infos[1:])
declaredFee = actor.declaredFaultPenalty(infos[1:])
faultFee = big.Sub(undeclaredFee, declaredFee)
pwr = miner.PowerForSectors(actor.sectorSize, infos[1:])
pwr := miner.PowerForSectors(actor.sectorSize, infos[1:])

cfg = &poStConfig{
expectedRawPowerDelta: pwr.Raw.Neg(),
expectedQAPowerDelta: pwr.QA.Neg(),
expectedPenalty: faultFee,
expectedPowerDelta: pwr.Neg(),
expectedPenalty: faultFee,
}
partitions = []miner.PoStPartition{
{Index: pIdx2, Skipped: bf(uint64(infos[1].SectorNumber))},
Expand Down Expand Up @@ -1057,18 +1063,16 @@ func TestWindowPost(t *testing.T) {
}

// Now submit PoSt with all faults skipped
// Sectors should be penalized as an undeclared fault and its power should be removed
// Sectors should be penalized as an undeclared fault and unproven power won't be activated.
// 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)
declaredFee := actor.declaredFaultPenalty(infos)
faultFee := big.Sub(undeclaredFee, declaredFee)

pwr := miner.PowerForSectors(actor.sectorSize, infos)
cfg := &poStConfig{
expectedRawPowerDelta: pwr.Raw.Neg(),
expectedQAPowerDelta: pwr.QA.Neg(),
expectedPenalty: faultFee,
expectedPowerDelta: miner.NewPowerPairZero(),
expectedPenalty: faultFee,
}
partitions := []miner.PoStPartition{
{Index: pIdx, Skipped: bf(uint64(infos[0].SectorNumber), uint64(infos[1].SectorNumber))},
Expand Down Expand Up @@ -1118,9 +1122,8 @@ func TestWindowPost(t *testing.T) {
ongoingFee := actor.declaredFaultPenalty(infos)
recoveryFee := big.Sub(actor.undeclaredFaultPenalty(infos), ongoingFee)
cfg := &poStConfig{
expectedRawPowerDelta: big.Zero(),
expectedQAPowerDelta: big.Zero(),
expectedPenalty: recoveryFee,
expectedPowerDelta: miner.NewPowerPairZero(),
expectedPenalty: recoveryFee,
}
partitions := []miner.PoStPartition{
{Index: pIdx, Skipped: bf(uint64(infos[0].SectorNumber))},
Expand Down Expand Up @@ -1159,9 +1162,8 @@ func TestWindowPost(t *testing.T) {

// Now submit PoSt for partition 1 and skip sector from other partition
cfg := &poStConfig{
expectedRawPowerDelta: big.Zero(),
expectedQAPowerDelta: big.Zero(),
expectedPenalty: big.Zero(),
expectedPowerDelta: miner.NewPowerPairZero(),
expectedPenalty: big.Zero(),
}
partitions := []miner.PoStPartition{
{Index: pIdx0, Skipped: bf(uint64(infos[n-1].SectorNumber))},
Expand Down Expand Up @@ -1479,7 +1481,7 @@ func TestDeclareRecoveries(t *testing.T) {
// Attempt to recover
dlIdx, pIdx, err := st.FindSector(rt.AdtStore(), oneSector[0].SectorNumber)
require.NoError(t, err)
rt.ExpectAbortContainsMessage(exitcode.ErrInsufficientFunds, "does not cover pledge requirements", func () {
rt.ExpectAbortContainsMessage(exitcode.ErrInsufficientFunds, "does not cover pledge requirements", func() {
actor.declareRecoveries(rt, dlIdx, pIdx, bf(uint64(oneSector[0].SectorNumber)))
})
})
Expand Down Expand Up @@ -1557,7 +1559,8 @@ func TestExtendSectorExpiration(t *testing.T) {
t.Run("rejects extension past max for seal proof", func(t *testing.T) {
rt := builder.Build(t)
sector := commitSector(t, rt)
rt.SetEpoch(sector.Expiration)
// and prove it once to activate it.
advanceAndSubmitPoSts(rt, actor, sector)

maxLifetime := sector.SealProof.SectorMaximumLifetime()

Expand Down Expand Up @@ -1602,6 +1605,7 @@ func TestExtendSectorExpiration(t *testing.T) {
t.Run("updates expiration with valid params", func(t *testing.T) {
rt := builder.Build(t)
oldSector := commitSector(t, rt)
advanceAndSubmitPoSts(rt, actor, oldSector)

st := getState(rt)
dlIdx, pIdx, err := st.FindSector(rt.AdtStore(), oldSector.SectorNumber)
Expand Down Expand Up @@ -1649,6 +1653,7 @@ func TestExtendSectorExpiration(t *testing.T) {

// commit a bunch of sectors to ensure that we get multiple partitions.
sectorInfos := actor.commitAndProveSectors(rt, sectorCount, defaultSectorExpiration, nil)
advanceAndSubmitPoSts(rt, actor, sectorInfos...)

newExpiration := sectorInfos[0].Expiration + 42*miner.WPoStProvingPeriod

Expand Down Expand Up @@ -1730,6 +1735,7 @@ func TestExtendSectorExpiration(t *testing.T) {
t.Run("supports extensions off deadline boundary", func(t *testing.T) {
rt := builder.Build(t)
oldSector := commitSector(t, rt)
advanceAndSubmitPoSts(rt, actor, oldSector)

st := getState(rt)
dlIdx, pIdx, err := st.FindSector(rt.AdtStore(), oldSector.SectorNumber)
Expand Down Expand Up @@ -1792,7 +1798,7 @@ func TestTerminateSectors(t *testing.T) {
rt.SetEpoch(abi.ChainEpoch(1))
sectorInfo := actor.commitAndProveSectors(rt, 1, defaultSectorExpiration, nil)
sector := sectorInfo[0]
rt.SetEpoch(rt.Epoch() + 100)
advanceAndSubmitPoSts(rt, actor, sector)

// A miner will pay the minimum of termination fee and locked funds. Add some locked funds to ensure
// correct fee calculation is used.
Expand Down Expand Up @@ -1846,6 +1852,7 @@ func TestTerminateSectors(t *testing.T) {

// Commit a sector to upgrade
oldSector := actor.commitAndProveSector(rt, 1, defaultSectorExpiration, nil)
advanceAndSubmitPoSts(rt, actor, oldSector) // activate power
st := getState(rt)
dlIdx, partIdx, err := st.FindSector(rt.AdtStore(), oldSector.SectorNumber)
require.NoError(t, err)
Expand All @@ -1870,6 +1877,9 @@ func TestTerminateSectors(t *testing.T) {
assert.Equal(t, oldSector.ExpectedDayReward, newSector.ReplacedDayReward)
assert.Equal(t, rt.Epoch()-oldSector.Activation, newSector.ReplacedSectorAge)

// post new sector to activate power
advanceAndSubmitPoSts(rt, actor, oldSector, newSector)

// advance clock a little and terminate new sector
rt.SetEpoch(rt.Epoch() + 5_000)
sectorPower := miner.QAPowerForSector(actor.sectorSize, newSector)
Expand Down Expand Up @@ -2905,9 +2915,8 @@ func (h *actorHarness) advancePastProvingPeriodWithCron(rt *mock.Runtime) {
}

type poStConfig struct {
expectedRawPowerDelta abi.StoragePower
expectedQAPowerDelta abi.StoragePower
expectedPenalty abi.TokenAmount
expectedPowerDelta miner.PowerPair
expectedPenalty abi.TokenAmount
}

func (h *actorHarness) submitWindowPoSt(rt *mock.Runtime, deadline *miner.DeadlineInfo, partitions []miner.PoStPartition, infos []*miner.SectorOnChainInfo, poStCfg *poStConfig) {
Expand Down Expand Up @@ -2983,10 +2992,10 @@ func (h *actorHarness) submitWindowPoSt(rt *mock.Runtime, deadline *miner.Deadli
}
if poStCfg != nil {
// expect power update
if !poStCfg.expectedRawPowerDelta.IsZero() || !poStCfg.expectedQAPowerDelta.IsZero() {
if !poStCfg.expectedPowerDelta.IsZero() {
claim := &power.UpdateClaimedPowerParams{
RawByteDelta: poStCfg.expectedRawPowerDelta,
QualityAdjustedDelta: poStCfg.expectedQAPowerDelta,
RawByteDelta: poStCfg.expectedPowerDelta.Raw,
QualityAdjustedDelta: poStCfg.expectedPowerDelta.QA,
}
rt.ExpectSend(builtin.StoragePowerActorAddr, builtin.MethodsPower.UpdateClaimedPower, claim, abi.NewTokenAmount(0),
nil, exitcode.Ok)
Expand Down Expand Up @@ -3364,6 +3373,9 @@ func advanceToEpochWithCron(rt *mock.Runtime, h *actorHarness, e abi.ChainEpoch)
func advanceAndSubmitPoSts(rt *mock.Runtime, h *actorHarness, sectors ...*miner.SectorOnChainInfo) {
st := getState(rt)

sectorArr, err := miner.LoadSectors(rt.AdtStore(), st.Sectors)
require.NoError(h.t, err)

deadlines := map[uint64][]*miner.SectorOnChainInfo{}
for _, sector := range sectors {
dlIdx, _, err := st.FindSector(rt.AdtStore(), sector.SectorNumber)
Expand All @@ -3389,6 +3401,7 @@ func advanceAndSubmitPoSts(rt *mock.Runtime, h *actorHarness, sectors ...*miner.

var partition miner.Partition
partitions := []miner.PoStPartition{}
powerDelta := miner.NewPowerPairZero()
require.NoError(h.t, parts.ForEach(&partition, func(partIdx int64) error {
live, err := partition.LiveSectors()
require.NoError(h.t, err)
Expand All @@ -3411,11 +3424,31 @@ func advanceAndSubmitPoSts(rt *mock.Runtime, h *actorHarness, sectors ...*miner.
toSkip, err = bitfield.SubtractBitField(toSkip, notRecovering)
require.NoError(h.t, err)

skippedProven, err := bitfield.SubtractBitField(toSkip, partition.Unproven)
require.NoError(h.t, err)

skippedProvenSectorInfos, err := sectorArr.Load(skippedProven)
require.NoError(h.t, err)
newFaultyPower := h.powerPairForSectors(skippedProvenSectorInfos)

newProven, err := bitfield.SubtractBitField(partition.Unproven, toSkip)
require.NoError(h.t, err)

newProvenInfos, err := sectorArr.Load(newProven)
require.NoError(h.t, err)
newProvenPower := h.powerPairForSectors(newProvenInfos)

powerDelta = powerDelta.Sub(newFaultyPower)
powerDelta = powerDelta.Add(newProvenPower)

partitions = append(partitions, miner.PoStPartition{Index: uint64(partIdx), Skipped: toSkip})
return nil
}))

h.submitWindowPoSt(rt, dlinfo, partitions, dlSectors, nil)
h.submitWindowPoSt(rt, dlinfo, partitions, dlSectors, &poStConfig{
expectedPowerDelta: powerDelta,
expectedPenalty: big.Zero(), // TODO
})
delete(deadlines, dlinfo.Index)
}

Expand Down
2 changes: 1 addition & 1 deletion actors/builtin/miner/partition_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func (p *Partition) LiveSectors() (bitfield.BitField, error) {

}

// Active sectors are those that are neither terminated nor faulty, i.e. actively contributing power.
// Active sectors are those that are neither terminated nor faulty nor unproven, i.e. actively contributing power.
func (p *Partition) ActiveSectors() (bitfield.BitField, error) {
live, err := p.LiveSectors()
if err != nil {
Expand Down

0 comments on commit 10a1e29

Please sign in to comment.