wallet: allow filtering of transactions by account

This commit is contained in:
Wilmer Paulino 2021-02-17 16:24:20 -08:00
parent f5845dfb42
commit a180b0fcaa
No known key found for this signature in database
GPG key ID: 6DF57B9F9514972F
3 changed files with 15 additions and 26 deletions

View file

@ -1293,20 +1293,14 @@ func listAllTransactions(icmd interface{}, w *wallet.Wallet) (interface{}, error
func listUnspent(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
cmd := icmd.(*btcjson.ListUnspentCmd)
var addresses map[string]struct{}
if cmd.Addresses != nil {
addresses = make(map[string]struct{})
// confirm that all of them are good:
for _, as := range *cmd.Addresses {
a, err := decodeAddress(as, w.ChainParams())
if err != nil {
return nil, err
}
addresses[a.EncodeAddress()] = struct{}{}
if cmd.Addresses != nil && len(*cmd.Addresses) > 0 {
return nil, &btcjson.RPCError{
Code: btcjson.ErrRPCInvalidParameter,
Message: "Filtering by addresses has been deprecated",
}
}
return w.ListUnspent(int32(*cmd.MinConf), int32(*cmd.MaxConf), addresses)
return w.ListUnspent(int32(*cmd.MinConf), int32(*cmd.MaxConf), "")
}
// lockUnspent handles the lockunspent command.

View file

@ -408,7 +408,7 @@ func (s *walletServer) GetTransactions(ctx context.Context, req *pb.GetTransacti
_ = minRecentTxs
gtr, err := s.wallet.GetTransactions(startBlock, endBlock, ctx.Done())
gtr, err := s.wallet.GetTransactions(startBlock, endBlock, "", ctx.Done())
if err != nil {
return nil, translateError(err)
}

View file

@ -2186,7 +2186,9 @@ type GetTransactionsResult struct {
// Transaction results are organized by blocks in ascending order and unmined
// transactions in an unspecified order. Mined transactions are saved in a
// Block structure which records properties about the block.
func (w *Wallet) GetTransactions(startBlock, endBlock *BlockIdentifier, cancel <-chan struct{}) (*GetTransactionsResult, error) {
func (w *Wallet) GetTransactions(startBlock, endBlock *BlockIdentifier,
accountName string, cancel <-chan struct{}) (*GetTransactionsResult, error) {
var start, end int32 = 0, -1
w.chainClientLock.Lock()
@ -2508,7 +2510,7 @@ func (s creditSlice) Swap(i, j int) {
// contained within it will be considered. If we know nothing about a
// transaction an empty array will be returned.
func (w *Wallet) ListUnspent(minconf, maxconf int32,
addresses map[string]struct{}) ([]*btcjson.ListUnspentResult, error) {
accountName string) ([]*btcjson.ListUnspentResult, error) {
var results []*btcjson.ListUnspentResult
err := walletdb.View(w.db, func(tx walletdb.ReadTx) error {
@ -2517,7 +2519,7 @@ func (w *Wallet) ListUnspent(minconf, maxconf int32,
syncBlock := w.Manager.SyncedTo()
filter := len(addresses) != 0
filter := accountName != ""
unspent, err := w.TxStore.UnspentOutputs(txmgrNs)
if err != nil {
return err
@ -2556,7 +2558,7 @@ func (w *Wallet) ListUnspent(minconf, maxconf int32,
//
// This will be unnecessary once transactions and outputs are
// grouped under the associated account in the db.
acctName := defaultAccountName
outputAcctName := defaultAccountName
sc, addrs, _, err := txscript.ExtractPkScriptAddrs(
output.PkScript, w.chainParams)
if err != nil {
@ -2567,22 +2569,15 @@ func (w *Wallet) ListUnspent(minconf, maxconf int32,
if err == nil {
s, err := smgr.AccountName(addrmgrNs, acct)
if err == nil {
acctName = s
outputAcctName = s
}
}
}
if filter {
for _, addr := range addrs {
_, ok := addresses[addr.EncodeAddress()]
if ok {
goto include
}
}
if filter && outputAcctName != accountName {
continue
}
include:
// At the moment watch-only addresses are not supported, so all
// recorded outputs that are not multisig are "spendable".
// Multisig outputs are only "spendable" if all keys are
@ -2622,7 +2617,7 @@ func (w *Wallet) ListUnspent(minconf, maxconf int32,
result := &btcjson.ListUnspentResult{
TxID: output.OutPoint.Hash.String(),
Vout: output.OutPoint.Index,
Account: acctName,
Account: outputAcctName,
ScriptPubKey: hex.EncodeToString(output.PkScript),
Amount: output.Amount.ToBTC(),
Confirmations: int64(confs),