forked from lthn/blockchain
wallet: global PoS / pos entries refactoring and code clean-up.
This commit is contained in:
parent
9215afb462
commit
27e695d4f1
11 changed files with 175 additions and 119 deletions
|
|
@ -964,10 +964,14 @@ namespace currency
|
|||
struct pos_entry
|
||||
{
|
||||
uint64_t amount;
|
||||
uint64_t index;
|
||||
uint64_t index; // global output index. TODO: remove, use tx_id + tx_out_index to get gindex in construct_miner_tx
|
||||
crypto::key_image keyimage;
|
||||
uint64_t block_timestamp;
|
||||
uint64_t stake_unlock_time;
|
||||
|
||||
crypto::hash tx_id; // stake output source tx id
|
||||
uint64_t tx_out_index; // stake output local index in its tx
|
||||
|
||||
//not for serialization
|
||||
uint64_t wallet_index;
|
||||
|
||||
|
|
@ -977,6 +981,8 @@ namespace currency
|
|||
KV_SERIALIZE(stake_unlock_time)
|
||||
KV_SERIALIZE(block_timestamp)
|
||||
KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE(keyimage)
|
||||
KV_SERIALIZE(tx_id)
|
||||
KV_SERIALIZE(tx_out_index)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -277,9 +277,14 @@ namespace currency
|
|||
|
||||
if (pos)
|
||||
{
|
||||
// TODO: add Zarcanum part
|
||||
|
||||
txin_to_key posin;
|
||||
posin.amount = pe.amount;
|
||||
|
||||
// TODO: using pe.index is deprecated, get input's global index by pe.tx_id and pe.tx_out_index
|
||||
posin.key_offsets.push_back(pe.index);
|
||||
|
||||
posin.k_image = pe.keyimage;
|
||||
tx.vin.push_back(posin);
|
||||
//reserve place for ring signature
|
||||
|
|
|
|||
|
|
@ -3471,7 +3471,7 @@ bool wallet2::get_transfer_address(const std::string& adr_str, currency::account
|
|||
return m_core_proxy->get_transfer_address(adr_str, addr, payment_id);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::is_transfer_okay_for_pos(const transfer_details& tr, uint64_t& stake_unlock_time)
|
||||
bool wallet2::is_transfer_okay_for_pos(const transfer_details& tr, uint64_t& stake_unlock_time) const
|
||||
{
|
||||
if (!tr.is_spendable())
|
||||
return false;
|
||||
|
|
@ -3505,7 +3505,25 @@ void wallet2::get_mining_history(wallet_public::mining_history& hist, uint64_t t
|
|||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::get_pos_entries(currency::COMMAND_RPC_SCAN_POS::request& req)
|
||||
size_t wallet2::get_pos_entries_count()
|
||||
{
|
||||
size_t counter = 0;
|
||||
|
||||
for (size_t i = 0, size = m_transfers.size(); i < size; i++)
|
||||
{
|
||||
auto& tr = m_transfers[i];
|
||||
|
||||
uint64_t stake_unlock_time = 0;
|
||||
if (!is_transfer_okay_for_pos(tr, stake_unlock_time))
|
||||
continue;
|
||||
|
||||
++counter;
|
||||
}
|
||||
|
||||
return counter;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::get_pos_entries(std::vector<currency::pos_entry>& entries)
|
||||
{
|
||||
for (size_t i = 0; i != m_transfers.size(); i++)
|
||||
{
|
||||
|
|
@ -3515,23 +3533,24 @@ bool wallet2::get_pos_entries(currency::COMMAND_RPC_SCAN_POS::request& req)
|
|||
if (!is_transfer_okay_for_pos(tr, stake_unlock_time))
|
||||
continue;
|
||||
|
||||
if (tr.m_global_output_index == WALLET_GLOBAL_OUTPUT_INDEX_UNDEFINED)
|
||||
{
|
||||
//TODO: this code needed mostly for coretests, since in real life cases only mobile wallet supposed to
|
||||
// have WALLET_GLOBAL_OUTPUT_INDEX_UNDEFINED, and mobile wallet is not supposed to do PoS mining
|
||||
std::vector<uint64_t> indicies; indicies.push_back(i);
|
||||
prefetch_global_indicies_if_needed(indicies);
|
||||
}
|
||||
//WLT_CHECK_AND_ASSERT_MES(tr.m_global_output_index != WALLET_GLOBAL_OUTPUT_INDEX_UNDEFINED, false, "Wrong output input in transaction");
|
||||
// We don't need to prefetch PoS outputs anymore as gindex in not required and fetched in construct_miner_tx
|
||||
// I commented this out, CZ, please, review this change -- sowle
|
||||
//if (tr.m_global_output_index == WALLET_GLOBAL_OUTPUT_INDEX_UNDEFINED)
|
||||
//{
|
||||
// //TODO: this code needed mostly for coretests, since in real life cases only mobile wallet supposed to
|
||||
// // have WALLET_GLOBAL_OUTPUT_INDEX_UNDEFINED, and mobile wallet is not supposed to do PoS mining
|
||||
// std::vector<uint64_t> indicies; indicies.push_back(i);
|
||||
// prefetch_global_indicies_if_needed(indicies);
|
||||
//}
|
||||
|
||||
currency::pos_entry pe = AUTO_VAL_INIT(pe);
|
||||
pos_entry pe = AUTO_VAL_INIT(pe);
|
||||
pe.amount = tr.amount();
|
||||
pe.index = tr.m_global_output_index;
|
||||
pe.keyimage = tr.m_key_image;
|
||||
pe.wallet_index = i;
|
||||
pe.stake_unlock_time = stake_unlock_time;
|
||||
pe.block_timestamp = tr.m_ptx_wallet_info->m_block_timestamp;
|
||||
req.pos_entries.push_back(pe);
|
||||
entries.push_back(pe);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -3544,24 +3563,19 @@ bool wallet2::is_in_hardfork_zone(uint64_t hardfork_index)
|
|||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::prepare_and_sign_pos_block(currency::block& b,
|
||||
const currency::pos_entry& pos_info,
|
||||
const pos_entry& pos_info,
|
||||
const crypto::public_key& source_tx_pub_key,
|
||||
uint64_t in_tx_output_index,
|
||||
const std::vector<const crypto::public_key*>& keys_ptrs)
|
||||
{
|
||||
//generate coinbase transaction
|
||||
WLT_CHECK_AND_ASSERT_MES(b.miner_tx.vin[0].type() == typeid(currency::txin_gen), false, "Wrong output input in transaction");
|
||||
WLT_CHECK_AND_ASSERT_MES(b.miner_tx.vin[1].type() == typeid(currency::txin_to_key), false, "Wrong output input in transaction");
|
||||
auto& txin = boost::get<currency::txin_to_key>(b.miner_tx.vin[1]);
|
||||
txin.k_image = pos_info.keyimage;
|
||||
if (!is_in_hardfork_zone(ZANO_HARDFORK_04_ZARCANUM))
|
||||
{
|
||||
// old PoS with non-hidden amounts
|
||||
WLT_CHECK_AND_ASSERT_MES(b.miner_tx.vin[0].type() == typeid(currency::txin_gen), false, "Wrong input 0 type in transaction: " << b.miner_tx.vin[0].type().name());
|
||||
WLT_CHECK_AND_ASSERT_MES(b.miner_tx.vin[1].type() == typeid(currency::txin_to_key), false, "Wrong input 1 type in transaction: " << b.miner_tx.vin[1].type().name());
|
||||
auto& txin = boost::get<currency::txin_to_key>(b.miner_tx.vin[1]);
|
||||
txin.k_image = pos_info.keyimage;
|
||||
|
||||
if (is_in_hardfork_zone(ZANO_HARDFORK_04_ZARCANUM))
|
||||
{
|
||||
//@#@ TODO: add proper support of Zarcanum
|
||||
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(false, "ZRCANUM BLOCKS NOT IMPLEMENTED YET");
|
||||
return false; // to get rid of warning
|
||||
}else
|
||||
{
|
||||
WLT_CHECK_AND_ASSERT_MES(b.miner_tx.signatures.size() == 1 &&
|
||||
b.miner_tx.signatures[0].type() == typeid(NLSAG_sig) &&
|
||||
boost::get<NLSAG_sig>(b.miner_tx.signatures[0]).s.size() == txin.key_offsets.size(),
|
||||
|
|
@ -3601,6 +3615,10 @@ bool wallet2::prepare_and_sign_pos_block(currency::block& b,
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Zarcanum
|
||||
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(false, "ZRCANUM BLOCKS NOT IMPLEMENTED YET");
|
||||
return false; // to get rid of warning
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool wallet2::build_kernel(const pos_entry& pe, const stake_modifier_type& stake_modifier, const uint64_t timestamp, stake_kernel& kernel)
|
||||
|
|
@ -3615,17 +3633,7 @@ bool wallet2::build_kernel(const pos_entry& pe, const stake_modifier_type& stake
|
|||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::fill_mining_context(mining_context& ctx)
|
||||
{
|
||||
// #ifdef _DEBUG
|
||||
// currency::COMMAND_RPC_GETBLOCKTEMPLATE::request tmpl_req = AUTO_VAL_INIT(tmpl_req);
|
||||
// currency::COMMAND_RPC_GETBLOCKTEMPLATE::response tmpl_rsp = AUTO_VAL_INIT(tmpl_rsp);
|
||||
// tmpl_req.wallet_address = m_account.get_public_address_str();
|
||||
// tmpl_req.pos_block = true;
|
||||
// m_core_proxy->call_COMMAND_RPC_GETBLOCKTEMPLATE(tmpl_req, tmpl_rsp);
|
||||
// #endif
|
||||
|
||||
|
||||
|
||||
bool r = get_pos_entries(ctx.sp);
|
||||
bool r = get_pos_entries(ctx.sp.pos_entries); // TODO: Remove this call. Transfers are filtered in scan_pos
|
||||
WLT_CHECK_AND_ASSERT_MES(r, false, "Failed to get_pos_entries()");
|
||||
|
||||
currency::COMMAND_RPC_GET_POS_MINING_DETAILS::request pos_details_req = AUTO_VAL_INIT(pos_details_req);
|
||||
|
|
@ -3685,7 +3693,7 @@ bool wallet2::try_mint_pos(const currency::account_public_address& miner_address
|
|||
|
||||
if (ctx.rsp.status == API_RETURN_CODE_OK)
|
||||
{
|
||||
build_minted_block(ctx.sp, ctx.rsp, miner_address);
|
||||
build_minted_block(ctx, miner_address);
|
||||
}
|
||||
|
||||
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));
|
||||
|
|
@ -3693,7 +3701,7 @@ bool wallet2::try_mint_pos(const currency::account_public_address& miner_address
|
|||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
void wallet2::do_pos_mining_prepare_entry(mining_context& cxt, size_t pos_entry_index)
|
||||
void wallet2::do_pos_mining_prepare_entry(mining_context& cxt, size_t transfer_index)
|
||||
{
|
||||
if (cxt.zarcanum)
|
||||
{
|
||||
|
|
@ -3703,22 +3711,30 @@ void wallet2::do_pos_mining_prepare_entry(mining_context& cxt, size_t pos_entry_
|
|||
}
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool wallet2::do_pos_mining_iteration(mining_context& cxt, size_t pos_entry_index, uint64_t ts)
|
||||
bool wallet2::do_pos_mining_iteration(mining_context& cxt, size_t transfer_index, uint64_t ts)
|
||||
{
|
||||
CHECK_AND_NO_ASSERT_MES(transfer_index < m_transfers.size(), false, "transfer_index is out of bounds: " << transfer_index);
|
||||
const transfer_details& td = m_transfers[transfer_index];
|
||||
|
||||
// build kernel
|
||||
currency::stake_kernel sk = AUTO_VAL_INIT(sk);
|
||||
build_kernel(cxt.sp.pos_entries[pos_entry_index], cxt.sm, ts, sk);
|
||||
|
||||
sk.kimage = td.m_key_image;
|
||||
sk.stake_modifier = cxt.sm;
|
||||
sk.block_timestamp = ts;
|
||||
|
||||
// calculate kernel hash
|
||||
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;
|
||||
const uint64_t stake_amount = td.amount();
|
||||
bool found = false;
|
||||
|
||||
if (cxt.zarcanum)
|
||||
{
|
||||
// TODO @#@#
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -3731,12 +3747,12 @@ bool wallet2::do_pos_mining_iteration(mining_context& cxt, size_t pos_entry_inde
|
|||
}
|
||||
if (found)
|
||||
{
|
||||
cxt.rsp.index = pos_entry_index;
|
||||
//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
|
||||
<< "index: " << td.m_global_output_index << ENDL
|
||||
<< "kernel info: " << ENDL
|
||||
<< print_stake_kernel_info(sk) << ENDL
|
||||
<< "kernel_hash(proof): " << kernel_hash,
|
||||
|
|
@ -3759,32 +3775,35 @@ bool wallet2::reset_history()
|
|||
return true;
|
||||
}
|
||||
//-------------------------------
|
||||
bool wallet2::build_minted_block(const currency::COMMAND_RPC_SCAN_POS::request& req,
|
||||
const currency::COMMAND_RPC_SCAN_POS::response& rsp,
|
||||
bool wallet2::build_minted_block(const mining_context& cxt,
|
||||
uint64_t new_block_expected_height /* = UINT64_MAX */)
|
||||
{
|
||||
return build_minted_block(req, rsp, m_account.get_public_address(), new_block_expected_height);
|
||||
return build_minted_block(cxt, m_account.get_public_address(), new_block_expected_height);
|
||||
}
|
||||
|
||||
bool wallet2::build_minted_block(const currency::COMMAND_RPC_SCAN_POS::request& req,
|
||||
const currency::COMMAND_RPC_SCAN_POS::response& rsp,
|
||||
bool wallet2::build_minted_block(const mining_context& cxt,
|
||||
const currency::account_public_address& miner_address,
|
||||
uint64_t new_block_expected_height /* UINT64_MAX */)
|
||||
{
|
||||
//found a block, construct it, sign and push to daemon
|
||||
WLT_LOG_GREEN("Found kernel, constructing block", LOG_LEVEL_0);
|
||||
|
||||
CHECK_AND_NO_ASSERT_MES(rsp.index < req.pos_entries.size(), false, "call_COMMAND_RPC_SCAN_POS returned wrong index: " << rsp.index << ", expected less then " << req.pos_entries.size());
|
||||
CHECK_AND_NO_ASSERT_MES(cxt.rsp.index < cxt.sp.pos_entries.size(), false, "call_COMMAND_RPC_SCAN_POS returned wrong index: " << cxt.rsp.index << ", expected less then " << cxt.sp.pos_entries.size());
|
||||
|
||||
const pos_entry& pe = cxt.sp.pos_entries[cxt.rsp.index];
|
||||
|
||||
currency::COMMAND_RPC_GETBLOCKTEMPLATE::request tmpl_req = AUTO_VAL_INIT(tmpl_req);
|
||||
currency::COMMAND_RPC_GETBLOCKTEMPLATE::response tmpl_rsp = AUTO_VAL_INIT(tmpl_rsp);
|
||||
tmpl_req.wallet_address = get_account_address_as_str(miner_address);
|
||||
tmpl_req.stakeholder_address = get_account_address_as_str(m_account.get_public_address());
|
||||
tmpl_req.pos_block = true;
|
||||
tmpl_req.pos_amount = req.pos_entries[rsp.index].amount;
|
||||
tmpl_req.pos_index = req.pos_entries[rsp.index].index;
|
||||
tmpl_req.pos_amount = pe.amount;
|
||||
|
||||
tmpl_req.pos_index = pe.index; // gindex <--- this should be removed as soon as pos_entry::index is replaced with tx_id and tx_out_index
|
||||
// TODO: also fill out tx_id and tx_out_index for mining tx creation
|
||||
|
||||
tmpl_req.extra_text = m_miner_text_info;
|
||||
tmpl_req.stake_unlock_time = req.pos_entries[rsp.index].stake_unlock_time;
|
||||
tmpl_req.stake_unlock_time = pe.stake_unlock_time;
|
||||
//generate packing tx
|
||||
transaction pack_tx = AUTO_VAL_INIT(pack_tx);
|
||||
if (generate_packing_transaction_if_needed(pack_tx, 0))
|
||||
|
|
@ -3802,38 +3821,38 @@ bool wallet2::build_minted_block(const currency::COMMAND_RPC_SCAN_POS::request&
|
|||
res = parse_and_validate_block_from_blob(block_blob, b);
|
||||
WLT_CHECK_AND_ASSERT_MES(res, false, "Failed to create block template after kernel hash found!");
|
||||
|
||||
if (rsp.last_block_hash != b.prev_id)
|
||||
if (cxt.rsp.last_block_hash != b.prev_id)
|
||||
{
|
||||
WLT_LOG_YELLOW("Kernel was found but block is behindhand, b.prev_id=" << b.prev_id << ", last_block_hash=" << rsp.last_block_hash, LOG_LEVEL_0);
|
||||
WLT_LOG_YELLOW("Kernel was found but block is behindhand, b.prev_id=" << b.prev_id << ", last_block_hash=" << cxt.rsp.last_block_hash, LOG_LEVEL_0);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<const crypto::public_key*> keys_ptrs;
|
||||
WLT_CHECK_AND_ASSERT_MES(req.pos_entries[rsp.index].wallet_index < m_transfers.size(),
|
||||
WLT_CHECK_AND_ASSERT_MES(pe.wallet_index < m_transfers.size(),
|
||||
false, "Wrong wallet_index at generating coinbase transacton");
|
||||
|
||||
if (m_transfers[req.pos_entries[rsp.index].wallet_index].m_ptx_wallet_info->m_tx.vout[m_transfers[req.pos_entries[rsp.index].wallet_index].m_internal_output_index].type() != typeid(tx_out_bare))
|
||||
if (m_transfers[pe.wallet_index].m_ptx_wallet_info->m_tx.vout[m_transfers[pe.wallet_index].m_internal_output_index].type() != typeid(tx_out_bare))
|
||||
{
|
||||
//@#@ review zarcanum here
|
||||
return false;
|
||||
}
|
||||
const auto& target = boost::get<tx_out_bare>(m_transfers[req.pos_entries[rsp.index].wallet_index].m_ptx_wallet_info->m_tx.vout[m_transfers[req.pos_entries[rsp.index].wallet_index].m_internal_output_index]).target;
|
||||
const auto& target = boost::get<tx_out_bare>(m_transfers[pe.wallet_index].m_ptx_wallet_info->m_tx.vout[m_transfers[pe.wallet_index].m_internal_output_index]).target;
|
||||
WLT_CHECK_AND_ASSERT_MES(target.type() == typeid(currency::txout_to_key), false, "wrong type_id in source transaction in coinbase tx");
|
||||
|
||||
const currency::txout_to_key& txtokey = boost::get<currency::txout_to_key>(target);
|
||||
keys_ptrs.push_back(&txtokey.key);
|
||||
|
||||
// set a real timestamp
|
||||
b.timestamp = rsp.block_timestamp;
|
||||
b.timestamp = cxt.rsp.block_timestamp;
|
||||
uint64_t current_timestamp = m_core_runtime_config.get_core_time();
|
||||
set_block_datetime(current_timestamp, b);
|
||||
WLT_LOG_MAGENTA("Applying actual timestamp: " << current_timestamp, LOG_LEVEL_0);
|
||||
|
||||
//sign block
|
||||
res = prepare_and_sign_pos_block(b,
|
||||
req.pos_entries[rsp.index],
|
||||
get_tx_pub_key_from_extra(m_transfers[req.pos_entries[rsp.index].wallet_index].m_ptx_wallet_info->m_tx),
|
||||
m_transfers[req.pos_entries[rsp.index].wallet_index].m_internal_output_index,
|
||||
pe,
|
||||
get_tx_pub_key_from_extra(m_transfers[pe.wallet_index].m_ptx_wallet_info->m_tx),
|
||||
m_transfers[pe.wallet_index].m_internal_output_index,
|
||||
keys_ptrs);
|
||||
WLT_CHECK_AND_ASSERT_MES(res, false, "Failed to prepare_and_sign_pos_block");
|
||||
|
||||
|
|
|
|||
|
|
@ -341,6 +341,7 @@ namespace tools
|
|||
// END_SERIALIZE()
|
||||
// };
|
||||
|
||||
|
||||
class wallet2: public tools::tor::t_transport_state_notifier
|
||||
{
|
||||
wallet2(const wallet2&) = delete;
|
||||
|
|
@ -445,8 +446,40 @@ namespace tools
|
|||
|
||||
struct mining_context
|
||||
{
|
||||
currency::COMMAND_RPC_SCAN_POS::request sp;
|
||||
currency::COMMAND_RPC_SCAN_POS::response rsp;
|
||||
// from struct COMMAND_RPC_SCAN_POS
|
||||
struct request_t
|
||||
{
|
||||
std::vector<currency::pos_entry> pos_entries;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(pos_entries)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct response_t
|
||||
{
|
||||
std::string status;
|
||||
uint64_t index; // index in pos_entries container
|
||||
uint64_t block_timestamp;
|
||||
uint64_t height;
|
||||
uint64_t starter_timestamp;
|
||||
crypto::hash last_block_hash;
|
||||
bool is_pos_allowed;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(index)
|
||||
KV_SERIALIZE(block_timestamp)
|
||||
KV_SERIALIZE(height)
|
||||
KV_SERIALIZE(is_pos_allowed)
|
||||
KV_SERIALIZE(starter_timestamp)
|
||||
KV_SERIALIZE_VAL_POD_AS_BLOB(last_block_hash);
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
request_t sp;
|
||||
response_t rsp;
|
||||
|
||||
currency::wide_difficulty_type basic_diff;
|
||||
currency::stake_modifier_type sm;
|
||||
|
||||
|
|
@ -692,10 +725,10 @@ namespace tools
|
|||
bool check_connection();
|
||||
|
||||
// PoS mining
|
||||
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);
|
||||
void do_pos_mining_prepare_entry(mining_context& cxt, size_t transfer_index);
|
||||
bool do_pos_mining_iteration(mining_context& cxt, size_t transfer_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 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);
|
||||
|
||||
void get_transfers(wallet2::transfer_container& incoming_transfers) const;
|
||||
|
|
@ -846,9 +879,12 @@ namespace tools
|
|||
uint64_t height);
|
||||
void process_htlc_triggers_on_block_added(uint64_t height);
|
||||
void unprocess_htlc_triggers_on_block_removed(uint64_t height);
|
||||
bool get_pos_entries(currency::COMMAND_RPC_SCAN_POS::request& req);
|
||||
bool build_minted_block(const currency::COMMAND_RPC_SCAN_POS::request& req, const currency::COMMAND_RPC_SCAN_POS::response& rsp, uint64_t new_block_expected_height = UINT64_MAX);
|
||||
bool build_minted_block(const currency::COMMAND_RPC_SCAN_POS::request& req, const currency::COMMAND_RPC_SCAN_POS::response& rsp, const currency::account_public_address& miner_address, uint64_t new_block_expected_height = UINT64_MAX);
|
||||
|
||||
bool get_pos_entries(std::vector<currency::pos_entry>& entries); // TODO: make it const
|
||||
size_t get_pos_entries_count();
|
||||
|
||||
bool build_minted_block(const mining_context& cxt, uint64_t new_block_expected_height = UINT64_MAX);
|
||||
bool build_minted_block(const mining_context& cxt, const currency::account_public_address& miner_address, uint64_t new_block_expected_height = UINT64_MAX);
|
||||
bool reset_history();
|
||||
bool is_transfer_unlocked(const transfer_details& td) const;
|
||||
bool is_transfer_unlocked(const transfer_details& td, bool for_pos_mining, uint64_t& stake_lock_time) const;
|
||||
|
|
@ -965,7 +1001,7 @@ private:
|
|||
std::vector<std::string> get_aliases_for_address(const std::string& addr);
|
||||
static bool build_kernel(const currency::pos_entry& pe, const currency::stake_modifier_type& stake_modifier, const uint64_t timestamp, currency::stake_kernel& kernel);
|
||||
bool is_connected_to_net();
|
||||
bool is_transfer_okay_for_pos(const transfer_details& tr, uint64_t& stake_unlock_time);
|
||||
bool is_transfer_okay_for_pos(const transfer_details& tr, uint64_t& stake_unlock_time) const;
|
||||
bool scan_unconfirmed_outdate_tx();
|
||||
const currency::transaction& get_transaction_by_id(const crypto::hash& tx_hash);
|
||||
void rise_on_transfer2(const wallet_public::wallet_transfer_info& wti);
|
||||
|
|
@ -1319,8 +1355,15 @@ namespace tools
|
|||
ts_middle -= ts_middle % POS_SCAN_STEP;
|
||||
uint64_t ts_window = std::min(ts_middle - ts_from, ts_to - ts_middle);
|
||||
|
||||
for (size_t i = 0; i != cxt.sp.pos_entries.size(); i++)
|
||||
size_t pos_entry_index = 0;
|
||||
for (size_t transfer_index = 0; transfer_index != m_transfers.size(); transfer_index++)
|
||||
{
|
||||
auto& tr = m_transfers[transfer_index];
|
||||
|
||||
uint64_t stake_unlock_time = 0;
|
||||
if (!is_transfer_okay_for_pos(tr, stake_unlock_time))
|
||||
continue;
|
||||
|
||||
bool go_past = true;
|
||||
uint64_t step = 0;
|
||||
|
||||
|
|
@ -1340,7 +1383,7 @@ namespace tools
|
|||
}
|
||||
};
|
||||
|
||||
do_pos_mining_prepare_entry(cxt, i);
|
||||
do_pos_mining_prepare_entry(cxt, transfer_index);
|
||||
|
||||
while(step <= ts_window)
|
||||
{
|
||||
|
|
@ -1367,7 +1410,7 @@ namespace tools
|
|||
if (stop)
|
||||
return false;
|
||||
|
||||
if (do_pos_mining_iteration(cxt, i, ts))
|
||||
if (do_pos_mining_iteration(cxt, transfer_index, ts))
|
||||
{
|
||||
cxt.rsp.status = API_RETURN_CODE_OK;
|
||||
return true;
|
||||
|
|
@ -1375,6 +1418,7 @@ namespace tools
|
|||
|
||||
next_turn();
|
||||
}
|
||||
++pos_entry_index;
|
||||
}
|
||||
cxt.rsp.status = API_RETURN_CODE_NOT_FOUND;
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -1997,13 +1997,13 @@ void wallets_manager::wallet_vs_options::worker_func()
|
|||
for (auto& ent : ctx.sp.pos_entries)
|
||||
pos_entries_amount += ent.amount;
|
||||
|
||||
tools::wallet2::scan_pos(ctx, break_mining_loop, [this](){
|
||||
w->get()->scan_pos(ctx, break_mining_loop, [this](){
|
||||
return *plast_daemon_network_state == currency::COMMAND_RPC_GET_INFO::daemon_network_state_online && *plast_daemon_height == last_wallet_synch_height;
|
||||
}, core_conf);
|
||||
|
||||
if (ctx.rsp.status == API_RETURN_CODE_OK)
|
||||
{
|
||||
w->get()->build_minted_block(ctx.sp, ctx.rsp);
|
||||
w->get()->build_minted_block(ctx);
|
||||
}
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -547,23 +547,23 @@ bool test_generator::find_kernel(const std::list<currency::account_base>& accs,
|
|||
if (m_ignore_last_pow_in_wallets)
|
||||
w->m_last_pow_block_h = CURRENCY_MAX_BLOCK_NUMBER;
|
||||
|
||||
currency::COMMAND_RPC_SCAN_POS::request scan_pos_entries;
|
||||
bool r = w->get_pos_entries(scan_pos_entries);
|
||||
std::vector<currency::pos_entry> pos_entries;
|
||||
bool r = w->get_pos_entries(pos_entries);
|
||||
CHECK_AND_ASSERT_THROW_MES(r, "Failed to get_pos_entries");
|
||||
|
||||
for (size_t i = 0; i != scan_pos_entries.pos_entries.size(); i++)
|
||||
for (size_t i = 0; i != pos_entries.size(); i++)
|
||||
{
|
||||
|
||||
stake_kernel sk = AUTO_VAL_INIT(sk);
|
||||
build_kernel(scan_pos_entries.pos_entries[i].amount,
|
||||
scan_pos_entries.pos_entries[i].index,
|
||||
scan_pos_entries.pos_entries[i].keyimage,
|
||||
build_kernel(pos_entries[i].amount,
|
||||
pos_entries[i].index,
|
||||
pos_entries[i].keyimage,
|
||||
sk,
|
||||
blck_chain,
|
||||
indexes,
|
||||
ts);
|
||||
crypto::hash kernel_hash = crypto::cn_fast_hash(&sk, sizeof(sk));
|
||||
wide_difficulty_type this_coin_diff = basic_diff / scan_pos_entries.pos_entries[i].amount;
|
||||
wide_difficulty_type this_coin_diff = basic_diff / pos_entries[i].amount;
|
||||
if (!check_hash(kernel_hash, this_coin_diff))
|
||||
continue;
|
||||
else
|
||||
|
|
@ -581,11 +581,11 @@ bool test_generator::find_kernel(const std::list<currency::account_base>& accs,
|
|||
}
|
||||
|
||||
//found kernel
|
||||
LOG_PRINT_GREEN("Found kernel: amount=" << print_money(scan_pos_entries.pos_entries[i].amount)
|
||||
<< ", index=" << scan_pos_entries.pos_entries[i].index
|
||||
<< ", key_image" << scan_pos_entries.pos_entries[i].keyimage
|
||||
LOG_PRINT_GREEN("Found kernel: amount=" << print_money(pos_entries[i].amount)
|
||||
<< ", index=" << pos_entries[i].index
|
||||
<< ", key_image" << pos_entries[i].keyimage
|
||||
<< ", diff: " << this_coin_diff, LOG_LEVEL_0);
|
||||
pe = scan_pos_entries.pos_entries[i];
|
||||
pe = pos_entries[i];
|
||||
found_wallet_index = i;
|
||||
found_kh = kernel_hash;
|
||||
found_timestamp = ts;
|
||||
|
|
@ -715,11 +715,6 @@ bool test_generator::build_stake_modifier(stake_modifier_type& sm, const test_ge
|
|||
return true;
|
||||
}
|
||||
|
||||
bool test_generator::call_COMMAND_RPC_SCAN_POS(const currency::COMMAND_RPC_SCAN_POS::request& req, currency::COMMAND_RPC_SCAN_POS::response& rsp)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
currency::wide_difficulty_type test_generator::get_difficulty_for_next_block(const crypto::hash& head_id, bool pow) const
|
||||
{
|
||||
std::vector<const block_info*> blocks;
|
||||
|
|
|
|||
|
|
@ -389,9 +389,6 @@ public:
|
|||
|
||||
test_generator();
|
||||
|
||||
//----------- tools::i_core_proxy
|
||||
virtual bool call_COMMAND_RPC_SCAN_POS(const currency::COMMAND_RPC_SCAN_POS::request& req, currency::COMMAND_RPC_SCAN_POS::response& rsp);
|
||||
|
||||
//-----------
|
||||
currency::wide_difficulty_type get_difficulty_for_next_block(const std::vector<const block_info*>& blocks, bool pow = true) const;
|
||||
currency::wide_difficulty_type get_difficulty_for_next_block(const crypto::hash& head_id, bool pow = true) const;
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ inline bool mine_next_pos_block_in_playtime_with_wallet(tools::wallet2& w, const
|
|||
if (ctx.rsp.status != API_RETURN_CODE_OK)
|
||||
return false;
|
||||
|
||||
return w.build_minted_block(ctx.sp, ctx.rsp, miner_address);
|
||||
return w.build_minted_block(ctx, miner_address);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -231,7 +231,6 @@ bool pos_emission_test::c1(currency::core& c, size_t ev_index, const std::vector
|
|||
bool r = false;
|
||||
block b;
|
||||
wide_difficulty_type diff = 0;
|
||||
currency::COMMAND_RPC_SCAN_POS::request scan_pos_req = AUTO_VAL_INIT(scan_pos_req);
|
||||
bool switched_to_higher_stake_amount = false;
|
||||
size_t height_to_twice_stake_amount = 2000;
|
||||
|
||||
|
|
@ -291,9 +290,7 @@ bool pos_emission_test::c1(currency::core& c, size_t ev_index, const std::vector
|
|||
c.get_blockchain_storage().get_top_block(b);
|
||||
//int64_t pos_block_timediff = b.timestamp - last_pos_block_ts;
|
||||
uint64_t stake_amount = boost::get<txin_to_key>(b.miner_tx.vin[1]).amount;
|
||||
scan_pos_req.pos_entries.clear();
|
||||
alice_wlt->get_pos_entries(scan_pos_req);
|
||||
size_t pos_entries_count = scan_pos_req.pos_entries.size();
|
||||
size_t pos_entries_count = alice_wlt->get_pos_entries_count();
|
||||
//s << epee::misc_utils::get_time_str_v3(boost::posix_time::from_time_t(ts)) << "(" << ts << ")\t" << get_block_height(b) << "\tPoS\t" << b.timestamp << " (" << (pos_block_timediff > 0 ? "+" : "") << pos_block_timediff << ")\t" << diff << "\tstake: " << stake_amount << " balance: " << print_money(wallet_balance) << ", mined: " << print_money(wallet_balance_mined) << ENDL;
|
||||
LOG_PRINT2("pos_emission_test_brief.log", "\t" << get_block_height(b) << "\t" << diff << "\t" << print_money(stake_amount) << "\t" << print_money(wallet_balance) << "\t" << pos_entries_count, LOG_LEVEL_0);
|
||||
//last_pos_block_ts = b.timestamp;
|
||||
|
|
|
|||
|
|
@ -504,10 +504,10 @@ bool pos_wallet_minting_same_amount_diff_outs::prepare_wallets_0(currency::core&
|
|||
|
||||
// check pos entries actually available
|
||||
w.w->refresh();
|
||||
currency::COMMAND_RPC_SCAN_POS::request req = AUTO_VAL_INIT(req);
|
||||
r = w.w->get_pos_entries(req);
|
||||
std::vector<pos_entry> pos_entries;
|
||||
r = w.w->get_pos_entries(pos_entries);
|
||||
CHECK_AND_ASSERT_MES(r, false, "get_pos_entries failed");
|
||||
CHECK_AND_ASSERT_MES(req.pos_entries.size() == w.pos_entries_count, false, "incorrect pos entries count in the wallet: " << req.pos_entries.size() << ", expected: " << w.pos_entries_count);
|
||||
CHECK_AND_ASSERT_MES(pos_entries.size() == w.pos_entries_count, false, "incorrect pos entries count in the wallet: " << pos_entries.size() << ", expected: " << w.pos_entries_count);
|
||||
uint64_t balance_unlocked = 0;
|
||||
w.w->balance(balance_unlocked);
|
||||
CHECK_AND_ASSERT_MES(balance_unlocked == m_wallet_stake_amount, false, "incorrect wallet unlocked balance: " << print_money(balance_unlocked) << ", expected: " << print_money(m_wallet_stake_amount));
|
||||
|
|
@ -515,13 +515,13 @@ bool pos_wallet_minting_same_amount_diff_outs::prepare_wallets_0(currency::core&
|
|||
// make sure all wallets has the same distribution of pos_entries
|
||||
if (i == 0)
|
||||
{
|
||||
first_wallet_pos_entries = req.pos_entries;
|
||||
first_wallet_pos_entries = pos_entries;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(size_t i = 0; i < pos_amounts.size(); ++i)
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(req.pos_entries[i].amount == first_wallet_pos_entries[i].amount, false, "Wallet pos entry #" << i << " has incorrect amount: " << print_money(req.pos_entries[i].amount) << ", expected (as in 1st wallet): " << print_money(first_wallet_pos_entries[i].amount));
|
||||
CHECK_AND_ASSERT_MES(pos_entries[i].amount == first_wallet_pos_entries[i].amount, false, "Wallet pos entry #" << i << " has incorrect amount: " << print_money(pos_entries[i].amount) << ", expected (as in 1st wallet): " << print_money(first_wallet_pos_entries[i].amount));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -561,10 +561,8 @@ bool pos_wallet_minting_same_amount_diff_outs::prepare_wallets_1(currency::core&
|
|||
|
||||
// check pos entries actually available
|
||||
w.w->refresh();
|
||||
currency::COMMAND_RPC_SCAN_POS::request req = AUTO_VAL_INIT(req);
|
||||
r = w.w->get_pos_entries(req);
|
||||
CHECK_AND_ASSERT_MES(r, false, "get_pos_entries failed");
|
||||
CHECK_AND_ASSERT_MES(req.pos_entries.size() == w.pos_entries_count, false, "incorrect pos entries count in the wallet: " << req.pos_entries.size() << ", expected: " << w.pos_entries_count);
|
||||
size_t pos_entries_count = w.w->get_pos_entries_count();
|
||||
CHECK_AND_ASSERT_MES(pos_entries_count == w.pos_entries_count, false, "incorrect pos entries count in the wallet: " << pos_entries_count << ", expected: " << w.pos_entries_count);
|
||||
uint64_t balance_unlocked = 0;
|
||||
w.w->balance(balance_unlocked);
|
||||
CHECK_AND_ASSERT_MES(balance_unlocked == m_wallet_stake_amount, false, "incorrect wallet unlocked balance: " << print_money(balance_unlocked) << ", expected: " << print_money(m_wallet_stake_amount));
|
||||
|
|
|
|||
|
|
@ -2461,9 +2461,8 @@ bool gen_wallet_selecting_pos_entries::c1(currency::core& c, size_t ev_index, co
|
|||
CHECK_AND_ASSERT_MES(blocks_fetched == CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 3 + 1 + WALLET_DEFAULT_TX_SPENDABLE_AGE - 2, false, "Incorrect numbers of blocks fetched");
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool");
|
||||
|
||||
currency::COMMAND_RPC_SCAN_POS::request req = AUTO_VAL_INIT(req);
|
||||
bool r = alice_wlt->get_pos_entries(req);
|
||||
CHECK_AND_ASSERT_MES(req.pos_entries.empty(), false, "Incorrect return value and pos_entries size");
|
||||
bool r = false;
|
||||
CHECK_AND_ASSERT_MES(alice_wlt->get_pos_entries_count() == 0, false, "Incorrect return value and pos_entries size");
|
||||
|
||||
tools::wallet2::mining_context ctx = AUTO_VAL_INIT(ctx);
|
||||
r = alice_wlt->fill_mining_context(ctx); // should internally fail because there's no unlocked money to be used as pos entries
|
||||
|
|
@ -2481,9 +2480,7 @@ bool gen_wallet_selecting_pos_entries::c1(currency::core& c, size_t ev_index, co
|
|||
alice_wlt->refresh(blocks_fetched, received_money, atomic_false);
|
||||
CHECK_AND_ASSERT_MES(blocks_fetched == 1, false, "Incorrect number of blocks fetched");
|
||||
|
||||
req = AUTO_VAL_INIT(req);
|
||||
r = alice_wlt->get_pos_entries(req);
|
||||
CHECK_AND_ASSERT_MES(req.pos_entries.size() == 3, false, "Incorrect return value and pos_entries size");
|
||||
CHECK_AND_ASSERT_MES(alice_wlt->get_pos_entries_count() == 3, false, "Incorrect return value and pos_entries size");
|
||||
|
||||
r = alice_wlt->try_mint_pos(); // should really mine a block
|
||||
CHECK_AND_ASSERT_MES(r, false, "try_mint_pos returns false");
|
||||
|
|
@ -2506,9 +2503,7 @@ bool gen_wallet_selecting_pos_entries::c1(currency::core& c, size_t ev_index, co
|
|||
CHECK_AND_ASSERT_MES(blocks_fetched == 1, false, "Incorrect number of blocks fetched");
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool");
|
||||
|
||||
req = AUTO_VAL_INIT(req);
|
||||
r = alice_wlt->get_pos_entries(req);
|
||||
CHECK_AND_ASSERT_MES(req.pos_entries.size() == 0, false, "Incorrect return value and pos_entries size");
|
||||
CHECK_AND_ASSERT_MES(alice_wlt->get_pos_entries_count() == 0, false, "Incorrect return value and pos_entries size");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue