From ba0794a4a725e4256be7d4264ddf30a9b34173c6 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Thu, 18 Apr 2019 10:01:15 +0200 Subject: [PATCH 1/4] WIP --- core/sr-primitives/src/generic/era.rs | 15 +++++++++------ .../generic/unchecked_mortal_compact_extrinsic.rs | 4 ++-- .../src/generic/unchecked_mortal_extrinsic.rs | 4 ++-- core/sr-primitives/src/traits.rs | 6 +++--- core/transaction-pool/graph/src/pool.rs | 2 +- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/core/sr-primitives/src/generic/era.rs b/core/sr-primitives/src/generic/era.rs index e5a7b24f0cc5f..a2be05ab19fa5 100644 --- a/core/sr-primitives/src/generic/era.rs +++ b/core/sr-primitives/src/generic/era.rs @@ -20,6 +20,7 @@ use serde_derive::{Serialize, Deserialize}; use crate::codec::{Decode, Encode, Input, Output}; +use crate::traits::SimpleArithmetic; pub type Period = u64; pub type Phase = u64; @@ -79,18 +80,20 @@ impl Era { /// Get the block number of the start of the era whose properties this object /// describes that `current` belongs to. - pub fn birth(self, current: u64) -> u64 { + pub fn birth>(self, current: T) -> T { match self { - Era::Immortal => 0, - Era::Mortal(period, phase) => (current.max(phase) - phase) / period * period + phase, + Era::Immortal => T::zero(), + Era::Mortal(period, phase) => { + (current.max(phase.into()) - phase.into()) / period.into() * period.into() + phase.into() + } } } /// Get the block number of the first block at which the era has ended. - pub fn death(self, current: u64) -> u64 { + pub fn death>(self, current: T) -> T { match self { - Era::Immortal => u64::max_value(), - Era::Mortal(period, _) => self.birth(current) + period, + Era::Immortal => T::max_value(), + Era::Mortal(period, _) => self.birth(current) + period.into(), } } } diff --git a/core/sr-primitives/src/generic/unchecked_mortal_compact_extrinsic.rs b/core/sr-primitives/src/generic/unchecked_mortal_compact_extrinsic.rs index 243747092c49c..d72fc88b3ae1e 100644 --- a/core/sr-primitives/src/generic/unchecked_mortal_compact_extrinsic.rs +++ b/core/sr-primitives/src/generic/unchecked_mortal_compact_extrinsic.rs @@ -73,7 +73,7 @@ where Call: Encode + Member, Signature: Member + traits::Verify, AccountId: Member + MaybeDisplay, - BlockNumber: SimpleArithmetic, + BlockNumber: SimpleArithmetic + From, Hash: Encode, Context: Lookup + CurrentHeight @@ -84,7 +84,7 @@ where fn check(self, context: &Context) -> Result { Ok(match self.signature { Some((signed, signature, index, era)) => { - let h = context.block_number_to_hash(BlockNumber::sa(era.birth(context.current_height().as_()))) + let h = context.block_number_to_hash(era.birth(context.current_height())) .ok_or("transaction birth block ancient")?; let signed = context.lookup(signed)?; let raw_payload = (index, self.function, era, h); diff --git a/core/sr-primitives/src/generic/unchecked_mortal_extrinsic.rs b/core/sr-primitives/src/generic/unchecked_mortal_extrinsic.rs index 93eeb55884479..11bb8d429907a 100644 --- a/core/sr-primitives/src/generic/unchecked_mortal_extrinsic.rs +++ b/core/sr-primitives/src/generic/unchecked_mortal_extrinsic.rs @@ -72,7 +72,7 @@ where Call: Encode + Member, Signature: Member + traits::Verify, AccountId: Member + MaybeDisplay, - BlockNumber: SimpleArithmetic, + BlockNumber: SimpleArithmetic + From, Hash: Encode, Context: Lookup + CurrentHeight @@ -83,7 +83,7 @@ where fn check(self, context: &Context) -> Result { Ok(match self.signature { Some((signed, signature, index, era)) => { - let h = context.block_number_to_hash(BlockNumber::sa(era.birth(context.current_height().as_()))) + let h = context.block_number_to_hash(era.birth(context.current_height())) .ok_or("transaction birth block ancient")?; let signed = context.lookup(signed)?; let raw_payload = (index, self.function, era, h); diff --git a/core/sr-primitives/src/traits.rs b/core/sr-primitives/src/traits.rs index b62bc067b6b84..93622e3de92fb 100644 --- a/core/sr-primitives/src/traits.rs +++ b/core/sr-primitives/src/traits.rs @@ -216,7 +216,7 @@ impl_numerics!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize); /// A meta trait for arithmetic. pub trait SimpleArithmetic: - Zero + One + IntegerSquareRoot + As + + Zero + One + IntegerSquareRoot + Add + AddAssign + Sub + SubAssign + Mul + MulAssign + @@ -234,7 +234,7 @@ pub trait SimpleArithmetic: HasCompact {} impl + + Zero + One + IntegerSquareRoot + Add + AddAssign + Sub + SubAssign + Mul + MulAssign + @@ -575,7 +575,7 @@ impl Mem /// You can also create a `new` one from those fields. pub trait Header: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebugButNotDeserialize + 'static { /// Header number. - type Number: Member + MaybeSerializeDebug + ::rstd::hash::Hash + Copy + MaybeDisplay + SimpleArithmetic + Codec; + type Number: Member + MaybeSerializeDebug + ::rstd::hash::Hash + Copy + MaybeDisplay + SimpleArithmetic + Codec + Into; /// Header hash type type Hash: Member + MaybeSerializeDebug + ::rstd::hash::Hash + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]>; /// Hashing algorithm diff --git a/core/transaction-pool/graph/src/pool.rs b/core/transaction-pool/graph/src/pool.rs index 91ded26630cf1..b33221084313c 100644 --- a/core/transaction-pool/graph/src/pool.rs +++ b/core/transaction-pool/graph/src/pool.rs @@ -138,7 +138,7 @@ impl Pool { priority, requires, provides, - valid_till: block_number.as_().saturating_add(longevity), + valid_till: block_number.into().saturating_add(longevity), }) }, TransactionValidity::Invalid(e) => { From 7c7e2f467c7f8aee90b76d1821a187a9a1ce8a3b Mon Sep 17 00:00:00 2001 From: thiolliere Date: Thu, 18 Apr 2019 12:23:06 +0200 Subject: [PATCH 2/4] WIP --- core/client/src/cht.rs | 2 +- core/consensus/common/src/evaluation.rs | 5 +- core/sr-primitives/src/generic/header.rs | 2 +- core/sr-primitives/src/traits.rs | 2 +- core/transaction-pool/graph/src/base_pool.rs | 47 +++++++-------- core/transaction-pool/graph/src/future.rs | 32 +++++----- core/transaction-pool/graph/src/pool.rs | 14 ++--- core/transaction-pool/graph/src/ready.rs | 62 ++++++++++---------- core/transaction-pool/graph/src/rotator.rs | 2 +- srml/system/src/lib.rs | 2 +- 10 files changed, 86 insertions(+), 84 deletions(-) diff --git a/core/client/src/cht.rs b/core/client/src/cht.rs index 13db1c67ebe81..92871e7614e4d 100644 --- a/core/client/src/cht.rs +++ b/core/client/src/cht.rs @@ -276,7 +276,7 @@ pub fn block_to_cht_number(cht_size: u64, block_num: N) -> } /// Convert header number into CHT key. -pub fn encode_cht_key>(number: N) -> Vec { +pub fn encode_cht_key>(number: N) -> Vec { let number: u64 = number.as_(); vec![ (number >> 56) as u8, diff --git a/core/consensus/common/src/evaluation.rs b/core/consensus/common/src/evaluation.rs index 48016b1e94c93..407200624d800 100644 --- a/core/consensus/common/src/evaluation.rs +++ b/core/consensus/common/src/evaluation.rs @@ -72,8 +72,9 @@ pub fn evaluate_initial( )); } - if parent_number.as_() + 1 != proposal.header().number().as_() { - bail!(ErrorKind::WrongNumber(parent_number.as_() + 1, proposal.header().number().as_())); + if parent_number + 1.into() != *proposal.header().number() { + // TODO TODO: make error generic + bail!(ErrorKind::WrongNumber(0, 0));// parent_number + 1.into(), proposal.header().number())); } Ok(()) diff --git a/core/sr-primitives/src/generic/header.rs b/core/sr-primitives/src/generic/header.rs index 60ccd93b3ded8..e4b9647d3fb86 100644 --- a/core/sr-primitives/src/generic/header.rs +++ b/core/sr-primitives/src/generic/header.rs @@ -84,7 +84,7 @@ impl Encode for Header where } impl traits::Header for Header where - Number: Member + MaybeSerializeDebug + ::rstd::hash::Hash + MaybeDisplay + SimpleArithmetic + Codec + Copy + Into, + Number: Member + MaybeSerializeDebug + ::rstd::hash::Hash + MaybeDisplay + SimpleArithmetic + Codec + Copy + Into + From, Hash: HashT, DigestItem: DigestItemT + Codec, Hash::Output: Default + ::rstd::hash::Hash + Copy + Member + MaybeSerializeDebugButNotDeserialize + MaybeDisplay + SimpleBitOps + Codec, diff --git a/core/sr-primitives/src/traits.rs b/core/sr-primitives/src/traits.rs index 93622e3de92fb..4d02b4ad4adab 100644 --- a/core/sr-primitives/src/traits.rs +++ b/core/sr-primitives/src/traits.rs @@ -575,7 +575,7 @@ impl Mem /// You can also create a `new` one from those fields. pub trait Header: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebugButNotDeserialize + 'static { /// Header number. - type Number: Member + MaybeSerializeDebug + ::rstd::hash::Hash + Copy + MaybeDisplay + SimpleArithmetic + Codec + Into; + type Number: Member + MaybeSerializeDebug + ::rstd::hash::Hash + Copy + MaybeDisplay + SimpleArithmetic + Codec + From; /// Header hash type type Hash: Member + MaybeSerializeDebug + ::rstd::hash::Hash + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]>; /// Hashing algorithm diff --git a/core/transaction-pool/graph/src/base_pool.rs b/core/transaction-pool/graph/src/base_pool.rs index ad434e57d45a2..6ace1d9c741b9 100644 --- a/core/transaction-pool/graph/src/base_pool.rs +++ b/core/transaction-pool/graph/src/base_pool.rs @@ -42,7 +42,7 @@ use crate::ready::ReadyTransactions; /// Successful import result. #[derive(Debug, PartialEq, Eq)] -pub enum Imported { +pub enum Imported { /// Transaction was successfuly imported to Ready queue. Ready { /// Hash of transaction that was successfuly imported. @@ -52,7 +52,7 @@ pub enum Imported { /// Transactions that failed to be promoted from the Future queue and are now discarded. failed: Vec, /// Transactions removed from the Ready pool (replaced). - removed: Vec>>, + removed: Vec>>, }, /// Transaction was successfuly imported to Future queue. Future { @@ -61,7 +61,7 @@ pub enum Imported { } } -impl Imported { +impl Imported { /// Returns the hash of imported transaction. pub fn hash(&self) -> &Hash { use self::Imported::*; @@ -74,19 +74,19 @@ impl Imported { /// Status of pruning the queue. #[derive(Debug)] -pub struct PruneStatus { +pub struct PruneStatus { /// A list of imports that satisfying the tag triggered. - pub promoted: Vec>, + pub promoted: Vec>, /// A list of transactions that failed to be promoted and now are discarded. pub failed: Vec, /// A list of transactions that got pruned from the ready queue. - pub pruned: Vec>>, + pub pruned: Vec>>, } /// Immutable transaction #[cfg_attr(test, derive(Clone))] #[derive(PartialEq, Eq)] -pub struct Transaction { +pub struct Transaction { /// Raw extrinsic representing that transaction. pub data: Extrinsic, /// Number of bytes encoding of the transaction requires. @@ -96,16 +96,17 @@ pub struct Transaction { /// Transaction priority (higher = better) pub priority: Priority, /// At which block the transaction becomes invalid? - pub valid_till: Longevity, + pub valid_till: BlockNumber, /// Tags required by the transaction. pub requires: Vec, /// Tags that this transaction provides. pub provides: Vec, } -impl fmt::Debug for Transaction where +impl fmt::Debug for Transaction where Hash: fmt::Debug, Extrinsic: fmt::Debug, + BlockNumber: fmt::Debug, { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn print_tags(fmt: &mut fmt::Formatter, tags: &[Tag]) -> fmt::Result { @@ -149,9 +150,9 @@ const RECENTLY_PRUNED_TAGS: usize = 2; /// Most likely it is required to revalidate them and recompute set of /// required tags. #[derive(Debug)] -pub struct BasePool { - future: FutureTransactions, - ready: ReadyTransactions, +pub struct BasePool { + future: FutureTransactions, + ready: ReadyTransactions, /// Store recently pruned tags (for last two invocations). /// /// This is used to make sure we don't accidentally put @@ -160,7 +161,7 @@ pub struct BasePool { recently_pruned_index: usize, } -impl Default for BasePool { +impl Default for BasePool { fn default() -> Self { BasePool { future: Default::default(), @@ -171,7 +172,7 @@ impl Default for BasePool { } } -impl BasePool { +impl BasePool { /// Imports transaction to the pool. /// /// The pool consists of two parts: Future and Ready. @@ -181,8 +182,8 @@ impl BasePool, - ) -> error::Result> { + tx: Transaction, + ) -> error::Result> { if self.future.contains(&tx.hash) || self.ready.contains(&tx.hash) { bail!(error::ErrorKind::AlreadyImported(Box::new(tx.hash.clone()))) } @@ -208,7 +209,7 @@ impl BasePool) -> error::Result> { + fn import_to_ready(&mut self, tx: WaitingTransaction) -> error::Result> { let hash = tx.transaction.hash.clone(); let mut promoted = vec![]; let mut failed = vec![]; @@ -271,12 +272,12 @@ impl BasePool impl Iterator>> { + pub fn ready(&self) -> impl Iterator>> { self.ready.get() } /// Returns an iterator over future transactions in the pool. - pub fn futures(&self) -> impl Iterator> { + pub fn futures(&self) -> impl Iterator> { self.future.all() } @@ -284,7 +285,7 @@ impl BasePool Vec>>> { + pub fn by_hash(&self, hashes: &[Hash]) -> Vec>>> { let ready = self.ready.by_hash(hashes); let future = self.future.by_hash(hashes); @@ -300,7 +301,7 @@ impl BasePool Vec>> { + pub fn enforce_limits(&mut self, ready: &Limit, future: &Limit) -> Vec>> { let mut removed = vec![]; while ready.is_exceeded(self.ready.len(), self.ready.bytes()) { @@ -355,7 +356,7 @@ impl BasePool Vec>> { + pub fn remove_invalid(&mut self, hashes: &[Hash]) -> Vec>> { let mut removed = self.ready.remove_invalid(hashes); removed.extend(self.future.remove(hashes)); removed @@ -367,7 +368,7 @@ impl BasePool) -> PruneStatus { + pub fn prune_tags(&mut self, tags: impl IntoIterator) -> PruneStatus { let mut to_import = vec![]; let mut pruned = vec![]; let recently_pruned = &mut self.recently_pruned[self.recently_pruned_index]; diff --git a/core/transaction-pool/graph/src/future.rs b/core/transaction-pool/graph/src/future.rs index 6ca5019e47fad..8322924808bf6 100644 --- a/core/transaction-pool/graph/src/future.rs +++ b/core/transaction-pool/graph/src/future.rs @@ -30,16 +30,16 @@ use sr_primitives::transaction_validity::{ use crate::base_pool::Transaction; /// Transaction with partially satisfied dependencies. -pub struct WaitingTransaction { +pub struct WaitingTransaction { /// Transaction details. - pub transaction: Arc>, + pub transaction: Arc>, /// Tags that are required and have not been satisfied yet by other transactions in the pool. pub missing_tags: HashSet, /// Time of import to the Future Queue. pub imported_at: time::Instant, } -impl fmt::Debug for WaitingTransaction { +impl fmt::Debug for WaitingTransaction { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "WaitingTransaction {{ ")?; write!(fmt, "imported_at: {:?}, ", self.imported_at)?; @@ -56,7 +56,7 @@ impl fmt::Debug for WaitingTransaction Clone for WaitingTransaction { +impl Clone for WaitingTransaction { fn clone(&self) -> Self { WaitingTransaction { transaction: self.transaction.clone(), @@ -66,13 +66,13 @@ impl Clone for WaitingTransaction { } } -impl WaitingTransaction { +impl WaitingTransaction { /// Creates a new `WaitingTransaction`. /// /// Computes the set of missing tags based on the requirements and tags that /// are provided by all transactions in the ready queue. pub fn new( - transaction: Transaction, + transaction: Transaction, provided: &HashMap, recently_pruned: &[HashSet], ) -> Self { @@ -110,14 +110,14 @@ impl WaitingTransaction { /// Contains transactions that are still awaiting for some other transactions that /// could provide a tag that they require. #[derive(Debug)] -pub struct FutureTransactions { +pub struct FutureTransactions { /// tags that are not yet provided by any transaction and we await for them wanted_tags: HashMap>, /// Transactions waiting for a particular other transaction - waiting: HashMap>, + waiting: HashMap>, } -impl Default for FutureTransactions { +impl Default for FutureTransactions { fn default() -> Self { FutureTransactions { wanted_tags: Default::default(), @@ -133,14 +133,14 @@ every hash from `wanted_tags` is always present in `waiting`; qed #"; -impl FutureTransactions { +impl FutureTransactions { /// Import transaction to Future queue. /// /// Only transactions that don't have all their tags satisfied should occupy /// the Future queue. /// As soon as required tags are provided by some other transactions that are ready /// we should remove the transactions from here and move them to the Ready queue. - pub fn import(&mut self, tx: WaitingTransaction) { + pub fn import(&mut self, tx: WaitingTransaction) { assert!(!tx.is_ready(), "Transaction is ready."); assert!(!self.waiting.contains_key(&tx.transaction.hash), "Transaction is already imported."); @@ -160,7 +160,7 @@ impl FutureTransactions { } /// Returns a list of known transactions - pub fn by_hash(&self, hashes: &[Hash]) -> Vec>>> { + pub fn by_hash(&self, hashes: &[Hash]) -> Vec>>> { hashes.iter().map(|h| self.waiting.get(h).map(|x| x.transaction.clone())).collect() } @@ -168,7 +168,7 @@ impl FutureTransactions { /// /// Returns (and removes) transactions that became ready after their last tag got /// satisfied and now we can remove them from Future and move to Ready queue. - pub fn satisfy_tags>(&mut self, tags: impl IntoIterator) -> Vec> { + pub fn satisfy_tags>(&mut self, tags: impl IntoIterator) -> Vec> { let mut became_ready = vec![]; for tag in tags { @@ -194,7 +194,7 @@ impl FutureTransactions { /// Removes transactions for given list of hashes. /// /// Returns a list of actually removed transactions. - pub fn remove(&mut self, hashes: &[Hash]) -> Vec>> { + pub fn remove(&mut self, hashes: &[Hash]) -> Vec>> { let mut removed = vec![]; for hash in hashes { if let Some(waiting_tx) = self.waiting.remove(hash) { @@ -216,14 +216,14 @@ impl FutureTransactions { } /// Fold a list of future transactions to compute a single value. - pub fn fold, &WaitingTransaction) -> Option>(&mut self, f: F) -> Option { + pub fn fold, &WaitingTransaction) -> Option>(&mut self, f: F) -> Option { self.waiting .values() .fold(None, f) } /// Returns iterator over all future transactions - pub fn all(&self) -> impl Iterator> { + pub fn all(&self) -> impl Iterator> { self.waiting.values().map(|waiting| &*waiting.transaction) } diff --git a/core/transaction-pool/graph/src/pool.rs b/core/transaction-pool/graph/src/pool.rs index b33221084313c..3d32edb8649d2 100644 --- a/core/transaction-pool/graph/src/pool.rs +++ b/core/transaction-pool/graph/src/pool.rs @@ -34,7 +34,7 @@ use futures::sync::mpsc; use parking_lot::{Mutex, RwLock}; use sr_primitives::{ generic::BlockId, - traits::{self, As}, + traits::{self, As, Saturating}, transaction_validity::{TransactionValidity, TransactionTag as Tag}, }; @@ -52,7 +52,7 @@ pub type ExtrinsicFor = <::Block as traits::Block>::Extrinsic; /// Block number type for the ChainApi pub type NumberFor = traits::NumberFor<::Block>; /// A type of transaction stored in the pool -pub type TransactionFor = Arc, ExtrinsicFor>>; +pub type TransactionFor = Arc, ExtrinsicFor, NumberFor>>; /// Concrete extrinsic validation and query logic. pub trait ChainApi: Send + Sync { @@ -108,6 +108,7 @@ pub struct Pool { pool: RwLock, ExtrinsicFor, + NumberFor, >>, import_notification_sinks: Mutex>>, rotator: PoolRotator>, @@ -138,7 +139,7 @@ impl Pool { priority, requires, provides, - valid_till: block_number.into().saturating_add(longevity), + valid_till: block_number.saturating_add(longevity.into()), }) }, TransactionValidity::Invalid(e) => { @@ -336,8 +337,7 @@ impl Pool { /// See `prune_tags` ifyou want this. pub fn clear_stale(&self, at: &BlockId) -> Result<(), B::Error> { let block_number = self.api.block_id_to_number(at)? - .ok_or_else(|| error::ErrorKind::Msg(format!("Invalid block id: {:?}", at)).into())? - .as_(); + .ok_or_else(|| error::ErrorKind::Msg(format!("Invalid block id: {:?}", at)).into())?; let now = time::Instant::now(); let to_remove = { self.ready() @@ -424,9 +424,9 @@ impl Pool { } } -fn fire_events( +fn fire_events( listener: &mut Listener, - imported: &base::Imported, + imported: &base::Imported, ) where H: hash::Hash + Eq + traits::Member + Serialize, H2: Clone, diff --git a/core/transaction-pool/graph/src/ready.rs b/core/transaction-pool/graph/src/ready.rs index befb1b60ccc2d..bb328b82aa977 100644 --- a/core/transaction-pool/graph/src/ready.rs +++ b/core/transaction-pool/graph/src/ready.rs @@ -38,14 +38,14 @@ use crate::base_pool::Transaction; /// /// Should be cheap to clone. #[derive(Debug)] -pub struct TransactionRef { +pub struct TransactionRef { /// The actual transaction data. - pub transaction: Arc>, + pub transaction: Arc>, /// Unique id when transaction was inserted into the pool. pub insertion_id: u64, } -impl Clone for TransactionRef { +impl Clone for TransactionRef { fn clone(&self) -> Self { TransactionRef { transaction: self.transaction.clone(), @@ -54,7 +54,7 @@ impl Clone for TransactionRef { } } -impl Ord for TransactionRef { +impl Ord for TransactionRef { fn cmp(&self, other: &Self) -> cmp::Ordering { self.transaction.priority.cmp(&other.transaction.priority) .then(other.transaction.valid_till.cmp(&self.transaction.valid_till)) @@ -62,23 +62,23 @@ impl Ord for TransactionRef { } } -impl PartialOrd for TransactionRef { +impl PartialOrd for TransactionRef { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } -impl PartialEq for TransactionRef { +impl PartialEq for TransactionRef { fn eq(&self, other: &Self) -> bool { self.cmp(other) == cmp::Ordering::Equal } } -impl Eq for TransactionRef {} +impl Eq for TransactionRef {} #[derive(Debug)] -pub struct ReadyTx { +pub struct ReadyTx { /// A reference to a transaction - pub transaction: TransactionRef, + pub transaction: TransactionRef, /// A list of transactions that get unlocked by this one pub unlocks: Vec, /// How many required tags are provided inherently @@ -88,7 +88,7 @@ pub struct ReadyTx { pub requires_offset: usize, } -impl Clone for ReadyTx { +impl Clone for ReadyTx { fn clone(&self) -> Self { ReadyTx { transaction: self.transaction.clone(), @@ -106,18 +106,18 @@ qed "#; #[derive(Debug)] -pub struct ReadyTransactions { +pub struct ReadyTransactions { /// Insertion id insertion_id: u64, /// tags that are provided by Ready transactions provided_tags: HashMap, /// Transactions that are ready (i.e. don't have any requirements external to the pool) - ready: Arc>>>, + ready: Arc>>>, /// Best transactions that are ready to be included to the block without any other previous transaction. - best: BTreeSet>, + best: BTreeSet>, } -impl Default for ReadyTransactions { +impl Default for ReadyTransactions { fn default() -> Self { ReadyTransactions { insertion_id: Default::default(), @@ -128,7 +128,7 @@ impl Default for ReadyTransactions { } } -impl ReadyTransactions { +impl ReadyTransactions { /// Borrows a map of tags that are provided by transactions in this queue. pub fn provided_tags(&self) -> &HashMap { &self.provided_tags @@ -145,7 +145,7 @@ impl ReadyTransactions { /// - transactions that are valid for a shorter time go first /// 4. Lastly we sort by the time in the queue /// - transactions that are longer in the queue go first - pub fn get(&self) -> impl Iterator>> { + pub fn get(&self) -> impl Iterator>> { BestIterator { all: self.ready.clone(), best: self.best.clone(), @@ -160,8 +160,8 @@ impl ReadyTransactions { /// Returns transactions that were replaced by the one imported. pub fn import( &mut self, - tx: WaitingTransaction, - ) -> error::Result>>> { + tx: WaitingTransaction, + ) -> error::Result>>> { assert!(tx.is_ready(), "Only ready transactions can be imported."); assert!(!self.ready.read().contains_key(&tx.transaction.hash), "Transaction is already imported."); @@ -211,7 +211,7 @@ impl ReadyTransactions { } /// Fold a list of ready transactions to compute a single value. - pub fn fold, &ReadyTx) -> Option>(&mut self, f: F) -> Option { + pub fn fold, &ReadyTx) -> Option>(&mut self, f: F) -> Option { self.ready .read() .values() @@ -224,7 +224,7 @@ impl ReadyTransactions { } /// Retrieve transaction by hash - pub fn by_hash(&self, hashes: &[Hash]) -> Vec>>> { + pub fn by_hash(&self, hashes: &[Hash]) -> Vec>>> { let ready = self.ready.read(); hashes.iter().map(|hash| { ready.get(hash).map(|x| x.transaction.transaction.clone()) @@ -236,7 +236,7 @@ impl ReadyTransactions { /// NOTE removing a transaction will also cause a removal of all transactions that depend on that one /// (i.e. the entire subgraph that this transaction is a start of will be removed). /// All removed transactions are returned. - pub fn remove_invalid(&mut self, hashes: &[Hash]) -> Vec>> { + pub fn remove_invalid(&mut self, hashes: &[Hash]) -> Vec>> { let mut removed = vec![]; let mut to_remove = hashes.iter().cloned().collect::>(); @@ -279,7 +279,7 @@ impl ReadyTransactions { /// All transactions that lead to a transaction, which provides this tag /// are going to be removed from the queue, but no other transactions are touched - /// i.e. all other subgraphs starting from given tag are still considered valid & ready. - pub fn prune_tags(&mut self, tag: Tag) -> Vec>> { + pub fn prune_tags(&mut self, tag: Tag) -> Vec>> { let mut removed = vec![]; let mut to_remove = vec![tag]; @@ -352,7 +352,7 @@ impl ReadyTransactions { /// We remove/replace old transactions in case they have lower priority. /// /// In case replacement is succesful returns a list of removed transactions. - fn replace_previous(&mut self, tx: &Transaction) -> error::Result>>> { + fn replace_previous(&mut self, tx: &Transaction) -> error::Result>>> { let mut to_remove = { // check if we are replacing a transaction let replace_hashes = tx.provides @@ -421,16 +421,16 @@ impl ReadyTransactions { } } -pub struct BestIterator { - all: Arc>>>, - awaiting: HashMap)>, - best: BTreeSet>, +pub struct BestIterator { + all: Arc>>>, + awaiting: HashMap)>, + best: BTreeSet>, } -impl BestIterator { +impl BestIterator { /// Depending on number of satisfied requirements insert given ref /// either to awaiting set or to best set. - fn best_or_awaiting(&mut self, satisfied: usize, tx_ref: TransactionRef) { + fn best_or_awaiting(&mut self, satisfied: usize, tx_ref: TransactionRef) { if satisfied == tx_ref.transaction.requires.len() { // If we have satisfied all deps insert to best self.best.insert(tx_ref); @@ -442,8 +442,8 @@ impl BestIterator { } } -impl Iterator for BestIterator { - type Item = Arc>; +impl Iterator for BestIterator { + type Item = Arc>; fn next(&mut self) -> Option { loop { diff --git a/core/transaction-pool/graph/src/rotator.rs b/core/transaction-pool/graph/src/rotator.rs index 2ca51ef74e880..92c6469b65ff5 100644 --- a/core/transaction-pool/graph/src/rotator.rs +++ b/core/transaction-pool/graph/src/rotator.rs @@ -79,7 +79,7 @@ impl PoolRotator { /// Bans extrinsic if it's stale. /// /// Returns `true` if extrinsic is stale and got banned. - pub fn ban_if_stale(&self, now: &Instant, current_block: u64, xt: &Transaction) -> bool { + pub fn ban_if_stale(&self, now: &Instant, current_block: BlockNumber, xt: &Transaction) -> bool { if xt.valid_till > current_block { return false; } diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index c410afd9ce6a7..8302c5f5e5457 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -135,7 +135,7 @@ pub trait Trait: 'static + Eq + Clone { /// The block number type used by the runtime. type BlockNumber: Parameter + Member + MaybeSerializeDebug + MaybeDisplay + SimpleArithmetic + Default + Bounded + Copy - + rstd::hash::Hash; + + rstd::hash::Hash + From; /// The output of the `Hashing` function. type Hash: From 33e435ac709b8fbb36d4df5c0268f94147c567e4 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Thu, 18 Apr 2019 12:26:17 +0200 Subject: [PATCH 3/4] WIP --- core/client/src/cht.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/client/src/cht.rs b/core/client/src/cht.rs index 92871e7614e4d..13db1c67ebe81 100644 --- a/core/client/src/cht.rs +++ b/core/client/src/cht.rs @@ -276,7 +276,7 @@ pub fn block_to_cht_number(cht_size: u64, block_num: N) -> } /// Convert header number into CHT key. -pub fn encode_cht_key>(number: N) -> Vec { +pub fn encode_cht_key>(number: N) -> Vec { let number: u64 = number.as_(); vec![ (number >> 56) as u8, From aed1e24034793033e77bdf946441e382c557f44b Mon Sep 17 00:00:00 2001 From: thiolliere Date: Thu, 18 Apr 2019 14:44:24 +0200 Subject: [PATCH 4/4] WIP --- core/client/src/cht.rs | 53 ++++++++++--------- core/client/src/in_mem.rs | 2 +- core/state-machine/src/changes_trie/mod.rs | 4 +- .../state-machine/src/changes_trie/storage.rs | 18 +++---- core/state-machine/src/testing.rs | 24 ++++----- 5 files changed, 53 insertions(+), 48 deletions(-) diff --git a/core/client/src/cht.rs b/core/client/src/cht.rs index 13db1c67ebe81..7ba070ff701f7 100644 --- a/core/client/src/cht.rs +++ b/core/client/src/cht.rs @@ -44,7 +44,7 @@ pub const SIZE: u64 = 2048; /// Returns Some(cht_number) if CHT is need to be built when the block with given number is canonized. pub fn is_build_required(cht_size: u64, block_num: N) -> Option where - N: Clone + SimpleArithmetic, + N: Clone + SimpleArithmetic + From, { let block_cht_num = block_to_cht_number(cht_size, block_num.clone())?; let two = N::one() + N::one(); @@ -184,7 +184,7 @@ pub fn for_each_cht_group( let mut current_cht_num = None; let mut current_cht_blocks = Vec::new(); for block in blocks { - let new_cht_num = match block_to_cht_number(cht_size, block.as_()) { + let new_cht_num = match block_to_cht_number(cht_size, block) { Some(new_cht_num) => new_cht_num, None => return Err(ClientError::Backend(format!( "Cannot compute CHT root for the block #{}", block)).into() @@ -199,7 +199,7 @@ pub fn for_each_cht_group( functor_param = functor( functor_param, - As::sa(current_cht_num), + current_cht_num, ::std::mem::replace(&mut current_cht_blocks, Vec::new()), )?; } @@ -211,7 +211,7 @@ pub fn for_each_cht_group( if let Some(current_cht_num) = current_cht_num { functor( functor_param, - As::sa(current_cht_num), + current_cht_num, ::std::mem::replace(&mut current_cht_blocks, Vec::new()), )?; } @@ -234,7 +234,8 @@ fn build_pairs( let mut hash_number = start_num; for hash in hashes.into_iter().take(cht_size as usize) { let hash = hash?.ok_or_else(|| ClientError::from( - ClientError::MissingHashRequiredForCHT(cht_num.as_(), hash_number.as_()) + // TODO TODO: make error generic + ClientError::MissingHashRequiredForCHT(0, 0)//cht_num, hash_number) ))?; pairs.push(( encode_cht_key(hash_number).to_vec(), @@ -246,7 +247,8 @@ fn build_pairs( if pairs.len() as u64 == cht_size { Ok(pairs) } else { - Err(ClientError::MissingHashRequiredForCHT(cht_num.as_(), hash_number.as_())) + // TODO TODO: make error generic + Err(ClientError::MissingHashRequiredForCHT(0, 0))//cht_num.as_(), hash_number.as_())) } } @@ -256,38 +258,41 @@ fn build_pairs( /// More generally: CHT N includes block (1 + N*SIZE)...((N+1)*SIZE). /// This is because the genesis hash is assumed to be known /// and including it would be redundant. -pub fn start_number(cht_size: u64, cht_num: N) -> N { - (cht_num * As::sa(cht_size)) + N::one() +pub fn start_number>(cht_size: u64, cht_num: N) -> N { + cht_num * cht_size.into() + N::one() } /// Get the ending block of a given CHT. -pub fn end_number(cht_size: u64, cht_num: N) -> N { - (cht_num + N::one()) * As::sa(cht_size) +// TODO TODO: we can convert cht_size to balance or overwise bound Mul that could make sense +// actually but at the end probably both would be implmeented same way +pub fn end_number>(cht_size: u64, cht_num: N) -> N { + (cht_num + N::one()) * cht_size.into() } /// Convert a block number to a CHT number. /// Returns `None` for `block_num` == 0, `Some` otherwise. -pub fn block_to_cht_number(cht_size: u64, block_num: N) -> Option { +pub fn block_to_cht_number>(cht_size: u64, block_num: N) -> Option { if block_num == N::zero() { None } else { - Some((block_num - N::one()) / As::sa(cht_size)) + Some((block_num - N::one()) / cht_size.into()) } } /// Convert header number into CHT key. -pub fn encode_cht_key>(number: N) -> Vec { - let number: u64 = number.as_(); - vec![ - (number >> 56) as u8, - ((number >> 48) & 0xff) as u8, - ((number >> 40) & 0xff) as u8, - ((number >> 32) & 0xff) as u8, - ((number >> 24) & 0xff) as u8, - ((number >> 16) & 0xff) as u8, - ((number >> 8) & 0xff) as u8, - (number & 0xff) as u8 - ] +pub fn encode_cht_key(number: N) -> Vec { + unimplemented!(); + // let number: u64 = number.as_(); + // vec![ + // (number >> 56) as u8, + // ((number >> 48) & 0xff) as u8, + // ((number >> 40) & 0xff) as u8, + // ((number >> 32) & 0xff) as u8, + // ((number >> 24) & 0xff) as u8, + // ((number >> 16) & 0xff) as u8, + // ((number >> 8) & 0xff) as u8, + // (number & 0xff) as u8 + // ] } /// Convert header hash into CHT value. diff --git a/core/client/src/in_mem.rs b/core/client/src/in_mem.rs index 5d436b0c893c6..2b65f21acbbb2 100644 --- a/core/client/src/in_mem.rs +++ b/core/client/src/in_mem.rs @@ -625,7 +625,7 @@ where if let Some(changes_trie_root) = changes_trie_root { if let Some(changes_trie_update) = operation.changes_trie_update { let changes_trie_root: H::Out = changes_trie_root.into(); - self.changes_trie_storage.0.insert(header.number().as_(), changes_trie_root, changes_trie_update); + self.changes_trie_storage.0.insert(header.number(), changes_trie_root, changes_trie_update); } } diff --git a/core/state-machine/src/changes_trie/mod.rs b/core/state-machine/src/changes_trie/mod.rs index c29131cc0c5d8..7b04df9b5e46c 100644 --- a/core/state-machine/src/changes_trie/mod.rs +++ b/core/state-machine/src/changes_trie/mod.rs @@ -68,10 +68,10 @@ pub struct AnchorBlockId { } /// Changes trie storage. Provides access to trie roots and trie nodes. -pub trait RootsStorage: Send + Sync { +pub trait RootsStorage: Send + Sync { /// Get changes trie root for the block with given number which is an ancestor (or the block /// itself) of the anchor_block (i.e. anchor_block.number >= block). - fn root(&self, anchor: &AnchorBlockId, block: u64) -> Result, String>; + fn root(&self, anchor: &AnchorBlockId, block: BlockNumber) -> Result, String>; } /// Changes trie storage. Provides access to trie roots and trie nodes. diff --git a/core/state-machine/src/changes_trie/storage.rs b/core/state-machine/src/changes_trie/storage.rs index decc332c1a618..463ff79f2c517 100644 --- a/core/state-machine/src/changes_trie/storage.rs +++ b/core/state-machine/src/changes_trie/storage.rs @@ -33,8 +33,8 @@ use crate::backend::insert_into_memory_db; use crate::changes_trie::input::InputPair; /// In-memory implementation of changes trie storage. -pub struct InMemoryStorage where H::Out: HeapSizeOf { - data: RwLock>, +pub struct InMemoryStorage where H::Out: HeapSizeOf { + data: RwLock>, } /// Adapter for using changes trie storage as a TrieBackendEssence' storage. @@ -43,12 +43,12 @@ pub struct TrieBackendAdapter<'a, H: Hasher, S: 'a + Storage> { _hasher: ::std::marker::PhantomData, } -struct InMemoryStorageData where H::Out: HeapSizeOf { - roots: HashMap, +struct InMemoryStorageData where H::Out: HeapSizeOf { + roots: HashMap, mdb: MemoryDB, } -impl InMemoryStorage where H::Out: HeapSizeOf { +impl InMemoryStorage where H::Out: HeapSizeOf { /// Create the storage from given in-memory database. pub fn with_db(mdb: MemoryDB) -> Self { Self { @@ -102,20 +102,20 @@ impl InMemoryStorage where H::Out: HeapSizeOf { } /// Insert changes trie for given block. - pub fn insert(&self, block: u64, changes_trie_root: H::Out, trie: MemoryDB) { + pub fn insert(&self, block: BlockNumber, changes_trie_root: H::Out, trie: MemoryDB) { let mut data = self.data.write(); data.roots.insert(block, changes_trie_root); data.mdb.consolidate(trie); } } -impl RootsStorage for InMemoryStorage where H::Out: HeapSizeOf { - fn root(&self, _anchor_block: &AnchorBlockId, block: u64) -> Result, String> { +impl RootsStorage for InMemoryStorage where H::Out: HeapSizeOf { + fn root(&self, _anchor_block: &AnchorBlockId, block: BlockNumber) -> Result, String> { Ok(self.data.read().roots.get(&block).cloned()) } } -impl Storage for InMemoryStorage where H::Out: HeapSizeOf { +impl Storage for InMemoryStorage where H::Out: HeapSizeOf { fn get(&self, key: &H::Out, prefix: &[u8]) -> Result, String> { MemoryDB::::get(&self.data.read().mdb, key, prefix) } diff --git a/core/state-machine/src/testing.rs b/core/state-machine/src/testing.rs index 6bbfc27667652..935030dd0b075 100644 --- a/core/state-machine/src/testing.rs +++ b/core/state-machine/src/testing.rs @@ -28,14 +28,14 @@ use parity_codec::Encode; use super::{Externalities, OverlayedChanges}; /// Simple HashMap-based Externalities impl. -pub struct TestExternalities where H::Out: HeapSizeOf { +pub struct TestExternalities where H::Out: HeapSizeOf { inner: HashMap, Vec>, - changes_trie_storage: ChangesTrieInMemoryStorage, + changes_trie_storage: ChangesTrieInMemoryStorage, changes: OverlayedChanges, code: Option>, } -impl TestExternalities where H::Out: HeapSizeOf { +impl TestExternalities where H::Out: HeapSizeOf { /// Create a new instance of `TestExternalities` pub fn new(inner: HashMap, Vec>) -> Self { Self::new_with_code(&[], inner) @@ -66,19 +66,19 @@ impl TestExternalities where H::Out: HeapSizeOf { } } -impl ::std::fmt::Debug for TestExternalities where H::Out: HeapSizeOf { +impl ::std::fmt::Debug for TestExternalities where H::Out: HeapSizeOf { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { write!(f, "{:?}", self.inner) } } -impl PartialEq for TestExternalities where H::Out: HeapSizeOf { - fn eq(&self, other: &TestExternalities) -> bool { +impl PartialEq for TestExternalities where H::Out: HeapSizeOf { + fn eq(&self, other: &TestExternalities) -> bool { self.inner.eq(&other.inner) } } -impl FromIterator<(Vec, Vec)> for TestExternalities where H::Out: HeapSizeOf { +impl FromIterator<(Vec, Vec)> for TestExternalities where H::Out: HeapSizeOf { fn from_iter, Vec)>>(iter: I) -> Self { let mut t = Self::new(Default::default()); t.inner.extend(iter); @@ -86,17 +86,17 @@ impl FromIterator<(Vec, Vec)> for TestExternalities where } } -impl Default for TestExternalities where H::Out: HeapSizeOf { +impl Default for TestExternalities where H::Out: HeapSizeOf { fn default() -> Self { Self::new(Default::default()) } } -impl From> for HashMap, Vec> where H::Out: HeapSizeOf { - fn from(tex: TestExternalities) -> Self { +impl From> for HashMap, Vec> where H::Out: HeapSizeOf { + fn from(tex: TestExternalities) -> Self { tex.inner.into() } } -impl From< HashMap, Vec> > for TestExternalities where H::Out: HeapSizeOf { +impl From< HashMap, Vec> > for TestExternalities where H::Out: HeapSizeOf { fn from(hashmap: HashMap, Vec>) -> Self { TestExternalities { inner: hashmap, @@ -110,7 +110,7 @@ impl From< HashMap, Vec> > for TestExternalities where // TODO child test primitives are currently limited to `changes` (for non child the way // things are defined seems utterly odd to (put changes in changes but never make them // available for read through inner) -impl Externalities for TestExternalities where H::Out: Ord + HeapSizeOf { +impl Externalities for TestExternalities where H::Out: Ord + HeapSizeOf { fn storage(&self, key: &[u8]) -> Option> { match key { CODE => self.code.clone(),