Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(trin-execution): execute multiple blocks in memory + able to execute to merge #1337

Merged
merged 11 commits into from
Sep 8, 2024
Merged
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
Loading