Adds fork-awareness and finalization notifications to transaction pool watchers. (#4740)

* adds finalization support to sc-transaction-pool using MaintainedTransactionPool for finalization events

* adds TransactionStatus::Retracted, notify watchers of retracted blocks, finalized now finalizes, transactions for current finalized -> last finalized block

* adds last_finalized to ChainApi, use generic BlockT for ChainEvent

* fix tests

* Apply suggestions from code review

Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com>

* tests

* fix tests, docs, lazily dedupe pruned hashes

* fix tests, Cargo.lock

* Apply suggestions from code review

Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com>

* remove tree_route, last_finalized from ChainApi, add block hash to Finalization and Retracted events

* prune finality watchers

* fix tests

* remove HeaderBackend bound from FullChainApi

* code style nits, terminate stream in finality_timeout

Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com>
This commit is contained in:
Seun Lanlege
2020-02-14 14:44:58 +01:00
committed by GitHub
parent b999911bcf
commit d3a3e288b6
18 changed files with 639 additions and 283 deletions
+39 -29
View File
@@ -51,7 +51,7 @@ use std::{
use wasm_timer::SystemTime;
use sysinfo::{get_current_pid, ProcessExt, System, SystemExt};
use sc_telemetry::{telemetry, SUBSTRATE_INFO};
use sp_transaction_pool::MaintainedTransactionPool;
use sp_transaction_pool::{MaintainedTransactionPool, ChainEvent};
use sp_blockchain;
use grafana_data_source::{self, record_metrics};
@@ -882,42 +882,52 @@ ServiceBuilder<
let network_state_info: Arc<dyn NetworkStateInfo + Send + Sync> = network.clone();
let is_validator = config.roles.is_authority();
let events = client.import_notification_stream()
.for_each(move |notification| {
let txpool = txpool.upgrade();
let (import_stream, finality_stream) = (
client.import_notification_stream().map(|n| ChainEvent::NewBlock {
id: BlockId::Hash(n.hash),
header: n.header,
retracted: n.retracted,
is_new_best: n.is_new_best,
}),
client.finality_notification_stream().map(|n| ChainEvent::Finalized {
hash: n.hash
})
);
let events = futures::stream::select(import_stream, finality_stream)
.for_each(move |event| {
// offchain worker is only interested in block import events
if let ChainEvent::NewBlock { ref header, is_new_best, .. } = event {
let offchain = offchain.as_ref().and_then(|o| o.upgrade());
match offchain {
Some(offchain) if is_new_best => {
let future = offchain.on_block_imported(
&header,
network_state_info.clone(),
is_validator,
);
let _ = to_spawn_tx_.unbounded_send((
Box::pin(future),
From::from("offchain-on-block"),
));
},
Some(_) => log::debug!(
target: "sc_offchain",
"Skipping offchain workers for non-canon block: {:?}",
header,
),
_ => {},
}
};
let txpool = txpool.upgrade();
if let Some(txpool) = txpool.as_ref() {
let future = txpool.maintain(
&BlockId::hash(notification.hash),
&notification.retracted,
);
let future = txpool.maintain(event);
let _ = to_spawn_tx_.unbounded_send((
Box::pin(future),
From::from("txpool-maintain")
));
}
let offchain = offchain.as_ref().and_then(|o| o.upgrade());
match offchain {
Some(offchain) if notification.is_new_best => {
let future = offchain.on_block_imported(
&notification.header,
network_state_info.clone(),
is_validator,
);
let _ = to_spawn_tx_.unbounded_send((
Box::pin(future),
From::from("offchain-on-block"),
));
},
Some(_) => log::debug!(
target: "sc_offchain",
"Skipping offchain workers for non-canon block: {:?}",
notification.header,
),
_ => {},
}
ready(())
});
let _ = to_spawn_tx.unbounded_send((