From bc88d0d642298c2a15f58c953a4226f9a8066e63 Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 29 Aug 2022 23:00:34 +0200 Subject: [PATCH] wallet: Zarcanum PoS (work in progress, scan_pos refactoring) --- src/rpc/core_rpc_server_commands_defs.h | 2 - src/wallet/wallet2.cpp | 67 ++++++++++++++++++++++++- src/wallet/wallet2.h | 52 ++++--------------- src/wallet/wallets_manager.cpp | 2 +- 4 files changed, 77 insertions(+), 46 deletions(-) diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 298d3ed9..2cbb3af2 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -1138,7 +1138,6 @@ namespace currency uint64_t starter_timestamp; crypto::hash last_block_hash; bool is_pos_allowed; - uint64_t iterations_processed; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(status) @@ -1146,7 +1145,6 @@ namespace currency KV_SERIALIZE(block_timestamp) KV_SERIALIZE(height) KV_SERIALIZE(is_pos_allowed) - KV_SERIALIZE(iterations_processed) KV_SERIALIZE(starter_timestamp) KV_SERIALIZE_VAL_POD_AS_BLOB(last_block_hash); END_KV_SERIALIZE_MAP() diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 26f191f1..c81dc55a 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -37,6 +37,7 @@ using namespace epee; #include "storages/levin_abstract_invoke2.h" #include "common/variant_helper.h" +#include "currency_core/crypto_config.h" using namespace currency; @@ -3635,10 +3636,18 @@ bool wallet2::fill_mining_context(mining_context& ctx) return false; ctx.basic_diff.assign(pos_details_resp.pos_basic_difficulty); ctx.sm = pos_details_resp.sm; + + if (get_core_runtime_config().hard_forks.is_hardfork_active_for_height(4, get_top_block_height() + 1)) + { + // Zarcanum (PoS with hidden amounts) + ctx.zarcanum = true; + ctx.last_pow_block_id_hashed = crypto::hash_helper_t::hs(CRYPTO_HDS_ZARCANUM_LAST_POW_HASH, ctx.sm.last_pow_id); + } + ctx.rsp.last_block_hash = pos_details_resp.last_block_hash; - ctx.rsp.status = API_RETURN_CODE_OK; ctx.rsp.is_pos_allowed = pos_details_resp.pos_mining_allowed; ctx.rsp.starter_timestamp = pos_details_resp.starter_timestamp; + ctx.rsp.status = API_RETURN_CODE_OK; return true; } //------------------------------------------------------------------ @@ -3679,10 +3688,64 @@ bool wallet2::try_mint_pos(const currency::account_public_address& miner_address build_minted_block(ctx.sp, ctx.rsp, miner_address); } - WLT_LOG_L0("PoS mining: " << ctx.rsp.iterations_processed << " iterations finished, status: " << ctx.rsp.status << ", used " << ctx.sp.pos_entries.size() << " entries with total amount: " << print_money_brief(pos_entries_amount)); + WLT_LOG_L0("PoS mining: " << ctx.iterations_processed << " iterations finished, status: " << ctx.rsp.status << ", used " << ctx.sp.pos_entries.size() << " entries with total amount: " << print_money_brief(pos_entries_amount)); return true; } +//------------------------------------------------------------------ +void wallet2::do_pos_mining_prepare_entry(mining_context& cxt, size_t pos_entry_index) +{ + if (cxt.zarcanum) + { + //uint64_t pos_entry_wallet_index = cxt.sp.pos_entries[pos_entry_index].wallet_index; + //CHECK_AND_ASSERT_MES_NO_RET(pos_entry_wallet_index < m_transfers.size(), "invalid pos_entry_wallet_index = " << pos_entry_wallet_index << ", m_transfers: " << m_transfers.size()); + + } +} +//------------------------------------------------------------------ +bool wallet2::do_pos_mining_iteration(mining_context& cxt, size_t pos_entry_index, uint64_t ts) +{ + currency::stake_kernel sk = AUTO_VAL_INIT(sk); + build_kernel(cxt.sp.pos_entries[pos_entry_index], cxt.sm, ts, sk); + + crypto::hash kernel_hash; + { + PROFILE_FUNC("calc_hash"); + kernel_hash = crypto::cn_fast_hash(&sk, sizeof(sk)); + } + + const uint64_t stake_amount = cxt.sp.pos_entries[pos_entry_index].amount; + bool found = false; + + if (cxt.zarcanum) + { + } + else + { + // old PoS with non-hidden amounts + currency::wide_difficulty_type final_diff = cxt.basic_diff / stake_amount; + { + PROFILE_FUNC("check_hash"); + found = currency::check_hash(kernel_hash, final_diff); + ++cxt.iterations_processed; + } + if (found) + { + cxt.rsp.index = pos_entry_index; + cxt.rsp.block_timestamp = ts; + + LOG_PRINT_GREEN("Found kernel: amount: " << currency::print_money_brief(stake_amount) << ENDL + << "difficulty: " << cxt.basic_diff << ", final_diff: " << final_diff << ENDL + << "index: " << cxt.sp.pos_entries[pos_entry_index].index << ENDL + << "kernel info: " << ENDL + << print_stake_kernel_info(sk) << ENDL + << "kernel_hash(proof): " << kernel_hash, + LOG_LEVEL_0); + } + } + + return found; +} //------------------------------- bool wallet2::reset_history() { diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 1f863ae4..77fa9886 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -449,6 +449,11 @@ namespace tools currency::COMMAND_RPC_SCAN_POS::response rsp; currency::wide_difficulty_type basic_diff; currency::stake_modifier_type sm; + + bool zarcanum; + crypto::scalar_t last_pow_block_id_hashed; // Zarcanum notation: f' + + uint64_t iterations_processed; }; struct expiration_entry_info @@ -687,7 +692,8 @@ namespace tools bool check_connection(); // PoS mining - static bool do_pos_mining_iteration(mining_context& cxt, uint64_t ts, size_t pos_entry_index); + static void do_pos_mining_prepare_entry(mining_context& cxt, size_t pos_entry_index); + static bool do_pos_mining_iteration(mining_context& cxt, size_t pos_entry_index, uint64_t ts); template //do refresh as external callback static bool scan_pos(mining_context& cxt, std::atomic& stop, idle_condition_cb_t idle_condition_cb, const currency::core_runtime_config &runtime_config); bool fill_mining_context(mining_context& ctx); @@ -1294,41 +1300,6 @@ namespace tools return true; } - inline bool wallet2::do_pos_mining_iteration(mining_context& cxt, uint64_t ts, size_t pos_entry_index) - { - currency::stake_kernel sk = AUTO_VAL_INIT(sk); - build_kernel(cxt.sp.pos_entries[pos_entry_index], cxt.sm, ts, sk); - - crypto::hash kernel_hash; - { - PROFILE_FUNC("calc_hash"); - kernel_hash = crypto::cn_fast_hash(&sk, sizeof(sk)); - } - - const uint64_t stake_amount = cxt.sp.pos_entries[pos_entry_index].amount; - currency::wide_difficulty_type final_diff = cxt.basic_diff / stake_amount; - - bool check_hash_res = false; - { - PROFILE_FUNC("check_hash"); - check_hash_res = currency::check_hash(kernel_hash, final_diff); - ++cxt.rsp.iterations_processed; - } - - if (check_hash_res) - { - LOG_PRINT_GREEN("Found kernel: amount: " << currency::print_money_brief(stake_amount) << ENDL - << "difficulty: " << cxt.basic_diff << ", final_diff: " << final_diff << ENDL - << "index: " << cxt.sp.pos_entries[pos_entry_index].index << ENDL - << "kernel info: " << ENDL - << print_stake_kernel_info(sk) << ENDL - << "kernel_hash(proof): " << kernel_hash, - LOG_LEVEL_0); - } - - return check_hash_res; - } - template //do refresh as external callback bool wallet2::scan_pos(mining_context& cxt, std::atomic& stop, @@ -1337,7 +1308,7 @@ namespace tools { cxt.rsp.status = API_RETURN_CODE_NOT_FOUND; uint64_t timstamp_last_idle_call = runtime_config.get_core_time(); - cxt.rsp.iterations_processed = 0; + cxt.iterations_processed = 0; uint64_t ts_from = cxt.rsp.starter_timestamp; // median ts of last BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW blocks ts_from = ts_from - (ts_from % POS_SCAN_STEP) + POS_SCAN_STEP; @@ -1369,6 +1340,8 @@ namespace tools } }; + do_pos_mining_prepare_entry(cxt, i); + while(step <= ts_window) { //check every WALLET_POS_MINT_CHECK_HEIGHT_INTERVAL seconds wheither top block changed, if so - break the loop @@ -1394,11 +1367,8 @@ namespace tools if (stop) return false; - if (do_pos_mining_iteration(cxt, ts, i)) + if (do_pos_mining_iteration(cxt, i, ts)) { - //found kernel - cxt.rsp.index = i; - cxt.rsp.block_timestamp = ts; cxt.rsp.status = API_RETURN_CODE_OK; return true; } diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index 4b06ef96..266e00af 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -2005,7 +2005,7 @@ void wallets_manager::wallet_vs_options::worker_func() { w->get()->build_minted_block(ctx.sp, ctx.rsp); } - LOG_PRINT_L1(get_log_prefix() << " PoS mining iteration finished, status: " << ctx.rsp.status << ", used " << ctx.sp.pos_entries.size() << " entries with total amount: " << currency::print_money_brief(pos_entries_amount) << ", processed: " << ctx.rsp.iterations_processed << " iter."); + LOG_PRINT_L1(get_log_prefix() << " PoS mining iteration finished, status: " << ctx.rsp.status << ", used " << ctx.sp.pos_entries.size() << " entries with total amount: " << currency::print_money_brief(pos_entries_amount) << ", processed: " << ctx.iterations_processed << " iter."); return true; }); }