AI-generated analysisPublished automatically and not human-verified. Validated context appears in community notes below.
← Watch feed
Moderate 60 Bitcoin

Merge bitcoin/bitcoin#35975: wallet: Fix `CWalletTx` malleated transaction metadata sync

Public commit record

What the developer wrote

Authored by merge-script

100/100 · Strong
Merge bitcoin/bitcoin#35975: wallet: Fix `CWalletTx` malleated transaction metadata sync

2c6047df8746a1d5333d17ad999dd32c40aba90e test: Bumping a transaction prevents bumping malleations (Ava Chow)
a44f9ad35058f0aa45a1cada9460f89f650ab261 test: Test rbf metadata sync of malleated tx (Ava Chow)
752fd437c7cf79f8987c556a43990c23f9a48756 wallet: persist synced metadata and do not sync on load (furszy)
31eedfc6fc8b4dbf75b9aa2b66255732c19f478b wallet: simplify wtx metadata sync (furszy)
6c16d76f790c169a6cb032b60594228c9f7af878 wallet: sync tx replacement metadata to malleated txs (furszy)
34533d5d22b635eb7529a6e457a4a62069e27909 wallet: Clarify IsEquivalentTo is actually checking malleation (Ava Chow)
b973a355c4ebd94cfa8cef61b68ac6da92fad787 Replace CTransaction::operator== with Equals that has options (Ava Chow)
2efaa6763bd210b367f4e67f67093156ef83da94 wallet: simplify and restrict SyncMetaData to malleated txs (furszy)
fc718ade4fce8003a9460e7f79a4b2a21a4dc702 test: Test that metadata is synced to malleated transactions (Ava Chow)

Pull request description:

`SyncMetaData` is intended to handle the case of malleated transactions by copying the metadata from a presumed original transaction to all of the malleations of that transaction. However, it did not do this correctly, leading to both a crash that can be reached during `bumpfee`, and failing to actually copy the metadata to some malleated transactions.

The crash was reachable by having both the original transaction and a malleation of it in the wallet, then calling `bumpfee` on the original, and then calling `bumpfee` on the malleation. Calling `bumpfee` on the malleation would result in an assertion failure in `MarkReplaced`, hitting `Assert(!wtx.m_replaced_by_txid);`. This is reached since adding the RBF to the wallet causes a metadata sync between the original and the malleation, which copies `m_replaced_by_txid`. `MarkReplaced` is called soon afterwards, resulting in the crash. This is fixed by syncing the metadata after `MarkReplaced` sets `replaced_by_txid` during the RBF of the original transaction so that `bumpfee` refuses to bump the malleation in the first place as it will check `m_replaced_by_txid` before bumping.

The other issue is that if a RBF transaction is malleated, `SyncMetaData` was not copying the metadata from the original RBF transaction to the malleation.

These are fixed by changing `SyncMetaData` to find all of the malleations of a transaction rather than all of the conflicts and simplifying how it is called. Additionally, `CWalletTx::IsEquivalentTo` is used by `SyncMetaData` to determine whether a transaction is a malleation, and this PR pulls in https://github.com/bitcoin/bitcoin/pull/32723#issuecomment-3028112892 to make it explicitly clear which fields it is actually checking to determine the equivalence. Lastly, `SyncMetaData` is renamed to `SyncMalleatedTxMetadata` and `IsEquivalntTo` renamed to `IsMalleation` to clarify that these functions are for handling malleated txs.

The last 2 commits of this PR adds tests for these cases, and the first commit a test for basic `SyncMalleatedTxMetadata` functionality that should not change here.

ACKs for top commit:
furszy:
utACK 2c6047df8746a1d5333d17ad999dd32c40aba90e
sedited:
utACK 2c6047df8746a1d5333d17ad999dd32c40aba90e

Tree-SHA512: b39e7a5804833fb43b07be1088670d5c3ff4bce6811df83a47119208789ac98f7d190053f1b5a58a4d46b877fd17f3c0c7e25e5fa7915647f340081b53700721
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Explains rationale or failure mode✓ Mentions testing or verification✓ Links an issue, advisory, or supporting reference
The short version

What changed, and why it matters

This update fixes a bug in Bitcoin Core's wallet that could crash the program when a user tried to speed up (bump) a transaction that had a slightly altered copy (a 'malleated' version) in the wallet. It also ensures that notes, replacement links, and other metadata are correctly copied between the original transaction and its malleated copies. The crash was a denial-of-service-style failure for the wallet process, not a way to steal coins, and it required the user to already have both the original and malleated transactions in their wallet.

Recommended action

Review and merge; the patch is a targeted bugfix with regression tests. Wallet operators should upgrade to a release containing this fix to avoid the bumpfee crash and ensure consistent metadata across malleated transactions. No immediate emergency response is warranted because exploitation requires the user to already possess a malleated transaction in their own wallet.

Security signals we found

01

Assertion failure / crash reachable through normal wallet RPC usage (bumpfee)

02

Incorrect metadata propagation between malleated wallet transactions

03

Race/order-of-operations issue between metadata sync and MarkReplaced

04

New explicit transaction equality helper with scriptSig/witness options to clarify malleation semantics

05

Persistence added for synced metadata via batch.WriteTxMetadata

Risk score

Why this scored 60/100

Our methodology →
Potential impact 18/30
Exploitability 12/25
Stealth signal 8/15
Affected reach 10/15
Confidence 8/10
Evidence quality 4/5
Human-validated context

Community notes

Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.

No validated notes yet.

The AI analysis stands alone for now. Submit a note if you can add evidence or important context.