Skip to content

Class BSV::Wallet::LocalPool

Inherits: Object Includes: BSV::Wallet::Interface::UTXOPool

In-process UTXO pool backed by the wallet's own Store.

LocalPool maintains a named basket of pre-funded outputs that callers can acquire for use as inputs in transactions. Acquired outputs are locked via lock_utxos with +no_send: true+, making them exempt from release_stale_pending! sweeps (bug #1 fix). Releasing an output returns it to :spendable state.

When the available count drops to or below the low-water mark, acquire signals the optional replenishment worker to top up the pool. The signal uses +=+ (not +<+) so the worker is triggered exactly at the boundary (bug #3 fix).

Thread safety

All public methods are safe to call concurrently. acquire holds the storage-level mutex via lock_utxos, which performs an atomic find-and-lock. The pool-level +@mutex+ guards +@state+ and +@replenisher+.

Pool basket naming

The basket name is derived as "pool:#{name}", placing all pool outputs in the structured pool: zone.

State values

status[:state] is one of:

:healthy       — pool has outputs above the low-water mark
:replenishing  — pool is below low-water mark and worker is running
:depleted      — pool is empty and worker cannot replenish
:shutdown      — pool has been shut down

Attributes

basket [R]

Returns the value of attribute basket.

name [R]

Returns the value of attribute name.

replenisher= [W]

Sets the attribute replenisher - @param value the value to set the attribute replenisher to.

storage [R]

Returns the value of attribute storage.

target_count [R]

Returns the value of attribute target_count.

target_satoshis [R]

Returns the value of attribute target_satoshis.

Public Instance Methods

acquire()

Acquires an available output from the pool and locks it.

Finds spendable outputs in the pool basket, then atomically locks the first candidate via lock_utxos with +no_send: true+. On contention (another thread claimed the output first), retries up to {UTXOPool::MAX_RETRIES} times before raising {PoolDepletedError}.

After a successful acquisition, signals the replenisher if the available count has dropped to or below the low-water mark. - @raise [PoolDepletedError] when the pool is empty or all retries fail - @return [String] the locked outpoint string ("txid.vout")

initialize(name:, storage:, wallet_client:, target_count:, target_satoshis:, low_water_mark:)

  • @param name [String] pool identifier; basket becomes "pool:#{name}"
  • @param storage [Store] wallet storage adapter
  • @param wallet_client [#create_action] wallet client for replenishment
  • @param target_count [Integer] desired number of UTXOs in the pool
  • @param target_satoshis [Integer] satoshi value per pool output
  • @param low_water_mark [Integer] available count at or below which replenishment is triggered
  • @return [LocalPool] a new instance of LocalPool

release(outpoint)

Releases a previously acquired output back to :spendable state. - @param outpoint [String] the outpoint string to release - @raise [BSV::Wallet::WalletError] if the outpoint is not found in storage - @return [void]

shutdown()

Shuts down the pool.

Stops the replenishment worker if one is running and marks the pool as :shutdown. Idempotent — safe to call more than once. - @return [void]

status()

Returns a summary of the pool's current state. - @return [Hash] status hash with keys +:available+, +:target+, +:satoshis_committed+, and +:state+