From a700e4902a177408f8945f1014e557a3d62b84c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Tue, 13 Sep 2022 15:31:10 +0200 Subject: [PATCH 1/3] ledger: use storage_api::Error in VpEnv and TxEnv instead of generic This inverts the wrapping of errors, storage_api::Error now wraps NativeVp:Error and some other IBC and PoS custom errors --- shared/src/ledger/ibc/handler.rs | 9 ++ shared/src/ledger/native_vp.rs | 55 ++++++----- shared/src/ledger/pos/mod.rs | 36 ++++++- shared/src/ledger/pos/vp.rs | 12 +-- shared/src/ledger/storage_api/error.rs | 23 +++++ shared/src/ledger/storage_api/mod.rs | 2 +- shared/src/ledger/tx_env.rs | 25 ++--- shared/src/ledger/vp_env.rs | 67 ++++++------- tx_prelude/src/error.rs | 112 ---------------------- tx_prelude/src/ibc.rs | 7 -- tx_prelude/src/lib.rs | 30 +++--- tx_prelude/src/proof_of_stake.rs | 47 ++------- vp_prelude/src/error.rs | 110 --------------------- vp_prelude/src/lib.rs | 88 ++++++++--------- wasm/wasm_source/src/tx_bond.rs | 4 +- wasm/wasm_source/src/tx_from_intent.rs | 4 +- wasm/wasm_source/src/tx_ibc.rs | 2 +- wasm/wasm_source/src/tx_init_account.rs | 4 +- wasm/wasm_source/src/tx_init_nft.rs | 4 +- wasm/wasm_source/src/tx_init_proposal.rs | 4 +- wasm/wasm_source/src/tx_init_validator.rs | 4 +- wasm/wasm_source/src/tx_mint_nft.rs | 4 +- wasm/wasm_source/src/tx_transfer.rs | 4 +- wasm/wasm_source/src/tx_unbond.rs | 4 +- wasm/wasm_source/src/tx_update_vp.rs | 4 +- wasm/wasm_source/src/tx_vote_proposal.rs | 4 +- wasm/wasm_source/src/tx_withdraw.rs | 4 +- wasm_for_tests/wasm_source/src/lib.rs | 4 +- 28 files changed, 237 insertions(+), 440 deletions(-) delete mode 100644 tx_prelude/src/error.rs delete mode 100644 vp_prelude/src/error.rs diff --git a/shared/src/ledger/ibc/handler.rs b/shared/src/ledger/ibc/handler.rs index 5cbee20756..4a3fe528a9 100644 --- a/shared/src/ledger/ibc/handler.rs +++ b/shared/src/ledger/ibc/handler.rs @@ -70,6 +70,7 @@ use crate::ibc::events::IbcEvent; use crate::ibc::mock::client_state::{MockClientState, MockConsensusState}; use crate::ibc::timestamp::Timestamp; use crate::ledger::ibc::storage; +use crate::ledger::storage_api; use crate::tendermint::Time; use crate::tendermint_proto::{Error as ProtoError, Protobuf}; use crate::types::address::{Address, InternalAddress}; @@ -117,6 +118,14 @@ pub enum Error { ReceivingToken(String), } +// This is needed to use `ibc::Handler::Error` with `IbcActions` in +// `tx_prelude/src/ibc.rs` +impl From for storage_api::Error { + fn from(err: Error) -> Self { + storage_api::Error::new(err) + } +} + /// for handling IBC modules pub type Result = std::result::Result; diff --git a/shared/src/ledger/native_vp.rs b/shared/src/ledger/native_vp.rs index f17b339086..b98794d12c 100644 --- a/shared/src/ledger/native_vp.rs +++ b/shared/src/ledger/native_vp.rs @@ -17,7 +17,9 @@ use crate::vm::prefix_iter::PrefixIterators; use crate::vm::WasmCacheAccess; /// Possible error in a native VP host function call -pub type Error = vp_env::RuntimeError; +/// The `storage_api::Error` may wrap the `vp_env::RuntimeError` and can +/// be extended with other custom errors when using `trait VpEnv`. +pub type Error = storage_api::Error; /// A native VP module should implement its validation logic using this trait. pub trait NativeVp { @@ -201,23 +203,23 @@ where &self, prefix: &crate::types::storage::Key, ) -> Result { - self.ctx.iter_prefix(prefix).into_storage_result() + self.ctx.iter_prefix(prefix) } fn get_chain_id(&self) -> Result { - self.ctx.get_chain_id().into_storage_result() + self.ctx.get_chain_id() } fn get_block_height(&self) -> Result { - self.ctx.get_block_height().into_storage_result() + self.ctx.get_block_height() } fn get_block_hash(&self) -> Result { - self.ctx.get_block_hash().into_storage_result() + self.ctx.get_block_hash() } fn get_block_epoch(&self) -> Result { - self.ctx.get_block_epoch().into_storage_result() + self.ctx.get_block_epoch() } } @@ -275,23 +277,23 @@ where &self, prefix: &crate::types::storage::Key, ) -> Result { - self.ctx.iter_prefix(prefix).into_storage_result() + self.ctx.iter_prefix(prefix) } fn get_chain_id(&self) -> Result { - self.ctx.get_chain_id().into_storage_result() + self.ctx.get_chain_id() } fn get_block_height(&self) -> Result { - self.ctx.get_block_height().into_storage_result() + self.ctx.get_block_height() } fn get_block_hash(&self) -> Result { - self.ctx.get_block_hash().into_storage_result() + self.ctx.get_block_hash() } fn get_block_epoch(&self) -> Result { - self.ctx.get_block_epoch().into_storage_result() + self.ctx.get_block_epoch() } } @@ -301,7 +303,6 @@ where H: 'static + StorageHasher, CA: 'static + WasmCacheAccess, { - type Error = Error; type Post = CtxPostStorageRead<'view, 'a, DB, H, CA>; type Pre = CtxPreStorageRead<'view, 'a, DB, H, CA>; type PrefixIter = >::PrefixIter; @@ -317,61 +318,70 @@ where fn read_temp( &self, key: &Key, - ) -> Result, Self::Error> { + ) -> Result, storage_api::Error> { vp_env::read_temp( &mut *self.gas_meter.borrow_mut(), self.write_log, key, ) .map(|data| data.and_then(|t| T::try_from_slice(&t[..]).ok())) + .into_storage_result() } fn read_bytes_temp( &self, key: &Key, - ) -> Result>, Self::Error> { + ) -> Result>, storage_api::Error> { vp_env::read_temp( &mut *self.gas_meter.borrow_mut(), self.write_log, key, ) + .into_storage_result() } - fn get_chain_id(&'view self) -> Result { + fn get_chain_id(&'view self) -> Result { vp_env::get_chain_id(&mut *self.gas_meter.borrow_mut(), self.storage) + .into_storage_result() } - fn get_block_height(&'view self) -> Result { + fn get_block_height( + &'view self, + ) -> Result { vp_env::get_block_height( &mut *self.gas_meter.borrow_mut(), self.storage, ) + .into_storage_result() } - fn get_block_hash(&'view self) -> Result { + fn get_block_hash(&'view self) -> Result { vp_env::get_block_hash(&mut *self.gas_meter.borrow_mut(), self.storage) + .into_storage_result() } - fn get_block_epoch(&'view self) -> Result { + fn get_block_epoch(&'view self) -> Result { vp_env::get_block_epoch(&mut *self.gas_meter.borrow_mut(), self.storage) + .into_storage_result() } fn iter_prefix( &'view self, prefix: &Key, - ) -> Result { + ) -> Result { vp_env::iter_prefix( &mut *self.gas_meter.borrow_mut(), self.storage, prefix, ) + .into_storage_result() } fn eval( &self, vp_code: Vec, input_data: Vec, - ) -> Result { + ) -> Result { #[cfg(feature = "wasm-runtime")] { use std::marker::PhantomData; @@ -429,11 +439,12 @@ where &self, pk: &crate::types::key::common::PublicKey, sig: &crate::types::key::common::Signature, - ) -> Result { + ) -> Result { Ok(self.tx.verify_sig(pk, sig).is_ok()) } - fn get_tx_code_hash(&self) -> Result { + fn get_tx_code_hash(&self) -> Result { vp_env::get_tx_code_hash(&mut *self.gas_meter.borrow_mut(), self.tx) + .into_storage_result() } } diff --git a/shared/src/ledger/pos/mod.rs b/shared/src/ledger/pos/mod.rs index a9d72e84bb..3b498727df 100644 --- a/shared/src/ledger/pos/mod.rs +++ b/shared/src/ledger/pos/mod.rs @@ -13,6 +13,7 @@ use namada_proof_of_stake::PosBase; pub use storage::*; pub use vp::PosVP; +use super::storage_api; use crate::ledger::storage::{self as ledger_storage, Storage, StorageHasher}; use crate::types::address::{self, Address, InternalAddress}; use crate::types::storage::Epoch; @@ -88,6 +89,40 @@ impl From for Epoch { } } +// The error conversions are needed to implement `PosActions` in +// `tx_prelude/src/proof_of_stake.rs` +impl From> + for storage_api::Error +{ + fn from(err: namada_proof_of_stake::BecomeValidatorError
) -> Self { + Self::new(err) + } +} + +impl From> for storage_api::Error { + fn from(err: namada_proof_of_stake::BondError
) -> Self { + Self::new(err) + } +} + +impl From> + for storage_api::Error +{ + fn from( + err: namada_proof_of_stake::UnbondError, + ) -> Self { + Self::new(err) + } +} + +impl From> + for storage_api::Error +{ + fn from(err: namada_proof_of_stake::WithdrawError
) -> Self { + Self::new(err) + } +} + #[macro_use] mod macros { /// Implement `PosReadOnly` for a type that implements @@ -115,7 +150,6 @@ mod macros { $( $any )* { type Address = $crate::types::address::Address; - // type Error = $crate::ledger::native_vp::Error; type $error = $err_ty; type PublicKey = $crate::types::key::common::PublicKey; type TokenAmount = $crate::types::token::Amount; diff --git a/shared/src/ledger/pos/vp.rs b/shared/src/ledger/pos/vp.rs index 2f19b6d1a4..0551c5de7f 100644 --- a/shared/src/ledger/pos/vp.rs +++ b/shared/src/ledger/pos/vp.rs @@ -47,8 +47,6 @@ use crate::vm::WasmCacheAccess; pub enum Error { #[error("Native VP error: {0}")] NativeVpError(native_vp::Error), - #[error("Storage error: {0}")] - StorageApi(storage_api::Error), } /// PoS functions result @@ -324,7 +322,7 @@ where } impl_pos_read_only! { - type Error = native_vp::Error; + type Error = storage_api::Error; impl<'f, 'a, DB, H, CA> PosReadOnly for CtxPreStorageRead<'f, 'a, DB, H, CA> where DB: ledger_storage::DB + for<'iter> ledger_storage::DBIter<'iter> +'static, @@ -333,7 +331,7 @@ impl_pos_read_only! { } impl_pos_read_only! { - type Error = native_vp::Error; + type Error = storage_api::Error; impl<'f, 'a, DB, H, CA> PosReadOnly for CtxPostStorageRead<'f, 'a, DB, H, CA> where DB: ledger_storage::DB + for<'iter> ledger_storage::DBIter<'iter> +'static, @@ -346,9 +344,3 @@ impl From for Error { Self::NativeVpError(err) } } - -impl From for Error { - fn from(err: storage_api::Error) -> Self { - Self::StorageApi(err) - } -} diff --git a/shared/src/ledger/storage_api/error.rs b/shared/src/ledger/storage_api/error.rs index d01fbfd287..8af95be723 100644 --- a/shared/src/ledger/storage_api/error.rs +++ b/shared/src/ledger/storage_api/error.rs @@ -6,6 +6,8 @@ use thiserror::Error; #[allow(missing_docs)] #[derive(Error, Debug)] pub enum Error { + #[error("{0}")] + SimpleMessage(&'static str), #[error("{0}")] Custom(CustomError), #[error("{0}: {1}")] @@ -48,6 +50,12 @@ impl Error { Self::Custom(CustomError(error.into())) } + /// Create an [`enum@Error`] from a static message. + #[inline] + pub const fn new_const(msg: &'static str) -> Self { + Self::SimpleMessage(msg) + } + /// Wrap another [`std::error::Error`] with a static message. pub fn wrap(msg: &'static str, error: E) -> Self where @@ -66,3 +74,18 @@ impl std::fmt::Display for CustomError { self.0.fmt(f) } } + +/// An extension to [`Option`] to allow turning `None` case to an Error from a +/// static string (handy for WASM). +pub trait OptionExt { + /// Transforms the [`Option`] into a [`Result`], mapping + /// [`Some(v)`] to [`Ok(v)`] and [`None`] to the given static error + /// message. + fn ok_or_err_msg(self, msg: &'static str) -> Result; +} + +impl OptionExt for Option { + fn ok_or_err_msg(self, msg: &'static str) -> Result { + self.ok_or_else(|| Error::new_const(msg)) + } +} diff --git a/shared/src/ledger/storage_api/mod.rs b/shared/src/ledger/storage_api/mod.rs index 94be4d8568..5dfec7e76e 100644 --- a/shared/src/ledger/storage_api/mod.rs +++ b/shared/src/ledger/storage_api/mod.rs @@ -4,7 +4,7 @@ mod error; use borsh::{BorshDeserialize, BorshSerialize}; -pub use error::{CustomError, Error, Result, ResultExt}; +pub use error::{CustomError, Error, OptionExt, Result, ResultExt}; use crate::types::storage::{self, BlockHash, BlockHeight, Epoch}; diff --git a/shared/src/ledger/tx_env.rs b/shared/src/ledger/tx_env.rs index 1db8fad09b..7672ac6505 100644 --- a/shared/src/ledger/tx_env.rs +++ b/shared/src/ledger/tx_env.rs @@ -3,7 +3,7 @@ use borsh::BorshSerialize; -use crate::ledger::storage_api::{StorageRead, StorageWrite}; +use crate::ledger::storage_api::{self, StorageRead, StorageWrite}; use crate::types::address::Address; use crate::types::ibc::IbcEvent; use crate::types::storage; @@ -11,23 +11,20 @@ use crate::types::time::Rfc3339String; /// Transaction host functions pub trait TxEnv<'iter>: StorageRead<'iter> + StorageWrite { - /// Host env functions possible errors - type Error; - /// Write a temporary value to be encoded with Borsh at the given key to /// storage. fn write_temp( &mut self, key: &storage::Key, val: T, - ) -> Result<(), Self::Error>; + ) -> Result<(), storage_api::Error>; /// Write a temporary value as bytes at the given key to storage. fn write_bytes_temp( &mut self, key: &storage::Key, val: impl AsRef<[u8]>, - ) -> Result<(), Self::Error>; + ) -> Result<(), storage_api::Error>; /// Insert a verifier address. This address must exist on chain, otherwise /// the transaction will be rejected. @@ -35,26 +32,32 @@ pub trait TxEnv<'iter>: StorageRead<'iter> + StorageWrite { /// Validity predicates of each verifier addresses inserted in the /// transaction will validate the transaction and will receive all the /// changed storage keys and initialized accounts in their inputs. - fn insert_verifier(&mut self, addr: &Address) -> Result<(), Self::Error>; + fn insert_verifier( + &mut self, + addr: &Address, + ) -> Result<(), storage_api::Error>; /// Initialize a new account generates a new established address and /// writes the given code as its validity predicate into the storage. fn init_account( &mut self, code: impl AsRef<[u8]>, - ) -> Result; + ) -> Result; /// Update a validity predicate fn update_validity_predicate( &mut self, addr: &Address, code: impl AsRef<[u8]>, - ) -> Result<(), Self::Error>; + ) -> Result<(), storage_api::Error>; /// Emit an IBC event. There can be only one event per transaction. On /// multiple calls, only the last emitted event will be used. - fn emit_ibc_event(&mut self, event: &IbcEvent) -> Result<(), Self::Error>; + fn emit_ibc_event( + &mut self, + event: &IbcEvent, + ) -> Result<(), storage_api::Error>; /// Get time of the current block header as rfc 3339 string - fn get_block_time(&self) -> Result; + fn get_block_time(&self) -> Result; } diff --git a/shared/src/ledger/vp_env.rs b/shared/src/ledger/vp_env.rs index e1f72d8505..8398f37cda 100644 --- a/shared/src/ledger/vp_env.rs +++ b/shared/src/ledger/vp_env.rs @@ -22,9 +22,6 @@ pub trait VpEnv<'view> { /// Storage read prefix iterator type PrefixIter; - /// Host functions possible errors, extensible with custom user errors. - type Error: From; - /// Type to read storage state before the transaction execution type Pre: StorageRead<'view, PrefixIter = Self::PrefixIter>; @@ -43,36 +40,37 @@ pub trait VpEnv<'view> { fn read_temp( &self, key: &Key, - ) -> Result, Self::Error>; + ) -> Result, storage_api::Error>; /// Storage read temporary state raw bytes (after tx execution). It will try /// to read from only the write log. fn read_bytes_temp( &self, key: &Key, - ) -> Result>, Self::Error>; + ) -> Result>, storage_api::Error>; /// Getting the chain ID. - fn get_chain_id(&'view self) -> Result; + fn get_chain_id(&'view self) -> Result; /// Getting the block height. The height is that of the block to which the /// current transaction is being applied. - fn get_block_height(&'view self) -> Result; + fn get_block_height(&'view self) + -> Result; /// Getting the block hash. The height is that of the block to which the /// current transaction is being applied. - fn get_block_hash(&'view self) -> Result; + fn get_block_hash(&'view self) -> Result; /// Getting the block epoch. The epoch is that of the block to which the /// current transaction is being applied. - fn get_block_epoch(&'view self) -> Result; + fn get_block_epoch(&'view self) -> Result; /// Storage prefix iterator. It will try to get an iterator from the /// storage. fn iter_prefix( &'view self, prefix: &Key, - ) -> Result; + ) -> Result; /// Evaluate a validity predicate with given data. The address, changed /// storage keys and verifiers will have the same values as the input to @@ -84,7 +82,7 @@ pub trait VpEnv<'view> { &self, vp_code: Vec, input_data: Vec, - ) -> Result; + ) -> Result; /// Verify a transaction signature. The signature is expected to have been /// produced on the encoded transaction [`crate::proto::Tx`] @@ -93,10 +91,10 @@ pub trait VpEnv<'view> { &self, pk: &common::PublicKey, sig: &common::Signature, - ) -> Result; + ) -> Result; /// Get a tx hash - fn get_tx_code_hash(&self) -> Result; + fn get_tx_code_hash(&self) -> Result; // ---- Methods below have default implementation via `pre/post` ---- @@ -105,8 +103,8 @@ pub trait VpEnv<'view> { fn read_pre( &'view self, key: &Key, - ) -> Result, Self::Error> { - self.pre().read(key).map_err(Into::into) + ) -> Result, storage_api::Error> { + self.pre().read(key) } /// Storage read prior state raw bytes (before tx execution). It @@ -114,8 +112,8 @@ pub trait VpEnv<'view> { fn read_bytes_pre( &'view self, key: &Key, - ) -> Result>, Self::Error> { - self.pre().read_bytes(key).map_err(Into::into) + ) -> Result>, storage_api::Error> { + self.pre().read_bytes(key) } /// Storage read posterior state Borsh encoded value (after tx execution). @@ -124,8 +122,8 @@ pub trait VpEnv<'view> { fn read_post( &'view self, key: &Key, - ) -> Result, Self::Error> { - self.post().read(key).map_err(Into::into) + ) -> Result, storage_api::Error> { + self.post().read(key) } /// Storage read posterior state raw bytes (after tx execution). It will try @@ -134,20 +132,23 @@ pub trait VpEnv<'view> { fn read_bytes_post( &'view self, key: &Key, - ) -> Result>, Self::Error> { - self.post().read_bytes(key).map_err(Into::into) + ) -> Result>, storage_api::Error> { + self.post().read_bytes(key) } /// Storage `has_key` in prior state (before tx execution). It will try to /// read from the storage. - fn has_key_pre(&'view self, key: &Key) -> Result { - self.pre().has_key(key).map_err(Into::into) + fn has_key_pre(&'view self, key: &Key) -> Result { + self.pre().has_key(key) } /// Storage `has_key` in posterior state (after tx execution). It will try /// to check the write log first and if no entry found then the storage. - fn has_key_post(&'view self, key: &Key) -> Result { - self.post().has_key(key).map_err(Into::into) + fn has_key_post( + &'view self, + key: &Key, + ) -> Result { + self.post().has_key(key) } /// Storage prefix iterator for prior state (before tx execution). It will @@ -155,8 +156,8 @@ pub trait VpEnv<'view> { fn iter_pre_next( &'view self, iter: &mut Self::PrefixIter, - ) -> Result)>, Self::Error> { - self.pre().iter_next(iter).map_err(Into::into) + ) -> Result)>, storage_api::Error> { + self.pre().iter_next(iter) } /// Storage prefix iterator next for posterior state (after tx execution). @@ -165,8 +166,8 @@ pub trait VpEnv<'view> { fn iter_post_next( &'view self, iter: &mut Self::PrefixIter, - ) -> Result)>, Self::Error> { - self.post().iter_next(iter).map_err(Into::into) + ) -> Result)>, storage_api::Error> { + self.post().iter_next(iter) } } @@ -190,8 +191,6 @@ pub enum RuntimeError { ReadTemporaryValueError, #[error("Trying to read a permament value with read_temp")] ReadPermanentValueError, - #[error("Storage error: {0}")] - StorageApi(storage_api::Error), } /// VP environment function result @@ -495,9 +494,3 @@ where } Ok(None) } - -impl From for RuntimeError { - fn from(err: storage_api::Error) -> Self { - Self::StorageApi(err) - } -} diff --git a/tx_prelude/src/error.rs b/tx_prelude/src/error.rs deleted file mode 100644 index ce7b9fa5e9..0000000000 --- a/tx_prelude/src/error.rs +++ /dev/null @@ -1,112 +0,0 @@ -//! Helpers for error handling in WASM -//! -//! This module is currently duplicated in tx_prelude and vp_prelude crates to -//! be able to implement `From` conversion on error types from other crates, -//! avoiding `error[E0117]: only traits defined in the current crate can be -//! implemented for arbitrary types` - -use namada::ledger::storage_api; -use thiserror::Error; - -#[allow(missing_docs)] -#[derive(Error, Debug)] -pub enum Error { - #[error("{0}")] - SimpleMessage(&'static str), - #[error("{0}")] - Custom(CustomError), - #[error("{0}: {1}")] - CustomWithMessage(&'static str, CustomError), -} - -/// Result of transaction or VP. -pub type EnvResult = Result; - -pub trait ResultExt { - /// Replace a possible error with a static message in [`EnvResult`]. - fn err_msg(self, msg: &'static str) -> EnvResult; -} - -// This is separate from `ResultExt`, because the implementation requires -// different bounds for `T`. -pub trait ResultExt2 { - /// Convert a [`Result`] into [`EnvResult`]. - fn into_env_result(self) -> EnvResult; - - /// Add a static message to a possible error in [`EnvResult`]. - fn wrap_err(self, msg: &'static str) -> EnvResult; -} - -pub trait OptionExt { - /// Transforms the [`Option`] into a [`EnvResult`], mapping - /// [`Some(v)`] to [`Ok(v)`] and [`None`] to the given static error - /// message. - fn ok_or_err_msg(self, msg: &'static str) -> EnvResult; -} - -impl ResultExt for Result { - fn err_msg(self, msg: &'static str) -> EnvResult { - self.map_err(|_err| Error::new_const(msg)) - } -} - -impl ResultExt2 for Result -where - E: std::error::Error + Send + Sync + 'static, -{ - fn into_env_result(self) -> EnvResult { - self.map_err(Error::new) - } - - fn wrap_err(self, msg: &'static str) -> EnvResult { - self.map_err(|err| Error::wrap(msg, err)) - } -} - -impl OptionExt for Option { - fn ok_or_err_msg(self, msg: &'static str) -> EnvResult { - self.ok_or_else(|| Error::new_const(msg)) - } -} - -impl Error { - /// Create an [`enum@Error`] from a static message. - #[inline] - pub const fn new_const(msg: &'static str) -> Self { - Self::SimpleMessage(msg) - } - - /// Create an [`enum@Error`] from another [`std::error::Error`]. - pub fn new(error: E) -> Self - where - E: Into>, - { - Self::Custom(CustomError(error.into())) - } - - /// Wrap another [`std::error::Error`] with a static message. - pub fn wrap(msg: &'static str, error: E) -> Self - where - E: Into>, - { - Self::CustomWithMessage(msg, CustomError(error.into())) - } -} - -/// A custom error -#[derive(Debug)] -pub struct CustomError(Box); - -impl std::fmt::Display for CustomError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.0.fmt(f) - } -} - -impl From for Error { - fn from(err: storage_api::Error) -> Self { - // storage_api::Error::Custom(CustomError {Box}) - // Error:Custom(storage_api::Error::Custom(CustomError {Box})) - Self::new(err) - } -} diff --git a/tx_prelude/src/ibc.rs b/tx_prelude/src/ibc.rs index 4a8a3ef3a9..494d5e7cd3 100644 --- a/tx_prelude/src/ibc.rs +++ b/tx_prelude/src/ibc.rs @@ -12,13 +12,6 @@ use namada::types::token::Amount; use crate::token::transfer; use crate::Ctx; -// This is needed to use `ibc::Handler::Error` with `IbcActions` below -impl From for crate::Error { - fn from(err: Error) -> Self { - crate::Error::new(err) - } -} - impl IbcActions for Ctx { type Error = crate::Error; diff --git a/tx_prelude/src/lib.rs b/tx_prelude/src/lib.rs index ade290bf65..a18d59c9a8 100644 --- a/tx_prelude/src/lib.rs +++ b/tx_prelude/src/lib.rs @@ -6,7 +6,6 @@ #![deny(rustdoc::broken_intra_doc_links)] #![deny(rustdoc::private_intra_doc_links)] -mod error; pub mod governance; pub mod ibc; pub mod intent; @@ -18,12 +17,13 @@ use core::slice; use std::marker::PhantomData; pub use borsh::{BorshDeserialize, BorshSerialize}; -pub use error::*; pub use namada::ledger::governance::storage as gov_storage; pub use namada::ledger::parameters::storage as parameters_storage; pub use namada::ledger::storage::types::encode; use namada::ledger::storage_api; -pub use namada::ledger::storage_api::{StorageRead, StorageWrite}; +pub use namada::ledger::storage_api::{ + Error, OptionExt, ResultExt, StorageRead, StorageWrite, +}; pub use namada::ledger::treasury::storage as treasury_storage; pub use namada::ledger::tx_env::TxEnv; pub use namada::proto::{Signed, SignedTxData}; @@ -89,6 +89,10 @@ impl Ctx { } } +/// Result of `TxEnv`, `storage_api::StorageRead` or `storage_api::StorageWrite` +/// method call +pub type EnvResult = Result; + /// Transaction result pub type TxResult = EnvResult<()>; @@ -101,7 +105,7 @@ impl StorageRead<'_> for Ctx { fn read_bytes( &self, key: &namada::types::storage::Key, - ) -> Result>, storage_api::Error> { + ) -> Result>, Error> { let key = key.to_string(); let read_result = unsafe { anoma_tx_read(key.as_ptr() as _, key.len() as _) }; @@ -111,14 +115,14 @@ impl StorageRead<'_> for Ctx { fn has_key( &self, key: &namada::types::storage::Key, - ) -> Result { + ) -> Result { let key = key.to_string(); let found = unsafe { anoma_tx_has_key(key.as_ptr() as _, key.len() as _) }; Ok(HostEnvResult::is_success(found)) } - fn get_chain_id(&self) -> Result { + fn get_chain_id(&self) -> Result { let result = Vec::with_capacity(CHAIN_ID_LENGTH); unsafe { anoma_tx_get_chain_id(result.as_ptr() as _); @@ -131,13 +135,13 @@ impl StorageRead<'_> for Ctx { fn get_block_height( &self, - ) -> Result { + ) -> Result { Ok(BlockHeight(unsafe { anoma_tx_get_block_height() })) } fn get_block_hash( &self, - ) -> Result { + ) -> Result { let result = Vec::with_capacity(BLOCK_HASH_LENGTH); unsafe { anoma_tx_get_block_hash(result.as_ptr() as _); @@ -148,16 +152,14 @@ impl StorageRead<'_> for Ctx { Ok(BlockHash::try_from(slice).expect("Cannot convert the hash")) } - fn get_block_epoch( - &self, - ) -> Result { + fn get_block_epoch(&self) -> Result { Ok(Epoch(unsafe { anoma_tx_get_block_epoch() })) } fn iter_prefix( &self, prefix: &namada::types::storage::Key, - ) -> Result { + ) -> Result { let prefix = prefix.to_string(); let iter_id = unsafe { anoma_tx_iter_prefix(prefix.as_ptr() as _, prefix.len() as _) @@ -168,7 +170,7 @@ impl StorageRead<'_> for Ctx { fn iter_next( &self, iter: &mut Self::PrefixIter, - ) -> Result)>, storage_api::Error> { + ) -> Result)>, Error> { let read_result = unsafe { anoma_tx_iter_next(iter.0) }; Ok(read_key_val_bytes_from_buffer( read_result, @@ -206,8 +208,6 @@ impl StorageWrite for Ctx { } impl TxEnv<'_> for Ctx { - type Error = Error; - fn get_block_time(&self) -> Result { let read_result = unsafe { anoma_tx_get_block_time() }; let time_value = read_from_buffer(read_result, anoma_tx_result_buffer) diff --git a/tx_prelude/src/proof_of_stake.rs b/tx_prelude/src/proof_of_stake.rs index 65a6c3f6cd..97a258365c 100644 --- a/tx_prelude/src/proof_of_stake.rs +++ b/tx_prelude/src/proof_of_stake.rs @@ -118,34 +118,6 @@ namada::impl_pos_read_only! { impl namada_proof_of_stake::PosReadOnly for Ctx } -impl From> for Error { - fn from(err: namada_proof_of_stake::BecomeValidatorError
) -> Self { - Self::new(err) - } -} - -impl From> for Error { - fn from(err: namada_proof_of_stake::BondError
) -> Self { - Self::new(err) - } -} - -impl From> - for Error -{ - fn from( - err: namada_proof_of_stake::UnbondError, - ) -> Self { - Self::new(err) - } -} - -impl From> for Error { - fn from(err: namada_proof_of_stake::WithdrawError
) -> Self { - Self::new(err) - } -} - impl namada_proof_of_stake::PosActions for Ctx { type BecomeValidatorError = crate::Error; type BondError = crate::Error; @@ -156,7 +128,7 @@ impl namada_proof_of_stake::PosActions for Ctx { &mut self, params: &PosParams, ) -> Result<(), Self::Error> { - self.write(¶ms_key(), params).into_env_result() + self.write(¶ms_key(), params) } fn write_validator_address_raw_hash( @@ -165,7 +137,6 @@ impl namada_proof_of_stake::PosActions for Ctx { ) -> Result<(), Self::Error> { let raw_hash = address.raw_hash().unwrap().to_owned(); self.write(&validator_address_raw_hash_key(raw_hash), address) - .into_env_result() } fn write_validator_staking_reward_address( @@ -174,7 +145,6 @@ impl namada_proof_of_stake::PosActions for Ctx { value: Self::Address, ) -> Result<(), Self::Error> { self.write(&validator_staking_reward_address_key(key), &value) - .into_env_result() } fn write_validator_consensus_key( @@ -183,7 +153,6 @@ impl namada_proof_of_stake::PosActions for Ctx { value: ValidatorConsensusKeys, ) -> Result<(), Self::Error> { self.write(&validator_consensus_key_key(key), &value) - .into_env_result() } fn write_validator_state( @@ -192,7 +161,6 @@ impl namada_proof_of_stake::PosActions for Ctx { value: ValidatorStates, ) -> Result<(), Self::Error> { self.write(&validator_state_key(key), &value) - .into_env_result() } fn write_validator_total_deltas( @@ -201,7 +169,6 @@ impl namada_proof_of_stake::PosActions for Ctx { value: ValidatorTotalDeltas, ) -> Result<(), Self::Error> { self.write(&validator_total_deltas_key(key), &value) - .into_env_result() } fn write_validator_voting_power( @@ -210,7 +177,6 @@ impl namada_proof_of_stake::PosActions for Ctx { value: ValidatorVotingPowers, ) -> Result<(), Self::Error> { self.write(&validator_voting_power_key(key), &value) - .into_env_result() } fn write_bond( @@ -218,7 +184,7 @@ impl namada_proof_of_stake::PosActions for Ctx { key: &BondId, value: Bonds, ) -> Result<(), Self::Error> { - self.write(&bond_key(key), &value).into_env_result() + self.write(&bond_key(key), &value) } fn write_unbond( @@ -226,14 +192,14 @@ impl namada_proof_of_stake::PosActions for Ctx { key: &BondId, value: Unbonds, ) -> Result<(), Self::Error> { - self.write(&unbond_key(key), &value).into_env_result() + self.write(&unbond_key(key), &value) } fn write_validator_set( &mut self, value: ValidatorSets, ) -> Result<(), Self::Error> { - self.write(&validator_set_key(), &value).into_env_result() + self.write(&validator_set_key(), &value) } fn write_total_voting_power( @@ -241,15 +207,14 @@ impl namada_proof_of_stake::PosActions for Ctx { value: TotalVotingPowers, ) -> Result<(), Self::Error> { self.write(&total_voting_power_key(), &value) - .into_env_result() } fn delete_bond(&mut self, key: &BondId) -> Result<(), Self::Error> { - self.delete(&bond_key(key)).into_env_result() + self.delete(&bond_key(key)) } fn delete_unbond(&mut self, key: &BondId) -> Result<(), Self::Error> { - self.delete(&unbond_key(key)).into_env_result() + self.delete(&unbond_key(key)) } fn transfer( diff --git a/vp_prelude/src/error.rs b/vp_prelude/src/error.rs deleted file mode 100644 index 099ae2540a..0000000000 --- a/vp_prelude/src/error.rs +++ /dev/null @@ -1,110 +0,0 @@ -//! Helpers for error handling in WASM -//! -//! This module is currently duplicated in tx_prelude and vp_prelude crates to -//! be able to implement `From` conversion on error types from other crates, -//! avoiding `error[E0117]: only traits defined in the current crate can be -//! implemented for arbitrary types` - -use namada::ledger::storage_api; -use thiserror::Error; - -#[allow(missing_docs)] -#[derive(Error, Debug)] -pub enum Error { - #[error("{0}")] - SimpleMessage(&'static str), - #[error("{0}")] - Custom(CustomError), - #[error("{0}: {1}")] - CustomWithMessage(&'static str, CustomError), -} - -/// Result of transaction or VP. -pub type EnvResult = Result; - -pub trait ResultExt { - /// Replace a possible error with a static message in [`EnvResult`]. - fn err_msg(self, msg: &'static str) -> EnvResult; -} - -// This is separate from `ResultExt`, because the implementation requires -// different bounds for `T`. -pub trait ResultExt2 { - /// Convert a [`Result`] into [`EnvResult`]. - fn into_env_result(self) -> EnvResult; - - /// Add a static message to a possible error in [`EnvResult`]. - fn wrap_err(self, msg: &'static str) -> EnvResult; -} - -pub trait OptionExt { - /// Transforms the [`Option`] into a [`EnvResult`], mapping - /// [`Some(v)`] to [`Ok(v)`] and [`None`] to the given static error - /// message. - fn ok_or_err_msg(self, msg: &'static str) -> EnvResult; -} - -impl ResultExt for Result { - fn err_msg(self, msg: &'static str) -> EnvResult { - self.map_err(|_err| Error::new_const(msg)) - } -} - -impl ResultExt2 for Result -where - E: std::error::Error + Send + Sync + 'static, -{ - fn into_env_result(self) -> EnvResult { - self.map_err(Error::new) - } - - fn wrap_err(self, msg: &'static str) -> EnvResult { - self.map_err(|err| Error::wrap(msg, err)) - } -} - -impl OptionExt for Option { - fn ok_or_err_msg(self, msg: &'static str) -> EnvResult { - self.ok_or_else(|| Error::new_const(msg)) - } -} - -impl Error { - /// Create an [`enum@Error`] from a static message. - #[inline] - pub const fn new_const(msg: &'static str) -> Self { - Self::SimpleMessage(msg) - } - - /// Create an [`enum@Error`] from another [`std::error::Error`]. - pub fn new(error: E) -> Self - where - E: Into>, - { - Self::Custom(CustomError(error.into())) - } - - /// Wrap another [`std::error::Error`] with a static message. - pub fn wrap(msg: &'static str, error: E) -> Self - where - E: Into>, - { - Self::CustomWithMessage(msg, CustomError(error.into())) - } -} - -/// A custom error -#[derive(Debug)] -pub struct CustomError(Box); - -impl std::fmt::Display for CustomError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.0.fmt(f) - } -} - -impl From for Error { - fn from(err: storage_api::Error) -> Self { - Self::new(err) - } -} diff --git a/vp_prelude/src/lib.rs b/vp_prelude/src/lib.rs index d1d3845a48..46432a3b52 100644 --- a/vp_prelude/src/lib.rs +++ b/vp_prelude/src/lib.rs @@ -6,7 +6,6 @@ #![deny(rustdoc::broken_intra_doc_links)] #![deny(rustdoc::private_intra_doc_links)] -mod error; pub mod intent; pub mod key; pub mod nft; @@ -20,9 +19,10 @@ use std::convert::TryFrom; use std::marker::PhantomData; pub use borsh::{BorshDeserialize, BorshSerialize}; -pub use error::*; pub use namada::ledger::governance::storage as gov_storage; -pub use namada::ledger::storage_api::{self, StorageRead}; +pub use namada::ledger::storage_api::{ + self, Error, OptionExt, ResultExt, StorageRead, +}; pub use namada::ledger::vp_env::VpEnv; pub use namada::ledger::{parameters, pos as proof_of_stake}; pub use namada::proto::{Signed, SignedTxData}; @@ -134,6 +134,9 @@ pub struct CtxPostStorageRead<'a> { _ctx: &'a Ctx, } +/// Result of `VpEnv` or `storage_api::StorageRead` method call +pub type EnvResult = Result; + /// Validity predicate result pub type VpResult = EnvResult; @@ -151,7 +154,6 @@ pub fn reject() -> VpResult { pub struct KeyValIterator(pub u64, pub PhantomData); impl<'view> VpEnv<'view> for Ctx { - type Error = Error; type Post = CtxPostStorageRead<'view>; type Pre = CtxPreStorageRead<'view>; type PrefixIter = KeyValIterator<(String, Vec)>; @@ -167,7 +169,7 @@ impl<'view> VpEnv<'view> for Ctx { fn read_temp( &self, key: &storage::Key, - ) -> Result, Self::Error> { + ) -> Result, Error> { let key = key.to_string(); let read_result = unsafe { anoma_vp_read_temp(key.as_ptr() as _, key.len() as _) }; @@ -178,46 +180,46 @@ impl<'view> VpEnv<'view> for Ctx { fn read_bytes_temp( &self, key: &storage::Key, - ) -> Result>, Self::Error> { + ) -> Result>, Error> { let key = key.to_string(); let read_result = unsafe { anoma_vp_read_temp(key.as_ptr() as _, key.len() as _) }; Ok(read_from_buffer(read_result, anoma_vp_result_buffer)) } - fn get_chain_id(&'view self) -> Result { + fn get_chain_id(&'view self) -> Result { // Both `CtxPreStorageRead` and `CtxPostStorageRead` have the same impl - get_chain_id().into_env_result() + get_chain_id() } - fn get_block_height(&'view self) -> Result { + fn get_block_height(&'view self) -> Result { // Both `CtxPreStorageRead` and `CtxPostStorageRead` have the same impl - get_block_height().into_env_result() + get_block_height() } - fn get_block_hash(&'view self) -> Result { + fn get_block_hash(&'view self) -> Result { // Both `CtxPreStorageRead` and `CtxPostStorageRead` have the same impl - get_block_hash().into_env_result() + get_block_hash() } - fn get_block_epoch(&'view self) -> Result { + fn get_block_epoch(&'view self) -> Result { // Both `CtxPreStorageRead` and `CtxPostStorageRead` have the same impl - get_block_epoch().into_env_result() + get_block_epoch() } fn iter_prefix( &self, prefix: &storage::Key, - ) -> Result { + ) -> Result { // Both `CtxPreStorageRead` and `CtxPostStorageRead` have the same impl - iter_prefix(prefix).into_env_result() + iter_prefix(prefix) } fn eval( &self, vp_code: Vec, input_data: Vec, - ) -> Result { + ) -> Result { let result = unsafe { anoma_vp_eval( vp_code.as_ptr() as _, @@ -233,7 +235,7 @@ impl<'view> VpEnv<'view> for Ctx { &self, pk: &common::PublicKey, sig: &common::Signature, - ) -> Result { + ) -> Result { let pk = BorshSerialize::try_to_vec(pk).unwrap(); let sig = BorshSerialize::try_to_vec(sig).unwrap(); let valid = unsafe { @@ -247,7 +249,7 @@ impl<'view> VpEnv<'view> for Ctx { Ok(HostEnvResult::is_success(valid)) } - fn get_tx_code_hash(&self) -> Result { + fn get_tx_code_hash(&self) -> Result { let result = Vec::with_capacity(HASH_LENGTH); unsafe { anoma_vp_get_tx_code_hash(result.as_ptr() as _); @@ -261,17 +263,14 @@ impl<'view> VpEnv<'view> for Ctx { impl StorageRead<'_> for CtxPreStorageRead<'_> { type PrefixIter = KeyValIterator<(String, Vec)>; - fn read_bytes( - &self, - key: &storage::Key, - ) -> Result>, storage_api::Error> { + fn read_bytes(&self, key: &storage::Key) -> Result>, Error> { let key = key.to_string(); let read_result = unsafe { anoma_vp_read_pre(key.as_ptr() as _, key.len() as _) }; Ok(read_from_buffer(read_result, anoma_vp_result_buffer)) } - fn has_key(&self, key: &storage::Key) -> Result { + fn has_key(&self, key: &storage::Key) -> Result { let key = key.to_string(); let found = unsafe { anoma_vp_has_key_pre(key.as_ptr() as _, key.len() as _) }; @@ -281,7 +280,7 @@ impl StorageRead<'_> for CtxPreStorageRead<'_> { fn iter_next( &self, iter: &mut Self::PrefixIter, - ) -> Result)>, storage_api::Error> { + ) -> Result)>, Error> { let read_result = unsafe { anoma_vp_iter_pre_next(iter.0) }; Ok(read_key_val_bytes_from_buffer( read_result, @@ -294,23 +293,23 @@ impl StorageRead<'_> for CtxPreStorageRead<'_> { fn iter_prefix( &self, prefix: &storage::Key, - ) -> Result { + ) -> Result { iter_prefix(prefix) } - fn get_chain_id(&self) -> Result { + fn get_chain_id(&self) -> Result { get_chain_id() } - fn get_block_height(&self) -> Result { + fn get_block_height(&self) -> Result { get_block_height() } - fn get_block_hash(&self) -> Result { + fn get_block_hash(&self) -> Result { get_block_hash() } - fn get_block_epoch(&self) -> Result { + fn get_block_epoch(&self) -> Result { get_block_epoch() } } @@ -318,17 +317,14 @@ impl StorageRead<'_> for CtxPreStorageRead<'_> { impl StorageRead<'_> for CtxPostStorageRead<'_> { type PrefixIter = KeyValIterator<(String, Vec)>; - fn read_bytes( - &self, - key: &storage::Key, - ) -> Result>, storage_api::Error> { + fn read_bytes(&self, key: &storage::Key) -> Result>, Error> { let key = key.to_string(); let read_result = unsafe { anoma_vp_read_post(key.as_ptr() as _, key.len() as _) }; Ok(read_from_buffer(read_result, anoma_vp_result_buffer)) } - fn has_key(&self, key: &storage::Key) -> Result { + fn has_key(&self, key: &storage::Key) -> Result { let key = key.to_string(); let found = unsafe { anoma_vp_has_key_post(key.as_ptr() as _, key.len() as _) }; @@ -338,7 +334,7 @@ impl StorageRead<'_> for CtxPostStorageRead<'_> { fn iter_next( &self, iter: &mut Self::PrefixIter, - ) -> Result)>, storage_api::Error> { + ) -> Result)>, Error> { let read_result = unsafe { anoma_vp_iter_post_next(iter.0) }; Ok(read_key_val_bytes_from_buffer( read_result, @@ -351,30 +347,30 @@ impl StorageRead<'_> for CtxPostStorageRead<'_> { fn iter_prefix( &self, prefix: &storage::Key, - ) -> Result { + ) -> Result { iter_prefix(prefix) } - fn get_chain_id(&self) -> Result { + fn get_chain_id(&self) -> Result { get_chain_id() } - fn get_block_height(&self) -> Result { + fn get_block_height(&self) -> Result { get_block_height() } - fn get_block_hash(&self) -> Result { + fn get_block_hash(&self) -> Result { get_block_hash() } - fn get_block_epoch(&self) -> Result { + fn get_block_epoch(&self) -> Result { get_block_epoch() } } fn iter_prefix( prefix: &storage::Key, -) -> Result)>, storage_api::Error> { +) -> Result)>, Error> { let prefix = prefix.to_string(); let iter_id = unsafe { anoma_vp_iter_prefix(prefix.as_ptr() as _, prefix.len() as _) @@ -382,7 +378,7 @@ fn iter_prefix( Ok(KeyValIterator(iter_id, PhantomData)) } -fn get_chain_id() -> Result { +fn get_chain_id() -> Result { let result = Vec::with_capacity(CHAIN_ID_LENGTH); unsafe { anoma_vp_get_chain_id(result.as_ptr() as _); @@ -395,11 +391,11 @@ fn get_chain_id() -> Result { ) } -fn get_block_height() -> Result { +fn get_block_height() -> Result { Ok(BlockHeight(unsafe { anoma_vp_get_block_height() })) } -fn get_block_hash() -> Result { +fn get_block_hash() -> Result { let result = Vec::with_capacity(BLOCK_HASH_LENGTH); unsafe { anoma_vp_get_block_hash(result.as_ptr() as _); @@ -409,6 +405,6 @@ fn get_block_hash() -> Result { Ok(BlockHash::try_from(slice).expect("Cannot convert the hash")) } -fn get_block_epoch() -> Result { +fn get_block_epoch() -> Result { Ok(Epoch(unsafe { anoma_vp_get_block_epoch() })) } diff --git a/wasm/wasm_source/src/tx_bond.rs b/wasm/wasm_source/src/tx_bond.rs index 9b04e2a939..e880380802 100644 --- a/wasm/wasm_source/src/tx_bond.rs +++ b/wasm/wasm_source/src/tx_bond.rs @@ -5,10 +5,10 @@ use namada_tx_prelude::*; #[transaction] fn apply_tx(ctx: &mut Ctx, tx_data: Vec) -> TxResult { let signed = SignedTxData::try_from_slice(&tx_data[..]) - .err_msg("failed to decode SignedTxData")?; + .wrap_err("failed to decode SignedTxData")?; let data = signed.data.ok_or_err_msg("Missing data")?; let bond = transaction::pos::Bond::try_from_slice(&data[..]) - .err_msg("failed to decode Bond")?; + .wrap_err("failed to decode Bond")?; ctx.bond_tokens(bond.source.as_ref(), &bond.validator, bond.amount) } diff --git a/wasm/wasm_source/src/tx_from_intent.rs b/wasm/wasm_source/src/tx_from_intent.rs index a299070393..deeb5f3eb0 100644 --- a/wasm/wasm_source/src/tx_from_intent.rs +++ b/wasm/wasm_source/src/tx_from_intent.rs @@ -7,10 +7,10 @@ use namada_tx_prelude::*; #[transaction] fn apply_tx(ctx: &mut Ctx, tx_data: Vec) -> TxResult { let signed = SignedTxData::try_from_slice(&tx_data[..]) - .err_msg("failed to decode SignedTxData")?; + .wrap_err("failed to decode SignedTxData")?; let data = signed.data.ok_or_err_msg("Missing data")?; let tx_data = intent::IntentTransfers::try_from_slice(&data[..]) - .err_msg("failed to decode IntentTransfers")?; + .wrap_err("failed to decode IntentTransfers")?; // make sure that the matchmaker has to validate this tx ctx.insert_verifier(&tx_data.source)?; diff --git a/wasm/wasm_source/src/tx_ibc.rs b/wasm/wasm_source/src/tx_ibc.rs index 08b3c60d60..79cbc6cf96 100644 --- a/wasm/wasm_source/src/tx_ibc.rs +++ b/wasm/wasm_source/src/tx_ibc.rs @@ -8,7 +8,7 @@ use namada_tx_prelude::*; #[transaction] fn apply_tx(ctx: &mut Ctx, tx_data: Vec) -> TxResult { let signed = SignedTxData::try_from_slice(&tx_data[..]) - .err_msg("failed to decode SignedTxData")?; + .wrap_err("failed to decode SignedTxData")?; let data = signed.data.ok_or_err_msg("Missing data")?; ctx.dispatch_ibc_action(&data) } diff --git a/wasm/wasm_source/src/tx_init_account.rs b/wasm/wasm_source/src/tx_init_account.rs index 05789751b2..e0fe700d63 100644 --- a/wasm/wasm_source/src/tx_init_account.rs +++ b/wasm/wasm_source/src/tx_init_account.rs @@ -6,10 +6,10 @@ use namada_tx_prelude::*; #[transaction] fn apply_tx(ctx: &mut Ctx, tx_data: Vec) -> TxResult { let signed = SignedTxData::try_from_slice(&tx_data[..]) - .err_msg("failed to decode SignedTxData")?; + .wrap_err("failed to decode SignedTxData")?; let data = signed.data.ok_or_err_msg("Missing data")?; let tx_data = transaction::InitAccount::try_from_slice(&data[..]) - .err_msg("failed to decode InitAccount")?; + .wrap_err("failed to decode InitAccount")?; debug_log!("apply_tx called to init a new established account"); let address = ctx.init_account(&tx_data.vp_code)?; diff --git a/wasm/wasm_source/src/tx_init_nft.rs b/wasm/wasm_source/src/tx_init_nft.rs index ace54fc161..de67dfbb53 100644 --- a/wasm/wasm_source/src/tx_init_nft.rs +++ b/wasm/wasm_source/src/tx_init_nft.rs @@ -5,10 +5,10 @@ use namada_tx_prelude::*; #[transaction] fn apply_tx(ctx: &mut Ctx, tx_data: Vec) -> TxResult { let signed = SignedTxData::try_from_slice(&tx_data[..]) - .err_msg("failed to decode SignedTxData")?; + .wrap_err("failed to decode SignedTxData")?; let data = signed.data.ok_or_err_msg("Missing data")?; let tx_data = transaction::nft::CreateNft::try_from_slice(&data[..]) - .err_msg("failed to decode CreateNft")?; + .wrap_err("failed to decode CreateNft")?; log_string("apply_tx called to create a new NFT"); let _address = nft::init_nft(ctx, tx_data)?; diff --git a/wasm/wasm_source/src/tx_init_proposal.rs b/wasm/wasm_source/src/tx_init_proposal.rs index 728d7613ae..cb7fe9ffbb 100644 --- a/wasm/wasm_source/src/tx_init_proposal.rs +++ b/wasm/wasm_source/src/tx_init_proposal.rs @@ -5,11 +5,11 @@ use namada_tx_prelude::*; #[transaction] fn apply_tx(ctx: &mut Ctx, tx_data: Vec) -> TxResult { let signed = SignedTxData::try_from_slice(&tx_data[..]) - .err_msg("failed to decode SignedTxData")?; + .wrap_err("failed to decode SignedTxData")?; let data = signed.data.ok_or_err_msg("Missing data")?; let tx_data = transaction::governance::InitProposalData::try_from_slice(&data[..]) - .err_msg("failed to decode InitProposalData")?; + .wrap_err("failed to decode InitProposalData")?; log_string("apply_tx called to create a new governance proposal"); governance::init_proposal(ctx, tx_data) diff --git a/wasm/wasm_source/src/tx_init_validator.rs b/wasm/wasm_source/src/tx_init_validator.rs index 2bfed44fac..2d5f1a6256 100644 --- a/wasm/wasm_source/src/tx_init_validator.rs +++ b/wasm/wasm_source/src/tx_init_validator.rs @@ -7,10 +7,10 @@ use namada_tx_prelude::*; #[transaction] fn apply_tx(ctx: &mut Ctx, tx_data: Vec) -> TxResult { let signed = SignedTxData::try_from_slice(&tx_data[..]) - .err_msg("failed to decode SignedTxData")?; + .wrap_err("failed to decode SignedTxData")?; let data = signed.data.ok_or_err_msg("Missing data")?; let init_validator = InitValidator::try_from_slice(&data[..]) - .err_msg("failed to decode InitValidator")?; + .wrap_err("failed to decode InitValidator")?; debug_log!("apply_tx called to init a new validator account"); // Register the validator in PoS diff --git a/wasm/wasm_source/src/tx_mint_nft.rs b/wasm/wasm_source/src/tx_mint_nft.rs index f132b74158..d3ab17e7ad 100644 --- a/wasm/wasm_source/src/tx_mint_nft.rs +++ b/wasm/wasm_source/src/tx_mint_nft.rs @@ -5,10 +5,10 @@ use namada_tx_prelude::*; #[transaction] fn apply_tx(ctx: &mut Ctx, tx_data: Vec) -> TxResult { let signed = SignedTxData::try_from_slice(&tx_data[..]) - .err_msg("failed to decode SignedTxData")?; + .wrap_err("failed to decode SignedTxData")?; let data = signed.data.ok_or_err_msg("Missing data")?; let tx_data = transaction::nft::MintNft::try_from_slice(&data[..]) - .err_msg("failed to decode MintNft")?; + .wrap_err("failed to decode MintNft")?; log_string("apply_tx called to mint a new NFT tokens"); nft::mint_tokens(ctx, tx_data) diff --git a/wasm/wasm_source/src/tx_transfer.rs b/wasm/wasm_source/src/tx_transfer.rs index 5731612888..eccddee2f0 100644 --- a/wasm/wasm_source/src/tx_transfer.rs +++ b/wasm/wasm_source/src/tx_transfer.rs @@ -7,10 +7,10 @@ use namada_tx_prelude::*; #[transaction] fn apply_tx(ctx: &mut Ctx, tx_data: Vec) -> TxResult { let signed = SignedTxData::try_from_slice(&tx_data[..]) - .err_msg("failed to decode SignedTxData")?; + .wrap_err("failed to decode SignedTxData")?; let data = signed.data.ok_or_err_msg("Missing data")?; let transfer = token::Transfer::try_from_slice(&data[..]) - .err_msg("failed to decode token::Transfer")?; + .wrap_err("failed to decode token::Transfer")?; debug_log!("apply_tx called with transfer: {:#?}", transfer); let token::Transfer { source, diff --git a/wasm/wasm_source/src/tx_unbond.rs b/wasm/wasm_source/src/tx_unbond.rs index c5ffc1ab6e..5d1765bb38 100644 --- a/wasm/wasm_source/src/tx_unbond.rs +++ b/wasm/wasm_source/src/tx_unbond.rs @@ -6,10 +6,10 @@ use namada_tx_prelude::*; #[transaction] fn apply_tx(ctx: &mut Ctx, tx_data: Vec) -> TxResult { let signed = SignedTxData::try_from_slice(&tx_data[..]) - .err_msg("failed to decode SignedTxData")?; + .wrap_err("failed to decode SignedTxData")?; let data = signed.data.ok_or_err_msg("Missing data")?; let unbond = transaction::pos::Unbond::try_from_slice(&data[..]) - .err_msg("failed to decode Unbond")?; + .wrap_err("failed to decode Unbond")?; ctx.unbond_tokens(unbond.source.as_ref(), &unbond.validator, unbond.amount) } diff --git a/wasm/wasm_source/src/tx_update_vp.rs b/wasm/wasm_source/src/tx_update_vp.rs index d0c41d3bd9..0bb819f026 100644 --- a/wasm/wasm_source/src/tx_update_vp.rs +++ b/wasm/wasm_source/src/tx_update_vp.rs @@ -7,10 +7,10 @@ use namada_tx_prelude::*; #[transaction] fn apply_tx(ctx: &mut Ctx, tx_data: Vec) -> TxResult { let signed = SignedTxData::try_from_slice(&tx_data[..]) - .err_msg("failed to decode SignedTxData")?; + .wrap_err("failed to decode SignedTxData")?; let data = signed.data.ok_or_err_msg("Missing data")?; let update_vp = transaction::UpdateVp::try_from_slice(&data[..]) - .err_msg("failed to decode UpdateVp")?; + .wrap_err("failed to decode UpdateVp")?; debug_log!("update VP for: {:#?}", update_vp.addr); diff --git a/wasm/wasm_source/src/tx_vote_proposal.rs b/wasm/wasm_source/src/tx_vote_proposal.rs index 614e4a9fa1..92c7af4c7f 100644 --- a/wasm/wasm_source/src/tx_vote_proposal.rs +++ b/wasm/wasm_source/src/tx_vote_proposal.rs @@ -5,11 +5,11 @@ use namada_tx_prelude::*; #[transaction] fn apply_tx(ctx: &mut Ctx, tx_data: Vec) -> TxResult { let signed = SignedTxData::try_from_slice(&tx_data[..]) - .err_msg("failed to decode SignedTxData")?; + .wrap_err("failed to decode SignedTxData")?; let data = signed.data.ok_or_err_msg("Missing data")?; let tx_data = transaction::governance::VoteProposalData::try_from_slice(&data[..]) - .err_msg("failed to decode VoteProposalData")?; + .wrap_err("failed to decode VoteProposalData")?; debug_log!("apply_tx called to vote a governance proposal"); diff --git a/wasm/wasm_source/src/tx_withdraw.rs b/wasm/wasm_source/src/tx_withdraw.rs index bcb64b4af0..3c841d88b0 100644 --- a/wasm/wasm_source/src/tx_withdraw.rs +++ b/wasm/wasm_source/src/tx_withdraw.rs @@ -6,10 +6,10 @@ use namada_tx_prelude::*; #[transaction] fn apply_tx(ctx: &mut Ctx, tx_data: Vec) -> TxResult { let signed = SignedTxData::try_from_slice(&tx_data[..]) - .err_msg("failed to decode SignedTxData")?; + .wrap_err("failed to decode SignedTxData")?; let data = signed.data.ok_or_err_msg("Missing data")?; let withdraw = transaction::pos::Withdraw::try_from_slice(&data[..]) - .err_msg("failed to decode Withdraw")?; + .wrap_err("failed to decode Withdraw")?; let slashed = ctx.withdraw_tokens(withdraw.source.as_ref(), &withdraw.validator)?; diff --git a/wasm_for_tests/wasm_source/src/lib.rs b/wasm_for_tests/wasm_source/src/lib.rs index 2b6ef24242..4731ef60be 100644 --- a/wasm_for_tests/wasm_source/src/lib.rs +++ b/wasm_for_tests/wasm_source/src/lib.rs @@ -88,7 +88,7 @@ pub mod main { #[transaction] fn apply_tx(ctx: &mut Ctx, tx_data: Vec) -> TxResult { let signed = SignedTxData::try_from_slice(&tx_data[..]) - .err_msg("failed to decode SignedTxData")?; + .wrap_err("failed to decode SignedTxData")?; let data = match signed.data { Some(data) => { log(&format!("got data ({} bytes)", data.len())); @@ -134,7 +134,7 @@ pub mod main { #[transaction] fn apply_tx(ctx: &mut Ctx, tx_data: Vec) -> TxResult { let signed = SignedTxData::try_from_slice(&tx_data[..]) - .err_msg("failed to decode SignedTxData")?; + .wrap_err("failed to decode SignedTxData")?; let transfer = token::Transfer::try_from_slice(&signed.data.unwrap()[..]).unwrap(); log_string(format!("apply_tx called to mint tokens: {:#?}", transfer)); From 45dddbeaed67c8bbc2720c8b7109a4e7dc0fd971 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 13 Sep 2022 15:51:26 +0000 Subject: [PATCH 2/3] [ci skip] wasm checksums update --- wasm/checksums.json | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/wasm/checksums.json b/wasm/checksums.json index 1c5fec452f..06f33fcda7 100644 --- a/wasm/checksums.json +++ b/wasm/checksums.json @@ -1,19 +1,19 @@ { - "tx_bond.wasm": "tx_bond.078d5be45d839fc1b6c034c4fdfe2055add709daa05868826682d3b6abf27ac4.wasm", - "tx_from_intent.wasm": "tx_from_intent.dcdfc49a02c76f277afac84e3511ad47c70b3bf54d1273a15c6dc75648316937.wasm", - "tx_ibc.wasm": "tx_ibc.3957053e0ea9caaa49128994711339aea6ede77a99f150688df3de870c8b17d4.wasm", - "tx_init_account.wasm": "tx_init_account.92e59887817a6d789dc8a85bb1eff3c86bd0a9bd1ddc8a9e0e5de5c9e9c2ddc6.wasm", - "tx_init_nft.wasm": "tx_init_nft.4125bdf149533cd201895cfaf6cdfbb9616182c187137029fe3c9214030f1877.wasm", - "tx_init_proposal.wasm": "tx_init_proposal.8da848905d5a8ad1b15046d5e59e04f307bde73dcc8d2ab0b6d8d235a31a8b52.wasm", - "tx_init_validator.wasm": "tx_init_validator.364786e78253bd9ce72d089cc1539a882eb8ef6fd8c818616d003241b47ac010.wasm", - "tx_mint_nft.wasm": "tx_mint_nft.b2c34b21a2f0b533e3dcd4b2ee64e45ca00ccad8b3f22c410474c7a67c3302e8.wasm", - "tx_transfer.wasm": "tx_transfer.6fac9a68bcd1a50d9cec64605f8637dfa897ce3be242edc344858cf4075fc100.wasm", - "tx_unbond.wasm": "tx_unbond.eeaf8ff32984275288b0a9a36c9579dace6f3ecfaf59255af769acf57a00df4a.wasm", - "tx_update_vp.wasm": "tx_update_vp.a304b3c70361cde5fda458ba5637d6825eb002198e73990a1c74351113b83d43.wasm", - "tx_vote_proposal.wasm": "tx_vote_proposal.8f306e1d1bcc9ca7f47a39108554fc847d4ac6df7a8d87a6effdffeae6adc4c4.wasm", - "tx_withdraw.wasm": "tx_withdraw.c288861e842f0b1ac6fbb95b14b33c8819ac587bbd5b483f2cdd0ea184206c65.wasm", - "vp_nft.wasm": "vp_nft.379f0a9fdbc9611ba9afc8b03ea17eb1e7c63992be3c2ecd5dd506a0ec3809f3.wasm", - "vp_testnet_faucet.wasm": "vp_testnet_faucet.9d28df0e4eea55c98ac05638cfc6211aaf8e1a4b9489f7057634c66d39835c36.wasm", - "vp_token.wasm": "vp_token.6506aea021bb6de9186e96fa0d9ea2ad35bcb66777d6ecf890a66cfe36a74f23.wasm", - "vp_user.wasm": "vp_user.77a0d0d406e300b2d5b9bc1c13bc50f233b6923d369db939ac82c8e10b64543c.wasm" + "tx_bond.wasm": "tx_bond.b3529e7dcdaf314353fa43b04eba22c44deb6143f8243933f66d20554565fa51.wasm", + "tx_from_intent.wasm": "tx_from_intent.6985cd22aa16334b008262beda3051d16f0522e019ba178c20b2cf0c92ef3cf5.wasm", + "tx_ibc.wasm": "tx_ibc.3ffa1662cb15d178be631adaeb060e96deaa44dfca8ee2978fc7d9ea09776977.wasm", + "tx_init_account.wasm": "tx_init_account.81c82e4f85575244dd833f8de566844de926f8869f1cce1dd86a1d69fe527a2f.wasm", + "tx_init_nft.wasm": "tx_init_nft.cde4c8c381369a61c6f0363c6748118d064202541c41c69c4e534f3ebbba2567.wasm", + "tx_init_proposal.wasm": "tx_init_proposal.bfc77114ad453d9791d115fd97d681f4bbba956c77fcdb97c619637bb807a7c8.wasm", + "tx_init_validator.wasm": "tx_init_validator.7ecc353a6668788e01aac3a5799e9baa7f83979cdb8c82011225a53f1952672d.wasm", + "tx_mint_nft.wasm": "tx_mint_nft.3bc71754956503b44f764dc27cd51796e0613435864dc3f10d089e3b99bda21e.wasm", + "tx_transfer.wasm": "tx_transfer.38b4c4ec9d949b72e51547ab55737c42db383f5e04385cffafccb36fa5a5dccb.wasm", + "tx_unbond.wasm": "tx_unbond.174499645c2aa9242f29050406a0c835d78e6c030b1f7978b5d5d1a602e88e99.wasm", + "tx_update_vp.wasm": "tx_update_vp.4ee18fa789b30215220f6edfd317314abb575baab34e9b0147afa65cbfec4543.wasm", + "tx_vote_proposal.wasm": "tx_vote_proposal.17c3d54babf760367f63609f4e7aa6cf4500b80a5ff01c2917b54b4cfdf78df4.wasm", + "tx_withdraw.wasm": "tx_withdraw.010c8141fe8dfe470887d80f77db482ddc7081e318496180208490226060787e.wasm", + "vp_nft.wasm": "vp_nft.bfc7e3a5a33226ee19111cc0cc627da4da7db3d863ce1955d195873b36ba6374.wasm", + "vp_testnet_faucet.wasm": "vp_testnet_faucet.b8d0069f0a287c57513b64daab378084d49c7e2cd52c44b0f5aa1a3ded262c88.wasm", + "vp_token.wasm": "vp_token.9f27451dba52d022ff02bbdf2421895e285e79ce2867dd1193a27fbfd2bff4fc.wasm", + "vp_user.wasm": "vp_user.eac794136d3c148b9997cc4e6fb458dcfc5e7c1f2edea49dad7c8b6d35b9c306.wasm" } \ No newline at end of file From 16d9aa6c8ad6b3f1b8fc4be1ecba6f9b31f17f2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Tue, 13 Sep 2022 18:42:46 +0200 Subject: [PATCH 3/3] changelog: add #465 --- .../unreleased/improvements/465-vp-tx-env-conrete-error.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .changelog/unreleased/improvements/465-vp-tx-env-conrete-error.md diff --git a/.changelog/unreleased/improvements/465-vp-tx-env-conrete-error.md b/.changelog/unreleased/improvements/465-vp-tx-env-conrete-error.md new file mode 100644 index 0000000000..e40ff76a17 --- /dev/null +++ b/.changelog/unreleased/improvements/465-vp-tx-env-conrete-error.md @@ -0,0 +1,2 @@ +- Re-use `storage_api::Error` type that supports wrapping custom error in `VpEnv` and `TxEnv` traits. + ([#465](https://github.com/anoma/namada/pull/465))