Summary
node/utxo_db.py::coin_select() documents a fallback to largest-first when smallest-first selection uses more than 20 inputs, but the fallback still returns more than 20 inputs when the UTXOs all have the same value.
This means the heuristic does not actually reduce input count in an important edge case, so transaction construction can still emit oversized multi-input spends even though the code claims it is trying to switch to a fewer-input strategy.
Affected code
node/utxo_db.py:1444-1489
node/utxo_endpoints.py:570 (calls coin_select() directly when building wallet transfers)
Reproduction
Run this from the repo root:
python3 - <<'PY'
import sys
sys.path.insert(0, '/root/rustchain/node')
from utxo_db import coin_select
utxos = [{'value_nrtc': 1} for _ in range(25)]
selected, change = coin_select(utxos, 21)
print('selected_inputs=', len(selected))
print('change=', change)
PY
Observed output on current main:
selected_inputs= 21
change= 0
Expected behavior
If the function says it will restart with largest-first when the selection exceeds 20 inputs, the fallback should actually reduce the input count or fail cleanly for this edge case.
Actual behavior
When all UTXOs have equal value, smallest-first and largest-first produce the same ordering, so the fallback still returns 21 inputs for a 21-RTC target.
Impact
- The input-count heuristic does not work for equal-value UTXO sets.
- Wallets with many same-sized UTXOs can still produce large transactions.
- That increases transaction size and makes the intended anti-bloat guard ineffective in a common consolidation scenario.
Notes
I searched for an existing open issue for this specific coin-selection edge case and did not find one.
Summary
node/utxo_db.py::coin_select()documents a fallback to largest-first when smallest-first selection uses more than 20 inputs, but the fallback still returns more than 20 inputs when the UTXOs all have the same value.This means the heuristic does not actually reduce input count in an important edge case, so transaction construction can still emit oversized multi-input spends even though the code claims it is trying to switch to a fewer-input strategy.
Affected code
node/utxo_db.py:1444-1489node/utxo_endpoints.py:570(callscoin_select()directly when building wallet transfers)Reproduction
Run this from the repo root:
Observed output on current
main:Expected behavior
If the function says it will restart with largest-first when the selection exceeds 20 inputs, the fallback should actually reduce the input count or fail cleanly for this edge case.
Actual behavior
When all UTXOs have equal value, smallest-first and largest-first produce the same ordering, so the fallback still returns 21 inputs for a 21-RTC target.
Impact
Notes
I searched for an existing open issue for this specific coin-selection edge case and did not find one.