github.com/filecoin-project/specs-actors/v4@v4.0.2/actors/builtin/power/power_test.go (about)

     1  package power_test
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"strconv"
     7  	"strings"
     8  	"testing"
     9  
    10  	addr "github.com/filecoin-project/go-address"
    11  	"github.com/filecoin-project/go-state-types/abi"
    12  	"github.com/filecoin-project/go-state-types/big"
    13  	"github.com/filecoin-project/go-state-types/exitcode"
    14  	"github.com/filecoin-project/go-state-types/network"
    15  	cid "github.com/ipfs/go-cid"
    16  	assert "github.com/stretchr/testify/assert"
    17  	require "github.com/stretchr/testify/require"
    18  
    19  	"github.com/filecoin-project/specs-actors/v4/actors/builtin"
    20  	initact "github.com/filecoin-project/specs-actors/v4/actors/builtin/init"
    21  	"github.com/filecoin-project/specs-actors/v4/actors/builtin/market"
    22  	mineract "github.com/filecoin-project/specs-actors/v4/actors/builtin/miner"
    23  	"github.com/filecoin-project/specs-actors/v4/actors/builtin/power"
    24  	"github.com/filecoin-project/specs-actors/v4/actors/runtime/proof"
    25  	"github.com/filecoin-project/specs-actors/v4/actors/util/adt"
    26  	"github.com/filecoin-project/specs-actors/v4/support/mock"
    27  	tutil "github.com/filecoin-project/specs-actors/v4/support/testing"
    28  )
    29  
    30  func TestExports(t *testing.T) {
    31  	mock.CheckActorExports(t, power.Actor{})
    32  }
    33  
    34  func TestConstruction(t *testing.T) {
    35  	actor := newHarness(t)
    36  	owner := tutil.NewIDAddr(t, 101)
    37  	miner := tutil.NewIDAddr(t, 103)
    38  	actr := tutil.NewActorAddr(t, "actor")
    39  
    40  	builder := mock.NewBuilder(builtin.StoragePowerActorAddr).WithCaller(builtin.SystemActorAddr, builtin.SystemActorCodeID)
    41  
    42  	t.Run("simple construction", func(t *testing.T) {
    43  		rt := builder.Build(t)
    44  
    45  		actor.constructAndVerify(rt)
    46  		actor.checkState(rt)
    47  	})
    48  
    49  	t.Run("create miner", func(t *testing.T) {
    50  		rt := builder.Build(t)
    51  		actor.constructAndVerify(rt)
    52  
    53  		actor.createMiner(rt, owner, owner, miner, actr, abi.PeerID("miner"), []abi.Multiaddrs{{1}},
    54  			abi.RegisteredPoStProof_StackedDrgWindow32GiBV1, abi.NewTokenAmount(10))
    55  
    56  		var st power.State
    57  		rt.GetState(&st)
    58  		assert.Equal(t, int64(1), st.MinerCount)
    59  		assert.Equal(t, abi.NewStoragePower(0), st.TotalQualityAdjPower)
    60  		assert.Equal(t, abi.NewStoragePower(0), st.TotalRawBytePower)
    61  		assert.Equal(t, int64(0), st.MinerAboveMinPowerCount)
    62  
    63  		claim, err := adt.AsMap(adt.AsStore(rt), st.Claims, builtin.DefaultHamtBitwidth)
    64  		assert.NoError(t, err)
    65  		keys, err := claim.CollectKeys()
    66  		require.NoError(t, err)
    67  		assert.Equal(t, 1, len(keys))
    68  		var actualClaim power.Claim
    69  		found, err_ := claim.Get(asKey(keys[0]), &actualClaim)
    70  		require.NoError(t, err_)
    71  		assert.True(t, found)
    72  		assert.Equal(t, power.Claim{abi.RegisteredPoStProof_StackedDrgWindow32GiBV1, big.Zero(), big.Zero()}, actualClaim) // miner has not proven anything
    73  
    74  		verifyEmptyMap(t, rt, st.CronEventQueue)
    75  		actor.checkState(rt)
    76  	})
    77  }
    78  
    79  func TestCreateMinerFailures(t *testing.T) {
    80  	owner := tutil.NewIDAddr(t, 101)
    81  	peer := abi.PeerID("miner")
    82  	mAddr := []abi.Multiaddrs{{1}}
    83  	windowPoStProofType := abi.RegisteredPoStProof_StackedDrgWindow2KiBV1
    84  
    85  	t.Run("fails when caller is not of signable type", func(t *testing.T) {
    86  		rt, ac := basicPowerSetup(t)
    87  
    88  		rt.SetCaller(owner, builtin.StorageMinerActorCodeID)
    89  		rt.ExpectValidateCallerType(builtin.CallerTypesSignable...)
    90  		rt.ExpectAbort(exitcode.SysErrForbidden, func() {
    91  			rt.Call(ac.CreateMiner, &power.CreateMinerParams{})
    92  		})
    93  		rt.Verify()
    94  	})
    95  
    96  	t.Run("fails if send to Init Actor fails", func(t *testing.T) {
    97  		rt, ac := basicPowerSetup(t)
    98  
    99  		createMinerParams := &power.CreateMinerParams{
   100  			Owner:               owner,
   101  			Worker:              owner,
   102  			WindowPoStProofType: windowPoStProofType,
   103  			Peer:                peer,
   104  			Multiaddrs:          mAddr,
   105  		}
   106  
   107  		// owner send CreateMiner to Actor
   108  		rt.SetCaller(owner, builtin.AccountActorCodeID)
   109  		rt.SetReceived(abi.NewTokenAmount(10))
   110  		rt.SetBalance(abi.NewTokenAmount(10))
   111  		rt.ExpectValidateCallerType(builtin.AccountActorCodeID, builtin.MultisigActorCodeID)
   112  
   113  		msgParams := &initact.ExecParams{
   114  			CodeCID:           builtin.StorageMinerActorCodeID,
   115  			ConstructorParams: initCreateMinerBytes(t, owner, owner, peer, mAddr, windowPoStProofType),
   116  		}
   117  		expRet := initact.ExecReturn{
   118  			IDAddress:     tutil.NewIDAddr(t, 1475),
   119  			RobustAddress: tutil.NewActorAddr(t, "test"),
   120  		}
   121  		rt.ExpectSend(builtin.InitActorAddr, builtin.MethodsInit.Exec, msgParams, abi.NewTokenAmount(10),
   122  			&expRet, exitcode.ErrInsufficientFunds)
   123  
   124  		rt.ExpectAbort(exitcode.ErrInsufficientFunds, func() {
   125  			rt.Call(ac.CreateMiner, createMinerParams)
   126  		})
   127  	})
   128  }
   129  
   130  func TestUpdateClaimedPowerFailures(t *testing.T) {
   131  	rawDelta := big.NewInt(100)
   132  	qaDelta := big.NewInt(200)
   133  	miner := tutil.NewIDAddr(t, 101)
   134  
   135  	t.Run("fails if caller is not a StorageMinerActor", func(t *testing.T) {
   136  		rt, ac := basicPowerSetup(t)
   137  		params := power.UpdateClaimedPowerParams{
   138  			RawByteDelta:         rawDelta,
   139  			QualityAdjustedDelta: qaDelta,
   140  		}
   141  		rt.SetCaller(miner, builtin.SystemActorCodeID)
   142  		rt.ExpectValidateCallerType(builtin.StorageMinerActorCodeID)
   143  
   144  		rt.ExpectAbort(exitcode.SysErrForbidden, func() {
   145  			rt.Call(ac.UpdateClaimedPower, &params)
   146  		})
   147  
   148  		rt.Verify()
   149  	})
   150  
   151  	t.Run("fails if claim does not exist for caller", func(t *testing.T) {
   152  		rt, ac := basicPowerSetup(t)
   153  		params := power.UpdateClaimedPowerParams{
   154  			RawByteDelta:         rawDelta,
   155  			QualityAdjustedDelta: qaDelta,
   156  		}
   157  		rt.SetCaller(miner, builtin.StorageMinerActorCodeID)
   158  		rt.ExpectValidateCallerType(builtin.StorageMinerActorCodeID)
   159  
   160  		rt.ExpectAbort(exitcode.ErrNotFound, func() {
   161  			rt.Call(ac.UpdateClaimedPower, &params)
   162  		})
   163  
   164  		rt.Verify()
   165  	})
   166  }
   167  
   168  func TestEnrollCronEpoch(t *testing.T) {
   169  	owner := tutil.NewBLSAddr(t, 0)
   170  	miner := tutil.NewIDAddr(t, 101)
   171  
   172  	t.Run("enroll multiple events", func(t *testing.T) {
   173  		rt, ac := basicPowerSetup(t)
   174  		ac.createMinerBasic(rt, owner, owner, miner)
   175  		e1 := abi.ChainEpoch(1)
   176  
   177  		// enroll event with miner 1
   178  		p1 := []byte("hello")
   179  		ac.enrollCronEvent(rt, miner, e1, p1)
   180  
   181  		events := ac.getEnrolledCronTicks(rt, e1)
   182  
   183  		evt := events[0]
   184  		require.EqualValues(t, p1, evt.CallbackPayload)
   185  		require.EqualValues(t, miner, evt.MinerAddr)
   186  
   187  		// enroll another event with the same miner
   188  		p2 := []byte("hello2")
   189  		ac.enrollCronEvent(rt, miner, e1, p2)
   190  		events = ac.getEnrolledCronTicks(rt, e1)
   191  		evt = events[0]
   192  		require.EqualValues(t, p1, evt.CallbackPayload)
   193  		require.EqualValues(t, miner, evt.MinerAddr)
   194  
   195  		evt = events[1]
   196  		require.EqualValues(t, p2, evt.CallbackPayload)
   197  		require.EqualValues(t, miner, evt.MinerAddr)
   198  
   199  		// enroll another event with a different miner for a different epoch
   200  		e2 := abi.ChainEpoch(2)
   201  		p3 := []byte("test")
   202  		miner2 := tutil.NewIDAddr(t, 501)
   203  		ac.createMinerBasic(rt, owner, owner, miner2)
   204  		ac.enrollCronEvent(rt, miner2, e2, p3)
   205  		events = ac.getEnrolledCronTicks(rt, e2)
   206  		evt = events[0]
   207  		require.EqualValues(t, p3, evt.CallbackPayload)
   208  		require.EqualValues(t, miner2, evt.MinerAddr)
   209  		ac.checkState(rt)
   210  	})
   211  
   212  	t.Run("enroll for an epoch before the current epoch", func(t *testing.T) {
   213  		rt, ac := basicPowerSetup(t)
   214  		ac.createMinerBasic(rt, owner, owner, miner)
   215  
   216  		// current epoch is 5
   217  		current := abi.ChainEpoch(5)
   218  		rt.SetEpoch(current)
   219  
   220  		// enroll event with miner at epoch=2
   221  		p1 := []byte("hello")
   222  		e1 := abi.ChainEpoch(2)
   223  		ac.enrollCronEvent(rt, miner, e1, p1)
   224  		events := ac.getEnrolledCronTicks(rt, e1)
   225  		evt := events[0]
   226  		require.EqualValues(t, p1, evt.CallbackPayload)
   227  		require.EqualValues(t, miner, evt.MinerAddr)
   228  		st := getState(rt)
   229  		require.EqualValues(t, abi.ChainEpoch(0), st.FirstCronEpoch)
   230  
   231  		// enroll event with miner at epoch=1
   232  		p2 := []byte("hello2")
   233  		e2 := abi.ChainEpoch(1)
   234  		ac.enrollCronEvent(rt, miner, e2, p2)
   235  		events = ac.getEnrolledCronTicks(rt, e2)
   236  		evt = events[0]
   237  		require.EqualValues(t, p2, evt.CallbackPayload)
   238  		require.EqualValues(t, miner, evt.MinerAddr)
   239  		require.EqualValues(t, abi.ChainEpoch(0), st.FirstCronEpoch)
   240  		ac.checkState(rt)
   241  	})
   242  
   243  	t.Run("fails if epoch is negative", func(t *testing.T) {
   244  		rt, ac := basicPowerSetup(t)
   245  
   246  		rt.ExpectAbort(exitcode.ErrIllegalArgument, func() {
   247  			ac.enrollCronEvent(rt, miner, abi.ChainEpoch(-1), []byte("payload"))
   248  		})
   249  	})
   250  }
   251  
   252  func TestPowerAndPledgeAccounting(t *testing.T) {
   253  	actor := newHarness(t)
   254  	owner := tutil.NewIDAddr(t, 101)
   255  	miner1 := tutil.NewIDAddr(t, 111)
   256  	miner2 := tutil.NewIDAddr(t, 112)
   257  	miner3 := tutil.NewIDAddr(t, 113)
   258  	miner4 := tutil.NewIDAddr(t, 114)
   259  	miner5 := tutil.NewIDAddr(t, 115)
   260  
   261  	// These tests use the min power for consensus to check the accounting above and below that value.
   262  	powerUnit, err := builtin.ConsensusMinerMinPower(abi.RegisteredPoStProof_StackedDrgWindow32GiBV1)
   263  	require.NoError(t, err)
   264  
   265  	mul := func(a big.Int, b int64) big.Int {
   266  		return big.Mul(a, big.NewInt(b))
   267  	}
   268  	div := func(a big.Int, b int64) big.Int {
   269  		return big.Div(a, big.NewInt(b))
   270  	}
   271  	smallPowerUnit := big.NewInt(1_000_000)
   272  	require.True(t, smallPowerUnit.LessThan(powerUnit), "power.ConsensusMinerMinPower has changed requiring update to this test")
   273  	// Subtests implicitly rely on ConsensusMinerMinMiners = 3
   274  	require.Equal(t, 4, power.ConsensusMinerMinMiners, "power.ConsensusMinerMinMiners has changed requiring update to this test")
   275  
   276  	builder := mock.NewBuilder(builtin.StoragePowerActorAddr).
   277  		WithCaller(builtin.SystemActorAddr, builtin.SystemActorCodeID)
   278  
   279  	t.Run("power & pledge accounted below threshold", func(t *testing.T) {
   280  
   281  		rt := builder.Build(t)
   282  		actor.constructAndVerify(rt)
   283  
   284  		actor.createMinerBasic(rt, owner, owner, miner1)
   285  		actor.createMinerBasic(rt, owner, owner, miner2)
   286  
   287  		ret := actor.currentPowerTotal(rt)
   288  		assert.Equal(t, big.Zero(), ret.RawBytePower)
   289  		assert.Equal(t, big.Zero(), ret.QualityAdjPower)
   290  		assert.Equal(t, big.Zero(), ret.PledgeCollateral)
   291  
   292  		// Add power for miner1
   293  		actor.updateClaimedPower(rt, miner1, smallPowerUnit, mul(smallPowerUnit, 2))
   294  		actor.expectTotalPowerEager(rt, smallPowerUnit, mul(smallPowerUnit, 2))
   295  		assert.Equal(t, big.Zero(), ret.PledgeCollateral)
   296  
   297  		// Add power and pledge for miner2
   298  		actor.updateClaimedPower(rt, miner2, smallPowerUnit, smallPowerUnit)
   299  		actor.updatePledgeTotal(rt, miner1, abi.NewTokenAmount(1e6))
   300  		actor.expectTotalPowerEager(rt, mul(smallPowerUnit, 2), mul(smallPowerUnit, 3))
   301  		actor.expectTotalPledgeEager(rt, abi.NewTokenAmount(1e6))
   302  
   303  		rt.Verify()
   304  
   305  		// Verify claims in state.
   306  		var st power.State
   307  		rt.GetState(&st)
   308  		claim1 := actor.getClaim(rt, miner1)
   309  		require.Equal(t, smallPowerUnit, claim1.RawBytePower)
   310  		require.Equal(t, mul(smallPowerUnit, 2), claim1.QualityAdjPower)
   311  
   312  		claim2 := actor.getClaim(rt, miner2)
   313  		require.Equal(t, smallPowerUnit, claim2.RawBytePower)
   314  		require.Equal(t, smallPowerUnit, claim2.QualityAdjPower)
   315  
   316  		// Subtract power and some pledge for miner2
   317  		actor.updateClaimedPower(rt, miner2, smallPowerUnit.Neg(), smallPowerUnit.Neg())
   318  		actor.updatePledgeTotal(rt, miner2, abi.NewTokenAmount(1e5).Neg())
   319  		actor.expectTotalPowerEager(rt, mul(smallPowerUnit, 1), mul(smallPowerUnit, 2))
   320  		actor.expectTotalPledgeEager(rt, abi.NewTokenAmount(9e5))
   321  
   322  		rt.GetState(&st)
   323  		claim2 = actor.getClaim(rt, miner2)
   324  		require.Equal(t, big.Zero(), claim2.RawBytePower)
   325  		require.Equal(t, big.Zero(), claim2.QualityAdjPower)
   326  		actor.checkState(rt)
   327  	})
   328  
   329  	t.Run("new miner updates MinerAboveMinPowerCount", func(t *testing.T) {
   330  		for _, test := range []struct {
   331  			version        network.Version
   332  			proof          abi.RegisteredPoStProof
   333  			expectedMiners int64
   334  		}{{
   335  			version:        network.Version7,
   336  			proof:          abi.RegisteredPoStProof_StackedDrgWindow2KiBV1,
   337  			expectedMiners: 0,
   338  		}, {
   339  			version:        network.Version7,
   340  			proof:          abi.RegisteredPoStProof_StackedDrgWindow32GiBV1,
   341  			expectedMiners: 0,
   342  		}} {
   343  			rt := builder.WithNetworkVersion(test.version).Build(t)
   344  			actor.constructAndVerify(rt)
   345  			actor.windowPoStProof = test.proof
   346  			actor.createMinerBasic(rt, owner, owner, miner1)
   347  
   348  			st := getState(rt)
   349  			assert.Equal(t, test.expectedMiners, st.MinerAboveMinPowerCount)
   350  		}
   351  	})
   352  
   353  	t.Run("power accounting crossing threshold", func(t *testing.T) {
   354  		rt := builder.Build(t)
   355  		actor.constructAndVerify(rt)
   356  
   357  		actor.createMinerBasic(rt, owner, owner, miner1)
   358  		actor.createMinerBasic(rt, owner, owner, miner2)
   359  		actor.createMinerBasic(rt, owner, owner, miner3)
   360  		actor.createMinerBasic(rt, owner, owner, miner4)
   361  		actor.createMinerBasic(rt, owner, owner, miner5)
   362  
   363  		// Use qa power 10x raw power to show it's not being used for threshold calculations.
   364  		actor.updateClaimedPower(rt, miner1, smallPowerUnit, mul(smallPowerUnit, 10))
   365  		actor.updateClaimedPower(rt, miner2, smallPowerUnit, mul(smallPowerUnit, 10))
   366  
   367  		actor.updateClaimedPower(rt, miner3, powerUnit, mul(powerUnit, 10))
   368  		actor.updateClaimedPower(rt, miner4, powerUnit, mul(powerUnit, 10))
   369  		actor.updateClaimedPower(rt, miner5, powerUnit, mul(powerUnit, 10))
   370  
   371  		// Below threshold small miner power is counted
   372  		expectedTotalBelow := big.Sum(mul(smallPowerUnit, 2), mul(powerUnit, 3))
   373  		actor.expectTotalPowerEager(rt, expectedTotalBelow, mul(expectedTotalBelow, 10))
   374  
   375  		// Above threshold (power.ConsensusMinerMinMiners = 4) small miner power is ignored
   376  		delta := big.Sub(powerUnit, smallPowerUnit)
   377  		actor.updateClaimedPower(rt, miner2, delta, mul(delta, 10))
   378  		expectedTotalAbove := mul(powerUnit, 4)
   379  		actor.expectTotalPowerEager(rt, expectedTotalAbove, mul(expectedTotalAbove, 10))
   380  
   381  		st := getState(rt)
   382  		assert.Equal(t, int64(4), st.MinerAboveMinPowerCount)
   383  
   384  		// Less than 4 miners above threshold again small miner power is counted again
   385  		actor.updateClaimedPower(rt, miner4, delta.Neg(), mul(delta.Neg(), 10))
   386  		actor.expectTotalPowerEager(rt, expectedTotalBelow, mul(expectedTotalBelow, 10))
   387  		actor.checkState(rt)
   388  	})
   389  
   390  	t.Run("all of one miner's power disappears when that miner dips below min power threshold", func(t *testing.T) {
   391  		// Setup four miners above threshold
   392  		rt := builder.Build(t)
   393  		actor.constructAndVerify(rt)
   394  
   395  		actor.createMinerBasic(rt, owner, owner, miner1)
   396  		actor.createMinerBasic(rt, owner, owner, miner2)
   397  		actor.createMinerBasic(rt, owner, owner, miner3)
   398  		actor.createMinerBasic(rt, owner, owner, miner4)
   399  		actor.createMinerBasic(rt, owner, owner, miner5)
   400  
   401  		actor.updateClaimedPower(rt, miner1, powerUnit, powerUnit)
   402  		actor.updateClaimedPower(rt, miner2, powerUnit, powerUnit)
   403  		actor.updateClaimedPower(rt, miner3, powerUnit, powerUnit)
   404  		actor.updateClaimedPower(rt, miner4, powerUnit, powerUnit)
   405  		actor.updateClaimedPower(rt, miner5, powerUnit, powerUnit)
   406  
   407  		expectedTotal := mul(powerUnit, 5)
   408  		actor.expectTotalPowerEager(rt, expectedTotal, expectedTotal)
   409  
   410  		// miner4 dips just below threshold
   411  		actor.updateClaimedPower(rt, miner4, smallPowerUnit.Neg(), smallPowerUnit.Neg())
   412  
   413  		expectedTotal = mul(powerUnit, 4)
   414  		actor.expectTotalPowerEager(rt, expectedTotal, expectedTotal)
   415  		actor.checkState(rt)
   416  	})
   417  
   418  	t.Run("power gets added when miner crosses minPower but not before", func(t *testing.T) {
   419  		// Setup four miners above threshold
   420  		rt := builder.Build(t)
   421  		actor.constructAndVerify(rt)
   422  
   423  		// create 4 miners that meet minimum
   424  		actor.createMinerBasic(rt, owner, owner, miner1)
   425  		actor.createMinerBasic(rt, owner, owner, miner2)
   426  		actor.createMinerBasic(rt, owner, owner, miner3)
   427  		actor.createMinerBasic(rt, owner, owner, miner4)
   428  
   429  		actor.updateClaimedPower(rt, miner1, powerUnit, powerUnit)
   430  		actor.updateClaimedPower(rt, miner2, powerUnit, powerUnit)
   431  		actor.updateClaimedPower(rt, miner3, powerUnit, powerUnit)
   432  		actor.updateClaimedPower(rt, miner4, powerUnit, powerUnit)
   433  
   434  		actor.expectMinersAboveMinPower(rt, 4)
   435  		expectedTotal := mul(powerUnit, 4)
   436  		actor.expectTotalPowerEager(rt, expectedTotal, expectedTotal)
   437  
   438  		actor.createMinerBasic(rt, owner, owner, miner5)
   439  		belowLimitUnit := big.Div(powerUnit, big.NewInt(2))
   440  
   441  		// below limit actors power is not added
   442  		actor.updateClaimedPower(rt, miner5, belowLimitUnit, belowLimitUnit)
   443  		actor.expectMinersAboveMinPower(rt, 4)
   444  		actor.expectTotalPowerEager(rt, expectedTotal, expectedTotal)
   445  
   446  		// just below limit
   447  		delta := big.Subtract(powerUnit, belowLimitUnit, big.NewInt(1))
   448  		actor.updateClaimedPower(rt, miner5, delta, delta)
   449  		actor.expectMinersAboveMinPower(rt, 4)
   450  		actor.expectTotalPowerEager(rt, expectedTotal, expectedTotal)
   451  
   452  		// at limit power is added
   453  		actor.updateClaimedPower(rt, miner5, big.NewInt(1), big.NewInt(1))
   454  		actor.expectMinersAboveMinPower(rt, 5)
   455  		newExpectedTotal := big.Add(expectedTotal, powerUnit)
   456  		actor.expectTotalPowerEager(rt, newExpectedTotal, newExpectedTotal)
   457  		actor.checkState(rt)
   458  	})
   459  
   460  	t.Run("threshold only depends on raw power, not qa power", func(t *testing.T) {
   461  		rt := builder.Build(t)
   462  		actor.constructAndVerify(rt)
   463  
   464  		actor.createMinerBasic(rt, owner, owner, miner1)
   465  		actor.createMinerBasic(rt, owner, owner, miner2)
   466  		actor.createMinerBasic(rt, owner, owner, miner3)
   467  		actor.createMinerBasic(rt, owner, owner, miner4)
   468  
   469  		actor.updateClaimedPower(rt, miner1, div(powerUnit, 2), powerUnit)
   470  		actor.updateClaimedPower(rt, miner2, div(powerUnit, 2), powerUnit)
   471  		actor.updateClaimedPower(rt, miner3, div(powerUnit, 2), powerUnit)
   472  		st := getState(rt)
   473  		assert.Equal(t, int64(0), st.MinerAboveMinPowerCount)
   474  
   475  		actor.updateClaimedPower(rt, miner1, div(powerUnit, 2), powerUnit)
   476  		actor.updateClaimedPower(rt, miner2, div(powerUnit, 2), powerUnit)
   477  		actor.updateClaimedPower(rt, miner3, div(powerUnit, 2), powerUnit)
   478  		st = getState(rt)
   479  		assert.Equal(t, int64(3), st.MinerAboveMinPowerCount)
   480  		actor.checkState(rt)
   481  	})
   482  
   483  	t.Run("qa power is above threshold before and after update", func(t *testing.T) {
   484  		rt := builder.Build(t)
   485  		actor.constructAndVerify(rt)
   486  
   487  		// update claim so qa is above threshold
   488  		actor.createMinerBasic(rt, owner, owner, miner1)
   489  		actor.updateClaimedPower(rt, miner1, mul(powerUnit, 3), mul(powerUnit, 3))
   490  		st := getState(rt)
   491  		require.EqualValues(t, mul(powerUnit, 3), st.TotalQualityAdjPower)
   492  		require.EqualValues(t, mul(powerUnit, 3), st.TotalRawBytePower)
   493  
   494  		// update such that it's above threshold again
   495  		actor.updateClaimedPower(rt, miner1, powerUnit, powerUnit)
   496  		st = getState(rt)
   497  		require.EqualValues(t, mul(powerUnit, 4), st.TotalQualityAdjPower)
   498  		require.EqualValues(t, mul(powerUnit, 4), st.TotalRawBytePower)
   499  		actor.checkState(rt)
   500  	})
   501  
   502  	t.Run("claimed power is externally available", func(t *testing.T) {
   503  		rt := builder.Build(t)
   504  		actor.constructAndVerify(rt)
   505  
   506  		actor.createMinerBasic(rt, owner, owner, miner1)
   507  		actor.updateClaimedPower(rt, miner1, powerUnit, powerUnit)
   508  		st := getState(rt)
   509  
   510  		claim, found, err := st.GetClaim(rt.AdtStore(), miner1)
   511  		require.NoError(t, err)
   512  		require.True(t, found)
   513  
   514  		assert.Equal(t, powerUnit, claim.RawBytePower)
   515  		assert.Equal(t, powerUnit, claim.QualityAdjPower)
   516  		actor.checkState(rt)
   517  	})
   518  }
   519  
   520  func TestUpdatePledgeTotal(t *testing.T) {
   521  	// most coverage of update pledge total is in accounting test above
   522  
   523  	actor := newHarness(t)
   524  	owner := tutil.NewIDAddr(t, 101)
   525  	miner := tutil.NewIDAddr(t, 111)
   526  	builder := mock.NewBuilder(builtin.StoragePowerActorAddr).
   527  		WithCaller(builtin.SystemActorAddr, builtin.SystemActorCodeID)
   528  
   529  	t.Run("update pledge total aborts if miner has no claim", func(t *testing.T) {
   530  		rt := builder.Build(t)
   531  		actor.constructAndVerify(rt)
   532  		actor.createMinerBasic(rt, owner, owner, miner)
   533  
   534  		// explicitly delete miner claim
   535  		actor.deleteClaim(rt, miner)
   536  
   537  		rt.ExpectAbortContainsMessage(exitcode.ErrForbidden, "unknown miner", func() {
   538  			actor.updatePledgeTotal(rt, miner, abi.NewTokenAmount(1e6))
   539  		})
   540  	})
   541  }
   542  
   543  func TestCron(t *testing.T) {
   544  	actor := newHarness(t)
   545  	miner1 := tutil.NewIDAddr(t, 101)
   546  	miner2 := tutil.NewIDAddr(t, 102)
   547  	owner := tutil.NewIDAddr(t, 103)
   548  
   549  	builder := mock.NewBuilder(builtin.StoragePowerActorAddr).WithCaller(builtin.SystemActorAddr, builtin.SystemActorCodeID)
   550  
   551  	t.Run("calls reward actor", func(t *testing.T) {
   552  		rt := builder.Build(t)
   553  		actor.constructAndVerify(rt)
   554  
   555  		expectedPower := big.NewInt(0)
   556  		rt.SetEpoch(1)
   557  		rt.ExpectValidateCallerAddr(builtin.CronActorAddr)
   558  		rt.ExpectSend(builtin.RewardActorAddr, builtin.MethodsReward.UpdateNetworkKPI, &expectedPower, abi.NewTokenAmount(0), nil, 0)
   559  		rt.SetCaller(builtin.CronActorAddr, builtin.CronActorCodeID)
   560  
   561  		rt.ExpectBatchVerifySeals(nil, nil, nil)
   562  		rt.Call(actor.Actor.OnEpochTickEnd, nil)
   563  		rt.Verify()
   564  		actor.checkState(rt)
   565  	})
   566  
   567  	t.Run("test amount sent to reward actor and state change", func(t *testing.T) {
   568  		powerUnit, err := builtin.ConsensusMinerMinPower(abi.RegisteredPoStProof_StackedDrgWindow2KiBV1)
   569  		require.NoError(t, err)
   570  
   571  		miner3 := tutil.NewIDAddr(t, 103)
   572  		miner4 := tutil.NewIDAddr(t, 104)
   573  
   574  		rt := builder.Build(t)
   575  		actor.constructAndVerify(rt)
   576  
   577  		actor.createMinerBasic(rt, owner, owner, miner1)
   578  		actor.createMinerBasic(rt, owner, owner, miner2)
   579  		actor.createMinerBasic(rt, owner, owner, miner3)
   580  		actor.createMinerBasic(rt, owner, owner, miner4)
   581  		actor.updateClaimedPower(rt, miner1, powerUnit, powerUnit)
   582  		actor.updateClaimedPower(rt, miner1, powerUnit, powerUnit)
   583  		actor.updateClaimedPower(rt, miner1, powerUnit, powerUnit)
   584  		actor.updateClaimedPower(rt, miner1, powerUnit, powerUnit)
   585  
   586  		expectedPower := big.Mul(big.NewInt(4), powerUnit)
   587  
   588  		delta := abi.NewTokenAmount(1)
   589  		actor.updatePledgeTotal(rt, miner1, delta)
   590  		actor.onEpochTickEnd(rt, 0, expectedPower, nil, nil)
   591  
   592  		st := getState(rt)
   593  		require.EqualValues(t, delta, st.ThisEpochPledgeCollateral)
   594  		require.EqualValues(t, expectedPower, st.ThisEpochQualityAdjPower)
   595  		require.EqualValues(t, expectedPower, st.ThisEpochRawBytePower)
   596  		actor.checkState(rt)
   597  	})
   598  
   599  	t.Run("event scheduled in null round called next round", func(t *testing.T) {
   600  		rt := builder.Build(t)
   601  		actor.constructAndVerify(rt)
   602  		actor.createMinerBasic(rt, owner, owner, miner1)
   603  		actor.createMinerBasic(rt, owner, owner, miner2)
   604  
   605  		//  0 - genesis
   606  		//  1 - block - registers events
   607  		//  2 - null  - has event
   608  		//  3 - null
   609  		//  4 - block - has event
   610  
   611  		rt.SetEpoch(1)
   612  		actor.enrollCronEvent(rt, miner1, 2, []byte{0x1, 0x3})
   613  		actor.enrollCronEvent(rt, miner2, 4, []byte{0x2, 0x3})
   614  
   615  		expectedRawBytePower := big.NewInt(0)
   616  		rt.SetEpoch(4)
   617  		rt.ExpectValidateCallerAddr(builtin.CronActorAddr)
   618  		rt.ExpectSend(miner1, builtin.MethodsMiner.OnDeferredCronEvent, builtin.CBORBytes([]byte{0x1, 0x3}), big.Zero(), nil, exitcode.Ok)
   619  		rt.ExpectSend(miner2, builtin.MethodsMiner.OnDeferredCronEvent, builtin.CBORBytes([]byte{0x2, 0x3}), big.Zero(), nil, exitcode.Ok)
   620  		rt.ExpectSend(builtin.RewardActorAddr, builtin.MethodsReward.UpdateNetworkKPI, &expectedRawBytePower, big.Zero(), nil, exitcode.Ok)
   621  		rt.SetCaller(builtin.CronActorAddr, builtin.CronActorCodeID)
   622  		rt.ExpectBatchVerifySeals(nil, nil, nil)
   623  
   624  		rt.Call(actor.Actor.OnEpochTickEnd, nil)
   625  		rt.Verify()
   626  		actor.checkState(rt)
   627  	})
   628  
   629  	t.Run("event scheduled in past called next round", func(t *testing.T) {
   630  		rt := builder.Build(t)
   631  		actor.constructAndVerify(rt)
   632  		actor.createMinerBasic(rt, owner, owner, miner1)
   633  
   634  		// run cron once to put it in a clean state at epoch 4
   635  		rt.SetEpoch(4)
   636  		expectedRawBytePower := big.NewInt(0)
   637  		rt.ExpectValidateCallerAddr(builtin.CronActorAddr)
   638  		rt.ExpectSend(builtin.RewardActorAddr, builtin.MethodsReward.UpdateNetworkKPI, &expectedRawBytePower, big.Zero(), nil, exitcode.Ok)
   639  		rt.SetCaller(builtin.CronActorAddr, builtin.CronActorCodeID)
   640  
   641  		rt.ExpectBatchVerifySeals(nil, nil, nil)
   642  
   643  		rt.Call(actor.Actor.OnEpochTickEnd, nil)
   644  		rt.Verify()
   645  
   646  		// enroll a cron task at epoch 2 (which is in the past)
   647  		actor.enrollCronEvent(rt, miner1, 2, []byte{0x1, 0x3})
   648  
   649  		// run cron again in the future
   650  		rt.SetEpoch(6)
   651  		rt.ExpectValidateCallerAddr(builtin.CronActorAddr)
   652  		rt.ExpectSend(miner1, builtin.MethodsMiner.OnDeferredCronEvent, builtin.CBORBytes([]byte{0x1, 0x3}), big.Zero(), nil, exitcode.Ok)
   653  		rt.ExpectSend(builtin.RewardActorAddr, builtin.MethodsReward.UpdateNetworkKPI, &expectedRawBytePower, big.Zero(), nil, exitcode.Ok)
   654  		rt.SetCaller(builtin.CronActorAddr, builtin.CronActorCodeID)
   655  		rt.ExpectBatchVerifySeals(nil, nil, nil)
   656  
   657  		rt.Call(actor.Actor.OnEpochTickEnd, nil)
   658  		rt.Verify()
   659  
   660  		// assert used cron events are cleaned up
   661  		st := getState(rt)
   662  
   663  		mmap, err := adt.AsMultimap(rt.AdtStore(), st.CronEventQueue, power.CronQueueHamtBitwidth, power.CronQueueAmtBitwidth)
   664  		require.NoError(t, err)
   665  
   666  		var ev power.CronEvent
   667  		err = mmap.ForEach(abi.IntKey(int64(2)), &ev, func(i int64) error {
   668  			t.Errorf("Unexpected bitfield at epoch %d", i)
   669  			return nil
   670  		})
   671  		require.NoError(t, err)
   672  		actor.checkState(rt)
   673  	})
   674  
   675  	t.Run("fails to enroll if epoch is negative", func(t *testing.T) {
   676  		rt := builder.Build(t)
   677  		actor.constructAndVerify(rt)
   678  
   679  		// enroll a cron task at epoch 2 (which is in the past)
   680  		rt.ExpectAbortContainsMessage(exitcode.ErrIllegalArgument, "epoch -2 cannot be less than zero", func() {
   681  			actor.enrollCronEvent(rt, miner1, -2, []byte{0x1, 0x3})
   682  		})
   683  	})
   684  
   685  	t.Run("skips invocation if miner has no claim", func(t *testing.T) {
   686  		rt := builder.Build(t)
   687  		actor.constructAndVerify(rt)
   688  
   689  		rt.SetEpoch(1)
   690  		actor.createMinerBasic(rt, owner, owner, miner1)
   691  		actor.createMinerBasic(rt, owner, owner, miner2)
   692  
   693  		actor.enrollCronEvent(rt, miner1, 2, []byte{})
   694  		actor.enrollCronEvent(rt, miner2, 2, []byte{})
   695  
   696  		// explicitly delete miner 1's claim
   697  		actor.deleteClaim(rt, miner1)
   698  
   699  		rt.SetEpoch(2)
   700  		rt.ExpectValidateCallerAddr(builtin.CronActorAddr)
   701  
   702  		// process batch verifies first
   703  		rt.ExpectBatchVerifySeals(nil, nil, nil)
   704  
   705  		// only expect second deferred cron event call
   706  		rt.ExpectSend(miner2, builtin.MethodsMiner.OnDeferredCronEvent, builtin.CBORBytes(nil), big.Zero(), nil, exitcode.Ok)
   707  
   708  		// Reward actor still invoked
   709  		expectedPower := big.NewInt(0)
   710  		rt.ExpectSend(builtin.RewardActorAddr, builtin.MethodsReward.UpdateNetworkKPI, &expectedPower, big.Zero(), nil, exitcode.Ok)
   711  		rt.SetCaller(builtin.CronActorAddr, builtin.CronActorCodeID)
   712  		rt.Call(actor.Actor.OnEpochTickEnd, nil)
   713  		rt.Verify()
   714  
   715  		// expect cron skip was logged
   716  		rt.ExpectLogsContain("skipping cron event for unknown miner t0101")
   717  		actor.checkState(rt)
   718  	})
   719  
   720  	t.Run("handles failed call", func(t *testing.T) {
   721  		rt := builder.Build(t)
   722  		actor.constructAndVerify(rt)
   723  
   724  		rt.SetEpoch(1)
   725  		actor.createMinerBasic(rt, owner, owner, miner1)
   726  		actor.createMinerBasic(rt, owner, owner, miner2)
   727  
   728  		actor.enrollCronEvent(rt, miner1, 2, []byte{})
   729  		actor.enrollCronEvent(rt, miner2, 2, []byte{})
   730  
   731  		rawPow, err := builtin.ConsensusMinerMinPower(abi.RegisteredPoStProof_StackedDrgWindow32GiBV1)
   732  		require.NoError(t, err)
   733  
   734  		qaPow := rawPow
   735  		actor.updateClaimedPower(rt, miner1, rawPow, qaPow)
   736  		actor.expectTotalPowerEager(rt, rawPow, qaPow)
   737  		actor.expectMinersAboveMinPower(rt, 1)
   738  
   739  		expectedPower := big.NewInt(0)
   740  		rt.SetEpoch(2)
   741  		rt.ExpectValidateCallerAddr(builtin.CronActorAddr)
   742  
   743  		// process batch verifies first
   744  		rt.ExpectBatchVerifySeals(nil, nil, nil)
   745  
   746  		// First send fails
   747  		rt.ExpectSend(miner1, builtin.MethodsMiner.OnDeferredCronEvent, builtin.CBORBytes(nil), big.Zero(), nil, exitcode.ErrIllegalState)
   748  
   749  		// Subsequent one still invoked
   750  		rt.ExpectSend(miner2, builtin.MethodsMiner.OnDeferredCronEvent, builtin.CBORBytes(nil), big.Zero(), nil, exitcode.Ok)
   751  		// Reward actor still invoked
   752  		rt.ExpectSend(builtin.RewardActorAddr, builtin.MethodsReward.UpdateNetworkKPI, &expectedPower, big.Zero(), nil, exitcode.Ok)
   753  		rt.SetCaller(builtin.CronActorAddr, builtin.CronActorCodeID)
   754  		rt.Call(actor.Actor.OnEpochTickEnd, nil)
   755  		rt.Verify()
   756  
   757  		// expect cron failure was logged
   758  		rt.ExpectLogsContain("OnDeferredCronEvent failed for miner")
   759  
   760  		// expect power stats to be decremented due to claim deletion
   761  		actor.expectTotalPowerEager(rt, big.Zero(), big.Zero())
   762  		actor.expectMinersAboveMinPower(rt, 0)
   763  
   764  		// miner's claim is removed
   765  		st := getState(rt)
   766  		_, found, err := st.GetClaim(rt.AdtStore(), miner1)
   767  		require.NoError(t, err)
   768  		assert.False(t, found)
   769  
   770  		// miner count has been reduced to 1
   771  		assert.Equal(t, int64(1), st.MinerCount)
   772  
   773  		// Next epoch, only the reward actor is invoked
   774  		rt.SetEpoch(3)
   775  		rt.ExpectValidateCallerAddr(builtin.CronActorAddr)
   776  		rt.ExpectSend(builtin.RewardActorAddr, builtin.MethodsReward.UpdateNetworkKPI, &expectedPower, big.Zero(), nil, exitcode.Ok)
   777  		rt.SetCaller(builtin.CronActorAddr, builtin.CronActorCodeID)
   778  		rt.ExpectBatchVerifySeals(nil, nil, nil)
   779  
   780  		rt.Call(actor.Actor.OnEpochTickEnd, nil)
   781  		rt.Verify()
   782  		actor.checkState(rt)
   783  	})
   784  }
   785  
   786  func TestSubmitPoRepForBulkVerify(t *testing.T) {
   787  	actor := newHarness(t)
   788  	miner := tutil.NewIDAddr(t, 101)
   789  	owner := tutil.NewIDAddr(t, 101)
   790  	builder := mock.NewBuilder(builtin.StoragePowerActorAddr).WithCaller(builtin.SystemActorAddr, builtin.SystemActorCodeID)
   791  
   792  	t.Run("registers porep and charges gas", func(t *testing.T) {
   793  		rt := builder.Build(t)
   794  		actor.constructAndVerify(rt)
   795  		actor.createMinerBasic(rt, owner, owner, miner)
   796  		commR := tutil.MakeCID("commR", &mineract.SealedCIDPrefix)
   797  		commD := tutil.MakeCID("commD", &market.PieceCIDPrefix)
   798  		sealInfo := &proof.SealVerifyInfo{
   799  			SealProof:   actor.sealProof,
   800  			SealedCID:   commR,
   801  			UnsealedCID: commD,
   802  		}
   803  		actor.submitPoRepForBulkVerify(rt, miner, sealInfo)
   804  		rt.ExpectGasCharged(power.GasOnSubmitVerifySeal)
   805  		st := getState(rt)
   806  		store := rt.AdtStore()
   807  		require.NotNil(t, st.ProofValidationBatch)
   808  		mmap, err := adt.AsMultimap(store, *st.ProofValidationBatch, builtin.DefaultHamtBitwidth, power.ProofValidationBatchAmtBitwidth)
   809  		require.NoError(t, err)
   810  		arr, found, err := mmap.Get(abi.AddrKey(miner))
   811  		require.NoError(t, err)
   812  		require.True(t, found)
   813  		assert.Equal(t, uint64(1), arr.Length())
   814  		var storedSealInfo proof.SealVerifyInfo
   815  		found, err = arr.Get(0, &storedSealInfo)
   816  		require.NoError(t, err)
   817  		require.True(t, found)
   818  		assert.Equal(t, commR, storedSealInfo.SealedCID)
   819  		actor.checkState(rt)
   820  	})
   821  
   822  	t.Run("aborts when too many poreps", func(t *testing.T) {
   823  		rt := builder.Build(t)
   824  		actor.constructAndVerify(rt)
   825  		actor.createMinerBasic(rt, owner, owner, miner)
   826  
   827  		sealInfo := func(i int) *proof.SealVerifyInfo {
   828  			var sealInfo proof.SealVerifyInfo
   829  			sealInfo.SealedCID = tutil.MakeCID(fmt.Sprintf("commR-%d", i), &mineract.SealedCIDPrefix)
   830  			sealInfo.UnsealedCID = tutil.MakeCID(fmt.Sprintf("commD-%d", i), &market.PieceCIDPrefix)
   831  			return &sealInfo
   832  		}
   833  
   834  		// Adding MaxMinerProveCommitsPerEpoch works without error
   835  		for i := 0; i < power.MaxMinerProveCommitsPerEpoch; i++ {
   836  			actor.submitPoRepForBulkVerify(rt, miner, sealInfo(i))
   837  		}
   838  
   839  		rt.ExpectAbort(power.ErrTooManyProveCommits, func() {
   840  			actor.submitPoRepForBulkVerify(rt, miner, sealInfo(power.MaxMinerProveCommitsPerEpoch))
   841  		})
   842  
   843  		// Gas only charged for successful submissions
   844  		rt.ExpectGasCharged(power.GasOnSubmitVerifySeal * power.MaxMinerProveCommitsPerEpoch)
   845  	})
   846  
   847  	t.Run("aborts when miner has no claim", func(t *testing.T) {
   848  		rt := builder.Build(t)
   849  		actor.constructAndVerify(rt)
   850  		actor.createMinerBasic(rt, owner, owner, miner)
   851  		commR := tutil.MakeCID("commR", &mineract.SealedCIDPrefix)
   852  		commD := tutil.MakeCID("commD", &market.PieceCIDPrefix)
   853  		sealInfo := &proof.SealVerifyInfo{
   854  			SealedCID:   commR,
   855  			UnsealedCID: commD,
   856  		}
   857  
   858  		// delete miner
   859  		actor.deleteClaim(rt, miner)
   860  
   861  		rt.ExpectAbortContainsMessage(exitcode.ErrForbidden, "unknown miner", func() {
   862  			actor.submitPoRepForBulkVerify(rt, miner, sealInfo)
   863  		})
   864  	})
   865  }
   866  
   867  func TestCronBatchProofVerifies(t *testing.T) {
   868  	sealInfo := func(i int) *proof.SealVerifyInfo {
   869  		var sealInfo proof.SealVerifyInfo
   870  		sealInfo.SealedCID = tutil.MakeCID(fmt.Sprintf("commR-%d", i), &mineract.SealedCIDPrefix)
   871  		sealInfo.UnsealedCID = tutil.MakeCID(fmt.Sprintf("commD-%d", i), &market.PieceCIDPrefix)
   872  		sealInfo.SectorID = abi.SectorID{Number: abi.SectorNumber(i)}
   873  		return &sealInfo
   874  	}
   875  
   876  	miner1 := tutil.NewIDAddr(t, 101)
   877  	owner := tutil.NewIDAddr(t, 102)
   878  	info := sealInfo(0)
   879  	info1 := sealInfo(1)
   880  	info2 := sealInfo(2)
   881  	info3 := sealInfo(3)
   882  	info4 := sealInfo(101)
   883  	info5 := sealInfo(200)
   884  	info6 := sealInfo(201)
   885  	info7 := sealInfo(300)
   886  	info8 := sealInfo(301)
   887  
   888  	t.Run("success with one miner and one confirmed sector", func(t *testing.T) {
   889  		rt, ac := basicPowerSetup(t)
   890  		ac.createMinerBasic(rt, owner, owner, miner1)
   891  
   892  		ac.submitPoRepForBulkVerify(rt, miner1, info)
   893  
   894  		infos := map[addr.Address][]proof.SealVerifyInfo{miner1: {*info}}
   895  		cs := []confirmedSectorSend{{miner1, []abi.SectorNumber{info.Number}}}
   896  
   897  		ac.onEpochTickEnd(rt, 0, big.Zero(), cs, infos)
   898  		ac.checkState(rt)
   899  	})
   900  
   901  	t.Run("success with one miner and multiple confirmed sectors", func(t *testing.T) {
   902  		rt, ac := basicPowerSetup(t)
   903  		ac.createMinerBasic(rt, owner, owner, miner1)
   904  
   905  		ac.submitPoRepForBulkVerify(rt, miner1, info1)
   906  		ac.submitPoRepForBulkVerify(rt, miner1, info2)
   907  		ac.submitPoRepForBulkVerify(rt, miner1, info3)
   908  
   909  		infos := map[addr.Address][]proof.SealVerifyInfo{miner1: {*info1, *info2, *info3}}
   910  		cs := []confirmedSectorSend{{miner1, []abi.SectorNumber{info1.Number, info2.Number, info3.Number}}}
   911  
   912  		ac.onEpochTickEnd(rt, 0, big.Zero(), cs, infos)
   913  		ac.checkState(rt)
   914  	})
   915  
   916  	t.Run("duplicate sector numbers are ignored for a miner", func(t *testing.T) {
   917  		rt, ac := basicPowerSetup(t)
   918  		ac.createMinerBasic(rt, owner, owner, miner1)
   919  
   920  		ac.submitPoRepForBulkVerify(rt, miner1, info1)
   921  		ac.submitPoRepForBulkVerify(rt, miner1, info1)
   922  		ac.submitPoRepForBulkVerify(rt, miner1, info2)
   923  
   924  		// duplicates will be sent to the batch verify call
   925  		infos := map[addr.Address][]proof.SealVerifyInfo{miner1: {*info1, *info1, *info2}}
   926  
   927  		// however, duplicates will not be sent to the miner as confirmed
   928  		cs := []confirmedSectorSend{{miner1, []abi.SectorNumber{info1.Number, info2.Number}}}
   929  
   930  		ac.onEpochTickEnd(rt, 0, big.Zero(), cs, infos)
   931  		ac.checkState(rt)
   932  	})
   933  
   934  	t.Run("skips verify if miner has no claim", func(t *testing.T) {
   935  		rt, ac := basicPowerSetup(t)
   936  		ac.createMinerBasic(rt, owner, owner, miner1)
   937  
   938  		ac.submitPoRepForBulkVerify(rt, miner1, info1)
   939  
   940  		// now explicitly delete miner's claim
   941  		ac.deleteClaim(rt, miner1)
   942  
   943  		// all infos will be skipped
   944  		infos := map[addr.Address][]proof.SealVerifyInfo{}
   945  
   946  		// nothing will be sent to miner
   947  		cs := []confirmedSectorSend{}
   948  
   949  		ac.onEpochTickEnd(rt, 0, big.Zero(), cs, infos)
   950  
   951  		// expect cron failure was logged
   952  		rt.ExpectLogsContain("skipping batch verifies for unknown miner t0101")
   953  		ac.checkState(rt)
   954  	})
   955  
   956  	t.Run("success with multiple miners and multiple confirmed sectors and assert expected power", func(t *testing.T) {
   957  		miner2 := tutil.NewIDAddr(t, 102)
   958  		miner3 := tutil.NewIDAddr(t, 103)
   959  		miner4 := tutil.NewIDAddr(t, 104)
   960  
   961  		rt, ac := basicPowerSetup(t)
   962  		ac.createMinerBasic(rt, owner, owner, miner1)
   963  		ac.createMinerBasic(rt, owner, owner, miner2)
   964  		ac.createMinerBasic(rt, owner, owner, miner3)
   965  		ac.createMinerBasic(rt, owner, owner, miner4)
   966  
   967  		ac.submitPoRepForBulkVerify(rt, miner1, info1)
   968  		ac.submitPoRepForBulkVerify(rt, miner1, info2)
   969  
   970  		ac.submitPoRepForBulkVerify(rt, miner2, info3)
   971  		ac.submitPoRepForBulkVerify(rt, miner2, info4)
   972  
   973  		ac.submitPoRepForBulkVerify(rt, miner3, info5)
   974  		ac.submitPoRepForBulkVerify(rt, miner3, info6)
   975  
   976  		ac.submitPoRepForBulkVerify(rt, miner4, info7)
   977  		ac.submitPoRepForBulkVerify(rt, miner4, info8)
   978  
   979  		// TODO Because read order of keys in a multi-map is not as per insertion order,
   980  		// we have to move around the expected sends
   981  		cs := []confirmedSectorSend{{miner1, []abi.SectorNumber{info1.Number, info2.Number}},
   982  			{miner3, []abi.SectorNumber{info5.Number, info6.Number}},
   983  			{miner4, []abi.SectorNumber{info7.Number, info8.Number}},
   984  			{miner2, []abi.SectorNumber{info3.Number, info4.Number}}}
   985  
   986  		infos := map[addr.Address][]proof.SealVerifyInfo{miner1: {*info1, *info2},
   987  			miner2: {*info3, *info4},
   988  			miner3: {*info5, *info6},
   989  			miner4: {*info7, *info8}}
   990  
   991  		ac.onEpochTickEnd(rt, 0, big.Zero(), cs, infos)
   992  		ac.checkState(rt)
   993  	})
   994  
   995  	t.Run("success when no confirmed sector", func(t *testing.T) {
   996  		rt, ac := basicPowerSetup(t)
   997  		ac.onEpochTickEnd(rt, 0, big.Zero(), nil, nil)
   998  		ac.checkState(rt)
   999  	})
  1000  
  1001  	t.Run("verification for one sector fails but others succeeds for a miner", func(t *testing.T) {
  1002  		rt, ac := basicPowerSetup(t)
  1003  		ac.createMinerBasic(rt, owner, owner, miner1)
  1004  
  1005  		ac.submitPoRepForBulkVerify(rt, miner1, info1)
  1006  		ac.submitPoRepForBulkVerify(rt, miner1, info2)
  1007  		ac.submitPoRepForBulkVerify(rt, miner1, info3)
  1008  
  1009  		infos := map[addr.Address][]proof.SealVerifyInfo{miner1: {*info1, *info2, *info3}}
  1010  
  1011  		res := map[addr.Address][]bool{
  1012  			miner1: {true, false, true},
  1013  		}
  1014  
  1015  		// send will only be for the first and third sector as the middle sector will fail verification
  1016  		cs := []confirmedSectorSend{{miner1, []abi.SectorNumber{info1.Number, info3.Number}}}
  1017  
  1018  		// expect sends for confirmed sectors
  1019  		for _, cs := range cs {
  1020  			param := &builtin.ConfirmSectorProofsParams{Sectors: cs.sectorNums}
  1021  			rt.ExpectSend(cs.miner, builtin.MethodsMiner.ConfirmSectorProofsValid, param, abi.NewTokenAmount(0), nil, 0)
  1022  		}
  1023  
  1024  		rt.ExpectBatchVerifySeals(infos, res, nil)
  1025  		power := big.Zero()
  1026  		//expect power sends to reward actor
  1027  		rt.ExpectSend(builtin.RewardActorAddr, builtin.MethodsReward.UpdateNetworkKPI, &power, abi.NewTokenAmount(0), nil, 0)
  1028  		rt.ExpectValidateCallerAddr(builtin.CronActorAddr)
  1029  
  1030  		rt.SetEpoch(0)
  1031  		rt.SetCaller(builtin.CronActorAddr, builtin.CronActorCodeID)
  1032  
  1033  		rt.Call(ac.OnEpochTickEnd, nil)
  1034  		rt.Verify()
  1035  		ac.checkState(rt)
  1036  	})
  1037  
  1038  	t.Run("fails if batch verify seals fails", func(t *testing.T) {
  1039  		rt, ac := basicPowerSetup(t)
  1040  		ac.createMinerBasic(rt, owner, owner, miner1)
  1041  
  1042  		ac.submitPoRepForBulkVerify(rt, miner1, info1)
  1043  		ac.submitPoRepForBulkVerify(rt, miner1, info2)
  1044  		ac.submitPoRepForBulkVerify(rt, miner1, info3)
  1045  
  1046  		infos := map[addr.Address][]proof.SealVerifyInfo{miner1: {*info1, *info2, *info3}}
  1047  
  1048  		rt.ExpectBatchVerifySeals(infos, batchVerifyDefaultOutput(infos), fmt.Errorf("fail"))
  1049  		rt.ExpectValidateCallerAddr(builtin.CronActorAddr)
  1050  
  1051  		rt.SetEpoch(abi.ChainEpoch(0))
  1052  		rt.SetCaller(builtin.CronActorAddr, builtin.CronActorCodeID)
  1053  
  1054  		rt.ExpectAbort(exitcode.ErrIllegalState, func() {
  1055  			rt.Call(ac.Actor.OnEpochTickEnd, nil)
  1056  		})
  1057  		rt.Verify()
  1058  	})
  1059  }
  1060  
  1061  //
  1062  // Misc. Utility Functions
  1063  //
  1064  
  1065  type key string
  1066  
  1067  func asKey(in string) abi.Keyer {
  1068  	return key(in)
  1069  }
  1070  
  1071  func verifyEmptyMap(t testing.TB, rt *mock.Runtime, cid cid.Cid) {
  1072  	mapChecked, err := adt.AsMap(adt.AsStore(rt), cid, builtin.DefaultHamtBitwidth)
  1073  	assert.NoError(t, err)
  1074  	keys, err := mapChecked.CollectKeys()
  1075  	require.NoError(t, err)
  1076  	assert.Empty(t, keys)
  1077  }
  1078  
  1079  type spActorHarness struct {
  1080  	power.Actor
  1081  	t               *testing.T
  1082  	minerSeq        int
  1083  	sealProof       abi.RegisteredSealProof
  1084  	windowPoStProof abi.RegisteredPoStProof
  1085  }
  1086  
  1087  func newHarness(t *testing.T) *spActorHarness {
  1088  	return &spActorHarness{
  1089  		Actor:           power.Actor{},
  1090  		t:               t,
  1091  		sealProof:       abi.RegisteredSealProof_StackedDrg32GiBV1_1,
  1092  		windowPoStProof: abi.RegisteredPoStProof_StackedDrgWindow32GiBV1,
  1093  	}
  1094  }
  1095  
  1096  func (h *spActorHarness) constructAndVerify(rt *mock.Runtime) {
  1097  	rt.ExpectValidateCallerAddr(builtin.SystemActorAddr)
  1098  	ret := rt.Call(h.Actor.Constructor, nil)
  1099  	assert.Nil(h.t, ret)
  1100  	rt.Verify()
  1101  
  1102  	var st power.State
  1103  
  1104  	rt.GetState(&st)
  1105  	assert.Equal(h.t, abi.NewStoragePower(0), st.TotalRawBytePower)
  1106  	assert.Equal(h.t, abi.NewStoragePower(0), st.TotalBytesCommitted)
  1107  	assert.Equal(h.t, abi.NewStoragePower(0), st.TotalQualityAdjPower)
  1108  	assert.Equal(h.t, abi.NewStoragePower(0), st.TotalQABytesCommitted)
  1109  	assert.Equal(h.t, abi.NewTokenAmount(0), st.TotalPledgeCollateral)
  1110  	assert.Equal(h.t, abi.NewStoragePower(0), st.ThisEpochRawBytePower)
  1111  	assert.Equal(h.t, abi.NewStoragePower(0), st.ThisEpochQualityAdjPower)
  1112  	assert.Equal(h.t, abi.NewTokenAmount(0), st.ThisEpochPledgeCollateral)
  1113  	assert.Equal(h.t, abi.ChainEpoch(0), st.FirstCronEpoch)
  1114  	assert.Equal(h.t, int64(0), st.MinerCount)
  1115  	assert.Equal(h.t, int64(0), st.MinerAboveMinPowerCount)
  1116  
  1117  	verifyEmptyMap(h.t, rt, st.Claims)
  1118  	verifyEmptyMap(h.t, rt, st.CronEventQueue)
  1119  }
  1120  
  1121  type confirmedSectorSend struct {
  1122  	miner      addr.Address
  1123  	sectorNums []abi.SectorNumber
  1124  }
  1125  
  1126  func (h *spActorHarness) onEpochTickEnd(rt *mock.Runtime, currEpoch abi.ChainEpoch, expectedRawPower abi.StoragePower,
  1127  	confirmedSectors []confirmedSectorSend, infos map[addr.Address][]proof.SealVerifyInfo) {
  1128  
  1129  	// expect sends for confirmed sectors
  1130  	for _, cs := range confirmedSectors {
  1131  		param := &builtin.ConfirmSectorProofsParams{Sectors: cs.sectorNums}
  1132  		rt.ExpectSend(cs.miner, builtin.MethodsMiner.ConfirmSectorProofsValid, param, abi.NewTokenAmount(0), nil, 0)
  1133  	}
  1134  
  1135  	rt.ExpectBatchVerifySeals(infos, batchVerifyDefaultOutput(infos), nil)
  1136  	//expect power sends to reward actor
  1137  	rt.ExpectSend(builtin.RewardActorAddr, builtin.MethodsReward.UpdateNetworkKPI, &expectedRawPower, abi.NewTokenAmount(0), nil, 0)
  1138  	rt.ExpectValidateCallerAddr(builtin.CronActorAddr)
  1139  
  1140  	rt.SetEpoch(currEpoch)
  1141  	rt.SetCaller(builtin.CronActorAddr, builtin.CronActorCodeID)
  1142  
  1143  	rt.Call(h.Actor.OnEpochTickEnd, nil)
  1144  	rt.Verify()
  1145  
  1146  	st := getState(rt)
  1147  	require.Nil(h.t, st.ProofValidationBatch)
  1148  }
  1149  
  1150  func (h *spActorHarness) createMiner(rt *mock.Runtime, owner, worker, miner, robust addr.Address, peer abi.PeerID,
  1151  	multiaddrs []abi.Multiaddrs, windowPoStProofType abi.RegisteredPoStProof, value abi.TokenAmount) {
  1152  
  1153  	st := getState(rt)
  1154  	prevMinerCount := st.MinerCount
  1155  
  1156  	createMinerParams := &power.CreateMinerParams{
  1157  		Owner:               owner,
  1158  		Worker:              worker,
  1159  		WindowPoStProofType: windowPoStProofType,
  1160  		Peer:                peer,
  1161  		Multiaddrs:          multiaddrs,
  1162  	}
  1163  
  1164  	// owner send CreateMiner to Actor
  1165  	rt.SetCaller(owner, builtin.AccountActorCodeID)
  1166  	rt.SetReceived(value)
  1167  	rt.SetBalance(value)
  1168  	rt.ExpectValidateCallerType(builtin.AccountActorCodeID, builtin.MultisigActorCodeID)
  1169  
  1170  	createMinerRet := &power.CreateMinerReturn{
  1171  		IDAddress:     miner,  // miner actor id address
  1172  		RobustAddress: robust, // should be long miner actor address
  1173  	}
  1174  
  1175  	msgParams := &initact.ExecParams{
  1176  		CodeCID:           builtin.StorageMinerActorCodeID,
  1177  		ConstructorParams: initCreateMinerBytes(h.t, owner, worker, peer, multiaddrs, windowPoStProofType),
  1178  	}
  1179  	rt.ExpectSend(builtin.InitActorAddr, builtin.MethodsInit.Exec, msgParams, value, createMinerRet, 0)
  1180  	rt.Call(h.Actor.CreateMiner, createMinerParams)
  1181  	rt.Verify()
  1182  
  1183  	cl := h.getClaim(rt, miner)
  1184  	require.True(h.t, cl.RawBytePower.IsZero())
  1185  	require.True(h.t, cl.QualityAdjPower.IsZero())
  1186  	require.EqualValues(h.t, prevMinerCount+1, getState(rt).MinerCount)
  1187  
  1188  }
  1189  
  1190  func (h *spActorHarness) getClaim(rt *mock.Runtime, a addr.Address) *power.Claim {
  1191  	var st power.State
  1192  	rt.GetState(&st)
  1193  
  1194  	claims, err := adt.AsMap(adt.AsStore(rt), st.Claims, builtin.DefaultHamtBitwidth)
  1195  	require.NoError(h.t, err)
  1196  
  1197  	var out power.Claim
  1198  	found, err := claims.Get(abi.AddrKey(a), &out)
  1199  	require.NoError(h.t, err)
  1200  	require.True(h.t, found)
  1201  
  1202  	return &out
  1203  }
  1204  
  1205  func (h *spActorHarness) deleteClaim(rt *mock.Runtime, a addr.Address) {
  1206  	st := getState(rt)
  1207  	claims, err := adt.AsMap(adt.AsStore(rt), st.Claims, builtin.DefaultHamtBitwidth)
  1208  	require.NoError(h.t, err)
  1209  	err = claims.Delete(abi.AddrKey(a))
  1210  	require.NoError(h.t, err)
  1211  	st.Claims, err = claims.Root()
  1212  	require.NoError(h.t, err)
  1213  	rt.ReplaceState(st)
  1214  }
  1215  
  1216  func (h *spActorHarness) getEnrolledCronTicks(rt *mock.Runtime, epoch abi.ChainEpoch) []power.CronEvent {
  1217  	var st power.State
  1218  	rt.GetState(&st)
  1219  
  1220  	events, err := adt.AsMultimap(adt.AsStore(rt), st.CronEventQueue, power.CronQueueHamtBitwidth, power.CronQueueAmtBitwidth)
  1221  	builtin.RequireNoErr(rt, err, exitcode.ErrIllegalState, "failed to load cron events")
  1222  
  1223  	evts, found, err := events.Get(abi.IntKey(int64(epoch)))
  1224  	require.NoError(h.t, err)
  1225  	require.True(h.t, found)
  1226  
  1227  	cronEvt := &power.CronEvent{}
  1228  	var cronEvents []power.CronEvent
  1229  	err = evts.ForEach(cronEvt, func(i int64) error {
  1230  		cronEvents = append(cronEvents, *cronEvt)
  1231  		return nil
  1232  	})
  1233  	require.NoError(h.t, err)
  1234  
  1235  	return cronEvents
  1236  }
  1237  
  1238  func basicPowerSetup(t *testing.T) (*mock.Runtime, *spActorHarness) {
  1239  	builder := mock.NewBuilder(builtin.StoragePowerActorAddr).WithCaller(builtin.SystemActorAddr, builtin.SystemActorCodeID)
  1240  	rt := builder.Build(t)
  1241  	h := newHarness(t)
  1242  	h.constructAndVerify(rt)
  1243  
  1244  	return rt, h
  1245  }
  1246  
  1247  func (h *spActorHarness) createMinerBasic(rt *mock.Runtime, owner, worker, miner addr.Address) {
  1248  	label := strconv.Itoa(h.minerSeq)
  1249  	actrAddr := tutil.NewActorAddr(h.t, label)
  1250  	h.minerSeq += 1
  1251  	h.createMiner(rt, owner, worker, miner, actrAddr, abi.PeerID(label), nil, h.windowPoStProof, big.Zero())
  1252  }
  1253  
  1254  func (h *spActorHarness) updateClaimedPower(rt *mock.Runtime, miner addr.Address, rawDelta, qaDelta abi.StoragePower) {
  1255  	prevCl := h.getClaim(rt, miner)
  1256  
  1257  	params := power.UpdateClaimedPowerParams{
  1258  		RawByteDelta:         rawDelta,
  1259  		QualityAdjustedDelta: qaDelta,
  1260  	}
  1261  	rt.SetCaller(miner, builtin.StorageMinerActorCodeID)
  1262  	rt.ExpectValidateCallerType(builtin.StorageMinerActorCodeID)
  1263  	rt.Call(h.UpdateClaimedPower, &params)
  1264  	rt.Verify()
  1265  
  1266  	cl := h.getClaim(rt, miner)
  1267  	expectedRaw := big.Add(prevCl.RawBytePower, rawDelta)
  1268  	expectedAdjusted := big.Add(prevCl.QualityAdjPower, qaDelta)
  1269  	if expectedRaw.IsZero() {
  1270  		require.True(h.t, cl.RawBytePower.IsZero())
  1271  	} else {
  1272  		require.EqualValues(h.t, big.Add(prevCl.RawBytePower, rawDelta), cl.RawBytePower)
  1273  	}
  1274  
  1275  	if expectedAdjusted.IsZero() {
  1276  		require.True(h.t, cl.QualityAdjPower.IsZero())
  1277  	} else {
  1278  		require.EqualValues(h.t, big.Add(prevCl.QualityAdjPower, qaDelta), cl.QualityAdjPower)
  1279  	}
  1280  }
  1281  
  1282  func (h *spActorHarness) updatePledgeTotal(rt *mock.Runtime, miner addr.Address, delta abi.TokenAmount) {
  1283  	st := getState(rt)
  1284  	prev := st.TotalPledgeCollateral
  1285  
  1286  	rt.SetCaller(miner, builtin.StorageMinerActorCodeID)
  1287  	rt.ExpectValidateCallerType(builtin.StorageMinerActorCodeID)
  1288  	rt.Call(h.UpdatePledgeTotal, &delta)
  1289  	rt.Verify()
  1290  
  1291  	st = getState(rt)
  1292  	new := st.TotalPledgeCollateral
  1293  	require.EqualValues(h.t, big.Add(prev, delta), new)
  1294  }
  1295  
  1296  func (h *spActorHarness) currentPowerTotal(rt *mock.Runtime) *power.CurrentTotalPowerReturn {
  1297  	rt.ExpectValidateCallerAny()
  1298  	ret := rt.Call(h.CurrentTotalPower, nil).(*power.CurrentTotalPowerReturn)
  1299  	rt.Verify()
  1300  	return ret
  1301  }
  1302  
  1303  func (h *spActorHarness) enrollCronEvent(rt *mock.Runtime, miner addr.Address, epoch abi.ChainEpoch, payload []byte) {
  1304  	rt.ExpectValidateCallerType(builtin.StorageMinerActorCodeID)
  1305  	rt.SetCaller(miner, builtin.StorageMinerActorCodeID)
  1306  	rt.Call(h.Actor.EnrollCronEvent, &power.EnrollCronEventParams{
  1307  		EventEpoch: epoch,
  1308  		Payload:    payload,
  1309  	})
  1310  	rt.Verify()
  1311  
  1312  }
  1313  
  1314  func (h *spActorHarness) submitPoRepForBulkVerify(rt *mock.Runtime, minerAddr addr.Address, sealInfo *proof.SealVerifyInfo) {
  1315  	rt.ExpectValidateCallerType(builtin.StorageMinerActorCodeID)
  1316  	rt.SetCaller(minerAddr, builtin.StorageMinerActorCodeID)
  1317  	rt.Call(h.Actor.SubmitPoRepForBulkVerify, sealInfo)
  1318  	rt.Verify()
  1319  }
  1320  
  1321  func (h *spActorHarness) expectTotalPowerEager(rt *mock.Runtime, expectedRaw, expectedQA abi.StoragePower) {
  1322  	st := getState(rt)
  1323  
  1324  	rawBytePower, qualityAdjPower := power.CurrentTotalPower(st)
  1325  	assert.Equal(h.t, expectedRaw, rawBytePower)
  1326  	assert.Equal(h.t, expectedQA, qualityAdjPower)
  1327  }
  1328  
  1329  func (h *spActorHarness) expectMinersAboveMinPower(rt *mock.Runtime, count int64) {
  1330  	st := getState(rt)
  1331  	assert.Equal(h.t, count, st.MinerAboveMinPowerCount)
  1332  }
  1333  
  1334  func (h *spActorHarness) expectTotalPledgeEager(rt *mock.Runtime, expectedPledge abi.TokenAmount) {
  1335  	st := getState(rt)
  1336  	assert.Equal(h.t, expectedPledge, st.TotalPledgeCollateral)
  1337  }
  1338  
  1339  func (h *spActorHarness) checkState(rt *mock.Runtime) {
  1340  	st := getState(rt)
  1341  	_, msgs := power.CheckStateInvariants(st, rt.AdtStore())
  1342  	assert.True(h.t, msgs.IsEmpty(), strings.Join(msgs.Messages(), "\n"))
  1343  }
  1344  
  1345  func initCreateMinerBytes(t testing.TB, owner, worker addr.Address, peer abi.PeerID, multiaddrs []abi.Multiaddrs, windowPoStProofType abi.RegisteredPoStProof) []byte {
  1346  	params := &power.MinerConstructorParams{
  1347  		OwnerAddr:           owner,
  1348  		WorkerAddr:          worker,
  1349  		WindowPoStProofType: windowPoStProofType,
  1350  		PeerId:              peer,
  1351  		Multiaddrs:          multiaddrs,
  1352  	}
  1353  
  1354  	buf := new(bytes.Buffer)
  1355  	require.NoError(t, params.MarshalCBOR(buf))
  1356  	return buf.Bytes()
  1357  }
  1358  
  1359  func (s key) Key() string {
  1360  	return string(s)
  1361  }
  1362  
  1363  func getState(rt *mock.Runtime) *power.State {
  1364  	var st power.State
  1365  	rt.GetState(&st)
  1366  	return &st
  1367  }
  1368  
  1369  func batchVerifyDefaultOutput(vis map[addr.Address][]proof.SealVerifyInfo) map[addr.Address][]bool {
  1370  	out := make(map[addr.Address][]bool)
  1371  	for k, v := range vis { //nolint:nomaprange
  1372  		validations := make([]bool, len(v))
  1373  		for i := range validations {
  1374  			validations[i] = true
  1375  		}
  1376  		out[k] = validations
  1377  	}
  1378  	return out
  1379  }