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, &params)
    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  }