Skip to content
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

refactor: bump alloy to 0.5.2, remove requests struct usage #59

Merged
merged 5 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "trevm"
version = "0.12.1"
version = "0.14.0"
rust-version = "1.79.0"
prestwich marked this conversation as resolved.
Show resolved Hide resolved
edition = "2021"
authors = ["init4"]
Expand Down Expand Up @@ -30,17 +30,17 @@ redundant-clone = "warn"
alloy-primitives = "=0.8.8"
alloy-sol-types = "=0.8.8"

alloy = { version = "=0.4.2", features = ["rpc-types-mev"] }
alloy = { version = "=0.5.2", features = ["rpc-types-mev"] }

revm = { version = "14.0.3", default-features = false, features = ["std"] }
revm = { version = "16.0.0", default-features = false, features = ["std"] }

zenith-types = "0.9"
zenith-types = "0.10"

thiserror = "1.0"
alloy-rlp = "0.3"

[dev-dependencies]
revm = { version = "14.0.3", features = [
revm = { version = "16.0.0", features = [
"test-utils",
"serde-json",
"std",
Expand Down
2 changes: 1 addition & 1 deletion src/driver/alloy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ impl BundleProcessor<EthCallBundle, EthCallBundleResponse> {
coinbase_diff,
eth_sent_to_coinbase,
from_address: tx.recover_signer()?,
to_address: match tx.to() {
to_address: match tx.kind() {
TxKind::Call(to) => Some(to),
_ => Some(Address::ZERO),
},
Expand Down
6 changes: 2 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,10 @@
//! requests by crediting accounts.
//! - [`eip6110`] - Prague's [EIP-6110], which extracts deposit
//! requests from the withdrawal contract events.
//! - [`eip7002`] - Prague's [EIP-7002], which extracts [`WithdrawalRequest`]s
//! - [`eip7002`] - Prague's [EIP-7002], which extracts withdrawal requestss
//! from the system withdrwal contract state.
//! - [`eip7251`] - Prague's [EIP-7251], which extracts
//! [`ConsolidationRequest`]s from the system consolidation contract state.
//! consolidation requestss from the system consolidation contract state.
//!
//! The [`BlockDriver`] and [`ChainDriver`] trait methods take a mutable
//! reference to allow the driver to accumulate information about the
Expand Down Expand Up @@ -350,8 +350,6 @@
//! [`eip6110`]: crate::system::eip6110
//! [`eip7002`]: crate::system::eip7002
//! [`eip7251`]: crate::system::eip7251
//! [`WithdrawalRequest`]: alloy::eips::eip7002::WithdrawalRequest
//! [`ConsolidationRequest`]: alloy::eips::eip7251::ConsolidationRequest

#![doc(
html_logo_url = "https://raw.githubusercontent.com/alloy-rs/core/main/assets/alloy.jpg",
Expand Down
9 changes: 3 additions & 6 deletions src/lifecycle/output.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
use alloy::{
consensus::{ReceiptEnvelope, TxReceipt},
eips::eip6110::DepositRequest,
};
use alloy_primitives::{Address, Bloom, Log};
use alloy::consensus::{ReceiptEnvelope, TxReceipt};
use alloy_primitives::{Address, Bloom, Bytes, Log};
use std::sync::OnceLock;

/// Information externalized during block execution.
Expand Down Expand Up @@ -106,7 +103,7 @@ impl<T: TxReceipt> BlockOutput<T> {
}

/// Find deposits in the logs of the transactions in the block.
pub fn find_deposit_logs(&self) -> impl Iterator<Item = DepositRequest> + '_ {
pub fn find_deposit_requests(&self) -> impl Iterator<Item = Bytes> + use<'_, T> {
crate::system::eip6110::check_logs_for_deposits(
self.receipts().iter().flat_map(TxReceipt::logs),
)
Expand Down
181 changes: 103 additions & 78 deletions src/system/eip6110.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use alloy::{consensus::ReceiptEnvelope, eips::eip6110::DepositRequest};
use alloy_primitives::Log;
use alloy::consensus::ReceiptEnvelope;
use alloy_primitives::{Bytes, Log};
use alloy_rlp::BufMut;
use alloy_sol_types::{sol, SolEvent};

/// The address for the Ethereum 2.0 deposit contract on the mainnet.
Expand All @@ -22,49 +23,34 @@ sol! {
///
/// - The `DepositEvent` is the only event in the deposit contract.
/// - The deposit contract enforces the length of the fields.
pub fn parse_deposit_from_log(log: &Log<DepositEvent>) -> DepositRequest {
// SAFETY: These `expect` https://github.com/ethereum/consensus-specs/blob/5f48840f4d768bf0e0a8156a3ed06ec333589007/solidity_deposit_contract/deposit_contract.sol#L107-L110
// are safe because the `DepositEvent` is the only event in the deposit contract and the length
// checks are done there.
DepositRequest {
pubkey: log
.pubkey
.as_ref()
.try_into()
.expect("pubkey length should be enforced in deposit contract"),
withdrawal_credentials: log
.withdrawal_credentials
.as_ref()
.try_into()
.expect("withdrawal_credentials length should be enforced in deposit contract"),
amount: u64::from_le_bytes(
log.amount
.as_ref()
.try_into()
.expect("amount length should be enforced in deposit contract"),
),
signature: log
.signature
.as_ref()
.try_into()
.expect("signature length should be enforced in deposit contract"),
index: u64::from_le_bytes(
log.index
.as_ref()
.try_into()
.expect("deposit index length should be enforced in deposit contract"),
),
}
pub fn parse_deposit_from_log(log: &Log<DepositEvent>) -> Bytes {
[
log.pubkey.as_ref(),
log.withdrawal_credentials.as_ref(),
log.amount.as_ref(),
log.signature.as_ref(),
log.index.as_ref(),
]
.concat()
.into()
}

/// Accumulate a deposit request from a log.
pub fn accumulate_deposit_from_log(log: &Log<DepositEvent>, out: &mut dyn BufMut) {
out.put_slice(log.pubkey.as_ref());
out.put_slice(log.withdrawal_credentials.as_ref());
out.put_slice(log.amount.as_ref());
out.put_slice(log.signature.as_ref());
out.put_slice(log.index.as_ref());
}

/// Check an iterator of logs for deposit events, parsing them into
/// [`DepositRequest`]s.
/// Check an iterator of logs for deposit events.
///
/// When parsing logs, the following assumptions are made
///
/// - The `DepositEvent` is the only event in the deposit contract.
/// - The deposit contract enforces the length of the fields.
pub fn check_logs_for_deposits<'a, I>(logs: I) -> impl Iterator<Item = DepositRequest> + 'a
pub fn check_logs_for_deposits<'a, I>(logs: I) -> impl Iterator<Item = Bytes> + 'a
where
I: IntoIterator<Item = &'a Log>,
I::IntoIter: 'a,
Expand All @@ -77,8 +63,23 @@ where
})
}

/// Accumulate deposits from an iterator of logs.
pub fn accumulate_deposits_from_logs<'a>(
logs: impl IntoIterator<Item = &'a Log>,
out: &mut dyn BufMut,
) {
logs.into_iter().filter(|log| log.address == MAINNET_DEPOSIT_CONTRACT_ADDRESS).for_each(
|log| {
// We assume that the log is valid because it was emitted by the
// deposit contract.
let decoded_log = DepositEvent::decode_log(log, false).expect("invalid log");
accumulate_deposit_from_log(&decoded_log, out);
},
);
}

/// Find deposit logs in a receipt. Iterates over the logs in the receipt and
/// returns a [`DepositRequest`] for each log that is emitted by the
/// returns a deposit request bytestring for each log that is emitted by the
/// deposit contract.
///
/// When parsing logs, the following assumptions are made
Expand All @@ -87,10 +88,36 @@ where
/// - The deposit contract enforces the length of the fields.
pub fn check_receipt_for_deposits(
receipt: &ReceiptEnvelope,
) -> impl Iterator<Item = DepositRequest> + '_ {
) -> impl Iterator<Item = Bytes> + use<'_> {
check_logs_for_deposits(receipt.logs())
}

/// Accumulate deposits from a receipt. Iterates over the logs in the receipt
/// and accumulates the deposit request bytestrings.
pub fn accumulate_deposits_from_receipt(receipt: &ReceiptEnvelope, out: &mut dyn BufMut) {
accumulate_deposits_from_logs(receipt.logs(), out);
}

/// Accumulate deposits from a list of receipts. Iterates over the logs in the
/// receipts and accumulates the deposit request bytestrings.
pub fn accumulate_deposits_from_receipts<'a, I>(receipts: I, out: &mut dyn BufMut)
where
I: IntoIterator<Item = &'a ReceiptEnvelope>,
{
receipts.into_iter().for_each(|receipt| accumulate_deposits_from_receipt(receipt, out));
}

/// Find deposit logs in a list of receipts, and return the concatenated
/// deposit request bytestring.
pub fn deposits_from_receipts<'a, I>(receipts: I) -> Bytes
where
I: IntoIterator<Item = &'a ReceiptEnvelope>,
{
let mut out = Vec::new();
accumulate_deposits_from_receipts(receipts, &mut out);
out.into()
}

// Some code above is reproduced from `reth`. It is reused here under the MIT
// license.
//
Expand All @@ -117,46 +144,44 @@ pub fn check_receipt_for_deposits(
// THE SOFTWARE.

#[cfg(test)]
mod test {
use alloy::{
consensus::{Receipt, ReceiptEnvelope},
eips::eip6110::MAINNET_DEPOSIT_CONTRACT_ADDRESS,
};
use alloy_primitives::{Log, LogData};
use alloy_sol_types::SolEvent;

use super::DepositEvent;
mod tests {
use super::*;
use alloy::consensus::{Receipt, ReceiptEnvelope};
use alloy_primitives::bytes;

#[test]
fn test_eip6110() {
let receipt = Receipt {
logs: vec![Log {
address: MAINNET_DEPOSIT_CONTRACT_ADDRESS,
data: LogData::new_unchecked(
vec![DepositEvent::SIGNATURE_HASH],
DepositEvent {
pubkey: [1; 48].to_vec().into(),
withdrawal_credentials: [2; 32].to_vec().into(),
amount: [3; 8].to_vec().into(),
signature: [4; 96].to_vec().into(),
index: [5; 8].to_vec().into(),
}
.encode_data()
.into(),
),
}],
status: true.into(),
cumulative_gas_used: 0,
};

let deposits: Vec<_> =
super::check_receipt_for_deposits(&ReceiptEnvelope::Eip1559(receipt.into())).collect();
fn test_parse_deposit_from_log() {
let receipts = vec![
// https://etherscan.io/tx/0xa5239d4c542063d29022545835815b78b09f571f2bf1c8427f4765d6f5abbce9
#[allow(clippy::needless_update)] // side-effect of optimism fields
ReceiptEnvelope::Legacy(Receipt {
// these don't matter
status: true.into(),
cumulative_gas_used: 0,
logs: serde_json::from_str(
r#"[{"address":"0x00000000219ab540356cbb839cbe05303d7705fa","topics":["0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"],"data":"0x00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030998c8086669bf65e24581cda47d8537966e9f5066fc6ffdcba910a1bfb91eae7a4873fcce166a1c4ea217e6b1afd396200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002001000000000000000000000001c340fb72ed14d4eaa71f7633ee9e33b88d4f3900000000000000000000000000000000000000000000000000000000000000080040597307000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006098ddbffd700c1aac324cfdf0492ff289223661eb26718ce3651ba2469b22f480d56efab432ed91af05a006bde0c1ea68134e0acd8cacca0c13ad1f716db874b44abfcc966368019753174753bca3af2ea84bc569c46f76592a91e97f311eddec0000000000000000000000000000000000000000000000000000000000000008e474160000000000000000000000000000000000000000000000000000000000","blockHash":"0x8d1289c5a7e0965b1d1bb75cdc4c3f73dda82d4ebb94ff5b98d1389cebd53b56","blockNumber":"0x12f0d8d","transactionHash":"0xa5239d4c542063d29022545835815b78b09f571f2bf1c8427f4765d6f5abbce9","transactionIndex":"0xc4","logIndex":"0x18f","removed":false}]"#
).unwrap(),
..Default::default()
}.with_bloom()),
// https://etherscan.io/tx/0xd9734d4e3953bcaa939fd1c1d80950ee54aeecc02eef6ae8179f47f5b7103338
#[allow(clippy::needless_update)] // side-effect of optimism fields
ReceiptEnvelope::Legacy(Receipt {
// these don't matter
status: true.into(),
cumulative_gas_used: 0,
logs: serde_json::from_str(
r#"[{"address":"0x00000000219ab540356cbb839cbe05303d7705fa","topics":["0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"],"data":"0x00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030a1a2ba870a90e889aa594a0cc1c6feffb94c2d8f65646c937f1f456a315ef649533e25a4614d8f4f66ebdb06481b90af0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200100000000000000000000000a0f04a231efbc29e1db7d086300ff550211c2f6000000000000000000000000000000000000000000000000000000000000000800405973070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060ad416d590e1a7f52baff770a12835b68904efad22cc9f8ba531e50cbbd26f32b9c7373cf6538a0577f501e4d3e3e63e208767bcccaae94e1e3720bfb734a286f9c017d17af46536545ccb7ca94d71f295e71f6d25bf978c09ada6f8d3f7ba0390000000000000000000000000000000000000000000000000000000000000008e374160000000000000000000000000000000000000000000000000000000000","blockHash":"0x8d1289c5a7e0965b1d1bb75cdc4c3f73dda82d4ebb94ff5b98d1389cebd53b56","blockNumber":"0x12f0d8d","transactionHash":"0xd9734d4e3953bcaa939fd1c1d80950ee54aeecc02eef6ae8179f47f5b7103338","transactionIndex":"0x7c","logIndex":"0xe2","removed":false}]"#,
).unwrap(),
..Default::default()
}.with_bloom()),
];

assert_eq!(deposits.len(), 1);
assert_eq!(deposits[0].pubkey, [1; 48]);
assert_eq!(deposits[0].withdrawal_credentials, [2; 32]);
assert_eq!(deposits[0].amount, 0x0303030303030303);
assert_eq!(deposits[0].signature, [4; 96]);
assert_eq!(deposits[0].index, 0x0505050505050505);
let request_data = deposits_from_receipts(&receipts);
assert_eq!(
request_data,
bytes!(
"998c8086669bf65e24581cda47d8537966e9f5066fc6ffdcba910a1bfb91eae7a4873fcce166a1c4ea217e6b1afd396201000000000000000000000001c340fb72ed14d4eaa71f7633ee9e33b88d4f39004059730700000098ddbffd700c1aac324cfdf0492ff289223661eb26718ce3651ba2469b22f480d56efab432ed91af05a006bde0c1ea68134e0acd8cacca0c13ad1f716db874b44abfcc966368019753174753bca3af2ea84bc569c46f76592a91e97f311eddece474160000000000a1a2ba870a90e889aa594a0cc1c6feffb94c2d8f65646c937f1f456a315ef649533e25a4614d8f4f66ebdb06481b90af0100000000000000000000000a0f04a231efbc29e1db7d086300ff550211c2f60040597307000000ad416d590e1a7f52baff770a12835b68904efad22cc9f8ba531e50cbbd26f32b9c7373cf6538a0577f501e4d3e3e63e208767bcccaae94e1e3720bfb734a286f9c017d17af46536545ccb7ca94d71f295e71f6d25bf978c09ada6f8d3f7ba039e374160000000000"
)
);
}
}
29 changes: 8 additions & 21 deletions src/system/eip7002.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::{checked_insert_code, execute_system_tx};
use crate::{system::SystemTx, EvmNeedsTx};
use alloy::eips::eip7002::{WithdrawalRequest, WITHDRAWAL_REQUEST_PREDEPLOY_CODE};
use alloy::eips::eip7002::WITHDRAWAL_REQUEST_PREDEPLOY_CODE;
use alloy_primitives::{Address, Bytes};
use revm::{
primitives::{EVMError, SpecId},
Expand Down Expand Up @@ -48,12 +48,12 @@ impl<'a, Ext, Db: Database + DatabaseCommit> EvmNeedsTx<'a, Ext, Db> {
/// request contract to accumulate withdrawal requests.
///
/// [EIP-7002]: https://eips.ethereum.org/EIPS/eip-7002
pub fn apply_eip7002(&mut self) -> Result<Vec<WithdrawalRequest>, EVMError<Db::Error>>
pub fn apply_eip7002(&mut self) -> Result<Bytes, EVMError<Db::Error>>
where
Db: Database + DatabaseCommit,
{
if self.spec_id() < SpecId::PRAGUE {
return Ok(vec![]);
return Ok(Bytes::new());
}

checked_insert_code(
Expand All @@ -75,19 +75,7 @@ impl<'a, Ext, Db: Database + DatabaseCommit> EvmNeedsTx<'a, Ext, Db> {
panic!("execution halted during withdrawal request system contract execution")
};

let mut requests = vec![];

requests.extend(output.chunks_exact(WITHDRAWAL_REQUEST_BYTES).map(|chunk| {
let mut req: WithdrawalRequest = Default::default();

req.source_address.copy_from_slice(&chunk[0..20]);
req.validator_pubkey.copy_from_slice(&chunk[20..68]);
req.amount = u64::from_be_bytes(chunk[68..76].try_into().unwrap());

req
}));

Ok(requests)
Ok(output.clone())
}
}

Expand Down Expand Up @@ -131,11 +119,10 @@ mod test {

let requests = trevm.apply_eip7002().unwrap();

assert_eq!(requests.len(), 1);

let withdrawal_request = requests[0];
assert_eq!(requests.len(), WITHDRAWAL_REQUEST_BYTES);

assert_eq!(withdrawal_request.validator_pubkey, VALIDATOR_PUBKEY);
assert_eq!(withdrawal_request.source_address, WITHDRAWAL_ADDR);
assert_eq!(&requests[0..20], WITHDRAWAL_ADDR.as_slice());
assert_eq!(&requests[20..68], VALIDATOR_PUBKEY.as_slice());
assert_eq!(&requests[68..], WITHDRAWAL_AMOUNT.as_slice());
}
}
Loading