Skip to content

Commit

Permalink
chore(jsonrpc): split the parser and errors module (#6917)
Browse files Browse the repository at this point in the history
Tracking issue: #6850

Requires: #6902

Splits up the `parser` and `errors` module into finer and more specialized modules, consolidating both parsing and type conversion logic.
  • Loading branch information
miraclx authored May 31, 2022
1 parent d9f6331 commit 7838182
Show file tree
Hide file tree
Showing 18 changed files with 937 additions and 999 deletions.
12 changes: 12 additions & 0 deletions chain/jsonrpc/src/api/adversarial.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use serde_json::Value;

use near_jsonrpc_adversarial_primitives::SetRoutingTableRequest;
use near_jsonrpc_primitives::errors::RpcParseError;

use super::{parse_params, RpcRequest};

impl RpcRequest for SetRoutingTableRequest {
fn parse(value: Option<Value>) -> Result<Self, RpcParseError> {
parse_params::<Self>(value)
}
}
42 changes: 42 additions & 0 deletions chain/jsonrpc/src/api/blocks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use serde_json::Value;

use near_client_primitives::types::GetBlockError;
use near_jsonrpc_primitives::errors::RpcParseError;
use near_jsonrpc_primitives::types::blocks::{RpcBlockError, RpcBlockRequest};
use near_primitives::types::{BlockId, BlockReference};

use super::{parse_params, RpcFrom, RpcRequest};

impl RpcRequest for RpcBlockRequest {
fn parse(value: Option<Value>) -> Result<Self, RpcParseError> {
let block_reference = if let Ok((block_id,)) = parse_params::<(BlockId,)>(value.clone()) {
BlockReference::BlockId(block_id)
} else {
parse_params::<BlockReference>(value)?
};
Ok(Self { block_reference })
}
}

impl RpcFrom<actix::MailboxError> for RpcBlockError {
fn rpc_from(error: actix::MailboxError) -> Self {
Self::InternalError { error_message: error.to_string() }
}
}

impl RpcFrom<GetBlockError> for RpcBlockError {
fn rpc_from(error: GetBlockError) -> Self {
match error {
GetBlockError::UnknownBlock { error_message } => Self::UnknownBlock { error_message },
GetBlockError::NotSyncedYet => Self::NotSyncedYet,
GetBlockError::IOError { error_message } => Self::InternalError { error_message },
GetBlockError::Unreachable { ref error_message } => {
tracing::warn!(target: "jsonrpc", "Unreachable error occurred: {}", error_message);
crate::metrics::RPC_UNREACHABLE_ERROR_COUNT
.with_label_values(&["RpcBlockError"])
.inc();
Self::InternalError { error_message: error.to_string() }
}
}
}
}
65 changes: 65 additions & 0 deletions chain/jsonrpc/src/api/changes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use serde_json::Value;

use near_client_primitives::types::{GetBlockError, GetStateChangesError};
use near_jsonrpc_primitives::errors::RpcParseError;
use near_jsonrpc_primitives::types::changes::{
RpcStateChangesError, RpcStateChangesInBlockByTypeRequest, RpcStateChangesInBlockRequest,
};

use super::{parse_params, RpcFrom, RpcRequest};

impl RpcRequest for RpcStateChangesInBlockRequest {
fn parse(value: Option<Value>) -> Result<Self, RpcParseError> {
parse_params::<Self>(value)
}
}

impl RpcRequest for RpcStateChangesInBlockByTypeRequest {
fn parse(value: Option<Value>) -> Result<Self, RpcParseError> {
parse_params::<Self>(value)
}
}

impl RpcFrom<actix::MailboxError> for RpcStateChangesError {
fn rpc_from(error: actix::MailboxError) -> Self {
Self::InternalError { error_message: error.to_string() }
}
}

impl RpcFrom<GetBlockError> for RpcStateChangesError {
fn rpc_from(error: GetBlockError) -> Self {
match error {
GetBlockError::UnknownBlock { error_message } => Self::UnknownBlock { error_message },
GetBlockError::NotSyncedYet => Self::NotSyncedYet,
GetBlockError::IOError { error_message } => Self::InternalError { error_message },
GetBlockError::Unreachable { ref error_message } => {
tracing::warn!(target: "jsonrpc", "Unreachable error occurred: {}", error_message);
crate::metrics::RPC_UNREACHABLE_ERROR_COUNT
.with_label_values(&["RpcStateChangesError"])
.inc();
Self::InternalError { error_message: error.to_string() }
}
}
}
}

impl RpcFrom<GetStateChangesError> for RpcStateChangesError {
fn rpc_from(error: GetStateChangesError) -> Self {
match error {
GetStateChangesError::IOError { error_message } => {
Self::InternalError { error_message }
}
GetStateChangesError::UnknownBlock { error_message } => {
Self::UnknownBlock { error_message }
}
GetStateChangesError::NotSyncedYet => Self::NotSyncedYet,
GetStateChangesError::Unreachable { ref error_message } => {
tracing::warn!(target: "jsonrpc", "Unreachable error occurred: {}", error_message);
crate::metrics::RPC_UNREACHABLE_ERROR_COUNT
.with_label_values(&["RpcStateChangesError"])
.inc();
Self::InternalError { error_message: error.to_string() }
}
}
}
}
62 changes: 62 additions & 0 deletions chain/jsonrpc/src/api/chunks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use serde_json::Value;

use near_client_primitives::types::{GetChunk, GetChunkError};
use near_jsonrpc_primitives::errors::RpcParseError;
use near_jsonrpc_primitives::types::chunks::{ChunkReference, RpcChunkError, RpcChunkRequest};
use near_primitives::hash::CryptoHash;
use near_primitives::types::{BlockId, ShardId};

use super::{parse_params, RpcFrom, RpcRequest};

impl RpcRequest for RpcChunkRequest {
fn parse(value: Option<Value>) -> Result<Self, RpcParseError> {
// Try to parse legacy positioned args and if it fails parse newer named args
let chunk_reference = if let Ok((chunk_id,)) = parse_params::<(CryptoHash,)>(value.clone())
{
ChunkReference::ChunkHash { chunk_id }
} else if let Ok(((block_id, shard_id),)) =
parse_params::<((BlockId, ShardId),)>(value.clone())
{
ChunkReference::BlockShardId { block_id, shard_id }
} else {
parse_params::<ChunkReference>(value)?
};
Ok(Self { chunk_reference })
}
}

impl RpcFrom<actix::MailboxError> for RpcChunkError {
fn rpc_from(error: actix::MailboxError) -> Self {
Self::InternalError { error_message: error.to_string() }
}
}

impl RpcFrom<ChunkReference> for GetChunk {
fn rpc_from(chunk_reference: ChunkReference) -> Self {
match chunk_reference {
ChunkReference::BlockShardId { block_id, shard_id } => match block_id {
BlockId::Height(height) => Self::Height(height, shard_id),
BlockId::Hash(block_hash) => Self::BlockHash(block_hash, shard_id),
},
ChunkReference::ChunkHash { chunk_id } => Self::ChunkHash(chunk_id.into()),
}
}
}

impl RpcFrom<GetChunkError> for RpcChunkError {
fn rpc_from(error: GetChunkError) -> Self {
match error {
GetChunkError::IOError { error_message } => Self::InternalError { error_message },
GetChunkError::UnknownBlock { error_message } => Self::UnknownBlock { error_message },
GetChunkError::InvalidShardId { shard_id } => Self::InvalidShardId { shard_id },
GetChunkError::UnknownChunk { chunk_hash } => Self::UnknownChunk { chunk_hash },
GetChunkError::Unreachable { ref error_message } => {
tracing::warn!(target: "jsonrpc", "Unreachable error occurred: {}", error_message);
crate::metrics::RPC_UNREACHABLE_ERROR_COUNT
.with_label_values(&["RpcChunkError"])
.inc();
Self::InternalError { error_message: error.to_string() }
}
}
}
}
38 changes: 38 additions & 0 deletions chain/jsonrpc/src/api/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use serde_json::Value;

use near_client_primitives::types::GetProtocolConfigError;
use near_jsonrpc_primitives::errors::RpcParseError;
use near_jsonrpc_primitives::types::config::{RpcProtocolConfigError, RpcProtocolConfigRequest};
use near_primitives::types::BlockReference;

use super::{parse_params, RpcFrom, RpcRequest};

impl RpcRequest for RpcProtocolConfigRequest {
fn parse(value: Option<Value>) -> Result<Self, RpcParseError> {
parse_params::<BlockReference>(value).map(|block_reference| Self { block_reference })
}
}

impl RpcFrom<actix::MailboxError> for RpcProtocolConfigError {
fn rpc_from(error: actix::MailboxError) -> Self {
Self::InternalError { error_message: error.to_string() }
}
}

impl RpcFrom<GetProtocolConfigError> for RpcProtocolConfigError {
fn rpc_from(error: GetProtocolConfigError) -> Self {
match error {
GetProtocolConfigError::UnknownBlock(error_message) => {
Self::UnknownBlock { error_message }
}
GetProtocolConfigError::IOError(error_message) => Self::InternalError { error_message },
GetProtocolConfigError::Unreachable(ref error_message) => {
tracing::warn!(target: "jsonrpc", "Unreachable error occurred: {}", error_message);
crate::metrics::RPC_UNREACHABLE_ERROR_COUNT
.with_label_values(&["RpcProtocolConfigError"])
.inc();
Self::InternalError { error_message: error.to_string() }
}
}
}
}
40 changes: 40 additions & 0 deletions chain/jsonrpc/src/api/gas_price.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use serde_json::Value;

use near_client_primitives::types::GetGasPriceError;
use near_jsonrpc_primitives::errors::RpcParseError;
use near_jsonrpc_primitives::types::gas_price::{RpcGasPriceError, RpcGasPriceRequest};
use near_primitives::types::MaybeBlockId;

use super::{parse_params, RpcFrom, RpcRequest};

impl RpcRequest for RpcGasPriceRequest {
fn parse(value: Option<Value>) -> Result<Self, RpcParseError> {
parse_params::<(MaybeBlockId,)>(value).map(|(block_id,)| Self { block_id })
}
}

impl RpcFrom<actix::MailboxError> for RpcGasPriceError {
fn rpc_from(error: actix::MailboxError) -> Self {
Self::InternalError { error_message: error.to_string() }
}
}

impl RpcFrom<GetGasPriceError> for RpcGasPriceError {
fn rpc_from(error: GetGasPriceError) -> Self {
match error {
GetGasPriceError::UnknownBlock { error_message } => {
Self::UnknownBlock { error_message }
}
GetGasPriceError::InternalError { error_message } => {
Self::InternalError { error_message }
}
GetGasPriceError::Unreachable { ref error_message } => {
tracing::warn!(target: "jsonrpc", "Unreachable error occurred: {}", error_message);
crate::metrics::RPC_UNREACHABLE_ERROR_COUNT
.with_label_values(&["RpcGasPriceError"])
.inc();
Self::InternalError { error_message: error.to_string() }
}
}
}
}
126 changes: 126 additions & 0 deletions chain/jsonrpc/src/api/light_client.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
use std::sync::Arc;

use serde_json::Value;

use near_client_primitives::types::{
GetBlockProofError, GetExecutionOutcomeError, GetNextLightClientBlockError,
};
use near_jsonrpc_primitives::errors::RpcParseError;
use near_jsonrpc_primitives::types::light_client::{
RpcLightClientExecutionProofRequest, RpcLightClientNextBlockError,
RpcLightClientNextBlockRequest, RpcLightClientNextBlockResponse, RpcLightClientProofError,
};
use near_primitives::hash::CryptoHash;
use near_primitives::views::LightClientBlockView;

use super::{parse_params, RpcFrom, RpcRequest};

impl RpcRequest for RpcLightClientExecutionProofRequest {
fn parse(value: Option<Value>) -> Result<Self, RpcParseError> {
Ok(parse_params::<Self>(value)?)
}
}

impl RpcRequest for RpcLightClientNextBlockRequest {
fn parse(value: Option<Value>) -> Result<Self, RpcParseError> {
if let Ok((last_block_hash,)) = parse_params::<(CryptoHash,)>(value.clone()) {
Ok(Self { last_block_hash })
} else {
Ok(parse_params::<Self>(value)?)
}
}
}

impl RpcFrom<Option<Arc<LightClientBlockView>>> for RpcLightClientNextBlockResponse {
fn rpc_from(light_client_block: Option<Arc<LightClientBlockView>>) -> Self {
Self { light_client_block }
}
}

impl RpcFrom<GetExecutionOutcomeError> for RpcLightClientProofError {
fn rpc_from(error: GetExecutionOutcomeError) -> Self {
match error {
GetExecutionOutcomeError::UnknownBlock { error_message } => {
Self::UnknownBlock { error_message }
}
GetExecutionOutcomeError::InconsistentState {
number_or_shards,
execution_outcome_shard_id,
} => Self::InconsistentState { number_or_shards, execution_outcome_shard_id },
GetExecutionOutcomeError::NotConfirmed { transaction_or_receipt_id } => {
Self::NotConfirmed { transaction_or_receipt_id }
}
GetExecutionOutcomeError::UnknownTransactionOrReceipt { transaction_or_receipt_id } => {
Self::UnknownTransactionOrReceipt { transaction_or_receipt_id }
}
GetExecutionOutcomeError::UnavailableShard { transaction_or_receipt_id, shard_id } => {
Self::UnavailableShard { transaction_or_receipt_id, shard_id }
}
GetExecutionOutcomeError::InternalError { error_message } => {
Self::InternalError { error_message }
}
GetExecutionOutcomeError::Unreachable { ref error_message } => {
tracing::warn!(target: "jsonrpc", "Unreachable error occurred: {}", error_message);
crate::metrics::RPC_UNREACHABLE_ERROR_COUNT
.with_label_values(&["RpcLightClientProofError"])
.inc();
Self::InternalError { error_message: error.to_string() }
}
}
}
}

impl RpcFrom<actix::MailboxError> for RpcLightClientProofError {
fn rpc_from(error: actix::MailboxError) -> Self {
Self::InternalError { error_message: error.to_string() }
}
}

impl RpcFrom<GetBlockProofError> for RpcLightClientProofError {
fn rpc_from(error: GetBlockProofError) -> Self {
match error {
GetBlockProofError::UnknownBlock { error_message } => {
Self::UnknownBlock { error_message }
}
GetBlockProofError::InternalError { error_message } => {
Self::InternalError { error_message }
}
GetBlockProofError::Unreachable { ref error_message } => {
tracing::warn!(target: "jsonrpc", "Unreachable error occurred: {}", error_message);
crate::metrics::RPC_UNREACHABLE_ERROR_COUNT
.with_label_values(&["RpcLightClientProofError"])
.inc();
Self::InternalError { error_message: error.to_string() }
}
}
}
}

impl RpcFrom<actix::MailboxError> for RpcLightClientNextBlockError {
fn rpc_from(error: actix::MailboxError) -> Self {
Self::InternalError { error_message: error.to_string() }
}
}

impl RpcFrom<GetNextLightClientBlockError> for RpcLightClientNextBlockError {
fn rpc_from(error: GetNextLightClientBlockError) -> Self {
match error {
GetNextLightClientBlockError::InternalError { error_message } => {
Self::InternalError { error_message }
}
GetNextLightClientBlockError::UnknownBlock { error_message } => {
Self::UnknownBlock { error_message }
}
GetNextLightClientBlockError::EpochOutOfBounds { epoch_id } => {
Self::EpochOutOfBounds { epoch_id }
}
GetNextLightClientBlockError::Unreachable { ref error_message } => {
tracing::warn!(target: "jsonrpc", "Unreachable error occurred: {}", error_message);
crate::metrics::RPC_UNREACHABLE_ERROR_COUNT
.with_label_values(&["RpcLightClientNextBlockError"])
.inc();
Self::InternalError { error_message: error.to_string() }
}
}
}
}
Loading

0 comments on commit 7838182

Please sign in to comment.