mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 17:31:05 +00:00
Generalised Transaction Queue API (#741)
* First effort * API versioning * Introduce validate_transaction * Introduce the API plus fixes. * Docs * Typo * Add longevity parameter to transaction validity info.
This commit is contained in:
@@ -31,6 +31,7 @@ extern crate parity_codec_derive;
|
||||
#[cfg_attr(test, macro_use)]
|
||||
extern crate srml_support as runtime_support;
|
||||
|
||||
#[cfg_attr(not(feature = "std"), macro_use)]
|
||||
extern crate sr_std as rstd;
|
||||
extern crate sr_io as runtime_io;
|
||||
extern crate parity_codec as codec;
|
||||
@@ -51,11 +52,12 @@ use rstd::prelude::*;
|
||||
use rstd::marker::PhantomData;
|
||||
use rstd::result;
|
||||
use primitives::traits::{self, Header, Zero, One, Checkable, Applyable, CheckEqual, OnFinalise,
|
||||
MakePayment, Hash};
|
||||
MakePayment, Hash, As};
|
||||
use runtime_support::Dispatchable;
|
||||
use codec::{Codec, Encode};
|
||||
use system::extrinsics_root;
|
||||
use primitives::{ApplyOutcome, ApplyError};
|
||||
use primitives::transaction_validity::{TransactionValidity, TransactionPriority, TransactionLongevity};
|
||||
|
||||
mod internal {
|
||||
pub enum ApplyError {
|
||||
@@ -213,6 +215,50 @@ impl<
|
||||
header.state_root().check_equal(&storage_root);
|
||||
assert!(header.state_root() == &storage_root, "Storage root must match that calculated.");
|
||||
}
|
||||
|
||||
/// Check a given transaction for validity. This doesn't execute any
|
||||
/// side-effects; it merely checks whether the transaction would panic if it were included or not.
|
||||
///
|
||||
/// Changes made to the storage should be discarded.
|
||||
pub fn validate_transaction(uxt: Block::Extrinsic) -> TransactionValidity {
|
||||
let encoded_len = uxt.encode().len();
|
||||
|
||||
let xt = match uxt.check_with(Lookup::lookup) {
|
||||
// Checks out. Carry on.
|
||||
Ok(xt) => xt,
|
||||
// An unknown account index implies that the transaction may yet become valid.
|
||||
Err("invalid account index") => return TransactionValidity::Unknown,
|
||||
// Technically a bad signature could also imply an out-of-date account index, but
|
||||
// that's more of an edge case.
|
||||
Err(_) => return TransactionValidity::Invalid,
|
||||
};
|
||||
|
||||
if let Some(sender) = xt.sender() {
|
||||
// pay any fees.
|
||||
if Payment::make_payment(sender, encoded_len).is_err() {
|
||||
return TransactionValidity::Invalid
|
||||
}
|
||||
|
||||
// check index
|
||||
let mut expected_index = <system::Module<System>>::account_nonce(sender);
|
||||
if xt.index() < &expected_index {
|
||||
return TransactionValidity::Invalid
|
||||
}
|
||||
if *xt.index() > expected_index + As::sa(256) {
|
||||
return TransactionValidity::Unknown
|
||||
}
|
||||
|
||||
let mut deps = Vec::new();
|
||||
while expected_index < *xt.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())
|
||||
} else {
|
||||
return TransactionValidity::Invalid
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user