Skip to content

Commit 3e2c5fa

Browse files
committed
passes sim result to the submit tasks
- adds a SimResult type that binds a BlockEnv to a BuiltBlock - passess that SimResult to the SubmitTask for gas calculations
1 parent da4a7fd commit 3e2c5fa

File tree

5 files changed

+160
-127
lines changed

5 files changed

+160
-127
lines changed

bin/submit_transaction.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! A simple transaction submitter that sends a transaction to a recipient address
2+
//! on a regular interval for the purposes of roughly testing rollup mining.
13
use alloy::{
24
network::{EthereumWallet, TransactionBuilder},
35
primitives::{Address, U256},
@@ -67,18 +69,29 @@ async fn main() {
6769
}
6870
}
6971

72+
/// Sends a transaction to the specified recipient address
7073
async fn send_transaction(provider: &HostProvider, recipient_address: Address) {
7174
// construct simple transaction to send ETH to a recipient
75+
let nonce = match provider.get_transaction_count(provider.default_signer_address()).await {
76+
Ok(count) => count,
77+
Err(e) => {
78+
error!(error = ?e, "failed to get transaction count");
79+
return;
80+
}
81+
};
82+
7283
let tx = TransactionRequest::default()
7384
.with_from(provider.default_signer_address())
7485
.with_to(recipient_address)
7586
.with_value(U256::from(1))
87+
.with_nonce(nonce)
7688
.with_gas_limit(30_000);
7789

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

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

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

98-
let hash = receipt.transaction_hash.to_string();
111+
record_metrics(dispatch_start_time, receipt);
112+
}
99113

100-
// record metrics for how long it took to mine the transaction
114+
/// Record metrics for how long it took to mine the transaction
115+
fn record_metrics(dispatch_start_time: Instant, receipt: alloy::rpc::types::TransactionReceipt) {
101116
let mine_time = dispatch_start_time.elapsed().as_secs();
117+
let hash = receipt.transaction_hash.to_string();
102118
debug!(success = receipt.status(), mine_time, hash, "transaction mined");
103119
histogram!("txn_submitter.tx_mine_time").record(mine_time as f64);
104120
}

src/tasks/block/sim.rs

Lines changed: 65 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@ use init4_bin_base::{
99
};
1010
use signet_sim::{BlockBuild, BuiltBlock, SimCache};
1111
use signet_types::constants::SignetSystemConstants;
12-
use std::time::{Duration, Instant};
12+
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
1313
use tokio::{
1414
sync::{
1515
mpsc::{self},
1616
watch,
1717
},
1818
task::JoinHandle,
1919
};
20+
use tracing::trace;
2021
use trevm::revm::{
2122
context::BlockEnv,
2223
database::{AlloyDB, WrapDatabaseAsync},
@@ -34,18 +35,27 @@ pub struct Simulator {
3435
pub config: BuilderConfig,
3536
/// A provider that cannot sign transactions, used for interacting with the rollup.
3637
pub ru_provider: RuProvider,
37-
3838
/// The block configuration environment on which to simulate
3939
pub block_env: watch::Receiver<Option<BlockEnv>>,
4040
}
4141

42+
/// SimResult bundles a BuiltBlock to the BlockEnv it was simulated against.
43+
#[derive(Debug, Clone)]
44+
pub struct SimResult {
45+
/// The block built with the successfully simulated transactions
46+
pub block: BuiltBlock,
47+
/// The block environment the transactions were simulated against.
48+
pub env: BlockEnv,
49+
}
50+
4251
impl Simulator {
4352
/// Creates a new `Simulator` instance.
4453
///
4554
/// # Arguments
4655
///
4756
/// - `config`: The configuration for the builder.
4857
/// - `ru_provider`: A provider for interacting with the rollup.
58+
/// - `block_env`: A receiver for the block environment to simulate against.
4959
///
5060
/// # Returns
5161
///
@@ -70,6 +80,7 @@ impl Simulator {
7080
/// - `constants`: The system constants for the rollup.
7181
/// - `sim_items`: The simulation cache containing transactions and bundles.
7282
/// - `finish_by`: The deadline by which the block must be built.
83+
/// - `block_env`: The block environment to simulate against.
7384
///
7485
/// # Returns
7586
///
@@ -79,22 +90,34 @@ impl Simulator {
7990
constants: SignetSystemConstants,
8091
sim_items: SimCache,
8192
finish_by: Instant,
82-
block: BlockEnv,
93+
block_env: BlockEnv,
8394
) -> eyre::Result<BuiltBlock> {
95+
debug!(
96+
block_number = block_env.number,
97+
deadline = ?self.instant_to_timestamp(finish_by),
98+
tx_count= sim_items.len(),
99+
"starting block build",
100+
);
101+
84102
let db = self.create_db().await.unwrap();
103+
85104
let block_build: BlockBuild<_, NoOpInspector> = BlockBuild::new(
86105
db,
87106
constants,
88107
self.config.cfg_env(),
89-
block,
108+
block_env,
90109
finish_by,
91110
self.config.concurrency_limit,
92111
sim_items,
93112
self.config.rollup_block_gas_limit,
94113
);
95114

96115
let built_block = block_build.build().await;
97-
debug!(block_number = ?built_block.block_number(), "finished building block");
116+
debug!(
117+
tx_count = built_block.tx_count(),
118+
block_number = ?built_block.block_number(),
119+
"block simulation completed",
120+
);
98121

99122
Ok(built_block)
100123
}
@@ -115,7 +138,7 @@ impl Simulator {
115138
self,
116139
constants: SignetSystemConstants,
117140
cache: SimCache,
118-
submit_sender: mpsc::UnboundedSender<BuiltBlock>,
141+
submit_sender: mpsc::UnboundedSender<SimResult>,
119142
) -> JoinHandle<()> {
120143
debug!("starting simulator task");
121144

@@ -140,26 +163,23 @@ impl Simulator {
140163
mut self,
141164
constants: SignetSystemConstants,
142165
cache: SimCache,
143-
submit_sender: mpsc::UnboundedSender<BuiltBlock>,
166+
submit_sender: mpsc::UnboundedSender<SimResult>,
144167
) {
145168
loop {
146-
let sim_cache = cache.clone();
147-
let finish_by = self.calculate_deadline();
148-
149169
// Wait for the block environment to be set
150170
if self.block_env.changed().await.is_err() {
151171
error!("block_env channel closed");
152172
return;
153173
}
154174

155-
// If no env, skip this run
156175
let Some(block_env) = self.block_env.borrow_and_update().clone() else { return };
157-
debug!(block_env = ?block_env, "building on block env");
158176

159-
match self.handle_build(constants, sim_cache, finish_by, block_env).await {
177+
let finish_by = self.calculate_deadline();
178+
let sim_cache = cache.clone();
179+
match self.handle_build(constants, sim_cache, finish_by, block_env.clone()).await {
160180
Ok(block) => {
161-
debug!(block = ?block, "built block");
162-
let _ = submit_sender.send(block);
181+
debug!(block = ?block.block_number(), tx_count = block.transactions().len(), "built block");
182+
let _ = submit_sender.send(SimResult { block, env: block_env });
163183
}
164184
Err(e) => {
165185
error!(err = %e, "failed to build block");
@@ -178,17 +198,25 @@ impl Simulator {
178198
pub fn calculate_deadline(&self) -> Instant {
179199
// Get the current timepoint within the slot.
180200
let timepoint = self.slot_calculator().current_timepoint_within_slot();
201+
trace!(timepoint, "current timepoint within slot");
181202

182203
// We have the timepoint in seconds into the slot. To find out what's
183204
// remaining, we need to subtract it from the slot duration
184205
let remaining = self.slot_calculator().slot_duration() - timepoint;
206+
trace!(remaining, "time remaining in slot");
185207

186208
// We add a 1500 ms buffer to account for sequencer stopping signing.
187-
188-
let candidate =
209+
let deadline =
189210
Instant::now() + Duration::from_secs(remaining) - Duration::from_millis(1500);
211+
trace!(deadline = ?self.instant_to_timestamp(deadline), "calculated deadline for block simulation");
212+
213+
let buffered_deadline = deadline.max(Instant::now());
214+
trace!(?buffered_deadline, "final deadline for block simulation");
190215

191-
candidate.max(Instant::now())
216+
let timestamp = self.instant_to_timestamp(buffered_deadline);
217+
trace!(?timestamp, "deadline converted to timestamp");
218+
219+
buffered_deadline
192220
}
193221

194222
/// Creates an `AlloyDB` instance from the rollup provider.
@@ -217,4 +245,23 @@ impl Simulator {
217245
let wrapped_db: AlloyDatabaseProvider = WrapDatabaseAsync::new(alloy_db).unwrap();
218246
Some(wrapped_db)
219247
}
248+
249+
/// Converts an `Instant` to a UNIX timestamp in seconds and milliseconds.
250+
pub fn instant_to_timestamp(&self, instant: Instant) -> (u64, u128) {
251+
let now_instant = Instant::now();
252+
let now_system = SystemTime::now();
253+
254+
let duration_from_now = now_instant.duration_since(instant);
255+
256+
// Subtract that duration from the system time
257+
let target_system_time = now_system - duration_from_now;
258+
259+
let duration_since_epoch =
260+
target_system_time.duration_since(UNIX_EPOCH).expect("Time went backwards");
261+
262+
let seconds = duration_since_epoch.as_secs();
263+
let milliseconds = duration_since_epoch.as_millis();
264+
265+
(seconds, milliseconds)
266+
}
220267
}

src/tasks/env.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ impl EnvTask {
6666
let Some(block) = blocks.last() else {
6767
// This case occurs when there are no changes to the block,
6868
// so we do nothing.
69-
debug!("empty filter changes");
7069
continue;
7170
};
7271
let span = info_span!("EnvTask::task_fut::loop", hash = %block, number = tracing::field::Empty);
@@ -96,10 +95,10 @@ impl EnvTask {
9695
}
9796
};
9897
span.record("number", previous.number);
99-
debug!("retrieved latest block");
10098

10199
let env = self.construct_block_env(&previous);
102-
debug!(?env, "constructed block env");
100+
debug!(block_number = ?env.number, env.basefee, "constructed latest block env");
101+
103102
if sender.send(Some(env)).is_err() {
104103
// The receiver has been dropped, so we can stop the task.
105104
debug!("receiver dropped, stopping task");

0 commit comments

Comments
 (0)