-
Notifications
You must be signed in to change notification settings - Fork 688
Implement Execution/Consensus interface over RPC #3617
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 9 commits
4f132e9
969a1b6
8219a5e
2a18ad2
eaad44a
901dbea
18097ee
f54a0f0
eeb55d3
f35e01b
acb0165
baca94a
61b8b17
55e3d05
7c9c449
e9b35e3
6894bbe
b71389d
f793c62
c65f6bf
25c70bd
6dac9b1
130a5ab
c2f6ebd
94aa08c
ac38683
75f885c
1f8c7c2
ffe9416
04b166e
5201dda
61a4017
2df87bc
cb34614
3b5fa3b
0acc651
f8b8f60
b71cb29
72458ac
4501faf
cd5bd77
3d7a2c5
6ce9b5b
cce9ac7
ceef817
ac94517
144c44e
c556785
310a61a
667db30
3f1cdd1
b584553
690b8e7
219dd11
04cdeb3
20e5888
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -37,18 +37,20 @@ import ( | |
| "github.com/offchainlabs/nitro/broadcaster" | ||
| "github.com/offchainlabs/nitro/cmd/chaininfo" | ||
| "github.com/offchainlabs/nitro/cmd/genericconf" | ||
| "github.com/offchainlabs/nitro/consensus" | ||
| consensusrpcserver "github.com/offchainlabs/nitro/consensus/rpcserver" | ||
| "github.com/offchainlabs/nitro/daprovider" | ||
| "github.com/offchainlabs/nitro/daprovider/daclient" | ||
| "github.com/offchainlabs/nitro/daprovider/das" | ||
| "github.com/offchainlabs/nitro/daprovider/das/dasserver" | ||
| "github.com/offchainlabs/nitro/execution" | ||
| "github.com/offchainlabs/nitro/execution/gethexec" | ||
| executionrpcclient "github.com/offchainlabs/nitro/execution/rpcclient" | ||
| "github.com/offchainlabs/nitro/solgen/go/bridgegen" | ||
| "github.com/offchainlabs/nitro/solgen/go/precompilesgen" | ||
| "github.com/offchainlabs/nitro/staker" | ||
| "github.com/offchainlabs/nitro/staker/bold" | ||
| "github.com/offchainlabs/nitro/staker/legacy" | ||
| "github.com/offchainlabs/nitro/staker/multi_protocol" | ||
| legacystaker "github.com/offchainlabs/nitro/staker/legacy" | ||
| multiprotocolstaker "github.com/offchainlabs/nitro/staker/multi_protocol" | ||
| "github.com/offchainlabs/nitro/staker/validatorwallet" | ||
| "github.com/offchainlabs/nitro/util/containers" | ||
| "github.com/offchainlabs/nitro/util/contracts" | ||
|
|
@@ -59,6 +61,24 @@ import ( | |
| "github.com/offchainlabs/nitro/wsbroadcastserver" | ||
| ) | ||
|
|
||
| type RPCServerConfig struct { | ||
| Enable bool `koanf:"enable"` | ||
| Public bool `koanf:"public"` | ||
| Authenticated bool `koanf:"authenticated"` | ||
| } | ||
|
|
||
| var DefaultRPCServerConfig = RPCServerConfig{ | ||
| Enable: false, | ||
| Public: false, | ||
| Authenticated: true, | ||
| } | ||
|
|
||
| func RPCServerAddOptions(prefix string, f *pflag.FlagSet) { | ||
| f.Bool(prefix+".enable", DefaultRPCServerConfig.Enable, "enable consensus node to serve over rpc") | ||
| f.Bool(prefix+".public", DefaultRPCServerConfig.Public, "rpc is public") | ||
| f.Bool(prefix+".authenticated", DefaultRPCServerConfig.Authenticated, "rpc is authenticated") | ||
| } | ||
|
|
||
| type Config struct { | ||
| Sequencer bool `koanf:"sequencer"` | ||
| ParentChainReader headerreader.Config `koanf:"parent-chain-reader" reload:"hot"` | ||
|
|
@@ -80,6 +100,8 @@ type Config struct { | |
| ResourceMgmt resourcemanager.Config `koanf:"resource-mgmt" reload:"hot"` | ||
| BlockMetadataFetcher BlockMetadataFetcherConfig `koanf:"block-metadata-fetcher" reload:"hot"` | ||
| ConsensusExecutionSyncer ConsensusExecutionSyncerConfig `koanf:"consensus-execution-syncer"` | ||
| RPCServer RPCServerConfig `koanf:"rpc-server"` | ||
| ExecutionRPCClient rpcclient.ClientConfig `koanf:"execution-rpc-client" reload:"hot"` | ||
| // SnapSyncConfig is only used for testing purposes, these should not be configured in production. | ||
| SnapSyncTest SnapSyncConfig | ||
| } | ||
|
|
@@ -119,6 +141,9 @@ func (c *Config) Validate() error { | |
| if c.TransactionStreamer.TrackBlockMetadataFrom != 0 && !c.BlockMetadataFetcher.Enable { | ||
| log.Warn("track-block-metadata-from is set but blockMetadata fetcher is not enabled") | ||
| } | ||
| if err := c.ExecutionRPCClient.Validate(); err != nil { | ||
ganeshvanahalli marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return fmt.Errorf("error validating ExecutionRPCClient config: %w", err) | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
|
|
@@ -153,6 +178,8 @@ func ConfigAddOptions(prefix string, f *pflag.FlagSet, feedInputEnable bool, fee | |
| resourcemanager.ConfigAddOptions(prefix+".resource-mgmt", f) | ||
| BlockMetadataFetcherConfigAddOptions(prefix+".block-metadata-fetcher", f) | ||
| ConsensusExecutionSyncerConfigAddOptions(prefix+".consensus-execution-syncer", f) | ||
| RPCServerAddOptions(prefix+".rpc-server", f) | ||
| rpcclient.RPCClientAddOptions(prefix+".execution-rpc-client", f, &ConfigDefault.ExecutionRPCClient) | ||
| } | ||
|
|
||
| var ConfigDefault = Config{ | ||
|
|
@@ -177,6 +204,15 @@ var ConfigDefault = Config{ | |
| Maintenance: DefaultMaintenanceConfig, | ||
| ConsensusExecutionSyncer: DefaultConsensusExecutionSyncerConfig, | ||
| SnapSyncTest: DefaultSnapSyncConfig, | ||
| RPCServer: DefaultRPCServerConfig, | ||
| ExecutionRPCClient: rpcclient.ClientConfig{ | ||
diegoximenes marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| URL: "", | ||
| JWTSecret: "", | ||
| Retries: 3, | ||
| RetryErrors: "websocket: close.*|dial tcp .*|.*i/o timeout|.*connection reset by peer|.*connection refused", | ||
| ArgLogLimit: 2048, | ||
| WebsocketMessageSizeLimit: 256 * 1024 * 1024, | ||
| }, | ||
| } | ||
|
|
||
| func ConfigDefaultL1Test() *Config { | ||
|
|
@@ -1228,6 +1264,16 @@ func registerAPIs(currentNode *Node, stack *node.Node) { | |
| Public: false, | ||
| }) | ||
| } | ||
| config := currentNode.configFetcher.Get() | ||
| if config.RPCServer.Enable { | ||
| apis = append(apis, rpc.API{ | ||
| Namespace: consensus.RPCNamespace, | ||
| Version: "1.0", | ||
| Service: consensusrpcserver.NewConsensusRpcServer(currentNode), | ||
| Public: config.RPCServer.Public, | ||
| Authenticated: config.RPCServer.Authenticated, | ||
| }) | ||
| } | ||
| stack.RegisterAPIs(apis) | ||
| } | ||
|
|
||
|
|
@@ -1251,6 +1297,10 @@ func CreateNodeExecutionClient( | |
| if executionClient == nil { | ||
| return nil, errors.New("execution client must be non-nil") | ||
| } | ||
| if configFetcher.Get().ExecutionRPCClient.URL != "" { | ||
| execConfigFetcher := func() *rpcclient.ClientConfig { return &configFetcher.Get().ExecutionRPCClient } | ||
| executionClient = executionrpcclient.NewExecutionRpcClient(execConfigFetcher, nil) | ||
| } | ||
ganeshvanahalli marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| currentNode, err := createNodeImpl(ctx, stack, executionClient, nil, nil, nil, arbDb, configFetcher, l2Config, l1client, deployInfo, txOptsValidator, txOptsBatchPoster, dataSigner, fatalErrChan, parentChainID, blobReader, latestWasmModuleRoot) | ||
| if err != nil { | ||
| return nil, err | ||
|
|
@@ -1282,6 +1332,10 @@ func CreateNodeFullExecutionClient( | |
| if (executionClient == nil) || (executionSequencer == nil) || (executionRecorder == nil) || (executionBatchPoster == nil) { | ||
| return nil, errors.New("execution client, sequencer, recorder, and batch poster must be non-nil") | ||
| } | ||
| if configFetcher.Get().ExecutionRPCClient.URL != "" { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about being more explicit here, and relying on ExecutionNode and ConsensusExecutionUseRPC instead of ExecutionRPCClient.URL?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In cmd/nitro.go, nodeConfig.ExecutionNode is being used to decide if the gethexec.ExecutionNode will be created or not. That is why I proposed to have a unified way to verify if the RPC client should be used, that takes into consideration nodeConfig.ConsensusExecutionUseRPC and nodeConfig.ExecutionNode, possibly through a function, or creating a variable and passing it around, instead of relying on RPC URLs. Also, the ConsensusExecutionUseRPC name could indicate more clearly that is only used when NodeConfig.ExecutionNode is set to true, that is why I suggested to rename to something like ConsensusExecutionUseRPCWhenBothAreRunInTheSameProcess. WDYT? |
||
| execConfigFetcher := func() *rpcclient.ClientConfig { return &configFetcher.Get().ExecutionRPCClient } | ||
| executionClient = executionrpcclient.NewExecutionRpcClient(execConfigFetcher, nil) | ||
| } | ||
| currentNode, err := createNodeImpl(ctx, stack, executionClient, executionSequencer, executionRecorder, executionBatchPoster, arbDb, configFetcher, l2Config, l1client, deployInfo, txOptsValidator, txOptsBatchPoster, dataSigner, fatalErrChan, parentChainID, blobReader, latestWasmModuleRoot) | ||
| if err != nil { | ||
| return nil, err | ||
|
|
@@ -1291,27 +1345,12 @@ func CreateNodeFullExecutionClient( | |
| } | ||
|
|
||
| func (n *Node) Start(ctx context.Context) error { | ||
| execClient, ok := n.ExecutionClient.(*gethexec.ExecutionNode) | ||
| if !ok { | ||
| execClient = nil | ||
| } | ||
| if execClient != nil { | ||
| err := execClient.Initialize(ctx) | ||
| if err != nil { | ||
| return fmt.Errorf("error initializing exec client: %w", err) | ||
| var err error | ||
| if execRPCClient, ok := n.ExecutionClient.(*executionrpcclient.ExecutionRpcClient); ok { | ||
| if err = execRPCClient.Start(ctx); err != nil { | ||
| return fmt.Errorf("error starting exec rpc client: %w", err) | ||
| } | ||
| } | ||
| err := n.Stack.Start() | ||
| if err != nil { | ||
| return fmt.Errorf("error starting geth stack: %w", err) | ||
| } | ||
| if execClient != nil { | ||
| execClient.SetConsensusClient(n) | ||
| } | ||
| err = n.ExecutionClient.Start(ctx) | ||
| if err != nil { | ||
| return fmt.Errorf("error starting exec client: %w", err) | ||
| } | ||
| if n.BlobReader != nil { | ||
| err = n.BlobReader.Initialize(ctx) | ||
| if err != nil { | ||
|
|
@@ -1418,7 +1457,10 @@ func (n *Node) Start(ctx context.Context) error { | |
| }() | ||
| } | ||
| if n.blockMetadataFetcher != nil { | ||
| n.blockMetadataFetcher.Start(ctx) | ||
| err = n.blockMetadataFetcher.Start(ctx) | ||
| if err != nil { | ||
| return fmt.Errorf("error starting block metadata fetcher: %w", err) | ||
| } | ||
| } | ||
| if n.configFetcher != nil { | ||
| n.configFetcher.Start(ctx) | ||
|
|
@@ -1493,16 +1535,15 @@ func (n *Node) StopAndWait() { | |
| n.dasServerCloseFn() | ||
| } | ||
| if n.ExecutionClient != nil { | ||
| n.ExecutionClient.StopAndWait() | ||
| } | ||
| if err := n.Stack.Close(); err != nil { | ||
| log.Error("error on stack close", "err", err) | ||
| if _, ok := n.ExecutionClient.(*executionrpcclient.ExecutionRpcClient); ok { | ||
| n.ExecutionClient.StopAndWait() | ||
| } | ||
| } | ||
| } | ||
|
|
||
| func (n *Node) FindInboxBatchContainingMessage(message arbutil.MessageIndex) containers.PromiseInterface[execution.InboxBatch] { | ||
| func (n *Node) FindInboxBatchContainingMessage(message arbutil.MessageIndex) containers.PromiseInterface[consensus.InboxBatch] { | ||
| batchNum, found, err := n.InboxTracker.FindInboxBatchContainingMessage(message) | ||
| inboxBatch := execution.InboxBatch{ | ||
| inboxBatch := consensus.InboxBatch{ | ||
| BatchNum: batchNum, | ||
| Found: found, | ||
| } | ||
|
|
@@ -1525,7 +1566,7 @@ func (n *Node) SyncTargetMessageCount() containers.PromiseInterface[arbutil.Mess | |
| return containers.NewReadyPromise(n.SyncMonitor.SyncTargetMessageCount(), nil) | ||
| } | ||
|
|
||
| func (n *Node) WriteMessageFromSequencer(pos arbutil.MessageIndex, msgWithMeta arbostypes.MessageWithMetadata, msgResult execution.MessageResult, blockMetadata common.BlockMetadata) containers.PromiseInterface[struct{}] { | ||
| func (n *Node) WriteMessageFromSequencer(pos arbutil.MessageIndex, msgWithMeta arbostypes.MessageWithMetadata, msgResult consensus.MessageResult, blockMetadata common.BlockMetadata) containers.PromiseInterface[struct{}] { | ||
| err := n.TxStreamer.WriteMessageFromSequencer(pos, msgWithMeta, msgResult, blockMetadata) | ||
| return containers.NewReadyPromise(struct{}{}, err) | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.