wip move MineUntilBlock under BlockMiner; other simplifications.

This commit is contained in:
Raúl Kripalani 2021-05-19 11:47:37 +01:00
parent 2a71c47397
commit 5d34c8b7da
14 changed files with 172 additions and 163 deletions

View File

@ -11,21 +11,26 @@ import (
lapi "github.com/filecoin-project/lotus/api" lapi "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"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/node/impl" "github.com/filecoin-project/lotus/node/impl"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
type testSuite struct {
makeNodes kit.APIBuilder
}
func TestAPI(t *testing.T) { func TestAPI(t *testing.T) {
runAPITest(t, Builder) runAPITest(t, kit.Builder)
} }
func TestAPIRPC(t *testing.T) { func TestAPIRPC(t *testing.T) {
runAPITest(t, RPCBuilder) runAPITest(t, kit.RPCBuilder)
} }
// runAPITest is the entry point to API test suite // runAPITest is the entry point to API test suite
func runAPITest(t *testing.T, b APIBuilder) { func runAPITest(t *testing.T, b kit.APIBuilder) {
ts := testSuite{ ts := testSuite{
makeNodes: b, makeNodes: b,
} }
@ -46,7 +51,7 @@ func (ts *testSuite) testVersion(t *testing.T) {
}) })
ctx := context.Background() ctx := context.Background()
apis, _ := ts.makeNodes(t, OneFull, OneMiner) apis, _ := ts.makeNodes(t, kit.OneFull, kit.OneMiner)
napi := apis[0] napi := apis[0]
v, err := napi.Version(ctx) v, err := napi.Version(ctx)
@ -61,7 +66,7 @@ func (ts *testSuite) testVersion(t *testing.T) {
} }
func (ts *testSuite) testSearchMsg(t *testing.T) { func (ts *testSuite) testSearchMsg(t *testing.T) {
apis, miners := ts.makeNodes(t, OneFull, OneMiner) apis, miners := ts.makeNodes(t, kit.OneFull, kit.OneMiner)
api := apis[0] api := apis[0]
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
@ -76,8 +81,8 @@ func (ts *testSuite) testSearchMsg(t *testing.T) {
To: senderAddr, To: senderAddr,
Value: big.Zero(), Value: big.Zero(),
} }
bm := NewBlockMiner(ctx, t, miners[0], 100*time.Millisecond) bm := kit.NewBlockMiner(t, miners[0])
bm.MineBlocks() bm.MineBlocks(ctx, 100*time.Millisecond)
defer bm.Stop() defer bm.Stop()
sm, err := api.MpoolPushMessage(ctx, msg, nil) sm, err := api.MpoolPushMessage(ctx, msg, nil)
@ -105,7 +110,7 @@ func (ts *testSuite) testSearchMsg(t *testing.T) {
func (ts *testSuite) testID(t *testing.T) { func (ts *testSuite) testID(t *testing.T) {
ctx := context.Background() ctx := context.Background()
apis, _ := ts.makeNodes(t, OneFull, OneMiner) apis, _ := ts.makeNodes(t, kit.OneFull, kit.OneMiner)
api := apis[0] api := apis[0]
id, err := api.ID(ctx) id, err := api.ID(ctx)
@ -117,7 +122,7 @@ func (ts *testSuite) testID(t *testing.T) {
func (ts *testSuite) testConnectTwo(t *testing.T) { func (ts *testSuite) testConnectTwo(t *testing.T) {
ctx := context.Background() ctx := context.Background()
apis, _ := ts.makeNodes(t, TwoFull, OneMiner) apis, _ := ts.makeNodes(t, kit.TwoFull, kit.OneMiner)
p, err := apis[0].NetPeers(ctx) p, err := apis[0].NetPeers(ctx)
if err != nil { if err != nil {
@ -163,8 +168,8 @@ func (ts *testSuite) testConnectTwo(t *testing.T) {
func (ts *testSuite) testMining(t *testing.T) { func (ts *testSuite) testMining(t *testing.T) {
ctx := context.Background() ctx := context.Background()
apis, sn := ts.makeNodes(t, OneFull, OneMiner) fulls, miners := ts.makeNodes(t, kit.OneFull, kit.OneMiner)
api := apis[0] api := fulls[0]
newHeads, err := api.ChainNotify(ctx) newHeads, err := api.ChainNotify(ctx)
require.NoError(t, err) require.NoError(t, err)
@ -175,7 +180,8 @@ func (ts *testSuite) testMining(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, int64(h1.Height()), int64(baseHeight)) require.Equal(t, int64(h1.Height()), int64(baseHeight))
MineUntilBlock(ctx, t, apis[0], sn[0], nil) bm := kit.NewBlockMiner(t, miners[0])
bm.MineUntilBlock(ctx, fulls[0], nil)
require.NoError(t, err) require.NoError(t, err)
<-newHeads <-newHeads
@ -192,8 +198,8 @@ func (ts *testSuite) testMiningReal(t *testing.T) {
}() }()
ctx := context.Background() ctx := context.Background()
apis, sn := ts.makeNodes(t, OneFull, OneMiner) fulls, miners := ts.makeNodes(t, kit.OneFull, kit.OneMiner)
api := apis[0] api := fulls[0]
newHeads, err := api.ChainNotify(ctx) newHeads, err := api.ChainNotify(ctx)
require.NoError(t, err) require.NoError(t, err)
@ -203,7 +209,9 @@ func (ts *testSuite) testMiningReal(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, int64(at), int64(h1.Height())) require.Equal(t, int64(at), int64(h1.Height()))
MineUntilBlock(ctx, t, apis[0], sn[0], nil) bm := kit.NewBlockMiner(t, miners[0])
bm.MineUntilBlock(ctx, fulls[0], nil)
require.NoError(t, err) require.NoError(t, err)
<-newHeads <-newHeads
@ -212,7 +220,7 @@ func (ts *testSuite) testMiningReal(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.Greater(t, int64(h2.Height()), int64(h1.Height())) require.Greater(t, int64(h2.Height()), int64(h1.Height()))
MineUntilBlock(ctx, t, apis[0], sn[0], nil) bm.MineUntilBlock(ctx, fulls[0], nil)
require.NoError(t, err) require.NoError(t, err)
<-newHeads <-newHeads
@ -224,11 +232,10 @@ func (ts *testSuite) testMiningReal(t *testing.T) {
func (ts *testSuite) testNonGenesisMiner(t *testing.T) { func (ts *testSuite) testNonGenesisMiner(t *testing.T) {
ctx := context.Background() ctx := context.Background()
n, sn := ts.makeNodes(t, []FullNodeOpts{ n, sn := ts.makeNodes(t,
FullNodeWithLatestActorsAt(-1), []kit.FullNodeOpts{kit.FullNodeWithLatestActorsAt(-1)},
}, []StorageMiner{ []kit.StorageMiner{{Full: 0, Preseal: kit.PresealGenesis}},
{Full: 0, Preseal: PresealGenesis}, )
})
full, ok := n[0].FullNode.(*impl.FullNodeAPI) full, ok := n[0].FullNode.(*impl.FullNodeAPI)
if !ok { if !ok {
@ -237,8 +244,8 @@ func (ts *testSuite) testNonGenesisMiner(t *testing.T) {
} }
genesisMiner := sn[0] genesisMiner := sn[0]
bm := NewBlockMiner(ctx, t, genesisMiner, 4*time.Millisecond) bm := kit.NewBlockMiner(t, genesisMiner)
bm.MineBlocks() bm.MineBlocks(ctx, 4*time.Millisecond)
t.Cleanup(bm.Stop) t.Cleanup(bm.Stop)
gaa, err := genesisMiner.ActorAddress(ctx) gaa, err := genesisMiner.ActorAddress(ctx)
@ -247,7 +254,7 @@ func (ts *testSuite) testNonGenesisMiner(t *testing.T) {
gmi, err := full.StateMinerInfo(ctx, gaa, types.EmptyTSK) gmi, err := full.StateMinerInfo(ctx, gaa, types.EmptyTSK)
require.NoError(t, err) require.NoError(t, err)
testm := n[0].Stb(ctx, t, TestSpt, gmi.Owner) testm := n[0].Stb(ctx, t, kit.TestSpt, gmi.Owner)
ta, err := testm.ActorAddress(ctx) ta, err := testm.ActorAddress(ctx)
require.NoError(t, err) require.NoError(t, err)

View File

@ -8,18 +8,19 @@ import (
"github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/miner" "github.com/filecoin-project/lotus/miner"
"github.com/stretchr/testify/require"
) )
// BlockMiner is a utility that makes a test miner Mine blocks on a timer. // BlockMiner is a utility that makes a test miner Mine blocks on a timer.
type BlockMiner struct { type BlockMiner struct {
t *testing.T t *testing.T
miner TestStorageNode miner TestMiner
nextNulls int64 nextNulls int64
stopCh chan chan struct{} stopCh chan chan struct{}
} }
func NewBlockMiner(t *testing.T, miner TestStorageNode) *BlockMiner { func NewBlockMiner(t *testing.T, miner TestMiner) *BlockMiner {
return &BlockMiner{ return &BlockMiner{
t: t, t: t,
miner: miner, miner: miner,
@ -59,6 +60,53 @@ func (bm *BlockMiner) InjectNulls(rounds abi.ChainEpoch) {
atomic.AddInt64(&bm.nextNulls, int64(rounds)) atomic.AddInt64(&bm.nextNulls, int64(rounds))
} }
func (bm *BlockMiner) MineUntilBlock(ctx context.Context, fn TestFullNode, cb func(abi.ChainEpoch)) {
for i := 0; i < 1000; i++ {
var (
success bool
err error
epoch abi.ChainEpoch
wait = make(chan struct{})
)
doneFn := func(win bool, ep abi.ChainEpoch, e error) {
success = win
err = e
epoch = ep
wait <- struct{}{}
}
mineErr := bm.miner.MineOne(ctx, miner.MineReq{Done: doneFn})
require.NoError(bm.t, mineErr)
<-wait
require.NoError(bm.t, err)
if success {
// Wait until it shows up on the given full nodes ChainHead
nloops := 50
for i := 0; i < nloops; i++ {
ts, err := fn.ChainHead(ctx)
require.NoError(bm.t, err)
if ts.Height() == epoch {
break
}
require.Equal(bm.t, i, nloops-1, "block never managed to sync to node")
time.Sleep(time.Millisecond * 10)
}
if cb != nil {
cb(epoch)
}
return
}
bm.t.Log("did not Mine block, trying again", i)
}
bm.t.Fatal("failed to Mine 1000 times in a row...")
}
// Stop stops the block miner. // Stop stops the block miner.
func (bm *BlockMiner) Stop() { func (bm *BlockMiner) Stop() {
bm.t.Log("shutting down mining") bm.t.Log("shutting down mining")

View File

@ -11,8 +11,6 @@ import (
"testing" "testing"
"time" "time"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/specs-actors/v2/actors/builtin" "github.com/filecoin-project/specs-actors/v2/actors/builtin"
@ -21,7 +19,7 @@ import (
) )
// RunClientTest exercises some of the Client CLI commands // RunClientTest exercises some of the Client CLI commands
func RunClientTest(t *testing.T, cmds []*lcli.Command, clientNode TestNode) { func RunClientTest(t *testing.T, cmds []*lcli.Command, clientNode TestFullNode) {
ctx, cancel := context.WithTimeout(context.Background(), time.Minute) ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel() defer cancel()
@ -38,7 +36,7 @@ func RunClientTest(t *testing.T, cmds []*lcli.Command, clientNode TestNode) {
fmt.Println("Miner:", minerAddr) fmt.Println("Miner:", minerAddr)
// Client query-ask <Miner addr> // Client query-ask <Miner addr>
out := clientCLI.RunCmd("Client", "query-ask", minerAddr.String()) out := clientCLI.RunCmd("client", "query-ask", minerAddr.String())
require.Regexp(t, regexp.MustCompile("Ask:"), out) require.Regexp(t, regexp.MustCompile("Ask:"), out)
// Create a deal (non-interactive) // Create a deal (non-interactive)
@ -90,7 +88,10 @@ func RunClientTest(t *testing.T, cmds []*lcli.Command, clientNode TestNode) {
} }
dealStatus = parts[3] dealStatus = parts[3]
fmt.Println(" Deal status:", dealStatus) fmt.Println(" Deal status:", dealStatus)
if dealComplete(t, dealStatus) {
st := CategorizeDealState(dealStatus)
require.NotEqual(t, TestDealStateFailed, st)
if st == TestDealStateComplete {
break break
} }
@ -106,14 +107,3 @@ func RunClientTest(t *testing.T, cmds []*lcli.Command, clientNode TestNode) {
fmt.Println("retrieve:\n", out) fmt.Println("retrieve:\n", out)
require.Regexp(t, regexp.MustCompile("Success"), out) require.Regexp(t, regexp.MustCompile("Success"), out)
} }
func dealComplete(t *testing.T, dealStatus string) bool {
switch dealStatus {
case "StorageDealFailing", "StorageDealError":
t.Fatal(xerrors.Errorf("Storage deal failed with status: " + dealStatus))
case "StorageDealStaged", "StorageDealAwaitingPreCommit", "StorageDealSealing", "StorageDealActive", "StorageDealExpired", "StorageDealSlashed":
return true
}
return false
}

View File

@ -29,7 +29,7 @@ import (
unixfile "github.com/ipfs/go-unixfs/file" unixfile "github.com/ipfs/go-unixfs/file"
) )
func MakeDeal(t *testing.T, ctx context.Context, rseed int, client api.FullNode, miner TestStorageNode, carExport, fastRet bool, startEpoch abi.ChainEpoch) { func MakeDeal(t *testing.T, ctx context.Context, rseed int, client api.FullNode, miner TestMiner, carExport, fastRet bool, startEpoch abi.ChainEpoch) {
res, data, err := CreateClientFile(ctx, client, rseed) res, data, err := CreateClientFile(ctx, client, rseed)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -73,7 +73,7 @@ func CreateClientFile(ctx context.Context, client api.FullNode, rseed int) (*api
return res, data, nil return res, data, nil
} }
func StartDeal(t *testing.T, ctx context.Context, miner TestStorageNode, client api.FullNode, fcid cid.Cid, fastRet bool, startEpoch abi.ChainEpoch) *cid.Cid { func StartDeal(t *testing.T, ctx context.Context, miner TestMiner, client api.FullNode, fcid cid.Cid, fastRet bool, startEpoch abi.ChainEpoch) *cid.Cid {
maddr, err := miner.ActorAddress(ctx) maddr, err := miner.ActorAddress(ctx)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -101,7 +101,7 @@ func StartDeal(t *testing.T, ctx context.Context, miner TestStorageNode, client
return deal return deal
} }
func WaitDealSealed(t *testing.T, ctx context.Context, miner TestStorageNode, client api.FullNode, deal *cid.Cid, noseal bool) { func WaitDealSealed(t *testing.T, ctx context.Context, miner TestMiner, client api.FullNode, deal *cid.Cid, noseal bool) {
loop: loop:
for { for {
di, err := client.ClientGetDealInfo(ctx, *deal) di, err := client.ClientGetDealInfo(ctx, *deal)
@ -129,7 +129,7 @@ loop:
} }
} }
func WaitDealPublished(t *testing.T, ctx context.Context, miner TestStorageNode, deal *cid.Cid) { func WaitDealPublished(t *testing.T, ctx context.Context, miner TestMiner, deal *cid.Cid) {
subCtx, cancel := context.WithCancel(ctx) subCtx, cancel := context.WithCancel(ctx)
defer cancel() defer cancel()
updates, err := miner.MarketGetDealUpdates(subCtx) updates, err := miner.MarketGetDealUpdates(subCtx)
@ -159,7 +159,7 @@ func WaitDealPublished(t *testing.T, ctx context.Context, miner TestStorageNode,
} }
} }
func StartSealingWaiting(t *testing.T, ctx context.Context, miner TestStorageNode) { func StartSealingWaiting(t *testing.T, ctx context.Context, miner TestMiner) {
snums, err := miner.SectorsList(ctx) snums, err := miner.SectorsList(ctx)
require.NoError(t, err) require.NoError(t, err)
@ -256,7 +256,7 @@ func ExtractCarData(t *testing.T, ctx context.Context, rdata []byte, rpath strin
type DealsScaffold struct { type DealsScaffold struct {
Ctx context.Context Ctx context.Context
Client *impl.FullNodeAPI Client *impl.FullNodeAPI
Miner TestStorageNode Miner TestMiner
BlockMiner *BlockMiner BlockMiner *BlockMiner
} }
@ -267,7 +267,7 @@ func SetupOneClientOneMiner(t *testing.T, b APIBuilder, blocktime time.Duration)
return ConnectAndStartMining(t, blocktime, client, miner) return ConnectAndStartMining(t, blocktime, client, miner)
} }
func ConnectAndStartMining(t *testing.T, blocktime time.Duration, client *impl.FullNodeAPI, miner TestStorageNode) *DealsScaffold { func ConnectAndStartMining(t *testing.T, blocktime time.Duration, client *impl.FullNodeAPI, miner TestMiner) *DealsScaffold {
ctx := context.Background() ctx := context.Background()
addrinfo, err := client.NetAddrsListen(ctx) addrinfo, err := client.NetAddrsListen(ctx)
if err != nil { if err != nil {
@ -289,3 +289,23 @@ func ConnectAndStartMining(t *testing.T, blocktime time.Duration, client *impl.F
BlockMiner: blockMiner, BlockMiner: blockMiner,
} }
} }
type TestDealState int
const (
TestDealStateFailed = TestDealState(-1)
TestDealStateInProgress = TestDealState(0)
TestDealStateComplete = TestDealState(1)
)
// CategorizeDealState categorizes deal states into one of three states:
// Complete, InProgress, Failed.
func CategorizeDealState(dealStatus string) TestDealState {
switch dealStatus {
case "StorageDealFailing", "StorageDealError":
return TestDealStateFailed
case "StorageDealStaged", "StorageDealAwaitingPreCommit", "StorageDealSealing", "StorageDealActive", "StorageDealExpired", "StorageDealSlashed":
return TestDealStateComplete
}
return TestDealStateInProgress
}

View File

@ -11,7 +11,7 @@ import (
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
) )
func SendFunds(ctx context.Context, t *testing.T, sender TestNode, addr address.Address, amount abi.TokenAmount) { func SendFunds(ctx context.Context, t *testing.T, sender TestFullNode, addr address.Address, amount abi.TokenAmount) {
senderAddr, err := sender.WalletDefaultAddress(ctx) senderAddr, err := sender.WalletDefaultAddress(ctx)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)

View File

@ -1,58 +0,0 @@
package kit
import (
"context"
"testing"
"time"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/miner"
)
func MineUntilBlock(ctx context.Context, t *testing.T, fn TestNode, sn TestStorageNode, cb func(abi.ChainEpoch)) {
for i := 0; i < 1000; i++ {
var success bool
var err error
var epoch abi.ChainEpoch
wait := make(chan struct{})
mineErr := sn.MineOne(ctx, miner.MineReq{
Done: func(win bool, ep abi.ChainEpoch, e error) {
success = win
err = e
epoch = ep
wait <- struct{}{}
},
})
if mineErr != nil {
t.Fatal(mineErr)
}
<-wait
if err != nil {
t.Fatal(err)
}
if success {
// Wait until it shows up on the given full nodes ChainHead
nloops := 50
for i := 0; i < nloops; i++ {
ts, err := fn.ChainHead(ctx)
if err != nil {
t.Fatal(err)
}
if ts.Height() == epoch {
break
}
if i == nloops-1 {
t.Fatal("block never managed to sync to node")
}
time.Sleep(time.Millisecond * 10)
}
if cb != nil {
cb(epoch)
}
return
}
t.Log("did not Mine block, trying again", i)
}
t.Fatal("failed to Mine 1000 times in a row...")
}

View File

@ -11,7 +11,7 @@ import (
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
) )
func StartOneNodeOneMiner(ctx context.Context, t *testing.T, blocktime time.Duration) (TestNode, address.Address) { func StartOneNodeOneMiner(ctx context.Context, t *testing.T, blocktime time.Duration) (TestFullNode, address.Address) {
n, sn := RPCMockSbBuilder(t, OneFull, OneMiner) n, sn := RPCMockSbBuilder(t, OneFull, OneMiner)
full := n[0] full := n[0]
@ -42,7 +42,7 @@ func StartOneNodeOneMiner(ctx context.Context, t *testing.T, blocktime time.Dura
return full, fullAddr return full, fullAddr
} }
func StartTwoNodesOneMiner(ctx context.Context, t *testing.T, blocktime time.Duration) ([]TestNode, []address.Address) { func StartTwoNodesOneMiner(ctx context.Context, t *testing.T, blocktime time.Duration) ([]TestFullNode, []address.Address) {
n, sn := RPCMockSbBuilder(t, TwoFull, OneMiner) n, sn := RPCMockSbBuilder(t, TwoFull, OneMiner)
fullNode1 := n[0] fullNode1 := n[0]

View File

@ -64,7 +64,7 @@ func init() {
messagepool.HeadChangeCoalesceMergeInterval = 100 * time.Nanosecond messagepool.HeadChangeCoalesceMergeInterval = 100 * time.Nanosecond
} }
func CreateTestStorageNode(ctx context.Context, t *testing.T, waddr address.Address, act address.Address, pk crypto.PrivKey, tnd TestNode, mn mocknet.Mocknet, opts node.Option) TestStorageNode { func CreateTestStorageNode(ctx context.Context, t *testing.T, waddr address.Address, act address.Address, pk crypto.PrivKey, tnd TestFullNode, mn mocknet.Mocknet, opts node.Option) TestMiner {
r := repo.NewMemory(nil) r := repo.NewMemory(nil)
lr, err := r.Lock(repo.StorageMiner) lr, err := r.Lock(repo.StorageMiner)
@ -153,11 +153,11 @@ func CreateTestStorageNode(ctx context.Context, t *testing.T, waddr address.Addr
} }
} }
return TestStorageNode{StorageMiner: minerapi, MineOne: mineOne, Stop: stop} return TestMiner{StorageMiner: minerapi, MineOne: mineOne, Stop: stop}
} }
func storageBuilder(parentNode TestNode, mn mocknet.Mocknet, opts node.Option) StorageBuilder { func storageBuilder(parentNode TestFullNode, mn mocknet.Mocknet, opts node.Option) StorageBuilder {
return func(ctx context.Context, t *testing.T, spt abi.RegisteredSealProof, owner address.Address) TestStorageNode { return func(ctx context.Context, t *testing.T, spt abi.RegisteredSealProof, owner address.Address) TestMiner {
pk, _, err := crypto.GenerateEd25519Key(rand.Reader) pk, _, err := crypto.GenerateEd25519Key(rand.Reader)
require.NoError(t, err) require.NoError(t, err)
@ -199,30 +199,30 @@ func storageBuilder(parentNode TestNode, mn mocknet.Mocknet, opts node.Option) S
} }
} }
func Builder(t *testing.T, fullOpts []FullNodeOpts, storage []StorageMiner) ([]TestNode, []TestStorageNode) { func Builder(t *testing.T, fullOpts []FullNodeOpts, storage []StorageMiner) ([]TestFullNode, []TestMiner) {
return mockBuilderOpts(t, fullOpts, storage, false) return mockBuilderOpts(t, fullOpts, storage, false)
} }
func MockSbBuilder(t *testing.T, fullOpts []FullNodeOpts, storage []StorageMiner) ([]TestNode, []TestStorageNode) { func MockSbBuilder(t *testing.T, fullOpts []FullNodeOpts, storage []StorageMiner) ([]TestFullNode, []TestMiner) {
return mockSbBuilderOpts(t, fullOpts, storage, false) return mockSbBuilderOpts(t, fullOpts, storage, false)
} }
func RPCBuilder(t *testing.T, fullOpts []FullNodeOpts, storage []StorageMiner) ([]TestNode, []TestStorageNode) { func RPCBuilder(t *testing.T, fullOpts []FullNodeOpts, storage []StorageMiner) ([]TestFullNode, []TestMiner) {
return mockBuilderOpts(t, fullOpts, storage, true) return mockBuilderOpts(t, fullOpts, storage, true)
} }
func RPCMockSbBuilder(t *testing.T, fullOpts []FullNodeOpts, storage []StorageMiner) ([]TestNode, []TestStorageNode) { func RPCMockSbBuilder(t *testing.T, fullOpts []FullNodeOpts, storage []StorageMiner) ([]TestFullNode, []TestMiner) {
return mockSbBuilderOpts(t, fullOpts, storage, true) return mockSbBuilderOpts(t, fullOpts, storage, true)
} }
func mockBuilderOpts(t *testing.T, fullOpts []FullNodeOpts, storage []StorageMiner, rpc bool) ([]TestNode, []TestStorageNode) { func mockBuilderOpts(t *testing.T, fullOpts []FullNodeOpts, storage []StorageMiner, rpc bool) ([]TestFullNode, []TestMiner) {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel) t.Cleanup(cancel)
mn := mocknet.New(ctx) mn := mocknet.New(ctx)
fulls := make([]TestNode, len(fullOpts)) fulls := make([]TestFullNode, len(fullOpts))
storers := make([]TestStorageNode, len(storage)) miners := make([]TestMiner, len(storage))
pk, _, err := crypto.GenerateEd25519Key(rand.Reader) pk, _, err := crypto.GenerateEd25519Key(rand.Reader)
require.NoError(t, err) require.NoError(t, err)
@ -342,17 +342,17 @@ func mockBuilderOpts(t *testing.T, fullOpts []FullNodeOpts, storage []StorageMin
if opts == nil { if opts == nil {
opts = node.Options() opts = node.Options()
} }
storers[i] = CreateTestStorageNode(ctx, t, wa, genMiner, pk, f, mn, opts) miners[i] = CreateTestStorageNode(ctx, t, wa, genMiner, pk, f, mn, opts)
if err := storers[i].StorageAddLocal(ctx, presealDirs[i]); err != nil { if err := miners[i].StorageAddLocal(ctx, presealDirs[i]); err != nil {
t.Fatalf("%+v", err) t.Fatalf("%+v", err)
} }
/* /*
sma := storers[i].StorageMiner.(*impl.StorageMinerAPI) sma := miners[i].StorageMiner.(*impl.StorageMinerAPI)
psd := presealDirs[i] psd := presealDirs[i]
*/ */
if rpc { if rpc {
storers[i] = storerRpc(t, storers[i]) miners[i] = storerRpc(t, miners[i])
} }
} }
@ -360,33 +360,35 @@ func mockBuilderOpts(t *testing.T, fullOpts []FullNodeOpts, storage []StorageMin
t.Fatal(err) t.Fatal(err)
} }
if len(storers) > 0 { if len(miners) > 0 {
// Mine 2 blocks to setup some CE stuff in some actors // Mine 2 blocks to setup some CE stuff in some actors
var wait sync.Mutex var wait sync.Mutex
wait.Lock() wait.Lock()
MineUntilBlock(ctx, t, fulls[0], storers[0], func(epoch abi.ChainEpoch) { bm := NewBlockMiner(t, miners[0])
bm.MineUntilBlock(ctx, fulls[0], func(epoch abi.ChainEpoch) {
wait.Unlock() wait.Unlock()
}) })
wait.Lock() wait.Lock()
MineUntilBlock(ctx, t, fulls[0], storers[0], func(epoch abi.ChainEpoch) { bm.MineUntilBlock(ctx, fulls[0], func(epoch abi.ChainEpoch) {
wait.Unlock() wait.Unlock()
}) })
wait.Lock() wait.Lock()
} }
return fulls, storers return fulls, miners
} }
func mockSbBuilderOpts(t *testing.T, fullOpts []FullNodeOpts, storage []StorageMiner, rpc bool) ([]TestNode, []TestStorageNode) { func mockSbBuilderOpts(t *testing.T, fullOpts []FullNodeOpts, storage []StorageMiner, rpc bool) ([]TestFullNode, []TestMiner) {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel) t.Cleanup(cancel)
mn := mocknet.New(ctx) mn := mocknet.New(ctx)
fulls := make([]TestNode, len(fullOpts)) fulls := make([]TestFullNode, len(fullOpts))
storers := make([]TestStorageNode, len(storage)) miners := make([]TestMiner, len(storage))
var genbuf bytes.Buffer var genbuf bytes.Buffer
@ -521,7 +523,7 @@ func mockSbBuilderOpts(t *testing.T, fullOpts []FullNodeOpts, storage []StorageM
if opts == nil { if opts == nil {
opts = node.Options() opts = node.Options()
} }
storers[i] = CreateTestStorageNode(ctx, t, genms[i].Worker, maddrs[i], pidKeys[i], f, mn, node.Options( miners[i] = CreateTestStorageNode(ctx, t, genms[i].Worker, maddrs[i], pidKeys[i], f, mn, node.Options(
node.Override(new(sectorstorage.SectorManager), func() (sectorstorage.SectorManager, error) { node.Override(new(sectorstorage.SectorManager), func() (sectorstorage.SectorManager, error) {
return mock.NewMockSectorMgr(sectors), nil return mock.NewMockSectorMgr(sectors), nil
}), }),
@ -531,7 +533,7 @@ func mockSbBuilderOpts(t *testing.T, fullOpts []FullNodeOpts, storage []StorageM
)) ))
if rpc { if rpc {
storers[i] = storerRpc(t, storers[i]) miners[i] = storerRpc(t, miners[i])
} }
} }
@ -539,25 +541,27 @@ func mockSbBuilderOpts(t *testing.T, fullOpts []FullNodeOpts, storage []StorageM
t.Fatal(err) t.Fatal(err)
} }
if len(storers) > 0 { bm := NewBlockMiner(t, miners[0])
if len(miners) > 0 {
// Mine 2 blocks to setup some CE stuff in some actors // Mine 2 blocks to setup some CE stuff in some actors
var wait sync.Mutex var wait sync.Mutex
wait.Lock() wait.Lock()
MineUntilBlock(ctx, t, fulls[0], storers[0], func(abi.ChainEpoch) { bm.MineUntilBlock(ctx, fulls[0], func(abi.ChainEpoch) {
wait.Unlock() wait.Unlock()
}) })
wait.Lock() wait.Lock()
MineUntilBlock(ctx, t, fulls[0], storers[0], func(abi.ChainEpoch) { bm.MineUntilBlock(ctx, fulls[0], func(abi.ChainEpoch) {
wait.Unlock() wait.Unlock()
}) })
wait.Lock() wait.Lock()
} }
return fulls, storers return fulls, miners
} }
func fullRpc(t *testing.T, nd TestNode) TestNode { func fullRpc(t *testing.T, nd TestFullNode) TestFullNode {
ma, listenAddr, err := CreateRPCServer(t, map[string]interface{}{ ma, listenAddr, err := CreateRPCServer(t, map[string]interface{}{
"/rpc/v1": nd, "/rpc/v1": nd,
"/rpc/v0": &v0api.WrapperV1Full{FullNode: nd}, "/rpc/v0": &v0api.WrapperV1Full{FullNode: nd},
@ -565,7 +569,7 @@ func fullRpc(t *testing.T, nd TestNode) TestNode {
require.NoError(t, err) require.NoError(t, err)
var stop func() var stop func()
var full TestNode var full TestFullNode
full.FullNode, stop, err = client.NewFullNodeRPCV1(context.Background(), listenAddr+"/rpc/v1", nil) full.FullNode, stop, err = client.NewFullNodeRPCV1(context.Background(), listenAddr+"/rpc/v1", nil)
require.NoError(t, err) require.NoError(t, err)
t.Cleanup(stop) t.Cleanup(stop)
@ -574,14 +578,14 @@ func fullRpc(t *testing.T, nd TestNode) TestNode {
return full return full
} }
func storerRpc(t *testing.T, nd TestStorageNode) TestStorageNode { func storerRpc(t *testing.T, nd TestMiner) TestMiner {
ma, listenAddr, err := CreateRPCServer(t, map[string]interface{}{ ma, listenAddr, err := CreateRPCServer(t, map[string]interface{}{
"/rpc/v0": nd, "/rpc/v0": nd,
}) })
require.NoError(t, err) require.NoError(t, err)
var stop func() var stop func()
var storer TestStorageNode var storer TestMiner
storer.StorageMiner, stop, err = client.NewStorageMinerRPCV0(context.Background(), listenAddr+"/rpc/v0", nil) storer.StorageMiner, stop, err = client.NewStorageMinerRPCV0(context.Background(), listenAddr+"/rpc/v0", nil)
require.NoError(t, err) require.NoError(t, err)
t.Cleanup(stop) t.Cleanup(stop)

View File

@ -14,7 +14,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func PledgeSectors(t *testing.T, ctx context.Context, miner TestStorageNode, n, existing int, blockNotif <-chan struct{}) { func PledgeSectors(t *testing.T, ctx context.Context, miner TestMiner, n, existing int, blockNotif <-chan struct{}) {
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
if i%3 == 0 && blockNotif != nil { if i%3 == 0 && blockNotif != nil {
<-blockNotif <-blockNotif

View File

@ -30,9 +30,9 @@ func init() {
build.InsecurePoStValidation = true build.InsecurePoStValidation = true
} }
type StorageBuilder func(context.Context, *testing.T, abi.RegisteredSealProof, address.Address) TestStorageNode type StorageBuilder func(context.Context, *testing.T, abi.RegisteredSealProof, address.Address) TestMiner
type TestNode struct { type TestFullNode struct {
v1api.FullNode v1api.FullNode
// ListenAddr is the address on which an API server is listening, if an // ListenAddr is the address on which an API server is listening, if an
// API server is created for this Node // API server is created for this Node
@ -41,7 +41,7 @@ type TestNode struct {
Stb StorageBuilder Stb StorageBuilder
} }
type TestStorageNode struct { type TestMiner struct {
lapi.StorageMiner lapi.StorageMiner
// ListenAddr is the address on which an API server is listening, if an // ListenAddr is the address on which an API server is listening, if an
// API server is created for this Node // API server is created for this Node
@ -64,7 +64,7 @@ type StorageMiner struct {
Preseal int Preseal int
} }
type OptionGenerator func([]TestNode) node.Option type OptionGenerator func([]TestFullNode) node.Option
// Options for setting up a mock full node // Options for setting up a mock full node
type FullNodeOpts struct { type FullNodeOpts struct {
@ -78,16 +78,13 @@ type FullNodeOpts struct {
// fullOpts array defines options for each full node // fullOpts array defines options for each full node
// storage array defines storage nodes, numbers in the array specify full node // storage array defines storage nodes, numbers in the array specify full node
// index the storage node 'belongs' to // index the storage node 'belongs' to
type APIBuilder func(t *testing.T, full []FullNodeOpts, storage []StorageMiner) ([]TestNode, []TestStorageNode) type APIBuilder func(t *testing.T, full []FullNodeOpts, storage []StorageMiner) ([]TestFullNode, []TestMiner)
type testSuite struct {
makeNodes APIBuilder
}
func DefaultFullOpts(nFull int) []FullNodeOpts { func DefaultFullOpts(nFull int) []FullNodeOpts {
full := make([]FullNodeOpts, nFull) full := make([]FullNodeOpts, nFull)
for i := range full { for i := range full {
full[i] = FullNodeOpts{ full[i] = FullNodeOpts{
Opts: func(nodes []TestNode) node.Option { Opts: func(nodes []TestFullNode) node.Option {
return node.Options() return node.Options()
}, },
} }
@ -105,7 +102,7 @@ var FullNodeWithLatestActorsAt = func(upgradeHeight abi.ChainEpoch) FullNodeOpts
} }
return FullNodeOpts{ return FullNodeOpts{
Opts: func(nodes []TestNode) node.Option { Opts: func(nodes []TestFullNode) node.Option {
return node.Override(new(stmgr.UpgradeSchedule), stmgr.UpgradeSchedule{{ return node.Override(new(stmgr.UpgradeSchedule), stmgr.UpgradeSchedule{{
// prepare for upgrade. // prepare for upgrade.
Network: network.Version9, Network: network.Version9,
@ -126,7 +123,7 @@ var FullNodeWithLatestActorsAt = func(upgradeHeight abi.ChainEpoch) FullNodeOpts
var FullNodeWithSDRAt = func(calico, persian abi.ChainEpoch) FullNodeOpts { var FullNodeWithSDRAt = func(calico, persian abi.ChainEpoch) FullNodeOpts {
return FullNodeOpts{ return FullNodeOpts{
Opts: func(nodes []TestNode) node.Option { Opts: func(nodes []TestFullNode) node.Option {
return node.Override(new(stmgr.UpgradeSchedule), stmgr.UpgradeSchedule{{ return node.Override(new(stmgr.UpgradeSchedule), stmgr.UpgradeSchedule{{
Network: network.Version6, Network: network.Version6,
Height: 1, Height: 1,

View File

@ -12,20 +12,21 @@ import (
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/cli" "github.com/filecoin-project/lotus/cli"
"github.com/filecoin-project/lotus/itests/kit"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
// TestMultisig does a basic test to exercise the multisig CLI commands // TestMultisig does a basic test to exercise the multisig CLI commands
func TestMultisig(t *testing.T) { func TestMultisig(t *testing.T) {
_ = os.Setenv("BELLMAN_NO_GPU", "1") _ = os.Setenv("BELLMAN_NO_GPU", "1")
harness.QuietMiningLogs() kit.QuietMiningLogs()
blocktime := 5 * time.Millisecond blocktime := 5 * time.Millisecond
ctx := context.Background() ctx := context.Background()
clientNode, _ := StartOneNodeOneMiner(ctx, t, blocktime) clientNode, _ := kit.StartOneNodeOneMiner(ctx, t, blocktime)
// Create mock CLI // Create mock CLI
mockCLI := NewMockCLI(ctx, t, cli.Commands) mockCLI := kit.NewMockCLI(ctx, t, cli.Commands)
clientCLI := mockCLI.Client(clientNode.ListenAddr) clientCLI := mockCLI.Client(clientNode.ListenAddr)
// Create some wallets on the node to use for testing multisig // Create some wallets on the node to use for testing multisig
@ -36,7 +37,7 @@ func TestMultisig(t *testing.T) {
walletAddrs = append(walletAddrs, addr) walletAddrs = append(walletAddrs, addr)
SendFunds(ctx, t, clientNode, addr, types.NewInt(1e15)) kit.SendFunds(ctx, t, clientNode, addr, types.NewInt(1e15))
} }
// Create an msig with three of the addresses and threshold of two sigs // Create an msig with three of the addresses and threshold of two sigs

View File

@ -268,7 +268,7 @@ func TestPaymentChannelsAPI(t *testing.T) {
bm.Stop() bm.Stop()
} }
func waitForBlocks(ctx context.Context, t *testing.T, bm *kit.BlockMiner, paymentReceiver kit.TestNode, receiverAddr address.Address, count int) { func waitForBlocks(ctx context.Context, t *testing.T, bm *kit.BlockMiner, paymentReceiver kit.TestFullNode, receiverAddr address.Address, count int) {
// We need to add null blocks in batches, if we add too many the chain can't sync // We need to add null blocks in batches, if we add too many the chain can't sync
batchSize := 60 batchSize := 60
for i := 0; i < count; i += batchSize { for i := 0; i < count; i += batchSize {
@ -297,7 +297,7 @@ func waitForBlocks(ctx context.Context, t *testing.T, bm *kit.BlockMiner, paymen
} }
} }
func waitForMessage(ctx context.Context, t *testing.T, paymentCreator kit.TestNode, msgCid cid.Cid, duration time.Duration, desc string) *api.MsgLookup { func waitForMessage(ctx context.Context, t *testing.T, paymentCreator kit.TestFullNode, msgCid cid.Cid, duration time.Duration, desc string) *api.MsgLookup {
ctx, cancel := context.WithTimeout(ctx, duration) ctx, cancel := context.WithTimeout(ctx, duration)
defer cancel() defer cancel()

View File

@ -378,7 +378,7 @@ func checkVoucherOutput(t *testing.T, list string, vouchers []voucherSpec) {
} }
// waitForHeight waits for the node to reach the given chain epoch // waitForHeight waits for the node to reach the given chain epoch
func waitForHeight(ctx context.Context, t *testing.T, node kit.TestNode, height abi.ChainEpoch) { func waitForHeight(ctx context.Context, t *testing.T, node kit.TestFullNode, height abi.ChainEpoch) {
atHeight := make(chan struct{}) atHeight := make(chan struct{})
chainEvents := events.NewEvents(ctx, node) chainEvents := events.NewEvents(ctx, node)
err := chainEvents.ChainAt(func(ctx context.Context, ts *types.TipSet, curH abi.ChainEpoch) error { err := chainEvents.ChainAt(func(ctx context.Context, ts *types.TipSet, curH abi.ChainEpoch) error {
@ -396,7 +396,7 @@ func waitForHeight(ctx context.Context, t *testing.T, node kit.TestNode, height
} }
// getPaychState gets the state of the payment channel with the given address // getPaychState gets the state of the payment channel with the given address
func getPaychState(ctx context.Context, t *testing.T, node kit.TestNode, chAddr address.Address) paych.State { func getPaychState(ctx context.Context, t *testing.T, node kit.TestFullNode, chAddr address.Address) paych.State {
act, err := node.StateGetActor(ctx, chAddr, types.EmptyTSK) act, err := node.StateGetActor(ctx, chAddr, types.EmptyTSK)
require.NoError(t, err) require.NoError(t, err)

View File

@ -44,7 +44,7 @@ func testTapeFix(t *testing.T, b kit.APIBuilder, blocktime time.Duration, after
}) })
} }
n, sn := b(t, []kit.FullNodeOpts{{Opts: func(_ []kit.TestNode) node.Option { n, sn := b(t, []kit.FullNodeOpts{{Opts: func(_ []kit.TestFullNode) node.Option {
return node.Override(new(stmgr.UpgradeSchedule), upgradeSchedule) return node.Override(new(stmgr.UpgradeSchedule), upgradeSchedule)
}}}, kit.OneMiner) }}}, kit.OneMiner)