diff --git a/rpc/legacyrpc/methods.go b/rpc/legacyrpc/methods.go index 82bd50c..91daa2b 100644 --- a/rpc/legacyrpc/methods.go +++ b/rpc/legacyrpc/methods.go @@ -1487,23 +1487,10 @@ func listSinceBlock(icmd interface{}, w *wallet.Wallet, chainClient *chain.RPCCl // listTransactions handles a listtransactions request by returning an // array of maps with details of sent and recevied wallet transactions. func listTransactions(icmd interface{}, w *wallet.Wallet) (interface{}, error) { + cmd := icmd.(*btcjson.ListTransactionsCmd) - // TODO: ListTransactions does not currently understand the difference - // between transactions pertaining to one account from another. This - // will be resolved when wtxmgr is combined with the waddrmgr namespace. - - if cmd.Account != nil && *cmd.Account != "*" && *cmd.Account != "default" { - // For now, don't bother trying to continue if the user - // specified an account, since this can't be (easily or - // efficiently) calculated. - return nil, &btcjson.RPCError{ - Code: btcjson.ErrRPCWallet, - Message: "Transactions are not yet grouped by account", - } - } - - return w.ListTransactions(*cmd.From, *cmd.Count) + return w.ListTransactions(*cmd.Account, *cmd.From, *cmd.Count) } // listAddressTransactions handles a listaddresstransactions request by diff --git a/wallet/wallet.go b/wallet/wallet.go index fed3eae..12d0f13 100644 --- a/wallet/wallet.go +++ b/wallet/wallet.go @@ -1916,7 +1916,8 @@ func RecvCategory(details *wtxmgr.TxDetails, syncHeight int32, net *chaincfg.Par // for a listtransactions RPC. // // TODO: This should be moved to the legacyrpc package. -func listTransactions(tx walletdb.ReadTx, details *wtxmgr.TxDetails, addrMgr *waddrmgr.Manager, +func listTransactions(accountName string, tx walletdb.ReadTx, + details *wtxmgr.TxDetails, addrMgr *waddrmgr.Manager, syncHeight int32, net *chaincfg.Params) []btcjson.ListTransactionsResult { addrmgrNs := tx.ReadBucket(waddrmgrNamespaceKey) @@ -1977,19 +1978,22 @@ outputs: } var address string - var accountName string + var name string _, addrs, _, _ := txscript.ExtractPkScriptAddrs(output.PkScript, net) if len(addrs) == 1 { addr := addrs[0] address = addr.EncodeAddress() mgr, account, err := addrMgr.AddrAccount(addrmgrNs, addrs[0]) if err == nil { - accountName, err = mgr.AccountName(addrmgrNs, account) + name, err = mgr.AccountName(addrmgrNs, account) if err != nil { - accountName = "" + name = "" } } } + if accountName != "*" && accountName != name { + continue + } amountF64 := btcutil.Amount(output.Value).ToBTC() result := btcjson.ListTransactionsResult{ @@ -1998,7 +2002,7 @@ outputs: // BlockIndex // // Fields set below: - // Account (only for non-"send" categories) + // Account // Category // Amount // Fee @@ -2025,13 +2029,14 @@ outputs: // with debits are grouped under the send category. if send || spentCredit { + result.Account = name result.Category = "send" result.Amount = -amountF64 result.Fee = &feeF64 results = append(results, result) } if isCredit { - result.Account = accountName + result.Account = name result.Category = recvCat result.Amount = amountF64 result.Fee = nil @@ -2070,7 +2075,7 @@ func (w *Wallet) ListSinceBlock(start, end, syncHeight int32) ([]btcjson.ListTra // ListTransactions returns a slice of objects with details about a recorded // transaction. This is intended to be used for listtransactions RPC // replies. -func (w *Wallet) ListTransactions(from, count int) ([]btcjson.ListTransactionsResult, error) { +func (w *Wallet) ListTransactions(accountName string, from, count int) ([]btcjson.ListTransactionsResult, error) { txList := []btcjson.ListTransactionsResult{} err := walletdb.View(w.db, func(tx walletdb.ReadTx) error { @@ -2083,7 +2088,6 @@ func (w *Wallet) ListTransactions(from, count int) ([]btcjson.ListTransactionsRe // Need to skip the first from transactions, and after those, only // include the next count transactions. skipped := 0 - n := 0 rangeFn := func(details []wtxmgr.TxDetails) (bool, error) { for _, detail := range details { @@ -2092,18 +2096,16 @@ func (w *Wallet) ListTransactions(from, count int) ([]btcjson.ListTransactionsRe continue } - n++ - if n > count { + if len(txList) >= count { + txList = txList[:count] return true, nil } - jsonResults := listTransactions(tx, &detail, - w.Manager, syncBlock.Height, w.chainParams) - txList = append(txList, jsonResults...) + jsonResults := listTransactions(accountName, + tx, &detail, w.Manager, + syncBlock.Height, w.chainParams) - if len(jsonResults) > 0 { - n++ - } + txList = append(txList, jsonResults...) } return false, nil