Files
nym/common/client-libs/validator-client/src/nymd/error.rs
T
Jędrzej Stuczyński 8f152d42f0 Feature/simulate (#950)
* Raw scaffold for tx simulate

* Proper error handling in AbciResult parsing

* Simulate without actual signing operation

* Moved all-fee related functionalities to separate module

* Adding GasInfo to transaction results

* Automated gas estimation

* Slightly adjusted public API

* Using auto fees in eth events

* Removed old print statement

* Reorganised nymd client fee handling

* Put bandaid on wallet gas estimation

* Fixed operation re-export

* warning note on get_approximate_fee

* [ci skip] Generate TS types

* Refactored ProtoAbciResult parsing

* Explicit error on abci query failure

Co-authored-by: jstuczyn <jstuczyn@users.noreply.github.com>
2021-12-14 09:28:15 +00:00

165 lines
5.7 KiB
Rust

// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::nymd::cosmwasm_client::types::ContractCodeId;
use cosmrs::tendermint::{abci, block};
use cosmrs::{bip32, tx, AccountId};
use std::io;
use thiserror::Error;
pub use cosmrs::rpc::error::{
Error as TendermintRpcError, ErrorDetail as TendermintRpcErrorDetail,
};
pub use cosmrs::rpc::response_error::{Code, ResponseError};
#[derive(Debug, Error)]
pub enum NymdError {
#[error("No contract address is available to perform the call")]
NoContractAddressAvailable,
#[error("There was an issue with bip32 - {0}")]
Bip32Error(#[from] bip32::Error),
#[error("There was an issue with bip32 - {0}")]
Bip39Error(#[from] bip39::Error),
#[error("Failed to derive account address")]
AccountDerivationError,
#[error("Address {0} was not found in the wallet")]
SigningAccountNotFound(AccountId),
#[error("Failed to sign raw transaction")]
SigningFailure,
#[error("{0} is not a valid tx hash")]
InvalidTxHash(String),
#[error("There was an issue with a tendermint RPC request - {0}")]
TendermintError(#[from] TendermintRpcError),
#[error("There was an issue when attempting to serialize data")]
SerializationError(String),
#[error("There was an issue when attempting to deserialize data")]
DeserializationError(String),
#[error("There was an issue when attempting to encode our protobuf data - {0}")]
ProtobufEncodingError(#[from] prost::EncodeError),
#[error("There was an issue when attempting to decode our protobuf data - {0}")]
ProtobufDecodingError(#[from] prost::DecodeError),
#[error("Account {0} does not exist on the chain")]
NonExistentAccountError(AccountId),
#[error("There was an issue with the serialization/deserialization - {0}")]
SerdeJsonError(#[from] serde_json::Error),
#[error("Account {0} is not a valid account address")]
MalformedAccountAddress(String),
#[error("Account {0} has an invalid associated public key")]
InvalidPublicKey(AccountId),
#[error("Queried contract (code_id: {0}) did not have any code information attached")]
NoCodeInformation(ContractCodeId),
#[error("Queried contract (address: {0}) did not have any contract information attached")]
NoContractInformation(AccountId),
#[error("Contract contains invalid operations in its history")]
InvalidContractHistoryOperation,
#[error("Block has an invalid height (either negative or larger than i64::MAX")]
InvalidHeight,
#[error("Failed to compress provided wasm code - {0}")]
WasmCompressionError(io::Error),
#[error("Logs returned from the validator were malformed")]
MalformedLogString,
#[error(
"Error when broadcasting tx {hash} at height {height}. Error occurred during CheckTx phase. Code: {code}; Raw log: {raw_log}"
)]
BroadcastTxErrorCheckTx {
hash: tx::Hash,
height: block::Height,
code: u32,
raw_log: String,
},
#[error(
"Error when broadcasting tx {hash} at height {height}. Error occurred during DeliverTx phase. Code: {code}; Raw log: {raw_log}"
)]
BroadcastTxErrorDeliverTx {
hash: tx::Hash,
height: block::Height,
code: u32,
raw_log: String,
},
#[error("The provided gas price is malformed")]
MalformedGasPrice,
#[error("Failed to estimate gas price for the transaction")]
GasEstimationFailure,
#[error("Abci query failed with code {0} - {1}")]
AbciError(u32, abci::Log),
}
impl NymdError {
pub fn is_tendermint_response_timeout(&self) -> bool {
match &self {
NymdError::TendermintError(TendermintRpcError(
TendermintRpcErrorDetail::Response(err),
_,
)) => {
let response = &err.source;
if response.code() == Code::InternalError {
// 0.34 (and earlier) versions of tendermint seemed to be using phrase "timed out waiting ..."
// (https://github.com/tendermint/tendermint/blob/v0.34.13/rpc/core/mempool.go#L124)
// while 0.35+ has "timeout waiting for ..."
// https://github.com/tendermint/tendermint/blob/v0.35.0-rc3/internal/rpc/core/mempool.go#L99
// note that as of the time of writing this comment (08.10.2021), the most recent version
// of cosmos-sdk (v0.44.1) uses tendermint 0.34.13
if let Some(data) = response.data() {
data.contains("timed out") || data.contains("timeout")
} else {
false
}
} else {
false
}
}
_ => false,
}
}
pub fn is_tendermint_response_duplicate(&self) -> bool {
match &self {
NymdError::TendermintError(TendermintRpcError(
TendermintRpcErrorDetail::Response(err),
_,
)) => {
let response = &err.source;
if response.code() == Code::InternalError {
// this particular error message seems to be unchanged between 0.34 and newer versions
// https://github.com/tendermint/tendermint/blob/v0.34.13/mempool/errors.go#L10
// https://github.com/tendermint/tendermint/blob/v0.35.0-rc3/types/mempool.go#L10
if let Some(data) = response.data() {
data.contains("tx already exists in cache")
} else {
false
}
} else {
false
}
}
_ => false,
}
}
}