Duplicate inputs inflate sent amounts and calculated fees

Aperta
#2,288 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
3/5
Tempo stimato
1-2 giorni
Idoneità per principianti
72/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
rust
Ambito
backend

Direzione di ricerca

Inizia da crates/chain/tests/test_duplicate_inputs.rs ed esegui cargo test -p bdk_chain --test test_duplicate_inputs per riprodurre i risultati della contabilità. Traccia SpkTxOutIndex::sent_and_received, net_value, spent_txouts e IndexedTxGraph::calculate_fee per i prevouts ripetuti. L’attività è completata quando gli input duplicati non gonfiano più la contabilità né producono una fee apparentemente valida e il test di regressione passa.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

bug

Describe the bug

A transaction repeating a prevout is accepted by TxGraph, and accounting counts its value once per input. SpkTxOutIndex::sent_and_received and net_value overstate the amount sent; spent_txouts repeats the output, and calculate_fee can return a positive fee even when outputs exceed the distinct input value.

This requires a consensus-invalid transaction; it affects accounting for supplied transaction data.

This issue was found by AI.

To Reproduce

Add crates/chain/tests/test_duplicate_inputs.rs and run cargo test -p bdk_chain --test test_duplicate_inputs. These assertions demonstrate the current double-counting:

use bdk_chain::{spk_txout::SpkTxOutIndex, BlockId, IndexedTxGraph};
use bitcoin::{absolute, hashes::Hash, transaction, Amount, OutPoint, ScriptBuf,
              Transaction, TxIn, TxOut, Txid};

#[test]
fn duplicate_inputs_inflate_accounting() {
    let script = ScriptBuf::from_bytes(vec![0x51]);
    let outpoint = OutPoint::new(Txid::from_byte_array([1; 32]), 0);
    let mut graph = IndexedTxGraph::<BlockId, SpkTxOutIndex<u32>>::default();
    graph.index.insert_spk(0, script.clone());
    let _ = graph.insert_txout(outpoint, TxOut {
        value: Amount::from_sat(10_000), script_pubkey: script,
    });
    let tx = Transaction {
        version: transaction::Version::TWO,
        lock_time: absolute::LockTime::ZERO,
        input: vec![TxIn { previous_output: outpoint, ..Default::default() }; 2],
        output: vec![TxOut {
            value: Amount::from_sat(19_000), script_pubkey: ScriptBuf::new(),
        }],
    };
    let _ = graph.insert_tx(tx.clone());

    // Current behavior: the same 10,000-sat outpoint is counted twice.
    assert_eq!(graph.index.sent_and_received(&tx, ..),
               (Amount::from_sat(20_000), Amount::ZERO));
    assert_eq!(graph.index.net_value(&tx, ..).to_sat(), -20_000);
    assert_eq!(graph.index.spent_txouts(&tx).count(), 2);
    assert_eq!(graph.graph().calculate_fee(&tx), Ok(Amount::from_sat(1_000)));
}

Expected behavior

Malformed transactions with repeated prevouts should not silently produce inflated wallet accounting or a seemingly valid fee.

Lingua principale
Rust
Stelle
1.1k
Fork
491
Merge medio
1g 5h
PR unite (30g)
1

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di bitcoindevkit/bdk

Tutte le issue di bitcoindevkit/bdk

Issue simili

Altre issue su Rust

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.