Skip to content

Commit

Permalink
ensure we can't dispute a correct window post
Browse files Browse the repository at this point in the history
  • Loading branch information
Stebalien committed Jan 22, 2021
1 parent 735d30a commit 0a294f1
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 10 deletions.
148 changes: 138 additions & 10 deletions api/test/window_post.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import (
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors"
"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"
bminer "github.com/filecoin-project/lotus/miner"
"github.com/filecoin-project/lotus/node/impl"
Expand Down Expand Up @@ -747,7 +747,7 @@ func TestWindowPostDispute(t *testing.T, b APIBuilder, blocktime time.Duration)

// OBJECTION! The good miner files a DISPUTE!!!!
{
params := &miner.DisputeWindowedPoStParams{
params := &minerActor.DisputeWindowedPoStParams{
Deadline: evilSectorLoc.Deadline,
PoStIndex: 0,
}
Expand All @@ -757,7 +757,7 @@ func TestWindowPostDispute(t *testing.T, b APIBuilder, blocktime time.Duration)

msg := &types.Message{
To: evilMinerAddr,
Method: miner.Methods.DisputeWindowedPoSt,
Method: minerActor.Methods.DisputeWindowedPoSt,
Params: enc,
Value: types.NewInt(0),
From: defaultFrom,
Expand All @@ -769,7 +769,6 @@ func TestWindowPostDispute(t *testing.T, b APIBuilder, blocktime time.Duration)
rec, err := client.StateWaitMsg(ctx, sm.Cid(), build.MessageConfidence)
require.NoError(t, err)
require.Zero(t, rec.Receipt.ExitCode, "dispute not accepted: %s", rec.Receipt.ExitCode.Error())
fmt.Println("GASS!!!: ", rec.Receipt.GasUsed)
}

// Objection SUSTAINED!
Expand All @@ -787,8 +786,8 @@ func TestWindowPostDispute(t *testing.T, b APIBuilder, blocktime time.Duration)
minerInfo, err := client.StateMinerInfo(ctx, evilMinerAddr, types.EmptyTSK)
require.NoError(t, err)

params := &miner.DeclareFaultsRecoveredParams{
Recoveries: []miner.RecoveryDeclaration{{
params := &minerActor.DeclareFaultsRecoveredParams{
Recoveries: []minerActor.RecoveryDeclaration{{
Deadline: evilSectorLoc.Deadline,
Partition: evilSectorLoc.Partition,
Sectors: bitfield.NewFromSet([]uint64{uint64(evilSectorNo)}),
Expand All @@ -800,7 +799,7 @@ func TestWindowPostDispute(t *testing.T, b APIBuilder, blocktime time.Duration)

msg := &types.Message{
To: evilMinerAddr,
Method: miner.Methods.DeclareFaultsRecovered,
Method: minerActor.Methods.DeclareFaultsRecovered,
Params: enc,
Value: types.FromFil(30), // repay debt.
From: minerInfo.Owner,
Expand Down Expand Up @@ -859,11 +858,11 @@ func submitBadProof(
if err != nil {
return err
}
params := &miner.SubmitWindowedPoStParams{
params := &minerActor.SubmitWindowedPoStParams{
ChainCommitEpoch: commEpoch,
ChainCommitRand: commRand,
Deadline: dlIdx,
Partitions: []miner.PoStPartition{{Index: partIdx}},
Partitions: []minerActor.PoStPartition{{Index: partIdx}},
Proofs: []proof3.PoStProof{{
PoStProof: minerInfo.WindowPoStProofType,
ProofBytes: []byte("I'm soooo very evil."),
Expand All @@ -877,7 +876,7 @@ func submitBadProof(

msg := &types.Message{
To: maddr,
Method: miner.Methods.SubmitWindowedPoSt,
Method: minerActor.Methods.SubmitWindowedPoSt,
Params: enc,
Value: types.NewInt(0),
From: from,
Expand All @@ -896,3 +895,132 @@ func submitBadProof(
}
return nil
}

func TestWindowPostDisputeFails(t *testing.T, b APIBuilder, blocktime time.Duration) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

n, sn := b(t, []FullNodeOpts{FullNodeWithActorsV3At(2)}, OneMiner)

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)
}
}

defaultFrom, err := client.WalletDefaultAddress(ctx)
require.NoError(t, err)

maddr, err := miner.ActorAddress(ctx)
require.NoError(t, err)

build.Clock.Sleep(time.Second)

// Mine with the _second_ node (the good one).
done := make(chan struct{})
go func() {
defer close(done)
for ctx.Err() == nil {
build.Clock.Sleep(blocktime)
if err := miner.MineOne(ctx, MineNext); err != nil {
if ctx.Err() != nil {
// context was canceled, ignore the error.
return
}
t.Error(err)
}
}
}()
defer func() {
cancel()
<-done
}()

pledgeSectors(t, ctx, miner, 10, 0, nil)

di, err := client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK)
require.NoError(t, err)

fmt.Printf("Running one proving period\n")
fmt.Printf("End for head.Height > %d\n", di.PeriodStart+di.WPoStProvingPeriod*2)

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)
}

ssz, err := miner.ActorSectorSize(ctx, maddr)
require.NoError(t, err)
expectedPower := types.NewInt(uint64(ssz) * (GenesisPreseals + 10))

p, err := client.StateMinerPower(ctx, maddr, types.EmptyTSK)
require.NoError(t, err)

// make sure it has gained power.
require.Equal(t, p.MinerPower.RawBytePower, expectedPower)

// Wait until a proof has been submitted.
var targetDeadline uint64
waitForProof:
for {
deadlines, err := client.StateMinerDeadlines(ctx, maddr, types.EmptyTSK)
require.NoError(t, err)
for dlIdx, dl := range deadlines {
nonEmpty, err := dl.PostSubmissions.IsEmpty()
require.NoError(t, err)
if nonEmpty {
targetDeadline = uint64(dlIdx)
break waitForProof
}
}

build.Clock.Sleep(blocktime)
}

for {
di, err := client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK)
require.NoError(t, err)
// wait until the deadline finishes.
if di.Index == ((targetDeadline + 1) % di.WPoStPeriodDeadlines) {
break
}

build.Clock.Sleep(blocktime)
}

// Try to object to the proof. This should fail.
{
params := &minerActor.DisputeWindowedPoStParams{
Deadline: targetDeadline,
PoStIndex: 0,
}

enc, aerr := actors.SerializeParams(params)
require.NoError(t, aerr)

msg := &types.Message{
To: maddr,
Method: minerActor.Methods.DisputeWindowedPoSt,
Params: enc,
Value: types.NewInt(0),
From: defaultFrom,
}
_, err := client.MpoolPushMessage(ctx, msg, nil)
require.Error(t, err)
require.Contains(t, err.Error(), "failed to dispute valid post (RetCode=16)")
}
}
13 changes: 13 additions & 0 deletions node/node_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,3 +211,16 @@ func TestWindowPostDispute(t *testing.T) {

test.TestWindowPostDispute(t, builder.MockSbBuilder, 2*time.Millisecond)
}

func TestWindowPostDisputeFails(t *testing.T) {
if os.Getenv("LOTUS_TEST_WINDOW_POST") != "1" {
t.Skip("this takes a few minutes, set LOTUS_TEST_WINDOW_POST=1 to run")
}
logging.SetLogLevel("miner", "ERROR")
logging.SetLogLevel("chainstore", "ERROR")
logging.SetLogLevel("chain", "ERROR")
logging.SetLogLevel("sub", "ERROR")
logging.SetLogLevel("storageminer", "ERROR")

test.TestWindowPostDisputeFails(t, builder.MockSbBuilder, 2*time.Millisecond)
}

0 comments on commit 0a294f1

Please sign in to comment.