chore: simplify committing withdrawals (#2404)

This commit is contained in:
Matthias Seitz
2023-04-26 14:20:16 +02:00
committed by GitHub
parent bf7960c87a
commit a7b3749312

View File

@ -16,9 +16,11 @@ use reth_payload_builder::{
}; };
use reth_primitives::{ use reth_primitives::{
bytes::{Bytes, BytesMut}, bytes::{Bytes, BytesMut},
constants::{EMPTY_RECEIPTS, EMPTY_TRANSACTIONS, RETH_CLIENT_VERSION, SLOT_DURATION}, constants::{
EMPTY_RECEIPTS, EMPTY_TRANSACTIONS, EMPTY_WITHDRAWALS, RETH_CLIENT_VERSION, SLOT_DURATION,
},
proofs, Block, BlockId, BlockNumberOrTag, ChainSpec, Header, IntoRecoveredTransaction, Receipt, proofs, Block, BlockId, BlockNumberOrTag, ChainSpec, Header, IntoRecoveredTransaction, Receipt,
SealedBlock, EMPTY_OMMER_ROOT, U256, SealedBlock, Withdrawal, EMPTY_OMMER_ROOT, H256, U256,
}; };
use reth_provider::{BlockProvider, PostState, StateProviderFactory}; use reth_provider::{BlockProvider, PostState, StateProviderFactory};
use reth_revm::{ use reth_revm::{
@ -32,7 +34,10 @@ use reth_revm::{
use reth_rlp::Encodable; use reth_rlp::Encodable;
use reth_tasks::TaskSpawner; use reth_tasks::TaskSpawner;
use reth_transaction_pool::TransactionPool; use reth_transaction_pool::TransactionPool;
use revm::primitives::{BlockEnv, CfgEnv, Env, ResultAndState, SpecId}; use revm::{
db::{CacheDB, DatabaseRef},
primitives::{BlockEnv, CfgEnv, Env, ResultAndState},
};
use std::{ use std::{
future::Future, future::Future,
pin::Pin, pin::Pin,
@ -529,33 +534,14 @@ fn build_payload<Pool, Client>(
return Ok(BuildOutcome::Aborted { fees: total_fees }) return Ok(BuildOutcome::Aborted { fees: total_fees })
} }
let mut withdrawals_root = None; let WithdrawalsOutcome { withdrawals_root, withdrawals } = commit_withdrawals(
let mut withdrawals = None; &mut db,
&mut post_state,
// get balance changes from withdrawals &chain_spec,
if initialized_cfg.spec_id >= SpecId::SHANGHAI { block_number,
let balance_increments = post_block_withdrawals_balance_increments( attributes.timestamp,
&chain_spec, attributes.withdrawals,
attributes.timestamp, )?;
&attributes.withdrawals,
);
for (address, increment) in balance_increments {
increment_account_balance(
&mut db,
&mut post_state,
block_number,
address,
increment,
)?;
}
// calculate withdrawals root
withdrawals_root =
Some(proofs::calculate_withdrawals_root(attributes.withdrawals.iter()));
// set withdrawals
withdrawals = Some(attributes.withdrawals);
}
let receipts_root = post_state.receipts_root(); let receipts_root = post_state.receipts_root();
let logs_bloom = post_state.logs_bloom(); let logs_bloom = post_state.logs_bloom();
@ -613,35 +599,22 @@ where
parent_block, parent_block,
extra_data, extra_data,
attributes, attributes,
initialized_cfg,
chain_spec, chain_spec,
..
} = config; } = config;
let base_fee = initialized_block_env.basefee.to::<u64>(); let base_fee = initialized_block_env.basefee.to::<u64>();
let block_number = initialized_block_env.number.to::<u64>(); let block_number = initialized_block_env.number.to::<u64>();
let block_gas_limit: u64 = initialized_block_env.gas_limit.try_into().unwrap_or(u64::MAX); let block_gas_limit: u64 = initialized_block_env.gas_limit.try_into().unwrap_or(u64::MAX);
let mut withdrawals_root = None; let WithdrawalsOutcome { withdrawals_root, withdrawals } = commit_withdrawals(
let mut withdrawals = None; &mut db,
&mut post_state,
// perform at least all the withdrawals &chain_spec,
if initialized_cfg.spec_id >= SpecId::SHANGHAI { block_number,
let balance_increments = post_block_withdrawals_balance_increments( attributes.timestamp,
&chain_spec, attributes.withdrawals,
attributes.timestamp, )?;
&attributes.withdrawals,
);
for (address, increment) in balance_increments {
increment_account_balance(&mut db, &mut post_state, block_number, address, increment)?;
}
// calculate withdrawals root
withdrawals_root = Some(proofs::calculate_withdrawals_root(attributes.withdrawals.iter()));
// set withdrawals
withdrawals = Some(attributes.withdrawals);
}
// calculate the state root // calculate the state root
let state_root = db.db.0.state_root(post_state)?; let state_root = db.db.0.state_root(post_state)?;
@ -672,6 +645,65 @@ where
Ok(BuiltPayload::new(attributes.id, sealed_block, U256::ZERO)) Ok(BuiltPayload::new(attributes.id, sealed_block, U256::ZERO))
} }
/// Represents the outcome of committing withdrawals to the runtime database and post state.
/// Pre-shanghai these are `None` values.
struct WithdrawalsOutcome {
withdrawals: Option<Vec<Withdrawal>>,
withdrawals_root: Option<H256>,
}
impl WithdrawalsOutcome {
/// No withdrawals pre shanghai
fn pre_shanghai() -> Self {
Self { withdrawals: None, withdrawals_root: None }
}
fn empty() -> Self {
Self { withdrawals: Some(vec![]), withdrawals_root: Some(EMPTY_WITHDRAWALS) }
}
}
/// Executes the withdrawals and commits them to the _runtime_ Database and PostState.
///
/// Returns the withdrawals root.
///
/// Returns `None` values pre shanghai
#[allow(clippy::too_many_arguments)]
fn commit_withdrawals<DB>(
db: &mut CacheDB<DB>,
post_state: &mut PostState,
chain_spec: &ChainSpec,
block_number: u64,
timestamp: u64,
withdrawals: Vec<Withdrawal>,
) -> Result<WithdrawalsOutcome, <DB as DatabaseRef>::Error>
where
DB: DatabaseRef,
{
if !chain_spec.is_shanghai_activated_at_timestamp(timestamp) {
return Ok(WithdrawalsOutcome::pre_shanghai())
}
if withdrawals.is_empty() {
return Ok(WithdrawalsOutcome::empty())
}
let balance_increments =
post_block_withdrawals_balance_increments(chain_spec, timestamp, &withdrawals);
for (address, increment) in balance_increments {
increment_account_balance(db, post_state, block_number, address, increment)?;
}
let withdrawals_root = proofs::calculate_withdrawals_root(withdrawals.iter());
// calculate withdrawals root
Ok(WithdrawalsOutcome {
withdrawals: Some(withdrawals),
withdrawals_root: Some(withdrawals_root),
})
}
/// Checks if the new payload is better than the current best. /// Checks if the new payload is better than the current best.
/// ///
/// This compares the total fees of the blocks, higher is better. /// This compares the total fees of the blocks, higher is better.