Skip to content

Fix transaction creation input validation and fee rate calculation - #326

Open
tvpeter wants to merge 3 commits into
bitcoindevkit:masterfrom
tvpeter:fix/create-tx-validation
Open

tvpeter wants to merge 3 commits into
bitcoindevkit:masterfrom
tvpeter:fix/create-tx-validation

Conversation

@tvpeter

@tvpeter tvpeter commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator

Description

This PR addresses input-validation problems on the transaction-building commands (create_tx, create_sp_tx, bump_fee), transaction fee rate and OP_RETURN data size:

  • Panics on malformed input: create_tx and bump_fee called .unwrap() on Results so they panic (exit 101) instead of an error (exit 1).
  • The create_sp_tx already guarded these paths, but improvements were made to the error type been returned
  • Fee rates: --fee_rate was an f32 cast with as u64, which truncates and saturates, and a None from from_sat_per_vb was silently skipped. Parsing now happens in a value_parser, so bad values are rejected with
    a usage message before a wallet is loaded. Because FeeRate counts sat/kwu, fractional rates keep 1/250 sat/vB precision instead of being truncated .
  • OP_RETURN size: Both --add_data and --add_string document "max 80 bytes" and neither enforced it. This has now been updated to 100_000 bytes and enforced in transaction building.
  • create_dns_tx was had the same fee-rate bug and the same OP_RETURN handling, and has been fixed too.
  • bump_fee --utxos and send_payjoin -f are fixed by the same changes.

Fixes #325

Notes to the reviewers

Changelog notice

  • Fixed create_tx and bump_fee panicking on malformed --utxos and --add_data values instead of returning an error
  • Fixed --fee_rate silently truncating to a whole sat/vB, falling back to a default, or producing a zero-fee transaction; unusable values are now rejected
  • Enforced the documented 100_000 byte limit on --add_data and --add_string OP_RETURN payloads

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

Bugfixes:

  • This pull request breaks the existing API
  • I've added tests to reproduce the issue which are now passing
  • I'm linking the issue being fixed by this PR

- `--fee_rate` was parsed as `f32` and cast with `as u64`, which is both
truncating and saturating, and when `FeeRate::from_sat_per_vb` returned
None the value was silently dropped. Update parsing fee_rate at the
clap boundary instead and `FeeRate` counts sat/kwu, so fractional
rates keep 1/250 sat/vB precision rather than being truncated, and
anything that cannot be represented is rejected.

- The `--add_data` and `--add_string` length was not checked. The limit
is now 99994 data bytes, Core v30's default `-datacarriersize` of
100_000 minus the 6 bytes the `OP_RETURN` opcode and `OP_PUSHDATA4`
prefix occupy, since Core measures the whole scriptPubKey.
 A unit test pins that arithmetic against `ScriptBuf::new_op_return`.
- update `create_tx`, `create_sp_tx`,` `bump_fee` commands
where `unwrap()` was called on Results and panicked.
- update fee_rate calculations accross create_tx, create_sp_tx
- update OP_RETURN data parsing accross the commands
- add test to check against panics and invalid fee_rates
- update fee_rate in dns module and payjoin
- update error propagation in dns and payjoin
- update CHANGELOG
@codecov

codecov Bot commented Sep 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 86.41975% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 58.75%. Comparing base (5afbc8a) to head (4a69235).
⚠️ Report is 3 commits behind head on master.

Files with missing lines Patch % Lines
src/handlers/offline.rs 50.00% 6 Missing ⚠️
src/handlers/dns/mod.rs 20.00% 4 Missing ⚠️
src/handlers/payjoin/mod.rs 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #326      +/-   ##
==========================================
+ Coverage   57.78%   58.75%   +0.97%     
==========================================
  Files          22       22              
  Lines        3733     3773      +40     
==========================================
+ Hits         2157     2217      +60     
+ Misses       1576     1556      -20     
Flag Coverage Δ
rust 58.75% <86.41%> (+0.97%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

create_tx panics on malformed input instead of returning an error; fee-rate parsing silently truncates or falls back

1 participant