diff --git a/crates/rpc/src/context/get_block_with_receipts.rs b/crates/rpc/src/context/get_block_with_receipts.rs index 7c52d2f6a7..fb5044097d 100644 --- a/crates/rpc/src/context/get_block_with_receipts.rs +++ b/crates/rpc/src/context/get_block_with_receipts.rs @@ -1,3 +1,4 @@ +use anyhow::Context; use pathfinder_common::{ receipt::Receipt, transaction::Transaction, BlockHeader, BlockId, PendingBlockHeader, }; @@ -11,15 +12,69 @@ pub(crate) enum BlockWithReceipts { }, Pending { header: PendingBlockHeader, + // TODO: consider making this an Arc so we can share this better. body: Vec<(Transaction, Receipt)>, }, } impl super::RpcContext { pub(crate) async fn get_block_with_receipts( - &self, - block: BlockId, + self, + block_id: BlockId, ) -> anyhow::Result> { - todo!(); + let span = tracing::Span::current(); + tokio::task::spawn_blocking(move || { + let _g = span.enter(); + let mut db = self + .storage + .connection() + .context("Creating database connection")?; + + let db = db.transaction().context("Creating database transaction")?; + + let block_id = match block_id { + BlockId::Pending => { + let pending = self + .pending_data + .get(&db) + .context("Querying pending data")?; + + let body = pending + .block + .transactions + .iter() + .zip(pending.block.transaction_receipts.iter()) + .map(|(t, r)| (t.clone(), r.clone())) + .collect(); + + return Ok(Some(BlockWithReceipts::Pending { + header: pending.pending_header(), + body, + })); + } + other => other.try_into().expect("Only pending cast should fail"), + }; + + let Some(header) = db.block_header(block_id).context("Fetching block header")? else { + return Ok(None); + }; + + let body = db + .transaction_data_for_block(block_id) + .context("Fetching transaction data")? + .context("Transaction data missing")?; + + let is_l1_accepted = db + .block_is_l1_accepted(block_id) + .context("Fetching block finality")?; + + Ok(Some(BlockWithReceipts::Full { + header, + body, + is_l1_accepted, + })) + }) + .await + .context("Joining blocking task")? } } diff --git a/crates/rpc/src/pending.rs b/crates/rpc/src/pending.rs index 077ec1d1cf..9dc457f121 100644 --- a/crates/rpc/src/pending.rs +++ b/crates/rpc/src/pending.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use anyhow::Context; -use pathfinder_common::{BlockHeader, BlockNumber, StateUpdate}; +use pathfinder_common::{BlockHeader, BlockNumber, PendingBlockHeader, StateUpdate}; use pathfinder_storage::Transaction; use starknet_gateway_types::reply::{PendingBlock, Status}; @@ -20,6 +20,17 @@ pub struct PendingData { } impl PendingData { + pub fn pending_header(&self) -> PendingBlockHeader { + PendingBlockHeader { + parent_hash: self.block.parent_hash, + timestamp: self.block.timestamp, + eth_l1_gas_price: self.block.eth_l1_gas_price(), + strk_l1_gas_price: self.block.strk_l1_gas_price().unwrap_or_default(), + sequencer_address: self.block.sequencer_address, + starknet_version: self.block.starknet_version.clone(), + } + } + pub fn header(&self) -> BlockHeader { // Be explicit about fields so that we are forced to check // if any new fields are added.