Merge #15779: test: Add wallet_balance benchmark

fad7c33342 refactor: Add handleNotifications method to wallet (MarcoFalke)
fa46ac3127 bench: Add wallet_balance benchmarks (MarcoFalke)

Pull request description:

ACKs for commit fad7c3:
  ryanofsky:
    utACK fad7c33342. I might squash or rearrange the commits to avoid adding code in one commit that just gets deleted in the next one. But overall this looks good and the cleanup is nice.

Tree-SHA512: 231faac168cbe9bb0ab4bf10ac1d5b042c610364406d75061fba27f1e9d16c71867e74cc4606e9f42659aa980d7133c00e29fcc18bbba7da2fa7a80178b3246c
This commit is contained in:
MarcoFalke 2019-04-17 15:14:05 -04:00
commit dae72998e8
No known key found for this signature in database
GPG key ID: D2EA4850E7528B25
8 changed files with 85 additions and 15 deletions

View file

@ -39,6 +39,7 @@
<ClCompile Include="..\..\src\bench\rpc_mempool.cpp" /> <ClCompile Include="..\..\src\bench\rpc_mempool.cpp" />
<ClCompile Include="..\..\src\bench\merkle_root.cpp" /> <ClCompile Include="..\..\src\bench\merkle_root.cpp" />
<ClCompile Include="..\..\src\bench\rollingbloom.cpp" /> <ClCompile Include="..\..\src\bench\rollingbloom.cpp" />
<ClCompile Include="..\..\src\bench\wallet_balance.cpp" />
<ClCompile Include="..\..\src\bench\verify_script.cpp" /> <ClCompile Include="..\..\src\bench\verify_script.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View file

@ -64,6 +64,7 @@ endif
if ENABLE_WALLET if ENABLE_WALLET
bench_bench_bitcoin_SOURCES += bench/coin_selection.cpp bench_bench_bitcoin_SOURCES += bench/coin_selection.cpp
bench_bench_bitcoin_SOURCES += bench/wallet_balance.cpp
endif endif
bench_bench_bitcoin_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(CRYPTO_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(MINIUPNPC_LIBS) bench_bench_bitcoin_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(CRYPTO_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(MINIUPNPC_LIBS)

View file

@ -0,0 +1,53 @@
// Copyright (c) 2012-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <bench/bench.h>
#include <interfaces/chain.h>
#include <key_io.h>
#include <optional.h>
#include <test/util.h>
#include <validationinterface.h>
#include <wallet/wallet.h>
static void WalletBalance(benchmark::State& state, const bool set_dirty, const bool add_watchonly, const bool add_mine)
{
const auto& ADDRESS_WATCHONLY = ADDRESS_BCRT1_UNSPENDABLE;
std::unique_ptr<interfaces::Chain> chain = interfaces::MakeChain();
CWallet wallet{chain.get(), WalletLocation(), WalletDatabase::CreateMock()};
{
bool first_run;
if (wallet.LoadWallet(first_run) != DBErrors::LOAD_OK) assert(false);
wallet.handleNotifications();
}
const Optional<std::string> address_mine{add_mine ? Optional<std::string>{getnewaddress(wallet)} : nullopt};
if (add_watchonly) importaddress(wallet, ADDRESS_WATCHONLY);
for (int i = 0; i < 100; ++i) {
generatetoaddress(address_mine.get_value_or(ADDRESS_WATCHONLY));
generatetoaddress(ADDRESS_WATCHONLY);
}
SyncWithValidationInterfaceQueue();
auto bal = wallet.GetBalance(); // Cache
while (state.KeepRunning()) {
if (set_dirty) wallet.MarkDirty();
bal = wallet.GetBalance();
if (add_mine) assert(bal.m_mine_trusted > 0);
if (add_watchonly) assert(bal.m_watchonly_trusted > 0);
}
}
static void WalletBalanceDirty(benchmark::State& state) { WalletBalance(state, /* set_dirty */ true, /* add_watchonly */ true, /* add_mine */ true); }
static void WalletBalanceClean(benchmark::State& state) { WalletBalance(state, /* set_dirty */ false, /* add_watchonly */ true, /* add_mine */ true); }
static void WalletBalanceMine(benchmark::State& state) { WalletBalance(state, /* set_dirty */ false, /* add_watchonly */ false, /* add_mine */ true); }
static void WalletBalanceWatch(benchmark::State& state) { WalletBalance(state, /* set_dirty */ false, /* add_watchonly */ true, /* add_mine */ false); }
BENCHMARK(WalletBalanceDirty, 2500);
BENCHMARK(WalletBalanceClean, 8000);
BENCHMARK(WalletBalanceMine, 16000);
BENCHMARK(WalletBalanceWatch, 8000);

View file

@ -22,6 +22,8 @@
#include <boost/thread.hpp> #include <boost/thread.hpp>
const std::string ADDRESS_BCRT1_UNSPENDABLE = "bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj";
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
std::string getnewaddress(CWallet& w) std::string getnewaddress(CWallet& w)
{ {
@ -75,7 +77,6 @@ CTxIn MineBlock(const CScript& coinbase_scriptPubKey)
return CTxIn{block->vtx[0]->GetHash(), 0}; return CTxIn{block->vtx[0]->GetHash(), 0};
} }
std::shared_ptr<CBlock> PrepareBlock(const CScript& coinbase_scriptPubKey) std::shared_ptr<CBlock> PrepareBlock(const CScript& coinbase_scriptPubKey)
{ {
auto block = std::make_shared<CBlock>( auto block = std::make_shared<CBlock>(

View file

@ -13,6 +13,10 @@ class CScript;
class CTxIn; class CTxIn;
class CWallet; class CWallet;
// Constants //
extern const std::string ADDRESS_BCRT1_UNSPENDABLE;
// Lower-level utils // // Lower-level utils //
/** Returns the generated coin */ /** Returns the generated coin */

View file

@ -8,12 +8,13 @@
#include <wallet/db.h> #include <wallet/db.h>
#include <wallet/rpcwallet.h> #include <wallet/rpcwallet.h>
WalletTestingSetup::WalletTestingSetup(const std::string& chainName): WalletTestingSetup::WalletTestingSetup(const std::string& chainName)
TestingSetup(chainName), m_wallet(m_chain.get(), WalletLocation(), WalletDatabase::CreateMock()) : TestingSetup(chainName),
m_wallet(m_chain.get(), WalletLocation(), WalletDatabase::CreateMock())
{ {
bool fFirstRun; bool fFirstRun;
m_wallet.LoadWallet(fFirstRun); m_wallet.LoadWallet(fFirstRun);
m_wallet.m_chain_notifications_handler = m_chain->handleNotifications(m_wallet); m_wallet.handleNotifications();
m_chain_client->registerRpcs(); m_chain_client->registerRpcs();
} }

View file

@ -5,9 +5,8 @@
#include <wallet/wallet.h> #include <wallet/wallet.h>
#include <checkpoints.h>
#include <chain.h> #include <chain.h>
#include <wallet/coincontrol.h> #include <checkpoints.h>
#include <consensus/consensus.h> #include <consensus/consensus.h>
#include <consensus/validation.h> #include <consensus/validation.h>
#include <fs.h> #include <fs.h>
@ -16,7 +15,6 @@
#include <key.h> #include <key.h>
#include <key_io.h> #include <key_io.h>
#include <keystore.h> #include <keystore.h>
#include <validation.h>
#include <net.h> #include <net.h>
#include <policy/fees.h> #include <policy/fees.h>
#include <policy/policy.h> #include <policy/policy.h>
@ -34,6 +32,8 @@
#include <util/moneystr.h> #include <util/moneystr.h>
#include <util/rbf.h> #include <util/rbf.h>
#include <util/validation.h> #include <util/validation.h>
#include <validation.h>
#include <wallet/coincontrol.h>
#include <wallet/fees.h> #include <wallet/fees.h>
#include <algorithm> #include <algorithm>
@ -4303,7 +4303,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
chain.loadWallet(interfaces::MakeWallet(walletInstance)); chain.loadWallet(interfaces::MakeWallet(walletInstance));
// Register with the validation interface. It's ok to do this after rescan since we're still holding locked_chain. // Register with the validation interface. It's ok to do this after rescan since we're still holding locked_chain.
walletInstance->m_chain_notifications_handler = chain.handleNotifications(*walletInstance); walletInstance->handleNotifications();
walletInstance->SetBroadcastTransactions(gArgs.GetBoolArg("-walletbroadcast", DEFAULT_WALLETBROADCAST)); walletInstance->SetBroadcastTransactions(gArgs.GetBoolArg("-walletbroadcast", DEFAULT_WALLETBROADCAST));
@ -4316,6 +4316,11 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
return walletInstance; return walletInstance;
} }
void CWallet::handleNotifications()
{
m_chain_notifications_handler = m_chain->handleNotifications(*this);
}
void CWallet::postInitProcess() void CWallet::postInitProcess()
{ {
auto locked_chain = chain().lock(); auto locked_chain = chain().lock();

View file

@ -11,16 +11,16 @@
#include <interfaces/handler.h> #include <interfaces/handler.h>
#include <outputtype.h> #include <outputtype.h>
#include <policy/feerate.h> #include <policy/feerate.h>
#include <script/ismine.h>
#include <script/sign.h>
#include <streams.h> #include <streams.h>
#include <tinyformat.h> #include <tinyformat.h>
#include <ui_interface.h> #include <ui_interface.h>
#include <util/strencodings.h> #include <util/strencodings.h>
#include <validationinterface.h>
#include <script/ismine.h>
#include <script/sign.h>
#include <util/system.h> #include <util/system.h>
#include <wallet/crypter.h> #include <validationinterface.h>
#include <wallet/coinselection.h> #include <wallet/coinselection.h>
#include <wallet/crypter.h>
#include <wallet/walletdb.h> #include <wallet/walletdb.h>
#include <wallet/walletutil.h> #include <wallet/walletutil.h>
@ -767,7 +767,10 @@ public:
unsigned int nMasterKeyMaxID = 0; unsigned int nMasterKeyMaxID = 0;
/** Construct wallet with specified name and database implementation. */ /** Construct wallet with specified name and database implementation. */
CWallet(interfaces::Chain* chain, const WalletLocation& location, std::unique_ptr<WalletDatabase> database) : m_chain(chain), m_location(location), database(std::move(database)) CWallet(interfaces::Chain* chain, const WalletLocation& location, std::unique_ptr<WalletDatabase> database)
: m_chain(chain),
m_location(location),
database(std::move(database))
{ {
} }
@ -794,6 +797,9 @@ public:
/** Registered interfaces::Chain::Notifications handler. */ /** Registered interfaces::Chain::Notifications handler. */
std::unique_ptr<interfaces::Handler> m_chain_notifications_handler; std::unique_ptr<interfaces::Handler> m_chain_notifications_handler;
/** Register the wallet for chain notifications */
void handleNotifications();
/** Interface for accessing chain state. */ /** Interface for accessing chain state. */
interfaces::Chain& chain() const { assert(m_chain); return *m_chain; } interfaces::Chain& chain() const { assert(m_chain); return *m_chain; }
@ -1208,8 +1214,6 @@ public:
/** Add a KeyOriginInfo to the wallet */ /** Add a KeyOriginInfo to the wallet */
bool AddKeyOrigin(const CPubKey& pubkey, const KeyOriginInfo& info); bool AddKeyOrigin(const CPubKey& pubkey, const KeyOriginInfo& info);
friend struct WalletTestingSetup;
}; };
/** /**