From 86150bd86893dbfdcf101d3e3d8a86fd661a278b Mon Sep 17 00:00:00 2001 From: andreespirela <60560109+andreespirela@users.noreply.github.com> Date: Mon, 21 Oct 2024 17:15:27 -0400 Subject: [PATCH] Revert "Revert "feat: Control behavior of structs and map them when its a transaction"" --- Cargo.lock | 16 ++ Cargo.toml | 1 + wvm-apps/wvm-exexed/Cargo.toml | 1 + .../src/inner/wvm_block_precompile.rs | 13 + wvm-apps/wvm-exexed/crates/tx/Cargo.toml | 20 ++ wvm-apps/wvm-exexed/crates/tx/src/lib.rs | 241 ++++++++++++++++++ .../wvm-exexed/crates/wvm-borsh/Cargo.toml | 1 + .../crates/wvm-borsh/src/signature.rs | 2 +- .../crates/wvm-borsh/src/transaction.rs | 47 +++- 9 files changed, 339 insertions(+), 3 deletions(-) create mode 100644 wvm-apps/wvm-exexed/crates/tx/Cargo.toml create mode 100644 wvm-apps/wvm-exexed/crates/tx/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 76096926a567..e09212400a74 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15510,6 +15510,7 @@ dependencies = [ "serde", "serde_json", "tokio", + "wvm-tx", ] [[package]] @@ -15551,6 +15552,7 @@ dependencies = [ "tracing", "wvm-borsh", "wvm-static", + "wvm-tx", ] [[package]] @@ -15566,6 +15568,20 @@ dependencies = [ "tracing", ] +[[package]] +name = "wvm-tx" +version = "1.0.8" +dependencies = [ + "alloy-consensus 0.4.2", + "alloy-eips 0.4.2", + "alloy-primitives", + "alloy-serde 0.4.2", + "op-alloy-consensus", + "reth-primitives", + "serde", + "serde_json", +] + [[package]] name = "wyz" version = "0.5.1" diff --git a/Cargo.toml b/Cargo.toml index d10dbd9c3eda..efb505259864 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -157,6 +157,7 @@ members = [ "wvm-apps/wvm-exexed/crates/wvm-borsh/", "wvm-apps/wvm-exexed/crates/static/", "wvm-apps/wvm-exexed/crates/brotli/", + "wvm-apps/wvm-exexed/crates/tx/", ] default-members = ["bin/reth"] exclude = ["book/sources"] diff --git a/wvm-apps/wvm-exexed/Cargo.toml b/wvm-apps/wvm-exexed/Cargo.toml index 85953c48e371..c519d85422f9 100644 --- a/wvm-apps/wvm-exexed/Cargo.toml +++ b/wvm-apps/wvm-exexed/Cargo.toml @@ -41,6 +41,7 @@ wvm-borsh = { path = "crates/wvm-borsh" } wvm-static = { path = "crates/static" } exex-etl = { path = "crates/exex-etl" } rbrotli = { path = "crates/brotli" } +wvm-tx = { path = "crates/tx" } borsh.workspace = true parse_duration.workspace = true diff --git a/wvm-apps/wvm-exexed/crates/precompiles/src/inner/wvm_block_precompile.rs b/wvm-apps/wvm-exexed/crates/precompiles/src/inner/wvm_block_precompile.rs index 507a7013e869..05175220226d 100644 --- a/wvm-apps/wvm-exexed/crates/precompiles/src/inner/wvm_block_precompile.rs +++ b/wvm-apps/wvm-exexed/crates/precompiles/src/inner/wvm_block_precompile.rs @@ -233,4 +233,17 @@ mod arweave_read_pc_tests { .to_vec() ); } + + #[test] + pub fn test_read_wvm_block_fix_test_141550_hash() { + let input = Bytes::from("141550;hash".as_bytes()); + let PrecompileOutput { gas_used, bytes } = wvm_read_block_pc(&input, 100_000).unwrap(); + assert_eq!(bytes.len(), 66); + assert_eq!( + bytes.to_vec(), + "0xb69e1a4a19c665b0573f74b2bf8e4824cb5b54176f4ad45b730f047e880cf5cc" + .as_bytes() + .to_vec() + ); + } } diff --git a/wvm-apps/wvm-exexed/crates/tx/Cargo.toml b/wvm-apps/wvm-exexed/crates/tx/Cargo.toml new file mode 100644 index 000000000000..f994f138dd66 --- /dev/null +++ b/wvm-apps/wvm-exexed/crates/tx/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "wvm-tx" +version.workspace = true +edition.workspace = true +rust-version.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +alloy-consensus.workspace = true +op-alloy-consensus.workspace = true +alloy-primitives.workspace = true +alloy-serde.workspace = true +alloy-eips.workspace = true +serde.workspace = true +serde_json.workspace = true +reth-primitives = { workspace = true } + +[features] +optimism = ["reth-primitives/optimism"] \ No newline at end of file diff --git a/wvm-apps/wvm-exexed/crates/tx/src/lib.rs b/wvm-apps/wvm-exexed/crates/tx/src/lib.rs new file mode 100644 index 000000000000..7d49ffd236b8 --- /dev/null +++ b/wvm-apps/wvm-exexed/crates/tx/src/lib.rs @@ -0,0 +1,241 @@ +use alloy_eips::eip2930::AccessList; +use alloy_eips::eip7702::SignedAuthorization; +use alloy_primitives::{Address, Bytes, ChainId, TxKind, B256, U256}; +use reth_primitives::Transaction; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct TxLegacy { + #[serde(default, with = "alloy_serde::quantity::opt", skip_serializing_if = "Option::is_none")] + #[serde(rename = "chainId", alias = "chain_id")] + pub chain_id: Option, + #[serde(with = "alloy_serde::quantity")] + pub nonce: u64, + #[serde(rename = "gasPrice", alias = "gas_price")] + #[serde(with = "alloy_serde::quantity")] + pub gas_price: u128, + #[serde(rename = "gasLimit", alias = "gas_limit")] + #[serde(with = "alloy_serde::quantity")] + pub gas_limit: u64, + #[serde(default, skip_serializing_if = "TxKind::is_create")] + pub to: TxKind, + pub value: U256, + pub input: Bytes, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct TxEip7702 { + #[serde(with = "alloy_serde::quantity")] + #[serde(rename = "chainId", alias = "chain_id")] + pub chain_id: ChainId, + #[serde(with = "alloy_serde::quantity")] + pub nonce: u64, + #[serde(rename = "gasLimit", alias = "gas_limit")] + #[serde(with = "alloy_serde::quantity")] + pub gas_limit: u64, + #[serde(rename = "maxFeePerGas", alias = "max_fee_per_gas")] + #[serde(with = "alloy_serde::quantity")] + pub max_fee_per_gas: u128, + #[serde(rename = "maxPriorityFeePerGas", alias = "max_priority_fee_per_gas")] + #[serde(with = "alloy_serde::quantity")] + pub max_priority_fee_per_gas: u128, + + pub to: Address, + pub value: U256, + #[serde(rename = "accessList", alias = "access_list")] + pub access_list: AccessList, + #[serde(rename = "authorizationList", alias = "authorization_list")] + pub authorization_list: Vec, + pub input: Bytes, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct TxEip4844 { + #[serde(rename = "chainId", alias = "chain_id")] + #[serde(with = "alloy_serde::quantity")] + pub chain_id: ChainId, + #[serde(with = "alloy_serde::quantity")] + pub nonce: u64, + + #[serde(rename = "gasLimit", alias = "gas_limit")] + #[serde(with = "alloy_serde::quantity")] + pub gas_limit: u64, + + #[serde(rename = "maxFeePerGas", alias = "max_fee_per_gas")] + #[serde(with = "alloy_serde::quantity")] + pub max_fee_per_gas: u128, + + #[serde(rename = "maxPriorityFeePerGas", alias = "max_priority_fee_per_gas")] + #[serde(with = "alloy_serde::quantity")] + pub max_priority_fee_per_gas: u128, + + pub to: Address, + + pub value: U256, + + pub access_list: AccessList, + + pub blob_versioned_hashes: Vec, + + #[serde(rename = "maxFeePerBlobGas", alias = "max_fee_per_blob_gas")] + #[serde(with = "alloy_serde::quantity")] + pub max_fee_per_blob_gas: u128, + pub input: Bytes, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct TxEip2930 { + #[serde(with = "alloy_serde::quantity")] + #[serde(rename = "chainId", alias = "chain_id")] + pub chain_id: ChainId, + #[serde(with = "alloy_serde::quantity")] + pub nonce: u64, + #[serde(rename = "gasPrice", alias = "gas_price")] + #[serde(with = "alloy_serde::quantity")] + pub gas_price: u128, + #[serde(rename = "gasLimit", alias = "gas_limit")] + #[serde(with = "alloy_serde::quantity")] + pub gas_limit: u64, + #[serde(default, skip_serializing_if = "TxKind::is_create")] + pub to: TxKind, + pub value: U256, + #[serde(rename = "accessList", alias = "access_list")] + pub access_list: AccessList, + pub input: Bytes, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct TxEip1559 { + #[serde(with = "alloy_serde::quantity")] + #[serde(rename = "chainId", alias = "chain_id")] + pub chain_id: ChainId, + #[serde(with = "alloy_serde::quantity")] + pub nonce: u64, + #[serde(rename = "gasLimit", alias = "gas_limit")] + #[serde(with = "alloy_serde::quantity")] + pub gas_limit: u64, + #[serde(rename = "maxFeePerGas", alias = "max_fee_per_gas")] + #[serde(with = "alloy_serde::quantity")] + pub max_fee_per_gas: u128, + #[serde(rename = "maxPriorityFeePerGas", alias = "max_priority_fee_per_gas")] + #[serde(with = "alloy_serde::quantity")] + pub max_priority_fee_per_gas: u128, + #[serde(default, skip_serializing_if = "TxKind::is_create")] + pub to: TxKind, + pub value: U256, + #[serde(rename = "accessList", alias = "access_list")] + pub access_list: AccessList, + pub input: Bytes, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct TxDeposit { + #[serde(rename = "sourceHash", alias = "source_hash")] + pub source_hash: B256, + pub from: Address, + #[serde(default, skip_serializing_if = "TxKind::is_create")] + pub to: TxKind, + #[serde(default, with = "alloy_serde::quantity::opt")] + pub mint: Option, + pub value: U256, + #[serde(rename = "gasLimit", alias = "gas_limit")] + #[serde(with = "alloy_serde::quantity")] + pub gas_limit: u64, + #[serde( + with = "alloy_serde::quantity", + rename = "isSystemTx", + alias = "is_system_transaction" + )] + pub is_system_transaction: bool, + pub input: Bytes, +} + +#[derive(Serialize, Deserialize, Debug)] +pub enum WvmTransaction { + Legacy(TxLegacy), + Eip2930(TxEip2930), + Eip1559(TxEip1559), + Eip4844(TxEip4844), + Eip7702(TxEip7702), + #[cfg(feature = "optimism")] + Deposit(TxDeposit), +} + +impl Into for WvmTransaction { + fn into(self) -> Transaction { + match self { + WvmTransaction::Legacy(data) => Transaction::Legacy(alloy_consensus::TxLegacy { + chain_id: data.chain_id, + nonce: data.nonce, + gas_price: data.gas_price, + gas_limit: data.gas_limit, + to: data.to, + value: data.value, + input: data.input, + }), + WvmTransaction::Eip2930(data) => Transaction::Eip2930(alloy_consensus::TxEip2930 { + chain_id: data.chain_id, + nonce: data.nonce, + gas_price: data.gas_price, + gas_limit: data.gas_limit, + to: data.to, + value: data.value, + access_list: data.access_list, + input: data.input, + }), + WvmTransaction::Eip1559(data) => Transaction::Eip1559(alloy_consensus::TxEip1559 { + chain_id: data.chain_id, + nonce: data.nonce, + gas_limit: data.gas_limit, + max_fee_per_gas: data.max_fee_per_gas, + max_priority_fee_per_gas: data.max_priority_fee_per_gas, + to: data.to, + value: data.value, + access_list: data.access_list, + input: data.input, + }), + WvmTransaction::Eip4844(data) => Transaction::Eip4844(alloy_consensus::TxEip4844 { + chain_id: data.chain_id, + nonce: data.nonce, + gas_limit: data.gas_limit, + max_fee_per_gas: data.max_fee_per_gas, + max_priority_fee_per_gas: data.max_priority_fee_per_gas, + to: data.to, + value: data.value, + access_list: data.access_list, + blob_versioned_hashes: data.blob_versioned_hashes, + max_fee_per_blob_gas: data.max_fee_per_blob_gas, + input: data.input, + }), + WvmTransaction::Eip7702(data) => Transaction::Eip7702(alloy_consensus::TxEip7702 { + chain_id: data.chain_id, + nonce: data.nonce, + gas_limit: data.gas_limit, + max_fee_per_gas: data.max_fee_per_gas, + max_priority_fee_per_gas: data.max_priority_fee_per_gas, + to: data.to, + value: data.value, + access_list: data.access_list, + authorization_list: data.authorization_list, + input: data.input, + }), + #[cfg(feature = "optimism")] + WvmTransaction::Deposit(data) => Transaction::Deposit(op_alloy_consensus::TxDeposit { + source_hash: data.source_hash, + gas_limit: data.gas_limit, + to: data.to, + mint: data.mint, + value: data.value, + input: data.input, + from: data.from, + is_system_transaction: data.is_system_transaction, + }), + } + } +} diff --git a/wvm-apps/wvm-exexed/crates/wvm-borsh/Cargo.toml b/wvm-apps/wvm-exexed/crates/wvm-borsh/Cargo.toml index d5b161cf28c2..103227d4eb19 100644 --- a/wvm-apps/wvm-exexed/crates/wvm-borsh/Cargo.toml +++ b/wvm-apps/wvm-exexed/crates/wvm-borsh/Cargo.toml @@ -20,6 +20,7 @@ tokio = "1.38.0" borsh.workspace = true reth-primitives.workspace = true alloy-primitives.workspace = true +wvm-tx = { path = "../tx" } [dev-dependencies] diff --git a/wvm-apps/wvm-exexed/crates/wvm-borsh/src/signature.rs b/wvm-apps/wvm-exexed/crates/wvm-borsh/src/signature.rs index 127fd783a720..3e146ce0a34c 100644 --- a/wvm-apps/wvm-exexed/crates/wvm-borsh/src/signature.rs +++ b/wvm-apps/wvm-exexed/crates/wvm-borsh/src/signature.rs @@ -6,7 +6,7 @@ pub struct BorshSignature(pub Signature); pub fn to_signature(bytes: &[u8]) -> std::io::Result { if bytes.len() != 65 { - return Err(Error::from(ErrorKind::UnexpectedEof)) + return Err(Error::from(ErrorKind::UnexpectedEof)); } let mut r_bytes = [0u8; 32]; diff --git a/wvm-apps/wvm-exexed/crates/wvm-borsh/src/transaction.rs b/wvm-apps/wvm-exexed/crates/wvm-borsh/src/transaction.rs index ae679d5e39ca..55d6a54e6d9c 100644 --- a/wvm-apps/wvm-exexed/crates/wvm-borsh/src/transaction.rs +++ b/wvm-apps/wvm-exexed/crates/wvm-borsh/src/transaction.rs @@ -1,7 +1,9 @@ use crate::{b256::BorshB256, signature::BorshSignature}; use borsh::{BorshDeserialize, BorshSerialize}; use reth::primitives::{Transaction, TransactionSigned}; +use serde_json::Value; use std::io::{Read, Write}; +use wvm_tx::WvmTransaction; pub struct BorshTransactionSigned(pub TransactionSigned); pub struct BorshTransaction(pub Transaction); @@ -17,8 +19,8 @@ impl BorshSerialize for BorshTransaction { impl BorshDeserialize for BorshTransaction { fn deserialize_reader(reader: &mut R) -> std::io::Result { let bytes = Vec::::deserialize_reader(reader)?; - let tx: Transaction = serde_json::from_slice(bytes.as_slice()).unwrap(); - Ok(BorshTransaction(tx)) + let tx: WvmTransaction = serde_json::from_slice(bytes.as_slice()).unwrap(); + Ok(BorshTransaction(tx.into())) } } @@ -50,6 +52,9 @@ impl BorshDeserialize for BorshTransactionSigned { mod txs_tests { use crate::transaction::BorshTransactionSigned; use reth::primitives::TransactionSigned; + use reth_primitives::Transaction; + use serde_json::Value; + use wvm_tx::WvmTransaction; #[test] pub fn test_sealed_header() { @@ -59,4 +64,42 @@ mod txs_tests { let from_borsh: BorshTransactionSigned = borsh::from_slice(to_borsh.as_slice()).unwrap(); assert_eq!(data, from_borsh.0); } + + #[test] + pub fn test_serialize_legacy() { + let legacy_data = r#" + { + "Legacy": { + "chain_id": 9496, + "gas_limit": 28647, + "gas_price": 1000000007, + "input": "0x1b6905401c07768cbc769037274298db8131a7d1124d94122c21bc879b1a1b306e8b7feae6f98bbcf93736d20335702d5f83b3c22cf4c4b6061c4ae28f9eb96bb71a14b59774a20b24ca316980bf72c21f2004a4b39a8ab1ba4724f790d6b527f5e573d1d6d0353187fc855234919a0d62b323e5d97c6bfea2e106aa96bd60b4ea2df0aa9c55fa863cb49201d9a47d1a90c5a63d2d8190c7d128b3c5ec71f744cb1e53f68d6b8175e896ca3ae07faea23292f800ff5a4863f3d5af7de6bd836692d65b63d0ae52f5a857a9b2dbd96575b9113733758b836105e20ac086ff4c2624710c36121d430f5134b70394712096c1841ca6232e400bfd8f100c00f90d054c84befabf859ec7e734f7f5db07bb7437e2006d66f41134788e08733d537fedbe5bcf5b50cdad6ec6af74cc9bc31f810a70e18ee6b8695d5ebd014c54392fd3923c0663652afb543904cc91f278b2df07b2f3a79b677db64dc632cba544adb47b18731e120b56b0a731be8344a61b86e1786c7fc39473cadba3084723facc942ac40bd034def5d55d1ade034d2b25214b7fa820f11a8d7a70e3c3e8a95680c7be648dc840eafe82e786ddf992c4ef1537e126cd00e8614e56323b129763b13132ec155ab746e3dbef459000", + "nonce": 15974, + "to": "0xa2a0d977847805fe224b789d8c4d3d711ab251e7", + "value": "0x0" + } +}"#; + let to_tx: WvmTransaction = serde_json::from_str(legacy_data).unwrap(); + let newer_data = r#" + { + "Legacy": { + "chainId": 9496, + "gasLimit": 28647, + "gasPrice": 1000000007, + "input": "0x1b6905401c07768cbc769037274298db8131a7d1124d94122c21bc879b1a1b306e8b7feae6f98bbcf93736d20335702d5f83b3c22cf4c4b6061c4ae28f9eb96bb71a14b59774a20b24ca316980bf72c21f2004a4b39a8ab1ba4724f790d6b527f5e573d1d6d0353187fc855234919a0d62b323e5d97c6bfea2e106aa96bd60b4ea2df0aa9c55fa863cb49201d9a47d1a90c5a63d2d8190c7d128b3c5ec71f744cb1e53f68d6b8175e896ca3ae07faea23292f800ff5a4863f3d5af7de6bd836692d65b63d0ae52f5a857a9b2dbd96575b9113733758b836105e20ac086ff4c2624710c36121d430f5134b70394712096c1841ca6232e400bfd8f100c00f90d054c84befabf859ec7e734f7f5db07bb7437e2006d66f41134788e08733d537fedbe5bcf5b50cdad6ec6af74cc9bc31f810a70e18ee6b8695d5ebd014c54392fd3923c0663652afb543904cc91f278b2df07b2f3a79b677db64dc632cba544adb47b18731e120b56b0a731be8344a61b86e1786c7fc39473cadba3084723facc942ac40bd034def5d55d1ade034d2b25214b7fa820f11a8d7a70e3c3e8a95680c7be648dc840eafe82e786ddf992c4ef1537e126cd00e8614e56323b129763b13132ec155ab746e3dbef459000", + "nonce": 15974, + "to": "0xa2a0d977847805fe224b789d8c4d3d711ab251e7", + "value": "0x0" + } +}"#; + + let newer_tx: WvmTransaction = serde_json::from_str(newer_data).unwrap(); + println!("{:?}", newer_tx); + + let txs: (Transaction, Transaction) = (to_tx.into(), newer_tx.into()); + println!("{:?}", txs.0); + println!("{:?}", txs.1); + assert_eq!(txs.0.chain_id().unwrap(), 9496); + assert_eq!(txs.1.chain_id().unwrap(), 9496); + } }