near_api/common/query/
block_rpc.rs

1use near_api_types::Reference;
2use near_openapi_client::types::{
3    BlockId, Finality, JsonRpcRequestForBlock, JsonRpcRequestForBlockMethod,
4    JsonRpcResponseForRpcBlockResponseAndRpcError, RpcBlockRequest, RpcBlockResponse, RpcError,
5};
6use near_openapi_client::Client;
7
8use crate::{
9    advanced::RpcType, common::utils::is_critical_blocks_error, config::RetryResponse,
10    errors::SendRequestError, NetworkConfig,
11};
12
13#[derive(Clone, Debug)]
14pub struct SimpleBlockRpc;
15
16#[async_trait::async_trait]
17impl RpcType for SimpleBlockRpc {
18    type RpcReference = Reference;
19    type Response = RpcBlockResponse;
20    type Error = RpcError;
21    async fn send_query(
22        &self,
23        client: &Client,
24        _network: &NetworkConfig,
25        reference: &Reference,
26    ) -> RetryResponse<RpcBlockResponse, SendRequestError<RpcError>> {
27        let request = match reference {
28            Reference::Optimistic => RpcBlockRequest::Finality(Finality::Optimistic),
29            Reference::NearFinal => RpcBlockRequest::Finality(Finality::NearFinal),
30            Reference::Final => RpcBlockRequest::Finality(Finality::Final),
31            Reference::AtBlock(block) => RpcBlockRequest::BlockId(BlockId::BlockHeight(*block)),
32            Reference::AtBlockHash(block_hash) => {
33                RpcBlockRequest::BlockId(BlockId::CryptoHash((*block_hash).into()))
34            }
35        };
36        let response = client
37            .block(&JsonRpcRequestForBlock {
38                id: "0".to_string(),
39                jsonrpc: "2.0".to_string(),
40                method: JsonRpcRequestForBlockMethod::Block,
41                params: request,
42            })
43            .await
44            .map(|r| r.into_inner());
45        match response {
46            Ok(JsonRpcResponseForRpcBlockResponseAndRpcError::Variant0 { result, .. }) => {
47                RetryResponse::Ok(result)
48            }
49            Ok(JsonRpcResponseForRpcBlockResponseAndRpcError::Variant1 { error, .. }) => {
50                if is_critical_blocks_error(&error) {
51                    RetryResponse::Critical(SendRequestError::ServerError(error))
52                } else {
53                    RetryResponse::Retry(SendRequestError::ServerError(error))
54                }
55            }
56            Err(err) => RetryResponse::Critical(SendRequestError::ClientError(err)),
57        }
58    }
59}