From 62c43a4ed2d4fd68cda428f8860c06141607e350 Mon Sep 17 00:00:00 2001 From: Some Random Crypto Guy Date: Thu, 30 Jan 2025 12:59:33 +0000 Subject: [PATCH] added audit index=all command; added audit RPC command; bumped version --- README.md | 2 +- src/simplewallet/simplewallet.cpp | 49 ++++++++------ src/version.cpp.in | 2 +- src/wallet/wallet_rpc_server.cpp | 71 ++++++++++++++++++++ src/wallet/wallet_rpc_server.h | 2 + src/wallet/wallet_rpc_server_commands_defs.h | 36 ++++++++++ 6 files changed, 141 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 2f08384..aa8788b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Salvium Zero v0.9.0-rc9 +# Salvium Zero v0.9.0-rc10 Copyright (c) 2023-2024, Salvium Portions Copyright (c) 2014-2023, The Monero Project diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 6df1ee2..17e4f62 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -6741,25 +6741,22 @@ bool simple_wallet::transfer_main( // "transfer [index=[,,...]] [] []
[]" if (!try_connect_to_daemon()) return false; - /* - bool audit = false; - if (m_wallet->get_current_hard_fork() >= HF_VERSION_SALVIUM_ONE_PROOFS) { - if (transfer_type == Audit) { - audit = true; - } - } - */ std::vector local_args = args_; std::set subaddr_indices; if (local_args.size() > 0 && local_args[0].substr(0, 6) == "index=") { - if (!parse_subaddress_indices(local_args[0], subaddr_indices)) - return false; + if (local_args[0] == "index=all") + { + for (uint32_t i = 0; i < m_wallet->get_num_subaddresses(m_current_subaddress_account); ++i) + subaddr_indices.insert(i); + } + else if (!parse_subaddress_indices(local_args[0], subaddr_indices)) + { + return true; + } local_args.erase(local_args.begin()); - if (transfer_type == Audit) - while (subaddr_indices.size() > 1) - subaddr_indices.erase(std::prev(subaddr_indices.end())); } + } uint32_t priority = m_wallet->get_default_priority(); if (local_args.size() > 0 && parse_priority(local_args[0], priority)) @@ -6975,8 +6972,25 @@ bool simple_wallet::transfer_main( std::vector ptx_vector; uint64_t unlock_block = 0; std::string err; - switch (transfer_type) - { + if (transfer_type == Audit) { + + // Get the subaddress unlocked balances + std::map>> unlocked_balance_per_subaddr = m_wallet->unlocked_balance_per_subaddress(m_current_subaddress_account, source_asset, true); + unlock_block = get_config(m_wallet->nettype()).AUDIT_LOCK_PERIOD; + for (const auto subaddr_index : subaddr_indices) { + + // Skip this wallet if there is no balance unlocked to audit + if (unlocked_balance_per_subaddr.count(subaddr_index) == 0) continue; + + std::set subaddr_indices_single; + subaddr_indices_single.insert(subaddr_index); + uint64_t unlock_block = get_config(m_wallet->nettype()).AUDIT_LOCK_PERIOD; + std::vector ptx_vector_audit = m_wallet->create_transactions_all(0, cryptonote::transaction_type::AUDIT, source_asset, m_wallet->get_subaddress({m_current_subaddress_account, subaddr_index}), (subaddr_index>0), 1, fake_outs_count, unlock_block, priority, extra, m_current_subaddress_account, subaddr_indices_single); + ptx_vector.insert(ptx_vector.end(), ptx_vector_audit.begin(), ptx_vector_audit.end()); + } + + } else { + switch (transfer_type) { case Burn: unlock_block = 0; ptx_vector = m_wallet->create_transactions_2(dsts, source_asset, dest_asset, cryptonote::transaction_type::BURN, fake_outs_count, unlock_block /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, subtract_fee_from_outputs); @@ -6985,10 +6999,6 @@ bool simple_wallet::transfer_main( unlock_block = CONVERT_LOCK_PERIOD; ptx_vector = m_wallet->create_transactions_2(dsts, source_asset, dest_asset, cryptonote::transaction_type::CONVERT, fake_outs_count, unlock_block /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, subtract_fee_from_outputs); break; - case Audit: - unlock_block = get_config(m_wallet->nettype()).AUDIT_LOCK_PERIOD; - ptx_vector = m_wallet->create_transactions_all(0, cryptonote::transaction_type::AUDIT, source_asset, m_wallet->get_subaddress({m_current_subaddress_account, 0}), false, 1, fake_outs_count, unlock_block, priority, extra, m_current_subaddress_account, subaddr_indices); - break; case Stake: unlock_block = get_config(m_wallet->nettype()).STAKE_LOCK_PERIOD; ptx_vector = m_wallet->create_transactions_2(dsts, source_asset, dest_asset, cryptonote::transaction_type::STAKE, fake_outs_count, unlock_block, priority, extra, m_current_subaddress_account, subaddr_indices, subtract_fee_from_outputs); @@ -7003,6 +7013,7 @@ bool simple_wallet::transfer_main( case Transfer: ptx_vector = m_wallet->create_transactions_2(dsts, source_asset, dest_asset, cryptonote::transaction_type::TRANSFER, fake_outs_count, 0 /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, subtract_fee_from_outputs); break; + } } if (ptx_vector.empty()) diff --git a/src/version.cpp.in b/src/version.cpp.in index 00e19f1..b043c63 100644 --- a/src/version.cpp.in +++ b/src/version.cpp.in @@ -1,5 +1,5 @@ #define DEF_SALVIUM_VERSION_TAG "@VERSIONTAG@" -#define DEF_SALVIUM_VERSION "0.9.0-rc9" +#define DEF_SALVIUM_VERSION "0.9.0-rc10" #define DEF_MONERO_VERSION_TAG "release" #define DEF_MONERO_VERSION "0.18.3.3" #define DEF_MONERO_RELEASE_NAME "Zero" diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 22df641..957f587 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -1093,6 +1093,77 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_audit(const wallet_rpc::COMMAND_RPC_AUDIT::request& req, wallet_rpc::COMMAND_RPC_AUDIT::response& res, epee::json_rpc::error& er, const connection_context *ctx) + { + std::vector dsts; + std::vector extra; + + if (!m_wallet) return not_open(er); + if (m_restricted) + { + er.code = WALLET_RPC_ERROR_CODE_DENIED; + er.message = "Command unavailable in restricted mode."; + return false; + } + + CHECK_MULTISIG_ENABLED(); + + std::string asset_type = req.asset_type.empty() ? "SAL" : req.asset_type; + + // validate the transfer requested and populate dsts & extra + std::list destinations; + destinations.push_back(wallet_rpc::transfer_destination()); + destinations.back().amount = 0; + destinations.back().address = req.address; + destinations.back().asset_type = asset_type; + + // validate the transfer requested and populate dsts & extra + if (!validate_transfer(destinations, asset_type, asset_type, cryptonote::transaction_type::AUDIT, req.payment_id, dsts, extra, true, er)) + { + return false; + } + + std::set subaddr_indices; + if (req.subaddr_indices_all) + { + for (uint32_t i = 0; i < m_wallet->get_num_subaddresses(req.account_index); ++i) + subaddr_indices.insert(i); + } + else + { + subaddr_indices= req.subaddr_indices; + } + + try + { + std::vector ptx_vector_all; + // Get the subaddress unlocked balances + std::map>> unlocked_balance_per_subaddr = m_wallet->unlocked_balance_per_subaddress(req.account_index, asset_type, true); + for (const auto subaddr_index : subaddr_indices) { + + // Skip this wallet if there is no balance unlocked to audit + if (unlocked_balance_per_subaddr.count(subaddr_index) == 0) continue; + + std::set subaddr_indices_single; + subaddr_indices_single.insert(subaddr_index); + uint64_t mixin = m_wallet->adjust_mixin(req.ring_size ? req.ring_size - 1 : 0); + uint32_t priority = m_wallet->adjust_priority(0); + uint64_t unlock_block = get_config(m_wallet->nettype()).AUDIT_LOCK_PERIOD; + std::vector ptx_vector = m_wallet->create_transactions_all(0, cryptonote::transaction_type::AUDIT, asset_type, m_wallet->get_subaddress({req.account_index, subaddr_index}), (subaddr_index > 0), 1, mixin, unlock_block, priority, extra, req.account_index, subaddr_indices_single); + ptx_vector_all.insert(ptx_vector_all.end(), ptx_vector.begin(), ptx_vector.end()); + } + + return fill_response(ptx_vector_all, req.get_tx_keys, res.tx_key_list, res.amount_list, res.amounts_by_dest_list, res.fee_list, res.weight_list, res.multisig_txset, res.unsigned_txset, req.do_not_relay, + res.tx_hash_list, req.get_tx_hex, res.tx_blob_list, req.get_tx_metadata, res.tx_metadata_list, res.spent_key_images_list, er); + } + catch (const std::exception& e) + { + handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR); + return false; + } + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_transfer(const wallet_rpc::COMMAND_RPC_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_TRANSFER::response& res, epee::json_rpc::error& er, const connection_context *ctx) { diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index 40bb543..21a61c2 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -87,6 +87,7 @@ namespace tools MAP_JON_RPC_WE("freeze", on_freeze, wallet_rpc::COMMAND_RPC_FREEZE) MAP_JON_RPC_WE("thaw", on_thaw, wallet_rpc::COMMAND_RPC_THAW) MAP_JON_RPC_WE("frozen", on_frozen, wallet_rpc::COMMAND_RPC_FROZEN) + MAP_JON_RPC_WE("audit", on_audit, wallet_rpc::COMMAND_RPC_AUDIT) MAP_JON_RPC_WE("transfer", on_transfer, wallet_rpc::COMMAND_RPC_TRANSFER) MAP_JON_RPC_WE("transfer_split", on_transfer_split, wallet_rpc::COMMAND_RPC_TRANSFER_SPLIT) MAP_JON_RPC_WE("sign_transfer", on_sign_transfer, wallet_rpc::COMMAND_RPC_SIGN_TRANSFER) @@ -180,6 +181,7 @@ namespace tools bool on_freeze(const wallet_rpc::COMMAND_RPC_FREEZE::request& req, wallet_rpc::COMMAND_RPC_FREEZE::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); bool on_thaw(const wallet_rpc::COMMAND_RPC_THAW::request& req, wallet_rpc::COMMAND_RPC_THAW::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); bool on_frozen(const wallet_rpc::COMMAND_RPC_FROZEN::request& req, wallet_rpc::COMMAND_RPC_FROZEN::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_audit(const wallet_rpc::COMMAND_RPC_AUDIT::request& req, wallet_rpc::COMMAND_RPC_AUDIT::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); bool on_transfer(const wallet_rpc::COMMAND_RPC_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_TRANSFER::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); bool on_transfer_split(const wallet_rpc::COMMAND_RPC_TRANSFER_SPLIT::request& req, wallet_rpc::COMMAND_RPC_TRANSFER_SPLIT::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); bool on_sign_transfer(const wallet_rpc::COMMAND_RPC_SIGN_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_SIGN_TRANSFER::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); diff --git a/src/wallet/wallet_rpc_server_commands_defs.h b/src/wallet/wallet_rpc_server_commands_defs.h index 310a832..3c11071 100644 --- a/src/wallet/wallet_rpc_server_commands_defs.h +++ b/src/wallet/wallet_rpc_server_commands_defs.h @@ -864,6 +864,42 @@ namespace wallet_rpc typedef epee::misc_utils::struct_init response; }; + struct COMMAND_RPC_AUDIT + { + struct request_t + { + std::string address; + uint32_t account_index; + std::set subaddr_indices; + bool subaddr_indices_all; + uint64_t ring_size; + std::string payment_id; + bool get_tx_keys; + bool do_not_relay; + bool get_tx_hex; + bool get_tx_metadata; + std::string asset_type; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(address) + KV_SERIALIZE(account_index) + KV_SERIALIZE(subaddr_indices) + KV_SERIALIZE_OPT(subaddr_indices_all, false) + KV_SERIALIZE_OPT(ring_size, (uint64_t)0) + KV_SERIALIZE(payment_id) + KV_SERIALIZE(get_tx_keys) + KV_SERIALIZE_OPT(do_not_relay, false) + KV_SERIALIZE_OPT(get_tx_hex, false) + KV_SERIALIZE_OPT(get_tx_metadata, false) + KV_SERIALIZE(asset_type) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; + + typedef split_transfer_response response_t; + typedef epee::misc_utils::struct_init response; + }; + struct COMMAND_RPC_SWEEP_ALL { struct request_t