-
Notifications
You must be signed in to change notification settings - Fork 0
/
balance.go
62 lines (56 loc) · 1.46 KB
/
balance.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package util
import (
"bytes"
"strconv"
wi "github.com/OpenBazaar/wallet-interface"
"github.com/btcsuite/btcd/wire"
)
func CalcBalance(utxos []wi.Utxo, txns []wi.Txn) (confirmed, unconfirmed int64) {
var txmap = make(map[string]wi.Txn)
for _, tx := range txns {
txmap[tx.Txid] = tx
}
for _, utxo := range utxos {
val, _ := strconv.ParseInt(utxo.Value, 10, 64)
if !utxo.WatchOnly {
if utxo.AtHeight > 0 {
confirmed += val
} else {
if checkIfStxoIsConfirmed(utxo.Op.Hash.String(), txmap) {
confirmed += val
} else {
unconfirmed += val
}
}
}
}
return confirmed, unconfirmed
}
func checkIfStxoIsConfirmed(txid string, txmap map[string]wi.Txn) bool {
// First look up tx and derserialize
txn, ok := txmap[txid]
if !ok {
return false
}
tx := wire.NewMsgTx(1)
rbuf := bytes.NewReader(txn.Bytes)
err := tx.BtcDecode(rbuf, wire.ProtocolVersion, wire.WitnessEncoding)
if err != nil {
return false
}
// For each input, recursively check if confirmed
inputsConfirmed := true
for _, in := range tx.TxIn {
checkTx, ok := txmap[in.PreviousOutPoint.Hash.String()]
if ok { // Is an stxo. If confirmed we can return true. If no, we need to check the dependency.
if checkTx.Height == 0 {
if !checkIfStxoIsConfirmed(in.PreviousOutPoint.Hash.String(), txmap) {
inputsConfirmed = false
}
}
} else { // We don't have the tx in our db so it can't be an stxo. Return false.
return false
}
}
return inputsConfirmed
}