Skip to content

[bug]: /v1/transactions doesn't work when adding filter param account #9664

Description

@zaneatbp

Background

I'm trying to filter the transactions that are only relevant to an account...

Your environment

  • lnd 0.18.5
  • Mac OS
  • bitcoind
  • any other relevant environment details

Steps to reproduce

Do this following steps in the polar environment:

step1 import an account into LND with /v2/wallet/accounts/import let's name this account A, and then create an p2tr address
step2: send 0.1 BTC to account A's p2tr address
step3: try to filter account A's transactions with https://lightning.engineering/api-docs/api/lnd/lightning/get-transactions/ and set the query parameters as : /v1/transactions?account=A&
and then send the request, we can get a reponse contains one transaction
step4: change the query paramter account to B、C、D or any other values, we can still get the same response with step3.

I invistigated into the source code, and found the in the 2411 line of the file wallet.go, which is in the btcsuit/btcwallet lib, the following method doesn't use accountName parameter at all.

`func (w *Wallet) GetTransactions(startBlock, endBlock *BlockIdentifier,
accountName string, cancel <-chan struct{}) (*GetTransactionsResult, error) {

var start, end int32 = 0, -1

w.chainClientLock.Lock()
chainClient := w.chainClient
w.chainClientLock.Unlock()

// TODO: Fetching block heights by their hashes is inherently racy
// because not all block headers are saved but when they are for SPV the
// db can be queried directly without this.
if startBlock != nil {
	if startBlock.hash == nil {
		start = startBlock.height
	} else {
		if chainClient == nil {
			return nil, errors.New("no chain server client")
		}
		switch client := chainClient.(type) {
		case *chain.RPCClient:
			startHeader, err := client.GetBlockHeaderVerbose(
				startBlock.hash,
			)
			if err != nil {
				return nil, err
			}
			start = startHeader.Height
		case *chain.BitcoindClient:
			var err error
			start, err = client.GetBlockHeight(startBlock.hash)
			if err != nil {
				return nil, err
			}
		case *chain.NeutrinoClient:
			var err error
			start, err = client.GetBlockHeight(startBlock.hash)
			if err != nil {
				return nil, err
			}
		}
	}
}
if endBlock != nil {
	if endBlock.hash == nil {
		end = endBlock.height
	} else {
		if chainClient == nil {
			return nil, errors.New("no chain server client")
		}
		switch client := chainClient.(type) {
		case *chain.RPCClient:
			endHeader, err := client.GetBlockHeaderVerbose(
				endBlock.hash,
			)
			if err != nil {
				return nil, err
			}
			end = endHeader.Height
		case *chain.BitcoindClient:
			var err error
			start, err = client.GetBlockHeight(endBlock.hash)
			if err != nil {
				return nil, err
			}
		case *chain.NeutrinoClient:
			var err error
			end, err = client.GetBlockHeight(endBlock.hash)
			if err != nil {
				return nil, err
			}
		}
	}
}

var res GetTransactionsResult
err := walletdb.View(w.db, func(dbtx walletdb.ReadTx) error {
	txmgrNs := dbtx.ReadBucket(wtxmgrNamespaceKey)

	rangeFn := func(details []wtxmgr.TxDetails) (bool, error) {
		// TODO: probably should make RangeTransactions not reuse the
		// details backing array memory.
		dets := make([]wtxmgr.TxDetails, len(details))
		copy(dets, details)
		details = dets

		txs := make([]TransactionSummary, 0, len(details))
		for i := range details {
			txs = append(txs, makeTxSummary(dbtx, w, &details[i]))
		}

		if details[0].Block.Height != -1 {
			blockHash := details[0].Block.Hash
			res.MinedTransactions = append(res.MinedTransactions, Block{
				Hash:         &blockHash,
				Height:       details[0].Block.Height,
				Timestamp:    details[0].Block.Time.Unix(),
				Transactions: txs,
			})
		} else {
			res.UnminedTransactions = txs
		}

		select {
		case <-cancel:
			return true, nil
		default:
			return false, nil
		}
	}

	return w.TxStore.RangeTransactions(txmgrNs, start, end, rangeFn)
})
return &res, err

}
`

Expected behaviour

transactions should filtered by the account.

Actual behaviour

account name filter dosn't work. Could you please give me some suggestions about how to solve this issue, or are there any other workarounds to achieve this requirement?
@guggero thanks :)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions