Skip to content

Commit

Permalink
chore(derive): online module touchups (#265)
Browse files Browse the repository at this point in the history
  • Loading branch information
refcell authored Jun 16, 2024
1 parent 1b5b2ea commit 3fe24f4
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 47 deletions.
25 changes: 13 additions & 12 deletions crates/derive/src/online/beacon_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::types::{
IndexedBlobHash,
};
use alloc::{boxed::Box, format, string::String, vec::Vec};
use anyhow::{anyhow, Result};
use async_trait::async_trait;
use reqwest::Client;

Expand All @@ -21,10 +22,10 @@ pub(crate) const SIDECARS_METHOD_PREFIX: &str = "eth/v1/beacon/blob_sidecars";
#[async_trait]
pub trait BeaconClient {
/// Returns the config spec.
async fn config_spec(&self) -> anyhow::Result<APIConfigResponse>;
async fn config_spec(&self) -> Result<APIConfigResponse>;

/// Returns the beacon genesis.
async fn beacon_genesis(&self) -> anyhow::Result<APIGenesisResponse>;
async fn beacon_genesis(&self) -> Result<APIGenesisResponse>;

/// Fetches blob sidecars that were confirmed in the specified L1 block with the given indexed
/// hashes. Order of the returned sidecars is guaranteed to be that of the hashes. Blob data is
Expand All @@ -33,7 +34,7 @@ pub trait BeaconClient {
&self,
slot: u64,
hashes: &[IndexedBlobHash],
) -> anyhow::Result<Vec<APIBlobSidecar>>;
) -> Result<Vec<APIBlobSidecar>>;
}

/// An online implementation of the [BeaconClient] trait.
Expand All @@ -54,42 +55,42 @@ impl OnlineBeaconClient {

#[async_trait]
impl BeaconClient for OnlineBeaconClient {
async fn config_spec(&self) -> anyhow::Result<APIConfigResponse> {
async fn config_spec(&self) -> Result<APIConfigResponse> {
self.inner
.get(format!("{}/{}", self.base, SPEC_METHOD))
.send()
.await
.map_err(|e| anyhow::anyhow!(e))?
.map_err(|e| anyhow!(e))?
.json::<APIConfigResponse>()
.await
.map_err(|e| anyhow::anyhow!(e))
.map_err(|e| anyhow!(e))
}

async fn beacon_genesis(&self) -> anyhow::Result<APIGenesisResponse> {
async fn beacon_genesis(&self) -> Result<APIGenesisResponse> {
self.inner
.get(format!("{}/{}", self.base, GENESIS_METHOD))
.send()
.await
.map_err(|e| anyhow::anyhow!(e))?
.map_err(|e| anyhow!(e))?
.json::<APIGenesisResponse>()
.await
.map_err(|e| anyhow::anyhow!(e))
.map_err(|e| anyhow!(e))
}

async fn beacon_blob_side_cars(
&self,
slot: u64,
hashes: &[IndexedBlobHash],
) -> anyhow::Result<Vec<APIBlobSidecar>> {
) -> Result<Vec<APIBlobSidecar>> {
let raw_response = self
.inner
.get(format!("{}/{}/{}", self.base, SIDECARS_METHOD_PREFIX, slot))
.send()
.await
.map_err(|e| anyhow::anyhow!(e))?
.map_err(|e| anyhow!(e))?
.json::<APIGetBlobSidecarsResponse>()
.await
.map_err(|e| anyhow::anyhow!(e))?;
.map_err(|e| anyhow!(e))?;

let mut sidecars = Vec::with_capacity(hashes.len());

Expand Down
17 changes: 6 additions & 11 deletions crates/derive/src/online/blob_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ use crate::{
types::{APIBlobSidecar, Blob, BlobProviderError, BlobSidecar, BlockInfo, IndexedBlobHash},
};
use alloc::{boxed::Box, vec::Vec};
use anyhow::{anyhow, ensure};
use async_trait::async_trait;
use core::marker::PhantomData;
use tracing::debug;

/// Specifies the derivation of a slot from a timestamp.
pub trait SlotDerivation {
Expand Down Expand Up @@ -42,11 +42,9 @@ impl<B: BeaconClient, S: SlotDerivation> OnlineBlobProvider<B, S> {
/// Loads the beacon genesis and config spec
pub async fn load_configs(&mut self) -> Result<(), BlobProviderError> {
if self.genesis_time.is_none() {
debug!("Loading missing BeaconGenesis");
self.genesis_time = Some(self.beacon_client.beacon_genesis().await?.data.genesis_time);
}
if self.slot_interval.is_none() {
debug!("Loading missing ConfigSpec");
self.slot_interval =
Some(self.beacon_client.config_spec().await?.data.seconds_per_slot);
}
Expand Down Expand Up @@ -108,13 +106,10 @@ pub struct SimpleSlotDerivation;

impl SlotDerivation for SimpleSlotDerivation {
fn slot(genesis: u64, slot_time: u64, timestamp: u64) -> anyhow::Result<u64> {
if timestamp < genesis {
return Err(anyhow::anyhow!(
"provided timestamp ({}) precedes genesis time ({})",
timestamp,
genesis
));
}
ensure!(
timestamp >= genesis,
"provided timestamp ({timestamp}) precedes genesis time ({genesis})"
);
Ok((timestamp - genesis) / slot_time)
}
}
Expand Down Expand Up @@ -145,7 +140,7 @@ where
.into_iter()
.enumerate()
.map(|(i, sidecar)| {
let hash = blob_hashes.get(i).ok_or(anyhow::anyhow!("failed to get blob hash"))?;
let hash = blob_hashes.get(i).ok_or(anyhow!("failed to get blob hash"))?;
match sidecar.verify_blob(hash) {
Ok(_) => Ok(sidecar.blob),
Err(e) => Err(e),
Expand Down
2 changes: 1 addition & 1 deletion crates/derive/src/online/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub use crate::{
sources::EthereumDataSource,
stages::StatefulAttributesBuilder,
traits::{ChainProvider, L2ChainProvider, OriginProvider, Pipeline},
types::RollupConfig,
types::{BlockInfo, RollupConfig},
};

mod pipeline;
Expand Down
20 changes: 8 additions & 12 deletions crates/derive/src/online/pipeline.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
//! Contains online pipeline types.
use crate::{
online::{
AlloyChainProvider, AlloyL2ChainProvider, OnlineBeaconClient, OnlineBlobProvider,
SimpleSlotDerivation,
},
pipeline::{DerivationPipeline, PipelineBuilder},
sources::EthereumDataSource,
stages::{
AttributesQueue, BatchQueue, ChannelBank, ChannelReader, FrameQueue, L1Retrieval,
L1Traversal, StatefulAttributesBuilder,
},
types::{BlockInfo, RollupConfig},
use super::{
AlloyChainProvider, AlloyL2ChainProvider, BlockInfo, DerivationPipeline, EthereumDataSource,
OnlineBeaconClient, OnlineBlobProvider, PipelineBuilder, RollupConfig, SimpleSlotDerivation,
StatefulAttributesBuilder,
};
use alloc::sync::Arc;
// Pipeline internal stages aren't re-exported at the module-level.
use crate::stages::{
AttributesQueue, BatchQueue, ChannelBank, ChannelReader, FrameQueue, L1Retrieval, L1Traversal,
};

/// An online derivation pipeline.
pub type OnlinePipeline =
Expand Down
20 changes: 9 additions & 11 deletions crates/derive/src/online/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use alloy_node_bindings::{Anvil, AnvilInstance};
use alloy_provider::{network::Ethereum, ReqwestProvider};
use alloy_rpc_client::RpcClient;
use alloy_transport_http::Http;
use anyhow::{anyhow, Result};
use async_trait::async_trait;
use reqwest::Client;

Expand Down Expand Up @@ -46,22 +47,19 @@ pub struct MockBeaconClient {

#[async_trait]
impl BeaconClient for MockBeaconClient {
async fn config_spec(&self) -> anyhow::Result<APIConfigResponse> {
self.config_spec.clone().ok_or_else(|| anyhow::anyhow!("config_spec not set"))
async fn config_spec(&self) -> Result<APIConfigResponse> {
self.config_spec.clone().ok_or_else(|| anyhow!("config_spec not set"))
}

async fn beacon_genesis(&self) -> anyhow::Result<APIGenesisResponse> {
self.beacon_genesis.clone().ok_or_else(|| anyhow::anyhow!("beacon_genesis not set"))
async fn beacon_genesis(&self) -> Result<APIGenesisResponse> {
self.beacon_genesis.clone().ok_or_else(|| anyhow!("beacon_genesis not set"))
}

async fn beacon_blob_side_cars(
&self,
_slot: u64,
_hashes: &[IndexedBlobHash],
) -> anyhow::Result<Vec<APIBlobSidecar>> {
self.blob_sidecars
.clone()
.ok_or_else(|| anyhow::anyhow!("blob_sidecars not set"))
.map(|r| r.data)
_: u64,
_: &[IndexedBlobHash],
) -> Result<Vec<APIBlobSidecar>> {
self.blob_sidecars.clone().ok_or_else(|| anyhow!("blob_sidecars not set")).map(|r| r.data)
}
}

0 comments on commit 3fe24f4

Please sign in to comment.