Merge pull request #6510 from filecoin-project/refactor/itest-wdpost-dispute

This commit is contained in:
raulk 2021-06-18 19:40:12 +01:00 committed by GitHub
commit a8bf7e7bad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -2,7 +2,6 @@ package itests
import ( import (
"context" "context"
"fmt"
"os" "os"
"testing" "testing"
"time" "time"
@ -16,8 +15,7 @@ import (
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
minerActor "github.com/filecoin-project/lotus/chain/actors/builtin/miner" minerActor "github.com/filecoin-project/lotus/chain/actors/builtin/miner"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/itests/kit" "github.com/filecoin-project/lotus/itests/kit2"
"github.com/filecoin-project/lotus/node/impl"
proof3 "github.com/filecoin-project/specs-actors/v3/actors/runtime/proof" proof3 "github.com/filecoin-project/specs-actors/v3/actors/runtime/proof"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -27,28 +25,29 @@ func TestWindowPostDispute(t *testing.T) {
t.Skip("this takes a few minutes, set LOTUS_TEST_WINDOW_POST=1 to run") t.Skip("this takes a few minutes, set LOTUS_TEST_WINDOW_POST=1 to run")
} }
kit.QuietMiningLogs() kit2.QuietMiningLogs()
b := kit.MockMinerBuilder
blocktime := 2 * time.Millisecond blocktime := 2 * time.Millisecond
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
defer cancel() defer cancel()
var (
client kit2.TestFullNode
chainMiner kit2.TestMiner
evilMiner kit2.TestMiner
)
// First, we configure two miners. After sealing, we're going to turn off the first miner so // First, we configure two miners. After sealing, we're going to turn off the first miner so
// it doesn't submit proofs. // it doesn't submit proofs.
// //
// Then we're going to manually submit bad proofs. // Then we're going to manually submit bad proofs.
n, sn := b(t, opts := kit2.ConstructorOpts(kit2.LatestActorsAt(-1))
[]kit.FullNodeOpts{kit.FullNodeWithLatestActorsAt(-1)}, ens := kit2.NewEnsemble(t, kit2.MockProofs()).
[]kit.StorageMiner{ FullNode(&client, opts).
{Full: 0, Preseal: kit.PresealGenesis}, Miner(&chainMiner, &client, opts).
{Full: 0}, Miner(&evilMiner, &client, opts, kit2.PresealSectors(0)).
}) Start()
client := n[0].FullNode.(*impl.FullNodeAPI)
chainMiner := sn[0]
evilMiner := sn[1]
{ {
addrinfo, err := client.NetAddrsListen(ctx) addrinfo, err := client.NetAddrsListen(ctx)
@ -68,32 +67,13 @@ func TestWindowPostDispute(t *testing.T) {
defaultFrom, err := client.WalletDefaultAddress(ctx) defaultFrom, err := client.WalletDefaultAddress(ctx)
require.NoError(t, err) require.NoError(t, err)
build.Clock.Sleep(time.Second)
// Mine with the _second_ node (the good one). // Mine with the _second_ node (the good one).
done := make(chan struct{}) ens.BeginMining(blocktime, &chainMiner)
go func() {
defer close(done)
for ctx.Err() == nil {
build.Clock.Sleep(blocktime)
if err := chainMiner.MineOne(ctx, kit.MineNext); err != nil {
if ctx.Err() != nil {
// context was canceled, ignore the error.
return
}
t.Error(err)
}
}
}()
defer func() {
cancel()
<-done
}()
// Give the chain miner enough sectors to win every block. // Give the chain miner enough sectors to win every block.
kit.PledgeSectors(t, ctx, chainMiner, 10, 0, nil) chainMiner.PledgeSectors(ctx, 10, 0, nil)
// And the evil one 1 sector. No cookie for you. // And the evil one 1 sector. No cookie for you.
kit.PledgeSectors(t, ctx, evilMiner, 1, 0, nil) evilMiner.PledgeSectors(ctx, 1, 0, nil)
// Let the evil miner's sectors gain power. // Let the evil miner's sectors gain power.
evilMinerAddr, err := evilMiner.ActorAddress(ctx) evilMinerAddr, err := evilMiner.ActorAddress(ctx)
@ -102,19 +82,13 @@ func TestWindowPostDispute(t *testing.T) {
di, err := client.StateMinerProvingDeadline(ctx, evilMinerAddr, types.EmptyTSK) di, err := client.StateMinerProvingDeadline(ctx, evilMinerAddr, types.EmptyTSK)
require.NoError(t, err) require.NoError(t, err)
fmt.Printf("Running one proving period\n") t.Logf("Running one proving period\n")
fmt.Printf("End for head.Height > %d\n", di.PeriodStart+di.WPoStProvingPeriod*2)
for { waitUntil := di.PeriodStart + di.WPoStProvingPeriod*2
head, err := client.ChainHead(ctx) t.Logf("End for head.Height > %d", waitUntil)
require.NoError(t, err)
if head.Height() > di.PeriodStart+di.WPoStProvingPeriod*2 { ts := client.WaitTillChain(ctx, kit2.HeightAtLeast(waitUntil))
fmt.Printf("Now head.Height = %d\n", head.Height()) t.Logf("Now head.Height = %d", ts.Height())
break
}
build.Clock.Sleep(blocktime)
}
p, err := client.StateMinerPower(ctx, evilMinerAddr, types.EmptyTSK) p, err := client.StateMinerPower(ctx, evilMinerAddr, types.EmptyTSK)
require.NoError(t, err) require.NoError(t, err)
@ -131,12 +105,12 @@ func TestWindowPostDispute(t *testing.T) {
evilSectorLoc, err := client.StateSectorPartition(ctx, evilMinerAddr, evilSectorNo, types.EmptyTSK) evilSectorLoc, err := client.StateSectorPartition(ctx, evilMinerAddr, evilSectorNo, types.EmptyTSK)
require.NoError(t, err) require.NoError(t, err)
fmt.Println("evil miner stopping") t.Log("evil miner stopping")
// Now stop the evil miner, and start manually submitting bad proofs. // Now stop the evil miner, and start manually submitting bad proofs.
require.NoError(t, evilMiner.Stop(ctx)) require.NoError(t, evilMiner.Stop(ctx))
fmt.Println("evil miner stopped") t.Log("evil miner stopped")
// Wait until we need to prove our sector. // Wait until we need to prove our sector.
for { for {
@ -148,7 +122,7 @@ func TestWindowPostDispute(t *testing.T) {
build.Clock.Sleep(blocktime) build.Clock.Sleep(blocktime)
} }
err = submitBadProof(ctx, client, evilMinerAddr, di, evilSectorLoc.Deadline, evilSectorLoc.Partition) err = submitBadProof(ctx, client, evilMiner.OwnerKey.Address, evilMinerAddr, di, evilSectorLoc.Deadline, evilSectorLoc.Partition)
require.NoError(t, err, "evil proof not accepted") require.NoError(t, err, "evil proof not accepted")
// Wait until after the proving period. // Wait until after the proving period.
@ -161,7 +135,7 @@ func TestWindowPostDispute(t *testing.T) {
build.Clock.Sleep(blocktime) build.Clock.Sleep(blocktime)
} }
fmt.Println("accepted evil proof") t.Log("accepted evil proof")
// Make sure the evil node didn't lose any power. // Make sure the evil node didn't lose any power.
p, err = client.StateMinerPower(ctx, evilMinerAddr, types.EmptyTSK) p, err = client.StateMinerPower(ctx, evilMinerAddr, types.EmptyTSK)
@ -188,7 +162,7 @@ func TestWindowPostDispute(t *testing.T) {
sm, err := client.MpoolPushMessage(ctx, msg, nil) sm, err := client.MpoolPushMessage(ctx, msg, nil)
require.NoError(t, err) require.NoError(t, err)
fmt.Println("waiting dispute") t.Log("waiting dispute")
rec, err := client.StateWaitMsg(ctx, sm.Cid(), build.MessageConfidence, api.LookbackNoLimit, true) rec, err := client.StateWaitMsg(ctx, sm.Cid(), build.MessageConfidence, api.LookbackNoLimit, true)
require.NoError(t, err) require.NoError(t, err)
require.Zero(t, rec.Receipt.ExitCode, "dispute not accepted: %s", rec.Receipt.ExitCode.Error()) require.Zero(t, rec.Receipt.ExitCode, "dispute not accepted: %s", rec.Receipt.ExitCode.Error())
@ -246,7 +220,7 @@ func TestWindowPostDispute(t *testing.T) {
} }
// Now try to be evil again // Now try to be evil again
err = submitBadProof(ctx, client, evilMinerAddr, di, evilSectorLoc.Deadline, evilSectorLoc.Partition) err = submitBadProof(ctx, client, evilMiner.OwnerKey.Address, evilMinerAddr, di, evilSectorLoc.Deadline, evilSectorLoc.Partition)
require.Error(t, err) require.Error(t, err)
require.Contains(t, err.Error(), "message execution failed: exit 16, reason: window post failed: invalid PoSt") require.Contains(t, err.Error(), "message execution failed: exit 16, reason: window post failed: invalid PoSt")
@ -258,29 +232,16 @@ func TestWindowPostDisputeFails(t *testing.T) {
t.Skip("this takes a few minutes, set LOTUS_TEST_WINDOW_POST=1 to run") t.Skip("this takes a few minutes, set LOTUS_TEST_WINDOW_POST=1 to run")
} }
kit.QuietMiningLogs() kit2.QuietMiningLogs()
b := kit.MockMinerBuilder
blocktime := 2 * time.Millisecond blocktime := 2 * time.Millisecond
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
defer cancel() defer cancel()
n, sn := b(t, []kit.FullNodeOpts{kit.FullNodeWithLatestActorsAt(-1)}, kit.OneMiner) opts := kit2.ConstructorOpts(kit2.LatestActorsAt(-1))
client, miner, ens := kit2.EnsembleMinimal(t, kit2.MockProofs(), opts)
client := n[0].FullNode.(*impl.FullNodeAPI) ens.InterconnectAll().BeginMining(blocktime)
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)
}
}
defaultFrom, err := client.WalletDefaultAddress(ctx) defaultFrom, err := client.WalletDefaultAddress(ctx)
require.NoError(t, err) require.NoError(t, err)
@ -290,48 +251,21 @@ func TestWindowPostDisputeFails(t *testing.T) {
build.Clock.Sleep(time.Second) build.Clock.Sleep(time.Second)
// Mine with the _second_ node (the good one). miner.PledgeSectors(ctx, 10, 0, nil)
done := make(chan struct{})
go func() {
defer close(done)
for ctx.Err() == nil {
build.Clock.Sleep(blocktime)
if err := miner.MineOne(ctx, kit.MineNext); err != nil {
if ctx.Err() != nil {
// context was canceled, ignore the error.
return
}
t.Error(err)
}
}
}()
defer func() {
cancel()
<-done
}()
kit.PledgeSectors(t, ctx, miner, 10, 0, nil)
di, err := client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK) di, err := client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK)
require.NoError(t, err) require.NoError(t, err)
fmt.Printf("Running one proving period\n") t.Log("Running one proving period")
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)
for { ts := client.WaitTillChain(ctx, kit2.HeightAtLeast(waitUntil))
head, err := client.ChainHead(ctx) t.Logf("Now head.Height = %d", ts.Height())
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)
}
ssz, err := miner.ActorSectorSize(ctx, maddr) ssz, err := miner.ActorSectorSize(ctx, maddr)
require.NoError(t, err) require.NoError(t, err)
expectedPower := types.NewInt(uint64(ssz) * (kit.GenesisPreseals + 10)) expectedPower := types.NewInt(uint64(ssz) * (kit2.DefaultPresealsPerBootstrapMiner + 10))
p, err := client.StateMinerPower(ctx, maddr, types.EmptyTSK) p, err := client.StateMinerPower(ctx, maddr, types.EmptyTSK)
require.NoError(t, err) require.NoError(t, err)
@ -393,7 +327,7 @@ waitForProof:
func submitBadProof( func submitBadProof(
ctx context.Context, ctx context.Context,
client api.FullNode, maddr address.Address, client api.FullNode, owner address.Address, maddr address.Address,
di *dline.Info, dlIdx, partIdx uint64, di *dline.Info, dlIdx, partIdx uint64,
) error { ) error {
head, err := client.ChainHead(ctx) head, err := client.ChainHead(ctx)