2018-07-14 02:15:37 +00:00
|
|
|
package node
|
|
|
|
|
|
|
|
import (
|
2022-08-16 16:19:01 +00:00
|
|
|
"context"
|
2018-07-14 19:48:42 +00:00
|
|
|
"flag"
|
2018-07-31 04:41:27 +00:00
|
|
|
"fmt"
|
2022-08-16 16:19:01 +00:00
|
|
|
"os"
|
2020-10-09 09:28:35 +00:00
|
|
|
"path/filepath"
|
2022-08-16 16:19:01 +00:00
|
|
|
"strconv"
|
2018-07-14 02:15:37 +00:00
|
|
|
"testing"
|
2022-08-16 16:19:01 +00:00
|
|
|
"time"
|
2018-07-14 02:15:37 +00:00
|
|
|
|
2023-03-17 18:52:56 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain"
|
|
|
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/builder"
|
|
|
|
statefeed "github.com/prysmaticlabs/prysm/v4/beacon-chain/core/feed/state"
|
2023-11-21 18:44:38 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/db/filesystem"
|
2023-03-17 18:52:56 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/execution"
|
|
|
|
mockExecution "github.com/prysmaticlabs/prysm/v4/beacon-chain/execution/testing"
|
|
|
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/monitor"
|
|
|
|
"github.com/prysmaticlabs/prysm/v4/cmd"
|
|
|
|
"github.com/prysmaticlabs/prysm/v4/cmd/beacon-chain/flags"
|
|
|
|
"github.com/prysmaticlabs/prysm/v4/config/features"
|
|
|
|
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
|
|
|
"github.com/prysmaticlabs/prysm/v4/config/params"
|
|
|
|
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
|
|
|
"github.com/prysmaticlabs/prysm/v4/runtime"
|
|
|
|
"github.com/prysmaticlabs/prysm/v4/runtime/interop"
|
|
|
|
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
2018-08-20 15:50:11 +00:00
|
|
|
logTest "github.com/sirupsen/logrus/hooks/test"
|
2020-05-31 06:44:34 +00:00
|
|
|
"github.com/urfave/cli/v2"
|
2018-07-14 02:15:37 +00:00
|
|
|
)
|
|
|
|
|
2019-11-19 22:15:48 +00:00
|
|
|
// Ensure BeaconNode implements interfaces.
|
2020-10-10 00:36:48 +00:00
|
|
|
var _ statefeed.Notifier = (*BeaconNode)(nil)
|
2019-11-19 22:15:48 +00:00
|
|
|
|
2018-08-20 15:50:11 +00:00
|
|
|
// Test that beacon chain node can close.
|
2019-02-22 15:11:26 +00:00
|
|
|
func TestNodeClose_OK(t *testing.T) {
|
2018-08-20 15:50:11 +00:00
|
|
|
hook := logTest.NewGlobal()
|
2020-11-10 22:45:17 +00:00
|
|
|
tmp := fmt.Sprintf("%s/datadirtest2", t.TempDir())
|
2018-11-06 21:43:10 +00:00
|
|
|
|
2020-03-19 21:46:44 +00:00
|
|
|
app := cli.App{}
|
2018-08-20 15:50:11 +00:00
|
|
|
set := flag.NewFlagSet("test", 0)
|
2019-03-04 20:10:03 +00:00
|
|
|
set.Bool("test-skip-pow", true, "skip pow dial")
|
2018-08-20 15:50:11 +00:00
|
|
|
set.String("datadir", tmp, "node data directory")
|
2019-09-05 16:04:06 +00:00
|
|
|
set.String("p2p-encoding", "ssz", "p2p encoding scheme")
|
2018-10-02 02:04:37 +00:00
|
|
|
set.Bool("demo-config", true, "demo configuration")
|
2019-03-04 20:10:03 +00:00
|
|
|
set.String("deposit-contract", "0x0000000000000000000000000000000000000000", "deposit contract address")
|
2022-09-22 16:35:35 +00:00
|
|
|
set.String("suggested-fee-recipient", "0x6e35733c5af9B61374A128e6F85f553aF09ff89A", "fee recipient")
|
|
|
|
require.NoError(t, set.Set("suggested-fee-recipient", "0x6e35733c5af9B61374A128e6F85f553aF09ff89A"))
|
2022-08-16 16:19:01 +00:00
|
|
|
cmd.ValidatorMonitorIndicesFlag.Value = &cli.IntSlice{}
|
|
|
|
cmd.ValidatorMonitorIndicesFlag.Value.SetInt(1)
|
|
|
|
ctx := cli.NewContext(&app, set, nil)
|
2018-08-20 15:50:11 +00:00
|
|
|
|
2022-08-16 16:19:01 +00:00
|
|
|
node, err := New(ctx)
|
2020-08-25 15:23:06 +00:00
|
|
|
require.NoError(t, err)
|
2018-08-20 15:50:11 +00:00
|
|
|
|
|
|
|
node.Close()
|
|
|
|
|
2020-08-13 16:22:25 +00:00
|
|
|
require.LogsContain(t, hook, "Stopping beacon node")
|
2022-08-16 16:19:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestNodeStart_Ok(t *testing.T) {
|
|
|
|
hook := logTest.NewGlobal()
|
|
|
|
app := cli.App{}
|
|
|
|
tmp := fmt.Sprintf("%s/datadirtest2", t.TempDir())
|
|
|
|
set := flag.NewFlagSet("test", 0)
|
|
|
|
set.String("datadir", tmp, "node data directory")
|
2022-09-22 16:35:35 +00:00
|
|
|
set.String("suggested-fee-recipient", "0x6e35733c5af9B61374A128e6F85f553aF09ff89A", "fee recipient")
|
|
|
|
require.NoError(t, set.Set("suggested-fee-recipient", "0x6e35733c5af9B61374A128e6F85f553aF09ff89A"))
|
|
|
|
|
2022-08-16 16:19:01 +00:00
|
|
|
ctx := cli.NewContext(&app, set, nil)
|
|
|
|
node, err := New(ctx, WithBlockchainFlagOptions([]blockchain.Option{}),
|
|
|
|
WithBuilderFlagOptions([]builder.Option{}),
|
2023-11-21 18:44:38 +00:00
|
|
|
WithExecutionChainOptions([]execution.Option{}),
|
|
|
|
WithBlobStorage(filesystem.NewEphemeralBlobStorage(t)))
|
2022-08-16 16:19:01 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
node.services = &runtime.ServiceRegistry{}
|
|
|
|
go func() {
|
|
|
|
node.Start()
|
|
|
|
}()
|
|
|
|
time.Sleep(3 * time.Second)
|
|
|
|
node.Close()
|
|
|
|
require.LogsContain(t, hook, "Starting beacon node")
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestNodeStart_Ok_registerDeterministicGenesisService(t *testing.T) {
|
|
|
|
numValidators := uint64(1)
|
|
|
|
hook := logTest.NewGlobal()
|
|
|
|
app := cli.App{}
|
|
|
|
tmp := fmt.Sprintf("%s/datadirtest2", t.TempDir())
|
|
|
|
set := flag.NewFlagSet("test", 0)
|
|
|
|
set.String("datadir", tmp, "node data directory")
|
|
|
|
set.Uint64(flags.InteropNumValidatorsFlag.Name, numValidators, "")
|
2022-09-22 16:35:35 +00:00
|
|
|
set.String("suggested-fee-recipient", "0x6e35733c5af9B61374A128e6F85f553aF09ff89A", "fee recipient")
|
|
|
|
require.NoError(t, set.Set("suggested-fee-recipient", "0x6e35733c5af9B61374A128e6F85f553aF09ff89A"))
|
2022-08-16 16:19:01 +00:00
|
|
|
genesisState, _, err := interop.GenerateGenesisState(context.Background(), 0, numValidators)
|
|
|
|
require.NoError(t, err, "Could not generate genesis beacon state")
|
|
|
|
for i := uint64(1); i < 2; i++ {
|
2022-12-22 09:20:10 +00:00
|
|
|
var someRoot [32]byte
|
|
|
|
var someKey [fieldparams.BLSPubkeyLength]byte
|
2022-08-16 16:19:01 +00:00
|
|
|
copy(someRoot[:], strconv.Itoa(int(i)))
|
|
|
|
copy(someKey[:], strconv.Itoa(int(i)))
|
|
|
|
genesisState.Validators = append(genesisState.Validators, ðpb.Validator{
|
|
|
|
PublicKey: someKey[:],
|
|
|
|
WithdrawalCredentials: someRoot[:],
|
|
|
|
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
|
|
|
|
Slashed: false,
|
|
|
|
ActivationEligibilityEpoch: 1,
|
|
|
|
ActivationEpoch: 1,
|
|
|
|
ExitEpoch: 1,
|
|
|
|
WithdrawableEpoch: 1,
|
|
|
|
})
|
|
|
|
genesisState.Balances = append(genesisState.Balances, params.BeaconConfig().MaxEffectiveBalance)
|
|
|
|
}
|
|
|
|
genesisBytes, err := genesisState.MarshalSSZ()
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NoError(t, os.WriteFile("genesis_ssz.json", genesisBytes, 0666))
|
2023-03-01 19:39:17 +00:00
|
|
|
set.String("genesis-state", "genesis_ssz.json", "")
|
2022-08-16 16:19:01 +00:00
|
|
|
ctx := cli.NewContext(&app, set, nil)
|
|
|
|
node, err := New(ctx, WithBlockchainFlagOptions([]blockchain.Option{}),
|
|
|
|
WithBuilderFlagOptions([]builder.Option{}),
|
|
|
|
WithExecutionChainOptions([]execution.Option{}))
|
|
|
|
require.NoError(t, err)
|
|
|
|
node.services = &runtime.ServiceRegistry{}
|
|
|
|
go func() {
|
|
|
|
node.Start()
|
|
|
|
}()
|
|
|
|
time.Sleep(3 * time.Second)
|
|
|
|
node.Close()
|
|
|
|
require.LogsContain(t, hook, "Starting beacon node")
|
|
|
|
require.NoError(t, os.Remove("genesis_ssz.json"))
|
2018-07-14 02:15:37 +00:00
|
|
|
}
|
2020-06-26 11:23:38 +00:00
|
|
|
|
2020-10-09 09:28:35 +00:00
|
|
|
// TestClearDB tests clearing the database
|
|
|
|
func TestClearDB(t *testing.T) {
|
|
|
|
hook := logTest.NewGlobal()
|
2022-08-01 14:43:47 +00:00
|
|
|
srv, endpoint, err := mockExecution.SetupRPCServer()
|
2022-04-01 18:04:24 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
t.Cleanup(func() {
|
|
|
|
srv.Stop()
|
|
|
|
})
|
2020-10-09 09:28:35 +00:00
|
|
|
|
2020-11-10 22:45:17 +00:00
|
|
|
tmp := filepath.Join(t.TempDir(), "datadirtest")
|
2020-10-09 09:28:35 +00:00
|
|
|
|
|
|
|
app := cli.App{}
|
|
|
|
set := flag.NewFlagSet("test", 0)
|
|
|
|
set.String("datadir", tmp, "node data directory")
|
|
|
|
set.Bool(cmd.ForceClearDB.Name, true, "force clear db")
|
2022-09-22 16:35:35 +00:00
|
|
|
set.String("suggested-fee-recipient", "0x6e35733c5af9B61374A128e6F85f553aF09ff89A", "fee recipient")
|
|
|
|
require.NoError(t, set.Set("suggested-fee-recipient", "0x6e35733c5af9B61374A128e6F85f553aF09ff89A"))
|
2020-10-09 09:28:35 +00:00
|
|
|
context := cli.NewContext(&app, set, nil)
|
2023-11-21 18:44:38 +00:00
|
|
|
options := []Option{
|
|
|
|
WithExecutionChainOptions([]execution.Option{execution.WithHttpEndpoint(endpoint)}),
|
|
|
|
WithBlobStorage(filesystem.NewEphemeralBlobStorage(t)),
|
|
|
|
}
|
|
|
|
_, err = New(context, options...)
|
2020-10-09 09:28:35 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.LogsContain(t, hook, "Removing database")
|
|
|
|
}
|
2022-10-04 10:44:57 +00:00
|
|
|
|
|
|
|
func TestMonitor_RegisteredCorrectly(t *testing.T) {
|
|
|
|
app := cli.App{}
|
|
|
|
set := flag.NewFlagSet("test", 0)
|
|
|
|
require.NoError(t, cmd.ValidatorMonitorIndicesFlag.Apply(set))
|
|
|
|
cliCtx := cli.NewContext(&app, set, nil)
|
|
|
|
require.NoError(t, cliCtx.Set(cmd.ValidatorMonitorIndicesFlag.Name, "1,2"))
|
|
|
|
n := &BeaconNode{ctx: context.Background(), cliCtx: cliCtx, services: runtime.NewServiceRegistry()}
|
|
|
|
require.NoError(t, n.services.RegisterService(&blockchain.Service{}))
|
2023-05-03 04:34:01 +00:00
|
|
|
require.NoError(t, n.registerValidatorMonitorService(make(chan struct{})))
|
2022-10-04 10:44:57 +00:00
|
|
|
|
|
|
|
var mService *monitor.Service
|
|
|
|
require.NoError(t, n.services.FetchService(&mService))
|
|
|
|
require.Equal(t, true, mService.TrackedValidators[1])
|
|
|
|
require.Equal(t, true, mService.TrackedValidators[2])
|
|
|
|
require.Equal(t, false, mService.TrackedValidators[100])
|
|
|
|
}
|
2022-10-25 10:48:25 +00:00
|
|
|
|
|
|
|
func Test_hasNetworkFlag(t *testing.T) {
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
networkName string
|
|
|
|
networkValue string
|
|
|
|
want bool
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "Prater testnet",
|
|
|
|
networkName: features.PraterTestnet.Name,
|
|
|
|
networkValue: "prater",
|
|
|
|
want: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "Mainnet",
|
|
|
|
networkName: features.Mainnet.Name,
|
|
|
|
networkValue: "mainnet",
|
|
|
|
want: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "No network flag",
|
|
|
|
networkName: "",
|
|
|
|
networkValue: "",
|
|
|
|
want: false,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
set := flag.NewFlagSet("test", 0)
|
|
|
|
set.String(tt.networkName, tt.networkValue, tt.name)
|
|
|
|
|
|
|
|
cliCtx := cli.NewContext(&cli.App{}, set, nil)
|
|
|
|
err := cliCtx.Set(tt.networkName, tt.networkValue)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
if got := hasNetworkFlag(cliCtx); got != tt.want {
|
|
|
|
t.Errorf("hasNetworkFlag() = %v, want %v", got, tt.want)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|