mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-28 19:07:57 +00:00
Add RPC to remove and ban transactions from the pool. (#2732)
This commit is contained in:
committed by
Gavin Wood
parent
683fd5d364
commit
7af8604cbe
@@ -0,0 +1,30 @@
|
||||
// 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/>.
|
||||
|
||||
use primitives::Bytes;
|
||||
use serde::Deserialize;
|
||||
|
||||
/// RPC Extrinsic or hash
|
||||
///
|
||||
/// Allows to refer to extrinsics either by their raw representation or by it's hash.
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum ExtrinsicOrHash<Hash> {
|
||||
/// The hash of the extrinsic.
|
||||
Hash(Hash),
|
||||
/// Raw extrinsic bytes.
|
||||
Extrinsic(Bytes),
|
||||
}
|
||||
@@ -18,9 +18,15 @@
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use log::warn;
|
||||
use client::{self, Client};
|
||||
use crate::rpc::futures::{Sink, Stream, Future};
|
||||
use crate::subscriptions::Subscriptions;
|
||||
use jsonrpc_derive::rpc;
|
||||
use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId};
|
||||
use log::warn;
|
||||
use parity_codec::{Encode, Decode};
|
||||
use primitives::{Bytes, Blake2Hasher, H256};
|
||||
use runtime_primitives::{generic, traits};
|
||||
use transaction_pool::{
|
||||
txpool::{
|
||||
ChainApi as PoolChainApi,
|
||||
@@ -31,14 +37,9 @@ use transaction_pool::{
|
||||
watcher::Status,
|
||||
},
|
||||
};
|
||||
use jsonrpc_derive::rpc;
|
||||
use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId};
|
||||
use primitives::{Bytes, Blake2Hasher, H256};
|
||||
use crate::rpc::futures::{Sink, Stream, Future};
|
||||
use runtime_primitives::{generic, traits};
|
||||
use crate::subscriptions::Subscriptions;
|
||||
|
||||
pub mod error;
|
||||
mod hash;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
@@ -59,6 +60,10 @@ pub trait AuthorApi<Hash, BlockHash> {
|
||||
#[rpc(name = "author_pendingExtrinsics")]
|
||||
fn pending_extrinsics(&self) -> Result<Vec<Bytes>>;
|
||||
|
||||
/// Remove given extrinsic from the pool and temporarily ban it to prevent reimporting.
|
||||
#[rpc(name = "author_removeExtrinsic")]
|
||||
fn remove_extrinsic(&self, bytes_or_hash: Vec<hash::ExtrinsicOrHash<Hash>>) -> Result<Vec<Hash>>;
|
||||
|
||||
/// Submit an extrinsic to watch.
|
||||
#[pubsub(subscription = "author_extrinsicUpdate", subscribe, name = "author_submitAndWatchExtrinsic")]
|
||||
fn watch_extrinsic(&self, metadata: Self::Metadata, subscriber: Subscriber<Status<Hash, BlockHash>>, bytes: Bytes);
|
||||
@@ -72,7 +77,7 @@ pub trait AuthorApi<Hash, BlockHash> {
|
||||
pub struct Author<B, E, P, RA> where P: PoolChainApi + Sync + Send + 'static {
|
||||
/// Substrate client
|
||||
client: Arc<Client<B, E, <P as PoolChainApi>::Block, RA>>,
|
||||
/// Extrinsic pool
|
||||
/// Transactions pool
|
||||
pool: Arc<Pool<P>>,
|
||||
/// Subscriptions manager
|
||||
subscriptions: Subscriptions,
|
||||
@@ -118,6 +123,25 @@ impl<B, E, P, RA> AuthorApi<ExHash<P>, BlockHash<P>> for Author<B, E, P, RA> whe
|
||||
Ok(self.pool.ready().map(|tx| tx.data.encode().into()).collect())
|
||||
}
|
||||
|
||||
fn remove_extrinsic(&self, bytes_or_hash: Vec<hash::ExtrinsicOrHash<ExHash<P>>>) -> Result<Vec<ExHash<P>>> {
|
||||
let hashes = bytes_or_hash.into_iter()
|
||||
.map(|x| match x {
|
||||
hash::ExtrinsicOrHash::Hash(h) => Ok(h),
|
||||
hash::ExtrinsicOrHash::Extrinsic(bytes) => {
|
||||
let xt = Decode::decode(&mut &bytes[..]).ok_or(error::Error::BadFormat)?;
|
||||
Ok(self.pool.hash_of(&xt))
|
||||
},
|
||||
})
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
|
||||
Ok(
|
||||
self.pool.remove_invalid(&hashes)
|
||||
.into_iter()
|
||||
.map(|tx| tx.hash.clone())
|
||||
.collect()
|
||||
)
|
||||
}
|
||||
|
||||
fn watch_extrinsic(&self, _metadata: Self::Metadata, subscriber: Subscriber<Status<ExHash<P>, BlockHash<P>>>, xt: Bytes) {
|
||||
let submit = || -> Result<_> {
|
||||
let best_block_hash = self.client.info()?.chain.best_hash;
|
||||
|
||||
@@ -137,3 +137,31 @@ fn should_return_pending_extrinsics() {
|
||||
Ok(ref expected) if *expected == vec![Bytes(ex.encode())]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_remove_extrinsics() {
|
||||
let runtime = runtime::Runtime::new().unwrap();
|
||||
let client = Arc::new(test_client::new());
|
||||
let pool = Arc::new(Pool::new(Default::default(), ChainApi::new(client.clone())));
|
||||
let p = Author {
|
||||
client,
|
||||
pool: pool.clone(),
|
||||
subscriptions: Subscriptions::new(runtime.executor()),
|
||||
};
|
||||
let ex1 = uxt(AccountKeyring::Alice, 0);
|
||||
p.submit_extrinsic(ex1.encode().into()).unwrap();
|
||||
let ex2 = uxt(AccountKeyring::Alice, 1);
|
||||
p.submit_extrinsic(ex2.encode().into()).unwrap();
|
||||
let ex3 = uxt(AccountKeyring::Bob, 0);
|
||||
let hash3 = p.submit_extrinsic(ex3.encode().into()).unwrap();
|
||||
assert_eq!(pool.status().ready, 3);
|
||||
|
||||
// now remove all 3
|
||||
let removed = p.remove_extrinsic(vec![
|
||||
hash::ExtrinsicOrHash::Hash(hash3),
|
||||
// Removing this one will also remove ex2
|
||||
hash::ExtrinsicOrHash::Extrinsic(ex1.encode().into()),
|
||||
]).unwrap();
|
||||
|
||||
assert_eq!(removed.len(), 3);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user