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 }