Module: BSV::Wallet::Interface::UTXOPool
- Defined in:
- lib/bsv/wallet/interface/utxo_pool.rb
Overview
UTXO selection strategy for transaction construction.
The pool recommends which outputs to spend. The actual locking happens in Store#create_action (Phase 1) via INSERT INTO inputs with ON CONFLICT — the database enforces single-spend atomically.
Three tiers of implementation, same interface:
Tier 1 (default): delegates to Store#find_spendable — a database query on every call. Fine for single-user, low-frequency use.
Tier 2 (pre-split): selects from a dedicated basket. Still a database query, but scoped to a smaller set with less contention.
Tier 3 (TxCache): dequeues from a pre-warmed in-memory queue. The hot path is pure memory — no database query, no lock contention, sub-millisecond latency.
Instance Method Summary collapse
-
#balance ⇒ Integer
Total available (unreserved) balance in satoshis.
-
#change_output_count ⇒ Integer
How many change outputs the next transaction should create.
-
#release(outputs:) ⇒ Object
Release outputs back to the pool after a failed or aborted action.
-
#select(satoshis:, exclude: []) ⇒ Array<Hash>
Select candidate outputs for spending.
-
#spendable_count ⇒ Integer
Number of spendable outputs currently in the pool.
Instance Method Details
#balance ⇒ Integer
Total available (unreserved) balance in satoshis.
57 58 59 |
# File 'lib/bsv/wallet/interface/utxo_pool.rb', line 57 def balance raise NotImplementedError end |
#change_output_count ⇒ Integer
How many change outputs the next transaction should create.
Uses a sizing formula to grow the pool toward a target count:
target = min(max_utxo_count, balance / min_utxo_sats)
deficit = target - spendable_count
result = clamp(deficit, 1, max_change_per_tx)
Always returns at least 1 (remainder has to go somewhere). Capped per transaction to avoid bloating any single tx.
79 80 81 |
# File 'lib/bsv/wallet/interface/utxo_pool.rb', line 79 def change_output_count raise NotImplementedError end |
#release(outputs:) ⇒ Object
Release outputs back to the pool after a failed or aborted action.
For tier 1/2: no-op — the Store’s CASCADE delete on abort frees the input rows, and the outputs were never reserved here.
For tier 3: re-enqueues outputs into the in-memory queue.
50 51 52 |
# File 'lib/bsv/wallet/interface/utxo_pool.rb', line 50 def release(outputs:) raise NotImplementedError end |
#select(satoshis:, exclude: []) ⇒ Array<Hash>
Select candidate outputs for spending.
Returns output data sufficient for transaction construction. These candidates are NOT locked — locking happens when the Store creates the action and its input rows.
For tier 3, the dequeue IS the reservation — the output leaves the in-memory queue and won’t be offered to concurrent callers.
38 39 40 |
# File 'lib/bsv/wallet/interface/utxo_pool.rb', line 38 def select(satoshis:, exclude: []) raise NotImplementedError end |
#spendable_count ⇒ Integer
Number of spendable outputs currently in the pool.
64 65 66 |
# File 'lib/bsv/wallet/interface/utxo_pool.rb', line 64 def spendable_count raise NotImplementedError end |