2023-06-24 11:21:58 -07:00
|
|
|
use napi::bindgen_prelude::*;
|
|
|
|
use napi_derive::napi;
|
|
|
|
|
2023-06-23 20:41:39 -04:00
|
|
|
use once_cell::sync::Lazy;
|
2023-06-23 18:37:03 -04:00
|
|
|
use std::collections::HashMap;
|
|
|
|
use std::sync::Mutex;
|
2023-06-23 16:42:58 -04:00
|
|
|
|
2023-06-23 20:41:39 -04:00
|
|
|
mod audit_transaction;
|
2023-06-23 16:42:58 -04:00
|
|
|
mod gbt;
|
|
|
|
mod thread_transaction;
|
2023-06-23 18:37:03 -04:00
|
|
|
mod utils;
|
|
|
|
use thread_transaction::ThreadTransaction;
|
2023-06-23 16:42:58 -04:00
|
|
|
|
2023-06-23 20:41:39 -04:00
|
|
|
static THREAD_TRANSACTIONS: Lazy<Mutex<HashMap<u32, ThreadTransaction>>> =
|
|
|
|
Lazy::new(|| Mutex::new(HashMap::new()));
|
2023-06-23 18:37:03 -04:00
|
|
|
|
2023-06-24 11:21:58 -07:00
|
|
|
#[napi]
|
|
|
|
pub fn make<F>(mempool_buffer: Uint8Array, callback: F) -> Result<()>
|
|
|
|
where
|
|
|
|
F: Fn(GbtResult) -> Result<()>,
|
|
|
|
{
|
2023-06-23 20:41:39 -04:00
|
|
|
let mut map = HashMap::new();
|
2023-06-24 11:21:58 -07:00
|
|
|
for tx in ThreadTransaction::batch_from_buffer(&mempool_buffer) {
|
2023-06-23 20:41:39 -04:00
|
|
|
map.insert(tx.uid, tx);
|
|
|
|
}
|
2023-06-23 16:42:58 -04:00
|
|
|
|
2023-06-23 20:41:39 -04:00
|
|
|
let mut global_map = THREAD_TRANSACTIONS.lock().unwrap();
|
|
|
|
*global_map = map;
|
2023-06-23 18:37:03 -04:00
|
|
|
|
2023-06-24 11:21:58 -07:00
|
|
|
run_in_thread(callback)
|
2023-06-23 18:37:03 -04:00
|
|
|
}
|
|
|
|
|
2023-06-24 11:21:58 -07:00
|
|
|
#[napi]
|
|
|
|
pub fn update<F>(new_txs: Uint8Array, remove_txs: Uint8Array, callback: F) -> Result<()>
|
|
|
|
where
|
|
|
|
F: Fn(GbtResult) -> Result<()>,
|
|
|
|
{
|
2023-06-23 18:37:03 -04:00
|
|
|
let mut map = THREAD_TRANSACTIONS.lock().unwrap();
|
2023-06-24 11:21:58 -07:00
|
|
|
for tx in ThreadTransaction::batch_from_buffer(&new_txs) {
|
2023-06-23 20:41:39 -04:00
|
|
|
map.insert(tx.uid, tx);
|
|
|
|
}
|
2023-06-24 11:21:58 -07:00
|
|
|
for txid in &utils::txids_from_buffer(&remove_txs) {
|
2023-06-23 20:41:39 -04:00
|
|
|
map.remove(txid);
|
|
|
|
}
|
2023-06-23 18:37:03 -04:00
|
|
|
drop(map);
|
2023-06-23 16:42:58 -04:00
|
|
|
|
2023-06-24 11:21:58 -07:00
|
|
|
run_in_thread(callback)
|
2023-06-23 20:41:39 -04:00
|
|
|
}
|
|
|
|
|
2023-06-24 11:21:58 -07:00
|
|
|
/// The result from calling the gbt function.
|
|
|
|
///
|
|
|
|
/// This tuple contains the following:
|
|
|
|
/// blocks: A 2D Vector of transaction IDs (u32), the inner Vecs each represent a block.
|
|
|
|
/// clusters: A 2D Vector of transaction IDs representing clusters of dependent mempool transactions
|
|
|
|
/// rates: A Vector of tuples containing transaction IDs (u32) and effective fee per vsize (f64)
|
|
|
|
#[napi(constructor)]
|
|
|
|
pub struct GbtResult {
|
|
|
|
pub blocks: Vec<Vec<u32>>,
|
|
|
|
pub clusters: Vec<Vec<u32>>,
|
|
|
|
pub rates: Vec<Vec<f64>>, // Tuples not supported. u32 fits inside f64
|
|
|
|
}
|
2023-06-23 20:41:39 -04:00
|
|
|
|
2023-06-24 11:21:58 -07:00
|
|
|
fn run_in_thread<F>(callback: F) -> Result<()>
|
|
|
|
where
|
|
|
|
F: Fn(GbtResult) -> Result<()>,
|
|
|
|
{
|
|
|
|
let handle = std::thread::spawn(|| -> Result<GbtResult> {
|
|
|
|
let mut map = THREAD_TRANSACTIONS
|
|
|
|
.lock()
|
|
|
|
.map_err(|_| napi::Error::from_reason("THREAD_TRANSACTIONS Mutex poisoned"))?;
|
|
|
|
gbt::gbt(&mut map).ok_or_else(|| napi::Error::from_reason("gbt failed"))
|
2023-06-23 16:42:58 -04:00
|
|
|
});
|
|
|
|
|
2023-06-24 11:21:58 -07:00
|
|
|
callback(
|
|
|
|
handle
|
|
|
|
.join()
|
|
|
|
.map_err(|_| napi::Error::from_reason("thread panicked"))??,
|
|
|
|
)
|
2023-06-23 16:42:58 -04:00
|
|
|
}
|