github.com/filecoin-project/specs-actors/v4@v4.0.2/actors/migration/nv12/test/miner_cron_test.go (about) 1 package test_test 2 3 import ( 4 "context" 5 "strings" 6 "testing" 7 8 "github.com/filecoin-project/go-address" 9 "github.com/filecoin-project/go-state-types/abi" 10 "github.com/filecoin-project/go-state-types/big" 11 "github.com/filecoin-project/go-state-types/exitcode" 12 "github.com/filecoin-project/go-state-types/rt" 13 ipld2 "github.com/filecoin-project/specs-actors/v2/support/ipld" 14 builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" 15 power3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/power" 16 vm3 "github.com/filecoin-project/specs-actors/v3/support/vm" 17 "github.com/ipfs/go-cid" 18 "github.com/stretchr/testify/assert" 19 "github.com/stretchr/testify/require" 20 21 builtin "github.com/filecoin-project/specs-actors/v4/actors/builtin" 22 exported "github.com/filecoin-project/specs-actors/v4/actors/builtin/exported" 23 "github.com/filecoin-project/specs-actors/v4/actors/builtin/miner" 24 "github.com/filecoin-project/specs-actors/v4/actors/migration/nv12" 25 "github.com/filecoin-project/specs-actors/v4/actors/states" 26 vm "github.com/filecoin-project/specs-actors/v4/support/vm" 27 ) 28 29 func TestEmptyMinersStopCronAfterMigration(t *testing.T) { 30 ctx := context.Background() 31 log := nv12.TestLogger{TB: t} 32 v := vm3.NewVMWithSingletons(ctx, t, ipld2.NewSyncBlockStoreInMemory()) 33 addrs := vm3.CreateAccounts(ctx, t, v, 110, big.Mul(big.NewInt(100_000), vm3.FIL), 93837779) 34 35 // create empty miners 36 minerAddrs := make([]address.Address, 100) 37 for i := 0; i < 100; i++ { 38 worker := addrs[i] 39 minerBalance := big.Mul(big.NewInt(10_000), vm3.FIL) 40 41 params := power3.CreateMinerParams{ 42 Owner: worker, 43 Worker: worker, 44 WindowPoStProofType: abi.RegisteredPoStProof_StackedDrgWindow32GiBV1, 45 Peer: abi.PeerID("fake peer id"), 46 } 47 ret := vm3.ApplyOk(t, v, worker, builtin3.StoragePowerActorAddr, minerBalance, builtin3.MethodsPower.CreateMiner, ¶ms) 48 createRet, ok := ret.(*power3.CreateMinerReturn) 49 require.True(t, ok) 50 minerAddrs[i] = createRet.IDAddress 51 } 52 // run network for a few proving periods 53 stop := v.GetEpoch() + abi.ChainEpoch(10_000) 54 v = AdvanceToEpochWithCronV3(t, v, stop) 55 56 // migrate 57 nextRoot, err := nv12.MigrateStateTree(ctx, v.Store(), v.StateRoot(), v.GetEpoch(), nv12.Config{MaxWorkers: 1}, log, nv12.NewMemMigrationCache()) 58 require.NoError(t, err) 59 60 lookup := map[cid.Cid]rt.VMActor{} 61 for _, ba := range exported.BuiltinActors() { 62 lookup[ba.Code()] = ba 63 } 64 v4, err := vm.NewVMAtEpoch(ctx, lookup, v.Store(), nextRoot, v.GetEpoch()) 65 require.NoError(t, err) 66 67 // check that all miners are cronning 68 stateTree, err := v4.GetStateTree() 69 require.NoError(t, err) 70 err = stateTree.ForEach(func(addr address.Address, act *states.Actor) error { 71 if act.Code.Equals(builtin.StorageMinerActorCodeID) { 72 var mSt miner.State 73 err := v4.GetState(addr, &mSt) 74 require.NoError(t, err) 75 assert.True(t, mSt.DeadlineCronActive) 76 } 77 return nil 78 }) 79 require.NoError(t, err) 80 81 // empty miners stop cronning within 1 proving period 82 v4 = AdvanceToEpochWithCron(t, v4, v4.GetEpoch()+miner.WPoStProvingPeriod) 83 84 // check invariants 85 stateTree, err = v4.GetStateTree() 86 require.NoError(t, err) 87 totalBalance, err := v4.GetTotalActorBalance() 88 require.NoError(t, err) 89 msgs, err := states.CheckStateInvariants(stateTree, totalBalance, v4.GetEpoch()-1) 90 require.NoError(t, err) 91 92 assert.Equal(t, 0, len(msgs.Messages()), strings.Join(msgs.Messages(), "\n")) 93 94 // check that no miners are cronning 95 err = stateTree.ForEach(func(addr address.Address, act *states.Actor) error { 96 if act.Code.Equals(builtin.StorageMinerActorCodeID) { 97 var mSt miner.State 98 err := v4.GetState(addr, &mSt) 99 require.NoError(t, err) 100 assert.False(t, mSt.DeadlineCronActive) 101 } 102 return nil 103 }) 104 require.NoError(t, err) 105 } 106 107 // Advances to given epoch running cron for all epochs up to but not including this epoch. 108 // This utility didn't exist in v3 vm utils so copying here after the fact to handle migrations. 109 func AdvanceToEpochWithCronV3(t *testing.T, v *vm3.VM, stop abi.ChainEpoch) *vm3.VM { 110 currEpoch := v.GetEpoch() 111 var err error 112 for currEpoch < stop { 113 _, code := v.ApplyMessage(builtin3.SystemActorAddr, builtin3.CronActorAddr, big.Zero(), builtin3.MethodsCron.EpochTick, nil) 114 require.Equal(t, exitcode.Ok, code) 115 currEpoch += 1 116 v, err = v.WithEpoch(currEpoch) 117 require.NoError(t, err) 118 } 119 return v 120 } 121 122 // Advances to given epoch running cron for all epochs up to but not including this epoch. 123 func AdvanceToEpochWithCron(t *testing.T, v *vm.VM, stop abi.ChainEpoch) *vm.VM { 124 currEpoch := v.GetEpoch() 125 var err error 126 for currEpoch < stop { 127 _, code := v.ApplyMessage(builtin.SystemActorAddr, builtin.CronActorAddr, big.Zero(), builtin.MethodsCron.EpochTick, nil) 128 require.Equal(t, exitcode.Ok, code) 129 currEpoch += 1 130 v, err = v.WithEpoch(currEpoch) 131 require.NoError(t, err) 132 } 133 return v 134 }