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

Commit d81f60e

Browse files
authored
Fix revalidation not revalidating multiple times (#5065)
1 parent 2afecf8 commit d81f60e

File tree

3 files changed

+61
-2
lines changed

3 files changed

+61
-2
lines changed

client/transaction-pool/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
//! Substrate transaction pool implementation.
1818
19+
#![recursion_limit="256"]
1920
#![warn(missing_docs)]
2021
#![warn(unused_extern_crates)]
2122

client/transaction-pool/src/revalidation.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,9 @@ async fn batch_revalidate<Api: ChainApi>(
113113
}
114114

115115
pool.validated_pool().remove_invalid(&invalid_hashes);
116-
pool.resubmit(revalidated);
116+
if revalidated.len() > 0 {
117+
pool.resubmit(revalidated);
118+
}
117119
}
118120

119121
impl<Api: ChainApi> RevalidationWorker<Api> {
@@ -149,6 +151,7 @@ impl<Api: ChainApi> RevalidationWorker<Api> {
149151
} else {
150152
for xt in &to_queue {
151153
extrinsics.remove(xt);
154+
self.members.remove(xt);
152155
}
153156
}
154157
left -= to_queue.len();
@@ -163,14 +166,26 @@ impl<Api: ChainApi> RevalidationWorker<Api> {
163166
queued_exts
164167
}
165168

169+
fn len(&self) -> usize {
170+
self.block_ordered.iter().map(|b| b.1.len()).sum()
171+
}
172+
166173
fn push(&mut self, worker_payload: WorkerPayload<Api>) {
167174
// we don't add something that already scheduled for revalidation
168175
let transactions = worker_payload.transactions;
169176
let block_number = worker_payload.at;
170177

171178
for ext_hash in transactions {
172179
// we don't add something that already scheduled for revalidation
173-
if self.members.contains_key(&ext_hash) { continue; }
180+
if self.members.contains_key(&ext_hash) {
181+
log::debug!(
182+
target: "txpool",
183+
"[{:?}] Skipped adding for revalidation: Already there.",
184+
ext_hash,
185+
);
186+
187+
continue;
188+
}
174189

175190
self.block_ordered.entry(block_number)
176191
.and_modify(|value| { value.insert(ext_hash.clone()); })
@@ -198,7 +213,18 @@ impl<Api: ChainApi> RevalidationWorker<Api> {
198213
futures::select! {
199214
_ = interval.next() => {
200215
let next_batch = this.prepare_batch();
216+
let batch_len = next_batch.len();
217+
201218
batch_revalidate(this.pool.clone(), this.api.clone(), this.best_block, next_batch).await;
219+
220+
if batch_len > 0 || this.len() > 0 {
221+
log::debug!(
222+
target: "txpool",
223+
"Revalidated {} transactions. Left in the queue for revalidation: {}.",
224+
batch_len,
225+
this.len(),
226+
);
227+
}
202228
},
203229
workload = from_queue.next() => {
204230
match workload {
@@ -264,6 +290,10 @@ where
264290
/// If queue configured without background worker, this will resolve after
265291
/// revalidation is actually done.
266292
pub async fn revalidate_later(&self, at: NumberFor<Api>, transactions: Vec<ExHash<Api>>) {
293+
if transactions.len() > 0 {
294+
log::debug!(target: "txpool", "Added {} transactions to revalidation queue", transactions.len());
295+
}
296+
267297
if let Some(ref to_worker) = self.background {
268298
if let Err(e) = to_worker.unbounded_send(WorkerPayload { at, transactions }) {
269299
log::warn!(target: "txpool", "Failed to update background worker: {:?}", e);

client/transaction-pool/src/testing/pool.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,34 @@ fn should_not_retain_invalid_hashes_from_retracted() {
267267
assert_eq!(pool.status().ready, 0);
268268
}
269269

270+
#[test]
271+
fn should_revalidate_transaction_multiple_times() {
272+
let xt = uxt(Alice, 209);
273+
274+
let (pool, _guard) = maintained_pool();
275+
276+
block_on(pool.submit_one(&BlockId::number(0), xt.clone())).expect("1. Imported");
277+
assert_eq!(pool.status().ready, 1);
278+
279+
pool.api.push_block(1, vec![xt.clone()]);
280+
281+
// maintenance is in background
282+
block_on(pool.maintain(block_event(1)));
283+
block_on(futures_timer::Delay::new(BACKGROUND_REVALIDATION_INTERVAL*2));
284+
285+
block_on(pool.submit_one(&BlockId::number(0), xt.clone())).expect("1. Imported");
286+
assert_eq!(pool.status().ready, 1);
287+
288+
pool.api.push_block(2, vec![]);
289+
pool.api.add_invalid(&xt);
290+
291+
// maintenance is in background
292+
block_on(pool.maintain(block_event(2)));
293+
block_on(futures_timer::Delay::new(BACKGROUND_REVALIDATION_INTERVAL*2));
294+
295+
assert_eq!(pool.status().ready, 0);
296+
}
297+
270298
#[test]
271299
fn should_push_watchers_during_maintaince() {
272300
fn alice_uxt(nonce: u64) -> Extrinsic {

0 commit comments

Comments
 (0)