Pass wallet pointer as receiver for requester funcs.

Each wallet needs its own handler running and listening to replies
from btcd, so that wallet can be synced to disk with the new tx or
utxo information.  Another rounter to map from addresses to wallets
could have been written, but we'll use the JSON Id router message
router instead.
This commit is contained in:
Josh Rickmar 2013-09-03 19:05:59 -04:00
parent 85425c2c80
commit 46077ac50a
2 changed files with 114 additions and 99 deletions

125
cmd.go
View file

@ -17,8 +17,10 @@
package main
import (
"encoding/json"
"errors"
"fmt"
"github.com/conformal/btcjson"
"github.com/conformal/btcwallet/tx"
"github.com/conformal/btcwallet/wallet"
"github.com/conformal/seelog"
@ -51,18 +53,6 @@ func main() {
}
cfg = tcfg
/*
// Open wallet
file, err := os.Open(cfg.WalletFile)
if err != nil {
log.Error("Error opening wallet:", err)
}
w := new(wallet.Wallet)
if _, err = w.ReadFrom(file); err != nil {
log.Error(err)
}
*/
// Open wallet
w, err := OpenWallet(cfg, "")
if err != nil {
@ -87,8 +77,18 @@ func main() {
type BtcWallet struct {
*wallet.Wallet
tx.UtxoStore
tx.TxStore
mtx sync.RWMutex
dirty bool
UtxoStore struct {
sync.RWMutex
dirty bool
s tx.UtxoStore
}
TxStore struct {
sync.RWMutex
dirty bool
s tx.TxStore
}
}
// walletdir returns the directory path which holds the wallet, utxo,
@ -172,10 +172,10 @@ func OpenWallet(cfg *config, account string) (*BtcWallet, error) {
}
w := &BtcWallet{
Wallet: wlt,
UtxoStore: utxos,
TxStore: txs,
Wallet: wlt,
}
w.UtxoStore.s = utxos
w.TxStore.s = txs
return w, nil
}
@ -187,4 +187,95 @@ func (w *BtcWallet) Track() {
wallets.m[name] = w
}
wallets.Unlock()
for _, addr := range w.GetActiveAddresses() {
go w.ReqUtxoForAddress(addr)
}
}
func (w *BtcWallet) RescanForAddress(addr string, blocks ...int) {
seq.Lock()
n := seq.n
seq.n++
seq.Unlock()
params := []interface{}{addr}
if len(blocks) > 0 {
params = append(params, blocks[0])
}
if len(blocks) > 1 {
params = append(params, blocks[1])
}
m := &btcjson.Message{
Jsonrpc: "1.0",
Id: fmt.Sprintf("btcwallet(%v)", n),
Method: "rescan",
Params: params,
}
msg, _ := json.Marshal(m)
replyHandlers.Lock()
replyHandlers.m[n] = func(result interface{}) bool {
// TODO(jrick)
// btcd returns a nil result when the rescan is complete.
// Returning true signals that this handler is finished
// and can be removed.
return result == nil
}
replyHandlers.Unlock()
btcdMsgs <- msg
}
func (w *BtcWallet) ReqUtxoForAddress(addr string) {
seq.Lock()
n := seq.n
seq.n++
seq.Unlock()
m := &btcjson.Message{
Jsonrpc: "1.0",
Id: fmt.Sprintf("btcwallet(%d)", n),
Method: "requestutxos",
Params: []interface{}{addr},
}
msg, _ := json.Marshal(m)
replyHandlers.Lock()
replyHandlers.m[n] = func(result interface{}) bool {
// TODO(jrick)
// Never remove this handler.
return false
}
replyHandlers.Unlock()
btcdMsgs <- msg
}
func (w *BtcWallet) ReqTxsForAddress(addr string) {
seq.Lock()
n := seq.n
seq.n++
seq.Unlock()
m := &btcjson.Message{
Jsonrpc: "1.0",
Id: fmt.Sprintf("btcwallet(%d)", n),
Method: "requesttxs",
Params: []interface{}{addr},
}
msg, _ := json.Marshal(m)
replyHandlers.Lock()
replyHandlers.m[n] = func(result interface{}) bool {
// TODO(jrick)
// Never remove this handler.
return false
}
replyHandlers.Unlock()
btcdMsgs <- msg
}

View file

@ -181,11 +181,6 @@ func BtcdHandler(ws *websocket.Conn) {
}
}()
// TODO(jrick): hook this up with addresses in wallet.
// reqTxsForAddress("addr")
reqUtxoForAddress("1PZ67BehXWbzoqkovph4Cyfiz9LiFfTUot")
for {
select {
case rply, ok := <-replies:
@ -293,12 +288,18 @@ func ProcessBtcdNotificationReply(b []byte) {
case "btcd:blockdisconnected":
// TODO(jrick): rollback txs and utxos from removed block.
// TODO(jrick): Update btcd to send back recvtx replies with the
// same id as the requester.
case "btcd:recvtx":
log.Info("got recvtx (ignoring)")
// TODO(jrick): Update btcd to send back sendtx replies with the
// same id as the requester.
case "btcd:sendtx":
log.Info("got sendtx (ignoring)")
// TODO(jrick): Update btcd to send back utxo replies with the
// same id as the requester.
case "btcd:utxo":
result := m["result"].(map[string]interface{})
spew.Dump(result)
@ -342,80 +343,3 @@ func ListenAndServe() error {
return nil
}
func reqTxsForAddress(addr string) {
for i := 0; i < 10; i++ {
seq.Lock()
n := seq.n
seq.n++
seq.Unlock()
id := fmt.Sprintf("btcwallet(%v)", n)
msg, err := btcjson.CreateMessageWithId("getblockhash", id, i)
if err != nil {
fmt.Println(msg)
panic(err)
}
replyHandlers.Lock()
replyHandlers.m[n] = func(result interface{}) bool {
fmt.Println(result)
return true
}
replyHandlers.Unlock()
btcdMsgs <- msg
}
seq.Lock()
n := seq.n
seq.n++
seq.Unlock()
m := &btcjson.Message{
Jsonrpc: "1.0",
Id: fmt.Sprintf("btcwallet(%v)", n),
Method: "rescanforutxo",
Params: []interface{}{
"17XhEvq9Nahdj7Xe1nv6oRe1tEmaHUuynH",
},
}
msg, err := json.Marshal(m)
if err != nil {
panic(err)
}
replyHandlers.Lock()
replyHandlers.m[n] = func(result interface{}) bool {
fmt.Println("result:", result)
return result == nil
}
replyHandlers.Unlock()
btcdMsgs <- msg
}
func reqUtxoForAddress(addr string) {
seq.Lock()
n := seq.n
seq.n++
seq.Unlock()
m := &btcjson.Message{
Jsonrpc: "1.0",
Id: fmt.Sprintf("btcwallet(%d)", n),
Method: "requestutxos",
Params: []interface{}{
addr,
},
}
msg, _ := json.Marshal(m)
replyHandlers.Lock()
replyHandlers.m[n] = func(result interface{}) bool {
return true
}
replyHandlers.Unlock()
btcdMsgs <- msg
}