feat: itest: minor UnmanagedMiner refactor for reusability and simplicity

* move some utility methods into UnmanagedMiner so they can be used from other itests
* make UnmanagedMiner aware of mock proofs so we can remove a lot of branching
This commit is contained in:
Rod Vagg 2024-06-14 18:00:14 +10:00
parent 5dffc05a30
commit 16efdf62d0
3 changed files with 106 additions and 201 deletions

View File

@ -327,7 +327,7 @@ func (n *Ensemble) UnmanagedMiner(full *TestFullNode, opts ...NodeOpt) (*TestUnm
actorAddr, err := address.NewIDAddress(genesis2.MinerStart + n.minerCount()) actorAddr, err := address.NewIDAddress(genesis2.MinerStart + n.minerCount())
require.NoError(n.t, err) require.NoError(n.t, err)
minerNode := NewTestUnmanagedMiner(n.t, full, actorAddr, opts...) minerNode := NewTestUnmanagedMiner(n.t, full, actorAddr, n.options.mockProofs, opts...)
n.AddInactiveUnmanagedMiner(minerNode) n.AddInactiveUnmanagedMiner(minerNode)
return minerNode, n return minerNode, n
} }

View File

@ -36,6 +36,7 @@ import (
type TestUnmanagedMiner struct { type TestUnmanagedMiner struct {
t *testing.T t *testing.T
options nodeOpts options nodeOpts
mockProofs bool
cacheDir string cacheDir string
unsealedSectorDir string unsealedSectorDir string
@ -65,7 +66,7 @@ type WindowPostResp struct {
Error error Error error
} }
func NewTestUnmanagedMiner(t *testing.T, full *TestFullNode, actorAddr address.Address, opts ...NodeOpt) *TestUnmanagedMiner { func NewTestUnmanagedMiner(t *testing.T, full *TestFullNode, actorAddr address.Address, mockProofs bool, opts ...NodeOpt) *TestUnmanagedMiner {
require.NotNil(t, full, "full node required when instantiating miner") require.NotNil(t, full, "full node required when instantiating miner")
options := DefaultNodeOpts options := DefaultNodeOpts
@ -94,6 +95,7 @@ func NewTestUnmanagedMiner(t *testing.T, full *TestFullNode, actorAddr address.A
tm := TestUnmanagedMiner{ tm := TestUnmanagedMiner{
t: t, t: t,
options: options, options: options,
mockProofs: mockProofs,
cacheDir: cacheDir, cacheDir: cacheDir,
unsealedSectorDir: unsealedSectorDir, unsealedSectorDir: unsealedSectorDir,
sealedSectorDir: sealedSectorDir, sealedSectorDir: sealedSectorDir,
@ -222,7 +224,7 @@ func (tm *TestUnmanagedMiner) makeAndSaveCCSector(_ context.Context, sectorNumbe
tm.cacheDirPaths[sectorNumber] = cacheDirPath tm.cacheDirPaths[sectorNumber] = cacheDirPath
} }
func (tm *TestUnmanagedMiner) OnboardSectorWithPiecesAndRealProofs(ctx context.Context, proofType abi.RegisteredSealProof) (abi.SectorNumber, chan WindowPostResp, func (tm *TestUnmanagedMiner) OnboardSectorWithPieces(ctx context.Context, proofType abi.RegisteredSealProof) (abi.SectorNumber, chan WindowPostResp,
context.CancelFunc) { context.CancelFunc) {
req := require.New(tm.t) req := require.New(tm.t)
sectorNumber := tm.currentSectorNum sectorNumber := tm.currentSectorNum
@ -232,10 +234,23 @@ func (tm *TestUnmanagedMiner) OnboardSectorWithPiecesAndRealProofs(ctx context.C
preCommitSealRand := tm.waitPreCommitSealRandomness(ctx, sectorNumber) preCommitSealRand := tm.waitPreCommitSealRandomness(ctx, sectorNumber)
// Step 2: Build a sector with non 0 Pieces that we want to onboard // Step 2: Build a sector with non 0 Pieces that we want to onboard
pieces := tm.mkAndSavePiecesToOnboard(ctx, sectorNumber, proofType) var pieces []abi.PieceInfo
if !tm.mockProofs {
pieces = tm.mkAndSavePiecesToOnboard(ctx, sectorNumber, proofType)
} else {
pieces = []abi.PieceInfo{{
Size: abi.PaddedPieceSize(tm.options.sectorSize),
PieceCID: cid.MustParse("baga6ea4seaqjtovkwk4myyzj56eztkh5pzsk5upksan6f5outesy62bsvl4dsha"),
}}
}
// Step 3: Generate a Pre-Commit for the CC sector -> this persists the proof on the `TestUnmanagedMiner` Miner State // Step 3: Generate a Pre-Commit for the CC sector -> this persists the proof on the `TestUnmanagedMiner` Miner State
if !tm.mockProofs {
tm.generatePreCommit(ctx, sectorNumber, preCommitSealRand, proofType, pieces) tm.generatePreCommit(ctx, sectorNumber, preCommitSealRand, proofType, pieces)
} else {
tm.sealedCids[sectorNumber] = cid.MustParse("bagboea4b5abcatlxechwbp7kjpjguna6r6q7ejrhe6mdp3lf34pmswn27pkkiekz")
tm.unsealedCids[sectorNumber] = cid.MustParse("baga6ea4seaqjtovkwk4myyzj56eztkh5pzsk5upksan6f5outesy62bsvl4dsha")
}
// Step 4 : Submit the Pre-Commit to the network // Step 4 : Submit the Pre-Commit to the network
unsealedCid := tm.unsealedCids[sectorNumber] unsealedCid := tm.unsealedCids[sectorNumber]
@ -255,7 +270,10 @@ func (tm *TestUnmanagedMiner) OnboardSectorWithPiecesAndRealProofs(ctx context.C
// Step 5: Generate a ProveCommit for the CC sector // Step 5: Generate a ProveCommit for the CC sector
waitSeedRandomness := tm.proveCommitWaitSeed(ctx, sectorNumber) waitSeedRandomness := tm.proveCommitWaitSeed(ctx, sectorNumber)
proveCommit := tm.generateProveCommit(ctx, sectorNumber, proofType, waitSeedRandomness, pieces) proveCommit := []byte{0xde, 0xad, 0xbe, 0xef} // mock prove commit
if !tm.mockProofs {
proveCommit = tm.generateProveCommit(ctx, sectorNumber, proofType, waitSeedRandomness, pieces)
}
// Step 6: Submit the ProveCommit to the network // Step 6: Submit the ProveCommit to the network
tm.t.Log("Submitting ProveCommitSector ...") tm.t.Log("Submitting ProveCommitSector ...")
@ -281,74 +299,7 @@ func (tm *TestUnmanagedMiner) OnboardSectorWithPiecesAndRealProofs(ctx context.C
respCh := make(chan WindowPostResp, 1) respCh := make(chan WindowPostResp, 1)
wdCtx, cancelF := context.WithCancel(ctx) wdCtx, cancelF := context.WithCancel(ctx)
go tm.wdPostLoop(wdCtx, sectorNumber, respCh, false, tm.sealedCids[sectorNumber], tm.sealedSectorPaths[sectorNumber], tm.cacheDirPaths[sectorNumber]) go tm.wdPostLoop(wdCtx, sectorNumber, respCh, tm.sealedCids[sectorNumber], tm.sealedSectorPaths[sectorNumber], tm.cacheDirPaths[sectorNumber])
return sectorNumber, respCh, cancelF
}
func (tm *TestUnmanagedMiner) OnboardSectorWithPiecesAndMockProofs(ctx context.Context, proofType abi.RegisteredSealProof) (abi.SectorNumber, chan WindowPostResp,
context.CancelFunc) {
req := require.New(tm.t)
sectorNumber := tm.currentSectorNum
tm.currentSectorNum++
// Step 1: Wait for the pre-commitseal randomness to be available (we can only draw seal randomness from tipsets that have already achieved finality)
preCommitSealRand := tm.waitPreCommitSealRandomness(ctx, sectorNumber)
// Step 2: Build a sector with non 0 Pieces that we want to onboard
pieces := []abi.PieceInfo{{
Size: abi.PaddedPieceSize(tm.options.sectorSize),
PieceCID: cid.MustParse("baga6ea4seaqjtovkwk4myyzj56eztkh5pzsk5upksan6f5outesy62bsvl4dsha"),
}}
// Step 3: Generate a Pre-Commit for the CC sector -> this persists the proof on the `TestUnmanagedMiner` Miner State
tm.sealedCids[sectorNumber] = cid.MustParse("bagboea4b5abcatlxechwbp7kjpjguna6r6q7ejrhe6mdp3lf34pmswn27pkkiekz")
tm.unsealedCids[sectorNumber] = cid.MustParse("baga6ea4seaqjtovkwk4myyzj56eztkh5pzsk5upksan6f5outesy62bsvl4dsha")
// Step 4 : Submit the Pre-Commit to the network
unsealedCid := tm.unsealedCids[sectorNumber]
r, err := tm.submitMessage(ctx, &miner14.PreCommitSectorBatchParams2{
Sectors: []miner14.SectorPreCommitInfo{{
Expiration: 2880 * 300,
SectorNumber: sectorNumber,
SealProof: TestSpt,
SealedCID: tm.sealedCids[sectorNumber],
SealRandEpoch: preCommitSealRand,
UnsealedCid: &unsealedCid,
}},
}, 1, builtin.MethodsMiner.PreCommitSectorBatch2)
req.NoError(err)
req.True(r.Receipt.ExitCode.IsSuccess())
// Step 5: Generate a ProveCommit for the CC sector
_ = tm.proveCommitWaitSeed(ctx, sectorNumber)
sectorProof := []byte{0xde, 0xad, 0xbe, 0xef}
// Step 6: Submit the ProveCommit to the network
tm.t.Log("Submitting ProveCommitSector ...")
var manifest []miner14.PieceActivationManifest
for _, piece := range pieces {
manifest = append(manifest, miner14.PieceActivationManifest{
CID: piece.PieceCID,
Size: piece.Size,
})
}
r, err = tm.submitMessage(ctx, &miner14.ProveCommitSectors3Params{
SectorActivations: []miner14.SectorActivationManifest{{SectorNumber: sectorNumber, Pieces: manifest}},
SectorProofs: [][]byte{sectorProof},
RequireActivationSuccess: true,
}, 1, builtin.MethodsMiner.ProveCommitSectors3)
req.NoError(err)
req.True(r.Receipt.ExitCode.IsSuccess())
tm.proofType[sectorNumber] = proofType
respCh := make(chan WindowPostResp, 1)
wdCtx, cancelF := context.WithCancel(ctx)
go tm.wdPostLoop(wdCtx, sectorNumber, respCh, true, tm.sealedCids[sectorNumber], tm.sealedSectorPaths[sectorNumber], tm.cacheDirPaths[sectorNumber])
return sectorNumber, respCh, cancelF return sectorNumber, respCh, cancelF
} }
@ -393,7 +344,11 @@ func (tm *TestUnmanagedMiner) mkStagedFileWithPieces(pt abi.RegisteredSealProof)
return publicPieces, unsealedSectorFile.Name() return publicPieces, unsealedSectorFile.Name()
} }
func (tm *TestUnmanagedMiner) SnapDealWithRealProofs(ctx context.Context, proofType abi.RegisteredSealProof, sectorNumber abi.SectorNumber) { func (tm *TestUnmanagedMiner) SnapDeal(ctx context.Context, proofType abi.RegisteredSealProof, sectorNumber abi.SectorNumber) {
if tm.mockProofs {
tm.t.Fatal("snap deal with mock proofs currently not supported")
}
// generate sector key // generate sector key
pieces, unsealedPath := tm.mkStagedFileWithPieces(proofType) pieces, unsealedPath := tm.mkStagedFileWithPieces(proofType)
updateProofType := abi.SealProofInfos[proofType].UpdateProof updateProofType := abi.SealProofInfos[proofType].UpdateProof
@ -489,56 +444,7 @@ func (tm *TestUnmanagedMiner) waitForMutableDeadline(ctx context.Context, sector
} }
} }
func (tm *TestUnmanagedMiner) OnboardCCSectorWithMockProofs(ctx context.Context, proofType abi.RegisteredSealProof) (abi.SectorNumber, chan WindowPostResp, func (tm *TestUnmanagedMiner) OnboardCCSector(ctx context.Context, proofType abi.RegisteredSealProof) (abi.SectorNumber, chan WindowPostResp,
context.CancelFunc) {
req := require.New(tm.t)
sectorNumber := tm.currentSectorNum
tm.currentSectorNum++
// Step 1: Wait for the pre-commitseal randomness to be available (we can only draw seal randomness from tipsets that have already achieved finality)
preCommitSealRand := tm.waitPreCommitSealRandomness(ctx, sectorNumber)
tm.sealedCids[sectorNumber] = cid.MustParse("bagboea4b5abcatlxechwbp7kjpjguna6r6q7ejrhe6mdp3lf34pmswn27pkkiekz")
// Step 4 : Submit the Pre-Commit to the network
r, err := tm.submitMessage(ctx, &miner14.PreCommitSectorBatchParams2{
Sectors: []miner14.SectorPreCommitInfo{{
Expiration: 2880 * 300,
SectorNumber: sectorNumber,
SealProof: TestSpt,
SealedCID: tm.sealedCids[sectorNumber],
SealRandEpoch: preCommitSealRand,
}},
}, 1, builtin.MethodsMiner.PreCommitSectorBatch2)
req.NoError(err)
req.True(r.Receipt.ExitCode.IsSuccess())
// Step 5: Generate a ProveCommit for the CC sector
_ = tm.proveCommitWaitSeed(ctx, sectorNumber)
sectorProof := []byte{0xde, 0xad, 0xbe, 0xef}
// Step 6: Submit the ProveCommit to the network
tm.t.Log("Submitting ProveCommitSector ...")
r, err = tm.submitMessage(ctx, &miner14.ProveCommitSectors3Params{
SectorActivations: []miner14.SectorActivationManifest{{SectorNumber: sectorNumber}},
SectorProofs: [][]byte{sectorProof},
RequireActivationSuccess: true,
}, 0, builtin.MethodsMiner.ProveCommitSectors3)
req.NoError(err)
req.True(r.Receipt.ExitCode.IsSuccess())
tm.proofType[sectorNumber] = proofType
respCh := make(chan WindowPostResp, 1)
wdCtx, cancelF := context.WithCancel(ctx)
go tm.wdPostLoop(wdCtx, sectorNumber, respCh, true, tm.sealedCids[sectorNumber], tm.sealedSectorPaths[sectorNumber], tm.cacheDirPaths[sectorNumber])
return sectorNumber, respCh, cancelF
}
func (tm *TestUnmanagedMiner) OnboardCCSectorWithRealProofs(ctx context.Context, proofType abi.RegisteredSealProof) (abi.SectorNumber, chan WindowPostResp,
context.CancelFunc) { context.CancelFunc) {
req := require.New(tm.t) req := require.New(tm.t)
sectorNumber := tm.currentSectorNum sectorNumber := tm.currentSectorNum
@ -549,11 +455,16 @@ func (tm *TestUnmanagedMiner) OnboardCCSectorWithRealProofs(ctx context.Context,
// Step 1: Wait for the pre-commitseal randomness to be available (we can only draw seal randomness from tipsets that have already achieved finality) // Step 1: Wait for the pre-commitseal randomness to be available (we can only draw seal randomness from tipsets that have already achieved finality)
preCommitSealRand := tm.waitPreCommitSealRandomness(ctx, sectorNumber) preCommitSealRand := tm.waitPreCommitSealRandomness(ctx, sectorNumber)
if !tm.mockProofs {
// Step 2: Write empty bytes that we want to seal i.e. create our CC sector // Step 2: Write empty bytes that we want to seal i.e. create our CC sector
tm.makeAndSaveCCSector(ctx, sectorNumber) tm.makeAndSaveCCSector(ctx, sectorNumber)
// Step 3: Generate a Pre-Commit for the CC sector -> this persists the proof on the `TestUnmanagedMiner` Miner State // Step 3: Generate a Pre-Commit for the CC sector -> this persists the proof on the `TestUnmanagedMiner` Miner State
tm.generatePreCommit(ctx, sectorNumber, preCommitSealRand, proofType, []abi.PieceInfo{}) tm.generatePreCommit(ctx, sectorNumber, preCommitSealRand, proofType, []abi.PieceInfo{})
} else {
// skip the above steps and use a mock sealed CID
tm.sealedCids[sectorNumber] = cid.MustParse("bagboea4b5abcatlxechwbp7kjpjguna6r6q7ejrhe6mdp3lf34pmswn27pkkiekz")
}
// Step 4 : Submit the Pre-Commit to the network // Step 4 : Submit the Pre-Commit to the network
r, err := tm.submitMessage(ctx, &miner14.PreCommitSectorBatchParams2{ r, err := tm.submitMessage(ctx, &miner14.PreCommitSectorBatchParams2{
@ -571,7 +482,10 @@ func (tm *TestUnmanagedMiner) OnboardCCSectorWithRealProofs(ctx context.Context,
// Step 5: Generate a ProveCommit for the CC sector // Step 5: Generate a ProveCommit for the CC sector
waitSeedRandomness := tm.proveCommitWaitSeed(ctx, sectorNumber) waitSeedRandomness := tm.proveCommitWaitSeed(ctx, sectorNumber)
proveCommit := tm.generateProveCommit(ctx, sectorNumber, proofType, waitSeedRandomness, []abi.PieceInfo{}) proveCommit := []byte{0xde, 0xad, 0xbe, 0xef} // mock prove commit
if !tm.mockProofs {
proveCommit = tm.generateProveCommit(ctx, sectorNumber, proofType, waitSeedRandomness, []abi.PieceInfo{})
}
// Step 6: Submit the ProveCommit to the network // Step 6: Submit the ProveCommit to the network
tm.t.Log("Submitting ProveCommitSector ...") tm.t.Log("Submitting ProveCommitSector ...")
@ -589,12 +503,12 @@ func (tm *TestUnmanagedMiner) OnboardCCSectorWithRealProofs(ctx context.Context,
respCh := make(chan WindowPostResp, 1) respCh := make(chan WindowPostResp, 1)
wdCtx, cancelF := context.WithCancel(ctx) wdCtx, cancelF := context.WithCancel(ctx)
go tm.wdPostLoop(wdCtx, sectorNumber, respCh, false, tm.sealedCids[sectorNumber], tm.sealedSectorPaths[sectorNumber], tm.cacheDirPaths[sectorNumber]) go tm.wdPostLoop(wdCtx, sectorNumber, respCh, tm.sealedCids[sectorNumber], tm.sealedSectorPaths[sectorNumber], tm.cacheDirPaths[sectorNumber])
return sectorNumber, respCh, cancelF return sectorNumber, respCh, cancelF
} }
func (tm *TestUnmanagedMiner) wdPostLoop(ctx context.Context, sectorNumber abi.SectorNumber, respCh chan WindowPostResp, withMockProofs bool, sealedCid cid.Cid, sealedPath, cacheDir string) { func (tm *TestUnmanagedMiner) wdPostLoop(ctx context.Context, sectorNumber abi.SectorNumber, respCh chan WindowPostResp, sealedCid cid.Cid, sealedPath, cacheDir string) {
go func() { go func() {
var firstPost bool var firstPost bool
@ -635,7 +549,7 @@ func (tm *TestUnmanagedMiner) wdPostLoop(ctx context.Context, sectorNumber abi.S
} }
} }
err = tm.submitWindowPost(ctx, sectorNumber, withMockProofs, sealedCid, sealedPath, cacheDir) err = tm.submitWindowPost(ctx, sectorNumber, sealedCid, sealedPath, cacheDir)
writeRespF(err) // send an error, or first post, or nothing if no error and this isn't the first post writeRespF(err) // send an error, or first post, or nothing if no error and this isn't the first post
postCount++ postCount++
tm.t.Logf("Sector %d: WindowPoSt #%d submitted", sectorNumber, postCount) tm.t.Logf("Sector %d: WindowPoSt #%d submitted", sectorNumber, postCount)
@ -675,7 +589,7 @@ func (tm *TestUnmanagedMiner) SubmitPostDispute(ctx context.Context, sectorNumbe
return err return err
} }
func (tm *TestUnmanagedMiner) submitWindowPost(ctx context.Context, sectorNumber abi.SectorNumber, withMockProofs bool, sealedCid cid.Cid, sealedPath, cacheDir string) error { func (tm *TestUnmanagedMiner) submitWindowPost(ctx context.Context, sectorNumber abi.SectorNumber, sealedCid cid.Cid, sealedPath, cacheDir string) error {
tm.t.Logf("Miner(%s): WindowPoST(%d): Running WindowPoSt ...\n", tm.ActorAddr, sectorNumber) tm.t.Logf("Miner(%s): WindowPoST(%d): Running WindowPoSt ...\n", tm.ActorAddr, sectorNumber)
head, err := tm.FullNode.ChainHead(ctx) head, err := tm.FullNode.ChainHead(ctx)
@ -698,7 +612,7 @@ func (tm *TestUnmanagedMiner) submitWindowPost(ctx context.Context, sectorNumber
} }
var proofBytes []byte var proofBytes []byte
if withMockProofs { if tm.mockProofs {
proofBytes = []byte{0xde, 0xad, 0xbe, 0xef} proofBytes = []byte{0xde, 0xad, 0xbe, 0xef}
} else { } else {
proofBytes, err = tm.generateWindowPost(ctx, sectorNumber, sealedCid, sealedPath, cacheDir) proofBytes, err = tm.generateWindowPost(ctx, sectorNumber, sealedCid, sealedPath, cacheDir)
@ -1070,3 +984,50 @@ func requireTempFile(t *testing.T, fileContentsReader io.Reader, size uint64) *o
return tempFile return tempFile
} }
func (tm *TestUnmanagedMiner) WaitTillActivatedAndAssertPower(
ctx context.Context,
respCh chan WindowPostResp,
sector abi.SectorNumber,
) {
// wait till sector is activated
select {
case resp := <-respCh:
require.NoError(tm.t, resp.Error)
require.True(tm.t, resp.Posted)
case <-ctx.Done():
tm.t.Fatal("timed out waiting for sector activation")
}
// Fetch on-chain sector properties
head, err := tm.FullNode.ChainHead(ctx)
require.NoError(tm.t, err)
soi, err := tm.FullNode.StateSectorGetInfo(ctx, tm.ActorAddr, sector, head.Key())
require.NoError(tm.t, err)
tm.t.Logf("Miner %s SectorOnChainInfo %d: %+v", tm.ActorAddr.String(), sector, soi)
_ = tm.FullNode.WaitTillChain(ctx, HeightAtLeast(head.Height()+5))
tm.t.Log("Checking power after PoSt ...")
// Miner B should now have power
tm.AssertPower(ctx, uint64(tm.options.sectorSize), uint64(tm.options.sectorSize))
if tm.mockProofs {
// WindowPost Dispute should succeed as we are using mock proofs
err := tm.SubmitPostDispute(ctx, sector)
require.NoError(tm.t, err)
} else {
// WindowPost Dispute should fail
tm.AssertDisputeFails(ctx, sector)
}
}
func (tm *TestUnmanagedMiner) AssertDisputeFails(ctx context.Context, sector abi.SectorNumber) {
err := tm.SubmitPostDispute(ctx, sector)
require.Error(tm.t, err)
require.Contains(tm.t, err.Error(), "failed to dispute valid post")
require.Contains(tm.t, err.Error(), "(RetCode=16)")
}

View File

@ -13,10 +13,10 @@ import (
"github.com/filecoin-project/lotus/itests/kit" "github.com/filecoin-project/lotus/itests/kit"
) )
const defaultSectorSize = abi.SectorSize(2 << 10) // 2KiB
// Manually onboard CC sectors, bypassing lotus-miner onboarding pathways // Manually onboard CC sectors, bypassing lotus-miner onboarding pathways
func TestManualSectorOnboarding(t *testing.T) { func TestManualSectorOnboarding(t *testing.T) {
const defaultSectorSize = abi.SectorSize(2 << 10) // 2KiB
req := require.New(t) req := require.New(t)
for _, withMockProofs := range []bool{true, false} { for _, withMockProofs := range []bool{true, false} {
@ -41,11 +41,7 @@ func TestManualSectorOnboarding(t *testing.T) {
// Setup and begin mining with a single miner (A) // Setup and begin mining with a single miner (A)
// Miner A will only be a genesis Miner with power allocated in the genesis block and will not onboard any sectors from here on // Miner A will only be a genesis Miner with power allocated in the genesis block and will not onboard any sectors from here on
kitOpts := []kit.EnsembleOpt{} ens := kit.NewEnsemble(t, kit.MockProofs(withMockProofs)).
if withMockProofs {
kitOpts = append(kitOpts, kit.MockProofs())
}
ens := kit.NewEnsemble(t, kitOpts...).
FullNode(&client, kit.SectorSize(defaultSectorSize)). FullNode(&client, kit.SectorSize(defaultSectorSize)).
// preseal more than the default number of sectors to ensure that the genesis miner has power // preseal more than the default number of sectors to ensure that the genesis miner has power
// because our unmanaged miners won't produce blocks so we may get null rounds // because our unmanaged miners won't produce blocks so we may get null rounds
@ -89,11 +85,7 @@ func TestManualSectorOnboarding(t *testing.T) {
var bRespCh chan kit.WindowPostResp var bRespCh chan kit.WindowPostResp
var bWdPostCancelF context.CancelFunc var bWdPostCancelF context.CancelFunc
if withMockProofs { bSectorNum, bRespCh, bWdPostCancelF = minerB.OnboardCCSector(ctx, kit.TestSpt)
bSectorNum, bRespCh, bWdPostCancelF = minerB.OnboardCCSectorWithMockProofs(ctx, kit.TestSpt)
} else {
bSectorNum, bRespCh, bWdPostCancelF = minerB.OnboardCCSectorWithRealProofs(ctx, kit.TestSpt)
}
// Miner B should still not have power as power can only be gained after sector is activated i.e. the first WindowPost is submitted for it // Miner B should still not have power as power can only be gained after sector is activated i.e. the first WindowPost is submitted for it
minerB.AssertNoPower(ctx) minerB.AssertNoPower(ctx)
// Ensure that the block miner checks for and waits for posts during the appropriate proving window from our new miner with a sector // Ensure that the block miner checks for and waits for posts during the appropriate proving window from our new miner with a sector
@ -103,72 +95,24 @@ func TestManualSectorOnboarding(t *testing.T) {
var cSectorNum abi.SectorNumber var cSectorNum abi.SectorNumber
var cRespCh chan kit.WindowPostResp var cRespCh chan kit.WindowPostResp
if withMockProofs { cSectorNum, cRespCh, _ = minerC.OnboardSectorWithPieces(ctx, kit.TestSpt)
cSectorNum, cRespCh, _ = minerC.OnboardSectorWithPiecesAndMockProofs(ctx, kit.TestSpt)
} else {
cSectorNum, cRespCh, _ = minerC.OnboardSectorWithPiecesAndRealProofs(ctx, kit.TestSpt)
}
// Miner C should still not have power as power can only be gained after sector is activated i.e. the first WindowPost is submitted for it // Miner C should still not have power as power can only be gained after sector is activated i.e. the first WindowPost is submitted for it
minerC.AssertNoPower(ctx) minerC.AssertNoPower(ctx)
// Ensure that the block miner checks for and waits for posts during the appropriate proving window from our new miner with a sector // Ensure that the block miner checks for and waits for posts during the appropriate proving window from our new miner with a sector
blockMiner.WatchMinerForPost(minerC.ActorAddr) blockMiner.WatchMinerForPost(minerC.ActorAddr)
// Wait till both miners' sectors have had their first post and are activated and check that this is reflected in miner power // Wait till both miners' sectors have had their first post and are activated and check that this is reflected in miner power
waitTillActivatedAndAssertPower(ctx, t, minerB, bRespCh, bSectorNum, uint64(defaultSectorSize), withMockProofs) minerB.WaitTillActivatedAndAssertPower(ctx, bRespCh, bSectorNum)
waitTillActivatedAndAssertPower(ctx, t, minerC, cRespCh, cSectorNum, uint64(defaultSectorSize), withMockProofs) minerC.WaitTillActivatedAndAssertPower(ctx, cRespCh, cSectorNum)
// Miner B has activated the CC sector -> upgrade it with snapdeals // Miner B has activated the CC sector -> upgrade it with snapdeals
// Note: We can't activate a sector with mock proofs as the WdPost is successfully disputed and so no point // Note: We can't activate a sector with mock proofs as the WdPost is successfully disputed and so no point
// in snapping it as snapping is only for activated sectors // in snapping it as snapping is only for activated sectors
if !withMockProofs { if !withMockProofs {
minerB.SnapDealWithRealProofs(ctx, kit.TestSpt, bSectorNum) minerB.SnapDeal(ctx, kit.TestSpt, bSectorNum)
// cancel the WdPost for the CC sector as the corresponding CommR is no longer valid // cancel the WdPost for the CC sector as the corresponding CommR is no longer valid
bWdPostCancelF() bWdPostCancelF()
} }
}) })
} }
} }
func waitTillActivatedAndAssertPower(ctx context.Context, t *testing.T, miner *kit.TestUnmanagedMiner, respCh chan kit.WindowPostResp, sector abi.SectorNumber,
sectorSize uint64, withMockProofs bool) {
req := require.New(t)
// wait till sector is activated
select {
case resp := <-respCh:
req.NoError(resp.Error)
req.True(resp.Posted)
case <-ctx.Done():
t.Fatal("timed out waiting for sector activation")
}
// Fetch on-chain sector properties
head, err := miner.FullNode.ChainHead(ctx)
req.NoError(err)
soi, err := miner.FullNode.StateSectorGetInfo(ctx, miner.ActorAddr, sector, head.Key())
req.NoError(err)
t.Logf("Miner %s SectorOnChainInfo %d: %+v", miner.ActorAddr.String(), sector, soi)
_ = miner.FullNode.WaitTillChain(ctx, kit.HeightAtLeast(head.Height()+5))
t.Log("Checking power after PoSt ...")
// Miner B should now have power
miner.AssertPower(ctx, sectorSize, sectorSize)
if withMockProofs {
// WindowPost Dispute should succeed as we are using mock proofs
err := miner.SubmitPostDispute(ctx, sector)
require.NoError(t, err)
} else {
// WindowPost Dispute should fail
assertDisputeFails(ctx, t, miner, sector)
}
}
func assertDisputeFails(ctx context.Context, t *testing.T, miner *kit.TestUnmanagedMiner, sector abi.SectorNumber) {
err := miner.SubmitPostDispute(ctx, sector)
require.Error(t, err)
require.Contains(t, err.Error(), "failed to dispute valid post")
require.Contains(t, err.Error(), "(RetCode=16)")
}