From 6a7c29be51d55e8568ceba27f43e0a331a2faeec Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Tue, 26 Nov 2024 21:51:23 +0400 Subject: [PATCH 01/82] Fix #482 suggested by @jeffro256 --- src/currency_core/basic_pow_helpers.cpp | 2 +- src/currency_core/basic_pow_helpers.h | 10 ++++++---- src/stratum/stratum_server.cpp | 6 +++--- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/currency_core/basic_pow_helpers.cpp b/src/currency_core/basic_pow_helpers.cpp index b7ee80ca..d029ee19 100644 --- a/src/currency_core/basic_pow_helpers.cpp +++ b/src/currency_core/basic_pow_helpers.cpp @@ -81,7 +81,7 @@ namespace currency { blobdata bd = get_block_hashing_blob(b); - access_nonce_in_block_blob(bd) = 0; + set_nonce_to_blockblob(bd, 0); return crypto::cn_fast_hash(bd.data(), bd.size()); } //--------------------------------------------------------------- diff --git a/src/currency_core/basic_pow_helpers.h b/src/currency_core/basic_pow_helpers.h index 32ded457..e9cc6ca5 100644 --- a/src/currency_core/basic_pow_helpers.h +++ b/src/currency_core/basic_pow_helpers.h @@ -34,13 +34,15 @@ namespace currency void get_block_longhash(const block& b, crypto::hash& res); crypto::hash get_block_longhash(const block& b); - inline uint64_t& access_nonce_in_block_blob(blobdata& bd) + inline uint64_t get_nonce_from_blockblob(const blobdata& bd) { - return *reinterpret_cast(&bd[CURRENCY_MINER_BLOCK_BLOB_NONCE_OFFSET]); + uint64_t nonce = 0; + std::memcpy(&nonce, &bd[CURRENCY_MINER_BLOCK_BLOB_NONCE_OFFSET], sizeof(nonce)); + return nonce; } - inline const uint64_t& access_nonce_in_block_blob(const blobdata& bd) + inline void set_nonce_to_blockblob(blobdata& bd, const uint64_t nonce) { - return *reinterpret_cast(&bd[CURRENCY_MINER_BLOCK_BLOB_NONCE_OFFSET]); + std::memcpy(&bd[CURRENCY_MINER_BLOCK_BLOB_NONCE_OFFSET], &nonce, sizeof(nonce)); } } \ No newline at end of file diff --git a/src/stratum/stratum_server.cpp b/src/stratum/stratum_server.cpp index 4cfa686a..95729637 100644 --- a/src/stratum/stratum_server.cpp +++ b/src/stratum/stratum_server.cpp @@ -402,11 +402,11 @@ namespace #endif m_blockchain_last_block_id = top_block_id; - m_block_template_hash_blob = get_block_hashing_blob(m_block_template); - if (access_nonce_in_block_blob(m_block_template_hash_blob) != 0) + m_block_template_hash_blob = get_block_hashing_blob(m_block_template); + if (get_nonce_from_blockblob(m_block_template_hash_blob) != 0) { LOG_PRINT_RED("non-zero nonce in generated block template", LOG_LEVEL_0); - access_nonce_in_block_blob(m_block_template_hash_blob) = 0; + set_nonce_to_blockblob(m_block_template_hash_blob, 0); } m_prev_block_template_ethash = m_block_template_ethash; m_block_template_ethash = crypto::cn_fast_hash(m_block_template_hash_blob.data(), m_block_template_hash_blob.size()); From 9763548fa8f9ee9f470465a1c71ea1aaf3a7c787 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 27 Nov 2024 15:34:34 +0400 Subject: [PATCH 02/82] add runtime check for buffer size --- src/currency_core/basic_pow_helpers.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/currency_core/basic_pow_helpers.h b/src/currency_core/basic_pow_helpers.h index e9cc6ca5..62ba7721 100644 --- a/src/currency_core/basic_pow_helpers.h +++ b/src/currency_core/basic_pow_helpers.h @@ -37,12 +37,14 @@ namespace currency inline uint64_t get_nonce_from_blockblob(const blobdata& bd) { uint64_t nonce = 0; + CHECK_AND_ASSERT_MES(bd.size() >= CURRENCY_MINER_BLOCK_BLOB_NONCE_OFFSET + sizeof(nonce), 0, "Unexpected block buffer size = " << bd.size()); std::memcpy(&nonce, &bd[CURRENCY_MINER_BLOCK_BLOB_NONCE_OFFSET], sizeof(nonce)); return nonce; } inline void set_nonce_to_blockblob(blobdata& bd, const uint64_t nonce) { + CHECK_AND_ASSERT_MES(bd.size() >= CURRENCY_MINER_BLOCK_BLOB_NONCE_OFFSET + sizeof(nonce), void(), "Unexpected block buffer size = " << bd.size()); std::memcpy(&bd[CURRENCY_MINER_BLOCK_BLOB_NONCE_OFFSET], &nonce, sizeof(nonce)); } } \ No newline at end of file From b903d84cac79c151f444791628d5c6fc5d2692b8 Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 3 Dec 2024 02:29:20 +0100 Subject: [PATCH 03/82] added https support to interruptible_http_client --- contrib/epee/include/net/http_client.h | 52 +++++++++++++++++++------- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/contrib/epee/include/net/http_client.h b/contrib/epee/include/net/http_client.h index b0c8838a..6facadb4 100644 --- a/contrib/epee/include/net/http_client.h +++ b/contrib/epee/include/net/http_client.h @@ -899,19 +899,25 @@ namespace epee template bool invoke_request(const std::string& url, t_transport& tr, unsigned int timeout, const http_response_info** ppresponse_info, const std::string& method = "GET", const std::string& body = std::string(), const fields_list& additional_params = fields_list()) { - http::url_content u_c; - bool res = parse_url(url, u_c); + http::url_content u_c{}; + bool r = parse_url(url, u_c); + CHECK_AND_ASSERT_MES(!tr.is_connected() && r && !u_c.host.empty(), false, "failed to parse url: " << url); + r = invoke_request(u_c, tr, timeout, ppresponse_info, method, body, additional_params); + return r; + } + template + bool invoke_request(const http::url_content& u_c, t_transport& tr, unsigned int timeout, const http_response_info** ppresponse_info, const std::string& method = "GET", const std::string& body = std::string(), const fields_list& additional_params = fields_list()) + { if (!tr.is_connected() && !u_c.host.empty()) { - CHECK_AND_ASSERT_MES(res, false, "failed to parse url: " << url); + int port = static_cast(u_c.port); + if (!port) + port = 80;//default for http - if (!u_c.port) - u_c.port = 80;//default for http - - if (!tr.connect(u_c.host, static_cast(u_c.port), timeout)) + if (!tr.connect(u_c.host, port, timeout)) { - LOG_PRINT_L2("invoke_request: cannot connect to " << u_c.host << ":" << u_c.port); + LOG_PRINT_L2("invoke_request: cannot connect to " << u_c.host << ":" << port); return false; } } @@ -937,14 +943,20 @@ namespace epee } }; - class interruptible_http_client : public http_simple_client + class interruptible_http_client : virtual public http_simple_client, virtual public https_simple_client { std::shared_ptr m_pcb; bool m_permanent_error = false; + bool m_ssl = false; - virtual bool handle_target_data(std::string& piece_of_transfer) + // class i_target_handler + virtual bool handle_target_data(std::string& piece_of_transfer) override { - bool r = m_pcb->do_call(piece_of_transfer, m_len_in_summary, m_len_in_summary - m_len_in_remain); + bool r = false; + if (m_ssl) + r = m_pcb->do_call(piece_of_transfer, https_simple_client::m_len_in_summary, https_simple_client::m_len_in_summary - https_simple_client::m_len_in_remain); + else + r = m_pcb->do_call(piece_of_transfer, http_simple_client::m_len_in_summary, http_simple_client::m_len_in_summary - http_simple_client::m_len_in_remain); piece_of_transfer.clear(); return r; } @@ -955,10 +967,24 @@ namespace epee { m_pcb.reset(new idle_handler(cb)); const http_response_info* p_hri = nullptr; - bool r = invoke_request(url, *this, timeout, &p_hri, method, body, additional_params); + http::url_content uc{}; + if (!parse_url(url, uc)) + { + LOG_PRINT_L0("HTTP request to " << url << " failed because the URL couldn't be parsed."); + m_permanent_error = true; + return false; + } + + bool r = false; + m_ssl = uc.schema == "https"; + if (m_ssl) + r = invoke_request(uc, static_cast(*this), timeout, &p_hri, method, body, additional_params); + else + r = invoke_request(uc, static_cast(*this), timeout, &p_hri, method, body, additional_params); + if (p_hri && !(p_hri->m_response_code >= 200 && p_hri->m_response_code < 300)) { - LOG_PRINT_L0("HTTP request to " << url << " failed with code: " << p_hri->m_response_code); + LOG_PRINT_L0(boost::to_upper_copy(uc.schema) << " request to " << url << " failed with code: " << p_hri->m_response_code); m_permanent_error = true; return false; } From 2e7359437825576c35c0777b1893f2fe74a4e706 Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 3 Dec 2024 02:30:09 +0100 Subject: [PATCH 04/82] predownload https test --- src/common/pre_download.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/pre_download.h b/src/common/pre_download.h index 3c46373f..6e4de659 100644 --- a/src/common/pre_download.h +++ b/src/common/pre_download.h @@ -22,7 +22,7 @@ namespace tools #ifndef TESTNET static constexpr pre_download_entry c_pre_download_mdbx = { "http://95.217.42.247/pre-download/zano_mdbx_95_2892700.pak", "68e819cd119e4af1b81f1852e42978d662f1e6355124352f3e835db32b5a8230", 6414724487, 10468823040 }; - static constexpr pre_download_entry c_pre_download_lmdb = { "http://95.217.42.247/pre-download/zano_lmdb_95_2892700.pak", "605eb4eb0903aa7b3a2a046514ef349d45c7de31d2702fd9dc104ca65705d6eb", 7860127140, 10204872704 }; + static constexpr pre_download_entry c_pre_download_lmdb = { "https://f005.backblazeb2.com/file/zano-predownload/zano_lmdb_95_2892700.pak", "605eb4eb0903aa7b3a2a046514ef349d45c7de31d2702fd9dc104ca65705d6eb", 7860127140, 10204872704 }; #else static constexpr pre_download_entry c_pre_download_mdbx = { "", "", 0, 0 }; static constexpr pre_download_entry c_pre_download_lmdb = { "", "", 0, 0 }; From be44020b1c7e7a4559c3cc67f47c7f930892da63 Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 3 Dec 2024 02:31:06 +0100 Subject: [PATCH 05/82] win32: CloseHandle removed from console handler stop() to avoid exception on exit in dbg --- contrib/epee/include/console_handler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/epee/include/console_handler.h b/contrib/epee/include/console_handler.h index 2d098e32..2bc53f3f 100644 --- a/contrib/epee/include/console_handler.h +++ b/contrib/epee/include/console_handler.h @@ -81,7 +81,7 @@ namespace epee m_run.store(false, std::memory_order_relaxed); #if defined(WIN32) - ::CloseHandle(::GetStdHandle(STD_INPUT_HANDLE)); + // ::CloseHandle(::GetStdHandle(STD_INPUT_HANDLE)); -- commented out by sowle, I belive we don't need to close this handle here #endif m_request_cv.notify_one(); From 9cfa03d119296b2f4aa748f4b65a2d03ae23f602 Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 3 Dec 2024 03:06:02 +0100 Subject: [PATCH 06/82] 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 7cd0e5e5..57c75007 160000 --- a/src/gui/qt-daemon/layout +++ b/src/gui/qt-daemon/layout @@ -1 +1 @@ -Subproject commit 7cd0e5e54a0d692ea819b9653f60a1cd5512dc2b +Subproject commit 57c750075b7b5f3338991b24c6a1d18ec5ca5f01 From 1701b97f86d7d390685561360389849da25d4309 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Tue, 3 Dec 2024 05:07:03 +0300 Subject: [PATCH 07/82] === build number: 367 -> 368 === --- 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 fc037031..79da7040 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "1" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 367 +#define PROJECT_VERSION_BUILD_NO 368 #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 95dabbe63a580f7d68094b32b053e90aa878a6b5 Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 4 Dec 2024 02:46:45 +0100 Subject: [PATCH 08/82] fixed url parse error for RPCs --- contrib/epee/include/net/http_client.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/epee/include/net/http_client.h b/contrib/epee/include/net/http_client.h index 6facadb4..65a2507e 100644 --- a/contrib/epee/include/net/http_client.h +++ b/contrib/epee/include/net/http_client.h @@ -901,7 +901,7 @@ namespace epee { http::url_content u_c{}; bool r = parse_url(url, u_c); - CHECK_AND_ASSERT_MES(!tr.is_connected() && r && !u_c.host.empty(), false, "failed to parse url: " << url); + CHECK_AND_ASSERT_MES(tr.is_connected() || u_c.host.empty() || r, false, "failed to parse url: " << url); r = invoke_request(u_c, tr, timeout, ppresponse_info, method, body, additional_params); return r; } From e747b11d4430d80ec2abf4fee8d5d67c1ef08596 Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 4 Dec 2024 02:49:28 +0100 Subject: [PATCH 09/82] implemented https multiple attempts support in interruptible_http_client (using another approach, http_https_simple_client_wrapper introduced) --- contrib/epee/include/net/http_client.h | 49 ++++++++++++++++++-------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/contrib/epee/include/net/http_client.h b/contrib/epee/include/net/http_client.h index 65a2507e..9c658e43 100644 --- a/contrib/epee/include/net/http_client.h +++ b/contrib/epee/include/net/http_client.h @@ -943,30 +943,50 @@ namespace epee } }; - class interruptible_http_client : virtual public http_simple_client, virtual public https_simple_client - { - std::shared_ptr m_pcb; - bool m_permanent_error = false; - bool m_ssl = false; + class http_https_simple_client_wrapper : virtual public http_simple_client, virtual public https_simple_client + { + public: + http_https_simple_client_wrapper(bool is_ssl, std::shared_ptr ihb_cb) + : m_ssl(is_ssl) + , m_ihb_cb(ihb_cb) + {} + + bool invoke_request(const http::url_content& u_c, unsigned int timeout, const http_response_info** ppresponse_info, const std::string& method = "GET", const std::string& body = std::string(), const fields_list& additional_params = fields_list()) + { + bool r = false; + if (m_ssl) + r = epee::net_utils::http::invoke_request(u_c, static_cast(*this), timeout, ppresponse_info, method, body, additional_params); + else + r = epee::net_utils::http::invoke_request(u_c, static_cast(*this), timeout, ppresponse_info, method, body, additional_params); + return r; + } + + private: // class i_target_handler virtual bool handle_target_data(std::string& piece_of_transfer) override { bool r = false; if (m_ssl) - r = m_pcb->do_call(piece_of_transfer, https_simple_client::m_len_in_summary, https_simple_client::m_len_in_summary - https_simple_client::m_len_in_remain); + r = m_ihb_cb->do_call(piece_of_transfer, https_simple_client::m_len_in_summary, https_simple_client::m_len_in_summary - https_simple_client::m_len_in_remain); else - r = m_pcb->do_call(piece_of_transfer, http_simple_client::m_len_in_summary, http_simple_client::m_len_in_summary - http_simple_client::m_len_in_remain); + r = m_ihb_cb->do_call(piece_of_transfer, http_simple_client::m_len_in_summary, http_simple_client::m_len_in_summary - http_simple_client::m_len_in_remain); piece_of_transfer.clear(); return r; } + bool m_ssl; + std::shared_ptr m_ihb_cb; + }; + + + class interruptible_http_client + { + bool m_permanent_error = false; public: template bool invoke_cb(callback_t cb, const std::string& url, uint64_t timeout, const std::string& method = "GET", const std::string& body = std::string(), const fields_list& additional_params = fields_list()) { - m_pcb.reset(new idle_handler(cb)); - const http_response_info* p_hri = nullptr; http::url_content uc{}; if (!parse_url(url, uc)) { @@ -974,13 +994,12 @@ namespace epee m_permanent_error = true; return false; } + bool is_ssl = uc.schema == "https"; - bool r = false; - m_ssl = uc.schema == "https"; - if (m_ssl) - r = invoke_request(uc, static_cast(*this), timeout, &p_hri, method, body, additional_params); - else - r = invoke_request(uc, static_cast(*this), timeout, &p_hri, method, body, additional_params); + http_https_simple_client_wrapper wrapper(is_ssl, std::make_shared>(cb)); + + const http_response_info* p_hri = nullptr; + bool r = wrapper.invoke_request(uc, timeout, &p_hri, method, body, additional_params); if (p_hri && !(p_hri->m_response_code >= 200 && p_hri->m_response_code < 300)) { From 504b4a2ad8e0096a95cb4b87fe5c32f6f76ca0fe Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 4 Dec 2024 16:19:47 +0100 Subject: [PATCH 10/82] ui update, PR 134 --- 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 57c75007..f6e3e061 160000 --- a/src/gui/qt-daemon/layout +++ b/src/gui/qt-daemon/layout @@ -1 +1 @@ -Subproject commit 57c750075b7b5f3338991b24c6a1d18ec5ca5f01 +Subproject commit f6e3e0611f2100c6d9e76631a9fcfeb60e82d6d6 From 192ad1382c6c61ae93d79c757bdda72fc1f17b2d Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 4 Dec 2024 16:25:17 +0100 Subject: [PATCH 11/82] get_connectivity_status: is_remote_node_mode flag implemented --- src/wallet/view_iface.h | 4 +++- src/wallet/wallets_manager.cpp | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/wallet/view_iface.h b/src/wallet/view_iface.h index dce4b5ee..91af1f9e 100644 --- a/src/wallet/view_iface.h +++ b/src/wallet/view_iface.h @@ -484,12 +484,14 @@ public: bool is_online; bool last_daemon_is_disconnected; bool is_server_busy; + bool is_remote_node_mode; uint64_t last_proxy_communicate_timestamp; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(is_online) - KV_SERIALIZE(is_server_busy) KV_SERIALIZE(last_daemon_is_disconnected) + KV_SERIALIZE(is_server_busy) + KV_SERIALIZE(is_remote_node_mode) KV_SERIALIZE(last_proxy_communicate_timestamp) END_KV_SERIALIZE_MAP() }; diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index 8859ec8d..b51f929f 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -1635,10 +1635,11 @@ bool wallets_manager::get_is_remote_daemon_connected() std::string wallets_manager::get_connectivity_status() { - view::general_connectivity_info gci = AUTO_VAL_INIT(gci); + view::general_connectivity_info gci{}; gci.is_online = get_is_remote_daemon_connected(); gci.last_daemon_is_disconnected = m_pproxy_diganostic_info->last_daemon_is_disconnected; gci.is_server_busy = m_pproxy_diganostic_info->is_busy; + gci.is_remote_node_mode = m_remote_node_mode; gci.last_proxy_communicate_timestamp = m_rpc_proxy->get_last_success_interract_time(); return epee::serialization::store_t_to_json(gci); } From 8a7572d1b8d0ced26a2e2be83b69740c1fcb4dfd Mon Sep 17 00:00:00 2001 From: zano build machine Date: Wed, 4 Dec 2024 18:27:52 +0300 Subject: [PATCH 12/82] === build number: 368 -> 369 === --- 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 79da7040..d718b1b6 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "1" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 368 +#define PROJECT_VERSION_BUILD_NO 369 #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 8a8e5c301123f50f833c13e3e08a41f735aedb32 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 5 Dec 2024 17:56:17 +0400 Subject: [PATCH 13/82] moved docker to subfolder --- utils/docker/{ => zano-full-node}/Dockerfile | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename utils/docker/{ => zano-full-node}/Dockerfile (100%) diff --git a/utils/docker/Dockerfile b/utils/docker/zano-full-node/Dockerfile similarity index 100% rename from utils/docker/Dockerfile rename to utils/docker/zano-full-node/Dockerfile From 13f524defbb530da0c176ba9edd3448e831c0bbe Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 6 Dec 2024 05:39:18 +0100 Subject: [PATCH 14/82] tx hardfork id: wip (basic structures, miner tx creation adapted, tests adapted almost all + hard_fork_5_tx_version) --- src/connectivity_tool/conn_tool.cpp | 2 +- src/currency_core/blockchain_storage.cpp | 11 +++++-- src/currency_core/currency_basic.h | 3 ++ src/currency_core/currency_config.h | 5 ++-- src/currency_core/currency_format_utils.cpp | 16 ++++++++++- src/currency_core/currency_format_utils.h | 2 ++ tests/core_tests/chaingen.cpp | 9 ++++-- tests/core_tests/chaingen.h | 4 ++- tests/core_tests/chaingen_main.cpp | 3 ++ tests/core_tests/chaingen_tests_list.h | 1 + tests/core_tests/hard_fork_5.cpp | 32 +++++++++++++++++++++ tests/core_tests/hard_fork_5.h | 12 ++++++++ tests/core_tests/pos_block_builder.cpp | 6 ++-- tests/core_tests/transaction_tests.cpp | 14 ++++----- tests/unit_tests/test_format_utils.cpp | 5 ++-- 15 files changed, 105 insertions(+), 20 deletions(-) create mode 100644 tests/core_tests/hard_fork_5.cpp create mode 100644 tests/core_tests/hard_fork_5.h diff --git a/src/connectivity_tool/conn_tool.cpp b/src/connectivity_tool/conn_tool.cpp index a7c32892..d1f37b0a 100644 --- a/src/connectivity_tool/conn_tool.cpp +++ b/src/connectivity_tool/conn_tool.cpp @@ -414,7 +414,7 @@ bool generate_genesis(const std::string& path_config, uint64_t premine_split_amo std::cout << ENDL << "PROOF PHRASE: " << gcp.proof_string << ENDL; uint64_t block_reward_without_fee = 0; uint64_t block_reward = 0; - construct_miner_tx(0, 0, 0, 0, 0, dummy_address, dummy_address, bl.miner_tx, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, gcp.proof_string, CURRENCY_MINER_TX_MAX_OUTS, false, pos_entry(), nullptr, nullptr, destinations); + construct_miner_tx(0, 0, 0, 0, 0, dummy_address, dummy_address, bl.miner_tx, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, 0, gcp.proof_string, CURRENCY_MINER_TX_MAX_OUTS, false, pos_entry(), nullptr, nullptr, destinations); currency::blobdata txb = tx_to_blob(bl.miner_tx); //self validate block diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 0d6d41f8..b36e218c 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -1589,6 +1589,9 @@ bool blockchain_storage::create_block_template(const create_block_template_param resp.txs_fee = fee; + size_t tx_hardfork_id = 0; + size_t tx_version = get_tx_version_and_hardfork_id(height, m_core_runtime_config.hard_forks, tx_hardfork_id); + /* instead of complicated two-phase template construction and adjustment of cumulative size with block reward we use CURRENCY_COINBASE_BLOB_RESERVED_SIZE as penalty-free coinbase transaction reservation. @@ -1601,7 +1604,8 @@ bool blockchain_storage::create_block_template(const create_block_template_param b.miner_tx, resp.block_reward_without_fee, resp.block_reward, - get_tx_version(height, m_core_runtime_config.hard_forks), + tx_version, + tx_hardfork_id, ex_nonce, CURRENCY_MINER_TX_MAX_OUTS, pos, @@ -6080,6 +6084,7 @@ struct visitor_proxy : public boost::static_visitor bool blockchain_storage::validate_tx_for_hardfork_specific_terms(const transaction& tx, const crypto::hash& tx_id, uint64_t block_height) const { + size_t most_recent_hardfork_id_for_height = m_core_runtime_config.hard_forks.get_the_most_recent_hardfork_id_for_height(block_height); bool var_is_after_hardfork_1_zone = m_core_runtime_config.is_hardfork_active_for_height(1, block_height); bool var_is_after_hardfork_2_zone = m_core_runtime_config.is_hardfork_active_for_height(2, block_height); bool var_is_after_hardfork_3_zone = m_core_runtime_config.is_hardfork_active_for_height(3, block_height); @@ -6218,7 +6223,9 @@ bool blockchain_storage::validate_tx_for_hardfork_specific_terms(const transacti if (var_is_after_hardfork_5_zone) { - // additional checks here + CHECK_AND_ASSERT_MES(tx.version >= TRANSACTION_VERSION_POST_HF5, false, "HF5: tx with version " << tx.version << " is not allowed"); + // starting from HF5 each tx must have hardfork_id corresponding to the current active hardfork + CHECK_AND_ASSERT_MES(tx.hardfork_id == most_recent_hardfork_id_for_height, false, "tx's hardfork_id is " << (int)tx.hardfork_id << ", but the current hardfork is " << most_recent_hardfork_id_for_height << ", rejected"); } else { diff --git a/src/currency_core/currency_basic.h b/src/currency_core/currency_basic.h index d0630089..5b0bfcc2 100644 --- a/src/currency_core/currency_basic.h +++ b/src/currency_core/currency_basic.h @@ -1032,6 +1032,7 @@ namespace currency { public: uint64_t version = 0; + uint8_t hardfork_id = 0; std::vector vin; std::vector extra; std::vector vout; @@ -1044,6 +1045,8 @@ namespace currency FIELD(vin) FIELD(extra) FIELD(vout) + if(version < TRANSACTION_VERSION_POST_HF5) return true; + FIELD(hardfork_id) END_SERIALIZE() }; diff --git a/src/currency_core/currency_config.h b/src/currency_core/currency_config.h index 1d6edf20..cd796b74 100644 --- a/src/currency_core/currency_config.h +++ b/src/currency_core/currency_config.h @@ -28,10 +28,11 @@ #define CURRENCY_PUBLIC_AUDITABLE_ADDRESS_BASE58_PREFIX 0x98c8 // auditable addresses start with 'aZx' #define CURRENCY_PUBLIC_AUDITABLE_INTEG_ADDRESS_BASE58_PREFIX 0x8a49 // auditable integrated addresses start with 'aiZX' #define CURRENCY_MINED_MONEY_UNLOCK_WINDOW 10 -#define CURRENT_TRANSACTION_VERSION 2 +#define CURRENT_TRANSACTION_VERSION 3 #define TRANSACTION_VERSION_INITAL 0 #define TRANSACTION_VERSION_PRE_HF4 1 -#define TRANSACTION_VERSION_POST_HF4 2 +#define TRANSACTION_VERSION_POST_HF4 2 +#define TRANSACTION_VERSION_POST_HF5 3 #define HF1_BLOCK_MAJOR_VERSION 1 #define HF3_BLOCK_MAJOR_VERSION 2 #define HF3_BLOCK_MINOR_VERSION 0 diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 96d55b46..ea309bdd 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -393,6 +393,7 @@ namespace currency uint64_t& block_reward_without_fee, uint64_t& block_reward, uint64_t tx_version, + size_t tx_hadrfork_id, const blobdata& extra_nonce /* = blobdata() */, size_t max_outs /* = CURRENCY_MINER_TX_MAX_OUTS */, bool pos /* = false */, @@ -476,6 +477,8 @@ namespace currency CHECK_AND_ASSERT_MES(destinations.size() <= CURRENCY_TX_MAX_ALLOWED_OUTS || height == 0, false, "Too many outs (" << destinations.size() << ")! Miner tx can't be constructed."); // tx is not cleared intentionally to allow passing additional args in the extra/attachments tx.version = tx_version; + if (tx.version >= TRANSACTION_VERSION_POST_HF5) + tx.hardfork_id = tx_hadrfork_id; tx_generation_context tx_gen_context{}; tx_gen_context.set_tx_key(tx_one_time_key_to_use ? *tx_one_time_key_to_use : keypair::generate()); @@ -2819,15 +2822,26 @@ namespace currency //--------------------------------------------------------------- - uint64_t get_tx_version(uint64_t tx_expected_block_height, const hard_forks_descriptor& hfd) + uint64_t get_tx_version_and_hardfork_id(uint64_t tx_expected_block_height, const hard_forks_descriptor& hfd, size_t& tx_hardfork_id) { + tx_hardfork_id = hfd.get_the_most_recent_hardfork_id_for_height(tx_expected_block_height); if (!hfd.is_hardfork_active_for_height(ZANO_HARDFORK_04_ZARCANUM, tx_expected_block_height)) { return TRANSACTION_VERSION_PRE_HF4; } + if (!hfd.is_hardfork_active_for_height(ZANO_HARDFORK_05, tx_expected_block_height)) + { + return TRANSACTION_VERSION_POST_HF4; + } return CURRENT_TRANSACTION_VERSION; } //--------------------------------------------------------------- + uint64_t get_tx_version(uint64_t tx_expected_block_height, const hard_forks_descriptor& hfd) + { + [[maybe_unused]] size_t tx_hardfork_id{}; + return get_tx_version_and_hardfork_id(tx_expected_block_height, hfd, tx_hardfork_id); + } + //--------------------------------------------------------------- // TODO @#@# this function is obsolete and needs to be re-written uint64_t get_reward_from_miner_tx(const transaction& tx) { diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index 399a6d90..3f9152cd 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -295,6 +295,7 @@ namespace currency uint64_t& block_reward_without_fee, uint64_t& block_reward, uint64_t tx_version, + size_t tx_hadrfork_id, const blobdata& extra_nonce = blobdata(), size_t max_outs = CURRENCY_MINER_TX_MAX_OUTS, bool pos = false, @@ -348,6 +349,7 @@ namespace currency bool shuffle = true, uint64_t flags = 0); + uint64_t get_tx_version_and_hardfork_id(uint64_t tx_expected_block_height, const hard_forks_descriptor& hfd, size_t& tx_hardfork_id); // returns tx version and tx hardfork id based on the height of the block where the transaction is expected to be uint64_t get_tx_version(uint64_t tx_expected_block_height, const hard_forks_descriptor& hfd); // returns tx version based on the height of the block where the transaction is expected to be bool construct_tx(const account_keys& sender_account_keys, const finalize_tx_param& param, finalized_tx& result); bool get_or_calculate_asset_id(const asset_descriptor_operation& ado, crypto::point_t* p_result_point, crypto::public_key* p_result_pub_key); diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index 2679dd39..dd4dffab 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -299,6 +299,8 @@ bool test_generator::construct_block(currency::block& blk, tx_generation_context miner_tx_tgc{}; uint64_t block_reward_without_fee = 0; uint64_t block_reward = 0; + size_t tx_hardfork_id = 0; + uint64_t tx_version = get_tx_version_and_hardfork_id(height, m_hardforks, tx_hardfork_id); while (true) { r = construct_miner_tx(height, misc_utils::median(block_sizes), @@ -310,7 +312,8 @@ bool test_generator::construct_block(currency::block& blk, blk.miner_tx, block_reward_without_fee, block_reward, - get_tx_version(height, m_hardforks), + tx_version, + tx_hardfork_id, blobdata(), test_generator::get_test_gentime_settings().miner_tx_max_outs, static_cast(coin_stake_sources.size()), @@ -956,10 +959,12 @@ bool test_generator::construct_block(int64_t manual_timestamp_adjustment, { uint64_t base_block_reward = 0; uint64_t block_reward = 0; + size_t tx_hardfork_id = 0; + uint64_t tx_version = get_tx_version_and_hardfork_id(height, m_hardforks, tx_hardfork_id); size_t current_block_size = txs_sizes + get_object_blobsize(blk.miner_tx); // TODO: This will work, until size of constructed block is less then CURRENCY_BLOCK_GRANTED_FULL_REWARD_ZONE if (!construct_miner_tx(height, misc_utils::median(block_sizes), already_generated_coins, current_block_size, 0, - miner_acc.get_public_address(), miner_acc.get_public_address(), blk.miner_tx, base_block_reward, block_reward, get_tx_version(height, m_hardforks), blobdata(), 1)) + miner_acc.get_public_address(), miner_acc.get_public_address(), blk.miner_tx, base_block_reward, block_reward, tx_version, tx_hardfork_id, blobdata(), 1)) return false; } diff --git a/tests/core_tests/chaingen.h b/tests/core_tests/chaingen.h index 1ff60a9a..962d9b95 100644 --- a/tests/core_tests/chaingen.h +++ b/tests/core_tests/chaingen.h @@ -994,10 +994,12 @@ bool test_generator::construct_block_gentime_with_coinbase_cb(const currency::bl uint64_t block_reward_without_fee = 0; uint64_t block_reward = 0; + size_t tx_hardfork_id = 0; + uint64_t tx_version = get_tx_version_and_hardfork_id(height, m_hardforks, tx_hardfork_id); currency::keypair tx_sec_key = currency::keypair::generate(); r = construct_miner_tx(height, epee::misc_utils::median(block_sizes), already_generated_coins, 0 /* current_block_size !HACK! */, 0, - acc.get_public_address(), acc.get_public_address(), miner_tx, block_reward_without_fee, block_reward, get_tx_version(height, m_hardforks), currency::blobdata(), /* max outs: */ 1, + acc.get_public_address(), acc.get_public_address(), miner_tx, block_reward_without_fee, block_reward, tx_version, tx_hardfork_id, currency::blobdata(), /* max outs: */ 1, /* pos: */ false, currency::pos_entry(), /* ogc_ptr: */ nullptr, &tx_sec_key); CHECK_AND_ASSERT_MES(r, false, "construct_miner_tx failed"); diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index d1a217c6..ec8ba6a2 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -1271,6 +1271,9 @@ int main(int argc, char* argv[]) GENERATE_AND_PLAY(hardfork_4_wallet_sweep_bare_outs); GENERATE_AND_PLAY_HF(hardfork_4_pop_tx_from_global_index, "4-*"); + // HF5 + GENERATE_AND_PLAY_HF(hard_fork_5_tx_version, "5-*"); + // atomics GENERATE_AND_PLAY(atomic_simple_test); GENERATE_AND_PLAY(atomic_test_wrong_redeem_wrong_refund); diff --git a/tests/core_tests/chaingen_tests_list.h b/tests/core_tests/chaingen_tests_list.h index abac7b00..8c128250 100644 --- a/tests/core_tests/chaingen_tests_list.h +++ b/tests/core_tests/chaingen_tests_list.h @@ -39,6 +39,7 @@ #include "hard_fork_1.h" #include "hard_fork_2.h" #include "hard_fork_4.h" +#include "hard_fork_5.h" #include "atomic_tests.h" #include "isolate_auditable_and_proof.h" #include "zarcanum_test.h" diff --git a/tests/core_tests/hard_fork_5.cpp b/tests/core_tests/hard_fork_5.cpp new file mode 100644 index 00000000..8a88658a --- /dev/null +++ b/tests/core_tests/hard_fork_5.cpp @@ -0,0 +1,32 @@ +// Copyright (c) 2024 Zano Project +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "chaingen.h" +#include "hard_fork_5.h" +#include "random_helper.h" + +using namespace currency; + +bool hard_fork_5_tx_version::generate(std::vector& events) const +{ + // + // Test idea: + // + uint64_t ts = test_core_time::get_time(); + GENERATE_ACCOUNT(miner_acc); + GENERATE_ACCOUNT(alice_acc); + + MAKE_GENESIS_BLOCK(events, blk_0, miner_acc, ts); + //// rebuild genesis miner tx + //std::vector destinations; + //destinations.emplace_back(MK_TEST_COINS(1), alice_acc.get_public_address()); + //destinations.emplace_back(MK_TEST_COINS(1), alice_acc.get_public_address()); + //CHECK_AND_ASSERT_MES(replace_coinbase_in_genesis_block(destinations, generator, events, blk_0), false, ""); // leftover amount will be also send to miner + + DO_CALLBACK(events, "configure_core"); // default configure_core callback will initialize core runtime config with m_hardforks + REWIND_BLOCKS_N_WITH_TIME(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 3); + + MAKE_TX(events, tx_1, miner_acc, alice_acc, MK_TEST_COINS(1), blk_0r); + + return true; +} diff --git a/tests/core_tests/hard_fork_5.h b/tests/core_tests/hard_fork_5.h new file mode 100644 index 00000000..692d3348 --- /dev/null +++ b/tests/core_tests/hard_fork_5.h @@ -0,0 +1,12 @@ +// Copyright (c) 2024 Zano Project +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#pragma once +#include "chaingen.h" +#include "wallet_tests_basic.h" + + +struct hard_fork_5_tx_version : public test_chain_unit_enchanced +{ + bool generate(std::vector& events) const; +}; diff --git a/tests/core_tests/pos_block_builder.cpp b/tests/core_tests/pos_block_builder.cpp index da3e08c1..6ebd50ab 100644 --- a/tests/core_tests/pos_block_builder.cpp +++ b/tests/core_tests/pos_block_builder.cpp @@ -161,6 +161,8 @@ void pos_block_builder::step4_generate_coinbase_tx(size_t median_size, CHECK_AND_ASSERT_THROW_MES(m_step == 3, "pos_block_builder: incorrect step sequence"); uint64_t tx_version = m_context.zarcanum ? TRANSACTION_VERSION_POST_HF4 : TRANSACTION_VERSION_PRE_HF4; + // TODO @#@# tx_hardfork_id + pos_entry pe{}; pe.stake_unlock_time = 0; // TODO pe.amount = m_context.stake_amount; @@ -171,7 +173,7 @@ void pos_block_builder::step4_generate_coinbase_tx(size_t median_size, size_t estimated_block_size = m_txs_total_size; m_block.miner_tx = transaction{}; bool r = construct_miner_tx(m_height, median_size, already_generated_coins, estimated_block_size, m_total_fee, - reward_receiver_address, stakeholder_address, m_block.miner_tx, block_reward_without_fee, m_block_reward, tx_version, extra_nonce, max_outs, true, pe, &m_miner_tx_tgc, tx_one_time_key_to_use); + reward_receiver_address, stakeholder_address, m_block.miner_tx, block_reward_without_fee, m_block_reward, tx_version, 0, extra_nonce, max_outs, true, pe, &m_miner_tx_tgc, tx_one_time_key_to_use); CHECK_AND_ASSERT_THROW_MES(r, "construct_miner_tx failed"); estimated_block_size = m_txs_total_size + get_object_blobsize(m_block.miner_tx); @@ -180,7 +182,7 @@ void pos_block_builder::step4_generate_coinbase_tx(size_t median_size, { m_block.miner_tx = transaction{}; r = construct_miner_tx(m_height, median_size, already_generated_coins, estimated_block_size, m_total_fee, - reward_receiver_address, stakeholder_address, m_block.miner_tx, block_reward_without_fee, m_block_reward, tx_version, extra_nonce, max_outs, true, pe, &m_miner_tx_tgc, tx_one_time_key_to_use); + reward_receiver_address, stakeholder_address, m_block.miner_tx, block_reward_without_fee, m_block_reward, tx_version, 0, extra_nonce, max_outs, true, pe, &m_miner_tx_tgc, tx_one_time_key_to_use); CHECK_AND_ASSERT_THROW_MES(r, "construct_homemade_pos_miner_tx failed"); cumulative_size = m_txs_total_size + get_object_blobsize(m_block.miner_tx); diff --git a/tests/core_tests/transaction_tests.cpp b/tests/core_tests/transaction_tests.cpp index 206a5596..d884c17e 100644 --- a/tests/core_tests/transaction_tests.cpp +++ b/tests/core_tests/transaction_tests.cpp @@ -42,17 +42,17 @@ bool test_transaction_generation_and_ring_signature() account_base rv_acc2; rv_acc2.generate(); transaction tx_mine_1; - construct_miner_tx(0, 0, 0, 10, 0, miner_acc1.get_keys().account_address, miner_acc1.get_keys().account_address, tx_mine_1, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4); + construct_miner_tx(0, 0, 0, 10, 0, miner_acc1.get_keys().account_address, miner_acc1.get_keys().account_address, tx_mine_1, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, 0); transaction tx_mine_2; - construct_miner_tx(0, 0, 0, 0, 0, miner_acc2.get_keys().account_address, miner_acc2.get_keys().account_address, tx_mine_2, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4); + construct_miner_tx(0, 0, 0, 0, 0, miner_acc2.get_keys().account_address, miner_acc2.get_keys().account_address, tx_mine_2, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, 0); transaction tx_mine_3; - construct_miner_tx(0, 0, 0, 0, 0, miner_acc3.get_keys().account_address, miner_acc3.get_keys().account_address, tx_mine_3, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4); + construct_miner_tx(0, 0, 0, 0, 0, miner_acc3.get_keys().account_address, miner_acc3.get_keys().account_address, tx_mine_3, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, 0); transaction tx_mine_4; - construct_miner_tx(0, 0, 0, 0, 0, miner_acc4.get_keys().account_address, miner_acc4.get_keys().account_address, tx_mine_4, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4); + construct_miner_tx(0, 0, 0, 0, 0, miner_acc4.get_keys().account_address, miner_acc4.get_keys().account_address, tx_mine_4, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, 0); transaction tx_mine_5; - construct_miner_tx(0, 0, 0, 0, 0, miner_acc5.get_keys().account_address, miner_acc5.get_keys().account_address, tx_mine_5, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4); + construct_miner_tx(0, 0, 0, 0, 0, miner_acc5.get_keys().account_address, miner_acc5.get_keys().account_address, tx_mine_5, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, 0); transaction tx_mine_6; - construct_miner_tx(0, 0, 0, 0, 0, miner_acc6.get_keys().account_address, miner_acc6.get_keys().account_address, tx_mine_6, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4); + construct_miner_tx(0, 0, 0, 0, 0, miner_acc6.get_keys().account_address, miner_acc6.get_keys().account_address, tx_mine_6, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, 0); //fill inputs entry typedef tx_source_entry::output_entry tx_output_entry; @@ -139,7 +139,7 @@ bool test_block_creation() uint64_t block_reward_without_fee = 0; uint64_t block_reward = 0; block b; - r = construct_miner_tx(90, epee::misc_utils::median(szs), 3553616528562147, 33094, 10000000, adr, adr, b.miner_tx, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4); + r = construct_miner_tx(90, epee::misc_utils::median(szs), 3553616528562147, 33094, 10000000, adr, adr, b.miner_tx, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, 0); return r; } diff --git a/tests/unit_tests/test_format_utils.cpp b/tests/unit_tests/test_format_utils.cpp index f12c149f..b42a45f3 100644 --- a/tests/unit_tests/test_format_utils.cpp +++ b/tests/unit_tests/test_format_utils.cpp @@ -1,3 +1,4 @@ +// Copyright (c) 2014-2024 Zano 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. @@ -16,7 +17,7 @@ TEST(parse_and_validate_tx_extra, is_correct_parse_and_validate_tx_extra) currency::blobdata b = "dsdsdfsdfsf"; uint64_t block_reward_without_fee = 0, block_reward = 0; bool r = currency::construct_miner_tx(0, 0, 10000000000000, 1000, TESTS_DEFAULT_FEE, acc.get_keys().account_address, acc.get_keys().account_address, tx, - block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, b, 1); + block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, 0, b, 1); ASSERT_TRUE(r); crypto::public_key tx_pub_key; r = currency::parse_and_validate_tx_extra(tx, tx_pub_key); @@ -30,7 +31,7 @@ TEST(parse_and_validate_tx_extra, is_correct_extranonce_too_big) currency::blobdata b(260, 0); uint64_t block_reward_without_fee = 0, block_reward = 0; bool r = currency::construct_miner_tx(0, 0, 10000000000000, 1000, TESTS_DEFAULT_FEE, acc.get_keys().account_address, acc.get_keys().account_address, tx, - block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, b, 1); + block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, 0, b, 1); ASSERT_FALSE(r); } From 8cc4e99199a4d6e61101854bf9387460fbadaef6 Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 9 Dec 2024 15:52:07 +0100 Subject: [PATCH 15/82] gui: is_remnotenode_mode_preconfigured() implemented --- src/gui/qt-daemon/application/mainwindow.cpp | 7 ++++++- src/wallet/wallets_manager.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/gui/qt-daemon/application/mainwindow.cpp b/src/gui/qt-daemon/application/mainwindow.cpp index 950c93af..30ca6bc8 100644 --- a/src/gui/qt-daemon/application/mainwindow.cpp +++ b/src/gui/qt-daemon/application/mainwindow.cpp @@ -959,7 +959,12 @@ bool MainWindow::init_backend(int argc, char* argv[]) QString MainWindow::is_remnotenode_mode_preconfigured(const QString& param) { TRY_ENTRY(); - return API_RETURN_CODE_FALSE; + view::api_response ar{}; + if (m_backend.is_remote_node_mode()) + ar.error_code = API_RETURN_CODE_TRUE; + else + ar.error_code = API_RETURN_CODE_FALSE; + return MAKE_RESPONSE(ar); CATCH_ENTRY2(API_RETURN_CODE_INTERNAL_ERROR); } diff --git a/src/wallet/wallets_manager.h b/src/wallet/wallets_manager.h index 4e7f73a0..1a804726 100644 --- a/src/wallet/wallets_manager.h +++ b/src/wallet/wallets_manager.h @@ -178,6 +178,7 @@ public: std::string add_custom_asset_id(uint64_t wallet_id, const crypto::public_key& asset_id, currency::asset_descriptor_base& asset_descriptor); std::string delete_custom_asset_id(uint64_t wallet_id, const crypto::public_key& asset_id); bool is_core_initialized() { return m_core_initialized;} + bool is_remote_node_mode() const { return m_remote_node_mode; } private: void main_worker(const po::variables_map& vm); From 11b89333451680019b7c79a136fab8fd799db604 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Mon, 9 Dec 2024 17:53:08 +0300 Subject: [PATCH 16/82] === build number: 369 -> 370 === --- 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 d718b1b6..cfdeffea 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "1" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 369 +#define PROJECT_VERSION_BUILD_NO 370 #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 9e3ece181842ebe1c51ed06b5d6f6c2300b57494 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=D1=91pa=20Dolgorukov?= <63650851+stepan-dolgorukov@users.noreply.github.com> Date: Mon, 9 Dec 2024 21:32:41 +0500 Subject: [PATCH 17/82] coretests: implemented the test "block_with_correct_prev_id_on_wrong_height" (#479) --- tests/core_tests/block_validation.cpp | 39 ++++++++++++++++++++++++++- tests/core_tests/block_validation.h | 10 +++++++ tests/core_tests/chaingen_main.cpp | 1 + 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/tests/core_tests/block_validation.cpp b/tests/core_tests/block_validation.cpp index e2890f37..c5a911a7 100644 --- a/tests/core_tests/block_validation.cpp +++ b/tests/core_tests/block_validation.cpp @@ -692,4 +692,41 @@ bool gen_block_wrong_version_agains_hardfork::generate(std::vector& events) const +{ + // Test idea: make sure that a block with correct previous block identifier that is at the wrong height won't be accepted by the core. + + GENERATE_ACCOUNT(miner); + MAKE_GENESIS_BLOCK(events, blk_0, miner, test_core_time::get_time()); + + DO_CALLBACK(events, "configure_core"); + REWIND_BLOCKS_N(events, blk_0r, blk_0, miner, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + MAKE_TX(events, tx_0, miner, miner, MK_TEST_COINS(2), blk_0r); + MAKE_NEXT_BLOCK(events, blk_1, blk_0r, miner); + m_blk_2.prev_id = currency::get_block_hash(blk_1); + m_blk_2.miner_tx = blk_0r.miner_tx; + m_blk_2.major_version = blk_0r.major_version; + // blk_1 is the previous for blk_2, but height(blk_2) < height(blk_1). + CHECK_AND_ASSERT_EQ(currency::get_block_height(blk_1), 11); + CHECK_AND_ASSERT_EQ(currency::get_block_height(m_blk_2), 10); + DO_CALLBACK(events, "assert_blk_2_has_wrong_height"); + + return true; +} + +bool block_with_correct_prev_id_on_wrong_height::assert_blk_2_has_wrong_height(currency::core& c, [[maybe_unused]] size_t ev_index, [[maybe_unused]] const std::vector& events) const +{ + currency::block_verification_context context_blk_2{}; + + CHECK_AND_ASSERT_EQ(boost::get(m_blk_2.miner_tx.vin.front()).height, 10); + CHECK_AND_ASSERT_EQ(c.get_blockchain_storage().add_new_block(m_blk_2, context_blk_2), false); + + return true; +} diff --git a/tests/core_tests/block_validation.h b/tests/core_tests/block_validation.h index f21463ca..7c56f206 100644 --- a/tests/core_tests/block_validation.h +++ b/tests/core_tests/block_validation.h @@ -187,3 +187,13 @@ struct gen_block_invalid_binary_format : public test_chain_unit_base private: size_t m_corrupt_blocks_begin_idx; }; + +struct block_with_correct_prev_id_on_wrong_height : public gen_block_verification_base<1 + CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 3> +{ + block_with_correct_prev_id_on_wrong_height(); + bool generate(std::vector& events) const; + bool assert_blk_2_has_wrong_height(currency::core& c, size_t ev_index, const std::vector& events) const; + +private: + mutable currency::block m_blk_2{}; +}; diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index d1a217c6..1e98aba1 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -1177,6 +1177,7 @@ int main(int argc, char* argv[]) GENERATE_AND_PLAY_HF(gen_block_unlock_time_is_timestamp_in_future, "0,3"); GENERATE_AND_PLAY_HF(gen_block_height_is_low, "0,3"); GENERATE_AND_PLAY_HF(gen_block_height_is_high, "0,3"); + GENERATE_AND_PLAY_HF(block_with_correct_prev_id_on_wrong_height, "3-*"); GENERATE_AND_PLAY_HF(gen_block_miner_tx_has_2_tx_gen_in, "0,3"); GENERATE_AND_PLAY_HF(gen_block_miner_tx_has_2_in, "0,3"); GENERATE_AND_PLAY_HF(gen_block_miner_tx_with_txin_to_key, "0,3"); From 18c17e48b1ae67922873aa556418cd048e8c86c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=D1=91pa=20Dolgorukov?= <63650851+stepan-dolgorukov@users.noreply.github.com> Date: Mon, 9 Dec 2024 21:34:28 +0500 Subject: [PATCH 18/82] coretests: implemented test "input_refers_to_incompatible_by_type_output" (#480) --- tests/core_tests/chaingen_main.cpp | 1 + tests/core_tests/tx_validation.cpp | 478 +++++++++++++++++++++++++++++ tests/core_tests/tx_validation.h | 10 + 3 files changed, 489 insertions(+) diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index 1e98aba1..89d6a5b9 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -1222,6 +1222,7 @@ int main(int argc, char* argv[]) /* To execute the check of bare balance (function "check_tx_bare_balance") we need to run the test "tx_pool_semantic_validation" on the HF 3. By default behaviour bare outputs are disallowed on the heights >= 10. */ GENERATE_AND_PLAY_HF(tx_pool_semantic_validation, "3"); + GENERATE_AND_PLAY(input_refers_to_incompatible_by_type_output); // Double spend GENERATE_AND_PLAY(gen_double_spend_in_tx); diff --git a/tests/core_tests/tx_validation.cpp b/tests/core_tests/tx_validation.cpp index 14b3db62..dea895ea 100644 --- a/tests/core_tests/tx_validation.cpp +++ b/tests/core_tests/tx_validation.cpp @@ -2121,3 +2121,481 @@ bool tx_pool_semantic_validation::generate(std::vector& events return true; } + +input_refers_to_incompatible_by_type_output::input_refers_to_incompatible_by_type_output() +{ + REGISTER_CALLBACK_METHOD(input_refers_to_incompatible_by_type_output, assert_htlc_input_refers_to_key_output_is_wrong); + REGISTER_CALLBACK_METHOD(input_refers_to_incompatible_by_type_output, assert_to_key_input_refers_zarcanum_output_is_wrong); + REGISTER_CALLBACK_METHOD(input_refers_to_incompatible_by_type_output, assert_htlc_input_refers_zarcanum_output_is_wrong); + REGISTER_CALLBACK_METHOD(input_refers_to_incompatible_by_type_output, assert_zc_input_refers_bare_output_is_wrong); + m_hardforks.set_hardfork_height(ZANO_HARDFORK_04_ZARCANUM, 14); +} + +bool input_refers_to_incompatible_by_type_output::generate(std::vector& events) const +{ + // Test idea: ensure that input and output compatibility checks work. + + GENERATE_ACCOUNT(miner); + MAKE_GENESIS_BLOCK(events, blk_0, miner, test_core_time::get_time()); + + DO_CALLBACK(events, "configure_core"); + + REWIND_BLOCKS(events, blk_0r, blk_0, miner); + block& top{blk_0r}; + MAKE_TX_FEE(events, tx_00, miner, miner, MK_TEST_COINS(2), TESTS_DEFAULT_FEE, top); + + { + MAKE_NEXT_BLOCK_TX1(events, blk_1, top, miner, tx_00); + top = blk_1; + } + + // An input of the type "txin_htlc" refers by a "ref_by_id" object to an output with a target of the type "txout_to_key". + { + MAKE_TX_FEE(events, tx_0, miner, miner, MK_TEST_COINS(2), TESTS_DEFAULT_FEE, top); + MAKE_NEXT_BLOCK_TX1(events, blk, top, miner, tx_0); + transaction tx_1{}; + + top = blk; + + { + txin_htlc input{}; + + { + ref_by_id reference{}; + + reference.tx_id = get_transaction_hash(tx_0); + reference.n = get_tx_out_index_by_amount(tx_0, MK_TEST_COINS(7)); + CHECK_AND_ASSERT_NEQ(reference.n, UINT64_MAX); + input.key_offsets.push_back(reference); + CHECK_AND_ASSERT_EQ(input.key_offsets.size(), 1); + } + + input.k_image = crypto::point_t{{0x59, 0x01, 0xed, 0xcc, 0x3a, 0xe7, 0xaa, 0x83, 0x6c, 0x79, 0xfb, 0xed, 0x5d, 0x60, 0x02, 0xc5, 0xd0, 0xbf, 0x65, 0x85, 0x7b, 0x65, 0x25, 0x0e, 0x22, 0xcb, 0x63, + 0x64, 0x3b, 0x3b, 0x47, 0x30}}.to_key_image(); + input.amount = MK_TEST_COINS(7); + tx_1.vin.push_back(input); + CHECK_AND_ASSERT_EQ(tx_1.vin.size(), 1); + } + + { + tx_out_bare output_bare{}; + txout_to_key output_to_key{}; + + output_bare.amount = MK_TEST_COINS(2); + output_to_key.key = crypto::point_t{{0x2c, 0xdc, 0xc4, 0x7c, 0x38, 0x69, 0xe5, 0xe2, 0x4c, 0x5e, 0x10, 0xb2, 0xbe, 0x57, 0xe9, 0x42, 0x72, 0xd8, 0xf8, 0xb5, 0x97, 0xb9, 0x02, 0x41, 0xba, 0xea, + 0x82, 0xb3, 0xaf, 0x0c, 0xf0, 0x09}}.to_public_key(); + output_bare.target = output_to_key; + tx_1.vout.push_back(output_bare); + CHECK_AND_ASSERT_EQ(tx_1.vout.size(), 1); + } + + DO_CALLBACK(events, "mark_invalid_tx"); + ADD_CUSTOM_EVENT(events, tx_1); + DO_CALLBACK_PARAMS_STR(events, "assert_htlc_input_refers_to_key_output_is_wrong", t_serializable_object_to_blob(tx_1)); + } + + // An input of the type "txin_htlc" refers by a global output index to an output with a target of the type "txout_to_key". + { + MAKE_TX_FEE(events, tx_0, miner, miner, MK_TEST_COINS(2), TESTS_DEFAULT_FEE, top); + MAKE_NEXT_BLOCK_TX1(events, blk, top, miner, tx_0); + transaction tx_1{}; + + top = blk; + + { + txin_htlc input{}; + + { + uint64_t global_output_index{}; + + CHECK_AND_ASSERT_EQ(find_global_index_for_output(events, get_block_hash(top), tx_0, get_tx_out_index_by_amount(tx_0, MK_TEST_COINS(7)), global_output_index), true); + CHECK_AND_ASSERT_NEQ(global_output_index, UINT64_MAX); + input.key_offsets.push_back(global_output_index); + CHECK_AND_ASSERT_EQ(input.key_offsets.size(), 1); + } + + input.k_image = crypto::point_t{{0xc6, 0x1c, 0xda, 0xf7, 0x9e, 0xb7, 0xd9, 0xc2, 0x46, 0x90, 0x29, 0xc8, 0x8a, 0x8f, 0xb4, 0x3e, 0x8e, 0xa8, 0x3b, 0x33, 0x4c, 0x75, 0xdf, 0xcb, 0x8b, 0x77, 0xf7, + 0x39, 0xa7, 0x17, 0xc9, 0xb4}}.to_key_image(); + input.amount = MK_TEST_COINS(7); + tx_1.vin.push_back(input); + CHECK_AND_ASSERT_EQ(tx_1.vin.size(), 1); + } + + { + tx_out_bare output_bare{}; + txout_to_key output_to_key{}; + + output_bare.amount = MK_TEST_COINS(2); + output_to_key.key = crypto::point_t{{0xc4, 0x17, 0xc7, 0x7f, 0xb2, 0x5d, 0xcb, 0x4b, 0x29, 0xdf, 0xea, 0x53, 0x70, 0x11, 0xbb, 0x42, 0x33, 0x0d, 0xf1, 0x22, 0x2d, 0xe4, 0x84, 0x24, 0x36, 0xc0, + 0x06, 0xd5, 0x8c, 0xf8, 0x23, 0x62}}.to_public_key(); + output_bare.target = output_to_key; + tx_1.vout.push_back(output_bare); + } + + tx_1.signatures.push_back(NLSAG_sig{{crypto::signature{}}}); + DO_CALLBACK(events, "mark_invalid_tx"); + ADD_CUSTOM_EVENT(events, tx_1); + DO_CALLBACK_PARAMS_STR(events, "assert_htlc_input_refers_to_key_output_is_wrong", t_serializable_object_to_blob(tx_1)); + } + + DO_CALLBACK_PARAMS(events, "check_hardfork_inactive", size_t{ZANO_HARDFORK_04_ZARCANUM}); + + { + REWIND_BLOCKS_N(events, blk, top, miner, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + top = blk; + } + + DO_CALLBACK_PARAMS(events, "check_hardfork_active", size_t{ZANO_HARDFORK_04_ZARCANUM}); + MAKE_TX_FEE(events, tx_01, miner, miner, MK_TEST_COINS(2), TESTS_DEFAULT_FEE, top); + + { + MAKE_NEXT_BLOCK_TX1(events, blk, top, miner, tx_01); + top = blk; + } + + MAKE_TX_FEE(events, tx_02, miner, miner, MK_TEST_COINS(2), TESTS_DEFAULT_FEE, top); + + { + MAKE_NEXT_BLOCK_TX1(events, blk, top, miner, tx_02); + top = blk; + } + + // An input of the type "txin_to_key" refers by a "ref_by_id" object to an output of the type "tx_out_zarcanum". + { + DO_CALLBACK_PARAMS(events, "check_hardfork_active", size_t{ZANO_HARDFORK_04_ZARCANUM}); + MAKE_TX_FEE(events, tx_0, miner, miner, MK_TEST_COINS(2), TESTS_DEFAULT_FEE, top); + + { + MAKE_NEXT_BLOCK_TX1(events, blk, top, miner, tx_0); + top = blk; + } + + { + REWIND_BLOCKS(events, blk_r, top, miner); + top = blk_r; + } + + transaction tx_1{}; + + tx_1.version = 2; + + { + txin_to_key input{}; + + input.key_offsets.emplace_back(ref_by_id{get_transaction_hash(tx_0), 0}); + CHECK_AND_ASSERT_EQ(tx_0.vout.at(boost::get(input.key_offsets.front()).n).type(), typeid(tx_out_zarcanum)); + CHECK_AND_ASSERT_EQ(input.key_offsets.size(), 1); + input.k_image = crypto::point_t({0x59,0x01, 0xed, 0xcc, 0x3a, 0xe7, 0xaa, 0x83, 0x6c, 0x79, 0xfb, 0xed, 0x5d, 0x60, 0x02, 0xc5, 0xd0, 0xbf, 0x65, 0x85, 0x7b, 0x65, 0x25, 0x0e, 0x22, 0xcb, 0x63, + 0x64, 0x3b, 0x3b, 0x47, 0x30}).to_key_image(); + input.amount = MK_TEST_COINS(2); + tx_1.vin.push_back(input); + CHECK_AND_ASSERT_EQ(tx_1.vin.size(), 1); + } + + tx_1.vout.push_back(tx_out_zarcanum{}); + tx_1.vout.push_back(tx_out_zarcanum{}); + CHECK_AND_ASSERT_EQ(tx_1.vout.size(), 2); + tx_1.extra.push_back(zarcanum_tx_data_v1{TESTS_DEFAULT_FEE}); + CHECK_AND_ASSERT_EQ(tx_1.extra.size(), 1); + DO_CALLBACK(events, "mark_invalid_tx"); + ADD_CUSTOM_EVENT(events, tx_1); + DO_CALLBACK_PARAMS_STR(events, "assert_to_key_input_refers_zarcanum_output_is_wrong", t_serializable_object_to_blob(tx_1)); + } + + // An input of the type "txin_to_key" refers by a global output index to an output of the type "tx_out_zarcanum". + { + DO_CALLBACK_PARAMS(events, "check_hardfork_active", size_t{ZANO_HARDFORK_04_ZARCANUM}); + MAKE_TX_FEE(events, tx_0, miner, miner, MK_TEST_COINS(2), TESTS_DEFAULT_FEE, top); + + { + MAKE_NEXT_BLOCK_TX1(events, blk, top, miner, tx_0); + top = blk; + } + + { + REWIND_BLOCKS(events, blk_r, top, miner); + top = blk_r; + } + + transaction tx_1{}; + + tx_1.version = 2; + + { + txin_to_key input{}; + + { + uint64_t global_output_index{}; + + CHECK_AND_ASSERT_EQ(tx_0.vout.front().type(), typeid(tx_out_zarcanum)); + CHECK_AND_ASSERT_EQ(find_global_index_for_output(events, get_block_hash(top), tx_0, 0, global_output_index), true); + input.key_offsets.push_back(global_output_index); + } + + CHECK_AND_ASSERT_EQ(input.key_offsets.size(), 1); + input.k_image = crypto::point_t{{0xbc, 0x2d, 0xdc, 0xc5, 0x93, 0x03, 0x9f, 0x0e, 0xce, 0x76, 0xee, 0xef, 0xd9, 0x1c, 0x2c, 0x3e, 0x8c, 0x4a, 0xca, 0x87, 0x9b, 0x6e, 0x3a, 0xda, 0xaf, 0x0c, + 0x92, 0x88, 0xda, 0x88, 0xc0, 0xf0}}.to_key_image(); + // A container is selected by an amount specified in an input. ZC outputs have .amount equals to 0. Thus, the input has .amount equals to 0. + input.amount = 0; + tx_1.vin.push_back(input); + CHECK_AND_ASSERT_EQ(tx_1.vin.size(), 1); + } + + tx_1.vout.push_back(tx_out_zarcanum{}); + tx_1.vout.push_back(tx_out_zarcanum{}); + CHECK_AND_ASSERT_EQ(tx_1.vout.size(), 2); + tx_1.extra.push_back(zarcanum_tx_data_v1{TESTS_DEFAULT_FEE}); + CHECK_AND_ASSERT_EQ(tx_1.extra.size(), 1); + DO_CALLBACK(events, "mark_invalid_tx"); + ADD_CUSTOM_EVENT(events, tx_1); + DO_CALLBACK_PARAMS_STR(events, "assert_to_key_input_refers_zarcanum_output_is_wrong", t_serializable_object_to_blob(tx_1)); + } + + // An input of the type "txin_zc_input" refers by a "ref_by_id" object to an output with a target of the type "txout_to_key". + { + DO_CALLBACK_PARAMS(events, "check_hardfork_active", size_t{ZANO_HARDFORK_04_ZARCANUM}); + MAKE_TX_FEE(events, tx_0, miner, miner, MK_TEST_COINS(2), TESTS_DEFAULT_FEE, top); + + { + MAKE_NEXT_BLOCK_TX1(events, blk, top, miner, tx_0); + top = blk; + } + + { + REWIND_BLOCKS(events, blk_r, top, miner); + top = blk_r; + } + + transaction tx_1{}; + + tx_1.version = 2; + + { + txin_zc_input input{}; + + input.key_offsets.emplace_back(ref_by_id{get_transaction_hash(tx_00), 0}); + + { + const auto& output{tx_00.vout.at(boost::get(input.key_offsets.front()).n)}; + + CHECK_AND_ASSERT_EQ(output.type(), typeid(tx_out_bare)); + CHECK_AND_ASSERT_EQ(boost::get(output).target.type(), typeid(txout_to_key)); + } + + CHECK_AND_ASSERT_EQ(input.key_offsets.size(), 1); + input.key_offsets.emplace_back(ref_by_id{get_transaction_hash(tx_01), 0}); + + { + const auto& output{tx_01.vout.at(boost::get(input.key_offsets.at(1)).n)}; + + CHECK_AND_ASSERT_EQ(output.type(), typeid(tx_out_zarcanum)); + } + + CHECK_AND_ASSERT_EQ(input.key_offsets.size(), 2); + input.k_image = crypto::point_t{{0x31, 0x31, 0xd0, 0xf7, 0x13, 0x73, 0xff, 0x21, 0x14, 0xe8, 0x17, 0x4d, 0x18, 0x20, 0x12, 0x2d, 0x80, 0x31, 0xd5, 0x11, 0x82, 0xc0, 0x37, 0xad, 0xd2, 0x7b, 0x8c, + 0xf2, 0xdd, 0xd4, 0x34, 0x9a}}.to_key_image(); + tx_1.vin.push_back(input); + CHECK_AND_ASSERT_EQ(tx_1.vin.size(), 1); + } + + tx_1.vout.push_back(tx_out_zarcanum{}); + tx_1.vout.push_back(tx_out_zarcanum{}); + CHECK_AND_ASSERT_EQ(tx_1.vout.size(), 2); + tx_1.extra.push_back(zarcanum_tx_data_v1{TESTS_DEFAULT_FEE}); + CHECK_AND_ASSERT_EQ(tx_1.extra.size(), 1); + DO_CALLBACK(events, "mark_invalid_tx"); + ADD_CUSTOM_EVENT(events, tx_1); + DO_CALLBACK_PARAMS_STR(events, "assert_zc_input_refers_bare_output_is_wrong", t_serializable_object_to_blob(tx_1)); + } + + // An input of the type "txin_htlc" refers by a "ref_by_id" object to an output of the type "tx_out_zarcanum". + { + DO_CALLBACK_PARAMS(events, "check_hardfork_active", size_t{ZANO_HARDFORK_04_ZARCANUM}); + MAKE_TX_FEE(events, tx_0, miner, miner, MK_TEST_COINS(2), TESTS_DEFAULT_FEE, top); + + { + MAKE_NEXT_BLOCK_TX1(events, blk, top, miner, tx_0); + top = blk; + } + + { + REWIND_BLOCKS_N_WITH_TIME(events, blk_r, top, miner, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + top = blk_r; + } + + transaction tx_1{}; + + tx_1.version = 2; + + { + txin_htlc input{}; + + input.key_offsets.push_back(ref_by_id{get_transaction_hash(tx_0), 0}); + CHECK_AND_ASSERT_EQ(tx_0.vout.at(boost::get(input.key_offsets.front()).n).type(), typeid(tx_out_zarcanum)); + input.k_image = crypto::point_t{{0x7b, 0xf5, 0x28, 0x09, 0xe8, 0x7e, 0x9c, 0x71, 0x0b, 0xad, 0x24, 0xa1, 0x9d, 0xb4, 0xc8, 0xd7, 0x96, 0x72, 0x18, 0xe6, 0x4b, 0x8f, 0x31, 0x01, 0xb0, 0x43, 0xa0, + 0xcc, 0xce, 0x72, 0x8c, 0x7e}}.to_key_image(); + input.amount = MK_TEST_COINS(2); + tx_1.vin.push_back(input); + CHECK_AND_ASSERT_EQ(tx_1.vin.size(), 1); + } + + tx_1.vout.push_back(tx_out_zarcanum{}); + tx_1.vout.push_back(tx_out_zarcanum{}); + CHECK_AND_ASSERT_EQ(tx_1.vout.size(), 2); + tx_1.extra.push_back(zarcanum_tx_data_v1{TESTS_DEFAULT_FEE}); + CHECK_AND_ASSERT_EQ(tx_1.extra.size(), 1); + DO_CALLBACK(events, "mark_invalid_tx"); + ADD_CUSTOM_EVENT(events, tx_1); + DO_CALLBACK_PARAMS_STR(events, "assert_htlc_input_refers_zarcanum_output_is_wrong", t_serializable_object_to_blob(tx_1)); + } + + // An input of the type "txin_htlc" refers by a global output index to an output of the type "tx_out_zarcanum". + { + MAKE_TX_FEE(events, tx_0, miner, miner, MK_TEST_COINS(2), TESTS_DEFAULT_FEE, top); + + { + MAKE_NEXT_BLOCK_TX1(events, blk, top, miner, tx_0); + top = blk; + } + + DO_CALLBACK_PARAMS(events, "check_hardfork_active", size_t{ZANO_HARDFORK_04_ZARCANUM}); + + { + REWIND_BLOCKS_N_WITH_TIME(events, blk_r, top, miner, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + top = blk_r; + } + + transaction tx_1{}; + + tx_1.version = 2; + + { + txin_htlc input{}; + uint64_t global_output_index{}; + + CHECK_AND_ASSERT_EQ(tx_0.vout.front().type(), typeid(tx_out_zarcanum)); + CHECK_AND_ASSERT_EQ(find_global_index_for_output(events, get_block_hash(top), tx_0, 0, global_output_index), true); + input.key_offsets.push_back(global_output_index); + CHECK_AND_ASSERT_EQ(input.key_offsets.size(), 1); + input.k_image = crypto::point_t{{0xbc, 0x2d, 0xdc, 0xc5, 0x93, 0x03, 0x9f, 0x0e, 0xce, 0x76, 0xee, 0xef, 0xd9, 0x1c, 0x2c, 0x3e, 0x8c, 0x4a, 0xca, 0x87, 0x9b, 0x6e, 0x3a, 0xda, 0xaf, 0x0c, 0x92, + 0x88, 0xda, 0x88, 0xc0, 0xf0}}.to_key_image(); + // A container is selected by an amount specified in an input. ZC outputs have .amount equals to 0. Thus, the input has .amount equals to 0. + input.amount = 0; + tx_1.vin.push_back(input); + CHECK_AND_ASSERT_EQ(tx_1.vin.size(), 1); + } + + tx_1.vout.push_back(tx_out_zarcanum{}); + tx_1.vout.push_back(tx_out_zarcanum{}); + CHECK_AND_ASSERT_EQ(tx_1.vout.size(), 2); + tx_1.extra.push_back(zarcanum_tx_data_v1{TESTS_DEFAULT_FEE}); + CHECK_AND_ASSERT_EQ(tx_1.extra.size(), 1); + DO_CALLBACK(events, "mark_invalid_tx"); + ADD_CUSTOM_EVENT(events, tx_1); + DO_CALLBACK_PARAMS_STR(events, "assert_htlc_input_refers_zarcanum_output_is_wrong", t_serializable_object_to_blob(tx_1)); + } + + return true; +} + +bool input_refers_to_incompatible_by_type_output::assert_htlc_input_refers_to_key_output_is_wrong(const currency::core& c, size_t ev_index, const std::vector& events) const +{ + transaction tx{}; + + CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(tx, boost::get(events.at(ev_index)).callback_params), true); + CHECK_AND_ASSERT_EQ(tx.vin.front().type(), typeid(txin_htlc)); + + { + uint64_t max_related_block_height{}; + + CHECK_AND_ASSERT_EQ(c.get_blockchain_storage().check_tx_input(tx, 0, boost::get(tx.vin.front()), get_transaction_hash(tx), max_related_block_height), false); + } + + { + std::vector keys{}; + uint64_t max_related_block_height{}; + uint64_t source_max_unlock_time_for_pos_coinbase{}; + + CHECK_AND_ASSERT_EQ(c.get_blockchain_storage().get_output_keys_for_input_with_checks(tx, tx.vin.front(), keys, max_related_block_height, source_max_unlock_time_for_pos_coinbase), false); + } + + return true; +} + +bool input_refers_to_incompatible_by_type_output::assert_to_key_input_refers_zarcanum_output_is_wrong(const currency::core& c, const size_t ev_index, const std::vector& events) const +{ + transaction tx{}; + + CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(tx, boost::get(events.at(ev_index)).callback_params), true); + CHECK_AND_ASSERT_EQ(tx.vin.front().type(), typeid(txin_to_key)); + + { + uint64_t max_related_block_height{}; + uint64_t source_max_unlock_time_for_pos_coinbase{}; + + CHECK_AND_ASSERT_EQ(c.get_blockchain_storage().check_tx_input(tx, 0, boost::get(tx.vin.front()), get_transaction_hash(tx), max_related_block_height, + source_max_unlock_time_for_pos_coinbase), false); + } + + { + std::vector keys{}; + uint64_t max_related_block_height{}; + uint64_t source_max_unlock_time_for_pos_coinbase{}; + + CHECK_AND_ASSERT_EQ(c.get_blockchain_storage().get_output_keys_for_input_with_checks(tx, tx.vin.front(), keys, max_related_block_height, source_max_unlock_time_for_pos_coinbase), false); + } + + return true; +} + +bool input_refers_to_incompatible_by_type_output::assert_zc_input_refers_bare_output_is_wrong(const currency::core& c, const size_t ev_index, const std::vector& events) const +{ + transaction tx{}; + + CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(tx, boost::get(events.at(ev_index)).callback_params), true); + CHECK_AND_ASSERT_EQ(tx.vin.front().type(), typeid(txin_zc_input)); + + { + std::vector keys{}; + uint64_t max_related_block_height{}; + uint64_t source_max_unlock_time_for_pos_coinbase{}; + + CHECK_AND_ASSERT_EQ(c.get_blockchain_storage().get_output_keys_for_input_with_checks(tx, tx.vin.front(), keys, max_related_block_height, source_max_unlock_time_for_pos_coinbase), true); + } + + { + bool all_inputs_have_explicit_native_asset_id{}; + uint64_t max_related_block_height{}; + + CHECK_AND_ASSERT_EQ(c.get_blockchain_storage().check_tx_input(tx, 0, boost::get(tx.vin.front()), get_transaction_hash(tx), max_related_block_height, + all_inputs_have_explicit_native_asset_id), false); + } + + return true; +} + +bool input_refers_to_incompatible_by_type_output::assert_htlc_input_refers_zarcanum_output_is_wrong(const currency::core& c, const size_t ev_index, const std::vector& events) const +{ + transaction tx{}; + + CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(tx, boost::get(events.at(ev_index)).callback_params), true); + CHECK_AND_ASSERT_EQ(tx.vin.front().type(), typeid(txin_htlc)); + + { + uint64_t max_related_block_height{}; + uint64_t source_max_unlock_time_for_pos_coinbase{}; + + CHECK_AND_ASSERT_EQ(c.get_blockchain_storage().check_tx_input(tx, 0, boost::get(tx.vin.front()), get_transaction_hash(tx), max_related_block_height, + source_max_unlock_time_for_pos_coinbase), false); + } + + { + std::vector keys{}; + uint64_t max_related_block_height{}; + uint64_t source_max_unlock_time_for_pos_coinbase{}; + + CHECK_AND_ASSERT_EQ(c.get_blockchain_storage().get_output_keys_for_input_with_checks(tx, tx.vin.front(), keys, max_related_block_height, source_max_unlock_time_for_pos_coinbase), false); + } + + return true; +} diff --git a/tests/core_tests/tx_validation.h b/tests/core_tests/tx_validation.h index 9888ee3e..6e3ae56e 100644 --- a/tests/core_tests/tx_validation.h +++ b/tests/core_tests/tx_validation.h @@ -165,3 +165,13 @@ struct tx_pool_semantic_validation : public test_chain_unit_enchanced { bool generate(std::vector& events) const; }; + +struct input_refers_to_incompatible_by_type_output : public test_chain_unit_enchanced +{ + input_refers_to_incompatible_by_type_output(); + bool generate(std::vector& events) const; + bool assert_htlc_input_refers_to_key_output_is_wrong(const currency::core& c, const size_t ev_index, const std::vector& events) const; + bool assert_to_key_input_refers_zarcanum_output_is_wrong(const currency::core& c, const size_t ev_index, const std::vector& events) const; + bool assert_zc_input_refers_bare_output_is_wrong(const currency::core& c, const size_t ev_index, const std::vector& events) const; + bool assert_htlc_input_refers_zarcanum_output_is_wrong(const currency::core& c, const size_t ev_index, const std::vector& events) const; +}; From b9557dd70efa8ee2f6211dfdcfbafa0a705c0a0d Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 9 Dec 2024 23:31:39 +0100 Subject: [PATCH 19/82] chaingen: run-single-test made more specific (exact match is now required) --- tests/core_tests/chaingen_main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index ec8ba6a2..b557b642 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -387,7 +387,7 @@ bool gen_and_play_intermitted_by_blockchain_saveload(const char* const genclass_ #define GENERATE_AND_PLAY(genclass) \ - if (!skip_all_till_the_end && ((!postponed_tests.count(#genclass) && run_single_test.empty()) || (!run_single_test.empty() && std::string::npos != std::string(#genclass).find(run_single_test)))) \ + if (!skip_all_till_the_end && ((!postponed_tests.count(#genclass) && run_single_test.empty()) || (!run_single_test.empty() && std::string(#genclass) == run_single_test))) \ { \ TIME_MEASURE_START_MS(t); \ ++tests_count; \ @@ -422,7 +422,7 @@ bool gen_and_play_intermitted_by_blockchain_saveload(const char* const genclass_ } #define GENERATE_AND_PLAY_HF(genclass, hardfork_str_mask) \ - if (!skip_all_till_the_end && ((!postponed_tests.count(#genclass) && run_single_test.empty()) || (!run_single_test.empty() && std::string::npos != std::string(#genclass).find(run_single_test)))) \ + if (!skip_all_till_the_end && ((!postponed_tests.count(#genclass) && run_single_test.empty()) || (!run_single_test.empty() && std::string(#genclass) == run_single_test))) \ { \ std::vector hardforks = parse_hardfork_str_mask(hardfork_str_mask); \ CHECK_AND_ASSERT_MES(!hardforks.empty(), false, "invalid hardforks mask: " << hardfork_str_mask); \ From 78f622ead1ec1bac665f5f50c267cbed1af33de2 Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 10 Dec 2024 21:27:34 +0100 Subject: [PATCH 20/82] bcs: get_block_reward_by_main_chain_height(), get_block_reward_by_hash() implemented; 2) core_rpc_server::fill_block_header_response() now correctly fills 'reward' --- src/currency_core/blockchain_storage.cpp | 51 ++++++++++++++++++++++++ src/currency_core/blockchain_storage.h | 2 + src/rpc/core_rpc_server.cpp | 17 +++++--- src/rpc/core_rpc_server.h | 2 +- 4 files changed, 66 insertions(+), 6 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 0d6d41f8..2a6af842 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -973,6 +973,57 @@ bool blockchain_storage::get_block_by_hash(const crypto::hash &h, block &blk) c return false; } +//------------------------------------------------------------------ +bool blockchain_storage::get_block_reward_by_main_chain_height(const uint64_t height, uint64_t& reward_with_fee) const +{ + CRITICAL_REGION_LOCAL(m_read_lock); + static const boost::multiprecision::uint128_t amount_max_mp = UINT64_MAX; + + if (height >= m_db_blocks.size()) + return false; + + boost::multiprecision::uint128_t reward_with_fee_mp{}; + if (height != 0) + reward_with_fee_mp = m_db_blocks[height]->already_generated_coins - m_db_blocks[height - 1]->already_generated_coins; + else + reward_with_fee_mp = m_db_blocks[height]->already_generated_coins; + + if (reward_with_fee_mp > amount_max_mp) + return false; + + reward_with_fee = reward_with_fee_mp.convert_to(); + return true; +} +//------------------------------------------------------------------ +bool blockchain_storage::get_block_reward_by_hash(const crypto::hash &h, uint64_t& reward_with_fee) const +{ + CRITICAL_REGION_LOCAL(m_read_lock); + static const boost::multiprecision::uint128_t amount_max_mp = UINT64_MAX; + + block_extended_info bei{}; + if (!get_block_extended_info_by_hash(h, bei)) + return false; + + boost::multiprecision::uint128_t reward_with_fee_mp{}; + if (bei.height != 0) + { + block_extended_info bei_prev{}; + if (!get_block_extended_info_by_hash(bei.bl.prev_id, bei_prev)) + return false; + reward_with_fee_mp = bei.already_generated_coins - bei_prev.already_generated_coins; + } + else + { + reward_with_fee_mp = bei.already_generated_coins; + } + + if (reward_with_fee_mp > amount_max_mp) + return false; + + reward_with_fee = reward_with_fee_mp.convert_to(); + return true; +} +//------------------------------------------------------------------ bool blockchain_storage::is_tx_related_to_altblock(crypto::hash tx_id) const { CRITICAL_REGION_LOCAL1(m_alternative_chains_lock); diff --git a/src/currency_core/blockchain_storage.h b/src/currency_core/blockchain_storage.h index 78c75e66..5ebc328c 100644 --- a/src/currency_core/blockchain_storage.h +++ b/src/currency_core/blockchain_storage.h @@ -233,6 +233,8 @@ namespace currency size_t get_alternative_blocks_count() const; crypto::hash get_block_id_by_height(uint64_t height) const; bool get_block_by_hash(const crypto::hash &h, block &blk) const; + bool get_block_reward_by_main_chain_height(const uint64_t height, uint64_t& reward_with_fee) const; // only for main chain blocks + bool get_block_reward_by_hash(const crypto::hash &h, uint64_t& reward_with_fee) const; // works for main chain and alt chain blocks bool get_block_extended_info_by_height(uint64_t h, block_extended_info &blk) const; bool get_block_extended_info_by_hash(const crypto::hash &h, block_extended_info &blk) const; bool get_block_by_height(uint64_t h, block &blk) const; diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 88938641..2cbf9a08 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -1156,16 +1156,22 @@ namespace currency return true; } //------------------------------------------------------------------------------------------------------------------------------ - uint64_t core_rpc_server::get_block_reward(const block& blk) + uint64_t core_rpc_server::get_block_reward(const block& blk, const crypto::hash& h) { + if (blk.miner_tx.version >= TRANSACTION_VERSION_POST_HF4) + { + uint64_t reward_with_fee = 0; + m_core.get_blockchain_storage().get_block_reward_by_hash(h, reward_with_fee); + return reward_with_fee; + } + + // legacy version, pre HF4 uint64_t reward = 0; BOOST_FOREACH(const auto& out, blk.miner_tx.vout) { VARIANT_SWITCH_BEGIN(out); VARIANT_CASE_CONST(tx_out_bare, out) reward += out.amount; - VARIANT_CASE_CONST(tx_out_zarcanum, out) - //@#@ VARIANT_SWITCH_END(); } return reward; @@ -1173,6 +1179,7 @@ namespace currency //------------------------------------------------------------------------------------------------------------------------------ bool core_rpc_server::fill_block_header_response(const block& blk, bool orphan_status, block_header_response& response) { + crypto::hash block_hash = get_block_hash(blk); response.major_version = blk.major_version; response.minor_version = blk.minor_version; response.timestamp = blk.timestamp; @@ -1181,9 +1188,9 @@ namespace currency response.orphan_status = orphan_status; response.height = get_block_height(blk); response.depth = m_core.get_current_blockchain_size() - response.height - 1; - response.hash = string_tools::pod_to_hex(get_block_hash(blk)); + response.hash = string_tools::pod_to_hex(block_hash); response.difficulty = m_core.get_blockchain_storage().block_difficulty(response.height).convert_to(); - response.reward = get_block_reward(blk); + response.reward = get_block_reward(blk, block_hash); return true; } //------------------------------------------------------------------------------------------------------------------------------ diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h index e95f5a41..0e55204b 100644 --- a/src/rpc/core_rpc_server.h +++ b/src/rpc/core_rpc_server.h @@ -182,7 +182,7 @@ namespace currency bool check_core_ready_(const std::string& calling_method); //utils - uint64_t get_block_reward(const block& blk); + uint64_t get_block_reward(const block& blk, const crypto::hash& h); bool fill_block_header_response(const block& blk, bool orphan_status, block_header_response& response); void set_session_blob(const std::string& session_id, const currency::block& blob); bool get_session_blob(const std::string& session_id, currency::block& blob); From 13ed32d67a89f31e55589384c2d6fc57629b8f74 Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 11 Dec 2024 13:56:20 +0100 Subject: [PATCH 21/82] ui update (pr 135) --- 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 f6e3e061..638f98f9 160000 --- a/src/gui/qt-daemon/layout +++ b/src/gui/qt-daemon/layout @@ -1 +1 @@ -Subproject commit f6e3e0611f2100c6d9e76631a9fcfeb60e82d6d6 +Subproject commit 638f98f9e25fa3c2f88338b7efe4b1c45ea0e23c From c0ca49c30ac8d064422a6fa03f9f80fabf2c030e Mon Sep 17 00:00:00 2001 From: zano build machine Date: Wed, 11 Dec 2024 15:58:01 +0300 Subject: [PATCH 22/82] === build number: 370 -> 371 === --- 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 cfdeffea..a3b0ca4f 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "1" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 370 +#define PROJECT_VERSION_BUILD_NO 371 #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 eda0472f1e26f8021e26e23c0fc542846f7ecf5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=D1=91pa=20Dolgorukov?= <63650851+stepan-dolgorukov@users.noreply.github.com> Date: Sat, 14 Dec 2024 03:10:34 +0500 Subject: [PATCH 23/82] coretests: implemented a test for the function "blockchain_storage::fill_tx_rpc_inputs" (#486) --- tests/core_tests/chaingen_main.cpp | 1 + tests/core_tests/chaingen_tests_list.h | 3 +- tests/core_tests/daemon_rpc.cpp | 573 +++++++++++++++++++++++++ tests/core_tests/daemon_rpc.h | 18 + 4 files changed, 594 insertions(+), 1 deletion(-) create mode 100644 tests/core_tests/daemon_rpc.cpp create mode 100644 tests/core_tests/daemon_rpc.h diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index 89d6a5b9..8c4fef66 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -1154,6 +1154,7 @@ int main(int argc, char* argv[]) GENERATE_AND_PLAY(one_block); GENERATE_AND_PLAY(gen_ring_signature_1); GENERATE_AND_PLAY(gen_ring_signature_2); + GENERATE_AND_PLAY(fill_tx_rpc_inputs); //GENERATE_AND_PLAY(gen_ring_signature_big); // Takes up to XXX hours (if CURRENCY_MINED_MONEY_UNLOCK_WINDOW == 10) // tests for outputs mixing in diff --git a/tests/core_tests/chaingen_tests_list.h b/tests/core_tests/chaingen_tests_list.h index abac7b00..e4ca2221 100644 --- a/tests/core_tests/chaingen_tests_list.h +++ b/tests/core_tests/chaingen_tests_list.h @@ -45,4 +45,5 @@ #include "multiassets_test.h" #include "ionic_swap_tests.h" #include "attachment_isolation_encryption_test.h" -#include "pos_fuse_test.h" \ No newline at end of file +#include "pos_fuse_test.h" +#include "daemon_rpc.h" diff --git a/tests/core_tests/daemon_rpc.cpp b/tests/core_tests/daemon_rpc.cpp new file mode 100644 index 00000000..f968719e --- /dev/null +++ b/tests/core_tests/daemon_rpc.cpp @@ -0,0 +1,573 @@ +#include "chaingen.h" +#include "daemon_rpc.h" + +fill_tx_rpc_inputs::fill_tx_rpc_inputs() +{ + REGISTER_CALLBACK_METHOD(fill_tx_rpc_inputs, c1); + REGISTER_CALLBACK_METHOD(fill_tx_rpc_inputs, c2); + REGISTER_CALLBACK_METHOD(fill_tx_rpc_inputs, c3); + REGISTER_CALLBACK_METHOD(fill_tx_rpc_inputs, c4); + REGISTER_CALLBACK_METHOD(fill_tx_rpc_inputs, c5); + REGISTER_CALLBACK_METHOD(fill_tx_rpc_inputs, c6); + REGISTER_CALLBACK_METHOD(fill_tx_rpc_inputs, c7); + REGISTER_CALLBACK_METHOD(fill_tx_rpc_inputs, c8); +} + +bool fill_tx_rpc_inputs::generate(std::vector& events) const +{ + // Test idea: make sure that the function "blockchain_storage::fill_tx_rpc_inputs" works as expected. + + GENERATE_ACCOUNT(miner); + MAKE_GENESIS_BLOCK(events, blk_0, miner, test_core_time::get_time()); + + DO_CALLBACK(events, "configure_core"); + + // A transaction in the default state. + DO_CALLBACK_PARAMS_STR(events, "c1", t_serializable_object_to_blob(currency::transaction{})); + + // A transaction with an input of the type "txin_to_key" in the default state. + { + currency::transaction tx{}; + + tx.vin.push_back(std::move(currency::txin_to_key{})); + DO_CALLBACK_PARAMS_STR(events, "c2", t_serializable_object_to_blob(tx)); + } + + // A transaction with an input of the type "txin_zc_input". + { + currency::transaction tx{}; + + { + currency::txin_zc_input input{}; + + input.k_image = {}; + tx.vin.push_back(std::move(input)); + } + + DO_CALLBACK_PARAMS_STR(events, "c6", t_serializable_object_to_blob(tx)); + } + + // A transaction with several "txin_to_key" inputs those have different .amount values. + { + currency::transaction tx{}; + + tx.vin.reserve(3); + + { + currency::txin_to_key input{}; + + CHECK_AND_ASSERT_EQ(input.amount, 0); + tx.vin.push_back(std::move(input)); + } + + { + currency::txin_to_key input{}; + + input.amount = UINT64_MAX; + tx.vin.push_back(std::move(input)); + } + + { + currency::txin_to_key input{}; + + input.amount = 16730018105294876523ull; + tx.vin.push_back(std::move(input)); + } + + DO_CALLBACK_PARAMS_STR(events, "c3", t_serializable_object_to_blob(tx)); + } + + // A transaction with inputs of all possible types. + { + currency::transaction tx{}; + + tx.vin.reserve(5); + tx.vin.push_back(std::move(currency::txin_gen{})); + tx.vin.push_back(std::move(currency::txin_to_key{})); + tx.vin.push_back(std::move(currency::txin_htlc{})); + + { + currency::txin_zc_input input{}; + + input.k_image = {}; + tx.vin.push_back(std::move(input)); + } + + tx.vin.push_back(std::move(currency::txin_multisig{})); + + DO_CALLBACK_PARAMS_STR(events, "c4", t_serializable_object_to_blob(tx)); + } + + REWIND_BLOCKS_N_WITH_TIME(events, blk_0r, blk_0, miner, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + MAKE_TX_FEE(events, tx_0, miner, miner, MK_TEST_COINS(2), TESTS_DEFAULT_FEE, blk_0r); + MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner, tx_0); + + // A transaction with inputs of all possible types. + { + currency::transaction tx{}; + + tx.vin.reserve(5); + tx.vin.push_back(std::move(currency::txin_gen{/* .height = */ 7137406440025745250})); + + { + currency::txin_to_key input{}; + + input.key_offsets.push_back(5350230927837587142ull); + input.key_offsets.push_back(std::move(currency::ref_by_id{currency::get_transaction_hash(tx_0), 0u})); + input.amount = 2341818593703234797ull; + input.k_image = crypto::point_t{{0x62, 0xd9, 0xa0, 0xff, 0xb1, 0x89, 0x06, 0xbe, 0xbd, 0xe9, 0xce, 0xd5, 0xc2, 0x04, 0x5b, 0x6b, 0xb4, 0x5f, 0x9c, 0x3b, 0x31, 0xcc, 0x72, 0xc7, 0x55, 0x25, 0x0f, + 0xa2, 0xb2, 0xbf, 0xb1, 0x0c}}.to_key_image(); + input.etc_details.push_back(std::move(currency::signed_parts{/* .n_outs = */ 2613407258u, /* .n_extras = */ 347754399u})); + input.etc_details.push_back(std::move(currency::extra_attachment_info{/* .sz = */ 5559118977069213037ull, /* .hsh = */ currency::null_hash, /* cnt = */ 8106306627691316520ull})); + tx.vin.push_back(std::move(input)); + } + + { + currency::txin_htlc input{}; + + input.key_offsets.push_back(9536097715806449708ull); + input.key_offsets.push_back(std::move(currency::ref_by_id{/* .tx_id = */ currency::get_transaction_hash(tx_0), /* .n = */ 9u})); + input.amount = 11357119244607763967ull; + input.k_image = crypto::point_t{{0xcb, 0xec, 0xfb, 0x36, 0x02, 0x1c, 0xe5, 0x64, 0xee, 0x6a, 0xb8, 0x67, 0xb2, 0x8e, 0xe9, 0xef, 0x80, 0x17, 0x34, 0x6f, 0xa8, 0x67, 0x3e, 0x45, 0x3a, 0xe0, 0xd4, + 0x8b, 0x1a, 0x13, 0x75, 0xe2}}.to_key_image(); + input.etc_details.push_back(std::move(currency::signed_parts{/* .n_outs = */ 517318753u, /* .n_extras = */ 1367922888u})); + input.etc_details.push_back(std::move(currency::extra_attachment_info{/* .sz = */ 10987762797757012676ull, /* .hsh = */ currency::null_hash, /* .cnt = */ 10767056422067827733ull})); + input.hltc_origin = "htlc-origin"; + tx.vin.push_back(std::move(input)); + } + + { + currency::txin_zc_input input{}; + + input.key_offsets.push_back(16540286509618649069ull); + input.key_offsets.push_back(std::move(currency::ref_by_id{/* .tx_id = */ currency::get_transaction_hash(tx_0), /* .n = */ 4})); + input.k_image = crypto::point_t{{0x53, 0xcf, 0xaf, 0x48, 0x4d, 0xf8, 0xfb, 0x09, 0x4c, 0x01, 0x59, 0x9f, 0xe2, 0x2d, 0x3c, 0x23, 0x96, 0x2d, 0x8c, 0x24, 0x09, 0xf9, 0xd3, 0xe6, 0xf3, 0x27, 0xe8, + 0x7c, 0x7a, 0x90, 0x9c, 0xab}}.to_key_image(); + input.etc_details.push_back(std::move(currency::signed_parts{/* .n_outs = */ 517318753u, /* .n_extras = */ 1367922888u})); + input.etc_details.push_back(std::move(currency::extra_attachment_info{/* .sz = */ 10987762797757012676ull, /* .hsh = */ currency::null_hash, /* .cnt = */ 10767056422067827733ull})); + tx.vin.push_back(std::move(input)); + } + + { + currency::txin_multisig input{}; + + input.amount = 14073369620052150183ull; + input.multisig_out_id = crypto::cn_fast_hash("multisig-out-id", 15); + input.sigs_count = 3497547654u; + input.etc_details.push_back(std::move(currency::signed_parts{/* .n_outs = */ 1801772931u, /* .n_extras = */ 167800219u})); + input.etc_details.push_back(std::move(currency::extra_attachment_info{/* .sz = */ 12438971857615319230ull, /* .hsh = */ currency::null_hash, /* .cnt = */ 13515222808659969031ull})); + tx.vin.push_back(std::move(input)); + } + + DO_CALLBACK_PARAMS_STR(events, "c5", t_serializable_object_to_blob(tx)); + } + + /* A wrong reference by an object of the type "ref_by_id": a value of the attribute ".n" representing an offset is greater than a length of a container of outputs.The function "fill_tx_rpc_inputs" + returns false. */ + { + currency::transaction tx{}; + + { + currency::txin_to_key input{}; + + CHECK_AND_ASSERT_GREATER(1968482779, tx_0.vout.size() - 1); + input.key_offsets.push_back(std::move(currency::ref_by_id{currency::get_transaction_hash(tx_0), 1968482779u})); + tx.vin.push_back(std::move(input)); + } + + DO_CALLBACK_PARAMS_STR(events, "c7", t_serializable_object_to_blob(tx)); + } + + // A wrong reference by an object of the type "ref_by_id": hashcode of non-existent transaction is specified. The function "fill_tx_rpc_inputs" returns false. + { + currency::transaction tx{}; + + { + currency::txin_to_key input{}; + + input.key_offsets.push_back(std::move(currency::ref_by_id{currency::null_hash, 0u})); + tx.vin.push_back(std::move(input)); + } + + DO_CALLBACK_PARAMS_STR(events, "c8", t_serializable_object_to_blob(tx)); + } + + return true; +} + +bool fill_tx_rpc_inputs::c1(const currency::core& core, const size_t event_position, const std::vector& events) const +{ + currency::transaction tx{}; + currency::tx_rpc_extended_info info{}; + + CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(tx, boost::get(events.at(event_position)).callback_params), true); + CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().fill_tx_rpc_inputs(info, tx), true); + CHECK_AND_ASSERT_EQ(info.blob.empty(), true); + CHECK_AND_ASSERT_EQ(info.blob_size, 0); + CHECK_AND_ASSERT_EQ(info.fee, 0); + CHECK_AND_ASSERT_EQ(info.amount, 0); + CHECK_AND_ASSERT_EQ(info.timestamp, 0); + CHECK_AND_ASSERT_EQ(info.keeper_block, 0); + CHECK_AND_ASSERT_EQ(info.id.empty(), true); + CHECK_AND_ASSERT_EQ(info.pub_key.empty(), true); + CHECK_AND_ASSERT_EQ(info.outs.empty(), true); + CHECK_AND_ASSERT_EQ(info.ins.empty(), true); + CHECK_AND_ASSERT_EQ(info.id.empty(), true); + CHECK_AND_ASSERT_EQ(info.extra.empty(), true); + CHECK_AND_ASSERT_EQ(info.attachments.empty(), true); + CHECK_AND_ASSERT_EQ(info.object_in_json.empty(), true); + + return true; +} + +bool fill_tx_rpc_inputs::c2(const currency::core& core, const size_t event_position, const std::vector& events) const +{ + currency::transaction tx{}; + currency::tx_rpc_extended_info info{}; + + CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(tx, boost::get(events.at(event_position)).callback_params), true); + CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().fill_tx_rpc_inputs(info, tx), true); + CHECK_AND_ASSERT_EQ(info.blob.empty(), true); + CHECK_AND_ASSERT_EQ(info.blob_size, 0); + CHECK_AND_ASSERT_EQ(info.fee, 0); + CHECK_AND_ASSERT_EQ(info.amount, 0); + CHECK_AND_ASSERT_EQ(info.timestamp, 0); + CHECK_AND_ASSERT_EQ(info.keeper_block, 0); + CHECK_AND_ASSERT_EQ(info.id.empty(), true); + CHECK_AND_ASSERT_EQ(info.pub_key.empty(), true); + CHECK_AND_ASSERT_EQ(info.outs.empty(), true); + + { + CHECK_AND_ASSERT_EQ(info.ins.size(), 1); + + { + CHECK_AND_ASSERT_EQ(info.ins.front().amount, 0); + CHECK_AND_ASSERT_EQ(info.ins.front().multisig_count, 0); + CHECK_AND_ASSERT_EQ(info.ins.front().htlc_origin.empty(), true); + CHECK_AND_ASSERT_EQ(info.ins.front().kimage_or_ms_id, epee::string_tools::pod_to_hex(currency::null_ki)); + CHECK_AND_ASSERT_EQ(info.ins.front().global_indexes.empty(), true); + CHECK_AND_ASSERT_EQ(info.ins.front().etc_options.empty(), true); + } + } + + CHECK_AND_ASSERT_EQ(info.id.empty(), true); + CHECK_AND_ASSERT_EQ(info.extra.empty(), true); + CHECK_AND_ASSERT_EQ(info.attachments.empty(), true); + CHECK_AND_ASSERT_EQ(info.object_in_json.empty(), true); + + return true; +} + +bool fill_tx_rpc_inputs::c3(const currency::core& core, const size_t event_position, const std::vector& events) const +{ + currency::transaction tx{}; + currency::tx_rpc_extended_info info{}; + + CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(tx, boost::get(events.at(event_position)).callback_params), true); + CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().fill_tx_rpc_inputs(info, tx), true); + CHECK_AND_ASSERT_EQ(info.blob.empty(), true); + CHECK_AND_ASSERT_EQ(info.blob_size, 0); + CHECK_AND_ASSERT_EQ(info.fee, 0); + CHECK_AND_ASSERT_EQ(info.amount, 0); + CHECK_AND_ASSERT_EQ(info.timestamp, 0); + CHECK_AND_ASSERT_EQ(info.keeper_block, 0); + CHECK_AND_ASSERT_EQ(info.id.empty(), true); + CHECK_AND_ASSERT_EQ(info.pub_key.empty(), true); + CHECK_AND_ASSERT_EQ(info.outs.empty(), true); + + { + CHECK_AND_ASSERT_EQ(info.ins.size(), 3); + + { + CHECK_AND_ASSERT_EQ(info.ins.front().amount, 0); + CHECK_AND_ASSERT_EQ(info.ins.front().multisig_count, 0); + CHECK_AND_ASSERT_EQ(info.ins.front().htlc_origin.empty(), true); + CHECK_AND_ASSERT_EQ(info.ins.front().kimage_or_ms_id, epee::string_tools::pod_to_hex(currency::null_ki)); + CHECK_AND_ASSERT_EQ(info.ins.front().global_indexes.empty(), true); + CHECK_AND_ASSERT_EQ(info.ins.front().etc_options.empty(), true); + } + + { + CHECK_AND_ASSERT_EQ(info.ins.at(1).amount, UINT64_MAX); + CHECK_AND_ASSERT_EQ(info.ins.at(1).multisig_count, 0); + CHECK_AND_ASSERT_EQ(info.ins.at(1).htlc_origin.empty(), true); + CHECK_AND_ASSERT_EQ(info.ins.at(1).kimage_or_ms_id, epee::string_tools::pod_to_hex(currency::null_ki)); + CHECK_AND_ASSERT_EQ(info.ins.at(1).global_indexes.empty(), true); + CHECK_AND_ASSERT_EQ(info.ins.at(1).etc_options.empty(), true); + } + + { + CHECK_AND_ASSERT_EQ(info.ins.back().amount, 16730018105294876523ull); + CHECK_AND_ASSERT_EQ(info.ins.back().multisig_count, 0); + CHECK_AND_ASSERT_EQ(info.ins.back().htlc_origin.empty(), true); + CHECK_AND_ASSERT_EQ(info.ins.back().kimage_or_ms_id, epee::string_tools::pod_to_hex(currency::null_ki)); + CHECK_AND_ASSERT_EQ(info.ins.back().global_indexes.empty(), true); + CHECK_AND_ASSERT_EQ(info.ins.back().etc_options.empty(), true); + } + } + + CHECK_AND_ASSERT_EQ(info.id.empty(), true); + CHECK_AND_ASSERT_EQ(info.extra.empty(), true); + CHECK_AND_ASSERT_EQ(info.attachments.empty(), true); + CHECK_AND_ASSERT_EQ(info.object_in_json.empty(), true); + + return true; +} + +bool fill_tx_rpc_inputs::c4(const currency::core& core, const size_t event_position, const std::vector& events) const +{ + currency::transaction tx{}; + currency::tx_rpc_extended_info info{}; + + CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(tx, boost::get(events.at(event_position)).callback_params), true); + CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().fill_tx_rpc_inputs(info, tx), true); + CHECK_AND_ASSERT_EQ(info.blob.empty(), true); + CHECK_AND_ASSERT_EQ(info.blob_size, 0); + CHECK_AND_ASSERT_EQ(info.fee, 0); + CHECK_AND_ASSERT_EQ(info.amount, 0); + CHECK_AND_ASSERT_EQ(info.timestamp, 0); + CHECK_AND_ASSERT_EQ(info.keeper_block, 0); + CHECK_AND_ASSERT_EQ(info.id.empty(), true); + CHECK_AND_ASSERT_EQ(info.pub_key.empty(), true); + CHECK_AND_ASSERT_EQ(info.outs.empty(), true); + + { + CHECK_AND_ASSERT_EQ(info.ins.size(), 5); + + for (size_t position{}; position < info.ins.size(); ++position) + { + CHECK_AND_ASSERT_EQ(info.ins.at(position).amount, 0); + CHECK_AND_ASSERT_EQ(info.ins.at(position).multisig_count, 0); + CHECK_AND_ASSERT_EQ(info.ins.at(position).htlc_origin.empty(), true); + + if (position == 0) + { + CHECK_AND_ASSERT_EQ(info.ins.at(position).kimage_or_ms_id.empty(), true); + } + + else + { + CHECK_AND_ASSERT_EQ(info.ins.at(position).kimage_or_ms_id, epee::string_tools::pod_to_hex(currency::null_ki)); + } + + CHECK_AND_ASSERT_EQ(info.ins.at(position).global_indexes.empty(), true); + CHECK_AND_ASSERT_EQ(info.ins.at(position).etc_options.empty(), true); + } + } + + CHECK_AND_ASSERT_EQ(info.id.empty(), true); + CHECK_AND_ASSERT_EQ(info.extra.empty(), true); + CHECK_AND_ASSERT_EQ(info.attachments.empty(), true); + CHECK_AND_ASSERT_EQ(info.object_in_json.empty(), true); + + return true; +} + +bool fill_tx_rpc_inputs::c5(const currency::core& core, const size_t event_position, const std::vector& events) const +{ + currency::transaction tx{}; + currency::tx_rpc_extended_info info{}; + + CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(tx, boost::get(events.at(event_position)).callback_params), true); + CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().fill_tx_rpc_inputs(info, tx), true); + CHECK_AND_ASSERT_EQ(info.blob.empty(), true); + CHECK_AND_ASSERT_EQ(info.blob_size, 0); + CHECK_AND_ASSERT_EQ(info.fee, 0); + CHECK_AND_ASSERT_EQ(info.amount, 0); + CHECK_AND_ASSERT_EQ(info.timestamp, 0); + CHECK_AND_ASSERT_EQ(info.keeper_block, 0); + CHECK_AND_ASSERT_EQ(info.id.empty(), true); + CHECK_AND_ASSERT_EQ(info.pub_key.empty(), true); + CHECK_AND_ASSERT_EQ(info.outs.empty(), true); + + { + CHECK_AND_ASSERT_EQ(info.ins.size(), 5); + + { + CHECK_AND_ASSERT_EQ(info.ins.front().amount, 0ull); + CHECK_AND_ASSERT_EQ(info.ins.front().multisig_count, 0ull); + CHECK_AND_ASSERT_EQ(info.ins.front().htlc_origin.empty(), true); + CHECK_AND_ASSERT_EQ(info.ins.front().kimage_or_ms_id.empty(), true); + CHECK_AND_ASSERT_EQ(info.ins.front().global_indexes.empty(), true); + CHECK_AND_ASSERT_EQ(info.ins.front().etc_options.empty(), true); + } + + { + CHECK_AND_ASSERT_EQ(info.ins.at(1).amount, 2341818593703234797ull); + CHECK_AND_ASSERT_EQ(info.ins.at(1).multisig_count, 0ull); + CHECK_AND_ASSERT_EQ(info.ins.at(1).htlc_origin.empty(), true); + CHECK_AND_ASSERT_EQ(info.ins.at(1).kimage_or_ms_id, "8172e80b8da3bcbce2ee7df42466627bb3559b80bb504f1fd56b460eedbc2ce9"); + CHECK_AND_ASSERT_EQ(info.ins.at(1).global_indexes.size(), 2ull); + + { + CHECK_AND_ASSERT_EQ(info.ins.at(1).global_indexes.front(), 5350230927837587142ull); + CHECK_AND_ASSERT_EQ(info.ins.at(1).global_indexes.back(), 0ull); + } + + CHECK_AND_ASSERT_EQ(info.ins.at(1).etc_options.size(), 2ull); + + { + CHECK_AND_ASSERT_EQ(info.ins.at(1).etc_options.front(), "n_outs: 2613407258, n_extras: 347754399"); + CHECK_AND_ASSERT_EQ(info.ins.at(1).etc_options.back(), "cnt: 8106306627691316520, sz: 5559118977069213037, hsh: " + std::string(64, '0')); + } + } + + { + CHECK_AND_ASSERT_EQ(info.ins.at(2).amount, 11357119244607763967ull); + CHECK_AND_ASSERT_EQ(info.ins.at(2).multisig_count, 0ull); + CHECK_AND_ASSERT_EQ(info.ins.at(2).htlc_origin, epee::string_tools::buff_to_hex_nodelimer(std::string{"htlc-origin"})); + CHECK_AND_ASSERT_EQ(info.ins.at(2).kimage_or_ms_id, "f15201980333d6ca8fda90c73814baea0864eb56597e40c38061ec77644585ea"); + CHECK_AND_ASSERT_EQ(info.ins.at(2).global_indexes.size(), 2ull); + + { + CHECK_AND_ASSERT_EQ(info.ins.at(2).global_indexes.front(), 9536097715806449708ull); + CHECK_AND_ASSERT_EQ(info.ins.at(2).global_indexes.back(), 0ull); + } + + CHECK_AND_ASSERT_EQ(info.ins.at(2).etc_options.size(), 2ull); + + { + CHECK_AND_ASSERT_EQ(info.ins.at(2).etc_options.front(), "n_outs: 517318753, n_extras: 1367922888"); + CHECK_AND_ASSERT_EQ(info.ins.at(2).etc_options.back(), "cnt: 10767056422067827733, sz: 10987762797757012676, hsh: " + std::string(64, '0')); + } + } + + { + CHECK_AND_ASSERT_EQ(info.ins.at(3).amount, 0ull); + CHECK_AND_ASSERT_EQ(info.ins.at(3).multisig_count, 0ull); + CHECK_AND_ASSERT_EQ(info.ins.at(3).htlc_origin.empty(), true); + CHECK_AND_ASSERT_EQ(info.ins.at(3).kimage_or_ms_id, "c08b36a7f77185f31a570a7f51aa550122026985e5de7941218510a1e973202e"); + CHECK_AND_ASSERT_EQ(info.ins.at(3).global_indexes.size(), 2ull); + + { + CHECK_AND_ASSERT_EQ(info.ins.at(3).global_indexes.front(), 16540286509618649069ull); + CHECK_AND_ASSERT_EQ(info.ins.at(3).global_indexes.back(), 0ull); + } + + CHECK_AND_ASSERT_EQ(info.ins.at(3).etc_options.size(), 2ull); + + { + CHECK_AND_ASSERT_EQ(info.ins.at(3).etc_options.front(), "n_outs: 517318753, n_extras: 1367922888"); + CHECK_AND_ASSERT_EQ(info.ins.at(3).etc_options.back(), "cnt: 10767056422067827733, sz: 10987762797757012676, hsh: " + std::string(64, '0')); + } + } + + { + CHECK_AND_ASSERT_EQ(info.ins.at(4).amount, 14073369620052150183ull); + CHECK_AND_ASSERT_EQ(info.ins.at(4).multisig_count, 0ull); + CHECK_AND_ASSERT_EQ(info.ins.at(4).htlc_origin.empty(), true); + CHECK_AND_ASSERT_EQ(info.ins.at(4).kimage_or_ms_id, "aacdff6018af0aae84d7a836a7f0b4309b51a28bfc4f566657c67b903a3ccba5"); + CHECK_AND_ASSERT_EQ(info.ins.at(4).global_indexes.size(), 0ull); + CHECK_AND_ASSERT_EQ(info.ins.at(4).etc_options.size(), 2ull); + + { + CHECK_AND_ASSERT_EQ(info.ins.at(4).etc_options.front(), "n_outs: 1801772931, n_extras: 167800219"); + CHECK_AND_ASSERT_EQ(info.ins.at(4).etc_options.back(), "cnt: 13515222808659969031, sz: 12438971857615319230, hsh: " + std::string(64, '0')); + } + } + } + + CHECK_AND_ASSERT_EQ(info.id.empty(), true); + CHECK_AND_ASSERT_EQ(info.extra.empty(), true); + CHECK_AND_ASSERT_EQ(info.attachments.empty(), true); + CHECK_AND_ASSERT_EQ(info.object_in_json.empty(), true); + + return true; +} + +bool fill_tx_rpc_inputs::c6(const currency::core& core, const size_t event_position, const std::vector& events) const +{ + currency::transaction tx{}; + currency::tx_rpc_extended_info info{}; + + CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(tx, boost::get(events.at(event_position)).callback_params), true); + CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().fill_tx_rpc_inputs(info, tx), true); + CHECK_AND_ASSERT_EQ(info.blob.empty(), true); + CHECK_AND_ASSERT_EQ(info.blob_size, 0); + CHECK_AND_ASSERT_EQ(info.fee, 0); + CHECK_AND_ASSERT_EQ(info.amount, 0); + CHECK_AND_ASSERT_EQ(info.timestamp, 0); + CHECK_AND_ASSERT_EQ(info.keeper_block, 0); + CHECK_AND_ASSERT_EQ(info.id.empty(), true); + CHECK_AND_ASSERT_EQ(info.pub_key.empty(), true); + CHECK_AND_ASSERT_EQ(info.outs.empty(), true); + + { + CHECK_AND_ASSERT_EQ(info.ins.size(), 1); + + { + CHECK_AND_ASSERT_EQ(info.ins.front().amount, 0); + CHECK_AND_ASSERT_EQ(info.ins.front().multisig_count, 0); + CHECK_AND_ASSERT_EQ(info.ins.front().htlc_origin.empty(), true); + CHECK_AND_ASSERT_EQ(info.ins.front().kimage_or_ms_id, epee::string_tools::pod_to_hex(currency::null_ki)); + CHECK_AND_ASSERT_EQ(info.ins.front().global_indexes.empty(), true); + CHECK_AND_ASSERT_EQ(info.ins.front().etc_options.empty(), true); + } + } + + CHECK_AND_ASSERT_EQ(info.id.empty(), true); + CHECK_AND_ASSERT_EQ(info.extra.empty(), true); + CHECK_AND_ASSERT_EQ(info.attachments.empty(), true); + CHECK_AND_ASSERT_EQ(info.object_in_json.empty(), true); + + return true; +} + +bool fill_tx_rpc_inputs::c7(const currency::core& core, const size_t event_position, const std::vector& events) const +{ + currency::transaction tx{}; + currency::tx_rpc_extended_info info{}; + + CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(tx, boost::get(events.at(event_position)).callback_params), true); + CHECK_AND_ASSERT_EQ(tx.vin.size(), 1); + + { + const auto& input{boost::get(tx.vin.front())}; + + CHECK_AND_ASSERT_EQ(input.key_offsets.size(), 1); + + { + const auto& reference{boost::get(input.key_offsets.front())}; + + CHECK_AND_ASSERT_EQ(reference.n, 1968482779u); + + { + const auto pointer_entry{core.get_blockchain_storage().get_tx_chain_entry(reference.tx_id)}; + + CHECK_AND_ASSERT_NEQ(pointer_entry, nullptr); + CHECK_AND_ASSERT(reference.n >= pointer_entry->m_global_output_indexes.size(), false); + } + } + } + + CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().fill_tx_rpc_inputs(info, tx), false); + + return true; +} + +bool fill_tx_rpc_inputs::c8(const currency::core& core, const size_t event_position, const std::vector& events) const +{ + currency::transaction tx{}; + currency::tx_rpc_extended_info info{}; + + CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(tx, boost::get(events.at(event_position)).callback_params), true); + CHECK_AND_ASSERT_EQ(tx.vin.size(), 1); + + { + const auto& input{boost::get(tx.vin.front())}; + + CHECK_AND_ASSERT_EQ(input.key_offsets.size(), 1); + + { + const auto& reference{boost::get(input.key_offsets.front())}; + + CHECK_AND_ASSERT_EQ(reference.tx_id, currency::null_hash); + CHECK_AND_ASSERT_EQ(reference.n, 0u); + CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().get_tx_chain_entry(reference.tx_id), nullptr); + } + } + + CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().fill_tx_rpc_inputs(info, tx), false); + + return true; +} diff --git a/tests/core_tests/daemon_rpc.h b/tests/core_tests/daemon_rpc.h new file mode 100644 index 00000000..75efa31b --- /dev/null +++ b/tests/core_tests/daemon_rpc.h @@ -0,0 +1,18 @@ +#pragma once + +#include +#include "chaingen.h" + +struct fill_tx_rpc_inputs : public test_chain_unit_enchanced +{ + fill_tx_rpc_inputs(); + bool generate(std::vector& events) const; + bool c1(const currency::core& core, const size_t event_position, const std::vector& events) const; + bool c2(const currency::core& core, const size_t event_position, const std::vector& events) const; + bool c3(const currency::core& core, const size_t event_position, const std::vector& events) const; + bool c4(const currency::core& core, const size_t event_position, const std::vector& events) const; + bool c5(const currency::core& core, const size_t event_position, const std::vector& events) const; + bool c6(const currency::core& core, const size_t event_position, const std::vector& events) const; + bool c7(const currency::core& core, const size_t event_position, const std::vector& events) const; + bool c8(const currency::core& core, const size_t event_position, const std::vector& events) const; +}; From 7b527483c2f42b1852846a8c1800768063240859 Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 24 Dec 2024 20:58:58 +0100 Subject: [PATCH 24/82] wallet rpc: getbalance now returns brief utxo stat for each asset --- src/wallet/wallet2.cpp | 4 ++++ src/wallet/wallet_public_structs_defs.h | 16 ++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 5ab899dd..ac486389 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -3756,6 +3756,10 @@ bool wallet2::balance(std::unordered_map Date: Tue, 24 Dec 2024 23:49:18 +0300 Subject: [PATCH 25/82] === build number: 371 -> 372 === --- 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 a3b0ca4f..9b2e4cac 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "1" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 371 +#define PROJECT_VERSION_BUILD_NO 372 #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 cd2f044ad888801f95dd8e20177c42ec4e8c3e95 Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 25 Dec 2024 02:22:22 +0100 Subject: [PATCH 26/82] an attempt to calm down heuristic av by disabling cpu mining in mainnet build --- src/currency_core/blockchain_storage.cpp | 1 - src/currency_core/miner.cpp | 61 +++++++++++++++++++++++- src/currency_core/miner.h | 7 ++- src/currency_core/miner_common.h | 8 ---- src/daemon/daemon_commands_handler.h | 51 +++++++++++--------- 5 files changed, 93 insertions(+), 35 deletions(-) delete mode 100644 src/currency_core/miner_common.h diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 2a6af842..ab6b33b8 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -30,7 +30,6 @@ #include "common/boost_serialization_helper.h" #include "warnings.h" #include "crypto/hash.h" -#include "miner_common.h" #include "storages/portable_storage_template_helper.h" #include "basic_pow_helpers.h" #include "version.h" diff --git a/src/currency_core/miner.cpp b/src/currency_core/miner.cpp index 109d9966..472c4654 100644 --- a/src/currency_core/miner.cpp +++ b/src/currency_core/miner.cpp @@ -31,6 +31,62 @@ using namespace epee; namespace currency { +#ifndef CPU_MINING_ENABLED + + // miner stub + + miner::miner(i_miner_handler* phandler, blockchain_storage& bc) + {} + miner::~miner() + {} + bool miner::init(const boost::program_options::variables_map& vm) + { + return false; + } + bool miner::deinit() + { + return false; + } + void miner::init_options(boost::program_options::options_description& desc) + {} + bool miner::start(const account_public_address& adr, size_t threads_count) + { + return false; + } + bool miner::stop() + { + return false; + } + bool miner::is_mining() + { + return false; + } + void miner::do_print_hashrate(bool do_hr) + {} + void miner::pause() + {} + void miner::resume() + {} + bool miner::on_block_chain_update() + { + return false; + } + uint64_t miner::get_speed() + { + return 0; + } + void miner::on_synchronized() + {} + bool miner::on_idle() + { + return false; + } + + + +#else + + namespace { const command_line::arg_descriptor arg_extra_messages ("extra-messages-file", "Specify file for extra messages to include into coinbase transactions"); @@ -379,5 +435,8 @@ namespace currency return true; } //----------------------------------------------------------------------------------------------------- -} + +#endif // #ifndef CPU_MINING_ENABLED + +} // namespace currency diff --git a/src/currency_core/miner.h b/src/currency_core/miner.h index c8a37225..6b3886d1 100644 --- a/src/currency_core/miner.h +++ b/src/currency_core/miner.h @@ -7,6 +7,11 @@ #pragma once +#ifdef TESTNET +#define CPU_MINING_ENABLED // disable CPU mining capabilities in mainnet +#endif // #ifndef TESTNET + + #include #include #include @@ -124,5 +129,3 @@ namespace currency }; } - - diff --git a/src/currency_core/miner_common.h b/src/currency_core/miner_common.h deleted file mode 100644 index 9c6db391..00000000 --- a/src/currency_core/miner_common.h +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2014-2018 Zano Project -// Copyright (c) 2014-2018 The Louisdor Project -// Copyright (c) 2012-2013 The Boolberry developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#pragma once - diff --git a/src/daemon/daemon_commands_handler.h b/src/daemon/daemon_commands_handler.h index 1b26fb73..2920c118 100644 --- a/src/daemon/daemon_commands_handler.h +++ b/src/daemon/daemon_commands_handler.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 @@ -49,12 +49,14 @@ public: 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("print_blocked_ips", boost::bind(&daemon_commands_handler::print_blocked_ips, this, ph::_1), "Print ip address blacklists"); +#ifdef CPU_MINING_ENABLED 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)"); - m_cmd_binder.set_handler("print_pool_sh", boost::bind(&daemon_commands_handler::print_pool_sh, this, ph::_1), "Print transaction pool (short format)"); m_cmd_binder.set_handler("show_hr", boost::bind(&daemon_commands_handler::show_hr, this, ph::_1), "Start showing hash rate"); m_cmd_binder.set_handler("hide_hr", boost::bind(&daemon_commands_handler::hide_hr, this, ph::_1), "Stop showing hash rate"); +#endif + m_cmd_binder.set_handler("print_pool", boost::bind(&daemon_commands_handler::print_pool, this, ph::_1), "Print transaction pool (long format)"); + m_cmd_binder.set_handler("print_pool_sh", boost::bind(&daemon_commands_handler::print_pool_sh, this, ph::_1), "Print transaction pool (short format)"); m_cmd_binder.set_handler("save", boost::bind(&daemon_commands_handler::save, this, ph::_1), "Save blockchain"); m_cmd_binder.set_handler("print_daemon_stat", boost::bind(&daemon_commands_handler::print_daemon_stat, this, ph::_1), "Print daemon stat"); m_cmd_binder.set_handler("print_debug_stat", boost::bind(&daemon_commands_handler::print_debug_stat, this, ph::_1), "Print debug stat info"); @@ -184,25 +186,6 @@ private: return true; } - //-------------------------------------------------------------------------------- - bool show_hr(const std::vector& args) - { - if (!m_srv.get_payload_object().get_core().get_miner().is_mining()) - { - std::cout << "Mining is not started. You need start mining before you can see hash rate." << ENDL; - } - else - { - m_srv.get_payload_object().get_core().get_miner().do_print_hashrate(true); - } - return true; - } - //-------------------------------------------------------------------------------- - bool hide_hr(const std::vector& args) - { - m_srv.get_payload_object().get_core().get_miner().do_print_hashrate(false); - return true; - } //-------------------------------------------------------------------------------- bool print_bc_outs(const std::vector& args) { @@ -910,7 +893,9 @@ private: { LOG_PRINT_L0("Pool state: " << ENDL << m_srv.get_payload_object().get_core().print_pool(true)); return true; - } //-------------------------------------------------------------------------------- + } + //-------------------------------------------------------------------------------- +#ifdef CPU_MINING_ENABLED bool start_mining(const std::vector& args) { if (!args.size()) @@ -941,6 +926,26 @@ private: m_srv.get_payload_object().get_core().get_miner().stop(); return true; } + //-------------------------------------------------------------------------------- + bool show_hr(const std::vector& args) + { + if (!m_srv.get_payload_object().get_core().get_miner().is_mining()) + { + std::cout << "Mining is not started. You need start mining before you can see hash rate." << ENDL; + } + else + { + m_srv.get_payload_object().get_core().get_miner().do_print_hashrate(true); + } + return true; + } + //-------------------------------------------------------------------------------- + bool hide_hr(const std::vector& args) + { + m_srv.get_payload_object().get_core().get_miner().do_print_hashrate(false); + return true; + } +#endif // #ifdef CPU_MINING_ENABLED //-------------------------------------------------------------------------------- bool forecast_difficulty(const std::vector& args) { From 61a358b7538cc010b5afee27d00c36a555dac7b0 Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 25 Dec 2024 16:16:10 +0100 Subject: [PATCH 27/82] 2nd attempt to calm down heuristic av by disabling cpu mining in mainnet build --- src/currency_core/miner.cpp | 5 +++-- src/rpc/core_rpc_server.cpp | 4 +++- src/rpc/core_rpc_server.h | 10 +++++++--- src/simplewallet/simplewallet.cpp | 4 ++++ src/simplewallet/simplewallet.h | 2 ++ 5 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/currency_core/miner.cpp b/src/currency_core/miner.cpp index 472c4654..c0cbd789 100644 --- a/src/currency_core/miner.cpp +++ b/src/currency_core/miner.cpp @@ -33,7 +33,8 @@ namespace currency #ifndef CPU_MINING_ENABLED - // miner stub + // CPU mining disabled + // currency::miner stub implementation miner::miner(i_miner_handler* phandler, blockchain_storage& bc) {} @@ -82,7 +83,7 @@ namespace currency return false; } - + // end of currency::miner stub implementation #else diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 2cbf9a08..46fe0a41 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -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 @@ -925,6 +925,7 @@ namespace currency return call_res; } //------------------------------------------------------------------------------------------------------------------------------ +#ifdef CPU_MINING_ENABLED bool core_rpc_server::on_start_mining(const COMMAND_RPC_START_MINING::request& req, COMMAND_RPC_START_MINING::response& res, connection_context& cntx) { CHECK_CORE_READY(); @@ -955,6 +956,7 @@ namespace currency res.status = API_RETURN_CODE_OK; return true; } +#endif // #ifdef CPU_MINING_ENABLED //------------------------------------------------------------------------------------------------------------------------------ bool core_rpc_server::on_getblockcount(const COMMAND_RPC_GETBLOCKCOUNT::request& req, COMMAND_RPC_GETBLOCKCOUNT::response& res, connection_context& cntx) { diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h index 0e55204b..c0a089ae 100644 --- a/src/rpc/core_rpc_server.h +++ b/src/rpc/core_rpc_server.h @@ -45,9 +45,11 @@ namespace currency bool on_get_blocks(const COMMAND_RPC_GET_BLOCKS_FAST::request& req, COMMAND_RPC_GET_BLOCKS_FAST::response& res, connection_context& cntx); bool on_get_transactions(const COMMAND_RPC_GET_TRANSACTIONS::request& req, COMMAND_RPC_GET_TRANSACTIONS::response& res, connection_context& cntx); bool on_get_indexes(const COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::request& req, COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::response& res, connection_context& cntx); - bool on_send_raw_tx(const COMMAND_RPC_SEND_RAW_TX::request& req, COMMAND_RPC_SEND_RAW_TX::response& res, connection_context& cntx); + bool on_send_raw_tx(const COMMAND_RPC_SEND_RAW_TX::request& req, COMMAND_RPC_SEND_RAW_TX::response& res, connection_context& cntx); +#ifdef CPU_MINING_ENABLED bool on_start_mining(const COMMAND_RPC_START_MINING::request& req, COMMAND_RPC_START_MINING::response& res, connection_context& cntx); bool on_stop_mining(const COMMAND_RPC_STOP_MINING::request& req, COMMAND_RPC_STOP_MINING::response& res, connection_context& cntx); +#endif 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_outs3(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::response& res, connection_context& cntx); @@ -56,7 +58,7 @@ namespace currency bool on_get_tx_pool(const COMMAND_RPC_GET_TX_POOL::request& req, COMMAND_RPC_GET_TX_POOL::response& res, connection_context& cntx); bool on_check_keyimages(const COMMAND_RPC_CHECK_KEYIMAGES::request& req, COMMAND_RPC_CHECK_KEYIMAGES::response& res, connection_context& cntx); bool on_rpc_get_blocks_details(const COMMAND_RPC_GET_BLOCKS_DETAILS::request& req, COMMAND_RPC_GET_BLOCKS_DETAILS::response& res, connection_context& cntx); - bool on_force_relaey_raw_txs(const COMMAND_RPC_FORCE_RELAY_RAW_TXS::request& req, COMMAND_RPC_FORCE_RELAY_RAW_TXS::response& res, connection_context& cntx); + bool on_force_relaey_raw_txs(const COMMAND_RPC_FORCE_RELAY_RAW_TXS::request& req, COMMAND_RPC_FORCE_RELAY_RAW_TXS::response& res, connection_context& cntx); bool on_get_offers_ex(const COMMAND_RPC_GET_OFFERS_EX::request& req, COMMAND_RPC_GET_OFFERS_EX::response& res, epee::json_rpc::error& error_resp, connection_context& cntx); @@ -107,9 +109,11 @@ namespace currency MAP_URI_AUTO_JON2("/getheight", on_get_height, COMMAND_RPC_GET_HEIGHT) MAP_URI_AUTO_JON2("/gettransactions", on_get_transactions, COMMAND_RPC_GET_TRANSACTIONS) MAP_URI_AUTO_JON2("/sendrawtransaction", on_send_raw_tx, COMMAND_RPC_SEND_RAW_TX) - MAP_URI_AUTO_JON2("/force_relay", on_force_relaey_raw_txs, COMMAND_RPC_FORCE_RELAY_RAW_TXS) + MAP_URI_AUTO_JON2("/force_relay", on_force_relaey_raw_txs, COMMAND_RPC_FORCE_RELAY_RAW_TXS) +#ifdef CPU_MINING_ENABLED MAP_URI_AUTO_JON2("/start_mining", on_start_mining, COMMAND_RPC_START_MINING) MAP_URI_AUTO_JON2("/stop_mining", on_stop_mining, COMMAND_RPC_STOP_MINING) +#endif MAP_URI_AUTO_JON2("/getinfo", on_get_info, COMMAND_RPC_GET_INFO) // binary RPCs MAP_URI_AUTO_BIN2("/getblocks.bin", on_get_blocks, COMMAND_RPC_GET_BLOCKS_FAST) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 9a5d07e2..a83ec2fb 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -288,8 +288,10 @@ simple_wallet::simple_wallet() m_refresh_progress_reporter(*this), m_offline_mode(false) { +#ifdef CPU_MINING_ENABLED 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"); +#endif // #ifdef CPU_MINING_ENABLED 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), "[raw] Show current wallet balance, with 'raw' 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"); @@ -761,6 +763,7 @@ bool simple_wallet::save(const std::vector &args) return true; } //---------------------------------------------------------------------------------------------------- +#ifdef CPU_MINING_ENABLED bool simple_wallet::start_mining(const std::vector& args) { if (!try_connect_to_daemon()) @@ -815,6 +818,7 @@ bool simple_wallet::stop_mining(const std::vector& args) fail_msg_writer() << "mining has NOT been stopped: " << err; return true; } +#endif // #ifdef CPU_MINING_ENABLED //---------------------------------------------------------------------------------------------------- void simple_wallet::on_new_block(uint64_t height, const currency::block& block) { diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index d8bbb5d8..d660e75c 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -50,8 +50,10 @@ namespace currency bool close_wallet(); bool help(const std::vector &args = std::vector()); +#ifdef CPU_MINING_ENABLED bool start_mining(const std::vector &args); bool stop_mining(const std::vector &args); +#endif // #ifdef CPU_MINING_ENABLED bool refresh(const std::vector &args); bool show_balance(const std::vector &args = std::vector()); bool list_recent_transfers(const std::vector& args); From 8dd8a6ac1c1e55d4e01671804e585cda6d7c722a Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 27 Dec 2024 07:27:43 +0100 Subject: [PATCH 28/82] tx hf id: WIP --- src/currency_core/currency_format_utils.cpp | 17 ++- src/currency_core/currency_format_utils.h | 6 + tests/core_tests/alias_tests.cpp | 19 +-- tests/core_tests/block_validation.cpp | 6 +- tests/core_tests/chain_switch_1.cpp | 34 ++--- tests/core_tests/chaingen.cpp | 133 ++++++++++++++++++-- tests/core_tests/chaingen.h | 36 ++++++ tests/core_tests/chaingen_helpers.h | 5 +- tests/core_tests/checkpoints_tests.cpp | 4 +- tests/core_tests/double_spend.inl | 4 +- tests/core_tests/emission_test.cpp | 5 +- tests/core_tests/escrow_wallet_common.h | 25 ++-- tests/core_tests/escrow_wallet_tests.cpp | 81 ++++++------ tests/core_tests/get_random_outs.cpp | 5 +- tests/core_tests/hard_fork_1.cpp | 4 +- tests/core_tests/integer_overflow.cpp | 7 +- tests/core_tests/misc_tests.cpp | 22 ++-- tests/core_tests/multiassets_test.cpp | 36 +++--- tests/core_tests/multisig_wallet_tests.cpp | 36 +++--- tests/core_tests/offers_test.cpp | 2 +- tests/core_tests/pos_basic_tests.cpp | 3 +- tests/core_tests/transaction_tests.cpp | 2 +- tests/core_tests/tx_validation.cpp | 29 +++-- tests/core_tests/wallet_tests.cpp | 2 +- tests/core_tests/zarcanum_test.cpp | 9 +- 25 files changed, 355 insertions(+), 177 deletions(-) diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index ea309bdd..7ec3400d 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -1442,12 +1442,13 @@ namespace currency const std::vector& attachments, transaction& tx, uint64_t tx_version, + size_t tx_hardfork_id, uint64_t unlock_time, uint8_t tx_outs_attr, bool shuffle) { - crypto::secret_key one_time_secret_key = AUTO_VAL_INIT(one_time_secret_key); - return construct_tx(sender_account_keys, sources, destinations, std::vector(), attachments, tx, tx_version, one_time_secret_key, unlock_time, tx_outs_attr, shuffle); + crypto::secret_key one_time_secret_key{}; + return construct_tx(sender_account_keys, sources, destinations, std::vector(), attachments, tx, tx_version, tx_hardfork_id, one_time_secret_key, unlock_time, tx_outs_attr, shuffle); } //--------------------------------------------------------------- @@ -1967,6 +1968,7 @@ namespace currency const std::vector& attachments, transaction& tx, uint64_t tx_version, + size_t tx_hardfork_id, crypto::secret_key& one_time_secret_key, uint64_t unlock_time, uint8_t tx_outs_attr, @@ -1979,7 +1981,7 @@ namespace currency //in case if there is no real targets we use sender credentials to encrypt attachments account_public_address crypt_destination_addr = get_crypt_address_from_destinations(sender_account_keys, destinations); - return construct_tx(sender_account_keys, sources, destinations, extra, attachments, tx, tx_version, one_time_secret_key, unlock_time, + return construct_tx(sender_account_keys, sources, destinations, extra, attachments, tx, tx_version, tx_hardfork_id, one_time_secret_key, unlock_time, crypt_destination_addr, 0, tx_outs_attr, @@ -1993,6 +1995,7 @@ namespace currency const std::vector& attachments, transaction& tx, uint64_t tx_version, + size_t tx_hardfork_id, crypto::secret_key& one_time_secret_key, uint64_t unlock_time, const account_public_address& crypt_destination_addr, @@ -2002,8 +2005,9 @@ namespace currency uint64_t flags) { //extra copy operation, but creating transaction is not sensitive to this - finalize_tx_param ftp = AUTO_VAL_INIT(ftp); + finalize_tx_param ftp{}; ftp.tx_version = tx_version; + ftp.tx_hardfork_id = tx_hardfork_id; ftp.sources = sources; ftp.prepared_destinations = destinations; ftp.extra = extra; @@ -2015,7 +2019,7 @@ namespace currency ftp.shuffle = shuffle; ftp.flags = flags; - finalized_tx ft = AUTO_VAL_INIT(ft); + finalized_tx ft{}; ft.tx = tx; ft.one_time_key = one_time_secret_key; bool r = construct_tx(sender_account_keys, ftp, ft); @@ -2405,6 +2409,9 @@ namespace currency tx.signatures.clear(); tx.version = ftp.tx_version; + if (tx.version >= TRANSACTION_VERSION_POST_HF5) + tx.hardfork_id = ftp.tx_hardfork_id; + if (unlock_time != 0) set_tx_unlock_time(tx, unlock_time); diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index 3f9152cd..1503baee 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -163,6 +163,7 @@ namespace currency uint64_t expiration_time; crypto::public_key spend_pub_key; // only for validations uint64_t tx_version; + uint8_t tx_hardfork_id = 0; uint64_t mode_separate_fee = 0; epee::misc_utils::events_dispatcher* pevents_dispatcher = nullptr; @@ -187,6 +188,7 @@ namespace currency FIELD(expiration_time) FIELD(spend_pub_key) FIELD(tx_version) + FIELD(tx_hardfork_id) FIELD(mode_separate_fee) if (flags & TX_FLAG_SIGNATURE_MODE_SEPARATE) { @@ -318,9 +320,11 @@ namespace currency const std::vector& attachments, transaction& tx, uint64_t tx_version, + size_t tx_hardfork_id, uint64_t unlock_time, uint8_t tx_outs_attr = CURRENCY_TO_KEY_OUT_RELAXED, bool shuffle = true); + bool construct_tx(const account_keys& sender_account_keys, const std::vector& sources, const std::vector& destinations, @@ -328,6 +332,7 @@ namespace currency const std::vector& attachments, transaction& tx, uint64_t tx_version, + size_t tx_hardfork_id, crypto::secret_key& one_time_secret_key, uint64_t unlock_time, uint8_t tx_outs_attr = CURRENCY_TO_KEY_OUT_RELAXED, @@ -341,6 +346,7 @@ namespace currency const std::vector& attachments, transaction& tx, uint64_t tx_version, + size_t tx_hardfork_id, crypto::secret_key& one_time_secret_key, uint64_t unlock_time, const account_public_address& crypt_account, diff --git a/tests/core_tests/alias_tests.cpp b/tests/core_tests/alias_tests.cpp index b8a1e4fd..1e5b1de5 100644 --- a/tests/core_tests/alias_tests.cpp +++ b/tests/core_tests/alias_tests.cpp @@ -975,7 +975,9 @@ bool gen_alias_too_much_reward::generate(std::vector& events) d.flags |= tx_destination_entry_flags::tdef_explicit_native_asset_id | tx_destination_entry_flags::tdef_zero_amount_blinding_mask; transaction tx_0{}; crypto::secret_key sk{}; - r = construct_tx(miner_acc.get_keys(), sources, destinations, std::vector({ ai }), empty_attachment, tx_0, get_tx_version_from_events(events), sk, 0); + size_t tx_hardfork_id{}; + uint64_t tx_version = get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id); + r = construct_tx(miner_acc.get_keys(), sources, destinations, std::vector({ ai }), empty_attachment, tx_0, tx_version, tx_hardfork_id, sk, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); if (tx_0.version <= TRANSACTION_VERSION_PRE_HF4) @@ -1166,8 +1168,9 @@ bool gen_alias_too_small_reward::make_tx_reg_alias(std::vector destinations.push_back(tx_destination_entry(sources_amount - (alias_reward + TESTS_DEFAULT_FEE), miner_acc.get_public_address())); // change crypto::secret_key stub = AUTO_VAL_INIT(stub); - uint64_t tx_version = get_tx_version(get_block_height(prev_block), m_hardforks); - r = construct_tx(miner_acc.get_keys(), sources, destinations, extra, empty_attachment, tx, tx_version, stub, uint64_t(0)); + size_t tx_hardfork_id{}; + uint64_t tx_version = get_tx_version_and_hardfork_id(get_block_height(prev_block), m_hardforks, tx_hardfork_id); + r = construct_tx(miner_acc.get_keys(), sources, destinations, extra, empty_attachment, tx, tx_version, tx_hardfork_id, stub, uint64_t(0)); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); PRINT_EVENT_N_TEXT(events, "make_tx_reg_alias -> construct_tx()"); events.push_back(tx); @@ -1382,8 +1385,9 @@ bool gen_alias_too_many_regs_in_block_template::generate(std::vector& events) } transaction tx{}; - uint64_t tx_version = currency::get_tx_version(get_block_height(blk_0r) + 1, generator.get_hardforks()); + size_t tx_hardfork_id{}; + uint64_t tx_version = currency::get_tx_version_and_hardfork_id(get_block_height(blk_0r) + 1, generator.get_hardforks(), tx_hardfork_id); crypto::secret_key sk{}; - r = construct_tx(miner_acc.get_keys(), sources, destinations, std::vector({ ai }), empty_attachment, tx, tx_version, sk, 0); + r = construct_tx(miner_acc.get_keys(), sources, destinations, std::vector({ ai }), empty_attachment, tx, tx_version, tx_hardfork_id, sk, 0); /*tx_builder tb; tb.step1_init(); diff --git a/tests/core_tests/block_validation.cpp b/tests/core_tests/block_validation.cpp index c5a911a7..26045224 100644 --- a/tests/core_tests/block_validation.cpp +++ b/tests/core_tests/block_validation.cpp @@ -321,10 +321,9 @@ bool gen_block_miner_tx_has_2_in::generate(std::vector& events destinations.push_back(de); transaction tmp_tx; - std::vector attachments; uint64_t tx_version = get_tx_version(get_block_height(blk_0r), m_hardforks); - if (!construct_tx(miner_account.get_keys(), sources, destinations, attachments, tmp_tx, tx_version, 0)) + if (!construct_tx(miner_account.get_keys(), sources, destinations, empty_extra, empty_attachment, tmp_tx, tx_version)) return false; MAKE_MINER_TX_MANUALLY(miner_tx, blk_0); @@ -369,9 +368,8 @@ bool gen_block_miner_tx_with_txin_to_key::generate(std::vector destinations.push_back(de); transaction tmp_tx = AUTO_VAL_INIT(tmp_tx); - std::vector attachments; uint64_t tx_version = get_tx_version(get_block_height(blk_1r), m_hardforks); - if (!construct_tx(miner_account.get_keys(), sources, destinations, attachments, tmp_tx, tx_version, 0)) + if (!construct_tx(miner_account.get_keys(), sources, destinations, empty_extra, empty_attachment, tmp_tx, tx_version)) return false; MAKE_MINER_TX_MANUALLY(miner_tx, blk_1); diff --git a/tests/core_tests/chain_switch_1.cpp b/tests/core_tests/chain_switch_1.cpp index 69ad2a28..b607e852 100644 --- a/tests/core_tests/chain_switch_1.cpp +++ b/tests/core_tests/chain_switch_1.cpp @@ -532,9 +532,10 @@ bool alt_blocks_validation_and_same_new_amount_in_two_txs::generate(std::vector< std::vector destinations; destinations.push_back(tx_destination_entry(new_amount, miner_acc.get_public_address())); destinations.push_back(tx_destination_entry(TESTS_DEFAULT_FEE, miner_acc.get_public_address())); //just to make two outputs (to please HF4 rules) - transaction tx_1 = AUTO_VAL_INIT(tx_1); - uint64_t tx_version = get_tx_version(get_block_height(blk_3), m_hardforks); - r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, tx_version, 0); + transaction tx_1{}; + size_t tx_hardfork_id{}; + uint64_t tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_3), m_hardforks, tx_hardfork_id); + r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, tx_version, tx_hardfork_id, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); ADD_CUSTOM_EVENT(events, tx_1); @@ -544,8 +545,8 @@ bool alt_blocks_validation_and_same_new_amount_in_two_txs::generate(std::vector< CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources failed"); transaction tx_2 = AUTO_VAL_INIT(tx_2); // use the same destinations - tx_version = get_tx_version(get_block_height(blk_3), m_hardforks); - r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_2, tx_version, 0); + tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_3), m_hardforks, tx_hardfork_id); + r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_2, tx_version, tx_hardfork_id, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); ADD_CUSTOM_EVENT(events, tx_2); @@ -913,16 +914,10 @@ bool alt_chain_and_block_tx_fee_median::generate( CHECK_AND_ASSERT_MES(success, false, "fail to fill sources, destinations"); - tx_version = get_tx_version(get_block_height(blk_1r), - m_hardforks); + size_t tx_hardfork_id{}; + tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_1r), m_hardforks, tx_hardfork_id); - success = construct_tx(miner.get_keys(), - sources, - destinations, - empty_attachment, - tx_0, - tx_version, - 0); + success = construct_tx(miner.get_keys(), sources, destinations, empty_attachment, tx_0, tx_version, tx_hardfork_id, 0); CHECK_AND_ASSERT_MES(success, false, "fail to construct tx_0"); @@ -934,8 +929,7 @@ bool alt_chain_and_block_tx_fee_median::generate( // Transaction tx_1 is constructed and placed in block blk_2a. - tx_version = get_tx_version(get_block_height(blk_1r), - m_hardforks); + tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_1r), m_hardforks, tx_hardfork_id); success = fill_tx_sources_and_destinations( events, @@ -950,13 +944,7 @@ bool alt_chain_and_block_tx_fee_median::generate( CHECK_AND_ASSERT_MES(success, false, "fail to fill sources, destinations"); - success = construct_tx(miner.get_keys(), - sources, - destinations, - empty_attachment, - tx_1, - tx_version, - 0); + success = construct_tx(miner.get_keys(), sources, destinations, empty_attachment, tx_1, tx_version, tx_hardfork_id, 0); CHECK_AND_ASSERT_MES(success, false, "fail to construct tx_1"); diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index dd4dffab..91fbe462 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -1750,8 +1750,9 @@ bool construct_tx_to_key(const currency::hard_forks_descriptor& hf, std::vector destinations; if (!fill_tx_sources_and_destinations(events, blk_head, from.get_keys(), to.get_public_address(), amount, fee, nmix, sources, destinations, check_for_spends, check_for_unlocktime)) return false; - uint64_t tx_version = currency::get_tx_version(get_block_height(blk_head) + 1, hf); // assuming the tx will be in the next block (blk_head + 1) - return construct_tx(from.get_keys(), sources, destinations, extr, att, tx, tx_version, sk, 0, mix_attr); + size_t tx_hardfork_id = 0; + uint64_t tx_version = currency::get_tx_version_and_hardfork_id(get_block_height(blk_head) + 1, hf, tx_hardfork_id); // assuming the tx will be in the next block (blk_head + 1) + return construct_tx(from.get_keys(), sources, destinations, extr, att, tx, tx_version, tx_hardfork_id, sk, 0, mix_attr); } bool construct_tx_to_key(const currency::hard_forks_descriptor& hf, @@ -1779,16 +1780,17 @@ bool construct_tx_to_key(const currency::hard_forks_descriptor& hf, return false; uint64_t tx_expected_block_height = get_block_height(blk_head) + 1; - uint64_t tx_version = currency::get_tx_version(tx_expected_block_height, hf); + size_t tx_hardfork_id = 0; + uint64_t tx_version = currency::get_tx_version_and_hardfork_id(tx_expected_block_height, hf, tx_hardfork_id); boost::multiprecision::int128_t change = get_sources_total_amount(sources); change -= spending_amount; if (change < 0) return false; // should never happen if fill_tx_sources succeded if (change == 0) - return construct_tx(from.get_keys(), sources, destinations, extr, att, tx, tx_version, sk, 0, mix_attr); + return construct_tx(from.get_keys(), sources, destinations, extr, att, tx, tx_version, tx_hardfork_id, sk, 0, mix_attr); std::vector local_dst = destinations; local_dst.push_back(tx_destination_entry(change.convert_to(), from.get_public_address())); - return construct_tx(from.get_keys(), sources, local_dst, extr, att, tx, tx_version, sk, 0, mix_attr); + return construct_tx(from.get_keys(), sources, local_dst, extr, att, tx, tx_version, tx_hardfork_id, sk, 0, mix_attr); } @@ -1817,8 +1819,53 @@ bool construct_tx_with_many_outputs(const currency::hard_forks_descriptor& hf, s uint64_t sources_amount = get_sources_total_amount(sources); if (sources_amount > total_amount + fee) destinations.push_back(tx_destination_entry(sources_amount - (total_amount + fee), keys_from.account_address)); // change - uint64_t tx_version = currency::get_tx_version(currency::get_block_height(blk_head), hf); - return construct_tx(keys_from, sources, destinations, empty_attachment, tx, tx_version, 0); + size_t tx_hardfork_id = 0; + uint64_t tx_version = currency::get_tx_version_and_hardfork_id(currency::get_block_height(blk_head), hf, tx_hardfork_id); + return construct_tx(keys_from, sources, destinations, empty_attachment, tx, tx_version, tx_hardfork_id, 0); +} + +bool construct_tx(const account_keys& sender_account_keys, + const std::vector& sources, + const std::vector& destinations, + const std::vector& extra, + const std::vector& attachments, + transaction& tx, + uint64_t tx_version, + size_t tx_hardfork_id, + crypto::secret_key& one_time_secret_key, + uint64_t unlock_time, + uint64_t expiration_time, + uint8_t tx_outs_attr, + bool shuffle, + uint64_t flags, + uint64_t explicit_consolidated_tx_fee, + tx_generation_context& gen_context) +{ + // extra copy operation, but creating transaction is not sensitive to this + finalize_tx_param ftp {}; + ftp.tx_version = tx_version; + ftp.tx_hardfork_id = tx_hardfork_id; + ftp.sources = sources; + ftp.prepared_destinations = destinations; + ftp.extra = extra; + ftp.attachments = attachments; + ftp.unlock_time = unlock_time; + // ftp.crypt_address = crypt_destination_addr; + ftp.expiration_time = expiration_time; + ftp.tx_outs_attr = tx_outs_attr; + ftp.shuffle = shuffle; + ftp.flags = flags; + ftp.mode_separate_fee = explicit_consolidated_tx_fee; + + finalized_tx ft{}; + ft.tx = tx; + ft.one_time_key = one_time_secret_key; + ftp.gen_context = gen_context; // ftp, not ft here, this is UGLY -- sowle + bool r = construct_tx(sender_account_keys, ftp, ft); + tx = ft.tx; + one_time_secret_key = ft.one_time_key; + gen_context = ft.ftp.gen_context; + return r; } bool construct_tx(const account_keys& sender_account_keys, @@ -1840,6 +1887,9 @@ bool construct_tx(const account_keys& sender_account_keys, // extra copy operation, but creating transaction is not sensitive to this finalize_tx_param ftp {}; ftp.tx_version = tx_version; + if (tx_version >= TRANSACTION_VERSION_POST_HF5) + LOG_PRINT_YELLOW("warning: tx_hardfork_id not set for tx, while it seems to be HF5", LOG_LEVEL_0); + ftp.tx_hardfork_id = 0; ftp.sources = sources; ftp.prepared_destinations = destinations; ftp.extra = extra; @@ -1852,7 +1902,7 @@ bool construct_tx(const account_keys& sender_account_keys, ftp.flags = flags; ftp.mode_separate_fee = explicit_consolidated_tx_fee; - finalized_tx ft = AUTO_VAL_INIT(ft); + finalized_tx ft{}; ft.tx = tx; ft.one_time_key = one_time_secret_key; ftp.gen_context = gen_context; // ftp, not ft here, this is UGLY -- sowle @@ -1863,6 +1913,60 @@ bool construct_tx(const account_keys& sender_account_keys, return r; } +bool construct_tx(const currency::account_keys& sender_account_keys, + const std::vector& sources, + const std::vector& destinations, + const std::vector& extra, + const std::vector& attachments, + currency::transaction& tx, + uint64_t tx_version, + crypto::secret_key& one_time_secret_key, + uint64_t unlock_time) +{ + return construct_tx(sender_account_keys, + sources, + destinations, + extra, + attachments, + tx, + tx_version, + one_time_secret_key, + unlock_time, + 0, /* expiration_time */ + CURRENCY_TO_KEY_OUT_RELAXED, /* tx_outs_attr */ + true, /* shuffle */ + 0, /* flags */ + 0, /* explicit_consolidated_tx_fee */ + tx_generation_context{} + ); +} + +bool construct_tx(const currency::account_keys& sender_account_keys, + const std::vector& sources, + const std::vector& destinations, + const std::vector& extra, + const std::vector& attachments, + currency::transaction& tx, + uint64_t tx_version) +{ + return construct_tx(sender_account_keys, + sources, + destinations, + extra, + attachments, + tx, + tx_version, + crypto::secret_key{}, /* one_time_secret_key */ + 0, /* unlock_time */ + 0, /* expiration_time */ + CURRENCY_TO_KEY_OUT_RELAXED, /* tx_outs_attr */ + true, /* shuffle */ + 0, /* flags */ + 0, /* explicit_consolidated_tx_fee */ + tx_generation_context{} + ); +} + uint64_t get_balance(const currency::account_keys& addr, const std::vector& blockchain, const map_hash2tx_t& mtx, bool dbg_log) { uint64_t res = 0; @@ -2565,19 +2669,26 @@ void test_chain_unit_base::register_callback(const std::string& cb_name, verify_ m_callbacks[cb_name] = cb; } -uint64_t test_chain_unit_base::get_tx_version_from_events(const std::vector &events)const +uint64_t test_chain_unit_base::get_tx_version_from_events(const std::vector &events) const +{ + [[maybe_unused]] size_t tx_hardfork_id{}; + return get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id); +} + +uint64_t test_chain_unit_base::get_tx_version_and_harfork_id_from_events(const std::vector &events, size_t& tx_hardfork_id) const { for (auto it = events.rbegin(); it!= events.rend(); it++) { if(it->type() == typeid(currency::block)) { const currency::block& b = boost::get(*it); - return currency::get_tx_version(get_block_height(b), m_hardforks); + return currency::get_tx_version_and_hardfork_id(get_block_height(b), m_hardforks, tx_hardfork_id); } } - return currency::get_tx_version(0, m_hardforks); + return currency::get_tx_version_and_hardfork_id(0, m_hardforks, tx_hardfork_id); } + bool test_chain_unit_base::verify(const std::string& cb_name, currency::core& c, size_t ev_index, const std::vector &events) { auto cb_it = m_callbacks.find(cb_name); diff --git a/tests/core_tests/chaingen.h b/tests/core_tests/chaingen.h index 962d9b95..f81efb4f 100644 --- a/tests/core_tests/chaingen.h +++ b/tests/core_tests/chaingen.h @@ -257,6 +257,7 @@ public: bool need_core_proxy() const { return false; } // tests can override this in order to obtain core proxy (e.g. for wallet) void set_core_proxy(std::shared_ptr) { /* do nothing */ } uint64_t get_tx_version_from_events(const std::vector &events) const; + uint64_t get_tx_version_and_harfork_id_from_events(const std::vector &events, size_t& tx_hardfork_id) const; virtual void on_test_constructed() {} // called right after test class is constructed by the chaingen void on_test_generator_created(test_generator& generator) const; // tests can override this for special initialization @@ -691,6 +692,41 @@ bool construct_tx(const currency::account_keys& sender_account_keys, uint64_t explicit_consolidated_tx_fee, currency::tx_generation_context& gen_context); +bool construct_tx(const currency::account_keys& sender_account_keys, + const std::vector& sources, + const std::vector& destinations, + const std::vector& extra, + const std::vector& attachments, + currency::transaction& tx, + uint64_t tx_version, + size_t tx_hardfork_id, + crypto::secret_key& one_time_secret_key, + uint64_t unlock_time, + uint64_t expiration_time, + uint8_t tx_outs_attr, + bool shuffle, + uint64_t flags, + uint64_t explicit_consolidated_tx_fee, + currency::tx_generation_context& gen_context); + +bool construct_tx(const currency::account_keys& sender_account_keys, + const std::vector& sources, + const std::vector& destinations, + const std::vector& extra, + const std::vector& attachments, + currency::transaction& tx, + uint64_t tx_version, + crypto::secret_key& one_time_secret_key, + uint64_t unlock_time); + +bool construct_tx(const currency::account_keys& sender_account_keys, + const std::vector& sources, + const std::vector& destinations, + const std::vector& extra, + const std::vector& attachments, + currency::transaction& tx, + uint64_t tx_version); + void get_confirmed_txs(const std::vector& blockchain, const map_hash2tx_t& mtx, map_hash2tx_t& confirmed_txs); bool find_block_chain(const std::vector& events, std::vector& blockchain, map_hash2tx_t& mtx, const crypto::hash& head); bool fill_tx_sources(std::vector& sources, const std::vector& events, diff --git a/tests/core_tests/chaingen_helpers.h b/tests/core_tests/chaingen_helpers.h index 703aec6f..1ae461b5 100644 --- a/tests/core_tests/chaingen_helpers.h +++ b/tests/core_tests/chaingen_helpers.h @@ -313,9 +313,10 @@ inline bool put_alias_via_tx_to_list(const currency::hard_forks_descriptor& hf, el.flags |= currency::tx_destination_entry_flags::tdef_explicit_native_asset_id | currency::tx_destination_entry_flags::tdef_zero_amount_blinding_mask; // all alias-burn outputs must have explicit native asset id and zero amount mask } - uint64_t tx_version = currency::get_tx_version(get_block_height(head_block) + 1, generator.get_hardforks()); // assuming the tx will be in the next block (head_block + 1) + size_t tx_hardfork_id{}; + uint64_t tx_version = currency::get_tx_version_and_hardfork_id(get_block_height(head_block) + 1, generator.get_hardforks(), tx_hardfork_id); // assuming the tx will be in the next block (head_block + 1) tx_set.emplace_back(); - r = construct_tx(miner_acc.get_keys(), sources, destinations, extra, empty_attachment, tx_set.back(), tx_version, generator.last_tx_generated_secret_key, 0); + r = construct_tx(miner_acc.get_keys(), sources, destinations, extra, empty_attachment, tx_set.back(), tx_version, tx_hardfork_id, generator.last_tx_generated_secret_key, 0); PRINT_EVENT_N_TEXT(events, "put_alias_via_tx_to_list()"); events.push_back(tx_set.back()); diff --git a/tests/core_tests/checkpoints_tests.cpp b/tests/core_tests/checkpoints_tests.cpp index d0b88650..50668524 100644 --- a/tests/core_tests/checkpoints_tests.cpp +++ b/tests/core_tests/checkpoints_tests.cpp @@ -930,8 +930,8 @@ bool gen_checkpoints_and_invalid_tx_to_pool::generate(std::vector::generate(std::vector attachments; - if (!construct_tx(bob_account.get_keys(), sources, destinations, attachments, tx_1, this->get_tx_version_from_events(events), uint64_t(0))) + size_t tx_hardfork_id{}; + uint64_t tx_version = get_tx_version_from_events(events); + if (!construct_tx(bob_account.get_keys(), sources, destinations, attachments, tx_1, tx_version, tx_hardfork_id, uint64_t(0))) return false; SET_EVENT_VISITOR_SETT(events, event_visitor_settings::set_txs_kept_by_block, txs_kept_by_block); diff --git a/tests/core_tests/emission_test.cpp b/tests/core_tests/emission_test.cpp index 035726ca..3f2a1127 100644 --- a/tests/core_tests/emission_test.cpp +++ b/tests/core_tests/emission_test.cpp @@ -181,8 +181,9 @@ bool pos_emission_test::generate(std::vector &events) for (size_t i = 0; i < m_pos_entries_to_generate; ++i) destinations.push_back(tx_destination_entry(pos_entry_amount, alice_acc.get_public_address())); - transaction tx_1 = AUTO_VAL_INIT(tx_1); - r = construct_tx(preminer_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_from_events(events), 0); + transaction tx_1{}; + size_t tx_hardfork_id{}; + r = construct_tx(preminer_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); events.push_back(tx_1); MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_acc, tx_1); diff --git a/tests/core_tests/escrow_wallet_common.h b/tests/core_tests/escrow_wallet_common.h index f084809c..83cb9585 100644 --- a/tests/core_tests/escrow_wallet_common.h +++ b/tests/core_tests/escrow_wallet_common.h @@ -167,6 +167,7 @@ inline bool build_custom_escrow_template(const std::vector& ev bc_services::contract_private_details& cpd, uint64_t unlock_time, uint64_t expiration_time, size_t nmix, uint64_t b_fee_release, uint64_t custom_config_mask, uint64_t tx_version, + size_t tx_hardfork_id, transaction& escrow_template_tx, /* OUT */ crypto::secret_key& tx_key_sec, /* OUT */ std::vector& used_sources /* IN/OUT */) @@ -231,7 +232,7 @@ inline bool build_custom_escrow_template(const std::vector& ev if (custom_config_mask & eccf_template_additional_attach) attachments.push_back(tx_comment({ get_random_text(1024) })); - r = construct_tx(a_keys, sources, destinations, extra, attachments, escrow_template_tx, tx_version, tx_key_sec, unlock_time, crypt_addr, expiration_time, CURRENCY_TO_KEY_OUT_RELAXED, true, flags); + r = construct_tx(a_keys, sources, destinations, extra, attachments, escrow_template_tx, tx_version, tx_hardfork_id, tx_key_sec, unlock_time, crypt_addr, expiration_time, CURRENCY_TO_KEY_OUT_RELAXED, true, flags); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); if (custom_config_mask & eccf_template_no_tx_flags) @@ -266,6 +267,7 @@ inline bool build_custom_escrow_proposal(const std::vector& ev uint64_t a_fee_proposal, uint64_t b_fee_release, uint64_t custom_config_mask, uint64_t tx_version, + size_t tx_hardfork_id, transaction& escrow_proposal_tx, /* OUT */ std::vector& used_sources,/* IN/OUT */ bc_services::proposal_body* p_pb = nullptr /* OUT */ ) @@ -283,7 +285,7 @@ inline bool build_custom_escrow_proposal(const std::vector& ev p_pb = &local_pb; if (~custom_config_mask & eccf_proposal_sa_empty_body) { - r = build_custom_escrow_template(events, head, a_keys, cpd, template_unlock_time, template_expiration_time, nmix, b_fee_release, custom_config_mask, tx_version, p_pb->tx_template, p_pb->tx_onetime_secret_key, used_sources); + r = build_custom_escrow_template(events, head, a_keys, cpd, template_unlock_time, template_expiration_time, nmix, b_fee_release, custom_config_mask, tx_version, tx_hardfork_id, p_pb->tx_template, p_pb->tx_onetime_secret_key, used_sources); CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_template failed"); } @@ -309,7 +311,7 @@ inline bool build_custom_escrow_proposal(const std::vector& ev account_public_address crypt_addr = cpd.b_addr; crypto::secret_key tx_key_sec; // stub, not used - r = construct_tx(a_keys, sources, destinations, empty_extra, attachments, escrow_proposal_tx, tx_version, tx_key_sec, unlock_time, crypt_addr, expiration_time, 0, true, (~custom_config_mask & eccf_proposal_inv_flags) ? 0 : TX_FLAG_SIGNATURE_MODE_SEPARATE); + r = construct_tx(a_keys, sources, destinations, empty_extra, attachments, escrow_proposal_tx, tx_version, tx_hardfork_id, tx_key_sec, unlock_time, crypt_addr, expiration_time, 0, true, (~custom_config_mask & eccf_proposal_inv_flags) ? 0 : TX_FLAG_SIGNATURE_MODE_SEPARATE); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); append_vector_by_another_vector(used_sources, sources); @@ -321,7 +323,8 @@ inline bool build_custom_escrow_release_template( const account_keys& b_keys, const bc_services::contract_private_details& cpd, uint64_t unlock_time, uint64_t expiration_time, - uint64_t tx_version, + uint64_t tx_version, + size_t tx_hardfork_id, const transaction& escrow_template_tx, /* IN (needed for ms output, tx pub key) */ uint64_t custom_config_mask, /* IN */ transaction& tx /* OUT */ @@ -420,7 +423,7 @@ inline bool build_custom_escrow_release_template( crypto::secret_key one_time_secret_key = AUTO_VAL_INIT(one_time_secret_key); account_public_address crypt_address = AUTO_VAL_INIT(crypt_address); - bool r = construct_tx(b_keys, sources, destinations, extra, attachments, tx, tx_version, one_time_secret_key, unlock_time, crypt_address, expiration_time, 0, true, tx_flags); + bool r = construct_tx(b_keys, sources, destinations, extra, attachments, tx, tx_version, tx_hardfork_id, one_time_secret_key, unlock_time, crypt_address, expiration_time, 0, true, tx_flags); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); bool tx_fully_signed = false; r = sign_multisig_input_in_tx(tx, 0, b_keys, escrow_template_tx, &tx_fully_signed); @@ -470,6 +473,7 @@ inline bool build_custom_escrow_accept_proposal( uint64_t custom_config_mask, /* IN */ crypto::secret_key one_time_secret_key, /* IN */ uint64_t tx_version, /* IN */ + size_t tx_hardfork_id, /* IN */ transaction& tx, /* IN (escrow template), OUT */ std::vector& used_sources /* IN/OUT */ ) @@ -496,9 +500,9 @@ inline bool build_custom_escrow_accept_proposal( // generate release templates bc_services::escrow_relese_templates_body rtb = AUTO_VAL_INIT(rtb); - r = build_custom_escrow_release_template(BC_ESCROW_SERVICE_INSTRUCTION_RELEASE_NORMAL, b_keys, cpd, release_unlock_time, release_expiration_time, tx_version, tx, custom_config_mask, rtb.tx_normal_template); + r = build_custom_escrow_release_template(BC_ESCROW_SERVICE_INSTRUCTION_RELEASE_NORMAL, b_keys, cpd, release_unlock_time, release_expiration_time, tx_version, tx_hardfork_id, tx, custom_config_mask, rtb.tx_normal_template); CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_release_template(normal) failed"); - r = build_custom_escrow_release_template(BC_ESCROW_SERVICE_INSTRUCTION_RELEASE_BURN, b_keys, cpd, release_unlock_time, release_expiration_time, tx_version, tx, custom_config_mask, rtb.tx_burn_template); + r = build_custom_escrow_release_template(BC_ESCROW_SERVICE_INSTRUCTION_RELEASE_BURN, b_keys, cpd, release_unlock_time, release_expiration_time, tx_version, tx_hardfork_id, tx, custom_config_mask, rtb.tx_burn_template); CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_release_template(burn) failed"); // put release templates into the extra @@ -529,7 +533,7 @@ inline bool build_custom_escrow_accept_proposal( sources.back().separately_signed_tx_complete = true; account_public_address crypt_address = AUTO_VAL_INIT(crypt_address); - r = construct_tx(b_keys, sources, destinations, extra, attachments, tx, tx_version, one_time_secret_key, 0, crypt_address, 0, 0, true, tx_flags); // see comment above regarding unlock_time and expiration_time + r = construct_tx(b_keys, sources, destinations, extra, attachments, tx, tx_version, tx_hardfork_id, one_time_secret_key, 0, crypt_address, 0, 0, true, tx_flags); // see comment above regarding unlock_time and expiration_time CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); return true; @@ -545,6 +549,7 @@ inline bool build_custom_escrow_cancel_proposal( uint64_t custom_config_mask, /* IN */ const transaction& escrow_template_tx, /* IN */ uint64_t tx_version, /* IN */ + size_t tx_hardfork_id, /* IN */ transaction& tx, /* OUT */ std::vector& used_sources /* IN/OUT */ ) @@ -568,7 +573,7 @@ inline bool build_custom_escrow_cancel_proposal( // generate cancel release template bc_services::escrow_cancel_templates_body ctb = AUTO_VAL_INIT(ctb); - r = build_custom_escrow_release_template(BC_ESCROW_SERVICE_INSTRUCTION_RELEASE_CANCEL, a_keys, cpd, release_unlock_time, release_expiration_time, tx_version, escrow_template_tx, custom_config_mask, ctb.tx_cancel_template); + r = build_custom_escrow_release_template(BC_ESCROW_SERVICE_INSTRUCTION_RELEASE_CANCEL, a_keys, cpd, release_unlock_time, release_expiration_time, tx_version, tx_hardfork_id, escrow_template_tx, custom_config_mask, ctb.tx_cancel_template); CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_release_template(cancel) failed"); // put release templates into the extra @@ -593,7 +598,7 @@ inline bool build_custom_escrow_cancel_proposal( if (~custom_config_mask & eccf_cancellation_inv_crypt_address) crypt_address = cpd.b_addr; crypto::secret_key one_time_secret_key = AUTO_VAL_INIT(one_time_secret_key); - r = construct_tx(a_keys, sources, destinations, extra, attachments, tx, tx_version, one_time_secret_key, unlock_time, crypt_address, expiration_time, 0, true, tx_flags); + r = construct_tx(a_keys, sources, destinations, extra, attachments, tx, tx_version, tx_hardfork_id, one_time_secret_key, unlock_time, crypt_address, expiration_time, 0, true, tx_flags); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); return true; diff --git a/tests/core_tests/escrow_wallet_tests.cpp b/tests/core_tests/escrow_wallet_tests.cpp index b511aaab..6c805d29 100644 --- a/tests/core_tests/escrow_wallet_tests.cpp +++ b/tests/core_tests/escrow_wallet_tests.cpp @@ -503,10 +503,11 @@ bool escrow_incorrect_proposal::generate(std::vector& events) // 1. create normal proposal and make sure it goes correctly through out the whole mechanism (test self-check) // if it fails, it means build_custom_escrow_proposal() produced incorrect proposal - uint64_t tx_version = get_tx_version(get_block_height(blk_1r), m_hardforks); + size_t tx_hardfork_id{}; + uint64_t tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_1r), m_hardforks, tx_hardfork_id); uint64_t normal_escrow_mask = eccf_proposal_additional_attach | eccf_template_additional_extra | eccf_template_additional_attach; transaction normal_escrow_proposal_tx = AUTO_VAL_INIT(normal_escrow_proposal_tx); - r = build_custom_escrow_proposal(events, blk_1r, miner_acc.get_keys(), cpd, 0, 0, 0, blk_1r.timestamp + 3600, 0, TESTS_DEFAULT_FEE, TESTS_DEFAULT_FEE, normal_escrow_mask, tx_version, normal_escrow_proposal_tx, used_sources); + r = build_custom_escrow_proposal(events, blk_1r, miner_acc.get_keys(), cpd, 0, 0, 0, blk_1r.timestamp + 3600, 0, TESTS_DEFAULT_FEE, TESTS_DEFAULT_FEE, normal_escrow_mask, tx_version, tx_hardfork_id, normal_escrow_proposal_tx, used_sources); CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_proposal failed"); events.push_back(normal_escrow_proposal_tx); @@ -550,9 +551,9 @@ bool escrow_incorrect_proposal::generate(std::vector& events) uint64_t config_mask = custom_config_masks[i].mask; cpd.comment = "#" + std::to_string(i) + " " + custom_config_masks[i].name; - tx_version = get_tx_version(get_block_height(top_block), m_hardforks); - transaction escrow_proposal_tx = AUTO_VAL_INIT(escrow_proposal_tx); - r = build_custom_escrow_proposal(events, top_block, miner_acc.get_keys(), cpd, 0, 0, 0, top_block.timestamp + 3600, 0, TESTS_DEFAULT_FEE, TESTS_DEFAULT_FEE, config_mask, tx_version, escrow_proposal_tx, used_sources); + tx_version = get_tx_version_and_hardfork_id(get_block_height(top_block), m_hardforks, tx_hardfork_id); + transaction escrow_proposal_tx{}; + r = build_custom_escrow_proposal(events, top_block, miner_acc.get_keys(), cpd, 0, 0, 0, top_block.timestamp + 3600, 0, TESTS_DEFAULT_FEE, TESTS_DEFAULT_FEE, config_mask, tx_version, tx_hardfork_id, escrow_proposal_tx, used_sources); CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_proposal failed"); LOG_PRINT_YELLOW("proposal tx: " << get_transaction_hash(escrow_proposal_tx) << " is built for mask: " << cpd.comment, LOG_LEVEL_0); @@ -579,10 +580,10 @@ bool escrow_incorrect_proposal::generate(std::vector& events) { cpd.comment = "incorrect unlock time (past)"; - transaction tx = AUTO_VAL_INIT(tx); - tx_version = get_tx_version(get_block_height(top_block), m_hardforks); + transaction tx{}; + tx_version = get_tx_version_and_hardfork_id(get_block_height(top_block), m_hardforks, tx_hardfork_id); // set unlock time to the past (suppose it's incorrect for escrow proposals) - r = build_custom_escrow_proposal(events, top_block, miner_acc.get_keys(), cpd, top_block.timestamp, 0, top_block.timestamp, 0, 0, TESTS_DEFAULT_FEE, TESTS_DEFAULT_FEE, eccf_normal, tx_version, tx, used_sources); + r = build_custom_escrow_proposal(events, top_block, miner_acc.get_keys(), cpd, top_block.timestamp, 0, top_block.timestamp, 0, 0, TESTS_DEFAULT_FEE, TESTS_DEFAULT_FEE, eccf_normal, tx_version, tx_hardfork_id, tx, used_sources); CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_proposal failed"); LOG_PRINT_YELLOW("proposal tx: " << get_transaction_hash(tx) << " is built for " << cpd.comment, LOG_LEVEL_0); events.push_back(tx); @@ -592,11 +593,11 @@ bool escrow_incorrect_proposal::generate(std::vector& events) { cpd.comment = "incorrect unlock time (future)"; - transaction tx = AUTO_VAL_INIT(tx); - tx_version = get_tx_version(get_block_height(top_block), m_hardforks); + transaction tx{}; + tx_version = get_tx_version_and_hardfork_id(get_block_height(top_block), m_hardforks, tx_hardfork_id); // set unlock time to the future (suppose it's incorrect for escrow proposals) uint64_t unlock_time = top_block.timestamp + 365 * 24 * 60 * 60; - r = build_custom_escrow_proposal(events, top_block, miner_acc.get_keys(), cpd, unlock_time, 0, unlock_time, 0, 0, TESTS_DEFAULT_FEE, TESTS_DEFAULT_FEE, eccf_normal, tx_version, tx, used_sources); + r = build_custom_escrow_proposal(events, top_block, miner_acc.get_keys(), cpd, unlock_time, 0, unlock_time, 0, 0, TESTS_DEFAULT_FEE, TESTS_DEFAULT_FEE, eccf_normal, tx_version, tx_hardfork_id, tx, used_sources); CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_proposal failed"); LOG_PRINT_YELLOW("proposal tx: " << get_transaction_hash(tx) << " is built for " << cpd.comment, LOG_LEVEL_0); events.push_back(tx); @@ -606,9 +607,9 @@ bool escrow_incorrect_proposal::generate(std::vector& events) { cpd.comment = "template zero expiration time"; - transaction tx = AUTO_VAL_INIT(tx); - tx_version = get_tx_version(get_block_height(top_block), m_hardforks); - r = build_custom_escrow_proposal(events, top_block, miner_acc.get_keys(), cpd, 0, 0, 0, 0, 0, TESTS_DEFAULT_FEE, TESTS_DEFAULT_FEE, eccf_normal, tx_version, tx, used_sources); + transaction tx{}; + tx_version = get_tx_version_and_hardfork_id(get_block_height(top_block), m_hardforks, tx_hardfork_id); + r = build_custom_escrow_proposal(events, top_block, miner_acc.get_keys(), cpd, 0, 0, 0, 0, 0, TESTS_DEFAULT_FEE, TESTS_DEFAULT_FEE, eccf_normal, tx_version, tx_hardfork_id, tx, used_sources); CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_proposal failed"); LOG_PRINT_YELLOW("proposal tx: " << get_transaction_hash(tx) << " is built for " << cpd.comment, LOG_LEVEL_0); events.push_back(tx); @@ -618,11 +619,11 @@ bool escrow_incorrect_proposal::generate(std::vector& events) { cpd.comment = "proposal non-zero expiration time"; - transaction tx = AUTO_VAL_INIT(tx); - tx_version = get_tx_version(get_block_height(top_block), m_hardforks); + transaction tx{}; + tx_version = get_tx_version_and_hardfork_id(get_block_height(top_block), m_hardforks, tx_hardfork_id); uint64_t proposal_expiration_time = top_block.timestamp + 12 * 60 * 60; uint64_t template_expiration_time = top_block.timestamp + 12 * 60 * 60; - r = build_custom_escrow_proposal(events, top_block, miner_acc.get_keys(), cpd, 0, proposal_expiration_time, 0, template_expiration_time, 0, TESTS_DEFAULT_FEE, TESTS_DEFAULT_FEE, eccf_normal, tx_version, tx, used_sources); + r = build_custom_escrow_proposal(events, top_block, miner_acc.get_keys(), cpd, 0, proposal_expiration_time, 0, template_expiration_time, 0, TESTS_DEFAULT_FEE, TESTS_DEFAULT_FEE, eccf_normal, tx_version, tx_hardfork_id, tx, used_sources); CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_proposal failed"); LOG_PRINT_YELLOW("proposal tx: " << get_transaction_hash(tx) << " is built for " << cpd.comment, LOG_LEVEL_0); events.push_back(tx); @@ -1149,17 +1150,18 @@ bool escrow_incorrect_proposal_acceptance::generate(std::vector& events) const destinations.push_back(tx_destination_entry(chunk_amount, bob_acc.get_public_address())); } // no change back to the miner - it will become a fee - transaction tx_1 = AUTO_VAL_INIT(tx_1); - r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_from_events(events), 0); + transaction tx_1{}; + size_t tx_hardfork_id{}; + r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); events.push_back(tx_1); @@ -1949,7 +1952,8 @@ bool escrow_incorrect_cancel_proposal::generate(std::vector& e } // no change back to the miner - it will become a fee transaction tx_1 = AUTO_VAL_INIT(tx_1); - r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_from_events(events), 0); + size_t tx_hardfork_id{}; + r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); events.push_back(tx_1); @@ -1969,27 +1973,27 @@ bool escrow_incorrect_cancel_proposal::generate(std::vector& e // create normal escrow proposal bc_services::proposal_body prop = AUTO_VAL_INIT(prop); - uint64_t tx_version = get_tx_version(get_block_height(blk_1r), m_hardforks); + uint64_t tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_1r), m_hardforks, tx_hardfork_id); transaction escrow_proposal_tx = AUTO_VAL_INIT(escrow_proposal_tx); - r = build_custom_escrow_proposal(events, blk_1r, alice_acc.get_keys(), m_cpd, 0, 0, 0, blk_1r.timestamp + 36000, 0, TESTS_DEFAULT_FEE, m_bob_fee_release, eccf_normal, tx_version, escrow_proposal_tx, used_sources, &prop); + r = build_custom_escrow_proposal(events, blk_1r, alice_acc.get_keys(), m_cpd, 0, 0, 0, blk_1r.timestamp + 36000, 0, TESTS_DEFAULT_FEE, m_bob_fee_release, eccf_normal, tx_version, tx_hardfork_id, escrow_proposal_tx, used_sources, &prop); CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_proposal failed"); events.push_back(escrow_proposal_tx); MAKE_NEXT_BLOCK_TX1(events, blk_2, blk_1r, miner_acc, escrow_proposal_tx); // create normal escrow proposal acceptance transaction escrow_normal_acceptance_tx = prop.tx_template; - tx_version = get_tx_version(get_block_height(blk_2), m_hardforks); + tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_2), m_hardforks, tx_hardfork_id); uint64_t normal_acceptance_mask = eccf_acceptance_no_tsa_compression; - r = build_custom_escrow_accept_proposal(events, blk_2, 0, bob_acc.get_keys(), m_cpd, 0, 0, 0, 0, TESTS_DEFAULT_FEE, m_bob_fee_release, normal_acceptance_mask, prop.tx_onetime_secret_key, tx_version, escrow_normal_acceptance_tx, used_sources); + r = build_custom_escrow_accept_proposal(events, blk_2, 0, bob_acc.get_keys(), m_cpd, 0, 0, 0, 0, TESTS_DEFAULT_FEE, m_bob_fee_release, normal_acceptance_mask, prop.tx_onetime_secret_key, tx_version, tx_hardfork_id, escrow_normal_acceptance_tx, used_sources); CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_accept_proposal failed"); events.push_back(escrow_normal_acceptance_tx); MAKE_NEXT_BLOCK_TX1(events, blk_3, blk_2, miner_acc, escrow_normal_acceptance_tx); // create normal cancel proposal - tx_version = get_tx_version(get_block_height(blk_3), m_hardforks); + tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_3), m_hardforks, tx_hardfork_id); transaction escrow_normal_cancel_proposal_tx = AUTO_VAL_INIT(escrow_normal_cancel_proposal_tx); - r = build_custom_escrow_cancel_proposal(events, blk_3, 0, alice_acc.get_keys(), m_cpd, 0, 0, 0, blk_3.timestamp + 3600, TESTS_DEFAULT_FEE, eccf_normal, prop.tx_template, tx_version, escrow_normal_cancel_proposal_tx, used_sources); + r = build_custom_escrow_cancel_proposal(events, blk_3, 0, alice_acc.get_keys(), m_cpd, 0, 0, 0, blk_3.timestamp + 3600, TESTS_DEFAULT_FEE, eccf_normal, prop.tx_template, tx_version, tx_hardfork_id, escrow_normal_cancel_proposal_tx, used_sources); CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_cancel_proposal failed"); events.push_back(escrow_normal_cancel_proposal_tx); @@ -2057,9 +2061,9 @@ bool escrow_incorrect_cancel_proposal::generate(std::vector& e uint64_t mask = ccm_el.mask; transaction incorrect_cancellation_proposal_tx = prop.tx_template; - uint64_t tx_version = get_tx_version(get_block_height(blk_3), m_hardforks); + tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_3), m_hardforks, tx_hardfork_id); r = build_custom_escrow_cancel_proposal(events, prev_block, 0, alice_acc.get_keys(), m_cpd, ccm_el.unlock_time, ccm_el.expiration_time, ccm_el.release_unlock_time, ccm_el.release_expiration_time, - TESTS_DEFAULT_FEE, mask, prop.tx_template, tx_version, incorrect_cancellation_proposal_tx, used_sources); + TESTS_DEFAULT_FEE, mask, prop.tx_template, tx_version, tx_hardfork_id, incorrect_cancellation_proposal_tx, used_sources); CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_cancel_proposal failed"); // In order to use the same escrow proposal to test different invalid cancellations we need to switch chains after each try @@ -2985,9 +2989,10 @@ bool escrow_proposal_acceptance_in_alt_chain::generate(std::vector& events r = fill_tx_sources(sources, events, blk_0r, miner_acc.get_keys(), m_amount * m_fake_amounts_count + TESTS_DEFAULT_FEE, 0); CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources failed"); - transaction tx_0 = AUTO_VAL_INIT(tx_0); - r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_from_events(events), 0); + transaction tx_0{}; + size_t tx_hardfork_id{}; + r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); uint64_t burned_tx_amount_total = get_burned_amount(tx_0); diff --git a/tests/core_tests/hard_fork_1.cpp b/tests/core_tests/hard_fork_1.cpp index 861b29aa..ff9d0381 100644 --- a/tests/core_tests/hard_fork_1.cpp +++ b/tests/core_tests/hard_fork_1.cpp @@ -437,7 +437,7 @@ bool hard_fork_1_checkpoint_basic_test::generate(std::vector& CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources failed"); transaction tx_1 = AUTO_VAL_INIT(tx_1); r = construct_tx(alice_acc.get_keys(), sources, std::vector{ tx_destination_entry(MK_TEST_COINS(90) - TESTS_DEFAULT_FEE, miner_acc.get_public_address()) }, - empty_attachment, tx_1, get_tx_version_from_events(events), stake_lock_time /* try to use stake unlock time -- should not work as it is not a coinbase */); + empty_attachment, tx_1, get_tx_version_from_events(events), 0, stake_lock_time /* try to use stake unlock time -- should not work as it is not a coinbase */); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); DO_CALLBACK(events, "mark_invalid_tx"); @@ -882,7 +882,7 @@ bool hard_fork_1_pos_locked_height_vs_time::generate(std::vector{ tx_destination_entry(stake_amount / 2, miner_acc.get_public_address()) }, - empty_attachment, tx_1, get_tx_version_from_events(events), stake_unlock_time /* try to use stake unlock time -- should not work as it is not a coinbase */); + empty_attachment, tx_1, get_tx_version_from_events(events), 0, stake_unlock_time /* try to use stake unlock time -- should not work as it is not a coinbase */); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); DO_CALLBACK(events, "mark_invalid_tx"); diff --git a/tests/core_tests/integer_overflow.cpp b/tests/core_tests/integer_overflow.cpp index e73c6cef..33361093 100644 --- a/tests/core_tests/integer_overflow.cpp +++ b/tests/core_tests/integer_overflow.cpp @@ -157,9 +157,10 @@ bool gen_uint_overflow_2::generate(std::vector& events) const // sources.front().amount = destinations[0].amount + destinations[2].amount + destinations[3].amount + TESTS_DEFAULT_FEE destinations.push_back(tx_destination_entry(sources.front().amount - TX_MAX_TRANSFER_AMOUNT - TX_MAX_TRANSFER_AMOUNT + 1 - TESTS_DEFAULT_FEE, bob_addr)); - currency::transaction tx_1; + currency::transaction tx_1{}; std::vector attachments; - if (!construct_tx(miner_account.get_keys(), sources, destinations, attachments, tx_1, get_tx_version_from_events(events), 0)) + size_t tx_hardfork_id{}; + if (!construct_tx(miner_account.get_keys(), sources, destinations, attachments, tx_1, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0)) return false; events.push_back(tx_1); @@ -186,7 +187,7 @@ bool gen_uint_overflow_2::generate(std::vector& events) const currency::transaction tx_2; std::vector attachments2; - if (!construct_tx(bob_account.get_keys(), sources, destinations, attachments2, tx_2, get_tx_version_from_events(events), 0)) + if (!construct_tx(bob_account.get_keys(), sources, destinations, attachments2, tx_2, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0)) return false; events.push_back(tx_2); diff --git a/tests/core_tests/misc_tests.cpp b/tests/core_tests/misc_tests.cpp index b9ccab13..c7b738ed 100644 --- a/tests/core_tests/misc_tests.cpp +++ b/tests/core_tests/misc_tests.cpp @@ -237,8 +237,9 @@ bool block_template_vs_invalid_txs_from_pool::generate(std::vector sources; r = fill_tx_sources(sources, events, blk_0r, miner_acc.get_keys(), de.amount + TESTS_DEFAULT_FEE, 0); CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources failed"); - transaction tx_1m = AUTO_VAL_INIT(tx_1m); - r = construct_tx(miner_acc.get_keys(), sources, std::vector({ de }), empty_attachment, tx_1m, get_tx_version_from_events(events), 0); + transaction tx_1m; + size_t tx_hardfork_id{}; + r = construct_tx(miner_acc.get_keys(), sources, std::vector({ de }), empty_attachment, tx_1m, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); events.push_back(tx_1m); @@ -269,18 +270,18 @@ bool block_template_vs_invalid_txs_from_pool::generate(std::vector(boost::get(tx_1m.vout[se.real_output_in_tx_index]).target).keys.size(); se.ms_sigs_count = 1; - transaction tx_2m = AUTO_VAL_INIT(tx_2m); + transaction tx_2m{}; r = construct_tx(bob_acc.get_keys(), std::vector({ se }), std::vector({ tx_destination_entry(se.amount - TESTS_DEFAULT_FEE, miner_acc.get_public_address()) }), - empty_attachment, tx_2m, get_tx_version_from_events(events), 0); + empty_attachment, tx_2m, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); bool input_fully_signed = false; r = sign_multisig_input_in_tx(tx_2m, 0, bob_acc.get_keys(), tx_1m, &input_fully_signed); CHECK_AND_ASSERT_MES(r && input_fully_signed, false, "sign_multisig_input_in_tx failed, input_fully_signed=" << input_fully_signed); events.push_back(tx_2m); - transaction tx_2ma = AUTO_VAL_INIT(tx_2ma); + transaction tx_2ma{}; r = construct_tx(bob_acc.get_keys(), std::vector({ se }), std::vector({ tx_destination_entry(se.amount - TESTS_DEFAULT_FEE, miner_acc.get_public_address()) }), - empty_attachment, tx_2ma, get_tx_version_from_events(events), 0); + empty_attachment, tx_2ma, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); input_fully_signed = false; r = sign_multisig_input_in_tx(tx_2ma, 0, bob_acc.get_keys(), tx_1m, &input_fully_signed); @@ -436,8 +437,9 @@ bool test_blockchain_vs_spent_multisig_outs::generate(std::vector destinations; r = fill_tx_sources_and_destinations(events, blk_0r, miner_acc, alice_acc, m_alice_initial_balance, TESTS_DEFAULT_FEE, 0, sources, destinations, true /* spends */, false /* unlock time */); CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed"); - r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_from_events(events), 0); + size_t tx_hardfork_id{}; + r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); ADD_CUSTOM_EVENT(events, tx_0); @@ -701,7 +702,8 @@ bool asset_depoyment_and_few_zc_utxos::generate(std::vector& e m_alice_initial_balance = TESTS_DEFAULT_FEE * 100; r = fill_tx_sources(sources, events, blk_0r, miner_acc.get_keys(), m_alice_initial_balance + TESTS_DEFAULT_FEE, 0); CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources failed"); - r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_from_events(events), 0); + size_t tx_hardfork_id{}; + r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); ADD_CUSTOM_EVENT(events, tx_0); @@ -1017,16 +1019,10 @@ bool asset_operation_and_hardfork_checks::generate( CHECK_AND_ASSERT_MES(success, false, "fail to fill sources, destinations"); - tx_version = get_tx_version(get_block_height(blk_0r), - m_hardforks); + size_t tx_hardfork_id{}; + tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_0r), m_hardforks, tx_hardfork_id); - success = construct_tx(miner.get_keys(), - sources, - destinations, - empty_attachment, - tx_0, - tx_version, - 0); + success = construct_tx(miner.get_keys(), sources, destinations, empty_attachment, tx_0, tx_version, tx_hardfork_id, 0); CHECK_AND_ASSERT_MES(success, false, "fail to construct tx_0"); @@ -1058,7 +1054,7 @@ bool asset_operation_and_hardfork_checks::generate( /* to = */ alice.get_public_address(), /* asset_id = */ currency::null_pkey); - tx_version = get_tx_version(get_block_height(blk_1r), m_hardforks); + tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_1r), m_hardforks, tx_hardfork_id); size_t hf_n = m_hardforks.get_the_most_recent_hardfork_id_for_height(get_block_height(blk_1r)); fill_ado_version_based_onhardfork(m_ado_hello, hf_n); fill_adb_version_based_onhardfork(*m_ado_hello.opt_descriptor, hf_n); @@ -1069,6 +1065,7 @@ bool asset_operation_and_hardfork_checks::generate( empty_attachment, tx_1, tx_version, + tx_hardfork_id, stub, 0); @@ -1105,8 +1102,7 @@ bool asset_operation_and_hardfork_checks::generate( CHECK_AND_ASSERT_MES(success, false, "fail to fill sources, destinations"); - tx_version = get_tx_version(get_block_height(blk_2r), - m_hardforks); + tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_2r), m_hardforks, tx_hardfork_id); hf_n = m_hardforks.get_the_most_recent_hardfork_id_for_height(get_block_height(blk_2r)); fill_ado_version_based_onhardfork(m_ado_hello, hf_n); @@ -1118,6 +1114,7 @@ bool asset_operation_and_hardfork_checks::generate( empty_attachment, tx_2, tx_version, + tx_hardfork_id, stub, 0); @@ -1159,6 +1156,7 @@ bool asset_operation_and_hardfork_checks::generate( /* attachments = */ {m_ado_bye}, tx_3, tx_version, + hf_n, 0); CHECK_AND_ASSERT_MES(success, false, "fail to construct tx_3"); @@ -1199,6 +1197,7 @@ bool asset_operation_and_hardfork_checks::generate( /* attachments = */ {m_ado_bye}, tx_4, tx_version, + hf_n, stub, 0); @@ -2068,6 +2067,7 @@ bool asset_current_and_total_supplies_comparative_constraints::generate(std::vec GENERATE_ACCOUNT(miner); GENERATE_ACCOUNT(alice); transaction tx_0{}, tx_1{}, tx_2{}, tx_3{}, tx_4{}; + size_t tx_hardfork_id{}; m_accounts.push_back(miner); m_accounts.push_back(alice); @@ -2091,7 +2091,7 @@ bool asset_current_and_total_supplies_comparative_constraints::generate(std::vec success = fill_tx_sources_and_destinations(events, top, miner.get_keys(), alice.get_public_address(), MK_TEST_COINS(8), TESTS_DEFAULT_FEE, 0, sources, destinations); CHECK_AND_ASSERT_EQ(success, true); - success = construct_tx(miner.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version(get_block_height(top), m_hardforks), 0); + success = construct_tx(miner.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_and_hardfork_id(get_block_height(top), m_hardforks, tx_hardfork_id), tx_hardfork_id, 0); CHECK_AND_ASSERT_EQ(success, true); } @@ -2115,7 +2115,7 @@ bool asset_current_and_total_supplies_comparative_constraints::generate(std::vec destinations.emplace_back(ado.opt_descriptor->current_supply, alice.get_public_address(), null_pkey); CHECK_AND_ASSERT_EQ(ado.opt_descriptor->total_max_supply, 0); CHECK_AND_ASSERT_EQ(ado.opt_descriptor->total_max_supply, ado.opt_descriptor->current_supply); - success = construct_tx(alice.get_keys(), sources, destinations, {ado}, empty_attachment, tx_1, get_tx_version(get_block_height(top), m_hardforks), one_time, 0); + success = construct_tx(alice.get_keys(), sources, destinations, {ado}, empty_attachment, tx_1, get_tx_version_and_hardfork_id(get_block_height(top), m_hardforks, tx_hardfork_id), tx_hardfork_id, one_time, 0); CHECK_AND_ASSERT_EQ(success, true); } @@ -2140,7 +2140,7 @@ bool asset_current_and_total_supplies_comparative_constraints::generate(std::vec CHECK_AND_ASSERT_EQ(success, true); destinations.emplace_back(ado.opt_descriptor->current_supply, alice.get_public_address(), null_pkey); CHECK_AND_ASSERT_MES(ado.opt_descriptor->current_supply > ado.opt_descriptor->total_max_supply, false, "current_supply <= total_max_supply"); - success = construct_tx(alice.get_keys(), sources, destinations, {ado}, empty_attachment, tx_2, get_tx_version(get_block_height(top), m_hardforks), one_time, 0); + success = construct_tx(alice.get_keys(), sources, destinations, {ado}, empty_attachment, tx_2, get_tx_version_and_hardfork_id(get_block_height(top), m_hardforks, tx_hardfork_id), tx_hardfork_id, one_time, 0); CHECK_AND_ASSERT_EQ(success, true); } @@ -2165,7 +2165,7 @@ bool asset_current_and_total_supplies_comparative_constraints::generate(std::vec CHECK_AND_ASSERT_EQ(success, true); destinations.emplace_back(ado.opt_descriptor->current_supply, alice.get_public_address(), null_pkey); CHECK_AND_ASSERT(ado.opt_descriptor->current_supply <= ado.opt_descriptor->total_max_supply, false); - success = construct_tx(alice.get_keys(), sources, destinations, {ado}, empty_attachment, tx_3, get_tx_version(get_block_height(top), m_hardforks), one_time, 0); + success = construct_tx(alice.get_keys(), sources, destinations, {ado}, empty_attachment, tx_3, get_tx_version_and_hardfork_id(get_block_height(top), m_hardforks, tx_hardfork_id), tx_hardfork_id, one_time, 0); CHECK_AND_ASSERT_EQ(success, true); } diff --git a/tests/core_tests/multisig_wallet_tests.cpp b/tests/core_tests/multisig_wallet_tests.cpp index ef4f0c34..ed0978e6 100644 --- a/tests/core_tests/multisig_wallet_tests.cpp +++ b/tests/core_tests/multisig_wallet_tests.cpp @@ -880,7 +880,7 @@ bool multisig_minimum_sigs::generate(std::vector& events) cons r = fill_tx_sources_and_destinations(events, blk_0r, miner_acc.get_keys(), ms_addr_list, amount, TESTS_DEFAULT_FEE, 0, sources, destinations, true, true, 4); CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed"); transaction tx = AUTO_VAL_INIT(tx); - r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx, get_tx_version_from_events(events), 0); + r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx, get_tx_version_from_events(events), 0, 0); CHECK_AND_ASSERT_MES(r == false, false, "construct_tx was expected to fail, but successed"); @@ -893,7 +893,7 @@ bool multisig_minimum_sigs::generate(std::vector& events) cons CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed"); transaction tx_1 = AUTO_VAL_INIT(tx_1); - r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_from_events(events), 0); + r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_from_events(events), 0, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); events.push_back(tx_1); @@ -917,7 +917,7 @@ bool multisig_minimum_sigs::generate(std::vector& events) cons // Transaction should be successfully created, but rejected by the core transaction tx_2 = AUTO_VAL_INIT(tx_2); - r = construct_tx(miner_acc.get_keys(), std::vector({ se }), std::vector({ de }), empty_attachment, tx_2, get_tx_version_from_events(events), 0); + r = construct_tx(miner_acc.get_keys(), std::vector({ se }), std::vector({ de }), empty_attachment, tx_2, get_tx_version_from_events(events), 0, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); bool tx_fully_signed = false; r = sign_multisig_input_in_tx(tx_2, 0, bob_acc.get_keys(), tx_1, &tx_fully_signed); @@ -947,7 +947,7 @@ bool multisig_minimum_sigs::generate(std::vector& events) cons se.ms_sigs_count = 2; transaction tx_3 = AUTO_VAL_INIT(tx_3); - r = construct_tx(miner_acc.get_keys(), std::vector({ se }), std::vector({ tx_destination_entry(se.amount - TESTS_DEFAULT_FEE, bob_acc.get_public_address()) }), empty_attachment, tx_3, get_tx_version_from_events(events), 0); + r = construct_tx(miner_acc.get_keys(), std::vector({ se }), std::vector({ tx_destination_entry(se.amount - TESTS_DEFAULT_FEE, bob_acc.get_public_address()) }), empty_attachment, tx_3, get_tx_version_from_events(events), 0, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); r = sign_multisig_input_in_tx(tx_3, 0, bob_acc.get_keys(), tx_1, &tx_fully_signed); CHECK_AND_ASSERT_MES(r && !tx_fully_signed, false, "sign_multisig_input_in_tx failed, tx_fully_signed : " << tx_fully_signed); @@ -966,7 +966,7 @@ bool multisig_minimum_sigs::generate(std::vector& events) cons CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed"); transaction tx_4 = AUTO_VAL_INIT(tx_4); - r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_4, get_tx_version_from_events(events), 0); + r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_4, get_tx_version_from_events(events), 0, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); events.push_back(tx_4); @@ -984,7 +984,7 @@ bool multisig_minimum_sigs::generate(std::vector& events) cons se.ms_sigs_count = 3; transaction tx_5 = AUTO_VAL_INIT(tx_5); - r = construct_tx(miner_acc.get_keys(), std::vector({ se }), std::vector({ tx_destination_entry(se.amount - TESTS_DEFAULT_FEE, alice_acc.get_public_address()) }), empty_attachment, tx_5, get_tx_version_from_events(events), 0); + r = construct_tx(miner_acc.get_keys(), std::vector({ se }), std::vector({ tx_destination_entry(se.amount - TESTS_DEFAULT_FEE, alice_acc.get_public_address()) }), empty_attachment, tx_5, get_tx_version_from_events(events), 0, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); // use sign_multisig_input_in_tx_custom to create tx with more signatures (3) than minimum_sigs (1) @@ -1009,7 +1009,7 @@ bool multisig_minimum_sigs::generate(std::vector& events) cons CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed"); transaction tx_6 = AUTO_VAL_INIT(tx_6); - r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_6, get_tx_version_from_events(events), 0); + r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_6, get_tx_version_from_events(events), 0, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); events.push_back(tx_6); @@ -1028,7 +1028,7 @@ bool multisig_minimum_sigs::generate(std::vector& events) cons se.ms_sigs_count = 4; transaction tx_7 = AUTO_VAL_INIT(tx_7); - r = construct_tx(miner_acc.get_keys(), std::vector({ se }), std::vector({ tx_destination_entry(se.amount - TESTS_DEFAULT_FEE, alice_acc.get_public_address()) }), empty_attachment, tx_7, get_tx_version_from_events(events), 0); + r = construct_tx(miner_acc.get_keys(), std::vector({ se }), std::vector({ tx_destination_entry(se.amount - TESTS_DEFAULT_FEE, alice_acc.get_public_address()) }), empty_attachment, tx_7, get_tx_version_from_events(events), 0, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); // use sign_multisig_input_in_tx_custom to create tx with more signatures (4) than minimum_sigs (1) @@ -1051,7 +1051,7 @@ bool multisig_minimum_sigs::generate(std::vector& events) cons CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed"); transaction tx_8 = AUTO_VAL_INIT(tx_8); - r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_8, get_tx_version_from_events(events), 0); + r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_8, get_tx_version_from_events(events), 0, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); events.push_back(tx_8); @@ -1071,7 +1071,7 @@ bool multisig_minimum_sigs::generate(std::vector& events) cons se.ms_sigs_count = redundant_keys_count; transaction tx_9 = AUTO_VAL_INIT(tx_9); - r = construct_tx(miner_acc.get_keys(), std::vector({ se }), std::vector({ tx_destination_entry(se.amount - TESTS_DEFAULT_FEE, alice_acc.get_public_address()) }), empty_attachment, tx_9, get_tx_version_from_events(events), 0); + r = construct_tx(miner_acc.get_keys(), std::vector({ se }), std::vector({ tx_destination_entry(se.amount - TESTS_DEFAULT_FEE, alice_acc.get_public_address()) }), empty_attachment, tx_9, get_tx_version_from_events(events), 0, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); boost::get(tx_9.signatures[0]).s.resize(redundant_keys_count, invalid_signature); @@ -1256,7 +1256,7 @@ bool multisig_and_unlock_time::generate(std::vector& events) c r = fill_tx_sources_and_destinations(events, blk_2, alice_acc, bob_acc, amount - TESTS_DEFAULT_FEE * 2, TESTS_DEFAULT_FEE, 0 /*nmix*/, sources, destinations, true, false /* check_for_unlocktime */); CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed"); transaction tx_3{}; - r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_3, get_tx_version_from_events(events), 0); + r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_3, get_tx_version_from_events(events), 0, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); ADD_CUSTOM_EVENT(events, tx_3); @@ -1281,7 +1281,7 @@ bool multisig_and_unlock_time::generate(std::vector& events) c crypto::secret_key stub_key = AUTO_VAL_INIT(stub_key); etc_tx_details_expiration_time extra_expiration_time = AUTO_VAL_INIT(extra_expiration_time); extra_expiration_time.v = expiration_time; - r = construct_tx(miner_acc.get_keys(), sources, destinations, std::vector({ extra_expiration_time }), empty_attachment, tx_4, get_tx_version_from_events(events), stub_key, 0, CURRENCY_TO_KEY_OUT_RELAXED, true); + r = construct_tx(miner_acc.get_keys(), sources, destinations, std::vector({ extra_expiration_time }), empty_attachment, tx_4, get_tx_version_from_events(events), 0, stub_key, 0, CURRENCY_TO_KEY_OUT_RELAXED, true); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); CHECK_AND_ASSERT_MES(get_tx_expiration_time(tx_4) == expiration_time, false, "Expiration time was not correctly set"); DO_CALLBACK(events, "mark_invalid_tx"); @@ -1289,7 +1289,7 @@ bool multisig_and_unlock_time::generate(std::vector& events) c // add similar tx (same sources and destinations) with no expiration_time - should be accepted by the core transaction tx_5 = AUTO_VAL_INIT(tx_5); - r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_extra, empty_attachment, tx_5, get_tx_version_from_events(events), stub_key, 0, CURRENCY_TO_KEY_OUT_RELAXED, true); + r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_extra, empty_attachment, tx_5, get_tx_version_from_events(events), 0, stub_key, 0, CURRENCY_TO_KEY_OUT_RELAXED, true); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); events.push_back(tx_5); @@ -1316,7 +1316,7 @@ bool multisig_and_unlock_time::generate(std::vector& events) c extra_expiration_time = AUTO_VAL_INIT(extra_expiration_time); extra_expiration_time.v = expiration_time; transaction tx_6 = AUTO_VAL_INIT(tx_6); - r = construct_tx(miner_acc.get_keys(), sources, destinations, std::vector({ extra_expiration_time }), empty_attachment, tx_6, get_tx_version_from_events(events), stub_key, 0, CURRENCY_TO_KEY_OUT_RELAXED, true); + r = construct_tx(miner_acc.get_keys(), sources, destinations, std::vector({ extra_expiration_time }), empty_attachment, tx_6, get_tx_version_from_events(events), 0, stub_key, 0, CURRENCY_TO_KEY_OUT_RELAXED, true); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); CHECK_AND_ASSERT_MES(get_tx_expiration_time(tx_6) == expiration_time, false, "Expiration time was not correctly set"); r = sign_multisig_input_in_tx(tx_6, tx_5_ms_out_idx, miner_acc.get_keys(), tx_5, &tx_fully_signed); @@ -1429,7 +1429,7 @@ bool multisig_and_coinbase::generate(std::vector& events) cons destinations.assign({ tx_destination_entry(se.amount - TESTS_DEFAULT_FEE, bob_acc.get_public_address()) }); transaction tx_1 = AUTO_VAL_INIT(tx_1); - r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_from_events(events), 0); + r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_from_events(events), 0, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); bool fully_signed_tx = false; r = sign_multisig_input_in_tx(tx_1, 0, alice_acc.get_keys(), blk_1.miner_tx, &fully_signed_tx); @@ -1493,7 +1493,7 @@ bool multisig_and_coinbase::generate(std::vector& events) cons transaction tx_2 = AUTO_VAL_INIT(tx_2); r = construct_tx(alice_acc.get_keys(), std::vector({ se }), std::vector({ tx_destination_entry(se.amount - TESTS_DEFAULT_FEE, alice_acc.get_public_address()) }), - empty_attachment, tx_2, get_tx_version_from_events(events), 0); + empty_attachment, tx_2, get_tx_version_from_events(events), 0, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); r = sign_multisig_input_in_tx(tx_2, 0, alice_acc.get_keys(), blk_3.miner_tx, &fully_signed_tx); @@ -2259,7 +2259,7 @@ bool multisig_n_participants_seq_signing::generate(std::vector r = fill_tx_sources_and_destinations(events, blk_0r, miner_acc.get_keys(), ms_addr_list, ms_amount, TESTS_DEFAULT_FEE, 0, sources, destinations, true, true, m_minimum_signs_to_spend); CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed"); transaction tx_1 = AUTO_VAL_INIT(tx_1); - r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_from_events(events), 0); + r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_from_events(events), 0, 0); events.push_back(tx_1); MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_acc, tx_1); @@ -2289,7 +2289,7 @@ bool multisig_n_participants_seq_signing::generate(std::vector // construct a transaction (no participants keys are provided, thus no signs for ms input are created) transaction tx = AUTO_VAL_INIT(tx); - r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx, get_tx_version_from_events(events), 0); + r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx, get_tx_version_from_events(events), 0, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); // sign the transaction by (m_minimum_signs_to_spend) participants in random order diff --git a/tests/core_tests/offers_test.cpp b/tests/core_tests/offers_test.cpp index e9be6c2c..39c115ae 100644 --- a/tests/core_tests/offers_test.cpp +++ b/tests/core_tests/offers_test.cpp @@ -633,7 +633,7 @@ bool offer_removing_and_selected_output::generate(std::vector& std::vector sources; r = fill_tx_sources(sources, events, blk_0r, miner_acc.get_keys(), destinations_amount + TESTS_DEFAULT_FEE, 0); CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources failed"); - r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_from_events(events), 0); + r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_from_events(events), 0, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); events.push_back(tx_0); MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_acc, tx_0); diff --git a/tests/core_tests/pos_basic_tests.cpp b/tests/core_tests/pos_basic_tests.cpp index 06fbf71a..c07a2850 100644 --- a/tests/core_tests/pos_basic_tests.cpp +++ b/tests/core_tests/pos_basic_tests.cpp @@ -174,7 +174,8 @@ bool pos_mining_with_decoys::generate(std::vector& events) con destinations.emplace_back(COIN, carol_acc.get_public_address()); transaction tx_0{}; - r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_from_events(events), 0); + size_t tx_hardfork_id{}; + r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); events.push_back(tx_0); MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_acc, tx_0); diff --git a/tests/core_tests/transaction_tests.cpp b/tests/core_tests/transaction_tests.cpp index d884c17e..9bff9d9b 100644 --- a/tests/core_tests/transaction_tests.cpp +++ b/tests/core_tests/transaction_tests.cpp @@ -101,7 +101,7 @@ bool test_transaction_generation_and_ring_signature() transaction tx_rc1; std::vector attachments; - bool r = construct_tx(miner_acc2.get_keys(), sources, destinations, attachments, tx_rc1, get_tx_version(0, hf), 0); + bool r = construct_tx(miner_acc2.get_keys(), sources, destinations, attachments, tx_rc1, get_tx_version(0, hf), 0, 0); CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction"); crypto::hash pref_hash = get_transaction_prefix_hash(tx_rc1); diff --git a/tests/core_tests/tx_validation.cpp b/tests/core_tests/tx_validation.cpp index dea895ea..a0527f4a 100644 --- a/tests/core_tests/tx_validation.cpp +++ b/tests/core_tests/tx_validation.cpp @@ -1239,8 +1239,9 @@ bool tx_expiration_time::generate(std::vector& events) const std::vector destinations; r = fill_tx_sources_and_destinations(events, blk_2, alice_acc.get_keys(), bob_acc.get_public_address(), MK_TEST_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations); CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed"); - transaction tx_2 = AUTO_VAL_INIT(tx_2); - r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_2, get_tx_version_from_events(events), 0); + transaction tx_2{}; + size_t tx_hardfork_id{}; + r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_2, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); set_tx_expiration_time(tx_2, ts_median + TX_EXPIRATION_MEDIAN_SHIFT + 1); // one second greather than minimum allowed r = resign_tx(alice_acc.get_keys(), sources, tx_2); @@ -1258,7 +1259,7 @@ bool tx_expiration_time::generate(std::vector& events) const r = fill_tx_sources_and_destinations(events, blk_3, alice_acc.get_keys(), bob_acc.get_public_address(), MK_TEST_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations); CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed"); transaction tx_3 = AUTO_VAL_INIT(tx_3); - r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_3, get_tx_version_from_events(events), 0); + r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_3, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); set_tx_expiration_time(tx_3, ts_median + TX_EXPIRATION_MEDIAN_SHIFT + 0); // exact expiration time, should not pass (see core condition above) r = resign_tx(alice_acc.get_keys(), sources, tx_3); @@ -1322,8 +1323,9 @@ bool tx_expiration_time_and_block_template::generate(std::vector destinations; bool r = fill_tx_sources_and_destinations(events, blk_0r, miner_acc.get_keys(), miner_acc.get_public_address(), MK_TEST_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations); CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed"); - transaction tx_1 = AUTO_VAL_INIT(tx_1); - r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_from_events(events), 0); + transaction tx_1{}; + size_t tx_hardfork_id{}; + r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); uint64_t tx_1_expiration_time = ts_median + TX_EXPIRATION_MEDIAN_SHIFT + 1; // one second greather than minimum allowed set_tx_expiration_time(tx_1, tx_1_expiration_time); @@ -1394,8 +1396,9 @@ bool tx_expiration_time_and_chain_switching::generate(std::vector destinations; r = fill_tx_sources_and_destinations(events, blk_0r, miner_acc.get_keys(), miner_acc.get_public_address(), MK_TEST_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations); CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed"); - transaction tx_0 = AUTO_VAL_INIT(tx_0); - r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_from_events(events), 0); + transaction tx_0{}; + size_t tx_hardfork_id{}; + r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); uint64_t tx_0_expiration_time = ts_median + TX_EXPIRATION_MEDIAN_SHIFT + 0; // one second less than minimum allowed (see condition above) set_tx_expiration_time(tx_0, tx_0_expiration_time); @@ -1515,8 +1518,9 @@ bool tx_key_image_pool_conflict::generate(std::vector& events) std::vector destinations; r = fill_tx_sources_and_destinations(events, blk_0r, m_miner_acc.get_keys(), bob_acc.get_public_address(), MK_TEST_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations); CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed"); - transaction tx_0 = AUTO_VAL_INIT(tx_0); - r = construct_tx(m_miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_from_events(events), 0); + transaction tx_0{}; + size_t tx_hardfork_id{}; + r = construct_tx(m_miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); LOG_PRINT_YELLOW("tx_0 = " << get_transaction_hash(tx_0), LOG_LEVEL_0); // do not push tx_0 into events yet @@ -1643,15 +1647,18 @@ bool tx_version_against_hardfork::generate(std::vector& events // tx_1 tx_1 is accepted uint64_t tx_version_good = 0, tx_version_bad = 0; + size_t tx_hardfork_id = 0; // select good and bad tx versions based on active hardfork size_t most_recent_hardfork_id = m_hardforks.get_the_most_recent_hardfork_id_for_height(get_block_height(blk_0r)); switch(most_recent_hardfork_id) { case ZANO_HARDFORK_04_ZARCANUM: + tx_hardfork_id = 0; case ZANO_HARDFORK_05: tx_version_good = TRANSACTION_VERSION_POST_HF4; tx_version_bad = TRANSACTION_VERSION_PRE_HF4; + tx_hardfork_id = ZANO_HARDFORK_05; break; default: LOG_ERROR("hardfork " << most_recent_hardfork_id << " is not supported by this test"); @@ -1667,7 +1674,7 @@ bool tx_version_against_hardfork::generate(std::vector& events r = fill_tx_sources_and_destinations(events, blk_0r, miner_acc.get_keys(), miner_acc.get_public_address(), MK_TEST_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations); CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed"); transaction tx_0{}; - r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, tx_version_good, 0); + r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, tx_version_good, tx_hardfork_id, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); events.push_back(tx_0); MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_acc, tx_0); @@ -1681,7 +1688,7 @@ bool tx_version_against_hardfork::generate(std::vector& events r = fill_tx_sources_and_destinations(events, blk_0, miner_acc.get_keys(), miner_acc.get_public_address(), MK_TEST_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations); CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed"); transaction tx_1{}; - r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, tx_version_bad, 0); + r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, tx_version_bad, tx_hardfork_id, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); // check tx pool rejection DO_CALLBACK(events, "mark_invalid_tx"); diff --git a/tests/core_tests/wallet_tests.cpp b/tests/core_tests/wallet_tests.cpp index 79eb631d..3e38e3ee 100644 --- a/tests/core_tests/wallet_tests.cpp +++ b/tests/core_tests/wallet_tests.cpp @@ -2306,7 +2306,7 @@ bool generate_oversized_offer(size_t min_size, size_t max_size, bc_services::off // construct fake tx to estimate it's size transaction tx = AUTO_VAL_INIT(tx); crypto::secret_key one_time_secret_key; - if (!construct_tx(account_keys(), std::vector(), std::vector(), empty_extra, att_container, tx, tx_version, one_time_secret_key, 0, 0, true, 0)) + if (!construct_tx(account_keys(), std::vector(), std::vector(), empty_extra, att_container, tx, tx_version, 0, one_time_secret_key, 0, 0, true, 0)) return false; size_t sz = get_object_blobsize(tx); diff --git a/tests/core_tests/zarcanum_test.cpp b/tests/core_tests/zarcanum_test.cpp index 72dea5b4..472d3315 100644 --- a/tests/core_tests/zarcanum_test.cpp +++ b/tests/core_tests/zarcanum_test.cpp @@ -520,7 +520,8 @@ bool zarcanum_txs_with_big_shuffled_decoy_set_shuffled::generate(std::vector Date: Fri, 27 Dec 2024 19:37:39 +0100 Subject: [PATCH 29/82] tests: fixes for performance_tests and functional_tests --- tests/functional_tests/core_concurrency_test.cpp | 3 ++- tests/performance_tests/single_tx_test_base.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/functional_tests/core_concurrency_test.cpp b/tests/functional_tests/core_concurrency_test.cpp index 3fcbc00c..1d791dcc 100644 --- a/tests/functional_tests/core_concurrency_test.cpp +++ b/tests/functional_tests/core_concurrency_test.cpp @@ -77,7 +77,8 @@ bool create_block_template_manually(const currency::block& prev_block, boost::mu result.miner_tx, block_reward_without_fee, block_reward, - TRANSACTION_VERSION_PRE_HF4); + TRANSACTION_VERSION_PRE_HF4, + 0); CHECK_AND_ASSERT_MES(r, false, "construct_miner_tx failed"); size_t coinbase_size = get_object_blobsize(result.miner_tx); diff --git a/tests/performance_tests/single_tx_test_base.h b/tests/performance_tests/single_tx_test_base.h index a605d624..a3aff814 100644 --- a/tests/performance_tests/single_tx_test_base.h +++ b/tests/performance_tests/single_tx_test_base.h @@ -20,7 +20,7 @@ public: 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)) + 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, 0, blobdata(), CURRENCY_MINER_TX_MAX_OUTS)) return false; m_tx_pub_key = get_tx_pub_key_from_extra(m_tx); return true; From 653b05298b22a9a3a9e200cd73314bd97bf4f43a Mon Sep 17 00:00:00 2001 From: sowle Date: Sat, 28 Dec 2024 00:27:16 +0100 Subject: [PATCH 30/82] coretests: hard_fork_5_tx_version implemented --- tests/core_tests/hard_fork_5.cpp | 79 ++++++++++++++++++++++++++++---- tests/core_tests/hard_fork_5.h | 4 +- 2 files changed, 73 insertions(+), 10 deletions(-) diff --git a/tests/core_tests/hard_fork_5.cpp b/tests/core_tests/hard_fork_5.cpp index 8a88658a..bd0cd4df 100644 --- a/tests/core_tests/hard_fork_5.cpp +++ b/tests/core_tests/hard_fork_5.cpp @@ -7,26 +7,87 @@ using namespace currency; +hard_fork_5_tx_version::hard_fork_5_tx_version() +{ + REGISTER_CALLBACK_METHOD(hard_fork_5_tx_version, c1); +} + bool hard_fork_5_tx_version::generate(std::vector& events) const { // - // Test idea: + // Test idea: ensure that the correct tx.hardfork_id is required after HF5. // + bool r = false; uint64_t ts = test_core_time::get_time(); - GENERATE_ACCOUNT(miner_acc); - GENERATE_ACCOUNT(alice_acc); + 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); - //// rebuild genesis miner tx - //std::vector destinations; - //destinations.emplace_back(MK_TEST_COINS(1), alice_acc.get_public_address()); - //destinations.emplace_back(MK_TEST_COINS(1), alice_acc.get_public_address()); - //CHECK_AND_ASSERT_MES(replace_coinbase_in_genesis_block(destinations, generator, events, blk_0), false, ""); // leftover amount will be also send to miner - DO_CALLBACK(events, "configure_core"); // default configure_core callback will initialize core runtime config with m_hardforks REWIND_BLOCKS_N_WITH_TIME(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 3); + // make a simple tx just to check HF5 tx.hardfork_id rule basic validity MAKE_TX(events, tx_1, miner_acc, alice_acc, MK_TEST_COINS(1), blk_0r); + MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_acc, tx_1); + + // + // construct a tx with an incorrect hardfork_id and make sure it won't be accepted by either the tx pool or the core + // + std::vector sources; + std::vector destinations; + + r = fill_tx_sources_and_destinations(events, blk_1, miner_acc, alice_acc, MK_TEST_COINS(7), TX_DEFAULT_FEE, 4, sources, destinations); + CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed"); + + transaction tx_2{}; + size_t tx_hardfork_id{}; + uint64_t tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_1) + 1, m_hardforks, tx_hardfork_id); + size_t incorrect_tx_hardfork_id = 0; + r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_2, tx_version, incorrect_tx_hardfork_id, 0); // note using incorrect hardfork id here + CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); + // mark as invalid, shouldn't be accepted by the tx pool + DO_CALLBACK(events, "mark_invalid_tx"); + ADD_CUSTOM_EVENT(events, tx_2); + + // now add tx_2 as 'kept_by_block', with tx pool checks turned off + ADD_CUSTOM_EVENT(events, event_visitor_settings(event_visitor_settings::set_txs_kept_by_block, true)); + events.push_back(tx_2); // now tx should be accepted by the pool + ADD_CUSTOM_EVENT(events, event_visitor_settings(event_visitor_settings::set_txs_kept_by_block, false)); + // the block shouldn't be accepted, because of invalid tx_2 + DO_CALLBACK(events, "mark_invalid_block"); + MAKE_NEXT_BLOCK_TX1(events, blk_2_bad, blk_1, miner_acc, tx_2); + + + // + // reconstruct the same tx, now using the correct tx_hardfork_id, and make sure it will be accepted + // + tx_2 = transaction{}; + r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_2, tx_version, tx_hardfork_id, 0); + CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); + ADD_CUSTOM_EVENT(events, tx_2); + MAKE_NEXT_BLOCK_TX1(events, blk_2, blk_1, miner_acc, tx_2); + + REWIND_BLOCKS_N_WITH_TIME(events, blk_2r, blk_2, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + + // epilogue + + DO_CALLBACK(events, "c1"); + + return true; +} + +bool hard_fork_5_tx_version::c1(currency::core& c, size_t ev_index, const std::vector &events) +{ + std::shared_ptr alice_wlt = init_playtime_test_wallet(events, c, ALICE_ACC_IDX); + + CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool"); + + size_t blocks_fetched = 0; + alice_wlt->refresh(blocks_fetched); + CHECK_AND_ASSERT_EQ(blocks_fetched, 2 * CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 5); + + CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt.get(), "alice_wlt", MK_TEST_COINS(8)), false, ""); return true; } diff --git a/tests/core_tests/hard_fork_5.h b/tests/core_tests/hard_fork_5.h index 692d3348..61c79c48 100644 --- a/tests/core_tests/hard_fork_5.h +++ b/tests/core_tests/hard_fork_5.h @@ -6,7 +6,9 @@ #include "wallet_tests_basic.h" -struct hard_fork_5_tx_version : public test_chain_unit_enchanced +struct hard_fork_5_tx_version : public wallet_test { + hard_fork_5_tx_version(); bool generate(std::vector& events) const; + bool c1(currency::core& c, size_t ev_index, const std::vector &events); }; From 059a71fd97e3c879847eff9f1a2a2cdbba61e928 Mon Sep 17 00:00:00 2001 From: sowle Date: Sat, 28 Dec 2024 04:20:50 +0100 Subject: [PATCH 31/82] tx hf id: wallet adaptation --- src/currency_core/currency_format_utils.h | 2 +- src/wallet/wallet2.cpp | 28 +++++++++++------------ src/wallet/wallet2.h | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index 1503baee..b3cfbeed 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -163,7 +163,7 @@ namespace currency uint64_t expiration_time; crypto::public_key spend_pub_key; // only for validations uint64_t tx_version; - uint8_t tx_hardfork_id = 0; + size_t tx_hardfork_id = 0; uint64_t mode_separate_fee = 0; epee::misc_utils::events_dispatcher* pevents_dispatcher = nullptr; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index ac486389..6dc46bc7 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1162,7 +1162,7 @@ void wallet2::accept_proposal(const crypto::hash& contract_id, uint64_t b_accept //build transaction currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp); - ftp.tx_version = this->get_current_tx_version(); + ftp.tx_version = get_current_tx_version_and_hardfork_id(ftp.tx_hardfork_id); prepare_transaction(construct_param, ftp, msc); mark_transfers_as_spent(ftp.selected_transfers, std::string("contract <") + epee::string_tools::pod_to_hex(contract_id) + "> has been accepted with tx <" + epee::string_tools::pod_to_hex(get_transaction_hash(tx)) + ">"); @@ -1182,10 +1182,10 @@ void wallet2::accept_proposal(const crypto::hash& contract_id, uint64_t b_accept *p_acceptance_tx = tx; } //--------------------------------------------------------------------------------- -uint64_t wallet2::get_current_tx_version() +uint64_t wallet2::get_current_tx_version_and_hardfork_id(size_t& tx_hardfork_id) { 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); + return currency::get_tx_version_and_hardfork_id(tx_expected_block_height, this->m_core_runtime_config.hard_forks, tx_hardfork_id); } //--------------------------------------------------------------------------------- void wallet2::finish_contract(const crypto::hash& contract_id, const std::string& release_type, currency::transaction* p_release_tx /* = nullptr */) @@ -1299,7 +1299,7 @@ void wallet2::request_cancel_contract(const crypto::hash& contract_id, uint64_t construct_param.split_strategy_id = get_current_split_strategy(); currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp); - ftp.tx_version = this->get_current_tx_version(); + ftp.tx_version = get_current_tx_version_and_hardfork_id(ftp.tx_hardfork_id); prepare_transaction(construct_param, ftp); currency::transaction tx = AUTO_VAL_INIT(tx); crypto::secret_key sk = AUTO_VAL_INIT(sk); @@ -2393,7 +2393,7 @@ bool wallet2::sweep_bare_unspent_outputs(const currency::account_public_address& currency::finalized_tx ftx{}; currency::finalize_tx_param ftp{}; ftp.pevents_dispatcher = &m_debug_events_dispatcher; - ftp.tx_version = this->get_current_tx_version(); + ftp.tx_version = get_current_tx_version_and_hardfork_id(ftp.tx_hardfork_id); if (!prepare_tx_sources(decoys_count, /*use_all_decoys_if_found_less_than_required*/ true, ftp.sources, group.tids)) { @@ -5924,7 +5924,7 @@ void wallet2::build_escrow_release_templates(crypto::hash multisig_id, construct_params.extra.push_back(tsa); { currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp); - ftp.tx_version = this->get_current_tx_version(); + ftp.tx_version = get_current_tx_version_and_hardfork_id(ftp.tx_hardfork_id); prepare_transaction(construct_params, ftp); crypto::secret_key sk = AUTO_VAL_INIT(sk); finalize_transaction(ftp, tx_release_template, sk, false); @@ -5941,7 +5941,7 @@ void wallet2::build_escrow_release_templates(crypto::hash multisig_id, construct_params.extra.push_back(tsa); { currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp); - ftp.tx_version = this->get_current_tx_version(); + ftp.tx_version = get_current_tx_version_and_hardfork_id(ftp.tx_hardfork_id); prepare_transaction(construct_params, ftp); crypto::secret_key sk = AUTO_VAL_INIT(sk); finalize_transaction(ftp, tx_burn_template, sk, false); @@ -5962,7 +5962,7 @@ void wallet2::build_escrow_cancel_template(crypto::hash multisig_id, construct_tx_param construct_params = AUTO_VAL_INIT(construct_params); currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp); - ftp.tx_version = this->get_current_tx_version(); + ftp.tx_version = get_current_tx_version_and_hardfork_id(ftp.tx_hardfork_id); construct_params.fee = it->second.amount() - (ecrow_details.amount_a_pledge + ecrow_details.amount_to_pay + ecrow_details.amount_b_pledge); construct_params.multisig_id = multisig_id; construct_params.split_strategy_id = get_current_split_strategy(); @@ -6045,7 +6045,7 @@ void wallet2::build_escrow_template(const bc_services::contract_private_details& } currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp); - ftp.tx_version = this->get_current_tx_version(); + ftp.tx_version = get_current_tx_version_and_hardfork_id(ftp.tx_hardfork_id); prepare_transaction(ctp, ftp); selected_transfers = ftp.selected_transfers; @@ -6181,7 +6181,7 @@ void wallet2::send_escrow_proposal(const bc_services::contract_private_details& ctp.unlock_time = unlock_time; currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp); - ftp.tx_version = this->get_current_tx_version(); + ftp.tx_version = get_current_tx_version_and_hardfork_id(ftp.tx_hardfork_id); try { prepare_transaction(ctp, ftp); @@ -6355,7 +6355,7 @@ bool wallet2::build_ionic_swap_template(const wallet_public::ionic_swap_proposal currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp); ftp.mode_separate_fee = ctp.fee; - ftp.tx_version = this->get_current_tx_version(); + ftp.tx_version = get_current_tx_version_and_hardfork_id(ftp.tx_hardfork_id); prepare_transaction(ctp, ftp); selected_transfers = ftp.selected_transfers; @@ -6584,7 +6584,7 @@ bool wallet2::accept_ionic_swap_proposal(const wallet_public::ionic_swap_proposa //build transaction currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp); - ftp.tx_version = this->get_current_tx_version(); + ftp.tx_version = get_current_tx_version_and_hardfork_id(ftp.tx_hardfork_id); ftp.gen_context = ionic_context.gen_context; prepare_transaction(construct_param, ftp, msc); @@ -8153,7 +8153,7 @@ void wallet2::transfer(construct_tx_param& ctp, TIME_MEASURE_START(prepare_transaction_time); currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp); ftp.pevents_dispatcher = &m_debug_events_dispatcher; - ftp.tx_version = this->get_current_tx_version(); + ftp.tx_version = get_current_tx_version_and_hardfork_id(ftp.tx_hardfork_id); if (!prepare_transaction(ctp, ftp)) { result.was_not_prepared = true; @@ -8280,7 +8280,7 @@ void wallet2::sweep_below(size_t fake_outs_count, const currency::account_public } currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp); - ftp.tx_version = this->get_current_tx_version(); + ftp.tx_version = get_current_tx_version_and_hardfork_id(ftp.tx_hardfork_id); bool is_hf4 = this->is_in_hardfork_zone(ZANO_HARDFORK_04_ZARCANUM); if (!payment_id.empty()) set_payment_id_to_tx(ftp.attachments, payment_id, is_hf4); diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 8fcced41..cc4d8f53 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -857,7 +857,7 @@ private: bool handle_cancel_proposal(wallet_public::wallet_transfer_info& wti, const bc_services::escrow_cancel_templates_body& ectb, const std::vector& decrypted_attach); bool handle_expiration_list(uint64_t tx_expiration_ts_median); void handle_contract_expirations(uint64_t tx_expiration_ts_median); - uint64_t get_current_tx_version(); + uint64_t get_current_tx_version_and_hardfork_id(size_t& tx_hardfork_id); void change_contract_state(wallet_public::escrow_contract_details_basic& contract, uint32_t new_state, const crypto::hash& contract_id, const wallet_public::wallet_transfer_info& wti) const; void change_contract_state(wallet_public::escrow_contract_details_basic& contract, uint32_t new_state, const crypto::hash& contract_id, const std::string& reason = "internal intention") const; void load_votes_config(); From 4197736fe245d356f82675ed8be23db082a56670 Mon Sep 17 00:00:00 2001 From: sowle Date: Sat, 28 Dec 2024 04:21:58 +0100 Subject: [PATCH 32/82] coretests: gcc compilation fixed for fill_tx_rpc_inputs --- tests/core_tests/daemon_rpc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/core_tests/daemon_rpc.cpp b/tests/core_tests/daemon_rpc.cpp index f968719e..502db5c0 100644 --- a/tests/core_tests/daemon_rpc.cpp +++ b/tests/core_tests/daemon_rpc.cpp @@ -534,7 +534,7 @@ bool fill_tx_rpc_inputs::c7(const currency::core& core, const size_t event_posit { const auto pointer_entry{core.get_blockchain_storage().get_tx_chain_entry(reference.tx_id)}; - CHECK_AND_ASSERT_NEQ(pointer_entry, nullptr); + CHECK_AND_ASSERT(pointer_entry, false); CHECK_AND_ASSERT(reference.n >= pointer_entry->m_global_output_indexes.size(), false); } } @@ -563,7 +563,7 @@ bool fill_tx_rpc_inputs::c8(const currency::core& core, const size_t event_posit CHECK_AND_ASSERT_EQ(reference.tx_id, currency::null_hash); CHECK_AND_ASSERT_EQ(reference.n, 0u); - CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().get_tx_chain_entry(reference.tx_id), nullptr); + CHECK_AND_ASSERT(core.get_blockchain_storage().get_tx_chain_entry(reference.tx_id), false); } } From 13b09ee91437b9588727130e9080ef8aa7b14f96 Mon Sep 17 00:00:00 2001 From: sowle Date: Sat, 28 Dec 2024 15:17:32 +0100 Subject: [PATCH 33/82] coretests: fill_tx_rpc_inputs temporarily disabled --- tests/core_tests/chaingen_main.cpp | 2 +- tests/core_tests/daemon_rpc.cpp | 3 +++ tests/core_tests/daemon_rpc.h | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index 8c4fef66..6693702e 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -1154,7 +1154,7 @@ int main(int argc, char* argv[]) GENERATE_AND_PLAY(one_block); GENERATE_AND_PLAY(gen_ring_signature_1); GENERATE_AND_PLAY(gen_ring_signature_2); - GENERATE_AND_PLAY(fill_tx_rpc_inputs); + //GENERATE_AND_PLAY(fill_tx_rpc_inputs); temporary disable, waiting for fix from @stepan-dolgorukov //GENERATE_AND_PLAY(gen_ring_signature_big); // Takes up to XXX hours (if CURRENCY_MINED_MONEY_UNLOCK_WINDOW == 10) // tests for outputs mixing in diff --git a/tests/core_tests/daemon_rpc.cpp b/tests/core_tests/daemon_rpc.cpp index 502db5c0..ca09027e 100644 --- a/tests/core_tests/daemon_rpc.cpp +++ b/tests/core_tests/daemon_rpc.cpp @@ -1,3 +1,6 @@ +// Copyright (c) 2024 Zano Project +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "chaingen.h" #include "daemon_rpc.h" diff --git a/tests/core_tests/daemon_rpc.h b/tests/core_tests/daemon_rpc.h index 75efa31b..3802b53f 100644 --- a/tests/core_tests/daemon_rpc.h +++ b/tests/core_tests/daemon_rpc.h @@ -1,3 +1,6 @@ +// Copyright (c) 2024 Zano Project +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. #pragma once #include From 6ab3d465294b34032b10b758c8f8279a9889d796 Mon Sep 17 00:00:00 2001 From: sowle Date: Sat, 28 Dec 2024 18:20:14 +0100 Subject: [PATCH 34/82] gcc compilation fix --- tests/core_tests/chaingen.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index 91fbe462..4203f616 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -1923,6 +1923,7 @@ bool construct_tx(const currency::account_keys& sender_account_keys, crypto::secret_key& one_time_secret_key, uint64_t unlock_time) { + [[maybe_unused]] tx_generation_context gen_context{}; return construct_tx(sender_account_keys, sources, destinations, @@ -1937,7 +1938,7 @@ bool construct_tx(const currency::account_keys& sender_account_keys, true, /* shuffle */ 0, /* flags */ 0, /* explicit_consolidated_tx_fee */ - tx_generation_context{} + gen_context /* tx_generation_context */ ); } @@ -1949,6 +1950,8 @@ bool construct_tx(const currency::account_keys& sender_account_keys, currency::transaction& tx, uint64_t tx_version) { + [[maybe_unused]] tx_generation_context gen_context{}; + [[maybe_unused]] crypto::secret_key tx_sec_key{}; return construct_tx(sender_account_keys, sources, destinations, @@ -1956,14 +1959,14 @@ bool construct_tx(const currency::account_keys& sender_account_keys, attachments, tx, tx_version, - crypto::secret_key{}, /* one_time_secret_key */ + tx_sec_key, /* one_time_secret_key */ 0, /* unlock_time */ 0, /* expiration_time */ CURRENCY_TO_KEY_OUT_RELAXED, /* tx_outs_attr */ true, /* shuffle */ 0, /* flags */ 0, /* explicit_consolidated_tx_fee */ - tx_generation_context{} + gen_context /* tx_generation_context */ ); } From ad2b10116dccc409ca817d2ed6b47642b3d7337a Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 30 Dec 2024 15:37:14 +0100 Subject: [PATCH 35/82] coretests: presumably all tests fixed: multisig_and_unlock_time, multisig_and_coinbase, pos_altblocks_validation@5, gen_wallet_alias_and_unconfirmed_txs@5, hard_fork_4_consolidated_txs@5, multisig_and_checkpoints@0 --- tests/core_tests/hard_fork_4.cpp | 8 ++++++-- tests/core_tests/multisig_wallet_tests.cpp | 12 ++++++------ tests/core_tests/pos_block_builder.cpp | 10 +++++----- tests/core_tests/pos_block_builder.h | 2 ++ tests/core_tests/wallet_tests.cpp | 4 +++- 5 files changed, 22 insertions(+), 14 deletions(-) diff --git a/tests/core_tests/hard_fork_4.cpp b/tests/core_tests/hard_fork_4.cpp index a87a1479..dc5fc492 100644 --- a/tests/core_tests/hard_fork_4.cpp +++ b/tests/core_tests/hard_fork_4.cpp @@ -82,7 +82,9 @@ bool hard_fork_4_consolidated_txs::generate(std::vector& event 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, + size_t tx_hardfork_id{}; + uint64_t tx_version = get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id); + r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_extra, empty_attachment, tx_1, tx_version, tx_hardfork_id, 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"); @@ -119,7 +121,9 @@ bool hard_fork_4_consolidated_txs::generate(std::vector& event std::vector destinations; - r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_extra, empty_attachment, tx_1, get_tx_version_from_events(events), one_time_secret_key, + size_t tx_hardfork_id{}; + uint64_t tx_version = get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id); + r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_extra, empty_attachment, tx_1, tx_version, tx_hardfork_id, one_time_secret_key, 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"); diff --git a/tests/core_tests/multisig_wallet_tests.cpp b/tests/core_tests/multisig_wallet_tests.cpp index ed0978e6..4c2dc2dc 100644 --- a/tests/core_tests/multisig_wallet_tests.cpp +++ b/tests/core_tests/multisig_wallet_tests.cpp @@ -1202,7 +1202,7 @@ bool multisig_and_unlock_time::generate(std::vector& events) c uint64_t unlock_time_2 = blk_0r.timestamp + DIFFICULTY_TOTAL_TARGET * 6 + CURRENCY_LOCKED_TX_ALLOWED_DELTA_SECONDS; transaction tx_1 = AUTO_VAL_INIT(tx_1); - r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_from_events(events), unlock_time, CURRENCY_TO_KEY_OUT_RELAXED, true); + r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_from_events(events), 0, unlock_time, CURRENCY_TO_KEY_OUT_RELAXED, true); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); CHECK_AND_ASSERT_MES(get_tx_max_unlock_time(tx_1) == unlock_time, false, "Unlock time was not correctly set"); events.push_back(tx_1); @@ -1232,7 +1232,7 @@ bool multisig_and_unlock_time::generate(std::vector& events) c // tx_2 should be created ok, but rejected by the core, as one of input refers to a locked tx // Note: tx_2 has unlock_time_2 specified transaction tx_2 = AUTO_VAL_INIT(tx_2); - r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_2, get_tx_version_from_events(events), unlock_time_2, CURRENCY_TO_KEY_OUT_RELAXED, true); + r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_2, get_tx_version_from_events(events), 0, unlock_time_2, CURRENCY_TO_KEY_OUT_RELAXED, true); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); bool tx_fully_signed = false; @@ -1256,7 +1256,7 @@ bool multisig_and_unlock_time::generate(std::vector& events) c r = fill_tx_sources_and_destinations(events, blk_2, alice_acc, bob_acc, amount - TESTS_DEFAULT_FEE * 2, TESTS_DEFAULT_FEE, 0 /*nmix*/, sources, destinations, true, false /* check_for_unlocktime */); CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed"); transaction tx_3{}; - r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_3, get_tx_version_from_events(events), 0, 0); + r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_3, get_tx_version_from_events(events), 0, 0 /* unlock time */, 0 /* mix attib */); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); ADD_CUSTOM_EVENT(events, tx_3); @@ -1459,7 +1459,7 @@ bool multisig_and_coinbase::generate(std::vector& events) cons r = fill_tx_sources_and_destinations(events, prev_block, miner_acc.get_keys(), ms_addr_list, blk_2_reward, TESTS_DEFAULT_FEE, 0, sources, destinations, false, false, 1); CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed"); transaction miner_tx = AUTO_VAL_INIT(miner_tx); - r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, miner_tx, get_tx_version_from_events(events), height + CURRENCY_MINED_MONEY_UNLOCK_WINDOW, CURRENCY_TO_KEY_OUT_RELAXED, true); + r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, miner_tx, get_tx_version_from_events(events), 0, height + CURRENCY_MINED_MONEY_UNLOCK_WINDOW, CURRENCY_TO_KEY_OUT_RELAXED, true); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); // replace vin with coinbase input @@ -1477,7 +1477,7 @@ bool multisig_and_coinbase::generate(std::vector& events) cons r = generator.construct_block_manually(b, prev_block, miner_acc, test_generator::bf_miner_tx, 0, 0, 0, null_hash, 1, miner_tx); CHECK_AND_ASSERT_MES(r, false, "construct_block_manually failed"); } - events.push_back(blk_3); + ADD_CUSTOM_EVENT(events, blk_3); // rewind blocks to be able to spend mined money REWIND_BLOCKS_N(events, blk_3r, blk_3, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); @@ -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, "fda3e645fbfd0f4852aa68e6ad021c9005c9faf2d7ba6b1b3c8e24efb9c0e8d0"); + checkpoints.add_checkpoint(15, "a78fa870608991aa773d5d5aaf684ac77fea30c3e103b00d3c05c15912215c31"); c.set_checkpoints(std::move(checkpoints)); return true; diff --git a/tests/core_tests/pos_block_builder.cpp b/tests/core_tests/pos_block_builder.cpp index 6ebd50ab..a6e4cd4e 100644 --- a/tests/core_tests/pos_block_builder.cpp +++ b/tests/core_tests/pos_block_builder.cpp @@ -28,6 +28,7 @@ void pos_block_builder::step1_init_header(const hard_forks_descriptor& hardforks m_height = block_height; m_context.zarcanum = hardforks.is_hardfork_active_for_height(ZANO_HARDFORK_04_ZARCANUM, m_height); + m_miner_tx_version = get_tx_version_and_hardfork_id(m_height, hardforks, m_miner_tx_hardfork_id); m_step = 1; } @@ -160,9 +161,6 @@ void pos_block_builder::step4_generate_coinbase_tx(size_t median_size, { CHECK_AND_ASSERT_THROW_MES(m_step == 3, "pos_block_builder: incorrect step sequence"); - uint64_t tx_version = m_context.zarcanum ? TRANSACTION_VERSION_POST_HF4 : TRANSACTION_VERSION_PRE_HF4; - // TODO @#@# tx_hardfork_id - pos_entry pe{}; pe.stake_unlock_time = 0; // TODO pe.amount = m_context.stake_amount; @@ -173,7 +171,8 @@ void pos_block_builder::step4_generate_coinbase_tx(size_t median_size, size_t estimated_block_size = m_txs_total_size; m_block.miner_tx = transaction{}; bool r = construct_miner_tx(m_height, median_size, already_generated_coins, estimated_block_size, m_total_fee, - reward_receiver_address, stakeholder_address, m_block.miner_tx, block_reward_without_fee, m_block_reward, tx_version, 0, extra_nonce, max_outs, true, pe, &m_miner_tx_tgc, tx_one_time_key_to_use); + reward_receiver_address, stakeholder_address, m_block.miner_tx, block_reward_without_fee, m_block_reward, m_miner_tx_version, m_miner_tx_hardfork_id, + extra_nonce, max_outs, true, pe, &m_miner_tx_tgc, tx_one_time_key_to_use); CHECK_AND_ASSERT_THROW_MES(r, "construct_miner_tx failed"); estimated_block_size = m_txs_total_size + get_object_blobsize(m_block.miner_tx); @@ -182,7 +181,8 @@ void pos_block_builder::step4_generate_coinbase_tx(size_t median_size, { m_block.miner_tx = transaction{}; r = construct_miner_tx(m_height, median_size, already_generated_coins, estimated_block_size, m_total_fee, - reward_receiver_address, stakeholder_address, m_block.miner_tx, block_reward_without_fee, m_block_reward, tx_version, 0, extra_nonce, max_outs, true, pe, &m_miner_tx_tgc, tx_one_time_key_to_use); + reward_receiver_address, stakeholder_address, m_block.miner_tx, block_reward_without_fee, m_block_reward, m_miner_tx_version, m_miner_tx_hardfork_id, + extra_nonce, max_outs, true, pe, &m_miner_tx_tgc, tx_one_time_key_to_use); CHECK_AND_ASSERT_THROW_MES(r, "construct_homemade_pos_miner_tx failed"); cumulative_size = m_txs_total_size + get_object_blobsize(m_block.miner_tx); diff --git a/tests/core_tests/pos_block_builder.h b/tests/core_tests/pos_block_builder.h index fdf7a297..a0014f1e 100644 --- a/tests/core_tests/pos_block_builder.h +++ b/tests/core_tests/pos_block_builder.h @@ -76,6 +76,8 @@ struct pos_block_builder uint64_t m_total_fee = 0; //currency::stake_kernel m_stake_kernel {}; size_t m_height = 0; + size_t m_miner_tx_hardfork_id = 0; + uint64_t m_miner_tx_version = 0; size_t m_pos_stake_output_gindex = 0; uint64_t m_block_reward = 0; currency::tx_generation_context m_miner_tx_tgc {}; diff --git a/tests/core_tests/wallet_tests.cpp b/tests/core_tests/wallet_tests.cpp index 3e38e3ee..e3039a06 100644 --- a/tests/core_tests/wallet_tests.cpp +++ b/tests/core_tests/wallet_tests.cpp @@ -1661,7 +1661,9 @@ bool gen_wallet_alias_and_unconfirmed_txs::generate(std::vector({ ai }), empty_attachment, tx_alice_alias, get_tx_version_from_events(events), sk, 0); + size_t tx_hardfork_id{}; + uint64_t tx_version = get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id); + r = construct_tx(miner_acc.get_keys(), sources, destinations, std::vector({ ai }), empty_attachment, tx_alice_alias, tx_version, tx_hardfork_id, sk, 0); CHECK_AND_ASSERT_MES(r, false, "construct_tx failed"); ADD_CUSTOM_EVENT(events, tx_alice_alias); From 303e216b266602b33685f588cd8b58001da77037 Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 6 Jan 2025 16:05:47 +0100 Subject: [PATCH 36/82] ui update (PR 136) --- 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 638f98f9..8304b635 160000 --- a/src/gui/qt-daemon/layout +++ b/src/gui/qt-daemon/layout @@ -1 +1 @@ -Subproject commit 638f98f9e25fa3c2f88338b7efe4b1c45ea0e23c +Subproject commit 8304b635c45b19a55ab6bfc90b7181ba49e295ad From 81e77ba37b1dc2b57a51997e35cb4d24563e392c Mon Sep 17 00:00:00 2001 From: zano build machine Date: Mon, 6 Jan 2025 18:06:45 +0300 Subject: [PATCH 37/82] === build number: 372 -> 373 === --- 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 9b2e4cac..ea6efb85 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "1" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 372 +#define PROJECT_VERSION_BUILD_NO 373 #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 bd4d54e491fcb38ee1fa936418c8b3eccb562afa Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 9 Jan 2025 20:26:02 +0400 Subject: [PATCH 38/82] added docker sources for remote node --- utils/docker/remote-node-mobile/Dockerfile | 160 +++++++++++++++++++++ utils/docker/remote-node-mobile/nginx.conf | 73 ++++++++++ 2 files changed, 233 insertions(+) create mode 100644 utils/docker/remote-node-mobile/Dockerfile create mode 100644 utils/docker/remote-node-mobile/nginx.conf diff --git a/utils/docker/remote-node-mobile/Dockerfile b/utils/docker/remote-node-mobile/Dockerfile new file mode 100644 index 00000000..0d08e778 --- /dev/null +++ b/utils/docker/remote-node-mobile/Dockerfile @@ -0,0 +1,160 @@ +########################################################################################### +## zanod Dockerfile +########################################################################################### + +# +# Usage: +# (make sure you have correct permission for /var/data/zano-data prior to run!) +# +# docker run --restart=always -v /var/data/zano-data:/home/zano/.Zano -p 11121:11121 -p 11211:11211 --name=zanod -dit zanoproject/remote-note +# +# To get into container and interact with the daemon: +# docker attach zanod +# +# To detach from container and left it running: +# Ctrl+P, Ctrl+Q +# +# To stop container: +# docker stop zanod +# +# To build with different lib versions, pass through --build-arg's +# docker build --build-arg OPENSSL_VERSION_DOT=1.1.1n --build-arg OPENSSL_HASH=40dceb51a4f6a5275bde0e6bf20ef4b91bfc32ed57c0552e2e8e15463372b17a -f utils/docker/Dockerfile . +# +# Available Build Args +# - CMake Version: CMAKE_VERSION_DOT, CMAKE_HASH +# - Boost Version: BOOST_VERSION, BOOST_VERSION_DOT, BOOST_HASH +# - OpenSSL Version: OPENSSL_VERSION_DOT, OPENSSL_HASH + +# +# Build Zano +# + +FROM ubuntu:18.04 as build-prep + +ENV DEBIAN_FRONTEND noninteractive + +RUN apt update && \ + apt install -y build-essential \ + libicu-dev \ + libz-dev \ + curl \ + gcc-8 \ + g++-8 \ + git + +RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 700 --slave /usr/bin/g++ g++ /usr/bin/g++-7 && \ + update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 800 --slave /usr/bin/g++ g++ /usr/bin/g++-8 + +WORKDIR /root + +# Lib Settings +ARG CMAKE_VERSION_DOT=3.16.9 +ARG CMAKE_HASH=d71eda07d6ecf3964de65a0e36d0b171565e1aced56ba9f53ca3783406b5cacf + +ARG BOOST_VERSION=1_84_0 +ARG BOOST_VERSION_DOT=1.84.0 +ARG BOOST_HASH=cc4b893acf645c9d4b698e9a0f08ca8846aa5d6c68275c14c3e7949c24109454 + +ARG OPENSSL_VERSION_DOT=1.1.1w +ARG OPENSSL_HASH=cf3098950cb4d853ad95c0841f1f9c6d3dc102dccfcacd521d93925208b76ac8 + +# Environment Variables +ENV BOOST_ROOT /root/boost_${BOOST_VERSION} +ENV OPENSSL_ROOT_DIR=/root/openssl + +########################################################## +# Split download & compile to use dockers caching layers # +########################################################## + +# Download CMake +RUN set -ex \ + && curl https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION_DOT}/cmake-${CMAKE_VERSION_DOT}-Linux-x86_64.sh -OL\ + && echo "${CMAKE_HASH} cmake-${CMAKE_VERSION_DOT}-Linux-x86_64.sh" | sha256sum -c + +# Download Boost +RUN set -ex \ + && curl -L -o boost_${BOOST_VERSION}.tar.bz2 https://downloads.sourceforge.net/project/boost/boost/${BOOST_VERSION_DOT}/boost_${BOOST_VERSION}.tar.bz2 \ + && sha256sum boost_${BOOST_VERSION}.tar.bz2 \ + && echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c\ + && tar -xvf boost_${BOOST_VERSION}.tar.bz2 + + +# Download OpenSSL +RUN curl https://www.openssl.org/source/openssl-${OPENSSL_VERSION_DOT}.tar.gz -OL \ + && sha256sum openssl-${OPENSSL_VERSION_DOT}.tar.gz \ + && echo "${OPENSSL_HASH} openssl-${OPENSSL_VERSION_DOT}.tar.gz" | sha256sum -c + + +# Compile CMake +RUN set -ex \ + && mkdir /opt/cmake \ + && sh cmake-3.16.9-Linux-x86_64.sh --prefix=/opt/cmake --skip-license\ + && ln -s /opt/cmake/bin/cmake /usr/local/bin/cmake\ + && cmake --version\ + && rm cmake-3.16.9-Linux-x86_64.sh + +# Compile Boost +RUN set -ex \ + && cd boost_${BOOST_VERSION} \ + && ./bootstrap.sh --with-libraries=system,filesystem,thread,date_time,chrono,regex,serialization,atomic,program_options,locale,timer,log \ + && ./b2 + +# Compile OpenSSL +RUN set -ex \ + && tar xaf openssl-${OPENSSL_VERSION_DOT}.tar.gz \ + && rm openssl-${OPENSSL_VERSION_DOT}.tar.gz \ + && cd openssl-${OPENSSL_VERSION_DOT} \ + && ./config --prefix=/root/openssl --openssldir=/root/openssl shared zlib \ + && make \ + && make test \ + && make install \ + && cd .. \ + && rm -rf openssl-${OPENSSL_VERSION_DOT} + +FROM build-prep as build + +# Zano + +RUN pwd && mem_avail_gb=$(( $(getconf _AVPHYS_PAGES) * $(getconf PAGE_SIZE) / (1024 * 1024 * 1024) )) &&\ + make_job_slots=$(( $mem_avail_gb < 4 ? 1 : $mem_avail_gb / 4)) &&\ + echo make_job_slots=$make_job_slots &&\ + set -x &&\ + git clone --single-branch --recursive https://github.com/hyle-team/zano.git &&\ + cd zano &&\ + mkdir build && cd build &&\ + cmake -D STATIC=TRUE .. &&\ + make -j $make_job_slots daemon simplewallet + + +# +# Run Zano +# + +FROM ubuntu:18.04 + +# Install dependencies and Nginx +RUN apt update && apt install -y \ + nginx \ + curl \ + && apt clean + +RUN useradd -ms /bin/bash zano &&\ + mkdir -p /home/zano/.Zano &&\ + chown -R zano:zano /home/zano/.Zano + +USER zano:zano + +WORKDIR /home/zano +COPY --chown=zano:zano --from=build /root/zano/build/src/zanod . +COPY --chown=zano:zano --from=build /root/zano/build/src/simplewallet . + +# Copy Nginx configuration +USER root +COPY nginx.conf /etc/nginx/nginx.conf + +# blockchain loaction +VOLUME /home/zano/.Zano + +EXPOSE 11121 11211 33340 + +CMD service nginx start && ./zanod --disable-upnp --log-level=0 diff --git a/utils/docker/remote-node-mobile/nginx.conf b/utils/docker/remote-node-mobile/nginx.conf new file mode 100644 index 00000000..245e8ed9 --- /dev/null +++ b/utils/docker/remote-node-mobile/nginx.conf @@ -0,0 +1,73 @@ +events {} + +http { + + ## + # Basic Settings + ## + + limit_conn_zone $binary_remote_addr zone=addr:10m; + limit_req_zone $binary_remote_addr zone=global_limit:10m rate=10r/s; + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + # server_tokens off; + + # server_names_hash_bucket_size 64; + # server_name_in_redirect off; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + ## + # SSL Settings + ## + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE + ssl_prefer_server_ciphers on; + + ## + # Logging Settings + ## + + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/error.log; + + ## + # Gzip Settings + ## + + gzip on; + + include /etc/nginx/conf.d/*.conf; + include /etc/nginx/sites-enabled/*; + + + #mainnet + server { + listen 33340; + listen [::]:33340; + + # Apply globally to all locations + limit_req zone=global_limit burst=20 nodelay; + limit_conn addr 30; + + access_log /var/log/nginx/reverse-access.log; + error_log /var/log/nginx/reverse-error.log; + + + location /general_info + { + root /home/mobile_app_config; + add_header Cache-Control no-cache; + # set the Expires header to 31 December 2037 23:59:59 GMT, and the Cache-Control max-age to 10 years + expires 1s; + } + + location ~ ^/(json_rpc|getheight|gettransactions|sendrawtransaction|force_relay|getinfo|getblocks\.bin|get_o_indexes\.bin|get_o_indexes\.bin|getrandom_outs\.bin|getrandom_outs1\.bin|getrandom_outs2\.bin|getrandom_outs3\.bin|set_maintainers_info\.bin|get_tx_pool\.bin|check_keyimages\.bin|get_pos_details\.bin) { + proxy_pass http://127.0.0.1:11211$uri; + } + } +} From e2a70189b3b2f81d5be82d04fa279ceab682793a Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 14 Jan 2025 18:57:50 +0100 Subject: [PATCH 39/82] OpenSSL 3.x support --- contrib/epee/include/storages/parserse_base_utils.h | 4 +--- contrib/tor-connect | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/contrib/epee/include/storages/parserse_base_utils.h b/contrib/epee/include/storages/parserse_base_utils.h index bd40c688..d27bfca7 100644 --- a/contrib/epee/include/storages/parserse_base_utils.h +++ b/contrib/epee/include/storages/parserse_base_utils.h @@ -23,10 +23,8 @@ // (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 namespace epee { diff --git a/contrib/tor-connect b/contrib/tor-connect index b589edb1..1be2073e 160000 --- a/contrib/tor-connect +++ b/contrib/tor-connect @@ -1 +1 @@ -Subproject commit b589edb1906dccb387cfeded6ed12286c5f0405f +Subproject commit 1be2073ed3da5e9e6e94e8362548df26a22b1bd2 From cc33fd8b9ca1fcc46824635156ac7b133b28d0ee Mon Sep 17 00:00:00 2001 From: sowle Date: Thu, 16 Jan 2025 04:24:00 +0100 Subject: [PATCH 40/82] fixed more serious warnings for gcc --- contrib/epee/include/gzip_encoding.h | 4 ++++ src/currency_core/currency_core.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/contrib/epee/include/gzip_encoding.h b/contrib/epee/include/gzip_encoding.h index e2e1ea2c..bea62d01 100644 --- a/contrib/epee/include/gzip_encoding.h +++ b/contrib/epee/include/gzip_encoding.h @@ -260,6 +260,10 @@ namespace net_utils m_pcb.reset(new abstract_callback(cb)); return content_encoding_gzip::update_in(piece_of_transfer); } + + virtual void stop(std::string& OUT collect_remains) override + {} + template bool stop(callback_t cb) {return true;} diff --git a/src/currency_core/currency_core.h b/src/currency_core/currency_core.h index feeca5f4..32f62b0d 100644 --- a/src/currency_core/currency_core.h +++ b/src/currency_core/currency_core.h @@ -136,8 +136,8 @@ namespace currency void check_free_space(); - blockchain_storage m_blockchain_storage; tx_memory_pool m_mempool; + blockchain_storage m_blockchain_storage; i_currency_protocol* m_pprotocol; i_critical_error_handler* m_critical_error_handler; epee::critical_section m_incoming_tx_lock; From 819fd97261e5aa777519d219850fbcaa73aed240 Mon Sep 17 00:00:00 2001 From: sowle Date: Thu, 16 Jan 2025 05:49:58 +0100 Subject: [PATCH 41/82] fixed more serious warnings for gcc --- .../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 1bd2db1c..0eefa26d 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h +++ b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h @@ -117,7 +117,7 @@ namespace epee static bool unserialize_stl_container_t_val(stl_container& container, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname) { container.clear(); - typename stl_container::value_type exchange_val; + typename stl_container::value_type exchange_val{}; typename t_storage::harray hval_array = stg.get_first_value(pname, exchange_val, hparent_section); if(!hval_array) return false; container.push_back(std::move(exchange_val)); From dcd7f6296882f347443084f29c4229b8fa82115f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=D1=91pa=20Dolgorukov?= <63650851+stepan-dolgorukov@users.noreply.github.com> Date: Mon, 20 Jan 2025 08:21:27 +0500 Subject: [PATCH 42/82] coretests: Fix an execution of the core test "fill_tx_rpc_inputs", rename callbacks (#498) * Core tests: implement a test of the function "blockchain_storage::fill_tx_rpc_inputs" * Fix test execution when compiling via gcc 8.4.0 * Rename callbacks in the test "fill_tx_rpc_inputs" --- tests/core_tests/chaingen_main.cpp | 2 +- tests/core_tests/daemon_rpc.cpp | 96 ++++++++++++++++-------------- tests/core_tests/daemon_rpc.h | 1 + 3 files changed, 52 insertions(+), 47 deletions(-) diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index 6693702e..8c4fef66 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -1154,7 +1154,7 @@ int main(int argc, char* argv[]) GENERATE_AND_PLAY(one_block); GENERATE_AND_PLAY(gen_ring_signature_1); GENERATE_AND_PLAY(gen_ring_signature_2); - //GENERATE_AND_PLAY(fill_tx_rpc_inputs); temporary disable, waiting for fix from @stepan-dolgorukov + GENERATE_AND_PLAY(fill_tx_rpc_inputs); //GENERATE_AND_PLAY(gen_ring_signature_big); // Takes up to XXX hours (if CURRENCY_MINED_MONEY_UNLOCK_WINDOW == 10) // tests for outputs mixing in diff --git a/tests/core_tests/daemon_rpc.cpp b/tests/core_tests/daemon_rpc.cpp index ca09027e..70d38898 100644 --- a/tests/core_tests/daemon_rpc.cpp +++ b/tests/core_tests/daemon_rpc.cpp @@ -1,6 +1,7 @@ -// Copyright (c) 2024 Zano Project +// Copyright (c) 2025 Zano Project // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. + #include "chaingen.h" #include "daemon_rpc.h" @@ -47,7 +48,7 @@ bool fill_tx_rpc_inputs::generate(std::vector& events) const tx.vin.push_back(std::move(input)); } - DO_CALLBACK_PARAMS_STR(events, "c6", t_serializable_object_to_blob(tx)); + DO_CALLBACK_PARAMS_STR(events, "c3", t_serializable_object_to_blob(tx)); } // A transaction with several "txin_to_key" inputs those have different .amount values. @@ -77,7 +78,7 @@ bool fill_tx_rpc_inputs::generate(std::vector& events) const tx.vin.push_back(std::move(input)); } - DO_CALLBACK_PARAMS_STR(events, "c3", t_serializable_object_to_blob(tx)); + DO_CALLBACK_PARAMS_STR(events, "c4", t_serializable_object_to_blob(tx)); } // A transaction with inputs of all possible types. @@ -98,7 +99,7 @@ bool fill_tx_rpc_inputs::generate(std::vector& events) const tx.vin.push_back(std::move(currency::txin_multisig{})); - DO_CALLBACK_PARAMS_STR(events, "c4", t_serializable_object_to_blob(tx)); + DO_CALLBACK_PARAMS_STR(events, "c5", t_serializable_object_to_blob(tx)); } REWIND_BLOCKS_N_WITH_TIME(events, blk_0r, blk_0, miner, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); @@ -162,7 +163,7 @@ bool fill_tx_rpc_inputs::generate(std::vector& events) const tx.vin.push_back(std::move(input)); } - DO_CALLBACK_PARAMS_STR(events, "c5", t_serializable_object_to_blob(tx)); + DO_CALLBACK_PARAMS_STR(events, "c6", t_serializable_object_to_blob(tx)); } /* A wrong reference by an object of the type "ref_by_id": a value of the attribute ".n" representing an offset is greater than a length of a container of outputs.The function "fill_tx_rpc_inputs" @@ -278,6 +279,44 @@ bool fill_tx_rpc_inputs::c3(const currency::core& core, const size_t event_posit CHECK_AND_ASSERT_EQ(info.pub_key.empty(), true); CHECK_AND_ASSERT_EQ(info.outs.empty(), true); + { + CHECK_AND_ASSERT_EQ(info.ins.size(), 1); + + { + CHECK_AND_ASSERT_EQ(info.ins.front().amount, 0); + CHECK_AND_ASSERT_EQ(info.ins.front().multisig_count, 0); + CHECK_AND_ASSERT_EQ(info.ins.front().htlc_origin.empty(), true); + CHECK_AND_ASSERT_EQ(info.ins.front().kimage_or_ms_id, epee::string_tools::pod_to_hex(currency::null_ki)); + CHECK_AND_ASSERT_EQ(info.ins.front().global_indexes.empty(), true); + CHECK_AND_ASSERT_EQ(info.ins.front().etc_options.empty(), true); + } + } + + CHECK_AND_ASSERT_EQ(info.id.empty(), true); + CHECK_AND_ASSERT_EQ(info.extra.empty(), true); + CHECK_AND_ASSERT_EQ(info.attachments.empty(), true); + CHECK_AND_ASSERT_EQ(info.object_in_json.empty(), true); + + return true; +} + +bool fill_tx_rpc_inputs::c4(const currency::core& core, const size_t event_position, const std::vector& events) const +{ + currency::transaction tx{}; + currency::tx_rpc_extended_info info{}; + + CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(tx, boost::get(events.at(event_position)).callback_params), true); + CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().fill_tx_rpc_inputs(info, tx), true); + CHECK_AND_ASSERT_EQ(info.blob.empty(), true); + CHECK_AND_ASSERT_EQ(info.blob_size, 0); + CHECK_AND_ASSERT_EQ(info.fee, 0); + CHECK_AND_ASSERT_EQ(info.amount, 0); + CHECK_AND_ASSERT_EQ(info.timestamp, 0); + CHECK_AND_ASSERT_EQ(info.keeper_block, 0); + CHECK_AND_ASSERT_EQ(info.id.empty(), true); + CHECK_AND_ASSERT_EQ(info.pub_key.empty(), true); + CHECK_AND_ASSERT_EQ(info.outs.empty(), true); + { CHECK_AND_ASSERT_EQ(info.ins.size(), 3); @@ -317,7 +356,7 @@ bool fill_tx_rpc_inputs::c3(const currency::core& core, const size_t event_posit return true; } -bool fill_tx_rpc_inputs::c4(const currency::core& core, const size_t event_position, const std::vector& events) const +bool fill_tx_rpc_inputs::c5(const currency::core& core, const size_t event_position, const std::vector& events) const { currency::transaction tx{}; currency::tx_rpc_extended_info info{}; @@ -366,7 +405,7 @@ bool fill_tx_rpc_inputs::c4(const currency::core& core, const size_t event_posit return true; } -bool fill_tx_rpc_inputs::c5(const currency::core& core, const size_t event_position, const std::vector& events) const +bool fill_tx_rpc_inputs::c6(const currency::core& core, const size_t event_position, const std::vector& events) const { currency::transaction tx{}; currency::tx_rpc_extended_info info{}; @@ -478,44 +517,6 @@ bool fill_tx_rpc_inputs::c5(const currency::core& core, const size_t event_posit return true; } -bool fill_tx_rpc_inputs::c6(const currency::core& core, const size_t event_position, const std::vector& events) const -{ - currency::transaction tx{}; - currency::tx_rpc_extended_info info{}; - - CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(tx, boost::get(events.at(event_position)).callback_params), true); - CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().fill_tx_rpc_inputs(info, tx), true); - CHECK_AND_ASSERT_EQ(info.blob.empty(), true); - CHECK_AND_ASSERT_EQ(info.blob_size, 0); - CHECK_AND_ASSERT_EQ(info.fee, 0); - CHECK_AND_ASSERT_EQ(info.amount, 0); - CHECK_AND_ASSERT_EQ(info.timestamp, 0); - CHECK_AND_ASSERT_EQ(info.keeper_block, 0); - CHECK_AND_ASSERT_EQ(info.id.empty(), true); - CHECK_AND_ASSERT_EQ(info.pub_key.empty(), true); - CHECK_AND_ASSERT_EQ(info.outs.empty(), true); - - { - CHECK_AND_ASSERT_EQ(info.ins.size(), 1); - - { - CHECK_AND_ASSERT_EQ(info.ins.front().amount, 0); - CHECK_AND_ASSERT_EQ(info.ins.front().multisig_count, 0); - CHECK_AND_ASSERT_EQ(info.ins.front().htlc_origin.empty(), true); - CHECK_AND_ASSERT_EQ(info.ins.front().kimage_or_ms_id, epee::string_tools::pod_to_hex(currency::null_ki)); - CHECK_AND_ASSERT_EQ(info.ins.front().global_indexes.empty(), true); - CHECK_AND_ASSERT_EQ(info.ins.front().etc_options.empty(), true); - } - } - - CHECK_AND_ASSERT_EQ(info.id.empty(), true); - CHECK_AND_ASSERT_EQ(info.extra.empty(), true); - CHECK_AND_ASSERT_EQ(info.attachments.empty(), true); - CHECK_AND_ASSERT_EQ(info.object_in_json.empty(), true); - - return true; -} - bool fill_tx_rpc_inputs::c7(const currency::core& core, const size_t event_position, const std::vector& events) const { currency::transaction tx{}; @@ -566,7 +567,10 @@ bool fill_tx_rpc_inputs::c8(const currency::core& core, const size_t event_posit CHECK_AND_ASSERT_EQ(reference.tx_id, currency::null_hash); CHECK_AND_ASSERT_EQ(reference.n, 0u); - CHECK_AND_ASSERT(core.get_blockchain_storage().get_tx_chain_entry(reference.tx_id), false); + + const auto pointer_entry{core.get_blockchain_storage().get_tx_chain_entry(reference.tx_id)}; + + CHECK_AND_ASSERT(pointer_entry == nullptr, false); } } diff --git a/tests/core_tests/daemon_rpc.h b/tests/core_tests/daemon_rpc.h index 3802b53f..72897ddd 100644 --- a/tests/core_tests/daemon_rpc.h +++ b/tests/core_tests/daemon_rpc.h @@ -1,6 +1,7 @@ // Copyright (c) 2024 Zano Project // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. + #pragma once #include From 1087be7b0acfe00676da787da0b6cc04cbdf35a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=D1=91pa=20Dolgorukov?= <63650851+stepan-dolgorukov@users.noreply.github.com> Date: Tue, 21 Jan 2025 05:12:44 +0500 Subject: [PATCH 43/82] coretests: implement the tests "block_reward_in_main_chain_basic", "block_reward_in_alt_chain_basic" (#493) * Core tests: implement tests "block_reward_in_main_chain_basic", "block_reward_in_alt_chain_basic" * Use an automatic variable type deduction * Call "assert_reward" callback before the callback "assert_balance" * Update comments for the test "block_reward_in_alt_chain_basic" --- tests/core_tests/block_validation.cpp | 462 +++++++++++++++++++++++++- tests/core_tests/block_validation.h | 25 +- tests/core_tests/chaingen_main.cpp | 2 + 3 files changed, 487 insertions(+), 2 deletions(-) diff --git a/tests/core_tests/block_validation.cpp b/tests/core_tests/block_validation.cpp index c5a911a7..75c453e2 100644 --- a/tests/core_tests/block_validation.cpp +++ b/tests/core_tests/block_validation.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2023 Zano Project +// Copyright (c) 2014-2025 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 @@ -730,3 +730,463 @@ bool block_with_correct_prev_id_on_wrong_height::assert_blk_2_has_wrong_height(c return true; } + +struct block_reward_in_main_chain_basic::argument_assert +{ + uint64_t m_height{}, m_balance{}; + std::list m_rewards{}; + + argument_assert() = default; + + template + argument_assert(const test* instance, uint64_t height, const std::list& blk_tx_fees = {}, const argument_assert previous = {}) : m_height{height} + { + CHECK_AND_ASSERT_THROW(instance, std::runtime_error{"Pointer to an instance of the test equals to the nullptr."}); + CHECK_AND_ASSERT_THROW(m_height >= previous.m_height, std::runtime_error{"A height specified in the previous argument is greather than current height."}); + + if (height == 0) + { + m_rewards.push_back(PREMINE_AMOUNT); + m_balance = m_rewards.back(); + } + + else + { + m_balance = previous.m_balance; + + for (auto fee_iterator{blk_tx_fees.rbegin()}; fee_iterator != blk_tx_fees.rend(); ++fee_iterator) + { + if (height != 0) + { + m_rewards.push_back(COIN); + + if (const auto& fee{*fee_iterator}; fee <= m_rewards.back()) + { + if (instance->m_hardforks.is_hardfork_active_for_height(ZANO_HARDFORK_04_ZARCANUM, height)) + { + m_rewards.back() -= fee; + } + } + + m_balance += m_rewards.back(); + } + + else + { + m_balance += PREMINE_AMOUNT; + } + + --height; + } + } + + CHECK_AND_ASSERT_THROW(m_rewards.size() > 0, std::runtime_error{"A list of the rewards is empty."}); + } + + BEGIN_SERIALIZE() + FIELD(m_height) + FIELD(m_balance) + FIELD(m_rewards) + END_SERIALIZE() +}; + +block_reward_in_main_chain_basic::block_reward_in_main_chain_basic() +{ + REGISTER_CALLBACK_METHOD(block_reward_in_main_chain_basic, assert_balance); + REGISTER_CALLBACK_METHOD(block_reward_in_main_chain_basic, assert_reward); +} + +bool block_reward_in_main_chain_basic::generate(std::vector& events) const +{ + // The test idea: make sure that receiving rewards for block insertion is counted correctly. + + const auto assert_balance{[&events](const argument_assert& argument) -> void + { + DO_CALLBACK_PARAMS_STR(events, "assert_balance", t_serializable_object_to_blob(argument)); + } + }; + + const auto assert_reward{[&events](const argument_assert& argument) -> void + { + DO_CALLBACK_PARAMS_STR(events, "assert_reward", t_serializable_object_to_blob(argument)); + } + }; + + GENERATE_ACCOUNT(miner); + MAKE_GENESIS_BLOCK(events, blk_0, miner, test_core_time::get_time()); + argument_assert argument{this, get_block_height(blk_0)}; + + m_accounts.push_back(miner); + assert_reward(argument); + // Make sure the balance equals to the PREMINE_AMOUNT. + assert_balance(argument); + DO_CALLBACK(events, "configure_core"); + + MAKE_NEXT_BLOCK(events, blk_1, blk_0, miner); + + argument = argument_assert{this, get_block_height(blk_1), {0}, argument}; + assert_balance(argument); + assert_reward(argument); + + REWIND_BLOCKS_N(events, blk_1r, blk_1, miner, CURRENCY_MINED_MONEY_UNLOCK_WINDOW - 1); + + argument = argument_assert{this, get_block_height(blk_1r), std::list(CURRENCY_MINED_MONEY_UNLOCK_WINDOW - 1), argument}; + assert_balance(argument); + assert_reward(argument); + + MAKE_TX_FEE(events, tx_0, miner, miner, MK_TEST_COINS(1), TESTS_DEFAULT_FEE, blk_1r); + MAKE_NEXT_BLOCK_TX1(events, blk_2, blk_1r, miner, tx_0); + + argument = {this, get_block_height(blk_2), {TESTS_DEFAULT_FEE}, argument}; + assert_reward(argument); + // Make sure in the balance change in the case of a transaction with the default fee. + assert_balance(argument); + + MAKE_TX_FEE(events, tx_1, miner, miner, MK_TEST_COINS(3), 2 * TESTS_DEFAULT_FEE, blk_2); + MAKE_TX_FEE(events, tx_2, miner, miner, MK_TEST_COINS(2), 3 * TESTS_DEFAULT_FEE, blk_2); + + const std::list txs{tx_1, tx_2}; + MAKE_NEXT_BLOCK_TX_LIST(events, blk_3, blk_2, miner, txs); + + argument = argument_assert{this, get_block_height(blk_3), {(2 + 3) * TESTS_DEFAULT_FEE}, argument}; + assert_reward(argument); + // A case of one inserted block with a several transactions with a non default fees. + assert_balance(argument); + + MAKE_TX_FEE(events, tx_3, miner, miner, MK_TEST_COINS(1), COIN + TESTS_DEFAULT_FEE, blk_3); + MAKE_NEXT_BLOCK(events, blk_4, blk_3, miner); + + argument = argument_assert{this, get_block_height(blk_4), {COIN + TESTS_DEFAULT_FEE}, argument}; + assert_reward(argument); + // A transaction inside blk_4 has a fee greater than a block reward. blk_4 includes only one transaction. + assert_balance(argument); + + MAKE_TX_FEE(events, tx_4, miner, miner, MK_TEST_COINS(1), 76 * COIN + 14 * TESTS_DEFAULT_FEE, blk_4); + MAKE_NEXT_BLOCK(events, blk_5, blk_4, miner); + + argument = argument_assert{this, get_block_height(blk_5), {76 * COIN + 14 * TESTS_DEFAULT_FEE}, argument}; + assert_reward(argument); + // A transaction inside blk_5 has a fee greater than a block reward. blk_5 includes only one transaction. + assert_balance(argument); + + REWIND_BLOCKS_N(events, blk_5r, blk_5, miner, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + + argument = argument_assert{this, get_block_height(blk_5r), std::list(CURRENCY_MINED_MONEY_UNLOCK_WINDOW), argument}; + assert_reward(argument); + assert_balance(argument); + + return true; +} + +bool block_reward_in_main_chain_basic::assert_balance(currency::core& core, size_t event_index, const std::vector& events) const +{ + argument_assert argument{}; + + { + const auto serialized_argument{boost::get(events.at(event_index)).callback_params}; + + CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(argument, serialized_argument), true); + } + + CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().get_top_block_height(), argument.m_height); + + const auto wallet{init_playtime_test_wallet(events, core, m_accounts.front())}; + + CHECK_AND_ASSERT(wallet, false); + wallet->refresh(); + CHECK_AND_ASSERT_EQ(wallet->balance(), argument.m_balance); + + return true; +} + +bool block_reward_in_main_chain_basic::assert_reward(currency::core& core, size_t event_index, const std::vector& events) const +{ + argument_assert argument{}; + + { + const auto serialized_argument{boost::get(events.at(event_index)).callback_params}; + + CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(argument, serialized_argument), true); + } + + for (const auto expected_reward : argument.m_rewards) + { + uint64_t reward{}; + + CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().get_block_reward_by_main_chain_height(argument.m_height, reward), true); + CHECK_AND_ASSERT_EQ(reward, expected_reward); + --argument.m_height; + } + + return true; +} + +struct block_reward_in_alt_chain_basic::argument_assert +{ + uint64_t m_height{}, m_balance{}; + crypto::hash blk_id{}; + std::list m_rewards{}; + + argument_assert() = default; + + template + argument_assert(const test* instance, const block& block, const std::list& blk_tx_fees = {}, const argument_assert previous = {}) : blk_id{get_block_hash(block)} + { + CHECK_AND_ASSERT_THROW(instance, std::runtime_error{"Pointer to an instance of the test equals to the nullptr."}); + + auto height{get_block_height(block)}; + + m_height = height; + + if (height == 0) + { + m_rewards.push_back(PREMINE_AMOUNT); + m_balance = m_rewards.back(); + return; + } + + m_balance = previous.m_balance; + + for (auto fee_iterator{blk_tx_fees.rbegin()}; fee_iterator != blk_tx_fees.rend(); ++fee_iterator) + { + if (height != 0) + { + m_rewards.push_back(COIN); + + if (const auto& fee{*fee_iterator}; fee <= m_rewards.back()) + { + if (instance->m_hardforks.is_hardfork_active_for_height(ZANO_HARDFORK_04_ZARCANUM, height)) + { + m_rewards.back() -= fee; + } + } + + m_balance += m_rewards.back(); + } + + else + { + m_balance += PREMINE_AMOUNT; + } + + --height; + } + + CHECK_AND_ASSERT_THROW(m_rewards.size() > 0, std::runtime_error{"A list of the rewards is empty."}); + } + + BEGIN_SERIALIZE() + FIELD(m_height) + FIELD(m_balance) + FIELD(m_rewards) + FIELD(blk_id) + END_SERIALIZE() +}; + +block_reward_in_alt_chain_basic::block_reward_in_alt_chain_basic() +{ + REGISTER_CALLBACK_METHOD(block_reward_in_alt_chain_basic, assert_balance); + REGISTER_CALLBACK_METHOD(block_reward_in_alt_chain_basic, assert_reward); +} + +bool block_reward_in_alt_chain_basic::generate(std::vector& events) const +{ + // The test idea: make sure that receiving rewards for block insertion is counted correctly. + + const auto assert_balance{[&events](const argument_assert& argument) -> void + { + DO_CALLBACK_PARAMS_STR(events, "assert_balance", t_serializable_object_to_blob(argument)); + } + }; + + const auto assert_reward{[&events](const argument_assert& argument) -> void + { + DO_CALLBACK_PARAMS_STR(events, "assert_reward", t_serializable_object_to_blob(argument)); + } + }; + + GENERATE_ACCOUNT(miner); + MAKE_GENESIS_BLOCK(events, blk_0, miner, test_core_time::get_time()); + argument_assert argument{this, blk_0}, argument_alt{}; + + /* 0 + (blk_0) */ + + m_accounts.push_back(miner); + // Make sure a reward for the blk_0 equals to PREMINE_AMOUNT. + assert_reward(argument); + // Make sure the balance equals to the PREMINE_AMOUNT. + assert_balance(argument); + DO_CALLBACK(events, "configure_core"); + + REWIND_BLOCKS_N(events, blk_0r, blk_0, miner, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + + /* 0 10 + (blk_0) - ... - (blk_0r) */ + + // A case of a 10 sequentally inserted empty sblocks. + argument_alt = argument = argument_assert{this, blk_0r, std::list(CURRENCY_MINED_MONEY_UNLOCK_WINDOW), argument}; + // Miner inserted 10 empty blocks. A sum of the rewards for them equals to 10 coins. + assert_reward(argument); + // Make sure the balance equals to PREMINE_AMOUNT + 10 * COIN. + assert_balance(argument); + + MAKE_TX_FEE(events, tx_0, miner, miner, MK_TEST_COINS(1), TESTS_DEFAULT_FEE, blk_0r); + MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner, tx_0); + + /* 0 10 11 + (blk_0) - ... - (blk_0r) - (blk_1) + {tx_0} */ + + MAKE_TX_FEE(events, tx_1, miner, miner, MK_TEST_COINS(1), 33 * TESTS_DEFAULT_FEE, blk_0r); + MAKE_NEXT_BLOCK_TX1(events, blk_1a, blk_0r, miner, tx_1); + + /* 0 10 11 + (blk_0) - ... - (blk_0r) - (blk_1a) + | {tx_1} + | + \ 11 + - (blk_1) + {tx_0} + + height(blk_1a) = height(blk_1) + fee(tx_1) > fee(tx_0). */ + + CHECK_AND_ASSERT_EQ(get_block_height(blk_1), get_block_height(blk_1a)); + + // Case of an alt block on the height 11 with greater total fee than total fee of blk_1 - the top of the main chain. + argument_alt = argument_assert{this, blk_1a, {33 * TESTS_DEFAULT_FEE}, argument_alt}; + argument = argument_assert{this, blk_1, {TESTS_DEFAULT_FEE}, argument}; + + if (m_hardforks.is_hardfork_active_for_height(ZANO_HARDFORK_04_ZARCANUM, get_block_height(blk_1))) + { + // Make sure that a reward for blk_1 equals to COIN. + assert_reward(argument_alt); + // Make sure that the balance equals to PREMINE_AMOUNT + 11 * COIN - 33 * TESTS_DEFAULT_FEE. + assert_balance(argument_alt); + } + + else + { + // Make sure that a reward for blk_1a equals to COIN. + assert_reward(argument); + // Make sure that the balance equals to PREMINE_AMOUNT + 11 * COIN. + assert_balance(argument); + } + + MAKE_TX_FEE(events, tx_2, miner, miner, MK_TEST_COINS(1), 8 * TESTS_DEFAULT_FEE, blk_1); + MAKE_TX_FEE(events, tx_3, miner, miner, MK_TEST_COINS(1), 57 * TESTS_DEFAULT_FEE, blk_1); + const std::list txs_0{tx_2, tx_3}; + + MAKE_NEXT_BLOCK_TX_LIST(events, blk_2, blk_1, miner, txs_0); + + /* 0 10 11 12 + (blk_0) - ... - (blk_0r) - (blk_1) - (blk_2) + | {tx_0} {tx_2, tx_3} + | + \ 11 + - (blk_1a) + {tx_1} + + height(blk_2) > height(blk_1a). */ + + // A case of block on the height 12 in the main chain. + argument = argument_assert{this, blk_2, {(8 + 57) * TESTS_DEFAULT_FEE}, argument}; + // A reward of blk_2 equals to coin. + assert_reward(argument); + /* HF3: The balance equals to PREMINE_AMOUNT + 12 * COIN. + HF4: The balance equals to PREMINE_AMOUNT + 12 * COIN - 65 * TESTS_DEFAULT_FEE. */ + assert_balance(argument); + + const auto& head_blk_for_txs_on_height_12{m_hardforks.is_hardfork_active_for_height(ZANO_HARDFORK_04_ZARCANUM, get_block_height(blk_2)) ? blk_1a : blk_0r}; + MAKE_TX_FEE(events, tx_4, miner, miner, MK_TEST_COINS(2), 15 * TESTS_DEFAULT_FEE, head_blk_for_txs_on_height_12); + MAKE_TX_FEE(events, tx_5, miner, miner, MK_TEST_COINS(5), 29 * TESTS_DEFAULT_FEE, head_blk_for_txs_on_height_12); + MAKE_TX_FEE(events, tx_6, miner, miner, MK_TEST_COINS(7), 22 * TESTS_DEFAULT_FEE, head_blk_for_txs_on_height_12); + const std::list txs_1{tx_4, tx_5, tx_6}; + MAKE_NEXT_BLOCK_TX_LIST(events, blk_2a, blk_1a, miner, txs_1); + + CHECK_AND_ASSERT_EQ(get_block_height(blk_2a), get_block_height(blk_2)); + + /* 0 10 11 12 + (blk_0) - ... - (blk_0r) - (blk_1a) - (blk_2a) + | {tx_1} {tx_4, tx_5, tx_6} + | + \ 11 12 + - (blk_1) - (blk_2) + {tx_0} {tx_2, tx_3} + + height(blk_2a) = height(blk_2) = 12 + fee(tx_2) + fee(tx_3) = (8 + 57) * TESTS_DEFAULT_FEE = 65 * TESTS_DEFAULT_FEE + fee(tx_4) + fee(tx_5) + fee(tx_6) = (15 + 29 + 22) * TESTS_DEFAULT_FEE = 66 * TESTS_DEFAULT_FEE + 66 > 65. */ + + if (m_hardforks.is_hardfork_active_for_height(ZANO_HARDFORK_04_ZARCANUM, get_block_height(blk_2))) + { + // Case of an alt block on the height 12 with greater total fee than total fee of blk_2 - the top of the main chain. + argument_alt = argument_assert{this, blk_2a, {(15 + 29 + 22) * TESTS_DEFAULT_FEE}, argument_alt}; + // Make sure a reward for blk_2a is equals to COIN. + assert_reward(argument_alt); + // Make sure the balance equals to PREMINE_AMOUNT + 12 * COIN - 99 * TESTS_DEFAULT_FEE. + assert_balance(argument_alt); + } + + else + { + // Make sure a reward for blk_2 is equals to COIN. + assert_reward(argument); + // Make sure the balance equals to PREMINE_AMOUNT + 12 * COIN. + assert_balance(argument); + } + + return true; +} + +bool block_reward_in_alt_chain_basic::assert_balance(currency::core& core, size_t event_index, const std::vector& events) const +{ + argument_assert argument{}; + + { + const auto serialized_argument{boost::get(events.at(event_index)).callback_params}; + + CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(argument, serialized_argument), true); + } + + CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().get_top_block_height(), argument.m_height); + CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().get_top_block_id(), argument.blk_id); + + const auto wallet{init_playtime_test_wallet(events, core, m_accounts.front())}; + + CHECK_AND_ASSERT(wallet, false); + wallet->refresh(); + CHECK_AND_ASSERT_EQ(wallet->balance(), argument.m_balance); + + return true; +} + +bool block_reward_in_alt_chain_basic::assert_reward(currency::core& core, size_t event_index, const std::vector& events) const +{ + argument_assert argument{}; + + { + const auto serialized_argument{boost::get(events.at(event_index)).callback_params}; + + CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(argument, serialized_argument), true); + } + + { + auto blk_id{argument.blk_id}; + + for (const auto expected_reward : argument.m_rewards) + { + uint64_t reward{}; + block blk{}; + + CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().get_block_reward_by_hash(blk_id, reward), true); + CHECK_AND_ASSERT_EQ(reward, expected_reward); + CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().get_block_by_hash(blk_id, blk), true); + blk_id = blk.prev_id; + } + } + + return true; +} diff --git a/tests/core_tests/block_validation.h b/tests/core_tests/block_validation.h index 7c56f206..2075c76d 100644 --- a/tests/core_tests/block_validation.h +++ b/tests/core_tests/block_validation.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2023 Zano Project +// Copyright (c) 2014-2025 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 @@ -6,6 +6,7 @@ #pragma once #include "chaingen.h" +#include "wallet_tests_basic.h" template class gen_block_verification_base : public test_chain_unit_enchanced @@ -197,3 +198,25 @@ struct block_with_correct_prev_id_on_wrong_height : public gen_block_verificatio private: mutable currency::block m_blk_2{}; }; + +struct block_reward_in_main_chain_basic : wallet_test +{ + block_reward_in_main_chain_basic(); + bool generate(std::vector& events) const; + +private: + bool assert_balance(currency::core& core, size_t event_index, const std::vector& events) const; + bool assert_reward(currency::core& core, size_t event_index, const std::vector& events) const; + struct argument_assert; +}; + +struct block_reward_in_alt_chain_basic : wallet_test +{ + block_reward_in_alt_chain_basic(); + bool generate(std::vector& events) const; + +private: + bool assert_balance(currency::core& core, size_t event_index, const std::vector& events) const; + bool assert_reward(currency::core& core, size_t event_index, const std::vector& events) const; + struct argument_assert; +}; diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index 8c4fef66..022cb5a8 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -1179,6 +1179,8 @@ int main(int argc, char* argv[]) GENERATE_AND_PLAY_HF(gen_block_height_is_low, "0,3"); GENERATE_AND_PLAY_HF(gen_block_height_is_high, "0,3"); GENERATE_AND_PLAY_HF(block_with_correct_prev_id_on_wrong_height, "3-*"); + GENERATE_AND_PLAY_HF(block_reward_in_main_chain_basic, "3-*"); + GENERATE_AND_PLAY_HF(block_reward_in_alt_chain_basic, "3-*"); GENERATE_AND_PLAY_HF(gen_block_miner_tx_has_2_tx_gen_in, "0,3"); GENERATE_AND_PLAY_HF(gen_block_miner_tx_has_2_in, "0,3"); GENERATE_AND_PLAY_HF(gen_block_miner_tx_with_txin_to_key, "0,3"); From ddd91d8fecd0e09f3f9c08ed366909b965aa6b77 Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 21 Jan 2025 01:22:28 +0100 Subject: [PATCH 44/82] minor warning fix --- tests/unit_tests/multiassets_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit_tests/multiassets_test.cpp b/tests/unit_tests/multiassets_test.cpp index ad637b01..533d8826 100644 --- a/tests/unit_tests/multiassets_test.cpp +++ b/tests/unit_tests/multiassets_test.cpp @@ -245,7 +245,7 @@ static std::optional deserialize(serialization_metho return {}; } -static std::string get_string_presentation(const std::string& data) +[[maybe_unused]] static std::string get_string_presentation(const std::string& data) { std::string presentation{}; From 35f79d3780e976028fd51236c836d882e5c05c7f Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 21 Jan 2025 02:22:13 +0100 Subject: [PATCH 45/82] zanod, simplewallet now return exit code 0 when '--version' or '--help' are given --- src/daemon/daemon.cpp | 16 ++++++++++++++-- src/simplewallet/simplewallet.cpp | 14 +++++++++++--- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index f5f768fc..604c0bbe 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -126,7 +126,6 @@ int main(int argc, char* argv[]) log_space::get_set_log_detalisation_level(true, LOG_LEVEL_0); log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL); log_space::log_singletone::enable_channels("core,currency_protocol,tx_pool,wallet", false); - LOG_PRINT_L0("Starting..."); tools::signal_handler::install_fatal([](int sig_number, void* address) { LOG_ERROR("\n\nFATAL ERROR\nsig: " << sig_number << ", address: " << address); @@ -184,6 +183,7 @@ int main(int argc, char* argv[]) desc_options.add(desc_cmd_only).add(desc_cmd_sett); po::variables_map vm; + bool exit_requested = false; bool r = command_line::handle_error_helper(desc_options, [&]() { po::store(po::parse_command_line(argc, argv, desc_options), vm); @@ -192,7 +192,14 @@ int main(int argc, char* argv[]) { std::cout << CURRENCY_NAME << " v" << PROJECT_VERSION_LONG << ENDL << ENDL; std::cout << desc_options << std::endl; - return false; + exit_requested = true; + return true; + } + else if (command_line::get_arg(vm, command_line::arg_version)) + { + std::cout << CURRENCY_NAME << " v" << PROJECT_VERSION_LONG << ENDL << ENDL; + exit_requested = true; + return true; } std::string data_dir = command_line::get_arg(vm, command_line::arg_data_dir); @@ -214,9 +221,13 @@ int main(int argc, char* argv[]) return true; }); + if (!r) return EXIT_FAILURE; + if (exit_requested) + return EXIT_SUCCESS; + //set up logging options std::string log_dir; std::string log_file_name = log_space::log_singletone::get_default_log_file(); @@ -238,6 +249,7 @@ int main(int argc, char* argv[]) return EXIT_SUCCESS; } + LOG_PRINT_L0("Starting..."); // stratum server is enabled if any of its options present bool stratum_enabled = currency::stratum_server::should_start(vm); diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 9a5d07e2..44d8df3e 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -3227,20 +3227,23 @@ int main(int argc, char* argv[]) po::options_description desc_all; desc_all.add(desc_general).add(desc_params); po::variables_map vm; + bool exit_requested = false; bool r = command_line::handle_error_helper(desc_all, [&]() { po::store(command_line::parse_command_line(argc, argv, desc_general, true), vm); if (command_line::get_arg(vm, command_line::arg_help)) { - success_msg_writer() << "Usage: simplewallet [--wallet-file=|--generate-new-wallet=] [--daemon-address=:] []"; + success_msg_writer() << "Usage: simplewallet [--wallet-file=|--generate-new[-auditable]-wallet=] [--daemon-address=:] []"; success_msg_writer() << desc_all << '\n' << sw->get_commands_str(); - return false; + exit_requested = true; + return true; } else if (command_line::get_arg(vm, command_line::arg_version)) { success_msg_writer() << CURRENCY_NAME << " wallet v" << PROJECT_VERSION_LONG; - return false; + exit_requested = true; + return true; } auto parser = po::command_line_parser(argc, argv).options(desc_params).positional(positional_options); @@ -3248,8 +3251,13 @@ int main(int argc, char* argv[]) po::notify(vm); return true; }); + if (!r) return EXIT_FAILURE; + + if (exit_requested) + return EXIT_SUCCESS; + //set up logging options log_space::get_set_log_detalisation_level(true, LOG_LEVEL_0); From 075ee3119bedee7a872a8f87e8498f7ed8e3e77d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=D1=91pa=20Dolgorukov?= <63650851+stepan-dolgorukov@users.noreply.github.com> Date: Tue, 21 Jan 2025 07:33:11 +0500 Subject: [PATCH 46/82] coretests: Update "asset_operation_in_consolidated_tx" test (#501) * coretests: Implement "asset_operation_in_consolidated_tx" test * Define "construct_tx" overload with a generation context argument * Update the test "asset_operation_in_consolidated_tx" --------- Co-authored-by: crypto.sowle --- tests/core_tests/multiassets_test.cpp | 101 +++++++++++++++----------- tests/core_tests/multiassets_test.h | 8 +- 2 files changed, 60 insertions(+), 49 deletions(-) diff --git a/tests/core_tests/multiassets_test.cpp b/tests/core_tests/multiassets_test.cpp index c7b13844..b5f4c053 100644 --- a/tests/core_tests/multiassets_test.cpp +++ b/tests/core_tests/multiassets_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2024 Zano Project +// Copyright (c) 2014-2025 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. @@ -1270,18 +1270,6 @@ bool asset_operation_and_hardfork_checks::c2( asset_operation_in_consolidated_tx::asset_operation_in_consolidated_tx() { - m_adb_alice_currency.version = ASSET_DESCRIPTOR_BASE_HF4_VER; - m_adb_alice_currency.total_max_supply = 1'000'000'000'000'000'000; - m_adb_alice_currency.current_supply = 1'000'000'000'000'000'000; - m_adb_alice_currency.ticker = "ALC"; - m_adb_alice_currency.full_name = "ALICE"; - m_adb_alice_currency.meta_info = "Currency created by Alice"; - m_adb_alice_currency.hidden_supply = false; - - m_ado_alice_currency.operation_type = ASSET_DESCRIPTOR_OPERATION_REGISTER; - m_ado_alice_currency.opt_asset_id = currency::null_pkey; - m_ado_alice_currency.version = ASSET_DESCRIPTOR_OPERATION_HF4_VER; - REGISTER_CALLBACK_METHOD(asset_operation_in_consolidated_tx, assert_balances); REGISTER_CALLBACK_METHOD(asset_operation_in_consolidated_tx, assert_alice_currency_not_registered); } @@ -1289,11 +1277,13 @@ asset_operation_in_consolidated_tx::asset_operation_in_consolidated_tx() bool asset_operation_in_consolidated_tx::generate(std::vector& events) const { // Test idea: make sure that the core rule prohibiting operations with assets in TX_FLAG_SIGNATURE_MODE_SEPARATE transactions works. - bool success {}; - transaction tx_2 {}; - uint64_t tx_version {}; - crypto::secret_key one_time {}; - tx_generation_context context_tx_2 {}; + bool success{}; + transaction tx_2{}; + uint64_t tx_version{}; + crypto::secret_key one_time{}; + tx_generation_context context_tx_2{}; + asset_descriptor_base adb_alice_currency{}; + asset_descriptor_operation ado_alice_currency{}; GENERATE_ACCOUNT(miner); GENERATE_ACCOUNT(alice); GENERATE_ACCOUNT(bob); @@ -1301,8 +1291,19 @@ bool asset_operation_in_consolidated_tx::generate(std::vector& m_accounts.push_back(miner); m_accounts.push_back(alice); m_accounts.push_back(bob); - m_adb_alice_currency.owner = m_accounts.at(ALICE_ACC_IDX).get_public_address().spend_public_key; - m_ado_alice_currency.opt_descriptor = m_adb_alice_currency; + + adb_alice_currency.version = ASSET_DESCRIPTOR_BASE_HF4_VER; + adb_alice_currency.total_max_supply = 1'000'000'000'000'000'000; + adb_alice_currency.current_supply = 1'000'000'000'000'000'000; + adb_alice_currency.ticker = "ALC"; + adb_alice_currency.full_name = "ALICE"; + adb_alice_currency.meta_info = "Currency created by Alice"; + adb_alice_currency.hidden_supply = false; + adb_alice_currency.owner = m_accounts.at(ALICE_ACC_IDX).get_public_address().spend_public_key; + ado_alice_currency.opt_descriptor = adb_alice_currency; + ado_alice_currency.operation_type = ASSET_DESCRIPTOR_OPERATION_REGISTER; + ado_alice_currency.opt_asset_id = currency::null_pkey; + ado_alice_currency.version = ASSET_DESCRIPTOR_OPERATION_HF4_VER; MAKE_GENESIS_BLOCK(events, blk_0, miner, test_core_time::get_time()); DO_CALLBACK(events, "configure_core"); @@ -1317,16 +1318,16 @@ bool asset_operation_in_consolidated_tx::generate(std::vector& DO_CALLBACK(events, "assert_balances"); { - std::vector sources {}; - std::vector destinations {}; + std::vector sources{}; + std::vector destinations{}; success = fill_tx_sources(sources, events, blk_2r, alice.get_keys(), MK_TEST_COINS(5), 1); CHECK_AND_ASSERT_MES(success, false, "failed to fill transaction sources on step 1"); destinations.emplace_back(MK_TEST_COINS(5), bob.get_public_address()); destinations.emplace_back(MK_TEST_COINS(/* 10 - 5 - 1 = */ 4), alice.get_public_address()); tx_version = get_tx_version(get_block_height(blk_2r), m_hardforks); - success = construct_tx(alice.get_keys(), sources, destinations, empty_extra, empty_attachment, tx_2, tx_version, one_time, 0, 0, 0, true, TX_FLAG_SIGNATURE_MODE_SEPARATE, TESTS_DEFAULT_FEE, - context_tx_2); + success = construct_tx(alice.get_keys(), sources, destinations, empty_extra, empty_attachment, tx_2, tx_version, one_time, 0, 0, 0, true, TX_FLAG_SIGNATURE_MODE_SEPARATE, TESTS_DEFAULT_FEE, + context_tx_2); CHECK_AND_ASSERT_MES(success, false, "failed to construct transaction tx_2 on step 1"); } @@ -1335,26 +1336,26 @@ bool asset_operation_in_consolidated_tx::generate(std::vector& ADD_CUSTOM_EVENT(events, tx_2); { - std::vector sources {}; - std::vector destinations {}; + std::vector sources{}; + std::vector destinations{}; success = fill_tx_sources(sources, events, blk_2r, bob.get_keys(), MK_TEST_COINS(5), 0); CHECK_AND_ASSERT_MES(success, false, "failed to fill transaction sources on step 2"); - for(tx_source_entry& source : sources) + + for (tx_source_entry& source : sources) { source.separately_signed_tx_complete = true; } + destinations.emplace_back(MK_TEST_COINS(5), alice.get_public_address()); destinations.emplace_back(MK_TEST_COINS(/* 10 - 5 - 0 = */ 5), bob.get_public_address()); - destinations.emplace_back(m_adb_alice_currency.current_supply, alice.get_public_address(), null_pkey); + destinations.emplace_back(adb_alice_currency.current_supply, alice.get_public_address(), null_pkey); tx_version = get_tx_version(get_block_height(blk_2r), m_hardforks); size_t hf_n = m_hardforks.get_the_most_recent_hardfork_id_for_height(get_block_height(blk_2r)); - fill_ado_version_based_onhardfork(m_ado_alice_currency, hf_n); - fill_adb_version_based_onhardfork(*m_ado_alice_currency.opt_descriptor, hf_n); - - - success = construct_tx(bob.get_keys(), sources, destinations, { m_ado_alice_currency }, empty_attachment, tx_2, tx_version, one_time, 0, 0, 0, true, TX_FLAG_SIGNATURE_MODE_SEPARATE, - /* fee = */ 0, context_tx_2); + fill_ado_version_based_onhardfork(ado_alice_currency, hf_n); + fill_adb_version_based_onhardfork(*ado_alice_currency.opt_descriptor, hf_n); + success = construct_tx(bob.get_keys(), sources, destinations, {ado_alice_currency}, empty_attachment, tx_2, tx_version, one_time, 0, 0, 0, true, TX_FLAG_SIGNATURE_MODE_SEPARATE, + /* fee = */ 0, context_tx_2); CHECK_AND_ASSERT_MES(success, false, "failed to construct transaction tx_2 on step 2"); } @@ -1363,15 +1364,15 @@ bool asset_operation_in_consolidated_tx::generate(std::vector& // Core rejects transaction tx_2. The balances of Alice, Bob haven't changed: Alice has 10 coins, Bob has 10 coins. DO_CALLBACK(events, "assert_balances"); // Alice's asset hasn't registered, because transaction tx_2 was rejected. - DO_CALLBACK(events, "assert_alice_currency_not_registered"); + DO_CALLBACK_PARAMS_STR(events, "assert_alice_currency_not_registered", t_serializable_object_to_blob(ado_alice_currency)); return true; } -bool asset_operation_in_consolidated_tx::assert_balances(currency::core& c, size_t ev_index, const std::vector& events) +bool asset_operation_in_consolidated_tx::assert_balances(currency::core& c, size_t ev_index, const std::vector& events) const { - std::shared_ptr alice_wallet{init_playtime_test_wallet(events, c, ALICE_ACC_IDX)}; - std::shared_ptr bob_wallet{init_playtime_test_wallet(events, c, BOB_ACC_IDX)}; + const auto alice_wallet{init_playtime_test_wallet_t(events, c, ALICE_ACC_IDX)}; + const auto bob_wallet{init_playtime_test_wallet_t(events, c, BOB_ACC_IDX)}; alice_wallet->refresh(); bob_wallet->refresh(); @@ -1382,14 +1383,28 @@ bool asset_operation_in_consolidated_tx::assert_balances(currency::core& c, size return true; } -bool asset_operation_in_consolidated_tx::assert_alice_currency_not_registered(currency::core& c, size_t ev_index, const std::vector& events) +bool asset_operation_in_consolidated_tx::assert_alice_currency_not_registered(const currency::core& c, size_t ev_index, const std::vector& events) const { - crypto::point_t asset_id_point{}; crypto::public_key asset_id{}; - currency::asset_descriptor_base stub{}; + asset_descriptor_operation ado{}; - CHECK_AND_ASSERT_MES(get_or_calculate_asset_id(m_ado_alice_currency, &asset_id_point, &asset_id), false, "fail to calculate asset id"); - CHECK_AND_ASSERT_MES(!c.get_blockchain_storage().get_asset_info(asset_id, stub), false, "unregistered asset has info"); + { + const auto serialized_ado{boost::get(events.at(ev_index)).callback_params}; + + CHECK_AND_ASSERT_MES(t_unserializable_object_from_blob(ado, serialized_ado), false, "ADO deserialization failed"); + } + + { + crypto::point_t point_asset_id{}; + + CHECK_AND_ASSERT_MES(get_or_calculate_asset_id(ado, &point_asset_id, &asset_id), false, "fail to calculate asset id"); + } + + { + currency::asset_descriptor_base adb_stub{}; + + CHECK_AND_ASSERT_MES(!c.get_blockchain_storage().get_asset_info(asset_id, adb_stub), false, "unregistered asset has info"); + } return true; } diff --git a/tests/core_tests/multiassets_test.h b/tests/core_tests/multiassets_test.h index d306a0f4..5b367533 100644 --- a/tests/core_tests/multiassets_test.h +++ b/tests/core_tests/multiassets_test.h @@ -74,12 +74,8 @@ struct asset_operation_in_consolidated_tx : public wallet_test public: asset_operation_in_consolidated_tx(); bool generate(std::vector& events) const; - bool assert_balances(currency::core& c, size_t ev_index, const std::vector& events); - bool assert_alice_currency_not_registered(currency::core& c, size_t ev_index, const std::vector& events); - -private: - mutable currency::asset_descriptor_base m_adb_alice_currency{}; - mutable currency::asset_descriptor_operation m_ado_alice_currency{}; + bool assert_balances(currency::core& c, size_t ev_index, const std::vector& events) const; + bool assert_alice_currency_not_registered(const currency::core& c, size_t ev_index, const std::vector& events) const; }; struct eth_signed_asset_basics : public wallet_test From aab20167fbcd55989ddc3f6d76420cf968b210e4 Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 21 Jan 2025 18:30:30 +0100 Subject: [PATCH 47/82] ui update (PR 137) --- 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 8304b635..8b8f8950 160000 --- a/src/gui/qt-daemon/layout +++ b/src/gui/qt-daemon/layout @@ -1 +1 @@ -Subproject commit 8304b635c45b19a55ab6bfc90b7181ba49e295ad +Subproject commit 8b8f8950d9350543913c38b7bec8581cafea6211 From f6d363d313234cbd50e7c3b1b7eff7dcdf1875d7 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Tue, 21 Jan 2025 20:35:34 +0300 Subject: [PATCH 48/82] === build number: 373 -> 374 === --- 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 ea6efb85..80c1cd48 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "1" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 373 +#define PROJECT_VERSION_BUILD_NO 374 #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 38e6556a49b622cfe9778f9f022f59692313e028 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 24 Jan 2025 04:41:55 +0100 Subject: [PATCH 49/82] 2nd iteration on diminishing CPU mining presence in mainnet builds --- src/currency_core/currency_core.cpp | 26 ++++++++-- src/currency_core/currency_core.h | 8 ++- src/currency_core/miner.cpp | 7 +-- src/currency_core/miner.h | 51 ++++++++++--------- src/daemon/daemon.cpp | 2 + src/wallet/wallets_manager.cpp | 2 + tests/core_tests/alias_tests.cpp | 6 +-- tests/core_tests/chaingen.cpp | 4 +- tests/core_tests/chaingen_helpers.h | 4 +- tests/core_tests/emission_test.cpp | 2 +- tests/core_tests/hard_fork_1.cpp | 2 +- .../core_concurrency_test.cpp | 2 +- 12 files changed, 73 insertions(+), 43 deletions(-) diff --git a/src/currency_core/currency_core.cpp b/src/currency_core/currency_core.cpp index 8d29c38d..37e67e93 100644 --- a/src/currency_core/currency_core.cpp +++ b/src/currency_core/currency_core.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2018 Zano Project +// Copyright (c) 2014-2025 Zano Project // Copyright (c) 2014-2018 The Louisdor Project // Copyright (c) 2012-2013 The Cryptonote developers // Copyright (c) 2012-2013 The Boolberry developers @@ -34,8 +34,10 @@ namespace currency core::core(i_currency_protocol* pprotocol) : m_mempool(m_blockchain_storage, pprotocol) , m_blockchain_storage(m_mempool) +#ifdef CPU_MINING_ENABLED , m_miner(this, m_blockchain_storage) - , m_miner_address(boost::value_initialized()) +#endif + //, m_miner_address(boost::value_initialized()) , m_starter_message_showed(false) , m_critical_error_handler(nullptr) , m_stop_after_height(0) @@ -165,8 +167,10 @@ namespace currency m_mempool.remove_incompatible_txs(); +#ifdef CPU_MINING_ENABLED r = m_miner.init(vm); CHECK_AND_ASSERT_MES(r, false, "Failed to initialize miner"); +#endif //check if tx_pool module synchronized with blockchaine storage // if (m_blockchain_storage.get_top_block_id() != m_mempool.get_last_core_hash()) @@ -193,8 +197,10 @@ namespace currency { //m_mempool.set_last_core_hash(m_blockchain_storage.get_top_block_id()); +#ifdef CPU_MINING_ENABLED m_miner.stop(); m_miner.deinit(); +#endif m_mempool.deinit(); m_blockchain_storage.deinit(); return true; @@ -274,7 +280,9 @@ namespace currency //----------------------------------------------------------------------------------------------- bool core::get_stat_info(const core_stat_info::params& pr, core_stat_info& st_inf) { +#ifdef CPU_MINING_ENABLED st_inf.mining_speed = m_miner.get_speed(); +#endif st_inf.alternative_blocks = m_blockchain_storage.get_alternative_blocks_count(); st_inf.blockchain_height = m_blockchain_storage.get_current_blockchain_size(); st_inf.tx_pool_size = m_mempool.get_transactions_count(); @@ -405,12 +413,16 @@ namespace currency //----------------------------------------------------------------------------------------------- void core::pause_mine() { +#ifdef CPU_MINING_ENABLED m_miner.pause(); +#endif } //----------------------------------------------------------------------------------------------- void core::resume_mine() { +#ifdef CPU_MINING_ENABLED m_miner.resume(); +#endif } //----------------------------------------------------------------------------------------------- bool core::handle_block_found(const block& b, block_verification_context* p_verification_result, bool need_update_miner_block_template) @@ -422,10 +434,10 @@ namespace currency if (!p_verification_result) p_verification_result = &bvc; - m_miner.pause(); + pause_mine(); misc_utils::auto_scope_leave_caller scope_exit_handler = misc_utils::create_scope_leave_handler([this]() { - m_miner.resume(); + resume_mine(); }); TIME_MEASURE_START_MS(time_add_new_block_ms); @@ -520,7 +532,9 @@ namespace currency //----------------------------------------------------------------------------------------------- void core::on_synchronized() { +#ifdef CPU_MINING_ENABLED m_miner.on_synchronized(); +#endif } bool core::get_backward_blocks_sizes(uint64_t from_height, std::vector& sizes, size_t count) { @@ -685,7 +699,9 @@ namespace currency bool core::update_miner_block_template() { notify_blockchain_update_listeners(); +#ifdef CPU_MINING_ENABLED m_miner.on_block_chain_update(); +#endif return true; } //----------------------------------------------------------------------------------------------- @@ -708,7 +724,9 @@ namespace currency m_prune_alt_blocks_interval.do_call([this](){return m_blockchain_storage.prune_aged_alt_blocks();}); m_check_free_space_interval.do_call([this](){ check_free_space(); return true; }); +#ifdef CPU_MINING_ENABLED m_miner.on_idle(); +#endif m_mempool.on_idle(); return true; } diff --git a/src/currency_core/currency_core.h b/src/currency_core/currency_core.h index 32f62b0d..a7df6051 100644 --- a/src/currency_core/currency_core.h +++ b/src/currency_core/currency_core.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2018 Zano Project +// Copyright (c) 2014-2025 Zano Project // Copyright (c) 2014-2018 The Louisdor Project // Copyright (c) 2012-2013 The Cryptonote developers // Copyright (c) 2012-2013 The Boolberry developers @@ -57,7 +57,9 @@ namespace currency virtual bool get_block_template(const create_block_template_params& params, create_block_template_response& resp); bool get_block_template(block& b, const account_public_address& adr, const account_public_address& stakeholder_address, wide_difficulty_type& diffic, uint64_t& height, const blobdata& ex_nonce, bool pos = false, const pos_entry& pe = pos_entry()); +#ifdef CPU_MINING_ENABLED miner& get_miner(){ return m_miner; } +#endif static void init_options(boost::program_options::options_description& desc); bool init(const boost::program_options::variables_map& vm); bool set_genesis_block(const block& b); @@ -141,8 +143,10 @@ namespace currency i_currency_protocol* m_pprotocol; i_critical_error_handler* m_critical_error_handler; epee::critical_section m_incoming_tx_lock; +#ifdef CPU_MINING_ENABLED miner m_miner; - account_public_address m_miner_address; +#endif + //account_public_address m_miner_address; std::string m_config_folder; uint64_t m_stop_after_height; currency_protocol_stub m_protocol_stub; diff --git a/src/currency_core/miner.cpp b/src/currency_core/miner.cpp index c0cbd789..dc37f3f6 100644 --- a/src/currency_core/miner.cpp +++ b/src/currency_core/miner.cpp @@ -36,17 +36,18 @@ namespace currency // CPU mining disabled // currency::miner stub implementation + /* miner::miner(i_miner_handler* phandler, blockchain_storage& bc) {} miner::~miner() {} bool miner::init(const boost::program_options::variables_map& vm) { - return false; + return true; } bool miner::deinit() { - return false; + return true; } void miner::init_options(boost::program_options::options_description& desc) {} @@ -84,7 +85,7 @@ namespace currency } // end of currency::miner stub implementation - + */ #else diff --git a/src/currency_core/miner.h b/src/currency_core/miner.h index 6b3886d1..674bb4d2 100644 --- a/src/currency_core/miner.h +++ b/src/currency_core/miner.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2018 Zano Project +// Copyright (c) 2014-2025 Zano Project // Copyright (c) 2014-2018 The Louisdor Project // Copyright (c) 2012-2013 The Cryptonote developers // Copyright (c) 2012-2013 The Boolberry developers @@ -11,7 +11,6 @@ #define CPU_MINING_ENABLED // disable CPU mining capabilities in mainnet #endif // #ifndef TESTNET - #include #include #include @@ -35,6 +34,29 @@ namespace currency ~i_miner_handler(){}; }; + inline + static bool find_nonce_for_given_block(block& bl, const wide_difficulty_type& diffic, uint64_t height) + { + bl.nonce = 0; + blobdata bd = get_block_hashing_blob(bl); + crypto::hash bd_hash = crypto::cn_fast_hash(bd.data(), bd.size()); + //uint64_t& nonce_ref = access_nonce_in_block_blob(bd); + //nonce_ref = 0; + + for(; bl.nonce != std::numeric_limits::max(); bl.nonce++) + { + crypto::hash h = get_block_longhash(height, bd_hash, bl.nonce); + if(check_hash(h, diffic)) + { + LOG_PRINT_L1("Found nonce for block: " << get_block_hash(bl) << "[" << height << "]: PoW:" << h << " (diff:" << diffic << "), ts: " << bl.timestamp); + return true; + } + } + return false; + } + +#ifdef CPU_MINING_ENABLED + /************************************************************************/ /* */ /************************************************************************/ @@ -59,27 +81,6 @@ namespace currency void resume(); void do_print_hashrate(bool do_hr); - inline - static bool find_nonce_for_given_block(block& bl, const wide_difficulty_type& diffic, uint64_t height) - { - bl.nonce = 0; - blobdata bd = get_block_hashing_blob(bl); - crypto::hash bd_hash = crypto::cn_fast_hash(bd.data(), bd.size()); - //uint64_t& nonce_ref = access_nonce_in_block_blob(bd); - //nonce_ref = 0; - - for(; bl.nonce != std::numeric_limits::max(); bl.nonce++) - { - crypto::hash h = get_block_longhash(height, bd_hash, bl.nonce); - if(check_hash(h, diffic)) - { - LOG_PRINT_L1("Found nonce for block: " << get_block_hash(bl) << "[" << height << "]: PoW:" << h << " (diff:" << diffic << "), ts: " << bl.timestamp); - return true; - } - } - return false; - } - private: bool set_block_template(const block& bl, const wide_difficulty_type& diffic, uint64_t height); bool worker_thread(); @@ -127,5 +128,7 @@ namespace currency bool m_do_mining; }; -} +#endif // #ifdef CPU_MINING_ENABLED + +} // namespace currency diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index 604c0bbe..4e5d0de0 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -174,7 +174,9 @@ int main(int argc, char* argv[]) currency::core_rpc_server::init_options(desc_cmd_sett); typedef nodetool::node_server > p2psrv_t; p2psrv_t::init_options(desc_cmd_sett); +#ifdef CPU_MINING_ENABLED currency::miner::init_options(desc_cmd_sett); +#endif bc_services::bc_offers_service::init_options(desc_cmd_sett); currency::stratum_server::init_options(desc_cmd_sett); tools::db::db_backend_selector::init_options(desc_cmd_sett); diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index b51f929f..caa6c9ef 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -201,7 +201,9 @@ bool wallets_manager::init_command_line(int argc, char* argv[], std::string& fai currency::core::init_options(desc_cmd_sett); currency::core_rpc_server::init_options(desc_cmd_sett); nodetool::node_server >::init_options(desc_cmd_sett); +#ifdef CPU_MINING_ENABLED currency::miner::init_options(desc_cmd_sett); +#endif bc_services::bc_offers_service::init_options(desc_cmd_sett); tools::db::db_backend_selector::init_options(desc_cmd_sett); #endif diff --git a/tests/core_tests/alias_tests.cpp b/tests/core_tests/alias_tests.cpp index b8a1e4fd..704702cc 100644 --- a/tests/core_tests/alias_tests.cpp +++ b/tests/core_tests/alias_tests.cpp @@ -381,7 +381,7 @@ bool gen_alias_tests::check_too_many_aliases_registration(currency::core& c, siz CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == total_alias_to_gen, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count() << ", expected: " << total_alias_to_gen); // complete block template and try to process it - r = miner::find_nonce_for_given_block(b, diff, height); + r = find_nonce_for_given_block(b, diff, height); CHECK_AND_ASSERT_MES(r, false, "find_nonce_for_given_block failed"); currency::block_verification_context bvc = AUTO_VAL_INIT(bvc); @@ -1317,7 +1317,7 @@ bool gen_alias_switch_and_check_block_template::add_block_from_template(currency bool r = c.get_block_template(b, acc.get_public_address(), acc.get_public_address(), diff, height, extra); CHECK_AND_ASSERT_MES(r, false, "get_block_template failed"); - r = miner::find_nonce_for_given_block(b, diff, height); + r = find_nonce_for_given_block(b, diff, height); CHECK_AND_ASSERT_MES(r, false, "find_nonce_for_given_block failed"); currency::block_verification_context bvc = AUTO_VAL_INIT(bvc); @@ -1439,7 +1439,7 @@ bool gen_alias_too_many_regs_in_block_template::add_block_from_template(currency bool r = c.get_block_template(b, acc.get_public_address(), acc.get_public_address(), diff, height, extra); CHECK_AND_ASSERT_MES(r, false, "get_block_template failed"); - r = miner::find_nonce_for_given_block(b, diff, height); + r = find_nonce_for_given_block(b, diff, height); CHECK_AND_ASSERT_MES(r, false, "find_nonce_for_given_block failed"); currency::block_verification_context bvc = AUTO_VAL_INIT(bvc); diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index 2679dd39..cfcd8376 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -836,7 +836,7 @@ bool test_generator::find_nounce(currency::block& blk, std::vector& event void fill_nonce(currency::block& blk, const wide_difficulty_type& diffic, uint64_t height) { blk.nonce = 0; - while (!miner::find_nonce_for_given_block(blk, diffic, height)) + while (!find_nonce_for_given_block(blk, diffic, height)) blk.timestamp++; }*/ diff --git a/tests/core_tests/chaingen_helpers.h b/tests/core_tests/chaingen_helpers.h index 703aec6f..f4033fae 100644 --- a/tests/core_tests/chaingen_helpers.h +++ b/tests/core_tests/chaingen_helpers.h @@ -33,7 +33,7 @@ inline bool mine_next_pow_block_in_playtime(const currency::account_public_addre test_core_time::adjust(b.timestamp); modify_block_cb(b); - r = currency::miner::find_nonce_for_given_block(b, cbtr.diffic, cbtr.height); + r = currency::find_nonce_for_given_block(b, cbtr.diffic, cbtr.height); CHECK_AND_ASSERT_MES(r, false, "find_nonce_for_given_block failed"); currency::block_verification_context bvc{}; @@ -119,7 +119,7 @@ inline bool mine_next_pow_block_in_playtime_with_given_txs(const currency::accou height = cbtr.height; } - r = currency::miner::find_nonce_for_given_block(b, cbtr.diffic, cbtr.height); + r = currency::find_nonce_for_given_block(b, cbtr.diffic, cbtr.height); CHECK_AND_ASSERT_MES(r, false, "find_nonce_for_given_block failed"); currency::block_verification_context bvc{}; diff --git a/tests/core_tests/emission_test.cpp b/tests/core_tests/emission_test.cpp index 035726ca..7bd66823 100644 --- a/tests/core_tests/emission_test.cpp +++ b/tests/core_tests/emission_test.cpp @@ -69,7 +69,7 @@ bool emission_test::c1(currency::core& c, size_t ev_index, const std::vector Date: Fri, 24 Jan 2025 07:27:36 +0300 Subject: [PATCH 50/82] === build number: 374 -> 375 === --- 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 80c1cd48..fe359bc5 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "1" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 374 +#define PROJECT_VERSION_BUILD_NO 375 #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 072d53de9b6c8ffba018ec852ee900a632663b60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=D1=91pa=20Dolgorukov?= <63650851+stepan-dolgorukov@users.noreply.github.com> Date: Tue, 28 Jan 2025 14:28:14 +0500 Subject: [PATCH 51/82] coretests: Fix MSVC C4146 warning in the test "get_xtype_from_string" (#503) * Change macros for creating test names * Add test for values of types int{16,32,64}_t * Fix MSVC C4146 warning --------- Co-authored-by: sowle --- tests/unit_tests/get_xtype_from_string.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/unit_tests/get_xtype_from_string.cpp b/tests/unit_tests/get_xtype_from_string.cpp index 5bcb74df..0a520c16 100644 --- a/tests/unit_tests/get_xtype_from_string.cpp +++ b/tests/unit_tests/get_xtype_from_string.cpp @@ -151,10 +151,10 @@ TEST_neg(int16_t, "+32768"); // 2^15 TEST_neg(int16_t, "-32769"); // -2^15 - 1 TEST_neg(int16_t, ""); -TEST_pos(int32_t, 2'147'483'647, "2147483647"); // 2^31 - 1 -TEST_pos(int32_t, -2'147'483'648, "-2147483648"); // -2^31 -TEST_pos(int32_t, 0, "-0"); -TEST_pos(int32_t, 0, "+0"); +TEST_pos(int32_t, 2'147'483'647, "2147483647"); // 2^31 - 1 +TEST_pos(int32_t, -2'147'483'647 - 1, "-2147483648"); // -2^31 +TEST_pos(int32_t, 0, "-0"); +TEST_pos(int32_t, 0, "+0"); TEST_neg(int32_t, "-2147483649"); TEST_neg(int32_t, "2147483648"); From dd64c805d7f4537b26aa841ea50f063e65c3e14d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=D1=91pa=20Dolgorukov?= <63650851+stepan-dolgorukov@users.noreply.github.com> Date: Wed, 29 Jan 2025 15:24:18 +0500 Subject: [PATCH 52/82] coretests: Update "block_with_correct_prev_id_on_wrong_height" test (#499) * Core tests: implement the test "block_with_correct_prev_id_on_wrong_height" * Core tests: update "block_with_correct_prev_id_on_wrong_height" test --- tests/core_tests/block_validation.cpp | 34 +++++++++++++++++++-------- tests/core_tests/block_validation.h | 3 --- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/tests/core_tests/block_validation.cpp b/tests/core_tests/block_validation.cpp index 75c453e2..bb1861bb 100644 --- a/tests/core_tests/block_validation.cpp +++ b/tests/core_tests/block_validation.cpp @@ -696,7 +696,7 @@ bool gen_block_wrong_version_agains_hardfork::generate(std::vector& events) const @@ -707,26 +707,40 @@ bool block_with_correct_prev_id_on_wrong_height::generate(std::vector& events) const { - currency::block_verification_context context_blk_2{}; + block blk_2{}; - CHECK_AND_ASSERT_EQ(boost::get(m_blk_2.miner_tx.vin.front()).height, 10); - CHECK_AND_ASSERT_EQ(c.get_blockchain_storage().add_new_block(m_blk_2, context_blk_2), false); + { + const auto serialized_block{boost::get(events.at(ev_index)).callback_params}; + + CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(blk_2, serialized_block), true); + } + + { + currency::block_verification_context context_blk_2{}; + + CHECK_AND_ASSERT_EQ(boost::get(blk_2.miner_tx.vin.front()).height, 10); + // Make sure, that it's impossible to insert blk_2. + CHECK_AND_ASSERT_EQ(c.get_blockchain_storage().add_new_block(blk_2, context_blk_2), false); + } return true; } diff --git a/tests/core_tests/block_validation.h b/tests/core_tests/block_validation.h index 2075c76d..59e4c149 100644 --- a/tests/core_tests/block_validation.h +++ b/tests/core_tests/block_validation.h @@ -194,9 +194,6 @@ struct block_with_correct_prev_id_on_wrong_height : public gen_block_verificatio block_with_correct_prev_id_on_wrong_height(); bool generate(std::vector& events) const; bool assert_blk_2_has_wrong_height(currency::core& c, size_t ev_index, const std::vector& events) const; - -private: - mutable currency::block m_blk_2{}; }; struct block_reward_in_main_chain_basic : wallet_test From d14ca4f53fc8020d269b2da3781a930092e76c1a Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 29 Jan 2025 21:07:07 +0100 Subject: [PATCH 53/82] ui update PR 138 --- 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 8b8f8950..1a01f6fc 160000 --- a/src/gui/qt-daemon/layout +++ b/src/gui/qt-daemon/layout @@ -1 +1 @@ -Subproject commit 8b8f8950d9350543913c38b7bec8581cafea6211 +Subproject commit 1a01f6fc383d765950972cd4d63cf4179094f21e From 2628656537228ad20584dcd7af6a8eaf005fc077 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Wed, 29 Jan 2025 23:08:01 +0300 Subject: [PATCH 54/82] === build number: 375 -> 376 === --- 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 fe359bc5..a8212258 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "1" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 375 +#define PROJECT_VERSION_BUILD_NO 376 #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 4ad93162e8c82896088d8ffc02fb11f5fc2ffa06 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 30 Jan 2025 14:50:15 +0400 Subject: [PATCH 55/82] https enabled in remote node --- contrib/epee/include/net/http_client.h | 79 +++++++++++++++++++++++++- src/wallet/core_default_rpc_proxy.cpp | 9 +++ src/wallet/core_default_rpc_proxy.h | 2 +- tests/performance_tests/main.cpp | 2 + 4 files changed, 90 insertions(+), 2 deletions(-) diff --git a/contrib/epee/include/net/http_client.h b/contrib/epee/include/net/http_client.h index 9c658e43..fea2f655 100644 --- a/contrib/epee/include/net/http_client.h +++ b/contrib/epee/include/net/http_client.h @@ -200,8 +200,26 @@ namespace epee namespace http { + + + struct i_http_client + { + virtual void set_host_name(const std::string& name) = 0; + virtual boost::asio::ip::tcp::socket& get_socket() = 0; + virtual bool connect(const std::string& host, int port, unsigned int timeout) = 0; + virtual bool set_timeouts(unsigned int connection_timeout, unsigned int recv_timeout) = 0; + virtual bool connect(const std::string& host, std::string port) = 0; + virtual bool connect(const std::string& host, const std::string& port, unsigned int timeout) = 0; + virtual bool disconnect() = 0; + virtual bool is_connected() = 0; + virtual bool invoke_get(const std::string& uri, const std::string& body = std::string(), const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list()) = 0; + virtual bool invoke(const std::string& uri, const std::string& method, const std::string& body, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list()) = 0; + virtual bool invoke_post(const std::string& uri, const std::string& body, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list()) = 0; + }; + template - class http_simple_client_t : public i_target_handler + class http_simple_client_t : public i_target_handler, + public i_http_client { public: @@ -893,6 +911,64 @@ namespace epee typedef http_simple_client_t https_simple_client; + //suitable for both http and https + class http_universal_client: public i_http_client + { + public: + http_universal_client(): m_pclient(new http_simple_client()) + {} + // Forward all calls to m_pclient + void set_host_name(const std::string& name) override + { + m_pclient->set_host_name(name); + } + bool connect(const std::string& host, int port, unsigned int timeout) override + { + return m_pclient->connect(host, port, timeout); + } + boost::asio::ip::tcp::socket& get_socket() override { return m_pclient->get_socket(); } + bool set_timeouts(unsigned int connection_timeout, unsigned int recv_timeout) override { return m_pclient->set_timeouts(connection_timeout, recv_timeout); } + bool connect(const std::string& host, std::string port) override { return m_pclient->connect(host, port); } + bool connect(const std::string& host, const std::string& port, unsigned int timeout) override { return m_pclient->connect(host, port, timeout); } + bool disconnect() override { return m_pclient->disconnect(); } + bool is_connected() override { return m_pclient->is_connected(); } + bool invoke_get(const std::string& uri, const std::string& body = std::string(), const http_response_info** ppresponse_info = nullptr, const fields_list& additional_params = fields_list()) override { return m_pclient->invoke_get(uri, body, ppresponse_info, additional_params); } + bool invoke(const std::string& uri, const std::string& method, const std::string& body, const http_response_info** ppresponse_info = nullptr, const fields_list& additional_params = fields_list()) override { return m_pclient->invoke(uri, method, body, ppresponse_info, additional_params); } + bool invoke_post(const std::string& uri, const std::string& body, const http_response_info** ppresponse_info = nullptr, const fields_list& additional_params = fields_list()) override { return m_pclient->invoke_post(uri, body, ppresponse_info, additional_params); } + + void set_is_ssl(bool is_ssl) + { + if (m_is_ssl != is_ssl) + { + if (is_ssl) + { + m_pclient.reset(new https_simple_client()); + } + else + { + m_pclient.reset(new http_simple_client()); + } + m_is_ssl = is_ssl; + } + } + private: + bool m_is_ssl = false; + std::shared_ptr m_pclient; + }; + + + template + void configure_transport(const std::string schema, transport& tr) + {} + inline void configure_transport(const std::string schema, http_universal_client& tr) + { + if (schema == "https") + tr.set_is_ssl(true); + else + tr.set_is_ssl(false); + } + + /************************************************************************/ /* */ /************************************************************************/ @@ -915,6 +991,7 @@ namespace epee if (!port) port = 80;//default for http + configure_transport(u_c.schema, tr); if (!tr.connect(u_c.host, port, timeout)) { LOG_PRINT_L2("invoke_request: cannot connect to " << u_c.host << ":" << port); diff --git a/src/wallet/core_default_rpc_proxy.cpp b/src/wallet/core_default_rpc_proxy.cpp index 38907e37..5e82efa4 100644 --- a/src/wallet/core_default_rpc_proxy.cpp +++ b/src/wallet/core_default_rpc_proxy.cpp @@ -167,6 +167,15 @@ namespace tools epee::net_utils::parse_url(m_daemon_address, u); if (!u.port) u.port = 8081; + if (u.schema == "https") + { + m_http_client.set_is_ssl(true); + } + else + { + m_http_client.set_is_ssl(false); + } + bool r = m_http_client.connect(u.host, std::to_string(u.port), m_connection_timeout); if (r) { diff --git a/src/wallet/core_default_rpc_proxy.h b/src/wallet/core_default_rpc_proxy.h index 7eb94397..b693fca6 100644 --- a/src/wallet/core_default_rpc_proxy.h +++ b/src/wallet/core_default_rpc_proxy.h @@ -134,7 +134,7 @@ namespace tools } epee::critical_section m_lock; - epee::net_utils::http::http_simple_client m_http_client; + epee::net_utils::http::http_universal_client m_http_client; std::string m_daemon_address; unsigned int m_connection_timeout; diff --git a/tests/performance_tests/main.cpp b/tests/performance_tests/main.cpp index 9b285b68..c03eb834 100644 --- a/tests/performance_tests/main.cpp +++ b/tests/performance_tests/main.cpp @@ -56,6 +56,8 @@ void test_plain_wallet() epee::misc_utils::sleep_no_w(2000); res = plain_wallet::sync_call("reset_connection_url", 0, "195.201.107.230:33336"); + //res = plain_wallet::sync_call("reset_connection_url", 0, "https://node.zano.org:443"); + r = plain_wallet::sync_call("run_wallet", instance_id, ""); while(true) From 1cd3a9562587567e6005a115667e693db963f356 Mon Sep 17 00:00:00 2001 From: sowle Date: Thu, 30 Jan 2025 15:35:53 +0100 Subject: [PATCH 56/82] ui update (PR 139) --- 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 1a01f6fc..dbca6947 160000 --- a/src/gui/qt-daemon/layout +++ b/src/gui/qt-daemon/layout @@ -1 +1 @@ -Subproject commit 1a01f6fc383d765950972cd4d63cf4179094f21e +Subproject commit dbca694737496434ef9c7da765ee6aafd7f90158 From 467fd4b6ba0e102905e9abc5b8bcd63186c66d44 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Thu, 30 Jan 2025 17:40:03 +0300 Subject: [PATCH 57/82] === build number: 376 -> 377 === --- 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 a8212258..abb5b1cc 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "1" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 376 +#define PROJECT_VERSION_BUILD_NO 377 #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 8fc70f4d6d38dd8d2b2b9097c1d996ad37c6edae Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 31 Jan 2025 17:28:28 +0100 Subject: [PATCH 58/82] wallet: fixed a bug when a freshly created wallet's node is in then-become alt-chain (credits to @cryptozoidberg) --- src/wallet/wallet2.cpp | 6 ++++++ src/wallet/wallet_chain_shortener.cpp | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index ac486389..5bcfa40c 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -2116,6 +2116,12 @@ void wallet2::handle_pulled_blocks(size_t& blocks_added, std::atomic& stop } else { + //if first synchronized block in the wallet accidently became orphaned we need to force wallet to resync + if(this->m_minimum_height == height) + { + full_reset_needed = true; + } + //this should happen ONLY after block been matched, if not then is internal error if (full_reset_needed) { diff --git a/src/wallet/wallet_chain_shortener.cpp b/src/wallet/wallet_chain_shortener.cpp index 77c5d82c..39d37c75 100644 --- a/src/wallet/wallet_chain_shortener.cpp +++ b/src/wallet/wallet_chain_shortener.cpp @@ -217,7 +217,7 @@ void wallet_chain_shortener::check_if_block_matched(uint64_t i, const crypto::ha } return; } - if (!m_last_20_blocks.empty() && i > m_last_20_blocks.begin()->first) + if (!m_last_20_blocks.empty() && i >= m_last_20_blocks.begin()->first) { //must be in short sequence (m_last_20_blocks) //self check From 3d1f4a53361f28651adeb90d6d459e1b6fe85789 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 31 Jan 2025 17:30:02 +0100 Subject: [PATCH 59/82] now max_seed_height is always greater then or equal to current node's top block height --- src/currency_core/currency_core.h | 2 +- src/currency_protocol/currency_protocol_handler.inl | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/currency_core/currency_core.h b/src/currency_core/currency_core.h index a7df6051..637103b1 100644 --- a/src/currency_core/currency_core.h +++ b/src/currency_core/currency_core.h @@ -68,7 +68,7 @@ namespace currency uint64_t get_current_tx_version() const; uint64_t get_top_block_height() const; std::string get_config_folder(); - bool get_blockchain_top(uint64_t& heeight, crypto::hash& top_id) const; + bool get_blockchain_top(uint64_t& height, crypto::hash& top_id) const; bool get_blocks(uint64_t start_offset, size_t count, std::list& blocks, std::list& txs); bool get_blocks(uint64_t start_offset, size_t count, std::list& blocks); template diff --git a/src/currency_protocol/currency_protocol_handler.inl b/src/currency_protocol/currency_protocol_handler.inl index b9c7a524..94b77505 100644 --- a/src/currency_protocol/currency_protocol_handler.inl +++ b/src/currency_protocol/currency_protocol_handler.inl @@ -229,7 +229,8 @@ namespace currency template uint64_t t_currency_protocol_handler::get_max_seen_height() { - return m_max_height_seen; + uint64_t max_seen = m_max_height_seen; + return std::max(max_seen, m_core.get_blockchain_storage().get_top_block_height()); } //------------------------------------------------------------------------------------------------------------------------ template From 3cf39eec882b3e5fd7512f693839ca7cb4884822 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Fri, 31 Jan 2025 19:30:36 +0300 Subject: [PATCH 60/82] === build number: 377 -> 378 === --- 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 abb5b1cc..5b55abd7 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "1" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 377 +#define PROJECT_VERSION_BUILD_NO 378 #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 a101a676b0f777b5805f3f470a9992c36b077e60 Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 3 Feb 2025 19:40:10 +0100 Subject: [PATCH 61/82] minor compilation fix --- tests/functional_tests/sha3.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/functional_tests/sha3.cpp b/tests/functional_tests/sha3.cpp index 537bb5ea..427c1e82 100644 --- a/tests/functional_tests/sha3.cpp +++ b/tests/functional_tests/sha3.cpp @@ -23,6 +23,7 @@ // SOFTWARE. #include #include +#include using namespace std; #ifndef KECCAKF_ROUNDS From a85445083f92b21a33d1947d1596336601da94e7 Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 3 Feb 2025 21:24:32 +0100 Subject: [PATCH 62/82] testnet restart (currency formation version: 99 -> 100) --- src/currency_core/currency_config.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/currency_core/currency_config.h b/src/currency_core/currency_config.h index cd796b74..06ce2813 100644 --- a/src/currency_core/currency_config.h +++ b/src/currency_core/currency_config.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2024 Zano Project +// Copyright (c) 2014-2025 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 @@ -10,7 +10,7 @@ #ifndef TESTNET #define CURRENCY_FORMATION_VERSION 84 #else -#define CURRENCY_FORMATION_VERSION 99 +#define CURRENCY_FORMATION_VERSION 100 #endif #define CURRENCY_GENESIS_NONCE (CURRENCY_FORMATION_VERSION + 101011010121) //bender's nightmare @@ -279,9 +279,9 @@ #define ZANO_HARDFORK_02_AFTER_HEIGHT 0 #define ZANO_HARDFORK_03_AFTER_HEIGHT 0 #define ZANO_HARDFORK_04_AFTER_HEIGHT 100 -#define ZANO_HARDFORK_04_TIMESTAMP_ACTUAL 1712800000ull // block 100, 2024-00-00 00:00:00 UTC +#define ZANO_HARDFORK_04_TIMESTAMP_ACTUAL 1738659600ull // block 100, 2025-00-00 00:00:00 UTC #define ZANO_HARDFORK_05_AFTER_HEIGHT 200 -#define ZANO_HARDFORK_05_MIN_BUILD_VER 356 +#define ZANO_HARDFORK_05_MIN_BUILD_VER 379 #endif From a25baf8d94e7d0485f30d9e7362dbf74264e1ec4 Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 3 Feb 2025 21:27:30 +0100 Subject: [PATCH 63/82] === version bump: 2.0.1.378 -> 2.1.0.379 === --- src/version.h.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/version.h.in b/src/version.h.in index 5b55abd7..db671fe0 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -4,10 +4,10 @@ #define BUILD_COMMIT_ID "@VERSION@" #define PROJECT_MAJOR_VERSION "2" -#define PROJECT_MINOR_VERSION "0" -#define PROJECT_REVISION "1" +#define PROJECT_MINOR_VERSION "1" +#define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 378 +#define PROJECT_VERSION_BUILD_NO 379 #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 3bbdc9c140539d2cb6a88c909e2d41fb81e336eb Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 5 Feb 2025 08:00:44 +0100 Subject: [PATCH 64/82] ui update (PR 140) --- 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 dbca6947..438562dc 160000 --- a/src/gui/qt-daemon/layout +++ b/src/gui/qt-daemon/layout @@ -1 +1 @@ -Subproject commit dbca694737496434ef9c7da765ee6aafd7f90158 +Subproject commit 438562dccd5f1ac5dcf4634af1539192d175b96f From c47dee5158aaebb43dbd184fcf6433cee6d2c887 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Wed, 5 Feb 2025 10:02:52 +0300 Subject: [PATCH 65/82] === build number: 379 -> 380 === --- 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 db671fe0..f2f97665 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 379 +#define PROJECT_VERSION_BUILD_NO 380 #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 820569ff4e15217bc0bab314a4573d0632cda697 Mon Sep 17 00:00:00 2001 From: sowle Date: Thu, 6 Feb 2025 22:09:28 +0100 Subject: [PATCH 66/82] ui update (PR 141) --- 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 438562dc..5d4d0da2 160000 --- a/src/gui/qt-daemon/layout +++ b/src/gui/qt-daemon/layout @@ -1 +1 @@ -Subproject commit 438562dccd5f1ac5dcf4634af1539192d175b96f +Subproject commit 5d4d0da275671594e5ddc8a68bd23d4bfe17be1e From b79e962e7568737becfe6d5c76b4efd5897333d8 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Fri, 7 Feb 2025 00:11:32 +0300 Subject: [PATCH 67/82] === build number: 380 -> 381 === --- 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 f2f97665..fb011fe5 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 380 +#define PROJECT_VERSION_BUILD_NO 381 #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 689353538847456313689b36f5dce4137de10427 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Mon, 10 Feb 2025 20:44:35 +0400 Subject: [PATCH 68/82] changed meta info format to json --- src/currency_core/currency_basic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/currency_core/currency_basic.h b/src/currency_core/currency_basic.h index 5b0bfcc2..4c4882b4 100644 --- a/src/currency_core/currency_basic.h +++ b/src/currency_core/currency_basic.h @@ -769,7 +769,7 @@ namespace currency KV_SERIALIZE(decimal_point) DOC_DSCR("Decimal point.") DOC_EXMP(12) DOC_END KV_SERIALIZE(ticker) DOC_DSCR("Ticker associated with the asset.") DOC_EXMP("ZABC") DOC_END KV_SERIALIZE(full_name) DOC_DSCR("Full name of the asset.") DOC_EXMP("Zano wrapped ABC") DOC_END - KV_SERIALIZE(meta_info) DOC_DSCR("Any other information associated with the asset in free form.") DOC_EXMP("Stable and private") DOC_END + KV_SERIALIZE(meta_info) DOC_DSCR("Any other information associated with the asset, by default in a json format.") DOC_EXMP("{ \"logo_url\": \"https://some.nice.logo.png\"}") DOC_END KV_SERIALIZE_POD_AS_HEX_STRING(owner) DOC_DSCR("Owner's key, used only for EMIT and UPDATE validation, can be changed by transferring asset ownership.") DOC_EXMP("f74bb56a5b4fa562e679ccaadd697463498a66de4f1760b2cd40f11c3a00a7a8") DOC_END KV_SERIALIZE(hidden_supply) DOC_DSCR("This field is reserved for future use and will be documented later.") DOC_END KV_SERIALIZE_POD_AS_HEX_STRING(owner_eth_pub_key) DOC_DSCR("[Optional] Owner's key in the case when ETH signature is used.") DOC_END From 05f045865865eb0eb33b2ea92963ae9d7f9a397f Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 12 Feb 2025 16:50:10 +0100 Subject: [PATCH 69/82] ui update (PR 142) --- 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 5d4d0da2..b973eec7 160000 --- a/src/gui/qt-daemon/layout +++ b/src/gui/qt-daemon/layout @@ -1 +1 @@ -Subproject commit 5d4d0da275671594e5ddc8a68bd23d4bfe17be1e +Subproject commit b973eec755acd61878133f2cb0b5675b58ead427 From 664a971c464ab75ee01f390853916c1a9f5dc164 Mon Sep 17 00:00:00 2001 From: sowle Date: Thu, 13 Feb 2025 11:54:05 +0100 Subject: [PATCH 70/82] readme: fixed a typo (credits to @dudebing99) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 97bd8b80..7dbf161d 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ For instance, by adding the following lines to `~/.bashrc` 1. If you skipped step 6 and did not set the environment variables: cd zano && mkdir build && cd build - BOOST_ROOT=$HOME/boost_1_70_0 OPENSSL_ROOT_DIR=$HOME/openssl cmake .. + BOOST_ROOT=$HOME/boost_1_84_0 OPENSSL_ROOT_DIR=$HOME/openssl cmake .. make -j1 daemon simplewallet 2. If you set the variables in step 6: From 2006b712502f44956063b35bdbf1a854fe7ef4ea Mon Sep 17 00:00:00 2001 From: sowle Date: Thu, 13 Feb 2025 11:57:47 +0100 Subject: [PATCH 71/82] readme: added bzip2 and libssl-dev to prerequisites --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7dbf161d..076253e8 100644 --- a/README.md +++ b/README.md @@ -36,11 +36,11 @@ Recommended OS versions: Ubuntu 20.04, 22.04 LTS. [*server version*] - sudo apt-get install -y build-essential g++ curl autotools-dev libicu-dev libbz2-dev cmake git screen checkinstall zlib1g-dev + sudo apt-get install -y build-essential g++ curl autotools-dev libicu-dev libbz2-dev cmake git screen checkinstall zlib1g-dev libssl-dev bzip2 [*GUI version*] - sudo apt-get install -y build-essential g++ python-dev autotools-dev libicu-dev libbz2-dev cmake git screen checkinstall zlib1g-dev mesa-common-dev libglu1-mesa-dev + sudo apt-get install -y build-essential g++ python-dev autotools-dev libicu-dev libbz2-dev cmake git screen checkinstall zlib1g-dev libssl-dev bzip2 mesa-common-dev libglu1-mesa-dev 2. Clone Zano into a local folder\ (If for some reason you need to use alternative Zano branch, change 'master' to the required branch name.) From 4c860417f5eb3db2a6bb681881bff35396d06c86 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 14 Feb 2025 03:17:33 +0100 Subject: [PATCH 72/82] pre hardfork tx freeze period implemented (+HF6) --- src/currency_core/blockchain_storage.cpp | 17 +++++++++++++++++ src/currency_core/blockchain_storage.h | 1 + src/currency_core/core_runtime_config.h | 5 ++++- src/currency_core/currency_config.h | 16 ++++++++++++++-- src/currency_core/currency_core.h | 1 + 5 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 01074e2c..65c0bb1d 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -1029,7 +1029,24 @@ bool blockchain_storage::is_tx_related_to_altblock(crypto::hash tx_id) const auto it = m_alternative_chains_txs.find(tx_id); return it != m_alternative_chains_txs.end(); } +//------------------------------------------------------------------ +bool blockchain_storage::is_pre_hardfork_tx_freeze_period_active() const +{ + CRITICAL_REGION_LOCAL(m_read_lock); + if (!is_hardfork_active(ZANO_HARDFORK_05)) + return false; + uint64_t next_block_height = m_db_blocks.size(); // top block height + 1 + size_t current_hardfork_id = m_core_runtime_config.hard_forks.get_the_most_recent_hardfork_id_for_height(next_block_height); + size_t next_hardfork_id = current_hardfork_id + 1; + if (next_hardfork_id >= ZANO_HARDFORKS_TOTAL) + return false; + + uint64_t next_hf_height_active_after = m_core_runtime_config.hard_forks.m_height_the_hardfork_n_active_after[next_hardfork_id]; + + bool result = (next_block_height + m_core_runtime_config.pre_hardfork_tx_freeze_period > next_hf_height_active_after); + return result; +} //------------------------------------------------------------------ bool blockchain_storage::get_block_extended_info_by_hash(const crypto::hash &h, block_extended_info &blk) const { diff --git a/src/currency_core/blockchain_storage.h b/src/currency_core/blockchain_storage.h index 5ebc328c..c98e86eb 100644 --- a/src/currency_core/blockchain_storage.h +++ b/src/currency_core/blockchain_storage.h @@ -240,6 +240,7 @@ namespace currency bool get_block_by_height(uint64_t h, block &blk) const; bool is_tx_related_to_altblock(crypto::hash tx_id) const; //void get_all_known_block_ids(std::list &main, std::list &alt, std::list &invalid) const; + bool is_pre_hardfork_tx_freeze_period_active() const; bc_attachment_services_manager& get_attachment_services_manager(){ return m_services_mgr; } diff --git a/src/currency_core/core_runtime_config.h b/src/currency_core/core_runtime_config.h index 799ba0f9..0ed52890 100644 --- a/src/currency_core/core_runtime_config.h +++ b/src/currency_core/core_runtime_config.h @@ -107,6 +107,7 @@ namespace currency core_time_func_t get_core_time; uint64_t hf4_minimum_mixins; wide_difficulty_type max_pos_difficulty; + uint64_t pre_hardfork_tx_freeze_period; // number of blocks before the hardfork activatio when no new txs are accepted (effective from HF5); 0 means feature is switched off hard_forks_descriptor hard_forks; std::array min_build_numbers_for_hard_forks; @@ -137,6 +138,7 @@ namespace currency pc.max_alt_blocks = CURRENCY_ALT_BLOCK_MAX_COUNT; pc.hf4_minimum_mixins = CURRENCY_HF4_MANDATORY_DECOY_SET_SIZE; pc.max_pos_difficulty = wide_difficulty_type(POS_MAX_DIFFICULTY_ALLOWED); + pc.pre_hardfork_tx_freeze_period = CURRENCY_PRE_HARDFORK_TX_FREEZE_PERIOD; // TODO: refactor the following pc.hard_forks.set_hardfork_height(1, ZANO_HARDFORK_01_AFTER_HEIGHT); @@ -144,7 +146,8 @@ namespace currency pc.hard_forks.set_hardfork_height(3, ZANO_HARDFORK_03_AFTER_HEIGHT); pc.hard_forks.set_hardfork_height(4, ZANO_HARDFORK_04_AFTER_HEIGHT); pc.hard_forks.set_hardfork_height(5, ZANO_HARDFORK_05_AFTER_HEIGHT); pc.min_build_numbers_for_hard_forks[5] = ZANO_HARDFORK_05_MIN_BUILD_VER; - static_assert(5 + 1 == ZANO_HARDFORKS_TOTAL); + pc.hard_forks.set_hardfork_height(6, ZANO_HARDFORK_06_AFTER_HEIGHT); pc.min_build_numbers_for_hard_forks[6] = ZANO_HARDFORK_06_MIN_BUILD_VER; + static_assert(6 + 1 == ZANO_HARDFORKS_TOTAL); pc.get_core_time = &core_runtime_config::_default_core_time_function; bool r = epee::string_tools::hex_to_pod(ALIAS_SHORT_NAMES_VALIDATION_PUB_KEY, pc.alias_validation_pubkey); diff --git a/src/currency_core/currency_config.h b/src/currency_core/currency_config.h index 06ce2813..6efa5517 100644 --- a/src/currency_core/currency_config.h +++ b/src/currency_core/currency_config.h @@ -41,6 +41,7 @@ #define CURRENCY_DEFAULT_DECOY_SET_SIZE 10 #define CURRENCY_HF4_MANDATORY_DECOY_SET_SIZE 15 #define CURRENCY_HF4_MANDATORY_MIN_COINAGE 10 +#define CURRENCY_PRE_HARDFORK_TX_FREEZE_PERIOD 60 // number of blocks before the hardfork activation when no new txs are accepted (effective from HF5) #define CURRENT_BLOCK_MINOR_VERSION 0 #define CURRENCY_BLOCK_FUTURE_TIME_LIMIT 60*60*2 @@ -269,19 +270,29 @@ #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 11:49:55 #define ZANO_HARDFORK_04_TIMESTAMP_ACTUAL 1711021795ull // block 2555000, 2024-03-21 11:49:55 UTC + #define ZANO_HARDFORK_05_AFTER_HEIGHT 999999999999999999 -#define ZANO_HARDFORK_05_MIN_BUILD_VER 354 +#define ZANO_HARDFORK_05_MIN_BUILD_VER 380 + +#define ZANO_HARDFORK_06_AFTER_HEIGHT 999999999999999999 +#define ZANO_HARDFORK_06_MIN_BUILD_VER 380 #else // 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 100 #define ZANO_HARDFORK_04_TIMESTAMP_ACTUAL 1738659600ull // block 100, 2025-00-00 00:00:00 UTC + #define ZANO_HARDFORK_05_AFTER_HEIGHT 200 #define ZANO_HARDFORK_05_MIN_BUILD_VER 379 + +#define ZANO_HARDFORK_06_AFTER_HEIGHT 999999999999999999 +#define ZANO_HARDFORK_06_MIN_BUILD_VER 379 #endif @@ -291,7 +302,8 @@ #define ZANO_HARDFORK_03 3 #define ZANO_HARDFORK_04_ZARCANUM 4 #define ZANO_HARDFORK_05 5 -#define ZANO_HARDFORKS_TOTAL 6 +#define ZANO_HARDFORK_06 6 +#define ZANO_HARDFORKS_TOTAL 7 diff --git a/src/currency_core/currency_core.h b/src/currency_core/currency_core.h index 637103b1..3da70452 100644 --- a/src/currency_core/currency_core.h +++ b/src/currency_core/currency_core.h @@ -107,6 +107,7 @@ namespace currency void resume_mine(); blockchain_storage& get_blockchain_storage() { return m_blockchain_storage; } const blockchain_storage& get_blockchain_storage() const { return m_blockchain_storage; } + const core_runtime_config& get_runtime_config() const { return m_blockchain_storage.get_core_runtime_config(); } //debug functions void print_blockchain(uint64_t start_index, uint64_t end_index); void print_blockchain_index(); From cb74abddc548cffde292a4fb2b886c53f9995023 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 14 Feb 2025 03:18:25 +0100 Subject: [PATCH 73/82] coretests: chaingen: fill_tx_sources improved --- tests/core_tests/chaingen.cpp | 41 +++++++++++++++++++++++++---------- tests/core_tests/chaingen.h | 16 ++++++++++++++ 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index 7fb1787a..1c206717 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -1419,9 +1419,22 @@ bool fill_tx_sources(std::vector& sources, const std::vector(), check_for_spends, check_for_unlocktime, use_ref_by_id); } +bool fill_tx_sources(std::vector& sources, const std::vector& events, + const currency::block& blk_head, const currency::account_keys& from, uint64_t amount, size_t nmix, const std::vector& sources_to_avoid, + bool check_for_spends, bool check_for_unlocktime, bool use_ref_by_id, uint64_t* p_sources_amount_found /* = nullptr */) +{ + uint64_t fts_flags = + (check_for_spends ? fts_check_for_spends : fts_none) | + (check_for_unlocktime ? fts_check_for_unlocktime : fts_none) | + (use_ref_by_id ? fts_use_ref_by_id : fts_none) | + fts_check_for_hf4_min_coinage; + + return fill_tx_sources(sources, events, blk_head, from, amount, nmix, sources_to_avoid, fts_flags, p_sources_amount_found); +} + bool fill_tx_sources(std::vector& sources, const std::vector& events, const currency::block& blk_head, const currency::account_keys& from, uint64_t amount, size_t nmix, const std::vector& sources_to_avoid, - bool check_for_spends, bool check_for_unlocktime, bool use_ref_by_id, uint64_t* p_sources_amount_found /* = nullptr */) + uint64_t fts_flags, uint64_t* p_sources_amount_found /* = nullptr */) { map_output_idx_t outs; map_output_t outs_mine; @@ -1434,7 +1447,7 @@ bool fill_tx_sources(std::vector& sources, const std: if (!init_output_indices(outs, outs_mine, blockchain, mtx, from)) return false; - if(check_for_spends) + if (fts_flags & fts_check_for_spends) { if (!init_spent_output_indices(outs, outs_mine, blockchain, mtx, from)) return false; @@ -1494,7 +1507,7 @@ bool fill_tx_sources(std::vector& sources, const std: const output_index& oi = outs[o.first][sender_out]; if (oi.spent) continue; - if (check_for_unlocktime) + if (fts_flags & fts_check_for_unlocktime) { uint64_t unlock_time = currency::get_tx_max_unlock_time(*oi.p_tx); if (unlock_time < CURRENCY_MAX_BLOCK_NUMBER) @@ -1509,8 +1522,10 @@ bool fill_tx_sources(std::vector& sources, const std: if (unlock_time > head_block_ts + DIFFICULTY_TOTAL_TARGET) continue; } - } - if (blk_head.miner_tx.version >= TRANSACTION_VERSION_POST_HF4 && next_block_height - get_block_height(*oi.p_blk) < CURRENCY_HF4_MANDATORY_MIN_COINAGE) + } + + if ((fts_flags & fts_check_for_hf4_min_coinage) && blk_head.miner_tx.version >= TRANSACTION_VERSION_POST_HF4 + && next_block_height - get_block_height(*oi.p_blk) < CURRENCY_HF4_MANDATORY_MIN_COINAGE) { //ignore outs that doesn't fit the HF4 rule continue; @@ -1524,8 +1539,11 @@ bool fill_tx_sources(std::vector& sources, const std: ts.real_out_amount_blinding_mask = oi.amount_blinding_mask; ts.real_output_in_tx_index = oi.out_no; ts.real_out_tx_key = get_tx_pub_key_from_extra(*oi.p_tx); // source tx public key - if (!fill_output_entries(outs[o.first], sender_out, nmix, check_for_unlocktime, use_ref_by_id, next_block_height, head_block_ts, ts.real_output, ts.outputs)) + if (!fill_output_entries(outs[o.first], sender_out, nmix, fts_flags & fts_check_for_unlocktime, fts_flags & fts_use_ref_by_id, + next_block_height, head_block_ts, ts.real_output, ts.outputs)) + { continue; + } sources.push_back(ts); @@ -1770,7 +1788,7 @@ bool construct_tx_to_key(const currency::hard_forks_descriptor& hf, bool check_for_unlocktime /* = true */, bool use_ref_by_id /* = false */) { - crypto::secret_key sk; // stub + [[maybe_unused]] crypto::secret_key sk; // stub uint64_t spending_amount = fee; for(auto& el: destinations) spending_amount += el.amount; @@ -1782,14 +1800,13 @@ bool construct_tx_to_key(const currency::hard_forks_descriptor& hf, uint64_t tx_expected_block_height = get_block_height(blk_head) + 1; size_t tx_hardfork_id = 0; uint64_t tx_version = currency::get_tx_version_and_hardfork_id(tx_expected_block_height, hf, tx_hardfork_id); - boost::multiprecision::int128_t change = get_sources_total_amount(sources); - change -= spending_amount; - if (change < 0) + uint64_t sources_amount = get_sources_total_amount(sources); + if (sources_amount < spending_amount) return false; // should never happen if fill_tx_sources succeded - if (change == 0) + if (sources_amount == spending_amount) return construct_tx(from.get_keys(), sources, destinations, extr, att, tx, tx_version, tx_hardfork_id, sk, 0, mix_attr); std::vector local_dst = destinations; - local_dst.push_back(tx_destination_entry(change.convert_to(), from.get_public_address())); + local_dst.push_back(tx_destination_entry(sources_amount - spending_amount, from.get_public_address())); return construct_tx(from.get_keys(), sources, local_dst, extr, att, tx, tx_version, tx_hardfork_id, sk, 0, mix_attr); } diff --git a/tests/core_tests/chaingen.h b/tests/core_tests/chaingen.h index f81efb4f..a697c013 100644 --- a/tests/core_tests/chaingen.h +++ b/tests/core_tests/chaingen.h @@ -729,12 +729,28 @@ bool construct_tx(const currency::account_keys& sender_account_keys, void get_confirmed_txs(const std::vector& blockchain, const map_hash2tx_t& mtx, map_hash2tx_t& confirmed_txs); bool find_block_chain(const std::vector& events, std::vector& blockchain, map_hash2tx_t& mtx, const crypto::hash& head); + +enum fill_tx_sources_flag_t +{ + fts_none = 0, + fts_check_for_spends = 1 << 0, + fts_check_for_unlocktime = 1 << 1, + fts_use_ref_by_id = 1 << 2, + fts_check_for_hf4_min_coinage = 1 << 3, + // keep the following line at the end + fts_default = (fts_check_for_spends | fts_check_for_unlocktime | fts_check_for_hf4_min_coinage) +}; + bool fill_tx_sources(std::vector& sources, const std::vector& events, const currency::block& blk_head, const currency::account_keys& from, uint64_t amount, size_t nmix, bool check_for_spends = true, bool check_for_unlocktime = true, bool use_ref_by_id = false); bool fill_tx_sources(std::vector& sources, const std::vector& events, const currency::block& blk_head, const currency::account_keys& from, uint64_t amount, size_t nmix, const std::vector& sources_to_avoid, bool check_for_spends = true, bool check_for_unlocktime = true, bool use_ref_by_id = false, uint64_t* p_sources_amount_found = nullptr); +bool fill_tx_sources(std::vector& sources, const std::vector& events, + const currency::block& blk_head, const currency::account_keys& from, uint64_t amount, size_t nmix, const std::vector& sources_to_avoid, + uint64_t fts_flags, uint64_t* p_sources_amount_found = nullptr); + bool fill_tx_sources_and_destinations(const std::vector& events, const currency::block& blk_head, const currency::account_keys& from, const std::list& to, uint64_t amount, uint64_t fee, size_t nmix, std::vector& sources, From d8f12cdcc888a4a37ddc2c86951925049cf76cf9 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 14 Feb 2025 03:20:23 +0100 Subject: [PATCH 74/82] chaingen: zarcanum_in_alt_chain_2 test added (highlights an issue in alt block validation) --- tests/core_tests/chaingen_main.cpp | 3 +- tests/core_tests/zarcanum_test.cpp | 184 +++++++++++++++++++++++++++++ tests/core_tests/zarcanum_test.h | 8 ++ 3 files changed, 194 insertions(+), 1 deletion(-) diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index 11856db7..e1f7a9ce 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2022 Zano Project +// Copyright (c) 2014-2025 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 @@ -1297,6 +1297,7 @@ int main(int argc, char* argv[]) GENERATE_AND_PLAY(zarcanum_txs_with_big_shuffled_decoy_set_shuffled); GENERATE_AND_PLAY(zarcanum_pos_block_math); GENERATE_AND_PLAY(zarcanum_in_alt_chain); + GENERATE_AND_PLAY_HF(zarcanum_in_alt_chain_2, "4-*"); GENERATE_AND_PLAY(assets_and_explicit_native_coins_in_outs); GENERATE_AND_PLAY(zarcanum_block_with_txs); GENERATE_AND_PLAY(asset_depoyment_and_few_zc_utxos); diff --git a/tests/core_tests/zarcanum_test.cpp b/tests/core_tests/zarcanum_test.cpp index 472d3315..73296355 100644 --- a/tests/core_tests/zarcanum_test.cpp +++ b/tests/core_tests/zarcanum_test.cpp @@ -827,3 +827,187 @@ bool zarcanum_block_with_txs::c1(currency::core& c, size_t ev_index, const std:: { return true; } + +//------------------------------------------------------------------------------ + +zarcanum_in_alt_chain_2::zarcanum_in_alt_chain_2() +{ + REGISTER_CALLBACK_METHOD(zarcanum_in_alt_chain_2, c1); + REGISTER_CALLBACK_METHOD(zarcanum_in_alt_chain_2, configure_core); +} + +bool zarcanum_in_alt_chain_2::configure_core(currency::core& c, size_t ev_index, const std::vector& events) +{ + if (!wallet_test::configure_core(c, ev_index, events)) + return false; + + currency::core_runtime_config pc = c.get_blockchain_storage().get_core_runtime_config(); + pc.min_coinstake_age = POS_MINIMUM_COINSTAKE_AGE; // note using main chain setting here + c.get_blockchain_storage().set_core_runtime_config(pc); + + return true; +} + +bool zarcanum_in_alt_chain_2::generate(std::vector& events) const +{ + // + // Test idea: + // (test is intended to be used for >= HF4) + // + + // if any of the following constants changed in future this test sould be carefully reviewed + static_assert(CURRENCY_HF4_MANDATORY_MIN_COINAGE == 10); + static_assert(POS_MINIMUM_COINSTAKE_AGE == 10); + static_assert(CURRENCY_MINED_MONEY_UNLOCK_WINDOW == 10); + + 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); + account_base& bob_acc = m_accounts[BOB_ACC_IDX]; bob_acc.generate(); bob_acc.set_createtime(ts); + account_base& carol_acc = m_accounts[CAROL_ACC_IDX]; carol_acc.generate(); carol_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); + + // this test requires at least HF4 + DO_CALLBACK_PARAMS(events, "check_hardfork_active", static_cast(ZANO_HARDFORK_04_ZARCANUM)); + + // transfer some coins to Alice, Bob and Carol in a single tx + std::vector destinations; + destinations.emplace_back(MK_TEST_COINS(99), alice_acc.get_public_address()); + destinations.emplace_back(MK_TEST_COINS(98), bob_acc.get_public_address()); + destinations.emplace_back(MK_TEST_COINS(97), carol_acc.get_public_address()); + transaction tx_0{}; + r = construct_tx_to_key(m_hardforks, events, tx_0, blk_0r, miner_acc, destinations); + CHECK_AND_ASSERT_MES(r, false, "construct_tx_to_key failed"); + ADD_CUSTOM_EVENT(events, tx_0); + + // create blk_1 (height 11), note that all stake sources originate from this block + MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_acc, tx_0); + + //std::list alice_stake_sources({ alice_acc }); + + // + // main chain checks + // + + // rewind 8 blocks + REWIND_BLOCKS_N_WITH_TIME(events, blk_1r, blk_1, miner_acc, 8); + + { + // PoS block at height 20 cannot use stake output from block 11 (20 - 11 = 9, 9 < 10) + block blk_2_pos_bad{}; + CHECK_AND_ASSERT_MES(make_next_pos_block(generator, events, blk_1r, alice_acc, MK_TEST_COINS(1), 0, std::vector{}, fts_none, blk_2_pos_bad), false, ""); + generator.add_block_info(blk_2_pos_bad, std::list{}); + DO_CALLBACK(events, "mark_invalid_block"); + ADD_CUSTOM_EVENT(events, blk_2_pos_bad); + } + + // rewind 1 block + MAKE_NEXT_BLOCK(events, blk_2, blk_1r, miner_acc); + + // PoS block at height 21 CAN use stake output from block 11 (21 - 11 = 10) + block blk_3{}; + CHECK_AND_ASSERT_MES(make_next_pos_block(generator, events, blk_2, alice_acc, MK_TEST_COINS(1), 0, std::vector{}, fts_none, blk_3), false, ""); + generator.add_block_info(blk_3, std::list{}); + ADD_CUSTOM_EVENT(events, blk_3); + + // PoS block at height 22 CAN use stake output from block 11 (22 - 11 = 11) + // note using Bob account for staking + block blk_4{}; + CHECK_AND_ASSERT_MES(make_next_pos_block(generator, events, blk_3, bob_acc, MK_TEST_COINS(1), 0, std::vector{}, fts_none, blk_4), false, ""); + generator.add_block_info(blk_4, std::list{}); + ADD_CUSTOM_EVENT(events, blk_4); + + + // + // alt chain checks + // + + // make an alt chain + MAKE_NEXT_BLOCK(events, blk_2a, blk_1r, miner_acc); + MAKE_NEXT_BLOCK(events, blk_3a, blk_2a, miner_acc); + MAKE_NEXT_BLOCK(events, blk_4a, blk_3a, miner_acc); + MAKE_NEXT_BLOCK(events, blk_5a, blk_4a, miner_acc); + // this altchain should win and previous PoS block are now in alt chain + DO_CALLBACK_PARAMS(events, "check_top_block", params_top_block{blk_5a}); + + { + // alt PoS block at height 20 cannot use stake output from block 11 (20 - 11 = 9, 9 < 10) + // note using carol_acc + block blk_2a_pos_bad{}; + CHECK_AND_ASSERT_MES(make_next_pos_block(generator, events, blk_1r, carol_acc, MK_TEST_COINS(1), 0, std::vector{}, fts_none, blk_2a_pos_bad), false, ""); + generator.add_block_info(blk_2a_pos_bad, std::list{}); + DO_CALLBACK(events, "mark_invalid_block"); + ADD_CUSTOM_EVENT(events, blk_2a_pos_bad); + } + + // rewind 1 block + MAKE_NEXT_BLOCK(events, blk_2b, blk_1r, miner_acc); + + // alt PoS block at height 21 CAN use stake output from block 11 (21 - 11 = 10) + block blk_3b{}; + CHECK_AND_ASSERT_MES(make_next_pos_block(generator, events, blk_2b, carol_acc, MK_TEST_COINS(1), 0, std::vector{}, fts_none, blk_3b), false, ""); + generator.add_block_info(blk_3b, std::list{}); + ADD_CUSTOM_EVENT(events, blk_3b); + + // alt PoS block at height 22 CAN use stake output from block 11 (22 - 11 = 11) + // note using Bob account for staking + block blk_4b{}; + CHECK_AND_ASSERT_MES(make_next_pos_block(generator, events, blk_3b, bob_acc, MK_TEST_COINS(1), 0, std::vector{}, fts_none, blk_4b), false, ""); + generator.add_block_info(blk_4b, std::list{}); + ADD_CUSTOM_EVENT(events, blk_4b); + + + // make sure the chain switching did not occured + DO_CALLBACK_PARAMS(events, "check_top_block", params_top_block{blk_5a}); + + + // in 10th block we can stake the output + //MAKE_NEXT_POS_BLOCK(events, blk_2, blk_1r, alice_acc, alice_stake_sources); + + //DO_CALLBACK_PARAMS(events, "check_hardfork_inactive", static_cast(ZANO_HARDFORK_04_ZARCANUM)); + //MAKE_NEXT_BLOCK(events, blk_3, blk_2, miner_acc); + //DO_CALLBACK_PARAMS(events, "check_hardfork_active", static_cast(ZANO_HARDFORK_04_ZARCANUM)); + + //uint64_t bob_amount = COIN * 100; + //MAKE_TX(events, tx_1, miner_acc, bob_acc, bob_amount, blk_3); + ////make another tx just to create more decoys to fit hf4 rules of 16 decoys + //account_base carol_acc; carol_acc.generate(); + //MAKE_TX(events, tx_1_1, miner_acc, carol_acc, bob_amount, blk_3); + //MAKE_NEXT_BLOCK_TX_LIST(events, blk_4, blk_3, miner_acc, std::list({ tx_1, tx_1_1 })); + + // HF4 + // | + // 0 10 11 21 22 23 | 24 34 35 36 <- blockchain height + // (0 )..(0r)- (1 )..(1r)- !2 !- (3 )- (4 )..(4r)- (5 ) <- main chain + // tx_0 tx_1 \ tx_2a + // \ tx_2b + // -!5a!- (6a) <- alt chain + + //REWIND_BLOCKS_N_WITH_TIME(events, blk_4r, blk_4, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + + //// Bob: move all to miner + //MAKE_TX(events, tx_2a, bob_acc, miner_acc, bob_amount - TESTS_DEFAULT_FEE, blk_4r); + //// Miner: a little to Alice + //MAKE_TX(events, tx_2b, miner_acc, alice_acc, COIN, blk_4r); + //MAKE_NEXT_BLOCK_TX_LIST(events, blk_5, blk_4r, miner_acc, std::list({ tx_2a, tx_2b })); + + //// now in the main chain Bob has zero coins + //// check it in gen time ... + //CREATE_TEST_WALLET(bob_wlt, bob_acc, blk_0); + //REFRESH_TEST_WALLET_AT_GEN_TIME(events, bob_wlt, blk_5, 3 * CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 5); + //CHECK_TEST_WALLET_BALANCE_AT_GEN_TIME(bob_wlt, 0); + //// ... and in play time + //DO_CALLBACK_PARAMS(events, "check_balance", params_check_balance(BOB_ACC_IDX, 0)); + + + return true; +} + +bool zarcanum_in_alt_chain_2::c1(currency::core& c, size_t ev_index, const std::vector& events) +{ + return true; +} diff --git a/tests/core_tests/zarcanum_test.h b/tests/core_tests/zarcanum_test.h index 36836c8c..0b9ccf38 100644 --- a/tests/core_tests/zarcanum_test.h +++ b/tests/core_tests/zarcanum_test.h @@ -53,3 +53,11 @@ struct zarcanum_block_with_txs : public wallet_test mutable uint64_t m_alice_balance = 0; }; +struct zarcanum_in_alt_chain_2 : public wallet_test +{ + zarcanum_in_alt_chain_2(); + bool generate(std::vector& events) const; + bool configure_core(currency::core& c, size_t ev_index, const std::vector& events); + bool c1(currency::core& c, size_t ev_index, const std::vector& events); +}; + From 672309ba5f5cd96908da8498c70bef030808d972 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 14 Feb 2025 03:21:24 +0100 Subject: [PATCH 75/82] fixed an issue in alt block miner tx validation --- src/currency_core/blockchain_storage.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 65c0bb1d..c13f8cbd 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -8373,10 +8373,19 @@ bool blockchain_storage::validate_alt_block_txs(const block& b, const crypto::ha CHECK_AND_ASSERT_MES(r, false, "miner tx " << get_transaction_hash(b.miner_tx) << ": validation failed"); ki_lookup_time_total += ki_lookup; - // check stake age - uint64_t coinstake_age = height - max_related_block_height - 1; - CHECK_AND_ASSERT_MES(coinstake_age >= m_core_runtime_config.min_coinstake_age, false, - "miner tx's coinstake age is " << coinstake_age << ", that is less than minimum required " << m_core_runtime_config.min_coinstake_age << "; max_related_block_height == " << max_related_block_height); + + if (is_hardfork_active_for_height(ZANO_HARDFORK_04_ZARCANUM, height)) + { + CHECK_AND_ASSERT_MES(height - max_related_block_height >= CURRENCY_HF4_MANDATORY_MIN_COINAGE, false, "Coinage rule broken (altblock): h = " << + abei.height << ", max_related_block_height=" << max_related_block_height << ", miner tx: " << get_transaction_hash(b.miner_tx)); + } + else + { + // legacy check of stake age (consider removing old hardforks alt block checks -- sowle) + uint64_t coinstake_age = height - max_related_block_height - 1; + CHECK_AND_ASSERT_MES(coinstake_age >= m_core_runtime_config.min_coinstake_age, false, + "miner tx's coinstake age is " << coinstake_age << ", that is less than minimum required " << m_core_runtime_config.min_coinstake_age << "; max_related_block_height == " << max_related_block_height); + } } update_alt_out_indexes_for_tx_in_block(b.miner_tx, abei); From 141a8eac6a8feca27655d0216c3968f49e880173 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 14 Feb 2025 03:22:31 +0100 Subject: [PATCH 76/82] chaingen: zarcanum_in_alt_chain_2 (forgotten changes) --- tests/core_tests/zarcanum_test.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/core_tests/zarcanum_test.cpp b/tests/core_tests/zarcanum_test.cpp index 73296355..9fc76438 100644 --- a/tests/core_tests/zarcanum_test.cpp +++ b/tests/core_tests/zarcanum_test.cpp @@ -55,14 +55,14 @@ bool invalidate_zarcanum_sig(size_t n, zarcanum_sig& sig) } bool make_next_pos_block(test_generator& generator, std::vector& events, const block& prev_block, const account_base& stake_acc, - uint64_t amount_to_find, size_t nmix, const std::vector& transactions, block& result) + uint64_t amount_to_find, size_t nmix, const std::vector& transactions, uint64_t fts_flags, block& result) { bool r = false; std::vector sources; size_t height = get_block_height(prev_block) + 1; crypto::hash prev_id = get_block_hash(prev_block); - r = fill_tx_sources(sources, events, prev_block, stake_acc.get_keys(), amount_to_find, nmix, true, true, false); + r = fill_tx_sources(sources, events, prev_block, stake_acc.get_keys(), amount_to_find, nmix, std::vector{}, fts_flags); CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources failed"); CHECK_AND_ASSERT_MES(shuffle_source_entries(sources), false, ""); auto it = std::max_element(sources.begin(), sources.end(), [&](const tx_source_entry& lhs, const tx_source_entry& rhs){ return lhs.amount < rhs.amount; }); @@ -439,7 +439,7 @@ bool zarcanum_pos_block_math::generate(std::vector& events) co for(size_t i = 1; ; ++i) { block blk_1_pos_bad; - CHECK_AND_ASSERT_MES(make_next_pos_block(generator, events, blk_1r, miner_acc, COIN, 10, std::vector(), blk_1_pos_bad), false, ""); + CHECK_AND_ASSERT_MES(make_next_pos_block(generator, events, blk_1r, miner_acc, COIN, 10, std::vector(), fts_default, blk_1_pos_bad), false, ""); LOG_PRINT_CYAN("i = " << i, LOG_LEVEL_0); if (!invalidate_zarcanum_sig(i, boost::get(blk_1_pos_bad.miner_tx.signatures[0]))) break; From 8341f4f31ff6329a53ac15ee063234de4ff2d23d Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 14 Feb 2025 03:23:40 +0100 Subject: [PATCH 77/82] minor improvements --- src/rpc/core_rpc_server.cpp | 20 ++++++++++---------- src/rpc/core_rpc_server.h | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 46fe0a41..add47f52 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -22,16 +22,16 @@ namespace currency { namespace { - const command_line::arg_descriptor arg_rpc_bind_ip ("rpc-bind-ip", "", "127.0.0.1"); - const command_line::arg_descriptor arg_rpc_bind_port ("rpc-bind-port", "", std::to_string(RPC_DEFAULT_PORT)); - const command_line::arg_descriptor arg_rpc_ignore_status ("rpc-ignore-offline", "Let rpc calls despite online/offline status"); + const command_line::arg_descriptor arg_rpc_bind_ip ("rpc-bind-ip", "", "127.0.0.1"); + const command_line::arg_descriptor arg_rpc_bind_port ("rpc-bind-port", "", std::to_string(RPC_DEFAULT_PORT)); + const command_line::arg_descriptor arg_rpc_ignore_offline_status ("rpc-ignore-offline", "Let rpc calls despite online/offline status"); } //----------------------------------------------------------------------------------- void core_rpc_server::init_options(boost::program_options::options_description& desc) { command_line::add_arg(desc, arg_rpc_bind_ip); command_line::add_arg(desc, arg_rpc_bind_port); - command_line::add_arg(desc, arg_rpc_ignore_status); + command_line::add_arg(desc, arg_rpc_ignore_offline_status); } //------------------------------------------------------------------------------------------------------------------------------ core_rpc_server::core_rpc_server(core& cr, nodetool::node_server >& p2p, @@ -39,16 +39,16 @@ namespace currency : m_core(cr) , m_p2p(p2p) , m_of(of) - , m_ignore_status(false) + , m_ignore_offline_status(false) {} //------------------------------------------------------------------------------------------------------------------------------ bool core_rpc_server::handle_command_line(const boost::program_options::variables_map& vm) { m_bind_ip = command_line::get_arg(vm, arg_rpc_bind_ip); m_port = command_line::get_arg(vm, arg_rpc_bind_port); - if (command_line::has_arg(vm, arg_rpc_ignore_status)) + if (command_line::has_arg(vm, arg_rpc_ignore_offline_status)) { - m_ignore_status = command_line::get_arg(vm, arg_rpc_ignore_status); + m_ignore_offline_status = command_line::get_arg(vm, arg_rpc_ignore_offline_status); } return true; } @@ -64,7 +64,7 @@ namespace currency bool core_rpc_server::check_core_ready_(const std::string& calling_method) { #ifndef TESTNET - if (m_ignore_status) + if (m_ignore_offline_status) return true; if(!m_p2p.get_payload_object().is_synchronized()) { @@ -576,7 +576,7 @@ namespace currency //------------------------------------------------------------------------------------------------------------------------------ bool core_rpc_server::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) { - if (!m_ignore_status && !m_p2p.get_connections_count()) + if (!m_ignore_offline_status && !m_p2p.get_connections_count()) { res.status = API_RETURN_CODE_DISCONNECTED; return true; @@ -862,7 +862,7 @@ namespace currency return true; } - if (!m_ignore_status && !m_p2p.get_payload_object().get_synchronized_connections_count()) + if (!m_ignore_offline_status && !m_p2p.get_payload_object().get_synchronized_connections_count()) { LOG_PRINT_L0("[on_send_raw_tx]: Failed to send, daemon not connected to net"); res.status = API_RETURN_CODE_DISCONNECTED; diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h index c0a089ae..49fd54c6 100644 --- a/src/rpc/core_rpc_server.h +++ b/src/rpc/core_rpc_server.h @@ -39,7 +39,7 @@ namespace currency void set_rpc_chain_handler(epee::net_utils::http::i_chain_handler* prpc_chain_handler) { m_prpc_chain_handler = prpc_chain_handler; } bool on_get_blocks_direct(const COMMAND_RPC_GET_BLOCKS_DIRECT::request& req, COMMAND_RPC_GET_BLOCKS_DIRECT::response& res, connection_context& cntx); - void set_ignore_connectivity_status(bool ignore) { m_ignore_status = ignore;} + void set_ignore_connectivity_status(bool ignore) { m_ignore_offline_status = ignore;} bool on_get_height(const COMMAND_RPC_GET_HEIGHT::request& req, COMMAND_RPC_GET_HEIGHT::response& res, connection_context& cntx); bool on_get_blocks(const COMMAND_RPC_GET_BLOCKS_FAST::request& req, COMMAND_RPC_GET_BLOCKS_FAST::response& res, connection_context& cntx); @@ -196,7 +196,7 @@ namespace currency bc_services::bc_offers_service& m_of; std::string m_port; std::string m_bind_ip; - bool m_ignore_status; + bool m_ignore_offline_status; epee::net_utils::http::i_chain_handler* m_prpc_chain_handler = nullptr; }; } From 38ae547f5c620b2e44c80ad2182f6b2c6dc8d8c6 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 14 Feb 2025 03:24:45 +0100 Subject: [PATCH 78/82] send raw tx is disabled during the pre hardfork tx freeze period --- src/rpc/core_rpc_server.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index add47f52..6306d3ac 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -869,6 +869,13 @@ namespace currency return true; } + if (m_p2p.get_payload_object().get_core().get_blockchain_storage().is_pre_hardfork_tx_freeze_period_active()) + { + LOG_PRINT_L0("[on_send_raw_tx]: pre hardfork freeze period is in effect, sending transactions is not allowed till the next hardfork. Please, try again after the hardfork activation."); + res.status = API_RETURN_CODE_BUSY; + return true; + } + currency_connection_context fake_context = AUTO_VAL_INIT(fake_context); tx_verification_context tvc = AUTO_VAL_INIT(tvc); if(!m_core.handle_incoming_tx(tx_blob, tvc, false)) From 88060ee2a4841f0033ff086b7332a260f3854169 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=D1=91pa=20Dolgorukov?= <63650851+stepan-dolgorukov@users.noreply.github.com> Date: Fri, 14 Feb 2025 19:03:53 +0500 Subject: [PATCH 79/82] linux gui: Escape back slash in the value by the key "Exec" (#505) --- utils/Zano.sh | 2 +- utils/Zano_appimage_wrapper.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/Zano.sh b/utils/Zano.sh index 6e4d22d8..696b3859 100755 --- a/utils/Zano.sh +++ b/utils/Zano.sh @@ -29,7 +29,7 @@ create_desktop_icon() echo GenericName=Zano | tee -a $target_file_name > /dev/null echo Comment=Privacy blockchain | tee -a $target_file_name > /dev/null echo Icon=$script_dir/html/files/desktop_linux_icon.png | tee -a $target_file_name > /dev/null - echo Exec=$script_dir/Zano.sh --deeplink-params=%u | tee -a $target_file_name > /dev/null + echo Exec=$script_dir/Zano.sh --deeplink-params=\\\\\"%u\\\\\" | tee -a $target_file_name > /dev/null echo Terminal=true | tee -a $target_file_name > /dev/null echo Type=Application | tee -a $target_file_name > /dev/null echo "Categories=Qt;Utility;" | tee -a $target_file_name > /dev/null diff --git a/utils/Zano_appimage_wrapper.sh b/utils/Zano_appimage_wrapper.sh index be3171c5..bd0902cc 100755 --- a/utils/Zano_appimage_wrapper.sh +++ b/utils/Zano_appimage_wrapper.sh @@ -32,7 +32,7 @@ create_desktop_icon() echo GenericName=Zano | tee -a $target_file_name > /dev/null echo Comment=Privacy blockchain | tee -a $target_file_name > /dev/null echo Icon=${out_dir}/Zano.png | tee -a $target_file_name > /dev/null - echo Exec=$APPIMAGE --deeplink-params=\\\"%u\\\" | tee -a $target_file_name > /dev/null + echo Exec=$APPIMAGE --deeplink-params=\\\\\"%u\\\\\" | tee -a $target_file_name > /dev/null echo Terminal=false | tee -a $target_file_name > /dev/null echo Type=Application | tee -a $target_file_name > /dev/null echo "Categories=Qt;Utility;" | tee -a $target_file_name > /dev/null From 2bcc6075b726dcfcdfcfd9e51bdd96f493e2b079 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 14 Feb 2025 16:08:07 +0100 Subject: [PATCH 80/82] HF5 height is set to 3076400 (mainnet) --- src/currency_core/currency_config.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/currency_core/currency_config.h b/src/currency_core/currency_config.h index 6efa5517..bf0b901b 100644 --- a/src/currency_core/currency_config.h +++ b/src/currency_core/currency_config.h @@ -274,11 +274,11 @@ #define ZANO_HARDFORK_04_AFTER_HEIGHT 2555000 // 2024-03-21 11:49:55 #define ZANO_HARDFORK_04_TIMESTAMP_ACTUAL 1711021795ull // block 2555000, 2024-03-21 11:49:55 UTC -#define ZANO_HARDFORK_05_AFTER_HEIGHT 999999999999999999 -#define ZANO_HARDFORK_05_MIN_BUILD_VER 380 +#define ZANO_HARDFORK_05_AFTER_HEIGHT 3076400 +#define ZANO_HARDFORK_05_MIN_BUILD_VER 382 -#define ZANO_HARDFORK_06_AFTER_HEIGHT 999999999999999999 -#define ZANO_HARDFORK_06_MIN_BUILD_VER 380 +#define ZANO_HARDFORK_06_AFTER_HEIGHT 999999999999999999 +#define ZANO_HARDFORK_06_MIN_BUILD_VER 382 #else // Testnet #define ZANO_HARDFORK_01_AFTER_HEIGHT 0 From ede5df5afe0771358b1c96bb368af3b35e7d0fd2 Mon Sep 17 00:00:00 2001 From: sowle Date: Sun, 16 Feb 2025 22:56:43 +0100 Subject: [PATCH 81/82] predownload files moved to CDN and updated to height 3030303 --- src/common/pre_download.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/pre_download.h b/src/common/pre_download.h index 6e4de659..c44649a0 100644 --- a/src/common/pre_download.h +++ b/src/common/pre_download.h @@ -21,8 +21,8 @@ namespace tools }; #ifndef TESTNET - static constexpr pre_download_entry c_pre_download_mdbx = { "http://95.217.42.247/pre-download/zano_mdbx_95_2892700.pak", "68e819cd119e4af1b81f1852e42978d662f1e6355124352f3e835db32b5a8230", 6414724487, 10468823040 }; - static constexpr pre_download_entry c_pre_download_lmdb = { "https://f005.backblazeb2.com/file/zano-predownload/zano_lmdb_95_2892700.pak", "605eb4eb0903aa7b3a2a046514ef349d45c7de31d2702fd9dc104ca65705d6eb", 7860127140, 10204872704 }; + static constexpr pre_download_entry c_pre_download_mdbx = { "https://f005.backblazeb2.com/file/zano-predownload/zano_mdbx_95_3030303.pak", "937c80a2a212e70f0b5c9001159f983db72dd0cf7a6d55d72bcd9d6998874ffb", 7809031729, 12347842560 }; + static constexpr pre_download_entry c_pre_download_lmdb = { "https://f005.backblazeb2.com/file/zano-predownload/zano_lmdb_95_3030303.pak", "227f20b3998a8622363ebd4b7189e73caac21cfc17fa8544a3fa9d593e41709d", 9450752666, 12102598656 }; #else static constexpr pre_download_entry c_pre_download_mdbx = { "", "", 0, 0 }; static constexpr pre_download_entry c_pre_download_lmdb = { "", "", 0, 0 }; From f0378d8be007c7c44d439c4f9c486ad6627045e7 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Mon, 17 Feb 2025 00:57:26 +0300 Subject: [PATCH 82/82] === build number: 381 -> 382 === --- 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 fb011fe5..10963e01 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 381 +#define PROJECT_VERSION_BUILD_NO 382 #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 "]"