mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-01-29 09:08:05 -05:00
feat(db): Make TransactionSigned compactable (#252)
This commit is contained in:
@@ -7,7 +7,7 @@ repository = "https://github.com/foundry-rs/reth"
|
||||
readme = "README.md"
|
||||
|
||||
[features]
|
||||
default = ["scale"]
|
||||
default = ["compact"]
|
||||
compact = ["codecs-derive/compact"]
|
||||
scale = ["codecs-derive/scale"]
|
||||
postcard = ["codecs-derive/postcard"]
|
||||
|
||||
@@ -19,7 +19,7 @@ serde = { version = "1.0.*", default-features = false }
|
||||
parity-scale-codec = { version = "3.2.1", features = ["derive", "bytes"] }
|
||||
|
||||
[features]
|
||||
default = ["scale"]
|
||||
default = ["compact"]
|
||||
compact = []
|
||||
scale = []
|
||||
postcard = []
|
||||
|
||||
@@ -71,6 +71,9 @@ fn build_struct_field_flags(
|
||||
|
||||
// Find out the adequate bit size for the length of each field, if applicable.
|
||||
for (name, ftype, is_compact) in fields {
|
||||
// This happens when dealing with a wrapper struct eg. Struct(pub U256).
|
||||
let name = if name.is_empty() { "placeholder" } else { name };
|
||||
|
||||
if *is_compact {
|
||||
if is_flag_type(ftype) {
|
||||
let name = format_ident!("{name}_len");
|
||||
|
||||
@@ -50,7 +50,13 @@ pub fn generate_from_to(ident: &Ident, fields: &FieldList) -> TokenStream2 {
|
||||
/// Generates code to implement the [`Compact`] trait method `to_compact`.
|
||||
fn generate_from_compact(fields: &FieldList, ident: &Ident) -> Vec<TokenStream2> {
|
||||
let mut lines = vec![];
|
||||
let known_types = ["H256", "H160", "Address", "Bloom", "Vec"];
|
||||
let mut known_types = vec!["H256", "H160", "Address", "Bloom", "Vec"];
|
||||
|
||||
// Only types without `bytes::Bytes` should be added here. It's currently manually added, since
|
||||
// it's hard to figure out with derive_macro which types have bytes::Bytes fields.
|
||||
//
|
||||
// This removes the requirement of the field to be placed last in the struct.
|
||||
known_types.append(&mut vec!["TransactionKind", "AccessList", "Signature"]);
|
||||
|
||||
// let mut handle = FieldListHandler::new(fields);
|
||||
let is_enum = fields.iter().any(|field| matches!(field, FieldTypes::EnumVariant(_)));
|
||||
@@ -66,24 +72,31 @@ fn generate_from_compact(fields: &FieldList, ident: &Ident) -> Vec<TokenStream2>
|
||||
};
|
||||
});
|
||||
} else {
|
||||
lines.append(&mut StructHandler::new(fields).generate_from(known_types.as_slice()));
|
||||
|
||||
let fields = fields.iter().filter_map(|field| {
|
||||
if let FieldTypes::StructField((name, _, _)) = field {
|
||||
let ident = format_ident!("{name}");
|
||||
return Some(quote! {
|
||||
#ident: #ident,
|
||||
})
|
||||
}
|
||||
None
|
||||
});
|
||||
let mut struct_handler = StructHandler::new(fields);
|
||||
lines.append(&mut struct_handler.generate_from(known_types.as_slice()));
|
||||
|
||||
// Builds the object instantiation.
|
||||
lines.push(quote! {
|
||||
let obj = #ident {
|
||||
#(#fields)*
|
||||
};
|
||||
});
|
||||
if struct_handler.is_wrapper {
|
||||
lines.push(quote! {
|
||||
let obj = #ident(placeholder);
|
||||
});
|
||||
} else {
|
||||
let fields = fields.iter().filter_map(|field| {
|
||||
if let FieldTypes::StructField((name, _, _)) = field {
|
||||
let ident = format_ident!("{name}");
|
||||
return Some(quote! {
|
||||
#ident: #ident,
|
||||
})
|
||||
}
|
||||
None
|
||||
});
|
||||
|
||||
lines.push(quote! {
|
||||
let obj = #ident {
|
||||
#(#fields)*
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
lines
|
||||
|
||||
@@ -124,16 +124,14 @@ fn load_field(field: &syn::Field, fields: &mut FieldList, is_enum: bool) {
|
||||
/// Given the field type in a string format, return the amount of bits necessary to save its maximum
|
||||
/// length.
|
||||
pub fn get_bit_size(ftype: &str) -> u8 {
|
||||
if ftype == "u64" || ftype == "BlockNumber" || ftype == "TxNumber" || ftype == "ChainId" {
|
||||
return 4
|
||||
} else if ftype == "TxType" {
|
||||
return 2
|
||||
} else if ftype == "bool" || ftype == "Option" {
|
||||
return 1
|
||||
} else if ftype == "U256" {
|
||||
return 6
|
||||
match ftype {
|
||||
"bool" | "Option" => 1,
|
||||
"TxType" => 2,
|
||||
"u64" | "BlockNumber" | "TxNumber" | "ChainId" => 4,
|
||||
"u128" => 5,
|
||||
"U256" | "TxHash" => 6,
|
||||
_ => 0,
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
/// Given the field type in a string format, checks if its type should be added to the
|
||||
|
||||
@@ -4,11 +4,16 @@ use super::*;
|
||||
pub struct StructHandler<'a> {
|
||||
fields_iterator: std::iter::Peekable<std::slice::Iter<'a, FieldTypes>>,
|
||||
lines: Vec<TokenStream2>,
|
||||
pub is_wrapper: bool,
|
||||
}
|
||||
|
||||
impl<'a> StructHandler<'a> {
|
||||
pub fn new(fields: &'a FieldList) -> Self {
|
||||
StructHandler { lines: vec![], fields_iterator: fields.iter().peekable() }
|
||||
StructHandler {
|
||||
lines: vec![],
|
||||
fields_iterator: fields.iter().peekable(),
|
||||
is_wrapper: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn next_field(&mut self) -> Option<&'a FieldTypes> {
|
||||
@@ -18,8 +23,6 @@ impl<'a> StructHandler<'a> {
|
||||
pub fn generate_to(mut self) -> Vec<TokenStream2> {
|
||||
while let Some(field) = self.next_field() {
|
||||
match field {
|
||||
// The following method will advance the
|
||||
// `fields_iterator` by itself and stop right before the next variant.
|
||||
FieldTypes::EnumVariant(_) => unreachable!(),
|
||||
FieldTypes::EnumUnnamedField(_) => unreachable!(),
|
||||
FieldTypes::StructField(field_descriptor) => self.to(field_descriptor),
|
||||
@@ -28,11 +31,9 @@ impl<'a> StructHandler<'a> {
|
||||
self.lines
|
||||
}
|
||||
|
||||
pub fn generate_from(mut self, known_types: &[&str]) -> Vec<TokenStream2> {
|
||||
pub fn generate_from(&mut self, known_types: &[&str]) -> Vec<TokenStream2> {
|
||||
while let Some(field) = self.next_field() {
|
||||
match field {
|
||||
// The following method will advance the
|
||||
// `fields_iterator` by itself and stop right before the next variant.
|
||||
FieldTypes::EnumVariant(_) => unreachable!(),
|
||||
FieldTypes::EnumUnnamedField(_) => unreachable!(),
|
||||
FieldTypes::StructField(field_descriptor) => {
|
||||
@@ -40,13 +41,30 @@ impl<'a> StructHandler<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
self.lines
|
||||
self.lines.clone()
|
||||
}
|
||||
|
||||
/// Generates `to_compact` code for a struct field.
|
||||
fn to(&mut self, field_descriptor: &StructFieldDescriptor) {
|
||||
let (name, ftype, is_compact) = field_descriptor;
|
||||
|
||||
// Should only happen on wrapper structs like `Struct(pub Field)`
|
||||
if name.is_empty() {
|
||||
self.is_wrapper = true;
|
||||
|
||||
self.lines.push(quote! {
|
||||
let _len = self.0.to_compact(&mut buffer);
|
||||
});
|
||||
|
||||
if is_flag_type(ftype) {
|
||||
self.lines.push(quote! {
|
||||
flags.set_placeholder_len(_len as u8);
|
||||
})
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
let name = format_ident!("{name}");
|
||||
let set_len_method = format_ident!("set_{name}_len");
|
||||
let len = format_ident!("{name}_len");
|
||||
@@ -77,8 +95,14 @@ impl<'a> StructHandler<'a> {
|
||||
fn from(&mut self, field_descriptor: &StructFieldDescriptor, known_types: &[&str]) {
|
||||
let (name, ftype, is_compact) = field_descriptor;
|
||||
|
||||
let name = format_ident!("{name}");
|
||||
let len = format_ident!("{name}_len");
|
||||
let (name, len) = if name.is_empty() {
|
||||
self.is_wrapper = true;
|
||||
|
||||
// Should only happen on wrapper structs like `Struct(pub Field)`
|
||||
(format_ident!("placeholder"), format_ident!("placeholder_len"))
|
||||
} else {
|
||||
(format_ident!("{name}"), format_ident!("{name}_len"))
|
||||
};
|
||||
|
||||
assert!(
|
||||
known_types.contains(&ftype.as_str()) ||
|
||||
|
||||
@@ -12,7 +12,10 @@ pub fn derive(input: TokenStream) -> TokenStream {
|
||||
#[proc_macro_attribute]
|
||||
#[rustfmt::skip]
|
||||
#[allow(unreachable_code)]
|
||||
pub fn main_codec(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
pub fn main_codec(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
#[cfg(feature = "compact")]
|
||||
return use_compact(args, input);
|
||||
|
||||
#[cfg(feature = "scale")]
|
||||
return use_scale(args, input);
|
||||
|
||||
@@ -21,9 +24,6 @@ pub fn main_codec(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
|
||||
#[cfg(feature = "no_codec")]
|
||||
return no_codec(args, input);
|
||||
|
||||
#[cfg(feature = "compact")]
|
||||
return use_compact(args, input);
|
||||
|
||||
// no features
|
||||
no_codec(args, input)
|
||||
|
||||
@@ -28,26 +28,34 @@ pub trait Compact {
|
||||
Self: Sized;
|
||||
}
|
||||
|
||||
impl Compact for u64 {
|
||||
fn to_compact(self, buf: &mut impl bytes::BufMut) -> usize {
|
||||
let leading = self.leading_zeros() as usize / 8;
|
||||
buf.put_slice(&self.to_be_bytes()[leading..]);
|
||||
8 - leading
|
||||
}
|
||||
macro_rules! impl_uint_compact {
|
||||
($($name:tt),+) => {
|
||||
$(
|
||||
impl Compact for $name {
|
||||
fn to_compact(self, buf: &mut impl bytes::BufMut) -> usize {
|
||||
let leading = self.leading_zeros() as usize / 8;
|
||||
buf.put_slice(&self.to_be_bytes()[leading..]);
|
||||
std::mem::size_of::<$name>() - leading
|
||||
}
|
||||
|
||||
fn from_compact(mut buf: &[u8], len: usize) -> (Self, &[u8]) {
|
||||
if len > 0 {
|
||||
let mut arr = [0; 8];
|
||||
arr[8 - len..].copy_from_slice(&buf[..len]);
|
||||
fn from_compact(mut buf: &[u8], len: usize) -> (Self, &[u8]) {
|
||||
if len > 0 {
|
||||
let mut arr = [0; std::mem::size_of::<$name>()];
|
||||
arr[std::mem::size_of::<$name>() - len..].copy_from_slice(&buf[..len]);
|
||||
|
||||
buf.advance(len);
|
||||
buf.advance(len);
|
||||
|
||||
return (u64::from_be_bytes(arr), buf)
|
||||
}
|
||||
(0, buf)
|
||||
}
|
||||
return ($name::from_be_bytes(arr), buf)
|
||||
}
|
||||
(0, buf)
|
||||
}
|
||||
}
|
||||
)+
|
||||
};
|
||||
}
|
||||
|
||||
impl_uint_compact!(u64, u128);
|
||||
|
||||
impl<T> Compact for Vec<T>
|
||||
where
|
||||
T: Compact + Default,
|
||||
@@ -144,12 +152,12 @@ impl Compact for Bytes {
|
||||
}
|
||||
|
||||
macro_rules! impl_hash_compact {
|
||||
($(($name:tt, $size:tt)),+) => {
|
||||
($($name:tt),+) => {
|
||||
$(
|
||||
impl Compact for $name {
|
||||
fn to_compact(self, buf: &mut impl bytes::BufMut) -> usize {
|
||||
buf.put_slice(&self.0);
|
||||
$size
|
||||
std::mem::size_of::<$name>()
|
||||
}
|
||||
|
||||
fn from_compact(mut buf: &[u8], len: usize) -> (Self,&[u8]) {
|
||||
@@ -158,9 +166,9 @@ macro_rules! impl_hash_compact {
|
||||
}
|
||||
|
||||
let v = $name::from_slice(
|
||||
buf.get(..$size).expect("size not matching"),
|
||||
buf.get(..std::mem::size_of::<$name>()).expect("size not matching"),
|
||||
);
|
||||
buf.advance($size);
|
||||
buf.advance(std::mem::size_of::<$name>());
|
||||
(v, buf)
|
||||
}
|
||||
}
|
||||
@@ -168,7 +176,7 @@ macro_rules! impl_hash_compact {
|
||||
};
|
||||
}
|
||||
|
||||
impl_hash_compact!((H256, 32), (H160, 20));
|
||||
impl_hash_compact!(H256, H160);
|
||||
|
||||
impl Compact for Bloom {
|
||||
fn to_compact(self, buf: &mut impl bytes::BufMut) -> usize {
|
||||
@@ -337,7 +345,7 @@ mod tests {
|
||||
assert_eq!(u64::from_compact(&buf, 8), (0xffffffffffffffffu64, vec![].as_slice()));
|
||||
}
|
||||
|
||||
#[use_compact]
|
||||
#[main_codec]
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct TestStruct {
|
||||
f_u64: u64,
|
||||
@@ -389,7 +397,7 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[use_compact]
|
||||
#[main_codec]
|
||||
#[derive(Debug, PartialEq, Clone, Default)]
|
||||
pub enum TestEnum {
|
||||
#[default]
|
||||
|
||||
@@ -6,7 +6,8 @@ use reth_interfaces::{
|
||||
Result as RethResult,
|
||||
};
|
||||
use reth_primitives::{
|
||||
Account, BlockLocked, BlockNumber, SealedHeader, Transaction, EMPTY_OMMER_ROOT, H256, U256,
|
||||
Account, BlockLocked, BlockNumber, SealedHeader, Transaction, TxEip1559, TxEip2930, TxLegacy,
|
||||
EMPTY_OMMER_ROOT, H256, U256,
|
||||
};
|
||||
use std::time::SystemTime;
|
||||
|
||||
@@ -74,21 +75,26 @@ pub fn validate_transaction_regarding_header(
|
||||
base_fee: Option<u64>,
|
||||
) -> Result<(), Error> {
|
||||
let chain_id = match transaction {
|
||||
Transaction::Legacy { chain_id, .. } => {
|
||||
Transaction::Legacy(TxLegacy { chain_id, .. }) => {
|
||||
// EIP-155: Simple replay attack protection: https://eips.ethereum.org/EIPS/eip-155
|
||||
if config.spurious_dragon_hard_fork_block <= at_block_number && chain_id.is_some() {
|
||||
return Err(Error::TransactionOldLegacyChainId)
|
||||
}
|
||||
*chain_id
|
||||
}
|
||||
Transaction::Eip2930 { chain_id, .. } => {
|
||||
Transaction::Eip2930(TxEip2930 { chain_id, .. }) => {
|
||||
// EIP-2930: Optional access lists: https://eips.ethereum.org/EIPS/eip-2930 (New transaction type)
|
||||
if config.berlin_hard_fork_block > at_block_number {
|
||||
return Err(Error::TransactionEip2930Disabled)
|
||||
}
|
||||
Some(*chain_id)
|
||||
}
|
||||
Transaction::Eip1559 { chain_id, max_fee_per_gas, max_priority_fee_per_gas, .. } => {
|
||||
Transaction::Eip1559(TxEip1559 {
|
||||
chain_id,
|
||||
max_fee_per_gas,
|
||||
max_priority_fee_per_gas,
|
||||
..
|
||||
}) => {
|
||||
// EIP-1559: Fee market change for ETH 1.0 chain https://eips.ethereum.org/EIPS/eip-1559
|
||||
if config.berlin_hard_fork_block > at_block_number {
|
||||
return Err(Error::TransactionEip1559Disabled)
|
||||
@@ -130,13 +136,13 @@ pub fn validate_transaction_regarding_account(
|
||||
}
|
||||
|
||||
let (nonce, gas_price, gas_limit, value) = match transaction {
|
||||
Transaction::Legacy { nonce, gas_price, gas_limit, value, .. } => {
|
||||
Transaction::Legacy(TxLegacy { nonce, gas_price, gas_limit, value, .. }) => {
|
||||
(nonce, gas_price, gas_limit, value)
|
||||
}
|
||||
Transaction::Eip2930 { nonce, gas_price, gas_limit, value, .. } => {
|
||||
Transaction::Eip2930(TxEip2930 { nonce, gas_price, gas_limit, value, .. }) => {
|
||||
(nonce, gas_price, gas_limit, value)
|
||||
}
|
||||
Transaction::Eip1559 { nonce, gas_limit, max_fee_per_gas, value, .. } => {
|
||||
Transaction::Eip1559(TxEip1559 { nonce, gas_limit, max_fee_per_gas, value, .. }) => {
|
||||
(nonce, max_fee_per_gas, gas_limit, value)
|
||||
}
|
||||
};
|
||||
|
||||
@@ -360,7 +360,7 @@ mod tests {
|
||||
|
||||
impl AccountProvider for StateProviderTest {
|
||||
fn basic_account(&self, address: Address) -> reth_interfaces::Result<Option<Account>> {
|
||||
let ret = Ok(self.accounts.get(&address).map(|(_, acc)| acc.clone()));
|
||||
let ret = Ok(self.accounts.get(&address).map(|(_, acc)| *acc));
|
||||
ret
|
||||
}
|
||||
}
|
||||
@@ -374,8 +374,7 @@ mod tests {
|
||||
Ok(self
|
||||
.accounts
|
||||
.get(&account)
|
||||
.map(|(storage, _)| storage.get(&storage_key).cloned())
|
||||
.flatten())
|
||||
.and_then(|(storage, _)| storage.get(&storage_key).cloned()))
|
||||
}
|
||||
|
||||
fn bytecode_by_hash(&self, code_hash: H256) -> reth_interfaces::Result<Option<Bytes>> {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use reth_interfaces::{provider::StateProvider, Error};
|
||||
use reth_primitives::{
|
||||
Header, Transaction, TransactionKind, TransactionSignedEcRecovered, H160, H256, KECCAK_EMPTY,
|
||||
U256,
|
||||
Header, Transaction, TransactionKind, TransactionSignedEcRecovered, TxEip1559, TxEip2930,
|
||||
TxLegacy, H160, H256, KECCAK_EMPTY, U256,
|
||||
};
|
||||
use revm::{
|
||||
db::{CacheDB, DatabaseRef},
|
||||
@@ -79,7 +79,15 @@ pub fn fill_block_env(block_env: &mut BlockEnv, header: &Header) {
|
||||
pub fn fill_tx_env(tx_env: &mut TxEnv, transaction: &TransactionSignedEcRecovered) {
|
||||
tx_env.caller = transaction.signer();
|
||||
match transaction.as_ref().as_ref() {
|
||||
Transaction::Legacy { nonce, chain_id, gas_price, gas_limit, to, value, input } => {
|
||||
Transaction::Legacy(TxLegacy {
|
||||
nonce,
|
||||
chain_id,
|
||||
gas_price,
|
||||
gas_limit,
|
||||
to,
|
||||
value,
|
||||
input,
|
||||
}) => {
|
||||
tx_env.gas_limit = *gas_limit;
|
||||
tx_env.gas_price = (*gas_price).into();
|
||||
tx_env.gas_priority_fee = None;
|
||||
@@ -92,7 +100,7 @@ pub fn fill_tx_env(tx_env: &mut TxEnv, transaction: &TransactionSignedEcRecovere
|
||||
tx_env.chain_id = *chain_id;
|
||||
tx_env.nonce = Some(*nonce);
|
||||
}
|
||||
Transaction::Eip2930 {
|
||||
Transaction::Eip2930(TxEip2930 {
|
||||
nonce,
|
||||
chain_id,
|
||||
gas_price,
|
||||
@@ -101,7 +109,7 @@ pub fn fill_tx_env(tx_env: &mut TxEnv, transaction: &TransactionSignedEcRecovere
|
||||
value,
|
||||
input,
|
||||
access_list,
|
||||
} => {
|
||||
}) => {
|
||||
tx_env.gas_limit = *gas_limit;
|
||||
tx_env.gas_price = (*gas_price).into();
|
||||
tx_env.gas_priority_fee = None;
|
||||
@@ -124,7 +132,7 @@ pub fn fill_tx_env(tx_env: &mut TxEnv, transaction: &TransactionSignedEcRecovere
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
Transaction::Eip1559 {
|
||||
Transaction::Eip1559(TxEip1559 {
|
||||
nonce,
|
||||
chain_id,
|
||||
gas_limit,
|
||||
@@ -134,7 +142,7 @@ pub fn fill_tx_env(tx_env: &mut TxEnv, transaction: &TransactionSignedEcRecovere
|
||||
value,
|
||||
input,
|
||||
access_list,
|
||||
} => {
|
||||
}) => {
|
||||
tx_env.gas_limit = *gas_limit;
|
||||
tx_env.gas_price = (*max_fee_per_gas).into();
|
||||
tx_env.gas_priority_fee = Some((*max_priority_fee_per_gas).into());
|
||||
|
||||
@@ -2,7 +2,9 @@ use crate::db::{
|
||||
models::{accounts::AccountBeforeTx, StoredBlockBody},
|
||||
Compress, Decompress, Error,
|
||||
};
|
||||
use reth_codecs::Compact;
|
||||
use bytes::Buf;
|
||||
use modular_bitfield::prelude::*;
|
||||
use reth_codecs::{main_codec, Compact};
|
||||
use reth_primitives::*;
|
||||
|
||||
/// Implements compression for Compact type.
|
||||
@@ -33,4 +35,42 @@ macro_rules! impl_compression_for_compact {
|
||||
}
|
||||
|
||||
impl_compression_for_compact!(Header, Account, Log, Receipt, TxType, StorageEntry, StoredBlockBody);
|
||||
impl_compression_for_compact!(AccountBeforeTx);
|
||||
impl_compression_for_compact!(AccountBeforeTx, TransactionSigned);
|
||||
impl_compression_for_compact!(CompactU256);
|
||||
|
||||
/// Adds wrapper structs for some primitive types so they can use StructFlags from Compact, when
|
||||
/// used as pure table values.
|
||||
macro_rules! add_wrapper_struct {
|
||||
($(($name:tt, $wrapper:tt)),+) => {
|
||||
$(
|
||||
/// Wrapper struct so it can use StructFlags from Compact, when used as pure table values.
|
||||
#[main_codec]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Default)]
|
||||
pub struct $wrapper(pub $name);
|
||||
|
||||
impl From<$name> for $wrapper {
|
||||
fn from(value: $name) -> Self {
|
||||
$wrapper(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<$wrapper> for $name {
|
||||
fn from(value: $wrapper) -> Self {
|
||||
value.0
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for $wrapper {
|
||||
type Target = $name;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
)+
|
||||
};
|
||||
}
|
||||
|
||||
add_wrapper_struct!((U256, CompactU256));
|
||||
add_wrapper_struct!((u64, CompactU64));
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
//! Integrates different codecs into table::Encode and table::Decode
|
||||
|
||||
mod compact;
|
||||
pub use compact::CompactU256;
|
||||
|
||||
pub mod fuzz;
|
||||
mod postcard;
|
||||
#[cfg(not(feature = "bench-postcard"))]
|
||||
|
||||
@@ -43,5 +43,4 @@ impl ScaleValue for Vec<u8> {}
|
||||
impl sealed::Sealed for Vec<u8> {}
|
||||
|
||||
impl_compression_for_scale!(U256, H256, H160);
|
||||
impl_compression_for_scale!(TransactionSigned);
|
||||
impl_compression_for_scale!(u8, u32, u16, u64);
|
||||
|
||||
@@ -8,12 +8,12 @@ use crate::{
|
||||
impl_fixed_arbitrary,
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use reth_codecs::{use_compact, Compact};
|
||||
use reth_codecs::{main_codec, Compact};
|
||||
use reth_primitives::{Account, Address, TxNumber};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Account as it is saved inside [`AccountChangeSet`]. [`Address`] is the subkey.
|
||||
#[use_compact]
|
||||
#[main_codec]
|
||||
#[derive(Debug, Default, Clone, PartialEq)]
|
||||
pub struct AccountBeforeTx {
|
||||
/// Address for the account. Acts as `DupSort::SubKey`.
|
||||
|
||||
@@ -9,7 +9,7 @@ use crate::{
|
||||
};
|
||||
use bytes::{Buf, Bytes};
|
||||
use modular_bitfield::prelude::*;
|
||||
use reth_codecs::{use_compact, Compact};
|
||||
use reth_codecs::{main_codec, Compact};
|
||||
use reth_primitives::{BlockHash, BlockNumber, Header, TxNumber, H256};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@@ -24,7 +24,7 @@ pub type NumTransactions = u64;
|
||||
/// The [TxNumber]s for all the transactions in the block are `base_tx_id..(base_tx_id +
|
||||
/// tx_amount)`.
|
||||
#[derive(Debug, Default, PartialEq, Clone)]
|
||||
#[use_compact]
|
||||
#[main_codec]
|
||||
pub struct StoredBlockBody {
|
||||
/// The ID of the first transaction in the block.
|
||||
pub base_tx_id: TxNumber,
|
||||
|
||||
@@ -17,11 +17,11 @@ use crate::db::{
|
||||
|
||||
/// Macro that implements [`Encode`] and [`Decode`] for uint types.
|
||||
macro_rules! impl_uints {
|
||||
($(($name:tt, $size:tt)),+) => {
|
||||
($($name:tt),+) => {
|
||||
$(
|
||||
impl Encode for $name
|
||||
{
|
||||
type Encoded = [u8; $size];
|
||||
type Encoded = [u8; std::mem::size_of::<$name>()];
|
||||
|
||||
fn encode(self) -> Self::Encoded {
|
||||
self.to_be_bytes()
|
||||
@@ -43,7 +43,7 @@ macro_rules! impl_uints {
|
||||
};
|
||||
}
|
||||
|
||||
impl_uints!((u64, 8), (u32, 4), (u16, 2), (u8, 1));
|
||||
impl_uints!(u64, u32, u16, u8);
|
||||
|
||||
impl Encode for Vec<u8> {
|
||||
type Encoded = Vec<u8>;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//! Declaration of all Database tables.
|
||||
|
||||
use crate::db::{
|
||||
codecs::CompactU256,
|
||||
models::{
|
||||
accounts::{AccountBeforeTx, TxNumberAddress},
|
||||
blocks::{BlockNumHash, HeaderHash, NumTransactions, StoredBlockBody},
|
||||
@@ -108,7 +109,7 @@ table!(
|
||||
|
||||
table!(
|
||||
/// Stores the total difficulty from a block header.
|
||||
HeaderTD => BlockNumHash => RlpTotalDifficulty);
|
||||
HeaderTD => BlockNumHash => CompactU256);
|
||||
|
||||
table!(
|
||||
/// Stores the block number corresponding to an header.
|
||||
@@ -244,8 +245,6 @@ pub type ConfigValue = Vec<u8>;
|
||||
/// Temporary placeholder type for DB.
|
||||
pub type BlockNumHashTxNumber = Vec<u8>;
|
||||
/// Temporary placeholder type for DB.
|
||||
pub type RlpTotalDifficulty = Vec<u8>;
|
||||
/// Temporary placeholder type for DB.
|
||||
pub type AddressStorageKey = Vec<u8>;
|
||||
/// Temporary placeholder type for DB.
|
||||
pub type Bytecode = Vec<u8>;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use rand::{thread_rng, Rng};
|
||||
use reth_primitives::{
|
||||
proofs, Address, BlockLocked, Bytes, Header, SealedHeader, Signature, Transaction,
|
||||
TransactionKind, TransactionSigned, H256, U256,
|
||||
TransactionKind, TransactionSigned, TxLegacy, H256, U256,
|
||||
};
|
||||
use secp256k1::{KeyPair, Message as SecpMessage, Secp256k1, SecretKey};
|
||||
|
||||
@@ -46,7 +46,7 @@ pub fn random_header(number: u64, parent: Option<H256>) -> SealedHeader {
|
||||
/// - The chain ID, which is always 1
|
||||
/// - The input, which is always nothing
|
||||
pub fn random_tx() -> Transaction {
|
||||
Transaction::Legacy {
|
||||
Transaction::Legacy(TxLegacy {
|
||||
chain_id: Some(1),
|
||||
nonce: rand::random::<u16>().into(),
|
||||
gas_price: rand::random::<u16>().into(),
|
||||
@@ -54,7 +54,7 @@ pub fn random_tx() -> Transaction {
|
||||
to: TransactionKind::Call(Address::random()),
|
||||
value: rand::random::<u16>().into(),
|
||||
input: Bytes::default(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Generates a random legacy [Transaction] that is signed.
|
||||
@@ -154,14 +154,14 @@ pub fn random_block_range(rng: std::ops::Range<u64>, head: H256) -> Vec<BlockLoc
|
||||
mod test {
|
||||
use super::*;
|
||||
use hex_literal::hex;
|
||||
use reth_primitives::{keccak256, AccessList, Address, TransactionKind};
|
||||
use reth_primitives::{keccak256, AccessList, Address, TransactionKind, TxEip1559};
|
||||
use secp256k1::KeyPair;
|
||||
|
||||
#[test]
|
||||
fn test_sign_message() {
|
||||
let secp = Secp256k1::new();
|
||||
|
||||
let tx = Transaction::Eip1559 {
|
||||
let tx = Transaction::Eip1559(TxEip1559 {
|
||||
chain_id: 1,
|
||||
nonce: 0x42,
|
||||
gas_limit: 44386,
|
||||
@@ -171,7 +171,7 @@ mod test {
|
||||
max_fee_per_gas: 0x4a817c800,
|
||||
max_priority_fee_per_gas: 0x3b9aca00,
|
||||
access_list: AccessList::default(),
|
||||
};
|
||||
});
|
||||
let signature_hash = tx.signature_hash();
|
||||
|
||||
for _ in 0..100 {
|
||||
|
||||
@@ -75,7 +75,7 @@ fn bench_put_rand(c: &mut Criterion) {
|
||||
c.bench_function("bench_put_rand", |b| {
|
||||
b.iter(|| {
|
||||
let txn = env.begin_rw_txn().unwrap();
|
||||
for &(ref key, ref data) in items.iter() {
|
||||
for (key, data) in items.iter() {
|
||||
txn.put(&db, key, data, WriteFlags::empty()).unwrap();
|
||||
}
|
||||
})
|
||||
@@ -101,7 +101,7 @@ fn bench_put_rand_raw(c: &mut Criterion) {
|
||||
mdbx_txn_begin_ex(env, ptr::null_mut(), 0, &mut txn, ptr::null_mut());
|
||||
|
||||
let mut i: ::libc::c_int = 0;
|
||||
for &(ref key, ref data) in items.iter() {
|
||||
for (key, data) in items.iter() {
|
||||
key_val.iov_len = key.len() as size_t;
|
||||
key_val.iov_base = key.as_bytes().as_ptr() as *mut _;
|
||||
data_val.iov_len = data.len() as size_t;
|
||||
|
||||
@@ -101,7 +101,8 @@ mod test {
|
||||
};
|
||||
use hex_literal::hex;
|
||||
use reth_primitives::{
|
||||
BlockHashOrNumber, Header, Signature, Transaction, TransactionKind, TransactionSigned, U256,
|
||||
BlockHashOrNumber, Header, Signature, Transaction, TransactionKind, TransactionSigned,
|
||||
TxLegacy, U256,
|
||||
};
|
||||
use reth_rlp::{Decodable, Encodable};
|
||||
|
||||
@@ -341,7 +342,7 @@ mod test {
|
||||
message: BlockBodies(vec![
|
||||
BlockBody {
|
||||
transactions: vec![
|
||||
TransactionSigned::from_transaction_and_signature(Transaction::Legacy {
|
||||
TransactionSigned::from_transaction_and_signature(Transaction::Legacy(TxLegacy {
|
||||
chain_id: Some(1),
|
||||
nonce: 0x8u64,
|
||||
gas_price: 0x4a817c808,
|
||||
@@ -350,7 +351,7 @@ mod test {
|
||||
TransactionKind::Call(hex!("3535353535353535353535353535353535353535").into()),
|
||||
value: 0x200u64.into(),
|
||||
input: Default::default(),
|
||||
},
|
||||
}),
|
||||
Signature {
|
||||
odd_y_parity: false,
|
||||
r:
|
||||
@@ -359,7 +360,7 @@ mod test {
|
||||
U256::from_str("64b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10").unwrap(),
|
||||
}
|
||||
),
|
||||
TransactionSigned::from_transaction_and_signature(Transaction::Legacy {
|
||||
TransactionSigned::from_transaction_and_signature(Transaction::Legacy(TxLegacy {
|
||||
chain_id: Some(1),
|
||||
nonce: 0x9u64,
|
||||
gas_price: 0x4a817c809,
|
||||
@@ -368,7 +369,7 @@ mod test {
|
||||
TransactionKind::Call(hex!("3535353535353535353535353535353535353535").into()),
|
||||
value: 0x2d9u64.into(),
|
||||
input: Default::default(),
|
||||
}, Signature {
|
||||
}), Signature {
|
||||
odd_y_parity: false,
|
||||
r:
|
||||
U256::from_str("52f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb").unwrap(),
|
||||
@@ -422,7 +423,7 @@ mod test {
|
||||
message: BlockBodies(vec![
|
||||
BlockBody {
|
||||
transactions: vec![
|
||||
TransactionSigned::from_transaction_and_signature(Transaction::Legacy {
|
||||
TransactionSigned::from_transaction_and_signature(Transaction::Legacy(TxLegacy {
|
||||
chain_id: Some(1),
|
||||
nonce: 0x8u64,
|
||||
gas_price: 0x4a817c808,
|
||||
@@ -431,7 +432,7 @@ mod test {
|
||||
TransactionKind::Call(hex!("3535353535353535353535353535353535353535").into()),
|
||||
value: 0x200u64.into(),
|
||||
input: Default::default(),
|
||||
},
|
||||
}),
|
||||
Signature {
|
||||
odd_y_parity: false,
|
||||
r:
|
||||
@@ -440,7 +441,7 @@ mod test {
|
||||
U256::from_str("64b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10").unwrap(),
|
||||
}
|
||||
),
|
||||
TransactionSigned::from_transaction_and_signature(Transaction::Legacy {
|
||||
TransactionSigned::from_transaction_and_signature(Transaction::Legacy(TxLegacy {
|
||||
chain_id: Some(1),
|
||||
nonce: 0x9u64,
|
||||
gas_price: 0x4a817c809,
|
||||
@@ -449,7 +450,7 @@ mod test {
|
||||
TransactionKind::Call(hex!("3535353535353535353535353535353535353535").into()),
|
||||
value: 0x2d9u64.into(),
|
||||
input: Default::default(),
|
||||
},
|
||||
}),
|
||||
Signature {
|
||||
odd_y_parity: false,
|
||||
r:
|
||||
|
||||
@@ -97,7 +97,9 @@ mod test {
|
||||
|
||||
use crate::{message::RequestPair, GetPooledTransactions, PooledTransactions};
|
||||
use hex_literal::hex;
|
||||
use reth_primitives::{Signature, Transaction, TransactionKind, TransactionSigned, U256};
|
||||
use reth_primitives::{
|
||||
Signature, Transaction, TransactionKind, TransactionSigned, TxEip1559, TxLegacy, U256,
|
||||
};
|
||||
use reth_rlp::{Decodable, Encodable};
|
||||
|
||||
#[test]
|
||||
@@ -142,7 +144,7 @@ mod test {
|
||||
request_id: 1111,
|
||||
message: vec![
|
||||
TransactionSigned::from_transaction_and_signature(
|
||||
Transaction::Legacy {
|
||||
Transaction::Legacy(TxLegacy {
|
||||
chain_id: Some(1),
|
||||
nonce: 0x8u64,
|
||||
gas_price: 0x4a817c808,
|
||||
@@ -152,7 +154,7 @@ mod test {
|
||||
),
|
||||
value: 0x200u64.into(),
|
||||
input: Default::default(),
|
||||
},
|
||||
}),
|
||||
Signature {
|
||||
odd_y_parity: false,
|
||||
r: U256::from_str(
|
||||
@@ -166,7 +168,7 @@ mod test {
|
||||
},
|
||||
),
|
||||
TransactionSigned::from_transaction_and_signature(
|
||||
Transaction::Legacy {
|
||||
Transaction::Legacy(TxLegacy {
|
||||
chain_id: Some(1),
|
||||
nonce: 0x09u64,
|
||||
gas_price: 0x4a817c809,
|
||||
@@ -176,7 +178,7 @@ mod test {
|
||||
),
|
||||
value: 0x2d9u64.into(),
|
||||
input: Default::default(),
|
||||
},
|
||||
}),
|
||||
Signature {
|
||||
odd_y_parity: false,
|
||||
r: U256::from_str(
|
||||
@@ -204,7 +206,7 @@ mod test {
|
||||
request_id: 1111,
|
||||
message: vec![
|
||||
TransactionSigned::from_transaction_and_signature(
|
||||
Transaction::Legacy {
|
||||
Transaction::Legacy(TxLegacy {
|
||||
chain_id: Some(1),
|
||||
nonce: 0x8u64,
|
||||
gas_price: 0x4a817c808,
|
||||
@@ -214,7 +216,7 @@ mod test {
|
||||
),
|
||||
value: 0x200u64.into(),
|
||||
input: Default::default(),
|
||||
},
|
||||
}),
|
||||
Signature {
|
||||
odd_y_parity: false,
|
||||
r: U256::from_str(
|
||||
@@ -228,7 +230,7 @@ mod test {
|
||||
},
|
||||
),
|
||||
TransactionSigned::from_transaction_and_signature(
|
||||
Transaction::Legacy {
|
||||
Transaction::Legacy(TxLegacy {
|
||||
chain_id: Some(1),
|
||||
nonce: 0x09u64,
|
||||
gas_price: 0x4a817c809,
|
||||
@@ -238,7 +240,7 @@ mod test {
|
||||
),
|
||||
value: 0x2d9u64.into(),
|
||||
input: Default::default(),
|
||||
},
|
||||
}),
|
||||
Signature {
|
||||
odd_y_parity: false,
|
||||
r: U256::from_str(
|
||||
@@ -269,7 +271,7 @@ mod test {
|
||||
request_id: 0,
|
||||
message: vec![
|
||||
TransactionSigned::from_transaction_and_signature(
|
||||
Transaction::Legacy {
|
||||
Transaction::Legacy(TxLegacy {
|
||||
chain_id: Some(4),
|
||||
nonce: 15u64,
|
||||
gas_price: 2200000000,
|
||||
@@ -279,7 +281,7 @@ mod test {
|
||||
),
|
||||
value: 1234u64.into(),
|
||||
input: Default::default(),
|
||||
},
|
||||
}),
|
||||
Signature {
|
||||
odd_y_parity: true,
|
||||
r: U256::from_str(
|
||||
@@ -293,7 +295,7 @@ mod test {
|
||||
},
|
||||
),
|
||||
TransactionSigned::from_transaction_and_signature(
|
||||
Transaction::Eip1559 {
|
||||
Transaction::Eip1559(TxEip1559 {
|
||||
chain_id: 4,
|
||||
nonce: 26u64,
|
||||
max_priority_fee_per_gas: 1500000000,
|
||||
@@ -305,7 +307,7 @@ mod test {
|
||||
value: 3000000000000000000u64.into(),
|
||||
input: Default::default(),
|
||||
access_list: Default::default(),
|
||||
},
|
||||
}),
|
||||
Signature {
|
||||
odd_y_parity: true,
|
||||
r: U256::from_str(
|
||||
@@ -319,7 +321,7 @@ mod test {
|
||||
},
|
||||
),
|
||||
TransactionSigned::from_transaction_and_signature(
|
||||
Transaction::Legacy {
|
||||
Transaction::Legacy(TxLegacy {
|
||||
chain_id: Some(4),
|
||||
nonce: 3u64,
|
||||
gas_price: 2000000000,
|
||||
@@ -329,7 +331,7 @@ mod test {
|
||||
),
|
||||
value: 1000000000000000u64.into(),
|
||||
input: Default::default(),
|
||||
},
|
||||
}),
|
||||
Signature {
|
||||
odd_y_parity: false,
|
||||
r: U256::from_str(
|
||||
@@ -343,7 +345,7 @@ mod test {
|
||||
},
|
||||
),
|
||||
TransactionSigned::from_transaction_and_signature(
|
||||
Transaction::Legacy {
|
||||
Transaction::Legacy(TxLegacy {
|
||||
chain_id: Some(4),
|
||||
nonce: 1u64,
|
||||
gas_price: 1000000000,
|
||||
@@ -353,7 +355,7 @@ mod test {
|
||||
),
|
||||
value: 693361000000000u64.into(),
|
||||
input: Default::default(),
|
||||
},
|
||||
}),
|
||||
Signature {
|
||||
odd_y_parity: false,
|
||||
r: U256::from_str(
|
||||
@@ -367,7 +369,7 @@ mod test {
|
||||
},
|
||||
),
|
||||
TransactionSigned::from_transaction_and_signature(
|
||||
Transaction::Legacy {
|
||||
Transaction::Legacy(TxLegacy {
|
||||
chain_id: Some(4),
|
||||
nonce: 2u64,
|
||||
gas_price: 1000000000,
|
||||
@@ -377,7 +379,7 @@ mod test {
|
||||
),
|
||||
value: 1000000000000000u64.into(),
|
||||
input: Default::default(),
|
||||
},
|
||||
}),
|
||||
Signature {
|
||||
odd_y_parity: false,
|
||||
r: U256::from_str(
|
||||
@@ -412,7 +414,7 @@ mod test {
|
||||
request_id: 0,
|
||||
message: vec![
|
||||
TransactionSigned::from_transaction_and_signature(
|
||||
Transaction::Legacy {
|
||||
Transaction::Legacy(TxLegacy {
|
||||
chain_id: Some(4),
|
||||
nonce: 15u64,
|
||||
gas_price: 2200000000,
|
||||
@@ -422,7 +424,7 @@ mod test {
|
||||
),
|
||||
value: 1234u64.into(),
|
||||
input: Default::default(),
|
||||
},
|
||||
}),
|
||||
Signature {
|
||||
odd_y_parity: true,
|
||||
r: U256::from_str(
|
||||
@@ -436,7 +438,7 @@ mod test {
|
||||
},
|
||||
),
|
||||
TransactionSigned::from_transaction_and_signature(
|
||||
Transaction::Eip1559 {
|
||||
Transaction::Eip1559(TxEip1559 {
|
||||
chain_id: 4,
|
||||
nonce: 26u64,
|
||||
max_priority_fee_per_gas: 1500000000,
|
||||
@@ -448,7 +450,7 @@ mod test {
|
||||
value: 3000000000000000000u64.into(),
|
||||
input: Default::default(),
|
||||
access_list: Default::default(),
|
||||
},
|
||||
}),
|
||||
Signature {
|
||||
odd_y_parity: true,
|
||||
r: U256::from_str(
|
||||
@@ -462,7 +464,7 @@ mod test {
|
||||
},
|
||||
),
|
||||
TransactionSigned::from_transaction_and_signature(
|
||||
Transaction::Legacy {
|
||||
Transaction::Legacy(TxLegacy {
|
||||
chain_id: Some(4),
|
||||
nonce: 3u64,
|
||||
gas_price: 2000000000,
|
||||
@@ -472,7 +474,7 @@ mod test {
|
||||
),
|
||||
value: 1000000000000000u64.into(),
|
||||
input: Default::default(),
|
||||
},
|
||||
}),
|
||||
Signature {
|
||||
odd_y_parity: false,
|
||||
r: U256::from_str(
|
||||
@@ -486,7 +488,7 @@ mod test {
|
||||
},
|
||||
),
|
||||
TransactionSigned::from_transaction_and_signature(
|
||||
Transaction::Legacy {
|
||||
Transaction::Legacy(TxLegacy {
|
||||
chain_id: Some(4),
|
||||
nonce: 1u64,
|
||||
gas_price: 1000000000,
|
||||
@@ -496,7 +498,7 @@ mod test {
|
||||
),
|
||||
value: 693361000000000u64.into(),
|
||||
input: Default::default(),
|
||||
},
|
||||
}),
|
||||
Signature {
|
||||
odd_y_parity: false,
|
||||
r: U256::from_str(
|
||||
@@ -510,7 +512,7 @@ mod test {
|
||||
},
|
||||
),
|
||||
TransactionSigned::from_transaction_and_signature(
|
||||
Transaction::Legacy {
|
||||
Transaction::Legacy(TxLegacy {
|
||||
chain_id: Some(4),
|
||||
nonce: 2u64,
|
||||
gas_price: 1000000000,
|
||||
@@ -520,7 +522,7 @@ mod test {
|
||||
),
|
||||
value: 1000000000000000u64.into(),
|
||||
input: Default::default(),
|
||||
},
|
||||
}),
|
||||
Signature {
|
||||
odd_y_parity: false,
|
||||
r: U256::from_str(
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use crate::{H256, U256};
|
||||
use bytes::Buf;
|
||||
use modular_bitfield::prelude::*;
|
||||
use reth_codecs::{use_compact, Compact};
|
||||
use reth_codecs::{main_codec, Compact};
|
||||
|
||||
/// Account saved in database
|
||||
#[use_compact]
|
||||
#[main_codec]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
|
||||
pub struct Account {
|
||||
/// Nonce.
|
||||
|
||||
@@ -5,12 +5,12 @@ use crate::{
|
||||
use bytes::{Buf, BufMut, BytesMut};
|
||||
use ethers_core::{types::H64, utils::keccak256};
|
||||
use modular_bitfield::prelude::*;
|
||||
use reth_codecs::{use_compact, Compact};
|
||||
use reth_codecs::{main_codec, Compact};
|
||||
use reth_rlp::{length_of_length, Decodable, Encodable};
|
||||
use std::ops::Deref;
|
||||
|
||||
/// Block header
|
||||
#[use_compact]
|
||||
#[main_codec]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Header {
|
||||
/// The Keccak 256-bit hash of the parent
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use reth_codecs::main_codec;
|
||||
use reth_codecs::{main_codec, Compact};
|
||||
use reth_rlp::{Decodable, DecodeError, Encodable};
|
||||
use serde::{Deserialize, Deserializer, Serializer};
|
||||
use std::{
|
||||
|
||||
@@ -45,7 +45,8 @@ pub use receipt::Receipt;
|
||||
pub use storage::StorageEntry;
|
||||
pub use transaction::{
|
||||
AccessList, AccessListItem, FromRecoveredTransaction, IntoRecoveredTransaction, Signature,
|
||||
Transaction, TransactionKind, TransactionSigned, TransactionSignedEcRecovered, TxType,
|
||||
Transaction, TransactionKind, TransactionSigned, TransactionSignedEcRecovered, TxEip1559,
|
||||
TxEip2930, TxLegacy, TxType,
|
||||
};
|
||||
|
||||
/// A block hash.
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use crate::{Address, H256};
|
||||
use reth_codecs::{use_compact, Compact};
|
||||
use reth_codecs::{main_codec, Compact};
|
||||
use reth_rlp::{RlpDecodable, RlpEncodable};
|
||||
|
||||
/// Ethereum Log
|
||||
#[use_compact]
|
||||
#[main_codec]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, RlpDecodable, RlpEncodable, Default)]
|
||||
pub struct Log {
|
||||
/// Contract that emitted this log.
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use crate::{Bloom, Log, TxType};
|
||||
use bytes::{Buf, BufMut, BytesMut};
|
||||
use modular_bitfield::prelude::*;
|
||||
use reth_codecs::{use_compact, Compact};
|
||||
use reth_codecs::{main_codec, Compact};
|
||||
use reth_rlp::{length_of_length, Decodable, Encodable};
|
||||
use std::cmp::Ordering;
|
||||
|
||||
/// Receipt containing result of transaction execution.
|
||||
#[use_compact]
|
||||
#[main_codec]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Default)]
|
||||
pub struct Receipt {
|
||||
/// Receipt type.
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use super::{H256, U256};
|
||||
use bytes::Buf;
|
||||
use modular_bitfield::prelude::*;
|
||||
use reth_codecs::{use_compact, Compact};
|
||||
use reth_codecs::{main_codec, Compact};
|
||||
|
||||
/// Account storage entry.
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
||||
#[use_compact]
|
||||
#[main_codec]
|
||||
pub struct StorageEntry {
|
||||
/// Storage key.
|
||||
pub key: H256,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::{Address, H256};
|
||||
|
||||
use reth_codecs::main_codec;
|
||||
use reth_codecs::{main_codec, Compact};
|
||||
use reth_rlp::{RlpDecodable, RlpDecodableWrapper, RlpEncodable, RlpEncodableWrapper};
|
||||
|
||||
/// A list of addresses and storage keys that the transaction plans to access.
|
||||
|
||||
@@ -3,7 +3,8 @@ pub use access_list::{AccessList, AccessListItem};
|
||||
use bytes::{Buf, BytesMut};
|
||||
use derive_more::{AsRef, Deref};
|
||||
use ethers_core::utils::keccak256;
|
||||
use reth_codecs::main_codec;
|
||||
use modular_bitfield::prelude::*;
|
||||
use reth_codecs::{main_codec, Compact};
|
||||
use reth_rlp::{length_of_length, Decodable, DecodeError, Encodable, Header, EMPTY_STRING_CODE};
|
||||
pub use signature::Signature;
|
||||
pub use tx_type::TxType;
|
||||
@@ -13,6 +14,152 @@ mod signature;
|
||||
mod tx_type;
|
||||
mod util;
|
||||
|
||||
/// Legacy transaction.
|
||||
#[main_codec]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
|
||||
pub struct TxLegacy {
|
||||
/// Added as EIP-155: Simple replay attack protection
|
||||
pub chain_id: Option<ChainId>,
|
||||
/// A scalar value equal to the number of transactions sent by the sender; formally Tn.
|
||||
pub nonce: u64,
|
||||
/// A scalar value equal to the number of
|
||||
/// Wei to be paid per unit of gas for all computation
|
||||
/// costs incurred as a result of the execution of this transaction; formally Tp.
|
||||
///
|
||||
/// As ethereum circulation is around 120mil eth as of 2022 that is around
|
||||
/// 120000000000000000000000000 wei we are safe to use u128 as its max number is:
|
||||
/// 340282366920938463463374607431768211455
|
||||
pub gas_price: u128,
|
||||
/// A scalar value equal to the maximum
|
||||
/// amount of gas that should be used in executing
|
||||
/// this transaction. This is paid up-front, before any
|
||||
/// computation is done and may not be increased
|
||||
/// later; formally Tg.
|
||||
pub gas_limit: u64,
|
||||
/// The 160-bit address of the message call’s recipient or, for a contract creation
|
||||
/// transaction, ∅, used here to denote the only member of B0 ; formally Tt.
|
||||
pub to: TransactionKind,
|
||||
/// A scalar value equal to the number of Wei to
|
||||
/// be transferred to the message call’s recipient or,
|
||||
/// in the case of contract creation, as an endowment
|
||||
/// to the newly created account; formally Tv.
|
||||
///
|
||||
/// As ethereum circulation is around 120mil eth as of 2022 that is around
|
||||
/// 120000000000000000000000000 wei we are safe to use u128 as its max number is:
|
||||
/// 340282366920938463463374607431768211455
|
||||
pub value: u128,
|
||||
/// Input has two uses depending if transaction is Create or Call (if `to` field is None or
|
||||
/// Some). pub init: An unlimited size byte array specifying the
|
||||
/// EVM-code for the account initialisation procedure CREATE,
|
||||
/// data: An unlimited size byte array specifying the
|
||||
/// input data of the message call, formally Td.
|
||||
pub input: Bytes,
|
||||
}
|
||||
|
||||
/// Transaction with an [`AccessList`] ([EIP-2930](https://eips.ethereum.org/EIPS/eip-2930)).
|
||||
#[main_codec]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
|
||||
pub struct TxEip2930 {
|
||||
/// Added as EIP-pub 155: Simple replay attack protection
|
||||
pub chain_id: ChainId,
|
||||
/// A scalar value equal to the number of transactions sent by the sender; formally Tn.
|
||||
pub nonce: u64,
|
||||
/// A scalar value equal to the number of
|
||||
/// Wei to be paid per unit of gas for all computation
|
||||
/// costs incurred as a result of the execution of this transaction; formally Tp.
|
||||
///
|
||||
/// As ethereum circulation is around 120mil eth as of 2022 that is around
|
||||
/// 120000000000000000000000000 wei we are safe to use u128 as its max number is:
|
||||
/// 340282366920938463463374607431768211455
|
||||
pub gas_price: u128,
|
||||
/// A scalar value equal to the maximum
|
||||
/// amount of gas that should be used in executing
|
||||
/// this transaction. This is paid up-front, before any
|
||||
/// computation is done and may not be increased
|
||||
/// later; formally Tg.
|
||||
pub gas_limit: u64,
|
||||
/// The 160-bit address of the message call’s recipient or, for a contract creation
|
||||
/// transaction, ∅, used here to denote the only member of B0 ; formally Tt.
|
||||
pub to: TransactionKind,
|
||||
/// A scalar value equal to the number of Wei to
|
||||
/// be transferred to the message call’s recipient or,
|
||||
/// in the case of contract creation, as an endowment
|
||||
/// to the newly created account; formally Tv.
|
||||
///
|
||||
/// As ethereum circulation is around 120mil eth as of 2022 that is around
|
||||
/// 120000000000000000000000000 wei we are safe to use u128 as its max number is:
|
||||
/// 340282366920938463463374607431768211455
|
||||
pub value: u128,
|
||||
/// The accessList specifies a list of addresses and storage keys;
|
||||
/// these addresses and storage keys are added into the `accessed_addresses`
|
||||
/// and `accessed_storage_keys` global sets (introduced in EIP-2929).
|
||||
/// A gas cost is charged, though at a discount relative to the cost of
|
||||
/// accessing outside the list.
|
||||
pub access_list: AccessList,
|
||||
/// Input has two uses depending if transaction is Create or Call (if `to` field is None or
|
||||
/// Some). pub init: An unlimited size byte array specifying the
|
||||
/// EVM-code for the account initialisation procedure CREATE,
|
||||
/// data: An unlimited size byte array specifying the
|
||||
/// input data of the message call, formally Td.
|
||||
pub input: Bytes,
|
||||
}
|
||||
|
||||
/// A transaction with a priority fee ([EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)).
|
||||
#[main_codec]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
|
||||
pub struct TxEip1559 {
|
||||
/// Added as EIP-pub 155: Simple replay attack protection
|
||||
pub chain_id: u64,
|
||||
/// A scalar value equal to the number of transactions sent by the sender; formally Tn.
|
||||
pub nonce: u64,
|
||||
/// A scalar value equal to the maximum
|
||||
/// amount of gas that should be used in executing
|
||||
/// this transaction. This is paid up-front, before any
|
||||
/// computation is done and may not be increased
|
||||
/// later; formally Tg.
|
||||
pub gas_limit: u64,
|
||||
/// A scalar value equal to the maximum
|
||||
/// amount of gas that should be used in executing
|
||||
/// this transaction. This is paid up-front, before any
|
||||
/// computation is done and may not be increased
|
||||
/// later; formally Tg.
|
||||
///
|
||||
/// As ethereum circulation is around 120mil eth as of 2022 that is around
|
||||
/// 120000000000000000000000000 wei we are safe to use u128 as its max number is:
|
||||
/// 340282366920938463463374607431768211455
|
||||
pub max_fee_per_gas: u128,
|
||||
/// Max Priority fee that transaction is paying
|
||||
///
|
||||
/// As ethereum circulation is around 120mil eth as of 2022 that is around
|
||||
/// 120000000000000000000000000 wei we are safe to use u128 as its max number is:
|
||||
/// 340282366920938463463374607431768211455
|
||||
pub max_priority_fee_per_gas: u128,
|
||||
/// The 160-bit address of the message call’s recipient or, for a contract creation
|
||||
/// transaction, ∅, used here to denote the only member of B0 ; formally Tt.
|
||||
pub to: TransactionKind,
|
||||
/// A scalar value equal to the number of Wei to
|
||||
/// be transferred to the message call’s recipient or,
|
||||
/// in the case of contract creation, as an endowment
|
||||
/// to the newly created account; formally Tv.
|
||||
///
|
||||
/// As ethereum circulation is around 120mil eth as of 2022 that is around
|
||||
/// 120000000000000000000000000 wei we are safe to use u128 as its max number is:
|
||||
/// 340282366920938463463374607431768211455
|
||||
pub value: u128,
|
||||
/// The accessList specifies a list of addresses and storage keys;
|
||||
/// these addresses and storage keys are added into the `accessed_addresses`
|
||||
/// and `accessed_storage_keys` global sets (introduced in EIP-2929).
|
||||
/// A gas cost is charged, though at a discount relative to the cost of
|
||||
/// accessing outside the list.
|
||||
pub access_list: AccessList,
|
||||
/// Input has two uses depending if transaction is Create or Call (if `to` field is None or
|
||||
/// Some). pub init: An unlimited size byte array specifying the
|
||||
/// EVM-code for the account initialisation procedure CREATE,
|
||||
/// data: An unlimited size byte array specifying the
|
||||
/// input data of the message call, formally Td.
|
||||
pub input: Bytes,
|
||||
}
|
||||
|
||||
/// A raw transaction.
|
||||
///
|
||||
/// Transaction types were introduced in [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718).
|
||||
@@ -20,142 +167,17 @@ mod util;
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum Transaction {
|
||||
/// Legacy transaction.
|
||||
Legacy {
|
||||
/// Added as EIP-155: Simple replay attack protection
|
||||
chain_id: Option<ChainId>,
|
||||
/// A scalar value equal to the number of transactions sent by the sender; formally Tn.
|
||||
nonce: u64,
|
||||
/// A scalar value equal to the number of
|
||||
/// Wei to be paid per unit of gas for all computation
|
||||
/// costs incurred as a result of the execution of this transaction; formally Tp.
|
||||
///
|
||||
/// As ethereum circulation is around 120mil eth as of 2022 that is around
|
||||
/// 120000000000000000000000000 wei we are safe to use u128 as its max number is:
|
||||
/// 340282366920938463463374607431768211455
|
||||
gas_price: u128,
|
||||
/// A scalar value equal to the maximum
|
||||
/// amount of gas that should be used in executing
|
||||
/// this transaction. This is paid up-front, before any
|
||||
/// computation is done and may not be increased
|
||||
/// later; formally Tg.
|
||||
gas_limit: u64,
|
||||
/// The 160-bit address of the message call’s recipient or, for a contract creation
|
||||
/// transaction, ∅, used here to denote the only member of B0 ; formally Tt.
|
||||
to: TransactionKind,
|
||||
/// A scalar value equal to the number of Wei to
|
||||
/// be transferred to the message call’s recipient or,
|
||||
/// in the case of contract creation, as an endowment
|
||||
/// to the newly created account; formally Tv.
|
||||
///
|
||||
/// As ethereum circulation is around 120mil eth as of 2022 that is around
|
||||
/// 120000000000000000000000000 wei we are safe to use u128 as its max number is:
|
||||
/// 340282366920938463463374607431768211455
|
||||
value: u128,
|
||||
/// Input has two uses depending if transaction is Create or Call (if `to` field is None or
|
||||
/// Some). init: An unlimited size byte array specifying the
|
||||
/// EVM-code for the account initialisation procedure CREATE,
|
||||
/// data: An unlimited size byte array specifying the
|
||||
/// input data of the message call, formally Td.
|
||||
input: Bytes,
|
||||
},
|
||||
Legacy(TxLegacy),
|
||||
/// Transaction with an [`AccessList`] ([EIP-2930](https://eips.ethereum.org/EIPS/eip-2930)).
|
||||
Eip2930 {
|
||||
/// Added as EIP-155: Simple replay attack protection
|
||||
chain_id: ChainId,
|
||||
/// A scalar value equal to the number of transactions sent by the sender; formally Tn.
|
||||
nonce: u64,
|
||||
/// A scalar value equal to the number of
|
||||
/// Wei to be paid per unit of gas for all computation
|
||||
/// costs incurred as a result of the execution of this transaction; formally Tp.
|
||||
///
|
||||
/// As ethereum circulation is around 120mil eth as of 2022 that is around
|
||||
/// 120000000000000000000000000 wei we are safe to use u128 as its max number is:
|
||||
/// 340282366920938463463374607431768211455
|
||||
gas_price: u128,
|
||||
/// A scalar value equal to the maximum
|
||||
/// amount of gas that should be used in executing
|
||||
/// this transaction. This is paid up-front, before any
|
||||
/// computation is done and may not be increased
|
||||
/// later; formally Tg.
|
||||
gas_limit: u64,
|
||||
/// The 160-bit address of the message call’s recipient or, for a contract creation
|
||||
/// transaction, ∅, used here to denote the only member of B0 ; formally Tt.
|
||||
to: TransactionKind,
|
||||
/// A scalar value equal to the number of Wei to
|
||||
/// be transferred to the message call’s recipient or,
|
||||
/// in the case of contract creation, as an endowment
|
||||
/// to the newly created account; formally Tv.
|
||||
///
|
||||
/// As ethereum circulation is around 120mil eth as of 2022 that is around
|
||||
/// 120000000000000000000000000 wei we are safe to use u128 as its max number is:
|
||||
/// 340282366920938463463374607431768211455
|
||||
value: u128,
|
||||
/// Input has two uses depending if transaction is Create or Call (if `to` field is None or
|
||||
/// Some). init: An unlimited size byte array specifying the
|
||||
/// EVM-code for the account initialisation procedure CREATE,
|
||||
/// data: An unlimited size byte array specifying the
|
||||
/// input data of the message call, formally Td.
|
||||
input: Bytes,
|
||||
/// The accessList specifies a list of addresses and storage keys;
|
||||
/// these addresses and storage keys are added into the `accessed_addresses`
|
||||
/// and `accessed_storage_keys` global sets (introduced in EIP-2929).
|
||||
/// A gas cost is charged, though at a discount relative to the cost of
|
||||
/// accessing outside the list.
|
||||
access_list: AccessList,
|
||||
},
|
||||
Eip2930(TxEip2930),
|
||||
/// A transaction with a priority fee ([EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)).
|
||||
Eip1559 {
|
||||
/// Added as EIP-155: Simple replay attack protection
|
||||
chain_id: u64,
|
||||
/// A scalar value equal to the number of transactions sent by the sender; formally Tn.
|
||||
nonce: u64,
|
||||
/// A scalar value equal to the maximum
|
||||
/// amount of gas that should be used in executing
|
||||
/// this transaction. This is paid up-front, before any
|
||||
/// computation is done and may not be increased
|
||||
/// later; formally Tg.
|
||||
gas_limit: u64,
|
||||
/// A scalar value equal to the maximum
|
||||
/// amount of gas that should be used in executing
|
||||
/// this transaction. This is paid up-front, before any
|
||||
/// computation is done and may not be increased
|
||||
/// later; formally Tg.
|
||||
///
|
||||
/// As ethereum circulation is around 120mil eth as of 2022 that is around
|
||||
/// 120000000000000000000000000 wei we are safe to use u128 as its max number is:
|
||||
/// 340282366920938463463374607431768211455
|
||||
max_fee_per_gas: u128,
|
||||
/// Max Priority fee that transaction is paying
|
||||
///
|
||||
/// As ethereum circulation is around 120mil eth as of 2022 that is around
|
||||
/// 120000000000000000000000000 wei we are safe to use u128 as its max number is:
|
||||
/// 340282366920938463463374607431768211455
|
||||
max_priority_fee_per_gas: u128,
|
||||
/// The 160-bit address of the message call’s recipient or, for a contract creation
|
||||
/// transaction, ∅, used here to denote the only member of B0 ; formally Tt.
|
||||
to: TransactionKind,
|
||||
/// A scalar value equal to the number of Wei to
|
||||
/// be transferred to the message call’s recipient or,
|
||||
/// in the case of contract creation, as an endowment
|
||||
/// to the newly created account; formally Tv.
|
||||
///
|
||||
/// As ethereum circulation is around 120mil eth as of 2022 that is around
|
||||
/// 120000000000000000000000000 wei we are safe to use u128 as its max number is:
|
||||
/// 340282366920938463463374607431768211455
|
||||
value: u128,
|
||||
/// Input has two uses depending if transaction is Create or Call (if `to` field is None or
|
||||
/// Some). init: An unlimited size byte array specifying the
|
||||
/// EVM-code for the account initialisation procedure CREATE,
|
||||
/// data: An unlimited size byte array specifying the
|
||||
/// input data of the message call, formally Td.
|
||||
input: Bytes,
|
||||
/// The accessList specifies a list of addresses and storage keys;
|
||||
/// these addresses and storage keys are added into the `accessed_addresses`
|
||||
/// and `accessed_storage_keys` global sets (introduced in EIP-2929).
|
||||
/// A gas cost is charged, though at a discount relative to the cost of
|
||||
/// accessing outside the list.
|
||||
access_list: AccessList,
|
||||
},
|
||||
Eip1559(TxEip1559),
|
||||
}
|
||||
|
||||
impl Default for Transaction {
|
||||
fn default() -> Self {
|
||||
Self::Legacy(TxLegacy::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl Transaction {
|
||||
@@ -170,9 +192,9 @@ impl Transaction {
|
||||
/// Sets the transaction's chain id to the provided value.
|
||||
pub fn set_chain_id(&mut self, chain_id: u64) {
|
||||
match self {
|
||||
Transaction::Legacy { chain_id: ref mut c, .. } => *c = Some(chain_id),
|
||||
Transaction::Eip2930 { chain_id: ref mut c, .. } => *c = chain_id,
|
||||
Transaction::Eip1559 { chain_id: ref mut c, .. } => *c = chain_id,
|
||||
Transaction::Legacy(TxLegacy { chain_id: ref mut c, .. }) => *c = Some(chain_id),
|
||||
Transaction::Eip2930(TxEip2930 { chain_id: ref mut c, .. }) => *c = chain_id,
|
||||
Transaction::Eip1559(TxEip1559 { chain_id: ref mut c, .. }) => *c = chain_id,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,9 +202,9 @@ impl Transaction {
|
||||
/// [`TransactionKind::Create`] if the transaction is a contract creation.
|
||||
pub fn kind(&self) -> &TransactionKind {
|
||||
match self {
|
||||
Transaction::Legacy { to, .. } |
|
||||
Transaction::Eip2930 { to, .. } |
|
||||
Transaction::Eip1559 { to, .. } => to,
|
||||
Transaction::Legacy(TxLegacy { to, .. }) |
|
||||
Transaction::Eip2930(TxEip2930 { to, .. }) |
|
||||
Transaction::Eip1559(TxEip1559 { to, .. }) => to,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,46 +220,45 @@ impl Transaction {
|
||||
/// Gets the transaction's value field.
|
||||
pub fn value(&self) -> &u128 {
|
||||
match self {
|
||||
Transaction::Legacy { value, .. } => value,
|
||||
Transaction::Eip2930 { value, .. } => value,
|
||||
Transaction::Eip1559 { value, .. } => value,
|
||||
Transaction::Legacy(TxLegacy { value, .. }) => value,
|
||||
Transaction::Eip2930(TxEip2930 { value, .. }) => value,
|
||||
Transaction::Eip1559(TxEip1559 { value, .. }) => value,
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the transaction's nonce.
|
||||
pub fn nonce(&self) -> u64 {
|
||||
match self {
|
||||
Transaction::Legacy { nonce, .. } => *nonce,
|
||||
Transaction::Eip2930 { nonce, .. } => *nonce,
|
||||
Transaction::Eip1559 { nonce, .. } => *nonce,
|
||||
Transaction::Legacy(TxLegacy { nonce, .. }) => *nonce,
|
||||
Transaction::Eip2930(TxEip2930 { nonce, .. }) => *nonce,
|
||||
Transaction::Eip1559(TxEip1559 { nonce, .. }) => *nonce,
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the gas limit of the transaction.
|
||||
pub fn gas_limit(&self) -> u64 {
|
||||
match self {
|
||||
Transaction::Legacy { gas_limit, .. } |
|
||||
Transaction::Eip2930 { gas_limit, .. } |
|
||||
Transaction::Eip1559 { gas_limit, .. } => *gas_limit,
|
||||
Transaction::Legacy(TxLegacy { gas_limit, .. }) |
|
||||
Transaction::Eip2930(TxEip2930 { gas_limit, .. }) |
|
||||
Transaction::Eip1559(TxEip1559 { gas_limit, .. }) => *gas_limit,
|
||||
}
|
||||
}
|
||||
|
||||
/// Max fee per gas for eip1559 transaction, for legacy transactions this is gas_price
|
||||
pub fn max_fee_per_gas(&self) -> u128 {
|
||||
match self {
|
||||
Transaction::Legacy { gas_price, .. } | Transaction::Eip2930 { gas_price, .. } => {
|
||||
*gas_price
|
||||
}
|
||||
Transaction::Eip1559 { max_fee_per_gas, .. } => *max_fee_per_gas,
|
||||
Transaction::Legacy(TxLegacy { gas_price, .. }) |
|
||||
Transaction::Eip2930(TxEip2930 { gas_price, .. }) => *gas_price,
|
||||
Transaction::Eip1559(TxEip1559 { max_fee_per_gas, .. }) => *max_fee_per_gas,
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the transaction's input field.
|
||||
pub fn input(&self) -> &Bytes {
|
||||
match self {
|
||||
Transaction::Legacy { input, .. } => input,
|
||||
Transaction::Eip2930 { input, .. } => input,
|
||||
Transaction::Eip1559 { input, .. } => input,
|
||||
Transaction::Legacy(TxLegacy { input, .. }) => input,
|
||||
Transaction::Eip2930(TxEip2930 { input, .. }) => input,
|
||||
Transaction::Eip1559(TxEip1559 { input, .. }) => input,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,7 +286,7 @@ impl Transaction {
|
||||
pub(crate) fn encode_eip155_fields(&self, out: &mut dyn bytes::BufMut) {
|
||||
// if this is a legacy transaction without a chain ID, it must be pre-EIP-155
|
||||
// and does not need to encode the chain ID for the signature hash encoding
|
||||
if let Transaction::Legacy { chain_id: Some(id), .. } = self {
|
||||
if let Transaction::Legacy(TxLegacy { chain_id: Some(id), .. }) = self {
|
||||
// EIP-155 encodes the chain ID and two zeroes
|
||||
id.encode(out);
|
||||
0x00u8.encode(out);
|
||||
@@ -276,7 +297,7 @@ impl Transaction {
|
||||
/// Outputs the length of EIP-155 fields. Only outputs a non-zero value for EIP-155 legacy
|
||||
/// transactions.
|
||||
pub(crate) fn eip155_fields_len(&self) -> usize {
|
||||
if let Transaction::Legacy { chain_id: Some(id), .. } = self {
|
||||
if let Transaction::Legacy(TxLegacy { chain_id: Some(id), .. }) = self {
|
||||
// EIP-155 encodes the chain ID and two zeroes, so we add 2 to the length of the chain
|
||||
// ID to get the length of all 3 fields
|
||||
// len(chain_id) + (0x00) + (0x00)
|
||||
@@ -306,7 +327,15 @@ impl Transaction {
|
||||
/// eip155 fields.
|
||||
pub(crate) fn fields_len(&self) -> usize {
|
||||
match self {
|
||||
Transaction::Legacy { chain_id: _, nonce, gas_price, gas_limit, to, value, input } => {
|
||||
Transaction::Legacy(TxLegacy {
|
||||
chain_id: _,
|
||||
nonce,
|
||||
gas_price,
|
||||
gas_limit,
|
||||
to,
|
||||
value,
|
||||
input,
|
||||
}) => {
|
||||
let mut len = 0;
|
||||
len += nonce.length();
|
||||
len += gas_price.length();
|
||||
@@ -316,7 +345,7 @@ impl Transaction {
|
||||
len += input.0.length();
|
||||
len
|
||||
}
|
||||
Transaction::Eip2930 {
|
||||
Transaction::Eip2930(TxEip2930 {
|
||||
chain_id,
|
||||
nonce,
|
||||
gas_price,
|
||||
@@ -325,7 +354,7 @@ impl Transaction {
|
||||
value,
|
||||
input,
|
||||
access_list,
|
||||
} => {
|
||||
}) => {
|
||||
let mut len = 0;
|
||||
len += chain_id.length();
|
||||
len += nonce.length();
|
||||
@@ -337,7 +366,7 @@ impl Transaction {
|
||||
len += access_list.length();
|
||||
len
|
||||
}
|
||||
Transaction::Eip1559 {
|
||||
Transaction::Eip1559(TxEip1559 {
|
||||
chain_id,
|
||||
nonce,
|
||||
gas_limit,
|
||||
@@ -347,7 +376,7 @@ impl Transaction {
|
||||
value,
|
||||
input,
|
||||
access_list,
|
||||
} => {
|
||||
}) => {
|
||||
let mut len = 0;
|
||||
len += chain_id.length();
|
||||
len += nonce.length();
|
||||
@@ -366,7 +395,15 @@ impl Transaction {
|
||||
/// Encodes only the transaction's fields into the desired buffer, without a RLP header.
|
||||
pub(crate) fn encode_fields(&self, out: &mut dyn bytes::BufMut) {
|
||||
match self {
|
||||
Transaction::Legacy { chain_id: _, nonce, gas_price, gas_limit, to, value, input } => {
|
||||
Transaction::Legacy(TxLegacy {
|
||||
chain_id: _,
|
||||
nonce,
|
||||
gas_price,
|
||||
gas_limit,
|
||||
to,
|
||||
value,
|
||||
input,
|
||||
}) => {
|
||||
nonce.encode(out);
|
||||
gas_price.encode(out);
|
||||
gas_limit.encode(out);
|
||||
@@ -374,7 +411,7 @@ impl Transaction {
|
||||
value.encode(out);
|
||||
input.0.encode(out);
|
||||
}
|
||||
Transaction::Eip2930 {
|
||||
Transaction::Eip2930(TxEip2930 {
|
||||
chain_id,
|
||||
nonce,
|
||||
gas_price,
|
||||
@@ -383,7 +420,7 @@ impl Transaction {
|
||||
value,
|
||||
input,
|
||||
access_list,
|
||||
} => {
|
||||
}) => {
|
||||
chain_id.encode(out);
|
||||
nonce.encode(out);
|
||||
gas_price.encode(out);
|
||||
@@ -393,7 +430,7 @@ impl Transaction {
|
||||
input.0.encode(out);
|
||||
access_list.encode(out);
|
||||
}
|
||||
Transaction::Eip1559 {
|
||||
Transaction::Eip1559(TxEip1559 {
|
||||
chain_id,
|
||||
nonce,
|
||||
gas_limit,
|
||||
@@ -403,7 +440,7 @@ impl Transaction {
|
||||
value,
|
||||
input,
|
||||
access_list,
|
||||
} => {
|
||||
}) => {
|
||||
chain_id.encode(out);
|
||||
nonce.encode(out);
|
||||
max_priority_fee_per_gas.encode(out);
|
||||
@@ -449,9 +486,10 @@ impl Encodable for Transaction {
|
||||
|
||||
/// Whether or not the transaction is a contract creation.
|
||||
#[main_codec]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
|
||||
pub enum TransactionKind {
|
||||
/// A transaction that creates a contract.
|
||||
#[default]
|
||||
Create,
|
||||
/// A transaction that calls a contract or transfer.
|
||||
Call(Address),
|
||||
@@ -490,16 +528,16 @@ impl Decodable for TransactionKind {
|
||||
|
||||
/// Signed transaction.
|
||||
#[main_codec]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, AsRef, Deref)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, AsRef, Deref, Default)]
|
||||
pub struct TransactionSigned {
|
||||
/// Raw transaction info
|
||||
#[deref]
|
||||
#[as_ref]
|
||||
pub transaction: Transaction,
|
||||
/// Transaction hash
|
||||
pub hash: TxHash,
|
||||
/// The transaction signature values
|
||||
pub signature: Signature,
|
||||
/// Raw transaction info
|
||||
#[deref]
|
||||
#[as_ref]
|
||||
pub transaction: Transaction,
|
||||
}
|
||||
|
||||
impl Encodable for TransactionSigned {
|
||||
@@ -540,7 +578,7 @@ impl Decodable for TransactionSigned {
|
||||
|
||||
// decode common fields
|
||||
let transaction = match tx_type {
|
||||
1 => Transaction::Eip2930 {
|
||||
1 => Transaction::Eip2930(TxEip2930 {
|
||||
chain_id: Decodable::decode(buf)?,
|
||||
nonce: Decodable::decode(buf)?,
|
||||
gas_price: Decodable::decode(buf)?,
|
||||
@@ -549,8 +587,8 @@ impl Decodable for TransactionSigned {
|
||||
value: Decodable::decode(buf)?,
|
||||
input: Bytes(Decodable::decode(buf)?),
|
||||
access_list: Decodable::decode(buf)?,
|
||||
},
|
||||
2 => Transaction::Eip1559 {
|
||||
}),
|
||||
2 => Transaction::Eip1559(TxEip1559 {
|
||||
chain_id: Decodable::decode(buf)?,
|
||||
nonce: Decodable::decode(buf)?,
|
||||
max_priority_fee_per_gas: Decodable::decode(buf)?,
|
||||
@@ -560,7 +598,7 @@ impl Decodable for TransactionSigned {
|
||||
value: Decodable::decode(buf)?,
|
||||
input: Bytes(Decodable::decode(buf)?),
|
||||
access_list: Decodable::decode(buf)?,
|
||||
},
|
||||
}),
|
||||
_ => return Err(DecodeError::Custom("unsupported typed transaction type")),
|
||||
};
|
||||
|
||||
@@ -574,7 +612,7 @@ impl Decodable for TransactionSigned {
|
||||
signed.hash = keccak256(&original_encoding[..first_header.payload_length]).into();
|
||||
Ok(signed)
|
||||
} else {
|
||||
let mut transaction = Transaction::Legacy {
|
||||
let mut transaction = Transaction::Legacy(TxLegacy {
|
||||
nonce: Decodable::decode(buf)?,
|
||||
gas_price: Decodable::decode(buf)?,
|
||||
gas_limit: Decodable::decode(buf)?,
|
||||
@@ -582,7 +620,7 @@ impl Decodable for TransactionSigned {
|
||||
value: Decodable::decode(buf)?,
|
||||
input: Bytes(Decodable::decode(buf)?),
|
||||
chain_id: None,
|
||||
};
|
||||
});
|
||||
let (signature, extracted_id) = Signature::decode_eip155_inner(buf)?;
|
||||
if let Some(id) = extracted_id {
|
||||
transaction.set_chain_id(id);
|
||||
@@ -630,7 +668,7 @@ impl TransactionSigned {
|
||||
/// Inner encoding function that is used for both rlp [`Encodable`] trait and for calculating
|
||||
/// hash that for eip2728 does not require rlp header
|
||||
pub(crate) fn encode_inner(&self, out: &mut dyn bytes::BufMut, with_header: bool) {
|
||||
if let Transaction::Legacy { chain_id, .. } = self.transaction {
|
||||
if let Transaction::Legacy(TxLegacy { chain_id, .. }) = self.transaction {
|
||||
let header = Header { list: true, payload_length: self.payload_len() };
|
||||
header.encode(out);
|
||||
self.transaction.encode_fields(out);
|
||||
@@ -688,7 +726,7 @@ impl TransactionSigned {
|
||||
/// Output the length of the inner transaction and signature fields.
|
||||
pub(crate) fn inner_tx_len(&self) -> usize {
|
||||
let mut len = self.transaction.fields_len();
|
||||
if let Transaction::Legacy { chain_id, .. } = self.transaction {
|
||||
if let Transaction::Legacy(TxLegacy { chain_id, .. }) = self.transaction {
|
||||
if let Some(id) = chain_id {
|
||||
len += self.signature.eip155_payload_len(id);
|
||||
} else {
|
||||
@@ -719,14 +757,14 @@ impl TransactionSigned {
|
||||
|
||||
/// Signed transaction with recovered signer.
|
||||
#[main_codec]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, AsRef, Deref)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, AsRef, Deref, Default)]
|
||||
pub struct TransactionSignedEcRecovered {
|
||||
/// Signer of the transaction
|
||||
signer: Address,
|
||||
/// Signed transaction
|
||||
#[deref]
|
||||
#[as_ref]
|
||||
signed_transaction: TransactionSigned,
|
||||
/// Signer of the transaction
|
||||
signer: Address,
|
||||
}
|
||||
|
||||
impl Encodable for TransactionSignedEcRecovered {
|
||||
@@ -792,7 +830,7 @@ impl IntoRecoveredTransaction for TransactionSignedEcRecovered {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{
|
||||
transaction::{signature::Signature, TransactionKind},
|
||||
transaction::{signature::Signature, TransactionKind, TxEip1559, TxEip2930, TxLegacy},
|
||||
AccessList, Address, Bytes, Transaction, TransactionSigned, H256, U256,
|
||||
};
|
||||
use bytes::BytesMut;
|
||||
@@ -803,7 +841,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_decode_create() {
|
||||
// tests that a contract creation tx encodes and decodes properly
|
||||
let request = Transaction::Eip2930 {
|
||||
let request = Transaction::Eip2930(TxEip2930 {
|
||||
chain_id: 1u64,
|
||||
nonce: 0,
|
||||
gas_price: 1,
|
||||
@@ -812,7 +850,7 @@ mod tests {
|
||||
value: 3,
|
||||
input: Bytes::from(vec![1, 2]),
|
||||
access_list: Default::default(),
|
||||
};
|
||||
});
|
||||
let signature = Signature { odd_y_parity: true, r: U256::default(), s: U256::default() };
|
||||
let tx = TransactionSigned::from_transaction_and_signature(request, signature);
|
||||
|
||||
@@ -834,7 +872,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_decode_call() {
|
||||
let request = Transaction::Eip2930 {
|
||||
let request = Transaction::Eip2930(TxEip2930 {
|
||||
chain_id: 1u64,
|
||||
nonce: 0,
|
||||
gas_price: 1,
|
||||
@@ -843,7 +881,7 @@ mod tests {
|
||||
value: 3,
|
||||
input: Bytes::from(vec![1, 2]),
|
||||
access_list: Default::default(),
|
||||
};
|
||||
});
|
||||
|
||||
let signature = Signature { odd_y_parity: true, r: U256::default(), s: U256::default() };
|
||||
|
||||
@@ -871,7 +909,7 @@ mod tests {
|
||||
#[test]
|
||||
fn decode_multiple_network_txs() {
|
||||
let bytes_first = &mut &hex::decode("f86b02843b9aca00830186a094d3e8763675e4c425df46cc3b5c0f6cbdac39604687038d7ea4c68000802ba00eb96ca19e8a77102767a41fc85a36afd5c61ccb09911cec5d3e86e193d9c5aea03a456401896b1b6055311536bf00a718568c744d8c1f9df59879e8350220ca18").unwrap()[..];
|
||||
let expected_request = Transaction::Legacy {
|
||||
let expected_request = Transaction::Legacy(TxLegacy {
|
||||
chain_id: Some(4u64),
|
||||
nonce: 2,
|
||||
gas_price: 1000000000,
|
||||
@@ -881,7 +919,7 @@ mod tests {
|
||||
),
|
||||
value: 1000000000000000,
|
||||
input: Bytes::default(),
|
||||
};
|
||||
});
|
||||
let expected_signature = Signature {
|
||||
odd_y_parity: false,
|
||||
r: U256::from_str("eb96ca19e8a77102767a41fc85a36afd5c61ccb09911cec5d3e86e193d9c5ae")
|
||||
@@ -899,7 +937,7 @@ mod tests {
|
||||
);
|
||||
|
||||
let bytes_second = &mut &hex::decode("f86b01843b9aca00830186a094d3e8763675e4c425df46cc3b5c0f6cbdac3960468702769bb01b2a00802ba0e24d8bd32ad906d6f8b8d7741e08d1959df021698b19ee232feba15361587d0aa05406ad177223213df262cb66ccbb2f46bfdccfdfbbb5ffdda9e2c02d977631da").unwrap()[..];
|
||||
let expected_request = Transaction::Legacy {
|
||||
let expected_request = Transaction::Legacy(TxLegacy {
|
||||
chain_id: Some(4),
|
||||
nonce: 1u64,
|
||||
gas_price: 1000000000,
|
||||
@@ -909,7 +947,7 @@ mod tests {
|
||||
)),
|
||||
value: 693361000000000u64.into(),
|
||||
input: Default::default(),
|
||||
};
|
||||
});
|
||||
let expected_signature = Signature {
|
||||
odd_y_parity: false,
|
||||
r: U256::from_str("e24d8bd32ad906d6f8b8d7741e08d1959df021698b19ee232feba15361587d0a")
|
||||
@@ -923,7 +961,7 @@ mod tests {
|
||||
assert_eq!(expected, TransactionSigned::decode(bytes_second).unwrap());
|
||||
|
||||
let bytes_third = &mut &hex::decode("f86b0384773594008398968094d3e8763675e4c425df46cc3b5c0f6cbdac39604687038d7ea4c68000802ba0ce6834447c0a4193c40382e6c57ae33b241379c5418caac9cdc18d786fd12071a03ca3ae86580e94550d7c071e3a02eadb5a77830947c9225165cf9100901bee88").unwrap()[..];
|
||||
let expected_request = Transaction::Legacy {
|
||||
let expected_request = Transaction::Legacy(TxLegacy {
|
||||
chain_id: Some(4),
|
||||
nonce: 3,
|
||||
gas_price: 2000000000,
|
||||
@@ -933,7 +971,7 @@ mod tests {
|
||||
)),
|
||||
value: 1000000000000000u64.into(),
|
||||
input: Bytes::default(),
|
||||
};
|
||||
});
|
||||
|
||||
let expected_signature = Signature {
|
||||
odd_y_parity: false,
|
||||
@@ -948,7 +986,7 @@ mod tests {
|
||||
assert_eq!(expected, TransactionSigned::decode(bytes_third).unwrap());
|
||||
|
||||
let bytes_fourth = &mut &hex::decode("b87502f872041a8459682f008459682f0d8252089461815774383099e24810ab832a5b2a5425c154d58829a2241af62c000080c001a059e6b67f48fb32e7e570dfb11e042b5ad2e55e3ce3ce9cd989c7e06e07feeafda0016b83f4f980694ed2eee4d10667242b1f40dc406901b34125b008d334d47469").unwrap()[..];
|
||||
let expected = Transaction::Eip1559 {
|
||||
let expected = Transaction::Eip1559(TxEip1559 {
|
||||
chain_id: 4,
|
||||
nonce: 26,
|
||||
max_priority_fee_per_gas: 1500000000,
|
||||
@@ -960,7 +998,7 @@ mod tests {
|
||||
value: 3000000000000000000u64.into(),
|
||||
input: Default::default(),
|
||||
access_list: Default::default(),
|
||||
};
|
||||
});
|
||||
|
||||
let expected_signature = Signature {
|
||||
odd_y_parity: true,
|
||||
@@ -975,7 +1013,7 @@ mod tests {
|
||||
assert_eq!(expected, TransactionSigned::decode(bytes_fourth).unwrap());
|
||||
|
||||
let bytes_fifth = &mut &hex::decode("f8650f84832156008287fb94cf7f9e66af820a19257a2108375b180b0ec491678204d2802ca035b7bfeb9ad9ece2cbafaaf8e202e706b4cfaeb233f46198f00b44d4a566a981a0612638fb29427ca33b9a3be2a0a561beecfe0269655be160d35e72d366a6a860").unwrap()[..];
|
||||
let expected = Transaction::Legacy {
|
||||
let expected = Transaction::Legacy(TxLegacy {
|
||||
chain_id: Some(4),
|
||||
nonce: 15,
|
||||
gas_price: 2200000000,
|
||||
@@ -985,7 +1023,7 @@ mod tests {
|
||||
)),
|
||||
value: 1234u64.into(),
|
||||
input: Bytes::default(),
|
||||
};
|
||||
});
|
||||
let signature = Signature {
|
||||
odd_y_parity: true,
|
||||
r: U256::from_str("35b7bfeb9ad9ece2cbafaaf8e202e706b4cfaeb233f46198f00b44d4a566a981")
|
||||
@@ -1022,7 +1060,7 @@ mod tests {
|
||||
let hash: H256 =
|
||||
hex!("bb3a336e3f823ec18197f1e13ee875700f08f03e2cab75f0d0b118dabb44cba0").into();
|
||||
|
||||
let tx = Transaction::Legacy {
|
||||
let tx = Transaction::Legacy(TxLegacy {
|
||||
chain_id: Some(1),
|
||||
nonce: 0x18,
|
||||
gas_price: 0xfa56ea00,
|
||||
@@ -1030,7 +1068,7 @@ mod tests {
|
||||
to: TransactionKind::Call( hex!("06012c8cf97bead5deae237070f9587f8e7a266d").into()),
|
||||
value: 0x1c6bf526340000u64.into(),
|
||||
input: hex!("f7d8c88300000000000000000000000000000000000000000000000000000000000cee6100000000000000000000000000000000000000000000000000000000000ac3e1").into(),
|
||||
};
|
||||
});
|
||||
|
||||
let sig = Signature {
|
||||
r: hex!("2a378831cf81d99a3f06a18ae1b6ca366817ab4d88a70053c41d7a8f0368e031").into(),
|
||||
@@ -1051,7 +1089,7 @@ mod tests {
|
||||
let hash: H256 =
|
||||
hex!("0ec0b6a2df4d87424e5f6ad2a654e27aaeb7dac20ae9e8385cc09087ad532ee0").into();
|
||||
|
||||
let tx = Transaction::Eip1559 {
|
||||
let tx = Transaction::Eip1559( TxEip1559 {
|
||||
chain_id: 1,
|
||||
nonce: 0x42,
|
||||
gas_limit: 44386,
|
||||
@@ -1061,7 +1099,7 @@ mod tests {
|
||||
max_fee_per_gas: 0x4a817c800,
|
||||
max_priority_fee_per_gas: 0x3b9aca00,
|
||||
access_list: AccessList::default(),
|
||||
};
|
||||
});
|
||||
|
||||
let sig = Signature {
|
||||
r: hex!("840cfc572845f5786e702984c2a582528cad4b49b2a10b9db1be7fca90058565").into(),
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
use crate::{transaction::util::secp256k1, Address, H256, U256};
|
||||
use reth_codecs::main_codec;
|
||||
use bytes::Buf;
|
||||
use modular_bitfield::prelude::*;
|
||||
use reth_codecs::{main_codec, Compact};
|
||||
use reth_rlp::{Decodable, DecodeError, Encodable};
|
||||
|
||||
/// r, s: Values corresponding to the signature of the
|
||||
/// transaction and used to determine the sender of
|
||||
/// the transaction; formally Tr and Ts. This is expanded in Appendix F of yellow paper.
|
||||
#[main_codec]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
|
||||
pub struct Signature {
|
||||
/// The R field of the signature; the point on the curve.
|
||||
pub r: U256,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use reth_codecs::{main_codec, Compact};
|
||||
use reth_codecs::Compact;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Transaction Type
|
||||
#[main_codec]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Default)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Default, Serialize, Deserialize)]
|
||||
pub enum TxType {
|
||||
/// Legacy transaction pre EIP-2929
|
||||
#[default]
|
||||
|
||||
@@ -66,6 +66,12 @@ pub enum DatabaseIntegrityError {
|
||||
/// The block number key
|
||||
number: BlockNumber,
|
||||
},
|
||||
/// The total difficulty from the block header is missing.
|
||||
#[error("Total difficulty not found for block #{number}")]
|
||||
TotalDifficulty {
|
||||
/// The block number key
|
||||
number: BlockNumber,
|
||||
},
|
||||
}
|
||||
|
||||
/// A pipeline execution error.
|
||||
|
||||
@@ -7,7 +7,7 @@ use reth_interfaces::{
|
||||
db::{models::blocks::BlockNumHash, tables, Database, DbCursorRO, DbCursorRW, DbTx, DbTxMut},
|
||||
p2p::headers::{client::HeadersClient, downloader::HeaderDownloader, error::DownloadError},
|
||||
};
|
||||
use reth_primitives::{rpc::BigEndianHash, BlockNumber, SealedHeader, H256, U256};
|
||||
use reth_primitives::{BlockNumber, SealedHeader, H256, U256};
|
||||
use std::{fmt::Debug, sync::Arc};
|
||||
use tracing::*;
|
||||
|
||||
@@ -119,8 +119,10 @@ impl<D: HeaderDownloader, C: Consensus, H: HeadersClient> HeaderStage<D, C, H> {
|
||||
height: BlockNumber,
|
||||
) -> Result<(), StageError> {
|
||||
let block_key = db.get_block_numhash(height)?;
|
||||
let td: Vec<u8> = db.get::<tables::HeaderTD>(block_key)?.unwrap(); // TODO:
|
||||
self.client.update_status(height, block_key.hash(), H256::from_slice(&td).into_uint());
|
||||
let td: U256 = *db
|
||||
.get::<tables::HeaderTD>(block_key)?
|
||||
.ok_or(DatabaseIntegrityError::TotalDifficulty { number: height })?;
|
||||
self.client.update_status(height, block_key.hash(), td);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -144,7 +146,7 @@ impl<D: HeaderDownloader, C: Consensus, H: HeadersClient> HeaderStage<D, C, H> {
|
||||
let mut cursor_header = db.cursor_mut::<tables::Headers>()?;
|
||||
let mut cursor_canonical = db.cursor_mut::<tables::CanonicalHeaders>()?;
|
||||
let mut cursor_td = db.cursor_mut::<tables::HeaderTD>()?;
|
||||
let mut td = U256::from_big_endian(&cursor_td.last()?.map(|(_, v)| v).unwrap());
|
||||
let mut td: U256 = cursor_td.last()?.map(|(_, v)| v).unwrap().into();
|
||||
|
||||
let mut latest = None;
|
||||
// Since the headers were returned in descending order,
|
||||
@@ -165,7 +167,7 @@ impl<D: HeaderDownloader, C: Consensus, H: HeadersClient> HeaderStage<D, C, H> {
|
||||
db.put::<tables::HeaderNumbers>(block_hash, header.number)?;
|
||||
cursor_header.append(key, header)?;
|
||||
cursor_canonical.append(key.number(), key.hash())?;
|
||||
cursor_td.append(key, H256::from_uint(&td).as_bytes().to_vec())?;
|
||||
cursor_td.append(key, td.into())?;
|
||||
}
|
||||
|
||||
Ok(latest)
|
||||
@@ -380,12 +382,10 @@ mod tests {
|
||||
let parent_td = tx.get::<tables::HeaderTD>(
|
||||
(header.number - 1, header.parent_hash).into(),
|
||||
)?;
|
||||
let td = tx.get::<tables::HeaderTD>(key)?.unwrap();
|
||||
let td: U256 = *tx.get::<tables::HeaderTD>(key)?.unwrap();
|
||||
assert_eq!(
|
||||
parent_td.map(
|
||||
|td| U256::from_big_endian(&td) + header.difficulty
|
||||
),
|
||||
Some(U256::from_big_endian(&td))
|
||||
parent_td.map(|td| *td + header.difficulty),
|
||||
Some(td)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ use reth_db::{
|
||||
use reth_interfaces::db::{
|
||||
self, models::BlockNumHash, tables, DbCursorRO, DbCursorRW, DbTx, DbTxMut, Table,
|
||||
};
|
||||
use reth_primitives::{BigEndianHash, BlockNumber, SealedHeader, H256, U256};
|
||||
use reth_primitives::{BlockNumber, SealedHeader, U256};
|
||||
use std::{borrow::Borrow, sync::Arc};
|
||||
|
||||
use crate::db::StageDB;
|
||||
@@ -167,9 +167,8 @@ impl TestStageDB {
|
||||
self.commit(|tx| {
|
||||
let headers = headers.collect::<Vec<_>>();
|
||||
|
||||
let mut td = U256::from_big_endian(
|
||||
&tx.cursor::<tables::HeaderTD>()?.last()?.map(|(_, v)| v).unwrap_or_default(),
|
||||
);
|
||||
let mut td: U256 =
|
||||
tx.cursor::<tables::HeaderTD>()?.last()?.map(|(_, v)| v).unwrap_or_default().into();
|
||||
|
||||
for header in headers {
|
||||
let key: BlockNumHash = (header.number, header.hash()).into();
|
||||
@@ -179,7 +178,7 @@ impl TestStageDB {
|
||||
tx.put::<tables::Headers>(key, header.clone().unseal())?;
|
||||
|
||||
td += header.difficulty;
|
||||
tx.put::<tables::HeaderTD>(key, H256::from_uint(&td).as_bytes().to_vec())?;
|
||||
tx.put::<tables::HeaderTD>(key, td.into())?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -12,8 +12,8 @@ use rand::{
|
||||
prelude::Distribution,
|
||||
};
|
||||
use reth_primitives::{
|
||||
Address, FromRecoveredTransaction, Transaction, TransactionSignedEcRecovered, TxHash, H256,
|
||||
U256,
|
||||
Address, FromRecoveredTransaction, Transaction, TransactionSignedEcRecovered, TxEip1559,
|
||||
TxHash, TxLegacy, H256, U256,
|
||||
};
|
||||
use std::{ops::Range, sync::Arc, time::Instant};
|
||||
|
||||
@@ -342,17 +342,23 @@ impl FromRecoveredTransaction for MockTransaction {
|
||||
let transaction = tx.into_signed();
|
||||
let hash = transaction.hash;
|
||||
match transaction.transaction {
|
||||
Transaction::Legacy { chain_id, nonce, gas_price, gas_limit, to, value, input } => {
|
||||
MockTransaction::Legacy {
|
||||
hash,
|
||||
sender,
|
||||
nonce,
|
||||
gas_price: gas_price.into(),
|
||||
gas_limit,
|
||||
value: value.into(),
|
||||
}
|
||||
}
|
||||
Transaction::Eip1559 {
|
||||
Transaction::Legacy(TxLegacy {
|
||||
chain_id,
|
||||
nonce,
|
||||
gas_price,
|
||||
gas_limit,
|
||||
to,
|
||||
value,
|
||||
input,
|
||||
}) => MockTransaction::Legacy {
|
||||
hash,
|
||||
sender,
|
||||
nonce,
|
||||
gas_price: gas_price.into(),
|
||||
gas_limit,
|
||||
value: value.into(),
|
||||
},
|
||||
Transaction::Eip1559(TxEip1559 {
|
||||
chain_id,
|
||||
nonce,
|
||||
gas_limit,
|
||||
@@ -362,7 +368,7 @@ impl FromRecoveredTransaction for MockTransaction {
|
||||
value,
|
||||
input,
|
||||
access_list,
|
||||
} => MockTransaction::Eip1559 {
|
||||
}) => MockTransaction::Eip1559 {
|
||||
hash,
|
||||
sender,
|
||||
nonce,
|
||||
|
||||
Reference in New Issue
Block a user