mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-01-31 10:08:13 -05:00
97 lines
3.5 KiB
Rust
97 lines
3.5 KiB
Rust
use crate::job::EmptyBlockPayloadJob;
|
|
use reth::{
|
|
providers::{BlockReaderIdExt, BlockSource, StateProviderFactory},
|
|
tasks::TaskSpawner,
|
|
transaction_pool::TransactionPool,
|
|
};
|
|
use reth_basic_payload_builder::{BasicPayloadJobGeneratorConfig, PayloadBuilder, PayloadConfig};
|
|
use reth_node_api::PayloadBuilderAttributes;
|
|
use reth_payload_builder::{error::PayloadBuilderError, PayloadJobGenerator};
|
|
use reth_primitives::{BlockNumberOrTag, Bytes, ChainSpec};
|
|
use std::sync::Arc;
|
|
|
|
/// The generator type that creates new jobs that builds empty blocks.
|
|
#[derive(Debug)]
|
|
pub struct EmptyBlockPayloadJobGenerator<Client, Pool, Tasks, Builder> {
|
|
/// The client that can interact with the chain.
|
|
client: Client,
|
|
/// txpool
|
|
pool: Pool,
|
|
/// How to spawn building tasks
|
|
executor: Tasks,
|
|
/// The configuration for the job generator.
|
|
_config: BasicPayloadJobGeneratorConfig,
|
|
/// The chain spec.
|
|
chain_spec: Arc<ChainSpec>,
|
|
/// The type responsible for building payloads.
|
|
///
|
|
/// See [PayloadBuilder]
|
|
builder: Builder,
|
|
}
|
|
|
|
// === impl EmptyBlockPayloadJobGenerator ===
|
|
|
|
impl<Client, Pool, Tasks, Builder> EmptyBlockPayloadJobGenerator<Client, Pool, Tasks, Builder> {
|
|
/// Creates a new [EmptyBlockPayloadJobGenerator] with the given config and custom
|
|
/// [PayloadBuilder]
|
|
pub fn with_builder(
|
|
client: Client,
|
|
pool: Pool,
|
|
executor: Tasks,
|
|
config: BasicPayloadJobGeneratorConfig,
|
|
chain_spec: Arc<ChainSpec>,
|
|
builder: Builder,
|
|
) -> Self {
|
|
Self { client, pool, executor, _config: config, builder, chain_spec }
|
|
}
|
|
}
|
|
|
|
impl<Client, Pool, Tasks, Builder> PayloadJobGenerator
|
|
for EmptyBlockPayloadJobGenerator<Client, Pool, Tasks, Builder>
|
|
where
|
|
Client: StateProviderFactory + BlockReaderIdExt + Clone + Unpin + 'static,
|
|
Pool: TransactionPool + Unpin + 'static,
|
|
Tasks: TaskSpawner + Clone + Unpin + 'static,
|
|
Builder: PayloadBuilder<Pool, Client> + Unpin + 'static,
|
|
<Builder as PayloadBuilder<Pool, Client>>::Attributes: Unpin + Clone,
|
|
<Builder as PayloadBuilder<Pool, Client>>::BuiltPayload: Unpin + Clone,
|
|
{
|
|
type Job = EmptyBlockPayloadJob<Client, Pool, Tasks, Builder>;
|
|
|
|
/// This is invoked when the node receives payload attributes from the beacon node via
|
|
/// `engine_forkchoiceUpdatedV1`
|
|
fn new_payload_job(
|
|
&self,
|
|
attributes: <Builder as PayloadBuilder<Pool, Client>>::Attributes,
|
|
) -> Result<Self::Job, PayloadBuilderError> {
|
|
let parent_block = if attributes.parent().is_zero() {
|
|
// use latest block if parent is zero: genesis block
|
|
self.client
|
|
.block_by_number_or_tag(BlockNumberOrTag::Latest)?
|
|
.ok_or_else(|| PayloadBuilderError::MissingParentBlock(attributes.parent()))?
|
|
.seal_slow()
|
|
} else {
|
|
let block = self
|
|
.client
|
|
.find_block_by_hash(attributes.parent(), BlockSource::Any)?
|
|
.ok_or_else(|| PayloadBuilderError::MissingParentBlock(attributes.parent()))?;
|
|
|
|
// we already know the hash, so we can seal it
|
|
block.seal(attributes.parent())
|
|
};
|
|
let config = PayloadConfig::new(
|
|
Arc::new(parent_block),
|
|
Bytes::default(),
|
|
attributes,
|
|
Arc::clone(&self.chain_spec),
|
|
);
|
|
Ok(EmptyBlockPayloadJob {
|
|
client: self.client.clone(),
|
|
_pool: self.pool.clone(),
|
|
_executor: self.executor.clone(),
|
|
_builder: self.builder.clone(),
|
|
config,
|
|
})
|
|
}
|
|
}
|