Fix repeated utxos (unconfirmed and confirmed) #275

This commit is contained in:
Martin Boehm 2020-01-03 11:53:49 +01:00
parent 35c9da1ce8
commit 1ed7b3f2d9

View File

@ -982,7 +982,10 @@ func (w *Worker) waitForBackendSync() {
func (w *Worker) getAddrDescUtxo(addrDesc bchain.AddressDescriptor, ba *db.AddrBalance, onlyConfirmed bool, onlyMempool bool) (Utxos, error) { func (w *Worker) getAddrDescUtxo(addrDesc bchain.AddressDescriptor, ba *db.AddrBalance, onlyConfirmed bool, onlyMempool bool) (Utxos, error) {
w.waitForBackendSync() w.waitForBackendSync()
var err error var err error
r := make(Utxos, 0, 8) utxos := make(Utxos, 0, 8)
// store txids from mempool so that they are not added twice in case of import of new block while processing utxos, issue #275
inMempool := make(map[string]struct{})
// outputs could be spent in mempool, record and check mempool spends
spentInMempool := make(map[string]struct{}) spentInMempool := make(map[string]struct{})
if !onlyConfirmed { if !onlyConfirmed {
// get utxo from mempool // get utxo from mempool
@ -1020,13 +1023,14 @@ func (w *Worker) getAddrDescUtxo(addrDesc bchain.AddressDescriptor, ba *db.AddrB
if len(bchainTx.Vin) == 1 && len(bchainTx.Vin[0].Coinbase) > 0 { if len(bchainTx.Vin) == 1 && len(bchainTx.Vin[0].Coinbase) > 0 {
coinbase = true coinbase = true
} }
r = append(r, Utxo{ utxos = append(utxos, Utxo{
Txid: bchainTx.Txid, Txid: bchainTx.Txid,
Vout: int32(i), Vout: int32(i),
AmountSat: (*Amount)(&vout.ValueSat), AmountSat: (*Amount)(&vout.ValueSat),
Locktime: bchainTx.LockTime, Locktime: bchainTx.LockTime,
Coinbase: coinbase, Coinbase: coinbase,
}) })
inMempool[bchainTx.Txid] = struct{}{}
} }
} }
} }
@ -1062,7 +1066,7 @@ func (w *Worker) getAddrDescUtxo(addrDesc bchain.AddressDescriptor, ba *db.AddrB
if !e { if !e {
confirmations := bestheight - int(utxo.Height) + 1 confirmations := bestheight - int(utxo.Height) + 1
coinbase := false coinbase := false
// for performance reasons, check coinbase transactions only in minimim confirmantion range // for performance reasons, check coinbase transactions only in minimum confirmantion range
if confirmations < w.chainParser.MinimumCoinbaseConfirmations() { if confirmations < w.chainParser.MinimumCoinbaseConfirmations() {
ta, err := w.db.GetTxAddresses(txid) ta, err := w.db.GetTxAddresses(txid)
if err != nil { if err != nil {
@ -1072,14 +1076,17 @@ func (w *Worker) getAddrDescUtxo(addrDesc bchain.AddressDescriptor, ba *db.AddrB
coinbase = true coinbase = true
} }
} }
r = append(r, Utxo{ _, e = inMempool[txid]
Txid: txid, if !e {
Vout: utxo.Vout, utxos = append(utxos, Utxo{
AmountSat: (*Amount)(&utxo.ValueSat), Txid: txid,
Height: int(utxo.Height), Vout: utxo.Vout,
Confirmations: confirmations, AmountSat: (*Amount)(&utxo.ValueSat),
Coinbase: coinbase, Height: int(utxo.Height),
}) Confirmations: confirmations,
Coinbase: coinbase,
})
}
} }
checksum.Sub(&checksum, &utxo.ValueSat) checksum.Sub(&checksum, &utxo.ValueSat)
} }
@ -1088,7 +1095,7 @@ func (w *Worker) getAddrDescUtxo(addrDesc bchain.AddressDescriptor, ba *db.AddrB
} }
} }
} }
return r, nil return utxos, nil
} }
// GetAddressUtxo returns unspent outputs for given address // GetAddressUtxo returns unspent outputs for given address