Increased performance
This commit is contained in:
parent
77c83a6a13
commit
2838b068f7
@ -49,15 +49,20 @@ impl PartialEq for AuditTransaction {
|
|||||||
|
|
||||||
impl Eq for AuditTransaction {}
|
impl Eq for AuditTransaction {}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn partial_cmp_uid_score(a: (u32, f64), b: (u32, f64)) -> Option<Ordering> {
|
||||||
|
// If either score is NaN, this is false,
|
||||||
|
// and partial_cmp will return None
|
||||||
|
if a.1 == b.1 {
|
||||||
|
Some(a.0.cmp(&b.0))
|
||||||
|
} else {
|
||||||
|
a.1.partial_cmp(&b.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PartialOrd for AuditTransaction {
|
impl PartialOrd for AuditTransaction {
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
// If either score is NaN, this is false,
|
partial_cmp_uid_score((self.uid, self.score), (other.uid, other.score))
|
||||||
// and partial_cmp will return None
|
|
||||||
if self.score == other.score {
|
|
||||||
Some(self.uid.cmp(&other.uid))
|
|
||||||
} else {
|
|
||||||
self.score.partial_cmp(&other.score)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,11 +77,13 @@ impl Ord for AuditTransaction {
|
|||||||
|
|
||||||
impl AuditTransaction {
|
impl AuditTransaction {
|
||||||
pub fn from_thread_transaction(tx: &ThreadTransaction) -> Self {
|
pub fn from_thread_transaction(tx: &ThreadTransaction) -> Self {
|
||||||
|
// rounded up to the nearest integer
|
||||||
|
let sigop_adjusted_vsize = ((tx.weight + 3) / 4).max(tx.sigops * 5);
|
||||||
Self {
|
Self {
|
||||||
uid: tx.uid,
|
uid: tx.uid,
|
||||||
fee: tx.fee,
|
fee: tx.fee,
|
||||||
weight: tx.weight,
|
weight: tx.weight,
|
||||||
sigop_adjusted_vsize: ((tx.weight + 3) / 4).max(tx.sigops * 5), // rounded up to the nearest integer
|
sigop_adjusted_vsize,
|
||||||
sigops: tx.sigops,
|
sigops: tx.sigops,
|
||||||
fee_per_vsize: tx.fee_per_vsize,
|
fee_per_vsize: tx.fee_per_vsize,
|
||||||
effective_fee_per_vsize: tx.effective_fee_per_vsize,
|
effective_fee_per_vsize: tx.effective_fee_per_vsize,
|
||||||
@ -87,7 +94,7 @@ impl AuditTransaction {
|
|||||||
children: u32hashset_new(),
|
children: u32hashset_new(),
|
||||||
ancestor_fee: tx.fee,
|
ancestor_fee: tx.fee,
|
||||||
ancestor_weight: tx.weight,
|
ancestor_weight: tx.weight,
|
||||||
ancestor_sigop_adjusted_vsize: ((tx.weight + 3) / 4).max(tx.sigops * 5), // rounded up to the nearest integer
|
ancestor_sigop_adjusted_vsize: sigop_adjusted_vsize,
|
||||||
ancestor_sigops: tx.sigops,
|
ancestor_sigops: tx.sigops,
|
||||||
score: 0.0,
|
score: 0.0,
|
||||||
used: false,
|
used: false,
|
||||||
|
@ -6,7 +6,7 @@ use std::{
|
|||||||
use tracing::{info, trace};
|
use tracing::{info, trace};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
audit_transaction::AuditTransaction,
|
audit_transaction::{partial_cmp_uid_score, AuditTransaction},
|
||||||
u32_hasher_types::{
|
u32_hasher_types::{
|
||||||
u32hashmap_with_capacity, u32hashset_new, u32priority_queue_with_capacity, U32HasherState,
|
u32hashmap_with_capacity, u32hashset_new, u32priority_queue_with_capacity, U32HasherState,
|
||||||
},
|
},
|
||||||
@ -78,15 +78,17 @@ pub fn gbt(mempool: &mut ThreadTransactionsMap) -> GbtResult {
|
|||||||
trace!("Post relative graph Audit Pool: {:#?}", audit_pool);
|
trace!("Post relative graph Audit Pool: {:#?}", audit_pool);
|
||||||
|
|
||||||
info!("Sorting by descending ancestor score");
|
info!("Sorting by descending ancestor score");
|
||||||
mempool_stack.sort_unstable_by(|a, b| {
|
let mut mempool_stack: Vec<(u32, f64)> = mempool_stack
|
||||||
let a_tx = audit_pool
|
.into_iter()
|
||||||
.get(a)
|
.map(|txid| {
|
||||||
.expect("audit_pool contains exact same txes as mempool_stack");
|
let atx = audit_pool
|
||||||
let b_tx = audit_pool
|
.get(&txid)
|
||||||
.get(b)
|
.expect("All txids are from audit_pool");
|
||||||
.expect("audit_pool contains exact same txes as mempool_stack");
|
(txid, atx.score())
|
||||||
a_tx.cmp(b_tx)
|
})
|
||||||
});
|
.collect();
|
||||||
|
mempool_stack.sort_unstable_by(|a, b| partial_cmp_uid_score(*a, *b).expect("Not NaN"));
|
||||||
|
let mut mempool_stack: Vec<u32> = mempool_stack.into_iter().map(|(txid, _)| txid).collect();
|
||||||
|
|
||||||
info!("Building blocks by greedily choosing the highest feerate package");
|
info!("Building blocks by greedily choosing the highest feerate package");
|
||||||
info!("(i.e. the package rooted in the transaction with the best ancestor score)");
|
info!("(i.e. the package rooted in the transaction with the best ancestor score)");
|
||||||
@ -136,7 +138,8 @@ pub fn gbt(mempool: &mut ThreadTransactionsMap) -> GbtResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if blocks.len() < (MAX_BLOCKS - 1)
|
if blocks.len() < (MAX_BLOCKS - 1)
|
||||||
&& ((block_weight + (4 * next_tx.ancestor_sigop_adjusted_vsize()) >= MAX_BLOCK_WEIGHT_UNITS)
|
&& ((block_weight + (4 * next_tx.ancestor_sigop_adjusted_vsize())
|
||||||
|
>= MAX_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
|
||||||
@ -215,12 +218,12 @@ pub fn gbt(mempool: &mut ThreadTransactionsMap) -> GbtResult {
|
|||||||
overflow = Vec::new();
|
overflow = Vec::new();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// add the final unbounded block if it contains any transactions
|
info!("add the final unbounded block if it contains any transactions");
|
||||||
if !transactions.is_empty() {
|
if !transactions.is_empty() {
|
||||||
blocks.push(transactions);
|
blocks.push(transactions);
|
||||||
}
|
}
|
||||||
|
|
||||||
// make a list of dirty transactions and their new rates
|
info!("make a list of dirty transactions and their new rates");
|
||||||
let mut rates: Vec<Vec<f64>> = Vec::new();
|
let mut rates: Vec<Vec<f64>> = Vec::new();
|
||||||
for (txid, tx) in audit_pool {
|
for (txid, tx) in audit_pool {
|
||||||
trace!("txid: {}, is_dirty: {}", txid, tx.dirty);
|
trace!("txid: {}, is_dirty: {}", txid, tx.dirty);
|
||||||
@ -311,7 +314,13 @@ fn set_relatives(txid: u32, audit_pool: &mut AuditPool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(tx) = audit_pool.get_mut(&txid) {
|
if let Some(tx) = audit_pool.get_mut(&txid) {
|
||||||
tx.set_ancestors(ancestors, total_fee, total_weight, total_sigop_adjusted_vsize, total_sigops);
|
tx.set_ancestors(
|
||||||
|
ancestors,
|
||||||
|
total_fee,
|
||||||
|
total_weight,
|
||||||
|
total_sigop_adjusted_vsize,
|
||||||
|
total_sigops,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -345,8 +354,14 @@ fn update_descendants(
|
|||||||
while let Some(next_txid) = descendant_stack.pop() {
|
while let Some(next_txid) = descendant_stack.pop() {
|
||||||
if let Some(descendant) = audit_pool.get_mut(&next_txid) {
|
if let Some(descendant) = audit_pool.get_mut(&next_txid) {
|
||||||
// remove root tx as ancestor
|
// remove root tx as ancestor
|
||||||
let old_score =
|
let old_score = descendant.remove_root(
|
||||||
descendant.remove_root(root_txid, root_fee, root_weight, root_sigop_adjusted_vsize, root_sigops, cluster_rate);
|
root_txid,
|
||||||
|
root_fee,
|
||||||
|
root_weight,
|
||||||
|
root_sigop_adjusted_vsize,
|
||||||
|
root_sigops,
|
||||||
|
cluster_rate,
|
||||||
|
);
|
||||||
// add to priority queue or update priority if score has changed
|
// add to priority queue or update priority if score has changed
|
||||||
if descendant.score() < old_score {
|
if descendant.score() < old_score {
|
||||||
descendant.modified = true;
|
descendant.modified = true;
|
||||||
|
@ -30,7 +30,7 @@ use u32_hasher_types::{u32hashmap_with_capacity, U32HasherState};
|
|||||||
/// by virtue of starting with such a large capacity.
|
/// by virtue of starting with such a large capacity.
|
||||||
///
|
///
|
||||||
/// Note: This doesn't *have* to be a power of 2. (uwu)
|
/// Note: This doesn't *have* to be a power of 2. (uwu)
|
||||||
const STARTING_CAPACITY: usize = 2048;
|
const STARTING_CAPACITY: usize = 32768;
|
||||||
|
|
||||||
type ThreadTransactionsMap = HashMap<u32, ThreadTransaction, U32HasherState>;
|
type ThreadTransactionsMap = HashMap<u32, ThreadTransaction, U32HasherState>;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user