From 6abe089740e1504548a597c105dce83b5c3022a6 Mon Sep 17 00:00:00 2001 From: Tyera Eulberg Date: Wed, 26 May 2021 13:27:41 -0600 Subject: [PATCH] Add custom error for tx-history queries when node does not support (#17494) --- client/src/rpc_custom_error.rs | 9 +++++++ core/src/rpc.rs | 43 ++++++++++++++++++++++++++++++---- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/client/src/rpc_custom_error.rs b/client/src/rpc_custom_error.rs index c7a962e17..400947dcd 100644 --- a/client/src/rpc_custom_error.rs +++ b/client/src/rpc_custom_error.rs @@ -16,6 +16,7 @@ pub const JSON_RPC_SERVER_ERROR_SLOT_SKIPPED: i64 = -32007; pub const JSON_RPC_SERVER_ERROR_NO_SNAPSHOT: i64 = -32008; pub const JSON_RPC_SERVER_ERROR_LONG_TERM_STORAGE_SLOT_SKIPPED: i64 = -32009; pub const JSON_RPC_SERVER_ERROR_KEY_EXCLUDED_FROM_SECONDARY_INDEX: i64 = -32010; +pub const JSON_RPC_SERVER_ERROR_TRANSACTION_HISTORY_NOT_AVAILABLE: i64 = -32011; pub enum RpcCustomError { BlockCleanedUp { @@ -44,6 +45,7 @@ pub enum RpcCustomError { KeyExcludedFromSecondaryIndex { index_key: String, }, + TransactionHistoryNotAvailable, } #[derive(Debug, Serialize, Deserialize)] @@ -132,6 +134,13 @@ impl From for Error { ), data: None, }, + RpcCustomError::TransactionHistoryNotAvailable => Self { + code: ErrorCode::ServerError( + JSON_RPC_SERVER_ERROR_TRANSACTION_HISTORY_NOT_AVAILABLE, + ), + message: "Transaction history is not available from this node".to_string(), + data: None, + }, } } } diff --git a/core/src/rpc.rs b/core/src/rpc.rs index 425f8fb0a..0d702304b 100644 --- a/core/src/rpc.rs +++ b/core/src/rpc.rs @@ -958,6 +958,8 @@ impl JsonRpcRequestProcessor { })); } } + } else { + return Err(RpcCustomError::TransactionHistoryNotAvailable.into()); } Err(RpcCustomError::BlockNotAvailable { slot }.into()) } @@ -1178,6 +1180,10 @@ impl JsonRpcRequestProcessor { .unwrap_or(false); let bank = self.bank(Some(CommitmentConfig::processed())); + if search_transaction_history && !self.config.enable_rpc_transaction_history { + return Err(RpcCustomError::TransactionHistoryNotAvailable.into()); + } + for signature in signatures { let status = if let Some(status) = self.get_transaction_status(signature, &bank) { Some(status) @@ -1313,6 +1319,8 @@ impl JsonRpcRequestProcessor { } } } + } else { + return Err(RpcCustomError::TransactionHistoryNotAvailable.into()); } Ok(None) } @@ -1415,7 +1423,7 @@ impl JsonRpcRequestProcessor { }) .collect()) } else { - Ok(vec![]) + Err(RpcCustomError::TransactionHistoryNotAvailable.into()) } } @@ -5132,7 +5140,7 @@ pub mod tests { let bob_pubkey = solana_sdk::pubkey::new_rand(); let RpcHandler { io, - meta, + mut meta, blockhash, alice, confirmed_block_signatures, @@ -5171,7 +5179,7 @@ pub mod tests { r#"{{"jsonrpc":"2.0","id":1,"method":"getSignatureStatuses","params":[["{}"]]}}"#, confirmed_block_signatures[1] ); - let res = io.handle_request_sync(&req, meta); + let res = io.handle_request_sync(&req, meta.clone()); let expected_res: transaction::Result<()> = Err(TransactionError::InstructionError( 0, InstructionError::Custom(1), @@ -5181,6 +5189,20 @@ pub mod tests { serde_json::from_value(json["result"]["value"][0].clone()) .expect("actual response deserialization"); assert_eq!(expected_res, result.as_ref().unwrap().status); + + // disable rpc-tx-history, but attempt historical query + meta.config.enable_rpc_transaction_history = false; + let req = format!( + r#"{{"jsonrpc":"2.0","id":1,"method":"getSignatureStatuses","params":[["{}"], {{"searchTransactionHistory": true}}]}}"#, + confirmed_block_signatures[1] + ); + let res = io.handle_request_sync(&req, meta); + assert_eq!( + res, + Some( + r#"{"jsonrpc":"2.0","error":{"code":-32011,"message":"Transaction history is not available from this node"},"id":1}"#.to_string(), + ) + ); } #[test] @@ -5757,7 +5779,7 @@ pub mod tests { let bob_pubkey = solana_sdk::pubkey::new_rand(); let RpcHandler { io, - meta, + mut meta, confirmed_block_signatures, blockhash, .. @@ -5809,7 +5831,7 @@ pub mod tests { } let req = r#"{"jsonrpc":"2.0","id":1,"method":"getBlock","params":[0,"binary"]}"#; - let res = io.handle_request_sync(&req, meta); + let res = io.handle_request_sync(&req, meta.clone()); let result: Value = serde_json::from_str(&res.expect("actual response")) .expect("actual response deserialization"); let confirmed_block: Option = @@ -5850,6 +5872,17 @@ pub mod tests { } } } + + // disable rpc-tx-history + meta.config.enable_rpc_transaction_history = false; + let req = r#"{"jsonrpc":"2.0","id":1,"method":"getBlock","params":[0]}"#; + let res = io.handle_request_sync(&req, meta); + assert_eq!( + res, + Some( + r#"{"jsonrpc":"2.0","error":{"code":-32011,"message":"Transaction history is not available from this node"},"id":1}"#.to_string(), + ) + ); } #[test]