From 1d2a7b9691689c1948a804359eac20917703e654 Mon Sep 17 00:00:00 2001 From: Louis Ponet Date: Sun, 18 May 2025 12:11:30 +0100 Subject: [PATCH 1/5] keep fetching from registry --- Makefile | 4 ++-- based/crates/common/src/config.rs | 4 ++-- based/crates/rpc/src/gossiper.rs | 10 +++------- optimism/op-node/node/node.go | 22 ++++++++++++---------- 4 files changed, 19 insertions(+), 21 deletions(-) diff --git a/Makefile b/Makefile index b6e675458..1f96a17c8 100644 --- a/Makefile +++ b/Makefile @@ -470,10 +470,10 @@ FOLLOWER_NODE_HOST?=http://localhost BLOCK_NUMBER?=$(shell echo $$(( $$(cast block-number --rpc-url http://localhost:$(BOP_EL_PORT)) + 1 ))) DUMMY_RICH_WALLET_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 DUMMY_TX=$(shell cast mktx --rpc-url $(FOLLOWER_NODE_HOST):$(BOP_EL_PORT) --private-key $(DUMMY_RICH_WALLET_PRIVATE_KEY) --value 1 0x7DDcC7c49D562997A68C98ae7Bb62eD1E8E4488a | xxd -r -p | base64) -PORTAL_PORT?=8080 +LOCAL_GETH_PORT?=8645 test-tx: - cast send --rpc-url http://127.0.0.1:$(PORTAL_PORT) --private-key $(DUMMY_RICH_WALLET_PRIVATE_KEY) --value 1 0x7DDcC7c49D562997A68C98ae7Bb62eD1E8E4488a + cast send --rpc-url http://0.0.0.0:$(LOCAL_GETH_PORT) --private-key $(DUMMY_RICH_WALLET_PRIVATE_KEY) --value 1 0x7DDcC7c49D562997A68C98ae7Bb62eD1E8E4488a test-frag: curl --request POST --url $(FOLLOWER_NODE_HOST):$(BOP_NODE_PORT) --header 'Content-Type: application/json' \ diff --git a/based/crates/common/src/config.rs b/based/crates/common/src/config.rs index 576148d5e..f880f7bba 100644 --- a/based/crates/common/src/config.rs +++ b/based/crates/common/src/config.rs @@ -40,8 +40,8 @@ pub struct GatewayArgs { #[arg(long = "eth_client.url", default_value = "http://localhost:8545")] pub eth_client_url: Url, /// Url to the root peer gossip node - #[arg(long = "gossip.root_peer_url")] - pub gossip_root_peer_url: Option, + #[arg(long = "gossip.root_peer_url", default_value = "http://localhost:8547")] + pub gossip_root_peer_url: Url, /// Gossip to sign frag messages #[arg(long = "gossip.signer_private_key")] pub gossip_signer_private_key: Option, diff --git a/based/crates/rpc/src/gossiper.rs b/based/crates/rpc/src/gossiper.rs index bbec837f6..cce2edbae 100644 --- a/based/crates/rpc/src/gossiper.rs +++ b/based/crates/rpc/src/gossiper.rs @@ -4,13 +4,13 @@ use reqwest::blocking::{Client, ClientBuilder}; use tracing::{error, info}; pub struct Gossiper { - target_rpc: Option, + target_rpc: Url, client: Client, signer: ECDSASigner, } impl Gossiper { - pub fn new(target_rpc: Option, signer: Option) -> Self { + pub fn new(target_rpc: Url, signer: Option) -> Self { let client = ClientBuilder::new() .timeout(std::time::Duration::from_secs(10)) .build() @@ -22,13 +22,9 @@ impl Gossiper { } fn gossip(&self, msg: p2p::VersionedMessage) { - let Some(url) = self.target_rpc.as_ref().cloned() else { - return; - }; - let payload = msg.to_json(&self.signer); - let Ok(res) = self.client.post(url).json(&payload).send() else { + let Ok(res) = self.client.post(self.target_rpc.clone()).json(&payload).send() else { tracing::error!("couldn't send {}", payload); return; }; diff --git a/optimism/op-node/node/node.go b/optimism/op-node/node/node.go index 21dff965f..6df0059c3 100644 --- a/optimism/op-node/node/node.go +++ b/optimism/op-node/node/node.go @@ -254,6 +254,18 @@ func (n *OpNode) initRegistry(ctx context.Context, cfg *Config) error { return fmt.Errorf("failed to fetch initial gateways: %w", err) } + // Start fetching future gateways + go func() { + for { + fetchCtx, cancel := context.WithTimeout(context.Background(), time.Second*10) + defer cancel() + + if err := n.registrySource.FetchNextNGateways(fetchCtx, 2, 3); err != nil { + n.log.Warn("registry fetch error", "err", err) + } + } + }() + return nil } @@ -765,16 +777,6 @@ func (n *OpNode) OnSealFrag(ctx context.Context, from peer.ID, seal *eth.SignedS n.log.Info("Received new seal", "seal", seal) n.preconfChannels.SendSeal(seal) - // Start fetching future gateways - go func() { - fetchCtx, cancel := context.WithTimeout(context.Background(), time.Second*10) - defer cancel() - - if err := n.registrySource.FetchNextNGateways(fetchCtx, 2, 3); err != nil { - n.log.Warn("registry fetch error", "err", err) - } - }() - return nil } From 47192b0d4b939e8b10cdc2d348fd10ff4ec194e0 Mon Sep 17 00:00:00 2001 From: Louis Ponet Date: Sun, 18 May 2025 12:33:11 +0100 Subject: [PATCH 2/5] sleep --- optimism/op-node/node/node.go | 1 + 1 file changed, 1 insertion(+) diff --git a/optimism/op-node/node/node.go b/optimism/op-node/node/node.go index 6df0059c3..3a456f443 100644 --- a/optimism/op-node/node/node.go +++ b/optimism/op-node/node/node.go @@ -263,6 +263,7 @@ func (n *OpNode) initRegistry(ctx context.Context, cfg *Config) error { if err := n.registrySource.FetchNextNGateways(fetchCtx, 2, 3); err != nil { n.log.Warn("registry fetch error", "err", err) } + time.Sleep(time.Second) } }() From e3a77b3c9bee0fc21f219d52074d98f99fbc2a59 Mon Sep 17 00:00:00 2001 From: Louis Ponet Date: Sun, 18 May 2025 13:40:51 +0100 Subject: [PATCH 3/5] always drive elsync --- optimism/op-node/rollup/engine/engine_controller.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/optimism/op-node/rollup/engine/engine_controller.go b/optimism/op-node/rollup/engine/engine_controller.go index 2a3057a92..6fee5c51c 100644 --- a/optimism/op-node/rollup/engine/engine_controller.go +++ b/optimism/op-node/rollup/engine/engine_controller.go @@ -141,7 +141,8 @@ func (e *EngineController) BackupUnsafeL2Head() eth.L2BlockRef { } func (e *EngineController) IsEngineSyncing() bool { - return e.syncStatus == syncStatusWillStartEL || e.syncStatus == syncStatusStartedEL || e.syncStatus == syncStatusFinishedELButNotFinalized + // return e.syncStatus == syncStatusWillStartEL || e.syncStatus == syncStatusStartedEL || e.syncStatus == syncStatusFinishedELButNotFinalized + return true } // Setters From 1b0518f038eb00b005d76c51f88ab32d9fa3f38c Mon Sep 17 00:00:00 2001 From: Louis Ponet Date: Sun, 18 May 2025 14:58:15 +0100 Subject: [PATCH 4/5] fixes for tx pool + registry fetch + syncmode --- based/bin/overseer/src/collections.rs | 5 +++ based/bin/overseer/src/data/frag.rs | 1 + based/crates/pool/src/transaction/pool.rs | 17 +++----- based/crates/sequencer/src/context.rs | 43 ++++++++++--------- .../sequencer/src/sorting/sorting_data.rs | 2 +- follower_node/compose.yml | 1 + 6 files changed, 36 insertions(+), 33 deletions(-) diff --git a/based/bin/overseer/src/collections.rs b/based/bin/overseer/src/collections.rs index cc7a35623..344f5b30a 100644 --- a/based/bin/overseer/src/collections.rs +++ b/based/bin/overseer/src/collections.rs @@ -373,6 +373,7 @@ impl KeyedCircularBuffer { pub fn new(size: usize) -> Self { Self { data: CircularBuffer::new(size), ids: HashMap::new(), count: 0 } } + } impl KeyedCircularBuffer { @@ -400,6 +401,10 @@ impl KeyedCircularBuffer { self.data.iter() } + #[inline] + pub fn len(&self) -> usize { + self.data.len() + } #[inline] pub fn is_empty(&self) -> bool { self.count == 0 diff --git a/based/bin/overseer/src/data/frag.rs b/based/bin/overseer/src/data/frag.rs index ff3e747e3..e826c8009 100644 --- a/based/bin/overseer/src/data/frag.rs +++ b/based/bin/overseer/src/data/frag.rs @@ -40,6 +40,7 @@ impl FragData { pub fn to_block_table_row(&self) -> Vec> { let Frag::SorterStart { seq, .. } = &self.updates[0].1 else { + tracing::warn!("strange frag setup"); return vec![]; }; let (payment, gas_used, n_txs) = self.frag_stats().unwrap_or_default(); diff --git a/based/crates/pool/src/transaction/pool.rs b/based/crates/pool/src/transaction/pool.rs index 2eeebf87b..8d266a6bb 100644 --- a/based/crates/pool/src/transaction/pool.rs +++ b/based/crates/pool/src/transaction/pool.rs @@ -18,7 +18,7 @@ pub struct TxPool { /// maps an eoa to all pending txs pool_data: HashMap, /// Current list of all simulated mineable txs in the pool - active_txs: Active, + pub active_txs: Active, } impl TxPool { @@ -39,12 +39,12 @@ impl TxPool { base_fee: u64, syncing: bool, sim_sender: Option<&SendersSpine>, - ) { + ) -> bool { let state_nonce = db.get_nonce(new_tx.sender()).expect("handle failed db"); let nonce = new_tx.nonce(); // check nonce is valid if nonce < state_nonce { - return; + return false; } let is_next_nonce = nonce == state_nonce; @@ -57,7 +57,7 @@ impl TxPool { // above where we didn't return if tx_list.get_effective_price_for_nonce(&nonce, base_fee) > new_tx.effective_gas_price(Some(base_fee)) { - return; + return false; } tx_list.put(new_tx.clone()); @@ -92,6 +92,7 @@ impl TxPool { self.pool_data.insert(tx_list.sender(), tx_list); } } + true } /// Validates simualted tx. If valid, fetch its TxList and save the new [SimulatedTxList] to `active_txs`. @@ -152,19 +153,13 @@ impl TxPool { /// This gets called in two places: /// 1) When we sync a new block. /// 2) When we commit a new Frag. - pub fn handle_new_block<'a, Db: DatabaseRead, T: TransactionSenderInfo + 'a>( + pub fn handle_new_block<'a, Db: DatabaseRead>( &mut self, - mined_txs: impl Iterator, base_fee: u64, db: &DBFrag, syncing: bool, sim_sender: Option<&SendersSpine>, - telemetry_producer: &mut Producer, ) { - // Completely wipe active txs as they may contain valid nonces with out of date sim results. - self.active_txs.clear(); - self.remove_mined_txs(mined_txs, telemetry_producer); - // If enabled, fill the active list with non-simulated txs and send off the first tx for each sender to // simulator. if !syncing { diff --git a/based/crates/sequencer/src/context.rs b/based/crates/sequencer/src/context.rs index 58e966aed..a3f8f7cdf 100644 --- a/based/crates/sequencer/src/context.rs +++ b/based/crates/sequencer/src/context.rs @@ -167,14 +167,15 @@ impl + Display>> Sequence self.deposits.push_back(tx); return; } - TelemetryUpdate::send(tx.uuid, tx.to_added_to_pool_telemetry(), &mut self.telemetry); - self.tx_pool.handle_new_tx( + if self.tx_pool.handle_new_tx( tx.clone(), self.shared_state.as_ref(), self.as_ref().basefee.to(), false, self.config.simulate_tof_in_pools.then_some(senders), - ); + ) { + TelemetryUpdate::send(tx.uuid, tx.to_added_to_pool_telemetry(), &mut self.telemetry); + } } /// Processes a new block from the sequencer by: @@ -306,17 +307,20 @@ impl + Display>> Sequence frag_seq.txs.len(), mgas / frag_seq.start_t.elapsed().as_secs() ); - (seal, OpExecutionPayloadEnvelopeV3 { - execution_payload: ExecutionPayloadV3 { - payload_inner: ExecutionPayloadV2 { payload_inner: v1, withdrawals: vec![] }, - blob_gas_used: 0, - excess_blob_gas: 0, + ( + seal, + OpExecutionPayloadEnvelopeV3 { + execution_payload: ExecutionPayloadV3 { + payload_inner: ExecutionPayloadV2 { payload_inner: v1, withdrawals: vec![] }, + blob_gas_used: 0, + excess_blob_gas: 0, + }, + block_value: frag_seq.payment.to(), + blobs_bundle: BlobsBundleV1::new(vec![]), + should_override_builder: false, + parent_beacon_block_root: parent_beacon_block_root.expect("should always be set"), }, - block_value: frag_seq.payment.to(), - blobs_bundle: BlobsBundleV1::new(vec![]), - should_override_builder: false, - parent_beacon_block_root: parent_beacon_block_root.expect("should always be set"), - }) + ) } } impl SequencerContext { @@ -337,17 +341,14 @@ impl SequencerContext { self.parent_header = block.header.clone(); self.parent_hash = block.hash_slow(); + // Completely wipe active txs as they may contain valid nonces with out of date sim results. + self.tx_pool.active_txs.clear(); + self.tx_pool.remove_mined_txs(block.body.transactions.iter(), &mut self.telemetry); + if let Some(base_fee) = block.base_fee_per_gas { self.base_fee = base_fee; - self.tx_pool.handle_new_block( - block.body.transactions.iter(), - base_fee, - self.shared_state.as_ref(), - false, - None, - &mut self.telemetry, - ); + self.tx_pool.handle_new_block(base_fee, self.shared_state.as_ref(), false, None); } blocks_to_fetch diff --git a/based/crates/sequencer/src/sorting/sorting_data.rs b/based/crates/sequencer/src/sorting/sorting_data.rs index 433b66c56..9589fa28b 100644 --- a/based/crates/sequencer/src/sorting/sorting_data.rs +++ b/based/crates/sequencer/src/sorting/sorting_data.rs @@ -141,7 +141,7 @@ impl SortingData { txs: vec![], start_t: Instant::now(), telemetry: Default::default(), - uuid: Uuid::new_v4(), + uuid, telemetry_producer, } } diff --git a/follower_node/compose.yml b/follower_node/compose.yml index c46a66bc8..f89416ec9 100644 --- a/follower_node/compose.yml +++ b/follower_node/compose.yml @@ -73,6 +73,7 @@ services: - --rpc.enable-based - --registry=$PORTAL - --p2p.bootnodes=$MAIN_OP_NODE_ENR + - --syncmode=execution-layer volumes: - ./data/node:/data/op-node - ./config:/config From b284f53df39691010add88a7307d66f5376d4120 Mon Sep 17 00:00:00 2001 From: Louis Ponet Date: Sun, 18 May 2025 14:59:36 +0100 Subject: [PATCH 5/5] clippy and fmt --- based/bin/overseer/src/collections.rs | 5 ----- based/crates/pool/src/transaction/pool.rs | 2 +- based/crates/sequencer/src/context.rs | 23 ++++++++++------------- 3 files changed, 11 insertions(+), 19 deletions(-) diff --git a/based/bin/overseer/src/collections.rs b/based/bin/overseer/src/collections.rs index 344f5b30a..cc7a35623 100644 --- a/based/bin/overseer/src/collections.rs +++ b/based/bin/overseer/src/collections.rs @@ -373,7 +373,6 @@ impl KeyedCircularBuffer { pub fn new(size: usize) -> Self { Self { data: CircularBuffer::new(size), ids: HashMap::new(), count: 0 } } - } impl KeyedCircularBuffer { @@ -401,10 +400,6 @@ impl KeyedCircularBuffer { self.data.iter() } - #[inline] - pub fn len(&self) -> usize { - self.data.len() - } #[inline] pub fn is_empty(&self) -> bool { self.count == 0 diff --git a/based/crates/pool/src/transaction/pool.rs b/based/crates/pool/src/transaction/pool.rs index 8d266a6bb..228643332 100644 --- a/based/crates/pool/src/transaction/pool.rs +++ b/based/crates/pool/src/transaction/pool.rs @@ -153,7 +153,7 @@ impl TxPool { /// This gets called in two places: /// 1) When we sync a new block. /// 2) When we commit a new Frag. - pub fn handle_new_block<'a, Db: DatabaseRead>( + pub fn handle_new_block( &mut self, base_fee: u64, db: &DBFrag, diff --git a/based/crates/sequencer/src/context.rs b/based/crates/sequencer/src/context.rs index a3f8f7cdf..ecc0ad658 100644 --- a/based/crates/sequencer/src/context.rs +++ b/based/crates/sequencer/src/context.rs @@ -307,20 +307,17 @@ impl + Display>> Sequence frag_seq.txs.len(), mgas / frag_seq.start_t.elapsed().as_secs() ); - ( - seal, - OpExecutionPayloadEnvelopeV3 { - execution_payload: ExecutionPayloadV3 { - payload_inner: ExecutionPayloadV2 { payload_inner: v1, withdrawals: vec![] }, - blob_gas_used: 0, - excess_blob_gas: 0, - }, - block_value: frag_seq.payment.to(), - blobs_bundle: BlobsBundleV1::new(vec![]), - should_override_builder: false, - parent_beacon_block_root: parent_beacon_block_root.expect("should always be set"), + (seal, OpExecutionPayloadEnvelopeV3 { + execution_payload: ExecutionPayloadV3 { + payload_inner: ExecutionPayloadV2 { payload_inner: v1, withdrawals: vec![] }, + blob_gas_used: 0, + excess_blob_gas: 0, }, - ) + block_value: frag_seq.payment.to(), + blobs_bundle: BlobsBundleV1::new(vec![]), + should_override_builder: false, + parent_beacon_block_root: parent_beacon_block_root.expect("should always be set"), + }) } } impl SequencerContext {