Skip to content

Commit

Permalink
wip: better e2e testing pipeline
Browse files Browse the repository at this point in the history
  • Loading branch information
0xOsiris committed Jan 16, 2025
1 parent 95bd0a3 commit 1d432e9
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 63 deletions.
114 changes: 78 additions & 36 deletions world-chain-builder/crates/tests/src/cases.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use std::sync::Arc;
use std::time::Duration;
use std::time::Instant;

use alloy_network::Network;
use alloy_primitives::hex;
use alloy_primitives::Bytes;
use alloy_provider::PendingTransactionBuilder;
Expand All @@ -13,39 +15,43 @@ use futures::StreamExt;
use futures::TryStreamExt;
use tokio::time::sleep;
use tracing::debug;
use tracing::info;

use crate::run_command;

const CONCURRENCY_LIMIT: usize = 50;

/// Asserts that the world-chain-builder payload is built correctly with a set of PBH transactions.
pub async fn ordering_test<T, P>(builder_provider: Arc<P>, fixture: Vec<Bytes>) -> Result<()>
/// Sends 5k transactions to the builder concurrently
pub async fn load_test<T, P>(builder_provider: Arc<P>, transactions: Vec<Bytes>) -> Result<()>
where
T: Transport + Clone,
P: Provider<T>,
{
let start = Instant::now();
let builder_provider_clone = builder_provider.clone();
stream::iter(fixture.chunks(100).enumerate())
stream::iter(transactions.iter().enumerate())
.map(Ok)
.try_for_each_concurrent(CONCURRENCY_LIMIT, move |(index, transactions)| {
.try_for_each_concurrent(CONCURRENCY_LIMIT, move |(index, tx)| {
let builder_provider = builder_provider_clone.clone();
async move {
for transaction in transactions {
let tx = builder_provider.send_raw_transaction(transaction).await?;
let hash = *tx.tx_hash();
let receipt = tx.get_receipt().await;
assert!(receipt.is_ok());
debug!(
receipt = ?receipt.unwrap(),
hash = ?hash,
index = index,
"Transaction Receipt Received"
);
}
let tx = builder_provider.send_raw_transaction(tx).await?;
let hash = *tx.tx_hash();
let receipt = tx.get_receipt().await;
assert!(receipt.is_ok());
debug!(
receipt = ?receipt.unwrap(),
hash = ?hash,
index = index,
"Transaction Receipt Received"
);

Ok::<(), eyre::Report>(())
}
})
.await?;

info!(duration = %start.elapsed().as_secs_f64(), total = %transactions.len(), "All PBH Transactions Processed");

Ok(())
}

Expand All @@ -68,7 +74,7 @@ where
.await?;

sleep(Duration::from_secs(5)).await;

// Grab the latest block number
let block_number = sequencer_provider.get_block_number().await?;

Expand All @@ -91,29 +97,65 @@ where
Ok(())
}

/// Spams the builder with 4000 transactions at once.
/// This is to test the builder's ability to handle a large number of transactions.
pub async fn load_test<T, P>(_builder_provider: Arc<P>) -> Result<()>
/// `eth_sendRawTransactionConditional` test cases
pub async fn transact_conditional_test<T, P>(
builder_provider: Arc<P>,
transactions: &[Bytes],
) -> Result<()>
where
T: Transport + Clone,
P: Provider<T>,
{ todo!() }
{
let tx = &transactions[0];
let latest = builder_provider.get_block_number().await?;
let conditions = TransactionConditional {
block_number_max: Some(latest + 2),
block_number_min: Some(latest),
..Default::default()
};
let builder =
send_raw_transaction_conditional(tx.clone(), conditions, builder_provider.clone()).await?;
let hash = *builder.tx_hash();
let receipt = builder.get_receipt().await;
assert!(receipt.is_ok());
info!(
block = %receipt.unwrap().block_number.unwrap_or_default(),
block_number_min = %latest,
block_number_max = %latest + 2,
hash = ?hash,
"Transaction Receipt Received"
);

/// `eth_sendRawTransactionConditional` test cases
pub async fn transact_conditional_test<T, P>(builder_provider: Arc<P>) -> Result<()>
// Fails due to block_number_max
let tx = &transactions[1];
let conditions = TransactionConditional {
block_number_max: Some(latest),
block_number_min: Some(latest),
..Default::default()
};

assert!(send_raw_transaction_conditional(tx.clone(), conditions, builder_provider.clone()).await.is_err());
Ok(())
}

async fn send_raw_transaction_conditional<T, N, P>(
tx: Bytes,
conditions: TransactionConditional,
provider: Arc<P>,
) -> Result<PendingTransactionBuilder<T, N>>
where
N: Network,
T: Transport + Clone,
P: Provider<T>,
{
// // Second half, use eth_sendRawTransactionConditional
// let rlp_hex = hex::encode_prefixed(transaction);
// let tx_hash = builder_provider
// .client()
// .request(
// "eth_sendRawTransactionConditional",
// (rlp_hex, TransactionConditional::default()),
// )
// .await?;
// PendingTransactionBuilder::new(builder_provider.root().clone(), tx_hash)
todo!()
P: Provider<T, N>,
{
let rlp_hex = hex::encode_prefixed(tx);
let tx_hash = provider
.client()
.request("eth_sendRawTransactionConditional", (rlp_hex, conditions))
.await?;

Ok(PendingTransactionBuilder::new(
provider.root().clone(),
tx_hash,
))
}
20 changes: 6 additions & 14 deletions world-chain-builder/crates/tests/src/fixtures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub struct TransactionFixtures {
}

/// Generates test fixtures for PBH transactions
pub async fn generate_fixture(size: u32) -> Vec<Bytes> {
pub async fn generate_fixture(size: u32) -> TransactionFixtures {
let mut test_fixture = TransactionFixtures::default();
for i in 0..=5 {
for j in 0..=size {
Expand All @@ -29,19 +29,11 @@ pub async fn generate_fixture(size: u32) -> Vec<Bytes> {
}
}

test_fixture
}

/// Generates test fixture for standerd EIP-1559 transactions
pub async fn generate_eip1559_fixture(size: u32) -> Vec<Bytes> {
let mut test_fixture = vec![];
for i in 0..=5 {
for j in 0..=size {
let tx = tx(DEV_CHAIN_ID, None, j as u64, Address::with_last_byte(0x01));
let envelope = TransactionTestContext::sign_tx(signer(i), tx).await;
let raw_tx = envelope.encoded_2718();
test_fixture.push(raw_tx.into());
}
for j in size..=size + 2 {
let tx = tx(DEV_CHAIN_ID, None, j as u64, Address::with_last_byte(0x01));
let envelope = TransactionTestContext::sign_tx(signer(0), tx).await;
let raw_tx = envelope.encoded_2718();
test_fixture.eip1559.push(raw_tx.into());
}

test_fixture
Expand Down
16 changes: 7 additions & 9 deletions world-chain-builder/crates/tests/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,23 @@ use alloy_provider::{Provider, ProviderBuilder};
use alloy_rpc_types_eth::{BlockNumberOrTag, BlockTransactionsKind};
use alloy_transport::Transport;
use eyre::eyre::{eyre, Result};
use fixtures::generate_pbh_4337_fixture;
use fixtures::generate_fixture;
use std::process::Command;
use tokio::time::sleep;
use tracing::info;

pub mod cases;
pub mod fixtures;



#[tokio::main]
async fn main() -> Result<()> {
if std::env::var("RUST_LOG").is_err() {
std::env::set_var("RUST_LOG", "info");
}

tracing_subscriber::fmt::init();
tracing_subscriber::fmt()
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
.init();

let (builder_rpc, sequencer_rpc) = start_devnet().await?;

Expand All @@ -51,15 +51,13 @@ async fn main() -> Result<()> {
};
f.await;

info!("Generating test fixtures");
let fixture = generate_pbh_4337_fixture(1000).await;

let fixture = generate_fixture(1000).await;
info!("Running block building test");
cases::ordering_test(builder_provider.clone(), fixture).await?;
cases::load_test(builder_provider.clone(), fixture.pbh).await?;
info!("Running fallback test");
cases::fallback_test(sequencer_provider.clone()).await?;
info!("Running Load Test");
cases::load_test(builder_provider.clone()).await?;
cases::transact_conditional_test(builder_provider.clone(), &fixture.eip1559[..2]).await?;
Ok(())
}

Expand Down
10 changes: 6 additions & 4 deletions world-chain-builder/crates/world/pool/src/test_utils.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use std::sync::LazyLock;
use alloy_consensus::TxEip1559;
use alloy_eips::{eip2930::AccessList,eip2718::Encodable2718};
use alloy_eips::{eip2718::Encodable2718, eip2930::AccessList};
use alloy_network::TxSigner;
use alloy_primitives::{address, Address, Bytes, ChainId, U256};
use alloy_primitives::{address, Address, Bytes, ChainId, U256};
use alloy_rlp::Encodable;
use alloy_signer_local::coins_bip39::English;
use alloy_signer_local::PrivateKeySigner;
Expand All @@ -18,6 +17,7 @@ use revm_primitives::TxKind;
use semaphore::identity::Identity;
use semaphore::poseidon_tree::LazyPoseidonTree;
use semaphore::Field;
use std::sync::LazyLock;
use world_chain_builder_pbh::external_nullifier::ExternalNullifier;
use world_chain_builder_pbh::payload::{PbhPayload, Proof, TREE_DEPTH};

Expand Down Expand Up @@ -143,7 +143,9 @@ pub async fn eth_tx(acc: u32, mut tx: TxEip1559) -> OpPooledTransaction {
pub async fn raw_tx(acc: u32, mut tx: TxEip1559) -> Bytes {
let signer = signer(acc);
let signature = signer
.sign_transaction(&mut tx).await.expect("Failed to sign transaction");
.sign_transaction(&mut tx)
.await
.expect("Failed to sign transaction");
let tx_signed = OpTransactionSigned::new(tx.into(), signature);
let mut buff = vec![];
tx_signed.encode_2718(&mut buff);
Expand Down

0 comments on commit 1d432e9

Please sign in to comment.