feat: op-reth (#4377)

Co-authored-by: Roberto Bayardo <bayardo@alum.mit.edu>
Co-authored-by: refcell.eth <abigger87@gmail.com>
Co-authored-by: Roman Krasiuk <rokrassyuk@gmail.com>
Co-authored-by: refcell <refcell@oplabs.co>
Co-authored-by: nicolas <48695862+merklefruit@users.noreply.github.com>
This commit is contained in:
clabby
2023-11-05 18:33:42 +01:00
committed by GitHub
parent 390abf3a44
commit 52670a8b24
105 changed files with 33415 additions and 408 deletions

View File

@ -35,6 +35,7 @@ metrics.workspace = true
tracing.workspace = true
thiserror.workspace = true
schnellru = "0.2"
cfg-if = "1.0.0"
[dev-dependencies]
# reth
@ -49,3 +50,12 @@ reth-revm = { path = "../../revm" }
reth-downloaders = { path = "../../net/downloaders" }
assert_matches.workspace = true
[features]
optimism = [
"reth-consensus-common/optimism",
"reth-primitives/optimism",
"reth-interfaces/optimism",
"reth-provider/optimism",
"reth-rpc-types/optimism",
]

View File

@ -666,12 +666,40 @@ where
Ok(outcome) => {
match outcome {
CanonicalOutcome::AlreadyCanonical { ref header } => {
debug!(
target: "consensus::engine",
fcu_head_num=?header.number,
current_head_num=?self.blockchain.canonical_tip().number,
"Ignoring beacon update to old head"
);
// On Optimism, the proposers are allowed to reorg their own chain at will.
cfg_if::cfg_if! {
if #[cfg(feature = "optimism")] {
if self.chain_spec().is_optimism() {
debug!(
target: "consensus::engine",
fcu_head_num=?header.number,
current_head_num=?self.blockchain.canonical_tip().number,
"[Optimism] Allowing beacon reorg to old head"
);
let _ = self.update_head(header.clone());
self.listeners.notify(
BeaconConsensusEngineEvent::CanonicalChainCommitted(
header.clone(),
elapsed,
),
);
} else {
debug!(
target: "consensus::engine",
fcu_head_num=?header.number,
current_head_num=?self.blockchain.canonical_tip().number,
"Ignoring beacon update to old head"
);
}
} else {
debug!(
target: "consensus::engine",
fcu_head_num=?header.number,
current_head_num=?self.blockchain.canonical_tip().number,
"Ignoring beacon update to old head"
);
}
}
}
CanonicalOutcome::Committed { ref head } => {
debug!(
@ -1045,27 +1073,30 @@ where
// forkchoiceState.headBlockHash and identified via buildProcessId value if
// payloadAttributes is not null and the forkchoice state has been updated successfully.
// The build process is specified in the Payload building section.
let attributes = PayloadBuilderAttributes::new(state.head_block_hash, attrs);
match PayloadBuilderAttributes::try_new(state.head_block_hash, attrs) {
Ok(attributes) => {
// send the payload to the builder and return the receiver for the pending payload
// id, initiating payload job is handled asynchronously
let pending_payload_id = self.payload_builder.send_new_payload(attributes);
// send the payload to the builder and return the receiver for the pending payload id,
// initiating payload job is handled asynchronously
let pending_payload_id = self.payload_builder.send_new_payload(attributes);
// Client software MUST respond to this method call in the following way:
// {
// payloadStatus: {
// status: VALID,
// latestValidHash: forkchoiceState.headBlockHash,
// validationError: null
// },
// payloadId: buildProcessId
// }
//
// if the payload is deemed VALID and the build process has begun.
OnForkChoiceUpdated::updated_with_pending_payload_id(
PayloadStatus::new(PayloadStatusEnum::Valid, Some(state.head_block_hash)),
pending_payload_id,
)
// Client software MUST respond to this method call in the following way:
// {
// payloadStatus: {
// status: VALID,
// latestValidHash: forkchoiceState.headBlockHash,
// validationError: null
// },
// payloadId: buildProcessId
// }
//
// if the payload is deemed VALID and the build process has begun.
OnForkChoiceUpdated::updated_with_pending_payload_id(
PayloadStatus::new(PayloadStatusEnum::Valid, Some(state.head_block_hash)),
pending_payload_id,
)
}
Err(_) => OnForkChoiceUpdated::invalid_payload_attributes(),
}
}
/// When the Consensus layer receives a new block via the consensus gossip protocol,

View File

@ -23,7 +23,7 @@ use reth_interfaces::{
test_utils::{NoopFullBlockClient, TestConsensus},
};
use reth_payload_builder::test_utils::spawn_test_payload_service;
use reth_primitives::{BlockNumber, ChainSpec, PruneModes, B256, U256};
use reth_primitives::{BlockNumber, ChainSpec, PruneModes, Receipt, B256, U256};
use reth_provider::{
providers::BlockchainProvider, test_utils::TestExecutorFactory, BlockExecutor,
BundleStateWithReceipts, ExecutorFactory, ProviderFactory, PrunableBlockExecutor,
@ -210,6 +210,22 @@ where
}
}
fn execute_transactions(
&mut self,
block: &reth_primitives::Block,
total_difficulty: U256,
senders: Option<Vec<reth_primitives::Address>>,
) -> Result<(Vec<Receipt>, u64), BlockExecutionError> {
match self {
EitherBlockExecutor::Left(a) => {
a.execute_transactions(block, total_difficulty, senders)
}
EitherBlockExecutor::Right(b) => {
b.execute_transactions(block, total_difficulty, senders)
}
}
}
fn take_output_state(&mut self) -> BundleStateWithReceipts {
match self {
EitherBlockExecutor::Left(a) => a.take_output_state(),