github.com/filecoin-project/specs-actors/v4@v4.0.2/actors/test/cron_catches_expiries_scenario_test.go (about)

     1  package test_test
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/filecoin-project/go-bitfield"
     8  	"github.com/filecoin-project/go-state-types/abi"
     9  	"github.com/filecoin-project/go-state-types/big"
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  
    13  	"github.com/filecoin-project/specs-actors/v4/actors/builtin"
    14  	"github.com/filecoin-project/specs-actors/v4/actors/builtin/miner"
    15  	"github.com/filecoin-project/specs-actors/v4/actors/builtin/power"
    16  	"github.com/filecoin-project/specs-actors/v4/actors/runtime/proof"
    17  	"github.com/filecoin-project/specs-actors/v4/support/ipld"
    18  	tutil "github.com/filecoin-project/specs-actors/v4/support/testing"
    19  	vm "github.com/filecoin-project/specs-actors/v4/support/vm"
    20  )
    21  
    22  var fakeChainRandomness = []byte("not really random")
    23  
    24  func TestCronCatchedCCExpirationsAtDeadlineBoundary(t *testing.T) {
    25  	ctx := context.Background()
    26  	v := vm.NewVMWithSingletons(ctx, t, ipld.NewBlockStoreInMemory())
    27  	addrs := vm.CreateAccounts(ctx, t, v, 2, big.Mul(big.NewInt(10_000), vm.FIL), 93837778)
    28  	worker, unverifiedClient := addrs[0], addrs[1]
    29  
    30  	minerBalance := big.Mul(big.NewInt(1_000), vm.FIL)
    31  	sectorNumber := abi.SectorNumber(100)
    32  	sealedCid := tutil.MakeCID("100", &miner.SealedCIDPrefix)
    33  	sealProof := abi.RegisteredSealProof_StackedDrg32GiBV1_1
    34  
    35  	// create miner
    36  	params := power.CreateMinerParams{
    37  		Owner:                worker,
    38  		Worker:               worker,
    39  		WindowPoStProofType:  abi.RegisteredPoStProof_StackedDrgWindow32GiBV1,
    40  		Peer:                 abi.PeerID("not really a peer id"),
    41  	}
    42  	ret := vm.ApplyOk(t, v, worker, builtin.StoragePowerActorAddr, minerBalance, builtin.MethodsPower.CreateMiner, &params)
    43  
    44  	minerAddrs, ok := ret.(*power.CreateMinerReturn)
    45  	require.True(t, ok)
    46  
    47  	// precommit sector
    48  	preCommitParams := miner.PreCommitSectorParams{
    49  		SealProof:     sealProof,
    50  		SectorNumber:  sectorNumber,
    51  		SealedCID:     sealedCid,
    52  		SealRandEpoch: v.GetEpoch() - 1,
    53  		DealIDs:       nil,
    54  		Expiration:    v.GetEpoch() + 200*builtin.EpochsInDay,
    55  	}
    56  	vm.ApplyOk(t, v, addrs[0], minerAddrs.RobustAddress, big.Zero(), builtin.MethodsMiner.PreCommitSector, &preCommitParams)
    57  
    58  	// advance time to max seal duration
    59  	proveTime := v.GetEpoch() + miner.PreCommitChallengeDelay + 1
    60  	v, _ = vm.AdvanceByDeadlineTillEpoch(t, v, minerAddrs.IDAddress, proveTime)
    61  
    62  	// Prove commit sector after max seal duration
    63  	v, err := v.WithEpoch(proveTime)
    64  	require.NoError(t, err)
    65  	proveCommitParams := miner.ProveCommitSectorParams{
    66  		SectorNumber: sectorNumber,
    67  	}
    68  	vm.ApplyOk(t, v, worker, minerAddrs.RobustAddress, big.Zero(), builtin.MethodsMiner.ProveCommitSector, &proveCommitParams)
    69  
    70  	// In the same epoch, trigger cron to validate prove commit
    71  	vm.ApplyOk(t, v, builtin.SystemActorAddr, builtin.CronActorAddr, big.Zero(), builtin.MethodsCron.EpochTick, nil)
    72  
    73  	// advance to proving period and submit post
    74  	dlInfo, pIdx, v := vm.AdvanceTillProvingDeadline(t, v, minerAddrs.IDAddress, sectorNumber)
    75  
    76  	submitParams := miner.SubmitWindowedPoStParams{
    77  		Deadline: dlInfo.Index,
    78  		Partitions: []miner.PoStPartition{{
    79  			Index:   pIdx,
    80  			Skipped: bitfield.New(),
    81  		}},
    82  		Proofs: []proof.PoStProof{{
    83  			PoStProof: abi.RegisteredPoStProof_StackedDrgWindow32GiBV1,
    84  		}},
    85  		ChainCommitEpoch: dlInfo.Challenge,
    86  		ChainCommitRand:  fakeChainRandomness,
    87  	}
    88  
    89  	vm.ApplyOk(t, v, addrs[0], minerAddrs.RobustAddress, big.Zero(), builtin.MethodsMiner.SubmitWindowedPoSt, &submitParams)
    90  
    91  	// add market collateral for client and miner
    92  	collateral := big.Mul(big.NewInt(3), vm.FIL)
    93  	vm.ApplyOk(t, v, unverifiedClient, builtin.StorageMarketActorAddr, collateral, builtin.MethodsMarket.AddBalance, &unverifiedClient)
    94  	collateral = big.Mul(big.NewInt(64), vm.FIL)
    95  	vm.ApplyOk(t, v, worker, builtin.StorageMarketActorAddr, collateral, builtin.MethodsMarket.AddBalance, &minerAddrs.IDAddress)
    96  
    97  	// create a deal required by upgrade sector
    98  	dealIDs := []abi.DealID{}
    99  	dealStart := v.GetEpoch() + miner.MaxProveCommitDuration[sealProof]
   100  	deals := publishDeal(t, v, worker, unverifiedClient, minerAddrs.IDAddress, "deal1", 1<<30, false, dealStart, 181*builtin.EpochsInDay)
   101  	dealIDs = append(dealIDs, deals.IDs...)
   102  
   103  	// precommit capacity upgrade sector with deals
   104  	upgradeSectorNumber := abi.SectorNumber(101)
   105  	upgradeSealedCid := tutil.MakeCID("101", &miner.SealedCIDPrefix)
   106  	preCommitParams = miner.PreCommitSectorParams{
   107  		SealProof:              sealProof,
   108  		SectorNumber:           upgradeSectorNumber,
   109  		SealedCID:              upgradeSealedCid,
   110  		SealRandEpoch:          v.GetEpoch() - 1,
   111  		DealIDs:                dealIDs,
   112  		Expiration:             v.GetEpoch() + 220*builtin.EpochsInDay,
   113  		ReplaceCapacity:        true,
   114  		ReplaceSectorDeadline:  dlInfo.Index,
   115  		ReplaceSectorPartition: pIdx,
   116  		ReplaceSectorNumber:    sectorNumber,
   117  	}
   118  	vm.ApplyOk(t, v, addrs[0], minerAddrs.RobustAddress, big.Zero(), builtin.MethodsMiner.PreCommitSector, &preCommitParams)
   119  
   120  	// Advance to beginning of the valid prove-commit window, then advance to proving deadline of original sector.
   121  	// This should allow us to prove commit the upgrade on the last epoch of the original sector's proving period.
   122  	proveTime = v.GetEpoch() + miner.PreCommitChallengeDelay + 1
   123  	v, _ = vm.AdvanceByDeadlineTillEpoch(t, v, minerAddrs.IDAddress, proveTime)
   124  	dlInfo, _, v = vm.AdvanceTillProvingDeadline(t, v, minerAddrs.IDAddress, sectorNumber)
   125  
   126  	// prove original sector so it won't be faulted
   127  	submitParams.ChainCommitEpoch = dlInfo.Challenge
   128  	vm.ApplyOk(t, v, addrs[0], minerAddrs.RobustAddress, big.Zero(), builtin.MethodsMiner.SubmitWindowedPoSt, &submitParams)
   129  
   130  	// one epoch before deadline close (i.e. Last) is where we might see a problem with cron scheduling of expirations
   131  	v, err = v.WithEpoch(dlInfo.Last())
   132  	require.NoError(t, err)
   133  
   134  	// miner still has power for old sector
   135  	sectorPower := vm.PowerForMinerSector(t, v, minerAddrs.IDAddress, sectorNumber)
   136  	minerPower := vm.MinerPower(t, v, minerAddrs.IDAddress)
   137  	assert.Equal(t, sectorPower.Raw, minerPower.Raw)
   138  	assert.Equal(t, sectorPower.QA, minerPower.QA)
   139  
   140  	// Prove commit sector after max seal duration
   141  	proveCommitParams = miner.ProveCommitSectorParams{
   142  		SectorNumber: upgradeSectorNumber,
   143  	}
   144  	vm.ApplyOk(t, v, worker, minerAddrs.RobustAddress, big.Zero(), builtin.MethodsMiner.ProveCommitSector, &proveCommitParams)
   145  
   146  	// In the same epoch, trigger cron to validate prove commit
   147  	// Replaced sector should be terminated at end of deadline it was replace in, so it should be terminated
   148  	// by this call. This requires the miner's proving period handling to be run after commit verification.
   149  	vm.ApplyOk(t, v, builtin.SystemActorAddr, builtin.CronActorAddr, big.Zero(), builtin.MethodsCron.EpochTick, nil)
   150  
   151  	// Loss of power indicates original sector has been terminated at correct time.
   152  	minerPower = vm.MinerPower(t, v, minerAddrs.IDAddress)
   153  	assert.Equal(t, big.Zero(), minerPower.Raw)
   154  	assert.Equal(t, big.Zero(), minerPower.QA)
   155  }