forked from OpenBazaar/openbazaar-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
txns.go
147 lines (138 loc) · 3.18 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
147
package db
import (
"bytes"
"database/sql"
"github.com/OpenBazaar/spvwallet"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"sync"
"time"
)
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
}
watchOnlyInt := 0
if watchOnly {
watchOnlyInt = 1
}
var buf bytes.Buffer
txn.Serialize(&buf)
_, 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, spvwallet.Txn, error) {
t.lock.Lock()
defer t.lock.Unlock()
var txn spvwallet.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 height int
var timestamp int
var value int
var watchOnlyInt int
err = stmt.QueryRow(txid.String()).Scan(&ret, &value, &height, ×tamp, &watchOnlyInt)
if err != nil {
return nil, txn, err
}
watchOnly := false
if watchOnlyInt > 0 {
watchOnly = true
}
r := bytes.NewReader(ret)
msgTx := wire.NewMsgTx(1)
msgTx.BtcDecode(r, 1)
txn = spvwallet.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) ([]spvwallet.Txn, error) {
t.lock.Lock()
defer t.lock.Unlock()
var ret []spvwallet.Txn
stm := "select tx, value, height, timestamp, watchOnly from txns"
rows, err := t.db.Query(stm)
defer rows.Close()
if err != nil {
return ret, err
}
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)
watchOnly := false
if watchOnlyInt > 0 {
if !includeWatchOnly {
continue
}
watchOnly = true
}
txn := spvwallet.Txn{msgTx.TxHash().String(), int64(value), int32(height), time.Unix(int64(timestamp), 0), watchOnly}
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) MarkAsDead(txid chainhash.Hash) 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=-1 where txid=?")
if err != nil {
return err
}
defer stmt.Close()
_, err = stmt.Exec(txid.String())
if err != nil {
tx.Rollback()
return err
}
tx.Commit()
return nil
}