summaryrefslogtreecommitdiff
path: root/patches/monero/0003-airgap.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/monero/0003-airgap.patch')
-rw-r--r--patches/monero/0003-airgap.patch187
1 files changed, 187 insertions, 0 deletions
diff --git a/patches/monero/0003-airgap.patch b/patches/monero/0003-airgap.patch
new file mode 100644
index 0000000..80bc18c
--- /dev/null
+++ b/patches/monero/0003-airgap.patch
@@ -0,0 +1,187 @@
+From c325add45cf950a42fc4cc16f99bb7385c53a634 Mon Sep 17 00:00:00 2001
+From: Czarek Nakamoto <cyjan@mrcyjanek.net>
+Date: Tue, 12 Mar 2024 10:09:50 +0100
+Subject: [PATCH 3/8] airgap
+
+---
+ src/wallet/api/wallet.cpp | 23 ++++++++++++++++++++++
+ src/wallet/api/wallet.h | 2 ++
+ src/wallet/api/wallet2_api.h | 3 +++
+ src/wallet/wallet2.cpp | 38 ++++++++++++++++++++++++++++++------
+ src/wallet/wallet2.h | 1 +
+ 5 files changed, 61 insertions(+), 6 deletions(-)
+
+diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
+index 1a9c6f674..42887dced 100644
+--- a/src/wallet/api/wallet.cpp
++++ b/src/wallet/api/wallet.cpp
+@@ -1129,6 +1129,24 @@ uint64_t WalletImpl::unlockedBalance(uint32_t accountIndex) const
+ return m_wallet->unlocked_balance(accountIndex, false);
+ }
+
++uint64_t WalletImpl::viewOnlyBalance(uint32_t accountIndex, const std::vector<std::string> &key_images) const
++{
++ clearStatus();
++
++ std::vector<crypto::key_image> kis;
++ for (const auto &key_image : key_images) {
++ crypto::key_image ki;
++ if (!epee::string_tools::hex_to_pod(key_image, ki))
++ {
++ setStatusError(tr("failed to parse key image"));
++ return 0;
++ }
++ kis.push_back(ki);
++ }
++
++ return m_wallet->view_only_balance(accountIndex, kis);
++}
++
+ uint64_t WalletImpl::blockChainHeight() const
+ {
+ if(m_wallet->light_wallet()) {
+@@ -1291,6 +1309,11 @@ bool WalletImpl::submitTransaction(const string &fileName) {
+ return true;
+ }
+
++bool WalletImpl::hasUnknownKeyImages() const
++{
++ return m_wallet->has_unknown_key_images();
++}
++
+ bool WalletImpl::exportKeyImages(const string &filename, bool all)
+ {
+ if (m_wallet->watch_only())
+diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
+index 9acd2871f..05d065c5c 100644
+--- a/src/wallet/api/wallet.h
++++ b/src/wallet/api/wallet.h
+@@ -122,6 +122,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;
++ uint64_t viewOnlyBalance(uint32_t accountIndex, const std::vector<std::string> &key_images) const override;
+ uint64_t blockChainHeight() const override;
+ uint64_t approximateBlockChainHeight() const override;
+ uint64_t estimateBlockChainHeight() const override;
+@@ -175,6 +176,7 @@ public:
+ virtual PendingTransaction * createSweepUnmixableTransaction() override;
+ bool submitTransaction(const std::string &fileName) override;
+ virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) override;
++ bool hasUnknownKeyImages() const override;
+ bool exportKeyImages(const std::string &filename, bool all = false) override;
+ bool importKeyImages(const std::string &filename) override;
+ bool exportOutputs(const std::string &filename, bool all = false) override;
+diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
+index 4268b656e..4edaefefd 100644
+--- a/src/wallet/api/wallet2_api.h
++++ b/src/wallet/api/wallet2_api.h
+@@ -626,6 +626,7 @@ struct Wallet
+ result += unlockedBalance(i);
+ return result;
+ }
++ virtual uint64_t viewOnlyBalance(uint32_t accountIndex, const std::vector<std::string> &key_images = {}) const = 0;
+
+ /**
+ * @brief watchOnly - checks if wallet is watch only
+@@ -910,6 +911,8 @@ struct Wallet
+ virtual uint64_t estimateTransactionFee(const std::vector<std::pair<std::string, uint64_t>> &destinations,
+ PendingTransaction::Priority priority) const = 0;
+
++ virtual bool hasUnknownKeyImages() const = 0;
++
+ /*!
+ * \brief exportKeyImages - exports key images to file
+ * \param filename
+diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
+index c7cbdbbe6..700816da6 100644
+--- a/src/wallet/wallet2.cpp
++++ b/src/wallet/wallet2.cpp
+@@ -949,6 +949,16 @@ uint32_t get_subaddress_clamped_sum(uint32_t idx, uint32_t extra)
+ return idx + extra;
+ }
+
++bool is_preferred_input(const std::vector<crypto::key_image>& preferred_input_list, const crypto::key_image& input) {
++ if (!preferred_input_list.empty()) {
++ auto it = std::find(preferred_input_list.begin(), preferred_input_list.end(), input);
++ if (it == preferred_input_list.end()) {
++ return false;
++ }
++ }
++ return true;
++}
++
+ 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);
+@@ -7037,6 +7047,25 @@ uint64_t wallet2::unlocked_balance(uint32_t index_major, bool strict, uint64_t *
+ return amount;
+ }
+ //----------------------------------------------------------------------------------------------------
++uint64_t wallet2::view_only_balance(uint32_t index_major, const std::vector<crypto::key_image>& selected_inputs)
++{
++ uint64_t amount = 0;
++ for (const auto &td : m_transfers) {
++ if (is_preferred_input(selected_inputs, td.m_key_image) &&
++ !is_spent(td, false) &&
++ !td.m_frozen &&
++ !td.m_key_image_partial &&
++ td.m_key_image_known &&
++ td.is_rct() &&
++ is_transfer_unlocked(td) &&
++ td.m_subaddr_index.major == index_major)
++ {
++ amount += td.m_amount;
++ }
++ }
++ return amount;
++}
++//----------------------------------------------------------------------------------------------------
+ std::map<uint32_t, uint64_t> wallet2::balance_per_subaddress(uint32_t index_major, bool strict) const
+ {
+ std::map<uint32_t, uint64_t> amount_per_subaddr;
+@@ -7887,9 +7916,7 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, std::vector<wallet2::pendin
+ crypto::key_derivation derivation;
+ std::vector<crypto::key_derivation> 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<crypto::public_key> additional_tx_pub_keys;
+ for (const crypto::secret_key &skey: txs[n].additional_tx_keys)
+ {
+@@ -11287,7 +11314,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
+ MDEBUG("Ignoring output " << i << " of amount " << print_money(td.amount()) << " which is below fractional threshold " << print_money(fractional_threshold));
+ continue;
+ }
+- if (!is_spent(td, false) && !td.m_frozen && !td.m_key_image_partial && (use_rct ? true : !td.is_rct()) && is_transfer_unlocked(td) && td.m_subaddr_index.major == subaddr_account && subaddr_indices.count(td.m_subaddr_index.minor) == 1)
++ if (!is_spent(td, false) && !td.m_frozen && !td.m_key_image_partial && td.m_key_image_known && (use_rct ? true : !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)
+ {
+@@ -11337,8 +11364,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
+
+ LOG_PRINT_L2("Starting with " << num_nondust_outputs << " non-dust outputs and " << num_dust_outputs << " dust outputs");
+
+- if (unused_dust_indices_per_subaddr.empty() && unused_transfers_indices_per_subaddr.empty())
+- return std::vector<wallet2::pending_tx>();
++ THROW_WALLET_EXCEPTION_IF(unused_dust_indices_per_subaddr.empty() && unused_transfers_indices_per_subaddr.empty(), error::wallet_internal_error, "No enotes available to spend")
+
+ // if empty, put dummy entry so that the front can be referenced later in the loop
+ if (unused_dust_indices_per_subaddr.empty())
+diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
+index d37332dd1..fc69b3d36 100644
+--- a/src/wallet/wallet2.h
++++ b/src/wallet/wallet2.h
+@@ -1172,6 +1172,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);
++ uint64_t view_only_balance(uint32_t index_major, const std::vector<crypto::key_image>& selected_inputs = {});
+ // locked & unlocked balance per subaddress of given or current subaddress account
+ std::map<uint32_t, uint64_t> balance_per_subaddress(uint32_t subaddr_index_major, bool strict) const;
+ std::map<uint32_t, std::pair<uint64_t, std::pair<uint64_t, uint64_t>>> unlocked_balance_per_subaddress(uint32_t subaddr_index_major, bool strict);
+--
+2.44.0
+