Skip to content

Commit

Permalink
chore: Add alloy-rlp and reth-rpc-types-compat dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
johntaiko committed Aug 14, 2024
1 parent 9122142 commit 966cbf9
Show file tree
Hide file tree
Showing 8 changed files with 255 additions and 421 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 9 additions & 8 deletions crates/primitives/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ impl Block {
let Some(senders) =
TransactionSigned::recover_signers_unchecked(&self.body, self.body.len())
else {
return Err(self)
return Err(self);
};
senders
};
Expand Down Expand Up @@ -400,7 +400,7 @@ impl SealedBlock {
let Some(senders) =
TransactionSigned::recover_signers_unchecked(&self.body, self.body.len())
else {
return Err(self)
return Err(self);
};
senders
};
Expand Down Expand Up @@ -459,7 +459,7 @@ impl SealedBlock {
return Err(GotExpected {
got: calculated_root,
expected: self.header.transactions_root,
})
});
}

Ok(())
Expand Down Expand Up @@ -593,11 +593,12 @@ impl BlockBody {
/// Calculates a heuristic for the in-memory size of the [`BlockBody`].
#[inline]
pub fn size(&self) -> usize {
self.transactions.iter().map(TransactionSigned::size).sum::<usize>() +
self.transactions.capacity() * core::mem::size_of::<TransactionSigned>() +
self.ommers.iter().map(Header::size).sum::<usize>() +
self.ommers.capacity() * core::mem::size_of::<Header>() +
self.withdrawals
self.transactions.iter().map(TransactionSigned::size).sum::<usize>()
+ self.transactions.capacity() * core::mem::size_of::<TransactionSigned>()
+ self.ommers.iter().map(Header::size).sum::<usize>()
+ self.ommers.capacity() * core::mem::size_of::<Header>()
+ self
.withdrawals
.as_ref()
.map_or(core::mem::size_of::<Option<Withdrawals>>(), Withdrawals::total_size)
}
Expand Down
127 changes: 76 additions & 51 deletions crates/primitives/src/transaction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ use crate::compression::{TRANSACTION_COMPRESSOR, TRANSACTION_DECOMPRESSOR};
use crate::{keccak256, Address, BlockHashOrNumber, Bytes, TxHash, TxKind, B256, U256};

use alloy_rlp::{
Decodable, Encodable, Error as RlpError, Header, EMPTY_LIST_CODE, EMPTY_STRING_CODE,
encode_list, list_length, Decodable, Encodable, Error as RlpError, Header, EMPTY_LIST_CODE,
EMPTY_STRING_CODE,
};
use bytes::Buf;
use core::mem;
Expand Down Expand Up @@ -157,9 +158,9 @@ impl Transaction {
pub const fn chain_id(&self) -> Option<u64> {
match self {
Self::Legacy(TxLegacy { chain_id, .. }) => *chain_id,
Self::Eip2930(TxEip2930 { chain_id, .. }) |
Self::Eip1559(TxEip1559 { chain_id, .. }) |
Self::Eip4844(TxEip4844 { chain_id, .. }) => Some(*chain_id),
Self::Eip2930(TxEip2930 { chain_id, .. })
| Self::Eip1559(TxEip1559 { chain_id, .. })
| Self::Eip4844(TxEip4844 { chain_id, .. }) => Some(*chain_id),
#[cfg(feature = "optimism")]
Self::Deposit(_) => None,
}
Expand All @@ -169,9 +170,9 @@ impl Transaction {
pub fn set_chain_id(&mut self, chain_id: u64) {
match self {
Self::Legacy(TxLegacy { chain_id: ref mut c, .. }) => *c = Some(chain_id),
Self::Eip2930(TxEip2930 { chain_id: ref mut c, .. }) |
Self::Eip1559(TxEip1559 { chain_id: ref mut c, .. }) |
Self::Eip4844(TxEip4844 { chain_id: ref mut c, .. }) => *c = chain_id,
Self::Eip2930(TxEip2930 { chain_id: ref mut c, .. })
| Self::Eip1559(TxEip1559 { chain_id: ref mut c, .. })
| Self::Eip4844(TxEip4844 { chain_id: ref mut c, .. }) => *c = chain_id,
#[cfg(feature = "optimism")]
Self::Deposit(_) => { /* noop */ }
}
Expand All @@ -181,9 +182,9 @@ impl Transaction {
/// [`TxKind::Create`] if the transaction is a contract creation.
pub const fn kind(&self) -> TxKind {
match self {
Self::Legacy(TxLegacy { to, .. }) |
Self::Eip2930(TxEip2930 { to, .. }) |
Self::Eip1559(TxEip1559 { to, .. }) => *to,
Self::Legacy(TxLegacy { to, .. })
| Self::Eip2930(TxEip2930 { to, .. })
| Self::Eip1559(TxEip1559 { to, .. }) => *to,
Self::Eip4844(TxEip4844 { to, .. }) => TxKind::Call(*to),
#[cfg(feature = "optimism")]
Self::Deposit(TxDeposit { to, .. }) => *to,
Expand Down Expand Up @@ -213,10 +214,10 @@ impl Transaction {
/// Gets the transaction's value field.
pub const fn value(&self) -> U256 {
*match self {
Self::Legacy(TxLegacy { value, .. }) |
Self::Eip2930(TxEip2930 { value, .. }) |
Self::Eip1559(TxEip1559 { value, .. }) |
Self::Eip4844(TxEip4844 { value, .. }) => value,
Self::Legacy(TxLegacy { value, .. })
| Self::Eip2930(TxEip2930 { value, .. })
| Self::Eip1559(TxEip1559 { value, .. })
| Self::Eip4844(TxEip4844 { value, .. }) => value,
#[cfg(feature = "optimism")]
Self::Deposit(TxDeposit { value, .. }) => value,
}
Expand All @@ -225,10 +226,10 @@ impl Transaction {
/// Get the transaction's nonce.
pub const fn nonce(&self) -> u64 {
match self {
Self::Legacy(TxLegacy { nonce, .. }) |
Self::Eip2930(TxEip2930 { nonce, .. }) |
Self::Eip1559(TxEip1559 { nonce, .. }) |
Self::Eip4844(TxEip4844 { nonce, .. }) => *nonce,
Self::Legacy(TxLegacy { nonce, .. })
| Self::Eip2930(TxEip2930 { nonce, .. })
| Self::Eip1559(TxEip1559 { nonce, .. })
| Self::Eip4844(TxEip4844 { nonce, .. }) => *nonce,
// Deposit transactions do not have nonces.
#[cfg(feature = "optimism")]
Self::Deposit(_) => 0,
Expand All @@ -252,10 +253,10 @@ impl Transaction {
/// Get the gas limit of the transaction.
pub const fn gas_limit(&self) -> u64 {
match self {
Self::Legacy(TxLegacy { gas_limit, .. }) |
Self::Eip2930(TxEip2930 { gas_limit, .. }) |
Self::Eip1559(TxEip1559 { gas_limit, .. }) |
Self::Eip4844(TxEip4844 { gas_limit, .. }) => *gas_limit,
Self::Legacy(TxLegacy { gas_limit, .. })
| Self::Eip2930(TxEip2930 { gas_limit, .. })
| Self::Eip1559(TxEip1559 { gas_limit, .. })
| Self::Eip4844(TxEip4844 { gas_limit, .. }) => *gas_limit,
#[cfg(feature = "optimism")]
Self::Deposit(TxDeposit { gas_limit, .. }) => *gas_limit,
}
Expand All @@ -276,10 +277,10 @@ impl Transaction {
/// This is also commonly referred to as the "Gas Fee Cap" (`GasFeeCap`).
pub const fn max_fee_per_gas(&self) -> u128 {
match self {
Self::Legacy(TxLegacy { gas_price, .. }) |
Self::Eip2930(TxEip2930 { gas_price, .. }) => *gas_price,
Self::Eip1559(TxEip1559 { max_fee_per_gas, .. }) |
Self::Eip4844(TxEip4844 { max_fee_per_gas, .. }) => *max_fee_per_gas,
Self::Legacy(TxLegacy { gas_price, .. })
| Self::Eip2930(TxEip2930 { gas_price, .. }) => *gas_price,
Self::Eip1559(TxEip1559 { max_fee_per_gas, .. })
| Self::Eip4844(TxEip4844 { max_fee_per_gas, .. }) => *max_fee_per_gas,
// Deposit transactions buy their L2 gas on L1 and, as such, the L2 gas is not
// refundable.
#[cfg(feature = "optimism")]
Expand All @@ -294,8 +295,8 @@ impl Transaction {
pub const fn max_priority_fee_per_gas(&self) -> Option<u128> {
match self {
Self::Legacy(_) | Self::Eip2930(_) => None,
Self::Eip1559(TxEip1559 { max_priority_fee_per_gas, .. }) |
Self::Eip4844(TxEip4844 { max_priority_fee_per_gas, .. }) => {
Self::Eip1559(TxEip1559 { max_priority_fee_per_gas, .. })
| Self::Eip4844(TxEip4844 { max_priority_fee_per_gas, .. }) => {
Some(*max_priority_fee_per_gas)
}
#[cfg(feature = "optimism")]
Expand Down Expand Up @@ -348,10 +349,12 @@ impl Transaction {
/// non-EIP-1559 transactions.
pub const fn priority_fee_or_price(&self) -> u128 {
match self {
Self::Legacy(TxLegacy { gas_price, .. }) |
Self::Eip2930(TxEip2930 { gas_price, .. }) => *gas_price,
Self::Eip1559(TxEip1559 { max_priority_fee_per_gas, .. }) |
Self::Eip4844(TxEip4844 { max_priority_fee_per_gas, .. }) => *max_priority_fee_per_gas,
Self::Legacy(TxLegacy { gas_price, .. })
| Self::Eip2930(TxEip2930 { gas_price, .. }) => *gas_price,
Self::Eip1559(TxEip1559 { max_priority_fee_per_gas, .. })
| Self::Eip4844(TxEip4844 { max_priority_fee_per_gas, .. }) => {
*max_priority_fee_per_gas
}
#[cfg(feature = "optimism")]
Self::Deposit(_) => 0,
}
Expand Down Expand Up @@ -388,7 +391,7 @@ impl Transaction {

// Check if max_fee_per_gas is less than base_fee
if max_fee_per_gas < base_fee {
return None
return None;
}

// Calculate the difference between max_fee_per_gas and base_fee
Expand All @@ -405,10 +408,10 @@ impl Transaction {
/// Get the transaction's input field.
pub const fn input(&self) -> &Bytes {
match self {
Self::Legacy(TxLegacy { input, .. }) |
Self::Eip2930(TxEip2930 { input, .. }) |
Self::Eip1559(TxEip1559 { input, .. }) |
Self::Eip4844(TxEip4844 { input, .. }) => input,
Self::Legacy(TxLegacy { input, .. })
| Self::Eip2930(TxEip2930 { input, .. })
| Self::Eip1559(TxEip1559 { input, .. })
| Self::Eip4844(TxEip4844 { input, .. }) => input,
#[cfg(feature = "optimism")]
Self::Deposit(TxDeposit { input, .. }) => input,
}
Expand Down Expand Up @@ -773,7 +776,7 @@ impl TransactionSignedNoHash {
// `from` address.
#[cfg(feature = "optimism")]
if let Transaction::Deposit(TxDeposit { from, .. }) = self.transaction {
return Some(from)
return Some(from);
}

let signature_hash = self.signature_hash();
Expand Down Expand Up @@ -802,15 +805,15 @@ impl TransactionSignedNoHash {
#[cfg(feature = "optimism")]
{
if let Transaction::Deposit(TxDeposit { from, .. }) = self.transaction {
return Some(from)
return Some(from);
}

// pre bedrock system transactions were sent from the zero address as legacy
// transactions with an empty signature
//
// NOTE: this is very hacky and only relevant for op-mainnet pre bedrock
if self.is_legacy() && self.signature == Signature::optimism_deposit_tx_signature() {
return Some(Address::ZERO)
return Some(Address::ZERO);
}
}

Expand Down Expand Up @@ -1027,7 +1030,7 @@ impl TransactionSigned {
// `from` address.
#[cfg(feature = "optimism")]
if let Transaction::Deposit(TxDeposit { from, .. }) = self.transaction {
return Some(from)
return Some(from);
}
let signature_hash = self.signature_hash();
self.signature.recover_signer(signature_hash)
Expand All @@ -1043,7 +1046,7 @@ impl TransactionSigned {
// `from` address.
#[cfg(feature = "optimism")]
if let Transaction::Deposit(TxDeposit { from, .. }) = self.transaction {
return Some(from)
return Some(from);
}
let signature_hash = self.signature_hash();
self.signature.recover_signer_unchecked(signature_hash)
Expand Down Expand Up @@ -1217,7 +1220,7 @@ impl TransactionSigned {
let transaction_payload_len = header.payload_length;

if transaction_payload_len > remaining_len {
return Err(RlpError::InputTooShort)
return Err(RlpError::InputTooShort);
}

let mut transaction = TxLegacy {
Expand All @@ -1235,7 +1238,7 @@ impl TransactionSigned {
// check the new length, compared to the original length and the header length
let decoded = remaining_len - data.len();
if decoded != transaction_payload_len {
return Err(RlpError::UnexpectedLength)
return Err(RlpError::UnexpectedLength);
}

let tx_length = header.payload_length + header.length();
Expand Down Expand Up @@ -1280,7 +1283,7 @@ impl TransactionSigned {
// decode the list header for the rest of the transaction
let header = Header::decode(data)?;
if !header.list {
return Err(RlpError::Custom("typed tx fields must be encoded as a list"))
return Err(RlpError::Custom("typed tx fields must be encoded as a list"));
}

let remaining_len = data.len();
Expand All @@ -1290,7 +1293,7 @@ impl TransactionSigned {

// decode common fields
let Ok(tx_type) = TxType::try_from(tx_type) else {
return Err(RlpError::Custom("unsupported typed transaction type"))
return Err(RlpError::Custom("unsupported typed transaction type"));
};

let transaction = match tx_type {
Expand All @@ -1314,7 +1317,7 @@ impl TransactionSigned {

let bytes_consumed = remaining_len - data.len();
if bytes_consumed != header.payload_length {
return Err(RlpError::UnexpectedLength)
return Err(RlpError::UnexpectedLength);
}

let hash = keccak256(&original_encoding_without_header[..tx_length]);
Expand All @@ -1341,7 +1344,7 @@ impl TransactionSigned {
/// of bytes in input data.
pub fn decode_enveloped(input_data: &mut &[u8]) -> alloy_rlp::Result<Self> {
if input_data.is_empty() {
return Err(RlpError::InputTooShort)
return Err(RlpError::InputTooShort);
}

// Check if the tx is a list
Expand All @@ -1353,7 +1356,7 @@ impl TransactionSigned {
};

if !input_data.is_empty() {
return Err(RlpError::UnexpectedLength)
return Err(RlpError::UnexpectedLength);
}

Ok(output_data)
Expand Down Expand Up @@ -1403,6 +1406,28 @@ impl Encodable for TransactionSigned {
}
}

/// List of signed transactions reference.
#[derive(Debug)]
pub struct TransactionSignedList<'a>(pub &'a [TransactionSigned]);

impl Encodable for TransactionSignedList<'_> {
/// This encodes the transaction _with_ the signature, and an rlp header.
///
/// For legacy transactions, it encodes the transaction data:
/// `rlp(tx-data)`
///
/// For EIP-2718 typed transactions, it encodes the transaction type followed by the rlp of the
/// transaction:
/// `rlp(tx-type || rlp(tx-data))`
fn encode(&self, out: &mut dyn bytes::BufMut) {
encode_list(self.0, out)
}

fn length(&self) -> usize {
list_length(self.0)
}
}

impl Decodable for TransactionSigned {
/// This `Decodable` implementation only supports decoding rlp encoded transactions as it's used
/// by p2p.
Expand Down Expand Up @@ -1431,7 +1456,7 @@ impl Decodable for TransactionSigned {
/// string header if the first byte is less than `0xf7`.
fn decode(buf: &mut &[u8]) -> alloy_rlp::Result<Self> {
if buf.is_empty() {
return Err(RlpError::InputTooShort)
return Err(RlpError::InputTooShort);
}

// decode header
Expand All @@ -1449,7 +1474,7 @@ impl Decodable for TransactionSigned {
// string Header with payload_length of 1, we need to make sure this check is only
// performed for transactions with a string header
if bytes_consumed != header.payload_length && original_encoding[0] > EMPTY_STRING_CODE {
return Err(RlpError::UnexpectedLength)
return Err(RlpError::UnexpectedLength);
}

Ok(tx)
Expand Down
Loading

0 comments on commit 966cbf9

Please sign in to comment.