diff --git a/Cargo.lock b/Cargo.lock index 1f9760216ab..56f5ef80bd9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2981,6 +2981,7 @@ dependencies = [ "failure", "failure_derive", "log", + "near-crypto", "near-primitives", "thiserror", ] @@ -3056,6 +3057,7 @@ dependencies = [ "near-chain-configs", "near-chain-primitives", "near-chunks", + "near-crypto", "near-network", "near-primitives", "serde", @@ -3214,12 +3216,14 @@ dependencies = [ "lazy_static", "near-chain-configs", "near-client-primitives", + "near-crypto", "near-metrics", "near-primitives", "near-primitives-core", "serde", "serde_json", "thiserror", + "tracing", "uuid", ] diff --git a/chain/chain-primitives/Cargo.toml b/chain/chain-primitives/Cargo.toml index ab4fac84053..0b1c0d4fb77 100644 --- a/chain/chain-primitives/Cargo.toml +++ b/chain/chain-primitives/Cargo.toml @@ -14,3 +14,4 @@ log = "0.4" thiserror = "1.0" near-primitives = { path = "../../core/primitives" } +near-crypto = { path = "../../core/crypto" } diff --git a/chain/chain-primitives/src/error.rs b/chain/chain-primitives/src/error.rs index 9b188b7141a..ee0ba648225 100644 --- a/chain/chain-primitives/src/error.rs +++ b/chain/chain-primitives/src/error.rs @@ -15,14 +15,14 @@ use near_primitives::types::{BlockHeight, ShardId}; #[derive(thiserror::Error, Debug)] pub enum QueryError { - #[error("Invalid account ID #{requested_account_id}")] + #[error("Account ID #{requested_account_id} is invalid")] InvalidAccount { requested_account_id: near_primitives::types::AccountId }, #[error("Account ID #{requested_account_id} does not exist while viewing")] AccountDoesNotExist { requested_account_id: near_primitives::types::AccountId }, #[error("Contract ID #{contract_account_id} code does not exist while viewing")] ContractCodeDoesNotExist { contract_account_id: near_primitives::types::AccountId }, #[error("Access key for public key #{public_key} does not exist while viewing")] - AccessKeyDoesNotExist { public_key: String }, + AccessKeyDoesNotExist { public_key: near_crypto::PublicKey }, #[error("Storage error occurred: #{storage_error:?}")] StorageError { #[from] diff --git a/chain/client-primitives/Cargo.toml b/chain/client-primitives/Cargo.toml index 55ed324dbe7..b8069eb4040 100644 --- a/chain/client-primitives/Cargo.toml +++ b/chain/client-primitives/Cargo.toml @@ -17,6 +17,7 @@ near-chain-primitives = { path = "../chain-primitives" } near-chain-configs = { path = "../../core/chain-configs" } near-chunks = { path = "../chunks" } +near-crypto = { path = "../../core/crypto" } near-network = { path = "../network" } near-primitives = { path = "../../core/primitives" } diff --git a/chain/client-primitives/src/types.rs b/chain/client-primitives/src/types.rs index 6b783055f65..bbf4230c8a6 100644 --- a/chain/client-primitives/src/types.rs +++ b/chain/client-primitives/src/types.rs @@ -284,7 +284,7 @@ pub enum QueryError { )] ContractCodeDoesNotExist { contract_account_id: near_primitives::types::AccountId }, #[error("Access key for public key #{public_key} has never been observed on the node")] - AccessKeyDoesNotExist { public_key: String }, + AccessKeyDoesNotExist { public_key: near_crypto::PublicKey }, #[error("VM error occurred: #{error_message}")] VMError { error_message: String }, // NOTE: Currently, the underlying errors are too broad, and while we tried to handle diff --git a/chain/jsonrpc-primitives/Cargo.toml b/chain/jsonrpc-primitives/Cargo.toml index 9076a383cf9..ee7a2e767cd 100644 --- a/chain/jsonrpc-primitives/Cargo.toml +++ b/chain/jsonrpc-primitives/Cargo.toml @@ -12,10 +12,12 @@ lazy_static = "1.4" serde = { version = "1", features = ["derive"] } serde_json = "1" thiserror = "1.0" +tracing = "0.1.13" uuid = { version = "~0.8", features = ["v4"] } +near-chain-configs = { path = "../../core/chain-configs" } near-client-primitives = { path = "../client-primitives" } +near-crypto = { path = "../../core/crypto" } +near-metrics = { path = "../../core/metrics" } near-primitives = { path = "../../core/primitives" } near-primitives-core = { path = "../../core/primitives-core" } -near-metrics = { path = "../../core/metrics" } -near-chain-configs = { path = "../../core/chain-configs" } diff --git a/chain/jsonrpc-primitives/src/types/blocks.rs b/chain/jsonrpc-primitives/src/types/blocks.rs index adecc05f7d8..d929127a352 100644 --- a/chain/jsonrpc-primitives/src/types/blocks.rs +++ b/chain/jsonrpc-primitives/src/types/blocks.rs @@ -1,5 +1,6 @@ use serde::{Deserialize, Serialize}; use serde_json::Value; +use tracing::error; #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] @@ -64,12 +65,13 @@ impl From for RpcBlockError { } near_client_primitives::types::GetBlockError::NotSyncedYet => Self::NotSyncedYet, near_client_primitives::types::GetBlockError::IOError(s) => Self::InternalError(s), - near_client_primitives::types::GetBlockError::Unreachable(s) => { + near_client_primitives::types::GetBlockError::Unreachable(error_message) => { + error!(target: "jsonrpc", "Unreachable error occurred: {}", &error_message); near_metrics::inc_counter_vec( &crate::metrics::RPC_UNREACHABLE_ERROR_COUNT, - &["RpcBlockError", &s], + &["RpcBlockError", &error_message], ); - Self::Unreachable(s) + Self::Unreachable(error_message) } } } diff --git a/chain/jsonrpc-primitives/src/types/chunks.rs b/chain/jsonrpc-primitives/src/types/chunks.rs index 83f7df24504..88fb54bd35c 100644 --- a/chain/jsonrpc-primitives/src/types/chunks.rs +++ b/chain/jsonrpc-primitives/src/types/chunks.rs @@ -1,5 +1,6 @@ use serde::{Deserialize, Serialize}; use serde_json::Value; +use tracing::error; #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -93,12 +94,13 @@ impl From for RpcChunkError { near_client_primitives::types::GetChunkError::UnknownChunk(hash) => { Self::UnknownChunk(hash) } - near_client_primitives::types::GetChunkError::Unreachable(s) => { + near_client_primitives::types::GetChunkError::Unreachable(error_message) => { + error!(target: "jsonrpc", "Unreachable error occurred: {}", &error_message); near_metrics::inc_counter_vec( &crate::metrics::RPC_UNREACHABLE_ERROR_COUNT, - &["RpcChunkError", &s], + &["RpcChunkError", &error_message], ); - Self::Unreachable(s) + Self::Unreachable(error_message) } } } diff --git a/chain/jsonrpc-primitives/src/types/config.rs b/chain/jsonrpc-primitives/src/types/config.rs index bcd4236c33a..076f9ac1a44 100644 --- a/chain/jsonrpc-primitives/src/types/config.rs +++ b/chain/jsonrpc-primitives/src/types/config.rs @@ -1,6 +1,7 @@ use crate::types::blocks::BlockReference; use serde::{Deserialize, Serialize}; use serde_json::Value; +use tracing::error; #[derive(Serialize, Deserialize)] pub struct RpcProtocolConfigRequest { @@ -46,12 +47,13 @@ impl From for RpcProtocol near_client_primitives::types::GetProtocolConfigError::IOError(s) => { Self::InternalError(s) } - near_client_primitives::types::GetProtocolConfigError::Unreachable(s) => { + near_client_primitives::types::GetProtocolConfigError::Unreachable(error_message) => { + error!(target: "jsonrpc", "Unreachable error occurred: {}", &error_message); near_metrics::inc_counter_vec( &crate::metrics::RPC_UNREACHABLE_ERROR_COUNT, - &["RpcProtocolConfigError", &s], + &["RpcProtocolConfigError", &error_message], ); - Self::Unreachable(s) + Self::Unreachable(error_message) } } } diff --git a/chain/jsonrpc-primitives/src/types/query.rs b/chain/jsonrpc-primitives/src/types/query.rs index 0f202c74a65..f1f67f38047 100644 --- a/chain/jsonrpc-primitives/src/types/query.rs +++ b/chain/jsonrpc-primitives/src/types/query.rs @@ -1,5 +1,6 @@ use serde::{Deserialize, Serialize}; use serde_json::Value; +use tracing::error; /// Max size of the query path (soft-deprecated) const QUERY_DATA_MAX_SIZE: usize = 10 * 1024; @@ -29,7 +30,7 @@ pub enum RpcQueryError { )] NoContractCode { contract_account_id: near_primitives::types::AccountId }, #[error("Access key for public key #{public_key} has never been observed on the node")] - UnknownAccessKey { public_key: String }, + UnknownAccessKey { public_key: near_crypto::PublicKey }, #[error("Function call returned an error: #{vm_error}")] FunctionCall { vm_error: String }, #[error("The node reached its limits. Try again later. More details: #{error_message}")] @@ -148,6 +149,7 @@ impl From for RpcQueryError { Self::FunctionCall { vm_error: error_message } } near_client_primitives::types::QueryError::Unreachable { error_message } => { + error!(target: "jsonrpc", "Unreachable error occurred: {}", &error_message); near_metrics::inc_counter_vec( &crate::metrics::RPC_UNREACHABLE_ERROR_COUNT, &["RpcQueryError", &error_message], diff --git a/chain/jsonrpc-primitives/src/types/receipts.rs b/chain/jsonrpc-primitives/src/types/receipts.rs index a17c16f87d7..b9f560effb1 100644 --- a/chain/jsonrpc-primitives/src/types/receipts.rs +++ b/chain/jsonrpc-primitives/src/types/receipts.rs @@ -1,5 +1,6 @@ use serde::{Deserialize, Serialize}; use serde_json::Value; +use tracing::error; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ReceiptReference { @@ -52,12 +53,13 @@ impl From for RpcReceiptError { near_client_primitives::types::GetReceiptError::UnknownReceipt(hash) => { Self::UnknownReceipt(hash) } - near_client_primitives::types::GetReceiptError::Unreachable(s) => { + near_client_primitives::types::GetReceiptError::Unreachable(error_message) => { + error!(target: "jsonrpc", "Unreachable error occurred: {}", &error_message); near_metrics::inc_counter_vec( &crate::metrics::RPC_UNREACHABLE_ERROR_COUNT, - &["RpcReceiptError", &s], + &["RpcReceiptError", &error_message], ); - Self::Unreachable(s) + Self::Unreachable(error_message) } } } diff --git a/chain/jsonrpc/client/src/lib.rs b/chain/jsonrpc/client/src/lib.rs index 4f70d15c42e..1d63cd13755 100644 --- a/chain/jsonrpc/client/src/lib.rs +++ b/chain/jsonrpc/client/src/lib.rs @@ -8,8 +8,9 @@ use serde::Serialize; use near_jsonrpc_primitives::errors::RpcError; use near_jsonrpc_primitives::message::{from_slice, Message}; use near_jsonrpc_primitives::rpc::{ - RpcQueryRequest, RpcStateChangesRequest, RpcStateChangesResponse, RpcValidatorsOrderedRequest, + RpcStateChangesRequest, RpcStateChangesResponse, RpcValidatorsOrderedRequest, }; +use near_jsonrpc_primitives::types::query::RpcQueryRequest; use near_primitives::hash::CryptoHash; use near_primitives::types::{BlockId, BlockReference, MaybeBlockId, ShardId}; use near_primitives::views::{ @@ -198,7 +199,10 @@ impl JsonRpcClient { call_method(&self.client, &self.server_addr, "query", [path, data]) } - pub fn query(&self, request: RpcQueryRequest) -> RpcRequest { + pub fn query( + &self, + request: near_jsonrpc_primitives::types::query::RpcQueryRequest, + ) -> RpcRequest { call_method(&self.client, &self.server_addr, "query", request) } diff --git a/neard/src/runtime/errors.rs b/neard/src/runtime/errors.rs index 4100bb35144..2e4b8d1c9ec 100644 --- a/neard/src/runtime/errors.rs +++ b/neard/src/runtime/errors.rs @@ -90,7 +90,7 @@ impl From for WrappedQue } => Self(QueryError::StorageError { storage_error }), node_runtime::state_viewer::errors::ViewAccessKeyError::AccessKeyDoesNotExist { public_key, - } => Self(QueryError::AccessKeyDoesNotExist { public_key: public_key.to_string() }), + } => Self(QueryError::AccessKeyDoesNotExist { public_key }), node_runtime::state_viewer::errors::ViewAccessKeyError::InternalError { error_message, } => Self(QueryError::InternalError { error_message }), diff --git a/neard/tests/rpc_nodes.rs b/neard/tests/rpc_nodes.rs index 4fc7a7e9180..ab9e2853280 100644 --- a/neard/tests/rpc_nodes.rs +++ b/neard/tests/rpc_nodes.rs @@ -728,3 +728,42 @@ fn test_protocol_config_rpc() { .unwrap(); }); } + +#[test] +fn test_query_rpc() { + init_integration_logger(); + heavy_test(|| { + System::builder() + .stop_on_panic(true) + .run(move || { + let num_nodes = 1; + let dirs = (0..num_nodes) + .map(|i| { + tempfile::Builder::new() + .prefix(&format!("protocol_config{}", i)) + .tempdir() + .unwrap() + }) + .collect::>(); + let (_genesis, rpc_addrs, _) = start_nodes(1, &dirs, 1, 0, 10, 0); + + actix::spawn(async move { + let client = new_client(&format!("http://{}", rpc_addrs[0])); + let query_response = client + .query(near_jsonrpc_primitives::types::query::RpcQueryRequest { + block_reference: near_primitives::types::BlockReference::Finality( + Finality::Final, + ), + request: near_primitives::views::QueryRequest::ViewAccount { + account_id: "test.near".to_string(), + }, + }) + .await + .unwrap(); + assert_eq!(false, true); + System::current().stop(); + }); + }) + .unwrap(); + }); +}