mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 15:51:12 +00:00
Call a state before block was imported. (#1294)
* Call a state before block was imported. * Add test to check if it works correctly.
This commit is contained in:
Generated
+1
@@ -3661,6 +3661,7 @@ dependencies = [
|
||||
"substrate-primitives 0.1.0",
|
||||
"substrate-rpc-servers 0.1.0",
|
||||
"substrate-telemetry 0.3.0",
|
||||
"substrate-test-client 0.1.0",
|
||||
"substrate-transaction-pool 0.1.0",
|
||||
"target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
||||
@@ -30,3 +30,6 @@ substrate-executor = { path = "../../core/executor" }
|
||||
substrate-transaction-pool = { path = "../../core/transaction-pool" }
|
||||
substrate-rpc-servers = { path = "../../core/rpc-servers" }
|
||||
substrate-telemetry = { path = "../../core/telemetry" }
|
||||
|
||||
[dev-dependencies]
|
||||
substrate-test-client = { path = "../test-client" }
|
||||
|
||||
@@ -184,6 +184,51 @@ pub trait MaintainTransactionPool<C: Components> {
|
||||
) -> error::Result<()>;
|
||||
}
|
||||
|
||||
fn on_block_imported<Api, Backend, Block, Executor, PoolApi>(
|
||||
id: &BlockId<Block>,
|
||||
client: &Client<Backend, Executor, Block, Api>,
|
||||
transaction_pool: &TransactionPool<PoolApi>,
|
||||
) -> error::Result<()> where
|
||||
Api: TaggedTransactionQueue<Block>,
|
||||
Block: BlockT<Hash = <Blake2Hasher as ::primitives::Hasher>::Out>,
|
||||
Backend: client::backend::Backend<Block, Blake2Hasher>,
|
||||
Client<Backend, Executor, Block, Api>: ProvideRuntimeApi<Api = Api>,
|
||||
Executor: client::CallExecutor<Block, Blake2Hasher>,
|
||||
PoolApi: txpool::ChainApi<Hash = Block::Hash, Block = Block>,
|
||||
{
|
||||
use runtime_primitives::transaction_validity::TransactionValidity;
|
||||
|
||||
// Avoid calling into runtime if there is nothing to prune from the pool anyway.
|
||||
if transaction_pool.status().is_empty() {
|
||||
return Ok(())
|
||||
}
|
||||
|
||||
let block = client.block(id)?;
|
||||
let tags = match block {
|
||||
None => return Ok(()),
|
||||
Some(block) => {
|
||||
let parent_id = BlockId::hash(*block.block.header().parent_hash());
|
||||
let mut tags = vec![];
|
||||
for tx in block.block.extrinsics() {
|
||||
let tx = client.runtime_api().validate_transaction(&parent_id, &tx)?;
|
||||
match tx {
|
||||
TransactionValidity::Valid { mut provides, .. } => {
|
||||
tags.append(&mut provides);
|
||||
},
|
||||
// silently ignore invalid extrinsics,
|
||||
// cause they might just be inherent
|
||||
_ => {}
|
||||
}
|
||||
|
||||
}
|
||||
tags
|
||||
}
|
||||
};
|
||||
|
||||
transaction_pool.prune_tags(id, tags).map_err(|e| format!("{:?}", e))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl<C: Components> MaintainTransactionPool<Self> for C where
|
||||
ComponentClient<C>: ProvideRuntimeApi<Api = C::RuntimeApi>,
|
||||
C::RuntimeApi: TaggedTransactionQueue<ComponentBlock<C>>,
|
||||
@@ -194,36 +239,7 @@ impl<C: Components> MaintainTransactionPool<Self> for C where
|
||||
client: &ComponentClient<C>,
|
||||
transaction_pool: &TransactionPool<C::TransactionPoolApi>,
|
||||
) -> error::Result<()> {
|
||||
use runtime_primitives::transaction_validity::TransactionValidity;
|
||||
|
||||
// Avoid calling into runtime if there is nothing to prune from the pool anyway.
|
||||
if transaction_pool.status().is_empty() {
|
||||
return Ok(())
|
||||
}
|
||||
|
||||
let block = client.block(id)?;
|
||||
let tags = match block {
|
||||
None => return Ok(()),
|
||||
Some(block) => {
|
||||
let mut tags = vec![];
|
||||
for tx in block.block.extrinsics() {
|
||||
let tx = client.runtime_api().validate_transaction(id, &tx)?;
|
||||
match tx {
|
||||
TransactionValidity::Valid { mut provides, .. } => {
|
||||
tags.append(&mut provides);
|
||||
},
|
||||
// silently ignore invalid extrinsics,
|
||||
// cause they might just be inherent
|
||||
_ => {}
|
||||
}
|
||||
|
||||
}
|
||||
tags
|
||||
}
|
||||
};
|
||||
|
||||
transaction_pool.prune_tags(id, tags).map_err(|e| format!("{:?}", e))?;
|
||||
Ok(())
|
||||
on_block_imported(id, client, transaction_pool)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -520,3 +536,53 @@ impl<Factory: ServiceFactory> Components for LightComponents<Factory> {
|
||||
Factory::build_light_import_queue(config, client)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use codec::Encode;
|
||||
use consensus_common::BlockOrigin;
|
||||
use substrate_test_client::{
|
||||
self,
|
||||
TestClient,
|
||||
keyring::Keyring,
|
||||
runtime::{Extrinsic, Transfer},
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn should_remove_transactions_from_the_pool() {
|
||||
let client = Arc::new(substrate_test_client::new());
|
||||
let pool = TransactionPool::new(Default::default(), ::transaction_pool::ChainApi::new(client.clone()));
|
||||
let transaction = {
|
||||
let transfer = Transfer {
|
||||
amount: 5,
|
||||
nonce: 0,
|
||||
from: Keyring::Alice.to_raw_public().into(),
|
||||
to: Default::default(),
|
||||
};
|
||||
let signature = Keyring::from_raw_public(transfer.from.to_fixed_bytes()).unwrap().sign(&transfer.encode()).into();
|
||||
Extrinsic { transfer, signature }
|
||||
};
|
||||
// store the transaction in the pool
|
||||
pool.submit_one(&BlockId::hash(client.best_block_header().unwrap().hash()), transaction.clone()).unwrap();
|
||||
|
||||
// import the block
|
||||
let mut builder = client.new_block().unwrap();
|
||||
builder.push(transaction.clone()).unwrap();
|
||||
let block = builder.bake().unwrap();
|
||||
let id = BlockId::hash(block.header().hash());
|
||||
client.import(BlockOrigin::Own, block).unwrap();
|
||||
|
||||
// fire notification - this should clean up the queue
|
||||
assert_eq!(pool.status().ready, 1);
|
||||
on_block_imported(
|
||||
&id,
|
||||
&client,
|
||||
&pool,
|
||||
).unwrap();
|
||||
|
||||
// then
|
||||
assert_eq!(pool.status().ready, 0);
|
||||
assert_eq!(pool.status().future, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,9 @@ extern crate log;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
#[cfg(test)]
|
||||
extern crate substrate_test_client;
|
||||
|
||||
mod components;
|
||||
mod error;
|
||||
mod chain_spec;
|
||||
|
||||
Reference in New Issue
Block a user