fix rust gbt priority queue handling

This commit is contained in:
Mononaut 2023-06-26 17:35:33 -04:00
parent f5e0662517
commit a66c0c88ce
No known key found for this signature in database
GPG Key ID: A3F058E41374C04E
2 changed files with 19 additions and 10 deletions

View File

@ -28,6 +28,7 @@ pub struct AuditTransaction {
// Safety: Must be private to prevent NaN breaking Ord impl. // Safety: Must be private to prevent NaN breaking Ord impl.
score: f64, score: f64,
pub used: bool, pub used: bool,
/// whether this transaction has been moved to the "modified" priority queue
pub modified: bool, pub modified: bool,
pub dirty: bool, pub dirty: bool,
} }
@ -132,14 +133,14 @@ impl AuditTransaction {
root_sigops: u32, root_sigops: u32,
cluster_rate: f64, cluster_rate: f64,
) -> f64 { ) -> f64 {
self.ancestors.remove(&root_txid);
self.ancestor_fee -= root_fee;
self.ancestor_weight -= root_weight;
self.ancestor_sigops -= root_sigops;
let old_score = self.score(); let old_score = self.score();
self.calc_new_score();
self.dependency_rate = self.dependency_rate.min(cluster_rate); self.dependency_rate = self.dependency_rate.min(cluster_rate);
self.modified = true; if self.ancestors.remove(&root_txid) {
self.ancestor_fee -= root_fee;
self.ancestor_weight -= root_weight;
self.ancestor_sigops -= root_sigops;
self.calc_new_score();
}
old_score old_score
} }
} }

View File

@ -35,7 +35,7 @@ impl PartialOrd for TxPriority {
if self.score == other.score { if self.score == other.score {
Some(self.uid.cmp(&other.uid)) Some(self.uid.cmp(&other.uid))
} else { } else {
other.score.partial_cmp(&self.score) self.score.partial_cmp(&other.score)
} }
} }
} }
@ -95,10 +95,13 @@ pub fn gbt(mempool: &mut ThreadTransactionsMap) -> Option<GbtResult> {
let mut failures = 0; let mut failures = 0;
while !mempool_array.is_empty() || !modified.is_empty() { while !mempool_array.is_empty() || !modified.is_empty() {
let next_txid: u32; let next_txid: u32;
let from_modified: bool;
if modified.is_empty() { if modified.is_empty() {
next_txid = mempool_array.pop_front()?; next_txid = mempool_array.pop_front()?;
from_modified = false;
} else if mempool_array.is_empty() { } else if mempool_array.is_empty() {
next_txid = modified.pop()?.0; next_txid = modified.pop()?.0;
from_modified = true;
} else { } else {
let next_array_txid = mempool_array.front()?; let next_array_txid = mempool_array.front()?;
let next_modified_txid = modified.peek()?.0; let next_modified_txid = modified.peek()?.0;
@ -107,16 +110,20 @@ pub fn gbt(mempool: &mut ThreadTransactionsMap) -> Option<GbtResult> {
match array_tx.cmp(modified_tx) { match array_tx.cmp(modified_tx) {
std::cmp::Ordering::Equal | std::cmp::Ordering::Greater => { std::cmp::Ordering::Equal | std::cmp::Ordering::Greater => {
next_txid = mempool_array.pop_front()?; next_txid = mempool_array.pop_front()?;
from_modified = false;
} }
std::cmp::Ordering::Less => { std::cmp::Ordering::Less => {
next_txid = modified.pop()?.0; next_txid = modified.pop()?.0;
from_modified = true;
} }
} }
} }
let next_tx = audit_pool.get(&next_txid)?; let next_tx = audit_pool.get(&next_txid)?;
if next_tx.used { // skip the transaction if it has already been used
// or has been moved to the "modified" priority queue
if next_tx.used || (!from_modified && next_tx.modified) {
continue; continue;
} }
@ -293,9 +300,9 @@ fn update_descendants(
// remove root tx as ancestor // remove root tx as ancestor
let old_score = let old_score =
descendant.remove_root(root_txid, root_fee, root_weight, root_sigops, cluster_rate); descendant.remove_root(root_txid, root_fee, root_weight, root_sigops, cluster_rate);
// update modified priority if score has changed // add to priority queue or update priority if score has changed
// remove_root() always sets modified to true
if descendant.score() < old_score { if descendant.score() < old_score {
descendant.modified = true;
modified.push_decrease( modified.push_decrease(
descendant.uid, descendant.uid,
TxPriority { TxPriority {
@ -304,6 +311,7 @@ fn update_descendants(
}, },
); );
} else if descendant.score() > old_score { } else if descendant.score() > old_score {
descendant.modified = true;
modified.push_increase( modified.push_increase(
descendant.uid, descendant.uid,
TxPriority { TxPriority {