From f003ac4a13f13f412ed0faade2c93e8999771865 Mon Sep 17 00:00:00 2001 From: Bohdan Khorolets Date: Thu, 8 Apr 2021 12:45:09 +0300 Subject: [PATCH] Move backward compatibility to jsonrpc-primitives from jsonrpc, move ServerError from jsonrpc to jsonrpc-primitives, fix dependencies --- Cargo.lock | 21 ++-- chain/jsonrpc-primitives/Cargo.toml | 3 +- chain/jsonrpc-primitives/src/errors.rs | 45 +++++++++ .../src/types/transactions.rs | 11 ++- chain/jsonrpc/src/lib.rs | 97 ++++--------------- test-utils/testlib/src/node/mod.rs | 2 +- test-utils/testlib/src/standard_test_cases.rs | 2 +- test-utils/testlib/src/user/mod.rs | 2 +- test-utils/testlib/src/user/rpc_user.rs | 2 +- test-utils/testlib/src/user/runtime_user.rs | 2 +- 10 files changed, 84 insertions(+), 103 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c610ae95587..aa72d19375e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2047,7 +2047,7 @@ dependencies = [ "near-crypto", "near-network", "near-primitives", - "near-runtime-utils 3.0.0", + "near-runtime-utils", "neard", "node-runtime", "serde", @@ -3201,7 +3201,7 @@ dependencies = [ "lunarity-lexer", "near-crypto", "near-primitives", - "near-runtime-utils 3.0.0", + "near-runtime-utils", "near-vm-errors", "near-vm-logic", "num-bigint", @@ -3290,7 +3290,8 @@ dependencies = [ "near-metrics", "near-primitives", "near-primitives-core", - "near-runtime-utils 4.0.0-pre.1", + "near-rpc-error-macro", + "near-runtime-utils", "serde", "serde_json", "thiserror", @@ -3508,16 +3509,6 @@ dependencies = [ "regex", ] -[[package]] -name = "near-runtime-utils" -version = "4.0.0-pre.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a48d80c4ca1d4cf99bc16490e1e3d49826c150dfc4410ac498918e45c7d98e07" -dependencies = [ - "lazy_static", - "regex", -] - [[package]] name = "near-rust-allocator-proxy" version = "0.2.9" @@ -3601,7 +3592,7 @@ dependencies = [ "bs58", "byteorder", "near-primitives-core", - "near-runtime-utils 3.0.0", + "near-runtime-utils", "near-vm-errors", "serde", "serde_json", @@ -3762,7 +3753,7 @@ dependencies = [ "near-evm-runner", "near-metrics", "near-primitives", - "near-runtime-utils 3.0.0", + "near-runtime-utils", "near-store", "near-test-contracts", "near-vm-errors", diff --git a/chain/jsonrpc-primitives/Cargo.toml b/chain/jsonrpc-primitives/Cargo.toml index 87594aca485..b132191bf0f 100644 --- a/chain/jsonrpc-primitives/Cargo.toml +++ b/chain/jsonrpc-primitives/Cargo.toml @@ -14,7 +14,6 @@ serde_json = "1" thiserror = "1.0" tracing = "0.1.13" uuid = { version = "~0.8", features = ["v4"] } -near-runtime-utils = "4.0.0-pre.1" near-chain-configs = { path = "../../core/chain-configs" } near-client-primitives = { path = "../client-primitives" } @@ -22,3 +21,5 @@ near-crypto = { path = "../../core/crypto" } near-metrics = { path = "../../core/metrics" } near-primitives = { path = "../../core/primitives" } near-primitives-core = { path = "../../core/primitives-core" } +near-rpc-error-macro = { path = "../../tools/rpctypegen/macro" } +near-runtime-utils = { path = "../../runtime/near-runtime-utils" } diff --git a/chain/jsonrpc-primitives/src/errors.rs b/chain/jsonrpc-primitives/src/errors.rs index cd77af8c45e..571e5fb3294 100644 --- a/chain/jsonrpc-primitives/src/errors.rs +++ b/chain/jsonrpc-primitives/src/errors.rs @@ -1,6 +1,10 @@ +use std::fmt::Display; + use serde::{Deserialize, Serialize}; use serde_json::{to_value, Value}; +use near_primitives::errors::{InvalidTxError, TxExecutionError}; + #[derive(Serialize)] pub struct RpcParseError(pub String); @@ -16,6 +20,15 @@ pub struct RpcError { pub data: Option, } +/// A general Server Error +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, near_rpc_error_macro::RpcError)] +pub enum ServerError { + TxExecutionError(TxExecutionError), + Timeout, + Closed, + InternalError, +} + impl RpcError { /// A generic constructor. /// @@ -75,3 +88,35 @@ impl From for RpcError { Self::invalid_params(parse_error.0) } } + +impl Display for ServerError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { + match self { + ServerError::TxExecutionError(e) => write!(f, "ServerError: {}", e), + ServerError::Timeout => write!(f, "ServerError: Timeout"), + ServerError::Closed => write!(f, "ServerError: Closed"), + ServerError::InternalError => write!(f, "ServerError: Internal Error"), + } + } +} + +impl From for ServerError { + fn from(e: InvalidTxError) -> ServerError { + ServerError::TxExecutionError(TxExecutionError::InvalidTxError(e)) + } +} + +impl From for ServerError { + fn from(e: actix::MailboxError) -> Self { + match e { + actix::MailboxError::Closed => ServerError::Closed, + actix::MailboxError::Timeout => ServerError::Timeout, + } + } +} + +impl From for RpcError { + fn from(e: ServerError) -> RpcError { + RpcError::server_error(Some(e)) + } +} diff --git a/chain/jsonrpc-primitives/src/types/transactions.rs b/chain/jsonrpc-primitives/src/types/transactions.rs index 77ebbb7f913..5c153dafc60 100644 --- a/chain/jsonrpc-primitives/src/types/transactions.rs +++ b/chain/jsonrpc-primitives/src/types/transactions.rs @@ -132,8 +132,15 @@ impl From for RpcTransact impl From for crate::errors::RpcError { fn from(error: RpcTransactionError) -> Self { - let error_data = Some(Value::String(error.to_string())); - + let error_data = match error { + RpcTransactionError::InvalidTransaction { ref context } => Some( + serde_json::to_value(crate::errors::ServerError::TxExecutionError( + near_primitives::errors::TxExecutionError::InvalidTxError(context.clone()), + )) + .unwrap_or(Value::String(error.to_string())), + ), + _ => Some(Value::String(error.to_string())), + }; Self::new(-32_000, "Server error".to_string(), error_data) } } diff --git a/chain/jsonrpc/src/lib.rs b/chain/jsonrpc/src/lib.rs index b1272ec5dc8..82f7479e640 100644 --- a/chain/jsonrpc/src/lib.rs +++ b/chain/jsonrpc/src/lib.rs @@ -1,4 +1,3 @@ -use std::fmt::Display; use std::string::FromUtf8Error; use std::time::Duration; @@ -34,7 +33,6 @@ use near_metrics::{Encoder, TextEncoder}; #[cfg(feature = "adversarial")] use near_network::types::{NetworkAdversarialMessage, NetworkViewClientMessages}; use near_network::{NetworkClientMessages, NetworkClientResponses}; -use near_primitives::errors::{InvalidTxError, TxExecutionError}; use near_primitives::hash::CryptoHash; use near_primitives::serialize::BaseEncode; use near_primitives::transaction::SignedTransaction; @@ -116,47 +114,6 @@ fn jsonify( .map_err(|err| RpcError::server_error(Some(err))) } -/// A general Server Error -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, near_rpc_error_macro::RpcError)] -pub enum ServerError { - TxExecutionError(TxExecutionError), - Timeout, - Closed, - InternalError, -} - -impl Display for ServerError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { - match self { - ServerError::TxExecutionError(e) => write!(f, "ServerError: {}", e), - ServerError::Timeout => write!(f, "ServerError: Timeout"), - ServerError::Closed => write!(f, "ServerError: Closed"), - ServerError::InternalError => write!(f, "ServerError: Internal Error"), - } - } -} - -impl From for ServerError { - fn from(e: InvalidTxError) -> ServerError { - ServerError::TxExecutionError(TxExecutionError::InvalidTxError(e)) - } -} - -impl From for ServerError { - fn from(e: MailboxError) -> Self { - match e { - MailboxError::Closed => ServerError::Closed, - MailboxError::Timeout => ServerError::Timeout, - } - } -} - -impl From for RpcError { - fn from(e: ServerError) -> RpcError { - RpcError::server_error(Some(e)) - } -} - #[easy_ext::ext(FromNetworkClientResponses)] impl near_jsonrpc_primitives::types::transactions::RpcTransactionError { pub fn from_network_client_responses(responses: NetworkClientResponses) -> Self { @@ -231,31 +188,6 @@ fn process_query_response( } } -/// This function processes response from tx related methods to introduce -/// backward compatible response in case of specific errors -fn process_tx_response( - tx_response: Result, -) -> Result -where - S: Serialize, -{ - // This match is used here to give backward compatible error message for specific - // error variants. Should be refactored once structured errors fully shipped - match tx_response { - Ok(response) => serde_json::to_value(response) - .map_err(|err| RpcError::parse_error(err.to_string())), - Err(err) => match err { - near_jsonrpc_primitives::types::transactions::RpcTransactionError::InvalidTransaction { context } => Err(RpcError::new( - -32_000, - "Server_error".to_string(), - Some(serde_json::to_value(ServerError::TxExecutionError(TxExecutionError::InvalidTxError(context))) - .map_err(|err| RpcError::parse_error(err.to_string()))?, - ))), - _ => Err(err.into()) - } - } -} - struct JsonRpcHandler { client_addr: Addr, view_client_addr: Addr, @@ -324,8 +256,9 @@ impl JsonRpcHandler { near_jsonrpc_primitives::types::transactions::RpcTransactionRequest::parse( request.params, )?; - let send_tx_response = self.send_tx_commit(rpc_transaction_request).await; - process_tx_response(send_tx_response) + let send_tx_response = self.send_tx_commit(rpc_transaction_request).await?; + serde_json::to_value(send_tx_response) + .map_err(|err| RpcError::parse_error(err.to_string())) } "chunk" => { let rpc_chunk_request = @@ -338,8 +271,9 @@ impl JsonRpcHandler { near_jsonrpc_primitives::types::transactions::RpcTransactionRequest::parse( request.params, )?; - let broadcast_tx_sync_response = self.send_tx_sync(rpc_transaction_request).await; - process_tx_response(broadcast_tx_sync_response) + let broadcast_tx_sync_response = self.send_tx_sync(rpc_transaction_request).await?; + serde_json::to_value(broadcast_tx_sync_response) + .map_err(|err| RpcError::parse_error(err.to_string())) } "EXPERIMENTAL_changes" => self.changes_in_block_by_type(request.params).await, "EXPERIMENTAL_changes_in_block" => self.changes_in_block(request.params).await, @@ -348,8 +282,9 @@ impl JsonRpcHandler { near_jsonrpc_primitives::types::transactions::RpcTransactionRequest::parse( request.params, )?; - let broadcast_tx_sync_response = self.check_tx(rpc_transaction_request).await; - process_tx_response(broadcast_tx_sync_response) + let broadcast_tx_sync_response = self.check_tx(rpc_transaction_request).await?; + serde_json::to_value(broadcast_tx_sync_response) + .map_err(|err| RpcError::parse_error(err.to_string())) } "EXPERIMENTAL_genesis_config" => self.genesis_config().await, "EXPERIMENTAL_light_client_proof" => { @@ -374,8 +309,9 @@ impl JsonRpcHandler { "EXPERIMENTAL_tx_status" => { let rpc_transaction_status_common_request = near_jsonrpc_primitives::types::transactions::RpcTransactionStatusCommonRequest::parse(request.params)?; let rpc_transaction_response = - self.tx_status_common(rpc_transaction_status_common_request, true).await; - process_tx_response(rpc_transaction_response) + self.tx_status_common(rpc_transaction_status_common_request, true).await?; + serde_json::to_value(rpc_transaction_response) + .map_err(|err| RpcError::parse_error(err.to_string())) } "EXPERIMENTAL_validators_ordered" => self.validators_ordered(request.params).await, "gas_price" => { @@ -401,8 +337,9 @@ impl JsonRpcHandler { "tx" => { let rpc_transaction_status_common_request = near_jsonrpc_primitives::types::transactions::RpcTransactionStatusCommonRequest::parse(request.params)?; let rpc_transaction_response = - self.tx_status_common(rpc_transaction_status_common_request, false).await; - process_tx_response(rpc_transaction_response) + self.tx_status_common(rpc_transaction_status_common_request, false).await?; + serde_json::to_value(rpc_transaction_response) + .map_err(|err| RpcError::parse_error(err.to_string())) } "validators" => { let rpc_validator_request = @@ -872,7 +809,7 @@ impl JsonRpcHandler { .view_client_addr .send(GetExecutionOutcome { id }) .await - .map_err(|e| RpcError::from(ServerError::from(e)))? + .map_err(|e| RpcError::from(near_jsonrpc_primitives::errors::ServerError::from(e)))? .map_err(|e| RpcError::server_error(Some(e)))?; let block_proof = self .view_client_addr @@ -881,7 +818,7 @@ impl JsonRpcHandler { head_block_hash: light_client_head, }) .await - .map_err(|e| RpcError::from(ServerError::from(e)))?; + .map_err(|e| RpcError::from(near_jsonrpc_primitives::errors::ServerError::from(e)))?; let res = block_proof.map(|block_proof| RpcLightClientExecutionProofResponse { outcome_proof: execution_outcome_proof.outcome_proof, outcome_root_proof: execution_outcome_proof.outcome_root_proof, diff --git a/test-utils/testlib/src/node/mod.rs b/test-utils/testlib/src/node/mod.rs index 97f1a456ba8..8cfb040fe49 100644 --- a/test-utils/testlib/src/node/mod.rs +++ b/test-utils/testlib/src/node/mod.rs @@ -3,7 +3,7 @@ use std::sync::RwLock; use near_chain_configs::Genesis; use near_crypto::{InMemorySigner, Signer}; -use near_jsonrpc::ServerError; +use near_jsonrpc_primitives::errors::ServerError; use near_primitives::state_record::StateRecord; use near_primitives::transaction::SignedTransaction; use near_primitives::types::{AccountId, Balance, NumSeats}; diff --git a/test-utils/testlib/src/standard_test_cases.rs b/test-utils/testlib/src/standard_test_cases.rs index 85916f0e358..eef765309cb 100644 --- a/test-utils/testlib/src/standard_test_cases.rs +++ b/test-utils/testlib/src/standard_test_cases.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use assert_matches::assert_matches; use near_crypto::{InMemorySigner, KeyType}; -use near_jsonrpc::ServerError; +use near_jsonrpc_primitives::errors::ServerError; use near_primitives::account::{AccessKey, AccessKeyPermission, FunctionCallPermission}; use near_primitives::errors::{ ActionError, ActionErrorKind, InvalidAccessKeyError, InvalidTxError, TxExecutionError, diff --git a/test-utils/testlib/src/user/mod.rs b/test-utils/testlib/src/user/mod.rs index 7cdbf34a849..d0b9dd6ce64 100644 --- a/test-utils/testlib/src/user/mod.rs +++ b/test-utils/testlib/src/user/mod.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use futures::{future::LocalBoxFuture, FutureExt}; use near_crypto::{PublicKey, Signer}; -use near_jsonrpc::ServerError; +use near_jsonrpc_primitives::errors::ServerError; use near_primitives::account::AccessKey; use near_primitives::hash::CryptoHash; use near_primitives::receipt::Receipt; diff --git a/test-utils/testlib/src/user/rpc_user.rs b/test-utils/testlib/src/user/rpc_user.rs index 5cabc8a364a..64b932ada6d 100644 --- a/test-utils/testlib/src/user/rpc_user.rs +++ b/test-utils/testlib/src/user/rpc_user.rs @@ -8,8 +8,8 @@ use futures::{Future, TryFutureExt}; use near_client::StatusResponse; use near_crypto::{PublicKey, Signer}; use near_jsonrpc::client::{new_client, JsonRpcClient}; -use near_jsonrpc::ServerError; use near_jsonrpc_client::ChunkId; +use near_jsonrpc_primitives::errors::ServerError; use near_jsonrpc_primitives::types::query::RpcQueryResponse; use near_primitives::hash::CryptoHash; use near_primitives::receipt::Receipt; diff --git a/test-utils/testlib/src/user/runtime_user.rs b/test-utils/testlib/src/user/runtime_user.rs index 5211f9b641c..4df1e6c64cd 100644 --- a/test-utils/testlib/src/user/runtime_user.rs +++ b/test-utils/testlib/src/user/runtime_user.rs @@ -3,7 +3,7 @@ use std::collections::{HashMap, HashSet}; use std::sync::{Arc, RwLock}; use near_crypto::{PublicKey, Signer}; -use near_jsonrpc::ServerError; +use near_jsonrpc_primitives::errors::ServerError; use near_primitives::errors::{RuntimeError, TxExecutionError}; use near_primitives::hash::CryptoHash; use near_primitives::receipt::Receipt;