Skip to content

Fix intermittent "fee cannot be less than vSize" errors and Firo EX address sends - #1426

Open
reubenyap wants to merge 5 commits into
cypherstack:stagingfrom
firoorg:claude/fee-vsize-consistency
Open

Fix intermittent "fee cannot be less than vSize" errors and Firo EX address sends#1426
reubenyap wants to merge 5 commits into
cypherstack:stagingfrom
firoorg:claude/fee-vsize-consistency

Conversation

@reubenyap

@reubenyap reubenyap commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Fixes intermittent fee-versus-vSize failures in legacy coin selection and restores Firo EX address sends through optimal selection.

Changes

  • Reconcile one-output, two-output, and send-all fees against the final signed vSize at the selected rate.
  • Retry fixed-amount sends with another eligible UTXO when final signing increases the required fee.
  • Return a built one-output transaction when the remaining value cannot form non-dust change.
  • Clamp server estimates to each coin's existing default and update eCash's fallback to its 1000-atom/kB relay minimum.
  • Parse Firo EX addresses consistently for selection and transaction building.
  • Keep caller-authoritative and MWEB fees unchanged.

Complementary to #1422, which fixes OP_RETURN sizing in optimal selection.

Validation

  • flutter test --no-pub test/wallets/electrumx_interface_test.dart: 4 passed.
  • flutter analyze --no-pub lib/wallets/crypto_currency/coins/ecash.dart lib/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart test/wallets/electrumx_interface_test.dart: no errors or warnings; 13 existing line-length infos.
  • dart format --output=none --set-exit-if-changed on the three analyzed files: clean.
  • git diff refs/codex/pr1426-base HEAD --check: clean.
  • flutter test --no-pub: 344 passed, 4 skipped, and 1 unrelated existing failure in create_pin_view_screen_test.dart.

A native desktop build was not completed because CMake is unavailable in the local environment.

GitHub Test run 33382300891 passed setup and changed-file formatting, then finished with 100 tests passed and 81 failed. The failures are compilation cascades because the workflow's fork fallback key stub omits four unrelated exchange constants. That workflow repair remains outside this PR.

claude and others added 5 commits August 6, 2026 12:26
The legacy fee paths estimate fees from a dummy build, then re-sign the
final transaction. Signature length can differ between signings, so the
final vSize occasionally exceeds the estimate and prepareSend throws
"Transaction fee cannot be less than vSize" at 1 sat/vB rates.

- _sendAllBuilder: apply the existing recalculate-from-final-tx loop to
  all tx types, not just mwebPegIn. Overridden and mweb/mwebPegOut fees
  (recalculated by the caller) still build once as before.
- coinSelection two-output branch: replace the one-shot vSize - fee == 1
  change adjustment with a loop that rebuilds until the fee covers the
  final signed size, dropping change and reverting to a single output
  if it would become dust.
- singleOutputTxn: report the whole input excess as the fee instead of
  the smaller rate-based estimate.
- fees getter: clamp server estimates below the coin's defaultFeeRate,
  consistent with the -1 fallback in ElectrumXClient.estimateFee, so a
  broken estimate cannot force the guard failure.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NFAYSbQoTjdbLmGwNJWzCj
_optimalCoinSelection parsed the recipient with bare
coinlib.Address.fromString, which throws on Firo EX (exchange)
addresses, so normal sends to them failed since the switch to coinlib
coin selection. Share buildTransaction's EX fallback as
_addressFromString and use it in both places.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NFAYSbQoTjdbLmGwNJWzCj
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants