mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 20:57:59 +00:00
Custom runtime module errors (#3433)
* srml-system checks * wip * more modules compiles * node-runtime checks * build.sh passes * include dispatch error in failed event * revert some unnecessary changes * refactor based on comments * more compile error fixes * avoid unnecessary into * reorder code * fixes some tests * manually implement encode & decode to avoid i8 workaround * more test fixes * more fixes * more error fixes * Apply suggestions from code review Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * address comments * test for DispatchError encoding * tyep alias for democracy * make error printable * line width * fix balances tests * fix executive test * fix system tests * bump version * ensure consistent method signature * Apply suggestions from code review Co-Authored-By: Gavin Wood <github@gavwood.com> * changes based on review * Add issue number for TODOs * fix * line width * fix test * Update core/sr-primitives/src/lib.rs Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com> * Update core/sr-primitives/src/traits.rs Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com> * Update srml/council/src/motions.rs Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com> * Update srml/council/src/motions.rs Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com> * update based on review * More concrete macro matching * fix test build issue * Update hex-literal dependency version. (#3141) * Update hex-literal dep version. * Update lock file. * Start to rework the new error handling * More work to get it back compiling * Start to fix after master merge * The great transaction error handling refactoring * Make `decl_error` errors convertible to `&'static str` * Make srml-executive build again * Fix `sr-primitives` tests * More fixes * Last round of fix ups * Fix build * Fix build * Apply suggestions from code review Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * Rename some stuff * Fixes after master merge * Adds `CheckBlockGasLimit` signed extension * Remove debug stuff * Fix srml-balances test * Rename `InvalidIndex` to `CannotLookup` * Remove weird generic parameters * Rename function again * Fix import * Document the signed extension * Change from `Into` to `From` * Update srml/contracts/src/lib.rs Co-Authored-By: Sergei Pepyakin <sergei@parity.io> * Fix compilation * Update srml/contracts/src/lib.rs Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * Update core/sr-primitives/src/transaction_validity.rs Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * Remove unused code * Fix compilation * Some cleanups * Fix compile errors * Make `TransactionValidity` a `Result` * Apply suggestions from code review Co-Authored-By: Gavin Wood <gavin@parity.io> * Beautify the code a little bit and fix test * Make `CannotLookup` an inherent error declared by `decl_error!` * Adds some documentation * Make `ApplyOutcome` a result * Up the spec_version * Apply suggestions from code review Co-Authored-By: Gavin Wood <gavin@parity.io> Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com>
This commit is contained in:
@@ -38,7 +38,9 @@ use substrate_client::{
|
||||
};
|
||||
use sr_primitives::{
|
||||
ApplyResult, create_runtime_str, Perbill, impl_opaque_keys,
|
||||
transaction_validity::{TransactionValidity, ValidTransaction},
|
||||
transaction_validity::{
|
||||
TransactionValidity, ValidTransaction, TransactionValidityError, InvalidTransaction,
|
||||
},
|
||||
traits::{
|
||||
BlindCheckable, BlakeTwo256, Block as BlockT, Extrinsic as ExtrinsicT,
|
||||
GetNodeBlockType, GetRuntimeBlockType, Verify, IdentityLookup,
|
||||
@@ -123,17 +125,17 @@ impl serde::Serialize for Extrinsic {
|
||||
impl BlindCheckable for Extrinsic {
|
||||
type Checked = Self;
|
||||
|
||||
fn check(self) -> Result<Self, &'static str> {
|
||||
fn check(self) -> Result<Self, TransactionValidityError> {
|
||||
match self {
|
||||
Extrinsic::AuthoritiesChange(new_auth) => Ok(Extrinsic::AuthoritiesChange(new_auth)),
|
||||
Extrinsic::Transfer(transfer, signature) => {
|
||||
if sr_primitives::verify_encoded_lazy(&signature, &transfer, &transfer.from) {
|
||||
Ok(Extrinsic::Transfer(transfer, signature))
|
||||
} else {
|
||||
Err(sr_primitives::BAD_SIGNATURE)
|
||||
Err(InvalidTransaction::BadProof.into())
|
||||
}
|
||||
},
|
||||
Extrinsic::IncludeData(_) => Err(sr_primitives::BAD_SIGNATURE),
|
||||
Extrinsic::IncludeData(_) => Err(InvalidTransaction::BadProof.into()),
|
||||
Extrinsic::StorageChange(key, value) => Ok(Extrinsic::StorageChange(key, value)),
|
||||
}
|
||||
}
|
||||
@@ -478,7 +480,7 @@ cfg_if! {
|
||||
impl client_api::TaggedTransactionQueue<Block> for Runtime {
|
||||
fn validate_transaction(utx: <Block as BlockT>::Extrinsic) -> TransactionValidity {
|
||||
if let Extrinsic::IncludeData(data) = utx {
|
||||
return TransactionValidity::Valid(ValidTransaction {
|
||||
return Ok(ValidTransaction {
|
||||
priority: data.len() as u64,
|
||||
requires: vec![],
|
||||
provides: vec![data],
|
||||
@@ -662,7 +664,7 @@ cfg_if! {
|
||||
impl client_api::TaggedTransactionQueue<Block> for Runtime {
|
||||
fn validate_transaction(utx: <Block as BlockT>::Extrinsic) -> TransactionValidity {
|
||||
if let Extrinsic::IncludeData(data) = utx {
|
||||
return TransactionValidity::Valid(ValidTransaction{
|
||||
return Ok(ValidTransaction{
|
||||
priority: data.len() as u64,
|
||||
requires: vec![],
|
||||
provides: vec![data],
|
||||
|
||||
@@ -21,12 +21,12 @@ use rstd::prelude::*;
|
||||
use runtime_io::{storage_root, ordered_trie_root, storage_changes_root, twox_128, blake2_256};
|
||||
use runtime_support::storage::{self, StorageValue, StorageMap};
|
||||
use runtime_support::storage_items;
|
||||
use sr_primitives::traits::{Hash as HashT, BlakeTwo256, Header as _};
|
||||
use sr_primitives::generic;
|
||||
use sr_primitives::{ApplyError, ApplyOutcome, ApplyResult};
|
||||
use sr_primitives::transaction_validity::{TransactionValidity, ValidTransaction};
|
||||
use sr_primitives::{
|
||||
traits::{Hash as HashT, BlakeTwo256, Header as _}, generic, ApplyError, ApplyResult,
|
||||
transaction_validity::{TransactionValidity, ValidTransaction, InvalidTransaction},
|
||||
};
|
||||
use codec::{KeyedVec, Encode};
|
||||
use super::{
|
||||
use crate::{
|
||||
AccountId, BlockNumber, Extrinsic, Transfer, H256 as Hash, Block, Header, Digest, AuthorityId
|
||||
};
|
||||
use primitives::{Blake2Hasher, storage::well_known_keys};
|
||||
@@ -119,7 +119,7 @@ fn execute_block_with_state_root_handler(
|
||||
// execute transactions
|
||||
block.extrinsics.iter().enumerate().for_each(|(i, e)| {
|
||||
storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &(i as u32));
|
||||
execute_transaction_backend(e).unwrap_or_else(|_| panic!("Invalid transaction"));
|
||||
let _ = execute_transaction_backend(e).unwrap_or_else(|_| panic!("Invalid transaction"));
|
||||
storage::unhashed::kill(well_known_keys::EXTRINSIC_INDEX);
|
||||
});
|
||||
|
||||
@@ -158,17 +158,17 @@ impl executive::ExecuteBlock<Block> for BlockExecutor {
|
||||
/// This doesn't attempt to validate anything regarding the block.
|
||||
pub fn validate_transaction(utx: Extrinsic) -> TransactionValidity {
|
||||
if check_signature(&utx).is_err() {
|
||||
return TransactionValidity::Invalid(ApplyError::BadSignature as i8);
|
||||
return InvalidTransaction::BadProof.into();
|
||||
}
|
||||
|
||||
let tx = utx.transfer();
|
||||
let nonce_key = tx.from.to_keyed_vec(NONCE_OF);
|
||||
let expected_nonce: u64 = storage::hashed::get_or(&blake2_256, &nonce_key, 0);
|
||||
if tx.nonce < expected_nonce {
|
||||
return TransactionValidity::Invalid(ApplyError::Stale as i8);
|
||||
return InvalidTransaction::Stale.into();
|
||||
}
|
||||
if tx.nonce > expected_nonce + 64 {
|
||||
return TransactionValidity::Unknown(ApplyError::Future as i8);
|
||||
return InvalidTransaction::Future.into();
|
||||
}
|
||||
|
||||
let hash = |from: &AccountId, nonce: u64| {
|
||||
@@ -188,7 +188,7 @@ pub fn validate_transaction(utx: Extrinsic) -> TransactionValidity {
|
||||
p
|
||||
};
|
||||
|
||||
TransactionValidity::Valid(ValidTransaction {
|
||||
Ok(ValidTransaction {
|
||||
priority: tx.amount,
|
||||
requires,
|
||||
provides,
|
||||
@@ -244,8 +244,7 @@ pub fn finalize_block() -> Header {
|
||||
#[inline(always)]
|
||||
fn check_signature(utx: &Extrinsic) -> Result<(), ApplyError> {
|
||||
use sr_primitives::traits::BlindCheckable;
|
||||
utx.clone().check().map_err(|_| ApplyError::BadSignature)?;
|
||||
Ok(())
|
||||
utx.clone().check().map_err(|_| InvalidTransaction::BadProof.into()).map(|_| ())
|
||||
}
|
||||
|
||||
fn execute_transaction_backend(utx: &Extrinsic) -> ApplyResult {
|
||||
@@ -253,7 +252,7 @@ fn execute_transaction_backend(utx: &Extrinsic) -> ApplyResult {
|
||||
match utx {
|
||||
Extrinsic::Transfer(ref transfer, _) => execute_transfer_backend(transfer),
|
||||
Extrinsic::AuthoritiesChange(ref new_auth) => execute_new_authorities_backend(new_auth),
|
||||
Extrinsic::IncludeData(_) => Ok(ApplyOutcome::Success),
|
||||
Extrinsic::IncludeData(_) => Ok(Ok(())),
|
||||
Extrinsic::StorageChange(key, value) => execute_storage_change(key, value.as_ref().map(|v| &**v)),
|
||||
}
|
||||
}
|
||||
@@ -263,7 +262,7 @@ fn execute_transfer_backend(tx: &Transfer) -> ApplyResult {
|
||||
let nonce_key = tx.from.to_keyed_vec(NONCE_OF);
|
||||
let expected_nonce: u64 = storage::hashed::get_or(&blake2_256, &nonce_key, 0);
|
||||
if !(tx.nonce == expected_nonce) {
|
||||
return Err(ApplyError::Stale)
|
||||
return Err(InvalidTransaction::Stale.into());
|
||||
}
|
||||
|
||||
// increment nonce in storage
|
||||
@@ -275,18 +274,18 @@ fn execute_transfer_backend(tx: &Transfer) -> ApplyResult {
|
||||
|
||||
// enact transfer
|
||||
if !(tx.amount <= from_balance) {
|
||||
return Err(ApplyError::CantPay)
|
||||
return Err(InvalidTransaction::Payment.into());
|
||||
}
|
||||
let to_balance_key = tx.to.to_keyed_vec(BALANCE_OF);
|
||||
let to_balance: u64 = storage::hashed::get_or(&blake2_256, &to_balance_key, 0);
|
||||
storage::hashed::put(&blake2_256, &from_balance_key, &(from_balance - tx.amount));
|
||||
storage::hashed::put(&blake2_256, &to_balance_key, &(to_balance + tx.amount));
|
||||
Ok(ApplyOutcome::Success)
|
||||
Ok(Ok(()))
|
||||
}
|
||||
|
||||
fn execute_new_authorities_backend(new_authorities: &[AuthorityId]) -> ApplyResult {
|
||||
NewAuthorities::put(new_authorities.to_vec());
|
||||
Ok(ApplyOutcome::Success)
|
||||
Ok(Ok(()))
|
||||
}
|
||||
|
||||
fn execute_storage_change(key: &[u8], value: Option<&[u8]>) -> ApplyResult {
|
||||
@@ -294,7 +293,7 @@ fn execute_storage_change(key: &[u8], value: Option<&[u8]>) -> ApplyResult {
|
||||
Some(value) => storage::unhashed::put_raw(key, value),
|
||||
None => storage::unhashed::kill(key),
|
||||
}
|
||||
Ok(ApplyOutcome::Success)
|
||||
Ok(Ok(()))
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
@@ -304,7 +303,7 @@ fn info_expect_equal_hash(given: &Hash, expected: &Hash) {
|
||||
println!(
|
||||
"Hash: given={}, expected={}",
|
||||
HexDisplay::from(given.as_fixed_bytes()),
|
||||
HexDisplay::from(expected.as_fixed_bytes())
|
||||
HexDisplay::from(expected.as_fixed_bytes()),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -312,9 +311,9 @@ fn info_expect_equal_hash(given: &Hash, expected: &Hash) {
|
||||
#[cfg(not(feature = "std"))]
|
||||
fn info_expect_equal_hash(given: &Hash, expected: &Hash) {
|
||||
if given != expected {
|
||||
::runtime_io::print("Hash not equal");
|
||||
::runtime_io::print(given.as_bytes());
|
||||
::runtime_io::print(expected.as_bytes());
|
||||
runtime_io::print("Hash not equal");
|
||||
runtime_io::print(given.as_bytes());
|
||||
runtime_io::print(expected.as_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user