Skip to content
This repository has been archived by the owner on Feb 6, 2025. It is now read-only.

Commit

Permalink
feat: optimize bsc trace api
Browse files Browse the repository at this point in the history
  • Loading branch information
pythonberg1997 committed Oct 25, 2024
1 parent 80317a4 commit 0d0a4d3
Show file tree
Hide file tree
Showing 27 changed files with 608 additions and 343 deletions.
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.

1 change: 1 addition & 0 deletions crates/bsc/consensus/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ reth-network.workspace = true
reth-engine-primitives.workspace = true
reth-network-p2p.workspace = true
reth-network-peers.workspace = true
reth-revm.workspace = true

# bsc
reth-bsc-chainspec.workspace = true
Expand Down
7 changes: 4 additions & 3 deletions crates/bsc/consensus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use alloy_rlp::Decodable;
use lazy_static::lazy_static;
use lru::LruCache;
use parking_lot::RwLock;
use reth_bsc_chainspec::BscChainSpec;
use reth_bsc_forks::BscHardforks;
use reth_chainspec::{ChainSpec, EthChainSpec, EthereumHardforks};
use reth_consensus::{Consensus, ConsensusError, PostExecutionInput};
Expand Down Expand Up @@ -50,16 +51,16 @@ mod go_rng;
pub use go_rng::{RngSource, Shuffle};
mod abi;
pub use abi::*;
use reth_bsc_chainspec::BscChainSpec;
mod system_tx;
mod trace_helper;
pub use trace_helper::{BscTraceHelper, BscTraceHelperError};

mod validation;
pub use validation::{
validate_4844_header_of_bsc, validate_against_parent_eip1559_base_fee_of_bsc,
validate_block_post_execution_of_bsc,
};

mod system_tx;

const RECOVERED_PROPOSER_CACHE_NUM: usize = 4096;

lazy_static! {
Expand Down
91 changes: 91 additions & 0 deletions crates/bsc/consensus/src/trace_helper.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
use std::sync::Arc;

use alloy_primitives::{address, Address, U256};
use reth_bsc_forks::BscHardforks;
use reth_bsc_primitives::system_contracts::get_upgrade_system_contracts;
use reth_primitives::revm_primitives::{db::DatabaseRef, BlockEnv};
use reth_revm::db::{
AccountState::{NotExisting, Touched},
CacheDB,
};

use crate::Parlia;

// redefine to avoid dependency on revm/bsc
const SYSTEM_ADDRESS: Address = address!("fffffffffffffffffffffffffffffffffffffffe");

#[derive(Debug, Clone)]
pub struct BscTraceHelper {
parlia: Arc<Parlia>,
}

impl BscTraceHelper {
pub const fn new(parlia: Arc<Parlia>) -> Self {
Self { parlia }
}

pub fn upgrade_system_contracts<ExtDB: DatabaseRef>(
&self,
db: &mut CacheDB<ExtDB>,
block_env: &BlockEnv,
parent_timestamp: u64,
before_tx: bool,
) -> Result<(), BscTraceHelperError> {
let is_feynman_active =
self.parlia.chain_spec().is_feynman_active_at_timestamp(block_env.timestamp.to());

if (before_tx && !is_feynman_active) || (!before_tx && is_feynman_active) {
let contracts = get_upgrade_system_contracts(
self.parlia.chain_spec(),
block_env.number.to(),
block_env.timestamp.to(),
parent_timestamp,
)
.map_err(|_| BscTraceHelperError::GetUpgradeSystemContractsFailed)?;

for (k, v) in contracts {
let account =
db.load_account(k).map_err(|_| BscTraceHelperError::LoadAccountFailed).unwrap();
if account.account_state == NotExisting {
account.account_state = Touched;
}
account.info.code_hash = v.clone().unwrap().hash_slow();
account.info.code = v;
}
}

Ok(())
}

pub fn add_block_reward<ExtDB: DatabaseRef>(
&self,
db: &mut CacheDB<ExtDB>,
block_env: &BlockEnv,
) -> Result<(), BscTraceHelperError> {
let sys_acc =
db.load_account(SYSTEM_ADDRESS).map_err(|_| BscTraceHelperError::LoadAccountFailed)?;
let balance = sys_acc.info.balance;
if balance > U256::ZERO {
sys_acc.info.balance = U256::ZERO;

let val_acc = db
.load_account(block_env.coinbase)
.map_err(|_| BscTraceHelperError::LoadAccountFailed)?;
if val_acc.account_state == NotExisting {
val_acc.account_state = Touched;
}
val_acc.info.balance += balance;
}

Ok(())
}
}

/// Errors that can occur when calling `BscTraceHelper` methods
#[derive(Debug, thiserror::Error)]
pub enum BscTraceHelperError {
#[error("Failed to load account from db")]
LoadAccountFailed,
#[error("Failed to get upgrade system contracts")]
GetUpgradeSystemContractsFailed,
}
6 changes: 3 additions & 3 deletions crates/bsc/evm/src/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ where
return Err(BscBlockExecutionError::EthCallFailed.into());
}

let output = result.output().ok_or_else(|| BscBlockExecutionError::EthCallFailed)?;
let output = result.output().ok_or(BscBlockExecutionError::EthCallFailed)?;
Ok(output.clone())
}

Expand Down Expand Up @@ -1008,7 +1008,7 @@ where
}
}

let mut snap = snap.ok_or_else(|| BscBlockExecutionError::SnapshotNotFound)?;
let mut snap = snap.ok_or(BscBlockExecutionError::SnapshotNotFound)?;

// the old snapshots don't have turn length, make sure we initialize it with default
// before accessing it
Expand Down Expand Up @@ -1061,7 +1061,7 @@ where
turn_length,
self.parlia.chain_spec().is_bohr_active_at_timestamp(header.timestamp),
)
.ok_or_else(|| BscBlockExecutionError::ApplySnapshotFailed)?;
.ok_or(BscBlockExecutionError::ApplySnapshotFailed)?;

cache.put(snap.block_hash, snap.clone());
}
Expand Down
8 changes: 4 additions & 4 deletions crates/bsc/evm/src/post_execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,10 @@ where
{
let max_elected_validators = post_execution_input
.max_elected_validators
.ok_or_else(|| BscBlockExecutionError::InvalidValidatorsElectionInfoData)?;
.ok_or(BscBlockExecutionError::InvalidValidatorsElectionInfoData)?;
let validators_election_info = post_execution_input
.validators_election_info
.ok_or_else(|| BscBlockExecutionError::InvalidValidatorsElectionInfoData)?;
.ok_or(BscBlockExecutionError::InvalidValidatorsElectionInfoData)?;

self.update_validator_set_v2(
max_elected_validators,
Expand Down Expand Up @@ -202,8 +202,8 @@ where
return Ok(())
};

let (mut validators, mut vote_addrs_map) = current_validators
.ok_or_else(|| BscBlockExecutionError::InvalidCurrentValidatorsData)?;
let (mut validators, mut vote_addrs_map) =
current_validators.ok_or(BscBlockExecutionError::InvalidCurrentValidatorsData)?;
validators.sort();

let validator_num = validators.len();
Expand Down
7 changes: 4 additions & 3 deletions crates/bsc/evm/src/pre_execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,10 @@ where
continue;
}

let val_info = snap.validators_map.get(val).ok_or_else(|| {
BscBlockExecutionError::VoteAddrNotFoundInSnap { address: *val }
})?;
let val_info = snap
.validators_map
.get(val)
.ok_or(BscBlockExecutionError::VoteAddrNotFoundInSnap { address: *val })?;
vote_addrs.push(val_info.vote_addr);
}

Expand Down
9 changes: 9 additions & 0 deletions crates/node/builder/src/launch/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ use reth_beacon_consensus::{
};
use reth_blockchain_tree::BlockchainTreeConfig;
#[cfg(feature = "bsc")]
use reth_bsc_consensus::BscTraceHelper;
#[cfg(feature = "bsc")]
use reth_bsc_engine::ParliaEngineBuilder;
use reth_chainspec::EthChainSpec;
use reth_consensus_debug_client::{DebugConsensusClient, EtherscanBlockProvider};
Expand Down Expand Up @@ -331,13 +333,20 @@ where
// extract the jwt secret from the args if possible
let jwt_secret = ctx.auth_jwt_secret()?;

#[cfg(not(feature = "bsc"))]
let bsc_trace_helper = None;
#[cfg(feature = "bsc")]
let bsc_trace_helper =
Some(BscTraceHelper::new(Arc::new(ctx.components().parlia().clone())));

// Start RPC servers
let (rpc_server_handles, rpc_registry) = launch_rpc_servers(
ctx.node_adapter().clone(),
engine_api,
ctx.node_config(),
jwt_secret,
rpc,
bsc_trace_helper,
)
.await?;

Expand Down
9 changes: 9 additions & 0 deletions crates/node/builder/src/launch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ use reth_beacon_consensus::{
};
use reth_blockchain_tree::{noop::NoopBlockchainTree, BlockchainTreeConfig};
#[cfg(feature = "bsc")]
use reth_bsc_consensus::BscTraceHelper;
#[cfg(feature = "bsc")]
use reth_bsc_engine::ParliaEngineBuilder;
use reth_chainspec::EthChainSpec;
use reth_consensus_debug_client::{DebugConsensusClient, EtherscanBlockProvider, RpcBlockProvider};
Expand Down Expand Up @@ -384,13 +386,20 @@ where
// extract the jwt secret from the args if possible
let jwt_secret = ctx.auth_jwt_secret()?;

#[cfg(not(feature = "bsc"))]
let bsc_trace_helper = None;
#[cfg(feature = "bsc")]
let bsc_trace_helper =
Some(BscTraceHelper::new(Arc::new(ctx.components().parlia().clone())));

// Start RPC servers
let (rpc_server_handles, rpc_registry) = crate::rpc::launch_rpc_servers(
ctx.node_adapter().clone(),
engine_api,
ctx.node_config(),
jwt_secret,
rpc,
bsc_trace_helper,
)
.await?;

Expand Down
3 changes: 3 additions & 0 deletions crates/node/builder/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::{
};

use futures::TryFutureExt;
use reth_bsc_consensus::BscTraceHelper;
use reth_node_api::{BuilderProvider, FullNodeComponents, NodeTypes, NodeTypesWithEngine};
use reth_node_core::{
node_config::NodeConfig,
Expand Down Expand Up @@ -299,6 +300,7 @@ pub async fn launch_rpc_servers<Node, Engine, EthApi>(
config: &NodeConfig<<Node::Types as NodeTypes>::ChainSpec>,
jwt_secret: JwtSecret,
add_ons: RpcAddOns<Node, EthApi>,
bsc_trace_helper: Option<BscTraceHelper>,
) -> eyre::Result<(RethRpcServerHandles, RpcRegistry<Node, EthApi>)>
where
Node: FullNodeComponents<Types: ProviderNodeTypes> + Clone,
Expand All @@ -317,6 +319,7 @@ where
.with_executor(node.task_executor().clone())
.with_evm_config(node.evm_config().clone())
.with_block_executor(node.block_executor().clone())
.with_bsc_trace_helper(bsc_trace_helper)
.build_with_auth_server(module_config, engine_api, EthApi::eth_api_builder());

let mut registry = RpcRegistry { registry };
Expand Down
3 changes: 3 additions & 0 deletions crates/rpc/rpc-builder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ reth-evm.workspace = true
reth-engine-primitives.workspace = true
reth-primitives.workspace = true

# bsc
reth-bsc-consensus.workspace = true

# ethereum
alloy-network.workspace = true
alloy-rpc-types.workspace = true
Expand Down
3 changes: 3 additions & 0 deletions crates/rpc/rpc-builder/src/eth.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::marker::PhantomData;

use reth_bsc_consensus::BscTraceHelper;
use reth_evm::ConfigureEvm;
use reth_primitives::Header;
use reth_provider::{BlockReader, CanonStateSubscriptions, EvmEnvProvider, StateProviderFactory};
Expand Down Expand Up @@ -57,6 +58,7 @@ where
Events,
EthApi,
>,
bsc_trace_helper: Option<BscTraceHelper>,
) -> Self
where
EvmConfig: ConfigureEvm<Header = Header>,
Expand Down Expand Up @@ -87,6 +89,7 @@ where
executor,
events,
cache,
bsc_trace_helper,
_rpc_ty_builders: PhantomData,
};

Expand Down
Loading

0 comments on commit 0d0a4d3

Please sign in to comment.