Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

81 changes: 81 additions & 0 deletions core/sr-primitives/src/call_attributes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright 2019 Parity Technologies (UK) Ltd.
// This file is part of Substrate.

// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.

//! Primitives for call metadata.
//!
//! Each dispatch function within `decl_module!` can have an optional
//! `#[meta = $x]` attribute. $x can be any object that implements the
//! `CallMetadata` trait. By default, All transactions are annotated by
//! `#[weight = WeightedTransaction::default()]`.
//!
//! Note that the `decl_module` macro _cannot_ enforce this and will simply fail
//! if an invalid struct is passed in.

use crate::traits::{Zero, Bounded};
use crate::transaction_validity::TransactionPriority;

/// The numeric representation of a transaction weight.
pub type Weight = u32;

/// A bundle of the types that must be included in the call metadata.
pub type CallDescriptor = (Weight, TransactionPriority);

/// A `Call` enum (aka transaction) that can carry a set of static information to the executive and
/// subsequent execution paths.
///
/// To be included, each `Call` function must include the `$[meta = $x]` attribute where `$x` can be
/// any type that implements the `TransactionInfo` trait.
pub trait CallMetadata {
/// Return the weight of this call.
/// The `len` argument is the encoded length of the transaction/call.
fn info(&self, len: usize) -> CallDescriptor;
}

/// Default type used as the weight representative in a `#[weight = x]` attribute.
///
/// A user may pass in any other type that implements [`CallMetadata`]. If not, the `Default`
/// implementation of [`WeightedTransaction`] is used.
pub enum WeightedTransaction {
/// Basic weight (base, byte).
/// The values contained are the base weight and byte weight respectively.
Basic(Weight, Weight),
/// An operational transaction (sudo calls, runtime upgrades, democracy actions). These will
/// incur no additional weight and will always have maximum priority.
Operational(Weight, Weight)
}

impl CallMetadata for WeightedTransaction {
fn info(&self, len: usize) -> CallDescriptor {
let weight = match self {
WeightedTransaction::Basic(base, byte) => base + byte * len as Weight,
WeightedTransaction::Operational(_, _) => Zero::zero(),
};
let priority: TransactionPriority = match self {
WeightedTransaction::Basic(_, _) => weight.into(),
WeightedTransaction::Operational(_, _) => Bounded::max_value()
};
(weight, priority)
}
}

impl Default for WeightedTransaction {
fn default() -> Self {
// This implies that the weight is currently equal to tx-size, nothing more
// for all substrate transactions that do NOT explicitly annotate weight.
// TODO #2431 needs to be updated with proper max values.
WeightedTransaction::Basic(0, 1)
}
}
22 changes: 11 additions & 11 deletions core/sr-primitives/src/generic/checked_extrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::traits::{
self, Member, MaybeDisplay, SignedExtension, DispatchError, Dispatchable, DispatchResult,
ValidateUnsigned
};
use crate::weights::{Weighable, Weight};
use crate::call_attributes::{CallMetadata, CallDescriptor};
use crate::transaction_validity::TransactionValidity;

/// Definition of something that the external world might want to say; its
Expand Down Expand Up @@ -57,12 +57,12 @@ where
}

fn validate<U: ValidateUnsigned<Call=Self::Call>>(&self,
weight: crate::weights::Weight,
info: CallDescriptor,
) -> TransactionValidity {
if let Some((ref id, ref extra)) = self.signed {
Extra::validate(extra, id, weight).into()
Extra::validate(extra, id, info).into()
} else {
match Extra::validate_unsigned(weight) {
match Extra::validate_unsigned(info) {
Ok(extra) => match U::validate_unsigned(&self.function) {
TransactionValidity::Valid(v) =>
TransactionValidity::Valid(v.combine_with(extra)),
Expand All @@ -74,24 +74,24 @@ where
}

fn dispatch(self,
weight: crate::weights::Weight,
info: CallDescriptor,
) -> Result<DispatchResult, DispatchError> {
let maybe_who = if let Some((id, extra)) = self.signed {
Extra::pre_dispatch(extra, &id, weight)?;
Extra::pre_dispatch(extra, &id, info)?;
Some(id)
} else {
Extra::pre_dispatch_unsigned(weight)?;
Extra::pre_dispatch_unsigned(info)?;
None
};
Ok(self.function.dispatch(Origin::from(maybe_who)))
}
}

impl<AccountId, Call, Extra> Weighable for CheckedExtrinsic<AccountId, Call, Extra>
impl<AccountId, Call, Extra> CallMetadata for CheckedExtrinsic<AccountId, Call, Extra>
where
Call: Weighable,
Call: CallMetadata,
{
fn weight(&self, len: usize) -> Weight {
self.function.weight(len)
fn info(&self, len: usize) -> CallDescriptor {
self.function.info(len)
}
}
2 changes: 1 addition & 1 deletion core/sr-primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ use codec::{Encode, Decode};
#[cfg(feature = "std")]
pub mod testing;

pub mod weights;
pub mod call_attributes;
pub mod traits;
use traits::{SaturatedConversion, UniqueSaturatedInto};

Expand Down
17 changes: 8 additions & 9 deletions core/sr-primitives/src/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use crate::traits::{
ValidateUnsigned, SignedExtension, Dispatchable,
};
use crate::{generic, KeyTypeId};
use crate::weights::{Weighable, Weight};
use crate::call_attributes::{CallDescriptor, CallMetadata};
pub use substrate_primitives::H256;
use substrate_primitives::U256;
use substrate_primitives::ed25519::{Public as AuthorityId};
Expand Down Expand Up @@ -240,30 +240,29 @@ impl<Origin, Call, Extra> Applyable for TestXt<Call, Extra> where

/// Checks to see if this is a valid *transaction*. It returns information on it if so.
fn validate<U: ValidateUnsigned<Call=Self::Call>>(&self,
_weight: Weight
_info: CallDescriptor
) -> TransactionValidity {
TransactionValidity::Valid(Default::default())
}

/// Executes all necessary logic needed prior to dispatch and deconstructs into function call,
/// index and sender.
fn dispatch(self,
weight: Weight
info: CallDescriptor
) -> Result<DispatchResult, DispatchError> {
let maybe_who = if let Some(who) = self.0 {
Extra::pre_dispatch(self.2, &who, weight)?;
Extra::pre_dispatch(self.2, &who, info)?;
Some(who)
} else {
Extra::pre_dispatch_unsigned(weight)?;
Extra::pre_dispatch_unsigned(info)?;
None
};
Ok(self.1.dispatch(maybe_who.into()))
}
}

impl<Call, Extra> Weighable for TestXt<Call, Extra> {
fn weight(&self, len: usize) -> Weight {
// for testing: weight == size.
len as Weight
impl<Call, Extra> CallMetadata for TestXt<Call, Extra> {
fn info(&self, len: usize) -> CallDescriptor {
(len as u32, len as u64)
}
}
33 changes: 17 additions & 16 deletions core/sr-primitives/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ use rstd::ops::{
Add, Sub, Mul, Div, Rem, AddAssign, SubAssign, MulAssign, DivAssign,
RemAssign, Shl, Shr
};
use crate::call_attributes::CallDescriptor;

/// A lazy value.
pub trait Lazy<T: ?Sized> {
Expand Down Expand Up @@ -825,27 +826,27 @@ pub trait SignedExtension:
fn validate(
&self,
_who: &Self::AccountId,
_weight: crate::weights::Weight,
_info: CallDescriptor,
) -> Result<ValidTransaction, DispatchError> { Ok(Default::default()) }

/// Do any pre-flight stuff for a signed transaction.
fn pre_dispatch(
self,
who: &Self::AccountId,
weight: crate::weights::Weight,
) -> Result<(), DispatchError> { self.validate(who, weight).map(|_| ()) }
info: CallDescriptor,
) -> Result<(), DispatchError> { self.validate(who, info).map(|_| ()) }

/// Validate an unsigned transaction for the transaction queue. Normally the default
/// implementation is fine since `ValidateUnsigned` is a better way of recognising and
/// validating unsigned transactions.
fn validate_unsigned(
_weight: crate::weights::Weight,
_info: CallDescriptor,
) -> Result<ValidTransaction, DispatchError> { Ok(Default::default()) }

/// Do any pre-flight stuff for a unsigned transaction.
fn pre_dispatch_unsigned(
weight: crate::weights::Weight,
) -> Result<(), DispatchError> { Self::validate_unsigned(weight).map(|_| ()) }
info: CallDescriptor,
) -> Result<(), DispatchError> { Self::validate_unsigned(info).map(|_| ()) }
}

macro_rules! tuple_impl_indexed {
Expand All @@ -865,29 +866,29 @@ macro_rules! tuple_impl_indexed {
fn validate(
&self,
who: &Self::AccountId,
weight: crate::weights::Weight,
info: CallDescriptor,
) -> Result<ValidTransaction, DispatchError> {
let aggregator = vec![$(<$direct as SignedExtension>::validate(&self.$index, who, weight)?),+];
let aggregator = vec![$(<$direct as SignedExtension>::validate(&self.$index, who, info)?),+];
Ok(aggregator.into_iter().fold(ValidTransaction::default(), |acc, a| acc.combine_with(a)))
}
fn pre_dispatch(
self,
who: &Self::AccountId,
weight: crate::weights::Weight,
info: CallDescriptor,
) -> Result<(), DispatchError> {
$(self.$index.pre_dispatch(who, weight)?;)+
$(self.$index.pre_dispatch(who, info)?;)+
Ok(())
}
fn validate_unsigned(
weight: crate::weights::Weight,
info: CallDescriptor,
) -> Result<ValidTransaction, DispatchError> {
let aggregator = vec![$($direct::validate_unsigned(weight)?),+];
let aggregator = vec![$($direct::validate_unsigned(info)?),+];
Ok(aggregator.into_iter().fold(ValidTransaction::default(), |acc, a| acc.combine_with(a)))
}
fn pre_dispatch_unsigned(
weight: crate::weights::Weight,
info: CallDescriptor,
) -> Result<(), DispatchError> {
$($direct::pre_dispatch_unsigned(weight)?;)+
$($direct::pre_dispatch_unsigned(info)?;)+
Ok(())
}
}
Expand Down Expand Up @@ -936,13 +937,13 @@ pub trait Applyable: Sized + Send + Sync {

/// Checks to see if this is a valid *transaction*. It returns information on it if so.
fn validate<V: ValidateUnsigned<Call=Self::Call>>(&self,
weight: crate::weights::Weight
info: CallDescriptor
) -> TransactionValidity;

/// Executes all necessary logic needed prior to dispatch and deconstructs into function call,
/// index and sender.
fn dispatch(self,
weight: crate::weights::Weight
info: CallDescriptor
) -> Result<DispatchResult, DispatchError>;
}

Expand Down
76 changes: 0 additions & 76 deletions core/sr-primitives/src/weights.rs

This file was deleted.

3 changes: 2 additions & 1 deletion node-template/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ use primitives::bytes;
use primitives::{ed25519, sr25519, OpaqueMetadata};
use runtime_primitives::{
ApplyResult, transaction_validity::TransactionValidity, generic, create_runtime_str,
traits::{self, NumberFor, BlakeTwo256, Block as BlockT, StaticLookup, Verify}, weights::Weight,
traits::{self, NumberFor, BlakeTwo256, Block as BlockT, StaticLookup, Verify},
call_attributes::Weight,
};
use client::{
block_builder::api::{CheckInherentsResult, InherentData, self as block_builder_api},
Expand Down
2 changes: 1 addition & 1 deletion node-template/runtime/src/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ mod tests {
use primitives::{H256, Blake2Hasher};
use support::{impl_outer_origin, assert_ok, parameter_types};
use runtime_primitives::{traits::{BlakeTwo256, IdentityLookup}, testing::Header};
use runtime_primitives::weights::Weight;
use runtime_primitives::call_attributes::Weight;

impl_outer_origin! {
pub enum Origin for Test {}
Expand Down
Loading