Port monero-lws to wownero-lws

Adapts monero-lws for Wownero cryptocurrency:

- Rename all monero-lws-* binaries to wownero-lws-*
- Update submodule to point to official Wownero repo
- Use Wownero default ports (RPC: 34568, ZMQ: 34569)
- Update data directory to ~/.wownero/light_wallet_server
- Adapt next_difficulty() calls for Wownero API signature

Key technical changes for Wownero compatibility:

- BulletproofPlus (RCTTypeBulletproofPlus, type 8) commitment verification:
  Wownero stores BP+ commitments in 'divided by 8' form. Must call
  rct::scalarmult8() on outPk commitment before comparing with computed
  commitment (mask*G + amount*H). This is essential for amount decryption.

- Pass rct_type to decode_amount() for proper commitment handling

- Handle Wownero's ZMQ JSON format for ecdhTuple (32-byte mask/amount fields)

No fork of Wownero is required - uses official codeberg.org/wownero/wownero.
This commit is contained in:
jwinterm
2026-01-04 13:12:56 -05:00
parent f2b3534002
commit 97877eda27
35 changed files with 809 additions and 396 deletions

View File

@@ -1,4 +1,5 @@
# Copyright (c) 2018-2020, The Monero Project
# Copyright (c) 2024-2025, The Wownero Project
#
# All rights reserved.
#
@@ -65,25 +66,24 @@ add_subdirectory(rpc)
add_subdirectory(util)
# For both the server and admin utility.
set(monero-lws-common_sources config.cpp error.cpp)
set(monero-lws-common_headers config.h error.h fwd.h)
set(wownero-lws-common_sources config.cpp error.cpp)
set(wownero-lws-common_headers config.h error.h fwd.h)
add_library(monero-lws-common ${monero-lws-common_sources} ${monero-lws-common_headers})
target_link_libraries(monero-lws-common monero::libraries)
add_library(wownero-lws-common ${wownero-lws-common_sources} ${wownero-lws-common_headers})
target_link_libraries(wownero-lws-common wownero::libraries)
add_library(monero-lws-daemon-common rest_server.cpp scanner.cpp)
target_include_directories(monero-lws-daemon-common PUBLIC ${ZMQ_INCLUDE_PATH})
target_link_libraries(monero-lws-daemon-common
add_library(wownero-lws-daemon-common rest_server.cpp scanner.cpp)
target_include_directories(wownero-lws-daemon-common PUBLIC ${ZMQ_INCLUDE_PATH})
target_link_libraries(wownero-lws-daemon-common
PUBLIC
monero::libraries
${MONERO_lmdb}
monero-lws-common
monero-lws-db
monero-lws-net
monero-lws-rpc
monero-lws-rpc-scanner
monero-lws-wire-json
monero-lws-util
${WOWNERO_lmdb}
wownero-lws-common
wownero-lws-db
wownero-lws-net
wownero-lws-rpc
wownero-lws-rpc-scanner
wownero-lws-wire-json
wownero-lws-util
${Boost_CHRONO_LIBRARY}
${Boost_COROUTINE_LIBRARY}
${Boost_CONTEXT_LIBRARY}
@@ -95,42 +95,43 @@ target_link_libraries(monero-lws-daemon-common
${ZMQ_LIB}
${SODIUM_LIBRARY}
Threads::Threads
wownero::libraries
)
add_executable(monero-lws-daemon server_main.cpp)
target_link_libraries(monero-lws-daemon
add_executable(wownero-lws-daemon server_main.cpp)
target_link_libraries(wownero-lws-daemon
PRIVATE
monero::libraries
monero-lws-daemon-common
monero-lws-rpc-scanner
wownero-lws-daemon-common
wownero-lws-rpc-scanner
${Boost_PROGRAM_OPTIONS_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
wownero::libraries
)
add_executable(monero-lws-admin admin_main.cpp)
target_link_libraries(monero-lws-admin
add_executable(wownero-lws-admin admin_main.cpp)
target_link_libraries(wownero-lws-admin
PRIVATE
monero::libraries
monero-lws-common
monero-lws-db
monero-lws-rpc
monero-lws-wire-json
wownero-lws-common
wownero-lws-db
wownero-lws-rpc
wownero-lws-wire-json
${Boost_PROGRAM_OPTIONS_LIBRARY}
Threads::Threads
wownero::libraries
)
add_executable(monero-lws-client client_main.cpp)
target_link_libraries(monero-lws-client
add_executable(wownero-lws-client client_main.cpp)
target_link_libraries(wownero-lws-client
PRIVATE
monero::libraries
monero-lws-common
monero-lws-daemon-common
monero-lws-rpc
monero-lws-rpc-scanner
wownero-lws-common
wownero-lws-daemon-common
wownero-lws-rpc
wownero-lws-rpc-scanner
${Boost_PROGRAM_OPTIONS_LIBRARY}
Threads::Threads
wownero::libraries
)
install(TARGETS monero-lws-daemon DESTINATION bin)
install(TARGETS monero-lws-admin DESTINATION bin)
install(TARGETS monero-lws-client DESTINATION bin)
install(TARGETS wownero-lws-daemon DESTINATION bin)
install(TARGETS wownero-lws-admin DESTINATION bin)
install(TARGETS wownero-lws-client DESTINATION bin)

View File

@@ -1,4 +1,5 @@
# Copyright (c) 2018-2020, The Monero Project
# Copyright (c) 2024-2025, The Wownero Project
#
# All rights reserved.
#
@@ -26,9 +27,9 @@
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set(monero-lws-db_sources account.cpp data.cpp storage.cpp string.cpp)
set(monero-lws-db_headers account.h data.h fwd.h storage.h string.h)
set(wownero-lws-db_sources account.cpp data.cpp storage.cpp string.cpp)
set(wownero-lws-db_headers account.h data.h fwd.h storage.h string.h)
add_library(monero-lws-db ${monero-lws-db_sources} ${monero-lws-db_headers})
target_include_directories(monero-lws-db PUBLIC "${LMDB_INCLUDE}")
target_link_libraries(monero-lws-db monero::libraries monero-lws-common monero-lws-lmdb monero-lws-wire-msgpack ${LMDB_LIB_PATH})
add_library(wownero-lws-db ${wownero-lws-db_sources} ${wownero-lws-db_headers})
target_include_directories(wownero-lws-db PUBLIC "${LMDB_INCLUDE}")
target_link_libraries(wownero-lws-db wownero-lws-common wownero-lws-lmdb wownero-lws-wire-msgpack ${LMDB_LIB_PATH} wownero::libraries)

View File

@@ -3178,8 +3178,14 @@ namespace db
std::min(lmdb::to_native(last_block.id), last_update);
const std::uint64_t offset = last_same - lmdb::to_native(height);
if (MONERO_UNWRAP(do_get_block_hash(*blocks_cur, block_id(last_same))) != *(chain_copy.begin() + offset))
const crypto::hash stored_hash = MONERO_UNWRAP(do_get_block_hash(*blocks_cur, block_id(last_same)));
const crypto::hash scanner_hash = *(chain_copy.begin() + offset);
if (stored_hash != scanner_hash)
{
MERROR("Hash mismatch at block " << last_same << ": DB has " << stored_hash << ", scanner has " << scanner_hash << ". FORCING ROLLBACK to " << last_same);
MONERO_CHECK(rollback_chain(this->db->tables, txn, *blocks_cur, block_id(last_same)));
return {lws::error::blockchain_reorg};
}
chain_copy.remove_prefix(offset + 1);
MONERO_CHECK(

View File

@@ -1,4 +1,5 @@
# Copyright (c) 2024, The Monero Project
# Copyright (c) 2024-2025, The Wownero Project
#
# All rights reserved.
#
@@ -26,9 +27,9 @@
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set(monero-lws-lmdb_sources lws_database.cpp lws_error.cpp)
set(monero-lws-lmdb_headers lws_database.h lws_error.h lws_key_stream.h lws_table.h lws_value_stream.h msgpack_table.h)
set(wownero-lws-lmdb_sources lws_database.cpp lws_error.cpp)
set(wownero-lws-lmdb_headers lws_database.h lws_error.h lws_key_stream.h lws_table.h lws_value_stream.h msgpack_table.h)
add_library(monero-lws-lmdb ${monero-lws-lmdb_sources} ${monero-lws-lmdb_headers})
target_include_directories(monero-lws-lmdb PUBLIC "${LMDB_INCLUDE}")
target_link_libraries(monero-lws-lmdb PRIVATE monero::libraries)
add_library(wownero-lws-lmdb ${wownero-lws-lmdb_sources} ${wownero-lws-lmdb_headers})
target_include_directories(wownero-lws-lmdb PUBLIC "${LMDB_INCLUDE}")
target_link_libraries(wownero-lws-lmdb PRIVATE wownero::libraries)

View File

@@ -69,6 +69,7 @@ namespace lws_lmdb
environment out{obj};
MONERO_LMDB_CHECK(mdb_env_set_maxdbs(out.get(), max_dbs));
MONERO_LMDB_CHECK(mdb_env_set_mapsize(out.get(), 10ull * 1024 * 1024 * 1024));
MONERO_LMDB_CHECK(mdb_env_open(out.get(), path, 0, open_flags));
return {std::move(out)};
}

View File

@@ -1,4 +1,5 @@
// Copyright (c) 2025, The Monero Project
// Copyright (c) 2024-2025, The Wownero Project
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
@@ -34,7 +35,7 @@ namespace lws { namespace version
constexpr const char commit[] = "@MLWS_COMMIT_HASH@";
constexpr const char date[] = "@MLWS_COMMIT_DATE@";
constexpr const char id[] = "1.0-alpha";
constexpr const char name[] = "monero-lws";
constexpr const char name[] = "wownero-lws";
// openmonero is currently on 1.6 and we have multiple additions since then
namespace api

View File

@@ -1,4 +1,5 @@
# Copyright (c) 2024, The Monero Project
# Copyright (c) 2024-2025, The Wownero Project
#
# All rights reserved.
#
@@ -28,8 +29,8 @@
add_subdirectory(http)
set(monero-lws-net_sources zmq_async.cpp)
set(monero-lws-net_headers zmq_async.h)
set(wownero-lws-net_sources zmq_async.cpp)
set(wownero-lws-net_headers zmq_async.h)
add_library(monero-lws-net ${monero-lws-net_sources} ${monero-lws-net_headers})
target_link_libraries(monero-lws-net monero-lws-net-http monero::libraries)
add_library(wownero-lws-net ${wownero-lws-net_sources} ${wownero-lws-net_headers})
target_link_libraries(wownero-lws-net wownero-lws-net-http wownero::libraries)

View File

@@ -1,4 +1,5 @@
# Copyright (c) 2024, The Monero Project
# Copyright (c) 2024-2025, The Wownero Project
#
# All rights reserved.
#
@@ -26,8 +27,8 @@
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set(monero-lws-net-http_sources client.cpp)
set(monero-lws-net-http_headers client.h slice_body.h)
set(wownero-lws-net-http_sources client.cpp)
set(wownero-lws-net-http_headers client.h slice_body.h)
add_library(monero-lws-net-http ${monero-lws-net-http_sources} ${monero-lws-net-http_headers})
target_link_libraries(monero-lws-net-http ${Boost_SYSTEM_LIBRARY} monero::libraries)
add_library(wownero-lws-net-http ${wownero-lws-net-http_sources} ${wownero-lws-net-http_headers})
target_link_libraries(wownero-lws-net-http ${Boost_SYSTEM_LIBRARY} wownero::libraries)

View File

@@ -1,4 +1,5 @@
# Copyright (c) 2020-2024, The Monero Project
# Copyright (c) 2024-2025, The Wownero Project
#
# All rights reserved.
#
@@ -28,9 +29,9 @@
add_subdirectory(scanner)
set(monero-lws-rpc_sources admin.cpp client.cpp daemon_pub.cpp daemon_zmq.cpp light_wallet.cpp lws_pub.cpp rates.cpp)
set(monero-lws-rpc_headers admin.h client.h daemon_pub.h daemon_zmq.h fwd.h json.h light_wallet.h lws_pub.h rates.h)
set(wownero-lws-rpc_sources admin.cpp client.cpp daemon_pub.cpp daemon_zmq.cpp light_wallet.cpp lws_pub.cpp rates.cpp)
set(wownero-lws-rpc_headers admin.h client.h daemon_pub.h daemon_zmq.h fwd.h json.h light_wallet.h lws_pub.h rates.h)
add_library(monero-lws-rpc ${monero-lws-rpc_sources} ${monero-lws-rpc_headers})
target_include_directories(monero-lws-rpc PRIVATE ${RMQ_INCLUDE_DIR})
target_link_libraries(monero-lws-rpc monero::libraries monero-lws-util monero-lws-wire-json monero-lws-wire-wrapper ${RMQ_LIBRARY})
add_library(wownero-lws-rpc ${wownero-lws-rpc_sources} ${wownero-lws-rpc_headers})
target_include_directories(wownero-lws-rpc PRIVATE ${RMQ_INCLUDE_DIR})
target_link_libraries(wownero-lws-rpc wownero::libraries wownero-lws-util wownero-lws-wire-json wownero-lws-wire-wrapper ${RMQ_LIBRARY})

View File

@@ -71,7 +71,7 @@ namespace rpc
constexpr const char abort_process_signal[] = "PROCESS";
constexpr const char minimal_chain_topic[] = "json-minimal-chain_main";
constexpr const char full_txpool_topic[] = "json-full-txpool_add";
constexpr const int daemon_zmq_linger = 0;
constexpr const int daemon_zmq_linger = 1000;
constexpr const int account_zmq_linger = 0;
constexpr const std::int64_t max_msg_sub = 10 * 1024 * 1024; // 50 MiB
constexpr const std::int64_t max_msg_req = 350 * 1024 * 1024; // 350 MiB

View File

@@ -28,9 +28,12 @@
#include "daemon_zmq.h"
#include <boost/optional/optional.hpp>
#include "misc_log_ex.h"
#include "string_tools.h"
#include "cryptonote_config.h" // monero/src
#include "crypto/crypto.h" // monero/src
#include "rpc/message_data_structs.h" // monero/src
#include "ringct/rctOps.h"
#include "wire/adapted/crypto.h"
#include "wire/json.h"
#include "wire/wrapper/array.h"
@@ -61,15 +64,23 @@ namespace
namespace rct
{
static void read_bytes(wire::json_reader& source, key& self)
{
source.binary(epee::as_mut_byte_span(self.bytes));
}
static void read_bytes(wire::json_reader& source, ctkey& self)
{
self.dest = {};
read_bytes(source, self.mask);
source.binary(epee::as_mut_byte_span(self.mask));
}
static void read_bytes(wire::json_reader& source, ecdhTuple& self)
{
wire::object(source, WIRE_FIELD(mask), WIRE_FIELD(amount));
wire::object(source,
WIRE_FIELD(mask),
WIRE_FIELD(amount)
);
}
static void read_bytes(wire::json_reader& source, clsag& self)
@@ -205,6 +216,11 @@ namespace rct
wire::optional_field("prunable", std::ref(prunable))
);
if (self.type != RCTTypeNull)
{
MDEBUG("Parsed rctSig: type=" << (int)self.type << " encrypted_count=" << self.ecdhInfo.size() << " commitments_count=" << self.outPk.size());
}
self.txnFee = 0;
if (self.type != RCTTypeNull)
{
@@ -213,7 +229,7 @@ namespace rct
self.txnFee = std::move(*txnFee);
}
else if (!self.ecdhInfo.empty() || !self.outPk.empty() || txnFee)
WIRE_DLOG_THROW(wire::error::schema::invalid_key, "Did not expected `encrypted`, `commitments`, or `fee`");
WIRE_DLOG_THROW(wire::error::schema::invalid_key, "Did not expect `encrypted`, `commitments`, or `fee`");
if (prunable)
{
@@ -289,30 +305,47 @@ namespace cryptonote
self.vin.reserve(default_inputs);
self.vout.reserve(default_outputs);
self.extra.reserve(default_txextra_size);
boost::optional<rct::rctSig> ringct;
wire::object(source,
WIRE_FIELD(version),
WIRE_FIELD(unlock_time),
wire::field("inputs", wire::array<max_inputs_per_tx>(std::ref(self.vin))),
wire::field("outputs", wire::array<max_outputs_per_tx>(std::ref(self.vout))),
WIRE_FIELD(extra),
WIRE_FIELD_ARRAY(signatures, max_inputs_per_tx),
wire::field("ringct", std::ref(self.rct_signatures))
wire::optional_field("signatures", wire::array<max_inputs_per_tx>(std::ref(self.signatures))),
wire::optional_field("ringct", std::ref(ringct))
);
if (ringct)
self.rct_signatures = std::move(*ringct);
}
static void read_bytes(wire::json_reader& source, block& self)
{
using min_hash_size = wire::min_element_sizeof<crypto::hash>;
self.tx_hashes.reserve(default_transaction_count);
boost::optional<crypto::signature> signature;
boost::optional<uint16_t> vote;
wire::object(source,
WIRE_FIELD(major_version),
WIRE_FIELD(minor_version),
WIRE_FIELD(timestamp),
WIRE_FIELD(miner_tx),
WIRE_FIELD_ARRAY(tx_hashes, min_hash_size),
WIRE_FIELD(prev_id),
WIRE_FIELD(nonce)
WIRE_FIELD(nonce),
wire::optional_field("signature", std::ref(signature)),
wire::optional_field("vote", std::ref(vote)),
WIRE_FIELD(miner_tx),
WIRE_FIELD_ARRAY(tx_hashes, min_hash_size)
);
if (signature)
self.signature = *signature;
if (vote)
self.vote = *vote;
}
static void read_bytes(wire::json_reader& source, std::vector<transaction>& self)

View File

@@ -1,4 +1,5 @@
# Copyright (c) 2024, The Monero Project
# Copyright (c) 2024-2025, The Wownero Project
#
# All rights reserved.
#
@@ -26,12 +27,12 @@
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set(monero-lws-rpc-scanner_sources
set(wownero-lws-rpc-scanner_sources
client.cpp commands.cpp connection.cpp queue.cpp server.cpp write_commands.cpp
)
set(monero-lws-rpc-scanner_headers
set(wownero-lws-rpc-scanner_headers
client.h commands.h connection.h fwd.h queue.h read_commands.h server.h write_commands.h
)
add_library(monero-lws-rpc-scanner ${monero-lws-rpc-scanner_sources} ${monero-lws-rpc-scanner_headers})
target_link_libraries(monero-lws-rpc-scanner monero::libraries monero-lws-wire-msgpack)
add_library(wownero-lws-rpc-scanner ${wownero-lws-rpc-scanner_sources} ${wownero-lws-rpc-scanner_headers})
target_link_libraries(wownero-lws-rpc-scanner wownero::libraries wownero-lws-wire-msgpack)

View File

@@ -27,6 +27,7 @@
#include "scanner.h"
#include <algorithm>
#include "string_tools.h"
#include <boost/asio/use_future.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/range/combine.hpp>
@@ -528,7 +529,7 @@ namespace lws
{
const bool bulletproof2 = (rct::RCTTypeBulletproof2 <= tx.rct_signatures.type);
const auto decrypted = lws::decode_amount(
tx.rct_signatures.outPk.at(index).mask, tx.rct_signatures.ecdhInfo.at(index), active_derived, index, bulletproof2
tx.rct_signatures.outPk.at(index).mask, tx.rct_signatures.ecdhInfo.at(index), active_derived, index, bulletproof2, tx.rct_signatures.type
);
if (!decrypted)
{
@@ -743,6 +744,12 @@ namespace lws
if (fetched->blocks.empty())
throw std::runtime_error{"Daemon unexpectedly returned zero blocks"};
MINFO("Processing batch: " << fetched->start_height << " to " << (fetched->start_height + fetched->blocks.size() - 1) << " (" << fetched->blocks.size() << " blocks)");
if (!fetched->blocks.empty())
{
MINFO("First block hash: " << cryptonote::get_block_hash(fetched->blocks.front().block) << ", Last block hash: " << cryptonote::get_block_hash(fetched->blocks.back().block));
}
if (fetched->start_height != req.start_height)
{
MWARNING("Daemon sent wrong blocks, resetting state");
@@ -907,7 +914,7 @@ namespace lws
if (self.stop_)
return false;
diff = cryptonote::next_difficulty(pow_window.pow_timestamps, pow_window.cumulative_diffs, get_target_time(db::block_id(fetched->start_height)));
diff = cryptonote::next_difficulty(pow_window.pow_timestamps, pow_window.cumulative_diffs, get_target_time(db::block_id(fetched->start_height)), std::uint64_t(fetched->start_height), lws::config::network);
// skip POW hashing if done previously
if (disk && last_pow < db::block_id(fetched->start_height))
@@ -963,6 +970,8 @@ namespace lws
reader.reader = std::error_code{common_error::kInvalidArgument}; // cleanup reader before next write
MINFO("Thread " << thread_n << " processed " << blockchain.size() << " blocks(s) @ height " << fetched->start_height << " against " << users.size() << " account(s)");
if (!blockchain.empty())
MINFO("First block hash: " << blockchain.front() << " at height " << (fetched->start_height - blockchain.size() + 1) << ", last block hash: " << blockchain.back() << " at height " << fetched->start_height);
if (!store(self.io_, client, self.webhooks_, epee::to_span(blockchain), epee::to_span(users), epee::to_span(new_pow)))
return false;
@@ -1151,7 +1160,10 @@ namespace lws
for (;;)
{
if (req.known_hashes.empty())
{
MERROR("sync_quick: req.known_hashes is empty");
return {lws::error::bad_blockchain};
}
auto resp = fetch_chain<rpc::get_hashes_fast>(self, client, "get_hashes_fast", req);
if (!resp)
@@ -1163,6 +1175,7 @@ namespace lws
if (resp->hashes.size() <= 1 || resp->hashes.back() == req.known_hashes.front())
return {std::move(client)};
MINFO("Syncing " << resp->hashes.size() << " hashes from height " << resp->start_height);
MONERO_CHECK(disk.sync_chain(db::block_id(resp->start_height), epee::to_span(resp->hashes), regtest));
req.known_hashes.erase(req.known_hashes.begin(), --(req.known_hashes.end()));
@@ -1193,7 +1206,10 @@ namespace lws
for (;;)
{
if (req.block_ids.empty())
{
MERROR("sync_full: req.block_ids is empty");
return {lws::error::bad_blockchain};
}
auto resp = fetch_chain<rpc::get_blocks_fast>(self, client, "get_blocks_fast", req);
if (!resp)
@@ -1204,7 +1220,10 @@ namespace lws
crypto::hash hash{};
if (!cryptonote::get_block_hash(resp->blocks.front().block, hash))
{
MERROR("sync_full: failed to get hash of first block");
return {lws::error::bad_blockchain};
}
//
// exit loop if it appears we have synced to top of chain
@@ -1243,11 +1262,17 @@ namespace lws
// important check, ensure we haven't deviated from chain
if (block.prev_id != hash)
{
MERROR("sync_full: block.prev_id (" << block.prev_id << ") != hash (" << hash << ") at height " << std::uint64_t(height));
return {lws::error::bad_blockchain};
}
// compute block id hash
if (!cryptonote::get_block_hash(block, hash))
{
MERROR("sync_full: failed to get hash of block at height " << std::uint64_t(height));
return {lws::error::bad_blockchain};
}
req.block_ids.push_front(hash);
update_window(pow_window.pow_timestamps);
@@ -1260,7 +1285,7 @@ namespace lws
if (self.has_shutdown())
return {error::signal_abort_process};
diff = cryptonote::next_difficulty(pow_window.pow_timestamps, pow_window.cumulative_diffs, get_target_time(height));
diff = cryptonote::next_difficulty(pow_window.pow_timestamps, pow_window.cumulative_diffs, get_target_time(height), std::uint64_t(height), lws::config::network);
// skip POW hashing when sync is within checkpoint
// storage::sync_pow(...) currently verifies checkpoint hashes

View File

@@ -1,4 +1,5 @@
# Copyright (c) 2020, The Monero Project
# Copyright (c) 2024-2025, The Wownero Project
#
# All rights reserved.
#
@@ -26,8 +27,8 @@
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set(monero-lws-util_sources blocks.cpp gamma_picker.cpp random_outputs.cpp source_location.cpp transactions.cpp)
set(monero-lws-util_headers blocks.h fwd.h gamma_picker.h random_outputs.h source_location.h transactions.h)
set(wownero-lws-util_sources blocks.cpp gamma_picker.cpp random_outputs.cpp source_location.cpp transactions.cpp)
set(wownero-lws-util_headers blocks.h fwd.h gamma_picker.h random_outputs.h source_location.h transactions.h)
add_library(monero-lws-util ${monero-lws-util_sources} ${monero-lws-util_headers})
target_link_libraries(monero-lws-util monero::libraries monero-lws-db)
add_library(wownero-lws-util ${wownero-lws-util_sources} ${wownero-lws-util_headers})
target_link_libraries(wownero-lws-util wownero::libraries wownero-lws-db)

View File

@@ -45,7 +45,7 @@ void lws::decrypt_payment_id(crypto::hash8& out, const crypto::key_derivation& k
out.data[b] ^= hash.data[b];
}
boost::optional<std::pair<std::uint64_t, rct::key>> lws::decode_amount(const rct::key& commitment, const rct::ecdhTuple& info, const crypto::key_derivation& sk, std::size_t index, const bool bulletproof2)
boost::optional<std::pair<std::uint64_t, rct::key>> lws::decode_amount(const rct::key& commitment, const rct::ecdhTuple& info, const crypto::key_derivation& sk, std::size_t index, const bool bulletproof2, const std::uint8_t rct_type)
{
crypto::secret_key scalar{};
crypto::derivation_to_scalar(sk, index, scalar);
@@ -55,7 +55,14 @@ boost::optional<std::pair<std::uint64_t, rct::key>> lws::decode_amount(const rct
rct::key Ctmp;
rct::addKeys2(Ctmp, copy.mask, copy.amount, rct::H);
if (rct::equalKeys(commitment, Ctmp))
// Wownero BulletproofPlus: commitments are stored in "divided by 8" form
// Must multiply by 8 (scalarmult8) before comparing
rct::key C = commitment;
if (rct_type == rct::RCTTypeBulletproofPlus)
C = rct::scalarmult8(C);
if (rct::equalKeys(C, Ctmp))
return {{rct::h2d(copy.amount), copy.mask}};
return boost::none;
}

View File

@@ -41,5 +41,5 @@ namespace crypto
namespace lws
{
void decrypt_payment_id(crypto::hash8& out, const crypto::key_derivation& key);
boost::optional<std::pair<std::uint64_t, rct::key>> decode_amount(const rct::key& commitment, const rct::ecdhTuple& info, const crypto::key_derivation& sk, std::size_t index, const bool bulletproof2);
boost::optional<std::pair<std::uint64_t, rct::key>> decode_amount(const rct::key& commitment, const rct::ecdhTuple& info, const crypto::key_derivation& sk, std::size_t index, const bool bulletproof2, const std::uint8_t rct_type);
}

View File

@@ -1,4 +1,5 @@
# Copyright (c) 2020-2023, The Monero Project
# Copyright (c) 2024-2025, The Wownero Project
#
# All rights reserved.
#
@@ -26,12 +27,12 @@
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set(monero-lws-wire_sources error.cpp read.cpp write.cpp)
set(monero-lws-wire_headers error.h field.h filters.h fwd.h json.h read.h traits.h vector.h write.h)
set(wownero-lws-wire_sources error.cpp read.cpp write.cpp)
set(wownero-lws-wire_headers error.h field.h filters.h fwd.h json.h read.h traits.h vector.h write.h)
add_library(monero-lws-wire ${monero-lws-wire_sources} ${monero-lws-wire_headers})
target_include_directories(monero-lws-wire PUBLIC "${LMDB_INCLUDE}")
target_link_libraries(monero-lws-wire PRIVATE monero::libraries)
add_library(wownero-lws-wire ${wownero-lws-wire_sources} ${wownero-lws-wire_headers})
target_include_directories(wownero-lws-wire PUBLIC "${LMDB_INCLUDE}")
target_link_libraries(wownero-lws-wire PRIVATE wownero::libraries)
add_subdirectory(json)
add_subdirectory(msgpack)

View File

@@ -1,4 +1,5 @@
# Copyright (c) 2020, The Monero Project
# Copyright (c) 2024-2025, The Wownero Project
#
# All rights reserved.
#
@@ -26,8 +27,8 @@
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set(monero-lws_wire-json_sources error.cpp read.cpp write.cpp)
set(monero-lws_wire-json_headers base.h error.h fwd.h read.h write.h)
set(wownero-lws_wire-json_sources error.cpp read.cpp write.cpp)
set(wownero-lws_wire-json_headers base.h error.h fwd.h read.h write.h)
add_library(monero-lws-wire-json ${monero-lws_wire-json_sources} ${monero-lws-wire-json_headers})
target_link_libraries(monero-lws-wire-json monero::libraries monero-lws-wire)
add_library(wownero-lws-wire-json ${wownero-lws_wire-json_sources} ${wownero-lws-wire-json_headers})
target_link_libraries(wownero-lws-wire-json wownero::libraries wownero-lws-wire)

View File

@@ -1,4 +1,5 @@
# Copyright (c) 2023, The Monero Project
# Copyright (c) 2024-2025, The Wownero Project
#
# All rights reserved.
#
@@ -26,8 +27,8 @@
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set(monero-lws_wire-msgpack_sources error.cpp read.cpp write.cpp)
set(monero-lws_wire-msgpack_headers base.h error.h fwd.h read.h write.h)
set(wownero-lws_wire-msgpack_sources error.cpp read.cpp write.cpp)
set(wownero-lws_wire-msgpack_headers base.h error.h fwd.h read.h write.h)
add_library(monero-lws-wire-msgpack ${monero-lws_wire-msgpack_sources} ${monero-lws-wire-msgpack_headers})
target_link_libraries(monero-lws-wire-msgpack monero::libraries monero-lws-wire)
add_library(wownero-lws-wire-msgpack ${wownero-lws_wire-msgpack_sources} ${wownero-lws-wire-msgpack_headers})
target_link_libraries(wownero-lws-wire-msgpack wownero::libraries wownero-lws-wire)

View File

@@ -1,4 +1,5 @@
# Copyright (c) 2020, The Monero Project
# Copyright (c) 2024-2025, The Wownero Project
#
# All rights reserved.
#
@@ -26,10 +27,10 @@
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set(monero-lws-wire_sources variant.cpp)
set(monero-lws-wire_headers variant.h)
set(wownero-lws-wire_sources variant.cpp)
set(wownero-lws-wire_headers variant.h)
add_library(monero-lws-wire-wrapper ${monero-lws-wire_sources} ${monero-lws-wire_headers})
target_include_directories(monero-lws-wire-wrapper PUBLIC "${LMDB_INCLUDE}")
target_link_libraries(monero-lws-wire-wrapper PRIVATE monero::libraries)
add_library(wownero-lws-wire-wrapper ${wownero-lws-wire_sources} ${wownero-lws-wire_headers})
target_include_directories(wownero-lws-wire-wrapper PUBLIC "${LMDB_INCLUDE}")
target_link_libraries(wownero-lws-wire-wrapper PRIVATE wownero::libraries)