Skip to content
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

[Config Change] Multi exec servers #2267

Merged
merged 11 commits into from
May 2, 2024
4 changes: 3 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,9 @@ USER user
FROM nitro-node-dev as nitro-node-split
USER root

RUN apt-get install -y xxd
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
apt-get install -y xxd netcat-traditional
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should remove the apt cache after this

COPY scripts/split-val-entry.sh /usr/local/bin
ENTRYPOINT [ "/usr/local/bin/split-val-entry.sh" ]
PlasmaPower marked this conversation as resolved.
Show resolved Hide resolved
USER user
Expand Down
6 changes: 3 additions & 3 deletions arbnode/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ func ConfigDefaultL1NonSequencerTest() *Config {
config.SyncMonitor = TestSyncMonitorConfig
config.Staker = staker.TestL1ValidatorConfig
config.Staker.Enable = false
config.BlockValidator.ExecutionServerConfigs = []rpcclient.ClientConfig{{URL: ""}}
config.BlockValidator.ValidationServerConfigs = []rpcclient.ClientConfig{{URL: ""}}

return &config
}
Expand All @@ -217,7 +217,7 @@ func ConfigDefaultL2Test() *Config {
config.Staker = staker.TestL1ValidatorConfig
config.SyncMonitor = TestSyncMonitorConfig
config.Staker.Enable = false
config.BlockValidator.ExecutionServerConfigs = []rpcclient.ClientConfig{{URL: ""}}
config.BlockValidator.ValidationServerConfigs = []rpcclient.ClientConfig{{URL: ""}}
config.TransactionStreamer = DefaultTransactionStreamerConfig

return &config
Expand Down Expand Up @@ -540,7 +540,7 @@ func createNodeImpl(
txStreamer.SetInboxReaders(inboxReader, delayedBridge)

var statelessBlockValidator *staker.StatelessBlockValidator
if config.BlockValidator.RedisValidationClientConfig.Enabled() || config.BlockValidator.ExecutionServerConfigs[0].URL != "" {
if config.BlockValidator.RedisValidationClientConfig.Enabled() || config.BlockValidator.ValidationServerConfigs[0].URL != "" {
statelessBlockValidator, err = staker.NewStatelessBlockValidator(
inboxReader,
inboxTracker,
Expand Down
2 changes: 1 addition & 1 deletion cmd/nitro/nitro.go
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ func mainImpl() int {
}

var sameProcessValidationNodeEnabled bool
if nodeConfig.Node.BlockValidator.Enable && (nodeConfig.Node.BlockValidator.ExecutionServerConfigs[0].URL == "self" || nodeConfig.Node.BlockValidator.ExecutionServerConfigs[0].URL == "self-auth") {
if nodeConfig.Node.BlockValidator.Enable && (nodeConfig.Node.BlockValidator.ValidationServerConfigs[0].URL == "self" || nodeConfig.Node.BlockValidator.ValidationServerConfigs[0].URL == "self-auth") {
sameProcessValidationNodeEnabled = true
valnode.EnsureValidationExposedViaAuthRPC(&stackConf)
}
Expand Down
2 changes: 1 addition & 1 deletion nitro-testnode
20 changes: 15 additions & 5 deletions scripts/split-val-entry.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
#!/bin/sh
#!/bin/bash

xxd -l 32 -ps -c 40 /dev/urandom > /tmp/nitro-val.jwt
echo launching validation
/usr/local/bin/nitro-val --file-logging.file nitro-val.log --auth.addr 127.0.0.10 --auth.origins 127.0.0.1 --auth.jwtsecret /tmp/nitro-val.jwt --auth.port 2000 &
sleep 2

echo launching validation servers
# To add validation server:
# > launch them here with a different port and --validation.wasm.root-path
# add their port to wait loop
# edit validation-server-configs-list to include the other nodes
/usr/local/bin/nitro-val --file-logging.enable=false --auth.addr 127.0.0.10 --auth.origins 127.0.0.1 --auth.jwtsecret /tmp/nitro-val.jwt --auth.port 52000 &
for port in 52000; do
while ! nc -w1 -z 127.0.0.10 $port; do
echo waiting for validation port $port
sleep 1
done
done
echo launching nitro-node
/usr/local/bin/nitro --node.block-validator.execution-server.jwtsecret /tmp/nitro-val.jwt --node.block-validator.execution-server.url http://127.0.0.10:2000 "$@"
/usr/local/bin/nitro --node.block-validator.pending-upgrade-module-root="0x8b104a2e80ac6165dc58b9048de12f301d70b02a0ab51396c22b4b4b802a16a4" --node.block-validator.validation-server-configs-list='[{"jwtsecret":"/tmp/nitro-val.jwt","url":"http://127.0.0.10:52000"}]' "$@"
39 changes: 19 additions & 20 deletions staker/block_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ type BlockValidator struct {
type BlockValidatorConfig struct {
Enable bool `koanf:"enable"`
RedisValidationClientConfig redis.ValidationClientConfig `koanf:"redis-validation-client-config"`
ExecutionServer rpcclient.ClientConfig `koanf:"execution-server" reload:"hot"`
ExecutionServerConfigs []rpcclient.ClientConfig `koanf:"execution-server-configs"`
ValidationServer rpcclient.ClientConfig `koanf:"validation-server" reload:"hot"`
ValidationServerConfigs []rpcclient.ClientConfig `koanf:"validation-server-configs"`
ValidationPoll time.Duration `koanf:"validation-poll" reload:"hot"`
PrerecordedBlocks uint64 `koanf:"prerecorded-blocks" reload:"hot"`
ForwardBlocks uint64 `koanf:"forward-blocks" reload:"hot"`
Expand All @@ -103,7 +103,7 @@ type BlockValidatorConfig struct {
FailureIsFatal bool `koanf:"failure-is-fatal" reload:"hot"`
Dangerous BlockValidatorDangerousConfig `koanf:"dangerous"`
MemoryFreeLimit string `koanf:"memory-free-limit" reload:"hot"`
ExecutionServerConfigsList string `koanf:"execution-server-configs-list"`
ValidationServerConfigsList string `koanf:"validation-server-configs-list"`

memoryFreeLimit int
}
Expand All @@ -119,19 +119,19 @@ func (c *BlockValidatorConfig) Validate() error {
c.memoryFreeLimit = limit
}
streamsEnabled := c.RedisValidationClientConfig.Enabled()
if c.ExecutionServerConfigs == nil {
c.ExecutionServerConfigs = []rpcclient.ClientConfig{c.ExecutionServer}
if c.ExecutionServerConfigsList != "default" {
if len(c.ValidationServerConfigs) == 0 {
c.ValidationServerConfigs = []rpcclient.ClientConfig{c.ValidationServer}
if c.ValidationServerConfigsList != "default" {
var executionServersConfigs []rpcclient.ClientConfig
if err := json.Unmarshal([]byte(c.ExecutionServerConfigsList), &executionServersConfigs); err != nil && !streamsEnabled {
if err := json.Unmarshal([]byte(c.ValidationServerConfigsList), &executionServersConfigs); err != nil && !streamsEnabled {
return fmt.Errorf("failed to parse block-validator validation-server-configs-list string: %w", err)
}
c.ExecutionServerConfigs = executionServersConfigs
c.ValidationServerConfigs = executionServersConfigs
}
}
for i := range c.ExecutionServerConfigs {
if err := c.ExecutionServerConfigs[i].Validate(); err != nil {
return fmt.Errorf("failed to validate one of the block-validator execution-server-configs. url: %s, err: %w", c.ExecutionServerConfigs[i].URL, err)
for i := range c.ValidationServerConfigs {
if err := c.ValidationServerConfigs[i].Validate(); err != nil {
return fmt.Errorf("failed to validate one of the block-validator validation-server-configs. url: %s, err: %w", c.ValidationServerConfigs[i].URL, err)
}
}
return nil
Expand All @@ -145,9 +145,9 @@ type BlockValidatorConfigFetcher func() *BlockValidatorConfig

func BlockValidatorConfigAddOptions(prefix string, f *pflag.FlagSet) {
f.Bool(prefix+".enable", DefaultBlockValidatorConfig.Enable, "enable block-by-block validation")
rpcclient.RPCClientAddOptions(prefix+".execution-server", f, &DefaultBlockValidatorConfig.ExecutionServer)
rpcclient.RPCClientAddOptions(prefix+".validation-server", f, &DefaultBlockValidatorConfig.ValidationServer)
redis.ValidationClientConfigAddOptions(prefix+".redis-validation-client-config", f)
f.String(prefix+".execution-server-configs-list", DefaultBlockValidatorConfig.ExecutionServerConfigsList, "array of execution rpc configs given as a json string. time duration should be supplied in number indicating nanoseconds")
f.String(prefix+".validation-server-configs-list", DefaultBlockValidatorConfig.ValidationServerConfigsList, "array of execution rpc configs given as a json string. time duration should be supplied in number indicating nanoseconds")
f.Duration(prefix+".validation-poll", DefaultBlockValidatorConfig.ValidationPoll, "poll time to check validations")
f.Uint64(prefix+".forward-blocks", DefaultBlockValidatorConfig.ForwardBlocks, "prepare entries for up to that many blocks ahead of validation (small footprint)")
f.Uint64(prefix+".prerecorded-blocks", DefaultBlockValidatorConfig.PrerecordedBlocks, "record that many blocks ahead of validation (larger footprint)")
Expand All @@ -164,8 +164,8 @@ func BlockValidatorDangerousConfigAddOptions(prefix string, f *pflag.FlagSet) {

var DefaultBlockValidatorConfig = BlockValidatorConfig{
Enable: false,
ExecutionServerConfigsList: "default",
ExecutionServer: rpcclient.DefaultClientConfig,
ValidationServerConfigsList: "default",
ValidationServer: rpcclient.DefaultClientConfig,
RedisValidationClientConfig: redis.DefaultValidationClientConfig,
ValidationPoll: time.Second,
ForwardBlocks: 1024,
Expand All @@ -179,8 +179,8 @@ var DefaultBlockValidatorConfig = BlockValidatorConfig{

var TestBlockValidatorConfig = BlockValidatorConfig{
Enable: false,
ExecutionServer: rpcclient.TestClientConfig,
ExecutionServerConfigs: []rpcclient.ClientConfig{rpcclient.TestClientConfig},
ValidationServer: rpcclient.TestClientConfig,
ValidationServerConfigs: []rpcclient.ClientConfig{rpcclient.TestClientConfig},
RedisValidationClientConfig: redis.TestValidationClientConfig,
ValidationPoll: 100 * time.Millisecond,
ForwardBlocks: 128,
Expand Down Expand Up @@ -335,7 +335,7 @@ func (v *BlockValidator) GetModuleRootsToValidate() []common.Hash {
defer v.moduleMutex.Unlock()

validatingModuleRoots := []common.Hash{v.currentWasmModuleRoot}
if (v.currentWasmModuleRoot != v.pendingWasmModuleRoot && v.pendingWasmModuleRoot != common.Hash{}) {
if v.currentWasmModuleRoot != v.pendingWasmModuleRoot && v.pendingWasmModuleRoot != (common.Hash{}) {
validatingModuleRoots = append(validatingModuleRoots, v.pendingWasmModuleRoot)
}
return validatingModuleRoots
Expand Down Expand Up @@ -1094,8 +1094,7 @@ func (v *BlockValidator) Initialize(ctx context.Context) error {
for _, root := range moduleRoots {
if v.redisValidator != nil && validator.SpawnerSupportsModule(v.redisValidator, root) {
v.chosenValidator[root] = v.redisValidator
}
if v.chosenValidator[root] == nil {
} else {
for _, spawner := range v.execSpawners {
if validator.SpawnerSupportsModule(spawner, root) {
v.chosenValidator[root] = spawner
Expand Down
6 changes: 3 additions & 3 deletions staker/stateless_block_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,10 @@ func NewStatelessBlockValidator(
return nil, fmt.Errorf("creating new redis validation client: %w", err)
}
}
configs := config().ExecutionServerConfigs
configs := config().ValidationServerConfigs
for i := range configs {
i := i
confFetcher := func() *rpcclient.ClientConfig { return &config().ExecutionServerConfigs[i] }
confFetcher := func() *rpcclient.ClientConfig { return &config().ValidationServerConfigs[i] }
executionSpawners = append(executionSpawners, validatorclient.NewExecutionClient(confFetcher, stack))
}

Expand Down Expand Up @@ -398,7 +398,7 @@ func (v *StatelessBlockValidator) ValidateResult(
}
}
if run == nil {
return false, &entry.End, errors.New("this validation not supported by node")
return false, nil, fmt.Errorf("validation woth WasmModuleRoot %v not supported by node", moduleRoot)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: woth -> with

}
defer run.Cancel()
gsEnd, err := run.Await(ctx)
Expand Down
4 changes: 2 additions & 2 deletions system_tests/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -579,8 +579,8 @@ func StaticFetcherFrom[T any](t *testing.T, config *T) func() *T {
}

func configByValidationNode(clientConfig *arbnode.Config, valStack *node.Node) {
clientConfig.BlockValidator.ExecutionServerConfigs[0].URL = valStack.WSEndpoint()
clientConfig.BlockValidator.ExecutionServerConfigs[0].JWTSecret = ""
clientConfig.BlockValidator.ValidationServerConfigs[0].URL = valStack.WSEndpoint()
clientConfig.BlockValidator.ValidationServerConfigs[0].JWTSecret = ""
}

func currentRootModule(t *testing.T) common.Hash {
Expand Down
Loading