Skip to content

bitcoin: add sign-only and getrawtransaction RPCs - #279

Merged
morehouse merged 3 commits into
lnfuzz:masterfrom
erickcestari:bitcoin-raw-tx-rpcs
Oct 15, 2026
Merged

morehouse merged 3 commits into
lnfuzz:masterfrom
erickcestari:bitcoin-raw-tx-rpcs

Conversation

@erickcestari

Copy link
Copy Markdown
Member

Channel establishment v2 needs the previous transaction bytes for tx_add_input and our own witnesses for tx_signatures, which the wallet can only produce as a partial signing of the shared transaction.

This is part of breaking down PR #239 into smaller PRs to make them easier to review.

Comment thread smite/src/bitcoin.rs Outdated
let signed = self
.sign_raw_transaction_with_wallet(tx)
.inspect_err(|stderr| {
log::debug!("bitcoin-cli signrawtransactionwithwallet failed: {stderr}");

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Under what circumstances would we expect an error?

Should we still panic for errors that are unexpected?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It only makes sense for the interactive-tx. Since the fuzzer and target might build invalid transactions that we can't sign. E.g a transaction without any input.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I asked Claude under what circumstances signrawtransactionwithwallet can return an error, and it gave me this table.

┌─────────────────────────────────────────────┬──────────────────────────────────────────────────────────────────────────────┐
│                    Error                    │                              Can smite hit it?                               │
├─────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────────┤
│ GetWalletForJSONRPCRequest: no wallet       │                                                                              │
│ loaded, or several loaded without           │ Only if the environment is broken                                            │
│ -rpcwallet                                  │                                                                              │
├─────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────────┤
│ DecodeHexTx fails ("TX decode failed. Make  │ Only with zero inputs. rust-bitcoin always produces a valid serialization;   │
│ sure the tx has at least one input.")       │ with zero inputs it adds a segwit marker but no witnesses, which Core        │
│                                             │ rejects as "Superfluous witness record"                                      │
├─────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────────┤
│ EnsureWalletIsUnlocked                      │ No, the wallet isn't encrypted                                               │
├─────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────────┤
│ ParsePrevouts / ParseSighashString          │ No, smite passes neither argument                                            │
├─────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────────┤
│ "Missing amount" (the one per-input error   │ No. It needs amount == MAX_MONEY, which only happens when prevtxs is passed  │
│ that becomes an RPC error)                  │ without an amount (rawtransaction_util.cpp:244)                              │
├─────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────────┤
│ bitcoind down, still starting up, or        │ Only if the environment is broken                                            │
│ failing auth                                │                                                                              │
└─────────────────────────────────────────────┴──────────────────────────────────────────────────────────────────────────────┘

The only one I can imagine us hitting is "zero inputs". But even then it seems like something we shouldn't ever hit unless there's a bug in smite.

  • splicing always has the funding input
  • for dual funding smite should only ever do the RPC if it added its own input, otherwise there's no reason to sign. And if the target allowed this, it seems like a bug we should detect and report early, before we ever try to sign.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. We can check it before calling the RPC. I've updated the code to panic.

Comment thread smite/src/bitcoin.rs Outdated
Lets a sign-only caller that does not require complete signing reuse it.
Channel establishment v2 needs our own witnesses for tx_signatures, which
the wallet can only produce as a partial signing of the shared
transaction.
Channel establishment v2 needs the previous transaction bytes for
tx_add_input's prevtx.

@morehouse morehouse left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@morehouse
morehouse merged commit 58b3046 into lnfuzz:master Oct 15, 2026
5 checks passed
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