-
Notifications
You must be signed in to change notification settings - Fork 686
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?
Implement Execution/Consensus interface over RPC #3617
Conversation
…on rpc server and connecting to one on both execution and consensus side
|
This PR has been changed from its initial design. Execution and Consensus each have capability to enable connections to them via json-rpc through the flags Nitro has two new flags that determine
Testing doneA new CI step has been added to run current system tests with json rpc interconnect enabled. Resolves NIT-2567 |
diegoximenes
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice 🙂, this is quite important for the alternative clients effort!
The way I see the UX on how to run a Nitro node, implemented in this repo, is something like this:
- Node operator runs only Execution
./nitro --consensus-node=false --execution-node=true. In that case Execution will connect with Consensus through RPC. We don't even create a arbnode.Node object in this scenario. - Node operator runs only Consensus
./nitro --consensus-node=true --execution-node=false. In that case Consensus will connect with Execution through RPC. - Node operator runs Execution and Consensus
./nitro --execution-node=true --consensus-node=true --consensus-execution-use-rpc=bool. A single process will run both Execution and Consensus.
I don't like the --consensus-execution-use-rpc flag on option 3 BTW, but it is worth having it for testing, at least for a while.
I don't see an advantage of running Option 3 over RPC in production if we have an option to have Consensus and Execution living in the same process.
But without this flag, to test this PR we would need to run two ./nitros, have an external component similar to consensusexecution_consensus.InitAndStartExecutionAndConsensusNodes, coordinating Execution/Consensus to handle the egg/chicken problem related to which component to start first.
It is a little bit different from what this PR is proposing.
WDYT?
|
To keep in mind:
By not worry I mean that we don't need to cover them in this PR, but we should definitely consider that those scenarios, could, and ideally will happen 🙂, so changes here shouldn't make our lives too difficult when covering them in the future. There is this test, in which is possible to create a Nitro node with an execution client that only implements the ExecutionClient interface, and not ExecutionRecorder, etc. That said, for this PR, the minimal requirements could be:
I am OK with covering all execution behaviors with the RPC approach right now TBH, it seems the way to go long term wise, but it is definitely not a requirement. We could have the same behavior without the --execution-node and --consensus-execution-use-rpc flags BTW, only relying on the rpc flags such as --execution-rpc-server and --execution-rpc-client.
WDYT? |
I've addressed your comments and added two new flags to nitro -
|
tsahee
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not done reviewing.. overall seems great
arbnode/node.go
Outdated
| latestWasmModuleRoot common.Hash, | ||
| useRPC bool, | ||
| ) (*Node, error) { | ||
| if useRPC { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why give a boolean that means "ignore executionClient" and not just give it the correct execution client?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since the RPC config is currently part of the arbnode's config, creating the client inside this method feels right?
The reason for using a separate boolean comes from this conversation with @diegoximenes #3617
arbnode/node.go
Outdated
| return nil, errors.New("full execution client must be non-nil") | ||
| } | ||
| var executionClient execution.ExecutionClient | ||
| if useRPC { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as before.. instead of useRPC, accept both "executionClient" and FullExecutionClient, and the "executionClient" could ewither be same as fullExecutionClient, or it could be the rpc client (?)
cmd/nitro/nitro.go
Outdated
| BlocksReExecutor blocksreexecutor.Config `koanf:"blocks-reexecutor"` | ||
| EnsureRollupDeployment bool `koanf:"ensure-rollup-deployment" reload:"hot"` | ||
| ExecutionNode bool `koanf:"execution-node"` | ||
| ConsensusExecutionInSameProcessUseRPC bool `koanf:"consensus-execution-in-same-process-use-rpc"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's instead just use the Node.ExecutionRPCClient.URL field:
- If it's empty (default) - create an execution node and use it directly.
- if it's "self" or "self-auth" - create an execution node and connect to it via rpc (still connect to it directly for fullExecutionNode)
tsahee
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
small comments
tsahee
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getting really close.. tiny comment + f2f
util/common.go
Outdated
| return ret | ||
| } | ||
|
|
||
| func BlockNumberToMessageIndex(blockNum, genesis uint64) (arbutil.MessageIndex, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we currently have, in arbutil/block_message_relation.go:
BlockNumberToMessageCount
MessageCountToBlockNumber
Either is reasonable, but we should not have both versions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed it
.github/workflows/_go-tests.yml
Outdated
| exit 1 | ||
| - name: run tests with consensus and execution nodes connected over json rpc | ||
| if: matrix.test-mode == 'defaults' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this step being run by CI?
Some possible strategies:
- Two new steps, one for inputs.run-defaults-a and another for inputs.run-defaults-b. This will likely "double" the CI times related to run-defaults-*.
- Create other two inputs, something like run-consensus-execution-over-rpc-a, run-consensus-execution-over-rpc-b, that will use hash scheme. This one seems safer right now.
- Create specific system tests related to consensus and execution communicating through RPC.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it used to run previously but this PR is pretty old and CI workflow was changed, I updated it to run along with defaults-A and defaults-B
| if err := c.Execution.Validate(); err != nil { | ||
| return err | ||
| } | ||
| if c.Node.ExecutionRPCClient.URL == "self" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
c.Node.Sequencer || c.Node.BatchPoster.Enable || c.Node.BlockValidator.Enable check should also be done here.
| if meta.ParentChainBlock <= l1BlockNum { | ||
| signedBlockNum := arbutil.MessageCountToBlockNumber(meta.MessageCount, genesisNum) | ||
| // #nosec G115 | ||
| signedBlockNum := int64(arbutil.MessageIndexToBlockNumber(meta.MessageCount, genesisNum)) - 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick:
| signedBlockNum := int64(arbutil.MessageIndexToBlockNumber(meta.MessageCount, genesisNum)) - 1 | |
| signedBlockNum := int64(arbutil.MessageIndexToBlockNumber(meta.MessageCount-1, genesisNum)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is intentional to avoid underflow
system_tests/common_test.go
Outdated
| return b | ||
| } | ||
|
|
||
| func (b *NodeBuilder) WithConsensusExecutionOverRPC() *NodeBuilder { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick: This func is not being called directly by any system test. Why to make it public, and why not rely on calling configureConsensusExecutionOverRPC directly?
Fixes NIT-2567
I have implemented the JSON-RPC interface for the consensus and execution layer.I setup a basic cli-arg setup has--node.interconnectwhich has 2 options-directthe default uses the pre-existing interfaces-jsonrpcruns the Consensus and Execution interfaces over a json rpcI rundirectand it works fine.jsonrpc fails with "failed to create node err="not connected" which to fix this I assume we need to ensure- the client is connecting to the right jsonrpc server- start the clients after the server is started^ so basically ensuring the server's are running and properly connect before trying to use the interfacesIn terms of scopeHave configuration to use existing interface or new RPC interfaceI set things up with this in mind. In the future I assume that we will allow users to specify running exclusively the consensus side so that a different execution layer client can be chosen, but to my knowledge that task was out of scope of this issue/pr and will definitely require some re-arranging and refactoring of how things are initialized.So I believe this Issue is more of a V1 before we add more complexity to how the node is initialized.If anybody has any questions feel free to ask meUpdated description
#3617 (comment)