mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 15:51:12 +00:00
Transaction eras (#758)
* Initial groundwork * A mess. * Integrate * Fix tests * Unit tests * Tests for unchecked_extrisnic * fix tab * Improve binary format. * fix tests * Rename extrinsic-pool -> transaction-pool Closes #770 * Implement unimplemented. * typo
This commit is contained in:
@@ -46,7 +46,7 @@ use codec::{Encode, Decode, Codec, Input, Output};
|
||||
use runtime_support::{StorageValue, StorageMap, Parameter};
|
||||
use runtime_support::dispatch::Result;
|
||||
use primitives::traits::{Zero, One, SimpleArithmetic, OnFinalise, MakePayment,
|
||||
As, Lookup, Member, CheckedAdd, CheckedSub};
|
||||
As, Lookup, Member, CheckedAdd, CheckedSub, GetHeight, BlockNumberToHash};
|
||||
use address::Address as RawAddress;
|
||||
use system::ensure_signed;
|
||||
|
||||
@@ -630,6 +630,13 @@ impl<T: Trait> Module<T> {
|
||||
<TotalIssuance<T>>::put(v);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lookup(a: address::Address<T::AccountId, T::AccountIndex>) -> result::Result<T::AccountId, &'static str> {
|
||||
match a {
|
||||
address::Address::Id(i) => Ok(i),
|
||||
address::Address::Index(i) => <Module<T>>::lookup_index(i).ok_or("invalid account index"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> OnFinalise<T::BlockNumber> for Module<T> {
|
||||
@@ -637,14 +644,33 @@ impl<T: Trait> OnFinalise<T::BlockNumber> for Module<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> Lookup for Module<T> {
|
||||
pub struct ChainContext<T>(::rstd::marker::PhantomData<T>);
|
||||
impl<T> Default for ChainContext<T> {
|
||||
fn default() -> Self {
|
||||
ChainContext(::rstd::marker::PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> Lookup for ChainContext<T> {
|
||||
type Source = address::Address<T::AccountId, T::AccountIndex>;
|
||||
type Target = T::AccountId;
|
||||
fn lookup(a: Self::Source) -> result::Result<Self::Target, &'static str> {
|
||||
match a {
|
||||
address::Address::Id(i) => Ok(i),
|
||||
address::Address::Index(i) => <Module<T>>::lookup_index(i).ok_or("invalid account index"),
|
||||
}
|
||||
fn lookup(&self, a: Self::Source) -> result::Result<Self::Target, &'static str> {
|
||||
<Module<T>>::lookup(a)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> GetHeight for ChainContext<T> {
|
||||
type BlockNumber = T::BlockNumber;
|
||||
fn get_height(&self) -> Self::BlockNumber {
|
||||
<system::Module<T>>::block_number()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> BlockNumberToHash for ChainContext<T> {
|
||||
type BlockNumber = T::BlockNumber;
|
||||
type Hash = T::Hash;
|
||||
fn block_number_to_hash(&self, n: Self::BlockNumber) -> Option<Self::Hash> {
|
||||
Some(<system::Module<T>>::block_hash(n))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
//! Council system: Handles the voting in and maintenance of council members.
|
||||
|
||||
use rstd::prelude::*;
|
||||
use primitives::traits::{Zero, One, As, Lookup, OnFinalise};
|
||||
use primitives::traits::{Zero, One, As, OnFinalise};
|
||||
use runtime_io::print;
|
||||
use srml_support::{StorageValue, StorageMap, dispatch::Result};
|
||||
use democracy;
|
||||
|
||||
@@ -76,23 +76,22 @@ mod internal {
|
||||
pub struct Executive<
|
||||
System,
|
||||
Block,
|
||||
Lookup,
|
||||
Context,
|
||||
Payment,
|
||||
Finalisation,
|
||||
>(PhantomData<(System, Block, Lookup, Payment, Finalisation)>);
|
||||
>(PhantomData<(System, Block, Context, Payment, Finalisation)>);
|
||||
|
||||
impl<
|
||||
Address,
|
||||
Context: Default,
|
||||
System: system::Trait,
|
||||
Block: traits::Block<Header=System::Header, Hash=System::Hash>,
|
||||
Lookup: traits::Lookup<Source=Address, Target=System::AccountId>,
|
||||
Payment: MakePayment<System::AccountId>,
|
||||
Finalisation: OnFinalise<System::BlockNumber>,
|
||||
> Executive<System, Block, Lookup, Payment, Finalisation> where
|
||||
Block::Extrinsic: Checkable<fn(Address) -> Result<System::AccountId, &'static str>> + Codec,
|
||||
<Block::Extrinsic as Checkable<fn(Address) -> Result<System::AccountId, &'static str>>>::Checked: Applyable<Index=System::Index, AccountId=System::AccountId>,
|
||||
<<Block::Extrinsic as Checkable<fn(Address) -> Result<System::AccountId, &'static str>>>::Checked as Applyable>::Call: Dispatchable,
|
||||
<<<Block::Extrinsic as Checkable<fn(Address) -> Result<System::AccountId, &'static str>>>::Checked as Applyable>::Call as Dispatchable>::Origin: From<Option<System::AccountId>>
|
||||
> Executive<System, Block, Context, Payment, Finalisation> where
|
||||
Block::Extrinsic: Checkable<Context> + Codec,
|
||||
<Block::Extrinsic as Checkable<Context>>::Checked: Applyable<Index=System::Index, AccountId=System::AccountId>,
|
||||
<<Block::Extrinsic as Checkable<Context>>::Checked as Applyable>::Call: Dispatchable,
|
||||
<<<Block::Extrinsic as Checkable<Context>>::Checked as Applyable>::Call as Dispatchable>::Origin: From<Option<System::AccountId>>
|
||||
{
|
||||
/// Start the execution of a particular block.
|
||||
pub fn initialise_block(header: &System::Header) {
|
||||
@@ -177,13 +176,13 @@ impl<
|
||||
/// Actually apply an extrinsic given its `encoded_len`; this doesn't note its hash.
|
||||
fn apply_extrinsic_no_note_with_len(uxt: Block::Extrinsic, encoded_len: usize) -> result::Result<internal::ApplyOutcome, internal::ApplyError> {
|
||||
// Verify the signature is good.
|
||||
let xt = uxt.check_with(Lookup::lookup).map_err(internal::ApplyError::BadSignature)?;
|
||||
let xt = uxt.check(&Default::default()).map_err(internal::ApplyError::BadSignature)?;
|
||||
|
||||
if let Some(sender) = xt.sender() {
|
||||
if let (Some(sender), Some(index)) = (xt.sender(), xt.index()) {
|
||||
// check index
|
||||
let expected_index = <system::Module<System>>::account_nonce(sender);
|
||||
if xt.index() != &expected_index { return Err(
|
||||
if xt.index() < &expected_index { internal::ApplyError::Stale } else { internal::ApplyError::Future }
|
||||
if index != &expected_index { return Err(
|
||||
if index < &expected_index { internal::ApplyError::Stale } else { internal::ApplyError::Future }
|
||||
) }
|
||||
|
||||
// pay any fees.
|
||||
@@ -223,7 +222,7 @@ impl<
|
||||
pub fn validate_transaction(uxt: Block::Extrinsic) -> TransactionValidity {
|
||||
let encoded_len = uxt.encode().len();
|
||||
|
||||
let xt = match uxt.check_with(Lookup::lookup) {
|
||||
let xt = match uxt.check(&Default::default()) {
|
||||
// Checks out. Carry on.
|
||||
Ok(xt) => xt,
|
||||
// An unknown account index implies that the transaction may yet become valid.
|
||||
@@ -233,7 +232,7 @@ impl<
|
||||
Err(_) => return TransactionValidity::Invalid,
|
||||
};
|
||||
|
||||
if let Some(sender) = xt.sender() {
|
||||
if let (Some(sender), Some(index)) = (xt.sender(), xt.index()) {
|
||||
// pay any fees.
|
||||
if Payment::make_payment(sender, encoded_len).is_err() {
|
||||
return TransactionValidity::Invalid
|
||||
@@ -241,20 +240,20 @@ impl<
|
||||
|
||||
// check index
|
||||
let mut expected_index = <system::Module<System>>::account_nonce(sender);
|
||||
if xt.index() < &expected_index {
|
||||
if index < &expected_index {
|
||||
return TransactionValidity::Invalid
|
||||
}
|
||||
if *xt.index() > expected_index + As::sa(256) {
|
||||
if *index > expected_index + As::sa(256) {
|
||||
return TransactionValidity::Unknown
|
||||
}
|
||||
|
||||
let mut deps = Vec::new();
|
||||
while expected_index < *xt.index() {
|
||||
while expected_index < *index {
|
||||
deps.push((sender, expected_index).encode());
|
||||
expected_index = expected_index + One::one();
|
||||
}
|
||||
|
||||
TransactionValidity::Valid(encoded_len as TransactionPriority, deps, vec![(sender, *xt.index()).encode()], TransactionLongevity::max_value())
|
||||
TransactionValidity::Valid(encoded_len as TransactionPriority, deps, vec![(sender, *index).encode()], TransactionLongevity::max_value())
|
||||
} else {
|
||||
return TransactionValidity::Invalid
|
||||
}
|
||||
@@ -268,19 +267,10 @@ mod tests {
|
||||
use runtime_io::with_externalities;
|
||||
use substrate_primitives::{H256, Blake2Hasher, RlpCodec};
|
||||
use primitives::BuildStorage;
|
||||
use primitives::traits::{Header as HeaderT, BlakeTwo256, Lookup};
|
||||
use primitives::traits::{Header as HeaderT, BlakeTwo256};
|
||||
use primitives::testing::{Digest, DigestItem, Header, Block};
|
||||
use system;
|
||||
|
||||
struct NullLookup;
|
||||
impl Lookup for NullLookup {
|
||||
type Source = u64;
|
||||
type Target = u64;
|
||||
fn lookup(s: Self::Source) -> Result<Self::Target, &'static str> {
|
||||
Ok(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl_outer_origin! {
|
||||
pub enum Origin for Runtime {
|
||||
}
|
||||
@@ -316,7 +306,7 @@ mod tests {
|
||||
}
|
||||
|
||||
type TestXt = primitives::testing::TestXt<Call<Runtime>>;
|
||||
type Executive = super::Executive<Runtime, Block<TestXt>, NullLookup, balances::Module<Runtime>, ()>;
|
||||
type Executive = super::Executive<Runtime, Block<TestXt>, balances::ChainContext<Runtime>, balances::Module<Runtime>, ()>;
|
||||
|
||||
#[test]
|
||||
fn balance_transfer_dispatch_works() {
|
||||
|
||||
@@ -52,8 +52,7 @@ use rstd::cmp;
|
||||
use runtime_support::{Parameter, StorageValue, StorageMap};
|
||||
use runtime_support::dispatch::Result;
|
||||
use session::OnSessionChange;
|
||||
use primitives::traits::{Zero, One, Bounded, OnFinalise,
|
||||
As, Lookup};
|
||||
use primitives::traits::{Zero, One, Bounded, OnFinalise, As};
|
||||
use balances::{address::Address, OnDilution};
|
||||
use system::ensure_signed;
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ extern crate safe_mix;
|
||||
|
||||
use rstd::prelude::*;
|
||||
use primitives::traits::{self, CheckEqual, SimpleArithmetic, SimpleBitOps, Zero, One, Bounded,
|
||||
Hash, Member, MaybeDisplay, EnsureOrigin, Digest as DigestT, As};
|
||||
Hash, Member, MaybeDisplay, EnsureOrigin, Digest as DigestT, As, GetHeight, BlockNumberToHash};
|
||||
use substrate_primitives::storage::well_known_keys;
|
||||
use runtime_support::{storage, StorageValue, StorageMap, Parameter};
|
||||
use safe_mix::TripletMix;
|
||||
@@ -384,6 +384,21 @@ impl<T: Trait> Module<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> GetHeight for Module<T> {
|
||||
type BlockNumber = T::BlockNumber;
|
||||
fn get_height(&self) -> Self::BlockNumber {
|
||||
<Module<T>>::block_number()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> BlockNumberToHash for Module<T> {
|
||||
type BlockNumber = T::BlockNumber;
|
||||
type Hash = T::Hash;
|
||||
fn block_number_to_hash(&self, n: Self::BlockNumber) -> Option<Self::Hash> {
|
||||
Some(<Module<T>>::block_hash(n))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
|
||||
Reference in New Issue
Block a user