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.
This commit is contained in:
Josh Rickmar 2013-11-25 23:50:07 -05:00
parent dfbb9446c4
commit d1570c5d87

View File

@ -1225,18 +1225,13 @@ func handleRescan(s *rpcServer, cmd btcjson.Cmd,
for i := range blkshalist { for i := range blkshalist {
blk, err := s.server.db.FetchBlockBySha(&blkshalist[i]) blk, err := s.server.db.FetchBlockBySha(&blkshalist[i])
if err != nil { if err != nil {
rpcsLog.Errorf("Error looking up block sha: %v", err)
return err return err
} }
txShaList, err := blk.TxShas() txs := blk.Transactions()
if err != nil { for _, tx := range txs {
return err var txReply *btcdb.TxListReply
} for txOutIdx, txout := range tx.MsgTx().TxOut {
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 {
st, txaddrhash, err := btcscript.ScriptToAddrHash(txout.PkScript) st, txaddrhash, err := btcscript.ScriptToAddrHash(txout.PkScript)
if st != btcscript.ScriptAddr || err != nil { if st != btcscript.ScriptAddr || err != nil {
continue continue
@ -1246,27 +1241,48 @@ func handleRescan(s *rpcServer, cmd btcjson.Cmd,
rpcsLog.Errorf("Error encoding address: %v", err) rpcsLog.Errorf("Error encoding address: %v", err)
return err return err
} }
if _, ok := rescanCmd.Addresses[txaddr]; ok { 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 { reply.Result = struct {
Sender string `json:"sender"` Receiver string `json:"receiver"`
Receiver string `json:"receiver"` Height int64 `json:"height"`
BlockHash string `json:"blockhash"` BlockHash string `json:"blockhash"`
Height int64 `json:"height"` BlockIndex int `json:"blockindex"`
TxHash string `json:"txhash"` BlockTime int64 `json:"blocktime"`
Index uint32 `json:"index"` TxID string `json:"txid"`
Amount int64 `json:"amount"` TxOutIndex uint32 `json:"txoutindex"`
PkScript string `json:"pkscript"` Amount int64 `json:"amount"`
Spent bool `json:"spent"` PkScript string `json:"pkscript"`
Spent bool `json:"spent"`
}{ }{
Sender: "Unknown", // TODO(jrick) Receiver: txaddr,
Receiver: txaddr, Height: blk.Height(),
BlockHash: blkshalist[i].String(), BlockHash: blkshalist[i].String(),
Height: blk.Height(), BlockIndex: tx.Index(),
TxHash: txReply.Sha.String(), BlockTime: blk.MsgBlock().Header.Timestamp.Unix(),
Index: uint32(txOutIdx), TxID: tx.Sha().String(),
Amount: txout.Value, TxOutIndex: uint32(txOutIdx),
PkScript: btcutil.Base58Encode(txout.PkScript), Amount: txout.Value,
Spent: txReply.TxSpent[txOutIdx], PkScript: btcutil.Base58Encode(txout.PkScript),
Spent: txReply.TxSpent[txOutIdx],
} }
mreply, _ := json.Marshal(reply) mreply, _ := json.Marshal(reply)
walletNotification <- mreply walletNotification <- mreply
@ -1643,23 +1659,25 @@ func (s *rpcServer) newBlockNotifyCheckTxOut(block *btcutil.Block,
} }
reply := &btcjson.Reply{ reply := &btcjson.Reply{
Result: struct { Result: struct {
Sender string `json:"sender"` Receiver string `json:"receiver"`
Receiver string `json:"receiver"` Height int64 `json:"height"`
BlockHash string `json:"blockhash"` BlockHash string `json:"blockhash"`
Height int64 `json:"height"` BlockIndex int `json:"blockindex"`
TxHash string `json:"txhash"` BlockTime int64 `json:"blocktime"`
Index uint32 `json:"index"` TxID string `json:"txid"`
Amount int64 `json:"amount"` TxOutIndex uint32 `json:"txoutindex"`
PkScript string `json:"pkscript"` Amount int64 `json:"amount"`
PkScript string `json:"pkscript"`
}{ }{
Sender: "Unknown", // TODO(jrick) Receiver: txaddr,
Receiver: txaddr, Height: block.Height(),
BlockHash: blkhash.String(), BlockHash: blkhash.String(),
Height: block.Height(), BlockIndex: tx.Index(),
TxHash: tx.Sha().String(), BlockTime: block.MsgBlock().Header.Timestamp.Unix(),
Index: uint32(i), TxID: tx.Sha().String(),
Amount: txout.Value, TxOutIndex: uint32(i),
PkScript: btcutil.Base58Encode(txout.PkScript), Amount: txout.Value,
PkScript: btcutil.Base58Encode(txout.PkScript),
}, },
Error: nil, Error: nil,
Id: &ctx.id, Id: &ctx.id,