From d1570c5d8718f46323a39c02495e2076741a1e39 Mon Sep 17 00:00:00 2001 From: Josh Rickmar <jrick@conformal.com> Date: Mon, 25 Nov 2013 23:50:07 -0500 Subject: [PATCH] Include more data in tx-to-wallet-address notifications. This updates the replies for rescan and tx notifications with additional information that is needed for wallet to properly support the listtransactions command. While here, drastically improve rescan performance by not looking up every sha in rescan's block range. --- rpcserver.go | 106 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 62 insertions(+), 44 deletions(-) diff --git a/rpcserver.go b/rpcserver.go index eaaf3d3fd..9f796f095 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -1225,18 +1225,13 @@ func handleRescan(s *rpcServer, cmd btcjson.Cmd, for i := range blkshalist { blk, err := s.server.db.FetchBlockBySha(&blkshalist[i]) if err != nil { + rpcsLog.Errorf("Error looking up block sha: %v", err) return err } - txShaList, err := blk.TxShas() - if err != nil { - return err - } - txList := s.server.db.FetchTxByShaList(txShaList) - for _, txReply := range txList { - if txReply.Err != nil || txReply.Tx == nil { - continue - } - for txOutIdx, txout := range txReply.Tx.TxOut { + txs := blk.Transactions() + for _, tx := range txs { + var txReply *btcdb.TxListReply + for txOutIdx, txout := range tx.MsgTx().TxOut { st, txaddrhash, err := btcscript.ScriptToAddrHash(txout.PkScript) if st != btcscript.ScriptAddr || err != nil { continue @@ -1246,27 +1241,48 @@ func handleRescan(s *rpcServer, cmd btcjson.Cmd, rpcsLog.Errorf("Error encoding address: %v", err) return err } + if _, ok := rescanCmd.Addresses[txaddr]; ok { + // TODO(jrick): This lookup is expensive and can be avoided + // if the wallet is sent the previous outpoints for all inputs + // of the tx, so any can removed from the utxo set (since + // they are, as of this tx, now spent). + if txReply == nil { + txReplyList, err := s.server.db.FetchTxBySha(tx.Sha()) + if err != nil { + rpcsLog.Errorf("Tx Sha %v not found by db.", tx.Sha()) + return err + } + for i := range txReplyList { + if txReplyList[i].Height == blk.Height() { + txReply = txReplyList[i] + break + } + } + } + reply.Result = struct { - Sender string `json:"sender"` - Receiver string `json:"receiver"` - BlockHash string `json:"blockhash"` - Height int64 `json:"height"` - TxHash string `json:"txhash"` - Index uint32 `json:"index"` - Amount int64 `json:"amount"` - PkScript string `json:"pkscript"` - Spent bool `json:"spent"` + Receiver string `json:"receiver"` + Height int64 `json:"height"` + BlockHash string `json:"blockhash"` + BlockIndex int `json:"blockindex"` + BlockTime int64 `json:"blocktime"` + TxID string `json:"txid"` + TxOutIndex uint32 `json:"txoutindex"` + Amount int64 `json:"amount"` + PkScript string `json:"pkscript"` + Spent bool `json:"spent"` }{ - Sender: "Unknown", // TODO(jrick) - Receiver: txaddr, - BlockHash: blkshalist[i].String(), - Height: blk.Height(), - TxHash: txReply.Sha.String(), - Index: uint32(txOutIdx), - Amount: txout.Value, - PkScript: btcutil.Base58Encode(txout.PkScript), - Spent: txReply.TxSpent[txOutIdx], + Receiver: txaddr, + Height: blk.Height(), + BlockHash: blkshalist[i].String(), + BlockIndex: tx.Index(), + BlockTime: blk.MsgBlock().Header.Timestamp.Unix(), + TxID: tx.Sha().String(), + TxOutIndex: uint32(txOutIdx), + Amount: txout.Value, + PkScript: btcutil.Base58Encode(txout.PkScript), + Spent: txReply.TxSpent[txOutIdx], } mreply, _ := json.Marshal(reply) walletNotification <- mreply @@ -1643,23 +1659,25 @@ func (s *rpcServer) newBlockNotifyCheckTxOut(block *btcutil.Block, } reply := &btcjson.Reply{ Result: struct { - Sender string `json:"sender"` - Receiver string `json:"receiver"` - BlockHash string `json:"blockhash"` - Height int64 `json:"height"` - TxHash string `json:"txhash"` - Index uint32 `json:"index"` - Amount int64 `json:"amount"` - PkScript string `json:"pkscript"` + Receiver string `json:"receiver"` + Height int64 `json:"height"` + BlockHash string `json:"blockhash"` + BlockIndex int `json:"blockindex"` + BlockTime int64 `json:"blocktime"` + TxID string `json:"txid"` + TxOutIndex uint32 `json:"txoutindex"` + Amount int64 `json:"amount"` + PkScript string `json:"pkscript"` }{ - Sender: "Unknown", // TODO(jrick) - Receiver: txaddr, - BlockHash: blkhash.String(), - Height: block.Height(), - TxHash: tx.Sha().String(), - Index: uint32(i), - Amount: txout.Value, - PkScript: btcutil.Base58Encode(txout.PkScript), + Receiver: txaddr, + Height: block.Height(), + BlockHash: blkhash.String(), + BlockIndex: tx.Index(), + BlockTime: block.MsgBlock().Header.Timestamp.Unix(), + TxID: tx.Sha().String(), + TxOutIndex: uint32(i), + Amount: txout.Value, + PkScript: btcutil.Base58Encode(txout.PkScript), }, Error: nil, Id: &ctx.id,