diff --git a/itests/deals_test.go b/itests/deals_test.go index 3a6d9c868..af0ef68c4 100644 --- a/itests/deals_test.go +++ b/itests/deals_test.go @@ -239,23 +239,10 @@ func TestFirstDealEnablesMining(t *testing.T) { // once the provider has mined a block, thanks to the power acquired from the deal, // we pass the test. providerMined := make(chan struct{}) - heads, err := client.ChainNotify(ctx) - require.NoError(t, err) go func() { - for chg := range heads { - for _, c := range chg { - if c.Type != "apply" { - continue - } - for _, b := range c.Val.Blocks() { - if b.Miner == provider.ActorAddr { - close(providerMined) - return - } - } - } - } + _ = client.WaitTillChain(ctx, kit2.BlockMinedBy(provider.ActorAddr)) + close(providerMined) }() // now perform the deal. diff --git a/itests/kit2/ensemble_opts.go b/itests/kit2/ensemble_opts.go index c7edb99a6..f8bc81535 100644 --- a/itests/kit2/ensemble_opts.go +++ b/itests/kit2/ensemble_opts.go @@ -23,7 +23,7 @@ type ensembleOpts struct { } var DefaultEnsembleOpts = ensembleOpts{ - pastOffset: 100000 * time.Second, // time sufficiently in the past to trigger catch-up mining. + pastOffset: 10000000 * time.Second, // time sufficiently in the past to trigger catch-up mining. proofType: abi.RegisteredSealProof_StackedDrg2KiBV1, } diff --git a/itests/kit2/node_full.go b/itests/kit2/node_full.go index b0b39b471..3dadb4d8d 100644 --- a/itests/kit2/node_full.go +++ b/itests/kit2/node_full.go @@ -4,8 +4,11 @@ import ( "context" "testing" + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/v1api" + "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/wallet" "github.com/multiformats/go-multiaddr" "github.com/stretchr/testify/require" @@ -33,3 +36,50 @@ func (f *TestFullNode) CreateImportFile(ctx context.Context, rseed int, size int require.NoError(f.t, err) return res, path } + +// WaitTillChain waits until a specified chain condition is met. It returns +// the first tipset where the condition is met. +func (f *TestFullNode) WaitTillChain(ctx context.Context, pred ChainPredicate) *types.TipSet { + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + heads, err := f.ChainNotify(ctx) + require.NoError(f.t, err) + + for chg := range heads { + for _, c := range chg { + if c.Type != "apply" { + continue + } + if ts := c.Val; pred(ts) { + return ts + } + } + } + require.Fail(f.t, "chain condition not met") + return nil +} + +// ChainPredicate encapsulates a chain condition. +type ChainPredicate func(set *types.TipSet) bool + +// HeightAtLeast returns a ChainPredicate that is satisfied when the chain +// height is equal or higher to the target. +func HeightAtLeast(target abi.ChainEpoch) ChainPredicate { + return func(ts *types.TipSet) bool { + return ts.Height() >= target + } +} + +// BlockMinedBy returns a ChainPredicate that is satisfied when we observe the +// first block mined by the specified miner. +func BlockMinedBy(miner address.Address) ChainPredicate { + return func(ts *types.TipSet) bool { + for _, b := range ts.Blocks() { + if b.Miner == miner { + return true + } + } + return false + } +} diff --git a/itests/sector_pledge_test.go b/itests/sector_pledge_test.go index 62daa1add..8e87f2658 100644 --- a/itests/sector_pledge_test.go +++ b/itests/sector_pledge_test.go @@ -9,8 +9,6 @@ import ( "github.com/stretchr/testify/require" - "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" sealing "github.com/filecoin-project/lotus/extern/storage-sealing" @@ -60,7 +58,7 @@ func TestPledgeBatching(t *testing.T) { client, miner, ens := kit2.EnsembleMinimal(t, kit2.MockProofs(), opts) ens.InterconnectAll().BeginMining(blockTime) - waitTillChainHeight(ctx, t, client, 10) + client.WaitTillChain(ctx, kit2.HeightAtLeast(10)) toCheck := miner.StartPledge(ctx, nSectors, 0, nil) @@ -117,7 +115,7 @@ func TestPledgeBeforeNv13(t *testing.T) { client, miner, ens := kit2.EnsembleMinimal(t, kit2.MockProofs(), opts) ens.InterconnectAll().BeginMining(blocktime) - waitTillChainHeight(ctx, t, client, 10) + client.WaitTillChain(ctx, kit2.HeightAtLeast(10)) toCheck := miner.StartPledge(ctx, nSectors, 0, nil) @@ -145,13 +143,3 @@ func TestPledgeBeforeNv13(t *testing.T) { runTest(t, 100) }) } - -func waitTillChainHeight(ctx context.Context, t *testing.T, node *kit2.TestFullNode, height int) { - for { - h, err := node.ChainHead(ctx) - require.NoError(t, err) - if h.Height() > abi.ChainEpoch(height) { - return - } - } -} diff --git a/itests/sector_terminate_test.go b/itests/sector_terminate_test.go index b00337c7e..faf12228c 100644 --- a/itests/sector_terminate_test.go +++ b/itests/sector_terminate_test.go @@ -2,18 +2,15 @@ package itests import ( "context" - "fmt" "os" "testing" "time" "github.com/filecoin-project/go-bitfield" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" sealing "github.com/filecoin-project/lotus/extern/storage-sealing" - "github.com/filecoin-project/lotus/itests/kit" - "github.com/filecoin-project/lotus/node/impl" + "github.com/filecoin-project/lotus/itests/kit2" "github.com/stretchr/testify/require" ) @@ -22,7 +19,7 @@ func TestTerminate(t *testing.T) { t.Skip("this takes a few minutes, set LOTUS_TEST_WINDOW_POST=1 to run") } - kit.QuietMiningLogs() + kit2.QuietMiningLogs() const blocktime = 2 * time.Millisecond @@ -31,42 +28,9 @@ func TestTerminate(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - n, sn := kit.MockMinerBuilder(t, - []kit.FullNodeOpts{kit.FullNodeWithLatestActorsAt(-1)}, - []kit.StorageMiner{{Full: 0, Preseal: int(nSectors)}}, - ) - - client := n[0].FullNode.(*impl.FullNodeAPI) - miner := sn[0] - - addrinfo, err := client.NetAddrsListen(ctx) - if err != nil { - t.Fatal(err) - } - - if err := miner.NetConnect(ctx, addrinfo); err != nil { - t.Fatal(err) - } - build.Clock.Sleep(time.Second) - - done := make(chan struct{}) - go func() { - defer close(done) - for ctx.Err() == nil { - build.Clock.Sleep(blocktime) - if err := sn[0].MineOne(ctx, kit.MineNext); err != nil { - if ctx.Err() != nil { - // context was canceled, ignore the error. - return - } - t.Error(err) - } - } - }() - defer func() { - cancel() - <-done - }() + opts := kit2.ConstructorOpts(kit2.LatestActorsAt(-1)) + client, miner, ens := kit2.EnsembleMinimal(t, kit2.MockProofs(), opts) + ens.InterconnectAll().BeginMining(blocktime) maddr, err := miner.ActorAddress(ctx) require.NoError(t, err) @@ -79,11 +43,11 @@ func TestTerminate(t *testing.T) { require.Equal(t, p.MinerPower, p.TotalPower) require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz)*nSectors)) - fmt.Printf("Seal a sector\n") + t.Log("Seal a sector") - kit.PledgeSectors(t, ctx, miner, 1, 0, nil) + miner.PledgeSectors(ctx, 1, 0, nil) - fmt.Printf("wait for power\n") + t.Log("wait for power") { // Wait until proven. @@ -91,17 +55,10 @@ func TestTerminate(t *testing.T) { require.NoError(t, err) waitUntil := di.PeriodStart + di.WPoStProvingPeriod + 2 - fmt.Printf("End for head.Height > %d\n", waitUntil) + t.Logf("End for head.Height > %d", waitUntil) - for { - head, err := client.ChainHead(ctx) - require.NoError(t, err) - - if head.Height() > waitUntil { - fmt.Printf("Now head.Height = %d\n", head.Height()) - break - } - } + ts := client.WaitTillChain(ctx, kit2.HeightAtLeast(waitUntil)) + t.Logf("Now head.Height = %d", ts.Height()) } nSectors++ @@ -111,7 +68,7 @@ func TestTerminate(t *testing.T) { require.Equal(t, p.MinerPower, p.TotalPower) require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz)*nSectors)) - fmt.Println("Terminate a sector") + t.Log("Terminate a sector") toTerminate := abi.SectorNumber(3) @@ -124,7 +81,7 @@ loop: si, err := miner.SectorsStatus(ctx, toTerminate, false) require.NoError(t, err) - fmt.Println("state: ", si.State, msgTriggerred) + t.Log("state: ", si.State, msgTriggerred) switch sealing.SectorState(si.State) { case sealing.Terminating: @@ -140,7 +97,7 @@ loop: require.NoError(t, err) if c != nil { msgTriggerred = true - fmt.Println("terminate message:", c) + t.Log("terminate message:", c) { p, err := miner.SectorTerminatePending(ctx) @@ -180,18 +137,11 @@ loop: di, err := client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK) require.NoError(t, err) - for { - head, err := client.ChainHead(ctx) - require.NoError(t, err) - if head.Height() > di.PeriodStart+di.WPoStProvingPeriod+2 { - fmt.Printf("Now head.Height = %d\n", head.Height()) - break - } - build.Clock.Sleep(blocktime) - } - require.NoError(t, err) - fmt.Printf("End for head.Height > %d\n", di.PeriodStart+di.WPoStProvingPeriod+2) + waitUntil := di.PeriodStart + di.WPoStProvingPeriod + 2 + t.Logf("End for head.Height > %d", waitUntil) + ts := client.WaitTillChain(ctx, kit2.HeightAtLeast(waitUntil)) + t.Logf("Now head.Height = %d", ts.Height()) p, err = client.StateMinerPower(ctx, maddr, types.EmptyTSK) require.NoError(t, err)