Emit mortal transactions from relay (#1073)

* mortal relay transactions

* sign block hash for mortal transactions

* TransactionEraOf

* add explanation

* enable mortal transactions for Westend -> Millau headers relay

* clippy

* spellcheck
This commit is contained in:
Svyatoslav Nikolsky
2021-09-02 10:55:57 +03:00
committed by Bastian Köcher
parent 8b52cd2593
commit 864c830618
33 changed files with 249 additions and 73 deletions
+9 -9
View File
@@ -235,26 +235,26 @@ impl<Call> parity_scale_codec::Decode for SignedExtensions<Call> {
impl<Call> SignedExtensions<Call> {
pub fn new(
version: sp_version::RuntimeVersion,
era: sp_runtime::generic::Era,
era: bp_runtime::TransactionEraOf<PolkadotLike>,
genesis_hash: Hash,
nonce: Nonce,
tip: Balance,
) -> Self {
Self {
encode_payload: (
(), // spec version
(), // tx version
(), // genesis
era, // era
nonce.into(), // nonce (compact encoding)
(), // Check weight
tip.into(), // transaction payment / tip (compact encoding)
(), // spec version
(), // tx version
(), // genesis
era.frame_era(), // era
nonce.into(), // nonce (compact encoding)
(), // Check weight
tip.into(), // transaction payment / tip (compact encoding)
),
additional_signed: (
version.spec_version,
version.transaction_version,
genesis_hash,
genesis_hash,
era.signed_payload(genesis_hash),
(),
(),
(),
+7 -1
View File
@@ -42,7 +42,10 @@ pub trait Chain: Send + Sync + 'static {
+ FromStr
+ MaybeMallocSizeOf
+ AsPrimitive<usize>
+ Default;
+ Default
// original `sp_runtime::traits::Header::BlockNumber` doesn't have this trait, but
// `sp_runtime::generic::Era` requires block number -> `u64` conversion.
+ Into<u64>;
/// A type that fulfills the abstract idea of what a Substrate hash is.
// Constraits come from the associated Hash type of `sp_runtime::traits::Header`
@@ -85,3 +88,6 @@ pub type HasherOf<C> = <C as Chain>::Hasher;
/// Header type used by the chain.
pub type HeaderOf<C> = <C as Chain>::Header;
/// Transaction era used by the chain.
pub type TransactionEraOf<C> = crate::TransactionEra<BlockNumberOf<C>, HashOf<C>>;
+43 -1
View File
@@ -19,11 +19,12 @@
#![cfg_attr(not(feature = "std"), no_std)]
use codec::Encode;
use frame_support::RuntimeDebug;
use sp_core::hash::H256;
use sp_io::hashing::blake2_256;
use sp_std::convert::TryFrom;
pub use chain::{BlockNumberOf, Chain, HashOf, HasherOf, HeaderOf};
pub use chain::{BlockNumberOf, Chain, HashOf, HasherOf, HeaderOf, TransactionEraOf};
pub use storage_proof::{Error as StorageProofError, StorageProofChecker};
#[cfg(feature = "std")]
@@ -138,3 +139,44 @@ impl Size for PreComputedSize {
u32::try_from(self.0).unwrap_or(u32::MAX)
}
}
/// Era of specific transaction.
#[derive(RuntimeDebug, Clone, Copy)]
pub enum TransactionEra<BlockNumber, BlockHash> {
/// Transaction is immortal.
Immortal,
/// Transaction is valid for given number of blocks, starting from given block.
Mortal(BlockNumber, BlockHash, u32),
}
impl<BlockNumber: Copy + Into<u64>, BlockHash: Copy> TransactionEra<BlockNumber, BlockHash> {
/// Prepare transaction era, based on mortality period and current best block number.
pub fn new(best_block_number: BlockNumber, best_block_hash: BlockHash, mortality_period: Option<u32>) -> Self {
mortality_period
.map(|mortality_period| TransactionEra::Mortal(best_block_number, best_block_hash, mortality_period))
.unwrap_or(TransactionEra::Immortal)
}
/// Create new immortal transaction era.
pub fn immortal() -> Self {
TransactionEra::Immortal
}
/// Returns era that is used by FRAME-based runtimes.
pub fn frame_era(&self) -> sp_runtime::generic::Era {
match *self {
TransactionEra::Immortal => sp_runtime::generic::Era::immortal(),
TransactionEra::Mortal(header_number, _, period) => {
sp_runtime::generic::Era::mortal(period as _, header_number.into())
}
}
}
/// Returns header hash that needs to be included in the signature payload.
pub fn signed_payload(&self, genesis_hash: BlockHash) -> BlockHash {
match *self {
TransactionEra::Immortal => genesis_hash,
TransactionEra::Mortal(_, header_hash, _) => header_hash,
}
}
}