Remove transaction RPC (#4949)
This commit is contained in:
parent
124ab28c9e
commit
34d28189ea
@ -1018,6 +1018,16 @@ impl MinerService for Miner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn remove_pending_transaction(&self, chain: &MiningBlockChainClient, hash: &H256) -> Option<PendingTransaction> {
|
||||||
|
let mut queue = self.transaction_queue.lock();
|
||||||
|
let tx = queue.find(hash);
|
||||||
|
if tx.is_some() {
|
||||||
|
let fetch_nonce = |a: &Address| chain.latest_nonce(a);
|
||||||
|
queue.remove_invalid(hash, &fetch_nonce);
|
||||||
|
}
|
||||||
|
tx
|
||||||
|
}
|
||||||
|
|
||||||
fn pending_receipt(&self, best_block: BlockNumber, hash: &H256) -> Option<RichReceipt> {
|
fn pending_receipt(&self, best_block: BlockNumber, hash: &H256) -> Option<RichReceipt> {
|
||||||
self.from_pending_block(
|
self.from_pending_block(
|
||||||
best_block,
|
best_block,
|
||||||
|
@ -150,6 +150,10 @@ pub trait MinerService : Send + Sync {
|
|||||||
/// Query pending transactions for hash.
|
/// Query pending transactions for hash.
|
||||||
fn transaction(&self, best_block: BlockNumber, hash: &H256) -> Option<PendingTransaction>;
|
fn transaction(&self, best_block: BlockNumber, hash: &H256) -> Option<PendingTransaction>;
|
||||||
|
|
||||||
|
/// Removes transaction from the queue.
|
||||||
|
/// NOTE: The transaction is not removed from pending block if mining.
|
||||||
|
fn remove_pending_transaction(&self, chain: &MiningBlockChainClient, hash: &H256) -> Option<PendingTransaction>;
|
||||||
|
|
||||||
/// Get a list of all pending transactions in the queue.
|
/// Get a list of all pending transactions in the queue.
|
||||||
fn pending_transactions(&self) -> Vec<PendingTransaction>;
|
fn pending_transactions(&self) -> Vec<PendingTransaction>;
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ use util::sha3;
|
|||||||
use jsonrpc_core::Error;
|
use jsonrpc_core::Error;
|
||||||
use v1::helpers::errors;
|
use v1::helpers::errors;
|
||||||
use v1::traits::ParitySet;
|
use v1::traits::ParitySet;
|
||||||
use v1::types::{Bytes, H160, H256, U256, ReleaseInfo};
|
use v1::types::{Bytes, H160, H256, U256, ReleaseInfo, Transaction};
|
||||||
|
|
||||||
/// Parity-specific rpc interface for operations altering the settings.
|
/// Parity-specific rpc interface for operations altering the settings.
|
||||||
pub struct ParitySetClient<F> {
|
pub struct ParitySetClient<F> {
|
||||||
@ -139,4 +139,8 @@ impl<F: Fetch> ParitySet for ParitySetClient<F> {
|
|||||||
fn execute_upgrade(&self) -> Result<bool, Error> {
|
fn execute_upgrade(&self) -> Result<bool, Error> {
|
||||||
Err(errors::light_unimplemented(None))
|
Err(errors::light_unimplemented(None))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn remove_transaction(&self, _hash: H256) -> Result<Option<Transaction>, Error> {
|
||||||
|
Err(errors::light_unimplemented(None))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,15 +30,10 @@ use updater::{Service as UpdateService};
|
|||||||
use jsonrpc_core::Error;
|
use jsonrpc_core::Error;
|
||||||
use v1::helpers::errors;
|
use v1::helpers::errors;
|
||||||
use v1::traits::ParitySet;
|
use v1::traits::ParitySet;
|
||||||
use v1::types::{Bytes, H160, H256, U256, ReleaseInfo};
|
use v1::types::{Bytes, H160, H256, U256, ReleaseInfo, Transaction};
|
||||||
|
|
||||||
/// Parity-specific rpc interface for operations altering the settings.
|
/// Parity-specific rpc interface for operations altering the settings.
|
||||||
pub struct ParitySetClient<C, M, U, F=fetch::Client> where
|
pub struct ParitySetClient<C, M, U, F = fetch::Client> {
|
||||||
C: MiningBlockChainClient,
|
|
||||||
M: MinerService,
|
|
||||||
U: UpdateService,
|
|
||||||
F: Fetch,
|
|
||||||
{
|
|
||||||
client: Weak<C>,
|
client: Weak<C>,
|
||||||
miner: Weak<M>,
|
miner: Weak<M>,
|
||||||
updater: Weak<U>,
|
updater: Weak<U>,
|
||||||
@ -46,12 +41,7 @@ pub struct ParitySetClient<C, M, U, F=fetch::Client> where
|
|||||||
fetch: F,
|
fetch: F,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, M, U, F> ParitySetClient<C, M, U, F> where
|
impl<C, M, U, F> ParitySetClient<C, M, U, F> {
|
||||||
C: MiningBlockChainClient,
|
|
||||||
M: MinerService,
|
|
||||||
U: UpdateService,
|
|
||||||
F: Fetch,
|
|
||||||
{
|
|
||||||
/// Creates new `ParitySetClient` with given `Fetch`.
|
/// Creates new `ParitySetClient` with given `Fetch`.
|
||||||
pub fn new(client: &Arc<C>, miner: &Arc<M>, updater: &Arc<U>, net: &Arc<ManageNetwork>, fetch: F) -> Self {
|
pub fn new(client: &Arc<C>, miner: &Arc<M>, updater: &Arc<U>, net: &Arc<ManageNetwork>, fetch: F) -> Self {
|
||||||
ParitySetClient {
|
ParitySetClient {
|
||||||
@ -181,4 +171,12 @@ impl<C, M, U, F> ParitySet for ParitySetClient<C, M, U, F> where
|
|||||||
let updater = take_weak!(self.updater);
|
let updater = take_weak!(self.updater);
|
||||||
Ok(updater.execute_upgrade())
|
Ok(updater.execute_upgrade())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn remove_transaction(&self, hash: H256) -> Result<Option<Transaction>, Error> {
|
||||||
|
let miner = take_weak!(self.miner);
|
||||||
|
let client = take_weak!(self.client);
|
||||||
|
let hash = hash.into();
|
||||||
|
|
||||||
|
Ok(miner.remove_pending_transaction(&*client, &hash).map(Into::into))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,6 +221,10 @@ impl MinerService for TestMinerService {
|
|||||||
self.pending_transactions.lock().get(hash).cloned().map(Into::into)
|
self.pending_transactions.lock().get(hash).cloned().map(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn remove_pending_transaction(&self, _chain: &MiningBlockChainClient, hash: &H256) -> Option<PendingTransaction> {
|
||||||
|
self.pending_transactions.lock().remove(hash).map(Into::into)
|
||||||
|
}
|
||||||
|
|
||||||
fn pending_transactions(&self) -> Vec<PendingTransaction> {
|
fn pending_transactions(&self) -> Vec<PendingTransaction> {
|
||||||
self.pending_transactions.lock().values().cloned().map(Into::into).collect()
|
self.pending_transactions.lock().values().cloned().map(Into::into).collect()
|
||||||
}
|
}
|
||||||
|
@ -204,3 +204,31 @@ fn rpc_parity_set_hash_content() {
|
|||||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rpc_parity_remove_transaction() {
|
||||||
|
use ethcore::transaction::{Transaction, Action};
|
||||||
|
|
||||||
|
let miner = miner_service();
|
||||||
|
let client = client_service();
|
||||||
|
let network = network_service();
|
||||||
|
let updater = updater_service();
|
||||||
|
let mut io = IoHandler::new();
|
||||||
|
io.extend_with(parity_set_client(&client, &miner, &updater, &network).to_delegate());
|
||||||
|
|
||||||
|
let tx = Transaction {
|
||||||
|
nonce: 1.into(),
|
||||||
|
gas_price: 0x9184e72a000u64.into(),
|
||||||
|
gas: 0x76c0.into(),
|
||||||
|
action: Action::Call(5.into()),
|
||||||
|
value: 0x9184e72au64.into(),
|
||||||
|
data: vec![]
|
||||||
|
};
|
||||||
|
let signed = tx.fake_sign(2.into());
|
||||||
|
let hash = signed.hash();
|
||||||
|
|
||||||
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_removeTransaction", "params":[""#.to_owned() + &format!("0x{:?}", hash) + r#""], "id": 1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":{"blockHash":null,"blockNumber":null,"condition":null,"creates":null,"from":"0x0000000000000000000000000000000000000002","gas":"0x76c0","gasPrice":"0x9184e72a000","hash":"0x0072c69d780cdfbfc02fed5c7d184151f9a166971d045e55e27695aaa5bcb55e","input":"0x","networkId":null,"nonce":"0x1","publicKey":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","r":"0x0","raw":"0xe9018609184e72a0008276c0940000000000000000000000000000000000000005849184e72a80808080","s":"0x0","standardV":"0x4","to":"0x0000000000000000000000000000000000000005","transactionIndex":null,"v":"0x0","value":"0x9184e72a"},"id":1}"#;
|
||||||
|
|
||||||
|
miner.pending_transactions.lock().insert(hash, signed);
|
||||||
|
assert_eq!(io.handle_request_sync(&request), Some(response.to_owned()));
|
||||||
|
}
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
use jsonrpc_core::Error;
|
use jsonrpc_core::Error;
|
||||||
use futures::BoxFuture;
|
use futures::BoxFuture;
|
||||||
|
|
||||||
use v1::types::{Bytes, H160, H256, U256, ReleaseInfo};
|
use v1::types::{Bytes, H160, H256, U256, ReleaseInfo, Transaction};
|
||||||
|
|
||||||
build_rpc_trait! {
|
build_rpc_trait! {
|
||||||
/// Parity-specific rpc interface for operations altering the settings.
|
/// Parity-specific rpc interface for operations altering the settings.
|
||||||
@ -103,5 +103,14 @@ build_rpc_trait! {
|
|||||||
/// Execute a release which is ready according to upgrade_ready().
|
/// Execute a release which is ready according to upgrade_ready().
|
||||||
#[rpc(name = "parity_executeUpgrade")]
|
#[rpc(name = "parity_executeUpgrade")]
|
||||||
fn execute_upgrade(&self) -> Result<bool, Error>;
|
fn execute_upgrade(&self) -> Result<bool, Error>;
|
||||||
|
|
||||||
|
/// Removes transaction from transaction queue.
|
||||||
|
/// Makes sense only for transactions that were not propagated to other peers yet
|
||||||
|
/// like scheduled transactions or transactions in future.
|
||||||
|
/// It might also work for some local transactions with to low gas price
|
||||||
|
/// or excessive gas limit that are not accepted by other peers whp.
|
||||||
|
/// Returns `true` when transaction was removed, `false` if it was not found.
|
||||||
|
#[rpc(name = "parity_removeTransaction")]
|
||||||
|
fn remove_transaction(&self, H256) -> Result<Option<Transaction>, Error>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user