feat: add end-to-end test for lite mode
This commit is contained in:
@@ -264,6 +264,7 @@ func Online() Option {
|
||||
Override(new(*stmgr.StateManager), stmgr.NewStateManagerWithUpgradeSchedule),
|
||||
Override(new(stmgr.StateManagerAPI), From(new(*stmgr.StateManager))),
|
||||
Override(new(*wallet.Wallet), wallet.NewWallet),
|
||||
Override(new(messagesigner.MpoolNonceAPI), From(new(*messagepool.MessagePool))),
|
||||
Override(new(*messagesigner.MessageSigner), messagesigner.NewMessageSigner),
|
||||
|
||||
Override(new(full.ChainModuleAPI), From(new(full.ChainModule))),
|
||||
@@ -401,6 +402,23 @@ func StorageMiner(out *api.StorageMiner) Option {
|
||||
)
|
||||
}
|
||||
|
||||
func LiteModeOverrides(gapi api.GatewayAPI) Option {
|
||||
return Options(
|
||||
Override(new(messagesigner.MpoolNonceAPI), From(new(modules.MpoolNonceAPI))),
|
||||
Override(new(api.GatewayAPI), gapi),
|
||||
Override(new(full.ChainModuleAPI), From(new(api.GatewayAPI))),
|
||||
Override(new(full.GasModuleAPI), From(new(api.GatewayAPI))),
|
||||
Override(new(full.MpoolModuleAPI), From(new(api.GatewayAPI))),
|
||||
Override(new(full.StateModuleAPI), From(new(api.GatewayAPI))),
|
||||
Override(new(stmgr.StateManagerAPI), modules.NewRPCStateManager),
|
||||
Unset(RunHelloKey),
|
||||
Unset(RunChainExchangeKey),
|
||||
Unset(RunPeerMgrKey),
|
||||
Unset(HandleIncomingBlocksKey),
|
||||
Unset(HandleIncomingMessagesKey),
|
||||
)
|
||||
}
|
||||
|
||||
// Config sets up constructors based on the provided Config
|
||||
func ConfigCommon(cfg *config.Common) Option {
|
||||
return Options(
|
||||
|
||||
@@ -180,7 +180,7 @@ func (a *MpoolAPI) MpoolPushMessage(ctx context.Context, msg *types.Message, spe
|
||||
|
||||
// Sign and push the message
|
||||
return a.MessageSigner.SignMessage(ctx, msg, func(smsg *types.SignedMessage) error {
|
||||
if _, err := a.Mpool.Push(smsg); err != nil {
|
||||
if _, err := a.MpoolModuleAPI.MpoolPush(ctx, smsg); err != nil {
|
||||
return xerrors.Errorf("mpool push: failed to push message: %w", err)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package modules
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.uber.org/fx"
|
||||
|
||||
"github.com/filecoin-project/lotus/node/impl/full"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/messagesigner"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
)
|
||||
|
||||
// MpoolNonceAPI substitutes the mpool nonce with an implementation that
|
||||
// doesn't rely on the mpool - it just gets the nonce from actor state
|
||||
type MpoolNonceAPI struct {
|
||||
fx.In
|
||||
|
||||
StateAPI full.StateAPI
|
||||
}
|
||||
|
||||
// GetNonce gets the nonce from actor state
|
||||
func (a *MpoolNonceAPI) GetNonce(addr address.Address) (uint64, error) {
|
||||
act, err := a.StateAPI.StateGetActor(context.Background(), addr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return act.Nonce, nil
|
||||
}
|
||||
|
||||
var _ messagesigner.MpoolNonceAPI = (*MpoolNonceAPI)(nil)
|
||||
+98
-56
@@ -7,10 +7,13 @@ import (
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-jsonrpc"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
@@ -117,6 +120,7 @@ func CreateTestStorageNode(ctx context.Context, t *testing.T, waddr address.Addr
|
||||
if err != nil {
|
||||
t.Fatalf("failed to construct node: %v", err)
|
||||
}
|
||||
|
||||
t.Cleanup(func() { _ = stop(context.Background()) })
|
||||
|
||||
/*// Bootstrap with full node
|
||||
@@ -137,13 +141,33 @@ func CreateTestStorageNode(ctx context.Context, t *testing.T, waddr address.Addr
|
||||
return test.TestStorageNode{StorageMiner: minerapi, MineOne: mineOne}
|
||||
}
|
||||
|
||||
func Builder(t *testing.T, nFull int, storage []test.StorageMiner, opts ...node.Option) ([]test.TestNode, []test.TestStorageNode) {
|
||||
func Builder(t *testing.T, fullOpts []test.OptionGenerator, storage []test.StorageMiner, opts ...node.Option) ([]test.TestNode, []test.TestStorageNode) {
|
||||
return mockBuilderOpts(t, fullOpts, storage, opts, false)
|
||||
}
|
||||
|
||||
func MockSbBuilder(t *testing.T, fullOpts []test.OptionGenerator, storage []test.StorageMiner, opts ...node.Option) ([]test.TestNode, []test.TestStorageNode) {
|
||||
return mockSbBuilderOpts(t, fullOpts, storage, opts, false)
|
||||
}
|
||||
|
||||
func RPCBuilder(t *testing.T, fullOpts []test.OptionGenerator, storage []test.StorageMiner, opts ...node.Option) ([]test.TestNode, []test.TestStorageNode) {
|
||||
return mockBuilderOpts(t, fullOpts, storage, opts, true)
|
||||
}
|
||||
|
||||
func RPCMockSbBuilder(t *testing.T, fullOpts []test.OptionGenerator, storage []test.StorageMiner) ([]test.TestNode, []test.TestStorageNode) {
|
||||
return mockSbBuilderOpts(t, fullOpts, storage, []node.Option{}, true)
|
||||
}
|
||||
|
||||
func RPCMockSbBuilderWithOpts(t *testing.T, fullOpts []test.OptionGenerator, storage []test.StorageMiner) ([]test.TestNode, []test.TestStorageNode) {
|
||||
return mockSbBuilderOpts(t, fullOpts, storage, []node.Option{}, true)
|
||||
}
|
||||
|
||||
func mockBuilderOpts(t *testing.T, fullOpts []test.OptionGenerator, storage []test.StorageMiner, opts []node.Option, rpc bool) ([]test.TestNode, []test.TestStorageNode) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
t.Cleanup(cancel)
|
||||
|
||||
mn := mocknet.New(ctx)
|
||||
|
||||
fulls := make([]test.TestNode, nFull)
|
||||
fulls := make([]test.TestNode, len(fullOpts))
|
||||
storers := make([]test.TestStorageNode, len(storage))
|
||||
|
||||
pk, _, err := crypto.GenerateEd25519Key(rand.Reader)
|
||||
@@ -208,7 +232,7 @@ func Builder(t *testing.T, nFull int, storage []test.StorageMiner, opts ...node.
|
||||
|
||||
// END PRESEAL SECTION
|
||||
|
||||
for i := 0; i < nFull; i++ {
|
||||
for i := 0; i < len(fullOpts); i++ {
|
||||
var genesis node.Option
|
||||
if i == 0 {
|
||||
genesis = node.Override(new(modules.Genesis), testing2.MakeGenesisMem(&genbuf, *templ))
|
||||
@@ -224,12 +248,18 @@ func Builder(t *testing.T, nFull int, storage []test.StorageMiner, opts ...node.
|
||||
node.Test(),
|
||||
|
||||
genesis,
|
||||
fullOpts[i](fulls),
|
||||
node.Options(opts...),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
t.Cleanup(func() { _ = stop(context.Background()) })
|
||||
|
||||
if rpc {
|
||||
fulls[i] = fullRpc(t, fulls[i])
|
||||
}
|
||||
}
|
||||
|
||||
for i, def := range storage {
|
||||
@@ -261,6 +291,9 @@ func Builder(t *testing.T, nFull int, storage []test.StorageMiner, opts ...node.
|
||||
|
||||
psd := presealDirs[i]
|
||||
*/
|
||||
if rpc {
|
||||
storers[i] = storerRpc(t, storers[i])
|
||||
}
|
||||
}
|
||||
|
||||
if err := mn.LinkAll(); err != nil {
|
||||
@@ -286,11 +319,13 @@ func Builder(t *testing.T, nFull int, storage []test.StorageMiner, opts ...node.
|
||||
return fulls, storers
|
||||
}
|
||||
|
||||
func MockSbBuilder(t *testing.T, nFull int, storage []test.StorageMiner, options ...node.Option) ([]test.TestNode, []test.TestStorageNode) {
|
||||
ctx := context.Background()
|
||||
func mockSbBuilderOpts(t *testing.T, fullOpts []test.OptionGenerator, storage []test.StorageMiner, options []node.Option, rpc bool) ([]test.TestNode, []test.TestStorageNode) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
t.Cleanup(cancel)
|
||||
|
||||
mn := mocknet.New(ctx)
|
||||
|
||||
fulls := make([]test.TestNode, nFull)
|
||||
fulls := make([]test.TestNode, len(fullOpts))
|
||||
storers := make([]test.TestStorageNode, len(storage))
|
||||
|
||||
var genbuf bytes.Buffer
|
||||
@@ -354,7 +389,7 @@ func MockSbBuilder(t *testing.T, nFull int, storage []test.StorageMiner, options
|
||||
|
||||
// END PRESEAL SECTION
|
||||
|
||||
for i := 0; i < nFull; i++ {
|
||||
for i := 0; i < len(fullOpts); i++ {
|
||||
var genesis node.Option
|
||||
if i == 0 {
|
||||
genesis = node.Override(new(modules.Genesis), testing2.MakeGenesisMem(&genbuf, *templ))
|
||||
@@ -374,12 +409,18 @@ func MockSbBuilder(t *testing.T, nFull int, storage []test.StorageMiner, options
|
||||
node.Override(new(ffiwrapper.Verifier), mock.MockVerifier),
|
||||
|
||||
genesis,
|
||||
fullOpts[i](fulls),
|
||||
node.Options(options...),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("%+v", err)
|
||||
}
|
||||
|
||||
t.Cleanup(func() { _ = stop(context.Background()) })
|
||||
|
||||
if rpc {
|
||||
fulls[i] = fullRpc(t, fulls[i])
|
||||
}
|
||||
}
|
||||
|
||||
for i, def := range storage {
|
||||
@@ -414,6 +455,10 @@ func MockSbBuilder(t *testing.T, nFull int, storage []test.StorageMiner, options
|
||||
node.Override(new(ffiwrapper.Verifier), mock.MockVerifier),
|
||||
node.Unset(new(*sectorstorage.Manager)),
|
||||
))
|
||||
|
||||
if rpc {
|
||||
storers[i] = storerRpc(t, storers[i])
|
||||
}
|
||||
}
|
||||
|
||||
if err := mn.LinkAll(); err != nil {
|
||||
@@ -438,69 +483,66 @@ func MockSbBuilder(t *testing.T, nFull int, storage []test.StorageMiner, options
|
||||
return fulls, storers
|
||||
}
|
||||
|
||||
func RPCBuilder(t *testing.T, nFull int, storage []test.StorageMiner, opts ...node.Option) ([]test.TestNode, []test.TestStorageNode) {
|
||||
return rpcWithBuilder(t, Builder, nFull, storage, opts...)
|
||||
func fullRpc(t *testing.T, nd test.TestNode) test.TestNode {
|
||||
ma, listenAddr, err := CreateRPCServer(nd)
|
||||
require.NoError(t, err)
|
||||
|
||||
var full test.TestNode
|
||||
full.FullNode, _, err = client.NewFullNodeRPC(context.Background(), listenAddr, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
full.ListenAddr = ma
|
||||
return full
|
||||
}
|
||||
|
||||
func RPCMockSbBuilder(t *testing.T, nFull int, storage []test.StorageMiner, opts ...node.Option) ([]test.TestNode, []test.TestStorageNode) {
|
||||
return rpcWithBuilder(t, MockSbBuilder, nFull, storage, opts...)
|
||||
func storerRpc(t *testing.T, nd test.TestStorageNode) test.TestStorageNode {
|
||||
ma, listenAddr, err := CreateRPCServer(nd)
|
||||
require.NoError(t, err)
|
||||
|
||||
var storer test.TestStorageNode
|
||||
storer.StorageMiner, _, err = client.NewStorageMinerRPC(context.Background(), listenAddr, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
storer.ListenAddr = ma
|
||||
storer.MineOne = nd.MineOne
|
||||
return storer
|
||||
}
|
||||
|
||||
func rpcWithBuilder(t *testing.T, b test.APIBuilder, nFull int, storage []test.StorageMiner, opts ...node.Option) ([]test.TestNode, []test.TestStorageNode) {
|
||||
fullApis, storaApis := b(t, nFull, storage, opts...)
|
||||
fulls := make([]test.TestNode, nFull)
|
||||
storers := make([]test.TestStorageNode, len(storage))
|
||||
func CreateRPCServer(handler interface{}) (multiaddr.Multiaddr, string, error) {
|
||||
rpcServer := jsonrpc.NewServer()
|
||||
rpcServer.Register("Filecoin", handler)
|
||||
testServ := httptest.NewServer(rpcServer) // todo: close
|
||||
|
||||
for i, a := range fullApis {
|
||||
rpcServer := jsonrpc.NewServer()
|
||||
rpcServer.Register("Filecoin", a)
|
||||
testServ := httptest.NewServer(rpcServer) // todo: close
|
||||
|
||||
addr := testServ.Listener.Addr()
|
||||
listenAddr := "ws://" + addr.String()
|
||||
var err error
|
||||
fulls[i].FullNode, _, err = client.NewFullNodeRPC(context.Background(), listenAddr, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ma, err := parseWSSMultiAddr(addr)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
fulls[i].ListenAddr = ma
|
||||
addr := testServ.Listener.Addr()
|
||||
listenAddr := "ws://" + addr.String()
|
||||
ma, err := parseWSMultiAddr(addr)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
for i, a := range storaApis {
|
||||
rpcServer := jsonrpc.NewServer()
|
||||
rpcServer.Register("Filecoin", a)
|
||||
testServ := httptest.NewServer(rpcServer) // todo: close
|
||||
|
||||
addr := testServ.Listener.Addr()
|
||||
listenAddr := "ws://" + addr.String()
|
||||
var err error
|
||||
storers[i].StorageMiner, _, err = client.NewStorageMinerRPC(context.Background(), listenAddr, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ma, err := parseWSSMultiAddr(addr)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
storers[i].ListenAddr = ma
|
||||
storers[i].MineOne = a.MineOne
|
||||
}
|
||||
|
||||
return fulls, storers
|
||||
return ma, listenAddr, err
|
||||
}
|
||||
|
||||
func parseWSSMultiAddr(addr net.Addr) (multiaddr.Multiaddr, error) {
|
||||
func parseWSMultiAddr(addr net.Addr) (multiaddr.Multiaddr, error) {
|
||||
host, port, err := net.SplitHostPort(addr.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ma, err := multiaddr.NewMultiaddr("/ip4/" + host + "/" + addr.Network() + "/" + port + "/wss")
|
||||
ma, err := multiaddr.NewMultiaddr("/ip4/" + host + "/" + addr.Network() + "/" + port + "/ws")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ma, nil
|
||||
}
|
||||
|
||||
func WSMultiAddrToString(addr multiaddr.Multiaddr) (string, error) {
|
||||
parts := strings.Split(addr.String(), "/")
|
||||
if len(parts) != 6 || parts[0] != "" {
|
||||
return "", xerrors.Errorf("Malformed ws multiaddr %s", addr)
|
||||
}
|
||||
|
||||
host := parts[2]
|
||||
port := parts[4]
|
||||
proto := parts[5]
|
||||
|
||||
return proto + "://" + host + ":" + port + "/rpc/v0", nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user