fix handling of used txs at top of mempool stack
This commit is contained in:
parent
75fd4ff5e1
commit
1688b7d24e
@ -94,45 +94,33 @@ pub fn gbt(mempool: &mut ThreadTransactionsMap) -> Option<GbtResult> {
|
|||||||
let mut overflow: Vec<u32> = Vec::new();
|
let mut overflow: Vec<u32> = Vec::new();
|
||||||
let mut failures = 0;
|
let mut failures = 0;
|
||||||
while !mempool_stack.is_empty() || !modified.is_empty() {
|
while !mempool_stack.is_empty() || !modified.is_empty() {
|
||||||
let next_txid: u32;
|
let next_from_stack = next_valid_from_stack(&mut mempool_stack, &audit_pool);
|
||||||
let from_modified: bool;
|
let next_from_queue = next_valid_from_queue(&mut modified, &audit_pool);
|
||||||
if modified.is_empty() {
|
if next_from_stack.is_none() && next_from_queue.is_none() {
|
||||||
next_txid = mempool_stack.pop()?;
|
|
||||||
from_modified = false;
|
|
||||||
} else if mempool_stack.is_empty() {
|
|
||||||
next_txid = modified.pop()?.0;
|
|
||||||
from_modified = true;
|
|
||||||
} else {
|
|
||||||
let next_array_txid = mempool_stack.last()?;
|
|
||||||
let next_modified_txid = modified.peek()?.0;
|
|
||||||
let array_tx: &AuditTransaction = audit_pool.get(next_array_txid)?;
|
|
||||||
let modified_tx: &AuditTransaction = audit_pool.get(next_modified_txid)?;
|
|
||||||
match array_tx.cmp(modified_tx) {
|
|
||||||
std::cmp::Ordering::Equal | std::cmp::Ordering::Greater => {
|
|
||||||
next_txid = mempool_stack.pop()?;
|
|
||||||
from_modified = false;
|
|
||||||
}
|
|
||||||
std::cmp::Ordering::Less => {
|
|
||||||
next_txid = modified.pop()?.0;
|
|
||||||
from_modified = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let next_tx = audit_pool.get(&next_txid)?;
|
|
||||||
|
|
||||||
// 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;
|
||||||
}
|
}
|
||||||
|
let (next_tx, from_stack) = match (next_from_stack, next_from_queue) {
|
||||||
|
(Some(stack_tx), Some(queue_tx)) => match queue_tx.cmp(stack_tx) {
|
||||||
|
std::cmp::Ordering::Less => (stack_tx, true),
|
||||||
|
_ => (queue_tx, false),
|
||||||
|
},
|
||||||
|
(Some(stack_tx), None) => (stack_tx, true),
|
||||||
|
(None, Some(queue_tx)) => (queue_tx, false),
|
||||||
|
(None, None) => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
if from_stack {
|
||||||
|
mempool_stack.pop();
|
||||||
|
} else {
|
||||||
|
modified.pop();
|
||||||
|
}
|
||||||
|
|
||||||
if blocks.len() < (MAX_BLOCKS - 1)
|
if blocks.len() < (MAX_BLOCKS - 1)
|
||||||
&& ((block_weight + next_tx.ancestor_weight() >= BLOCK_WEIGHT_UNITS)
|
&& ((block_weight + next_tx.ancestor_weight() >= BLOCK_WEIGHT_UNITS)
|
||||||
|| (block_sigops + next_tx.ancestor_sigops() > BLOCK_SIGOPS))
|
|| (block_sigops + next_tx.ancestor_sigops() > BLOCK_SIGOPS))
|
||||||
{
|
{
|
||||||
// hold this package in an overflow list while we check for smaller options
|
// hold this package in an overflow list while we check for smaller options
|
||||||
overflow.push(next_txid);
|
overflow.push(next_tx.uid);
|
||||||
failures += 1;
|
failures += 1;
|
||||||
} else {
|
} else {
|
||||||
let mut package: Vec<(u32, usize)> = Vec::new();
|
let mut package: Vec<(u32, usize)> = Vec::new();
|
||||||
@ -144,7 +132,7 @@ pub fn gbt(mempool: &mut ThreadTransactionsMap) -> Option<GbtResult> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
package.sort_unstable_by_key(|a| a.1);
|
package.sort_unstable_by_key(|a| a.1);
|
||||||
package.push((next_txid, next_tx.ancestors.len()));
|
package.push((next_tx.uid, next_tx.ancestors.len()));
|
||||||
|
|
||||||
let cluster_rate = next_tx
|
let cluster_rate = next_tx
|
||||||
.dependency_rate
|
.dependency_rate
|
||||||
@ -226,6 +214,28 @@ pub fn gbt(mempool: &mut ThreadTransactionsMap) -> Option<GbtResult> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn next_valid_from_stack<'a>(mempool_stack: &mut Vec<u32>, audit_pool: &'a AuditPool) -> Option<&'a AuditTransaction> {
|
||||||
|
let mut next_txid = mempool_stack.last()?;
|
||||||
|
let mut tx: &AuditTransaction = audit_pool.get(next_txid)?;
|
||||||
|
while tx.used || tx.modified {
|
||||||
|
mempool_stack.pop();
|
||||||
|
next_txid = mempool_stack.last()?;
|
||||||
|
tx = audit_pool.get(next_txid)?;
|
||||||
|
}
|
||||||
|
Some(tx)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next_valid_from_queue<'a>(queue: &mut ModifiedQueue, audit_pool: &'a AuditPool) -> Option<&'a AuditTransaction> {
|
||||||
|
let mut next_txid = queue.peek()?.0;
|
||||||
|
let mut tx: &AuditTransaction = audit_pool.get(next_txid)?;
|
||||||
|
while tx.used {
|
||||||
|
queue.pop();
|
||||||
|
next_txid = queue.peek()?.0;
|
||||||
|
tx = audit_pool.get(next_txid)?;
|
||||||
|
}
|
||||||
|
Some(tx)
|
||||||
|
}
|
||||||
|
|
||||||
fn set_relatives(txid: u32, audit_pool: &mut AuditPool) {
|
fn set_relatives(txid: u32, audit_pool: &mut AuditPool) {
|
||||||
let mut parents: HashSet<u32, U32HasherState> = u32hashset_new();
|
let mut parents: HashSet<u32, U32HasherState> = u32hashset_new();
|
||||||
if let Some(tx) = audit_pool.get(&txid) {
|
if let Some(tx) = audit_pool.get(&txid) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user