From 587f6208a717cc362eb399e54005fb4093bcf8e3 Mon Sep 17 00:00:00 2001 From: evalir Date: Thu, 29 May 2025 18:16:03 +0200 Subject: [PATCH 01/11] chore(deps): upgrade to latest alloy/sdk/trevm Closes ENG-1109 From 44b50ff0dbe6fefbb24fd2c6c2236d07a829856c Mon Sep 17 00:00:00 2001 From: dylan Date: Fri, 16 May 2025 16:37:20 -0600 Subject: [PATCH 02/11] refactors: submit channel refactors --- src/tasks/submit.rs | 232 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 187 insertions(+), 45 deletions(-) diff --git a/src/tasks/submit.rs b/src/tasks/submit.rs index 7f9a1dd..02ea51d 100644 --- a/src/tasks/submit.rs +++ b/src/tasks/submit.rs @@ -4,7 +4,7 @@ use crate::{ utils::extract_signature_components, }; use alloy::{ - consensus::{SimpleCoder, constants::GWEI_TO_WEI}, + consensus::{SimpleCoder, Transaction, constants::GWEI_TO_WEI}, eips::BlockNumberOrTag, network::{TransactionBuilder, TransactionBuilder4844}, primitives::{FixedBytes, TxHash, U256}, @@ -22,9 +22,9 @@ use signet_sim::BuiltBlock; use signet_types::{SignRequest, SignResponse}; use signet_zenith::{ BundleHelper::{self, BlockHeader, FillPermit2, submitCall}, - Zenith::IncorrectHostBlock, + Zenith::{self, IncorrectHostBlock}, }; -use std::time::Instant; +use std::time::{Instant, UNIX_EPOCH}; use tokio::{sync::mpsc, task::JoinHandle}; macro_rules! spawn_provider_send { @@ -53,17 +53,14 @@ pub enum ControlFlow { } /// Submits sidecars in ethereum txns to mainnet ethereum -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct SubmitTask { /// Zenith pub zenith: ZenithInstance, - /// Quincey pub quincey: Quincey, - /// Config pub config: crate::config::BuilderConfig, - /// Channel over which to send pending transactions pub outbound_tx_channel: mpsc::UnboundedSender, } @@ -99,47 +96,69 @@ impl SubmitTask { v: u8, r: FixedBytes<32>, s: FixedBytes<32>, - in_progress: &BuiltBlock, + block: &BuiltBlock, ) -> eyre::Result { let data = submitCall { fills, header, v, r, s }.abi_encode(); - let sidecar = in_progress.encode_blob::().build()?; + let sidecar = block.encode_blob::().build()?; Ok(TransactionRequest::default() .with_blob_sidecar(sidecar) .with_input(data) .with_max_priority_fee_per_gas((GWEI_TO_WEI * 16) as u128)) } - /// Returns the next host block height + /// Returns the next host block height. async fn next_host_block_height(&self) -> eyre::Result { let result = self.provider().get_block_number().await?; let next = result.checked_add(1).ok_or_else(|| eyre!("next host block height overflow"))?; Ok(next) } - /// Submits the EIP 4844 transaction to the network + /// Prepares and then sends the EIP-4844 transaction with a sidecar encoded with a rollup block to the network. async fn submit_transaction( &self, + retry_count: usize, resp: &SignResponse, - in_progress: &BuiltBlock, + block: &BuiltBlock, ) -> eyre::Result { + let tx = self.prepare_tx(retry_count, resp, block).await?; + + self.send_transaction(resp, tx).await + } + + /// Prepares the transaction by extracting the signature components, creating the transaction + /// request, and simulating the transaction with a call to the host provider. + async fn prepare_tx( + &self, + retry_count: usize, + resp: &SignResponse, + block: &BuiltBlock, + ) -> Result { + // Extract the signature components from the response let (v, r, s) = extract_signature_components(&resp.sig); - let header = BlockHeader { - hostBlockNumber: resp.req.host_block_number, - rollupChainId: U256::from(self.config.ru_chain_id), - gasLimit: resp.req.gas_limit, - rewardAddress: resp.req.ru_reward_address, - blockDataHash: *in_progress.contents_hash(), - }; + // Create the transaction request with the signature values + let tx: TransactionRequest = self.tx_request(retry_count, resp, block, v, r, s).await?; - let fills = vec![]; // NB: ignored until fills are implemented - let tx = self - .build_blob_tx(fills, header, v, r, s, in_progress)? - .with_from(self.provider().default_signer_address()) - .with_to(self.config.builder_helper_address) - .with_gas_limit(1_000_000); + // Simulate the transaction with a call to the host provider + if let Some(maybe_error) = self.sim_with_call(&tx).await { + warn!( + error = ?maybe_error, + "error in transaction simulation" + ); + if let Err(e) = maybe_error { + return Err(e); + } + } + + Ok(tx) + } + /// Simulates the transaction with a call to the host provider to check for reverts. + async fn sim_with_call( + &self, + tx: &TransactionRequest, + ) -> Option> { if let Err(TransportError::ErrorResp(e)) = self.provider().call(tx.clone()).block(BlockNumberOrTag::Pending.into()).await { @@ -154,16 +173,79 @@ impl SubmitTask { .map(|data| data.starts_with(&IncorrectHostBlock::SELECTOR)) .unwrap_or_default() { - return Ok(ControlFlow::Retry); + debug!(%e, "incorrect host block"); + return Some(Ok(ControlFlow::Retry)); } - return Ok(ControlFlow::Skip); + if e.as_revert_data() + .map(|data| data.starts_with(&Zenith::BadSignature::SELECTOR)) + .unwrap_or_default() + { + debug!(%e, "bad signature"); + return Some(Ok(ControlFlow::Skip)); + } + + if e.as_revert_data() + .map(|data| data.starts_with(&Zenith::OneRollupBlockPerHostBlock::SELECTOR)) + .unwrap_or_default() + { + debug!(%e, "one rollup block per host block"); + return Some(Ok(ControlFlow::Skip)); + } + + return Some(Ok(ControlFlow::Skip)); } - // All validation checks have passed, send the transaction - self.send_transaction(resp, tx).await + debug!(?tx, "successfully simulated transaction request"); + None } + /// Creates a transaction request for the blob with the given header and signature values. + async fn tx_request( + &self, + retry_count: usize, + resp: &SignResponse, + block: &BuiltBlock, + v: u8, + r: FixedBytes<32>, + s: FixedBytes<32>, + ) -> Result { + // TODO: ENG-1082 Implement fills + let fills = vec![]; + + // Bump gas with each retry to replace the previous transaction while maintaining the same nonce + let gas_coefficient = 10 * (retry_count + 1) as u64; + let gas_limit = 1_000_000 + (gas_coefficient * 1_000_000); + debug!(retry_count, gas_coefficient, gas_limit, "calculated gas limit"); + + // Build the block header + let header: BlockHeader = BlockHeader { + hostBlockNumber: resp.req.host_block_number, + rollupChainId: U256::from(self.config.ru_chain_id), + gasLimit: resp.req.gas_limit, + rewardAddress: resp.req.ru_reward_address, + blockDataHash: *block.contents_hash(), + }; + debug!(?header, "built block header"); + + // manually retrieve nonce + let nonce = + self.provider().get_transaction_count(self.provider().default_signer_address()).await?; + debug!(nonce, "manually setting transaction nonce"); + + // Create a blob transaction with the blob header and signature values and return it + let tx = self + .build_blob_tx(fills, header, v, r, s, block)? + .with_from(self.provider().default_signer_address()) + .with_to(self.config.builder_helper_address) + .with_gas_limit(gas_limit); + + debug!(?tx, "prepared transaction request"); + Ok(tx) + } + + /// Fills the transaction request with the provider and sends it to the network + /// and any additionally configured broadcast providers. async fn send_transaction( &self, resp: &SignResponse, @@ -172,17 +254,21 @@ impl SubmitTask { debug!( host_block_number = %resp.req.host_block_number, gas_limit = %resp.req.gas_limit, + nonce = ?tx.nonce, "sending transaction to network" ); + + // assign the nonce and fill the rest of the values let SendableTx::Envelope(tx) = self.provider().fill(tx).await? else { bail!("failed to fill transaction") }; + debug!(tx_hash = %tx.tx_hash(), nonce = ?tx.nonce(), gas_limit = ?tx.gas_limit(), blob_gas_used = ?tx.blob_gas_used(), "filled blob transaction"); - // Send the tx via the primary host_provider + // send the tx via the primary host_provider let fut = spawn_provider_send!(self.provider(), &tx); - // Spawn send_tx futures for all additional broadcast host_providers + // spawn send_tx futures for all additional broadcast host_providers for host_provider in self.config.connect_additional_broadcast() { spawn_provider_send!(&host_provider, &tx); } @@ -209,9 +295,14 @@ impl SubmitTask { Ok(ControlFlow::Done) } + /// Handles the inbound block by constructing a signature request and submitting the transaction. #[instrument(skip_all)] - async fn handle_inbound(&self, block: &BuiltBlock) -> eyre::Result { - info!(txns = block.tx_count(), "handling inbound block"); + async fn handle_inbound( + &self, + retry_count: usize, + block: &BuiltBlock, + ) -> eyre::Result { + info!(retry_count, txns = block.tx_count(), "handling inbound block"); let Ok(sig_request) = self.construct_sig_request(block).await.inspect_err(|e| { error!(error = %e, "error constructing signature request"); }) else { @@ -226,9 +317,10 @@ impl SubmitTask { let signed = self.quincey.get_signature(&sig_request).await?; - self.submit_transaction(&signed, block).await + self.submit_transaction(retry_count, &signed, block).await } + /// Handles the retry logic for the inbound block. async fn retrying_handle_inbound( &self, block: &BuiltBlock, @@ -236,37 +328,65 @@ impl SubmitTask { ) -> eyre::Result { let mut retries = 0; let building_start_time = Instant::now(); + let (current_slot, start, end) = self.calculate_slot_window()?; + debug!(current_slot, start, end, "calculating target slot window"); + // Retry loop let result = loop { let span = debug_span!("SubmitTask::retrying_handle_inbound", retries); + debug!(retries, "number of retries"); - let result = - self.handle_inbound(block).instrument(span.clone()).await.inspect_err(|e| { - error!(error = %e, "error handling inbound block"); - })?; + let inbound_result = match self.handle_inbound(retries, block).instrument(span.clone()).await { + Ok(control_flow) => { + debug!(?control_flow, retries, "successfully handled inbound block"); + control_flow + } + Err(err) => { + retries += 1; + error!(error = %err, "error handling inbound block"); + + if err.to_string().contains("403") { + debug!("403 error - skipping block"); + let (slot_number, start, end) = self.calculate_slot_window()?; + debug!(slot_number, start, end, "403 sleep until skipping block"); + // TODO: Sleep until the end of the next slot and return retry + return Ok(ControlFlow::Done); + } + ControlFlow::Retry + } + }; let guard = span.entered(); - match result { + match inbound_result { ControlFlow::Retry => { - retries += 1; if retries > retry_limit { counter!("builder.building_too_many_retries").increment(1); + debug!("retries exceeded - skipping block"); return Ok(ControlFlow::Skip); } - error!("error handling inbound block: retrying"); drop(guard); - tokio::time::sleep(tokio::time::Duration::from_secs(2)).await; + // Detect a slot change and break out of the loop in that case too + let (this_slot, start, end) = self.calculate_slot_window()?; + if this_slot != current_slot { + debug!("slot changed - skipping block"); + break inbound_result; + } + + // Otherwise retry the block + debug!(retries, this_slot, start, end, "retrying block"); continue; } ControlFlow::Skip => { counter!("builder.skipped_blocks").increment(1); - break result; + debug!(retries, "skipping block"); + break inbound_result; } ControlFlow::Done => { counter!("builder.submitted_successful_blocks").increment(1); - break result; + debug!(retries, "successfully submitted block"); + break inbound_result; } } }; @@ -278,16 +398,38 @@ impl SubmitTask { Ok(result) } + /// Calculates and returns the slot number and its start and end timestamps for the current instant. + fn calculate_slot_window(&self) -> eyre::Result<(u64, u64, u64)> { + let now_ts = self.now(); + let current_slot = self.config.slot_calculator.calculate_slot(now_ts); + let (start, end) = self.config.slot_calculator.calculate_slot_window(current_slot); + Ok((current_slot, start, end)) + } + + /// Returns the current timestamp in seconds since the UNIX epoch. + fn now(&self) -> u64 { + let now = std::time::SystemTime::now(); + now.duration_since(UNIX_EPOCH).unwrap().as_secs() + } + + /// Task future for the submit task async fn task_future(self, mut inbound: mpsc::UnboundedReceiver) { loop { let Some(block) = inbound.recv().await else { debug!("upstream task gone"); break; }; + debug!(?block, "submit channel received block"); + + // TODO: Pass a BlockEnv to this function to give retrying handle inbound access to the block + // env and thus the block number so that we can be sure that we try for only our assigned slots. + // Instead this needs to fire off a task that attempts to land the block for the given slot + // Once that slot is up, it's invalid for the next anyway, so this job can be ephemeral. if self.retrying_handle_inbound(&block, 3).await.is_err() { + debug!("error handling inbound block"); continue; - } + }; } } From 1b376b0d5b37ab2099dafdd109a57d834f213b7c Mon Sep 17 00:00:00 2001 From: dylan Date: Mon, 19 May 2025 22:18:29 -0600 Subject: [PATCH 03/11] wip: detect and sleep during 403 slots --- src/tasks/block/sim.rs | 12 ++++----- src/tasks/submit.rs | 57 +++++++++++++++++++++++++++++++----------- 2 files changed, 48 insertions(+), 21 deletions(-) diff --git a/src/tasks/block/sim.rs b/src/tasks/block/sim.rs index dad6482..a663dcd 100644 --- a/src/tasks/block/sim.rs +++ b/src/tasks/block/sim.rs @@ -82,7 +82,7 @@ impl Simulator { block: BlockEnv, ) -> eyre::Result { let db = self.create_db().await.unwrap(); - + let number = block.number; let block_build: BlockBuild<_, NoOpInspector> = BlockBuild::new( db, constants, @@ -94,10 +94,11 @@ impl Simulator { self.config.rollup_block_gas_limit, ); - let block = block_build.build().await; - debug!(block = ?block, "finished block simulation"); + let mut built_block = block_build.build().await; + built_block.set_block_number(number); + debug!(block = ?built_block, "finished block simulation"); - Ok(block) + Ok(built_block) } /// Spawns the simulator task, which handles the setup and sets the deadline @@ -155,8 +156,7 @@ impl Simulator { // If no env, skip this run let Some(block_env) = self.block_env.borrow_and_update().clone() else { return }; - - debug!(block_env = ?block_env, "building on block"); + debug!(block_env = ?block_env, "building on block env"); match self.handle_build(constants, sim_cache, finish_by, block_env).await { Ok(block) => { diff --git a/src/tasks/submit.rs b/src/tasks/submit.rs index 02ea51d..4b06354 100644 --- a/src/tasks/submit.rs +++ b/src/tasks/submit.rs @@ -111,6 +111,7 @@ impl SubmitTask { async fn next_host_block_height(&self) -> eyre::Result { let result = self.provider().get_block_number().await?; let next = result.checked_add(1).ok_or_else(|| eyre!("next host block height overflow"))?; + debug!(next, "next host block height"); Ok(next) } @@ -146,9 +147,7 @@ impl SubmitTask { error = ?maybe_error, "error in transaction simulation" ); - if let Err(e) = maybe_error { - return Err(e); - } + maybe_error?; } Ok(tx) @@ -257,7 +256,6 @@ impl SubmitTask { nonce = ?tx.nonce, "sending transaction to network" ); - // assign the nonce and fill the rest of the values let SendableTx::Envelope(tx) = self.provider().fill(tx).await? else { @@ -285,6 +283,9 @@ impl SubmitTask { return Ok(ControlFlow::Skip); } + // Okay so the code gets all the way to this log + // but we don't see the tx hash in the logs or in the explorer, + // not even as a failed TX, just not at all. info!( tx_hash = %tx.tx_hash(), ru_chain_id = %resp.req.ru_chain_id, @@ -336,22 +337,31 @@ impl SubmitTask { let span = debug_span!("SubmitTask::retrying_handle_inbound", retries); debug!(retries, "number of retries"); - let inbound_result = match self.handle_inbound(retries, block).instrument(span.clone()).await { + let inbound_result = match self + .handle_inbound(retries, block) + .instrument(span.clone()) + .await + { Ok(control_flow) => { debug!(?control_flow, retries, "successfully handled inbound block"); control_flow } Err(err) => { + // Log the retry attempt retries += 1; error!(error = %err, "error handling inbound block"); + // Delay until next slot if we get a 403 error if err.to_string().contains("403") { - debug!("403 error - skipping block"); - let (slot_number, start, end) = self.calculate_slot_window()?; - debug!(slot_number, start, end, "403 sleep until skipping block"); - // TODO: Sleep until the end of the next slot and return retry - return Ok(ControlFlow::Done); + let (slot_number, _, end) = self.calculate_slot_window()?; + let now = self.now(); + if end > now { + let sleep_duration = std::time::Duration::from_secs(end - now); + debug!(sleep_duration = ?sleep_duration, slot_number, "403 detected - sleeping until end of slot"); + tokio::time::sleep(sleep_duration).await; + } } + ControlFlow::Retry } }; @@ -413,19 +423,36 @@ impl SubmitTask { } /// Task future for the submit task + /// NB: This task assumes that the simulator will only send it blocks for + /// slots that it's assigned. async fn task_future(self, mut inbound: mpsc::UnboundedReceiver) { + // Holds a reference to the last block we attempted to submit + let mut last_block_attempted: u64 = 0; + loop { + // Wait to receive a new block let Some(block) = inbound.recv().await else { debug!("upstream task gone"); break; }; - debug!(?block, "submit channel received block"); + debug!(block_number = block.block_number(), ?block, "submit channel received block"); + + // Check if a block number was set and skip if not + if block.block_number() == 0 { + debug!("block number is 0 - skipping"); + continue; + } + + // Only attempt each block number once + if block.block_number() == last_block_attempted { + debug!("block number is unchanged from last attempt - skipping"); + continue; + } - // TODO: Pass a BlockEnv to this function to give retrying handle inbound access to the block - // env and thus the block number so that we can be sure that we try for only our assigned slots. + // This means we have encountered a new block, so reset the last block attempted + last_block_attempted = block.block_number(); + debug!(last_block_attempted, "resetting last block attempted"); - // Instead this needs to fire off a task that attempts to land the block for the given slot - // Once that slot is up, it's invalid for the next anyway, so this job can be ephemeral. if self.retrying_handle_inbound(&block, 3).await.is_err() { debug!("error handling inbound block"); continue; From 6c2ed5390dd24e870153bafe4d83480214d7edba Mon Sep 17 00:00:00 2001 From: dylan Date: Tue, 20 May 2025 13:42:43 -0600 Subject: [PATCH 04/11] wip: adjusting mpfpg and gas limit to replace transaction in pool --- src/tasks/submit.rs | 57 +++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/src/tasks/submit.rs b/src/tasks/submit.rs index 4b06354..f506953 100644 --- a/src/tasks/submit.rs +++ b/src/tasks/submit.rs @@ -135,11 +135,8 @@ impl SubmitTask { resp: &SignResponse, block: &BuiltBlock, ) -> Result { - // Extract the signature components from the response - let (v, r, s) = extract_signature_components(&resp.sig); - // Create the transaction request with the signature values - let tx: TransactionRequest = self.tx_request(retry_count, resp, block, v, r, s).await?; + let tx: TransactionRequest = self.new_tx_request(retry_count, resp, block).await?; // Simulate the transaction with a call to the host provider if let Some(maybe_error) = self.sim_with_call(&tx).await { @@ -200,22 +197,33 @@ impl SubmitTask { } /// Creates a transaction request for the blob with the given header and signature values. - async fn tx_request( + async fn new_tx_request( &self, retry_count: usize, resp: &SignResponse, block: &BuiltBlock, - v: u8, - r: FixedBytes<32>, - s: FixedBytes<32>, ) -> Result { // TODO: ENG-1082 Implement fills let fills = vec![]; - // Bump gas with each retry to replace the previous transaction while maintaining the same nonce - let gas_coefficient = 10 * (retry_count + 1) as u64; - let gas_limit = 1_000_000 + (gas_coefficient * 1_000_000); - debug!(retry_count, gas_coefficient, gas_limit, "calculated gas limit"); + // Extract the signature components from the response + let (v, r, s) = extract_signature_components(&resp.sig); + + // Bump gas with each retry to replace the previous + // transaction while maintaining the same nonce + // TODO: Clean this up if this works + let gas_coefficient: u64 = (15 * (retry_count + 1)).try_into().unwrap(); + let gas_limit: u64 = 1_500_000 + (gas_coefficient * 1_000_000); + let max_priority_fee_per_gas: u128 = (retry_count as u128); + debug!( + retry_count, + gas_coefficient, gas_limit, max_priority_fee_per_gas, "calculated gas limit" + ); + + // manually retrieve nonce + let nonce = + self.provider().get_transaction_count(self.provider().default_signer_address()).await?; + debug!(nonce, "assigned nonce"); // Build the block header let header: BlockHeader = BlockHeader { @@ -227,17 +235,14 @@ impl SubmitTask { }; debug!(?header, "built block header"); - // manually retrieve nonce - let nonce = - self.provider().get_transaction_count(self.provider().default_signer_address()).await?; - debug!(nonce, "manually setting transaction nonce"); - // Create a blob transaction with the blob header and signature values and return it let tx = self .build_blob_tx(fills, header, v, r, s, block)? .with_from(self.provider().default_signer_address()) .with_to(self.config.builder_helper_address) - .with_gas_limit(gas_limit); + .with_gas_limit(gas_limit) + .with_max_priority_fee_per_gas(max_priority_fee_per_gas) + .with_nonce(nonce); debug!(?tx, "prepared transaction request"); Ok(tx) @@ -335,7 +340,6 @@ impl SubmitTask { // Retry loop let result = loop { let span = debug_span!("SubmitTask::retrying_handle_inbound", retries); - debug!(retries, "number of retries"); let inbound_result = match self .handle_inbound(retries, block) @@ -349,17 +353,14 @@ impl SubmitTask { Err(err) => { // Log the retry attempt retries += 1; - error!(error = %err, "error handling inbound block"); // Delay until next slot if we get a 403 error - if err.to_string().contains("403") { - let (slot_number, _, end) = self.calculate_slot_window()?; - let now = self.now(); - if end > now { - let sleep_duration = std::time::Duration::from_secs(end - now); - debug!(sleep_duration = ?sleep_duration, slot_number, "403 detected - sleeping until end of slot"); - tokio::time::sleep(sleep_duration).await; - } + if err.to_string().contains("403 Forbidden") { + let (slot_number, _, _) = self.calculate_slot_window()?; + debug!(slot_number, ?block, "403 detected - not assigned to slot"); + return Ok(ControlFlow::Skip); + } else { + error!(error = %err, "error handling inbound block"); } ControlFlow::Retry From d8507916d827369e198b44e28b58f0a0e6c43bb3 Mon Sep 17 00:00:00 2001 From: dylan Date: Wed, 21 May 2025 12:35:13 -0600 Subject: [PATCH 05/11] fix: retry logic bugs --- src/config.rs | 5 +- src/tasks/submit.rs | 163 +++++++++++++++++++++----------------------- 2 files changed, 80 insertions(+), 88 deletions(-) diff --git a/src/config.rs b/src/config.rs index 593eceb..f869fad 100644 --- a/src/config.rs +++ b/src/config.rs @@ -72,8 +72,9 @@ pub struct BuilderConfig { /// NOTE: should not include the host_rpc_url value #[from_env( var = "TX_BROADCAST_URLS", - desc = "Additional RPC URLs to which to broadcast transactions", - infallible + desc = "Additional RPC URLs to which the builder broadcasts transactions", + infallible, + optional )] pub tx_broadcast_urls: Vec>, /// address of the Zenith contract on Host. diff --git a/src/tasks/submit.rs b/src/tasks/submit.rs index f506953..e91a1b6 100644 --- a/src/tasks/submit.rs +++ b/src/tasks/submit.rs @@ -4,7 +4,7 @@ use crate::{ utils::extract_signature_components, }; use alloy::{ - consensus::{SimpleCoder, Transaction, constants::GWEI_TO_WEI}, + consensus::SimpleCoder, eips::BlockNumberOrTag, network::{TransactionBuilder, TransactionBuilder4844}, primitives::{FixedBytes, TxHash, U256}, @@ -13,7 +13,7 @@ use alloy::{ sol_types::{SolCall, SolError}, transports::TransportError, }; -use eyre::{bail, eyre}; +use eyre::bail; use init4_bin_base::deps::{ metrics::{counter, histogram}, tracing::{self, Instrument, debug, debug_span, error, info, instrument, warn}, @@ -101,21 +101,11 @@ impl SubmitTask { let data = submitCall { fills, header, v, r, s }.abi_encode(); let sidecar = block.encode_blob::().build()?; - Ok(TransactionRequest::default() - .with_blob_sidecar(sidecar) - .with_input(data) - .with_max_priority_fee_per_gas((GWEI_TO_WEI * 16) as u128)) - } - /// Returns the next host block height. - async fn next_host_block_height(&self) -> eyre::Result { - let result = self.provider().get_block_number().await?; - let next = result.checked_add(1).ok_or_else(|| eyre!("next host block height overflow"))?; - debug!(next, "next host block height"); - Ok(next) + Ok(TransactionRequest::default().with_blob_sidecar(sidecar).with_input(data)) } - /// Prepares and then sends the EIP-4844 transaction with a sidecar encoded with a rollup block to the network. + /// Prepares and sends the EIP-4844 transaction with a sidecar encoded with a rollup block to the network. async fn submit_transaction( &self, retry_count: usize, @@ -158,19 +148,13 @@ impl SubmitTask { if let Err(TransportError::ErrorResp(e)) = self.provider().call(tx.clone()).block(BlockNumberOrTag::Pending.into()).await { - error!( - code = e.code, - message = %e.message, - data = ?e.data, - "error in transaction submission" - ); - + // NB: These errors are all handled the same way but are logged for debugging purposes if e.as_revert_data() .map(|data| data.starts_with(&IncorrectHostBlock::SELECTOR)) .unwrap_or_default() { debug!(%e, "incorrect host block"); - return Some(Ok(ControlFlow::Retry)); + return Some(Ok(ControlFlow::Skip)); } if e.as_revert_data() @@ -189,6 +173,12 @@ impl SubmitTask { return Some(Ok(ControlFlow::Skip)); } + error!( + code = e.code, + message = %e.message, + data = ?e.data, + "unknown error in host transaction simulation call" + ); return Some(Ok(ControlFlow::Skip)); } @@ -205,22 +195,14 @@ impl SubmitTask { ) -> Result { // TODO: ENG-1082 Implement fills let fills = vec![]; - // Extract the signature components from the response let (v, r, s) = extract_signature_components(&resp.sig); - // Bump gas with each retry to replace the previous - // transaction while maintaining the same nonce - // TODO: Clean this up if this works - let gas_coefficient: u64 = (15 * (retry_count + 1)).try_into().unwrap(); - let gas_limit: u64 = 1_500_000 + (gas_coefficient * 1_000_000); - let max_priority_fee_per_gas: u128 = (retry_count as u128); - debug!( - retry_count, - gas_coefficient, gas_limit, max_priority_fee_per_gas, "calculated gas limit" - ); + // Calculate gas limits based on retry attempts + let (max_fee_per_gas, max_priority_fee_per_gas, max_fee_per_blob_gas) = + calculate_gas_limits(retry_count); - // manually retrieve nonce + // manually retrieve nonce // TODO: Maybe this should be done in Env task and passed through elsewhere let nonce = self.provider().get_transaction_count(self.provider().default_signer_address()).await?; debug!(nonce, "assigned nonce"); @@ -238,13 +220,12 @@ impl SubmitTask { // Create a blob transaction with the blob header and signature values and return it let tx = self .build_blob_tx(fills, header, v, r, s, block)? - .with_from(self.provider().default_signer_address()) .with_to(self.config.builder_helper_address) - .with_gas_limit(gas_limit) + .with_max_fee_per_gas(max_fee_per_gas) .with_max_priority_fee_per_gas(max_priority_fee_per_gas) + .with_max_fee_per_blob_gas(max_fee_per_blob_gas) .with_nonce(nonce); - debug!(?tx, "prepared transaction request"); Ok(tx) } @@ -255,23 +236,16 @@ impl SubmitTask { resp: &SignResponse, tx: TransactionRequest, ) -> Result { - debug!( - host_block_number = %resp.req.host_block_number, - gas_limit = %resp.req.gas_limit, - nonce = ?tx.nonce, - "sending transaction to network" - ); - // assign the nonce and fill the rest of the values let SendableTx::Envelope(tx) = self.provider().fill(tx).await? else { bail!("failed to fill transaction") }; - debug!(tx_hash = %tx.tx_hash(), nonce = ?tx.nonce(), gas_limit = ?tx.gas_limit(), blob_gas_used = ?tx.blob_gas_used(), "filled blob transaction"); + debug!(tx_hash = ?tx.hash(), host_block_number = %resp.req.host_block_number, "sending transaction to network"); // send the tx via the primary host_provider let fut = spawn_provider_send!(self.provider(), &tx); - // spawn send_tx futures for all additional broadcast host_providers + // spawn send_tx futures on retry attempts for all additional broadcast host_providers for host_provider in self.config.connect_additional_broadcast() { spawn_provider_send!(&host_provider, &tx); } @@ -281,16 +255,19 @@ impl SubmitTask { error!("receipts task gone"); } - // question mark unwraps join error, which would be an internal panic - // then if let checks for rpc error if let Err(e) = fut.await? { - error!(error = %e, "Primary tx broadcast failed. Skipping transaction."); + // Detect and handle transaction underprice errors + if matches!(e, TransportError::ErrorResp(ref err) if err.code == -32000 && err.message.contains("replacement transaction underpriced")) + { + debug!(?tx, "underpriced transaction error - retrying tx with gas bump"); + return Ok(ControlFlow::Retry); + } + + // Unknown error, log and skip + error!(error = %e, "Primary tx broadcast failed"); return Ok(ControlFlow::Skip); } - // Okay so the code gets all the way to this log - // but we don't see the tx hash in the logs or in the explorer, - // not even as a failed TX, just not at all. info!( tx_hash = %tx.tx_hash(), ru_chain_id = %resp.req.ru_chain_id, @@ -339,54 +316,38 @@ impl SubmitTask { // Retry loop let result = loop { + // Log the retry attempt let span = debug_span!("SubmitTask::retrying_handle_inbound", retries); - let inbound_result = match self - .handle_inbound(retries, block) - .instrument(span.clone()) - .await - { - Ok(control_flow) => { - debug!(?control_flow, retries, "successfully handled inbound block"); - control_flow - } - Err(err) => { - // Log the retry attempt - retries += 1; - - // Delay until next slot if we get a 403 error - if err.to_string().contains("403 Forbidden") { - let (slot_number, _, _) = self.calculate_slot_window()?; - debug!(slot_number, ?block, "403 detected - not assigned to slot"); - return Ok(ControlFlow::Skip); - } else { - error!(error = %err, "error handling inbound block"); + let inbound_result = + match self.handle_inbound(retries, block).instrument(span.clone()).await { + Ok(control_flow) => control_flow, + Err(err) => { + // Delay until next slot if we get a 403 error + if err.to_string().contains("403 Forbidden") { + let (slot_number, _, _) = self.calculate_slot_window()?; + debug!(slot_number, "403 detected - skipping slot"); + return Ok(ControlFlow::Skip); + } else { + error!(error = %err, "error handling inbound block"); + } + + ControlFlow::Retry } - - ControlFlow::Retry - } - }; + }; let guard = span.entered(); match inbound_result { ControlFlow::Retry => { + retries += 1; if retries > retry_limit { counter!("builder.building_too_many_retries").increment(1); debug!("retries exceeded - skipping block"); return Ok(ControlFlow::Skip); } drop(guard); - - // Detect a slot change and break out of the loop in that case too - let (this_slot, start, end) = self.calculate_slot_window()?; - if this_slot != current_slot { - debug!("slot changed - skipping block"); - break inbound_result; - } - - // Otherwise retry the block - debug!(retries, this_slot, start, end, "retrying block"); + debug!(retries, start, end, "retrying block"); continue; } ControlFlow::Skip => { @@ -423,6 +384,12 @@ impl SubmitTask { now.duration_since(UNIX_EPOCH).unwrap().as_secs() } + /// Returns the next host block height. + async fn next_host_block_height(&self) -> eyre::Result { + let block_num = self.provider().get_block_number().await?; + Ok(block_num + 1) + } + /// Task future for the submit task /// NB: This task assumes that the simulator will only send it blocks for /// slots that it's assigned. @@ -469,3 +436,27 @@ impl SubmitTask { (sender, handle) } } + +fn calculate_gas_limits(retry_count: usize) -> (u128, u128, u128) { + let base_fee_per_gas: u128 = 100_000_000_000; + let base_priority_fee_per_gas: u128 = 2_000_000_000; + let base_fee_per_blob_gas: u128 = 1_000_000_000; + + let bump_multiplier = 1150u128.pow(retry_count as u32); // 15% bump + let blob_bump_multiplier = 2000u128.pow(retry_count as u32); // 100% bump (double each time) for blob gas + let bump_divisor = 1000u128.pow(retry_count as u32); + + let max_fee_per_gas = base_fee_per_gas * bump_multiplier / bump_divisor; + let max_priority_fee_per_gas = base_priority_fee_per_gas * bump_multiplier / bump_divisor; + let max_fee_per_blob_gas = base_fee_per_blob_gas * blob_bump_multiplier / bump_divisor; + + debug!( + retry_count, + max_fee_per_gas, + max_priority_fee_per_gas, + max_fee_per_blob_gas, + "calculated bumped gas parameters" + ); + + (max_fee_per_gas, max_priority_fee_per_gas, max_fee_per_blob_gas) +} From ba696d4626a62bbfe2a3a756abbf15a7169c2911 Mon Sep 17 00:00:00 2001 From: dylan Date: Fri, 23 May 2025 13:34:26 -0600 Subject: [PATCH 06/11] refactor sim_with_call function --- src/tasks/submit.rs | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/src/tasks/submit.rs b/src/tasks/submit.rs index e91a1b6..bd7a6c9 100644 --- a/src/tasks/submit.rs +++ b/src/tasks/submit.rs @@ -128,23 +128,16 @@ impl SubmitTask { // Create the transaction request with the signature values let tx: TransactionRequest = self.new_tx_request(retry_count, resp, block).await?; - // Simulate the transaction with a call to the host provider - if let Some(maybe_error) = self.sim_with_call(&tx).await { - warn!( - error = ?maybe_error, - "error in transaction simulation" - ); - maybe_error?; + // Simulate the transaction with a call to the host provider and report any errors + if let Err(err) = self.sim_with_call(&tx).await { + warn!(%err, "error in transaction simulation"); } Ok(tx) } /// Simulates the transaction with a call to the host provider to check for reverts. - async fn sim_with_call( - &self, - tx: &TransactionRequest, - ) -> Option> { + async fn sim_with_call(&self, tx: &TransactionRequest) -> eyre::Result<()> { if let Err(TransportError::ErrorResp(e)) = self.provider().call(tx.clone()).block(BlockNumberOrTag::Pending.into()).await { @@ -154,7 +147,7 @@ impl SubmitTask { .unwrap_or_default() { debug!(%e, "incorrect host block"); - return Some(Ok(ControlFlow::Skip)); + bail!(e) } if e.as_revert_data() @@ -162,7 +155,7 @@ impl SubmitTask { .unwrap_or_default() { debug!(%e, "bad signature"); - return Some(Ok(ControlFlow::Skip)); + bail!(e) } if e.as_revert_data() @@ -170,7 +163,7 @@ impl SubmitTask { .unwrap_or_default() { debug!(%e, "one rollup block per host block"); - return Some(Ok(ControlFlow::Skip)); + bail!(e) } error!( @@ -179,11 +172,10 @@ impl SubmitTask { data = ?e.data, "unknown error in host transaction simulation call" ); - return Some(Ok(ControlFlow::Skip)); + bail!(e) } - debug!(?tx, "successfully simulated transaction request"); - None + Ok(()) } /// Creates a transaction request for the blob with the given header and signature values. From 19905794b31e569402e50844fd9c96ba3f21a96e Mon Sep 17 00:00:00 2001 From: dylan Date: Fri, 23 May 2025 14:32:39 -0600 Subject: [PATCH 07/11] gas calculation refactors --- src/tasks/block/sim.rs | 7 ++--- src/tasks/submit.rs | 68 +++++++++++++++++++++++------------------- 2 files changed, 41 insertions(+), 34 deletions(-) diff --git a/src/tasks/block/sim.rs b/src/tasks/block/sim.rs index a663dcd..0f511a4 100644 --- a/src/tasks/block/sim.rs +++ b/src/tasks/block/sim.rs @@ -82,7 +82,7 @@ impl Simulator { block: BlockEnv, ) -> eyre::Result { let db = self.create_db().await.unwrap(); - let number = block.number; + let block_build: BlockBuild<_, NoOpInspector> = BlockBuild::new( db, constants, @@ -94,9 +94,8 @@ impl Simulator { self.config.rollup_block_gas_limit, ); - let mut built_block = block_build.build().await; - built_block.set_block_number(number); - debug!(block = ?built_block, "finished block simulation"); + let built_block = block_build.build().await; + debug!(block_number = ?built_block.block_number(), "finished building block"); Ok(built_block) } diff --git a/src/tasks/submit.rs b/src/tasks/submit.rs index bd7a6c9..427a36f 100644 --- a/src/tasks/submit.rs +++ b/src/tasks/submit.rs @@ -4,7 +4,7 @@ use crate::{ utils::extract_signature_components, }; use alloy::{ - consensus::SimpleCoder, + consensus::{SimpleCoder, constants::GWEI_TO_WEI}, eips::BlockNumberOrTag, network::{TransactionBuilder, TransactionBuilder4844}, primitives::{FixedBytes, TxHash, U256}, @@ -21,12 +21,19 @@ use init4_bin_base::deps::{ use signet_sim::BuiltBlock; use signet_types::{SignRequest, SignResponse}; use signet_zenith::{ - BundleHelper::{self, BlockHeader, FillPermit2, submitCall}, + BundleHelper::{self, submitCall, BlockHeader, FillPermit2}, Zenith::{self, IncorrectHostBlock}, }; use std::time::{Instant, UNIX_EPOCH}; use tokio::{sync::mpsc, task::JoinHandle}; +/// Base maximum fee per gas to use as a starting point for retry bumps +pub const BASE_FEE_PER_GAS: u128 = 10 * GWEI_TO_WEI as u128; +/// Base max priority fee per gas to use as a starting point for retry bumps +pub const BASE_MAX_PRIORITY_FEE_PER_GAS: u128 = 2 * GWEI_TO_WEI as u128; +/// Base maximum fee per blob gas to use as a starting point for retry bumps +pub const BASE_MAX_FEE_PER_BLOB_GAS: u128 = 1 * GWEI_TO_WEI as u128; + macro_rules! spawn_provider_send { ($provider:expr, $tx:expr) => { { @@ -88,7 +95,7 @@ impl SubmitTask { }) } - /// Builds blob transaction from the provided header and signature values + /// Builds blob transaction and encodes the sidecar for it from the provided header and signature values fn build_blob_tx( &self, fills: Vec, @@ -187,17 +194,23 @@ impl SubmitTask { ) -> Result { // TODO: ENG-1082 Implement fills let fills = vec![]; + + // manually retrieve nonce + let nonce = + self.provider().get_transaction_count(self.provider().default_signer_address()).await?; + debug!(nonce, "assigned nonce"); + // Extract the signature components from the response let (v, r, s) = extract_signature_components(&resp.sig); // Calculate gas limits based on retry attempts let (max_fee_per_gas, max_priority_fee_per_gas, max_fee_per_blob_gas) = - calculate_gas_limits(retry_count); - - // manually retrieve nonce // TODO: Maybe this should be done in Env task and passed through elsewhere - let nonce = - self.provider().get_transaction_count(self.provider().default_signer_address()).await?; - debug!(nonce, "assigned nonce"); + calculate_gas_limits( + retry_count, + BASE_FEE_PER_GAS, + BASE_MAX_PRIORITY_FEE_PER_GAS, + BASE_MAX_FEE_PER_BLOB_GAS, + ); // Build the block header let header: BlockHeader = BlockHeader { @@ -249,9 +262,8 @@ impl SubmitTask { if let Err(e) = fut.await? { // Detect and handle transaction underprice errors - if matches!(e, TransportError::ErrorResp(ref err) if err.code == -32000 && err.message.contains("replacement transaction underpriced")) - { - debug!(?tx, "underpriced transaction error - retrying tx with gas bump"); + if matches!(e, TransportError::ErrorResp(ref err) if err.code == -32603) { + debug!(tx_hash = ?tx.hash(), "underpriced transaction error - retrying tx with gas bump"); return Ok(ControlFlow::Retry); } @@ -303,7 +315,7 @@ impl SubmitTask { ) -> eyre::Result { let mut retries = 0; let building_start_time = Instant::now(); - let (current_slot, start, end) = self.calculate_slot_window()?; + let (current_slot, start, end) = self.calculate_slot_window(); debug!(current_slot, start, end, "calculating target slot window"); // Retry loop @@ -317,7 +329,7 @@ impl SubmitTask { Err(err) => { // Delay until next slot if we get a 403 error if err.to_string().contains("403 Forbidden") { - let (slot_number, _, _) = self.calculate_slot_window()?; + let (slot_number, _, _) = self.calculate_slot_window(); debug!(slot_number, "403 detected - skipping slot"); return Ok(ControlFlow::Skip); } else { @@ -363,11 +375,11 @@ impl SubmitTask { } /// Calculates and returns the slot number and its start and end timestamps for the current instant. - fn calculate_slot_window(&self) -> eyre::Result<(u64, u64, u64)> { + fn calculate_slot_window(&self) -> (u64, u64, u64) { let now_ts = self.now(); let current_slot = self.config.slot_calculator.calculate_slot(now_ts); let (start, end) = self.config.slot_calculator.calculate_slot_window(current_slot); - Ok((current_slot, start, end)) + (current_slot, start, end) } /// Returns the current timestamp in seconds since the UNIX epoch. @@ -397,12 +409,6 @@ impl SubmitTask { }; debug!(block_number = block.block_number(), ?block, "submit channel received block"); - // Check if a block number was set and skip if not - if block.block_number() == 0 { - debug!("block number is 0 - skipping"); - continue; - } - // Only attempt each block number once if block.block_number() == last_block_attempted { debug!("block number is unchanged from last attempt - skipping"); @@ -429,18 +435,20 @@ impl SubmitTask { } } -fn calculate_gas_limits(retry_count: usize) -> (u128, u128, u128) { - let base_fee_per_gas: u128 = 100_000_000_000; - let base_priority_fee_per_gas: u128 = 2_000_000_000; - let base_fee_per_blob_gas: u128 = 1_000_000_000; - +// Returns gas parameters based on retry counts. This uses +fn calculate_gas_limits( + retry_count: usize, + base_max_fee_per_gas: u128, + base_max_priority_fee_per_gas: u128, + base_max_fee_per_blob_gas: u128, +) -> (u128, u128, u128) { let bump_multiplier = 1150u128.pow(retry_count as u32); // 15% bump let blob_bump_multiplier = 2000u128.pow(retry_count as u32); // 100% bump (double each time) for blob gas let bump_divisor = 1000u128.pow(retry_count as u32); - let max_fee_per_gas = base_fee_per_gas * bump_multiplier / bump_divisor; - let max_priority_fee_per_gas = base_priority_fee_per_gas * bump_multiplier / bump_divisor; - let max_fee_per_blob_gas = base_fee_per_blob_gas * blob_bump_multiplier / bump_divisor; + let max_fee_per_gas = base_max_fee_per_gas * bump_multiplier / bump_divisor; + let max_priority_fee_per_gas = base_max_priority_fee_per_gas * bump_multiplier / bump_divisor; + let max_fee_per_blob_gas = base_max_fee_per_blob_gas * blob_bump_multiplier / bump_divisor; debug!( retry_count, From 934788cc4c10b7d0ef60994478af41f5b619c242 Mon Sep 17 00:00:00 2001 From: dylan Date: Thu, 29 May 2025 16:19:14 -0600 Subject: [PATCH 08/11] address review feedback --- bin/submit_transaction.rs | 16 ++++++++-------- src/tasks/block/sim.rs | 2 +- src/tasks/submit.rs | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/bin/submit_transaction.rs b/bin/submit_transaction.rs index abf45d3..71b10f4 100644 --- a/bin/submit_transaction.rs +++ b/bin/submit_transaction.rs @@ -11,7 +11,7 @@ use builder::config::HostProvider; use init4_bin_base::{ deps::{ metrics::{counter, histogram}, - tracing, + tracing::{debug, error}, }, init4, utils::{from_env::FromEnv, signer::LocalOrAwsConfig}, @@ -52,16 +52,17 @@ async fn main() { let _guard = init4(); let config = Config::from_env().unwrap(); - tracing::trace!("connecting to provider"); + debug!(?config.recipient_address, "connecting to provider"); + let provider = config.provider().await; let recipient_address = config.recipient_address; let sleep_time = config.sleep_time; loop { - tracing::debug!("attempting transaction"); + debug!(?recipient_address, "attempting transaction"); send_transaction(&provider, recipient_address).await; - tracing::debug!(sleep_time, "sleeping"); + debug!(sleep_time, "sleeping"); tokio::time::sleep(tokio::time::Duration::from_secs(sleep_time)).await; } } @@ -78,18 +79,17 @@ async fn send_transaction(provider: &HostProvider, recipient_address: Address) { let dispatch_start_time: Instant = Instant::now(); // dispatch the transaction - tracing::debug!("dispatching transaction"); let result = provider.send_transaction(tx).await.unwrap(); // wait for the transaction to mine let receipt = match timeout(Duration::from_secs(240), result.get_receipt()).await { Ok(Ok(receipt)) => receipt, Ok(Err(e)) => { - tracing::error!(error = ?e, "failed to get transaction receipt"); + error!(error = ?e, "failed to get transaction receipt"); return; } Err(_) => { - tracing::error!("timeout waiting for transaction receipt"); + error!("timeout waiting for transaction receipt"); counter!("txn_submitter.tx_timeout").increment(1); return; } @@ -99,6 +99,6 @@ async fn send_transaction(provider: &HostProvider, recipient_address: Address) { // record metrics for how long it took to mine the transaction let mine_time = dispatch_start_time.elapsed().as_secs(); - tracing::debug!(success = receipt.status(), mine_time, hash, "transaction mined"); + debug!(success = receipt.status(), mine_time, hash, "transaction mined"); histogram!("txn_submitter.tx_mine_time").record(mine_time as f64); } diff --git a/src/tasks/block/sim.rs b/src/tasks/block/sim.rs index 0f511a4..6868837 100644 --- a/src/tasks/block/sim.rs +++ b/src/tasks/block/sim.rs @@ -82,7 +82,7 @@ impl Simulator { block: BlockEnv, ) -> eyre::Result { let db = self.create_db().await.unwrap(); - + let block_build: BlockBuild<_, NoOpInspector> = BlockBuild::new( db, constants, diff --git a/src/tasks/submit.rs b/src/tasks/submit.rs index 427a36f..8bfa5a7 100644 --- a/src/tasks/submit.rs +++ b/src/tasks/submit.rs @@ -21,7 +21,7 @@ use init4_bin_base::deps::{ use signet_sim::BuiltBlock; use signet_types::{SignRequest, SignResponse}; use signet_zenith::{ - BundleHelper::{self, submitCall, BlockHeader, FillPermit2}, + BundleHelper::{self, BlockHeader, FillPermit2, submitCall}, Zenith::{self, IncorrectHostBlock}, }; use std::time::{Instant, UNIX_EPOCH}; @@ -32,7 +32,7 @@ pub const BASE_FEE_PER_GAS: u128 = 10 * GWEI_TO_WEI as u128; /// Base max priority fee per gas to use as a starting point for retry bumps pub const BASE_MAX_PRIORITY_FEE_PER_GAS: u128 = 2 * GWEI_TO_WEI as u128; /// Base maximum fee per blob gas to use as a starting point for retry bumps -pub const BASE_MAX_FEE_PER_BLOB_GAS: u128 = 1 * GWEI_TO_WEI as u128; +pub const BASE_MAX_FEE_PER_BLOB_GAS: u128 = GWEI_TO_WEI as u128; macro_rules! spawn_provider_send { ($provider:expr, $tx:expr) => { From 601c2d5a80b54695f8320687a892037df0da04e2 Mon Sep 17 00:00:00 2001 From: dylan Date: Thu, 29 May 2025 16:31:06 -0600 Subject: [PATCH 09/11] bump to sdk version with block number updates --- Cargo.toml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ce77458..8a9174b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,11 +27,11 @@ integration = [] [dependencies] init4-bin-base = { version = "0.4.1", features = ["perms"] } -signet-constants = { git = "https://github.com/init4tech/signet-sdk", rev = "bd183b627dcb0eb682da801093b13f1f8311446b" } -signet-sim = { git = "https://github.com/init4tech/signet-sdk", rev = "bd183b627dcb0eb682da801093b13f1f8311446b" } -signet-tx-cache = { git = "https://github.com/init4tech/signet-sdk", rev = "bd183b627dcb0eb682da801093b13f1f8311446b" } -signet-types = { git = "https://github.com/init4tech/signet-sdk", rev = "bd183b627dcb0eb682da801093b13f1f8311446b" } -signet-zenith = { git = "https://github.com/init4tech/signet-sdk", rev = "bd183b627dcb0eb682da801093b13f1f8311446b" } +signet-constants = { git = "https://github.com/init4tech/signet-sdk", rev = "ba5894f6fac35299d495ae115cd465a1f0791637" } +signet-sim = { git = "https://github.com/init4tech/signet-sdk", rev = "ba5894f6fac35299d495ae115cd465a1f0791637" } +signet-tx-cache = { git = "https://github.com/init4tech/signet-sdk", rev = "ba5894f6fac35299d495ae115cd465a1f0791637" } +signet-types = { git = "https://github.com/init4tech/signet-sdk", rev = "ba5894f6fac35299d495ae115cd465a1f0791637" } +signet-zenith = { git = "https://github.com/init4tech/signet-sdk", rev = "ba5894f6fac35299d495ae115cd465a1f0791637" } trevm = { version = "0.23.4", features = ["concurrent-db", "test-utils"] } From 0e8eda5f1b357d6a0453c11ef101137885bdde7a Mon Sep 17 00:00:00 2001 From: dylan Date: Thu, 29 May 2025 16:45:26 -0600 Subject: [PATCH 10/11] remove clone --- src/tasks/submit.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tasks/submit.rs b/src/tasks/submit.rs index 8bfa5a7..3b124ce 100644 --- a/src/tasks/submit.rs +++ b/src/tasks/submit.rs @@ -60,7 +60,7 @@ pub enum ControlFlow { } /// Submits sidecars in ethereum txns to mainnet ethereum -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct SubmitTask { /// Zenith pub zenith: ZenithInstance, From e40f408f45b168f60c78f2e6cc6ad7c7e4e2bcec Mon Sep 17 00:00:00 2001 From: dylan Date: Tue, 3 Jun 2025 19:22:55 -0600 Subject: [PATCH 11/11] comment --- src/tasks/submit.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tasks/submit.rs b/src/tasks/submit.rs index 3b124ce..e5e002b 100644 --- a/src/tasks/submit.rs +++ b/src/tasks/submit.rs @@ -435,7 +435,7 @@ impl SubmitTask { } } -// Returns gas parameters based on retry counts. This uses +// Returns gas parameters based on retry counts. fn calculate_gas_limits( retry_count: usize, base_max_fee_per_gas: u128,