0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-03-11 15:56:58 -04:00
bitcoin-core/src/wallet/rpc
Andrew Chow 187504b038
Merge bitcoin/bitcoin#23662: rpc: improve getreceivedby{address,label} performance
f336ff7f21 rpc: avoid expensive `IsMine` calls in `GetReceived` tally (Sebastian Falbesoner)
a7b65af2a4 rpc: avoid scriptPubKey<->CTxDestination conversions in `GetReceived` tally (Sebastian Falbesoner)

Pull request description:

  The RPC calls `getreceivedbyaddress`/`getreceivedbylabel` both use the internal helper function `GetReceived` which was introduced in PR #17579 to deduplicate tallying code. For every wallet-related transaction output, the following unnecessary operations are currently performed in the tally loop, leading to a quite bad performance (as reported in #23645):
  - converting from CScript -> TxDestination (`ExtractDestination(...)`), converting from TxDestination -> CScript (`CWallet::IsMine(const CTxDestination& dest)`); this can be avoided by directly using output scripts in the search set instead of addresses (first commit)
  - checking if the iterated output script belongs to the wallet by calling `IsMine`; this can be avoided by only adding addresses to the search set which fulfil `IsMine` in the first place (second commit)

  ### Benchmark results
  The functional test [wallet_pr23662.py](https://github.com/theStack/bitcoin/blob/pr23662_benchmarks/test/functional/wallet_pr23662.py) (not part of this PR) creates transactions with 15000 different addresses:
  - 5000 outputs (500 txs with 10 outputs each) with label set, IsMine set (received)
  - 5000 outputs (500 txs with 10 outputs each) with label set, IsMine not set (sent)
  - 5000 outputs (500 txs with 10 outputs each) without label set, IsMine not set (sent)

  Then, the time is measured for calling `getreceivedbyaddress` and `getreceivedbylabel`, the latter with two variants. Results on my machine:

  | branch             | `getreceivedbyaddress` (single) | `getreceivedbylabel` (single) | `getreceivedbylabel` (10000) |
  |--------------------|---------------------------------|-------------------------------|------------------------------|
  | master             |             406.13ms            |          425.33ms             |          446.58ms            |
  | PR (first commit)  |             367.18ms            |          365.81ms             |          426.33ms            |
  | PR (second commit) |               3.96ms            |            4.83ms             |          339.69ms            |

  Fixes #23645.

ACKs for top commit:
  achow101:
    ACK f336ff7f21
  w0xlt:
    ACK f336ff7f21
  furszy:
    Code ACK f336ff7f

Tree-SHA512: 9cbf402b9e269713bd3feda9e31719d9dca8a0dfd526de12fd3d561711589195d0c50143432c65dae279c4eab90a4fc3f99e29fbc0452fefe05113e92d129b8f
2022-05-16 14:35:42 -04:00
..
addresses.cpp refactor: fix clang-tidy named args usage 2022-04-04 09:01:19 +01:00
backup.cpp Merge bitcoin/bitcoin#24977: rpc: Explain active and internal in listdescriptors 2022-04-26 15:09:39 +01:00
coins.cpp Merge bitcoin/bitcoin#23662: rpc: improve getreceivedby{address,label} performance 2022-05-16 14:35:42 -04:00
encrypt.cpp Replace "can not" with "cannot" in docs, user messages, and tests 2022-02-21 19:07:29 +01:00
signmessage.cpp Add src/wallet/* code to wallet:: namespace 2022-01-06 22:14:16 -05:00
spend.cpp refactor: fix clang-tidy named args usage 2022-04-04 09:01:19 +01:00
transactions.cpp refactor: use named args when ScriptToUniv or TxToUniv are invoked 2022-03-30 20:00:27 +01:00
util.cpp Add src/wallet/* code to wallet:: namespace 2022-01-06 22:14:16 -05:00
util.h Add src/wallet/* code to wallet:: namespace 2022-01-06 22:14:16 -05:00
wallet.cpp Remove not needed clang-format off comments 2022-04-25 10:55:07 +02:00
wallet.h Add src/wallet/* code to wallet:: namespace 2022-01-06 22:14:16 -05:00