mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 19:09:54 +00:00
fix: enforce unsupported fork rules on get_payload_v3 (#4562)
This commit is contained in:
@ -412,6 +412,10 @@ where
|
||||
build_empty_payload(&self.client, self.config.clone()).map(Arc::new)
|
||||
}
|
||||
|
||||
fn payload_attributes(&self) -> Result<PayloadBuilderAttributes, PayloadBuilderError> {
|
||||
Ok(self.config.attributes.clone())
|
||||
}
|
||||
|
||||
fn resolve(&mut self) -> (Self::ResolvePayloadFuture, KeepPayloadJobAlive) {
|
||||
let best_payload = self.best_payload.take();
|
||||
let maybe_better = self.pending_block.take();
|
||||
|
||||
@ -86,6 +86,10 @@
|
||||
//! Ok(Arc::new(payload))
|
||||
//! }
|
||||
//!
|
||||
//! fn payload_attributes(&self) -> Result<PayloadBuilderAttributes, PayloadBuilderError> {
|
||||
//! Ok(self.attributes.clone())
|
||||
//! }
|
||||
//!
|
||||
//! fn resolve(&mut self) -> (Self::ResolvePayloadFuture, KeepPayloadJobAlive) {
|
||||
//! let payload = self.best_payload();
|
||||
//! (futures_util::future::ready(payload), KeepPayloadJobAlive::No)
|
||||
|
||||
@ -48,6 +48,16 @@ impl PayloadStore {
|
||||
) -> Option<Result<Arc<BuiltPayload>, PayloadBuilderError>> {
|
||||
self.inner.best_payload(id).await
|
||||
}
|
||||
|
||||
/// Returns the payload attributes associated with the given identifier.
|
||||
///
|
||||
/// Note: this returns the attributes of the payload and does not resolve the job.
|
||||
pub async fn payload_attributes(
|
||||
&self,
|
||||
id: PayloadId,
|
||||
) -> Option<Result<PayloadBuilderAttributes, PayloadBuilderError>> {
|
||||
self.inner.payload_attributes(id).await
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PayloadBuilderHandle> for PayloadStore {
|
||||
@ -94,6 +104,18 @@ impl PayloadBuilderHandle {
|
||||
rx.await.ok()?
|
||||
}
|
||||
|
||||
/// Returns the payload attributes associated with the given identifier.
|
||||
///
|
||||
/// Note: this returns the attributes of the payload and does not resolve the job.
|
||||
pub async fn payload_attributes(
|
||||
&self,
|
||||
id: PayloadId,
|
||||
) -> Option<Result<PayloadBuilderAttributes, PayloadBuilderError>> {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
self.to_service.send(PayloadServiceCommand::PayloadAttributes(id, tx)).ok()?;
|
||||
rx.await.ok()?
|
||||
}
|
||||
|
||||
/// Sends a message to the service to start building a new payload for the given payload.
|
||||
///
|
||||
/// This is the same as [PayloadBuilderHandle::new_payload] but does not wait for the result and
|
||||
@ -178,6 +200,17 @@ where
|
||||
self.payload_jobs.iter().find(|(_, job_id)| *job_id == id).map(|(j, _)| j.best_payload())
|
||||
}
|
||||
|
||||
/// Returns the payload attributes for the given payload.
|
||||
fn payload_attributes(
|
||||
&self,
|
||||
id: PayloadId,
|
||||
) -> Option<Result<PayloadBuilderAttributes, PayloadBuilderError>> {
|
||||
self.payload_jobs
|
||||
.iter()
|
||||
.find(|(_, job_id)| *job_id == id)
|
||||
.map(|(j, _)| j.payload_attributes())
|
||||
}
|
||||
|
||||
/// Returns the best payload for the given identifier that has been built so far and terminates
|
||||
/// the job if requested.
|
||||
fn resolve(&mut self, id: PayloadId) -> Option<PayloadFuture> {
|
||||
@ -262,6 +295,9 @@ where
|
||||
PayloadServiceCommand::BestPayload(id, tx) => {
|
||||
let _ = tx.send(this.best_payload(id));
|
||||
}
|
||||
PayloadServiceCommand::PayloadAttributes(id, tx) => {
|
||||
let _ = tx.send(this.payload_attributes(id));
|
||||
}
|
||||
PayloadServiceCommand::Resolve(id, tx) => {
|
||||
let _ = tx.send(this.resolve(id));
|
||||
}
|
||||
@ -287,6 +323,11 @@ enum PayloadServiceCommand {
|
||||
),
|
||||
/// Get the best payload so far
|
||||
BestPayload(PayloadId, oneshot::Sender<Option<Result<Arc<BuiltPayload>, PayloadBuilderError>>>),
|
||||
/// Get the payload attributes for the given payload
|
||||
PayloadAttributes(
|
||||
PayloadId,
|
||||
oneshot::Sender<Option<Result<PayloadBuilderAttributes, PayloadBuilderError>>>,
|
||||
),
|
||||
/// Resolve the payload and return the payload
|
||||
Resolve(PayloadId, oneshot::Sender<Option<PayloadFuture>>),
|
||||
}
|
||||
|
||||
@ -68,6 +68,10 @@ impl PayloadJob for TestPayloadJob {
|
||||
)))
|
||||
}
|
||||
|
||||
fn payload_attributes(&self) -> Result<PayloadBuilderAttributes, PayloadBuilderError> {
|
||||
Ok(self.attr.clone())
|
||||
}
|
||||
|
||||
fn resolve(&mut self) -> (Self::ResolvePayloadFuture, KeepPayloadJobAlive) {
|
||||
let fut = futures_util::future::ready(self.best_payload());
|
||||
(fut, KeepPayloadJobAlive::No)
|
||||
|
||||
@ -26,6 +26,9 @@ pub trait PayloadJob: Future<Output = Result<(), PayloadBuilderError>> + Send +
|
||||
/// Note: This is never called by the CL.
|
||||
fn best_payload(&self) -> Result<Arc<BuiltPayload>, PayloadBuilderError>;
|
||||
|
||||
/// Returns the payload attributes for the payload being built.
|
||||
fn payload_attributes(&self) -> Result<PayloadBuilderAttributes, PayloadBuilderError>;
|
||||
|
||||
/// Called when the payload is requested by the CL.
|
||||
///
|
||||
/// This is invoked on [`engine_getPayloadV2`](https://github.com/ethereum/execution-apis/blob/main/src/engine/shanghai.md#engine_getpayloadv2) and [`engine_getPayloadV1`](https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#engine_getpayloadv1).
|
||||
|
||||
@ -208,6 +208,24 @@ where
|
||||
&self,
|
||||
payload_id: PayloadId,
|
||||
) -> EngineApiResult<ExecutionPayloadEnvelopeV3> {
|
||||
// First we fetch the payload attributes to check the timestamp
|
||||
let attributes = self
|
||||
.inner
|
||||
.payload_store
|
||||
.payload_attributes(payload_id)
|
||||
.await
|
||||
.ok_or(EngineApiError::UnknownPayload)??;
|
||||
|
||||
// From the Engine API spec:
|
||||
// <https://github.com/ethereum/execution-apis/blob/ff43500e653abde45aec0f545564abfb648317af/src/engine/cancun.md#specification-2>
|
||||
//
|
||||
// 1. Client software **MUST** return `-38005: Unsupported fork` error if the `timestamp` of
|
||||
// the built payload does not fall within the time frame of the Cancun fork.
|
||||
if !self.inner.chain_spec.is_cancun_activated_at_timestamp(attributes.timestamp) {
|
||||
return Err(EngineApiError::UnsupportedFork)
|
||||
}
|
||||
|
||||
// Now resolve the payload
|
||||
Ok(self
|
||||
.inner
|
||||
.payload_store
|
||||
|
||||
Reference in New Issue
Block a user