From ea6fa6b89f39eb824863c2f32d63e9449c1b6d4b Mon Sep 17 00:00:00 2001 From: c r Date: Fri, 1 Oct 2021 10:07:42 -0500 Subject: [PATCH] Fix #1486 (#1489) * two more failing tests but otherwise working * code review? code reviewed. * tests passin\' * https://www.youtube.com/watch?v=W1i4mTyidOc check pass * found the source of the cbor errors.... forgot about gen.go. * fixes for code review * bump determinism hash Co-authored-by: ZenGround0 --- actors/builtin/cbor_gen.go | 128 ++++++++++++++++-- actors/builtin/miner/miner_actor.go | 53 ++++---- actors/builtin/miner/miner_test.go | 33 ++--- actors/builtin/power/power_actor.go | 38 +++--- actors/builtin/power/power_test.go | 87 +++++++----- actors/builtin/shared.go | 14 +- actors/test/commit_post_test.go | 10 -- .../test/committed_capacity_scenario_test.go | 7 - actors/test/power_scenario_test.go | 5 +- gen/gen.go | 1 + test-vectors/determinism-check | 2 +- 11 files changed, 242 insertions(+), 136 deletions(-) diff --git a/actors/builtin/cbor_gen.go b/actors/builtin/cbor_gen.go index 407c409a5..bac9729a3 100644 --- a/actors/builtin/cbor_gen.go +++ b/actors/builtin/cbor_gen.go @@ -148,18 +148,18 @@ func (t *ConfirmSectorProofsParams) MarshalCBOR(w io.Writer) error { } } - // t.RewardStatsThisEpochRewardSmoothed (smoothing.FilterEstimate) (struct) - if err := t.RewardStatsThisEpochRewardSmoothed.MarshalCBOR(w); err != nil { + // t.RewardSmoothed (smoothing.FilterEstimate) (struct) + if err := t.RewardSmoothed.MarshalCBOR(w); err != nil { return err } - // t.RewardStatsThisEpochBaselinePower (big.Int) (struct) - if err := t.RewardStatsThisEpochBaselinePower.MarshalCBOR(w); err != nil { + // t.RewardBaselinePower (big.Int) (struct) + if err := t.RewardBaselinePower.MarshalCBOR(w); err != nil { return err } - // t.PwrTotalQualityAdjPowerSmoothed (smoothing.FilterEstimate) (struct) - if err := t.PwrTotalQualityAdjPowerSmoothed.MarshalCBOR(w); err != nil { + // t.QualityAdjPowerSmoothed (smoothing.FilterEstimate) (struct) + if err := t.QualityAdjPowerSmoothed.MarshalCBOR(w); err != nil { return err } return nil @@ -216,30 +216,128 @@ func (t *ConfirmSectorProofsParams) UnmarshalCBOR(r io.Reader) error { t.Sectors[i] = abi.SectorNumber(val) } - // t.RewardStatsThisEpochRewardSmoothed (smoothing.FilterEstimate) (struct) + // t.RewardSmoothed (smoothing.FilterEstimate) (struct) { - if err := t.RewardStatsThisEpochRewardSmoothed.UnmarshalCBOR(br); err != nil { - return xerrors.Errorf("unmarshaling t.RewardStatsThisEpochRewardSmoothed: %w", err) + if err := t.RewardSmoothed.UnmarshalCBOR(br); err != nil { + return xerrors.Errorf("unmarshaling t.RewardSmoothed: %w", err) } } - // t.RewardStatsThisEpochBaselinePower (big.Int) (struct) + // t.RewardBaselinePower (big.Int) (struct) { - if err := t.RewardStatsThisEpochBaselinePower.UnmarshalCBOR(br); err != nil { - return xerrors.Errorf("unmarshaling t.RewardStatsThisEpochBaselinePower: %w", err) + if err := t.RewardBaselinePower.UnmarshalCBOR(br); err != nil { + return xerrors.Errorf("unmarshaling t.RewardBaselinePower: %w", err) } } - // t.PwrTotalQualityAdjPowerSmoothed (smoothing.FilterEstimate) (struct) + // t.QualityAdjPowerSmoothed (smoothing.FilterEstimate) (struct) { - if err := t.PwrTotalQualityAdjPowerSmoothed.UnmarshalCBOR(br); err != nil { - return xerrors.Errorf("unmarshaling t.PwrTotalQualityAdjPowerSmoothed: %w", err) + if err := t.QualityAdjPowerSmoothed.UnmarshalCBOR(br); err != nil { + return xerrors.Errorf("unmarshaling t.QualityAdjPowerSmoothed: %w", err) + } + + } + return nil +} + +var lengthBufDeferredCronEventParams = []byte{131} + +func (t *DeferredCronEventParams) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write(lengthBufDeferredCronEventParams); err != nil { + return err + } + + scratch := make([]byte, 9) + + // t.EventPayload ([]uint8) (slice) + if len(t.EventPayload) > cbg.ByteArrayMaxLen { + return xerrors.Errorf("Byte array in field t.EventPayload was too long") + } + + if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajByteString, uint64(len(t.EventPayload))); err != nil { + return err + } + + if _, err := w.Write(t.EventPayload[:]); err != nil { + return err + } + + // t.RewardSmoothed (smoothing.FilterEstimate) (struct) + if err := t.RewardSmoothed.MarshalCBOR(w); err != nil { + return err + } + + // t.QualityAdjPowerSmoothed (smoothing.FilterEstimate) (struct) + if err := t.QualityAdjPowerSmoothed.MarshalCBOR(w); err != nil { + return err + } + return nil +} + +func (t *DeferredCronEventParams) UnmarshalCBOR(r io.Reader) error { + *t = DeferredCronEventParams{} + + br := cbg.GetPeeker(r) + scratch := make([]byte, 8) + + maj, extra, err := cbg.CborReadHeaderBuf(br, scratch) + if err != nil { + return err + } + if maj != cbg.MajArray { + return fmt.Errorf("cbor input should be of type array") + } + + if extra != 3 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + // t.EventPayload ([]uint8) (slice) + + maj, extra, err = cbg.CborReadHeaderBuf(br, scratch) + if err != nil { + return err + } + + if extra > cbg.ByteArrayMaxLen { + return fmt.Errorf("t.EventPayload: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + + if extra > 0 { + t.EventPayload = make([]uint8, extra) + } + + if _, err := io.ReadFull(br, t.EventPayload[:]); err != nil { + return err + } + // t.RewardSmoothed (smoothing.FilterEstimate) (struct) + + { + + if err := t.RewardSmoothed.UnmarshalCBOR(br); err != nil { + return xerrors.Errorf("unmarshaling t.RewardSmoothed: %w", err) + } + + } + // t.QualityAdjPowerSmoothed (smoothing.FilterEstimate) (struct) + + { + + if err := t.QualityAdjPowerSmoothed.UnmarshalCBOR(br); err != nil { + return xerrors.Errorf("unmarshaling t.QualityAdjPowerSmoothed: %w", err) } } diff --git a/actors/builtin/miner/miner_actor.go b/actors/builtin/miner/miner_actor.go index d64d9e758..2a613dbe9 100644 --- a/actors/builtin/miner/miner_actor.go +++ b/actors/builtin/miner/miner_actor.go @@ -956,10 +956,10 @@ func (a Actor) ProveCommitAggregate(rt Runtime, params *ProveCommitAggregatePara }) builtin.RequireNoErr(rt, err, exitcode.ErrIllegalArgument, "aggregate seal verify failed") - rewret := requestCurrentEpochBlockReward(rt) + rew := requestCurrentEpochBlockReward(rt) pwr := requestCurrentTotalPower(rt) - confirmSectorProofsValid(rt, precommitsToConfirm, rewret.ThisEpochBaselinePower, rewret.ThisEpochRewardSmoothed, pwr.QualityAdjPowerSmoothed) + confirmSectorProofsValid(rt, precommitsToConfirm, rew.ThisEpochBaselinePower, rew.ThisEpochRewardSmoothed, pwr.QualityAdjPowerSmoothed) // Compute and burn the aggregate network fee. We need to re-load the state as // confirmSectorProofsValid can change it. @@ -1065,8 +1065,7 @@ func (a Actor) ConfirmSectorProofsValid(rt Runtime, params *builtin.ConfirmSecto precommittedSectors, err := st.FindPrecommittedSectors(store, params.Sectors...) builtin.RequireNoErr(rt, err, exitcode.ErrIllegalState, "failed to load pre-committed sectors") - confirmSectorProofsValid(rt, precommittedSectors, params.RewardStatsThisEpochBaselinePower, - params.RewardStatsThisEpochRewardSmoothed, params.PwrTotalQualityAdjPowerSmoothed) + confirmSectorProofsValid(rt, precommittedSectors, params.RewardBaselinePower, params.RewardSmoothed, params.QualityAdjPowerSmoothed) return nil } @@ -1550,8 +1549,11 @@ func (a Actor) TerminateSectors(rt Runtime, params *TerminateSectorsParams) *Ter builtin.RequireNoErr(rt, err, exitcode.ErrIllegalState, "failed to save deadlines") }) + epochReward := requestCurrentEpochBlockReward(rt) + pwrTotal := requestCurrentTotalPower(rt) + // Now, try to process these sectors. - more := processEarlyTerminations(rt) + more := processEarlyTerminations(rt, epochReward.ThisEpochRewardSmoothed, pwrTotal.QualityAdjPowerSmoothed) if more && !hadEarlyTerminations { // We have remaining terminations, and we didn't _previously_ // have early terminations to process, schedule a cron job. @@ -2096,23 +2098,27 @@ const ( CronEventProcessEarlyTerminations = miner0.CronEventProcessEarlyTerminations ) -func (a Actor) OnDeferredCronEvent(rt Runtime, payload *CronEventPayload) *abi.EmptyValue { +func (a Actor) OnDeferredCronEvent(rt Runtime, params *builtin.DeferredCronEventParams) *abi.EmptyValue { rt.ValidateImmediateCallerIs(builtin.StoragePowerActorAddr) + var payload miner0.CronEventPayload + err := payload.UnmarshalCBOR(bytes.NewBuffer(params.EventPayload)) + builtin.RequireNoErr(rt, err, exitcode.ErrIllegalState, "failed to unmarshal miner cron payload into expected structure") + switch payload.EventType { case CronEventProvingDeadline: - handleProvingDeadline(rt) + handleProvingDeadline(rt, params.RewardSmoothed, params.QualityAdjPowerSmoothed) case CronEventProcessEarlyTerminations: - if processEarlyTerminations(rt) { + if processEarlyTerminations(rt, params.RewardSmoothed, params.QualityAdjPowerSmoothed) { scheduleEarlyTerminationWork(rt) } default: - rt.Log(rtt.ERROR, "unhandled payload EventType in OnDeferredCronEvent") + rt.Log(rtt.ERROR, "onDeferredCronEvent invalid event type: %v", payload.EventType) } var st State rt.StateReadonly(&st) - err := st.CheckBalanceInvariants(rt.CurrentBalance()) + err = st.CheckBalanceInvariants(rt.CurrentBalance()) builtin.RequireNoErr(rt, err, ErrBalanceInvariantBroken, "balance invariants broken") return nil } @@ -2121,15 +2127,12 @@ func (a Actor) OnDeferredCronEvent(rt Runtime, payload *CronEventPayload) *abi.E // Utility functions & helpers //////////////////////////////////////////////////////////////////////////////// -func processEarlyTerminations(rt Runtime) (more bool) { +// TODO: We're using the current power+epoch reward. Technically, we +// should use the power/reward at the time of termination. +// https://github.com/filecoin-project/specs-actors/v6/pull/648 +func processEarlyTerminations(rt Runtime, rewardSmoothed smoothing.FilterEstimate, qualityAdjPowerSmoothed smoothing.FilterEstimate) (more bool) { store := adt.AsStore(rt) - // TODO: We're using the current power+epoch reward. Technically, we - // should use the power/reward at the time of termination. - // https://github.com/filecoin-project/specs-actors/v6/pull/648 - rewardStats := requestCurrentEpochBlockReward(rt) - pwrTotal := requestCurrentTotalPower(rt) - var ( result TerminationResult dealsToTerminate []market.OnMinerSectorsTerminateParams @@ -2170,7 +2173,7 @@ func processEarlyTerminations(rt Runtime) (more bool) { totalInitialPledge = big.Add(totalInitialPledge, sector.InitialPledge) } penalty = big.Add(penalty, terminationPenalty(info.SectorSize, epoch, - rewardStats.ThisEpochRewardSmoothed, pwrTotal.QualityAdjPowerSmoothed, sectors)) + rewardSmoothed, qualityAdjPowerSmoothed, sectors)) dealsToTerminate = append(dealsToTerminate, params) return nil @@ -2215,13 +2218,12 @@ func processEarlyTerminations(rt Runtime) (more bool) { } // Invoked at the end of the last epoch for each proving deadline. -func handleProvingDeadline(rt Runtime) { +func handleProvingDeadline(rt Runtime, + rewardSmoothed smoothing.FilterEstimate, + qualityAdjPowerSmoothed smoothing.FilterEstimate) { currEpoch := rt.CurrEpoch() store := adt.AsStore(rt) - epochReward := requestCurrentEpochBlockReward(rt) - pwrTotal := requestCurrentTotalPower(rt) - hadEarlyTerminations := false powerDeltaTotal := NewPowerPairZero() @@ -2265,8 +2267,8 @@ func handleProvingDeadline(rt Runtime) { // Faults detected by this missed PoSt pay no penalty, but sectors that were already faulty // and remain faulty through this deadline pay the fault fee. penaltyTarget := PledgePenaltyForContinuedFault( - epochReward.ThisEpochRewardSmoothed, - pwrTotal.QualityAdjPowerSmoothed, + rewardSmoothed, + qualityAdjPowerSmoothed, result.PreviouslyFaultyPower.QA, ) @@ -2287,7 +2289,6 @@ func handleProvingDeadline(rt Runtime) { st.DeadlineCronActive = false } }) - // Remove power for new faults, and burn penalties. requestUpdatePower(rt, powerDeltaTotal) burnFunds(rt, penaltyTotal) @@ -2310,7 +2311,7 @@ func handleProvingDeadline(rt Runtime) { // handle them at the next epoch. if !hadEarlyTerminations && hasEarlyTerminations { // First, try to process some of these terminations. - if processEarlyTerminations(rt) { + if processEarlyTerminations(rt, rewardSmoothed, qualityAdjPowerSmoothed) { // If that doesn't work, just defer till the next epoch. scheduleEarlyTerminationWork(rt) } diff --git a/actors/builtin/miner/miner_test.go b/actors/builtin/miner/miner_test.go index 2a56d8484..31e6b3d4c 100644 --- a/actors/builtin/miner/miner_test.go +++ b/actors/builtin/miner/miner_test.go @@ -5153,10 +5153,10 @@ func (h *actorHarness) confirmSectorProofsValid(rt *mock.Runtime, conf proveComm rt.ExpectValidateCallerAddr(builtin.StoragePowerActorAddr) rt.Call(h.a.ConfirmSectorProofsValid, &builtin.ConfirmSectorProofsParams{ - Sectors: allSectorNumbers, - RewardStatsThisEpochRewardSmoothed: h.epochRewardSmooth, - RewardStatsThisEpochBaselinePower: h.baselinePower, - PwrTotalQualityAdjPowerSmoothed: h.epochQAPowerSmooth, + Sectors: allSectorNumbers, + RewardSmoothed: h.epochRewardSmooth, + RewardBaselinePower: h.baselinePower, + QualityAdjPowerSmoothed: h.epochQAPowerSmooth, }) rt.Verify() } @@ -5776,21 +5776,6 @@ func (h *actorHarness) onDeadlineCron(rt *mock.Runtime, config *cronConfig) { rt.ExpectValidateCallerAddr(builtin.StoragePowerActorAddr) // Preamble - rwd := reward.ThisEpochRewardReturn{ - ThisEpochBaselinePower: h.baselinePower, - ThisEpochRewardSmoothed: h.epochRewardSmooth, - } - rt.ExpectSend(builtin.RewardActorAddr, builtin.MethodsReward.ThisEpochReward, nil, big.Zero(), &rwd, exitcode.Ok) - networkPower := big.NewIntUnsigned(1 << 50) - rt.ExpectSend(builtin.StoragePowerActorAddr, builtin.MethodsPower.CurrentTotalPower, nil, big.Zero(), - &power.CurrentTotalPowerReturn{ - RawBytePower: networkPower, - QualityAdjPower: networkPower, - PledgeCollateral: h.networkPledge, - QualityAdjPowerSmoothed: h.epochQAPowerSmooth, - }, - exitcode.Ok) - powerDelta := miner.NewPowerPairZero() if config.detectedFaultsPowerDelta != nil { powerDelta = powerDelta.Add(*config.detectedFaultsPowerDelta) @@ -5852,9 +5837,15 @@ func (h *actorHarness) onDeadlineCron(rt *mock.Runtime, config *cronConfig) { makeDeadlineCronEventParams(h.t, config.expectedEnrollment), big.Zero(), nil, exitcode.Ok) } + eventPayloadBuf := bytes.Buffer{} + payload := &miner0.CronEventPayload{EventType: miner.CronEventProvingDeadline} + require.NoError(h.t, payload.MarshalCBOR(&eventPayloadBuf), "failed to marshal event payload") + rt.SetCaller(builtin.StoragePowerActorAddr, builtin.StoragePowerActorCodeID) - rt.Call(h.a.OnDeferredCronEvent, &miner.CronEventPayload{ - EventType: miner.CronEventProvingDeadline, + rt.Call(h.a.OnDeferredCronEvent, &builtin.DeferredCronEventParams{ + EventPayload: eventPayloadBuf.Bytes(), + RewardSmoothed: h.epochRewardSmooth, + QualityAdjPowerSmoothed: h.epochQAPowerSmooth, }) rt.Verify() } diff --git a/actors/builtin/power/power_actor.go b/actors/builtin/power/power_actor.go index d187d2cad..e987e48ed 100644 --- a/actors/builtin/power/power_actor.go +++ b/actors/builtin/power/power_actor.go @@ -214,8 +214,12 @@ func (a Actor) EnrollCronEvent(rt Runtime, params *EnrollCronEventParams) *abi.E func (a Actor) OnEpochTickEnd(rt Runtime, _ *abi.EmptyValue) *abi.EmptyValue { rt.ValidateImmediateCallerIs(builtin.CronActorAddr) - a.processBatchProofVerifies(rt) - a.processDeferredCronEvents(rt) + var rewret reward.ThisEpochRewardReturn + rewretcode := rt.Send(builtin.RewardActorAddr, builtin.MethodsReward.ThisEpochReward, nil, big.Zero(), &rewret) + builtin.RequireSuccess(rt, rewretcode, "failed to check epoch baseline power") + + a.processBatchProofVerifies(rt, rewret) + a.processDeferredCronEvents(rt, rewret) var st State rt.StateTransaction(&st, func() { @@ -339,7 +343,7 @@ func validateMinerHasClaim(rt Runtime, st State, minerAddr addr.Address) { } } -func (a Actor) processBatchProofVerifies(rt Runtime) { +func (a Actor) processBatchProofVerifies(rt Runtime, rewret reward.ThisEpochRewardReturn) { var st State var miners []addr.Address @@ -390,14 +394,6 @@ func (a Actor) processBatchProofVerifies(rt Runtime) { res, err := rt.BatchVerifySeals(verifies) builtin.RequireNoErr(rt, err, exitcode.ErrIllegalState, "failed to batch verify") - var rewret reward.ThisEpochRewardReturn - rewretcode := rt.Send(builtin.RewardActorAddr, builtin.MethodsReward.ThisEpochReward, nil, big.Zero(), &rewret) - builtin.RequireSuccess(rt, rewretcode, "failed to check epoch baseline power") - - var pwr CurrentTotalPowerReturn - powretcode := rt.Send(builtin.StoragePowerActorAddr, builtin.MethodsPower.CurrentTotalPower, nil, big.Zero(), &pwr) - builtin.RequireSuccess(rt, powretcode, "failed to check current power") - for _, m := range miners { vres, ok := res[m] if !ok { @@ -430,10 +426,10 @@ func (a Actor) processBatchProofVerifies(rt Runtime) { m, builtin.MethodsMiner.ConfirmSectorProofsValid, &builtin.ConfirmSectorProofsParams{ - Sectors: successful, - RewardStatsThisEpochRewardSmoothed: rewret.ThisEpochRewardSmoothed, - RewardStatsThisEpochBaselinePower: rewret.ThisEpochBaselinePower, - PwrTotalQualityAdjPowerSmoothed: pwr.QualityAdjPowerSmoothed}, + Sectors: successful, + RewardSmoothed: rewret.ThisEpochRewardSmoothed, + RewardBaselinePower: rewret.ThisEpochBaselinePower, + QualityAdjPowerSmoothed: st.ThisEpochQAPowerSmoothed}, abi.NewTokenAmount(0), &builtin.Discard{}, ) @@ -446,7 +442,7 @@ func (a Actor) processBatchProofVerifies(rt Runtime) { } } -func (a Actor) processDeferredCronEvents(rt Runtime) { +func (a Actor) processDeferredCronEvents(rt Runtime, rewret reward.ThisEpochRewardReturn) { rtEpoch := rt.CurrEpoch() var cronEvents []CronEvent @@ -487,11 +483,19 @@ func (a Actor) processDeferredCronEvents(rt Runtime) { builtin.RequireNoErr(rt, err, exitcode.ErrIllegalState, "failed to flush events") }) failedMinerCrons := make([]addr.Address, 0) + for _, event := range cronEvents { + + params := builtin.DeferredCronEventParams{ + EventPayload: event.CallbackPayload, + RewardSmoothed: rewret.ThisEpochRewardSmoothed, + QualityAdjPowerSmoothed: st.ThisEpochQAPowerSmoothed, + } + code := rt.Send( event.MinerAddr, builtin.MethodsMiner.OnDeferredCronEvent, - builtin.CBORBytes(event.CallbackPayload), + ¶ms, abi.NewTokenAmount(0), &builtin.Discard{}, ) diff --git a/actors/builtin/power/power_test.go b/actors/builtin/power/power_test.go index f43d19108..d775ae9c3 100644 --- a/actors/builtin/power/power_test.go +++ b/actors/builtin/power/power_test.go @@ -615,9 +615,22 @@ func TestCron(t *testing.T) { rt.SetEpoch(4) rt.ExpectValidateCallerAddr(builtin.CronActorAddr) expectQueryNetworkInfo(rt, actor) + st := getState(rt) + + params1 := builtin.DeferredCronEventParams{ + EventPayload: []byte{0x1, 0x3}, + RewardSmoothed: actor.thisEpochRewardSmoothed, + QualityAdjPowerSmoothed: st.ThisEpochQAPowerSmoothed, + } + rt.ExpectSend(miner1, builtin.MethodsMiner.OnDeferredCronEvent, ¶ms1, big.Zero(), nil, exitcode.Ok) + + params2 := builtin.DeferredCronEventParams{ + EventPayload: []byte{0x2, 0x3}, + RewardSmoothed: actor.thisEpochRewardSmoothed, + QualityAdjPowerSmoothed: st.ThisEpochQAPowerSmoothed, + } + rt.ExpectSend(miner2, builtin.MethodsMiner.OnDeferredCronEvent, ¶ms2, big.Zero(), nil, exitcode.Ok) - rt.ExpectSend(miner1, builtin.MethodsMiner.OnDeferredCronEvent, builtin.CBORBytes([]byte{0x1, 0x3}), big.Zero(), nil, exitcode.Ok) - rt.ExpectSend(miner2, builtin.MethodsMiner.OnDeferredCronEvent, builtin.CBORBytes([]byte{0x2, 0x3}), big.Zero(), nil, exitcode.Ok) rt.ExpectSend(builtin.RewardActorAddr, builtin.MethodsReward.UpdateNetworkKPI, &expectedRawBytePower, big.Zero(), nil, exitcode.Ok) rt.SetCaller(builtin.CronActorAddr, builtin.CronActorCodeID) rt.ExpectBatchVerifySeals(nil, nil, nil) @@ -652,7 +665,16 @@ func TestCron(t *testing.T) { rt.SetEpoch(6) rt.ExpectValidateCallerAddr(builtin.CronActorAddr) expectQueryNetworkInfo(rt, actor) - rt.ExpectSend(miner1, builtin.MethodsMiner.OnDeferredCronEvent, builtin.CBORBytes([]byte{0x1, 0x3}), big.Zero(), nil, exitcode.Ok) + + st := getState(rt) + + input := builtin.DeferredCronEventParams{ + EventPayload: []byte{0x1, 0x3}, + RewardSmoothed: actor.thisEpochRewardSmoothed, + QualityAdjPowerSmoothed: st.ThisEpochQAPowerSmoothed, + } + + rt.ExpectSend(miner1, builtin.MethodsMiner.OnDeferredCronEvent, &input, big.Zero(), nil, exitcode.Ok) rt.ExpectSend(builtin.RewardActorAddr, builtin.MethodsReward.UpdateNetworkKPI, &expectedRawBytePower, big.Zero(), nil, exitcode.Ok) rt.SetCaller(builtin.CronActorAddr, builtin.CronActorCodeID) rt.ExpectBatchVerifySeals(nil, nil, nil) @@ -661,7 +683,7 @@ func TestCron(t *testing.T) { rt.Verify() // assert used cron events are cleaned up - st := getState(rt) + st = getState(rt) mmap, err := adt.AsMultimap(rt.AdtStore(), st.CronEventQueue, power.CronQueueHamtBitwidth, power.CronQueueAmtBitwidth) require.NoError(t, err) @@ -707,8 +729,16 @@ func TestCron(t *testing.T) { expectQueryNetworkInfo(rt, actor) + st := getState(rt) + + input := builtin.DeferredCronEventParams{ + EventPayload: []byte{}, + RewardSmoothed: actor.thisEpochRewardSmoothed, + QualityAdjPowerSmoothed: st.ThisEpochQAPowerSmoothed, + } + // only expect second deferred cron event call - rt.ExpectSend(miner2, builtin.MethodsMiner.OnDeferredCronEvent, builtin.CBORBytes(nil), big.Zero(), nil, exitcode.Ok) + rt.ExpectSend(miner2, builtin.MethodsMiner.OnDeferredCronEvent, &input, big.Zero(), nil, exitcode.Ok) // Reward actor still invoked expectedPower := big.NewInt(0) @@ -750,11 +780,19 @@ func TestCron(t *testing.T) { expectQueryNetworkInfo(rt, actor) + st := getState(rt) + + input := builtin.DeferredCronEventParams{ + EventPayload: []byte{}, + RewardSmoothed: actor.thisEpochRewardSmoothed, + QualityAdjPowerSmoothed: st.ThisEpochQAPowerSmoothed, + } + // First send fails - rt.ExpectSend(miner1, builtin.MethodsMiner.OnDeferredCronEvent, builtin.CBORBytes(nil), big.Zero(), nil, exitcode.ErrIllegalState) + rt.ExpectSend(miner1, builtin.MethodsMiner.OnDeferredCronEvent, &input, big.Zero(), nil, exitcode.ErrIllegalState) // Subsequent one still invoked - rt.ExpectSend(miner2, builtin.MethodsMiner.OnDeferredCronEvent, builtin.CBORBytes(nil), big.Zero(), nil, exitcode.Ok) + rt.ExpectSend(miner2, builtin.MethodsMiner.OnDeferredCronEvent, &input, big.Zero(), nil, exitcode.Ok) // Reward actor still invoked rt.ExpectSend(builtin.RewardActorAddr, builtin.MethodsReward.UpdateNetworkKPI, &expectedPower, big.Zero(), nil, exitcode.Ok) @@ -770,7 +808,7 @@ func TestCron(t *testing.T) { actor.expectMinersAboveMinPower(rt, 0) // miner's claim is removed - st := getState(rt) + st = getState(rt) _, found, err := st.GetClaim(rt.AdtStore(), miner1) require.NoError(t, err) assert.False(t, found) @@ -1033,10 +1071,10 @@ func TestCronBatchProofVerifies(t *testing.T) { // expect sends for confirmed sectors for _, cs := range cs { param := &builtin.ConfirmSectorProofsParams{ - Sectors: cs.sectorNums, - RewardStatsThisEpochRewardSmoothed: ac.thisEpochRewardSmoothed, - RewardStatsThisEpochBaselinePower: ac.thisEpochBaselinePower, - PwrTotalQualityAdjPowerSmoothed: st.ThisEpochQAPowerSmoothed, + Sectors: cs.sectorNums, + RewardSmoothed: ac.thisEpochRewardSmoothed, + RewardBaselinePower: ac.thisEpochBaselinePower, + QualityAdjPowerSmoothed: st.ThisEpochQAPowerSmoothed, } rt.ExpectSend(cs.miner, builtin.MethodsMiner.ConfirmSectorProofsValid, param, abi.NewTokenAmount(0), nil, 0) } @@ -1071,6 +1109,8 @@ func TestCronBatchProofVerifies(t *testing.T) { rt.SetEpoch(abi.ChainEpoch(0)) rt.SetCaller(builtin.CronActorAddr, builtin.CronActorCodeID) + expectQueryNetworkInfo(rt, ac) + rt.ExpectAbort(exitcode.ErrIllegalState, func() { rt.Call(ac.Actor.OnEpochTickEnd, nil) }) @@ -1159,10 +1199,10 @@ func (h *spActorHarness) onEpochTickEnd(rt *mock.Runtime, currEpoch abi.ChainEpo // expect sends for confirmed sectors for _, cs := range confirmedSectors { param := &builtin.ConfirmSectorProofsParams{ - Sectors: cs.sectorNums, - RewardStatsThisEpochRewardSmoothed: h.thisEpochRewardSmoothed, - RewardStatsThisEpochBaselinePower: h.thisEpochBaselinePower, - PwrTotalQualityAdjPowerSmoothed: st.ThisEpochQAPowerSmoothed, + Sectors: cs.sectorNums, + RewardSmoothed: h.thisEpochRewardSmoothed, + RewardBaselinePower: h.thisEpochBaselinePower, + QualityAdjPowerSmoothed: st.ThisEpochQAPowerSmoothed, } rt.ExpectSend(cs.miner, builtin.MethodsMiner.ConfirmSectorProofsValid, param, abi.NewTokenAmount(0), nil, 0) } @@ -1365,12 +1405,6 @@ func (h *spActorHarness) expectTotalPowerEager(rt *mock.Runtime, expectedRaw, ex /// at the start of every onEpochTickEnd, cron should get these values- they're necessary for ConfirmSectorProofsValid but don't change, so they only need to be looked up once. /// should expect these two sends in the tests and mock up the values as needed... func expectQueryNetworkInfo(rt *mock.Runtime, h *spActorHarness) { - st := getState(rt) - - currentPower := power.CurrentTotalPowerReturn{ - QualityAdjPowerSmoothed: st.ThisEpochQAPowerSmoothed, - } - currentReward := reward.ThisEpochRewardReturn{ ThisEpochBaselinePower: h.thisEpochBaselinePower, ThisEpochRewardSmoothed: h.thisEpochRewardSmoothed, @@ -1383,15 +1417,6 @@ func expectQueryNetworkInfo(rt *mock.Runtime, h *spActorHarness) { ¤tReward, exitcode.Ok, ) - - rt.ExpectSend( - builtin.StoragePowerActorAddr, - builtin.MethodsPower.CurrentTotalPower, - nil, - big.Zero(), - ¤tPower, - exitcode.Ok, - ) } func (h *spActorHarness) expectMinersAboveMinPower(rt *mock.Runtime, count int64) { diff --git a/actors/builtin/shared.go b/actors/builtin/shared.go index 70bc0da1f..ddad80d1a 100644 --- a/actors/builtin/shared.go +++ b/actors/builtin/shared.go @@ -96,13 +96,19 @@ type MinerAddrs struct { ControlAddrs []addr.Address } +type DeferredCronEventParams struct { + EventPayload []byte + RewardSmoothed smoothing.FilterEstimate + QualityAdjPowerSmoothed smoothing.FilterEstimate +} + // Note: we could move this alias back to the mutually-importing packages that use it, now that they // can instead both alias the v2 version. type ConfirmSectorProofsParams struct { - Sectors []abi.SectorNumber - RewardStatsThisEpochRewardSmoothed smoothing.FilterEstimate - RewardStatsThisEpochBaselinePower abi.StoragePower - PwrTotalQualityAdjPowerSmoothed smoothing.FilterEstimate + Sectors []abi.SectorNumber + RewardSmoothed smoothing.FilterEstimate + RewardBaselinePower abi.StoragePower + QualityAdjPowerSmoothed smoothing.FilterEstimate } // ResolveToIDAddr resolves the given address to it's ID address form. diff --git a/actors/test/commit_post_test.go b/actors/test/commit_post_test.go index e85843bad..803876db8 100644 --- a/actors/test/commit_post_test.go +++ b/actors/test/commit_post_test.go @@ -76,15 +76,11 @@ func TestCommitPoStFlow(t *testing.T) { SubInvocations: []vm.ExpectInvocation{ {To: builtin.StoragePowerActorAddr, Method: builtin.MethodsPower.OnEpochTickEnd, SubInvocations: []vm.ExpectInvocation{ {To: builtin.RewardActorAddr, Method: builtin.MethodsReward.ThisEpochReward}, - {To: builtin.StoragePowerActorAddr, Method: builtin.MethodsPower.CurrentTotalPower}, {To: minerAddrs.IDAddress, Method: builtin.MethodsMiner.OnDeferredCronEvent, SubInvocations: []vm.ExpectInvocation{ - {To: builtin.RewardActorAddr, Method: builtin.MethodsReward.ThisEpochReward}, - {To: builtin.StoragePowerActorAddr, Method: builtin.MethodsPower.CurrentTotalPower}, // The call to burnt funds indicates the overdue precommit has been penalized {To: builtin.BurntFundsActorAddr, Method: builtin.MethodSend, Value: vm.ExpectAttoFil(precommits[0].PreCommitDeposit)}, // No re-enrollment of cron because burning of PCD discontinues miner cron scheduling }}, - //{To: minerAddrs.IDAddress, Method: builtin.MethodsMiner.ConfirmSectorProofsValid}, {To: builtin.RewardActorAddr, Method: builtin.MethodsReward.UpdateNetworkKPI}, }}, {To: builtin.StorageMarketActorAddr, Method: builtin.MethodsMarket.CronTick}, @@ -135,7 +131,6 @@ func TestCommitPoStFlow(t *testing.T) { SubInvocations: []vm.ExpectInvocation{ {To: builtin.StoragePowerActorAddr, Method: builtin.MethodsPower.OnEpochTickEnd, SubInvocations: []vm.ExpectInvocation{ {To: builtin.RewardActorAddr, Method: builtin.MethodsReward.ThisEpochReward}, - {To: builtin.StoragePowerActorAddr, Method: builtin.MethodsPower.CurrentTotalPower}, // expect confirm sector proofs valid because we prove committed, // but not an on deferred cron event because this is not a deadline boundary {To: minerAddrs.IDAddress, Method: builtin.MethodsMiner.ConfirmSectorProofsValid, SubInvocations: []vm.ExpectInvocation{ @@ -255,10 +250,7 @@ func TestCommitPoStFlow(t *testing.T) { SubInvocations: []vm.ExpectInvocation{ {To: builtin.StoragePowerActorAddr, Method: builtin.MethodsPower.OnEpochTickEnd, SubInvocations: []vm.ExpectInvocation{ {To: builtin.RewardActorAddr, Method: builtin.MethodsReward.ThisEpochReward}, - {To: builtin.StoragePowerActorAddr, Method: builtin.MethodsPower.CurrentTotalPower}, {To: minerAddrs.IDAddress, Method: builtin.MethodsMiner.OnDeferredCronEvent, SubInvocations: []vm.ExpectInvocation{ - {To: builtin.RewardActorAddr, Method: builtin.MethodsReward.ThisEpochReward}, - {To: builtin.StoragePowerActorAddr, Method: builtin.MethodsPower.CurrentTotalPower}, {To: builtin.StoragePowerActorAddr, Method: builtin.MethodsPower.EnrollCronEvent}, }}, {To: builtin.RewardActorAddr, Method: builtin.MethodsReward.UpdateNetworkKPI}, @@ -405,7 +397,6 @@ func TestMeasurePoRepGas(t *testing.T) { SubInvocations: []vm.ExpectInvocation{ {To: builtin.StoragePowerActorAddr, Method: builtin.MethodsPower.OnEpochTickEnd, SubInvocations: []vm.ExpectInvocation{ {To: builtin.RewardActorAddr, Method: builtin.MethodsReward.ThisEpochReward}, - {To: builtin.StoragePowerActorAddr, Method: builtin.MethodsPower.CurrentTotalPower}, // expect confirm sector proofs valid because we prove committed, // but not an on deferred cron event because this is not a deadline boundary {To: minerAddrs.IDAddress, Method: builtin.MethodsMiner.ConfirmSectorProofsValid, SubInvocations: []vm.ExpectInvocation{ @@ -853,7 +844,6 @@ func TestMeasureAggregatePorepGas(t *testing.T) { SubInvocations: []vm.ExpectInvocation{ {To: builtin.StoragePowerActorAddr, Method: builtin.MethodsPower.OnEpochTickEnd, SubInvocations: []vm.ExpectInvocation{ {To: builtin.RewardActorAddr, Method: builtin.MethodsReward.ThisEpochReward}, - {To: builtin.StoragePowerActorAddr, Method: builtin.MethodsPower.CurrentTotalPower}, // expect no confirm sector proofs valid because we prove committed with aggregation. // expect no on deferred cron event because this is not a deadline boundary {To: builtin.RewardActorAddr, Method: builtin.MethodsReward.UpdateNetworkKPI}, diff --git a/actors/test/committed_capacity_scenario_test.go b/actors/test/committed_capacity_scenario_test.go index cb7e6d2bf..bef5e99a0 100644 --- a/actors/test/committed_capacity_scenario_test.go +++ b/actors/test/committed_capacity_scenario_test.go @@ -186,10 +186,7 @@ func TestReplaceCommittedCapacitySectorWithDealLadenSector(t *testing.T) { SubInvocations: []vm.ExpectInvocation{ {To: builtin.StoragePowerActorAddr, Method: builtin.MethodsPower.OnEpochTickEnd, SubInvocations: []vm.ExpectInvocation{ {To: builtin.RewardActorAddr, Method: builtin.MethodsReward.ThisEpochReward}, - {To: builtin.StoragePowerActorAddr, Method: builtin.MethodsPower.CurrentTotalPower}, {To: minerAddrs.IDAddress, Method: builtin.MethodsMiner.OnDeferredCronEvent, SubInvocations: []vm.ExpectInvocation{ - {To: builtin.RewardActorAddr, Method: builtin.MethodsReward.ThisEpochReward}, - {To: builtin.StoragePowerActorAddr, Method: builtin.MethodsPower.CurrentTotalPower}, // pre-commit deposit is burnt {To: builtin.BurntFundsActorAddr, Method: builtin.MethodSend}, {To: builtin.StoragePowerActorAddr, Method: builtin.MethodsPower.EnrollCronEvent}, @@ -238,7 +235,6 @@ func TestReplaceCommittedCapacitySectorWithDealLadenSector(t *testing.T) { SubInvocations: []vm.ExpectInvocation{ {To: builtin.StoragePowerActorAddr, Method: builtin.MethodsPower.OnEpochTickEnd, SubInvocations: []vm.ExpectInvocation{ {To: builtin.RewardActorAddr, Method: builtin.MethodsReward.ThisEpochReward}, - {To: builtin.StoragePowerActorAddr, Method: builtin.MethodsPower.CurrentTotalPower}, {To: minerAddrs.IDAddress, Method: builtin.MethodsMiner.ConfirmSectorProofsValid, SubInvocations: []vm.ExpectInvocation{ // deals are now activated {To: builtin.StorageMarketActorAddr, Method: builtin.MethodsMarket.ActivateDeals}, @@ -281,10 +277,7 @@ func TestReplaceCommittedCapacitySectorWithDealLadenSector(t *testing.T) { SubInvocations: []vm.ExpectInvocation{ {To: builtin.StoragePowerActorAddr, Method: builtin.MethodsPower.OnEpochTickEnd, SubInvocations: []vm.ExpectInvocation{ {To: builtin.RewardActorAddr, Method: builtin.MethodsReward.ThisEpochReward}, - {To: builtin.StoragePowerActorAddr, Method: builtin.MethodsPower.CurrentTotalPower}, {To: minerAddrs.IDAddress, Method: builtin.MethodsMiner.OnDeferredCronEvent, SubInvocations: []vm.ExpectInvocation{ - {To: builtin.RewardActorAddr, Method: builtin.MethodsReward.ThisEpochReward}, - {To: builtin.StoragePowerActorAddr, Method: builtin.MethodsPower.CurrentTotalPower}, // power is removed for old sector and pledge is burnt {To: builtin.StoragePowerActorAddr, Method: builtin.MethodsPower.UpdateClaimedPower}, {To: builtin.StoragePowerActorAddr, Method: builtin.MethodsPower.UpdatePledgeTotal}, diff --git a/actors/test/power_scenario_test.go b/actors/test/power_scenario_test.go index 1a16d662f..dfc4a79eb 100644 --- a/actors/test/power_scenario_test.go +++ b/actors/test/power_scenario_test.go @@ -111,9 +111,8 @@ func TestOnEpochTickEnd(t *testing.T) { To: builtin.StoragePowerActorAddr, Method: builtin.MethodsPower.OnEpochTickEnd, SubInvocations: []vm.ExpectInvocation{ - // get data from reward and power actors for any eventual calls to confirmsectorproofvalid + // get data from reward actor for any eventual calls to confirmsectorproofsparams {To: builtin.RewardActorAddr, Method: builtin.MethodsReward.ThisEpochReward}, - {To: builtin.StoragePowerActorAddr, Method: builtin.MethodsPower.CurrentTotalPower}, { // expect call to reward to update kpi To: builtin.RewardActorAddr, @@ -138,14 +137,12 @@ func TestOnEpochTickEnd(t *testing.T) { SubInvocations: []vm.ExpectInvocation{ // get data from reward and power actors for any eventual calls to confirmsectorproofsvalid {To: builtin.RewardActorAddr, Method: builtin.MethodsReward.ThisEpochReward}, - {To: builtin.StoragePowerActorAddr, Method: builtin.MethodsPower.CurrentTotalPower}, { // expect call back to miner that was set up in create miner To: minerAddrs.IDAddress, Method: builtin.MethodsMiner.OnDeferredCronEvent, From: builtin.StoragePowerActorAddr, Value: vm.ExpectAttoFil(big.Zero()), - Params: vm.ExpectBytes(cronConfig.Payload), }, { // expect call to reward to update kpi diff --git a/gen/gen.go b/gen/gen.go index 629234b52..83007d2d9 100644 --- a/gen/gen.go +++ b/gen/gen.go @@ -34,6 +34,7 @@ func main() { if err := gen.WriteTupleEncodersToFile("./actors/builtin/cbor_gen.go", "builtin", builtin.MinerAddrs{}, builtin.ConfirmSectorProofsParams{}, + builtin.DeferredCronEventParams{}, // builtin.ApplyRewardParams{}, // Aliased from v2 ); err != nil { panic(err) diff --git a/test-vectors/determinism-check b/test-vectors/determinism-check index e3167444b..79d950b80 100644 --- a/test-vectors/determinism-check +++ b/test-vectors/determinism-check @@ -1 +1 @@ -- a24707af5859e242dc227b70545abb4f6b0ae33a8d466844e65d7a0c49da1d5f +- 29f667bb66182ab879be1b697696fccd352d6bc0e125d618da606ec55e2a1269