Skip to content

Commit

Permalink
fix: add block rewards to trace_block (#3491)
Browse files Browse the repository at this point in the history
Co-authored-by: Georgios Konstantopoulos <me@gakonst.com>
  • Loading branch information
onbjerg and gakonst committed Jul 2, 2023
1 parent 951fd0a commit 4f32f56
Show file tree
Hide file tree
Showing 12 changed files with 160 additions and 34 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

5 changes: 4 additions & 1 deletion bin/reth/src/args/rpc_server_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ use clap::{
use futures::TryFutureExt;
use reth_network_api::{NetworkInfo, Peers};
use reth_provider::{
BlockReaderIdExt, CanonStateSubscriptions, EvmEnvProvider, HeaderProvider, StateProviderFactory,
BlockReaderIdExt, CanonStateSubscriptions, ChainSpecProvider, EvmEnvProvider, HeaderProvider,
StateProviderFactory,
};
use reth_rpc::{
eth::{
Expand Down Expand Up @@ -235,6 +236,7 @@ impl RpcServerArgs {
+ HeaderProvider
+ StateProviderFactory
+ EvmEnvProvider
+ ChainSpecProvider
+ Clone
+ Unpin
+ 'static,
Expand Down Expand Up @@ -295,6 +297,7 @@ impl RpcServerArgs {
+ HeaderProvider
+ StateProviderFactory
+ EvmEnvProvider
+ ChainSpecProvider
+ Clone
+ Unpin
+ 'static,
Expand Down
44 changes: 34 additions & 10 deletions crates/rpc/rpc-builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@
//!
//! ```
//! use reth_network_api::{NetworkInfo, Peers};
//! use reth_provider::{BlockReaderIdExt, CanonStateSubscriptions, StateProviderFactory, EvmEnvProvider};
//! use reth_provider::{BlockReaderIdExt, ChainSpecProvider, CanonStateSubscriptions, StateProviderFactory, EvmEnvProvider};
//! use reth_rpc_builder::{RethRpcModule, RpcModuleBuilder, RpcServerConfig, ServerBuilder, TransportRpcModuleConfig};
//! use reth_tasks::TokioTaskExecutor;
//! use reth_transaction_pool::TransactionPool;
//! pub async fn launch<Provider, Pool, Network, Events>(provider: Provider, pool: Pool, network: Network, events: Events)
//! where
//! Provider: BlockReaderIdExt + StateProviderFactory + EvmEnvProvider + Clone + Unpin + 'static,
//! Provider: BlockReaderIdExt + ChainSpecProvider + StateProviderFactory + EvmEnvProvider + Clone + Unpin + 'static,
//! Pool: TransactionPool + Clone + 'static,
//! Network: NetworkInfo + Peers + Clone + 'static,
//! Events: CanonStateSubscriptions + Clone + 'static,
Expand All @@ -64,7 +64,7 @@
//! ```
//! use tokio::try_join;
//! use reth_network_api::{NetworkInfo, Peers};
//! use reth_provider::{BlockReaderIdExt, CanonStateSubscriptions, StateProviderFactory, EvmEnvProvider};
//! use reth_provider::{BlockReaderIdExt, ChainSpecProvider, CanonStateSubscriptions, StateProviderFactory, EvmEnvProvider};
//! use reth_rpc::JwtSecret;
//! use reth_rpc_builder::{RethRpcModule, RpcModuleBuilder, RpcServerConfig, TransportRpcModuleConfig};
//! use reth_tasks::TokioTaskExecutor;
Expand All @@ -73,7 +73,7 @@
//! use reth_rpc_builder::auth::AuthServerConfig;
//! pub async fn launch<Provider, Pool, Network, Events, EngineApi>(provider: Provider, pool: Pool, network: Network, events: Events, engine_api: EngineApi)
//! where
//! Provider: BlockReaderIdExt + StateProviderFactory + EvmEnvProvider + Clone + Unpin + 'static,
//! Provider: BlockReaderIdExt + ChainSpecProvider + StateProviderFactory + EvmEnvProvider + Clone + Unpin + 'static,
//! Pool: TransactionPool + Clone + 'static,
//! Network: NetworkInfo + Peers + Clone + 'static,
//! Events: CanonStateSubscriptions + Clone + 'static,
Expand Down Expand Up @@ -113,7 +113,8 @@ use jsonrpsee::{
use reth_ipc::server::IpcServer;
use reth_network_api::{NetworkInfo, Peers};
use reth_provider::{
BlockReader, BlockReaderIdExt, CanonStateSubscriptions, EvmEnvProvider, StateProviderFactory,
BlockReader, BlockReaderIdExt, CanonStateSubscriptions, ChainSpecProvider, EvmEnvProvider,
StateProviderFactory,
};
use reth_rpc::{
eth::{
Expand Down Expand Up @@ -169,7 +170,13 @@ pub async fn launch<Provider, Pool, Network, Tasks, Events>(
events: Events,
) -> Result<RpcServerHandle, RpcError>
where
Provider: BlockReaderIdExt + StateProviderFactory + EvmEnvProvider + Clone + Unpin + 'static,
Provider: BlockReaderIdExt
+ StateProviderFactory
+ EvmEnvProvider
+ ChainSpecProvider
+ Clone
+ Unpin
+ 'static,
Pool: TransactionPool + Clone + 'static,
Network: NetworkInfo + Peers + Clone + 'static,
Tasks: TaskSpawner + Clone + 'static,
Expand Down Expand Up @@ -268,7 +275,13 @@ impl<Provider, Pool, Network, Tasks, Events>
impl<Provider, Pool, Network, Tasks, Events>
RpcModuleBuilder<Provider, Pool, Network, Tasks, Events>
where
Provider: BlockReaderIdExt + StateProviderFactory + EvmEnvProvider + Clone + Unpin + 'static,
Provider: BlockReaderIdExt
+ StateProviderFactory
+ EvmEnvProvider
+ ChainSpecProvider
+ Clone
+ Unpin
+ 'static,
Pool: TransactionPool + Clone + 'static,
Network: NetworkInfo + Peers + Clone + 'static,
Tasks: TaskSpawner + Clone + 'static,
Expand Down Expand Up @@ -485,8 +498,13 @@ impl RpcModuleSelection {
config: RpcModuleConfig,
) -> RpcModule<()>
where
Provider:
BlockReaderIdExt + StateProviderFactory + EvmEnvProvider + Clone + Unpin + 'static,
Provider: BlockReaderIdExt
+ StateProviderFactory
+ EvmEnvProvider
+ ChainSpecProvider
+ Clone
+ Unpin
+ 'static,
Pool: TransactionPool + Clone + 'static,
Network: NetworkInfo + Peers + Clone + 'static,
Tasks: TaskSpawner + Clone + 'static,
Expand Down Expand Up @@ -692,7 +710,13 @@ where
impl<Provider, Pool, Network, Tasks, Events>
RethModuleRegistry<Provider, Pool, Network, Tasks, Events>
where
Provider: BlockReaderIdExt + StateProviderFactory + EvmEnvProvider + Clone + Unpin + 'static,
Provider: BlockReaderIdExt
+ StateProviderFactory
+ EvmEnvProvider
+ ChainSpecProvider
+ Clone
+ Unpin
+ 'static,
Pool: TransactionPool + Clone + 'static,
Network: NetworkInfo + Peers + Clone + 'static,
Tasks: TaskSpawner + Clone + 'static,
Expand Down
1 change: 1 addition & 0 deletions crates/rpc/rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ reth-rpc-engine-api = { path = "../rpc-engine-api" }
reth-revm = { path = "../../revm" }
reth-tasks = { workspace = true }
reth-metrics = { workspace = true }
reth-consensus-common = { path = "../../consensus/common" }

# eth
revm = { workspace = true, features = [
Expand Down
67 changes: 62 additions & 5 deletions crates/rpc/rpc/src/trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@ use crate::{
};
use async_trait::async_trait;
use jsonrpsee::core::RpcResult as Result;
use reth_primitives::{BlockId, BlockNumberOrTag, Bytes, H256};
use reth_provider::{BlockReader, EvmEnvProvider, StateProviderBox, StateProviderFactory};
use reth_consensus_common::calc::{base_block_reward, block_reward};
use reth_primitives::{BlockId, BlockNumberOrTag, Bytes, SealedHeader, H256, U256};
use reth_provider::{
BlockReader, ChainSpecProvider, EvmEnvProvider, StateProviderBox, StateProviderFactory,
};
use reth_revm::{
database::{State, SubState},
env::tx_env_with_recovered,
Expand Down Expand Up @@ -77,7 +80,7 @@ impl<Provider, Eth> TraceApi<Provider, Eth> {

impl<Provider, Eth> TraceApi<Provider, Eth>
where
Provider: BlockReader + StateProviderFactory + EvmEnvProvider + 'static,
Provider: BlockReader + StateProviderFactory + EvmEnvProvider + ChainSpecProvider + 'static,
Eth: EthTransactions + 'static,
{
/// Executes the future on a new blocking task.
Expand Down Expand Up @@ -396,7 +399,7 @@ where
&self,
block_id: BlockId,
) -> EthResult<Option<Vec<LocalizedTransactionTrace>>> {
let traces = self
let mut traces: Option<Vec<LocalizedTransactionTrace>> = self
.trace_block_with(
block_id,
TracingInspectorConfig::default_parity(),
Expand All @@ -408,6 +411,43 @@ where
)
.await?
.map(|traces| traces.into_iter().flatten().collect());

// Add block reward traces
// TODO: We only really need the header and ommers here to determine the reward
if let (Some(block), Some(traces)) =
(self.inner.eth_api.block_by_id(block_id).await?, traces.as_mut())
{
if let Some(header_td) = self.provider().header_td(&block.header.hash)? {
if let Some(base_block_reward) = base_block_reward(
self.provider().chain_spec().as_ref(),
block.header.number,
block.header.difficulty,
header_td,
) {
traces.push(reward_trace(
&block.header,
RewardAction {
author: block.header.beneficiary,
reward_type: RewardType::Block,
value: U256::from(base_block_reward),
},
));

if !block.ommers.is_empty() {
traces.push(reward_trace(
&block.header,
RewardAction {
author: block.header.beneficiary,
reward_type: RewardType::Uncle,
value: block_reward(base_block_reward, block.ommers.len()) -
U256::from(base_block_reward),
},
));
}
}
}
}

Ok(traces)
}

Expand Down Expand Up @@ -448,7 +488,7 @@ where
#[async_trait]
impl<Provider, Eth> TraceApiServer for TraceApi<Provider, Eth>
where
Provider: BlockReader + StateProviderFactory + EvmEnvProvider + 'static,
Provider: BlockReader + StateProviderFactory + EvmEnvProvider + ChainSpecProvider + 'static,
Eth: EthTransactions + 'static,
{
/// Executes the given call and returns a number of possible traces for it.
Expand Down Expand Up @@ -581,3 +621,20 @@ fn tracing_config(trace_types: &HashSet<TraceType>) -> TracingInspectorConfig {
.set_state_diffs(trace_types.contains(&TraceType::StateDiff))
.set_steps(trace_types.contains(&TraceType::VmTrace))
}

/// Helper to construct a [`LocalizedTransactionTrace`] that describes a reward to the block
/// beneficiary.
fn reward_trace(header: &SealedHeader, reward: RewardAction) -> LocalizedTransactionTrace {
LocalizedTransactionTrace {
block_hash: Some(header.hash),
block_number: Some(header.number),
transaction_hash: None,
transaction_position: None,
trace: TransactionTrace {
trace_address: vec![],
subtraces: 0,
action: Action::Reward(reward),
result: None,
},
}
}
11 changes: 6 additions & 5 deletions crates/storage/provider/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ pub use traits::{
AccountExtReader, AccountReader, BlockExecutionWriter, BlockExecutor, BlockHashReader,
BlockIdReader, BlockNumReader, BlockReader, BlockReaderIdExt, BlockSource, BlockWriter,
BlockchainTreePendingStateProvider, CanonChainTracker, CanonStateNotification,
CanonStateNotificationSender, CanonStateNotifications, CanonStateSubscriptions, EvmEnvProvider,
ExecutorFactory, HashingWriter, HeaderProvider, HistoryWriter, PostStateDataProvider,
ReceiptProvider, ReceiptProviderIdExt, StageCheckpointReader, StageCheckpointWriter,
StateProvider, StateProviderBox, StateProviderFactory, StateRootProvider, StorageReader,
TransactionsProvider, WithdrawalsProvider,
CanonStateNotificationSender, CanonStateNotifications, CanonStateSubscriptions,
ChainSpecProvider, EvmEnvProvider, ExecutorFactory, HashingWriter, HeaderProvider,
HistoryWriter, PostStateDataProvider, ReceiptProvider, ReceiptProviderIdExt,
StageCheckpointReader, StageCheckpointWriter, StateProvider, StateProviderBox,
StateProviderFactory, StateRootProvider, StorageReader, TransactionsProvider,
WithdrawalsProvider,
};

/// Provider trait implementations.
Expand Down
14 changes: 12 additions & 2 deletions crates/storage/provider/src/providers/database/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::{
providers::state::{historical::HistoricalStateProvider, latest::LatestStateProvider},
traits::{BlockSource, ReceiptProvider},
BlockHashReader, BlockNumReader, BlockReader, EvmEnvProvider, HeaderProvider, ProviderError,
StageCheckpointReader, StateProviderBox, TransactionsProvider, WithdrawalsProvider,
BlockHashReader, BlockNumReader, BlockReader, ChainSpecProvider, EvmEnvProvider,
HeaderProvider, ProviderError, StageCheckpointReader, StateProviderBox, TransactionsProvider,
WithdrawalsProvider,
};
use reth_db::{database::Database, init_db, models::StoredBlockBodyIndices, DatabaseEnv};
use reth_interfaces::Result;
Expand Down Expand Up @@ -343,6 +344,15 @@ impl<DB: Database> EvmEnvProvider for ProviderFactory<DB> {
}
}

impl<DB> ChainSpecProvider for ProviderFactory<DB>
where
DB: Send + Sync,
{
fn chain_spec(&self) -> Arc<ChainSpec> {
self.chain_spec.clone()
}
}

#[cfg(test)]
mod tests {
use super::ProviderFactory;
Expand Down
20 changes: 16 additions & 4 deletions crates/storage/provider/src/providers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use crate::{
BlockHashReader, BlockIdReader, BlockNumReader, BlockReader, BlockReaderIdExt,
BlockchainTreePendingStateProvider, CanonChainTracker, CanonStateNotifications,
CanonStateSubscriptions, EvmEnvProvider, HeaderProvider, PostStateDataProvider, ProviderError,
ReceiptProvider, ReceiptProviderIdExt, StageCheckpointReader, StateProviderBox,
StateProviderFactory, TransactionsProvider, WithdrawalsProvider,
CanonStateSubscriptions, ChainSpecProvider, EvmEnvProvider, HeaderProvider,
PostStateDataProvider, ProviderError, ReceiptProvider, ReceiptProviderIdExt,
StageCheckpointReader, StateProviderBox, StateProviderFactory, TransactionsProvider,
WithdrawalsProvider,
};
use reth_db::{database::Database, models::StoredBlockBodyIndices};
use reth_interfaces::{
Expand All @@ -14,7 +15,7 @@ use reth_interfaces::{
use reth_primitives::{
stage::{StageCheckpoint, StageId},
Address, Block, BlockHash, BlockHashOrNumber, BlockId, BlockNumHash, BlockNumber,
BlockNumberOrTag, BlockWithSenders, ChainInfo, Header, Receipt, SealedBlock,
BlockNumberOrTag, BlockWithSenders, ChainInfo, ChainSpec, Header, Receipt, SealedBlock,
SealedBlockWithSenders, SealedHeader, TransactionMeta, TransactionSigned,
TransactionSignedNoHash, TxHash, TxNumber, Withdrawal, H256, U256,
};
Expand All @@ -26,6 +27,7 @@ pub use state::{
use std::{
collections::{BTreeMap, HashSet},
ops::RangeBounds,
sync::Arc,
time::Instant,
};
use tracing::trace;
Expand Down Expand Up @@ -431,6 +433,16 @@ where
}
}

impl<DB, Tree> ChainSpecProvider for BlockchainProvider<DB, Tree>
where
DB: Send + Sync,
Tree: Send + Sync,
{
fn chain_spec(&self) -> Arc<ChainSpec> {
self.database.chain_spec()
}
}

impl<DB, Tree> StateProviderFactory for BlockchainProvider<DB, Tree>
where
DB: Database,
Expand Down
18 changes: 12 additions & 6 deletions crates/storage/provider/src/test_utils/noop.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
use crate::{
traits::{BlockSource, ReceiptProvider},
AccountReader, BlockHashReader, BlockIdReader, BlockNumReader, BlockReader, BlockReaderIdExt,
EvmEnvProvider, HeaderProvider, PostState, ReceiptProviderIdExt, StageCheckpointReader,
StateProvider, StateProviderBox, StateProviderFactory, StateRootProvider, TransactionsProvider,
WithdrawalsProvider,
ChainSpecProvider, EvmEnvProvider, HeaderProvider, PostState, ReceiptProviderIdExt,
StageCheckpointReader, StateProvider, StateProviderBox, StateProviderFactory,
StateRootProvider, TransactionsProvider, WithdrawalsProvider,
};
use reth_db::models::StoredBlockBodyIndices;
use reth_interfaces::Result;
use reth_primitives::{
stage::{StageCheckpoint, StageId},
Account, Address, Block, BlockHash, BlockHashOrNumber, BlockId, BlockNumber, Bytecode, Bytes,
ChainInfo, Header, Receipt, SealedBlock, SealedHeader, StorageKey, StorageValue,
TransactionMeta, TransactionSigned, TxHash, TxNumber, H256, KECCAK_EMPTY, U256,
ChainInfo, ChainSpec, Header, Receipt, SealedBlock, SealedHeader, StorageKey, StorageValue,
TransactionMeta, TransactionSigned, TxHash, TxNumber, H256, KECCAK_EMPTY, MAINNET, U256,
};
use reth_revm_primitives::primitives::{BlockEnv, CfgEnv};
use std::ops::RangeBounds;
use std::{ops::RangeBounds, sync::Arc};

/// Supports various api interfaces for testing purposes.
#[derive(Debug, Clone, Default, Copy)]
#[non_exhaustive]
pub struct NoopProvider;

impl ChainSpecProvider for NoopProvider {
fn chain_spec(&self) -> Arc<ChainSpec> {
MAINNET.clone()
}
}

/// Noop implementation for testing purposes
impl BlockHashReader for NoopProvider {
fn block_hash(&self, _number: u64) -> Result<Option<H256>> {
Expand Down
3 changes: 3 additions & 0 deletions crates/storage/provider/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ pub use chain::{
CanonStateSubscriptions,
};

mod spec;
pub use spec::ChainSpecProvider;

mod stage_checkpoint;
pub use stage_checkpoint::{StageCheckpointReader, StageCheckpointWriter};

Expand Down
Loading

0 comments on commit 4f32f56

Please sign in to comment.