github.com/prysmaticlabs/prysm@v1.4.4/endtoend/components/beacon_node.go (about)

     1  // Package components defines utilities to spin up actual
     2  // beacon node and validator processes as needed by end to end tests.
     3  package components
     4  
     5  import (
     6  	"context"
     7  	"errors"
     8  	"fmt"
     9  	"os/exec"
    10  	"strings"
    11  
    12  	"github.com/bazelbuild/rules_go/go/tools/bazel"
    13  	"github.com/prysmaticlabs/prysm/cmd/beacon-chain/flags"
    14  	"github.com/prysmaticlabs/prysm/endtoend/helpers"
    15  	e2e "github.com/prysmaticlabs/prysm/endtoend/params"
    16  	e2etypes "github.com/prysmaticlabs/prysm/endtoend/types"
    17  	cmdshared "github.com/prysmaticlabs/prysm/shared/cmd"
    18  	"github.com/prysmaticlabs/prysm/shared/featureconfig"
    19  	"github.com/prysmaticlabs/prysm/shared/params"
    20  )
    21  
    22  var _ e2etypes.ComponentRunner = (*BeaconNode)(nil)
    23  var _ e2etypes.ComponentRunner = (*BeaconNodeSet)(nil)
    24  
    25  // BeaconNodeSet represents set of beacon nodes.
    26  type BeaconNodeSet struct {
    27  	e2etypes.ComponentRunner
    28  	config  *e2etypes.E2EConfig
    29  	enr     string
    30  	started chan struct{}
    31  }
    32  
    33  // SetENR assigns ENR to the set of beacon nodes.
    34  func (s *BeaconNodeSet) SetENR(enr string) {
    35  	s.enr = enr
    36  }
    37  
    38  // NewBeaconNodes creates and returns a set of beacon nodes.
    39  func NewBeaconNodes(config *e2etypes.E2EConfig) *BeaconNodeSet {
    40  	return &BeaconNodeSet{
    41  		config:  config,
    42  		started: make(chan struct{}, 1),
    43  	}
    44  }
    45  
    46  // Start starts all the beacon nodes in set.
    47  func (s *BeaconNodeSet) Start(ctx context.Context) error {
    48  	if s.enr == "" {
    49  		return errors.New("empty ENR")
    50  	}
    51  
    52  	// Create beacon nodes.
    53  	nodes := make([]e2etypes.ComponentRunner, e2e.TestParams.BeaconNodeCount)
    54  	for i := 0; i < e2e.TestParams.BeaconNodeCount; i++ {
    55  		nodes[i] = NewBeaconNode(s.config, i, s.enr)
    56  	}
    57  
    58  	// Wait for all nodes to finish their job (blocking).
    59  	// Once nodes are ready passed in handler function will be called.
    60  	return helpers.WaitOnNodes(ctx, nodes, func() {
    61  		// All nodes stated, close channel, so that all services waiting on a set, can proceed.
    62  		close(s.started)
    63  	})
    64  }
    65  
    66  // Started checks whether beacon node set is started and all nodes are ready to be queried.
    67  func (s *BeaconNodeSet) Started() <-chan struct{} {
    68  	return s.started
    69  }
    70  
    71  // BeaconNode represents beacon node.
    72  type BeaconNode struct {
    73  	e2etypes.ComponentRunner
    74  	config  *e2etypes.E2EConfig
    75  	started chan struct{}
    76  	index   int
    77  	enr     string
    78  }
    79  
    80  // NewBeaconNode creates and returns a beacon node.
    81  func NewBeaconNode(config *e2etypes.E2EConfig, index int, enr string) *BeaconNode {
    82  	return &BeaconNode{
    83  		config:  config,
    84  		index:   index,
    85  		enr:     enr,
    86  		started: make(chan struct{}, 1),
    87  	}
    88  }
    89  
    90  // Start starts a fresh beacon node, connecting to all passed in beacon nodes.
    91  func (node *BeaconNode) Start(ctx context.Context) error {
    92  	binaryPath, found := bazel.FindBinary("cmd/beacon-chain", "beacon-chain")
    93  	if !found {
    94  		log.Info(binaryPath)
    95  		return errors.New("beacon chain binary not found")
    96  	}
    97  
    98  	config, index, enr := node.config, node.index, node.enr
    99  	stdOutFile, err := helpers.DeleteAndCreateFile(e2e.TestParams.LogPath, fmt.Sprintf(e2e.BeaconNodeLogFileName, index))
   100  	if err != nil {
   101  		return err
   102  	}
   103  
   104  	args := []string{
   105  		fmt.Sprintf("--%s=%s/eth2-beacon-node-%d", cmdshared.DataDirFlag.Name, e2e.TestParams.TestPath, index),
   106  		fmt.Sprintf("--%s=%s", cmdshared.LogFileName.Name, stdOutFile.Name()),
   107  		fmt.Sprintf("--%s=%s", flags.DepositContractFlag.Name, e2e.TestParams.ContractAddress.Hex()),
   108  		fmt.Sprintf("--%s=%d", flags.RPCPort.Name, e2e.TestParams.BeaconNodeRPCPort+index),
   109  		fmt.Sprintf("--%s=http://127.0.0.1:%d", flags.HTTPWeb3ProviderFlag.Name, e2e.TestParams.Eth1RPCPort),
   110  		fmt.Sprintf("--%s=%d", flags.MinSyncPeers.Name, e2e.TestParams.BeaconNodeCount-1),
   111  		fmt.Sprintf("--%s=%d", cmdshared.P2PUDPPort.Name, e2e.TestParams.BeaconNodeRPCPort+index+10),
   112  		fmt.Sprintf("--%s=%d", cmdshared.P2PTCPPort.Name, e2e.TestParams.BeaconNodeRPCPort+index+20),
   113  		fmt.Sprintf("--%s=%d", flags.MonitoringPortFlag.Name, e2e.TestParams.BeaconNodeMetricsPort+index),
   114  		fmt.Sprintf("--%s=%d", flags.GRPCGatewayPort.Name, e2e.TestParams.BeaconNodeRPCPort+index+40),
   115  		fmt.Sprintf("--%s=%d", flags.EthApiPort.Name, e2e.TestParams.BeaconNodeRPCPort+index+30),
   116  		fmt.Sprintf("--%s=%d", flags.ContractDeploymentBlock.Name, 0),
   117  		fmt.Sprintf("--%s=%d", cmdshared.RPCMaxPageSizeFlag.Name, params.BeaconConfig().MinGenesisActiveValidatorCount),
   118  		fmt.Sprintf("--%s=%s", cmdshared.BootstrapNode.Name, enr),
   119  		fmt.Sprintf("--%s=%s", cmdshared.VerbosityFlag.Name, "debug"),
   120  		"--" + cmdshared.ForceClearDB.Name,
   121  		"--" + cmdshared.E2EConfigFlag.Name,
   122  		"--" + cmdshared.AcceptTosFlag.Name,
   123  	}
   124  	if config.UsePprof {
   125  		args = append(args, "--pprof", fmt.Sprintf("--pprofport=%d", e2e.TestParams.BeaconNodeRPCPort+index+50))
   126  	}
   127  	args = append(args, featureconfig.E2EBeaconChainFlags...)
   128  	args = append(args, config.BeaconFlags...)
   129  
   130  	cmd := exec.CommandContext(ctx, binaryPath, args...)
   131  	log.Infof("Starting beacon chain %d with flags: %s", index, strings.Join(args[2:], " "))
   132  	if err = cmd.Start(); err != nil {
   133  		return fmt.Errorf("failed to start beacon node: %w", err)
   134  	}
   135  
   136  	if err = helpers.WaitForTextInFile(stdOutFile, "gRPC server listening on port"); err != nil {
   137  		return fmt.Errorf("could not find multiaddr for node %d, this means the node had issues starting: %w", index, err)
   138  	}
   139  
   140  	// Mark node as ready.
   141  	close(node.started)
   142  
   143  	return cmd.Wait()
   144  }
   145  
   146  // Started checks whether beacon node is started and ready to be queried.
   147  func (node *BeaconNode) Started() <-chan struct{} {
   148  	return node.started
   149  }