diff options
-rw-r--r-- | configure.ac | 2 | ||||
-rwxr-xr-x | contrib/guix/libexec/codesign.sh | 6 | ||||
-rw-r--r-- | contrib/guix/manifest.scm | 6 | ||||
-rw-r--r-- | doc/man/bitcoin-cli.1 | 6 | ||||
-rw-r--r-- | doc/man/bitcoin-qt.1 | 6 | ||||
-rw-r--r-- | doc/man/bitcoin-tx.1 | 6 | ||||
-rw-r--r-- | doc/man/bitcoin-util.1 | 6 | ||||
-rw-r--r-- | doc/man/bitcoin-wallet.1 | 6 | ||||
-rw-r--r-- | doc/man/bitcoind.1 | 6 | ||||
-rw-r--r-- | src/addresstype.h | 9 | ||||
-rw-r--r-- | src/bench/wallet_create_tx.cpp | 7 | ||||
-rw-r--r-- | src/i2p.cpp | 15 | ||||
-rw-r--r-- | src/node/blockstorage.cpp | 7 | ||||
-rw-r--r-- | src/qt/transactionview.cpp | 3 | ||||
-rw-r--r-- | src/qt/walletmodel.cpp | 3 | ||||
-rw-r--r-- | src/test/i2p_tests.cpp | 44 | ||||
-rw-r--r-- | src/wallet/test/spend_tests.cpp | 2 | ||||
-rw-r--r-- | src/wallet/test/wallet_tests.cpp | 2 | ||||
-rwxr-xr-x | test/functional/feature_assumeutxo.py | 19 |
19 files changed, 125 insertions, 36 deletions
diff --git a/configure.ac b/configure.ac index 59b1d70698..11b40c31e1 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ([2.69]) define(_CLIENT_VERSION_MAJOR, 26) define(_CLIENT_VERSION_MINOR, 0) define(_CLIENT_VERSION_BUILD, 0) -define(_CLIENT_VERSION_RC, 1) +define(_CLIENT_VERSION_RC, 2) define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2023) define(_COPYRIGHT_HOLDERS,[The %s developers]) diff --git a/contrib/guix/libexec/codesign.sh b/contrib/guix/libexec/codesign.sh index 0b5f77d01e..54edfecb26 100755 --- a/contrib/guix/libexec/codesign.sh +++ b/contrib/guix/libexec/codesign.sh @@ -86,7 +86,11 @@ mkdir -p "$DISTSRC" signapple apply dist/Bitcoin-Qt.app codesignatures/osx/dist # Make a .zip from dist/ - zip "${OUTDIR}/${DISTNAME}-${HOST}.zip" dist/* + cd dist/ + find . -print0 \ + | xargs -0r touch --no-dereference --date="@${SOURCE_DATE_EPOCH}" + find . | sort \ + | zip -X@ "${OUTDIR}/${DISTNAME}-${HOST}.zip" ;; *) exit 1 diff --git a/contrib/guix/manifest.scm b/contrib/guix/manifest.scm index 3c4ad6cdbc..12f57fcc45 100644 --- a/contrib/guix/manifest.scm +++ b/contrib/guix/manifest.scm @@ -19,7 +19,6 @@ ((gnu packages python) #:select (python-minimal)) ((gnu packages python-build) #:select (python-tomli)) ((gnu packages python-crypto) #:select (python-asn1crypto)) - ((gnu packages python-web) #:select (python-requests)) ((gnu packages tls) #:select (openssl)) ((gnu packages version-control) #:select (git-minimal)) (guix build-system cmake) @@ -445,7 +444,7 @@ and endian independent.") (license license:expat))) (define-public python-signapple - (let ((commit "8a945a2e7583be2665cf3a6a89d665b70ecd1ab6")) + (let ((commit "7a96b4171a360abf0f0f56e499f8f9ed2116280d")) (package (name "python-signapple") (version (git-version "0.1" "1" commit)) @@ -458,14 +457,13 @@ and endian independent.") (file-name (git-file-name name commit)) (sha256 (base32 - "0fr1hangvfyiwflca6jg5g8zvg3jc9qr7vd2c12ff89pznf38dlg")))) + "0aa4k180jnpal15yhncnm3g3z9gzmi7qb25q5l0kaj444a1p2pm4")))) (build-system python-build-system) (propagated-inputs `(("python-asn1crypto" ,python-asn1crypto) ("python-oscrypto" ,python-oscrypto) ("python-certvalidator" ,python-certvalidator) ("python-elfesteem" ,python-elfesteem) - ("python-requests" ,python-requests) ("python-macholib" ,python-macholib))) ;; There are no tests, but attempting to run python setup.py test leads to ;; problems, just disable the test diff --git a/doc/man/bitcoin-cli.1 b/doc/man/bitcoin-cli.1 index 5c226100bf..b70f532c05 100644 --- a/doc/man/bitcoin-cli.1 +++ b/doc/man/bitcoin-cli.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-CLI "1" "October 2023" "bitcoin-cli v26.0.0rc1" "User Commands" +.TH BITCOIN-CLI "1" "October 2023" "bitcoin-cli v26.0.0rc2" "User Commands" .SH NAME -bitcoin-cli \- manual page for bitcoin-cli v26.0.0rc1 +bitcoin-cli \- manual page for bitcoin-cli v26.0.0rc2 .SH SYNOPSIS .B bitcoin-cli [\fI\,options\/\fR] \fI\,<command> \/\fR[\fI\,params\/\fR] \fI\,Send command to Bitcoin Core\/\fR @@ -15,7 +15,7 @@ bitcoin-cli \- manual page for bitcoin-cli v26.0.0rc1 .B bitcoin-cli [\fI\,options\/\fR] \fI\,help <command> Get help for a command\/\fR .SH DESCRIPTION -Bitcoin Core RPC client version v26.0.0rc1 +Bitcoin Core RPC client version v26.0.0rc2 .SH OPTIONS .HP \-? diff --git a/doc/man/bitcoin-qt.1 b/doc/man/bitcoin-qt.1 index b6b081a31e..b45b4ff027 100644 --- a/doc/man/bitcoin-qt.1 +++ b/doc/man/bitcoin-qt.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-QT "1" "October 2023" "bitcoin-qt v26.0.0rc1" "User Commands" +.TH BITCOIN-QT "1" "October 2023" "bitcoin-qt v26.0.0rc2" "User Commands" .SH NAME -bitcoin-qt \- manual page for bitcoin-qt v26.0.0rc1 +bitcoin-qt \- manual page for bitcoin-qt v26.0.0rc2 .SH SYNOPSIS .B bitcoin-qt [\fI\,command-line options\/\fR] .SH DESCRIPTION -Bitcoin Core version v26.0.0rc1 +Bitcoin Core version v26.0.0rc2 .SH OPTIONS .HP \-? diff --git a/doc/man/bitcoin-tx.1 b/doc/man/bitcoin-tx.1 index 4c3729c6c4..52f1e6e73c 100644 --- a/doc/man/bitcoin-tx.1 +++ b/doc/man/bitcoin-tx.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-TX "1" "October 2023" "bitcoin-tx v26.0.0rc1" "User Commands" +.TH BITCOIN-TX "1" "October 2023" "bitcoin-tx v26.0.0rc2" "User Commands" .SH NAME -bitcoin-tx \- manual page for bitcoin-tx v26.0.0rc1 +bitcoin-tx \- manual page for bitcoin-tx v26.0.0rc2 .SH SYNOPSIS .B bitcoin-tx [\fI\,options\/\fR] \fI\,<hex-tx> \/\fR[\fI\,commands\/\fR] \fI\,Update hex-encoded bitcoin transaction\/\fR @@ -9,7 +9,7 @@ bitcoin-tx \- manual page for bitcoin-tx v26.0.0rc1 .B bitcoin-tx [\fI\,options\/\fR] \fI\,-create \/\fR[\fI\,commands\/\fR] \fI\,Create hex-encoded bitcoin transaction\/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-tx utility version v26.0.0rc1 +Bitcoin Core bitcoin\-tx utility version v26.0.0rc2 .SH OPTIONS .HP \-? diff --git a/doc/man/bitcoin-util.1 b/doc/man/bitcoin-util.1 index 04380848fb..bd96107e09 100644 --- a/doc/man/bitcoin-util.1 +++ b/doc/man/bitcoin-util.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-UTIL "1" "October 2023" "bitcoin-util v26.0.0rc1" "User Commands" +.TH BITCOIN-UTIL "1" "October 2023" "bitcoin-util v26.0.0rc2" "User Commands" .SH NAME -bitcoin-util \- manual page for bitcoin-util v26.0.0rc1 +bitcoin-util \- manual page for bitcoin-util v26.0.0rc2 .SH SYNOPSIS .B bitcoin-util [\fI\,options\/\fR] [\fI\,commands\/\fR] \fI\,Do stuff\/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-util utility version v26.0.0rc1 +Bitcoin Core bitcoin\-util utility version v26.0.0rc2 .SH OPTIONS .HP \-? diff --git a/doc/man/bitcoin-wallet.1 b/doc/man/bitcoin-wallet.1 index 60104d4e53..da856035a7 100644 --- a/doc/man/bitcoin-wallet.1 +++ b/doc/man/bitcoin-wallet.1 @@ -1,9 +1,9 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-WALLET "1" "October 2023" "bitcoin-wallet v26.0.0rc1" "User Commands" +.TH BITCOIN-WALLET "1" "October 2023" "bitcoin-wallet v26.0.0rc2" "User Commands" .SH NAME -bitcoin-wallet \- manual page for bitcoin-wallet v26.0.0rc1 +bitcoin-wallet \- manual page for bitcoin-wallet v26.0.0rc2 .SH DESCRIPTION -Bitcoin Core bitcoin\-wallet version v26.0.0rc1 +Bitcoin Core bitcoin\-wallet version v26.0.0rc2 .PP bitcoin\-wallet is an offline tool for creating and interacting with Bitcoin Core wallet files. By default bitcoin\-wallet will act on wallets in the default mainnet wallet directory in the datadir. diff --git a/doc/man/bitcoind.1 b/doc/man/bitcoind.1 index 8a6c6b9d5c..d44c9bb6c4 100644 --- a/doc/man/bitcoind.1 +++ b/doc/man/bitcoind.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIND "1" "October 2023" "bitcoind v26.0.0rc1" "User Commands" +.TH BITCOIND "1" "October 2023" "bitcoind v26.0.0rc2" "User Commands" .SH NAME -bitcoind \- manual page for bitcoind v26.0.0rc1 +bitcoind \- manual page for bitcoind v26.0.0rc2 .SH SYNOPSIS .B bitcoind [\fI\,options\/\fR] \fI\,Start Bitcoin Core\/\fR .SH DESCRIPTION -Bitcoin Core version v26.0.0rc1 +Bitcoin Core version v26.0.0rc2 .SH OPTIONS .HP \-? diff --git a/src/addresstype.h b/src/addresstype.h index d3422c6813..522f58fef1 100644 --- a/src/addresstype.h +++ b/src/addresstype.h @@ -13,15 +13,16 @@ #include <variant> #include <algorithm> -class CNoDestination { +class CNoDestination +{ private: CScript m_script; public: CNoDestination() = default; - CNoDestination(const CScript& script) : m_script(script) {} + explicit CNoDestination(const CScript& script) : m_script(script) {} - const CScript& GetScript() const { return m_script; } + const CScript& GetScript() const LIFETIMEBOUND { return m_script; } friend bool operator==(const CNoDestination& a, const CNoDestination& b) { return a.GetScript() == b.GetScript(); } friend bool operator<(const CNoDestination& a, const CNoDestination& b) { return a.GetScript() < b.GetScript(); } @@ -32,7 +33,7 @@ private: CPubKey m_pubkey; public: - PubKeyDestination(const CPubKey& pubkey) : m_pubkey(pubkey) {} + explicit PubKeyDestination(const CPubKey& pubkey) : m_pubkey(pubkey) {} const CPubKey& GetPubKey() const LIFETIMEBOUND { return m_pubkey; } diff --git a/src/bench/wallet_create_tx.cpp b/src/bench/wallet_create_tx.cpp index 160534b63c..632918c0ca 100644 --- a/src/bench/wallet_create_tx.cpp +++ b/src/bench/wallet_create_tx.cpp @@ -94,13 +94,14 @@ static void WalletCreateTx(benchmark::Bench& bench, const OutputType output_type } // Generate destinations - CScript dest = GetScriptForDestination(getNewDestination(wallet, output_type)); + const auto dest{getNewDestination(wallet, output_type)}; // Generate chain; each coinbase will have two outputs to fill-up the wallet const auto& params = Params(); + const CScript coinbase_out{GetScriptForDestination(dest)}; unsigned int chain_size = 5000; // 5k blocks means 10k UTXO for the wallet (minus 200 due COINBASE_MATURITY) for (unsigned int i = 0; i < chain_size; ++i) { - generateFakeBlock(params, test_setup->m_node, wallet, dest); + generateFakeBlock(params, test_setup->m_node, wallet, coinbase_out); } // Check available balance @@ -185,4 +186,4 @@ static void WalletAvailableCoins(benchmark::Bench& bench) { AvailableCoins(bench BENCHMARK(WalletCreateTxUseOnlyPresetInputs, benchmark::PriorityLevel::LOW) BENCHMARK(WalletCreateTxUsePresetInputsAndCoinSelection, benchmark::PriorityLevel::LOW) -BENCHMARK(WalletAvailableCoins, benchmark::PriorityLevel::LOW);
\ No newline at end of file +BENCHMARK(WalletAvailableCoins, benchmark::PriorityLevel::LOW); diff --git a/src/i2p.cpp b/src/i2p.cpp index 05a5dde396..685b43ba18 100644 --- a/src/i2p.cpp +++ b/src/i2p.cpp @@ -384,11 +384,26 @@ Binary Session::MyDestination() const static constexpr size_t CERT_LEN_POS = 385; uint16_t cert_len; + + if (m_private_key.size() < CERT_LEN_POS + sizeof(cert_len)) { + throw std::runtime_error(strprintf("The private key is too short (%d < %d)", + m_private_key.size(), + CERT_LEN_POS + sizeof(cert_len))); + } + memcpy(&cert_len, &m_private_key.at(CERT_LEN_POS), sizeof(cert_len)); cert_len = be16toh(cert_len); const size_t dest_len = DEST_LEN_BASE + cert_len; + if (dest_len > m_private_key.size()) { + throw std::runtime_error(strprintf("Certificate length (%d) designates that the private key should " + "be %d bytes, but it is only %d bytes", + cert_len, + dest_len, + m_private_key.size())); + } + return Binary{m_private_key.begin(), m_private_key.begin() + dest_len}; } diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp index 53f616de23..058e524745 100644 --- a/src/node/blockstorage.cpp +++ b/src/node/blockstorage.cpp @@ -387,7 +387,12 @@ bool BlockManager::LoadBlockIndex(const std::optional<uint256>& snapshot_blockha } if (snapshot_blockhash) { - const AssumeutxoData au_data = *Assert(GetParams().AssumeutxoForBlockhash(*snapshot_blockhash)); + const std::optional<AssumeutxoData> maybe_au_data = GetParams().AssumeutxoForBlockhash(*snapshot_blockhash); + if (!maybe_au_data) { + m_opts.notifications.fatalError(strprintf("Assumeutxo data not found for the given blockhash '%s'.", snapshot_blockhash->ToString())); + return false; + } + const AssumeutxoData& au_data = *Assert(maybe_au_data); m_snapshot_height = au_data.height; CBlockIndex* base{LookupBlockIndex(*snapshot_blockhash)}; diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 67af62285d..7e24dbd3ec 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -531,6 +531,9 @@ void TransactionView::showDetails() TransactionDescDialog *dlg = new TransactionDescDialog(selection.at(0)); dlg->setAttribute(Qt::WA_DeleteOnClose); m_opened_dialogs.append(dlg); + connect(dlg, &QObject::destroyed, [this, dlg] { + m_opened_dialogs.removeOne(dlg); + }); dlg->show(); } } diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index ee3327530c..a45579fa0d 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -187,8 +187,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact setAddress.insert(rcp.address); ++nAddresses; - CScript scriptPubKey = GetScriptForDestination(DecodeDestination(rcp.address.toStdString())); - CRecipient recipient = {scriptPubKey, rcp.amount, rcp.fSubtractFeeFromAmount}; + CRecipient recipient{DecodeDestination(rcp.address.toStdString()), rcp.amount, rcp.fSubtractFeeFromAmount}; vecSend.push_back(recipient); total += rcp.amount; diff --git a/src/test/i2p_tests.cpp b/src/test/i2p_tests.cpp index 5b8b0e9215..f80f07d190 100644 --- a/src/test/i2p_tests.cpp +++ b/src/test/i2p_tests.cpp @@ -9,6 +9,7 @@ #include <test/util/logging.h> #include <test/util/net.h> #include <test/util/setup_common.h> +#include <util/readwritefile.h> #include <util/threadinterrupt.h> #include <boost/test/unit_test.hpp> @@ -125,4 +126,47 @@ BOOST_AUTO_TEST_CASE(listen_ok_accept_fail) } } +BOOST_AUTO_TEST_CASE(damaged_private_key) +{ + const auto CreateSockOrig = CreateSock; + + CreateSock = [](const CService&) { + return std::make_unique<StaticContentsSock>("HELLO REPLY RESULT=OK VERSION=3.1\n" + "SESSION STATUS RESULT=OK DESTINATION=\n"); + }; + + const auto i2p_private_key_file = m_args.GetDataDirNet() / "test_i2p_private_key_damaged"; + + for (const auto& [file_contents, expected_error] : std::vector<std::tuple<std::string, std::string>>{ + {"", "The private key is too short (0 < 387)"}, + + {"abcd", "The private key is too short (4 < 387)"}, + + {std::string(386, '\0'), "The private key is too short (386 < 387)"}, + + {std::string(385, '\0') + '\0' + '\1', + "Certificate length (1) designates that the private key should be 388 bytes, but it is only " + "387 bytes"}, + + {std::string(385, '\0') + '\0' + '\5' + "abcd", + "Certificate length (5) designates that the private key should be 392 bytes, but it is only " + "391 bytes"}}) { + BOOST_REQUIRE(WriteBinaryFile(i2p_private_key_file, file_contents)); + + CThreadInterrupt interrupt; + i2p::sam::Session session(i2p_private_key_file, CService{}, &interrupt); + + { + ASSERT_DEBUG_LOG("Creating persistent SAM session"); + ASSERT_DEBUG_LOG(expected_error); + + i2p::Connection conn; + bool proxy_error; + BOOST_CHECK(!session.Connect(CService{}, conn, proxy_error)); + } + } + + CreateSock = CreateSockOrig; +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/wallet/test/spend_tests.cpp b/src/wallet/test/spend_tests.cpp index 68c98ae6b9..5926d88129 100644 --- a/src/wallet/test/spend_tests.cpp +++ b/src/wallet/test/spend_tests.cpp @@ -78,7 +78,7 @@ BOOST_FIXTURE_TEST_CASE(wallet_duplicated_preset_inputs_test, TestChain100Setup) // Try to create a tx that spends more than what preset inputs + wallet selected inputs are covering for. // The wallet can cover up to 200 BTC, and the tx target is 299 BTC. - std::vector<CRecipient> recipients = {{GetScriptForDestination(*Assert(wallet->GetNewDestination(OutputType::BECH32, "dummy"))), + std::vector<CRecipient> recipients{{*Assert(wallet->GetNewDestination(OutputType::BECH32, "dummy")), /*nAmount=*/299 * COIN, /*fSubtractFeeFromAmount=*/true}}; CCoinControl coin_control; coin_control.m_allow_other_inputs = true; diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index ad4bb3a9d2..dea7be03a6 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -605,7 +605,7 @@ BOOST_FIXTURE_TEST_CASE(ListCoinsTest, ListCoinsTestingSetup) // returns the coin associated with the change address underneath the // coinbaseKey pubkey, even though the change address has a different // pubkey. - AddTx(CRecipient{GetScriptForRawPubKey({}), 1 * COIN, /*subtract_fee=*/false}); + AddTx(CRecipient{PubKeyDestination{{}}, 1 * COIN, /*subtract_fee=*/false}); { LOCK(wallet->cs_wallet); list = ListCoins(*wallet); diff --git a/test/functional/feature_assumeutxo.py b/test/functional/feature_assumeutxo.py index 9c265649d5..ab2e6c4d0b 100755 --- a/test/functional/feature_assumeutxo.py +++ b/test/functional/feature_assumeutxo.py @@ -33,6 +33,8 @@ Interesting starting states could be loading a snapshot when the current chain t - TODO: Not an ancestor or a descendant of the snapshot block and has more work """ +from shutil import rmtree + from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, @@ -107,6 +109,22 @@ class AssumeutxoTest(BitcoinTestFramework): f.write(valid_snapshot_contents[(32 + 8 + offset + len(content)):]) expected_error(log_msg=f"[snapshot] bad snapshot content hash: expected 61d9c2b29a2571a5fe285fe2d8554f91f93309666fc9b8223ee96338de25ff53, got {wrong_hash}") + def test_invalid_chainstate_scenarios(self): + self.log.info("Test different scenarios of invalid snapshot chainstate in datadir") + + self.log.info(" - snapshot chainstate refering to a block that is not in the assumeutxo parameters") + self.stop_node(0) + chainstate_snapshot_path = self.nodes[0].chain_path / "chainstate_snapshot" + chainstate_snapshot_path.mkdir() + with open(chainstate_snapshot_path / "base_blockhash", 'wb') as f: + f.write(b'z' * 32) + expected_error = f"Error: A fatal internal error occurred, see debug.log for details" + self.nodes[0].assert_start_raises_init_error(expected_msg=expected_error) + + # resurrect node again + rmtree(chainstate_snapshot_path) + self.start_node(0) + def run_test(self): """ Bring up two (disconnected) nodes, mine some new blocks on the first, @@ -166,6 +184,7 @@ class AssumeutxoTest(BitcoinTestFramework): assert_equal(n0.getblockchaininfo()["blocks"], FINAL_HEIGHT) self.test_invalid_snapshot_scenarios(dump_output['path']) + self.test_invalid_chainstate_scenarios() self.log.info(f"Loading snapshot into second node from {dump_output['path']}") loaded = n1.loadtxoutset(dump_output['path']) |