Class: BSV::Wallet::Postgres::UTXOPool
- Inherits:
-
Object
- Object
- BSV::Wallet::Postgres::UTXOPool
- Includes:
- Interface::UTXOPool
- Defined in:
- lib/bsv/wallet/postgres/utxo_pool.rb
Overview
Tier 1 UTXO selection — delegates to Store#find_spendable.
No reservation at this tier. Locking happens in Store#create_action via the input row INSERT ON CONFLICT.
Constant Summary collapse
- MAX_UTXO_COUNT =
500- MIN_UTXO_SATS =
1000- MAX_CHANGE_PER_TX =
8
Instance Method Summary collapse
- #balance ⇒ Object
- #change_output_count ⇒ Object
-
#initialize(store:, max_utxo_count: MAX_UTXO_COUNT, min_utxo_sats: MIN_UTXO_SATS, max_change_per_tx: MAX_CHANGE_PER_TX) ⇒ UTXOPool
constructor
A new instance of UTXOPool.
- #release(outputs:) ⇒ Object
- #select(satoshis:, exclude: []) ⇒ Object
- #spendable_count ⇒ Object
Constructor Details
#initialize(store:, max_utxo_count: MAX_UTXO_COUNT, min_utxo_sats: MIN_UTXO_SATS, max_change_per_tx: MAX_CHANGE_PER_TX) ⇒ UTXOPool
Returns a new instance of UTXOPool.
17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/bsv/wallet/postgres/utxo_pool.rb', line 17 def initialize(store:, max_utxo_count: MAX_UTXO_COUNT, min_utxo_sats: MIN_UTXO_SATS, max_change_per_tx: MAX_CHANGE_PER_TX) raise ArgumentError, 'max_utxo_count must be >= 1' unless max_utxo_count >= 1 raise ArgumentError, 'min_utxo_sats must be positive' unless min_utxo_sats.positive? raise ArgumentError, 'max_change_per_tx must be >= 1' unless max_change_per_tx >= 1 @store = store @max_utxo_count = max_utxo_count @min_utxo_sats = min_utxo_sats @max_change_per_tx = max_change_per_tx end |
Instance Method Details
#balance ⇒ Object
42 43 44 |
# File 'lib/bsv/wallet/postgres/utxo_pool.rb', line 42 def balance (Output.spendable.sum(:satoshis) || 0).to_i end |
#change_output_count ⇒ Object
50 51 52 53 54 |
# File 'lib/bsv/wallet/postgres/utxo_pool.rb', line 50 def change_output_count target = [@max_utxo_count, balance / @min_utxo_sats].min deficit = target - spendable_count deficit.clamp(1, @max_change_per_tx) end |
#release(outputs:) ⇒ Object
38 39 40 |
# File 'lib/bsv/wallet/postgres/utxo_pool.rb', line 38 def release(outputs:) # No-op for tier 1 — CASCADE handles it end |
#select(satoshis:, exclude: []) ⇒ Object
30 31 32 33 34 35 36 |
# File 'lib/bsv/wallet/postgres/utxo_pool.rb', line 30 def select(satoshis:, exclude: []) candidates = @store.find_spendable(satoshis: satoshis, exclude: exclude) total = candidates.sum { |c| c[:satoshis] } raise BSV::Wallet::PoolDepletedError, 'default' if total < satoshis candidates end |
#spendable_count ⇒ Object
46 47 48 |
# File 'lib/bsv/wallet/postgres/utxo_pool.rb', line 46 def spendable_count Output.spendable.count end |