Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions bin/node-template/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
use rstd::prelude::*;
use primitives::OpaqueMetadata;
use sr_primitives::{
ApplyResult, transaction_validity::TransactionValidity, generic, create_runtime_str,
InclusionOutcome, transaction_validity::TransactionValidity, generic, create_runtime_str,
impl_opaque_keys, MultiSignature
};
use sr_primitives::traits::{
Expand Down Expand Up @@ -301,7 +301,7 @@ impl_runtime_apis! {
}

impl block_builder_api::BlockBuilder<Block> for Runtime {
fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyResult {
fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> InclusionOutcome {
Executive::apply_extrinsic(extrinsic)
}

Expand Down
10 changes: 5 additions & 5 deletions bin/node/executor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ mod tests {
};
use sr_primitives::{
Fixed64,
traits::{Header as HeaderT, Hash as HashT, Convert}, ApplyResult,
traits::{Header as HeaderT, Hash as HashT, Convert}, InclusionOutcome,
transaction_validity::InvalidTransaction, weights::GetDispatchInfo,
};
use contracts::ContractAddressFor;
Expand Down Expand Up @@ -170,7 +170,7 @@ mod tests {
true,
None,
).0.unwrap();
let r = ApplyResult::decode(&mut &v.as_encoded()[..]).unwrap();
let r = InclusionOutcome::decode(&mut &v.as_encoded()[..]).unwrap();
assert_eq!(r, Err(InvalidTransaction::Payment.into()));
}

Expand Down Expand Up @@ -206,7 +206,7 @@ mod tests {
true,
None,
).0.unwrap();
let r = ApplyResult::decode(&mut &v.as_encoded()[..]).unwrap();
let r = InclusionOutcome::decode(&mut &v.as_encoded()[..]).unwrap();
assert_eq!(r, Err(InvalidTransaction::Payment.into()));
}

Expand Down Expand Up @@ -841,7 +841,7 @@ mod tests {
false,
None,
).0.unwrap().into_encoded();
let r = ApplyResult::decode(&mut &r[..]).unwrap();
let r = InclusionOutcome::decode(&mut &r[..]).unwrap();
assert_eq!(r, Err(InvalidTransaction::Payment.into()));
}

Expand Down Expand Up @@ -874,7 +874,7 @@ mod tests {
false,
None,
).0.unwrap().into_encoded();
ApplyResult::decode(&mut &r[..])
InclusionOutcome::decode(&mut &r[..])
.unwrap()
.expect("Extrinsic could be applied")
.expect("Extrinsic did not fail");
Expand Down
4 changes: 2 additions & 2 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use support::{
use primitives::u32_trait::{_1, _2, _3, _4};
use node_primitives::{AccountId, AccountIndex, Balance, BlockNumber, Hash, Index, Moment, Signature};
use sr_api::impl_runtime_apis;
use sr_primitives::{Permill, Perbill, ApplyResult, impl_opaque_keys, generic, create_runtime_str};
use sr_primitives::{Permill, Perbill, InclusionOutcome, impl_opaque_keys, generic, create_runtime_str};
use sr_primitives::curve::PiecewiseLinear;
use sr_primitives::transaction_validity::TransactionValidity;
use sr_primitives::weights::Weight;
Expand Down Expand Up @@ -583,7 +583,7 @@ impl_runtime_apis! {
}

impl block_builder_api::BlockBuilder<Block> for Runtime {
fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyResult {
fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> InclusionOutcome {
Executive::apply_extrinsic(extrinsic)
}

Expand Down
6 changes: 3 additions & 3 deletions client/api/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

use std::{self, error, result};
use state_machine;
use sr_primitives::ApplyError;
use sr_primitives::InclusionError;
use consensus;
use derive_more::{Display, From};

Expand All @@ -38,8 +38,8 @@ pub enum Error {
#[display(fmt = "UnknownBlock: {}", _0)]
UnknownBlock(String),
/// Applying extrinsic error.
#[display(fmt = "Extrinsic error: {:?}", _0)]
ApplyExtrinsicFailed(ApplyError),
#[display(fmt = "Extrinsic inclusion error: {:?}", _0)]
ApplyExtrinsicFailed(InclusionError),
/// Execution error.
#[display(fmt = "Execution: {}", _0)]
Execution(Box<dyn state_machine::Error>),
Expand Down
2 changes: 1 addition & 1 deletion client/block-builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ use sr_api::{Core, ApiExt, ApiErrorFor};
pub use runtime_api::BlockBuilder as BlockBuilderApi;

/// Error when the runtime failed to apply an extrinsic.
pub struct ApplyExtrinsicFailed(pub sr_primitives::ApplyError);
pub struct ApplyExtrinsicFailed(pub sr_primitives::InclusionError);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be renamed as well?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My logic was that I'd leave this as is to denote that apply_extrinsic failed because of the following reason which is represented by InclusionError.

I thought maybe it would be better to name apply_extrinsic as include_extrinsic, but that is getting out of hand...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That said, I am not strong on it. Give me a sign (thumbs up will do) and I will make the change


/// Utility for building new (valid) blocks from a stream of extrinsics.
pub struct BlockBuilder<'a, Block: BlockT, A: ProvideRuntimeApi> {
Expand Down
12 changes: 6 additions & 6 deletions paint/executive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@

use rstd::{prelude::*, marker::PhantomData};
use sr_primitives::{
generic::Digest, ApplyResult,
generic::Digest, InclusionOutcome,
weights::{GetDispatchInfo, WeighBlock},
traits::{
self, Header, Zero, One, Checkable, Applyable, CheckEqual, OnFinalize, OnInitialize,
Expand Down Expand Up @@ -227,7 +227,7 @@ where
/// Apply extrinsic outside of the block execution function.
/// This doesn't attempt to validate anything regarding the block, but it builds a list of uxt
/// hashes.
pub fn apply_extrinsic(uxt: Block::Extrinsic) -> ApplyResult {
pub fn apply_extrinsic(uxt: Block::Extrinsic) -> InclusionOutcome {
Comment thread
pepyakin marked this conversation as resolved.
Outdated
let encoded = uxt.encode();
let encoded_len = encoded.len();
Self::apply_extrinsic_with_len(uxt, encoded_len, Some(encoded))
Expand All @@ -248,7 +248,7 @@ where
uxt: Block::Extrinsic,
encoded_len: usize,
to_note: Option<Vec<u8>>,
) -> ApplyResult {
) -> InclusionOutcome {
// Verify that the signature is good.
let xt = uxt.check(&Default::default())?;

Expand Down Expand Up @@ -318,7 +318,7 @@ mod tests {
use sr_primitives::{
generic::Era, Perbill, DispatchError, weights::Weight, testing::{Digest, Header, Block},
traits::{Bounded, Header as HeaderT, BlakeTwo256, IdentityLookup, ConvertInto},
transaction_validity::{InvalidTransaction, UnknownTransaction}, ApplyError,
transaction_validity::{InvalidTransaction, UnknownTransaction}, InclusionError,
};
use support::{
impl_outer_event, impl_outer_origin, parameter_types, impl_outer_dispatch,
Expand Down Expand Up @@ -443,7 +443,7 @@ mod tests {
impl ValidateUnsigned for Runtime {
type Call = Call;

fn pre_dispatch(_call: &Self::Call) -> Result<(), ApplyError> {
fn pre_dispatch(_call: &Self::Call) -> Result<(), InclusionError> {
Ok(())
}

Expand Down Expand Up @@ -696,7 +696,7 @@ mod tests {
} else {
assert_eq!(
Executive::apply_extrinsic(xt),
Err(ApplyError::Validity(InvalidTransaction::Payment.into())),
Err(InclusionError::Validity(InvalidTransaction::Payment.into())),
);
assert_eq!(<balances::Module<Runtime>>::total_balance(&1), 111);
}
Expand Down
4 changes: 2 additions & 2 deletions paint/support/src/unsigned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub use crate::sr_primitives::traits::ValidateUnsigned;
#[doc(hidden)]
pub use crate::sr_primitives::transaction_validity::{TransactionValidity, UnknownTransaction};
#[doc(hidden)]
pub use crate::sr_primitives::ApplyError;
pub use crate::sr_primitives::InclusionError;


/// Implement `ValidateUnsigned` for `Runtime`.
Expand Down Expand Up @@ -70,7 +70,7 @@ macro_rules! impl_outer_validate_unsigned {
impl $crate::unsigned::ValidateUnsigned for $runtime {
type Call = Call;

fn pre_dispatch(call: &Self::Call) -> Result<(), $crate::unsigned::ApplyError> {
fn pre_dispatch(call: &Self::Call) -> Result<(), $crate::unsigned::InclusionError> {
#[allow(unreachable_patterns)]
match call {
$( Call::$module(inner_call) => $module::pre_dispatch(inner_call), )*
Expand Down
12 changes: 5 additions & 7 deletions paint/system/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ use rstd::fmt::Debug;
use sr_version::RuntimeVersion;
use sr_primitives::{
RuntimeDebug,
generic::{self, Era}, Perbill, ApplyError, ApplyOutcome, DispatchError,
generic::{self, Era}, Perbill, InclusionError, DispatchOutcome, DispatchError,
weights::{Weight, DispatchInfo, DispatchClass, SimpleDispatchInfo},
transaction_validity::{
ValidTransaction, TransactionPriority, TransactionLongevity, TransactionValidityError,
Expand Down Expand Up @@ -320,8 +320,6 @@ decl_event!(
decl_error! {
/// Error for the System module
pub enum Error {
BadSignature,
BlockFull,
RequireSignedOrigin,
RequireRootOrigin,
RequireNoOrigin,
Expand Down Expand Up @@ -754,9 +752,9 @@ impl<T: Trait> Module<T> {
}

/// To be called immediately after an extrinsic has been applied.
pub fn note_applied_extrinsic(r: &ApplyOutcome, _encoded_len: u32) {
pub fn note_applied_extrinsic(outcome: &DispatchOutcome, _encoded_len: u32) {
Self::deposit_event(
match r {
match outcome {
Ok(()) => Event::ExtrinsicSuccess,
Err(err) => Event::ExtrinsicFailed(err.clone()),
}
Expand Down Expand Up @@ -859,7 +857,7 @@ impl<T: Trait + Send + Sync> SignedExtension for CheckWeight<T> {
_call: &Self::Call,
info: DispatchInfo,
len: usize,
) -> Result<(), ApplyError> {
) -> Result<(), InclusionError> {
let next_len = Self::check_block_length(info, len)?;
AllExtrinsicsLen::put(next_len);
let next_weight = Self::check_weight(info)?;
Expand Down Expand Up @@ -938,7 +936,7 @@ impl<T: Trait> SignedExtension for CheckNonce<T> {
_call: &Self::Call,
_info: DispatchInfo,
_len: usize,
) -> Result<(), ApplyError> {
) -> Result<(), InclusionError> {
let expected = <AccountNonce<T>>::get(who);
if self.0 != expected {
return Err(
Expand Down
9 changes: 6 additions & 3 deletions primitives/block-builder/runtime-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,19 @@

#![cfg_attr(not(feature = "std"), no_std)]

use sr_primitives::{traits::Block as BlockT, ApplyResult};
use sr_primitives::{traits::Block as BlockT, InclusionOutcome};

use inherents::{InherentData, CheckInherentsResult};

sr_api::decl_runtime_apis! {
/// The `BlockBuilder` api trait that provides the required functionality for building a block.
#[api_version(3)]
pub trait BlockBuilder {
/// Apply the given extrinsics.
fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyResult;
/// Apply the given extrinsic.
///
/// Returns an inclusion outcome which specifies if this extrinsic should be included in
Comment thread
pepyakin marked this conversation as resolved.
Outdated
/// this block or not.
fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> InclusionOutcome;
/// Finish the current block.
#[renamed("finalise_block", 3)]
fn finalize_block() -> <Block as BlockT>::Header;
Expand Down
2 changes: 1 addition & 1 deletion primitives/sr-primitives/src/generic/checked_extrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ where
self,
info: DispatchInfo,
len: usize,
) -> crate::ApplyResult {
) -> crate::InclusionOutcome {
let (maybe_who, pre) = if let Some((id, extra)) = self.signed {
let pre = Extra::pre_dispatch(extra, &id, &self.function, info, len)?;
(Some(id), pre)
Expand Down
54 changes: 30 additions & 24 deletions primitives/sr-primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,56 +348,41 @@ impl From<ed25519::Signature> for AnySignature {

#[derive(Eq, PartialEq, Clone, Copy, Decode, Encode, RuntimeDebug)]
#[cfg_attr(feature = "std", derive(Serialize))]
/// Reason why an extrinsic couldn't be applied (i.e. invalid extrinsic).
pub enum ApplyError {
/// General error to do with the permissions of the sender.
NoPermission,

/// General error to do with the state of the system in general.
BadState,

/// Reason why an extrinsic couldn't be included into a block.
Comment thread
pepyakin marked this conversation as resolved.
Outdated
pub enum InclusionError {
Comment thread
pepyakin marked this conversation as resolved.
Outdated
/// Any error to do with the transaction validity.
Validity(transaction_validity::TransactionValidityError),
Comment thread
pepyakin marked this conversation as resolved.
Outdated
}

impl ApplyError {
impl InclusionError {
/// Returns if the reason for the error was block resource exhaustion.
pub fn exhausted_resources(&self) -> bool {
match self {
Self::Validity(e) => e.exhausted_resources(),
_ => false,
}
}
}

impl From<ApplyError> for &'static str {
fn from(err: ApplyError) -> &'static str {
impl From<InclusionError> for &'static str {
fn from(err: InclusionError) -> &'static str {
match err {
ApplyError::NoPermission => "Transaction does not have required permissions",
ApplyError::BadState => "System state currently prevents this transaction",
ApplyError::Validity(v) => v.into(),
InclusionError::Validity(v) => v.into(),
}
}
}

impl From<transaction_validity::TransactionValidityError> for ApplyError {
impl From<transaction_validity::TransactionValidityError> for InclusionError {
fn from(err: transaction_validity::TransactionValidityError) -> Self {
ApplyError::Validity(err)
InclusionError::Validity(err)
}
}

/// The outcome of applying a transaction.
pub type ApplyOutcome = Result<(), DispatchError>;

impl From<DispatchError> for ApplyOutcome {
impl From<DispatchError> for DispatchOutcome {
fn from(err: DispatchError) -> Self {
Err(err)
}
}

/// Result from attempt to apply an extrinsic.
pub type ApplyResult = Result<ApplyOutcome, ApplyError>;

#[derive(Eq, PartialEq, Clone, Copy, Encode, Decode, RuntimeDebug)]
#[cfg_attr(feature = "std", derive(Serialize))]
/// Reason why a dispatch call failed
Expand Down Expand Up @@ -451,6 +436,27 @@ impl From<&'static str> for DispatchError {
}
}

/// This type specifies the outcome of dispatching a call to a module.
///
/// In case of failure an error specific to the module is returned.
Comment thread
pepyakin marked this conversation as resolved.
pub type DispatchOutcome = Result<(), DispatchError>;

/// The outcome of inclusion of an extrinsic into a block.
///
/// This type is typically used in the context of `BlockBuilder` to signal that the extrinsic
/// in question cannot be included. It is fair to say that a valid block doesn't contain any
Comment thread
pepyakin marked this conversation as resolved.
Outdated
/// extrinsic that would have had a negative inclusion outcome. On successful inclusion this type
/// supplies the result of the extrinsic dispatch.
///
/// Examples of reasons preventing inclusion in a block:
/// - More block weight is required to process the extrinsic than is left in the block being built.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't name weight here and just say block resources. Weight is Palette specific while I suppose these error types are.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahhh, that's a good point. I am mistakingly assumed that we are in the pallete context.

/// This doesn't neccessarily mean that the extrinsic is invalid, since it can still be
/// included in the next block if it has enough spare weight available.
/// - The sender doesn't have enough funds to pay the transaction inclusion fee. Including such
/// a transaction in the block doesn't make sense.
/// - The extrinsic supplied a bad signature. This transaction won't become valid ever.

@kianenigma kianenigma Nov 19, 2019

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would make it very clear that a dispatch has two phases 1- pre-dispatch stuff and 2- the dispatch itself.

A signature check, and any other code that we might put in Executive::apply_extrinsic_xxx is in the first group (.check). For instance a signature check gives you Err(InclusionError)

A weight check, nonce and other things that happen either in signedExtensions or dispatch code itself are in the second group. I think a wrong nonce gives you Ok(DispatchError) (while an all okay dispatch gives Ok(())).

So I would make this distinction very clear in the docs.

(take the above with a grain of slat and double check, I didn't look super deep into the code.)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on this, without any explanation, I find it confusing that signature check and weight check are enumerated next to each other, as it seems that they are natively different types of checks.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I would redirect the reader from this documentation to how apply/dispatch + SignedExtensions work in general to get more details into the lifecycle of extrinsic.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, they are different checks in practice, but we are dealing with the non-pallete context, from the block builder API perspective, from that PoV they are essentially the same, isn't it This also relates to referencing the user to the documentation of SignedExtensions and co.

pub type InclusionOutcome = Result<DispatchOutcome, InclusionError>;

/// Verify a signature on an encoded value in a lazy manner. This can be
/// an optimization if the signature scheme has an "unsigned" escape hash.
pub fn verify_encoded_lazy<V: Verify, T: codec::Encode>(
Expand Down
4 changes: 2 additions & 2 deletions primitives/sr-primitives/src/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use crate::traits::{
};
#[allow(deprecated)]
use crate::traits::ValidateUnsigned;
use crate::{generic, KeyTypeId, ApplyResult};
use crate::{generic, KeyTypeId, InclusionOutcome};
use crate::weights::{GetDispatchInfo, DispatchInfo};
pub use primitives::{H256, sr25519};
use primitives::{crypto::{CryptoType, Dummy, key_types, Public}, U256};
Expand Down Expand Up @@ -353,7 +353,7 @@ impl<Origin, Call, Extra> Applyable for TestXt<Call, Extra> where
self,
info: DispatchInfo,
len: usize,
) -> ApplyResult {
) -> InclusionOutcome {
let maybe_who = if let Some((who, extra)) = self.0 {
Extra::pre_dispatch(extra, &who, &self.1, info, len)?;
Some(who)
Expand Down
Loading