1#![allow(unreachable_patterns)]
3
4use base64::{prelude::BASE64_STANDARD, Engine};
5use near_api_types::NearToken;
6use near_openapi_client::types::{
7 RpcBlockError, RpcQueryError, RpcTransactionError, RpcValidatorError,
8};
9use reqwest::StatusCode;
10
11use crate::{config::RetryResponse, errors::SendRequestError};
12
13pub fn to_base64(input: &[u8]) -> String {
14 BASE64_STANDARD.encode(input)
15}
16
17pub fn from_base64(encoded: &str) -> Result<Vec<u8>, base64::DecodeError> {
18 BASE64_STANDARD.decode(encoded)
19}
20
21pub const fn near_data_to_near_token(data: near_api_types::Data<u128>) -> NearToken {
23 NearToken::from_yoctonear(data.data)
24}
25
26pub fn to_retry_error<T, E: std::fmt::Debug + Send + Sync>(
27 err: SendRequestError<E>,
28 is_critical_t: impl Fn(&SendRequestError<E>) -> bool,
29) -> RetryResponse<T, SendRequestError<E>> {
30 if is_critical_t(&err) {
31 RetryResponse::Critical(err)
32 } else {
33 RetryResponse::Retry(err)
34 }
35}
36
37pub fn is_critical_blocks_error(err: &SendRequestError<RpcBlockError>) -> bool {
38 is_critical_json_rpc_error(err, |err| match err {
39 RpcBlockError::UnknownBlock { .. }
40 | RpcBlockError::NotSyncedYet
41 | RpcBlockError::InternalError { .. } => false,
42 _ => false,
43 })
44}
45
46pub fn is_critical_validator_error(err: &SendRequestError<RpcValidatorError>) -> bool {
47 is_critical_json_rpc_error(err, |err| match err {
48 RpcValidatorError::UnknownEpoch
49 | RpcValidatorError::ValidatorInfoUnavailable
50 | RpcValidatorError::InternalError { .. } => false,
51 _ => false,
52 })
53}
54pub fn is_critical_query_error(err: &SendRequestError<RpcQueryError>) -> bool {
55 is_critical_json_rpc_error(err, |err| match err {
56 RpcQueryError::NoSyncedBlocks
57 | RpcQueryError::UnavailableShard { .. }
58 | RpcQueryError::UnknownBlock { .. }
59 | RpcQueryError::InternalError { .. } => false,
60
61 RpcQueryError::GarbageCollectedBlock { .. }
62 | RpcQueryError::InvalidAccount { .. }
63 | RpcQueryError::UnknownAccount { .. }
64 | RpcQueryError::NoContractCode { .. }
65 | RpcQueryError::TooLargeContractState { .. }
66 | RpcQueryError::UnknownAccessKey { .. }
67 | RpcQueryError::ContractExecutionError { .. }
68 | RpcQueryError::UnknownGasKey { .. } => true,
69
70 RpcQueryError::NoGlobalContractCode { .. } => false,
72 _ => false,
73 })
74}
75
76pub fn is_critical_transaction_error(err: &SendRequestError<RpcTransactionError>) -> bool {
77 is_critical_json_rpc_error(err, |err| match err {
78 RpcTransactionError::TimeoutError | RpcTransactionError::RequestRouted { .. } => false,
79 RpcTransactionError::InvalidTransaction { .. }
80 | RpcTransactionError::DoesNotTrackShard
81 | RpcTransactionError::UnknownTransaction { .. }
82 | RpcTransactionError::InternalError { .. } => true,
83 _ => false,
84 })
85}
86
87fn is_critical_json_rpc_error<RpcError: std::fmt::Debug + Send + Sync>(
88 err: &SendRequestError<RpcError>,
89 is_critical_t: impl Fn(&RpcError) -> bool,
90) -> bool {
91 match err {
92 SendRequestError::ServerError(rpc_error) => is_critical_t(rpc_error),
93 SendRequestError::WasmExecutionError(_) => true,
94 SendRequestError::InternalError { .. } => false,
95 SendRequestError::RequestValidationError(_) => true,
96 SendRequestError::RequestCreationError(_) => true,
97 SendRequestError::TransportError(error) => match error {
98 near_openapi_client::Error::InvalidRequest(_)
99 | near_openapi_client::Error::CommunicationError(_)
100 | near_openapi_client::Error::InvalidUpgrade(_)
101 | near_openapi_client::Error::ResponseBodyError(_)
102 | near_openapi_client::Error::InvalidResponsePayload(_, _)
103 | near_openapi_client::Error::UnexpectedResponse(_)
104 | near_openapi_client::Error::Custom(_) => true,
105
106 near_openapi_client::Error::ErrorResponse(response_value) => {
107 #[allow(clippy::match_like_matches_macro)]
109 match response_value.status() {
110 StatusCode::REQUEST_TIMEOUT
111 | StatusCode::TOO_MANY_REQUESTS
112 | StatusCode::INTERNAL_SERVER_ERROR
113 | StatusCode::BAD_GATEWAY
114 | StatusCode::SERVICE_UNAVAILABLE
115 | StatusCode::GATEWAY_TIMEOUT => false,
116 _ => true,
117 }
118 }
119 _ => false,
120 },
121 _ => false,
122 }
123}