Make decl_error! errors usable (#4449)

* Make `decl_error!` errors usable

This pr implements support for returning errors of different pallets in
a pallet. These errors need to be declared with `decl_error!`.

The pr changes the following:

- Each dispatchable function now returns a `DispatchResult` which is an
alias for `Result<(), DispatchError>`.
- `DispatchError` is an enum that has 4 variants:
  - `Other`: For storing string error messages
  - `CannotLookup`: Variant that is returned when something returns a
  `sp_runtime::LookupError`
  - `BadOrigin`: Variant that is returned for any kind of bad origin
  - `Module`: The error of a specific module. Contains the `index`,
  `error` and the `message`. The index is the index of the module in
  `construct_runtime!`. `error` is the index of the error in the error
  enum declared by `decl_error!`. `message` is the message to the error
  variant (this will not be encoded).
- `construct_runtime!` now creates a new struct `ModuleToIndex`. This
struct implements the trait `ModuleToIndex`.
- `frame_system::Trait` has a new associated type: `ModuleToIndex` that
expects the `ModuleToIndex` generated by `construct_runtime!`.
- All error strings returned in any module are being converted now to `DispatchError`.
- `BadOrigin` is the default error returned by any type that implements `EnsureOrigin`.

* Fix frame system benchmarks
This commit is contained in:
Bastian Köcher
2019-12-19 14:01:52 +01:00
committed by Gavin Wood
parent 0aab5c659e
commit 8e393aa5a8
69 changed files with 868 additions and 611 deletions
+20 -8
View File
@@ -22,7 +22,7 @@ use sp_std::{prelude::*, result, marker::PhantomData, ops::Div, fmt::Debug};
use codec::{FullCodec, Codec, Encode, Decode};
use sp_core::u32_trait::Value as U32;
use sp_runtime::{
ConsensusEngineId,
ConsensusEngineId, DispatchResult, DispatchError,
traits::{MaybeSerializeDeserialize, SimpleArithmetic, Saturating},
};
@@ -386,7 +386,7 @@ pub trait Currency<AccountId> {
_amount: Self::Balance,
reasons: WithdrawReasons,
new_balance: Self::Balance,
) -> result::Result<(), &'static str>;
) -> DispatchResult;
// PUBLIC MUTABLES (DANGEROUS)
@@ -399,7 +399,7 @@ pub trait Currency<AccountId> {
dest: &AccountId,
value: Self::Balance,
existence_requirement: ExistenceRequirement,
) -> result::Result<(), &'static str>;
) -> DispatchResult;
/// Deducts up to `value` from the combined balance of `who`, preferring to deduct from the
/// free balance. This function cannot fail.
@@ -419,7 +419,7 @@ pub trait Currency<AccountId> {
fn deposit_into_existing(
who: &AccountId,
value: Self::Balance
) -> result::Result<Self::PositiveImbalance, &'static str>;
) -> result::Result<Self::PositiveImbalance, DispatchError>;
/// Similar to deposit_creating, only accepts a `NegativeImbalance` and returns nothing on
/// success.
@@ -465,7 +465,7 @@ pub trait Currency<AccountId> {
value: Self::Balance,
reasons: WithdrawReasons,
liveness: ExistenceRequirement,
) -> result::Result<Self::NegativeImbalance, &'static str>;
) -> result::Result<Self::NegativeImbalance, DispatchError>;
/// Similar to withdraw, only accepts a `PositiveImbalance` and returns nothing on success.
fn settle(
@@ -528,7 +528,7 @@ pub trait ReservableCurrency<AccountId>: Currency<AccountId> {
///
/// If the free balance is lower than `value`, then no funds will be moved and an `Err` will
/// be returned to notify of this. This is different behavior than `unreserve`.
fn reserve(who: &AccountId, value: Self::Balance) -> result::Result<(), &'static str>;
fn reserve(who: &AccountId, value: Self::Balance) -> DispatchResult;
/// Moves up to `value` from reserved balance to free balance. This function cannot fail.
///
@@ -552,7 +552,7 @@ pub trait ReservableCurrency<AccountId>: Currency<AccountId> {
slashed: &AccountId,
beneficiary: &AccountId,
value: Self::Balance
) -> result::Result<Self::Balance, &'static str>;
) -> result::Result<Self::Balance, DispatchError>;
}
/// An identifier for a lock. Used for disambiguating different locks so that
@@ -619,7 +619,7 @@ pub trait VestingCurrency<AccountId>: Currency<AccountId> {
locked: Self::Balance,
per_block: Self::Balance,
starting_block: Self::Moment,
) -> result::Result<(), &'static str>;
) -> DispatchResult;
/// Remove a vesting schedule for a given account.
fn remove_vesting_schedule(who: &AccountId);
@@ -777,3 +777,15 @@ pub trait ValidatorRegistration<ValidatorId> {
/// module
fn is_registered(id: &ValidatorId) -> bool;
}
/// Something that can convert a given module into the index of the module in the runtime.
///
/// The index of a module is determined by the position it appears in `construct_runtime!`.
pub trait ModuleToIndex {
/// Convert the given module `M` into an index.
fn module_to_index<M: 'static>() -> Option<usize>;
}
impl ModuleToIndex for () {
fn module_to_index<M: 'static>() -> Option<usize> { Some(0) }
}