multi-account: update listtransactions

This commit is contained in:
Roy Lee 2022-08-25 22:17:01 -07:00
parent 4acd03be8b
commit 2e8dcc4312
2 changed files with 20 additions and 31 deletions

View file

@ -1487,23 +1487,10 @@ func listSinceBlock(icmd interface{}, w *wallet.Wallet, chainClient *chain.RPCCl
// listTransactions handles a listtransactions request by returning an // listTransactions handles a listtransactions request by returning an
// array of maps with details of sent and recevied wallet transactions. // array of maps with details of sent and recevied wallet transactions.
func listTransactions(icmd interface{}, w *wallet.Wallet) (interface{}, error) { func listTransactions(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
cmd := icmd.(*btcjson.ListTransactionsCmd) cmd := icmd.(*btcjson.ListTransactionsCmd)
// TODO: ListTransactions does not currently understand the difference return w.ListTransactions(*cmd.Account, *cmd.From, *cmd.Count)
// 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)
} }
// listAddressTransactions handles a listaddresstransactions request by // listAddressTransactions handles a listaddresstransactions request by

View file

@ -1916,7 +1916,8 @@ func RecvCategory(details *wtxmgr.TxDetails, syncHeight int32, net *chaincfg.Par
// for a listtransactions RPC. // for a listtransactions RPC.
// //
// TODO: This should be moved to the legacyrpc package. // 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 { syncHeight int32, net *chaincfg.Params) []btcjson.ListTransactionsResult {
addrmgrNs := tx.ReadBucket(waddrmgrNamespaceKey) addrmgrNs := tx.ReadBucket(waddrmgrNamespaceKey)
@ -1977,19 +1978,22 @@ outputs:
} }
var address string var address string
var accountName string var name string
_, addrs, _, _ := txscript.ExtractPkScriptAddrs(output.PkScript, net) _, addrs, _, _ := txscript.ExtractPkScriptAddrs(output.PkScript, net)
if len(addrs) == 1 { if len(addrs) == 1 {
addr := addrs[0] addr := addrs[0]
address = addr.EncodeAddress() address = addr.EncodeAddress()
mgr, account, err := addrMgr.AddrAccount(addrmgrNs, addrs[0]) mgr, account, err := addrMgr.AddrAccount(addrmgrNs, addrs[0])
if err == nil { if err == nil {
accountName, err = mgr.AccountName(addrmgrNs, account) name, err = mgr.AccountName(addrmgrNs, account)
if err != nil { if err != nil {
accountName = "" name = ""
} }
} }
} }
if accountName != "*" && accountName != name {
continue
}
amountF64 := btcutil.Amount(output.Value).ToBTC() amountF64 := btcutil.Amount(output.Value).ToBTC()
result := btcjson.ListTransactionsResult{ result := btcjson.ListTransactionsResult{
@ -1998,7 +2002,7 @@ outputs:
// BlockIndex // BlockIndex
// //
// Fields set below: // Fields set below:
// Account (only for non-"send" categories) // Account
// Category // Category
// Amount // Amount
// Fee // Fee
@ -2025,13 +2029,14 @@ outputs:
// with debits are grouped under the send category. // with debits are grouped under the send category.
if send || spentCredit { if send || spentCredit {
result.Account = name
result.Category = "send" result.Category = "send"
result.Amount = -amountF64 result.Amount = -amountF64
result.Fee = &feeF64 result.Fee = &feeF64
results = append(results, result) results = append(results, result)
} }
if isCredit { if isCredit {
result.Account = accountName result.Account = name
result.Category = recvCat result.Category = recvCat
result.Amount = amountF64 result.Amount = amountF64
result.Fee = nil 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 // ListTransactions returns a slice of objects with details about a recorded
// transaction. This is intended to be used for listtransactions RPC // transaction. This is intended to be used for listtransactions RPC
// replies. // 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{} txList := []btcjson.ListTransactionsResult{}
err := walletdb.View(w.db, func(tx walletdb.ReadTx) error { 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 // Need to skip the first from transactions, and after those, only
// include the next count transactions. // include the next count transactions.
skipped := 0 skipped := 0
n := 0
rangeFn := func(details []wtxmgr.TxDetails) (bool, error) { rangeFn := func(details []wtxmgr.TxDetails) (bool, error) {
for _, detail := range details { for _, detail := range details {
@ -2092,18 +2096,16 @@ func (w *Wallet) ListTransactions(from, count int) ([]btcjson.ListTransactionsRe
continue continue
} }
n++ if len(txList) >= count {
if n > count { txList = txList[:count]
return true, nil return true, nil
} }
jsonResults := listTransactions(tx, &detail, jsonResults := listTransactions(accountName,
w.Manager, syncBlock.Height, w.chainParams) tx, &detail, w.Manager,
txList = append(txList, jsonResults...) syncBlock.Height, w.chainParams)
if len(jsonResults) > 0 { txList = append(txList, jsonResults...)
n++
}
} }
return false, nil return false, nil