Fix a import+prune+replace case for multi-provides transactions. (#3939)

* Fix a import+prune+replace case for multi-provides transactions.

* Fix tests.
This commit is contained in:
Tomasz Drwięga
2019-10-28 16:06:20 +01:00
committed by Gavin Wood
parent 448ce2adff
commit 06433c9889
3 changed files with 65 additions and 10 deletions
@@ -240,6 +240,7 @@ impl<B: ChainApi> Pool<B> {
tags: impl IntoIterator<Item=Tag>,
known_imported_hashes: impl IntoIterator<Item=ExHash<B>> + Clone,
) -> impl Future<Output=Result<(), B::Error>> {
log::trace!(target: "txpool", "Pruning at {:?}", at);
// Prune all transactions that provide given tags
let prune_status = match self.validated_pool.prune_tags(tags) {
Ok(prune_status) => prune_status,
@@ -257,6 +258,7 @@ impl<B: ChainApi> Pool<B> {
let pruned_transactions = prune_status.pruned.into_iter().map(|tx| tx.data.clone());
let reverify_future = self.verify(at, pruned_transactions, false);
log::trace!(target: "txpool", "Prunning at {:?}. Resubmitting transactions.", at);
// And finally - submit reverified transactions back to the pool
let at = at.clone();
let validated_pool = self.validated_pool.clone();
@@ -908,3 +910,4 @@ mod tests {
}
}
}
@@ -338,7 +338,20 @@ impl<Hash: hash::Hash + Member + Serialize, Ex> ReadyTransactions<Hash, Ex> {
}
}
debug!(target: "txpool", "[{:?}] Pruned.", tx.hash);
// we also need to remove all other tags that this transaction provides,
// but since all the hard work is done, we only clear the provided_tag -> hash
// mapping.
let current_tag = &tag;
for tag in &tx.provides {
let removed = self.provided_tags.remove(tag);
assert_eq!(
removed.as_ref(),
if current_tag == tag { None } else { Some(&tx.hash) },
"The pool contains exactly one transaction providing given tag; the removed transaction
claims to provide that tag, so it has to be mapped to it's hash; qed"
);
}
removed.push(tx);
}
}