Skip to content

Commit

Permalink
feat(trin-execution): execute multiple blocks in memory + execute to …
Browse files Browse the repository at this point in the history
…merge
  • Loading branch information
KolbyML committed Aug 29, 2024
1 parent e5f9020 commit fce4ca0
Show file tree
Hide file tree
Showing 15 changed files with 662 additions and 520 deletions.
26 changes: 14 additions & 12 deletions portal-bridge/src/bridge/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use ethportal_api::{
types::state_trie::account_state::AccountState as AccountStateInfo, StateContentKey,
StateContentValue,
};
use revm::DatabaseRef;
use revm::Database;
use revm_primitives::{keccak256, Bytecode, SpecId, B256};
use surf::{Client, Config};
use tokio::{
Expand All @@ -24,7 +24,6 @@ use trin_execution::{
create_account_content_key, create_account_content_value, create_contract_content_key,
create_contract_content_value, create_storage_content_key, create_storage_content_value,
},
era::manager::EraManager,
execution::State,
spec_id::get_spec_block_number,
storage::utils::setup_temp_dir,
Expand Down Expand Up @@ -86,10 +85,10 @@ impl StateBridge {
info!("Launching state bridge: {:?}", self.mode);
match self.mode.clone() {
BridgeMode::Single(ModeType::Block(last_block)) => {
if last_block > get_spec_block_number(SpecId::DAO_FORK) {
if last_block > get_spec_block_number(SpecId::MERGE) {
panic!(
"State bridge only supports blocks up to {} for the time being.",
get_spec_block_number(SpecId::DAO_FORK)
get_spec_block_number(SpecId::MERGE)
);
}
self.launch_state(last_block)
Expand All @@ -110,14 +109,10 @@ impl StateBridge {
cache_contract_storage_changes: true,
block_to_trace: BlockToTrace::None,
};
let mut state = State::new(Some(temp_directory.path().to_path_buf()), state_config)?;
let starting_block = 0;
let mut era_manager = EraManager::new(starting_block).await?;
for block_number in starting_block..=last_block {
let mut state = State::new(Some(temp_directory.path().to_path_buf()), state_config).await?;
for block_number in 0..=last_block {
info!("Gossipping state for block at height: {block_number}");

let block = era_manager.get_next_block().await?;

// process block
let RootWithTrieDiff {
root: root_hash,
Expand All @@ -126,8 +121,15 @@ impl StateBridge {
true => state
.initialize_genesis()
.map_err(|e| anyhow!("unable to create genesis state: {e}"))?,
false => state.process_block(block)?,
false => state.process_block(block_number).await?,
};
let block = state
.era_manager
.lock()
.await
.last_fetched_block()
.await?
.clone();

let walk_diff = TrieWalker::new(root_hash, changed_nodes);

Expand Down Expand Up @@ -162,7 +164,7 @@ impl StateBridge {
// if the code_hash is empty then then don't try to gossip the contract bytecode
if account.code_hash != keccak256([]) {
// gossip contract bytecode
let code = state.database.code_by_hash_ref(account.code_hash)?;
let code = state.database.code_by_hash(account.code_hash)?;
self.gossip_contract_bytecode(
address_hash,
&account_proof,
Expand Down
159 changes: 83 additions & 76 deletions portal-bridge/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {

let bridge_config = BridgeConfig::parse();

if bridge_config
.portal_subnetworks
.contains(&NetworkKind::State)
&& bridge_config.portal_subnetworks.len() > 1
{
return Err("The State network doesn't support being ran with the other networks bridges at the same time".into());
}

if let Some(addr) = bridge_config.metrics_url {
prometheus_exporter::start(addr)?;
}
Expand All @@ -41,30 +49,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {

let mut bridge_tasks = Vec::new();

// Launch Beacon Network portal bridge
if bridge_config
.portal_subnetworks
.contains(&NetworkKind::Beacon)
{
let bridge_mode = bridge_config.mode.clone();
let consensus_api = ConsensusApi::new(
bridge_config.cl_provider,
bridge_config.cl_provider_fallback,
)
.await?;
let portal_client_clone = portal_client.clone();
let bridge_handle = tokio::spawn(async move {
let beacon_bridge = BeaconBridge::new(consensus_api, bridge_mode, portal_client_clone);

beacon_bridge
.launch()
.instrument(tracing::trace_span!("beacon"))
.await;
});

bridge_tasks.push(bridge_handle);
}

// Launch State Network portal bridge
if bridge_config
.portal_subnetworks
Expand All @@ -82,65 +66,88 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
bridge_config.gossip_limit,
)
.await?;
let bridge_handle = tokio::spawn(async move {
state_bridge
.launch()
.instrument(tracing::trace_span!("state"))
.await;
});
bridge_tasks.push(bridge_handle);
}

// Launch History Network portal bridge
if bridge_config
.portal_subnetworks
.contains(&NetworkKind::History)
{
let execution_api = ExecutionApi::new(
bridge_config.el_provider,
bridge_config.el_provider_fallback,
)
.await?;
match bridge_config.mode {
BridgeMode::FourFours(_) => {
let header_oracle = HeaderOracle::default();
let era1_bridge = Era1Bridge::new(
bridge_config.mode,
portal_client,
header_oracle,
bridge_config.epoch_acc_path,
bridge_config.gossip_limit,
execution_api,
)
.await?;
let bridge_handle = tokio::spawn(async move {
era1_bridge
.launch()
.instrument(tracing::trace_span!("history(era1)"))
.await;
});
bridge_tasks.push(bridge_handle);
}
_ => {
let bridge_handle = tokio::spawn(async move {
let header_oracle = HeaderOracle::default();
state_bridge
.launch()
.instrument(tracing::trace_span!("state"))
.await;
} else {
// Launch Beacon Network portal bridge
if bridge_config
.portal_subnetworks
.contains(&NetworkKind::Beacon)
{
let bridge_mode = bridge_config.mode.clone();
let consensus_api = ConsensusApi::new(
bridge_config.cl_provider,
bridge_config.cl_provider_fallback,
)
.await?;
let portal_client_clone = portal_client.clone();
let bridge_handle = tokio::spawn(async move {
let beacon_bridge =
BeaconBridge::new(consensus_api, bridge_mode, portal_client_clone);

beacon_bridge
.launch()
.instrument(tracing::trace_span!("beacon"))
.await;
});

bridge_tasks.push(bridge_handle);
}

let bridge = HistoryBridge::new(
// Launch History Network portal bridge
if bridge_config
.portal_subnetworks
.contains(&NetworkKind::History)
{
let execution_api = ExecutionApi::new(
bridge_config.el_provider,
bridge_config.el_provider_fallback,
)
.await?;
match bridge_config.mode {
BridgeMode::FourFours(_) => {
let header_oracle = HeaderOracle::default();
let era1_bridge = Era1Bridge::new(
bridge_config.mode,
execution_api,
portal_client,
header_oracle,
bridge_config.epoch_acc_path,
bridge_config.gossip_limit,
);

bridge
.launch()
.instrument(tracing::trace_span!("history"))
.await;
});

bridge_tasks.push(bridge_handle);
execution_api,
)
.await?;
let bridge_handle = tokio::spawn(async move {
era1_bridge
.launch()
.instrument(tracing::trace_span!("history(era1)"))
.await;
});
bridge_tasks.push(bridge_handle);
}
_ => {
let bridge_handle = tokio::spawn(async move {
let header_oracle = HeaderOracle::default();

let bridge = HistoryBridge::new(
bridge_config.mode,
execution_api,
portal_client,
header_oracle,
bridge_config.epoch_acc_path,
bridge_config.gossip_limit,
);

bridge
.launch()
.instrument(tracing::trace_span!("history"))
.await;
});

bridge_tasks.push(bridge_handle);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1097,4 +1097,4 @@
"uid": "fdqcqby1pyvb4d",
"version": 1,
"weekStart": ""
}
}
1 change: 1 addition & 0 deletions trin-execution/metrics/prometheus/prometheus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ scrape_configs:
- localhost:9091
labels:
instance: local_node

59 changes: 10 additions & 49 deletions trin-execution/src/dao_fork.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
//! DAO Fork related constants from [EIP-779](https://eips.ethereum.org/EIPS/eip-779).
//! It happened on Ethereum block 1_920_000
use alloy_rlp::Decodable;
use eth_trie::Trie;
use ethportal_api::types::state_trie::account_state::AccountState as AccountStateInfo;
use revm_primitives::{address, keccak256, Address, U256};
use revm::{db::State as RevmState, Evm};
use revm_primitives::{address, Address};

use crate::storage::{account::Account, evm_db::EvmDB};
use crate::storage::evm_db::EvmDB;

/// Dao hardfork beneficiary that received ether from accounts from DAO and DAO creator children.
pub static DAO_HARDFORK_BENEFICIARY: Address = address!("bf4ed7b27f1d666546e30d74d50d173d20bca754");
Expand Down Expand Up @@ -131,52 +129,15 @@ pub static DAO_HARDKFORK_ACCOUNTS: [Address; 116] = [
address!("807640a13483f8ac783c557fcdf27be11ea4ac7a"),
];

pub fn process_dao_fork(database: &EvmDB) -> anyhow::Result<()> {
let mut drained_balance_sum = U256::ZERO;

// drain dao accounts
for address in DAO_HARDKFORK_ACCOUNTS {
let address_hash = keccak256(address);
let mut account: Account = match database
.db
.get(address_hash)
.expect("Reading account from database should never fail")
{
Some(raw_account) => Decodable::decode(&mut raw_account.as_slice())?,
None => Account::default(),
};

drained_balance_sum += account.balance;
account.balance = U256::ZERO;

let _ = database.trie.lock().insert(
address_hash.as_ref(),
&alloy_rlp::encode(AccountStateInfo::from(&account)),
);

database.db.put(address_hash, alloy_rlp::encode(account))?;
}
pub fn process_dao_fork(database: &mut Evm<(), RevmState<EvmDB>>) -> anyhow::Result<()> {
// drain balances from DAO hardfork accounts
let drained_balances = database.db_mut().drain_balances(DAO_HARDKFORK_ACCOUNTS)?;
let drained_balance_sum: u128 = drained_balances.iter().sum();

// transfer drained balance to beneficiary
let address_hash = keccak256(DAO_HARDFORK_BENEFICIARY);

let mut account: Account = match database
.db
.get(address_hash)
.expect("Reading account from database should never fail")
{
Some(raw_account) => Decodable::decode(&mut raw_account.as_slice())?,
None => Account::default(),
};

account.balance += drained_balance_sum;

let _ = database.trie.lock().insert(
address_hash.as_ref(),
&alloy_rlp::encode(AccountStateInfo::from(&account)),
);

database.db.put(address_hash, alloy_rlp::encode(account))?;
database
.db_mut()
.increment_balances([(DAO_HARDFORK_BENEFICIARY, drained_balance_sum)].into_iter())?;

Ok(())
}
11 changes: 11 additions & 0 deletions trin-execution/src/era/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,17 @@ impl EraManager {
self.next_block_number
}

pub async fn last_fetched_block(&self) -> anyhow::Result<&ProcessedBlock> {
let Some(current_era) = &self.current_era else {
panic!("current_era should be initialized in EraManager::new");
};
ensure!(
self.next_block_number > 0,
"next_block_number should be greater than 0"
);
Ok(current_era.get_block(self.next_block_number - 1))
}

pub async fn get_next_block(&mut self) -> anyhow::Result<&ProcessedBlock> {
let processed_era = match &self.current_era {
Some(processed_era) if processed_era.contains_block(self.next_block_number) => {
Expand Down
Loading

0 comments on commit fce4ca0

Please sign in to comment.