Skip to content

Commit

Permalink
feat(trin-execution): execute multiple blocks in memory + able to exe…
Browse files Browse the repository at this point in the history
…cute to merge (#1337)
  • Loading branch information
KolbyML authored Sep 8, 2024
1 parent 0cb2275 commit d48cb58
Show file tree
Hide file tree
Showing 22 changed files with 941 additions and 738 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.

1 change: 1 addition & 0 deletions ethportal-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ categories = ["cryptography::cryptocurrencies"]
authors = ["https://github.com/ethereum/trin/graphs/contributors"]

[dependencies]
alloy-consensus.workspace = true
alloy-primitives.workspace = true
alloy-rlp.workspace = true
anyhow.workspace = true
Expand Down
9 changes: 5 additions & 4 deletions ethportal-api/src/types/state_trie/account_state.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use alloy_primitives::{keccak256, B256, U256};
use alloy_rlp::{RlpDecodable, RlpEncodable, EMPTY_STRING_CODE};
use alloy_consensus::{constants::KECCAK_EMPTY, EMPTY_ROOT_HASH};
use alloy_primitives::{B256, U256};
use alloy_rlp::{RlpDecodable, RlpEncodable};
use serde::{Deserialize, Serialize};

/// The Account State stored in the state trie.
Expand All @@ -16,8 +17,8 @@ impl Default for AccountState {
Self {
nonce: 0,
balance: U256::ZERO,
storage_root: keccak256([EMPTY_STRING_CODE]),
code_hash: keccak256([]),
storage_root: EMPTY_ROOT_HASH,
code_hash: KECCAK_EMPTY,
}
}
}
41 changes: 20 additions & 21 deletions portal-bridge/src/bridge/state.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
use std::{path::PathBuf, sync::Arc};

use alloy_rlp::Decodable;
use anyhow::anyhow;
use e2store::utils::get_shuffled_era1_files;
use eth_trie::{decode_node, node::Node, RootWithTrieDiff};
use ethportal_api::{
jsonrpsee::http_client::HttpClient,
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,8 +23,7 @@ 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,
execution::TrinExecution,
spec_id::get_spec_block_number,
storage::utils::setup_temp_dir,
trie_walker::TrieWalker,
Expand Down Expand Up @@ -86,10 +84,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,24 +108,24 @@ 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 trin_execution =
TrinExecution::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,
trie_diff: changed_nodes,
} = match block_number == 0 {
true => state
.initialize_genesis()
.map_err(|e| anyhow!("unable to create genesis state: {e}"))?,
false => state.process_block(block)?,
};
} = trin_execution.process_next_block().await?;

let block = trin_execution
.era_manager
.lock()
.await
.last_fetched_block()
.await?
.clone();

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

Expand Down Expand Up @@ -162,7 +160,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 = trin_execution.database.code_by_hash(account.code_hash)?;
self.gossip_contract_bytecode(
address_hash,
&account_proof,
Expand All @@ -174,7 +172,8 @@ impl StateBridge {
}

// gossip contract storage
let storage_changed_nodes = state.database.get_storage_trie_diff(address_hash);
let storage_changed_nodes =
trin_execution.database.get_storage_trie_diff(address_hash);

let storage_walk_diff =
TrieWalker::new(account.storage_root, storage_changed_nodes);
Expand All @@ -193,7 +192,7 @@ impl StateBridge {

// flush the database cache
// This is used for gossiping storage trie diffs
state.database.storage_cache.clear();
trin_execution.database.storage_cache.clear();
}
Ok(())
}
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

Loading

0 comments on commit d48cb58

Please sign in to comment.