global: snapshot

This commit is contained in:
nym21
2025-12-26 22:41:36 +01:00
parent d538280f4b
commit de93f08e93
120 changed files with 1125 additions and 1773 deletions

View File

@@ -4,8 +4,7 @@ use brk_types::TxidPrefix;
use rustc_hash::FxHashMap;
use super::tx_node::TxNode;
use crate::entry::Entry;
use crate::types::{PoolIndex, TxIndex};
use crate::{entry::Entry, types::{PoolIndex, TxIndex}};
/// Type-safe wrapper around Vec<TxNode> that only allows PoolIndex access.
pub struct Graph(Vec<TxNode>);

View File

@@ -1,3 +1,5 @@
use std::cmp::Ordering;
use brk_types::{Sats, VSize};
use super::tx_node::TxNode;
@@ -44,18 +46,18 @@ impl PartialEq for HeapEntry {
impl Eq for HeapEntry {}
impl PartialOrd for HeapEntry {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for HeapEntry {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
fn cmp(&self, other: &Self) -> Ordering {
// Higher fee rate = higher priority
if self.has_higher_fee_rate_than(other) {
std::cmp::Ordering::Greater
Ordering::Greater
} else if other.has_higher_fee_rate_than(self) {
std::cmp::Ordering::Less
Ordering::Less
} else {
// Tiebreaker: lower index first (deterministic)
other.pool_index.cmp(&self.pool_index)

View File

@@ -1,11 +1,3 @@
//! Builds projected blocks from mempool transactions.
//!
//! The algorithm:
//! 1. Build a dependency graph from mempool entries
//! 2. Select transactions using a heap (CPFP-aware)
//! 3. Group into atomic packages (parent + child stay together)
//! 4. Partition packages into blocks by fee rate
mod graph;
mod heap_entry;
mod package;
@@ -13,8 +5,7 @@ mod partitioner;
mod selector;
mod tx_node;
use crate::entry::Entry;
use crate::types::SelectedTx;
use crate::{entry::Entry, types::SelectedTx};
/// Target vsize per block (~1MB, derived from 4MW weight limit).
const BLOCK_VSIZE: u64 = 1_000_000;

View File

@@ -1,5 +1,4 @@
use super::package::Package;
use super::BLOCK_VSIZE;
use super::{BLOCK_VSIZE, package::Package};
use crate::types::SelectedTx;
/// How many packages to look ahead when current doesn't fit.

View File

@@ -4,10 +4,7 @@ use brk_types::FeeRate;
use rustc_hash::FxHashSet;
use smallvec::SmallVec;
use super::BLOCK_VSIZE;
use super::graph::Graph;
use super::heap_entry::HeapEntry;
use super::package::Package;
use super::{BLOCK_VSIZE, graph::Graph, heap_entry::HeapEntry, package::Package};
use crate::types::PoolIndex;
/// Select transactions from the graph and group into CPFP packages.

View File

@@ -1,8 +1,7 @@
use brk_types::TxidPrefix;
use rustc_hash::FxHashMap;
use crate::entry::Entry;
use crate::types::TxIndex;
use crate::{entry::Entry, types::TxIndex};
/// Pool of mempool entries with slot recycling.
///

View File

@@ -1,10 +1,3 @@
//! Bitcoin mempool monitor with fee estimation.
//!
//! Provides real-time mempool tracking with:
//! - Fee estimation via projected blocks
//! - Address mempool stats
//! - CPFP-aware block building
mod addresses;
mod block_builder;
mod entry;

View File

@@ -1,5 +1,3 @@
//! Projected block building and fee estimation.
mod fees;
mod snapshot;
mod stats;

View File

@@ -1,9 +1,7 @@
use brk_types::RecommendedFees;
use super::fees;
use super::stats::{self, BlockStats};
use crate::entry::Entry;
use crate::types::{SelectedTx, TxIndex};
use super::{fees, stats::{self, BlockStats}};
use crate::{entry::Entry, types::{SelectedTx, TxIndex}};
/// Immutable snapshot of projected blocks.
#[derive(Debug, Clone, Default)]

View File

@@ -1,7 +1,6 @@
use brk_types::{FeeRate, Sats, VSize};
use crate::entry::Entry;
use crate::types::SelectedTx;
use crate::{entry::Entry, types::SelectedTx};
/// Statistics for a single projected block.
#[derive(Debug, Clone, Default)]

View File

@@ -4,7 +4,7 @@ use std::{
atomic::{AtomicBool, AtomicU64, Ordering},
},
thread,
time::{Duration, Instant},
time::{Duration, Instant, SystemTime, UNIX_EPOCH},
};
use brk_error::Result;
@@ -15,12 +15,14 @@ use log::{debug, error};
use parking_lot::{RwLock, RwLockReadGuard};
use rustc_hash::FxHashMap;
use crate::addresses::AddressTracker;
use crate::block_builder::build_projected_blocks;
use crate::entry::Entry;
use crate::entry_pool::EntryPool;
use crate::projected_blocks::{BlockStats, RecommendedFees, Snapshot};
use crate::tx_store::TxStore;
use crate::{
addresses::AddressTracker,
block_builder::build_projected_blocks,
entry::Entry,
entry_pool::EntryPool,
projected_blocks::{BlockStats, RecommendedFees, Snapshot},
tx_store::TxStore,
};
/// Max new txs to fetch full data for per update cycle (for address tracking).
const MAX_TX_FETCHES_PER_CYCLE: usize = 10_000;
@@ -44,16 +46,13 @@ impl Mempool {
pub struct MempoolInner {
client: Client,
// Mempool state
info: RwLock<MempoolInfo>,
txs: RwLock<TxStore>,
addresses: RwLock<AddressTracker>,
entries: RwLock<EntryPool>,
// Projected blocks snapshot
snapshot: RwLock<Snapshot>,
// Rate limiting
dirty: AtomicBool,
last_rebuild_ms: AtomicU64,
}
@@ -205,8 +204,8 @@ impl MempoolInner {
return;
}
let now_ms = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
let now_ms = SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|d| d.as_millis() as u64)
.unwrap_or(0);