Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
8 changes: 6 additions & 2 deletions crates/core/src/types/engine/payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use crate::rlp::decode::RLPDecode;
use crate::{rlp::error::RLPDecodeError, serde_utils};

use crate::types::{
compute_withdrawals_root, BlockBody, BlockHeader, EIP1559Transaction, LegacyTransaction,
Transaction, Withdrawal, DEFAULT_OMMERS_HASH,
compute_withdrawals_root, BlockBody, BlockHeader, EIP1559Transaction, EIP2930Transaction,
LegacyTransaction, Transaction, Withdrawal, DEFAULT_OMMERS_HASH,
};

#[allow(unused)]
Expand Down Expand Up @@ -73,6 +73,10 @@ impl EncodedTransaction {
match *tx_type {
// Legacy
0x0 => LegacyTransaction::decode(tx_bytes).map(Transaction::LegacyTransaction), // TODO: check if this is a real case scenario
// EIP2930
0x1 => {
EIP2930Transaction::decode(tx_bytes).map(Transaction::EIP2930Transaction)
}
// EIP1559
0x2 => {
EIP1559Transaction::decode(tx_bytes).map(Transaction::EIP1559Transaction)
Expand Down
98 changes: 98 additions & 0 deletions crates/core/src/types/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::rlp::{
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Transaction {
LegacyTransaction(LegacyTransaction),
EIP2930Transaction(EIP2930Transaction),
EIP1559Transaction(EIP1559Transaction),
}

Expand All @@ -32,6 +33,21 @@ pub struct LegacyTransaction {
pub s: U256,
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct EIP2930Transaction {
pub chain_id: u64,
pub nonce: u64,
pub gas_price: u64,
pub gas_limit: u64,
pub to: TxKind,
pub value: U256,
pub data: Bytes,
pub access_list: Vec<(Address, Vec<H256>)>,
pub signature_y_parity: bool,
pub signature_r: U256,
pub signature_s: U256,
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct EIP1559Transaction {
pub chain_id: u64,
Expand Down Expand Up @@ -72,6 +88,7 @@ impl Transaction {
pub fn tx_type(&self) -> TxType {
match self {
Transaction::LegacyTransaction(_) => TxType::Legacy,
Transaction::EIP2930Transaction(_) => TxType::EIP2930,
Transaction::EIP1559Transaction(_) => TxType::EIP1559,
}
}
Expand All @@ -81,6 +98,7 @@ impl RLPEncode for Transaction {
fn encode(&self, buf: &mut dyn bytes::BufMut) {
match self {
Transaction::LegacyTransaction(t) => t.encode(buf),
Transaction::EIP2930Transaction(t) => t.encode(buf),
Transaction::EIP1559Transaction(t) => t.encode(buf),
};
}
Expand Down Expand Up @@ -128,6 +146,24 @@ impl RLPEncode for LegacyTransaction {
}
}

impl RLPEncode for EIP2930Transaction {
fn encode(&self, buf: &mut dyn bytes::BufMut) {
Encoder::new(buf)
.encode_field(&self.chain_id)
.encode_field(&self.nonce)
.encode_field(&self.gas_price)
.encode_field(&self.gas_limit)
.encode_field(&self.to)
.encode_field(&self.value)
.encode_field(&self.data)
.encode_field(&self.access_list)
.encode_field(&self.signature_y_parity)
.encode_field(&self.signature_r)
.encode_field(&self.signature_s)
.finish();
}
}

impl RLPEncode for EIP1559Transaction {
fn encode(&self, buf: &mut dyn bytes::BufMut) {
Encoder::new(buf)
Expand Down Expand Up @@ -175,6 +211,38 @@ impl RLPDecode for LegacyTransaction {
}
}

impl RLPDecode for EIP2930Transaction {
fn decode_unfinished(rlp: &[u8]) -> Result<(EIP2930Transaction, &[u8]), RLPDecodeError> {
let decoder = Decoder::new(rlp)?;
let (chain_id, decoder) = decoder.decode_field("chain_id")?;
let (nonce, decoder) = decoder.decode_field("nonce")?;
let (gas_price, decoder) = decoder.decode_field("gas_price")?;
let (gas_limit, decoder) = decoder.decode_field("gas_limit")?;
let (to, decoder) = decoder.decode_field("to")?;
let (value, decoder) = decoder.decode_field("value")?;
let (data, decoder) = decoder.decode_field("data")?;
let (access_list, decoder) = decoder.decode_field("access_list")?;
let (signature_y_parity, decoder) = decoder.decode_field("signature_y_parity")?;
let (signature_r, decoder) = decoder.decode_field("signature_r")?;
let (signature_s, decoder) = decoder.decode_field("signature_s")?;

let tx = EIP2930Transaction {
chain_id,
nonce,
gas_price,
gas_limit,
to,
value,
data,
access_list,
signature_y_parity,
signature_r,
signature_s,
};
Ok((tx, decoder.finish()?))
}
}

impl RLPDecode for EIP1559Transaction {
fn decode_unfinished(rlp: &[u8]) -> Result<(EIP1559Transaction, &[u8]), RLPDecodeError> {
let decoder = Decoder::new(rlp)?;
Expand Down Expand Up @@ -229,6 +297,27 @@ impl Transaction {
.finish();
recover_address(&tx.r, &tx.s, signature_y_parity, &Bytes::from(buf))
}
Transaction::EIP2930Transaction(tx) => {
let mut buf = vec![self.tx_type() as u8];
Encoder::new(&mut buf)
.encode_field(&tx.nonce)
.encode_field(&tx.gas_price)
.encode_field(&tx.gas_limit)
.encode_field(&tx.to)
.encode_field(&tx.value)
.encode_field(&tx.data)
.encode_field(&tx.access_list)
.encode_field(&tx.signature_y_parity)
.encode_field(&tx.signature_r)
.encode_field(&tx.signature_s)
.finish();
recover_address(
&tx.signature_r,
&tx.signature_s,
tx.signature_y_parity,
&Bytes::from(buf),
)
}
Transaction::EIP1559Transaction(tx) => {
let mut buf = vec![self.tx_type() as u8];
Encoder::new(&mut buf)
Expand All @@ -255,62 +344,71 @@ impl Transaction {
pub fn gas_limit(&self) -> u64 {
match self {
Transaction::LegacyTransaction(tx) => tx.gas,
Transaction::EIP2930Transaction(tx) => tx.gas_limit,
Transaction::EIP1559Transaction(tx) => tx.gas_limit,
}
}

pub fn gas_price(&self) -> u64 {
match self {
Transaction::LegacyTransaction(tx) => tx.gas_price,
Transaction::EIP2930Transaction(tx) => tx.gas_price,
Transaction::EIP1559Transaction(tx) => tx.max_fee_per_gas,
}
}

pub fn to(&self) -> TxKind {
match self {
Transaction::LegacyTransaction(tx) => tx.to.clone(),
Transaction::EIP2930Transaction(tx) => tx.to.clone(),
Transaction::EIP1559Transaction(tx) => TxKind::Call(tx.destination),
}
}

pub fn value(&self) -> U256 {
match self {
Transaction::LegacyTransaction(tx) => tx.value,
Transaction::EIP2930Transaction(tx) => tx.value,
Transaction::EIP1559Transaction(tx) => tx.amount,
}
}

pub fn max_priority_fee(&self) -> Option<u64> {
match self {
Transaction::LegacyTransaction(_tx) => None,
Transaction::EIP2930Transaction(_tx) => None,
Transaction::EIP1559Transaction(tx) => Some(tx.max_priority_fee_per_gas),
}
}

pub fn chain_id(&self) -> Option<u64> {
match self {
Transaction::LegacyTransaction(_tx) => None,
Transaction::EIP2930Transaction(tx) => Some(tx.chain_id),
Transaction::EIP1559Transaction(tx) => Some(tx.chain_id),
}
}

pub fn access_list(&self) -> Vec<(Address, Vec<H256>)> {
match self {
Transaction::LegacyTransaction(_tx) => Vec::new(),
Transaction::EIP2930Transaction(tx) => tx.access_list.clone(),
Transaction::EIP1559Transaction(tx) => tx.access_list.clone(),
}
}

pub fn nonce(&self) -> u64 {
match self {
Transaction::LegacyTransaction(tx) => tx.nonce,
Transaction::EIP2930Transaction(tx) => tx.nonce,
Transaction::EIP1559Transaction(tx) => tx.signer_nonce,
}
}

pub fn data(&self) -> &Bytes {
match self {
Transaction::LegacyTransaction(tx) => &tx.data,
Transaction::EIP2930Transaction(tx) => &tx.data,
Transaction::EIP1559Transaction(tx) => &tx.payload,
}
}
Expand Down