mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat(db): codec encoding/decoding (#51)
* wip * add table macro * add simple put get test with Address * add Env.view and Env.update * docs * slightly change the test * add initial table initialization and placeholders * lint & some * replace String with str * add error.rs * add docs to encode * add docs * clamp * add source on libmdbx_max_page_size * add BlockNumer_BlockHash * add scale * set header filed to bytes Bytes * remove unwrap * restrict scale to chosen types * into bytes * add postcard * changed to BlockNumHash * add proc_macro_attribute codecs * fix feature flagging * set a version for postcard * cleanup * seal ScaleOnly * remove unnecessary dependencies * properly encode/decode blocknumhash * change Account codec to scale * add missing feature to scale * add codec to a couple more types * silence clippy * add docs about table encoding * move and add reth-codecs * clippy * make proc-macro visible * add README.md
This commit is contained in:
13
crates/codecs/Cargo.toml
Normal file
13
crates/codecs/Cargo.toml
Normal file
@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "reth-codecs"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[features]
|
||||
default = ["scale"]
|
||||
scale = ["codecs-derive/scale"]
|
||||
postcard = ["codecs-derive/postcard"]
|
||||
no_codec = ["codecs-derive/no_codec"]
|
||||
|
||||
[dependencies]
|
||||
codecs-derive = { version = "0.1.0", path = "./derive", default-features = false }
|
||||
22
crates/codecs/README.md
Normal file
22
crates/codecs/README.md
Normal file
@ -0,0 +1,22 @@
|
||||
# codecs
|
||||
|
||||
This crate allows to easily configure different codecs for different purposes (benchmarks, user configuration) with minimal changes. Having them to be configurable through annotations allows us to contain their implementations/leakage to isolated portions of the project.
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
[Header struct](../primitives/src/header.rs)
|
||||
|
||||
[DB usage](../db/src/kv/codecs/scale.rs)
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
Feature defines what is the main codec used by `#[main_codec]`. However it is still possible to define them directly: `#[use_scale]`, `#[use_postcat]`, `#[no_codec]`.
|
||||
|
||||
```rust
|
||||
default = ["scale"]
|
||||
scale = ["codecs-derive/scale"]
|
||||
postcard = ["codecs-derive/postcard"]
|
||||
no_codec = ["codecs-derive/no_codec"]
|
||||
```
|
||||
22
crates/codecs/derive/Cargo.toml
Normal file
22
crates/codecs/derive/Cargo.toml
Normal file
@ -0,0 +1,22 @@
|
||||
[package]
|
||||
name = "codecs-derive"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "1.0"
|
||||
quote = "1.0"
|
||||
syn = { version = "1.0", features = ["full"] }
|
||||
|
||||
# codecs
|
||||
serde = { version = "1.0.*", default-features = false }
|
||||
parity-scale-codec = { version = "3.2.1", features = ["derive", "bytes"] }
|
||||
|
||||
[features]
|
||||
default = ["scale"]
|
||||
scale = []
|
||||
postcard = []
|
||||
no_codec = []
|
||||
66
crates/codecs/derive/src/lib.rs
Normal file
66
crates/codecs/derive/src/lib.rs
Normal file
@ -0,0 +1,66 @@
|
||||
use proc_macro::{self, TokenStream};
|
||||
use quote::quote;
|
||||
use syn::{parse_macro_input, DeriveInput};
|
||||
|
||||
#[proc_macro_attribute]
|
||||
#[rustfmt::skip]
|
||||
#[allow(unreachable_code)]
|
||||
pub fn main_codec(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
#[cfg(feature = "scale")]
|
||||
return use_scale(args, input);
|
||||
|
||||
#[cfg(feature = "postcard")]
|
||||
return use_postcard(args, input);
|
||||
|
||||
#[cfg(feature = "no_codec")]
|
||||
return no_codec(args, input);
|
||||
|
||||
// no features
|
||||
no_codec(args, input)
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn use_scale(_args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let mut ast = parse_macro_input!(input as DeriveInput);
|
||||
let compactable_types = ["u8", "u16", "u32", "i32", "i64", "u64", "f32", "f64"];
|
||||
|
||||
if let syn::Data::Struct(ref mut data) = &mut ast.data {
|
||||
if let syn::Fields::Named(fields) = &mut data.fields {
|
||||
for field in fields.named.iter_mut() {
|
||||
if let syn::Type::Path(ref path) = field.ty {
|
||||
if !path.path.segments.is_empty() {
|
||||
let _type = format!("{}", path.path.segments[0].ident);
|
||||
if compactable_types.contains(&_type.as_str()) {
|
||||
field.attrs.push(syn::parse_quote! {
|
||||
#[codec(compact)]
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
quote! {
|
||||
#[derive(parity_scale_codec::Encode, parity_scale_codec::Decode)]
|
||||
#ast
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn use_postcard(_args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let ast = parse_macro_input!(input as DeriveInput);
|
||||
|
||||
quote! {
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#ast
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn no_codec(_args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let ast = parse_macro_input!(input as DeriveInput);
|
||||
quote! { #ast }.into()
|
||||
}
|
||||
1
crates/codecs/src/lib.rs
Normal file
1
crates/codecs/src/lib.rs
Normal file
@ -0,0 +1 @@
|
||||
pub use codecs_derive::*;
|
||||
@ -11,6 +11,12 @@ description = "Staged syncing primitives used in reth."
|
||||
# reth
|
||||
reth-primitives = { path = "../primitives" }
|
||||
|
||||
# codecs
|
||||
serde = { version = "1.0.*", default-features = false }
|
||||
postcard = { version = "1.0.2", features = ["heapless"] }
|
||||
heapless = "0.7.16"
|
||||
parity-scale-codec = { version = "3.2.1", features = ["bytes"] }
|
||||
|
||||
# misc
|
||||
bytes = "1.2.1"
|
||||
libmdbx = "0.1.8"
|
||||
|
||||
2
crates/db/src/kv/codecs/mod.rs
Normal file
2
crates/db/src/kv/codecs/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
mod postcard;
|
||||
mod scale;
|
||||
35
crates/db/src/kv/codecs/postcard.rs
Normal file
35
crates/db/src/kv/codecs/postcard.rs
Normal file
@ -0,0 +1,35 @@
|
||||
#![allow(unused)]
|
||||
|
||||
use crate::kv::{Decode, Encode, KVError};
|
||||
use heapless::Vec;
|
||||
use postcard::{from_bytes, to_vec};
|
||||
use reth_primitives::Account;
|
||||
|
||||
// Just add `Serialize` and `Deserialize`, and set impl_heapless_postcard!(T, MaxSize(T))
|
||||
//
|
||||
//
|
||||
// use serde::{Deserialize, Serialize};
|
||||
//
|
||||
// #[derive(Serialize, Deserialize )]
|
||||
// pub struct T {
|
||||
// }
|
||||
//
|
||||
// impl_heapless_postcard!(T, MaxSize(T))
|
||||
|
||||
macro_rules! impl_heapless_postcard {
|
||||
($name:tt, $static_size:tt) => {
|
||||
impl Encode for $name {
|
||||
type Encoded = Vec<u8, $static_size>;
|
||||
|
||||
fn encode(self) -> Self::Encoded {
|
||||
to_vec(&self).expect("Failed to encode")
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for $name {
|
||||
fn decode<B: Into<bytes::Bytes>>(value: B) -> Result<Self, KVError> {
|
||||
from_bytes(&value.into()).map_err(|_| KVError::InvalidValue)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
43
crates/db/src/kv/codecs/scale.rs
Normal file
43
crates/db/src/kv/codecs/scale.rs
Normal file
@ -0,0 +1,43 @@
|
||||
use crate::kv::{Decode, Encode, KVError};
|
||||
use parity_scale_codec::decode_from_bytes;
|
||||
use reth_primitives::*;
|
||||
|
||||
mod sealed {
|
||||
pub trait Sealed {}
|
||||
}
|
||||
/// Marker trait type to restrict the TableEncode and TableDecode with scale to chosen types.
|
||||
pub trait ScaleOnly: sealed::Sealed {}
|
||||
|
||||
impl<T> Encode for T
|
||||
where
|
||||
T: ScaleOnly + parity_scale_codec::Encode + Sync + Send + std::fmt::Debug,
|
||||
{
|
||||
type Encoded = Vec<u8>;
|
||||
|
||||
fn encode(self) -> Self::Encoded {
|
||||
parity_scale_codec::Encode::encode(&self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Decode for T
|
||||
where
|
||||
T: ScaleOnly + parity_scale_codec::Decode + Sync + Send + std::fmt::Debug,
|
||||
{
|
||||
fn decode<B: Into<bytes::Bytes>>(value: B) -> Result<T, KVError> {
|
||||
decode_from_bytes(value.into()).map_err(|_| KVError::InvalidValue)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_scale {
|
||||
($($name:tt),+) => {
|
||||
$(
|
||||
impl ScaleOnly for $name {}
|
||||
impl sealed::Sealed for $name {}
|
||||
)+
|
||||
};
|
||||
}
|
||||
|
||||
impl_scale!(u16, H256, U256, H160, u8, u64, Header, Account, Log, Receipt, TxType);
|
||||
|
||||
impl ScaleOnly for Vec<u8> {}
|
||||
impl sealed::Sealed for Vec<u8> {}
|
||||
@ -31,6 +31,6 @@ pub enum KVError {
|
||||
#[error("{0:?}")]
|
||||
InitTransaction(Error),
|
||||
/// Failed to decode or encode a key or value coming from a table..
|
||||
#[error("{0:?}")]
|
||||
InvalidValue(Option<String>),
|
||||
#[error("Error decoding value.")]
|
||||
InvalidValue,
|
||||
}
|
||||
|
||||
@ -15,12 +15,17 @@ use tables::TABLES;
|
||||
|
||||
pub mod cursor;
|
||||
|
||||
pub mod models;
|
||||
pub use models::*;
|
||||
|
||||
pub mod tx;
|
||||
use tx::Tx;
|
||||
|
||||
mod error;
|
||||
pub use error::KVError;
|
||||
|
||||
mod codecs;
|
||||
|
||||
/// Environment used when opening a MDBX environment. RO/RW.
|
||||
#[derive(Debug)]
|
||||
pub enum EnvKind {
|
||||
@ -164,9 +169,12 @@ pub mod test_utils {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{tables::PlainState, test_utils, Env, EnvKind};
|
||||
use super::{
|
||||
tables::{Headers, PlainState},
|
||||
test_utils, Env, EnvKind,
|
||||
};
|
||||
use libmdbx::{NoWriteMap, WriteMap};
|
||||
use reth_primitives::Address;
|
||||
use reth_primitives::{Account, Address, Header, H256, U256};
|
||||
use std::str::FromStr;
|
||||
use tempfile::TempDir;
|
||||
|
||||
@ -187,18 +195,17 @@ mod tests {
|
||||
fn db_manual_put_get() {
|
||||
let env = test_utils::create_test_db::<NoWriteMap>(EnvKind::RW);
|
||||
|
||||
let value = vec![1, 3, 3, 7];
|
||||
let key = Address::from_str("0xa2c122be93b0074270ebee7f6b7292c7deb45047")
|
||||
.expect(ERROR_ETH_ADDRESS);
|
||||
let value = Header::default();
|
||||
let key = (1u64, H256::zero());
|
||||
|
||||
// PUT
|
||||
let tx = env.begin_mut_tx().expect(ERROR_INIT_TX);
|
||||
tx.put::<PlainState>(key, value.clone()).expect(ERROR_PUT);
|
||||
tx.put::<Headers>(key.into(), value.clone()).expect(ERROR_PUT);
|
||||
tx.commit().expect(ERROR_COMMIT);
|
||||
|
||||
// GET
|
||||
let tx = env.begin_tx().expect(ERROR_INIT_TX);
|
||||
let result = tx.get::<PlainState>(key).expect(ERROR_GET);
|
||||
let result = tx.get::<Headers>(key.into()).expect(ERROR_GET);
|
||||
assert!(result.expect(ERROR_RETURN_VALUE) == value);
|
||||
tx.commit().expect(ERROR_COMMIT);
|
||||
}
|
||||
@ -207,7 +214,11 @@ mod tests {
|
||||
fn db_closure_put_get() {
|
||||
let path = TempDir::new().expect(test_utils::ERROR_TEMPDIR).into_path();
|
||||
|
||||
let value = vec![1, 3, 3, 7];
|
||||
let value = Account {
|
||||
nonce: 18446744073709551615,
|
||||
bytecode_hash: H256::random(),
|
||||
balance: U256::max_value(),
|
||||
};
|
||||
let key = Address::from_str("0xa2c122be93b0074270ebee7f6b7292c7deb45047")
|
||||
.expect(ERROR_ETH_ADDRESS);
|
||||
|
||||
@ -216,7 +227,7 @@ mod tests {
|
||||
|
||||
// PUT
|
||||
let result = env.update(|tx| {
|
||||
tx.put::<PlainState>(key, value.clone()).expect(ERROR_PUT);
|
||||
tx.put::<PlainState>(key, value).expect(ERROR_PUT);
|
||||
200
|
||||
});
|
||||
assert!(result.expect(ERROR_RETURN_VALUE) == 200);
|
||||
|
||||
64
crates/db/src/kv/models/blocks.rs
Normal file
64
crates/db/src/kv/models/blocks.rs
Normal file
@ -0,0 +1,64 @@
|
||||
//! Block related models and types.
|
||||
|
||||
use crate::kv::{
|
||||
table::{Decode, Encode},
|
||||
KVError,
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use reth_primitives::{BlockHash, BlockNumber, H256};
|
||||
|
||||
/// Total chain number of transactions. Key for [`CumulativeTxCount`].
|
||||
pub type NumTransactions = u64;
|
||||
|
||||
/// Number of transactions in the block. Value for [`BlockBodies`].
|
||||
pub type NumTxesInBlock = u16;
|
||||
|
||||
/// Hash of the block header. Value for [`CanonicalHeaders`]
|
||||
pub type HeaderHash = H256;
|
||||
|
||||
/// BlockNumber concatenated with BlockHash. Used as a key for multiple tables. Having the first
|
||||
/// element as BlockNumber, helps out with querying/sorting.
|
||||
///
|
||||
/// Since it's used as a key, the `BlockNumber` is not compressed when encoding it.
|
||||
#[derive(Debug)]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct BlockNumHash((BlockNumber, BlockHash));
|
||||
|
||||
impl BlockNumHash {
|
||||
/// Consumes `Self` and returns [`BlockNumber`], [`BlockHash`]
|
||||
pub fn take(self) -> (BlockNumber, BlockHash) {
|
||||
(self.0 .0, self.0 .1)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(u64, H256)> for BlockNumHash {
|
||||
fn from(tpl: (u64, H256)) -> Self {
|
||||
BlockNumHash(tpl)
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for BlockNumHash {
|
||||
type Encoded = [u8; 40];
|
||||
|
||||
fn encode(self) -> Self::Encoded {
|
||||
let number = self.0 .0;
|
||||
let hash = self.0 .1;
|
||||
|
||||
let mut rnum = [0; 40];
|
||||
|
||||
rnum[..8].copy_from_slice(&number.to_be_bytes());
|
||||
rnum[8..].copy_from_slice(&hash.encode());
|
||||
rnum
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for BlockNumHash {
|
||||
fn decode<B: Into<Bytes>>(value: B) -> Result<Self, KVError> {
|
||||
let value: bytes::Bytes = value.into();
|
||||
|
||||
let num = u64::from_be_bytes(value.as_ref().try_into().map_err(|_| KVError::InvalidValue)?);
|
||||
let hash = H256::decode(value.slice(8..))?;
|
||||
|
||||
Ok(BlockNumHash((num, hash)))
|
||||
}
|
||||
}
|
||||
3
crates/db/src/kv/models/mod.rs
Normal file
3
crates/db/src/kv/models/mod.rs
Normal file
@ -0,0 +1,3 @@
|
||||
//! Implements data structures specific to the database
|
||||
|
||||
pub mod blocks;
|
||||
@ -2,9 +2,10 @@
|
||||
|
||||
use super::KVError;
|
||||
use bytes::Bytes;
|
||||
use reth_primitives::{Address, U256};
|
||||
use std::fmt::Debug;
|
||||
|
||||
use std::{
|
||||
fmt::Debug,
|
||||
marker::{Send, Sync},
|
||||
};
|
||||
/// Trait that will transform the data to be saved in the DB.
|
||||
pub trait Encode: Send + Sync + Sized + Debug {
|
||||
/// Encoded type.
|
||||
@ -17,7 +18,7 @@ pub trait Encode: Send + Sync + Sized + Debug {
|
||||
/// Trait that will transform the data to be read from the DB.
|
||||
pub trait Decode: Send + Sync + Sized + Debug {
|
||||
/// Decodes data coming from the database.
|
||||
fn decode(value: &[u8]) -> Result<Self, KVError>;
|
||||
fn decode<B: Into<Bytes>>(value: B) -> Result<Self, KVError>;
|
||||
}
|
||||
|
||||
/// Generic trait that enforces the database value to implement [`Encode`] and [`Decode`].
|
||||
@ -26,10 +27,19 @@ pub trait Object: Encode + Decode {}
|
||||
impl<T> Object for T where T: Encode + Decode {}
|
||||
|
||||
/// Generic trait that a database table should follow.
|
||||
///
|
||||
/// [`Table::Key`], [`Table::Value`], [`Table::SeekKey`] types should implement [`Encode`] and
|
||||
/// [`Decode`] when appropriate. These traits define how the data is stored and read from the
|
||||
/// database.
|
||||
///
|
||||
/// It allows for the use of codecs. See [`crate::kv::models::blocks::BlockNumHash`] for a custom
|
||||
/// implementation, and [`crate::kv::codecs::scale`] for the use of an external codec.
|
||||
pub trait Table: Send + Sync + Debug + 'static {
|
||||
/// Return table name as it is present inside the MDBX.
|
||||
const NAME: &'static str;
|
||||
/// Key element of `Table`.
|
||||
///
|
||||
/// Sorting should be taken into account when encoding this.
|
||||
type Key: Encode;
|
||||
/// Value element of `Table`.
|
||||
type Value: Object;
|
||||
@ -41,93 +51,7 @@ pub trait Table: Send + Sync + Debug + 'static {
|
||||
/// for more check: https://libmdbx.dqdkfa.ru/usage.html#autotoc_md48
|
||||
pub trait DupSort: Table {
|
||||
/// Subkey type. For more check https://libmdbx.dqdkfa.ru/usage.html#autotoc_md48
|
||||
///
|
||||
/// Sorting should be taken into account when encoding this.
|
||||
type SubKey: Object;
|
||||
}
|
||||
|
||||
impl Encode for Vec<u8> {
|
||||
type Encoded = Self;
|
||||
|
||||
fn encode(self) -> Self::Encoded {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for Vec<u8> {
|
||||
fn decode(value: &[u8]) -> Result<Self, KVError> {
|
||||
Ok(value.to_vec())
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for Bytes {
|
||||
type Encoded = Self;
|
||||
|
||||
fn encode(self) -> Self::Encoded {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for Bytes {
|
||||
fn decode(value: &[u8]) -> Result<Self, KVError> {
|
||||
Ok(value.to_vec().into())
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for Address {
|
||||
type Encoded = [u8; 20];
|
||||
|
||||
fn encode(self) -> Self::Encoded {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for Address {
|
||||
fn decode(value: &[u8]) -> Result<Self, KVError> {
|
||||
Ok(Address::from_slice(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for u16 {
|
||||
type Encoded = [u8; 2];
|
||||
|
||||
fn encode(self) -> Self::Encoded {
|
||||
self.to_be_bytes()
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for u16 {
|
||||
fn decode(value: &[u8]) -> Result<Self, KVError> {
|
||||
unsafe { Ok(u16::from_be_bytes(*(value.as_ptr() as *const [_; 2]))) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for u64 {
|
||||
type Encoded = [u8; 8];
|
||||
|
||||
fn encode(self) -> Self::Encoded {
|
||||
self.to_be_bytes()
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for u64 {
|
||||
fn decode(value: &[u8]) -> Result<Self, KVError> {
|
||||
unsafe { Ok(u64::from_be_bytes(*(value.as_ptr() as *const [_; 8]))) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for U256 {
|
||||
type Encoded = [u8; 32];
|
||||
|
||||
fn encode(self) -> Self::Encoded {
|
||||
let mut result = [0; 32];
|
||||
self.to_big_endian(&mut result);
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for U256 {
|
||||
fn decode(value: &[u8]) -> Result<Self, KVError> {
|
||||
let mut result = [0; 32];
|
||||
result.copy_from_slice(value);
|
||||
Ok(Self::from_big_endian(&result))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
//! Declaration of all MDBX tables.
|
||||
|
||||
use crate::utils::TableType;
|
||||
use reth_primitives::{Address, BlockNumber, U256};
|
||||
use crate::{
|
||||
kv::blocks::{BlockNumHash, HeaderHash, NumTransactions, NumTxesInBlock},
|
||||
utils::TableType,
|
||||
};
|
||||
use reth_primitives::{Account, Address, BlockNumber, Header, Receipt};
|
||||
|
||||
/// Default tables that should be present inside database.
|
||||
pub const TABLES: [(TableType, &str); 18] = [
|
||||
@ -63,28 +65,28 @@ macro_rules! table {
|
||||
// TABLE DEFINITIONS
|
||||
//
|
||||
|
||||
table!(CanonicalHeaders => BNum => HeaderHash);
|
||||
table!(HeaderTD => BNum_BHash => RlpTotalDifficulty);
|
||||
table!(HeaderNumbers => BNum_BHash => BNum);
|
||||
table!(Headers => BNum_BHash => RlpHeader);
|
||||
table!(CanonicalHeaders => BlockNumber => HeaderHash);
|
||||
table!(HeaderTD => BlockNumHash => RlpTotalDifficulty);
|
||||
table!(HeaderNumbers => BlockNumHash => BlockNumber);
|
||||
table!(Headers => BlockNumHash => Header);
|
||||
|
||||
table!(BlockBodies => BNum_BHash => NumTxesInBlock);
|
||||
table!(CumulativeTxCount => BNum_BHash => u64); // TODO U256?
|
||||
table!(BlockBodies => BlockNumHash => NumTxesInBlock);
|
||||
table!(CumulativeTxCount => BlockNumHash => NumTransactions); // TODO U256?
|
||||
|
||||
table!(NonCanonicalTransactions => BNum_BHash_TxId => RlpTxBody);
|
||||
table!(Transactions => TxId => RlpTxBody); // Canonical only
|
||||
table!(Receipts => TxId => Receipt); // Canonical only
|
||||
table!(Logs => TxId => Receipt); // Canonical only
|
||||
table!(NonCanonicalTransactions => BlockNumHashTxNumber => RlpTxBody);
|
||||
table!(Transactions => TxNumber => RlpTxBody); // Canonical only
|
||||
table!(Receipts => TxNumber => Receipt); // Canonical only
|
||||
table!(Logs => TxNumber => Receipt); // Canonical only
|
||||
|
||||
table!(PlainState => PlainStateKey => Vec<u8>);
|
||||
table!(PlainState => PlainStateKey => Account);
|
||||
|
||||
table!(AccountHistory => Address => TxIdList);
|
||||
table!(StorageHistory => Address_StorageKey => TxIdList);
|
||||
table!(AccountHistory => Address => TxNumberList);
|
||||
table!(StorageHistory => Address_StorageKey => TxNumberList);
|
||||
|
||||
table!(AccountChangeSet => TxId => AccountBeforeTx);
|
||||
table!(StorageChangeSet => TxId => StorageKeyBeforeTx);
|
||||
table!(AccountChangeSet => TxNumber => AccountBeforeTx);
|
||||
table!(StorageChangeSet => TxNumber => StorageKeyBeforeTx);
|
||||
|
||||
table!(TxSenders => TxId => Address); // Is it necessary?
|
||||
table!(TxSenders => TxNumber => Address); // Is it necessary?
|
||||
table!(Config => ConfigKey => ConfigValue);
|
||||
|
||||
table!(SyncStage => StageId => BlockNumber);
|
||||
@ -96,19 +98,12 @@ table!(SyncStage => StageId => BlockNumber);
|
||||
type ConfigKey = Vec<u8>;
|
||||
type ConfigValue = Vec<u8>;
|
||||
#[allow(non_camel_case_types)]
|
||||
type BNum_BHash = Vec<u8>;
|
||||
#[allow(non_camel_case_types)]
|
||||
type BNum_BHash_TxId = Vec<u8>;
|
||||
type RlpHeader = Vec<u8>;
|
||||
type BlockNumHashTxNumber = Vec<u8>;
|
||||
type RlpTotalDifficulty = Vec<u8>;
|
||||
type RlpTxBody = Vec<u8>;
|
||||
type Receipt = Vec<u8>;
|
||||
type NumTxesInBlock = u16; // TODO can it be u16
|
||||
type BNum = u64; // TODO check size
|
||||
type TxId = u64; // TODO check size
|
||||
type HeaderHash = U256;
|
||||
type TxNumber = u64; // TODO check size
|
||||
type PlainStateKey = Address; // TODO new type will have to account for address_incarna_skey as well
|
||||
type TxIdList = Vec<u8>;
|
||||
type TxNumberList = Vec<u8>;
|
||||
#[allow(non_camel_case_types)]
|
||||
type Address_StorageKey = Vec<u8>;
|
||||
type AccountBeforeTx = Vec<u8>;
|
||||
|
||||
@ -4,6 +4,7 @@ use crate::kv::{
|
||||
table::{Decode, Table},
|
||||
KVError,
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use std::borrow::Cow;
|
||||
|
||||
/// Enum for the type of table present in libmdbx.
|
||||
@ -35,7 +36,10 @@ where
|
||||
T: Table,
|
||||
T::Key: Decode,
|
||||
{
|
||||
Ok((Decode::decode(&kv.0)?, Decode::decode(&kv.1)?))
|
||||
Ok((
|
||||
Decode::decode(Bytes::from(kv.0.into_owned()))?,
|
||||
Decode::decode(Bytes::from(kv.1.into_owned()))?,
|
||||
))
|
||||
}
|
||||
|
||||
/// Helper function to decode only a value from a `(key, value)` pair.
|
||||
@ -43,7 +47,7 @@ pub(crate) fn decode_value<'a, T>(kv: (Cow<'a, [u8]>, Cow<'a, [u8]>)) -> Result<
|
||||
where
|
||||
T: Table,
|
||||
{
|
||||
Decode::decode(&kv.1)
|
||||
Decode::decode(Bytes::from(kv.1.into_owned()))
|
||||
}
|
||||
|
||||
/// Helper function to decode a value. It can be a key or subkey.
|
||||
@ -51,5 +55,5 @@ pub(crate) fn decode_one<T>(value: Cow<'_, [u8]>) -> Result<T::Value, KVError>
|
||||
where
|
||||
T: Table,
|
||||
{
|
||||
Decode::decode(&value)
|
||||
Decode::decode(Bytes::from(value.into_owned()))
|
||||
}
|
||||
|
||||
@ -10,9 +10,13 @@ description = "Commonly used types in reth."
|
||||
[dependencies]
|
||||
ethers-core = { git = "https://github.com/gakonst/ethers-rs", default-features = false }
|
||||
bytes = "1.2"
|
||||
|
||||
serde = "1.0"
|
||||
thiserror = "1"
|
||||
|
||||
reth-rlp = { path = "../common/rlp", features = ["derive"]}
|
||||
parity-scale-codec = { version = "3.2.1", features = ["derive", "bytes"] }
|
||||
reth-codecs = { version = "0.1.0", path = "../codecs" }
|
||||
|
||||
#used for forkid
|
||||
crc = "1"
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
use crate::{H256, U256};
|
||||
use reth_codecs::main_codec;
|
||||
|
||||
/// Account saved in database
|
||||
#[main_codec]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub struct Account {
|
||||
/// Nonce.
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
use std::ops::Deref;
|
||||
|
||||
use crate::{BlockNumber, Bytes, H160, H256, U256};
|
||||
use crate::{BlockNumber, H160, H256, U256};
|
||||
use reth_codecs::main_codec;
|
||||
|
||||
/// Block header
|
||||
#[main_codec]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Default)]
|
||||
pub struct Header {
|
||||
/// The Keccak 256-bit hash of the parent
|
||||
@ -43,7 +45,7 @@ pub struct Header {
|
||||
pub timestamp: u64,
|
||||
/// An arbitrary byte array containing data relevant to this block. This must be 32 bytes or
|
||||
/// fewer; formally Hx.
|
||||
pub extra_data: Bytes,
|
||||
pub extra_data: bytes::Bytes,
|
||||
/// A 256-bit hash which, combined with the
|
||||
/// nonce, proves that a sufficient amount of computation has been carried out on this block;
|
||||
/// formally Hm.
|
||||
|
||||
@ -73,7 +73,6 @@ impl<'a> Visitor<'a> for JsonU256Visitor {
|
||||
mod test {
|
||||
use super::JsonU256;
|
||||
use crate::U256;
|
||||
use serde_json;
|
||||
|
||||
#[test]
|
||||
fn jsonu256_deserialize() {
|
||||
|
||||
@ -25,6 +25,8 @@ pub use log::Log;
|
||||
pub use receipt::Receipt;
|
||||
pub use transaction::{AccessList, AccessListItem, Transaction, TransactionSigned, TxType};
|
||||
|
||||
/// Block hash.
|
||||
pub type BlockHash = H256;
|
||||
/// Block Number is height of chain
|
||||
pub type BlockNumber = u64;
|
||||
/// Ethereum address
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
use crate::{Address, Bytes, H256};
|
||||
use crate::{Address, H256};
|
||||
use reth_codecs::main_codec;
|
||||
|
||||
/// Ethereum Log
|
||||
#[main_codec]
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Log {
|
||||
/// Contract that emitted this log.
|
||||
@ -8,5 +10,5 @@ pub struct Log {
|
||||
/// Topics of the log. The number of logs depend on what `LOG` opcode is used.
|
||||
pub topics: Vec<H256>,
|
||||
/// Arbitrary length data.
|
||||
pub data: Bytes,
|
||||
pub data: bytes::Bytes,
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
use crate::{Log, TxType, H256};
|
||||
use reth_codecs::main_codec;
|
||||
|
||||
/// Receipt containing result of transaction execution.
|
||||
#[main_codec]
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Receipt {
|
||||
/// Receipt type.
|
||||
|
||||
@ -1,10 +1,13 @@
|
||||
use reth_codecs::main_codec;
|
||||
|
||||
/// Transaction Type
|
||||
#[main_codec]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum TxType {
|
||||
/// Legacy transaction pre EIP-2929
|
||||
Legacy = 0,
|
||||
Legacy = 0_isize,
|
||||
/// AccessList transaction
|
||||
EIP2930 = 1,
|
||||
EIP2930 = 1_isize,
|
||||
/// Transaction with Priority fee
|
||||
EIP1559 = 2,
|
||||
EIP1559 = 2_isize,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user