diff --git a/docs/CUSTOM_RPC_METHODS.md b/docs/CUSTOM_RPC_METHODS.md index 6a7db218..33927ed9 100644 --- a/docs/CUSTOM_RPC_METHODS.md +++ b/docs/CUSTOM_RPC_METHODS.md @@ -85,3 +85,34 @@ Next page response: ``` In the last page response `next_page_token` field will be `null`. +# view_receipt_record + +The `view_receipt_record` method is a custom method that allows you to view the record of the receipt by its ID. + +## How to use it +### Example + +Request: +```json +{ + "jsonrpc": "2.0", + "id": "dontcare", + "method": "view_receipt_record", + "params": { + "receipt_id": "6aB1XxfnhuQ83FWHb5xyqssGnaD5CUQgxHpbAVJFRrPe" + } +} +``` +Response: +```json +{ + "id": "dontcare", + "jsonrpc": "2.0", + "result": { + "block_height": 118875440, + "parent_transaction_hash": "6iJgcM5iZrWuhG4ZpUyX6ivtMQUho2S1JRdBYdY7Y7vX", + "receipt_id": "6aB1XxfnhuQ83FWHb5xyqssGnaD5CUQgxHpbAVJFRrPe", + "shard_id": 0 + } +} +``` diff --git a/readnode-primitives/src/lib.rs b/readnode-primitives/src/lib.rs index 4f73080c..aba339d1 100644 --- a/readnode-primitives/src/lib.rs +++ b/readnode-primitives/src/lib.rs @@ -177,6 +177,7 @@ pub struct QueryData { pub block_height: near_indexer_primitives::types::BlockHeight, pub block_hash: CryptoHash, } + pub struct ReceiptRecord { pub receipt_id: CryptoHash, pub parent_transaction_hash: CryptoHash, diff --git a/rpc-server/src/main.rs b/rpc-server/src/main.rs index ea7971b0..0142af2d 100644 --- a/rpc-server/src/main.rs +++ b/rpc-server/src/main.rs @@ -91,6 +91,10 @@ async fn main() -> anyhow::Result<()> { "view_state_paginated", modules::state::methods::view_state_paginated, ) + .with_method( + "view_receipt_record", + modules::receipts::methods::view_receipt_record, + ) // requests methods .with_method("query", modules::queries::methods::query) // basic requests methods diff --git a/rpc-server/src/modules/receipts/methods.rs b/rpc-server/src/modules/receipts/methods.rs index 84733987..422b5291 100644 --- a/rpc-server/src/modules/receipts/methods.rs +++ b/rpc-server/src/modules/receipts/methods.rs @@ -31,6 +31,23 @@ pub async fn receipt( Ok(result.map_err(near_jsonrpc::primitives::errors::RpcError::from)?) } +/// Fetches a receipt record by it's ID +#[cfg_attr(feature = "tracing-instrumentation", tracing::instrument(skip(data)))] +pub async fn view_receipt_record( + data: Data, + Params(params): Params, +) -> Result { + tracing::debug!("`view_receipt_record` call. Params: {:?}", params); + let receipt_request = + near_jsonrpc::primitives::types::receipts::RpcReceiptRequest::parse(params)?; + + let result = fetch_receipt_record(&data, &receipt_request, "view_receipt_record").await; + + Ok(result + .map_err(near_jsonrpc::primitives::errors::RpcError::from)? + .into()) +} + #[cfg_attr(feature = "tracing-instrumentation", tracing::instrument(skip(data)))] async fn fetch_receipt( data: &Data, @@ -41,16 +58,7 @@ async fn fetch_receipt( > { let receipt_id = request.receipt_reference.receipt_id; - let receipt_record = data - .db_manager - .get_receipt_by_id(receipt_id, "EXPERIMENTAL_receipt") - .await - .map_err(|err| { - tracing::warn!("Error in `receipt` call: {:?}", err); - near_jsonrpc::primitives::types::receipts::RpcReceiptError::UnknownReceipt { - receipt_id, - } - })?; + let receipt_record = fetch_receipt_record(data, request, "EXPERIMENTAL_receipt").await?; // Getting the raw Vec of the TransactionDetails from ScyllaDB let transaction_details = data @@ -85,3 +93,25 @@ async fn fetch_receipt( Ok(near_jsonrpc::primitives::types::receipts::RpcReceiptResponse { receipt_view }) } + +#[cfg_attr(feature = "tracing-instrumentation", tracing::instrument(skip(data)))] +async fn fetch_receipt_record( + data: &Data, + request: &near_jsonrpc::primitives::types::receipts::RpcReceiptRequest, + method_name: &str, +) -> Result< + readnode_primitives::ReceiptRecord, + near_jsonrpc::primitives::types::receipts::RpcReceiptError, +> { + let receipt_id = request.receipt_reference.receipt_id; + + data.db_manager + .get_receipt_by_id(receipt_id, method_name) + .await + .map_err(|err| { + tracing::warn!("Error in `{}` call: {:?}", method_name, err); + near_jsonrpc::primitives::types::receipts::RpcReceiptError::UnknownReceipt { + receipt_id, + } + }) +} diff --git a/rpc-server/src/modules/receipts/mod.rs b/rpc-server/src/modules/receipts/mod.rs index 93d46dac..1a54123b 100644 --- a/rpc-server/src/modules/receipts/mod.rs +++ b/rpc-server/src/modules/receipts/mod.rs @@ -1 +1,20 @@ pub mod methods; + +#[derive(serde::Serialize, serde::Deserialize, Debug)] +pub struct RpcReceiptRecordResponse { + pub receipt_id: near_indexer_primitives::CryptoHash, + pub parent_transaction_hash: near_indexer_primitives::CryptoHash, + pub block_height: near_indexer_primitives::types::BlockHeight, + pub shard_id: near_indexer_primitives::types::ShardId, +} + +impl From for RpcReceiptRecordResponse { + fn from(receipt: readnode_primitives::ReceiptRecord) -> Self { + Self { + receipt_id: receipt.receipt_id, + parent_transaction_hash: receipt.parent_transaction_hash, + block_height: receipt.block_height, + shard_id: receipt.shard_id, + } + } +}