Faster sendtoaddress RPC and p2p_stresstest.py spam generation/stress testing script
This merge request does two things:
- It makes the sendtoaddress RPC much (100x-1000x) faster when operating on large wallets when the coinsel=2 RPC option is used. This is accomplished with two changes:
a) Don't call
GetBalance in the success path (moved to separate MR -- !794 (merged))
b) When the coinsel=1 or 2 RPC option is used, sendtoaddress will only enumerate 10*AmountToSend worth of coins out of the wallet to be passed to the knapsack solver or the BNB coin selection algorithms, rather than the full wallet's balance. This mitigates the O(n^2) performance of the knapsack solver.
- It adds test/functional/p2p_stresstest.py, which can be used to fairly quickly generate many megabytes of spam transactions, and can test block propagation, mempool acceptance, and transaction propagation. This test suite, as well as the more recent multi-machine version (https://github.com/jtoomim/remote_stress), has been an important part of what I've used for testing Xthinner's performance and correctness.
It should be mentioned that despite the 100x-1000x performance improvement, the sendtoaddress RPC is still fairly slow. On my desktop (Core i7 4790k), I get between 50 tx/sec and 220 tx/sec per core with this code, whereas I can get about 1500-2000 tx/sec with a more substantial reworking of the CreateTransaction code. But this is such a minor set of changes to wallet.cpp and rpcwallet.cpp that I think it's a no-brainer to include these, whereas the more substantial rework will have more substantial code maintenance implications. The 50-200 tx/sec/core performance should be good enough for testing Xthinner up to around 3-30 MB block sizes with some patience.
First, you will need to copy or symlink over the config.ini file from your
build/test directory into
test/, then run:
ninja check-all cd ../test/benchmark python3 p2p_stresstest.py
Alternately, you can do:
ninja check-all cd test/functional python3 ../../../test/benchmark/p2p_stresstest.py
The alternative method requires that a symbolic link is created in the source tree, from
test/benchmark/test_framework -> ../functional/test_framework.