Skip to content

Commit 9d812ce

Browse files
committed
WIP: adding a block builder loop test
1 parent a142314 commit 9d812ce

File tree

8 files changed

+298
-66
lines changed

8 files changed

+298
-66
lines changed

Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ path = "bin/submit_transaction.rs"
2424
[dependencies]
2525
init4-bin-base = { git = "https://github.com/init4tech/bin-base.git" }
2626

27-
signet-zenith = { git = "https://github.com/init4tech/signet-sdk", branch = "prestwich/sim-crate" }
28-
signet-types = { git = "https://github.com/init4tech/signet-sdk", branch = "prestwich/sim-crate" }
29-
signet-bundle = { git = "https://github.com/init4tech/signet-sdk", branch = "prestwich/sim-crate" }
30-
signet-sim = { git = "https://github.com/init4tech/signet-sdk", branch = "prestwich/sim-crate" }
27+
signet-zenith = { path = "../signet-sdk/crates/zenith" }
28+
signet-types = { path = "../signet-sdk/crates/types" }
29+
signet-bundle = { path = "../signet-sdk/crates/bundle" }
30+
signet-sim = { path = "../signet-sdk/crates/sim" }
3131

3232
trevm = { version = "0.20.10", features = ["concurrent-db", "test-utils"] }
3333

bin/builder.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@ async fn main() -> eyre::Result<()> {
1515
let span = tracing::info_span!("zenith-builder");
1616

1717
let config = BuilderConfig::load_from_env()?.clone();
18-
let host_provider = config.connect_host_provider().await?;
19-
let ru_provider = config.connect_ru_provider().await?;
18+
let constants = config.load_pecorino_constants();
2019
let authenticator = Authenticator::new(&config);
2120

22-
tracing::debug!(rpc_url = config.host_rpc_url.as_ref(), "instantiated provider");
21+
let host_provider = config.connect_host_provider().await?;
22+
let ru_provider = config.connect_ru_provider().await?;
2323

2424
let sequencer_signer = config.connect_sequencer_signer().await?;
25+
2526
let zenith = config.connect_zenith(host_provider.clone());
2627

2728
let metrics = MetricsTask { host_provider: host_provider.clone() };
@@ -48,7 +49,8 @@ async fn main() -> eyre::Result<()> {
4849

4950
let (submit_channel, submit_jh) = submit.spawn();
5051

51-
let build_jh = builder.spawn(ru_provider, tx_receiver, bundle_receiver, submit_channel);
52+
let build_jh =
53+
builder.spawn(constants, ru_provider, tx_receiver, bundle_receiver, submit_channel);
5254

5355
let port = config.builder_port;
5456
let server = serve_builder_with_span(([0, 0, 0, 0], port), span);

src/config.rs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::signer::{LocalOrAws, SignerError};
22
use alloy::{
33
network::{Ethereum, EthereumWallet},
4-
primitives::Address,
4+
primitives::{Address, address},
55
providers::{
66
Identity, ProviderBuilder, RootProvider,
77
fillers::{
@@ -10,6 +10,8 @@ use alloy::{
1010
},
1111
},
1212
};
13+
use eyre::Result;
14+
use signet_types::config::{HostConfig, PredeployTokens, RollupConfig, SignetSystemConstants};
1315
use signet_zenith::Zenith;
1416
use std::{borrow::Cow, env, num, str::FromStr};
1517

@@ -37,6 +39,7 @@ const OAUTH_CLIENT_ID: &str = "OAUTH_CLIENT_ID";
3739
const OAUTH_CLIENT_SECRET: &str = "OAUTH_CLIENT_SECRET";
3840
const OAUTH_AUTHENTICATE_URL: &str = "OAUTH_AUTHENTICATE_URL";
3941
const OAUTH_TOKEN_URL: &str = "OAUTH_TOKEN_URL";
42+
const CONCURRENCY_LIMIT: &str = "CONCURRENCY_LIMIT";
4043

4144
/// Configuration for a builder running a specific rollup on a specific host
4245
/// chain.
@@ -92,6 +95,8 @@ pub struct BuilderConfig {
9295
pub oauth_token_url: String,
9396
/// The oauth token refresh interval in seconds.
9497
pub oauth_token_refresh_interval: u64,
98+
/// The max number of simultaneous block simulations to run.
99+
pub concurrency_limit: usize,
95100
}
96101

97102
/// Error loading the configuration.
@@ -115,6 +120,9 @@ pub enum ConfigError {
115120
/// Error connecting to the signer
116121
#[error("failed to connect to signer: {0}")]
117122
Signer(#[from] SignerError),
123+
/// Error parsing the provided genesis file
124+
#[error("failed")]
125+
Genesis(String),
118126
}
119127

120128
impl ConfigError {
@@ -184,6 +192,7 @@ impl BuilderConfig {
184192
oauth_authenticate_url: load_string(OAUTH_AUTHENTICATE_URL)?,
185193
oauth_token_url: load_string(OAUTH_TOKEN_URL)?,
186194
oauth_token_refresh_interval: load_u64(AUTH_TOKEN_REFRESH_INTERVAL)?,
195+
concurrency_limit: load_u64(CONCURRENCY_LIMIT).map(|v| v as usize).unwrap_or(1000),
187196
})
188197
}
189198

@@ -244,6 +253,36 @@ impl BuilderConfig {
244253
pub const fn connect_zenith(&self, provider: Provider) -> ZenithInstance {
245254
Zenith::new(self.zenith_address, provider)
246255
}
256+
257+
/// Loads the Signet system constants for Pecorino.
258+
pub fn load_pecorino_constants(&self) -> SignetSystemConstants {
259+
let host = HostConfig::new(
260+
self.host_chain_id,
261+
149984,
262+
self.zenith_address,
263+
address!("0x4E8cC181805aFC307C83298242271142b8e2f249"),
264+
address!("0xd553C4CA4792Af71F4B61231409eaB321c1Dd2Ce"),
265+
address!("0x1af3A16857C28917Ab2C4c78Be099fF251669200"),
266+
PredeployTokens::new(
267+
address!("0x885F8DB528dC8a38aA3DDad9D3F619746B4a6A81"),
268+
address!("0x7970D259D4a96764Fa9B23FF0715A35f06f52D1A"),
269+
address!("0x7970D259D4a96764Fa9B23FF0715A35f06f52D1A"),
270+
),
271+
);
272+
let rollup = RollupConfig::new(
273+
self.ru_chain_id,
274+
address!("0x4E8cC181805aFC307C83298242271142b8e2f249"),
275+
address!("0xd553C4CA4792Af71F4B61231409eaB321c1Dd2Ce"),
276+
address!("0xe0eDA3701D44511ce419344A4CeD30B52c9Ba231"),
277+
PredeployTokens::new(
278+
address!("0x0B8BC5e60EE10957E0d1A0d95598fA63E65605e2"),
279+
address!("0xF34326d3521F1b07d1aa63729cB14A372f8A737C"),
280+
address!("0xE3d7066115f7d6b65F88Dff86288dB4756a7D733"),
281+
),
282+
);
283+
284+
SignetSystemConstants::new(host, rollup)
285+
}
247286
}
248287

249288
/// Load a string from an environment variable.

src/tasks/block.rs

Lines changed: 132 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,20 @@ use crate::{
66
tx_poller::TxPoller,
77
},
88
};
9-
use alloy::{consensus::TxEnvelope, eips::BlockId, genesis::Genesis};
10-
use signet_sim::{BlockBuild, BuiltBlock, SimCache};
9+
use alloy::{consensus::TxEnvelope, eips::BlockId, providers::Provider};
10+
use signet_sim::{BlockBuild, BuiltBlock, SimCache, SimItem};
1111
use signet_types::config::SignetSystemConstants;
1212
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
13-
use tokio::{select, sync::mpsc, task::JoinHandle};
13+
use tokio::{
14+
select,
15+
sync::mpsc::{self, UnboundedReceiver},
16+
task::JoinHandle,
17+
};
1418
use tracing::{Instrument, info};
1519
use trevm::{
1620
NoopBlock, NoopCfg,
1721
revm::{
18-
database::{AlloyDB, CacheDB, WrapDatabaseAsync},
22+
database::{AlloyDB, WrapDatabaseAsync},
1923
inspector::NoOpInspector,
2024
},
2125
};
@@ -54,7 +58,6 @@ impl BlockBuilder {
5458

5559
// calculate the duration in seconds until the beginning of the next block slot.
5660
fn secs_to_next_slot(&self) -> u64 {
57-
// TODO: Account for multiple builders and return the time to our next _assigned_ slot here.
5861
let curr_timestamp: u64 = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs();
5962
let current_slot_time = (curr_timestamp - self.config.chain_offset) % ETHEREUM_SLOT_TIME;
6063
(ETHEREUM_SLOT_TIME - current_slot_time) % ETHEREUM_SLOT_TIME
@@ -69,49 +72,83 @@ impl BlockBuilder {
6972
/// a handle to the running task.
7073
pub fn spawn(
7174
self,
75+
constants: SignetSystemConstants,
7276
ru_provider: WalletlessProvider,
73-
mut tx_receiver: mpsc::UnboundedReceiver<TxEnvelope>,
77+
mut tx_receiver: UnboundedReceiver<TxEnvelope>,
7478
mut bundle_receiver: mpsc::UnboundedReceiver<Bundle>,
75-
outbound: mpsc::UnboundedSender<BuiltBlock>,
79+
block_sender: mpsc::UnboundedSender<BuiltBlock>,
7680
) -> JoinHandle<()> {
77-
let genesis = Genesis::default();
78-
let constants = SignetSystemConstants::try_from_genesis(&genesis).unwrap(); // TODO: get from actual genesis file.
79-
let concurrency_limit = 1000;
80-
let max_gas = 30_000_000;
81-
81+
println!("GOT HERE 0");
8282
tokio::spawn(
8383
async move {
84+
// Create a sim item handler
85+
let sim_items = SimCache::new();
86+
println!("got here 1");
87+
88+
tokio::spawn({
89+
let sim_items = sim_items.clone();
90+
async move {
91+
println!("starting up the receiver");
92+
loop {
93+
select! {
94+
tx = tx_receiver.recv() => {
95+
if let Some(tx) = tx {
96+
println!("received transaction {}", tx.hash());
97+
sim_items.add_item(signet_sim::SimItem::Tx(tx.into()));
98+
}
99+
}
100+
bundle = bundle_receiver.recv() => {
101+
if let Some(bundle) = bundle {
102+
println!("received bundle {}", bundle.id);
103+
sim_items.add_item(SimItem::Bundle(bundle.bundle));
104+
}
105+
}
106+
}
107+
}
108+
}
109+
});
110+
111+
println!("starting the block builder loop");
112+
84113
loop {
85-
// setup during slot time dead zone
86-
let alloy_db = AlloyDB::new(ru_provider.clone(), BlockId::from(1));
87-
let wrapped_db = WrapDatabaseAsync::new(alloy_db).unwrap();
88-
let cached_db = CacheDB::new(wrapped_db);
89-
90-
let sim_items = SimCache::new();
91-
92-
let deadline = Instant::now()
93-
.checked_add(Duration::from_secs(self.secs_to_next_target()))
94-
.unwrap();
95-
96-
let block_builder: BlockBuild<_, NoOpInspector> = BlockBuild::new(
97-
cached_db,
98-
constants,
99-
NoopCfg,
100-
NoopBlock,
101-
deadline,
102-
concurrency_limit,
103-
sim_items.clone(),
104-
max_gas,
105-
);
106-
107-
// sleep until next buffer time
108-
tokio::time::sleep(Duration::from_secs(self.secs_to_next_target())).await;
109-
info!("beginning block build cycle");
114+
println!("STARTING 1");
115+
// Calculate the next wake up
116+
let buffer = self.secs_to_next_target();
117+
let deadline = Instant::now().checked_add(Duration::from_secs(buffer)).unwrap();
118+
println!("DEADLINE {:?}", deadline.clone());
119+
120+
tokio::time::sleep(Duration::from_secs(buffer)).await;
121+
122+
// Fetch latest block number from the rollup
123+
let db = match create_db(&ru_provider).await {
124+
Some(value) => value,
125+
None => {
126+
println!("failed to get a database - check runtime type");
127+
continue;
128+
}
129+
};
130+
131+
println!("SIM ITEMS LEN {}", sim_items.len());
110132

111133
tokio::spawn({
112-
let outbound = outbound.clone();
134+
let outbound = block_sender.clone();
135+
let sim_items = sim_items.clone();
136+
113137
async move {
138+
let block_builder: BlockBuild<_, NoOpInspector> = BlockBuild::new(
139+
db,
140+
constants,
141+
NoopCfg,
142+
NoopBlock,
143+
deadline,
144+
self.config.concurrency_limit.clone(),
145+
sim_items.clone(),
146+
self.config.rollup_block_gas_limit.clone(),
147+
);
148+
114149
let block = block_builder.build().await;
150+
println!("GOT BLOCK {}", block.contents_hash());
151+
115152
if let Err(e) = outbound.send(block) {
116153
println!("failed to send built block: {}", e);
117154
tracing::error!(error = %e, "failed to send built block");
@@ -120,28 +157,66 @@ impl BlockBuilder {
120157
}
121158
}
122159
});
123-
124-
// Feed it transactions and bundles until deadline
125-
loop {
126-
select! {
127-
tx = tx_receiver.recv() => {
128-
if let Some(tx) = tx {
129-
sim_items.add_item(tx);
130-
}
131-
}
132-
bundle = bundle_receiver.recv() => {
133-
if let Some(bundle) = bundle {
134-
sim_items.add_item(bundle.bundle);
135-
}
136-
}
137-
_ = tokio::time::sleep_until(deadline.into()) => {
138-
break;
139-
}
140-
}
141-
}
142160
}
143161
}
144162
.in_current_span(),
145163
)
146164
}
147165
}
166+
167+
/// Creates an AlloyDB from a rollup provider
168+
async fn create_db(
169+
ru_provider: &alloy::providers::fillers::FillProvider<
170+
alloy::providers::fillers::JoinFill<
171+
alloy::providers::Identity,
172+
alloy::providers::fillers::JoinFill<
173+
alloy::providers::fillers::GasFiller,
174+
alloy::providers::fillers::JoinFill<
175+
alloy::providers::fillers::BlobGasFiller,
176+
alloy::providers::fillers::JoinFill<
177+
alloy::providers::fillers::NonceFiller,
178+
alloy::providers::fillers::ChainIdFiller,
179+
>,
180+
>,
181+
>,
182+
>,
183+
alloy::providers::RootProvider,
184+
>,
185+
) -> Option<
186+
WrapDatabaseAsync<
187+
AlloyDB<
188+
alloy::network::Ethereum,
189+
alloy::providers::fillers::FillProvider<
190+
alloy::providers::fillers::JoinFill<
191+
alloy::providers::Identity,
192+
alloy::providers::fillers::JoinFill<
193+
alloy::providers::fillers::GasFiller,
194+
alloy::providers::fillers::JoinFill<
195+
alloy::providers::fillers::BlobGasFiller,
196+
alloy::providers::fillers::JoinFill<
197+
alloy::providers::fillers::NonceFiller,
198+
alloy::providers::fillers::ChainIdFiller,
199+
>,
200+
>,
201+
>,
202+
>,
203+
alloy::providers::RootProvider,
204+
>,
205+
>,
206+
>,
207+
> {
208+
let latest = match ru_provider.get_block_number().await {
209+
Ok(block_number) => block_number,
210+
Err(e) => {
211+
tracing::error!(error = %e, "failed to get latest block number");
212+
println!("failed to get latest block number");
213+
// Should this do anything else?
214+
return None;
215+
}
216+
};
217+
let alloy_db = AlloyDB::new(ru_provider.clone(), BlockId::from(latest));
218+
let wrapped_db = WrapDatabaseAsync::new(alloy_db).unwrap_or_else(|| {
219+
panic!("failed to acquire async alloy_db; check which runtime you're using")
220+
});
221+
Some(wrapped_db)
222+
}

src/tasks/oauth.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ mod tests {
168168
tx_broadcast_urls: vec!["http://localhost:9000".into()],
169169
oauth_token_refresh_interval: 300, // 5 minutes
170170
builder_helper_address: Address::default(),
171+
concurrency_limit: 1000,
171172
};
172173
Ok(config)
173174
}

0 commit comments

Comments
 (0)