diff options
| author | Czarek Nakamoto <cyjan@mrcyjanek.net> | 2026-05-26 13:29:48 +0200 |
|---|---|---|
| committer | Czarek Nakamoto <cyjan@mrcyjanek.net> | 2026-05-26 13:29:48 +0200 |
| commit | 883d69804bc8c984085b84604788383e57274280 (patch) | |
| tree | 4d69071960fc64b29bbcea7b68acfa68c4b9de46 /patches/monero/0021-trezor-import-export-sign-functions.patch | |
| parent | d2c7a142225517f9f9e1cfed9d8761d702f1cdc6 (diff) | |
Diffstat (limited to 'patches/monero/0021-trezor-import-export-sign-functions.patch')
| -rw-r--r-- | patches/monero/0021-trezor-import-export-sign-functions.patch | 197 |
1 files changed, 167 insertions, 30 deletions
diff --git a/patches/monero/0021-trezor-import-export-sign-functions.patch b/patches/monero/0021-trezor-import-export-sign-functions.patch index 8f89f01..b682139 100644 --- a/patches/monero/0021-trezor-import-export-sign-functions.patch +++ b/patches/monero/0021-trezor-import-export-sign-functions.patch @@ -1,21 +1,21 @@ -From b0fb84c69bba4cc6ffdd7c401a804c2d73089043 Mon Sep 17 00:00:00 2001 +From 8af15fadb4095f94145cfe5086a1f6796d1cc44a Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto <cyjan@mrcyjanek.net> Date: Wed, 13 May 2026 11:35:01 -0400 -Subject: [PATCH] trezor import/export/sign functions +Subject: [PATCH] trezor import/export/sign/submit functions --- cmake/CheckTrezor.cmake | 28 +-- - src/device_trezor/trezor/protocol.cpp | 220 ++++++++++++++++++++++++ + src/device_trezor/trezor/protocol.cpp | 220 ++++++++++++++++++++++ src/device_trezor/trezor/protocol.hpp | 8 + - src/wallet/api/pending_transaction.cpp | 60 +++++++ + src/wallet/api/pending_transaction.cpp | 60 ++++++ src/wallet/api/pending_transaction.h | 1 + src/wallet/api/unsigned_transaction.cpp | 2 + - src/wallet/api/wallet.cpp | 31 +++- - src/wallet/api/wallet.h | 2 + - src/wallet/api/wallet2_api.h | 14 ++ - src/wallet/wallet2.cpp | 158 +++++++++++++++++ - src/wallet/wallet2.h | 5 +- - 11 files changed, 500 insertions(+), 29 deletions(-) + src/wallet/api/wallet.cpp | 70 ++++++- + src/wallet/api/wallet.h | 9 +- + src/wallet/api/wallet2_api.h | 71 ++++--- + src/wallet/wallet2.cpp | 234 ++++++++++++++++++++++++ + src/wallet/wallet2.h | 7 +- + 11 files changed, 650 insertions(+), 60 deletions(-) diff --git a/cmake/CheckTrezor.cmake b/cmake/CheckTrezor.cmake index 4fae15fad..57e3d4866 100644 @@ -445,19 +445,56 @@ index fd03e959d..7232e518f 100644 #include "bc-ur/src/bc-ur.hpp" diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp -index c24b4a97d..cc85398ca 100644 +index c24b4a97d..3a977d6d2 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp -@@ -1545,7 +1545,7 @@ bool WalletImpl::importKeyImages(const string &filename) - return false; - } - -- return true; -+ return true; +@@ -1457,6 +1457,45 @@ bool WalletImpl::submitTransactionUR(const string &input) { + return true; } ++bool WalletImpl::submitTransactionHex(const string &hex) { ++ clearStatus(); ++ if (checkBackgroundSync("cannot submit tx")) ++ return false; ++ ++ pauseRefresh(); ++ try { ++ m_wallet->relay_raw_tx(hex); ++ } catch (const tools::error::daemon_busy&) { ++ setStatusError(tr("daemon is busy. Please try again later.")); ++ startRefresh(); ++ return false; ++ } catch (const tools::error::no_connection_to_daemon&) { ++ setStatusError(tr("no connection to daemon.")); ++ startRefresh(); ++ return false; ++ } catch (const tools::error::tx_rejected& e) { ++ std::ostringstream writer; ++ writer << (boost::format(tr("transaction %s was rejected by daemon with status: ")) % get_transaction_hash(e.tx())) << e.status(); ++ if (!e.reason().empty()) ++ writer << tr(". Reason: ") << e.reason(); ++ setStatusError(writer.str()); ++ startRefresh(); ++ return false; ++ } catch (const std::exception &e) { ++ setStatusError(string(tr("Unknown exception: ")) + e.what()); ++ startRefresh(); ++ return false; ++ } catch (...) { ++ setStatusError(tr("Unhandled exception")); ++ startRefresh(); ++ return false; ++ } ++ startRefresh(); ++ if (m_history) ++ m_history->refresh(); ++ return true; ++} ++ -@@ -3479,4 +3479,33 @@ std::string WalletImpl::serializeCacheToJson() const + bool WalletImpl::hasUnknownKeyImages() const + { +@@ -3479,4 +3518,33 @@ std::string WalletImpl::serializeCacheToJson() const return std::string(m_wallet->serialize_cache_to_json()); } @@ -492,10 +529,18 @@ index c24b4a97d..cc85398ca 100644 + } // namespace diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h -index 98c03b9c1..5248badb8 100644 +index 98c03b9c1..45a3b6b2f 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h -@@ -337,6 +337,8 @@ private: +@@ -183,6 +183,7 @@ public: + virtual PendingTransaction * createSweepUnmixableTransaction() override; + bool submitTransaction(const std::string &fileName) override; + bool submitTransactionUR(const std::string &input) override; ++ bool submitTransactionHex(const std::string &hex) override; + virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) override; + virtual UnsignedTransaction * loadUnsignedTxUR(const std::string &input) override; + bool hasUnknownKeyImages() const override; +@@ -337,6 +338,8 @@ private: bool getWaitsForDeviceReceive(); virtual std::string serializeCacheToJson() const override; @@ -505,7 +550,7 @@ index 98c03b9c1..5248badb8 100644 diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h -index 3d11929f9..ee9edd68e 100644 +index 3d11929f9..ac1dd9fb0 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h @@ -92,6 +92,7 @@ struct PendingTransaction @@ -516,7 +561,15 @@ index 3d11929f9..ee9edd68e 100644 virtual uint64_t amount() const = 0; virtual uint64_t dust() const = 0; virtual uint64_t fee() const = 0; -@@ -1220,6 +1221,19 @@ struct Wallet +@@ -948,6 +949,7 @@ struct Wallet + */ + virtual bool submitTransaction(const std::string &fileName) = 0; + virtual bool submitTransactionUR(const std::string &input) = 0; ++ virtual bool submitTransactionHex(const std::string &input) = 0; + + + /*! +@@ -1220,6 +1222,19 @@ struct Wallet //! serialize wallet cache to JSON virtual std::string serializeCacheToJson() const = 0; @@ -537,7 +590,7 @@ index 3d11929f9..ee9edd68e 100644 /** diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp -index a7532d7ec..bb0ada04d 100644 +index a7532d7ec..0c3a628ed 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -98,6 +98,7 @@ extern "C" @@ -548,7 +601,89 @@ index a7532d7ec..bb0ada04d 100644 } using namespace std; using namespace crypto; -@@ -7838,6 +7839,20 @@ std::string wallet2::dump_tx_to_str(const std::vector<pending_tx> &ptx_vector) c +@@ -7799,6 +7800,81 @@ void wallet2::commit_tx(std::vector<pending_tx>& ptx_vector) + } + } + //---------------------------------------------------------------------------------------------------- ++void wallet2::relay_raw_tx(const std::string &tx_as_hex) ++{ ++ using namespace cryptonote; ++ ++ cryptonote::blobdata tx_blob; ++ THROW_WALLET_EXCEPTION_IF(!epee::string_tools::parse_hexstr_to_binbuff(tx_as_hex, tx_blob), error::wallet_internal_error, "Failed to parse hex"); ++ ++ transaction tx; ++ THROW_WALLET_EXCEPTION_IF(!parse_and_validate_tx_from_blob(tx_blob, tx), error::wallet_internal_error, "Failed to parse transaction"); ++ ++ if (m_light_wallet) ++ { ++ COMMAND_RPC_SUBMIT_RAW_TX::request oreq; ++ COMMAND_RPC_SUBMIT_RAW_TX::response ores; ++ oreq.address = get_account().get_public_address_str(m_nettype); ++ oreq.view_key = string_tools::pod_to_hex(unwrap(unwrap(get_account().get_keys().m_view_secret_key))); ++ oreq.tx = tx_as_hex; ++ { ++ const boost::lock_guard<boost::recursive_mutex> lock{m_daemon_rpc_mutex}; ++ bool r = epee::net_utils::invoke_http_json("/submit_raw_tx", oreq, ores, *m_http_client, rpc_timeout, "POST"); ++ THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "submit_raw_tx"); ++ THROW_WALLET_EXCEPTION_IF(ores.status != "OK" && ores.status != "success", error::tx_rejected, tx, get_rpc_status(ores.status), ores.error); ++ } ++ } ++ else ++ { ++ COMMAND_RPC_SEND_RAW_TX::request req; ++ req.tx_as_hex = tx_as_hex; ++ req.do_not_relay = false; ++ req.do_sanity_checks = true; ++ COMMAND_RPC_SEND_RAW_TX::response daemon_send_resp; ++ ++ { ++ const boost::lock_guard<boost::recursive_mutex> lock{m_daemon_rpc_mutex}; ++ uint64_t pre_call_credits = m_rpc_payment_state.credits; ++ req.client = get_client_signature(); ++ bool r = epee::net_utils::invoke_http_json("/sendrawtransaction", req, daemon_send_resp, *m_http_client, rpc_timeout); ++ THROW_ON_RPC_RESPONSE_ERROR(r, {}, daemon_send_resp, "sendrawtransaction", error::tx_rejected, tx, get_rpc_status(daemon_send_resp.status), get_text_reason(daemon_send_resp)); ++ check_rpc_cost("/sendrawtransaction", daemon_send_resp.credits, pre_call_credits, COST_PER_TX_RELAY); ++ } ++ } ++ ++ crypto::hash txid = get_transaction_hash(tx); ++ uint64_t tx_money_spent_in_ins = 0; ++ auto subaddr_account = []()->boost::optional<uint32_t> { return boost::none; }(); ++ std::set<uint32_t> subaddr_indices; ++ for (const auto &in : tx.vin) ++ { ++ if (in.type() != typeid(cryptonote::txin_to_key)) ++ continue; ++ const cryptonote::txin_to_key &in_to_key = boost::get<cryptonote::txin_to_key>(in); ++ const auto kit = m_key_images.find(in_to_key.k_image); ++ if (kit == m_key_images.end()) ++ continue; ++ const transfer_details &td = m_transfers[kit->second]; ++ const uint64_t amount = in_to_key.amount > 0 ? in_to_key.amount : td.amount(); ++ tx_money_spent_in_ins += amount; ++ subaddr_account = td.m_subaddr_index.major; ++ subaddr_indices.insert(td.m_subaddr_index.minor); ++ set_spent(kit->second, 0); ++ } ++ ++ if (tx_money_spent_in_ins > 0 && store_tx_info() && !m_unconfirmed_txs.count(txid)) ++ { ++ THROW_WALLET_EXCEPTION_IF(!subaddr_account, error::wallet_internal_error, ++ "Relayed tx spends our outputs but subaddress account is unknown"); ++ add_unconfirmed_tx(txid, tx, tx_money_spent_in_ins, {}, crypto::null_hash, 0, *subaddr_account, subaddr_indices); ++ auto utx_it = m_unconfirmed_txs.find(txid); ++ THROW_WALLET_EXCEPTION_IF(utx_it == m_unconfirmed_txs.end(), error::wallet_internal_error, ++ "unconfirmed tx wasn't found: " + string_tools::pod_to_hex(txid)); ++ utx_it->second.m_amount_out = get_outgoing_amount(tx, tx_money_spent_in_ins); ++ LOG_PRINT_L1("Raw transaction relayed. <" << txid << ">"); ++ } ++} ++//---------------------------------------------------------------------------------------------------- + bool wallet2::save_tx(const std::vector<pending_tx>& ptx_vector, const std::string &filename) const + { + LOG_PRINT_L0("saving " << ptx_vector.size() << " transactions"); +@@ -7838,6 +7915,20 @@ std::string wallet2::dump_tx_to_str(const std::vector<pending_tx> &ptx_vector) c return std::string(UNSIGNED_TX_PREFIX) + ciphertext; } //---------------------------------------------------------------------------------------------------- @@ -569,7 +704,7 @@ index a7532d7ec..bb0ada04d 100644 bool wallet2::load_unsigned_tx(const std::string &unsigned_filename, unsigned_tx_set &exported_txs) const { std::string s; -@@ -16384,4 +16399,147 @@ std::pair<size_t, uint64_t> wallet2::estimate_tx_size_and_weight(bool use_rct, i +@@ -16384,4 +16475,147 @@ std::pair<size_t, uint64_t> wallet2::estimate_tx_size_and_weight(bool use_rct, i return std::make_pair(size, weight); } //---------------------------------------------------------------------------------------------------- @@ -718,19 +853,21 @@ index a7532d7ec..bb0ada04d 100644 +//---------------------------------------------------------------------------------------------------- } diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h -index 37a2447d2..a1ca49e90 100644 +index 37a2447d2..2e93f3dbf 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h -@@ -1207,6 +1207,8 @@ private: +@@ -1205,8 +1205,10 @@ private: + + void commit_tx(pending_tx& ptx_vector); void commit_tx(std::vector<pending_tx>& ptx_vector); ++ void relay_raw_tx(const std::string &tx_as_hex); bool save_tx(const std::vector<pending_tx>& ptx_vector, const std::string &filename) const; std::string dump_tx_to_str(const std::vector<pending_tx> &ptx_vector) const; -+ //! Populate \p utx from pending txs for cold/device signing (uses live transfer indices). + void construct_unsigned_tx_set_for_signing(const std::vector<pending_tx>& ptx_vector, unsigned_tx_set &utx) const; std::string save_multisig_tx(multisig_tx_set txs); bool save_multisig_tx(const multisig_tx_set &txs, const std::string &filename); std::string save_multisig_tx(const std::vector<pending_tx>& ptx_vector); -@@ -1717,7 +1719,8 @@ private: +@@ -1717,7 +1721,8 @@ private: bool is_unattended() const { return m_unattended; } std::pair<size_t, uint64_t> estimate_tx_size_and_weight(bool use_rct, int n_inputs, int ring_size, int n_outputs, size_t extra_size); @@ -741,5 +878,5 @@ index 37a2447d2..a1ca49e90 100644 bool daemon_requires_payment(); bool make_rpc_payment(uint32_t nonce, uint32_t cookie, uint64_t &credits, uint64_t &balance); -- -2.51.0 +2.50.1 (Apple Git-155) |
