diff options
-rw-r--r-- | SECURITY.md | 2 | ||||
-rw-r--r-- | build_msvc/bitcoin.sln | 6 | ||||
-rw-r--r-- | build_msvc/testconsensus/testconsensus.cpp | 54 | ||||
-rw-r--r-- | build_msvc/testconsensus/testconsensus.vcxproj | 28 | ||||
-rwxr-xr-x | ci/test/00_setup_env_android.sh | 2 | ||||
-rwxr-xr-x | ci/test/00_setup_env_native_fuzz.sh | 2 | ||||
-rwxr-xr-x | ci/test/00_setup_env_native_fuzz_with_valgrind.sh | 2 | ||||
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | doc/build-unix.md | 39 | ||||
-rw-r--r-- | src/Makefile.qt.include | 2 | ||||
-rw-r--r-- | src/Makefile.test.include | 11 | ||||
-rw-r--r-- | src/wallet/test/fuzz/notifications.cpp | 173 | ||||
-rw-r--r-- | src/wallet/wallet.cpp | 6 |
13 files changed, 205 insertions, 123 deletions
diff --git a/SECURITY.md b/SECURITY.md index 7ed96c7cea..27757c14eb 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -14,7 +14,7 @@ The following keys may be used to communicate sensitive information to developer | Name | Fingerprint | |------|-------------| | Wladimir van der Laan | 71A3 B167 3540 5025 D447 E8F2 7481 0B01 2346 C9A6 | -| Jonas Schnelli | 32EE 5C4C 3FA1 5CCA DB46 ABE5 29D4 BCB6 416F 53EC | | Pieter Wuille | 133E AC17 9436 F14A 5CF1 B794 860F EB80 4E66 9320 | +| Michael Ford | E777 299F C265 DD04 7930 70EB 944D 35F9 AC3D B76A | You can import a key by running the following command with that individual’s fingerprint: `gpg --recv-keys "<fingerprint>"` Ensure that you put quotes around fingerprints containing spaces. diff --git a/build_msvc/bitcoin.sln b/build_msvc/bitcoin.sln index 1b1f27a8a9..5095617812 100644 --- a/build_msvc/bitcoin.sln +++ b/build_msvc/bitcoin.sln @@ -4,8 +4,6 @@ VisualStudioVersion = 16.0.28803.452 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbitcoinconsensus", "libbitcoinconsensus\libbitcoinconsensus.vcxproj", "{2B384FA8-9EE1-4544-93CB-0D733C25E8CE}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testconsensus", "testconsensus\testconsensus.vcxproj", "{E78473E9-B850-456C-9120-276301E04C06}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bitcoind", "bitcoind\bitcoind.vcxproj", "{D4513DDF-6013-44DC-ADCC-12EAF6D1F038}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbitcoin_util", "libbitcoin_util\libbitcoin_util.vcxproj", "{B53A5535-EE9D-4C6F-9A26-F79EE3BC3754}" @@ -60,10 +58,6 @@ Global {2B384FA8-9EE1-4544-93CB-0D733C25E8CE}.Debug|x64.Build.0 = Debug|x64 {2B384FA8-9EE1-4544-93CB-0D733C25E8CE}.Release|x64.ActiveCfg = Release|x64 {2B384FA8-9EE1-4544-93CB-0D733C25E8CE}.Release|x64.Build.0 = Release|x64 - {E78473E9-B850-456C-9120-276301E04C06}.Debug|x64.ActiveCfg = Debug|x64 - {E78473E9-B850-456C-9120-276301E04C06}.Debug|x64.Build.0 = Debug|x64 - {E78473E9-B850-456C-9120-276301E04C06}.Release|x64.ActiveCfg = Release|x64 - {E78473E9-B850-456C-9120-276301E04C06}.Release|x64.Build.0 = Release|x64 {D4513DDF-6013-44DC-ADCC-12EAF6D1F038}.Debug|x64.ActiveCfg = Debug|x64 {D4513DDF-6013-44DC-ADCC-12EAF6D1F038}.Debug|x64.Build.0 = Debug|x64 {D4513DDF-6013-44DC-ADCC-12EAF6D1F038}.Release|x64.ActiveCfg = Release|x64 diff --git a/build_msvc/testconsensus/testconsensus.cpp b/build_msvc/testconsensus/testconsensus.cpp deleted file mode 100644 index f3c8517130..0000000000 --- a/build_msvc/testconsensus/testconsensus.cpp +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 2018-2020 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 <iostream> - -// bitcoin includes. -#include <..\src\script\bitcoinconsensus.h> -#include <..\src\primitives\transaction.h> -#include <..\src\script\script.h> -#include <..\src\streams.h> -#include <..\src\version.h> - -CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CScriptWitness& scriptWitness, int nValue = 0) -{ - CMutableTransaction txSpend; - txSpend.nVersion = 1; - txSpend.nLockTime = 0; - txSpend.vin.resize(1); - txSpend.vout.resize(1); - txSpend.vin[0].scriptWitness = scriptWitness; - txSpend.vin[0].prevout.hash = uint256(); - txSpend.vin[0].prevout.n = 0; - txSpend.vin[0].scriptSig = scriptSig; - txSpend.vin[0].nSequence = CTxIn::SEQUENCE_FINAL; - txSpend.vout[0].scriptPubKey = CScript(); - txSpend.vout[0].nValue = nValue; - - return txSpend; -} - -int main() -{ - std::cout << "bitcoinconsensus version: " << bitcoinconsensus_version() << std::endl; - - CScript pubKeyScript; - pubKeyScript << OP_1 << OP_0 << OP_1; - - int amount = 0; // 600000000; - - CScript scriptSig; - CScriptWitness scriptWitness; - CTransaction vanillaSpendTx = BuildSpendingTransaction(scriptSig, scriptWitness, amount); - CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); - stream << vanillaSpendTx; - - bitcoinconsensus_error err; - auto op0Result = bitcoinconsensus_verify_script_with_amount(pubKeyScript.data(), pubKeyScript.size(), amount, stream.data(), stream.size(), 0, bitcoinconsensus_SCRIPT_FLAGS_VERIFY_ALL, &err); - std::cout << "Op0 result: " << op0Result << ", error code " << err << std::endl; - - getchar(); - - return 0; -} diff --git a/build_msvc/testconsensus/testconsensus.vcxproj b/build_msvc/testconsensus/testconsensus.vcxproj deleted file mode 100644 index 776c40920a..0000000000 --- a/build_msvc/testconsensus/testconsensus.vcxproj +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="..\common.init.vcxproj" /> - <PropertyGroup Label="Globals"> - <ProjectGuid>{E78473E9-B850-456C-9120-276301E04C06}</ProjectGuid> - </PropertyGroup> - <PropertyGroup Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> - </PropertyGroup> - <ItemGroup> - <ClCompile Include="testconsensus.cpp" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="..\libbitcoinconsensus\libbitcoinconsensus.vcxproj"> - <Project>{2B384FA8-9EE1-4544-93CB-0D733C25E8CE}</Project> - </ProjectReference> - <ProjectReference Include="..\libbitcoin_util\libbitcoin_util.vcxproj"> - <Project>{B53A5535-EE9D-4C6F-9A26-F79EE3BC3754}</Project> - </ProjectReference> - <ProjectReference Include="..\libsecp256k1\libsecp256k1.vcxproj"> - <Project>{BB493552-3B8C-4A8C-BF69-A6E7A51D2EA6}</Project> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <Import Project="..\common.vcxproj" /> -</Project> diff --git a/ci/test/00_setup_env_android.sh b/ci/test/00_setup_env_android.sh index 2f9d1f2a9f..6faf60bd66 100755 --- a/ci/test/00_setup_env_android.sh +++ b/ci/test/00_setup_env_android.sh @@ -22,4 +22,4 @@ export ANDROID_HOME="${DEPENDS_DIR}/SDKs/android" export ANDROID_NDK_HOME="${ANDROID_HOME}/ndk/${ANDROID_NDK_VERSION}" export DEP_OPTS="ANDROID_SDK=${ANDROID_HOME} ANDROID_NDK=${ANDROID_NDK_HOME} ANDROID_API_LEVEL=${ANDROID_API_LEVEL} ANDROID_TOOLCHAIN_BIN=${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/" -export BITCOIN_CONFIG="--disable-ccache --disable-tests --enable-gui-tests --disable-bench --disable-fuzz-binary --without-utils --without-libs --without-daemon" +export BITCOIN_CONFIG="--disable-tests --enable-gui-tests --disable-bench --disable-fuzz-binary --without-utils --without-libs --without-daemon" diff --git a/ci/test/00_setup_env_native_fuzz.sh b/ci/test/00_setup_env_native_fuzz.sh index b8ac691346..9c34cfdf50 100755 --- a/ci/test/00_setup_env_native_fuzz.sh +++ b/ci/test/00_setup_env_native_fuzz.sh @@ -8,7 +8,7 @@ export LC_ALL=C.UTF-8 export DOCKER_NAME_TAG="ubuntu:20.04" export CONTAINER_NAME=ci_native_fuzz -export PACKAGES="clang llvm python3 libevent-dev bsdmainutils libboost-dev libboost-system-dev libboost-filesystem-dev libboost-test-dev" +export PACKAGES="clang llvm python3 libevent-dev bsdmainutils libboost-dev libboost-system-dev libboost-filesystem-dev libboost-test-dev libsqlite3-dev" export NO_DEPENDS=1 export RUN_UNIT_TESTS=false export RUN_FUNCTIONAL_TESTS=false diff --git a/ci/test/00_setup_env_native_fuzz_with_valgrind.sh b/ci/test/00_setup_env_native_fuzz_with_valgrind.sh index 2cf672b91e..673326ded7 100755 --- a/ci/test/00_setup_env_native_fuzz_with_valgrind.sh +++ b/ci/test/00_setup_env_native_fuzz_with_valgrind.sh @@ -8,7 +8,7 @@ export LC_ALL=C.UTF-8 export DOCKER_NAME_TAG="ubuntu:20.04" export CONTAINER_NAME=ci_native_fuzz_valgrind -export PACKAGES="clang llvm python3 libevent-dev bsdmainutils libboost-dev libboost-system-dev libboost-filesystem-dev libboost-test-dev valgrind" +export PACKAGES="clang llvm python3 libevent-dev bsdmainutils libboost-dev libboost-system-dev libboost-filesystem-dev libboost-test-dev libsqlite3-dev valgrind" export NO_DEPENDS=1 export RUN_UNIT_TESTS=false export RUN_FUNCTIONAL_TESTS=false diff --git a/configure.ac b/configure.ac index dc3b07e4bb..7e8b124b02 100644 --- a/configure.ac +++ b/configure.ac @@ -1244,7 +1244,6 @@ if test "x$enable_fuzz" = "xyes"; then bitcoin_enable_qt=no bitcoin_enable_qt_test=no bitcoin_enable_qt_dbus=no - enable_wallet=no use_bench=no use_external_signer=no use_upnp=no diff --git a/doc/build-unix.md b/doc/build-unix.md index 02c36eea7c..70bbb3f8af 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -42,12 +42,11 @@ Optional dependencies: ------------|------------------|---------------------- miniupnpc | UPnP Support | Firewall-jumping support libnatpmp | NAT-PMP Support | Firewall-jumping support - libdb4.8 | Berkeley DB | Optional, wallet storage (only needed when wallet enabled) + libdb4.8 | Berkeley DB | Optional, wallet storage (only needed when legacy wallet enabled) qt | GUI | GUI toolkit (only needed when GUI enabled) libqrencode | QR codes in GUI | Optional for generating QR codes (only needed when GUI enabled) - univalue | Utility | JSON parsing and encoding (bundled version will be used unless --with-system-univalue passed to configure) libzmq3 | ZMQ notification | Optional, allows generating ZMQ notifications (requires ZMQ version >= 4.0.0) - sqlite3 | SQLite DB | Optional, wallet storage (only needed when wallet enabled) + sqlite3 | SQLite DB | Optional, wallet storage (only needed when descriptor wallet enabled) systemtap | Tracing (USDT) | Optional, statically defined tracepoints For the versions used, see [dependencies.md](dependencies.md) @@ -85,19 +84,15 @@ Now, you can either build from self-compiled [depends](/depends/README.md) or in sudo apt-get install libevent-dev libboost-dev libboost-system-dev libboost-filesystem-dev libboost-test-dev -Berkeley DB is required for the wallet. - -Ubuntu and Debian have their own `libdb-dev` and `libdb++-dev` packages, but these will install -Berkeley DB 5.1 or later. This will break binary wallet compatibility with the distributed executables, which -are based on BerkeleyDB 4.8. If you do not care about wallet compatibility, -pass `--with-incompatible-bdb` to configure. - -Otherwise, you can build Berkeley DB [yourself](#berkeley-db). - SQLite is required for the descriptor wallet: sudo apt install libsqlite3-dev +Berkeley DB is required for the legacy wallet. Ubuntu and Debian have their own `libdb-dev` and `libdb++-dev` packages, +but these will install Berkeley DB 5.1 or later. This will break binary wallet compatibility with the distributed +executables, which are based on BerkeleyDB 4.8. If you do not care about wallet compatibility, pass +`--with-incompatible-bdb` to configure. Otherwise, you can build Berkeley DB [yourself](#berkeley-db). + To build Bitcoin Core without wallet, see [*Disable-wallet mode*](#disable-wallet-mode) Optional port mapping libraries (see: `--with-miniupnpc`, `--enable-upnp-default`, and `--with-natpmp`, `--enable-natpmp-default`): @@ -146,20 +141,18 @@ Now, you can either build from self-compiled [depends](/depends/README.md) or in sudo dnf install libevent-devel boost-devel -Berkeley DB is required for the wallet: +SQLite is required for the descriptor wallet: + + sudo dnf install sqlite-devel + +Berkeley DB is required for the legacy wallet: sudo dnf install libdb4-devel libdb4-cxx-devel Newer Fedora releases, since Fedora 33, have only `libdb-devel` and `libdb-cxx-devel` packages, but these will install Berkeley DB 5.3 or later. This will break binary wallet compatibility with the distributed executables, which are based on Berkeley DB 4.8. If you do not care about wallet compatibility, -pass `--with-incompatible-bdb` to configure. - -Otherwise, you can build Berkeley DB [yourself](#berkeley-db). - -SQLite is required for the descriptor wallet: - - sudo dnf install sqlite-devel +pass `--with-incompatible-bdb` to configure. Otherwise, you can build Berkeley DB [yourself](#berkeley-db). To build Bitcoin Core without wallet, see [*Disable-wallet mode*](#disable-wallet-mode) @@ -225,8 +218,10 @@ turned off by default. See the configure options for NAT-PMP behavior desired: Berkeley DB ----------- -It is recommended to use Berkeley DB 4.8. If you have to build it yourself, -you can use [the installation script included in contrib/](/contrib/install_db4.sh) + +The legacy wallet uses Berkeley DB. To ensure backwards compatibility it is +recommended to use Berkeley DB 4.8. If you have to build it yourself, you can +use [the installation script included in contrib/](/contrib/install_db4.sh) like so: ```shell diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index e6ea8bdf61..35d5b0004a 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -391,7 +391,7 @@ QT_BASE_TLD = $(shell tar tf $(QT_BASE_PATH) --exclude='*/*') bitcoin_qt_apk: FORCE mkdir -p $(APK_LIB_DIR) - cp $(dir $(CC))../sysroot/usr/lib/$(host_alias)/libc++_shared.so $(APK_LIB_DIR) + cp $(dir $(lastword $(CC)))../sysroot/usr/lib/$(host_alias)/libc++_shared.so $(APK_LIB_DIR) tar xf $(QT_BASE_PATH) -C qt/android/src/ $(QT_BASE_TLD)src/android/jar/src --strip-components=5 tar xf $(QT_BASE_PATH) -C qt/android/src/ $(QT_BASE_TLD)src/android/java/src --strip-components=5 tar xf $(QT_BASE_PATH) -C qt/android/res/ $(QT_BASE_TLD)src/android/java/res --strip-components=5 diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 27f9382631..5a5c74c044 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -170,6 +170,10 @@ if USE_BDB BITCOIN_TESTS += wallet/test/db_tests.cpp endif +if USE_SQLITE +FUZZ_WALLET_SRC = \ + wallet/test/fuzz/notifications.cpp +endif # USE_SQLITE BITCOIN_TEST_SUITE += \ wallet/test/util.cpp \ @@ -178,7 +182,7 @@ BITCOIN_TEST_SUITE += \ wallet/test/wallet_test_fixture.h \ wallet/test/init_test_fixture.cpp \ wallet/test/init_test_fixture.h -endif +endif # ENABLE_WALLET test_test_bitcoin_SOURCES = $(BITCOIN_TEST_SUITE) $(BITCOIN_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES) test_test_bitcoin_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(TESTDEFS) $(EVENT_CFLAGS) @@ -199,14 +203,13 @@ test_test_bitcoin_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) FUZZ_SUITE_LD_COMMON += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) endif -FUZZ_SUITE_LDFLAGS_COMMON = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) $(PTHREAD_FLAGS) - if ENABLE_FUZZ_BINARY test_fuzz_fuzz_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) test_fuzz_fuzz_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) test_fuzz_fuzz_LDADD = $(FUZZ_SUITE_LD_COMMON) -test_fuzz_fuzz_LDFLAGS = $(FUZZ_SUITE_LDFLAGS_COMMON) $(RUNTIME_LDFLAGS) +test_fuzz_fuzz_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) $(PTHREAD_FLAGS) $(RUNTIME_LDFLAGS) test_fuzz_fuzz_SOURCES = \ + $(FUZZ_WALLET_SRC) \ test/fuzz/addition_overflow.cpp \ test/fuzz/addrman.cpp \ test/fuzz/asmap.cpp \ diff --git a/src/wallet/test/fuzz/notifications.cpp b/src/wallet/test/fuzz/notifications.cpp new file mode 100644 index 0000000000..252832785b --- /dev/null +++ b/src/wallet/test/fuzz/notifications.cpp @@ -0,0 +1,173 @@ +// Copyright (c) 2021 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 <test/fuzz/FuzzedDataProvider.h> +#include <test/fuzz/fuzz.h> +#include <test/fuzz/util.h> +#include <test/util/setup_common.h> +#include <util/translation.h> +#include <wallet/context.h> +#include <wallet/receive.h> +#include <wallet/wallet.h> +#include <wallet/walletdb.h> +#include <wallet/walletutil.h> + +#include <cassert> +#include <cstdint> +#include <string> +#include <vector> + +namespace { +const TestingSetup* g_setup; + +void initialize_setup() +{ + static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>(); + g_setup = testing_setup.get(); +} + +/** + * Wraps a descriptor wallet for fuzzing. The constructor writes the sqlite db + * to disk, the destructor deletes it. + */ +struct FuzzedWallet { + ArgsManager args; + WalletContext context; + std::shared_ptr<CWallet> wallet; + FuzzedWallet(const std::string& name) + { + context.args = &args; + context.chain = g_setup->m_node.chain.get(); + + DatabaseOptions options; + options.require_create = true; + options.create_flags = WALLET_FLAG_DESCRIPTORS; + const std::optional<bool> load_on_start; + gArgs.ForceSetArg("-keypool", "0"); // Avoid timeout in TopUp() + + DatabaseStatus status; + bilingual_str error; + std::vector<bilingual_str> warnings; + wallet = CreateWallet(context, name, load_on_start, options, status, error, warnings); + assert(wallet); + assert(error.empty()); + assert(warnings.empty()); + assert(wallet->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)); + } + ~FuzzedWallet() + { + const auto name{wallet->GetName()}; + std::vector<bilingual_str> warnings; + std::optional<bool> load_on_start; + assert(RemoveWallet(context, wallet, load_on_start, warnings)); + assert(warnings.empty()); + UnloadWallet(std::move(wallet)); + fs::remove_all(GetWalletDir() / name); + } + CScript GetScriptPubKey(FuzzedDataProvider& fuzzed_data_provider) + { + auto type{fuzzed_data_provider.PickValueInArray(OUTPUT_TYPES)}; + if (type == OutputType::BECH32M) { + type = OutputType::BECH32; // TODO: Setup taproot descriptor and remove this line + } + CTxDestination dest; + bilingual_str error; + if (fuzzed_data_provider.ConsumeBool()) { + assert(wallet->GetNewDestination(type, "", dest, error)); + } else { + assert(wallet->GetNewChangeDestination(type, dest, error)); + } + assert(error.empty()); + return GetScriptForDestination(dest); + } +}; + +FUZZ_TARGET_INIT(wallet_notifications, initialize_setup) +{ + FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; + // The total amount, to be distributed to the wallets a and b in txs + // without fee. Thus, the balance of the wallets should always equal the + // total amount. + const auto total_amount{ConsumeMoney(fuzzed_data_provider)}; + FuzzedWallet a{"fuzzed_wallet_a"}; + FuzzedWallet b{"fuzzed_wallet_b"}; + + // Keep track of all coins in this test. + // Each tuple in the chain represents the coins and the block created with + // those coins. Once the block is mined, the next tuple will have an empty + // block and the freshly mined coins. + using Coins = std::set<std::tuple<CAmount, COutPoint>>; + std::vector<std::tuple<Coins, CBlock>> chain; + { + // Add the inital entry + chain.emplace_back(); + auto& [coins, block]{chain.back()}; + coins.emplace(total_amount, COutPoint{uint256::ONE, 1}); + } + LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 200) + { + CallOneOf( + fuzzed_data_provider, + [&] { + auto& [coins_orig, block]{chain.back()}; + // Copy the coins for this block and consume all of them + Coins coins = coins_orig; + while (!coins.empty()) { + // Create a new tx + CMutableTransaction tx{}; + // Add some coins as inputs to it + auto num_inputs{fuzzed_data_provider.ConsumeIntegralInRange<int>(1, coins.size())}; + CAmount in{0}; + while (num_inputs-- > 0) { + const auto& [coin_amt, coin_outpoint]{*coins.begin()}; + in += coin_amt; + tx.vin.emplace_back(coin_outpoint); + coins.erase(coins.begin()); + } + // Create some outputs spending all inputs, without fee + LIMITED_WHILE(in > 0 && fuzzed_data_provider.ConsumeBool(), 100) + { + const auto out_value{ConsumeMoney(fuzzed_data_provider, in)}; + in -= out_value; + auto& wallet{fuzzed_data_provider.ConsumeBool() ? a : b}; + tx.vout.emplace_back(out_value, wallet.GetScriptPubKey(fuzzed_data_provider)); + } + // Spend the remaining input value, if any + auto& wallet{fuzzed_data_provider.ConsumeBool() ? a : b}; + tx.vout.emplace_back(in, wallet.GetScriptPubKey(fuzzed_data_provider)); + // Add tx to block + block.vtx.emplace_back(MakeTransactionRef(tx)); + } + // Mine block + a.wallet->blockConnected(block, chain.size()); + b.wallet->blockConnected(block, chain.size()); + // Store the coins for the next block + Coins coins_new; + for (const auto& tx : block.vtx) { + uint32_t i{0}; + for (const auto& out : tx->vout) { + coins_new.emplace(out.nValue, COutPoint{tx->GetHash(), i++}); + } + } + chain.emplace_back(coins_new, CBlock{}); + }, + [&] { + if (chain.size() <= 1) return; // The first entry can't be removed + auto& [coins, block]{chain.back()}; + if (block.vtx.empty()) return; // Can only disconnect if the block was submitted first + // Disconnect block + a.wallet->blockDisconnected(block, chain.size() - 1); + b.wallet->blockDisconnected(block, chain.size() - 1); + chain.pop_back(); + }); + auto& [coins, first_block]{chain.front()}; + if (!first_block.vtx.empty()) { + // Only check balance when at least one block was submitted + const auto bal_a{GetBalance(*a.wallet).m_mine_trusted}; + const auto bal_b{GetBalance(*b.wallet).m_mine_trusted}; + assert(total_amount == bal_a + bal_b); + } + } +} +} // namespace diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 4eb9d5560d..606a30a999 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2732,11 +2732,11 @@ std::shared_ptr<CWallet> CWallet::Create(WalletContext& context, const std::stri walletInstance->m_default_max_tx_fee = max_fee.value(); } - if (gArgs.IsArgSet("-consolidatefeerate")) { - if (std::optional<CAmount> consolidate_feerate = ParseMoney(gArgs.GetArg("-consolidatefeerate", ""))) { + if (args.IsArgSet("-consolidatefeerate")) { + if (std::optional<CAmount> consolidate_feerate = ParseMoney(args.GetArg("-consolidatefeerate", ""))) { walletInstance->m_consolidate_feerate = CFeeRate(*consolidate_feerate); } else { - error = AmountErrMsg("consolidatefeerate", gArgs.GetArg("-consolidatefeerate", "")); + error = AmountErrMsg("consolidatefeerate", args.GetArg("-consolidatefeerate", "")); return nullptr; } } |