diff --git a/cmd.go b/cmd.go index c5f39e3..0d939bb 100644 --- a/cmd.go +++ b/cmd.go @@ -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 } diff --git a/sockets.go b/sockets.go index f80745c..3e19edc 100644 --- a/sockets.go +++ b/sockets.go @@ -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 -}