From dc26758a923b98f2ceb0c2e2e14e9792fff8ca15 Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto Date: Fri, 17 Apr 2026 08:47:13 +0200 Subject: wip: initial FCMP --- monero | 2 +- ...issing-___clear_cache-when-targetting-iOS.patch | 17 +- patches/monero/0002-store-crash-fix.patch | 84 ++-- .../0003-uint64_t-missing-definition-fix.patch | 8 +- ...004-use-proper-error-handling-in-get_seed.patch | 16 +- patches/monero/0005-UR-functions.patch | 243 ++++------- .../monero/0006-add-dummy-device-for-ledger.patch | 75 ++-- patches/monero/0007-polyseed.patch | 182 ++++---- patches/monero/0008-coin-control.patch | 163 ++++---- ...oding-and-tx-key-getter-for-PendingTransc.patch | 14 +- ...dd-recoverDeterministicWalletFromSpendKey.patch | 24 +- .../monero/0011-add-monero-submodule-support.patch | 49 +-- patches/monero/0012-fix-iOS-depends-build.patch | 32 +- .../0013-change-earliest-fork-height-message.patch | 25 ++ ...-include-locale-only-when-targeting-WIN32.patch | 44 -- .../0014-change-earliest-fork-height-message.patch | 25 -- patches/monero/0014-serialize-cache-to-JSON.patch | 464 +++++++++++++++++++++ ...enerate_translations_header.c-requirement.patch | 123 ++++++ .../0015-remove-trivially_copyable-assert.patch | 24 -- patches/monero/0016-fix-mingw-build-issues.patch | 46 ++ patches/monero/0016-serialize-cache-to-JSON.patch | 463 -------------------- ...enerate_translations_header.c-requirement.patch | 123 ------ patches/monero/0017-fix-remove-flaky-test.patch | 27 ++ ...s-remove-icu4c-monero-project-monero-8880.patch | 39 -- patches/monero/0019-fix-mingw-build-issues.patch | 46 -- patches/monero/0020-fix-remove-flaky-test.patch | 27 -- 26 files changed, 1084 insertions(+), 1301 deletions(-) create mode 100644 patches/monero/0013-change-earliest-fork-height-message.patch delete mode 100644 patches/monero/0013-include-locale-only-when-targeting-WIN32.patch delete mode 100644 patches/monero/0014-change-earliest-fork-height-message.patch create mode 100644 patches/monero/0014-serialize-cache-to-JSON.patch create mode 100644 patches/monero/0015-drop-generate_translations_header.c-requirement.patch delete mode 100644 patches/monero/0015-remove-trivially_copyable-assert.patch create mode 100644 patches/monero/0016-fix-mingw-build-issues.patch delete mode 100644 patches/monero/0016-serialize-cache-to-JSON.patch delete mode 100644 patches/monero/0017-drop-generate_translations_header.c-requirement.patch create mode 100644 patches/monero/0017-fix-remove-flaky-test.patch delete mode 100644 patches/monero/0018-depends-remove-icu4c-monero-project-monero-8880.patch delete mode 100644 patches/monero/0019-fix-mingw-build-issues.patch delete mode 100644 patches/monero/0020-fix-remove-flaky-test.patch diff --git a/monero b/monero index dbcc7d2..5c45416 160000 --- a/monero +++ b/monero @@ -1 +1 @@ -Subproject commit dbcc7d212c094bd1a45f7291dbb99a4b4627a96d +Subproject commit 5c454168c9ca9af91f6673de13fdda3512403612 diff --git a/patches/monero/0001-fix-missing-___clear_cache-when-targetting-iOS.patch b/patches/monero/0001-fix-missing-___clear_cache-when-targetting-iOS.patch index 888a502..9475f73 100644 --- a/patches/monero/0001-fix-missing-___clear_cache-when-targetting-iOS.patch +++ b/patches/monero/0001-fix-missing-___clear_cache-when-targetting-iOS.patch @@ -1,24 +1,23 @@ -From 41d9f755a1392dd116241acb32b887091669f090 Mon Sep 17 00:00:00 2001 +From fcc142aa6183f8125284bbc194e705523820552b Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto Date: Tue, 2 Apr 2024 16:51:56 +0200 -Subject: [PATCH 01/20] fix missing ___clear_cache when targetting iOS +Subject: [PATCH 01/17] fix missing ___clear_cache when targetting iOS --- - .gitmodules | 3 ++- + .gitmodules | 2 +- external/randomx | 2 +- - 2 files changed, 3 insertions(+), 2 deletions(-) + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules -index 721cce3b4..ffb73fe9a 100644 +index 40fb2b826..e9568bc46 100644 --- a/.gitmodules +++ b/.gitmodules -@@ -9,7 +9,8 @@ - url = https://github.com/trezor/trezor-common.git +@@ -6,7 +6,7 @@ + url = https://github.com/Tencent/rapidjson [submodule "external/randomx"] path = external/randomx - url = https://github.com/tevador/RandomX + url = https://github.com/MrCyjaneK/RandomX -+ branch = cyjan-fix-ios [submodule "external/supercop"] path = external/supercop url = https://github.com/monero-project/supercop @@ -30,5 +29,5 @@ index 102f8acf9..5dfeeb30e 160000 -Subproject commit 102f8acf90a7649ada410de5499a7ec62e49e1da +Subproject commit 5dfeeb30ec3446ec9d348153767abc324436c56c -- -2.50.1 (Apple Git-155) +2.51.0 diff --git a/patches/monero/0002-store-crash-fix.patch b/patches/monero/0002-store-crash-fix.patch index 8ecd8b1..9ff2e27 100644 --- a/patches/monero/0002-store-crash-fix.patch +++ b/patches/monero/0002-store-crash-fix.patch @@ -1,7 +1,7 @@ -From 94cf21261079d6d4ceb848be3863613e98c3bc89 Mon Sep 17 00:00:00 2001 +From 2d91d3e2006753ada1ce342536e8a339487d0963 Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto Date: Sat, 11 May 2024 16:25:10 +0200 -Subject: [PATCH 02/20] store crash fix +Subject: [PATCH 02/17] store crash fix Monero wallet crashes (sometimes) when it is syncing, while the proper solution (that can be seen in feather) @@ -36,18 +36,17 @@ would just wait for it to finish before actually storing). Also imo store() functin should store the wallet, no matter the current state. --- - external/randomx | 2 +- - src/wallet/api/wallet.cpp | 53 +++++++++++++++++++-------------------- + src/wallet/api/wallet.cpp | 51 +++++++++++++++++++-------------------- src/wallet/api/wallet.h | 1 - - src/wallet/wallet2.cpp | 11 +++++++- + src/wallet/wallet2.cpp | 11 ++++++++- src/wallet/wallet2.h | 3 +++ - 5 files changed, 40 insertions(+), 30 deletions(-) + 4 files changed, 38 insertions(+), 28 deletions(-) diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp -index 165b21c9f..c2f4176e2 100644 +index 51dd050e4..4d72455b6 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp -@@ -55,8 +55,8 @@ using namespace cryptonote; +@@ -59,8 +59,8 @@ using namespace cryptonote; #define MONERO_DEFAULT_LOG_CATEGORY "WalletAPI" #define LOCK_REFRESH() \ @@ -58,7 +57,7 @@ index 165b21c9f..c2f4176e2 100644 m_wallet->stop(); \ m_refreshCV.notify_one(); \ boost::mutex::scoped_lock lock(m_refreshMutex); \ -@@ -178,7 +178,7 @@ struct Wallet2CallbackImpl : public tools::i_wallet2_callback +@@ -184,7 +184,7 @@ struct Wallet2CallbackImpl : public tools::i_wallet2_callback virtual void on_new_block(uint64_t height, const cryptonote::block& block) { // Don't flood the GUI with signals. On fast refresh - send signal every 1000th block @@ -67,7 +66,7 @@ index 165b21c9f..c2f4176e2 100644 // created or the restore height specified when wallet was recovered if(height >= m_wallet->m_wallet->get_refresh_from_block_height() || height % 1000 == 0) { // LOG_PRINT_L3(__FUNCTION__ << ": new block. height: " << height); -@@ -379,7 +379,7 @@ bool Wallet::keyValid(const std::string &secret_key_string, const std::string &a +@@ -356,7 +356,7 @@ bool Wallet::keyValid(const std::string &secret_key_string, const std::string &a error = tr("Failed to parse address"); return false; } @@ -76,7 +75,7 @@ index 165b21c9f..c2f4176e2 100644 cryptonote::blobdata key_data; if(!epee::string_tools::parse_hexstr_to_binbuff(secret_key_string, key_data) || key_data.size() != sizeof(crypto::secret_key)) { -@@ -404,7 +404,7 @@ bool Wallet::keyValid(const std::string &secret_key_string, const std::string &a +@@ -381,7 +381,7 @@ bool Wallet::keyValid(const std::string &secret_key_string, const std::string &a error = tr("key does not match address"); return false; } @@ -85,7 +84,7 @@ index 165b21c9f..c2f4176e2 100644 return true; } -@@ -466,7 +466,7 @@ WalletImpl::WalletImpl(NetworkType nettype, uint64_t kdf_rounds) +@@ -443,7 +443,7 @@ WalletImpl::WalletImpl(NetworkType nettype, uint64_t kdf_rounds) m_wallet2Callback.reset(new Wallet2CallbackImpl(this)); m_wallet->callback(m_wallet2Callback.get()); m_refreshThreadDone = false; @@ -94,7 +93,7 @@ index 165b21c9f..c2f4176e2 100644 m_addressBook.reset(new AddressBookImpl(this)); m_subaddress.reset(new SubaddressImpl(this)); m_subaddressAccount.reset(new SubaddressAccountImpl(this)); -@@ -487,7 +487,7 @@ WalletImpl::~WalletImpl() +@@ -464,7 +464,7 @@ WalletImpl::~WalletImpl() m_wallet->callback(NULL); // Pause refresh thread - prevents refresh from starting again WalletImpl::pauseRefresh(); // Call the method directly (not polymorphically) to protect against UB in destructor. @@ -103,7 +102,7 @@ index 165b21c9f..c2f4176e2 100644 close(false); // do not store wallet as part of the closing activities // Stop refresh thread stopRefresh(); -@@ -698,7 +698,7 @@ bool WalletImpl::recoverFromKeysWithPassword(const std::string &path, +@@ -675,7 +675,7 @@ bool WalletImpl::recoverFromKeysWithPassword(const std::string &path, setSeedLanguage(language); LOG_PRINT_L1("Generated deterministic wallet from spend key with seed language: " + language); } @@ -112,7 +111,7 @@ index 165b21c9f..c2f4176e2 100644 } catch (const std::exception& e) { setStatusError(string(tr("failed to generate new wallet: ")) + e.what()); -@@ -962,6 +962,7 @@ void WalletImpl::stop() +@@ -939,6 +939,7 @@ void WalletImpl::stop() bool WalletImpl::store(const std::string &path) { clearStatus(); @@ -120,7 +119,7 @@ index 165b21c9f..c2f4176e2 100644 try { if (path.empty()) { m_wallet->store(); -@@ -1110,14 +1111,14 @@ uint64_t WalletImpl::daemonBlockChainTargetHeight() const +@@ -1047,14 +1048,14 @@ uint64_t WalletImpl::daemonBlockChainTargetHeight() const } else { clearStatus(); } @@ -137,7 +136,7 @@ index 165b21c9f..c2f4176e2 100644 if(connected() == Wallet::ConnectionStatus_Disconnected) return false; uint64_t blockChainHeight = daemonBlockChainHeight(); -@@ -1189,14 +1190,14 @@ UnsignedTransaction *WalletImpl::loadUnsignedTx(const std::string &unsigned_file +@@ -1126,14 +1127,14 @@ UnsignedTransaction *WalletImpl::loadUnsignedTx(const std::string &unsigned_file return transaction; } @@ -154,7 +153,7 @@ index 165b21c9f..c2f4176e2 100644 return transaction; } -@@ -1211,7 +1212,7 @@ bool WalletImpl::submitTransaction(const string &fileName) { +@@ -1148,7 +1149,7 @@ bool WalletImpl::submitTransaction(const string &fileName) { setStatus(Status_Ok, tr("Failed to load transaction from file")); return false; } @@ -163,7 +162,7 @@ index 165b21c9f..c2f4176e2 100644 if(!transaction->commit()) { setStatusError(transaction->m_errorString); return false; -@@ -1220,7 +1221,7 @@ bool WalletImpl::submitTransaction(const string &fileName) { +@@ -1157,7 +1158,7 @@ bool WalletImpl::submitTransaction(const string &fileName) { return true; } @@ -172,7 +171,7 @@ index 165b21c9f..c2f4176e2 100644 { if (m_wallet->watch_only()) { -@@ -1229,7 +1230,7 @@ bool WalletImpl::exportKeyImages(const string &filename, bool all) +@@ -1166,7 +1167,7 @@ bool WalletImpl::exportKeyImages(const string &filename, bool all) } if (checkBackgroundSync("cannot export key images")) return false; @@ -181,16 +180,7 @@ index 165b21c9f..c2f4176e2 100644 try { if (!m_wallet->export_key_images(filename, all)) -@@ -1664,7 +1665,7 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vectoradjust_priority(static_cast(priority)); -@@ -2448,10 +2449,10 @@ void WalletImpl::refreshThreadFunc() +@@ -2407,10 +2408,10 @@ void WalletImpl::refreshThreadFunc() } LOG_PRINT_L3(__FUNCTION__ << ": refresh lock acquired..."); @@ -203,7 +193,7 @@ index 165b21c9f..c2f4176e2 100644 LOG_PRINT_L3(__FUNCTION__ << ": refreshing..."); doRefresh(); } -@@ -2485,7 +2486,7 @@ void WalletImpl::doRefresh() +@@ -2444,7 +2445,7 @@ void WalletImpl::doRefresh() } catch (const std::exception &e) { setStatusError(e.what()); break; @@ -212,7 +202,7 @@ index 165b21c9f..c2f4176e2 100644 if (m_wallet2Callback->getListener()) { m_wallet2Callback->getListener()->refreshed(); -@@ -2495,9 +2496,9 @@ void WalletImpl::doRefresh() +@@ -2454,9 +2455,9 @@ void WalletImpl::doRefresh() void WalletImpl::startRefresh() { @@ -224,7 +214,7 @@ index 165b21c9f..c2f4176e2 100644 m_refreshCV.notify_one(); } } -@@ -2507,7 +2508,7 @@ void WalletImpl::startRefresh() +@@ -2466,7 +2467,7 @@ void WalletImpl::startRefresh() void WalletImpl::stopRefresh() { if (!m_refreshThreadDone) { @@ -233,7 +223,7 @@ index 165b21c9f..c2f4176e2 100644 m_refreshThreadDone = true; m_refreshCV.notify_one(); m_refreshThread.join(); -@@ -2518,9 +2519,7 @@ void WalletImpl::pauseRefresh() +@@ -2477,9 +2478,7 @@ void WalletImpl::pauseRefresh() { LOG_PRINT_L2(__FUNCTION__ << ": refresh paused..."); // TODO synchronize access @@ -244,7 +234,7 @@ index 165b21c9f..c2f4176e2 100644 } -@@ -2530,7 +2529,7 @@ bool WalletImpl::isNewWallet() const +@@ -2489,7 +2488,7 @@ bool WalletImpl::isNewWallet() const // it's the same case as if it created from scratch, i.e. we need "fast sync" // with the daemon (pull hashes instead of pull blocks). // If wallet cache is rebuilt, creation height stored in .keys is used. @@ -253,7 +243,7 @@ index 165b21c9f..c2f4176e2 100644 return !(blockChainHeight() > 1 || m_recoveringFromSeed || m_recoveringFromDevice || m_rebuildWalletCache) && !watchOnly(); } -@@ -2642,7 +2641,7 @@ void WalletImpl::hardForkInfo(uint8_t &version, uint64_t &earliest_height) const +@@ -2601,7 +2600,7 @@ void WalletImpl::hardForkInfo(uint8_t &version, uint64_t &earliest_height) const m_wallet->get_hard_fork_info(version, earliest_height); } @@ -263,10 +253,10 @@ index 165b21c9f..c2f4176e2 100644 return m_wallet->use_fork_rules(version,early_blocks); } diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h -index 1f199a72c..ac7ce2f6a 100644 +index d48d7f130..365025c6e 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h -@@ -273,7 +273,6 @@ private: +@@ -274,7 +274,6 @@ private: std::unique_ptr m_subaddressAccount; // multi-threaded refresh stuff @@ -275,10 +265,10 @@ index 1f199a72c..ac7ce2f6a 100644 std::atomic m_refreshIntervalMillis; std::atomic m_refreshShouldRescan; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp -index af1f03d2c..af876c9f3 100644 +index 68a0586d6..d04bbe0da 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp -@@ -1195,6 +1195,7 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended, std +@@ -1212,6 +1212,7 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended, std m_upper_transaction_weight_limit(0), m_run(true), m_callback(0), @@ -286,7 +276,7 @@ index af1f03d2c..af876c9f3 100644 m_trusted_daemon(false), m_nettype(nettype), m_multisig_rounds_passed(0), -@@ -1415,6 +1416,14 @@ bool wallet2::set_daemon(std::string daemon_address, boost::optionalset_proxy(address); -@@ -4178,7 +4187,7 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo - // infer when we get an incoming output +@@ -4420,7 +4429,7 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo + bool first = true, last = false; - while(m_run.load(std::memory_order_relaxed) && blocks_fetched < max_blocks) @@ -311,10 +301,10 @@ index af1f03d2c..af876c9f3 100644 uint64_t next_blocks_start_height; std::vector next_blocks; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h -index a765dc475..92f735f96 100644 +index 49894cce0..31f9aa913 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h -@@ -1078,6 +1078,8 @@ private: +@@ -582,6 +582,8 @@ private: epee::net_utils::ssl_options_t ssl_options = epee::net_utils::ssl_support_t::e_ssl_support_autodetect, const std::string &proxy = ""); bool set_proxy(const std::string &address); @@ -323,7 +313,7 @@ index a765dc475..92f735f96 100644 void stop() { m_run.store(false, std::memory_order_relaxed); m_message_store.stop(); } -@@ -1997,6 +1999,7 @@ private: +@@ -1592,6 +1594,7 @@ private: boost::recursive_mutex m_daemon_rpc_mutex; @@ -332,5 +322,5 @@ index a765dc475..92f735f96 100644 i_wallet2_callback* m_callback; hw::device::device_type m_key_device_type; -- -2.50.1 (Apple Git-155) +2.51.0 diff --git a/patches/monero/0003-uint64_t-missing-definition-fix.patch b/patches/monero/0003-uint64_t-missing-definition-fix.patch index 87aef72..c530714 100644 --- a/patches/monero/0003-uint64_t-missing-definition-fix.patch +++ b/patches/monero/0003-uint64_t-missing-definition-fix.patch @@ -1,14 +1,14 @@ -From 3cdb4ef9bdf88936276b4c5286eb7f9d39f556d0 Mon Sep 17 00:00:00 2001 +From 34ecfa2bc9f6bc08375338db8b2ae19977a354f8 Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto Date: Mon, 2 Sep 2024 16:40:31 +0200 -Subject: [PATCH 03/20] uint64_t missing definition fix +Subject: [PATCH 03/17] uint64_t missing definition fix --- contrib/epee/include/net/http_base.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/epee/include/net/http_base.h b/contrib/epee/include/net/http_base.h -index f32fdd9ae..a95a7d34f 100644 +index b53766780..05af46731 100644 --- a/contrib/epee/include/net/http_base.h +++ b/contrib/epee/include/net/http_base.h @@ -28,7 +28,7 @@ @@ -21,5 +21,5 @@ index f32fdd9ae..a95a7d34f 100644 #include -- -2.50.1 (Apple Git-155) +2.51.0 diff --git a/patches/monero/0004-use-proper-error-handling-in-get_seed.patch b/patches/monero/0004-use-proper-error-handling-in-get_seed.patch index 154fa90..465cc60 100644 --- a/patches/monero/0004-use-proper-error-handling-in-get_seed.patch +++ b/patches/monero/0004-use-proper-error-handling-in-get_seed.patch @@ -1,7 +1,7 @@ -From 9174c5ab87a00d16e2930616686de5e57f3e7539 Mon Sep 17 00:00:00 2001 +From beeda121f0457f5f6aeeedd55e07e0b3485e936e Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto Date: Mon, 24 Jun 2024 10:49:12 +0200 -Subject: [PATCH 04/20] use proper error handling in get_seed +Subject: [PATCH 04/17] use proper error handling in get_seed --- src/wallet/api/wallet.cpp | 17 ++++++++++++----- @@ -9,10 +9,10 @@ Subject: [PATCH 04/20] use proper error handling in get_seed 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp -index c2f4176e2..6301bd1ef 100644 +index 4d72455b6..b6ce7b05a 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp -@@ -826,12 +826,19 @@ bool WalletImpl::close(bool store) +@@ -803,12 +803,19 @@ bool WalletImpl::close(bool store) std::string WalletImpl::seed(const std::string& seed_offset) const { @@ -38,10 +38,10 @@ index c2f4176e2..6301bd1ef 100644 std::string WalletImpl::getSeedLanguage() const diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp -index af876c9f3..ac2a1fec3 100644 +index d04bbe0da..2c2268f7a 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp -@@ -1452,11 +1452,13 @@ bool wallet2::get_seed(epee::wipeable_string& electrum_words, const epee::wipeab +@@ -1459,11 +1459,13 @@ bool wallet2::get_seed(epee::wipeable_string& electrum_words, const epee::wipeab bool keys_deterministic = is_deterministic(); if (!keys_deterministic) { @@ -55,7 +55,7 @@ index af876c9f3..ac2a1fec3 100644 std::cout << "seed_language not set" << std::endl; return false; } -@@ -1466,8 +1468,9 @@ bool wallet2::get_seed(epee::wipeable_string& electrum_words, const epee::wipeab +@@ -1473,8 +1475,9 @@ bool wallet2::get_seed(epee::wipeable_string& electrum_words, const epee::wipeab key = cryptonote::encrypt_key(key, passphrase); if (!crypto::ElectrumWords::bytes_to_words(key, electrum_words, seed_language)) { @@ -67,5 +67,5 @@ index af876c9f3..ac2a1fec3 100644 return true; -- -2.50.1 (Apple Git-155) +2.51.0 diff --git a/patches/monero/0005-UR-functions.patch b/patches/monero/0005-UR-functions.patch index 116d050..95296e6 100644 --- a/patches/monero/0005-UR-functions.patch +++ b/patches/monero/0005-UR-functions.patch @@ -1,7 +1,7 @@ -From ccd02185be7d4a928776ff38111eb3ce9face61f Mon Sep 17 00:00:00 2001 +From b8b0ff67a9a6eb1dd18a259cfa9c136336d1101a Mon Sep 17 00:00:00 2001 From: tobtoht Date: Tue, 12 Mar 2024 10:09:50 +0100 -Subject: [PATCH 05/20] UR functions +Subject: [PATCH 05/17] UR functions This commit adds UR functions for UR tasks, I believe that the right place to get @@ -20,10 +20,9 @@ Things broken in the commit of this patch) it is not a dealbreaker. --- .gitmodules | 4 + - CMakeLists.txt | 4 +- + CMakeLists.txt | 1 + external/CMakeLists.txt | 1 + - external/bc-ur | 1 + - src/device/device_ledger.cpp | 5 +- + src/device/device_ledger.cpp | 4 +- src/wallet/CMakeLists.txt | 1 + src/wallet/api/pending_transaction.cpp | 33 +++ src/wallet/api/pending_transaction.h | 1 + @@ -32,96 +31,77 @@ Things broken in the commit src/wallet/api/wallet.cpp | 307 ++++++++++++++++++++++++ src/wallet/api/wallet.h | 8 + src/wallet/api/wallet2_api.h | 22 +- - src/wallet/wallet2.cpp | 141 +++++++---- + src/wallet/wallet2.cpp | 94 ++++++-- src/wallet/wallet2.h | 3 + - 15 files changed, 518 insertions(+), 56 deletions(-) - create mode 160000 external/bc-ur + 14 files changed, 492 insertions(+), 30 deletions(-) diff --git a/.gitmodules b/.gitmodules -index ffb73fe9a..72af74d55 100644 +index e9568bc46..8abd99092 100644 --- a/.gitmodules +++ b/.gitmodules -@@ -15,3 +15,7 @@ - path = external/supercop - url = https://github.com/monero-project/supercop - branch = monero +@@ -21,3 +21,7 @@ + path = external/mx25519 + url = https://github.com/jeffro256/mx25519 + branch = unclamped +[submodule "external/bc-ur"] + path = external/bc-ur + url = https://github.com/MrCyjaneK/bc-ur + branch = misc diff --git a/CMakeLists.txt b/CMakeLists.txt -index 9b922046e..268339201 100644 +index 4d96243d4..ee46cabcd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt -@@ -96,7 +96,8 @@ enable_language(C ASM) - set(CMAKE_C_STANDARD 11) - set(CMAKE_C_STANDARD_REQUIRED ON) +@@ -103,6 +103,7 @@ set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_EXTENSIONS OFF) --set(CMAKE_CXX_STANDARD 14) -+set(CMAKE_CXX_STANDARD 17) -+add_definitions(-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES) # boost: no template named 'unary_function' in namespace 'std'; did you mean '__unary_function'? + set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) ++add_definitions(-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES) # boost: no template named 'unary_function' in namespace 'std'; did you mean '__unary_function'? set(CMAKE_CXX_EXTENSIONS OFF) -@@ -364,6 +365,7 @@ if(NOT MANUAL_SUBMODULES) - endfunction () - - message(STATUS "Checking submodules") -+# check_submodule(external/bc-ur) - check_submodule(external/miniupnp) - check_submodule(external/rapidjson) - check_submodule(external/trezor-common) + function (die msg) diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt -index 538e4d215..074e23f16 100644 +index b16723b63..9d3bcd853 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt -@@ -70,4 +70,5 @@ endif() +@@ -66,5 +66,6 @@ endif() add_subdirectory(db_drivers) add_subdirectory(easylogging++) add_subdirectory(qrcodegen) +add_subdirectory(bc-ur) add_subdirectory(randomx EXCLUDE_FROM_ALL) -diff --git a/external/bc-ur b/external/bc-ur -new file mode 160000 -index 000000000..d82e7c753 ---- /dev/null -+++ b/external/bc-ur -@@ -0,0 +1 @@ -+Subproject commit d82e7c753e710b8000706dc3383b498438795208 + add_subdirectory(mx25519) diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp -index 6dde4a564..7e4be6347 100644 +index 7369620ca..45a01abd0 100644 --- a/src/device/device_ledger.cpp +++ b/src/device/device_ledger.cpp -@@ -313,12 +313,13 @@ namespace hw { - - /* ======================================================================= */ +@@ -316,10 +316,12 @@ namespace hw { /* LOCKER */ -- /* ======================================================================= */ -+ /* ======================================================================= */ + /* ======================================================================= */ - //automatic lock one more level on device ensuring the current thread is allowed to use it + #pragma message ("Warning AUTO_LOCK_CMD is intentionally left broken. This is yet to be fixed.") ++ + //automatic lock one more level on device ensuring the current thread is allowed to use it #define AUTO_LOCK_CMD() \ /* lock both mutexes without deadlock*/ \ -- boost::lock(device_locker, command_locker); \ -+ /* boost::lock(device_locker, command_locker); */ \ +- std::lock(device_locker, command_locker); \ ++ /* std::lock(device_locker, command_locker); */ \ /* make sure both already-locked mutexes are unlocked at the end of scope */ \ - boost::lock_guard lock1(device_locker, boost::adopt_lock); \ - boost::lock_guard lock2(command_locker, boost::adopt_lock) + std::lock_guard lock1(device_locker, std::adopt_lock); \ + std::lock_guard lock2(command_locker, std::adopt_lock) diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt -index 6095f99d5..b163212b7 100644 +index 9bffe76be..f128d5c0c 100644 --- a/src/wallet/CMakeLists.txt +++ b/src/wallet/CMakeLists.txt -@@ -50,6 +50,7 @@ monero_add_library(wallet +@@ -52,6 +52,7 @@ monero_add_library(wallet target_link_libraries(wallet PUBLIC rpc_base + bc-ur multisig + carrot_impl common - cryptonote_core diff --git a/src/wallet/api/pending_transaction.cpp b/src/wallet/api/pending_transaction.cpp -index 70a702796..9c3c26ee5 100644 +index 1618b915d..919e210f0 100644 --- a/src/wallet/api/pending_transaction.cpp +++ b/src/wallet/api/pending_transaction.cpp @@ -42,6 +42,8 @@ @@ -172,7 +152,7 @@ index 70a702796..9c3c26ee5 100644 { uint64_t result = 0; diff --git a/src/wallet/api/pending_transaction.h b/src/wallet/api/pending_transaction.h -index 0a9779c07..403bfe281 100644 +index 9d8d754c0..8a70d774d 100644 --- a/src/wallet/api/pending_transaction.h +++ b/src/wallet/api/pending_transaction.h @@ -46,6 +46,7 @@ public: @@ -184,7 +164,7 @@ index 0a9779c07..403bfe281 100644 uint64_t dust() const override; uint64_t fee() const override; diff --git a/src/wallet/api/unsigned_transaction.cpp b/src/wallet/api/unsigned_transaction.cpp -index 6165a2240..fd03e959d 100644 +index c549539e5..062df7f41 100644 --- a/src/wallet/api/unsigned_transaction.cpp +++ b/src/wallet/api/unsigned_transaction.cpp @@ -40,6 +40,8 @@ @@ -244,7 +224,7 @@ index 6165a2240..fd03e959d 100644 bool UnsignedTransactionImpl::checkLoadedTx(const std::function get_num_txes, const std::function &get_tx, const std::string &extra_message) { diff --git a/src/wallet/api/unsigned_transaction.h b/src/wallet/api/unsigned_transaction.h -index 30065a7fa..a94b23f75 100644 +index b07d43fb1..76165a230 100644 --- a/src/wallet/api/unsigned_transaction.h +++ b/src/wallet/api/unsigned_transaction.h @@ -53,6 +53,7 @@ public: @@ -256,18 +236,18 @@ index 30065a7fa..a94b23f75 100644 uint64_t minMixinCount() const override; diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp -index 6301bd1ef..d179e502b 100644 +index b6ce7b05a..b1ffe77a7 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp -@@ -47,6 +47,7 @@ +@@ -51,6 +51,7 @@ + #endif - #include #include +#include "bc-ur/src/bc-ur.hpp" using namespace std; using namespace cryptonote; -@@ -1066,6 +1067,24 @@ uint64_t WalletImpl::unlockedBalance(uint32_t accountIndex) const +@@ -1012,6 +1013,24 @@ uint64_t WalletImpl::unlockedBalance(uint32_t accountIndex) const return m_wallet->unlocked_balance(accountIndex, false); } @@ -291,8 +271,8 @@ index 6301bd1ef..d179e502b 100644 + uint64_t WalletImpl::blockChainHeight() const { - if(m_wallet->light_wallet()) { -@@ -1208,6 +1227,61 @@ UnsignedTransaction *WalletImpl::loadUnsignedTx(const std::string &unsigned_file + return m_wallet->get_blockchain_current_height(); +@@ -1145,6 +1164,61 @@ UnsignedTransaction *WalletImpl::loadUnsignedTx(const std::string &unsigned_file return transaction; } @@ -354,7 +334,7 @@ index 6301bd1ef..d179e502b 100644 bool WalletImpl::submitTransaction(const string &fileName) { clearStatus(); if (checkBackgroundSync("cannot submit tx")) -@@ -1228,6 +1302,61 @@ bool WalletImpl::submitTransaction(const string &fileName) { +@@ -1165,6 +1239,61 @@ bool WalletImpl::submitTransaction(const string &fileName) { return true; } @@ -416,7 +396,7 @@ index 6301bd1ef..d179e502b 100644 bool WalletImpl::exportKeyImages(const string &filename, bool all) { if (m_wallet->watch_only()) -@@ -1255,6 +1384,39 @@ bool WalletImpl::exportKeyImages(const string &filename, bool all) +@@ -1192,6 +1321,39 @@ bool WalletImpl::exportKeyImages(const string &filename, bool all) return true; } @@ -456,7 +436,7 @@ index 6301bd1ef..d179e502b 100644 bool WalletImpl::importKeyImages(const string &filename) { if (checkBackgroundSync("cannot import key images")) -@@ -1280,6 +1442,62 @@ bool WalletImpl::importKeyImages(const string &filename) +@@ -1217,6 +1379,62 @@ bool WalletImpl::importKeyImages(const string &filename) return true; } @@ -519,7 +499,7 @@ index 6301bd1ef..d179e502b 100644 bool WalletImpl::exportOutputs(const string &filename, bool all) { if (checkBackgroundSync("cannot export outputs")) -@@ -1312,6 +1530,40 @@ bool WalletImpl::exportOutputs(const string &filename, bool all) +@@ -1249,6 +1467,40 @@ bool WalletImpl::exportOutputs(const string &filename, bool all) return true; } @@ -560,7 +540,7 @@ index 6301bd1ef..d179e502b 100644 bool WalletImpl::importOutputs(const string &filename) { if (checkBackgroundSync("cannot import outputs")) -@@ -1346,6 +1598,61 @@ bool WalletImpl::importOutputs(const string &filename) +@@ -1283,6 +1535,61 @@ bool WalletImpl::importOutputs(const string &filename) return true; } @@ -623,10 +603,10 @@ index 6301bd1ef..d179e502b 100644 { if (checkBackgroundSync("cannot scan transactions")) diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h -index ac7ce2f6a..edf8bb8ce 100644 +index 365025c6e..a50983a69 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h -@@ -112,6 +112,7 @@ public: +@@ -113,6 +113,7 @@ public: bool setProxy(const std::string &address) override; uint64_t balance(uint32_t accountIndex = 0) const override; uint64_t unlockedBalance(uint32_t accountIndex = 0) const override; @@ -634,7 +614,7 @@ index ac7ce2f6a..edf8bb8ce 100644 uint64_t blockChainHeight() const override; uint64_t approximateBlockChainHeight() const override; uint64_t estimateBlockChainHeight() const override; -@@ -164,11 +165,18 @@ public: +@@ -166,11 +167,18 @@ public: std::set subaddr_indices = {}) override; virtual PendingTransaction * createSweepUnmixableTransaction() override; bool submitTransaction(const std::string &fileName) override; @@ -654,10 +634,10 @@ index ac7ce2f6a..edf8bb8ce 100644 bool setupBackgroundSync(const BackgroundSyncType background_sync_type, const std::string &wallet_password, const optional &background_cache_password = optional()) override; diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h -index e349df176..764adbfbf 100644 +index 2bedcc7d2..308bcad4b 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h -@@ -91,6 +91,7 @@ struct PendingTransaction +@@ -83,6 +83,7 @@ struct PendingTransaction virtual std::string errorString() const = 0; // commit transaction or save to file if filename is provided. virtual bool commit(const std::string &filename = "", bool overwrite = false) = 0; @@ -665,7 +645,7 @@ index e349df176..764adbfbf 100644 virtual uint64_t amount() const = 0; virtual uint64_t dust() const = 0; virtual uint64_t fee() const = 0; -@@ -160,7 +161,8 @@ struct UnsignedTransaction +@@ -152,7 +153,8 @@ struct UnsignedTransaction * @param signedFileName * return - true on success */ @@ -675,7 +655,7 @@ index e349df176..764adbfbf 100644 }; /** -@@ -626,6 +628,7 @@ struct Wallet +@@ -619,6 +621,7 @@ struct Wallet result += unlockedBalance(i); return result; } @@ -683,7 +663,7 @@ index e349df176..764adbfbf 100644 /** * @brief watchOnly - checks if wallet is watch only -@@ -884,13 +887,15 @@ struct Wallet +@@ -886,13 +889,15 @@ struct Wallet * after object returned */ virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) = 0; @@ -702,7 +682,7 @@ index e349df176..764adbfbf 100644 /*! * \brief disposeTransaction - destroys transaction object -@@ -906,6 +911,8 @@ struct Wallet +@@ -908,6 +913,8 @@ struct Wallet virtual uint64_t estimateTransactionFee(const std::vector> &destinations, PendingTransaction::Priority priority) const = 0; @@ -711,7 +691,7 @@ index e349df176..764adbfbf 100644 /*! * \brief exportKeyImages - exports key images to file * \param filename -@@ -913,20 +920,22 @@ struct Wallet +@@ -915,20 +922,22 @@ struct Wallet * \return - true on success */ virtual bool exportKeyImages(const std::string &filename, bool all = false) = 0; @@ -736,7 +716,7 @@ index e349df176..764adbfbf 100644 /*! * \brief importOutputs - imports outputs from file -@@ -934,6 +943,7 @@ struct Wallet +@@ -936,6 +945,7 @@ struct Wallet * \return - true on success */ virtual bool importOutputs(const std::string &filename) = 0; @@ -745,10 +725,10 @@ index e349df176..764adbfbf 100644 /*! * \brief scanTransactions - scan a list of transaction ids, this operation may reveal the txids to the remote node and affect your privacy diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp -index ac2a1fec3..a8db99c3f 100644 +index 2c2268f7a..131c9cccf 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp -@@ -953,6 +953,16 @@ uint32_t get_subaddress_clamped_sum(uint32_t idx, uint32_t extra) +@@ -974,6 +974,16 @@ uint32_t get_subaddress_clamped_sum(uint32_t idx, uint32_t extra) return idx + extra; } @@ -765,7 +745,7 @@ index ac2a1fec3..a8db99c3f 100644 static void setup_shim(hw::wallet_shim * shim, tools::wallet2 * wallet) { shim->get_tx_pub_key_from_received_outs = std::bind(&tools::wallet2::get_tx_pub_key_from_received_outs, wallet, std::placeholders::_1); -@@ -7065,6 +7075,25 @@ uint64_t wallet2::unlocked_balance(uint32_t index_major, bool strict, uint64_t * +@@ -7311,6 +7321,25 @@ uint64_t wallet2::unlocked_balance(uint32_t index_major, bool strict, uint64_t * return amount; } //---------------------------------------------------------------------------------------------------- @@ -791,18 +771,7 @@ index ac2a1fec3..a8db99c3f 100644 std::map wallet2::balance_per_subaddress(uint32_t index_major, bool strict) const { std::map amount_per_subaddr; -@@ -7916,9 +7945,7 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, std::vector additional_derivations; - -- // compute public keys from out secret keys -- crypto::public_key tx_pub_key; -- crypto::secret_key_to_public_key(txs[n].tx_key, tx_pub_key); -+ crypto::public_key tx_pub_key = get_tx_pub_key_from_extra(tx); - std::vector additional_tx_pub_keys; - for (const crypto::secret_key &skey: txs[n].additional_tx_keys) - { -@@ -11261,7 +11288,7 @@ std::vector wallet2::create_transactions_2(std::vector wallet2::create_transactions_2( MDEBUG("Ignoring output " << i << " of amount " << print_money(td.amount()) << " which is below fractional threshold " << print_money(fractional_threshold)); continue; } @@ -811,7 +780,7 @@ index ac2a1fec3..a8db99c3f 100644 { if (td.amount() > m_ignore_outputs_above || td.amount() < m_ignore_outputs_below) { -@@ -11311,9 +11338,15 @@ std::vector wallet2::create_transactions_2(std::vector wallet2::create_transactions_2( LOG_PRINT_L2("Starting with " << num_nondust_outputs << " non-dust outputs and " << num_dust_outputs << " dust outputs"); @@ -829,71 +798,31 @@ index ac2a1fec3..a8db99c3f 100644 // if empty, put dummy entry so that the front can be referenced later in the loop if (unused_dust_indices_per_subaddr.empty()) unused_dust_indices_per_subaddr.push_back({}); -@@ -13949,33 +13982,40 @@ crypto::public_key wallet2::get_tx_pub_key_from_received_outs(const tools::walle - - bool wallet2::export_key_images(const std::string &filename, bool all) const - { -- PERF_TIMER(export_key_images); -- std::pair>> ski = export_key_images(all); -- std::string magic(KEY_IMAGE_EXPORT_FILE_MAGIC, strlen(KEY_IMAGE_EXPORT_FILE_MAGIC)); -- const cryptonote::account_public_address &keys = get_account().get_keys().m_account_address; -- const uint32_t offset = ski.first; -+ std::string data = export_key_images_str(all); -+ return save_to_file(filename, data); -+} - -- std::string data; -- data.reserve(4 + ski.second.size() * (sizeof(crypto::key_image) + sizeof(crypto::signature)) + 2 * sizeof(crypto::public_key)); -- data.resize(4); -- data[0] = offset & 0xff; -- data[1] = (offset >> 8) & 0xff; -- data[2] = (offset >> 16) & 0xff; -- data[3] = (offset >> 24) & 0xff; -- data += std::string((const char *)&keys.m_spend_public_key, sizeof(crypto::public_key)); -- data += std::string((const char *)&keys.m_view_public_key, sizeof(crypto::public_key)); -- for (const auto &i: ski.second) -- { -- data += std::string((const char *)&i.first, sizeof(crypto::key_image)); -- data += std::string((const char *)&i.second, sizeof(crypto::signature)); -- } -+std::string wallet2::export_key_images_str(bool all) const +@@ -13556,7 +13591,13 @@ crypto::public_key wallet2::get_tx_pub_key_from_received_outs(const tools::walle + return main_tx_pubkey; + } + //---------------------------------------------------------------------------------------------------- +-bool wallet2::export_key_images(const std::string &filename, bool all) const ++bool wallet2::export_key_images(bool all) const +{ -+ PERF_TIMER(export_key_images); -+ std::pair>> ski = export_key_images(all); -+ std::string magic(KEY_IMAGE_EXPORT_FILE_MAGIC, strlen(KEY_IMAGE_EXPORT_FILE_MAGIC)); -+ const cryptonote::account_public_address &keys = get_account().get_keys().m_account_address; -+ const uint32_t offset = ski.first; - -- // encrypt data, keep magic plaintext -- PERF_TIMER(export_key_images_encrypt); -- std::string ciphertext = encrypt_with_view_secret_key(data); -- return save_to_file(filename, magic + ciphertext); -+ std::string data; -+ data.reserve(4 + ski.second.size() * (sizeof(crypto::key_image) + sizeof(crypto::signature)) + 2 * sizeof(crypto::public_key)); -+ data.resize(4); -+ data[0] = offset & 0xff; -+ data[1] = (offset >> 8) & 0xff; -+ data[2] = (offset >> 16) & 0xff; -+ data[3] = (offset >> 24) & 0xff; -+ data += std::string((const char *)&keys.m_spend_public_key, sizeof(crypto::public_key)); -+ data += std::string((const char *)&keys.m_view_public_key, sizeof(crypto::public_key)); -+ for (const auto &i: ski.second) -+ { -+ data += std::string((const char *)&i.first, sizeof(crypto::key_image)); -+ data += std::string((const char *)&i.second, sizeof(crypto::signature)); -+ } ++ std::string data = export_key_images_str(all); ++ return save_to_file(filename, data); ++} + -+ // encrypt data, keep magic plaintext -+ PERF_TIMER(export_key_images_encrypt); -+ std::string ciphertext = encrypt_with_view_secret_key(data); -+ return magic + ciphertext; ++std::string wallet2::export_key_images_str(const std::string &filename, bool all) const + { + PERF_TIMER(export_key_images); + std::pair>> ski = export_key_images(all); +@@ -13582,7 +13623,7 @@ bool wallet2::export_key_images(const std::string &filename, bool all) const + // encrypt data, keep magic plaintext + PERF_TIMER(export_key_images_encrypt); + std::string ciphertext = encrypt_with_view_secret_key(data); +- return save_to_file(filename, magic + ciphertext); ++ return magic + ciphertext; } -+ //---------------------------------------------------------------------------------------------------- - std::pair>> wallet2::export_key_images(bool all) const - { -@@ -14030,53 +14070,60 @@ std::pair> +@@ -13639,53 +13680,60 @@ std::pair> return std::make_pair(offset, ski); } @@ -973,10 +902,10 @@ index ac2a1fec3..a8db99c3f 100644 ski.push_back(std::make_pair(key_image, signature)); } diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h -index 92f735f96..18e60d89a 100644 +index 31f9aa913..e7dfd0ddf 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h -@@ -1164,6 +1164,7 @@ private: +@@ -670,6 +670,7 @@ private: // locked & unlocked balance of given or current subaddress account uint64_t balance(uint32_t subaddr_index_major, bool strict) const; uint64_t unlocked_balance(uint32_t subaddr_index_major, bool strict, uint64_t *blocks_to_unlock = NULL, uint64_t *time_to_unlock = NULL); @@ -984,7 +913,7 @@ index 92f735f96..18e60d89a 100644 // locked & unlocked balance per subaddress of given or current subaddress account std::map balance_per_subaddress(uint32_t subaddr_index_major, bool strict) const; std::map>> unlocked_balance_per_subaddress(uint32_t subaddr_index_major, bool strict); -@@ -1639,9 +1640,11 @@ private: +@@ -1199,9 +1200,11 @@ private: std::tuple> export_blockchain() const; void import_blockchain(const std::tuple> &bc); bool export_key_images(const std::string &filename, bool all = false) const; @@ -997,5 +926,5 @@ index 92f735f96..18e60d89a 100644 bool import_key_images(signed_tx_set & signed_tx, size_t offset=0, bool only_selected_transfers=false); crypto::public_key get_tx_pub_key_from_received_outs(const tools::wallet2::transfer_details &td) const; -- -2.50.1 (Apple Git-155) +2.51.0 diff --git a/patches/monero/0006-add-dummy-device-for-ledger.patch b/patches/monero/0006-add-dummy-device-for-ledger.patch index 816ad5d..db9512c 100644 --- a/patches/monero/0006-add-dummy-device-for-ledger.patch +++ b/patches/monero/0006-add-dummy-device-for-ledger.patch @@ -1,7 +1,7 @@ -From eb9ffa912fb31dd2bddf96d7d55d5e5f9d8219b4 Mon Sep 17 00:00:00 2001 +From 8dc2464244e60bf03f0605360663e2e62864bf02 Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto Date: Thu, 8 May 2025 13:14:23 +0200 -Subject: [PATCH 06/20] add dummy device for ledger +Subject: [PATCH 06/17] add dummy device for ledger --- CMakeLists.txt | 19 ++-- @@ -11,20 +11,20 @@ Subject: [PATCH 06/20] add dummy device for ledger src/device/device_io_dummy.cpp | 161 ++++++++++++++++++++++++++++++ src/device/device_io_dummy.hpp | 82 +++++++++++++++ src/device/device_ledger.cpp | 6 +- - src/device/device_ledger.hpp | 7 +- + src/device/device_ledger.hpp | 9 +- src/wallet/api/wallet.cpp | 100 +++++++++++++++++++ src/wallet/api/wallet.h | 14 +++ src/wallet/api/wallet2_api.h | 13 +++ src/wallet/api/wallet_manager.cpp | 12 ++- - 12 files changed, 411 insertions(+), 31 deletions(-) + 12 files changed, 412 insertions(+), 32 deletions(-) create mode 100644 src/device/device_io_dummy.cpp create mode 100644 src/device/device_io_dummy.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt -index 268339201..eb0d12225 100644 +index ee46cabcd..dbd0b2d48 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt -@@ -692,16 +692,21 @@ include_directories(${LMDB_INCLUDE}) +@@ -664,16 +664,21 @@ include_directories(${LMDB_INCLUDE}) include_directories(${LIBUNWIND_INCLUDE}) link_directories(${LIBUNWIND_LIBRARY_DIRS}) @@ -54,7 +54,7 @@ index 268339201..eb0d12225 100644 include(CheckTrezor) diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt -index e4f1159b5..14d398f87 100644 +index e8901cd4c..a0cdcdd1d 100644 --- a/src/device/CMakeLists.txt +++ b/src/device/CMakeLists.txt @@ -29,10 +29,11 @@ @@ -84,7 +84,7 @@ index e4f1159b5..14d398f87 100644 ${device_headers} device_ledger.hpp diff --git a/src/device/device.cpp b/src/device/device.cpp -index e6cd358b6..dd0701e0c 100644 +index e6c39c0b4..8a5d14c41 100644 --- a/src/device/device.cpp +++ b/src/device/device.cpp @@ -29,7 +29,7 @@ @@ -122,7 +122,7 @@ index e6cd358b6..dd0701e0c 100644 return *device->second; } diff --git a/src/device/device.hpp b/src/device/device.hpp -index 392703a24..ffd419779 100644 +index f91ae1ddf..9e262b62a 100644 --- a/src/device/device.hpp +++ b/src/device/device.hpp @@ -34,17 +34,7 @@ @@ -401,19 +401,19 @@ index 000000000..87a5f109f + +#endif // HAVE_HIDAPI diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp -index 7e4be6347..ee330ba59 100644 +index 45a01abd0..a30082e80 100644 --- a/src/device/device_ledger.cpp +++ b/src/device/device_ledger.cpp -@@ -41,7 +41,7 @@ namespace hw { +@@ -38,7 +38,7 @@ namespace hw { namespace ledger { - #ifdef WITH_DEVICE_LEDGER + #if defined(WITH_DEVICE_LEDGER) || defined(HIDAPI_DUMMY) - #undef MONERO_DEFAULT_LOG_CATEGORY - #define MONERO_DEFAULT_LOG_CATEGORY "device.ledger" -@@ -299,7 +299,7 @@ namespace hw { + namespace { + bool apdu_verbose =true; +@@ -300,7 +300,7 @@ namespace hw { device_ledger::device_ledger(): hw_device(0x0101, 0x05, 64, 2000) { this->id = device_id++; @@ -422,7 +422,7 @@ index 7e4be6347..ee330ba59 100644 this->mode = NONE; this->has_view_key = false; this->tx_in_progress = false; -@@ -534,7 +534,9 @@ namespace hw { +@@ -536,7 +536,9 @@ namespace hw { bool device_ledger::connect(void) { this->disconnect(); @@ -433,7 +433,7 @@ index 7e4be6347..ee330ba59 100644 #ifdef DEBUG_HWDEVICE cryptonote::account_public_address pubkey; diff --git a/src/device/device_ledger.hpp b/src/device/device_ledger.hpp -index 61ac6f9c8..44a1af6c8 100644 +index 2634454a7..fe60dffc1 100644 --- a/src/device/device_ledger.hpp +++ b/src/device/device_ledger.hpp @@ -35,6 +35,7 @@ @@ -441,10 +441,10 @@ index 61ac6f9c8..44a1af6c8 100644 #include "log.hpp" #include "device_io_hid.hpp" +#include "device_io_dummy.hpp" - #include - #include + #include -@@ -56,7 +57,7 @@ namespace hw { + namespace hw { +@@ -55,7 +56,7 @@ namespace hw { void register_all(std::map> ®istry); @@ -453,24 +453,25 @@ index 61ac6f9c8..44a1af6c8 100644 // Origin: https://github.com/LedgerHQ/ledger-app-monero/blob/master/src/monero_types.h #define SW_OK 0x9000 -@@ -148,7 +149,11 @@ namespace hw { - mutable boost::mutex command_locker; +@@ -143,7 +144,11 @@ namespace hw { + mutable std::mutex command_locker; //IO -+#if defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI) -+ hw::io::device_io_dummy hw_device; -+#else - hw::io::device_io_hid hw_device; -+#endif +- hw::io::device_io_hid hw_device; ++ #if defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI) ++ hw::io::device_io_dummy hw_device; ++ #else ++ hw::io::device_io_hid hw_device; ++ #endif unsigned int length_send; unsigned char buffer_send[BUFFER_SEND_SIZE]; unsigned int length_recv; diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp -index d179e502b..fb71a0521 100644 +index b1ffe77a7..819982528 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp -@@ -48,6 +48,9 @@ - #include +@@ -52,6 +52,9 @@ + #include #include "bc-ur/src/bc-ur.hpp" +#if defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI) @@ -479,7 +480,7 @@ index d179e502b..fb71a0521 100644 using namespace std; using namespace cryptonote; -@@ -3177,4 +3180,101 @@ uint64_t WalletImpl::getBytesSent() +@@ -3136,4 +3139,101 @@ uint64_t WalletImpl::getBytesSent() return m_wallet->get_bytes_sent(); } @@ -582,10 +583,10 @@ index d179e502b..fb71a0521 100644 + } // namespace diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h -index edf8bb8ce..6bfb61cb8 100644 +index a50983a69..194f21ebe 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h -@@ -301,6 +301,20 @@ private: +@@ -302,6 +302,20 @@ private: // cache connection status to avoid unnecessary RPC calls mutable std::atomic m_is_connected; boost::optional m_daemon_login{}; @@ -607,10 +608,10 @@ index edf8bb8ce..6bfb61cb8 100644 diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h -index 764adbfbf..f433b064f 100644 +index 308bcad4b..302f6b082 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h -@@ -1150,6 +1150,19 @@ struct Wallet +@@ -1146,6 +1146,19 @@ struct Wallet //! get bytes sent virtual uint64_t getBytesSent() = 0; @@ -631,10 +632,10 @@ index 764adbfbf..f433b064f 100644 /** diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp -index e81b8f83a..277be6ac9 100644 +index b18333e8f..bd92f7829 100644 --- a/src/wallet/api/wallet_manager.cpp +++ b/src/wallet/api/wallet_manager.cpp -@@ -188,10 +188,14 @@ bool WalletManagerImpl::verifyWalletPassword(const std::string &keys_file_name, +@@ -184,10 +184,14 @@ bool WalletManagerImpl::verifyWalletPassword(const std::string &keys_file_name, bool WalletManagerImpl::queryWalletDevice(Wallet::Device& device_type, const std::string &keys_file_name, const std::string &password, uint64_t kdf_rounds) const { @@ -654,5 +655,5 @@ index e81b8f83a..277be6ac9 100644 std::vector WalletManagerImpl::findWallets(const std::string &path) -- -2.50.1 (Apple Git-155) +2.51.0 diff --git a/patches/monero/0007-polyseed.patch b/patches/monero/0007-polyseed.patch index 5caf7c2..351b1ad 100644 --- a/patches/monero/0007-polyseed.patch +++ b/patches/monero/0007-polyseed.patch @@ -1,7 +1,7 @@ -From da0be39a81107060f032c8242c575f04ad61c59f Mon Sep 17 00:00:00 2001 +From 1b77ce8267c3d22a21e0ba0e6ada121aca3a2603 Mon Sep 17 00:00:00 2001 From: tobtoht Date: Tue, 12 Mar 2024 09:42:37 +0100 -Subject: [PATCH 07/20] polyseed +Subject: [PATCH 07/17] polyseed Co-authored-by: Czarek Nakamoto --- @@ -10,6 +10,7 @@ Co-authored-by: Czarek Nakamoto contrib/epee/include/wipeable_string.h | 7 + contrib/epee/src/wipeable_string.cpp | 10 ++ external/CMakeLists.txt | 2 + + external/bc-ur | 1 + external/polyseed | 1 + external/utf8proc | 1 + src/CMakeLists.txt | 1 + @@ -27,9 +28,10 @@ Co-authored-by: Czarek Nakamoto src/wallet/api/wallet2_api.h | 25 ++++ src/wallet/api/wallet_manager.cpp | 9 ++ src/wallet/api/wallet_manager.h | 10 ++ - src/wallet/wallet2.cpp | 100 ++++++++++++-- - src/wallet/wallet2.h | 30 +++- - 24 files changed, 805 insertions(+), 18 deletions(-) + src/wallet/wallet2.cpp | 97 +++++++++++-- + src/wallet/wallet2.h | 29 +++- + 25 files changed, 803 insertions(+), 17 deletions(-) + create mode 160000 external/bc-ur create mode 160000 external/polyseed create mode 160000 external/utf8proc create mode 100644 src/polyseed/CMakeLists.txt @@ -39,46 +41,44 @@ Co-authored-by: Czarek Nakamoto create mode 100644 src/polyseed/polyseed.hpp diff --git a/.gitmodules b/.gitmodules -index 72af74d55..b838e84e0 100644 +index 8abd99092..011c960f2 100644 --- a/.gitmodules +++ b/.gitmodules -@@ -11,6 +11,12 @@ - path = external/randomx - url = https://github.com/MrCyjaneK/RandomX - branch = cyjan-fix-ios +@@ -25,3 +25,9 @@ + path = external/bc-ur + url = https://github.com/MrCyjaneK/bc-ur + branch = misc +[submodule "external/utf8proc"] + path = external/utf8proc + url = https://github.com/JuliaStrings/utf8proc.git +[submodule "external/polyseed"] + path = external/polyseed + url = https://github.com/tevador/polyseed.git - [submodule "external/supercop"] - path = external/supercop - url = https://github.com/monero-project/supercop +\ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt -index eb0d12225..390339523 100644 +index dbd0b2d48..dfb7a0bd8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt -@@ -371,6 +371,8 @@ if(NOT MANUAL_SUBMODULES) - check_submodule(external/trezor-common) +@@ -384,6 +384,8 @@ if(NOT MANUAL_SUBMODULES) check_submodule(external/randomx) check_submodule(external/supercop) + check_submodule(external/mx25519) + check_submodule(external/polyseed) + check_submodule(external/utf8proc) endif() endif() -@@ -460,7 +462,7 @@ endif() - # elseif(CMAKE_SYSTEM_NAME MATCHES ".*BSDI.*") - # set(BSDI TRUE) +@@ -456,7 +458,7 @@ elseif(CMAKE_SYSTEM_NAME MATCHES ".*BSDI.*") + set(BSDI TRUE) + endif() --include_directories(external/rapidjson/include external/easylogging++ src contrib/epee/include external external/supercop/include) -+include_directories(external/rapidjson/include external/easylogging++ src contrib/epee/include external external/supercop/include external/polyseed/include external/utf8proc) +-include_directories(external/rapidjson/include external/easylogging++ src contrib/epee/include external external/supercop/include external/mx25519/include) ++include_directories(external/rapidjson/include external/easylogging++ src contrib/epee/include external external/supercop/include external/mx25519/include external/polyseed/include external/utf8proc) - if(APPLE) - cmake_policy(SET CMP0042 NEW) + if(MINGW) + set(DEFAULT_STATIC true) diff --git a/contrib/epee/include/wipeable_string.h b/contrib/epee/include/wipeable_string.h -index 65977cd97..594e15de4 100644 +index 0a324c159..16c4a8539 100644 --- a/contrib/epee/include/wipeable_string.h +++ b/contrib/epee/include/wipeable_string.h @@ -34,6 +34,7 @@ @@ -103,7 +103,7 @@ index 65977cd97..594e15de4 100644 private: void grow(size_t sz, size_t reserved = 0); diff --git a/contrib/epee/src/wipeable_string.cpp b/contrib/epee/src/wipeable_string.cpp -index b016f2f48..f2f365b1b 100644 +index 5d4d87d8e..ce1a3baf0 100644 --- a/contrib/epee/src/wipeable_string.cpp +++ b/contrib/epee/src/wipeable_string.cpp @@ -261,4 +261,14 @@ wipeable_string &wipeable_string::operator=(const wipeable_string &other) @@ -122,10 +122,10 @@ index b016f2f48..f2f365b1b 100644 + } diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt -index 074e23f16..f7e35f98f 100644 +index 9d3bcd853..959648e38 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt -@@ -70,5 +70,7 @@ endif() +@@ -66,6 +66,8 @@ endif() add_subdirectory(db_drivers) add_subdirectory(easylogging++) add_subdirectory(qrcodegen) @@ -133,6 +133,14 @@ index 074e23f16..f7e35f98f 100644 +add_subdirectory(utf8proc EXCLUDE_FROM_ALL) add_subdirectory(bc-ur) add_subdirectory(randomx EXCLUDE_FROM_ALL) + add_subdirectory(mx25519) +diff --git a/external/bc-ur b/external/bc-ur +new file mode 160000 +index 000000000..d82e7c753 +--- /dev/null ++++ b/external/bc-ur +@@ -0,0 +1 @@ ++Subproject commit d82e7c753e710b8000706dc3383b498438795208 diff --git a/external/polyseed b/external/polyseed new file mode 160000 index 000000000..bd79f5014 @@ -148,19 +156,19 @@ index 000000000..3de4596fb @@ -0,0 +1 @@ +Subproject commit 3de4596fbe28956855df2ecb3c11c0bbc3535838 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt -index 3335d3c21..06b708cf0 100644 +index f43fec4de..a238faeb5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt -@@ -95,6 +95,7 @@ add_subdirectory(net) +@@ -98,6 +98,7 @@ add_subdirectory(net) add_subdirectory(hardforks) add_subdirectory(blockchain_db) add_subdirectory(mnemonics) +add_subdirectory(polyseed) add_subdirectory(rpc) + add_subdirectory(seraphis_crypto) if(NOT IOS) - add_subdirectory(serialization) diff --git a/src/cryptonote_basic/CMakeLists.txt b/src/cryptonote_basic/CMakeLists.txt -index 1414be1b2..414936a05 100644 +index 5b4a84b67..ed48c15e3 100644 --- a/src/cryptonote_basic/CMakeLists.txt +++ b/src/cryptonote_basic/CMakeLists.txt @@ -71,6 +71,7 @@ target_link_libraries(cryptonote_basic @@ -168,11 +176,11 @@ index 1414be1b2..414936a05 100644 cryptonote_format_utils_basic device + polyseed_wrapper + ringct_basic ${Boost_DATE_TIME_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} - ${Boost_SERIALIZATION_LIBRARY} diff --git a/src/cryptonote_basic/account.cpp b/src/cryptonote_basic/account.cpp -index 4e87d4477..2d556f285 100644 +index 3ba5638bf..aaacf08e4 100644 --- a/src/cryptonote_basic/account.cpp +++ b/src/cryptonote_basic/account.cpp @@ -87,12 +87,16 @@ DISABLE_VS_WARNINGS(4244 4345) @@ -225,7 +233,7 @@ index 4e87d4477..2d556f285 100644 { m_keys.m_account_address.m_spend_public_key = spend_public_key; diff --git a/src/cryptonote_basic/account.h b/src/cryptonote_basic/account.h -index 93d1d28f0..1f76febce 100644 +index de5912032..ce6707b12 100644 --- a/src/cryptonote_basic/account.h +++ b/src/cryptonote_basic/account.h @@ -33,6 +33,7 @@ @@ -263,10 +271,10 @@ index 93d1d28f0..1f76febce 100644 const account_keys& get_keys() const; std::string get_public_address_str(network_type nettype) const; diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h -index 82891b9de..26200bf34 100644 +index fb3adbc6c..ab4efa147 100644 --- a/src/cryptonote_config.h +++ b/src/cryptonote_config.h -@@ -211,6 +211,8 @@ +@@ -243,6 +243,8 @@ #define DNS_BLOCKLIST_LIFETIME (86400 * 8) @@ -814,10 +822,10 @@ index 000000000..2c8c777a7 +#endif //POLYSEED_HPP \ No newline at end of file diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp -index fb71a0521..17a98c066 100644 +index 819982528..277e5ff41 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp -@@ -728,6 +728,28 @@ bool WalletImpl::recoverFromDevice(const std::string &path, const std::string &p +@@ -705,6 +705,28 @@ bool WalletImpl::recoverFromDevice(const std::string &path, const std::string &p return true; } @@ -846,7 +854,7 @@ index fb71a0521..17a98c066 100644 Wallet::Device WalletImpl::getDeviceType() const { return static_cast(m_wallet->get_device_type()); -@@ -845,6 +867,54 @@ std::string WalletImpl::seed(const std::string& seed_offset) const +@@ -822,6 +844,54 @@ std::string WalletImpl::seed(const std::string& seed_offset) const } } @@ -902,10 +910,10 @@ index fb71a0521..17a98c066 100644 { return m_wallet->get_seed_language(); diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h -index 6bfb61cb8..e7873dd78 100644 +index 194f21ebe..179897da2 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h -@@ -79,9 +79,19 @@ public: +@@ -80,9 +80,19 @@ public: bool recoverFromDevice(const std::string &path, const std::string &password, const std::string &device_name); @@ -926,10 +934,10 @@ index 6bfb61cb8..e7873dd78 100644 void setSeedLanguage(const std::string &arg) override; // void setListener(Listener *) {} diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h -index f433b064f..80bfdacb2 100644 +index 302f6b082..fabe77e04 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h -@@ -709,6 +709,10 @@ struct Wallet +@@ -702,6 +702,10 @@ struct Wallet static void warning(const std::string &category, const std::string &str); static void error(const std::string &category, const std::string &str); @@ -940,7 +948,7 @@ index f433b064f..80bfdacb2 100644 /** * @brief StartRefresh - Start/resume refresh thread (refresh every 10 seconds) */ -@@ -1321,6 +1325,27 @@ struct WalletManager +@@ -1317,6 +1321,27 @@ struct WalletManager uint64_t kdf_rounds = 1, WalletListener * listener = nullptr) = 0; @@ -969,10 +977,10 @@ index f433b064f..80bfdacb2 100644 * \brief Closes wallet. In case operation succeeded, wallet object deleted. in case operation failed, wallet object not deleted * \param wallet previously opened / created wallet instance diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp -index 277be6ac9..da2056d8a 100644 +index bd92f7829..4a50ec8cc 100644 --- a/src/wallet/api/wallet_manager.cpp +++ b/src/wallet/api/wallet_manager.cpp -@@ -156,6 +156,15 @@ Wallet *WalletManagerImpl::createWalletFromDevice(const std::string &path, +@@ -152,6 +152,15 @@ Wallet *WalletManagerImpl::createWalletFromDevice(const std::string &path, return wallet; } @@ -989,7 +997,7 @@ index 277be6ac9..da2056d8a 100644 { WalletImpl * wallet_ = dynamic_cast(wallet); diff --git a/src/wallet/api/wallet_manager.h b/src/wallet/api/wallet_manager.h -index a223e1df9..28fcd36c9 100644 +index 45a9f010f..793ac492c 100644 --- a/src/wallet/api/wallet_manager.h +++ b/src/wallet/api/wallet_manager.h @@ -75,6 +75,16 @@ public: @@ -1010,32 +1018,29 @@ index a223e1df9..28fcd36c9 100644 bool walletExists(const std::string &path) override; bool verifyWalletPassword(const std::string &keys_file_name, const std::string &password, bool no_spend_key, uint64_t kdf_rounds = 1) const override; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp -index a8db99c3f..972310343 100644 +index 131c9cccf..837590c6c 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp -@@ -92,6 +92,7 @@ using namespace epee; +@@ -96,6 +96,7 @@ using namespace epee; #include "device/device_cold.hpp" #include "device_trezor/device_trezor.hpp" #include "net/socks_connect.h" +#include "polyseed/include/polyseed.h" - - extern "C" - { -@@ -1281,7 +1282,8 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended, std - m_enable_multisig(false), - m_pool_info_query_time(0), + #include "carrot_impl/address_device_ram_borrowed.h" + #include "carrot_impl/address_utils.h" + #include "carrot_impl/format_utils.h" +@@ -1288,6 +1289,7 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended, std + m_secondary_pool_info_query_time(0), m_has_ever_refreshed_from_node(false), -- m_allow_mismatched_daemon_version(false) -+ m_allow_mismatched_daemon_version(false), -+ m_polyseed(false) + m_allow_mismatched_daemon_version(false), ++ m_polyseed(false), + m_curve_trees(fcmp_pp::curve_trees::curve_trees_v1()), + m_tree_cache(fcmp_pp::curve_trees::TreeCacheV1(m_curve_trees, m_max_reorg_depth)) { - set_rpc_client_secret_key(rct::rct2sk(rct::skGen())); - } -@@ -1486,6 +1488,20 @@ bool wallet2::get_seed(epee::wipeable_string& electrum_words, const epee::wipeab +@@ -1493,6 +1495,19 @@ bool wallet2::get_seed(epee::wipeable_string& electrum_words, const epee::wipeab return true; } //---------------------------------------------------------------------------------------------------- -+ +bool wallet2::get_polyseed(epee::wipeable_string& polyseed, epee::wipeable_string& passphrase) const +{ + if (!m_polyseed) { @@ -1051,8 +1056,8 @@ index a8db99c3f..972310343 100644 +//---------------------------------------------------------------------------------------------------- bool wallet2::get_multisig_seed(epee::wipeable_string& seed, const epee::wipeable_string &passphrase) const { - bool ready; -@@ -4877,6 +4893,9 @@ boost::optional wallet2::get_keys_file_data(const crypt + const multisig::multisig_account_status ms_status{get_multisig_status()}; +@@ -5110,6 +5125,9 @@ boost::optional wallet2::get_keys_file_data(const crypt value2.SetInt(m_enable_multisig ? 1 : 0); json.AddMember("enable_multisig", value2, json.GetAllocator()); @@ -1062,7 +1067,7 @@ index a8db99c3f..972310343 100644 if (m_background_sync_type == BackgroundSyncCustomPassword && !background_keys_file && m_custom_background_key) { value.SetString(reinterpret_cast(m_custom_background_key.get().data()), m_custom_background_key.get().size()); -@@ -5116,6 +5135,7 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st +@@ -5343,6 +5361,7 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st m_enable_multisig = false; m_allow_mismatched_daemon_version = false; m_custom_background_key = boost::none; @@ -1070,7 +1075,7 @@ index a8db99c3f..972310343 100644 } else if(json.IsObject()) { -@@ -5356,6 +5376,9 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st +@@ -5569,6 +5588,9 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, background_sync_type, BackgroundSyncType, Int, false, BackgroundSyncOff); m_background_sync_type = field_background_sync_type; @@ -1080,7 +1085,7 @@ index a8db99c3f..972310343 100644 // Load encryption key used to encrypt background cache crypto::chacha_key custom_background_key; m_custom_background_key = boost::none; -@@ -5675,6 +5698,48 @@ void wallet2::init_type(hw::device::device_type device_type) +@@ -5900,6 +5922,48 @@ void wallet2::init_type(hw::device::device_type device_type) m_key_device_type = device_type; } @@ -1129,7 +1134,7 @@ index a8db99c3f..972310343 100644 /*! * \brief Generates a wallet or restores one. Assumes the multisig setup * has already completed for the provided multisig info. -@@ -5802,7 +5867,7 @@ crypto::secret_key wallet2::generate(const std::string& wallet_, const epee::wip +@@ -6027,7 +6091,7 @@ crypto::secret_key wallet2::generate(const std::string& wallet_, const epee::wip return retval; } @@ -1138,7 +1143,7 @@ index a8db99c3f..972310343 100644 { // -1 month for fluctuations in block time and machine date/time setup. // avg seconds per block -@@ -5826,7 +5891,7 @@ crypto::secret_key wallet2::generate(const std::string& wallet_, const epee::wip +@@ -6051,7 +6115,7 @@ crypto::secret_key wallet2::generate(const std::string& wallet_, const epee::wip // the daemon is currently syncing. // If we use the approximate height we subtract one month as // a safety margin. @@ -1147,7 +1152,7 @@ index a8db99c3f..972310343 100644 uint64_t target_height = get_daemon_blockchain_target_height(err); if (err.empty()) { if (target_height < height) -@@ -13661,7 +13726,7 @@ uint64_t wallet2::get_daemon_blockchain_target_height(string &err) +@@ -13293,7 +13357,7 @@ uint64_t wallet2::get_daemon_blockchain_target_height(string &err) return target_height; } @@ -1156,7 +1161,7 @@ index a8db99c3f..972310343 100644 { // time of v2 fork const time_t fork_time = m_nettype == TESTNET ? 1448285909 : m_nettype == STAGENET ? 1520937818 : 1458748658; -@@ -13670,7 +13735,7 @@ uint64_t wallet2::get_approximate_blockchain_height() const +@@ -13302,7 +13366,7 @@ uint64_t wallet2::get_approximate_blockchain_height() const // avg seconds per block const int seconds_per_block = DIFFICULTY_TARGET_V2; // Calculated blockchain height @@ -1165,7 +1170,7 @@ index a8db99c3f..972310343 100644 // testnet and stagenet got some huge rollbacks, so the estimation is way off static const uint64_t approximate_rolled_back_blocks = m_nettype == TESTNET ? 342100 : m_nettype == STAGENET ? 60000 : 30000; if ((m_nettype == TESTNET || m_nettype == STAGENET) && approx_blockchain_height > approximate_rolled_back_blocks) -@@ -15796,15 +15861,6 @@ bool wallet2::parse_uri(const std::string &uri, std::string &address, std::strin +@@ -15363,15 +15427,6 @@ bool wallet2::parse_uri(const std::string &uri, std::string &address, std::strin //---------------------------------------------------------------------------------------------------- uint64_t wallet2::get_blockchain_height_by_date(uint16_t year, uint8_t month, uint8_t day) { @@ -1181,7 +1186,7 @@ index a8db99c3f..972310343 100644 std::tm date = { 0, 0, 0, 0, 0, 0, 0, 0 }; date.tm_year = year - 1900; date.tm_mon = month - 1; -@@ -15813,7 +15869,23 @@ uint64_t wallet2::get_blockchain_height_by_date(uint16_t year, uint8_t month, ui +@@ -15380,7 +15435,23 @@ uint64_t wallet2::get_blockchain_height_by_date(uint16_t year, uint8_t month, ui { throw std::runtime_error("month or day out of range"); } @@ -1206,18 +1211,18 @@ index a8db99c3f..972310343 100644 uint64_t height_min = 0; uint64_t height_max = get_daemon_blockchain_height(err) - 1; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h -index 18e60d89a..419272a54 100644 +index e7dfd0ddf..1cd72edfb 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h -@@ -72,6 +72,7 @@ +@@ -76,6 +76,7 @@ + #include "common/password.h" + #include "node_rpc_proxy.h" #include "message_store.h" - #include "wallet_light_rpc.h" - #include "wallet_rpc_helpers.h" +#include "polyseed/polyseed.hpp" + #include "fee_priority.h" + #include "fee_algorithm.h" - #undef MONERO_DEFAULT_LOG_CATEGORY - #define MONERO_DEFAULT_LOG_CATEGORY "wallet.wallet2" -@@ -921,6 +922,20 @@ private: +@@ -402,6 +403,20 @@ private: void generate(const std::string& wallet_, const epee::wipeable_string& password, const epee::wipeable_string& multisig_data, bool create_address_file = false); @@ -1238,10 +1243,10 @@ index 18e60d89a..419272a54 100644 /*! * \brief Generates a wallet or restores one. * \param wallet_ Name of wallet file -@@ -1095,6 +1110,15 @@ private: +@@ -598,6 +613,14 @@ private: + */ bool is_deterministic() const; bool get_seed(epee::wipeable_string& electrum_words, const epee::wipeable_string &passphrase = epee::wipeable_string()) const; - + /*! + * \brief get_polyseed Gets the polyseed (if available) and passphrase (if set) needed to recover the wallet. + * @param seed Polyseed mnemonic phrase @@ -1250,11 +1255,10 @@ index 18e60d89a..419272a54 100644 + * Note: both the mnemonic phrase and the passphrase are needed to recover the wallet + */ + bool get_polyseed(epee::wipeable_string& seed, epee::wipeable_string &passphrase) const; -+ + /*! - * \brief Checks if light wallet. A light wallet sends view key to a server where the blockchain is scanned. - */ -@@ -1570,8 +1594,8 @@ private: + * \brief Gets the seed language +@@ -1130,8 +1153,8 @@ private: /*! * \brief Calculates the approximate blockchain height from current date/time. */ @@ -1265,7 +1269,7 @@ index 18e60d89a..419272a54 100644 std::vector select_available_outputs_from_histogram(uint64_t count, bool atleast, bool unlocked, bool allow_rct); std::vector select_available_outputs(const std::function &f); std::vector select_available_unmixable_outputs(); -@@ -1665,6 +1689,7 @@ private: +@@ -1225,6 +1248,7 @@ private: bool parse_uri(const std::string &uri, std::string &address, std::string &payment_id, uint64_t &amount, std::string &tx_description, std::string &recipient_name, std::vector &unknown_parameters, std::string &error); uint64_t get_blockchain_height_by_date(uint16_t year, uint8_t month, uint8_t day); // 1<=month<=12, 1<=day<=31 @@ -1273,7 +1277,7 @@ index 18e60d89a..419272a54 100644 bool is_synced(); -@@ -2011,6 +2036,7 @@ private: +@@ -1606,6 +1630,7 @@ private: std::string seed_language; /*!< Language of the mnemonics (seed). */ bool is_old_file_format; /*!< Whether the wallet file is of an old file format */ bool m_watch_only; /*!< no spend key */ @@ -1282,5 +1286,5 @@ index 18e60d89a..419272a54 100644 uint32_t m_multisig_threshold; std::vector m_multisig_signers; -- -2.50.1 (Apple Git-155) +2.51.0 diff --git a/patches/monero/0008-coin-control.patch b/patches/monero/0008-coin-control.patch index 0ed4fb2..103c1e2 100644 --- a/patches/monero/0008-coin-control.patch +++ b/patches/monero/0008-coin-control.patch @@ -1,7 +1,7 @@ -From 6811bdac7b98fd29c0566e758fc2d4353b9c3cec Mon Sep 17 00:00:00 2001 +From 0a046ce2b4525069ec795f71e6ed63de0664fa87 Mon Sep 17 00:00:00 2001 From: tobtoht Date: Tue, 12 Mar 2024 11:07:57 +0100 -Subject: [PATCH 08/20] coin control +Subject: [PATCH 08/17] coin control --- src/simplewallet/simplewallet.cpp | 2 +- @@ -13,19 +13,19 @@ Subject: [PATCH 08/20] coin control src/wallet/api/wallet.cpp | 170 +++++++++++++++++++++------ src/wallet/api/wallet.h | 10 +- src/wallet/api/wallet2_api.h | 52 ++++++++- - src/wallet/wallet2.cpp | 46 +++++++- - src/wallet/wallet2.h | 11 +- - 11 files changed, 667 insertions(+), 51 deletions(-) + src/wallet/wallet2.cpp | 43 ++++++- + src/wallet/wallet2.h | 10 +- + 11 files changed, 665 insertions(+), 49 deletions(-) create mode 100644 src/wallet/api/coins.cpp create mode 100644 src/wallet/api/coins.h create mode 100644 src/wallet/api/coins_info.cpp create mode 100644 src/wallet/api/coins_info.h diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp -index 39bf169f3..40e25e1d0 100644 +index 74b2d3e81..01f1f840d 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp -@@ -6917,7 +6917,7 @@ bool simple_wallet::transfer_main(const std::vector &args_, bool ca +@@ -6644,7 +6644,7 @@ bool simple_wallet::transfer_main(const std::vector &args_, bool ca { // figure out what tx will be necessary auto ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, priority, extra, @@ -35,7 +35,7 @@ index 39bf169f3..40e25e1d0 100644 if (ptx_vector.empty()) { diff --git a/src/wallet/api/CMakeLists.txt b/src/wallet/api/CMakeLists.txt -index af7948d8a..bb740e2ac 100644 +index 3428de27a..4a2003528 100644 --- a/src/wallet/api/CMakeLists.txt +++ b/src/wallet/api/CMakeLists.txt @@ -40,7 +40,9 @@ set(wallet_api_sources @@ -504,7 +504,7 @@ index 000000000..c43e45abd + +#endif //FEATHER_COINS_INFO_H diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp -index 17a98c066..1b86404be 100644 +index 277e5ff41..f88879cea 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -35,6 +35,7 @@ @@ -515,7 +515,7 @@ index 17a98c066..1b86404be 100644 #include "subaddress_account.h" #include "common_defines.h" #include "common/util.h" -@@ -473,6 +474,7 @@ WalletImpl::WalletImpl(NetworkType nettype, uint64_t kdf_rounds) +@@ -450,6 +451,7 @@ WalletImpl::WalletImpl(NetworkType nettype, uint64_t kdf_rounds) m_wallet->set_refresh_enabled(false); m_addressBook.reset(new AddressBookImpl(this)); m_subaddress.reset(new SubaddressImpl(this)); @@ -523,7 +523,7 @@ index 17a98c066..1b86404be 100644 m_subaddressAccount.reset(new SubaddressAccountImpl(this)); -@@ -2046,7 +2048,7 @@ PendingTransaction* WalletImpl::restoreMultisigTransaction(const string& signDat +@@ -2005,7 +2007,7 @@ PendingTransaction* WalletImpl::restoreMultisigTransaction(const string& signDat // - unconfirmed_transfer_details; // - confirmed_transfer_details) @@ -532,7 +532,7 @@ index 17a98c066..1b86404be 100644 { clearStatus(); -@@ -2083,57 +2085,116 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector amount, uint32_t mixin_count, @@ -747,7 +747,7 @@ index 17a98c066..1b86404be 100644 } PendingTransaction *WalletImpl::createSweepUnmixableTransaction() -@@ -2342,6 +2433,11 @@ AddressBook *WalletImpl::addressBook() +@@ -2302,6 +2393,11 @@ AddressBook *WalletImpl::addressBook() return m_addressBook.get(); } @@ -760,10 +760,10 @@ index 17a98c066..1b86404be 100644 { return m_subaddress.get(); diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h -index e7873dd78..bc782dd4a 100644 +index 179897da2..21af6f510 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h -@@ -46,6 +46,7 @@ class PendingTransactionImpl; +@@ -47,6 +47,7 @@ class PendingTransactionImpl; class UnsignedTransactionImpl; class AddressBookImpl; class SubaddressImpl; @@ -771,7 +771,7 @@ index e7873dd78..bc782dd4a 100644 class SubaddressAccountImpl; struct Wallet2CallbackImpl; -@@ -167,12 +168,14 @@ public: +@@ -169,12 +170,14 @@ public: optional> amount, uint32_t mixin_count, PendingTransaction::Priority priority = PendingTransaction::Priority_Low, uint32_t subaddr_account = 0, @@ -788,7 +788,7 @@ index e7873dd78..bc782dd4a 100644 virtual PendingTransaction * createSweepUnmixableTransaction() override; bool submitTransaction(const std::string &fileName) override; bool submitTransactionUR(const std::string &input) override; -@@ -201,6 +204,7 @@ public: +@@ -203,6 +206,7 @@ public: PendingTransaction::Priority priority) const override; virtual TransactionHistory * history() override; virtual AddressBook * addressBook() override; @@ -803,8 +803,8 @@ index e7873dd78..bc782dd4a 100644 + friend class CoinsImpl; friend class SubaddressImpl; friend class SubaddressAccountImpl; - -@@ -288,6 +293,7 @@ private: + friend class ::WalletApiAccessorTest; +@@ -289,6 +294,7 @@ private: std::unique_ptr m_wallet2Callback; std::unique_ptr m_addressBook; std::unique_ptr m_subaddress; @@ -813,10 +813,10 @@ index e7873dd78..bc782dd4a 100644 // multi-threaded refresh stuff diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h -index 80bfdacb2..97dd29bde 100644 +index fabe77e04..5ae54196e 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h -@@ -263,6 +263,51 @@ struct AddressBook +@@ -255,6 +255,51 @@ struct AddressBook virtual int lookupPaymentID(const std::string &payment_id) const = 0; }; @@ -868,7 +868,7 @@ index 80bfdacb2..97dd29bde 100644 struct SubaddressRow { public: SubaddressRow(std::size_t _rowId, const std::string &_address, const std::string &_label): -@@ -856,7 +901,8 @@ struct Wallet +@@ -858,7 +903,8 @@ struct Wallet optional> amount, uint32_t mixin_count, PendingTransaction::Priority = PendingTransaction::Priority_Low, uint32_t subaddr_account = 0, @@ -878,7 +878,7 @@ index 80bfdacb2..97dd29bde 100644 /*! * \brief createTransaction creates transaction. if dst_addr is an integrated address, payment_id is ignored -@@ -875,7 +921,8 @@ struct Wallet +@@ -877,7 +923,8 @@ struct Wallet optional amount, uint32_t mixin_count, PendingTransaction::Priority = PendingTransaction::Priority_Low, uint32_t subaddr_account = 0, @@ -888,7 +888,7 @@ index 80bfdacb2..97dd29bde 100644 /*! * \brief createSweepUnmixableTransaction creates transaction with unmixable outputs. -@@ -994,6 +1041,7 @@ struct Wallet +@@ -996,6 +1043,7 @@ struct Wallet virtual TransactionHistory * history() = 0; virtual AddressBook * addressBook() = 0; @@ -897,10 +897,10 @@ index 80bfdacb2..97dd29bde 100644 virtual SubaddressAccount * subaddressAccount() = 0; virtual void setListener(WalletListener *) = 0; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp -index 972310343..c50a840b6 100644 +index 837590c6c..e8514a207 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp -@@ -2136,12 +2136,21 @@ bool wallet2::frozen(const multisig_tx_set& txs) const +@@ -2354,12 +2354,21 @@ bool wallet2::frozen(const multisig_tx_set& txs) const return false; } @@ -922,7 +922,7 @@ index 972310343..c50a840b6 100644 void wallet2::thaw(const crypto::key_image &ki) { thaw(get_transfer_details(ki)); -@@ -2152,6 +2161,18 @@ bool wallet2::frozen(const crypto::key_image &ki) const +@@ -2370,6 +2379,18 @@ bool wallet2::frozen(const crypto::key_image &ki) const return frozen(get_transfer_details(ki)); } //---------------------------------------------------------------------------------------------------- @@ -941,23 +941,7 @@ index 972310343..c50a840b6 100644 size_t wallet2::get_transfer_details(const crypto::key_image &ki) const { for (size_t idx = 0; idx < m_transfers.size(); ++idx) -@@ -2563,6 +2584,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote - uint64_t amount = tx.vout[o].amount ? tx.vout[o].amount : tx_scan_info[o].amount; - if (!pool) - { -+ boost::unique_lock lock(m_transfers_mutex); - m_transfers.push_back(transfer_details{}); - transfer_details& td = m_transfers.back(); - td.m_block_height = height; -@@ -2666,6 +2688,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote - uint64_t extra_amount = amount - burnt; - if (!pool) - { -+ boost::unique_lock lock(m_transfers_mutex); - transfer_details &td = m_transfers[kit->second]; - td.m_block_height = height; - td.m_internal_output_index = o; -@@ -10526,7 +10549,7 @@ void wallet2::transfer_selected_rct(std::vector picks; float current_output_relatdness = 1.0f; -@@ -10537,6 +10560,9 @@ std::vector wallet2::pick_preferred_rct_inputs(uint64_t needed_money, ui +@@ -10620,6 +10641,9 @@ std::vector wallet2::pick_preferred_rct_inputs(uint64_t needed_money, ui for (size_t i = 0; i < m_transfers.size(); ++i) { const transfer_details& td = m_transfers[i]; @@ -976,7 +960,7 @@ index 972310343..c50a840b6 100644 if (!is_spent(td, false) && !td.m_frozen && td.is_rct() && td.amount() >= needed_money && is_transfer_unlocked(td) && td.m_subaddr_index.major == subaddr_account && subaddr_indices.count(td.m_subaddr_index.minor) == 1) { if (td.amount() > m_ignore_outputs_above || td.amount() < m_ignore_outputs_below) -@@ -10557,6 +10583,9 @@ std::vector wallet2::pick_preferred_rct_inputs(uint64_t needed_money, ui +@@ -10640,6 +10664,9 @@ std::vector wallet2::pick_preferred_rct_inputs(uint64_t needed_money, ui for (size_t i = 0; i < m_transfers.size(); ++i) { const transfer_details& td = m_transfers[i]; @@ -986,7 +970,7 @@ index 972310343..c50a840b6 100644 if (!is_spent(td, false) && !td.m_frozen && !td.m_key_image_partial && td.is_rct() && is_transfer_unlocked(td) && td.m_subaddr_index.major == subaddr_account && subaddr_indices.count(td.m_subaddr_index.minor) == 1) { if (td.amount() > m_ignore_outputs_above || td.amount() < m_ignore_outputs_below) -@@ -10568,6 +10597,9 @@ std::vector wallet2::pick_preferred_rct_inputs(uint64_t needed_money, ui +@@ -10651,6 +10678,9 @@ std::vector wallet2::pick_preferred_rct_inputs(uint64_t needed_money, ui for (size_t j = i + 1; j < m_transfers.size(); ++j) { const transfer_details& td2 = m_transfers[j]; @@ -996,16 +980,15 @@ index 972310343..c50a840b6 100644 if (td2.amount() > m_ignore_outputs_above || td2.amount() < m_ignore_outputs_below) { MDEBUG("Ignoring output " << j << " of amount " << print_money(td2.amount()) << " which is outside prescribed range [" << print_money(m_ignore_outputs_below) << ", " << print_money(m_ignore_outputs_above) << "]"); -@@ -11140,7 +11172,7 @@ bool wallet2::light_wallet_key_image_is_ours(const crypto::key_image& key_image, - // This system allows for sending (almost) the entire balance, since it does - // not generate spurious change in all txes, thus decreasing the instantaneous - // usable balance. --std::vector wallet2::create_transactions_2(std::vector dsts, const size_t fake_outs_count, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices, const unique_index_container& subtract_fee_from_outputs) -+std::vector wallet2::create_transactions_2(std::vector dsts, const size_t fake_outs_count, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices, const std::vector& preferred_input_list, const unique_index_container& subtract_fee_from_outputs) +@@ -10760,6 +10790,7 @@ std::vector wallet2::create_transactions_2( + const std::vector& extra, + uint32_t subaddr_account, + std::set subaddr_indices, ++ const std::vector& preferred_input_list, + const unique_index_container& subtract_fee_from_outputs, + const std::size_t max_n_inputs) { - //ensure device is let in NONE mode in any case - hw::device &hwdev = m_account.get_device(); -@@ -11348,6 +11380,9 @@ std::vector wallet2::create_transactions_2(std::vector wallet2::create_transactions_2( for (size_t i = 0; i < m_transfers.size(); ++i) { const transfer_details& td = m_transfers[i]; @@ -1015,7 +998,7 @@ index 972310343..c50a840b6 100644 if (m_ignore_fractional_outputs && td.amount() < fractional_threshold) { MDEBUG("Ignoring output " << i << " of amount " << print_money(td.amount()) << " which is below fractional threshold " << print_money(fractional_threshold)); -@@ -11439,7 +11474,7 @@ std::vector wallet2::create_transactions_2(std::vector wallet2::create_transactions_2( // will get us a known fee. uint64_t estimated_fee = estimate_fee(use_per_byte_fee, use_rct, 2, fake_outs_count, 2, extra.size(), bulletproof, clsag, bulletproof_plus, use_view_tags, base_fee, fee_quantization_mask); total_needed_money = needed_money + (subtract_fee_from_outputs.size() ? 0 : estimated_fee); @@ -1024,16 +1007,16 @@ index 972310343..c50a840b6 100644 if (!preferred_inputs.empty()) { string s; -@@ -11918,7 +11953,7 @@ bool wallet2::sanity_check(const std::vector &ptx_vector, c +@@ -11559,7 +11593,7 @@ bool wallet2::sanity_check(const std::vector &ptx_vector, c return true; } --std::vector wallet2::create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices) -+std::vector wallet2::create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices, const std::vector& preferred_input_list) +-std::vector wallet2::create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, fee_priority priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices) ++std::vector wallet2::create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, fee_priority priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices, const std::vector& preferred_input_list) { - std::vector unused_transfers_indices; - std::vector unused_dust_indices; -@@ -11947,6 +11982,9 @@ std::vector wallet2::create_transactions_all(uint64_t below + boost::lock_guard refresh_lock(m_refresh_mutex); + +@@ -11611,6 +11645,9 @@ std::vector wallet2::create_transactions_all(uint64_t below for (size_t i = 0; i < m_transfers.size(); ++i) { const transfer_details& td = m_transfers[i]; @@ -1044,21 +1027,27 @@ index 972310343..c50a840b6 100644 { MDEBUG("Ignoring output " << i << " of amount " << print_money(td.amount()) << " which is below threshold " << print_money(fractional_threshold)); diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h -index 419272a54..d07dc7e8b 100644 +index 1cd72edfb..ae3623d30 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h -@@ -1223,8 +1223,8 @@ private: - bool parse_unsigned_tx_from_str(const std::string &unsigned_tx_st, unsigned_tx_set &exported_txs) const; - bool load_tx(const std::string &signed_filename, std::vector &ptx, std::function accept_func = NULL); - bool parse_tx_from_str(const std::string &signed_tx_st, std::vector &ptx, std::function accept_func); -- std::vector create_transactions_2(std::vector dsts, const size_t fake_outs_count, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices, const unique_index_container& subtract_fee_from_outputs = {}); // pass subaddr_indices by value on purpose -- std::vector create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices); -+ std::vector create_transactions_2(std::vector dsts, const size_t fake_outs_count, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices, const std::vector& preferred_input_list = {}, const unique_index_container& subtract_fee_from_outputs = {}); // pass subaddr_indices by value on purpose +@@ -748,6 +748,7 @@ private: + const std::vector& extra, + uint32_t subaddr_account, + std::set subaddr_indices, // pass subaddr_indices by value on purpose ++ const std::vector& preferred_input_list = {}, + const unique_index_container& subtract_fee_from_outputs = {}, + const std::size_t max_n_inputs = 0); + /** +@@ -765,7 +766,7 @@ private: + * + * Sweep-all-style means that transactions are added until all inputs <= amount `below` are spent. + */ +- std::vector create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, fee_priority priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices); + std::vector create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices, const std::vector& preferred_input_list = {}); - std::vector create_transactions_single(const crypto::key_image &ki, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector& extra); - std::vector create_transactions_from(const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, std::vector unused_transfers_indices, std::vector unused_dust_indices, const size_t fake_outs_count, uint32_t priority, const std::vector& extra); - bool sanity_check(const std::vector &ptx_vector, const std::vector& dsts, const unique_index_container& subtract_fee_from_outputs = {}) const; -@@ -1576,6 +1576,7 @@ private: + /** + * brief: create_transactions_single: create "sweep-single" style txs (or tx proposals in hot/cold & multisig wallets) + * param: ki - the key image of the input that is to be spent +@@ -1122,6 +1123,7 @@ private: uint64_t get_num_rct_outputs(); size_t get_num_transfer_details() const { return m_transfers.size(); } const transfer_details &get_transfer_details(size_t idx) const; @@ -1066,7 +1055,7 @@ index 419272a54..d07dc7e8b 100644 uint8_t get_current_hard_fork(); void get_hard_fork_info(uint8_t version, uint64_t &earliest_height); -@@ -1808,7 +1809,9 @@ private: +@@ -1342,7 +1344,9 @@ private: void freeze(size_t idx); void thaw(size_t idx); bool frozen(size_t idx) const; @@ -1076,16 +1065,16 @@ index 419272a54..d07dc7e8b 100644 void thaw(const crypto::key_image &ki); bool frozen(const crypto::key_image &ki) const; bool frozen(const transfer_details &td) const; -@@ -1849,6 +1852,8 @@ private: +@@ -1379,6 +1383,8 @@ private: + bool is_offline() const { return m_offline; } static std::string get_default_daemon_address() { CRITICAL_REGION_LOCAL(default_daemon_address_lock); return default_daemon_address; } ++ ++ boost::shared_mutex m_transfers_mutex; -+ boost::shared_mutex m_transfers_mutex; -+ + #ifndef IN_UNIT_TESTS private: - /*! - * \brief Stores wallet information to wallet file. -@@ -1920,7 +1925,7 @@ private: +@@ -1517,7 +1523,7 @@ private: std::vector get_unspent_amounts_vector(bool strict); uint64_t get_dynamic_base_fee_estimate(); float get_output_relatedness(const transfer_details &td0, const transfer_details &td1) const; @@ -1095,5 +1084,5 @@ index 419272a54..d07dc7e8b 100644 void set_unspent(size_t idx); bool is_spent(const transfer_details &td, bool strict = true) const; -- -2.50.1 (Apple Git-155) +2.51.0 diff --git a/patches/monero/0009-Add-hex-encoding-and-tx-key-getter-for-PendingTransc.patch b/patches/monero/0009-Add-hex-encoding-and-tx-key-getter-for-PendingTransc.patch index df3b9ad..9a67abb 100644 --- a/patches/monero/0009-Add-hex-encoding-and-tx-key-getter-for-PendingTransc.patch +++ b/patches/monero/0009-Add-hex-encoding-and-tx-key-getter-for-PendingTransc.patch @@ -1,7 +1,7 @@ -From 300a5110cccb1e3caf763b1f9bf5dc0ecc0973c8 Mon Sep 17 00:00:00 2001 +From d65fa370d3e486a31fe5d83e1b83cce8c43e3926 Mon Sep 17 00:00:00 2001 From: M Date: Fri, 21 Apr 2023 15:43:47 -0400 -Subject: [PATCH 09/20] Add hex encoding and tx key getter for +Subject: [PATCH 09/17] Add hex encoding and tx key getter for PendingTransction in wallet api. --- @@ -11,7 +11,7 @@ Subject: [PATCH 09/20] Add hex encoding and tx key getter for 3 files changed, 20 insertions(+) diff --git a/src/wallet/api/pending_transaction.cpp b/src/wallet/api/pending_transaction.cpp -index 9c3c26ee5..1f714d229 100644 +index 919e210f0..40108cee9 100644 --- a/src/wallet/api/pending_transaction.cpp +++ b/src/wallet/api/pending_transaction.cpp @@ -80,6 +80,22 @@ std::vector PendingTransactionImpl::txid() const @@ -38,7 +38,7 @@ index 9c3c26ee5..1f714d229 100644 { diff --git a/src/wallet/api/pending_transaction.h b/src/wallet/api/pending_transaction.h -index 403bfe281..0cc6c58e9 100644 +index 8a70d774d..eb5c75c5f 100644 --- a/src/wallet/api/pending_transaction.h +++ b/src/wallet/api/pending_transaction.h @@ -59,6 +59,8 @@ public: @@ -51,10 +51,10 @@ index 403bfe281..0cc6c58e9 100644 private: friend class WalletImpl; diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h -index 97dd29bde..b5cccac40 100644 +index 5ae54196e..08a4c45a4 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h -@@ -127,6 +127,8 @@ struct PendingTransaction +@@ -119,6 +119,8 @@ struct PendingTransaction * @return vector of base58-encoded signers' public keys */ virtual std::vector signersKeys() const = 0; @@ -64,5 +64,5 @@ index 97dd29bde..b5cccac40 100644 /** -- -2.50.1 (Apple Git-155) +2.51.0 diff --git a/patches/monero/0010-Add-recoverDeterministicWalletFromSpendKey.patch b/patches/monero/0010-Add-recoverDeterministicWalletFromSpendKey.patch index e8f7538..7f3f9ab 100644 --- a/patches/monero/0010-Add-recoverDeterministicWalletFromSpendKey.patch +++ b/patches/monero/0010-Add-recoverDeterministicWalletFromSpendKey.patch @@ -1,7 +1,7 @@ -From 3e15968c13d2a7c0098d26e72168a5774d6cdd89 Mon Sep 17 00:00:00 2001 +From 5e45ae217b3d58418e530e27748407e52d910f01 Mon Sep 17 00:00:00 2001 From: Konstantin Ullrich Date: Wed, 11 Oct 2023 16:47:59 +0200 -Subject: [PATCH 10/20] Add recoverDeterministicWalletFromSpendKey +Subject: [PATCH 10/17] Add recoverDeterministicWalletFromSpendKey This function is used by Cake Wallet to enable polyseed (dart implementation) support. @@ -19,10 +19,10 @@ Co-authored-by: Godwin Asuquo 5 files changed, 75 insertions(+) diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp -index 1b86404be..00918e357 100644 +index f88879cea..a76c33db1 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp -@@ -824,6 +824,35 @@ bool WalletImpl::recover(const std::string &path, const std::string &password, c +@@ -801,6 +801,35 @@ bool WalletImpl::recover(const std::string &path, const std::string &password, c return status() == Status_Ok; } @@ -59,10 +59,10 @@ index 1b86404be..00918e357 100644 { diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h -index bc782dd4a..bfe81c590 100644 +index 21af6f510..d4b11d96a 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h -@@ -77,6 +77,10 @@ public: +@@ -78,6 +78,10 @@ public: const std::string &address_string, const std::string &viewkey_string, const std::string &spendkey_string = ""); @@ -74,10 +74,10 @@ index bc782dd4a..bfe81c590 100644 const std::string &password, const std::string &device_name); diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h -index b5cccac40..fcb8187d4 100644 +index 08a4c45a4..6bfb9e593 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h -@@ -1324,6 +1324,25 @@ struct WalletManager +@@ -1320,6 +1320,25 @@ struct WalletManager return createWalletFromKeys(path, password, language, testnet ? TESTNET : MAINNET, restoreHeight, addressString, viewKeyString, spendKeyString); } @@ -104,10 +104,10 @@ index b5cccac40..fcb8187d4 100644 * \deprecated this method creates a wallet WITHOUT a passphrase, use createWalletFromKeys(..., password, ...) instead * \brief recovers existing wallet using keys. Creates a view only wallet if spend key is omitted diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp -index da2056d8a..c200f52ae 100644 +index 4a50ec8cc..7ee87d04c 100644 --- a/src/wallet/api/wallet_manager.cpp +++ b/src/wallet/api/wallet_manager.cpp -@@ -127,6 +127,22 @@ Wallet *WalletManagerImpl::createWalletFromKeys(const std::string &path, +@@ -123,6 +123,22 @@ Wallet *WalletManagerImpl::createWalletFromKeys(const std::string &path, return wallet; } @@ -131,7 +131,7 @@ index da2056d8a..c200f52ae 100644 const std::string &password, NetworkType nettype, diff --git a/src/wallet/api/wallet_manager.h b/src/wallet/api/wallet_manager.h -index 28fcd36c9..be3ff8184 100644 +index 793ac492c..96373affb 100644 --- a/src/wallet/api/wallet_manager.h +++ b/src/wallet/api/wallet_manager.h @@ -67,6 +67,13 @@ public: @@ -149,5 +149,5 @@ index 28fcd36c9..be3ff8184 100644 const std::string &password, NetworkType nettype, -- -2.50.1 (Apple Git-155) +2.51.0 diff --git a/patches/monero/0011-add-monero-submodule-support.patch b/patches/monero/0011-add-monero-submodule-support.patch index fee1fba..e2bbf90 100644 --- a/patches/monero/0011-add-monero-submodule-support.patch +++ b/patches/monero/0011-add-monero-submodule-support.patch @@ -1,18 +1,17 @@ -From e06b0e86b6b6204bf20c0caadde64da1f0966da1 Mon Sep 17 00:00:00 2001 +From 0b51e896d52843b54fac03da8b3d0182f1b8ae2c Mon Sep 17 00:00:00 2001 From: cyan Date: Thu, 7 Nov 2024 16:46:24 +0000 -Subject: [PATCH 11/20] add monero submodule support +Subject: [PATCH 11/17] add monero submodule support --- - CMakeLists.txt | 12 ++++++------ - src/wallet/wallet_rpc_server.cpp | 2 +- - 2 files changed, 7 insertions(+), 7 deletions(-) + CMakeLists.txt | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt -index 390339523..d0af390d0 100644 +index dfb7a0bd8..303d17dcd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt -@@ -75,7 +75,7 @@ if (${CMAKE_VERSION} VERSION_GREATER "3.0.0" AND CMAKE_MAKE_PROGRAM MATCHES "nin +@@ -80,7 +80,7 @@ if (${CMAKE_VERSION} VERSION_GREATER "3.0.0" AND CMAKE_MAKE_PROGRAM MATCHES "nin set(CMAKE_JOB_POOL_LINK link_job_pool) endif () endif () @@ -21,8 +20,8 @@ index 390339523..d0af390d0 100644 option (USE_CLANG_TIDY_C "Lint the code with clang-tidy - variant C" OFF) option (USE_CLANG_TIDY_CXX "Lint the code with clang-tidy - variant C++" OFF) if (USE_CLANG_TIDY_C AND USE_CLANG_TIDY_CXX) -@@ -223,9 +223,9 @@ function(forbid_undefined_symbols) - cmake_minimum_required(VERSION 3.5) +@@ -228,9 +228,9 @@ function(forbid_undefined_symbols) + cmake_minimum_required(VERSION 3.10) project(test) option(EXPECT_SUCCESS "" ON) -file(WRITE "${CMAKE_SOURCE_DIR}/incorrect_source.cpp" "void undefined_symbol(); void symbol() { undefined_symbol(); }") @@ -33,25 +32,16 @@ index 390339523..d0af390d0 100644 endif() add_library(l0 SHARED incorrect_source.cpp) add_library(l1 MODULE incorrect_source.cpp) -@@ -363,7 +363,7 @@ if(NOT MANUAL_SUBMODULES) - message(FATAL_ERROR "Submodule '${relative_path}' is not up-to-date. Please update all submodules with\ngit submodule update --init --force\nor run cmake with -DMANUAL_SUBMODULES=1\n") - endif() - endfunction () -- -+ - message(STATUS "Checking submodules") - # check_submodule(external/bc-ur) - check_submodule(external/miniupnp) -@@ -390,7 +390,7 @@ else() +@@ -398,7 +398,7 @@ if(PER_BLOCK_CHECKPOINT) endif() list(INSERT CMAKE_MODULE_PATH 0 - "${CMAKE_SOURCE_DIR}/cmake") + "${CMAKE_CURRENT_SOURCE_DIR}/cmake") - if (NOT DEFINED ENV{DEVELOPER_LOCAL_TOOLS}) - message(STATUS "Could not find DEVELOPER_LOCAL_TOOLS in env (not required)") -@@ -1003,7 +1003,7 @@ else() + option(BOOST_IGNORE_SYSTEM_PATHS "Ignore boost system paths for local boost installation" OFF) + if (BOOST_IGNORE_SYSTEM_PATHS) +@@ -952,7 +952,7 @@ include(CheckTrezor) # random crash on startup when asan is on if pie is enabled if(NOT SANITIZE AND ANDROID AND NOT BUILD_GUI_DEPS STREQUAL "ON" OR IOS) @@ -60,19 +50,6 @@ index 390339523..d0af390d0 100644 message(STATUS "Enabling PIE executable") set(PIC_FLAG "") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE") -diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp -index 0cf75a1c4..66def08ef 100644 ---- a/src/wallet/wallet_rpc_server.cpp -+++ b/src/wallet/wallet_rpc_server.cpp -@@ -1261,7 +1261,7 @@ namespace tools - { - uint64_t mixin = m_wallet->adjust_mixin(req.ring_size ? req.ring_size - 1 : 0); - uint32_t priority = m_wallet->adjust_priority(req.priority); -- std::vector ptx_vector = m_wallet->create_transactions_2(dsts, mixin, priority, extra, req.account_index, req.subaddr_indices, req.subtract_fee_from_outputs); -+ std::vector ptx_vector = m_wallet->create_transactions_2(dsts, mixin, priority, extra, req.account_index, req.subaddr_indices, {}, req.subtract_fee_from_outputs); - - if (ptx_vector.empty()) - { -- -2.50.1 (Apple Git-155) +2.51.0 diff --git a/patches/monero/0012-fix-iOS-depends-build.patch b/patches/monero/0012-fix-iOS-depends-build.patch index 2e4845e..c61403f 100644 --- a/patches/monero/0012-fix-iOS-depends-build.patch +++ b/patches/monero/0012-fix-iOS-depends-build.patch @@ -1,7 +1,7 @@ -From 92ca945665cab44adace3331685ae4270a14c07e Mon Sep 17 00:00:00 2001 +From d12831d35b6a7d181fb1669f0c7b9f5ccf6f5224 Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto Date: Thu, 21 Nov 2024 06:05:03 -0500 -Subject: [PATCH 12/20] fix iOS depends build +Subject: [PATCH 12/17] fix iOS depends build --- CMakeLists.txt | 4 ---- @@ -11,22 +11,22 @@ Subject: [PATCH 12/20] fix iOS depends build 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt -index d0af390d0..b814c76b7 100644 +index 303d17dcd..d3fda1975 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt -@@ -39,10 +39,6 @@ include(CheckLibraryExists) - include(CheckFunctionExists) - include(FindPythonInterp) +@@ -47,10 +47,6 @@ if (POLICY CMP0077) + cmake_policy(SET CMP0077 NEW) + endif() -if (IOS) - INCLUDE(CmakeLists_IOS.txt) -endif() - - cmake_minimum_required(VERSION 3.5) - message(STATUS "CMake version ${CMAKE_VERSION}") + project(monero) + option (USE_CCACHE "Use ccache if a usable instance is found" ON) diff --git a/src/checkpoints/CMakeLists.txt b/src/checkpoints/CMakeLists.txt -index 665441f62..841df3256 100644 +index cc7f261ed..939aa3b90 100644 --- a/src/checkpoints/CMakeLists.txt +++ b/src/checkpoints/CMakeLists.txt @@ -28,7 +28,11 @@ @@ -43,7 +43,7 @@ index 665441f62..841df3256 100644 find_library(IOKIT_LIBRARY IOKit) mark_as_advanced(IOKIT_LIBRARY) diff --git a/src/cryptonote_basic/CMakeLists.txt b/src/cryptonote_basic/CMakeLists.txt -index 414936a05..81c81767f 100644 +index ed48c15e3..5ec366791 100644 --- a/src/cryptonote_basic/CMakeLists.txt +++ b/src/cryptonote_basic/CMakeLists.txt @@ -28,7 +28,11 @@ @@ -60,10 +60,10 @@ index 414936a05..81c81767f 100644 find_library(IOKIT_LIBRARY IOKit) mark_as_advanced(IOKIT_LIBRARY) diff --git a/src/cryptonote_basic/miner.cpp b/src/cryptonote_basic/miner.cpp -index 71b8f78cc..0f53f024e 100644 +index 258e782a2..e278da0b9 100644 --- a/src/cryptonote_basic/miner.cpp +++ b/src/cryptonote_basic/miner.cpp -@@ -45,7 +45,7 @@ +@@ -46,7 +46,7 @@ #include "boost/logic/tribool.hpp" #include @@ -72,7 +72,7 @@ index 71b8f78cc..0f53f024e 100644 #include #include #include -@@ -883,7 +883,7 @@ namespace cryptonote +@@ -885,7 +885,7 @@ namespace cryptonote return true; @@ -81,7 +81,7 @@ index 71b8f78cc..0f53f024e 100644 mach_msg_type_number_t count; kern_return_t status; -@@ -949,7 +949,7 @@ namespace cryptonote +@@ -951,7 +951,7 @@ namespace cryptonote return true; } @@ -90,7 +90,7 @@ index 71b8f78cc..0f53f024e 100644 struct tms tms; if ( times(&tms) != (clock_t)-1 ) -@@ -978,7 +978,7 @@ namespace cryptonote +@@ -980,7 +980,7 @@ namespace cryptonote return boost::logic::tribool(power_status.ACLineStatus != 1); } @@ -100,5 +100,5 @@ index 71b8f78cc..0f53f024e 100644 #if TARGET_OS_MAC && (!defined(MAC_OS_X_VERSION_MIN_REQUIRED) || MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7) return boost::logic::tribool(IOPSGetTimeRemainingEstimate() != kIOPSTimeRemainingUnlimited); -- -2.50.1 (Apple Git-155) +2.51.0 diff --git a/patches/monero/0013-change-earliest-fork-height-message.patch b/patches/monero/0013-change-earliest-fork-height-message.patch new file mode 100644 index 0000000..53ab468 --- /dev/null +++ b/patches/monero/0013-change-earliest-fork-height-message.patch @@ -0,0 +1,25 @@ +From b635126bbe684ce566b5666aa66a66fcd8774bfb Mon Sep 17 00:00:00 2001 +From: Czarek Nakamoto +Date: Wed, 29 Jan 2025 16:13:28 +0100 +Subject: [PATCH 13/17] change earliest fork height message + +--- + src/wallet/wallet2.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp +index e8514a207..12d7f8efc 100644 +--- a/src/wallet/wallet2.cpp ++++ b/src/wallet/wallet2.cpp +@@ -12089,7 +12089,7 @@ bool wallet2::use_fork_rules(uint8_t version, int64_t early_blocks) + boost::optional result = m_node_rpc_proxy.get_height(height); + THROW_WALLET_EXCEPTION_IF(result, error::wallet_internal_error, "Failed to get height"); + result = m_node_rpc_proxy.get_earliest_height(version, earliest_height); +- THROW_WALLET_EXCEPTION_IF(result, error::wallet_internal_error, "Failed to get earliest fork height"); ++ THROW_WALLET_EXCEPTION_IF(result, error::wallet_internal_error, "Failed to get earliest fork height. Please check your connection and/or switch node you are connected to currently."); + + bool close_enough = (int64_t)height >= (int64_t)earliest_height - early_blocks && earliest_height != std::numeric_limits::max(); // start using the rules that many blocks beforehand + if (close_enough) +-- +2.51.0 + diff --git a/patches/monero/0013-include-locale-only-when-targeting-WIN32.patch b/patches/monero/0013-include-locale-only-when-targeting-WIN32.patch deleted file mode 100644 index 56c8132..0000000 --- a/patches/monero/0013-include-locale-only-when-targeting-WIN32.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 60ef2d2a25b07aca8f25ef5016eb4b9b7c253a50 Mon Sep 17 00:00:00 2001 -From: Czarek Nakamoto -Date: Mon, 18 Nov 2024 10:57:37 -0500 -Subject: [PATCH 13/20] include locale only when targeting WIN32 - ---- - CMakeLists.txt | 6 +++++- - src/wallet/api/wallet.cpp | 2 ++ - 2 files changed, 7 insertions(+), 1 deletion(-) - -diff --git a/CMakeLists.txt b/CMakeLists.txt -index b814c76b7..cef44dd1b 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -1090,7 +1090,11 @@ if(NOT Boost_FOUND) - elseif(Boost_FOUND) - message(STATUS "Found Boost Version: ${Boost_VERSION_STRING}") - -- set(BOOST_COMPONENTS filesystem thread date_time chrono serialization program_options locale) -+ set(BOOST_COMPONENTS filesystem thread date_time chrono serialization program_options) -+ -+ if(WIN32) -+ list(APPEND BOOST_COMPONENTS locale) -+ endif() - - # Boost System is header-only since 1.69 - if (Boost_VERSION_STRING VERSION_LESS 1.69.0) -diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp -index 00918e357..107f516f3 100644 ---- a/src/wallet/api/wallet.cpp -+++ b/src/wallet/api/wallet.cpp -@@ -46,7 +46,9 @@ - #include - #include - -+#ifdef WIN32 - #include -+#endif - #include - #include "bc-ur/src/bc-ur.hpp" - #if defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI) --- -2.50.1 (Apple Git-155) - diff --git a/patches/monero/0014-change-earliest-fork-height-message.patch b/patches/monero/0014-change-earliest-fork-height-message.patch deleted file mode 100644 index 3a4321b..0000000 --- a/patches/monero/0014-change-earliest-fork-height-message.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 7c58eb392e94ff5b50bcb15b8d91038476743ba9 Mon Sep 17 00:00:00 2001 -From: Czarek Nakamoto -Date: Wed, 29 Jan 2025 16:13:28 +0100 -Subject: [PATCH 14/20] change earliest fork height message - ---- - src/wallet/wallet2.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp -index c50a840b6..a7532d7ec 100644 ---- a/src/wallet/wallet2.cpp -+++ b/src/wallet/wallet2.cpp -@@ -12380,7 +12380,7 @@ bool wallet2::use_fork_rules(uint8_t version, int64_t early_blocks) - boost::optional result = m_node_rpc_proxy.get_height(height); - THROW_WALLET_EXCEPTION_IF(result, error::wallet_internal_error, "Failed to get height"); - result = m_node_rpc_proxy.get_earliest_height(version, earliest_height); -- THROW_WALLET_EXCEPTION_IF(result, error::wallet_internal_error, "Failed to get earliest fork height"); -+ THROW_WALLET_EXCEPTION_IF(result, error::wallet_internal_error, "Failed to get earliest fork height. Please check your connection and/or switch node you are connected to currently."); - - bool close_enough = (int64_t)height >= (int64_t)earliest_height - early_blocks && earliest_height != std::numeric_limits::max(); // start using the rules that many blocks beforehand - if (close_enough) --- -2.50.1 (Apple Git-155) - diff --git a/patches/monero/0014-serialize-cache-to-JSON.patch b/patches/monero/0014-serialize-cache-to-JSON.patch new file mode 100644 index 0000000..0a034d8 --- /dev/null +++ b/patches/monero/0014-serialize-cache-to-JSON.patch @@ -0,0 +1,464 @@ +From aef21118f5848946c43d38eb82b5697209bed5fa Mon Sep 17 00:00:00 2001 +From: Czarek Nakamoto +Date: Tue, 12 Aug 2025 07:09:14 -0400 +Subject: [PATCH 14/17] serialize cache to JSON + +--- + src/wallet/CMakeLists.txt | 1 + + src/wallet/api/wallet.cpp | 5 + + src/wallet/api/wallet.h | 2 + + src/wallet/api/wallet2_api.h | 3 + + src/wallet/wallet2.h | 7 + + src/wallet/wallet_cache_to_json.cpp | 368 ++++++++++++++++++++++++++++ + 6 files changed, 386 insertions(+) + create mode 100644 src/wallet/wallet_cache_to_json.cpp + +diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt +index f128d5c0c..ad7e6bc55 100644 +--- a/src/wallet/CMakeLists.txt ++++ b/src/wallet/CMakeLists.txt +@@ -40,6 +40,7 @@ set(wallet_sources + message_transporter.cpp + scanning_tools.cpp + tx_builder.cpp ++ wallet_cache_to_json.cpp + ) + + monero_find_all_headers(wallet_private_headers "${CMAKE_CURRENT_SOURCE_DIR}") +diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp +index a76c33db1..380a1e0af 100644 +--- a/src/wallet/api/wallet.cpp ++++ b/src/wallet/api/wallet.cpp +@@ -3431,4 +3431,9 @@ void Wallet::setLedgerCallback(void (*sendToLedgerDevice)(unsigned char *command + #endif + } + ++std::string WalletImpl::serializeCacheToJson() const ++{ ++ return std::string(m_wallet->serialize_cache_to_json()); ++} ++ + } // namespace +diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h +index d4b11d96a..8e4846e27 100644 +--- a/src/wallet/api/wallet.h ++++ b/src/wallet/api/wallet.h +@@ -336,6 +336,8 @@ private: + bool getWaitsForDeviceSend(); + + bool getWaitsForDeviceReceive(); ++ ++ virtual std::string serializeCacheToJson() const override; + }; + + +diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h +index 6bfb9e593..6c69bdd86 100644 +--- a/src/wallet/api/wallet2_api.h ++++ b/src/wallet/api/wallet2_api.h +@@ -1213,6 +1213,9 @@ struct Wallet + static void setDeviceReceivedData(unsigned char* data, size_t len); + static void setDeviceSendData(unsigned char* data, size_t len); + static void setLedgerCallback(void (*sendToLedgerDevice)(unsigned char *command, unsigned int cmd_len)); ++ ++ //! serialize wallet cache to JSON ++ virtual std::string serializeCacheToJson() const = 0; + }; + + /** +diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h +index ae3623d30..447faaa88 100644 +--- a/src/wallet/wallet2.h ++++ b/src/wallet/wallet2.h +@@ -996,6 +996,13 @@ private: + FIELD(m_tree_cache) + END_SERIALIZE() + ++ /*! ++ * \brief Serialize wallet cache fields to JSON ++ * \return const char* pointing to JSON string containing all cache fields ++ */ ++ const char* serialize_cache_to_json() const; ++ ++ + /*! + * \brief Check if wallet keys and bin files exist + * \param file_path Wallet file path +diff --git a/src/wallet/wallet_cache_to_json.cpp b/src/wallet/wallet_cache_to_json.cpp +new file mode 100644 +index 000000000..4743852ca +--- /dev/null ++++ b/src/wallet/wallet_cache_to_json.cpp +@@ -0,0 +1,368 @@ ++#include "wallet2.h" ++#include "serialization/binary_archive.h" ++#include "serialization/json_archive.h" ++#include "serialization/serialization.h" ++#include ++#include ++ ++namespace tools ++{ ++ ++static void write_escaped_json_string(std::ostream& os, const std::string& str) ++{ ++ for (char c : str) { ++ switch (c) { ++ case '"': os << "\\\""; break; ++ case '\\': os << "\\\\"; break; ++ case '\n': os << "\\n"; break; ++ case '\r': os << "\\r"; break; ++ case '\t': os << "\\t"; break; ++ case '\b': os << "\\b"; break; ++ case '\f': os << "\\f"; break; ++ default: os << c; break; ++ } ++ } ++} ++ ++static void post_process_json(std::string& json) ++{ ++ // ": ," --> ": null," ++ size_t pos = 0; ++ while ((pos = json.find(": ,", pos)) != std::string::npos) { ++ json.replace(pos, 3, ": null,"); ++ pos += 7; ++ } ++ ++ // ": }" --> ": null}" ++ pos = 0; ++ while ((pos = json.find(": }", pos)) != std::string::npos) { ++ json.replace(pos, 3, ": null}"); ++ pos += 7; ++ } ++ ++ // ": ]" --> ": null]" ++ pos = 0; ++ while ((pos = json.find(": ]", pos)) != std::string::npos) { ++ json.replace(pos, 3, ": null]"); ++ pos += 7; ++ } ++ ++ // "key": number"hexstring" --> "key": "numberhexstring" ++ pos = 0; ++ while (pos < json.length()) { ++ size_t colon_pos = json.find(": ", pos); ++ if (colon_pos == std::string::npos) break; ++ ++ size_t value_start = colon_pos + 2; ++ if (value_start >= json.length()) break; ++ ++ if (std::isdigit(json[value_start])) { ++ size_t quote_pos = json.find('"', value_start); ++ if (quote_pos != std::string::npos && quote_pos < json.find_first_of(",}]", value_start)) { ++ size_t closing_quote = json.find('"', quote_pos + 1); ++ if (closing_quote != std::string::npos && closing_quote < json.find_first_of(",}]", value_start)) { ++ std::string digits; ++ size_t digit_end = value_start; ++ while (digit_end < quote_pos && std::isdigit(json[digit_end])) { ++ digits += json[digit_end]; ++ digit_end++; ++ } ++ ++ if (digit_end == quote_pos && !digits.empty()) { ++ std::string hex_part = json.substr(quote_pos + 1, closing_quote - quote_pos - 1); ++ ++ std::string replacement = "\"" + digits + hex_part + "\""; ++ json.replace(value_start, closing_quote - value_start + 1, replacement); ++ pos = value_start + replacement.length(); ++ continue; ++ } ++ } ++ } ++ } ++ ++ pos = colon_pos + 1; ++ } ++} ++ ++const char* wallet2::serialize_cache_to_json() const ++{ ++ static std::string json_result; ++ ++ try ++ { ++ std::stringstream oss; ++ json_archive ar(oss, true); // true for pretty printing ++ ++ ar.begin_object(); ++ ++ // MAGIC_FIELD("monero wallet cache") ++ std::string magic = "monero wallet cache"; ++ ar.tag("magic"); ++ ar.serialize_blob((void*)magic.data(), magic.size()); ++ if (!ar.good()) { ++ json_result = "{\"error\":\"Failed to serialize magic field\"}"; ++ return json_result.c_str(); ++ } ++ ++ // VERSION_FIELD(2) ++ uint32_t version = 2; ++ ar.tag("version"); ++ ar.serialize_varint(version); ++ if (!ar.good()) { ++ json_result = "{\"error\":\"Failed to serialize version field\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_blockchain) - hashchain type, has serialization support ++ ar.tag("m_blockchain"); ++ if (!::serialization::serialize(ar, const_cast(m_blockchain))) { ++ json_result = "{\"error\":\"Failed to serialize m_blockchain\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_transfers) - transfer_container (std::vector) ++ ar.tag("m_transfers"); ++ if (!::serialization::serialize(ar, const_cast(m_transfers))) { ++ json_result = "{\"error\":\"Failed to serialize m_transfers\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_account_public_address) - cryptonote::account_public_address ++ ar.tag("m_account_public_address"); ++ if (!::serialization::serialize(ar, const_cast(m_account_public_address))) { ++ json_result = "{\"error\":\"Failed to serialize m_account_public_address\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_key_images) - serializable_unordered_map ++ ar.tag("m_key_images"); ++ if (!::serialization::serialize(ar, const_cast&>(m_key_images))) { ++ json_result = "{\"error\":\"Failed to serialize m_key_images\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_unconfirmed_txs) - serializable_unordered_map ++ ar.tag("m_unconfirmed_txs"); ++ if (!::serialization::serialize(ar, const_cast&>(m_unconfirmed_txs))) { ++ json_result = "{\"error\":\"Failed to serialize m_unconfirmed_txs\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_payments) - payment_container (serializable_unordered_multimap) ++ ar.tag("m_payments"); ++ if (!::serialization::serialize(ar, const_cast(m_payments))) { ++ json_result = "{\"error\":\"Failed to serialize m_payments\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_tx_keys) - serializable_unordered_map ++ ar.tag("m_tx_keys"); ++ if (!::serialization::serialize(ar, const_cast&>(m_tx_keys))) { ++ json_result = "{\"error\":\"Failed to serialize m_tx_keys\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_confirmed_txs) - serializable_unordered_map ++ ar.tag("m_confirmed_txs"); ++ if (!::serialization::serialize(ar, const_cast&>(m_confirmed_txs))) { ++ json_result = "{\"error\":\"Failed to serialize m_confirmed_txs\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_tx_notes) - serializable_unordered_map ++ ar.tag("m_tx_notes"); ++ if (!::serialization::serialize(ar, const_cast&>(m_tx_notes))) { ++ json_result = "{\"error\":\"Failed to serialize m_tx_notes\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_unconfirmed_payments) - serializable_unordered_multimap ++ ar.tag("m_unconfirmed_payments"); ++ if (!::serialization::serialize(ar, const_cast&>(m_unconfirmed_payments))) { ++ json_result = "{\"error\":\"Failed to serialize m_unconfirmed_payments\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_pub_keys) - serializable_unordered_map ++ ar.tag("m_pub_keys"); ++ if (!::serialization::serialize(ar, const_cast&>(m_pub_keys))) { ++ json_result = "{\"error\":\"Failed to serialize m_pub_keys\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_address_book) - std::vector ++ ar.tag("m_address_book"); ++ if (!::serialization::serialize(ar, const_cast&>(m_address_book))) { ++ json_result = "{\"error\":\"Failed to serialize m_address_book\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_scanned_pool_txs[0]) - std::unordered_set ++ ar.tag("m_scanned_pool_txs_0"); ++ if (!::serialization::serialize(ar, const_cast&>(m_scanned_pool_txs[0]))) { ++ json_result = "{\"error\":\"Failed to serialize m_scanned_pool_txs[0]\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_scanned_pool_txs[1]) - std::unordered_set ++ ar.tag("m_scanned_pool_txs_1"); ++ if (!::serialization::serialize(ar, const_cast&>(m_scanned_pool_txs[1]))) { ++ json_result = "{\"error\":\"Failed to serialize m_scanned_pool_txs[1]\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_subaddresses) - serializable_unordered_map ++ ar.tag("m_subaddresses"); ++ if (!::serialization::serialize(ar, const_cast&>(m_subaddresses))) { ++ json_result = "{\"error\":\"Failed to serialize m_subaddresses\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_subaddress_labels) - std::vector> - manual JSON serialization ++ oss << ", \n \"m_subaddress_labels\": ["; ++ for (size_t i = 0; i < m_subaddress_labels.size(); ++i) { ++ if (i > 0) oss << ", "; ++ oss << "\n ["; ++ for (size_t j = 0; j < m_subaddress_labels[i].size(); ++j) { ++ if (j > 0) oss << ", "; ++ oss << "\""; ++ write_escaped_json_string(oss, m_subaddress_labels[i][j]); ++ oss << "\""; ++ } ++ oss << "]"; ++ } ++ oss << "\n ]"; ++ ++ // FIELD(m_additional_tx_keys) - serializable_unordered_map> ++ ar.tag("m_additional_tx_keys"); ++ if (!::serialization::serialize(ar, const_cast>&>(m_additional_tx_keys))) { ++ json_result = "{\"error\":\"Failed to serialize m_additional_tx_keys\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_attributes) - serializable_unordered_map - manual JSON serialization ++ oss << ", \n \"m_attributes\": {"; ++ bool first_attr = true; ++ for (const auto& attr : m_attributes) { ++ if (!first_attr) oss << ", "; ++ first_attr = false; ++ oss << "\n \""; ++ write_escaped_json_string(oss, attr.first); ++ oss << "\": \""; ++ write_escaped_json_string(oss, attr.second); ++ oss << "\""; ++ } ++ oss << "\n }"; ++ ++ // FIELD(m_account_tags) - std::pair, std::vector> - manual JSON serialization ++ oss << ", \n \"m_account_tags\": {"; ++ oss << "\n \"tags_map\": {"; ++ bool first_tag = true; ++ for (const auto& tag : m_account_tags.first) { ++ if (!first_tag) oss << ", "; ++ first_tag = false; ++ oss << "\n \""; ++ write_escaped_json_string(oss, tag.first); ++ oss << "\": \""; ++ write_escaped_json_string(oss, tag.second); ++ oss << "\""; ++ } ++ oss << "\n },"; ++ oss << "\n \"account_list\": ["; ++ for (size_t i = 0; i < m_account_tags.second.size(); ++i) { ++ if (i > 0) oss << ", "; ++ oss << "\n \""; ++ write_escaped_json_string(oss, m_account_tags.second[i]); ++ oss << "\""; ++ } ++ oss << "\n ]"; ++ oss << "\n }"; ++ ++ // FIELD(m_ring_history_saved) - bool ++ // ar.tag("m_ring_history_saved"); ++ // ar.serialize_blob(&m_ring_history_saved, sizeof(m_ring_history_saved)); ++ // if (!ar.good()) { ++ // json_result = "{\"error\":\"Failed to serialize m_ring_history_saved\"}"; ++ // return json_result.c_str(); ++ // } ++ ++ // FIELD(m_last_block_reward) - uint64_t ++ ar.tag("m_last_block_reward"); ++ ar.serialize_int(m_last_block_reward); ++ if (!ar.good()) { ++ json_result = "{\"error\":\"Failed to serialize m_last_block_reward\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_tx_device) - serializable_unordered_map ++ ar.tag("m_tx_device"); ++ if (!::serialization::serialize(ar, const_cast&>(m_tx_device))) { ++ json_result = "{\"error\":\"Failed to serialize m_tx_device\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_device_last_key_image_sync) - uint64_t ++ ar.tag("m_device_last_key_image_sync"); ++ ar.serialize_int(m_device_last_key_image_sync); ++ if (!ar.good()) { ++ json_result = "{\"error\":\"Failed to serialize m_device_last_key_image_sync\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_cold_key_images) - serializable_unordered_map ++ ar.tag("m_cold_key_images"); ++ if (!::serialization::serialize(ar, const_cast&>(m_cold_key_images))) { ++ json_result = "{\"error\":\"Failed to serialize m_cold_key_images\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_rpc_client_secret_key) - crypto::secret_key ++ // ar.tag("m_rpc_client_secret_key"); ++ // ar.serialize_blob(&m_rpc_client_secret_key, sizeof(m_rpc_client_secret_key)); ++ // if (!ar.good()) { ++ // json_result = "{\"error\":\"Failed to serialize m_rpc_client_secret_key\"}"; ++ // return json_result.c_str(); ++ // } ++ ++ // Version-dependent fields ++ if (version >= 1) { ++ // FIELD(m_has_ever_refreshed_from_node) - bool ++ // ar.tag("m_has_ever_refreshed_from_node"); ++ // ar.serialize_blob(&m_has_ever_refreshed_from_node, sizeof(m_has_ever_refreshed_from_node)); ++ // if (!ar.good()) { ++ // json_result = "{\"error\":\"Failed to serialize m_has_ever_refreshed_from_node\"}"; ++ // return json_result.c_str(); ++ // } ++ } ++ ++ if (version >= 2) { ++ // FIELD(m_background_sync_data) - background_sync_data_t ++ ar.tag("m_background_sync_data"); ++ if (!::serialization::serialize(ar, const_cast(m_background_sync_data))) { ++ json_result = "{\"error\":\"Failed to serialize m_background_sync_data\"}"; ++ return json_result.c_str(); ++ } ++ } ++ ++ ar.end_object(); ++ ++ if (!ar.good()) { ++ json_result = "{\"error\":\"Failed to finalize JSON serialization\"}"; ++ return json_result.c_str(); ++ } ++ ++ json_result = oss.str(); ++ ++ // Post-process to fix malformed JSON ++ post_process_json(json_result); ++ ++ return json_result.c_str(); ++ } ++ catch (const std::exception& e) ++ { ++ json_result = "{\"error\":\"Failed to serialize wallet cache: " + std::string(e.what()) + "\"}"; ++ return json_result.c_str(); ++ } ++} ++ ++} // namespace tools +\ No newline at end of file +-- +2.51.0 + diff --git a/patches/monero/0015-drop-generate_translations_header.c-requirement.patch b/patches/monero/0015-drop-generate_translations_header.c-requirement.patch new file mode 100644 index 0000000..80c8cb0 --- /dev/null +++ b/patches/monero/0015-drop-generate_translations_header.c-requirement.patch @@ -0,0 +1,123 @@ +From 522059fc457aa56373c4ce59b66d237397f4e8f0 Mon Sep 17 00:00:00 2001 +From: Czarek Nakamoto +Date: Fri, 20 Feb 2026 08:03:01 +0100 +Subject: [PATCH 15/17] drop generate_translations_header.c requirement + +--- + CMakeLists.txt | 9 +---- + translations/CMakeLists.txt | 79 +++++++++++++------------------------ + 2 files changed, 30 insertions(+), 58 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index d3fda1975..bb258883c 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -638,16 +638,11 @@ endfunction () + # Generate header for embedded translations + # Generate header for embedded translations, use target toolchain if depends, otherwise use the + # lrelease and lupdate binaries from the host +-include(ExternalProject) +-ExternalProject_Add(generate_translations_header +- SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/translations" +- BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/translations" +- STAMP_DIR ${LRELEASE_PATH} +- CMAKE_ARGS -DLRELEASE_PATH=${LRELEASE_PATH} +- INSTALL_COMMAND ${CMAKE_COMMAND} -E echo "") ++add_subdirectory(translations) + include_directories("${CMAKE_CURRENT_BINARY_DIR}/translations") + add_subdirectory(external) + ++ + # Final setup for libunbound + include_directories(${UNBOUND_INCLUDE_DIR}) + +diff --git a/translations/CMakeLists.txt b/translations/CMakeLists.txt +index 4bc579aaa..ad37b8ba7 100644 +--- a/translations/CMakeLists.txt ++++ b/translations/CMakeLists.txt +@@ -30,54 +30,31 @@ cmake_minimum_required(VERSION 3.10) + + project(translations) + +-# when crosscompiling import the executable targets from a file +-IF(CMAKE_CROSSCOMPILING) +- message(WARNING "CrossCompiling") +- SET(IMPORT_EXECUTABLES "${CMAKE_CURRENT_BINARY_DIR}/ImportExecutables.cmake" CACHE FILEPATH "Point it to the export file from a native build") +- INCLUDE(${IMPORT_EXECUTABLES}) +-ENDIF(CMAKE_CROSSCOMPILING) +- +-# only build the generator if not crosscompiling +-IF(NOT CMAKE_CROSSCOMPILING) +- add_executable(generate_translations_header generate_translations_header.c) +-ENDIF(NOT CMAKE_CROSSCOMPILING) +- +-if(LRELEASE_PATH STREQUAL "") +- find_program(LRELEASE lrelease) +-else() +- set(LRELEASE ${LRELEASE_PATH}/lrelease) +-endif() +- +-if(LRELEASE STREQUAL "LRELEASE-NOTFOUND") +- set(ts_files "") +- message(WARNING "lrelease program not found, translation files not built") +-else() +- execute_process(COMMAND ${LRELEASE} -version +- RESULT_VARIABLE lrelease_ret) +- if(NOT lrelease_ret EQUAL "0") +- set(ts_files "") +- message(WARNING "lrelease program not working, translation files not built") +- else() +- file(GLOB ts_files RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" *.ts) +- foreach(ts_file ${ts_files}) +- string(REPLACE ".ts" ".qm" qm_file "${ts_file}") +- add_custom_command(TARGET generate_translations_header +- PRE_BUILD +- COMMAND ${LRELEASE} "${CMAKE_CURRENT_SOURCE_DIR}/${ts_file}" -qm "${qm_file}" +- WORKING_DIRECTORY "${CMAKE_CURRENT_BIN_DIR}") +- endforeach() +- endif() +-endif() +- +-string(REPLACE ".ts" ".qm" qm_files "${ts_files}") +- +-add_custom_command(TARGET generate_translations_header +- POST_BUILD +- COMMAND $ ${qm_files} +- WORKING_DIRECTORY "${CMAKE_CURRENT_BIN_DIR}" +- COMMENT "Generating embedded translations header") +- +-# export the generator target to a file, so it can be imported (see above) by another build +-IF(NOT CMAKE_CROSSCOMPILING) +- EXPORT(TARGETS generate_translations_header FILE ${CMAKE_CURRENT_BINARY_DIR}/ImportExecutables.cmake ) +-ENDIF(NOT CMAKE_CROSSCOMPILING) ++add_custom_target(generate_translations_header) ++ ++file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/translation_files.h" ++"#ifndef TRANSLATION_FILES_H ++#define TRANSLATION_FILES_H ++ ++#include ++ ++static const struct embedded_file { ++ const std::string *name; ++ const std::string *data; ++} embedded_files[] = { ++ {NULL, NULL} ++}; ++ ++static bool find_embedded_file(const std::string &name, std::string &data) { ++ const struct embedded_file *p; ++ for (p = embedded_files; p->name != NULL; p++) { ++ if (*p->name == name) { ++ data = *p->data; ++ return true; ++ } ++ } ++ return false; ++} ++ ++#endif /* TRANSLATION_FILES_H */ ++") +-- +2.51.0 + diff --git a/patches/monero/0015-remove-trivially_copyable-assert.patch b/patches/monero/0015-remove-trivially_copyable-assert.patch deleted file mode 100644 index 8113bdd..0000000 --- a/patches/monero/0015-remove-trivially_copyable-assert.patch +++ /dev/null @@ -1,24 +0,0 @@ -From dc67abfbc3dec2f4aa4c4157378509c9ee07cb0b Mon Sep 17 00:00:00 2001 -From: Czarek Nakamoto -Date: Thu, 20 Feb 2025 08:36:28 +0100 -Subject: [PATCH 15/20] remove trivially_copyable assert - ---- - contrib/epee/include/span.h | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/contrib/epee/include/span.h b/contrib/epee/include/span.h -index 01dc387d6..2ad733a2f 100644 ---- a/contrib/epee/include/span.h -+++ b/contrib/epee/include/span.h -@@ -162,7 +162,6 @@ namespace epee - { - static_assert(!std::is_empty(), "empty types will not work -> sizeof == 1"); - static_assert(std::is_standard_layout(), "type must have standard layout"); -- static_assert(std::is_trivially_copyable(), "type must be trivially copyable"); - static_assert(alignof(T) == 1, "type may have padding"); - return {reinterpret_cast(std::addressof(src)), sizeof(T)}; - } --- -2.50.1 (Apple Git-155) - diff --git a/patches/monero/0016-fix-mingw-build-issues.patch b/patches/monero/0016-fix-mingw-build-issues.patch new file mode 100644 index 0000000..2f19124 --- /dev/null +++ b/patches/monero/0016-fix-mingw-build-issues.patch @@ -0,0 +1,46 @@ +From 4bae0074bf325e11054994f7ac2a825d0cda8f14 Mon Sep 17 00:00:00 2001 +From: Czarek Nakamoto +Date: Wed, 4 Mar 2026 14:52:14 +0100 +Subject: [PATCH 16/17] fix: mingw build issues + +--- + contrib/epee/include/serialization/keyvalue_serialization.h | 1 + + contrib/epee/src/abstract_http_client.cpp | 3 ++- + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/contrib/epee/include/serialization/keyvalue_serialization.h b/contrib/epee/include/serialization/keyvalue_serialization.h +index ccfa2f15e..71f4909e1 100644 +--- a/contrib/epee/include/serialization/keyvalue_serialization.h ++++ b/contrib/epee/include/serialization/keyvalue_serialization.h +@@ -26,6 +26,7 @@ + + #pragma once + ++#include + #include + #include + #include +diff --git a/contrib/epee/src/abstract_http_client.cpp b/contrib/epee/src/abstract_http_client.cpp +index bd9cb0dde..340a7cf85 100644 +--- a/contrib/epee/src/abstract_http_client.cpp ++++ b/contrib/epee/src/abstract_http_client.cpp +@@ -3,6 +3,7 @@ + #include "net/http_base.h" + #include "net/net_parse_helpers.h" + #include "misc_log_ex.h" ++#include + + #undef MONERO_DEFAULT_LOG_CATEGORY + #define MONERO_DEFAULT_LOG_CATEGORY "net.http" +@@ -39,7 +40,7 @@ namespace net_utils + while (num_char >= radix) + { + temp = num_char % radix; +- num_char = (int)floor((float)num_char / (float)radix); ++ num_char = (int)std::floor((float)num_char / (float)radix); + csTmp = get_hex_vals()[temp]; + } + +-- +2.51.0 + diff --git a/patches/monero/0016-serialize-cache-to-JSON.patch b/patches/monero/0016-serialize-cache-to-JSON.patch deleted file mode 100644 index 38aaee4..0000000 --- a/patches/monero/0016-serialize-cache-to-JSON.patch +++ /dev/null @@ -1,463 +0,0 @@ -From e6785290c24eb48d6b6aec8e1831b96f65cd3bfd Mon Sep 17 00:00:00 2001 -From: Czarek Nakamoto -Date: Tue, 12 Aug 2025 07:09:14 -0400 -Subject: [PATCH 16/20] serialize cache to JSON - ---- - src/wallet/CMakeLists.txt | 1 + - src/wallet/api/wallet.cpp | 5 + - src/wallet/api/wallet.h | 2 + - src/wallet/api/wallet2_api.h | 3 + - src/wallet/wallet2.h | 6 + - src/wallet/wallet_cache_to_json.cpp | 368 ++++++++++++++++++++++++++++ - 6 files changed, 385 insertions(+) - create mode 100644 src/wallet/wallet_cache_to_json.cpp - -diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt -index b163212b7..196ad671f 100644 ---- a/src/wallet/CMakeLists.txt -+++ b/src/wallet/CMakeLists.txt -@@ -38,6 +38,7 @@ set(wallet_sources - message_store.cpp - message_transporter.cpp - wallet_rpc_payments.cpp -+ wallet_cache_to_json.cpp - ) - - monero_find_all_headers(wallet_private_headers "${CMAKE_CURRENT_SOURCE_DIR}") -diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp -index 107f516f3..c24b4a97d 100644 ---- a/src/wallet/api/wallet.cpp -+++ b/src/wallet/api/wallet.cpp -@@ -3474,4 +3474,9 @@ void Wallet::setLedgerCallback(void (*sendToLedgerDevice)(unsigned char *command - #endif - } - -+std::string WalletImpl::serializeCacheToJson() const -+{ -+ return std::string(m_wallet->serialize_cache_to_json()); -+} -+ - } // namespace -diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h -index bfe81c590..98c03b9c1 100644 ---- a/src/wallet/api/wallet.h -+++ b/src/wallet/api/wallet.h -@@ -335,6 +335,8 @@ private: - bool getWaitsForDeviceSend(); - - bool getWaitsForDeviceReceive(); -+ -+ virtual std::string serializeCacheToJson() const override; - }; - - -diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h -index fcb8187d4..3d11929f9 100644 ---- a/src/wallet/api/wallet2_api.h -+++ b/src/wallet/api/wallet2_api.h -@@ -1217,6 +1217,9 @@ struct Wallet - static void setDeviceReceivedData(unsigned char* data, size_t len); - static void setDeviceSendData(unsigned char* data, size_t len); - static void setLedgerCallback(void (*sendToLedgerDevice)(unsigned char *command, unsigned int cmd_len)); -+ -+ //! serialize wallet cache to JSON -+ virtual std::string serializeCacheToJson() const = 0; - }; - - /** -diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h -index d07dc7e8b..37a2447d2 100644 ---- a/src/wallet/wallet2.h -+++ b/src/wallet/wallet2.h -@@ -1436,6 +1436,12 @@ private: - FIELD(m_background_sync_data) - END_SERIALIZE() - -+ /*! -+ * \brief Serialize wallet cache fields to JSON -+ * \return const char* pointing to JSON string containing all cache fields -+ */ -+ const char* serialize_cache_to_json() const; -+ - /*! - * \brief Check if wallet keys and bin files exist - * \param file_path Wallet file path -diff --git a/src/wallet/wallet_cache_to_json.cpp b/src/wallet/wallet_cache_to_json.cpp -new file mode 100644 -index 000000000..4743852ca ---- /dev/null -+++ b/src/wallet/wallet_cache_to_json.cpp -@@ -0,0 +1,368 @@ -+#include "wallet2.h" -+#include "serialization/binary_archive.h" -+#include "serialization/json_archive.h" -+#include "serialization/serialization.h" -+#include -+#include -+ -+namespace tools -+{ -+ -+static void write_escaped_json_string(std::ostream& os, const std::string& str) -+{ -+ for (char c : str) { -+ switch (c) { -+ case '"': os << "\\\""; break; -+ case '\\': os << "\\\\"; break; -+ case '\n': os << "\\n"; break; -+ case '\r': os << "\\r"; break; -+ case '\t': os << "\\t"; break; -+ case '\b': os << "\\b"; break; -+ case '\f': os << "\\f"; break; -+ default: os << c; break; -+ } -+ } -+} -+ -+static void post_process_json(std::string& json) -+{ -+ // ": ," --> ": null," -+ size_t pos = 0; -+ while ((pos = json.find(": ,", pos)) != std::string::npos) { -+ json.replace(pos, 3, ": null,"); -+ pos += 7; -+ } -+ -+ // ": }" --> ": null}" -+ pos = 0; -+ while ((pos = json.find(": }", pos)) != std::string::npos) { -+ json.replace(pos, 3, ": null}"); -+ pos += 7; -+ } -+ -+ // ": ]" --> ": null]" -+ pos = 0; -+ while ((pos = json.find(": ]", pos)) != std::string::npos) { -+ json.replace(pos, 3, ": null]"); -+ pos += 7; -+ } -+ -+ // "key": number"hexstring" --> "key": "numberhexstring" -+ pos = 0; -+ while (pos < json.length()) { -+ size_t colon_pos = json.find(": ", pos); -+ if (colon_pos == std::string::npos) break; -+ -+ size_t value_start = colon_pos + 2; -+ if (value_start >= json.length()) break; -+ -+ if (std::isdigit(json[value_start])) { -+ size_t quote_pos = json.find('"', value_start); -+ if (quote_pos != std::string::npos && quote_pos < json.find_first_of(",}]", value_start)) { -+ size_t closing_quote = json.find('"', quote_pos + 1); -+ if (closing_quote != std::string::npos && closing_quote < json.find_first_of(",}]", value_start)) { -+ std::string digits; -+ size_t digit_end = value_start; -+ while (digit_end < quote_pos && std::isdigit(json[digit_end])) { -+ digits += json[digit_end]; -+ digit_end++; -+ } -+ -+ if (digit_end == quote_pos && !digits.empty()) { -+ std::string hex_part = json.substr(quote_pos + 1, closing_quote - quote_pos - 1); -+ -+ std::string replacement = "\"" + digits + hex_part + "\""; -+ json.replace(value_start, closing_quote - value_start + 1, replacement); -+ pos = value_start + replacement.length(); -+ continue; -+ } -+ } -+ } -+ } -+ -+ pos = colon_pos + 1; -+ } -+} -+ -+const char* wallet2::serialize_cache_to_json() const -+{ -+ static std::string json_result; -+ -+ try -+ { -+ std::stringstream oss; -+ json_archive ar(oss, true); // true for pretty printing -+ -+ ar.begin_object(); -+ -+ // MAGIC_FIELD("monero wallet cache") -+ std::string magic = "monero wallet cache"; -+ ar.tag("magic"); -+ ar.serialize_blob((void*)magic.data(), magic.size()); -+ if (!ar.good()) { -+ json_result = "{\"error\":\"Failed to serialize magic field\"}"; -+ return json_result.c_str(); -+ } -+ -+ // VERSION_FIELD(2) -+ uint32_t version = 2; -+ ar.tag("version"); -+ ar.serialize_varint(version); -+ if (!ar.good()) { -+ json_result = "{\"error\":\"Failed to serialize version field\"}"; -+ return json_result.c_str(); -+ } -+ -+ // FIELD(m_blockchain) - hashchain type, has serialization support -+ ar.tag("m_blockchain"); -+ if (!::serialization::serialize(ar, const_cast(m_blockchain))) { -+ json_result = "{\"error\":\"Failed to serialize m_blockchain\"}"; -+ return json_result.c_str(); -+ } -+ -+ // FIELD(m_transfers) - transfer_container (std::vector) -+ ar.tag("m_transfers"); -+ if (!::serialization::serialize(ar, const_cast(m_transfers))) { -+ json_result = "{\"error\":\"Failed to serialize m_transfers\"}"; -+ return json_result.c_str(); -+ } -+ -+ // FIELD(m_account_public_address) - cryptonote::account_public_address -+ ar.tag("m_account_public_address"); -+ if (!::serialization::serialize(ar, const_cast(m_account_public_address))) { -+ json_result = "{\"error\":\"Failed to serialize m_account_public_address\"}"; -+ return json_result.c_str(); -+ } -+ -+ // FIELD(m_key_images) - serializable_unordered_map -+ ar.tag("m_key_images"); -+ if (!::serialization::serialize(ar, const_cast&>(m_key_images))) { -+ json_result = "{\"error\":\"Failed to serialize m_key_images\"}"; -+ return json_result.c_str(); -+ } -+ -+ // FIELD(m_unconfirmed_txs) - serializable_unordered_map -+ ar.tag("m_unconfirmed_txs"); -+ if (!::serialization::serialize(ar, const_cast&>(m_unconfirmed_txs))) { -+ json_result = "{\"error\":\"Failed to serialize m_unconfirmed_txs\"}"; -+ return json_result.c_str(); -+ } -+ -+ // FIELD(m_payments) - payment_container (serializable_unordered_multimap) -+ ar.tag("m_payments"); -+ if (!::serialization::serialize(ar, const_cast(m_payments))) { -+ json_result = "{\"error\":\"Failed to serialize m_payments\"}"; -+ return json_result.c_str(); -+ } -+ -+ // FIELD(m_tx_keys) - serializable_unordered_map -+ ar.tag("m_tx_keys"); -+ if (!::serialization::serialize(ar, const_cast&>(m_tx_keys))) { -+ json_result = "{\"error\":\"Failed to serialize m_tx_keys\"}"; -+ return json_result.c_str(); -+ } -+ -+ // FIELD(m_confirmed_txs) - serializable_unordered_map -+ ar.tag("m_confirmed_txs"); -+ if (!::serialization::serialize(ar, const_cast&>(m_confirmed_txs))) { -+ json_result = "{\"error\":\"Failed to serialize m_confirmed_txs\"}"; -+ return json_result.c_str(); -+ } -+ -+ // FIELD(m_tx_notes) - serializable_unordered_map -+ ar.tag("m_tx_notes"); -+ if (!::serialization::serialize(ar, const_cast&>(m_tx_notes))) { -+ json_result = "{\"error\":\"Failed to serialize m_tx_notes\"}"; -+ return json_result.c_str(); -+ } -+ -+ // FIELD(m_unconfirmed_payments) - serializable_unordered_multimap -+ ar.tag("m_unconfirmed_payments"); -+ if (!::serialization::serialize(ar, const_cast&>(m_unconfirmed_payments))) { -+ json_result = "{\"error\":\"Failed to serialize m_unconfirmed_payments\"}"; -+ return json_result.c_str(); -+ } -+ -+ // FIELD(m_pub_keys) - serializable_unordered_map -+ ar.tag("m_pub_keys"); -+ if (!::serialization::serialize(ar, const_cast&>(m_pub_keys))) { -+ json_result = "{\"error\":\"Failed to serialize m_pub_keys\"}"; -+ return json_result.c_str(); -+ } -+ -+ // FIELD(m_address_book) - std::vector -+ ar.tag("m_address_book"); -+ if (!::serialization::serialize(ar, const_cast&>(m_address_book))) { -+ json_result = "{\"error\":\"Failed to serialize m_address_book\"}"; -+ return json_result.c_str(); -+ } -+ -+ // FIELD(m_scanned_pool_txs[0]) - std::unordered_set -+ ar.tag("m_scanned_pool_txs_0"); -+ if (!::serialization::serialize(ar, const_cast&>(m_scanned_pool_txs[0]))) { -+ json_result = "{\"error\":\"Failed to serialize m_scanned_pool_txs[0]\"}"; -+ return json_result.c_str(); -+ } -+ -+ // FIELD(m_scanned_pool_txs[1]) - std::unordered_set -+ ar.tag("m_scanned_pool_txs_1"); -+ if (!::serialization::serialize(ar, const_cast&>(m_scanned_pool_txs[1]))) { -+ json_result = "{\"error\":\"Failed to serialize m_scanned_pool_txs[1]\"}"; -+ return json_result.c_str(); -+ } -+ -+ // FIELD(m_subaddresses) - serializable_unordered_map -+ ar.tag("m_subaddresses"); -+ if (!::serialization::serialize(ar, const_cast&>(m_subaddresses))) { -+ json_result = "{\"error\":\"Failed to serialize m_subaddresses\"}"; -+ return json_result.c_str(); -+ } -+ -+ // FIELD(m_subaddress_labels) - std::vector> - manual JSON serialization -+ oss << ", \n \"m_subaddress_labels\": ["; -+ for (size_t i = 0; i < m_subaddress_labels.size(); ++i) { -+ if (i > 0) oss << ", "; -+ oss << "\n ["; -+ for (size_t j = 0; j < m_subaddress_labels[i].size(); ++j) { -+ if (j > 0) oss << ", "; -+ oss << "\""; -+ write_escaped_json_string(oss, m_subaddress_labels[i][j]); -+ oss << "\""; -+ } -+ oss << "]"; -+ } -+ oss << "\n ]"; -+ -+ // FIELD(m_additional_tx_keys) - serializable_unordered_map> -+ ar.tag("m_additional_tx_keys"); -+ if (!::serialization::serialize(ar, const_cast>&>(m_additional_tx_keys))) { -+ json_result = "{\"error\":\"Failed to serialize m_additional_tx_keys\"}"; -+ return json_result.c_str(); -+ } -+ -+ // FIELD(m_attributes) - serializable_unordered_map - manual JSON serialization -+ oss << ", \n \"m_attributes\": {"; -+ bool first_attr = true; -+ for (const auto& attr : m_attributes) { -+ if (!first_attr) oss << ", "; -+ first_attr = false; -+ oss << "\n \""; -+ write_escaped_json_string(oss, attr.first); -+ oss << "\": \""; -+ write_escaped_json_string(oss, attr.second); -+ oss << "\""; -+ } -+ oss << "\n }"; -+ -+ // FIELD(m_account_tags) - std::pair, std::vector> - manual JSON serialization -+ oss << ", \n \"m_account_tags\": {"; -+ oss << "\n \"tags_map\": {"; -+ bool first_tag = true; -+ for (const auto& tag : m_account_tags.first) { -+ if (!first_tag) oss << ", "; -+ first_tag = false; -+ oss << "\n \""; -+ write_escaped_json_string(oss, tag.first); -+ oss << "\": \""; -+ write_escaped_json_string(oss, tag.second); -+ oss << "\""; -+ } -+ oss << "\n },"; -+ oss << "\n \"account_list\": ["; -+ for (size_t i = 0; i < m_account_tags.second.size(); ++i) { -+ if (i > 0) oss << ", "; -+ oss << "\n \""; -+ write_escaped_json_string(oss, m_account_tags.second[i]); -+ oss << "\""; -+ } -+ oss << "\n ]"; -+ oss << "\n }"; -+ -+ // FIELD(m_ring_history_saved) - bool -+ // ar.tag("m_ring_history_saved"); -+ // ar.serialize_blob(&m_ring_history_saved, sizeof(m_ring_history_saved)); -+ // if (!ar.good()) { -+ // json_result = "{\"error\":\"Failed to serialize m_ring_history_saved\"}"; -+ // return json_result.c_str(); -+ // } -+ -+ // FIELD(m_last_block_reward) - uint64_t -+ ar.tag("m_last_block_reward"); -+ ar.serialize_int(m_last_block_reward); -+ if (!ar.good()) { -+ json_result = "{\"error\":\"Failed to serialize m_last_block_reward\"}"; -+ return json_result.c_str(); -+ } -+ -+ // FIELD(m_tx_device) - serializable_unordered_map -+ ar.tag("m_tx_device"); -+ if (!::serialization::serialize(ar, const_cast&>(m_tx_device))) { -+ json_result = "{\"error\":\"Failed to serialize m_tx_device\"}"; -+ return json_result.c_str(); -+ } -+ -+ // FIELD(m_device_last_key_image_sync) - uint64_t -+ ar.tag("m_device_last_key_image_sync"); -+ ar.serialize_int(m_device_last_key_image_sync); -+ if (!ar.good()) { -+ json_result = "{\"error\":\"Failed to serialize m_device_last_key_image_sync\"}"; -+ return json_result.c_str(); -+ } -+ -+ // FIELD(m_cold_key_images) - serializable_unordered_map -+ ar.tag("m_cold_key_images"); -+ if (!::serialization::serialize(ar, const_cast&>(m_cold_key_images))) { -+ json_result = "{\"error\":\"Failed to serialize m_cold_key_images\"}"; -+ return json_result.c_str(); -+ } -+ -+ // FIELD(m_rpc_client_secret_key) - crypto::secret_key -+ // ar.tag("m_rpc_client_secret_key"); -+ // ar.serialize_blob(&m_rpc_client_secret_key, sizeof(m_rpc_client_secret_key)); -+ // if (!ar.good()) { -+ // json_result = "{\"error\":\"Failed to serialize m_rpc_client_secret_key\"}"; -+ // return json_result.c_str(); -+ // } -+ -+ // Version-dependent fields -+ if (version >= 1) { -+ // FIELD(m_has_ever_refreshed_from_node) - bool -+ // ar.tag("m_has_ever_refreshed_from_node"); -+ // ar.serialize_blob(&m_has_ever_refreshed_from_node, sizeof(m_has_ever_refreshed_from_node)); -+ // if (!ar.good()) { -+ // json_result = "{\"error\":\"Failed to serialize m_has_ever_refreshed_from_node\"}"; -+ // return json_result.c_str(); -+ // } -+ } -+ -+ if (version >= 2) { -+ // FIELD(m_background_sync_data) - background_sync_data_t -+ ar.tag("m_background_sync_data"); -+ if (!::serialization::serialize(ar, const_cast(m_background_sync_data))) { -+ json_result = "{\"error\":\"Failed to serialize m_background_sync_data\"}"; -+ return json_result.c_str(); -+ } -+ } -+ -+ ar.end_object(); -+ -+ if (!ar.good()) { -+ json_result = "{\"error\":\"Failed to finalize JSON serialization\"}"; -+ return json_result.c_str(); -+ } -+ -+ json_result = oss.str(); -+ -+ // Post-process to fix malformed JSON -+ post_process_json(json_result); -+ -+ return json_result.c_str(); -+ } -+ catch (const std::exception& e) -+ { -+ json_result = "{\"error\":\"Failed to serialize wallet cache: " + std::string(e.what()) + "\"}"; -+ return json_result.c_str(); -+ } -+} -+ -+} // namespace tools -\ No newline at end of file --- -2.50.1 (Apple Git-155) - diff --git a/patches/monero/0017-drop-generate_translations_header.c-requirement.patch b/patches/monero/0017-drop-generate_translations_header.c-requirement.patch deleted file mode 100644 index f6549dc..0000000 --- a/patches/monero/0017-drop-generate_translations_header.c-requirement.patch +++ /dev/null @@ -1,123 +0,0 @@ -From 6aa368c9613a1a7b7f2f1ce1f025962d40827c67 Mon Sep 17 00:00:00 2001 -From: Czarek Nakamoto -Date: Fri, 20 Feb 2026 08:03:01 +0100 -Subject: [PATCH 17/20] drop generate_translations_header.c requirement - ---- - CMakeLists.txt | 9 +---- - translations/CMakeLists.txt | 79 +++++++++++++------------------------ - 2 files changed, 30 insertions(+), 58 deletions(-) - -diff --git a/CMakeLists.txt b/CMakeLists.txt -index cef44dd1b..ce5e1b557 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -666,16 +666,11 @@ endfunction () - # Generate header for embedded translations - # Generate header for embedded translations, use target toolchain if depends, otherwise use the - # lrelease and lupdate binaries from the host --include(ExternalProject) --ExternalProject_Add(generate_translations_header -- SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/translations" -- BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/translations" -- STAMP_DIR ${LRELEASE_PATH} -- CMAKE_ARGS -DLRELEASE_PATH=${LRELEASE_PATH} -- INSTALL_COMMAND ${CMAKE_COMMAND} -E echo "") -+add_subdirectory(translations) - include_directories("${CMAKE_CURRENT_BINARY_DIR}/translations") - add_subdirectory(external) - -+ - # Final setup for libunbound - include_directories(${UNBOUND_INCLUDE_DIR}) - -diff --git a/translations/CMakeLists.txt b/translations/CMakeLists.txt -index 3b43360f8..d88a78ced 100644 ---- a/translations/CMakeLists.txt -+++ b/translations/CMakeLists.txt -@@ -30,54 +30,31 @@ cmake_minimum_required(VERSION 3.5) - - project(translations) - --# when crosscompiling import the executable targets from a file --IF(CMAKE_CROSSCOMPILING) -- message(WARNING "CrossCompiling") -- SET(IMPORT_EXECUTABLES "${CMAKE_CURRENT_BINARY_DIR}/ImportExecutables.cmake" CACHE FILEPATH "Point it to the export file from a native build") -- INCLUDE(${IMPORT_EXECUTABLES}) --ENDIF(CMAKE_CROSSCOMPILING) -- --# only build the generator if not crosscompiling --IF(NOT CMAKE_CROSSCOMPILING) -- add_executable(generate_translations_header generate_translations_header.c) --ENDIF(NOT CMAKE_CROSSCOMPILING) -- --if(LRELEASE_PATH STREQUAL "") -- find_program(LRELEASE lrelease) --else() -- set(LRELEASE ${LRELEASE_PATH}/lrelease) --endif() -- --if(LRELEASE STREQUAL "LRELEASE-NOTFOUND") -- set(ts_files "") -- message(WARNING "lrelease program not found, translation files not built") --else() -- execute_process(COMMAND ${LRELEASE} -version -- RESULT_VARIABLE lrelease_ret) -- if(NOT lrelease_ret EQUAL "0") -- set(ts_files "") -- message(WARNING "lrelease program not working, translation files not built") -- else() -- file(GLOB ts_files RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" *.ts) -- foreach(ts_file ${ts_files}) -- string(REPLACE ".ts" ".qm" qm_file "${ts_file}") -- add_custom_command(TARGET generate_translations_header -- PRE_BUILD -- COMMAND ${LRELEASE} "${CMAKE_CURRENT_SOURCE_DIR}/${ts_file}" -qm "${qm_file}" -- WORKING_DIRECTORY "${CMAKE_CURRENT_BIN_DIR}") -- endforeach() -- endif() --endif() -- --string(REPLACE ".ts" ".qm" qm_files "${ts_files}") -- --add_custom_command(TARGET generate_translations_header -- POST_BUILD -- COMMAND $ ${qm_files} -- WORKING_DIRECTORY "${CMAKE_CURRENT_BIN_DIR}" -- COMMENT "Generating embedded translations header") -- --# export the generator target to a file, so it can be imported (see above) by another build --IF(NOT CMAKE_CROSSCOMPILING) -- EXPORT(TARGETS generate_translations_header FILE ${CMAKE_CURRENT_BINARY_DIR}/ImportExecutables.cmake ) --ENDIF(NOT CMAKE_CROSSCOMPILING) -+add_custom_target(generate_translations_header) -+ -+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/translation_files.h" -+"#ifndef TRANSLATION_FILES_H -+#define TRANSLATION_FILES_H -+ -+#include -+ -+static const struct embedded_file { -+ const std::string *name; -+ const std::string *data; -+} embedded_files[] = { -+ {NULL, NULL} -+}; -+ -+static bool find_embedded_file(const std::string &name, std::string &data) { -+ const struct embedded_file *p; -+ for (p = embedded_files; p->name != NULL; p++) { -+ if (*p->name == name) { -+ data = *p->data; -+ return true; -+ } -+ } -+ return false; -+} -+ -+#endif /* TRANSLATION_FILES_H */ -+") --- -2.50.1 (Apple Git-155) - diff --git a/patches/monero/0017-fix-remove-flaky-test.patch b/patches/monero/0017-fix-remove-flaky-test.patch new file mode 100644 index 0000000..e195be9 --- /dev/null +++ b/patches/monero/0017-fix-remove-flaky-test.patch @@ -0,0 +1,27 @@ +From 5c454168c9ca9af91f6673de13fdda3512403612 Mon Sep 17 00:00:00 2001 +From: Czarek Nakamoto +Date: Thu, 5 Mar 2026 18:12:53 +0100 +Subject: [PATCH 17/17] fix: remove flaky test + +--- + CMakeLists.txt | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index bb258883c..38bec3751 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -240,9 +240,7 @@ add_library(l3 OBJECT incorrect_source.cpp) + "-DCMAKE_MODULE_LINKER_FLAGS=${CMAKE_MODULE_LINKER_FLAGS}" + "-DEXPECT_SUCCESS=${EXPECT}" + ) +- if (NOT ${SUCCESS} STREQUAL ${EXPECT}) +- message(FATAL_ERROR "Undefined symbols test failure: expect(${EXPECT}), success(${SUCCESS})") +- endif() ++ + file(REMOVE_RECURSE "${TEST_PROJECT}") + endforeach() + endfunction() +-- +2.51.0 + diff --git a/patches/monero/0018-depends-remove-icu4c-monero-project-monero-8880.patch b/patches/monero/0018-depends-remove-icu4c-monero-project-monero-8880.patch deleted file mode 100644 index 84b4b99..0000000 --- a/patches/monero/0018-depends-remove-icu4c-monero-project-monero-8880.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 960a5efe59725eab4c03ce8025de8fc0fbffaacf Mon Sep 17 00:00:00 2001 -From: Czarek Nakamoto -Date: Tue, 3 Mar 2026 13:55:59 +0100 -Subject: [PATCH 18/20] depends: remove icu4c monero-project/monero#8880 - ---- - CMakeLists.txt | 9 ++------- - 1 file changed, 2 insertions(+), 7 deletions(-) - -diff --git a/CMakeLists.txt b/CMakeLists.txt -index ce5e1b557..25e034301 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -1117,20 +1117,15 @@ if(MINGW) - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wa,-mbig-obj") - set(EXTRA_LIBRARIES mswsock;ws2_32;iphlpapi;crypt32;bcrypt) - if(DEPENDS) -- set(ICU_LIBRARIES icuio icui18n icuuc icudata icutu iconv) -+ set(ICU_LIBRARIES iconv) - else() - # This is an extremely ugly hack to get around Boost not being built with static ICU. - # We reported the issue, we are waiting for upstream to fix this issue: https://github.com/boostorg/boost/issues/1079#issue-3384962885 - # This hack links shared ICU libs to avoid linker errors we get in MSYS2 compilation (undefined symbols to ICU). - set(OLD_LIB_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) - set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll.a") -- find_library(ICUIO_LIBRARIES NAMES icuio REQUIRED) -- find_library(ICUIN_LIBRARIES NAMES icuin REQUIRED) -- find_library(ICUUC_LIBRARIES NAMES icuuc REQUIRED) -- find_library(ICUDT_LIBRARIES NAMES icudt REQUIRED) -- find_library(ICUTU_LIBRARIES NAMES icutu REQUIRED) - find_library(ICONV_LIBRARIES NAMES iconv REQUIRED) -- set(ICU_LIBRARIES ${ICUIO_LIBRARIES} ${ICUIN_LIBRARIES} ${ICUUC_LIBRARIES} ${ICUDT_LIBRARIES} ${ICUTU_LIBRARIES} ${ICONV_LIBRARIES}) -+ set(ICU_LIBRARIES ${ICUIO_LIBRARIES} ${ICONV_LIBRARIES}) - set(CMAKE_FIND_LIBRARY_SUFFIXES ${OLD_LIB_SUFFIXES}) - endif() - elseif(APPLE OR OPENBSD OR ANDROID) --- -2.50.1 (Apple Git-155) - diff --git a/patches/monero/0019-fix-mingw-build-issues.patch b/patches/monero/0019-fix-mingw-build-issues.patch deleted file mode 100644 index a9e7b5c..0000000 --- a/patches/monero/0019-fix-mingw-build-issues.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 2d4ed0b13eea96b25a574e8a87644df75c16ffb0 Mon Sep 17 00:00:00 2001 -From: Czarek Nakamoto -Date: Wed, 4 Mar 2026 14:52:14 +0100 -Subject: [PATCH 19/20] fix: mingw build issues - ---- - contrib/epee/include/serialization/keyvalue_serialization.h | 1 + - contrib/epee/src/abstract_http_client.cpp | 3 ++- - 2 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/contrib/epee/include/serialization/keyvalue_serialization.h b/contrib/epee/include/serialization/keyvalue_serialization.h -index fbbddc7d2..5104f284d 100644 ---- a/contrib/epee/include/serialization/keyvalue_serialization.h -+++ b/contrib/epee/include/serialization/keyvalue_serialization.h -@@ -26,6 +26,7 @@ - - #pragma once - -+#include - #include - #include - #include -diff --git a/contrib/epee/src/abstract_http_client.cpp b/contrib/epee/src/abstract_http_client.cpp -index ed4a193d9..2352c7d62 100644 ---- a/contrib/epee/src/abstract_http_client.cpp -+++ b/contrib/epee/src/abstract_http_client.cpp -@@ -3,6 +3,7 @@ - #include "net/http_base.h" - #include "net/net_parse_helpers.h" - #include "misc_log_ex.h" -+#include - - #undef MONERO_DEFAULT_LOG_CATEGORY - #define MONERO_DEFAULT_LOG_CATEGORY "net.http" -@@ -39,7 +40,7 @@ namespace net_utils - while (num_char >= radix) - { - temp = num_char % radix; -- num_char = (int)floor((float)num_char / (float)radix); -+ num_char = (int)std::floor((float)num_char / (float)radix); - csTmp = get_hex_vals()[temp]; - } - --- -2.50.1 (Apple Git-155) - diff --git a/patches/monero/0020-fix-remove-flaky-test.patch b/patches/monero/0020-fix-remove-flaky-test.patch deleted file mode 100644 index 1075db5..0000000 --- a/patches/monero/0020-fix-remove-flaky-test.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 81eb38a5add85266cc0d2aa39ecba9d62337f4b1 Mon Sep 17 00:00:00 2001 -From: Czarek Nakamoto -Date: Thu, 5 Mar 2026 18:12:53 +0100 -Subject: [PATCH 20/20] fix: remove flaky test - ---- - CMakeLists.txt | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/CMakeLists.txt b/CMakeLists.txt -index 25e034301..19417f072 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -235,9 +235,7 @@ add_library(l3 OBJECT incorrect_source.cpp) - "-DCMAKE_MODULE_LINKER_FLAGS=${CMAKE_MODULE_LINKER_FLAGS}" - "-DEXPECT_SUCCESS=${EXPECT}" - ) -- if (NOT ${SUCCESS} STREQUAL ${EXPECT}) -- message(FATAL_ERROR "Undefined symbols test failure: expect(${EXPECT}), success(${SUCCESS})") -- endif() -+ - file(REMOVE_RECURSE "${TEST_PROJECT}") - endforeach() - endfunction() --- -2.50.1 (Apple Git-155) - -- cgit v1.2.3