Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit 67f1d05

Browse files
tomusdrwgavofyork
authored andcommitted
Call a state before block was imported. (#1294)
* Call a state before block was imported. * Add test to check if it works correctly.
1 parent fe193bd commit 67f1d05

File tree

4 files changed

+103
-30
lines changed

4 files changed

+103
-30
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/service/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,6 @@ substrate-executor = { path = "../../core/executor" }
3030
substrate-transaction-pool = { path = "../../core/transaction-pool" }
3131
substrate-rpc-servers = { path = "../../core/rpc-servers" }
3232
substrate-telemetry = { path = "../../core/telemetry" }
33+
34+
[dev-dependencies]
35+
substrate-test-client = { path = "../test-client" }

core/service/src/components.rs

Lines changed: 96 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,51 @@ pub trait MaintainTransactionPool<C: Components> {
184184
) -> error::Result<()>;
185185
}
186186

187+
fn on_block_imported<Api, Backend, Block, Executor, PoolApi>(
188+
id: &BlockId<Block>,
189+
client: &Client<Backend, Executor, Block, Api>,
190+
transaction_pool: &TransactionPool<PoolApi>,
191+
) -> error::Result<()> where
192+
Api: TaggedTransactionQueue<Block>,
193+
Block: BlockT<Hash = <Blake2Hasher as ::primitives::Hasher>::Out>,
194+
Backend: client::backend::Backend<Block, Blake2Hasher>,
195+
Client<Backend, Executor, Block, Api>: ProvideRuntimeApi<Api = Api>,
196+
Executor: client::CallExecutor<Block, Blake2Hasher>,
197+
PoolApi: txpool::ChainApi<Hash = Block::Hash, Block = Block>,
198+
{
199+
use runtime_primitives::transaction_validity::TransactionValidity;
200+
201+
// Avoid calling into runtime if there is nothing to prune from the pool anyway.
202+
if transaction_pool.status().is_empty() {
203+
return Ok(())
204+
}
205+
206+
let block = client.block(id)?;
207+
let tags = match block {
208+
None => return Ok(()),
209+
Some(block) => {
210+
let parent_id = BlockId::hash(*block.block.header().parent_hash());
211+
let mut tags = vec![];
212+
for tx in block.block.extrinsics() {
213+
let tx = client.runtime_api().validate_transaction(&parent_id, &tx)?;
214+
match tx {
215+
TransactionValidity::Valid { mut provides, .. } => {
216+
tags.append(&mut provides);
217+
},
218+
// silently ignore invalid extrinsics,
219+
// cause they might just be inherent
220+
_ => {}
221+
}
222+
223+
}
224+
tags
225+
}
226+
};
227+
228+
transaction_pool.prune_tags(id, tags).map_err(|e| format!("{:?}", e))?;
229+
Ok(())
230+
}
231+
187232
impl<C: Components> MaintainTransactionPool<Self> for C where
188233
ComponentClient<C>: ProvideRuntimeApi<Api = C::RuntimeApi>,
189234
C::RuntimeApi: TaggedTransactionQueue<ComponentBlock<C>>,
@@ -194,36 +239,7 @@ impl<C: Components> MaintainTransactionPool<Self> for C where
194239
client: &ComponentClient<C>,
195240
transaction_pool: &TransactionPool<C::TransactionPoolApi>,
196241
) -> error::Result<()> {
197-
use runtime_primitives::transaction_validity::TransactionValidity;
198-
199-
// Avoid calling into runtime if there is nothing to prune from the pool anyway.
200-
if transaction_pool.status().is_empty() {
201-
return Ok(())
202-
}
203-
204-
let block = client.block(id)?;
205-
let tags = match block {
206-
None => return Ok(()),
207-
Some(block) => {
208-
let mut tags = vec![];
209-
for tx in block.block.extrinsics() {
210-
let tx = client.runtime_api().validate_transaction(id, &tx)?;
211-
match tx {
212-
TransactionValidity::Valid { mut provides, .. } => {
213-
tags.append(&mut provides);
214-
},
215-
// silently ignore invalid extrinsics,
216-
// cause they might just be inherent
217-
_ => {}
218-
}
219-
220-
}
221-
tags
222-
}
223-
};
224-
225-
transaction_pool.prune_tags(id, tags).map_err(|e| format!("{:?}", e))?;
226-
Ok(())
242+
on_block_imported(id, client, transaction_pool)
227243
}
228244
}
229245

@@ -520,3 +536,53 @@ impl<Factory: ServiceFactory> Components for LightComponents<Factory> {
520536
Factory::build_light_import_queue(config, client)
521537
}
522538
}
539+
540+
#[cfg(test)]
541+
mod tests {
542+
use super::*;
543+
use codec::Encode;
544+
use consensus_common::BlockOrigin;
545+
use substrate_test_client::{
546+
self,
547+
TestClient,
548+
keyring::Keyring,
549+
runtime::{Extrinsic, Transfer},
550+
};
551+
552+
#[test]
553+
fn should_remove_transactions_from_the_pool() {
554+
let client = Arc::new(substrate_test_client::new());
555+
let pool = TransactionPool::new(Default::default(), ::transaction_pool::ChainApi::new(client.clone()));
556+
let transaction = {
557+
let transfer = Transfer {
558+
amount: 5,
559+
nonce: 0,
560+
from: Keyring::Alice.to_raw_public().into(),
561+
to: Default::default(),
562+
};
563+
let signature = Keyring::from_raw_public(transfer.from.to_fixed_bytes()).unwrap().sign(&transfer.encode()).into();
564+
Extrinsic { transfer, signature }
565+
};
566+
// store the transaction in the pool
567+
pool.submit_one(&BlockId::hash(client.best_block_header().unwrap().hash()), transaction.clone()).unwrap();
568+
569+
// import the block
570+
let mut builder = client.new_block().unwrap();
571+
builder.push(transaction.clone()).unwrap();
572+
let block = builder.bake().unwrap();
573+
let id = BlockId::hash(block.header().hash());
574+
client.import(BlockOrigin::Own, block).unwrap();
575+
576+
// fire notification - this should clean up the queue
577+
assert_eq!(pool.status().ready, 1);
578+
on_block_imported(
579+
&id,
580+
&client,
581+
&pool,
582+
).unwrap();
583+
584+
// then
585+
assert_eq!(pool.status().ready, 0);
586+
assert_eq!(pool.status().future, 0);
587+
}
588+
}

core/service/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ extern crate log;
5050
#[macro_use]
5151
extern crate serde_derive;
5252

53+
#[cfg(test)]
54+
extern crate substrate_test_client;
55+
5356
mod components;
5457
mod error;
5558
mod chain_spec;

0 commit comments

Comments
 (0)