;
/// Transaction hash type for a pool.
pub type TxHash =
::Hash;
/// Block hash type for a pool.
pub type BlockHash
= <
::Block as BlockT>::Hash;
/// Transaction type for a pool.
pub type TransactionFor
= <
::Block as BlockT>::Extrinsic;
/// Type of transactions event stream for a pool.
pub type TransactionStatusStreamFor
= TransactionStatusStream, BlockHash>;
/// Transaction type for a local pool.
pub type LocalTransactionFor
= <
::Block as BlockT>::Extrinsic;
/// Typical future type used in transaction pool api.
pub type PoolFuture = std::pin::Pin> + Send>>;
/// 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_propagable(&self) -> bool;
}
/// Transaction pool interface.
pub trait TransactionPool: Send + Sync {
/// Block type.
type Block: BlockT;
/// Transaction hash type.
type Hash: Hash + Eq + Member + Serialize + DeserializeOwned;
/// In-pool transaction type.
type InPoolTransaction: InPoolTransaction<
Transaction = TransactionFor,
Hash = TxHash,
>;
/// Error type.
type Error: From + crate::error::IntoPoolError;
// *** RPC
/// Returns a future that imports a bunch of unverified transactions to the pool.
fn submit_at(
&self,
at: &BlockId,
source: TransactionSource,
xts: Vec>,
) -> PoolFuture, Self::Error>>, Self::Error>;
/// Returns a future that imports one unverified transaction to the pool.
fn submit_one(
&self,
at: &BlockId,
source: TransactionSource,
xt: TransactionFor,
) -> PoolFuture, Self::Error>;
/// Returns a future that import a single transaction and starts to watch their progress in the
/// pool.
fn submit_and_watch(
&self,
at: &BlockId,
source: TransactionSource,
xt: TransactionFor,
) -> PoolFuture>>, Self::Error>;
// *** Block production / Networking
/// Get an iterator for ready transactions ordered by priority.
///
/// Guarantees to return only when transaction pool got updated at `at` block.
/// Guarantees to return immediately when `None` is passed.
fn ready_at(
&self,
at: NumberFor,
) -> Pin<
Box<
dyn Future<
Output = Box> + Send>,
> + Send,
>,
>;
/// Get an iterator for ready transactions ordered by priority.
fn ready(&self) -> Box> + Send>;
// *** Block production
/// Remove transactions identified by given hashes (and dependent transactions) from the pool.
fn remove_invalid(&self, hashes: &[TxHash]) -> Vec>;
// *** logging
/// Returns pool status.
fn status(&self) -> PoolStatus;
// *** logging / RPC / networking
/// Return an event stream of transactions imported to the pool.
fn import_notification_stream(&self) -> ImportNotificationStream>;
// *** networking
/// Notify the pool about transactions broadcast.
fn on_broadcasted(&self, propagations: HashMap, Vec>);
/// Returns transaction hash
fn hash_of(&self, xt: &TransactionFor) -> TxHash;
/// Return specific ready transaction by hash, if there is one.
fn ready_transaction(&self, hash: &TxHash) -> Option>;
}
/// An iterator of ready transactions.
///
/// The trait extends regular [`std::iter::Iterator`] trait and allows reporting
/// last-returned element as invalid.
///
/// The implementation is then allowed, for performance reasons, to change the elements
/// returned next, by e.g. skipping elements that are known to depend on the reported
/// transaction, which yields them invalid as well.
pub trait ReadyTransactions: Iterator {
/// Report given transaction as invalid.
///
/// This might affect subsequent elements returned by the iterator, so dependent transactions
/// are skipped for performance reasons.
fn report_invalid(&mut self, _tx: &Self::Item);
}
/// A no-op implementation for an empty iterator.
impl ReadyTransactions for std::iter::Empty {
fn report_invalid(&mut self, _tx: &T) {}
}
/// Events that the transaction pool listens for.
pub enum ChainEvent {
/// New best block have been added to the chain.
NewBestBlock {
/// Hash of the block.
hash: B::Hash,
/// Tree route from old best to new best parent that was calculated on import.
///
/// If `None`, no re-org happened on import.
tree_route: Option>>,
},
/// An existing block has been finalized.
Finalized {
/// Hash of just finalized block.
hash: B::Hash,
/// Path from old finalized to new finalized parent.
tree_route: Arc<[B::Hash]>,
},
}
/// Trait for transaction pool maintenance.
pub trait MaintainedTransactionPool: TransactionPool {
/// Perform maintenance
fn maintain(&self, event: ChainEvent) -> Pin + Send>>;
}
/// Transaction pool interface for submitting local transactions that exposes a
/// blocking interface for submission.
pub trait LocalTransactionPool: Send + Sync {
/// Block type.
type Block: BlockT;
/// Transaction hash type.
type Hash: Hash + Eq + Member + Serialize;
/// Error type.
type Error: From + crate::error::IntoPoolError;
/// Submits the given local unverified transaction to the pool blocking the
/// current thread for any necessary pre-verification.
/// NOTE: It MUST NOT be used for transactions that originate from the
/// network or RPC, since the validation is performed with
/// `TransactionSource::Local`.
fn submit_local(
&self,
at: &BlockId,
xt: LocalTransactionFor,
) -> Result;
}
/// 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: Send + Sync {
/// Submit transaction.
///
/// The transaction will end up in the pool and be propagated to others.
fn submit_at(&self, at: &BlockId, extrinsic: Block::Extrinsic) -> Result<(), ()>;
}
impl OffchainSubmitTransaction for TPool {
fn submit_at(
&self,
at: &BlockId,
extrinsic: ::Extrinsic,
) -> Result<(), ()> {
log::debug!(
target: "txpool",
"(offchain call) Submitting a transaction to the pool: {:?}",
extrinsic
);
let result = self.submit_local(at, extrinsic);
result.map(|_| ()).map_err(|e| {
log::warn!(
target: "txpool",
"(offchain call) Error submitting a transaction to the pool: {}",
e
)
})
}
}