forked from cpacia/BitcoinCash-Wallet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
txns.go
146 lines (138 loc) · 3.25 KB
/
txns.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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package db
import (
"bytes"
"database/sql"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"sync"
"time"
"github.com/OpenBazaar/wallet-interface"
)
type TxnsDB struct {
db *sql.DB
lock *sync.RWMutex
}
func (t *TxnsDB) Put(txn *wire.MsgTx, value, height int, timestamp time.Time, watchOnly bool) error {
t.lock.Lock()
defer t.lock.Unlock()
tx, err := t.db.Begin()
if err != nil {
return err
}
stmt, err := tx.Prepare("insert or replace into txns(txid, value, height, timestamp, watchOnly, tx) values(?,?,?,?,?,?)")
defer stmt.Close()
if err != nil {
tx.Rollback()
return err
}
var buf bytes.Buffer
txn.BtcEncode(&buf, 1, wire.BaseEncoding)
watchOnlyInt := 0
if watchOnly {
watchOnlyInt = 1
}
_, err = stmt.Exec(txn.TxHash().String(), value, height, int(timestamp.Unix()), watchOnlyInt, buf.Bytes())
if err != nil {
tx.Rollback()
return err
}
tx.Commit()
return nil
}
func (t *TxnsDB) Get(txid chainhash.Hash) (*wire.MsgTx, wallet.Txn, error) {
t.lock.RLock()
defer t.lock.RUnlock()
var txn wallet.Txn
stmt, err := t.db.Prepare("select tx, value, height, timestamp, watchOnly from txns where txid=?")
if err != nil {
return nil, txn, err
}
defer stmt.Close()
var ret []byte
var value int
var height int
var timestamp int
var watchOnlyInt int
err = stmt.QueryRow(txid.String()).Scan(&ret, &value, &height, ×tamp, &watchOnlyInt)
if err != nil {
return nil, txn, err
}
r := bytes.NewReader(ret)
msgTx := wire.NewMsgTx(1)
msgTx.BtcDecode(r, 1, wire.BaseEncoding)
watchOnly := false
if watchOnlyInt > 0 {
watchOnly = true
}
txn = wallet.Txn{
Txid: msgTx.TxHash().String(),
Value: int64(value),
Height: int32(height),
Timestamp: time.Unix(int64(timestamp), 0),
WatchOnly: watchOnly,
}
return msgTx, txn, nil
}
func (t *TxnsDB) GetAll(includeWatchOnly bool) ([]wallet.Txn, error) {
t.lock.RLock()
defer t.lock.RUnlock()
var ret []wallet.Txn
stm := "select tx, value, height, timestamp, watchOnly from txns"
rows, err := t.db.Query(stm)
if err != nil {
return ret, err
}
defer rows.Close()
for rows.Next() {
var tx []byte
var value int
var height int
var timestamp int
var watchOnlyInt int
if err := rows.Scan(&tx, &value, &height, ×tamp, &watchOnlyInt); err != nil {
continue
}
r := bytes.NewReader(tx)
msgTx := wire.NewMsgTx(1)
msgTx.BtcDecode(r, 1, wire.BaseEncoding)
watchOnly := false
if watchOnlyInt > 0 {
if !includeWatchOnly {
continue
}
watchOnly = true
}
txn := wallet.Txn{msgTx.TxHash().String(), int64(value), int32(height), time.Unix(int64(timestamp), 0), watchOnly, tx}
ret = append(ret, txn)
}
return ret, nil
}
func (t *TxnsDB) Delete(txid *chainhash.Hash) error {
t.lock.Lock()
defer t.lock.Unlock()
_, err := t.db.Exec("delete from txns where txid=?", txid.String())
if err != nil {
return err
}
return nil
}
func (t *TxnsDB) UpdateHeight(txid chainhash.Hash, height int) error {
t.lock.Lock()
defer t.lock.Unlock()
tx, err := t.db.Begin()
if err != nil {
return err
}
stmt, err := tx.Prepare("update txns set height=? where txid=?")
if err != nil {
return err
}
defer stmt.Close()
_, err = stmt.Exec(height, txid.String())
if err != nil {
tx.Rollback()
return err
}
tx.Commit()
return nil
}