Skip to content
This repository has been archived by the owner on Mar 28, 2023. It is now read-only.

Commit

Permalink
Add and implement wallet interface method to get a transaction list
Browse files Browse the repository at this point in the history
Adds the interface method to get the transaction list and makes the necessary
changes to the spvwallet and bitcoind wallet get this list.
  • Loading branch information
cpacia committed Jan 12, 2017
1 parent 14553d0 commit 47bca52
Show file tree
Hide file tree
Showing 11 changed files with 110 additions and 43 deletions.
2 changes: 1 addition & 1 deletion Godeps/Godeps.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions api/jsonapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -1272,6 +1272,7 @@ func (i *jsonAPIHandler) GETOrder(w http.ResponseWriter, r *http.Request) {
tx := new(pb.TransactionRecord)
tx.Txid = r.Txid
tx.Value = r.Value
// TODO: add confirmations
txs = append(txs, tx)
}

Expand Down
27 changes: 25 additions & 2 deletions bitcoin/bitcoind/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,27 @@ func (w *BitcoindWallet) Balance() (confirmed, unconfirmed int64) {
return int64(c.ToUnit(btc.AmountSatoshi)), int64(u.ToUnit(btc.AmountSatoshi))
}

func (w *BitcoindWallet) Transactions() ([]spvwallet.Txn, error) {
var ret []spvwallet.Txn
resp, err := w.rpcClient.ListTransactions(Account)
if err != nil {
return ret, err
}
for _, r := range resp {
amt, err := btc.NewAmount(r.Amount)
if err != nil {
return ret, err
}
t := spvwallet.Txn{
Txid: r.TxID,
Value: int64(amt.ToUnit(btc.AmountSatoshi)),
Height: uint32(*r.BlockIndex),
}
ret = append(ret, t)
}
return ret, nil
}

func (w *BitcoindWallet) ChainTip() uint32 {
info, err := w.rpcClient.GetInfo()
if err != nil {
Expand Down Expand Up @@ -564,6 +585,8 @@ func (w *BitcoindWallet) ReSyncBlockchain(fromHeight int32) {
}

func (w *BitcoindWallet) Close() {
w.rpcClient.RawRequest("stop", []json.RawMessage{})
w.rpcClient.Shutdown()
if w.rpcClient != nil {
w.rpcClient.RawRequest("stop", []json.RawMessage{})
w.rpcClient.Shutdown()
}
}
3 changes: 3 additions & 0 deletions bitcoin/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ type BitcoinWallet interface {
// Get the confirmed and unconfirmed balances
Balance() (confirmed, unconfirmed int64)

// Returns a list of transactions for this wallet
Transactions() ([]spvwallet.Txn, error)

// Get the height of the blockchain
ChainTip() uint32

Expand Down
2 changes: 1 addition & 1 deletion repo/db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ func initDatabaseTables(db *sql.DB, password string) error {
create table keys (scriptPubKey text primary key not null, purpose integer, keyIndex integer, used integer, key text);
create table utxos (outpoint text primary key not null, value integer, height integer, scriptPubKey text, freeze int);
create table stxos (outpoint text primary key not null, value integer, height integer, scriptPubKey text, spendHeight integer, spendTxid text);
create table txns (txid text primary key not null, tx blob);
create table txns (txid text primary key not null, value integer, height integer, tx blob);
create table inventory (slug text primary key not null, count integer);
create table purchases (orderID text primary key not null, contract blob, state integer, read integer, date integer, total integer, thumbnail text, vendorID text, vendorBlockchainID text, title text, shippingName text, shippingAddress text, paymentAddr text, funded integer, transactions blob);
create index index_purchases on purchases (paymentAddr);
Expand Down
46 changes: 26 additions & 20 deletions repo/db/txns.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package db
import (
"bytes"
"database/sql"
"github.com/OpenBazaar/spvwallet"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"sync"
Expand All @@ -13,22 +14,22 @@ type TxnsDB struct {
lock sync.RWMutex
}

func (t *TxnsDB) Put(txn *wire.MsgTx) error {
func (t *TxnsDB) Put(txn *wire.MsgTx, value, height int) error {
t.lock.Lock()
defer t.lock.Unlock()
tx, err := t.db.Begin()
if err != nil {
return err
}
stmt, err := tx.Prepare("insert into txns(txid, tx) values(?,?)")
stmt, err := tx.Prepare("insert or replace into txns(txid, value, height, 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(), buf.Bytes())
_, err = stmt.Exec(txn.TxHash().String(), value, height, buf.Bytes())
if err != nil {
tx.Rollback()
return err
Expand All @@ -37,41 +38,46 @@ func (t *TxnsDB) Put(txn *wire.MsgTx) error {
return nil
}

func (t *TxnsDB) Get(txid chainhash.Hash) (*wire.MsgTx, error) {
t.lock.RLock()
defer t.lock.RUnlock()
stmt, err := t.db.Prepare("select tx from txns where txid=?")
func (t *TxnsDB) Get(txid chainhash.Hash) (*wire.MsgTx, uint32, error) {
t.lock.Lock()
defer t.lock.Unlock()
stmt, err := t.db.Prepare("select tx, height from txns where txid=?")
defer stmt.Close()
var ret []byte
err = stmt.QueryRow(txid.String()).Scan(&ret)
var height int
err = stmt.QueryRow(txid.String()).Scan(&ret, &height)
if err != nil {
return nil, err
return nil, uint32(0), err
}
r := bytes.NewReader(ret)
msgTx := wire.NewMsgTx(wire.TxVersion)
msgTx := wire.NewMsgTx(1)
msgTx.BtcDecode(r, 1)
return msgTx, nil
return msgTx, uint32(height), nil
}

func (t *TxnsDB) GetAll() ([]*wire.MsgTx, error) {
t.lock.RLock()
defer t.lock.RUnlock()
var ret []*wire.MsgTx
stm := "select tx from txns"
func (t *TxnsDB) GetAll() ([]spvwallet.Txn, error) {
t.lock.Lock()
defer t.lock.Unlock()
var ret []spvwallet.Txn
stm := "select tx, value, height from txns"
rows, err := t.db.Query(stm)
defer rows.Close()
if err != nil {
return ret, err
}
defer rows.Close()
for rows.Next() {
var tx []byte
if err := rows.Scan(&tx); err != nil {
var value int
var height int
if err := rows.Scan(&tx, &value, &height); err != nil {
continue
}
r := bytes.NewReader(tx)
msgTx := wire.NewMsgTx(wire.TxVersion)
msgTx := wire.NewMsgTx(1)
msgTx.BtcDecode(r, 1)
ret = append(ret, msgTx)

txn := spvwallet.Txn{msgTx.TxHash().String(), int64(value), uint32(height)}
ret = append(ret, txn)
}
return ret, nil
}
Expand Down
27 changes: 19 additions & 8 deletions repo/db/txns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,28 @@ func TestTxnsPut(t *testing.T) {
r := bytes.NewReader(raw)
tx.Deserialize(r)

err := txdb.Put(tx)
err := txdb.Put(tx, 5, 1)
if err != nil {
t.Error(err)
}
stmt, err := txdb.db.Prepare("select tx from txns where txid=?")
stmt, err := txdb.db.Prepare("select tx, value, height from txns where txid=?")
defer stmt.Close()
var ret []byte
err = stmt.QueryRow(tx.TxHash().String()).Scan(&ret)
var val int
var height int
err = stmt.QueryRow(tx.TxHash().String()).Scan(&ret, &val, &height)
if err != nil {
t.Error(err)
}
if hex.EncodeToString(ret) != txHex {
t.Error("Txn db put failed")
}
if val != 5 {
t.Error("Txn db failed to put value")
}
if height != 1 {
t.Error("Tns db failed to put height")
}
}

func TestTxnsGet(t *testing.T) {
Expand All @@ -48,17 +56,20 @@ func TestTxnsGet(t *testing.T) {
r := bytes.NewReader(raw)
tx.Deserialize(r)

err := txdb.Put(tx)
err := txdb.Put(tx, 0, 1)
if err != nil {
t.Error(err)
}
tx2, err := txdb.Get(tx.TxHash())
tx2, h, err := txdb.Get(tx.TxHash())
if err != nil {
t.Error(err)
}
if tx.TxHash().String() != tx2.TxHash().String() {
t.Error("Txn db get failed")
}
if h != 1 {
t.Error("Txn db failed to get height")
}
}

func TestTxnsGetAll(t *testing.T) {
Expand All @@ -68,7 +79,7 @@ func TestTxnsGetAll(t *testing.T) {
r := bytes.NewReader(raw)
tx.Deserialize(r)

err := txdb.Put(tx)
err := txdb.Put(tx, 1, 5)
if err != nil {
t.Error(err)
}
Expand All @@ -88,7 +99,7 @@ func TestDeleteTxns(t *testing.T) {
r := bytes.NewReader(raw)
tx.Deserialize(r)

err := txdb.Put(tx)
err := txdb.Put(tx, 0, 1)
if err != nil {
t.Error(err)
}
Expand All @@ -102,7 +113,7 @@ func TestDeleteTxns(t *testing.T) {
t.Error(err)
}
for _, txn := range txns {
if txn.TxHash().String() == txid.String() {
if txn.Txid == txid.String() {
t.Error("Txns db delete failed")
}
}
Expand Down
19 changes: 15 additions & 4 deletions vendor/github.com/OpenBazaar/spvwallet/datastore.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion vendor/github.com/OpenBazaar/spvwallet/eight333.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 13 additions & 5 deletions vendor/github.com/OpenBazaar/spvwallet/txstore.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion vendor/github.com/OpenBazaar/spvwallet/wallet.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 47bca52

Please sign in to comment.