-
Notifications
You must be signed in to change notification settings - Fork 8
ADR 003 implementation: custom EvTransaction using EIP-2718, with sponsorship and atomic batch txs. #103
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
base: main
Are you sure you want to change the base?
ADR 003 implementation: custom EvTransaction using EIP-2718, with sponsorship and atomic batch txs. #103
Changes from all commits
93cb8fd
d525ad2
77e5614
9e61d28
738d8f9
0992079
400e072
d8cf5f5
3c1af2b
f5e1c19
e182cdd
185a52e
dae3ab6
0f23ac3
d10f79e
46081cc
073760c
5555a95
c921f2f
25c810a
b735012
71b419f
9b49507
fb81941
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,7 @@ resolver = "2" | |
| members = [ | ||
| "bin/ev-reth", | ||
| "crates/common", | ||
| "crates/ev-primitives", | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this needs to be a separate crate because multiple other crates depend on it and there would be no way to include them in one of the existing ones without circular imports is that correct? |
||
| "crates/evolve", | ||
| "crates/node", | ||
| "crates/tests", | ||
|
|
@@ -47,13 +48,14 @@ reth-transaction-pool = { git = "https://github.com/paradigmxyz/reth.git", tag = | |
| reth-network = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" } | ||
| reth-network-types = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" } | ||
| reth-chain-state = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" } | ||
| reth-db-api = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" } | ||
| reth-ethereum = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" } | ||
| reth-ethereum-cli = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" } | ||
| reth-basic-payload-builder = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" } | ||
| reth-engine-local = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" } | ||
| reth-engine-primitives = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" } | ||
| reth-ethereum-payload-builder = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" } | ||
| reth-ethereum-primitives = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" } | ||
| reth-ethereum-primitives = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4", features = ["serde", "serde-bincode-compat", "reth-codec"] } | ||
| reth-e2e-test-utils = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" } | ||
| reth-evm = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" } | ||
| reth-evm-ethereum = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" } | ||
|
|
@@ -69,8 +71,12 @@ reth-revm = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" } | |
| reth-rpc-api = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" } | ||
| reth-rpc-builder = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" } | ||
| reth-rpc-engine-api = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" } | ||
| reth-rpc = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" } | ||
| reth-rpc-convert = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" } | ||
| reth-codecs = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" } | ||
|
|
||
| ev-revm = { path = "crates/ev-revm" } | ||
| ev-primitives = { path = "crates/ev-primitives" } | ||
|
|
||
|
|
||
| # Consensus dependencies | ||
|
|
@@ -106,12 +112,18 @@ alloy-rpc-types-eth = { version = "1.0.37", default-features = false } | |
| alloy-rpc-types-engine = { version = "1.0.37", default-features = false } | ||
| alloy-signer = { version = "1.0.37", default-features = false } | ||
| alloy-signer-local = { version = "1.0.37", features = ["mnemonic"] } | ||
| alloy-serde = { version = "1.0.37", default-features = false } | ||
| alloy-primitives = { version = "1.3.1", default-features = false } | ||
| alloy-consensus = { version = "1.0.37", default-features = false } | ||
| alloy-consensus-any = { version = "1.0.37", default-features = false } | ||
| alloy-rlp = { version = "0.3.12", default-features = false } | ||
| alloy-genesis = { version = "1.0.37", default-features = false } | ||
| alloy-rpc-types-txpool = { version = "1.0.37", default-features = false } | ||
| alloy-sol-types = { version = "1.3.1", default-features = false } | ||
|
|
||
| # Utility dependencies | ||
| bytes = "1.10.1" | ||
|
|
||
| revm-inspector = { version = "10.0.1" } | ||
| # Core dependencies | ||
| eyre = "0.6" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| [package] | ||
| name = "ev-primitives" | ||
| version = "0.1.0" | ||
| edition = "2021" | ||
| rust-version = "1.82" | ||
| license = "MIT OR Apache-2.0" | ||
|
|
||
| [dependencies] | ||
| alloy-consensus = { workspace = true } | ||
| alloy-eips = { workspace = true, features = ["serde"] } | ||
| alloy-primitives = { workspace = true, features = ["k256", "rlp", "serde"] } | ||
| alloy-serde = { workspace = true } | ||
| alloy-rlp = { workspace = true, features = ["derive"] } | ||
| bytes = { workspace = true } | ||
| reth-codecs = { workspace = true } | ||
| reth-db-api = { workspace = true } | ||
| reth-ethereum-primitives = { workspace = true } | ||
| reth-primitives-traits = { workspace = true, features = ["serde-bincode-compat"] } | ||
| serde = { workspace = true, features = ["derive"] } | ||
|
|
||
| [features] | ||
| serde-bincode-compat = ["reth-primitives-traits/serde-bincode-compat"] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| //! EV-specific primitive types, including the EvNode 0x76 transaction. | ||
| mod pool; | ||
| mod tx; | ||
|
|
||
| pub use pool::{EvPooledTxEnvelope, EvPooledTxType}; | ||
| pub use tx::{ | ||
| Call, EvNodeSignedTx, EvNodeTransaction, EvTxEnvelope, EvTxType, TransactionSigned, | ||
| EVNODE_SPONSOR_DOMAIN, EVNODE_TX_TYPE_ID, | ||
| }; | ||
|
|
||
| use reth_primitives_traits::NodePrimitives; | ||
|
|
||
| /// Block type alias for ev-reth. | ||
| pub type Block = alloy_consensus::Block<TransactionSigned>; | ||
|
|
||
| /// Block body type alias for ev-reth. | ||
| pub type BlockBody = alloy_consensus::BlockBody<TransactionSigned>; | ||
|
|
||
| /// Receipt type alias for ev-reth. | ||
| pub type Receipt = reth_ethereum_primitives::Receipt<EvTxType>; | ||
|
|
||
| /// Helper struct that specifies the ev-reth NodePrimitives types. | ||
| #[derive(Debug, Clone, Default, PartialEq, Eq)] | ||
| pub struct EvPrimitives; | ||
|
|
||
| impl NodePrimitives for EvPrimitives { | ||
| type Block = Block; | ||
| type BlockHeader = alloy_consensus::Header; | ||
| type BlockBody = BlockBody; | ||
| type SignedTx = TransactionSigned; | ||
| type Receipt = Receipt; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| //! Pooled transaction envelope for ev-reth. | ||
| use alloy_consensus::{ | ||
| error::ValueError, | ||
| transaction::{SignerRecoverable, TxHashRef}, | ||
| TransactionEnvelope, | ||
| }; | ||
| use alloy_primitives::{Address, B256}; | ||
| use reth_primitives_traits::{InMemorySize, SignedTransaction}; | ||
|
|
||
| use crate::tx::{EvNodeSignedTx, EvTxEnvelope}; | ||
|
|
||
| /// Pooled transaction envelope with optional blob sidecar support. | ||
| #[derive(Clone, Debug, TransactionEnvelope)] | ||
| #[envelope(tx_type_name = EvPooledTxType)] | ||
| pub enum EvPooledTxEnvelope { | ||
| /// Standard Ethereum pooled transaction envelope (may include blob sidecar). | ||
| #[envelope(flatten)] | ||
| Ethereum(reth_ethereum_primitives::PooledTransactionVariant), | ||
| /// EvNode typed transaction (no sidecar). | ||
| #[envelope(ty = 0x76)] | ||
| EvNode(EvNodeSignedTx), | ||
| } | ||
|
|
||
| impl InMemorySize for EvPooledTxEnvelope { | ||
| fn size(&self) -> usize { | ||
| match self { | ||
| EvPooledTxEnvelope::Ethereum(tx) => tx.size(), | ||
| EvPooledTxEnvelope::EvNode(tx) => tx.size(), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl SignerRecoverable for EvPooledTxEnvelope { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. only comment really in this file is just adding some docs about why we're implementing all these traits, that might be the most valuable addition. |
||
| fn recover_signer(&self) -> Result<Address, alloy_consensus::crypto::RecoveryError> { | ||
| match self { | ||
| EvPooledTxEnvelope::Ethereum(tx) => tx.recover_signer(), | ||
| EvPooledTxEnvelope::EvNode(tx) => tx | ||
| .signature() | ||
| .recover_address_from_prehash(&tx.tx().executor_signing_hash()) | ||
| .map_err(|_| alloy_consensus::crypto::RecoveryError::new()), | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is there a corresponding EDIT: I think the answer is no, and the lib itself discards errors intentionally. |
||
| } | ||
| } | ||
|
|
||
| fn recover_signer_unchecked(&self) -> Result<Address, alloy_consensus::crypto::RecoveryError> { | ||
| self.recover_signer() | ||
| } | ||
| } | ||
|
|
||
| impl TxHashRef for EvPooledTxEnvelope { | ||
| fn tx_hash(&self) -> &B256 { | ||
| match self { | ||
| EvPooledTxEnvelope::Ethereum(tx) => tx.tx_hash(), | ||
| EvPooledTxEnvelope::EvNode(tx) => tx.hash(), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl TryFrom<EvTxEnvelope> for EvPooledTxEnvelope { | ||
| type Error = ValueError<reth_ethereum_primitives::TransactionSigned>; | ||
|
|
||
| fn try_from(value: EvTxEnvelope) -> Result<Self, Self::Error> { | ||
| match value { | ||
| EvTxEnvelope::Ethereum(tx) => Ok(Self::Ethereum(tx.try_into()?)), | ||
| EvTxEnvelope::EvNode(tx) => Ok(Self::EvNode(tx)), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl From<EvPooledTxEnvelope> for EvTxEnvelope { | ||
| fn from(value: EvPooledTxEnvelope) -> Self { | ||
| match value { | ||
| EvPooledTxEnvelope::Ethereum(tx) => EvTxEnvelope::Ethereum(tx.into()), | ||
| EvPooledTxEnvelope::EvNode(tx) => EvTxEnvelope::EvNode(tx), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl SignedTransaction for EvPooledTxEnvelope {} | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we remove this?