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, ¶ms) 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 }