Wallet and consolidation
How the client selects and bounds its own UTXOs, and when it merges them.
The wallet block controls how the client reads your node wallet, how many boxes it may hold in
flight, and whether it merges small boxes back together. These knobs help control how your wallet is used in the client,
and how to deal with UTXO growth inside of it. A miner with a fragmented wallet wants
different behaviour from one with a handful of large boxes.
Every default reproduces the constant it replaced, so leaving the block out changes nothing.
Selection and paging#
| Setting | Default | Range | What it does |
|---|---|---|---|
wallet.max-inputs | 75 | 1 to 4096 | Inputs one selection may take. Also the ceiling on a single consolidation |
wallet.page-size | 500 | 1 to 10000 | Boxes per node read while walking the wallet |
wallet.max-input-bytes | 4096 | 512 to 1048576 | Largest box the client will hydrate. Anything above is skipped, not fatal |
wallet.max-descriptors | 2048 | 1 to 1000000 | Box descriptors held in the selection cache |
wallet.max-descriptor-bytes | 1048576 | 1024 to 1073741824 | Memory that cache may occupy |
A wallet of large boxes reaches the byte bound before the count bound, which is why both exist.
Timeouts#
| Setting | Default | Range | What it does |
|---|---|---|---|
wallet.inventory-walk-timeout-ms | 240000 | 1000 to 3600000 ms | Budget for one whole-inventory walk |
wallet.reservation-timeout-ms | 30000 | 1000 to 600000 ms | How long a caller waits for funding |
wallet.node-call-timeout-ms | 30000 | 1000 to 600000 ms | Whole-call deadline on the engine's node client, retries included |
wallet.node-read-timeout-ms | 30000 | 1000 to 600000 ms | Idle-read deadline on the same client, per socket read |
wallet.node-max-response-bytes | 2097152 | 65536 to 268435456 | Ceiling on one node response |
An inventory walk fails rather than returning a prefix. A partial answer would misreport what the wallet holds, and consolidation would then act on the wrong total.
Funding is serialised on one thread, so reservation-timeout-ms bounds the queue behind a slow node
read rather than the read itself. Raise it before raising the pool if joins are timing out on a busy
node.
In-flight ceilings#
| Setting | Default | Range | What it does |
|---|---|---|---|
wallet.max-wallet-inputs | 512 | 1 to 100000 | Wallet inputs the engine may own at once across everything in flight |
wallet.max-optional-inputs | 362 | 1 to 100000, and at most max-wallet-inputs | The share of that which optional work may take |
The gap between them is deliberate and it is a reserve. The default of 362 is exactly two full
transactions' worth below the ceiling, at 512 - 2 × 75.
That reserve is what a NISP submission or a fraud proof funds itself from while the optional queue is saturated. Without it a long consolidation pass could hold every input the engine owns, and a submission would find nothing to fund a bond with.
Startup refuses max-optional-inputs above max-wallet-inputs and says so. Raising the optional share
is what lets a big consolidation pass hold more boxes at once, so raise max-wallet-inputs alongside
it or the reserve for critical work shrinks.
Consolidation#
Consolidation merges your own wallet boxes back together. It ships off, because a miner who never fragments their wallet gains nothing from it.
| Setting | Default | Range | What it does |
|---|---|---|---|
wallet.consolidation.enabled | false | true or false | Run consolidation at all |
wallet.consolidation.target-utxos | 500 | 1 to 2147483647 | Wallet size to aim for |
wallet.consolidation.interval-ms | 300000 | 1000 to 86400000 ms | Shortest gap between passes |
wallet.consolidation.min-inputs | 100 | 2 to 4096 | Inputs a pass must be able to merge before it is worth a fee |
wallet.consolidation.num-transactions | 1 | 1 to 1000 | Independent consolidations one pass may build |
wallet.consolidation.attempt-timeout-ms | 300000 | 10000 to 86400000 ms, and longer than the inventory walk | How long one pass may take end to end |
wallet.consolidation.request-timeout-ms | 40000 | 1000 to 600000 ms | How long a pass waits on the engine |
Above target-utxos one pass merges the excess. At or below it nothing happens.
It is the lowest-priority work the engine does. It runs only when nothing else is in flight, so
interval-ms is a floor rather than a schedule, and a busy client may go much longer between passes.
min-inputs exists because merging two boxes pays a fee to remove one box. Anything below the floor is
not worth building.
Reducing a wallet of thousands#
One transaction removes at most max-inputs - 1 boxes, which is 74 at the defaults. A wallet of
several thousand boxes would take many passes at one transaction each.
num-transactions is the lever. Each consolidation spends its own boxes and pays its own fee, and
they do not chain, so a rejection costs only its own transaction rather than invalidating the rest.
Next steps#
- Collateral and emission: the work that spends what this wallet selects.
- Synchronization and storage: the other large background subsystem.