Describe the bug
Duplicate inputs are handled differently depending on whether the bitcoinkernel feature is enabled.
With bitcoinkernel enabled, duplicate inputs are naturally rejected because spent UTXOs are removed from the map during script verification. However, in the default non-bitcoinkernel path, verify_transaction() validates inputs using get_utxo(), which only performs a .get() lookup and does not consume the entry.
This means the same OutPoint can be referenced multiple times within the same transaction and its value counted multiple times toward in_value.
Steps to Reproduce
- Build Floresta without the
bitcoinkernel feature enabled
- Construct a transaction containing two identical inputs spending the same
OutPoint
- Pass the transaction through
verify_transaction()
- Observe that both inputs successfully fetch the same UTXO through
get_utxo()
Expected behavior
Duplicate inputs should be rejected consistently across all build configurations, matching Bitcoin Core's CheckTransaction() behavior for duplicate input handling (CVE-2018-17144).
Build environment
master branch, non-bitcoinkernel build
Additional context
Relevant code paths:
Non-bitcoinkernel path:
let utxo = Self::get_utxo(input, utxos, txid)?;
match utxos.get(&input.previous_output)
bitcoinkernel path:
utxos.remove(&input.previous_output)
There are currently two possible approaches being discussed:
- Add explicit duplicate input detection in
check_transaction_context_free()
- Change the non-
bitcoinkernel path to consume UTXOs with .remove() instead of .get()
This was identified and discussed in PR #979.
Describe the bug
Duplicate inputs are handled differently depending on whether the
bitcoinkernelfeature is enabled.With
bitcoinkernelenabled, duplicate inputs are naturally rejected because spent UTXOs are removed from the map during script verification. However, in the default non-bitcoinkernelpath,verify_transaction()validates inputs usingget_utxo(), which only performs a.get()lookup and does not consume the entry.This means the same
OutPointcan be referenced multiple times within the same transaction and its value counted multiple times towardin_value.Steps to Reproduce
bitcoinkernelfeature enabledOutPointverify_transaction()get_utxo()Expected behavior
Duplicate inputs should be rejected consistently across all build configurations, matching Bitcoin Core's
CheckTransaction()behavior for duplicate input handling (CVE-2018-17144).Build environment
master branch, non-bitcoinkernel buildAdditional context
Relevant code paths:
Non-
bitcoinkernelpath:bitcoinkernelpath:There are currently two possible approaches being discussed:
check_transaction_context_free()bitcoinkernelpath to consume UTXOs with.remove()instead of.get()This was identified and discussed in PR #979.