42 lines
1.2 KiB
Rust
42 lines
1.2 KiB
Rust
|
|
// Copyright (C) 2024 Riften Labs AS
|
||
|
|
//
|
||
|
|
// This software is licensed under the GNU Affero General Public License (AGPL), version 3.0 or later.
|
||
|
|
// A copy of the license can be found in the LICENSE file or at https://www.gnu.org/licenses/agpl-3.0.html
|
||
|
|
|
||
|
|
use std::collections::{HashSet, VecDeque};
|
||
|
|
|
||
|
|
use bitcoincash::{Transaction, Txid};
|
||
|
|
use rayon::prelude::*;
|
||
|
|
|
||
|
|
// TTOR sort a list of transactions
|
||
|
|
pub fn ttor_sorted(txs: Vec<Transaction>) -> Vec<Transaction> {
|
||
|
|
let txs = {
|
||
|
|
let mut queue: VecDeque<Transaction> = txs.into_iter().collect();
|
||
|
|
|
||
|
|
let mut queue_txids: HashSet<Txid> = queue.par_iter().map(|tx| tx.txid()).collect();
|
||
|
|
|
||
|
|
let mut txs: Vec<Transaction> = Vec::with_capacity(queue.len());
|
||
|
|
|
||
|
|
while let Some(tx) = queue.pop_front() {
|
||
|
|
let mut has_parent = false;
|
||
|
|
|
||
|
|
for i in &tx.input {
|
||
|
|
if queue_txids.contains(&i.previous_output.txid) {
|
||
|
|
// depends on parent
|
||
|
|
has_parent = true;
|
||
|
|
break;
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
if has_parent {
|
||
|
|
queue.push_back(tx);
|
||
|
|
} else {
|
||
|
|
queue_txids.remove(&tx.txid());
|
||
|
|
txs.push(tx)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
txs
|
||
|
|
};
|
||
|
|
txs
|
||
|
|
}
|