From 2afb28b61d882aee3c3d0a438b66edc35d4a88a2 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Thu, 9 Mar 2023 17:42:34 +0200 Subject: [PATCH 01/23] execnode - initial, only build passes --- arbnode/delayed_sequencer.go | 6 +- arbnode/execution/node.go | 89 ----- arbnode/inbox_test.go | 5 +- arbnode/node.go | 199 +++-------- arbnode/seq_coordinator.go | 7 +- arbnode/transaction_streamer.go | 8 +- cmd/nitro/init.go | 16 +- cmd/nitro/nitro.go | 37 +- .../execution => execution/gethclient}/api.go | 2 +- .../gethclient}/arb_interface.go | 2 +- .../gethclient}/block_recorder.go | 19 +- .../gethclient}/blockchain.go | 2 +- .../gethclient}/executionengine.go | 34 +- .../gethclient}/forwarder.go | 2 +- execution/gethclient/node.go | 333 ++++++++++++++++++ .../gethclient}/sequencer.go | 7 +- .../gethclient}/tx_pre_checker.go | 2 +- execution/interface.go | 77 ++++ go-ethereum | 2 +- nodeInterface/NodeInterface.go | 15 +- nodeInterface/virtual-contracts.go | 12 + staker/stateless_block_validator.go | 18 +- 22 files changed, 556 insertions(+), 338 deletions(-) delete mode 100644 arbnode/execution/node.go rename {arbnode/execution => execution/gethclient}/api.go (99%) rename {arbnode/execution => execution/gethclient}/arb_interface.go (98%) rename {arbnode/execution => execution/gethclient}/block_recorder.go (97%) rename {arbnode/execution => execution/gethclient}/blockchain.go (99%) rename {arbnode/execution => execution/gethclient}/executionengine.go (95%) rename {arbnode/execution => execution/gethclient}/forwarder.go (99%) create mode 100644 execution/gethclient/node.go rename {arbnode/execution => execution/gethclient}/sequencer.go (99%) rename {arbnode/execution => execution/gethclient}/tx_pre_checker.go (99%) create mode 100644 execution/interface.go diff --git a/arbnode/delayed_sequencer.go b/arbnode/delayed_sequencer.go index b308b464b9..9a0cb29153 100644 --- a/arbnode/delayed_sequencer.go +++ b/arbnode/delayed_sequencer.go @@ -15,8 +15,8 @@ import ( "github.com/ethereum/go-ethereum/log" flag "github.com/spf13/pflag" - "github.com/offchainlabs/nitro/arbnode/execution" "github.com/offchainlabs/nitro/arbos/arbostypes" + "github.com/offchainlabs/nitro/execution" "github.com/offchainlabs/nitro/util/headerreader" "github.com/offchainlabs/nitro/util/stopwaiter" ) @@ -26,7 +26,7 @@ type DelayedSequencer struct { l1Reader *headerreader.HeaderReader bridge *DelayedBridge inbox *InboxTracker - exec *execution.ExecutionEngine + exec execution.ExecutionClient coordinator *SeqCoordinator waitingForFinalizedBlock uint64 mutex sync.Mutex @@ -63,7 +63,7 @@ var TestDelayedSequencerConfig = DelayedSequencerConfig{ UseMergeFinality: true, } -func NewDelayedSequencer(l1Reader *headerreader.HeaderReader, reader *InboxReader, exec *execution.ExecutionEngine, coordinator *SeqCoordinator, config DelayedSequencerConfigFetcher) (*DelayedSequencer, error) { +func NewDelayedSequencer(l1Reader *headerreader.HeaderReader, reader *InboxReader, exec execution.ExecutionClient, coordinator *SeqCoordinator, config DelayedSequencerConfigFetcher) (*DelayedSequencer, error) { d := &DelayedSequencer{ l1Reader: l1Reader, bridge: reader.DelayedBridge(), diff --git a/arbnode/execution/node.go b/arbnode/execution/node.go deleted file mode 100644 index e59a56876f..0000000000 --- a/arbnode/execution/node.go +++ /dev/null @@ -1,89 +0,0 @@ -package execution - -import ( - "errors" - - "github.com/ethereum/go-ethereum/arbitrum" - "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/eth/filters" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/node" - "github.com/offchainlabs/nitro/util/headerreader" -) - -type ExecutionNode struct { - ChainDB ethdb.Database - Backend *arbitrum.Backend - FilterSystem *filters.FilterSystem - ArbInterface *ArbInterface - ExecEngine *ExecutionEngine - Recorder *BlockRecorder - Sequencer *Sequencer // either nil or same as TxPublisher - TxPublisher TransactionPublisher -} - -func CreateExecutionNode( - stack *node.Node, - chainDB ethdb.Database, - l2BlockChain *core.BlockChain, - l1Reader *headerreader.HeaderReader, - syncMonitor arbitrum.SyncProgressBackend, - fwTarget string, - fwConfig *ForwarderConfig, - rpcConfig arbitrum.Config, - seqConfigFetcher SequencerConfigFetcher, - strictnessFetcher func() uint, -) (*ExecutionNode, error) { - execEngine, err := NewExecutionEngine(l2BlockChain) - if err != nil { - return nil, err - } - recorder := NewBlockRecorder(execEngine, chainDB) - var txPublisher TransactionPublisher - var sequencer *Sequencer - seqConfig := seqConfigFetcher() - if seqConfig.Enable { - if fwTarget != "" { - return nil, errors.New("sequencer and forwarding target both set") - } - sequencer, err = NewSequencer(execEngine, l1Reader, seqConfigFetcher) - if err != nil { - return nil, err - } - txPublisher = sequencer - } else { - if fwConfig.RedisUrl != "" { - txPublisher = NewRedisTxForwarder(fwTarget, fwConfig) - } else if fwTarget == "" { - txPublisher = NewTxDropper() - } else { - txPublisher = NewForwarder(fwTarget, fwConfig) - } - } - - txPublisher = NewTxPreChecker(txPublisher, l2BlockChain, strictnessFetcher) - arbInterface, err := NewArbInterface(execEngine, txPublisher) - if err != nil { - return nil, err - } - filterConfig := filters.Config{ - LogCacheSize: rpcConfig.FilterLogCacheSize, - Timeout: rpcConfig.FilterTimeout, - } - backend, filterSystem, err := arbitrum.NewBackend(stack, &rpcConfig, chainDB, arbInterface, syncMonitor, filterConfig) - if err != nil { - return nil, err - } - - return &ExecutionNode{ - chainDB, - backend, - filterSystem, - arbInterface, - execEngine, - recorder, - sequencer, - txPublisher, - }, nil - -} diff --git a/arbnode/inbox_test.go b/arbnode/inbox_test.go index 8f67f83eb9..037bbc2945 100644 --- a/arbnode/inbox_test.go +++ b/arbnode/inbox_test.go @@ -11,10 +11,11 @@ import ( "testing" "time" - "github.com/offchainlabs/nitro/arbnode/execution" "github.com/offchainlabs/nitro/arbos/arbostypes" "github.com/offchainlabs/nitro/arbos/l2pricing" "github.com/offchainlabs/nitro/arbutil" + "github.com/offchainlabs/nitro/execution" + "github.com/offchainlabs/nitro/execution/gethclient" "github.com/offchainlabs/nitro/statetransfer" nitroutil "github.com/offchainlabs/nitro/util" @@ -45,7 +46,7 @@ func NewTransactionStreamerForTest(t *testing.T, ownerAddress common.Address) (* arbDb := rawdb.NewMemoryDatabase() initReader := statetransfer.NewMemoryInitDataReader(&initData) - bc, err := execution.WriteOrTestBlockChain(chainDb, nil, initReader, chainConfig, ConfigDefaultL2Test().TxLookupLimit, 0) + bc, err := gethclient.WriteOrTestBlockChain(chainDb, nil, initReader, chainConfig, ConfigDefaultL2Test().TxLookupLimit, 0) if err != nil { Fail(t, err) diff --git a/arbnode/node.go b/arbnode/node.go index c7a38a4e5e..b6c002a0ed 100644 --- a/arbnode/node.go +++ b/arbnode/node.go @@ -14,25 +14,23 @@ import ( flag "github.com/spf13/pflag" "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/arbitrum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" - "github.com/offchainlabs/nitro/arbnode/execution" "github.com/offchainlabs/nitro/arbutil" "github.com/offchainlabs/nitro/broadcastclient" "github.com/offchainlabs/nitro/broadcastclients" "github.com/offchainlabs/nitro/broadcaster" "github.com/offchainlabs/nitro/das" + "github.com/offchainlabs/nitro/execution" "github.com/offchainlabs/nitro/solgen/go/bridgegen" "github.com/offchainlabs/nitro/solgen/go/challengegen" "github.com/offchainlabs/nitro/solgen/go/ospgen" @@ -384,36 +382,26 @@ func DeployOnL1(ctx context.Context, l1client arbutil.L1Interface, deployAuth *b } type Config struct { - RPC arbitrum.Config `koanf:"rpc"` - Sequencer execution.SequencerConfig `koanf:"sequencer" reload:"hot"` - L1Reader headerreader.Config `koanf:"l1-reader" reload:"hot"` - InboxReader InboxReaderConfig `koanf:"inbox-reader" reload:"hot"` - DelayedSequencer DelayedSequencerConfig `koanf:"delayed-sequencer" reload:"hot"` - BatchPoster BatchPosterConfig `koanf:"batch-poster" reload:"hot"` - ForwardingTargetImpl string `koanf:"forwarding-target"` - Forwarder execution.ForwarderConfig `koanf:"forwarder"` - TxPreCheckerStrictness uint `koanf:"tx-pre-checker-strictness" reload:"hot"` - BlockValidator staker.BlockValidatorConfig `koanf:"block-validator" reload:"hot"` - Feed broadcastclient.FeedConfig `koanf:"feed" reload:"hot"` - Staker staker.L1ValidatorConfig `koanf:"staker"` - SeqCoordinator SeqCoordinatorConfig `koanf:"seq-coordinator"` - DataAvailability das.DataAvailabilityConfig `koanf:"data-availability"` - SyncMonitor SyncMonitorConfig `koanf:"sync-monitor"` - Dangerous DangerousConfig `koanf:"dangerous"` - Caching execution.CachingConfig `koanf:"caching"` - Archive bool `koanf:"archive"` - TxLookupLimit uint64 `koanf:"tx-lookup-limit"` - TransactionStreamer TransactionStreamerConfig `koanf:"transaction-streamer" reload:"hot"` - Maintenance MaintenanceConfig `koanf:"maintenance" reload:"hot"` + Sequencer bool `koanf:"sequencer"` + L1Reader headerreader.Config `koanf:"l1-reader" reload:"hot"` + InboxReader InboxReaderConfig `koanf:"inbox-reader" reload:"hot"` + DelayedSequencer DelayedSequencerConfig `koanf:"delayed-sequencer" reload:"hot"` + BatchPoster BatchPosterConfig `koanf:"batch-poster" reload:"hot"` + BlockValidator staker.BlockValidatorConfig `koanf:"block-validator" reload:"hot"` + Feed broadcastclient.FeedConfig `koanf:"feed" reload:"hot"` + Staker staker.L1ValidatorConfig `koanf:"staker"` + SeqCoordinator SeqCoordinatorConfig `koanf:"seq-coordinator"` + DataAvailability das.DataAvailabilityConfig `koanf:"data-availability"` + SyncMonitor SyncMonitorConfig `koanf:"sync-monitor"` + Dangerous DangerousConfig `koanf:"dangerous"` + TransactionStreamer TransactionStreamerConfig `koanf:"transaction-streamer" reload:"hot"` + Maintenance MaintenanceConfig `koanf:"maintenance" reload:"hot"` } func (c *Config) Validate() error { - if c.L1Reader.Enable && c.Sequencer.Enable && !c.DelayedSequencer.Enable { + if c.L1Reader.Enable && c.Sequencer && !c.DelayedSequencer.Enable { log.Warn("delayed sequencer is not enabled, despite sequencer and l1 reader being enabled") } - if err := c.Sequencer.Validate(); err != nil { - return err - } if err := c.Maintenance.Validate(); err != nil { return err } @@ -441,14 +429,6 @@ func (c *Config) Started() bool { return true } -func (c *Config) ForwardingTarget() string { - if c.ForwardingTargetImpl == "null" { - return "" - } - - return c.ForwardingTargetImpl -} - func (c *Config) ValidatorRequired() bool { if c.BlockValidator.Enable { return true @@ -460,18 +440,11 @@ func (c *Config) ValidatorRequired() bool { } func ConfigAddOptions(prefix string, f *flag.FlagSet, feedInputEnable bool, feedOutputEnable bool) { - arbitrum.ConfigAddOptions(prefix+".rpc", f) - execution.SequencerConfigAddOptions(prefix+".sequencer", f) + f.Bool(prefix+".sequencer", ConfigDefault.Sequencer, "enable sequencer") headerreader.AddOptions(prefix+".l1-reader", f) InboxReaderConfigAddOptions(prefix+".inbox-reader", f) DelayedSequencerConfigAddOptions(prefix+".delayed-sequencer", f) BatchPosterConfigAddOptions(prefix+".batch-poster", f) - f.String(prefix+".forwarding-target", ConfigDefault.ForwardingTargetImpl, "transaction forwarding target URL, or \"null\" to disable forwarding (iff not sequencer)") - execution.AddOptionsForNodeForwarderConfig(prefix+".forwarder", f) - txPreCheckerDescription := "how strict to be when checking txs before forwarding them. 0 = accept anything, " + - "10 = should never reject anything that'd succeed, 20 = likely won't reject anything that'd succeed, " + - "30 = full validation which may reject txs that would succeed" - f.Uint(prefix+".tx-pre-checker-strictness", ConfigDefault.TxPreCheckerStrictness, txPreCheckerDescription) staker.BlockValidatorConfigAddOptions(prefix+".block-validator", f) broadcastclient.FeedConfigAddOptions(prefix+".feed", f, feedInputEnable, feedOutputEnable) staker.L1ValidatorConfigAddOptions(prefix+".staker", f) @@ -479,40 +452,26 @@ func ConfigAddOptions(prefix string, f *flag.FlagSet, feedInputEnable bool, feed das.DataAvailabilityConfigAddNodeOptions(prefix+".data-availability", f) SyncMonitorConfigAddOptions(prefix+".sync-monitor", f) DangerousConfigAddOptions(prefix+".dangerous", f) - execution.CachingConfigAddOptions(prefix+".caching", f) - f.Uint64(prefix+".tx-lookup-limit", ConfigDefault.TxLookupLimit, "retain the ability to lookup transactions by hash for the past N blocks (0 = all blocks)") TransactionStreamerConfigAddOptions(prefix+".transaction-streamer", f) MaintenanceConfigAddOptions(prefix+".maintenance", f) - - archiveMsg := fmt.Sprintf("retain past block state (deprecated, please use %v.caching.archive)", prefix) - f.Bool(prefix+".archive", ConfigDefault.Archive, archiveMsg) } var ConfigDefault = Config{ - RPC: arbitrum.DefaultConfig, - Sequencer: execution.DefaultSequencerConfig, - L1Reader: headerreader.DefaultConfig, - InboxReader: DefaultInboxReaderConfig, - DelayedSequencer: DefaultDelayedSequencerConfig, - BatchPoster: DefaultBatchPosterConfig, - ForwardingTargetImpl: "", - TxPreCheckerStrictness: execution.TxPreCheckerStrictnessNone, - BlockValidator: staker.DefaultBlockValidatorConfig, - Feed: broadcastclient.FeedConfigDefault, - Staker: staker.DefaultL1ValidatorConfig, - SeqCoordinator: DefaultSeqCoordinatorConfig, - DataAvailability: das.DefaultDataAvailabilityConfig, - SyncMonitor: DefaultSyncMonitorConfig, - Dangerous: DefaultDangerousConfig, - Archive: false, - TxLookupLimit: 126_230_400, // 1 year at 4 blocks per second - Caching: execution.DefaultCachingConfig, - TransactionStreamer: DefaultTransactionStreamerConfig, + L1Reader: headerreader.DefaultConfig, + InboxReader: DefaultInboxReaderConfig, + DelayedSequencer: DefaultDelayedSequencerConfig, + BatchPoster: DefaultBatchPosterConfig, + BlockValidator: staker.DefaultBlockValidatorConfig, + Feed: broadcastclient.FeedConfigDefault, + Staker: staker.DefaultL1ValidatorConfig, + SeqCoordinator: DefaultSeqCoordinatorConfig, + DataAvailability: das.DefaultDataAvailabilityConfig, + SyncMonitor: DefaultSyncMonitorConfig, + TransactionStreamer: DefaultTransactionStreamerConfig, } func ConfigDefaultL1Test() *Config { config := ConfigDefaultL1NonSequencerTest() - config.Sequencer = execution.TestSequencerConfig config.DelayedSequencer = TestDelayedSequencerConfig config.BatchPoster = TestBatchPosterConfig config.SeqCoordinator = TestSeqCoordinatorConfig @@ -524,19 +483,16 @@ func ConfigDefaultL1NonSequencerTest() *Config { config := ConfigDefault config.L1Reader = headerreader.TestConfig config.InboxReader = TestInboxReaderConfig - config.Sequencer.Enable = false config.DelayedSequencer.Enable = false config.BatchPoster.Enable = false config.SeqCoordinator.Enable = false config.BlockValidator = staker.TestBlockValidatorConfig - config.Forwarder = execution.DefaultTestForwarderConfig return &config } func ConfigDefaultL2Test() *Config { config := ConfigDefault - config.Sequencer = execution.TestSequencerConfig config.L1Reader.Enable = false config.SeqCoordinator = TestSeqCoordinatorConfig config.Feed.Input.Verifier.Dangerous.AcceptMissing = true @@ -548,24 +504,24 @@ func ConfigDefaultL2Test() *Config { } type DangerousConfig struct { - NoL1Listener bool `koanf:"no-l1-listener"` - ReorgToBlock int64 `koanf:"reorg-to-block"` + NoL1Listener bool `koanf:"no-l1-listener"` + NoCoordinator bool `koanf:"no-seq-coordinator"` } var DefaultDangerousConfig = DangerousConfig{ - NoL1Listener: false, - ReorgToBlock: -1, + NoL1Listener: false, + NoCoordinator: false, } func DangerousConfigAddOptions(prefix string, f *flag.FlagSet) { f.Bool(prefix+".no-l1-listener", DefaultDangerousConfig.NoL1Listener, "DANGEROUS! disables listening to L1. To be used in test nodes only") - f.Int64(prefix+".reorg-to-block", DefaultDangerousConfig.ReorgToBlock, "DANGEROUS! forces a reorg to an old block height. To be used for testing only. -1 to disable") + f.Bool(prefix+".no-seq-coordinator", DefaultDangerousConfig.NoCoordinator, "DANGEROUS! allows sequencing without sequencer-coordinator") } type Node struct { ArbDB ethdb.Database Stack *node.Node - Execution *execution.ExecutionNode + Execution execution.ExecutionClient L1Reader *headerreader.HeaderReader TxStreamer *TransactionStreamer DeployInfo *RollupAddresses @@ -637,6 +593,7 @@ func checkArbDbSchemaVersion(arbDb ethdb.Database) error { func createNodeImpl( ctx context.Context, stack *node.Node, + exec execution.FullExecutionClient, chainDb ethdb.Database, arbDb ethdb.Database, configFetcher ConfigFetcher, @@ -659,12 +616,7 @@ func createNodeImpl( //TODO: // var reorgingToBlock *types.Block - if config.Dangerous.ReorgToBlock >= 0 { - _, err = execution.ReorgToBlock(l2BlockChain, uint64(config.Dangerous.ReorgToBlock)) - if err != nil { - return nil, err - } - } + // config.Dangerous.ReorgToBlock >= 0 { syncMonitor := NewSyncMonitor(&config.SyncMonitor) var classicOutbox *ClassicOutboxRetriever @@ -683,15 +635,6 @@ func createNodeImpl( l1Reader = headerreader.New(l1client, func() *headerreader.Config { return &configFetcher.Get().L1Reader }) } - sequencerConfigFetcher := func() *execution.SequencerConfig { return &configFetcher.Get().Sequencer } - txprecheckStrictFetcher := func() uint { return configFetcher.Get().TxPreCheckerStrictness } - exec, err := execution.CreateExecutionNode(stack, chainDb, l2BlockChain, l1Reader, syncMonitor, - config.ForwardingTarget(), &config.Forwarder, config.RPC, - sequencerConfigFetcher, txprecheckStrictFetcher) - if err != nil { - return nil, err - } - var broadcastServer *broadcaster.Broadcaster if config.Feed.Output.Enable { var maybeDataSigner signature.DataSignerFunc @@ -705,7 +648,7 @@ func createNodeImpl( } transactionStreamerConfigFetcher := func() *TransactionStreamerConfig { return &configFetcher.Get().TransactionStreamer } - txStreamer, err := NewTransactionStreamer(arbDb, l2Config, exec.ExecEngine, broadcastServer, fatalErrChan, transactionStreamerConfigFetcher) + txStreamer, err := NewTransactionStreamer(arbDb, l2Config, exec, broadcastServer, fatalErrChan, transactionStreamerConfigFetcher) if err != nil { return nil, err } @@ -721,16 +664,12 @@ func createNodeImpl( bpVerifier = contracts.NewBatchPosterVerifier(seqInboxCaller) } - if config.DelayedSequencer.Enable != (config.Sequencer.Enable && (l1Reader != nil)) { - return nil, errors.New("cannot have delayedsequencer without sequencer or vice versa") - } - if config.SeqCoordinator.Enable { - coordinator, err = NewSeqCoordinator(dataSigner, bpVerifier, txStreamer, exec.Sequencer, syncMonitor, config.SeqCoordinator) + coordinator, err = NewSeqCoordinator(dataSigner, bpVerifier, txStreamer, exec, syncMonitor, config.SeqCoordinator) if err != nil { return nil, err } - } else if config.Sequencer.Enable && (!config.Sequencer.Dangerous.NoCoordinator) { + } else if config.Sequencer && (!config.Dangerous.NoCoordinator) { return nil, errors.New("sequencer must be enabled with coordinator, unless dangerous.no-coordinator set") } dbs := []ethdb.Database{chainDb, arbDb} @@ -843,7 +782,7 @@ func createNodeImpl( inboxReader, inboxTracker, txStreamer, - exec.Recorder, + exec, rawdb.NewTable(arbDb, blockValidatorPrefix), daReader, &configFetcher.Get().BlockValidator, @@ -933,7 +872,7 @@ func createNodeImpl( } } // always create DelayedSequencer, it won't do anything if it is disabled - delayedSequencer, err = NewDelayedSequencer(l1Reader, inboxReader, exec.ExecEngine, coordinator, func() *DelayedSequencerConfig { return &configFetcher.Get().DelayedSequencer }) + delayedSequencer, err = NewDelayedSequencer(l1Reader, inboxReader, exec, coordinator, func() *DelayedSequencerConfig { return &configFetcher.Get().DelayedSequencer }) if err != nil { return nil, err } @@ -972,6 +911,7 @@ func (n *Node) OnConfigReload(_ *Config, _ *Config) error { func CreateNode( ctx context.Context, stack *node.Node, + exec execution.FullExecutionClient, chainDb ethdb.Database, arbDb ethdb.Database, configFetcher ConfigFetcher, @@ -982,7 +922,7 @@ func CreateNode( dataSigner signature.DataSignerFunc, fatalErrChan chan error, ) (*Node, error) { - currentNode, err := createNodeImpl(ctx, stack, chainDb, arbDb, configFetcher, l2BlockChain, l1client, deployInfo, txOpts, dataSigner, fatalErrChan) + currentNode, err := createNodeImpl(ctx, stack, exec, chainDb, arbDb, configFetcher, l2BlockChain, l1client, deployInfo, txOpts, dataSigner, fatalErrChan) if err != nil { return nil, err } @@ -1007,37 +947,6 @@ func CreateNode( }) } - apis = append(apis, rpc.API{ - Namespace: "arb", - Version: "1.0", - Service: execution.NewArbAPI(currentNode.Execution.TxPublisher), - Public: false, - }) - config := configFetcher.Get() - apis = append(apis, rpc.API{ - Namespace: "arbdebug", - Version: "1.0", - Service: execution.NewArbDebugAPI( - l2BlockChain, - config.RPC.ArbDebug.BlockRangeBound, - config.RPC.ArbDebug.TimeoutQueueBound, - ), - Public: false, - }) - apis = append(apis, rpc.API{ - Namespace: "arbtrace", - Version: "1.0", - Service: execution.NewArbTraceForwarderAPI( - config.RPC.ClassicRedirect, - config.RPC.ClassicRedirectTimeout, - ), - Public: false, - }) - apis = append(apis, rpc.API{ - Namespace: "debug", - Service: eth.NewDebugAPI(eth.NewArbEthereum(l2BlockChain, chainDb)), - Public: false, - }) stack.RegisterAPIs(apis) return currentNode, nil @@ -1045,19 +954,10 @@ func CreateNode( func (n *Node) Start(ctx context.Context) error { n.SyncMonitor.Initialize(n.InboxReader, n.TxStreamer, n.SeqCoordinator) - n.Execution.ArbInterface.Initialize(n) err := n.Stack.Start() if err != nil { return fmt.Errorf("error starting geth stack: %w", err) } - err = n.Execution.Backend.Start() - if err != nil { - return fmt.Errorf("error starting geth backend: %w", err) - } - err = n.Execution.TxPublisher.Initialize(ctx) - if err != nil { - return fmt.Errorf("error initializing transaction publisher: %w", err) - } if n.InboxTracker != nil { err = n.InboxTracker.Initialize() if err != nil { @@ -1074,14 +974,12 @@ func (n *Node) Start(ctx context.Context) error { if err != nil { return fmt.Errorf("error starting transaction streamer: %w", err) } - n.Execution.ExecEngine.Start(ctx) if n.InboxReader != nil { err = n.InboxReader.Start(ctx) if err != nil { return fmt.Errorf("error starting inbox reader: %w", err) } } - err = n.Execution.TxPublisher.Start(ctx) if err != nil { return fmt.Errorf("error starting transaction puiblisher: %w", err) } @@ -1168,9 +1066,6 @@ func (n *Node) StopAndWait() { n.SeqCoordinator.PrepareForShutdown() } n.Stack.StopRPC() // does nothing if not running - if n.Execution.TxPublisher.Started() { - n.Execution.TxPublisher.StopAndWait() - } if n.DelayedSequencer != nil && n.DelayedSequencer.Started() { n.DelayedSequencer.StopAndWait() } @@ -1192,7 +1087,6 @@ func (n *Node) StopAndWait() { if n.StatelessBlockValidator != nil { n.StatelessBlockValidator.Stop() } - n.Execution.Recorder.OrderlyShutdown() if n.InboxReader != nil && n.InboxReader.Started() { n.InboxReader.StopAndWait() } @@ -1202,17 +1096,10 @@ func (n *Node) StopAndWait() { if n.TxStreamer.Started() { n.TxStreamer.StopAndWait() } - if n.Execution.ExecEngine.Started() { - n.Execution.ExecEngine.StopAndWait() - } if n.SeqCoordinator != nil && n.SeqCoordinator.Started() { // Just stops the redis client (most other stuff was stopped earlier) n.SeqCoordinator.StopAndWait() } - n.Execution.ArbInterface.BlockChain().Stop() // does nothing if not running - if err := n.Execution.Backend.Stop(); err != nil { - log.Error("backend stop", "err", err) - } if n.DASLifecycleManager != nil { n.DASLifecycleManager.StopAndWaitUntil(2 * time.Second) } diff --git a/arbnode/seq_coordinator.go b/arbnode/seq_coordinator.go index 16df3153c2..60a9616bf5 100644 --- a/arbnode/seq_coordinator.go +++ b/arbnode/seq_coordinator.go @@ -20,9 +20,9 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" - "github.com/offchainlabs/nitro/arbnode/execution" "github.com/offchainlabs/nitro/arbos/arbostypes" "github.com/offchainlabs/nitro/arbutil" + "github.com/offchainlabs/nitro/execution" "github.com/offchainlabs/nitro/util/arbmath" "github.com/offchainlabs/nitro/util/contracts" "github.com/offchainlabs/nitro/util/redisutil" @@ -41,7 +41,7 @@ type SeqCoordinator struct { sync *SyncMonitor streamer *TransactionStreamer - sequencer *execution.Sequencer + sequencer execution.ExecutionSequencer delayedSequencer *DelayedSequencer signer *signature.SignVerify config SeqCoordinatorConfig // warning: static, don't use for hot reloadable fields @@ -132,7 +132,8 @@ var TestSeqCoordinatorConfig = SeqCoordinatorConfig{ Signing: signature.DefaultSignVerifyConfig, } -func NewSeqCoordinator(dataSigner signature.DataSignerFunc, bpvalidator *contracts.BatchPosterVerifier, streamer *TransactionStreamer, sequencer *execution.Sequencer, sync *SyncMonitor, config SeqCoordinatorConfig) (*SeqCoordinator, error) { +func NewSeqCoordinator(dataSigner signature.DataSignerFunc, bpvalidator *contracts.BatchPosterVerifier, streamer *TransactionStreamer, sequencer execution.ExecutionSequencer, + sync *SyncMonitor, config SeqCoordinatorConfig) (*SeqCoordinator, error) { redisCoordinator, err := redisutil.NewRedisCoordinator(config.RedisUrl) if err != nil { return nil, err diff --git a/arbnode/transaction_streamer.go b/arbnode/transaction_streamer.go index 0fa5e6886c..f0228272b7 100644 --- a/arbnode/transaction_streamer.go +++ b/arbnode/transaction_streamer.go @@ -26,10 +26,10 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" - "github.com/offchainlabs/nitro/arbnode/execution" "github.com/offchainlabs/nitro/arbos/arbostypes" "github.com/offchainlabs/nitro/arbutil" "github.com/offchainlabs/nitro/broadcaster" + "github.com/offchainlabs/nitro/execution" "github.com/offchainlabs/nitro/staker" "github.com/offchainlabs/nitro/util/sharedmetrics" "github.com/offchainlabs/nitro/util/stopwaiter" @@ -41,7 +41,7 @@ type TransactionStreamer struct { stopwaiter.StopWaiter chainConfig *params.ChainConfig - exec *execution.ExecutionEngine + exec execution.FullExecutionClient validator *staker.BlockValidator db ethdb.Database @@ -86,7 +86,7 @@ func TransactionStreamerConfigAddOptions(prefix string, f *flag.FlagSet) { func NewTransactionStreamer( db ethdb.Database, chainConfig *params.ChainConfig, - exec *execution.ExecutionEngine, + exec execution.FullExecutionClient, broadcastServer *broadcaster.Broadcaster, fatalErrChan chan<- error, config TransactionStreamerConfigFetcher, @@ -860,7 +860,7 @@ func (s *TransactionStreamer) ResultAtCount(count arbutil.MessageIndex) (*execut } // return value: true if should be called again -func (s *TransactionStreamer) executeNextMsg(ctx context.Context, exec *execution.ExecutionEngine) bool { +func (s *TransactionStreamer) executeNextMsg(ctx context.Context, exec execution.ExecutionClient) bool { if ctx.Err() != nil { return false } diff --git a/cmd/nitro/init.go b/cmd/nitro/init.go index 8e50eabcb5..c4d13c8617 100644 --- a/cmd/nitro/init.go +++ b/cmd/nitro/init.go @@ -23,10 +23,10 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/params" - "github.com/offchainlabs/nitro/arbnode/execution" "github.com/offchainlabs/nitro/arbos" "github.com/offchainlabs/nitro/arbos/arbosState" "github.com/offchainlabs/nitro/cmd/ipfshelper" + "github.com/offchainlabs/nitro/execution/gethclient" "github.com/offchainlabs/nitro/statetransfer" "github.com/pkg/errors" flag "github.com/spf13/pflag" @@ -176,13 +176,13 @@ func validateBlockChain(blockChain *core.BlockChain, expectedChainId *big.Int) e func openInitializeChainDb(ctx context.Context, stack *node.Node, config *NodeConfig, chainId *big.Int, cacheConfig *core.CacheConfig) (ethdb.Database, *core.BlockChain, error) { if !config.Init.Force { if readOnlyDb, err := stack.OpenDatabaseWithFreezer("l2chaindata", 0, 0, "", "", true); err == nil { - if chainConfig := execution.TryReadStoredChainConfig(readOnlyDb); chainConfig != nil { + if chainConfig := gethclient.TryReadStoredChainConfig(readOnlyDb); chainConfig != nil { readOnlyDb.Close() - chainDb, err := stack.OpenDatabaseWithFreezer("l2chaindata", config.Node.Caching.DatabaseCache, config.Persistent.Handles, "", "", false) + chainDb, err := stack.OpenDatabaseWithFreezer("l2chaindata", config.Execution.Caching.DatabaseCache, config.Persistent.Handles, "", "", false) if err != nil { return chainDb, nil, err } - l2BlockChain, err := execution.GetBlockChain(chainDb, cacheConfig, chainConfig, config.Node.TxLookupLimit) + l2BlockChain, err := gethclient.GetBlockChain(chainDb, cacheConfig, chainConfig, config.Execution.TxLookupLimit) if err != nil { return chainDb, nil, err } @@ -219,7 +219,7 @@ func openInitializeChainDb(ctx context.Context, stack *node.Node, config *NodeCo var initDataReader statetransfer.InitDataReader = nil - chainDb, err := stack.OpenDatabaseWithFreezer("l2chaindata", config.Node.Caching.DatabaseCache, config.Persistent.Handles, "", "", false) + chainDb, err := stack.OpenDatabaseWithFreezer("l2chaindata", config.Execution.Caching.DatabaseCache, config.Persistent.Handles, "", "", false) if err != nil { return chainDb, nil, err } @@ -261,11 +261,11 @@ func openInitializeChainDb(ctx context.Context, stack *node.Node, config *NodeCo var l2BlockChain *core.BlockChain txIndexWg := sync.WaitGroup{} if initDataReader == nil { - chainConfig = execution.TryReadStoredChainConfig(chainDb) + chainConfig = gethclient.TryReadStoredChainConfig(chainDb) if chainConfig == nil { return chainDb, nil, errors.New("no --init.* mode supplied and chain data not in expected directory") } - l2BlockChain, err = execution.GetBlockChain(chainDb, cacheConfig, chainConfig, config.Node.TxLookupLimit) + l2BlockChain, err = gethclient.GetBlockChain(chainDb, cacheConfig, chainConfig, config.Execution.TxLookupLimit) if err != nil { return chainDb, nil, err } @@ -307,7 +307,7 @@ func openInitializeChainDb(ctx context.Context, stack *node.Node, config *NodeCo if config.Init.ThenQuit { cacheConfig.SnapshotWait = true } - l2BlockChain, err = execution.WriteOrTestBlockChain(chainDb, cacheConfig, initDataReader, chainConfig, config.Node.TxLookupLimit, config.Init.AccountsPerSync) + l2BlockChain, err = gethclient.WriteOrTestBlockChain(chainDb, cacheConfig, initDataReader, chainConfig, config.Execution.TxLookupLimit, config.Init.AccountsPerSync) if err != nil { return chainDb, nil, err } diff --git a/cmd/nitro/nitro.go b/cmd/nitro/nitro.go index 40271ab8ae..a2f1cff2ba 100644 --- a/cmd/nitro/nitro.go +++ b/cmd/nitro/nitro.go @@ -45,11 +45,11 @@ import ( "github.com/ethereum/go-ethereum/rpc" "github.com/offchainlabs/nitro/arbnode" - "github.com/offchainlabs/nitro/arbnode/execution" "github.com/offchainlabs/nitro/cmd/conf" "github.com/offchainlabs/nitro/cmd/genericconf" "github.com/offchainlabs/nitro/cmd/util" "github.com/offchainlabs/nitro/cmd/util/confighelpers" + "github.com/offchainlabs/nitro/execution/gethclient" _ "github.com/offchainlabs/nitro/nodeInterface" "github.com/offchainlabs/nitro/staker" "github.com/offchainlabs/nitro/util/colors" @@ -273,9 +273,9 @@ func mainImpl() int { fmt.Fprintf(os.Stderr, "Error initializing logging: %v\n", err) os.Exit(1) } - if nodeConfig.Node.Archive { + if nodeConfig.Execution.Archive { log.Warn("--node.archive has been deprecated. Please use --node.caching.archive instead.") - nodeConfig.Node.Caching.Archive = true + nodeConfig.Execution.Caching.Archive = true } log.Info("Running Arbitrum nitro node", "revision", vcsRevision, "vcs.time", vcsTime) @@ -288,8 +288,8 @@ func mainImpl() int { nodeConfig.Node.L1Reader.Enable = true } - if nodeConfig.Node.Sequencer.Enable { - if nodeConfig.Node.ForwardingTarget() != "" { + if nodeConfig.Execution.Sequencer.Enable { + if nodeConfig.Execution.ForwardingTarget() != "" { flag.Usage() log.Crit("forwarding-target cannot be set when sequencer is enabled") } @@ -297,14 +297,14 @@ func mainImpl() int { flag.Usage() log.Crit("hard reorgs cannot safely be enabled with sequencer mode enabled") } - } else if nodeConfig.Node.ForwardingTargetImpl == "" { + } else if nodeConfig.Execution.ForwardingTargetImpl == "" { flag.Usage() log.Crit("forwarding-target unset, and not sequencer (can set to \"null\" to disable forwarding)") } var l1TransactionOpts *bind.TransactOpts var dataSigner signature.DataSignerFunc - sequencerNeedsKey := nodeConfig.Node.Sequencer.Enable && !nodeConfig.Node.Feed.Output.DisableSigning + sequencerNeedsKey := nodeConfig.Node.Sequencer && !nodeConfig.Node.Feed.Output.DisableSigning setupNeedsKey := l1Wallet.OnlyCreateKey || nodeConfig.Node.Staker.OnlyCreateWalletContract validatorCanAct := nodeConfig.Node.Staker.Enable && !strings.EqualFold(nodeConfig.Node.Staker.Strategy, "watchtower") if sequencerNeedsKey || nodeConfig.Node.BatchPoster.Enable || setupNeedsKey || validatorCanAct { @@ -360,9 +360,9 @@ func mainImpl() int { return 0 } - if nodeConfig.Node.Caching.Archive && nodeConfig.Node.TxLookupLimit != 0 { + if nodeConfig.Execution.Caching.Archive && nodeConfig.Execution.TxLookupLimit != 0 { log.Info("retaining ability to lookup full transaction history as archive mode is enabled") - nodeConfig.Node.TxLookupLimit = 0 + nodeConfig.Execution.TxLookupLimit = 0 } stack, err := node.New(&stackConf) @@ -381,7 +381,7 @@ func mainImpl() int { } } - chainDb, l2BlockChain, err := openInitializeChainDb(ctx, stack, nodeConfig, new(big.Int).SetUint64(nodeConfig.L2.ChainID), execution.DefaultCacheConfigFor(stack, &nodeConfig.Node.Caching)) + chainDb, l2BlockChain, err := openInitializeChainDb(ctx, stack, nodeConfig, new(big.Int).SetUint64(nodeConfig.L2.ChainID), gethclient.DefaultCacheConfigFor(stack, &nodeConfig.Execution.Caching)) defer closeDb(chainDb, "chainDb") if l2BlockChain != nil { // Calling Stop on the blockchain multiple times does nothing @@ -439,9 +439,23 @@ func mainImpl() int { log.Warn("couldn't init validation node", "err", err) } + execNode, err := gethclient.CreateExecutionNode( + stack, + chainDb, + l2BlockChain, + l1Client, + nil, // TODO + func() *gethclient.Config { return &liveNodeConfig.get().Execution }, + ) + if err != nil { + log.Error("failed to create execution node", "err", err) + return 1 + } + currentNode, err := arbnode.CreateNode( ctx, stack, + execNode, chainDb, arbDb, &NodeConfigFetcher{liveNodeConfig}, @@ -477,7 +491,7 @@ func mainImpl() int { } gqlConf := nodeConfig.GraphQL if gqlConf.Enable { - if err := graphql.New(stack, currentNode.Execution.Backend.APIBackend(), currentNode.Execution.FilterSystem, gqlConf.CORSDomain, gqlConf.VHosts); err != nil { + if err := graphql.New(stack, execNode.Backend.APIBackend(), execNode.FilterSystem, gqlConf.CORSDomain, gqlConf.VHosts); err != nil { log.Error("failed to register the GraphQL service", "err", err) return 1 } @@ -520,6 +534,7 @@ func mainImpl() int { type NodeConfig struct { Conf genericconf.ConfConfig `koanf:"conf" reload:"hot"` Node arbnode.Config `koanf:"node" reload:"hot"` + Execution gethclient.Config `koanf:"exec" reload:"hot"` Validation valnode.Config `koanf:"validation" reload:"hot"` L1 conf.L1Config `koanf:"l1"` L2 conf.L2Config `koanf:"l2"` diff --git a/arbnode/execution/api.go b/execution/gethclient/api.go similarity index 99% rename from arbnode/execution/api.go rename to execution/gethclient/api.go index 8f3c37b9b3..d7f686baff 100644 --- a/arbnode/execution/api.go +++ b/execution/gethclient/api.go @@ -1,7 +1,7 @@ // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE -package execution +package gethclient import ( "context" diff --git a/arbnode/execution/arb_interface.go b/execution/gethclient/arb_interface.go similarity index 98% rename from arbnode/execution/arb_interface.go rename to execution/gethclient/arb_interface.go index c1e64db141..7585e29749 100644 --- a/arbnode/execution/arb_interface.go +++ b/execution/gethclient/arb_interface.go @@ -1,7 +1,7 @@ // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE -package execution +package gethclient import ( "context" diff --git a/arbnode/execution/block_recorder.go b/execution/gethclient/block_recorder.go similarity index 97% rename from arbnode/execution/block_recorder.go rename to execution/gethclient/block_recorder.go index 5152f33ebb..c59d484ef7 100644 --- a/arbnode/execution/block_recorder.go +++ b/execution/gethclient/block_recorder.go @@ -1,4 +1,4 @@ -package execution +package gethclient import ( "context" @@ -15,6 +15,7 @@ import ( "github.com/offchainlabs/nitro/arbos/arbosState" "github.com/offchainlabs/nitro/arbos/arbostypes" "github.com/offchainlabs/nitro/arbutil" + "github.com/offchainlabs/nitro/execution" "github.com/offchainlabs/nitro/validator" ) @@ -39,13 +40,6 @@ type BlockRecorder struct { preparedLock sync.Mutex } -type RecordResult struct { - Pos arbutil.MessageIndex - BlockHash common.Hash - Preimages map[common.Hash][]byte - BatchInfo []validator.BatchInfo -} - func NewBlockRecorder(execEngine *ExecutionEngine, ethDb ethdb.Database) *BlockRecorder { recorder := &BlockRecorder{ execEngine: execEngine, @@ -77,7 +71,7 @@ func (r *BlockRecorder) RecordBlockCreation( ctx context.Context, pos arbutil.MessageIndex, msg *arbostypes.MessageWithMetadata, -) (*RecordResult, error) { +) (*execution.RecordResult, error) { blockNum := r.execEngine.MessageIndexToBlockNumber(pos) @@ -168,7 +162,12 @@ func (r *BlockRecorder) RecordBlockCreation( r.updateLastHdr(prevHeader) r.updateValidCandidateHdr(prevHeader) - return &RecordResult{pos, blockHash, preimages, readBatchInfo}, err + return &execution.RecordResult{ + Pos: pos, + BlockHash: blockHash, + Preimages: preimages, + BatchInfo: readBatchInfo, + }, err } func (r *BlockRecorder) updateLastHdr(hdr *types.Header) { diff --git a/arbnode/execution/blockchain.go b/execution/gethclient/blockchain.go similarity index 99% rename from arbnode/execution/blockchain.go rename to execution/gethclient/blockchain.go index 4c84467bb7..2a953c5dbd 100644 --- a/arbnode/execution/blockchain.go +++ b/execution/gethclient/blockchain.go @@ -1,4 +1,4 @@ -package execution +package gethclient import ( "errors" diff --git a/arbnode/execution/executionengine.go b/execution/gethclient/executionengine.go similarity index 95% rename from arbnode/execution/executionengine.go rename to execution/gethclient/executionengine.go index f32aef49e2..060d0cbb4f 100644 --- a/arbnode/execution/executionengine.go +++ b/execution/gethclient/executionengine.go @@ -1,4 +1,4 @@ -package execution +package gethclient import ( "context" @@ -8,7 +8,6 @@ import ( "testing" "time" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" @@ -19,22 +18,17 @@ import ( "github.com/offchainlabs/nitro/arbos/arbostypes" "github.com/offchainlabs/nitro/arbos/l1pricing" "github.com/offchainlabs/nitro/arbutil" + "github.com/offchainlabs/nitro/execution" "github.com/offchainlabs/nitro/util/sharedmetrics" "github.com/offchainlabs/nitro/util/stopwaiter" "github.com/pkg/errors" ) -type TransactionStreamerInterface interface { - WriteMessageFromSequencer(pos arbutil.MessageIndex, msgWithMeta arbostypes.MessageWithMetadata) error - ExpectChosenSequencer() error - FetchBatch(batchNum uint64) ([]byte, error) -} - type ExecutionEngine struct { stopwaiter.StopWaiter bc *core.BlockChain - streamer TransactionStreamerInterface + streamer execution.TransactionStreamer recorder *BlockRecorder resequenceChan chan []*arbostypes.MessageWithMetadata @@ -77,7 +71,7 @@ func (s *ExecutionEngine) EnableReorgSequencing() { s.reorgSequencing = true } -func (s *ExecutionEngine) SetTransactionStreamer(streamer TransactionStreamerInterface) { +func (s *ExecutionEngine) SetTransactionStreamer(streamer execution.TransactionStreamer) { if s.Started() { panic("trying to set transaction streamer after start") } @@ -225,15 +219,13 @@ func (s *ExecutionEngine) resequenceReorgedMessages(messages []*arbostypes.Messa } } -var ErrSequencerInsertLockTaken = errors.New("insert lock taken") - func (s *ExecutionEngine) SequenceTransactions(header *arbostypes.L1IncomingMessageHeader, txes types.Transactions, hooks *arbos.SequencingHooks) (*types.Block, error) { for { hooks.TxErrors = nil s.createBlocksMutex.Lock() block, err := s.sequenceTransactionsWithBlockMutex(header, txes, hooks) s.createBlocksMutex.Unlock() - if !errors.Is(err, ErrSequencerInsertLockTaken) { + if !errors.Is(err, execution.ErrSequencerInsertLockTaken) { return block, err } <-time.After(time.Millisecond * 100) @@ -322,7 +314,7 @@ func (s *ExecutionEngine) SequenceDelayedMessage(message *arbostypes.L1IncomingM s.createBlocksMutex.Lock() err := s.sequenceDelayedMessageWithBlockMutex(message, delayedSeqNum) s.createBlocksMutex.Unlock() - if !errors.Is(err, ErrSequencerInsertLockTaken) { + if !errors.Is(err, execution.ErrSequencerInsertLockTaken) { return err } <-time.After(time.Millisecond * 100) @@ -428,12 +420,7 @@ func (s *ExecutionEngine) appendBlock(block *types.Block, statedb *state.StateDB return nil } -type MessageResult struct { - BlockHash common.Hash - SendRoot common.Hash -} - -func (s *ExecutionEngine) resultFromHeader(header *types.Header) (*MessageResult, error) { +func (s *ExecutionEngine) resultFromHeader(header *types.Header) (*execution.MessageResult, error) { if header == nil { return nil, fmt.Errorf("result not found") } @@ -441,10 +428,13 @@ func (s *ExecutionEngine) resultFromHeader(header *types.Header) (*MessageResult if err != nil { return nil, err } - return &MessageResult{header.Hash(), info.SendRoot}, nil + return &execution.MessageResult{ + BlockHash: header.Hash(), + SendRoot: info.SendRoot, + }, nil } -func (s *ExecutionEngine) ResultAtPos(pos arbutil.MessageIndex) (*MessageResult, error) { +func (s *ExecutionEngine) ResultAtPos(pos arbutil.MessageIndex) (*execution.MessageResult, error) { return s.resultFromHeader(s.bc.GetHeaderByNumber(s.MessageIndexToBlockNumber(pos))) } diff --git a/arbnode/execution/forwarder.go b/execution/gethclient/forwarder.go similarity index 99% rename from arbnode/execution/forwarder.go rename to execution/gethclient/forwarder.go index f0ed7eec46..60dd4f4d87 100644 --- a/arbnode/execution/forwarder.go +++ b/execution/gethclient/forwarder.go @@ -1,7 +1,7 @@ // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE -package execution +package gethclient import ( "context" diff --git a/execution/gethclient/node.go b/execution/gethclient/node.go new file mode 100644 index 0000000000..249fcfe251 --- /dev/null +++ b/execution/gethclient/node.go @@ -0,0 +1,333 @@ +package gethclient + +import ( + "context" + "errors" + "fmt" + "testing" + + "github.com/ethereum/go-ethereum/arbitrum" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/eth/filters" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/rpc" + "github.com/offchainlabs/nitro/arbos/arbostypes" + "github.com/offchainlabs/nitro/arbutil" + "github.com/offchainlabs/nitro/execution" + "github.com/offchainlabs/nitro/util/headerreader" + flag "github.com/spf13/pflag" +) + +type DangerousConfig struct { + ReorgToBlock int64 `koanf:"reorg-to-block"` +} + +var DefaultDangerousConfig = DangerousConfig{ + ReorgToBlock: -1, +} + +func DangerousConfigAddOptions(prefix string, f *flag.FlagSet) { + f.Int64(prefix+".reorg-to-block", DefaultDangerousConfig.ReorgToBlock, "DANGEROUS! forces a reorg to an old block height. To be used for testing only. -1 to disable") +} + +type Config struct { + L1Reader headerreader.Config `koanf:"l1-reader" reload:"hot"` + Sequencer SequencerConfig `koanf:"sequencer" reload:"hot"` + TxPreCheckerStrictness uint `koanf:"tx-pre-checker-strictness" reload:"hot"` + Forwarder ForwarderConfig `koanf:"forwarder"` + ForwardingTargetImpl string `koanf:"forwarding-target"` + Caching CachingConfig `koanf:"caching"` + RPC arbitrum.Config `koanf:"rpc"` + Archive bool `koanf:"archive"` + TxLookupLimit uint64 `koanf:"tx-lookup-limit"` + Dangerous DangerousConfig `koanf:"dangerous"` +} + +func (c *Config) ForwardingTarget() string { + if c.ForwardingTargetImpl == "null" { + return "" + } + + return c.ForwardingTargetImpl +} + +func (c *Config) Validate() error { + if err := c.Sequencer.Validate(); err != nil { + return err + } + return nil +} + +func ConfigAddOptions(prefix string, f *flag.FlagSet, feedInputEnable bool, feedOutputEnable bool) { + arbitrum.ConfigAddOptions(prefix+".rpc", f) + SequencerConfigAddOptions(prefix+".sequencer", f) + f.String(prefix+".forwarding-target", ConfigDefault.ForwardingTargetImpl, "transaction forwarding target URL, or \"null\" to disable forwarding (iff not sequencer)") + AddOptionsForNodeForwarderConfig(prefix+".forwarder", f) + txPreCheckerDescription := "how strict to be when checking txs before forwarding them. 0 = accept anything, " + + "10 = should never reject anything that'd succeed, 20 = likely won't reject anything that'd succeed, " + + "30 = full validation which may reject txs that would succeed" + f.Uint(prefix+".tx-pre-checker-strictness", ConfigDefault.TxPreCheckerStrictness, txPreCheckerDescription) + CachingConfigAddOptions(prefix+".caching", f) + f.Uint64(prefix+".tx-lookup-limit", ConfigDefault.TxLookupLimit, "retain the ability to lookup transactions by hash for the past N blocks (0 = all blocks)") + + archiveMsg := fmt.Sprintf("retain past block state (deprecated, please use %v.caching.archive)", prefix) + f.Bool(prefix+".archive", ConfigDefault.Archive, archiveMsg) + DangerousConfigAddOptions(prefix+".dangerous", f) +} + +var ConfigDefault = Config{ + RPC: arbitrum.DefaultConfig, + Sequencer: DefaultSequencerConfig, + ForwardingTargetImpl: "", + TxPreCheckerStrictness: TxPreCheckerStrictnessNone, + Archive: false, + TxLookupLimit: 126_230_400, // 1 year at 4 blocks per second + Caching: DefaultCachingConfig, +} + +func ConfigDefaultL1Test() *Config { + config := ConfigDefaultL1NonSequencerTest() + config.Sequencer = TestSequencerConfig + + return config +} + +func ConfigDefaultL1NonSequencerTest() *Config { + config := ConfigDefault + config.Sequencer.Enable = false + config.Forwarder = DefaultTestForwarderConfig + + return &config +} + +func ConfigDefaultL2Test() *Config { + config := ConfigDefault + config.Sequencer = TestSequencerConfig + + return &config +} + +type ConfigFetcher func() *Config + +type ExecutionNode struct { + ChainDB ethdb.Database + Backend *arbitrum.Backend + FilterSystem *filters.FilterSystem + ArbInterface *ArbInterface + ExecEngine *ExecutionEngine + Recorder *BlockRecorder + Sequencer *Sequencer // either nil or same as TxPublisher + TxPublisher TransactionPublisher +} + +func CreateExecutionNode( + stack *node.Node, + chainDB ethdb.Database, + l2BlockChain *core.BlockChain, + l1client arbutil.L1Interface, + syncMonitor arbitrum.SyncProgressBackend, + configFetcher ConfigFetcher, +) (*ExecutionNode, error) { + config := configFetcher() + execEngine, err := NewExecutionEngine(l2BlockChain) + if err != nil { + return nil, err + } + recorder := NewBlockRecorder(execEngine, chainDB) + var txPublisher TransactionPublisher + var sequencer *Sequencer + + l1Reader := headerreader.New(l1client, func() *headerreader.Config { return &configFetcher().L1Reader }) + + fwTarget := config.ForwardingTarget() + if config.Sequencer.Enable { + if fwTarget != "" { + return nil, errors.New("sequencer and forwarding target both set") + } + seqConfigFetcher := func() *SequencerConfig { return &configFetcher().Sequencer } + sequencer, err = NewSequencer(execEngine, l1Reader, seqConfigFetcher) + if err != nil { + return nil, err + } + txPublisher = sequencer + } else { + if config.Forwarder.RedisUrl != "" { + txPublisher = NewRedisTxForwarder(fwTarget, &config.Forwarder) + } else if fwTarget == "" { + txPublisher = NewTxDropper() + } else { + txPublisher = NewForwarder(fwTarget, &config.Forwarder) + } + } + + strictnessFetcher := func() uint { return configFetcher().TxPreCheckerStrictness } + txPublisher = NewTxPreChecker(txPublisher, l2BlockChain, strictnessFetcher) + arbInterface, err := NewArbInterface(execEngine, txPublisher) + if err != nil { + return nil, err + } + filterConfig := filters.Config{ + LogCacheSize: config.RPC.FilterLogCacheSize, + Timeout: config.RPC.FilterTimeout, + } + backend, filterSystem, err := arbitrum.NewBackend(stack, &config.RPC, chainDB, arbInterface, syncMonitor, filterConfig) + if err != nil { + return nil, err + } + + apis := []rpc.API{{ + Namespace: "arb", + Version: "1.0", + Service: NewArbAPI(txPublisher), + Public: false, + }} + apis = append(apis, rpc.API{ + Namespace: "arbdebug", + Version: "1.0", + Service: NewArbDebugAPI( + l2BlockChain, + config.RPC.ArbDebug.BlockRangeBound, + config.RPC.ArbDebug.TimeoutQueueBound, + ), + Public: false, + }) + apis = append(apis, rpc.API{ + Namespace: "arbtrace", + Version: "1.0", + Service: NewArbTraceForwarderAPI( + config.RPC.ClassicRedirect, + config.RPC.ClassicRedirectTimeout, + ), + Public: false, + }) + apis = append(apis, rpc.API{ + Namespace: "debug", + Service: eth.NewDebugAPI(eth.NewArbEthereum(l2BlockChain, chainDB)), + Public: false, + }) + + stack.RegisterAPIs(apis) + + return &ExecutionNode{ + chainDB, + backend, + filterSystem, + arbInterface, + execEngine, + recorder, + sequencer, + txPublisher, + }, nil + +} + +func (n *ExecutionNode) Initialize(ctx context.Context, arbnode interface{}) error { + n.ArbInterface.Initialize(n) + err := n.Backend.Start() + if err != nil { + return fmt.Errorf("error starting geth backend: %w", err) + } + err = n.TxPublisher.Initialize(ctx) + if err != nil { + return fmt.Errorf("error initializing transaction publisher: %w", err) + } + return nil +} + +func (n *ExecutionNode) Start(ctx context.Context) error { + // TODO after separation + // err := n.Stack.Start() + // if err != nil { + // return fmt.Errorf("error starting geth stack: %w", err) + // } + n.ExecEngine.Start(ctx) + err := n.TxPublisher.Start(ctx) + if err != nil { + return fmt.Errorf("error starting transaction puiblisher: %w", err) + } + // TODO after separation + // if n.L1Reader != nil { + // n.L1Reader.Start(ctx) + // } + return nil +} + +func (n *ExecutionNode) StopAndWait() { + // TODO after separation + // n.Stack.StopRPC() // does nothing if not running + if n.TxPublisher.Started() { + n.TxPublisher.StopAndWait() + } + n.Recorder.OrderlyShutdown() + // TODO after separation + // if n.L1Reader != nil && n.L1Reader.Started() { + // n.L1Reader.StopAndWait() + // } + if n.ExecEngine.Started() { + n.ExecEngine.StopAndWait() + } + n.ArbInterface.BlockChain().Stop() // does nothing if not running + if err := n.Backend.Stop(); err != nil { + log.Error("backend stop", "err", err) + } + // TODO after separation + // if err := n.Stack.Close(); err != nil { + // log.Error("error on stak close", "err", err) + // } +} + +func (n *ExecutionNode) DigestMessage(num arbutil.MessageIndex, msg *arbostypes.MessageWithMetadata) error { + return n.ExecEngine.DigestMessage(num, msg) +} +func (n *ExecutionNode) Reorg(count arbutil.MessageIndex, newMessages []arbostypes.MessageWithMetadata, oldMessages []*arbostypes.MessageWithMetadata) error { + return n.ExecEngine.Reorg(count, newMessages, oldMessages) +} +func (n *ExecutionNode) HeadMessageNumber() (arbutil.MessageIndex, error) { + return n.ExecEngine.HeadMessageNumber() +} +func (n *ExecutionNode) HeadMessageNumberSync(t *testing.T) (arbutil.MessageIndex, error) { + return n.ExecEngine.HeadMessageNumberSync(t) +} +func (n *ExecutionNode) NextDelayedMessageNumber() (uint64, error) { + return n.ExecEngine.NextDelayedMessageNumber() +} +func (n *ExecutionNode) SequenceDelayedMessage(message *arbostypes.L1IncomingMessage, delayedSeqNum uint64) error { + return n.ExecEngine.SequenceDelayedMessage(message, delayedSeqNum) +} +func (n *ExecutionNode) ResultAtPos(pos arbutil.MessageIndex) (*execution.MessageResult, error) { + return n.ExecEngine.ResultAtPos(pos) +} + +func (n *ExecutionNode) RecordBlockCreation( + ctx context.Context, + pos arbutil.MessageIndex, + msg *arbostypes.MessageWithMetadata, +) (*execution.RecordResult, error) { + return n.Recorder.RecordBlockCreation(ctx, pos, msg) +} +func (n *ExecutionNode) MarkValid(pos arbutil.MessageIndex, resultHash common.Hash) { + n.Recorder.MarkValid(pos, resultHash) +} +func (n *ExecutionNode) PrepareForRecord(ctx context.Context, start, end arbutil.MessageIndex) error { + return n.Recorder.PrepareForRecord(ctx, start, end) +} + +func (n *ExecutionNode) Pause() { + n.Sequencer.Pause() +} +func (n *ExecutionNode) Activate() { + n.Sequencer.Activate() +} +func (n *ExecutionNode) ForwardTo(url string) error { + return n.Sequencer.ForwardTo(url) +} +func (n *ExecutionNode) SetTransactionStreamer(streamer execution.TransactionStreamer) { + n.ExecEngine.SetTransactionStreamer(streamer) +} +func (n *ExecutionNode) MessageIndexToBlockNumber(messageNum arbutil.MessageIndex) uint64 { + return n.ExecEngine.MessageIndexToBlockNumber(messageNum) +} diff --git a/arbnode/execution/sequencer.go b/execution/gethclient/sequencer.go similarity index 99% rename from arbnode/execution/sequencer.go rename to execution/gethclient/sequencer.go index 830ffd6a99..ddc70ac2b5 100644 --- a/arbnode/execution/sequencer.go +++ b/execution/gethclient/sequencer.go @@ -1,7 +1,7 @@ // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE -package execution +package gethclient import ( "context" @@ -14,6 +14,7 @@ import ( "sync/atomic" "time" + "github.com/offchainlabs/nitro/execution" "github.com/offchainlabs/nitro/util/arbmath" "github.com/offchainlabs/nitro/util/containers" "github.com/offchainlabs/nitro/util/headerreader" @@ -334,8 +335,6 @@ func (s *Sequencer) onNonceFailureEvict(_ addressAndNonce, failure *nonceFailure } } -var ErrRetrySequencer = errors.New("please retry transaction") - func (s *Sequencer) ctxWithQueueTimeout(inctx context.Context) (context.Context, context.CancelFunc) { timeout := s.config().QueueTimeout if timeout == time.Duration(0) { @@ -813,7 +812,7 @@ func (s *Sequencer) createBlock(ctx context.Context) (returnValue bool) { if err == nil && len(hooks.TxErrors) != len(txes) { err = fmt.Errorf("unexpected number of error results: %v vs number of txes %v", len(hooks.TxErrors), len(txes)) } - if errors.Is(err, ErrRetrySequencer) { + if errors.Is(err, execution.ErrRetrySequencer) { log.Warn("error sequencing transactions", "err", err) // we changed roles // forward if we have where to diff --git a/arbnode/execution/tx_pre_checker.go b/execution/gethclient/tx_pre_checker.go similarity index 99% rename from arbnode/execution/tx_pre_checker.go rename to execution/gethclient/tx_pre_checker.go index 8a41d61774..3c991343d5 100644 --- a/arbnode/execution/tx_pre_checker.go +++ b/execution/gethclient/tx_pre_checker.go @@ -1,7 +1,7 @@ // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE -package execution +package gethclient import ( "context" diff --git a/execution/interface.go b/execution/interface.go new file mode 100644 index 0000000000..eb929274d2 --- /dev/null +++ b/execution/interface.go @@ -0,0 +1,77 @@ +package execution + +import ( + "context" + "errors" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/offchainlabs/nitro/arbos/arbostypes" + "github.com/offchainlabs/nitro/arbutil" + "github.com/offchainlabs/nitro/validator" +) + +type MessageResult struct { + BlockHash common.Hash + SendRoot common.Hash +} + +type RecordResult struct { + Pos arbutil.MessageIndex + BlockHash common.Hash + Preimages map[common.Hash][]byte + BatchInfo []validator.BatchInfo +} + +var ErrRetrySequencer = errors.New("please retry transaction") +var ErrSequencerInsertLockTaken = errors.New("insert lock taken") + +// always needed +type ExecutionClient interface { + DigestMessage(num arbutil.MessageIndex, msg *arbostypes.MessageWithMetadata) error + Reorg(count arbutil.MessageIndex, newMessages []arbostypes.MessageWithMetadata, oldMessages []*arbostypes.MessageWithMetadata) error + HeadMessageNumber() (arbutil.MessageIndex, error) + HeadMessageNumberSync(t *testing.T) (arbutil.MessageIndex, error) + NextDelayedMessageNumber() (uint64, error) + SequenceDelayedMessage(message *arbostypes.L1IncomingMessage, delayedSeqNum uint64) error + ResultAtPos(pos arbutil.MessageIndex) (*MessageResult, error) +} + +// needed for validators / stakers +type ExecutionRecorder interface { + RecordBlockCreation( + ctx context.Context, + pos arbutil.MessageIndex, + msg *arbostypes.MessageWithMetadata, + ) (*RecordResult, error) + MarkValid(pos arbutil.MessageIndex, resultHash common.Hash) + PrepareForRecord(ctx context.Context, start, end arbutil.MessageIndex) error +} + +// needed for sequencer +type ExecutionSequencer interface { + Pause() + Activate() + ForwardTo(url string) error + SetTransactionStreamer(streamer TransactionStreamer) +} + +type FullExecutionClient interface { + ExecutionClient + ExecutionRecorder + ExecutionSequencer + + // TODO: only used to get safe/finalized block numbers + MessageIndexToBlockNumber(messageNum arbutil.MessageIndex) uint64 +} + +// not implemented in execution, used as input +type BatchFetcher interface { + FetchBatch(batchNum uint64) ([]byte, error) +} + +type TransactionStreamer interface { + BatchFetcher + WriteMessageFromSequencer(pos arbutil.MessageIndex, msgWithMeta arbostypes.MessageWithMetadata) error + ExpectChosenSequencer() error +} diff --git a/go-ethereum b/go-ethereum index c9b451414c..c3e683a62a 160000 --- a/go-ethereum +++ b/go-ethereum @@ -1 +1 @@ -Subproject commit c9b451414caba4ecacd8aac993e7bf49f16ad887 +Subproject commit c3e683a62a256a7f3aed280778e94862f74de700 diff --git a/nodeInterface/NodeInterface.go b/nodeInterface/NodeInterface.go index 5a5bbc5c8a..097f0dcca2 100644 --- a/nodeInterface/NodeInterface.go +++ b/nodeInterface/NodeInterface.go @@ -78,7 +78,10 @@ func (n NodeInterface) GetL1Confirmations(c ctx, evm mech, blockHash bytes32) (u if node.InboxReader == nil { return 0, nil } - bc := node.Execution.ArbInterface.BlockChain() + bc, err := blockchainFromNodeInterfaceBackend(n.backend) + if err != nil { + return 0, err + } header := bc.GetHeaderByHash(blockHash) if header == nil { return 0, errors.New("unknown block hash") @@ -486,16 +489,16 @@ func (n NodeInterface) GasEstimateL1Component( func (n NodeInterface) GasEstimateComponents( c ctx, evm mech, value huge, to addr, contractCreation bool, data []byte, ) (uint64, uint64, huge, huge, error) { - node, err := arbNodeFromNodeInterfaceBackend(n.backend) - if err != nil { - return 0, 0, nil, nil, err - } if to == types.NodeInterfaceAddress || to == types.NodeInterfaceDebugAddress { return 0, 0, nil, nil, errors.New("cannot estimate virtual contract") } + backend, ok := n.backend.(*arbitrum.APIBackend) + if !ok { + return 0, 0, nil, nil, errors.New("failed getting API backend") + } + context := n.context - backend := node.Execution.Backend.APIBackend() gasCap := backend.RPCGasCap() block := rpc.BlockNumberOrHashWithHash(n.header.Hash(), false) args := n.messageArgs(evm, value, to, contractCreation, data) diff --git a/nodeInterface/virtual-contracts.go b/nodeInterface/virtual-contracts.go index 3e7d78e66f..50eb1f47bb 100644 --- a/nodeInterface/virtual-contracts.go +++ b/nodeInterface/virtual-contracts.go @@ -181,3 +181,15 @@ func arbNodeFromNodeInterfaceBackend(backend BackendAPI) (*arbnode.Node, error) } return arbNode, nil } + +func blockchainFromNodeInterfaceBackend(backend BackendAPI) (*core.BlockChain, error) { + apiBackend, ok := backend.(*arbitrum.APIBackend) + if !ok { + return nil, errors.New("API backend isn't Arbitrum") + } + bc := apiBackend.BlockChain() + if bc == nil { + return nil, errors.New("failed to get Blockchain from backend") + } + return bc, nil +} diff --git a/staker/stateless_block_validator.go b/staker/stateless_block_validator.go index 2976b6b17e..9ad3f3629c 100644 --- a/staker/stateless_block_validator.go +++ b/staker/stateless_block_validator.go @@ -9,7 +9,7 @@ import ( "sync" "testing" - "github.com/offchainlabs/nitro/arbnode/execution" + "github.com/offchainlabs/nitro/execution" "github.com/offchainlabs/nitro/util/signature" "github.com/offchainlabs/nitro/validator/server_api" @@ -31,7 +31,7 @@ type StatelessBlockValidator struct { execSpawner validator.ExecutionSpawner validationSpawners []validator.ValidationSpawner - recorder BlockRecorder + recorder execution.ExecutionRecorder inboxReader InboxReaderInterface inboxTracker InboxTrackerInterface @@ -48,16 +48,6 @@ type BlockValidatorRegistrer interface { SetBlockValidator(*BlockValidator) } -type BlockRecorder interface { - RecordBlockCreation( - ctx context.Context, - pos arbutil.MessageIndex, - msg *arbostypes.MessageWithMetadata, - ) (*execution.RecordResult, error) - MarkValid(pos arbutil.MessageIndex, resultHash common.Hash) - PrepareForRecord(ctx context.Context, start, end arbutil.MessageIndex) error -} - type InboxTrackerInterface interface { BlockValidatorRegistrer GetDelayedMessageBytes(uint64) ([]byte, error) @@ -229,7 +219,7 @@ func NewStatelessBlockValidator( inboxReader InboxReaderInterface, inbox InboxTrackerInterface, streamer TransactionStreamerInterface, - recorder BlockRecorder, + recorder execution.ExecutionRecorder, arbdb ethdb.Database, das arbstate.DataAvailabilityReader, config *BlockValidatorConfig, @@ -434,7 +424,7 @@ func (v *StatelessBlockValidator) ValidateResult( return true, &entry.End, nil } -func (v *StatelessBlockValidator) OverrideRecorder(t *testing.T, recorder BlockRecorder) { +func (v *StatelessBlockValidator) OverrideRecorder(t *testing.T, recorder execution.ExecutionRecorder) { v.recorder = recorder } From 9b54f4954dc404e60bf750435cb869f5a1c63742 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Wed, 15 Mar 2023 10:48:48 +0200 Subject: [PATCH 02/23] move maintenance to gethclient --- arbnode/api.go | 4 +--- arbnode/maintenance.go | 15 ++++++++++++--- arbnode/node.go | 20 ++++++++------------ cmd/nitro/nitro.go | 3 +-- execution/gethclient/node.go | 4 ++++ execution/interface.go | 2 ++ 6 files changed, 28 insertions(+), 20 deletions(-) diff --git a/arbnode/api.go b/arbnode/api.go index 6c067329e6..fe9b00cebe 100644 --- a/arbnode/api.go +++ b/arbnode/api.go @@ -7,7 +7,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/core" "github.com/offchainlabs/nitro/arbutil" "github.com/offchainlabs/nitro/staker" "github.com/offchainlabs/nitro/validator" @@ -23,8 +22,7 @@ func (a *BlockValidatorAPI) LatestValidatedMsgNum(ctx context.Context) (*staker. } type BlockValidatorDebugAPI struct { - val *staker.StatelessBlockValidator - blockchain *core.BlockChain + val *staker.StatelessBlockValidator } type ValidateBlockResult struct { diff --git a/arbnode/maintenance.go b/arbnode/maintenance.go index 1b059df48d..339da45a34 100644 --- a/arbnode/maintenance.go +++ b/arbnode/maintenance.go @@ -12,6 +12,7 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" + "github.com/offchainlabs/nitro/execution" "github.com/offchainlabs/nitro/util/stopwaiter" flag "github.com/spf13/pflag" ) @@ -20,6 +21,7 @@ import ( type MaintenanceRunner struct { stopwaiter.StopWaiter + exec execution.FullExecutionClient config MaintenanceConfigFetcher seqCoordinator *SeqCoordinator dbs []ethdb.Database @@ -75,13 +77,14 @@ var DefaultMaintenanceConfig = MaintenanceConfig{ type MaintenanceConfigFetcher func() *MaintenanceConfig -func NewMaintenanceRunner(config MaintenanceConfigFetcher, seqCoordinator *SeqCoordinator, dbs []ethdb.Database) (*MaintenanceRunner, error) { +func NewMaintenanceRunner(config MaintenanceConfigFetcher, seqCoordinator *SeqCoordinator, dbs []ethdb.Database, exec execution.FullExecutionClient) (*MaintenanceRunner, error) { err := config().Validate() if err != nil { return nil, err } return &MaintenanceRunner{ config: config, + exec: exec, seqCoordinator: seqCoordinator, dbs: dbs, lastCheck: time.Now().UTC(), @@ -142,16 +145,22 @@ func (c *MaintenanceRunner) maybeRunMaintenance(ctx context.Context) time.Durati func (c *MaintenanceRunner) runMaintenance() { log.Info("compacting databases (this may take a while...)") results := make(chan error, len(c.dbs)) + expected := 0 for _, db := range c.dbs { + expected++ db := db go func() { results <- db.Compact(nil, nil) }() } - for range c.dbs { + expected++ + go func() { + results <- c.exec.Maintenance() + }() + for i := 0; i < expected; i++ { err := <-results if err != nil { - log.Warn("failed to compact database", "err", err) + log.Warn("maintenance error", "err", err) } } log.Info("done compacting databases") diff --git a/arbnode/node.go b/arbnode/node.go index b6c002a0ed..f22b8ebdc8 100644 --- a/arbnode/node.go +++ b/arbnode/node.go @@ -15,7 +15,6 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" @@ -31,6 +30,7 @@ import ( "github.com/offchainlabs/nitro/broadcaster" "github.com/offchainlabs/nitro/das" "github.com/offchainlabs/nitro/execution" + "github.com/offchainlabs/nitro/execution/gethclient" "github.com/offchainlabs/nitro/solgen/go/bridgegen" "github.com/offchainlabs/nitro/solgen/go/challengegen" "github.com/offchainlabs/nitro/solgen/go/ospgen" @@ -594,10 +594,9 @@ func createNodeImpl( ctx context.Context, stack *node.Node, exec execution.FullExecutionClient, - chainDb ethdb.Database, arbDb ethdb.Database, configFetcher ConfigFetcher, - l2BlockChain *core.BlockChain, + l2Config *params.ChainConfig, l1client arbutil.L1Interface, deployInfo *RollupAddresses, txOpts *bind.TransactOpts, @@ -611,7 +610,6 @@ func createNodeImpl( return nil, err } - l2Config := l2BlockChain.Config() l2ChainId := l2Config.ChainID.Uint64() //TODO: @@ -672,8 +670,8 @@ func createNodeImpl( } else if config.Sequencer && (!config.Dangerous.NoCoordinator) { return nil, errors.New("sequencer must be enabled with coordinator, unless dangerous.no-coordinator set") } - dbs := []ethdb.Database{chainDb, arbDb} - maintenanceRunner, err := NewMaintenanceRunner(func() *MaintenanceConfig { return &configFetcher.Get().Maintenance }, coordinator, dbs) + dbs := []ethdb.Database{arbDb} + maintenanceRunner, err := NewMaintenanceRunner(func() *MaintenanceConfig { return &configFetcher.Get().Maintenance }, coordinator, dbs, exec) if err != nil { return nil, err } @@ -762,7 +760,7 @@ func createNodeImpl( } daReader = das.NewReaderPanicWrapper(daReader) } - } else if l2BlockChain.Config().ArbitrumChainParams.DataAvailabilityCommittee { + } else if l2Config.ArbitrumChainParams.DataAvailabilityCommittee { return nil, errors.New("a data availability service is required for this chain, but it was not configured") } @@ -912,17 +910,16 @@ func CreateNode( ctx context.Context, stack *node.Node, exec execution.FullExecutionClient, - chainDb ethdb.Database, arbDb ethdb.Database, configFetcher ConfigFetcher, - l2BlockChain *core.BlockChain, + l2Config *params.ChainConfig, l1client arbutil.L1Interface, deployInfo *RollupAddresses, txOpts *bind.TransactOpts, dataSigner signature.DataSignerFunc, fatalErrChan chan error, ) (*Node, error) { - currentNode, err := createNodeImpl(ctx, stack, exec, chainDb, arbDb, configFetcher, l2BlockChain, l1client, deployInfo, txOpts, dataSigner, fatalErrChan) + currentNode, err := createNodeImpl(ctx, stack, exec, arbDb, configFetcher, l2Config, l1client, deployInfo, txOpts, dataSigner, fatalErrChan) if err != nil { return nil, err } @@ -940,8 +937,7 @@ func CreateNode( Namespace: "arbvalidator", Version: "1.0", Service: &BlockValidatorDebugAPI{ - val: currentNode.StatelessBlockValidator, - blockchain: l2BlockChain, + val: currentNode.StatelessBlockValidator, }, Public: false, }) diff --git a/cmd/nitro/nitro.go b/cmd/nitro/nitro.go index a2f1cff2ba..11a4cbee00 100644 --- a/cmd/nitro/nitro.go +++ b/cmd/nitro/nitro.go @@ -456,10 +456,9 @@ func mainImpl() int { ctx, stack, execNode, - chainDb, arbDb, &NodeConfigFetcher{liveNodeConfig}, - l2BlockChain, + l2BlockChain.Config(), l1Client, &rollupAddrs, l1TransactionOpts, diff --git a/execution/gethclient/node.go b/execution/gethclient/node.go index 249fcfe251..a66920de2f 100644 --- a/execution/gethclient/node.go +++ b/execution/gethclient/node.go @@ -331,3 +331,7 @@ func (n *ExecutionNode) SetTransactionStreamer(streamer execution.TransactionStr func (n *ExecutionNode) MessageIndexToBlockNumber(messageNum arbutil.MessageIndex) uint64 { return n.ExecEngine.MessageIndexToBlockNumber(messageNum) } + +func (n *ExecutionNode) Maintenance() error { + return n.ChainDB.Compact(nil, nil) +} diff --git a/execution/interface.go b/execution/interface.go index eb929274d2..036f98f2bc 100644 --- a/execution/interface.go +++ b/execution/interface.go @@ -61,6 +61,8 @@ type FullExecutionClient interface { ExecutionRecorder ExecutionSequencer + Maintenance() error + // TODO: only used to get safe/finalized block numbers MessageIndexToBlockNumber(messageNum arbutil.MessageIndex) uint64 } From 97ff2123b41b6d0ecc10d7b04ce5257b5ce71aa2 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Wed, 15 Mar 2023 11:01:28 +0200 Subject: [PATCH 03/23] update geth --- go-ethereum | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go-ethereum b/go-ethereum index c3e683a62a..942746e4d6 160000 --- a/go-ethereum +++ b/go-ethereum @@ -1 +1 @@ -Subproject commit c3e683a62a256a7f3aed280778e94862f74de700 +Subproject commit 942746e4d6996ced8a5ce50f04a3d2c1c332c4f9 From 4a70e05a5bc5949c158f508b35dfd71b2df975eb Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Wed, 15 Mar 2023 14:41:25 +0200 Subject: [PATCH 04/23] improve execution-consensus separation --- arbnode/node.go | 24 ++++++++++++++++++++++-- arbnode/sync_monitor.go | 9 ++++++--- arbnode/transaction_streamer.go | 4 ++-- cmd/nitro/nitro.go | 1 - execution/gethclient/node.go | 20 ++++++++------------ execution/interface.go | 1 + 6 files changed, 39 insertions(+), 20 deletions(-) diff --git a/arbnode/node.go b/arbnode/node.go index f22b8ebdc8..6c1e4d5356 100644 --- a/arbnode/node.go +++ b/arbnode/node.go @@ -521,7 +521,7 @@ func DangerousConfigAddOptions(prefix string, f *flag.FlagSet) { type Node struct { ArbDB ethdb.Database Stack *node.Node - Execution execution.ExecutionClient + Execution execution.FullExecutionClient L1Reader *headerreader.HeaderReader TxStreamer *TransactionStreamer DeployInfo *RollupAddresses @@ -949,11 +949,24 @@ func CreateNode( } func (n *Node) Start(ctx context.Context) error { - n.SyncMonitor.Initialize(n.InboxReader, n.TxStreamer, n.SeqCoordinator) + execClient, ok := n.Execution.(*gethclient.ExecutionNode) + if !ok { + execClient = nil + } + if execClient != nil { + execClient.Initialize(ctx, n, n.SyncMonitor) + } + n.SyncMonitor.Initialize(n.InboxReader, n.TxStreamer, n.SeqCoordinator, n.Execution) err := n.Stack.Start() if err != nil { return fmt.Errorf("error starting geth stack: %w", err) } + if execClient != nil { + err := execClient.Start(ctx) + if err != nil { + return fmt.Errorf("error starting exec client: %w", err) + } + } if n.InboxTracker != nil { err = n.InboxTracker.Initialize() if err != nil { @@ -1050,6 +1063,13 @@ func (n *Node) Start(ctx context.Context) error { } func (n *Node) StopAndWait() { + execClient, ok := n.Execution.(*gethclient.ExecutionNode) + if !ok { + execClient = nil + } + if execClient != nil { + execClient.StopAndWait() + } if n.MaintenanceRunner != nil && n.MaintenanceRunner.Started() { n.MaintenanceRunner.StopAndWait() } diff --git a/arbnode/sync_monitor.go b/arbnode/sync_monitor.go index 1afb41756b..bd9b24529c 100644 --- a/arbnode/sync_monitor.go +++ b/arbnode/sync_monitor.go @@ -6,6 +6,7 @@ import ( "sync/atomic" "github.com/offchainlabs/nitro/arbutil" + "github.com/offchainlabs/nitro/execution" flag "github.com/spf13/pflag" ) @@ -14,6 +15,7 @@ type SyncMonitor struct { inboxReader *InboxReader txStreamer *TransactionStreamer coordinator *SeqCoordinator + exec execution.FullExecutionClient initialized bool } @@ -41,10 +43,11 @@ func SyncMonitorConfigAddOptions(prefix string, f *flag.FlagSet) { f.Uint64(prefix+".coordinator-msg-lag", DefaultSyncMonitorConfig.CoordinatorMsgLag, "allowed lag between local and remote messages") } -func (s *SyncMonitor) Initialize(inboxReader *InboxReader, txStreamer *TransactionStreamer, coordinator *SeqCoordinator) { +func (s *SyncMonitor) Initialize(inboxReader *InboxReader, txStreamer *TransactionStreamer, coordinator *SeqCoordinator, exec execution.FullExecutionClient) { s.inboxReader = inboxReader s.txStreamer = txStreamer s.coordinator = coordinator + s.exec = exec s.initialized = true } @@ -148,7 +151,7 @@ func (s *SyncMonitor) SafeBlockNumber(ctx context.Context) (uint64, error) { if err != nil { return 0, err } - block := s.txStreamer.exec.MessageIndexToBlockNumber(msg - 1) + block := s.exec.MessageIndexToBlockNumber(msg - 1) return block, nil } @@ -160,7 +163,7 @@ func (s *SyncMonitor) FinalizedBlockNumber(ctx context.Context) (uint64, error) if err != nil { return 0, err } - block := s.txStreamer.exec.MessageIndexToBlockNumber(msg - 1) + block := s.exec.MessageIndexToBlockNumber(msg - 1) return block, nil } diff --git a/arbnode/transaction_streamer.go b/arbnode/transaction_streamer.go index f0228272b7..6773f4d821 100644 --- a/arbnode/transaction_streamer.go +++ b/arbnode/transaction_streamer.go @@ -41,7 +41,7 @@ type TransactionStreamer struct { stopwaiter.StopWaiter chainConfig *params.ChainConfig - exec execution.FullExecutionClient + exec execution.ExecutionSequencer validator *staker.BlockValidator db ethdb.Database @@ -86,7 +86,7 @@ func TransactionStreamerConfigAddOptions(prefix string, f *flag.FlagSet) { func NewTransactionStreamer( db ethdb.Database, chainConfig *params.ChainConfig, - exec execution.FullExecutionClient, + exec execution.ExecutionSequencer, broadcastServer *broadcaster.Broadcaster, fatalErrChan chan<- error, config TransactionStreamerConfigFetcher, diff --git a/cmd/nitro/nitro.go b/cmd/nitro/nitro.go index 11a4cbee00..9cef2136c0 100644 --- a/cmd/nitro/nitro.go +++ b/cmd/nitro/nitro.go @@ -444,7 +444,6 @@ func mainImpl() int { chainDb, l2BlockChain, l1Client, - nil, // TODO func() *gethclient.Config { return &liveNodeConfig.get().Execution }, ) if err != nil { diff --git a/execution/gethclient/node.go b/execution/gethclient/node.go index a66920de2f..5983155444 100644 --- a/execution/gethclient/node.go +++ b/execution/gethclient/node.go @@ -89,14 +89,7 @@ var ConfigDefault = Config{ Caching: DefaultCachingConfig, } -func ConfigDefaultL1Test() *Config { - config := ConfigDefaultL1NonSequencerTest() - config.Sequencer = TestSequencerConfig - - return config -} - -func ConfigDefaultL1NonSequencerTest() *Config { +func ConfigDefaultNonSequencerTest() *Config { config := ConfigDefault config.Sequencer.Enable = false config.Forwarder = DefaultTestForwarderConfig @@ -104,7 +97,7 @@ func ConfigDefaultL1NonSequencerTest() *Config { return &config } -func ConfigDefaultL2Test() *Config { +func ConfigDefaultTest() *Config { config := ConfigDefault config.Sequencer = TestSequencerConfig @@ -129,7 +122,6 @@ func CreateExecutionNode( chainDB ethdb.Database, l2BlockChain *core.BlockChain, l1client arbutil.L1Interface, - syncMonitor arbitrum.SyncProgressBackend, configFetcher ConfigFetcher, ) (*ExecutionNode, error) { config := configFetcher() @@ -174,7 +166,7 @@ func CreateExecutionNode( LogCacheSize: config.RPC.FilterLogCacheSize, Timeout: config.RPC.FilterTimeout, } - backend, filterSystem, err := arbitrum.NewBackend(stack, &config.RPC, chainDB, arbInterface, syncMonitor, filterConfig) + backend, filterSystem, err := arbitrum.NewBackend(stack, &config.RPC, chainDB, arbInterface, filterConfig) if err != nil { return nil, err } @@ -225,7 +217,7 @@ func CreateExecutionNode( } -func (n *ExecutionNode) Initialize(ctx context.Context, arbnode interface{}) error { +func (n *ExecutionNode) Initialize(ctx context.Context, arbnode interface{}, sync arbitrum.SyncProgressBackend) error { n.ArbInterface.Initialize(n) err := n.Backend.Start() if err != nil { @@ -235,6 +227,10 @@ func (n *ExecutionNode) Initialize(ctx context.Context, arbnode interface{}) err if err != nil { return fmt.Errorf("error initializing transaction publisher: %w", err) } + err = n.Backend.APIBackend().SetSyncBackend(sync) + if err != nil { + return fmt.Errorf("error setting sync backend: %w", err) + } return nil } diff --git a/execution/interface.go b/execution/interface.go index 036f98f2bc..dc1551d8cf 100644 --- a/execution/interface.go +++ b/execution/interface.go @@ -50,6 +50,7 @@ type ExecutionRecorder interface { // needed for sequencer type ExecutionSequencer interface { + ExecutionClient Pause() Activate() ForwardTo(url string) error From 444cef110cedf181c66da3ebf5f061877f2fed84 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Wed, 15 Mar 2023 14:44:42 +0200 Subject: [PATCH 05/23] rename gethclient to gethexec --- arbnode/node.go | 6 +++--- cmd/nitro/init.go | 12 ++++++------ cmd/nitro/nitro.go | 10 +++++----- execution/{gethclient => gethexec}/api.go | 2 +- execution/{gethclient => gethexec}/arb_interface.go | 2 +- execution/{gethclient => gethexec}/block_recorder.go | 2 +- execution/{gethclient => gethexec}/blockchain.go | 2 +- .../{gethclient => gethexec}/executionengine.go | 2 +- execution/{gethclient => gethexec}/forwarder.go | 2 +- execution/{gethclient => gethexec}/node.go | 2 +- execution/{gethclient => gethexec}/sequencer.go | 2 +- execution/{gethclient => gethexec}/tx_pre_checker.go | 2 +- 12 files changed, 23 insertions(+), 23 deletions(-) rename execution/{gethclient => gethexec}/api.go (99%) rename execution/{gethclient => gethexec}/arb_interface.go (98%) rename execution/{gethclient => gethexec}/block_recorder.go (99%) rename execution/{gethclient => gethexec}/blockchain.go (99%) rename execution/{gethclient => gethexec}/executionengine.go (99%) rename execution/{gethclient => gethexec}/forwarder.go (99%) rename execution/{gethclient => gethexec}/node.go (99%) rename execution/{gethclient => gethexec}/sequencer.go (99%) rename execution/{gethclient => gethexec}/tx_pre_checker.go (99%) diff --git a/arbnode/node.go b/arbnode/node.go index 6c1e4d5356..f7dad45e40 100644 --- a/arbnode/node.go +++ b/arbnode/node.go @@ -30,7 +30,7 @@ import ( "github.com/offchainlabs/nitro/broadcaster" "github.com/offchainlabs/nitro/das" "github.com/offchainlabs/nitro/execution" - "github.com/offchainlabs/nitro/execution/gethclient" + "github.com/offchainlabs/nitro/execution/gethexec" "github.com/offchainlabs/nitro/solgen/go/bridgegen" "github.com/offchainlabs/nitro/solgen/go/challengegen" "github.com/offchainlabs/nitro/solgen/go/ospgen" @@ -949,7 +949,7 @@ func CreateNode( } func (n *Node) Start(ctx context.Context) error { - execClient, ok := n.Execution.(*gethclient.ExecutionNode) + execClient, ok := n.Execution.(*gethexec.ExecutionNode) if !ok { execClient = nil } @@ -1063,7 +1063,7 @@ func (n *Node) Start(ctx context.Context) error { } func (n *Node) StopAndWait() { - execClient, ok := n.Execution.(*gethclient.ExecutionNode) + execClient, ok := n.Execution.(*gethexec.ExecutionNode) if !ok { execClient = nil } diff --git a/cmd/nitro/init.go b/cmd/nitro/init.go index c4d13c8617..b54c96935f 100644 --- a/cmd/nitro/init.go +++ b/cmd/nitro/init.go @@ -26,7 +26,7 @@ import ( "github.com/offchainlabs/nitro/arbos" "github.com/offchainlabs/nitro/arbos/arbosState" "github.com/offchainlabs/nitro/cmd/ipfshelper" - "github.com/offchainlabs/nitro/execution/gethclient" + "github.com/offchainlabs/nitro/execution/gethexec" "github.com/offchainlabs/nitro/statetransfer" "github.com/pkg/errors" flag "github.com/spf13/pflag" @@ -176,13 +176,13 @@ func validateBlockChain(blockChain *core.BlockChain, expectedChainId *big.Int) e func openInitializeChainDb(ctx context.Context, stack *node.Node, config *NodeConfig, chainId *big.Int, cacheConfig *core.CacheConfig) (ethdb.Database, *core.BlockChain, error) { if !config.Init.Force { if readOnlyDb, err := stack.OpenDatabaseWithFreezer("l2chaindata", 0, 0, "", "", true); err == nil { - if chainConfig := gethclient.TryReadStoredChainConfig(readOnlyDb); chainConfig != nil { + if chainConfig := gethexec.TryReadStoredChainConfig(readOnlyDb); chainConfig != nil { readOnlyDb.Close() chainDb, err := stack.OpenDatabaseWithFreezer("l2chaindata", config.Execution.Caching.DatabaseCache, config.Persistent.Handles, "", "", false) if err != nil { return chainDb, nil, err } - l2BlockChain, err := gethclient.GetBlockChain(chainDb, cacheConfig, chainConfig, config.Execution.TxLookupLimit) + l2BlockChain, err := gethexec.GetBlockChain(chainDb, cacheConfig, chainConfig, config.Execution.TxLookupLimit) if err != nil { return chainDb, nil, err } @@ -261,11 +261,11 @@ func openInitializeChainDb(ctx context.Context, stack *node.Node, config *NodeCo var l2BlockChain *core.BlockChain txIndexWg := sync.WaitGroup{} if initDataReader == nil { - chainConfig = gethclient.TryReadStoredChainConfig(chainDb) + chainConfig = gethexec.TryReadStoredChainConfig(chainDb) if chainConfig == nil { return chainDb, nil, errors.New("no --init.* mode supplied and chain data not in expected directory") } - l2BlockChain, err = gethclient.GetBlockChain(chainDb, cacheConfig, chainConfig, config.Execution.TxLookupLimit) + l2BlockChain, err = gethexec.GetBlockChain(chainDb, cacheConfig, chainConfig, config.Execution.TxLookupLimit) if err != nil { return chainDb, nil, err } @@ -307,7 +307,7 @@ func openInitializeChainDb(ctx context.Context, stack *node.Node, config *NodeCo if config.Init.ThenQuit { cacheConfig.SnapshotWait = true } - l2BlockChain, err = gethclient.WriteOrTestBlockChain(chainDb, cacheConfig, initDataReader, chainConfig, config.Execution.TxLookupLimit, config.Init.AccountsPerSync) + l2BlockChain, err = gethexec.WriteOrTestBlockChain(chainDb, cacheConfig, initDataReader, chainConfig, config.Execution.TxLookupLimit, config.Init.AccountsPerSync) if err != nil { return chainDb, nil, err } diff --git a/cmd/nitro/nitro.go b/cmd/nitro/nitro.go index 9cef2136c0..14d3f88ba9 100644 --- a/cmd/nitro/nitro.go +++ b/cmd/nitro/nitro.go @@ -49,7 +49,7 @@ import ( "github.com/offchainlabs/nitro/cmd/genericconf" "github.com/offchainlabs/nitro/cmd/util" "github.com/offchainlabs/nitro/cmd/util/confighelpers" - "github.com/offchainlabs/nitro/execution/gethclient" + "github.com/offchainlabs/nitro/execution/gethexec" _ "github.com/offchainlabs/nitro/nodeInterface" "github.com/offchainlabs/nitro/staker" "github.com/offchainlabs/nitro/util/colors" @@ -381,7 +381,7 @@ func mainImpl() int { } } - chainDb, l2BlockChain, err := openInitializeChainDb(ctx, stack, nodeConfig, new(big.Int).SetUint64(nodeConfig.L2.ChainID), gethclient.DefaultCacheConfigFor(stack, &nodeConfig.Execution.Caching)) + chainDb, l2BlockChain, err := openInitializeChainDb(ctx, stack, nodeConfig, new(big.Int).SetUint64(nodeConfig.L2.ChainID), gethexec.DefaultCacheConfigFor(stack, &nodeConfig.Execution.Caching)) defer closeDb(chainDb, "chainDb") if l2BlockChain != nil { // Calling Stop on the blockchain multiple times does nothing @@ -439,12 +439,12 @@ func mainImpl() int { log.Warn("couldn't init validation node", "err", err) } - execNode, err := gethclient.CreateExecutionNode( + execNode, err := gethexec.CreateExecutionNode( stack, chainDb, l2BlockChain, l1Client, - func() *gethclient.Config { return &liveNodeConfig.get().Execution }, + func() *gethexec.Config { return &liveNodeConfig.get().Execution }, ) if err != nil { log.Error("failed to create execution node", "err", err) @@ -532,7 +532,7 @@ func mainImpl() int { type NodeConfig struct { Conf genericconf.ConfConfig `koanf:"conf" reload:"hot"` Node arbnode.Config `koanf:"node" reload:"hot"` - Execution gethclient.Config `koanf:"exec" reload:"hot"` + Execution gethexec.Config `koanf:"exec" reload:"hot"` Validation valnode.Config `koanf:"validation" reload:"hot"` L1 conf.L1Config `koanf:"l1"` L2 conf.L2Config `koanf:"l2"` diff --git a/execution/gethclient/api.go b/execution/gethexec/api.go similarity index 99% rename from execution/gethclient/api.go rename to execution/gethexec/api.go index d7f686baff..fa8780a38a 100644 --- a/execution/gethclient/api.go +++ b/execution/gethexec/api.go @@ -1,7 +1,7 @@ // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE -package gethclient +package gethexec import ( "context" diff --git a/execution/gethclient/arb_interface.go b/execution/gethexec/arb_interface.go similarity index 98% rename from execution/gethclient/arb_interface.go rename to execution/gethexec/arb_interface.go index 7585e29749..049dc4e240 100644 --- a/execution/gethclient/arb_interface.go +++ b/execution/gethexec/arb_interface.go @@ -1,7 +1,7 @@ // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE -package gethclient +package gethexec import ( "context" diff --git a/execution/gethclient/block_recorder.go b/execution/gethexec/block_recorder.go similarity index 99% rename from execution/gethclient/block_recorder.go rename to execution/gethexec/block_recorder.go index c59d484ef7..745dc0d2fe 100644 --- a/execution/gethclient/block_recorder.go +++ b/execution/gethexec/block_recorder.go @@ -1,4 +1,4 @@ -package gethclient +package gethexec import ( "context" diff --git a/execution/gethclient/blockchain.go b/execution/gethexec/blockchain.go similarity index 99% rename from execution/gethclient/blockchain.go rename to execution/gethexec/blockchain.go index 2a953c5dbd..9086ef10b5 100644 --- a/execution/gethclient/blockchain.go +++ b/execution/gethexec/blockchain.go @@ -1,4 +1,4 @@ -package gethclient +package gethexec import ( "errors" diff --git a/execution/gethclient/executionengine.go b/execution/gethexec/executionengine.go similarity index 99% rename from execution/gethclient/executionengine.go rename to execution/gethexec/executionengine.go index 060d0cbb4f..07a54d0757 100644 --- a/execution/gethclient/executionengine.go +++ b/execution/gethexec/executionengine.go @@ -1,4 +1,4 @@ -package gethclient +package gethexec import ( "context" diff --git a/execution/gethclient/forwarder.go b/execution/gethexec/forwarder.go similarity index 99% rename from execution/gethclient/forwarder.go rename to execution/gethexec/forwarder.go index 60dd4f4d87..e4e5686b34 100644 --- a/execution/gethclient/forwarder.go +++ b/execution/gethexec/forwarder.go @@ -1,7 +1,7 @@ // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE -package gethclient +package gethexec import ( "context" diff --git a/execution/gethclient/node.go b/execution/gethexec/node.go similarity index 99% rename from execution/gethclient/node.go rename to execution/gethexec/node.go index 5983155444..06801bfb41 100644 --- a/execution/gethclient/node.go +++ b/execution/gethexec/node.go @@ -1,4 +1,4 @@ -package gethclient +package gethexec import ( "context" diff --git a/execution/gethclient/sequencer.go b/execution/gethexec/sequencer.go similarity index 99% rename from execution/gethclient/sequencer.go rename to execution/gethexec/sequencer.go index ddc70ac2b5..e8333e5443 100644 --- a/execution/gethclient/sequencer.go +++ b/execution/gethexec/sequencer.go @@ -1,7 +1,7 @@ // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE -package gethclient +package gethexec import ( "context" diff --git a/execution/gethclient/tx_pre_checker.go b/execution/gethexec/tx_pre_checker.go similarity index 99% rename from execution/gethclient/tx_pre_checker.go rename to execution/gethexec/tx_pre_checker.go index 3c991343d5..2e92144d79 100644 --- a/execution/gethclient/tx_pre_checker.go +++ b/execution/gethexec/tx_pre_checker.go @@ -1,7 +1,7 @@ // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE -package gethclient +package gethexec import ( "context" From 8f6ef39321ccfc4f124ccb0ba171f98d8d1ba7e4 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Wed, 15 Mar 2023 17:27:31 +0200 Subject: [PATCH 06/23] execnode: small fixes --- arbnode/inbox_test.go | 21 +++++++++++++++------ arbnode/node.go | 5 ++++- execution/gethexec/node.go | 23 ++++++++++++++--------- 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/arbnode/inbox_test.go b/arbnode/inbox_test.go index 037bbc2945..2daa60161f 100644 --- a/arbnode/inbox_test.go +++ b/arbnode/inbox_test.go @@ -14,8 +14,7 @@ import ( "github.com/offchainlabs/nitro/arbos/arbostypes" "github.com/offchainlabs/nitro/arbos/l2pricing" "github.com/offchainlabs/nitro/arbutil" - "github.com/offchainlabs/nitro/execution" - "github.com/offchainlabs/nitro/execution/gethclient" + "github.com/offchainlabs/nitro/execution/gethexec" "github.com/offchainlabs/nitro/statetransfer" nitroutil "github.com/offchainlabs/nitro/util" @@ -30,7 +29,16 @@ import ( "github.com/offchainlabs/nitro/arbos" ) -func NewTransactionStreamerForTest(t *testing.T, ownerAddress common.Address) (*execution.ExecutionEngine, *TransactionStreamer, ethdb.Database, *core.BlockChain) { +type execClientWrapper struct { + *gethexec.ExecutionEngine + t *testing.T +} + +func (w *execClientWrapper) Pause() { w.t.Error("not supported") } +func (w *execClientWrapper) Activate() { w.t.Error("not supported") } +func (w *execClientWrapper) ForwardTo(url string) error { w.t.Error("not supported"); return nil } + +func NewTransactionStreamerForTest(t *testing.T, ownerAddress common.Address) (*gethexec.ExecutionEngine, *TransactionStreamer, ethdb.Database, *core.BlockChain) { chainConfig := params.ArbitrumDevTestChainConfig() initData := statetransfer.ArbosInitializationInfo{ @@ -46,18 +54,19 @@ func NewTransactionStreamerForTest(t *testing.T, ownerAddress common.Address) (* arbDb := rawdb.NewMemoryDatabase() initReader := statetransfer.NewMemoryInitDataReader(&initData) - bc, err := gethclient.WriteOrTestBlockChain(chainDb, nil, initReader, chainConfig, ConfigDefaultL2Test().TxLookupLimit, 0) + bc, err := gethexec.WriteOrTestBlockChain(chainDb, nil, initReader, chainConfig, gethexec.ConfigDefaultTest().TxLookupLimit, 0) if err != nil { Fail(t, err) } transactionStreamerConfigFetcher := func() *TransactionStreamerConfig { return &DefaultTransactionStreamerConfig } - execEngine, err := execution.NewExecutionEngine(bc) + execEngine, err := gethexec.NewExecutionEngine(bc) if err != nil { Fail(t, err) } - inbox, err := NewTransactionStreamer(arbDb, bc.Config(), execEngine, nil, make(chan error, 1), transactionStreamerConfigFetcher) + execSeq := &execClientWrapper{execEngine, t} + inbox, err := NewTransactionStreamer(arbDb, bc.Config(), execSeq, nil, make(chan error, 1), transactionStreamerConfigFetcher) if err != nil { Fail(t, err) } diff --git a/arbnode/node.go b/arbnode/node.go index f7dad45e40..822cbcbccb 100644 --- a/arbnode/node.go +++ b/arbnode/node.go @@ -954,7 +954,10 @@ func (n *Node) Start(ctx context.Context) error { execClient = nil } if execClient != nil { - execClient.Initialize(ctx, n, n.SyncMonitor) + err := execClient.Initialize(ctx, n, n.SyncMonitor) + if err != nil { + return fmt.Errorf("error initializing exec client: %w", err) + } } n.SyncMonitor.Initialize(n.InboxReader, n.TxStreamer, n.SeqCoordinator, n.Execution) err := n.Stack.Start() diff --git a/execution/gethexec/node.go b/execution/gethexec/node.go index 06801bfb41..3d292730d2 100644 --- a/execution/gethexec/node.go +++ b/execution/gethexec/node.go @@ -107,14 +107,15 @@ func ConfigDefaultTest() *Config { type ConfigFetcher func() *Config type ExecutionNode struct { - ChainDB ethdb.Database - Backend *arbitrum.Backend - FilterSystem *filters.FilterSystem - ArbInterface *ArbInterface - ExecEngine *ExecutionEngine - Recorder *BlockRecorder - Sequencer *Sequencer // either nil or same as TxPublisher - TxPublisher TransactionPublisher + ChainDB ethdb.Database + Backend *arbitrum.Backend + FilterSystem *filters.FilterSystem + ArbInterface *ArbInterface + ExecEngine *ExecutionEngine + Recorder *BlockRecorder + Sequencer *Sequencer // either nil or same as TxPublisher + TxPublisher TransactionPublisher + ConfigFetcher ConfigFetcher } func CreateExecutionNode( @@ -133,7 +134,10 @@ func CreateExecutionNode( var txPublisher TransactionPublisher var sequencer *Sequencer - l1Reader := headerreader.New(l1client, func() *headerreader.Config { return &configFetcher().L1Reader }) + var l1Reader *headerreader.HeaderReader + if l1client != nil { + l1Reader = headerreader.New(l1client, func() *headerreader.Config { return &configFetcher().L1Reader }) + } fwTarget := config.ForwardingTarget() if config.Sequencer.Enable { @@ -213,6 +217,7 @@ func CreateExecutionNode( recorder, sequencer, txPublisher, + configFetcher, }, nil } From bb797fd11d7a394782414181c237ac23b15e0e0c Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Wed, 15 Mar 2023 17:27:51 +0200 Subject: [PATCH 07/23] update geth --- go-ethereum | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go-ethereum b/go-ethereum index 942746e4d6..dcb407568c 160000 --- a/go-ethereum +++ b/go-ethereum @@ -1 +1 @@ -Subproject commit 942746e4d6996ced8a5ce50f04a3d2c1c332c4f9 +Subproject commit dcb407568c3641278ce496c2576205719acf19c9 From caa4823cbe918a3670a331f84acd69ee95399a44 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Wed, 15 Mar 2023 17:29:42 +0200 Subject: [PATCH 08/23] execution service - fix tests --- cmd/nitro/config_test.go | 29 +++++----- cmd/nitro/nitro.go | 11 ++-- cmd/util/confighelpers/configuration.go | 2 +- execution/gethexec/node.go | 2 +- system_tests/arbtrace_test.go | 10 ++-- system_tests/batch_poster_test.go | 7 ++- system_tests/block_validator_test.go | 13 +++-- system_tests/bloom_test.go | 14 ++--- system_tests/common_test.go | 71 +++++++++++++++++++----- system_tests/contract_tx_test.go | 4 +- system_tests/das_test.go | 25 ++++++--- system_tests/debugapi_test.go | 2 +- system_tests/estimation_test.go | 3 +- system_tests/fees_test.go | 5 +- system_tests/forwarder_test.go | 30 +++++----- system_tests/full_challenge_impl_test.go | 21 ++++--- system_tests/infra_fee_test.go | 4 +- system_tests/initialization_test.go | 3 +- system_tests/ipc_test.go | 2 +- system_tests/meaningless_reorg_test.go | 5 +- system_tests/reorg_resequencing_test.go | 8 ++- system_tests/seq_coordinator_test.go | 2 +- system_tests/seq_nonce_test.go | 14 ++--- system_tests/seq_pause_test.go | 7 ++- system_tests/seq_reject_test.go | 4 +- system_tests/seq_whitelist_test.go | 6 +- system_tests/seqfeed_test.go | 29 ++++++---- system_tests/seqinbox_test.go | 7 ++- system_tests/staker_test.go | 13 +++-- system_tests/twonodes_test.go | 2 +- system_tests/twonodeslong_test.go | 2 +- system_tests/validation_mock_test.go | 2 +- testnode-scripts/config.ts | 12 ++-- 33 files changed, 229 insertions(+), 142 deletions(-) diff --git a/cmd/nitro/config_test.go b/cmd/nitro/config_test.go index c1ef5b3a8f..47f74fe231 100644 --- a/cmd/nitro/config_test.go +++ b/cmd/nitro/config_test.go @@ -19,25 +19,25 @@ import ( ) func TestSeqConfig(t *testing.T) { - args := strings.Split("--persistent.chain /tmp/data --init.dev-init --node.l1-reader.enable=false --l1.chain-id 5 --l2.chain-id 421613 --l1.wallet.pathname /l1keystore --l1.wallet.password passphrase --http.addr 0.0.0.0 --ws.addr 0.0.0.0 --node.sequencer.enable --node.feed.output.enable --node.feed.output.port 9642", " ") + args := strings.Split("--persistent.chain /tmp/data --init.dev-init --node.l1-reader.enable=false --l1.chain-id 5 --l2.chain-id 421613 --l1.wallet.pathname /l1keystore --l1.wallet.password passphrase --http.addr 0.0.0.0 --ws.addr 0.0.0.0 --node.sequencer --execution.sequencer.enable --node.feed.output.enable --node.feed.output.port 9642", " ") _, _, _, _, _, err := ParseNode(context.Background(), args) Require(t, err) } func TestUnsafeStakerConfig(t *testing.T) { - args := strings.Split("--persistent.chain /tmp/data --init.dev-init --node.l1-reader.enable=false --l1.chain-id 5 --l2.chain-id 421613 --l1.wallet.pathname /l1keystore --l1.wallet.password passphrase --http.addr 0.0.0.0 --ws.addr 0.0.0.0 --node.staker.enable --node.staker.strategy MakeNodes --node.staker.staker-interval 10s --node.forwarding-target null --node.staker.dangerous.without-block-validator", " ") + args := strings.Split("--persistent.chain /tmp/data --init.dev-init --node.l1-reader.enable=false --l1.chain-id 5 --l2.chain-id 421613 --l1.wallet.pathname /l1keystore --l1.wallet.password passphrase --http.addr 0.0.0.0 --ws.addr 0.0.0.0 --node.staker.enable --node.staker.strategy MakeNodes --node.staker.staker-interval 10s --execution.forwarding-target null --node.staker.dangerous.without-block-validator", " ") _, _, _, _, _, err := ParseNode(context.Background(), args) Require(t, err) } func TestValidatorConfig(t *testing.T) { - args := strings.Split("--persistent.chain /tmp/data --init.dev-init --node.l1-reader.enable=false --l1.chain-id 5 --l2.chain-id 421613 --l1.wallet.pathname /l1keystore --l1.wallet.password passphrase --http.addr 0.0.0.0 --ws.addr 0.0.0.0 --node.staker.enable --node.staker.strategy MakeNodes --node.staker.staker-interval 10s --node.forwarding-target null", " ") + args := strings.Split("--persistent.chain /tmp/data --init.dev-init --node.l1-reader.enable=false --l1.chain-id 5 --l2.chain-id 421613 --l1.wallet.pathname /l1keystore --l1.wallet.password passphrase --http.addr 0.0.0.0 --ws.addr 0.0.0.0 --node.staker.enable --node.staker.strategy MakeNodes --node.staker.staker-interval 10s --execution.forwarding-target null", " ") _, _, _, _, _, err := ParseNode(context.Background(), args) Require(t, err) } func TestAggregatorConfig(t *testing.T) { - args := strings.Split("--persistent.chain /tmp/data --init.dev-init --node.l1-reader.enable=false --l1.chain-id 5 --l2.chain-id 421613 --l1.wallet.pathname /l1keystore --l1.wallet.password passphrase --http.addr 0.0.0.0 --ws.addr 0.0.0.0 --node.sequencer.enable --node.feed.output.enable --node.feed.output.port 9642 --node.data-availability.enable --node.data-availability.rpc-aggregator.backends {[\"url\":\"http://localhost:8547\",\"pubkey\":\"abc==\",\"signerMask\":0x1]}", " ") + args := strings.Split("--persistent.chain /tmp/data --init.dev-init --node.l1-reader.enable=false --l1.chain-id 5 --l2.chain-id 421613 --l1.wallet.pathname /l1keystore --l1.wallet.password passphrase --http.addr 0.0.0.0 --ws.addr 0.0.0.0 --node.sequencer --execution.sequencer.enable --node.feed.output.enable --node.feed.output.port 9642 --node.data-availability.enable --node.data-availability.rpc-aggregator.backends {[\"url\":\"http://localhost:8547\",\"pubkey\":\"abc==\",\"signerMask\":0x1]}", " ") _, _, _, _, _, err := ParseNode(context.Background(), args) Require(t, err) } @@ -68,13 +68,14 @@ func TestReloads(t *testing.T) { config := NodeConfigDefault update := NodeConfigDefault - update.Node.Sequencer.MaxBlockSpeed++ + update.Node.BatchPoster.BatchPollDelay++ check(reflect.ValueOf(config), false, "config") Require(t, config.CanReload(&config)) Require(t, config.CanReload(&update)) testUnsafe := func() { + t.Helper() if config.CanReload(&update) == nil { Fail(t, "failed to detect unsafe reload") } @@ -86,7 +87,7 @@ func TestReloads(t *testing.T) { testUnsafe() update.L2.ChainID++ testUnsafe() - update.Node.Sequencer.Forwarder.ConnectionTimeout++ + update.Node.Staker.Enable = !update.Node.Staker.Enable testUnsafe() } @@ -99,7 +100,7 @@ func TestLiveNodeConfig(t *testing.T) { jsonConfig := "{\"l2\":{\"chain-id\":421613}}" Require(t, WriteToConfigFile(configFile, jsonConfig)) - args := strings.Split("--file-logging.enable=false --persistent.chain /tmp/data --init.dev-init --node.l1-reader.enable=false --l1.chain-id 5 --l1.wallet.pathname /l1keystore --l1.wallet.password passphrase --http.addr 0.0.0.0 --ws.addr 0.0.0.0 --node.sequencer.enable --node.feed.output.enable --node.feed.output.port 9642", " ") + args := strings.Split("--file-logging.enable=false --persistent.chain /tmp/data --init.dev-init --node.l1-reader.enable=false --l1.chain-id 5 --l1.wallet.pathname /l1keystore --l1.wallet.password passphrase --http.addr 0.0.0.0 --ws.addr 0.0.0.0 --node.sequencer --execution.sequencer.enable --node.feed.output.enable --node.feed.output.port 9642", " ") args = append(args, []string{"--conf.file", configFile}...) config, _, _, _, _, err := ParseNode(context.Background(), args) Require(t, err) @@ -109,8 +110,8 @@ func TestLiveNodeConfig(t *testing.T) { // check updating the config update := config.ShallowClone() expected := config.ShallowClone() - update.Node.Sequencer.MaxBlockSpeed += 2 * time.Millisecond - expected.Node.Sequencer.MaxBlockSpeed += 2 * time.Millisecond + update.Node.BatchPoster.BatchPollDelay += 2 * time.Millisecond + expected.Node.BatchPoster.BatchPollDelay += 2 * time.Millisecond Require(t, liveConfig.set(update)) if !reflect.DeepEqual(liveConfig.get(), expected) { Fail(t, "failed to set config") @@ -145,19 +146,19 @@ func TestLiveNodeConfig(t *testing.T) { // change the config file expected = config.ShallowClone() - expected.Node.Sequencer.MaxBlockSpeed += time.Millisecond - jsonConfig = fmt.Sprintf("{\"node\":{\"sequencer\":{\"max-block-speed\":\"%s\"}}, \"l2\":{\"chain-id\":421613}}", expected.Node.Sequencer.MaxBlockSpeed.String()) + expected.Node.BatchPoster.BatchPollDelay += time.Millisecond + jsonConfig = fmt.Sprintf("{\"node\":{\"batch-poster\":{\"poll-delay\":\"%s\"}}, \"l2\":{\"chain-id\":421613}}", expected.Node.BatchPoster.BatchPollDelay.String()) Require(t, WriteToConfigFile(configFile, jsonConfig)) // trigger LiveConfig reload Require(t, syscall.Kill(syscall.Getpid(), syscall.SIGUSR1)) if !PollLiveConfigUntilEqual(liveConfig, expected) { - Fail(t, "failed to update config", config.Node.Sequencer.MaxBlockSpeed, update.Node.Sequencer.MaxBlockSpeed) + Fail(t, "failed to update config", config.Node.BatchPoster.BatchPollDelay, update.Node.BatchPoster.BatchPollDelay) } // change l2.chain-id in the config file (currently non-reloadable) - jsonConfig = fmt.Sprintf("{\"node\":{\"sequencer\":{\"max-block-speed\":\"%s\"}}, \"l2\":{\"chain-id\":421703}}", expected.Node.Sequencer.MaxBlockSpeed.String()) + jsonConfig = fmt.Sprintf("{\"node\":{\"batch-poster\":{\"poll-delay\":\"%s\"}}, \"l2\":{\"chain-id\":421703}}", expected.Node.BatchPoster.BatchPollDelay.String()) Require(t, WriteToConfigFile(configFile, jsonConfig)) // trigger LiveConfig reload @@ -177,7 +178,7 @@ func TestPeriodicReloadOfLiveNodeConfig(t *testing.T) { jsonConfig := "{\"conf\":{\"reload-interval\":\"20ms\"}}" Require(t, WriteToConfigFile(configFile, jsonConfig)) - args := strings.Split("--persistent.chain /tmp/data --init.dev-init --node.l1-reader.enable=false --l1.chain-id 5 --l2.chain-id 421613 --l1.wallet.pathname /l1keystore --l1.wallet.password passphrase --http.addr 0.0.0.0 --ws.addr 0.0.0.0 --node.sequencer.enable --node.feed.output.enable --node.feed.output.port 9642", " ") + args := strings.Split("--persistent.chain /tmp/data --init.dev-init --node.l1-reader.enable=false --l1.chain-id 5 --l2.chain-id 421613 --l1.wallet.pathname /l1keystore --l1.wallet.password passphrase --http.addr 0.0.0.0 --ws.addr 0.0.0.0 --node.sequencer --execution.sequencer.enable --node.feed.output.enable --node.feed.output.port 9642", " ") args = append(args, []string{"--conf.file", configFile}...) config, _, _, _, _, err := ParseNode(context.Background(), args) Require(t, err) diff --git a/cmd/nitro/nitro.go b/cmd/nitro/nitro.go index 14d3f88ba9..ec827c61d8 100644 --- a/cmd/nitro/nitro.go +++ b/cmd/nitro/nitro.go @@ -532,7 +532,7 @@ func mainImpl() int { type NodeConfig struct { Conf genericconf.ConfConfig `koanf:"conf" reload:"hot"` Node arbnode.Config `koanf:"node" reload:"hot"` - Execution gethexec.Config `koanf:"exec" reload:"hot"` + Execution gethexec.Config `koanf:"execution" reload:"hot"` Validation valnode.Config `koanf:"validation" reload:"hot"` L1 conf.L1Config `koanf:"l1"` L2 conf.L2Config `koanf:"l2"` @@ -568,6 +568,7 @@ var NodeConfigDefault = NodeConfig{ func NodeConfigAddOptions(f *flag.FlagSet) { genericconf.ConfConfigAddOptions("conf", f) arbnode.ConfigAddOptions("node", f, true, true) + gethexec.ConfigAddOptions("execution", f) valnode.ValidationConfigAddOptions("validation", f) conf.L1ConfigAddOptions("l1", f) conf.L2ConfigAddOptions("l2", f) @@ -822,7 +823,7 @@ func ParseNode(ctx context.Context, args []string) (*NodeConfig, *genericconf.Wa func applyArbitrumOneParameters(k *koanf.Koanf) error { return k.Load(confmap.Provider(map[string]interface{}{ "persistent.chain": "arb1", - "node.forwarding-target": "https://arb1.arbitrum.io/rpc", + "execution.forwarding-target": "https://arb1.arbitrum.io/rpc", "node.feed.input.url": "wss://arb1.arbitrum.io/feed", "l1.rollup.bridge": "0x8315177ab297ba92a06054ce80a67ed4dbd7ed3a", "l1.rollup.inbox": "0x4dbd4fc535ac27206064b68ffcf827b0a60bab3f", @@ -838,7 +839,7 @@ func applyArbitrumOneParameters(k *koanf.Koanf) error { func applyArbitrumNovaParameters(k *koanf.Koanf) error { return k.Load(confmap.Provider(map[string]interface{}{ "persistent.chain": "nova", - "node.forwarding-target": "https://nova.arbitrum.io/rpc", + "execution.forwarding-target": "https://nova.arbitrum.io/rpc", "node.feed.input.url": "wss://nova.arbitrum.io/feed", "node.data-availability.enable": true, "node.data-availability.rest-aggregator.enable": true, @@ -858,7 +859,7 @@ func applyArbitrumNovaParameters(k *koanf.Koanf) error { func applyArbitrumRollupGoerliTestnetParameters(k *koanf.Koanf) error { return k.Load(confmap.Provider(map[string]interface{}{ "persistent.chain": "goerli-rollup", - "node.forwarding-target": "https://goerli-rollup.arbitrum.io/rpc", + "execution.forwarding-target": "https://goerli-rollup.arbitrum.io/rpc", "node.feed.input.url": "wss://goerli-rollup.arbitrum.io/feed", "l1.rollup.bridge": "0xaf4159a80b6cc41ed517db1c453d1ef5c2e4db72", "l1.rollup.inbox": "0x6bebc4925716945d46f0ec336d5c2564f419682c", @@ -875,7 +876,7 @@ func applyArbitrumRollupGoerliTestnetParameters(k *koanf.Koanf) error { func applyArbitrumRollupRinkebyTestnetParameters(k *koanf.Koanf) error { return k.Load(confmap.Provider(map[string]interface{}{ "persistent.chain": "rinkeby-nitro", - "node.forwarding-target": "https://rinkeby.arbitrum.io/rpc", + "execution.forwarding-target": "https://rinkeby.arbitrum.io/rpc", "node.feed.input.url": "wss://rinkeby.arbitrum.io/feed", "l1.rollup.bridge": "0x85c720444e436e1f9407e0c3895d3fe149f41168", "l1.rollup.inbox": "0x578BAde599406A8fE3d24Fd7f7211c0911F5B29e", diff --git a/cmd/util/confighelpers/configuration.go b/cmd/util/confighelpers/configuration.go index b86016505a..179a6503f3 100644 --- a/cmd/util/confighelpers/configuration.go +++ b/cmd/util/confighelpers/configuration.go @@ -150,7 +150,7 @@ func BeginCommonParse(f *flag.FlagSet, args []string) (*koanf.Koanf, error) { if f.NArg() != 0 { // Unexpected number of parameters - return nil, errors.New("unexpected number of parameters") + return nil, fmt.Errorf("unexpected parameter: %s", f.Arg(0)) } var k = koanf.New(".") diff --git a/execution/gethexec/node.go b/execution/gethexec/node.go index 3d292730d2..8114f9c623 100644 --- a/execution/gethexec/node.go +++ b/execution/gethexec/node.go @@ -62,7 +62,7 @@ func (c *Config) Validate() error { return nil } -func ConfigAddOptions(prefix string, f *flag.FlagSet, feedInputEnable bool, feedOutputEnable bool) { +func ConfigAddOptions(prefix string, f *flag.FlagSet) { arbitrum.ConfigAddOptions(prefix+".rpc", f) SequencerConfigAddOptions(prefix+".sequencer", f) f.String(prefix+".forwarding-target", ConfigDefault.ForwardingTargetImpl, "transaction forwarding target URL, or \"null\" to disable forwarding (iff not sequencer)") diff --git a/system_tests/arbtrace_test.go b/system_tests/arbtrace_test.go index b877e85dff..4075892284 100644 --- a/system_tests/arbtrace_test.go +++ b/system_tests/arbtrace_test.go @@ -11,7 +11,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/rpc" - "github.com/offchainlabs/nitro/arbnode" + "github.com/offchainlabs/nitro/execution/gethexec" "github.com/offchainlabs/nitro/util/testhelpers" ) @@ -145,10 +145,10 @@ func TestArbTraceForwarding(t *testing.T) { defer srv.Stop() defer listener.Close() - nodeConfig := arbnode.ConfigDefaultL1Test() - nodeConfig.RPC.ClassicRedirect = ipcPath - nodeConfig.RPC.ClassicRedirectTimeout = time.Second - _, _, _, l2stack, _, _, _, l1stack := createTestNodeOnL1WithConfigImpl(t, ctx, true, nodeConfig, nil, nil) + execConfig := gethexec.ConfigDefaultTest() + execConfig.RPC.ClassicRedirect = ipcPath + execConfig.RPC.ClassicRedirectTimeout = time.Second + _, _, _, l2stack, _, _, _, l1stack := createTestNodeOnL1WithConfigImpl(t, ctx, true, nil, execConfig, nil, nil) defer requireClose(t, l1stack) defer requireClose(t, l2stack) diff --git a/system_tests/batch_poster_test.go b/system_tests/batch_poster_test.go index 1e5451cdcd..884ef2f807 100644 --- a/system_tests/batch_poster_test.go +++ b/system_tests/batch_poster_test.go @@ -14,6 +14,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/offchainlabs/nitro/arbnode" + "github.com/offchainlabs/nitro/execution/gethexec" "github.com/offchainlabs/nitro/util/redisutil" ) @@ -35,7 +36,7 @@ func TestBatchPosterParallel(t *testing.T) { conf := arbnode.ConfigDefaultL1Test() conf.BatchPoster.Enable = false conf.BatchPoster.RedisUrl = redisUrl - l2info, nodeA, l2clientA, l1info, _, l1client, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, conf, nil, nil) + l2info, nodeA, l2clientA, l1info, _, l1client, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, conf, nil, nil, nil) defer requireClose(t, l1stack) defer nodeA.StopAndWait() @@ -127,9 +128,9 @@ func TestBatchPosterLargeTx(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - conf := arbnode.ConfigDefaultL1Test() + conf := gethexec.ConfigDefaultTest() conf.Sequencer.MaxTxDataSize = 110000 - l2info, nodeA, l2clientA, l1info, _, _, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, conf, nil, nil) + l2info, nodeA, l2clientA, l1info, _, _, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, nil, conf, nil, nil) defer requireClose(t, l1stack) defer nodeA.StopAndWait() diff --git a/system_tests/block_validator_test.go b/system_tests/block_validator_test.go index a20e7992d4..c394dff941 100644 --- a/system_tests/block_validator_test.go +++ b/system_tests/block_validator_test.go @@ -18,6 +18,7 @@ import ( "github.com/offchainlabs/nitro/arbnode" "github.com/offchainlabs/nitro/arbos/l2pricing" "github.com/offchainlabs/nitro/arbutil" + "github.com/offchainlabs/nitro/execution/gethexec" ) func testBlockValidatorSimple(t *testing.T, dasModeString string, simpletxloops int, expensiveTx bool, arbitrator bool) { @@ -34,7 +35,7 @@ func testBlockValidatorSimple(t *testing.T, dasModeString string, simpletxloops delayEvery = simpletxloops / 3 } - l2info, nodeA, l2client, l1info, _, l1client, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, l1NodeConfigA, chainConfig, nil) + l2info, nodeA, l2client, l1info, _, l1client, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, l1NodeConfigA, nil, chainConfig, nil) defer requireClose(t, l1stack) defer nodeA.StopAndWait() @@ -45,7 +46,7 @@ func testBlockValidatorSimple(t *testing.T, dasModeString string, simpletxloops validatorConfig.DataAvailability = l1NodeConfigA.DataAvailability validatorConfig.DataAvailability.AggregatorConfig.Enable = false AddDefaultValNode(t, ctx, validatorConfig, !arbitrator) - l2clientB, nodeB := Create2ndNodeWithConfig(t, ctx, nodeA, l1stack, l1info, &l2info.ArbInitData, validatorConfig, nil) + l2clientB, nodeB := Create2ndNodeWithConfig(t, ctx, nodeA, l1stack, l1info, &l2info.ArbInitData, validatorConfig, nil, nil) defer nodeB.StopAndWait() l2info.GenerateAccount("User2") @@ -134,8 +135,12 @@ func testBlockValidatorSimple(t *testing.T, dasModeString string, simpletxloops if !nodeB.BlockValidator.WaitForPos(t, ctx, arbutil.MessageIndex(lastBlock.NumberU64()), timeout) { Fail(t, "did not validate all blocks") } - nodeB.Execution.Recorder.TrimAllPrepared(t) - finalRefCount := nodeB.Execution.Recorder.RecordingDBReferenceCount() + gethExec, ok := nodeB.Execution.(*gethexec.ExecutionNode) + if !ok { + t.Fail() + } + gethExec.Recorder.TrimAllPrepared(t) + finalRefCount := gethExec.Recorder.RecordingDBReferenceCount() lastBlockNow, err := l2clientB.BlockByNumber(ctx, nil) Require(t, err) // up to 3 extra references: awaiting validation, recently valid, lastValidatedHeader diff --git a/system_tests/bloom_test.go b/system_tests/bloom_test.go index c932e0f185..600a468cc3 100644 --- a/system_tests/bloom_test.go +++ b/system_tests/bloom_test.go @@ -17,7 +17,7 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" - "github.com/offchainlabs/nitro/arbnode" + "github.com/offchainlabs/nitro/execution/gethexec" "github.com/offchainlabs/nitro/solgen/go/mocksgen" ) @@ -25,10 +25,10 @@ func TestBloom(t *testing.T) { t.Parallel() ctx, cancel := context.WithCancel(context.Background()) defer cancel() - nodeconfig := arbnode.ConfigDefaultL2Test() - nodeconfig.RPC.BloomBitsBlocks = 256 - nodeconfig.RPC.BloomConfirms = 1 - l2info, node, client := CreateTestL2WithConfig(t, ctx, nil, nodeconfig, false) + execconfig := gethexec.ConfigDefaultTest() + execconfig.RPC.BloomBitsBlocks = 256 + execconfig.RPC.BloomConfirms = 1 + l2info, node, client := CreateTestL2WithConfig(t, ctx, nil, nil, execconfig, false) defer node.StopAndWait() l2info.GenerateAccount("User2") @@ -80,9 +80,9 @@ func TestBloom(t *testing.T) { t.Log("counts: ", i, "/", countsNum) } } - + execNode := getExecNode(t, node) for { - sectionSize, sectionNum := node.Execution.Backend.APIBackend().BloomStatus() + sectionSize, sectionNum := execNode.Backend.APIBackend().BloomStatus() if sectionSize != 256 { Fail(t, "unexpected section size: ", sectionSize) } diff --git a/system_tests/common_test.go b/system_tests/common_test.go index 07ee38a234..dd16b2081c 100644 --- a/system_tests/common_test.go +++ b/system_tests/common_test.go @@ -12,12 +12,12 @@ import ( "testing" "time" - "github.com/offchainlabs/nitro/arbnode/execution" "github.com/offchainlabs/nitro/arbos/util" "github.com/offchainlabs/nitro/arbstate" "github.com/offchainlabs/nitro/blsSignatures" "github.com/offchainlabs/nitro/cmd/genericconf" "github.com/offchainlabs/nitro/das" + "github.com/offchainlabs/nitro/execution/gethexec" "github.com/offchainlabs/nitro/util/arbmath" "github.com/offchainlabs/nitro/util/headerreader" "github.com/offchainlabs/nitro/util/signature" @@ -388,7 +388,7 @@ func createL2BlockChainWithStackConfig( Require(t, err) initReader := statetransfer.NewMemoryInitDataReader(&l2info.ArbInitData) - blockchain, err := execution.WriteOrTestBlockChain(chainDb, nil, initReader, chainConfig, arbnode.ConfigDefaultL2Test().TxLookupLimit, 0) + blockchain, err := gethexec.WriteOrTestBlockChain(chainDb, nil, initReader, chainConfig, gethexec.ConfigDefaultTest().TxLookupLimit, 0) Require(t, err) return l2info, stack, chainDb, arbDb, blockchain @@ -409,7 +409,7 @@ func createTestNodeOnL1( l2info info, node *arbnode.Node, l2client *ethclient.Client, l1info info, l1backend *eth.Ethereum, l1client *ethclient.Client, l1stack *node.Node, ) { - return createTestNodeOnL1WithConfig(t, ctx, isSequencer, nil, nil, nil) + return createTestNodeOnL1WithConfig(t, ctx, isSequencer, nil, nil, nil, nil) } func createTestNodeOnL1WithConfig( @@ -417,13 +417,14 @@ func createTestNodeOnL1WithConfig( ctx context.Context, isSequencer bool, nodeConfig *arbnode.Config, + execConfig *gethexec.Config, chainConfig *params.ChainConfig, stackConfig *node.Config, ) ( l2info info, currentNode *arbnode.Node, l2client *ethclient.Client, l1info info, l1backend *eth.Ethereum, l1client *ethclient.Client, l1stack *node.Node, ) { - l2info, currentNode, l2client, _, l1info, l1backend, l1client, l1stack = createTestNodeOnL1WithConfigImpl(t, ctx, isSequencer, nodeConfig, chainConfig, stackConfig) + l2info, currentNode, l2client, _, l1info, l1backend, l1client, l1stack = createTestNodeOnL1WithConfigImpl(t, ctx, isSequencer, nodeConfig, execConfig, chainConfig, stackConfig) return } @@ -432,6 +433,7 @@ func createTestNodeOnL1WithConfigImpl( ctx context.Context, isSequencer bool, nodeConfig *arbnode.Config, + execConfig *gethexec.Config, chainConfig *params.ChainConfig, stackConfig *node.Config, ) ( @@ -441,6 +443,9 @@ func createTestNodeOnL1WithConfigImpl( if nodeConfig == nil { nodeConfig = arbnode.ConfigDefaultL1Test() } + if execConfig == nil { + execConfig = gethexec.ConfigDefaultTest() + } if chainConfig == nil { chainConfig = params.ArbitrumDevTestChainConfig() } @@ -461,15 +466,20 @@ func createTestNodeOnL1WithConfigImpl( if !isSequencer { nodeConfig.BatchPoster.Enable = false - nodeConfig.Sequencer.Enable = false + nodeConfig.Sequencer = false nodeConfig.DelayedSequencer.Enable = false + execConfig.Sequencer.Enable = false } AddDefaultValNode(t, ctx, nodeConfig, true) - var err error + Require(t, execConfig.Validate()) + execConfigFetcher := func() *gethexec.Config { return execConfig } + execNode, err := gethexec.CreateExecutionNode(l2stack, l2chainDb, l2blockchain, l1client, execConfigFetcher) + Require(t, err) + currentNode, err = arbnode.CreateNode( - ctx, l2stack, l2chainDb, l2arbDb, nodeConfig, l2blockchain, l1client, + ctx, l2stack, execNode, l2arbDb, nodeConfig, l2blockchain.Config(), l1client, addresses, sequencerTxOptsPtr, dataSigner, fatalErrChan, ) Require(t, err) @@ -486,18 +496,31 @@ func createTestNodeOnL1WithConfigImpl( // L2 -Only. Enough for tests that needs no interface to L1 // Requires precompiles.AllowDebugPrecompiles = true func CreateTestL2(t *testing.T, ctx context.Context) (*BlockchainTestInfo, *arbnode.Node, *ethclient.Client) { - return CreateTestL2WithConfig(t, ctx, nil, arbnode.ConfigDefaultL2Test(), true) + return CreateTestL2WithConfig(t, ctx, nil, nil, nil, true) } func CreateTestL2WithConfig( - t *testing.T, ctx context.Context, l2Info *BlockchainTestInfo, nodeConfig *arbnode.Config, takeOwnership bool, + t *testing.T, ctx context.Context, l2Info *BlockchainTestInfo, nodeConfig *arbnode.Config, execConfig *gethexec.Config, takeOwnership bool, ) (*BlockchainTestInfo, *arbnode.Node, *ethclient.Client) { + if nodeConfig == nil { + nodeConfig = arbnode.ConfigDefaultL2Test() + } + if execConfig == nil { + execConfig = gethexec.ConfigDefaultTest() + } + feedErrChan := make(chan error, 10) AddDefaultValNode(t, ctx, nodeConfig, true) l2info, stack, chainDb, arbDb, blockchain := createL2BlockChain(t, l2Info, "", params.ArbitrumDevTestChainConfig()) - currentNode, err := arbnode.CreateNode(ctx, stack, chainDb, arbDb, nodeConfig, blockchain, nil, nil, nil, nil, feedErrChan) + + Require(t, execConfig.Validate()) + execConfigFetcher := func() *gethexec.Config { return execConfig } + execNode, err := gethexec.CreateExecutionNode(stack, chainDb, blockchain, nil, execConfigFetcher) + Require(t, err) + + currentNode, err := arbnode.CreateNode(ctx, stack, execNode, arbDb, nodeConfig, blockchain.Config(), nil, nil, nil, nil, feedErrChan) Require(t, err) // Give the node an init message @@ -565,7 +588,7 @@ func Create2ndNode( } else { nodeConf.DataAvailability = *dasConfig } - return Create2ndNodeWithConfig(t, ctx, first, l1stack, l1info, l2InitData, nodeConf, nil) + return Create2ndNodeWithConfig(t, ctx, first, l1stack, l1info, l2InitData, nodeConf, nil, nil) } func Create2ndNodeWithConfig( @@ -576,8 +599,15 @@ func Create2ndNodeWithConfig( l1info *BlockchainTestInfo, l2InitData *statetransfer.ArbosInitializationInfo, nodeConfig *arbnode.Config, + execConfig *gethexec.Config, stackConfig *node.Config, ) (*ethclient.Client, *arbnode.Node) { + if nodeConfig == nil { + nodeConfig = arbnode.ConfigDefaultL1NonSequencerTest() + } + if execConfig == nil { + execConfig = gethexec.ConfigDefaultNonSequencerTest() + } feedErrChan := make(chan error, 10) l1rpcClient, err := l1stack.Attach() if err != nil { @@ -600,12 +630,18 @@ func Create2ndNodeWithConfig( dataSigner := signature.DataSignerFromPrivateKey(l1info.GetInfoWithPrivKey("Sequencer").PrivateKey) txOpts := l1info.GetDefaultTransactOpts("Sequencer", ctx) - l2blockchain, err := execution.WriteOrTestBlockChain(l2chainDb, nil, initReader, first.Execution.ArbInterface.BlockChain().Config(), arbnode.ConfigDefaultL2Test().TxLookupLimit, 0) + firstExec := getExecNode(t, first) + + l2blockchain, err := gethexec.WriteOrTestBlockChain(l2chainDb, nil, initReader, firstExec.ArbInterface.BlockChain().Config(), gethexec.ConfigDefaultTest().TxLookupLimit, 0) Require(t, err) AddDefaultValNode(t, ctx, nodeConfig, true) - currentNode, err := arbnode.CreateNode(ctx, l2stack, l2chainDb, l2arbDb, nodeConfig, l2blockchain, l1client, first.DeployInfo, &txOpts, dataSigner, feedErrChan) + configFetcher := func() *gethexec.Config { return execConfig } + currentExec, err := gethexec.CreateExecutionNode(l2stack, l2chainDb, l2blockchain, l1client, configFetcher) + Require(t, err) + + currentNode, err := arbnode.CreateNode(ctx, l2stack, currentExec, l2arbDb, nodeConfig, l2blockchain.Config(), l1client, first.DeployInfo, &txOpts, dataSigner, feedErrChan) Require(t, err) err = currentNode.Start(ctx) @@ -759,3 +795,12 @@ func deploySimple( Require(t, err) return addr, simple } + +func getExecNode(t *testing.T, node *arbnode.Node) *gethexec.ExecutionNode { + t.Helper() + gethExec, ok := node.Execution.(*gethexec.ExecutionNode) + if !ok { + t.Fatal("failed to get exec node from arbnode") + } + return gethExec +} diff --git a/system_tests/contract_tx_test.go b/system_tests/contract_tx_test.go index 9214884c26..084eada6eb 100644 --- a/system_tests/contract_tx_test.go +++ b/system_tests/contract_tx_test.go @@ -16,7 +16,6 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" - "github.com/offchainlabs/nitro/arbnode" "github.com/offchainlabs/nitro/arbos" "github.com/offchainlabs/nitro/arbos/arbostypes" "github.com/offchainlabs/nitro/util/arbmath" @@ -26,8 +25,7 @@ func TestContractTxDeploy(t *testing.T) { t.Parallel() ctx, cancel := context.WithCancel(context.Background()) defer cancel() - nodeconfig := arbnode.ConfigDefaultL2Test() - l2info, node, client := CreateTestL2WithConfig(t, ctx, nil, nodeconfig, false) + l2info, node, client := CreateTestL2WithConfig(t, ctx, nil, nil, nil, false) defer node.StopAndWait() from := common.HexToAddress("0x123412341234") diff --git a/system_tests/das_test.go b/system_tests/das_test.go index 8fadf316b0..430239fcc7 100644 --- a/system_tests/das_test.go +++ b/system_tests/das_test.go @@ -22,11 +22,11 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/offchainlabs/nitro/arbnode" - "github.com/offchainlabs/nitro/arbnode/execution" "github.com/offchainlabs/nitro/arbutil" "github.com/offchainlabs/nitro/blsSignatures" "github.com/offchainlabs/nitro/cmd/genericconf" "github.com/offchainlabs/nitro/das" + "github.com/offchainlabs/nitro/execution/gethexec" "github.com/offchainlabs/nitro/solgen/go/bridgegen" "github.com/offchainlabs/nitro/util/headerreader" "github.com/offchainlabs/nitro/util/signature" @@ -137,8 +137,10 @@ func TestDASRekey(t *testing.T) { l1NodeConfigA.DataAvailability.RestfulClientAggregatorConfig.Enable = true l1NodeConfigA.DataAvailability.RestfulClientAggregatorConfig.Urls = []string{restServerUrlA} l1NodeConfigA.DataAvailability.L1NodeURL = "none" + execA, err := gethexec.CreateExecutionNode(l2stackA, l2chainDb, l2blockchain, l1client, gethexec.ConfigDefaultTest) + Require(t, err) - nodeA, err := arbnode.CreateNode(ctx, l2stackA, l2chainDb, l2arbDb, l1NodeConfigA, l2blockchain, l1client, addresses, sequencerTxOptsPtr, nil, feedErrChan) + nodeA, err := arbnode.CreateNode(ctx, l2stackA, execA, l2arbDb, l1NodeConfigA, l2blockchain.Config(), l1client, addresses, sequencerTxOptsPtr, nil, feedErrChan) Require(t, err) Require(t, nodeA.Start(ctx)) l2clientA := ClientForStack(t, l2stackA) @@ -151,7 +153,7 @@ func TestDASRekey(t *testing.T) { l1NodeConfigB.DataAvailability.L1NodeURL = "none" - l2clientB, nodeB := Create2ndNodeWithConfig(t, ctx, nodeA, l1stack, l1info, &l2info.ArbInitData, l1NodeConfigB, nil) + l2clientB, nodeB := Create2ndNodeWithConfig(t, ctx, nodeA, l1stack, l1info, &l2info.ArbInitData, l1NodeConfigB, nil, nil) checkBatchPosting(t, ctx, l1client, l2clientA, l1info, l2info, big.NewInt(1e12), l2clientB) nodeA.StopAndWait() nodeB.StopAndWait() @@ -177,15 +179,19 @@ func TestDASRekey(t *testing.T) { l2arbDb, err := l2stackA.OpenDatabase("arbdb", 0, 0, "", false) Require(t, err) - l2blockchain, err := execution.GetBlockChain(l2chainDb, nil, chainConfig, arbnode.ConfigDefaultL2Test().TxLookupLimit) + l2blockchain, err := gethexec.GetBlockChain(l2chainDb, nil, chainConfig, gethexec.ConfigDefaultTest().TxLookupLimit) + Require(t, err) + + execA, err := gethexec.CreateExecutionNode(l2stackA, l2chainDb, l2blockchain, l1client, gethexec.ConfigDefaultTest) Require(t, err) + l1NodeConfigA.DataAvailability.AggregatorConfig = aggConfigForBackend(t, backendConfigB) - nodeA, err := arbnode.CreateNode(ctx, l2stackA, l2chainDb, l2arbDb, l1NodeConfigA, l2blockchain, l1client, addresses, sequencerTxOptsPtr, nil, feedErrChan) + nodeA, err := arbnode.CreateNode(ctx, l2stackA, execA, l2arbDb, l1NodeConfigA, l2blockchain.Config(), l1client, addresses, sequencerTxOptsPtr, nil, feedErrChan) Require(t, err) Require(t, nodeA.Start(ctx)) l2clientA := ClientForStack(t, l2stackA) - l2clientB, nodeB := Create2ndNodeWithConfig(t, ctx, nodeA, l1stack, l1info, &l2info.ArbInitData, l1NodeConfigB, nil) + l2clientB, nodeB := Create2ndNodeWithConfig(t, ctx, nodeA, l1stack, l1info, &l2info.ArbInitData, l1NodeConfigB, nil, nil) checkBatchPosting(t, ctx, l1client, l2clientA, l1info, l2info, big.NewInt(2e12), l2clientB) nodeA.StopAndWait() @@ -306,9 +312,12 @@ func TestDASComplexConfigAndRestMirror(t *testing.T) { l2info, l2stackA, l2chainDb, l2arbDb, l2blockchain := createL2BlockChain(t, nil, "", chainConfig) l2info.GenerateAccount("User2") + execA, err := gethexec.CreateExecutionNode(l2stackA, l2chainDb, l2blockchain, l1client, gethexec.ConfigDefaultTest) + Require(t, err) + sequencerTxOpts := l1info.GetDefaultTransactOpts("Sequencer", ctx) sequencerTxOptsPtr := &sequencerTxOpts - nodeA, err := arbnode.CreateNode(ctx, l2stackA, l2chainDb, l2arbDb, l1NodeConfigA, l2blockchain, l1client, addresses, sequencerTxOptsPtr, dataSigner, feedErrChan) + nodeA, err := arbnode.CreateNode(ctx, l2stackA, execA, l2arbDb, l1NodeConfigA, l2blockchain.Config(), l1client, addresses, sequencerTxOptsPtr, dataSigner, feedErrChan) Require(t, err) Require(t, nodeA.Start(ctx)) l2clientA := ClientForStack(t, l2stackA) @@ -330,7 +339,7 @@ func TestDASComplexConfigAndRestMirror(t *testing.T) { l1NodeConfigB.DataAvailability.RestfulClientAggregatorConfig.Enable = true l1NodeConfigB.DataAvailability.RestfulClientAggregatorConfig.Urls = []string{"http://" + restLis.Addr().String()} l1NodeConfigB.DataAvailability.L1NodeURL = "none" - l2clientB, nodeB := Create2ndNodeWithConfig(t, ctx, nodeA, l1stack, l1info, &l2info.ArbInitData, l1NodeConfigB, nil) + l2clientB, nodeB := Create2ndNodeWithConfig(t, ctx, nodeA, l1stack, l1info, &l2info.ArbInitData, l1NodeConfigB, nil, nil) checkBatchPosting(t, ctx, l1client, l2clientA, l1info, l2info, big.NewInt(1e12), l2clientB) diff --git a/system_tests/debugapi_test.go b/system_tests/debugapi_test.go index df954685d1..03e3dfd405 100644 --- a/system_tests/debugapi_test.go +++ b/system_tests/debugapi_test.go @@ -14,7 +14,7 @@ import ( func TestDebugAPI(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - _, _, _, l2stack, _, _, _, l1stack := createTestNodeOnL1WithConfigImpl(t, ctx, true, nil, nil, nil) + _, _, _, l2stack, _, _, _, l1stack := createTestNodeOnL1WithConfigImpl(t, ctx, true, nil, nil, nil, nil) defer requireClose(t, l1stack) defer requireClose(t, l2stack) diff --git a/system_tests/estimation_test.go b/system_tests/estimation_test.go index c80492326c..a1c411d7d5 100644 --- a/system_tests/estimation_test.go +++ b/system_tests/estimation_test.go @@ -185,8 +185,9 @@ func TestComponentEstimate(t *testing.T) { baseFee, _ := outputs[2].(*big.Int) l1BaseFeeEstimate, _ := outputs[3].(*big.Int) + execNode := getExecNode(t, node) tx := l2info.SignTxAs("User", &types.DynamicFeeTx{ - ChainID: node.Execution.ArbInterface.BlockChain().Config().ChainID, + ChainID: execNode.ArbInterface.BlockChain().Config().ChainID, Nonce: 0, GasTipCap: maxPriorityFeePerGas, GasFeeCap: maxFeePerGas, diff --git a/system_tests/fees_test.go b/system_tests/fees_test.go index 734ccc7529..3efe2bfdf3 100644 --- a/system_tests/fees_test.go +++ b/system_tests/fees_test.go @@ -37,7 +37,8 @@ func TestSequencerFeePaid(t *testing.T) { defer requireClose(t, l1stack) defer l2node.StopAndWait() - version := l2node.Execution.ArbInterface.BlockChain().Config().ArbitrumChainParams.InitialArbOSVersion + execNode := getExecNode(t, l2node) + version := execNode.ArbInterface.BlockChain().Config().ArbitrumChainParams.InitialArbOSVersion callOpts := l2info.GetDefaultCallOpts("Owner", ctx) // get the network fee account @@ -133,7 +134,7 @@ func testSequencerPriceAdjustsFrom(t *testing.T, initialEstimate uint64) { conf := arbnode.ConfigDefaultL1Test() conf.DelayedSequencer.FinalizeDistance = 1 - l2info, node, l2client, l1info, _, l1client, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, conf, chainConfig, nil) + l2info, node, l2client, l1info, _, l1client, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, conf, nil, chainConfig, nil) defer requireClose(t, l1stack) defer node.StopAndWait() diff --git a/system_tests/forwarder_test.go b/system_tests/forwarder_test.go index 5ec897604e..6595eefb61 100644 --- a/system_tests/forwarder_test.go +++ b/system_tests/forwarder_test.go @@ -17,8 +17,8 @@ import ( "github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/node" "github.com/offchainlabs/nitro/arbnode" - "github.com/offchainlabs/nitro/arbnode/execution" "github.com/offchainlabs/nitro/cmd/genericconf" + "github.com/offchainlabs/nitro/execution/gethexec" "github.com/offchainlabs/nitro/statetransfer" "github.com/offchainlabs/nitro/util/redisutil" "github.com/offchainlabs/nitro/util/testhelpers" @@ -35,18 +35,20 @@ func TestStaticForwarder(t *testing.T) { nodeConfigA := arbnode.ConfigDefaultL1Test() nodeConfigA.BatchPoster.Enable = false - l2info, nodeA, clientA, l1info, _, _, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, nodeConfigA, nil, stackConfig) + l2info, nodeA, clientA, l1info, _, _, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, nodeConfigA, nil, nil, stackConfig) defer requireClose(t, l1stack) defer nodeA.StopAndWait() nodeConfigB := arbnode.ConfigDefaultL1Test() - nodeConfigB.Sequencer.Enable = false + execConfigB := gethexec.ConfigDefaultTest() + execConfigB.Sequencer.Enable = false + nodeConfigB.Sequencer = false nodeConfigB.DelayedSequencer.Enable = false - nodeConfigB.Forwarder.RedisUrl = "" - nodeConfigB.ForwardingTargetImpl = ipcPath + execConfigB.Forwarder.RedisUrl = "" + execConfigB.ForwardingTargetImpl = ipcPath nodeConfigB.BatchPoster.Enable = false - clientB, nodeB := Create2ndNodeWithConfig(t, ctx, nodeA, l1stack, l1info, &l2info.ArbInitData, nodeConfigB, nil) + clientB, nodeB := Create2ndNodeWithConfig(t, ctx, nodeA, l1stack, l1info, &l2info.ArbInitData, nodeConfigB, execConfigB, nil) defer nodeB.StopAndWait() l2info.GenerateAccount("User2") @@ -93,7 +95,7 @@ func createFallbackSequencer( nodeConfig.SeqCoordinator.Enable = false nodeConfig.SeqCoordinator.RedisUrl = redisUrl nodeConfig.SeqCoordinator.MyUrlImpl = ipcPath - return createTestNodeOnL1WithConfig(t, ctx, true, nodeConfig, nil, stackConfig) + return createTestNodeOnL1WithConfig(t, ctx, true, nodeConfig, nil, nil, stackConfig) } func createForwardingNode( @@ -113,13 +115,15 @@ func createForwardingNode( ipcConfig.Apply(stackConfig) } nodeConfig := arbnode.ConfigDefaultL1Test() - nodeConfig.Sequencer.Enable = false + nodeConfig.Sequencer = false nodeConfig.DelayedSequencer.Enable = false - nodeConfig.Forwarder.RedisUrl = redisUrl - nodeConfig.ForwardingTargetImpl = fallbackPath + execConfig := gethexec.ConfigDefaultTest() + execConfig.Sequencer.Enable = false + execConfig.Forwarder.RedisUrl = redisUrl + execConfig.ForwardingTargetImpl = fallbackPath // nodeConfig.Feed.Output.Enable = false - return Create2ndNodeWithConfig(t, ctx, first, l1stack, l1info, l2InitData, nodeConfig, stackConfig) + return Create2ndNodeWithConfig(t, ctx, first, l1stack, l1info, l2InitData, nodeConfig, execConfig, stackConfig) } func createSequencer( @@ -141,7 +145,7 @@ func createSequencer( nodeConfig.SeqCoordinator.RedisUrl = redisUrl nodeConfig.SeqCoordinator.MyUrlImpl = ipcPath - return Create2ndNodeWithConfig(t, ctx, first, l1stack, l1info, l2InitData, nodeConfig, stackConfig) + return Create2ndNodeWithConfig(t, ctx, first, l1stack, l1info, l2InitData, nodeConfig, gethexec.ConfigDefaultTest(), stackConfig) } func TestRedisForwarder(t *testing.T) { @@ -210,7 +214,7 @@ func TestRedisForwarder(t *testing.T) { if err == nil { break } - time.Sleep(execution.DefaultTestForwarderConfig.UpdateInterval / 2) + time.Sleep(gethexec.DefaultTestForwarderConfig.UpdateInterval / 2) } testhelpers.RequireImpl(t, err) _, err = EnsureTxSucceeded(ctx, clients[i], tx) diff --git a/system_tests/full_challenge_impl_test.go b/system_tests/full_challenge_impl_test.go index 24795f6237..8b28832a3a 100644 --- a/system_tests/full_challenge_impl_test.go +++ b/system_tests/full_challenge_impl_test.go @@ -27,6 +27,7 @@ import ( "github.com/offchainlabs/nitro/arbos" "github.com/offchainlabs/nitro/arbstate" "github.com/offchainlabs/nitro/arbutil" + "github.com/offchainlabs/nitro/execution/gethexec" "github.com/offchainlabs/nitro/solgen/go/challengegen" "github.com/offchainlabs/nitro/solgen/go/mocksgen" "github.com/offchainlabs/nitro/solgen/go/ospgen" @@ -266,7 +267,9 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall asserterL2Info, asserterL2Stack, asserterL2ChainDb, asserterL2ArbDb, asserterL2Blockchain := createL2BlockChain(t, nil, "", chainConfig) asserterRollupAddresses.Bridge = asserterBridgeAddr asserterRollupAddresses.SequencerInbox = asserterSeqInboxAddr - asserterL2, err := arbnode.CreateNode(ctx, asserterL2Stack, asserterL2ChainDb, asserterL2ArbDb, conf, asserterL2Blockchain, l1Backend, asserterRollupAddresses, nil, nil, fatalErrChan) + asserterExec, err := gethexec.CreateExecutionNode(asserterL2Stack, asserterL2ChainDb, asserterL2Blockchain, l1Backend, gethexec.ConfigDefaultTest) + Require(t, err) + asserterL2, err := arbnode.CreateNode(ctx, asserterL2Stack, asserterExec, asserterL2ArbDb, conf, chainConfig, l1Backend, asserterRollupAddresses, nil, nil, fatalErrChan) Require(t, err) err = asserterL2.Start(ctx) Require(t, err) @@ -275,7 +278,9 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall challengerRollupAddresses := *asserterRollupAddresses challengerRollupAddresses.Bridge = challengerBridgeAddr challengerRollupAddresses.SequencerInbox = challengerSeqInboxAddr - challengerL2, err := arbnode.CreateNode(ctx, challengerL2Stack, challengerL2ChainDb, challengerL2ArbDb, conf, challengerL2Blockchain, l1Backend, &challengerRollupAddresses, nil, nil, fatalErrChan) + challengerExec, err := gethexec.CreateExecutionNode(challengerL2Stack, challengerL2ChainDb, challengerL2Blockchain, l1Backend, gethexec.ConfigDefaultTest) + Require(t, err) + challengerL2, err := arbnode.CreateNode(ctx, challengerL2Stack, challengerExec, challengerL2ArbDb, conf, chainConfig, l1Backend, &challengerRollupAddresses, nil, nil, fatalErrChan) Require(t, err) err = challengerL2.Start(ctx) Require(t, err) @@ -323,13 +328,13 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall } } - asserterGenesis := asserterL2.Execution.ArbInterface.BlockChain().Genesis() - challengerGenesis := challengerL2.Execution.ArbInterface.BlockChain().Genesis() + asserterGenesis := asserterExec.ArbInterface.BlockChain().Genesis() + challengerGenesis := challengerExec.ArbInterface.BlockChain().Genesis() if asserterGenesis.Hash() != challengerGenesis.Hash() { Fail(t, "asserter and challenger have different genesis hashes") } - asserterLatestBlock := asserterL2.Execution.ArbInterface.BlockChain().CurrentBlock() - challengerLatestBlock := challengerL2.Execution.ArbInterface.BlockChain().CurrentBlock() + asserterLatestBlock := asserterExec.ArbInterface.BlockChain().CurrentBlock() + challengerLatestBlock := challengerExec.ArbInterface.BlockChain().CurrentBlock() if asserterLatestBlock.Hash() == challengerLatestBlock.Hash() { Fail(t, "asserter and challenger have the same end block") } @@ -364,7 +369,7 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall confirmLatestBlock(ctx, t, l1Info, l1Backend) - asserterValidator, err := staker.NewStatelessBlockValidator(asserterL2.InboxReader, asserterL2.InboxTracker, asserterL2.TxStreamer, asserterL2.Execution.Recorder, asserterL2ArbDb, nil, &conf.BlockValidator) + asserterValidator, err := staker.NewStatelessBlockValidator(asserterL2.InboxReader, asserterL2.InboxTracker, asserterL2.TxStreamer, asserterExec.Recorder, asserterL2ArbDb, nil, &conf.BlockValidator) if err != nil { Fail(t, err) } @@ -381,7 +386,7 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall if err != nil { Fail(t, err) } - challengerValidator, err := staker.NewStatelessBlockValidator(challengerL2.InboxReader, challengerL2.InboxTracker, challengerL2.TxStreamer, challengerL2.Execution.Recorder, challengerL2ArbDb, nil, &conf.BlockValidator) + challengerValidator, err := staker.NewStatelessBlockValidator(challengerL2.InboxReader, challengerL2.InboxTracker, challengerL2.TxStreamer, challengerExec.Recorder, challengerL2ArbDb, nil, &conf.BlockValidator) if err != nil { Fail(t, err) } diff --git a/system_tests/infra_fee_test.go b/system_tests/infra_fee_test.go index fd10badd4e..488c085fcb 100644 --- a/system_tests/infra_fee_test.go +++ b/system_tests/infra_fee_test.go @@ -13,7 +13,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" - "github.com/offchainlabs/nitro/arbnode" "github.com/offchainlabs/nitro/arbos/l2pricing" "github.com/offchainlabs/nitro/solgen/go/precompilesgen" "github.com/offchainlabs/nitro/util/arbmath" @@ -23,9 +22,8 @@ func TestInfraFee(t *testing.T) { t.Parallel() ctx, cancel := context.WithCancel(context.Background()) defer cancel() - nodeconfig := arbnode.ConfigDefaultL2Test() - l2info, node, client := CreateTestL2WithConfig(t, ctx, nil, nodeconfig, true) + l2info, node, client := CreateTestL2WithConfig(t, ctx, nil, nil, nil, true) defer node.StopAndWait() l2info.GenerateAccount("User2") diff --git a/system_tests/initialization_test.go b/system_tests/initialization_test.go index c7797d35e6..0e055adc5f 100644 --- a/system_tests/initialization_test.go +++ b/system_tests/initialization_test.go @@ -11,7 +11,6 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/params" - "github.com/offchainlabs/nitro/arbnode" "github.com/offchainlabs/nitro/statetransfer" "github.com/offchainlabs/nitro/util/testhelpers" ) @@ -63,7 +62,7 @@ func TestInitContract(t *testing.T) { l2info.ArbInitData.Accounts = append(l2info.ArbInitData.Accounts, accountInfo) expectedSums[accountAddress] = sum } - _, node, client := CreateTestL2WithConfig(t, ctx, l2info, arbnode.ConfigDefaultL2Test(), true) + _, node, client := CreateTestL2WithConfig(t, ctx, l2info, nil, nil, true) defer node.StopAndWait() for accountAddress, sum := range expectedSums { diff --git a/system_tests/ipc_test.go b/system_tests/ipc_test.go index ad5a8fbc64..4fb6473faf 100644 --- a/system_tests/ipc_test.go +++ b/system_tests/ipc_test.go @@ -24,7 +24,7 @@ func TestIpcRpc(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - _, l2node, _, _, _, _, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, nil, nil, stackConf) + _, l2node, _, _, _, _, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, nil, nil, nil, stackConf) defer requireClose(t, l1stack) defer l2node.StopAndWait() diff --git a/system_tests/meaningless_reorg_test.go b/system_tests/meaningless_reorg_test.go index f9e9f6e57f..6d4a98614f 100644 --- a/system_tests/meaningless_reorg_test.go +++ b/system_tests/meaningless_reorg_test.go @@ -20,7 +20,7 @@ func TestMeaninglessBatchReorg(t *testing.T) { defer cancel() conf := arbnode.ConfigDefaultL1Test() conf.BatchPoster.Enable = false - l2Info, arbNode, l2Client, l1Info, l1Backend, l1Client, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, conf, nil, nil) + l2Info, arbNode, l2Client, l1Info, l1Backend, l1Client, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, conf, nil, nil, nil) defer requireClose(t, l1stack) defer arbNode.StopAndWait() @@ -33,11 +33,12 @@ func TestMeaninglessBatchReorg(t *testing.T) { batchReceipt, err := EnsureTxSucceeded(ctx, l1Client, tx) Require(t, err) + execNode := getExecNode(t, arbNode) for i := 0; ; i++ { if i >= 500 { Fail(t, "Failed to read batch from L1") } - msgNum, err := arbNode.Execution.ExecEngine.HeadMessageNumber() + msgNum, err := execNode.ExecEngine.HeadMessageNumber() Require(t, err) if msgNum == 1 { break diff --git a/system_tests/reorg_resequencing_test.go b/system_tests/reorg_resequencing_test.go index c56f919403..05ca0a25c0 100644 --- a/system_tests/reorg_resequencing_test.go +++ b/system_tests/reorg_resequencing_test.go @@ -22,6 +22,8 @@ func TestReorgResequencing(t *testing.T) { l2info, node, client := CreateTestL2(t, ctx) defer node.StopAndWait() + execNode := getExecNode(t, node) + startMsgCount, err := node.TxStreamer.GetMessageCount() Require(t, err) @@ -51,7 +53,7 @@ func TestReorgResequencing(t *testing.T) { err = node.TxStreamer.ReorgTo(startMsgCount) Require(t, err) - _, err = node.Execution.ExecEngine.HeadMessageNumberSync(t) + _, err = execNode.ExecEngine.HeadMessageNumberSync(t) Require(t, err) verifyBalances("after empty reorg") @@ -76,7 +78,7 @@ func TestReorgResequencing(t *testing.T) { }}) Require(t, err) - _, err = node.Execution.ExecEngine.HeadMessageNumberSync(t) + _, err = execNode.ExecEngine.HeadMessageNumberSync(t) Require(t, err) accountsWithBalance = append(accountsWithBalance, "User4") @@ -85,7 +87,7 @@ func TestReorgResequencing(t *testing.T) { err = node.TxStreamer.ReorgTo(startMsgCount) Require(t, err) - _, err = node.Execution.ExecEngine.HeadMessageNumberSync(t) + _, err = execNode.ExecEngine.HeadMessageNumberSync(t) Require(t, err) verifyBalances("after second empty reorg") diff --git a/system_tests/seq_coordinator_test.go b/system_tests/seq_coordinator_test.go index 51a61aec0c..f395826f31 100644 --- a/system_tests/seq_coordinator_test.go +++ b/system_tests/seq_coordinator_test.go @@ -20,9 +20,9 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/offchainlabs/nitro/arbnode" - "github.com/offchainlabs/nitro/arbnode/execution" "github.com/offchainlabs/nitro/arbos/arbostypes" "github.com/offchainlabs/nitro/arbutil" + "github.com/offchainlabs/nitro/execution" "github.com/offchainlabs/nitro/util/redisutil" ) diff --git a/system_tests/seq_nonce_test.go b/system_tests/seq_nonce_test.go index 80de4cfa0a..ec4d4365a2 100644 --- a/system_tests/seq_nonce_test.go +++ b/system_tests/seq_nonce_test.go @@ -15,7 +15,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" - "github.com/offchainlabs/nitro/arbnode" + "github.com/offchainlabs/nitro/execution/gethexec" "github.com/offchainlabs/nitro/util/arbmath" ) @@ -24,9 +24,9 @@ func TestSequencerParallelNonces(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - config := arbnode.ConfigDefaultL2Test() + config := gethexec.ConfigDefaultTest() config.Sequencer.NonceFailureCacheExpiry = time.Minute - l2info, node, client := CreateTestL2WithConfig(t, ctx, nil, config, false) + l2info, node, client := CreateTestL2WithConfig(t, ctx, nil, nil, config, false) defer node.StopAndWait() l2info.GenerateAccount("Destination") @@ -62,8 +62,8 @@ func TestSequencerNonceTooHigh(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - config := arbnode.ConfigDefaultL2Test() - l2info, node, client := CreateTestL2WithConfig(t, ctx, nil, config, false) + config := gethexec.ConfigDefaultTest() + l2info, node, client := CreateTestL2WithConfig(t, ctx, nil, nil, config, false) defer node.StopAndWait() l2info.GetInfoWithPrivKey("Owner").Nonce++ @@ -88,10 +88,10 @@ func TestSequencerNonceTooHighQueueFull(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - config := arbnode.ConfigDefaultL2Test() + config := gethexec.ConfigDefaultTest() config.Sequencer.NonceFailureCacheSize = 5 config.Sequencer.NonceFailureCacheExpiry = time.Minute - l2info, node, client := CreateTestL2WithConfig(t, ctx, nil, config, false) + l2info, node, client := CreateTestL2WithConfig(t, ctx, nil, nil, config, false) defer node.StopAndWait() count := 15 diff --git a/system_tests/seq_pause_test.go b/system_tests/seq_pause_test.go index 4b2c907d70..8ce76846ab 100644 --- a/system_tests/seq_pause_test.go +++ b/system_tests/seq_pause_test.go @@ -8,7 +8,7 @@ import ( "time" "github.com/ethereum/go-ethereum/core/types" - "github.com/offchainlabs/nitro/arbnode/execution" + "github.com/offchainlabs/nitro/execution/gethexec" ) func TestSequencerPause(t *testing.T) { @@ -21,11 +21,12 @@ func TestSequencerPause(t *testing.T) { const numUsers = 100 - prechecker, ok := nodeA.Execution.TxPublisher.(*execution.TxPreChecker) + execA := getExecNode(t, nodeA) + prechecker, ok := execA.TxPublisher.(*gethexec.TxPreChecker) if !ok { t.Error("prechecker not found on node") } - sequencer, ok := prechecker.TransactionPublisher.(*execution.Sequencer) + sequencer, ok := prechecker.TransactionPublisher.(*gethexec.Sequencer) if !ok { t.Error("sequencer not found on node") } diff --git a/system_tests/seq_reject_test.go b/system_tests/seq_reject_test.go index 1e26c0182d..5fbbda8d52 100644 --- a/system_tests/seq_reject_test.go +++ b/system_tests/seq_reject_test.go @@ -31,14 +31,14 @@ func TestSequencerRejection(t *testing.T) { seqNodeConfig := arbnode.ConfigDefaultL2Test() seqNodeConfig.Feed.Output = *newBroadcasterConfigTest() feedErrChan := make(chan error, 10) - l2info1, nodeA, client1 := CreateTestL2WithConfig(t, ctx, nil, seqNodeConfig, true) + l2info1, nodeA, client1 := CreateTestL2WithConfig(t, ctx, nil, seqNodeConfig, nil, true) defer nodeA.StopAndWait() clientNodeConfig := arbnode.ConfigDefaultL2Test() port := nodeA.BroadcastServer.ListenerAddr().(*net.TCPAddr).Port clientNodeConfig.Feed.Input = *newBroadcastClientConfigTest(port) - _, nodeB, client2 := CreateTestL2WithConfig(t, ctx, nil, clientNodeConfig, false) + _, nodeB, client2 := CreateTestL2WithConfig(t, ctx, nil, clientNodeConfig, nil, false) defer nodeB.StopAndWait() auth := l2info1.GetDefaultTransactOpts("Owner", ctx) diff --git a/system_tests/seq_whitelist_test.go b/system_tests/seq_whitelist_test.go index f24ce79c9b..936745176e 100644 --- a/system_tests/seq_whitelist_test.go +++ b/system_tests/seq_whitelist_test.go @@ -9,16 +9,16 @@ import ( "testing" "github.com/ethereum/go-ethereum/params" - "github.com/offchainlabs/nitro/arbnode" + "github.com/offchainlabs/nitro/execution/gethexec" ) func TestSequencerWhitelist(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - config := arbnode.ConfigDefaultL2Test() + config := gethexec.ConfigDefaultTest() config.Sequencer.SenderWhitelist = GetTestAddressForAccountName(t, "Owner").String() + "," + GetTestAddressForAccountName(t, "User").String() - l2info, l2node, client := CreateTestL2WithConfig(t, ctx, nil, config, true) + l2info, l2node, client := CreateTestL2WithConfig(t, ctx, nil, nil, config, true) defer l2node.StopAndWait() l2info.GenerateAccount("User") diff --git a/system_tests/seqfeed_test.go b/system_tests/seqfeed_test.go index 0ae72e384f..83a8fc0642 100644 --- a/system_tests/seqfeed_test.go +++ b/system_tests/seqfeed_test.go @@ -13,6 +13,7 @@ import ( "github.com/offchainlabs/nitro/arbnode" "github.com/offchainlabs/nitro/broadcastclient" + "github.com/offchainlabs/nitro/execution/gethexec" "github.com/offchainlabs/nitro/relay" "github.com/offchainlabs/nitro/util/signature" "github.com/offchainlabs/nitro/wsbroadcastserver" @@ -44,13 +45,13 @@ func TestSequencerFeed(t *testing.T) { seqNodeConfig := arbnode.ConfigDefaultL2Test() seqNodeConfig.Feed.Output = *newBroadcasterConfigTest() - l2info1, nodeA, client1 := CreateTestL2WithConfig(t, ctx, nil, seqNodeConfig, true) + l2info1, nodeA, client1 := CreateTestL2WithConfig(t, ctx, nil, seqNodeConfig, nil, true) defer nodeA.StopAndWait() clientNodeConfig := arbnode.ConfigDefaultL2Test() port := nodeA.BroadcastServer.ListenerAddr().(*net.TCPAddr).Port clientNodeConfig.Feed.Input = *newBroadcastClientConfigTest(port) - _, nodeB, client2 := CreateTestL2WithConfig(t, ctx, nil, clientNodeConfig, false) + _, nodeB, client2 := CreateTestL2WithConfig(t, ctx, nil, clientNodeConfig, nil, false) defer nodeB.StopAndWait() l2info1.GenerateAccount("User2") @@ -79,7 +80,7 @@ func TestRelayedSequencerFeed(t *testing.T) { seqNodeConfig := arbnode.ConfigDefaultL2Test() seqNodeConfig.Feed.Output = *newBroadcasterConfigTest() - l2info1, nodeA, client1 := CreateTestL2WithConfig(t, ctx, nil, seqNodeConfig, true) + l2info1, nodeA, client1 := CreateTestL2WithConfig(t, ctx, nil, seqNodeConfig, nil, true) defer nodeA.StopAndWait() bigChainId, err := client1.ChainID(ctx) @@ -101,7 +102,7 @@ func TestRelayedSequencerFeed(t *testing.T) { clientNodeConfig := arbnode.ConfigDefaultL2Test() port = currentRelay.GetListenerAddr().(*net.TCPAddr).Port clientNodeConfig.Feed.Input = *newBroadcastClientConfigTest(port) - _, nodeC, client3 := CreateTestL2WithConfig(t, ctx, nil, clientNodeConfig, false) + _, nodeC, client3 := CreateTestL2WithConfig(t, ctx, nil, clientNodeConfig, nil, false) defer nodeC.StopAndWait() StartWatchChanErr(t, ctx, feedErrChan, nodeC) @@ -135,7 +136,7 @@ func testLyingSequencer(t *testing.T, dasModeStr string) { nodeConfigA.BatchPoster.Enable = true nodeConfigA.Feed.Output.Enable = false - l2infoA, nodeA, l2clientA, l1info, _, l1client, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, nodeConfigA, chainConfig, nil) + l2infoA, nodeA, l2clientA, l1info, _, l1client, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, nodeConfigA, nil, chainConfig, nil) defer requireClose(t, l1stack, "unable to close l1stack") defer nodeA.StopAndWait() @@ -147,7 +148,7 @@ func testLyingSequencer(t *testing.T, dasModeStr string) { nodeConfigC.DataAvailability = nodeConfigA.DataAvailability nodeConfigC.DataAvailability.AggregatorConfig.Enable = false nodeConfigC.Feed.Output = *newBroadcasterConfigTest() - l2clientC, nodeC := Create2ndNodeWithConfig(t, ctx, nodeA, l1stack, l1info, &l2infoA.ArbInitData, nodeConfigC, nil) + l2clientC, nodeC := Create2ndNodeWithConfig(t, ctx, nodeA, l1stack, l1info, &l2infoA.ArbInitData, nodeConfigC, gethexec.ConfigDefaultTest(), nil) defer nodeC.StopAndWait() port := nodeC.BroadcastServer.ListenerAddr().(*net.TCPAddr).Port @@ -158,7 +159,7 @@ func testLyingSequencer(t *testing.T, dasModeStr string) { nodeConfigB.Feed.Input = *newBroadcastClientConfigTest(port) nodeConfigB.DataAvailability = nodeConfigA.DataAvailability nodeConfigB.DataAvailability.AggregatorConfig.Enable = false - l2clientB, nodeB := Create2ndNodeWithConfig(t, ctx, nodeA, l1stack, l1info, &l2infoA.ArbInitData, nodeConfigB, nil) + l2clientB, nodeB := Create2ndNodeWithConfig(t, ctx, nodeA, l1stack, l1info, &l2infoA.ArbInitData, nodeConfigB, nil, nil) defer nodeB.StopAndWait() l2infoA.GenerateAccount("FraudUser") @@ -168,12 +169,18 @@ func testLyingSequencer(t *testing.T, dasModeStr string) { l2infoA.GetInfoWithPrivKey("Owner").Nonce -= 1 // Use same l2info object for different l2s realTx := l2infoA.PrepareTx("Owner", "RealUser", l2infoA.TransferGas, big.NewInt(1e12), nil) - err := l2clientC.SendTransaction(ctx, fraudTx) - if err != nil { - t.Fatal("error sending fraud transaction:", err) + for i := 0; i < 10; i++ { + err := l2clientC.SendTransaction(ctx, fraudTx) + if err == nil { + break + } + <-time.After(time.Millisecond * 10) + if i == 9 { + t.Fatal("error sending fraud transaction:", err) + } } - _, err = EnsureTxSucceeded(ctx, l2clientC, fraudTx) + _, err := EnsureTxSucceeded(ctx, l2clientC, fraudTx) if err != nil { t.Fatal("error ensuring fraud transaction succeeded:", err) } diff --git a/system_tests/seqinbox_test.go b/system_tests/seqinbox_test.go index 30b51fcc2c..36364ea767 100644 --- a/system_tests/seqinbox_test.go +++ b/system_tests/seqinbox_test.go @@ -47,8 +47,9 @@ func testSequencerInboxReaderImpl(t *testing.T, validator bool) { if validator { conf.BlockValidator.Enable = true } - l2Info, arbNode, _, l1Info, l1backend, l1Client, l1stack := createTestNodeOnL1WithConfig(t, ctx, false, conf, nil, nil) - l2Backend := arbNode.Execution.Backend + l2Info, arbNode, _, l1Info, l1backend, l1Client, l1stack := createTestNodeOnL1WithConfig(t, ctx, false, conf, nil, nil, nil) + execNode := getExecNode(t, arbNode) + l2Backend := execNode.Backend defer requireClose(t, l1stack) defer arbNode.StopAndWait() @@ -268,7 +269,7 @@ func testSequencerInboxReaderImpl(t *testing.T, validator bool) { if validator && i%15 == 0 { for i := 0; ; i++ { - expectedPos, err := arbNode.Execution.ExecEngine.BlockNumberToMessageIndex(expectedBlockNumber) + expectedPos, err := execNode.ExecEngine.BlockNumberToMessageIndex(expectedBlockNumber) Require(t, err) lastValidated := arbNode.BlockValidator.Validated(t) if lastValidated == expectedPos+1 { diff --git a/system_tests/staker_test.go b/system_tests/staker_test.go index 3aee6074b5..39b6169ad5 100644 --- a/system_tests/staker_test.go +++ b/system_tests/staker_test.go @@ -23,6 +23,7 @@ import ( "github.com/offchainlabs/nitro/arbnode" "github.com/offchainlabs/nitro/arbutil" + "github.com/offchainlabs/nitro/execution/gethexec" "github.com/offchainlabs/nitro/solgen/go/rollupgen" "github.com/offchainlabs/nitro/staker" "github.com/offchainlabs/nitro/util/colors" @@ -65,15 +66,17 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) l2info, l2nodeA, l2clientA, l1info, _, l1client, l1stack := createTestNodeOnL1(t, ctx, true) defer requireClose(t, l1stack) defer l2nodeA.StopAndWait() + execNodeA := getExecNode(t, l2nodeA) if faultyStaker { l2info.GenerateGenesisAccount("FaultyAddr", common.Big1) } - l2clientB, l2nodeB := Create2ndNodeWithConfig(t, ctx, l2nodeA, l1stack, l1info, &l2info.ArbInitData, arbnode.ConfigDefaultL1Test(), nil) + l2clientB, l2nodeB := Create2ndNodeWithConfig(t, ctx, l2nodeA, l1stack, l1info, &l2info.ArbInitData, arbnode.ConfigDefaultL1Test(), gethexec.ConfigDefaultTest(), nil) defer l2nodeB.StopAndWait() + execNodeB := getExecNode(t, l2nodeB) - nodeAGenesis := l2nodeA.Execution.Backend.APIBackend().CurrentHeader().Hash() - nodeBGenesis := l2nodeB.Execution.Backend.APIBackend().CurrentHeader().Hash() + nodeAGenesis := execNodeA.Backend.APIBackend().CurrentHeader().Hash() + nodeBGenesis := execNodeB.Backend.APIBackend().CurrentHeader().Hash() if faultyStaker { if nodeAGenesis == nodeBGenesis { Fail(t, "node A L2 genesis hash", nodeAGenesis, "== node B L2 genesis hash", nodeBGenesis) @@ -135,7 +138,7 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) l2nodeA.InboxReader, l2nodeA.InboxTracker, l2nodeA.TxStreamer, - l2nodeA.Execution.Recorder, + execNodeA, l2nodeA.ArbDB, nil, &blockValidatorConfig, @@ -161,7 +164,7 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) l2nodeB.InboxReader, l2nodeB.InboxTracker, l2nodeB.TxStreamer, - l2nodeB.Execution.Recorder, + execNodeB, l2nodeB.ArbDB, nil, &blockValidatorConfig, diff --git a/system_tests/twonodes_test.go b/system_tests/twonodes_test.go index 6fef8ce484..af6ac426bd 100644 --- a/system_tests/twonodes_test.go +++ b/system_tests/twonodes_test.go @@ -20,7 +20,7 @@ func testTwoNodesSimple(t *testing.T, dasModeStr string) { chainConfig, l1NodeConfigA, lifecycleManager, _, dasSignerKey := setupConfigWithDAS(t, ctx, dasModeStr) defer lifecycleManager.StopAndWaitUntil(time.Second) - l2info, nodeA, l2clientA, l1info, _, l1client, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, l1NodeConfigA, chainConfig, nil) + l2info, nodeA, l2clientA, l1info, _, l1client, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, l1NodeConfigA, nil, chainConfig, nil) defer requireClose(t, l1stack) defer nodeA.StopAndWait() diff --git a/system_tests/twonodeslong_test.go b/system_tests/twonodeslong_test.go index 0c11c1fcb5..2c31603085 100644 --- a/system_tests/twonodeslong_test.go +++ b/system_tests/twonodeslong_test.go @@ -42,7 +42,7 @@ func testTwoNodesLong(t *testing.T, dasModeStr string) { chainConfig, l1NodeConfigA, lifecycleManager, _, dasSignerKey := setupConfigWithDAS(t, ctx, dasModeStr) defer lifecycleManager.StopAndWaitUntil(time.Second) - l2info, nodeA, l2client, l1info, l1backend, l1client, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, l1NodeConfigA, chainConfig, nil) + l2info, nodeA, l2client, l1info, l1backend, l1client, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, l1NodeConfigA, nil, chainConfig, nil) defer requireClose(t, l1stack) authorizeDASKeyset(t, ctx, dasSignerKey, l1info, l1client) diff --git a/system_tests/validation_mock_test.go b/system_tests/validation_mock_test.go index 98db34c0eb..f6023c5e4e 100644 --- a/system_tests/validation_mock_test.go +++ b/system_tests/validation_mock_test.go @@ -12,9 +12,9 @@ import ( "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/rpc" "github.com/offchainlabs/nitro/arbnode" - "github.com/offchainlabs/nitro/arbnode/execution" "github.com/offchainlabs/nitro/arbos/arbostypes" "github.com/offchainlabs/nitro/arbutil" + "github.com/offchainlabs/nitro/execution" "github.com/offchainlabs/nitro/staker" "github.com/offchainlabs/nitro/util/containers" "github.com/offchainlabs/nitro/validator" diff --git a/testnode-scripts/config.ts b/testnode-scripts/config.ts index 2724401ba8..4b94d5f632 100644 --- a/testnode-scripts/config.ts +++ b/testnode-scripts/config.ts @@ -180,9 +180,7 @@ function writeConfigs(argv: any) { "strategy": "MakeNodes", "target-machine-count": 4, }, - "sequencer": { - "enable": false - }, + "sequencer": false, "delayed-sequencer": { "enable": false }, @@ -207,6 +205,11 @@ function writeConfigs(argv: any) { } } }, + "execution" : { + "sequencer": { + "enable": false + }, + }, "init": { "dev-init": "true" }, @@ -238,7 +241,8 @@ function writeConfigs(argv: any) { fs.writeFileSync(path.join(consts.configpath, "unsafe_staker_config.json"), JSON.stringify(unsafeStakerConfig)) let sequencerConfig = JSON.parse(baseConfJSON) - sequencerConfig.node.sequencer.enable = true + sequencerConfig.execution.sequencer.enable = true + sequencerConfig.node.sequencer = true sequencerConfig.node["seq-coordinator"].enable = true sequencerConfig.node["delayed-sequencer"].enable = true fs.writeFileSync(path.join(consts.configpath, "sequencer_config.json"), JSON.stringify(sequencerConfig)) From f7c611fea6495633e36a6370b4e8d9e8c8b30133 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Wed, 15 Mar 2023 18:49:47 +0200 Subject: [PATCH 09/23] update geth --- go-ethereum | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go-ethereum b/go-ethereum index dcb407568c..ce5c501564 160000 --- a/go-ethereum +++ b/go-ethereum @@ -1 +1 @@ -Subproject commit dcb407568c3641278ce496c2576205719acf19c9 +Subproject commit ce5c50156406f408cc6fc80575c99db1d4d9b2f0 From a7984e2106734f754b5c114f9be7a5fc1d1eba4a Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Sat, 25 Mar 2023 09:05:02 -0600 Subject: [PATCH 10/23] gethexec: dont break if sequencer is nil --- execution/gethexec/node.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/execution/gethexec/node.go b/execution/gethexec/node.go index 8114f9c623..2791afb273 100644 --- a/execution/gethexec/node.go +++ b/execution/gethexec/node.go @@ -318,13 +318,21 @@ func (n *ExecutionNode) PrepareForRecord(ctx context.Context, start, end arbutil } func (n *ExecutionNode) Pause() { - n.Sequencer.Pause() + if n.Sequencer != nil { + n.Sequencer.Pause() + } } func (n *ExecutionNode) Activate() { - n.Sequencer.Activate() + if n.Sequencer != nil { + n.Sequencer.Activate() + } } func (n *ExecutionNode) ForwardTo(url string) error { - return n.Sequencer.ForwardTo(url) + if n.Sequencer != nil { + return n.Sequencer.ForwardTo(url) + } else { + return errors.New("forwardTo not supported - sequencer not acrtive") + } } func (n *ExecutionNode) SetTransactionStreamer(streamer execution.TransactionStreamer) { n.ExecEngine.SetTransactionStreamer(streamer) From b2e298f57813480459e8d9ac6eb7cda3b1ce3c8d Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Sat, 25 Mar 2023 09:05:22 -0600 Subject: [PATCH 11/23] fix redis tests compilation --- system_tests/seq_coordinator_test.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/system_tests/seq_coordinator_test.go b/system_tests/seq_coordinator_test.go index f395826f31..0167ed1aa1 100644 --- a/system_tests/seq_coordinator_test.go +++ b/system_tests/seq_coordinator_test.go @@ -23,6 +23,7 @@ import ( "github.com/offchainlabs/nitro/arbos/arbostypes" "github.com/offchainlabs/nitro/arbutil" "github.com/offchainlabs/nitro/execution" + "github.com/offchainlabs/nitro/execution/gethexec" "github.com/offchainlabs/nitro/util/redisutil" ) @@ -65,7 +66,7 @@ func TestRedisSeqCoordinatorPriorities(t *testing.T) { createStartNode := func(nodeNum int) { nodeConfig.SeqCoordinator.MyUrlImpl = nodeNames[nodeNum] - _, node, _ := CreateTestL2WithConfig(t, ctx, l2Info, nodeConfig, false) + _, node, _ := CreateTestL2WithConfig(t, ctx, l2Info, nodeConfig, nil, false) nodes[nodeNum] = node } @@ -149,7 +150,8 @@ func TestRedisSeqCoordinatorPriorities(t *testing.T) { } nodeForwardTarget := func(nodeNum int) int { - fwTarget := nodes[nodeNum].Execution.TxPublisher.(*execution.TxPreChecker).TransactionPublisher.(*execution.Sequencer).ForwardTarget() + execNode := getExecNode(t, nodes[nodeNum]) + fwTarget := execNode.TxPublisher.(*gethexec.TxPreChecker).TransactionPublisher.(*gethexec.Sequencer).ForwardTarget() if fwTarget == "" { return -1 } @@ -283,7 +285,7 @@ func testCoordinatorMessageSync(t *testing.T, successCase bool) { initRedisForTest(t, ctx, nodeConfig.SeqCoordinator.RedisUrl, nodeNames) nodeConfig.SeqCoordinator.MyUrlImpl = nodeNames[0] - l2Info, nodeA, clientA, l1info, _, _, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, nodeConfig, params.ArbitrumDevTestChainConfig(), nil) + l2Info, nodeA, clientA, l1info, _, _, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, nodeConfig, nil, params.ArbitrumDevTestChainConfig(), nil) defer requireClose(t, l1stack) defer nodeA.StopAndWait() @@ -312,7 +314,7 @@ func testCoordinatorMessageSync(t *testing.T, successCase bool) { nodeConfig.SeqCoordinator.Signing.ECDSA.AcceptSequencer = false nodeConfig.SeqCoordinator.Signing.ECDSA.AllowedAddresses = []string{l2Info.GetAddress("User2").Hex()} } - clientB, nodeB := Create2ndNodeWithConfig(t, ctx, nodeA, l1stack, l1info, &l2Info.ArbInitData, nodeConfig, nil) + clientB, nodeB := Create2ndNodeWithConfig(t, ctx, nodeA, l1stack, l1info, &l2Info.ArbInitData, nodeConfig, nil, nil) defer nodeB.StopAndWait() tx := l2Info.PrepareTx("Owner", "User2", l2Info.TransferGas, big.NewInt(1e12), nil) From 92296a058aae931fd71da8c1e7aef21c7a815ccb Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Wed, 29 Mar 2023 17:12:29 -0600 Subject: [PATCH 12/23] delayed_seq uses ExecutionSequencer --- arbnode/delayed_sequencer.go | 4 ++-- execution/interface.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arbnode/delayed_sequencer.go b/arbnode/delayed_sequencer.go index 9a0cb29153..092b7d12d0 100644 --- a/arbnode/delayed_sequencer.go +++ b/arbnode/delayed_sequencer.go @@ -26,7 +26,7 @@ type DelayedSequencer struct { l1Reader *headerreader.HeaderReader bridge *DelayedBridge inbox *InboxTracker - exec execution.ExecutionClient + exec execution.ExecutionSequencer coordinator *SeqCoordinator waitingForFinalizedBlock uint64 mutex sync.Mutex @@ -63,7 +63,7 @@ var TestDelayedSequencerConfig = DelayedSequencerConfig{ UseMergeFinality: true, } -func NewDelayedSequencer(l1Reader *headerreader.HeaderReader, reader *InboxReader, exec execution.ExecutionClient, coordinator *SeqCoordinator, config DelayedSequencerConfigFetcher) (*DelayedSequencer, error) { +func NewDelayedSequencer(l1Reader *headerreader.HeaderReader, reader *InboxReader, exec execution.ExecutionSequencer, coordinator *SeqCoordinator, config DelayedSequencerConfigFetcher) (*DelayedSequencer, error) { d := &DelayedSequencer{ l1Reader: l1Reader, bridge: reader.DelayedBridge(), diff --git a/execution/interface.go b/execution/interface.go index dc1551d8cf..e6895bc149 100644 --- a/execution/interface.go +++ b/execution/interface.go @@ -32,8 +32,6 @@ type ExecutionClient interface { Reorg(count arbutil.MessageIndex, newMessages []arbostypes.MessageWithMetadata, oldMessages []*arbostypes.MessageWithMetadata) error HeadMessageNumber() (arbutil.MessageIndex, error) HeadMessageNumberSync(t *testing.T) (arbutil.MessageIndex, error) - NextDelayedMessageNumber() (uint64, error) - SequenceDelayedMessage(message *arbostypes.L1IncomingMessage, delayedSeqNum uint64) error ResultAtPos(pos arbutil.MessageIndex) (*MessageResult, error) } @@ -54,6 +52,8 @@ type ExecutionSequencer interface { Pause() Activate() ForwardTo(url string) error + SequenceDelayedMessage(message *arbostypes.L1IncomingMessage, delayedSeqNum uint64) error + NextDelayedMessageNumber() (uint64, error) SetTransactionStreamer(streamer TransactionStreamer) } From 6c332b274bc9e23c2fe1d9e337b7cf52286f91c5 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Tue, 18 Apr 2023 23:07:09 -0600 Subject: [PATCH 13/23] sync_monitor: remove blockNum It will be back from execNode's sync_monitor --- arbnode/sync_monitor.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/arbnode/sync_monitor.go b/arbnode/sync_monitor.go index 22d2a47e37..bd9b24529c 100644 --- a/arbnode/sync_monitor.go +++ b/arbnode/sync_monitor.go @@ -73,8 +73,6 @@ func (s *SyncMonitor) SyncProgressMap() map[string]interface{} { syncing = true builtMessageCount = 0 } else { - blockNum := s.txStreamer.exec.MessageIndexToBlockNumber(builtMessageCount) - res["blockNum"] = blockNum builtMessageCount++ res["messageOfLastBlock"] = builtMessageCount } From 7678cd7456ef6325d6d2c20bf04133185754b3cb Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Wed, 19 Apr 2023 15:06:25 -0600 Subject: [PATCH 14/23] execnode L1 reader --- execution/gethexec/node.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/execution/gethexec/node.go b/execution/gethexec/node.go index 0625c21ed1..af0541cfca 100644 --- a/execution/gethexec/node.go +++ b/execution/gethexec/node.go @@ -116,6 +116,7 @@ type ExecutionNode struct { Sequencer *Sequencer // either nil or same as TxPublisher TxPublisher TransactionPublisher ConfigFetcher ConfigFetcher + L1Reader *headerreader.HeaderReader } func CreateExecutionNode( @@ -219,6 +220,7 @@ func CreateExecutionNode( sequencer, txPublisher, configFetcher, + l1Reader, }, nil } @@ -251,10 +253,9 @@ func (n *ExecutionNode) Start(ctx context.Context) error { if err != nil { return fmt.Errorf("error starting transaction puiblisher: %w", err) } - // TODO after separation - // if n.L1Reader != nil { - // n.L1Reader.Start(ctx) - // } + if n.L1Reader != nil { + n.L1Reader.Start(ctx) + } return nil } @@ -265,10 +266,9 @@ func (n *ExecutionNode) StopAndWait() { n.TxPublisher.StopAndWait() } n.Recorder.OrderlyShutdown() - // TODO after separation - // if n.L1Reader != nil && n.L1Reader.Started() { - // n.L1Reader.StopAndWait() - // } + if n.L1Reader != nil && n.L1Reader.Started() { + n.L1Reader.StopAndWait() + } if n.ExecEngine.Started() { n.ExecEngine.StopAndWait() } From a6aeffa7501bd69d8fe0c95a90a6cb467cb07303 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Wed, 19 Apr 2023 15:07:40 -0600 Subject: [PATCH 15/23] fix merge errors --- cmd/nitro/init.go | 5 ++-- cmd/nitro/nitro.go | 2 +- system_tests/conditionaltx_test.go | 48 ++++++++++++++++-------------- 3 files changed, 28 insertions(+), 27 deletions(-) diff --git a/cmd/nitro/init.go b/cmd/nitro/init.go index 5bcfe66f67..891e4d5cb1 100644 --- a/cmd/nitro/init.go +++ b/cmd/nitro/init.go @@ -28,7 +28,6 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" "github.com/offchainlabs/nitro/arbnode" - "github.com/offchainlabs/nitro/arbnode/execution" "github.com/offchainlabs/nitro/arbos" "github.com/offchainlabs/nitro/arbos/arbosState" "github.com/offchainlabs/nitro/arbutil" @@ -242,7 +241,7 @@ var hashListRegex = regexp.MustCompile("^(0x)?[0-9a-fA-F]{64}(,(0x)?[0-9a-fA-F]{ // Finds important roots to retain while proving func findImportantRoots(ctx context.Context, chainDb ethdb.Database, stack *node.Node, nodeConfig *NodeConfig, cacheConfig *core.CacheConfig, l1Client arbutil.L1Interface, rollupAddrs arbnode.RollupAddresses) ([]common.Hash, error) { initConfig := &nodeConfig.Init - chainConfig := execution.TryReadStoredChainConfig(chainDb) + chainConfig := gethexec.TryReadStoredChainConfig(chainDb) if chainConfig == nil { return nil, errors.New("database doesn't have a chain config (was this node initialized?)") } @@ -423,7 +422,7 @@ func openInitializeChainDb(ctx context.Context, stack *node.Node, config *NodeCo if err != nil { return chainDb, nil, fmt.Errorf("error pruning: %w", err) } - l2BlockChain, err := execution.GetBlockChain(chainDb, cacheConfig, chainConfig, config.Execution.TxLookupLimit) + l2BlockChain, err := gethexec.GetBlockChain(chainDb, cacheConfig, chainConfig, config.Execution.TxLookupLimit) if err != nil { return chainDb, nil, err } diff --git a/cmd/nitro/nitro.go b/cmd/nitro/nitro.go index 31c1f73261..99da4606b8 100644 --- a/cmd/nitro/nitro.go +++ b/cmd/nitro/nitro.go @@ -386,7 +386,7 @@ func mainImpl() int { } } - chainDb, l2BlockChain, err := openInitializeChainDb(ctx, stack, nodeConfig, new(big.Int).SetUint64(nodeConfig.L2.ChainID), gethexec.DefaultCacheConfigFor(stack, &nodeConfig.Node.Caching), l1Client, rollupAddrs) + chainDb, l2BlockChain, err := openInitializeChainDb(ctx, stack, nodeConfig, new(big.Int).SetUint64(nodeConfig.L2.ChainID), gethexec.DefaultCacheConfigFor(stack, &nodeConfig.Execution.Caching), l1Client, rollupAddrs) defer closeDb(chainDb, "chainDb") if l2BlockChain != nil { // Calling Stop on the blockchain multiple times does nothing diff --git a/system_tests/conditionaltx_test.go b/system_tests/conditionaltx_test.go index 9204c83246..7364581bd0 100644 --- a/system_tests/conditionaltx_test.go +++ b/system_tests/conditionaltx_test.go @@ -20,22 +20,21 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/rpc" - "github.com/offchainlabs/nitro/arbnode" - "github.com/offchainlabs/nitro/arbnode/execution" + "github.com/offchainlabs/nitro/execution/gethexec" "github.com/offchainlabs/nitro/solgen/go/mocksgen" ) -func getStorageRootHash(t *testing.T, node *arbnode.Node, address common.Address) common.Hash { +func getStorageRootHash(t *testing.T, execNode *gethexec.ExecutionNode, address common.Address) common.Hash { t.Helper() - statedb, err := node.Execution.Backend.ArbInterface().BlockChain().State() + statedb, err := execNode.Backend.ArbInterface().BlockChain().State() Require(t, err) trie := statedb.StorageTrie(address) return trie.Hash() } -func getStorageSlotValue(t *testing.T, node *arbnode.Node, address common.Address) map[common.Hash]common.Hash { +func getStorageSlotValue(t *testing.T, execNode *gethexec.ExecutionNode, address common.Address) map[common.Hash]common.Hash { t.Helper() - statedb, err := node.Execution.Backend.ArbInterface().BlockChain().State() + statedb, err := execNode.Backend.ArbInterface().BlockChain().State() Require(t, err) slotValue := make(map[common.Hash]common.Hash) Require(t, err) @@ -206,6 +205,7 @@ func TestSendRawTransactionConditionalBasic(t *testing.T) { defer requireClose(t, l1stack) defer node.StopAndWait() + execNode := getExecNode(t, node) auth := l2info.GetDefaultTransactOpts("Owner", ctx) contractAddress1, simple1 := deploySimple(t, ctx, auth, l2client) tx, err := simple1.Increment(&auth) @@ -222,10 +222,10 @@ func TestSendRawTransactionConditionalBasic(t *testing.T) { _, err = EnsureTxSucceeded(ctx, l2client, tx) Require(t, err) - currentRootHash1 := getStorageRootHash(t, node, contractAddress1) - currentSlotValueMap1 := getStorageSlotValue(t, node, contractAddress1) - currentRootHash2 := getStorageRootHash(t, node, contractAddress2) - currentSlotValueMap2 := getStorageSlotValue(t, node, contractAddress2) + currentRootHash1 := getStorageRootHash(t, execNode, contractAddress1) + currentSlotValueMap1 := getStorageSlotValue(t, execNode, contractAddress1) + currentRootHash2 := getStorageRootHash(t, execNode, contractAddress2) + currentSlotValueMap2 := getStorageSlotValue(t, execNode, contractAddress2) rpcClient, err := node.Stack.Attach() Require(t, err) @@ -261,18 +261,18 @@ func TestSendRawTransactionConditionalBasic(t *testing.T) { Require(t, err) previousStorageRootHash1 := currentRootHash1 - currentRootHash1 = getStorageRootHash(t, node, contractAddress1) + currentRootHash1 = getStorageRootHash(t, execNode, contractAddress1) if bytes.Equal(previousStorageRootHash1.Bytes(), currentRootHash1.Bytes()) { Fail(t, "storage root hash didn't change as expected") } - currentSlotValueMap1 = getStorageSlotValue(t, node, contractAddress1) + currentSlotValueMap1 = getStorageSlotValue(t, execNode, contractAddress1) previousStorageRootHash2 := currentRootHash2 - currentRootHash2 = getStorageRootHash(t, node, contractAddress2) + currentRootHash2 = getStorageRootHash(t, execNode, contractAddress2) if bytes.Equal(previousStorageRootHash2.Bytes(), currentRootHash2.Bytes()) { Fail(t, "storage root hash didn't change as expected") } - currentSlotValueMap2 = getStorageSlotValue(t, node, contractAddress2) + currentSlotValueMap2 = getStorageSlotValue(t, execNode, contractAddress2) block, err = l1client.BlockByNumber(ctx, nil) Require(t, err) @@ -366,7 +366,8 @@ func TestSendRawTransactionConditionalMultiRoutine(t *testing.T) { } cancelCtxWithTimeout() wg.Wait() - bc := node.Execution.Backend.ArbInterface().BlockChain() + execNode := getExecNode(t, node) + bc := execNode.Backend.ArbInterface().BlockChain() genesis := bc.Config().ArbitrumChainParams.GenesisBlockNum var receipts types.Receipts @@ -402,17 +403,18 @@ func TestSendRawTransactionConditionalPreCheck(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - nodeConfig := arbnode.ConfigDefaultL1Test() - nodeConfig.Sequencer.MaxBlockSpeed = 0 - nodeConfig.TxPreChecker.Strictness = execution.TxPreCheckerStrictnessLikelyCompatible - nodeConfig.TxPreChecker.RequiredStateAge = 1 - nodeConfig.TxPreChecker.RequiredStateMaxBlocks = 2 + execConfig := gethexec.ConfigDefaultTest() + execConfig.Sequencer.MaxBlockSpeed = 0 + execConfig.TxPreChecker.Strictness = gethexec.TxPreCheckerStrictnessLikelyCompatible + execConfig.TxPreChecker.RequiredStateAge = 1 + execConfig.TxPreChecker.RequiredStateMaxBlocks = 2 - l2info, node, l2client, _, _, _, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, nodeConfig, nil, nil) + l2info, node, l2client, _, _, _, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, nil, execConfig, nil, nil) defer requireClose(t, l1stack) defer node.StopAndWait() rpcClient, err := node.Stack.Attach() Require(t, err) + execNode := getExecNode(t, node) l2info.GenerateAccount("User2") @@ -427,7 +429,7 @@ func TestSendRawTransactionConditionalPreCheck(t *testing.T) { Require(t, err, "failed to call Increment()") _, err = EnsureTxSucceeded(ctx, l2client, tx) Require(t, err) - currentRootHash := getStorageRootHash(t, node, contractAddress) + currentRootHash := getStorageRootHash(t, execNode, contractAddress) options := &arbitrum_types.ConditionalOptions{ KnownAccounts: map[common.Address]arbitrum_types.RootHashOrSlots{ contractAddress: {RootHash: ¤tRootHash}, @@ -446,7 +448,7 @@ func TestSendRawTransactionConditionalPreCheck(t *testing.T) { Require(t, err, "failed to call Increment()") _, err = EnsureTxSucceeded(ctx, l2client, tx) Require(t, err) - currentRootHash = getStorageRootHash(t, node, contractAddress) + currentRootHash = getStorageRootHash(t, execNode, contractAddress) options = &arbitrum_types.ConditionalOptions{ KnownAccounts: map[common.Address]arbitrum_types.RootHashOrSlots{ contractAddress: {RootHash: ¤tRootHash}, From f28de1a2419aa7878cca725cdf638be944ab4750 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Sun, 30 Apr 2023 13:37:23 -0600 Subject: [PATCH 16/23] fix merge problems --- arbnode/node.go | 2 ++ system_tests/batch_poster_test.go | 5 +++-- system_tests/debugapi_test.go | 2 +- system_tests/staker_test.go | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/arbnode/node.go b/arbnode/node.go index 9cb8c33ef1..f68eff96cd 100644 --- a/arbnode/node.go +++ b/arbnode/node.go @@ -470,6 +470,8 @@ func ConfigDefaultL1Test() *Config { config.DelayedSequencer = TestDelayedSequencerConfig config.BatchPoster = TestBatchPosterConfig config.SeqCoordinator = TestSeqCoordinatorConfig + config.Sequencer = true + config.Dangerous.NoCoordinator = true return config } diff --git a/system_tests/batch_poster_test.go b/system_tests/batch_poster_test.go index 863f7ab045..fa33a0deb7 100644 --- a/system_tests/batch_poster_test.go +++ b/system_tests/batch_poster_test.go @@ -175,8 +175,9 @@ func TestBatchPosterKeepsUp(t *testing.T) { conf := arbnode.ConfigDefaultL1Test() conf.BatchPoster.CompressionLevel = brotli.BestCompression conf.BatchPoster.MaxBatchPostDelay = time.Hour - conf.RPC.RPCTxFeeCap = 1000. - l2info, nodeA, l2clientA, _, _, _, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, conf, nil, nil) + execConf := gethexec.ConfigDefaultTest() + execConf.RPC.RPCTxFeeCap = 1000. + l2info, nodeA, l2clientA, _, _, _, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, conf, execConf, nil, nil) defer requireClose(t, l1stack) defer nodeA.StopAndWait() l2info.GasPrice = big.NewInt(100e9) diff --git a/system_tests/debugapi_test.go b/system_tests/debugapi_test.go index 03e3dfd405..ff28e2350c 100644 --- a/system_tests/debugapi_test.go +++ b/system_tests/debugapi_test.go @@ -14,7 +14,7 @@ import ( func TestDebugAPI(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - _, _, _, l2stack, _, _, _, l1stack := createTestNodeOnL1WithConfigImpl(t, ctx, true, nil, nil, nil, nil) + _, _, _, l2stack, _, _, _, l1stack := createTestNodeOnL1WithConfigImpl(t, ctx, true, nil, nil, nil, nil, nil) defer requireClose(t, l1stack) defer requireClose(t, l2stack) diff --git a/system_tests/staker_test.go b/system_tests/staker_test.go index 47cc19f698..bf89f5febe 100644 --- a/system_tests/staker_test.go +++ b/system_tests/staker_test.go @@ -76,7 +76,7 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) types.NewArbitrumSigner(types.NewLondonSigner(l2chainConfig.ChainID)), big.NewInt(l2pricing.InitialBaseFeeWei*2), transferGas, ) - _, l2nodeA, l2clientA, _, l1info, _, l1client, l1stack := createTestNodeOnL1WithConfigImpl(t, ctx, true, nil, l2chainConfig, nil, l2info) + _, l2nodeA, l2clientA, _, l1info, _, l1client, l1stack := createTestNodeOnL1WithConfigImpl(t, ctx, true, nil, nil, l2chainConfig, nil, l2info) defer requireClose(t, l1stack) defer l2nodeA.StopAndWait() execNodeA := getExecNode(t, l2nodeA) From 85d6480bb3866c85ef79e825c2313f12ec42193d Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Wed, 10 May 2023 20:01:24 -0600 Subject: [PATCH 17/23] update headerreader API --- cmd/nitro/nitro.go | 1 + execution/gethexec/node.go | 6 +++++- system_tests/common_test.go | 6 +++--- system_tests/das_test.go | 6 +++--- system_tests/full_challenge_impl_test.go | 4 ++-- 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/cmd/nitro/nitro.go b/cmd/nitro/nitro.go index 2b46bb183d..5e55d153a5 100644 --- a/cmd/nitro/nitro.go +++ b/cmd/nitro/nitro.go @@ -465,6 +465,7 @@ func mainImpl() int { } execNode, err := gethexec.CreateExecutionNode( + ctx, stack, chainDb, l2BlockChain, diff --git a/execution/gethexec/node.go b/execution/gethexec/node.go index af0541cfca..e6ec68ed32 100644 --- a/execution/gethexec/node.go +++ b/execution/gethexec/node.go @@ -120,6 +120,7 @@ type ExecutionNode struct { } func CreateExecutionNode( + ctx context.Context, stack *node.Node, chainDB ethdb.Database, l2BlockChain *core.BlockChain, @@ -137,7 +138,10 @@ func CreateExecutionNode( var l1Reader *headerreader.HeaderReader if l1client != nil { - l1Reader = headerreader.New(l1client, func() *headerreader.Config { return &configFetcher().L1Reader }) + l1Reader, err = headerreader.New(ctx, l1client, func() *headerreader.Config { return &configFetcher().L1Reader }) + if err != nil { + return nil, err + } } fwTarget := config.ForwardingTarget() diff --git a/system_tests/common_test.go b/system_tests/common_test.go index 8c030c5e7c..8fb396e3de 100644 --- a/system_tests/common_test.go +++ b/system_tests/common_test.go @@ -568,7 +568,7 @@ func createTestNodeOnL1WithConfigImpl( Require(t, execConfig.Validate()) execConfigFetcher := func() *gethexec.Config { return execConfig } - execNode, err := gethexec.CreateExecutionNode(l2stack, l2chainDb, l2blockchain, l1client, execConfigFetcher) + execNode, err := gethexec.CreateExecutionNode(ctx, l2stack, l2chainDb, l2blockchain, l1client, execConfigFetcher) Require(t, err) currentNode, err = arbnode.CreateNode( @@ -610,7 +610,7 @@ func CreateTestL2WithConfig( Require(t, execConfig.Validate()) execConfigFetcher := func() *gethexec.Config { return execConfig } - execNode, err := gethexec.CreateExecutionNode(stack, chainDb, blockchain, nil, execConfigFetcher) + execNode, err := gethexec.CreateExecutionNode(ctx, stack, chainDb, blockchain, nil, execConfigFetcher) Require(t, err) currentNode, err := arbnode.CreateNode(ctx, stack, execNode, arbDb, NewFetcherFromConfig(nodeConfig), blockchain.Config(), nil, nil, nil, nil, feedErrChan) @@ -731,7 +731,7 @@ func Create2ndNodeWithConfig( AddDefaultValNode(t, ctx, nodeConfig, true) configFetcher := func() *gethexec.Config { return execConfig } - currentExec, err := gethexec.CreateExecutionNode(l2stack, l2chainDb, l2blockchain, l1client, configFetcher) + currentExec, err := gethexec.CreateExecutionNode(ctx, l2stack, l2chainDb, l2blockchain, l1client, configFetcher) Require(t, err) currentNode, err := arbnode.CreateNode(ctx, l2stack, currentExec, l2arbDb, NewFetcherFromConfig(nodeConfig), l2blockchain.Config(), l1client, first.DeployInfo, &txOpts, dataSigner, feedErrChan) diff --git a/system_tests/das_test.go b/system_tests/das_test.go index 1259372390..aaa3bfffb5 100644 --- a/system_tests/das_test.go +++ b/system_tests/das_test.go @@ -137,7 +137,7 @@ func TestDASRekey(t *testing.T) { l1NodeConfigA.DataAvailability.RestfulClientAggregatorConfig.Enable = true l1NodeConfigA.DataAvailability.RestfulClientAggregatorConfig.Urls = []string{restServerUrlA} l1NodeConfigA.DataAvailability.L1NodeURL = "none" - execA, err := gethexec.CreateExecutionNode(l2stackA, l2chainDb, l2blockchain, l1client, gethexec.ConfigDefaultTest) + execA, err := gethexec.CreateExecutionNode(ctx, l2stackA, l2chainDb, l2blockchain, l1client, gethexec.ConfigDefaultTest) Require(t, err) nodeA, err := arbnode.CreateNode(ctx, l2stackA, execA, l2arbDb, NewFetcherFromConfig(l1NodeConfigA), l2blockchain.Config(), l1client, addresses, sequencerTxOptsPtr, nil, feedErrChan) @@ -182,7 +182,7 @@ func TestDASRekey(t *testing.T) { l2blockchain, err := gethexec.GetBlockChain(l2chainDb, nil, chainConfig, gethexec.ConfigDefaultTest().TxLookupLimit) Require(t, err) - execA, err := gethexec.CreateExecutionNode(l2stackA, l2chainDb, l2blockchain, l1client, gethexec.ConfigDefaultTest) + execA, err := gethexec.CreateExecutionNode(ctx, l2stackA, l2chainDb, l2blockchain, l1client, gethexec.ConfigDefaultTest) Require(t, err) l1NodeConfigA.DataAvailability.AggregatorConfig = aggConfigForBackend(t, backendConfigB) @@ -313,7 +313,7 @@ func TestDASComplexConfigAndRestMirror(t *testing.T) { l2info, l2stackA, l2chainDb, l2arbDb, l2blockchain := createL2BlockChain(t, nil, "", chainConfig) l2info.GenerateAccount("User2") - execA, err := gethexec.CreateExecutionNode(l2stackA, l2chainDb, l2blockchain, l1client, gethexec.ConfigDefaultTest) + execA, err := gethexec.CreateExecutionNode(ctx, l2stackA, l2chainDb, l2blockchain, l1client, gethexec.ConfigDefaultTest) Require(t, err) sequencerTxOpts := l1info.GetDefaultTransactOpts("Sequencer", ctx) diff --git a/system_tests/full_challenge_impl_test.go b/system_tests/full_challenge_impl_test.go index f946a8a9c4..bcd8c3ffc1 100644 --- a/system_tests/full_challenge_impl_test.go +++ b/system_tests/full_challenge_impl_test.go @@ -271,7 +271,7 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall asserterL2Info, asserterL2Stack, asserterL2ChainDb, asserterL2ArbDb, asserterL2Blockchain := createL2BlockChain(t, nil, "", chainConfig) asserterRollupAddresses.Bridge = asserterBridgeAddr asserterRollupAddresses.SequencerInbox = asserterSeqInboxAddr - asserterExec, err := gethexec.CreateExecutionNode(asserterL2Stack, asserterL2ChainDb, asserterL2Blockchain, l1Backend, gethexec.ConfigDefaultTest) + asserterExec, err := gethexec.CreateExecutionNode(ctx, asserterL2Stack, asserterL2ChainDb, asserterL2Blockchain, l1Backend, gethexec.ConfigDefaultTest) Require(t, err) asserterL2, err := arbnode.CreateNode(ctx, asserterL2Stack, asserterExec, asserterL2ArbDb, NewFetcherFromConfig(conf), chainConfig, l1Backend, asserterRollupAddresses, nil, nil, fatalErrChan) Require(t, err) @@ -282,7 +282,7 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall challengerRollupAddresses := *asserterRollupAddresses challengerRollupAddresses.Bridge = challengerBridgeAddr challengerRollupAddresses.SequencerInbox = challengerSeqInboxAddr - challengerExec, err := gethexec.CreateExecutionNode(challengerL2Stack, challengerL2ChainDb, challengerL2Blockchain, l1Backend, gethexec.ConfigDefaultTest) + challengerExec, err := gethexec.CreateExecutionNode(ctx, challengerL2Stack, challengerL2ChainDb, challengerL2Blockchain, l1Backend, gethexec.ConfigDefaultTest) Require(t, err) challengerL2, err := arbnode.CreateNode(ctx, challengerL2Stack, challengerExec, challengerL2ArbDb, NewFetcherFromConfig(conf), chainConfig, l1Backend, &challengerRollupAddresses, nil, nil, fatalErrChan) Require(t, err) From ed4cd44420fd118c65265fabd1267fdfdeac1564 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Wed, 14 Jun 2023 18:44:49 -0600 Subject: [PATCH 18/23] fix merge --- arbnode/node.go | 2 +- cmd/nitro/nitro.go | 3 +++ go-ethereum | 2 +- system_tests/forwarder_test.go | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/arbnode/node.go b/arbnode/node.go index 11ce2f5497..760ba4ebfd 100644 --- a/arbnode/node.go +++ b/arbnode/node.go @@ -808,7 +808,7 @@ func createNodeImpl( } } var messagePruner *MessagePruner - if config.MessagePruner.Enable && !config.Caching.Archive && stakerObj != nil { + if config.MessagePruner.Enable && stakerObj != nil { messagePruner = NewMessagePruner(txStreamer, inboxTracker, stakerObj, func() *MessagePrunerConfig { return &configFetcher.Get().MessagePruner }) } // always create DelayedSequencer, it won't do anything if it is disabled diff --git a/cmd/nitro/nitro.go b/cmd/nitro/nitro.go index 40662e37f9..b8589cbe16 100644 --- a/cmd/nitro/nitro.go +++ b/cmd/nitro/nitro.go @@ -683,6 +683,9 @@ func ParseNode(ctx context.Context, args []string) (*NodeConfig, *genericconf.Wa nodeConfig.L1.Wallet = genericconf.WalletConfigDefault nodeConfig.L2.DevWallet = genericconf.WalletConfigDefault + if nodeConfig.Execution.Archive { + nodeConfig.Node.MessagePruner.Enable = false + } err = nodeConfig.Validate() if err != nil { return nil, nil, nil, err diff --git a/go-ethereum b/go-ethereum index aa93654f73..7ea707239f 160000 --- a/go-ethereum +++ b/go-ethereum @@ -1 +1 @@ -Subproject commit aa93654f732abdbb7cf79574b8ca6e2f8a3337e7 +Subproject commit 7ea707239f34fc2fa56be4b1b97a470f00cab600 diff --git a/system_tests/forwarder_test.go b/system_tests/forwarder_test.go index 0ae266fd23..22421407d8 100644 --- a/system_tests/forwarder_test.go +++ b/system_tests/forwarder_test.go @@ -323,7 +323,7 @@ func TestRedisForwarderFallbackNoRedis(t *testing.T) { l2info.GenerateAccount(user) tx := l2info.PrepareTx("Owner", "User2", l2info.TransferGas, transferAmount, nil) sendFunc := func() error { return forwardingClient.SendTransaction(ctx, tx) } - err := tryWithTimeout(ctx, sendFunc, execution.DefaultTestForwarderConfig.UpdateInterval*10) + err := tryWithTimeout(ctx, sendFunc, gethexec.DefaultTestForwarderConfig.UpdateInterval*10) Require(t, err) _, err = EnsureTxSucceeded(ctx, fallbackClient, tx) From a5434adc36c57c019768a6b525e364a234511e95 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Tue, 27 Jun 2023 11:36:14 -0600 Subject: [PATCH 19/23] remove unused sequencer.dangerous config --- execution/gethexec/sequencer.go | 44 +++++++++------------------------ 1 file changed, 12 insertions(+), 32 deletions(-) diff --git a/execution/gethexec/sequencer.go b/execution/gethexec/sequencer.go index ffb919caa3..8712003fa6 100644 --- a/execution/gethexec/sequencer.go +++ b/execution/gethexec/sequencer.go @@ -54,35 +54,18 @@ var ( ) type SequencerConfig struct { - Enable bool `koanf:"enable"` - MaxBlockSpeed time.Duration `koanf:"max-block-speed" reload:"hot"` - MaxRevertGasReject uint64 `koanf:"max-revert-gas-reject" reload:"hot"` - MaxAcceptableTimestampDelta time.Duration `koanf:"max-acceptable-timestamp-delta" reload:"hot"` - SenderWhitelist string `koanf:"sender-whitelist"` - Forwarder ForwarderConfig `koanf:"forwarder"` - QueueSize int `koanf:"queue-size"` - QueueTimeout time.Duration `koanf:"queue-timeout" reload:"hot"` - NonceCacheSize int `koanf:"nonce-cache-size" reload:"hot"` - MaxTxDataSize int `koanf:"max-tx-data-size" reload:"hot"` - NonceFailureCacheSize int `koanf:"nonce-failure-cache-size" reload:"hot"` - NonceFailureCacheExpiry time.Duration `koanf:"nonce-failure-cache-expiry" reload:"hot"` - Dangerous DangerousSequencerConfig `koanf:"dangerous"` -} - -type DangerousSequencerConfig struct { - NoCoordinator bool `koanf:"no-coordinator"` -} - -var DefaultDangerousSequencerConfig = DangerousSequencerConfig{ - NoCoordinator: false, -} - -var TestDangerousSequencerConfig = DangerousSequencerConfig{ - NoCoordinator: true, -} - -func DangerousSequencerConfigAddOptions(prefix string, f *flag.FlagSet) { - f.Bool(prefix+".no-coordinator", DefaultDangerousSequencerConfig.NoCoordinator, "DANGEROUS! allows sequencer without coordinator.") + Enable bool `koanf:"enable"` + MaxBlockSpeed time.Duration `koanf:"max-block-speed" reload:"hot"` + MaxRevertGasReject uint64 `koanf:"max-revert-gas-reject" reload:"hot"` + MaxAcceptableTimestampDelta time.Duration `koanf:"max-acceptable-timestamp-delta" reload:"hot"` + SenderWhitelist string `koanf:"sender-whitelist"` + Forwarder ForwarderConfig `koanf:"forwarder"` + QueueSize int `koanf:"queue-size"` + QueueTimeout time.Duration `koanf:"queue-timeout" reload:"hot"` + NonceCacheSize int `koanf:"nonce-cache-size" reload:"hot"` + MaxTxDataSize int `koanf:"max-tx-data-size" reload:"hot"` + NonceFailureCacheSize int `koanf:"nonce-failure-cache-size" reload:"hot"` + NonceFailureCacheExpiry time.Duration `koanf:"nonce-failure-cache-expiry" reload:"hot"` } func (c *SequencerConfig) Validate() error { @@ -109,7 +92,6 @@ var DefaultSequencerConfig = SequencerConfig{ QueueSize: 1024, QueueTimeout: time.Second * 12, NonceCacheSize: 1024, - Dangerous: DefaultDangerousSequencerConfig, // 95% of the default batch poster limit, leaving 5KB for headers and such MaxTxDataSize: 95000, NonceFailureCacheSize: 1024, @@ -126,7 +108,6 @@ var TestSequencerConfig = SequencerConfig{ QueueSize: 128, QueueTimeout: time.Second * 5, NonceCacheSize: 4, - Dangerous: TestDangerousSequencerConfig, MaxTxDataSize: 95000, NonceFailureCacheSize: 1024, NonceFailureCacheExpiry: time.Second, @@ -145,7 +126,6 @@ func SequencerConfigAddOptions(prefix string, f *flag.FlagSet) { f.Int(prefix+".max-tx-data-size", DefaultSequencerConfig.MaxTxDataSize, "maximum transaction size the sequencer will accept") f.Int(prefix+".nonce-failure-cache-size", DefaultSequencerConfig.NonceFailureCacheSize, "number of transactions with too high of a nonce to keep in memory while waiting for their predecessor") f.Duration(prefix+".nonce-failure-cache-expiry", DefaultSequencerConfig.NonceFailureCacheExpiry, "maximum amount of time to wait for a predecessor before rejecting a tx with nonce too high") - DangerousSequencerConfigAddOptions(prefix+".dangerous", f) } type txQueueItem struct { From 698165465e14311d43dbdb912977f5ddbcff498c Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Mon, 10 Jul 2023 16:42:24 -0600 Subject: [PATCH 20/23] fix merge errors --- arbnode/node.go | 58 ++++++++++---------------------------- execution/gethexec/node.go | 27 ++++++++++-------- 2 files changed, 30 insertions(+), 55 deletions(-) diff --git a/arbnode/node.go b/arbnode/node.go index e695da4831..65e16f721b 100644 --- a/arbnode/node.go +++ b/arbnode/node.go @@ -14,7 +14,6 @@ import ( flag "github.com/spf13/pflag" "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/arbitrum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" @@ -371,7 +370,6 @@ func ConfigAddOptions(prefix string, f *flag.FlagSet, feedInputEnable bool, feed BatchPosterConfigAddOptions(prefix+".batch-poster", f) MessagePrunerConfigAddOptions(prefix+".message-pruner", f) staker.BlockValidatorConfigAddOptions(prefix+".block-validator", f) - arbitrum.RecordingDatabaseConfigAddOptions(prefix+".recording-database", f) broadcastclient.FeedConfigAddOptions(prefix+".feed", f, feedInputEnable, feedOutputEnable) staker.L1ValidatorConfigAddOptions(prefix+".staker", f) SeqCoordinatorConfigAddOptions(prefix+".seq-coordinator", f) @@ -380,32 +378,22 @@ func ConfigAddOptions(prefix string, f *flag.FlagSet, feedInputEnable bool, feed DangerousConfigAddOptions(prefix+".dangerous", f) TransactionStreamerConfigAddOptions(prefix+".transaction-streamer", f) MaintenanceConfigAddOptions(prefix+".maintenance", f) - - archiveMsg := fmt.Sprintf("retain past block state (deprecated, please use %v.caching.archive)", prefix) - f.Bool(prefix+".archive", ConfigDefault.Archive, archiveMsg) } var ConfigDefault = Config{ - RPC: arbitrum.DefaultConfig, - Sequencer: execution.DefaultSequencerConfig, - L1Reader: headerreader.DefaultConfig, - InboxReader: DefaultInboxReaderConfig, - DelayedSequencer: DefaultDelayedSequencerConfig, - BatchPoster: DefaultBatchPosterConfig, - MessagePruner: DefaultMessagePrunerConfig, - ForwardingTargetImpl: "", - TxPreChecker: execution.DefaultTxPreCheckerConfig, - BlockValidator: staker.DefaultBlockValidatorConfig, - Feed: broadcastclient.FeedConfigDefault, - Staker: staker.DefaultL1ValidatorConfig, - SeqCoordinator: DefaultSeqCoordinatorConfig, - DataAvailability: das.DefaultDataAvailabilityConfig, - SyncMonitor: DefaultSyncMonitorConfig, - Dangerous: DefaultDangerousConfig, - Archive: false, - TxLookupLimit: 126_230_400, // 1 year at 4 blocks per second - Caching: execution.DefaultCachingConfig, - TransactionStreamer: DefaultTransactionStreamerConfig, + L1Reader: headerreader.DefaultConfig, + InboxReader: DefaultInboxReaderConfig, + DelayedSequencer: DefaultDelayedSequencerConfig, + BatchPoster: DefaultBatchPosterConfig, + MessagePruner: DefaultMessagePrunerConfig, + BlockValidator: staker.DefaultBlockValidatorConfig, + Feed: broadcastclient.FeedConfigDefault, + Staker: staker.DefaultL1ValidatorConfig, + SeqCoordinator: DefaultSeqCoordinatorConfig, + DataAvailability: das.DefaultDataAvailabilityConfig, + SyncMonitor: DefaultSyncMonitorConfig, + Dangerous: DefaultDangerousConfig, + TransactionStreamer: DefaultTransactionStreamerConfig, } func ConfigDefaultL1Test() *Config { @@ -579,15 +567,6 @@ func createNodeImpl( } } - sequencerConfigFetcher := func() *execution.SequencerConfig { return &configFetcher.Get().Sequencer } - txprecheckConfigFetcher := func() *execution.TxPreCheckerConfig { return &configFetcher.Get().TxPreChecker } - exec, err := execution.CreateExecutionNode(stack, chainDb, l2BlockChain, l1Reader, syncMonitor, - config.ForwardingTarget(), &config.Forwarder, config.RPC, - sequencerConfigFetcher, txprecheckConfigFetcher) - if err != nil { - return nil, err - } - var broadcastServer *broadcaster.Broadcaster if config.Feed.Output.Enable { var maybeDataSigner signature.DataSignerFunc @@ -797,7 +776,7 @@ func createNodeImpl( } notifiers := make([]staker.LatestStakedNotifier, 0) - if config.MessagePruner.Enable && !config.Caching.Archive { + if config.MessagePruner.Enable { messagePruner = NewMessagePruner(txStreamer, inboxTracker, func() *MessagePrunerConfig { return &configFetcher.Get().MessagePruner }) notifiers = append(notifiers, messagePruner) } @@ -834,10 +813,7 @@ func createNodeImpl( return nil, err } } - var messagePruner *MessagePruner - if config.MessagePruner.Enable && !config.Caching.Archive && stakerObj != nil { - messagePruner = NewMessagePruner(txStreamer, inboxTracker, stakerObj, func() *MessagePrunerConfig { return &configFetcher.Get().MessagePruner }) - } + // always create DelayedSequencer, it won't do anything if it is disabled delayedSequencer, err = NewDelayedSequencer(l1Reader, inboxReader, exec, coordinator, func() *DelayedSequencerConfig { return &configFetcher.Get().DelayedSequencer }) if err != nil { @@ -973,10 +949,6 @@ func (n *Node) Start(ctx context.Context) error { return fmt.Errorf("error starting inbox reader: %w", err) } } - err = n.Execution.TxPublisher.Start(ctx) - if err != nil { - return fmt.Errorf("error starting transaction puiblisher: %w", err) - } if n.SeqCoordinator != nil { n.SeqCoordinator.Start(ctx) } diff --git a/execution/gethexec/node.go b/execution/gethexec/node.go index e6ec68ed32..9dc546b529 100644 --- a/execution/gethexec/node.go +++ b/execution/gethexec/node.go @@ -35,16 +35,17 @@ func DangerousConfigAddOptions(prefix string, f *flag.FlagSet) { } type Config struct { - L1Reader headerreader.Config `koanf:"l1-reader" reload:"hot"` - Sequencer SequencerConfig `koanf:"sequencer" reload:"hot"` - TxPreChecker TxPreCheckerConfig `koanf:"tx-pre-checker" reload:"hot"` - Forwarder ForwarderConfig `koanf:"forwarder"` - ForwardingTargetImpl string `koanf:"forwarding-target"` - Caching CachingConfig `koanf:"caching"` - RPC arbitrum.Config `koanf:"rpc"` - Archive bool `koanf:"archive"` - TxLookupLimit uint64 `koanf:"tx-lookup-limit"` - Dangerous DangerousConfig `koanf:"dangerous"` + L1Reader headerreader.Config `koanf:"l1-reader" reload:"hot"` + Sequencer SequencerConfig `koanf:"sequencer" reload:"hot"` + RecordingDB arbitrum.RecordingDatabaseConfig `koanf:"recording-database"` + TxPreChecker TxPreCheckerConfig `koanf:"tx-pre-checker" reload:"hot"` + Forwarder ForwarderConfig `koanf:"forwarder"` + ForwardingTargetImpl string `koanf:"forwarding-target"` + Caching CachingConfig `koanf:"caching"` + RPC arbitrum.Config `koanf:"rpc"` + Archive bool `koanf:"archive"` + TxLookupLimit uint64 `koanf:"tx-lookup-limit"` + Dangerous DangerousConfig `koanf:"dangerous"` } func (c *Config) ForwardingTarget() string { @@ -68,12 +69,12 @@ func (c *Config) Validate() error { func ConfigAddOptions(prefix string, f *flag.FlagSet) { arbitrum.ConfigAddOptions(prefix+".rpc", f) SequencerConfigAddOptions(prefix+".sequencer", f) + arbitrum.RecordingDatabaseConfigAddOptions(prefix+".recording-database", f) f.String(prefix+".forwarding-target", ConfigDefault.ForwardingTargetImpl, "transaction forwarding target URL, or \"null\" to disable forwarding (iff not sequencer)") AddOptionsForNodeForwarderConfig(prefix+".forwarder", f) TxPreCheckerConfigAddOptions(prefix+".tx-pre-checker", f) CachingConfigAddOptions(prefix+".caching", f) f.Uint64(prefix+".tx-lookup-limit", ConfigDefault.TxLookupLimit, "retain the ability to lookup transactions by hash for the past N blocks (0 = all blocks)") - archiveMsg := fmt.Sprintf("retain past block state (deprecated, please use %v.caching.archive)", prefix) f.Bool(prefix+".archive", ConfigDefault.Archive, archiveMsg) DangerousConfigAddOptions(prefix+".dangerous", f) @@ -82,11 +83,13 @@ func ConfigAddOptions(prefix string, f *flag.FlagSet) { var ConfigDefault = Config{ RPC: arbitrum.DefaultConfig, Sequencer: DefaultSequencerConfig, + RecordingDB: arbitrum.DefaultRecordingDatabaseConfig, ForwardingTargetImpl: "", TxPreChecker: DefaultTxPreCheckerConfig, Archive: false, TxLookupLimit: 126_230_400, // 1 year at 4 blocks per second Caching: DefaultCachingConfig, + Dangerous: DefaultDangerousConfig, } func ConfigDefaultNonSequencerTest() *Config { @@ -132,7 +135,7 @@ func CreateExecutionNode( if err != nil { return nil, err } - recorder := NewBlockRecorder(execEngine, chainDB) + recorder := NewBlockRecorder(&config.RecordingDB, execEngine, chainDB) var txPublisher TransactionPublisher var sequencer *Sequencer From 6a9e0c2aa010e16a2c7294edb1cde7df7751d870 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Tue, 26 Sep 2023 17:20:37 -0600 Subject: [PATCH 21/23] fix merge errors --- arbnode/node.go | 4 ++-- cmd/nitro/config_test.go | 14 +++++------ cmd/nitro/nitro.go | 10 ++++---- execution/gethexec/node.go | 33 ++++++++++++++------------ system_tests/debugapi_test.go | 2 +- system_tests/recreatestate_rpc_test.go | 15 +++++++----- system_tests/retryable_test.go | 3 ++- system_tests/staker_test.go | 6 +++-- 8 files changed, 48 insertions(+), 39 deletions(-) diff --git a/arbnode/node.go b/arbnode/node.go index a339f56b05..25bc7bafcd 100644 --- a/arbnode/node.go +++ b/arbnode/node.go @@ -414,7 +414,7 @@ func ConfigDefaultL2Test() *Config { type DangerousConfig struct { NoL1Listener bool `koanf:"no-l1-listener"` - NoCoordinator bool `koanf:"no-seq-coordinator"` + NoCoordinator bool `koanf:"no-coordinator"` } var DefaultDangerousConfig = DangerousConfig{ @@ -424,7 +424,7 @@ var DefaultDangerousConfig = DangerousConfig{ func DangerousConfigAddOptions(prefix string, f *flag.FlagSet) { f.Bool(prefix+".no-l1-listener", DefaultDangerousConfig.NoL1Listener, "DANGEROUS! disables listening to L1. To be used in test nodes only") - f.Bool(prefix+".no-seq-coordinator", DefaultDangerousConfig.NoCoordinator, "DANGEROUS! allows sequencing without sequencer-coordinator") + f.Bool(prefix+".no-coordinator", DefaultDangerousConfig.NoCoordinator, "DANGEROUS! allows sequencing without sequencer-coordinator") } type Node struct { diff --git a/cmd/nitro/config_test.go b/cmd/nitro/config_test.go index 5e3f6a8ef2..417b256116 100644 --- a/cmd/nitro/config_test.go +++ b/cmd/nitro/config_test.go @@ -69,7 +69,7 @@ func TestReloads(t *testing.T) { config := NodeConfigDefault update := NodeConfigDefault - update.Node.BatchPoster.BatchPollDelay++ + update.Node.BatchPoster.MaxSize++ check(reflect.ValueOf(config), false, "config") Require(t, config.CanReload(&config)) @@ -114,8 +114,8 @@ func TestLiveNodeConfig(t *testing.T) { // check updating the config update := config.ShallowClone() expected := config.ShallowClone() - update.Node.BatchPoster.BatchPollDelay += 2 * time.Millisecond - expected.Node.BatchPoster.BatchPollDelay += 2 * time.Millisecond + update.Node.BatchPoster.MaxSize += 100 + expected.Node.BatchPoster.MaxSize += 100 Require(t, liveConfig.Set(update)) if !reflect.DeepEqual(liveConfig.Get(), expected) { Fail(t, "failed to set config") @@ -150,19 +150,19 @@ func TestLiveNodeConfig(t *testing.T) { // change the config file expected = config.ShallowClone() - expected.Node.BatchPoster.BatchPollDelay += time.Millisecond - jsonConfig = fmt.Sprintf("{\"node\":{\"batch-poster\":{\"poll-delay\":\"%s\"}}, \"chain\":{\"id\":421613}}", expected.Node.BatchPoster.BatchPollDelay.String()) + expected.Node.BatchPoster.MaxSize += 100 + jsonConfig = fmt.Sprintf("{\"node\":{\"batch-poster\":{\"max-size\":\"%d\"}}, \"chain\":{\"id\":421613}}", expected.Node.BatchPoster.MaxSize) Require(t, WriteToConfigFile(configFile, jsonConfig)) // trigger LiveConfig reload Require(t, syscall.Kill(syscall.Getpid(), syscall.SIGUSR1)) if !PollLiveConfigUntilEqual(liveConfig, expected) { - Fail(t, "failed to update config", config.Node.BatchPoster.BatchPollDelay, update.Node.BatchPoster.BatchPollDelay) + Fail(t, "failed to update config", config.Node.BatchPoster.MaxSize, update.Node.BatchPoster.MaxSize) } // change chain.id in the config file (currently non-reloadable) - jsonConfig = fmt.Sprintf("{\"node\":{\"batch-poster\":{\"poll-delay\":\"%s\"}}, \"chain\":{\"id\":421703}}", expected.Node.BatchPoster.BatchPollDelay.String()) + jsonConfig = fmt.Sprintf("{\"node\":{\"batch-poster\":{\"max-size\":\"%d\"}}, \"chain\":{\"id\":421703}}", expected.Node.BatchPoster.MaxSize) Require(t, WriteToConfigFile(configFile, jsonConfig)) // trigger LiveConfig reload diff --git a/cmd/nitro/nitro.go b/cmd/nitro/nitro.go index 03c559ca26..c0abe6d605 100644 --- a/cmd/nitro/nitro.go +++ b/cmd/nitro/nitro.go @@ -313,11 +313,11 @@ func mainImpl() int { } } - if nodeConfig.Node.RPC.MaxRecreateStateDepth == arbitrum.UninitializedMaxRecreateStateDepth { - if nodeConfig.Node.Archive { - nodeConfig.Node.RPC.MaxRecreateStateDepth = arbitrum.DefaultArchiveNodeMaxRecreateStateDepth + if nodeConfig.Execution.RPC.MaxRecreateStateDepth == arbitrum.UninitializedMaxRecreateStateDepth { + if nodeConfig.Execution.Archive { + nodeConfig.Execution.RPC.MaxRecreateStateDepth = arbitrum.DefaultArchiveNodeMaxRecreateStateDepth } else { - nodeConfig.Node.RPC.MaxRecreateStateDepth = arbitrum.DefaultNonArchiveNodeMaxRecreateStateDepth + nodeConfig.Execution.RPC.MaxRecreateStateDepth = arbitrum.DefaultNonArchiveNodeMaxRecreateStateDepth } } liveNodeConfig := genericconf.NewLiveConfig[*NodeConfig](args, nodeConfig, func(ctx context.Context, args []string) (*NodeConfig, error) { @@ -818,7 +818,7 @@ func applyChainParameters(ctx context.Context, k *koanf.Koanf, chainId uint64, c chainDefaults["init.empty"] = true } if parentChainIsArbitrum { - l2MaxTxSize := execution.DefaultSequencerConfig.MaxTxDataSize + l2MaxTxSize := gethexec.DefaultSequencerConfig.MaxTxDataSize bufferSpace := 5000 if l2MaxTxSize < bufferSpace*2 { return false, fmt.Errorf("not enough room in parent chain max tx size %v for bufferSpace %v * 2", l2MaxTxSize, bufferSpace) diff --git a/execution/gethexec/node.go b/execution/gethexec/node.go index 36a35d2c15..5176eb28dd 100644 --- a/execution/gethexec/node.go +++ b/execution/gethexec/node.go @@ -9,6 +9,7 @@ import ( "github.com/ethereum/go-ethereum/arbitrum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth/filters" "github.com/ethereum/go-ethereum/ethdb" @@ -18,6 +19,7 @@ import ( "github.com/offchainlabs/nitro/arbos/arbostypes" "github.com/offchainlabs/nitro/arbutil" "github.com/offchainlabs/nitro/execution" + "github.com/offchainlabs/nitro/solgen/go/precompilesgen" "github.com/offchainlabs/nitro/util/headerreader" flag "github.com/spf13/pflag" ) @@ -35,9 +37,9 @@ func DangerousConfigAddOptions(prefix string, f *flag.FlagSet) { } type Config struct { - ParentChainReader headerreader.Config `koanf:"l1-reader" reload:"hot"` + ParentChainReader headerreader.Config `koanf:"parent-chain-reader" reload:"hot"` Sequencer SequencerConfig `koanf:"sequencer" reload:"hot"` - RecordingDB arbitrum.RecordingDatabaseConfig `koanf:"recording-database"` + RecordingDatabase arbitrum.RecordingDatabaseConfig `koanf:"recording-database"` TxPreChecker TxPreCheckerConfig `koanf:"tx-pre-checker" reload:"hot"` Forwarder ForwarderConfig `koanf:"forwarder"` ForwardingTarget string `koanf:"forwarding-target"` @@ -70,7 +72,7 @@ func ConfigAddOptions(prefix string, f *flag.FlagSet) { arbitrum.ConfigAddOptions(prefix+".rpc", f) SequencerConfigAddOptions(prefix+".sequencer", f) arbitrum.RecordingDatabaseConfigAddOptions(prefix+".recording-database", f) - f.String(prefix+".forwarding-target", ConfigDefault.ForwardingTargetImpl, "transaction forwarding target URL, or \"null\" to disable forwarding (iff not sequencer)") + f.String(prefix+".forwarding-target", ConfigDefault.ForwardingTarget, "transaction forwarding target URL, or \"null\" to disable forwarding (iff not sequencer)") AddOptionsForNodeForwarderConfig(prefix+".forwarder", f) TxPreCheckerConfigAddOptions(prefix+".tx-pre-checker", f) CachingConfigAddOptions(prefix+".caching", f) @@ -81,15 +83,15 @@ func ConfigAddOptions(prefix string, f *flag.FlagSet) { } var ConfigDefault = Config{ - RPC: arbitrum.DefaultConfig, - Sequencer: DefaultSequencerConfig, - RecordingDB: arbitrum.DefaultRecordingDatabaseConfig, - ForwardingTarget: "", - TxPreChecker: DefaultTxPreCheckerConfig, - Archive: false, - TxLookupLimit: 126_230_400, // 1 year at 4 blocks per second - Caching: DefaultCachingConfig, - Dangerous: DefaultDangerousConfig, + RPC: arbitrum.DefaultConfig, + Sequencer: DefaultSequencerConfig, + RecordingDatabase: arbitrum.DefaultRecordingDatabaseConfig, + ForwardingTarget: "", + TxPreChecker: DefaultTxPreCheckerConfig, + Archive: false, + TxLookupLimit: 126_230_400, // 1 year at 4 blocks per second + Caching: DefaultCachingConfig, + Dangerous: DefaultDangerousConfig, } func ConfigDefaultNonSequencerTest() *Config { @@ -135,19 +137,20 @@ func CreateExecutionNode( if err != nil { return nil, err } - recorder := NewBlockRecorder(&config.RecordingDB, execEngine, chainDB) + recorder := NewBlockRecorder(&config.RecordingDatabase, execEngine, chainDB) var txPublisher TransactionPublisher var sequencer *Sequencer var parentChainReader *headerreader.HeaderReader if l1client != nil { - parentChainReader, err = headerreader.New(ctx, l1client, func() *headerreader.Config { return &configFetcher().ParentChainReader }) + arbSys, _ := precompilesgen.NewArbSys(types.ArbSysAddress, l1client) + parentChainReader, err = headerreader.New(ctx, l1client, func() *headerreader.Config { return &configFetcher().ParentChainReader }, arbSys) if err != nil { return nil, err } } - fwTarget := config.ForwardingTarget() + fwTarget := config.ForwardingTargetF() if config.Sequencer.Enable { if fwTarget != "" { return nil, errors.New("sequencer and forwarding target both set") diff --git a/system_tests/debugapi_test.go b/system_tests/debugapi_test.go index ff28e2350c..17398de26b 100644 --- a/system_tests/debugapi_test.go +++ b/system_tests/debugapi_test.go @@ -14,7 +14,7 @@ import ( func TestDebugAPI(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - _, _, _, l2stack, _, _, _, l1stack := createTestNodeOnL1WithConfigImpl(t, ctx, true, nil, nil, nil, nil, nil) + _, _, _, l2stack, _, _, _, l1stack := createTestNodeOnL1WithConfigImpl(t, ctx, true, nil, nil, nil, nil, nil, nil) defer requireClose(t, l1stack) defer requireClose(t, l2stack) diff --git a/system_tests/recreatestate_rpc_test.go b/system_tests/recreatestate_rpc_test.go index 561085c3f3..f4ccc5ca90 100644 --- a/system_tests/recreatestate_rpc_test.go +++ b/system_tests/recreatestate_rpc_test.go @@ -18,6 +18,7 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/trie" "github.com/offchainlabs/nitro/arbnode" + "github.com/offchainlabs/nitro/execution/gethexec" "github.com/offchainlabs/nitro/util" "github.com/offchainlabs/nitro/util/testhelpers" ) @@ -25,9 +26,10 @@ import ( func prepareNodeWithHistory(t *testing.T, ctx context.Context, maxRecreateStateDepth int64, txCount uint64) (node *arbnode.Node, bc *core.BlockChain, db ethdb.Database, l2client *ethclient.Client, l2info info, cancel func()) { t.Helper() nodeConfig := arbnode.ConfigDefaultL1Test() - nodeConfig.RPC.MaxRecreateStateDepth = maxRecreateStateDepth - nodeConfig.Sequencer.MaxBlockSpeed = 0 - nodeConfig.Sequencer.MaxTxDataSize = 150 // 1 test tx ~= 110 + execConfig := gethexec.ConfigDefaultTest() + execConfig.RPC.MaxRecreateStateDepth = maxRecreateStateDepth + execConfig.Sequencer.MaxBlockSpeed = 0 + execConfig.Sequencer.MaxTxDataSize = 150 // 1 test tx ~= 110 cacheConfig := &core.CacheConfig{ // Arbitrum Config Options TriesInMemory: 128, @@ -43,7 +45,7 @@ func prepareNodeWithHistory(t *testing.T, ctx context.Context, maxRecreateStateD SnapshotLimit: 256, SnapshotWait: true, } - l2info, node, l2client, _, _, _, _, l1stack := createTestNodeOnL1WithConfigImpl(t, ctx, true, nodeConfig, nil, nil, cacheConfig, nil) + l2info, node, l2client, _, _, _, _, l1stack := createTestNodeOnL1WithConfigImpl(t, ctx, true, nodeConfig, execConfig, nil, nil, cacheConfig, nil) cancel = func() { defer requireClose(t, l1stack) defer node.StopAndWait() @@ -60,8 +62,9 @@ func prepareNodeWithHistory(t *testing.T, ctx context.Context, maxRecreateStateD _, err := EnsureTxSucceeded(ctx, l2client, tx) testhelpers.RequireImpl(t, err) } - bc = node.Execution.Backend.ArbInterface().BlockChain() - db = node.Execution.Backend.ChainDb() + exec := getExecNode(t, node) + bc = exec.Backend.ArbInterface().BlockChain() + db = exec.Backend.ChainDb() return } diff --git a/system_tests/retryable_test.go b/system_tests/retryable_test.go index b1dd32d1dc..0fc6d24ed0 100644 --- a/system_tests/retryable_test.go +++ b/system_tests/retryable_test.go @@ -21,6 +21,7 @@ import ( "github.com/offchainlabs/nitro/arbos/arbostypes" "github.com/offchainlabs/nitro/arbos/retryables" "github.com/offchainlabs/nitro/arbos/util" + "github.com/offchainlabs/nitro/execution/gethexec" "github.com/offchainlabs/nitro/arbos/l2pricing" "github.com/offchainlabs/nitro/solgen/go/bridgegen" @@ -802,7 +803,7 @@ func elevateL2Basefee(t *testing.T, ctx context.Context, l2client *ethclient.Cli _, err = precompilesgen.NewArbosTest(common.HexToAddress("0x69"), l2client) Require(t, err, "failed to deploy ArbosTest") - burnAmount := arbnode.ConfigDefaultL1Test().RPC.RPCGasCap + burnAmount := gethexec.ConfigDefaultTest().RPC.RPCGasCap burnTarget := uint64(5 * l2pricing.InitialSpeedLimitPerSecondV6 * l2pricing.InitialBacklogTolerance) for i := uint64(0); i < (burnTarget+burnAmount)/burnAmount; i++ { burnArbGas := arbostestabi.Methods["burnArbGas"] diff --git a/system_tests/staker_test.go b/system_tests/staker_test.go index bf393a47b1..326b6939c2 100644 --- a/system_tests/staker_test.go +++ b/system_tests/staker_test.go @@ -74,10 +74,12 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) l2info.GenerateGenesisAccount("FaultyAddr", common.Big1) } config := arbnode.ConfigDefaultL1Test() - config.Sequencer.Enable = false + execConfig := gethexec.ConfigDefaultTest() + execConfig.Sequencer.Enable = false + config.Sequencer = false config.DelayedSequencer.Enable = false config.BatchPoster.Enable = false - _, l2nodeB := Create2ndNodeWithConfig(t, ctx, l2nodeA, l1stack, l1info, &l2info.ArbInitData, config, gethexec.ConfigDefaultTest(), nil) + _, l2nodeB := Create2ndNodeWithConfig(t, ctx, l2nodeA, l1stack, l1info, &l2info.ArbInitData, config, execConfig, nil) defer l2nodeB.StopAndWait() execNodeB := getExecNode(t, l2nodeB) From 0e7ddcc82c573604e5ec8aedaab45e9addb9dbb7 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Thu, 28 Sep 2023 16:08:02 -0600 Subject: [PATCH 22/23] fix review comments --- arbnode/node.go | 32 +++++++--------- arbnode/seq_coordinator.go | 10 ++++- arbnode/sync_monitor.go | 6 ++- cmd/nitro/nitro.go | 24 ++++-------- execution/gethexec/node.go | 51 +++++++++++++++----------- execution/interface.go | 3 ++ system_tests/common_test.go | 1 + system_tests/recreatestate_rpc_test.go | 1 + 8 files changed, 67 insertions(+), 61 deletions(-) diff --git a/arbnode/node.go b/arbnode/node.go index 25bc7bafcd..ec2f28b77b 100644 --- a/arbnode/node.go +++ b/arbnode/node.go @@ -376,7 +376,7 @@ func ConfigDefaultL1Test() *Config { config.BatchPoster = TestBatchPosterConfig config.SeqCoordinator = TestSeqCoordinatorConfig config.Sequencer = true - config.Dangerous.NoCoordinator = true + config.Dangerous.NoSequencerCoordinator = true return config } @@ -413,18 +413,18 @@ func ConfigDefaultL2Test() *Config { } type DangerousConfig struct { - NoL1Listener bool `koanf:"no-l1-listener"` - NoCoordinator bool `koanf:"no-coordinator"` + NoL1Listener bool `koanf:"no-l1-listener"` + NoSequencerCoordinator bool `koanf:"no-sequencer-coordinator"` } var DefaultDangerousConfig = DangerousConfig{ - NoL1Listener: false, - NoCoordinator: false, + NoL1Listener: false, + NoSequencerCoordinator: false, } func DangerousConfigAddOptions(prefix string, f *flag.FlagSet) { f.Bool(prefix+".no-l1-listener", DefaultDangerousConfig.NoL1Listener, "DANGEROUS! disables listening to L1. To be used in test nodes only") - f.Bool(prefix+".no-coordinator", DefaultDangerousConfig.NoCoordinator, "DANGEROUS! allows sequencing without sequencer-coordinator") + f.Bool(prefix+".no-sequencer-coordinator", DefaultDangerousConfig.NoSequencerCoordinator, "DANGEROUS! allows sequencing without sequencer-coordinator") } type Node struct { @@ -606,8 +606,8 @@ func createNodeImpl( if err != nil { return nil, err } - } else if config.Sequencer && !config.Dangerous.NoCoordinator { - return nil, errors.New("sequencer must be enabled with coordinator, unless dangerous.no-coordinator set") + } else if config.Sequencer && !config.Dangerous.NoSequencerCoordinator { + return nil, errors.New("sequencer must be enabled with coordinator, unless dangerous.no-sequencer-coordinator set") } dbs := []ethdb.Database{arbDb} maintenanceRunner, err := NewMaintenanceRunner(func() *MaintenanceConfig { return &configFetcher.Get().Maintenance }, coordinator, dbs, exec) @@ -929,11 +929,9 @@ func (n *Node) Start(ctx context.Context) error { if err != nil { return fmt.Errorf("error starting geth stack: %w", err) } - if execClient != nil { - err := execClient.Start(ctx) - if err != nil { - return fmt.Errorf("error starting exec client: %w", err) - } + err = n.Execution.Start(ctx) + if err != nil { + return fmt.Errorf("error starting exec client: %w", err) } if n.InboxTracker != nil { err = n.InboxTracker.Initialize() @@ -1038,12 +1036,8 @@ func (n *Node) Start(ctx context.Context) error { } func (n *Node) StopAndWait() { - execClient, ok := n.Execution.(*gethexec.ExecutionNode) - if !ok { - execClient = nil - } - if execClient != nil { - execClient.StopAndWait() + if n.Execution != nil { + n.Execution.StopAndWait() } if n.MaintenanceRunner != nil && n.MaintenanceRunner.Started() { n.MaintenanceRunner.StopAndWait() diff --git a/arbnode/seq_coordinator.go b/arbnode/seq_coordinator.go index 34197eea7a..2339935e1f 100644 --- a/arbnode/seq_coordinator.go +++ b/arbnode/seq_coordinator.go @@ -132,8 +132,14 @@ var TestSeqCoordinatorConfig = SeqCoordinatorConfig{ Signer: signature.DefaultSignVerifyConfig, } -func NewSeqCoordinator(dataSigner signature.DataSignerFunc, bpvalidator *contracts.BatchPosterVerifier, streamer *TransactionStreamer, sequencer execution.ExecutionSequencer, - sync *SyncMonitor, config SeqCoordinatorConfig) (*SeqCoordinator, error) { +func NewSeqCoordinator( + dataSigner signature.DataSignerFunc, + bpvalidator *contracts.BatchPosterVerifier, + streamer *TransactionStreamer, + sequencer execution.ExecutionSequencer, + sync *SyncMonitor, + config SeqCoordinatorConfig, +) (*SeqCoordinator, error) { redisCoordinator, err := redisutil.NewRedisCoordinator(config.RedisUrl) if err != nil { return nil, err diff --git a/arbnode/sync_monitor.go b/arbnode/sync_monitor.go index bd9b24529c..598ea4fb34 100644 --- a/arbnode/sync_monitor.go +++ b/arbnode/sync_monitor.go @@ -67,12 +67,14 @@ func (s *SyncMonitor) SyncProgressMap() map[string]interface{} { } res["broadcasterQueuedMessagesPos"] = broadcasterQueuedMessagesPos - builtMessageCount, err := s.txStreamer.exec.HeadMessageNumber() + builtMessageCount, err := s.exec.HeadMessageNumber() if err != nil { - res["blockMessageToMessageCountError"] = err.Error() + res["builtMessageCountError"] = err.Error() syncing = true builtMessageCount = 0 } else { + blockNum := s.exec.MessageIndexToBlockNumber(builtMessageCount) + res["blockNum"] = blockNum builtMessageCount++ res["messageOfLastBlock"] = builtMessageCount } diff --git a/cmd/nitro/nitro.go b/cmd/nitro/nitro.go index 560a68b8b5..587cb884dd 100644 --- a/cmd/nitro/nitro.go +++ b/cmd/nitro/nitro.go @@ -203,10 +203,6 @@ func mainImpl() int { fmt.Fprintf(os.Stderr, "Error initializing logging: %v\n", err) return 1 } - if nodeConfig.Execution.Archive { - log.Warn("--node.archive has been deprecated. Please use --node.caching.archive instead.") - nodeConfig.Execution.Caching.Archive = true - } log.Info("Running Arbitrum nitro node", "revision", vcsRevision, "vcs.time", vcsTime) @@ -218,18 +214,12 @@ func mainImpl() int { nodeConfig.Node.ParentChainReader.Enable = true } - if nodeConfig.Execution.Sequencer.Enable { - if nodeConfig.Execution.ForwardingTargetF() != "" { - flag.Usage() - log.Crit("forwarding-target cannot be set when sequencer is enabled") - } - if nodeConfig.Node.ParentChainReader.Enable && nodeConfig.Node.InboxReader.HardReorg { - flag.Usage() - log.Crit("hard reorgs cannot safely be enabled with sequencer mode enabled") - } - } else if nodeConfig.Execution.ForwardingTarget == "" { + if nodeConfig.Execution.Sequencer.Enable && nodeConfig.Node.ParentChainReader.Enable && nodeConfig.Node.InboxReader.HardReorg { flag.Usage() - log.Crit("forwarding-target unset, and not sequencer (can set to \"null\" to disable forwarding)") + log.Crit("hard reorgs cannot safely be enabled with sequencer mode enabled") + } + if nodeConfig.Execution.Sequencer.Enable != nodeConfig.Node.Sequencer { + log.Error("consensus and execution must agree if sequencing is enabled or not", "Execution.Sequencer.Enable", nodeConfig.Execution.Sequencer.Enable, "Node.Sequencer", nodeConfig.Node.Sequencer) } var l1TransactionOpts *bind.TransactOpts @@ -314,7 +304,7 @@ func mainImpl() int { } if nodeConfig.Execution.RPC.MaxRecreateStateDepth == arbitrum.UninitializedMaxRecreateStateDepth { - if nodeConfig.Execution.Archive { + if nodeConfig.Execution.Caching.Archive { nodeConfig.Execution.RPC.MaxRecreateStateDepth = arbitrum.DefaultArchiveNodeMaxRecreateStateDepth } else { nodeConfig.Execution.RPC.MaxRecreateStateDepth = arbitrum.DefaultNonArchiveNodeMaxRecreateStateDepth @@ -764,7 +754,7 @@ func ParseNode(ctx context.Context, args []string) (*NodeConfig, *genericconf.Wa nodeConfig.ParentChain.Wallet = genericconf.WalletConfigDefault nodeConfig.Chain.DevWallet = genericconf.WalletConfigDefault - if nodeConfig.Execution.Archive { + if nodeConfig.Execution.Caching.Archive { nodeConfig.Node.MessagePruner.Enable = false } err = nodeConfig.Validate() diff --git a/execution/gethexec/node.go b/execution/gethexec/node.go index 5176eb28dd..b29309cdbb 100644 --- a/execution/gethexec/node.go +++ b/execution/gethexec/node.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "sync/atomic" "testing" "github.com/ethereum/go-ethereum/arbitrum" @@ -45,25 +46,26 @@ type Config struct { ForwardingTarget string `koanf:"forwarding-target"` Caching CachingConfig `koanf:"caching"` RPC arbitrum.Config `koanf:"rpc"` - Archive bool `koanf:"archive"` TxLookupLimit uint64 `koanf:"tx-lookup-limit"` Dangerous DangerousConfig `koanf:"dangerous"` -} - -func (c *Config) ForwardingTargetF() string { - if c.ForwardingTarget == "null" { - return "" - } - return c.ForwardingTarget + forwardingTarget string } func (c *Config) Validate() error { if err := c.Sequencer.Validate(); err != nil { return err } - if err := c.Sequencer.Validate(); err != nil { - return err + if !c.Sequencer.Enable && c.ForwardingTarget == "" { + return errors.New("ForwardingTarget not set and not sequencer (can use \"null\")") + } + if c.ForwardingTarget == "null" { + c.forwardingTarget = "" + } else { + c.forwardingTarget = c.ForwardingTarget + } + if c.forwardingTarget != "" && c.Sequencer.Enable { + return errors.New("ForwardingTarget set and sequencer enabled") } return nil } @@ -77,8 +79,6 @@ func ConfigAddOptions(prefix string, f *flag.FlagSet) { TxPreCheckerConfigAddOptions(prefix+".tx-pre-checker", f) CachingConfigAddOptions(prefix+".caching", f) f.Uint64(prefix+".tx-lookup-limit", ConfigDefault.TxLookupLimit, "retain the ability to lookup transactions by hash for the past N blocks (0 = all blocks)") - archiveMsg := fmt.Sprintf("retain past block state (deprecated, please use %v.caching.archive)", prefix) - f.Bool(prefix+".archive", ConfigDefault.Archive, archiveMsg) DangerousConfigAddOptions(prefix+".dangerous", f) } @@ -88,7 +88,6 @@ var ConfigDefault = Config{ RecordingDatabase: arbitrum.DefaultRecordingDatabaseConfig, ForwardingTarget: "", TxPreChecker: DefaultTxPreCheckerConfig, - Archive: false, TxLookupLimit: 126_230_400, // 1 year at 4 blocks per second Caching: DefaultCachingConfig, Dangerous: DefaultDangerousConfig, @@ -98,6 +97,9 @@ func ConfigDefaultNonSequencerTest() *Config { config := ConfigDefault config.Sequencer.Enable = false config.Forwarder = DefaultTestForwarderConfig + config.ForwardingTarget = "null" + + _ = config.Validate() return &config } @@ -105,6 +107,9 @@ func ConfigDefaultNonSequencerTest() *Config { func ConfigDefaultTest() *Config { config := ConfigDefault config.Sequencer = TestSequencerConfig + config.ForwardingTarget = "null" + + _ = config.Validate() return &config } @@ -122,6 +127,7 @@ type ExecutionNode struct { TxPublisher TransactionPublisher ConfigFetcher ConfigFetcher ParentChainReader *headerreader.HeaderReader + started atomic.Bool } func CreateExecutionNode( @@ -150,11 +156,7 @@ func CreateExecutionNode( } } - fwTarget := config.ForwardingTargetF() if config.Sequencer.Enable { - if fwTarget != "" { - return nil, errors.New("sequencer and forwarding target both set") - } seqConfigFetcher := func() *SequencerConfig { return &configFetcher().Sequencer } sequencer, err = NewSequencer(execEngine, parentChainReader, seqConfigFetcher) if err != nil { @@ -163,11 +165,11 @@ func CreateExecutionNode( txPublisher = sequencer } else { if config.Forwarder.RedisUrl != "" { - txPublisher = NewRedisTxForwarder(fwTarget, &config.Forwarder) - } else if fwTarget == "" { + txPublisher = NewRedisTxForwarder(config.forwardingTarget, &config.Forwarder) + } else if config.forwardingTarget == "" { txPublisher = NewTxDropper() } else { - txPublisher = NewForwarder(fwTarget, &config.Forwarder) + txPublisher = NewForwarder(config.forwardingTarget, &config.Forwarder) } } @@ -252,7 +254,11 @@ func (n *ExecutionNode) Initialize(ctx context.Context, arbnode interface{}, syn return nil } +// not thread safe func (n *ExecutionNode) Start(ctx context.Context) error { + if n.started.Swap(true) { + return errors.New("already started") + } // TODO after separation // err := n.Stack.Start() // if err != nil { @@ -270,6 +276,9 @@ func (n *ExecutionNode) Start(ctx context.Context) error { } func (n *ExecutionNode) StopAndWait() { + if !n.started.Load() { + return + } // TODO after separation // n.Stack.StopRPC() // does nothing if not running if n.TxPublisher.Started() { @@ -342,7 +351,7 @@ func (n *ExecutionNode) ForwardTo(url string) error { if n.Sequencer != nil { return n.Sequencer.ForwardTo(url) } else { - return errors.New("forwardTo not supported - sequencer not acrtive") + return errors.New("forwardTo not supported - sequencer not active") } } func (n *ExecutionNode) SetTransactionStreamer(streamer execution.TransactionStreamer) { diff --git a/execution/interface.go b/execution/interface.go index e6895bc149..ef9409b9c1 100644 --- a/execution/interface.go +++ b/execution/interface.go @@ -62,6 +62,9 @@ type FullExecutionClient interface { ExecutionRecorder ExecutionSequencer + Start(ctx context.Context) error + StopAndWait() + Maintenance() error // TODO: only used to get safe/finalized block numbers diff --git a/system_tests/common_test.go b/system_tests/common_test.go index a31c354cd6..19357c5b79 100644 --- a/system_tests/common_test.go +++ b/system_tests/common_test.go @@ -797,6 +797,7 @@ func Create2ndNodeWithConfig( AddDefaultValNode(t, ctx, nodeConfig, true) + Require(t, execConfig.Validate()) configFetcher := func() *gethexec.Config { return execConfig } currentExec, err := gethexec.CreateExecutionNode(ctx, l2stack, l2chainDb, l2blockchain, l1client, configFetcher) Require(t, err) diff --git a/system_tests/recreatestate_rpc_test.go b/system_tests/recreatestate_rpc_test.go index 9e23ccdff8..28e72b0653 100644 --- a/system_tests/recreatestate_rpc_test.go +++ b/system_tests/recreatestate_rpc_test.go @@ -338,6 +338,7 @@ func testSkippingSavingStateAndRecreatingAfterRestart(t *testing.T, cacheConfig feedErrChan := make(chan error, 10) l2info, stack, chainDb, arbDb, blockchain := createL2BlockChain(t, nil, t.TempDir(), params.ArbitrumDevTestChainConfig(), &execConfig.Caching) + Require(t, execConfig.Validate()) execConfigFetcher := func() *gethexec.Config { return execConfig } execNode, err := gethexec.CreateExecutionNode(ctx1, stack, chainDb, blockchain, nil, execConfigFetcher) Require(t, err) From e09ddd66f98ded8a6bde960ecb970697d6539848 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Wed, 4 Oct 2023 11:00:05 -0600 Subject: [PATCH 23/23] update geth: for PR review --- go-ethereum | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go-ethereum b/go-ethereum index 59ec2cbc8f..b4221631e1 160000 --- a/go-ethereum +++ b/go-ethereum @@ -1 +1 @@ -Subproject commit 59ec2cbc8fbd7081bd7b35af1b1a7c8b5798f4f6 +Subproject commit b4221631e1e5eac86f01582bd74234e3c0f7f5c7