LithosDocs
ProtocolPayoutsTokenStatsDocs
Start mining
Documentation home
Protocol
  • Lithos Protocol
  • LFSM
    • Rollups
    • NISPs
    • Emissions
    • Mining on Lithos
    • Candidate building
    • Ergo Voting
  • LithosDex
    • Trading with orders
    • Providing liquidity
Run Lithos
  • Startup guide
    • Setting up an Ergo testnet node
  • Configuration
    • Node connection and security
    • Stratum and difficulty
    • Block packages
    • Batching and orders
    • Collateral and emission
    • Wallet and consolidation
    • Statistics and web panels
    • Synchronization and storage
    • Tasks and dispatchers
    • Failure modes
    • Reporting issues
Client API
  • Overview
    • getLithos client information
    • getList UTXO ids for blocks
    • getUTXO ids by block height
    • getBlock info by UTXO id
    • postBlock info for multiple UTXO ids
    • getGet a block's miner set
    • getList all pool blocks
    • getGet Lithos payouts
    • getStatistics overview
    • getMining and payment totals
    • getMining statistics by hour or day
    • getEstimate Lithos hashrate
    • getNetwork difficulty by epoch
    • getThis client's own hashrate
    • getThis client's hashrate over time
    • getThis client's payouts and claims
    • getCollateral inventory
    • getLocal mining activity
    • getCollateral market snapshot
    • getList queue boxes
    • getList the active set
    • getPermit price history
    • getYour locked block rewards
    • postClaim unlocked block rewards
    • postQuote joining the queue
    • postJoin the collateral queue
    • getLithosDex pool state
    • getLithosDex fee vault state
    • getList your outstanding orders
    • postQuote a swap order
    • postPlace a swap order
    • postQuote a deposit order
    • postPlace a deposit order
    • postQuote a redeem order
    • postPlace a redeem order
    • postCancel an order
    • postQuote a swap
    • postQuote a swap by desired output
    • postExecute a swap
    • postQuote a liquidity deposit
    • postDeposit liquidity
    • postQuote a liquidity redemption
    • postRedeem liquidity
    • getList liquidity provisions
    • postClaim settled fees for a provision
    • postQuote a provision resize
    • postResize a provision
    • postCheck a pending fee flush
    • postFlush pending fees to the vault
    • getPool-wide fee history
    • getPool price history
    • getRecent pool activity
    • getFee history for one provision
    • getWallet balances and lending status
    • getGet Stratum information
    • getGet candidate settings
    • getGet difficulty commitment
    • postCommit a difficulty
    • getGet best NISP at height
Lithos

A decentralized mining pool protocol on Ergo. Miners build their own blocks; contracts pay them for proven work.

Live on Ergo mainnet
Protocol
  • How Lithos works
  • Mining on Lithos
  • NISPs
  • Emissions
  • LFSM contracts
Run Lithos
  • Startup guide
  • Configuration
  • LithosDex
  • Client API
  • Failure modes
Network
  • Live stats
  • Public stats API
  • Ergo Platform↗
  • SOAT Miner↗
Community
  • Telegram↗
  • X / Twitter↗
  • GitHub↗
Lithos
© 2026 Lithos Protocol. Open source under the MIT licence.λίθος — stone
Docs/Run Lithos/Configuration

Wallet and consolidation

How the client selects and bounds its own UTXOs, and when it merges them.

Advanced5 min readAssumes you know what a UTXO is and why a fragmented wallet is a problem.

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#

SettingDefaultRangeWhat it does
wallet.max-inputs751 to 4096Inputs one selection may take. Also the ceiling on a single consolidation
wallet.page-size5001 to 10000Boxes per node read while walking the wallet
wallet.max-input-bytes4096512 to 1048576Largest box the client will hydrate. Anything above is skipped, not fatal
wallet.max-descriptors20481 to 1000000Box descriptors held in the selection cache
wallet.max-descriptor-bytes10485761024 to 1073741824Memory that cache may occupy

A wallet of large boxes reaches the byte bound before the count bound, which is why both exist.

Timeouts#

SettingDefaultRangeWhat it does
wallet.inventory-walk-timeout-ms2400001000 to 3600000 msBudget for one whole-inventory walk
wallet.reservation-timeout-ms300001000 to 600000 msHow long a caller waits for funding
wallet.node-call-timeout-ms300001000 to 600000 msWhole-call deadline on the engine's node client, retries included
wallet.node-read-timeout-ms300001000 to 600000 msIdle-read deadline on the same client, per socket read
wallet.node-max-response-bytes209715265536 to 268435456Ceiling 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.

Warning
Three settings move together, and not in the direction people expect

node-call-timeout-ms is the one that bites a large wallet. A page of /wallet/boxes/unspent that takes longer than this fails outright, and no caller-side timeout can rescue it.

It is coupled to page-size backwards from intuition: a bigger page means fewer calls but more work per call, so raising page-size makes each call more likely to hit the timeout, and more likely to approach node-max-response-bytes as well. If you raise the page size on a slow node, raise all three.

In-flight ceilings#

SettingDefaultRangeWhat it does
wallet.max-wallet-inputs5121 to 100000Wallet inputs the engine may own at once across everything in flight
wallet.max-optional-inputs3621 to 100000, and at most max-wallet-inputsThe 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.

SettingDefaultRangeWhat it does
wallet.consolidation.enabledfalsetrue or falseRun consolidation at all
wallet.consolidation.target-utxos5001 to 2147483647Wallet size to aim for
wallet.consolidation.interval-ms3000001000 to 86400000 msShortest gap between passes
wallet.consolidation.min-inputs1002 to 4096Inputs a pass must be able to merge before it is worth a fee
wallet.consolidation.num-transactions11 to 1000Independent consolidations one pass may build
wallet.consolidation.attempt-timeout-ms30000010000 to 86400000 ms, and longer than the inventory walkHow long one pass may take end to end
wallet.consolidation.request-timeout-ms400001000 to 600000 msHow 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.

Warning
The attempt timeout must exceed the inventory walk

A pass includes a whole wallet walk, then signing, then every send. The walk alone may take inventory-walk-timeout-ms, so an attempt budget at or below that expires before it can send anything. Startup refuses the pair:

wallet.consolidation.attempt-timeout-ms
    240000 is not longer than wallet.inventory-walk-timeout-ms (240000), so a pass whose
    wallet walk takes that long expires before it can send

Next steps#

  • Collateral and emission: the work that spends what this wallet selects.
  • Synchronization and storage: the other large background subsystem.
Edit this page on GitHubsynced from e0ca86a
← PreviousCollateral and emissionNext →Statistics and web panels
On this page
  • Selection and paging
  • Timeouts
  • In-flight ceilings
  • Consolidation
  • Reducing a wallet of thousands
  • Next steps