Wallet should be able to store multiple transactions with same txid #11240

issue sdaftuar opened this issue on September 5, 2017
  1. sdaftuar commented at 4:13 PM on September 5, 2017: member

    Pre-segwit, malleated transactions would have a different txid and therefore be accepted and stored by the wallet when seen on the network.

    Post-segwit, it's possible for a malleated transaction that is seen on the network to be ignored by the wallet, because we index the wallet db by txid, and we are currently only able to store one entry for a given txid (and I have no idea whether this assumption is easy to change). This means that if a malleated transaction were mined on the network, we would only store the original version of the transaction. While this doesn't appear to have any direct impact on our wallet's behavior, this could frustrate wallet users who expect the stored transaction to be the same as the one mined.

    Within the current paradigm (of storing a single transaction per txid), we could instead store the latest seen version of any transaction, so that if a malleated version of a transaction is mined, that will get stored in our wallet and we'd forget about any previous version. However, that isn't an ideal solution either: suppose the malleated version of the transaction violates local mempool policy, and the block containing the malleated transaction gets reorged out. If the wallet would replace the non-malleated transaction with the malleated one when it was received, we'd have no way to rebroadcast the transaction again after such a reorg. And since I think losing a signed transaction (which we may not be able to reproduce) is a terrible outcome, I think we should for now continue to keep whatever original signed version of a transaction that we see, and not replace.

    Slightly relevant to this: #11225 adds the ability to replace a transaction that has no witness with one that has a witness, under the reasoning that this is only possible if we have upgraded a wallet that was pre-segwit, and are now receiving the full transaction post-upgrade. Since any transaction that is valid with a witness must be invalid under segwit's rules without the witness, doing this specific replacement should put the wallet in a strictly better position (where it might now be storing a valid transaction, which is possibly the same as the version of the transaction which was/will be mined).

  2. fanquake added the label Wallet on Sep 5, 2017
  3. furszy commented at 2:34 PM on August 23, 2022: member

    As this is still relevant, started working on it in #25909. Essentially, added coverage for the current wallet behavior and its limitations (which are the ones stated here).

    Will keep going. Next step will be the actual solution for this; add support for (a) storing all the different witness versions of single transactions or.. (b) storing multiple transactions indexed by witness id (which would duplicate information but simplify the model). In either case, proper research pending.

  4. sipa commented at 3:01 PM on April 17, 2025: member

    I think this really calls for storing up to 2 variants of each transactions: the one we expect to confirm, and optionally the one we've seen accepted in a block.

    Super hacky way of avoiding database upgrade issues: store inside the wtx record a concatenation of both serialized transactions. Old wallets (I think) will just read the first one, ignoring the second variant if any.

  5. glozow commented at 5:18 PM on April 17, 2025: member

    I think this really calls for storing up to 2 variants of each transactions: the one we expect to confirm, and optionally the one we've seen accepted in a block.

    Here, does "expect to confirm" mean the "best" or smallest size / highest feerate variant? So if "the one we've seen accepted in a block" is reorged and rejected from mempool for being nonstandard, we wouldn't try to rebroadcast that, we'd rebroadcast the "best" one.

  6. sipa commented at 5:46 PM on April 17, 2025: member

    Maybe this is clearer:

    • a. If a transaction with the same txid is in the mempool, then the wallet should store just that one.
    • b. If no transaction with the same txid is in the mempool, then the wallet should store:
      • (b.1) The version that was last in the mempool.
      • (b.2) And, if different from (b.1), the version that has been confirmed.

    If no version of the transaction has been confirmed, b.1 should be rebroadcast.


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-04-14 12:15 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me