5f7b3db9a4
* Add coconut verifier structure for coconut protocol in gateway * Add endpoint for validator-api cred verification * Remove unused signature field * Register new endpoint * Improve validator-api config handling * Aggregate verif result from all apis * Simplify aggregate functions * Verify cred on apis correctly * Introduced coconut bandwidth contract to validator client * Fix rebase double import * Fix clippy on non-coconut * Add multisig contract address to validator client * Refactor Credential struct * Do bincode magic in the coconut interface * Implement serialization for credential and remove bindcode * Fix clippy and don't remove dkg * Client release funds proposal * Add wrapper for blinded serial number Also compare theta with a blinded serial number (in base 58 form) for future double spend protection. * Only post blinded serial number to blockchain * Validator api propose credential spending * Fix wallet * Gateway calls proposal creation * Query for proposal in verify coconut * Remove db from git * Verify against proposal description * Validator apis vote based on verification of cred * Fix wallet fmt * Execute the release of funds * Fix translation between token and bytes * Update CHANGELOG
187 lines
6.7 KiB
Rust
187 lines
6.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 std::time::Duration;
|
|
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 bip39 - {0}")]
|
|
Bip39Error(#[from] bip39::Error),
|
|
|
|
#[error("There was an issue on the cosmrs side - {0}")]
|
|
CosmrsError(#[from] cosmrs::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 ({0})")]
|
|
SerializationError(String),
|
|
|
|
#[error("There was an issue when attempting to deserialize data ({0})")]
|
|
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: Option<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: Option<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),
|
|
|
|
#[error("Unsupported account type: {type_url}")]
|
|
UnsupportedAccountType { type_url: String },
|
|
|
|
#[error("{coin_representation} is not a valid Cosmos Coin")]
|
|
MalformedCoin { coin_representation: String },
|
|
|
|
#[error("This account does not have BaseAccount information available to it")]
|
|
NoBaseAccountInformationAvailable,
|
|
|
|
#[error("Transaction with ID {hash} has been submitted but not yet found on the chain. You might want to check for it later. There was a total wait of {} seconds", .timeout.as_secs())]
|
|
BroadcastTimeout { hash: tx::Hash, timeout: Duration },
|
|
|
|
#[error("Cosmwasm std error: {0}")]
|
|
CosmwasmStdError(#[from] cosmwasm_std::StdError),
|
|
|
|
#[error("Coconut interface error: {0}")]
|
|
CoconutInterfaceError(#[from] coconut_interface::error::CoconutInterfaceError),
|
|
}
|
|
|
|
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,
|
|
}
|
|
}
|
|
}
|