mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 08:51:09 +00:00
Fix most tests, introduce split-block processing tools for authoring.
This commit is contained in:
@@ -38,7 +38,7 @@ pub mod runtime;
|
||||
use runtime_std::prelude::*;
|
||||
use codec::Slicable;
|
||||
use runtime_std::print;
|
||||
use primitives::{Block, UncheckedTransaction};
|
||||
use primitives::{Block, Header, BlockNumber, UncheckedTransaction};
|
||||
|
||||
/// Execute a block, with `input` being the canonical serialisation of the block. Returns the
|
||||
/// empty vector.
|
||||
@@ -49,8 +49,9 @@ pub fn execute_block(input: &[u8]) -> Vec<u8> {
|
||||
|
||||
/// Execute a given, serialised, transaction. Returns the empty vector.
|
||||
pub fn execute_transaction(input: &[u8]) -> Vec<u8> {
|
||||
let utx = UncheckedTransaction::from_slice(input).unwrap();
|
||||
runtime::system::internal::execute_transaction(&utx);
|
||||
let number = BlockNumber::from_slice(&input[0..8]).unwrap();
|
||||
let utx = UncheckedTransaction::from_slice(&input[8..]).unwrap();
|
||||
runtime::system::internal::execute_transaction(&utx, Header::from_block_number(number));
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,18 @@ pub struct Header {
|
||||
pub digest: Digest,
|
||||
}
|
||||
|
||||
impl Header {
|
||||
pub fn from_block_number(number: BlockNumber) -> Self {
|
||||
Header {
|
||||
parent_hash: Default::default(),
|
||||
number,
|
||||
state_root: Default::default(),
|
||||
transaction_root: Default::default(),
|
||||
digest: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Slicable for Header {
|
||||
fn from_slice(value: &[u8]) -> Option<Self> {
|
||||
let mut reader = StreamReader::new(value);
|
||||
|
||||
@@ -151,9 +151,9 @@ mod tests {
|
||||
twox_128(&0u32.to_keyed_vec(ValidatorStorageVec::PREFIX)).to_vec() => vec![10; 32],
|
||||
twox_128(&1u32.to_keyed_vec(ValidatorStorageVec::PREFIX)).to_vec() => vec![20; 32],
|
||||
// initial session keys (11, 21, ...)
|
||||
twox_128(b"con:aut:len").to_vec() => vec![].join(&2u32),
|
||||
twox_128(&0u32.to_keyed_vec(b"con:aut:")).to_vec() => vec![11; 32],
|
||||
twox_128(&1u32.to_keyed_vec(b"con:aut:")).to_vec() => vec![21; 32]
|
||||
b"con:aut:len".to_vec() => vec![].join(&2u32),
|
||||
0u32.to_keyed_vec(b"con:aut:") => vec![11; 32],
|
||||
1u32.to_keyed_vec(b"con:aut:") => vec![21; 32]
|
||||
], }
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ use runtime_std::prelude::*;
|
||||
use runtime_std::{mem, storage_root, enumerated_trie_root};
|
||||
use codec::{KeyedVec, Slicable};
|
||||
use support::{Hashable, storage, with_env};
|
||||
use primitives::{Block, BlockNumber, Hash, UncheckedTransaction, TxOrder};
|
||||
use primitives::{Block, BlockNumber, Header, Hash, UncheckedTransaction, TxOrder};
|
||||
use runtime::{staking, session};
|
||||
|
||||
const NONCE_OF: &[u8] = b"sys:non:";
|
||||
@@ -84,7 +84,7 @@ pub mod internal {
|
||||
|
||||
// execute transactions
|
||||
for tx in &block.transactions {
|
||||
execute_transaction(tx);
|
||||
super::execute_transaction(tx);
|
||||
}
|
||||
|
||||
staking::internal::check_new_era();
|
||||
@@ -98,29 +98,34 @@ pub mod internal {
|
||||
debug_assert_hash(&header.state_root, &storage_root);
|
||||
assert!(header.state_root == storage_root, "Storage root must match that calculated.");
|
||||
|
||||
// store the header hash in storage; we can't do it before otherwise there would be a
|
||||
// cyclic dependency.
|
||||
let header_hash_key = header.number.to_keyed_vec(BLOCK_HASH_AT);
|
||||
storage::put(&header_hash_key, &header.blake2_256());
|
||||
// any stuff that we do after taking the storage root.
|
||||
post_finalise(header);
|
||||
}
|
||||
|
||||
/// Execute a given transaction.
|
||||
pub fn execute_transaction(utx: &UncheckedTransaction) {
|
||||
// Verify the signature is good.
|
||||
assert!(utx.ed25519_verify(), "All transactions should be properly signed");
|
||||
/// Execute a transaction outside of the block execution function.
|
||||
/// This doesn't attempt to validate anything regarding the block.
|
||||
pub fn execute_transaction(utx: &UncheckedTransaction, mut header: Header) {
|
||||
// populate environment from header.
|
||||
with_env(|e| {
|
||||
e.block_number = header.number;
|
||||
mem::swap(&mut e.digest, &mut header.digest);
|
||||
e.next_log_index = 0;
|
||||
});
|
||||
|
||||
let ref tx = utx.transaction;
|
||||
super::execute_transaction(utx);
|
||||
}
|
||||
|
||||
// check nonce
|
||||
let nonce_key = tx.signed.to_keyed_vec(NONCE_OF);
|
||||
let expected_nonce: TxOrder = storage::get_or(&nonce_key, 0);
|
||||
assert!(tx.nonce == expected_nonce, "All transactions should have the correct nonce");
|
||||
/// Finalise the block - it is up the caller to ensure that all header fields are valid
|
||||
/// except state-root.
|
||||
pub fn finalise_block(mut header: Header) -> Header {
|
||||
staking::internal::check_new_era();
|
||||
session::internal::check_rotate_session();
|
||||
|
||||
// increment nonce in storage
|
||||
storage::put(&nonce_key, &(expected_nonce + 1));
|
||||
header.state_root = storage_root();
|
||||
|
||||
// decode parameters and dispatch
|
||||
tx.function.dispatch(&tx.signed, &tx.input_data);
|
||||
post_finalise(&header);
|
||||
|
||||
header
|
||||
}
|
||||
|
||||
#[cfg(feature = "with-std")]
|
||||
@@ -135,12 +140,36 @@ pub mod internal {
|
||||
fn debug_assert_hash(_given: &Hash, _expected: &Hash) {}
|
||||
}
|
||||
|
||||
fn execute_transaction(utx: &UncheckedTransaction) {
|
||||
// Verify the signature is good.
|
||||
assert!(utx.ed25519_verify(), "All transactions should be properly signed");
|
||||
|
||||
let ref tx = utx.transaction;
|
||||
|
||||
// check nonce
|
||||
let nonce_key = tx.signed.to_keyed_vec(NONCE_OF);
|
||||
let expected_nonce: TxOrder = storage::get_or(&nonce_key, 0);
|
||||
assert!(tx.nonce == expected_nonce, "All transactions should have the correct nonce");
|
||||
|
||||
// increment nonce in storage
|
||||
storage::put(&nonce_key, &(expected_nonce + 1));
|
||||
|
||||
// decode parameters and dispatch
|
||||
tx.function.dispatch(&tx.signed, &tx.input_data);
|
||||
}
|
||||
|
||||
fn final_checks(_block: &Block) {
|
||||
with_env(|e| {
|
||||
assert_eq!(e.next_log_index, e.digest.logs.len());
|
||||
});
|
||||
}
|
||||
|
||||
fn post_finalise(header: &Header) {
|
||||
// store the header hash in storage; we can't do it before otherwise there would be a
|
||||
// cyclic dependency.
|
||||
storage::put(&header.number.to_keyed_vec(BLOCK_HASH_AT), &header.blake2_256());
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@@ -174,7 +203,7 @@ mod tests {
|
||||
println!("tx is {}", HexDisplay::from(&tx.transaction.to_vec()));
|
||||
|
||||
with_externalities(&mut t, || {
|
||||
execute_transaction(&tx);
|
||||
internal::execute_transaction(&tx, Header::from_block_number(1));
|
||||
assert_eq!(staking::balance(&one), 42);
|
||||
assert_eq!(staking::balance(&two), 69);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user