Tagged transaction queue integration (#893)

* Make the graph generic.

* Adapting pool API for the graph.

* Merge pool & graph.

* Restructure.

* Fix test of transaction pool.

* Get rid of node/transaction-pool.

* Compilation fixes.

* Test7

* Fix compilation of tests.

* Revert runtime changes.

* Add validate_transaction to test-runtime.

* Fix RPC tests.

* Add clearing of the old transactions.

* Trigger pool events.

* Use new queue API.

* Fix wasm build, re-export Hasher.

* No warning if validate transaction fails.

* Get rid of Into<u64> and use As
This commit is contained in:
Tomasz Drwięga
2018-10-12 13:09:35 +02:00
committed by Gav Wood
parent 2404d3c89f
commit 671b0e0007
48 changed files with 1234 additions and 1524 deletions
+52 -6
View File
@@ -18,14 +18,14 @@
//! and depositing logs.
use rstd::prelude::*;
use runtime_io::{storage_root, enumerated_trie_root, storage_changes_root};
use runtime_io::{storage_root, enumerated_trie_root, storage_changes_root, twox_128};
use runtime_support::storage::{self, StorageValue, StorageMap};
use runtime_primitives::traits::{Hash as HashT, BlakeTwo256, Digest as DigestT};
use runtime_primitives::generic;
use runtime_primitives::{ApplyError, ApplyOutcome, ApplyResult};
use runtime_primitives::{ApplyError, ApplyOutcome, ApplyResult, transaction_validity::TransactionValidity};
use codec::{KeyedVec, Encode};
use super::{AccountId, BlockNumber, Extrinsic, H256 as Hash, Block, Header, Digest};
use primitives::Blake2Hasher;
use primitives::{Blake2Hasher};
use primitives::storage::well_known_keys;
const NONCE_OF: &[u8] = b"nonce:";
@@ -99,6 +99,47 @@ pub fn execute_block(block: Block) {
assert!(digest == header.digest, "Header digest items must match that calculated.");
}
/// Execute a transaction outside of the block execution function.
/// This doesn't attempt to validate anything regarding the block.
pub fn validate_transaction(utx: Extrinsic) -> TransactionValidity {
let tx = match check_signature(&utx) {
Ok(tx) => tx,
Err(_) => return TransactionValidity::Invalid,
};
let nonce_key = tx.from.to_keyed_vec(NONCE_OF);
let expected_nonce: u64 = storage::get_or(&nonce_key, 0);
if tx.nonce < expected_nonce {
return TransactionValidity::Invalid;
}
if tx.nonce > expected_nonce + 64 {
return TransactionValidity::Unknown;
}
let hash = |from: &AccountId, nonce: u64| {
twox_128(&nonce.to_keyed_vec(&*from)).to_vec()
};
let requires = if tx.nonce != expected_nonce && tx.nonce > 0 {
let mut deps = Vec::new();
deps.push(hash(&tx.from, tx.nonce - 1));
deps
} else { Vec::new() };
let provides = {
let mut p = Vec::new();
p.push(hash(&tx.from, tx.nonce));
p
};
TransactionValidity::Valid(
/* priority: */tx.amount,
requires,
provides,
/* longevity: */64
)
}
/// Execute a transaction outside of the block execution function.
/// This doesn't attempt to validate anything regarding the block.
pub fn execute_transaction(utx: Extrinsic) -> ApplyResult {
@@ -135,16 +176,21 @@ pub fn finalise_block() -> Header {
}
}
fn execute_transaction_backend(utx: &Extrinsic) -> ApplyResult {
#[inline(always)]
fn check_signature(utx: &Extrinsic) -> Result<::Transfer, ApplyError> {
use runtime_primitives::traits::BlindCheckable;
// check signature
let utx = match utx.clone().check() {
Ok(tx) => tx,
Err(_) => return Err(ApplyError::BadSignature),
};
let tx: ::Transfer = utx.transfer;
Ok(utx.transfer)
}
fn execute_transaction_backend(utx: &Extrinsic) -> ApplyResult {
// check signature
let tx = check_signature(utx)?;
// check nonce
let nonce_key = tx.from.to_keyed_vec(NONCE_OF);