Skip to content

Commit

Permalink
Add Taiko support, update dependencies, refactor code, fix bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
johntaiko committed Dec 30, 2024
1 parent b15b302 commit 0773b63
Show file tree
Hide file tree
Showing 12 changed files with 249 additions and 28 deletions.
4 changes: 4 additions & 0 deletions Cargo.lock

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

28 changes: 27 additions & 1 deletion crates/consensus/beacon/src/engine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -935,6 +935,28 @@ where
Ok(())
}

/// Sets the head of the canon chain without any additional checks.
fn taiko_reorg(&self, max_block: BlockNumber) -> RethResult<()> {
let max_header = self.blockchain.sealed_header(max_block)
.inspect_err(|error| {
error!(target: "consensus::engine", %error, "Error getting canonical header for continuous sync");
})?
.ok_or_else(|| ProviderError::HeaderNotFound(max_block.into()))?;
let max_hash = max_header.hash();
self.update_canon_chain(
max_header,
&ForkchoiceState {
head_block_hash: max_hash,
finalized_block_hash: max_hash,
safe_block_hash: max_hash,
},
)?;
self.blockchain.update_block_hashes_and_clear_buffered()?;
self.blockchain.connect_buffered_blocks_to_canonical_hashes()?;
// We are on an optimistic syncing process, better to wait for the next FCU to handle
Ok(())
}

/// Updates the state of the canon chain tracker based on the given head.
///
/// This expects the given head to be the new canonical head.
Expand Down Expand Up @@ -1202,7 +1224,7 @@ where
// client software MUST respond with -38003: `Invalid payload attributes` and MUST NOT
// begin a payload build process. In such an event, the forkchoiceState update MUST NOT
// be rolled back.
if attrs.timestamp() <= head.timestamp {
if attrs.timestamp() < head.timestamp {
return OnForkChoiceUpdated::invalid_payload_attributes()
}

Expand Down Expand Up @@ -1497,6 +1519,10 @@ where
}
};

trace!(target: "consensus::engine", ?sync_target_state, "Check sync target state");
// ignore the finalized block hash if we are in taiko mode
return self.taiko_reorg(ctrl.block_number().unwrap_or_default());

if sync_target_state.finalized_block_hash.is_zero() {
self.set_canonical_head(ctrl.block_number().unwrap_or_default())?;
self.blockchain.update_block_hashes_and_clear_buffered()?;
Expand Down
6 changes: 5 additions & 1 deletion crates/engine/local/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,13 @@ where
V: EngineValidator<N::Engine, Block = BlockTy<N>>,
{
let chain_spec = provider.chain_spec();
let engine_kind =
let mut engine_kind =
if chain_spec.is_optimism() { EngineApiKind::OpStack } else { EngineApiKind::Ethereum };

if chain_spec.is_taiko() {
engine_kind = EngineApiKind::Taiko
}

let persistence_handle =
PersistenceHandle::<N::Primitives>::spawn_service(provider, pruner, sync_metrics_tx);
let canonical_in_memory_state = blockchain_db.canonical_in_memory_state();
Expand Down
6 changes: 5 additions & 1 deletion crates/engine/service/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,13 @@ where
where
V: EngineValidator<N::Engine, Block = BlockTy<N>>,
{
let engine_kind =
let mut engine_kind =
if chain_spec.is_optimism() { EngineApiKind::OpStack } else { EngineApiKind::Ethereum };

if chain_spec.is_taiko() {
engine_kind = EngineApiKind::Taiko
}

let downloader = BasicBlockDownloader::new(client, consensus.clone().as_consensus());

let persistence_handle =
Expand Down
7 changes: 7 additions & 0 deletions crates/engine/tree/src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ pub enum EngineApiKind {
Ethereum,
/// The chain contains Optimism configuration.
OpStack,
/// The chain contains Taiko configuration.
Taiko,
}

impl EngineApiKind {
Expand All @@ -238,6 +240,11 @@ impl EngineApiKind {
pub const fn is_opstack(&self) -> bool {
matches!(self, Self::OpStack)
}

/// Returns true if this is the taiko variant
pub const fn is_taiko(&self) -> bool {
matches!(self, Self::Taiko)
}
}

/// The request variants that the engine API handler can receive.
Expand Down
2 changes: 1 addition & 1 deletion crates/engine/tree/src/tree/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1072,7 +1072,7 @@ where

// For OpStack the proposers are allowed to reorg their own chain at will, so we need to
// always trigger a new payload job if requested.
if self.engine_kind.is_opstack() {
if self.engine_kind.is_opstack() || self.engine_kind.is_taiko() {
if let Some(attr) = attrs {
debug!(target: "engine::tree", head = canonical_header.number(), "handling payload attributes for canonical head");
let updated =
Expand Down
2 changes: 1 addition & 1 deletion crates/rpc/rpc-api/src/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ pub trait DebugApi {
/// Sets the current head of the local chain by block number. Note, this is a destructive action
/// and may severely damage your chain. Use with extreme caution.
#[method(name = "setHead")]
async fn debug_set_head(&self, number: u64) -> RpcResult<()>;
async fn debug_set_head(&self, number: BlockNumberOrTag) -> RpcResult<()>;

/// Sets the rate of mutex profiling.
#[method(name = "setMutexProfileFraction")]
Expand Down
7 changes: 5 additions & 2 deletions crates/rpc/rpc/src/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ use tokio::{
sync::{AcquireError, OwnedSemaphorePermit},
time::sleep,
};
use tracing::info;
/// `debug` API implementation.
///
/// This type provides the functionality for handling `debug` related requests.
Expand Down Expand Up @@ -1113,15 +1114,16 @@ where
Ok(())
}

async fn debug_set_head(&self, number: u64) -> RpcResult<()> {
async fn debug_set_head(&self, number: BlockNumberOrTag) -> RpcResult<()> {
let block_hash = self
.provider()
.block_hash_for_id(number.into())
.map_err(Eth::Error::from_eth_err)
.map_err(Into::into)?
.ok_or_else(|| EthApiError::HeaderNotFound(number.into()))?;

self.inner
let res = self
.inner
.beacon_consensus
.debug_fork_choice_updated(
ForkchoiceState {
Expand All @@ -1135,6 +1137,7 @@ where
.await
.map_err(|op| internal_rpc_err(op.to_string()))
.map_err(EthApiError::other)?;
info!(target: "rpc::eth", "Debug set head: {res:?}");
sleep(Duration::from_secs(1)).await;
Ok(())
}
Expand Down
1 change: 1 addition & 0 deletions crates/taiko/node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ reth-taiko-chainspec.workspace = true
reth-taiko-payload-validator.workspace = true

alloy-rpc-types-engine.workspace = true
alloy-consensus.workspace = true

reth-evm = { workspace = true, features = ["taiko"] }

Expand Down
15 changes: 14 additions & 1 deletion crates/taiko/node/src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
use std::sync::Arc;

use alloy_consensus::{BlockHeader, Header};
use alloy_rpc_types_engine::{ExecutionPayloadSidecar, PayloadError};
use reth_node_builder::{
EngineApiMessageVersion, EngineObjectValidationError, EngineTypes, EngineValidator,
PayloadOrAttributes, PayloadTypes, PayloadValidator,
InvalidPayloadAttributesError, PayloadAttributes, PayloadOrAttributes, PayloadTypes,
PayloadValidator,
};
use reth_payload_builder::EthBuiltPayload;
use reth_payload_primitives::validate_version_specific_fields;
Expand Down Expand Up @@ -105,4 +107,15 @@ where
) -> Result<(), EngineObjectValidationError> {
validate_version_specific_fields(self.chain_spec(), version, attributes.into())
}

fn validate_payload_attributes_against_header(
&self,
attr: &TaikoPayloadAttributes,
header: &Header,
) -> Result<(), InvalidPayloadAttributesError> {
if attr.timestamp() < header.timestamp() {
return Err(InvalidPayloadAttributesError::InvalidTimestamp);
}
Ok(())
}
}
3 changes: 3 additions & 0 deletions crates/taiko/payload/validator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@ workspace = true
reth-chainspec.workspace = true
reth-primitives = { workspace = true, features = ["taiko"] }
reth-payload-validator.workspace = true
reth-rpc-types-compat.workspace = true

# ethereum
alloy-rpc-types-engine.workspace = true
alloy-primitives.workspace = true
alloy-consensus.workspace = true

# taiko
reth-taiko-engine-types.workspace = true
Loading

0 comments on commit 0773b63

Please sign in to comment.