Merge txpool-runtime-api with txpool-api (#4320)

* Remove transaction-pool-runtime-api

* Merge runtime-api with transaction-pool.
This commit is contained in:
Tomasz Drwięga
2019-12-06 17:24:17 +01:00
committed by Bastian Köcher
parent 70db5da6c4
commit 3805393a13
22 changed files with 386 additions and 372 deletions
+3 -13
View File
@@ -3146,7 +3146,7 @@ dependencies = [
"sp-session 2.0.0",
"sp-staking 2.0.0",
"sp-std 2.0.0",
"sp-transaction-pool-runtime-api 2.0.0",
"sp-transaction-pool-api 2.0.0",
"sp-version 2.0.0",
"substrate-wasm-builder-runner 1.0.4",
]
@@ -3213,7 +3213,7 @@ dependencies = [
"sp-runtime 2.0.0",
"sp-session 2.0.0",
"sp-std 2.0.0",
"sp-transaction-pool-runtime-api 2.0.0",
"sp-transaction-pool-api 2.0.0",
"sp-version 2.0.0",
"substrate-wasm-builder-runner 1.0.4",
]
@@ -5484,7 +5484,6 @@ dependencies = [
"sp-runtime 2.0.0",
"sp-session 2.0.0",
"sp-transaction-pool-api 2.0.0",
"sp-transaction-pool-runtime-api 2.0.0",
"substrate-test-runtime-client 2.0.0",
"sysinfo 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
"target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -5597,7 +5596,6 @@ dependencies = [
"sp-keyring 2.0.0",
"sp-runtime 2.0.0",
"sp-transaction-pool-api 2.0.0",
"sp-transaction-pool-runtime-api 2.0.0",
"substrate-test-runtime-client 2.0.0",
]
@@ -6374,14 +6372,6 @@ dependencies = [
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
"sp-core 2.0.0",
"sp-runtime 2.0.0",
]
[[package]]
name = "sp-transaction-pool-runtime-api"
version = "2.0.0"
dependencies = [
"sp-api 2.0.0",
"sp-core 2.0.0",
"sp-runtime 2.0.0",
@@ -6643,7 +6633,7 @@ dependencies = [
"sp-session 2.0.0",
"sp-state-machine 2.0.0",
"sp-std 2.0.0",
"sp-transaction-pool-runtime-api 2.0.0",
"sp-transaction-pool-api 2.0.0",
"sp-trie 2.0.0",
"sp-version 2.0.0",
"substrate-test-runtime-client 2.0.0",
-1
View File
@@ -127,7 +127,6 @@ members = [
"primitives/state-machine",
"primitives/timestamp",
"primitives/transaction-pool",
"primitives/transaction-pool/runtime-api",
"primitives/trie",
"primitives/wasm-interface",
"test/utils/chain-spec-builder",
@@ -29,7 +29,7 @@ support = { package = "frame-support", path = "../../../frame/support", default-
system = { package = "frame-system", path = "../../../frame/system", default-features = false }
timestamp = { package = "pallet-timestamp", path = "../../../frame/timestamp", default-features = false }
transaction-payment = { package = "pallet-transaction-payment", path = "../../../frame/transaction-payment", default-features = false }
txpool-runtime-api = { package = "sp-transaction-pool-runtime-api", path = "../../../primitives/transaction-pool/runtime-api", default-features = false }
sp-transaction-pool = { package = "sp-transaction-pool-api", path = "../../../primitives/transaction-pool", default-features = false }
version = { package = "sp-version", path = "../../../primitives/sr-version", default-features = false }
[build-dependencies]
@@ -62,6 +62,6 @@ std = [
"system/std",
"timestamp/std",
"transaction-payment/std",
"txpool-runtime-api/std",
"sp-transaction-pool/std",
"version/std",
]
@@ -328,7 +328,7 @@ impl_runtime_apis! {
}
}
impl txpool_runtime_api::TaggedTransactionQueue<Block> for Runtime {
impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
fn validate_transaction(tx: <Block as BlockT>::Extrinsic) -> TransactionValidity {
Executive::validate_transaction(tx)
}
+2 -2
View File
@@ -27,7 +27,7 @@ sp-runtime = { path = "../../../primitives/sr-primitives", default-features = fa
sp-staking = { path = "../../../primitives/sr-staking-primitives", default-features = false }
sp-keyring = { path = "../../../primitives/keyring", optional = true }
sp-session = { path = "../../../primitives/session", default-features = false }
txpool-runtime-api = { package = "sp-transaction-pool-runtime-api", path = "../../../primitives/transaction-pool/runtime-api", default-features = false }
sp-transaction-pool = { package = "sp-transaction-pool-api", path = "../../../primitives/transaction-pool", default-features = false }
version = { package = "sp-version", path = "../../../primitives/sr-version", default-features = false }
# frame dependencies
@@ -116,7 +116,7 @@ std = [
"transaction-payment-rpc-runtime-api/std",
"transaction-payment/std",
"treasury/std",
"txpool-runtime-api/std",
"sp-transaction-pool/std",
"utility/std",
"version/std",
]
+1 -1
View File
@@ -613,7 +613,7 @@ impl_runtime_apis! {
}
}
impl txpool_runtime_api::TaggedTransactionQueue<Block> for Runtime {
impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
fn validate_transaction(tx: <Block as BlockT>::Extrinsic) -> TransactionValidity {
Executive::validate_transaction(tx)
}
+1 -1
View File
@@ -39,7 +39,7 @@ use sp_api::ConstructRuntimeApi;
use sp_runtime::{generic, traits::{self, ProvideRuntimeApi}};
use txpool_api::{
TransactionPool, InPoolTransaction, TransactionStatus,
BlockHash, TxHash, TransactionFor, IntoPoolError,
BlockHash, TxHash, TransactionFor, error::IntoPoolError,
};
use session::SessionKeys;
+1 -2
View File
@@ -41,12 +41,11 @@ chain-spec = { package = "sc-chain-spec", path = "../chain-spec" }
client-api = { package = "sc-client-api", path = "../api" }
client = { package = "sc-client", path = "../" }
sp-api = { path = "../../primitives/sr-api" }
txpool-runtime-api = { package = "sp-transaction-pool-runtime-api", path = "../../primitives/transaction-pool/runtime-api" }
client_db = { package = "sc-client-db", path = "../db" }
codec = { package = "parity-scale-codec", version = "1.0.0" }
sc-executor = { path = "../executor" }
txpool = { package = "sc-transaction-pool", path = "../transaction-pool" }
txpool-api = { package = "sp-transaction-pool-api", path = "../../primitives/transaction-pool" }
sp-transaction-pool = { package = "sp-transaction-pool-api", path = "../../primitives/transaction-pool" }
rpc-servers = { package = "sc-rpc-server", path = "../rpc-servers" }
rpc = { package = "sc-rpc", path = "../rpc" }
tel = { package = "sc-telemetry", path = "../telemetry" }
+2 -2
View File
@@ -52,7 +52,7 @@ use std::{
};
use sysinfo::{get_current_pid, ProcessExt, System, SystemExt};
use tel::{telemetry, SUBSTRATE_INFO};
use txpool_api::{TransactionPool, TransactionPoolMaintainer};
use sp_transaction_pool::{TransactionPool, TransactionPoolMaintainer};
use sp_blockchain;
use grafana_data_source::{self, record_metrics};
@@ -714,7 +714,7 @@ ServiceBuilder<
<Client<TBackend, TExec, TBl, TRtApi> as ProvideRuntimeApi>::Api:
sp_api::Metadata<TBl> +
offchain::OffchainWorkerApi<TBl> +
txpool_runtime_api::TaggedTransactionQueue<TBl> +
sp_transaction_pool::runtime_api::TaggedTransactionQueue<TBl> +
session::SessionKeys<TBl> +
sp_api::ApiExt<TBl, Error = sp_blockchain::Error>,
TBl: BlockT<Hash = <Blake2Hasher as Hasher>::Out>,
+4 -4
View File
@@ -56,7 +56,7 @@ pub use self::error::Error;
pub use self::builder::{ServiceBuilder, ServiceBuilderCommand};
pub use config::{Configuration, Roles, PruningMode};
pub use chain_spec::{ChainSpec, Properties, RuntimeGenesis, Extension as ChainSpecExtension};
pub use txpool_api::{TransactionPool, TransactionPoolMaintainer, InPoolTransaction, IntoPoolError};
pub use sp_transaction_pool::{TransactionPool, TransactionPoolMaintainer, InPoolTransaction, error::IntoPoolError};
pub use txpool::txpool::Options as TransactionPoolOptions;
pub use client::FinalityNotifications;
pub use rpc::Metadata as RpcMetadata;
@@ -599,7 +599,7 @@ where
Pool: TransactionPool<Block=B, Hash=H, Error=E>,
B: BlockT,
H: std::hash::Hash + Eq + sp_runtime::traits::Member + sp_runtime::traits::MaybeSerialize,
E: IntoPoolError + From<txpool_api::error::Error>,
E: IntoPoolError + From<sp_transaction_pool::error::Error>,
{
pool.ready()
.filter(|t| t.is_propagateable())
@@ -618,7 +618,7 @@ where
Pool: 'static + TransactionPool<Block=B, Hash=H, Error=E>,
B: BlockT,
H: std::hash::Hash + Eq + sp_runtime::traits::Member + sp_runtime::traits::MaybeSerialize,
E: 'static + IntoPoolError + From<txpool_api::error::Error>,
E: 'static + IntoPoolError + From<sp_transaction_pool::error::Error>,
{
fn transactions(&self) -> Vec<(H, <B as BlockT>::Extrinsic)> {
transactions_to_propagate(&*self.pool)
@@ -651,7 +651,7 @@ where
match import_result {
Ok(_) => report_handle.report_peer(who, reputation_change_good),
Err(e) => match e.into_pool_error() {
Ok(txpool_api::error::Error::AlreadyImported(_)) => (),
Ok(sp_transaction_pool::error::Error::AlreadyImported(_)) => (),
Ok(e) => {
report_handle.report_peer(who, reputation_change_bad);
debug!("Error adding transaction to the pool: {:?}", e)
@@ -15,7 +15,6 @@ sp-api = { path = "../../primitives/sr-api" }
sp-runtime = { path = "../../primitives/sr-primitives" }
txpool = { package = "sc-transaction-graph", path = "./graph" }
txpool-api = { package = "sp-transaction-pool-api", path = "../../primitives/transaction-pool" }
txpool-runtime-api = { package = "sp-transaction-pool-runtime-api", path = "../../primitives/transaction-pool/runtime-api" }
client-api = { package = "sc-client-api", path = "../api" }
sp-blockchain = { path = "../../primitives/blockchain" }
+1 -1
View File
@@ -26,7 +26,7 @@ use client_api::{
};
use primitives::{H256, Blake2Hasher, Hasher};
use sp_runtime::{generic::BlockId, traits::{self, Block as BlockT}, transaction_validity::TransactionValidity};
use txpool_runtime_api::TaggedTransactionQueue;
use txpool_api::runtime_api::TaggedTransactionQueue;
use crate::error::{self, Error};
@@ -16,6 +16,8 @@
//! Transaction pool error.
use txpool_api::error::Error as TxPoolError;
/// Transaction pool result.
pub type Result<T> = std::result::Result<T, Error>;
@@ -23,7 +25,7 @@ pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, derive_more::Display, derive_more::From)]
pub enum Error {
/// Pool error.
Pool(txpool_api::error::Error),
Pool(TxPoolError),
/// Blockchain error.
Blockchain(sp_blockchain::Error),
/// Error while converting a `BlockId`.
@@ -45,8 +47,8 @@ impl std::error::Error for Error {
}
}
impl txpool_api::IntoPoolError for Error {
fn into_pool_error(self) -> std::result::Result<txpool_api::error::Error, Self> {
impl txpool_api::error::IntoPoolError for Error {
fn into_pool_error(self) -> std::result::Result<TxPoolError, Self> {
match self {
Error::Pool(e) => Ok(e),
e => Err(e),
@@ -37,7 +37,7 @@ use sp_runtime::{
};
use sp_blockchain::HeaderBackend;
use txpool_api::TransactionPoolMaintainer;
use txpool_runtime_api::TaggedTransactionQueue;
use txpool_api::runtime_api::TaggedTransactionQueue;
use txpool::{self, ChainApi};
@@ -5,10 +5,23 @@ authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
[dependencies]
derive_more = "0.99.2"
futures = "0.3.1"
log = "0.4.8"
serde = { version = "1.0.101", features = ["derive"] }
codec = { package = "parity-scale-codec", version = "1.0.0" }
primitives = { package = "sp-core", path = "../core" }
sp-runtime = { path = "../sr-primitives" }
codec = { package = "parity-scale-codec", version = "1.0.0", optional = true }
derive_more = { version = "0.99.2", optional = true }
futures = { version = "0.3.1", optional = true }
log = { version = "0.4.8", optional = true }
primitives = { package = "sp-core", path = "../core", optional = true}
serde = { version = "1.0.101", features = ["derive"], optional = true}
sp-api = { path = "../sr-api", default-features = false }
sp-runtime = { path = "../sr-primitives", default-features = false }
[features]
std = [
"codec",
"derive_more",
"futures",
"log",
"primitives",
"serde",
"sp-api/std",
"sp-runtime/std",
]
@@ -1,14 +0,0 @@
[package]
name = "sp-transaction-pool-runtime-api"
version = "2.0.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
[dependencies]
primitives = { package = "sp-core", path = "../../core", default-features = false }
sp-api = { path = "../../sr-api", default-features = false }
sp-runtime = { path = "../../sr-primitives", default-features = false }
[features]
default = [ "std" ]
std = [ "sp-runtime/std", "primitives/std", "sp-api/std" ]
@@ -68,15 +68,15 @@ pub enum Error {
impl std::error::Error for Error {}
/// Transaction pool error conversion.
pub trait IntoPoolError: ::std::error::Error + Send + Sized {
pub trait IntoPoolError: std::error::Error + Send + Sized {
/// Try to extract original `Error`
///
/// This implementation is optional and used only to
/// provide more descriptive error messages for end users
/// of RPC API.
fn into_pool_error(self) -> ::std::result::Result<Error, Self> { Err(self) }
fn into_pool_error(self) -> std::result::Result<Error, Self> { Err(self) }
}
impl IntoPoolError for Error {
fn into_pool_error(self) -> ::std::result::Result<Error, Self> { Ok(self) }
fn into_pool_error(self) -> std::result::Result<Error, Self> { Ok(self) }
}
@@ -14,315 +14,20 @@
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
//! Transaction pool types.
//! Transaction pool primitives types & Runtime API.
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)]
pub mod runtime_api;
#[cfg(feature = "std")]
pub mod error;
#[cfg(feature = "std")]
mod pool;
#[cfg(feature = "std")]
pub use pool::*;
pub use error::IntoPoolError;
pub use sp_runtime::transaction_validity::{
TransactionLongevity, TransactionPriority, TransactionTag,
};
use std::{
collections::HashMap,
hash::Hash,
sync::Arc,
};
use futures::{
Future, Stream,
channel::mpsc,
};
use serde::{Deserialize, Serialize};
use sp_runtime::{
generic::BlockId,
traits::{Block as BlockT, Member},
};
/// Transaction pool status.
#[derive(Debug)]
pub struct PoolStatus {
/// Number of transactions in the ready queue.
pub ready: usize,
/// Sum of bytes of ready transaction encodings.
pub ready_bytes: usize,
/// Number of transactions in the future queue.
pub future: usize,
/// Sum of bytes of ready transaction encodings.
pub future_bytes: usize,
}
impl PoolStatus {
/// Returns true if the are no transactions in the pool.
pub fn is_empty(&self) -> bool {
self.ready == 0 && self.future == 0
}
}
/// Possible transaction status events.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum TransactionStatus<Hash, BlockHash> {
/// Transaction is part of the future queue.
Future,
/// Transaction is part of the ready queue.
Ready,
/// Transaction has been finalized in block with given hash.
Finalized(BlockHash),
/// Some state change (perhaps another transaction was included) rendered this transaction invalid.
Usurped(Hash),
/// The transaction has been broadcast to the given peers.
Broadcast(Vec<String>),
/// Transaction has been dropped from the pool because of the limit.
Dropped,
/// Transaction was detected as invalid.
Invalid,
}
/// The stream of transaction events.
pub type TransactionStatusStream<Hash, BlockHash> = dyn Stream<Item=TransactionStatus<Hash, BlockHash>> + Send + Unpin;
/// The import notification event stream.
pub type ImportNotificationStream = mpsc::UnboundedReceiver<()>;
/// Transaction hash type for a pool.
pub type TxHash<P> = <P as TransactionPool>::Hash;
/// Block hash type for a pool.
pub type BlockHash<P> = <<P as TransactionPool>::Block as BlockT>::Hash;
/// Transaction type for a pool.
pub type TransactionFor<P> = <<P as TransactionPool>::Block as BlockT>::Extrinsic;
/// Type of transactions event stream for a pool.
pub type TransactionStatusStreamFor<P> = TransactionStatusStream<TxHash<P>, BlockHash<P>>;
/// In-pool transaction interface.
///
/// The pool is container of transactions that are implementing this trait.
/// See `sp_runtime::ValidTransaction` for details about every field.
pub trait InPoolTransaction {
/// Transaction type.
type Transaction;
/// Transaction hash type.
type Hash;
/// Get the reference to the transaction data.
fn data(&self) -> &Self::Transaction;
/// Get hash of the transaction.
fn hash(&self) -> &Self::Hash;
/// Get priority of the transaction.
fn priority(&self) -> &TransactionPriority;
/// Get longevity of the transaction.
fn longevity(&self) ->&TransactionLongevity;
/// Get transaction dependencies.
fn requires(&self) -> &[TransactionTag];
/// Get tags that transaction provides.
fn provides(&self) -> &[TransactionTag];
/// Return a flag indicating if the transaction should be propagated to other peers.
fn is_propagateable(&self) -> bool;
}
/// Transaction pool interface.
pub trait TransactionPool: Send + Sync {
/// Block type.
type Block: BlockT;
/// Transaction hash type.
type Hash: Hash + Eq + Member + Serialize;
/// In-pool transaction type.
type InPoolTransaction: InPoolTransaction<
Transaction = TransactionFor<Self>,
Hash = TxHash<Self>
>;
/// Error type.
type Error: From<error::Error> + IntoPoolError;
/// Returns a future that imports a bunch of unverified transactions to the pool.
fn submit_at(
&self,
at: &BlockId<Self::Block>,
xts: impl IntoIterator<Item=TransactionFor<Self>> + 'static,
) -> Box<dyn Future<Output=Result<
Vec<Result<TxHash<Self>, Self::Error>>,
Self::Error
>> + Send + Unpin>;
/// Returns a future that imports one unverified transaction to the pool.
fn submit_one(
&self,
at: &BlockId<Self::Block>,
xt: TransactionFor<Self>,
) -> Box<dyn Future<Output=Result<
TxHash<Self>,
Self::Error
>> + Send + Unpin>;
/// Returns a future that import a single transaction and starts to watch their progress in the pool.
fn submit_and_watch(
&self,
at: &BlockId<Self::Block>,
xt: TransactionFor<Self>,
) -> Box<dyn Future<Output=Result<Box<TransactionStatusStreamFor<Self>>, Self::Error>> + Send + Unpin>;
/// Remove transactions identified by given hashes (and dependent transactions) from the pool.
fn remove_invalid(&self, hashes: &[TxHash<Self>]) -> Vec<Arc<Self::InPoolTransaction>>;
/// Returns pool status.
fn status(&self) -> PoolStatus;
/// Get an iterator for ready transactions ordered by priority
fn ready(&self) -> Box<dyn Iterator<Item=Arc<Self::InPoolTransaction>>>;
/// Return an event stream of transactions imported to the pool.
fn import_notification_stream(&self) -> ImportNotificationStream;
/// Returns transaction hash
fn hash_of(&self, xt: &TransactionFor<Self>) -> TxHash<Self>;
/// Notify the pool about transactions broadcast.
fn on_broadcasted(&self, propagations: HashMap<TxHash<Self>, Vec<String>>);
}
/// An abstraction for transaction pool.
///
/// This trait is used by offchain calls to be able to submit transactions.
/// The main use case is for offchain workers, to feed back the results of computations,
/// but since the transaction pool access is a separate `ExternalitiesExtension` it can
/// be also used in context of other offchain calls. For one may generate and submit
/// a transaction for some misbehavior reports (say equivocation).
pub trait OffchainSubmitTransaction<Block: BlockT>: Send + Sync {
/// Submit transaction.
///
/// The transaction will end up in the pool and be propagated to others.
fn submit_at(
&self,
at: &BlockId<Block>,
extrinsic: Block::Extrinsic,
) -> Result<(), ()>;
}
impl<TPool: TransactionPool> OffchainSubmitTransaction<TPool::Block> for TPool {
fn submit_at(
&self,
at: &BlockId<TPool::Block>,
extrinsic: <TPool::Block as BlockT>::Extrinsic,
) -> Result<(), ()> {
log::debug!(
target: "txpool",
"(offchain call) Submitting a transaction to the pool: {:?}",
extrinsic
);
let result = futures::executor::block_on(self.submit_one(&at, extrinsic));
result.map(|_| ())
.map_err(|e| log::warn!(
target: "txpool",
"(offchain call) Error submitting a transaction to the pool: {:?}",
e
))
}
}
/// Transaction pool maintainer interface.
pub trait TransactionPoolMaintainer: Send + Sync {
/// Block type.
type Block: BlockT;
/// Transaction Hash type.
type Hash: Hash + Eq + Member + Serialize;
/// Returns a future that performs maintenance procedures on the pool when
/// with given hash is imported.
fn maintain(
&self,
id: &BlockId<Self::Block>,
retracted: &[Self::Hash],
) -> Box<dyn Future<Output=()> + Send + Unpin>;
}
/// Maintainable pool implementation.
pub struct MaintainableTransactionPool<Pool, Maintainer> {
pool: Pool,
maintainer: Maintainer,
}
impl<Pool, Maintainer> MaintainableTransactionPool<Pool, Maintainer> {
/// Create new maintainable pool using underlying pool and maintainer.
pub fn new(pool: Pool, maintainer: Maintainer) -> Self {
MaintainableTransactionPool { pool, maintainer }
}
}
impl<Pool, Maintainer> TransactionPool for MaintainableTransactionPool<Pool, Maintainer>
where
Pool: TransactionPool,
Maintainer: Send + Sync,
{
type Block = Pool::Block;
type Hash = Pool::Hash;
type InPoolTransaction = Pool::InPoolTransaction;
type Error = Pool::Error;
fn submit_at(
&self,
at: &BlockId<Self::Block>,
xts: impl IntoIterator<Item=TransactionFor<Self>> + 'static,
) -> Box<dyn Future<Output=Result<Vec<Result<TxHash<Self>, Self::Error>>, Self::Error>> + Send + Unpin> {
self.pool.submit_at(at, xts)
}
fn submit_one(
&self,
at: &BlockId<Self::Block>,
xt: TransactionFor<Self>,
) -> Box<dyn Future<Output=Result<TxHash<Self>, Self::Error>> + Send + Unpin> {
self.pool.submit_one(at, xt)
}
fn submit_and_watch(
&self,
at: &BlockId<Self::Block>,
xt: TransactionFor<Self>,
) -> Box<dyn Future<Output=Result<Box<TransactionStatusStreamFor<Self>>, Self::Error>> + Send + Unpin> {
self.pool.submit_and_watch(at, xt)
}
fn remove_invalid(&self, hashes: &[TxHash<Self>]) -> Vec<Arc<Self::InPoolTransaction>> {
self.pool.remove_invalid(hashes)
}
fn status(&self) -> PoolStatus {
self.pool.status()
}
fn ready(&self) -> Box<dyn Iterator<Item=Arc<Self::InPoolTransaction>>> {
self.pool.ready()
}
fn import_notification_stream(&self) -> ImportNotificationStream {
self.pool.import_notification_stream()
}
fn hash_of(&self, xt: &TransactionFor<Self>) -> TxHash<Self> {
self.pool.hash_of(xt)
}
fn on_broadcasted(&self, propagations: HashMap<TxHash<Self>, Vec<String>>) {
self.pool.on_broadcasted(propagations)
}
}
impl<Pool, Maintainer> TransactionPoolMaintainer for MaintainableTransactionPool<Pool, Maintainer>
where
Pool: Send + Sync,
Maintainer: TransactionPoolMaintainer
{
type Block = Maintainer::Block;
type Hash = Maintainer::Hash;
fn maintain(
&self,
id: &BlockId<Self::Block>,
retracted: &[Self::Hash],
) -> Box<dyn Future<Output=()> + Send + Unpin> {
self.maintainer.maintain(id, retracted)
}
}
@@ -0,0 +1,322 @@
// Copyright 2019 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
//! Transaction pool primitives types & Runtime API.
use std::{
collections::HashMap,
hash::Hash,
sync::Arc,
};
use futures::{
Future, Stream,
channel::mpsc,
};
use serde::{Deserialize, Serialize};
use sp_runtime::{
generic::BlockId,
traits::{Block as BlockT, Member},
transaction_validity::{
TransactionLongevity, TransactionPriority, TransactionTag,
},
};
/// Transaction pool status.
#[derive(Debug)]
pub struct PoolStatus {
/// Number of transactions in the ready queue.
pub ready: usize,
/// Sum of bytes of ready transaction encodings.
pub ready_bytes: usize,
/// Number of transactions in the future queue.
pub future: usize,
/// Sum of bytes of ready transaction encodings.
pub future_bytes: usize,
}
impl PoolStatus {
/// Returns true if the are no transactions in the pool.
pub fn is_empty(&self) -> bool {
self.ready == 0 && self.future == 0
}
}
/// Possible transaction status events.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum TransactionStatus<Hash, BlockHash> {
/// Transaction is part of the future queue.
Future,
/// Transaction is part of the ready queue.
Ready,
/// Transaction has been finalized in block with given hash.
Finalized(BlockHash),
/// Some state change (perhaps another transaction was included) rendered this transaction invalid.
Usurped(Hash),
/// The transaction has been broadcast to the given peers.
Broadcast(Vec<String>),
/// Transaction has been dropped from the pool because of the limit.
Dropped,
/// Transaction was detected as invalid.
Invalid,
}
/// The stream of transaction events.
pub type TransactionStatusStream<Hash, BlockHash> = dyn Stream<Item=TransactionStatus<Hash, BlockHash>> + Send + Unpin;
/// The import notification event stream.
pub type ImportNotificationStream = mpsc::UnboundedReceiver<()>;
/// Transaction hash type for a pool.
pub type TxHash<P> = <P as TransactionPool>::Hash;
/// Block hash type for a pool.
pub type BlockHash<P> = <<P as TransactionPool>::Block as BlockT>::Hash;
/// Transaction type for a pool.
pub type TransactionFor<P> = <<P as TransactionPool>::Block as BlockT>::Extrinsic;
/// Type of transactions event stream for a pool.
pub type TransactionStatusStreamFor<P> = TransactionStatusStream<TxHash<P>, BlockHash<P>>;
/// In-pool transaction interface.
///
/// The pool is container of transactions that are implementing this trait.
/// See `sp_runtime::ValidTransaction` for details about every field.
pub trait InPoolTransaction {
/// Transaction type.
type Transaction;
/// Transaction hash type.
type Hash;
/// Get the reference to the transaction data.
fn data(&self) -> &Self::Transaction;
/// Get hash of the transaction.
fn hash(&self) -> &Self::Hash;
/// Get priority of the transaction.
fn priority(&self) -> &TransactionPriority;
/// Get longevity of the transaction.
fn longevity(&self) ->&TransactionLongevity;
/// Get transaction dependencies.
fn requires(&self) -> &[TransactionTag];
/// Get tags that transaction provides.
fn provides(&self) -> &[TransactionTag];
/// Return a flag indicating if the transaction should be propagated to other peers.
fn is_propagateable(&self) -> bool;
}
/// Transaction pool interface.
pub trait TransactionPool: Send + Sync {
/// Block type.
type Block: BlockT;
/// Transaction hash type.
type Hash: Hash + Eq + Member + Serialize;
/// In-pool transaction type.
type InPoolTransaction: InPoolTransaction<
Transaction = TransactionFor<Self>,
Hash = TxHash<Self>
>;
/// Error type.
type Error: From<crate::error::Error> + crate::error::IntoPoolError;
/// Returns a future that imports a bunch of unverified transactions to the pool.
fn submit_at(
&self,
at: &BlockId<Self::Block>,
xts: impl IntoIterator<Item=TransactionFor<Self>> + 'static,
) -> Box<dyn Future<Output=Result<
Vec<Result<TxHash<Self>, Self::Error>>,
Self::Error
>> + Send + Unpin>;
/// Returns a future that imports one unverified transaction to the pool.
fn submit_one(
&self,
at: &BlockId<Self::Block>,
xt: TransactionFor<Self>,
) -> Box<dyn Future<Output=Result<
TxHash<Self>,
Self::Error
>> + Send + Unpin>;
/// Returns a future that import a single transaction and starts to watch their progress in the pool.
fn submit_and_watch(
&self,
at: &BlockId<Self::Block>,
xt: TransactionFor<Self>,
) -> Box<dyn Future<Output=Result<Box<TransactionStatusStreamFor<Self>>, Self::Error>> + Send + Unpin>;
/// Remove transactions identified by given hashes (and dependent transactions) from the pool.
fn remove_invalid(&self, hashes: &[TxHash<Self>]) -> Vec<Arc<Self::InPoolTransaction>>;
/// Returns pool status.
fn status(&self) -> PoolStatus;
/// Get an iterator for ready transactions ordered by priority
fn ready(&self) -> Box<dyn Iterator<Item=Arc<Self::InPoolTransaction>>>;
/// Return an event stream of transactions imported to the pool.
fn import_notification_stream(&self) -> ImportNotificationStream;
/// Returns transaction hash
fn hash_of(&self, xt: &TransactionFor<Self>) -> TxHash<Self>;
/// Notify the pool about transactions broadcast.
fn on_broadcasted(&self, propagations: HashMap<TxHash<Self>, Vec<String>>);
}
/// An abstraction for transaction pool.
///
/// This trait is used by offchain calls to be able to submit transactions.
/// The main use case is for offchain workers, to feed back the results of computations,
/// but since the transaction pool access is a separate `ExternalitiesExtension` it can
/// be also used in context of other offchain calls. For one may generate and submit
/// a transaction for some misbehavior reports (say equivocation).
pub trait OffchainSubmitTransaction<Block: BlockT>: Send + Sync {
/// Submit transaction.
///
/// The transaction will end up in the pool and be propagated to others.
fn submit_at(
&self,
at: &BlockId<Block>,
extrinsic: Block::Extrinsic,
) -> Result<(), ()>;
}
impl<TPool: TransactionPool> OffchainSubmitTransaction<TPool::Block> for TPool {
fn submit_at(
&self,
at: &BlockId<TPool::Block>,
extrinsic: <TPool::Block as BlockT>::Extrinsic,
) -> Result<(), ()> {
log::debug!(
target: "txpool",
"(offchain call) Submitting a transaction to the pool: {:?}",
extrinsic
);
let result = futures::executor::block_on(self.submit_one(&at, extrinsic));
result.map(|_| ())
.map_err(|e| log::warn!(
target: "txpool",
"(offchain call) Error submitting a transaction to the pool: {:?}",
e
))
}
}
/// Transaction pool maintainer interface.
pub trait TransactionPoolMaintainer: Send + Sync {
/// Block type.
type Block: BlockT;
/// Transaction Hash type.
type Hash: Hash + Eq + Member + Serialize;
/// Returns a future that performs maintenance procedures on the pool when
/// with given hash is imported.
fn maintain(
&self,
id: &BlockId<Self::Block>,
retracted: &[Self::Hash],
) -> Box<dyn Future<Output=()> + Send + Unpin>;
}
/// Maintainable pool implementation.
pub struct MaintainableTransactionPool<Pool, Maintainer> {
pool: Pool,
maintainer: Maintainer,
}
impl<Pool, Maintainer> MaintainableTransactionPool<Pool, Maintainer> {
/// Create new maintainable pool using underlying pool and maintainer.
pub fn new(pool: Pool, maintainer: Maintainer) -> Self {
MaintainableTransactionPool { pool, maintainer }
}
}
impl<Pool, Maintainer> TransactionPool for MaintainableTransactionPool<Pool, Maintainer>
where
Pool: TransactionPool,
Maintainer: Send + Sync,
{
type Block = Pool::Block;
type Hash = Pool::Hash;
type InPoolTransaction = Pool::InPoolTransaction;
type Error = Pool::Error;
fn submit_at(
&self,
at: &BlockId<Self::Block>,
xts: impl IntoIterator<Item=TransactionFor<Self>> + 'static,
) -> Box<dyn Future<Output=Result<Vec<Result<TxHash<Self>, Self::Error>>, Self::Error>> + Send + Unpin> {
self.pool.submit_at(at, xts)
}
fn submit_one(
&self,
at: &BlockId<Self::Block>,
xt: TransactionFor<Self>,
) -> Box<dyn Future<Output=Result<TxHash<Self>, Self::Error>> + Send + Unpin> {
self.pool.submit_one(at, xt)
}
fn submit_and_watch(
&self,
at: &BlockId<Self::Block>,
xt: TransactionFor<Self>,
) -> Box<dyn Future<Output=Result<Box<TransactionStatusStreamFor<Self>>, Self::Error>> + Send + Unpin> {
self.pool.submit_and_watch(at, xt)
}
fn remove_invalid(&self, hashes: &[TxHash<Self>]) -> Vec<Arc<Self::InPoolTransaction>> {
self.pool.remove_invalid(hashes)
}
fn status(&self) -> PoolStatus {
self.pool.status()
}
fn ready(&self) -> Box<dyn Iterator<Item=Arc<Self::InPoolTransaction>>> {
self.pool.ready()
}
fn import_notification_stream(&self) -> ImportNotificationStream {
self.pool.import_notification_stream()
}
fn hash_of(&self, xt: &TransactionFor<Self>) -> TxHash<Self> {
self.pool.hash_of(xt)
}
fn on_broadcasted(&self, propagations: HashMap<TxHash<Self>, Vec<String>>) {
self.pool.on_broadcasted(propagations)
}
}
impl<Pool, Maintainer> TransactionPoolMaintainer for MaintainableTransactionPool<Pool, Maintainer>
where
Pool: Send + Sync,
Maintainer: TransactionPoolMaintainer
{
type Block = Maintainer::Block;
type Hash = Maintainer::Hash;
fn maintain(
&self,
id: &BlockId<Self::Block>,
retracted: &[Self::Hash],
) -> Box<dyn Future<Output=()> + Send + Unpin> {
self.maintainer.maintain(id, retracted)
}
}
@@ -1,4 +1,4 @@
// Copyright 2018-2019 Parity Technologies (UK) Ltd.
// Copyright 2019 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate is free software: you can redistribute it and/or modify
@@ -14,11 +14,10 @@
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
//! Substrate runtime api for the transaction queue.
//! Tagged Transaction Queue Runtime API.
#![cfg_attr(not(feature = "std"), no_std)]
use sp_runtime::{transaction_validity::TransactionValidity, traits::Block as BlockT};
use sp_runtime::transaction_validity::TransactionValidity;
use sp_runtime::traits::Block as BlockT;
sp_api::decl_runtime_apis! {
/// The `TaggedTransactionQueue` api trait for interfering with the transaction queue.
+2 -2
View File
@@ -34,7 +34,7 @@ frame-system-rpc-runtime-api = { path = "../../../frame/system/rpc/runtime-api",
pallet-timestamp = { path = "../../../frame/timestamp", default-features = false }
sc-client = { path = "../../../client", optional = true }
sp-trie = { path = "../../../primitives/trie", default-features = false }
txpool-runtime-api = { package = "sp-transaction-pool-runtime-api", path = "../../../primitives/transaction-pool/runtime-api", default-features = false }
sp-transaction-pool = { package = "sp-transaction-pool-api", path = "../../../primitives/transaction-pool", default-features = false }
trie-db = { version = "0.16.0", default-features = false }
[dev-dependencies]
@@ -78,6 +78,6 @@ std = [
"pallet-timestamp/std",
"sc-client",
"sp-trie/std",
"txpool-runtime-api/std",
"sp-transaction-pool/std",
"trie-db/std",
]
+2 -2
View File
@@ -477,7 +477,7 @@ cfg_if! {
}
}
impl txpool_runtime_api::TaggedTransactionQueue<Block> for Runtime {
impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
fn validate_transaction(utx: <Block as BlockT>::Extrinsic) -> TransactionValidity {
if let Extrinsic::IncludeData(data) = utx {
return Ok(ValidTransaction {
@@ -662,7 +662,7 @@ cfg_if! {
}
}
impl txpool_runtime_api::TaggedTransactionQueue<Block> for Runtime {
impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
fn validate_transaction(utx: <Block as BlockT>::Extrinsic) -> TransactionValidity {
if let Extrinsic::IncludeData(data) = utx {
return Ok(ValidTransaction{