1
0
Fork 0
forked from lthn/blockchain

wallet: Zarcanum PoS (work in progress, scan_pos refactoring)

This commit is contained in:
sowle 2022-08-29 23:00:34 +02:00
parent 6b85159119
commit bc88d0d642
No known key found for this signature in database
GPG key ID: C07A24B2D89D49FC
4 changed files with 77 additions and 46 deletions

View file

@ -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()

View file

@ -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()
{

View file

@ -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<typename idle_condition_cb_t> //do refresh as external callback
static bool scan_pos(mining_context& cxt, std::atomic<bool>& 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<typename idle_condition_cb_t> //do refresh as external callback
bool wallet2::scan_pos(mining_context& cxt,
std::atomic<bool>& 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;
}

View file

@ -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;
});
}