aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/addresstype.h9
-rw-r--r--src/bench/wallet_create_tx.cpp7
-rw-r--r--src/i2p.cpp15
-rw-r--r--src/node/blockstorage.cpp7
-rw-r--r--src/qt/transactionview.cpp3
-rw-r--r--src/qt/walletmodel.cpp3
-rw-r--r--src/test/i2p_tests.cpp44
-rw-r--r--src/wallet/test/spend_tests.cpp2
-rw-r--r--src/wallet/test/wallet_tests.cpp2
9 files changed, 80 insertions, 12 deletions
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);