From 93d7ff1eebdafefc1eda3f3e0bcf275c2b3d36d4 Mon Sep 17 00:00:00 2001 From: Lee *!* Clagett Date: Tue, 22 Jul 2025 20:01:20 -0400 Subject: [PATCH] Changes for monero_c --- CMakeLists.txt | 3 +++ src/CMakeLists.txt | 5 +++++ src/backend.cpp | 49 ++++++++++++++++++++++++++++++++++------------ src/backend.h | 2 +- src/rpc.cpp | 2 ++ src/rpc.h | 2 ++ src/wallet.cpp | 39 ++++++++++++++++++++++++++---------- src/wallet.h | 14 ++++++++++++- 8 files changed, 91 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 08ca98c..52e53ad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,10 +67,12 @@ endif() find_package(Sodium REQUIRED) add_library(monero::libraries INTERFACE IMPORTED) + set_property(TARGET monero::libraries PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Boost_INCLUDE_DIR} "${MONERO_SOURCE_DIR}/contrib/epee/include" + "${MONERO_SOURCE_DIR}/external" "${MONERO_SOURCE_DIR}/external/easylogging++" "${MONERO_SOURCE_DIR}/external/rapidjson/include" "${MONERO_SOURCE_DIR}/external/supercop/include" @@ -79,6 +81,7 @@ set_property(TARGET monero::libraries PROPERTY set_property(TARGET monero::libraries PROPERTY INTERFACE_LINK_LIBRARIES common + cryptonote_basic epee mnemonics qrcodegen diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f632ef3..e5738c7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -76,6 +76,10 @@ target_link_libraries(lwsf-api Threads::Threads ) +if (${LWSF_MASTER_ENABLE}) + target_compile_definitions(lwsf-api PRIVATE LWSF_MASTER_ENABLE) +endif() + add_executable(lwsf-ledger ledger_main.cpp) target_link_libraries(lwsf-ledger PRIVATE @@ -83,3 +87,4 @@ target_link_libraries(lwsf-ledger ${Boost_PROGRAM_OPTIONS_LIBRARY} ) + diff --git a/src/backend.cpp b/src/backend.cpp index 2fc1536..8754229 100644 --- a/src/backend.cpp +++ b/src/backend.cpp @@ -343,6 +343,19 @@ namespace lwsf { namespace internal { namespace backend return out.sender; } + namespace + { + const unsigned char* ec_to_bytes(const crypto::ec_scalar& out) + { + return reinterpret_cast(out.data); + } + + unsigned char* ec_to_bytes(crypto::ec_scalar& out) + { + return reinterpret_cast(out.data); + } + } + crypto::secret_key get_spend_secret(const account& self, const std::optional& index) { if (!index || index->is_default()) @@ -353,7 +366,7 @@ namespace lwsf { namespace internal { namespace backend // D = B + M crypto::secret_key out; - sc_add(to_bytes(out), to_bytes(m), to_bytes(self.spend.sec)); + sc_add(ec_to_bytes(out), ec_to_bytes(m), ec_to_bytes(self.spend.sec)); return out; } @@ -1245,12 +1258,21 @@ namespace lwsf { namespace internal { namespace backend return {}; } - std::error_code wallet::restore_height(const std::uint64_t height) + expect wallet::restore_height(const std::uint64_t height) { + const auto update_import = [this](expect value) + { + if (value) + this->import_error = {}; + else + this->import_error = value.error(); + return value + } + boost::unique_lock lock{sync}; if (primary.restore_height <= height) - return import_error = {}; + return update_import(import_response{}); if (import_error && import_error == error::import_pending) return import_error; @@ -1271,10 +1293,10 @@ namespace lwsf { namespace internal { namespace backend lock.lock(); if (!import) - return import_error = import.error(); + return update_import(import.error()); if (import->request_fulfilled) - return import_error = {}; + return update_import(std::move(*import)); const unsigned total = unsigned(bool(import->import_fee)) + bool(import->payment_address); @@ -1282,23 +1304,24 @@ namespace lwsf { namespace internal { namespace backend { default: case 0: - return import_error = error::import_pending; + return update_import(error::import_pending); case 1: if (import->import_fee.value_or(rpc::uint64_string(0)) == rpc::uint64_string(0)) - return import_error = error::import_pending; - return import_error = error::import_invalid; + return update_import(error::import_pending); + return update_import(error::import_invalid); case 2: break; } cryptonote::address_parse_info info{}; if (!cryptonote::get_account_address_from_str(info, convert_net_type(primary.type), *import->payment_address)) - return import_error = error::import_invalid; + return update_import(error::import_invalid); if (info.has_payment_id && import->payment_id) - return import_error = error::import_invalid; + return update_import(error::import_invalid); if (import->payment_id && (import->payment_id->empty() || (import->payment_id->size() != sizeof(crypto::hash8) && import->payment_id->size() != sizeof(crypto::hash)))) - return import_error = error::import_invalid; + return update_import(error::import_invalid); +#ifdef LWSF_MASTER_ENABLE std::string payment_id; if (import->payment_id) payment_id = epee::to_hex::string(epee::to_span(*import->payment_id)); @@ -1318,8 +1341,8 @@ namespace lwsf { namespace internal { namespace backend primary.addressbook.push_back(address_book_entry{std::move(*import->payment_address), std::move(payment_id), std::move(description)}); else primary.addressbook[i] = address_book_entry{std::move(*import->payment_address), std::move(payment_id), std::move(description)}; - - return import_error = {}; +#endif + return update_import(std::move(*import)); } expect> wallet::get_decoys(const rpc::get_random_outs_request& req) diff --git a/src/backend.h b/src/backend.h index 435fea3..e773a32 100644 --- a/src/backend.h +++ b/src/backend.h @@ -277,7 +277,7 @@ namespace lwsf { namespace internal { namespace backend //! Modify local and possibly server lookahead std::error_code set_lookahead(std::uint32_t major, std::uint32_t minor); - std::error_code restore_height(const std::uint64_t height); + expect restore_height(const std::uint64_t height); expect> get_decoys(const rpc::get_random_outs_request& req); std::error_code send_tx(epee::byte_slice tx_bytes); diff --git a/src/rpc.cpp b/src/rpc.cpp index 9c52012..46e3cae 100644 --- a/src/rpc.cpp +++ b/src/rpc.cpp @@ -437,6 +437,8 @@ namespace lwsf { namespace internal { namespace rpc WIRE_OPTIONAL_FIELD(payment_address), WIRE_OPTIONAL_FIELD(payment_id), WIRE_OPTIONAL_FIELD(import_fee), + WIRE_FIELD(status), + WIRE_FIELD(new_request), WIRE_FIELD(request_fulfilled) ); } diff --git a/src/rpc.h b/src/rpc.h index 0e4f95f..4e7758a 100644 --- a/src/rpc.h +++ b/src/rpc.h @@ -385,6 +385,8 @@ namespace lwsf { namespace internal { namespace rpc std::optional payment_address; std::optional payment_id; std::optional import_fee; + std::string status; + bool new_request; bool request_fulfilled; }; void read_bytes(wire::json_reader&, import_response&); diff --git a/src/wallet.cpp b/src/wallet.cpp index 21be7be..5e91589 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -778,7 +778,7 @@ namespace lwsf { namespace internal { const boost::lock_guard lock{data_->sync}; data_->primary.requested_start = std::min(data_->primary.requested_start, height); - queue_work([this, height] () { return data_->restore_height(height); }); + queue_work([this, height] () { return data_->restore_height(height).error(); }); } uint64_t wallet::getRefreshFromBlockHeight() const @@ -1077,9 +1077,9 @@ namespace lwsf { namespace internal { if (!amount && dst_addr.size() > 1) throw std::invalid_argument{"Sweep requested with multiple destinations"}; - if (amount && amount->size() != dst_addr.size()) + if (amount && (*amount).size() != dst_addr.size()) throw std::invalid_argument{"Must have equal amounts and destinations"}; - if (amount && amount->empty()) + if (amount && (*amount).empty()) throw std::invalid_argument{"Zero destinations only valid with empty amounts"}; if (!payment_id.empty()) throw std::invalid_argument{"Long payment id was provided - deprecated"}; @@ -1566,25 +1566,25 @@ namespace lwsf { namespace internal cryptonote::set_encrypted_payment_id_to_tx_extra_nonce(extra_nonce, info.payment_id); } - transfers_flat.insert({amount->at(i), dst_addr.at(i)}); + transfers_flat.insert({(*amount).at(i), dst_addr.at(i)}); auto& dest = dests_flat.emplace_back(); dest.original = dst_addr.at(i); dest.addr = info.address; - dest.amount = amount->at(i); + dest.amount = (*amount).at(i); dest.is_subaddress = info.is_subaddress; dest.is_integrated = info.has_payment_id; } LWSF_TX_VERIFY(bool(amount)); - LWSF_TX_VERIFY(dst_addr.size() <= amount->size()); - for (std::size_t i = dst_addr.size(); i < amount->size(); ++i) + LWSF_TX_VERIFY(dst_addr.size() <= (*amount).size()); + for (std::size_t i = dst_addr.size(); i < (*amount).size(); ++i) { // this is a "self-sweep" (consolidation) auto& dest = dests_flat.emplace_back(); dest.original = change_address; dest.addr = change_account; - dest.amount = amount->at(i); + dest.amount = (*amount).at(i); dest.is_subaddress = subaddr_account; dest.is_integrated = false; } @@ -1723,12 +1723,12 @@ namespace lwsf { namespace internal } Monero::PendingTransaction* wallet::createTransaction(const std::string &dst_addr, const std::string &payment_id, - std::optional amount, uint32_t mixin_count, + Monero::optional amount, uint32_t mixin_count, Monero::PendingTransaction::Priority priority, uint32_t subaddr_account, std::set subaddr_indices) { - return createTransactionMultDest({dst_addr}, payment_id, amount ? std::optional>{{*amount}} : std::nullopt, mixin_count, priority, subaddr_account, subaddr_indices); + return createTransactionMultDest({dst_addr}, payment_id, amount ? Monero::optional>{{*amount}} : std::nullopt, mixin_count, priority, subaddr_account, subaddr_indices); } bool wallet::submitTransaction(const std::string &fileName) @@ -1904,4 +1904,23 @@ namespace lwsf { namespace internal return out; } + +#ifndef LWSF_MASTER_ENABLE + bool wallet::lightWalletLogin(bool &isNewWallet) const override + { + } + + bool wallet::lightWalletImportWalletRequest(std::string &payment_id, uint64_t &fee, bool &new_request, bool &request_fulfilled, std::string &payment_address, std::string &status) override + { + expect import = data_->restore_height(0); + if (!import) + return false; + fee = std::uint64_t(import->import_fee.value_or(rpc::uint64_string(0))); + new_request = import->new_request; + request_fulfilled = import->request_fulfilled; + payment_address = import->payment_address.value_or({}); + status = std::move(import->status); + } +#endif LWSF_MASTER_ENABLE + }} // lwsf // internal diff --git a/src/wallet.h b/src/wallet.h index efbb04f..6dad380 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -417,6 +417,8 @@ namespace internal * @return new info string if more rounds required or an empty string if wallet creation is done */ virtual std::string exchangeMultisigKeys(const std::vector &info, const bool force_update_use_with_caution) override { /* TODO */ return {}; } + +#ifdef LWSF_MASTER_ENABLE /** * @brief getMultisigKeyExchangeBooster - obtain partial information for the key exchange round after the in-progress round, * to speed up another signer's key exchange process @@ -426,6 +428,8 @@ namespace internal * @return new info string if more rounds required or exception if no more rounds (i.e. no rounds to boost) */ virtual std::string getMultisigKeyExchangeBooster(const std::vector &info, const uint32_t threshold, const uint32_t num_signers) override { /* TODO */ return {}; } +#endif + /** * @brief exportMultisigImages - exports transfers' key images * @param images - output paramter for hex encoded array of images @@ -484,7 +488,7 @@ namespace internal */ virtual Monero::PendingTransaction* createTransaction(const std::string &dst_addr, const std::string &payment_id, - std::optional amount, uint32_t mixin_count, + Monero::optional amount, uint32_t mixin_count, Monero::PendingTransaction::Priority = Monero::PendingTransaction::Priority_Low, uint32_t subaddr_account = 0, std::set subaddr_indices = {}) override; @@ -727,6 +731,14 @@ namespace internal //! secondary key reuse mitigation virtual void keyReuseMitigation2(bool mitigation) override { /* TODO */ } +#ifndef LWSF_MASTER_ENABLE + //! Light wallet authenticate and login + virtual bool lightWalletLogin(bool &isNewWallet) const override; + + //! Initiates a light wallet import wallet request + virtual bool lightWalletImportWalletRequest(std::string &payment_id, uint64_t &fee, bool &new_request, bool &request_fulfilled, std::string &payment_address, std::string &status) override; +#endif LWSF_MASTER_ENABLE + //! locks/unlocks the keys file; returns true on success virtual bool lockKeysFile() override { return false; } virtual bool unlockKeysFile() override { return true; }