Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion crates/consensus/auto-seal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ impl StorageInner {
executor.post_execution_state_change(block, U256::ZERO)?;

// merge transitions
executor.db().merge_transitions();
executor.db().merge_transitions(true);

// apply post block changes
Ok((executor.take_output_state(), gas_used))
Expand Down
26 changes: 20 additions & 6 deletions crates/consensus/beacon/src/engine/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,17 +199,31 @@ where
}
}

fn stats(&self) -> reth_provider::BlockExecutorStats {
fn take_output_state(&mut self) -> reth_provider::BundleState {
match self {
EitherBlockExecutor::Left(a) => a.stats(),
EitherBlockExecutor::Right(b) => b.stats(),
EitherBlockExecutor::Left(a) => a.take_output_state(),
EitherBlockExecutor::Right(b) => b.take_output_state(),
}
}

fn take_output_state(&mut self) -> reth_provider::BundleState {
fn set_prune_modes(&mut self, prune_modes: PruneModes) {
match self {
EitherBlockExecutor::Left(a) => a.take_output_state(),
EitherBlockExecutor::Right(b) => b.take_output_state(),
EitherBlockExecutor::Left(a) => a.set_prune_modes(prune_modes),
EitherBlockExecutor::Right(b) => b.set_prune_modes(prune_modes),
}
}

fn set_tip(&mut self, tip: BlockNumber) {
match self {
EitherBlockExecutor::Left(a) => a.set_tip(tip),
EitherBlockExecutor::Right(b) => b.set_tip(tip),
}
}

fn stats(&self) -> reth_provider::BlockExecutorStats {
match self {
EitherBlockExecutor::Left(a) => a.stats(),
EitherBlockExecutor::Right(b) => b.stats(),
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions crates/payload/basic/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,7 @@ where
commit_withdrawals(&mut db, &chain_spec, attributes.timestamp, attributes.withdrawals)?;

// merge made transaction into bundle state.
db.merge_transitions();
db.merge_transitions(false);

let bundle = BundleState::new(db.take_bundle(), vec![receipts], block_number);
let receipts_root = bundle.receipts_root_slow(block_number).expect("Number is in range");
Expand Down Expand Up @@ -829,7 +829,7 @@ where
commit_withdrawals(&mut db, &chain_spec, attributes.timestamp, attributes.withdrawals)?;

// merge transition, this would apply the withdrawal balance changes.
db.merge_transitions();
db.merge_transitions(false);

// calculate the state root
let bundle_state = BundleState::new(db.take_bundle(), vec![], block_number);
Expand Down
26 changes: 23 additions & 3 deletions crates/revm/src/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ use reth_interfaces::{
Error,
};
use reth_primitives::{
Address, Block, BlockNumber, Bloom, ChainSpec, Hardfork, Header, Receipt, ReceiptWithBloom,
TransactionSigned, H256, U256,
Address, Block, BlockNumber, Bloom, ChainSpec, Hardfork, Header, PruneModes, Receipt,
ReceiptWithBloom, TransactionSigned, H256, U256,
};
use reth_provider::{change::BundleState, BlockExecutor, BlockExecutorStats, StateProvider};
use revm::{
Expand All @@ -32,6 +32,10 @@ pub struct EVMProcessor<'a> {
/// First block will be initialized to ZERO
/// and be set to the block number of first block executed.
first_block: BlockNumber,
/// The maximum known block .
tip: Option<BlockNumber>,
/// Pruning configuration.
prune_modes: PruneModes,
/// Execution stats
stats: BlockExecutorStats,
}
Expand All @@ -47,6 +51,8 @@ impl<'a> From<Arc<ChainSpec>> for EVMProcessor<'a> {
stack: InspectorStack::new(InspectorStackConfig::default()),
receipts: Vec::new(),
first_block: 0,
tip: None,
prune_modes: PruneModes::none(),
stats: BlockExecutorStats::default(),
}
}
Expand All @@ -70,6 +76,8 @@ impl<'a> EVMProcessor<'a> {
stack: InspectorStack::new(InspectorStackConfig::default()),
receipts: Vec::new(),
first_block: 0,
tip: None,
prune_modes: PruneModes::default(),
stats: BlockExecutorStats::default(),
}
}
Expand Down Expand Up @@ -294,7 +302,11 @@ impl<'a> BlockExecutor for EVMProcessor<'a> {
self.stats.apply_post_execution_changes_duration += time.elapsed();

let time = Instant::now();
self.db().merge_transitions();
let with_reverts = self.tip.map_or(true, |tip| {
!self.prune_modes.should_prune_account_history(block.number, tip) &&
!self.prune_modes.should_prune_storage_history(block.number, tip)
});
self.db().merge_transitions(with_reverts);
Comment on lines +305 to +309
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense. We collect reverts either if tip is not set, or if pruning tells us to not prune the block we're processing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup, later on we can address the granularity of the revert retention in the bundle state

self.stats.merge_transitions_duration += time.elapsed();

if self.first_block == 0 {
Expand Down Expand Up @@ -337,6 +349,14 @@ impl<'a> BlockExecutor for EVMProcessor<'a> {
Ok(())
}

fn set_prune_modes(&mut self, prune_modes: PruneModes) {
self.prune_modes = prune_modes;
}

fn set_tip(&mut self, tip: BlockNumber) {
self.tip = Some(tip);
}

fn take_output_state(&mut self) -> BundleState {
let receipts = std::mem::take(&mut self.receipts);
BundleState::new(self.evm.db().unwrap().take_bundle(), receipts, self.first_block)
Expand Down
4 changes: 2 additions & 2 deletions crates/rpc/rpc/src/eth/api/pending_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ impl PendingBlockEnv {
// append transaction to the list of executed transactions
executed_txs.push(tx.into_signed());
}
// merge made transations into bundle state.
db.merge_transitions();
// merge made transitions into bundle state.
db.merge_transitions(false);

let bundle = BundleState::new(db.take_bundle(), vec![receipts], block_number);

Expand Down
7 changes: 3 additions & 4 deletions crates/stages/src/stages/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,13 @@ impl<EF: ExecutorFactory> ExecutionStage<EF> {

let start_block = input.next_block();
let max_block = input.target();
// TODO(rakita) integrate
let _prune_modes = self.adjust_prune_modes(provider, start_block, max_block)?;
let prune_modes = self.adjust_prune_modes(provider, start_block, max_block)?;

// Build executor
let mut executor =
self.executor_factory.with_sp(LatestStateProviderRef::new(provider.tx_ref()));
executor.set_prune_modes(prune_modes);
executor.set_tip(max_block);

// Progress tracking
let mut stage_progress = start_block;
Expand All @@ -138,8 +139,6 @@ impl<EF: ExecutorFactory> ExecutionStage<EF> {

let mut cumulative_gas = 0;

// TODO(rakita) integrate prunning.
//state.add_prune_modes(prune_modes);
for block_number in start_block..=max_block {
let time = Instant::now();
let td = provider
Expand Down
28 changes: 14 additions & 14 deletions crates/storage/provider/src/change.rs
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,7 @@ mod tests {
},
)]));

state.merge_transitions();
state.merge_transitions(true);
let mut revm_bundle_state = state.take_bundle();

// Write plain state and reverts separately.
Expand Down Expand Up @@ -681,7 +681,7 @@ mod tests {
},
)]));

state.merge_transitions();
state.merge_transitions(true);
let mut revm_bundle_state = state.take_bundle();

// Write plain state and reverts separately.
Expand Down Expand Up @@ -770,7 +770,7 @@ mod tests {
),
]));

state.merge_transitions();
state.merge_transitions(true);

BundleState::new(state.take_bundle(), Vec::new(), 1)
.write_to_db(provider.tx_ref(), false)
Expand Down Expand Up @@ -870,7 +870,7 @@ mod tests {
},
)]));

state.merge_transitions();
state.merge_transitions(true);
BundleState::new(state.take_bundle(), Vec::new(), 2)
.write_to_db(provider.tx_ref(), false)
.expect("Could not write bundle state to DB");
Expand Down Expand Up @@ -937,7 +937,7 @@ mod tests {
]),
},
)]));
init_state.merge_transitions();
init_state.merge_transitions(true);
BundleState::new(init_state.take_bundle(), Vec::new(), 0)
.write_to_db(provider.tx_ref(), false)
.expect("Could not write init bundle state to DB");
Expand Down Expand Up @@ -966,7 +966,7 @@ mod tests {
)]),
},
)]));
state.merge_transitions();
state.merge_transitions(true);

// Block #2: destroy account.
state.commit(HashMap::from([(
Expand All @@ -977,7 +977,7 @@ mod tests {
storage: HashMap::default(),
},
)]));
state.merge_transitions();
state.merge_transitions(true);

// Block #3: re-create account and change storage.
state.commit(HashMap::from([(
Expand All @@ -988,7 +988,7 @@ mod tests {
storage: HashMap::default(),
},
)]));
state.merge_transitions();
state.merge_transitions(true);

// Block #4: change storage.
state.commit(HashMap::from([(
Expand All @@ -1015,7 +1015,7 @@ mod tests {
]),
},
)]));
state.merge_transitions();
state.merge_transitions(true);

// Block #5: Destroy account again.
state.commit(HashMap::from([(
Expand All @@ -1026,7 +1026,7 @@ mod tests {
storage: HashMap::default(),
},
)]));
state.merge_transitions();
state.merge_transitions(true);

// Block #6: Create, change, destroy and re-create in the same block.
state.commit(HashMap::from([(
Expand Down Expand Up @@ -1065,7 +1065,7 @@ mod tests {
storage: HashMap::default(),
},
)]));
state.merge_transitions();
state.merge_transitions(true);

// Block #7: Change storage.
state.commit(HashMap::from([(
Expand All @@ -1080,7 +1080,7 @@ mod tests {
)]),
},
)]));
state.merge_transitions();
state.merge_transitions(true);

let bundle = state.take_bundle();

Expand Down Expand Up @@ -1248,7 +1248,7 @@ mod tests {
]),
},
)]));
init_state.merge_transitions();
init_state.merge_transitions(true);
BundleState::new(init_state.take_bundle(), Vec::new(), 0)
.write_to_db(provider.tx_ref(), false)
.expect("Could not write init bundle state to DB");
Expand Down Expand Up @@ -1294,7 +1294,7 @@ mod tests {
)]));

// Commit block #1 changes to the database.
state.merge_transitions();
state.merge_transitions(true);
BundleState::new(state.take_bundle(), Vec::new(), 1)
.write_to_db(provider.tx_ref(), false)
.expect("Could not write bundle state to DB");
Expand Down
6 changes: 5 additions & 1 deletion crates/storage/provider/src/test_utils/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
};
use parking_lot::Mutex;
use reth_interfaces::executor::BlockExecutionError;
use reth_primitives::{Address, Block, ChainSpec, U256};
use reth_primitives::{Address, Block, BlockNumber, ChainSpec, U256};
use std::sync::Arc;
/// Test executor with mocked result.
pub struct TestExecutor(pub Option<BundleState>);
Expand Down Expand Up @@ -33,6 +33,10 @@ impl BlockExecutor for TestExecutor {
Ok(())
}

fn set_prune_modes(&mut self, _prune_modes: reth_primitives::PruneModes) {}

fn set_tip(&mut self, _tip: BlockNumber) {}

fn take_output_state(&mut self) -> BundleState {
self.0.clone().unwrap_or_default()
}
Expand Down
12 changes: 9 additions & 3 deletions crates/storage/provider/src/traits/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::time::Duration;

use crate::{change::BundleState, StateProvider};
use reth_interfaces::executor::BlockExecutionError;
use reth_primitives::{Address, Block, ChainSpec, U256};
use reth_primitives::{Address, Block, BlockNumber, ChainSpec, PruneModes, U256};
use tracing::info;

/// Executor factory that would create the EVM with particular state provider.
Expand Down Expand Up @@ -77,9 +77,15 @@ pub trait BlockExecutor {
senders: Option<Vec<Address>>,
) -> Result<(), BlockExecutionError>;

/// Internal statistics of execution.
fn stats(&self) -> BlockExecutorStats;
/// Set prune modes.
fn set_prune_modes(&mut self, prune_modes: PruneModes);

/// Set tip - highest known block number.
fn set_tip(&mut self, tip: BlockNumber);

/// Return bundle state. This is output of the execution.
fn take_output_state(&mut self) -> BundleState;

/// Internal statistics of execution.
fn stats(&self) -> BlockExecutorStats;
}