Skip to content

feat: passes sim result to the submit tasks #100

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: prestwich/simrevert
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions bin/submit_transaction.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! A simple transaction submitter that sends a transaction to a recipient address
//! on a regular interval for the purposes of roughly testing rollup mining.
use alloy::{
network::{EthereumWallet, TransactionBuilder},
primitives::{Address, U256},
Expand Down Expand Up @@ -67,18 +69,29 @@ async fn main() {
}
}

/// Sends a transaction to the specified recipient address
async fn send_transaction(provider: &HostProvider, recipient_address: Address) {
// construct simple transaction to send ETH to a recipient
let nonce = match provider.get_transaction_count(provider.default_signer_address()).await {
Ok(count) => count,
Err(e) => {
error!(error = ?e, "failed to get transaction count");
return;
}
};

let tx = TransactionRequest::default()
.with_from(provider.default_signer_address())
.with_to(recipient_address)
.with_value(U256::from(1))
.with_nonce(nonce)
.with_gas_limit(30_000);

// start timer to measure how long it takes to mine the transaction
let dispatch_start_time: Instant = Instant::now();

// dispatch the transaction
debug!(?tx.nonce, "sending transaction with nonce");
let result = provider.send_transaction(tx).await.unwrap();

// wait for the transaction to mine
Expand All @@ -95,10 +108,13 @@ async fn send_transaction(provider: &HostProvider, recipient_address: Address) {
}
};

let hash = receipt.transaction_hash.to_string();
record_metrics(dispatch_start_time, receipt);
}

// record metrics for how long it took to mine the transaction
/// Record metrics for how long it took to mine the transaction
fn record_metrics(dispatch_start_time: Instant, receipt: alloy::rpc::types::TransactionReceipt) {
let mine_time = dispatch_start_time.elapsed().as_secs();
let hash = receipt.transaction_hash.to_string();
debug!(success = receipt.status(), mine_time, hash, "transaction mined");
histogram!("txn_submitter.tx_mine_time").record(mine_time as f64);
}
52 changes: 35 additions & 17 deletions src/tasks/block/sim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,27 @@ pub struct Simulator {
pub config: BuilderConfig,
/// A provider that cannot sign transactions, used for interacting with the rollup.
pub ru_provider: RuProvider,

/// The block configuration environment on which to simulate
pub block_env: watch::Receiver<Option<BlockEnv>>,
}

/// SimResult bundles a BuiltBlock to the BlockEnv it was simulated against.
#[derive(Debug, Clone)]
pub struct SimResult {
/// The block built with the successfully simulated transactions
pub block: BuiltBlock,
/// The block environment the transactions were simulated against.
pub env: BlockEnv,
}

impl Simulator {
/// Creates a new `Simulator` instance.
///
/// # Arguments
///
/// - `config`: The configuration for the builder.
/// - `ru_provider`: A provider for interacting with the rollup.
/// - `block_env`: A receiver for the block environment to simulate against.
///
/// # Returns
///
Expand All @@ -70,6 +79,7 @@ impl Simulator {
/// - `constants`: The system constants for the rollup.
/// - `sim_items`: The simulation cache containing transactions and bundles.
/// - `finish_by`: The deadline by which the block must be built.
/// - `block_env`: The block environment to simulate against.
///
/// # Returns
///
Expand All @@ -79,22 +89,34 @@ impl Simulator {
constants: SignetSystemConstants,
sim_items: SimCache,
finish_by: Instant,
block: BlockEnv,
block_env: BlockEnv,
) -> eyre::Result<BuiltBlock> {
debug!(
block_number = block_env.number,
?finish_by,
tx_count = sim_items.len(),
"starting block build",
);

let db = self.create_db().await.unwrap();

let block_build: BlockBuild<_, NoOpInspector> = BlockBuild::new(
db,
constants,
self.config.cfg_env(),
block,
block_env,
finish_by,
self.config.concurrency_limit,
sim_items,
self.config.rollup_block_gas_limit,
);

let built_block = block_build.build().await;
debug!(block_number = ?built_block.block_number(), "finished building block");
debug!(
tx_count = built_block.tx_count(),
block_number = ?built_block.block_number(),
"block simulation completed",
);

Ok(built_block)
}
Expand All @@ -115,7 +137,7 @@ impl Simulator {
self,
constants: SignetSystemConstants,
cache: SimCache,
submit_sender: mpsc::UnboundedSender<BuiltBlock>,
submit_sender: mpsc::UnboundedSender<SimResult>,
) -> JoinHandle<()> {
debug!("starting simulator task");

Expand All @@ -140,26 +162,23 @@ impl Simulator {
mut self,
constants: SignetSystemConstants,
cache: SimCache,
submit_sender: mpsc::UnboundedSender<BuiltBlock>,
submit_sender: mpsc::UnboundedSender<SimResult>,
) {
loop {
let sim_cache = cache.clone();
let finish_by = self.calculate_deadline();

// Wait for the block environment to be set
if self.block_env.changed().await.is_err() {
error!("block_env channel closed");
return;
}

// 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 env");

match self.handle_build(constants, sim_cache, finish_by, block_env).await {
let finish_by = self.calculate_deadline();
let sim_cache = cache.clone();
match self.handle_build(constants, sim_cache, finish_by, block_env.clone()).await {
Ok(block) => {
debug!(block = ?block, "built block");
let _ = submit_sender.send(block);
debug!(block = ?block.block_number(), tx_count = block.transactions().len(), "built block");
let _ = submit_sender.send(SimResult { block, env: block_env });
}
Err(e) => {
error!(err = %e, "failed to build block");
Expand All @@ -184,11 +203,10 @@ impl Simulator {
let remaining = self.slot_calculator().slot_duration() - timepoint;

// We add a 1500 ms buffer to account for sequencer stopping signing.

let candidate =
let deadline =
Instant::now() + Duration::from_secs(remaining) - Duration::from_millis(1500);

candidate.max(Instant::now())
deadline.max(Instant::now())
}

/// Creates an `AlloyDB` instance from the rollup provider.
Expand Down
5 changes: 2 additions & 3 deletions src/tasks/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ impl EnvTask {
let Some(block) = blocks.last() else {
// This case occurs when there are no changes to the block,
// so we do nothing.
debug!("empty filter changes");
continue;
};
let span = info_span!("EnvTask::task_fut::loop", hash = %block, number = tracing::field::Empty);
Expand Down Expand Up @@ -96,10 +95,10 @@ impl EnvTask {
}
};
span.record("number", previous.number);
debug!("retrieved latest block");

let env = self.construct_block_env(&previous);
debug!(?env, "constructed block env");
debug!(block_number = ?env.number, env.basefee, "constructed latest block env");

if sender.send(Some(env)).is_err() {
// The receiver has been dropped, so we can stop the task.
debug!("receiver dropped, stopping task");
Expand Down
2 changes: 1 addition & 1 deletion src/tasks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ pub mod metrics;
/// Tx submission task
pub mod submit;

/// Constructs the simualtion environment.
/// Constructs the simulation environment.
pub mod env;
Loading