76 lines
2.4 KiB
Rust
Raw Normal View History

use napi::bindgen_prelude::*;
2023-06-24 11:21:58 -07:00
use napi_derive::napi;
2023-06-23 20:41:39 -04:00
use once_cell::sync::Lazy;
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;
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()));
#[napi(ts_args_type = "mempoolBuffer: Uint8Array")]
pub async fn make(mempool_buffer: Uint8Array) -> Result<GbtResult> {
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
{
let mut global_map = THREAD_TRANSACTIONS
.lock()
.map_err(|_| napi::Error::from_reason("THREAD_TRANSACTIONS Mutex poisoned"))?;
*global_map = map;
}
run_in_thread().await
}
#[napi(ts_args_type = "newTxs: Uint8Array, removeTxs: Uint8Array")]
pub async fn update(new_txs: Uint8Array, remove_txs: Uint8Array) -> Result<GbtResult> {
{
let mut map = THREAD_TRANSACTIONS
.lock()
.map_err(|_| napi::Error::from_reason("THREAD_TRANSACTIONS Mutex poisoned"))?;
for tx in ThreadTransaction::batch_from_buffer(&new_txs) {
map.insert(tx.uid, tx);
}
for txid in &utils::txids_from_buffer(&remove_txs) {
map.remove(txid);
}
2023-06-23 20:41:39 -04:00
}
2023-06-23 16:42:58 -04:00
run_in_thread().await
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
async fn run_in_thread() -> Result<GbtResult> {
let handle = napi::tokio::task::spawn_blocking(move || {
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 12:21:33 -07:00
handle
.await
2023-06-24 12:21:33 -07:00
.map_err(|_| napi::Error::from_reason("thread panicked"))?
2023-06-23 16:42:58 -04:00
}