From 19a618e3a49449eb14acdb9bc08e2013cdeba063 Mon Sep 17 00:00:00 2001 From: rakita Date: Sun, 25 Dec 2022 01:13:03 +0100 Subject: [PATCH] fix(db): Dont compress DupSort SubKey (#594) * bug(db): Dont compress DupSort SubKey * unwrap or default config, Added notes * fmt empty lines --- bin/reth/src/node/mod.rs | 2 +- crates/primitives/src/storage.rs | 23 +++++++++++++++-- crates/stages/src/stages/execution.rs | 6 +++++ .../storage/db/src/tables/models/accounts.rs | 25 ++++++++++++++++--- 4 files changed, 49 insertions(+), 7 deletions(-) diff --git a/bin/reth/src/node/mod.rs b/bin/reth/src/node/mod.rs index 2afbbebb1..a49147dc5 100644 --- a/bin/reth/src/node/mod.rs +++ b/bin/reth/src/node/mod.rs @@ -84,7 +84,7 @@ impl Command { /// Execute `node` command // TODO: RPC pub async fn execute(&self) -> eyre::Result<()> { - let config: Config = confy::load_path(&self.config)?; + let config: Config = confy::load_path(&self.config).unwrap_or_default(); info!("reth {} starting", crate_version!()); info!("Opening database at {}", &self.db); diff --git a/crates/primitives/src/storage.rs b/crates/primitives/src/storage.rs index 26b29aff1..1b5ad8b9f 100644 --- a/crates/primitives/src/storage.rs +++ b/crates/primitives/src/storage.rs @@ -1,12 +1,31 @@ use super::{H256, U256}; -use reth_codecs::{main_codec, Compact}; +use reth_codecs::Compact; /// Account storage entry. #[derive(Debug, Default, Clone, PartialEq, Eq)] -#[main_codec] pub struct StorageEntry { /// Storage key. pub key: H256, /// Value on storage key. pub value: U256, } + +// NOTE: Removing main_codec and manually encode subkey +// and compress second part of the value. If we have compression +// over whole value (Even SubKey) that would mess up fetching of values with seek_by_key_subkey +impl Compact for StorageEntry { + fn to_compact(self, buf: &mut impl bytes::BufMut) -> usize { + // for now put full bytes and later compress it. + buf.put_slice(&self.key.to_fixed_bytes()[..]); + self.value.to_compact(buf) + 32 + } + + fn from_compact(buf: &[u8], len: usize) -> (Self, &[u8]) + where + Self: Sized, + { + let key = H256::from_slice(&buf[..32]); + let (value, out) = U256::from_compact(&buf[32..], len - 32); + (Self { key, value }, out) + } +} diff --git a/crates/stages/src/stages/execution.rs b/crates/stages/src/stages/execution.rs index 95192048d..6f60e6419 100644 --- a/crates/stages/src/stages/execution.rs +++ b/crates/stages/src/stages/execution.rs @@ -177,6 +177,12 @@ impl Stage for ExecutionStage { let state_provider = SubState::new(State::new(StateProviderImplRefLatest::new(&**tx))); trace!(target: "sync::stages::execution", number = header.number, txs = recovered_transactions.len(), "Executing block"); + + // For ethereum tests that has MAX gas that calls contract until max depth (1024 calls) + // revm can take more then default allocated stack space. For this case we are using + // local thread with increased stack size. After this task is done https://github.com/bluealloy/revm/issues/305 + // we can see to set more accurate stack size or even optimize revm to move more data to + // heap. let changeset = std::thread::scope(|scope| { let handle = std::thread::Builder::new() .stack_size(50 * 1024 * 1024) diff --git a/crates/storage/db/src/tables/models/accounts.rs b/crates/storage/db/src/tables/models/accounts.rs index 6d8b0f0aa..0b53c0de1 100644 --- a/crates/storage/db/src/tables/models/accounts.rs +++ b/crates/storage/db/src/tables/models/accounts.rs @@ -6,14 +6,11 @@ use crate::{ Error, }; use bytes::Bytes; -use reth_codecs::{main_codec, Compact}; +use reth_codecs::Compact; use reth_primitives::{Account, Address, TransitionId}; use serde::{Deserialize, Serialize}; /// Account as it is saved inside [`AccountChangeSet`]. [`Address`] is the subkey. -/// TODO there should be `not_existing` boolean or Account be made as `Option` to -/// handle scenario where account was not present before transaction. -#[main_codec] #[derive(Debug, Default, Clone, Eq, PartialEq)] pub struct AccountBeforeTx { /// Address for the account. Acts as `DupSort::SubKey`. @@ -22,6 +19,26 @@ pub struct AccountBeforeTx { pub info: Option, } +// NOTE: Removing main_codec and manually encode subkey +// and compress second part of the value. If we have compression +// over whole value (Even SubKey) that would mess up fetching of values with seek_by_key_subkey +impl Compact for AccountBeforeTx { + fn to_compact(self, buf: &mut impl bytes::BufMut) -> usize { + // for now put full bytes and later compress it. + buf.put_slice(&self.address.to_fixed_bytes()[..]); + self.info.to_compact(buf) + 32 + } + + fn from_compact(buf: &[u8], len: usize) -> (Self, &[u8]) + where + Self: Sized, + { + let address = Address::from_slice(&buf[..20]); + let (info, out) = >::from_compact(&buf[20..], len - 20); + (Self { address, info }, out) + } +} + /// [`TxNumber`] concatenated with [`Address`]. Used as a key for [`StorageChangeSet`] /// /// Since it's used as a key, it isn't compressed when encoding it.