lotus/itests/kit/node_full.go

219 lines
5.3 KiB
Go
Raw Normal View History

2021-06-18 18:45:29 +00:00
package kit
import (
"bytes"
"context"
"fmt"
"testing"
"time"
libp2pcrypto "github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/peer"
2022-06-14 15:00:51 +00:00
"github.com/multiformats/go-multiaddr"
"github.com/stretchr/testify/require"
cbg "github.com/whyrusleeping/cbor-gen"
test: actors: manual CC onboarding and proving integration test (#12017) * remove client CLI * remove markets CLI from miner * remove markets from all CLI * remove client API * update go mod * remove EnableMarkets flag * remove market subsystem * remove dagstore * remove index provider * remove graphsync and data-transfer * remove markets * go mod tidy * fix cbor gen deps * remove deal making from config * remove eol alert * go mod tidy * changes as per review * make jen * changes as per review * test: actors: manual CC onboarding and proving integration test * test: actors: manual CC onboarding itest with real proofs * test: actors: fix lint issue, require proofs in CI * test: actors: rename real proofs test, fix dispute window wait * feat: add TestUnmanagedMiner in the itest kit for non-storage managed miners * feat: test: improve UnmanagedMiner test harness * feat: test: MineBlocksMustPost can watch for >1 miners (#12063) * feat: test: MineBlocksMustPost can watch for >1 miners * feat: test: wait for both sectors at the end of test * feat: test: minor manual onboarding test fixups and speed up * feat: test: handle case where miners have close deadline ends * Implement snap deals test for manual sector onboarding (#12066) * changes as per review * thread safety * test for snap deals * remove extraneous change * Apply suggestions from code review Co-authored-by: Rod Vagg <rod@vagg.org> * cancel CC Post after snap deals --------- Co-authored-by: Rod Vagg <rod@vagg.org> * fix config --------- Co-authored-by: aarshkshah1992 <aarshkshah1992@gmail.com>
2024-06-06 04:47:25 +00:00
"golang.org/x/xerrors"
2022-06-14 15:00:51 +00:00
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/exitcode"
2022-06-14 15:00:51 +00:00
"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/key"
2022-09-27 16:08:04 +00:00
cliutil "github.com/filecoin-project/lotus/cli/util"
2023-01-26 14:20:49 +00:00
"github.com/filecoin-project/lotus/gateway"
"github.com/filecoin-project/lotus/node"
)
type Libp2p struct {
PeerID peer.ID
PrivKey libp2pcrypto.PrivKey
}
// TestFullNode represents a full node enrolled in an Ensemble.
type TestFullNode struct {
v1api.FullNode
t *testing.T
// ListenAddr is the address on which an API server is listening, if an
// API server is created for this Node.
ListenAddr multiaddr.Multiaddr
2022-11-07 15:14:56 +00:00
ListenURL string
DefaultKey *key.Key
Pkey *Libp2p
Stop node.StopFunc
2023-01-26 14:20:49 +00:00
// gateway handler makes it convenient to register callbalks per topic, so we
// also use it for tests
EthSubRouter *gateway.EthSubHandler
options nodeOpts
}
2022-09-27 16:08:04 +00:00
func MergeFullNodes(fullNodes []*TestFullNode) *TestFullNode {
var wrappedFullNode TestFullNode
var fns api.FullNodeStruct
wrappedFullNode.FullNode = &fns
cliutil.FullNodeProxy(fullNodes, &fns)
wrappedFullNode.t = fullNodes[0].t
wrappedFullNode.ListenAddr = fullNodes[0].ListenAddr
wrappedFullNode.DefaultKey = fullNodes[0].DefaultKey
wrappedFullNode.Stop = fullNodes[0].Stop
wrappedFullNode.options = fullNodes[0].options
return &wrappedFullNode
}
func (f TestFullNode) Shutdown(ctx context.Context) error {
return f.Stop(ctx)
}
// 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
}
test: actors: manual CC onboarding and proving integration test (#12017) * remove client CLI * remove markets CLI from miner * remove markets from all CLI * remove client API * update go mod * remove EnableMarkets flag * remove market subsystem * remove dagstore * remove index provider * remove graphsync and data-transfer * remove markets * go mod tidy * fix cbor gen deps * remove deal making from config * remove eol alert * go mod tidy * changes as per review * make jen * changes as per review * test: actors: manual CC onboarding and proving integration test * test: actors: manual CC onboarding itest with real proofs * test: actors: fix lint issue, require proofs in CI * test: actors: rename real proofs test, fix dispute window wait * feat: add TestUnmanagedMiner in the itest kit for non-storage managed miners * feat: test: improve UnmanagedMiner test harness * feat: test: MineBlocksMustPost can watch for >1 miners (#12063) * feat: test: MineBlocksMustPost can watch for >1 miners * feat: test: wait for both sectors at the end of test * feat: test: minor manual onboarding test fixups and speed up * feat: test: handle case where miners have close deadline ends * Implement snap deals test for manual sector onboarding (#12066) * changes as per review * thread safety * test for snap deals * remove extraneous change * Apply suggestions from code review Co-authored-by: Rod Vagg <rod@vagg.org> * cancel CC Post after snap deals --------- Co-authored-by: Rod Vagg <rod@vagg.org> * fix config --------- Co-authored-by: aarshkshah1992 <aarshkshah1992@gmail.com>
2024-06-06 04:47:25 +00:00
// WaitTillChain waits until a specified chain condition is met. It returns
// the first tipset where the condition is met.
func (f *TestFullNode) WaitTillChainOrError(ctx context.Context, pred ChainPredicate) (*types.TipSet, error) {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
heads, err := f.ChainNotify(ctx)
if err != nil {
return nil, err
}
for chg := range heads {
for _, c := range chg {
if c.Type != "apply" {
continue
}
if ts := c.Val; pred(ts) {
return ts, nil
}
}
}
return nil, xerrors.New("chain condition not met")
}
func (f *TestFullNode) WaitForSectorActive(ctx context.Context, t *testing.T, sn abi.SectorNumber, maddr address.Address) {
for {
active, err := f.StateMinerActiveSectors(ctx, maddr, types.EmptyTSK)
require.NoError(t, err)
for _, si := range active {
if si.SectorNumber == sn {
fmt.Printf("ACTIVE\n")
return
}
}
time.Sleep(time.Second)
}
}
2022-09-12 20:37:24 +00:00
func (f *TestFullNode) AssignPrivKey(pkey *Libp2p) {
f.Pkey = pkey
}
type SendCall struct {
Method abi.MethodNum
Params []byte
}
func (f *TestFullNode) MakeSendCall(m abi.MethodNum, params cbg.CBORMarshaler) SendCall {
var b bytes.Buffer
err := params.MarshalCBOR(&b)
require.NoError(f.t, err)
return SendCall{
Method: m,
Params: b.Bytes(),
}
}
func (f *TestFullNode) ExpectSend(ctx context.Context, from, to address.Address, value types.BigInt, errContains string, sc ...SendCall) *types.SignedMessage {
msg := &types.Message{From: from, To: to, Value: value}
if len(sc) == 1 {
msg.Method = sc[0].Method
msg.Params = sc[0].Params
}
_, err := f.GasEstimateMessageGas(ctx, msg, nil, types.EmptyTSK)
if errContains != "" {
require.ErrorContains(f.t, err, errContains)
return nil
}
require.NoError(f.t, err)
if errContains == "" {
m, err := f.MpoolPushMessage(ctx, msg, nil)
require.NoError(f.t, err)
r, err := f.StateWaitMsg(ctx, m.Cid(), 1, api.LookbackNoLimit, true)
require.NoError(f.t, err)
require.Equal(f.t, exitcode.Ok, r.Receipt.ExitCode)
return m
}
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
}
}
// BlocksMinedByAll returns a ChainPredicate that is satisfied when we observe a
// tipset including blocks from all the specified miners, in no particular order.
func BlocksMinedByAll(miner ...address.Address) ChainPredicate {
return func(ts *types.TipSet) bool {
seen := make([]bool, len(miner))
var done int
for _, b := range ts.Blocks() {
for i, m := range miner {
if b.Miner != m || seen[i] {
continue
}
seen[i] = true
if done++; done == len(miner) {
return true
}
}
}
return false
}
}