Changes for monero_c

This commit is contained in:
Lee *!* Clagett
2025-07-22 20:01:20 -04:00
parent b365726cbf
commit 93d7ff1eeb
8 changed files with 91 additions and 25 deletions
+3
View File
@@ -67,10 +67,12 @@ endif()
find_package(Sodium REQUIRED) find_package(Sodium REQUIRED)
add_library(monero::libraries INTERFACE IMPORTED) add_library(monero::libraries INTERFACE IMPORTED)
set_property(TARGET monero::libraries PROPERTY set_property(TARGET monero::libraries PROPERTY
INTERFACE_INCLUDE_DIRECTORIES INTERFACE_INCLUDE_DIRECTORIES
${Boost_INCLUDE_DIR} ${Boost_INCLUDE_DIR}
"${MONERO_SOURCE_DIR}/contrib/epee/include" "${MONERO_SOURCE_DIR}/contrib/epee/include"
"${MONERO_SOURCE_DIR}/external"
"${MONERO_SOURCE_DIR}/external/easylogging++" "${MONERO_SOURCE_DIR}/external/easylogging++"
"${MONERO_SOURCE_DIR}/external/rapidjson/include" "${MONERO_SOURCE_DIR}/external/rapidjson/include"
"${MONERO_SOURCE_DIR}/external/supercop/include" "${MONERO_SOURCE_DIR}/external/supercop/include"
@@ -79,6 +81,7 @@ set_property(TARGET monero::libraries PROPERTY
set_property(TARGET monero::libraries PROPERTY set_property(TARGET monero::libraries PROPERTY
INTERFACE_LINK_LIBRARIES INTERFACE_LINK_LIBRARIES
common common
cryptonote_basic
epee epee
mnemonics mnemonics
qrcodegen qrcodegen
+5
View File
@@ -76,6 +76,10 @@ target_link_libraries(lwsf-api
Threads::Threads Threads::Threads
) )
if (${LWSF_MASTER_ENABLE})
target_compile_definitions(lwsf-api PRIVATE LWSF_MASTER_ENABLE)
endif()
add_executable(lwsf-ledger ledger_main.cpp) add_executable(lwsf-ledger ledger_main.cpp)
target_link_libraries(lwsf-ledger target_link_libraries(lwsf-ledger
PRIVATE PRIVATE
@@ -83,3 +87,4 @@ target_link_libraries(lwsf-ledger
${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY}
) )
+36 -13
View File
@@ -343,6 +343,19 @@ namespace lwsf { namespace internal { namespace backend
return out.sender; return out.sender;
} }
namespace
{
const unsigned char* ec_to_bytes(const crypto::ec_scalar& out)
{
return reinterpret_cast<const unsigned char*>(out.data);
}
unsigned char* ec_to_bytes(crypto::ec_scalar& out)
{
return reinterpret_cast<unsigned char*>(out.data);
}
}
crypto::secret_key get_spend_secret(const account& self, const std::optional<rpc::address_meta>& index) crypto::secret_key get_spend_secret(const account& self, const std::optional<rpc::address_meta>& index)
{ {
if (!index || index->is_default()) if (!index || index->is_default())
@@ -353,7 +366,7 @@ namespace lwsf { namespace internal { namespace backend
// D = B + M // D = B + M
crypto::secret_key out; 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; return out;
} }
@@ -1245,12 +1258,21 @@ namespace lwsf { namespace internal { namespace backend
return {}; return {};
} }
std::error_code wallet::restore_height(const std::uint64_t height) expect<rpc::import_response> wallet::restore_height(const std::uint64_t height)
{ {
const auto update_import = [this](expect<rpc::import_response> value)
{
if (value)
this->import_error = {};
else
this->import_error = value.error();
return value
}
boost::unique_lock<boost::mutex> lock{sync}; boost::unique_lock<boost::mutex> lock{sync};
if (primary.restore_height <= height) if (primary.restore_height <= height)
return import_error = {}; return update_import(import_response{});
if (import_error && import_error == error::import_pending) if (import_error && import_error == error::import_pending)
return import_error; return import_error;
@@ -1271,10 +1293,10 @@ namespace lwsf { namespace internal { namespace backend
lock.lock(); lock.lock();
if (!import) if (!import)
return import_error = import.error(); return update_import(import.error());
if (import->request_fulfilled) if (import->request_fulfilled)
return import_error = {}; return update_import(std::move(*import));
const unsigned total = const unsigned total =
unsigned(bool(import->import_fee)) + bool(import->payment_address); unsigned(bool(import->import_fee)) + bool(import->payment_address);
@@ -1282,23 +1304,24 @@ namespace lwsf { namespace internal { namespace backend
{ {
default: default:
case 0: case 0:
return import_error = error::import_pending; return update_import(error::import_pending);
case 1: case 1:
if (import->import_fee.value_or(rpc::uint64_string(0)) == rpc::uint64_string(0)) if (import->import_fee.value_or(rpc::uint64_string(0)) == rpc::uint64_string(0))
return import_error = error::import_pending; return update_import(error::import_pending);
return import_error = error::import_invalid; return update_import(error::import_invalid);
case 2: case 2:
break; break;
} }
cryptonote::address_parse_info info{}; cryptonote::address_parse_info info{};
if (!cryptonote::get_account_address_from_str(info, convert_net_type(primary.type), *import->payment_address)) 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) 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)))) 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; std::string payment_id;
if (import->payment_id) if (import->payment_id)
payment_id = epee::to_hex::string(epee::to_span(*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)}); primary.addressbook.push_back(address_book_entry{std::move(*import->payment_address), std::move(payment_id), std::move(description)});
else else
primary.addressbook[i] = address_book_entry{std::move(*import->payment_address), std::move(payment_id), std::move(description)}; primary.addressbook[i] = address_book_entry{std::move(*import->payment_address), std::move(payment_id), std::move(description)};
#endif
return import_error = {}; return update_import(std::move(*import));
} }
expect<std::vector<rpc::random_outputs>> wallet::get_decoys(const rpc::get_random_outs_request& req) expect<std::vector<rpc::random_outputs>> wallet::get_decoys(const rpc::get_random_outs_request& req)
+1 -1
View File
@@ -277,7 +277,7 @@ namespace lwsf { namespace internal { namespace backend
//! Modify local and possibly server lookahead //! Modify local and possibly server lookahead
std::error_code set_lookahead(std::uint32_t major, std::uint32_t minor); std::error_code set_lookahead(std::uint32_t major, std::uint32_t minor);
std::error_code restore_height(const std::uint64_t height); expect<rpc::import_response> restore_height(const std::uint64_t height);
expect<std::vector<rpc::random_outputs>> get_decoys(const rpc::get_random_outs_request& req); expect<std::vector<rpc::random_outputs>> get_decoys(const rpc::get_random_outs_request& req);
std::error_code send_tx(epee::byte_slice tx_bytes); std::error_code send_tx(epee::byte_slice tx_bytes);
+2
View File
@@ -437,6 +437,8 @@ namespace lwsf { namespace internal { namespace rpc
WIRE_OPTIONAL_FIELD(payment_address), WIRE_OPTIONAL_FIELD(payment_address),
WIRE_OPTIONAL_FIELD(payment_id), WIRE_OPTIONAL_FIELD(payment_id),
WIRE_OPTIONAL_FIELD(import_fee), WIRE_OPTIONAL_FIELD(import_fee),
WIRE_FIELD(status),
WIRE_FIELD(new_request),
WIRE_FIELD(request_fulfilled) WIRE_FIELD(request_fulfilled)
); );
} }
+2
View File
@@ -385,6 +385,8 @@ namespace lwsf { namespace internal { namespace rpc
std::optional<std::string> payment_address; std::optional<std::string> payment_address;
std::optional<epee::byte_slice> payment_id; std::optional<epee::byte_slice> payment_id;
std::optional<uint64_string> import_fee; std::optional<uint64_string> import_fee;
std::string status;
bool new_request;
bool request_fulfilled; bool request_fulfilled;
}; };
void read_bytes(wire::json_reader&, import_response&); void read_bytes(wire::json_reader&, import_response&);
+29 -10
View File
@@ -778,7 +778,7 @@ namespace lwsf { namespace internal
{ {
const boost::lock_guard<boost::mutex> lock{data_->sync}; const boost::lock_guard<boost::mutex> lock{data_->sync};
data_->primary.requested_start = std::min(data_->primary.requested_start, height); 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 uint64_t wallet::getRefreshFromBlockHeight() const
@@ -1077,9 +1077,9 @@ namespace lwsf { namespace internal
{ {
if (!amount && dst_addr.size() > 1) if (!amount && dst_addr.size() > 1)
throw std::invalid_argument{"Sweep requested with multiple destinations"}; 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"}; 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"}; throw std::invalid_argument{"Zero destinations only valid with empty amounts"};
if (!payment_id.empty()) if (!payment_id.empty())
throw std::invalid_argument{"Long payment id was provided - deprecated"}; 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); 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(); auto& dest = dests_flat.emplace_back();
dest.original = dst_addr.at(i); dest.original = dst_addr.at(i);
dest.addr = info.address; dest.addr = info.address;
dest.amount = amount->at(i); dest.amount = (*amount).at(i);
dest.is_subaddress = info.is_subaddress; dest.is_subaddress = info.is_subaddress;
dest.is_integrated = info.has_payment_id; dest.is_integrated = info.has_payment_id;
} }
LWSF_TX_VERIFY(bool(amount)); LWSF_TX_VERIFY(bool(amount));
LWSF_TX_VERIFY(dst_addr.size() <= amount->size()); LWSF_TX_VERIFY(dst_addr.size() <= (*amount).size());
for (std::size_t i = dst_addr.size(); i < amount->size(); ++i) for (std::size_t i = dst_addr.size(); i < (*amount).size(); ++i)
{ {
// this is a "self-sweep" (consolidation) // this is a "self-sweep" (consolidation)
auto& dest = dests_flat.emplace_back(); auto& dest = dests_flat.emplace_back();
dest.original = change_address; dest.original = change_address;
dest.addr = change_account; dest.addr = change_account;
dest.amount = amount->at(i); dest.amount = (*amount).at(i);
dest.is_subaddress = subaddr_account; dest.is_subaddress = subaddr_account;
dest.is_integrated = false; 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, Monero::PendingTransaction* wallet::createTransaction(const std::string &dst_addr, const std::string &payment_id,
std::optional<uint64_t> amount, uint32_t mixin_count, Monero::optional<uint64_t> amount, uint32_t mixin_count,
Monero::PendingTransaction::Priority priority, Monero::PendingTransaction::Priority priority,
uint32_t subaddr_account, uint32_t subaddr_account,
std::set<uint32_t> subaddr_indices) std::set<uint32_t> subaddr_indices)
{ {
return createTransactionMultDest({dst_addr}, payment_id, amount ? std::optional<std::vector<uint64_t>>{{*amount}} : std::nullopt, mixin_count, priority, subaddr_account, subaddr_indices); return createTransactionMultDest({dst_addr}, payment_id, amount ? Monero::optional<std::vector<uint64_t>>{{*amount}} : std::nullopt, mixin_count, priority, subaddr_account, subaddr_indices);
} }
bool wallet::submitTransaction(const std::string &fileName) bool wallet::submitTransaction(const std::string &fileName)
@@ -1904,4 +1904,23 @@ namespace lwsf { namespace internal
return out; 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<rpc::import_wallet_response> 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 }} // lwsf // internal
+13 -1
View File
@@ -417,6 +417,8 @@ namespace internal
* @return new info string if more rounds required or an empty string if wallet creation is done * @return new info string if more rounds required or an empty string if wallet creation is done
*/ */
virtual std::string exchangeMultisigKeys(const std::vector<std::string> &info, const bool force_update_use_with_caution) override { /* TODO */ return {}; } virtual std::string exchangeMultisigKeys(const std::vector<std::string> &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, * @brief getMultisigKeyExchangeBooster - obtain partial information for the key exchange round after the in-progress round,
* to speed up another signer's key exchange process * 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) * @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<std::string> &info, const uint32_t threshold, const uint32_t num_signers) override { /* TODO */ return {}; } virtual std::string getMultisigKeyExchangeBooster(const std::vector<std::string> &info, const uint32_t threshold, const uint32_t num_signers) override { /* TODO */ return {}; }
#endif
/** /**
* @brief exportMultisigImages - exports transfers' key images * @brief exportMultisigImages - exports transfers' key images
* @param images - output paramter for hex encoded array of 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, virtual Monero::PendingTransaction* createTransaction(const std::string &dst_addr, const std::string &payment_id,
std::optional<uint64_t> amount, uint32_t mixin_count, Monero::optional<uint64_t> amount, uint32_t mixin_count,
Monero::PendingTransaction::Priority = Monero::PendingTransaction::Priority_Low, Monero::PendingTransaction::Priority = Monero::PendingTransaction::Priority_Low,
uint32_t subaddr_account = 0, uint32_t subaddr_account = 0,
std::set<uint32_t> subaddr_indices = {}) override; std::set<uint32_t> subaddr_indices = {}) override;
@@ -727,6 +731,14 @@ namespace internal
//! secondary key reuse mitigation //! secondary key reuse mitigation
virtual void keyReuseMitigation2(bool mitigation) override { /* TODO */ } 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 //! locks/unlocks the keys file; returns true on success
virtual bool lockKeysFile() override { return false; } virtual bool lockKeysFile() override { return false; }
virtual bool unlockKeysFile() override { return true; } virtual bool unlockKeysFile() override { return true; }