Implement getreceivedbyaddress RPC.

Unlike Bitcoin Core wallet, this implementation does not ignore
coinbase transactions.
This commit is contained in:
Josh Rickmar 2014-09-02 13:54:56 -05:00
parent 7faa16c238
commit 2c52062894
2 changed files with 53 additions and 1 deletions

View file

@ -1343,6 +1343,7 @@ var rpcHandlers = map[string]requestHandler{
"getnewaddress": GetNewAddress, "getnewaddress": GetNewAddress,
"getrawchangeaddress": GetRawChangeAddress, "getrawchangeaddress": GetRawChangeAddress,
"getreceivedbyaccount": GetReceivedByAccount, "getreceivedbyaccount": GetReceivedByAccount,
"getreceivedbyaddress": GetReceivedByAddress,
"gettransaction": GetTransaction, "gettransaction": GetTransaction,
"importprivkey": ImportPrivKey, "importprivkey": ImportPrivKey,
"keypoolrefill": KeypoolRefill, "keypoolrefill": KeypoolRefill,
@ -1368,7 +1369,6 @@ var rpcHandlers = map[string]requestHandler{
// Reference implementation methods (still unimplemented) // Reference implementation methods (still unimplemented)
"backupwallet": Unimplemented, "backupwallet": Unimplemented,
"dumpwallet": Unimplemented, "dumpwallet": Unimplemented,
"getreceivedbyaddress": Unimplemented,
"getwalletinfo": Unimplemented, "getwalletinfo": Unimplemented,
"importwallet": Unimplemented, "importwallet": Unimplemented,
"listaddressgroupings": Unimplemented, "listaddressgroupings": Unimplemented,
@ -1881,6 +1881,23 @@ func GetReceivedByAccount(w *Wallet, chainSvr *chain.Client, icmd btcjson.Cmd) (
return bal.ToUnit(btcutil.AmountBTC), nil return bal.ToUnit(btcutil.AmountBTC), nil
} }
// GetReceivedByAddress handles a getreceivedbyaddress request by returning
// the total amount received by a single address.
func GetReceivedByAddress(w *Wallet, chainSvr *chain.Client, icmd btcjson.Cmd) (interface{}, error) {
cmd := icmd.(*btcjson.GetReceivedByAddressCmd)
addr, err := btcutil.DecodeAddress(cmd.Address, activeNet.Params)
if err != nil {
return nil, InvalidAddressOrKeyError{err}
}
total, err := w.TotalReceivedForAddr(addr, cmd.MinConf)
if err != nil {
return nil, err
}
return total.ToUnit(btcutil.AmountBTC), nil
}
// GetTransaction handles a gettransaction request by returning details about // GetTransaction handles a gettransaction request by returning details about
// a single transaction saved by wallet. // a single transaction saved by wallet.
func GetTransaction(w *Wallet, chainSvr *chain.Client, icmd btcjson.Cmd) (interface{}, error) { func GetTransaction(w *Wallet, chainSvr *chain.Client, icmd btcjson.Cmd) (interface{}, error) {

View file

@ -1350,6 +1350,41 @@ func (w *Wallet) TotalReceived(confirms int) (btcutil.Amount, error) {
return amount, nil return amount, nil
} }
// TotalReceivedForAddr iterates through a wallet's transaction history,
// returning the total amount of bitcoins received for a single wallet
// address.
func (w *Wallet) TotalReceivedForAddr(addr btcutil.Address, confirms int) (btcutil.Amount, error) {
bs, err := w.SyncedChainTip()
if err != nil {
return 0, err
}
addrStr := addr.EncodeAddress()
var amount btcutil.Amount
for _, r := range w.TxStore.Records() {
for _, c := range r.Credits() {
if !c.Confirmed(confirms, bs.Height) {
continue
}
_, addrs, _, err := c.Addresses(activeNet.Params)
// An error creating addresses from the output script only
// indicates a non-standard script, so ignore this credit.
if err != nil {
continue
}
for _, a := range addrs {
if addrStr == a.EncodeAddress() {
amount += c.Amount()
break
}
}
}
}
return amount, nil
}
// TxRecord iterates through all transaction records saved in the store, // TxRecord iterates through all transaction records saved in the store,
// returning the first with an equivalent transaction hash. // returning the first with an equivalent transaction hash.
func (w *Wallet) TxRecord(txSha *btcwire.ShaHash) (r *txstore.TxRecord, ok bool) { func (w *Wallet) TxRecord(txSha *btcwire.ShaHash) (r *txstore.TxRecord, ok bool) {