From 21c16318257d729679d587e7e23d9556b9b31246 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 13 Mar 2024 13:16:36 +0100 Subject: [PATCH 001/184] auth basic r and d --- contrib/epee/include/net/net_helper.h | 2 +- .../currency_protocol_handler.inl | 5 +++ src/gui/qt-daemon/layout | 2 +- src/wallet/wallet_rpc_server.cpp | 33 +++++++++++++++++++ src/wallet/wallet_rpc_server.h | 11 ++++--- tests/CMakeLists.txt | 6 ++-- tests/performance_tests/main.cpp | 26 +++++++++++++++ tests/performance_tests/single_tx_test_base.h | 3 +- 8 files changed, 78 insertions(+), 10 deletions(-) diff --git a/contrib/epee/include/net/net_helper.h b/contrib/epee/include/net/net_helper.h index 4a42e679..fb3be17c 100644 --- a/contrib/epee/include/net/net_helper.h +++ b/contrib/epee/include/net/net_helper.h @@ -1,4 +1,4 @@ -// Copyright (c) 2019, anonimal, + // Copyright (c) 2019, anonimal, // Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net // All rights reserved. // diff --git a/src/currency_protocol/currency_protocol_handler.inl b/src/currency_protocol/currency_protocol_handler.inl index a23e85b5..9f4c22de 100644 --- a/src/currency_protocol/currency_protocol_handler.inl +++ b/src/currency_protocol/currency_protocol_handler.inl @@ -171,6 +171,11 @@ namespace currency return true; } + if(hshd.top_id == currency::null_hash) + { + LOG_PRINT_L0("wtf"); + } + int64_t diff = static_cast(hshd.current_height) - static_cast(m_core.get_current_blockchain_size()); LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, (is_inital ? "Inital ":"Idle ") << "sync data returned unknown top block (" << hshd.top_id << "): " << m_core.get_top_block_height() << " -> " << hshd.current_height - 1 << " [" << std::abs(diff) << " blocks (" << diff / (24 * 60 * 60 / DIFFICULTY_TOTAL_TARGET ) << " days) " diff --git a/src/gui/qt-daemon/layout b/src/gui/qt-daemon/layout index e4a76ad1..f8e9556f 160000 --- a/src/gui/qt-daemon/layout +++ b/src/gui/qt-daemon/layout @@ -1 +1 @@ -Subproject commit e4a76ad1329244ec4fb9ec7825361518e95d1933 +Subproject commit f8e9556fbaccd49841ce91afc3c90c8e3142ac95 diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index a602ecba..35e47b57 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -17,6 +17,7 @@ using namespace epee; #include "wallet_rpc_server_error_codes.h" #include "wallet_helpers.h" #include "wrap_service.h" +#include #define GET_WALLET() wallet_rpc_locker w(m_pwallet_provider); @@ -184,11 +185,43 @@ namespace tools m_net_server.set_threads_prefix("RPC"); bool r = handle_command_line(vm); CHECK_AND_ASSERT_MES(r, false, "Failed to process command line in core_rpc_server"); + m_jwt_secrete = "secretesecrete"; + return epee::http_server_impl_base::init(m_port, m_bind_ip); } //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::auth_http_request(const epee::net_utils::http::http_request_info& query_info, epee::net_utils::http::http_response_info& response, connection_context& m_conn_context) + { + + auto it = std::find_if(query_info.m_header_info.m_etc_fields.begin(), query_info.m_header_info.m_etc_fields.end(), [](const auto& element) + { return element.first == ZANO_ACCESS_TOKEN; }); + if(it == query_info.m_header_info.m_etc_fields.end()) + return false; + std::string token = it->second; //"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCIsInNhbXBsZSI6InRlc3QifQ.lQm3N2bVlqt2-1L-FsOjtR6uE-L4E9zJutMWKIe1v1M"; + auto decoded_token = jwt::decode(token); + + auto verifier = jwt::verify() + .with_issuer("auth0") + .with_claim("sample", jwt::claim(std::string("test"))) + .allow_algorithm(jwt::algorithm::hs256 { m_jwt_secrete }); + + verifier.verify(decoded_token); + return false; + + } + //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::handle_http_request(const epee::net_utils::http::http_request_info& query_info, epee::net_utils::http::http_response_info& response, connection_context& m_conn_context) { + if (m_jwt_secrete.size()) + { + if (!auth_http_request(query_info, response, m_conn_context)) + { + response.m_response_code = 401; + response.m_response_comment = "Unauthorized"; + return true; + } + } + response.m_response_code = 200; response.m_response_comment = "Ok"; std::string reference_stub; diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index f95ae920..aa848276 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -12,11 +12,11 @@ #include "wallet_public_structs_defs.h" #include "wallet2.h" #include "common/command_line.h" + +#define ZANO_ACCESS_TOKEN "Zano-Access-Token" + namespace tools { - - - struct i_wallet_provider { virtual void lock() {}; @@ -143,8 +143,9 @@ namespace tools MAP_JON_RPC_WE("encrypt_data", on_encrypt_data, wallet_public::COMMAND_ENCRYPT_DATA) MAP_JON_RPC_WE("decrypt_data", on_decrypt_data, wallet_public::COMMAND_DECRYPT_DATA) END_JSON_RPC_MAP() - END_URI_MAP2() + END_URI_MAP2() + bool auth_http_request(const epee::net_utils::http::http_request_info& query_info, epee::net_utils::http::http_response_info& response, connection_context& m_conn_context); //json_rpc bool on_getbalance(const wallet_public::COMMAND_RPC_GET_BALANCE::request& req, wallet_public::COMMAND_RPC_GET_BALANCE::response& res, epee::json_rpc::error& er, connection_context& cntx); bool on_getaddress(const wallet_public::COMMAND_RPC_GET_ADDRESS::request& req, wallet_public::COMMAND_RPC_GET_ADDRESS::response& res, epee::json_rpc::error& er, connection_context& cntx); @@ -212,6 +213,8 @@ namespace tools bool m_do_mint; bool m_deaf; uint64_t m_last_wallet_store_height; + std::string m_jwt_secrete; + }; } // namespace tools diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 71b544c1..323dbbd8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -29,11 +29,11 @@ add_executable(net_load_tests_srv net_load_tests/srv.cpp) add_dependencies(coretests version) target_link_libraries(coretests rpc wallet currency_core common crypto zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto) -target_link_libraries(functional_tests rpc wallet currency_core crypto common zlibstatic ethash libminiupnpc-static ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) +target_link_libraries(functional_tests rpc wallet currency_core crypto common zlibstatic ethash libminiupnpc-static ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto) target_link_libraries(hash-tests crypto ethash) target_link_libraries(hash-target-tests crypto currency_core ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) -target_link_libraries(performance_tests rpc wallet currency_core common crypto zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) -target_link_libraries(unit_tests wallet currency_core common crypto gtest_main zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) +target_link_libraries(performance_tests rpc wallet currency_core common crypto zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto) +target_link_libraries(unit_tests wallet currency_core common crypto gtest_main zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto) target_link_libraries(net_load_tests_clt currency_core common crypto gtest_main ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) target_link_libraries(net_load_tests_srv currency_core common crypto gtest_main ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) diff --git a/tests/performance_tests/main.cpp b/tests/performance_tests/main.cpp index acd1f406..36e60807 100644 --- a/tests/performance_tests/main.cpp +++ b/tests/performance_tests/main.cpp @@ -26,9 +26,35 @@ #include "threads_pool_tests.h" #include "wallet/plain_wallet_api.h" #include "wallet/view_iface.h" +#include + void test_plain_wallet() { + + + std::string token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCIsInNhbXBsZSI6InRlc3QifQ.lQm3N2bVlqt2-1L-FsOjtR6uE-L4E9zJutMWKIe1v1M"; + auto decoded_token = jwt::decode(token); + + auto verifier = jwt::verify() + .with_issuer("auth0") + .with_claim("sample", jwt::claim(std::string("test"))) + .allow_algorithm(jwt::algorithm::hs256 { "secret" }); + + verifier.verify(decoded_token); + + auto token = jwt::create() + .set_type("JWS") + .set_issuer("auth0") + .set_payload_claim("sample", jwt::claim(std::string("test"))) + .sign(jwt::algorithm::hs256 { "secret" }); + + + return; + + + + std::string res = plain_wallet::init("195.201.107.230", "33336", "E:\\tmp\\", 0); uint64_t instance_id = 0; diff --git a/tests/performance_tests/single_tx_test_base.h b/tests/performance_tests/single_tx_test_base.h index 9bda3809..13c4d0ae 100644 --- a/tests/performance_tests/single_tx_test_base.h +++ b/tests/performance_tests/single_tx_test_base.h @@ -18,7 +18,8 @@ public: m_bob.generate(); uint64_t block_reward_without_fee = 0; - if (!construct_miner_tx(0, 0, 0, 2, 0, m_bob.get_keys().account_address, m_bob.get_keys().account_address, m_tx, block_reward_without_fee, TRANSACTION_VERSION_PRE_HF4, blobdata(), CURRENCY_MINER_TX_MAX_OUTS)) + uint64_t block_reward = 0; + if(!construct_miner_tx(0, 0, 0, 2, 0, m_bob.get_keys().account_address, m_bob.get_keys().account_address, m_tx, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, blobdata(), CURRENCY_MINER_TX_MAX_OUTS)) return false; m_tx_pub_key = get_tx_pub_key_from_extra(m_tx); From cf5e38e78fb90776ad59c8f7aa35e3a7ded67726 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 13 Mar 2024 18:36:53 +0100 Subject: [PATCH 002/184] implemented asset whitelisting RPC API --- src/wallet/wallet2.cpp | 13 +++- src/wallet/wallet2.h | 1 + src/wallet/wallet_public_structs_defs.h | 82 +++++++++++++++++++++++++ src/wallet/wallet_rpc_server.cpp | 38 ++++++++++++ src/wallet/wallet_rpc_server.h | 24 +++++--- 5 files changed, 150 insertions(+), 8 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index b2af9d58..87c72e83 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -3600,7 +3600,7 @@ bool wallet2::add_custom_asset_id(const crypto::public_key& asset_id, asset_desc //---------------------------------------------------------------------------------------------------- bool wallet2::delete_custom_asset_id(const crypto::public_key& asset_id) { - auto it = m_custom_assets.find(asset_id); + const auto it = m_custom_assets.find(asset_id); if (it != m_custom_assets.end()) { m_custom_assets.erase(it); @@ -3609,6 +3609,17 @@ bool wallet2::delete_custom_asset_id(const crypto::public_key& asset_id) return true; } //---------------------------------------------------------------------------------------------------- +bool wallet2::get_custom_assets(std::list& assets) const +{ + for(const auto& pr : m_custom_assets) + { + assets.push_back(currency::asset_descriptor_with_id()); + assets.back().asset_id = pr.first; + static_cast(assets.back()) = pr.second; + } + return true; +} +//---------------------------------------------------------------------------------------------------- bool wallet2::load_whitelisted_tokens() const { if(!m_use_assets_whitelisting) diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 3097a9c5..d65f5fd6 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -656,6 +656,7 @@ namespace tools bool add_custom_asset_id(const crypto::public_key& asset_id, currency::asset_descriptor_base& asset_descriptor); bool delete_custom_asset_id(const crypto::public_key& asset_id); + bool get_custom_assets(std::list& assets) const; bool load_whitelisted_tokens_if_not_loaded() const; bool load_whitelisted_tokens() const; diff --git a/src/wallet/wallet_public_structs_defs.h b/src/wallet/wallet_public_structs_defs.h index 6610bb7d..6db3db3b 100644 --- a/src/wallet/wallet_public_structs_defs.h +++ b/src/wallet/wallet_public_structs_defs.h @@ -1736,5 +1736,87 @@ namespace wallet_public return lhs.amount == rhs.amount && lhs.asset_id == rhs.asset_id; } + + + struct COMMAND_ASSETS_WHITELIST_GET + { + struct request + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + + + struct response + { + std::list assets; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(assets) + END_KV_SERIALIZE_MAP() + }; + }; + + struct COMMAND_ASSETS_WHITELIST_ADD + { + struct request + { + crypto::public_key asset_id = currency::null_pkey; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE_POD_AS_HEX_STRING(asset_id) + END_KV_SERIALIZE_MAP() + }; + + + struct response + { + std::string status; + currency::asset_descriptor_base asset_descriptor; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(status) + KV_SERIALIZE(asset_descriptor) + END_KV_SERIALIZE_MAP() + }; + }; + + struct COMMAND_ASSETS_WHITELIST_REMOVE + { + struct request + { + crypto::public_key asset_id = currency::null_pkey; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE_POD_AS_HEX_STRING(asset_id) + END_KV_SERIALIZE_MAP() + }; + + + struct response + { + std::string status; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(status) + END_KV_SERIALIZE_MAP() + }; + }; + + + + + + + + + + + + + + + + } // namespace wallet_rpc } // namespace tools diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index a602ecba..8a8c80e5 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -1018,6 +1018,44 @@ namespace tools WALLET_RPC_CATCH_TRY_ENTRY(); } //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_assets_whitelist_get(const wallet_public::COMMAND_ASSETS_WHITELIST_GET::request& req, wallet_public::COMMAND_ASSETS_WHITELIST_GET::response& res, epee::json_rpc::error& er, connection_context& cntx) + { + WALLET_RPC_BEGIN_TRY_ENTRY(); + w.get_wallet()->get_custom_assets(res.assets); + return true; + WALLET_RPC_CATCH_TRY_ENTRY(); + } + //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_assets_whitelist_add(const wallet_public::COMMAND_ASSETS_WHITELIST_ADD::request& req, wallet_public::COMMAND_ASSETS_WHITELIST_ADD::response& res, epee::json_rpc::error& er, connection_context& cntx) + { + WALLET_RPC_BEGIN_TRY_ENTRY(); + if(!w.get_wallet()->add_custom_asset_id(req.asset_id, res.asset_descriptor)) + { + res.status = API_RETURN_CODE_NOT_FOUND; + } + else + { + res.status = API_RETURN_CODE_OK; + } + return true; + WALLET_RPC_CATCH_TRY_ENTRY(); + } + //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_assets_whitelist_remove(const wallet_public::COMMAND_ASSETS_WHITELIST_REMOVE::request& req, wallet_public::COMMAND_ASSETS_WHITELIST_REMOVE::response& res, epee::json_rpc::error& er, connection_context& cntx) + { + WALLET_RPC_BEGIN_TRY_ENTRY(); + if(!w.get_wallet()->delete_custom_asset_id(req.asset_id)) + { + res.status = API_RETURN_CODE_NOT_FOUND; + } + else + { + res.status = API_RETURN_CODE_OK; + } + return true; + WALLET_RPC_CATCH_TRY_ENTRY(); + } + //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_mw_get_wallets(const wallet_public::COMMAND_MW_GET_WALLETS::request& req, wallet_public::COMMAND_MW_GET_WALLETS::response& res, epee::json_rpc::error& er, connection_context& cntx) { WALLET_RPC_BEGIN_TRY_ENTRY(); diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index f95ae920..093a7f98 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -124,15 +124,20 @@ namespace tools MAP_JON_RPC_WE("marketplace_push_update_offer", on_marketplace_push_update_offer, wallet_public::COMMAND_MARKETPLACE_PUSH_UPDATE_OFFER) MAP_JON_RPC_WE("marketplace_cancel_offer", on_marketplace_cancel_offer, wallet_public::COMMAND_MARKETPLACE_CANCEL_OFFER) //HTLC API - MAP_JON_RPC_WE("atomics_create_htlc_proposal", on_create_htlc_proposal, wallet_public::COMMAND_CREATE_HTLC_PROPOSAL) - MAP_JON_RPC_WE("atomics_get_list_of_active_htlc", on_get_list_of_active_htlc, wallet_public::COMMAND_GET_LIST_OF_ACTIVE_HTLC) - MAP_JON_RPC_WE("atomics_redeem_htlc", on_redeem_htlc, wallet_public::COMMAND_REDEEM_HTLC) - MAP_JON_RPC_WE("atomics_check_htlc_redeemed", on_check_htlc_redeemed, wallet_public::COMMAND_CHECK_HTLC_REDEEMED) + MAP_JON_RPC_WE("atomics_create_htlc_proposal", on_create_htlc_proposal, wallet_public::COMMAND_CREATE_HTLC_PROPOSAL) + MAP_JON_RPC_WE("atomics_get_list_of_active_htlc", on_get_list_of_active_htlc, wallet_public::COMMAND_GET_LIST_OF_ACTIVE_HTLC) + MAP_JON_RPC_WE("atomics_redeem_htlc", on_redeem_htlc, wallet_public::COMMAND_REDEEM_HTLC) + MAP_JON_RPC_WE("atomics_check_htlc_redeemed", on_check_htlc_redeemed, wallet_public::COMMAND_CHECK_HTLC_REDEEMED) //IONIC_SWAPS API - MAP_JON_RPC_WE("ionic_swap_generate_proposal", on_ionic_swap_generate_proposal, wallet_public::COMMAND_IONIC_SWAP_GENERATE_PROPOSAL) - MAP_JON_RPC_WE("ionic_swap_get_proposal_info", on_ionic_swap_get_proposal_info, wallet_public::COMMAND_IONIC_SWAP_GET_PROPOSAL_INFO) - MAP_JON_RPC_WE("ionic_swap_accept_proposal", on_ionic_swap_accept_proposal, wallet_public::COMMAND_IONIC_SWAP_ACCEPT_PROPOSAL) + MAP_JON_RPC_WE("ionic_swap_generate_proposal", on_ionic_swap_generate_proposal, wallet_public::COMMAND_IONIC_SWAP_GENERATE_PROPOSAL) + MAP_JON_RPC_WE("ionic_swap_get_proposal_info", on_ionic_swap_get_proposal_info, wallet_public::COMMAND_IONIC_SWAP_GET_PROPOSAL_INFO) + MAP_JON_RPC_WE("ionic_swap_accept_proposal", on_ionic_swap_accept_proposal, wallet_public::COMMAND_IONIC_SWAP_ACCEPT_PROPOSAL) + + // Assets API + MAP_JON_RPC_WE("assets_whitelist_get", on_assets_whitelist_get, wallet_public::COMMAND_ASSETS_WHITELIST_GET) + MAP_JON_RPC_WE("assets_whitelist_add", on_assets_whitelist_add, wallet_public::COMMAND_ASSETS_WHITELIST_ADD) + MAP_JON_RPC_WE("assets_whitelist_remove", on_assets_whitelist_remove, wallet_public::COMMAND_ASSETS_WHITELIST_REMOVE) //MULTIWALLET APIs MAP_JON_RPC_WE("mw_get_wallets", on_mw_get_wallets, wallet_public::COMMAND_MW_GET_WALLETS) @@ -189,6 +194,11 @@ namespace tools bool on_ionic_swap_get_proposal_info(const wallet_public::COMMAND_IONIC_SWAP_GET_PROPOSAL_INFO::request& req, wallet_public::COMMAND_IONIC_SWAP_GET_PROPOSAL_INFO::response& res, epee::json_rpc::error& er, connection_context& cntx); bool on_ionic_swap_accept_proposal(const wallet_public::COMMAND_IONIC_SWAP_ACCEPT_PROPOSAL::request& req, wallet_public::COMMAND_IONIC_SWAP_ACCEPT_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool on_assets_whitelist_get(const wallet_public::COMMAND_ASSETS_WHITELIST_GET::request& req, wallet_public::COMMAND_ASSETS_WHITELIST_GET::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool on_assets_whitelist_add(const wallet_public::COMMAND_ASSETS_WHITELIST_ADD::request& req, wallet_public::COMMAND_ASSETS_WHITELIST_ADD::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool on_assets_whitelist_remove(const wallet_public::COMMAND_ASSETS_WHITELIST_REMOVE::request& req, wallet_public::COMMAND_ASSETS_WHITELIST_REMOVE::response& res, epee::json_rpc::error& er, connection_context& cntx); + + bool on_mw_get_wallets(const wallet_public::COMMAND_MW_GET_WALLETS::request& req, wallet_public::COMMAND_MW_GET_WALLETS::response& res, epee::json_rpc::error& er, connection_context& cntx); bool on_mw_select_wallet(const wallet_public::COMMAND_MW_SELECT_WALLET::request& req, wallet_public::COMMAND_MW_SELECT_WALLET::response& res, epee::json_rpc::error& er, connection_context& cntx); From b99bdb68df892b4850478cd13ac4f0e511eae191 Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 13 Mar 2024 21:26:39 +0100 Subject: [PATCH 003/184] wallet2: minor code cleanup --- src/wallet/wallet2.cpp | 32 ++++---------------------------- src/wallet/wallet2.h | 1 - 2 files changed, 4 insertions(+), 29 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 87c72e83..b184852c 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -343,31 +343,6 @@ const currency::txout_htlc& out_get_htlc(const currency::tx_out_v& out_t) return boost::get(boost::get(out_t).target); } -uint8_t wallet2::out_get_mixin_attr(const currency::tx_out_v& out_t) -{ - if (out_t.type() == typeid(currency::tx_out_bare)) - { - if (boost::get(out_t).target.type() == typeid(currency::txout_to_key)) - { - return boost::get(boost::get(out_t).target).mix_attr; - } - else - { - THROW_WALLET_CMN_ERR_EX("Unexpected type in out_get_mixin_attr"); - } - } - else if (out_t.type() == typeid(currency::tx_out_zarcanum)) - { - return boost::get(out_t).mix_attr; - } - else - { - THROW_WALLET_CMN_ERR_EX("Unexpected type in out_get_mixin_attr"); - } - THROW_WALLET_CMN_ERR_EX("Unexpected out type im wallet: " << out_t.type().name()); - return false; -} - const crypto::public_key& wallet2::out_get_pub_key(const currency::tx_out_v& out_t, std::list& htlc_info_list) { if (out_t.type() == typeid(tx_out_bare)) @@ -723,15 +698,16 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t } } - if (is_auditable() && (out_type_to_key || out_type_zc) && - out_get_mixin_attr(out_v) != CURRENCY_TO_KEY_OUT_FORCED_NO_MIX) + uint8_t mix_attr = CURRENCY_TO_KEY_OUT_RELAXED; + [[maybe_unused]] bool mix_attr_r = get_mix_attr_from_tx_out_v(out_v, mix_attr); + if (is_auditable() && (out_type_to_key || out_type_zc) && mix_attr != CURRENCY_TO_KEY_OUT_FORCED_NO_MIX) { std::stringstream ss; ss << "output #" << o << " from tx " << ptc.tx_hash(); if (!out.is_native_coin()) ss << " asset_id: " << out.asset_id; ss << " with amount " << print_money_brief(out.amount) - << " is targeted to this auditable wallet and has INCORRECT mix_attr = " << (uint64_t)out_get_mixin_attr(out_v) << ". Output is IGNORED."; + << " is targeted to this auditable wallet and has INCORRECT mix_attr = " << (uint64_t)mix_attr << ". Output is IGNORED."; WLT_LOG_YELLOW(ss.str(), LOG_LEVEL_0); if (m_wcallback) m_wcallback->on_message(i_wallet2_callback::ms_red, ss.str()); diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index d65f5fd6..22548e39 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -843,7 +843,6 @@ private: uint64_t get_directly_spent_transfer_index_by_input_in_tracking_wallet(uint64_t amount, const std::vector & key_offsets); uint64_t get_directly_spent_transfer_index_by_input_in_tracking_wallet(const currency::txin_to_key& intk); uint64_t get_directly_spent_transfer_index_by_input_in_tracking_wallet(const currency::txin_zc_input& inzc); - uint8_t out_get_mixin_attr(const currency::tx_out_v& out_t); const crypto::public_key& out_get_pub_key(const currency::tx_out_v& out_t, std::list& htlc_info_list); bool expand_selection_with_zc_input(assets_selection_context& needed_money_map, uint64_t fake_outputs_count, std::vector& selected_indexes); From 41386a91c8e75b82c1325850eae442e9d961fbfb Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 13 Mar 2024 21:29:09 +0100 Subject: [PATCH 004/184] privacy improvement: one derivation hint per output (not per receiver as before) --- src/currency_core/currency_format_utils.cpp | 86 ++++++++++++++------- 1 file changed, 58 insertions(+), 28 deletions(-) diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 8eb17e2d..f84a45cd 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -261,6 +261,30 @@ namespace currency return diff; } //------------------------------------------------------------------ + bool add_random_derivation_hints_and_put_them_to_tx(const std::set& existing_derivation_hints, std::set& new_derivation_hints, transaction& tx) + { + if (existing_derivation_hints.size() > tx.vout.size()) + return false; + + size_t hints_to_be_added = tx.vout.size() - existing_derivation_hints.size(); + + size_t attempts_cnt = 0, attempts_max = 4096; + while(new_derivation_hints.size() < hints_to_be_added && ++attempts_cnt < attempts_max) + { + uint16_t hint = crypto::rand(); + if (existing_derivation_hints.count(hint) == 0) + new_derivation_hints.insert(hint); + } + + if (attempts_cnt == attempts_max) + return false; + + for(auto& el : new_derivation_hints) // iterating in sorted sequence + tx.extra.push_back(make_tx_derivation_hint_from_uint16(el)); + + return true; + } + //--------------------------------------------------------------- bool generate_tx_balance_proof(const transaction &tx, const crypto::hash& tx_id, const tx_generation_context& ogc, uint64_t block_reward_for_miner_tx, currency::zc_balance_proof& proof) { CHECK_AND_ASSERT_MES(tx.version > TRANSACTION_VERSION_PRE_HF4, false, "unsupported tx.version: " << tx.version); @@ -488,12 +512,12 @@ namespace currency // fill outputs tx_gen_context.resize(zc_ins_count, destinations.size()); // auxiliary data for each output uint64_t output_index = 0; - std::set deriv_cache; + std::set derivation_hints; for (auto& d : destinations) { finalized_tx result = AUTO_VAL_INIT(result); uint8_t tx_outs_attr = 0; - r = construct_tx_out(d, tx_gen_context.tx_key.sec, output_index, tx, deriv_cache, account_keys(), + r = construct_tx_out(d, tx_gen_context.tx_key.sec, output_index, tx, derivation_hints, account_keys(), tx_gen_context.asset_id_blinding_masks[output_index], tx_gen_context.amount_blinding_masks[output_index], tx_gen_context.blinded_asset_ids[output_index], tx_gen_context.amount_commitments[output_index], result, tx_outs_attr); CHECK_AND_ASSERT_MES(r, false, "construct_tx_out failed, output #" << output_index << ", amount: " << print_money_brief(d.amount)); @@ -504,6 +528,7 @@ namespace currency tx_gen_context.amount_commitments_sum += tx_gen_context.amount_commitments[output_index]; ++output_index; } + CHECK_AND_ASSERT_MES(add_random_derivation_hints_and_put_them_to_tx(std::set(), derivation_hints, tx), false, "add_random_derivation_hints_and_put_them_to_tx failed"); if (tx.attachment.size()) add_attachments_info_to_extra(tx.extra, tx.attachment); @@ -1116,14 +1141,13 @@ namespace currency return dh; } //--------------------------------------------------------------- -// bool get_uint16_from_tx_derivation_hint(const tx_derivation_hint& dh, uint16_t& hint) -// { -// tx_derivation_hint dh; -// if (dh.msg.size() != sizeof(hint)) -// return false; -// hint = *((uint16_t*)dh.msg.data()); -// return true; -// } + bool get_uint16_from_tx_derivation_hint(const tx_derivation_hint& dh, uint16_t& hint) + { + if (dh.msg.size() != sizeof(hint)) + return false; + hint = *((uint16_t*)dh.msg.data()); + return true; + } //--------------------------------------------------------------- std::string generate_origin_for_htlc(const txout_htlc& htlc, const account_keys& acc_keys) { @@ -1250,11 +1274,7 @@ namespace currency out.mix_attr = tx_outs_attr; uint16_t hint = get_derivation_hint(reinterpret_cast(derivation)); - if (deriv_cache.count(hint) == 0) - { - tx.extra.push_back(make_tx_derivation_hint_from_uint16(hint)); - deriv_cache.insert(hint); - } + deriv_cache.insert(hint); // won't be inserted if such hint already exists } tx.vout.push_back(out); @@ -1282,11 +1302,7 @@ namespace currency CHECK_AND_ASSERT_MES(r, false, "failed to derive_public_key_from_target_address"); uint16_t hint = get_derivation_hint(derivation); - if (deriv_cache.count(hint) == 0) - { - tx.extra.push_back(make_tx_derivation_hint_from_uint16(hint)); - deriv_cache.insert(hint); - } + deriv_cache.insert(hint); // won't be inserted if such hint already exists } target_keys.push_back(out_eph_public_key); } @@ -1311,11 +1327,7 @@ namespace currency htlc.pkey_refund = out_eph_public_key; //add derivation hint for refund address uint16_t hint = get_derivation_hint(derivation); - if (deriv_cache.count(hint) == 0) - { - tx.extra.push_back(make_tx_derivation_hint_from_uint16(hint)); - deriv_cache.insert(hint); - } + deriv_cache.insert(hint); // won't be inserted if such hint already exists if (htlc_dest.htlc_hash == null_hash) @@ -1905,7 +1917,22 @@ namespace currency } return n; } - + //--------------------------------------------------------------- + bool copy_all_derivation_hints_from_tx_to_container(transaction& tx, std::set& derivation_hints) + { + for(auto it = tx.extra.begin(); it != tx.extra.end(); ++it) + { + if (it->type() == typeid(tx_derivation_hint)) + { + uint16_t hint = 0; + if (!get_uint16_from_tx_derivation_hint(boost::get(*it), hint)) + return false; + if (!derivation_hints.insert(hint).second) + return false; // maybe we need to skip this? + } + } + return true; + } //--------------------------------------------------------------- bool construct_tx(const account_keys& sender_account_keys, const std::vector& sources, @@ -2575,14 +2602,15 @@ namespace currency uint64_t native_coins_output_sum = 0; size_t output_index = tx.vout.size(); // in case of append mode we need to start output indexing from the last one + 1 uint64_t range_proof_start_index = 0; - std::set deriv_cache; + std::set existing_derivation_hints, new_derivation_hints; + CHECK_AND_ASSERT_MES(copy_all_derivation_hints_from_tx_to_container(tx, existing_derivation_hints), false, "move_all_derivation_hints_from_tx_to_container failed"); for(size_t destination_index = 0; destination_index < shuffled_dsts.size(); ++destination_index, ++output_index) { tx_destination_entry& dst_entr = shuffled_dsts[destination_index]; if (!(flags & TX_FLAG_SIGNATURE_MODE_SEPARATE) && all_inputs_are_obviously_native_coins && gen_context.ao_asset_id == currency::null_pkey) dst_entr.flags |= tx_destination_entry_flags::tdef_explicit_native_asset_id; // all inputs are obviously native coins -- all outputs must have explicit asset ids (unless there's an asset emission) - r = construct_tx_out(dst_entr, gen_context.tx_key.sec, output_index, tx, deriv_cache, sender_account_keys, + r = construct_tx_out(dst_entr, gen_context.tx_key.sec, output_index, tx, new_derivation_hints, sender_account_keys, gen_context.asset_id_blinding_masks[output_index], gen_context.amount_blinding_masks[output_index], gen_context.blinded_asset_ids[output_index], gen_context.amount_commitments[output_index], result, tx_outs_attr); CHECK_AND_ASSERT_MES(r, false, "Failed to construct tx out"); @@ -2595,6 +2623,8 @@ namespace currency native_coins_output_sum += dst_entr.amount; } + CHECK_AND_ASSERT_MES(add_random_derivation_hints_and_put_them_to_tx(existing_derivation_hints, new_derivation_hints, tx), false, "add_random_derivation_hints_and_put_them_to_tx failed"); + //process offers and put there offers derived keys uint64_t att_count = 0; for (auto& o : tx.attachment) From c5a55f1e85b60f3aecce8ff07bb4cbf46dd43d64 Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 13 Mar 2024 21:30:43 +0100 Subject: [PATCH 005/184] coretests: hard_fork_4_consolidated_txs test finished, now it also checks derivation hints for normal and consolidated txs before and after HF4 --- tests/core_tests/chaingen_main.cpp | 2 +- tests/core_tests/hard_fork_4.cpp | 42 +++++++++++++++++++++--------- tests/core_tests/hard_fork_4.h | 1 + 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index 31d317f7..3c152878 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -1244,7 +1244,7 @@ int main(int argc, char* argv[]) GENERATE_AND_PLAY(hard_fork_2_incorrect_alias_update); // HF4 - // GENERATE_AND_PLAY_HF(hard_fork_4_consolidated_txs, "4"); TODO, doesn't work atm -- sowle + GENERATE_AND_PLAY_HF(hard_fork_4_consolidated_txs, "3-*"); // atomics GENERATE_AND_PLAY(atomic_simple_test); diff --git a/tests/core_tests/hard_fork_4.cpp b/tests/core_tests/hard_fork_4.cpp index 2c4a7fd3..8652a846 100644 --- a/tests/core_tests/hard_fork_4.cpp +++ b/tests/core_tests/hard_fork_4.cpp @@ -89,6 +89,10 @@ bool hard_fork_4_consolidated_txs::generate(std::vector& event ADD_CUSTOM_EVENT(events, tx_0b); MAKE_NEXT_BLOCK_TX_LIST(events, blk_1, blk_0r, miner_acc, std::list({tx_0a, tx_0b})); + size_t dhc = count_type_in_variant_container(tx_0b.extra); + CHECK_AND_ASSERT_MES(dhc == tx_0b.vout.size(), false, "unexpected derivation hints count: " << dhc); + + REWIND_BLOCKS_N_WITH_TIME(events, blk_1r, blk_1, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); // check Alice's balance @@ -100,7 +104,7 @@ bool hard_fork_4_consolidated_txs::generate(std::vector& event CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt.get(), "alice", alice_amount, 0, alice_amount, 0, 0), false, ""); uint64_t miner_amount = MK_TEST_COINS(60); - uint64_t bob_amount = miner_amount + alice_amount - TX_DEFAULT_FEE; + m_bob_amount = miner_amount + alice_amount - TX_DEFAULT_FEE; // Consolidated tx (TX_FLAG_SIGNATURE_MODE_SEPARATE). @@ -119,17 +123,29 @@ bool hard_fork_4_consolidated_txs::generate(std::vector& event std::vector destinations; if (miner_change != 0) destinations.push_back(tx_destination_entry(miner_change, miner_acc.get_public_address())); - destinations.push_back(tx_destination_entry(bob_amount, bob_acc.get_public_address())); + destinations.push_back(tx_destination_entry(m_bob_amount, bob_acc.get_public_address())); add_flags_to_all_destination_entries(tx_destination_entry_flags::tdef_explicit_native_asset_id, destinations); r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_extra, empty_attachment, tx_1, get_tx_version_from_events(events), one_time_secret_key, 0, 0, 0, true, TX_FLAG_SIGNATURE_MODE_SEPARATE, TX_DEFAULT_FEE, gen_context); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); + dhc = count_type_in_variant_container(tx_1.extra); + CHECK_AND_ASSERT_MES(dhc == destinations.size(), false, "unexpected derivation hints count: " << dhc); + // partially completed tx_1 shouldn't be accepted - //DO_CALLBACK(events, "mark_invalid_tx"); - ADD_CUSTOM_EVENT(events, tx_1); - MAKE_NEXT_BLOCK_TX1(events, blk_2a, blk_1r, miner_acc, tx_1); + if (m_post_hf4_zarcanum) + { + ADD_CUSTOM_EVENT(events, tx_1); + DO_CALLBACK(events, "mark_invalid_block"); + MAKE_NEXT_BLOCK_TX1(events, blk_2a, blk_1r, miner_acc, tx_1); + } + else + { + DO_CALLBACK(events, "mark_invalid_tx"); + ADD_CUSTOM_EVENT(events, tx_1); + } + DO_CALLBACK(events, "clear_tx_pool"); } @@ -147,23 +163,25 @@ bool hard_fork_4_consolidated_txs::generate(std::vector& event 0, 0, 0, true, TX_FLAG_SIGNATURE_MODE_SEPARATE, 0 /* note zero fee here */, gen_context); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); + size_t dhc_2 = count_type_in_variant_container(tx_1.extra); + CHECK_AND_ASSERT_MES(dhc_2 == dhc, false, "unexpected derivation hints count: " << dhc_2); + ADD_CUSTOM_EVENT(events, tx_1); } MAKE_NEXT_BLOCK_TX1(events, blk_2, blk_1r, miner_acc, tx_1); - //std::shared_ptr bob_wlt; - //r = generator.init_test_wallet(bob_acc, get_block_hash(blk_0), bob_wlt); - //CHECK_AND_ASSERT_MES(r, false, "init_test_wallet failed"); - //r = generator.refresh_test_wallet(events, bob_wlt.get(), get_block_hash(blk_2), 2 * CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 2); - //CHECK_AND_ASSERT_MES(r, false, "refresh_test_wallet failed"); - //CHECK_AND_ASSERT_MES(check_balance_via_wallet(*bob_wlt.get(), "Bob", bob_amount, 0, 0, 0, 0), false, ""); - + DO_CALLBACK(events, "c1"); return true; } bool hard_fork_4_consolidated_txs::c1(currency::core& c, size_t ev_index, const std::vector& events) { + std::shared_ptr bob_wlt = init_playtime_test_wallet(events, c, BOB_ACC_IDX); + bob_wlt->refresh(); + + CHECK_AND_ASSERT_MES(check_balance_via_wallet(*bob_wlt.get(), "Bob", m_bob_amount, 0, 0, 0, 0), false, ""); + return true; } diff --git a/tests/core_tests/hard_fork_4.h b/tests/core_tests/hard_fork_4.h index bf12419f..f8235675 100644 --- a/tests/core_tests/hard_fork_4.h +++ b/tests/core_tests/hard_fork_4.h @@ -13,6 +13,7 @@ struct hard_fork_4_consolidated_txs : public wallet_test bool c1(currency::core& c, size_t ev_index, const std::vector& events); mutable bool m_post_hf4_zarcanum = false; + mutable uint64_t m_bob_amount = 0; }; From d04abe0e48bf4f0ff130df0257f44b14d7bdfae6 Mon Sep 17 00:00:00 2001 From: sowle Date: Thu, 14 Mar 2024 18:28:47 +0100 Subject: [PATCH 006/184] fixed derivation hints for pre-HF4 consolidation txs --- src/currency_core/currency_format_utils.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index f84a45cd..46d0e849 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -261,10 +261,14 @@ namespace currency return diff; } //------------------------------------------------------------------ - bool add_random_derivation_hints_and_put_them_to_tx(const std::set& existing_derivation_hints, std::set& new_derivation_hints, transaction& tx) + bool add_random_derivation_hints_and_put_them_to_tx(uint8_t tx_flags, const std::set& existing_derivation_hints, std::set& new_derivation_hints, transaction& tx) { if (existing_derivation_hints.size() > tx.vout.size()) + { + if (tx.version < TRANSACTION_VERSION_POST_HF4 && (tx_flags & TX_FLAG_SIGNATURE_MODE_SEPARATE)) // for pre-HF4 consolidated txs just skip if all hints are already added + return true; return false; + } size_t hints_to_be_added = tx.vout.size() - existing_derivation_hints.size(); @@ -528,7 +532,7 @@ namespace currency tx_gen_context.amount_commitments_sum += tx_gen_context.amount_commitments[output_index]; ++output_index; } - CHECK_AND_ASSERT_MES(add_random_derivation_hints_and_put_them_to_tx(std::set(), derivation_hints, tx), false, "add_random_derivation_hints_and_put_them_to_tx failed"); + CHECK_AND_ASSERT_MES(add_random_derivation_hints_and_put_them_to_tx(0, std::set(), derivation_hints, tx), false, "add_random_derivation_hints_and_put_them_to_tx failed"); if (tx.attachment.size()) add_attachments_info_to_extra(tx.extra, tx.attachment); @@ -2623,7 +2627,7 @@ namespace currency native_coins_output_sum += dst_entr.amount; } - CHECK_AND_ASSERT_MES(add_random_derivation_hints_and_put_them_to_tx(existing_derivation_hints, new_derivation_hints, tx), false, "add_random_derivation_hints_and_put_them_to_tx failed"); + CHECK_AND_ASSERT_MES(add_random_derivation_hints_and_put_them_to_tx(flags, existing_derivation_hints, new_derivation_hints, tx), false, "add_random_derivation_hints_and_put_them_to_tx failed"); //process offers and put there offers derived keys uint64_t att_count = 0; From a8bfdc13ed8d9f1ae58cf6a3bf3f4c7cf1df3597 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Thu, 14 Mar 2024 20:38:49 +0300 Subject: [PATCH 007/184] === build number: 273 -> 274 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index 5094f5be..04891ccc 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 273 +#define PROJECT_VERSION_BUILD_NO 274 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From 7e676e74e91756e7d18149f06ad553f6340e4cbe Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 14 Mar 2024 21:55:22 +0100 Subject: [PATCH 008/184] implemented JWT support in simplewallet --- .gitmodules | 5 +- CMakeLists.txt | 4 +- contrib/CMakeLists.txt | 2 + contrib/epee/include/misc_language.h | 25 +++++++++ contrib/jwt-cpp | 1 + src/currency_core/currency_config.h | 5 -- src/simplewallet/simplewallet.cpp | 20 ++++--- src/wallet/wallet2.cpp | 53 ++++++++++++++++++ src/wallet/wallet2.h | 8 ++- src/wallet/wallet_rpc_server.cpp | 83 ++++++++++++++++++++++++---- src/wallet/wallet_rpc_server.h | 6 +- tests/performance_tests/main.cpp | 26 ++++++++- 12 files changed, 205 insertions(+), 33 deletions(-) create mode 160000 contrib/jwt-cpp diff --git a/.gitmodules b/.gitmodules index 191af28d..97a855bd 100644 --- a/.gitmodules +++ b/.gitmodules @@ -8,4 +8,7 @@ [submodule "contrib/tor-connect"] path = contrib/tor-connect url = https://github.com/hyle-team/tor-connect.git - branch = main \ No newline at end of file + branch = main +[submodule "contrib/jwt-cpp"] + path = contrib/jwt-cpp + url = https://github.com/Thalhammer/jwt-cpp.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 31c80a7a..9baf00a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,7 +58,7 @@ else() endif() endif() message("Generated with config types: ${CMAKE_CONFIGURATION_TYPES}, and built type: ${CMAKE_BUILD_TYPE}") - + enable_testing() set(OPENSSL_USE_STATIC_LIBS TRUE) # link statically @@ -74,7 +74,7 @@ set(DISABLE_TOR FALSE CACHE BOOL "Disable TOR library(and related tor-connect su set(TESTNET FALSE CACHE BOOL "Compile for testnet") set(BUILD_GUI FALSE CACHE BOOL "Build qt-daemon") -include_directories(src contrib/eos_portable_archive contrib contrib/epee/include ${OPENSSL_INCLUDE_DIR} "${CMAKE_BINARY_DIR}/version" "${CMAKE_BINARY_DIR}/contrib/zlib") +include_directories(src contrib/eos_portable_archive contrib contrib/epee/include contrib/jwt-cpp/include ${OPENSSL_INCLUDE_DIR} "${CMAKE_BINARY_DIR}/version" "${CMAKE_BINARY_DIR}/contrib/zlib") add_definitions(-DSTATICLIB) diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt index a3220829..abfc4885 100644 --- a/contrib/CMakeLists.txt +++ b/contrib/CMakeLists.txt @@ -14,9 +14,11 @@ if(CMAKE_SYSTEM_NAME STREQUAL "iOS" OR CMAKE_SYSTEM_NAME STREQUAL "Android") message("excluded upnp support for IOS build") return() endif() + add_subdirectory(miniupnp/miniupnpc) + set_property(TARGET libminiupnpc-static PROPERTY FOLDER "contrib") set_property(TARGET zlibstatic PROPERTY FOLDER "contrib") set_property(TARGET mdbx PROPERTY FOLDER "contrib") diff --git a/contrib/epee/include/misc_language.h b/contrib/epee/include/misc_language.h index 5855d977..6e2e09f2 100644 --- a/contrib/epee/include/misc_language.h +++ b/contrib/epee/include/misc_language.h @@ -532,6 +532,31 @@ namespace misc_utils }; + template + struct expirating_set + { + typedef std::set main_set; + main_set m_set; + std::multimap m_expirations; + + const main_set& get_set() + { + return m_set; + } + void add(const key& k, const expiration_type& e) + { + auto res = m_set.insert(k); + m_expirations.insert({ e, res.first }); + } + + void remove_if_expiration_less_than(const expiration_type& e) + { + while(m_expirations.size() && m_expirations.begin()->first < e) + { + m_expirations.erase(m_expirations.begin()); + } + } + }; } // namespace misc_utils diff --git a/contrib/jwt-cpp b/contrib/jwt-cpp new file mode 160000 index 00000000..364a5572 --- /dev/null +++ b/contrib/jwt-cpp @@ -0,0 +1 @@ +Subproject commit 364a5572f4b46bb9f4304cb1c92acec8ddb2c620 diff --git a/src/currency_core/currency_config.h b/src/currency_core/currency_config.h index 50ca76a8..aee33609 100644 --- a/src/currency_core/currency_config.h +++ b/src/currency_core/currency_config.h @@ -249,13 +249,8 @@ #define BC_OFFERS_CURRENT_OFFERS_SERVICE_ARCHIVE_VER CURRENCY_FORMATION_VERSION + BLOCKCHAIN_STORAGE_MAJOR_COMPATIBILITY_VERSION + 9 #define BC_OFFERS_CURRENCY_MARKET_FILENAME "market.bin" -#ifndef TESTNET #define WALLET_FILE_SERIALIZATION_VERSION 163 #define WALLET_FILE_LAST_SUPPORTED_VERSION 163 -#else -#define WALLET_FILE_LAST_SUPPORTED_VERSION (CURRENCY_FORMATION_VERSION+76) -#define WALLET_FILE_SERIALIZATION_VERSION (CURRENCY_FORMATION_VERSION+76) -#endif #define CURRENT_MEMPOOL_ARCHIVE_VER (CURRENCY_FORMATION_VERSION+31) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 1a1f1e8e..681d356f 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -287,7 +287,7 @@ simple_wallet::simple_wallet() m_cmd_binder.set_handler("start_mining", boost::bind(&simple_wallet::start_mining, this, ph::_1), "start_mining - Start mining in daemon"); m_cmd_binder.set_handler("stop_mining", boost::bind(&simple_wallet::stop_mining, this, ph::_1), "Stop mining in daemon"); m_cmd_binder.set_handler("refresh", boost::bind(&simple_wallet::refresh, this, ph::_1), "Resynchronize transactions and balance"); - m_cmd_binder.set_handler("balance", boost::bind(&simple_wallet::show_balance, this, ph::_1), "Show current wallet balance"); + m_cmd_binder.set_handler("balance", boost::bind(&simple_wallet::show_balance, this, ph::_1), "[force_all] Show current wallet balance, with 'force_all' param it displays all assets without filtering against whitelists"); m_cmd_binder.set_handler("show_staking_history", boost::bind(&simple_wallet::show_staking_history, this, ph::_1), "show_staking_history [2] - Show staking transfers, if option provided - number of days for history to display"); m_cmd_binder.set_handler("incoming_transfers", boost::bind(&simple_wallet::show_incoming_transfers, this, ph::_1), "incoming_transfers [available|unavailable] - Show incoming transfers - all of them or filter them by availability"); m_cmd_binder.set_handler("incoming_counts", boost::bind(&simple_wallet::show_incoming_transfers_counts, this, ph::_1), "incoming_transfers counts"); @@ -539,8 +539,7 @@ void simple_wallet::handle_command_line(const boost::program_options::variables_ m_restore_wallet = command_line::get_arg(vm, arg_restore_wallet); m_disable_tor = command_line::get_arg(vm, arg_disable_tor_relay); m_voting_config_file = command_line::get_arg(vm, arg_voting_config_file); - m_no_password_confirmations = command_line::get_arg(vm, arg_no_password_confirmations); - + m_no_password_confirmations = command_line::get_arg(vm, arg_no_password_confirmations); } //---------------------------------------------------------------------------------------------------- @@ -998,9 +997,16 @@ bool simple_wallet::refresh(const std::vector& args) return true; } //---------------------------------------------------------------------------------------------------- -bool simple_wallet::show_balance(const std::vector& args/* = std::vector()*/) +bool simple_wallet::show_balance(const std::vector& args /* = std::vector()*/) { - success_msg_writer() << m_wallet->get_balance_str(); + if (args.size() == 1 && args[0] == "raw") + { + success_msg_writer() << m_wallet->get_balance_str_raw(); + } + else + { + success_msg_writer() << m_wallet->get_balance_str(); + } return true; } //---------------------------------------------------------------------------------------------------- @@ -2675,9 +2681,7 @@ int main(int argc, char* argv[]) command_line::add_arg(desc_params, arg_set_timeout); command_line::add_arg(desc_params, arg_voting_config_file); command_line::add_arg(desc_params, arg_no_password_confirmations); - - - + tools::wallet_rpc_server::init_options(desc_params); diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 87c72e83..07fab031 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -3752,6 +3752,59 @@ std::string wallet2::get_balance_str() const return ss.str(); } //---------------------------------------------------------------------------------------------------- +std::string wallet2::get_balance_str_raw() const +{ + // balance unlocked / [balance total] ticker asset id + // 1391306.970000000000 / 1391306.970000000000 ZANO d6329b5b1f7c0805b5c345f4957554002a2f557845f64d7645dae0e051a6498a + // 1391306.97 ZANO d6329b5b1f7c0805b5c345f4957554002a2f557845f64d7645dae0e051a6498a + // 106.971 / 206.4 ZANO d6329b5b1f7c0805b5c345f4957554002a2f557845f64d7645dae0e051a6498a + + static const char* header = " balance unlocked / [balance total] asset id"; + std::stringstream ss; + ss << header << ENDL; + + uint64_t dummy = 0; + std::unordered_map balances_map; + this->balance(balances_map, dummy); + + for(const auto& entry : balances_map) + { + ss << " " << std::left << std::setw(20) << print_fixed_decimal_point_with_trailing_spaces(entry.second.unlocked, 12); + if(entry.second.total == entry.second.unlocked) + ss << " "; + else + ss << " / " << std::setw(20) << print_fixed_decimal_point_with_trailing_spaces(entry.second.total, 12); + ss << " " << std::setw(8) << std::left << entry.first << ENDL; + } + + //print whitelist + ss << "WHITELIST: " << ENDL; + + + for(const auto& entry : m_whitelisted_assets) + { + ss << " " << std::left << entry.first << " " << entry.second.ticker << ENDL; + } + + // print whitelist + ss << "CUSTOM LIST: " << ENDL; + + + for(const auto& entry : m_custom_assets) + { + ss << " " << std::left << entry.first << " " << entry.second.ticker << ENDL; + } + + ss << "OWN DESCRIPTORS LIST: " << ENDL; + + for(const auto& entry : m_own_asset_descriptors) + { + ss << " " << std::left << entry.first << " " << entry.second.asset_descriptor.ticker << ENDL; + } + + return ss.str(); +} +//---------------------------------------------------------------------------------------------------- void wallet2::get_payments(const std::string& payment_id, std::list& payments, uint64_t min_height) const { auto range = m_payments.equal_range(payment_id); diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index d65f5fd6..f26f88d8 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -154,7 +154,9 @@ namespace tools std::atomic m_last_sync_percent = 0; mutable uint64_t m_current_wallet_file_size = 0; bool m_use_assets_whitelisting = true; - + + // variables that should be part of state data object but should not be stored during serialization + mutable std::atomic m_whitelist_updated = false; //=============================================================== template @@ -218,7 +220,7 @@ namespace tools a & m_rollback_events; a & m_whitelisted_assets; a & m_use_assets_whitelisting; - } + } }; @@ -536,6 +538,7 @@ namespace tools void get_transfers(transfer_container& incoming_transfers) const; std::string get_transfers_str(bool include_spent = true, bool include_unspent = true, bool show_only_unknown = false, const std::string& filter_asset_ticker = std::string{}) const; std::string get_balance_str() const; + std::string get_balance_str_raw() const; // Returns all payments by given id in unspecified order void get_payments(const std::string& payment_id, std::list& payments, uint64_t min_height = 0) const; @@ -886,7 +889,6 @@ private: uint64_t m_upper_transaction_size_limit; //TODO: auto-calc this value or request from daemon, now use some fixed value std::atomic m_stop; - mutable std::atomic m_whitelist_updated = false; std::shared_ptr m_core_proxy; std::shared_ptr m_wcallback; diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index a9f87356..166dd787 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -17,7 +17,16 @@ using namespace epee; #include "wallet_rpc_server_error_codes.h" #include "wallet_helpers.h" #include "wrap_service.h" -#include +#include "jwt-cpp/jwt.h" +#include "crypto/bitcoin/sha256_helper.h" + +#define JWT_TOKEN_EXPIRATION_MAXIMUM (60 * 60) +#define JWT_TOKEN_CLAIM_NAME_BODY_HASH "body_hash" +#define JWT_TOKEN_CLAIM_NAME_SALT "salt" +#define JWT_TOKEN_CLAIM_NAME_EXPIRATION "exp" +#define JWT_TOKEN_OVERWHELM_LIMIT 100000 // if there are more records in m_jwt_used_salts then we consider it as an attack + + #define GET_WALLET() wallet_rpc_locker w(m_pwallet_provider); @@ -61,6 +70,7 @@ namespace tools const command_line::arg_descriptor wallet_rpc_server::arg_rpc_bind_ip ("rpc-bind-ip", "Specify ip to bind rpc server", "127.0.0.1"); const command_line::arg_descriptor wallet_rpc_server::arg_miner_text_info ( "miner-text-info", "Wallet password"); const command_line::arg_descriptor wallet_rpc_server::arg_deaf_mode ( "deaf", "Put wallet into 'deaf' mode make it ignore any rpc commands(usable for safe PoS mining)"); + const command_line::arg_descriptor wallet_rpc_server::arg_jwt_secret("jwt-secret", "Enables JWT auth over secret string provided"); void wallet_rpc_server::init_options(boost::program_options::options_description& desc) { @@ -68,6 +78,7 @@ namespace tools command_line::add_arg(desc, arg_rpc_bind_port); command_line::add_arg(desc, arg_miner_text_info); command_line::add_arg(desc, arg_deaf_mode); + command_line::add_arg(desc, arg_jwt_secret); } //------------------------------------------------------------------------------------------------------------------------------ wallet_rpc_server::wallet_rpc_server(std::shared_ptr wptr): @@ -185,8 +196,12 @@ namespace tools m_net_server.set_threads_prefix("RPC"); bool r = handle_command_line(vm); CHECK_AND_ASSERT_MES(r, false, "Failed to process command line in core_rpc_server"); - m_jwt_secrete = "secretesecrete"; + + if(command_line::has_arg(vm, arg_jwt_secret)) + { + m_jwt_secret = command_line::get_arg(vm, arg_jwt_secret); + } return epee::http_server_impl_base::init(m_port, m_bind_ip); } //------------------------------------------------------------------------------------------------------------------------------ @@ -197,22 +212,65 @@ namespace tools { return element.first == ZANO_ACCESS_TOKEN; }); if(it == query_info.m_header_info.m_etc_fields.end()) return false; - std::string token = it->second; //"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCIsInNhbXBsZSI6InRlc3QifQ.lQm3N2bVlqt2-1L-FsOjtR6uE-L4E9zJutMWKIe1v1M"; - auto decoded_token = jwt::decode(token); + + try + { + if(m_jwt_used_salts.get_set().size() > JWT_TOKEN_OVERWHELM_LIMIT) + { + throw std::runtime_error("Salt is overwhelmed"); + } + + auto decoded = jwt::decode(it->second, [](const std::string& str) + { return jwt::base::decode(jwt::base::pad(str)); }); + + + auto verifier = jwt::verify().allow_algorithm(jwt::algorithm::hs256 { m_jwt_secret }); + + verifier.verify(decoded); + std::string body_hash = decoded.get_payload_claim(JWT_TOKEN_CLAIM_NAME_BODY_HASH).as_string(); + std::string salt = decoded.get_payload_claim(JWT_TOKEN_CLAIM_NAME_SALT).as_string(); + crypto::hash jwt_claim_sha256 = currency::null_hash; + epee::string_tools::hex_to_pod(body_hash, jwt_claim_sha256); + crypto::hash sha256 = crypto::sha256_hash(query_info.m_body.data(), query_info.m_body.size()); + if (sha256 != jwt_claim_sha256) + { + throw std::runtime_error("Body hash missmatch"); + } + if(m_jwt_used_salts.get_set().find(salt) != m_jwt_used_salts.get_set().end()) + { + throw std::runtime_error("Salt reused"); + } + + uint64_t ticks_now = epee::misc_utils::get_tick_count(); + m_jwt_used_salts.add(salt, ticks_now + JWT_TOKEN_EXPIRATION_MAXIMUM); + m_jwt_used_salts.remove_if_expiration_less_than(ticks_now); + + + //TODO: check for salt unique + + // std::cout << "Token is valid. Claims:" << std::endl; + //for(auto& e : decoded.get_payload_json()) + //{ + // std::cout << e.first << " = " << e.second << std::endl; + //} + + LOG_PRINT_L0("JWT token OK"); + return true; + } + catch(const std::exception& e) + { + LOG_ERROR("Invalid JWT token: " << e.what()); + return false; + } - auto verifier = jwt::verify() - .with_issuer("auth0") - .with_claim("sample", jwt::claim(std::string("test"))) - .allow_algorithm(jwt::algorithm::hs256 { m_jwt_secrete }); - verifier.verify(decoded_token); return false; } //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::handle_http_request(const epee::net_utils::http::http_request_info& query_info, epee::net_utils::http::http_response_info& response, connection_context& m_conn_context) { - if (m_jwt_secrete.size()) + if (m_jwt_secret.size()) { if (!auth_http_request(query_info, response, m_conn_context)) { @@ -247,6 +305,11 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ + void wallet_rpc_server::set_jwt_secret(const std::string& jwt) + { + m_jwt_secret = jwt; + } + //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_getbalance(const wallet_public::COMMAND_RPC_GET_BALANCE::request& req, wallet_public::COMMAND_RPC_GET_BALANCE::response& res, epee::json_rpc::error& er, connection_context& cntx) { WALLET_RPC_BEGIN_TRY_ENTRY(); diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index 14da11a4..fc0e60be 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -82,12 +82,14 @@ namespace tools const static command_line::arg_descriptor arg_rpc_bind_ip; const static command_line::arg_descriptor arg_miner_text_info; const static command_line::arg_descriptor arg_deaf_mode; + const static command_line::arg_descriptor arg_jwt_secret; static void init_options(boost::program_options::options_description& desc); bool init(const boost::program_options::variables_map& vm); bool run(bool do_mint, bool offline_mode, const currency::account_public_address& miner_address); bool handle_http_request(const epee::net_utils::http::http_request_info& query_info, epee::net_utils::http::http_response_info& response, connection_context& m_conn_context); + void set_jwt_secret(const std::string& jwt); BEGIN_URI_MAP2_VIRTUAL() BEGIN_JSON_RPC_MAP("/json_rpc") @@ -223,8 +225,8 @@ namespace tools bool m_do_mint; bool m_deaf; uint64_t m_last_wallet_store_height; - std::string m_jwt_secrete; - + std::string m_jwt_secret; + epee::misc_utils::expirating_set m_jwt_used_salts; }; } // namespace tools diff --git a/tests/performance_tests/main.cpp b/tests/performance_tests/main.cpp index 36e60807..ed6d991e 100644 --- a/tests/performance_tests/main.cpp +++ b/tests/performance_tests/main.cpp @@ -33,9 +33,31 @@ void test_plain_wallet() { - std::string token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCIsInNhbXBsZSI6InRlc3QifQ.lQm3N2bVlqt2-1L-FsOjtR6uE-L4E9zJutMWKIe1v1M"; + std::string token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiemFub19leHRlbnNpb24iLCJzYWx0IjoiYTUyMTk5MzQyNmYxN2Y2MDQyMzkzYTI4YzJhMzk1NjFiYTgxYmVkZDkxODJlY2E5NTY3ZDBlNjQ3YjIwZTE2NSIsImV4cCI6MTcxMDM2MzA1MH0.CwqvPBtgE8ZUFZ4cYy1ZJLWdYCnhfEiCzEhqDYCK4CQ"; auto decoded_token = jwt::decode(token); + std::string sharedSecret = "DFDvfedceEDCECECecedcyhtyh"; + + try + { + auto decoded = jwt::decode(token); + + auto verifier = jwt::verify() + .allow_algorithm(jwt::algorithm::hs256 { sharedSecret }); + + verifier.verify(decoded); + + std::cout << "Token is valid. Claims:" << std::endl; + for(auto& e : decoded.get_payload_json()) + std::cout << e.first << " = " << e.second << std::endl; + } + catch(const std::exception& e) + { + std::cerr << "Invalid token: " << e.what() << std::endl; + } + + + /* auto verifier = jwt::verify() .with_issuer("auth0") .with_claim("sample", jwt::claim(std::string("test"))) @@ -49,7 +71,7 @@ void test_plain_wallet() .set_payload_claim("sample", jwt::claim(std::string("test"))) .sign(jwt::algorithm::hs256 { "secret" }); - +*/ return; From ddbc8e2484165abd2a065dcc9594ee65a596b008 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 14 Mar 2024 22:04:36 +0100 Subject: [PATCH 009/184] removed comment --- src/wallet/wallet_rpc_server.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 166dd787..605ffed5 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -245,15 +245,6 @@ namespace tools m_jwt_used_salts.add(salt, ticks_now + JWT_TOKEN_EXPIRATION_MAXIMUM); m_jwt_used_salts.remove_if_expiration_less_than(ticks_now); - - //TODO: check for salt unique - - // std::cout << "Token is valid. Claims:" << std::endl; - //for(auto& e : decoded.get_payload_json()) - //{ - // std::cout << e.first << " = " << e.second << std::endl; - //} - LOG_PRINT_L0("JWT token OK"); return true; } From f538fc3a7612e7ce86556a1cd2602400f6b4e9aa Mon Sep 17 00:00:00 2001 From: sowle Date: Thu, 14 Mar 2024 22:04:38 +0100 Subject: [PATCH 010/184] coretests: gen_crypted_attachments and fixed-hash tests --- tests/core_tests/checkpoints_tests.cpp | 2 +- tests/core_tests/multisig_wallet_tests.cpp | 2 +- tests/core_tests/tx_validation.cpp | 20 +++++++++++++++++++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/tests/core_tests/checkpoints_tests.cpp b/tests/core_tests/checkpoints_tests.cpp index 68565f8d..d0b88650 100644 --- a/tests/core_tests/checkpoints_tests.cpp +++ b/tests/core_tests/checkpoints_tests.cpp @@ -708,7 +708,7 @@ bool gen_no_attchments_in_coinbase::init_config_set_cp(currency::core& c, size_t // different checkpoints due to different block versions for different hardforks -> different hashes if (crc.is_hardfork_active_for_height(ZANO_HARDFORK_03, 11) && !crc.is_hardfork_active_for_height(ZANO_HARDFORK_04_ZARCANUM, 11)) { - m_checkpoints.add_checkpoint(12, "4e6055dda442e04b2feb70bc7245584742604e8515b8d2e1c3d46c26f758d59f"); + m_checkpoints.add_checkpoint(12, "70fbbd33d88ccaa26f9fe64d102bcff2572494009339de9fab7158a40633fbb5"); } else { diff --git a/tests/core_tests/multisig_wallet_tests.cpp b/tests/core_tests/multisig_wallet_tests.cpp index fd327b76..4fdbcc7f 100644 --- a/tests/core_tests/multisig_wallet_tests.cpp +++ b/tests/core_tests/multisig_wallet_tests.cpp @@ -1638,7 +1638,7 @@ multisig_and_checkpoints::multisig_and_checkpoints() bool multisig_and_checkpoints::set_cp(currency::core& c, size_t ev_index, const std::vector& events) { currency::checkpoints checkpoints; - checkpoints.add_checkpoint(15, "6f9194c144afd73077478e7f04e947c50160b5673558e6f696a4f662a3ca261e"); + checkpoints.add_checkpoint(15, "fda3e645fbfd0f4852aa68e6ad021c9005c9faf2d7ba6b1b3c8e24efb9c0e8d0"); c.set_checkpoints(std::move(checkpoints)); return true; diff --git a/tests/core_tests/tx_validation.cpp b/tests/core_tests/tx_validation.cpp index 7382060b..37acebec 100644 --- a/tests/core_tests/tx_validation.cpp +++ b/tests/core_tests/tx_validation.cpp @@ -939,7 +939,25 @@ bool gen_crypted_attachments::check_crypted_tx(currency::core& c, size_t ev_inde std::vector at; bool r = currency::decrypt_payload_items(true, *ptx_from_bc, bob_acc.get_keys(), at); CHECK_EQ(r, true); - CHECK_EQ(at.size(), 8); // custom attachments: 1) tx_payer, 2) tx_comment, 3) std::string; system attachments: 4) tx_crypto_checksum; system extra: 5) tx pub key, 6) extra_attachment_info, 7) etc_tx_flags16_t + if (at.size() != 16) + { + std::stringstream ss; + for(auto& el : at) + ss << " " << el.type().name() << ENDL; + LOG_PRINT_RED("at.size() = " << at.size() << " : " << ENDL << ss.str(), LOG_LEVEL_0); + + // expected items: + // public_key + // etc_tx_flags16_t + // tx_derivation_hint x 10 + // extra_attachment_info + // tx_payer + // tx_comment + // tx_crypto_checksum + // + // total: 16 + CHECK_AND_ASSERT_MES(false, false, "unexpected number of decrypted items"); + } currency::tx_payer decrypted_pr = AUTO_VAL_INIT(decrypted_pr); r = get_type_in_variant_container(at, decrypted_pr); From ad3b022fc1e0355a55815a27fb1a1808cca87af8 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Fri, 15 Mar 2024 18:49:50 +0300 Subject: [PATCH 011/184] === build number: 274 -> 275 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index 04891ccc..390ec57e 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 274 +#define PROJECT_VERSION_BUILD_NO 275 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From 66cf29ccd3bbe3339db70dff39f78fd089958489 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 15 Mar 2024 19:58:44 +0100 Subject: [PATCH 012/184] coretests: hard_fork_2_alias_update_using_old_tx<> fixed --- tests/core_tests/hard_fork_2.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/tests/core_tests/hard_fork_2.cpp b/tests/core_tests/hard_fork_2.cpp index b4700f0e..173bb2b9 100644 --- a/tests/core_tests/hard_fork_2.cpp +++ b/tests/core_tests/hard_fork_2.cpp @@ -1217,23 +1217,28 @@ bool hard_fork_2_alias_update_using_old_tx::c1(currency::core& c, s // // Send tx and print it's blob // this code was used to generate old-style tx in develop branch, commit 36eabb916b95c7db06bdfb5d34d9820bd94b82df + // UPD: 2024-03-15 tx blob was updated as of commit f538fc3a7612e7ce86556a1cd2602400f6b4e9aa // - transaction tx_upd = AUTO_VAL_INIT(tx_upd); - alice_wlt->request_alias_update(ai_upd, tx_upd, TESTS_DEFAULT_FEE, 0); - std::string tx_upd_hex = epee::string_tools::buff_to_hex_nodelimer(t_serializable_object_to_blob(tx_upd)); - LOG_PRINT_L0("tx upd: " << ENDL << tx_upd_hex); + { + transaction tx_upd = AUTO_VAL_INIT(tx_upd); + alice_wlt->request_alias_update(ai_upd, tx_upd, TESTS_DEFAULT_FEE, 0); + std::string tx_upd_hex = epee::string_tools::buff_to_hex_nodelimer(t_serializable_object_to_blob(tx_upd)); + LOG_PRINT_L0("tx upd: " << ENDL << tx_upd_hex); + } */ // use prepared tx blob - std::string tx_upd_hex("01010180988be49903011a0100000000000000ff593921b61d52e818058ef881764383fe9fb0cf4512da460daf477e3a216144000180d0dbc3f402037c2e68e9c60914d369dc53fcc91522dcec284e1b7c1604ccc3d8fcf67e2da0790003140a616c696365616c696365efdcf084d7af59e0d68e8bda3ff4514a02d812ccfd6a09f69811c5a6a1b035c9b1b2395fcd84283d02e2fc4f37395ac9d8f01ff3f1ad1b94a26aaf1c76bb39d00c48656c6c6f206d696e657221000118faf7b79730fd6c1ec5c918891e264e959749a0d8eebc7997b503bd185ef100fd9e0150c175e0f048ee729137ceed035e9145d7857eae9ab786dd319fe6520b16b0cc0d6a8766cd098fe5a42875243789cc3b4bf66ee0c12ff6ef2fc179d4cef50b0288360101f3012451b07e58e742c020d68e8ff6db2905fa3aad78806ba80b16f3c861ee09f79817ea1ec36b0e30c7be5412daf59bcbc34410461a0d126de4a2dd897ecf0200"); + std::string tx_upd_hex("01010180988be49903011a01000000000000007bdeaff6ac11597e9fe397349dd2ecfcd6880cda9bbedaa67f759a5b95ba2ed9000180d0dbc3f4020335db05c510daddcb82257be70789650007ad2d567092ec1eb2a38a93ef8fa0070004140a616c696365616c696365efdcf084d7af59e0d68e8bda3ff4514a02d812ccfd6a09f69811c5a6a1b035c9b1b2395fcd84283d02e2fc4f37395ac9d8f01ff3f1ad1b94a26aaf1c76bb39d00c48656c6c6f206d696e6572210001c2537b8203e9c9981b87a3c63cc0c63e4ccc14ddd0309fdcee94664e4b3bc307ee438e90bb5720b7ac7cbec38fcac9c7aa5b9df02abd2fa1a58c580f9b3eaf0516116e8d89a67440aad0922a7e5dd88870e6f0af792a7af201ee21effd90cc6c7f1700000b02f37101016ed0997a3fe0c6bc47ffde14599a77697ba95c5c1489b65e5e54854146079f06569313d921f19ed2848cdccc8bad7f75fb46fc1608912365f569b7690703010b00"); std::string tx_upd_blob; r = epee::string_tools::parse_hexstr_to_binbuff(tx_upd_hex, tx_upd_blob); CHECK_AND_ASSERT_MES(r, false, "parse_hexstr_to_binbuff failed"); - //r = t_unserializable_object_from_blob(tx_upd, tx_upd_blob); - //CHECK_AND_ASSERT_MES(r, false, "t_unserializable_object_from_blob failed"); + crypto::hash tx_upd_hash{}; + transaction tx_upd{}; + CHECK_AND_ASSERT_MES(parse_and_validate_tx_from_blob(tx_upd_blob, tx_upd, tx_upd_hash), false, "parse_tx_form_blob failed"); + //LOG_PRINT_L0("tx_upd: " << tx_upd_hash << ", json:" << ENDL << obj_to_json_str(tx_upd)); tx_verification_context tvc = AUTO_VAL_INIT(tvc); - r = c.handle_incoming_tx(tx_upd_blob, tvc, false); + r = c.handle_incoming_tx(tx_upd, tvc, false, tx_upd_hash); CHECK_AND_ASSERT_MES(r, false, "handle_incoming_tx failed"); From 7f851205a0495ae9c33c7b91562d6bd85d96dc9a Mon Sep 17 00:00:00 2001 From: sowle Date: Sat, 16 Mar 2024 14:57:25 +0100 Subject: [PATCH 013/184] tx_pool: add post-HF4 txs are now being check for balance proof. Core test hard_fork_4_consolidated_txs changed accordingly --- src/currency_core/tx_pool.cpp | 12 +++++++++++- src/currency_core/tx_pool.h | 3 ++- tests/core_tests/hard_fork_4.cpp | 24 ++++++++++++++---------- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/currency_core/tx_pool.cpp b/src/currency_core/tx_pool.cpp index 94a69124..3f133932 100644 --- a/src/currency_core/tx_pool.cpp +++ b/src/currency_core/tx_pool.cpp @@ -224,6 +224,14 @@ namespace currency } TIME_MEASURE_FINISH_PD(check_inputs_time); + TIME_MEASURE_START_PD(check_post_hf4_balance); + if (tx.version > TRANSACTION_VERSION_PRE_HF4) + { + r = check_tx_balance(tx, id); + CHECK_AND_ASSERT_MES_CUSTOM(r, false, { tvc.m_verification_failed = true; }, "post-HF4 tx: balance proof is invalid"); + } + TIME_MEASURE_FINISH_PD(check_post_hf4_balance); + do_insert_transaction(tx, id, blob_size, kept_by_block, tx_fee, ch_inp_res ? max_used_block_id : null_hash, ch_inp_res ? max_used_block_height : 0); TIME_MEASURE_FINISH_PD(tx_processing_time); @@ -240,9 +248,11 @@ namespace currency << "/" << m_performance_data.validate_alias_time.get_last_val() << "/" << m_performance_data.check_keyimages_ws_ms_time.get_last_val() << "/" << m_performance_data.check_inputs_time.get_last_val() + << "/b"<< m_performance_data.check_post_hf4_balance.get_last_val() << "/" << m_performance_data.begin_tx_time.get_last_val() << "/" << m_performance_data.update_db_time.get_last_val() - << "/" << m_performance_data.db_commit_time.get_last_val() << ")" ); + << "/" << m_performance_data.db_commit_time.get_last_val() + << ")"); return true; } diff --git a/src/currency_core/tx_pool.h b/src/currency_core/tx_pool.h index 4ede52a2..df604f59 100644 --- a/src/currency_core/tx_pool.h +++ b/src/currency_core/tx_pool.h @@ -77,7 +77,8 @@ namespace currency epee::math_helper::average check_inputs_time; epee::math_helper::average begin_tx_time; epee::math_helper::average update_db_time; - epee::math_helper::average db_commit_time; + epee::math_helper::average db_commit_time; + epee::math_helper::average check_post_hf4_balance; }; typedef std::unordered_map> key_image_cache; diff --git a/tests/core_tests/hard_fork_4.cpp b/tests/core_tests/hard_fork_4.cpp index 8652a846..e5b4d6b4 100644 --- a/tests/core_tests/hard_fork_4.cpp +++ b/tests/core_tests/hard_fork_4.cpp @@ -134,18 +134,22 @@ bool hard_fork_4_consolidated_txs::generate(std::vector& event CHECK_AND_ASSERT_MES(dhc == destinations.size(), false, "unexpected derivation hints count: " << dhc); // partially completed tx_1 shouldn't be accepted - if (m_post_hf4_zarcanum) - { - ADD_CUSTOM_EVENT(events, tx_1); - DO_CALLBACK(events, "mark_invalid_block"); - MAKE_NEXT_BLOCK_TX1(events, blk_2a, blk_1r, miner_acc, tx_1); - } - else - { + + // now we added a balance check to tx_memory_pool::add_tx() for post-HF4 txs, so the behaviour is the same -- partially completed consolidated tx won't be added to the pool -- sowle + // (subject to change in future) + + //if (m_post_hf4_zarcanum) + //{ + // ADD_CUSTOM_EVENT(events, tx_1); + // DO_CALLBACK(events, "mark_invalid_block"); + // MAKE_NEXT_BLOCK_TX1(events, blk_2a, blk_1r, miner_acc, tx_1); + // DO_CALLBACK(events, "clear_tx_pool"); + //} + //else + //{ DO_CALLBACK(events, "mark_invalid_tx"); ADD_CUSTOM_EVENT(events, tx_1); - } - DO_CALLBACK(events, "clear_tx_pool"); + //} } From 2eb76a5fc8a2413d50c1b21adc51bec67f8111e8 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Sat, 16 Mar 2024 18:16:26 +0300 Subject: [PATCH 014/184] === build number: 275 -> 276 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index 390ec57e..abd6fb50 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 275 +#define PROJECT_VERSION_BUILD_NO 276 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From 86e8446e424b96fabddf31d1e3d380d8767e4ef4 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Mon, 18 Mar 2024 23:26:39 +0100 Subject: [PATCH 015/184] Implemented JWT support in UI, multiple API improvements and fixes --- contrib/epee/include/misc_language.h | 7 +++ contrib/epee/include/net/http_base.h | 14 ++--- src/currency_core/currency_format_utils.h | 14 +++++ src/gui/qt-daemon/application/mainwindow.cpp | 58 ++++++++++++-------- src/gui/qt-daemon/application/mainwindow.h | 47 ++++++++-------- src/wallet/core_default_rpc_proxy.cpp | 21 +++++++ src/wallet/core_default_rpc_proxy.h | 1 + src/wallet/core_fast_rpc_proxy.h | 16 ++++++ src/wallet/core_rpc_proxy.h | 2 + src/wallet/view_iface.h | 6 +- src/wallet/wallet2.cpp | 50 ++++++++++------- src/wallet/wallet2.h | 10 +++- src/wallet/wallet2_base.h | 9 ++- src/wallet/wallet_public_structs_defs.h | 38 ++++++++++++- src/wallet/wallet_rpc_server.cpp | 27 ++++++++- src/wallet/wallet_rpc_server.h | 9 ++- src/wallet/wallets_manager.cpp | 25 +++++++-- src/wallet/wallets_manager.h | 2 + 18 files changed, 263 insertions(+), 93 deletions(-) diff --git a/contrib/epee/include/misc_language.h b/contrib/epee/include/misc_language.h index 6e2e09f2..ecf6677e 100644 --- a/contrib/epee/include/misc_language.h +++ b/contrib/epee/include/misc_language.h @@ -82,6 +82,13 @@ namespace epee namespace misc_utils { + + template + void cast_assign_a_to_b(t_type_a& a, const t_type_b& b) + { + *static_cast(&a) = b; + } + template diff --git a/contrib/epee/include/net/http_base.h b/contrib/epee/include/net/http_base.h index cca1add3..afaadbf4 100644 --- a/contrib/epee/include/net/http_base.h +++ b/contrib/epee/include/net/http_base.h @@ -98,7 +98,7 @@ namespace net_utils std::string m_transfer_encoding;//"Transfer-Encoding:" std::string m_content_encoding; //"Content-Encoding:" std::string m_host; //"Host:" - std::string m_cookie; //"Cookie:" + std::string m_cookie; //"Cookie:" fields_list m_etc_fields; void clear() @@ -147,10 +147,10 @@ namespace net_utils std::string m_http_method_str; std::string m_full_request_str; std::string m_replace_html; - std::string m_request_head; + std::string m_request_head; int m_http_ver_hi; int m_http_ver_lo; - bool m_have_to_block; + bool m_have_to_block; http_header_info m_header_info; uri_content m_uri_content; size_t m_full_request_buf_size; @@ -166,11 +166,11 @@ namespace net_utils struct http_response_info { - int m_response_code; - std::string m_response_comment; + int m_response_code; + std::string m_response_comment; fields_list m_additional_fields; - std::string m_body; - std::string m_mime_tipe; + std::string m_body; + std::string m_mime_tipe; http_header_info m_header_info; int m_http_ver_hi;// OUT paramter only int m_http_ver_lo;// OUT paramter only diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index 8f858303..9be85e20 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -534,6 +534,20 @@ namespace currency bool is_pos_coinbase(const transaction& tx); bool have_attachment_service_in_container(const std::vector& av, const std::string& service_id, const std::string& instruction); crypto::hash prepare_prefix_hash_for_sign(const transaction& tx, uint64_t in_index, const crypto::hash& tx_id); + + + //--------------------------------------------------------------- + template + void assets_map_to_assets_list(std::list& assets_list, const t_assets_map& assets_map) + { + for (const auto& pr : assets_map) + { + assets_list.push_back(currency::asset_descriptor_with_id()); + assets_list.back().asset_id = pr.first; + epee::misc_utils::cast_assign_a_to_b(assets_list.back(), static_cast(pr.second)); + //*static_cast(&assets_list.back()) = pr.second; + } + } //--------------------------------------------------------------- template diff --git a/src/gui/qt-daemon/application/mainwindow.cpp b/src/gui/qt-daemon/application/mainwindow.cpp index d2cc787c..0e3c974e 100644 --- a/src/gui/qt-daemon/application/mainwindow.cpp +++ b/src/gui/qt-daemon/application/mainwindow.cpp @@ -223,7 +223,7 @@ QString MainWindow::get_default_user_dir(const QString& param) } -bool MainWindow::toggle_mining() +bool MainWindow::toggle_mining(const QString& param) { TRY_ENTRY(); m_backend.toggle_pos_mining(); @@ -238,7 +238,7 @@ QString MainWindow::get_exchange_last_top(const QString& params) CATCH_ENTRY_FAIL_API_RESPONCE(); } -QString MainWindow::get_tx_pool_info() +QString MainWindow::get_tx_pool_info(const QString& param) { TRY_ENTRY(); LOG_API_TIMING(); @@ -248,7 +248,7 @@ QString MainWindow::get_tx_pool_info() CATCH_ENTRY_FAIL_API_RESPONCE(); } -QString MainWindow::request_dummy() +QString MainWindow::request_dummy(const QString& param) { static int code_ = 0; TRY_ENTRY(); @@ -284,7 +284,7 @@ QString MainWindow::call_rpc(const QString& params) epee::net_utils::http::http_request_info query_info = AUTO_VAL_INIT(query_info); epee::net_utils::http::http_response_info response_info = AUTO_VAL_INIT(response_info); - currency::core_rpc_server::connection_context dummy_context = AUTO_VAL_INIT(dummy_context); + currency::core_rpc_server::connection_context dummy_context(RPC_INTERNAL_UI_CONTEXT, 0, 0, true); query_info.m_URI = "/json_rpc"; query_info.m_body = params.toStdString(); @@ -301,14 +301,14 @@ QString MainWindow::call_rpc(const QString& params) return QString::fromStdString(response_info.m_body); CATCH_ENTRY_FAIL_API_RESPONCE(); } -QString MainWindow::get_default_fee() +QString MainWindow::get_default_fee(const QString& param) { TRY_ENTRY(); return QString(std::to_string(m_backend.get_default_fee()).c_str()); CATCH_ENTRY_FAIL_API_RESPONCE(); } -QString MainWindow::get_options() +QString MainWindow::get_options(const QString& param) { TRY_ENTRY(); LOG_API_TIMING(); @@ -319,7 +319,7 @@ QString MainWindow::get_options() CATCH_ENTRY_FAIL_API_RESPONCE(); } -void MainWindow::tray_quit_requested() +void MainWindow::tray_quit_requested(const QString& param) { TRY_ENTRY(); LOG_PRINT_MAGENTA("[GUI]->[HTML] tray_quit_requested", LOG_LEVEL_0); @@ -350,10 +350,10 @@ void MainWindow::closeEvent(QCloseEvent *event) } else { + event->ignore(); //m_quit_requested = true; LOG_PRINT_L0("[GUI]->[HTML] quit_requested"); emit quit_requested("{}"); - event->ignore(); } CATCH_ENTRY2(void()); } @@ -474,7 +474,7 @@ bool MainWindow::init(const std::string& html_path) CATCH_ENTRY2(false); } -void MainWindow::on_menu_show() +void MainWindow::on_menu_show(const QString& param) { TRY_ENTRY(); qDebug() << "Context menu: show()"; @@ -546,7 +546,7 @@ void MainWindow::bool_toggle_icon(const QString& param) CATCH_ENTRY2(void()); } -QString MainWindow::get_log_file() +QString MainWindow::get_log_file(const QString& param) { TRY_ENTRY(); std::string buff; @@ -662,7 +662,7 @@ QString MainWindow::set_clipboard(const QString& param) CATCH_ENTRY2(API_RETURN_CODE_INTERNAL_ERROR); } -QString MainWindow::get_clipboard() +QString MainWindow::get_clipboard(const QString& param) { TRY_ENTRY(); LOG_API_TIMING(); @@ -671,7 +671,7 @@ QString MainWindow::get_clipboard() CATCH_ENTRY2(API_RETURN_CODE_INTERNAL_ERROR); } -QString MainWindow::on_request_quit() +QString MainWindow::on_request_quit(const QString& param) { TRY_ENTRY(); LOG_PRINT_MAGENTA("[HTML]->[GUI] on_request_quit", LOG_LEVEL_0); @@ -933,7 +933,7 @@ bool MainWindow::init_backend(int argc, char* argv[]) CATCH_ENTRY2(false); } -QString MainWindow::is_remnotenode_mode_preconfigured() +QString MainWindow::is_remnotenode_mode_preconfigured(const QString& param) { TRY_ENTRY(); return API_RETURN_CODE_FALSE; @@ -1044,7 +1044,7 @@ bool MainWindow::nativeEventFilter(const QByteArray &eventType, void *message, l CATCH_ENTRY2(false); } -bool MainWindow::get_is_disabled_notifications() +bool MainWindow::get_is_disabled_notifications(const QString& param) { return m_config.disable_notifications; } @@ -1181,21 +1181,21 @@ bool MainWindow::pos_block_found(const currency::block& block_found) CATCH_ENTRY2(false); } -QString MainWindow::get_version() +QString MainWindow::get_version(const QString& param) { TRY_ENTRY(); return PROJECT_VERSION_LONG; CATCH_ENTRY_FAIL_API_RESPONCE(); } -QString MainWindow::get_os_version() +QString MainWindow::get_os_version(const QString& param) { TRY_ENTRY(); return tools::get_os_version_string().c_str(); CATCH_ENTRY2(API_RETURN_CODE_INTERNAL_ERROR); } -QString MainWindow::get_network_type() +QString MainWindow::get_network_type(const QString& param) { #if defined(TESTNET) return "testnet"; @@ -1626,7 +1626,7 @@ QString MainWindow::load_from_file(const QString& path) CATCH_ENTRY2(API_RETURN_CODE_INTERNAL_ERROR); } -QString MainWindow::get_app_data() +QString MainWindow::get_app_data(const QString& param) { TRY_ENTRY(); LOG_API_TIMING(); @@ -1637,7 +1637,7 @@ QString MainWindow::get_app_data() } -QString MainWindow::have_secure_app_data() +QString MainWindow::have_secure_app_data(const QString& param) { TRY_ENTRY(); LOG_API_TIMING(); @@ -1655,7 +1655,7 @@ QString MainWindow::have_secure_app_data() CATCH_ENTRY_FAIL_API_RESPONCE(); } -QString MainWindow::drop_secure_app_data() +QString MainWindow::drop_secure_app_data(const QString& param) { TRY_ENTRY(); LOG_API_TIMING(); @@ -1673,7 +1673,7 @@ QString MainWindow::drop_secure_app_data() CATCH_ENTRY_FAIL_API_RESPONCE(); } -QString MainWindow::get_all_aliases() +QString MainWindow::get_all_aliases(const QString& param) { TRY_ENTRY(); LOG_API_TIMING(); @@ -1779,7 +1779,7 @@ QString MainWindow::set_enable_tor(const QString& param) // return MAKE_RESPONSE(ar); // } -QString MainWindow::webkit_launched_script() +QString MainWindow::webkit_launched_script(const QString& param) { TRY_ENTRY(); m_last_update_daemon_status_json.clear(); @@ -1993,7 +1993,7 @@ QString MainWindow::get_fav_offers(const QString& param) return MAKE_RESPONSE(ar); CATCH_ENTRY_FAIL_API_RESPONCE(); } -QString MainWindow::is_pos_allowed() +QString MainWindow::is_pos_allowed(const QString& param) { TRY_ENTRY(); LOG_API_TIMING(); @@ -2265,7 +2265,7 @@ QString MainWindow::is_wallet_password_valid(const QString& param) CATCH_ENTRY_FAIL_API_RESPONCE(); } -QString MainWindow::is_autostart_enabled() +QString MainWindow::is_autostart_enabled(const QString& param) { TRY_ENTRY(); LOG_API_TIMING(); @@ -2319,6 +2319,16 @@ QString MainWindow::open_url_in_browser(const QString& param) CATCH_ENTRY2(API_RETURN_CODE_INTERNAL_ERROR); } +QString MainWindow::setup_jwt_wallet_rpc(const QString& param) +{ + TRY_ENTRY(); + + m_backend.setup_wallet_rpc(param.toStdString()); + + return API_RETURN_CODE_OK; + CATCH_ENTRY2(API_RETURN_CODE_INTERNAL_ERROR); +} + QString MainWindow::is_valid_restore_wallet_text(const QString& param) { TRY_ENTRY(); diff --git a/src/gui/qt-daemon/application/mainwindow.h b/src/gui/qt-daemon/application/mainwindow.h index ed980f7d..c2725682 100644 --- a/src/gui/qt-daemon/application/mainwindow.h +++ b/src/gui/qt-daemon/application/mainwindow.h @@ -106,17 +106,18 @@ public: QString accept_cancel_contract(const QString& param); - QString get_version(); - QString get_os_version(); - QString get_network_type(); + QString on_request_quit(const QString& param); + QString get_version(const QString& param); + QString get_os_version(const QString& param); + QString get_network_type(const QString& param); QString transfer(const QString& json_transfer_object); - QString have_secure_app_data(); - QString drop_secure_app_data(); + QString have_secure_app_data(const QString& param); + QString drop_secure_app_data(const QString& param); QString get_secure_app_data(const QString& param); QString store_secure_app_data(const QString& param); QString set_master_password(const QString& param); QString check_master_password(const QString& param); - QString get_app_data(); + QString get_app_data(const QString& param); QString store_app_data(const QString& param); QString get_default_user_dir(const QString& param); // QString get_all_offers(const QString& param); @@ -126,12 +127,11 @@ public: QString push_update_offer(const QString& param); QString get_alias_info_by_address(const QString& param); QString get_alias_info_by_name(const QString& param); - QString get_all_aliases(); + QString get_all_aliases(const QString& param); QString request_alias_registration(const QString& param); QString request_alias_update(const QString& param); QString get_alias_coast(const QString& param); QString validate_address(const QString& param); - QString on_request_quit(); QString resync_wallet(const QString& param); QString get_recent_transfers(const QString& param); QString get_mining_history(const QString& param); @@ -141,11 +141,11 @@ public: QString get_log_level(const QString& param); QString set_enable_tor(const QString& param); // QString dump_all_offers(); - QString webkit_launched_script(); + QString webkit_launched_script(const QString& param); QString get_smart_wallet_info(const QString& param); QString restore_wallet(const QString& param); QString use_whitelisting(const QString& param); - QString is_pos_allowed(); + QString is_pos_allowed(const QString& param); QString store_to_file(const QString& path, const QString& buff); QString load_from_file(const QString& path); QString is_file_exist(const QString& path); @@ -153,7 +153,7 @@ public: QString backup_wallet_keys(const QString& obj); QString reset_wallet_password(const QString& param); QString is_wallet_password_valid(const QString& param); - QString is_autostart_enabled(); + QString is_autostart_enabled(const QString& param); QString toggle_autostart(const QString& param); QString is_valid_restore_wallet_text(const QString& param); QString get_seed_phrase_info(const QString& param); @@ -161,13 +161,13 @@ public: QString print_log(const QString& param); QString set_clipboard(const QString& param); QString set_localization_strings(const QString str); - QString get_clipboard(); + QString get_clipboard(const QString& param); void message_box(const QString& msg); - bool toggle_mining(); + bool toggle_mining(const QString& param); QString get_exchange_last_top(const QString& params); - QString get_tx_pool_info(); - QString get_default_fee(); - QString get_options(); + QString get_tx_pool_info(const QString& param); + QString get_default_fee(const QString& param); + QString get_options(const QString& param); void bool_toggle_icon(const QString& param); QString add_custom_asset_id(const QString& param); QString remove_custom_asset_id(const QString& param); @@ -177,24 +177,25 @@ public: QString get_ionic_swap_proposal_info(const QString& param); QString accept_ionic_swap_proposal(const QString& param); - bool get_is_disabled_notifications(); + bool get_is_disabled_notifications(const QString& param); bool set_is_disabled_notifications(const bool& param); QString export_wallet_history(const QString& param); - QString get_log_file(); + QString get_log_file(const QString& param); //QString check_available_sources(const QString& param); QString open_url_in_browser(const QString& param); + QString setup_jwt_wallet_rpc(const QString& param); void trayIconActivated(QSystemTrayIcon::ActivationReason reason); - void tray_quit_requested(); - void on_menu_show(); - QString is_remnotenode_mode_preconfigured(); + void tray_quit_requested(const QString& param); + void on_menu_show(const QString& param); + QString is_remnotenode_mode_preconfigured(const QString& param); QString start_backend(const QString& params); QString async_call(const QString& func_name, const QString& params); QString sync_call(const QString& func_name, const QString& params); - //for test purposes onlys - QString request_dummy(); + //for test purposes only + QString request_dummy(const QString& param); QString call_rpc(const QString& params); diff --git a/src/wallet/core_default_rpc_proxy.cpp b/src/wallet/core_default_rpc_proxy.cpp index 92cf11bc..7035b57c 100644 --- a/src/wallet/core_default_rpc_proxy.cpp +++ b/src/wallet/core_default_rpc_proxy.cpp @@ -52,6 +52,27 @@ namespace tools return r; } //------------------------------------------------------------------------------------------------------------------------------ + bool default_http_core_proxy::call_COMMAND_RPC_INVOKE(const std::string& uri, const std::string& body, int& response_code, std::string& response_body) + { + return call_request([&]() { +#ifdef MOBILE_WALLET_BUILD + LOG_PRINT_L0("[INVOKE_PROXY] ---> " << method_name) +#endif + + const epee::net_utils::http::http_response_info* response = nullptr; + bool res = m_http_client.invoke(uri, "POST", body, &response); + if (response) + { + response_body = response->m_body; + response_code = response->m_response_code; + } +#ifdef MOBILE_WALLET_BUILD + LOG_PRINT_L0("[INVOKE_PROXY] <---" << method_name) +#endif + return res; + }); + } + //------------------------------------------------------------------------------------------------------------------------------ bool default_http_core_proxy::call_COMMAND_RPC_GET_EST_HEIGHT_FROM_DATE(const currency::COMMAND_RPC_GET_EST_HEIGHT_FROM_DATE::request& rqt, currency::COMMAND_RPC_GET_EST_HEIGHT_FROM_DATE::response& rsp) { return invoke_http_json_rpc_update_is_disconnect("get_est_height_from_date", rqt, rsp); diff --git a/src/wallet/core_default_rpc_proxy.h b/src/wallet/core_default_rpc_proxy.h index 2d28c071..51a014a5 100644 --- a/src/wallet/core_default_rpc_proxy.h +++ b/src/wallet/core_default_rpc_proxy.h @@ -53,6 +53,7 @@ namespace tools bool call_COMMAND_RPC_GET_CURRENT_CORE_TX_EXPIRATION_MEDIAN(const currency::COMMAND_RPC_GET_CURRENT_CORE_TX_EXPIRATION_MEDIAN::request& req, currency::COMMAND_RPC_GET_CURRENT_CORE_TX_EXPIRATION_MEDIAN::response& res) override; bool call_COMMAND_RPC_GET_POOL_INFO(const currency::COMMAND_RPC_GET_POOL_INFO::request& req, currency::COMMAND_RPC_GET_POOL_INFO::response& res) override; bool call_COMMAND_RPC_GET_ASSET_INFO(const currency::COMMAND_RPC_GET_ASSET_INFO::request& req, currency::COMMAND_RPC_GET_ASSET_INFO::response& res) override; + bool call_COMMAND_RPC_INVOKE(const std::string& uri, const std::string& body, int& response_code, std::string& response_body) override; bool check_connection() override; bool get_transfer_address(const std::string& adr_str, currency::account_public_address& addr, std::string& payment_id) override; diff --git a/src/wallet/core_fast_rpc_proxy.h b/src/wallet/core_fast_rpc_proxy.h index 3d212676..daac69eb 100644 --- a/src/wallet/core_fast_rpc_proxy.h +++ b/src/wallet/core_fast_rpc_proxy.h @@ -143,6 +143,22 @@ namespace tools return m_rpc.on_get_asset_info(req, res, m_cntxt_stub); } //------------------------------------------------------------------------------------------------------------------------------ + virtual bool call_COMMAND_RPC_INVOKE(const std::string& uri, const std::string& body, int& response_code, std::string& response_body) override + { + epee::net_utils::http::http_request_info query_info = AUTO_VAL_INIT(query_info); + query_info.m_URI = uri; + query_info.m_http_method = epee::net_utils::http::http_method_get; + query_info.m_body = body; + + epee::net_utils::http::http_response_info response = AUTO_VAL_INIT(response); + epee::net_utils::connection_context_base conn_context = AUTO_VAL_INIT(conn_context); + + bool res = m_rpc.handle_http_request(query_info, response, conn_context); + response_body = response.m_body; + response_code = response.m_response_code; + return res; + } + //------------------------------------------------------------------------------------------------------------------------------ virtual bool get_transfer_address(const std::string& adr_str, currency::account_public_address& addr, std::string& payment_id) override { return tools::get_transfer_address(adr_str, addr, payment_id, this); diff --git a/src/wallet/core_rpc_proxy.h b/src/wallet/core_rpc_proxy.h index effec340..407e4b49 100644 --- a/src/wallet/core_rpc_proxy.h +++ b/src/wallet/core_rpc_proxy.h @@ -53,6 +53,8 @@ namespace tools virtual bool call_COMMAND_RPC_GET_CURRENT_CORE_TX_EXPIRATION_MEDIAN(const currency::COMMAND_RPC_GET_CURRENT_CORE_TX_EXPIRATION_MEDIAN::request& req, currency::COMMAND_RPC_GET_CURRENT_CORE_TX_EXPIRATION_MEDIAN::response& res){ return false; } virtual bool call_COMMAND_RPC_GET_POOL_INFO(const currency::COMMAND_RPC_GET_POOL_INFO::request& req, currency::COMMAND_RPC_GET_POOL_INFO::response& res) { return false; } virtual bool call_COMMAND_RPC_GET_ASSET_INFO(const currency::COMMAND_RPC_GET_ASSET_INFO::request& req, currency::COMMAND_RPC_GET_ASSET_INFO::response& res) { return false; } + + virtual bool call_COMMAND_RPC_INVOKE(const std::string& uri, const std::string& body, int& response_code, std::string& response_body) { return false; } i_core_proxy() { diff --git a/src/wallet/view_iface.h b/src/wallet/view_iface.h index d315a041..16faf90e 100644 --- a/src/wallet/view_iface.h +++ b/src/wallet/view_iface.h @@ -729,12 +729,14 @@ public: struct gui_options { - bool use_debug_mode; - bool disable_price_fetch; + bool use_debug_mode = false; + bool disable_price_fetch = false; + int32_t rpc_port = 0; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(use_debug_mode) KV_SERIALIZE(disable_price_fetch) + KV_SERIALIZE(rpc_port) END_KV_SERIALIZE_MAP() }; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 49c13987..67b48f2c 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -390,16 +390,17 @@ void wallet2::process_ado_in_new_transaction(const currency::asset_descriptor_op WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(m_own_asset_descriptors.count(asset_id) == 0, "asset with asset_id " << asset_id << " has already been registered in the wallet as own asset"); wallet_own_asset_context& asset_context = m_own_asset_descriptors[asset_id]; - asset_context.asset_descriptor = ado.descriptor; + epee::misc_utils::cast_assign_a_to_b(asset_context, ado.descriptor); + //*static_cast(&asset_context) = ado.descriptor; std::stringstream ss; ss << "New Asset Registered:" << ENDL << "asset id: " << asset_id - << ENDL << "Name: " << asset_context.asset_descriptor.full_name - << ENDL << "Ticker: " << asset_context.asset_descriptor.ticker - << ENDL << "Total Max Supply: " << print_asset_money(asset_context.asset_descriptor.total_max_supply, asset_context.asset_descriptor.decimal_point) - << ENDL << "Current Supply: " << print_asset_money(asset_context.asset_descriptor.current_supply, asset_context.asset_descriptor.decimal_point) - << ENDL << "Decimal Point: " << asset_context.asset_descriptor.decimal_point; + << ENDL << "Name: " << asset_context.full_name + << ENDL << "Ticker: " << asset_context.ticker + << ENDL << "Total Max Supply: " << print_asset_money(asset_context.total_max_supply, asset_context.decimal_point) + << ENDL << "Current Supply: " << print_asset_money(asset_context.current_supply, asset_context.decimal_point) + << ENDL << "Decimal Point: " << asset_context.decimal_point; add_rollback_event(ptc.height, asset_register_event{ asset_id }); @@ -414,7 +415,8 @@ void wallet2::process_ado_in_new_transaction(const currency::asset_descriptor_op break; //asset had been updated add_rollback_event(ptc.height, asset_update_event{ it->first, it->second }); - it->second.asset_descriptor = ado.descriptor; + epee::misc_utils::cast_assign_a_to_b(it->second, ado.descriptor); + } else if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_UPDATE ) { @@ -426,7 +428,7 @@ void wallet2::process_ado_in_new_transaction(const currency::asset_descriptor_op // ownership of the asset acquired wallet_own_asset_context& asset_context = m_own_asset_descriptors[asset_id]; - asset_context.asset_descriptor = ado.descriptor; + epee::misc_utils::cast_assign_a_to_b(asset_context, ado.descriptor); std::stringstream ss; ss << "Asset ownership acquired:" @@ -477,7 +479,8 @@ void wallet2::process_ado_in_new_transaction(const currency::asset_descriptor_op { //just an update of the asset add_rollback_event(ptc.height, asset_update_event{ it->first, it->second }); - it->second.asset_descriptor = ado.descriptor; + epee::misc_utils::cast_assign_a_to_b(it->second, ado.descriptor); + } } } @@ -3461,7 +3464,7 @@ bool wallet2::balance(std::list& balances, u { if (m_whitelisted_assets.find(own_asset.first) == m_whitelisted_assets.end()) { - custom_assets_local[own_asset.first] = own_asset.second.asset_descriptor; + custom_assets_local[own_asset.first] = own_asset.second; } } @@ -3585,17 +3588,21 @@ bool wallet2::delete_custom_asset_id(const crypto::public_key& asset_id) return true; } //---------------------------------------------------------------------------------------------------- -bool wallet2::get_custom_assets(std::list& assets) const +const std::unordered_map& wallet2::get_local_whitelist() const { - for(const auto& pr : m_custom_assets) - { - assets.push_back(currency::asset_descriptor_with_id()); - assets.back().asset_id = pr.first; - static_cast(assets.back()) = pr.second; - } - return true; + return m_custom_assets; } //---------------------------------------------------------------------------------------------------- +const std::unordered_map& wallet2::get_global_whitelist() const +{ + return m_whitelisted_assets; +} +//---------------------------------------------------------------------------------------------------- +const std::unordered_map& wallet2::get_own_assets() const +{ + return m_own_asset_descriptors; +} + //---------------------------------------------------------------------------------------------------- bool wallet2::load_whitelisted_tokens() const { if(!m_use_assets_whitelisting) @@ -3775,7 +3782,7 @@ std::string wallet2::get_balance_str_raw() const for(const auto& entry : m_own_asset_descriptors) { - ss << " " << std::left << entry.first << " " << entry.second.asset_descriptor.ticker << ENDL; + ss << " " << std::left << entry.first << " " << entry.second.ticker << ENDL; } return ss.str(); @@ -4252,6 +4259,11 @@ bool wallet2::is_in_hardfork_zone(uint64_t hardfork_index) const return m_core_runtime_config.is_hardfork_active_for_height(hardfork_index, get_blockchain_current_size()); } //---------------------------------------------------------------------------------------------------- +bool wallet2::proxy_to_daemon(const std::string& uri, const std::string& body, int& response_code, std::string& response_body) +{ + return m_core_proxy->call_COMMAND_RPC_INVOKE(uri, body, response_code, response_body); +} +//---------------------------------------------------------------------------------------------------- bool wallet2::prepare_and_sign_pos_block(const mining_context& cxt, uint64_t full_block_reward, const currency::pos_entry& pe, currency::tx_generation_context& miner_tx_tgc, currency::block& b) const { bool r = false; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index da47141b..1b0c2892 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -397,7 +397,6 @@ namespace tools void transfer_asset_ownership(const crypto::public_key asset_id, const crypto::public_key& new_owner, currency::transaction& result_tx); bool daemon_get_asset_info(const crypto::public_key& asset_id, currency::asset_descriptor_base& adb); - const std::unordered_map& get_own_assets() const { return m_own_asset_descriptors; } bool set_core_proxy(const std::shared_ptr& proxy); void set_pos_utxo_count_limits_for_defragmentation_tx(uint64_t min_outs, uint64_t max_outs); // don't create UTXO defrag. tx if there are less than 'min_outs' outs; don't put more than 'max_outs' outs void set_pos_decoys_count_for_defragmentation_tx(size_t decoys_count); @@ -659,10 +658,14 @@ namespace tools bool add_custom_asset_id(const crypto::public_key& asset_id, currency::asset_descriptor_base& asset_descriptor); bool delete_custom_asset_id(const crypto::public_key& asset_id); - bool get_custom_assets(std::list& assets) const; + const std::unordered_map& get_local_whitelist() const; + const std::unordered_map& get_global_whitelist() const; + const std::unordered_map& get_own_assets() const; + bool load_whitelisted_tokens_if_not_loaded() const; bool load_whitelisted_tokens() const; + void set_connectivity_options(unsigned int timeout); /* @@ -696,6 +699,9 @@ namespace tools bool encrypt_buffer(const std::string& buff, std::string& res_buff); bool decrypt_buffer(const std::string& buff, std::string& res_buff); bool is_in_hardfork_zone(uint64_t hardfork_index) const; + + //performance inefficient call, suitable only for rare ocasions or super lazy developers + bool proxy_to_daemon(const std::string& uri, const std::string& body, int& response_code, std::string& response_body); construct_tx_param get_default_construct_tx_param(); diff --git a/src/wallet/wallet2_base.h b/src/wallet/wallet2_base.h index d9c9589c..c2ec860b 100644 --- a/src/wallet/wallet2_base.h +++ b/src/wallet/wallet2_base.h @@ -251,19 +251,18 @@ namespace tools crypto::public_key asset_id = currency::null_pkey; BEGIN_BOOST_SERIALIZATION() BOOST_SERIALIZE(asset_id) - END_BOOST_SERIALIZATION() + END_BOOST_SERIALIZATION() }; - struct wallet_own_asset_context + struct wallet_own_asset_context: public currency::asset_descriptor_base { - currency::asset_descriptor_base asset_descriptor; bool thirdparty_custody = false; BEGIN_BOOST_SERIALIZATION() - BOOST_SERIALIZE(asset_descriptor) + BOOST_SERIALIZE_BASE_CLASS(currency::asset_descriptor_base) BOOST_SERIALIZE(thirdparty_custody) - END_BOOST_SERIALIZATION() + END_BOOST_SERIALIZATION() }; struct asset_update_event diff --git a/src/wallet/wallet_public_structs_defs.h b/src/wallet/wallet_public_structs_defs.h index 6db3db3b..59d3f110 100644 --- a/src/wallet/wallet_public_structs_defs.h +++ b/src/wallet/wallet_public_structs_defs.h @@ -14,8 +14,12 @@ #include "currency_core/bc_escrow_service.h" #include "rpc/core_rpc_server_commands_defs.h" + + const uint64_t WALLET_GLOBAL_OUTPUT_INDEX_UNDEFINED = std::numeric_limits::max(); +const boost::uuids::uuid RPC_INTERNAL_UI_CONTEXT = {0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 2, 1, 0, 0}; //Bender's nightmare + namespace tools { namespace wallet_public @@ -1697,6 +1701,31 @@ namespace wallet_public }; }; + struct COMMAND_PROXY_TO_DAEMON + { + struct request + { + + std::string uri; + std::string base64_body; //base64 encoded body + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(uri) + KV_SERIALIZE(base64_body) + END_KV_SERIALIZE_MAP() + }; + + struct response + { + std::string base64_body; //base64 encoded response body + int32_t response_code; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(base64_body) + KV_SERIALIZE(response_code) + END_KV_SERIALIZE_MAP() + }; + }; struct assets_whitelist { @@ -1749,10 +1778,15 @@ namespace wallet_public struct response { - std::list assets; + std::list local_whitelist; + std::list global_whitelist; + std::list own_assets; + BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(assets) + KV_SERIALIZE(local_whitelist) + KV_SERIALIZE(global_whitelist) + KV_SERIALIZE(own_assets) END_KV_SERIALIZE_MAP() }; }; diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 605ffed5..bd157d01 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -261,7 +261,7 @@ namespace tools //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::handle_http_request(const epee::net_utils::http::http_request_info& query_info, epee::net_utils::http::http_response_info& response, connection_context& m_conn_context) { - if (m_jwt_secret.size()) + if (m_jwt_secret.size() && m_conn_context.m_connection_id != RPC_INTERNAL_UI_CONTEXT) { if (!auth_http_request(query_info, response, m_conn_context)) { @@ -301,6 +301,11 @@ namespace tools m_jwt_secret = jwt; } //------------------------------------------------------------------------------------------------------------------------------ + const std::string& wallet_rpc_server::get_jwt_secret() + { + return m_jwt_secret; + } + //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_getbalance(const wallet_public::COMMAND_RPC_GET_BALANCE::request& req, wallet_public::COMMAND_RPC_GET_BALANCE::response& res, epee::json_rpc::error& er, connection_context& cntx) { WALLET_RPC_BEGIN_TRY_ENTRY(); @@ -1108,7 +1113,13 @@ namespace tools bool wallet_rpc_server::on_assets_whitelist_get(const wallet_public::COMMAND_ASSETS_WHITELIST_GET::request& req, wallet_public::COMMAND_ASSETS_WHITELIST_GET::response& res, epee::json_rpc::error& er, connection_context& cntx) { WALLET_RPC_BEGIN_TRY_ENTRY(); - w.get_wallet()->get_custom_assets(res.assets); + + currency::assets_map_to_assets_list(res.local_whitelist, w.get_wallet()->get_local_whitelist()); + currency::assets_map_to_assets_list(res.global_whitelist, w.get_wallet()->get_global_whitelist()); + currency::assets_map_to_assets_list(res.own_assets, w.get_wallet()->get_own_assets()); + + const auto global_whitelist = w.get_wallet()->get_global_whitelist(); + return true; WALLET_RPC_CATCH_TRY_ENTRY(); } @@ -1193,6 +1204,18 @@ namespace tools WALLET_RPC_CATCH_TRY_ENTRY(); } //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_proxy_to_daemon(const wallet_public::COMMAND_PROXY_TO_DAEMON::request& req, wallet_public::COMMAND_PROXY_TO_DAEMON::response& res, epee::json_rpc::error& er, connection_context& cntx) + { + WALLET_RPC_BEGIN_TRY_ENTRY(); + std::string buff = epee::string_encoding::base64_decode(req.base64_body); + + w.get_wallet()->proxy_to_daemon(req.uri, buff, res.response_code, res.base64_body); + + res.base64_body = epee::string_encoding::base64_encode(res.base64_body); + return true; + WALLET_RPC_CATCH_TRY_ENTRY(); + } + //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_decrypt_data(const wallet_public::COMMAND_DECRYPT_DATA::request& req, wallet_public::COMMAND_DECRYPT_DATA::response& res, epee::json_rpc::error& er, connection_context& cntx) { WALLET_RPC_BEGIN_TRY_ENTRY(); diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index fc0e60be..86faf178 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -90,6 +90,7 @@ namespace tools bool run(bool do_mint, bool offline_mode, const currency::account_public_address& miner_address); bool handle_http_request(const epee::net_utils::http::http_request_info& query_info, epee::net_utils::http::http_response_info& response, connection_context& m_conn_context); void set_jwt_secret(const std::string& jwt); + const std::string& get_jwt_secret(); BEGIN_URI_MAP2_VIRTUAL() BEGIN_JSON_RPC_MAP("/json_rpc") @@ -149,8 +150,11 @@ namespace tools MAP_JON_RPC_WE("sign_message", on_sign_message, wallet_public::COMMAND_SIGN_MESSAGE) MAP_JON_RPC_WE("encrypt_data", on_encrypt_data, wallet_public::COMMAND_ENCRYPT_DATA) MAP_JON_RPC_WE("decrypt_data", on_decrypt_data, wallet_public::COMMAND_DECRYPT_DATA) - END_JSON_RPC_MAP() - END_URI_MAP2() + + //utility call + MAP_JON_RPC_WE("proxy_to_daemon", on_proxy_to_daemon, wallet_public::COMMAND_PROXY_TO_DAEMON) + END_JSON_RPC_MAP() + END_URI_MAP2() bool auth_http_request(const epee::net_utils::http::http_request_info& query_info, epee::net_utils::http::http_response_info& response, connection_context& m_conn_context); //json_rpc @@ -209,6 +213,7 @@ namespace tools bool on_encrypt_data(const wallet_public::COMMAND_ENCRYPT_DATA::request& req, wallet_public::COMMAND_ENCRYPT_DATA::response& res, epee::json_rpc::error& er, connection_context& cntx); bool on_decrypt_data(const wallet_public::COMMAND_DECRYPT_DATA::request& req, wallet_public::COMMAND_DECRYPT_DATA::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool on_proxy_to_daemon(const wallet_public::COMMAND_PROXY_TO_DAEMON::request& req, wallet_public::COMMAND_PROXY_TO_DAEMON::response& res, epee::json_rpc::error& er, connection_context& cntx); //std::shared_ptr get_wallet(); diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index c1edabff..045ba196 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -546,13 +546,12 @@ bool wallets_manager::init_local_daemon() CHECK_AND_ASSERT_AND_SET_GUI(res, "Failed to initialize core rpc server."); LOG_PRINT_GREEN("Core rpc server initialized OK on port: " << m_rpc_server.get_binded_port(), LOG_LEVEL_0); + m_ui_opt.rpc_port = m_rpc_server.get_binded_port(); + + //chain calls to rpc server m_prpc_chain_handler = &m_wallet_rpc_server; //disable this for main net until we get full support of authentication with network -#ifdef TESTNET - m_rpc_server.set_rpc_chain_handler(this); -#endif - LOG_PRINT_L0("Starting core rpc server..."); //dsi.text_state = "Starting core rpc server"; @@ -572,6 +571,23 @@ bool wallets_manager::init_local_daemon() return true; } +std::string wallets_manager::setup_wallet_rpc(const std::string& jwt_secret) +{ + if (!jwt_secret.size()) + { + //disabling wallet RPC + m_rpc_server.set_rpc_chain_handler(nullptr); + return WALLET_RPC_STATUS_OK; + } + + //we don't override command line JWT secret + if(!m_wallet_rpc_server.get_jwt_secret().size() ) + m_wallet_rpc_server.set_jwt_secret(jwt_secret); + + m_rpc_server.set_rpc_chain_handler(this); + return WALLET_RPC_STATUS_OK; +} + bool wallets_manager::deinit_local_daemon() { #ifndef MOBILE_WALLET_BUILD @@ -2103,7 +2119,6 @@ bool wallets_manager::on_mw_select_wallet(const tools::wallet_public::COMMAND_MW return true; } - void wallets_manager::lock() { #ifndef MOBILE_WALLET_BUILD diff --git a/src/wallet/wallets_manager.h b/src/wallet/wallets_manager.h index a19e8138..d07c3000 100644 --- a/src/wallet/wallets_manager.h +++ b/src/wallet/wallets_manager.h @@ -146,6 +146,8 @@ public: std::string get_fav_offers(const std::list& hashes, const bc_services::core_offers_filter& filter, std::list& offers); std::string get_tx_pool_info(currency::COMMAND_RPC_GET_POOL_INFO::response& res); std::string export_wallet_history(const view::export_wallet_info& ewi); + std::string setup_wallet_rpc(const std::string& jwt_secret); + #ifndef MOBILE_WALLET_BUILD currency::core_rpc_server& get_rpc_server() { return m_rpc_server; } #endif From 30b6082ce5a6fb0b379262d3b7465491623f719d Mon Sep 17 00:00:00 2001 From: zano build machine Date: Tue, 19 Mar 2024 01:35:09 +0300 Subject: [PATCH 016/184] === build number: 276 -> 277 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index abd6fb50..3c7a81ab 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 276 +#define PROJECT_VERSION_BUILD_NO 277 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From c14b5b6b2139ef391627a991da327548ccde7d87 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Tue, 19 Mar 2024 01:35:54 +0300 Subject: [PATCH 017/184] === build number: 277 -> 278 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index 3c7a81ab..79c6174b 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 277 +#define PROJECT_VERSION_BUILD_NO 278 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From 0455e81b4c2c35c89008f3a60d3a0169e0adfd77 Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 19 Mar 2024 01:35:36 +0100 Subject: [PATCH 018/184] minor log improvement (take fee burning into account) --- src/currency_core/blockchain_storage.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 17ed1fbd..66764dfa 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -6714,7 +6714,7 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt TIME_MEASURE_FINISH_PD_MS(block_processing_time_0_ms); //print result - stringstream powpos_str_entry, timestamp_str_entry, pos_validation_str_entry; + stringstream powpos_str_entry, timestamp_str_entry, pos_validation_str_entry, block_reward_entry; if (is_pos_bl) { // PoS int64_t actual_ts = get_block_datetime(bei.bl); // signed int is intentionally used here @@ -6736,6 +6736,10 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt powpos_str_entry << "PoW:\t" << proof_hash; timestamp_str_entry << ", block ts: " << bei.bl.timestamp << " (diff: " << std::showpos << ts_diff << "s)"; } + if(bei.bl.miner_tx.version >= TRANSACTION_VERSION_POST_HF4) + block_reward_entry << "block reward: " << print_money_brief(base_reward) << ", fee burnt: " << print_money_brief(fee_summary); + else + block_reward_entry << "block reward: " << print_money_brief(base_reward + fee_summary) << " (" << print_money_brief(base_reward) << " + " << print_money_brief(fee_summary) << ")"; //explanation of this code will be provided later with public announce set_lost_tx_unmixable_for_height(bei.height); @@ -6744,8 +6748,7 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt << ENDL << "id:\t" << id << timestamp_str_entry.str() << ENDL << powpos_str_entry.str() << ENDL << "HEIGHT " << bei.height << ", difficulty: " << current_diffic << ", cumul_diff_precise: " << bei.cumulative_diff_precise << ", cumul_diff_precise_adj: " << bei.cumulative_diff_precise_adjusted << " (+" << cumulative_diff_delta << ")" - << ENDL << "block reward: " << print_money_brief(base_reward + fee_summary) << " (" << print_money_brief(base_reward) << " + " << print_money_brief(fee_summary) - << ")" << ", coinbase_blob_size: " << coinbase_blob_size << ", cumulative size: " << cumulative_block_size << ", tx_count: " << bei.bl.tx_hashes.size() + << ENDL << block_reward_entry.str() << ", coinbase_blob_size: " << coinbase_blob_size << ", cumulative size: " << cumulative_block_size << ", tx_count: " << bei.bl.tx_hashes.size() << ", timing: " << block_processing_time_0_ms << "ms" << "(micrsec:" << block_processing_time_1 << "(" << target_calculating_time_2 << "(" << m_performance_data.target_calculating_enum_blocks.get_last_val() << "/" << m_performance_data.target_calculating_calc.get_last_val() << ")" From 1548ab662a576040b17ebc46caaf6e9f2453ceee Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 19 Mar 2024 01:40:45 +0100 Subject: [PATCH 019/184] wallet2::get_current_tx_version() fixed --- src/wallet/wallet2.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 67b48f2c..575a082f 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1080,7 +1080,8 @@ void wallet2::accept_proposal(const crypto::hash& contract_id, uint64_t b_accept //--------------------------------------------------------------------------------- uint64_t wallet2::get_current_tx_version() { - return currency::get_tx_version(this->get_top_block_height(), this->m_core_runtime_config.hard_forks); + uint64_t tx_expected_block_height = get_top_block_height() + 1; + return currency::get_tx_version(tx_expected_block_height, this->m_core_runtime_config.hard_forks); } //--------------------------------------------------------------------------------- void wallet2::finish_contract(const crypto::hash& contract_id, const std::string& release_type, currency::transaction* p_release_tx /* = nullptr */) From 7a6883457b65b63268b700d3fdb576403cb49e3d Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Tue, 19 Mar 2024 12:30:09 +0000 Subject: [PATCH 020/184] fix for MOBILE_WALLET_BUILD --- src/wallet/core_default_rpc_proxy.cpp | 4 ++-- src/wallet/wallets_manager.cpp | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/wallet/core_default_rpc_proxy.cpp b/src/wallet/core_default_rpc_proxy.cpp index 7035b57c..ae7ff6ea 100644 --- a/src/wallet/core_default_rpc_proxy.cpp +++ b/src/wallet/core_default_rpc_proxy.cpp @@ -56,7 +56,7 @@ namespace tools { return call_request([&]() { #ifdef MOBILE_WALLET_BUILD - LOG_PRINT_L0("[INVOKE_PROXY] ---> " << method_name) + LOG_PRINT_L0("[INVOKE_PROXY] ---> " << uri) #endif const epee::net_utils::http::http_response_info* response = nullptr; @@ -67,7 +67,7 @@ namespace tools response_code = response->m_response_code; } #ifdef MOBILE_WALLET_BUILD - LOG_PRINT_L0("[INVOKE_PROXY] <---" << method_name) + LOG_PRINT_L0("[INVOKE_PROXY] <---" << uri) #endif return res; }); diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index 045ba196..33d1cb03 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -573,6 +573,7 @@ bool wallets_manager::init_local_daemon() std::string wallets_manager::setup_wallet_rpc(const std::string& jwt_secret) { +#ifndef MOBILE_WALLET_BUILD if (!jwt_secret.size()) { //disabling wallet RPC @@ -585,6 +586,7 @@ std::string wallets_manager::setup_wallet_rpc(const std::string& jwt_secret) m_wallet_rpc_server.set_jwt_secret(jwt_secret); m_rpc_server.set_rpc_chain_handler(this); +#endif return WALLET_RPC_STATUS_OK; } From c03438ba231cd9aa9185e4196f393f1a169e9434 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Tue, 19 Mar 2024 17:54:41 +0100 Subject: [PATCH 021/184] fixed mw_get_wallets for simplewallet, fail-resistant whitelisti loading --- src/simplewallet/simplewallet.cpp | 17 ++++++++ src/wallet/wallet2.cpp | 5 ++- src/wallet/wallet_rpc_server.cpp | 3 ++ src/wallet/wallets_manager.cpp | 2 +- tests/performance_tests/main.cpp | 70 ++++++++----------------------- 5 files changed, 42 insertions(+), 55 deletions(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 681d356f..0cd51835 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -2816,6 +2816,22 @@ int main(int argc, char* argv[]) break; } //try to sync it + struct wallet_rpc_local_callback : public tools::i_wallet2_callback + { + std::shared_ptr m_wlt_ptr; + wallet_rpc_local_callback(std::shared_ptr ptr): m_wlt_ptr(ptr) + {} + virtual void on_mw_get_wallets(std::vector& wallets) + { + wallets.push_back(tools::wallet_public::wallet_entry_info()); + wallets.back().wallet_id = 0; + tools::get_wallet_info(*m_wlt_ptr, wallets.back().wi); + } + + }; + + std::shared_ptr callback(new wallet_rpc_local_callback(wallet_ptr)); + while (true) { try @@ -2828,6 +2844,7 @@ int main(int argc, char* argv[]) return EXIT_FAILURE; wal.set_use_assets_whitelisting(true); + wal.callback(callback); if (!offline_mode) wal.refresh(); diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 575a082f..200f5469 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -3617,9 +3617,10 @@ bool wallet2::load_whitelisted_tokens() const for (auto it = aw.assets.begin(); it != aw.assets.end(); it++) { m_whitelisted_assets[it->asset_id] = static_cast(*it); - } + } + return true; } - return true; + return false; } //---------------------------------------------------------------------------------------------------- bool wallet2::load_whitelisted_tokens_if_not_loaded() const diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index bd157d01..ddd09634 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -17,7 +17,10 @@ using namespace epee; #include "wallet_rpc_server_error_codes.h" #include "wallet_helpers.h" #include "wrap_service.h" +PUSH_VS_WARNINGS +DISABLE_VS_WARNINGS(4244) #include "jwt-cpp/jwt.h" +POP_VS_WARNINGS #include "crypto/bitcoin/sha256_helper.h" #define JWT_TOKEN_EXPIRATION_MAXIMUM (60 * 60) diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index 33d1cb03..cce0066b 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -1043,7 +1043,6 @@ std::string wallets_manager::open_wallet(const std::wstring& path, const std::st std::shared_ptr w(new tools::wallet2()); w->set_use_deffered_global_outputs(m_use_deffered_global_outputs); - w->set_use_assets_whitelisting(true); owr.wallet_id = m_wallet_id_counter++; w->callback(std::shared_ptr(new i_wallet_to_i_backend_adapter(this, owr.wallet_id))); @@ -1075,6 +1074,7 @@ std::string wallets_manager::open_wallet(const std::wstring& path, const std::st w->get_recent_transfers_history(owr.recent_history.history, 0, txs_to_return, owr.recent_history.total_history_items, owr.recent_history.last_item_index, exclude_mining_txs); //w->get_unconfirmed_transfers(owr.recent_history.unconfirmed); w->get_unconfirmed_transfers(owr.recent_history.history, exclude_mining_txs); + w->set_use_assets_whitelisting(true); owr.wallet_local_bc_size = w->get_blockchain_current_size(); //workaround for missed fee diff --git a/tests/performance_tests/main.cpp b/tests/performance_tests/main.cpp index ed6d991e..6d435955 100644 --- a/tests/performance_tests/main.cpp +++ b/tests/performance_tests/main.cpp @@ -26,61 +26,19 @@ #include "threads_pool_tests.h" #include "wallet/plain_wallet_api.h" #include "wallet/view_iface.h" -#include +PUSH_VS_WARNINGS +DISABLE_VS_WARNINGS(4244) +#include "jwt-cpp/jwt.h" +POP_VS_WARNINGS void test_plain_wallet() { - - std::string token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiemFub19leHRlbnNpb24iLCJzYWx0IjoiYTUyMTk5MzQyNmYxN2Y2MDQyMzkzYTI4YzJhMzk1NjFiYTgxYmVkZDkxODJlY2E5NTY3ZDBlNjQ3YjIwZTE2NSIsImV4cCI6MTcxMDM2MzA1MH0.CwqvPBtgE8ZUFZ4cYy1ZJLWdYCnhfEiCzEhqDYCK4CQ"; - auto decoded_token = jwt::decode(token); - - std::string sharedSecret = "DFDvfedceEDCECECecedcyhtyh"; - - try - { - auto decoded = jwt::decode(token); - - auto verifier = jwt::verify() - .allow_algorithm(jwt::algorithm::hs256 { sharedSecret }); - - verifier.verify(decoded); - - std::cout << "Token is valid. Claims:" << std::endl; - for(auto& e : decoded.get_payload_json()) - std::cout << e.first << " = " << e.second << std::endl; - } - catch(const std::exception& e) - { - std::cerr << "Invalid token: " << e.what() << std::endl; - } - - - /* - auto verifier = jwt::verify() - .with_issuer("auth0") - .with_claim("sample", jwt::claim(std::string("test"))) - .allow_algorithm(jwt::algorithm::hs256 { "secret" }); - - verifier.verify(decoded_token); - - auto token = jwt::create() - .set_type("JWS") - .set_issuer("auth0") - .set_payload_claim("sample", jwt::claim(std::string("test"))) - .sign(jwt::algorithm::hs256 { "secret" }); - -*/ - return; - - - - - std::string res = plain_wallet::init("195.201.107.230", "33336", "E:\\tmp\\", 0); + std::string res = plain_wallet::init("195.201.107.230", "33336", "C:\\Users\\roky\\home\\", 0); uint64_t instance_id = 0; - res = plain_wallet::open("test.zan", "111"); + res = plain_wallet::open("SEGA_2", "Test2"); while(true) { epee::misc_utils::sleep_no_w(2000); @@ -95,6 +53,14 @@ void test_plain_wallet() std::string invoke_body = "{\"method\":\"get_recent_txs_and_info\",\"params\":{\"offset\":0,\"count\":30,\"update_provision_info\":true}}"; res = plain_wallet::sync_call("invoke", instance_id, invoke_body); + + invoke_body = "{\"method\":\"assets_whitelist_get\",\"params\":{}}"; + + res = plain_wallet::sync_call("invoke", instance_id, invoke_body); + + + res = plain_wallet::close_wallet(instance_id); + LOG_PRINT_L0(res); } @@ -104,10 +70,10 @@ int main(int argc, char** argv) { epee::string_tools::set_module_name_and_folder(argv[0]); epee::log_space::get_set_log_detalisation_level(true, LOG_LEVEL_2); - epee::log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL, LOG_LEVEL_2); - epee::log_space::log_singletone::add_logger(LOGGER_FILE, - epee::log_space::log_singletone::get_default_log_file().c_str(), - epee::log_space::log_singletone::get_default_log_folder().c_str()); + //epee::log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL, LOG_LEVEL_2); + //epee::log_space::log_singletone::add_logger(LOGGER_FILE, + // epee::log_space::log_singletone::get_default_log_file().c_str(), + // epee::log_space::log_singletone::get_default_log_folder().c_str()); test_plain_wallet(); //parse_weird_tx(); From 1cffbaa9b867ac840f2104595ce8bd407630ab78 Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 19 Mar 2024 18:30:54 +0100 Subject: [PATCH 022/184] ui update --- src/gui/qt-daemon/layout | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/qt-daemon/layout b/src/gui/qt-daemon/layout index f8e9556f..d593aa34 160000 --- a/src/gui/qt-daemon/layout +++ b/src/gui/qt-daemon/layout @@ -1 +1 @@ -Subproject commit f8e9556fbaccd49841ce91afc3c90c8e3142ac95 +Subproject commit d593aa3485395d7cc0415519dc1fc079de82e0ea From 5ba45867f79043b4883df96b0983bf76c7ac8622 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Tue, 19 Mar 2024 20:32:04 +0300 Subject: [PATCH 023/184] === build number: 278 -> 279 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index 79c6174b..49405629 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 278 +#define PROJECT_VERSION_BUILD_NO 279 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From 80e8392be0395674e6ca37c5136a632cf556c8c2 Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 19 Mar 2024 18:47:26 +0100 Subject: [PATCH 024/184] code clean-up and logging improvements --- src/currency_core/blockchain_storage.cpp | 6 +++++- src/currency_core/pos_mining.cpp | 9 ++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 66764dfa..d19bb381 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -1910,7 +1910,11 @@ bool blockchain_storage::handle_alternative_block(const block& b, const crypto:: std::stringstream ss_pow_pos_info; if (pos_block) { - ss_pow_pos_info << "PoS:\t" << abei.stake_hash << ", stake amount: " << print_money(pos_amount) << ", final_difficulty: " << pos_diff_final; + ss_pow_pos_info << "PoS:\t" << abei.stake_hash << ", stake amount: "; + if (abei.bl.miner_tx.version >= TRANSACTION_VERSION_POST_HF4) + ss_pow_pos_info << "hidden"; + else + ss_pow_pos_info << print_money_brief(pos_amount) << ", final_difficulty: " << pos_diff_final; proof = abei.stake_hash; } else diff --git a/src/currency_core/pos_mining.cpp b/src/currency_core/pos_mining.cpp index 5bc1d973..478284d8 100644 --- a/src/currency_core/pos_mining.cpp +++ b/src/currency_core/pos_mining.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2022 Zano Project +// Copyright (c) 2022-2024 Zano Project // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. // @@ -56,7 +56,7 @@ namespace currency bool found = false; - if (this->zarcanum /* && td.is_zc() */) + if (this->zarcanum) { crypto::mp::uint256_t lhs; crypto::mp::uint512_t rhs; @@ -70,7 +70,7 @@ namespace currency const boost::multiprecision::uint256_t d_mp = lhs / (crypto::c_zarcanum_z_coeff_mp * this->stake_amount) + 1; const boost::multiprecision::uint256_t ba = d_mp * crypto::c_zarcanum_z_coeff_mp * this->stake_amount - lhs; const boost::multiprecision::uint256_t l_div_z_D = this->z_l_div_z_D / crypto::c_zarcanum_z_coeff_mp; - LOG_PRINT_GREEN("Found Zarcanum kernel: amount: " << currency::print_money_brief(this->stake_amount) << /* ", gindex: " << td.m_global_output_index << */ ENDL + LOG_PRINT_GREEN("Found Zarcanum kernel: amount: " << currency::print_money_brief(this->stake_amount) << ENDL << "difficulty: " << this->basic_diff << ENDL << "kernel info: " << ENDL << print_stake_kernel_info(this->sk) @@ -78,9 +78,8 @@ namespace currency << "lhs: 0x" << crypto::scalar_t(lhs).to_string_as_hex_number() << " = 0x" << std::hex << d_mp << " * 2^64 * " << this->stake_amount << " - 0x" << std::hex << ba << ENDL << "rhs: 0x" << crypto::scalar_t(rhs).to_string_as_hex_number() << ENDL << "d: 0x" << std::hex << d_mp << ENDL - << "l / floor(z * D): 0x" << std::hex << l_div_z_D + << "floor(l / z * D): 0x" << std::hex << l_div_z_D , LOG_LEVEL_0); - } } else From 97c3460af8700de1675d39ea40019c36b3dc5a01 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 20 Mar 2024 14:45:29 +0100 Subject: [PATCH 025/184] autodoc inital code + cmake warningns + improvements over compilation performance --- CMakeLists.txt | 9 +++++++-- .../include/net/http_server_handlers_map2.h | 17 +++++++++++++++-- .../serialization/keyvalue_serialization.h | 12 ++++++++---- .../keyvalue_serialization_overloads.h | 4 ++-- .../epee/include/storages/portable_storage.h | 12 ++++++------ contrib/zlib/CMakeLists.txt | 1 - src/CMakeLists.txt | 4 ++-- src/daemon/daemon.cpp | 2 ++ src/rpc/core_rpc_server_commands_defs.h | 5 +++-- tests/gtest/CMakeLists.txt | 5 ++++- utils/Directory.Build.props.in | 7 +++++++ 11 files changed, 56 insertions(+), 22 deletions(-) create mode 100644 utils/Directory.Build.props.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 9baf00a1..0666e592 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.5) +cmake_minimum_required(VERSION 3.16) PROJECT(Zano) @@ -18,6 +18,9 @@ endif() if(POLICY CMP0043) cmake_policy(SET CMP0074 NEW) endif() +if(POLICY CMP0144) + cmake_policy(SET CMP0144 NEW) +endif() set(CMAKE_CXX_STANDARD 17) @@ -122,6 +125,7 @@ if(MSVC) endforeach() endif() include_directories(SYSTEM src/platform/msc) + configure_file(utils/Directory.Build.props.in ${CMAKE_BINARY_DIR}/Directory.Build.props) else() set(ARCH default CACHE STRING "CPU to build for: -march value or default") if("${ARCH}" STREQUAL "default") @@ -258,8 +262,9 @@ elseif(NOT MSVC) endif() if(BUILD_GUI) - cmake_minimum_required(VERSION 3.1) find_package(Qt5Widgets REQUIRED) + find_package(Qt5WebEngineWidgets REQUIRED) + find_package(Qt5WebChannel REQUIRED) endif() set(COMMIT_ID_IN_VERSION ON CACHE BOOL "Include commit ID in version") diff --git a/contrib/epee/include/net/http_server_handlers_map2.h b/contrib/epee/include/net/http_server_handlers_map2.h index 3102cb2d..93fac55e 100644 --- a/contrib/epee/include/net/http_server_handlers_map2.h +++ b/contrib/epee/include/net/http_server_handlers_map2.h @@ -45,10 +45,23 @@ bool auto_doc_t(const std::string& prefix_name, std::string& generate_reference) if (!generate_reference.size()) return true; request_t req = get_documentation_json_struct(); response_t res = get_documentation_json_struct(); + + std::string req_str; + epee::serialization::portable_storage ps; + req.store(ps, nullptr, true); + ps.dump_as_json(req_str); + + + std::string res_str; + epee::serialization::portable_storage ps_res; + res.store(ps_res, nullptr, true); + ps_res.dump_as_json(res_str); + + std::stringstream ss; ss << prefix_name << ENDL - << "REQUEST: " << ENDL << epee::serialization::store_t_to_json(req) << ENDL << "--------------------------------" << ENDL - << "RESPONSE: " << ENDL << epee::serialization::store_t_to_json(res) << ENDL << "################################" << ENDL; + << "REQUEST: " << ENDL << req_str << ENDL << "--------------------------------" << ENDL + << "RESPONSE: " << ENDL << res_str << ENDL << "################################" << ENDL; generate_reference += ss.str(); return true; } diff --git a/contrib/epee/include/serialization/keyvalue_serialization.h b/contrib/epee/include/serialization/keyvalue_serialization.h index 31c90df7..033b12ca 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization.h +++ b/contrib/epee/include/serialization/keyvalue_serialization.h @@ -32,16 +32,16 @@ #include "keyvalue_helpers.h" #include "keyvalue_serialization_overloads.h" namespace epee -{ +{ /************************************************************************/ /* Serialize map declarations */ /************************************************************************/ #define BEGIN_KV_SERIALIZE_MAP() \ public: \ template \ - bool store(t_storage& st, typename t_storage::hsection hparent_section = nullptr) const\ + bool store(t_storage& st, typename t_storage::hsection hparent_section = nullptr, bool auto_doc_mode = false) const\ {\ - return serialize_map(*this, st, hparent_section); \ + return serialize_map(*this, st, hparent_section, auto_doc_mode); \ }\ template \ bool _load(t_storage& stg, typename t_storage::hsection hparent_section = nullptr)\ @@ -62,12 +62,15 @@ public: \ }\ }\ template \ - static bool serialize_map(this_type& this_ref, t_storage& stg, typename t_storage::hsection hparent_section) \ + static bool serialize_map(this_type& this_ref, t_storage& stg, typename t_storage::hsection hparent_section, bool auto_doc_mode = false) \ { #define KV_SERIALIZE_N(varialble, val_name) \ epee::serialization::selector::serialize(this_ref.varialble, stg, hparent_section, val_name); +#define KV_SERIALIZE_N_DOC(varialble, val_name, substitute) \ + epee::serialization::selector::serialize(this_ref.varialble, stg, hparent_section, val_name, auto_doc_mode, substitute); + #define KV_SERIALIZE_CUSTOM_N(varialble, stored_type, from_v_to_stored, from_stored_to_v, val_name) \ epee::serialization::selector::template serialize_custom(this_ref.varialble, stg, hparent_section, val_name, from_v_to_stored, from_stored_to_v); @@ -95,6 +98,7 @@ public: \ #define END_KV_SERIALIZE_MAP() return true;} #define KV_SERIALIZE(varialble) KV_SERIALIZE_N(varialble, #varialble) +#define KV_SERIALIZE_DOC(varialble, substitute) KV_SERIALIZE_N_DOC( varialble, #varialble, substitute) #define KV_SERIALIZE_VAL_POD_AS_BLOB(varialble) KV_SERIALIZE_VAL_POD_AS_BLOB_N(varialble, #varialble) #define KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE(varialble) KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(varialble, #varialble) //skip is_pod compile time check #define KV_SERIALIZE_CONTAINER_POD_AS_BLOB(varialble) KV_SERIALIZE_CONTAINER_POD_AS_BLOB_N(varialble, #varialble) diff --git a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h index c0d46af3..c79c56b2 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h +++ b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h @@ -315,9 +315,9 @@ namespace epee struct selector { template - static bool serialize(const t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname) + static bool serialize(const t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname, bool doc_mode = false, const t_type& doc_substitute = t_type()) { - return kv_serialize(d, stg, hparent_section, pname); + return kv_serialize( (doc_mode ? doc_substitute:d), stg, hparent_section, pname); } template diff --git a/contrib/epee/include/storages/portable_storage.h b/contrib/epee/include/storages/portable_storage.h index a5d46e19..0a8b8127 100644 --- a/contrib/epee/include/storages/portable_storage.h +++ b/contrib/epee/include/storages/portable_storage.h @@ -63,18 +63,18 @@ namespace epee //serial access for arrays of values -------------------------------------- //values template - harray get_first_value(const std::string& value_name, t_value& target, hsection hparent_section); + harray get_first_value(const std::string& value_name, t_value& target, hsection hparent_section); template bool get_next_value(harray hval_array, t_value& target); template - harray insert_first_value(const std::string& value_name, const t_value& target, hsection hparent_section); + harray insert_first_value(const std::string& value_name, const t_value& target, hsection hparent_section); template bool insert_next_value(harray hval_array, const t_value& target); //sections - harray get_first_section(const std::string& pSectionName, hsection& h_child_section, hsection hparent_section); - bool get_next_section(harray hSecArray, hsection& h_child_section); - harray insert_first_section(const std::string& pSectionName, hsection& hinserted_childsection, hsection hparent_section); - bool insert_next_section(harray hSecArray, hsection& hinserted_childsection); + harray get_first_section(const std::string& pSectionName, hsection& h_child_section, hsection hparent_section); + bool get_next_section(harray hSecArray, hsection& h_child_section); + harray insert_first_section(const std::string& pSectionName, hsection& hinserted_childsection, hsection hparent_section); + bool insert_next_section(harray hSecArray, hsection& hinserted_childsection); //------------------------------------------------------------------------ //delete entry (section, value or array) bool delete_entry(const std::string& pentry_name, hsection hparent_section = nullptr); diff --git a/contrib/zlib/CMakeLists.txt b/contrib/zlib/CMakeLists.txt index 696b9f52..97fd8bf4 100644 --- a/contrib/zlib/CMakeLists.txt +++ b/contrib/zlib/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.4.4) set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON) project(zlib C) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6b5ff732..200096f3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -196,10 +196,10 @@ if(BUILD_GUI) ENABLE_SHARED_PCH(Zano QTDAEMON) ENABLE_SHARED_PCH_EXECUTABLE(Zano) - QT5_USE_MODULES(Zano WebEngineWidgets WebChannel) + #QT5_USE_MODULES(Zano WebEngineWidgets WebChannel) find_package(Qt5PrintSupport REQUIRED) - target_link_libraries(Zano wallet rpc currency_core crypto common zlibstatic ethash Qt5::WebEngineWidgets Qt5::PrintSupport ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto) + target_link_libraries(Zano wallet rpc currency_core crypto common zlibstatic ethash Qt5::WebChannel Qt5::WebEngineWidgets Qt5::PrintSupport ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto) if (UNIX AND NOT APPLE) target_link_libraries(Zano rt) endif() diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index cb09bdb2..004da0b8 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -287,6 +287,8 @@ int main(int argc, char* argv[]) rpc_server.handle_http_request_map(query_info, response_info, conn_context, call_found, json_rpc_reference); LOG_PRINT_L0(generate_reference << ENDL << "----------------------------------------" << ENDL << json_rpc_reference); + + return 0; } bool res = false; diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index ca55f2d4..056b3bfe 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -149,12 +149,13 @@ namespace currency std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(height) - KV_SERIALIZE(status) + KV_SERIALIZE_DOC(height, uint64_t(11111)) + KV_SERIALIZE_DOC(status, std::string("OK")) END_KV_SERIALIZE_MAP() }; }; + template struct COMMAND_RPC_GET_BLOCKS_FAST_T { diff --git a/tests/gtest/CMakeLists.txt b/tests/gtest/CMakeLists.txt index ddd5443b..5b6e758e 100644 --- a/tests/gtest/CMakeLists.txt +++ b/tests/gtest/CMakeLists.txt @@ -9,6 +9,10 @@ # make it prominent in the GUI. option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)." OFF) +if(POLICY CMP0148) + cmake_policy(SET CMP0148 OLD) +endif() + # When other libraries are using a shared version of runtime libraries, # Google Test also has to use one. option( @@ -40,7 +44,6 @@ endif() # ${gtest_BINARY_DIR}. # Language "C" is required for find_package(Threads). project(gtest CXX C) -cmake_minimum_required(VERSION 2.6.2) if (COMMAND set_up_hermetic_build) set_up_hermetic_build() diff --git a/utils/Directory.Build.props.in b/utils/Directory.Build.props.in new file mode 100644 index 00000000..168abb6a --- /dev/null +++ b/utils/Directory.Build.props.in @@ -0,0 +1,7 @@ + + + + true + true + + From f15a8421f9f047e9a1bee9cfbc457b056e5e0616 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 20 Mar 2024 17:49:03 +0100 Subject: [PATCH 026/184] added call_wallet_rpc to avoid using of mw_select_wallet --- src/gui/qt-daemon/application/mainwindow.cpp | 20 ++++++++++++++++++++ src/gui/qt-daemon/application/mainwindow.h | 1 + 2 files changed, 21 insertions(+) diff --git a/src/gui/qt-daemon/application/mainwindow.cpp b/src/gui/qt-daemon/application/mainwindow.cpp index 0e3c974e..9f4f0313 100644 --- a/src/gui/qt-daemon/application/mainwindow.cpp +++ b/src/gui/qt-daemon/application/mainwindow.cpp @@ -301,6 +301,26 @@ QString MainWindow::call_rpc(const QString& params) return QString::fromStdString(response_info.m_body); CATCH_ENTRY_FAIL_API_RESPONCE(); } + +QString MainWindow::call_wallet_rpc(const QString& wallet_id_str, const QString& params) +{ + TRY_ENTRY(); + + if (!m_backend.is_core_initialized()) + { + epee::json_rpc::error_response rsp; + rsp.jsonrpc = "2.0"; + rsp.error.code = -1; + rsp.error.message = API_RETURN_CODE_CORE_BUSY; + return QString::fromStdString(epee::serialization::store_t_to_json(static_cast(rsp))); + } + + uint64_t wallet_id = std::stoull(wallet_id_str.toStdString()); + + return QString::fromStdString(m_backend.invoke(wallet_id, params.toStdString())); + CATCH_ENTRY_FAIL_API_RESPONCE(); +} + QString MainWindow::get_default_fee(const QString& param) { TRY_ENTRY(); diff --git a/src/gui/qt-daemon/application/mainwindow.h b/src/gui/qt-daemon/application/mainwindow.h index c2725682..c0df8862 100644 --- a/src/gui/qt-daemon/application/mainwindow.h +++ b/src/gui/qt-daemon/application/mainwindow.h @@ -198,6 +198,7 @@ public: QString request_dummy(const QString& param); QString call_rpc(const QString& params); + QString call_wallet_rpc(const QString& wallet_id, const QString& params); signals: void quit_requested(const QString str); From 921b447b0279b2a70124e891fa64ca3ff1679f1a Mon Sep 17 00:00:00 2001 From: sowle Date: Thu, 21 Mar 2024 10:48:11 +0100 Subject: [PATCH 027/184] p2p: block old clients (<2.x) on in and out conn + build version bump to 280 --- src/common/util.cpp | 8 ++------ src/p2p/net_node.inl | 2 +- src/version.h.in | 2 +- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/common/util.cpp b/src/common/util.cpp index f5d4baa9..1fdbe537 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -684,12 +684,8 @@ std::string get_nix_version_display_string() // got v_major, v_minor, v_revision - // allow 1.1.x and greater - - if (v_major < 1) - return false; - - if (v_major == 1 && v_minor < 1) + // allow 2.x and greater + if (v_major < 2) return false; return true; diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index 22c2e457..46a39ee5 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -525,7 +525,7 @@ namespace nodetool if (!tools::check_remote_client_version(rsp.payload_data.client_version)) { - LOG_ERROR_CCONTEXT("COMMAND_HANDSHAKE Failed, wrong client version: " << rsp.payload_data.client_version << ", closing connection."); + LOG_PRINT_CC_YELLOW(context, "COMMAND_HANDSHAKE Failed, wrong client version: " << rsp.payload_data.client_version << ", closing connection.", LOG_LEVEL_1); return; } diff --git a/src/version.h.in b/src/version.h.in index 997c9452..c6196432 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 272 +#define PROJECT_VERSION_BUILD_NO 280 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From 1f5c862168df6520f03ce80bc6865d6b33bb5cc8 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Thu, 21 Mar 2024 13:42:15 +0300 Subject: [PATCH 028/184] === build number: 279 -> 280 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index 49405629..c6196432 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 279 +#define PROJECT_VERSION_BUILD_NO 280 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From f13d3e7b35d2a295be3ce37ba96e0d37ba322df1 Mon Sep 17 00:00:00 2001 From: sowle Date: Thu, 21 Mar 2024 11:43:53 +0100 Subject: [PATCH 029/184] Merge branch 'master' into develop --- src/common/util.cpp | 8 ++------ src/p2p/net_node.inl | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/common/util.cpp b/src/common/util.cpp index f5d4baa9..1fdbe537 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -684,12 +684,8 @@ std::string get_nix_version_display_string() // got v_major, v_minor, v_revision - // allow 1.1.x and greater - - if (v_major < 1) - return false; - - if (v_major == 1 && v_minor < 1) + // allow 2.x and greater + if (v_major < 2) return false; return true; diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index 22c2e457..46a39ee5 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -525,7 +525,7 @@ namespace nodetool if (!tools::check_remote_client_version(rsp.payload_data.client_version)) { - LOG_ERROR_CCONTEXT("COMMAND_HANDSHAKE Failed, wrong client version: " << rsp.payload_data.client_version << ", closing connection."); + LOG_PRINT_CC_YELLOW(context, "COMMAND_HANDSHAKE Failed, wrong client version: " << rsp.payload_data.client_version << ", closing connection.", LOG_LEVEL_1); return; } From 8f68ef56e27e0caa77c0147067938a0803881479 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Thu, 21 Mar 2024 13:44:13 +0300 Subject: [PATCH 030/184] === build number: 280 -> 281 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index c6196432..d058a727 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 280 +#define PROJECT_VERSION_BUILD_NO 281 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From 919790e8080cffb1b7ff1e54bfddf74a572e4713 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 21 Mar 2024 14:31:40 +0100 Subject: [PATCH 031/184] some temporary commits --- .../keyvalue_serialization_overloads.h | 2 +- .../epee/include/storages/portable_storage.h | 16 ++-- .../portable_storage_extended_for_doc.h | 96 +++++++++++++++++++ src/gui/qt-daemon/layout | 2 +- utils/Directory.Build.props.in | 1 + 5 files changed, 109 insertions(+), 8 deletions(-) create mode 100644 contrib/epee/include/storages/portable_storage_extended_for_doc.h diff --git a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h index c79c56b2..42397206 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h +++ b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h @@ -315,7 +315,7 @@ namespace epee struct selector { template - static bool serialize(const t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname, bool doc_mode = false, const t_type& doc_substitute = t_type()) + static bool serialize(const t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname, bool doc_mode = false, const t_type& doc_substitute = t_type(), const std::string& description = std::string()) { return kv_serialize( (doc_mode ? doc_substitute:d), stg, hparent_section, pname); } diff --git a/contrib/epee/include/storages/portable_storage.h b/contrib/epee/include/storages/portable_storage.h index 0a8b8127..2b41cdfc 100644 --- a/contrib/epee/include/storages/portable_storage.h +++ b/contrib/epee/include/storages/portable_storage.h @@ -44,15 +44,19 @@ namespace epee /************************************************************************/ /* */ /************************************************************************/ - class portable_storage + template + class portable_storage_base { public: - typedef epee::serialization::hsection hsection; + //typedef epee::serialization::hsection hsection; + typedef t_section hasection; typedef epee::serialization::harray harray; typedef storage_entry meta_entry; - portable_storage(){} - virtual ~portable_storage(){} + portable_storage_base + (){} + virtual ~portable_storage_base + (){} hsection open_section(const std::string& section_name, hsection hparent_section, bool create_if_notexist = false); template bool get_value(const std::string& value_name, t_value& val, hsection hparent_section); @@ -107,8 +111,8 @@ namespace epee }; #pragma pack(pop) }; - inline - bool portable_storage::dump_as_json(std::string& buff, size_t indent /* = 0 */, end_of_line_t eol /* = eol_crlf */) + template + bool portable_storage_base::dump_as_json(std::string& buff, size_t indent /* = 0 */, end_of_line_t eol /* = eol_crlf */) { TRY_ENTRY(); std::stringstream ss; diff --git a/contrib/epee/include/storages/portable_storage_extended_for_doc.h b/contrib/epee/include/storages/portable_storage_extended_for_doc.h new file mode 100644 index 00000000..35de4c65 --- /dev/null +++ b/contrib/epee/include/storages/portable_storage_extended_for_doc.h @@ -0,0 +1,96 @@ +// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the Andrey N. Sabelnikov nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 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. +// + + + +#pragma once + +#include "portable_storage.h" + +namespace epee +{ + namespace serialization + { + /************************************************************************/ + /* */ + /************************************************************************/ + class portable_storage_extended: public portable_storage + { + public: + typedef epee::serialization::hsection hsection; + typedef epee::serialization::harray harray; + typedef storage_entry meta_entry; + + portable_storage_extended(){} + virtual ~portable_storage_extended(){} + hsection open_section(const std::string& section_name, hsection hparent_section, bool create_if_notexist = false); + template + bool get_value(const std::string& value_name, t_value& val, hsection hparent_section); + bool get_value(const std::string& value_name, storage_entry& val, hsection hparent_section); + template + bool set_value(const std::string& value_name, const t_value& target, hsection hparent_section); + + //serial access for arrays of values -------------------------------------- + //values + template + harray get_first_value(const std::string& value_name, t_value& target, hsection hparent_section); + template + bool get_next_value(harray hval_array, t_value& target); + template + harray insert_first_value(const std::string& value_name, const t_value& target, hsection hparent_section); + template + bool insert_next_value(harray hval_array, const t_value& target); + //sections + harray get_first_section(const std::string& pSectionName, hsection& h_child_section, hsection hparent_section); + bool get_next_section(harray hSecArray, hsection& h_child_section); + harray insert_first_section(const std::string& pSectionName, hsection& hinserted_childsection, hsection hparent_section); + bool insert_next_section(harray hSecArray, hsection& hinserted_childsection); + //------------------------------------------------------------------------ + //delete entry (section, value or array) + bool delete_entry(const std::string& pentry_name, hsection hparent_section = nullptr); + //------------------------------------------------------------------------------- + bool store_to_binary(binarybuffer& target); + bool load_from_binary(const binarybuffer& target); + template + bool dump_as_xml(std::string& targetObj, const std::string& root_name = ""); + bool dump_as_json(std::string& targetObj, size_t indent = 0, end_of_line_t eol = eol_crlf); + bool load_from_json(const std::string& source); + + template + bool enum_entries(hsection hparent_section, cb_t cb); + private: + section m_root; + hsection get_root_section() {return &m_root;} + storage_entry* find_storage_entry(const std::string& pentry_name, hsection psection); + template + storage_entry* insert_new_entry_get_storage_entry(const std::string& pentry_name, hsection psection, const entry_type& entry); + + hsection insert_new_section(const std::string& pentry_name, hsection psection); + }; + + //--------------------------------------------------------------------------------------------------------------- + } +} diff --git a/src/gui/qt-daemon/layout b/src/gui/qt-daemon/layout index d593aa34..f8e9556f 160000 --- a/src/gui/qt-daemon/layout +++ b/src/gui/qt-daemon/layout @@ -1 +1 @@ -Subproject commit d593aa3485395d7cc0415519dc1fc079de82e0ea +Subproject commit f8e9556fbaccd49841ce91afc3c90c8e3142ac95 diff --git a/utils/Directory.Build.props.in b/utils/Directory.Build.props.in index 168abb6a..5f263a21 100644 --- a/utils/Directory.Build.props.in +++ b/utils/Directory.Build.props.in @@ -3,5 +3,6 @@ true true + 11 From e11ee0fa073c28027c1575193800e0cb29b5f5fb Mon Sep 17 00:00:00 2001 From: sowle Date: Thu, 21 Mar 2024 19:52:18 +0100 Subject: [PATCH 032/184] tx_pool: remove HF4-incompatible txs on load --- src/currency_core/currency_core.cpp | 2 ++ src/currency_core/tx_pool.cpp | 21 +++++++++++++++++++++ src/currency_core/tx_pool.h | 2 ++ src/version.h.in | 2 +- 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/currency_core/currency_core.cpp b/src/currency_core/currency_core.cpp index 876c2d17..7658f4da 100644 --- a/src/currency_core/currency_core.cpp +++ b/src/currency_core/currency_core.cpp @@ -163,6 +163,8 @@ namespace currency r = m_blockchain_storage.init(m_config_folder, vm); CHECK_AND_ASSERT_MES(r, false, "Failed to initialize blockchain storage"); + m_mempool.remove_incompatible_txs(); + r = m_miner.init(vm); CHECK_AND_ASSERT_MES(r, false, "Failed to initialize miner"); diff --git a/src/currency_core/tx_pool.cpp b/src/currency_core/tx_pool.cpp index 94a69124..3acf108c 100644 --- a/src/currency_core/tx_pool.cpp +++ b/src/currency_core/tx_pool.cpp @@ -1293,6 +1293,27 @@ namespace currency return true; } //--------------------------------------------------------------------------------- + void tx_memory_pool::remove_incompatible_txs() + { + std::vector invalid_tx_ids; + + m_db_transactions.enumerate_items([&](uint64_t i, const crypto::hash& h, const tx_details &tx_entry) + { + if (!m_blockchain.validate_tx_for_hardfork_specific_terms(tx_entry.tx, h)) + invalid_tx_ids.push_back(h); + return true; + }); + + for(const auto& id : invalid_tx_ids) + { + transaction tx{}; + size_t blob_size = 0; + uint64_t fee = 0; + take_tx(id, tx, blob_size, fee); + LOG_PRINT_L0("tx " << id << " was incompatible with the hardfork rules and removed"); + } + } + //--------------------------------------------------------------------------------- bool tx_memory_pool::load_keyimages_cache() { CRITICAL_REGION_LOCAL(m_key_images_lock); diff --git a/src/currency_core/tx_pool.h b/src/currency_core/tx_pool.h index 4ede52a2..92d60604 100644 --- a/src/currency_core/tx_pool.h +++ b/src/currency_core/tx_pool.h @@ -138,6 +138,8 @@ namespace currency bool remove_stuck_transactions(); // made public to be called from coretests + void remove_incompatible_txs(); // made public to be called after the BCS is loaded and hardfork info is ready + private: bool on_tx_add(crypto::hash tx_id, const transaction& tx, bool kept_by_block); bool on_tx_remove(const crypto::hash &tx_id, const transaction& tx, bool kept_by_block); diff --git a/src/version.h.in b/src/version.h.in index c6196432..6bfc64f8 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 280 +#define PROJECT_VERSION_BUILD_NO 282 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From 2283a77104151f246f7710c202985b68923ee465 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 21 Mar 2024 22:57:55 +0100 Subject: [PATCH 033/184] more work on json/descriptions improvements --- .../include/net/http_server_handlers_map2.h | 9 +- .../serialization/keyvalue_serialization.h | 6 +- .../keyvalue_serialization_overloads.h | 1 + .../epee/include/storages/portable_storage.h | 133 ++++---- .../include/storages/portable_storage_base.h | 1 + .../portable_storage_extended_for_doc.h | 64 +--- .../portable_storage_template_helper.h | 4 +- .../storages/portable_storage_to_json.h | 321 ++++++++++-------- .../currency_protocol_defs_print.h | 2 +- src/rpc/core_rpc_server_commands_defs.h | 4 +- 10 files changed, 280 insertions(+), 265 deletions(-) diff --git a/contrib/epee/include/net/http_server_handlers_map2.h b/contrib/epee/include/net/http_server_handlers_map2.h index 93fac55e..50ab3e30 100644 --- a/contrib/epee/include/net/http_server_handlers_map2.h +++ b/contrib/epee/include/net/http_server_handlers_map2.h @@ -30,6 +30,7 @@ #include "storages/portable_storage_template_helper.h" #include "http_base.h" #include "net/net_utils_base.h" +#include "storages/portable_storage_extended_for_doc.h" @@ -47,15 +48,19 @@ bool auto_doc_t(const std::string& prefix_name, std::string& generate_reference) response_t res = get_documentation_json_struct(); std::string req_str; - epee::serialization::portable_storage ps; + std::string req_str_descr; + epee::serialization::portable_storage_extended_doc ps; req.store(ps, nullptr, true); ps.dump_as_json(req_str); + ps.dump_as_decriptions(req_str_descr); std::string res_str; - epee::serialization::portable_storage ps_res; + std::string res_str_descr; + epee::serialization::portable_storage_extended_doc ps_res; res.store(ps_res, nullptr, true); ps_res.dump_as_json(res_str); + ps_res.dump_as_decriptions(res_str_descr); std::stringstream ss; diff --git a/contrib/epee/include/serialization/keyvalue_serialization.h b/contrib/epee/include/serialization/keyvalue_serialization.h index 033b12ca..e510f30a 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization.h +++ b/contrib/epee/include/serialization/keyvalue_serialization.h @@ -68,8 +68,8 @@ public: \ #define KV_SERIALIZE_N(varialble, val_name) \ epee::serialization::selector::serialize(this_ref.varialble, stg, hparent_section, val_name); -#define KV_SERIALIZE_N_DOC(varialble, val_name, substitute) \ - epee::serialization::selector::serialize(this_ref.varialble, stg, hparent_section, val_name, auto_doc_mode, substitute); +#define KV_SERIALIZE_N_DOC(varialble, val_name, substitute, description) \ + epee::serialization::selector::serialize(this_ref.varialble, stg, hparent_section, val_name, auto_doc_mode, substitute, description); #define KV_SERIALIZE_CUSTOM_N(varialble, stored_type, from_v_to_stored, from_stored_to_v, val_name) \ epee::serialization::selector::template serialize_custom(this_ref.varialble, stg, hparent_section, val_name, from_v_to_stored, from_stored_to_v); @@ -98,7 +98,7 @@ public: \ #define END_KV_SERIALIZE_MAP() return true;} #define KV_SERIALIZE(varialble) KV_SERIALIZE_N(varialble, #varialble) -#define KV_SERIALIZE_DOC(varialble, substitute) KV_SERIALIZE_N_DOC( varialble, #varialble, substitute) +#define KV_SERIALIZE_DOC(varialble, substitute, description) KV_SERIALIZE_N_DOC( varialble, #varialble, substitute, description) #define KV_SERIALIZE_VAL_POD_AS_BLOB(varialble) KV_SERIALIZE_VAL_POD_AS_BLOB_N(varialble, #varialble) #define KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE(varialble) KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(varialble, #varialble) //skip is_pod compile time check #define KV_SERIALIZE_CONTAINER_POD_AS_BLOB(varialble) KV_SERIALIZE_CONTAINER_POD_AS_BLOB_N(varialble, #varialble) diff --git a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h index 42397206..9123fe6f 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h +++ b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h @@ -317,6 +317,7 @@ namespace epee template static bool serialize(const t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname, bool doc_mode = false, const t_type& doc_substitute = t_type(), const std::string& description = std::string()) { + stg.set_entry_description(hparent_section, pname, description); return kv_serialize( (doc_mode ? doc_substitute:d), stg, hparent_section, pname); } diff --git a/contrib/epee/include/storages/portable_storage.h b/contrib/epee/include/storages/portable_storage.h index 2b41cdfc..0eed742b 100644 --- a/contrib/epee/include/storages/portable_storage.h +++ b/contrib/epee/include/storages/portable_storage.h @@ -49,7 +49,7 @@ namespace epee { public: //typedef epee::serialization::hsection hsection; - typedef t_section hasection; + typedef t_section* hsection; typedef epee::serialization::harray harray; typedef storage_entry meta_entry; @@ -87,12 +87,13 @@ namespace epee bool load_from_binary(const binarybuffer& target); template bool dump_as_xml(std::string& targetObj, const std::string& root_name = ""); - bool dump_as_json(std::string& targetObj, size_t indent = 0, end_of_line_t eol = eol_crlf); + bool dump_as_json(std::string& targetObj, size_t indent = 0/*, end_of_line_t eol = eol_crlf*/); bool load_from_json(const std::string& source); + void set_entry_description(hsection hparent_section, const std::string& name, const std::string& description) {} template bool enum_entries(hsection hparent_section, cb_t cb); - private: + protected: section m_root; hsection get_root_section() {return &m_root;} storage_entry* find_storage_entry(const std::string& pentry_name, hsection psection); @@ -111,32 +112,36 @@ namespace epee }; #pragma pack(pop) }; + + template - bool portable_storage_base::dump_as_json(std::string& buff, size_t indent /* = 0 */, end_of_line_t eol /* = eol_crlf */) + bool portable_storage_base::dump_as_json(std::string& buff, size_t indent /* = 0 *//*, end_of_line_t eol *//* = eol_crlf */) { TRY_ENTRY(); std::stringstream ss; - epee::serialization::dump_as_json(ss, m_root, indent, eol); + epee::serialization::recursive_visitor::dump_as_(ss, m_root, indent/*, eol*/); buff = ss.str(); return true; - CATCH_ENTRY("portable_storage::dump_as_json", false) + CATCH_ENTRY("portable_storage_base::dump_as_json", false) } - inline - bool portable_storage::load_from_json(const std::string& source) + + template + bool portable_storage_base::load_from_json(const std::string& source) { TRY_ENTRY(); return json::load_from_json(source, *this); - CATCH_ENTRY("portable_storage::load_from_json", false) + CATCH_ENTRY("portable_storage_base::load_from_json", false) } + template template - bool portable_storage::dump_as_xml(std::string& targetObj, const std::string& root_name) + bool portable_storage_base::dump_as_xml(std::string& targetObj, const std::string& root_name) { return false;//TODO: don't think i ever again will use xml - ambiguous and "overtagged" format } - inline - bool portable_storage::store_to_binary(binarybuffer& target) + template + bool portable_storage_base::store_to_binary(binarybuffer& target) { TRY_ENTRY(); std::stringstream ss; @@ -148,10 +153,10 @@ namespace epee pack_entry_to_buff(ss, m_root); target = ss.str(); return true; - CATCH_ENTRY("portable_storage::store_to_binary", false) + CATCH_ENTRY("portable_storage_base::store_to_binary", false) } - inline - bool portable_storage::load_from_binary(const binarybuffer& source) + template + bool portable_storage_base::load_from_binary(const binarybuffer& source) { m_root.m_entries.clear(); if(source.size() < sizeof(storage_block_header)) @@ -176,11 +181,11 @@ namespace epee throwable_buffer_reader buf_reader(source.data()+sizeof(storage_block_header), source.size()-sizeof(storage_block_header)); buf_reader.read(m_root); return true;//TODO: - CATCH_ENTRY("portable_storage::load_from_binary", false); + CATCH_ENTRY("portable_storage_base::load_from_binary", false); } //--------------------------------------------------------------------------------------------------------------- - inline - hsection portable_storage::open_section(const std::string& section_name, hsection hparent_section, bool create_if_notexist) + template + typename portable_storage_base::hsection portable_storage_base::open_section(const std::string& section_name, hsection hparent_section, bool create_if_notexist) { TRY_ENTRY(); hparent_section = hparent_section ? hparent_section:&m_root; @@ -201,7 +206,7 @@ namespace epee return nullptr; } return &boost::get
(*pentry); - CATCH_ENTRY("portable_storage::open_section", nullptr); + CATCH_ENTRY("portable_storage_base::open_section", nullptr); } //--------------------------------------------------------------------------------------------------------------- template @@ -213,8 +218,9 @@ namespace epee void operator()(const from_type& v){convert_t(v, m_target);} }; + template template - bool portable_storage::get_value(const std::string& value_name, t_value& val, hsection hparent_section) + bool portable_storage_base::get_value(const std::string& value_name, t_value& val, hsection hparent_section) { BOOST_MPL_ASSERT(( boost::mpl::contains )); //TRY_ENTRY(); @@ -226,11 +232,11 @@ namespace epee get_value_visitor gvv(val); boost::apply_visitor(gvv, *pentry); return true; - //CATCH_ENTRY("portable_storage::template<>get_value", false); + //CATCH_ENTRY("portable_storage_base::template<>get_value", false); } //--------------------------------------------------------------------------------------------------------------- - inline - bool portable_storage::get_value(const std::string& value_name, storage_entry& val, hsection hparent_section) + template + bool portable_storage_base::get_value(const std::string& value_name, storage_entry& val, hsection hparent_section) { //TRY_ENTRY(); if(!hparent_section) hparent_section = &m_root; @@ -240,11 +246,12 @@ namespace epee val = *pentry; return true; - //CATCH_ENTRY("portable_storage::template<>get_value", false); + //CATCH_ENTRY("portable_storage_base::template<>get_value", false); } //--------------------------------------------------------------------------------------------------------------- + template template - bool portable_storage::set_value(const std::string& value_name, const t_value& v, hsection hparent_section) + bool portable_storage_base::set_value(const std::string& value_name, const t_value& v, hsection hparent_section) { BOOST_MPL_ASSERT(( boost::mpl::contains::type, t_value> )); TRY_ENTRY(); @@ -260,11 +267,11 @@ namespace epee } *pentry = storage_entry(v); return true; - CATCH_ENTRY("portable_storage::template<>set_value", false); + CATCH_ENTRY("portable_storage_base::template<>set_value", false); } //--------------------------------------------------------------------------------------------------------------- - inline - storage_entry* portable_storage::find_storage_entry(const std::string& pentry_name, hsection psection) + template + storage_entry* portable_storage_base::find_storage_entry(const std::string& pentry_name, hsection psection) { TRY_ENTRY(); CHECK_AND_ASSERT(psection, nullptr); @@ -273,27 +280,28 @@ namespace epee return nullptr; return &it->second; - CATCH_ENTRY("portable_storage::find_storage_entry", nullptr); + CATCH_ENTRY("portable_storage_base::find_storage_entry", nullptr); } //--------------------------------------------------------------------------------------------------------------- + template template - storage_entry* portable_storage::insert_new_entry_get_storage_entry(const std::string& pentry_name, hsection psection, const entry_type& entry) + storage_entry* portable_storage_base::insert_new_entry_get_storage_entry(const std::string& pentry_name, hsection psection, const entry_type& entry) { TRY_ENTRY(); CHECK_AND_ASSERT(psection, nullptr); auto ins_res = psection->m_entries.insert(std::pair(pentry_name, entry)); return &ins_res.first->second; - CATCH_ENTRY("portable_storage::insert_new_entry_get_storage_entry", nullptr); + CATCH_ENTRY("portable_storage_base::insert_new_entry_get_storage_entry", nullptr); } //--------------------------------------------------------------------------------------------------------------- - inline - hsection portable_storage::insert_new_section(const std::string& pentry_name, hsection psection) + template + typename portable_storage_base::hsection portable_storage_base::insert_new_section(const std::string& pentry_name, hsection psection) { TRY_ENTRY(); storage_entry* pse = insert_new_entry_get_storage_entry(pentry_name, psection, section()); if(!pse) return nullptr; return &boost::get
(*pse); - CATCH_ENTRY("portable_storage::insert_new_section", nullptr); + CATCH_ENTRY("portable_storage_base::insert_new_section", nullptr); } //--------------------------------------------------------------------------------------------------------------- template @@ -312,8 +320,9 @@ namespace epee } }; //--------------------------------------------------------------------------------------------------------------- + template template - harray portable_storage::get_first_value(const std::string& value_name, t_value& target, hsection hparent_section) + harray portable_storage_base::get_first_value(const std::string& value_name, t_value& target, hsection hparent_section) { BOOST_MPL_ASSERT(( boost::mpl::contains )); //TRY_ENTRY(); @@ -329,7 +338,7 @@ namespace epee if(!boost::apply_visitor(gfv, ar_entry)) return nullptr; return &ar_entry; - //CATCH_ENTRY("portable_storage::get_first_value", nullptr); + //CATCH_ENTRY("portable_storage_base::get_first_value", nullptr); } //--------------------------------------------------------------------------------------------------------------- template @@ -348,10 +357,10 @@ namespace epee return true; } }; - - + //--------------------------------------------------------------------------------------------------------------- + template template - bool portable_storage::get_next_value(harray hval_array, t_value& target) + bool portable_storage_base::get_next_value(harray hval_array, t_value& target) { BOOST_MPL_ASSERT(( boost::mpl::contains )); //TRY_ENTRY(); @@ -361,11 +370,12 @@ namespace epee if(!boost::apply_visitor(gnv, ar_entry)) return false; return true; - //CATCH_ENTRY("portable_storage::get_next_value", false); + //CATCH_ENTRY("portable_storage_base::get_next_value", false); } //--------------------------------------------------------------------------------------------------------------- + template template - harray portable_storage::insert_first_value(const std::string& value_name, const t_value& target, hsection hparent_section) + harray portable_storage_base::insert_first_value(const std::string& value_name, const t_value& target, hsection hparent_section) { TRY_ENTRY(); if(!hparent_section) hparent_section = &m_root; @@ -386,11 +396,12 @@ namespace epee array_entry_t& arr_typed = boost::get >(arr); arr_typed.insert_first_val(target); return &arr; - CATCH_ENTRY("portable_storage::insert_first_value", nullptr); + CATCH_ENTRY("portable_storage_base::insert_first_value", nullptr); } //--------------------------------------------------------------------------------------------------------------- + template template - bool portable_storage::enum_entries(hsection hparent_section, cb_t cb) + bool portable_storage_base::enum_entries(hsection hparent_section, cb_t cb) { TRY_ENTRY(); if (!hparent_section) hparent_section = &m_root; @@ -400,11 +411,12 @@ namespace epee break; } return true; - CATCH_ENTRY("portable_storage::enum_entries", false); + CATCH_ENTRY("portable_storage_base::enum_entries", false); } - + //--------------------------------------------------------------------------------------------------------------- + template template - bool portable_storage::insert_next_value(harray hval_array, const t_value& target) + bool portable_storage_base::insert_next_value(harray hval_array, const t_value& target) { TRY_ENTRY(); CHECK_AND_ASSERT(hval_array, false); @@ -415,12 +427,12 @@ namespace epee array_entry_t& arr_typed = boost::get >(*hval_array); arr_typed.insert_next_value(target); return true; - CATCH_ENTRY("portable_storage::insert_next_value", false); + CATCH_ENTRY("portable_storage_base::insert_next_value", false); } //--------------------------------------------------------------------------------------------------------------- //sections - inline - harray portable_storage::get_first_section(const std::string& sec_name, hsection& h_child_section, hsection hparent_section) + template + harray portable_storage_base::get_first_section(const std::string& sec_name, hsection& h_child_section, hsection hparent_section) { TRY_ENTRY(); if(!hparent_section) hparent_section = &m_root; @@ -438,11 +450,11 @@ namespace epee return nullptr; h_child_section = psec; return &ar_entry; - CATCH_ENTRY("portable_storage::get_first_section", nullptr); + CATCH_ENTRY("portable_storage_base::get_first_section", nullptr); } //--------------------------------------------------------------------------------------------------------------- - inline - bool portable_storage::get_next_section(harray hsec_array, hsection& h_child_section) + template + bool portable_storage_base::get_next_section(harray hsec_array, hsection& h_child_section) { TRY_ENTRY(); CHECK_AND_ASSERT(hsec_array, false); @@ -453,11 +465,11 @@ namespace epee if(!h_child_section) return false; return true; - CATCH_ENTRY("portable_storage::get_next_section", false); + CATCH_ENTRY("portable_storage_base::get_next_section", false); } //--------------------------------------------------------------------------------------------------------------- - inline - harray portable_storage::insert_first_section(const std::string& sec_name, hsection& hinserted_childsection, hsection hparent_section) + template + harray portable_storage_base::insert_first_section(const std::string& sec_name, hsection& hinserted_childsection, hsection hparent_section) { TRY_ENTRY(); if(!hparent_section) hparent_section = &m_root; @@ -478,11 +490,11 @@ namespace epee array_entry_t
& sec_array = boost::get>(ar_entry); hinserted_childsection = &sec_array.insert_first_val(section()); return &ar_entry; - CATCH_ENTRY("portable_storage::insert_first_section", nullptr); + CATCH_ENTRY("portable_storage_base::insert_first_section", nullptr); } //--------------------------------------------------------------------------------------------------------------- - inline - bool portable_storage::insert_next_section(harray hsec_array, hsection& hinserted_childsection) + template + bool portable_storage_base::insert_next_section(harray hsec_array, hsection& hinserted_childsection) { TRY_ENTRY(); CHECK_AND_ASSERT(hsec_array, false); @@ -492,8 +504,9 @@ namespace epee array_entry_t
& sec_array = boost::get>(*hsec_array); hinserted_childsection = &sec_array.insert_next_value(section()); return true; - CATCH_ENTRY("portable_storage::insert_next_section", false); + CATCH_ENTRY("portable_storage_base::insert_next_section", false); } - //--------------------------------------------------------------------------------------------------------------- + //--------------------------------------------------------------------------------------------------------------- + typedef portable_storage_base
portable_storage; } } diff --git a/contrib/epee/include/storages/portable_storage_base.h b/contrib/epee/include/storages/portable_storage_base.h index 99c792e5..2f2ed5d1 100644 --- a/contrib/epee/include/storages/portable_storage_base.h +++ b/contrib/epee/include/storages/portable_storage_base.h @@ -153,6 +153,7 @@ namespace epee /************************************************************************/ struct section { + std::map m_descriptions; std::map m_entries; }; diff --git a/contrib/epee/include/storages/portable_storage_extended_for_doc.h b/contrib/epee/include/storages/portable_storage_extended_for_doc.h index 35de4c65..81e70ed9 100644 --- a/contrib/epee/include/storages/portable_storage_extended_for_doc.h +++ b/contrib/epee/include/storages/portable_storage_extended_for_doc.h @@ -37,60 +37,28 @@ namespace epee /************************************************************************/ /* */ /************************************************************************/ - class portable_storage_extended: public portable_storage + class portable_storage_extended_doc: public portable_storage { public: - typedef epee::serialization::hsection hsection; - typedef epee::serialization::harray harray; - typedef storage_entry meta_entry; + void set_entry_description(hsection hparent_section, const std::string& name, const std::string& description) + { + if (!hparent_section) + hparent_section = &m_root; + hparent_section->m_descriptions[name] = description; + } - portable_storage_extended(){} - virtual ~portable_storage_extended(){} - hsection open_section(const std::string& section_name, hsection hparent_section, bool create_if_notexist = false); - template - bool get_value(const std::string& value_name, t_value& val, hsection hparent_section); - bool get_value(const std::string& value_name, storage_entry& val, hsection hparent_section); - template - bool set_value(const std::string& value_name, const t_value& target, hsection hparent_section); + bool dump_as_decriptions(std::string& buff, size_t indent = 0 , end_of_line_t eol = eol_crlf) + { + TRY_ENTRY(); + std::stringstream ss; - //serial access for arrays of values -------------------------------------- - //values - template - harray get_first_value(const std::string& value_name, t_value& target, hsection hparent_section); - template - bool get_next_value(harray hval_array, t_value& target); - template - harray insert_first_value(const std::string& value_name, const t_value& target, hsection hparent_section); - template - bool insert_next_value(harray hval_array, const t_value& target); - //sections - harray get_first_section(const std::string& pSectionName, hsection& h_child_section, hsection hparent_section); - bool get_next_section(harray hSecArray, hsection& h_child_section); - harray insert_first_section(const std::string& pSectionName, hsection& hinserted_childsection, hsection hparent_section); - bool insert_next_section(harray hSecArray, hsection& hinserted_childsection); - //------------------------------------------------------------------------ - //delete entry (section, value or array) - bool delete_entry(const std::string& pentry_name, hsection hparent_section = nullptr); - //------------------------------------------------------------------------------- - bool store_to_binary(binarybuffer& target); - bool load_from_binary(const binarybuffer& target); - template - bool dump_as_xml(std::string& targetObj, const std::string& root_name = ""); - bool dump_as_json(std::string& targetObj, size_t indent = 0, end_of_line_t eol = eol_crlf); - bool load_from_json(const std::string& source); + //epee::serialization::dump_as_descriptions(ss, m_root, indent, eol); + buff = ss.str(); + return true; + CATCH_ENTRY("portable_storage_base::dump_as_json", false) + } - template - bool enum_entries(hsection hparent_section, cb_t cb); - private: - section m_root; - hsection get_root_section() {return &m_root;} - storage_entry* find_storage_entry(const std::string& pentry_name, hsection psection); - template - storage_entry* insert_new_entry_get_storage_entry(const std::string& pentry_name, hsection psection, const entry_type& entry); - - hsection insert_new_section(const std::string& pentry_name, hsection psection); }; - //--------------------------------------------------------------------------------------------------------------- } } diff --git a/contrib/epee/include/storages/portable_storage_template_helper.h b/contrib/epee/include/storages/portable_storage_template_helper.h index 896f9eb2..841a094a 100644 --- a/contrib/epee/include/storages/portable_storage_template_helper.h +++ b/contrib/epee/include/storages/portable_storage_template_helper.h @@ -56,11 +56,11 @@ namespace epee } //----------------------------------------------------------------------------------------------------------- template - bool store_t_to_json(const t_struct& str_in, std::string& json_buff, size_t indent = 0, end_of_line_t eol = eol_crlf) + bool store_t_to_json(const t_struct& str_in, std::string& json_buff, size_t indent = 0/*, end_of_line_t eol = eol_crlf*/) { portable_storage ps; str_in.store(ps); - ps.dump_as_json(json_buff, indent, eol); + ps.dump_as_json(json_buff, indent/*, eol*/); return true; } //----------------------------------------------------------------------------------------------------------- diff --git a/contrib/epee/include/storages/portable_storage_to_json.h b/contrib/epee/include/storages/portable_storage_to_json.h index 1e2d5d97..a118e755 100644 --- a/contrib/epee/include/storages/portable_storage_to_json.h +++ b/contrib/epee/include/storages/portable_storage_to_json.h @@ -35,169 +35,196 @@ namespace epee { namespace serialization { - - template - void dump_as_json(t_stream& strm, const array_entry& ae, size_t indent, end_of_line_t eol = eol_crlf); - template - void dump_as_json(t_stream& strm, const storage_entry& se, size_t indent, end_of_line_t eol = eol_crlf); - template - void dump_as_json(t_stream& strm, const std::string& v, size_t indent, end_of_line_t eol = eol_crlf); - template - void dump_as_json(t_stream& strm, const int8_t& v, size_t indent, end_of_line_t eol = eol_crlf); - template - void dump_as_json(t_stream& strm, const uint8_t& v, size_t indent, end_of_line_t eol = eol_crlf); - template - void dump_as_json(t_stream& strm, const bool& v, size_t indent, end_of_line_t eol = eol_crlf); - template - void dump_as_json(t_stream& strm, const double& v, size_t indent, end_of_line_t eol = eol_crlf); - template - void dump_as_json(t_stream& strm, const t_type& v, size_t indent, end_of_line_t eol = eol_crlf); - template - void dump_as_json(t_stream& strm, const section& sec, size_t indent, end_of_line_t eol = eol_crlf); - + inline const char* get_endline(end_of_line_t eol) + { + switch (eol) + { + case eol_lf: return "\n"; + case eol_cr: return "\r"; + case eol_space: return " "; + default: return "\r\n"; + } + } inline std::string make_indent(size_t indent) { - return std::string(indent*2, ' '); + return std::string(indent * 2, ' '); } - template - struct array_entry_store_to_json_visitor: public boost::static_visitor + class strategy_json { - t_stream& m_strm; - size_t m_indent; - end_of_line_t m_eol; - - array_entry_store_to_json_visitor(t_stream& strm, size_t indent, end_of_line_t eol) - : m_strm(strm) - , m_indent(indent) - , m_eol(eol) - {} - - template - void operator()(const array_entry_t& a) + public: + inline static const char* eol = get_endline(eol_crlf); + //static const end_of_line_t eol = eol_crlf; + template + static void handle_value(t_stream& strm, const std::string& v, size_t indent) { - m_strm << "["; - if(a.m_array.size()) + strm << "\"" << misc_utils::parse::transform_to_json_escape_sequence(v) << "\""; + } + template + static void handle_value(t_stream& strm, const int8_t& v, size_t indent) + { + strm << static_cast(v); + } + template + static void handle_value(t_stream& strm, const uint8_t& v, size_t indent) + { + strm << static_cast(v); + } + template + static void handle_value(t_stream& strm, const bool& v, size_t indent) + { + if (v) + strm << "true"; + else + strm << "false"; + } + template + static void handle_value(t_stream& strm, const double& v, size_t indent) + { + boost::io::ios_flags_saver ifs(strm); + strm.precision(8); + strm << std::fixed << v; + } + template + static void handle_value(t_stream& strm, const t_type& v, size_t indent) + { + strm << v; + } + + template + static void handle_array_start(t_stream& strm, size_t indent) + { + strm << "["; + } + + template + static void handle_array_end(t_stream& strm, size_t indent) + { + strm << "]"; + } + + template + static void handle_obj_begin(t_stream& strm, size_t indent) + { + strm << "{"; + } + + template + static void handle_obj_end(t_stream& strm, size_t indent) + { + strm << "}"; + } + + template + static void handle_print_key(t_stream& strm, const std::string& key, size_t indent) + { + const std::string indent_str = make_indent(indent); + strm << indent_str << "\"" << misc_utils::parse::transform_to_json_escape_sequence(key) << "\"" << ": "; + } + + + + }; + + + template + class recursive_visitor + { + public: + template + struct array_entry_store_to_json_visitor : public boost::static_visitor + { + t_stream& m_strm; + size_t m_indent; + + array_entry_store_to_json_visitor(t_stream& strm, size_t indent) + : m_strm(strm) + , m_indent(indent) + {} + + template + void operator()(const array_entry_t& a) { - auto last_it = --a.m_array.end(); - for(auto it = a.m_array.begin(); it != a.m_array.end(); it++) + + t_strategy_layout_strategy::handle_array_start(m_strm, m_indent); + if (a.m_array.size()) { - dump_as_json(m_strm, *it, m_indent, m_eol); - if(it != last_it) - m_strm << ","; + auto last_it = --a.m_array.end(); + for (auto it = a.m_array.begin(); it != a.m_array.end(); it++) + { + dump_as_(m_strm, *it, m_indent); + if (it != last_it) + m_strm << ","; + } } - } - m_strm << "]"; - } - }; - - template - struct storage_entry_store_to_json_visitor: public boost::static_visitor - { - t_stream& m_strm; - size_t m_indent; - end_of_line_t m_eol; - - storage_entry_store_to_json_visitor(t_stream& strm, size_t indent, end_of_line_t eol) - : m_strm(strm) - , m_indent(indent) - , m_eol(eol) - {} - - //section, array_entry - template - void operator()(const visited_type& v) - { - dump_as_json(m_strm, v, m_indent, m_eol); - } - }; - - template - void dump_as_json(t_stream& strm, const array_entry& ae, size_t indent, end_of_line_t eol) - { - array_entry_store_to_json_visitor aesv(strm, indent, eol); - boost::apply_visitor(aesv, ae); - } - - template - void dump_as_json(t_stream& strm, const storage_entry& se, size_t indent, end_of_line_t eol) - { - storage_entry_store_to_json_visitor sv(strm, indent, eol); - boost::apply_visitor(sv, se); - } - - template - void dump_as_json(t_stream& strm, const std::string& v, size_t indent, end_of_line_t eol) - { - strm << "\"" << misc_utils::parse::transform_to_json_escape_sequence(v) << "\""; - } - - template - void dump_as_json(t_stream& strm, const int8_t& v, size_t indent, end_of_line_t eol) - { - strm << static_cast(v); - } - - template - void dump_as_json(t_stream& strm, const uint8_t& v, size_t indent, end_of_line_t eol) - { - strm << static_cast(v); - } - - template - void dump_as_json(t_stream& strm, const bool& v, size_t indent, end_of_line_t eol) - { - if(v) - strm << "true"; - else - strm << "false"; - } - - template - void dump_as_json(t_stream& strm, const double& v, size_t indent, end_of_line_t eol) - { - boost::io::ios_flags_saver ifs(strm); - strm.precision(8); - strm << std::fixed << v; - } - - template - void dump_as_json(t_stream& strm, const t_type& v, size_t indent, end_of_line_t eol) - { - strm << v; - } - - template - void dump_as_json(t_stream& strm, const section& sec, size_t indent, end_of_line_t eol) - { - auto put_eol = [&]() { - switch (eol) - { - case eol_lf: strm << "\n"; break; - case eol_cr: strm << "\r"; break; - case eol_space: strm << " "; break; - default: strm << "\r\n"; break; + t_strategy_layout_strategy::handle_array_end(m_strm, m_indent); } }; - size_t local_indent = indent + 1; - strm << "{"; - put_eol(); - std::string indent_str = make_indent(local_indent); - if(sec.m_entries.size()) + template + struct storage_entry_store_to_json_visitor : public boost::static_visitor { - auto it_last = --sec.m_entries.end(); - for(auto it = sec.m_entries.begin(); it!= sec.m_entries.end();it++) + t_stream& m_strm; + size_t m_indent; + + storage_entry_store_to_json_visitor(t_stream& strm, size_t indent) + : m_strm(strm) + , m_indent(indent) + {} + + //section, array_entry + template + void operator()(const visited_type& v) { - strm << indent_str << "\"" << misc_utils::parse::transform_to_json_escape_sequence(it->first) << "\"" << ": "; - dump_as_json(strm, it->second, local_indent, eol); - if(it_last != it) - strm << ","; - put_eol(); + dump_as_(m_strm, v, m_indent); } + }; + + template + void static dump_as_(t_stream& strm, const array_entry& ae, size_t indent) + { + array_entry_store_to_json_visitor aesv(strm, indent); + boost::apply_visitor(aesv, ae); } - strm << make_indent(indent) << "}"; - } + + template + void static dump_as_(t_stream& strm, const storage_entry& se, size_t indent) + { + storage_entry_store_to_json_visitor sv(strm, indent); + boost::apply_visitor(sv, se); + } + + template + void static dump_as_(t_stream& strm, const t_type& v, size_t indent) + { + t_strategy_layout_strategy::handle_value(strm, v, indent); + } + + template + void static dump_as_(t_stream& strm, const section& sec, size_t indent) + { + + + size_t local_indent = indent + 1; + t_strategy_layout_strategy::handle_obj_begin(strm, indent); + put_eol(); + + if (sec.m_entries.size()) + { + auto it_last = --sec.m_entries.end(); + for (auto it = sec.m_entries.begin(); it != sec.m_entries.end(); it++) + { + t_strategy_layout_strategy::handle_print_key(strm, it->first, local_indent); + dump_as_(strm, it->second, local_indent/*, eol*/); + if (it_last != it) + strm << ","; + put_eol(); + } + } + t_strategy_layout_strategy::handle_obj_end(strm, indent); + } + }; + } } diff --git a/src/currency_protocol/currency_protocol_defs_print.h b/src/currency_protocol/currency_protocol_defs_print.h index 68f6fa4b..023ed305 100644 --- a/src/currency_protocol/currency_protocol_defs_print.h +++ b/src/currency_protocol/currency_protocol_defs_print.h @@ -57,7 +57,7 @@ namespace currency std::stringstream ss; ss << "\"blocks\":{" << ENDL << print_complete_block_entry_list(v.blocks) << ENDL << "}, " << ENDL; ss << "\"missed_ids\":" << ENDL; - ::epee::serialization::dump_as_json(ss, v.missed_ids, 2); + ::epee::serialization::recursive_visitor<::epee::serialization::strategy_json>::dump_as_(ss, v.missed_ids, 2); ss << ENDL << "\"current_blockchain_height\":" << v.current_blockchain_height; return ss.str(); } diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 056b3bfe..abf3e02e 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -149,8 +149,8 @@ namespace currency std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_DOC(height, uint64_t(11111)) - KV_SERIALIZE_DOC(status, std::string("OK")) + KV_SERIALIZE_DOC(height, uint64_t(11111), "Some height of the block") + KV_SERIALIZE_DOC(status, std::string("OK"), "Status of the operation") END_KV_SERIALIZE_MAP() }; }; From 09d08baeccce2d6c00cbaf4c29d3c45ef0dccd58 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 21 Mar 2024 23:01:33 +0100 Subject: [PATCH 034/184] fixed consensus bug related to miners motivations to include transactions --- src/currency_core/blockchain_storage.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 17ed1fbd..ec98bea6 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -2089,7 +2089,14 @@ bool blockchain_storage::is_reorganize_required(const block_extended_info& main_ main_chain_bei.this_block_tx_fee_median * main_chain_bei.bl.tx_hashes.size()) { //with the rest equal, alt block has more fees in it, prefer it + LOG_PRINT_L1("[is_reorganize_required]:TRUE, \"by order of tx_hashes.size()\" main_stake_hash:" << &main_chain_bei.stake_hash << ", alt_stake_hash" << proof_alt); return true; + }else if (alt_chain_bei.this_block_tx_fee_median * alt_chain_bei.bl.tx_hashes.size() < + main_chain_bei.this_block_tx_fee_median * main_chain_bei.bl.tx_hashes.size()) + { + //with the rest equal, alt block has more fees in it, prefer it + LOG_PRINT_L1("[is_reorganize_required]:FALSE, \"by order of tx_hashes.size()\" main_stake_hash:" << &main_chain_bei.stake_hash << ", alt_stake_hash" << proof_alt); + return false; } } if (!is_pos_block(main_chain_bei.bl)) From 63940b1d2fbdd88c088a2c91adbbe404951281ab Mon Sep 17 00:00:00 2001 From: zano build machine Date: Fri, 22 Mar 2024 01:02:38 +0300 Subject: [PATCH 035/184] === build number: 282 -> 283 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index 6bfc64f8..27401048 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 282 +#define PROJECT_VERSION_BUILD_NO 283 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From 256206af09df3713ac38ca85fb15442eae20bce8 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Fri, 22 Mar 2024 13:54:46 +0100 Subject: [PATCH 036/184] more code on autodoc descriptions --- .../portable_storage_extended_for_doc.h | 5 +- .../portable_storage_template_helper.h | 6 +- .../include/storages/portable_storage_to_.h | 149 ++++++++++++++++++ .../portable_storage_to_description.h | 118 ++++++++++++++ .../storages/portable_storage_to_json.h | 98 ++---------- 5 files changed, 282 insertions(+), 94 deletions(-) create mode 100644 contrib/epee/include/storages/portable_storage_to_.h create mode 100644 contrib/epee/include/storages/portable_storage_to_description.h diff --git a/contrib/epee/include/storages/portable_storage_extended_for_doc.h b/contrib/epee/include/storages/portable_storage_extended_for_doc.h index 81e70ed9..6c314664 100644 --- a/contrib/epee/include/storages/portable_storage_extended_for_doc.h +++ b/contrib/epee/include/storages/portable_storage_extended_for_doc.h @@ -29,6 +29,8 @@ #pragma once #include "portable_storage.h" +#include "portable_storage.h" + namespace epee { @@ -51,8 +53,7 @@ namespace epee { TRY_ENTRY(); std::stringstream ss; - - //epee::serialization::dump_as_descriptions(ss, m_root, indent, eol); + epee::serialization::recursive_visitor::dump_as_(ss, m_root, indent); buff = ss.str(); return true; CATCH_ENTRY("portable_storage_base::dump_as_json", false) diff --git a/contrib/epee/include/storages/portable_storage_template_helper.h b/contrib/epee/include/storages/portable_storage_template_helper.h index 841a094a..318ae462 100644 --- a/contrib/epee/include/storages/portable_storage_template_helper.h +++ b/contrib/epee/include/storages/portable_storage_template_helper.h @@ -56,16 +56,16 @@ namespace epee } //----------------------------------------------------------------------------------------------------------- template - bool store_t_to_json(const t_struct& str_in, std::string& json_buff, size_t indent = 0/*, end_of_line_t eol = eol_crlf*/) + bool store_t_to_json(const t_struct& str_in, std::string& json_buff, size_t indent = 0) { portable_storage ps; str_in.store(ps); - ps.dump_as_json(json_buff, indent/*, eol*/); + ps.dump_as_json(json_buff, indent); return true; } //----------------------------------------------------------------------------------------------------------- template - std::string store_t_to_json(const t_struct& str_in, size_t indent = 0, end_of_line_t eol = eol_crlf) + std::string store_t_to_json(const t_struct& str_in, size_t indent = 0) { std::string json_buff; store_t_to_json(str_in, json_buff, indent); diff --git a/contrib/epee/include/storages/portable_storage_to_.h b/contrib/epee/include/storages/portable_storage_to_.h new file mode 100644 index 00000000..cb5ece69 --- /dev/null +++ b/contrib/epee/include/storages/portable_storage_to_.h @@ -0,0 +1,149 @@ +// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the Andrey N. Sabelnikov nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 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. +// + + + +#pragma once + +#include "misc_language.h" +#include "portable_storage_base.h" + +namespace epee +{ + namespace serialization + { + template + class recursive_visitor + { + public: + template + struct array_entry_store_to_json_visitor : public boost::static_visitor + { + t_stream& m_strm; + size_t m_indent; + + array_entry_store_to_json_visitor(t_stream& strm, size_t indent) + : m_strm(strm) + , m_indent(indent) + {} + + template + void operator()(const array_entry_t& a) + { + + t_strategy_layout_strategy::handle_array_start(m_strm, m_indent); + if (a.m_array.size()) + { + auto last_it = --a.m_array.end(); + for (auto it = a.m_array.begin(); it != a.m_array.end(); it++) + { + dump_as_(m_strm, *it, m_indent); + if (it != last_it) + t_strategy_layout_strategy::handle_array_entry_separator(m_strm, m_indent); + } + } + t_strategy_layout_strategy::handle_array_end(m_strm, m_indent); + } + }; + + template + struct storage_entry_store_to_json_visitor : public boost::static_visitor + { + t_stream& m_strm; + size_t m_indent; + + storage_entry_store_to_json_visitor(t_stream& strm, size_t indent) + : m_strm(strm) + , m_indent(indent) + {} + + //section, array_entry + template + void operator()(const visited_type& v) + { + dump_as_(m_strm, v, m_indent); + } + }; + + template + void static dump_as_(t_stream& strm, const array_entry& ae, size_t indent) + { + array_entry_store_to_json_visitor aesv(strm, indent); + boost::apply_visitor(aesv, ae); + } + + template + void static dump_as_(t_stream& strm, const storage_entry& se, size_t indent) + { + storage_entry_store_to_json_visitor sv(strm, indent); + boost::apply_visitor(sv, se); + } + + template + void static dump_as_(t_stream& strm, const t_type& v, size_t indent) + { + t_strategy_layout_strategy::handle_value(strm, v, indent); + } + + template + void static dump_as_(t_stream& strm, const section& sec, size_t indent) + { + size_t local_indent = indent + 1; + t_strategy_layout_strategy::handle_obj_begin(strm, indent); + t_strategy_layout_strategy::handle_line_break(strm, indent); + + if (sec.m_entries.size()) + { + auto it_last = --sec.m_entries.end(); + for (auto it = sec.m_entries.begin(); it != sec.m_entries.end(); it++) + { + if (constexpr t_strategy_layout_strategy::use_descriptions::value) + { + std::string descr; + auto it_descr = sec.m_descriptions.find(it->first); + if (it_descr != sec.m_descriptions.end()) + descr = it_descr->second; + + t_strategy_layout_strategy::handle_print_key(strm, it->first, descr, local_indent); + } + else + { + t_strategy_layout_strategy::handle_print_key(strm, it->first, local_indent); + } + + dump_as_(strm, it->second, local_indent); + if (it_last != it) + t_strategy_layout_strategy::handle_section_entry_separator(strm, indent); + + t_strategy_layout_strategy::handle_line_break(strm, indent); + } + } + t_strategy_layout_strategy::handle_obj_end(strm, indent); + } + }; + + } +} diff --git a/contrib/epee/include/storages/portable_storage_to_description.h b/contrib/epee/include/storages/portable_storage_to_description.h new file mode 100644 index 00000000..2c9c1c91 --- /dev/null +++ b/contrib/epee/include/storages/portable_storage_to_description.h @@ -0,0 +1,118 @@ +// Copyright (c) 2006-2024, Andrey N. Sabelnikov, www.sabelnikov.net +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the Andrey N. Sabelnikov nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 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. +// + + + +#pragma once + +#include "misc_language.h" +#include "portable_storage_base.h" +#include "portable_storage_to_.h" + +namespace epee +{ + namespace serialization + { + inline const char* get_endline(end_of_line_t eol) + { + switch (eol) + { + case eol_lf: return "\n"; + case eol_cr: return "\r"; + case eol_space: return " "; + default: return "\r\n"; + } + } + + inline std::string make_indent(size_t indent) + { + return std::string(indent * 2, ' '); + } + + class strategy_json + { + public: + inline static const char* eol = get_endline(eol_crlf); + //static const end_of_line_t eol = eol_crlf; + + template + static void handle_value(t_stream& strm, const t_type& v, size_t indent) + {} + + template + static void handle_array_start(t_stream& strm, size_t indent) + { + strm << "["; + } + + template + static void handle_array_end(t_stream& strm, size_t indent) + { + strm << "]"; + } + + template + static void handle_obj_begin(t_stream& strm, size_t indent) + {} + + template + static void handle_obj_end(t_stream& strm, size_t indent) + {} + + template + static void handle_print_key(t_stream& strm, const std::string& key, size_t indent) + { + const std::string indent_str = make_indent(indent); + strm << indent_str << "\"" << misc_utils::parse::transform_to_json_escape_sequence(key) << "\"" << ": "; + } + + template + static void handle_print_description(t_stream& strm, const std::string& description, size_t indent) + { + } + + + template + static void handle_section_entry_separator(t_stream& strm, size_t indent) + { + strm << ","; + } + + template + static void handle_array_entry_separator(t_stream& strm, size_t indent) + { + strm << ","; + } + + template + static void handle_line_break(t_stream& strm, size_t indent) + { + strm << eol; + } + }; + + } +} diff --git a/contrib/epee/include/storages/portable_storage_to_json.h b/contrib/epee/include/storages/portable_storage_to_json.h index a118e755..415b4d91 100644 --- a/contrib/epee/include/storages/portable_storage_to_json.h +++ b/contrib/epee/include/storages/portable_storage_to_json.h @@ -30,6 +30,7 @@ #include "misc_language.h" #include "portable_storage_base.h" +#include "portable_storage_to_.h" namespace epee { @@ -54,6 +55,8 @@ namespace epee class strategy_json { public: + typedef std::false_type use_descriptions; + inline static const char* eol = get_endline(eol_crlf); //static const end_of_line_t eol = eol_crlf; template @@ -124,105 +127,22 @@ namespace epee } - - }; - - - template - class recursive_visitor - { - public: template - struct array_entry_store_to_json_visitor : public boost::static_visitor + static void handle_section_entry_separator(t_stream& strm, size_t indent) { - t_stream& m_strm; - size_t m_indent; - - array_entry_store_to_json_visitor(t_stream& strm, size_t indent) - : m_strm(strm) - , m_indent(indent) - {} - - template - void operator()(const array_entry_t& a) - { - - t_strategy_layout_strategy::handle_array_start(m_strm, m_indent); - if (a.m_array.size()) - { - auto last_it = --a.m_array.end(); - for (auto it = a.m_array.begin(); it != a.m_array.end(); it++) - { - dump_as_(m_strm, *it, m_indent); - if (it != last_it) - m_strm << ","; - } - } - t_strategy_layout_strategy::handle_array_end(m_strm, m_indent); - } - }; - - template - struct storage_entry_store_to_json_visitor : public boost::static_visitor - { - t_stream& m_strm; - size_t m_indent; - - storage_entry_store_to_json_visitor(t_stream& strm, size_t indent) - : m_strm(strm) - , m_indent(indent) - {} - - //section, array_entry - template - void operator()(const visited_type& v) - { - dump_as_(m_strm, v, m_indent); - } - }; - - template - void static dump_as_(t_stream& strm, const array_entry& ae, size_t indent) - { - array_entry_store_to_json_visitor aesv(strm, indent); - boost::apply_visitor(aesv, ae); + strm << ","; } template - void static dump_as_(t_stream& strm, const storage_entry& se, size_t indent) + static void handle_array_entry_separator(t_stream& strm, size_t indent) { - storage_entry_store_to_json_visitor sv(strm, indent); - boost::apply_visitor(sv, se); - } - - template - void static dump_as_(t_stream& strm, const t_type& v, size_t indent) - { - t_strategy_layout_strategy::handle_value(strm, v, indent); + strm << ","; } template - void static dump_as_(t_stream& strm, const section& sec, size_t indent) + static void handle_line_break(t_stream& strm, size_t indent) { - - - size_t local_indent = indent + 1; - t_strategy_layout_strategy::handle_obj_begin(strm, indent); - put_eol(); - - if (sec.m_entries.size()) - { - auto it_last = --sec.m_entries.end(); - for (auto it = sec.m_entries.begin(); it != sec.m_entries.end(); it++) - { - t_strategy_layout_strategy::handle_print_key(strm, it->first, local_indent); - dump_as_(strm, it->second, local_indent/*, eol*/); - if (it_last != it) - strm << ","; - put_eol(); - } - } - t_strategy_layout_strategy::handle_obj_end(strm, indent); + strm << eol; } }; From 3acd7667bc73d27988ee9dacc78e3c123c5b2fc7 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Fri, 22 Mar 2024 18:44:31 +0100 Subject: [PATCH 037/184] fix for uninitialized data on transaction details(including fee) in unconfirmed transactions --- src/wallet/wallet2.cpp | 1 + src/wallet/wallet_public_structs_defs.h | 26 ++++++++++++------------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index b2af9d58..aac7839a 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -4706,6 +4706,7 @@ void wallet2::get_unconfirmed_transfers(std::vector service_entries; std::vector remote_addresses; //optional @@ -153,11 +153,11 @@ namespace wallet_public std::vector subtransfers; //not included in streaming serialization - uint64_t fee; - bool show_sender; + uint64_t fee = 0; + bool show_sender = false; std::vector contract; - uint16_t extra_flags; - uint64_t transfer_internal_index; + uint16_t extra_flags = 0; + uint64_t transfer_internal_index = 0; //not included in kv serialization map currency::transaction tx; From 8ec5aebd3c710ab00f84c94e2282916a191a0eef Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 22 Mar 2024 23:20:10 +0100 Subject: [PATCH 038/184] minor log improvement --- src/wallet/wallet2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 200f5469..e59dd55d 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -7023,7 +7023,7 @@ void wallet2::prepare_tx_destinations(uint64_t needed_money, const crypto::public_key& asset_id, std::vector& final_destinations) { - WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(found_money >= needed_money, "needed_money==" << needed_money << " < found_money==" << found_money); + WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(found_money >= needed_money, "found_money = " << print_money_brief(found_money) << " is less than needed_money = " << print_money_brief(needed_money) << ", assed_id: " << asset_id); if (is_in_hardfork_zone(ZANO_HARDFORK_04_ZARCANUM)) { From f7a98ed7d19ff81a9b2db66dce08e09a0b490518 Mon Sep 17 00:00:00 2001 From: sowle Date: Sat, 23 Mar 2024 00:34:03 +0100 Subject: [PATCH 039/184] wallet2: scan_not_compliant_unconfirmed_txs --- src/wallet/wallet2.cpp | 47 ++++++++++++++++++++++++++++-------------- src/wallet/wallet2.h | 2 +- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index aac7839a..23ff2596 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -2499,20 +2499,37 @@ void wallet2::scan_tx_pool(bool& has_related_alias_in_unconfirmed) //---------------------------------------------------------------------------------------------------- bool wallet2::on_idle() { - scan_unconfirmed_outdate_tx(); + scan_not_compliant_unconfirmed_txs(); return true; } //---------------------------------------------------------------------------------------------------- -bool wallet2::scan_unconfirmed_outdate_tx() +bool wallet2::scan_not_compliant_unconfirmed_txs() { uint64_t tx_expiration_ts_median = get_tx_expiration_median(); uint64_t time_limit = m_core_runtime_config.get_core_time() - CURRENCY_MEMPOOL_TX_LIVETIME; for (auto it = m_unconfirmed_txs.begin(); it != m_unconfirmed_txs.end(); ) { - bool tx_outdated = it->second.timestamp < time_limit; - if (tx_outdated || is_tx_expired(it->second.tx, tx_expiration_ts_median)) + bool remove_this_tx = false; + std::stringstream reason_ss; + if (it->second.timestamp < time_limit) { - WLT_LOG_BLUE("removing unconfirmed tx " << it->second.tx_hash << ", reason: " << (tx_outdated ? "outdated" : "expired") << ", tx_expiration_ts_median=" << tx_expiration_ts_median, LOG_LEVEL_0); + remove_this_tx = true; + reason_ss << "outdated, "; + } + if (is_tx_expired(it->second.tx, tx_expiration_ts_median)) + { + remove_this_tx = true; + reason_ss << "expired, "; + } + if (is_in_hardfork_zone(ZANO_HARDFORK_04_ZARCANUM) && it->second.tx.version < TRANSACTION_VERSION_POST_HF4) + { + remove_this_tx = true; + reason_ss << "not compliant with HF4, "; + } + + if (remove_this_tx) + { + WLT_LOG_BLUE("removing unconfirmed tx " << it->second.tx_hash << ", reason: " << reason_ss.str() << "tx_expiration_ts_median=" << tx_expiration_ts_median, LOG_LEVEL_0); //lookup all used transfer and update flags for (auto i : it->second.selected_indicies) { @@ -2524,15 +2541,18 @@ bool wallet2::scan_unconfirmed_outdate_tx() if (!m_transfers[i].m_spent_height) { uint32_t flags_before = m_transfers[i].m_flags; - m_transfers[i].m_flags &= ~(WALLET_TRANSFER_DETAIL_FLAG_SPENT); + m_transfers[i].m_flags &= ~(WALLET_TRANSFER_DETAIL_FLAG_SPENT); // TODO: consider removing other blocking flags (e.g. for escrow tx) -- sowle WLT_LOG_BLUE("mark transfer #" << i << " as unspent, flags: " << flags_before << " -> " << m_transfers[i].m_flags << ", reason: removing unconfirmed tx " << it->second.tx_hash, LOG_LEVEL_0); } } //fire some event m_wcallback->on_transfer_canceled(it->second); m_unconfirmed_txs.erase(it++); - }else + } + else + { it++; + } } //scan marked as spent but don't have height (unconfirmed, and actually not unconfirmed) @@ -2542,16 +2562,11 @@ bool wallet2::scan_unconfirmed_outdate_tx() if (!it->second.has_outgoing_entries()) continue; - for (auto& in : it->second.tx.vin) + for (auto& in_v : it->second.tx.vin) { - if (in.type() == typeid(txin_to_key)) - { - ki_in_unconfirmed.insert(boost::get(in).k_image); - } - else if (in.type() == typeid(txin_zc_input)) - { - ki_in_unconfirmed.insert(boost::get(in).k_image); - } + crypto::key_image ki{}; + if (get_key_image_from_txin_v(in_v, ki)) + ki_in_unconfirmed.insert(ki); } } diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 3097a9c5..74df897c 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -751,7 +751,7 @@ private: std::vector get_aliases_for_address(const std::string& addr); bool is_connected_to_net(); bool is_transfer_okay_for_pos(const transfer_details& tr, bool is_zarcanum_hf, uint64_t& stake_unlock_time) const; - bool scan_unconfirmed_outdate_tx(); + bool scan_not_compliant_unconfirmed_txs(); const currency::transaction& get_transaction_by_id(const crypto::hash& tx_hash); void rise_on_transfer2(const wallet_public::wallet_transfer_info& wti); void process_genesis_if_needed(const currency::block& genesis); From 7c3e2cbc703584d456147f5db6a32a8887111bc4 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Sat, 23 Mar 2024 03:32:49 +0300 Subject: [PATCH 040/184] === build number: 283 -> 284 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index 27401048..2f3a2265 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 283 +#define PROJECT_VERSION_BUILD_NO 284 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From 60bb74cbb0ccbe49a3f3e0c181584068e8616f51 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Sat, 23 Mar 2024 15:45:24 +0100 Subject: [PATCH 041/184] more consistent documentation code is working now --- .../serialization/keyvalue_serialization.h | 31 ++++++++++++++----- .../keyvalue_serialization_overloads.h | 1 - .../portable_storage_extended_for_doc.h | 4 +-- .../include/storages/portable_storage_to_.h | 2 +- .../portable_storage_to_description.h | 24 +++----------- .../storages/portable_storage_to_json.h | 18 +++-------- src/rpc/core_rpc_server_commands_defs.h | 10 +++--- 7 files changed, 42 insertions(+), 48 deletions(-) diff --git a/contrib/epee/include/serialization/keyvalue_serialization.h b/contrib/epee/include/serialization/keyvalue_serialization.h index e510f30a..0e63fc10 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization.h +++ b/contrib/epee/include/serialization/keyvalue_serialization.h @@ -71,6 +71,17 @@ public: \ #define KV_SERIALIZE_N_DOC(varialble, val_name, substitute, description) \ epee::serialization::selector::serialize(this_ref.varialble, stg, hparent_section, val_name, auto_doc_mode, substitute, description); +#define KV_SERIALIZE_N_DOC2(varialble, val_name) \ + {using var_type = decltype(this_ref.varialble); epee::serialization::selector::serialize(this_ref.varialble, stg, hparent_section, val_name, auto_doc_mode, + + + //substitute, description); +#define DOC_EXAMPLE(substitute) substitute, +#define DOC_EX(substitute__) var_type(substitute__), +#define DOC_DSCR(description) description); } + + + #define KV_SERIALIZE_CUSTOM_N(varialble, stored_type, from_v_to_stored, from_stored_to_v, val_name) \ epee::serialization::selector::template serialize_custom(this_ref.varialble, stg, hparent_section, val_name, from_v_to_stored, from_stored_to_v); @@ -97,14 +108,20 @@ public: \ #define END_KV_SERIALIZE_MAP() return true;} -#define KV_SERIALIZE(varialble) KV_SERIALIZE_N(varialble, #varialble) -#define KV_SERIALIZE_DOC(varialble, substitute, description) KV_SERIALIZE_N_DOC( varialble, #varialble, substitute, description) -#define KV_SERIALIZE_VAL_POD_AS_BLOB(varialble) KV_SERIALIZE_VAL_POD_AS_BLOB_N(varialble, #varialble) -#define KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE(varialble) KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(varialble, #varialble) //skip is_pod compile time check -#define KV_SERIALIZE_CONTAINER_POD_AS_BLOB(varialble) KV_SERIALIZE_CONTAINER_POD_AS_BLOB_N(varialble, #varialble) +#define KV_SERIALIZE(varialble) KV_SERIALIZE_N(varialble, #varialble) +#define KV_SERIALIZE_DOC2(varialble) KV_SERIALIZE_N_DOC2( varialble, #varialble) +#define KV_SERIALIZE_DOC(varialble, substitute, description) KV_SERIALIZE_N_DOC( varialble, #varialble, substitute, description) + + + //#define KV_SERIALIZE_DOC(varialble, substitute, description) KV_SERIALIZE_N_DOC( varialble, #varialble, substitute, description) + + +#define KV_SERIALIZE_VAL_POD_AS_BLOB(varialble) KV_SERIALIZE_VAL_POD_AS_BLOB_N(varialble, #varialble) +#define KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE(varialble) KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(varialble, #varialble) //skip is_pod compile time check +#define KV_SERIALIZE_CONTAINER_POD_AS_BLOB(varialble) KV_SERIALIZE_CONTAINER_POD_AS_BLOB_N(varialble, #varialble) #define KV_SERIALIZE_CUSTOM(varialble, stored_type, from_v_to_stored, from_stored_to_v) KV_SERIALIZE_CUSTOM_N(varialble, stored_type, from_v_to_stored, from_stored_to_v, #varialble) -#define KV_SERIALIZE_POD_AS_HEX_STRING(varialble) KV_SERIALIZE_POD_AS_HEX_STRING_N(varialble, #varialble) -#define KV_SERIALIZE_BLOB_AS_HEX_STRING(varialble) KV_SERIALIZE_BLOB_AS_HEX_STRING_N(varialble, #varialble) +#define KV_SERIALIZE_POD_AS_HEX_STRING(varialble) KV_SERIALIZE_POD_AS_HEX_STRING_N(varialble, #varialble) +#define KV_SERIALIZE_BLOB_AS_HEX_STRING(varialble) KV_SERIALIZE_BLOB_AS_HEX_STRING_N(varialble, #varialble) diff --git a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h index 9123fe6f..e0b6f6d8 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h +++ b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h @@ -479,6 +479,5 @@ namespace epee return r; } - } } \ No newline at end of file diff --git a/contrib/epee/include/storages/portable_storage_extended_for_doc.h b/contrib/epee/include/storages/portable_storage_extended_for_doc.h index 6c314664..aec4a766 100644 --- a/contrib/epee/include/storages/portable_storage_extended_for_doc.h +++ b/contrib/epee/include/storages/portable_storage_extended_for_doc.h @@ -29,7 +29,7 @@ #pragma once #include "portable_storage.h" -#include "portable_storage.h" +#include "portable_storage_to_description.h" namespace epee @@ -53,7 +53,7 @@ namespace epee { TRY_ENTRY(); std::stringstream ss; - epee::serialization::recursive_visitor::dump_as_(ss, m_root, indent); + recursive_visitor::dump_as_(ss, m_root, indent); buff = ss.str(); return true; CATCH_ENTRY("portable_storage_base::dump_as_json", false) diff --git a/contrib/epee/include/storages/portable_storage_to_.h b/contrib/epee/include/storages/portable_storage_to_.h index cb5ece69..8c3bc592 100644 --- a/contrib/epee/include/storages/portable_storage_to_.h +++ b/contrib/epee/include/storages/portable_storage_to_.h @@ -120,7 +120,7 @@ namespace epee auto it_last = --sec.m_entries.end(); for (auto it = sec.m_entries.begin(); it != sec.m_entries.end(); it++) { - if (constexpr t_strategy_layout_strategy::use_descriptions::value) + if constexpr (t_strategy_layout_strategy::use_descriptions::value) { std::string descr; auto it_descr = sec.m_descriptions.find(it->first); diff --git a/contrib/epee/include/storages/portable_storage_to_description.h b/contrib/epee/include/storages/portable_storage_to_description.h index 2c9c1c91..c38c3f62 100644 --- a/contrib/epee/include/storages/portable_storage_to_description.h +++ b/contrib/epee/include/storages/portable_storage_to_description.h @@ -36,25 +36,11 @@ namespace epee { namespace serialization { - inline const char* get_endline(end_of_line_t eol) - { - switch (eol) - { - case eol_lf: return "\n"; - case eol_cr: return "\r"; - case eol_space: return " "; - default: return "\r\n"; - } - } - - inline std::string make_indent(size_t indent) - { - return std::string(indent * 2, ' '); - } - - class strategy_json + class strategy_descriptin { public: + using use_descriptions = std::true_type; + inline static const char* eol = get_endline(eol_crlf); //static const end_of_line_t eol = eol_crlf; @@ -83,10 +69,10 @@ namespace epee {} template - static void handle_print_key(t_stream& strm, const std::string& key, size_t indent) + static void handle_print_key(t_stream& strm, const std::string& key, const std::string& description, size_t indent) { const std::string indent_str = make_indent(indent); - strm << indent_str << "\"" << misc_utils::parse::transform_to_json_escape_sequence(key) << "\"" << ": "; + strm << indent_str << "\"" << key << "\"" << ": " << description; } template diff --git a/contrib/epee/include/storages/portable_storage_to_json.h b/contrib/epee/include/storages/portable_storage_to_json.h index 415b4d91..cb434b87 100644 --- a/contrib/epee/include/storages/portable_storage_to_json.h +++ b/contrib/epee/include/storages/portable_storage_to_json.h @@ -55,7 +55,7 @@ namespace epee class strategy_json { public: - typedef std::false_type use_descriptions; + using use_descriptions = std::false_type; inline static const char* eol = get_endline(eol_crlf); //static const end_of_line_t eol = eol_crlf; @@ -109,15 +109,11 @@ namespace epee template static void handle_obj_begin(t_stream& strm, size_t indent) - { - strm << "{"; - } + {} template static void handle_obj_end(t_stream& strm, size_t indent) - { - strm << "}"; - } + {} template static void handle_print_key(t_stream& strm, const std::string& key, size_t indent) @@ -129,15 +125,11 @@ namespace epee template static void handle_section_entry_separator(t_stream& strm, size_t indent) - { - strm << ","; - } + {} template static void handle_array_entry_separator(t_stream& strm, size_t indent) - { - strm << ","; - } + {} template static void handle_line_break(t_stream& strm, size_t indent) diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index abf3e02e..5da22c9f 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -149,8 +149,8 @@ namespace currency std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_DOC(height, uint64_t(11111), "Some height of the block") - KV_SERIALIZE_DOC(status, std::string("OK"), "Status of the operation") + KV_SERIALIZE_DOC2(height) DOC_EX(11111) DOC_DSCR("Some height of the block") + KV_SERIALIZE_DOC2(status) DOC_EX("OK") DOC_DSCR("Status of the operation") END_KV_SERIALIZE_MAP() }; }; @@ -212,9 +212,9 @@ namespace currency std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(txs_as_hex) - KV_SERIALIZE(missed_tx) - KV_SERIALIZE(status) + KV_SERIALIZE_DOC(txs_as_hex, std::list(1, "97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc97d914497d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc2f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc"), "Transactions stored as blobs") + KV_SERIALIZE_DOC(missed_tx, std::list(1, "97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc"), "Missed transactions hashes") + KV_SERIALIZE_DOC(status, std::string("OK"), "Command response status") END_KV_SERIALIZE_MAP() }; }; From 83968977a186f4f1b62485cc1263ce1a747e574c Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Sun, 24 Mar 2024 13:47:52 +0100 Subject: [PATCH 042/184] current fixes --- src/wallet/wallet_rpc_server.cpp | 10 ++++---- src/wallet/wallet_rpc_server_error_codes.h | 1 + tests/performance_tests/main.cpp | 24 ++++++++++++------- tests/performance_tests/single_tx_test_base.h | 2 +- .../test_api_files/get_alias_by_address.json | 1 + utils/test_api_files/get_alias_details.json | 2 +- 6 files changed, 24 insertions(+), 16 deletions(-) create mode 100644 utils/test_api_files/get_alias_by_address.json diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index ddd09634..5baf588d 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -38,25 +38,25 @@ POP_VS_WARNINGS catch (const tools::error::daemon_busy& e) \ { \ er.code = WALLET_RPC_ERROR_CODE_DAEMON_IS_BUSY; \ - er.message = e.what(); \ + er.message = std::string("WALLET_RPC_ERROR_CODE_DAEMON_IS_BUSY") + e.what(); \ return false; \ } \ catch (const tools::error::not_enough_money& e) \ { \ - er.code = WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR; \ - er.message = e.error_code(); \ + er.code = WALLET_RPC_ERROR_CODE_NOT_ENOUGH_MONEY; \ + er.message = std::string("WALLET_RPC_ERROR_CODE_NOT_ENOUGH_MONEY") + e.error_code(); \ return false; \ } \ catch (const tools::error::wallet_error& e) \ { \ er.code = WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR; \ - er.message = e.error_code(); \ + er.message = std::string("WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR") + e.error_code(); \ return false; \ } \ catch (const std::exception& e) \ { \ er.code = WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR; \ - er.message = e.what(); \ + er.message = std::string("WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR") + e.what(); \ return false; \ } \ catch (...) \ diff --git a/src/wallet/wallet_rpc_server_error_codes.h b/src/wallet/wallet_rpc_server_error_codes.h index f9c0a2a0..d24302e0 100644 --- a/src/wallet/wallet_rpc_server_error_codes.h +++ b/src/wallet/wallet_rpc_server_error_codes.h @@ -13,3 +13,4 @@ #define WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR -4 #define WALLET_RPC_ERROR_CODE_WRONG_PAYMENT_ID -5 #define WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT -6 +#define WALLET_RPC_ERROR_CODE_NOT_ENOUGH_MONEY -7 diff --git a/tests/performance_tests/main.cpp b/tests/performance_tests/main.cpp index 6d435955..d1a507b1 100644 --- a/tests/performance_tests/main.cpp +++ b/tests/performance_tests/main.cpp @@ -34,11 +34,15 @@ POP_VS_WARNINGS void test_plain_wallet() { - - std::string res = plain_wallet::init("195.201.107.230", "33336", "C:\\Users\\roky\\home\\", 0); + //std::string res = plain_wallet::init("195.201.107.230", "33336", "E:\\tmp\\", 0); + std::string res = plain_wallet::init("127.0.0.1", "12111", "C:\\Users\\roky\\home\\", 0); uint64_t instance_id = 0; - res = plain_wallet::open("SEGA_2", "Test2"); + res = plain_wallet::open("test_restored.zan", "111"); + //res = plain_wallet::restore("heart level clear fate sorrow childhood sent fate ceiling party third steel came ask mix neither message already almost vast date glide tumble color okay space", + // "test_restored.zan", "111", ""); + + while(true) { epee::misc_utils::sleep_no_w(2000); @@ -50,16 +54,18 @@ void test_plain_wallet() } - std::string invoke_body = "{\"method\":\"get_recent_txs_and_info\",\"params\":{\"offset\":0,\"count\":30,\"update_provision_info\":true}}"; - - res = plain_wallet::sync_call("invoke", instance_id, invoke_body); + std::string invoke_body = "{\"method\":\"store\",\"params\":{}}"; + //std::string res1 = plain_wallet::sync_call("invoke", instance_id, invoke_body); - invoke_body = "{\"method\":\"assets_whitelist_get\",\"params\":{}}"; + invoke_body = "{\"method\":\"get_recent_txs_and_info\",\"params\":{\"offset\":0,\"count\":30,\"update_provision_info\":true}}"; + std::string res2 = plain_wallet::sync_call("invoke", instance_id, invoke_body); - res = plain_wallet::sync_call("invoke", instance_id, invoke_body); + invoke_body = "{\"method\":\"getbalance\",\"params\":{}}"; + std::string res3 = plain_wallet::sync_call("invoke", instance_id, invoke_body); - res = plain_wallet::close_wallet(instance_id); + invoke_body = "{\r\n \"method\": \"transfer\",\r\n \"params\": {\r\n \"destinations\": [\r\n {\r\n \"amount\": \"1000000000000\",\r\n \"address\": \"ZxD9oVwGwW6ULix9Pqttnr7JDpaoLvDVA1KJ9eA9KRxPMRZT5X7WwtU94XH1Z6q6XTMxNbHmbV2xfZ429XxV6fST2DxEg4BQV\",\r\n \"asset_id\": \"cc4e69455e63f4a581257382191de6856c2156630b3fba0db4bdd73ffcfb36b6\"\r\n }\r\n ],\r\n \"fee\": 10000000000,\r\n \"mixin\": 10,\r\n \"payment_id\": \"\",\r\n \"comment\": \"\",\r\n \"push_payer\": false,\r\n \"hide_receiver\": true\r\n }\r\n}"; + std::string res4 = plain_wallet::sync_call("invoke", instance_id, invoke_body); LOG_PRINT_L0(res); diff --git a/tests/performance_tests/single_tx_test_base.h b/tests/performance_tests/single_tx_test_base.h index 13c4d0ae..a605d624 100644 --- a/tests/performance_tests/single_tx_test_base.h +++ b/tests/performance_tests/single_tx_test_base.h @@ -18,10 +18,10 @@ public: m_bob.generate(); uint64_t block_reward_without_fee = 0; + uint64_t block_reward = 0; if(!construct_miner_tx(0, 0, 0, 2, 0, m_bob.get_keys().account_address, m_bob.get_keys().account_address, m_tx, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, blobdata(), CURRENCY_MINER_TX_MAX_OUTS)) return false; - m_tx_pub_key = get_tx_pub_key_from_extra(m_tx); return true; } diff --git a/utils/test_api_files/get_alias_by_address.json b/utils/test_api_files/get_alias_by_address.json new file mode 100644 index 00000000..c89f7e97 --- /dev/null +++ b/utils/test_api_files/get_alias_by_address.json @@ -0,0 +1 @@ +{"method": "get_alias_details","params": {"alias": "zoidb"}} \ No newline at end of file diff --git a/utils/test_api_files/get_alias_details.json b/utils/test_api_files/get_alias_details.json index c89f7e97..27871aa7 100644 --- a/utils/test_api_files/get_alias_details.json +++ b/utils/test_api_files/get_alias_details.json @@ -1 +1 @@ -{"method": "get_alias_details","params": {"alias": "zoidb"}} \ No newline at end of file +{"method": "get_alias_details","params": "ZxCjF84feY7GQZ1fdy9r3ZJABwaFjmb2Dd25H5qANWZ2VufpmyNu7ZnShMBDpiw8VW2k1EjPZswgFZnx3v1EYgJ32Rjn64mq9"} \ No newline at end of file From 3fb4f16db9d52a5e46925066be732311f975fec4 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Sun, 24 Mar 2024 13:47:52 +0100 Subject: [PATCH 043/184] fore get rid of WALLET_GLOBAL_OUTPUT_INDEX_UNDEFINED --- src/currency_core/blockchain_storage.cpp | 7 ++-- src/currency_core/blockchain_storage.h | 4 +- src/rpc/core_rpc_server.cpp | 18 +++------ src/rpc/core_rpc_server_commands_defs.h | 2 - src/wallet/core_default_rpc_proxy.cpp | 1 - src/wallet/wallet2.cpp | 2 - src/wallet/wallet_rpc_server.cpp | 10 ++--- src/wallet/wallet_rpc_server_error_codes.h | 1 + src/wallet/wallets_manager.cpp | 2 +- tests/CMakeLists.txt | 4 +- tests/core_tests/wallet_test_core_proxy.cpp | 1 - tests/performance_tests/main.cpp | 38 ++++++++++++++----- tests/performance_tests/single_tx_test_base.h | 5 ++- .../test_api_files/get_alias_by_address.json | 1 + utils/test_api_files/get_alias_details.json | 2 +- 15 files changed, 54 insertions(+), 44 deletions(-) create mode 100644 utils/test_api_files/get_alias_by_address.json diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index ec98bea6..43a32e9d 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -3591,7 +3591,7 @@ bool blockchain_storage::get_est_height_from_date(uint64_t date, uint64_t& res_h return true; } //------------------------------------------------------------------ -bool blockchain_storage::find_blockchain_supplement(const std::list& qblock_ids, std::list > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count, uint64_t minimum_height, bool need_global_indexes)const +bool blockchain_storage::find_blockchain_supplement(const std::list& qblock_ids, std::list > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count, uint64_t minimum_height)const { CRITICAL_REGION_LOCAL(m_read_lock); blocks_direct_container blocks_direct; @@ -3610,7 +3610,7 @@ bool blockchain_storage::find_blockchain_supplement(const std::list& qblock_ids, blocks_direct_container& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count, uint64_t minimum_height, bool request_coinbase_info)const +bool blockchain_storage::find_blockchain_supplement(const std::list& qblock_ids, blocks_direct_container& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count, uint64_t minimum_height)const { CRITICAL_REGION_LOCAL(m_read_lock); if (!find_blockchain_supplement(qblock_ids, start_height)) @@ -3627,8 +3627,7 @@ bool blockchain_storage::find_blockchain_supplement(const std::list mis; get_transactions_direct(m_db_blocks[i]->bl.tx_hashes, blocks.back().second, mis); CHECK_AND_ASSERT_MES(!mis.size(), false, "internal error, block " << get_block_hash(m_db_blocks[i]->bl) << " [" << i << "] contains missing transactions: " << mis); - if(request_coinbase_info) - blocks.back().third = m_db_transactions.find(get_transaction_hash(m_db_blocks[i]->bl.miner_tx)); + blocks.back().third = m_db_transactions.find(get_transaction_hash(m_db_blocks[i]->bl.miner_tx)); } return true; } diff --git a/src/currency_core/blockchain_storage.h b/src/currency_core/blockchain_storage.h index 5bf57ad4..e448f2d0 100644 --- a/src/currency_core/blockchain_storage.h +++ b/src/currency_core/blockchain_storage.h @@ -280,8 +280,8 @@ namespace currency bool get_short_chain_history(std::list& ids)const; bool find_blockchain_supplement(const std::list& qblock_ids, NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp)const; bool find_blockchain_supplement(const std::list& qblock_ids, uint64_t& starter_offset)const; - bool find_blockchain_supplement(const std::list& qblock_ids, std::list > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count, uint64_t minimum_height = 0, bool need_global_indexes = false)const; - bool find_blockchain_supplement(const std::list& qblock_ids, blocks_direct_container& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count, uint64_t minimum_height = 0, bool request_coinbase_info = false)const; + bool find_blockchain_supplement(const std::list& qblock_ids, std::list > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count, uint64_t minimum_height = 0)const; + bool find_blockchain_supplement(const std::list& qblock_ids, blocks_direct_container& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count, uint64_t minimum_height = 0)const; //bool find_blockchain_supplement(const std::list& qblock_ids, std::list > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count)const; bool handle_get_objects(NOTIFY_REQUEST_GET_OBJECTS::request& arg, NOTIFY_RESPONSE_GET_OBJECTS::request& rsp)const; bool handle_get_objects(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res)const; diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 7eda942c..77774cc1 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -289,7 +289,7 @@ namespace currency } blockchain_storage::blocks_direct_container bs; - if(!m_core.get_blockchain_storage().find_blockchain_supplement(req.block_ids, bs, res.current_height, res.start_height, COMMAND_RPC_GET_BLOCKS_FAST_MAX_COUNT, req.minimum_height, req.need_global_indexes)) + if(!m_core.get_blockchain_storage().find_blockchain_supplement(req.block_ids, bs, res.current_height, res.start_height, COMMAND_RPC_GET_BLOCKS_FAST_MAX_COUNT, req.minimum_height)) { res.status = API_RETURN_CODE_FAIL; return false; @@ -326,7 +326,7 @@ namespace currency } blockchain_storage::blocks_direct_container bs; - if (!m_core.get_blockchain_storage().find_blockchain_supplement(req.block_ids, bs, res.current_height, res.start_height, COMMAND_RPC_GET_BLOCKS_FAST_MAX_COUNT, req.minimum_height, req.need_global_indexes)) + if (!m_core.get_blockchain_storage().find_blockchain_supplement(req.block_ids, bs, res.current_height, res.start_height, COMMAND_RPC_GET_BLOCKS_FAST_MAX_COUNT, req.minimum_height)) { res.status = API_RETURN_CODE_FAIL; return false; @@ -336,21 +336,15 @@ namespace currency { res.blocks.resize(res.blocks.size()+1); res.blocks.back().block = block_to_blob(b.first->bl); - if (req.need_global_indexes) - { - CHECK_AND_ASSERT_MES(b.third.get(), false, "Internal error on handling COMMAND_RPC_GET_BLOCKS_FAST: b.third is empty, ie coinbase info is not prepared"); - res.blocks.back().coinbase_global_outs = b.third->m_global_output_indexes; - res.blocks.back().tx_global_outs.resize(b.second.size()); - } + CHECK_AND_ASSERT_MES(b.third.get(), false, "Internal error on handling COMMAND_RPC_GET_BLOCKS_FAST: b.third is empty, ie coinbase info is not prepared"); + res.blocks.back().coinbase_global_outs = b.third->m_global_output_indexes; + res.blocks.back().tx_global_outs.resize(b.second.size()); size_t i = 0; BOOST_FOREACH(auto& t, b.second) { res.blocks.back().txs.push_back(tx_to_blob(t->tx)); - if (req.need_global_indexes) - { - res.blocks.back().tx_global_outs[i].v = t->m_global_output_indexes; - } + res.blocks.back().tx_global_outs[i].v = t->m_global_output_indexes; i++; } } diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index ca55f2d4..8850e584 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -161,12 +161,10 @@ namespace currency struct request { - bool need_global_indexes; uint64_t minimum_height; std::list block_ids; //*first 10 blocks id goes sequential, next goes in pow(2,n) offset, like 2, 4, 8, 16, 32, 64 and so on, and the last one is always genesis block */ BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(need_global_indexes) KV_SERIALIZE(minimum_height) KV_SERIALIZE_CONTAINER_POD_AS_BLOB(block_ids) END_KV_SERIALIZE_MAP() diff --git a/src/wallet/core_default_rpc_proxy.cpp b/src/wallet/core_default_rpc_proxy.cpp index 92cf11bc..8223cd06 100644 --- a/src/wallet/core_default_rpc_proxy.cpp +++ b/src/wallet/core_default_rpc_proxy.cpp @@ -39,7 +39,6 @@ namespace tools currency::COMMAND_RPC_GET_BLOCKS_FAST::request req; req.block_ids = rqt.block_ids; req.minimum_height = rqt.minimum_height; - req.need_global_indexes = rqt.need_global_indexes; currency::COMMAND_RPC_GET_BLOCKS_FAST::response res = AUTO_VAL_INIT(res); bool r = call_COMMAND_RPC_GET_BLOCKS_FAST(req, res); rsp.status = res.status; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 23ff2596..3c2e45b9 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1917,8 +1917,6 @@ void wallet2::pull_blocks(size_t& blocks_added, std::atomic& stop) currency::COMMAND_RPC_GET_BLOCKS_DIRECT::response res = AUTO_VAL_INIT(res); req.minimum_height = get_wallet_minimum_height(); - if (is_auditable()) - req.need_global_indexes = true; if (req.minimum_height > m_height_of_start_sync) m_height_of_start_sync = req.minimum_height; diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index a602ecba..516329ff 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -25,25 +25,25 @@ using namespace epee; catch (const tools::error::daemon_busy& e) \ { \ er.code = WALLET_RPC_ERROR_CODE_DAEMON_IS_BUSY; \ - er.message = e.what(); \ + er.message = std::string("WALLET_RPC_ERROR_CODE_DAEMON_IS_BUSY") + e.what(); \ return false; \ } \ catch (const tools::error::not_enough_money& e) \ { \ - er.code = WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR; \ - er.message = e.error_code(); \ + er.code = WALLET_RPC_ERROR_CODE_NOT_ENOUGH_MONEY; \ + er.message = std::string("WALLET_RPC_ERROR_CODE_NOT_ENOUGH_MONEY") + e.error_code(); \ return false; \ } \ catch (const tools::error::wallet_error& e) \ { \ er.code = WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR; \ - er.message = e.error_code(); \ + er.message = std::string("WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR") + e.error_code(); \ return false; \ } \ catch (const std::exception& e) \ { \ er.code = WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR; \ - er.message = e.what(); \ + er.message = std::string("WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR") + e.what(); \ return false; \ } \ catch (...) \ diff --git a/src/wallet/wallet_rpc_server_error_codes.h b/src/wallet/wallet_rpc_server_error_codes.h index f9c0a2a0..d24302e0 100644 --- a/src/wallet/wallet_rpc_server_error_codes.h +++ b/src/wallet/wallet_rpc_server_error_codes.h @@ -13,3 +13,4 @@ #define WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR -4 #define WALLET_RPC_ERROR_CODE_WRONG_PAYMENT_ID -5 #define WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT -6 +#define WALLET_RPC_ERROR_CODE_NOT_ENOUGH_MONEY -7 diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index c1edabff..d41ccca1 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -48,7 +48,7 @@ #define TX_POOL_SCAN_INTERVAL 1 #endif -#define HTTP_PROXY_TIMEOUT 2000 +#define HTTP_PROXY_TIMEOUT 4000 #define HTTP_PROXY_ATTEMPTS_COUNT 1 const command_line::arg_descriptor arg_alloc_win_console ( "alloc-win-console", "Allocates debug console with GUI", false ); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 71b544c1..005a314f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -29,10 +29,10 @@ add_executable(net_load_tests_srv net_load_tests/srv.cpp) add_dependencies(coretests version) target_link_libraries(coretests rpc wallet currency_core common crypto zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto) -target_link_libraries(functional_tests rpc wallet currency_core crypto common zlibstatic ethash libminiupnpc-static ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) +target_link_libraries(functional_tests rpc wallet currency_core crypto common zlibstatic ethash libminiupnpc-static ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto) target_link_libraries(hash-tests crypto ethash) target_link_libraries(hash-target-tests crypto currency_core ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) -target_link_libraries(performance_tests rpc wallet currency_core common crypto zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) +target_link_libraries(performance_tests rpc wallet currency_core common crypto zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto) target_link_libraries(unit_tests wallet currency_core common crypto gtest_main zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) target_link_libraries(net_load_tests_clt currency_core common crypto gtest_main ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) target_link_libraries(net_load_tests_srv currency_core common crypto gtest_main ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) diff --git a/tests/core_tests/wallet_test_core_proxy.cpp b/tests/core_tests/wallet_test_core_proxy.cpp index e303bc8c..0ceae0ab 100644 --- a/tests/core_tests/wallet_test_core_proxy.cpp +++ b/tests/core_tests/wallet_test_core_proxy.cpp @@ -112,7 +112,6 @@ bool wallet_test_core_proxy::call_COMMAND_RPC_GET_BLOCKS_DIRECT(const currency:: currency::COMMAND_RPC_GET_BLOCKS_FAST::request req = AUTO_VAL_INIT(req); req.block_ids = rqt.block_ids; req.minimum_height = rqt.minimum_height; - req.need_global_indexes = rqt.need_global_indexes; currency::COMMAND_RPC_GET_BLOCKS_FAST::response res = AUTO_VAL_INIT(res); bool r = this->call_COMMAND_RPC_GET_BLOCKS_FAST(req, res); rsp.status = res.status; diff --git a/tests/performance_tests/main.cpp b/tests/performance_tests/main.cpp index acd1f406..e84f17d3 100644 --- a/tests/performance_tests/main.cpp +++ b/tests/performance_tests/main.cpp @@ -27,12 +27,18 @@ #include "wallet/plain_wallet_api.h" #include "wallet/view_iface.h" + void test_plain_wallet() { - std::string res = plain_wallet::init("195.201.107.230", "33336", "E:\\tmp\\", 0); + //std::string res = plain_wallet::init("195.201.107.230", "33336", "E:\\tmp\\", 0); + std::string res = plain_wallet::init("127.0.0.1", "12111", "C:\\Users\\roky\\home\\", 0); uint64_t instance_id = 0; - res = plain_wallet::open("test.zan", "111"); + res = plain_wallet::open("test_restored.zan", "111"); + //res = plain_wallet::restore("heart level clear fate sorrow childhood sent fate ceiling party third steel came ask mix neither message already almost vast date glide tumble color okay space", + // "test_restored.zan", "111", ""); + + while(true) { epee::misc_utils::sleep_no_w(2000); @@ -44,9 +50,23 @@ void test_plain_wallet() } - std::string invoke_body = "{\"method\":\"get_recent_txs_and_info\",\"params\":{\"offset\":0,\"count\":30,\"update_provision_info\":true}}"; - - res = plain_wallet::sync_call("invoke", instance_id, invoke_body); + std::string invoke_body = "{\"method\":\"store\",\"params\":{}}"; + //std::string res1 = plain_wallet::sync_call("invoke", instance_id, invoke_body); + + invoke_body = "{\"method\":\"get_recent_txs_and_info\",\"params\":{\"offset\":0,\"count\":30,\"update_provision_info\":true}}"; + std::string res2 = plain_wallet::sync_call("invoke", instance_id, invoke_body); + + invoke_body = "{\"method\":\"getbalance\",\"params\":{}}"; + std::string res3 = plain_wallet::sync_call("invoke", instance_id, invoke_body); + + + invoke_body = "{\"method\":\"getbalance\",\"params\":{}}"; + std::string res4 = plain_wallet::sync_call("invoke", instance_id, invoke_body); + + + invoke_body = "{\r\n \"method\": \"transfer\",\r\n \"params\": {\r\n \"destinations\": [\r\n {\r\n \"amount\": \"1000000000000\",\r\n \"address\": \"ZxD9oVwGwW6ULix9Pqttnr7JDpaoLvDVA1KJ9eA9KRxPMRZT5X7WwtU94XH1Z6q6XTMxNbHmbV2xfZ429XxV6fST2DxEg4BQV\" }\r\n ],\r\n \"fee\": 10000000000,\r\n \"mixin\": 10,\r\n \"payment_id\": \"\",\r\n \"comment\": \"\",\r\n \"push_payer\": false,\r\n \"hide_receiver\": true\r\n }\r\n}"; + std::string res5 = plain_wallet::sync_call("invoke", instance_id, invoke_body); + LOG_PRINT_L0(res); } @@ -56,10 +76,10 @@ int main(int argc, char** argv) { epee::string_tools::set_module_name_and_folder(argv[0]); epee::log_space::get_set_log_detalisation_level(true, LOG_LEVEL_2); - epee::log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL, LOG_LEVEL_2); - epee::log_space::log_singletone::add_logger(LOGGER_FILE, - epee::log_space::log_singletone::get_default_log_file().c_str(), - epee::log_space::log_singletone::get_default_log_folder().c_str()); + //epee::log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL, LOG_LEVEL_2); + //epee::log_space::log_singletone::add_logger(LOGGER_FILE, + // epee::log_space::log_singletone::get_default_log_file().c_str(), + // epee::log_space::log_singletone::get_default_log_folder().c_str()); test_plain_wallet(); //parse_weird_tx(); diff --git a/tests/performance_tests/single_tx_test_base.h b/tests/performance_tests/single_tx_test_base.h index 9bda3809..a605d624 100644 --- a/tests/performance_tests/single_tx_test_base.h +++ b/tests/performance_tests/single_tx_test_base.h @@ -18,9 +18,10 @@ public: m_bob.generate(); uint64_t block_reward_without_fee = 0; - if (!construct_miner_tx(0, 0, 0, 2, 0, m_bob.get_keys().account_address, m_bob.get_keys().account_address, m_tx, block_reward_without_fee, TRANSACTION_VERSION_PRE_HF4, blobdata(), CURRENCY_MINER_TX_MAX_OUTS)) - return false; + uint64_t block_reward = 0; + if(!construct_miner_tx(0, 0, 0, 2, 0, m_bob.get_keys().account_address, m_bob.get_keys().account_address, m_tx, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, blobdata(), CURRENCY_MINER_TX_MAX_OUTS)) + return false; m_tx_pub_key = get_tx_pub_key_from_extra(m_tx); return true; } diff --git a/utils/test_api_files/get_alias_by_address.json b/utils/test_api_files/get_alias_by_address.json new file mode 100644 index 00000000..c89f7e97 --- /dev/null +++ b/utils/test_api_files/get_alias_by_address.json @@ -0,0 +1 @@ +{"method": "get_alias_details","params": {"alias": "zoidb"}} \ No newline at end of file diff --git a/utils/test_api_files/get_alias_details.json b/utils/test_api_files/get_alias_details.json index c89f7e97..27871aa7 100644 --- a/utils/test_api_files/get_alias_details.json +++ b/utils/test_api_files/get_alias_details.json @@ -1 +1 @@ -{"method": "get_alias_details","params": {"alias": "zoidb"}} \ No newline at end of file +{"method": "get_alias_details","params": "ZxCjF84feY7GQZ1fdy9r3ZJABwaFjmb2Dd25H5qANWZ2VufpmyNu7ZnShMBDpiw8VW2k1EjPZswgFZnx3v1EYgJ32Rjn64mq9"} \ No newline at end of file From 2eac22d626580c39d3862e18f75c0ec6e9aa8907 Mon Sep 17 00:00:00 2001 From: sowle Date: Sun, 24 Mar 2024 18:53:26 +0100 Subject: [PATCH 044/184] utils: configuration scripts for msvc2022 --- utils/configure_win64_msvs2022_gui.cmd | 7 +++++++ utils/configure_win64_msvs2022_gui_testnet.cmd | 7 +++++++ 2 files changed, 14 insertions(+) create mode 100644 utils/configure_win64_msvs2022_gui.cmd create mode 100644 utils/configure_win64_msvs2022_gui_testnet.cmd diff --git a/utils/configure_win64_msvs2022_gui.cmd b/utils/configure_win64_msvs2022_gui.cmd new file mode 100644 index 00000000..b5dcbbf5 --- /dev/null +++ b/utils/configure_win64_msvs2022_gui.cmd @@ -0,0 +1,7 @@ +call configure_local_paths_msvs2022.cmd + +cd .. +@mkdir build_msvc2022_64 +cd build_msvc2022_64 + +cmake -D TESTNET=FALSE -D USE_PCH=TRUE -D BUILD_TESTS=TRUE -D OPENSSL_ROOT_DIR="%OPENSSL_ROOT_DIR%" -D CMAKE_PREFIX_PATH="%QT_PREFIX_PATH%"\msvc2019_64 -D BUILD_GUI=TRUE -D STATIC=FALSE -DBOOST_ROOT="%BOOST_ROOT%" -DBOOST_LIBRARYDIR="%BOOST_ROOT%\lib64-msvc-14.3" -G "Visual Studio 17 2022" -A x64 -T host=x64 ".." diff --git a/utils/configure_win64_msvs2022_gui_testnet.cmd b/utils/configure_win64_msvs2022_gui_testnet.cmd new file mode 100644 index 00000000..f41547c3 --- /dev/null +++ b/utils/configure_win64_msvs2022_gui_testnet.cmd @@ -0,0 +1,7 @@ +call configure_local_paths_msvs2022.cmd + +cd .. +@mkdir build_msvc2022_64_tn +cd build_msvc2022_64_tn + +cmake -D TESTNET=TRUE -D USE_PCH=TRUE -D BUILD_TESTS=TRUE -D OPENSSL_ROOT_DIR="%OPENSSL_ROOT_DIR%" -D CMAKE_PREFIX_PATH="%QT_PREFIX_PATH%"\msvc2019_64 -D BUILD_GUI=TRUE -D STATIC=FALSE -DBOOST_ROOT="%BOOST_ROOT%" -DBOOST_LIBRARYDIR="%BOOST_ROOT%\lib64-msvc-14.3" -G "Visual Studio 17 2022" -A x64 -T host=x64 ".." From d83ec66775a05bf6d1cf4797fb538b600b0faebd Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 25 Mar 2024 17:21:02 +0100 Subject: [PATCH 045/184] fixed a bug in prepare_tx_sources_for_defragmentation_tx() causing old dust outs to prevent staking --- src/wallet/wallet2.cpp | 12 +++++++----- src/wallet/wallet2.h | 1 + 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 3c2e45b9..fd3c83ba 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -77,9 +77,10 @@ namespace tools , m_log_prefix("???") , m_watch_only(false) , m_required_decoys_count(CURRENCY_DEFAULT_DECOY_SET_SIZE) + , m_max_allowed_output_amount_for_defragmentation_tx(CURRENCY_BLOCK_REWARD) , m_min_utxo_count_for_defragmentation_tx(WALLET_MIN_UTXO_COUNT_FOR_DEFRAGMENTATION_TX) , m_max_utxo_count_for_defragmentation_tx(WALLET_MAX_UTXO_COUNT_FOR_DEFRAGMENTATION_TX) - , m_decoys_count_for_defragmentation_tx(WALLET_DEFAULT_DECOYS_COUNT_FOR_DEFRAGMENTATION_TX) + , m_decoys_count_for_defragmentation_tx(SIZE_MAX) , m_use_deffered_global_outputs(false) #ifdef DISABLE_TOR , m_disable_tor_relay(true) @@ -5933,10 +5934,11 @@ bool wallet2::prepare_tx_sources_for_defragmentation_tx(std::vector CURRENCY_BLOCK_REWARD) + if (!td.is_native_coin() || td.m_amount > m_max_allowed_output_amount_for_defragmentation_tx) continue; - if (is_transfer_ready_to_go(td, m_decoys_count_for_defragmentation_tx)) + uint64_t fake_outs_count_for_td = m_decoys_count_for_defragmentation_tx == SIZE_MAX ? (td.is_zc() ? m_core_runtime_config.hf4_minimum_mixins : CURRENCY_DEFAULT_DECOY_SET_SIZE) : m_decoys_count_for_defragmentation_tx; + if (is_transfer_ready_to_go(td, fake_outs_count_for_td)) { found_money += td.m_amount; selected_indicies.push_back(i); @@ -5945,7 +5947,7 @@ bool wallet2::prepare_tx_sources_for_defragmentation_tx(std::vector& sources, std::vector& selected_indicies) diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 74df897c..6c68b735 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -877,6 +877,7 @@ private: bool m_do_rise_transfer; + uint64_t m_max_allowed_output_amount_for_defragmentation_tx; uint64_t m_min_utxo_count_for_defragmentation_tx; uint64_t m_max_utxo_count_for_defragmentation_tx; size_t m_decoys_count_for_defragmentation_tx; From 360417c5fc17015319529d9d93fbfac7e7f07c4a Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 25 Mar 2024 17:28:28 +0100 Subject: [PATCH 046/184] === build number: 284 -> 285 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index 2f3a2265..ff34f72e 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 284 +#define PROJECT_VERSION_BUILD_NO 285 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From 9af876ccaaf3ed5659d03bd671129c72b5ee52f9 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Mon, 25 Mar 2024 21:56:22 +0100 Subject: [PATCH 047/184] decoy selection algo refactoring --- src/currency_core/blockchain_storage.cpp | 117 ++-------------- src/currency_core/blockchain_storage.h | 6 +- src/currency_core/currency_config.h | 10 +- src/rpc/core_rpc_server.cpp | 4 +- src/rpc/core_rpc_server.h | 6 +- src/rpc/core_rpc_server_commands_defs.h | 15 +- src/wallet/core_default_rpc_proxy.cpp | 4 +- src/wallet/core_default_rpc_proxy.h | 2 +- src/wallet/core_fast_rpc_proxy.h | 4 +- src/wallet/core_rpc_proxy.h | 2 +- src/wallet/decoy_selection.cpp | 66 ++++++++- src/wallet/decoy_selection.h | 4 + src/wallet/wallet2.cpp | 146 ++++++++++++++++---- src/wallet/wallet2.h | 11 +- tests/CMakeLists.txt | 2 +- tests/core_tests/chaingen.cpp | 6 +- tests/core_tests/chaingen.h | 12 ++ tests/core_tests/wallet_test_core_proxy.cpp | 13 +- tests/core_tests/wallet_test_core_proxy.h | 3 + tests/unit_tests/decoy_selection.cpp | 51 ++++--- 20 files changed, 297 insertions(+), 187 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 43a32e9d..b818c746 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -2548,7 +2548,7 @@ bool blockchain_storage::add_out_to_get_random_outs(COMMAND_RPC_GET_RANDOM_OUTPU CHECK_AND_ASSERT_MES(tx_ptr->tx.vout.size() > out_ptr->out_no, false, "internal error: in global outs index, transaction out index=" << out_ptr->out_no << " is greater than transaction outputs = " << tx_ptr->tx.vout.size() << ", for tx id = " << out_ptr->tx_id); - CHECK_AND_ASSERT_MES(amount != 0 || height_upper_limit != 0, false, "height_upper_limit must be nonzero for hidden amounts (amount = 0)"); + //CHECK_AND_ASSERT_MES(amount != 0 || height_upper_limit != 0, false, "height_upper_limit must be nonzero for hidden amounts (amount = 0)"); if (height_upper_limit != 0 && tx_ptr->m_keeper_block_height > height_upper_limit) return false; @@ -2694,9 +2694,9 @@ bool blockchain_storage::get_random_outs_for_amounts(const COMMAND_RPC_GET_RANDO return true; } //------------------------------------------------------------------ -bool blockchain_storage::get_target_outs_for_amount_prezarcanum(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request& req, const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::offsets_distribution& details, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, std::map& amounts_to_up_index_limit_cache) const +bool blockchain_storage::get_target_outs_for_amount_prezarcanum(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request& req, const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::offsets_distribution& details, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, std::map& amounts_to_up_index_limit_cache) const { - size_t decoys_count = details.offsets.size(); + size_t decoys_count = details.global_offsets.size(); uint64_t amount = details.amount; uint64_t outs_container_size = m_db_outputs.get_item_size(details.amount); @@ -2723,7 +2723,7 @@ bool blockchain_storage::get_target_outs_for_amount_prezarcanum(const COMMAND_RP if (up_index_limit >= decoys_count) { std::set used; - used.insert(details.own_global_index); + //used.insert(details.own_global_index); for (uint64_t j = 0; j != decoys_count || used.size() >= up_index_limit;) { size_t g_index_initial = crypto::rand() % up_index_limit; @@ -2766,110 +2766,23 @@ bool blockchain_storage::get_target_outs_for_amount_prezarcanum(const COMMAND_RP } } //------------------------------------------------------------------ -bool blockchain_storage::get_target_outs_for_postzarcanum(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request& req, const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::offsets_distribution& details, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, std::map& amounts_to_up_index_limit_cache) const +bool blockchain_storage::get_target_outs_for_postzarcanum(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request& req, const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::offsets_distribution& details, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, std::map& amounts_to_up_index_limit_cache) const { - std::set used; - used.insert(details.own_global_index); - for (auto offset : details.offsets) + for (auto global_index : details.global_offsets) { - - //perfectly we would need to find transaction's output on the given height, with the given probability - //of being coinbase(coinbase outputs should be included less in decoy selection algorithm) - bool is_coinbase = (crypto::rand() % 101) > req.coinbase_percents ? false : true; - - //TODO: Consider including PoW coinbase to transactions(does it needed?) - - // convert offset to estimated height - uint64_t estimated_h = this->get_current_blockchain_size() - 1 - offset; - //make sure it's after zc hardfork - if (estimated_h < m_core_runtime_config.hard_forks.m_height_the_hardfork_n_active_after[ZANO_HARDFORK_04_ZARCANUM]) - { - LOG_ERROR("Wrong estimated offset(" << offset << "), it hits zone before zarcanum hardfork"); - return false; - } - -#define TARGET_RANDOM_OUTS_SELECTIOM_POOL_MIN 10 - //try to find output around given H - std::vector selected_global_indexes; - auto process_tx = [&](const crypto::hash& tx_id) { - - auto tx_ptr = m_db_transactions.find(tx_id); - CHECK_AND_ASSERT_THROW_MES(tx_ptr, "internal error: tx_id " << tx_id << " around estimated_h = " << estimated_h << " not found in db"); - //go through tx outputs - for (size_t i = 0; i != tx_ptr->tx.vout.size(); i++) - { - if (tx_ptr->tx.vout[i].type() != typeid(tx_out_zarcanum)) - { - continue; - } - const tx_out_zarcanum& z_out = boost::get(tx_ptr->tx.vout[i]); - - // NOTE: second part of condition (mix_attr >= CURRENCY_TO_KEY_OUT_FORCED_MIX_LOWER_BOUND && ..) might be not accurate - // since the wallet might want to request more inputs then it planning to do mixins. For now let's keep it this way and fix - // it if we see the problems about it. - if (z_out.mix_attr == CURRENCY_TO_KEY_OUT_FORCED_NO_MIX || (z_out.mix_attr >= CURRENCY_TO_KEY_OUT_FORCED_MIX_LOWER_BOUND && z_out.mix_attr < details.offsets.size())) - { - continue; - } - - // skip spent outptus - if (tx_ptr->m_spent_flags[i]) - { - continue; - } - - if (used.find(tx_ptr->m_global_output_indexes[i]) != used.end()) - { - continue; - } - - // add output - // note: code that will process selected_global_indes will be revisiting transactions entries to obtain all - // needed data, that should work relatively effective because of on-top-of-db cache keep daya unserialized - selected_global_indexes.push_back(tx_ptr->m_global_output_indexes[i]); - } - - }; - - while (selected_global_indexes.size() < TARGET_RANDOM_OUTS_SELECTIOM_POOL_MIN) - { - auto block_ptr = m_db_blocks.get(estimated_h); - if (is_coinbase && is_pos_block(block_ptr->bl) ) - { - process_tx(get_transaction_hash(block_ptr->bl.miner_tx)); - } - else - { - //looking for regular output of regular transactions - for (auto tx_id : block_ptr->bl.tx_hashes) - { - process_tx(tx_id); - } - } - if(estimated_h) - estimated_h--; - else - { - //likely unusual situation when blocks enumerated all way back to genesis - //let's check if we have at least something - if (!selected_global_indexes.size()) - { - //need to regenerate offsets - return false; - } - } - } - //pick up a random output from selected_global_indes - uint64_t global_index = selected_global_indexes[crypto::rand() % selected_global_indexes.size()]; - bool res = add_out_to_get_random_outs(result_outs, details.amount, global_index, details.offsets.size(), req.use_forced_mix_outs, req.height_upper_limit); - CHECK_AND_ASSERT_THROW_MES(res, "Failed to add_out_to_get_random_outs([" << global_index << "]) at postzarcanum era"); - used.insert(global_index); + bool res = add_out_to_get_random_outs(result_outs, details.amount, global_index, this->get_core_runtime_config().hf4_minimum_mixins, false); + if (!res) + { + COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::out_entry& oen = *result_outs.outs.insert(result_outs.outs.end(), COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::out_entry{}); + oen.flags = RANDOM_OUTPUTS_FOR_AMOUNTS_FLAGS_NOT_ALLOWED; + } } + CHECK_AND_ASSERT_THROW_MES(details.global_offsets.size() == result_outs.outs.size(), "details.global_offsets.size() == result_outs.outs.size() check failed"); return true; } //------------------------------------------------------------------ -bool blockchain_storage::get_random_outs_for_amounts2(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::response& res)const +bool blockchain_storage::get_random_outs_for_amounts3(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::response& res)const { CRITICAL_REGION_LOCAL(m_read_lock); LOG_PRINT_L3("[get_random_outs_for_amounts] amounts: " << req.amounts.size()); @@ -2887,7 +2800,7 @@ bool blockchain_storage::get_random_outs_for_amounts2(const COMMAND_RPC_GET_RAND result_outs.amount = amount; bool r = false; - if (amount == 0 && count_zarcanum_blocks > 20000) + if (amount == 0) { //zarcanum era inputs r = get_target_outs_for_postzarcanum(req, req.amounts[i], result_outs, amounts_to_up_index_limit_cache); diff --git a/src/currency_core/blockchain_storage.h b/src/currency_core/blockchain_storage.h index e448f2d0..c59bdcd0 100644 --- a/src/currency_core/blockchain_storage.h +++ b/src/currency_core/blockchain_storage.h @@ -286,7 +286,7 @@ namespace currency bool handle_get_objects(NOTIFY_REQUEST_GET_OBJECTS::request& arg, NOTIFY_RESPONSE_GET_OBJECTS::request& rsp)const; bool handle_get_objects(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res)const; bool get_random_outs_for_amounts(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res)const; - bool get_random_outs_for_amounts2(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::response& res)const; + bool get_random_outs_for_amounts3(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::response& res)const; bool get_backward_blocks_sizes(size_t from_height, std::vector& sz, size_t count)const; bool get_tx_outputs_gindexs(const crypto::hash& tx_id, std::vector& indexs)const; bool get_alias_info(const std::string& alias, extra_alias_entry_base& info)const; @@ -643,8 +643,8 @@ namespace currency bool push_transaction_to_global_outs_index(const transaction& tx, const crypto::hash& tx_id, std::vector& global_indexes); bool pop_transaction_from_global_index(const transaction& tx, const crypto::hash& tx_id); bool add_out_to_get_random_outs(COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, uint64_t amount, size_t i, uint64_t mix_count, bool use_only_forced_to_mix = false, uint64_t height_upper_limit = 0) const; - bool get_target_outs_for_amount_prezarcanum(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request& req, const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::offsets_distribution& details, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, std::map& amounts_to_up_index_limit_cache) const; - bool get_target_outs_for_postzarcanum(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request& req, const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::offsets_distribution& details, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, std::map& amounts_to_up_index_limit_cache) const; + bool get_target_outs_for_amount_prezarcanum(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request& req, const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::offsets_distribution& details, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, std::map& amounts_to_up_index_limit_cache) const; + bool get_target_outs_for_postzarcanum(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request& req, const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::offsets_distribution& details, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, std::map& amounts_to_up_index_limit_cache) const; bool add_block_as_invalid(const block& bl, const crypto::hash& h); bool add_block_as_invalid(const block_extended_info& bei, const crypto::hash& h); size_t find_end_of_allowed_index(uint64_t amount)const; diff --git a/src/currency_core/currency_config.h b/src/currency_core/currency_config.h index 50ca76a8..487502f4 100644 --- a/src/currency_core/currency_config.h +++ b/src/currency_core/currency_config.h @@ -249,13 +249,9 @@ #define BC_OFFERS_CURRENT_OFFERS_SERVICE_ARCHIVE_VER CURRENCY_FORMATION_VERSION + BLOCKCHAIN_STORAGE_MAJOR_COMPATIBILITY_VERSION + 9 #define BC_OFFERS_CURRENCY_MARKET_FILENAME "market.bin" -#ifndef TESTNET -#define WALLET_FILE_SERIALIZATION_VERSION 163 -#define WALLET_FILE_LAST_SUPPORTED_VERSION 163 -#else -#define WALLET_FILE_LAST_SUPPORTED_VERSION (CURRENCY_FORMATION_VERSION+76) -#define WALLET_FILE_SERIALIZATION_VERSION (CURRENCY_FORMATION_VERSION+76) -#endif + +#define WALLET_FILE_SERIALIZATION_VERSION 165 +#define WALLET_FILE_LAST_SUPPORTED_VERSION 165 #define CURRENT_MEMPOOL_ARCHIVE_VER (CURRENCY_FORMATION_VERSION+31) diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 77774cc1..d45e9704 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -418,11 +418,11 @@ namespace currency return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_random_outs2(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::response& res, connection_context& cntx) + bool core_rpc_server::on_get_random_outs3(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::response& res, connection_context& cntx) { CHECK_CORE_READY(); res.status = API_RETURN_CODE_FAIL; - if (!m_core.get_blockchain_storage().get_random_outs_for_amounts2(req, res)) + if (!m_core.get_blockchain_storage().get_random_outs_for_amounts3(req, res)) { return true; } diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h index 2c7b47a9..e88f6dbf 100644 --- a/src/rpc/core_rpc_server.h +++ b/src/rpc/core_rpc_server.h @@ -50,7 +50,7 @@ namespace currency bool on_stop_mining(const COMMAND_RPC_STOP_MINING::request& req, COMMAND_RPC_STOP_MINING::response& res, connection_context& cntx); bool on_get_random_outs(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_LEGACY::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_LEGACY::response& res, connection_context& cntx); bool on_get_random_outs1(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res, connection_context& cntx); - bool on_get_random_outs2(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::response& res, connection_context& cntx); + bool on_get_random_outs3(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::response& res, connection_context& cntx); bool on_get_info(const COMMAND_RPC_GET_INFO::request& req, COMMAND_RPC_GET_INFO::response& res, connection_context& cntx); bool on_set_maintainers_info(const COMMAND_RPC_SET_MAINTAINERS_INFO::request& req, COMMAND_RPC_SET_MAINTAINERS_INFO::response& res, connection_context& cntx); bool on_get_tx_pool(const COMMAND_RPC_GET_TX_POOL::request& req, COMMAND_RPC_GET_TX_POOL::response& res, connection_context& cntx); @@ -112,7 +112,7 @@ namespace currency MAP_URI_AUTO_BIN2("/get_o_indexes.bin", on_get_indexes, COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES) MAP_URI_AUTO_BIN2("/getrandom_outs.bin", on_get_random_outs, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_LEGACY) MAP_URI_AUTO_BIN2("/getrandom_outs1.bin", on_get_random_outs1, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS) - MAP_URI_AUTO_BIN2("/getrandom_outs2.bin", on_get_random_outs2, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2) + MAP_URI_AUTO_BIN2("/getrandom_outs3.bin", on_get_random_outs3, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3) MAP_URI_AUTO_BIN2("/set_maintainers_info.bin", on_set_maintainers_info, COMMAND_RPC_SET_MAINTAINERS_INFO) MAP_URI_AUTO_BIN2("/get_tx_pool.bin", on_get_tx_pool, COMMAND_RPC_GET_TX_POOL) MAP_URI_AUTO_BIN2("/check_keyimages.bin", on_check_keyimages, COMMAND_RPC_CHECK_KEYIMAGES) @@ -146,7 +146,7 @@ namespace currency MAP_JON_RPC ("get_pool_info", on_get_pool_info, COMMAND_RPC_GET_POOL_INFO) MAP_JON_RPC ("getrandom_outs", on_get_random_outs, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_LEGACY) MAP_JON_RPC ("getrandom_outs1", on_get_random_outs1, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS) - MAP_JON_RPC ("getrandom_outs2", on_get_random_outs2, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2) + MAP_JON_RPC ("getrandom_outs3", on_get_random_outs3, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3) MAP_JON_RPC ("get_votes", on_get_votes, COMMAND_RPC_GET_VOTES) //assets api MAP_JON_RPC ("get_asset_info", on_get_asset_info, COMMAND_RPC_GET_ASSET_INFO) diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 8850e584..03284a6e 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -380,6 +380,10 @@ namespace currency END_KV_SERIALIZE_MAP() }; + +#define RANDOM_OUTPUTS_FOR_AMOUNTS_FLAGS_COINBASE 0x0000000000000001LL +#define RANDOM_OUTPUTS_FOR_AMOUNTS_FLAGS_NOT_ALLOWED 0x0000000000000002LL + #pragma pack (push, 1) struct out_entry { @@ -395,12 +399,13 @@ namespace currency crypto::public_key concealing_point; // premultiplied by 1/8 crypto::public_key amount_commitment; // premultiplied by 1/8 crypto::public_key blinded_asset_id; // premultiplied by 1/8 + uint64_t flags; }; #pragma pack(pop) struct outs_for_amount { - uint64_t amount; + uint64_t amount = 0; std::list outs; BEGIN_KV_SERIALIZE_MAP() @@ -420,18 +425,16 @@ namespace currency }; }; //----------------------------------------------- - struct COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2 + struct COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3 { struct offsets_distribution { uint64_t amount; //if amount is 0 then lookup in post-zarcanum zone only, if not 0 then pre-zarcanum only - std::vector offsets; //[i] = height, estimated location where to pickup output of transaction - uint64_t own_global_index; //index to exclude from selection + std::vector global_offsets; //[i] = global_index to pick up BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(amount) - KV_SERIALIZE(offsets) - KV_SERIALIZE(own_global_index) + KV_SERIALIZE(global_offsets) END_KV_SERIALIZE_MAP() }; diff --git a/src/wallet/core_default_rpc_proxy.cpp b/src/wallet/core_default_rpc_proxy.cpp index 8223cd06..0836cb75 100644 --- a/src/wallet/core_default_rpc_proxy.cpp +++ b/src/wallet/core_default_rpc_proxy.cpp @@ -76,9 +76,9 @@ namespace tools return invoke_http_bin_remote_command2_update_is_disconnect("/getrandom_outs1.bin", req, res); } //------------------------------------------------------------------------------------------------------------------------------ - bool default_http_core_proxy::call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2(const currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request& req, currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::response& res) + bool default_http_core_proxy::call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3(const currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request& req, currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::response& res) { - return invoke_http_bin_remote_command2_update_is_disconnect("/getrandom_outs2.bin", req, res); + return invoke_http_bin_remote_command2_update_is_disconnect("/getrandom_outs3.bin", req, res); } //------------------------------------------------------------------------------------------------------------------------------ bool default_http_core_proxy::call_COMMAND_RPC_SEND_RAW_TX(const currency::COMMAND_RPC_SEND_RAW_TX::request& req, currency::COMMAND_RPC_SEND_RAW_TX::response& res) diff --git a/src/wallet/core_default_rpc_proxy.h b/src/wallet/core_default_rpc_proxy.h index 2d28c071..b27cbbcf 100644 --- a/src/wallet/core_default_rpc_proxy.h +++ b/src/wallet/core_default_rpc_proxy.h @@ -37,7 +37,7 @@ namespace tools bool call_COMMAND_RPC_GET_TX_POOL(const currency::COMMAND_RPC_GET_TX_POOL::request& rqt, currency::COMMAND_RPC_GET_TX_POOL::response& rsp) override; bool call_COMMAND_RPC_GET_ALIASES_BY_ADDRESS(const currency::COMMAND_RPC_GET_ALIASES_BY_ADDRESS::request& rqt, currency::COMMAND_RPC_GET_ALIASES_BY_ADDRESS::response& rsp) override; bool call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS(const currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& rqt, currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& rsp) override; - bool call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2(const currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request& rqt, currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::response& rsp) override; + bool call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3(const currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request& rqt, currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::response& rsp) override; bool call_COMMAND_RPC_SEND_RAW_TX(const currency::COMMAND_RPC_SEND_RAW_TX::request& rqt, currency::COMMAND_RPC_SEND_RAW_TX::response& rsp) override; bool call_COMMAND_RPC_FORCE_RELAY_RAW_TXS(const currency::COMMAND_RPC_FORCE_RELAY_RAW_TXS::request& rqt, currency::COMMAND_RPC_FORCE_RELAY_RAW_TXS::response& rsp) override; bool call_COMMAND_RPC_GET_ALL_ALIASES(currency::COMMAND_RPC_GET_ALL_ALIASES::response& rsp) override; diff --git a/src/wallet/core_fast_rpc_proxy.h b/src/wallet/core_fast_rpc_proxy.h index 3d212676..d96ee86f 100644 --- a/src/wallet/core_fast_rpc_proxy.h +++ b/src/wallet/core_fast_rpc_proxy.h @@ -58,9 +58,9 @@ namespace tools return m_rpc.on_get_random_outs1(req, res, m_cntxt_stub); } //------------------------------------------------------------------------------------------------------------------------------ - bool call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2(const currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request& req, currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::response& res) override + bool call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3(const currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request& req, currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::response& res) override { - return m_rpc.on_get_random_outs2(req, res, m_cntxt_stub); + return m_rpc.on_get_random_outs3(req, res, m_cntxt_stub); } //------------------------------------------------------------------------------------------------------------------------------ bool call_COMMAND_RPC_SEND_RAW_TX(const currency::COMMAND_RPC_SEND_RAW_TX::request& req, currency::COMMAND_RPC_SEND_RAW_TX::response& res) override diff --git a/src/wallet/core_rpc_proxy.h b/src/wallet/core_rpc_proxy.h index effec340..1ab16633 100644 --- a/src/wallet/core_rpc_proxy.h +++ b/src/wallet/core_rpc_proxy.h @@ -36,7 +36,7 @@ namespace tools virtual bool call_COMMAND_RPC_GET_TX_POOL(const currency::COMMAND_RPC_GET_TX_POOL::request& rqt, currency::COMMAND_RPC_GET_TX_POOL::response& rsp){ return false; } virtual bool call_COMMAND_RPC_GET_ALIASES_BY_ADDRESS(const currency::COMMAND_RPC_GET_ALIASES_BY_ADDRESS::request& rqt, currency::COMMAND_RPC_GET_ALIASES_BY_ADDRESS::response& rsp){ return false; } virtual bool call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS(const currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& rqt, currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& rsp){ return false; } - virtual bool call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2(const currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request& rqt, currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::response& rsp) { return false; } + virtual bool call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3(const currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request& rqt, currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::response& rsp) { return false; } virtual bool call_COMMAND_RPC_SEND_RAW_TX(const currency::COMMAND_RPC_SEND_RAW_TX::request& rqt, currency::COMMAND_RPC_SEND_RAW_TX::response& rsp){ return false; } virtual bool call_COMMAND_RPC_FORCE_RELAY_RAW_TXS(const currency::COMMAND_RPC_FORCE_RELAY_RAW_TXS::request& rqt, currency::COMMAND_RPC_FORCE_RELAY_RAW_TXS::response& rsp){ return false; } virtual bool call_COMMAND_RPC_GET_ALL_ALIASES(currency::COMMAND_RPC_GET_ALL_ALIASES::response& rsp){ return false; } diff --git a/src/wallet/decoy_selection.cpp b/src/wallet/decoy_selection.cpp index a75f333d..7a3c8d01 100644 --- a/src/wallet/decoy_selection.cpp +++ b/src/wallet/decoy_selection.cpp @@ -24,9 +24,10 @@ uint64_t scaler::scale(uint64_t h) void decoy_selection_generator::init(uint64_t max_h) { + load_distribution(g_default_distribution, max_h); m_is_initialized = true; - + m_max = max_h; // distribution INCLUDE m_max, count = m_max + 1 } bool decoy_selection_generator::load_distribution_from_file(const char* path) { @@ -66,6 +67,60 @@ std::vector decoy_selection_generator::generate_distribution(uint64_t return res; } + +std::vector decoy_selection_generator::generate_unique_reversed_distribution(uint64_t count) +{ + std::set set_to_extend; + generate_unique_reversed_distribution(count, set_to_extend); + return std::vector(set_to_extend.begin(), set_to_extend.end()); +} + +std::vector decoy_selection_generator::generate_unique_reversed_distribution(uint64_t count, uint64_t preincluded_item) +{ + std::set set_to_extend; + set_to_extend.insert(preincluded_item); + generate_unique_reversed_distribution(count, set_to_extend); + return std::vector(set_to_extend.begin(), set_to_extend.end()); +} + +#define DECOY_SELECTION_GENERATOR_MAX_ITERATIONS 1000000 + +void decoy_selection_generator::generate_unique_reversed_distribution(uint64_t count, std::set& set_to_extend) +{ + if (count + set_to_extend.size() > m_max) + { + throw std::runtime_error("generate_distribution_set with unexpected count"); + } + + size_t attempt_count = 0; + while (set_to_extend.size() != count) + { + attempt_count++; + if (attempt_count > DECOY_SELECTION_GENERATOR_MAX_ITERATIONS) + { + throw std::runtime_error("generate_distribution_set: attempt_count hit DECOY_SELECTION_GENERATOR_MAX_ITERATIONS"); + } + + uint64_t r = 0; + crypto::generate_random_bytes(sizeof(r), &r); + double r_ = map_uint_to_double(r); + auto it = m_distribution_mapping.upper_bound(r_); + if (it == m_distribution_mapping.end()) + { + throw(std::runtime_error(std::string("_r not found in m_distribution_mapping: ") + std::to_string(r_))); + } + uint64_t h = it->second; + if (it != m_distribution_mapping.begin()) + { + uint64_t h_0 = (--it)->second; + crypto::generate_random_bytes(sizeof(r), &r); + h = h_0 + r % (h - h_0) + 1; + } + //scale from nominal to max_h + set_to_extend.insert(m_max - h); + } +} + uint64_t get_distance(const std::vector entries, size_t i) { if (i == 0) @@ -79,7 +134,8 @@ bool decoy_selection_generator::load_distribution(const std::vector derived_distribution; scaler scl; - scl.config_scale(original_distribution.back().h, max_h); + uint64_t adjustment_value = original_distribution[0].h; + scl.config_scale(original_distribution.back().h - adjustment_value, max_h); uint64_t last_scaled_h = 0; std::list last_scaled_array; @@ -87,7 +143,7 @@ bool decoy_selection_generator::load_distribution(const std::vector generate_distribution(uint64_t count); + std::vector generate_unique_reversed_distribution(uint64_t count, uint64_t preincluded_item); + std::vector generate_unique_reversed_distribution(uint64_t count); + void generate_unique_reversed_distribution(uint64_t count, std::set& set_to_extend); bool is_initialized() { return m_is_initialized; } private: bool load_distribution(const std::vector& entries, uint64_t max_h); bool m_is_initialized = false; + uint64_t m_max = 0; std::map m_distribution_mapping; }; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index fd3c83ba..f212d2bb 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -62,6 +62,10 @@ using namespace currency; #define WALLET_TX_MAX_ALLOWED_FEE (COIN * 100) +#define WALLET_FETCH_RANDOM_OUTS_SIZE 200 + + + #undef LOG_DEFAULT_CHANNEL #define LOG_DEFAULT_CHANNEL "wallet" ENABLE_CHANNEL_BY_DEFAULT("wallet") @@ -527,8 +531,18 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t //PoW block don't have change, so all outs supposed to be marked as "mined" ptc.is_derived_from_coinbase = !ptc.is_pos_coinbase; ptc.height = height; - - + WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(pglobal_indexes, "pglobal_indexes not set"); + if (this->is_in_hardfork_zone(ZANO_HARDFORK_04_ZARCANUM)) + { + if (pglobal_indexes->size()) + { + //store global index that is under coinage, so we can used in decoy selection algo + if (ptc.height < m_last_known_daemon_height && m_last_known_daemon_height - ptc.height > WALLET_DEFAULT_TX_SPENDABLE_AGE) + { + m_last_zc_global_index = pglobal_indexes->back(); + } + } + } for(auto& in : tx.vin) { @@ -1970,12 +1984,14 @@ void wallet2::handle_pulled_blocks(size_t& blocks_added, std::atomic& stop currency::COMMAND_RPC_GET_BLOCKS_DIRECT::response& res) { size_t current_index = res.start_height; + m_last_known_daemon_height = res.current_height; bool been_matched_block = false; if (res.start_height == 0 && get_blockchain_current_size() == 1 && !res.blocks.empty()) { const currency::block& genesis = res.blocks.front().block_ptr->bl; THROW_IF_TRUE_WALLET_EX(get_block_height(genesis) != 0, error::wallet_internal_error, "first block expected to be genesis"); - process_genesis_if_needed(genesis); + WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(res.blocks.front().coinbase_ptr, "Unexpected empty coinbase"); + process_genesis_if_needed(genesis, &(res.blocks.front().coinbase_ptr->m_global_output_indexes)); res.blocks.pop_front(); ++current_index; been_matched_block = true; @@ -5970,17 +5986,18 @@ bool wallet2::prepare_tx_sources(assets_selection_context& needed_money_map, siz //---------------------------------------------------------------------------------------------------- void wallet2::prefetch_global_indicies_if_needed(const std::vector& selected_indicies) { - std::list> txs; - std::list indices_that_requested_global_indicies; + //std::list> txs; + //std::list indices_that_requested_global_indicies; for (uint64_t i : selected_indicies) { - if (m_transfers[i].m_global_output_index == WALLET_GLOBAL_OUTPUT_INDEX_UNDEFINED) - { - indices_that_requested_global_indicies.push_back(i); - txs.push_back(m_transfers[i].m_ptx_wallet_info->m_tx); - } + WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(m_transfers[i].m_global_output_index != WALLET_GLOBAL_OUTPUT_INDEX_UNDEFINED, + "m_transfers[" << i << "].m_global_output_index is WALLET_GLOBAL_OUTPUT_INDEX_UNDEFINED"); + //indices_that_requested_global_indicies.push_back(i); + //txs.push_back(m_transfers[i].m_ptx_wallet_info->m_tx); + //} } + /* std::vector > outputs_for_all_txs; fetch_tx_global_indixes(txs, outputs_for_all_txs); WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(txs.size() == outputs_for_all_txs.size(), "missmatch sizes txs.size() == outputs_for_all_txs.size()"); @@ -5991,7 +6008,7 @@ void wallet2::prefetch_global_indicies_if_needed(const std::vector& se transfer_details& td = m_transfers[*it_indices]; td.m_global_output_index = (*it_ooutputs)[td.m_internal_output_index]; it_ooutputs++; it_indices++; - } + }*/ } //---------------------------------------------------------------------------------------------------- bool wallet2::prepare_tx_sources(size_t fake_outputs_count_, std::vector& sources, const std::vector& selected_indicies) @@ -6011,26 +6028,26 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count_, std::vector= zarcanum_start_from) { //in Zarcanum era - const uint64_t test_scale_size = current_size - 1 - zarcanum_start_from; - zarcanum_decoy_set_generator.init(test_scale_size - 1); + //const uint64_t test_scale_size = current_size - 1 - zarcanum_start_from; + zarcanum_decoy_set_generator.init(m_last_zc_global_index); } bool need_to_request = fake_outputs_count != 0; - COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request req = AUTO_VAL_INIT(req); + COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request req = AUTO_VAL_INIT(req); req.height_upper_limit = m_last_pow_block_h; // request decoys to be either older than, or the same age as stake output's height req.use_forced_mix_outs = false; // TODO: add this feature to UI later //req.decoys_count = fake_outputs_count + 1; // one more to be able to skip a decoy in case it hits the real output for (uint64_t i: selected_indicies) { - req.amounts.push_back(COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::offsets_distribution()); - COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::offsets_distribution& rdisttib = req.amounts.back(); + req.amounts.push_back(COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::offsets_distribution()); + COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::offsets_distribution& rdisttib = req.amounts.back(); auto it = m_transfers.begin() + i; WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(it->m_ptx_wallet_info->m_tx.vout.size() > it->m_internal_output_index, "m_internal_output_index = " << it->m_internal_output_index << " is greater or equal to outputs count = " << it->m_ptx_wallet_info->m_tx.vout.size()); - rdisttib.own_global_index = it->m_global_output_index; + //rdisttib.own_global_index = it->m_global_output_index; //check if we have Zarcanum era output of pre-Zarcanum if (it->is_zc()) { @@ -6039,15 +6056,14 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count_, std::vectorm_global_output_index); need_to_request = true; } else { //for prezarcanum era use flat distribution rdisttib.amount = it->m_amount; - rdisttib.offsets.resize(fake_outputs_count, 0); + rdisttib.global_offsets.resize(fake_outputs_count + 1, 0); } } if (need_to_request) @@ -6056,7 +6072,7 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count_, std::vectorcall_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2(req, daemon_resp); + bool r = m_core_proxy->call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3(req, daemon_resp); THROW_IF_FALSE_WALLET_EX(r, error::no_connection_to_daemon, "getrandom_outs2.bin"); if (daemon_resp.status == API_RETURN_CODE_FAIL) { @@ -6080,10 +6096,9 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count_, std::vector scanty_outs; THROW_IF_FALSE_WALLET_EX(daemon_resp.outs.size() == req.amounts.size(), error::not_enough_outs_to_mix, scanty_outs, fake_outputs_count); - //for (COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& amount_outs : daemon_resp.outs) for(size_t i = 0; i != daemon_resp.outs.size(); i++) { - if (daemon_resp.outs[i].outs.size() != req.amounts[i].offsets.size()) + if (req.amounts[i].amount != 0 && daemon_resp.outs[i].outs.size() != req.amounts[i].global_offsets.size()) { scanty_outs.push_back(daemon_resp.outs[i]); } @@ -6093,6 +6108,7 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count_, std::vector= fake_outputs_count) break; @@ -6188,6 +6214,72 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count_, std::vector +typename t_obj_container::value_type extract_random_from_container(t_obj_container& container) +{ + auto it = container.begin(); + std::advance(it, (crypto::rand() % container.size())); + typename t_obj_container::value_type obj = *it; + container.erase(it); + return obj; +} +//---------------------------------------------------------------------------------------------------------------- +void wallet2::select_decoys(currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& amount_entry, uint64_t own_g_index) +{ + THROW_IF_FALSE_WALLET_INT_ERR_EX(amount_entry.amount == 0, "Amount is not 0 in zc decoys entry"); + typedef currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::out_entry out_entry; + + //TODO: This strategy would be a subject for continuous refactoring + + //first take all real transactions if ther are some + std::list local_outs; + std::list coinbases; + + while (amount_entry.outs.size() && local_outs.size() != m_core_runtime_config.hf4_minimum_mixins) + { + out_entry entry = extract_random_from_container(amount_entry.outs); + + //skip auditable + if ((entry.flags & (RANDOM_OUTPUTS_FOR_AMOUNTS_FLAGS_NOT_ALLOWED))) + { + continue; + } + if (entry.flags & (RANDOM_OUTPUTS_FOR_AMOUNTS_FLAGS_COINBASE)) + { + coinbases.push_back(entry); + continue; + } + // + if (entry.global_amount_index == own_g_index) + { + continue; + } + + local_outs.push_back(entry); + } + + //extend with coin base outs if needed + while (coinbases.size() && local_outs.size() != m_core_runtime_config.hf4_minimum_mixins) + { + out_entry entry = extract_random_from_container(coinbases); + local_outs.push_back(entry); + } + + THROW_IF_FALSE_WALLET_INT_ERR_EX(local_outs.size() == m_core_runtime_config.hf4_minimum_mixins, "Amount is not 0 in zc decoys entry"); + amount_entry.outs = local_outs; +} +//---------------------------------------------------------------------------------------------------------------- +void wallet2::build_distribution_for_input(decoy_selection_generator& zarcanum_decoy_set_generator, std::vector& offsets, uint64_t own_index) +{ + THROW_IF_FALSE_WALLET_INT_ERR_EX(zarcanum_decoy_set_generator.is_initialized(), "zarcanum_decoy_set_generator are not initialized"); + if (m_core_runtime_config.hf4_minimum_mixins) + { + offsets = zarcanum_decoy_set_generator.generate_unique_reversed_distribution(m_last_zc_global_index - 1 > WALLET_FETCH_RANDOM_OUTS_SIZE ? WALLET_FETCH_RANDOM_OUTS_SIZE: m_last_zc_global_index - 1, own_index); + } +} //---------------------------------------------------------------------------------------------------------------- bool wallet2::prepare_tx_sources(crypto::hash multisig_id, std::vector& sources, uint64_t& found_money) { @@ -6719,7 +6811,7 @@ bool wallet2::prepare_free_transfers_cache(uint64_t fake_outputs_count) if (td.m_zc_info_ptr) { //zarcanum out, redefine fake_outputs_count - fake_outputs_count_local = this->is_auditable() ? 0 : CURRENCY_HF4_MANDATORY_DECOY_SET_SIZE; + fake_outputs_count_local = this->is_auditable() ? 0 : m_core_runtime_config.hf4_minimum_mixins; } if (is_transfer_able_to_go(td, fake_outputs_count_local)) { @@ -6824,7 +6916,7 @@ bool wallet2::is_connected_to_net() return (res.synchronized_connections_count) ? true : false; } //---------------------------------------------------------------------------------------------------- -void wallet2::process_genesis_if_needed(const currency::block& genesis) +void wallet2::process_genesis_if_needed(const currency::block& genesis, const std::vector* pglobal_indexes) { if (!m_transfers.empty() || !m_key_images.empty()) return; @@ -6842,7 +6934,7 @@ void wallet2::process_genesis_if_needed(const currency::block& genesis) m_last_bc_timestamp = genesis.timestamp; WLT_LOG_L2("Processing genesis block: " << genesis_hash); - process_new_transaction(genesis.miner_tx, 0, genesis, nullptr); + process_new_transaction(genesis.miner_tx, 0, genesis, pglobal_indexes); } //---------------------------------------------------------------------------------------------------- void wallet2::set_genesis(const crypto::hash& genesis_hash) diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 6c68b735..5ea7a30b 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -46,6 +46,7 @@ #include "currency_core/pos_mining.h" #include "view_iface.h" #include "wallet2_base.h" +#include "decoy_selection.h" #define WALLET_DEFAULT_TX_SPENDABLE_AGE CURRENCY_HF4_MANDATORY_MIN_COINAGE #define WALLET_POS_MINT_CHECK_HEIGHT_INTERVAL 1 @@ -147,6 +148,9 @@ namespace tools std::unordered_map m_pending_key_images; // (out_pk -> ki) pairs of change outputs to be added in watch-only wallet without spend sec key uint64_t m_last_pow_block_h = 0; std::list> m_rollback_events; + uint64_t m_last_zc_global_index = 0; + + //variables that not being serialized std::atomic m_last_bc_timestamp = 0; @@ -218,6 +222,7 @@ namespace tools a & m_rollback_events; a & m_whitelisted_assets; a & m_use_assets_whitelisting; + a & m_last_zc_global_index; } }; @@ -754,7 +759,7 @@ private: bool scan_not_compliant_unconfirmed_txs(); const currency::transaction& get_transaction_by_id(const crypto::hash& tx_hash); void rise_on_transfer2(const wallet_public::wallet_transfer_info& wti); - void process_genesis_if_needed(const currency::block& genesis); + void process_genesis_if_needed(const currency::block& genesis, const std::vector* pglobal_indexes); bool build_escrow_proposal(bc_services::contract_private_details& ecrow_details, uint64_t fee, uint64_t unlock_time, currency::tx_service_attachment& att, std::vector& selected_indicies); bool prepare_tx_sources(assets_selection_context& needed_money_map, size_t fake_outputs_count, uint64_t dust_threshold, std::vector& sources, std::vector& selected_indicies); bool prepare_tx_sources(size_t fake_outputs_count, std::vector& sources, const std::vector& selected_indicies); @@ -850,6 +855,8 @@ private: void remove_transfer_from_amount_gindex_map(uint64_t tid); uint64_t get_alias_cost(const std::string& alias); detail::split_strategy_id_t get_current_split_strategy(); + void build_distribution_for_input(decoy_selection_generator& zarcanum_decoy_set_generator, std::vector& offsets, uint64_t own_index); + void select_decoys(currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount & amount_entry, uint64_t own_g_index); static void wti_to_csv_entry(std::ostream& ss, const wallet_public::wallet_transfer_info& wti, size_t index); static void wti_to_txt_line(std::ostream& ss, const wallet_public::wallet_transfer_info& wti, size_t index); @@ -904,6 +911,8 @@ private: std::string m_votes_config_path; tools::wallet_public::wallet_vote_config m_votes_config; + uint64_t m_last_known_daemon_height = 0; + //this needed to access wallets state in coretests, for creating abnormal blocks and tranmsactions friend class test_generator; }; // class wallet2 diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 005a314f..323dbbd8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -33,7 +33,7 @@ target_link_libraries(functional_tests rpc wallet currency_core crypto common zl target_link_libraries(hash-tests crypto ethash) target_link_libraries(hash-target-tests crypto currency_core ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) target_link_libraries(performance_tests rpc wallet currency_core common crypto zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto) -target_link_libraries(unit_tests wallet currency_core common crypto gtest_main zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) +target_link_libraries(unit_tests wallet currency_core common crypto gtest_main zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto) target_link_libraries(net_load_tests_clt currency_core common crypto gtest_main ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) target_link_libraries(net_load_tests_srv currency_core common crypto gtest_main ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index f03bf1a2..f7aa0612 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -553,12 +553,16 @@ bool test_generator::build_wallets(const blockchain_vector& blockchain, //skip genesis currency::block_direct_data_entry bdde = AUTO_VAL_INIT(bdde); std::shared_ptr bptr(new block_extended_info()); - bptr->bl = b->b; + bptr->bl = b->b; bdde.block_ptr = bptr; + std::shared_ptr coinbase_tx_ptr(new transaction_chain_entry()); + coinbase_tx_ptr->m_global_output_indexes = get_tx_gindex_from_map(currency::get_transaction_hash(b->b.miner_tx), txs_outs); + bdde.coinbase_ptr = coinbase_tx_ptr; for (auto& tx : b->m_transactions) { std::shared_ptr tx_ptr(new transaction_chain_entry()); tx_ptr->tx = tx; + tx_ptr->m_global_output_indexes = get_tx_gindex_from_map(currency::get_transaction_hash(tx), txs_outs); bdde.txs_ptr.push_back(tx_ptr); } diff --git a/tests/core_tests/chaingen.h b/tests/core_tests/chaingen.h index 690bdef5..65a89226 100644 --- a/tests/core_tests/chaingen.h +++ b/tests/core_tests/chaingen.h @@ -752,6 +752,17 @@ bool shuffle_source_entries(std::vector& sources); // one output will be created for each destination entry and one additional output to add up to old coinbase total amount bool replace_coinbase_in_genesis_block(const std::vector& destinations, test_generator& generator, std::vector& events, currency::block& genesis_block); +template +const std::vector& get_tx_gindex_from_map(const crypto::hash& tx_id, const t_map& id_to_vector) +{ + auto it_global_indexes = id_to_vector.find(tx_id); + if (it_global_indexes == id_to_vector.end()) + { + throw std::runtime_error("TX ID NOT FOUND"); + } + return it_global_indexes->second; +} + //-------------------------------------------------------------------------- template auto do_check_tx_verification_context(const currency::tx_verification_context& tvc, bool tx_added, size_t event_index, const currency::transaction& tx, t_test_class& validator, int) @@ -994,6 +1005,7 @@ namespace crypto { } } + inline uint64_t get_sources_total_amount(const std::vector& s) { uint64_t result = 0; diff --git a/tests/core_tests/wallet_test_core_proxy.cpp b/tests/core_tests/wallet_test_core_proxy.cpp index 0ceae0ab..db0fd0fc 100644 --- a/tests/core_tests/wallet_test_core_proxy.cpp +++ b/tests/core_tests/wallet_test_core_proxy.cpp @@ -99,14 +99,25 @@ bool wallet_test_core_proxy::call_COMMAND_RPC_GET_BLOCKS_FAST(const currency::CO { auto b = m_blocks[i]; currency::block_complete_entry bce = AUTO_VAL_INIT(bce); - for (auto tx : b->m_transactions) + bce.tx_global_outs.resize(b->m_transactions.size()); + bce.coinbase_global_outs = get_tx_gindex(currency::get_transaction_hash(b->b.miner_tx)); + for (size_t j = 0; j != b->m_transactions.size(); j++) + { + const auto& tx = b->m_transactions[j]; bce.txs.push_back(tx_to_blob(tx)); + bce.tx_global_outs[j].v = get_tx_gindex(currency::get_transaction_hash(tx)); + } bce.block = block_to_blob(b->b); rsp.blocks.push_back(bce); } rsp.current_height = m_blocks.size(); return true; } + +const std::vector& wallet_test_core_proxy::get_tx_gindex(const crypto::hash& tx_id) +{ + return get_tx_gindex_from_map(tx_id, m_txs_outs); +} bool wallet_test_core_proxy::call_COMMAND_RPC_GET_BLOCKS_DIRECT(const currency::COMMAND_RPC_GET_BLOCKS_DIRECT::request& rqt, currency::COMMAND_RPC_GET_BLOCKS_DIRECT::response& rsp) { currency::COMMAND_RPC_GET_BLOCKS_FAST::request req = AUTO_VAL_INIT(req); diff --git a/tests/core_tests/wallet_test_core_proxy.h b/tests/core_tests/wallet_test_core_proxy.h index 322a7bb3..052a4f70 100644 --- a/tests/core_tests/wallet_test_core_proxy.h +++ b/tests/core_tests/wallet_test_core_proxy.h @@ -26,6 +26,9 @@ struct wallet_test_core_proxy : public tools::i_core_proxy virtual bool call_COMMAND_RPC_GET_CURRENT_CORE_TX_EXPIRATION_MEDIAN(const currency::COMMAND_RPC_GET_CURRENT_CORE_TX_EXPIRATION_MEDIAN::request& req, currency::COMMAND_RPC_GET_CURRENT_CORE_TX_EXPIRATION_MEDIAN::response& res) override; virtual bool get_transfer_address(const std::string& adr_str, currency::account_public_address& addr, std::string& payment_id) override; + const std::vector& get_tx_gindex(const crypto::hash& tx_id); + + test_generator::tx_global_indexes m_txs_outs; test_generator::blockchain_vector m_blocks; test_generator::outputs_index m_oi; diff --git a/tests/unit_tests/decoy_selection.cpp b/tests/unit_tests/decoy_selection.cpp index 47ff298d..19c2d178 100644 --- a/tests/unit_tests/decoy_selection.cpp +++ b/tests/unit_tests/decoy_selection.cpp @@ -10,32 +10,39 @@ TEST(decoy_selection_test, decoy_selection_test) { const uint64_t test_scale_size = 20000; decoy_selection_generator dsg; - dsg.init(test_scale_size - 1); + dsg.init(100); std::map hits; + + + + //std::vector decoys = dsg.generate_distribution(15); + + std::cout << ""; + //std::vector hits(test_scale_size, 0); -// while (true) -// { -// std::vector decoys = dsg.generate_distribution(15); -// for (auto d : decoys) -// { -// hits[d]++; -// } -// -// if (hits[10] > 500) -// break; -// -// } -// std::stringstream ss; -// for (auto it = hits.begin(); it != hits.end(); it++) -// { -// //if (hits[i] != 0) -// { -// ss << it->first << ", " << it->second << ENDL; -// } -// } -// epee::file_io_utils::save_string_to_file("distribution.csv", ss.str()); + while (true) + { + std::vector decoys = dsg.generate_distribution(15); + for (auto d : decoys) + { + hits[d]++; + } + + if (hits[10] > 500) + break; + + } + std::stringstream ss; + for (auto it = hits.begin(); it != hits.end(); it++) + { + if (it->second != 0) + { + ss << it->first << ", " << it->second << std::endl; + } + } + epee::file_io_utils::save_string_to_file("distribution.csv", ss.str()); From cceeda0588a05a17dcc4213dca08afbbb39aa104 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Tue, 26 Mar 2024 14:05:22 +0300 Subject: [PATCH 048/184] === build number: 285 -> 286 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index ff34f72e..a85f5f41 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 285 +#define PROJECT_VERSION_BUILD_NO 286 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From 6311c2078fe9a76ae4945c663b269dfa50b4f52b Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Tue, 26 Mar 2024 16:35:00 +0100 Subject: [PATCH 049/184] fixed RANDOM_OUTPUTS_FOR_AMOUNTS_FLAGS_COINBASE and added RANDOM_OUTPUTS_FOR_AMOUNTS_FLAGS_POS_COINBASE for future use --- src/currency_core/blockchain_storage.cpp | 11 ++++++++--- src/rpc/core_rpc_server_commands_defs.h | 1 + 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index b818c746..c5f26e11 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -2606,6 +2606,14 @@ bool blockchain_storage::add_out_to_get_random_outs(COMMAND_RPC_GET_RANDOM_OUTPU oen.amount_commitment = toz.amount_commitment; oen.concealing_point = toz.concealing_point; oen.blinded_asset_id = toz.blinded_asset_id; // TODO @#@# bad design, too much manual coping, consider redesign -- sowle + if (is_coinbase(tx_ptr->tx)) + { + oen.flags |= RANDOM_OUTPUTS_FOR_AMOUNTS_FLAGS_COINBASE; + if (is_pos_coinbase(tx_ptr->tx)) + { + oen.flags |= RANDOM_OUTPUTS_FOR_AMOUNTS_FLAGS_POS_COINBASE; + } + } } VARIANT_SWITCH_END(); @@ -2787,9 +2795,6 @@ bool blockchain_storage::get_random_outs_for_amounts3(const COMMAND_RPC_GET_RAND CRITICAL_REGION_LOCAL(m_read_lock); LOG_PRINT_L3("[get_random_outs_for_amounts] amounts: " << req.amounts.size()); std::map amounts_to_up_index_limit_cache; - uint64_t count_zarcanum_blocks = 0; - if(is_hardfork_active(ZANO_HARDFORK_04_ZARCANUM)) - count_zarcanum_blocks = this->get_current_blockchain_size() - m_core_runtime_config.hard_forks.m_height_the_hardfork_n_active_after[ZANO_HARDFORK_04_ZARCANUM]; for (size_t i = 0; i != req.amounts.size(); i++) diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 03284a6e..df0b699e 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -383,6 +383,7 @@ namespace currency #define RANDOM_OUTPUTS_FOR_AMOUNTS_FLAGS_COINBASE 0x0000000000000001LL #define RANDOM_OUTPUTS_FOR_AMOUNTS_FLAGS_NOT_ALLOWED 0x0000000000000002LL +#define RANDOM_OUTPUTS_FOR_AMOUNTS_FLAGS_POS_COINBASE 0x0000000000000004LL #pragma pack (push, 1) struct out_entry From 7f134072f60b947b70ed5813613abee259c6e772 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Tue, 26 Mar 2024 19:22:45 +0100 Subject: [PATCH 050/184] minor changes in error messages(to avoid misleading) --- src/wallet/wallet2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index f212d2bb..7b5d1f30 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -6073,7 +6073,7 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count_, std::vectorcall_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3(req, daemon_resp); - THROW_IF_FALSE_WALLET_EX(r, error::no_connection_to_daemon, "getrandom_outs2.bin"); + THROW_IF_FALSE_WALLET_EX(r, error::no_connection_to_daemon, "getrandom_outs3.bin"); if (daemon_resp.status == API_RETURN_CODE_FAIL) { if (attempt_count < 10) From 0015c8934df855aa0ca61e0753dc0ba5a10348bb Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 26 Mar 2024 19:51:02 +0100 Subject: [PATCH 051/184] KV_SERIALIZE_BLOB_AS_BASE64_STRING() implemented --- .../epee/include/serialization/keyvalue_helpers.h | 12 ++++++++++++ .../include/serialization/keyvalue_serialization.h | 5 ++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/contrib/epee/include/serialization/keyvalue_helpers.h b/contrib/epee/include/serialization/keyvalue_helpers.h index 79a4886b..09555a9e 100644 --- a/contrib/epee/include/serialization/keyvalue_helpers.h +++ b/contrib/epee/include/serialization/keyvalue_helpers.h @@ -85,6 +85,18 @@ namespace epee } return res; } + + // helper for blob-to-base64 serialization + inline std::string transfrom_binbuf_to_base64(const std::string& a) + { + return epee::string_encoding::base64_encode(a); + } + + inline std::string transform_base64_to_binbuf(const std::string& a) + { + return epee::string_encoding::base64_decode(a); + } + //------------------------------------------------------------------------------------------------------------------- #pragma pack(push, 1) template diff --git a/contrib/epee/include/serialization/keyvalue_serialization.h b/contrib/epee/include/serialization/keyvalue_serialization.h index 31c90df7..50f917b4 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization.h +++ b/contrib/epee/include/serialization/keyvalue_serialization.h @@ -81,6 +81,8 @@ public: \ #define KV_SERIALIZE_BLOB_AS_HEX_STRING_N(varialble, val_name) \ KV_SERIALIZE_CUSTOM_N(varialble, std::string, epee::transform_binbuf_to_hexstr, epee::transform_hexstr_to_binbuff, val_name) +#define KV_SERIALIZE_BLOB_AS_BASE64_STRING_N(varialble, val_name) \ + KV_SERIALIZE_CUSTOM_N(varialble, std::string, epee::transfrom_binbuf_to_base64, epee::transform_base64_to_binbuf, val_name) #define KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(varialble, val_name) \ epee::serialization::selector::serialize_t_val_as_blob(this_ref.varialble, stg, hparent_section, val_name); @@ -100,7 +102,8 @@ public: \ #define KV_SERIALIZE_CONTAINER_POD_AS_BLOB(varialble) KV_SERIALIZE_CONTAINER_POD_AS_BLOB_N(varialble, #varialble) #define KV_SERIALIZE_CUSTOM(varialble, stored_type, from_v_to_stored, from_stored_to_v) KV_SERIALIZE_CUSTOM_N(varialble, stored_type, from_v_to_stored, from_stored_to_v, #varialble) #define KV_SERIALIZE_POD_AS_HEX_STRING(varialble) KV_SERIALIZE_POD_AS_HEX_STRING_N(varialble, #varialble) -#define KV_SERIALIZE_BLOB_AS_HEX_STRING(varialble) KV_SERIALIZE_BLOB_AS_HEX_STRING_N(varialble, #varialble) +#define KV_SERIALIZE_BLOB_AS_HEX_STRING(varialble) KV_SERIALIZE_BLOB_AS_HEX_STRING_N(varialble, #varialble) +#define KV_SERIALIZE_BLOB_AS_BASE64_STRING(variable) KV_SERIALIZE_BLOB_AS_BASE64_STRING_N(variable, #variable) From 6740a0df284d23e6b35cfcf05260bd8d1ca0d533 Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 26 Mar 2024 19:52:30 +0100 Subject: [PATCH 052/184] tx pool: short tx listing improved --- src/currency_core/tx_pool.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/currency_core/tx_pool.cpp b/src/currency_core/tx_pool.cpp index 3acf108c..211599ab 100644 --- a/src/currency_core/tx_pool.cpp +++ b/src/currency_core/tx_pool.cpp @@ -966,8 +966,8 @@ namespace currency return "(no transactions, the pool is empty)"; // sort output by receive time txs.sort([](const std::pair& lhs, const std::pair& rhs) -> bool { return lhs.second.receive_time < rhs.second.receive_time; }); - ss << "# | transaction id | size | fee | ins | outs | outs money | live_time | max used block | last failed block | kept by a block?" << ENDL; - // 1234 f99fe6d4335fc0ddd69e6880a4d95e0f6ea398de0324a6837021a61c6a31cacd 87157 0.10000111 2000 2000 112000.12345678 d0.h10.m16.s17 123456 <12345..> 123456 <12345..> YES + ss << "# | transaction id | size | fee | ins | outs | live_time | max used block | last failed block | ver | kept by a block?" << ENDL; + // 1234 f99fe6d4335fc0ddd69e6880a4d95e0f6ea398de0324a6837021a61c6a31cacd 187157 0.10000111 2000 2000 d0.h10.m16.s17 1234567 <12345..> 1234567 <12345..> 2 YES size_t i = 0; for (auto& tx : txs) { @@ -975,16 +975,16 @@ namespace currency ss << std::left << std::setw(4) << i++ << " " << tx.first << " " - << std::setw(5) << txd.blob_size << " " + << std::setw(6) << txd.blob_size << " " << std::setw(10) << print_money_brief(txd.fee) << " " << std::setw(4) << txd.tx.vin.size() << " " << std::setw(4) << txd.tx.vout.size() << " " - << std::right << std::setw(15) << print_money(get_outs_money_amount(txd.tx)) << std::left << " " << std::setw(14) << epee::misc_utils::get_time_interval_string(get_core_time() - txd.receive_time) << " " - << std::setw(6) << txd.max_used_block_height << " " + << std::setw(7) << txd.max_used_block_height << " " << std::setw(9) << print16(txd.max_used_block_id) << " " - << std::setw(6) << txd.last_failed_height << " " + << std::setw(7) << txd.last_failed_height << " " << std::setw(9) << print16(txd.last_failed_id) << " " + << std::setw(3) << txd.tx.version << " " << (txd.kept_by_block ? "YES" : "no ") << ENDL; } From c2fa96883525e627e3ab0a2034bd708a9bf696dd Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 26 Mar 2024 19:55:34 +0100 Subject: [PATCH 053/184] daemon: 1) print_asset_info command added; 2) print_tx greatly improved; 3) fill_tx_rpc_details() now fills blob and object_in_json fields and use base64 encoding --- src/currency_core/blockchain_storage.cpp | 15 ++- src/currency_core/blockchain_storage.h | 1 + src/daemon/daemon_commands_handler.h | 150 +++++++++++++++++------ src/rpc/core_rpc_server_commands_defs.h | 4 +- 4 files changed, 127 insertions(+), 43 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index c5f26e11..6e781c68 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -3780,6 +3780,17 @@ uint64_t blockchain_storage::get_aliases_count() const return m_db_aliases.size(); } //------------------------------------------------------------------ +bool blockchain_storage::get_asset_history(const crypto::public_key& asset_id, std::list& result) const +{ + CRITICAL_REGION_LOCAL(m_read_lock); + auto as_ptr = m_db_assets.find(asset_id); + if (!as_ptr) + return false; + + result = *as_ptr; + return true; +} +//------------------------------------------------------------------ bool blockchain_storage::get_asset_info(const crypto::public_key& asset_id, asset_descriptor_base& result) const { CRITICAL_REGION_LOCAL(m_read_lock); @@ -5443,7 +5454,6 @@ std::shared_ptr blockchain_storage::find_key_imag //--------------------------------------------------------------- bool blockchain_storage::fill_tx_rpc_details(tx_rpc_extended_info& tei, const transaction& tx, const transaction_chain_entry* ptce, const crypto::hash& h, uint64_t timestamp, bool is_short) const { - //tei.blob = tx_ptr->tx tei.id = epee::string_tools::pod_to_hex(h); if (!tei.blob_size) tei.blob_size = get_object_blobsize(tx); @@ -5460,6 +5470,9 @@ bool blockchain_storage::fill_tx_rpc_details(tx_rpc_extended_info& tei, const tr fill_tx_rpc_outputs(tei, tx, ptce); fill_tx_rpc_payload_items(tei.extra, tx.extra); fill_tx_rpc_payload_items(tei.attachments, tx.attachment); + + tei.blob = t_serializable_object_to_blob(tx); + tei.object_in_json = obj_to_json_str(tx); return true; } //------------------------------------------------------------------ diff --git a/src/currency_core/blockchain_storage.h b/src/currency_core/blockchain_storage.h index c59bdcd0..eb9c017a 100644 --- a/src/currency_core/blockchain_storage.h +++ b/src/currency_core/blockchain_storage.h @@ -299,6 +299,7 @@ namespace currency uint64_t get_aliases_count()const; uint64_t get_block_h_older_then(uint64_t timestamp) const; bool validate_tx_service_attachmens_in_services(const tx_service_attachment& a, size_t i, const transaction& tx)const; + bool get_asset_history(const crypto::public_key& asset_id, std::list& result) const; bool get_asset_info(const crypto::public_key& asset_id, asset_descriptor_base& info)const; uint64_t get_assets_count() const; bool check_tx_input(const transaction& tx, size_t in_index, const txin_to_key& txin, const crypto::hash& tx_prefix_hash, uint64_t& max_related_block_height, uint64_t& source_max_unlock_time_for_pos_coinbase)const; diff --git a/src/daemon/daemon_commands_handler.h b/src/daemon/daemon_commands_handler.h index 7e395584..8f2aa24a 100644 --- a/src/daemon/daemon_commands_handler.h +++ b/src/daemon/daemon_commands_handler.h @@ -47,6 +47,7 @@ public: m_cmd_binder.set_handler("print_block_info", boost::bind(&daemon_commands_handler::print_block_info, this, ph::_1), "Print block info, print_block | "); m_cmd_binder.set_handler("print_tx_prun_info", boost::bind(&daemon_commands_handler::print_tx_prun_info, this, ph::_1), "Print tx prunning info"); m_cmd_binder.set_handler("print_tx", boost::bind(&daemon_commands_handler::print_tx, this, ph::_1), "Print transaction, print_tx "); + m_cmd_binder.set_handler("print_asset_info", boost::bind(&daemon_commands_handler::print_asset_info, this, ph::_1), "Print information about the given asset by its id"); m_cmd_binder.set_handler("start_mining", boost::bind(&daemon_commands_handler::start_mining, this, ph::_1), "Start mining for specified address, start_mining [threads=1]"); m_cmd_binder.set_handler("stop_mining", boost::bind(&daemon_commands_handler::stop_mining, this, ph::_1), "Stop mining"); m_cmd_binder.set_handler("print_pool", boost::bind(&daemon_commands_handler::print_pool, this, ph::_1), "Print transaction pool (long format)"); @@ -688,7 +689,7 @@ private: { if (args.empty()) { - std::cout << "expected: print_tx " << std::endl; + std::cout << "usage: print_tx " << std::endl; return true; } @@ -696,55 +697,74 @@ private: crypto::hash tx_hash; if (!parse_hash256(str_hash, tx_hash)) { + LOG_PRINT_RED_L0("invalid tx hash was given"); return true; } - // std::vector tx_ids; - // tx_ids.push_back(tx_hash); - // std::list txs; - // std::list missed_ids; - // m_srv.get_payload_object().get_core().get_transactions(tx_ids, txs, missed_ids); - - currency::transaction_chain_entry tx_entry = AUTO_VAL_INIT(tx_entry); - - if (!m_srv.get_payload_object().get_core().get_blockchain_storage().get_tx_chain_entry(tx_hash, tx_entry)) + currency::tx_rpc_extended_info tx_rpc_ei{}; + currency::core& core = m_srv.get_payload_object().get_core(); + if (core.get_blockchain_storage().get_tx_rpc_details(tx_hash, tx_rpc_ei, 0, false)) { - LOG_PRINT_RED("transaction wasn't found: " << tx_hash, LOG_LEVEL_0); + // pass } - currency::block_extended_info bei = AUTO_VAL_INIT(bei); - m_srv.get_payload_object().get_core().get_blockchain_storage().get_block_extended_info_by_height(tx_entry.m_keeper_block_height, bei); - uint64_t timestamp = bei.bl.timestamp; - - const currency::transaction& tx = tx_entry.tx; - std::stringstream ss; - - ss << "------------------------------------------------------" - << ENDL << "tx_id: " << tx_hash - << ENDL << "keeper_block: " << tx_entry.m_keeper_block_height << ", timestamp (" << timestamp << ") " << epee::misc_utils::get_internet_time_str(timestamp) - << ENDL << currency::obj_to_json_str(tx) - << ENDL << "------------------------------------------------------" - << ENDL << epee::string_tools::buff_to_hex_nodelimer(t_serializable_object_to_blob(tx)) - << ENDL << "------------------------------------------------------"; - - - ss << "ATTACHMENTS: " << ENDL; - for (auto at : tx.attachment) + else if (core.get_tx_pool().get_transaction_details(tx_hash, tx_rpc_ei)) { - if (at.type() == typeid(currency::tx_service_attachment)) - { - const currency::tx_service_attachment& sa = boost::get(at); - ss << "++++++++++++++++++++++++++++++++ " << ENDL; - ss << "[SERVICE_ATTACHMENT]: ID = \'" << sa.service_id << "\', INSTRUCTION: \'" << sa.instruction << "\'" << ENDL; + // pass + } + else + { + LOG_PRINT_RED("transaction " << tx_hash << " was not found in either the blockchain or the pool", LOG_LEVEL_0); + return true; + } - if (!(sa.flags&TX_SERVICE_ATTACHMENT_ENCRYPT_BODY)) + std::stringstream ss; + ss << ENDL << + "----------------------TX-HEX--------------------------" << ENDL << + epee::string_tools::buff_to_hex_nodelimer(tx_rpc_ei.blob) << ENDL << + "------------------END-OF-TX-HEX-----------------------" << ENDL; + + ss << ENDL << + "tx " << tx_hash << " "; + + if (tx_rpc_ei.keeper_block == -1) + { + ss << "has been in the transaction pool for " << epee::misc_utils::get_time_interval_string(core.get_blockchain_storage().get_core_runtime_config().get_core_time() - tx_rpc_ei.timestamp) << + ", added " << epee::misc_utils::get_internet_time_str(tx_rpc_ei.timestamp) << ", ts: " << tx_rpc_ei.timestamp << ", blob size: " << tx_rpc_ei.blob_size << ENDL; + } + else + { + ss << "was added to block @ " << tx_rpc_ei.keeper_block << ", block time: " << epee::misc_utils::get_internet_time_str(tx_rpc_ei.timestamp) << ", ts: " << tx_rpc_ei.timestamp << ", blob size: " << tx_rpc_ei.blob_size << ENDL; + } + + ss << ENDL << + "-----------------------JSON---------------------------" << ENDL << + tx_rpc_ei.object_in_json << ENDL << + "--------------------END-OF-JSON-----------------------" << ENDL; + + currency::transaction tx{}; + CHECK_AND_ASSERT_MES(currency::parse_and_validate_tx_from_blob(tx_rpc_ei.blob, tx), true, "parse_and_validate_tx_from_blob failed"); + + if (!tx.attachment.empty()) + { + ss << "ATTACHMENTS: " << ENDL; + for (auto at : tx.attachment) + { + if (at.type() == typeid(currency::tx_service_attachment)) { - std::string body = sa.body; - if (sa.flags&TX_SERVICE_ATTACHMENT_DEFLATE_BODY) + const currency::tx_service_attachment& sa = boost::get(at); + ss << "++++++++++++++++++++++++++++++++ " << ENDL; + ss << "[SERVICE_ATTACHMENT]: ID = \'" << sa.service_id << "\', INSTRUCTION: \'" << sa.instruction << "\'" << ENDL; + + if (!(sa.flags&TX_SERVICE_ATTACHMENT_ENCRYPT_BODY)) { - bool r = epee::zlib_helper::unpack(sa.body, body); - CHECK_AND_ASSERT_MES(r, false, "Failed to unpack"); + std::string body = sa.body; + if (sa.flags&TX_SERVICE_ATTACHMENT_DEFLATE_BODY) + { + bool r = epee::zlib_helper::unpack(sa.body, body); + CHECK_AND_ASSERT_MES(r, false, "Failed to unpack"); + } + ss << "BODY: " << body << ENDL; } - ss << "BODY: " << body << ENDL; } } } @@ -753,6 +773,56 @@ private: return true; } //-------------------------------------------------------------------------------- + bool print_asset_info(const std::vector& args) + { + if (args.empty()) + { + std::cout << "usage: print_asset_info " << std::endl; + return true; + } + + const std::string& str_asset_id = args.front(); + crypto::public_key asset_id{}; + crypto::point_t asset_id_pt{}; + if (!crypto::parse_tpod_from_hex_string(str_asset_id, asset_id) || !asset_id_pt.from_public_key(asset_id)) + { + LOG_PRINT_RED_L0("invalid asset id was given"); + return true; + } + + currency::core& core = m_srv.get_payload_object().get_core(); + + std::list asset_history; + if (!core.get_blockchain_storage().get_asset_history(asset_id, asset_history)) + { + LOG_PRINT_RED_L0("asset id doesn't present in the blockchain"); + return true; + } + + std::stringstream ss; + ss << ENDL << + "history for asset " << asset_id << ":" << ENDL; + + size_t idx = 0; + for(auto& aop: asset_history) + { + ss << "[" << std::setw(2) << idx << "] operation: " << currency::get_asset_operation_type_string(aop.operation_type) << " (" << (int)aop.operation_type << ")" << ENDL << + " ticker: \"" << aop.descriptor.ticker << "\"" << ENDL << + " full name: \"" << aop.descriptor.full_name << "\"" << ENDL << + " meta info: \"" << aop.descriptor.meta_info << "\"" << ENDL << + " current supply: " << currency::print_money_brief(aop.descriptor.current_supply, aop.descriptor.decimal_point) << ENDL << + " max supply: " << currency::print_money_brief(aop.descriptor.total_max_supply, aop.descriptor.decimal_point) << ENDL << + " decimal point: " << (int)aop.descriptor.decimal_point << ENDL << + " owner * 1/8: " << aop.descriptor.owner << ENDL << + " amount cmt * 1/8: " << aop.amount_commitment << ENDL << + " hidden supply: " << (aop.descriptor.hidden_supply ? "yes" : "no") << ENDL << + ""; + } + + LOG_PRINT_L0(ss.str()); + return true; + } + //-------------------------------------------------------------------------------- bool print_tx_outputs_usage(const std::vector& args) { if (args.empty()) diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index df0b699e..ce931d9d 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -1344,7 +1344,7 @@ namespace currency std::string object_in_json; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(blob) + KV_SERIALIZE_BLOB_AS_BASE64_STRING(blob) KV_SERIALIZE(blob_size) KV_SERIALIZE(timestamp) KV_SERIALIZE(keeper_block) @@ -1356,7 +1356,7 @@ namespace currency KV_SERIALIZE(ins) KV_SERIALIZE(extra) KV_SERIALIZE(attachments) - KV_SERIALIZE(object_in_json) + KV_SERIALIZE_BLOB_AS_BASE64_STRING(object_in_json) END_KV_SERIALIZE_MAP() }; From e1d7ea63029d106485375cab9e05175d911a414b Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 26 Mar 2024 19:57:31 +0100 Subject: [PATCH 054/184] asset emission: 1) fixed simplewallet's emit_asset command; 2) wallet2:emit_asset() now fix destinations for asset emission ad-hoc (null_pkey); 3) typos corrected --- src/simplewallet/simplewallet.cpp | 4 ++-- src/wallet/wallet2.cpp | 8 +++++++- src/wallet/wallet2.h | 2 +- tests/core_tests/multiassets_test.cpp | 14 +++++++------- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 1a1f1e8e..ed51ef76 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -2113,11 +2113,11 @@ bool simple_wallet::emit_asset(const std::vector &args) tx_destination_entry td = AUTO_VAL_INIT(td); td.addr.push_back(m_wallet->get_account().get_public_address()); td.amount = amount; - td.asset_id = asset_id; + td.asset_id = currency::null_pkey; std::vector destinations; destinations.push_back(td); currency::transaction result_tx = AUTO_VAL_INIT(result_tx); - m_wallet->emmit_asset(asset_id, destinations, result_tx); + m_wallet->emit_asset(asset_id, destinations, result_tx); success_msg_writer(true) << "Emitted " << get_transaction_hash(result_tx) << " (unconfirmed) : " << ENDL << "Asset ID: " << asset_id << ENDL diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 7b5d1f30..cc533644 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -4954,7 +4954,7 @@ void wallet2::deploy_new_asset(const currency::asset_descriptor_base& asset_info m_custom_assets[new_asset_id] = ado.descriptor; } //---------------------------------------------------------------------------------------------------- -void wallet2::emmit_asset(const crypto::public_key asset_id, std::vector& destinations, currency::transaction& result_tx) +void wallet2::emit_asset(const crypto::public_key asset_id, std::vector& destinations, currency::transaction& result_tx) { auto own_asset_entry_it = m_own_asset_descriptors.find(asset_id); @@ -4976,6 +4976,12 @@ void wallet2::emmit_asset(const crypto::public_key asset_id, std::vectorsecond.control_key; + for(auto& dst : ctp.dsts) + { + if (dst.asset_id == asset_id) + dst.asset_id = null_pkey; // emit operation requires null_pkey for emitting asset outputs, fix it ad-hoc here + } + finalized_tx ft = AUTO_VAL_INIT(ft); this->transfer(ctp, ft, true, nullptr); result_tx = ft.tx; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 5ea7a30b..413adb97 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -394,7 +394,7 @@ namespace tools bool check_available_sources(std::list& amounts); void deploy_new_asset(const currency::asset_descriptor_base& asset_info, const std::vector& destinations, currency::transaction& result_tx, crypto::public_key& new_asset_id); - void emmit_asset(const crypto::public_key asset_id, std::vector& destinations, currency::transaction& result_tx); + void emit_asset(const crypto::public_key asset_id, std::vector& destinations, currency::transaction& result_tx); void update_asset(const crypto::public_key asset_id, const currency::asset_descriptor_base new_descriptor, currency::transaction& result_tx); void burn_asset(const crypto::public_key asset_id, uint64_t amount_to_burn, currency::transaction& result_tx); void transfer_asset_ownership(const crypto::public_key asset_id, const crypto::public_key& new_owner, currency::transaction& result_tx); diff --git a/tests/core_tests/multiassets_test.cpp b/tests/core_tests/multiassets_test.cpp index 28dda0e5..1a933292 100644 --- a/tests/core_tests/multiassets_test.cpp +++ b/tests/core_tests/multiassets_test.cpp @@ -142,9 +142,9 @@ bool multiassets_basic_test::c1(currency::core& c, size_t ev_index, const std::v CHECK_AND_ASSERT_MES(asset_info2.meta_info == asset_info.meta_info, false, "Failed to find needed asset in result balances"); - //test emmit function + //test emit function //use same destinations as we used before - miner_wlt->emmit_asset(asset_id, destinations, tx); + miner_wlt->emit_asset(asset_id, destinations, tx); r = mine_next_pow_blocks_in_playtime(miner_wlt->get_account().get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed"); @@ -252,13 +252,13 @@ bool multiassets_basic_test::c1(currency::core& c, size_t ev_index, const std::v //miner_wlt->refresh(); - // check emmit_asset() with modified 'current_supply' + // check emit_asset() with modified 'current_supply' miner_wlt->get_debug_events_dispatcher().SUBSCIRBE_DEBUG_EVENT([&](const wde_construct_tx_handle_asset_descriptor_operation_before_seal& o) { o.pado->descriptor.current_supply += 1000000; }); - //test emmit function but re-adjust current_supply to wrong amount - miner_wlt->emmit_asset(asset_id, destinations, tx); + //test emit function but re-adjust current_supply to wrong amount + miner_wlt->emit_asset(asset_id, destinations, tx); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count()); r = mine_next_pow_block_in_playtime(miner_wlt->get_account().get_public_address(), c); CHECK_AND_ASSERT_MES(!r, false, "block with a bad tx was unexpectedly mined"); @@ -305,7 +305,7 @@ bool multiassets_basic_test::c1(currency::core& c, size_t ev_index, const std::v uint64_t balance_alice_asset = alice_wlt->balance(asset_id); uint64_t balance_miner_asset = miner_wlt->balance(asset_id); - alice_wlt->emmit_asset(asset_id, destinations, tx); + alice_wlt->emit_asset(asset_id, destinations, tx); r = mine_next_pow_blocks_in_playtime(miner_wlt->get_account().get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed"); @@ -315,7 +315,7 @@ bool multiassets_basic_test::c1(currency::core& c, size_t ev_index, const std::v CHECK_AND_ASSERT_MES(miner_wlt->balance(asset_id) == balance_miner_asset + destinations[0].amount, false, "Miner balance wrong"); CHECK_AND_ASSERT_MES(alice_wlt->balance(asset_id) == balance_alice_asset + destinations[1].amount, false, "Alice balance wrong"); - //TODO: attempt to emmmit from old key, attempt to emmit from more then max supply + //TODO: attempt to emmmit from old key, attempt to emit from more then max supply return true; } From 7d3e3ae3584857916e1763c1ef561eefbd6875ad Mon Sep 17 00:00:00 2001 From: zano build machine Date: Tue, 26 Mar 2024 21:58:01 +0300 Subject: [PATCH 055/184] === build number: 286 -> 287 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index a85f5f41..931b5c93 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 286 +#define PROJECT_VERSION_BUILD_NO 287 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From e5afb6b0c65a7011ec9b5fb29422f6cd830284d0 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 27 Mar 2024 15:52:30 +0100 Subject: [PATCH 056/184] in the middle of refactoring autodoc --- .../serialization/keyvalue_serialization.h | 10 +++++++++- .../keyvalue_serialization_overloads.h | 9 ++++++++- contrib/epee/include/storages/portable_storage.h | 1 + .../storages/portable_storage_extended_for_doc.h | 2 ++ .../include/storages/portable_storage_to_json.h | 16 ++++++++++++---- 5 files changed, 32 insertions(+), 6 deletions(-) diff --git a/contrib/epee/include/serialization/keyvalue_serialization.h b/contrib/epee/include/serialization/keyvalue_serialization.h index ae8779f8..856ee830 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization.h +++ b/contrib/epee/include/serialization/keyvalue_serialization.h @@ -72,7 +72,15 @@ public: \ epee::serialization::selector::serialize(this_ref.varialble, stg, hparent_section, val_name, auto_doc_mode, substitute, description); #define KV_SERIALIZE_N_DOC2(varialble, val_name) \ - {using var_type = decltype(this_ref.varialble); epee::serialization::selector::serialize(this_ref.varialble, stg, hparent_section, val_name, auto_doc_mode, + {using var_type = decltype(this_ref.varialble); \ + epee::serialization::selector::serialize(this_ref.varialble, stg, hparent_section, val_name); \ + if constexpr (t_storage::use_descriptions::value) \ + { \ + epee::serialization::selector::set_descr(this_ref.varialble, stg, hparent_section, val_name); \ + } \ + } + + //substitute, description); diff --git a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h index e0b6f6d8..7ca5dd98 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h +++ b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h @@ -315,11 +315,18 @@ namespace epee struct selector { template - static bool serialize(const t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname, bool doc_mode = false, const t_type& doc_substitute = t_type(), const std::string& description = std::string()) + static bool serialize(const t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname) { stg.set_entry_description(hparent_section, pname, description); return kv_serialize( (doc_mode ? doc_substitute:d), stg, hparent_section, pname); } + //bool doc_mode = false, const t_type& doc_substitute = t_type(), const std::string& description = std::string() + template + static bool set_descr(t_storage& stg, typename t_storage::hsection hparent_section, const char* pname, const std::string& description = std::string(), const t_type& doc_substitute = t_type()) + { + stg.set_entry_description(hparent_section, pname, description); + return kv_serialize((doc_mode ? doc_substitute : d), stg, hparent_section, pname); + } template static bool serialize_stl_container_pod_val_as_blob(const t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname) diff --git a/contrib/epee/include/storages/portable_storage.h b/contrib/epee/include/storages/portable_storage.h index 0eed742b..b6e72668 100644 --- a/contrib/epee/include/storages/portable_storage.h +++ b/contrib/epee/include/storages/portable_storage.h @@ -49,6 +49,7 @@ namespace epee { public: //typedef epee::serialization::hsection hsection; + using use_descriptions = std::false_type; typedef t_section* hsection; typedef epee::serialization::harray harray; typedef storage_entry meta_entry; diff --git a/contrib/epee/include/storages/portable_storage_extended_for_doc.h b/contrib/epee/include/storages/portable_storage_extended_for_doc.h index aec4a766..a7b6094f 100644 --- a/contrib/epee/include/storages/portable_storage_extended_for_doc.h +++ b/contrib/epee/include/storages/portable_storage_extended_for_doc.h @@ -42,6 +42,8 @@ namespace epee class portable_storage_extended_doc: public portable_storage { public: + using use_descriptions = std::true_type; + void set_entry_description(hsection hparent_section, const std::string& name, const std::string& description) { if (!hparent_section) diff --git a/contrib/epee/include/storages/portable_storage_to_json.h b/contrib/epee/include/storages/portable_storage_to_json.h index cb434b87..3292c952 100644 --- a/contrib/epee/include/storages/portable_storage_to_json.h +++ b/contrib/epee/include/storages/portable_storage_to_json.h @@ -109,11 +109,15 @@ namespace epee template static void handle_obj_begin(t_stream& strm, size_t indent) - {} + { + strm << "{"; + } template static void handle_obj_end(t_stream& strm, size_t indent) - {} + { + strm << "}"; + } template static void handle_print_key(t_stream& strm, const std::string& key, size_t indent) @@ -125,11 +129,15 @@ namespace epee template static void handle_section_entry_separator(t_stream& strm, size_t indent) - {} + { + strm << ","; + } template static void handle_array_entry_separator(t_stream& strm, size_t indent) - {} + { + strm << ","; + } template static void handle_line_break(t_stream& strm, size_t indent) From 806eb326d1e9f8abde2d0fd138adf12ffcffe7cf Mon Sep 17 00:00:00 2001 From: sowle Date: Sat, 16 Mar 2024 14:57:25 +0100 Subject: [PATCH 057/184] (cherry picked) tx_pool: add post-HF4 txs are now being check for balance proof. Core test hard_fork_4_consolidated_txs changed accordingly --- src/currency_core/tx_pool.cpp | 12 ++++++++- src/currency_core/tx_pool.h | 3 ++- tests/core_tests/hard_fork_4.cpp | 46 +++++++++++++++++++++++--------- 3 files changed, 47 insertions(+), 14 deletions(-) diff --git a/src/currency_core/tx_pool.cpp b/src/currency_core/tx_pool.cpp index 211599ab..b8185cbf 100644 --- a/src/currency_core/tx_pool.cpp +++ b/src/currency_core/tx_pool.cpp @@ -224,6 +224,14 @@ namespace currency } TIME_MEASURE_FINISH_PD(check_inputs_time); + TIME_MEASURE_START_PD(check_post_hf4_balance); + if (tx.version > TRANSACTION_VERSION_PRE_HF4) + { + r = check_tx_balance(tx, id); + CHECK_AND_ASSERT_MES_CUSTOM(r, false, { tvc.m_verification_failed = true; }, "post-HF4 tx: balance proof is invalid"); + } + TIME_MEASURE_FINISH_PD(check_post_hf4_balance); + do_insert_transaction(tx, id, blob_size, kept_by_block, tx_fee, ch_inp_res ? max_used_block_id : null_hash, ch_inp_res ? max_used_block_height : 0); TIME_MEASURE_FINISH_PD(tx_processing_time); @@ -240,9 +248,11 @@ namespace currency << "/" << m_performance_data.validate_alias_time.get_last_val() << "/" << m_performance_data.check_keyimages_ws_ms_time.get_last_val() << "/" << m_performance_data.check_inputs_time.get_last_val() + << "/b"<< m_performance_data.check_post_hf4_balance.get_last_val() << "/" << m_performance_data.begin_tx_time.get_last_val() << "/" << m_performance_data.update_db_time.get_last_val() - << "/" << m_performance_data.db_commit_time.get_last_val() << ")" ); + << "/" << m_performance_data.db_commit_time.get_last_val() + << ")"); return true; } diff --git a/src/currency_core/tx_pool.h b/src/currency_core/tx_pool.h index 92d60604..b837f28f 100644 --- a/src/currency_core/tx_pool.h +++ b/src/currency_core/tx_pool.h @@ -77,7 +77,8 @@ namespace currency epee::math_helper::average check_inputs_time; epee::math_helper::average begin_tx_time; epee::math_helper::average update_db_time; - epee::math_helper::average db_commit_time; + epee::math_helper::average db_commit_time; + epee::math_helper::average check_post_hf4_balance; }; typedef std::unordered_map> key_image_cache; diff --git a/tests/core_tests/hard_fork_4.cpp b/tests/core_tests/hard_fork_4.cpp index 2c4a7fd3..e5b4d6b4 100644 --- a/tests/core_tests/hard_fork_4.cpp +++ b/tests/core_tests/hard_fork_4.cpp @@ -89,6 +89,10 @@ bool hard_fork_4_consolidated_txs::generate(std::vector& event ADD_CUSTOM_EVENT(events, tx_0b); MAKE_NEXT_BLOCK_TX_LIST(events, blk_1, blk_0r, miner_acc, std::list({tx_0a, tx_0b})); + size_t dhc = count_type_in_variant_container(tx_0b.extra); + CHECK_AND_ASSERT_MES(dhc == tx_0b.vout.size(), false, "unexpected derivation hints count: " << dhc); + + REWIND_BLOCKS_N_WITH_TIME(events, blk_1r, blk_1, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); // check Alice's balance @@ -100,7 +104,7 @@ bool hard_fork_4_consolidated_txs::generate(std::vector& event CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt.get(), "alice", alice_amount, 0, alice_amount, 0, 0), false, ""); uint64_t miner_amount = MK_TEST_COINS(60); - uint64_t bob_amount = miner_amount + alice_amount - TX_DEFAULT_FEE; + m_bob_amount = miner_amount + alice_amount - TX_DEFAULT_FEE; // Consolidated tx (TX_FLAG_SIGNATURE_MODE_SEPARATE). @@ -119,17 +123,33 @@ bool hard_fork_4_consolidated_txs::generate(std::vector& event std::vector destinations; if (miner_change != 0) destinations.push_back(tx_destination_entry(miner_change, miner_acc.get_public_address())); - destinations.push_back(tx_destination_entry(bob_amount, bob_acc.get_public_address())); + destinations.push_back(tx_destination_entry(m_bob_amount, bob_acc.get_public_address())); add_flags_to_all_destination_entries(tx_destination_entry_flags::tdef_explicit_native_asset_id, destinations); r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_extra, empty_attachment, tx_1, get_tx_version_from_events(events), one_time_secret_key, 0, 0, 0, true, TX_FLAG_SIGNATURE_MODE_SEPARATE, TX_DEFAULT_FEE, gen_context); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); + dhc = count_type_in_variant_container(tx_1.extra); + CHECK_AND_ASSERT_MES(dhc == destinations.size(), false, "unexpected derivation hints count: " << dhc); + // partially completed tx_1 shouldn't be accepted - //DO_CALLBACK(events, "mark_invalid_tx"); - ADD_CUSTOM_EVENT(events, tx_1); - MAKE_NEXT_BLOCK_TX1(events, blk_2a, blk_1r, miner_acc, tx_1); + + // now we added a balance check to tx_memory_pool::add_tx() for post-HF4 txs, so the behaviour is the same -- partially completed consolidated tx won't be added to the pool -- sowle + // (subject to change in future) + + //if (m_post_hf4_zarcanum) + //{ + // ADD_CUSTOM_EVENT(events, tx_1); + // DO_CALLBACK(events, "mark_invalid_block"); + // MAKE_NEXT_BLOCK_TX1(events, blk_2a, blk_1r, miner_acc, tx_1); + // DO_CALLBACK(events, "clear_tx_pool"); + //} + //else + //{ + DO_CALLBACK(events, "mark_invalid_tx"); + ADD_CUSTOM_EVENT(events, tx_1); + //} } @@ -147,23 +167,25 @@ bool hard_fork_4_consolidated_txs::generate(std::vector& event 0, 0, 0, true, TX_FLAG_SIGNATURE_MODE_SEPARATE, 0 /* note zero fee here */, gen_context); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); + size_t dhc_2 = count_type_in_variant_container(tx_1.extra); + CHECK_AND_ASSERT_MES(dhc_2 == dhc, false, "unexpected derivation hints count: " << dhc_2); + ADD_CUSTOM_EVENT(events, tx_1); } MAKE_NEXT_BLOCK_TX1(events, blk_2, blk_1r, miner_acc, tx_1); - //std::shared_ptr bob_wlt; - //r = generator.init_test_wallet(bob_acc, get_block_hash(blk_0), bob_wlt); - //CHECK_AND_ASSERT_MES(r, false, "init_test_wallet failed"); - //r = generator.refresh_test_wallet(events, bob_wlt.get(), get_block_hash(blk_2), 2 * CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 2); - //CHECK_AND_ASSERT_MES(r, false, "refresh_test_wallet failed"); - //CHECK_AND_ASSERT_MES(check_balance_via_wallet(*bob_wlt.get(), "Bob", bob_amount, 0, 0, 0, 0), false, ""); - + DO_CALLBACK(events, "c1"); return true; } bool hard_fork_4_consolidated_txs::c1(currency::core& c, size_t ev_index, const std::vector& events) { + std::shared_ptr bob_wlt = init_playtime_test_wallet(events, c, BOB_ACC_IDX); + bob_wlt->refresh(); + + CHECK_AND_ASSERT_MES(check_balance_via_wallet(*bob_wlt.get(), "Bob", m_bob_amount, 0, 0, 0, 0), false, ""); + return true; } From 3eb711fbf80c48518fa12fe813c53544e6731519 Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 27 Mar 2024 17:08:19 +0100 Subject: [PATCH 058/184] tx_pool: is_tx_blacklisted() --- src/currency_core/tx_pool.cpp | 13 +++++++++---- src/currency_core/tx_pool.h | 2 ++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/currency_core/tx_pool.cpp b/src/currency_core/tx_pool.cpp index b8185cbf..998d4fed 100644 --- a/src/currency_core/tx_pool.cpp +++ b/src/currency_core/tx_pool.cpp @@ -885,7 +885,7 @@ namespace currency { //not the best implementation at this time, sorry :( - if (m_db_black_tx_list.get(get_transaction_hash(txd.tx))) + if (is_tx_blacklisted(get_transaction_hash(txd.tx))) return false; //check is ring_signature already checked ? @@ -976,8 +976,8 @@ namespace currency return "(no transactions, the pool is empty)"; // sort output by receive time txs.sort([](const std::pair& lhs, const std::pair& rhs) -> bool { return lhs.second.receive_time < rhs.second.receive_time; }); - ss << "# | transaction id | size | fee | ins | outs | live_time | max used block | last failed block | ver | kept by a block?" << ENDL; - // 1234 f99fe6d4335fc0ddd69e6880a4d95e0f6ea398de0324a6837021a61c6a31cacd 187157 0.10000111 2000 2000 d0.h10.m16.s17 1234567 <12345..> 1234567 <12345..> 2 YES + ss << "# | transaction id | size | fee | ins | outs | live_time | max used block | last failed block | ver | status " << ENDL; + // 1234 f99fe6d4335fc0ddd69e6880a4d95e0f6ea398de0324a6837021a61c6a31cacd 187157 0.10000111 2000 2000 d0.h10.m16.s17 1234567 <12345..> 1234567 <12345..> 2 kept_by_block BLACKLISTED size_t i = 0; for (auto& tx : txs) { @@ -995,7 +995,7 @@ namespace currency << std::setw(7) << txd.last_failed_height << " " << std::setw(9) << print16(txd.last_failed_id) << " " << std::setw(3) << txd.tx.version << " " - << (txd.kept_by_block ? "YES" : "no ") + << (txd.kept_by_block ? "kept_by_block " : "") << (is_tx_blacklisted(tx.first) ? "BLACKLISTED " : "") << ENDL; } return ss.str(); @@ -1324,6 +1324,11 @@ namespace currency } } //--------------------------------------------------------------------------------- + bool tx_memory_pool::is_tx_blacklisted(const crypto::hash& id) const + { + return m_db_black_tx_list.get(id) != nullptr; + } + //--------------------------------------------------------------------------------- bool tx_memory_pool::load_keyimages_cache() { CRITICAL_REGION_LOCAL(m_key_images_lock); diff --git a/src/currency_core/tx_pool.h b/src/currency_core/tx_pool.h index b837f28f..8b3ec595 100644 --- a/src/currency_core/tx_pool.h +++ b/src/currency_core/tx_pool.h @@ -141,6 +141,8 @@ namespace currency void remove_incompatible_txs(); // made public to be called after the BCS is loaded and hardfork info is ready + bool is_tx_blacklisted(const crypto::hash& id) const; + private: bool on_tx_add(crypto::hash tx_id, const transaction& tx, bool kept_by_block); bool on_tx_remove(const crypto::hash &tx_id, const transaction& tx, bool kept_by_block); From 709d16eb753be332773d681a404406affd562577 Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 27 Mar 2024 17:18:17 +0100 Subject: [PATCH 059/184] tx pool: asset operations basic validation on tx add --- src/currency_core/blockchain_storage.cpp | 72 ++++++++++--------- src/currency_core/blockchain_storage.h | 4 +- .../currency_format_utils_abstract.h | 21 ++++++ src/currency_core/tx_pool.cpp | 10 ++- 4 files changed, 71 insertions(+), 36 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 6e781c68..500983fc 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -4012,7 +4012,7 @@ bool blockchain_storage::pop_asset_info(const crypto::public_key& asset_id) return true; } //------------------------------------------------------------------ -bool blockchain_storage::validate_ado_ownership(asset_op_verification_context& avc) +bool validate_ado_ownership(asset_op_verification_context& avc) { asset_operation_ownership_proof aoop = AUTO_VAL_INIT(aoop); bool r = get_type_in_variant_container(avc.tx.proofs, aoop); @@ -4024,32 +4024,23 @@ bool blockchain_storage::validate_ado_ownership(asset_op_verification_context& a return crypto::verify_schnorr_sig(avc.tx_id, owner_key, aoop.gss); } //------------------------------------------------------------------ -bool blockchain_storage::put_asset_info(const transaction& tx, const crypto::hash& tx_id, const asset_descriptor_operation& ado) +bool blockchain_storage::validate_asset_operation_against_current_blochain_state(asset_op_verification_context& avc) const { CRITICAL_REGION_LOCAL(m_read_lock); - asset_op_verification_context avc = { tx, tx_id, ado }; + CHECK_AND_ASSERT_MES(get_or_calculate_asset_id(avc.ado, &avc.asset_id_pt, &avc.asset_id), false, "get_or_calculate_asset_id failed"); + avc.asset_op_history = m_db_assets.find(avc.asset_id); + + const asset_descriptor_operation& ado = avc.ado; if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_REGISTER) { - CHECK_AND_ASSERT_MES(get_or_calculate_asset_id(avc.ado, &avc.asset_id_pt, &avc.asset_id), false, "get_or_calculate_asset_id failed"); - - avc.asset_op_history = m_db_assets.find(avc.asset_id); CHECK_AND_ASSERT_MES(!avc.asset_op_history, false, "asset with id " << avc.asset_id << " has already been registered"); - avc.amount_to_validate = ado.descriptor.current_supply; - CHECK_AND_ASSERT_MES(validate_asset_operation_amount_commitment(avc), false, "asset operation validation failed!"); - - assets_container::t_value_type local_asset_history = AUTO_VAL_INIT(local_asset_history); - local_asset_history.push_back(ado); - m_db_assets.set(avc.asset_id, local_asset_history); - LOG_PRINT_MAGENTA("[ASSET_REGISTERED]: " << print_money_brief(ado.descriptor.current_supply, ado.descriptor.decimal_point) << ", " << avc.asset_id << ": " << ado.descriptor.ticker << ", \"" << ado.descriptor.full_name << "\"", LOG_LEVEL_1); + CHECK_AND_ASSERT_MES(validate_asset_operation_amount_commitment(avc), false, "validate_asset_operation_amount_commitment failed!"); } else { - CHECK_AND_ASSERT_MES(get_or_calculate_asset_id(avc.ado, &avc.asset_id_pt, &avc.asset_id), false, "get_or_calculate_asset_id failed"); - avc.asset_op_history = m_db_assets.find(avc.asset_id); - CHECK_AND_ASSERT_MES(avc.asset_op_history && avc.asset_op_history->size(), false, "asset with id " << avc.asset_id << " has not been registered"); // check ownership permission if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_EMIT || ado.operation_type == ASSET_DESCRIPTOR_OPERATION_UPDATE /*|| ado.operation_type == ASSET_DESCRIPTOR_OPERATION_PUBLIC_BURN*/) @@ -4092,25 +4083,40 @@ bool blockchain_storage::put_asset_info(const transaction& tx, const crypto::has bool r = validate_asset_operation_amount_commitment(avc); CHECK_AND_ASSERT_MES(r, false, "Balance proof validation failed for asset_descriptor_operation"); } + } - assets_container::t_value_type local_asset_history = *avc.asset_op_history; - local_asset_history.push_back(ado); - m_db_assets.set(avc.asset_id, local_asset_history); + return true; +} +//------------------------------------------------------------------ +bool blockchain_storage::put_asset_info(const transaction& tx, const crypto::hash& tx_id, const asset_descriptor_operation& ado) +{ + CRITICAL_REGION_LOCAL(m_read_lock); - switch(ado.operation_type) - { - case ASSET_DESCRIPTOR_OPERATION_UPDATE: - LOG_PRINT_MAGENTA("[ASSET_UPDATED]: " << avc.asset_id << ": " << ado.descriptor.ticker << ", \"" << ado.descriptor.full_name << "\"", LOG_LEVEL_1); - break; - case ASSET_DESCRIPTOR_OPERATION_EMIT: - LOG_PRINT_MAGENTA("[ASSET_EMITTED]: " << print_money_brief(avc.amount_to_validate, ado.descriptor.decimal_point) << ", " << avc.asset_id << ": " << ado.descriptor.ticker << ", \"" << ado.descriptor.full_name << "\"", LOG_LEVEL_1); - break; - case ASSET_DESCRIPTOR_OPERATION_PUBLIC_BURN: - LOG_PRINT_MAGENTA("[ASSET_BURNT]: " << print_money_brief(avc.amount_to_validate, ado.descriptor.decimal_point) << ", " << avc.asset_id << ": " << ado.descriptor.ticker << ", \"" << ado.descriptor.full_name << "\"", LOG_LEVEL_1); - break; - default: - LOG_ERROR("Unknown operation type: " << (int)ado.operation_type); - } + asset_op_verification_context avc = { tx, tx_id, ado }; + CHECK_AND_ASSERT_MES(validate_asset_operation_against_current_blochain_state(avc), false, "asset operation validation failed"); + + assets_container::t_value_type local_asset_history{}; + if (avc.asset_op_history) + local_asset_history = *avc.asset_op_history; + local_asset_history.push_back(ado); + m_db_assets.set(avc.asset_id, local_asset_history); + + switch(ado.operation_type) + { + case ASSET_DESCRIPTOR_OPERATION_REGISTER: + LOG_PRINT_MAGENTA("[ASSET_REGISTERED]: " << print_money_brief(ado.descriptor.current_supply, ado.descriptor.decimal_point) << ", " << avc.asset_id << ": " << ado.descriptor.ticker << ", \"" << ado.descriptor.full_name << "\"", LOG_LEVEL_1); + break; + case ASSET_DESCRIPTOR_OPERATION_UPDATE: + LOG_PRINT_MAGENTA("[ASSET_UPDATED]: " << avc.asset_id << ": " << ado.descriptor.ticker << ", \"" << ado.descriptor.full_name << "\"", LOG_LEVEL_1); + break; + case ASSET_DESCRIPTOR_OPERATION_EMIT: + LOG_PRINT_MAGENTA("[ASSET_EMITTED]: " << print_money_brief(avc.amount_to_validate, ado.descriptor.decimal_point) << ", " << avc.asset_id << ": " << ado.descriptor.ticker << ", \"" << ado.descriptor.full_name << "\"", LOG_LEVEL_1); + break; + case ASSET_DESCRIPTOR_OPERATION_PUBLIC_BURN: + LOG_PRINT_MAGENTA("[ASSET_BURNT]: " << print_money_brief(avc.amount_to_validate, ado.descriptor.decimal_point) << ", " << avc.asset_id << ": " << ado.descriptor.ticker << ", \"" << ado.descriptor.full_name << "\"", LOG_LEVEL_1); + break; + default: + LOG_ERROR("Unknown operation type: " << (int)ado.operation_type); } return true; diff --git a/src/currency_core/blockchain_storage.h b/src/currency_core/blockchain_storage.h index eb9c017a..c24e1104 100644 --- a/src/currency_core/blockchain_storage.h +++ b/src/currency_core/blockchain_storage.h @@ -375,6 +375,8 @@ namespace currency bool for_altchain, const alt_chain_type& alt_chain = alt_chain_type(), uint64_t split_height = 0)const; + bool validate_asset_operation_against_current_blochain_state(asset_op_verification_context& avc) const; + void set_core_runtime_config(const core_runtime_config& pc) const; const core_runtime_config& get_core_runtime_config()const; size_t get_current_sequence_factor(bool pos)const; @@ -494,6 +496,7 @@ namespace currency bool print_tx_outputs_lookup(const crypto::hash& tx_id) const; uint64_t get_last_x_block_height(bool pos)const; bool is_tx_spendtime_unlocked(uint64_t unlock_time)const; + private: //-------------- DB containers -------------- @@ -670,7 +673,6 @@ namespace currency bool unprocess_blockchain_tx_extra(const transaction& tx); bool process_blockchain_tx_attachments(const transaction& tx, uint64_t h, const crypto::hash& bl_id, uint64_t timestamp); bool unprocess_blockchain_tx_attachments(const transaction& tx, uint64_t h, uint64_t timestamp); - bool validate_ado_ownership(asset_op_verification_context& avc); bool pop_alias_info(const extra_alias_entry& ai); bool put_alias_info(const transaction& tx, extra_alias_entry& ai); bool pop_asset_info(const crypto::public_key& asset_id); diff --git a/src/currency_core/currency_format_utils_abstract.h b/src/currency_core/currency_format_utils_abstract.h index 11d051b9..416d955b 100644 --- a/src/currency_core/currency_format_utils_abstract.h +++ b/src/currency_core/currency_format_utils_abstract.h @@ -151,6 +151,27 @@ namespace currency return return_value_if_none_found; } //--------------------------------------------------------------- + // if cb returns false, stop immediately and return false + template + bool process_type_in_variant_container_and_make_sure_its_unique(const variant_container_t& av, callback_t& cb, bool return_value_if_none_found = true) + { + bool found = false; + for (auto& ai : av) + { + if (ai.type() == typeid(specific_type_t)) + { + if (found) + return false; // already have it, type in not unique + found = true; + if (!cb(boost::get(ai))) + return false; + } + } + if (found) + return true; + return return_value_if_none_found; + } + //--------------------------------------------------------------- // callback should return true to continue iterating through the container template bool handle_2_alternative_types_in_variant_container(const container_t& container, callback_t cb) diff --git a/src/currency_core/tx_pool.cpp b/src/currency_core/tx_pool.cpp index 998d4fed..a18e896d 100644 --- a/src/currency_core/tx_pool.cpp +++ b/src/currency_core/tx_pool.cpp @@ -224,13 +224,19 @@ namespace currency } TIME_MEASURE_FINISH_PD(check_inputs_time); - TIME_MEASURE_START_PD(check_post_hf4_balance); if (tx.version > TRANSACTION_VERSION_PRE_HF4) { + TIME_MEASURE_START_PD(check_post_hf4_balance); r = check_tx_balance(tx, id); CHECK_AND_ASSERT_MES_CUSTOM(r, false, { tvc.m_verification_failed = true; }, "post-HF4 tx: balance proof is invalid"); + TIME_MEASURE_FINISH_PD(check_post_hf4_balance); + + r = process_type_in_variant_container_and_make_sure_its_unique(tx.extra, [&](const asset_descriptor_operation& ado){ + asset_op_verification_context avc = { tx, id, ado }; + return m_blockchain.validate_asset_operation_against_current_blochain_state(avc); + }, true); + CHECK_AND_ASSERT_MES_CUSTOM(r, false, { tvc.m_verification_failed = true; }, "post-HF4 tx: asset operation is invalid"); } - TIME_MEASURE_FINISH_PD(check_post_hf4_balance); do_insert_transaction(tx, id, blob_size, kept_by_block, tx_fee, ch_inp_res ? max_used_block_id : null_hash, ch_inp_res ? max_used_block_height : 0); From 80fd303081008bd53a29fbade886e90a334e0d05 Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 13 Mar 2024 21:30:43 +0100 Subject: [PATCH 060/184] compilation fixed for gcc (by using universal references for process_type_in_variant_container_*) --- src/currency_core/currency_format_utils_abstract.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/currency_core/currency_format_utils_abstract.h b/src/currency_core/currency_format_utils_abstract.h index 416d955b..3e5a63fe 100644 --- a/src/currency_core/currency_format_utils_abstract.h +++ b/src/currency_core/currency_format_utils_abstract.h @@ -134,7 +134,7 @@ namespace currency //--------------------------------------------------------------- // if cb returns true, it means "continue", false -- means "stop" template - bool process_type_in_variant_container(const variant_container_t& av, callback_t& cb, bool return_value_if_none_found = true) + bool process_type_in_variant_container(const variant_container_t& av, callback_t&& cb, bool return_value_if_none_found = true) { bool found = false; for (auto& ai : av) @@ -153,7 +153,7 @@ namespace currency //--------------------------------------------------------------- // if cb returns false, stop immediately and return false template - bool process_type_in_variant_container_and_make_sure_its_unique(const variant_container_t& av, callback_t& cb, bool return_value_if_none_found = true) + bool process_type_in_variant_container_and_make_sure_its_unique(const variant_container_t& av, callback_t&& cb, bool return_value_if_none_found = true) { bool found = false; for (auto& ai : av) From 69e68807bfe1afa2ea2a3f00c89a894cc1996ff3 Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 27 Mar 2024 18:57:30 +0100 Subject: [PATCH 061/184] coretests: minor forgotten change --- tests/core_tests/hard_fork_4.h | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/core_tests/hard_fork_4.h b/tests/core_tests/hard_fork_4.h index bf12419f..f8235675 100644 --- a/tests/core_tests/hard_fork_4.h +++ b/tests/core_tests/hard_fork_4.h @@ -13,6 +13,7 @@ struct hard_fork_4_consolidated_txs : public wallet_test bool c1(currency::core& c, size_t ev_index, const std::vector& events); mutable bool m_post_hf4_zarcanum = false; + mutable uint64_t m_bob_amount = 0; }; From 320816fd992a13f02ec1bd939437f083de5e6688 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 27 Mar 2024 18:34:03 +0100 Subject: [PATCH 062/184] added test for getblocktemplate --- src/currency_core/blockchain_storage.cpp | 10 ++- tests/core_tests/chaingen_main.cpp | 2 + tests/core_tests/wallet_tests.cpp | 92 ++++++++++++++++++++++++ tests/core_tests/wallet_tests.h | 8 +++ 4 files changed, 109 insertions(+), 3 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 500983fc..0e6c923c 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -6414,11 +6414,16 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt tx.signatures.clear(); tx.proofs.clear(); } - + currency::tx_verification_context tvc = AUTO_VAL_INIT(tvc); //std::vector tx_outs_commitments; if (!m_is_in_checkpoint_zone) { - auto cleanup = [&](){ purge_block_data_from_blockchain(bl, tx_processed_count); bvc.m_verification_failed = true; }; + auto cleanup = [&](){ + bool add_res = m_tx_pool.add_tx(tx, tvc, true, true); + m_tx_pool.add_transaction_to_black_list(tx); + purge_block_data_from_blockchain(bl, tx_processed_count); + bvc.m_verification_failed = true; + }; CHECK_AND_ASSERT_MES_CUSTOM(collect_rangeproofs_data_from_tx(tx, tx_id, range_proofs_agregated), false, cleanup(), "block " << id << ", tx " << tx_id << ": collect_rangeproofs_data_from_tx failed"); @@ -6435,7 +6440,6 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt if(!check_tx_inputs(tx, tx_id)) { LOG_PRINT_L0("Block with id: " << id << " has at least one transaction (id: " << tx_id << ") with wrong inputs."); - currency::tx_verification_context tvc = AUTO_VAL_INIT(tvc); if (taken_from_pool) { bool add_res = m_tx_pool.add_tx(tx, tvc, true, true); diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index 31d317f7..aa0974a4 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -1089,6 +1089,8 @@ int main(int argc, char* argv[]) GENERATE_AND_PLAY_HF(wallet_rpc_exchange_suite, "3,4"); GENERATE_AND_PLAY(wallet_chain_switch_with_spending_the_same_ki); GENERATE_AND_PLAY(wallet_sending_to_integrated_address); + GENERATE_AND_PLAY_HF(block_template_blacklist_test, "4-*"); + // GENERATE_AND_PLAY(emission_test); // simulate 1 year of blockchain, too long run (1 y ~= 1 hr), by demand only // LOG_ERROR2("print_reward_change_first_blocks.log", currency::print_reward_change_first_blocks(525601).str()); // outputs first 1 year of blocks' rewards (simplier) diff --git a/tests/core_tests/wallet_tests.cpp b/tests/core_tests/wallet_tests.cpp index 373ac3a0..0be2a9bd 100644 --- a/tests/core_tests/wallet_tests.cpp +++ b/tests/core_tests/wallet_tests.cpp @@ -3809,3 +3809,95 @@ bool wallet_and_sweep_below::c1(currency::core& c, size_t ev_index, const std::v return true; } + + +//------------------------------------------------------------------------------ +block_template_blacklist_test::block_template_blacklist_test() +{ + REGISTER_CALLBACK_METHOD(block_template_blacklist_test, c1); +} + +bool block_template_blacklist_test::generate(std::vector& events) const +{ + // Test idea: basic check for wallet2::sweep_below() functionality + + uint64_t ts = test_core_time::get_time(); + m_accounts.resize(TOTAL_ACCS_COUNT); + account_base preminer_acc; + preminer_acc.generate(); + preminer_acc.set_createtime(ts); + account_base& miner_acc = m_accounts[MINER_ACC_IDX]; miner_acc.generate(); miner_acc.set_createtime(ts); + account_base& alice_acc = m_accounts[ALICE_ACC_IDX]; alice_acc.generate(); alice_acc.set_createtime(ts); + MAKE_GENESIS_BLOCK(events, blk_0, preminer_acc, ts); + DO_CALLBACK(events, "configure_core"); + + MAKE_NEXT_BLOCK(events, blk_1, blk_0, preminer_acc); + + REWIND_BLOCKS_N_WITH_TIME(events, blk_1r, blk_1, miner_acc, 3 * CURRENCY_MINED_MONEY_UNLOCK_WINDOW - 1); + + DO_CALLBACK(events, "c1"); + return true; +} + +bool block_template_blacklist_test::c1(currency::core& c, size_t ev_index, const std::vector& events) +{ + bool r = false; + std::shared_ptr miner_wlt = init_playtime_test_wallet(events, c, MINER_ACC_IDX); + std::shared_ptr alice_wlt = init_playtime_test_wallet(events, c, ALICE_ACC_IDX); + + miner_wlt->refresh(); + miner_wlt->transfer(COIN / 10, alice_wlt->get_account().get_public_address()); + miner_wlt->transfer(COIN / 10, alice_wlt->get_account().get_public_address()); + + //take first transaction and corrupt it intentionalyy + std::list txs; + c.get_tx_pool().get_transactions(txs); + CHECK_AND_ASSERT_MES(txs.size() == 2, false, "wrong tx count"); + + + txs.resize(1); + currency::transaction broken_tx; + uint64_t blob_size = 0; + uint64_t fee = 0; + r = c.get_tx_pool().take_tx(currency::get_transaction_hash(*txs.begin()), broken_tx, blob_size, fee); + CHECK_AND_ASSERT_MES(r, false, "failed to take from pool"); + + + broken_tx.signatures.resize(broken_tx.signatures.size() - 1); + //manually add completely broken tx to pool + c.get_tx_pool().do_insert_transaction(broken_tx, get_transaction_hash(broken_tx), currency::get_object_blobsize(broken_tx), false, get_tx_fee(broken_tx), c.get_block_id_by_height(0), 0); + + CHECK_AND_ASSERT_MES(c.get_tx_pool().get_transactions_count() == 2, false, "wrong tx count"); + + + currency::create_block_template_params cbtp = AUTO_VAL_INIT(cbtp); + cbtp.miner_address = miner_wlt->get_account().get_public_address(); + + { + currency::create_block_template_response cbtr = AUTO_VAL_INIT(cbtr); + r = c.get_block_template(cbtp, cbtr); + + CHECK_AND_ASSERT_MES(r, false, "failed to create block template"); + CHECK_AND_ASSERT_MES(cbtr.b.tx_hashes.size() == 2, false, "failed to create block template"); + } + + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); + CHECK_AND_ASSERT_MES(!r, false, "Unexpectedly created block"); + + //now let's check if broken tx actually added to next blocktemplate + + { + currency::create_block_template_response cbtr = AUTO_VAL_INIT(cbtr); + r = c.get_block_template(cbtp, cbtr); + + CHECK_AND_ASSERT_MES(r, false, "failed to create block template"); + CHECK_AND_ASSERT_MES(cbtr.b.tx_hashes.size() == 1, false, "failed to create block template"); + + } + + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); + CHECK_AND_ASSERT_MES(r, false, "Unexpectedly failed to create block"); + + + return true; +} diff --git a/tests/core_tests/wallet_tests.h b/tests/core_tests/wallet_tests.h index a5aad448..cad3871e 100644 --- a/tests/core_tests/wallet_tests.h +++ b/tests/core_tests/wallet_tests.h @@ -294,3 +294,11 @@ struct wallet_and_sweep_below : public wallet_test bool generate(std::vector& events) const; bool c1(currency::core& c, size_t ev_index, const std::vector& events); }; + + +struct block_template_blacklist_test : public wallet_test +{ + block_template_blacklist_test(); + bool generate(std::vector& events) const; + bool c1(currency::core& c, size_t ev_index, const std::vector& events); +}; \ No newline at end of file From d2ee1b3fa8ae18a9ad96d76fbdff49b0da36ee5c Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 27 Mar 2024 19:10:15 +0100 Subject: [PATCH 063/184] added COMMAND_RPC_REMOVE_TX_FROM_POOL --- src/rpc/core_rpc_server.cpp | 14 ++++++++++++++ src/rpc/core_rpc_server.h | 2 ++ src/rpc/core_rpc_server_commands_defs.h | 22 ++++++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index d45e9704..1fbe0a5a 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -1333,6 +1333,20 @@ namespace currency res.status = API_RETURN_CODE_OK; return true; } + + //------------------------------------------------------------------------------------------------------------------------------ + bool core_rpc_server::on_remove_tx_from_pool(const COMMAND_RPC_REMOVE_TX_FROM_POOL::request& req, COMMAND_RPC_REMOVE_TX_FROM_POOL::response& res, connection_context& cntx) + { + for (const auto& tx_id_str : req.tx_to_remove) + { + crypto::hash tx_id = epee::transform_str_to_t_pod(tx_id_str); + currency::transaction tx; uint64_t dummy1 = 0; uint64_t dummy2 = 0; + m_core.get_tx_pool().take_tx(tx_id,tx, dummy1, dummy1); + } + + res.status = API_RETURN_CODE_OK; + return true; + } } diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h index e88f6dbf..daf9452c 100644 --- a/src/rpc/core_rpc_server.h +++ b/src/rpc/core_rpc_server.h @@ -75,6 +75,7 @@ namespace currency bool on_aliases_by_address(const COMMAND_RPC_GET_ALIASES_BY_ADDRESS::request& req, COMMAND_RPC_GET_ALIASES_BY_ADDRESS::response& res, epee::json_rpc::error& error_resp, connection_context& cntx); bool on_get_alias_reward(const COMMAND_RPC_GET_ALIAS_REWARD::request& req, COMMAND_RPC_GET_ALIAS_REWARD::response& res, epee::json_rpc::error& error_resp, connection_context& cntx); bool on_reset_transaction_pool(const COMMAND_RPC_RESET_TX_POOL::request& req, COMMAND_RPC_RESET_TX_POOL::response& res, connection_context& cntx); + bool on_remove_tx_from_pool(const COMMAND_RPC_REMOVE_TX_FROM_POOL::request& req, COMMAND_RPC_REMOVE_TX_FROM_POOL::response& res, connection_context& cntx); bool on_get_pos_mining_details(const COMMAND_RPC_GET_POS_MINING_DETAILS::request& req, COMMAND_RPC_GET_POS_MINING_DETAILS::response& res, connection_context& cntx); bool on_get_current_core_tx_expiration_median(const COMMAND_RPC_GET_CURRENT_CORE_TX_EXPIRATION_MEDIAN::request& req, COMMAND_RPC_GET_CURRENT_CORE_TX_EXPIRATION_MEDIAN::response& res, connection_context& cntx); bool on_get_tx_details(const COMMAND_RPC_GET_TX_DETAILS::request& req, COMMAND_RPC_GET_TX_DETAILS::response& res, epee::json_rpc::error& error_resp, connection_context& cntx); @@ -156,6 +157,7 @@ namespace currency MAP_JON_RPC ("get_alt_blocks_details", on_get_alt_blocks_details, COMMAND_RPC_GET_ALT_BLOCKS_DETAILS) // MAP_JON_RPC ("reset_transaction_pool", on_reset_transaction_pool, COMMAND_RPC_RESET_TX_POOL) + MAP_JON_RPC ("remove_tx_from_pool", on_remove_tx_from_pool, COMMAND_RPC_REMOVE_TX_FROM_POOL) MAP_JON_RPC ("get_current_core_tx_expiration_median", on_get_current_core_tx_expiration_median, COMMAND_RPC_GET_CURRENT_CORE_TX_EXPIRATION_MEDIAN) // MAP_JON_RPC_WE("marketplace_global_get_offers_ex", on_get_offers_ex, COMMAND_RPC_GET_OFFERS_EX) diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index ce931d9d..42648bfa 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -1250,6 +1250,28 @@ namespace currency }; }; + struct COMMAND_RPC_REMOVE_TX_FROM_POOL + { + + struct request + { + std::list tx_to_remove; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(tx_to_remove) + END_KV_SERIALIZE_MAP() + }; + + struct response + { + std::string status; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(status) + END_KV_SERIALIZE_MAP() + }; + }; + struct COMMAND_RPC_GET_POS_MINING_DETAILS { struct request From f3820c32f2831a53ce10bcce75e8e65a872cb6d1 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 27 Mar 2024 20:06:20 +0100 Subject: [PATCH 064/184] added log message for COMMAND_RPC_GETBLOCKTEMPLATE --- src/rpc/core_rpc_server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 1fbe0a5a..65a90b58 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -983,7 +983,7 @@ namespace currency res.seed = currency::ethash_epoch_to_seed(currency::ethash_height_to_epoch(res.height)); res.status = API_RETURN_CODE_OK; - + LOG_PRINT_L1("COMMAND_RPC_GETBLOCKTEMPLATE OK, response block: " << ENDL << currency::obj_to_json_str(resp.b)); return true; } //------------------------------------------------------------------------------------------------------------------------------ From b72a0593c6816b686656cd9ac9b90ad9c9b1fd1d Mon Sep 17 00:00:00 2001 From: zano build machine Date: Wed, 27 Mar 2024 22:53:47 +0300 Subject: [PATCH 065/184] === build number: 287 -> 288 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index 931b5c93..c1e80ca9 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 287 +#define PROJECT_VERSION_BUILD_NO 288 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From df7b6a36745b7fbf436b0bb57b668a9931a5a485 Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 27 Mar 2024 22:13:43 +0100 Subject: [PATCH 066/184] tx pool: added ability to disable tx validation for tests --- src/currency_core/tx_pool.cpp | 14 ++++++++++++++ src/currency_core/tx_pool.h | 5 +++++ 2 files changed, 19 insertions(+) diff --git a/src/currency_core/tx_pool.cpp b/src/currency_core/tx_pool.cpp index a18e896d..33315870 100644 --- a/src/currency_core/tx_pool.cpp +++ b/src/currency_core/tx_pool.cpp @@ -104,6 +104,20 @@ namespace currency //--------------------------------------------------------------------------------- bool tx_memory_pool::add_tx(const transaction &tx, const crypto::hash &id, uint64_t blob_size, tx_verification_context& tvc, bool kept_by_block, bool from_core) { + // ------------------ UNSECURE CODE FOR TESTS --------------------- + if (m_unsecure_disable_tx_validation_on_addition) + { + uint64_t tx_fee = 0; + CHECK_AND_ASSERT_MES(get_tx_fee(tx, tx_fee), false, "get_tx_fee failed"); + do_insert_transaction(tx, id, blob_size, kept_by_block, tx_fee, null_hash, 0); + tvc.m_added_to_pool = true; + tvc.m_should_be_relayed = true; + tvc.m_verification_failed = false; + tvc.m_verification_impossible = false; + return true; + } + // ---------------- END OF UNSECURE CODE FOR TESTS ------------------- + bool r = false; // defaults diff --git a/src/currency_core/tx_pool.h b/src/currency_core/tx_pool.h index 8b3ec595..c97a498a 100644 --- a/src/currency_core/tx_pool.h +++ b/src/currency_core/tx_pool.h @@ -143,6 +143,10 @@ namespace currency bool is_tx_blacklisted(const crypto::hash& id) const; +#ifdef TX_POOL_USE_UNSECURE_TEST_FUNCTIONS + void unsecure_disable_tx_validation_on_addition(bool validation_disabled) { m_unsecure_disable_tx_validation_on_addition = validation_disabled; } +#endif + private: bool on_tx_add(crypto::hash tx_id, const transaction& tx, bool kept_by_block); bool on_tx_remove(const crypto::hash &tx_id, const transaction& tx, bool kept_by_block); @@ -197,6 +201,7 @@ namespace currency key_image_cache m_key_images; mutable epee::critical_section m_remove_stuck_txs_lock; + bool m_unsecure_disable_tx_validation_on_addition = false; }; } From 754a29a70963cb6904b75b8f3b2c72d84b9a30b6 Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 27 Mar 2024 22:15:13 +0100 Subject: [PATCH 067/184] wallet: defragmentation tx generation is now disabled by default --- src/wallet/wallet2.cpp | 10 +++++++--- src/wallet/wallet2.h | 3 +++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index cc533644..1264781e 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2023 Zano Project +// Copyright (c) 2014-2024 Zano Project // Copyright (c) 2014-2018 The Louisdor Project // Copyright (c) 2012-2013 The Cryptonote developers // Distributed under the MIT/X11 software license, see the accompanying @@ -81,6 +81,7 @@ namespace tools , m_log_prefix("???") , m_watch_only(false) , m_required_decoys_count(CURRENCY_DEFAULT_DECOY_SET_SIZE) + , m_defragmentation_tx_enabled(false) , m_max_allowed_output_amount_for_defragmentation_tx(CURRENCY_BLOCK_REWARD) , m_min_utxo_count_for_defragmentation_tx(WALLET_MIN_UTXO_COUNT_FOR_DEFRAGMENTATION_TX) , m_max_utxo_count_for_defragmentation_tx(WALLET_MAX_UTXO_COUNT_FOR_DEFRAGMENTATION_TX) @@ -3676,6 +3677,9 @@ void wallet2::get_transfers(transfer_container& incoming_transfers) const //---------------------------------------------------------------------------------------------------- bool wallet2::generate_utxo_defragmentation_transaction_if_needed(currency::transaction& tx) { + if (!m_defragmentation_tx_enabled) + return false; + construct_tx_param ctp = get_default_construct_tx_param(); ctp.create_utxo_defragmentation_tx = true; finalized_tx ftp{}; @@ -5947,8 +5951,8 @@ bool wallet2::decrypt_buffer(const std::string& buff, std::string& res_buff) //---------------------------------------------------------------------------------------------------- bool wallet2::prepare_tx_sources_for_defragmentation_tx(std::vector& sources, std::vector& selected_indicies, uint64_t& found_money) { - //prepare_free_transfers_cache(fake_outputs_count); - //free_amounts_cache_type& free_amounts_for_native_coin = m_found_free_amounts[currency::native_coin_asset_id]; + if (!m_defragmentation_tx_enabled) + return false; std::stringstream ss; if (epee::log_space::log_singletone::get_log_detalisation_level() >= LOG_LEVEL_2) diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 413adb97..05863a18 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -884,10 +884,13 @@ private: bool m_do_rise_transfer; + + bool m_defragmentation_tx_enabled; uint64_t m_max_allowed_output_amount_for_defragmentation_tx; uint64_t m_min_utxo_count_for_defragmentation_tx; uint64_t m_max_utxo_count_for_defragmentation_tx; size_t m_decoys_count_for_defragmentation_tx; + size_t m_required_decoys_count; pending_ki_file_container_t m_pending_key_images_file_container; uint64_t m_upper_transaction_size_limit; //TODO: auto-calc this value or request from daemon, now use some fixed value From dd04d6367b35ff6379c3ecbaf9b872db6fd63647 Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 27 Mar 2024 22:18:06 +0100 Subject: [PATCH 068/184] coretests: multiassets_basic_test improved to reflect recent changes with tx pool validation --- tests/core_tests/chaingen.cpp | 4 +- tests/core_tests/chaingen.h | 5 +- tests/core_tests/multiassets_test.cpp | 86 ++++++++++++++++++++++++++- 3 files changed, 89 insertions(+), 6 deletions(-) diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index f7aa0612..73340589 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -1,11 +1,9 @@ -// Copyright (c) 2014-2022 Zano Project +// Copyright (c) 2014-2024 Zano Project // Copyright (c) 2014-2018 The Louisdor Project // Copyright (c) 2012-2013 The Cryptonote developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#define USE_INSECURE_RANDOM_RPNG_ROUTINES // turns on pseudorandom number generator manupulations for tests - #include "chaingen.h" #include diff --git a/tests/core_tests/chaingen.h b/tests/core_tests/chaingen.h index 65a89226..087e0c3a 100644 --- a/tests/core_tests/chaingen.h +++ b/tests/core_tests/chaingen.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2022 Zano Project +// Copyright (c) 2014-2024 Zano Project // Copyright (c) 2014-2018 The Louisdor Project // Copyright (c) 2012-2013 The Cryptonote developers // Distributed under the MIT/X11 software license, see the accompanying @@ -9,7 +9,8 @@ #include #include -#define USE_INSECURE_RANDOM_RPNG_ROUTINES // turns on pseudorandom number generator manupulations for tests +#define USE_INSECURE_RANDOM_RPNG_ROUTINES // turns on pseudorandom number generator manupulations for tests +#define TX_POOL_USE_UNSECURE_TEST_FUNCTIONS // turns on special tests functions of tx pool #include "currency_core/currency_basic.h" #include "currency_core/currency_core.h" diff --git a/tests/core_tests/multiassets_test.cpp b/tests/core_tests/multiassets_test.cpp index 1a933292..240b3bb3 100644 --- a/tests/core_tests/multiassets_test.cpp +++ b/tests/core_tests/multiassets_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2023 Zano Project +// Copyright (c) 2014-2024 Zano Project // Copyright (c) 2014-2018 The Louisdor Project // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -186,7 +186,20 @@ bool multiassets_basic_test::c1(currency::core& c, size_t ev_index, const std::v CHECK_AND_ASSERT_MES(r, false, "Failed to get_asset_info"); asset_info.meta_info = "{\"some2\": \"info2\"}"; + r = false; + try + { + miner_wlt->update_asset(asset_id, asset_info, tx); + } + catch(tools::error::tx_rejected&) + { + r = true; + } + CHECK_AND_ASSERT_MES(r, false, "Test failed, broken ownership passed"); + + c.get_tx_pool().unsecure_disable_tx_validation_on_addition(true); miner_wlt->update_asset(asset_id, asset_info, tx); + c.get_tx_pool().unsecure_disable_tx_validation_on_addition(false); r = mine_next_pow_blocks_in_playtime(miner_wlt->get_account().get_public_address(), c, 2); CHECK_AND_ASSERT_MES(!r, false, "Test failed, broken ownership passed"); c.get_tx_pool().purge_transactions(); @@ -202,25 +215,54 @@ bool multiassets_basic_test::c1(currency::core& c, size_t ev_index, const std::v CHECK_AND_ASSERT_MES(r, false, "Failed to get_asset_info"); asset_info.ticker = "XXX"; + r = false; + try + { + miner_wlt->update_asset(asset_id, asset_info, tx); + } + catch(tools::error::tx_rejected&) + { + r = true; + } + CHECK_AND_ASSERT_MES(r, false, "update_asset succeeded, but this shouldn't happened"); + + c.get_tx_pool().unsecure_disable_tx_validation_on_addition(true); miner_wlt->update_asset(asset_id, asset_info, tx); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count()); r = mine_next_pow_block_in_playtime(miner_wlt->get_account().get_public_address(), c); CHECK_AND_ASSERT_MES(!r, false, "block with a bad tx was unexpectedly mined"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count()); // make sure tx was not confirmed + c.get_tx_pool().unsecure_disable_tx_validation_on_addition(false); c.get_tx_pool().purge_transactions(); + CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count()); // make sure tx was not added + // check update_asset() with modified 'full_name' r = c.get_blockchain_storage().get_asset_info(asset_id, asset_info); CHECK_AND_ASSERT_MES(r, false, "Failed to get_asset_info"); asset_info.full_name = "XXX"; + r = false; + try + { + miner_wlt->update_asset(asset_id, asset_info, tx); + } + catch(tools::error::tx_rejected&) + { + r = true; + } + CHECK_AND_ASSERT_MES(r, false, "update_asset succeeded, but this shouldn't happened"); + + c.get_tx_pool().unsecure_disable_tx_validation_on_addition(true); miner_wlt->update_asset(asset_id, asset_info, tx); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count()); r = mine_next_pow_block_in_playtime(miner_wlt->get_account().get_public_address(), c); CHECK_AND_ASSERT_MES(!r, false, "block with a bad tx was unexpectedly mined"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count()); // make sure tx was not confirmed + c.get_tx_pool().unsecure_disable_tx_validation_on_addition(false); c.get_tx_pool().purge_transactions(); + CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count()); // make sure tx was not added miner_wlt->refresh(); @@ -229,13 +271,27 @@ bool multiassets_basic_test::c1(currency::core& c, size_t ev_index, const std::v CHECK_AND_ASSERT_MES(r, false, "Failed to get_asset_info"); asset_info.decimal_point = 3; + r = false; + try + { + miner_wlt->update_asset(asset_id, asset_info, tx); + } + catch(tools::error::tx_rejected&) + { + r = true; + } + CHECK_AND_ASSERT_MES(r, false, "update_asset succeeded, but this shouldn't happened"); + + c.get_tx_pool().unsecure_disable_tx_validation_on_addition(true); miner_wlt->update_asset(asset_id, asset_info, tx); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count()); r = mine_next_pow_block_in_playtime(miner_wlt->get_account().get_public_address(), c); CHECK_AND_ASSERT_MES(!r, false, "block with a bad tx was unexpectedly mined"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count()); // make sure tx was not confirmed + c.get_tx_pool().unsecure_disable_tx_validation_on_addition(false); c.get_tx_pool().purge_transactions(); miner_wlt->refresh(); + CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count()); // make sure tx was not added // check update_asset() with modified 'owner' @@ -258,14 +314,29 @@ bool multiassets_basic_test::c1(currency::core& c, size_t ev_index, const std::v o.pado->descriptor.current_supply += 1000000; }); //test emit function but re-adjust current_supply to wrong amount + r = false; + try + { + miner_wlt->emit_asset(asset_id, destinations, tx); + } + catch(tools::error::tx_rejected&) + { + r = true; + } + CHECK_AND_ASSERT_MES(r, false, "emit_asset succeeded, but this shouldn't happened"); + + c.get_tx_pool().unsecure_disable_tx_validation_on_addition(true); miner_wlt->emit_asset(asset_id, destinations, tx); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count()); r = mine_next_pow_block_in_playtime(miner_wlt->get_account().get_public_address(), c); CHECK_AND_ASSERT_MES(!r, false, "block with a bad tx was unexpectedly mined"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count()); // make sure tx was not confirmed + c.get_tx_pool().unsecure_disable_tx_validation_on_addition(false); c.get_tx_pool().purge_transactions(); miner_wlt->refresh(); + CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count()); // make sure tx was not added + //------------------- tests that trying to break stuff ------------------- //test burn that burns more than tx has miner_wlt->get_debug_events_dispatcher().UNSUBSCRIBE_ALL(); @@ -276,11 +347,24 @@ bool multiassets_basic_test::c1(currency::core& c, size_t ev_index, const std::v }); + r = false; + try + { + miner_wlt->burn_asset(asset_id, 10000000000000, tx); + } + catch(tools::error::tx_rejected&) + { + r = true; + } + CHECK_AND_ASSERT_MES(r, false, "burn_asset succeeded, but this shouldn't happened"); + + c.get_tx_pool().unsecure_disable_tx_validation_on_addition(true); miner_wlt->burn_asset(asset_id, 10000000000000, tx); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count()); r = mine_next_pow_block_in_playtime(miner_wlt->get_account().get_public_address(), c); CHECK_AND_ASSERT_MES(!r, false, "block with a bad tx was unexpectedly mined"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count()); // make sure tx was not confirmed + c.get_tx_pool().unsecure_disable_tx_validation_on_addition(false); c.get_tx_pool().purge_transactions(); miner_wlt->refresh(); miner_wlt->get_debug_events_dispatcher().UNSUBSCRIBE_ALL(); From 9cf3c80fba6a46c55ea057ee52b91c4a91b18e18 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Thu, 28 Mar 2024 00:23:34 +0300 Subject: [PATCH 069/184] === build number: 288 -> 289 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index c1e80ca9..0292ae28 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 288 +#define PROJECT_VERSION_BUILD_NO 289 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From ad281664c38b5208d5782e143129c592eb38a89a Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 27 Mar 2024 23:07:26 +0100 Subject: [PATCH 070/184] fixed macos compilation --- src/rpc/core_rpc_server.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 65a90b58..46d27670 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -1340,8 +1340,8 @@ namespace currency for (const auto& tx_id_str : req.tx_to_remove) { crypto::hash tx_id = epee::transform_str_to_t_pod(tx_id_str); - currency::transaction tx; uint64_t dummy1 = 0; uint64_t dummy2 = 0; - m_core.get_tx_pool().take_tx(tx_id,tx, dummy1, dummy1); + currency::transaction tx; size_t dummy1 = 0; uint64_t dummy2 = 0; + m_core.get_tx_pool().take_tx(tx_id, tx, dummy1, dummy1); } res.status = API_RETURN_CODE_OK; From 6f35ced0525e71dce0ed57329bfc3aa50e4104e9 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Thu, 28 Mar 2024 01:08:01 +0300 Subject: [PATCH 071/184] === build number: 289 -> 290 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index 0292ae28..fc6d8a54 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 289 +#define PROJECT_VERSION_BUILD_NO 290 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From 98d124860cbef3747991ce9637948ff62cef717c Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 27 Mar 2024 23:21:56 +0100 Subject: [PATCH 072/184] fixed macos compilation - 2 --- src/rpc/core_rpc_server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 46d27670..cd9c20d2 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -1341,7 +1341,7 @@ namespace currency { crypto::hash tx_id = epee::transform_str_to_t_pod(tx_id_str); currency::transaction tx; size_t dummy1 = 0; uint64_t dummy2 = 0; - m_core.get_tx_pool().take_tx(tx_id, tx, dummy1, dummy1); + m_core.get_tx_pool().take_tx(tx_id, tx, dummy1, dummy2); } res.status = API_RETURN_CODE_OK; From cfb4e481b4ad37b33c2bc7660299e6fac7e8afb6 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 28 Mar 2024 12:49:43 +0100 Subject: [PATCH 073/184] Implemented auto documentation --- .../include/net/http_server_handlers_map2.h | 1 + .../serialization/keyvalue_serialization.h | 39 ++++++++++++++----- .../keyvalue_serialization_overloads.h | 23 ++++++++--- src/rpc/core_rpc_server_commands_defs.h | 14 ++++--- 4 files changed, 56 insertions(+), 21 deletions(-) diff --git a/contrib/epee/include/net/http_server_handlers_map2.h b/contrib/epee/include/net/http_server_handlers_map2.h index 50ab3e30..b7ad8799 100644 --- a/contrib/epee/include/net/http_server_handlers_map2.h +++ b/contrib/epee/include/net/http_server_handlers_map2.h @@ -40,6 +40,7 @@ typename_t get_documentation_json_struct() return AUTO_VAL_INIT_T(typename_t); } + template bool auto_doc_t(const std::string& prefix_name, std::string& generate_reference) { diff --git a/contrib/epee/include/serialization/keyvalue_serialization.h b/contrib/epee/include/serialization/keyvalue_serialization.h index 856ee830..e3a48a34 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization.h +++ b/contrib/epee/include/serialization/keyvalue_serialization.h @@ -39,9 +39,9 @@ namespace epee #define BEGIN_KV_SERIALIZE_MAP() \ public: \ template \ - bool store(t_storage& st, typename t_storage::hsection hparent_section = nullptr, bool auto_doc_mode = false) const\ + bool store(t_storage& st, typename t_storage::hsection hparent_section = nullptr) const\ {\ - return serialize_map(*this, st, hparent_section, auto_doc_mode); \ + return serialize_map(*this, st, hparent_section); \ }\ template \ bool _load(t_storage& stg, typename t_storage::hsection hparent_section = nullptr)\ @@ -62,7 +62,7 @@ public: \ }\ }\ template \ - static bool serialize_map(this_type& this_ref, t_storage& stg, typename t_storage::hsection hparent_section, bool auto_doc_mode = false) \ + static bool serialize_map(this_type& this_ref, t_storage& stg, typename t_storage::hsection hparent_section) \ { #define KV_SERIALIZE_N(varialble, val_name) \ @@ -72,22 +72,43 @@ public: \ epee::serialization::selector::serialize(this_ref.varialble, stg, hparent_section, val_name, auto_doc_mode, substitute, description); #define KV_SERIALIZE_N_DOC2(varialble, val_name) \ - {using var_type = decltype(this_ref.varialble); \ + { using var_type = decltype(this_ref.varialble); \ epee::serialization::selector::serialize(this_ref.varialble, stg, hparent_section, val_name); \ if constexpr (t_storage::use_descriptions::value) \ { \ - epee::serialization::selector::set_descr(this_ref.varialble, stg, hparent_section, val_name); \ + epee::serialization::selector::serialize_and_doc(stg, hparent_section, val_name + +/* + {using var_type = decltype(this_ref.varialble); \ + epee::serialization::selector::serialize(this_ref.varialble, stg, hparent_section, val_name); \ + if constexpr (t_storage::use_descriptions::value) \ + { \ + epee::serialization::selector::set_descr(stg, hparent_section, val_name, description, default = var_type()); \ } \ } - +*/ +#define DOC_DSCR(description) , description +#define DOC_EXMP(substitute) , substitute +#define DOC_EXMP_AUTO_1(arg_1) , var_type(arg_1) +#define DOC_EXMP_AUTO_2(arg_1, arg_2) , var_type(arg_1, arg_2) +#define DOC_END ); } } +#define DOC_EXMP_AUTO(...) epee::create_t_object(__VA_ARGS__) + + +// Function template to create an object with forwarded constructor arguments + template + T create_t_object(Args&&... args) { + return T(std::forward(args)...); + } + //substitute, description); -#define DOC_EXAMPLE(substitute) substitute, -#define DOC_EX(substitute__) var_type(substitute__), -#define DOC_DSCR(description) description); } +//#define DOC_EXAMPLE(substitute) substitute, +//#define DOC_EX(substitute__) var_type(substitute__), +//#define DOC_COMMAND(command_general_description) static const char* explain_yourseflf = command_general_description; #define KV_SERIALIZE_CUSTOM_N(varialble, stored_type, from_v_to_stored, from_stored_to_v, val_name) \ diff --git a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h index 7ca5dd98..bd4eb2fe 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h +++ b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h @@ -317,15 +317,26 @@ namespace epee template static bool serialize(const t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname) { - stg.set_entry_description(hparent_section, pname, description); - return kv_serialize( (doc_mode ? doc_substitute:d), stg, hparent_section, pname); + if constexpr (!t_storage::use_descriptions::value) + { + return kv_serialize(d, stg, hparent_section, pname); + } + else + return false; + } - //bool doc_mode = false, const t_type& doc_substitute = t_type(), const std::string& description = std::string() + //const t_type& doc_substitute = t_type(), const std::string& description = std::string() template - static bool set_descr(t_storage& stg, typename t_storage::hsection hparent_section, const char* pname, const std::string& description = std::string(), const t_type& doc_substitute = t_type()) + static bool serialize_and_doc(t_storage& stg, typename t_storage::hsection hparent_section, const char* pname, const std::string& description = std::string(), const t_type& doc_substitute = t_type()) { - stg.set_entry_description(hparent_section, pname, description); - return kv_serialize((doc_mode ? doc_substitute : d), stg, hparent_section, pname); + if constexpr (t_storage::use_descriptions::value) + { + stg.set_entry_description(hparent_section, pname, description); + return kv_serialize(doc_substitute, stg, hparent_section, pname); + } + else + return false; + } template diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 66b34896..4ad4d674 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -137,6 +137,9 @@ namespace currency struct COMMAND_RPC_GET_HEIGHT { + DOC_COMMAND("Return current blockchain height"); + + struct request { BEGIN_KV_SERIALIZE_MAP() @@ -149,8 +152,8 @@ namespace currency std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_DOC2(height) DOC_EX(11111) DOC_DSCR("Some height of the block") - KV_SERIALIZE_DOC2(status) DOC_EX("OK") DOC_DSCR("Status of the operation") + KV_SERIALIZE_DOC2(height) DOC_DSCR("Some height of the block") DOC_EXMP(11111) DOC_END + KV_SERIALIZE_DOC2(status) DOC_DSCR("Status of the operation") DOC_EXMP("OK") DOC_END END_KV_SERIALIZE_MAP() }; }; @@ -202,7 +205,6 @@ namespace currency END_KV_SERIALIZE_MAP() }; - struct response { std::list txs_as_hex; //transactions blobs as hex @@ -210,9 +212,9 @@ namespace currency std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_DOC(txs_as_hex, std::list(1, "97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc97d914497d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc2f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc"), "Transactions stored as blobs") - KV_SERIALIZE_DOC(missed_tx, std::list(1, "97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc"), "Missed transactions hashes") - KV_SERIALIZE_DOC(status, std::string("OK"), "Command response status") + KV_SERIALIZE_DOC2(txs_as_hex) DOC_DSCR("Transactions stored as blobs") DOC_EXMP_AUTO(1, "7d914497d91442f8f3c2268397d914497d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc2f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc") DOC_END + KV_SERIALIZE_DOC2(missed_tx) DOC_DSCR("Missed transactions hashes") DOC_EXMP_AUTO(1, "97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc") DOC_END + KV_SERIALIZE_DOC2(status) DOC_DSCR("Command response status") DOC_EXMP_AUTO("OK") DOC_END END_KV_SERIALIZE_MAP() }; }; From a2b28806b1096fd1cc28a11d9d6f2ba449223f42 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 28 Mar 2024 13:04:23 +0100 Subject: [PATCH 074/184] added struct documentation macro --- .../include/serialization/keyvalue_serialization.h | 11 +++-------- src/rpc/core_rpc_server_commands_defs.h | 10 +++++----- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/contrib/epee/include/serialization/keyvalue_serialization.h b/contrib/epee/include/serialization/keyvalue_serialization.h index e3a48a34..a7064b91 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization.h +++ b/contrib/epee/include/serialization/keyvalue_serialization.h @@ -68,10 +68,7 @@ public: \ #define KV_SERIALIZE_N(varialble, val_name) \ epee::serialization::selector::serialize(this_ref.varialble, stg, hparent_section, val_name); -#define KV_SERIALIZE_N_DOC(varialble, val_name, substitute, description) \ - epee::serialization::selector::serialize(this_ref.varialble, stg, hparent_section, val_name, auto_doc_mode, substitute, description); - -#define KV_SERIALIZE_N_DOC2(varialble, val_name) \ +#define KV_SERIALIZE_N_DOC(varialble, val_name) \ { using var_type = decltype(this_ref.varialble); \ epee::serialization::selector::serialize(this_ref.varialble, stg, hparent_section, val_name); \ if constexpr (t_storage::use_descriptions::value) \ @@ -140,11 +137,9 @@ public: \ #define END_KV_SERIALIZE_MAP() return true;} #define KV_SERIALIZE(varialble) KV_SERIALIZE_N(varialble, #varialble) -#define KV_SERIALIZE_DOC2(varialble) KV_SERIALIZE_N_DOC2( varialble, #varialble) -#define KV_SERIALIZE_DOC(varialble, substitute, description) KV_SERIALIZE_N_DOC( varialble, #varialble, substitute, description) - +#define KV_SERIALIZE_DOC(varialble) KV_SERIALIZE_N_DOC( varialble, #varialble) - //#define KV_SERIALIZE_DOC(varialble, substitute, description) KV_SERIALIZE_N_DOC( varialble, #varialble, substitute, description) +#define DOC_COMMAND(desciption_text) inline static const char* description; #define KV_SERIALIZE_VAL_POD_AS_BLOB(varialble) KV_SERIALIZE_VAL_POD_AS_BLOB_N(varialble, #varialble) diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 8895b9e7..f45128fc 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -152,8 +152,8 @@ namespace currency std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_DOC2(height) DOC_DSCR("Some height of the block") DOC_EXMP(11111) DOC_END - KV_SERIALIZE_DOC2(status) DOC_DSCR("Status of the operation") DOC_EXMP("OK") DOC_END + KV_SERIALIZE_DOC(height) DOC_DSCR("Some height of the block") DOC_EXMP(11111) DOC_END + KV_SERIALIZE_DOC(status) DOC_DSCR("Status of the operation") DOC_EXMP("OK") DOC_END END_KV_SERIALIZE_MAP() }; }; @@ -212,9 +212,9 @@ namespace currency std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_DOC2(txs_as_hex) DOC_DSCR("Transactions stored as blobs") DOC_EXMP_AUTO(1, "7d914497d91442f8f3c2268397d914497d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc2f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc") DOC_END - KV_SERIALIZE_DOC2(missed_tx) DOC_DSCR("Missed transactions hashes") DOC_EXMP_AUTO(1, "97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc") DOC_END - KV_SERIALIZE_DOC2(status) DOC_DSCR("Command response status") DOC_EXMP_AUTO("OK") DOC_END + KV_SERIALIZE_DOC(txs_as_hex) DOC_DSCR("Transactions stored as blobs") DOC_EXMP_AUTO(1, "7d914497d91442f8f3c2268397d914497d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc2f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc") DOC_END + KV_SERIALIZE_DOC(missed_tx) DOC_DSCR("Missed transactions hashes") DOC_EXMP_AUTO(1, "97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc") DOC_END + KV_SERIALIZE_DOC(status) DOC_DSCR("Command response status") DOC_EXMP_AUTO("OK") DOC_END END_KV_SERIALIZE_MAP() }; }; From d933a221540ca7d7a61903d8bad5c588684aba29 Mon Sep 17 00:00:00 2001 From: sowle Date: Thu, 28 Mar 2024 13:29:00 +0100 Subject: [PATCH 075/184] wallet: set_pos_utxo_count_limits_for_defragmentation_tx() added, coretests: packing_outputs_on_pos_minting_wallet, pos_minting_tx_packing fixed --- src/wallet/wallet2.cpp | 14 ++++++-------- src/wallet/wallet2.h | 3 +-- tests/core_tests/pos_validation.cpp | 2 +- tests/core_tests/wallet_tests.cpp | 12 ++++-------- 4 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 1264781e..b76b9717 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -174,15 +174,13 @@ bool wallet2::set_core_proxy(const std::shared_ptr& proxy) return true; } //---------------------------------------------------------------------------------------------------- -void wallet2::set_pos_utxo_count_limits_for_defragmentation_tx(uint64_t min_outs, uint64_t max_outs) +void wallet2::set_defragmentation_tx_settings(bool enabled, uint64_t min_outs, uint64_t max_outs, uint64_t max_allowed_amount, size_t decoys_count) { - m_min_utxo_count_for_defragmentation_tx = min_outs; - m_max_utxo_count_for_defragmentation_tx = max_outs; -} -//---------------------------------------------------------------------------------------------------- -void wallet2::set_pos_decoys_count_for_defragmentation_tx(size_t decoys_count) -{ - m_decoys_count_for_defragmentation_tx = decoys_count; + m_defragmentation_tx_enabled = enabled; + m_min_utxo_count_for_defragmentation_tx = min_outs; + m_max_utxo_count_for_defragmentation_tx = max_outs; + m_max_allowed_output_amount_for_defragmentation_tx = max_allowed_amount; + m_decoys_count_for_defragmentation_tx = decoys_count; } //---------------------------------------------------------------------------------------------------- std::shared_ptr wallet2::get_core_proxy() diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 05863a18..b0c55331 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -402,8 +402,7 @@ namespace tools bool daemon_get_asset_info(const crypto::public_key& asset_id, currency::asset_descriptor_base& adb); const std::unordered_map& get_own_assets() const { return m_own_asset_descriptors; } bool set_core_proxy(const std::shared_ptr& proxy); - void set_pos_utxo_count_limits_for_defragmentation_tx(uint64_t min_outs, uint64_t max_outs); // don't create UTXO defrag. tx if there are less than 'min_outs' outs; don't put more than 'max_outs' outs - void set_pos_decoys_count_for_defragmentation_tx(size_t decoys_count); + void set_defragmentation_tx_settings(bool enabled, uint64_t min_outs, uint64_t max_outs, uint64_t max_allowed_amount = CURRENCY_BLOCK_REWARD, size_t decoys_count = SIZE_MAX); void set_pos_required_decoys_count(size_t v) { m_required_decoys_count = v; } void set_minimum_height(uint64_t h); std::shared_ptr get_core_proxy(); diff --git a/tests/core_tests/pos_validation.cpp b/tests/core_tests/pos_validation.cpp index 0106b050..4f444e69 100644 --- a/tests/core_tests/pos_validation.cpp +++ b/tests/core_tests/pos_validation.cpp @@ -1085,7 +1085,7 @@ bool pos_minting_tx_packing::c1(currency::core& c, size_t ev_index, const std::v m_alice_start_amount + CURRENCY_BLOCK_REWARD * m_pos_mint_packing_size // unlocked ), false, ""); - alice_wlt->set_pos_utxo_count_limits_for_defragmentation_tx(m_pos_mint_packing_size + 1, m_pos_mint_packing_size + 1); // +1 because previous implementation () had an error with this limit + alice_wlt->set_defragmentation_tx_settings(true, m_pos_mint_packing_size + 1, m_pos_mint_packing_size + 1); // +1 because previous implementation () had an error with this limit // no coinbase tx outputs should be packed r = alice_wlt->try_mint_pos(); diff --git a/tests/core_tests/wallet_tests.cpp b/tests/core_tests/wallet_tests.cpp index 0be2a9bd..bfadc1fb 100644 --- a/tests/core_tests/wallet_tests.cpp +++ b/tests/core_tests/wallet_tests.cpp @@ -3440,8 +3440,7 @@ bool packing_outputs_on_pos_minting_wallet::c1(currency::core& c, size_t ev_inde // 1. Try to defragment the same UTXO that is used for staking // (Bob has two: one UTXO is for staking, other is being defragmented) - bob_wlt->set_pos_utxo_count_limits_for_defragmentation_tx(1, 10); - bob_wlt->set_pos_decoys_count_for_defragmentation_tx(0); + bob_wlt->set_defragmentation_tx_settings(true, 1, 10, CURRENCY_BLOCK_REWARD, 0); bob_wlt->try_mint_pos(); CHECK_AND_ASSERT_MES(c.get_current_blockchain_size() == CURRENCY_MINED_MONEY_UNLOCK_WINDOW * 2 + 3, false, "Incorrect blockchain height:" << c.get_current_blockchain_size()); @@ -3453,8 +3452,7 @@ bool packing_outputs_on_pos_minting_wallet::c1(currency::core& c, size_t ev_inde // 2. Try to mine a PoS block and defragment some of UTXO - alice_wlt->set_pos_utxo_count_limits_for_defragmentation_tx(2, 2); - alice_wlt->set_pos_decoys_count_for_defragmentation_tx(0); + alice_wlt->set_defragmentation_tx_settings(true, 2, 2, CURRENCY_BLOCK_REWARD, 0); alice_wlt->try_mint_pos(); CHECK_AND_ASSERT_MES(c.get_current_blockchain_size() == CURRENCY_MINED_MONEY_UNLOCK_WINDOW * 2 + 4, false, "Incorrect blockchain height:" << c.get_current_blockchain_size()); @@ -3467,8 +3465,7 @@ bool packing_outputs_on_pos_minting_wallet::c1(currency::core& c, size_t ev_inde // 3. Try to mine a PoS block and defragment with huge decoy set. Make sure block is mined successfully without a defragmentation tx // Alice has one UTXO - alice_wlt->set_pos_utxo_count_limits_for_defragmentation_tx(1, 1); - alice_wlt->set_pos_decoys_count_for_defragmentation_tx(80); + alice_wlt->set_defragmentation_tx_settings(true, 1, 1, CURRENCY_BLOCK_REWARD, 80); alice_wlt->try_mint_pos(); CHECK_AND_ASSERT_MES(c.get_current_blockchain_size() == CURRENCY_MINED_MONEY_UNLOCK_WINDOW * 2 + 5, false, "Incorrect blockchain height:" << c.get_current_blockchain_size()); @@ -3480,8 +3477,7 @@ bool packing_outputs_on_pos_minting_wallet::c1(currency::core& c, size_t ev_inde // 4. Finally mine a PoS and defragment the last one unlocked UTXO - alice_wlt->set_pos_utxo_count_limits_for_defragmentation_tx(1, 1); - alice_wlt->set_pos_decoys_count_for_defragmentation_tx(0); + alice_wlt->set_defragmentation_tx_settings(true, 1, 1, CURRENCY_BLOCK_REWARD, 0); alice_wlt->try_mint_pos(); CHECK_AND_ASSERT_MES(c.get_current_blockchain_size() == CURRENCY_MINED_MONEY_UNLOCK_WINDOW * 2 + 6, false, "Incorrect blockchain height:" << c.get_current_blockchain_size()); From 4d6aa1a4f9c555a2d2b6b0975af451d60a51f2ad Mon Sep 17 00:00:00 2001 From: sowle Date: Thu, 28 Mar 2024 13:32:26 +0100 Subject: [PATCH 076/184] wallet: minor fixes (logging) --- src/wallet/wallet2.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index b76b9717..5de4c730 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -428,7 +428,7 @@ void wallet2::process_ado_in_new_transaction(const currency::asset_descriptor_op << ENDL << "Ticker: " << asset_context.asset_descriptor.ticker << ENDL << "Total Max Supply: " << print_asset_money(asset_context.asset_descriptor.total_max_supply, asset_context.asset_descriptor.decimal_point) << ENDL << "Current Supply: " << print_asset_money(asset_context.asset_descriptor.current_supply, asset_context.asset_descriptor.decimal_point) - << ENDL << "Decimal Point: " << asset_context.asset_descriptor.decimal_point; + << ENDL << "Decimal Point: " << (int)asset_context.asset_descriptor.decimal_point; add_rollback_event(ptc.height, asset_register_event{ asset_id }); @@ -464,7 +464,7 @@ void wallet2::process_ado_in_new_transaction(const currency::asset_descriptor_op << ENDL << "Ticker: " << ado.descriptor.ticker << ENDL << "Total Max Supply: " << print_asset_money(ado.descriptor.total_max_supply, ado.descriptor.decimal_point) << ENDL << "Current Supply: " << print_asset_money(ado.descriptor.current_supply, ado.descriptor.decimal_point) - << ENDL << "Decimal Point: " << ado.descriptor.decimal_point; + << ENDL << "Decimal Point: " << (int)ado.descriptor.decimal_point; add_rollback_event(ptc.height, asset_register_event{ asset_id }); @@ -495,7 +495,7 @@ void wallet2::process_ado_in_new_transaction(const currency::asset_descriptor_op << ENDL << "Ticker: " << ado.descriptor.ticker << ENDL << "Total Max Supply: " << print_asset_money(ado.descriptor.total_max_supply, ado.descriptor.decimal_point) << ENDL << "Current Supply: " << print_asset_money(ado.descriptor.current_supply, ado.descriptor.decimal_point) - << ENDL << "Decimal Point: " << ado.descriptor.decimal_point; + << ENDL << "Decimal Point: " << (int)ado.descriptor.decimal_point; add_rollback_event(ptc.height, asset_register_event{ asset_id }); WLT_LOG_MAGENTA(ss.str(), LOG_LEVEL_0); From b8c97e3f70b9c78e38056b19ff7c3e57d4269c3b Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 28 Mar 2024 13:51:13 +0100 Subject: [PATCH 077/184] fixed broken build --- src/wallet/wallet2.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 05863a18..1509c620 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -159,7 +159,8 @@ namespace tools mutable uint64_t m_current_wallet_file_size = 0; bool m_use_assets_whitelisting = true; - + // variables that should be part of state data object but should not be stored during serialization + mutable std::atomic m_whitelist_updated = false; //=============================================================== template inline void serialize(t_archive &a, const unsigned int ver) @@ -400,7 +401,6 @@ namespace tools void transfer_asset_ownership(const crypto::public_key asset_id, const crypto::public_key& new_owner, currency::transaction& result_tx); bool daemon_get_asset_info(const crypto::public_key& asset_id, currency::asset_descriptor_base& adb); - const std::unordered_map& get_own_assets() const { return m_own_asset_descriptors; } bool set_core_proxy(const std::shared_ptr& proxy); void set_pos_utxo_count_limits_for_defragmentation_tx(uint64_t min_outs, uint64_t max_outs); // don't create UTXO defrag. tx if there are less than 'min_outs' outs; don't put more than 'max_outs' outs void set_pos_decoys_count_for_defragmentation_tx(size_t decoys_count); @@ -541,6 +541,7 @@ namespace tools void get_transfers(transfer_container& incoming_transfers) const; std::string get_transfers_str(bool include_spent = true, bool include_unspent = true, bool show_only_unknown = false, const std::string& filter_asset_ticker = std::string{}) const; std::string get_balance_str() const; + std::string get_balance_str_raw() const; // Returns all payments by given id in unspecified order void get_payments(const std::string& payment_id, std::list& payments, uint64_t min_height = 0) const; @@ -661,6 +662,10 @@ namespace tools bool add_custom_asset_id(const crypto::public_key& asset_id, currency::asset_descriptor_base& asset_descriptor); bool delete_custom_asset_id(const crypto::public_key& asset_id); + const std::unordered_map& get_local_whitelist() const; + const std::unordered_map& get_global_whitelist() const; + const std::unordered_map& get_own_assets() const; + bool load_whitelisted_tokens_if_not_loaded() const; bool load_whitelisted_tokens() const; @@ -697,6 +702,8 @@ namespace tools bool encrypt_buffer(const std::string& buff, std::string& res_buff); bool decrypt_buffer(const std::string& buff, std::string& res_buff); bool is_in_hardfork_zone(uint64_t hardfork_index) const; + //performance inefficient call, suitable only for rare ocasions or super lazy developers + bool proxy_to_daemon(const std::string& uri, const std::string& body, int& response_code, std::string& response_body); construct_tx_param get_default_construct_tx_param(); @@ -896,7 +903,6 @@ private: uint64_t m_upper_transaction_size_limit; //TODO: auto-calc this value or request from daemon, now use some fixed value std::atomic m_stop; - mutable std::atomic m_whitelist_updated = false; std::shared_ptr m_core_proxy; std::shared_ptr m_wcallback; From 312d500a36c0ccfc3e53b435efb2b46f11872ac3 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 28 Mar 2024 19:22:20 +0100 Subject: [PATCH 078/184] fixed problem with decoy selection algo --- src/wallet/wallet2.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 5de4c730..bac76141 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -6250,6 +6250,12 @@ void wallet2::select_decoys(currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS { out_entry entry = extract_random_from_container(amount_entry.outs); + // + if (entry.global_amount_index == own_g_index) + { + continue; + } + //skip auditable if ((entry.flags & (RANDOM_OUTPUTS_FOR_AMOUNTS_FLAGS_NOT_ALLOWED))) { @@ -6260,11 +6266,7 @@ void wallet2::select_decoys(currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS coinbases.push_back(entry); continue; } - // - if (entry.global_amount_index == own_g_index) - { - continue; - } + local_outs.push_back(entry); } From b00fb7671ef482b5256c4827e6f17d362043e119 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 28 Mar 2024 19:24:11 +0100 Subject: [PATCH 079/184] added few fixes to autodoc --- contrib/epee/include/net/http_server_handlers_map2.h | 4 ++-- contrib/epee/include/serialization/keyvalue_serialization.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/epee/include/net/http_server_handlers_map2.h b/contrib/epee/include/net/http_server_handlers_map2.h index b7ad8799..a8888983 100644 --- a/contrib/epee/include/net/http_server_handlers_map2.h +++ b/contrib/epee/include/net/http_server_handlers_map2.h @@ -51,7 +51,7 @@ bool auto_doc_t(const std::string& prefix_name, std::string& generate_reference) std::string req_str; std::string req_str_descr; epee::serialization::portable_storage_extended_doc ps; - req.store(ps, nullptr, true); + req.store(ps, nullptr); ps.dump_as_json(req_str); ps.dump_as_decriptions(req_str_descr); @@ -59,7 +59,7 @@ bool auto_doc_t(const std::string& prefix_name, std::string& generate_reference) std::string res_str; std::string res_str_descr; epee::serialization::portable_storage_extended_doc ps_res; - res.store(ps_res, nullptr, true); + res.store(ps_res, nullptr); ps_res.dump_as_json(res_str); ps_res.dump_as_decriptions(res_str_descr); diff --git a/contrib/epee/include/serialization/keyvalue_serialization.h b/contrib/epee/include/serialization/keyvalue_serialization.h index a7064b91..d47918cc 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization.h +++ b/contrib/epee/include/serialization/keyvalue_serialization.h @@ -92,7 +92,7 @@ public: \ -#define DOC_EXMP_AUTO(...) epee::create_t_object(__VA_ARGS__) +#define DOC_EXMP_AUTO(...) , epee::create_t_object(__VA_ARGS__) // Function template to create an object with forwarded constructor arguments From b0c92e28dd7f6b05b5b00f3563eb88f3db6caf5d Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 28 Mar 2024 21:19:57 +0100 Subject: [PATCH 080/184] added more logs for generate_unique_reversed_distribution --- src/wallet/decoy_selection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/decoy_selection.cpp b/src/wallet/decoy_selection.cpp index 7a3c8d01..e9d24446 100644 --- a/src/wallet/decoy_selection.cpp +++ b/src/wallet/decoy_selection.cpp @@ -89,7 +89,7 @@ void decoy_selection_generator::generate_unique_reversed_distribution(uint64_t c { if (count + set_to_extend.size() > m_max) { - throw std::runtime_error("generate_distribution_set with unexpected count"); + throw std::runtime_error(std::string("generate_distribution_set with unexpected count=") + std::to_string(count) + ", set_to_extend.size() = " + std::to_string(set_to_extend.size()) + ", m_max: " + std::to_string(m_max)); } size_t attempt_count = 0; From a45e42e0a54db72539557930209a29677252fdf5 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 29 Mar 2024 14:31:00 +0100 Subject: [PATCH 081/184] handle ethash epoch context allocation errors by triggering an immediate stop via the critical error handler --- src/currency_core/basic_pow_helpers.cpp | 6 +- src/currency_core/blockchain_storage.cpp | 7 +- src/currency_core/currency_core.cpp | 226 +++++++++++++---------- 3 files changed, 144 insertions(+), 95 deletions(-) diff --git a/src/currency_core/basic_pow_helpers.cpp b/src/currency_core/basic_pow_helpers.cpp index ddb87912..b7ee80ca 100644 --- a/src/currency_core/basic_pow_helpers.cpp +++ b/src/currency_core/basic_pow_helpers.cpp @@ -66,7 +66,11 @@ namespace currency init_ethash_log_if_necessary(); int epoch = ethash_height_to_epoch(height); std::shared_ptr p_context = progpow::get_global_epoch_context_full(static_cast(epoch)); - CHECK_AND_ASSERT_THROW_MES(p_context, "progpow::get_global_epoch_context_full returned null"); + if (!p_context) + { + LOG_ERROR("fatal error: get_global_epoch_context_full failed, throwing bad_alloc..."); + throw std::bad_alloc(); + } auto res_eth = progpow::hash(*p_context, static_cast(height), *(ethash::hash256*)&block_header_hash, nonce); crypto::hash result = currency::null_hash; memcpy(&result.data, &res_eth.final_hash, sizeof(res_eth.final_hash)); diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 0e6c923c..eb6d0fb3 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -6941,7 +6941,12 @@ bool blockchain_storage::add_new_block(const block& bl, block_verification_conte if (m_event_handler) m_event_handler->on_complete_events(); return res; - } + } + catch (const std::bad_alloc&) + { + // failed memory allocation is critical; this is supposed to be handled by the called (assuming immediate stop) + throw; + } catch (const std::exception& ex) { bvc.m_verification_failed = true; diff --git a/src/currency_core/currency_core.cpp b/src/currency_core/currency_core.cpp index 7658f4da..1c15498b 100644 --- a/src/currency_core/currency_core.cpp +++ b/src/currency_core/currency_core.cpp @@ -415,82 +415,102 @@ namespace currency //----------------------------------------------------------------------------------------------- bool core::handle_block_found(const block& b, block_verification_context* p_verification_result, bool need_update_miner_block_template) { - TIME_MEASURE_START_MS(time_total_ms); - block_verification_context bvc = boost::value_initialized(); - if (!p_verification_result) - p_verification_result = &bvc; - - m_miner.pause(); - misc_utils::auto_scope_leave_caller scope_exit_handler = misc_utils::create_scope_leave_handler([this]() + try { - m_miner.resume(); - }); + TIME_MEASURE_START_MS(time_total_ms); + block_verification_context bvc = boost::value_initialized(); + if (!p_verification_result) + p_verification_result = &bvc; - TIME_MEASURE_START_MS(time_add_new_block_ms); - m_blockchain_storage.add_new_block(b, *p_verification_result); - TIME_MEASURE_FINISH_MS(time_add_new_block_ms); - - - //anyway - update miner template - TIME_MEASURE_START_MS(time_update_block_template_ms); - if (need_update_miner_block_template) - update_miner_block_template(); - TIME_MEASURE_FINISH_MS(time_update_block_template_ms); - - uint64_t time_pack_txs_ms = 0, time_relay_ms = 0; - - if (p_verification_result->m_verification_failed || !p_verification_result->m_added_to_main_chain) - { - LOG_PRINT2("failed_mined_blocks.log", "verification_failed: " << p_verification_result->m_verification_failed << ", added_to_main_chain: " << p_verification_result->m_added_to_main_chain << ENDL << - currency::obj_to_json_str(b), LOG_LEVEL_0); - } - CHECK_AND_ASSERT_MES(!p_verification_result->m_verification_failed, false, "mined block has failed to pass verification: id " << get_block_hash(b) << " @ height " << get_block_height(b) << " prev_id: " << b.prev_id); - - if(p_verification_result->m_added_to_main_chain) - { - time_pack_txs_ms = epee::misc_utils::get_tick_count(); - currency_connection_context exclude_context = boost::value_initialized(); - NOTIFY_NEW_BLOCK::request arg = AUTO_VAL_INIT(arg); - arg.hop = 0; - arg.current_blockchain_height = m_blockchain_storage.get_current_blockchain_size(); - std::list missed_txs; - std::list txs; - m_blockchain_storage.get_transactions(b.tx_hashes, txs, missed_txs); - if(missed_txs.size() && m_blockchain_storage.get_block_id_by_height(get_block_height(b)) != get_block_hash(b)) + m_miner.pause(); + misc_utils::auto_scope_leave_caller scope_exit_handler = misc_utils::create_scope_leave_handler([this]() { - LOG_PRINT_L0("Block found (id " << get_block_hash(b) << " @ height " << get_block_height(b) << ") but it seems that reorganize just happened after that, do not relay this block"); - return true; + m_miner.resume(); + }); + + TIME_MEASURE_START_MS(time_add_new_block_ms); + m_blockchain_storage.add_new_block(b, *p_verification_result); + TIME_MEASURE_FINISH_MS(time_add_new_block_ms); + + + //anyway - update miner template + TIME_MEASURE_START_MS(time_update_block_template_ms); + if (need_update_miner_block_template) + update_miner_block_template(); + TIME_MEASURE_FINISH_MS(time_update_block_template_ms); + + uint64_t time_pack_txs_ms = 0, time_relay_ms = 0; + + if (p_verification_result->m_verification_failed || !p_verification_result->m_added_to_main_chain) + { + LOG_PRINT2("failed_mined_blocks.log", "verification_failed: " << p_verification_result->m_verification_failed << ", added_to_main_chain: " << p_verification_result->m_added_to_main_chain << ENDL << + currency::obj_to_json_str(b), LOG_LEVEL_0); } - if (txs.size() != b.tx_hashes.size() || missed_txs.size() != 0) + CHECK_AND_ASSERT_MES(!p_verification_result->m_verification_failed, false, "mined block has failed to pass verification: id " << get_block_hash(b) << " @ height " << get_block_height(b) << " prev_id: " << b.prev_id); + + if(p_verification_result->m_added_to_main_chain) { - std::stringstream ss; - ss << "txs:" << ENDL; - for (auto& t : txs) - ss << get_transaction_hash(t) << ENDL; - ss << "missed txs:" << ENDL; - for (auto& tx_id : missed_txs) - ss << tx_id << ENDL; - LOG_ERROR("can't find some transactions in found block: " << get_block_hash(b) << ", txs.size()=" << txs.size() - << ", b.tx_hashes.size()=" << b.tx_hashes.size() << ", missed_txs.size()=" << missed_txs.size() << ENDL << ss.str()); - return false; + time_pack_txs_ms = epee::misc_utils::get_tick_count(); + currency_connection_context exclude_context = boost::value_initialized(); + NOTIFY_NEW_BLOCK::request arg = AUTO_VAL_INIT(arg); + arg.hop = 0; + arg.current_blockchain_height = m_blockchain_storage.get_current_blockchain_size(); + std::list missed_txs; + std::list txs; + m_blockchain_storage.get_transactions(b.tx_hashes, txs, missed_txs); + if(missed_txs.size() && m_blockchain_storage.get_block_id_by_height(get_block_height(b)) != get_block_hash(b)) + { + LOG_PRINT_L0("Block found (id " << get_block_hash(b) << " @ height " << get_block_height(b) << ") but it seems that reorganize just happened after that, do not relay this block"); + return true; + } + if (txs.size() != b.tx_hashes.size() || missed_txs.size() != 0) + { + std::stringstream ss; + ss << "txs:" << ENDL; + for (auto& t : txs) + ss << get_transaction_hash(t) << ENDL; + ss << "missed txs:" << ENDL; + for (auto& tx_id : missed_txs) + ss << tx_id << ENDL; + LOG_ERROR("can't find some transactions in found block: " << get_block_hash(b) << ", txs.size()=" << txs.size() + << ", b.tx_hashes.size()=" << b.tx_hashes.size() << ", missed_txs.size()=" << missed_txs.size() << ENDL << ss.str()); + return false; + } + + block_to_blob(b, arg.b.block); + //pack transactions + for(auto& tx : txs) + arg.b.txs.push_back(t_serializable_object_to_blob(tx)); + + TIME_MEASURE_FINISH_MS(time_pack_txs_ms); + + time_relay_ms = epee::misc_utils::get_tick_count(); + m_pprotocol->relay_block(arg, exclude_context); + TIME_MEASURE_FINISH_MS(time_relay_ms); } - block_to_blob(b, arg.b.block); - //pack transactions - for(auto& tx : txs) - arg.b.txs.push_back(t_serializable_object_to_blob(tx)); + TIME_MEASURE_FINISH_MS(time_total_ms); + LOG_PRINT_L2("handle_block_found timings (ms): total: " << time_total_ms << ", add new block: " << time_add_new_block_ms << ", update template: " << time_update_block_template_ms << ", pack txs: " << time_pack_txs_ms << ", relay: " << time_relay_ms); - TIME_MEASURE_FINISH_MS(time_pack_txs_ms); - - time_relay_ms = epee::misc_utils::get_tick_count(); - m_pprotocol->relay_block(arg, exclude_context); - TIME_MEASURE_FINISH_MS(time_relay_ms); + return p_verification_result->m_added_to_main_chain; + } + catch(std::bad_alloc&) + { + LOG_ERROR("bad_alloc in core::handle_block_found(), requesting immediate stop..."); + if (m_critical_error_handler) + m_critical_error_handler->on_immediate_stop_requested(); + return false; + } + catch(std::exception& e) + { + LOG_ERROR("caught exception in core::handle_block_found(): " << e.what()); + return false; + } + catch(...) + { + LOG_ERROR("caught unknown exception in core::handle_block_found()"); + return false; } - - TIME_MEASURE_FINISH_MS(time_total_ms); - LOG_PRINT_L2("handle_block_found timings (ms): total: " << time_total_ms << ", add new block: " << time_add_new_block_ms << ", update template: " << time_update_block_template_ms << ", pack txs: " << time_pack_txs_ms << ", relay: " << time_relay_ms); - - return p_verification_result->m_added_to_main_chain; } //----------------------------------------------------------------------------------------------- bool core::handle_block_found(const block& b, block_verification_context* p_verification_result /* = nullptr */) @@ -509,39 +529,59 @@ namespace currency //----------------------------------------------------------------------------------------------- bool core::add_new_block(const block& b, block_verification_context& bvc) { - uint64_t h = m_blockchain_storage.get_top_block_height(); - if (m_stop_after_height != 0 && h >= m_stop_after_height) + try { - LOG_PRINT_YELLOW("Blockchain top block height is " << h << ", the daemon will now stop as requested", LOG_LEVEL_0); - if (m_critical_error_handler) - return m_critical_error_handler->on_immediate_stop_requested(); - return false; - } - - bool r = m_blockchain_storage.add_new_block(b, bvc); - if (r && bvc.m_added_to_main_chain) - { - uint64_t h = get_block_height(b); - if (h > 0) + uint64_t h = m_blockchain_storage.get_top_block_height(); + if (m_stop_after_height != 0 && h >= m_stop_after_height) { - auto& crc = m_blockchain_storage.get_core_runtime_config(); - size_t hardfork_id_for_prev_block = crc.hard_forks.get_the_most_recent_hardfork_id_for_height(h); - size_t hardfork_id_for_curr_block = crc.hard_forks.get_the_most_recent_hardfork_id_for_height(h + 1); - if (hardfork_id_for_prev_block != hardfork_id_for_curr_block) - { - LOG_PRINT_GREEN("Hardfork " << hardfork_id_for_curr_block << " has been activated after the block at height " << h, LOG_LEVEL_0); - } - } - - if (h == m_stop_after_height) - { - LOG_PRINT_YELLOW("Reached block " << h << ", the daemon will now stop as requested", LOG_LEVEL_0); + LOG_PRINT_YELLOW("Blockchain top block height is " << h << ", the daemon will now stop as requested", LOG_LEVEL_0); if (m_critical_error_handler) return m_critical_error_handler->on_immediate_stop_requested(); return false; } + + bool r = m_blockchain_storage.add_new_block(b, bvc); + if (r && bvc.m_added_to_main_chain) + { + uint64_t h = get_block_height(b); + if (h > 0) + { + auto& crc = m_blockchain_storage.get_core_runtime_config(); + size_t hardfork_id_for_prev_block = crc.hard_forks.get_the_most_recent_hardfork_id_for_height(h); + size_t hardfork_id_for_curr_block = crc.hard_forks.get_the_most_recent_hardfork_id_for_height(h + 1); + if (hardfork_id_for_prev_block != hardfork_id_for_curr_block) + { + LOG_PRINT_GREEN("Hardfork " << hardfork_id_for_curr_block << " has been activated after the block at height " << h, LOG_LEVEL_0); + } + } + + if (h == m_stop_after_height) + { + LOG_PRINT_YELLOW("Reached block " << h << ", the daemon will now stop as requested", LOG_LEVEL_0); + if (m_critical_error_handler) + return m_critical_error_handler->on_immediate_stop_requested(); + return false; + } + } + return r; + } + catch(std::bad_alloc&) + { + LOG_ERROR("bad_alloc in core::add_new_block(), requesting immediate stop..."); + if (m_critical_error_handler) + m_critical_error_handler->on_immediate_stop_requested(); + return false; + } + catch(std::exception& e) + { + LOG_ERROR("caught exception in core::add_new_block(): " << e.what()); + return false; + } + catch(...) + { + LOG_ERROR("caught unknown exception in core::add_new_block()"); + return false; } - return r; } //----------------------------------------------------------------------------------------------- bool core::parse_block(const blobdata& block_blob, block& b, block_verification_context& bvc) From 01c60fa07ed135f69e2d4387dc6ba4c5ac2e4d82 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 29 Mar 2024 15:53:51 +0100 Subject: [PATCH 082/184] simplewallet: --pos-mining-defrag CLI option added --- src/currency_core/currency_format_utils.cpp | 1 + src/simplewallet/simplewallet.cpp | 68 ++++++++++++++------- src/wallet/wallet2.cpp | 10 ++- 3 files changed, 52 insertions(+), 27 deletions(-) diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 8eb17e2d..32b43656 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -756,6 +756,7 @@ namespace currency } } //--------------------------------------------------------------- + // TODO: reverse order of arguments bool parse_amount(uint64_t& amount, const std::string& str_amount_) { std::string str_amount = str_amount_; diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index ed51ef76..7bdb3ef7 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2023 Zano Project +// Copyright (c) 2014-2024 Zano Project // Copyright (c) 2014-2018 The Louisdor Project // Copyright (c) 2012-2013 The Cryptonote developers // Distributed under the MIT/X11 software license, see the accompanying @@ -118,29 +118,32 @@ namespace ph = boost::placeholders; #define CONFIRM_WITH_PASSWORD() if(!check_password_for_operation()) return true; +#define DEFAULT_WALLET_MIN_UTXO_COUNT_FOR_DEFRAGMENTATION_TX 3 +#define DEFAULT_WALLET_MAX_UTXO_COUNT_FOR_DEFRAGMENTATION_TX 10 + namespace { - const command_line::arg_descriptor arg_wallet_file ("wallet-file", "Use wallet ", ""); - const command_line::arg_descriptor arg_generate_new_wallet ("generate-new-wallet", "Generate new wallet and save it to or
.wallet by default", ""); - const command_line::arg_descriptor arg_generate_new_auditable_wallet ("generate-new-auditable-wallet", "Generate new auditable wallet and store it to ", ""); - const command_line::arg_descriptor arg_daemon_address ("daemon-address", "Use daemon instance at :", ""); - const command_line::arg_descriptor arg_daemon_host ("daemon-host", "Use daemon instance at host instead of localhost", ""); - const command_line::arg_descriptor arg_password ("password", "Wallet password"); - const command_line::arg_descriptor arg_dont_refresh ( "no-refresh", "Do not refresh after load"); - const command_line::arg_descriptor arg_dont_set_date ( "no-set-creation-date", "Do not set wallet creation date", false); - const command_line::arg_descriptor arg_daemon_port ("daemon-port", "Use daemon instance at port instead of default", 0); - //const command_line::arg_descriptor arg_log_level ("set-log", ""); - const command_line::arg_descriptor arg_do_pos_mining ( "do-pos-mining", "Do PoS mining", false); - const command_line::arg_descriptor arg_pos_mining_reward_address ( "pos-mining-reward-address", "Block reward will be sent to the giving address if specified", "" ); - const command_line::arg_descriptor arg_restore_wallet ( "restore-wallet", "Restore wallet from seed phrase or tracking seed and save it to ", "" ); - const command_line::arg_descriptor arg_offline_mode ( "offline-mode", "Don't connect to daemon, work offline (for cold-signing process)"); - const command_line::arg_descriptor arg_scan_for_wallet ( "scan-for-wallet", ""); - const command_line::arg_descriptor arg_addr_to_compare ( "addr-to-compare", ""); - const command_line::arg_descriptor arg_disable_tor_relay ( "disable-tor-relay", "Disable TOR relay", false); - const command_line::arg_descriptor arg_set_timeout("set-timeout", "Set timeout for the wallet"); - const command_line::arg_descriptor arg_voting_config_file("voting-config-file", "Set voting config instead of getting if from daemon", ""); - const command_line::arg_descriptor arg_no_password_confirmations("no-password-confirmation", "Enable/Disable password confirmation for transactions", false); + const command_line::arg_descriptor arg_wallet_file ("wallet-file", "Use wallet ", ""); + const command_line::arg_descriptor arg_generate_new_wallet ("generate-new-wallet", "Generate new wallet and save it to or
.wallet by default", ""); + const command_line::arg_descriptor arg_generate_new_auditable_wallet ("generate-new-auditable-wallet", "Generate new auditable wallet and store it to ", ""); + const command_line::arg_descriptor arg_daemon_address ("daemon-address", "Use daemon instance at :", ""); + const command_line::arg_descriptor arg_daemon_host ("daemon-host", "Use daemon instance at host instead of localhost", ""); + const command_line::arg_descriptor arg_password ("password", "Wallet password"); + const command_line::arg_descriptor arg_dont_refresh ( "no-refresh", "Do not refresh after load"); + const command_line::arg_descriptor arg_dont_set_date ( "no-set-creation-date", "Do not set wallet creation date", false); + const command_line::arg_descriptor arg_daemon_port ("daemon-port", "Use daemon instance at port instead of default", 0); + const command_line::arg_descriptor arg_do_pos_mining ( "do-pos-mining", "Do PoS mining", false); + const command_line::arg_descriptor arg_pos_mining_reward_address ( "pos-mining-reward-address", "Block reward will be sent to the giving address if specified", "" ); + const command_line::arg_descriptor arg_pos_mining_defrag ( "pos-mining-defrag", " Generate defragmentation tx for small outputs each time a PoS block is found. Default params: " STR(DEFAULT_WALLET_MIN_UTXO_COUNT_FOR_DEFRAGMENTATION_TX) "," STR(DEFAULT_WALLET_MAX_UTXO_COUNT_FOR_DEFRAGMENTATION_TX) ",1.0", "" ); + const command_line::arg_descriptor arg_restore_wallet ( "restore-wallet", "Restore wallet from seed phrase or tracking seed and save it to ", "" ); + const command_line::arg_descriptor arg_offline_mode ( "offline-mode", "Don't connect to daemon, work offline (for cold-signing process)"); + const command_line::arg_descriptor arg_scan_for_wallet ( "scan-for-wallet", ""); + const command_line::arg_descriptor arg_addr_to_compare ( "addr-to-compare", ""); + const command_line::arg_descriptor arg_disable_tor_relay ( "disable-tor-relay", "Disable TOR relay", false); + const command_line::arg_descriptor arg_set_timeout("set-timeout", "Set timeout for the wallet"); + const command_line::arg_descriptor arg_voting_config_file("voting-config-file", "Set voting config instead of getting if from daemon", ""); + const command_line::arg_descriptor arg_no_password_confirmations("no-password-confirmation", "Enable/Disable password confirmation for transactions", false); const command_line::arg_descriptor< std::vector > arg_command ("command", ""); @@ -2665,6 +2668,7 @@ int main(int argc, char* argv[]) command_line::add_arg(desc_params, arg_dont_set_date); command_line::add_arg(desc_params, arg_do_pos_mining); command_line::add_arg(desc_params, arg_pos_mining_reward_address); + command_line::add_arg(desc_params, arg_pos_mining_defrag); command_line::add_arg(desc_params, arg_restore_wallet); command_line::add_arg(desc_params, arg_offline_mode); command_line::add_arg(desc_params, command_line::arg_log_file); @@ -2850,6 +2854,28 @@ int main(int argc, char* argv[]) LOG_PRINT_YELLOW("PoS reward will be sent to another address: " << arg_pos_mining_reward_address_str, LOG_LEVEL_0); } } + + if (command_line::has_arg(vm, arg_pos_mining_defrag)) + { + std::string arg_pos_mining_defrag_str = command_line::get_arg(vm, arg_pos_mining_defrag); + if (arg_pos_mining_defrag_str.empty()) + { + // enable with default params + wal.set_defragmentation_tx_settings(true, DEFAULT_WALLET_MIN_UTXO_COUNT_FOR_DEFRAGMENTATION_TX, DEFAULT_WALLET_MAX_UTXO_COUNT_FOR_DEFRAGMENTATION_TX, COIN); + } + else + { + std::vector params; + boost::split(params, arg_pos_mining_defrag_str, boost::is_any_of(",;"), boost::token_compress_on); + CHECK_AND_ASSERT_MES(params.size() != 3, EXIT_FAILURE, "incorrect number of params given: " << arg_pos_mining_defrag_str); + int64_t outs_min = 0, outs_max = 0; + uint64_t max_amount = 0; + CHECK_AND_ASSERT_MES(epee::string_tools::string_to_num_fast(params[0], outs_min) && outs_min > 0 && outs_min < 256, EXIT_FAILURE, "incorrect param: " << params[0]); + CHECK_AND_ASSERT_MES(epee::string_tools::string_to_num_fast(params[1], outs_max) && outs_max > 0 && outs_max < 256, EXIT_FAILURE, "incorrect param: " << params[1]); + CHECK_AND_ASSERT_MES(currency::parse_amount(max_amount, params[2]), EXIT_FAILURE, "incorrect param: " << params[2]); + wal.set_defragmentation_tx_settings(true, outs_min, outs_max, max_amount); + } + } diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index bac76141..0cadb402 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -56,10 +56,6 @@ using namespace currency; #define MINIMUM_REQUIRED_WALLET_FREE_SPACE_BYTES (100*1024*1024) // 100 MB -#define WALLET_DEFAULT_DECOYS_COUNT_FOR_DEFRAGMENTATION_TX 10 // TODO @#@# change to default decoy set number -#define WALLET_MIN_UTXO_COUNT_FOR_DEFRAGMENTATION_TX 3 // TODO: @#@# consider descreasing to mimic normal tx -#define WALLET_MAX_UTXO_COUNT_FOR_DEFRAGMENTATION_TX 10 // TODO: @#@# consider descreasing to mimic normal tx - #define WALLET_TX_MAX_ALLOWED_FEE (COIN * 100) #define WALLET_FETCH_RANDOM_OUTS_SIZE 200 @@ -83,8 +79,8 @@ namespace tools , m_required_decoys_count(CURRENCY_DEFAULT_DECOY_SET_SIZE) , m_defragmentation_tx_enabled(false) , m_max_allowed_output_amount_for_defragmentation_tx(CURRENCY_BLOCK_REWARD) - , m_min_utxo_count_for_defragmentation_tx(WALLET_MIN_UTXO_COUNT_FOR_DEFRAGMENTATION_TX) - , m_max_utxo_count_for_defragmentation_tx(WALLET_MAX_UTXO_COUNT_FOR_DEFRAGMENTATION_TX) + , m_min_utxo_count_for_defragmentation_tx(0) + , m_max_utxo_count_for_defragmentation_tx(0) , m_decoys_count_for_defragmentation_tx(SIZE_MAX) , m_use_deffered_global_outputs(false) #ifdef DISABLE_TOR @@ -181,6 +177,8 @@ void wallet2::set_defragmentation_tx_settings(bool enabled, uint64_t min_outs, u m_max_utxo_count_for_defragmentation_tx = max_outs; m_max_allowed_output_amount_for_defragmentation_tx = max_allowed_amount; m_decoys_count_for_defragmentation_tx = decoys_count; + WLT_LOG_L0("Defragmentation tx creation is enabled, settings: min outs: " << min_outs << ", max outs: " << max_outs << ", max amount: " << print_money_brief(max_allowed_amount) << + ", decoys: " << (decoys_count != SIZE_MAX ? epee::string_tools::num_to_string_fast(decoys_count) : std::string("default"))); } //---------------------------------------------------------------------------------------------------- std::shared_ptr wallet2::get_core_proxy() From 950c80a108261afa976a50cdc61b6e53abf47905 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Fri, 29 Mar 2024 17:54:22 +0300 Subject: [PATCH 083/184] === build number: 290 -> 291 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index fc6d8a54..1a64a14d 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 290 +#define PROJECT_VERSION_BUILD_NO 291 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From 16be157addfb86a79f846633bb60f43014bf6e63 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 29 Mar 2024 16:31:12 +0100 Subject: [PATCH 084/184] simplewallet: fixed typo + logs --- src/simplewallet/simplewallet.cpp | 2 +- src/wallet/wallet2.cpp | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 7bdb3ef7..97418e35 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -2867,7 +2867,7 @@ int main(int argc, char* argv[]) { std::vector params; boost::split(params, arg_pos_mining_defrag_str, boost::is_any_of(",;"), boost::token_compress_on); - CHECK_AND_ASSERT_MES(params.size() != 3, EXIT_FAILURE, "incorrect number of params given: " << arg_pos_mining_defrag_str); + CHECK_AND_ASSERT_MES(params.size() == 3, EXIT_FAILURE, "incorrect number of params given: " << arg_pos_mining_defrag_str); int64_t outs_min = 0, outs_max = 0; uint64_t max_amount = 0; CHECK_AND_ASSERT_MES(epee::string_tools::string_to_num_fast(params[0], outs_min) && outs_min > 0 && outs_min < 256, EXIT_FAILURE, "incorrect param: " << params[0]); diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 0cadb402..fe7efa42 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -177,8 +177,15 @@ void wallet2::set_defragmentation_tx_settings(bool enabled, uint64_t min_outs, u m_max_utxo_count_for_defragmentation_tx = max_outs; m_max_allowed_output_amount_for_defragmentation_tx = max_allowed_amount; m_decoys_count_for_defragmentation_tx = decoys_count; - WLT_LOG_L0("Defragmentation tx creation is enabled, settings: min outs: " << min_outs << ", max outs: " << max_outs << ", max amount: " << print_money_brief(max_allowed_amount) << - ", decoys: " << (decoys_count != SIZE_MAX ? epee::string_tools::num_to_string_fast(decoys_count) : std::string("default"))); + if (enabled) + { + WLT_LOG_L0("Defragmentation tx creation is enabled, settings: min outs: " << min_outs << ", max outs: " << max_outs << ", max amount: " << print_money_brief(max_allowed_amount) << + ", decoys: " << (decoys_count != SIZE_MAX ? epee::string_tools::num_to_string_fast(decoys_count) : std::string("default"))); + } + else + { + WLT_LOG_L0("Defragmentation tx creation is disabled"); + } } //---------------------------------------------------------------------------------------------------- std::shared_ptr wallet2::get_core_proxy() From c375d6fa1050d03c941291a11b5cde354862dd5d Mon Sep 17 00:00:00 2001 From: zano build machine Date: Fri, 29 Mar 2024 18:31:42 +0300 Subject: [PATCH 085/184] === build number: 291 -> 292 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index 1a64a14d..3a89fbcd 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 291 +#define PROJECT_VERSION_BUILD_NO 292 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From c552916266f419061f6a293e5bf30d3ddab77dd2 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Fri, 29 Mar 2024 18:54:04 +0100 Subject: [PATCH 086/184] fix for mobile android build --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 31c80a7a..c9340683 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -233,6 +233,8 @@ if(CMAKE_SYSTEM_NAME STREQUAL "iOS") elseif(CMAKE_SYSTEM_NAME STREQUAL "Android") set(Boost_LIBRARY_DIRS "${Boost_LIBRARY_DIRS}/${CMAKE_ANDROID_ARCH_ABI}/") set(Boost_LIBRARIES "${Boost_LIBRARY_DIRS}libboost_system.a;${Boost_LIBRARY_DIRS}libboost_filesystem.a;${Boost_LIBRARY_DIRS}libboost_thread.a;${Boost_LIBRARY_DIRS}libboost_timer.a;${Boost_LIBRARY_DIRS}libboost_date_time.a;${Boost_LIBRARY_DIRS}libboost_chrono.a;${Boost_LIBRARY_DIRS}libboost_regex.a;${Boost_LIBRARY_DIRS}libboost_serialization.a;${Boost_LIBRARY_DIRS}libboost_atomic.a;${Boost_LIBRARY_DIRS}libboost_program_options.a") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fPIC") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fPIC") elseif(APPLE) find_package(Boost 1.71 REQUIRED COMPONENTS system filesystem thread timer date_time chrono regex serialization atomic program_options locale) else() From f2d63512118a49e80bf0971a8dbbafb87b1824de Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 29 Mar 2024 20:34:03 +0100 Subject: [PATCH 087/184] simplewallet: minor improvements --- src/simplewallet/simplewallet.cpp | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 97418e35..24a2053f 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -135,7 +135,7 @@ namespace const command_line::arg_descriptor arg_daemon_port ("daemon-port", "Use daemon instance at port instead of default", 0); const command_line::arg_descriptor arg_do_pos_mining ( "do-pos-mining", "Do PoS mining", false); const command_line::arg_descriptor arg_pos_mining_reward_address ( "pos-mining-reward-address", "Block reward will be sent to the giving address if specified", "" ); - const command_line::arg_descriptor arg_pos_mining_defrag ( "pos-mining-defrag", " Generate defragmentation tx for small outputs each time a PoS block is found. Default params: " STR(DEFAULT_WALLET_MIN_UTXO_COUNT_FOR_DEFRAGMENTATION_TX) "," STR(DEFAULT_WALLET_MAX_UTXO_COUNT_FOR_DEFRAGMENTATION_TX) ",1.0", "" ); + const command_line::arg_descriptor arg_pos_mining_defrag ( "pos-mining-defrag", ",,|disable Generate defragmentation tx for small outputs each time a PoS block is found. Disabled by default. If empty string given, the default params used: " STR(DEFAULT_WALLET_MIN_UTXO_COUNT_FOR_DEFRAGMENTATION_TX) "," STR(DEFAULT_WALLET_MAX_UTXO_COUNT_FOR_DEFRAGMENTATION_TX) ",1.0", "disable" ); const command_line::arg_descriptor arg_restore_wallet ( "restore-wallet", "Restore wallet from seed phrase or tracking seed and save it to ", "" ); const command_line::arg_descriptor arg_offline_mode ( "offline-mode", "Don't connect to daemon, work offline (for cold-signing process)"); const command_line::arg_descriptor arg_scan_for_wallet ( "scan-for-wallet", ""); @@ -2654,7 +2654,7 @@ int main(int argc, char* argv[]) command_line::add_arg(desc_general, command_line::arg_help); command_line::add_arg(desc_general, command_line::arg_version); - po::options_description desc_params("Wallet options"); + po::options_description desc_params("Wallet options", 160); command_line::add_arg(desc_params, arg_wallet_file); command_line::add_arg(desc_params, arg_generate_new_wallet); command_line::add_arg(desc_params, arg_generate_new_auditable_wallet); @@ -2725,7 +2725,7 @@ int main(int argc, char* argv[]) std::string log_dir; log_dir = log_file_path.has_parent_path() ? log_file_path.parent_path().string() : log_space::log_singletone::get_default_log_folder(); log_space::log_singletone::add_logger(LOGGER_FILE, log_file_path.filename().string().c_str(), log_dir.c_str(), LOG_LEVEL_4); - message_writer(epee::log_space::console_color_white, true) << CURRENCY_NAME << " wallet v" << PROJECT_VERSION_LONG; + message_writer(epee::log_space::console_color_white, true, std::string(), LOG_LEVEL_0) << CURRENCY_NAME << " simplewallet v" << PROJECT_VERSION_LONG; if (command_line::has_arg(vm, command_line::arg_log_level)) { @@ -2865,15 +2865,18 @@ int main(int argc, char* argv[]) } else { - std::vector params; - boost::split(params, arg_pos_mining_defrag_str, boost::is_any_of(",;"), boost::token_compress_on); - CHECK_AND_ASSERT_MES(params.size() == 3, EXIT_FAILURE, "incorrect number of params given: " << arg_pos_mining_defrag_str); - int64_t outs_min = 0, outs_max = 0; - uint64_t max_amount = 0; - CHECK_AND_ASSERT_MES(epee::string_tools::string_to_num_fast(params[0], outs_min) && outs_min > 0 && outs_min < 256, EXIT_FAILURE, "incorrect param: " << params[0]); - CHECK_AND_ASSERT_MES(epee::string_tools::string_to_num_fast(params[1], outs_max) && outs_max > 0 && outs_max < 256, EXIT_FAILURE, "incorrect param: " << params[1]); - CHECK_AND_ASSERT_MES(currency::parse_amount(max_amount, params[2]), EXIT_FAILURE, "incorrect param: " << params[2]); - wal.set_defragmentation_tx_settings(true, outs_min, outs_max, max_amount); + if (arg_pos_mining_defrag_str != "disable") + { + std::vector params; + boost::split(params, arg_pos_mining_defrag_str, boost::is_any_of(",;"), boost::token_compress_on); + CHECK_AND_ASSERT_MES(params.size() == 3, EXIT_FAILURE, "incorrect number of params given: " << arg_pos_mining_defrag_str); + int64_t outs_min = 0, outs_max = 0; + uint64_t max_amount = 0; + CHECK_AND_ASSERT_MES(epee::string_tools::string_to_num_fast(params[0], outs_min) && outs_min > 0 && outs_min < 256, EXIT_FAILURE, "incorrect param: " << params[0]); + CHECK_AND_ASSERT_MES(epee::string_tools::string_to_num_fast(params[1], outs_max) && outs_max > 0 && outs_max < 256, EXIT_FAILURE, "incorrect param: " << params[1]); + CHECK_AND_ASSERT_MES(currency::parse_amount(max_amount, params[2]), EXIT_FAILURE, "incorrect param: " << params[2]); + wal.set_defragmentation_tx_settings(true, outs_min, outs_max, max_amount); + } } } From 23d2b93506c706fb98d4f036bbe5d7cba3e9a4e8 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Fri, 29 Mar 2024 22:42:10 +0300 Subject: [PATCH 088/184] === build number: 292 -> 293 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index 3a89fbcd..0c4a9f38 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 292 +#define PROJECT_VERSION_BUILD_NO 293 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From 5053bc9a6dae3990bd84e87d22bd71f649ff502b Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 1 Apr 2024 14:11:07 +0200 Subject: [PATCH 089/184] ui update --- src/gui/qt-daemon/layout | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/qt-daemon/layout b/src/gui/qt-daemon/layout index f8e9556f..49aaf057 160000 --- a/src/gui/qt-daemon/layout +++ b/src/gui/qt-daemon/layout @@ -1 +1 @@ -Subproject commit f8e9556fbaccd49841ce91afc3c90c8e3142ac95 +Subproject commit 49aaf057dcea6c28f7eb6cd63f25d2d14fde8a3e From aab28aea8cd6322c30b6ae45619a36c35d80b979 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Mon, 1 Apr 2024 15:15:20 +0300 Subject: [PATCH 090/184] === build number: 293 -> 294 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index 0c4a9f38..72eaf612 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 293 +#define PROJECT_VERSION_BUILD_NO 294 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From 097420a66fa132a3da983585749dca85f66109fc Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 1 Apr 2024 15:32:00 +0200 Subject: [PATCH 091/184] wallet2: is_transfer_ready_to_go, is_transfer_able_to_go made const --- src/wallet/wallet2.cpp | 4 ++-- src/wallet/wallet2.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index fe7efa42..5b09b36d 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -6777,7 +6777,7 @@ uint64_t wallet2::select_indices_for_transfer(std::vector& selected_in return found_money; } //---------------------------------------------------------------------------------------------------- -bool wallet2::is_transfer_ready_to_go(const transfer_details& td, uint64_t fake_outputs_count) +bool wallet2::is_transfer_ready_to_go(const transfer_details& td, uint64_t fake_outputs_count) const { if (is_transfer_able_to_go(td, fake_outputs_count) && is_transfer_unlocked(td)) { @@ -6786,7 +6786,7 @@ bool wallet2::is_transfer_ready_to_go(const transfer_details& td, uint64_t fake_ return false; } //---------------------------------------------------------------------------------------------------- -bool wallet2::is_transfer_able_to_go(const transfer_details& td, uint64_t fake_outputs_count) +bool wallet2::is_transfer_able_to_go(const transfer_details& td, uint64_t fake_outputs_count) const { if (!td.is_spendable()) return false; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index b0c55331..c5c0022d 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -576,8 +576,8 @@ namespace tools wallet2_base_state::serialize(a, ver); } - bool is_transfer_ready_to_go(const transfer_details& td, uint64_t fake_outputs_count); - bool is_transfer_able_to_go(const transfer_details& td, uint64_t fake_outputs_count); + bool is_transfer_ready_to_go(const transfer_details& td, uint64_t fake_outputs_count) const; + bool is_transfer_able_to_go(const transfer_details& td, uint64_t fake_outputs_count) const; uint64_t select_indices_for_transfer(std::vector& ind, free_amounts_cache_type& found_free_amounts, uint64_t needed_money, uint64_t fake_outputs_count); bool select_indices_for_transfer(assets_selection_context& needed_money_map, uint64_t fake_outputs_count, std::vector& selected_indexes); From 635f52d4995f86474f51f2d60bef52b41ad3ff3b Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Mon, 1 Apr 2024 16:49:58 +0200 Subject: [PATCH 092/184] fix for compilation on macos --- contrib/epee/include/serialization/keyvalue_serialization.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/epee/include/serialization/keyvalue_serialization.h b/contrib/epee/include/serialization/keyvalue_serialization.h index d47918cc..f60b92d1 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization.h +++ b/contrib/epee/include/serialization/keyvalue_serialization.h @@ -73,7 +73,7 @@ public: \ epee::serialization::selector::serialize(this_ref.varialble, stg, hparent_section, val_name); \ if constexpr (t_storage::use_descriptions::value) \ { \ - epee::serialization::selector::serialize_and_doc(stg, hparent_section, val_name + epee::serialization::selector::template serialize_and_doc(stg, hparent_section, val_name /* {using var_type = decltype(this_ref.varialble); \ From 6e036356dfc2fecff516dcac808dd8f4198e0a22 Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 2 Apr 2024 22:00:53 +0200 Subject: [PATCH 093/184] wallet: sweeping of bare unspent outputs implemented --- src/simplewallet/password_container.cpp | 17 ++- src/simplewallet/password_container.h | 6 +- src/simplewallet/simplewallet.cpp | 122 ++++++++++++++++ src/simplewallet/simplewallet.h | 3 +- src/wallet/wallet2.cpp | 187 ++++++++++++++++++++++++ src/wallet/wallet2.h | 14 ++ src/wallet/wallet_helpers.h | 1 + src/wallet/wallet_public_structs_defs.h | 2 + 8 files changed, 343 insertions(+), 9 deletions(-) diff --git a/src/simplewallet/password_container.cpp b/src/simplewallet/password_container.cpp index b4ca7448..6203eee9 100644 --- a/src/simplewallet/password_container.cpp +++ b/src/simplewallet/password_container.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2018 Zano Project +// Copyright (c) 2014-2024 Zano Project // Copyright (c) 2014-2018 The Louisdor Project // Copyright (c) 2012-2013 The Cryptonote developers // Distributed under the MIT/X11 software license, see the accompanying @@ -63,6 +63,11 @@ namespace tools } bool password_container::read_password(const std::string& prompt_text) + { + return read_input(prompt_text, '*'); + } + + bool password_container::read_input(const std::string& prompt_text, char char_to_replace_user_input /* = '\0' */) { clear(); @@ -70,7 +75,7 @@ namespace tools if (is_cin_tty()) { std::cout << prompt_text; - r = read_from_tty(); + r = read_from_tty(char_to_replace_user_input); } else { @@ -122,7 +127,7 @@ namespace tools } } - bool password_container::read_from_tty() + bool password_container::read_from_tty(char char_to_replace_user_input) { const char BACKSPACE = 8; @@ -162,7 +167,7 @@ namespace tools else { m_password.push_back(ch); - std::cout << '*'; + std::cout << (char_to_replace_user_input != '\0' ? char_to_replace_user_input : ch); } } @@ -198,7 +203,7 @@ namespace tools } } - bool password_container::read_from_tty() + bool password_container::read_from_tty(char char_to_replace_user_input) { const char BACKSPACE = 127; @@ -227,7 +232,7 @@ namespace tools else { m_password.push_back(ch); - std::cout << '*'; + std::cout << (char_to_replace_user_input != '\0' ? char_to_replace_user_input : ch); } } diff --git a/src/simplewallet/password_container.h b/src/simplewallet/password_container.h index 49a3412a..5bca195b 100644 --- a/src/simplewallet/password_container.h +++ b/src/simplewallet/password_container.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2018 Zano Project +// Copyright (c) 2014-2024 Zano Project // Copyright (c) 2014-2018 The Louisdor Project // Copyright (c) 2012-2013 The Cryptonote developers // Distributed under the MIT/X11 software license, see the accompanying @@ -24,13 +24,15 @@ namespace tools void clear(); bool empty() const { return m_empty; } const std::string& password() const { return m_password; } + const std::string& get_input() const { return m_password; } // TODO: refactor this void password(std::string&& val) { m_password = std::move(val); m_empty = false; } bool read_password(); bool read_password(const std::string& prompt_text); + bool read_input(const std::string& prompt_text, char char_to_replace_user_input = '\0'); private: bool read_from_file(); - bool read_from_tty(); + bool read_from_tty(char char_to_replace_user_input); private: bool m_empty; diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 24a2053f..bb1ac622 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -315,6 +315,7 @@ simple_wallet::simple_wallet() m_cmd_binder.set_handler("scan_transfers_for_ki", boost::bind(&simple_wallet::scan_transfers_for_ki, this,ph::_1), "Rescan transfers for key image"); m_cmd_binder.set_handler("print_utxo_distribution", boost::bind(&simple_wallet::print_utxo_distribution, this,ph::_1), "Prints utxo distribution"); m_cmd_binder.set_handler("sweep_below", boost::bind(&simple_wallet::sweep_below, this,ph::_1), "sweep_below
[payment_id] - Tries to transfers all coins with amount below the given limit to the given address"); + m_cmd_binder.set_handler("sweep_bare_outs", boost::bind(&simple_wallet::sweep_bare_outs, this,ph::_1), "sweep_bare_outs - Transfers all bare unspent outputs to itself. Uses several txs if necessary."); m_cmd_binder.set_handler("address", boost::bind(&simple_wallet::print_address, this,ph::_1), "Show current wallet public address"); m_cmd_binder.set_handler("integrated_address", boost::bind(&simple_wallet::integrated_address, this,ph::_1), "integrated_address [| &args) SIMPLE_WALLET_CATCH_TRY_ENTRY(); return true; } +//---------------------------------------------------------------------------------------------------- +bool simple_wallet::sweep_bare_outs(const std::vector &args) +{ + CONFIRM_WITH_PASSWORD(); + SIMPLE_WALLET_BEGIN_TRY_ENTRY(); + bool r = false; + if (args.size() > 1) + { + fail_msg_writer() << "Invalid number of agruments given"; + return true; + } + currency::account_public_address target_address = m_wallet->get_account().get_public_address(); + currency::payment_id_t integrated_payment_id{}; + if (args.size() == 1) + { + if (!m_wallet->get_transfer_address(args[0], target_address, integrated_payment_id)) + { + fail_msg_writer() << "Unable to parse address from " << args[1]; + return true; + } + if (!integrated_payment_id.empty()) + { + fail_msg_writer() << "Payment id is not supported. Please, don't use integrated address with this command."; + return true; + } + } + + if (!m_wallet->has_bare_unspent_outputs()) + { + success_msg_writer(true) << "This wallet doesn't have bare unspent outputs.\nNothing to do. Everything looks good."; + return true; + } + + std::vector groups; + m_wallet->get_bare_unspent_outputs_stats(groups); + if (groups.empty()) + { + uint64_t unlocked_balance = 0; + uint64_t balance = m_wallet->balance(unlocked_balance); + if (balance < COIN) + success_msg_writer(false) << "Looks like it's not enough coins to perform this operation. Transferring " << print_money_brief(TX_MINIMUM_FEE) << " ZANO or more to this wallet may help."; + else if (unlocked_balance < COIN) + success_msg_writer(false) << "Not enough spendable outputs to perform this operation. Please, try again later."; + else + { + success_msg_writer(false) << "This operation couldn't be performed for some reason. Please, copy simplewallet's log file and ask for support. Nothing was done."; + LOG_PRINT_L0("strange situation: balance: " << print_money_brief(balance) << ", unlocked_balance: " << print_money_brief(unlocked_balance) << " but get_bare_unspent_outputs_stats returned empty result"); + } + return true; + } + + size_t i = 0, total_bare_outs = 0; + uint64_t total_mount = 0; + std::stringstream details_ss; + for(auto &g : groups) + { + details_ss << std::setw(2) << i << ": "; + for (auto& tid: g.tids) + { + tools::transfer_details td{}; + CHECK_AND_ASSERT_THROW_MES(m_wallet->get_transfer_info_by_index(tid, td), "get_transfer_info_by_index failed with index " << tid); + details_ss << tid << " (" << print_money_brief(td.m_amount) << "), "; + total_mount += td.m_amount; + } + + if (g.additional_tid) + details_ss << "additional tid: " << g.tids.back() << "( " << print_money_brief(g.additional_tid_amount) << ")"; + else + details_ss.seekp(-2, std::ios_base::end); + + details_ss << ENDL; + ++i; + total_bare_outs += g.tids.size(); + } + + LOG_PRINT_L1("bare UTXO:" << ENDL << details_ss.str()); + + success_msg_writer(true) << "This wallet contains " << total_bare_outs << " bare outputs with total amount of " << print_money_brief(total_mount) << + ". They can be converted in " << groups.size() << " transaction" << (groups.size() > 1 ? "s" : "") << ", with total fee = " << print_money_brief(TX_DEFAULT_FEE * i) << "."; + if (target_address != m_wallet->get_account().get_public_address()) + message_writer(epee::log_space::console_color_yellow, false) << print_money_brief(total_mount) << " coins will be sent to address " << get_account_address_as_str(target_address); + + tools::password_container reader; + if (!reader.read_input("Would you like to continue? (y/yes/n/no):\n") || (reader.get_input() != "y" && reader.get_input() != "yes")) + { + success_msg_writer(false) << "Operatation terminated as requested by user."; + return true; + } + + size_t total_tx_sent = 0; + uint64_t total_fee_spent = 0; + uint64_t total_amount_sent = 0; + auto on_tx_sent_callback = [&](size_t batch_index, const currency::transaction& tx, uint64_t amount, uint64_t fee, bool sent_ok, const std::string& err) { + auto mw = success_msg_writer(false); + mw << std::setw(2) << batch_index << ": transaction "; + if (!sent_ok) + { + mw << "failed (" << err << ")"; + return; + } + mw << get_transaction_hash(tx) << ", fee: " << print_money_brief(fee) << ", amount: " << print_money_brief(amount); + ++total_tx_sent; + total_fee_spent += fee; + total_amount_sent += amount; + }; + + if (!m_wallet->sweep_bare_unspent_outputs(target_address, groups, on_tx_sent_callback)) + { + auto mw = fail_msg_writer(); + mw << "Operatation failed."; + if (total_tx_sent > 0) + mw << " However, " << total_tx_sent << " transaction" << (total_tx_sent == 1 ? " was" : "s were") << " successfully sent, " << print_money_brief(total_amount_sent) << " coins transferred, and " << print_money_brief(total_fee_spent) << " was spent for fees."; + } + else + { + success_msg_writer(true) << "Operatation succeeded. " << ENDL << total_tx_sent << " transaction" << (total_tx_sent == 1 ? " was" : "s were") << " successfully sent, " << print_money_brief(total_amount_sent) << " coins transferred, and " << print_money_brief(total_fee_spent) << " was spent for fees."; + } + + SIMPLE_WALLET_CATCH_TRY_ENTRY(); + return true; +} //---------------------------------------------------------------------------------------------------- uint64_t get_tick_count__() diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index 81958f18..0b0843d0 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2018 Zano Project +// Copyright (c) 2014-2024 Zano Project // Copyright (c) 2014-2018 The Louisdor Project // Copyright (c) 2012-2013 The Cryptonote developers // Distributed under the MIT/X11 software license, see the accompanying @@ -87,6 +87,7 @@ namespace currency bool sign_transfer(const std::vector &args); bool submit_transfer(const std::vector &args); bool sweep_below(const std::vector &args); + bool sweep_bare_outs(const std::vector &args); bool tor_enable(const std::vector &args); bool tor_disable(const std::vector &args); bool deploy_new_asset(const std::vector &args); diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 5b09b36d..93189335 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -2200,6 +2200,189 @@ bool wallet2::has_related_alias_entry_unconfirmed(const currency::transaction& t return false; } //---------------------------------------------------------------------------------------------------- +#define HARDFORK_04_TIMESTAMP_ACTUAL 1711021795ull // block 2555000, 2024-03-21 11:49:55 UTC +bool wallet2::has_bare_unspent_outputs() const +{ + if (m_account.get_createtime() > HARDFORK_04_TIMESTAMP_ACTUAL) + return false; + + [[maybe_unused]] uint64_t bal = 0; + if (!m_has_bare_unspent_outputs.has_value()) + bal = balance(); + + WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(m_has_bare_unspent_outputs.has_value(), "m_has_bare_unspent_outputs has no value after balance()"); + + return m_has_bare_unspent_outputs.value(); +} +//---------------------------------------------------------------------------------------------------- +#define MAX_INPUTS_FOR_SIMPLE_TX_EURISTIC 20 +bool wallet2::get_bare_unspent_outputs_stats(std::vector& tids_grouped_by_txs) const +{ + tids_grouped_by_txs.clear(); + + // 1/3. Populate a list of bare unspent outputs + std::unordered_map> buo_ids; // tx hash -> Bare Unspent Outs list + for(size_t tid = 0; tid != m_transfers.size(); ++tid) + { + const auto& td = m_transfers[tid]; + if (!td.is_zc() && td.is_spendable()) + { + buo_ids[td.tx_hash()].push_back(tid); + } + } + + if (buo_ids.empty()) + return true; + + // 2/3. Split them into groups + tids_grouped_by_txs.emplace_back(); + for(auto& buo_el : buo_ids) + { + if (tids_grouped_by_txs.back().tids.size() + buo_el.second.size() > MAX_INPUTS_FOR_SIMPLE_TX_EURISTIC) + tids_grouped_by_txs.emplace_back(); + + for(auto& tid : buo_el.second) + { + if (tids_grouped_by_txs.back().tids.size() >= MAX_INPUTS_FOR_SIMPLE_TX_EURISTIC) + tids_grouped_by_txs.emplace_back(); + tids_grouped_by_txs.back().tids.push_back(tid); + tids_grouped_by_txs.back().total_amount += m_transfers[tid].m_amount; + } + } + + + // 3/3. Iterate through groups and check whether total amount is big enough to cover min fee. + // Add additional zc output if not. + std::multimap usable_zc_outs_tids; // grouped by amount + bool usable_zc_outs_tids_precalculated = false; + auto precalculate_usable_zc_outs_if_needed = [&](){ + if (usable_zc_outs_tids_precalculated) + return; + size_t decoys = is_auditable() ? 0 : m_core_runtime_config.hf4_minimum_mixins; + for(size_t tid = 0; tid != m_transfers.size(); ++tid) + { + auto& td = m_transfers[tid]; + if (td.is_zc() && td.is_native_coin() && is_transfer_ready_to_go(td, decoys)) + usable_zc_outs_tids.insert(std::make_pair(td.m_amount, tid)); + } + usable_zc_outs_tids_precalculated = true; + }; + + std::unordered_set used_zc_outs; + for(auto it = tids_grouped_by_txs.begin(); it != tids_grouped_by_txs.end(); ) + { + auto& group = *it; + if (group.total_amount < TX_MINIMUM_FEE) + { + precalculate_usable_zc_outs_if_needed(); + + uint64_t min_required_amount = TX_MINIMUM_FEE - group.total_amount; + auto jt = usable_zc_outs_tids.lower_bound(min_required_amount); + bool found = false; + while(jt != usable_zc_outs_tids.end()) + { + WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(jt->first >= min_required_amount, "jt->first=" << jt->first << ", min_required_amount=" << min_required_amount); + if (used_zc_outs.count(jt->second) == 0) + { + group.tids.push_back(jt->second); + used_zc_outs.insert(jt->second); + group.additional_tid = true; + group.additional_tid_amount = jt->first; + found = true; + break; + } + ++jt; + } + + if (!found) + { + // no usable outs for required amount, remove this group and go to the next + it = tids_grouped_by_txs.erase(it); + continue; + } + } + + ++it; + } + + return true; +} +//---------------------------------------------------------------------------------------------------- +bool wallet2::sweep_bare_unspent_outputs(const currency::account_public_address& target_address, const std::vector& tids_grouped_by_txs, + std::function on_tx_sent) +{ + if (m_watch_only) + return false; + + size_t decoys_count = is_auditable() ? 0 : CURRENCY_DEFAULT_DECOY_SET_SIZE; + + bool send_to_network = true; + + size_t batch_index = 0; + for(const batch_of_bare_unspent_outs& group : tids_grouped_by_txs) + { + currency::finalized_tx ftx{}; + currency::finalize_tx_param ftp{}; + ftp.pevents_dispatcher = &m_debug_events_dispatcher; + ftp.tx_version = this->get_current_tx_version(); + + if (!prepare_tx_sources(decoys_count, ftp.sources, group.tids)) + { + on_tx_sent(batch_index, transaction{}, 0, 0, false, "sources for tx couldn't be prepared"); + LOG_PRINT_L0("prepare_tx_sources failed, batch_index = " << batch_index); + return false; + } + uint64_t fee = TX_DEFAULT_FEE; + std::vector destinations{tx_destination_entry(group.total_amount + group.additional_tid_amount - fee, target_address)}; + assets_selection_context needed_money_map{std::make_pair(native_coin_asset_id, selection_for_amount{group.total_amount + group.additional_tid_amount, group.total_amount + group.additional_tid_amount})}; + try + { + prepare_tx_destinations(needed_money_map, get_current_split_strategy(), tx_dust_policy{}, destinations, 0 /* tx_flags */, ftp.prepared_destinations); + } + catch(...) + { + on_tx_sent(batch_index, transaction{}, 0, 0, false, "destinations for tx couldn't be prepared"); + LOG_PRINT_L0("prepare_tx_destinations failed, batch_index = " << batch_index); + return false; + } + + mark_transfers_as_spent(ftp.selected_transfers, std::string("sweep bare UTXO, tx: ") + epee::string_tools::pod_to_hex(get_transaction_hash(ftx.tx))); + try + { + finalize_transaction(ftp, ftx, send_to_network); + on_tx_sent(batch_index, ftx.tx, group.total_amount + group.additional_tid_amount, fee, true, std::string()); + } + catch(std::exception& e) + { + clear_transfers_from_flag(ftp.selected_transfers, WALLET_TRANSFER_DETAIL_FLAG_SPENT, std::string("exception on sweep bare UTXO, tx: ") + epee::string_tools::pod_to_hex(get_transaction_hash(ftx.tx))); + on_tx_sent(batch_index, transaction{}, 0, 0, false, e.what()); + return false; + } + + ++batch_index; + } + + return true; +} +//---------------------------------------------------------------------------------------------------- +bool wallet2::sweep_bare_unspent_outputs(const currency::account_public_address& target_address, const std::vector& tids_grouped_by_txs, + size_t& total_txs_sent, uint64_t& total_amount_sent, uint64_t& total_fee_spent) +{ + total_txs_sent = 0; + total_amount_sent = 0; + total_fee_spent = 0; + auto on_tx_sent_callback = [&](size_t batch_index, const currency::transaction& tx, uint64_t amount, uint64_t fee, bool sent_ok, const std::string& err) { + if (sent_ok) + { + ++total_txs_sent; + total_fee_spent += fee; + total_amount_sent += amount; + } + }; + + return sweep_bare_unspent_outputs(target_address, tids_grouped_by_txs, on_tx_sent_callback); +} +//---------------------------------------------------------------------------------------------------- uint64_t wallet2::get_directly_spent_transfer_index_by_input_in_tracking_wallet(const currency::txin_to_key& intk) { return get_directly_spent_transfer_index_by_input_in_tracking_wallet(intk.amount, intk.key_offsets); @@ -3444,6 +3627,7 @@ uint64_t wallet2::balance(const crypto::public_key& asset_id) const bool wallet2::balance(std::unordered_map& balances, uint64_t& mined) const { mined = 0; + m_has_bare_unspent_outputs = false; for(auto& td : m_transfers) { @@ -3464,6 +3648,9 @@ bool wallet2::balance(std::unordered_map m_last_sync_percent = 0; mutable uint64_t m_current_wallet_file_size = 0; bool m_use_assets_whitelisting = true; + mutable std::optional m_has_bare_unspent_outputs; // recalculated each time the balance() is called //=============================================================== @@ -342,6 +343,13 @@ namespace tools mutable crypto::hash tx_hash_ = currency::null_hash; }; + struct batch_of_bare_unspent_outs + { + std::vector tids; + uint64_t total_amount = 0; + bool additional_tid = false; // additional zc transfer if total_amount < min fee + uint64_t additional_tid_amount = 0; + }; @@ -377,6 +385,12 @@ namespace tools void set_do_rise_transfer(bool do_rise) { m_do_rise_transfer = do_rise; } bool has_related_alias_entry_unconfirmed(const currency::transaction& tx); + bool has_bare_unspent_outputs() const; + bool get_bare_unspent_outputs_stats(std::vector& buo_txs) const; + bool sweep_bare_unspent_outputs(const currency::account_public_address& target_address, const std::vector& tids_grouped_by_txs, + std::function on_tx_sent); + bool sweep_bare_unspent_outputs(const currency::account_public_address& target_address, const std::vector& tids_grouped_by_txs, + size_t& total_txs_sent, uint64_t& total_amount_sent, uint64_t& total_fee); void handle_unconfirmed_tx(process_transaction_context& ptc); void scan_tx_pool(bool& has_related_alias_in_unconfirmed); void refresh(); diff --git a/src/wallet/wallet_helpers.h b/src/wallet/wallet_helpers.h index 12a75d7a..6c24ef88 100644 --- a/src/wallet/wallet_helpers.h +++ b/src/wallet/wallet_helpers.h @@ -20,6 +20,7 @@ namespace tools wi.path = epee::string_encoding::wstring_to_utf8(w.get_wallet_path()); wi.is_auditable = w.is_auditable(); wi.is_watch_only = w.is_watch_only(); + wi.has_bare_unspent_outputs = w.has_bare_unspent_outputs(); return true; } diff --git a/src/wallet/wallet_public_structs_defs.h b/src/wallet/wallet_public_structs_defs.h index 523aa2d4..db98aad3 100644 --- a/src/wallet/wallet_public_structs_defs.h +++ b/src/wallet/wallet_public_structs_defs.h @@ -1550,6 +1550,7 @@ namespace wallet_public std::string path; bool is_auditable; bool is_watch_only; + bool has_bare_unspent_outputs; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(balances) @@ -1559,6 +1560,7 @@ namespace wallet_public KV_SERIALIZE(path) KV_SERIALIZE(is_auditable) KV_SERIALIZE(is_watch_only) + KV_SERIALIZE(has_bare_unspent_outputs) END_KV_SERIALIZE_MAP() }; From d69a47a46d69ca409dde2051a548056fa53b95df Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 2 Apr 2024 22:03:09 +0200 Subject: [PATCH 094/184] wallet: removed unnecessary setting of mix_att to hf4_minimum_mixins in finalize_transaction() --- src/wallet/wallet2.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 93189335..a4039a7a 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -7431,10 +7431,6 @@ void wallet2::finalize_transaction(currency::finalize_tx_param& ftp, currency::f // broadcasting tx without secret key storing is forbidden to avoid lost key issues WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(!broadcast_tx || store_tx_secret_key, "finalize_tx is requested to broadcast a tx without storing the key"); - //overide mixins count for hardfork 4 outputs - if (is_in_hardfork_zone(ZANO_HARDFORK_04_ZARCANUM)) - ftp.tx_outs_attr = m_core_runtime_config.hf4_minimum_mixins; - bool r = currency::construct_tx(m_account.get_keys(), ftp, result); //TIME_MEASURE_FINISH_MS(construct_tx_time); From 1f3ae7b725e78c5b80d4d6b551c8bb766b6b1e16 Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 3 Apr 2024 16:45:33 +0200 Subject: [PATCH 095/184] wallet RPC: get_bare_outs_stats, sweep_bare_outs implemented + minor improvements --- src/simplewallet/simplewallet.cpp | 8 +-- src/wallet/view_iface.h | 2 + src/wallet/wallet2.cpp | 4 +- src/wallet/wallet2.h | 2 +- src/wallet/wallet_public_structs_defs.h | 50 +++++++++++++++++ src/wallet/wallet_rpc_server.cpp | 72 +++++++++++++++++++++++++ src/wallet/wallet_rpc_server.h | 4 ++ src/wallet/wallets_manager.cpp | 1 + 8 files changed, 137 insertions(+), 6 deletions(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 6c544581..a69bed93 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -2572,7 +2572,7 @@ bool simple_wallet::sweep_bare_outs(const std::vector &args) } size_t i = 0, total_bare_outs = 0; - uint64_t total_mount = 0; + uint64_t total_amount = 0; std::stringstream details_ss; for(auto &g : groups) { @@ -2582,7 +2582,7 @@ bool simple_wallet::sweep_bare_outs(const std::vector &args) tools::transfer_details td{}; CHECK_AND_ASSERT_THROW_MES(m_wallet->get_transfer_info_by_index(tid, td), "get_transfer_info_by_index failed with index " << tid); details_ss << tid << " (" << print_money_brief(td.m_amount) << "), "; - total_mount += td.m_amount; + total_amount += td.m_amount; } if (g.additional_tid) @@ -2597,10 +2597,10 @@ bool simple_wallet::sweep_bare_outs(const std::vector &args) LOG_PRINT_L1("bare UTXO:" << ENDL << details_ss.str()); - success_msg_writer(true) << "This wallet contains " << total_bare_outs << " bare outputs with total amount of " << print_money_brief(total_mount) << + success_msg_writer(true) << "This wallet contains " << total_bare_outs << " bare outputs with total amount of " << print_money_brief(total_amount) << ". They can be converted in " << groups.size() << " transaction" << (groups.size() > 1 ? "s" : "") << ", with total fee = " << print_money_brief(TX_DEFAULT_FEE * i) << "."; if (target_address != m_wallet->get_account().get_public_address()) - message_writer(epee::log_space::console_color_yellow, false) << print_money_brief(total_mount) << " coins will be sent to address " << get_account_address_as_str(target_address); + message_writer(epee::log_space::console_color_yellow, false) << print_money_brief(total_amount) << " coins will be sent to address " << get_account_address_as_str(target_address); tools::password_container reader; if (!reader.read_input("Would you like to continue? (y/yes/n/no):\n") || (reader.get_input() != "y" && reader.get_input() != "yes")) diff --git a/src/wallet/view_iface.h b/src/wallet/view_iface.h index 16faf90e..dce4b5ee 100644 --- a/src/wallet/view_iface.h +++ b/src/wallet/view_iface.h @@ -201,11 +201,13 @@ public: std::list balances; uint64_t minied_total; + bool has_bare_unspent_outputs; BEGIN_KV_SERIALIZE_MAP() KV_CHAIN_BASE(wallet_status_info_base) KV_SERIALIZE(balances) KV_SERIALIZE(minied_total) + KV_SERIALIZE(has_bare_unspent_outputs) END_KV_SERIALIZE_MAP() }; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index c0e1f45b..ed88296c 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -2346,14 +2346,16 @@ bool wallet2::sweep_bare_unspent_outputs(const currency::account_public_address& } //---------------------------------------------------------------------------------------------------- bool wallet2::sweep_bare_unspent_outputs(const currency::account_public_address& target_address, const std::vector& tids_grouped_by_txs, - size_t& total_txs_sent, uint64_t& total_amount_sent, uint64_t& total_fee_spent) + size_t& total_txs_sent, uint64_t& total_amount_sent, uint64_t& total_fee_spent, uint64_t& total_bare_outs_sent) { total_txs_sent = 0; total_amount_sent = 0; total_fee_spent = 0; + total_bare_outs_sent = 0; auto on_tx_sent_callback = [&](size_t batch_index, const currency::transaction& tx, uint64_t amount, uint64_t fee, bool sent_ok, const std::string& err) { if (sent_ok) { + total_bare_outs_sent += count_type_in_variant_container(tx.vin); ++total_txs_sent; total_fee_spent += fee; total_amount_sent += amount; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 5907ed33..c10892ea 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -391,7 +391,7 @@ namespace tools bool sweep_bare_unspent_outputs(const currency::account_public_address& target_address, const std::vector& tids_grouped_by_txs, std::function on_tx_sent); bool sweep_bare_unspent_outputs(const currency::account_public_address& target_address, const std::vector& tids_grouped_by_txs, - size_t& total_txs_sent, uint64_t& total_amount_sent, uint64_t& total_fee); + size_t& total_txs_sent, uint64_t& total_amount_sent, uint64_t& total_fee, uint64_t& total_bare_outs_sent); void handle_unconfirmed_tx(process_transaction_context& ptc); void scan_tx_pool(bool& has_related_alias_in_unconfirmed); void refresh(); diff --git a/src/wallet/wallet_public_structs_defs.h b/src/wallet/wallet_public_structs_defs.h index d4b2a100..8089fa71 100644 --- a/src/wallet/wallet_public_structs_defs.h +++ b/src/wallet/wallet_public_structs_defs.h @@ -445,6 +445,7 @@ namespace wallet_public uint64_t transfers_count; uint64_t transfer_entries_count; bool is_whatch_only; + bool has_bare_unspent_outputs; std::vector utxo_distribution; uint64_t current_height; @@ -454,6 +455,7 @@ namespace wallet_public KV_SERIALIZE(transfers_count) KV_SERIALIZE(transfer_entries_count) KV_SERIALIZE(is_whatch_only) + KV_SERIALIZE(has_bare_unspent_outputs) KV_SERIALIZE(utxo_distribution) KV_SERIALIZE(current_height) END_KV_SERIALIZE_MAP() @@ -834,6 +836,54 @@ namespace wallet_public }; }; + struct COMMAND_RPC_GET_BARE_OUTS_STATS + { + struct request + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + + struct response + { + uint64_t total_bare_outs; + uint64_t total_amount; + uint64_t expected_total_fee; + uint64_t txs_count; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(total_bare_outs) + KV_SERIALIZE(total_amount) + KV_SERIALIZE(expected_total_fee) + KV_SERIALIZE(txs_count) + END_KV_SERIALIZE_MAP() + }; + }; + + struct COMMAND_RPC_SWEEP_BARE_OUTS + { + struct request + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + + struct response + { + uint64_t bare_outs_swept; + uint64_t amount_swept; + uint64_t fee_spent; + uint64_t txs_sent; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(bare_outs_swept) + KV_SERIALIZE(amount_swept) + KV_SERIALIZE(fee_spent) + KV_SERIALIZE(txs_sent) + END_KV_SERIALIZE_MAP() + }; + }; + struct COMMAND_SIGN_TRANSFER { struct request diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 5baf588d..9c80cb96 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -351,6 +351,7 @@ namespace tools res.utxo_distribution.push_back(currency::print_money_brief(ent.first) + ":" + std::to_string(ent.second)); res.current_height = w.get_wallet()->get_top_block_height(); + res.has_bare_unspent_outputs = w.get_wallet()->has_bare_unspent_outputs(); return true; WALLET_RPC_CATCH_TRY_ENTRY(); } @@ -752,6 +753,77 @@ namespace tools WALLET_RPC_CATCH_TRY_ENTRY(); } //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_get_bare_outs_stats(const wallet_public::COMMAND_RPC_GET_BARE_OUTS_STATS ::request& req, wallet_public::COMMAND_RPC_GET_BARE_OUTS_STATS::response& res, epee::json_rpc::error& er, connection_context& cntx) + { + WALLET_RPC_BEGIN_TRY_ENTRY(); + + if (w.get_wallet()->is_watch_only()) + { + er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; + er.message = "operation cannot be performed in watch-only wallet"; + return false; + } + + std::vector groups; + if (!w.get_wallet()->get_bare_unspent_outputs_stats(groups)) + { + er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; + er.message = "get_bare_unspent_outputs_stats failed"; + return false; + } + + res.total_amount = 0; + res.total_bare_outs = 0; + res.expected_total_fee = 0; + res.txs_count = 0; + + for(auto &g : groups) + { + for (auto& tid: g.tids) + { + tools::transfer_details td{}; + CHECK_AND_ASSERT_THROW_MES(w.get_wallet()->get_transfer_info_by_index(tid, td), "get_transfer_info_by_index failed with index " << tid); + res.total_amount += td.m_amount; + } + ++res.txs_count; + res.total_bare_outs += g.tids.size(); + res.expected_total_fee += TX_DEFAULT_FEE; + } + + return true; + WALLET_RPC_CATCH_TRY_ENTRY(); + } + //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_sweep_bare_outs(const wallet_public::COMMAND_RPC_SWEEP_BARE_OUTS::request& req, wallet_public::COMMAND_RPC_SWEEP_BARE_OUTS::response& res, epee::json_rpc::error& er, connection_context& cntx) + { + WALLET_RPC_BEGIN_TRY_ENTRY(); + + if (w.get_wallet()->is_watch_only()) + { + er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; + er.message = "operation cannot be performed in watch-only wallet"; + return false; + } + + std::vector groups; + if (!w.get_wallet()->get_bare_unspent_outputs_stats(groups)) + { + er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; + er.message = "get_bare_unspent_outputs_stats failed"; + return false; + } + + res.amount_swept = 0; + res.bare_outs_swept = 0; + res.fee_spent = 0; + res.txs_sent = 0; + + w.get_wallet()->sweep_bare_unspent_outputs(w.get_wallet()->get_account().get_public_address(), groups, res.txs_sent, res.amount_swept, res.fee_spent, res.bare_outs_swept); + + return true; + WALLET_RPC_CATCH_TRY_ENTRY(); + } + //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_sign_transfer(const wallet_public::COMMAND_SIGN_TRANSFER::request& req, wallet_public::COMMAND_SIGN_TRANSFER::response& res, epee::json_rpc::error& er, connection_context& cntx) { WALLET_RPC_BEGIN_TRY_ENTRY(); diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index 86faf178..7e8f4843 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -106,6 +106,8 @@ namespace tools MAP_JON_RPC_WE("make_integrated_address", on_make_integrated_address, wallet_public::COMMAND_RPC_MAKE_INTEGRATED_ADDRESS) MAP_JON_RPC_WE("split_integrated_address", on_split_integrated_address, wallet_public::COMMAND_RPC_SPLIT_INTEGRATED_ADDRESS) MAP_JON_RPC_WE("sweep_below", on_sweep_below, wallet_public::COMMAND_SWEEP_BELOW) + MAP_JON_RPC_WE("get_bare_outs_stats", on_get_bare_outs_stats, wallet_public::COMMAND_RPC_GET_BARE_OUTS_STATS) + MAP_JON_RPC_WE("sweep_bare_outs", on_sweep_bare_outs, wallet_public::COMMAND_RPC_SWEEP_BARE_OUTS) MAP_JON_RPC_WE("sign_transfer", on_sign_transfer, wallet_public::COMMAND_SIGN_TRANSFER) MAP_JON_RPC_WE("submit_transfer", on_submit_transfer, wallet_public::COMMAND_SUBMIT_TRANSFER) MAP_JON_RPC_WE("search_for_transactions", on_search_for_transactions, wallet_public::COMMAND_RPC_SEARCH_FOR_TRANSACTIONS_LEGACY) @@ -172,6 +174,8 @@ namespace tools bool on_make_integrated_address(const wallet_public::COMMAND_RPC_MAKE_INTEGRATED_ADDRESS::request& req, wallet_public::COMMAND_RPC_MAKE_INTEGRATED_ADDRESS::response& res, epee::json_rpc::error& er, connection_context& cntx); bool on_split_integrated_address(const wallet_public::COMMAND_RPC_SPLIT_INTEGRATED_ADDRESS::request& req, wallet_public::COMMAND_RPC_SPLIT_INTEGRATED_ADDRESS::response& res, epee::json_rpc::error& er, connection_context& cntx); bool on_sweep_below(const wallet_public::COMMAND_SWEEP_BELOW::request& req, wallet_public::COMMAND_SWEEP_BELOW::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool on_get_bare_outs_stats(const wallet_public::COMMAND_RPC_GET_BARE_OUTS_STATS ::request& req, wallet_public::COMMAND_RPC_GET_BARE_OUTS_STATS::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool on_sweep_bare_outs(const wallet_public::COMMAND_RPC_SWEEP_BARE_OUTS::request& req, wallet_public::COMMAND_RPC_SWEEP_BARE_OUTS::response& res, epee::json_rpc::error& er, connection_context& cntx); bool on_sign_transfer(const wallet_public::COMMAND_SIGN_TRANSFER::request& req, wallet_public::COMMAND_SIGN_TRANSFER::response& res, epee::json_rpc::error& er, connection_context& cntx); bool on_submit_transfer(const wallet_public::COMMAND_SUBMIT_TRANSFER::request& req, wallet_public::COMMAND_SUBMIT_TRANSFER::response& res, epee::json_rpc::error& er, connection_context& cntx); bool on_search_for_transactions(const wallet_public::COMMAND_RPC_SEARCH_FOR_TRANSACTIONS_LEGACY::request& req, wallet_public::COMMAND_RPC_SEARCH_FOR_TRANSACTIONS_LEGACY::response& res, epee::json_rpc::error& er, connection_context& cntx); diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index 6b867f7f..ba2635f5 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -1898,6 +1898,7 @@ void wallets_manager::prepare_wallet_status_info(wallet_vs_options& wo, view::wa wsi.wallet_id = wo.wallet_id; wsi.is_alias_operations_available = !wo.has_related_alias_in_unconfirmed; wo.w->get()->balance(wsi.balances, wsi.minied_total); + wsi.has_bare_unspent_outputs = wo.w->get()->has_bare_unspent_outputs(); } std::string wallets_manager::check_available_sources(uint64_t wallet_id, std::list& amounts) { From b5879f73606c0bf9f0c5b37b9fdfaf667975f46c Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 3 Apr 2024 17:18:47 +0200 Subject: [PATCH 096/184] gcc warning fixed --- .../include/serialization/keyvalue_serialization_overloads.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h index bd4eb2fe..933935b2 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h +++ b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h @@ -315,7 +315,7 @@ namespace epee struct selector { template - static bool serialize(const t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname) + static bool serialize(const t_type& d, t_storage& stg, [[maybe_unused]] typename t_storage::hsection hparent_section, [[maybe_unused]] const char* pname) { if constexpr (!t_storage::use_descriptions::value) { From 88a0d072b09ce3820aee7168294907077413bcde Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 3 Apr 2024 18:24:03 +0200 Subject: [PATCH 097/184] msvc compilation fix --- src/gui/qt-daemon/application/mainwindow.cpp | 26 ++++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/gui/qt-daemon/application/mainwindow.cpp b/src/gui/qt-daemon/application/mainwindow.cpp index 9f4f0313..80437eed 100644 --- a/src/gui/qt-daemon/application/mainwindow.cpp +++ b/src/gui/qt-daemon/application/mainwindow.cpp @@ -1017,11 +1017,11 @@ bool MainWindow::update_wallet_status(const view::wallet_status_info& wsi) m_wallet_states->operator [](wsi.wallet_id) = wsi.wallet_state; std::string json_str_pub; - epee::serialization::store_t_to_json(static_cast(wsi), json_str_pub, 0, epee::serialization::eol_lf); + epee::serialization::store_t_to_json(static_cast(wsi), json_str_pub, 0); LOG_PRINT_L0(get_wallet_log_prefix(wsi.wallet_id) + "SENDING SIGNAL -> [update_wallet_status]:" << std::endl << json_str_pub); std::string json_str; - epee::serialization::store_t_to_json(wsi, json_str, 0, epee::serialization::eol_lf); + epee::serialization::store_t_to_json(wsi, json_str, 0); QMetaObject::invokeMethod(this, "update_wallet_status", Qt::QueuedConnection, Q_ARG(QString, json_str.c_str())); return true; CATCH_ENTRY2(false); @@ -1031,7 +1031,7 @@ bool MainWindow::set_options(const view::gui_options& opt) { TRY_ENTRY(); std::string json_str; - epee::serialization::store_t_to_json(opt, json_str, 0, epee::serialization::eol_lf); + epee::serialization::store_t_to_json(opt, json_str, 0); LOG_PRINT_L0("SENDING SIGNAL -> [set_options]:" << std::endl << json_str); QMetaObject::invokeMethod(this, "set_options", Qt::QueuedConnection, Q_ARG(QString, json_str.c_str())); return true; @@ -1042,7 +1042,7 @@ bool MainWindow::update_tor_status(const view::current_action_status& opt) { TRY_ENTRY(); std::string json_str; - epee::serialization::store_t_to_json(opt, json_str, 0, epee::serialization::eol_lf); + epee::serialization::store_t_to_json(opt, json_str, 0); LOG_PRINT_L0("SENDING SIGNAL -> [HANDLE_CURRENT_ACTION_STATE]:" << std::endl << json_str); QMetaObject::invokeMethod(this, "handle_current_action_state", Qt::QueuedConnection, Q_ARG(QString, json_str.c_str())); return true; @@ -1087,7 +1087,7 @@ bool MainWindow::update_wallets_info(const view::wallets_summary_info& wsi) { TRY_ENTRY(); std::string json_str; - epee::serialization::store_t_to_json(wsi, json_str, 0, epee::serialization::eol_lf); + epee::serialization::store_t_to_json(wsi, json_str, 0); LOG_PRINT_L0("SENDING SIGNAL -> [update_wallets_info]"<< std::endl << json_str ); QMetaObject::invokeMethod(this, "update_wallets_info", Qt::QueuedConnection, Q_ARG(QString, json_str.c_str())); @@ -1099,7 +1099,7 @@ bool MainWindow::money_transfer(const view::transfer_event_info& tei) { TRY_ENTRY(); std::string json_str; - epee::serialization::store_t_to_json(tei, json_str, 0, epee::serialization::eol_lf); + epee::serialization::store_t_to_json(tei, json_str, 0); LOG_PRINT_L0(get_wallet_log_prefix(tei.wallet_id) + "SENDING SIGNAL -> [money_transfer]" << std::endl << json_str); //this->money_transfer(json_str.c_str()); @@ -1154,7 +1154,7 @@ bool MainWindow::money_transfer_cancel(const view::transfer_event_info& tei) { TRY_ENTRY(); std::string json_str; - epee::serialization::store_t_to_json(tei, json_str, 0, epee::serialization::eol_lf); + epee::serialization::store_t_to_json(tei, json_str, 0); LOG_PRINT_L0(get_wallet_log_prefix(tei.wallet_id) + "SENDING SIGNAL -> [money_transfer_cancel]"); //this->money_transfer_cancel(json_str.c_str()); @@ -1169,7 +1169,7 @@ bool MainWindow::wallet_sync_progress(const view::wallet_sync_progres_param& p) TRY_ENTRY(); LOG_PRINT_L2(get_wallet_log_prefix(p.wallet_id) + "SENDING SIGNAL -> [wallet_sync_progress]" << " wallet_id: " << p.wallet_id << ": " << p.progress << "%"); //this->wallet_sync_progress(epee::serialization::store_t_to_json(p).c_str()); - QMetaObject::invokeMethod(this, "wallet_sync_progress", Qt::QueuedConnection, Q_ARG(QString, epee::serialization::store_t_to_json(p, 0, epee::serialization::eol_lf).c_str())); + QMetaObject::invokeMethod(this, "wallet_sync_progress", Qt::QueuedConnection, Q_ARG(QString, epee::serialization::store_t_to_json(p, 0).c_str())); return true; CATCH_ENTRY2(false); } @@ -1231,7 +1231,7 @@ QString MainWindow::get_alias_coast(const QString& param) PREPARE_ARG_FROM_JSON(currency::struct_with_one_t_type, lvl); view::get_alias_coast_response resp; resp.error_code = m_backend.get_alias_coast(lvl.v, resp.coast); - return epee::serialization::store_t_to_json(resp, 0, epee::serialization::eol_lf).c_str(); + return epee::serialization::store_t_to_json(resp, 0).c_str(); CATCH_ENTRY_FAIL_API_RESPONCE(); } @@ -1259,7 +1259,7 @@ QString MainWindow::set_localization_strings(const QString param) resp.error_code = API_RETURN_CODE_OK; LOG_PRINT_L0("New localization set, language title: " << lr.language_title << ", strings " << lr.strings.size()); } - return epee::serialization::store_t_to_json(resp, 0, epee::serialization::eol_lf).c_str(); + return epee::serialization::store_t_to_json(resp, 0).c_str(); CATCH_ENTRY_FAIL_API_RESPONCE(); } @@ -1815,7 +1815,7 @@ QString MainWindow::show_openfile_dialog(const QString& param) if (!epee::serialization::load_t_from_json(ofdr, param.toStdString())) { ofdres.error_code = API_RETURN_CODE_BAD_ARG; - return epee::serialization::store_t_to_json(ofdres, 0, epee::serialization::eol_lf).c_str(); + return epee::serialization::store_t_to_json(ofdres, 0).c_str(); } QString path = QFileDialog::getOpenFileName(this, ofdr.caption.c_str(), @@ -1825,7 +1825,7 @@ QString MainWindow::show_openfile_dialog(const QString& param) if (!path.length()) { ofdres.error_code = API_RETURN_CODE_CANCELED; - return epee::serialization::store_t_to_json(ofdres, 0, epee::serialization::eol_lf).c_str(); + return epee::serialization::store_t_to_json(ofdres, 0).c_str(); } ofdres.error_code = API_RETURN_CODE_OK; @@ -1848,7 +1848,7 @@ QString MainWindow::show_savefile_dialog(const QString& param) if (!path.length()) { ofdres.error_code = API_RETURN_CODE_CANCELED; - return epee::serialization::store_t_to_json(ofdres, 0, epee::serialization::eol_lf).c_str(); + return epee::serialization::store_t_to_json(ofdres, 0).c_str(); } ofdres.error_code = API_RETURN_CODE_OK; From 59f38273e316a4535d8702823520cc00bc8278f4 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Wed, 3 Apr 2024 19:33:19 +0300 Subject: [PATCH 098/184] === build number: 294 -> 295 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index 72eaf612..291d51c9 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 294 +#define PROJECT_VERSION_BUILD_NO 295 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From 9cd8e88ab4dfd6c18c3e3df1f60907d26b2f48f9 Mon Sep 17 00:00:00 2001 From: sowle Date: Thu, 4 Apr 2024 16:34:43 +0200 Subject: [PATCH 099/184] an attempt to fix macos compilation --- src/wallet/wallet_rpc_server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 9c80cb96..8b75bfd2 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -818,7 +818,7 @@ namespace tools res.fee_spent = 0; res.txs_sent = 0; - w.get_wallet()->sweep_bare_unspent_outputs(w.get_wallet()->get_account().get_public_address(), groups, res.txs_sent, res.amount_swept, res.fee_spent, res.bare_outs_swept); + w.get_wallet()->sweep_bare_unspent_outputs(w.get_wallet()->get_account().get_public_address(), groups, static_cast(res.txs_sent), res.amount_swept, res.fee_spent, res.bare_outs_swept); return true; WALLET_RPC_CATCH_TRY_ENTRY(); From 3f1968837f4b7898a5896b4411d1ced60d562825 Mon Sep 17 00:00:00 2001 From: sowle Date: Thu, 4 Apr 2024 16:54:04 +0200 Subject: [PATCH 100/184] dependencies version updated --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 1b661e0a..e4515a47 100644 --- a/README.md +++ b/README.md @@ -15,10 +15,10 @@ Be sure to clone the repository properly:\ |--|--|--|--| | gcc (Linux) | 5.4.0 | 9.4.0 | 12.3.0 | | llvm/clang (Linux) | UNKNOWN | 7.0.1 | 8.0.0 | -| [MSVC](https://visualstudio.microsoft.com/downloads/) (Windows) | 2017 (15.9.30) | 2017 (15.9.30) | 2022 (17.7.5) | -| [XCode](https://developer.apple.com/downloads/) (macOS) | 12.3 | 14.3 | 14.3 | -| [CMake](https://cmake.org/download/) | 3.15.5 | 3.22.1 | 3.26.3 | -| [Boost](https://www.boost.org/users/download/) | 1.70 | 1.70 | 1.76 | +| [MSVC](https://visualstudio.microsoft.com/downloads/) (Windows) | 2017 (15.9.30) | 2019 (16.11.34) | 2022 (17.9.5) | +| [XCode](https://developer.apple.com/downloads/) (macOS) | 12.3 | 14.3 | 15.2 | +| [CMake](https://cmake.org/download/) | 3.15.5 | 3.26.3 | 3.29.0 | +| [Boost](https://www.boost.org/users/download/) | 1.70 | 1.70 | 1.84 | | [OpenSSL](https://www.openssl.org/source/) [(win)](https://slproweb.com/products/Win32OpenSSL.html) | 1.1.1n | 1.1.1w | 1.1.1w | | [Qt](https://download.qt.io/archive/qt/) (*only for GUI*) | 5.8.0 | 5.11.2 | 5.15.2 | From 60e8fcdc47ba058e66068b0bd10c1d97c121a363 Mon Sep 17 00:00:00 2001 From: sowle Date: Thu, 4 Apr 2024 18:01:26 +0200 Subject: [PATCH 101/184] an attempt to fix macOS compilation --- src/crypto/crypto-sugar.h | 2 +- src/wallet/wallet2.h | 2 -- src/wallet/wallet_rpc_server.cpp | 5 +++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/crypto/crypto-sugar.h b/src/crypto/crypto-sugar.h index b708283f..be99731f 100644 --- a/src/crypto/crypto-sugar.h +++ b/src/crypto/crypto-sugar.h @@ -1043,7 +1043,7 @@ namespace crypto void zero() { PUSH_GCC_WARNINGS - DISABLE_GCC_AND_CLANG_WARNING(class-memaccess) + DISABLE_GCC_WARNING(class-memaccess) size_t size_bytes = sizeof(scalar_t) * size(); memset(data(), 0, size_bytes); POP_GCC_WARNINGS diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index c10892ea..aae4d6fd 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -1096,7 +1096,6 @@ namespace tools ts_middle -= ts_middle % POS_SCAN_STEP; uint64_t ts_window = std::min(ts_middle - ts_from, ts_to - ts_middle); - size_t pos_entry_index = 0; for (size_t transfer_index = 0; transfer_index != m_transfers.size(); transfer_index++) { auto& tr = m_transfers[transfer_index]; @@ -1164,7 +1163,6 @@ namespace tools next_turn(); } - ++pos_entry_index; } cxt.status = API_RETURN_CODE_NOT_FOUND; return false; diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 8b75bfd2..9a8dd1d1 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -816,9 +816,10 @@ namespace tools res.amount_swept = 0; res.bare_outs_swept = 0; res.fee_spent = 0; - res.txs_sent = 0; - w.get_wallet()->sweep_bare_unspent_outputs(w.get_wallet()->get_account().get_public_address(), groups, static_cast(res.txs_sent), res.amount_swept, res.fee_spent, res.bare_outs_swept); + size_t txs_sent = 0; + w.get_wallet()->sweep_bare_unspent_outputs(w.get_wallet()->get_account().get_public_address(), groups, txs_sent, res.amount_swept, res.fee_spent, res.bare_outs_swept); + res.txs_sent = txs_sent; return true; WALLET_RPC_CATCH_TRY_ENTRY(); From ea7e99f7d3b109981a63944dab08ffb45e405e00 Mon Sep 17 00:00:00 2001 From: sowle Date: Thu, 4 Apr 2024 19:03:55 +0200 Subject: [PATCH 102/184] yet another attempt to fix macOS warnings and errors --- src/wallet/core_default_rpc_proxy.h | 2 +- src/wallet/wallet2.cpp | 4 ++-- src/wallet/wallet2.h | 2 +- src/wallet/wallets_manager.h | 12 ++++++------ 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/wallet/core_default_rpc_proxy.h b/src/wallet/core_default_rpc_proxy.h index c44f8d27..7eb94397 100644 --- a/src/wallet/core_default_rpc_proxy.h +++ b/src/wallet/core_default_rpc_proxy.h @@ -28,7 +28,7 @@ namespace tools bool set_connection_addr(const std::string& url) override; - void set_connectivity(unsigned int connection_timeout, size_t repeats_count); + void set_connectivity(unsigned int connection_timeout, size_t repeats_count) override; bool call_COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES(const currency::COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::request& rqt, currency::COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::response& rsp) override; bool call_COMMAND_RPC_GET_BLOCKS_FAST(const currency::COMMAND_RPC_GET_BLOCKS_FAST::request& rqt, currency::COMMAND_RPC_GET_BLOCKS_FAST::response& rsp) override; bool call_COMMAND_RPC_GET_BLOCKS_DIRECT(const currency::COMMAND_RPC_GET_BLOCKS_DIRECT::request& rqt, currency::COMMAND_RPC_GET_BLOCKS_DIRECT::response& rsp) override; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index ed88296c..c554e8d5 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -2225,7 +2225,7 @@ bool wallet2::get_bare_unspent_outputs_stats(std::vector= MAX_INPUTS_FOR_SIMPLE_TX_EURISTIC) tids_grouped_by_txs.emplace_back(); - tids_grouped_by_txs.back().tids.push_back(tid); + tids_grouped_by_txs.back().tids.push_back((uint64_t)tid); tids_grouped_by_txs.back().total_amount += m_transfers[tid].m_amount; } } @@ -2264,7 +2264,7 @@ bool wallet2::get_bare_unspent_outputs_stats(std::vectorfirst >= min_required_amount, "jt->first=" << jt->first << ", min_required_amount=" << min_required_amount); if (used_zc_outs.count(jt->second) == 0) { - group.tids.push_back(jt->second); + group.tids.push_back((uint64_t)jt->second); used_zc_outs.insert(jt->second); group.additional_tid = true; group.additional_tid_amount = jt->first; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index aae4d6fd..a44b69fa 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -346,7 +346,7 @@ namespace tools struct batch_of_bare_unspent_outs { - std::vector tids; + std::vector tids; uint64_t total_amount = 0; bool additional_tid = false; // additional zc transfer if total_amount < min fee uint64_t additional_tid_amount = 0; diff --git a/src/wallet/wallets_manager.h b/src/wallet/wallets_manager.h index d07c3000..60ea6fee 100644 --- a/src/wallet/wallets_manager.h +++ b/src/wallet/wallets_manager.h @@ -195,12 +195,12 @@ private: bool do_exception_safe_call(guarded_code_t guarded_code, error_prefix_maker_t error_prefix_maker, std::string& api_return_code_result); //----- i_backend_wallet_callback ------ - virtual void on_new_block(size_t wallet_id, uint64_t height, const currency::block& block); - virtual void on_transfer2(size_t wallet_id, const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined); - virtual void on_pos_block_found(size_t wallet_id, const currency::block& /*block*/); - virtual void on_sync_progress(size_t wallet_id, const uint64_t& /*percents*/); - virtual void on_transfer_canceled(size_t wallet_id, const tools::wallet_public::wallet_transfer_info& wti); - virtual void on_tor_status_change(size_t wallet_id, const std::string& state); + virtual void on_new_block(size_t wallet_id, uint64_t height, const currency::block& block) override; + virtual void on_transfer2(size_t wallet_id, const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) override; + virtual void on_pos_block_found(size_t wallet_id, const currency::block& /*block*/) override; + virtual void on_sync_progress(size_t wallet_id, const uint64_t& /*percents*/) override; + virtual void on_transfer_canceled(size_t wallet_id, const tools::wallet_public::wallet_transfer_info& wti) override; + virtual void on_tor_status_change(size_t wallet_id, const std::string& state) override; virtual void on_mw_get_wallets(std::vector& wallets) override; virtual bool on_mw_select_wallet(uint64_t wallet_id) override; From 95368faccd3f6761dc81103b44b5c0515f4fbe94 Mon Sep 17 00:00:00 2001 From: sowle Date: Thu, 4 Apr 2024 20:58:02 +0200 Subject: [PATCH 103/184] yet another attempt to fix macOS warnings and errors (CMAKE_OSX_DEPLOYMENT_TARGET: 10.12 -> 10.13) --- CMakeLists.txt | 2 +- src/wallet/wallet2.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dda630e4..4422f361 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,7 +69,7 @@ find_package(OpenSSL REQUIRED) if(APPLE) - set(CMAKE_OSX_DEPLOYMENT_TARGET 10.12) + set(CMAKE_OSX_DEPLOYMENT_TARGET 10.13) endif() set(USE_PCH FALSE CACHE BOOL "Use shared precompiled headers") diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index a44b69fa..e32d61f9 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -234,6 +234,7 @@ namespace tools wallet2(const wallet2&) = delete; public: wallet2(); + virtual ~wallet2() {} static std::string transfer_flags_to_str(uint32_t flags); From 2c181de6a34a632f3f8777889ac727da5c255264 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 4 Apr 2024 23:41:35 +0200 Subject: [PATCH 104/184] fixed serialization for hex-encoded array of pod items --- .../include/serialization/keyvalue_helpers.h | 34 +++++++++++++++++++ .../serialization/keyvalue_serialization.h | 5 +++ src/currency_core/currency_basic.h | 2 +- tests/performance_tests/main.cpp | 10 ++++-- 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/contrib/epee/include/serialization/keyvalue_helpers.h b/contrib/epee/include/serialization/keyvalue_helpers.h index 09555a9e..9b719103 100644 --- a/contrib/epee/include/serialization/keyvalue_helpers.h +++ b/contrib/epee/include/serialization/keyvalue_helpers.h @@ -97,6 +97,40 @@ namespace epee return epee::string_encoding::base64_decode(a); } + + //basic helpers for pod-to-hex serialization + template + std::string transform_t_pod_array_to_hex_str_array(const t_pod_container_type& a) + { + std::string res; + for (const auto& item : a) + { + res += epee::string_tools::pod_to_hex(a) + ", "; + } + if (a.size()) + { + res.erase(res.size() - 2); + } + + return res; + } + template + t_pod_container_type transform_hex_str_array_to_t_pod_array(const std::string& a) + { + std::vector pod_items; + boost::split(pod_items, a, boost::is_any_of(", ][\"")); + + t_pod_container_type res; + for (const auto& item : pod_items) + { + res.resize(res.size() + 1); + t_pod_container_type::value_type& pod_val = res.back(); + + if (!epee::string_tools::hex_to_pod(item, pod_val)) + throw std::runtime_error(std::string("Unable to transform \"") + item + "\" to pod type " + typeid(t_pod_container_type::value_type).name()); + } + return res; + } //------------------------------------------------------------------------------------------------------------------- #pragma pack(push, 1) template diff --git a/contrib/epee/include/serialization/keyvalue_serialization.h b/contrib/epee/include/serialization/keyvalue_serialization.h index f60b92d1..317944ca 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization.h +++ b/contrib/epee/include/serialization/keyvalue_serialization.h @@ -131,6 +131,10 @@ public: \ static_assert(std::is_pod::value, "t_type must be a POD type."); \ KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(varialble, val_name) +#define KV_SERIALIZE_CONTAINER_POD_AS_HEX_N(varialble, val_name) \ + KV_SERIALIZE_CUSTOM_N(varialble, std::string, epee::transform_t_pod_array_to_hex_str_array, epee::transform_hex_str_array_to_t_pod_array, val_name) + + #define KV_SERIALIZE_CONTAINER_POD_AS_BLOB_N(varialble, val_name) \ epee::serialization::selector::serialize_stl_container_pod_val_as_blob(this_ref.varialble, stg, hparent_section, val_name); @@ -145,6 +149,7 @@ public: \ #define KV_SERIALIZE_VAL_POD_AS_BLOB(varialble) KV_SERIALIZE_VAL_POD_AS_BLOB_N(varialble, #varialble) #define KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE(varialble) KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(varialble, #varialble) //skip is_pod compile time check #define KV_SERIALIZE_CONTAINER_POD_AS_BLOB(varialble) KV_SERIALIZE_CONTAINER_POD_AS_BLOB_N(varialble, #varialble) +#define KV_SERIALIZE_CONTAINER_POD_AS_HEX(varialble) KV_SERIALIZE_CONTAINER_POD_AS_HEX_N(varialble, #varialble) #define KV_SERIALIZE_CUSTOM(varialble, stored_type, from_v_to_stored, from_stored_to_v) KV_SERIALIZE_CUSTOM_N(varialble, stored_type, from_v_to_stored, from_stored_to_v, #varialble) #define KV_SERIALIZE_POD_AS_HEX_STRING(varialble) KV_SERIALIZE_POD_AS_HEX_STRING_N(varialble, #varialble) #define KV_SERIALIZE_BLOB_AS_HEX_STRING(varialble) KV_SERIALIZE_BLOB_AS_HEX_STRING_N(varialble, #varialble) diff --git a/src/currency_core/currency_basic.h b/src/currency_core/currency_basic.h index b5aa7fab..f3ba4b31 100644 --- a/src/currency_core/currency_basic.h +++ b/src/currency_core/currency_basic.h @@ -592,7 +592,7 @@ namespace currency KV_SERIALIZE(service_id) KV_SERIALIZE(instruction) KV_SERIALIZE_BLOB_AS_HEX_STRING(body) - KV_SERIALIZE_CONTAINER_POD_AS_BLOB(security) + KV_SERIALIZE_CONTAINER_POD_AS_HEX(security) KV_SERIALIZE(flags) END_KV_SERIALIZE_MAP() }; diff --git a/tests/performance_tests/main.cpp b/tests/performance_tests/main.cpp index d1a507b1..d93220b5 100644 --- a/tests/performance_tests/main.cpp +++ b/tests/performance_tests/main.cpp @@ -38,9 +38,9 @@ void test_plain_wallet() std::string res = plain_wallet::init("127.0.0.1", "12111", "C:\\Users\\roky\\home\\", 0); uint64_t instance_id = 0; - res = plain_wallet::open("test_restored.zan", "111"); - //res = plain_wallet::restore("heart level clear fate sorrow childhood sent fate ceiling party third steel came ask mix neither message already almost vast date glide tumble color okay space", - // "test_restored.zan", "111", ""); + res = plain_wallet::open("test_restored_2.zan", "111"); + //res = plain_wallet::restore("", + // "test_restored_2.zan", "111", ""); while(true) @@ -60,6 +60,10 @@ void test_plain_wallet() invoke_body = "{\"method\":\"get_recent_txs_and_info\",\"params\":{\"offset\":0,\"count\":30,\"update_provision_info\":true}}"; std::string res2 = plain_wallet::sync_call("invoke", instance_id, invoke_body); + invoke_body = "{\"method\":\"get_recent_txs_and_info2\",\"params\":{\"offset\":0,\"count\":30,\"update_provision_info\":true}}"; + res2 = plain_wallet::sync_call("invoke", instance_id, invoke_body); + + invoke_body = "{\"method\":\"getbalance\",\"params\":{}}"; std::string res3 = plain_wallet::sync_call("invoke", instance_id, invoke_body); From 737d7353a448ab614eb35556f666fe232f0bc401 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 5 Apr 2024 12:01:38 +0200 Subject: [PATCH 105/184] wallet2: minor code clean-up --- src/wallet/wallet2.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index c554e8d5..c1ddca9b 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -6952,8 +6952,6 @@ bool wallet2::expand_selection_with_zc_input(assets_selection_context& needed_mo //---------------------------------------------------------------------------------------------------- bool wallet2::select_indices_for_transfer(assets_selection_context& needed_money_map, uint64_t fake_outputs_count, std::vector& selected_indexes) { - bool res = true; - // for (auto& item : needed_money_map) { if(item.second.needed_amount == 0) @@ -6980,8 +6978,7 @@ bool wallet2::select_indices_for_transfer(assets_selection_context& needed_money } } - - return res; + return true; } //---------------------------------------------------------------------------------------------------- uint64_t wallet2::select_indices_for_transfer(std::vector& selected_indexes, free_amounts_cache_type& found_free_amounts, uint64_t needed_money, uint64_t fake_outputs_count_) @@ -7097,7 +7094,7 @@ void wallet2::add_transfer_to_transfers_cache(uint64_t amount, uint64_t index, c m_found_free_amounts[asset_id][amount].insert(index); } //---------------------------------------------------------------------------------------------------- -bool wallet2::select_transfers(assets_selection_context& needed_money_map, size_t fake_outputs_count, uint64_t dust, std::vector& selected_indicies) +bool wallet2::select_transfers(assets_selection_context& needed_money_map, size_t fake_outputs_count, uint64_t /*dust_threshold*/, std::vector& selected_indicies) { prepare_free_transfers_cache(fake_outputs_count); return select_indices_for_transfer(needed_money_map, fake_outputs_count, selected_indicies); From 92c6a9d51da0b097fbb5f89511eef1dba9f3f7bb Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 5 Apr 2024 13:56:24 +0200 Subject: [PATCH 106/184] coretests: hardfork_4_wallet_transfer_with_mandatory_mixins test added, exposing a bug where a wallet cannot spend coins before a specific sync process was done --- tests/core_tests/chaingen_main.cpp | 1 + tests/core_tests/hard_fork_4.cpp | 79 +++++++++++++++++++++++++++++- tests/core_tests/hard_fork_4.h | 9 ++++ 3 files changed, 88 insertions(+), 1 deletion(-) diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index d5f4a7cc..486237ed 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -1247,6 +1247,7 @@ int main(int argc, char* argv[]) // HF4 GENERATE_AND_PLAY_HF(hard_fork_4_consolidated_txs, "3-*"); + GENERATE_AND_PLAY_HF(hardfork_4_wallet_transfer_with_mandatory_mixins, "3-*"); // atomics GENERATE_AND_PLAY(atomic_simple_test); diff --git a/tests/core_tests/hard_fork_4.cpp b/tests/core_tests/hard_fork_4.cpp index e5b4d6b4..787caf51 100644 --- a/tests/core_tests/hard_fork_4.cpp +++ b/tests/core_tests/hard_fork_4.cpp @@ -242,4 +242,81 @@ bool hardfork_4_explicit_native_ids_in_outs::c1(currency::core& c, size_t ev_ind { return true; } -*/ \ No newline at end of file +*/ + +//------------------------------------------------------------------------------ + +hardfork_4_wallet_transfer_with_mandatory_mixins::hardfork_4_wallet_transfer_with_mandatory_mixins() +{ + REGISTER_CALLBACK_METHOD(hardfork_4_wallet_transfer_with_mandatory_mixins, c1); + REGISTER_CALLBACK_METHOD(hardfork_4_wallet_transfer_with_mandatory_mixins, configure_core); +} + +bool hardfork_4_wallet_transfer_with_mandatory_mixins::configure_core(currency::core& c, size_t ev_index, const std::vector& events) +{ + test_chain_unit_enchanced::configure_core(c, ev_index, events); // call default + currency::core_runtime_config pc = c.get_blockchain_storage().get_core_runtime_config(); + pc.hf4_minimum_mixins = CURRENCY_HF4_MANDATORY_DECOY_SET_SIZE; + c.get_blockchain_storage().set_core_runtime_config(pc); + return true; +} + +bool hardfork_4_wallet_transfer_with_mandatory_mixins::generate(std::vector& events) const +{ + /* Test outline: make sure that after HF4 a normal transfer with CURRENCY_HF4_MANDATORY_DECOY_SET_SIZE decoys goes normal. + * (It should also work prior to HF4.) + */ + + bool r = false; + + uint64_t ts = test_core_time::get_time(); + m_accounts.resize(TOTAL_ACCS_COUNT); + account_base& miner_acc = m_accounts[MINER_ACC_IDX]; miner_acc.generate(); miner_acc.set_createtime(ts); + account_base& alice_acc = m_accounts[ALICE_ACC_IDX]; alice_acc.generate(); alice_acc.set_createtime(ts); + MAKE_GENESIS_BLOCK(events, blk_0, miner_acc, ts); + DO_CALLBACK(events, "configure_core"); // necessary for the test to be run by GENERATE_AND_PLAY_HF + + REWIND_BLOCKS_N_WITH_TIME(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + + MAKE_TX(events, tx_1, miner_acc, alice_acc, MK_TEST_COINS(10), blk_0r); + MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_acc, tx_1); + + DO_CALLBACK(events, "c1"); + + return true; +} + +bool hardfork_4_wallet_transfer_with_mandatory_mixins::c1(currency::core& c, size_t ev_index, const std::vector& events) +{ + bool r = false; + std::shared_ptr alice_wlt = init_playtime_test_wallet(events, c, ALICE_ACC_IDX); + alice_wlt->refresh(); + + CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt.get(), "Alice", MK_TEST_COINS(10), 0, 0, 0, 0), false, ""); + + r = mine_next_pow_blocks_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed"); + + alice_wlt->refresh(); + + CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt.get(), "Alice", MK_TEST_COINS(10), 0, MK_TEST_COINS(10), 0, 0), false, ""); + + alice_wlt->transfer(MK_TEST_COINS(9), m_accounts[BOB_ACC_IDX].get_public_address()); + + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); + CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed"); + + std::shared_ptr bob_wlt = init_playtime_test_wallet(events, c, BOB_ACC_IDX); + bob_wlt->refresh(); + CHECK_AND_ASSERT_MES(check_balance_via_wallet(*bob_wlt.get(), "Bob", MK_TEST_COINS(9), 0, 0, 0, 0), false, ""); + + r = mine_next_pow_blocks_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed"); + + alice_wlt->refresh(); + CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt.get(), "Alice", 0, 0, 0, 0, 0), false, ""); + bob_wlt->refresh(); + CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt.get(), "Alice", MK_TEST_COINS(9), 0, MK_TEST_COINS(9), 0, 0), false, ""); + + return true; +} diff --git a/tests/core_tests/hard_fork_4.h b/tests/core_tests/hard_fork_4.h index f8235675..600a17c8 100644 --- a/tests/core_tests/hard_fork_4.h +++ b/tests/core_tests/hard_fork_4.h @@ -25,3 +25,12 @@ struct hardfork_4_explicit_native_ids_in_outs : public wallet_test mutable uint64_t m_alice_initial_balance = 0; }; + + +struct hardfork_4_wallet_transfer_with_mandatory_mixins : public wallet_test +{ + hardfork_4_wallet_transfer_with_mandatory_mixins(); + bool configure_core(currency::core& c, size_t ev_index, const std::vector& events); + bool generate(std::vector& events) const; + bool c1(currency::core& c, size_t ev_index, const std::vector& events); +}; From fa67466d2068cd7bcabc4b765a8201a24d36af73 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 5 Apr 2024 14:09:27 +0200 Subject: [PATCH 107/184] wallet2: fix an issue in prepare_tx_sources() where some transfers may be locked if there's was exception during preparing phase --- src/wallet/wallet2.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index c1ddca9b..2d3a5ceb 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -6234,10 +6234,18 @@ bool wallet2::prepare_tx_sources_for_defragmentation_tx(std::vector& sources, std::vector& selected_indicies) { - bool r = select_transfers(needed_money_map, fake_outputs_count, dust_threshold, selected_indicies); - if (!r) - return r; - return prepare_tx_sources(fake_outputs_count, sources, selected_indicies); + try + { + select_transfers(needed_money_map, fake_outputs_count, dust_threshold, selected_indicies); // always returns true, TODO consider refactoring -- sowle + return prepare_tx_sources(fake_outputs_count, sources, selected_indicies); + } + catch(...) + { + // if smth went wrong -- invalidate transfers cache to trigger its regeneration on the next use + // it is necessary because it may be in invalid state (some items might be erased within select_indices_for_transfer() or expand_selection_with_zc_input()) + m_found_free_amounts.clear(); + throw; + } } //---------------------------------------------------------------------------------------------------- void wallet2::prefetch_global_indicies_if_needed(const std::vector& selected_indicies) From a142d39fc9477413ac12e175e857c07b8a8c54c4 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 5 Apr 2024 17:20:40 +0200 Subject: [PATCH 108/184] coretests: hardfork_4_wallet_transfer_with_mandatory_mixins test fixed --- tests/core_tests/hard_fork_4.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/core_tests/hard_fork_4.cpp b/tests/core_tests/hard_fork_4.cpp index 787caf51..b8b9a3e5 100644 --- a/tests/core_tests/hard_fork_4.cpp +++ b/tests/core_tests/hard_fork_4.cpp @@ -273,6 +273,7 @@ bool hardfork_4_wallet_transfer_with_mandatory_mixins::generate(std::vectorrefresh(); CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt.get(), "Alice", 0, 0, 0, 0, 0), false, ""); bob_wlt->refresh(); - CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt.get(), "Alice", MK_TEST_COINS(9), 0, MK_TEST_COINS(9), 0, 0), false, ""); + CHECK_AND_ASSERT_MES(check_balance_via_wallet(*bob_wlt.get(), "Bob", MK_TEST_COINS(9), 0, MK_TEST_COINS(9), 0, 0), false, ""); return true; } From 0b62abbca0a4a1f0345469b1d856df62a2acd113 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Fri, 5 Apr 2024 17:00:51 +0200 Subject: [PATCH 109/184] test changes --- tests/performance_tests/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/performance_tests/main.cpp b/tests/performance_tests/main.cpp index d93220b5..eefed6c3 100644 --- a/tests/performance_tests/main.cpp +++ b/tests/performance_tests/main.cpp @@ -55,7 +55,7 @@ void test_plain_wallet() std::string invoke_body = "{\"method\":\"store\",\"params\":{}}"; - //std::string res1 = plain_wallet::sync_call("invoke", instance_id, invoke_body); + std::string res1 = plain_wallet::sync_call("invoke", instance_id, invoke_body); invoke_body = "{\"method\":\"get_recent_txs_and_info\",\"params\":{\"offset\":0,\"count\":30,\"update_provision_info\":true}}"; std::string res2 = plain_wallet::sync_call("invoke", instance_id, invoke_body); From d4b29a30b534de731b760d06141990c6fb1f39b6 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Fri, 5 Apr 2024 17:21:51 +0200 Subject: [PATCH 110/184] fixes for gcc --- contrib/epee/include/serialization/keyvalue_helpers.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/epee/include/serialization/keyvalue_helpers.h b/contrib/epee/include/serialization/keyvalue_helpers.h index 9b719103..7dc812ad 100644 --- a/contrib/epee/include/serialization/keyvalue_helpers.h +++ b/contrib/epee/include/serialization/keyvalue_helpers.h @@ -124,10 +124,10 @@ namespace epee for (const auto& item : pod_items) { res.resize(res.size() + 1); - t_pod_container_type::value_type& pod_val = res.back(); + typename t_pod_container_type::value_type& pod_val = res.back(); if (!epee::string_tools::hex_to_pod(item, pod_val)) - throw std::runtime_error(std::string("Unable to transform \"") + item + "\" to pod type " + typeid(t_pod_container_type::value_type).name()); + throw std::runtime_error(std::string("Unable to transform \"") + item + "\" to pod type " + typeid(typename t_pod_container_type::value_type).name()); } return res; } From b4ab654f119ca5538a7d5796cb0620415cca347d Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Sat, 6 Apr 2024 17:21:03 +0200 Subject: [PATCH 111/184] fixed wallet bug in calculating last available global index in zarcanum era --- src/currency_core/currency_config.h | 2 +- src/wallet/wallet2.cpp | 76 +++++++++++++++++++++++------ src/wallet/wallet2.h | 20 +++++--- 3 files changed, 76 insertions(+), 22 deletions(-) diff --git a/src/currency_core/currency_config.h b/src/currency_core/currency_config.h index 487502f4..16646940 100644 --- a/src/currency_core/currency_config.h +++ b/src/currency_core/currency_config.h @@ -250,7 +250,7 @@ #define BC_OFFERS_CURRENCY_MARKET_FILENAME "market.bin" -#define WALLET_FILE_SERIALIZATION_VERSION 165 +#define WALLET_FILE_SERIALIZATION_VERSION 166 #define WALLET_FILE_LAST_SUPPORTED_VERSION 165 #define CURRENT_MEMPOOL_ARCHIVE_VER (CURRENCY_FORMATION_VERSION+31) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index a4039a7a..37b1d069 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -523,6 +523,59 @@ void wallet2::add_rollback_event(uint64_t h, const wallet_event_t& ev) m_rollback_events.emplace_back(h, ev); } //---------------------------------------------------------------------------------------------------- +#define M_LAST_ZC_GLOBAL_INDEXS_MAX_SIZE 30 +void wallet2::add_to_last_zc_global_indexs(uint64_t h, uint64_t last_zc_output_index) +{ + //m_last_zc_global_indexs.remove_if_expiration_less_than(m_last_known_daemon_height - (WALLET_DEFAULT_TX_SPENDABLE_AGE * 2) ); + + if (m_last_zc_global_indexs.size()) + { + if (m_last_zc_global_indexs.begin()->first > h) + { + //new block added on top of last one, simply add new record + m_last_zc_global_indexs.push_front(std::make_pair(h, last_zc_output_index)); + } + else if (m_last_zc_global_indexs.begin()->first < h) + { + //looks like reorganize, pop all records before + while (m_last_zc_global_indexs.size() && m_last_zc_global_indexs.begin()->first >= h) + { + m_last_zc_global_indexs.erase(m_last_zc_global_indexs.begin()); + } + m_last_zc_global_indexs.push_front(std::make_pair(h, last_zc_output_index)); + } + else + { + //equals, same h but new last_zc_output_index, just update it, should be always bigger then prev + WLT_THROW_IF_FALSE_WITH_CODE(m_last_zc_global_indexs.begin()->second <= last_zc_output_index, + "condition m_last_zc_global_indexs.begin()->second " << m_last_zc_global_indexs.begin()->second << " <= last_zc_output_index " << last_zc_output_index << " failed", API_RETURN_CODE_INTERNAL_ERROR); + m_last_zc_global_indexs.begin()->second = last_zc_output_index; + } + } + else + { + //new block added on top of last one, simply add new record + m_last_zc_global_indexs.push_front(std::make_pair(h, last_zc_output_index)); + } + + if (m_last_zc_global_indexs.size() > M_LAST_ZC_GLOBAL_INDEXS_MAX_SIZE) + m_last_zc_global_indexs.pop_back(); +} +//---------------------------------------------------------------------------------------------------- +uint64_t wallet2::get_actual_zc_global_index() +{ + WLT_THROW_IF_FALSE_WITH_CODE(m_last_zc_global_indexs.size(), "m_last_zc_global_indexs is empty", API_RETURN_CODE_INTERNAL_ERROR); + for (auto it = m_last_zc_global_indexs.begin(); it != m_last_zc_global_indexs.end(); it++) + { + if (it->first <= m_last_known_daemon_height - WALLET_DEFAULT_TX_SPENDABLE_AGE) + { + return it->second; + } + } + WLT_THROW_IF_FALSE_WITH_CODE(false, "doesn't have anything that match expected height = " << m_last_known_daemon_height - WALLET_DEFAULT_TX_SPENDABLE_AGE, API_RETURN_CODE_INTERNAL_ERROR); + throw std::runtime_error(""); //mostly to suppress compiler warning +} +//---------------------------------------------------------------------------------------------------- void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t height, const currency::block& b, const std::vector* pglobal_indexes) { //check for transaction spends @@ -540,11 +593,7 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t { if (pglobal_indexes->size()) { - //store global index that is under coinage, so we can used in decoy selection algo - if (ptc.height < m_last_known_daemon_height && m_last_known_daemon_height - ptc.height > WALLET_DEFAULT_TX_SPENDABLE_AGE) - { - m_last_zc_global_index = pglobal_indexes->back(); - } + add_to_last_zc_global_indexs(ptc.height, pglobal_indexes->back()); } } @@ -6224,13 +6273,6 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count_, std::vector= zarcanum_start_from) - { - //in Zarcanum era - //const uint64_t test_scale_size = current_size - 1 - zarcanum_start_from; - zarcanum_decoy_set_generator.init(m_last_zc_global_index); - } bool need_to_request = fake_outputs_count != 0; COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request req = AUTO_VAL_INIT(req); @@ -6256,7 +6298,7 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count_, std::vectorm_global_output_index); + build_distribution_for_input(rdisttib.global_offsets, it->m_global_output_index); need_to_request = true; } else @@ -6474,12 +6516,16 @@ void wallet2::select_decoys(currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS amount_entry.outs = local_outs; } //---------------------------------------------------------------------------------------------------------------- -void wallet2::build_distribution_for_input(decoy_selection_generator& zarcanum_decoy_set_generator, std::vector& offsets, uint64_t own_index) +void wallet2::build_distribution_for_input(std::vector& offsets, uint64_t own_index) { + decoy_selection_generator zarcanum_decoy_set_generator; + zarcanum_decoy_set_generator.init(get_actual_zc_global_index()); + THROW_IF_FALSE_WALLET_INT_ERR_EX(zarcanum_decoy_set_generator.is_initialized(), "zarcanum_decoy_set_generator are not initialized"); if (m_core_runtime_config.hf4_minimum_mixins) { - offsets = zarcanum_decoy_set_generator.generate_unique_reversed_distribution(m_last_zc_global_index - 1 > WALLET_FETCH_RANDOM_OUTS_SIZE ? WALLET_FETCH_RANDOM_OUTS_SIZE: m_last_zc_global_index - 1, own_index); + uint64_t actual_zc_index = get_actual_zc_global_index(); + offsets = zarcanum_decoy_set_generator.generate_unique_reversed_distribution(actual_zc_index - 1 > WALLET_FETCH_RANDOM_OUTS_SIZE ? WALLET_FETCH_RANDOM_OUTS_SIZE : actual_zc_index - 1, own_index); } } //---------------------------------------------------------------------------------------------------------------- diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 28b1fbd8..9bb4676a 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -148,9 +148,7 @@ namespace tools std::unordered_map m_pending_key_images; // (out_pk -> ki) pairs of change outputs to be added in watch-only wallet without spend sec key uint64_t m_last_pow_block_h = 0; std::list> m_rollback_events; - uint64_t m_last_zc_global_index = 0; - - + std::list > m_last_zc_global_indexs; // , biggest height comes in front //variables that not being serialized std::atomic m_last_bc_timestamp = 0; @@ -223,7 +221,16 @@ namespace tools a & m_rollback_events; a & m_whitelisted_assets; a & m_use_assets_whitelisting; - a & m_last_zc_global_index; + if (ver <= 165) + { + uint64_t last_zc_global_index = 0; + a& last_zc_global_index; + m_last_zc_global_indexs.push_back(std::make_pair(uint64_t(0), last_zc_global_index)); + } + else + { + a& m_last_zc_global_indexs; + } } }; @@ -762,7 +769,8 @@ private: void handle_money(const currency::block& b, const process_transaction_context& tx_process_context); void load_wti_from_process_transaction_context(wallet_public::wallet_transfer_info& wti, const process_transaction_context& tx_process_context); bool process_payment_id_for_wti(wallet_public::wallet_transfer_info& wti, const process_transaction_context& tx_process_context); - + void add_to_last_zc_global_indexs(uint64_t h, uint64_t last_zc_output_index); + uint64_t get_actual_zc_global_index(); void handle_pulled_blocks(size_t& blocks_added, std::atomic& stop, currency::COMMAND_RPC_GET_BLOCKS_DIRECT::response& blocks); std::string get_alias_for_address(const std::string& addr); @@ -868,7 +876,7 @@ private: void remove_transfer_from_amount_gindex_map(uint64_t tid); uint64_t get_alias_cost(const std::string& alias); detail::split_strategy_id_t get_current_split_strategy(); - void build_distribution_for_input(decoy_selection_generator& zarcanum_decoy_set_generator, std::vector& offsets, uint64_t own_index); + void build_distribution_for_input(std::vector& offsets, uint64_t own_index); void select_decoys(currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount & amount_entry, uint64_t own_g_index); static void wti_to_csv_entry(std::ostream& ss, const wallet_public::wallet_transfer_info& wti, size_t index); From e422b42ba635aa956a95d178aae7f5d6d4c77cee Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Sat, 6 Apr 2024 17:22:44 +0200 Subject: [PATCH 112/184] fixes in lang tools --- contrib/epee/include/misc_language.h | 61 ++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/contrib/epee/include/misc_language.h b/contrib/epee/include/misc_language.h index ecf6677e..10033990 100644 --- a/contrib/epee/include/misc_language.h +++ b/contrib/epee/include/misc_language.h @@ -560,11 +560,72 @@ namespace misc_utils { while(m_expirations.size() && m_expirations.begin()->first < e) { + m_set.erase(m_expirations.begin()->second); m_expirations.erase(m_expirations.begin()); } } }; + template + struct expirating_map + { + typedef std::map main_map; + main_map m_map; + std::multimap m_expirations; + + const main_map& get_map() + { + return m_map; + } + void add(const key& k, const value_type& v, const expiration_type& e) + { + auto res = m_map.insert(k, v); + m_expirations.insert({ e, res.first }); + } + + void remove_if_expiration_less_than(const expiration_type& e) + { + while (m_expirations.size() && m_expirations.begin()->first < e) + { + m_map.erase(m_expirations.begin()->second) + m_expirations.erase(m_expirations.begin()); + } + } + + template + inline void serialize(t_archive& a, const unsigned int ver) + { + std::vector > items; + if constexpr (t_archive::is_saving::value) + { + for (const auto& item: m_expirations) + { + items.resize(items.size + 1); + std::get<2>(items.back()) = item.first; + std::get<0>(items.back()) = item.second.first; + std::get<1>(items.back()) = item.second.second; + } + } + a & items; + + if constexpr (!t_archive::is_saving::value) + { + for (const auto& item : items) + { + this->add(std::get<0>(item), std::get<1>(item), std::get<2>(item)); + + + items.resize(items.size + 1); + std::get<2>(items.back()) = item.first; + std::get<0>(items.back()) = item.second.first; + std::get<1>(items.back()) = item.second.second; + } + } + + } + + }; + } // namespace misc_utils } // namespace epee From a2307d45fdf2f77bd44eb29c53b52dfae76e9fed Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Sat, 6 Apr 2024 18:54:02 +0200 Subject: [PATCH 113/184] fixed broken compilation --- contrib/epee/include/misc_language.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/epee/include/misc_language.h b/contrib/epee/include/misc_language.h index 10033990..3ee7001e 100644 --- a/contrib/epee/include/misc_language.h +++ b/contrib/epee/include/misc_language.h @@ -587,7 +587,7 @@ namespace misc_utils { while (m_expirations.size() && m_expirations.begin()->first < e) { - m_map.erase(m_expirations.begin()->second) + m_map.erase(m_expirations.begin()->second); m_expirations.erase(m_expirations.begin()); } } From 63d4bde2d98b64bc03ab31a12826fad50a932a2a Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Sat, 6 Apr 2024 19:23:19 +0200 Subject: [PATCH 114/184] removed seed phrase from open wallet response --- src/wallet/view_iface.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wallet/view_iface.h b/src/wallet/view_iface.h index dce4b5ee..45ba36e8 100644 --- a/src/wallet/view_iface.h +++ b/src/wallet/view_iface.h @@ -451,7 +451,7 @@ public: uint64_t wallet_id; transfers_array recent_history; wallet_info wi; - std::string seed; + //std::string seed; bool recovered; uint64_t wallet_local_bc_size; uint64_t wallet_file_size; @@ -462,7 +462,7 @@ public: KV_SERIALIZE(wallet_id) KV_SERIALIZE(recent_history) KV_SERIALIZE(wi) - KV_SERIALIZE(seed) + //KV_SERIALIZE(seed) KV_SERIALIZE(recovered) KV_SERIALIZE(wallet_local_bc_size) KV_SERIALIZE(wallet_file_size) From 7f0b99c25e7443599ca9660e18384d9ad3e8510f Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Sun, 7 Apr 2024 16:43:55 +0200 Subject: [PATCH 115/184] another good iteration on auto documenting feature --- .../include/net/http_server_handlers_map2.h | 4 +- .../serialization/keyvalue_serialization.h | 45 ++++++++++++++----- .../keyvalue_serialization_overloads.h | 10 ++--- src/currency_core/currency_basic.h | 18 ++++---- src/daemon/daemon.cpp | 10 ++--- src/rpc/core_rpc_server_commands_defs.h | 12 ++--- src/simplewallet/simplewallet.cpp | 25 ++++++++++- src/wallet/view_iface.h | 4 +- src/wallet/wallet_public_structs_defs.h | 16 +++---- src/wallet/wallets_manager.cpp | 2 +- 10 files changed, 95 insertions(+), 51 deletions(-) diff --git a/contrib/epee/include/net/http_server_handlers_map2.h b/contrib/epee/include/net/http_server_handlers_map2.h index a8888983..0200b558 100644 --- a/contrib/epee/include/net/http_server_handlers_map2.h +++ b/contrib/epee/include/net/http_server_handlers_map2.h @@ -66,8 +66,8 @@ bool auto_doc_t(const std::string& prefix_name, std::string& generate_reference) std::stringstream ss; ss << prefix_name << ENDL - << "REQUEST: " << ENDL << req_str << ENDL << "--------------------------------" << ENDL - << "RESPONSE: " << ENDL << res_str << ENDL << "################################" << ENDL; + << "REQUEST: " << ENDL << req_str << ENDL << req_str_descr << "--------------------------------" << ENDL + << "RESPONSE: " << ENDL << res_str << ENDL << res_str_descr << "################################" << ENDL; generate_reference += ss.str(); return true; } diff --git a/contrib/epee/include/serialization/keyvalue_serialization.h b/contrib/epee/include/serialization/keyvalue_serialization.h index 317944ca..d350eda0 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization.h +++ b/contrib/epee/include/serialization/keyvalue_serialization.h @@ -65,17 +65,33 @@ public: \ static bool serialize_map(this_type& this_ref, t_storage& stg, typename t_storage::hsection hparent_section) \ { + +#define KV_CAT_(a, b) a ## b +#define KV_CAT(a, b) KV_CAT_(a, b) +#define VARNAME(Var) KV_CAT(Var, __LINE__) + +#define KV_MAKE_ALIAS_NAME() VARNAME(alias_tmp_name) +#define KV_MAKE_VAR_NAME() VARNAME(val_tmp_name) + #define KV_SERIALIZE_N(varialble, val_name) \ + using KV_MAKE_ALIAS_NAME() = decltype(this_ref.varialble); \ + const char* KV_MAKE_VAR_NAME() = val_name;\ epee::serialization::selector::serialize(this_ref.varialble, stg, hparent_section, val_name); -#define KV_SERIALIZE_N_DOC(varialble, val_name) \ - { using var_type = decltype(this_ref.varialble); \ - epee::serialization::selector::serialize(this_ref.varialble, stg, hparent_section, val_name); \ - if constexpr (t_storage::use_descriptions::value) \ - { \ - epee::serialization::selector::template serialize_and_doc(stg, hparent_section, val_name +//#define KV_SERIALIZE_N_DOC(varialble, val_name) \ +// using KV_MAKE_ALIAS_NAME() = decltype(this_ref.varialble); \ +// epee::serialization::selector::serialize(this_ref.varialble, stg, hparent_section, val_name); \ +// if constexpr (t_storage::use_descriptions::value) \ +// { \ +// epee::serialization::selector::template serialize_and_doc(stg, hparent_section, val_name + -/* +#define DOC_DSCR(description) if constexpr (t_storage::use_descriptions::value) \ + { \ + epee::serialization::selector::template serialize_and_doc(stg, hparent_section, KV_MAKE_VAR_NAME(), description + + + /* {using var_type = decltype(this_ref.varialble); \ epee::serialization::selector::serialize(this_ref.varialble, stg, hparent_section, val_name); \ if constexpr (t_storage::use_descriptions::value) \ @@ -84,15 +100,16 @@ public: \ } \ } */ -#define DOC_DSCR(description) , description + +//#define DOC_DSCR(description) , description #define DOC_EXMP(substitute) , substitute -#define DOC_EXMP_AUTO_1(arg_1) , var_type(arg_1) -#define DOC_EXMP_AUTO_2(arg_1, arg_2) , var_type(arg_1, arg_2) -#define DOC_END ); } } +#define DOC_EXMP_AUTO_1(arg_1) , KV_MAKE_ALIAS_NAME() (arg_1) +#define DOC_EXMP_AUTO_2(arg_1, arg_2) , KV_MAKE_ALIAS_NAME() (arg_1, arg_2) +#define DOC_END ); } -#define DOC_EXMP_AUTO(...) , epee::create_t_object(__VA_ARGS__) +#define DOC_EXMP_AUTO(...) , epee::create_t_object(__VA_ARGS__) // Function template to create an object with forwarded constructor arguments @@ -109,9 +126,13 @@ public: \ #define KV_SERIALIZE_CUSTOM_N(varialble, stored_type, from_v_to_stored, from_stored_to_v, val_name) \ + using KV_MAKE_ALIAS_NAME() = stored_type; \ + const char* VARNAME(val_tmp_name) = val_name;\ epee::serialization::selector::template serialize_custom(this_ref.varialble, stg, hparent_section, val_name, from_v_to_stored, from_stored_to_v); #define KV_SERIALIZE_EPHEMERAL_N(stored_type, from_v_to_stored, val_name) \ + using KV_MAKE_ALIAS_NAME() = stored_type; \ + const char* VARNAME(val_tmp_name) = val_name;\ epee::serialization::selector::template serialize_ephemeral(this_ref, stg, hparent_section, val_name, from_v_to_stored); diff --git a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h index 933935b2..cb88897f 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h +++ b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h @@ -317,12 +317,12 @@ namespace epee template static bool serialize(const t_type& d, t_storage& stg, [[maybe_unused]] typename t_storage::hsection hparent_section, [[maybe_unused]] const char* pname) { - if constexpr (!t_storage::use_descriptions::value) - { + //if constexpr (!t_storage::use_descriptions::value) + //{ return kv_serialize(d, stg, hparent_section, pname); - } - else - return false; + //} + //else + // return false; } //const t_type& doc_substitute = t_type(), const std::string& description = std::string() diff --git a/src/currency_core/currency_basic.h b/src/currency_core/currency_basic.h index f3ba4b31..85b65544 100644 --- a/src/currency_core/currency_basic.h +++ b/src/currency_core/currency_basic.h @@ -732,14 +732,14 @@ namespace currency END_BOOST_SERIALIZATION() BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(total_max_supply) - KV_SERIALIZE(current_supply) - KV_SERIALIZE(decimal_point) - KV_SERIALIZE(ticker) - KV_SERIALIZE(full_name) - KV_SERIALIZE(meta_info) - KV_SERIALIZE_POD_AS_HEX_STRING(owner) - KV_SERIALIZE(hidden_supply) + KV_SERIALIZE(total_max_supply) DOC_DSCR("Maximum possible supply for given asset, can't be changed after deployment") DOC_EXMP(1000000000000000000) DOC_END + KV_SERIALIZE(current_supply) DOC_DSCR("Currently emitted supply for given asset") DOC_EXMP(500000000000000000) DOC_END + KV_SERIALIZE(decimal_point) DOC_DSCR("Decimal point") DOC_EXMP(12) DOC_END + KV_SERIALIZE(ticker) DOC_DSCR("Ticker associated with asset") DOC_EXMP("ZUSD") DOC_END + KV_SERIALIZE(full_name) DOC_DSCR("Full name of the asset") DOC_EXMP("Zano wrapped USD") DOC_END + KV_SERIALIZE(meta_info) DOC_DSCR("Any other information assetiaded with asset in a free form") DOC_EXMP("Stable and private") DOC_END + KV_SERIALIZE_POD_AS_HEX_STRING(owner) DOC_DSCR("Owner's key, used to validate any operations on the asset altering, could be changed in case of transfer ownership") DOC_EXMP("f74bb56a5b4fa562e679ccaadd697463498a66de4f1760b2cd40f11c3a00a7a8") DOC_END + KV_SERIALIZE(hidden_supply) DOC_DSCR("This one reserved for future use, will be documented later") DOC_END END_KV_SERIALIZE_MAP() }; @@ -757,7 +757,7 @@ namespace currency BEGIN_KV_SERIALIZE_MAP() KV_CHAIN_BASE(asset_descriptor_base) - KV_SERIALIZE_POD_AS_HEX_STRING(asset_id) + KV_SERIALIZE_POD_AS_HEX_STRING(asset_id) DOC_DSCR("Asset ID") DOC_EXMP("f74bb56a5b4fa562e679ccaadd697463498a66de4f1760b2cd40f11c3a00a7a8") DOC_END END_KV_SERIALIZE_MAP() }; diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index 004da0b8..2be409f2 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -281,12 +281,12 @@ int main(int argc, char* argv[]) std::string generate_reference = std::string("RPC_COMMANDS_LIST:\n"); bool call_found = false; rpc_server.handle_http_request_map(query_info, response_info, conn_context, call_found, generate_reference); - std::string json_rpc_reference; - query_info.m_URI = JSON_RPC_REFERENCE_MARKER; - query_info.m_body = "{\"jsonrpc\": \"2.0\", \"method\": \"nonexisting_method\", \"params\": {}},"; - rpc_server.handle_http_request_map(query_info, response_info, conn_context, call_found, json_rpc_reference); + //std::string json_rpc_reference; + //query_info.m_URI = JSON_RPC_REFERENCE_MARKER; + //query_info.m_body = "{\"jsonrpc\": \"2.0\", \"method\": \"nonexisting_method\", \"params\": {}},"; + //rpc_server.handle_http_request_map(query_info, response_info, conn_context, call_found, json_rpc_reference); - LOG_PRINT_L0(generate_reference << ENDL << "----------------------------------------" << ENDL << json_rpc_reference); + LOG_PRINT_L0(generate_reference); return 0; } diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index f45128fc..945846e7 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -152,12 +152,12 @@ namespace currency std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_DOC(height) DOC_DSCR("Some height of the block") DOC_EXMP(11111) DOC_END - KV_SERIALIZE_DOC(status) DOC_DSCR("Status of the operation") DOC_EXMP("OK") DOC_END + KV_SERIALIZE(height) DOC_DSCR("Some height of the block") DOC_EXMP(11111) DOC_END + KV_SERIALIZE(status) DOC_DSCR("Status of the operation") DOC_EXMP("OK") DOC_END END_KV_SERIALIZE_MAP() }; }; - + template struct COMMAND_RPC_GET_BLOCKS_FAST_T @@ -212,9 +212,9 @@ namespace currency std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_DOC(txs_as_hex) DOC_DSCR("Transactions stored as blobs") DOC_EXMP_AUTO(1, "7d914497d91442f8f3c2268397d914497d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc2f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc") DOC_END - KV_SERIALIZE_DOC(missed_tx) DOC_DSCR("Missed transactions hashes") DOC_EXMP_AUTO(1, "97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc") DOC_END - KV_SERIALIZE_DOC(status) DOC_DSCR("Command response status") DOC_EXMP_AUTO("OK") DOC_END + KV_SERIALIZE(txs_as_hex) DOC_DSCR("Transactions stored as blobs") DOC_EXMP_AUTO(1, "7d914497d91442f8f3c2268397d914497d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc2f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc") DOC_END + KV_SERIALIZE(missed_tx) DOC_DSCR("Missed transactions hashes") DOC_EXMP_AUTO(1, "97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc") DOC_END + KV_SERIALIZE(status) DOC_DSCR("Command response status") DOC_EXMP_AUTO("OK") DOC_END END_KV_SERIALIZE_MAP() }; }; diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index a69bed93..e4375a56 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -2807,7 +2807,7 @@ int main(int argc, char* argv[]) command_line::add_arg(desc_params, arg_set_timeout); command_line::add_arg(desc_params, arg_voting_config_file); command_line::add_arg(desc_params, arg_no_password_confirmations); - + command_line::add_arg(desc_params, command_line::arg_show_rpc_autodoc); tools::wallet_rpc_server::init_options(desc_params); @@ -2863,6 +2863,29 @@ int main(int argc, char* argv[]) } + if (command_line::get_arg(vm, command_line::arg_show_rpc_autodoc)) + { + LOG_PRINT_L0("Dumping RPC auto-generated documents!"); + epee::net_utils::http::http_request_info query_info; + epee::net_utils::http::http_response_info response_info; + epee::net_utils::connection_context_base conn_context; + std::string generate_reference = std::string("WALLET_RPC_COMMANDS_LIST:\n"); + bool call_found = false; + tools::wallet_rpc_server wallet_rpc_server(std::shared_ptr(new tools::wallet2())); + //wallet_rpc_server.handle_http_request_map(query_info, response_info, conn_context, call_found, generate_reference); + + std::string json_rpc_reference = generate_reference; + query_info.m_URI = JSON_RPC_REFERENCE_MARKER; + query_info.m_body = "{\"jsonrpc\": \"2.0\", \"method\": \"nonexisting_method\", \"params\": {}},"; + wallet_rpc_server.handle_http_request_map(query_info, response_info, conn_context, call_found, json_rpc_reference); + + + LOG_PRINT_L0(json_rpc_reference); + + return 0; + } + + if (command_line::has_arg(vm, arg_scan_for_wallet)) { log_space::log_singletone::add_logger(LOGGER_CONSOLE, nullptr, nullptr, LOG_LEVEL_4); diff --git a/src/wallet/view_iface.h b/src/wallet/view_iface.h index 45ba36e8..dce4b5ee 100644 --- a/src/wallet/view_iface.h +++ b/src/wallet/view_iface.h @@ -451,7 +451,7 @@ public: uint64_t wallet_id; transfers_array recent_history; wallet_info wi; - //std::string seed; + std::string seed; bool recovered; uint64_t wallet_local_bc_size; uint64_t wallet_file_size; @@ -462,7 +462,7 @@ public: KV_SERIALIZE(wallet_id) KV_SERIALIZE(recent_history) KV_SERIALIZE(wi) - //KV_SERIALIZE(seed) + KV_SERIALIZE(seed) KV_SERIALIZE(recovered) KV_SERIALIZE(wallet_local_bc_size) KV_SERIALIZE(wallet_file_size) diff --git a/src/wallet/wallet_public_structs_defs.h b/src/wallet/wallet_public_structs_defs.h index 8089fa71..61538912 100644 --- a/src/wallet/wallet_public_structs_defs.h +++ b/src/wallet/wallet_public_structs_defs.h @@ -312,10 +312,10 @@ namespace wallet_public //v2 BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(total) - KV_SERIALIZE(unlocked) - KV_SERIALIZE(awaiting_in) - KV_SERIALIZE(awaiting_out) + KV_SERIALIZE(total) DOC_DSCR("Total coins available(including locked)") DOC_EXMP(100000000000000) DOC_END + KV_SERIALIZE(unlocked) DOC_DSCR("Unlocked coins available(the ones that could be used right now)") DOC_EXMP(50000000000000) DOC_END + KV_SERIALIZE(awaiting_in) DOC_DSCR("Unconfirmed amount for receive") DOC_EXMP(1000000000000) DOC_END + KV_SERIALIZE(awaiting_out) DOC_DSCR("Unconfirmed amount for send") DOC_EXMP(2000000000000) DOC_END END_KV_SERIALIZE_MAP() }; @@ -324,7 +324,7 @@ namespace wallet_public currency::asset_descriptor_with_id asset_info; //v2 BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(asset_info) + KV_SERIALIZE(asset_info) DOC_DSCR("Asset info details") DOC_END KV_CHAIN_BASE(asset_balance_entry_base) END_KV_SERIALIZE_MAP() }; @@ -403,9 +403,9 @@ namespace wallet_public std::list balances; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(balance) - KV_SERIALIZE(unlocked_balance) - KV_SERIALIZE(balances) + KV_SERIALIZE(balance) DOC_DSCR("Native coins total amount") DOC_EXMP(10000000000) DOC_END + KV_SERIALIZE(unlocked_balance) DOC_DSCR("Native coins total unlocked amount") DOC_EXMP(11000000000) DOC_END + KV_SERIALIZE(balances) DOC_DSCR("Balances groupped by it's asset_id") DOC_EXMP_AUTO(1) DOC_END END_KV_SERIALIZE_MAP() }; }; diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index ba2635f5..1e1ab4a0 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -1078,7 +1078,7 @@ std::string wallets_manager::open_wallet(const std::wstring& path, const std::st owr.wallet_local_bc_size = w->get_blockchain_current_size(); //workaround for missed fee - //owr.seed = w->get_account().get_seed_phrase(); + owr.seed = w->get_account().get_seed_phrase(""); break; } catch (const tools::error::file_not_found& /**/) From eddc3091a7b1370fbcc493447b41dce2054fcdbd Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 8 Apr 2024 13:52:03 +0200 Subject: [PATCH 116/184] ui update --- src/gui/qt-daemon/layout | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/qt-daemon/layout b/src/gui/qt-daemon/layout index 49aaf057..3b816edf 160000 --- a/src/gui/qt-daemon/layout +++ b/src/gui/qt-daemon/layout @@ -1 +1 @@ -Subproject commit 49aaf057dcea6c28f7eb6cd63f25d2d14fde8a3e +Subproject commit 3b816edf2da54c8df55e871a8005ac575ccb5dcd From b8cc8818ee035e22ba87f3dbd60f8c5bc910e9ee Mon Sep 17 00:00:00 2001 From: zano build machine Date: Mon, 8 Apr 2024 14:54:06 +0300 Subject: [PATCH 117/184] === build number: 295 -> 296 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index 291d51c9..83bbe615 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 295 +#define PROJECT_VERSION_BUILD_NO 296 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From 7be88657551ed11c11ab3ebc31a269c4041cefb9 Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 8 Apr 2024 18:31:06 +0200 Subject: [PATCH 118/184] wallet2: fixed add_to_last_zc_global_indexs() --- src/wallet/wallet2.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 6fc49d2e..964d2e76 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -504,16 +504,14 @@ void wallet2::add_rollback_event(uint64_t h, const wallet_event_t& ev) #define M_LAST_ZC_GLOBAL_INDEXS_MAX_SIZE 30 void wallet2::add_to_last_zc_global_indexs(uint64_t h, uint64_t last_zc_output_index) { - //m_last_zc_global_indexs.remove_if_expiration_less_than(m_last_known_daemon_height - (WALLET_DEFAULT_TX_SPENDABLE_AGE * 2) ); - if (m_last_zc_global_indexs.size()) { - if (m_last_zc_global_indexs.begin()->first > h) + if (h > m_last_zc_global_indexs.begin()->first) { //new block added on top of last one, simply add new record m_last_zc_global_indexs.push_front(std::make_pair(h, last_zc_output_index)); } - else if (m_last_zc_global_indexs.begin()->first < h) + else if (h < m_last_zc_global_indexs.begin()->first) { //looks like reorganize, pop all records before while (m_last_zc_global_indexs.size() && m_last_zc_global_indexs.begin()->first >= h) From 19eb7baaa231cb6daee624661f5fdb324e4d2495 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Mon, 8 Apr 2024 19:33:30 +0300 Subject: [PATCH 119/184] === build number: 296 -> 297 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index 83bbe615..19b7c316 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 296 +#define PROJECT_VERSION_BUILD_NO 297 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From 021fbb7d378bcd6834dec0c65140f2e5b6f01a61 Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 9 Apr 2024 21:43:13 +0200 Subject: [PATCH 120/184] coretests: added test hardfork_4_wallet_sweep_bare_outs which exposes a bug in sweep_bare_outs() where it fails if there's not enough decoys --- tests/core_tests/chaingen.cpp | 22 ++++-- tests/core_tests/chaingen_main.cpp | 1 + tests/core_tests/hard_fork_4.cpp | 118 +++++++++++++++++++++++++++++ tests/core_tests/hard_fork_4.h | 8 ++ 4 files changed, 143 insertions(+), 6 deletions(-) diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index 73340589..5ab4bf0e 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -2319,15 +2319,25 @@ bool check_ring_signature_at_gen_time(const std::vector& event bool check_mixin_value_for_each_input(size_t mixin, const crypto::hash& tx_id, currency::core& c) { - std::shared_ptr ptce = c.get_blockchain_storage().get_tx_chain_entry(tx_id); - if (!ptce) - return false; + transaction tx_local; + const transaction* ptx = &tx_local; - for (size_t i = 0; i < ptce->tx.vin.size(); ++i) + std::shared_ptr ptce = c.get_blockchain_storage().get_tx_chain_entry(tx_id); + if (ptce) { - auto& input = ptce->tx.vin[i]; + ptx = &ptce->tx; + } + else + { + if (!c.get_tx_pool().get_transaction(tx_id, tx_local)) + return false; + } + + for (size_t i = 0; i < ptx->vin.size(); ++i) + { + auto& input = ptx->vin[i]; const std::vector& key_offsets = get_key_offsets_from_txin_v(input); - CHECK_AND_ASSERT_MES(key_offsets.size() == mixin + 1, false, "for input #" << i << " mixin count is " << key_offsets.size() - 1 << ", expected is " << mixin); + CHECK_AND_ASSERT_MES(key_offsets.size() == mixin + 1, false, "for input #" << i << " ring size is " << key_offsets.size() << ", mixin count is " << key_offsets.size() - 1 << ", expected mixin count is " << mixin); } return true; diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index 486237ed..01f5c9cc 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -1248,6 +1248,7 @@ int main(int argc, char* argv[]) // HF4 GENERATE_AND_PLAY_HF(hard_fork_4_consolidated_txs, "3-*"); GENERATE_AND_PLAY_HF(hardfork_4_wallet_transfer_with_mandatory_mixins, "3-*"); + GENERATE_AND_PLAY(hardfork_4_wallet_sweep_bare_outs); // atomics GENERATE_AND_PLAY(atomic_simple_test); diff --git a/tests/core_tests/hard_fork_4.cpp b/tests/core_tests/hard_fork_4.cpp index b8b9a3e5..2349167d 100644 --- a/tests/core_tests/hard_fork_4.cpp +++ b/tests/core_tests/hard_fork_4.cpp @@ -321,3 +321,121 @@ bool hardfork_4_wallet_transfer_with_mandatory_mixins::c1(currency::core& c, siz return true; } + +//------------------------------------------------------------------------------ + +hardfork_4_wallet_sweep_bare_outs::hardfork_4_wallet_sweep_bare_outs() +{ + REGISTER_CALLBACK_METHOD(hardfork_4_wallet_sweep_bare_outs, c1); + + m_hardforks.set_hardfork_height(ZANO_HARDFORK_04_ZARCANUM, 10); +} + +bool hardfork_4_wallet_sweep_bare_outs::generate(std::vector& events) const +{ + // Test idea: make sure wallet2::sweep_bare_outs works well even if there's not enough outputs to mix + + uint64_t ts = test_core_time::get_time(); + m_accounts.resize(TOTAL_ACCS_COUNT); + account_base& miner_acc = m_accounts[MINER_ACC_IDX]; miner_acc.generate(); miner_acc.set_createtime(ts); + account_base& alice_acc = m_accounts[ALICE_ACC_IDX]; alice_acc.generate(); alice_acc.set_createtime(ts); + account_base& bob_acc = m_accounts[BOB_ACC_IDX]; bob_acc.generate(); bob_acc.set_createtime(ts); + + MAKE_GENESIS_BLOCK(events, blk_0, miner_acc, ts); + + // rebuild genesis miner tx + std::vector destinations; + destinations.emplace_back(MK_TEST_COINS(23), alice_acc.get_public_address()); + destinations.emplace_back(MK_TEST_COINS(23), bob_acc.get_public_address()); + destinations.emplace_back(MK_TEST_COINS(55), bob_acc.get_public_address()); // this output is unique and doesn't have decoys + for (size_t i = 0; i < 10; ++i) + destinations.emplace_back(MK_TEST_COINS(23), miner_acc.get_public_address()); // decoys (later Alice will spend her output using mixins) + destinations.emplace_back(COIN, miner_acc.get_public_address()); // leftover amount will be also send to the last destination + CHECK_AND_ASSERT_MES(replace_coinbase_in_genesis_block(destinations, generator, events, blk_0), false, ""); + + DO_CALLBACK(events, "configure_core"); // default configure_core callback will initialize core runtime config with m_hardforks + REWIND_BLOCKS_N(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 1); + + DO_CALLBACK_PARAMS(events, "check_hardfork_active", static_cast(ZANO_HARDFORK_04_ZARCANUM)); + + DO_CALLBACK(events, "c1"); + + return true; +} + +bool hardfork_4_wallet_sweep_bare_outs::c1(currency::core& c, size_t ev_index, const std::vector& events) +{ + bool r = false; + std::shared_ptr alice_wlt = init_playtime_test_wallet(events, c, ALICE_ACC_IDX); + alice_wlt->refresh(); + CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt.get(), "Alice", MK_TEST_COINS(23), UINT64_MAX, MK_TEST_COINS(23), 0, 0), false, ""); + + std::shared_ptr bob_wlt = init_playtime_test_wallet(events, c, BOB_ACC_IDX); + bob_wlt->refresh(); + CHECK_AND_ASSERT_MES(check_balance_via_wallet(*bob_wlt.get(), "Bob", MK_TEST_COINS(23 + 55), UINT64_MAX, MK_TEST_COINS(23 + 55), 0, 0), false, ""); + + CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count()); + + // 1. Try to sweep bare out for Alice (enough decoys to mix with) + std::vector tids_grouped_by_txs; + CHECK_AND_ASSERT_MES(alice_wlt->get_bare_unspent_outputs_stats(tids_grouped_by_txs), false, ""); + size_t total_txs_sent = 0; + uint64_t total_amount_sent = 0; + uint64_t total_fee_spent = 0; + uint64_t total_bare_outs_sent = 0; + CHECK_AND_ASSERT_MES(alice_wlt->sweep_bare_unspent_outputs(m_accounts[ALICE_ACC_IDX].get_public_address(), tids_grouped_by_txs, total_txs_sent, total_amount_sent, total_fee_spent, total_bare_outs_sent), false, ""); + + CHECK_V_EQ_EXPECTED_AND_ASSERT(total_txs_sent, 1); + CHECK_V_EQ_EXPECTED_AND_ASSERT(total_amount_sent, MK_TEST_COINS(23)); + CHECK_V_EQ_EXPECTED_AND_ASSERT(total_fee_spent, TESTS_DEFAULT_FEE); + CHECK_V_EQ_EXPECTED_AND_ASSERT(total_bare_outs_sent, 1); + + CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count()); + + std::list txs; + c.get_pool_transactions(txs); + auto& tx = txs.back(); + CHECK_AND_ASSERT_MES(check_mixin_value_for_each_input(CURRENCY_DEFAULT_DECOY_SET_SIZE, get_transaction_hash(tx), c), false, ""); + + r = mine_next_pow_blocks_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed"); + + CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count()); + + alice_wlt->refresh(); + CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt.get(), "Alice", MK_TEST_COINS(23) - TESTS_DEFAULT_FEE, UINT64_MAX, MK_TEST_COINS(23) - TESTS_DEFAULT_FEE, 0, 0), false, ""); + + + // 2. Try to sweep bare out for Bob (not enough decoys to mix with) + tids_grouped_by_txs.clear(); + CHECK_AND_ASSERT_MES(bob_wlt->get_bare_unspent_outputs_stats(tids_grouped_by_txs), false, ""); + CHECK_AND_ASSERT_MES(bob_wlt->sweep_bare_unspent_outputs(m_accounts[BOB_ACC_IDX].get_public_address(), tids_grouped_by_txs, total_txs_sent, total_amount_sent, total_fee_spent, total_bare_outs_sent), false, ""); + + CHECK_V_EQ_EXPECTED_AND_ASSERT(total_txs_sent, 1); + CHECK_V_EQ_EXPECTED_AND_ASSERT(total_amount_sent, MK_TEST_COINS(23 + 55)); + CHECK_V_EQ_EXPECTED_AND_ASSERT(total_fee_spent, TESTS_DEFAULT_FEE); + CHECK_V_EQ_EXPECTED_AND_ASSERT(total_bare_outs_sent, 2); + + CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count()); + + txs.clear(); + c.get_pool_transactions(txs); + auto& tx2 = txs.back(); + CHECK_V_EQ_EXPECTED_AND_ASSERT(tx2.vin.size(), 2); + + const txin_to_key &input_with_enough_decoys = boost::get(tx2.vin[0]).amount == MK_TEST_COINS(23) ? boost::get(tx2.vin[0]) : boost::get(tx2.vin[1]); + const txin_to_key &input_with_not_enough_decoys = boost::get(tx2.vin[0]).amount == MK_TEST_COINS(23) ? boost::get(tx2.vin[1]) : boost::get(tx2.vin[0]); + + CHECK_V_EQ_EXPECTED_AND_ASSERT(input_with_enough_decoys.key_offsets.size(), CURRENCY_DEFAULT_DECOY_SET_SIZE + 1); + CHECK_V_EQ_EXPECTED_AND_ASSERT(input_with_not_enough_decoys.key_offsets.size(), 1); + + r = mine_next_pow_blocks_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed"); + + CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count()); + + bob_wlt->refresh(); + CHECK_AND_ASSERT_MES(check_balance_via_wallet(*bob_wlt.get(), "Bob", MK_TEST_COINS(23 + 55) - TESTS_DEFAULT_FEE, UINT64_MAX, MK_TEST_COINS(23 + 55) - TESTS_DEFAULT_FEE, 0, 0), false, ""); + + return true; +} diff --git a/tests/core_tests/hard_fork_4.h b/tests/core_tests/hard_fork_4.h index 600a17c8..b3684f80 100644 --- a/tests/core_tests/hard_fork_4.h +++ b/tests/core_tests/hard_fork_4.h @@ -34,3 +34,11 @@ struct hardfork_4_wallet_transfer_with_mandatory_mixins : public wallet_test bool generate(std::vector& events) const; bool c1(currency::core& c, size_t ev_index, const std::vector& events); }; + + +struct hardfork_4_wallet_sweep_bare_outs : public wallet_test +{ + hardfork_4_wallet_sweep_bare_outs(); + bool generate(std::vector& events) const; + bool c1(currency::core& c, size_t ev_index, const std::vector& events); +}; From 65dfe9052658f2db915184652750d04a23ab4bcf Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 9 Apr 2024 21:44:44 +0200 Subject: [PATCH 121/184] wallet2: fixed sweep_bare_outs(), added new overloading for prepare_tx_sources() --- src/wallet/wallet2.cpp | 22 ++++++++++++++-------- src/wallet/wallet2.h | 1 + 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 964d2e76..0f73afad 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -2353,7 +2353,7 @@ bool wallet2::sweep_bare_unspent_outputs(const currency::account_public_address& ftp.pevents_dispatcher = &m_debug_events_dispatcher; ftp.tx_version = this->get_current_tx_version(); - if (!prepare_tx_sources(decoys_count, ftp.sources, group.tids)) + if (!prepare_tx_sources(decoys_count, /*use_all_decoys_if_found_less_than_required*/ true, ftp.sources, group.tids)) { on_tx_sent(batch_index, transaction{}, 0, 0, false, "sources for tx couldn't be prepared"); LOG_PRINT_L0("prepare_tx_sources failed, batch_index = " << batch_index); @@ -6322,7 +6322,12 @@ void wallet2::prefetch_global_indicies_if_needed(const std::vector& se }*/ } //---------------------------------------------------------------------------------------------------- -bool wallet2::prepare_tx_sources(size_t fake_outputs_count_, std::vector& sources, const std::vector& selected_indicies) +bool wallet2::prepare_tx_sources(size_t fake_outputs_count, std::vector& sources, const std::vector& selected_indicies) +{ + return prepare_tx_sources(fake_outputs_count, false, sources, selected_indicies); +} +//---------------------------------------------------------------------------------------------------- +bool wallet2::prepare_tx_sources(size_t fake_outputs_count_, bool use_all_decoys_if_found_less_than_required, std::vector& sources, const std::vector& selected_indicies) { typedef COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::out_entry out_entry; typedef currency::tx_source_entry::output_entry tx_output_entry; @@ -6400,14 +6405,15 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count_, std::vector scanty_outs; THROW_IF_FALSE_WALLET_EX(daemon_resp.outs.size() == req.amounts.size(), error::not_enough_outs_to_mix, scanty_outs, fake_outputs_count); - for(size_t i = 0; i != daemon_resp.outs.size(); i++) + + if (!use_all_decoys_if_found_less_than_required) { - if (req.amounts[i].amount != 0 && daemon_resp.outs[i].outs.size() != req.amounts[i].global_offsets.size()) - { - scanty_outs.push_back(daemon_resp.outs[i]); - } + // make sure we have received the requested number of decoys + for(size_t i = 0; i != daemon_resp.outs.size(); i++) + if (req.amounts[i].amount != 0 && daemon_resp.outs[i].outs.size() != req.amounts[i].global_offsets.size()) + scanty_outs.push_back(daemon_resp.outs[i]); + THROW_IF_FALSE_WALLET_EX(scanty_outs.empty(), error::not_enough_outs_to_mix, scanty_outs, fake_outputs_count); } - THROW_IF_FALSE_WALLET_EX(scanty_outs.empty(), error::not_enough_outs_to_mix, scanty_outs, fake_outputs_count); } } diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index f3b42762..e220959c 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -792,6 +792,7 @@ private: bool build_escrow_proposal(bc_services::contract_private_details& ecrow_details, uint64_t fee, uint64_t unlock_time, currency::tx_service_attachment& att, std::vector& selected_indicies); bool prepare_tx_sources(assets_selection_context& needed_money_map, size_t fake_outputs_count, uint64_t dust_threshold, std::vector& sources, std::vector& selected_indicies); bool prepare_tx_sources(size_t fake_outputs_count, std::vector& sources, const std::vector& selected_indicies); + bool prepare_tx_sources(size_t fake_outputs_count, bool use_all_decoys_if_found_less_than_required, std::vector& sources, const std::vector& selected_indicies); bool prepare_tx_sources(crypto::hash multisig_id, std::vector& sources, uint64_t& found_money); bool prepare_tx_sources_htlc(crypto::hash htlc_tx_id, const std::string& origin, std::vector& sources, uint64_t& found_money); bool prepare_tx_sources_for_defragmentation_tx(std::vector& sources, std::vector& selected_indicies, uint64_t& found_money); From 56b62603483d91716863417017ee14ea2d15396d Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 9 Apr 2024 22:21:42 +0200 Subject: [PATCH 122/184] warning fixed --- .../include/serialization/keyvalue_serialization.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/contrib/epee/include/serialization/keyvalue_serialization.h b/contrib/epee/include/serialization/keyvalue_serialization.h index d350eda0..494046cc 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization.h +++ b/contrib/epee/include/serialization/keyvalue_serialization.h @@ -74,8 +74,8 @@ public: \ #define KV_MAKE_VAR_NAME() VARNAME(val_tmp_name) #define KV_SERIALIZE_N(varialble, val_name) \ - using KV_MAKE_ALIAS_NAME() = decltype(this_ref.varialble); \ - const char* KV_MAKE_VAR_NAME() = val_name;\ + using KV_MAKE_ALIAS_NAME() [[maybe_unused]] = decltype(this_ref.varialble); \ + [[maybe_unused]] const char* KV_MAKE_VAR_NAME() = val_name;\ epee::serialization::selector::serialize(this_ref.varialble, stg, hparent_section, val_name); //#define KV_SERIALIZE_N_DOC(varialble, val_name) \ @@ -126,13 +126,13 @@ public: \ #define KV_SERIALIZE_CUSTOM_N(varialble, stored_type, from_v_to_stored, from_stored_to_v, val_name) \ - using KV_MAKE_ALIAS_NAME() = stored_type; \ - const char* VARNAME(val_tmp_name) = val_name;\ + using KV_MAKE_ALIAS_NAME() [[maybe_unused]] = stored_type; \ + [[maybe_unused]] const char* VARNAME(val_tmp_name) = val_name;\ epee::serialization::selector::template serialize_custom(this_ref.varialble, stg, hparent_section, val_name, from_v_to_stored, from_stored_to_v); #define KV_SERIALIZE_EPHEMERAL_N(stored_type, from_v_to_stored, val_name) \ - using KV_MAKE_ALIAS_NAME() = stored_type; \ - const char* VARNAME(val_tmp_name) = val_name;\ + using KV_MAKE_ALIAS_NAME() [[maybe_unused]] = stored_type; \ + [[maybe_unused]] const char* VARNAME(val_tmp_name) = val_name;\ epee::serialization::selector::template serialize_ephemeral(this_ref, stg, hparent_section, val_name, from_v_to_stored); From 42fda5eaf734d0a9169619ed7c273d4af5d91251 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Tue, 9 Apr 2024 23:22:56 +0300 Subject: [PATCH 123/184] === build number: 297 -> 298 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index 19b7c316..ad9013ed 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 297 +#define PROJECT_VERSION_BUILD_NO 298 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From 3a792e9a8e10cb870f36b03ab4042473d3021192 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Tue, 9 Apr 2024 22:52:41 +0200 Subject: [PATCH 124/184] added wallet API complete documentation --- .../include/net/http_server_handlers_map2.h | 386 ++++++++------ .../serialization/keyvalue_serialization.h | 9 +- .../portable_storage_to_description.h | 17 +- src/common/command_line.cpp | 2 +- src/common/command_line.h | 4 +- src/currency_core/currency_basic.h | 10 +- src/currency_core/offers_service_basics.h | 85 ++-- src/daemon/daemon.cpp | 10 +- src/rpc/core_rpc_server_commands_defs.h | 10 +- src/simplewallet/simplewallet.cpp | 40 +- src/wallet/wallet_public_structs_defs.h | 481 ++++++++++-------- src/wallet/wallet_rpc_server.cpp | 2 +- src/wallet/wallet_rpc_server.h | 32 +- src/wallet/wallets_manager.cpp | 3 +- 14 files changed, 632 insertions(+), 459 deletions(-) diff --git a/contrib/epee/include/net/http_server_handlers_map2.h b/contrib/epee/include/net/http_server_handlers_map2.h index 0200b558..1452aa57 100644 --- a/contrib/epee/include/net/http_server_handlers_map2.h +++ b/contrib/epee/include/net/http_server_handlers_map2.h @@ -34,148 +34,7 @@ -template -typename_t get_documentation_json_struct() -{ - return AUTO_VAL_INIT_T(typename_t); -} - - -template -bool auto_doc_t(const std::string& prefix_name, std::string& generate_reference) -{ - if (!generate_reference.size()) return true; - request_t req = get_documentation_json_struct(); - response_t res = get_documentation_json_struct(); - - std::string req_str; - std::string req_str_descr; - epee::serialization::portable_storage_extended_doc ps; - req.store(ps, nullptr); - ps.dump_as_json(req_str); - ps.dump_as_decriptions(req_str_descr); - - - std::string res_str; - std::string res_str_descr; - epee::serialization::portable_storage_extended_doc ps_res; - res.store(ps_res, nullptr); - ps_res.dump_as_json(res_str); - ps_res.dump_as_decriptions(res_str_descr); - - - std::stringstream ss; - ss << prefix_name << ENDL - << "REQUEST: " << ENDL << req_str << ENDL << req_str_descr << "--------------------------------" << ENDL - << "RESPONSE: " << ENDL << res_str << ENDL << res_str_descr << "################################" << ENDL; - generate_reference += ss.str(); - return true; -} - - -template -bool auto_doc(const std::string& prefix_name, std::string& generate_reference) -{ - return auto_doc_t(prefix_name, generate_reference); -} - -namespace epee { - namespace net_utils { - namespace http { - struct i_chain_handler - { - virtual bool handle_http_request_map(const epee::net_utils::http::http_request_info& query_info, epee::net_utils::http::http_response_info& response_info, - epee::net_utils::connection_context_base& m_conn_context, bool& call_found, std::string& generate_reference) = 0; - }; - } - } -} - - - - -#define CHAIN_HTTP_TO_MAP2(context_type) bool handle_http_request(const epee::net_utils::http::http_request_info& query_info, \ - epee::net_utils::http::http_response_info& response, \ - context_type& m_conn_context) \ -{\ - response.m_response_code = 200; \ - response.m_response_comment = "Ok"; \ - std::string reference_stub; \ - bool call_found = false; \ - if(!handle_http_request_map(query_info, response, m_conn_context, call_found, reference_stub) && response.m_response_code == 200) \ - { response.m_response_code = 500; response.m_response_comment = "Internal Server Error"; return true; } \ - if (!call_found) \ - { response.m_response_code = 404; response.m_response_comment = "Not Found"; return true; } \ - return true; \ -} - -#define BEGIN_URI_MAP2() template bool handle_http_request_map(const epee::net_utils::http::http_request_info& query_info, \ - epee::net_utils::http::http_response_info& response_info, \ - t_context& m_conn_context, bool& call_found, std::string& generate_reference) { \ - call_found = false; \ - if(false) return true; //just a stub to have "else if" - -#define BEGIN_URI_MAP2_VIRTUAL() virtual bool handle_http_request_map(const epee::net_utils::http::http_request_info& query_info, \ - epee::net_utils::http::http_response_info& response_info, \ - epee::net_utils::connection_context_base& m_conn_context, bool& call_found, std::string& generate_reference) { \ - call_found = false; \ - if(false) return true; //just a stub to have "else if" - - -#define MAP_URI2(pattern, callback) else if(std::string::npos != query_info.m_URI.find(pattern)) return callback(query_info, response_info, m_conn_context); - -#define MAP_URI_AUTO_XML2(s_pattern, callback_f, command_type) //TODO: don't think i ever again will use xml - ambiguous and "overtagged" format - -#define MAP_URI_AUTO_JON2(s_pattern, callback_f, command_type) \ - else if(auto_doc(s_pattern "[JSON]", generate_reference) && query_info.m_URI == s_pattern) \ - { \ - call_found = true; \ - uint64_t ticks = misc_utils::get_tick_count(); \ - boost::value_initialized req; \ - bool res = epee::serialization::load_t_from_json(static_cast(req), query_info.m_body); \ - CHECK_AND_ASSERT_MES(res, false, "Failed to parse json: \r\n" << query_info.m_body); \ - uint64_t ticks1 = epee::misc_utils::get_tick_count(); \ - boost::value_initialized resp;\ - res = callback_f(static_cast(req), static_cast(resp), m_conn_context); \ - CHECK_AND_ASSERT_MES(res, false, "Failed to call " << #callback_f << "() while handling " << s_pattern); \ - uint64_t ticks2 = epee::misc_utils::get_tick_count(); \ - epee::serialization::store_t_to_json(static_cast(resp), response_info.m_body); \ - uint64_t ticks3 = epee::misc_utils::get_tick_count(); \ - response_info.m_mime_tipe = "application/json"; \ - response_info.m_header_info.m_content_type = " application/json"; \ - LOG_PRINT("[HTTP/JSON][" << epee::string_tools::get_ip_string_from_int32(m_conn_context.m_remote_ip ) << "][" << query_info.m_URI << "] processed with " << ticks1-ticks << "/"<< ticks2-ticks1 << "/" << ticks3-ticks2 << "ms", LOG_LEVEL_2); \ - } - -#define MAP_URI_AUTO_BIN2(s_pattern, callback_f, command_type) \ - else if(auto_doc(s_pattern "[BIN]", generate_reference) && query_info.m_URI == s_pattern) \ - { \ - call_found = true; \ - uint64_t ticks = misc_utils::get_tick_count(); \ - boost::value_initialized req; \ - bool res = epee::serialization::load_t_from_binary(static_cast(req), query_info.m_body); \ - CHECK_AND_ASSERT_MES(res, false, "Failed to parse bin body data, body size=" << query_info.m_body.size()); \ - uint64_t ticks1 = misc_utils::get_tick_count(); \ - boost::value_initialized resp;\ - res = callback_f(static_cast(req), static_cast(resp), m_conn_context); \ - CHECK_AND_ASSERT_MES(res, false, "Failed to call " << #callback_f << "() while handling " << s_pattern); \ - uint64_t ticks2 = misc_utils::get_tick_count(); \ - epee::serialization::store_t_to_binary(static_cast(resp), response_info.m_body); \ - uint64_t ticks3 = epee::misc_utils::get_tick_count(); \ - response_info.m_mime_tipe = " application/octet-stream"; \ - response_info.m_header_info.m_content_type = " application/octet-stream"; \ - LOG_PRINT( "[HTTP/BIN][" << epee::string_tools::get_ip_string_from_int32(m_conn_context.m_remote_ip ) << "][" << query_info.m_URI << "] processed with " << ticks1-ticks << "/"<< ticks2-ticks1 << "/" << ticks3-ticks2 << "ms", LOG_LEVEL_2); \ - } - -#define CHAIN_TO_PHANDLER(pi_chain_handler) else if (pi_chain_handler && pi_chain_handler->handle_http_request_map(query_info, response_info, m_conn_context, call_found, generate_reference) && call_found) { return true;} - -#define CHAIN_URI_MAP2(callback) else {callback(query_info, response_info, m_conn_context);call_found = true;} - -#define END_URI_MAP2() return true;} - - - - -namespace epee +namespace epee { namespace json_rpc { @@ -204,7 +63,7 @@ namespace epee KV_SERIALIZE(message) END_KV_SERIALIZE_MAP() }; - + struct dummy_error { BEGIN_KV_SERIALIZE_MAP() @@ -264,20 +123,241 @@ namespace epee } } -template -struct json_command_type_t + +template +typename_t get_documentation_json_struct() { - typedef typename epee::json_rpc::request request; - typedef typename epee::json_rpc::request response; + return AUTO_VAL_INIT_T(typename_t); +} + +struct documentation_entry +{ + std::string uri; + bool is_binary = false; //if not - then it's JSON + std::string json_method_name; + std::string request_json_example; + std::string request_json_descriptions; + + std::string response_json_example; + std::string response_json_descriptions; + + std::string method_general_decription; }; -#define JSON_RPC_REFERENCE_MARKER "JSON_RPC" +struct documentation +{ + bool do_generate_documentation = false; + std::list entries; +}; + + +// Primary template +template +struct has_static_member_description { +private: + // SFINAE test function + template + static auto test(int) -> decltype(U::description, std::true_type{}); + + // Fallback function + template + static auto test(...) -> std::false_type; + +public: + // Member constant indicating whether T has a static member + static constexpr bool value = decltype(test(0))::value; +}; -#define BEGIN_JSON_RPC_MAP(uri) else if(query_info.m_URI == JSON_RPC_REFERENCE_MARKER || query_info.m_URI == uri) \ + +template +const char* get_command_description() +{ + if constexpr (has_static_member_description::value) + { + return T::description; + } + else + { + return "NO DESCRIPTION"; + } +} + +template +void f(T) {} // Definition #2 + + +template +bool auto_doc(const std::string& uri, const std::string& method, bool is_json, documentation& docs) +{ + if (!docs.do_generate_documentation) return true; + + docs.entries.resize(docs.entries.size()+1); + docs.entries.back().is_binary = !is_json; + docs.entries.back().json_method_name = method; + docs.entries.back().method_general_decription = get_command_description(); + + if constexpr (is_json_rpc_method) + { + //json rpc-like call + typedef typename epee::json_rpc::request request_t; + typedef typename epee::json_rpc::request response_t; + request_t req = AUTO_VAL_INIT(req); //get_documentation_json_struct(); + response_t res = AUTO_VAL_INIT(res); //get_documentation_json_struct(); + + + epee::serialization::portable_storage_extended_doc ps; + req.store(ps, nullptr); + ps.dump_as_json(docs.entries.back().request_json_example); + ps.dump_as_decriptions(docs.entries.back().request_json_descriptions); + + epee::serialization::portable_storage_extended_doc ps_res; + res.store(ps_res, nullptr); + ps_res.dump_as_json(docs.entries.back().response_json_example); + ps_res.dump_as_decriptions(docs.entries.back().response_json_descriptions); + + } + else + { + //json/bin uri/based + typedef command_type_t::request request_t; + typedef command_type_t::response response_t; + + request_t req = AUTO_VAL_INIT(req); //get_documentation_json_struct(); + response_t res = AUTO_VAL_INIT(res); //get_documentation_json_struct(); + + + epee::serialization::portable_storage_extended_doc ps; + req.store(ps, nullptr); + ps.dump_as_json(docs.entries.back().request_json_example); + ps.dump_as_decriptions(docs.entries.back().request_json_descriptions); + + epee::serialization::portable_storage_extended_doc ps_res; + res.store(ps_res, nullptr); + ps_res.dump_as_json(docs.entries.back().response_json_example); + ps_res.dump_as_decriptions(docs.entries.back().response_json_descriptions); + } + + +// std::stringstream ss; +// ss << prefix_name << ENDL +// << "REQUEST: " << ENDL << req_str << ENDL << req_str_descr << "--------------------------------" << ENDL +// << "RESPONSE: " << ENDL << res_str << ENDL << res_str_descr << "################################" << ENDL; +// generate_reference += ss.str(); + return true; + + //return auto_doc_t(prefix_name, generate_reference); +} + +namespace epee { + namespace net_utils { + namespace http { + struct i_chain_handler + { + virtual bool handle_http_request_map(const epee::net_utils::http::http_request_info& query_info, epee::net_utils::http::http_response_info& response_info, + epee::net_utils::connection_context_base& m_conn_context, bool& call_found, documentation& docs = documentation()) = 0; + }; + } + } +} + + + + +#define CHAIN_HTTP_TO_MAP2(context_type) bool handle_http_request(const epee::net_utils::http::http_request_info& query_info, \ + epee::net_utils::http::http_response_info& response, \ + context_type& m_conn_context) \ +{\ + response.m_response_code = 200; \ + response.m_response_comment = "Ok"; \ + bool call_found = false; \ + if(!handle_http_request_map(query_info, response, m_conn_context, call_found) && response.m_response_code == 200) \ + { response.m_response_code = 500; response.m_response_comment = "Internal Server Error"; return true; } \ + if (!call_found) \ + { response.m_response_code = 404; response.m_response_comment = "Not Found"; return true; } \ + return true; \ +} + +#define BEGIN_URI_MAP2() template bool handle_http_request_map(const epee::net_utils::http::http_request_info& query_info, \ + epee::net_utils::http::http_response_info& response_info, \ + t_context& m_conn_context, bool& call_found, documentation& docs = documentation()) { \ + call_found = false; \ + if(false) return true; //just a stub to have "else if" + +#define BEGIN_URI_MAP2_VIRTUAL() virtual bool handle_http_request_map(const epee::net_utils::http::http_request_info& query_info, \ + epee::net_utils::http::http_response_info& response_info, \ + epee::net_utils::connection_context_base& m_conn_context, bool& call_found, documentation& docs = documentation()) { \ + call_found = false; \ + if(false) return true; //just a stub to have "else if" + + +#define MAP_URI2(pattern, callback) else if(std::string::npos != query_info.m_URI.find(pattern)) return callback(query_info, response_info, m_conn_context); + +#define MAP_URI_AUTO_XML2(s_pattern, callback_f, command_type) //TODO: don't think i ever again will use xml - ambiguous and "overtagged" format + +#define MAP_URI_AUTO_JON2(s_pattern, callback_f, command_type) \ + else if(auto_doc(s_pattern, "", true, docs) && query_info.m_URI == s_pattern) \ { \ - if(query_info.m_URI == JSON_RPC_REFERENCE_MARKER) {generate_reference = "JSON RPC URL: " uri "\n";} \ + call_found = true; \ + uint64_t ticks = misc_utils::get_tick_count(); \ + boost::value_initialized req; \ + bool res = epee::serialization::load_t_from_json(static_cast(req), query_info.m_body); \ + CHECK_AND_ASSERT_MES(res, false, "Failed to parse json: \r\n" << query_info.m_body); \ + uint64_t ticks1 = epee::misc_utils::get_tick_count(); \ + boost::value_initialized resp;\ + res = callback_f(static_cast(req), static_cast(resp), m_conn_context); \ + CHECK_AND_ASSERT_MES(res, false, "Failed to call " << #callback_f << "() while handling " << s_pattern); \ + uint64_t ticks2 = epee::misc_utils::get_tick_count(); \ + epee::serialization::store_t_to_json(static_cast(resp), response_info.m_body); \ + uint64_t ticks3 = epee::misc_utils::get_tick_count(); \ + response_info.m_mime_tipe = "application/json"; \ + response_info.m_header_info.m_content_type = " application/json"; \ + LOG_PRINT("[HTTP/JSON][" << epee::string_tools::get_ip_string_from_int32(m_conn_context.m_remote_ip ) << "][" << query_info.m_URI << "] processed with " << ticks1-ticks << "/"<< ticks2-ticks1 << "/" << ticks3-ticks2 << "ms", LOG_LEVEL_2); \ + } + +#define MAP_URI_AUTO_BIN2(s_pattern, callback_f, command_type) \ + else if(auto_doc(s_pattern, "", false, docs) && query_info.m_URI == s_pattern) \ + { \ + call_found = true; \ + uint64_t ticks = misc_utils::get_tick_count(); \ + boost::value_initialized req; \ + bool res = epee::serialization::load_t_from_binary(static_cast(req), query_info.m_body); \ + CHECK_AND_ASSERT_MES(res, false, "Failed to parse bin body data, body size=" << query_info.m_body.size()); \ + uint64_t ticks1 = misc_utils::get_tick_count(); \ + boost::value_initialized resp;\ + res = callback_f(static_cast(req), static_cast(resp), m_conn_context); \ + CHECK_AND_ASSERT_MES(res, false, "Failed to call " << #callback_f << "() while handling " << s_pattern); \ + uint64_t ticks2 = misc_utils::get_tick_count(); \ + epee::serialization::store_t_to_binary(static_cast(resp), response_info.m_body); \ + uint64_t ticks3 = epee::misc_utils::get_tick_count(); \ + response_info.m_mime_tipe = " application/octet-stream"; \ + response_info.m_header_info.m_content_type = " application/octet-stream"; \ + LOG_PRINT( "[HTTP/BIN][" << epee::string_tools::get_ip_string_from_int32(m_conn_context.m_remote_ip ) << "][" << query_info.m_URI << "] processed with " << ticks1-ticks << "/"<< ticks2-ticks1 << "/" << ticks3-ticks2 << "ms", LOG_LEVEL_2); \ + } + +#define CHAIN_TO_PHANDLER(pi_chain_handler) else if (pi_chain_handler && pi_chain_handler->handle_http_request_map(query_info, response_info, m_conn_context, call_found, docs) && call_found) { return true;} + +#define CHAIN_URI_MAP2(callback) else {callback(query_info, response_info, m_conn_context);call_found = true;} + +#define END_URI_MAP2() return true;} + + + +//template +//struct json_command_type_t +//{ +// typedef typename epee::json_rpc::request request; +// typedef typename epee::json_rpc::request response; +//}; + +//#define JSON_RPC_REFERENCE_MARKER "JSON_RPC" + +// if(query_info.m_URI == JSON_RPC_REFERENCE_MARKER) {generate_reference = "JSON RPC URL: " uri "\n";} \ + +#define BEGIN_JSON_RPC_MAP(uri) else if(docs.do_generate_documentation || query_info.m_URI == uri) \ + { \ + const char* current_zone_json_uri = uri;\ LOG_PRINT_L4("[JSON_REQUEST_BODY]: " << ENDL << query_info.m_body); \ uint64_t ticks = epee::misc_utils::get_tick_count(); \ epee::serialization::portable_storage ps; \ @@ -336,7 +416,7 @@ struct json_command_type_t LOG_PRINT( query_info.m_URI << "[" << method_name << "] processed with " << ticks1-ticks << "/"<< ticks2-ticks1 << "/" << ticks3-ticks2 << "ms", LOG_LEVEL_2); #define MAP_JON_RPC_WE(method_name, callback_f, command_type) \ - else if(auto_doc>("[" method_name "]", generate_reference) && callback_name == method_name) \ + else if(auto_doc(current_zone_json_uri, method_name, true, docs) && callback_name == method_name) \ { \ call_found = true; \ PREPARE_OBJECTS_FROM_JSON(command_type) \ @@ -354,7 +434,7 @@ struct json_command_type_t } #define MAP_JON_RPC_WERI(method_name, callback_f, command_type) \ - else if(auto_doc>("[" method_name "]", generate_reference) && callback_name == method_name) \ + else if(auto_doc(current_zone_json_uri, method_name, true, docs) && callback_name == method_name) \ { \ call_found = true; \ PREPARE_OBJECTS_FROM_JSON(command_type) \ @@ -372,7 +452,7 @@ struct json_command_type_t } #define MAP_JON_RPC(method_name, callback_f, command_type) \ - else if(auto_doc>(std::string("[") + method_name + "]", generate_reference) && callback_name == method_name) \ + else if(auto_doc(current_zone_json_uri, method_name, true, docs) && callback_name == method_name) \ { \ call_found = true; \ PREPARE_OBJECTS_FROM_JSON(command_type) \ diff --git a/contrib/epee/include/serialization/keyvalue_serialization.h b/contrib/epee/include/serialization/keyvalue_serialization.h index 494046cc..91f1aeda 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization.h +++ b/contrib/epee/include/serialization/keyvalue_serialization.h @@ -103,12 +103,9 @@ public: \ //#define DOC_DSCR(description) , description #define DOC_EXMP(substitute) , substitute -#define DOC_EXMP_AUTO_1(arg_1) , KV_MAKE_ALIAS_NAME() (arg_1) -#define DOC_EXMP_AUTO_2(arg_1, arg_2) , KV_MAKE_ALIAS_NAME() (arg_1, arg_2) +//#define DOC_EXMP_AUTO_1(arg_1) , KV_MAKE_ALIAS_NAME() (arg_1) +//#define DOC_EXMP_AUTO_2(arg_1, arg_2) , KV_MAKE_ALIAS_NAME() (arg_1, arg_2) #define DOC_END ); } - - - #define DOC_EXMP_AUTO(...) , epee::create_t_object(__VA_ARGS__) @@ -164,7 +161,7 @@ public: \ #define KV_SERIALIZE(varialble) KV_SERIALIZE_N(varialble, #varialble) #define KV_SERIALIZE_DOC(varialble) KV_SERIALIZE_N_DOC( varialble, #varialble) -#define DOC_COMMAND(desciption_text) inline static const char* description; +#define DOC_COMMAND(desciption_text) inline static const char* description = desciption_text; #define KV_SERIALIZE_VAL_POD_AS_BLOB(varialble) KV_SERIALIZE_VAL_POD_AS_BLOB_N(varialble, #varialble) diff --git a/contrib/epee/include/storages/portable_storage_to_description.h b/contrib/epee/include/storages/portable_storage_to_description.h index c38c3f62..2d87d5d7 100644 --- a/contrib/epee/include/storages/portable_storage_to_description.h +++ b/contrib/epee/include/storages/portable_storage_to_description.h @@ -51,13 +51,13 @@ namespace epee template static void handle_array_start(t_stream& strm, size_t indent) { - strm << "["; + //strm << "["; } template static void handle_array_end(t_stream& strm, size_t indent) { - strm << "]"; + //strm << "]"; } template @@ -71,8 +71,11 @@ namespace epee template static void handle_print_key(t_stream& strm, const std::string& key, const std::string& description, size_t indent) { - const std::string indent_str = make_indent(indent); - strm << indent_str << "\"" << key << "\"" << ": " << description; + if (description.size()) + { + const std::string indent_str = make_indent(indent); + strm << indent_str << "\"" << key << "\"" << ": " << description << eol; + } } template @@ -84,19 +87,19 @@ namespace epee template static void handle_section_entry_separator(t_stream& strm, size_t indent) { - strm << ","; + //strm << ","; } template static void handle_array_entry_separator(t_stream& strm, size_t indent) { - strm << ","; + //strm << ","; } template static void handle_line_break(t_stream& strm, size_t indent) { - strm << eol; + //strm << eol; } }; diff --git a/src/common/command_line.cpp b/src/common/command_line.cpp index a7b9a5ff..a596dfd9 100644 --- a/src/common/command_line.cpp +++ b/src/common/command_line.cpp @@ -25,7 +25,7 @@ namespace command_line const arg_descriptor arg_console ( "no-console", "Disable daemon console commands" ); const arg_descriptor arg_show_details ( "currency-details", "Display currency details" ); - const arg_descriptor arg_show_rpc_autodoc ( "show_rpc_autodoc", "Display rpc auto-generated documentation template" ); + const arg_descriptor arg_generate_rpc_autodoc ( "generate_rpc_autodoc", "Make auto-generated RPC API documentation documents at the given path" ); const arg_descriptor arg_disable_upnp ( "disable-upnp", "Disable UPnP (enhances local network privacy)"); const arg_descriptor arg_disable_ntp ( "disable-ntp", "Disable NTP, could enhance to time synchronization issue but increase network privacy, consider using disable-stop-if-time-out-of-sync with it"); diff --git a/src/common/command_line.h b/src/common/command_line.h index 905b1067..0b326917 100644 --- a/src/common/command_line.h +++ b/src/common/command_line.h @@ -220,7 +220,7 @@ namespace command_line extern const arg_descriptor arg_log_level; extern const arg_descriptor arg_console; extern const arg_descriptor arg_show_details; - extern const arg_descriptor arg_show_rpc_autodoc; + //extern const arg_descriptor arg_show_rpc_autodoc; extern const arg_descriptor arg_disable_upnp; extern const arg_descriptor arg_disable_ntp; extern const arg_descriptor arg_disable_stop_if_time_out_of_sync; @@ -233,4 +233,6 @@ namespace command_line extern const arg_descriptor arg_validate_predownload; extern const arg_descriptor arg_predownload_link; extern const arg_descriptor arg_deeplink; + extern const arg_descriptor arg_generate_rpc_autodoc; + } diff --git a/src/currency_core/currency_basic.h b/src/currency_core/currency_basic.h index 85b65544..80ddef17 100644 --- a/src/currency_core/currency_basic.h +++ b/src/currency_core/currency_basic.h @@ -589,11 +589,11 @@ namespace currency END_SERIALIZE() BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(service_id) - KV_SERIALIZE(instruction) - KV_SERIALIZE_BLOB_AS_HEX_STRING(body) - KV_SERIALIZE_CONTAINER_POD_AS_HEX(security) - KV_SERIALIZE(flags) + KV_SERIALIZE(service_id) DOC_DSCR("Service ID, identificator that diferent one service from another") DOC_EXMP("C") DOC_END + KV_SERIALIZE(instruction) DOC_DSCR("Instruction that make sence for this particular service") DOC_EXMP("K") DOC_END + KV_SERIALIZE_BLOB_AS_HEX_STRING(body) DOC_DSCR("Hex-encoded body of the attachment") DOC_EXMP("dcfd7e055a6a3043ea3541a571a57a63e25dcc64e4a270f14fa9a58ac5dbec85dcfd7e055a6a3043ea3541a571a57a63e25dcc64e4a270f14fa9a58ac5dbec85") DOC_END + KV_SERIALIZE_CONTAINER_POD_AS_HEX(security) DOC_DSCR("Hex-encoded public key of the owner, optional") DOC_EXMP("d8f6e37f28a632c06b0b3466db1b9d2d1b36a580ee35edfd971dc1423bc412a5") DOC_END + KV_SERIALIZE(flags) DOC_DSCR("Flags that help wallet to automatically process some properties of the attachment(combination of TX_SERVICE_ATTACHMENT_ENCRYPT_BODY=1, TX_SERVICE_ATTACHMENT_DEFLATE_BODY=2, TX_SERVICE_ATTACHMENT_ENCRYPT_BODY_ISOLATE_AUDITABLE=4,TX_SERVICE_ATTACHMENT_ENCRYPT_ADD_PROOF=8 )") DOC_END END_KV_SERIALIZE_MAP() }; diff --git a/src/currency_core/offers_service_basics.h b/src/currency_core/offers_service_basics.h index 1dffe367..a2ca2e7c 100644 --- a/src/currency_core/offers_service_basics.h +++ b/src/currency_core/offers_service_basics.h @@ -37,21 +37,21 @@ namespace bc_services //----------------- BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_N(offer_type, "ot") - KV_SERIALIZE_CUSTOM_N(amount_primary, std::string, bc_services::transform_amount_to_string, bc_services::transform_string_to_amount, "ap") - KV_SERIALIZE_CUSTOM_N(amount_target, std::string, bc_services::transform_amount_to_string, bc_services::transform_string_to_amount, "at") - KV_SERIALIZE_N(bonus, "b") - KV_SERIALIZE_N(target, "t") - KV_SERIALIZE_N(primary, "p") - KV_SERIALIZE_N(location_country, "lco") - KV_SERIALIZE_N(location_city, "lci") - KV_SERIALIZE_N(contacts, "cnt") - KV_SERIALIZE_N(comment, "com") - KV_SERIALIZE_N(payment_types, "pt") - KV_SERIALIZE_N(deal_option, "do") - KV_SERIALIZE_N(category, "cat") - KV_SERIALIZE_N(expiration_time, "et") - KV_SERIALIZE_N(preview_url, "url") + KV_SERIALIZE_N(offer_type, "ot") DOC_DSCR("Type of the offer: OFFER_TYPE_PRIMARY_TO_TARGET(SELL ORDER) - 0, OFFER_TYPE_TARGET_TO_PRIMARY(BUY ORDER) - 1 etc.") DOC_EXMP(0) DOC_END + KV_SERIALIZE_CUSTOM_N(amount_primary, std::string, bc_services::transform_amount_to_string, bc_services::transform_string_to_amount, "ap") DOC_DSCR("Amount of the currency") DOC_EXMP("100000") DOC_END + KV_SERIALIZE_CUSTOM_N(amount_target, std::string, bc_services::transform_amount_to_string, bc_services::transform_string_to_amount, "at") DOC_DSCR("Smount of other currency or goods") DOC_EXMP("10000000") DOC_END + KV_SERIALIZE_N(bonus, "b") DOC_DSCR("Bonus associated with the offer") DOC_EXMP(false) DOC_END + KV_SERIALIZE_N(target, "t") DOC_DSCR("Target: currency / goods") DOC_EXMP("USDT") DOC_END + KV_SERIALIZE_N(primary, "p") DOC_DSCR("Currency for goods") DOC_EXMP("ZANO") DOC_END + KV_SERIALIZE_N(location_country, "lco") DOC_DSCR("Country of the offer location") DOC_EXMP("Montenegro") DOC_END + KV_SERIALIZE_N(location_city, "lci") DOC_DSCR("City of the offer location") DOC_EXMP("Kolasin") DOC_END + KV_SERIALIZE_N(contacts, "cnt") DOC_DSCR("Contacts related to the offer") DOC_EXMP("Ranko +38211111111") DOC_END + KV_SERIALIZE_N(comment, "com") DOC_DSCR("Comment associated with the offer") DOC_EXMP("Dobr dan") DOC_END + KV_SERIALIZE_N(payment_types, "pt") DOC_DSCR("Types of payment accepted for the offer") DOC_EXMP("zano") DOC_END + KV_SERIALIZE_N(deal_option, "do") DOC_DSCR("Deal option for the offer") DOC_EXMP("full amount, by parts") DOC_END + KV_SERIALIZE_N(category, "cat") DOC_DSCR("Category of the offer") DOC_EXMP("") DOC_END + KV_SERIALIZE_N(expiration_time, "et") DOC_DSCR("Expiration time of the offer") DOC_EXMP(0) DOC_END + KV_SERIALIZE_N(preview_url, "url") DOC_DSCR("URL for previewing the offer") DOC_EXMP("") DOC_END END_KV_SERIALIZE_MAP() }; @@ -69,12 +69,12 @@ namespace bc_services mutable bool stopped; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_POD_AS_HEX_STRING(tx_hash) - KV_SERIALIZE_POD_AS_HEX_STRING(tx_original_hash) - KV_SERIALIZE(index_in_tx) - KV_SERIALIZE(timestamp) - KV_SERIALIZE(fee) - KV_SERIALIZE_POD_AS_HEX_STRING(security) + KV_SERIALIZE_POD_AS_HEX_STRING(tx_hash) DOC_DSCR("Transaction hash represented as a hexadecimal string") DOC_EXMP("cc608f59f8080e2fbfe3c8c80eb6e6a953d47cf2d6aebd345bada3a1cab99852") DOC_END + KV_SERIALIZE_POD_AS_HEX_STRING(tx_original_hash) DOC_DSCR("Origin transaction hash represented as a hexadecimal string(if offer updated)") DOC_EXMP("cc608f59f8080e2fbfe3c8c80eb6e6a953d47cf2d6aebd345bada3a1cab99852") DOC_END + KV_SERIALIZE(index_in_tx) DOC_DSCR("Index of the tx_service_attachment entrie in transaction") DOC_EXMP(0) DOC_END + KV_SERIALIZE(timestamp) DOC_DSCR("Timestamp of the transaction") DOC_EXMP(1712683857) DOC_END + KV_SERIALIZE(fee) DOC_DSCR("Fee associated with the transaction") DOC_EXMP(10000000000) DOC_END + KV_SERIALIZE_POD_AS_HEX_STRING(security) DOC_DSCR("Onwer's public key for access control") DOC_EXMP("40fa6db923728b38962718c61b4dc3af1acaa1967479c73703e260dc3609c58d") DOC_END KV_CHAIN_BASE(offer_details) END_KV_SERIALIZE_MAP() }; @@ -163,32 +163,33 @@ namespace bc_services bool bonus; std::string category; std::string keyword; - bool fake; + //bool fake; uint64_t current_time; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(order_by) - KV_SERIALIZE(reverse) - KV_SERIALIZE(offset) - KV_SERIALIZE(limit) - KV_SERIALIZE(timestamp_start) - KV_SERIALIZE(timestamp_stop) - KV_SERIALIZE(offer_type_mask) - KV_SERIALIZE(amount_low_limit) - KV_SERIALIZE(amount_up_limit) - KV_SERIALIZE_CUSTOM(rate_low_limit, std::string, bc_services::transform_double_to_string, bc_services::transform_string_to_double) - KV_SERIALIZE_CUSTOM(rate_up_limit, std::string, bc_services::transform_double_to_string, bc_services::transform_string_to_double) - KV_SERIALIZE(payment_types) - KV_SERIALIZE(location_country) - KV_SERIALIZE(location_city) - KV_SERIALIZE(target) - KV_SERIALIZE(primary) - KV_SERIALIZE(bonus) - KV_SERIALIZE(category) - KV_SERIALIZE(keyword) - KV_SERIALIZE(fake) + KV_SERIALIZE(order_by) DOC_DSCR("Field to order the results by one on this: ORDER_BY_TIMESTAMP=0,ORDER_BY_AMOUNT_PRIMARY=1,ORDER_BY_AMOUNT_TARGET=2,ORDER_BY_AMOUNT_RATE=3,ORDER_BY_PAYMENT_TYPES=4,ORDER_BY_CONTACTS=5,ORDER_BY_LOCATION=6,ORDER_BY_NAME=7") DOC_EXMP(0) DOC_END + KV_SERIALIZE(reverse) DOC_DSCR("Flag to indicate whether the results should be sorted in reverse order") DOC_EXMP(false) DOC_END + KV_SERIALIZE(offset) DOC_DSCR("Offset for pagination") DOC_EXMP(0) DOC_END + KV_SERIALIZE(limit) DOC_DSCR("Maximum number of results to return") DOC_EXMP(100) DOC_END + KV_SERIALIZE(timestamp_start) DOC_DSCR("Start timestamp for filtering results") DOC_EXMP(0) DOC_END + KV_SERIALIZE(timestamp_stop) DOC_DSCR("Stop timestamp for filtering results") DOC_EXMP(0) DOC_END + KV_SERIALIZE(offer_type_mask) DOC_DSCR("Mask representing the types of offers to include in the results, conbination of this: OFFER_TYPE_MASK_PRIMARY_TO_TARGET 0x00000001, OFFER_TYPE_MASK_TARGET_TO_PRIMARY 0x00000002, OFFER_TYPE_MASK_GOODS_TO_PRIMARY 0x00000004, OFFER_TYPE_MASK_PRIMARY_TO_GOODS 0x00000008") DOC_EXMP(0) DOC_END + KV_SERIALIZE(amount_low_limit) DOC_DSCR("Lower limit for the amount of offers") DOC_EXMP(0) DOC_END + KV_SERIALIZE(amount_up_limit) DOC_DSCR("Upper limit for the amount of offers") DOC_EXMP(0) DOC_END + KV_SERIALIZE_CUSTOM(rate_low_limit, std::string, bc_services::transform_double_to_string, bc_services::transform_string_to_double) DOC_DSCR("Lower limit for the rate") DOC_EXMP("0.1") DOC_END + KV_SERIALIZE_CUSTOM(rate_up_limit, std::string, bc_services::transform_double_to_string, bc_services::transform_string_to_double) DOC_DSCR("Upper limit for the rate") DOC_EXMP("0.1") DOC_END + KV_SERIALIZE(payment_types) DOC_DSCR("Types of payment accepted for the offers(in a free form as it is in contract)") DOC_END + KV_SERIALIZE(location_country) DOC_DSCR("Country of the location for the offers") DOC_END + KV_SERIALIZE(location_city) DOC_DSCR("City of the location for the offers") DOC_END + KV_SERIALIZE(target) DOC_DSCR("Target entity of the offers") DOC_END + KV_SERIALIZE(primary) DOC_DSCR("Primary field for the offers") DOC_END + KV_SERIALIZE(bonus) DOC_DSCR("Bonus associated with the offers") DOC_EXMP(false) DOC_END + KV_SERIALIZE(category) DOC_DSCR("Category of the offers") DOC_END + KV_SERIALIZE(keyword) DOC_DSCR("Keyword for searching offers") DOC_EXMP("tubes") DOC_END + //KV_SERIALIZE(fake) DOC_DSCR("Flag indicating whether the offer is fake") DOC_EXMP() DOC_END END_KV_SERIALIZE_MAP() + }; diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index 2be409f2..eb697db8 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -155,7 +155,7 @@ int main(int argc, char* argv[]) command_line::add_arg(desc_cmd_sett, command_line::arg_log_level); command_line::add_arg(desc_cmd_sett, command_line::arg_console); command_line::add_arg(desc_cmd_only, command_line::arg_show_details); - command_line::add_arg(desc_cmd_only, command_line::arg_show_rpc_autodoc); + command_line::add_arg(desc_cmd_only, command_line::arg_generate_rpc_autodoc); command_line::add_arg(desc_cmd_sett, command_line::arg_disable_stop_if_time_out_of_sync); command_line::add_arg(desc_cmd_sett, command_line::arg_disable_stop_on_low_free_space); command_line::add_arg(desc_cmd_sett, command_line::arg_enable_offers_service); @@ -272,15 +272,17 @@ int main(int argc, char* argv[]) if (stratum_enabled) stratum_server_ptr = std::make_shared(&ccore); - if (command_line::get_arg(vm, command_line::arg_show_rpc_autodoc)) + if (command_line::has_arg(vm, command_line::arg_generate_rpc_autodoc)) { LOG_PRINT_L0("Dumping RPC auto-generated documents!"); epee::net_utils::http::http_request_info query_info; epee::net_utils::http::http_response_info response_info; epee::net_utils::connection_context_base conn_context; - std::string generate_reference = std::string("RPC_COMMANDS_LIST:\n"); + //std::string generate_reference = std::string("RPC_COMMANDS_LIST:\n"); + documentation doc; + doc.do_generate_documentation = true; bool call_found = false; - rpc_server.handle_http_request_map(query_info, response_info, conn_context, call_found, generate_reference); + rpc_server.handle_http_request_map(query_info, response_info, conn_context, call_found, doc); //std::string json_rpc_reference; //query_info.m_URI = JSON_RPC_REFERENCE_MARKER; //query_info.m_body = "{\"jsonrpc\": \"2.0\", \"method\": \"nonexisting_method\", \"params\": {}},"; diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 945846e7..27388f04 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -1687,11 +1687,13 @@ namespace currency struct COMMAND_RPC_GET_OFFERS_EX { + DOC_COMMAND("Fetch from daemon offers listed in the marketplace with given filters"); + struct request { bc_services::core_offers_filter filter; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(filter) + KV_SERIALIZE(filter) DOC_DSCR("Filter options.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1702,9 +1704,9 @@ namespace currency uint64_t total_offers; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) - KV_SERIALIZE(offers) - KV_SERIALIZE(total_offers) + KV_SERIALIZE(status) DOC_DSCR("Status of the operation") DOC_EXMP("OK") DOC_END + KV_SERIALIZE(offers) DOC_DSCR("List of offers related to the operation") DOC_EXMP_AUTO(1) DOC_END + KV_SERIALIZE(total_offers) DOC_DSCR("Total number of offers") DOC_EXMP(1) DOC_END END_KV_SERIALIZE_MAP() }; }; diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index e4375a56..6f230939 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -2807,7 +2807,7 @@ int main(int argc, char* argv[]) command_line::add_arg(desc_params, arg_set_timeout); command_line::add_arg(desc_params, arg_voting_config_file); command_line::add_arg(desc_params, arg_no_password_confirmations); - command_line::add_arg(desc_params, command_line::arg_show_rpc_autodoc); + command_line::add_arg(desc_params, command_line::arg_generate_rpc_autodoc); tools::wallet_rpc_server::init_options(desc_params); @@ -2863,24 +2863,50 @@ int main(int argc, char* argv[]) } - if (command_line::get_arg(vm, command_line::arg_show_rpc_autodoc)) + if (command_line::has_arg(vm, command_line::arg_generate_rpc_autodoc)) { LOG_PRINT_L0("Dumping RPC auto-generated documents!"); epee::net_utils::http::http_request_info query_info; epee::net_utils::http::http_response_info response_info; epee::net_utils::connection_context_base conn_context; - std::string generate_reference = std::string("WALLET_RPC_COMMANDS_LIST:\n"); + //std::string generate_reference = std::string("WALLET_RPC_COMMANDS_LIST:\n"); bool call_found = false; tools::wallet_rpc_server wallet_rpc_server(std::shared_ptr(new tools::wallet2())); //wallet_rpc_server.handle_http_request_map(query_info, response_info, conn_context, call_found, generate_reference); - std::string json_rpc_reference = generate_reference; - query_info.m_URI = JSON_RPC_REFERENCE_MARKER; + //::string json_rpc_reference = generate_reference; + documentation docs; + docs.do_generate_documentation = true; +// query_info.m_URI = JSON_RPC_REFERENCE_MARKER; query_info.m_body = "{\"jsonrpc\": \"2.0\", \"method\": \"nonexisting_method\", \"params\": {}},"; - wallet_rpc_server.handle_http_request_map(query_info, response_info, conn_context, call_found, json_rpc_reference); + wallet_rpc_server.handle_http_request_map(query_info, response_info, conn_context, call_found, docs); + + std::string path_to_generate = command_line::get_arg(vm, command_line::arg_generate_rpc_autodoc); + for (const auto& de : docs.entries) + { + std::stringstream ss; + ss << de.method_general_decription << ENDL; + ss << "URL: ```http:://127.0.0.1:11211" << de.uri << "```" << ENDL; - LOG_PRINT_L0(json_rpc_reference); + ss << "### Request: " << ENDL << "```json" << ENDL << de.request_json_example << ENDL << "```" << ENDL; + ss << "### Request description: " << ENDL << "```" << ENDL << de.request_json_descriptions << ENDL << "```" << ENDL; + ss << "### Response: " << ENDL << "```json" << ENDL << de.response_json_example << ENDL << "```" << ENDL; + ss << "### Response description: " << ENDL << "```" << ENDL << de.response_json_descriptions << ENDL << "```" << ENDL; + + std::string filename = de.json_method_name; + if (!filename.size()) + { + filename = de.uri; + } + filename += ".md"; + bool r = epee::file_io_utils::save_string_to_file(path_to_generate + "/" + filename, ss.str()); + if (!r) + { + LOG_ERROR("Failed to save file " << filename); + return 1; + } + } return 0; } diff --git a/src/wallet/wallet_public_structs_defs.h b/src/wallet/wallet_public_structs_defs.h index 61538912..a274ad7f 100644 --- a/src/wallet/wallet_public_structs_defs.h +++ b/src/wallet/wallet_public_structs_defs.h @@ -123,9 +123,9 @@ namespace wallet_public crypto::public_key asset_id = currency::native_coin_asset_id; // not blinded, not premultiplied by 1/8 BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(amount) - KV_SERIALIZE(is_income) - KV_SERIALIZE_POD_AS_HEX_STRING(asset_id) + KV_SERIALIZE(amount) DOC_DSCR("Amount of asset the had been transfered") DOC_EXMP(1000000000000) DOC_END + KV_SERIALIZE(is_income) DOC_DSCR("Indicates if transfer was income our outgoing") DOC_EXMP(false) DOC_END + KV_SERIALIZE_POD_AS_HEX_STRING(asset_id) DOC_DSCR("Asset id") DOC_EXMP("cc608f59f8080e2fbfe3c8c80eb6e6a953d47cf2d6aebd345bada3a1cab99852") DOC_END END_KV_SERIALIZE_MAP() BEGIN_BOOST_SERIALIZATION() @@ -168,27 +168,29 @@ namespace wallet_public std::vector selected_indicies; std::list marketplace_entries; + + BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_POD_AS_HEX_STRING(tx_hash) - KV_SERIALIZE(height) - KV_SERIALIZE(unlock_time) - KV_SERIALIZE(tx_blob_size) - KV_SERIALIZE_BLOB_AS_HEX_STRING(payment_id) - KV_SERIALIZE(comment) - KV_SERIALIZE(timestamp) - KV_SERIALIZE(employed_entries) - KV_SERIALIZE(fee) - KV_SERIALIZE(is_service) - KV_SERIALIZE(is_mixing) - KV_SERIALIZE(is_mining) - KV_SERIALIZE(tx_type) - KV_SERIALIZE(show_sender) - KV_SERIALIZE(contract) - KV_SERIALIZE(service_entries) - KV_SERIALIZE(transfer_internal_index) - KV_SERIALIZE(remote_addresses) - KV_SERIALIZE(remote_aliases) - KV_SERIALIZE(subtransfers) + KV_SERIALIZE_POD_AS_HEX_STRING(tx_hash) DOC_DSCR("Transaction ID(hash)") DOC_EXMP("5509650e12c8f901e6731a2bfaf3abfd64409e3e1366d3d94cd11db8beddb0c3") DOC_END + KV_SERIALIZE(height) DOC_DSCR("Height of the block that included transaction(0 i transaction is unconfirmed)") DOC_EXMP(0) DOC_END + KV_SERIALIZE(unlock_time) DOC_DSCR("Unlock time of this transfer (if present)") DOC_EXMP(0) DOC_END + KV_SERIALIZE(tx_blob_size) DOC_DSCR("Size of transaction in bytes") DOC_EXMP(0) DOC_END + KV_SERIALIZE_BLOB_AS_HEX_STRING(payment_id) DOC_DSCR("HEX-encoded payment id blob, if it was present") DOC_EXMP("00000000ff00ff00") DOC_END + KV_SERIALIZE(comment) DOC_DSCR("Some human-readable comment") DOC_EXMP("Comment here") DOC_END + KV_SERIALIZE(timestamp) DOC_DSCR("Timestamp of the block that included transaction in blockchain, 0 for unconfirmed") DOC_EXMP(1712590951) DOC_END + KV_SERIALIZE(employed_entries) DOC_DSCR("Mark entries from transaction that was connected to this wallet") DOC_END + KV_SERIALIZE(fee) DOC_DSCR("Transaction fee") DOC_EXMP(10000000000) DOC_END + KV_SERIALIZE(is_service) DOC_DSCR("Tells if this transaction is used as utility by one of Zano services(contracts, ionic swaps, etc)") DOC_EXMP(false) DOC_END + KV_SERIALIZE(is_mixing) DOC_DSCR("Tells if this transaction using mixins or not(auditble wallets normally don't use mixins)") DOC_EXMP(false) DOC_END + KV_SERIALIZE(is_mining) DOC_DSCR("Tells if this transaction is coinbase transaction(ie generated by PoW mining or by PoS staking)") DOC_EXMP(false) DOC_END + KV_SERIALIZE(tx_type) DOC_DSCR("Could be one of this: GUI_TX_TYPE_NORMAL=0, GUI_TX_TYPE_PUSH_OFFER=1, GUI_TX_TYPE_UPDATE_OFFER=2, GUI_TX_TYPE_CANCEL_OFFER=3, GUI_TX_TYPE_NEW_ALIAS=4,GUI_TX_TYPE_UPDATE_ALIAS=5,GUI_TX_TYPE_COIN_BASE=6,GUI_TX_TYPE_ESCROW_PROPOSAL=7,GUI_TX_TYPE_ESCROW_TRANSFER=8,GUI_TX_TYPE_ESCROW_RELEASE_NORMAL=9,GUI_TX_TYPE_ESCROW_RELEASE_BURN=10,GUI_TX_TYPE_ESCROW_CANCEL_PROPOSAL=11,GUI_TX_TYPE_ESCROW_RELEASE_CANCEL=12,GUI_TX_TYPE_HTLC_DEPOSIT=13,GUI_TX_TYPE_HTLC_REDEEM=14") DOC_EXMP(0) DOC_END + KV_SERIALIZE(show_sender) DOC_DSCR("If sender is included in tx") DOC_EXMP(false) DOC_END + KV_SERIALIZE(contract) DOC_DSCR("Escrow contract if it's part of transaction") DOC_EXMP_AUTO(1) DOC_END + KV_SERIALIZE(service_entries) DOC_DSCR("Additional entries that might be stored in transaction but not part of it's consensus") DOC_EXMP_AUTO(1) DOC_END + KV_SERIALIZE(transfer_internal_index) DOC_DSCR("Index of this entry in the wallet's array of transaction's history") DOC_EXMP(12) DOC_END + KV_SERIALIZE(remote_addresses) DOC_DSCR("Remote addresses of this transfer(destination if it's outgoing transfer or sender if it's incoming transaction)") DOC_EXMP_AUTO(1, "ZxBvJDuQjMG9R2j4WnYUhBYNrwZPwuyXrC7FHdVmWqaESgowDvgfWtiXeNGu8Px9B24pkmjsA39fzSSiEQG1ekB225ZnrMTBp") DOC_END + KV_SERIALIZE(remote_aliases) DOC_DSCR("Aliases for remot addresses, of discovered") DOC_EXMP_AUTO(1, "roger") DOC_END + KV_SERIALIZE(subtransfers) DOC_DSCR("Essential part of transfer entry: amounts that been transfered in this transaction grouped by asset id") DOC_EXMP_AUTO(1) DOC_END END_KV_SERIALIZE_MAP() BEGIN_BOOST_SERIALIZATION() @@ -283,8 +285,8 @@ namespace wallet_public //bool is_income = false; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_EPHEMERAL_N(uint64_t, wallet_transfer_info_to_amount, "amount") - KV_SERIALIZE_EPHEMERAL_N(bool, wallet_transfer_info_to_is_income, "is_income") + KV_SERIALIZE_EPHEMERAL_N(uint64_t, wallet_transfer_info_to_amount, "amount") DOC_DSCR("Native coins amount") DOC_EXMP(1000000000000) DOC_END + KV_SERIALIZE_EPHEMERAL_N(bool, wallet_transfer_info_to_is_income, "is_income") DOC_DSCR("If trnasfer entrie is income (taken from native subtransfer)") DOC_EXMP(false) DOC_END //KV_SERIALIZE(amount) KV_CHAIN_BASE(wallet_transfer_info) END_KV_SERIALIZE_MAP() @@ -346,9 +348,9 @@ namespace wallet_public uint64_t t; uint64_t h; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(a) - KV_SERIALIZE(t) - KV_SERIALIZE(h) + KV_SERIALIZE(a) DOC_DSCR("Mined amount(block reward)") DOC_EXMP(1000000000000) DOC_END + KV_SERIALIZE(t) DOC_DSCR("Timestamp") DOC_EXMP(1712683857) DOC_END + KV_SERIALIZE(h) DOC_DSCR("height") DOC_EXMP(102000) DOC_END END_KV_SERIALIZE_MAP() }; @@ -357,7 +359,7 @@ namespace wallet_public { std::vector mined_entries; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(mined_entries) + KV_SERIALIZE(mined_entries) DOC_DSCR("Mined blocks entries.") DOC_EXMP_AUTO(1) DOC_END END_KV_SERIALIZE_MAP() }; @@ -368,8 +370,8 @@ namespace wallet_public std::string seed_password; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(seed_phrase) - KV_SERIALIZE(seed_password) + KV_SERIALIZE(seed_phrase) DOC_DSCR("Mnemonic seed phrase used for wallet recovery or generation.") DOC_EXMP("girlfriend unlike mutter tightly social silent expect constant bid nowhere reach flower bite salt lightning conversation dog rush quietly become usually midnight each secret offer class") DOC_END + KV_SERIALIZE(seed_password) DOC_DSCR("Password used to encrypt or decrypt the mnemonic seed phrase, if applicable.") DOC_EXMP("0101010103") DOC_END END_KV_SERIALIZE_MAP() }; @@ -381,15 +383,17 @@ namespace wallet_public bool tracking; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(syntax_correct) - KV_SERIALIZE(require_password) - KV_SERIALIZE(hash_sum_matched) - KV_SERIALIZE(tracking) + KV_SERIALIZE(syntax_correct) DOC_DSCR("Indicates whether the syntax is correct.") DOC_EXMP(true) DOC_END + KV_SERIALIZE(require_password) DOC_DSCR("Indicates whether a password is required.") DOC_EXMP(true) DOC_END + KV_SERIALIZE(hash_sum_matched) DOC_DSCR("Indicates whether the hash sum matches.") DOC_EXMP(true) DOC_END + KV_SERIALIZE(tracking) DOC_DSCR("Indicates whether tracking is enabled.") DOC_EXMP(false) DOC_END END_KV_SERIALIZE_MAP() }; struct COMMAND_RPC_GET_BALANCE { + DOC_COMMAND("Return the balances across all whitelisted assets of the wallet"); + struct request { BEGIN_KV_SERIALIZE_MAP() @@ -412,6 +416,8 @@ namespace wallet_public struct COMMAND_RPC_GET_ADDRESS { + DOC_COMMAND("Obtains wallet's public address"); + struct request { BEGIN_KV_SERIALIZE_MAP() @@ -423,7 +429,7 @@ namespace wallet_public std::string address; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(address) + KV_SERIALIZE(address) DOC_DSCR("string; standard public address of the wallet.") DOC_EXMP("ZxDNaMeZjwCjnHuU5gUNyrP1pM3U5vckbakzzV6dEHyDYeCpW8XGLBFTshcaY8LkG9RQn7FsQx8w2JeJzJwPwuDm2NfixPAXf") DOC_END END_KV_SERIALIZE_MAP() }; }; @@ -432,6 +438,8 @@ namespace wallet_public struct COMMAND_RPC_GET_WALLET_INFO { + DOC_COMMAND("Returns wallet helpful wallet information"); + struct request { BEGIN_KV_SERIALIZE_MAP() @@ -450,26 +458,28 @@ namespace wallet_public uint64_t current_height; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(address) - KV_SERIALIZE(path) - KV_SERIALIZE(transfers_count) - KV_SERIALIZE(transfer_entries_count) - KV_SERIALIZE(is_whatch_only) - KV_SERIALIZE(has_bare_unspent_outputs) - KV_SERIALIZE(utxo_distribution) - KV_SERIALIZE(current_height) + KV_SERIALIZE(address) DOC_DSCR("string; standard public address of the wallet.") DOC_EXMP("ZxDNaMeZjwCjnHuU5gUNyrP1pM3U5vckbakzzV6dEHyDYeCpW8XGLBFTshcaY8LkG9RQn7FsQx8w2JeJzJwPwuDm2NfixPAXf") DOC_END + KV_SERIALIZE(path) DOC_DSCR("Path to wallet file location") DOC_EXMP("/some/path/to/wallet/file.zan") DOC_END + KV_SERIALIZE(transfers_count) DOC_DSCR("Represent number of transactions that happened to this wallet(basically tx history)") DOC_EXMP(11) DOC_END + KV_SERIALIZE(transfer_entries_count) DOC_DSCR("Represent number of internal entries count(each entry represent tx output that have been addressed to this wallet)") DOC_EXMP(24) DOC_END + KV_SERIALIZE(is_whatch_only) DOC_DSCR("Shows if the wallet is watch-only") DOC_EXMP(false) DOC_END + KV_SERIALIZE(has_bare_unspent_outputs) DOC_DSCR("Shows if the wallet still has UTXO from pre-zarcanum era") DOC_EXMP(false) DOC_END + KV_SERIALIZE(utxo_distribution) DOC_DSCR("UTXO distribution for this particular wallet: disabled right now") DOC_EXMP_AUTO(1, "1") DOC_END + KV_SERIALIZE(current_height) DOC_DSCR("Current wallet/daemon height") DOC_EXMP(112132) DOC_END END_KV_SERIALIZE_MAP() }; }; struct COMMAND_RPC_GET_WALLET_RESTORE_INFO { + DOC_COMMAND("Return wallet seed, which could be password-protected(seed secured with passphrase) or open(unsecured seed). If no password provided it returns open (unsecured) seed. "); + struct request { std::string seed_password; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(seed_password) + KV_SERIALIZE(seed_password) DOC_DSCR("Password to secure wallet's seed") DOC_EXMP("010101012") DOC_END END_KV_SERIALIZE_MAP() }; @@ -478,13 +488,15 @@ namespace wallet_public std::string seed_phrase; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(seed_phrase) + KV_SERIALIZE(seed_phrase) DOC_DSCR("Wallet's seed(secured with password if it was provided in argument)") DOC_EXMP("girlfriend unlike offer mutter tightly social silent expect constant bid nowhere reach flower bite salt becomeconversation dog rush quietly become usually lightning midnight each secret class") DOC_END END_KV_SERIALIZE_MAP() }; }; struct COMMAND_RPC_GET_SEED_PHRASE_INFO { + DOC_COMMAND("This call is used to validate seed phrase and to fetch additional information about it"); + typedef seed_info_param request; typedef seed_phrase_info response; }; @@ -509,6 +521,8 @@ namespace wallet_public struct COMMAND_RPC_GET_MINING_HISTORY { + DOC_COMMAND("Returns wallet statistic on mining. As an argument 'v' it receive timestamp from which history is reviewed"); + typedef currency::struct_with_one_t_type request; typedef wallet_public::mining_history response; }; @@ -519,6 +533,8 @@ namespace wallet_public struct COMMAND_RPC_GET_RECENT_TXS_AND_INFO2 { + DOC_COMMAND("Returns wallet history of transactions V2(post-zarcanum version)"); + struct request { @@ -541,12 +557,12 @@ namespace wallet_public std::string order; // "FROM_BEGIN_TO_END" or "FROM_END_TO_BEGIN" BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(offset) - KV_SERIALIZE(count) - KV_SERIALIZE(update_provision_info) - KV_SERIALIZE(exclude_mining_txs) - KV_SERIALIZE(exclude_unconfirmed) - KV_SERIALIZE(order) + KV_SERIALIZE(offset) DOC_DSCR("Offset from what index to start fetching transfers entries(if filters are used then last_item_index could be used from previous call)") DOC_EXMP(0) DOC_END + KV_SERIALIZE(count) DOC_DSCR("How many items to fetch, if items fetched is less then count, then it enumeration is over") DOC_EXMP(100) DOC_END + KV_SERIALIZE(update_provision_info) DOC_DSCR("If update pi is required, could be false only if need to optimize performance(appliable for a veru big wallets)") DOC_EXMP(true) DOC_END + KV_SERIALIZE(exclude_mining_txs) DOC_DSCR("Exclude mining/staking transactions from results(last_item_index should be used for subsequential calls)") DOC_EXMP(false) DOC_END + KV_SERIALIZE(exclude_unconfirmed) DOC_DSCR("Do not include uncomfirmed transactions in results (it also not included is offset is non zero)") DOC_EXMP(false) DOC_END + KV_SERIALIZE(order) DOC_DSCR("Order: \"FROM_BEGIN_TO_END\" or \"FROM_END_TO_BEGIN\"") DOC_EXMP("FROM_END_TO_BEGIN") DOC_END END_KV_SERIALIZE_MAP() }; @@ -569,6 +585,8 @@ namespace wallet_public struct COMMAND_RPC_GET_RECENT_TXS_AND_INFO { + DOC_COMMAND("Returns wallet history of transactions"); + typedef COMMAND_RPC_GET_RECENT_TXS_AND_INFO2::request request; struct response @@ -579,27 +597,26 @@ namespace wallet_public uint64_t last_item_index; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(pi) - KV_SERIALIZE(transfers) - KV_SERIALIZE(total_transfers) - KV_SERIALIZE(last_item_index) + KV_SERIALIZE(pi) DOC_DSCR("Additiona details about balance state") DOC_END + KV_SERIALIZE(transfers) DOC_DSCR("Transfers history array") DOC_EXMP_AUTO(1) DOC_END + KV_SERIALIZE(total_transfers) DOC_DSCR("Total number of transfers in the tx history") DOC_EXMP(1) DOC_END + KV_SERIALIZE(last_item_index) DOC_DSCR("Index of last returned item(might be needed if filters are used)") DOC_EXMP(1) DOC_END END_KV_SERIALIZE_MAP() }; }; - - - struct COMMAND_RPC_REGISTER_ALIAS { + DOC_COMMAND("Register an alias for the address"); + struct request { currency::alias_rpc_details al; crypto::secret_key authority_key; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(al) - KV_SERIALIZE_POD_AS_HEX_STRING(authority_key) + KV_SERIALIZE(al) DOC_DSCR("Alias details") DOC_END + KV_SERIALIZE_POD_AS_HEX_STRING(authority_key) DOC_DSCR("Key for registering aliases shorter than 6 letters (team)") DOC_END END_KV_SERIALIZE_MAP() }; @@ -608,7 +625,7 @@ namespace wallet_public crypto::hash tx_id; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_POD_AS_HEX_STRING(tx_id) + KV_SERIALIZE_POD_AS_HEX_STRING(tx_id) DOC_DSCR("If success - transactions that performs registration(alias becomes available after few confirmations)") DOC_EXMP("97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc") DOC_END END_KV_SERIALIZE_MAP() }; }; @@ -620,14 +637,16 @@ namespace wallet_public std::string address; crypto::public_key asset_id = currency::native_coin_asset_id; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(amount) - KV_SERIALIZE(address) - KV_SERIALIZE_POD_AS_HEX_STRING(asset_id) + KV_SERIALIZE(amount) DOC_DSCR("Amount to transfer to destination") DOC_EXMP(10000000000000) DOC_END + KV_SERIALIZE(address) DOC_DSCR("Destination address") DOC_EXMP("ZxBvJDuQjMG9R2j4WnYUhBYNrwZPwuyXrC7FHdVmWqaESgowDvgfWtiXeNGu8Px9B24pkmjsA39fzSSiEQG1ekB225ZnrMTBp") DOC_END + KV_SERIALIZE_POD_AS_HEX_STRING(asset_id) DOC_DSCR("Asset id to transfer") DOC_EXMP("cc608f59f8080e2fbfe3c8c80eb6e6a953d47cf2d6aebd345bada3a1cab99852") DOC_END END_KV_SERIALIZE_MAP() }; struct COMMAND_RPC_TRANSFER { + DOC_COMMAND("Make new payment transaction from the wallet"); + struct request { std::list destinations; @@ -642,15 +661,15 @@ namespace wallet_public bool service_entries_permanent; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(destinations) - KV_SERIALIZE(fee) - KV_SERIALIZE(mixin) - KV_SERIALIZE(payment_id) - KV_SERIALIZE(comment) - KV_SERIALIZE(push_payer) - KV_SERIALIZE(hide_receiver) - KV_SERIALIZE(service_entries) - KV_SERIALIZE(service_entries_permanent) + KV_SERIALIZE(destinations) DOC_DSCR("List of destinations") DOC_EXMP_AUTO(1) DOC_END + KV_SERIALIZE(fee) DOC_DSCR("Fee to be paid on behalf of sender's wallet(paid in native coins)") DOC_EXMP_AUTO(10000000000) DOC_END + KV_SERIALIZE(mixin) DOC_DSCR("Specifies number of mixins(decoys) that would be used to create input, actual for pre-zarcanum outputs, for post-zarcanum outputs instead of this option, number that is defined by network hard rules(15+)") DOC_EXMP(15) DOC_END + KV_SERIALIZE(payment_id) DOC_DSCR("Hex-encoded payment_id, that normally used for user database by exchanges") DOC_EXMP_AUTO("1dfe5a88ff9effb3") DOC_END + KV_SERIALIZE(comment) DOC_DSCR("Text comment that is displayed in UI") DOC_EXMP_AUTO("Thanks for the coffe") DOC_END + KV_SERIALIZE(push_payer) DOC_DSCR("Reveal information about sender of this transaction, basically add sender address to transaction in encrypted way, so only receiver can see who sent transaction") DOC_EXMP(false) DOC_END + KV_SERIALIZE(hide_receiver) DOC_DSCR("This add to transaction information about remote address(destination), might be needed when the wallet restored from seed phrase and fully resynched, if this option were true, then sender won't be able to see remote address for sent transactions anymore.") DOC_EXMP(true) DOC_END + KV_SERIALIZE(service_entries) DOC_DSCR("Service entries that might be used by different apps that works on top of Zano network, not part of consensus") DOC_EXMP_AUTO(1) DOC_END + KV_SERIALIZE(service_entries_permanent) DOC_DSCR("Point to wallet that service_entries should be placed to 'extra' section of transaction(which won't be pruned after checkpoints)") DOC_EXMP_AUTO(1) DOC_END END_KV_SERIALIZE_MAP() }; @@ -670,6 +689,8 @@ namespace wallet_public struct COMMAND_RPC_STORE { + DOC_COMMAND("Store wallet's data to file"); + struct request { BEGIN_KV_SERIALIZE_MAP() @@ -681,7 +702,7 @@ namespace wallet_public uint64_t wallet_file_size; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(wallet_file_size) + KV_SERIALIZE(wallet_file_size) DOC_DSCR("Resulting file size in bytes") DOC_EXMP(232243) DOC_END END_KV_SERIALIZE_MAP() }; }; @@ -695,24 +716,27 @@ namespace wallet_public uint64_t unlock_time; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(payment_id) - KV_SERIALIZE(tx_hash) - KV_SERIALIZE(amount) - KV_SERIALIZE(block_height) - KV_SERIALIZE(unlock_time) + KV_SERIALIZE(payment_id) DOC_DSCR("Payment id that related to this payment") DOC_EXMP("1dfe5a88ff9effb3") DOC_END + KV_SERIALIZE(tx_hash) DOC_DSCR("Transaction ID that is holding this payment") DOC_EXMP("01220e8304d46b940a86e383d55ca5887b34f158a7365bbcdd17c5a305814a93") DOC_END + KV_SERIALIZE(amount) DOC_DSCR("Amount of native coins transfered") DOC_EXMP(100000000000) DOC_END + KV_SERIALIZE(block_height) DOC_DSCR("Block height that holds transaction") DOC_EXMP(12321) DOC_END + KV_SERIALIZE(unlock_time) DOC_DSCR("Timestamp/blocknumber after which this money would become availabe, recommended don't count transfers that has this field not 0") DOC_EXMP(0) DOC_END END_KV_SERIALIZE_MAP() }; struct COMMAND_RPC_GET_PAYMENTS { + DOC_COMMAND("Gets list of incoming transfers by a given payment ID"); + + struct request { std::string payment_id; // hex-encoded bool allow_locked_transactions; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(payment_id) - KV_SERIALIZE(allow_locked_transactions) + KV_SERIALIZE(payment_id) DOC_DSCR("Payment id that is used to identify transfers") DOC_EXMP("1dfe5a88ff9effb3") DOC_END + KV_SERIALIZE(allow_locked_transactions) DOC_DSCR("Says to wallet if locked transfers should be included or not (false is strongly recomennded)") DOC_EXMP(false) DOC_END END_KV_SERIALIZE_MAP() }; @@ -721,13 +745,16 @@ namespace wallet_public std::list payments; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(payments) + KV_SERIALIZE(payments) DOC_DSCR("Array of payments that connected to given payment_id") DOC_EXMP_AUTO(1) DOC_END END_KV_SERIALIZE_MAP() }; }; struct COMMAND_RPC_GET_BULK_PAYMENTS { + DOC_COMMAND("Gets list of incoming transfers by a given multiple payment_ids"); + + struct request { std::vector payment_ids; @@ -735,30 +762,25 @@ namespace wallet_public bool allow_locked_transactions; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(payment_ids) - KV_SERIALIZE(min_block_height) - KV_SERIALIZE(allow_locked_transactions) + KV_SERIALIZE(payment_ids) DOC_DSCR("Payment ids that is used to identify transfers") DOC_EXMP_AUTO(2, "1dfe5a88ff9effb3") DOC_END + KV_SERIALIZE(min_block_height) DOC_DSCR("Minimal block height to consider") DOC_EXMP(0) DOC_END + KV_SERIALIZE(allow_locked_transactions) DOC_DSCR("Says to wallet if locked transfers should be included or not (false is strongly recomennded)") DOC_EXMP(false) DOC_END END_KV_SERIALIZE_MAP() }; - struct response - { - std::list payments; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(payments) - END_KV_SERIALIZE_MAP() - }; + typedef COMMAND_RPC_GET_PAYMENTS::response response; }; struct COMMAND_RPC_MAKE_INTEGRATED_ADDRESS { + DOC_COMMAND("Generate integrated address"); + struct request { std::string payment_id; // hex-encoded BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(payment_id) + KV_SERIALIZE(payment_id) DOC_DSCR("Hex-encoded Payment ID to be associated with the this address. If empty then wallet would generate new payment id using system random library") DOC_EXMP("1dfe5a88ff9effb3") DOC_END END_KV_SERIALIZE_MAP() }; @@ -768,20 +790,22 @@ namespace wallet_public std::string payment_id; // hex-encoded BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(integrated_address) - KV_SERIALIZE(payment_id) + KV_SERIALIZE(integrated_address) DOC_DSCR("Integrated address combining a standard address and payment ID, if applicable.") DOC_EXMP("iZ2EMyPD7g28hgBfboZeCENaYrHBYZ1bLFi5cgWvn4WJLaxfgs4kqG6cJi9ai2zrXWSCpsvRXit14gKjeijx6YPCLJEv6Fx4rVm1hdAGQFis") DOC_END + KV_SERIALIZE(payment_id) DOC_DSCR("Payment ID associated with the this address.") DOC_EXMP("1dfe5a88ff9effb3") DOC_END END_KV_SERIALIZE_MAP() }; }; struct COMMAND_RPC_SPLIT_INTEGRATED_ADDRESS { + DOC_COMMAND("Decode integrated address"); + struct request { std::string integrated_address; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(integrated_address) + KV_SERIALIZE(integrated_address) DOC_DSCR("Integrated address combining a standard address and payment ID, if applicable.") DOC_EXMP("iZ2EMyPD7g28hgBfboZeCENaYrHBYZ1bLFi5cgWvn4WJLaxfgs4kqG6cJi9ai2zrXWSCpsvRXit14gKjeijx6YPCLJEv6Fx4rVm1hdAGQFis") DOC_END END_KV_SERIALIZE_MAP() }; @@ -791,14 +815,16 @@ namespace wallet_public std::string payment_id; // hex-encoded BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(standard_address) - KV_SERIALIZE(payment_id) + KV_SERIALIZE(standard_address) DOC_DSCR("Standart address.") DOC_EXMP("ZxBvJDuQjMG9R2j4WnYUhBYNrwZPwuyXrC7FHdVmWqaESgowDvgfWtiXeNGu8Px9B24pkmjsA39fzSSiEQG1ekB225ZnrMTBp") DOC_END + KV_SERIALIZE(payment_id) DOC_DSCR("Hex-encoded payment id") DOC_EXMP("1dfe5a88ff9effb3") DOC_END END_KV_SERIALIZE_MAP() }; }; struct COMMAND_SWEEP_BELOW { + DOC_COMMAND("Tries to transfer all coins with amount below the given limit to the given address"); + struct request { uint64_t mixin; @@ -808,11 +834,11 @@ namespace wallet_public uint64_t fee; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(mixin) - KV_SERIALIZE(address) - KV_SERIALIZE(amount) - KV_SERIALIZE(payment_id_hex) - KV_SERIALIZE(fee) + KV_SERIALIZE(mixin) DOC_DSCR("Number of outputs from the blockchain to mix with when sending a transaction to improve privacy.") DOC_EXMP(15) DOC_END + KV_SERIALIZE(address) DOC_DSCR("Public address for sending or receiving native coins.") DOC_EXMP("ZxBvJDuQjMG9R2j4WnYUhBYNrwZPwuyXrC7FHdVmWqaESgowDvgfWtiXeNGu8Px9B24pkmjsA39fzSSiEQG1ekB225ZnrMTBp") DOC_END + KV_SERIALIZE(amount) DOC_DSCR("Threshold amount of native coins to sweep.") DOC_EXMP(1000000000000) DOC_END + KV_SERIALIZE(payment_id_hex) DOC_DSCR("Payment ID associated with the transaction in hexadecimal format.") DOC_EXMP("1dfe5a88ff9effb3") DOC_END + KV_SERIALIZE(fee) DOC_DSCR("Transaction fee required for processing the transaction.") DOC_EXMP(10000000000) DOC_END END_KV_SERIALIZE_MAP() }; @@ -826,18 +852,21 @@ namespace wallet_public uint64_t amount_swept; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(tx_hash) - KV_SERIALIZE(tx_unsigned_hex) - KV_SERIALIZE(outs_total) - KV_SERIALIZE(amount_total) - KV_SERIALIZE(outs_swept) - KV_SERIALIZE(amount_swept) + KV_SERIALIZE(tx_hash) DOC_DSCR("Transaction ID (hash) format.") DOC_EXMP("01220e8304d46b940a86e383d55ca5887b34f158a7365bbcdd17c5a305814a93") DOC_END + KV_SERIALIZE(tx_unsigned_hex) DOC_DSCR("Unsigned transaction data in hexadecimal format.") DOC_EXMP("8304d46b940a86e383d55ca5887b34f158a7365bbcdd17c5a305814a9334f158a7368304d46b940a86e383d55ca5887b34f158a7365bbcdd17c5a305814a9334f158a736") DOC_END + KV_SERIALIZE(outs_total) DOC_DSCR("Total number of outputs in the transaction.") DOC_EXMP(10) DOC_END + KV_SERIALIZE(amount_total) DOC_DSCR("Total amount of native coins involved in the transaction.") DOC_EXMP(100000000000) DOC_END + KV_SERIALIZE(outs_swept) DOC_DSCR("Number of outputs swept in the transaction.") DOC_EXMP(112) DOC_END + KV_SERIALIZE(amount_swept) DOC_DSCR("Amount of native coins swept in the transaction.") DOC_EXMP(101000000000) DOC_END END_KV_SERIALIZE_MAP() }; }; struct COMMAND_RPC_GET_BARE_OUTS_STATS { + DOC_COMMAND("Return information about wallet's pre-zarcanum era outputs. Those outputs should be converted to post-zarcanum varian with trnasfering it sooner or later. (Only outputs that have been created in Zarcanum era can participaet in staking)"); + + struct request { BEGIN_KV_SERIALIZE_MAP() @@ -852,16 +881,19 @@ namespace wallet_public uint64_t txs_count; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(total_bare_outs) - KV_SERIALIZE(total_amount) - KV_SERIALIZE(expected_total_fee) - KV_SERIALIZE(txs_count) + KV_SERIALIZE(total_bare_outs) DOC_DSCR("Total number of inspent bare outputs in the wallet.") DOC_EXMP(112) DOC_END + KV_SERIALIZE(total_amount) DOC_DSCR("Total amount of native coins involved in bare outputs.") DOC_EXMP(12000000000000) DOC_END + KV_SERIALIZE(expected_total_fee) DOC_DSCR("Expected total transaction fee required for processing the transaction.") DOC_EXMP(10000000000) DOC_END + KV_SERIALIZE(txs_count) DOC_DSCR("Total number of transactions needed to convert all bare outputs .") DOC_EXMP(2) DOC_END END_KV_SERIALIZE_MAP() }; }; struct COMMAND_RPC_SWEEP_BARE_OUTS { + DOC_COMMAND("Execute transactions needed be convert all bare(pre-zarcanum) outputs to post-zarcanum outputs. (Only outputs that have been created in Zarcanum era can participaet in staking)"); + + struct request { BEGIN_KV_SERIALIZE_MAP() @@ -876,22 +908,24 @@ namespace wallet_public uint64_t txs_sent; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(bare_outs_swept) - KV_SERIALIZE(amount_swept) - KV_SERIALIZE(fee_spent) - KV_SERIALIZE(txs_sent) + KV_SERIALIZE(bare_outs_swept) DOC_DSCR("Number of bare outputs swept in the transactions.") DOC_EXMP(112) DOC_END + KV_SERIALIZE(amount_swept) DOC_DSCR("Amount of native coins swept in the transactions.") DOC_EXMP(12000000000000) DOC_END + KV_SERIALIZE(fee_spent) DOC_DSCR("Total fee spent on the transactions.") DOC_EXMP(10000000000) DOC_END + KV_SERIALIZE(txs_sent) DOC_DSCR("Total number of transactions sent.") DOC_EXMP(2) DOC_END END_KV_SERIALIZE_MAP() }; }; struct COMMAND_SIGN_TRANSFER { + DOC_COMMAND("Sign transaction with the wallet's keys"); + struct request { std::string tx_unsigned_hex; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(tx_unsigned_hex) + KV_SERIALIZE(tx_unsigned_hex) DOC_DSCR("Unsigned transaction hex-encoded blob.") DOC_EXMP("8304d46b940a86e383d55ca5887b34f158a7365bbcdd17c5a305814a9334f158a7368304d46b940a86e383d55ca5887b34f158a7365bbcdd17c5a305814a9334f158a736") DOC_END END_KV_SERIALIZE_MAP() }; @@ -901,22 +935,22 @@ namespace wallet_public std::string tx_hash; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(tx_signed_hex) - KV_SERIALIZE(tx_hash) + KV_SERIALIZE(tx_signed_hex) DOC_DSCR("Signed transaction hex-encoded blob.") DOC_EXMP("8304d46b940a86e383d55ca5887b34f158a7365bbcdd17c5a305814a9334f158a7368304d46b940a86e383d55ca5887b34f158a7365bbcdd17c5a305814a9334f158a7368304d46b940a86e383d55ca5887b34f158a7365bbcdd17c5a305814a9334f158a7368304d46b940a86e383d55ca5887b34f158a7365bbcdd17c5a305814a9334f158a736") DOC_END + KV_SERIALIZE(tx_hash) DOC_DSCR("Signed transaction hash.") DOC_EXMP("01220e8304d46b940a86e383d55ca5887b34f158a7365bbcdd17c5a305814a93") DOC_END END_KV_SERIALIZE_MAP() }; }; struct COMMAND_SUBMIT_TRANSFER { + DOC_COMMAND("Relay signed transaction over the network"); + struct request { - //std::string tx_unsigned_hex; std::string tx_signed_hex; BEGIN_KV_SERIALIZE_MAP() - //KV_SERIALIZE(tx_unsigned_hex) - KV_SERIALIZE(tx_signed_hex) + KV_SERIALIZE(tx_signed_hex) DOC_DSCR("Signed transaction hex-encoded blob.") DOC_EXMP("8304d46b940a86e383d55ca5887b34f158a7365bbcdd17c5a305814a9334f158a7368304d46b940a86e383d55ca5887b34f158a7365bbcdd17c5a305814a9334f158a7368304d46b940a86e383d55ca5887b34f158a7365bbcdd17c5a305814a9334f158a7368304d46b940a86e383d55ca5887b34f158a7365bbcdd17c5a305814a9334f158a736") DOC_END END_KV_SERIALIZE_MAP() }; @@ -925,7 +959,7 @@ namespace wallet_public std::string tx_hash; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(tx_hash) + KV_SERIALIZE(tx_hash) DOC_DSCR("Signed transaction hash.") DOC_EXMP("01220e8304d46b940a86e383d55ca5887b34f158a7365bbcdd17c5a305814a93") DOC_END END_KV_SERIALIZE_MAP() }; }; @@ -1163,10 +1197,18 @@ namespace wallet_public }; //-------------------- - typedef currency::COMMAND_RPC_GET_OFFERS_EX COMMAND_MARKETPLACE_GET_MY_OFFERS; + struct COMMAND_MARKETPLACE_GET_MY_OFFERS + { + DOC_COMMAND("Fetch wallet's offers listed in the marketplace with given filters"); + + typedef currency::COMMAND_RPC_GET_OFFERS_EX::request request; + typedef currency::COMMAND_RPC_GET_OFFERS_EX::response response; + }; struct COMMAND_MARKETPLACE_PUSH_OFFER { + DOC_COMMAND("Creates new offer and publish it on the blockchain"); + struct request { bc_services::offer_details_ex od; @@ -1183,14 +1225,16 @@ namespace wallet_public uint64_t tx_blob_size; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(tx_hash) - KV_SERIALIZE(tx_blob_size) + KV_SERIALIZE(tx_hash) DOC_DSCR("Transaction hash") DOC_EXMP("40fa6db923728b38962718c61b4dc3af1acaa1967479c73703e260dc3609c58d") DOC_END + KV_SERIALIZE(tx_blob_size) DOC_DSCR("Size of the transaction blob") DOC_EXMP(1234) DOC_END END_KV_SERIALIZE_MAP() }; }; struct COMMAND_MARKETPLACE_PUSH_UPDATE_OFFER { + DOC_COMMAND("Updates existing offer that this wallet created, and publish updated version on the blockchain"); + struct request { crypto::hash tx_id; @@ -1198,8 +1242,8 @@ namespace wallet_public bc_services::offer_details_ex od; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_POD_AS_HEX_STRING(tx_id) - KV_SERIALIZE(no) + KV_SERIALIZE_POD_AS_HEX_STRING(tx_id) DOC_DSCR("Transaction ID represented as a hexadecimal string") DOC_EXMP("40fa6db923728b38962718c61b4dc3af1acaa1967479c73703e260dc3609c58d") DOC_END + KV_SERIALIZE(no) DOC_DSCR("Number of offer entrie inside transacton(likely 0)") DOC_EXMP(0) DOC_END KV_SERIALIZE(od) END_KV_SERIALIZE_MAP() }; @@ -1211,14 +1255,16 @@ namespace wallet_public uint64_t tx_blob_size; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(tx_hash) - KV_SERIALIZE(tx_blob_size) + KV_SERIALIZE(tx_hash) DOC_DSCR("Transaction hash") DOC_EXMP("40fa6db923728b38962718c61b4dc3af1acaa1967479c73703e260dc3609c58d") DOC_END + KV_SERIALIZE(tx_blob_size) DOC_DSCR("Size of the transaction blob") DOC_EXMP(1232) DOC_END END_KV_SERIALIZE_MAP() }; }; struct COMMAND_MARKETPLACE_CANCEL_OFFER { + DOC_COMMAND("Cancel existing offer that this wallet created(it actually create transaction that says that existing order got canceled)"); + struct request { crypto::hash tx_id; @@ -1226,9 +1272,9 @@ namespace wallet_public uint64_t fee; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_POD_AS_HEX_STRING(tx_id) - KV_SERIALIZE(no) - KV_SERIALIZE(fee) + KV_SERIALIZE_POD_AS_HEX_STRING(tx_id) DOC_DSCR("Transaction ID represented as a hexadecimal string") DOC_EXMP("40fa6db923728b38962718c61b4dc3af1acaa1967479c73703e260dc3609c58d") DOC_END + KV_SERIALIZE(no) DOC_DSCR("Number of offer entrie inside transacton(likely 0)") DOC_EXMP(0) DOC_END + KV_SERIALIZE(fee) DOC_DSCR("Fee for operation") DOC_EXMP(10000000000) DOC_END END_KV_SERIALIZE_MAP() }; @@ -1239,36 +1285,33 @@ namespace wallet_public uint64_t tx_blob_size; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(tx_hash) - KV_SERIALIZE(tx_blob_size) + KV_SERIALIZE(tx_hash) DOC_DSCR("Transaction hash") DOC_EXMP("40fa6db923728b38962718c61b4dc3af1acaa1967479c73703e260dc3609c58d") DOC_END + KV_SERIALIZE(tx_blob_size) DOC_DSCR("Size of the transaction blob") DOC_EXMP(1232) DOC_END END_KV_SERIALIZE_MAP() }; }; struct COMMAND_RPC_SEARCH_FOR_TRANSACTIONS { + DOC_COMMAND("Search for transacrions in the wallet by few parameters"); struct request { crypto::hash tx_id; bool in; bool out; - //bool pending; - //bool failed; bool pool; bool filter_by_height; uint64_t min_height; uint64_t max_height; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_POD_AS_HEX_STRING(tx_id) - KV_SERIALIZE(in) - KV_SERIALIZE(out) - //KV_SERIALIZE(pending) - //KV_SERIALIZE(failed) - KV_SERIALIZE(pool) - KV_SERIALIZE(filter_by_height) - KV_SERIALIZE(min_height) - KV_SERIALIZE(max_height) + KV_SERIALIZE_POD_AS_HEX_STRING(tx_id) DOC_DSCR("Transaction ID represented as a hexadecimal string.") DOC_EXMP("97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc") DOC_END + KV_SERIALIZE(in) DOC_DSCR("Search over incoming transactions.") DOC_EXMP(true) DOC_END + KV_SERIALIZE(out) DOC_DSCR("Search over outgoing transactions.") DOC_EXMP(true) DOC_END + KV_SERIALIZE(pool) DOC_DSCR("Search over pool transactions.") DOC_EXMP(false) DOC_END + KV_SERIALIZE(filter_by_height) DOC_DSCR("Do filter transactions by height or not.") DOC_EXMP(true) DOC_END + KV_SERIALIZE(min_height) DOC_DSCR("Minimum height for filtering transactions.") DOC_EXMP(11000) DOC_END + KV_SERIALIZE(max_height) DOC_DSCR("Maximum height for filtering transactions.") DOC_EXMP(20000) DOC_END END_KV_SERIALIZE_MAP() }; @@ -1276,38 +1319,32 @@ namespace wallet_public { std::list in; std::list out; - //std::list pending; - //std::list failed; std::list pool; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(in) - KV_SERIALIZE(out) - //KV_SERIALIZE(pending) - //KV_SERIALIZE(failed) - KV_SERIALIZE(pool) + KV_SERIALIZE(in) DOC_DSCR("List of incoming transactions.") DOC_EXMP_AUTO(1) DOC_END + KV_SERIALIZE(out) DOC_DSCR("List of outgoing transactions.") DOC_EXMP_AUTO(1) DOC_END + KV_SERIALIZE(pool) DOC_DSCR("List of pool transactions.") DOC_EXMP_AUTO(1) DOC_END END_KV_SERIALIZE_MAP() }; }; struct COMMAND_RPC_SEARCH_FOR_TRANSACTIONS_LEGACY - { + { + DOC_COMMAND("Search for transacrions in the wallet by few parameters(legacy version)"); + typedef COMMAND_RPC_SEARCH_FOR_TRANSACTIONS::request request; struct response { std::list in; std::list out; - //std::list pending; - //std::list failed; std::list pool; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(in) - KV_SERIALIZE(out) - //KV_SERIALIZE(pending) - //KV_SERIALIZE(failed) - KV_SERIALIZE(pool) + KV_SERIALIZE(in) DOC_DSCR("List of incoming transactions.") DOC_EXMP_AUTO(1) DOC_END + KV_SERIALIZE(out) DOC_DSCR("List of outgoing transactions.") DOC_EXMP_AUTO(1) DOC_END + KV_SERIALIZE(pool) DOC_DSCR("List of pool transactions.") DOC_EXMP_AUTO(1) DOC_END END_KV_SERIALIZE_MAP() }; }; @@ -1475,17 +1512,15 @@ namespace wallet_public { std::vector to_finalizer; //assets that addressed to receiver of proposal (aka Bob, aka "finalizer") and funded by side that creating proposal (aka Alice, aka "initiator") std::vector to_initiator; //assets addressed to initiator of proposal (aka Alice, aka "initiator") and expected to be funded by the side that receiving proposal (aka Bob, aka "finalizer") - uint64_t mixins; + //uint64_t mixins; uint64_t fee_paid_by_a; //uint64_t expiration_time; BEGIN_KV_SERIALIZE_MAP() - - KV_SERIALIZE(to_finalizer) - KV_SERIALIZE(to_initiator) - KV_SERIALIZE(mixins) - KV_SERIALIZE(fee_paid_by_a) - //KV_SERIALIZE(expiration_time) + KV_SERIALIZE(to_finalizer) DOC_DSCR("Assets sent to the finalizer") DOC_EXMP_AUTO(1, asset_funds{ epee::transform_str_to_t_pod("97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc"), 1000000000000}) DOC_END + KV_SERIALIZE(to_initiator) DOC_DSCR("Assets sent to the initiator") DOC_EXMP_AUTO(1, asset_funds{ currency::native_coin_asset_id, 10000000000}) DOC_END + //KV_SERIALIZE(mixins) DOC_DSCR("Number of mixins used") DOC_EXMP() DOC_END + KV_SERIALIZE(fee_paid_by_a) DOC_DSCR("Fee paid by party A(initiator)") DOC_EXMP(10000000000) DOC_END END_KV_SERIALIZE_MAP() }; @@ -1529,13 +1564,16 @@ namespace wallet_public struct COMMAND_IONIC_SWAP_GENERATE_PROPOSAL { + DOC_COMMAND("Generates ionic swap proposal according to details provided in request, result present as hex-encoded blob, that should be passed to recepient to validate this proposal and executing on it") + struct request { ionic_swap_proposal_info proposal; std::string destination_address; + BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(proposal) - KV_SERIALIZE(destination_address) + KV_SERIALIZE(proposal) DOC_DSCR("Proposal details") DOC_END + KV_SERIALIZE(destination_address) DOC_DSCR("Destination address") DOC_EXMP("ZxBvJDuQjMG9R2j4WnYUhBYNrwZPwuyXrC7FHdVmWqaESgowDvgfWtiXeNGu8Px9B24pkmjsA39fzSSiEQG1ekB225ZnrMTBp") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1545,19 +1583,22 @@ namespace wallet_public std::string hex_raw_proposal; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(hex_raw_proposal) + KV_SERIALIZE(hex_raw_proposal) DOC_DSCR("Hex-encoded proposal raw data(encrypted with common shared key). Includes half-created transaction template and some extra information that would be needed counterparty to finialize and sign transaction") DOC_EXMP("97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc") DOC_END END_KV_SERIALIZE_MAP() }; }; struct COMMAND_IONIC_SWAP_GET_PROPOSAL_INFO { + DOC_COMMAND("Reads hex-encoded ionic swap proposal info, generated by other user and addressed to this wallet") + + struct request { std::string hex_raw_proposal; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(hex_raw_proposal) + KV_SERIALIZE(hex_raw_proposal) DOC_DSCR("Hex-encoded proposal raw data(encrypted with common shared key). Includes half-created transaction template and some extra information that would be needed counterparty to finialize and sign transaction") DOC_EXMP("97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1567,19 +1608,22 @@ namespace wallet_public ionic_swap_proposal_info proposal; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(proposal) + KV_SERIALIZE(proposal) DOC_DSCR("Proposal details") DOC_END END_KV_SERIALIZE_MAP() }; }; struct COMMAND_IONIC_SWAP_ACCEPT_PROPOSAL { + DOC_COMMAND("This essential command actually execute proposal that was sent by counter party, by completing and signing transaction template that was in proposal, and sending it to the network.") + + struct request { std::string hex_raw_proposal; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(hex_raw_proposal) + KV_SERIALIZE(hex_raw_proposal) DOC_DSCR("Hex-encoded proposal raw data(encrypted with common shared key). Includes half-created transaction template and some extra information that would be needed counterparty to finialize and sign transaction") DOC_EXMP("97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1589,7 +1633,7 @@ namespace wallet_public crypto::hash result_tx_id; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_POD_AS_HEX_STRING(result_tx_id) + KV_SERIALIZE_POD_AS_HEX_STRING(result_tx_id) DOC_DSCR("Result transaction id") DOC_EXMP("97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc") DOC_END END_KV_SERIALIZE_MAP() }; }; @@ -1607,14 +1651,14 @@ namespace wallet_public bool has_bare_unspent_outputs; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(balances) - KV_SERIALIZE(mined_total) - KV_SERIALIZE(address) - KV_SERIALIZE(view_sec_key) - KV_SERIALIZE(path) - KV_SERIALIZE(is_auditable) - KV_SERIALIZE(is_watch_only) - KV_SERIALIZE(has_bare_unspent_outputs) + KV_SERIALIZE(balances) DOC_DSCR("Balances hold by this wallet") DOC_EXMP_AUTO(1) DOC_END + KV_SERIALIZE(mined_total) DOC_DSCR("Total amount mined") DOC_EXMP(1000000000000) DOC_END + KV_SERIALIZE(address) DOC_DSCR("Address") DOC_EXMP("ZxBvJDuQjMG9R2j4WnYUhBYNrwZPwuyXrC7FHdVmWqaESgowDvgfWtiXeNGu8Px9B24pkmjsA39fzSSiEQG1ekB225ZnrMTBp") DOC_END + KV_SERIALIZE(view_sec_key) DOC_DSCR("View secret key") DOC_EXMP("97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc") DOC_END + KV_SERIALIZE(path) DOC_DSCR("Path to wallet file") DOC_EXMP("/some/path/to/wallet/file.zan") DOC_END + KV_SERIALIZE(is_auditable) DOC_DSCR("Flag indicating whether the wallet is auditable") DOC_EXMP(false) DOC_END + KV_SERIALIZE(is_watch_only) DOC_DSCR("Flag indicating whether the wallet is watch-only") DOC_EXMP(false) DOC_END + KV_SERIALIZE(has_bare_unspent_outputs) DOC_DSCR("Flag indicating whether the wallet has bare unspent outputs(pre-zarcanum outputs)") DOC_EXMP(false) DOC_END END_KV_SERIALIZE_MAP() }; @@ -1643,13 +1687,15 @@ namespace wallet_public BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(wi) - KV_SERIALIZE(wallet_id) + KV_SERIALIZE(wallet_id) DOC_DSCR("Wallet ID") DOC_EXMP() DOC_END END_KV_SERIALIZE_MAP() }; struct COMMAND_MW_GET_WALLETS { + DOC_COMMAND("Get loaded wallets list, userful for multi-wallet API") + struct request { BEGIN_KV_SERIALIZE_MAP() @@ -1661,19 +1707,21 @@ namespace wallet_public std::vector wallets; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(wallets) + KV_SERIALIZE(wallets) DOC_DSCR("Array of wallets") DOC_EXMP_AUTO(1) DOC_END END_KV_SERIALIZE_MAP() }; }; struct COMMAND_MW_SELECT_WALLET { + DOC_COMMAND("Select curent active wallet, after that all wallet RPC call would be addressed to this wallet") + struct request { uint64_t wallet_id; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(wallet_id) + KV_SERIALIZE(wallet_id) DOC_DSCR("Wallet id") DOC_EXMP_AUTO(2) DOC_END END_KV_SERIALIZE_MAP() }; @@ -1682,19 +1730,21 @@ namespace wallet_public { std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) + KV_SERIALIZE(status) DOC_DSCR("Result (OK if success)") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; struct COMMAND_SIGN_MESSAGE { + DOC_COMMAND("Trivially sign base64 encoded data message using wallet spend key") + struct request { std::string buff; //base64 encoded data BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(buff) + KV_SERIALIZE(buff) DOC_DSCR("base64 encoded data message to be signed") DOC_EXMP("ZGNjc2Ztc2xrZm12O2xrZm12OydlbGtmdm0nbGtmbXY=") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1705,20 +1755,22 @@ namespace wallet_public crypto::public_key pkey = currency::null_pkey; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_POD_AS_HEX_STRING(sig) - KV_SERIALIZE_POD_AS_HEX_STRING(pkey) + KV_SERIALIZE_POD_AS_HEX_STRING(sig) DOC_DSCR("Signature represented as a hexadecimal string") DOC_EXMP("97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc") DOC_END + KV_SERIALIZE_POD_AS_HEX_STRING(pkey) DOC_DSCR("Wallet's public key represented as a hexadecimal string") DOC_EXMP("97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc") DOC_END END_KV_SERIALIZE_MAP() }; }; struct COMMAND_ENCRYPT_DATA { + DOC_COMMAND("Trivially encrypt base64 encoded data message with chacha using wallet spend key") + struct request { std::string buff; //base64 encoded data BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(buff) + KV_SERIALIZE(buff) DOC_DSCR("base64 encoded data message to be encrypted") DOC_EXMP("ZGNjc2Ztc2xrZm12O2xrZm12OydlbGtmdm0nbGtmbXY=") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1726,19 +1778,20 @@ namespace wallet_public { std::string res_buff; //base64 encoded encrypted data BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(res_buff) + KV_SERIALIZE(res_buff) DOC_DSCR("base64 encoded resulted data message") DOC_EXMP("ZGNjc2Ztc2xrZm12O2xrZm12OydlbGtmdm0nbGtmbXY=") DOC_END END_KV_SERIALIZE_MAP() }; }; struct COMMAND_DECRYPT_DATA { + DOC_COMMAND("Trivially decrypt base64 encoded data message with chacha using wallet spend key") struct request { std::string buff; //base64 encoded encrypted data BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(buff) + KV_SERIALIZE(buff) DOC_DSCR("base64 encoded data message to be decrypted") DOC_EXMP("ZGNjc2Ztc2xrZm12O2xrZm12OydlbGtmdm0nbGtmbXY=") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1748,22 +1801,23 @@ namespace wallet_public std::string res_buff; //base64 encoded data BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(res_buff) + KV_SERIALIZE(res_buff) DOC_DSCR("base64 encoded resulted data message") DOC_EXMP("ZGNjc2Ztc2xrZm12O2xrZm12OydlbGtmdm0nbGtmbXY=") DOC_END END_KV_SERIALIZE_MAP() }; }; struct COMMAND_PROXY_TO_DAEMON { + DOC_COMMAND("Proxy call to daemon(node), might be not effective in some cases, so need to be carefull with use of it") + struct request { - std::string uri; std::string base64_body; //base64 encoded body BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(uri) - KV_SERIALIZE(base64_body) + KV_SERIALIZE(uri) DOC_DSCR("URI for daemon API") DOC_EXMP("/json_rpc") DOC_END + KV_SERIALIZE(base64_body) DOC_DSCR("Base64 encoded request body") DOC_EXMP("ewogICAgImpzb25ycGMiOiAiMi4wIiwKICAgICJpZCI6IDAsCiAgICAibWV0aG9kIjogImdldF9taW5pbmdfaGlzdG9yeSIKfQ==") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1773,8 +1827,8 @@ namespace wallet_public int32_t response_code; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(base64_body) - KV_SERIALIZE(response_code) + KV_SERIALIZE(base64_body) DOC_DSCR("Base64 encoded daemon response body") DOC_EXMP("ewogICJpZCI6IDAsCiAgImpzb25ycGMiOiAiMi4wIiwKICAicmVzdWx0IjogewogICAgInBheW1lbnRzIjogWwogICAgICB7CiAgICAgICAgInBheW1lbnRfaWQiOiAiMDAwMDAwMDBmZjAwZmYwMCIsCiAgICAgICAgImFtb3VudCI6IDEwMDAwMDAwMCwKICAgICAgICAiYmxvY2tfaGVpZ2h0IjogMjAyNTU2LAogICAgICAgICJ0eF9oYXNoIjogIjAxMjIwZTgzMDRkNDZiOTQwYTg2ZTM4M2Q1NWNhNTg4N2IzNGYxNThhNzM2NWJiY2RkMTdjNWEzMDU4MTRhOTMiLAogICAgICAgICJ1bmxvY2tfdGltZSI6IDAKICAgICAgfSwKICAgICAgewogICAgICAgICJwYXltZW50X2lkIjogIjAwMDAwMDAwZmYwMGZmMDEiLAogICAgICAgICJhbW91bnQiOiAxMDAwMDAwMDAsCiAgICAgICAgImJsb2NrX2hlaWdodCI6IDIwMjU1NiwKICAgICAgICAidHhfaGFzaCI6ICIwYjVlYjk2ODVjMGMxMWRiNzdlMmNkZDk4NzljOGQzYjgxNTUyM2M2ZTRiZjAzZGNlZTYyYzU4M2I3ZTFmNzcyIiwKICAgICAgICAidW5sb2NrX3RpbWUiOiAwCiAgICAgIH0KICAgIF0KICB9Cn0=") DOC_END + KV_SERIALIZE(response_code) DOC_DSCR("Response code") DOC_EXMP(200) DOC_END END_KV_SERIALIZE_MAP() }; }; @@ -1821,6 +1875,9 @@ namespace wallet_public struct COMMAND_ASSETS_WHITELIST_GET { + DOC_COMMAND("Get whitelisted assets for this wallet, assets descriptors present in any of the lists in results would be present in balance() call results(if those assets are part of the wallet transfers). Assets that are not included in those lists won't be included in balance even if the wallet own inputs with such assets.") + + struct request { BEGIN_KV_SERIALIZE_MAP() @@ -1836,21 +1893,23 @@ namespace wallet_public BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(local_whitelist) - KV_SERIALIZE(global_whitelist) - KV_SERIALIZE(own_assets) + KV_SERIALIZE(local_whitelist) DOC_DSCR("Local whitelist, assets that hase been added to this wallet file manually(!)") DOC_EXMP_AUTO(1) DOC_END + KV_SERIALIZE(global_whitelist) DOC_DSCR("Global whitelist, well-known assets with adoption, mantained by the team and community") DOC_EXMP_AUTO(1) DOC_END + KV_SERIALIZE(own_assets) DOC_DSCR("Own assets, the ones that is under control of this wallet") DOC_EXMP_AUTO(1) DOC_END END_KV_SERIALIZE_MAP() }; }; struct COMMAND_ASSETS_WHITELIST_ADD { + DOC_COMMAND("Add given asset id to local whitelist. This whitelist is stored with the wallet file and reset in case of wallet resync or restoring wallet from seed phrase.") + struct request { crypto::public_key asset_id = currency::null_pkey; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_POD_AS_HEX_STRING(asset_id) + KV_SERIALIZE_POD_AS_HEX_STRING(asset_id) DOC_DSCR("Asset id that needed to be added to local whitelist, asset_id must exist in the network") DOC_EXMP("f74bb56a5b4fa562e679ccaadd697463498a66de4f1760b2cd40f11c3a00a7a8") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1861,20 +1920,22 @@ namespace wallet_public currency::asset_descriptor_base asset_descriptor; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) - KV_SERIALIZE(asset_descriptor) + KV_SERIALIZE(status) DOC_DSCR("Status of the asset") DOC_EXMP("OK") DOC_END + KV_SERIALIZE(asset_descriptor) DOC_DSCR("Details of the asset, recieved from node") DOC_END END_KV_SERIALIZE_MAP() }; }; struct COMMAND_ASSETS_WHITELIST_REMOVE { + DOC_COMMAND("Remove given asset id from local whitelist. This whitelist is stored with the wallet file and reset in case of wallet resync or restoring wallet from seed phrase.") + struct request { crypto::public_key asset_id = currency::null_pkey; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_POD_AS_HEX_STRING(asset_id) + KV_SERIALIZE_POD_AS_HEX_STRING(asset_id) DOC_DSCR("Asset id to be removed from local whitelist") DOC_EXMP("f74bb56a5b4fa562e679ccaadd697463498a66de4f1760b2cd40f11c3a00a7a8") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1884,7 +1945,7 @@ namespace wallet_public std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) + KV_SERIALIZE(status) DOC_DSCR("Command result (OK if success)") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 9a8dd1d1..4428ee3a 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -284,7 +284,7 @@ namespace tools response.m_response_comment = "Internal Server Error"; return true; } - if (!handle_http_request_map(query_info, response, m_conn_context, call_found, reference_stub) && response.m_response_code == 200) + if (!handle_http_request_map(query_info, response, m_conn_context, call_found) && response.m_response_code == 200) { response.m_response_code = 500; response.m_response_comment = "Internal Server Error"; diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index 7e8f4843..e5451a37 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -117,22 +117,22 @@ namespace tools MAP_JON_RPC_WE("get_mining_history", on_get_mining_history, wallet_public::COMMAND_RPC_GET_MINING_HISTORY) MAP_JON_RPC_WE("register_alias", on_register_alias, wallet_public::COMMAND_RPC_REGISTER_ALIAS) //contracts API - MAP_JON_RPC_WE("contracts_send_proposal", on_contracts_send_proposal, wallet_public::COMMAND_CONTRACTS_SEND_PROPOSAL) - MAP_JON_RPC_WE("contracts_accept_proposal", on_contracts_accept_proposal, wallet_public::COMMAND_CONTRACTS_ACCEPT_PROPOSAL) - MAP_JON_RPC_WE("contracts_get_all", on_contracts_get_all, wallet_public::COMMAND_CONTRACTS_GET_ALL) - MAP_JON_RPC_WE("contracts_release", on_contracts_release, wallet_public::COMMAND_CONTRACTS_RELEASE) - MAP_JON_RPC_WE("contracts_request_cancel", on_contracts_request_cancel, wallet_public::COMMAND_CONTRACTS_REQUEST_CANCEL) - MAP_JON_RPC_WE("contracts_accept_cancel", on_contracts_accept_cancel, wallet_public::COMMAND_CONTRACTS_ACCEPT_CANCEL) + //MAP_JON_RPC_WE("contracts_send_proposal", on_contracts_send_proposal, wallet_public::COMMAND_CONTRACTS_SEND_PROPOSAL) + //MAP_JON_RPC_WE("contracts_accept_proposal", on_contracts_accept_proposal, wallet_public::COMMAND_CONTRACTS_ACCEPT_PROPOSAL) + //MAP_JON_RPC_WE("contracts_get_all", on_contracts_get_all, wallet_public::COMMAND_CONTRACTS_GET_ALL) + //MAP_JON_RPC_WE("contracts_release", on_contracts_release, wallet_public::COMMAND_CONTRACTS_RELEASE) + //MAP_JON_RPC_WE("contracts_request_cancel", on_contracts_request_cancel, wallet_public::COMMAND_CONTRACTS_REQUEST_CANCEL) + //MAP_JON_RPC_WE("contracts_accept_cancel", on_contracts_accept_cancel, wallet_public::COMMAND_CONTRACTS_ACCEPT_CANCEL) //marketplace API MAP_JON_RPC_WE("marketplace_get_offers_ex", on_marketplace_get_my_offers, wallet_public::COMMAND_MARKETPLACE_GET_MY_OFFERS) MAP_JON_RPC_WE("marketplace_push_offer", on_marketplace_push_offer, wallet_public::COMMAND_MARKETPLACE_PUSH_OFFER) MAP_JON_RPC_WE("marketplace_push_update_offer", on_marketplace_push_update_offer, wallet_public::COMMAND_MARKETPLACE_PUSH_UPDATE_OFFER) MAP_JON_RPC_WE("marketplace_cancel_offer", on_marketplace_cancel_offer, wallet_public::COMMAND_MARKETPLACE_CANCEL_OFFER) //HTLC API - MAP_JON_RPC_WE("atomics_create_htlc_proposal", on_create_htlc_proposal, wallet_public::COMMAND_CREATE_HTLC_PROPOSAL) - MAP_JON_RPC_WE("atomics_get_list_of_active_htlc", on_get_list_of_active_htlc, wallet_public::COMMAND_GET_LIST_OF_ACTIVE_HTLC) - MAP_JON_RPC_WE("atomics_redeem_htlc", on_redeem_htlc, wallet_public::COMMAND_REDEEM_HTLC) - MAP_JON_RPC_WE("atomics_check_htlc_redeemed", on_check_htlc_redeemed, wallet_public::COMMAND_CHECK_HTLC_REDEEMED) + //MAP_JON_RPC_WE("atomics_create_htlc_proposal", on_create_htlc_proposal, wallet_public::COMMAND_CREATE_HTLC_PROPOSAL) + //MAP_JON_RPC_WE("atomics_get_list_of_active_htlc", on_get_list_of_active_htlc, wallet_public::COMMAND_GET_LIST_OF_ACTIVE_HTLC) + //MAP_JON_RPC_WE("atomics_redeem_htlc", on_redeem_htlc, wallet_public::COMMAND_REDEEM_HTLC) + //MAP_JON_RPC_WE("atomics_check_htlc_redeemed", on_check_htlc_redeemed, wallet_public::COMMAND_CHECK_HTLC_REDEEMED) //IONIC_SWAPS API MAP_JON_RPC_WE("ionic_swap_generate_proposal", on_ionic_swap_generate_proposal, wallet_public::COMMAND_IONIC_SWAP_GENERATE_PROPOSAL) @@ -145,16 +145,16 @@ namespace tools MAP_JON_RPC_WE("assets_whitelist_remove", on_assets_whitelist_remove, wallet_public::COMMAND_ASSETS_WHITELIST_REMOVE) //MULTIWALLET APIs - MAP_JON_RPC_WE("mw_get_wallets", on_mw_get_wallets, wallet_public::COMMAND_MW_GET_WALLETS) - MAP_JON_RPC_WE("mw_select_wallet", on_mw_select_wallet, wallet_public::COMMAND_MW_SELECT_WALLET) + MAP_JON_RPC_WE("mw_get_wallets", on_mw_get_wallets, wallet_public::COMMAND_MW_GET_WALLETS) + MAP_JON_RPC_WE("mw_select_wallet", on_mw_select_wallet, wallet_public::COMMAND_MW_SELECT_WALLET) //basic crypto operations - MAP_JON_RPC_WE("sign_message", on_sign_message, wallet_public::COMMAND_SIGN_MESSAGE) - MAP_JON_RPC_WE("encrypt_data", on_encrypt_data, wallet_public::COMMAND_ENCRYPT_DATA) - MAP_JON_RPC_WE("decrypt_data", on_decrypt_data, wallet_public::COMMAND_DECRYPT_DATA) + MAP_JON_RPC_WE("sign_message", on_sign_message, wallet_public::COMMAND_SIGN_MESSAGE) + MAP_JON_RPC_WE("encrypt_data", on_encrypt_data, wallet_public::COMMAND_ENCRYPT_DATA) + MAP_JON_RPC_WE("decrypt_data", on_decrypt_data, wallet_public::COMMAND_DECRYPT_DATA) //utility call - MAP_JON_RPC_WE("proxy_to_daemon", on_proxy_to_daemon, wallet_public::COMMAND_PROXY_TO_DAEMON) + MAP_JON_RPC_WE("proxy_to_daemon", on_proxy_to_daemon, wallet_public::COMMAND_PROXY_TO_DAEMON) END_JSON_RPC_MAP() END_URI_MAP2() diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index 1e1ab4a0..30e469d3 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -1663,11 +1663,10 @@ std::string wallets_manager::invoke(uint64_t wallet_id, std::string params) epee::net_utils::http::http_request_info query_info = AUTO_VAL_INIT(query_info); epee::net_utils::http::http_response_info response_info = AUTO_VAL_INIT(response_info); epee::net_utils::connection_context_base stub_conn_context = AUTO_VAL_INIT(stub_conn_context); - std::string reference_stub; bool call_found = false; query_info.m_URI = "/json_rpc"; query_info.m_body = params; - wo.rpc_wrapper->handle_http_request_map(query_info, response_info, stub_conn_context, call_found, reference_stub); + wo.rpc_wrapper->handle_http_request_map(query_info, response_info, stub_conn_context, call_found); return response_info.m_body; } From cd88249598e65e5c10459801aee6b1c6668fbd22 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Tue, 9 Apr 2024 23:00:27 +0200 Subject: [PATCH 125/184] fixed few compilation issies --- src/wallet/wallet2.cpp | 10 +++++----- src/wallet/wallet_public_structs_defs.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 0f73afad..b1b9b376 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -5934,7 +5934,7 @@ bool wallet2::build_ionic_swap_template(const wallet_public::ionic_swap_proposal construct_tx_param ctp = get_default_construct_tx_param(); - ctp.fake_outputs_count = proposal_detais.mixins; + //ctp.fake_outputs_count = proposal_detais.mixins; ctp.fee = proposal_detais.fee_paid_by_a; ctp.flags = TX_FLAG_SIGNATURE_MODE_SEPARATE; ctp.mark_tx_as_complete = false; @@ -6079,10 +6079,10 @@ bool wallet2::get_ionic_swap_proposal_info(const wallet_public::ionic_swap_propo } amounts_provided_by_a[in_asset_id] += amount; - if (proposal_info.mixins == 0 || proposal_info.mixins > mx) - { - proposal_info.mixins = mx; - } + //if (proposal_info.mixins == 0 || proposal_info.mixins > mx) + //{ + // proposal_info.mixins = mx; + //} } diff --git a/src/wallet/wallet_public_structs_defs.h b/src/wallet/wallet_public_structs_defs.h index a274ad7f..8f29d7b3 100644 --- a/src/wallet/wallet_public_structs_defs.h +++ b/src/wallet/wallet_public_structs_defs.h @@ -1687,7 +1687,7 @@ namespace wallet_public BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(wi) - KV_SERIALIZE(wallet_id) DOC_DSCR("Wallet ID") DOC_EXMP() DOC_END + KV_SERIALIZE(wallet_id) DOC_DSCR("Wallet ID") DOC_EXMP(2) DOC_END END_KV_SERIALIZE_MAP() }; From a91ded81b0fadfe62e9a6e72d966d4bdbfb379dd Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Tue, 9 Apr 2024 23:09:22 +0200 Subject: [PATCH 126/184] and fixed another compilation issUe --- src/daemon/daemon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index eb697db8..51930c78 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -288,7 +288,7 @@ int main(int argc, char* argv[]) //query_info.m_body = "{\"jsonrpc\": \"2.0\", \"method\": \"nonexisting_method\", \"params\": {}},"; //rpc_server.handle_http_request_map(query_info, response_info, conn_context, call_found, json_rpc_reference); - LOG_PRINT_L0(generate_reference); + //LOG_PRINT_L0(generate_reference); return 0; } From e8280f7e42899a4f6e49bcf437ac6731a851bc4b Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 10 Apr 2024 12:16:45 +0200 Subject: [PATCH 127/184] coretests: fixed compilation & warnings --- contrib/epee/include/net/http_server_handlers_map2.h | 4 ++-- tests/core_tests/ionic_swap_tests.cpp | 12 ++---------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/contrib/epee/include/net/http_server_handlers_map2.h b/contrib/epee/include/net/http_server_handlers_map2.h index 1452aa57..66e13f9a 100644 --- a/contrib/epee/include/net/http_server_handlers_map2.h +++ b/contrib/epee/include/net/http_server_handlers_map2.h @@ -221,8 +221,8 @@ bool auto_doc(const std::string& uri, const std::string& method, bool is_json, d else { //json/bin uri/based - typedef command_type_t::request request_t; - typedef command_type_t::response response_t; + typedef typename command_type_t::request request_t; + typedef typename command_type_t::response response_t; request_t req = AUTO_VAL_INIT(req); //get_documentation_json_struct(); response_t res = AUTO_VAL_INIT(res); //get_documentation_json_struct(); diff --git a/tests/core_tests/ionic_swap_tests.cpp b/tests/core_tests/ionic_swap_tests.cpp index c08634a1..9942b2f5 100644 --- a/tests/core_tests/ionic_swap_tests.cpp +++ b/tests/core_tests/ionic_swap_tests.cpp @@ -178,7 +178,6 @@ bool ionic_swap_basic_test::c1(currency::core& c, size_t ev_index, const std::ve // Alice wants to trade with Bob, to exchange 10.0 TCT to 0.5 ZANO view::ionic_swap_proposal_info proposal_details = AUTO_VAL_INIT(proposal_details); proposal_details.fee_paid_by_a = TESTS_DEFAULT_FEE; - proposal_details.mixins = c.get_blockchain_storage().get_core_runtime_config().hf4_minimum_mixins; proposal_details.to_finalizer.push_back(view::asset_funds{ asset_id , assets_to_exchange }); proposal_details.to_initiator.push_back(view::asset_funds{ currency::native_coin_asset_id , native_coins_to_exchange }); @@ -192,7 +191,6 @@ bool ionic_swap_basic_test::c1(currency::core& c, size_t ev_index, const std::ve if (proposal_decoded_info.to_finalizer != proposal_details.to_finalizer || proposal_decoded_info.to_initiator != proposal_details.to_initiator || proposal_decoded_info.fee_paid_by_a != proposal_details.fee_paid_by_a - || proposal_decoded_info.mixins != proposal_details.mixins ) { CHECK_AND_ASSERT_MES(false, false, "proposal actual and proposals decoded mismatch"); @@ -233,7 +231,6 @@ bool ionic_swap_basic_test::c1(currency::core& c, size_t ev_index, const std::ve //now Alice want to trade with Bob, to send 0.5 ZANO and get 10.0 TCT in exchange view::ionic_swap_proposal_info proposal_details = AUTO_VAL_INIT(proposal_details); proposal_details.fee_paid_by_a = TESTS_DEFAULT_FEE; - proposal_details.mixins = c.get_blockchain_storage().get_core_runtime_config().hf4_minimum_mixins; proposal_details.to_finalizer.push_back(view::asset_funds{ currency::native_coin_asset_id , native_coins_to_exchange }); proposal_details.to_initiator.push_back(view::asset_funds{ asset_id , assets_to_exchange }); @@ -247,7 +244,6 @@ bool ionic_swap_basic_test::c1(currency::core& c, size_t ev_index, const std::ve if (proposal_decoded_info.to_finalizer != proposal_details.to_finalizer || proposal_decoded_info.to_initiator != proposal_details.to_initiator || proposal_decoded_info.fee_paid_by_a != proposal_details.fee_paid_by_a - || proposal_decoded_info.mixins != proposal_details.mixins ) { CHECK_AND_ASSERT_MES(false, false, "proposal actual and proposals decoded mismatch"); @@ -387,7 +383,6 @@ bool ionic_swap_exact_amounts_test::c1(currency::core& c, size_t ev_index, const proposal_details.to_initiator.push_back(view::asset_funds{ asset_id, adb.total_max_supply }); proposal_details.to_finalizer.push_back(view::asset_funds{ native_coin_asset_id, MK_TEST_COINS(20) }); proposal_details.fee_paid_by_a = MK_TEST_COINS(1); - proposal_details.mixins = c.get_blockchain_storage().get_core_runtime_config().hf4_minimum_mixins; tools::wallet_public::ionic_swap_proposal proposal{}; alice_wlt->create_ionic_swap_proposal(proposal_details, m_accounts[BOB_ACC_IDX].get_public_address(), proposal); @@ -397,8 +392,7 @@ bool ionic_swap_exact_amounts_test::c1(currency::core& c, size_t ev_index, const CHECK_AND_ASSERT_MES( proposal_decoded_info.to_finalizer == proposal_details.to_finalizer && proposal_decoded_info.to_initiator == proposal_details.to_initiator && - proposal_decoded_info.fee_paid_by_a == proposal_details.fee_paid_by_a && - proposal_decoded_info.mixins == proposal_details.mixins, + proposal_decoded_info.fee_paid_by_a == proposal_details.fee_paid_by_a, false, "actual and decoded proposal mismatch \nproposal_decoded_info: " << epee::serialization::store_t_to_json(proposal_decoded_info) << "\nproposal_details" << epee::serialization::store_t_to_json(proposal_details)); @@ -429,7 +423,6 @@ bool ionic_swap_exact_amounts_test::c1(currency::core& c, size_t ev_index, const proposal_details.to_initiator.push_back(view::asset_funds{ asset_id, adb.total_max_supply }); proposal_details.to_finalizer.push_back(view::asset_funds{ native_coin_asset_id, MK_TEST_COINS(20) }); proposal_details.fee_paid_by_a = MK_TEST_COINS(1); - proposal_details.mixins = c.get_blockchain_storage().get_core_runtime_config().hf4_minimum_mixins; proposal = tools::wallet_public::ionic_swap_proposal{}; carol_wlt->create_ionic_swap_proposal(proposal_details, m_accounts[ALICE_ACC_IDX].get_public_address(), proposal); @@ -439,8 +432,7 @@ bool ionic_swap_exact_amounts_test::c1(currency::core& c, size_t ev_index, const CHECK_AND_ASSERT_MES( proposal_decoded_info.to_finalizer == proposal_details.to_finalizer && proposal_decoded_info.to_initiator == proposal_details.to_initiator && - proposal_decoded_info.fee_paid_by_a == proposal_details.fee_paid_by_a && - proposal_decoded_info.mixins == proposal_details.mixins, + proposal_decoded_info.fee_paid_by_a == proposal_details.fee_paid_by_a, false, "actual and decoded proposal mismatch"); currency::transaction tx_is2{}; From 18650cda631249e783d098a8db762f4105c3bb06 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 10 Apr 2024 13:19:19 +0200 Subject: [PATCH 128/184] moved code to common header --- .../include/net/http_server_handlers_map2.h | 46 ++++++++++++++++++- src/simplewallet/simplewallet.cpp | 42 +---------------- 2 files changed, 47 insertions(+), 41 deletions(-) diff --git a/contrib/epee/include/net/http_server_handlers_map2.h b/contrib/epee/include/net/http_server_handlers_map2.h index 66e13f9a..57454682 100644 --- a/contrib/epee/include/net/http_server_handlers_map2.h +++ b/contrib/epee/include/net/http_server_handlers_map2.h @@ -150,7 +150,6 @@ struct documentation std::list entries; }; - // Primary template template struct has_static_member_description { @@ -485,4 +484,49 @@ namespace epee { return true; \ } +namespace epee +{ + template + bool generate_doc_as_md_files(const std::string& folder, t_rpc_server& server) + { + LOG_PRINT_L0("Dumping RPC auto-generated documents!"); + epee::net_utils::http::http_request_info query_info; + epee::net_utils::http::http_response_info response_info; + epee::net_utils::connection_context_base conn_context; + //std::string generate_reference = std::string("WALLET_RPC_COMMANDS_LIST:\n"); + bool call_found = false; + documentation docs; + docs.do_generate_documentation = true; + // query_info.m_URI = JSON_RPC_REFERENCE_MARKER; + query_info.m_body = "{\"jsonrpc\": \"2.0\", \"method\": \"nonexisting_method\", \"params\": {}},"; + server.handle_http_request_map(query_info, response_info, conn_context, call_found, docs); + + for (const auto& de : docs.entries) + { + std::stringstream ss; + ss << de.method_general_decription << ENDL; + + ss << "URL: ```http:://127.0.0.1:11211" << de.uri << "```" << ENDL; + + ss << "### Request: " << ENDL << "```json" << ENDL << de.request_json_example << ENDL << "```" << ENDL; + ss << "### Request description: " << ENDL << "```" << ENDL << de.request_json_descriptions << ENDL << "```" << ENDL; + ss << "### Response: " << ENDL << "```json" << ENDL << de.response_json_example << ENDL << "```" << ENDL; + ss << "### Response description: " << ENDL << "```" << ENDL << de.response_json_descriptions << ENDL << "```" << ENDL; + + std::string filename = de.json_method_name; + if (!filename.size()) + { + filename = de.uri; + } + filename += ".md"; + bool r = epee::file_io_utils::save_string_to_file(folder + "/" + filename, ss.str()); + if (!r) + { + LOG_ERROR("Failed to save file " << filename); + return false; + } + } + return true; + } +} \ No newline at end of file diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 6f230939..53be3f99 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -2865,49 +2865,11 @@ int main(int argc, char* argv[]) if (command_line::has_arg(vm, command_line::arg_generate_rpc_autodoc)) { - LOG_PRINT_L0("Dumping RPC auto-generated documents!"); - epee::net_utils::http::http_request_info query_info; - epee::net_utils::http::http_response_info response_info; - epee::net_utils::connection_context_base conn_context; - //std::string generate_reference = std::string("WALLET_RPC_COMMANDS_LIST:\n"); - bool call_found = false; tools::wallet_rpc_server wallet_rpc_server(std::shared_ptr(new tools::wallet2())); - //wallet_rpc_server.handle_http_request_map(query_info, response_info, conn_context, call_found, generate_reference); - - //::string json_rpc_reference = generate_reference; - documentation docs; - docs.do_generate_documentation = true; -// query_info.m_URI = JSON_RPC_REFERENCE_MARKER; - query_info.m_body = "{\"jsonrpc\": \"2.0\", \"method\": \"nonexisting_method\", \"params\": {}},"; - wallet_rpc_server.handle_http_request_map(query_info, response_info, conn_context, call_found, docs); - std::string path_to_generate = command_line::get_arg(vm, command_line::arg_generate_rpc_autodoc); - for (const auto& de : docs.entries) - { - std::stringstream ss; - ss << de.method_general_decription << ENDL; - - ss << "URL: ```http:://127.0.0.1:11211" << de.uri << "```" << ENDL; - - ss << "### Request: " << ENDL << "```json" << ENDL << de.request_json_example << ENDL << "```" << ENDL; - ss << "### Request description: " << ENDL << "```" << ENDL << de.request_json_descriptions << ENDL << "```" << ENDL; - ss << "### Response: " << ENDL << "```json" << ENDL << de.response_json_example << ENDL << "```" << ENDL; - ss << "### Response description: " << ENDL << "```" << ENDL << de.response_json_descriptions << ENDL << "```" << ENDL; - - std::string filename = de.json_method_name; - if (!filename.size()) - { - filename = de.uri; - } - filename += ".md"; - bool r = epee::file_io_utils::save_string_to_file(path_to_generate + "/" + filename, ss.str()); - if (!r) - { - LOG_ERROR("Failed to save file " << filename); - return 1; - } - } + if (!generate_doc_as_md_files(path_to_generate, wallet_rpc_server)) + return 1; return 0; } From 30eba2dadf684f570bf46c145c9f4a0abc33c75b Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 10 Apr 2024 13:33:37 +0200 Subject: [PATCH 129/184] fixed compilation (handle_http_request_map definition) --- contrib/epee/include/net/http_server_handlers_map2.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/contrib/epee/include/net/http_server_handlers_map2.h b/contrib/epee/include/net/http_server_handlers_map2.h index 57454682..0c1a0df2 100644 --- a/contrib/epee/include/net/http_server_handlers_map2.h +++ b/contrib/epee/include/net/http_server_handlers_map2.h @@ -255,7 +255,9 @@ namespace epee { struct i_chain_handler { virtual bool handle_http_request_map(const epee::net_utils::http::http_request_info& query_info, epee::net_utils::http::http_response_info& response_info, - epee::net_utils::connection_context_base& m_conn_context, bool& call_found, documentation& docs = documentation()) = 0; + epee::net_utils::connection_context_base& m_conn_context, bool& call_found, documentation& docs = epee::net_utils::http::i_chain_handler::m_empty_documentation) = 0; + + static inline documentation m_empty_documentation; }; } } @@ -280,13 +282,13 @@ namespace epee { #define BEGIN_URI_MAP2() template bool handle_http_request_map(const epee::net_utils::http::http_request_info& query_info, \ epee::net_utils::http::http_response_info& response_info, \ - t_context& m_conn_context, bool& call_found, documentation& docs = documentation()) { \ + t_context& m_conn_context, bool& call_found, documentation& docs = epee::net_utils::http::i_chain_handler::m_empty_documentation) { \ call_found = false; \ if(false) return true; //just a stub to have "else if" #define BEGIN_URI_MAP2_VIRTUAL() virtual bool handle_http_request_map(const epee::net_utils::http::http_request_info& query_info, \ epee::net_utils::http::http_response_info& response_info, \ - epee::net_utils::connection_context_base& m_conn_context, bool& call_found, documentation& docs = documentation()) { \ + epee::net_utils::connection_context_base& m_conn_context, bool& call_found, documentation& docs = epee::net_utils::http::i_chain_handler::m_empty_documentation) { \ call_found = false; \ if(false) return true; //just a stub to have "else if" From 75cb3bcaf844e57436997598872225220b768d43 Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 10 Apr 2024 13:49:44 +0200 Subject: [PATCH 130/184] more compilation fixes --- src/currency_core/offers_service_basics.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/currency_core/offers_service_basics.h b/src/currency_core/offers_service_basics.h index a2ca2e7c..63feedb9 100644 --- a/src/currency_core/offers_service_basics.h +++ b/src/currency_core/offers_service_basics.h @@ -40,7 +40,7 @@ namespace bc_services KV_SERIALIZE_N(offer_type, "ot") DOC_DSCR("Type of the offer: OFFER_TYPE_PRIMARY_TO_TARGET(SELL ORDER) - 0, OFFER_TYPE_TARGET_TO_PRIMARY(BUY ORDER) - 1 etc.") DOC_EXMP(0) DOC_END KV_SERIALIZE_CUSTOM_N(amount_primary, std::string, bc_services::transform_amount_to_string, bc_services::transform_string_to_amount, "ap") DOC_DSCR("Amount of the currency") DOC_EXMP("100000") DOC_END KV_SERIALIZE_CUSTOM_N(amount_target, std::string, bc_services::transform_amount_to_string, bc_services::transform_string_to_amount, "at") DOC_DSCR("Smount of other currency or goods") DOC_EXMP("10000000") DOC_END - KV_SERIALIZE_N(bonus, "b") DOC_DSCR("Bonus associated with the offer") DOC_EXMP(false) DOC_END + KV_SERIALIZE_N(bonus, "b") DOC_DSCR("Bonus associated with the offer") DOC_EXMP("") DOC_END KV_SERIALIZE_N(target, "t") DOC_DSCR("Target: currency / goods") DOC_EXMP("USDT") DOC_END KV_SERIALIZE_N(primary, "p") DOC_DSCR("Currency for goods") DOC_EXMP("ZANO") DOC_END KV_SERIALIZE_N(location_country, "lco") DOC_DSCR("Country of the offer location") DOC_EXMP("Montenegro") DOC_END From cb1f62d4ffee88414b7d8a9e713b4420a3ebdd37 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 10 Apr 2024 13:50:03 +0200 Subject: [PATCH 131/184] fixedbug with crash on autodoc --- src/daemon/daemon.cpp | 20 +++++--------------- src/simplewallet/simplewallet.cpp | 1 - 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index 51930c78..5f46b088 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -272,24 +272,14 @@ int main(int argc, char* argv[]) if (stratum_enabled) stratum_server_ptr = std::make_shared(&ccore); + + if (command_line::has_arg(vm, command_line::arg_generate_rpc_autodoc)) { - LOG_PRINT_L0("Dumping RPC auto-generated documents!"); - epee::net_utils::http::http_request_info query_info; - epee::net_utils::http::http_response_info response_info; - epee::net_utils::connection_context_base conn_context; - //std::string generate_reference = std::string("RPC_COMMANDS_LIST:\n"); - documentation doc; - doc.do_generate_documentation = true; - bool call_found = false; - rpc_server.handle_http_request_map(query_info, response_info, conn_context, call_found, doc); - //std::string json_rpc_reference; - //query_info.m_URI = JSON_RPC_REFERENCE_MARKER; - //query_info.m_body = "{\"jsonrpc\": \"2.0\", \"method\": \"nonexisting_method\", \"params\": {}},"; - //rpc_server.handle_http_request_map(query_info, response_info, conn_context, call_found, json_rpc_reference); - - //LOG_PRINT_L0(generate_reference); + std::string path_to_generate = command_line::get_arg(vm, command_line::arg_generate_rpc_autodoc); + if (!generate_doc_as_md_files(path_to_generate, rpc_server)) + return 1; return 0; } diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 53be3f99..c953138f 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -2862,7 +2862,6 @@ int main(int argc, char* argv[]) message_writer(epee::log_space::console_color_white, true) << "Log level changed: " << old_log_level << " -> " << new_log_level; } - if (command_line::has_arg(vm, command_line::arg_generate_rpc_autodoc)) { tools::wallet_rpc_server wallet_rpc_server(std::shared_ptr(new tools::wallet2())); From ac63489325c00834ce0d6c4bebee829f8e051ea0 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 10 Apr 2024 14:17:07 +0200 Subject: [PATCH 132/184] last fixes for uri --- contrib/epee/include/net/http_server_handlers_map2.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contrib/epee/include/net/http_server_handlers_map2.h b/contrib/epee/include/net/http_server_handlers_map2.h index 0c1a0df2..fe4e7c9b 100644 --- a/contrib/epee/include/net/http_server_handlers_map2.h +++ b/contrib/epee/include/net/http_server_handlers_map2.h @@ -194,6 +194,7 @@ bool auto_doc(const std::string& uri, const std::string& method, bool is_json, d docs.entries.resize(docs.entries.size()+1); docs.entries.back().is_binary = !is_json; + docs.entries.back().uri = uri; docs.entries.back().json_method_name = method; docs.entries.back().method_general_decription = get_command_description(); @@ -520,6 +521,8 @@ namespace epee if (!filename.size()) { filename = de.uri; + if (filename.front() == '/') + filename.erase(filename.begin()); } filename += ".md"; bool r = epee::file_io_utils::save_string_to_file(folder + "/" + filename, ss.str()); From d3f3bb07e01020a58adecbd323451611d3fce2f7 Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 10 Apr 2024 14:24:59 +0200 Subject: [PATCH 133/184] restarted testnet (build version bumped up to 299) --- src/currency_core/currency_config.h | 6 +++--- src/version.h.in | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/currency_core/currency_config.h b/src/currency_core/currency_config.h index 487502f4..ddd37b57 100644 --- a/src/currency_core/currency_config.h +++ b/src/currency_core/currency_config.h @@ -10,7 +10,7 @@ #ifndef TESTNET #define CURRENCY_FORMATION_VERSION 84 #else -#define CURRENCY_FORMATION_VERSION 97 +#define CURRENCY_FORMATION_VERSION 98 #endif #define CURRENCY_GENESIS_NONCE (CURRENCY_FORMATION_VERSION + 101011010121) //bender's nightmare @@ -263,7 +263,7 @@ #define ZANO_HARDFORK_01_AFTER_HEIGHT 194624 // 2019-09-21 20:25:16 #define ZANO_HARDFORK_02_AFTER_HEIGHT 999999 // 2021-04-05 09:11:45 #define ZANO_HARDFORK_03_AFTER_HEIGHT 1082577 // 2021-06-01 23:28:10 -#define ZANO_HARDFORK_04_AFTER_HEIGHT 2555000 // 2024-03-21 10:16:46 (expected) +#define ZANO_HARDFORK_04_AFTER_HEIGHT 2555000 // 2024-03-21 11:49:55 #else /////// Zarcanum Testnet ////////////////////////////// #define ZANO_HARDFORK_01_AFTER_HEIGHT 0 @@ -295,4 +295,4 @@ static_assert(PREMINE_AMOUNT / WALLET_MAX_ALLOWED_OUTPUT_AMOUNT < CURRENCY_MINER #endif -#define WALLET_ASSETS_WHITELIST_VALIDATION_PUBLIC_KEY "" //TODO@#@ \ No newline at end of file +#define WALLET_ASSETS_WHITELIST_VALIDATION_PUBLIC_KEY "" //TODO@#@ diff --git a/src/version.h.in b/src/version.h.in index 0c4a9f38..4bc7f5a7 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 293 +#define PROJECT_VERSION_BUILD_NO 299 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From ef16abb41ac8c46cb17daeda7685a3d53329fdb4 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 10 Apr 2024 14:47:28 +0200 Subject: [PATCH 134/184] extra line break added --- contrib/epee/include/net/http_server_handlers_map2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/epee/include/net/http_server_handlers_map2.h b/contrib/epee/include/net/http_server_handlers_map2.h index fe4e7c9b..61acf12f 100644 --- a/contrib/epee/include/net/http_server_handlers_map2.h +++ b/contrib/epee/include/net/http_server_handlers_map2.h @@ -508,7 +508,7 @@ namespace epee for (const auto& de : docs.entries) { std::stringstream ss; - ss << de.method_general_decription << ENDL; + ss << de.method_general_decription << ENDL << ENDL;; ss << "URL: ```http:://127.0.0.1:11211" << de.uri << "```" << ENDL; From 53a27a43060e5e5d9dcf721424ea03f2bc536579 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 10 Apr 2024 14:51:33 +0200 Subject: [PATCH 135/184] documented wallet_provision_info --- src/wallet/wallet_public_structs_defs.h | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/wallet/wallet_public_structs_defs.h b/src/wallet/wallet_public_structs_defs.h index 8f29d7b3..ab7c82e2 100644 --- a/src/wallet/wallet_public_structs_defs.h +++ b/src/wallet/wallet_public_structs_defs.h @@ -511,12 +511,13 @@ namespace wallet_public BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(transfers_count) - KV_SERIALIZE(transfer_entries_count) - KV_SERIALIZE(balance) - KV_SERIALIZE(unlocked_balance) - KV_SERIALIZE(curent_height) + KV_SERIALIZE(transfers_count) DOC_DSCR("Number of transfers in wallet") DOC_EXMP() DOC_END + KV_SERIALIZE(transfer_entries_count) DOC_DSCR("Number of UTXO entries in wallet") DOC_EXMP() DOC_END + KV_SERIALIZE(balance) DOC_DSCR("Current balance of native coins") DOC_EXMP() DOC_END + KV_SERIALIZE(unlocked_balance) DOC_DSCR("Unlocked balance oof native coins") DOC_EXMP() DOC_END + KV_SERIALIZE(curent_height) DOC_DSCR("Current sync height of the wallet") DOC_EXMP() DOC_END END_KV_SERIALIZE_MAP() + }; struct COMMAND_RPC_GET_MINING_HISTORY @@ -574,10 +575,10 @@ namespace wallet_public uint64_t last_item_index; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(pi) - KV_SERIALIZE(transfers) - KV_SERIALIZE(total_transfers) - KV_SERIALIZE(last_item_index) + KV_SERIALIZE(pi) DOC_DSCR("Details on wallet balance etc") DOC_END + KV_SERIALIZE(transfers) DOC_DSCR("Transfers") DOC_EXMP_AUTO(1) DOC_END + KV_SERIALIZE(total_transfers) DOC_DSCR("Total transfers") DOC_EXMP(1) DOC_END + KV_SERIALIZE(last_item_index) DOC_DSCR("Last item index") DOC_EXMP(1) DOC_END END_KV_SERIALIZE_MAP() }; }; From 3cde8738c2196500d177ea4fb73ca9c80162269b Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 10 Apr 2024 14:52:46 +0200 Subject: [PATCH 136/184] added example values to wallet_provision_info --- src/wallet/wallet_public_structs_defs.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/wallet/wallet_public_structs_defs.h b/src/wallet/wallet_public_structs_defs.h index ab7c82e2..00cbc3de 100644 --- a/src/wallet/wallet_public_structs_defs.h +++ b/src/wallet/wallet_public_structs_defs.h @@ -511,11 +511,11 @@ namespace wallet_public BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(transfers_count) DOC_DSCR("Number of transfers in wallet") DOC_EXMP() DOC_END - KV_SERIALIZE(transfer_entries_count) DOC_DSCR("Number of UTXO entries in wallet") DOC_EXMP() DOC_END - KV_SERIALIZE(balance) DOC_DSCR("Current balance of native coins") DOC_EXMP() DOC_END - KV_SERIALIZE(unlocked_balance) DOC_DSCR("Unlocked balance oof native coins") DOC_EXMP() DOC_END - KV_SERIALIZE(curent_height) DOC_DSCR("Current sync height of the wallet") DOC_EXMP() DOC_END + KV_SERIALIZE(transfers_count) DOC_DSCR("Number of transfers in wallet") DOC_EXMP(1) DOC_END + KV_SERIALIZE(transfer_entries_count) DOC_DSCR("Number of UTXO entries in wallet") DOC_EXMP(3) DOC_END + KV_SERIALIZE(balance) DOC_DSCR("Current balance of native coins") DOC_EXMP(100000000000) DOC_END + KV_SERIALIZE(unlocked_balance) DOC_DSCR("Unlocked balance oof native coins") DOC_EXMP(90000000000) DOC_END + KV_SERIALIZE(curent_height) DOC_DSCR("Current sync height of the wallet") DOC_EXMP(121212) DOC_END END_KV_SERIALIZE_MAP() }; From ed62452853f7336900fee516d12442584e2ec288 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 10 Apr 2024 19:10:32 +0200 Subject: [PATCH 137/184] hardfork 5 --- src/currency_core/blockchain_storage.cpp | 4 ++++ src/currency_core/currency_config.h | 7 +++++-- src/currency_core/currency_format_utils.cpp | 6 ++++++ src/currency_core/currency_format_utils.h | 3 ++- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index eb6d0fb3..c12e5ca9 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -4038,6 +4038,10 @@ bool blockchain_storage::validate_asset_operation_against_current_blochain_state CHECK_AND_ASSERT_MES(!avc.asset_op_history, false, "asset with id " << avc.asset_id << " has already been registered"); avc.amount_to_validate = ado.descriptor.current_supply; CHECK_AND_ASSERT_MES(validate_asset_operation_amount_commitment(avc), false, "validate_asset_operation_amount_commitment failed!"); + if(this->is_hardfork_active(ZANO_HARDFORK_05)) + { + CHECK_AND_ASSERT_MES(validate_ado_initial(ado.descriptor), false, "validate_ado_initial failed!"); + } } else { diff --git a/src/currency_core/currency_config.h b/src/currency_core/currency_config.h index ddd37b57..2afc400a 100644 --- a/src/currency_core/currency_config.h +++ b/src/currency_core/currency_config.h @@ -264,12 +264,14 @@ #define ZANO_HARDFORK_02_AFTER_HEIGHT 999999 // 2021-04-05 09:11:45 #define ZANO_HARDFORK_03_AFTER_HEIGHT 1082577 // 2021-06-01 23:28:10 #define ZANO_HARDFORK_04_AFTER_HEIGHT 2555000 // 2024-03-21 11:49:55 +#define ZANO_HARDFORK_05_AFTER_HEIGHT 999999999999999999 #else /////// Zarcanum Testnet ////////////////////////////// #define ZANO_HARDFORK_01_AFTER_HEIGHT 0 #define ZANO_HARDFORK_02_AFTER_HEIGHT 0 #define ZANO_HARDFORK_03_AFTER_HEIGHT 0 -#define ZANO_HARDFORK_04_AFTER_HEIGHT 2440 +#define ZANO_HARDFORK_04_AFTER_HEIGHT 200 +#define ZANO_HARDFORK_05_AFTER_HEIGHT 200 #endif @@ -278,7 +280,8 @@ #define ZANO_HARDFORK_02 2 #define ZANO_HARDFORK_03 3 #define ZANO_HARDFORK_04_ZARCANUM 4 -#define ZANO_HARDFORKS_TOTAL 5 +#define ZANO_HARDFORK_05 5 +#define ZANO_HARDFORKS_TOTAL 6 diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 32b43656..410d6a91 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -1152,6 +1152,12 @@ namespace currency return true; } //--------------------------------------------------------------- + bool validate_ado_initial(const asset_descriptor_base& new_ado) + { + if (new_ado.current_supply > new_ado.total_max_supply) return false; + return true; + } + //--------------------------------------------------------------- /* crypto::hash get_signature_hash_for_asset_operation(const asset_descriptor_operation& ado) { diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index 8f858303..70751c8d 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -276,6 +276,7 @@ namespace currency bool check_tx_bare_balance(const transaction& tx, uint64_t additional_inputs_amount_and_fees_for_mining_tx = 0); bool check_tx_balance(const transaction& tx, const crypto::hash& tx_id, uint64_t additional_inputs_amount_and_fees_for_mining_tx = 0); bool validate_asset_operation_amount_commitment(asset_op_verification_context& context); + const char* get_asset_operation_type_string(size_t asset_operation_type, bool short_name = false); //--------------------------------------------------------------- bool construct_miner_tx(size_t height, size_t median_size, const boost::multiprecision::uint128_t& already_generated_coins, @@ -463,7 +464,7 @@ namespace currency std::string generate_origin_for_htlc(const txout_htlc& htlc, const account_keys& acc_keys); bool validate_ado_update_allowed(const asset_descriptor_base& a, const asset_descriptor_base& b); - + bool validate_ado_initial(const asset_descriptor_base& a); void normalize_asset_operation_for_hashing(asset_descriptor_operation& op); crypto::hash get_signature_hash_for_asset_operation(const asset_descriptor_operation& ado); From d1f7f436f8bff3b8411032427acce505ea20a934 Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 10 Apr 2024 19:13:13 +0200 Subject: [PATCH 138/184] build version: 299 -> 300 --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index 4bc7f5a7..a6b75ab0 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 299 +#define PROJECT_VERSION_BUILD_NO 300 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From 82e52e951a28a100cf762d498167bbc9b614a26e Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 10 Apr 2024 19:13:13 +0200 Subject: [PATCH 139/184] build version: 299 -> 300 --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index 4bc7f5a7..a6b75ab0 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 299 +#define PROJECT_VERSION_BUILD_NO 300 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From c54f3fc1d8612fb007bfc25c7a9221508aae9e1c Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 10 Apr 2024 19:31:01 +0200 Subject: [PATCH 140/184] added seed to wallet generation api --- src/wallet/wallets_manager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index 30e469d3..c9bfddb3 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -1188,7 +1188,7 @@ std::string wallets_manager::generate_wallet(const std::wstring& path, const std { w->generate(path, password, false); w->set_minimum_height(m_last_daemon_height-1); - //owr.seed = w->get_account().get_seed_phrase(); + owr.seed = w->get_account().get_seed_phrase(""); } catch (const tools::error::file_exists&) { @@ -1297,7 +1297,7 @@ std::string wallets_manager::restore_wallet(const std::wstring& path, const std: { bool is_tracking = currency::account_base::is_seed_tracking(seed_phrase); w->restore(path, password, seed_phrase, is_tracking, seed_password); - //owr.seed = w->get_account().get_seed_phrase(); + owr.seed = w->get_account().get_seed_phrase(""); } catch (const tools::error::file_exists&) { From e3d1956ba39fb9db4b24550a3ba7ba42dbdd4f38 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 11 Apr 2024 14:29:03 +0200 Subject: [PATCH 141/184] implemented RPC API for assets deployment --- src/wallet/wallet_public_structs_defs.h | 68 +++++++++++++++++++++++++ src/wallet/wallet_rpc_server.cpp | 65 ++++++++++++++++++++++- src/wallet/wallet_rpc_server.h | 9 ++++ 3 files changed, 140 insertions(+), 2 deletions(-) diff --git a/src/wallet/wallet_public_structs_defs.h b/src/wallet/wallet_public_structs_defs.h index 00cbc3de..2d8a3685 100644 --- a/src/wallet/wallet_public_structs_defs.h +++ b/src/wallet/wallet_public_structs_defs.h @@ -1954,16 +1954,84 @@ namespace wallet_public + struct COMMAND_ASSETS_DEPLOY + { + DOC_COMMAND("Deploy new asset in the system."); + + struct request + { + std::list destinations; + currency::asset_descriptor_base asset_descriptor; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(destinations) DOC_DSCR("Addresses where to receive emitted coins. Asset id in destinations should be set to 0000000000000000000000000000000000000000000000000000000000000000") DOC_EXMP_AUTO(1) DOC_END + KV_SERIALIZE(asset_descriptor) DOC_DSCR("Descriptor that holds all information about asset - ticker, emission, description etc") DOC_END + END_KV_SERIALIZE_MAP() + }; + struct response + { + crypto::hash result_tx; + crypto::public_key new_asset_id; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE_POD_AS_HEX_STRING(result_tx) DOC_DSCR("Id of transaction that carries asset registration command, asset would be registered as soon as transaction got confirmed") DOC_EXMP("f74bb56a5b4fa562e679ccaadd697463498a66de4f1760b2cd40f11c3a00a7a8") DOC_END + KV_SERIALIZE_POD_AS_HEX_STRING(new_asset_id) DOC_DSCR("Issued asset id") DOC_EXMP("40fa6db923728b38962718c61b4dc3af1acaa1967479c73703e260dc3609c58d") DOC_END + END_KV_SERIALIZE_MAP() + }; + }; + + struct COMMAND_ASSETS_EMIT + { + DOC_COMMAND("Emmit new coins of the the asset, that is controlled by this wallet."); + + struct request + { + crypto::public_key asset_id; + std::list destinations; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE_POD_AS_HEX_STRING(asset_id) DOC_DSCR("Id of the asset to emit more coins") DOC_EXMP("40fa6db923728b38962718c61b4dc3af1acaa1967479c73703e260dc3609c58d") DOC_END + KV_SERIALIZE(destinations) DOC_DSCR("Addresses where to receive emitted coins. Asset id in destinations should be set to 0000000000000000000000000000000000000000000000000000000000000000") DOC_EXMP_AUTO(1) DOC_END + END_KV_SERIALIZE_MAP() + }; + struct response + { + crypto::hash result_tx; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE_POD_AS_HEX_STRING(result_tx) DOC_DSCR("Id of transaction that carries asset registration command, asset would be registered as soon as transaction got confirmed") DOC_EXMP("f74bb56a5b4fa562e679ccaadd697463498a66de4f1760b2cd40f11c3a00a7a8") DOC_END + END_KV_SERIALIZE_MAP() + }; + }; + struct COMMAND_ASSETS_UPDATE + { + DOC_COMMAND("Update asset descriptor(you can change only owner so far)"); + struct request + { + crypto::public_key asset_id; + currency::asset_descriptor_base asset_descriptor; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE_POD_AS_HEX_STRING(asset_id) DOC_DSCR("Id of the asset to update") DOC_EXMP("40fa6db923728b38962718c61b4dc3af1acaa1967479c73703e260dc3609c58d") DOC_END + KV_SERIALIZE(asset_descriptor) DOC_DSCR("Descriptor that holds all information about asset that need to be updated (only owner could be updated)") DOC_END + END_KV_SERIALIZE_MAP() + }; + struct response + { + crypto::hash result_tx; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE_POD_AS_HEX_STRING(result_tx) DOC_DSCR("Id of transaction that carries asset registration command, asset would be registered as soon as transaction got confirmed") DOC_EXMP("f74bb56a5b4fa562e679ccaadd697463498a66de4f1760b2cd40f11c3a00a7a8") DOC_END + END_KV_SERIALIZE_MAP() + }; + }; } // namespace wallet_rpc diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 4428ee3a..10d2a399 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -50,7 +50,7 @@ POP_VS_WARNINGS catch (const tools::error::wallet_error& e) \ { \ er.code = WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR; \ - er.message = std::string("WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR") + e.error_code(); \ + er.message = e.error_code(); \ return false; \ } \ catch (const std::exception& e) \ @@ -66,6 +66,10 @@ POP_VS_WARNINGS return false; \ } + +void exception_handler() +{} + namespace tools { //----------------------------------------------------------------------------------- @@ -421,7 +425,7 @@ namespace tools return true; WALLET_RPC_CATCH_TRY_ENTRY(); } - //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_transfer(const wallet_public::COMMAND_RPC_TRANSFER::request& req, wallet_public::COMMAND_RPC_TRANSFER::response& res, epee::json_rpc::error& er, connection_context& cntx) { WALLET_RPC_BEGIN_TRY_ENTRY(); @@ -453,6 +457,7 @@ namespace tools } bool wrap = false; std::vector& dsts = ctp.dsts; + for (auto it = req.destinations.begin(); it != req.destinations.end(); it++) { currency::tx_destination_entry de; @@ -1230,6 +1235,62 @@ namespace tools WALLET_RPC_CATCH_TRY_ENTRY(); } //------------------------------------------------------------------------------------------------------------------------------ + void wallet_rpc_server::rpc_destinations_to_currency_destination(const std::list& rpc_destinations, std::vector& currency_destinations) + { + GET_WALLET(); + std::vector& dsts = currency_destinations; + for (auto it = rpc_destinations.begin(); it != rpc_destinations.end(); it++) + { + currency::tx_destination_entry de; + de.addr.resize(1); + std::string embedded_payment_id; + //check if address looks like wrapped address + WLT_THROW_IF_FALSE_WITH_CODE(!currency::is_address_like_wrapped(it->address), "WALLET_RPC_ERROR_CODE_WRONG_ADDRESS", "WALLET_RPC_ERROR_CODE_WRONG_ADDRESS"); + WLT_THROW_IF_FALSE_WITH_CODE(!w.get_wallet()->get_transfer_address(it->address, de.addr.back(), embedded_payment_id), "WALLET_RPC_ERROR_CODE_WRONG_ADDRESS", "WALLET_RPC_ERROR_CODE_WRONG_ADDRESS"); + WLT_THROW_IF_FALSE_WITH_CODE(embedded_payment_id.size() == 0, "WALLET_RPC_ERROR_CODE_WRONG_ADDRESS", "WALLET_RPC_ERROR_CODE_WRONG_ADDRESS"); + de.amount = it->amount; + de.asset_id = it->asset_id; + dsts.push_back(de); + } + } + //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_assets_deploy(const wallet_public::COMMAND_ASSETS_DEPLOY::request& req, wallet_public::COMMAND_ASSETS_DEPLOY::response& res, epee::json_rpc::error& er, connection_context& cntx) + { + WALLET_RPC_BEGIN_TRY_ENTRY(); + currency::transaction result_tx; + std::vector currency_destinations; + rpc_destinations_to_currency_destination(req.destinations, currency_destinations); + w.get_wallet()->deploy_new_asset(req.asset_descriptor, currency_destinations, result_tx, res.new_asset_id); + res.result_tx = currency::get_transaction_hash(result_tx); + return true; + WALLET_RPC_CATCH_TRY_ENTRY(); + } + //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_assets_emit(const wallet_public::COMMAND_ASSETS_EMIT::request& req, wallet_public::COMMAND_ASSETS_EMIT::response& res, epee::json_rpc::error& er, connection_context& cntx) + { + WALLET_RPC_BEGIN_TRY_ENTRY(); + currency::transaction result_tx; + std::vector currency_destinations; + rpc_destinations_to_currency_destination(req.destinations, currency_destinations); + + w.get_wallet()->emit_asset(req.asset_id, currency_destinations, result_tx); + res.result_tx = currency::get_transaction_hash(result_tx); + return true; + + WALLET_RPC_CATCH_TRY_ENTRY(); + } + //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_assets_update(const wallet_public::COMMAND_ASSETS_UPDATE::request& req, wallet_public::COMMAND_ASSETS_UPDATE::response& res, epee::json_rpc::error& er, connection_context& cntx) + { + WALLET_RPC_BEGIN_TRY_ENTRY(); + currency::transaction result_tx; + w.get_wallet()->update_asset(req.asset_id, req.asset_descriptor, result_tx); + res.result_tx = currency::get_transaction_hash(result_tx); + return true; + + WALLET_RPC_CATCH_TRY_ENTRY(); + } + //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_mw_get_wallets(const wallet_public::COMMAND_MW_GET_WALLETS::request& req, wallet_public::COMMAND_MW_GET_WALLETS::response& res, epee::json_rpc::error& er, connection_context& cntx) { WALLET_RPC_BEGIN_TRY_ENTRY(); diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index e5451a37..86a0039a 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -143,6 +143,10 @@ namespace tools MAP_JON_RPC_WE("assets_whitelist_get", on_assets_whitelist_get, wallet_public::COMMAND_ASSETS_WHITELIST_GET) MAP_JON_RPC_WE("assets_whitelist_add", on_assets_whitelist_add, wallet_public::COMMAND_ASSETS_WHITELIST_ADD) MAP_JON_RPC_WE("assets_whitelist_remove", on_assets_whitelist_remove, wallet_public::COMMAND_ASSETS_WHITELIST_REMOVE) + + MAP_JON_RPC_WE("deploy_asset", on_assets_deploy, wallet_public::COMMAND_ASSETS_DEPLOY) + MAP_JON_RPC_WE("emit_asset", on_assets_emit, wallet_public::COMMAND_ASSETS_EMIT) + MAP_JON_RPC_WE("update_asset", on_assets_update, wallet_public::COMMAND_ASSETS_UPDATE) //MULTIWALLET APIs MAP_JON_RPC_WE("mw_get_wallets", on_mw_get_wallets, wallet_public::COMMAND_MW_GET_WALLETS) @@ -208,6 +212,10 @@ namespace tools bool on_assets_whitelist_get(const wallet_public::COMMAND_ASSETS_WHITELIST_GET::request& req, wallet_public::COMMAND_ASSETS_WHITELIST_GET::response& res, epee::json_rpc::error& er, connection_context& cntx); bool on_assets_whitelist_add(const wallet_public::COMMAND_ASSETS_WHITELIST_ADD::request& req, wallet_public::COMMAND_ASSETS_WHITELIST_ADD::response& res, epee::json_rpc::error& er, connection_context& cntx); bool on_assets_whitelist_remove(const wallet_public::COMMAND_ASSETS_WHITELIST_REMOVE::request& req, wallet_public::COMMAND_ASSETS_WHITELIST_REMOVE::response& res, epee::json_rpc::error& er, connection_context& cntx); + + bool on_assets_deploy(const wallet_public::COMMAND_ASSETS_DEPLOY::request& req, wallet_public::COMMAND_ASSETS_DEPLOY::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool on_assets_emit(const wallet_public::COMMAND_ASSETS_EMIT::request& req, wallet_public::COMMAND_ASSETS_EMIT::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool on_assets_update(const wallet_public::COMMAND_ASSETS_UPDATE::request& req, wallet_public::COMMAND_ASSETS_UPDATE::response& res, epee::json_rpc::error& er, connection_context& cntx); bool on_mw_get_wallets(const wallet_public::COMMAND_MW_GET_WALLETS::request& req, wallet_public::COMMAND_MW_GET_WALLETS::response& res, epee::json_rpc::error& er, connection_context& cntx); @@ -225,6 +233,7 @@ namespace tools //bool reset_active_wallet(std::shared_ptr w); bool handle_command_line(const boost::program_options::variables_map& vm); + void rpc_destinations_to_currency_destination(const std::list& rpc_destinations, std::vector& currency_destinations); private: std::shared_ptr m_pwallet_provider_sh_ptr; From e52ff16733164b56ee911abf2fce1768193c2aca Mon Sep 17 00:00:00 2001 From: sowle Date: Thu, 11 Apr 2024 17:00:36 +0200 Subject: [PATCH 142/184] wallet2: fixed height upper limit in decoy request for pre-HF4 PoS mining (effective mostly for the testnet) --- src/wallet/wallet2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index b1b9b376..b15a6172 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -4581,7 +4581,7 @@ bool wallet2::prepare_and_sign_pos_block(const mining_context& cxt, uint64_t ful if (m_required_decoys_count > 0 && !is_auditable()) { COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request decoys_req = AUTO_VAL_INIT(decoys_req); - decoys_req.height_upper_limit = 0; // TODO @#@# maybe use m_last_pow_block_h like Zarcanum? + decoys_req.height_upper_limit = std::min(m_last_pow_block_h, m_last_known_daemon_height > m_core_runtime_config.min_coinstake_age ? m_last_known_daemon_height - m_core_runtime_config.min_coinstake_age : m_last_pow_block_h); decoys_req.use_forced_mix_outs = false; decoys_req.decoys_count = m_required_decoys_count + 1; // one more to be able to skip a decoy in case it hits the real output decoys_req.amounts.push_back(pe.amount); // request one batch of decoys From 530acf4662759a7603c6b4f68750b04635014916 Mon Sep 17 00:00:00 2001 From: sowle Date: Thu, 11 Apr 2024 17:14:43 +0200 Subject: [PATCH 143/184] wallet2::has_bare_unspent_outputs() was fixed for the testnet --- src/currency_core/currency_config.h | 2 ++ src/wallet/wallet2.cpp | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/currency_core/currency_config.h b/src/currency_core/currency_config.h index 9218bfe8..f0a297ce 100644 --- a/src/currency_core/currency_config.h +++ b/src/currency_core/currency_config.h @@ -265,6 +265,7 @@ #define ZANO_HARDFORK_03_AFTER_HEIGHT 1082577 // 2021-06-01 23:28:10 #define ZANO_HARDFORK_04_AFTER_HEIGHT 2555000 // 2024-03-21 11:49:55 #define ZANO_HARDFORK_05_AFTER_HEIGHT 999999999999999999 +#define ZANO_HARDFORK_04_TIMESTAMP_ACTUAL 1711021795ull // block 2555000, 2024-03-21 11:49:55 UTC #else /////// Zarcanum Testnet ////////////////////////////// #define ZANO_HARDFORK_01_AFTER_HEIGHT 0 @@ -272,6 +273,7 @@ #define ZANO_HARDFORK_03_AFTER_HEIGHT 0 #define ZANO_HARDFORK_04_AFTER_HEIGHT 200 #define ZANO_HARDFORK_05_AFTER_HEIGHT 200 +#define ZANO_HARDFORK_04_TIMESTAMP_ACTUAL 1712785801ull // block 200, 2024-04-10 21:50:01 UTC #endif diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index b15a6172..8ac646ca 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -2227,10 +2227,9 @@ bool wallet2::has_related_alias_entry_unconfirmed(const currency::transaction& t return false; } //---------------------------------------------------------------------------------------------------- -#define HARDFORK_04_TIMESTAMP_ACTUAL 1711021795ull // block 2555000, 2024-03-21 11:49:55 UTC bool wallet2::has_bare_unspent_outputs() const { - if (m_account.get_createtime() > HARDFORK_04_TIMESTAMP_ACTUAL) + if (m_account.get_createtime() > ZANO_HARDFORK_04_TIMESTAMP_ACTUAL) return false; [[maybe_unused]] uint64_t bal = 0; From eae8fde294ba2daa0b04c48a3a975ad108388447 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Tue, 16 Apr 2024 17:26:21 +0300 Subject: [PATCH 144/184] === build number: 300 -> 301 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index a6b75ab0..ef17d768 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 300 +#define PROJECT_VERSION_BUILD_NO 301 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From ad66a6db30ee4edc3030ff94ed61cb270de1d1ba Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Sat, 20 Apr 2024 00:05:31 +0400 Subject: [PATCH 145/184] added get_assets_list command to daemon API --- src/currency_core/blockchain_storage.cpp | 22 +++++++++++++++++++ src/currency_core/blockchain_storage.h | 1 + src/gui/qt-daemon/layout | 2 +- src/rpc/core_rpc_server.cpp | 12 +++++++++++ src/rpc/core_rpc_server.h | 4 +++- src/rpc/core_rpc_server_commands_defs.h | 27 ++++++++++++++++++++++++ src/wallet/wallets_manager.cpp | 4 ++-- 7 files changed, 68 insertions(+), 4 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 35e575a8..ef050958 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -3810,6 +3810,28 @@ bool blockchain_storage::get_asset_info(const crypto::public_key& asset_id, asse return false; } //------------------------------------------------------------------ +uint64_t blockchain_storage::get_assets(uint64_t offset, uint64_t count, std::list& assets) const +{ + CRITICAL_REGION_LOCAL(m_read_lock); + m_db_assets.enumerate_items([&](uint64_t i, const crypto::public_key& asset_id, const std::list& asset_descriptor_history) + { + if (i < offset) + { + return true; + } + + CHECK_AND_ASSERT_THROW_MES(asset_descriptor_history.size(), "asset_descriptor_history unexpectedly have 0 size"); + assets.push_back(asset_descriptor_with_id()); + static_cast(assets.back()) = asset_descriptor_history.back(); + assets.back().asset_id = asset_id; + if (i + count > offset) + { + return false; + } + return true; + }); +} +//------------------------------------------------------------------ uint64_t blockchain_storage::get_assets_count() const { CRITICAL_REGION_LOCAL(m_read_lock); diff --git a/src/currency_core/blockchain_storage.h b/src/currency_core/blockchain_storage.h index c24e1104..df87ce37 100644 --- a/src/currency_core/blockchain_storage.h +++ b/src/currency_core/blockchain_storage.h @@ -302,6 +302,7 @@ namespace currency bool get_asset_history(const crypto::public_key& asset_id, std::list& result) const; bool get_asset_info(const crypto::public_key& asset_id, asset_descriptor_base& info)const; uint64_t get_assets_count() const; + uint64_t get_assets(uint64_t offset, uint64_t count, std::list& assets) const; bool check_tx_input(const transaction& tx, size_t in_index, const txin_to_key& txin, const crypto::hash& tx_prefix_hash, uint64_t& max_related_block_height, uint64_t& source_max_unlock_time_for_pos_coinbase)const; bool check_tx_input(const transaction& tx, size_t in_index, const txin_multisig& txin, const crypto::hash& tx_prefix_hash, uint64_t& max_related_block_height)const; bool check_tx_input(const transaction& tx, size_t in_index, const txin_htlc& txin, const crypto::hash& tx_prefix_hash, uint64_t& max_related_block_height)const; diff --git a/src/gui/qt-daemon/layout b/src/gui/qt-daemon/layout index 3b816edf..3b882866 160000 --- a/src/gui/qt-daemon/layout +++ b/src/gui/qt-daemon/layout @@ -1 +1 @@ -Subproject commit 3b816edf2da54c8df55e871a8005ac575ccb5dcd +Subproject commit 3b882866ddece56b624f7c326e317e69740fbe86 diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index cd9c20d2..f4bb2aff 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -738,6 +738,18 @@ namespace currency return true; } //------------------------------------------------------------------------------------------------------------------------------ + bool core_rpc_server::on_get_assets_list(const COMMAND_RPC_GET_ASSETS_LIST::request& req, COMMAND_RPC_GET_ASSETS_LIST::response& res, connection_context& cntx) + { + CHECK_CORE_READY(); + if (!m_core.get_blockchain_storage().get_assets(req.offset, req.count, res.assets)) + { + res.status = API_RETURN_CODE_NOT_FOUND; + return true; + } + res.status = API_RETURN_CODE_OK; + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ bool core_rpc_server::on_get_main_block_details(const COMMAND_RPC_GET_BLOCK_DETAILS::request& req, COMMAND_RPC_GET_BLOCK_DETAILS::response& res, epee::json_rpc::error& error_resp, connection_context& cntx) { if (!m_core.get_blockchain_storage().get_main_block_rpc_details(req.id, res.block_details)) diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h index daf9452c..ad4786f2 100644 --- a/src/rpc/core_rpc_server.h +++ b/src/rpc/core_rpc_server.h @@ -88,6 +88,7 @@ namespace currency bool on_get_pool_info(const COMMAND_RPC_GET_POOL_INFO::request& req, COMMAND_RPC_GET_POOL_INFO::response& res, connection_context& cntx); bool on_get_votes(const COMMAND_RPC_GET_VOTES::request& req, COMMAND_RPC_GET_VOTES::response& res, connection_context& cntx); bool on_get_asset_info(const COMMAND_RPC_GET_ASSET_INFO::request& req, COMMAND_RPC_GET_ASSET_INFO::response& res, connection_context& cntx); + bool on_get_assets_list(const COMMAND_RPC_GET_ASSETS_LIST::request& req, COMMAND_RPC_GET_ASSETS_LIST::response& res, connection_context& cntx); bool on_get_main_block_details(const COMMAND_RPC_GET_BLOCK_DETAILS::request& req, COMMAND_RPC_GET_BLOCK_DETAILS::response& res, epee::json_rpc::error& error_resp, connection_context& cntx); bool on_get_alt_block_details(const COMMAND_RPC_GET_BLOCK_DETAILS::request& req, COMMAND_RPC_GET_BLOCK_DETAILS::response& res, epee::json_rpc::error& error_resp, connection_context& cntx); @@ -150,7 +151,8 @@ namespace currency MAP_JON_RPC ("getrandom_outs3", on_get_random_outs3, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3) MAP_JON_RPC ("get_votes", on_get_votes, COMMAND_RPC_GET_VOTES) //assets api - MAP_JON_RPC ("get_asset_info", on_get_asset_info, COMMAND_RPC_GET_ASSET_INFO) + MAP_JON_RPC ("get_asset_info", on_get_asset_info, COMMAND_RPC_GET_ASSET_INFO) + MAP_JON_RPC ("get_assets_list", on_get_assets_list, COMMAND_RPC_GET_ASSETS_LIST) MAP_JON_RPC_WE("get_main_block_details", on_get_main_block_details, COMMAND_RPC_GET_BLOCK_DETAILS) MAP_JON_RPC_WE("get_alt_block_details", on_get_alt_block_details, COMMAND_RPC_GET_BLOCK_DETAILS) diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 27388f04..431cfd20 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -135,6 +135,33 @@ namespace currency }; }; + struct COMMAND_RPC_GET_ASSETS_LIST + { + DOC_COMMAND("Return list of assets registered in Zano blockchain"); + + struct request + { + uint64_t offset = 0; + uint64_t count = 100; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(offset) DOC_DSCR("Offset for the item to start copying") DOC_EXMP(0) DOC_END + KV_SERIALIZE(count) DOC_DSCR("Number of items to recieve") DOC_EXMP(100) DOC_END + END_KV_SERIALIZE_MAP() + }; + + struct response + { + std::string status; + std::list assets; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(status) DOC_DSCR("Status code of operation, OK if success") DOC_EXMP(API_RETURN_CODE_OK) DOC_END + KV_SERIALIZE(assets) DOC_DSCR("List of assets registered in Zano blockchain") DOC_EXMP_AUTO(1) DOC_END + END_KV_SERIALIZE_MAP() + }; + }; + struct COMMAND_RPC_GET_HEIGHT { DOC_COMMAND("Return current blockchain height"); diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index c9bfddb3..2bcdb3dd 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -582,8 +582,8 @@ std::string wallets_manager::setup_wallet_rpc(const std::string& jwt_secret) } //we don't override command line JWT secret - if(!m_wallet_rpc_server.get_jwt_secret().size() ) - m_wallet_rpc_server.set_jwt_secret(jwt_secret); + //if(!m_wallet_rpc_server.get_jwt_secret().size() ) + m_wallet_rpc_server.set_jwt_secret(jwt_secret); m_rpc_server.set_rpc_chain_handler(this); #endif From 2e2d3c26b42b5a0389ae5445cc8601ba9726b68a Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Sat, 20 Apr 2024 00:10:55 +0400 Subject: [PATCH 146/184] Moved UI to latest commit --- src/gui/qt-daemon/layout | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/qt-daemon/layout b/src/gui/qt-daemon/layout index 3b882866..155dd4c9 160000 --- a/src/gui/qt-daemon/layout +++ b/src/gui/qt-daemon/layout @@ -1 +1 @@ -Subproject commit 3b882866ddece56b624f7c326e317e69740fbe86 +Subproject commit 155dd4c96525a915353261110662a831efe7685a From 9f8ce4cc0988e73588ccea29f2c5bbddbc3b2dc8 Mon Sep 17 00:00:00 2001 From: sowle Date: Sun, 21 Apr 2024 04:41:43 +0200 Subject: [PATCH 147/184] daemon RPC documentation added --- src/currency_core/blockchain_storage_basic.h | 12 +- src/currency_core/currency_format_utils.cpp | 1 + src/rpc/core_rpc_server_commands_defs.h | 778 +++++++++++-------- tests/core_tests/multisig_wallet_tests.cpp | 2 +- 4 files changed, 467 insertions(+), 326 deletions(-) diff --git a/src/currency_core/blockchain_storage_basic.h b/src/currency_core/blockchain_storage_basic.h index 27908fbf..65c6862b 100644 --- a/src/currency_core/blockchain_storage_basic.h +++ b/src/currency_core/blockchain_storage_basic.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2023 Zano Project +// Copyright (c) 2014-2024 Zano Project // Copyright (c) 2014-2018 The Louisdor Project // Copyright (c) 2012-2013 The Cryptonote developers // Copyright (c) 2012-2013 The Boolberry developers @@ -167,9 +167,9 @@ namespace currency uint64_t no; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(proposal_id) - KV_SERIALIZE(yes) - KV_SERIALIZE(no) + KV_SERIALIZE(proposal_id) DOC_DSCR("ID of the proposal.") DOC_EXMP("ZAP999") DOC_END + KV_SERIALIZE(yes) DOC_DSCR("Nubmer of positve votes.") DOC_EXMP(42) DOC_END + KV_SERIALIZE(no) DOC_DSCR("Number of negative votes.") DOC_EXMP(37) DOC_END END_KV_SERIALIZE_MAP() }; @@ -179,8 +179,8 @@ namespace currency std::list votes; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(total_pos_blocks) - KV_SERIALIZE(votes) + KV_SERIALIZE(total_pos_blocks) DOC_DSCR("Number of blocks in a given range.") DOC_EXMP(87482) DOC_END + KV_SERIALIZE(votes) DOC_DSCR("Result of votes in a given range.") DOC_END END_KV_SERIALIZE_MAP() }; diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 1124d625..20d43d9f 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -2814,6 +2814,7 @@ namespace currency return CURRENT_TRANSACTION_VERSION; } //--------------------------------------------------------------- + // TODO @#@# this function is obsolete and needs to be re-written uint64_t get_reward_from_miner_tx(const transaction& tx) { uint64_t income = 0; diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 431cfd20..6ccd37ba 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -1,20 +1,30 @@ -// Copyright (c) 2014-2018 Zano Project +// Copyright (c) 2014-2024 Zano Project // Copyright (c) 2014-2018 The Louisdor Project // Copyright (c) 2012-2013 The Cryptonote developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. - #pragma once #include "serialization/keyvalue_hexemizer.h" #include "currency_protocol/currency_protocol_defs.h" #include "currency_core/currency_basic.h" -#include "currency_core/difficulty.h" +//#include "currency_core/difficulty.h" #include "crypto/hash.h" #include "p2p/p2p_protocol_defs.h" -#include "storages/portable_storage_base.h" +//#include "storages/portable_storage_base.h" #include "currency_core/offers_service_basics.h" -#include "currency_core/basic_api_response_codes.h" +#include +#include +#include +#include +#include +#include #include "common/error_codes.h" +#include +#include +#include +#include +//#include "currency_core/basic_api_response_codes.h" + namespace currency { //----------------------------------------------- @@ -26,9 +36,9 @@ namespace currency std::string comment; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(address) - KV_SERIALIZE(tracking_key) - KV_SERIALIZE(comment) + KV_SERIALIZE(address) DOC_DSCR("Address of the alias.") DOC_EXMP("ZxCSpsGGeJsS8fwvQ4HktDU3qBeauoJTR6j73jAWWZxFXdF7XTbGm4YfS2kXJmAP4Rf5BVsSQ9iZ45XANXEYsrLN2L2W77dH7") DOC_END + KV_SERIALIZE(tracking_key) DOC_DSCR("View secret key of the corresponding address (optional).") DOC_EXMP("18bb94f69ed61b47b6556f3871b89dff8f9a6f4f798f706fd199b05ccf8ef20c") DOC_END + KV_SERIALIZE(comment) DOC_DSCR("Arbitrary comment (optional).") DOC_EXMP("Society is never gonna make any progress until we all learn to pretend to like each other.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -38,8 +48,8 @@ namespace currency alias_rpc_details_base details; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(alias) - KV_CHAIN_MAP(details) + KV_SERIALIZE(alias) DOC_DSCR("Alias itself, a brief shortcut for an address.") DOC_EXMP("zxdya6q6whzwqjkmtcsjpc3ku") DOC_END + KV_CHAIN_MAP(details) //DOC_DSCR("Object of alias_rpc_details_base struct.") DOC_EXMP_AUTO() DOC_END END_KV_SERIALIZE_MAP() }; @@ -51,9 +61,9 @@ namespace currency alias_rpc_details_base details; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(old_address) - KV_SERIALIZE(alias) - KV_SERIALIZE(details) + KV_SERIALIZE(old_address) DOC_DSCR("Previous address of the alias.") DOC_EXMP("ZxCSpsGGeJsS8fwvQ4HktDU3qBeauoJTR6j73jAWWZxFXdF7XTbGm4YfS2kXJmAP4Rf5BVsSQ9iZ45XANXEYsrLN2L2W77dH7") DOC_END + KV_SERIALIZE(alias) DOC_DSCR("Alias itself, a brief shortcut for an address.") DOC_EXMP("zxdya6q6whzwqjkmtcsjpc3ku") DOC_END + KV_SERIALIZE(details) DOC_DSCR("Object of alias_rpc_details_base struct.") DOC_EXMP_AUTO() DOC_END END_KV_SERIALIZE_MAP() }; @@ -62,6 +72,8 @@ namespace currency struct COMMAND_RPC_GET_POOL_INFO { + DOC_COMMAND("Obtain basic information about the transaction pool."); + struct request { BEGIN_KV_SERIALIZE_MAP() @@ -75,23 +87,25 @@ namespace currency std::list aliases_que; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) - KV_SERIALIZE(error_code) - KV_SERIALIZE(aliases_que) + KV_SERIALIZE(status) DOC_DSCR("Status code, OK if succeeded.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END + KV_SERIALIZE(error_code) DOC_DSCR("Error code, if there's any error (optional).") DOC_EXMP_AUTO() DOC_END + KV_SERIALIZE(aliases_que) DOC_DSCR("List of aliases from txs that are currently in the tx pool.") DOC_EXMP_AUTO() DOC_END END_KV_SERIALIZE_MAP() }; }; struct COMMAND_RPC_GET_VOTES { + DOC_COMMAND("Get votes' results from the given block range."); + struct request { uint64_t h_start; uint64_t h_end; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(h_start) - KV_SERIALIZE(h_end) + KV_SERIALIZE(h_start) DOC_DSCR("Start of the block range to search in (including).") DOC_EXMP(0) DOC_END + KV_SERIALIZE(h_end) DOC_DSCR("End of the block range to serach in (excluding).") DOC_EXMP(40000) DOC_END END_KV_SERIALIZE_MAP() }; @@ -102,9 +116,9 @@ namespace currency vote_results votes; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) - KV_SERIALIZE(error_code) - KV_SERIALIZE(votes) + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END + KV_SERIALIZE(error_code) DOC_DSCR("Error code, if any.") DOC_END + KV_SERIALIZE(votes) DOC_DSCR("Found votes in the given range.") DOC_END END_KV_SERIALIZE_MAP() }; }; @@ -114,13 +128,15 @@ namespace currency crypto::public_key asset_id; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_POD_AS_HEX_STRING(asset_id) + KV_SERIALIZE_POD_AS_HEX_STRING(asset_id) DOC_DSCR("ID of an asset.") DOC_EXMP("cc4e69455e63f4a581257382191de6856c2156630b3fba0db4bdd73ffcfb36b6") DOC_END END_KV_SERIALIZE_MAP() }; struct COMMAND_RPC_GET_ASSET_INFO { + DOC_COMMAND("Obtain information for the given asset by its ID."); + typedef asset_id_kv request; struct response @@ -129,8 +145,8 @@ namespace currency asset_descriptor_base asset_descriptor; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) - KV_SERIALIZE(asset_descriptor) + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END + KV_SERIALIZE(asset_descriptor) DOC_DSCR("Descriptor of the given asset.") DOC_END END_KV_SERIALIZE_MAP() }; }; @@ -165,7 +181,6 @@ namespace currency struct COMMAND_RPC_GET_HEIGHT { DOC_COMMAND("Return current blockchain height"); - struct request { @@ -179,8 +194,8 @@ namespace currency std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(height) DOC_DSCR("Some height of the block") DOC_EXMP(11111) DOC_END - KV_SERIALIZE(status) DOC_DSCR("Status of the operation") DOC_EXMP("OK") DOC_END + KV_SERIALIZE(height) DOC_DSCR("Height of the blockchain (equals to top block's height + 1).") DOC_EXMP(11111) DOC_END + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; @@ -193,11 +208,11 @@ namespace currency struct request { uint64_t minimum_height; - std::list block_ids; //*first 10 blocks id goes sequential, next goes in pow(2,n) offset, like 2, 4, 8, 16, 32, 64 and so on, and the last one is always genesis block */ + std::list block_ids; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(minimum_height) - KV_SERIALIZE_CONTAINER_POD_AS_BLOB(block_ids) + KV_SERIALIZE(minimum_height) DOC_DSCR("The minimum height of the returning buch of blocks.") DOC_EXMP(0) DOC_END + KV_SERIALIZE_CONTAINER_POD_AS_BLOB(block_ids) /* TODO !!! DOC_DSCR("Current state of the local blockchain. Hashes of the most recent 10 blocks goes first, then each 2nd, then 4th, 8, 16, 32, 64 and so on, and the last one is always hash of the genesis block.") DOC_END */ END_KV_SERIALIZE_MAP() }; @@ -209,10 +224,10 @@ namespace currency std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(blocks) - KV_SERIALIZE(start_height) - KV_SERIALIZE(current_height) - KV_SERIALIZE(status) + KV_SERIALIZE(blocks) DOC_DSCR("Bunch of blocks") DOC_END + KV_SERIALIZE(start_height) DOC_DSCR("Starting height of the resulting bunch of blocks.") DOC_END + KV_SERIALIZE(current_height) DOC_DSCR("Current height of the blockchain.") DOC_END + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; @@ -223,12 +238,14 @@ namespace currency //----------------------------------------------- struct COMMAND_RPC_GET_TRANSACTIONS { + DOC_COMMAND("Retreive transactions by their IDs.") + struct request { std::list txs_hashes; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(txs_hashes) + KV_SERIALIZE(txs_hashes) DOC_DSCR("List of transactions' IDs.") DOC_EXMP_AUTO() DOC_END // "146791c4f5ca94bcf423557e5eb859a3a69991bd33960d52f709d88bf5d1ac6d","ec4d913a40a9ac1fbd9d33b71ef507b5c85d1f503b89096618a18b08991b5171") DOC_END END_KV_SERIALIZE_MAP() }; @@ -239,9 +256,9 @@ namespace currency std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(txs_as_hex) DOC_DSCR("Transactions stored as blobs") DOC_EXMP_AUTO(1, "7d914497d91442f8f3c2268397d914497d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc2f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc") DOC_END - KV_SERIALIZE(missed_tx) DOC_DSCR("Missed transactions hashes") DOC_EXMP_AUTO(1, "97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc") DOC_END - KV_SERIALIZE(status) DOC_DSCR("Command response status") DOC_EXMP_AUTO("OK") DOC_END + KV_SERIALIZE(txs_as_hex) DOC_DSCR("Transactions stored as blobs") DOC_EXMP_AUTO(1, "7d914497d91442f8f3c2268397d914497d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc2f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc") DOC_END + KV_SERIALIZE(missed_tx) DOC_DSCR("Missed transactions hashes") DOC_EXMP_AUTO(1, "97d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc") DOC_END + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; @@ -249,12 +266,14 @@ namespace currency //----------------------------------------------- struct COMMAND_RPC_GET_EST_HEIGHT_FROM_DATE { + DOC_COMMAND("Give an estimation of block height by the given date.") + struct request { uint64_t timestamp; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(timestamp) + KV_SERIALIZE(timestamp) DOC_DSCR("Linux timestamp for the required date.") DOC_EXMP(1711021795) DOC_END END_KV_SERIALIZE_MAP() }; @@ -264,14 +283,16 @@ namespace currency std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(h) - KV_SERIALIZE(status) + KV_SERIALIZE(h) DOC_DSCR("Estimated height of a block.") DOC_EXMP(2555000) DOC_END + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; //----------------------------------------------- struct COMMAND_RPC_GET_TX_POOL { + DOC_COMMAND("Retreives transactions from tx pool (and other information).") + struct request { BEGIN_KV_SERIALIZE_MAP() @@ -285,20 +306,22 @@ namespace currency std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(txs) - KV_SERIALIZE(tx_expiration_ts_median) - KV_SERIALIZE(status) + KV_SERIALIZE(txs) DOC_DSCR("Transactions as blobs.") DOC_EXMP_AUTO(1, "7d914497d91442f8f3c2268397d914497d91442f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc2f8f3c22683585eaa60b53757d49bf046a96269cef45c1bc9ff7300cc") DOC_END + KV_SERIALIZE(tx_expiration_ts_median) DOC_DSCR("Timestamp median value of last TX_EXPIRATION_TIMESTAMP_CHECK_WINDOW blocks.") DOC_END + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; //----------------------------------------------- struct COMMAND_RPC_CHECK_KEYIMAGES { + DOC_COMMAND("Check spent status of given key images.") + struct request { std::list images; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_CONTAINER_POD_AS_BLOB(images) + KV_SERIALIZE_CONTAINER_POD_AS_BLOB(images) //DOC_DSCR("List of key images.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -308,20 +331,22 @@ namespace currency std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(images_stat) - KV_SERIALIZE(status) + KV_SERIALIZE(images_stat) DOC_DSCR("List of spent states, where 1 means unspent and 0 means spent.") DOC_EXMP_AUTO(1, 0) DOC_END + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; //----------------------------------------------- struct COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES { + DOC_COMMAND("Obtain global outputs' indexes for the given txs.") + struct request { std::list txids; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_CONTAINER_POD_AS_BLOB(txids) + KV_SERIALIZE_CONTAINER_POD_AS_BLOB(txids)// DOC_DSCR("List of transaction hashes.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -332,8 +357,8 @@ namespace currency //std::vector o_indexes; std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(tx_global_outs) - KV_SERIALIZE(status) + KV_SERIALIZE(tx_global_outs) DOC_DSCR("List of global indexies for each output for each transaction.") DOC_END + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; @@ -341,18 +366,19 @@ namespace currency struct COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES_BY_AMOUNT { + DOC_COMMAND("Returns transaction ID and local output index for a given output amount and its global index.") + struct request { uint64_t amount; uint64_t i; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(amount) - KV_SERIALIZE(i) + KV_SERIALIZE(amount) DOC_DSCR("The specific amount of output to query.") DOC_END + KV_SERIALIZE(i) DOC_DSCR("The global index of the output amount to be queried.") DOC_END END_KV_SERIALIZE_MAP() }; - struct response { std::string status; @@ -360,9 +386,9 @@ namespace currency uint64_t out_no; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_POD_AS_HEX_STRING(tx_id) - KV_SERIALIZE(out_no) - KV_SERIALIZE(status) + KV_SERIALIZE_POD_AS_HEX_STRING(tx_id) DOC_DSCR("Transaction ID where the queried output is present, if found.") DOC_END + KV_SERIALIZE(out_no) DOC_DSCR("Local output index within the transaction.") DOC_END + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; @@ -370,16 +396,17 @@ namespace currency struct COMMAND_RPC_GET_MULTISIG_INFO { + DOC_COMMAND("Retrieve basic information about a multisig output using its unique identifier (hash)."); + struct request { crypto::hash ms_id; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_POD_AS_HEX_STRING(ms_id) + KV_SERIALIZE_POD_AS_HEX_STRING(ms_id) DOC_DSCR("The multisig output's unique identifier (hash).") DOC_END END_KV_SERIALIZE_MAP() }; - struct response { std::string status; @@ -387,15 +414,17 @@ namespace currency uint64_t out_no; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_POD_AS_HEX_STRING(tx_id) - KV_SERIALIZE(out_no) - KV_SERIALIZE(status) + KV_SERIALIZE_POD_AS_HEX_STRING(tx_id) DOC_DSCR("Transaction ID where the multisig output is present, if found.")DOC_END + KV_SERIALIZE(out_no) DOC_DSCR("Local output index within the transaction.") DOC_END + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; //----------------------------------------------- struct COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS { + DOC_COMMAND("Retrieve random decoy outputs for specified amounts, to be used for mixing in transactions."); + struct request { std::list amounts; @@ -403,10 +432,10 @@ namespace currency uint64_t height_upper_limit; // if nonzero, all the decoy outputs must be either older than, or the same age as this height bool use_forced_mix_outs; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(amounts) - KV_SERIALIZE(decoys_count) - KV_SERIALIZE(height_upper_limit) - KV_SERIALIZE(use_forced_mix_outs) + KV_SERIALIZE(amounts) DOC_DSCR("List of amounts for which decoy outputs are requested.") DOC_END + KV_SERIALIZE(decoys_count) DOC_DSCR("Number of decoy outputs required for each amount specified.") DOC_END + KV_SERIALIZE(height_upper_limit) DOC_DSCR("Maximum blockchain height from which decoys can be taken. If nonzero, decoys must be at this height or older.") DOC_END + KV_SERIALIZE(use_forced_mix_outs) DOC_DSCR("If true, only outputs with a 'mix_attr' greater than 0 are used as decoys.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -440,8 +469,8 @@ namespace currency std::list outs; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(amount) - KV_SERIALIZE_CONTAINER_POD_AS_BLOB(outs) + KV_SERIALIZE(amount) DOC_DSCR("The amount for which decoys are returned.") DOC_END + KV_SERIALIZE_CONTAINER_POD_AS_BLOB(outs) //DOC_DSCR("List of 'out_entry' structures, serialized as a blob.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -450,22 +479,24 @@ namespace currency std::vector outs; std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(outs) - KV_SERIALIZE(status) + KV_SERIALIZE(outs) DOC_DSCR("List of 'outs_for_amount' structures, each containing decoys for a specific amount.") DOC_END + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; //----------------------------------------------- struct COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3 { + DOC_COMMAND("Version 3 of the command to retrieve random decoy outputs for specified amounts, focusing on either pre-zarcanum or post-zarcanum zones based on the amount value."); + struct offsets_distribution { uint64_t amount; //if amount is 0 then lookup in post-zarcanum zone only, if not 0 then pre-zarcanum only std::vector global_offsets; //[i] = global_index to pick up BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(amount) - KV_SERIALIZE(global_offsets) + KV_SERIALIZE(amount) DOC_DSCR("If set to 0, only ZC outputs are considered. If nonzero, only old bare outputs are considered.") DOC_END + KV_SERIALIZE(global_offsets) DOC_DSCR("List of global indices for picking decoys. Each index corresponds to a potential decoy output.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -477,27 +508,30 @@ namespace currency bool use_forced_mix_outs; uint64_t coinbase_percents; //from 0 to 100, estimate percents of coinbase outputs included in decoy sets BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(amounts) - KV_SERIALIZE(height_upper_limit) - KV_SERIALIZE(use_forced_mix_outs) - KV_SERIALIZE(coinbase_percents) + KV_SERIALIZE(amounts) DOC_DSCR("List of amount distributions specifying where to look for decoys, based on old bare outputs or ZC outputs.") DOC_END + KV_SERIALIZE(height_upper_limit) DOC_DSCR("Maximum blockchain height from which decoys can be taken. If nonzero, decoys must be at this height or older.") DOC_END + KV_SERIALIZE(use_forced_mix_outs) DOC_DSCR("If true, only outputs with a 'mix_attr' greater than 0 are used as decoys.") DOC_END + KV_SERIALIZE(coinbase_percents) DOC_DSCR("Specifies the estimated percentage of coinbase outputs to be included in the decoy sets, ranging from 0 to 100.") DOC_END END_KV_SERIALIZE_MAP() }; typedef COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response response; }; - - struct COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_LEGACY + //----------------------------------------------- + struct COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_LEGACY { + DOC_COMMAND("Retrieve random decoy outputs for specified amounts (legacy format)."); + struct request { std::list amounts; uint64_t outs_count; bool use_forced_mix_outs; + BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(amounts) - KV_SERIALIZE(outs_count) - KV_SERIALIZE(use_forced_mix_outs) + KV_SERIALIZE(amounts) DOC_DSCR("List of amounts for which decoy outputs are requested.") DOC_END + KV_SERIALIZE(outs_count) DOC_DSCR("Number of decoy outputs requested for each amount.") DOC_END + KV_SERIALIZE(use_forced_mix_outs) DOC_DSCR("If true, only outputs with a 'mix_attr' greater than 0 are used as decoys.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -515,8 +549,8 @@ namespace currency std::list outs; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(amount) - KV_SERIALIZE_CONTAINER_POD_AS_BLOB(outs) + KV_SERIALIZE(amount) DOC_DSCR("The amount for which decoys are returned.") DOC_END + KV_SERIALIZE_CONTAINER_POD_AS_BLOB(outs) //DOC_DSCR("List of 'out_entry' structures serialized as a blob, representing the decoy outputs for the specified amount.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -524,9 +558,10 @@ namespace currency { std::vector outs; std::string status; + BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(outs) - KV_SERIALIZE(status) + KV_SERIALIZE(outs) DOC_DSCR("List of 'outs_for_amount' structures, each containing decoys for a specific amount.") DOC_END + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; @@ -542,7 +577,7 @@ namespace currency { std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; @@ -550,7 +585,9 @@ namespace currency //----------------------------------------------- struct COMMAND_RPC_SEND_RAW_TX { - struct request + DOC_COMMAND("Broadcasts a raw transaction encoded in hexadecimal format to the network."); + + struct request { std::string tx_as_hex; @@ -558,8 +595,8 @@ namespace currency explicit request(const transaction &); BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(tx_as_hex) - END_KV_SERIALIZE_MAP() + KV_SERIALIZE(tx_as_hex) DOC_DSCR("The transaction data as a hexadecimal string, ready for network broadcast.") DOC_END + END_KV_SERIALIZE_MAP() }; @@ -568,11 +605,12 @@ namespace currency std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; + //----------------------------------------------- struct COMMAND_RPC_FORCE_RELAY_RAW_TXS { @@ -581,7 +619,7 @@ namespace currency std::vector txs_as_hex; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(txs_as_hex) + KV_SERIALIZE(txs_as_hex) DOC_DSCR("List of transactions as a hexadecimal strings.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -591,21 +629,23 @@ namespace currency std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; //----------------------------------------------- struct COMMAND_RPC_START_MINING { + DOC_COMMAND("Initiates PoW mining process on a node using the specified miner address and the number of CPU threads."); + struct request { std::string miner_address; uint64_t threads_count; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(miner_address) - KV_SERIALIZE(threads_count) + KV_SERIALIZE(miner_address) DOC_DSCR("The address where the mining rewards will be deposited.") DOC_END + KV_SERIALIZE(threads_count) DOC_DSCR("The number of CPU threads to use for mining.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -614,7 +654,7 @@ namespace currency std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; @@ -801,11 +841,14 @@ namespace currency struct COMMAND_RPC_GET_INFO { + DOC_COMMAND("Retrieves various information about the blockchain node. The user must specify their needs via a 'flags' field in the request by combining necessary flags using binary OR. Some values are always calculated and provided, others only if the corresponding flag is specified."); + struct request { uint64_t flags; + BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(flags) + KV_SERIALIZE(flags) DOC_DSCR("Combination of flags to request specific data elements that are computationally expensive to calculate.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -873,83 +916,92 @@ namespace currency uint64_t offers_count; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) - KV_SERIALIZE(height) - KV_SERIALIZE(pos_difficulty) - KV_SERIALIZE(pow_difficulty) - KV_SERIALIZE(tx_count) - KV_SERIALIZE(tx_pool_size) - KV_SERIALIZE(alt_blocks_count) - KV_SERIALIZE(outgoing_connections_count) - KV_SERIALIZE(incoming_connections_count) - KV_SERIALIZE(synchronized_connections_count) - KV_SERIALIZE(net_time_delta_median) - KV_SERIALIZE(white_peerlist_size) - KV_SERIALIZE(grey_peerlist_size) - KV_SERIALIZE(current_blocks_median) - KV_SERIALIZE(current_network_hashrate_50) - KV_SERIALIZE(current_network_hashrate_350) - KV_SERIALIZE(alias_count) - KV_SERIALIZE(daemon_network_state) - KV_SERIALIZE(synchronization_start_height) - KV_SERIALIZE(max_net_seen_height) - KV_SERIALIZE(transactions_cnt_per_day) - KV_SERIALIZE(transactions_volume_per_day) - KV_SERIALIZE(mi) - KV_SERIALIZE(pos_sequence_factor) - KV_SERIALIZE(pow_sequence_factor) - KV_SERIALIZE(last_pow_timestamp) - KV_SERIALIZE(last_pos_timestamp) - KV_SERIALIZE(seconds_for_10_blocks) - KV_SERIALIZE(seconds_for_30_blocks) - KV_SERIALIZE(total_coins) - KV_SERIALIZE(block_reward) - KV_SERIALIZE(last_block_total_reward) - KV_SERIALIZE(pos_diff_total_coins_rate) - KV_SERIALIZE(pos_block_ts_shift_vs_actual) - KV_SERIALIZE(expiration_median_timestamp) - KV_SERIALIZE(pos_allowed) - KV_SERIALIZE(outs_stat) - KV_SERIALIZE(performance_data) - KV_SERIALIZE(tx_pool_performance_data) - KV_SERIALIZE(last_block_size) - KV_SERIALIZE(current_max_allowed_block_size) - KV_SERIALIZE(tx_count_in_last_block) - KV_SERIALIZE(default_fee) - KV_SERIALIZE(minimum_fee) - KV_SERIALIZE(last_block_timestamp) - KV_SERIALIZE(last_block_hash) - KV_SERIALIZE(is_hardfok_active) - KV_SERIALIZE(offers_count) + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END + // Always calculated and provided fields + KV_SERIALIZE(height) DOC_DSCR("The current size of the blockchain, equal to the height of the top block plus one.") DOC_END + KV_SERIALIZE(pos_allowed) DOC_DSCR("Boolean value indicating whether PoS mining is currently allowed based on network rules and state.") DOC_END + KV_SERIALIZE(pos_difficulty) DOC_DSCR("Current difficulty for Proof of Stake mining.") DOC_END + KV_SERIALIZE(pow_difficulty) DOC_DSCR("Current difficulty for Proof of Work mining.") DOC_END + KV_SERIALIZE(tx_count) DOC_DSCR("Total number of transactions in the blockchain.") DOC_END + KV_SERIALIZE(tx_pool_size) DOC_DSCR("Number of transactions currently in the pool.") DOC_END + KV_SERIALIZE(alt_blocks_count) DOC_DSCR("Number of alternative blocks on the blockchain.") DOC_END + KV_SERIALIZE(outgoing_connections_count) DOC_DSCR("Number of outgoing P2P connections to other nodes.") DOC_END + KV_SERIALIZE(incoming_connections_count) DOC_DSCR("Number of incoming P2P connections established by other nodes.") DOC_END + KV_SERIALIZE(synchronized_connections_count) DOC_DSCR("Number of P2P connections to nodes that have a fully synchronized blockchain.") DOC_END + KV_SERIALIZE(white_peerlist_size) DOC_DSCR("Size of the white peer list, which includes addresses of reliable nodes.") DOC_END + KV_SERIALIZE(grey_peerlist_size) DOC_DSCR("Size of the grey peer list, which includes addresses of nodes with less consistent availability.") DOC_END + KV_SERIALIZE(current_blocks_median) // TODO + KV_SERIALIZE(alias_count) DOC_DSCR("The total number of unique aliases registered on the blockchain. Aliases are alternate, human-readable names associated with addresses.") DOC_END + KV_SERIALIZE(current_max_allowed_block_size) DOC_DSCR("Current maximum allowed cummulative block size in bytes.") DOC_END + KV_SERIALIZE(is_hardfok_active) DOC_DSCR("A list of boolean values indicating whether each corresponding hardfork is active. For example, a list 'true, true, false' indicates that the first hardfork is activated, while the second is not. Hardfork #0 is always active as it is a stub.") DOC_END + KV_SERIALIZE(daemon_network_state) DOC_DSCR("Current network state of the daemon, which could be connecting, synchronizing, online, loading core, internal error, unloading core, or downloading database.") DOC_END + KV_SERIALIZE(synchronization_start_height) DOC_DSCR("Blockchain height at which the current synchronization process started. Indicates the starting point for catching up to the network's latest state.") DOC_END + KV_SERIALIZE(max_net_seen_height) DOC_DSCR("Maximum blockchain height observed in the network by this node.") DOC_END + KV_SERIALIZE(default_fee) DOC_DSCR("Default fee for transactions.") DOC_END + KV_SERIALIZE(minimum_fee) DOC_DSCR("Minimum fee for transactions.") DOC_END + KV_SERIALIZE(mi) DOC_DSCR("The most recent mainterner's info.") DOC_END + + // Fields dependent on flags for their inclusion + KV_SERIALIZE(net_time_delta_median) DOC_DSCR("A value of 0 indicates no time synchronization issues, while a value of 1 indicates the presence of time sync issues. Only available if the COMMAND_RPC_GET_INFO_FLAG_NET_TIME_DELTA_MEDIAN flag is set.") DOC_END + KV_SERIALIZE(current_network_hashrate_50)DOC_DSCR("The PoW hash rate calculated over the last 50 blocks of any type. This information is only provided if the COMMAND_RPC_GET_INFO_FLAG_CURRENT_NETWORK_HASHRATE_50 flag is set.") DOC_END + KV_SERIALIZE(current_network_hashrate_350) DOC_DSCR("The PoW hash rate calculated over the last 350 blocks of any type. This information is only provided if the COMMAND_RPC_GET_INFO_FLAG_CURRENT_NETWORK_HASHRATE_350 flag is set.") DOC_END + KV_SERIALIZE(seconds_for_10_blocks) DOC_DSCR("The time period in seconds between the most recent block and the 10th block older. This information is only provided if the COMMAND_RPC_GET_INFO_FLAG_SECONDS_FOR_10_BLOCKS flag is set.") DOC_END + KV_SERIALIZE(seconds_for_30_blocks) DOC_DSCR("The time period in seconds between the most recent block and the 30th block older. This information is only provided if the COMMAND_RPC_GET_INFO_FLAG_SECONDS_FOR_30_BLOCKS flag is set.") DOC_END + KV_SERIALIZE(transactions_cnt_per_day) DOC_DSCR("The number of non-mining transactions recorded over the last 24 hours. This information is only provided if the COMMAND_RPC_GET_INFO_FLAG_TRANSACTIONS_DAILY_STAT flag is set.") DOC_END + KV_SERIALIZE(transactions_volume_per_day)DOC_DSCR("The total sum of input amounts from all non-mining transactions over the last 24 hours. Only old bare inputs with explicit amounts are considered. This information is only provided if the COMMAND_RPC_GET_INFO_FLAG_TRANSACTIONS_DAILY_STAT flag is set.") DOC_END + KV_SERIALIZE(last_pos_timestamp) DOC_DSCR("The timestamp of the most recent PoS block. This information is only provided if the COMMAND_RPC_GET_INFO_FLAG_LAST_POS_TIMESTAMP flag is set.") DOC_END + KV_SERIALIZE(last_pow_timestamp) DOC_DSCR("The timestamp of the most recent PoW block. This information is only provided if the COMMAND_RPC_GET_INFO_FLAG_LAST_POW_TIMESTAMP flag is set.") DOC_END + KV_SERIALIZE(total_coins) DOC_DSCR("The total amount of all emitted coins in the system. This information is only provided if the COMMAND_RPC_GET_INFO_FLAG_TOTAL_COINS flag is set.") DOC_END + KV_SERIALIZE(last_block_size) DOC_DSCR("The size of the last block in bytes. This information is only provided if the COMMAND_RPC_GET_INFO_FLAG_LAST_BLOCK_SIZE flag is set.") DOC_END + KV_SERIALIZE(tx_count_in_last_block) DOC_DSCR("The number of non-mining transactions in the last block. This information is only provided if the COMMAND_RPC_GET_INFO_FLAG_TX_COUNT_IN_LAST_BLOCK flag is set.") DOC_END + KV_SERIALIZE(pos_sequence_factor) DOC_DSCR("The current PoS sequence factor, representing the number of consecutive PoS blocks. This information is only provided if the COMMAND_RPC_GET_INFO_FLAG_POS_SEQUENCE_FACTOR flag is set.") DOC_END + KV_SERIALIZE(pow_sequence_factor) DOC_DSCR("The current PoW sequence factor, representing the number of consecutive PoW blocks. This information is only provided if the COMMAND_RPC_GET_INFO_FLAG_POW_SEQUENCE_FACTOR flag is set.") DOC_END + KV_SERIALIZE(block_reward) DOC_DSCR("The base block reward that is effective for the next block. Calculated only if either COMMAND_RPC_GET_INFO_FLAG_POS_DIFFICULTY or COMMAND_RPC_GET_INFO_FLAG_TOTAL_COINS flag is set.") DOC_END + KV_SERIALIZE(last_block_total_reward) DOC_DSCR("Reward for the last block, including base reward and transaction fees. Calculated only if either COMMAND_RPC_GET_INFO_FLAG_POS_DIFFICULTY or COMMAND_RPC_GET_INFO_FLAG_TOTAL_COINS flag is set.") DOC_END + KV_SERIALIZE(pos_diff_total_coins_rate) DOC_DSCR("PoS difficulty divided by the total amount of all coins in the system minus a premined amount (17,517,203). Calculated only if either COMMAND_RPC_GET_INFO_FLAG_POS_DIFFICULTY or COMMAND_RPC_GET_INFO_FLAG_TOTAL_COINS flag is set.") DOC_END + KV_SERIALIZE(last_block_timestamp) DOC_DSCR("Timestamp of the last block. Calculated only if either COMMAND_RPC_GET_INFO_FLAG_POS_DIFFICULTY or COMMAND_RPC_GET_INFO_FLAG_TOTAL_COINS flag is set.") DOC_END + KV_SERIALIZE(last_block_hash) DOC_DSCR("Hash of the last block. Calculated only if either COMMAND_RPC_GET_INFO_FLAG_POS_DIFFICULTY or COMMAND_RPC_GET_INFO_FLAG_TOTAL_COINS flag is set.") DOC_END + KV_SERIALIZE(pos_block_ts_shift_vs_actual) DOC_DSCR("The difference between the timestamp used in the last PoS block for mining purposes and its actual timestamp as stored in the miner's transaction extra data. This information is only provided if the COMMAND_RPC_GET_INFO_FLAG_POS_BLOCK_TS_SHIFT_VS_ACTUAL flag is set.") DOC_END + KV_SERIALIZE(outs_stat) DOC_DSCR("Statistics for the number of outputs that have a specific amount. This information is only provided if the COMMAND_RPC_GET_INFO_FLAG_OUTS_STAT flag is set.") DOC_END + KV_SERIALIZE(performance_data) DOC_DSCR("Detailed technical performance data intended for developers. This information is only provided if the COMMAND_RPC_GET_INFO_FLAG_PERFORMANCE flag is set.") DOC_END + KV_SERIALIZE(tx_pool_performance_data) DOC_DSCR("Detailed technical performance data intended for developers. This information is only provided if the COMMAND_RPC_GET_INFO_FLAG_PERFORMANCE flag is set.") DOC_END + KV_SERIALIZE(offers_count) DOC_DSCR("Current number of offers in the offers service. This information is only provided if the COMMAND_RPC_GET_INFO_FLAG_PERFORMANCE flag is set.") DOC_END + KV_SERIALIZE(expiration_median_timestamp)DOC_DSCR("Median of timestamps of the last N blocks, used to determine the expiration status of transactions. This information is only provided if the COMMAND_RPC_GET_INFO_FLAG_EXPIRATIONS_MEDIAN flag is set.") DOC_END END_KV_SERIALIZE_MAP() }; }; //----------------------------------------------- struct COMMAND_RPC_STOP_MINING { + DOC_COMMAND("Stop PoW mining process on CPU.") + struct request { - BEGIN_KV_SERIALIZE_MAP() END_KV_SERIALIZE_MAP() }; - struct response { std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; + //----------------------------------------------- - // struct COMMAND_RPC_GETBLOCKCOUNT { - typedef std::list request; + DOC_COMMAND("Returns the total number of blocks in the blockchain (the height of the top block plus one)."); + + struct request + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; struct response { @@ -957,39 +1009,45 @@ namespace currency std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(count) - KV_SERIALIZE(status) + KV_SERIALIZE(count) DOC_DSCR("The total number of blocks in the blockchain, equivalent to the top block's height plus one.") DOC_END + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; - }; + //----------------------------------------------- + struct COMMAND_RPC_GETBLOCKHASH { + DOC_COMMAND("Returns block hash by the given height."); + typedef std::vector request; typedef std::string response; }; + //----------------------------------------------- struct COMMAND_RPC_GETBLOCKTEMPLATE { + DOC_COMMAND("Generates a block template for mining, intended for both PoW and PoS types of blocks based on the provided parameters."); + struct request { blobdata explicit_transaction; std::string extra_text; std::string wallet_address; - std::string stakeholder_address; // address for stake return (PoS blocks) - pos_entry pe; // for PoS blocks - bool pos_block; // is pos block + std::string stakeholder_address; // address for stake return (PoS blocks) + pos_entry pe; // for PoS blocks + bool pos_block; // is pos block BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_BLOB_AS_HEX_STRING(explicit_transaction) - KV_SERIALIZE(extra_text) - KV_SERIALIZE(wallet_address) - KV_SERIALIZE(stakeholder_address); - KV_SERIALIZE(pe) - KV_SERIALIZE(pos_block) + KV_SERIALIZE_BLOB_AS_HEX_STRING(explicit_transaction) DOC_DSCR("A transaction blob that must be explicitly included in the block.") DOC_END + KV_SERIALIZE(extra_text) DOC_DSCR("Arbitrary data added to the extra field of the miner transaction.") DOC_END + KV_SERIALIZE(wallet_address) DOC_DSCR("Address where mining rewards will be deposited.") DOC_END + KV_SERIALIZE(stakeholder_address) DOC_DSCR("Address where the stake is returned for PoS blocks (usually the same as 'wallet_address').") DOC_END + KV_SERIALIZE(pe) DOC_DSCR("PoS entry details, relevant only for PoS block generation.") DOC_END + KV_SERIALIZE(pos_block) DOC_DSCR("Flag indicating whether the block is a PoS block.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1007,22 +1065,26 @@ namespace currency std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(difficulty) - KV_SERIALIZE(height) - KV_SERIALIZE_POD_AS_HEX_STRING(seed) - KV_SERIALIZE(blocktemplate_blob) - KV_SERIALIZE(prev_hash) - KV_SERIALIZE(miner_tx_tgc) - KV_SERIALIZE(block_reward_without_fee) - KV_SERIALIZE(block_reward) - KV_SERIALIZE(txs_fee) - KV_SERIALIZE(status) + KV_SERIALIZE(difficulty) DOC_DSCR("The mining difficulty targeted by the block template.") DOC_END + KV_SERIALIZE(height) DOC_DSCR("The height of the block template in the blockchain.") DOC_END + KV_SERIALIZE_POD_AS_HEX_STRING(seed) DOC_DSCR("Seed value for the ProgPoWZ mining algorithm's epoch.") DOC_END + KV_SERIALIZE(blocktemplate_blob) DOC_DSCR("Serialized block template blob.") DOC_END + KV_SERIALIZE(prev_hash) DOC_DSCR("Hash of the previous block in the chain.") DOC_END + KV_SERIALIZE(miner_tx_tgc) DOC_DSCR("Miner transaction generation context. Intended for PoS blocks and Zarcanum.") DOC_END + KV_SERIALIZE(block_reward_without_fee) DOC_DSCR("Base block reward excluding any transaction fees.") DOC_END + KV_SERIALIZE(block_reward) DOC_DSCR("Total block reward, including transaction fees if they are given to the miner (legacy), or the base reward if fees are burnt (current state).") DOC_END + KV_SERIALIZE(txs_fee) DOC_DSCR("Total fees from transactions included in the block.") DOC_END + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; + //----------------------------------------------- + struct COMMAND_RPC_SUBMITBLOCK { + DOC_COMMAND("Adds new block to the blockchain. Request should contain one string with hex-encoded block blob."); + typedef std::vector request; struct response @@ -1030,21 +1092,25 @@ namespace currency std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; + //----------------------------------------------- + struct COMMAND_RPC_SUBMITBLOCK2 { + DOC_COMMAND("Adds new block to the blockchain."); + struct request { std::string b; //hex encoded block blob std::list explicit_txs; //hex encoded tx blobs BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_BLOB_AS_HEX_STRING(b) - KV_SERIALIZE(explicit_txs) + KV_SERIALIZE_BLOB_AS_HEX_STRING(b) DOC_DSCR("Hex-encoded serialized block.") DOC_END + KV_SERIALIZE(explicit_txs) DOC_DSCR("List of hex-encoded transactions to be explicitly included in the block.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1053,11 +1119,13 @@ namespace currency std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; + //----------------------------------------------- + struct block_header_response { uint8_t major_version; @@ -1073,23 +1141,24 @@ namespace currency uint64_t reward; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(major_version) - KV_SERIALIZE(minor_version) - KV_SERIALIZE(timestamp) - KV_SERIALIZE(prev_hash) - KV_SERIALIZE(nonce) - KV_SERIALIZE(orphan_status) - KV_SERIALIZE(height) - KV_SERIALIZE(depth) - KV_SERIALIZE(hash) - KV_SERIALIZE(difficulty) - KV_SERIALIZE(reward) + KV_SERIALIZE(major_version) DOC_DSCR("Major version of the block.") DOC_END + KV_SERIALIZE(minor_version) DOC_DSCR("Minor version of the block.") DOC_END + KV_SERIALIZE(timestamp) DOC_DSCR("Timestamp of the block creation.") DOC_END + KV_SERIALIZE(prev_hash) DOC_DSCR("Hash of the previous block in the chain.") DOC_END + KV_SERIALIZE(nonce) DOC_DSCR("Nonce used for generating the block to meet the network difficulty.") DOC_END + KV_SERIALIZE(orphan_status) DOC_DSCR("Indicates if the block is an orphan (true) or a normal block (false).") DOC_END + KV_SERIALIZE(height) DOC_DSCR("Height of the block in the blockchain.") DOC_END + KV_SERIALIZE(depth) DOC_DSCR("Depth of the block in the blockchain. Depth 0 indicates the most recent block.") DOC_END + KV_SERIALIZE(hash) DOC_DSCR("Hash of the block.") DOC_END + KV_SERIALIZE(difficulty) DOC_DSCR("Network difficulty target that the block met.") DOC_END + KV_SERIALIZE(reward) DOC_DSCR("Total mining reward of the block including transaction fees (if applicable).") DOC_END END_KV_SERIALIZE_MAP() }; struct COMMAND_RPC_GET_LAST_BLOCK_HEADER { - typedef std::list request; + DOC_COMMAND("Returns the block header information of the most recent block."); + typedef std::list request; // TODO @#@# fix this struct response { @@ -1098,20 +1167,24 @@ namespace currency BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(block_header) - KV_SERIALIZE(status) + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; + //----------------------------------------------- + struct COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH { + DOC_COMMAND("Retrieves the block header information for a given block hash."); + struct request { std::string hash; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(hash) + KV_SERIALIZE(hash) DOC_DSCR("The hash of the block for which the header information is being requested.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1121,21 +1194,24 @@ namespace currency block_header_response block_header; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(block_header) - KV_SERIALIZE(status) + KV_SERIALIZE(block_header) DOC_DSCR("Detailed header information of the block.") DOC_END + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; - }; + //----------------------------------------------- + struct COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT { + DOC_COMMAND("Retrieves the block header information for a given block height."); + struct request { uint64_t height; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(height) + KV_SERIALIZE(height) DOC_DSCR("The height of the block for which the header information is being requested.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1145,20 +1221,23 @@ namespace currency block_header_response block_header; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(block_header) - KV_SERIALIZE(status) + KV_SERIALIZE(block_header) DOC_DSCR("Detailed header information of the block.") DOC_END + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; - }; + //----------------------------------------------- + struct COMMAND_RPC_GET_ALIAS_DETAILS { + DOC_COMMAND("Retrieves information about a specific address alias."); + struct request { std::string alias; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(alias) + KV_SERIALIZE(alias) DOC_DSCR("The alias name for which details are being requested.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1168,19 +1247,23 @@ namespace currency std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(alias_details) - KV_SERIALIZE(status) + KV_SERIALIZE(alias_details) DOC_DSCR("Contains the detailed information about the specified alias, including the associated wallet address, tracking key, comment etc..") DOC_END + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; + //----------------------------------------------- + struct COMMAND_RPC_GET_ALIAS_REWARD { + DOC_COMMAND("Retrieves the cost of registering an alias on the blockchain."); + struct request { std::string alias; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(alias) + KV_SERIALIZE(alias) DOC_DSCR("The alias name for which the registration cost is being queried.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1190,15 +1273,18 @@ namespace currency std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(reward) - KV_SERIALIZE(status) + KV_SERIALIZE(reward) DOC_DSCR("The registration cost for the specified alias.") DOC_END + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; + //----------------------------------------------- struct COMMAND_RPC_GET_ALL_ALIASES { + DOC_COMMAND("Retrieves all registered aliases along with associated information."); + struct request { BEGIN_KV_SERIALIZE_MAP() @@ -1211,22 +1297,26 @@ namespace currency std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(aliases) - KV_SERIALIZE(status) + KV_SERIALIZE(aliases) DOC_DSCR("List of alias_rpc_details objects, each containing information about an individual alias.") DOC_END + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; + //----------------------------------------------- + struct COMMAND_RPC_GET_ALIASES { + DOC_COMMAND("Retrieves a specified portion of all registered aliases, allowing pagination through large sets of aliases."); + struct request { - uint64_t offset; - uint64_t count; + uint64_t offset; // The starting point from which aliases are to be retrieved. + uint64_t count; // The number of aliases to retrieve. BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(offset) - KV_SERIALIZE(count) + KV_SERIALIZE(offset) DOC_DSCR("The offset in the list of all aliases from which to start retrieving.") DOC_END + KV_SERIALIZE(count) DOC_DSCR("The number of aliases to retrieve from the specified offset.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1236,33 +1326,37 @@ namespace currency std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(aliases) - KV_SERIALIZE(status) + KV_SERIALIZE(aliases) DOC_DSCR("List of alias_rpc_details objects, each containing information about an individual alias retrieved based on the request parameters.") DOC_END + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; + //----------------------------------------------- + struct COMMAND_RPC_GET_ALIASES_BY_ADDRESS { + DOC_COMMAND("Retrieves all aliases registered for a given address."); typedef std::string request; struct response { - //std::string alias; std::vector alias_info_list; std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(alias_info_list) - KV_SERIALIZE(status) + KV_SERIALIZE(alias_info_list) DOC_DSCR("List of alias_rpc_details objects, each containing detailed information about each alias registered to the specified address.") DOC_END + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; + //----------------------------------------------- struct COMMAND_RPC_RESET_TX_POOL { + DOC_COMMAND("Clears transaction pool."); struct request { @@ -1275,20 +1369,23 @@ namespace currency std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; + //----------------------------------------------- + struct COMMAND_RPC_REMOVE_TX_FROM_POOL { + DOC_COMMAND("Removes specified transactions from the transaction pool, typically to clear out transactions that are no longer valid or needed."); struct request { std::list tx_to_remove; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(tx_to_remove) + KV_SERIALIZE(tx_to_remove) DOC_DSCR("List of transaction IDs that are to be removed from the transaction pool.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1297,13 +1394,17 @@ namespace currency std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; + //----------------------------------------------- + struct COMMAND_RPC_GET_POS_MINING_DETAILS - { + { + DOC_COMMAND("Retrieves basic information regarding PoS mining, including current PoS conditions and constraints."); + struct request { BEGIN_KV_SERIALIZE_MAP() @@ -1321,17 +1422,19 @@ namespace currency bool pos_sequence_factor_is_good; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_VAL_POD_AS_BLOB(sm) - KV_SERIALIZE(pos_basic_difficulty) - KV_SERIALIZE(starter_timestamp) - KV_SERIALIZE(pos_mining_allowed) - KV_SERIALIZE(pos_sequence_factor_is_good) - KV_SERIALIZE(status) - KV_SERIALIZE_VAL_POD_AS_BLOB(last_block_hash) + KV_SERIALIZE_VAL_POD_AS_BLOB(sm) //DOC_DSCR("Stake modifier object used in PoS mining calculations.") DOC_END + KV_SERIALIZE(pos_basic_difficulty) DOC_DSCR("Current PoS difficulty.") DOC_END + KV_SERIALIZE(starter_timestamp) DOC_DSCR("Timestamp from which timestamps are evaluated for meeting PoS win condition.") DOC_END + KV_SERIALIZE(pos_mining_allowed) DOC_DSCR("Indicates whether PoS mining is currently allowed, which may be restricted under certain blockchain conditions or in testnets.") DOC_END + KV_SERIALIZE(pos_sequence_factor_is_good) DOC_DSCR("Indicates whether the PoS sequence factor is at a level that allows for continued PoS mining, requiring a PoW block to reset if too high.") DOC_END + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END + KV_SERIALIZE_VAL_POD_AS_BLOB(last_block_hash) //DOC_DSCR("Hash of the most recent block in the blockchain.") DOC_END END_KV_SERIALIZE_MAP() }; }; + //----------------------------------------------- + struct tx_out_rpc_entry { uint64_t amount; @@ -1340,11 +1443,11 @@ namespace currency bool is_spent; uint64_t global_index; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(amount) - KV_SERIALIZE(pub_keys) - KV_SERIALIZE(minimum_sigs) - KV_SERIALIZE(is_spent) - KV_SERIALIZE(global_index) + KV_SERIALIZE(amount) DOC_DSCR("The output's amount, 0 for ZC outputs.") DOC_END + KV_SERIALIZE(pub_keys) DOC_DSCR("List of public keys associated with the output.") DOC_END + KV_SERIALIZE(minimum_sigs) DOC_DSCR("Minimum number of signatures required to spend the output, for multisig outputs only.") DOC_END + KV_SERIALIZE(is_spent) DOC_DSCR("Indicates whether the output has been spent.") DOC_END + KV_SERIALIZE(global_index) DOC_DSCR("Global index of the output for this specific amount.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1357,12 +1460,12 @@ namespace currency std::vector global_indexes; std::vector etc_options; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(amount) - KV_SERIALIZE(htlc_origin) - KV_SERIALIZE(kimage_or_ms_id) - KV_SERIALIZE(global_indexes) - KV_SERIALIZE(multisig_count) - KV_SERIALIZE(etc_options) + KV_SERIALIZE(amount) DOC_DSCR("The amount of coins being transacted.") DOC_END + KV_SERIALIZE(htlc_origin) DOC_DSCR("Origin hash for HTLC (Hash Time Locked Contract).") DOC_END + KV_SERIALIZE(kimage_or_ms_id) DOC_DSCR("Contains either the key image for the input or the multisig output ID, depending on the input type.") DOC_END + KV_SERIALIZE(global_indexes) DOC_DSCR("List of global indexes indicating the outputs referenced by this input, where only one is actually being spent.") DOC_END + KV_SERIALIZE(multisig_count) DOC_DSCR("Number of multisig signatures used, relevant only for multisig outputs.") DOC_END + KV_SERIALIZE(etc_options) DOC_DSCR("Auxiliary options associated with the input, containing additional configuration or data.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1372,9 +1475,9 @@ namespace currency std::string short_view; std::string details_view; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(type) - KV_SERIALIZE(short_view) - KV_SERIALIZE(details_view) + KV_SERIALIZE(type) DOC_DSCR("Type of the extra entry in the transaction.") DOC_END + KV_SERIALIZE(short_view) DOC_DSCR("A concise representation of the extra entry.") DOC_END + KV_SERIALIZE(details_view) DOC_DSCR("A detailed representation of the extra entry.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1396,19 +1499,19 @@ namespace currency std::string object_in_json; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_BLOB_AS_BASE64_STRING(blob) - KV_SERIALIZE(blob_size) - KV_SERIALIZE(timestamp) - KV_SERIALIZE(keeper_block) - KV_SERIALIZE(fee) - KV_SERIALIZE(amount) - KV_SERIALIZE(id) - KV_SERIALIZE(pub_key) - KV_SERIALIZE(outs) - KV_SERIALIZE(ins) - KV_SERIALIZE(extra) - KV_SERIALIZE(attachments) - KV_SERIALIZE_BLOB_AS_BASE64_STRING(object_in_json) + KV_SERIALIZE_BLOB_AS_BASE64_STRING(blob) DOC_DSCR("Serialized form of the transaction, encoded in Base64.") DOC_END + KV_SERIALIZE(blob_size) DOC_DSCR("Size of the serialized transaction in bytes.") DOC_END + KV_SERIALIZE(timestamp) DOC_DSCR("Timestamp when the transaction was created.") DOC_END + KV_SERIALIZE(keeper_block) DOC_DSCR("Block height where the transaction is confirmed, or -1 if it is unconfirmed.") DOC_END + KV_SERIALIZE(fee) DOC_DSCR("Transaction fee in the smallest currency unit.") DOC_END + KV_SERIALIZE(amount) DOC_DSCR("Total output amount of the transaction (legacy, for pre-Zarcanum txs).") DOC_END + KV_SERIALIZE(id) DOC_DSCR("Hash of the transaction.") DOC_END + KV_SERIALIZE(pub_key) DOC_DSCR("Public key associated with the transaction.") DOC_END + KV_SERIALIZE(outs) DOC_DSCR("Outputs of the transaction.") DOC_END + KV_SERIALIZE(ins) DOC_DSCR("Inputs of the transaction.") DOC_END + KV_SERIALIZE(extra) DOC_DSCR("Extra data associated with the transaction.") DOC_END + KV_SERIALIZE(attachments) DOC_DSCR("Additional attachments to the transaction.") DOC_END + KV_SERIALIZE_BLOB_AS_BASE64_STRING(object_in_json) DOC_DSCR("Serialized transaction represented in JSON, encoded in Base64.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1420,10 +1523,10 @@ namespace currency uint64_t sz; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(id) - KV_SERIALIZE(fee) - KV_SERIALIZE(total_amount) - KV_SERIALIZE(sz) + KV_SERIALIZE(id) DOC_DSCR("Hash of the transaction.") DOC_END + KV_SERIALIZE(fee) DOC_DSCR("Transaction fee in the smallest currency unit.") DOC_END + KV_SERIALIZE(total_amount) DOC_DSCR("Total amount transferred in the transaction (legacy, for pre-Zarcanum txs).") DOC_END + KV_SERIALIZE(sz) DOC_DSCR("Size of the transaction in bytes.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1454,41 +1557,43 @@ namespace currency std::list transactions_details; std::string miner_text_info; std::string object_in_json; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(blob) - KV_SERIALIZE(height) - KV_SERIALIZE(timestamp) - KV_SERIALIZE(actual_timestamp) - KV_SERIALIZE(block_cumulative_size) - KV_SERIALIZE(total_txs_size) - KV_SERIALIZE(block_tself_size) - KV_SERIALIZE(base_reward) - KV_SERIALIZE(summary_reward) - KV_SERIALIZE(total_fee) - KV_SERIALIZE(penalty) - KV_SERIALIZE(id) - KV_SERIALIZE(prev_id) - KV_SERIALIZE(pow_seed) - KV_SERIALIZE(cumulative_diff_adjusted) - KV_SERIALIZE(cumulative_diff_precise) - KV_SERIALIZE(difficulty) - KV_SERIALIZE(already_generated_coins) - KV_SERIALIZE(this_block_fee_median) - KV_SERIALIZE(effective_fee_median) - KV_SERIALIZE(transactions_details) - KV_SERIALIZE(type) - KV_SERIALIZE(is_orphan) - KV_SERIALIZE(miner_text_info) - KV_SERIALIZE(object_in_json) + KV_SERIALIZE(blob) DOC_DSCR("Serialized form of the block.") DOC_END + KV_SERIALIZE(height) DOC_DSCR("Height of the block in the blockchain.") DOC_END + KV_SERIALIZE(timestamp) DOC_DSCR("Timestamp when the block was created, in PoS blocks used for mining.") DOC_END + KV_SERIALIZE(actual_timestamp) DOC_DSCR("Actual timestamp encoded in the block's extra data for PoS blocks.") DOC_END + KV_SERIALIZE(block_cumulative_size) DOC_DSCR("Cumulative size of the block including all transactions.") DOC_END + KV_SERIALIZE(total_txs_size) DOC_DSCR("Total size of all transactions included in the block.") DOC_END + KV_SERIALIZE(block_tself_size) // TODO ? + KV_SERIALIZE(base_reward) DOC_DSCR("Base mining reward for the block.") DOC_END + KV_SERIALIZE(summary_reward) DOC_DSCR("Total reward for the block, including base reward and transaction fees (legacy).") DOC_END + KV_SERIALIZE(total_fee) DOC_DSCR("Total transaction fees included in the block.") DOC_END + KV_SERIALIZE(penalty) DOC_DSCR("Penalty applied to the reward if the block is larger than median but not large enough to be rejected.") DOC_END + KV_SERIALIZE(id) DOC_DSCR("Unique identifier of the block.") DOC_END + KV_SERIALIZE(prev_id) DOC_DSCR("Hash of the previous block in the chain.") DOC_END + KV_SERIALIZE(pow_seed) // TODO + KV_SERIALIZE(cumulative_diff_adjusted) DOC_DSCR("Adjusted cumulative difficulty of the blockchain up to this block.") DOC_END + KV_SERIALIZE(cumulative_diff_precise) DOC_DSCR("Precise cumulative difficulty of the blockchain up to this block.") DOC_END + KV_SERIALIZE(difficulty) DOC_DSCR("Mining difficulty of the block.") DOC_END + KV_SERIALIZE(already_generated_coins) DOC_DSCR("Total amount of coins generated in the blockchain up to this block.") DOC_END + KV_SERIALIZE(this_block_fee_median) DOC_DSCR("Median transaction fee of the transactions within this block.") DOC_END + KV_SERIALIZE(effective_fee_median) // TODO + KV_SERIALIZE(transactions_details) DOC_DSCR("Detailed information about each transaction included in the block.") DOC_END + KV_SERIALIZE(type) DOC_DSCR("Type of the block.") DOC_END + KV_SERIALIZE(is_orphan) DOC_DSCR("Indicates whether the block is an orphan.") DOC_END + KV_SERIALIZE(miner_text_info) DOC_DSCR("Additional textual information provided by the miner of the block.") DOC_END + KV_SERIALIZE(object_in_json) DOC_DSCR("Serialized representation of the block in JSON format.") DOC_END END_KV_SERIALIZE_MAP() }; - + //----------------------------------------------- + struct COMMAND_RPC_GET_BLOCKS_DETAILS { + DOC_COMMAND("Retrieves detailed information about a sequence of blocks starting from a specific height."); + struct request { uint64_t height_start; @@ -1496,9 +1601,9 @@ namespace currency bool ignore_transactions; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(height_start) - KV_SERIALIZE(count) - KV_SERIALIZE(ignore_transactions) + KV_SERIALIZE(height_start) DOC_DSCR("The starting block height from which block details are retrieved.") DOC_END + KV_SERIALIZE(count) DOC_DSCR("The number of blocks to retrieve from the starting height.") DOC_END + KV_SERIALIZE(ignore_transactions) // TODO END_KV_SERIALIZE_MAP() }; @@ -1508,22 +1613,26 @@ namespace currency std::list blocks; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) - KV_SERIALIZE(blocks) + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END + KV_SERIALIZE(blocks) DOC_DSCR("List of blocks with detailed information, starting from the specified height.") DOC_END END_KV_SERIALIZE_MAP() }; }; + //----------------------------------------------- + struct COMMAND_RPC_GET_ALT_BLOCKS_DETAILS { + DOC_COMMAND("Retrieves details of alternative blocks in the blockchain, allowing for pagination through large datasets."); + struct request { uint64_t offset; uint64_t count; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(offset) - KV_SERIALIZE(count) + KV_SERIALIZE(offset) DOC_DSCR("The offset in the list of alternative blocks from which to start retrieval.") DOC_END + KV_SERIALIZE(count) DOC_DSCR("The number of alternative blocks to retrieve from the specified offset.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1533,21 +1642,24 @@ namespace currency std::vector blocks; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) - KV_SERIALIZE(blocks) + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END + KV_SERIALIZE(blocks) DOC_DSCR("List of alternative blocks with detailed information, retrieved based on the specified parameters.") DOC_END END_KV_SERIALIZE_MAP() }; }; + //----------------------------------------------- struct COMMAND_RPC_GET_BLOCK_DETAILS { + DOC_COMMAND("Retrieves detailed information about a specific block identified by its hash."); + struct request { crypto::hash id; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_POD_AS_HEX_STRING(id) + KV_SERIALIZE_POD_AS_HEX_STRING(id) DOC_DSCR("The hash ID of the block for which detailed information is being requested.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1557,21 +1669,24 @@ namespace currency block_rpc_extended_info block_details; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) - KV_SERIALIZE(block_details) + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END + KV_SERIALIZE(block_details) DOC_DSCR("Detailed information about the block retrieved based on the provided hash ID.") DOC_END END_KV_SERIALIZE_MAP() }; }; + //----------------------------------------------- struct COMMAND_RPC_GET_POOL_TXS_DETAILS { + DOC_COMMAND("Retrieves detailed information about specific transactions in the transaction pool, identified by their IDs."); + struct request { std::list ids; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(ids) + KV_SERIALIZE(ids) DOC_DSCR("List of transaction IDs.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1581,21 +1696,24 @@ namespace currency std::list txs; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) - KV_SERIALIZE(txs) + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END + KV_SERIALIZE(txs) DOC_DSCR("List of transactions with detailed information.") DOC_END END_KV_SERIALIZE_MAP() }; }; + //----------------------------------------------- struct COMMAND_RPC_GET_POOL_TXS_BRIEF_DETAILS { + DOC_COMMAND("Retrieves brief details about specific transactions in the transaction pool, identified by their IDs."); + struct request { std::list ids; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(ids) + KV_SERIALIZE(ids) DOC_DSCR("List of transaction IDs.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1605,14 +1723,18 @@ namespace currency std::list txs; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) - KV_SERIALIZE(txs) + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END + KV_SERIALIZE(txs) DOC_DSCR("List of transactions with detailed information.") DOC_END END_KV_SERIALIZE_MAP() }; }; + //----------------------------------------------- + struct COMMAND_RPC_GET_ALL_POOL_TX_LIST { + DOC_COMMAND("Retrieves a list of all transaction IDs currently in the transaction pool."); + struct request { BEGIN_KV_SERIALIZE_MAP() @@ -1625,13 +1747,15 @@ namespace currency std::list ids; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) - KV_SERIALIZE(ids) + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END + KV_SERIALIZE(ids) DOC_DSCR("List of all transaction IDs currently in the transaction pool.") DOC_END END_KV_SERIALIZE_MAP() }; }; + //----------------------------------------------- + // TODO looks like it is never used, a typo? struct COMMAND_RPC_GET_GLOBAL_INDEX_INFO { struct request @@ -1659,14 +1783,18 @@ namespace currency }; }; + //----------------------------------------------- + struct COMMAND_RPC_GET_TX_DETAILS { + DOC_COMMAND("Retrieves detailed information about a specific transaction."); + struct request { std::string tx_hash; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(tx_hash) + KV_SERIALIZE(tx_hash) DOC_DSCR("The hash of the transaction for which detailed information is being requested.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1676,12 +1804,13 @@ namespace currency tx_rpc_extended_info tx_info; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) - KV_SERIALIZE(tx_info) + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END + KV_SERIALIZE(tx_info) DOC_DSCR("Detailed information about the transaction.") DOC_END END_KV_SERIALIZE_MAP() }; }; + //----------------------------------------------- struct search_entry { @@ -1690,12 +1819,14 @@ namespace currency struct COMMAND_RPC_SERARCH_BY_ID { + DOC_COMMAND("Searches for a given ID across various entity types such as blocks, transactions, key images, multisig outputs, and alternative blocks, useful when the entity type is unknown or unspecified."); + struct request { std::string id; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(id) + KV_SERIALIZE(id) DOC_DSCR("The identifier used to search across various types of entities.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1705,12 +1836,13 @@ namespace currency std::list types_found; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) - KV_SERIALIZE(types_found) + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END + KV_SERIALIZE(types_found) DOC_DSCR("List of entity types where the identifier was found.") DOC_END END_KV_SERIALIZE_MAP() }; }; + //----------------------------------------------- struct COMMAND_RPC_GET_OFFERS_EX { @@ -1720,7 +1852,7 @@ namespace currency { bc_services::core_offers_filter filter; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(filter) DOC_DSCR("Filter options.") DOC_END + KV_SERIALIZE(filter) DOC_DSCR("Filter options.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -1731,15 +1863,19 @@ namespace currency uint64_t total_offers; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) DOC_DSCR("Status of the operation") DOC_EXMP("OK") DOC_END - KV_SERIALIZE(offers) DOC_DSCR("List of offers related to the operation") DOC_EXMP_AUTO(1) DOC_END - KV_SERIALIZE(total_offers) DOC_DSCR("Total number of offers") DOC_EXMP(1) DOC_END + KV_SERIALIZE(status) DOC_DSCR("Status of the operation.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END + KV_SERIALIZE(offers) DOC_DSCR("List of offers related to the operation.") DOC_EXMP_AUTO(1) DOC_END + KV_SERIALIZE(total_offers) DOC_DSCR("Total number of offers.") DOC_EXMP(1) DOC_END END_KV_SERIALIZE_MAP() }; }; + //----------------------------------------------- + struct COMMAND_RPC_GET_CURRENT_CORE_TX_EXPIRATION_MEDIAN { + DOC_COMMAND("Retrieves the current core transaction expiration median."); + struct request { BEGIN_KV_SERIALIZE_MAP() @@ -1752,15 +1888,18 @@ namespace currency uint64_t expiration_median; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) - KV_SERIALIZE(expiration_median) + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END + KV_SERIALIZE(expiration_median) DOC_DSCR("The median timestamp from the last N blocks, used to determine if transactions are expired based on their timestamp.") DOC_END END_KV_SERIALIZE_MAP() }; }; + //----------------------------------------------- struct COMMAND_VALIDATE_SIGNATURE { + DOC_COMMAND("Validates a Schnorr signature for arbitrary data. The public key for verification is provided directly or retrieved using an associated alias."); + struct request { std::string buff; //base64 encoded data @@ -1769,23 +1908,24 @@ namespace currency std::string alias; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(buff) - KV_SERIALIZE_POD_AS_HEX_STRING(sig) - KV_SERIALIZE_POD_AS_HEX_STRING(pkey) - KV_SERIALIZE(alias) + KV_SERIALIZE(buff) DOC_DSCR("Base64 encoded data for which the signature is to be validated.") DOC_END + KV_SERIALIZE_POD_AS_HEX_STRING(sig) DOC_DSCR("Schnorr signature to validate, encoded as a hexadecimal string.") DOC_END + KV_SERIALIZE_POD_AS_HEX_STRING(pkey) DOC_DSCR("Public key used for signature verification, encoded as a hexadecimal string. If null or not set, the public key is retrieved using the provided alias.") DOC_END + KV_SERIALIZE(alias) DOC_DSCR("Alias to retrieve the associated public spend key if no explicit public key is provided for verification.") DOC_END END_KV_SERIALIZE_MAP() }; - struct response { std::string status; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) + KV_SERIALIZE(status) DOC_DSCR("Status of the call.") DOC_EXMP(API_RETURN_CODE_OK) DOC_END END_KV_SERIALIZE_MAP() }; }; + //----------------------------------------------- + struct void_struct { BEGIN_KV_SERIALIZE_MAP() diff --git a/tests/core_tests/multisig_wallet_tests.cpp b/tests/core_tests/multisig_wallet_tests.cpp index 4fdbcc7f..2801b1fc 100644 --- a/tests/core_tests/multisig_wallet_tests.cpp +++ b/tests/core_tests/multisig_wallet_tests.cpp @@ -23,7 +23,7 @@ using namespace currency; #define TMP_LOG_RESTORE #endif -void exception_handler(){} +static void exception_handler(){} //============================================================================================================================== // helper routine: creates multisig-spending tx using a wallet and keys of other ms-participants, then sends it to the core proxy From 63dadb37c637ba38b4d5a9d83e8e2009777d38e8 Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 22 Apr 2024 01:25:28 +0200 Subject: [PATCH 148/184] compilation fix for blockchain_storage::get_assets() --- src/currency_core/blockchain_storage.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index ef050958..677f6d58 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -3813,7 +3813,8 @@ bool blockchain_storage::get_asset_info(const crypto::public_key& asset_id, asse uint64_t blockchain_storage::get_assets(uint64_t offset, uint64_t count, std::list& assets) const { CRITICAL_REGION_LOCAL(m_read_lock); - m_db_assets.enumerate_items([&](uint64_t i, const crypto::public_key& asset_id, const std::list& asset_descriptor_history) + assets.clear(); + m_db_assets.enumerate_items([&](uint64_t i, const crypto::public_key& asset_id, const std::list& asset_descriptor_history) { if (i < offset) { @@ -3822,7 +3823,7 @@ uint64_t blockchain_storage::get_assets(uint64_t offset, uint64_t count, std::li CHECK_AND_ASSERT_THROW_MES(asset_descriptor_history.size(), "asset_descriptor_history unexpectedly have 0 size"); assets.push_back(asset_descriptor_with_id()); - static_cast(assets.back()) = asset_descriptor_history.back(); + static_cast(assets.back()) = asset_descriptor_history.back().descriptor; assets.back().asset_id = asset_id; if (i + count > offset) { @@ -3830,6 +3831,7 @@ uint64_t blockchain_storage::get_assets(uint64_t offset, uint64_t count, std::li } return true; }); + return assets.size(); } //------------------------------------------------------------------ uint64_t blockchain_storage::get_assets_count() const From 08a753b4c93186b16d5a966ff3f28c831fcf7c97 Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 22 Apr 2024 16:30:42 +0200 Subject: [PATCH 149/184] ui update --- src/gui/qt-daemon/layout | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/qt-daemon/layout b/src/gui/qt-daemon/layout index 155dd4c9..585ffce6 160000 --- a/src/gui/qt-daemon/layout +++ b/src/gui/qt-daemon/layout @@ -1 +1 @@ -Subproject commit 155dd4c96525a915353261110662a831efe7685a +Subproject commit 585ffce64de124a8b503c89c33939666d2bfc1ab From 47dfdf1e0bd87dce029a992436b55cc7beee94ec Mon Sep 17 00:00:00 2001 From: zano build machine Date: Mon, 22 Apr 2024 17:31:56 +0300 Subject: [PATCH 150/184] === build number: 301 -> 302 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index ef17d768..8a121a4f 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 301 +#define PROJECT_VERSION_BUILD_NO 302 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From b102d0d3b9e2dc350a4bc80089e788fc37b9ab0b Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Mon, 22 Apr 2024 18:47:59 +0400 Subject: [PATCH 151/184] fixed command line to common style --- src/common/command_line.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/command_line.cpp b/src/common/command_line.cpp index a596dfd9..ae22e874 100644 --- a/src/common/command_line.cpp +++ b/src/common/command_line.cpp @@ -25,7 +25,7 @@ namespace command_line const arg_descriptor arg_console ( "no-console", "Disable daemon console commands" ); const arg_descriptor arg_show_details ( "currency-details", "Display currency details" ); - const arg_descriptor arg_generate_rpc_autodoc ( "generate_rpc_autodoc", "Make auto-generated RPC API documentation documents at the given path" ); + const arg_descriptor arg_generate_rpc_autodoc ( "generate-rpc-autodoc", "Make auto-generated RPC API documentation documents at the given path" ); const arg_descriptor arg_disable_upnp ( "disable-upnp", "Disable UPnP (enhances local network privacy)"); const arg_descriptor arg_disable_ntp ( "disable-ntp", "Disable NTP, could enhance to time synchronization issue but increase network privacy, consider using disable-stop-if-time-out-of-sync with it"); From 15e653a8aec8a84c8af02b3e4d8680705db67820 Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 22 Apr 2024 17:45:10 +0200 Subject: [PATCH 152/184] minor refactoring: get_base_block_reward() now requires only block height (for clarity) --- src/currency_core/blockchain_storage.cpp | 2 +- src/currency_core/currency_format_utils.cpp | 15 ++++++++++++--- src/currency_core/currency_format_utils.h | 2 +- src/rpc/core_rpc_server.cpp | 2 +- tests/core_tests/block_reward.cpp | 4 ++-- tests/core_tests/chaingen.cpp | 2 +- 6 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 677f6d58..58249f3a 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -6533,7 +6533,7 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt } boost::multiprecision::uint128_t already_generated_coins = m_db_blocks.size() ? m_db_blocks.back()->already_generated_coins:0; - uint64_t base_reward = get_base_block_reward(is_pos_bl, already_generated_coins, height); + uint64_t base_reward = get_base_block_reward(height); if (!m_is_in_checkpoint_zone) { diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 20d43d9f..e19697a8 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -4057,7 +4057,7 @@ namespace currency pei_rpc.miner_text_info = eud.buff; } - pei_rpc.base_reward = get_base_block_reward(is_pos_block(bei_chain.bl), bei_chain.already_generated_coins, bei_chain.height); + pei_rpc.base_reward = get_base_block_reward(bei_chain.height); pei_rpc.summary_reward = get_reward_from_miner_tx(bei_chain.bl.miner_tx); pei_rpc.penalty = (pei_rpc.base_reward + pei_rpc.total_fee) - pei_rpc.summary_reward; return true; @@ -4110,7 +4110,7 @@ namespace currency return CURRENCY_MAX_BLOCK_SIZE; } //----------------------------------------------------------------------------------------------- - uint64_t get_base_block_reward(bool is_pos, const boost::multiprecision::uint128_t& already_generated_coins, uint64_t height) + uint64_t get_base_block_reward(uint64_t height) { if (!height) return PREMINE_AMOUNT; @@ -4118,9 +4118,18 @@ namespace currency return CURRENCY_BLOCK_REWARD; } //----------------------------------------------------------------------------------------------- + // Modern version, requires only necessary arguments. Returns 0 if block is too big (current_block_size > 2 * median_block_size) + uint64_t get_block_reward(uint64_t height, size_t median_block_size, size_t current_block_size) + { + uint64_t reward = 0; + get_block_reward(/* is_pos - doesn't matter */ false, median_block_size, current_block_size, /* boost::multiprecision::uint128_t -- doesn't matter*/ boost::multiprecision::uint128_t(0), reward, height); + return reward; + } + //----------------------------------------------------------------------------------------------- + // legacy version, some arguments are unnecessary now bool get_block_reward(bool is_pos, size_t median_size, size_t current_block_size, const boost::multiprecision::uint128_t& already_generated_coins, uint64_t &reward, uint64_t height) { - uint64_t base_reward = get_base_block_reward(is_pos, already_generated_coins, height); + uint64_t base_reward = get_base_block_reward(height); //make it soft if (median_size < CURRENCY_BLOCK_GRANTED_FULL_REWARD_ZONE) diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index bde3840d..7b769e6a 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -523,7 +523,7 @@ namespace currency size_t get_max_block_size(); size_t get_max_tx_size(); bool get_block_reward(bool is_pos, size_t median_size, size_t current_block_size, const boost::multiprecision::uint128_t& already_generated_coins, uint64_t &reward, uint64_t height); - uint64_t get_base_block_reward(bool is_pos, const boost::multiprecision::uint128_t& already_generated_coins, uint64_t height); + uint64_t get_base_block_reward(uint64_t height); bool is_payment_id_size_ok(const payment_id_t& payment_id); std::string get_account_address_as_str(const account_public_address& addr); std::string get_account_address_and_payment_id_as_str(const account_public_address& addr, const payment_id_t& payment_id); diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index f4bb2aff..371d0a81 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -176,7 +176,7 @@ namespace currency res.pow_sequence_factor = m_core.get_blockchain_storage().get_current_sequence_factor(false); if (req.flags&(COMMAND_RPC_GET_INFO_FLAG_POS_DIFFICULTY | COMMAND_RPC_GET_INFO_FLAG_TOTAL_COINS)) { - res.block_reward = currency::get_base_block_reward(true, total_coins, res.height); + res.block_reward = currency::get_base_block_reward(res.height); currency::block b = AUTO_VAL_INIT(b); m_core.get_blockchain_storage().get_top_block(b); res.last_block_total_reward = currency::get_reward_from_miner_tx(b.miner_tx); diff --git a/tests/core_tests/block_reward.cpp b/tests/core_tests/block_reward.cpp index e9ec72c1..f4672ff1 100644 --- a/tests/core_tests/block_reward.cpp +++ b/tests/core_tests/block_reward.cpp @@ -69,8 +69,8 @@ bool block_template_against_txs_size::c1(currency::core& c, size_t ev_index, con uint64_t top_block_height = bcs.get_top_block_height(); uint64_t blocksize_limit = bcs.get_current_comulative_blocksize_limit(); - uint64_t base_block_reward_pow = get_base_block_reward(false, bcs.total_coins(), top_block_height + 1); - uint64_t base_block_reward_pos = get_base_block_reward(true, bcs.total_coins(), top_block_height + 1); + uint64_t base_block_reward_pow = get_base_block_reward(top_block_height + 1); + uint64_t base_block_reward_pos = base_block_reward_pow; g_block_txs_fee = TESTS_DEFAULT_FEE; // passing an argument to custom_fill_block_template_func via global variable (not perfect but works well) diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index 5ab4bf0e..21005216 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -828,7 +828,7 @@ uint64_t test_generator::get_base_reward_for_next_block(const crypto::hash& head auto it = m_blocks_info.find(head_id); if (it == m_blocks_info.end()) return 0; - return get_base_block_reward(!pow, it->second.already_generated_coins, get_block_height(it->second.b)); + return get_base_block_reward(get_block_height(it->second.b)); } bool test_generator::find_nounce(currency::block& blk, std::vector& blocks, wide_difficulty_type dif, uint64_t height) const From 6f4e1465bc5ef44f5475c92f31c25777697d9dc4 Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 22 Apr 2024 17:50:41 +0200 Subject: [PATCH 153/184] utils: macosx_bild_uploader: increased attempts count (i.e. timeout) --- utils/macosx_build_uploader.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/macosx_build_uploader.sh b/utils/macosx_build_uploader.sh index acd23652..45813204 100644 --- a/utils/macosx_build_uploader.sh +++ b/utils/macosx_build_uploader.sh @@ -27,7 +27,7 @@ function upload_build() # $1 - path to the file to be uploaded counter=0 while [ ! -f DONE ] do - if [ "$counter" -ge 150 ] + if [ "$counter" -ge 500 ] then echo "ERROR: uploading is taking longer than expected" touch STOP From 1196423f02bee014c7e9d36194d282f2d5772b35 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Mon, 22 Apr 2024 23:28:36 +0400 Subject: [PATCH 154/184] fixes over documentation autogen --- .../include/net/http_server_handlers_map2.h | 37 ++++++++++++++++--- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/contrib/epee/include/net/http_server_handlers_map2.h b/contrib/epee/include/net/http_server_handlers_map2.h index 61acf12f..b4466ad4 100644 --- a/contrib/epee/include/net/http_server_handlers_map2.h +++ b/contrib/epee/include/net/http_server_handlers_map2.h @@ -47,7 +47,7 @@ namespace epee t_param params; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(jsonrpc) + KV_SERIALIZE(jsonrpc) DOC_DSCR("") DOC_EXMP("2.0") DOC_END KV_SERIALIZE(id) KV_SERIALIZE(method) KV_SERIALIZE(params) @@ -98,7 +98,7 @@ namespace epee t_param result; epee::serialization::storage_entry id; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(jsonrpc) + KV_SERIALIZE(jsonrpc) DOC_DSCR("") DOC_EXMP("2.0") DOC_END KV_SERIALIZE(id) KV_SERIALIZE(result) END_KV_SERIALIZE_MAP() @@ -187,6 +187,24 @@ template void f(T) {} // Definition #2 +// Base template +template +struct is_std_simple_container : std::false_type {}; + +// Specializations for each container +template +struct is_std_simple_container> : std::true_type {}; + +template +struct is_std_simple_container> : std::true_type {}; + +template +struct is_std_simple_container> : std::true_type {}; + +template +struct is_std_simple_container> : std::true_type {}; + + template bool auto_doc(const std::string& uri, const std::string& method, bool is_json, documentation& docs) { @@ -202,11 +220,20 @@ bool auto_doc(const std::string& uri, const std::string& method, bool is_json, d { //json rpc-like call typedef typename epee::json_rpc::request request_t; - typedef typename epee::json_rpc::request response_t; + typedef typename epee::json_rpc::response response_t; request_t req = AUTO_VAL_INIT(req); //get_documentation_json_struct(); - response_t res = AUTO_VAL_INIT(res); //get_documentation_json_struct(); - + if constexpr (is_std_simple_container::value) + { + req.params.resize(1); + } + + response_t res = AUTO_VAL_INIT(res); + if constexpr (is_std_simple_container::value) + { + req.result.resize(1); + } + req.method = method; epee::serialization::portable_storage_extended_doc ps; req.store(ps, nullptr); ps.dump_as_json(docs.entries.back().request_json_example); From 7fdc82a630b2ab6852c1d26663372b1b68b09976 Mon Sep 17 00:00:00 2001 From: sowle Date: Thu, 25 Apr 2024 16:46:36 +0200 Subject: [PATCH 155/184] minor code cleanup --- src/crypto/crypto-sugar.h | 9 --------- src/crypto/range_proofs.h | 1 - src/currency_core/blockchain_storage.cpp | 1 - 3 files changed, 11 deletions(-) diff --git a/src/crypto/crypto-sugar.h b/src/crypto/crypto-sugar.h index be99731f..846e4572 100644 --- a/src/crypto/crypto-sugar.h +++ b/src/crypto/crypto-sugar.h @@ -1202,15 +1202,6 @@ namespace crypto void add_point(const point_t& point) { m_elements.emplace_back(point.to_public_key()); - - // faster? - /* static_assert(sizeof point.m_p3 == 5 * sizeof(item_t), "size missmatch"); - const item_t *p = (item_t*)&point.m_p3; - m_elements.emplace_back(p[0]); - m_elements.emplace_back(p[1]); - m_elements.emplace_back(p[2]); - m_elements.emplace_back(p[3]); - m_elements.emplace_back(p[4]); */ } void add_pub_key(const crypto::public_key& pk) diff --git a/src/crypto/range_proofs.h b/src/crypto/range_proofs.h index 646f2908..17cbba51 100644 --- a/src/crypto/range_proofs.h +++ b/src/crypto/range_proofs.h @@ -100,7 +100,6 @@ namespace crypto } // TODO: refactor with proper OOB handling - // TODO: @#@# add domain separation static const point_t& get_generator(bool select_H, size_t index) { if (index >= c_bpp_mn_max) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 58249f3a..90d573d2 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -4508,7 +4508,6 @@ bool blockchain_storage::add_transaction_from_block(const transaction& tx, const << " (fee: " << (is_coinbase(tx) ? "0 [coinbase]" : print_money_brief(get_tx_fee(tx))) << ")"); TIME_MEASURE_FINISH_PD_COND(need_to_profile, tx_print_log); - //@#@ del me // LOG_PRINT_L0("APPEND_TX_TIME_INNER: " << m_performance_data.tx_append_rl_wait.get_last_val() // << " | " << m_performance_data.tx_append_is_expired.get_last_val() // << " | " << m_performance_data.tx_process_extra.get_last_val() From 3ab93654f53bb1bc8295f1a6c6d7b96e7d41999a Mon Sep 17 00:00:00 2001 From: sowle Date: Thu, 25 Apr 2024 16:59:42 +0200 Subject: [PATCH 156/184] ui update --- src/gui/qt-daemon/layout | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/qt-daemon/layout b/src/gui/qt-daemon/layout index 585ffce6..b936229a 160000 --- a/src/gui/qt-daemon/layout +++ b/src/gui/qt-daemon/layout @@ -1 +1 @@ -Subproject commit 585ffce64de124a8b503c89c33939666d2bfc1ab +Subproject commit b936229a66becf133459f11586e04e08ccb05c63 From 89e6555e2a9a77d5af1cf1947b201ac73fdae3bc Mon Sep 17 00:00:00 2001 From: zano build machine Date: Thu, 25 Apr 2024 18:00:29 +0300 Subject: [PATCH 157/184] === build number: 302 -> 303 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index 8a121a4f..599bc643 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 302 +#define PROJECT_VERSION_BUILD_NO 303 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From db4b841f571f713f33ea1e9ae77e76ebf38e7750 Mon Sep 17 00:00:00 2001 From: sowle Date: Thu, 25 Apr 2024 19:13:57 +0200 Subject: [PATCH 158/184] minor fixes and code cleanup --- src/currency_core/blockchain_storage.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 90d573d2..f55b6934 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -4703,7 +4703,8 @@ bool blockchain_storage::print_tx_outputs_lookup(const crypto::hash& tx_id)const continue; usage_stat[o.amount][tx_ptr->m_global_output_indexes[i]]; VARIANT_CASE_CONST(tx_out_zarcanum, toz) - //@#@ + strm_tx << "[" << i << "]: " << ENDL; + usage_stat[0][tx_ptr->m_global_output_indexes[i]]; VARIANT_SWITCH_END(); } @@ -4966,7 +4967,7 @@ struct outputs_visitor //check tx unlock time uint64_t source_out_unlock_time = get_tx_unlock_time(source_tx, out_i); //let coinbase sources for PoS block to have locked inputs, the outputs supposed to be locked same way, except the reward - if (is_coinbase(validated_tx) && is_pos_miner_tx(validated_tx)) // @#@ consider changing to one call to is_pos_coinbase() + if (is_pos_miner_tx(validated_tx)) { CHECK_AND_ASSERT_MES(should_unlock_value_be_treated_as_block_height(source_out_unlock_time), false, "source output #" << out_i << " is locked by time, not by height, which is not allowed for PoS coinbase"); if (source_out_unlock_time > m_source_max_unlock_time_for_pos_coinbase) @@ -5299,7 +5300,7 @@ bool blockchain_storage::check_tx_input(const transaction& tx, size_t in_index, CRITICAL_REGION_LOCAL(m_read_lock); // we need a list this input is referring to - // and make sure that all of them are good (i.e. check 1) source tx unlock time validity; 2) mixin restrictions; 3) general gindex/ref_by_id corectness) + // and make sure that all of them are good (i.e. check: 1) source tx unlock time validity; 2) mixin restrictions; 3) general gindex/ref_by_id corectness) // get_output_keys_for_input_with_checks is used for that // std::vector dummy_output_keys; // won't be used @@ -5475,7 +5476,7 @@ std::shared_ptr blockchain_storage::find_key_imag { if (k_image == ki) { - id_result = get_transaction_hash(tx_chain_entry->tx); // ??? @#@# why not just use tx_id ? + id_result = tx_id; return tx_chain_entry; } } From d718d876fc3d1f7cb3027b52be09e96ecdc33a66 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Sat, 27 Apr 2024 23:26:32 +0400 Subject: [PATCH 159/184] added address field to get_seed_phrase_info --- src/wallet/wallet_helpers.h | 29 ++++++++++++++++++++----- src/wallet/wallet_public_structs_defs.h | 2 ++ 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/wallet/wallet_helpers.h b/src/wallet/wallet_helpers.h index 6c24ef88..50da63a0 100644 --- a/src/wallet/wallet_helpers.h +++ b/src/wallet/wallet_helpers.h @@ -38,21 +38,40 @@ namespace tools result.hash_sum_matched = false; result.syntax_correct = acc.restore_from_tracking_seed(seed_phrase); if (result.syntax_correct) + { result.tracking = true; + result.address = acc.get_public_address_str(); + } } else { result.syntax_correct = currency::account_base::is_seed_password_protected(seed_phrase, result.require_password); - if (result.syntax_correct && result.require_password) + if (result.syntax_correct ) { - if (seed_password.size()) + if (result.require_password) { - currency::account_base acc; - result.hash_sum_matched = acc.restore_from_seed_phrase(seed_phrase, seed_password); + if (seed_password.size()) + { + currency::account_base acc; + result.hash_sum_matched = acc.restore_from_seed_phrase(seed_phrase, seed_password); + if (result.hash_sum_matched) + { + result.address = acc.get_public_address_str(); + } + } + else + { + result.hash_sum_matched = false; + } } else { - result.hash_sum_matched = false; + currency::account_base acc; + result.syntax_correct = acc.restore_from_seed_phrase(seed_phrase, ""); + if (result.syntax_correct) + { + result.address = acc.get_public_address_str(); + } } } } diff --git a/src/wallet/wallet_public_structs_defs.h b/src/wallet/wallet_public_structs_defs.h index 2d8a3685..663fb080 100644 --- a/src/wallet/wallet_public_structs_defs.h +++ b/src/wallet/wallet_public_structs_defs.h @@ -381,12 +381,14 @@ namespace wallet_public bool require_password; bool hash_sum_matched; bool tracking; + std::string address; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(syntax_correct) DOC_DSCR("Indicates whether the syntax is correct.") DOC_EXMP(true) DOC_END KV_SERIALIZE(require_password) DOC_DSCR("Indicates whether a password is required.") DOC_EXMP(true) DOC_END KV_SERIALIZE(hash_sum_matched) DOC_DSCR("Indicates whether the hash sum matches.") DOC_EXMP(true) DOC_END KV_SERIALIZE(tracking) DOC_DSCR("Indicates whether tracking is enabled.") DOC_EXMP(false) DOC_END + KV_SERIALIZE(address) DOC_DSCR("Return address of the seed phrase.") DOC_EXMP("ZxDNaMeZjwCjnHuU5gUNyrP1pM3U5vckbakzzV6dEHyDYeCpW8XGLBFTshcaY8LkG9RQn7FsQx8w2JeJzJwPwuDm2NfixPAXf") DOC_END END_KV_SERIALIZE_MAP() }; From 1d153834d9521503e07991601abcad225ac2a3cc Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Tue, 30 Apr 2024 20:29:11 +0400 Subject: [PATCH 160/184] fixed m3 simulator build for ios --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4422f361..20e01aa2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -229,11 +229,11 @@ if(CMAKE_SYSTEM_NAME STREQUAL "iOS") set(Boost_LIBRARIES "libboost.a") #workaround for new XCode 12 policy for builds(now it includes a slice for the "arm64" when builds for simulator) set(__iphoneos_archs "arm64") - set(__iphonesimulator_archs "x86_64") + #set(__iphonesimulator_archs "arm64,x86_64") set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=iphoneos*] "${__iphoneos_archs}") set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphoneos*] "${__iphoneos_archs}") - set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] "${__iphonesimulator_archs}") - set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphonesimulator*] "${__iphonesimulator_archs}") + #set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] "${__iphonesimulator_archs}") + #set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphonesimulator*] "${__iphonesimulator_archs}") elseif(CMAKE_SYSTEM_NAME STREQUAL "Android") set(Boost_LIBRARY_DIRS "${Boost_LIBRARY_DIRS}/${CMAKE_ANDROID_ARCH_ABI}/") set(Boost_LIBRARIES "${Boost_LIBRARY_DIRS}libboost_system.a;${Boost_LIBRARY_DIRS}libboost_filesystem.a;${Boost_LIBRARY_DIRS}libboost_thread.a;${Boost_LIBRARY_DIRS}libboost_timer.a;${Boost_LIBRARY_DIRS}libboost_date_time.a;${Boost_LIBRARY_DIRS}libboost_chrono.a;${Boost_LIBRARY_DIRS}libboost_regex.a;${Boost_LIBRARY_DIRS}libboost_serialization.a;${Boost_LIBRARY_DIRS}libboost_atomic.a;${Boost_LIBRARY_DIRS}libboost_program_options.a") From a853f77c009c45a1d2016443ac1d5a1193330e8f Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 1 May 2024 19:20:24 +0400 Subject: [PATCH 161/184] added Debug config, replace boost to std (due to deadlock in boost guts) --- CMakeLists.txt | 2 +- contrib/epee/include/file_io_utils.h | 8 ++++---- tests/performance_tests/main.cpp | 7 +++++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 20e01aa2..59d61a4e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,7 +53,7 @@ if (UNIX AND NOT APPLE) else() # multi configurations for MSVC and XCode if(CMAKE_SYSTEM_NAME STREQUAL "iOS") - set(CMAKE_CONFIGURATION_TYPES "Release") + set(CMAKE_CONFIGURATION_TYPES "Debug;Release") elseif(CMAKE_SYSTEM_NAME STREQUAL "Android") set(CMAKE_CONFIGURATION_TYPES "Debug;Release") else() diff --git a/contrib/epee/include/file_io_utils.h b/contrib/epee/include/file_io_utils.h index 7ece78b1..9d5118cb 100644 --- a/contrib/epee/include/file_io_utils.h +++ b/contrib/epee/include/file_io_utils.h @@ -35,6 +35,7 @@ #include #include #include +#include #ifndef MAKE64 #define MAKE64(low,high) ((__int64)(((DWORD)(low)) | ((__int64)((DWORD)(high))) << 32)) @@ -561,16 +562,15 @@ namespace file_io_utils try { - boost::filesystem::directory_iterator end_itr; // default construction yields past-the-end - for ( boost::filesystem::directory_iterator itr( epee::string_encoding::utf8_to_wstring(path) ); itr != end_itr; ++itr ) + std::filesystem::directory_iterator end_itr; // default construction yields past-the-end + for ( std::filesystem::directory_iterator itr( epee::string_encoding::utf8_to_wstring(path) ); itr != end_itr; ++itr ) { - if ( only_files && boost::filesystem::is_directory(itr->status()) ) + if ( only_files && std::filesystem::is_directory(itr->status()) ) { continue; } target_list.push_back(itr->path().filename().string()); } - } catch(...) diff --git a/tests/performance_tests/main.cpp b/tests/performance_tests/main.cpp index eefed6c3..58fbd85f 100644 --- a/tests/performance_tests/main.cpp +++ b/tests/performance_tests/main.cpp @@ -35,8 +35,12 @@ POP_VS_WARNINGS void test_plain_wallet() { //std::string res = plain_wallet::init("195.201.107.230", "33336", "E:\\tmp\\", 0); - std::string res = plain_wallet::init("127.0.0.1", "12111", "C:\\Users\\roky\\home\\", 0); + std::string res = plain_wallet::init("127.0.0.1", "12111", "C:\\Users\\roky\\home22\\", 0); + + std::string res___ = plain_wallet::get_wallet_files(); + + uint64_t instance_id = 0; res = plain_wallet::open("test_restored_2.zan", "111"); //res = plain_wallet::restore("", @@ -53,7 +57,6 @@ void test_plain_wallet() break; } - std::string invoke_body = "{\"method\":\"store\",\"params\":{}}"; std::string res1 = plain_wallet::sync_call("invoke", instance_id, invoke_body); From 423b99cc5eec3e547243401cdeb126a69ea2ec3e Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 2 May 2024 19:12:35 +0400 Subject: [PATCH 162/184] fixes in UI for latest qt and latest UI commits --- src/gui/qt-daemon/application/mainwindow.cpp | 2 +- src/gui/qt-daemon/application/mainwindow.h | 2 +- src/gui/qt-daemon/layout | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/qt-daemon/application/mainwindow.cpp b/src/gui/qt-daemon/application/mainwindow.cpp index 80437eed..6cb817e0 100644 --- a/src/gui/qt-daemon/application/mainwindow.cpp +++ b/src/gui/qt-daemon/application/mainwindow.cpp @@ -1428,7 +1428,7 @@ void MainWindow::on_clear_events() } -QString MainWindow::store_secure_app_data(const QString& param) +QString MainWindow::store_secure_app_data(const QString& param, const QString& password) { TRY_ENTRY(); LOG_API_TIMING(); diff --git a/src/gui/qt-daemon/application/mainwindow.h b/src/gui/qt-daemon/application/mainwindow.h index c0df8862..074fb9f5 100644 --- a/src/gui/qt-daemon/application/mainwindow.h +++ b/src/gui/qt-daemon/application/mainwindow.h @@ -114,7 +114,7 @@ public: QString have_secure_app_data(const QString& param); QString drop_secure_app_data(const QString& param); QString get_secure_app_data(const QString& param); - QString store_secure_app_data(const QString& param); + QString store_secure_app_data(const QString& param, const QString& password); QString set_master_password(const QString& param); QString check_master_password(const QString& param); QString get_app_data(const QString& param); diff --git a/src/gui/qt-daemon/layout b/src/gui/qt-daemon/layout index b936229a..1f2ce4ce 160000 --- a/src/gui/qt-daemon/layout +++ b/src/gui/qt-daemon/layout @@ -1 +1 @@ -Subproject commit b936229a66becf133459f11586e04e08ccb05c63 +Subproject commit 1f2ce4ce600e97b8e21e8f8674f97cb89a0e875f From 7a0ec043a1fafcec35d166551a0ed545094a4f7a Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Fri, 3 May 2024 20:08:22 +0400 Subject: [PATCH 163/184] fixed issue with multithreadin and jwt rpc --- src/wallet/wallets_manager.cpp | 2 ++ src/wallet/wallets_manager.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index 2bcdb3dd..02287be5 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -2124,6 +2124,7 @@ bool wallets_manager::on_mw_select_wallet(const tools::wallet_public::COMMAND_MW void wallets_manager::lock() { #ifndef MOBILE_WALLET_BUILD + m_select_wallet_rpc_lock.lock(); { SHARED_CRITICAL_REGION_LOCAL(m_wallets_lock); auto it = m_wallets.find(m_rpc_selected_wallet_id); @@ -2140,6 +2141,7 @@ void wallets_manager::unlock() { #ifndef MOBILE_WALLET_BUILD m_current_wallet_locked_object.reset(); + m_select_wallet_rpc_lock.unlock(); #endif } std::shared_ptr wallets_manager::get_wallet() diff --git a/src/wallet/wallets_manager.h b/src/wallet/wallets_manager.h index 60ea6fee..014ea3ef 100644 --- a/src/wallet/wallets_manager.h +++ b/src/wallet/wallets_manager.h @@ -234,6 +234,8 @@ private: std::mutex m_stop_singal_sent_mutex; std::condition_variable m_stop_singal_sent_mutex_cv; + std::mutex m_select_wallet_rpc_lock; + view::i_view m_view_stub; view::i_view* m_pview; std::shared_ptr m_rpc_proxy; From 2b1c1094a60fbfb9d9c261f9f9bc2f51690c5fe4 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 3 May 2024 18:39:26 +0200 Subject: [PATCH 164/184] fix for m_db_per_block_gindex_incs container (was not populated properly due to a bug in append_per_block_increments_for_tx()) --- src/currency_core/blockchain_storage.cpp | 64 ++++++++++++++++++--- src/currency_core/currency_config.h | 2 +- src/currency_core/currency_format_utils.cpp | 2 +- 3 files changed, 59 insertions(+), 9 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index f55b6934..6179559a 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -297,10 +297,13 @@ bool blockchain_storage::init(const std::string& config_folder, const boost::pro m_db_addr_to_alias.set_cache_size(cache_size); } + LOG_PRINT_L0("Opened DB ver " << m_db_storage_major_compatibility_version << "." << m_db_storage_minor_compatibility_version); + bool need_reinit = false; if (m_db_blocks.size() != 0) { #ifndef TESTNET + // MAINNET ONLY if ((m_db_storage_major_compatibility_version == 93 || m_db_storage_major_compatibility_version == 94) && BLOCKCHAIN_STORAGE_MAJOR_COMPATIBILITY_VERSION == 95) { // migrate DB to rebuild aliases container @@ -379,14 +382,21 @@ bool blockchain_storage::init(const std::string& config_folder, const boost::pro // do not reinit db if moving from version 93 to version 94 LOG_PRINT_MAGENTA("DB storage does not need reinit because moving from v93 to v94", LOG_LEVEL_0); } + +#define DB_MAJ_VERSION_FOR_PER_BLOCK_GINDEX_FIX 95 + #else - // TESTNET + // TESTNET ONLY if (m_db_storage_major_compatibility_version == 95 && BLOCKCHAIN_STORAGE_MAJOR_COMPATIBILITY_VERSION == 96) { // do not reinit TESTNET db if moving from version 95 to version 96 LOG_PRINT_MAGENTA("DB storage does not need reinit because moving from v95 to v96", LOG_LEVEL_0); } + +#define DB_MAJ_VERSION_FOR_PER_BLOCK_GINDEX_FIX 109 + #endif + // MAINNET and TESTNET else if (m_db_storage_major_compatibility_version != BLOCKCHAIN_STORAGE_MAJOR_COMPATIBILITY_VERSION) { need_reinit = true; @@ -398,6 +408,46 @@ bool blockchain_storage::init(const std::string& config_folder, const boost::pro need_reinit = true; LOG_PRINT_MAGENTA("DB storage needs reinit because it has minor compatibility ver " << m_db_storage_minor_compatibility_version << " that is greater than BLOCKCHAIN_STORAGE_MINOR_COMPATIBILITY_VERSION: " << BLOCKCHAIN_STORAGE_MINOR_COMPATIBILITY_VERSION, LOG_LEVEL_0); } + + if (!need_reinit && m_db_storage_major_compatibility_version == DB_MAJ_VERSION_FOR_PER_BLOCK_GINDEX_FIX && m_db_storage_minor_compatibility_version == 1) + { + // such version means that DB has unpopulated container m_db_per_block_gindex_incs, fix it now + LOG_PRINT_MAGENTA("DB version is " << DB_MAJ_VERSION_FOR_PER_BLOCK_GINDEX_FIX << ".1, migrating m_db_per_block_gindex_incs to ver. " << DB_MAJ_VERSION_FOR_PER_BLOCK_GINDEX_FIX << ".2...", LOG_LEVEL_0); + + // temporary set db compatibility version to zero during migration in order to trigger db reinit on the next lanunch in case the process stops in the middle + m_db.begin_transaction(); + uint64_t tmp_db_maj_version = m_db_storage_major_compatibility_version; + m_db_storage_major_compatibility_version = 0; + m_db.commit_transaction(); + + m_db.begin_transaction(); + std::unordered_map gindices; + for(size_t height = ZANO_HARDFORK_04_AFTER_HEIGHT + 1, size = m_db_blocks.size(); height < size; ++height) + { + auto block_ptr = m_db_blocks[height]; + gindices.clear(); + append_per_block_increments_for_tx(block_ptr->bl.miner_tx, gindices); + for(const crypto::hash& tx_id : block_ptr->bl.tx_hashes) + { + auto tx_ptr = m_db_transactions.get(tx_id); + if (!tx_ptr) + { + LOG_ERROR("Internal error: couldn't find a transactions with id " << tx_id << ", migration stops now and full resync is triggered in attempt to fix this."); + need_reinit = true; + break; + } + append_per_block_increments_for_tx(tx_ptr->tx, gindices); + } + push_block_to_per_block_increments(height, gindices); + } + m_db.commit_transaction(); + + // restore db maj compatibility + m_db.begin_transaction(); + m_db_storage_major_compatibility_version = tmp_db_maj_version; + m_db.commit_transaction(); + LOG_PRINT_MAGENTA("migration of m_db_per_block_gindex_incs completed successfully", LOG_LEVEL_0); + } } if (need_reinit) @@ -452,12 +502,12 @@ bool blockchain_storage::init(const std::string& config_folder, const boost::pro set_lost_tx_unmixable(); m_db.commit_transaction(); - LOG_PRINT_GREEN("Blockchain initialized. (v:" << m_db_storage_major_compatibility_version << ") last block: " << m_db_blocks.size() - 1 << ENDL - << "genesis: " << get_block_hash(m_db_blocks[0]->bl) << ENDL - << "last block: " << m_db_blocks.size() - 1 << ", " << misc_utils::get_time_interval_string(timestamp_diff) << " time ago" << ENDL - << "current pos difficulty: " << get_next_diff_conditional(true) << ENDL - << "current pow difficulty: " << get_next_diff_conditional(false) << ENDL - << "total transactions: " << m_db_transactions.size(), + LOG_PRINT_GREEN("Blockchain initialized, ver: " << m_db_storage_major_compatibility_version << "." << m_db_storage_minor_compatibility_version << ", last block: " << m_db_blocks.size() - 1 << ENDL + << " genesis: " << get_block_hash(m_db_blocks[0]->bl) << ENDL + << " last block: " << m_db_blocks.size() - 1 << ", " << misc_utils::get_time_interval_string(timestamp_diff) << " ago" << ENDL + << " current pos difficulty: " << get_next_diff_conditional(true) << ENDL + << " current pow difficulty: " << get_next_diff_conditional(false) << ENDL + << " total transactions: " << m_db_transactions.size(), LOG_LEVEL_0); return true; diff --git a/src/currency_core/currency_config.h b/src/currency_core/currency_config.h index f0a297ce..a15af43c 100644 --- a/src/currency_core/currency_config.h +++ b/src/currency_core/currency_config.h @@ -243,7 +243,7 @@ #define CURRENT_BLOCK_EXTENDED_INFO_ARCHIVE_VER 1 #define BLOCKCHAIN_STORAGE_MAJOR_COMPATIBILITY_VERSION CURRENCY_FORMATION_VERSION + 11 -#define BLOCKCHAIN_STORAGE_MINOR_COMPATIBILITY_VERSION 1 +#define BLOCKCHAIN_STORAGE_MINOR_COMPATIBILITY_VERSION 2 #define BC_OFFERS_CURRENT_OFFERS_SERVICE_ARCHIVE_VER CURRENCY_FORMATION_VERSION + BLOCKCHAIN_STORAGE_MAJOR_COMPATIBILITY_VERSION + 9 diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index e19697a8..5c406e4d 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -4076,7 +4076,7 @@ namespace currency gindices[amount] += 1; } VARIANT_CASE_CONST(tx_out_zarcanum, o) - //@#@ + gindices[0] += 1; VARIANT_SWITCH_END(); } } From 5e07e3c4e0e04e71f42431a892d5f4b18ea15b06 Mon Sep 17 00:00:00 2001 From: sowle Date: Sat, 4 May 2024 02:05:17 +0200 Subject: [PATCH 165/184] an attempt to fix linux build --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 59d61a4e..843659dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -264,6 +264,7 @@ elseif(NOT MSVC) endif() if(BUILD_GUI) + cmake_minimum_required(VERSION 3.1) # <-- this is important for Linux GUI build, don't touch it -- sowle find_package(Qt5Widgets REQUIRED) find_package(Qt5WebEngineWidgets REQUIRED) find_package(Qt5WebChannel REQUIRED) From a12fd42a8e3d49ce4255206479aee5b0dd459aba Mon Sep 17 00:00:00 2001 From: zano build machine Date: Sat, 4 May 2024 03:13:22 +0300 Subject: [PATCH 166/184] === build number: 303 -> 304 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index 599bc643..5e08cda4 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 303 +#define PROJECT_VERSION_BUILD_NO 304 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From 2e75597365be08492f344cbd12016f2c6dc28194 Mon Sep 17 00:00:00 2001 From: sowle Date: Sat, 4 May 2024 02:21:34 +0200 Subject: [PATCH 167/184] code clean-up and minor improvements --- src/common/variant_helper.h | 1 + src/currency_core/blockchain_storage.cpp | 6 ++---- src/currency_core/currency_format_utils.cpp | 8 ++++---- src/currency_core/currency_format_utils.h | 6 +++--- src/currency_core/tx_semantic_validation.cpp | 2 +- 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/common/variant_helper.h b/src/common/variant_helper.h index 7fcf996b..9f98cbaa 100644 --- a/src/common/variant_helper.h +++ b/src/common/variant_helper.h @@ -14,6 +14,7 @@ #define VARIANT_SWITCH_END() } } +#define VARIANT_OBJ_TYPENAME local_reference_eokcmeokmeokcm.type().name() /* diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 6179559a..1d9ee976 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -1314,8 +1314,8 @@ wide_difficulty_type blockchain_storage::get_next_difficulty_for_alternative_cha //------------------------------------------------------------------ bool blockchain_storage::prevalidate_miner_transaction(const block& b, uint64_t height, bool pos) const { - CHECK_AND_ASSERT_MES((pos ? (b.miner_tx.vin.size() == 2) : (b.miner_tx.vin.size() == 1)), false, "coinbase transaction in the block has no inputs"); - CHECK_AND_ASSERT_MES(b.miner_tx.vin[0].type() == typeid(txin_gen), false, "coinbase transaction in the block has the wrong type"); + CHECK_AND_ASSERT_MES((pos ? (b.miner_tx.vin.size() == 2) : (b.miner_tx.vin.size() == 1)), false, "coinbase transaction in the block has incorrect inputs number: " << b.miner_tx.vin.size()); + CHECK_AND_ASSERT_MES(b.miner_tx.vin[0].type() == typeid(txin_gen), false, "input #0 of the coinbase transaction in the block has the wrong type : " << b.miner_tx.vin[0].type().name()); if(boost::get(b.miner_tx.vin[0]).height != height) { LOG_PRINT_RED_L0("The miner transaction in block has invalid height: " << boost::get(b.miner_tx.vin[0]).height << ", expected: " << height); @@ -1341,8 +1341,6 @@ bool blockchain_storage::prevalidate_miner_transaction(const block& b, uint64_t } else { - //------------------------------------------------------------------ - //bool blockchain_storage:: // pre-hard fork rules that don't allow different unlock time in coinbase outputs uint64_t max_unlock_time = 0; uint64_t min_unlock_time = 0; diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 5c406e4d..5f4fa38f 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -3118,12 +3118,12 @@ namespace currency return true; } //----------------------------------------------------------------------------------------------- - bool check_money_overflow(const transaction& tx) + bool check_bare_money_overflow(const transaction& tx) { - return check_inputs_overflow(tx) && check_outs_overflow(tx); + return check_bare_inputs_overflow(tx) && check_bare_outs_overflow(tx); } //--------------------------------------------------------------- - bool check_inputs_overflow(const transaction& tx) + bool check_bare_inputs_overflow(const transaction& tx) { uint64_t money = 0; for(const auto& in : tx.vin) @@ -3160,7 +3160,7 @@ namespace currency return true; } //--------------------------------------------------------------- - bool check_outs_overflow(const transaction& tx) + bool check_bare_outs_overflow(const transaction& tx) { uint64_t money = 0; for(const auto& o : tx.vout) diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index 7b769e6a..312eff34 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -414,9 +414,9 @@ namespace currency uint64_t get_alias_coast_from_fee(const std::string& alias, uint64_t fee_median); //const crypto::public_key get_offer_secure_key_by_index_from_tx(const transaction& tx, size_t index); - bool check_money_overflow(const transaction& tx); - bool check_outs_overflow(const transaction& tx); - bool check_inputs_overflow(const transaction& tx); + bool check_bare_money_overflow(const transaction& tx); + bool check_bare_outs_overflow(const transaction& tx); + bool check_bare_inputs_overflow(const transaction& tx); uint64_t get_block_height(const transaction& coinbase); uint64_t get_block_height(const block& b); std::vector relative_output_offsets_to_absolute(const std::vector& off); diff --git a/src/currency_core/tx_semantic_validation.cpp b/src/currency_core/tx_semantic_validation.cpp index 26d95916..d358edf2 100644 --- a/src/currency_core/tx_semantic_validation.cpp +++ b/src/currency_core/tx_semantic_validation.cpp @@ -60,7 +60,7 @@ namespace currency return false; } - if (!check_money_overflow(tx)) + if (!check_bare_money_overflow(tx)) { LOG_PRINT_RED_L0("tx has money overflow, rejected for tx id= " << get_transaction_hash(tx)); return false; From e57709a67f3c6d08a3c48212411020542fdcedf5 Mon Sep 17 00:00:00 2001 From: sowle Date: Sat, 4 May 2024 02:24:11 +0200 Subject: [PATCH 168/184] prevalidate_miner_transaction() now checks HF condition for the given height instead of the top height --- src/currency_core/blockchain_storage.cpp | 26 ++++++++++++++---------- src/currency_core/blockchain_storage.h | 1 + 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 1d9ee976..d10918d6 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -1323,13 +1323,13 @@ bool blockchain_storage::prevalidate_miner_transaction(const block& b, uint64_t } if (pos) { - if (is_hardfork_active(ZANO_HARDFORK_04_ZARCANUM)) // TODO @#@# consider moving to validate_tx_for_hardfork_specific_terms + if (is_hardfork_active_for_height(ZANO_HARDFORK_04_ZARCANUM, height)) // TODO @#@# consider moving to validate_tx_for_hardfork_specific_terms CHECK_AND_ASSERT_MES(b.miner_tx.vin[1].type() == typeid(txin_zc_input), false, "coinstake tx has incorrect type of input #1: " << b.miner_tx.vin[1].type().name()); else CHECK_AND_ASSERT_MES(b.miner_tx.vin[1].type() == typeid(txin_to_key), false, "coinstake tx has incorrect type of input #1: " << b.miner_tx.vin[1].type().name()); } - if (m_core_runtime_config.is_hardfork_active_for_height(1, height)) + if (is_hardfork_active_for_height(ZANO_HARDFORK_01, height)) { // new rules that allow different unlock time in coinbase outputs uint64_t max_unlock_time = 0; @@ -1337,7 +1337,7 @@ bool blockchain_storage::prevalidate_miner_transaction(const block& b, uint64_t bool r = get_tx_max_min_unlock_time(b.miner_tx, max_unlock_time, min_unlock_time); CHECK_AND_ASSERT_MES(r && min_unlock_time >= height + CURRENCY_MINED_MONEY_UNLOCK_WINDOW, false, - "coinbase transaction has wrong min_unlock_time: " << min_unlock_time << ", expected: " << height + CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + "coinbase transaction has wrong min_unlock_time: " << min_unlock_time << ", expected to be greater than or equal to " << height + CURRENCY_MINED_MONEY_UNLOCK_WINDOW); } else { @@ -1352,14 +1352,7 @@ bool blockchain_storage::prevalidate_miner_transaction(const block& b, uint64_t } - //check outs overflow - if(!check_outs_overflow(b.miner_tx)) - { - LOG_PRINT_RED_L0("miner transaction have money overflow in block " << get_block_hash(b)); - return false; - } - - if (is_hardfork_active(ZANO_HARDFORK_04_ZARCANUM)) // TODO @#@# consider moving to validate_tx_for_hardfork_specific_terms + if (is_hardfork_active_for_height(ZANO_HARDFORK_04_ZARCANUM, height)) // TODO @#@# consider moving to validate_tx_for_hardfork_specific_terms { CHECK_AND_ASSERT_MES(b.miner_tx.attachment.empty(), false, "coinbase transaction has attachments; attachments are not allowed for coinbase transactions."); CHECK_AND_ASSERT_MES(b.miner_tx.proofs.size() == 3, false, "coinbase transaction has incorrect number of proofs (" << b.miner_tx.proofs.size() << "), expected 3"); @@ -1369,6 +1362,12 @@ bool blockchain_storage::prevalidate_miner_transaction(const block& b, uint64_t } else { + if(!check_bare_outs_overflow(b.miner_tx)) + { + LOG_PRINT_RED_L0("miner transaction have money overflow in block " << get_block_hash(b)); + return false; + } + CHECK_AND_ASSERT_MES(b.miner_tx.attachment.empty(), false, "coinbase transaction has attachments; attachments are not allowed for coinbase transactions."); CHECK_AND_ASSERT_MES(b.miner_tx.proofs.size() == 0, false, "pre-HF4 coinbase shoudn't have non-empty proofs containter"); } @@ -6902,6 +6901,11 @@ bool blockchain_storage::is_hardfork_active(size_t hardfork_id) const return m_core_runtime_config.is_hardfork_active_for_height(hardfork_id, m_db_blocks.size()); // note using m_db_blocks.size() ( == top_block_height + 1 ) } //------------------------------------------------------------------ +bool blockchain_storage::is_hardfork_active_for_height(size_t hardfork_id, uint64_t height) const +{ + return m_core_runtime_config.is_hardfork_active_for_height(hardfork_id, height); +} +//------------------------------------------------------------------ bool blockchain_storage::prevalidate_block(const block& bl) { diff --git a/src/currency_core/blockchain_storage.h b/src/currency_core/blockchain_storage.h index df87ce37..babebf89 100644 --- a/src/currency_core/blockchain_storage.h +++ b/src/currency_core/blockchain_storage.h @@ -348,6 +348,7 @@ namespace currency // returns true as soon as the hardfork is active for the NEXT upcoming block (not for the top block in the blockchain storage) bool is_hardfork_active(size_t hardfork_id) const; + bool is_hardfork_active_for_height(size_t hardfork_id, uint64_t height) const; bool fill_tx_rpc_inputs(tx_rpc_extended_info& tei, const transaction& tx) const; bool fill_tx_rpc_details(tx_rpc_extended_info& tei, const transaction& tx, const transaction_chain_entry* ptce, const crypto::hash& h, uint64_t timestamp, bool is_short = false) const; From 5500e943dd4d56010c7365c85d3df8653d8cec1b Mon Sep 17 00:00:00 2001 From: sowle Date: Sat, 4 May 2024 02:33:05 +0200 Subject: [PATCH 169/184] did some refactoring around validate_miner_transaction() code simplified fixed an issue with already_generated_coins not taking block size penalty into consideration --- src/currency_core/blockchain_storage.cpp | 65 ++++++++++++------------ src/currency_core/blockchain_storage.h | 3 +- tests/core_tests/block_reward.cpp | 7 ++- 3 files changed, 39 insertions(+), 36 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index d10918d6..5941c0fe 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -1375,50 +1375,44 @@ bool blockchain_storage::prevalidate_miner_transaction(const block& b, uint64_t return true; } //------------------------------------------------------------------ -bool blockchain_storage::validate_miner_transaction(const block& b, - size_t cumulative_block_size, - uint64_t fee, - uint64_t& base_reward, - const boost::multiprecision::uint128_t& already_generated_coins) const +bool blockchain_storage::calculate_block_reward_for_next_top_block(size_t next_block_cumulative_size, uint64_t& block_reward_without_fee) const { CRITICAL_REGION_LOCAL(m_read_lock); std::vector last_blocks_sizes; get_last_n_blocks_sizes(last_blocks_sizes, CURRENCY_REWARD_BLOCKS_WINDOW); size_t blocks_size_median = misc_utils::median(last_blocks_sizes); - if (!get_block_reward(is_pos_block(b), blocks_size_median, cumulative_block_size, already_generated_coins, base_reward, get_block_height(b))) - { - LOG_PRINT_L0("block size " << cumulative_block_size << " is bigger than allowed for this blockchain"); - return false; - } - - uint64_t block_reward = base_reward; - // before HF4: add tx fee to the block reward; after HF4: burn it - if (b.miner_tx.version < TRANSACTION_VERSION_POST_HF4) + LOG_PRINT_MAGENTA("blocks_size_median = " << blocks_size_median, LOG_LEVEL_2); + block_reward_without_fee = get_block_reward(get_top_block_height() + 1, blocks_size_median, next_block_cumulative_size); + CHECK_AND_ASSERT_MES(block_reward_without_fee != 0, false, "block size " << next_block_cumulative_size << " is bigger than allowed for this blockchain, blocks_size_median: " << blocks_size_median); + return true; +} +//------------------------------------------------------------------ +bool blockchain_storage::validate_miner_transaction(const transaction& miner_tx, + uint64_t fee, + uint64_t block_reward_without_fee) const +{ + uint64_t block_reward = block_reward_without_fee; + // before HF4: add tx fee to the block reward; after HF4: burn fees, so they don't count in block_reward + if (miner_tx.version < TRANSACTION_VERSION_POST_HF4) { block_reward += fee; } - crypto::hash tx_id_for_post_hf4_era = b.miner_tx.version > TRANSACTION_VERSION_PRE_HF4 ? get_transaction_hash(b.miner_tx) : null_hash; - if (!check_tx_balance(b.miner_tx, tx_id_for_post_hf4_era, block_reward)) + crypto::hash tx_id_for_post_hf4_era = miner_tx.version > TRANSACTION_VERSION_PRE_HF4 ? get_transaction_hash(miner_tx) : null_hash; // used in the input context for the proofs for txs ver >= 2 + if (!check_tx_balance(miner_tx, tx_id_for_post_hf4_era, block_reward)) { - LOG_ERROR("coinbase transaction balance check failed. Block reward is " << print_money_brief(block_reward) << "(" << print_money(base_reward) << "+" << print_money(fee) - << ", blocks_size_median = " << blocks_size_median - << ", cumulative_block_size = " << cumulative_block_size - << ", fee = " << fee - << ", already_generated_coins = " << already_generated_coins - << "), tx:"); - LOG_PRINT_L0(currency::obj_to_json_str(b.miner_tx)); + LOG_ERROR("coinbase transaction balance check failed. Block reward is " << print_money_brief(block_reward) << " (" << print_money(block_reward_without_fee) << "+" << print_money(fee) << "), tx:"); + LOG_PRINT_L0(currency::obj_to_json_str(miner_tx)); return false; } - if (!verify_asset_surjection_proof(b.miner_tx, tx_id_for_post_hf4_era)) + if (!verify_asset_surjection_proof(miner_tx, tx_id_for_post_hf4_era)) { LOG_ERROR("asset surjection proof verification failed for miner tx"); return false; } - LOG_PRINT_MAGENTA("Mining tx verification ok, blocks_size_median = " << blocks_size_median, LOG_LEVEL_2); return true; } //------------------------------------------------------------------ @@ -6579,15 +6573,19 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt return false; } - boost::multiprecision::uint128_t already_generated_coins = m_db_blocks.size() ? m_db_blocks.back()->already_generated_coins:0; - uint64_t base_reward = get_base_block_reward(height); + uint64_t block_reward_without_fee = 0; + if (!calculate_block_reward_for_next_top_block(cumulative_block_size, block_reward_without_fee)) + { + LOG_ERROR("calculate_block_reward_for_next_top_block filed"); + purge_block_data_from_blockchain(bl, tx_processed_count); + bvc.m_verification_failed = true; + return false; + } if (!m_is_in_checkpoint_zone) { - // validate_miner_transaction will check balance proof and asset surjection proof - // and, as a side effect, it MAY recalculate base_reward, consider redisign, TODO -- sowle TIME_MEASURE_START_PD(validate_miner_transaction_time); - if (!validate_miner_transaction(bl, cumulative_block_size, fee_summary, base_reward, already_generated_coins)) // TODO @#@# base_reward will be calculated once again, consider refactoring + if (!validate_miner_transaction(bl.miner_tx, fee_summary, block_reward_without_fee)) { LOG_PRINT_L0("Block with id: " << id << " have wrong miner transaction"); @@ -6678,6 +6676,7 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt ////////////////////////////////////////////////////////////////////////// //etc + boost::multiprecision::uint128_t already_generated_coins = m_db_blocks.size() ? m_db_blocks.back()->already_generated_coins : 0; if (already_generated_coins < burned_coins) { LOG_ERROR("Condition failed: already_generated_coins(" << already_generated_coins << ") >= burned_coins(" << burned_coins << ")"); @@ -6685,7 +6684,7 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt bvc.m_verification_failed = true; return false; } - bei.already_generated_coins = already_generated_coins - burned_coins + base_reward; + bei.already_generated_coins = already_generated_coins - burned_coins + block_reward_without_fee; if (bei.bl.miner_tx.version >= TRANSACTION_VERSION_POST_HF4) { bei.already_generated_coins -= fee_summary; @@ -6763,9 +6762,9 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt timestamp_str_entry << ", block ts: " << bei.bl.timestamp << " (diff: " << std::showpos << ts_diff << "s)"; } if(bei.bl.miner_tx.version >= TRANSACTION_VERSION_POST_HF4) - block_reward_entry << "block reward: " << print_money_brief(base_reward) << ", fee burnt: " << print_money_brief(fee_summary); + block_reward_entry << "block reward: " << print_money_brief(block_reward_without_fee) << ", fee burnt: " << print_money_brief(fee_summary); else - block_reward_entry << "block reward: " << print_money_brief(base_reward + fee_summary) << " (" << print_money_brief(base_reward) << " + " << print_money_brief(fee_summary) << ")"; + block_reward_entry << "block reward: " << print_money_brief(block_reward_without_fee + fee_summary) << " (" << print_money_brief(block_reward_without_fee) << " + " << print_money_brief(fee_summary) << ")"; //explanation of this code will be provided later with public announce set_lost_tx_unmixable_for_height(bei.height); diff --git a/src/currency_core/blockchain_storage.h b/src/currency_core/blockchain_storage.h index babebf89..19bd0205 100644 --- a/src/currency_core/blockchain_storage.h +++ b/src/currency_core/blockchain_storage.h @@ -340,7 +340,8 @@ namespace currency uint64_t get_last_timestamps_check_window_median() const; uint64_t get_last_n_blocks_timestamps_median(size_t n) const; bool prevalidate_alias_info(const transaction& tx, const extra_alias_entry& eae); - bool validate_miner_transaction(const block& b, size_t cumulative_block_size, uint64_t fee, uint64_t& base_reward, const boost::multiprecision::uint128_t& already_generated_coins) const; + bool calculate_block_reward_for_next_top_block(size_t next_block_cumulative_size, uint64_t& block_reward_without_fee) const; + bool validate_miner_transaction(const transaction& miner_tx, uint64_t fee, uint64_t block_reward_without_fee) const; performnce_data& get_performnce_data()const; bool validate_instance(const std::string& path); bool is_tx_expired(const transaction& tx) const; diff --git a/tests/core_tests/block_reward.cpp b/tests/core_tests/block_reward.cpp index f4672ff1..0aff096f 100644 --- a/tests/core_tests/block_reward.cpp +++ b/tests/core_tests/block_reward.cpp @@ -91,13 +91,16 @@ bool block_template_against_txs_size::c1(currency::core& c, size_t ev_index, con CHECK_AND_ASSERT_MES(r, false, "create_block_template failed, txs_total_size = " << txs_total_size); CHECK_AND_ASSERT_MES(height == top_block_height + 1, false, "Incorrect height: " << height << ", expected: " << top_block_height + 1 << ", txs_total_size = " << txs_total_size); - uint64_t base_reward = 0; + uint64_t block_reward_without_fee = 0; size_t cumulative_block_size = txs_total_size; size_t coinbase_blob_size = get_object_blobsize(b.miner_tx); if (coinbase_blob_size > CURRENCY_COINBASE_BLOB_RESERVED_SIZE) cumulative_block_size += coinbase_blob_size; - r = bcs.validate_miner_transaction(b, cumulative_block_size, g_block_txs_fee, base_reward, bcs.total_coins()); + + r = bcs.calculate_block_reward_for_next_top_block(cumulative_block_size, block_reward_without_fee); + CHECK_AND_ASSERT_MES(r, false, "calculate_block_reward_for_next_top_block failed"); + r = bcs.validate_miner_transaction(b.miner_tx, g_block_txs_fee, block_reward_without_fee); CHECK_AND_ASSERT_MES(r, false, "validate_miner_transaction failed, txs_total_size = " << txs_total_size); uint64_t generated_coins = get_outs_money_amount(b.miner_tx) - (is_pos != 0 ? boost::get(b.miner_tx.vout.back()).amount : 0) - g_block_txs_fee / 2; From e38dfc1472007edf0944037ea99c9dc279e65410 Mon Sep 17 00:00:00 2001 From: sowle Date: Sat, 4 May 2024 02:35:51 +0200 Subject: [PATCH 170/184] coretests: hardfork_4_pop_tx_from_global_index test added to cover uncovered areas in pop_transaction_from_global_index() --- src/currency_core/blockchain_storage.cpp | 22 ++++----- src/rpc/core_rpc_server_commands_defs.h | 2 + tests/core_tests/chaingen_main.cpp | 1 + tests/core_tests/hard_fork_4.cpp | 57 ++++++++++++++++++++++++ tests/core_tests/hard_fork_4.h | 7 +++ 5 files changed, 78 insertions(+), 11 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 5941c0fe..9fe5c021 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -3773,7 +3773,6 @@ bool blockchain_storage::pop_transaction_from_global_index(const transaction& tx CHECK_AND_ASSERT_MES(res, false, "Internal error: multisig out not found, multisig_out_id " << multisig_out_id << "in multisig outs index"); } VARIANT_CASE_CONST(tx_out_zarcanum, toz) - // TODO: @#@# temporary comment this section and make a test for the corresponding bug if (!do_pop_output(i, 0)) return false; VARIANT_CASE_THROW_ON_OTHER(); @@ -4291,16 +4290,17 @@ bool blockchain_storage::process_blockchain_tx_extra(const transaction& tx, cons bool blockchain_storage::get_outs_index_stat(outs_index_stat& outs_stat) const { CRITICAL_REGION_LOCAL(m_read_lock); - outs_stat.amount_0_001 = m_db_outputs.get_item_size(COIN / 1000); - outs_stat.amount_0_01 = m_db_outputs.get_item_size(COIN / 100); - outs_stat.amount_0_1 = m_db_outputs.get_item_size(COIN / 10); - outs_stat.amount_1 = m_db_outputs.get_item_size(COIN); - outs_stat.amount_10 = m_db_outputs.get_item_size(COIN * 10); - outs_stat.amount_100 = m_db_outputs.get_item_size(COIN * 100); - outs_stat.amount_1000 = m_db_outputs.get_item_size(COIN * 1000); - outs_stat.amount_10000 = m_db_outputs.get_item_size(COIN * 10000); - outs_stat.amount_100000 = m_db_outputs.get_item_size(COIN * 100000); - outs_stat.amount_1000000 = m_db_outputs.get_item_size(COIN * 1000000); + outs_stat.amount_0 = m_db_outputs.get_item_size(0); + outs_stat.amount_0_001 = m_db_outputs.get_item_size(COIN / 1000); + outs_stat.amount_0_01 = m_db_outputs.get_item_size(COIN / 100); + outs_stat.amount_0_1 = m_db_outputs.get_item_size(COIN / 10); + outs_stat.amount_1 = m_db_outputs.get_item_size(COIN); + outs_stat.amount_10 = m_db_outputs.get_item_size(COIN * 10); + outs_stat.amount_100 = m_db_outputs.get_item_size(COIN * 100); + outs_stat.amount_1000 = m_db_outputs.get_item_size(COIN * 1000); + outs_stat.amount_10000 = m_db_outputs.get_item_size(COIN * 10000); + outs_stat.amount_100000 = m_db_outputs.get_item_size(COIN * 100000); + outs_stat.amount_1000000 = m_db_outputs.get_item_size(COIN * 1000000); return true; } //------------------------------------------------------------------ diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 6ccd37ba..f088ccc6 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -661,6 +661,7 @@ namespace currency //----------------------------------------------- struct outs_index_stat { + uint64_t amount_0; uint64_t amount_0_001; uint64_t amount_0_01; uint64_t amount_0_1; @@ -673,6 +674,7 @@ namespace currency uint64_t amount_1000000; BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(amount_0) KV_SERIALIZE(amount_0_001) KV_SERIALIZE(amount_0_01) KV_SERIALIZE(amount_0_1) diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index 01f5c9cc..2287d612 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -1249,6 +1249,7 @@ int main(int argc, char* argv[]) GENERATE_AND_PLAY_HF(hard_fork_4_consolidated_txs, "3-*"); GENERATE_AND_PLAY_HF(hardfork_4_wallet_transfer_with_mandatory_mixins, "3-*"); GENERATE_AND_PLAY(hardfork_4_wallet_sweep_bare_outs); + GENERATE_AND_PLAY_HF(hardfork_4_pop_tx_from_global_index, "4-*"); // atomics GENERATE_AND_PLAY(atomic_simple_test); diff --git a/tests/core_tests/hard_fork_4.cpp b/tests/core_tests/hard_fork_4.cpp index 2349167d..396ac2ec 100644 --- a/tests/core_tests/hard_fork_4.cpp +++ b/tests/core_tests/hard_fork_4.cpp @@ -439,3 +439,60 @@ bool hardfork_4_wallet_sweep_bare_outs::c1(currency::core& c, size_t ev_index, c return true; } + +//------------------------------------------------------------------------------ + +hardfork_4_pop_tx_from_global_index::hardfork_4_pop_tx_from_global_index() +{ + REGISTER_CALLBACK_METHOD(hardfork_4_pop_tx_from_global_index, c1); +} + +bool hardfork_4_pop_tx_from_global_index::generate(std::vector& events) const +{ + // Test idea: make sure that pop_transaction_from_global_index works for tx_out_zarcanum as well (m_db_outputs is consistent after pop_transaction_from_global_index() call) + + uint64_t ts = test_core_time::get_time(); + m_accounts.resize(TOTAL_ACCS_COUNT); + account_base& miner_acc = m_accounts[MINER_ACC_IDX]; miner_acc.generate(); miner_acc.set_createtime(ts); + account_base& alice_acc = m_accounts[ALICE_ACC_IDX]; alice_acc.generate(); alice_acc.set_createtime(ts); + + MAKE_GENESIS_BLOCK(events, blk_0, miner_acc, ts); + DO_CALLBACK(events, "configure_core"); // default configure_core callback will initialize core runtime config with m_hardforks + REWIND_BLOCKS_N(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + + DO_CALLBACK_PARAMS(events, "check_hardfork_active", static_cast(ZANO_HARDFORK_04_ZARCANUM)); + + MAKE_NEXT_BLOCK(events, blk_1a, blk_0r, miner_acc); // blk_1a will be the alt chain + DO_CALLBACK_PARAMS(events, "check_top_block", params_top_block(blk_1a)); // make sure now it's the main chain + + MAKE_NEXT_BLOCK(events, blk_1, blk_0r, miner_acc); + + MAKE_NEXT_BLOCK(events, blk_2, blk_1, miner_acc); // this should trigger chain switching + DO_CALLBACK_PARAMS(events, "check_top_block", params_top_block(blk_2)); // make sure it did + + // during switching to the alternative chain pop_block_from_blockchain() -> ... -> pop_transaction_from_global_index() will be called + // but abort_transaction() will not, meaning m_db_outputs will be in incorrect state, if pop_transaction_from_global_index() hasn't properly pop all outs + // this will be checked later in c1 + + DO_CALLBACK(events, "c1"); + return true; +} + +bool hardfork_4_pop_tx_from_global_index::c1(currency::core& c, size_t ev_index, const std::vector& events) +{ + auto& bcs = c.get_blockchain_storage(); + bool r = false; + + //currency::outs_index_stat outs_stat{}; + //bcs.get_outs_index_stat(outs_stat); // 24 - bad, 22 - good + + COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES_BY_AMOUNT::response res; + COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES_BY_AMOUNT::request req; + req.amount = 0; + req.i = 22; + CHECK_AND_ASSERT_MES(!bcs.get_global_index_details(req, res), false, "gindex 22 exists which is unexpected"); + req.i = 21; + CHECK_AND_ASSERT_MES(bcs.get_global_index_details(req, res), false, "gindex 21 does not exist which is unexpected"); + + return true; +} diff --git a/tests/core_tests/hard_fork_4.h b/tests/core_tests/hard_fork_4.h index b3684f80..5e9014b8 100644 --- a/tests/core_tests/hard_fork_4.h +++ b/tests/core_tests/hard_fork_4.h @@ -42,3 +42,10 @@ struct hardfork_4_wallet_sweep_bare_outs : public wallet_test bool generate(std::vector& events) const; bool c1(currency::core& c, size_t ev_index, const std::vector& events); }; + +struct hardfork_4_pop_tx_from_global_index : public wallet_test +{ + hardfork_4_pop_tx_from_global_index(); + bool generate(std::vector& events) const; + bool c1(currency::core& c, size_t ev_index, const std::vector& events); +}; From 81ac6cf333a49bb12c2ade4f3a7af1db1e7c13c1 Mon Sep 17 00:00:00 2001 From: sowle Date: Sat, 4 May 2024 03:15:13 +0200 Subject: [PATCH 171/184] removed redundant hardfork check from check_tx_inputs(), because it's already in validate_tx_for_hardfork_specific_terms() --- src/currency_core/blockchain_storage.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 9fe5c021..b2c60cf2 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -4908,12 +4908,6 @@ bool blockchain_storage::check_tx_inputs(const transaction& tx, const crypto::ha } VARIANT_CASE_CONST(txin_htlc, in_htlc) { - if (!is_hardfork_active(3)) // @#@ CZ, consider removing this to validate_tx_for_hardfork_specific_terms - { - LOG_ERROR("Error: Transaction with txin_htlc before hardfork 3 (before height " << m_core_runtime_config.hard_forks.get_str_height_the_hardfork_active_after(3) << ")"); - return false; - } - CHECK_AND_ASSERT_MES(in_htlc.key_offsets.size(), false, "Empty in_to_key.key_offsets for input #" << sig_index << " tx: " << tx_prefix_hash); if (!local_check_key_image(in_htlc.k_image)) return false; From 702817e3514b877e2fabacb3ce6fa891d951ff47 Mon Sep 17 00:00:00 2001 From: sowle Date: Sat, 4 May 2024 03:16:28 +0200 Subject: [PATCH 172/184] fixed a potential issue in check_ms_input() --- src/currency_core/blockchain_storage.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index b2c60cf2..d9b689fa 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -5189,9 +5189,7 @@ bool blockchain_storage::check_ms_input(const transaction& tx, size_t in_index, LOC_CHK(tx.signatures.size() > in_index, "ms input index is out of signatures container bounds, signatures.size() = " << tx.signatures.size()); - //@#@ VARIANT_SWITCH_BEGIN(tx.signatures[in_index]); - VARIANT_CASE_CONST(void_sig, v); VARIANT_CASE_CONST(NLSAG_sig, sig) { const std::vector& input_signatures = sig.s; @@ -5236,9 +5234,9 @@ bool blockchain_storage::check_ms_input(const transaction& tx, size_t in_index, LOC_CHK(r, "failed to check extra signature for last out with TX_FLAG_SIGNATURE_MODE_SEPARATE"); } } - VARIANT_CASE_CONST(ZC_sig, s); - //@#@ - //TODO: don't forget about need_to_check_extra_sign + VARIANT_CASE_OTHER() + LOG_ERROR("Unexpected signature type: " << VARIANT_OBJ_TYPENAME); + return false; VARIANT_SWITCH_END(); From b3c44598b09e152be6646a33c6b608be6174f5ab Mon Sep 17 00:00:00 2001 From: sowle Date: Sat, 4 May 2024 03:17:56 +0200 Subject: [PATCH 173/184] minor improvements & code cleanup --- src/currency_core/blockchain_storage.cpp | 8 ++++---- src/currency_core/blockchain_storage.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index d9b689fa..1084ee16 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -5908,7 +5908,7 @@ bool blockchain_storage::validate_tx_for_hardfork_specific_terms(const transacti return true; } //------------------------------------------------------------------ -bool blockchain_storage::validate_pos_coinbase_outs_unlock_time(const transaction& miner_tx, uint64_t staked_amount, uint64_t source_max_unlock_time)const +bool blockchain_storage::validate_pre_zarcanum_pos_coinbase_outs_unlock_time(const transaction& miner_tx, uint64_t staked_amount, uint64_t source_max_unlock_time)const { uint64_t major_unlock_time = get_tx_x_detail(miner_tx); if (major_unlock_time) @@ -5935,7 +5935,7 @@ bool blockchain_storage::validate_pos_coinbase_outs_unlock_time(const transactio for (uint64_t i = 0; i != miner_tx.vout.size(); i++) { uint64_t unlock_value = ut2.unlock_time_array[i]; - CHECK_AND_ASSERT_MES(should_unlock_value_be_treated_as_block_height(unlock_value), false, "output #" << i << " is locked by time, not buy height, which is not allowed for PoS coinbase"); + CHECK_AND_ASSERT_MES(should_unlock_value_be_treated_as_block_height(unlock_value), false, "output #" << i << " is locked by time, not by height, which is not allowed for PoS coinbase"); if (unlock_value >= source_max_unlock_time) { VARIANT_SWITCH_BEGIN(miner_tx.vout[i]); @@ -6112,8 +6112,8 @@ bool blockchain_storage::validate_pos_block(const block& b, uint64_t last_pow_h = get_last_x_block_height(false); CHECK_AND_ASSERT_MES(max_related_block_height <= last_pow_h, false, "Failed to validate coinbase in PoS block, condition failed: max_related_block_height(" << max_related_block_height << ") <= last_pow_h(" << last_pow_h << ")"); //let's check that coinbase amount and unlock time - r = validate_pos_coinbase_outs_unlock_time(b.miner_tx, coinstake_in.amount, source_max_unlock_time_for_pos_coinbase); - CHECK_AND_ASSERT_MES(r, false, "Failed to validate_pos_coinbase_outs_unlock_time() in miner tx, block_id = " << get_block_hash(b) + r = validate_pre_zarcanum_pos_coinbase_outs_unlock_time(b.miner_tx, coinstake_in.amount, source_max_unlock_time_for_pos_coinbase); + CHECK_AND_ASSERT_MES(r, false, "Failed to validate_pre_zarcanum_pos_coinbase_outs_unlock_time() in miner tx, block_id = " << get_block_hash(b) << "source_max_unlock_time_for_pos_coinbase=" << source_max_unlock_time_for_pos_coinbase); } else diff --git a/src/currency_core/blockchain_storage.h b/src/currency_core/blockchain_storage.h index 19bd0205..97f712e1 100644 --- a/src/currency_core/blockchain_storage.h +++ b/src/currency_core/blockchain_storage.h @@ -366,7 +366,7 @@ namespace currency uint64_t timestamp) const; bool build_stake_modifier(stake_modifier_type& sm, const alt_chain_type& alt_chain = alt_chain_type(), uint64_t split_height = 0, crypto::hash* p_last_block_hash = nullptr, uint64_t* p_last_pow_block_height = nullptr) const; - bool validate_pos_coinbase_outs_unlock_time(const transaction& miner_tx, uint64_t staked_amount, uint64_t source_max_unlock_time)const; + bool validate_pre_zarcanum_pos_coinbase_outs_unlock_time(const transaction& miner_tx, uint64_t staked_amount, uint64_t source_max_unlock_time)const; bool validate_pos_block(const block& b, const crypto::hash& id, bool for_altchain)const; bool validate_pos_block(const block& b, wide_difficulty_type basic_diff, const crypto::hash& id, bool for_altchain)const; bool validate_pos_block(const block& b, From f7aab6f3320812395355d2444056ad96bed7ca5e Mon Sep 17 00:00:00 2001 From: sowle Date: Sat, 4 May 2024 03:18:40 +0200 Subject: [PATCH 174/184] coretests: restored forgotten multisig_n_participants_seq_signing test --- tests/core_tests/chaingen_main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index 2287d612..71bb8fe1 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -977,6 +977,7 @@ int main(int argc, char* argv[]) GENERATE_AND_PLAY(multisig_out_make_and_spent_in_altchain); GENERATE_AND_PLAY(multisig_unconfirmed_transfer_and_multiple_scan_pool_calls); GENERATE_AND_PLAY(multisig_out_spent_in_altchain_case_b4); + GENERATE_AND_PLAY(multisig_n_participants_seq_signing); GENERATE_AND_PLAY(ref_by_id_basics); GENERATE_AND_PLAY(ref_by_id_mixed_inputs_types); From d52cb725d155fb91d18fbecc6c4cf1ebc26429cc Mon Sep 17 00:00:00 2001 From: sowle Date: Sat, 4 May 2024 03:24:15 +0200 Subject: [PATCH 175/184] updated macos deployment target: 10.13 -> 10.15 (required for std::filesystem) --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 843659dc..04790815 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,7 +69,7 @@ find_package(OpenSSL REQUIRED) if(APPLE) - set(CMAKE_OSX_DEPLOYMENT_TARGET 10.13) + set(CMAKE_OSX_DEPLOYMENT_TARGET 10.15) endif() set(USE_PCH FALSE CACHE BOOL "Use shared precompiled headers") From d9633d5b069041a0078b8b426d436d2a69283496 Mon Sep 17 00:00:00 2001 From: sowle Date: Sat, 4 May 2024 03:48:14 +0200 Subject: [PATCH 176/184] get_block_reward simplified ver --- src/currency_core/currency_format_utils.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index 312eff34..fd33a6b8 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -522,6 +522,7 @@ namespace currency /************************************************************************/ size_t get_max_block_size(); size_t get_max_tx_size(); + uint64_t get_block_reward(uint64_t height, size_t median_block_size, size_t current_block_size); bool get_block_reward(bool is_pos, size_t median_size, size_t current_block_size, const boost::multiprecision::uint128_t& already_generated_coins, uint64_t &reward, uint64_t height); uint64_t get_base_block_reward(uint64_t height); bool is_payment_id_size_ok(const payment_id_t& payment_id); From 455ece8cbabc74de78fdd019124d879f60373219 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Sat, 4 May 2024 05:28:48 +0300 Subject: [PATCH 177/184] === build number: 304 -> 305 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index 5e08cda4..da88897c 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 304 +#define PROJECT_VERSION_BUILD_NO 305 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From e40d9df2eca9d30fda35d6fb150663027cda09b3 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Sat, 4 May 2024 22:27:57 +0300 Subject: [PATCH 178/184] === build number: 305 -> 306 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index da88897c..7109f3be 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 305 +#define PROJECT_VERSION_BUILD_NO 306 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From c6488622ebeb12849072014a1f0a450b8c53aaef Mon Sep 17 00:00:00 2001 From: sowle Date: Sun, 5 May 2024 22:19:16 +0200 Subject: [PATCH 179/184] temporary fix for ZC outs validation in validate_alt_block_input() --- src/currency_core/blockchain_storage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 1084ee16..ba9e2b32 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -7432,7 +7432,7 @@ bool blockchain_storage::validate_alt_block_input(const transaction& input_tx, if (!alt_chain.empty()) { auto abg_it = alt_chain.back()->second.gindex_lookup_table.find(input_amount); - if (abg_it != alt_chain.back()->second.gindex_lookup_table.end()) + if (input_amount != 0 /* <-- TODO @#@# remove this condition after ZC outs support is implemented*/ && abg_it != alt_chain.back()->second.gindex_lookup_table.end()) { amount_touched_altchain = true; // local gindex lookup table contains last used gindex, so we can't get total number of outs From b56a0fb90c8e1fbd6c40c865fc9d3bde173b5351 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Sun, 5 May 2024 23:25:41 +0300 Subject: [PATCH 180/184] === build number: 306 -> 307 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index 7109f3be..7eaa11b0 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 306 +#define PROJECT_VERSION_BUILD_NO 307 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From c68f841fdbb04aae56a292e16da39ad16b356958 Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 7 May 2024 16:42:37 +0200 Subject: [PATCH 181/184] ui update --- src/gui/qt-daemon/layout | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/qt-daemon/layout b/src/gui/qt-daemon/layout index 1f2ce4ce..a1d86d01 160000 --- a/src/gui/qt-daemon/layout +++ b/src/gui/qt-daemon/layout @@ -1 +1 @@ -Subproject commit 1f2ce4ce600e97b8e21e8f8674f97cb89a0e875f +Subproject commit a1d86d01aaeb13bb013c8b2539e01967de9b5f04 From 4c2553a4829c2303970f080b9d8c3bf689e3287a Mon Sep 17 00:00:00 2001 From: zano build machine Date: Tue, 7 May 2024 17:43:07 +0300 Subject: [PATCH 182/184] === build number: 307 -> 308 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index 7eaa11b0..d5a80407 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 307 +#define PROJECT_VERSION_BUILD_NO 308 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" From fd25b5a8e5f5e8229d5fc1c94d2b9fde6182861f Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 8 May 2024 01:03:46 +0400 Subject: [PATCH 183/184] attempt to fix wallet exception on alt blocks --- src/wallet/wallet2.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 8ac646ca..ecda7231 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -522,6 +522,13 @@ void wallet2::add_to_last_zc_global_indexs(uint64_t h, uint64_t last_zc_output_i } else { + //@#@ +#ifdef _DEBUG + if (m_last_zc_global_indexs.begin()->second > last_zc_output_index) + { + LOG_ERROR("!!!!!!!!!!!!!!!!!"); + } +#endif //equals, same h but new last_zc_output_index, just update it, should be always bigger then prev WLT_THROW_IF_FALSE_WITH_CODE(m_last_zc_global_indexs.begin()->second <= last_zc_output_index, "condition m_last_zc_global_indexs.begin()->second " << m_last_zc_global_indexs.begin()->second << " <= last_zc_output_index " << last_zc_output_index << " failed", API_RETURN_CODE_INTERNAL_ERROR); @@ -3072,6 +3079,12 @@ void wallet2::detach_blockchain(uint64_t including_height) ++it; } + //detach in m_last_zc_global_indexs + while (m_last_zc_global_indexs.size() && including_height <= m_last_zc_global_indexs.begin()->first ) + { + m_last_zc_global_indexs.erase(m_last_zc_global_indexs.begin()); + } + //asset descriptors handle_rollback_events(including_height); From e809d821a1b52a0d4df38c3d406d772a3123210b Mon Sep 17 00:00:00 2001 From: zano build machine Date: Wed, 8 May 2024 02:44:25 +0300 Subject: [PATCH 184/184] === build number: 308 -> 309 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index d5a80407..6f6c9bad 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 308 +#define PROJECT_VERSION_BUILD_NO 309 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]"