forked from paradigmxyz/reth
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: blob e2e test (paradigmxyz#7823)
Showing
16 changed files
with
373 additions
and
129 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
use alloy_consensus::TxEnvelope; | ||
use alloy_network::eip2718::Decodable2718; | ||
use reth::{api::FullNodeComponents, builder::rpc::RpcRegistry, rpc::api::DebugApiServer}; | ||
use reth_primitives::{Bytes, B256}; | ||
use reth_rpc::eth::{error::EthResult, EthTransactions}; | ||
|
||
pub struct RpcTestContext<Node: FullNodeComponents> { | ||
pub inner: RpcRegistry<Node>, | ||
} | ||
|
||
impl<Node: FullNodeComponents> RpcTestContext<Node> { | ||
/// Injects a raw transaction into the node tx pool via RPC server | ||
pub async fn inject_tx(&mut self, raw_tx: Bytes) -> EthResult<B256> { | ||
let eth_api = self.inner.eth_api(); | ||
eth_api.send_raw_transaction(raw_tx).await | ||
} | ||
|
||
/// Retrieves a transaction envelope by its hash | ||
pub async fn envelope_by_hash(&mut self, hash: B256) -> eyre::Result<TxEnvelope> { | ||
let tx = self.inner.debug_api().raw_transaction(hash).await?.unwrap(); | ||
let tx = tx.to_vec(); | ||
Ok(TxEnvelope::decode_2718(&mut tx.as_ref()).unwrap()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
use alloy_consensus::{ | ||
BlobTransactionSidecar, SidecarBuilder, SimpleCoder, TxEip4844Variant, TxEnvelope, | ||
}; | ||
use alloy_network::{eip2718::Encodable2718, EthereumSigner, TransactionBuilder}; | ||
use alloy_rpc_types::{TransactionInput, TransactionRequest}; | ||
use alloy_signer_wallet::LocalWallet; | ||
use eyre::Ok; | ||
use reth_primitives::{hex, Address, Bytes, U256}; | ||
|
||
use reth_primitives::{constants::eip4844::MAINNET_KZG_TRUSTED_SETUP, B256}; | ||
|
||
pub struct TransactionTestContext; | ||
|
||
impl TransactionTestContext { | ||
/// Creates a static transfer and signs it | ||
pub async fn transfer_tx(chain_id: u64, wallet: LocalWallet) -> Bytes { | ||
let tx = tx(chain_id, None, 0); | ||
let signer = EthereumSigner::from(wallet); | ||
tx.build(&signer).await.unwrap().encoded_2718().into() | ||
} | ||
|
||
/// Creates a tx with blob sidecar and sign it | ||
pub async fn tx_with_blobs(chain_id: u64, wallet: LocalWallet) -> eyre::Result<Bytes> { | ||
let mut tx = tx(chain_id, None, 0); | ||
|
||
let mut builder = SidecarBuilder::<SimpleCoder>::new(); | ||
builder.ingest(b"dummy blob"); | ||
let sidecar: BlobTransactionSidecar = builder.build()?; | ||
|
||
tx.set_blob_sidecar(sidecar); | ||
tx.set_max_fee_per_blob_gas(15e9 as u128); | ||
|
||
let signer = EthereumSigner::from(wallet); | ||
let signed = tx.clone().build(&signer).await.unwrap(); | ||
|
||
Ok(signed.encoded_2718().into()) | ||
} | ||
|
||
pub async fn optimism_l1_block_info_tx( | ||
chain_id: u64, | ||
wallet: LocalWallet, | ||
nonce: u64, | ||
) -> Bytes { | ||
let l1_block_info = Bytes::from_static(&hex!("7ef9015aa044bae9d41b8380d781187b426c6fe43df5fb2fb57bd4466ef6a701e1f01e015694deaddeaddeaddeaddeaddeaddeaddeaddead000194420000000000000000000000000000000000001580808408f0d18001b90104015d8eb900000000000000000000000000000000000000000000000000000000008057650000000000000000000000000000000000000000000000000000000063d96d10000000000000000000000000000000000000000000000000000000000009f35273d89754a1e0387b89520d989d3be9c37c1f32495a88faf1ea05c61121ab0d1900000000000000000000000000000000000000000000000000000000000000010000000000000000000000002d679b567db6187c0c8323fa982cfb88b74dbcc7000000000000000000000000000000000000000000000000000000000000083400000000000000000000000000000000000000000000000000000000000f4240")); | ||
let tx = tx(chain_id, Some(l1_block_info), nonce); | ||
let signer = EthereumSigner::from(wallet); | ||
tx.build(&signer).await.unwrap().encoded_2718().into() | ||
} | ||
|
||
/// Validates the sidecar of a given tx envelope and returns the versioned hashes | ||
pub fn validate_sidecar(tx: TxEnvelope) -> Vec<B256> { | ||
let proof_setting = MAINNET_KZG_TRUSTED_SETUP.clone(); | ||
|
||
match tx { | ||
TxEnvelope::Eip4844(signed) => match signed.tx() { | ||
TxEip4844Variant::TxEip4844WithSidecar(tx) => { | ||
tx.validate_blob(&proof_setting).unwrap(); | ||
tx.sidecar.versioned_hashes().collect() | ||
} | ||
_ => panic!("Expected Eip4844 transaction with sidecar"), | ||
}, | ||
_ => panic!("Expected Eip4844 transaction"), | ||
} | ||
} | ||
} | ||
|
||
/// Creates a type 2 transaction | ||
fn tx(chain_id: u64, data: Option<Bytes>, nonce: u64) -> TransactionRequest { | ||
TransactionRequest { | ||
nonce: Some(nonce), | ||
value: Some(U256::from(100)), | ||
to: Some(Address::random()), | ||
gas: Some(210000), | ||
max_fee_per_gas: Some(20e9 as u128), | ||
max_priority_fee_per_gas: Some(20e9 as u128), | ||
chain_id: Some(chain_id), | ||
input: TransactionInput { input: None, data }, | ||
..Default::default() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
use std::sync::Arc; | ||
|
||
use reth::{ | ||
args::RpcServerArgs, | ||
builder::{NodeBuilder, NodeConfig, NodeHandle}, | ||
rpc::types::engine::PayloadStatusEnum, | ||
tasks::TaskManager, | ||
}; | ||
use reth_e2e_test_utils::{ | ||
node::NodeTestContext, transaction::TransactionTestContext, wallet::Wallet, | ||
}; | ||
use reth_node_ethereum::EthereumNode; | ||
use reth_primitives::{b256, ChainSpecBuilder, Genesis, MAINNET}; | ||
use reth_transaction_pool::TransactionPool; | ||
|
||
use crate::utils::eth_payload_attributes; | ||
|
||
#[tokio::test] | ||
async fn can_handle_blobs() -> eyre::Result<()> { | ||
reth_tracing::init_test_tracing(); | ||
let tasks = TaskManager::current(); | ||
let exec = tasks.executor(); | ||
|
||
let genesis: Genesis = serde_json::from_str(include_str!("../assets/genesis.json")).unwrap(); | ||
let chain_spec = Arc::new( | ||
ChainSpecBuilder::default() | ||
.chain(MAINNET.chain) | ||
.genesis(genesis) | ||
.cancun_activated() | ||
.build(), | ||
); | ||
let node_config = NodeConfig::test() | ||
.with_chain(chain_spec) | ||
.with_unused_ports() | ||
.with_rpc(RpcServerArgs::default().with_unused_ports().with_http()); | ||
let NodeHandle { node, node_exit_future: _ } = NodeBuilder::new(node_config.clone()) | ||
.testing_node(exec.clone()) | ||
.node(EthereumNode::default()) | ||
.launch() | ||
.await?; | ||
|
||
let mut node = NodeTestContext::new(node).await?; | ||
|
||
let wallets = Wallet::new(2).gen(); | ||
let blob_wallet = wallets.first().unwrap(); | ||
let second_wallet = wallets.last().unwrap(); | ||
|
||
// inject normal tx | ||
let raw_tx = TransactionTestContext::transfer_tx(1, second_wallet.clone()).await; | ||
let tx_hash = node.rpc.inject_tx(raw_tx).await?; | ||
// build payload with normal tx | ||
let (payload, attributes) = node.new_payload(eth_payload_attributes).await?; | ||
|
||
// clean the pool | ||
node.inner.pool.remove_transactions(vec![tx_hash]); | ||
|
||
// build blob tx | ||
let blob_tx = TransactionTestContext::tx_with_blobs(1, blob_wallet.clone()).await?; | ||
|
||
// inject blob tx to the pool | ||
let blob_tx_hash = node.rpc.inject_tx(blob_tx).await?; | ||
// fetch it from rpc | ||
let envelope = node.rpc.envelope_by_hash(blob_tx_hash).await?; | ||
// validate sidecar | ||
let versioned_hashes = TransactionTestContext::validate_sidecar(envelope); | ||
|
||
// build a payload | ||
let (blob_payload, blob_attr) = node.new_payload(eth_payload_attributes).await?; | ||
|
||
// submit the blob payload | ||
let blob_block_hash = node | ||
.engine_api | ||
.submit_payload(blob_payload, blob_attr, PayloadStatusEnum::Valid, versioned_hashes.clone()) | ||
.await?; | ||
|
||
let genesis_hash = b256!("d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3"); | ||
|
||
let (_, _) = tokio::join!( | ||
// send fcu with blob hash | ||
node.engine_api.update_forkchoice(genesis_hash, blob_block_hash), | ||
// send fcu with normal hash | ||
node.engine_api.update_forkchoice(genesis_hash, payload.block().hash()) | ||
); | ||
|
||
// submit normal payload | ||
node.engine_api.submit_payload(payload, attributes, PayloadStatusEnum::Valid, vec![]).await?; | ||
|
||
tokio::time::sleep(std::time::Duration::from_secs(3)).await; | ||
|
||
// expects the blob tx to be back in the pool | ||
let envelope = node.rpc.envelope_by_hash(blob_tx_hash).await?; | ||
// make sure the sidecar is present | ||
TransactionTestContext::validate_sidecar(envelope); | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
mod blobs; | ||
mod dev; | ||
mod eth; | ||
mod p2p; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters