forked from OpenBazaar/openbazaar-go
-
Notifications
You must be signed in to change notification settings - Fork 3
/
txns.go
128 lines (120 loc) · 2.75 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
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) 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, tx) values(?,?,?,?,?)")
defer stmt.Close()
if err != nil {
tx.Rollback()
return err
}
var buf bytes.Buffer
txn.Serialize(&buf)
_, err = stmt.Exec(txn.TxHash().String(), value, height, int(timestamp.Unix()), 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 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
err = stmt.QueryRow(txid.String()).Scan(&ret, &value, &height, ×tamp)
if err != nil {
return nil, txn, err
}
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),
}
return msgTx, txn, nil
}
func (t *TxnsDB) GetAll() ([]spvwallet.Txn, error) {
t.lock.Lock()
defer t.lock.Unlock()
var ret []spvwallet.Txn
stm := "select tx, value, height, timestamp 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
if err := rows.Scan(&tx, &value, &height, ×tamp); err != nil {
continue
}
r := bytes.NewReader(tx)
msgTx := wire.NewMsgTx(1)
msgTx.BtcDecode(r, 1)
txn := spvwallet.Txn{msgTx.TxHash().String(), int64(value), int32(height), time.Unix(int64(timestamp), 0)}
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
}