diff --git a/crates/rpc/src/context.rs b/crates/rpc/src/context.rs index 53dfbbfce6..8ee1dc396d 100644 --- a/crates/rpc/src/context.rs +++ b/crates/rpc/src/context.rs @@ -8,6 +8,8 @@ use pathfinder_storage::Storage; use std::num::NonZeroUsize; use std::sync::Arc; +pub(crate) mod get_block_with_receipts; + type SequencerClient = starknet_gateway_client::Client; use tokio::sync::watch as tokio_watch; diff --git a/crates/rpc/src/context/get_block_with_receipts.rs b/crates/rpc/src/context/get_block_with_receipts.rs new file mode 100644 index 0000000000..7c52d2f6a7 --- /dev/null +++ b/crates/rpc/src/context/get_block_with_receipts.rs @@ -0,0 +1,25 @@ +use pathfinder_common::{ + receipt::Receipt, transaction::Transaction, BlockHeader, BlockId, PendingBlockHeader, +}; + +#[derive(Debug, Clone, PartialEq)] +pub(crate) enum BlockWithReceipts { + Full { + header: BlockHeader, + body: Vec<(Transaction, Receipt)>, + is_l1_accepted: bool, + }, + Pending { + header: PendingBlockHeader, + body: Vec<(Transaction, Receipt)>, + }, +} + +impl super::RpcContext { + pub(crate) async fn get_block_with_receipts( + &self, + block: BlockId, + ) -> anyhow::Result> { + todo!(); + } +} diff --git a/crates/rpc/src/v07.rs b/crates/rpc/src/v07.rs index afbe4a8c3c..9157138e1b 100644 --- a/crates/rpc/src/v07.rs +++ b/crates/rpc/src/v07.rs @@ -1,4 +1,5 @@ pub mod dto; +pub mod method; use crate::jsonrpc::{RpcRouter, RpcRouterBuilder}; @@ -34,9 +35,10 @@ pub fn register_routes() -> RpcRouterBuilder { // .register("starknet_getTransactionByHash" , method::get_transaction_by_hash) // .register("starknet_getTransactionReceipt" , method::get_transaction_receipt) // .register("starknet_simulateTransactions" , method::simulate_transactions) - .register("starknet_specVersion" , || "0.7.0-rc0") + .register("starknet_specVersion", || "0.7.0-rc0") // .register("starknet_traceBlockTransactions" , method::trace_block_transactions) // .register("starknet_traceTransaction" , method::trace_transaction) + .register("starknet_getBlockWithReceipts", method::get_block_with_receipts) - .register("pathfinder_getProof" , crate::pathfinder::methods::get_proof) + .register("pathfinder_getProof", crate::pathfinder::methods::get_proof) } diff --git a/crates/rpc/src/v07/method.rs b/crates/rpc/src/v07/method.rs new file mode 100644 index 0000000000..b4f9d80587 --- /dev/null +++ b/crates/rpc/src/v07/method.rs @@ -0,0 +1,3 @@ +pub mod get_block_with_receipts; + +pub use get_block_with_receipts::get_block_with_receipts; diff --git a/crates/rpc/src/v07/method/get_block_with_receipts.rs b/crates/rpc/src/v07/method/get_block_with_receipts.rs new file mode 100644 index 0000000000..0d37102171 --- /dev/null +++ b/crates/rpc/src/v07/method/get_block_with_receipts.rs @@ -0,0 +1,81 @@ +use pathfinder_common::BlockId; +use serde::Deserialize; + +use crate::v07::dto; + +use crate::context::{get_block_with_receipts::BlockWithReceipts, RpcContext}; +use crate::v07::dto::transaction::TxnFinalityStatus; + +#[derive(Deserialize, Debug, PartialEq, Eq)] +#[cfg_attr(test, derive(Copy, Clone))] +#[serde(deny_unknown_fields)] +pub struct Input { + block_id: BlockId, +} + +#[derive(Debug, PartialEq)] +pub struct Output(BlockWithReceipts); + +crate::error::generate_rpc_error_subset!(Error: BlockNotFound); + +pub async fn get_block_with_receipts(context: RpcContext, input: Input) -> Result { + context + .get_block_with_receipts(input.block_id) + .await? + .ok_or(Error::BlockNotFound) + .map(Output) +} + +impl serde::Serialize for Output { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + match &self.0 { + BlockWithReceipts::Full { + header, + body, + is_l1_accepted, + } => { + #[derive(serde::Serialize)] + struct Dto<'a> { + #[serde(flatten)] + header: dto::header::Header<'a>, + #[serde(flatten)] + body: dto::transaction::BlockBodyWithReceipts<'a>, + } + + let finality_status = if *is_l1_accepted { + TxnFinalityStatus::AcceptedOnL1 + } else { + TxnFinalityStatus::AcceptedOnL2 + }; + + let header = dto::header::Header(header); + let body = dto::transaction::BlockBodyWithReceipts { + transaction_data: body, + finality_status, + }; + + Dto { header, body }.serialize(serializer) + } + BlockWithReceipts::Pending { header, body } => { + #[derive(serde::Serialize)] + struct Dto<'a> { + #[serde(flatten)] + header: dto::header::PendingHeader<'a>, + #[serde(flatten)] + body: dto::transaction::BlockBodyWithReceipts<'a>, + } + + let header = dto::header::PendingHeader(header); + let body = dto::transaction::BlockBodyWithReceipts { + transaction_data: body, + finality_status: TxnFinalityStatus::AcceptedOnL2, + }; + + Dto { header, body }.serialize(serializer) + } + } + } +}