forked from lthn/blockchain
wallet2::prepare_and_sign_pos_block() and COMMAND_RPC_GETBLOCKTEMPLATE refactored
This commit is contained in:
parent
642cc94691
commit
f0bbcb5f40
5 changed files with 65 additions and 71 deletions
|
|
@ -833,11 +833,7 @@ namespace currency
|
|||
params.stakeholder_address = stakeholder_address;
|
||||
params.ex_nonce = req.extra_text;
|
||||
params.pos = req.pos_block;
|
||||
params.pe.amount = req.pos_amount;
|
||||
params.pe.g_index = req.pos_g_index;
|
||||
params.pe.tx_id = req.tx_id;
|
||||
params.pe.tx_out_index = req.tx_out_index;
|
||||
params.pe.stake_unlock_time = req.stake_unlock_time;
|
||||
params.pe = req.pe;
|
||||
//params.pe.keyimage key image will be set in the wallet
|
||||
//params.pe.wallet_index is not included in serialization map, TODO: refactoring here
|
||||
params.pcustom_fill_block_template_func = nullptr;
|
||||
|
|
|
|||
|
|
@ -803,11 +803,13 @@ namespace currency
|
|||
std::string wallet_address;
|
||||
std::string stakeholder_address;
|
||||
bool pos_block; //is pos block
|
||||
uint64_t pos_amount; //do we still need it?
|
||||
uint64_t pos_g_index; //
|
||||
crypto::hash tx_id;
|
||||
uint64_t tx_out_index;
|
||||
uint64_t stake_unlock_time;
|
||||
//uint64_t pos_amount; //do we still need it?
|
||||
//uint64_t pos_g_index; //
|
||||
//crypto::hash tx_id;
|
||||
//uint64_t tx_out_index;
|
||||
//uint64_t stake_unlock_time;
|
||||
|
||||
pos_entry pe; // for making PoS blocks
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE_BLOB_AS_HEX_STRING(explicit_transaction)
|
||||
|
|
@ -815,11 +817,12 @@ namespace currency
|
|||
KV_SERIALIZE(wallet_address)
|
||||
KV_SERIALIZE(stakeholder_address);
|
||||
KV_SERIALIZE(pos_block)
|
||||
KV_SERIALIZE(pos_amount)
|
||||
KV_SERIALIZE(pos_g_index)
|
||||
KV_SERIALIZE_POD_AS_HEX_STRING(tx_id)
|
||||
KV_SERIALIZE(tx_out_index)
|
||||
KV_SERIALIZE(stake_unlock_time)
|
||||
//KV_SERIALIZE(pos_amount)
|
||||
//KV_SERIALIZE(pos_g_index)
|
||||
//KV_SERIALIZE_POD_AS_HEX_STRING(tx_id)
|
||||
//KV_SERIALIZE(tx_out_index)
|
||||
//KV_SERIALIZE(stake_unlock_time)
|
||||
KV_SERIALIZE(pe)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -3594,45 +3594,50 @@ bool wallet2::is_in_hardfork_zone(uint64_t hardfork_index) const
|
|||
return m_core_runtime_config.is_hardfork_active_for_height(hardfork_index, get_blockchain_current_size());
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::prepare_and_sign_pos_block(currency::block& b,
|
||||
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)
|
||||
bool wallet2::prepare_and_sign_pos_block(currency::block& b, const pos_entry& pe) const
|
||||
{
|
||||
WLT_CHECK_AND_ASSERT_MES(pe.wallet_index < m_transfers.size(), false, "invalid pe.wallet_index: " << pe.wallet_index);
|
||||
const transaction& source_tx = m_transfers[pe.wallet_index].m_ptx_wallet_info->m_tx;
|
||||
|
||||
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;
|
||||
txin.k_image = pe.keyimage;
|
||||
|
||||
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(),
|
||||
false, "Wrong signatures amount in coinbase transacton");
|
||||
|
||||
|
||||
//derive secret key
|
||||
crypto::key_derivation pos_coin_derivation = AUTO_VAL_INIT(pos_coin_derivation);
|
||||
bool r = crypto::generate_key_derivation(source_tx_pub_key,
|
||||
bool r = crypto::generate_key_derivation(get_tx_pub_key_from_extra(source_tx),
|
||||
m_account.get_keys().view_secret_key,
|
||||
pos_coin_derivation);
|
||||
|
||||
WLT_CHECK_AND_ASSERT_MES(r, false, "internal error: pos coin base generator: failed to generate_key_derivation("
|
||||
<< source_tx_pub_key
|
||||
<< pe.tx_id
|
||||
<< ", view secret key: " << m_account.get_keys().view_secret_key << ")");
|
||||
|
||||
crypto::secret_key derived_secret_ephemeral_key = AUTO_VAL_INIT(derived_secret_ephemeral_key);
|
||||
crypto::derive_secret_key(pos_coin_derivation,
|
||||
in_tx_output_index,
|
||||
pe.tx_out_index,
|
||||
m_account.get_keys().spend_secret_key,
|
||||
derived_secret_ephemeral_key);
|
||||
|
||||
// sign block actually in coinbase transaction
|
||||
crypto::hash block_hash = currency::get_block_hash(b);
|
||||
|
||||
// get stake output pub key (stealth address) for ring signature generation
|
||||
std::vector<const crypto::public_key*> keys_ptrs;
|
||||
TRY_ENTRY()
|
||||
const currency::tx_out_v& stake_out_v = source_tx.vout[pe.tx_out_index];
|
||||
keys_ptrs.push_back(&boost::get<currency::txout_to_key>(boost::get<tx_out_bare>(stake_out_v).target).key);
|
||||
CATCH_ENTRY_CUSTOM("wallet2::prepare_and_sign_pos_block", { LOG_PRINT_RED_L0("unable to get output's pub key because of the exception"); }, false);
|
||||
|
||||
crypto::generate_ring_signature(block_hash,
|
||||
txin.k_image,
|
||||
keys_ptrs,
|
||||
|
|
@ -3808,15 +3813,12 @@ bool wallet2::reset_history()
|
|||
return true;
|
||||
}
|
||||
//-------------------------------
|
||||
bool wallet2::build_minted_block(const mining_context& cxt,
|
||||
uint64_t new_block_expected_height /* = UINT64_MAX */)
|
||||
bool wallet2::build_minted_block(const mining_context& cxt)
|
||||
{
|
||||
return build_minted_block(cxt, m_account.get_public_address(), new_block_expected_height);
|
||||
return build_minted_block(cxt, m_account.get_public_address());
|
||||
}
|
||||
|
||||
bool wallet2::build_minted_block(const mining_context& cxt,
|
||||
const currency::account_public_address& miner_address,
|
||||
uint64_t new_block_expected_height /* UINT64_MAX */)
|
||||
bool wallet2::build_minted_block(const mining_context& cxt, const currency::account_public_address& miner_address)
|
||||
{
|
||||
//found a block, construct it, sign and push to daemon
|
||||
WLT_LOG_GREEN("Found kernel, constructing block", LOG_LEVEL_0);
|
||||
|
|
@ -3824,21 +3826,30 @@ bool wallet2::build_minted_block(const mining_context& cxt,
|
|||
WLT_CHECK_AND_ASSERT_MES(cxt.index < m_transfers.size(), false, "cxt.index = " << cxt.index << " is out of bounds");
|
||||
const transfer_details& td = m_transfers[cxt.index];
|
||||
|
||||
pos_entry pe = AUTO_VAL_INIT(pe);
|
||||
|
||||
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;
|
||||
pe.g_index = tmpl_req.pos_g_index = td.m_global_output_index;
|
||||
pe.amount = tmpl_req.pos_amount = td.amount();// pe.amount;
|
||||
pe.keyimage = td.m_key_image;
|
||||
pe.block_timestamp = td.m_ptx_wallet_info->m_block_timestamp;
|
||||
pe.stake_unlock_time = tmpl_req.stake_unlock_time = cxt.stake_unlock_time;
|
||||
pe.tx_id = tmpl_req.tx_id = td.tx_hash();
|
||||
pe.tx_out_index = tmpl_req.tx_out_index = td.m_internal_output_index;
|
||||
pe.wallet_index = cxt.index;
|
||||
|
||||
tmpl_req.pe = AUTO_VAL_INIT(tmpl_req.pe);
|
||||
tmpl_req.pe.amount = td.amount();
|
||||
tmpl_req.pe.block_timestamp = td.m_ptx_wallet_info->m_block_timestamp;
|
||||
tmpl_req.pe.g_index = td.m_global_output_index;
|
||||
tmpl_req.pe.keyimage = td.m_key_image;
|
||||
tmpl_req.pe.stake_unlock_time = cxt.stake_unlock_time;
|
||||
tmpl_req.pe.tx_id = td.tx_hash();
|
||||
tmpl_req.pe.tx_out_index = td.m_internal_output_index;
|
||||
tmpl_req.pe.wallet_index = cxt.index;
|
||||
|
||||
//pe.g_index = tmpl_req.pos_g_index = td.m_global_output_index;
|
||||
//pe.amount = tmpl_req.pos_amount = td.amount();// pe.amount;
|
||||
//pe.keyimage = td.m_key_image;
|
||||
//pe.block_timestamp = td.m_ptx_wallet_info->m_block_timestamp;
|
||||
//pe.stake_unlock_time = tmpl_req.stake_unlock_time = cxt.stake_unlock_time;
|
||||
//pe.tx_id = tmpl_req.tx_id = td.tx_hash();
|
||||
//pe.tx_out_index = tmpl_req.tx_out_index = td.m_internal_output_index;
|
||||
//pe.wallet_index = cxt.index;
|
||||
|
||||
//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
|
||||
|
|
@ -3856,9 +3867,9 @@ bool wallet2::build_minted_block(const mining_context& cxt,
|
|||
currency::block b = AUTO_VAL_INIT(b);
|
||||
currency::blobdata block_blob;
|
||||
bool res = epee::string_tools::parse_hexstr_to_binbuff(tmpl_rsp.blocktemplate_blob, block_blob);
|
||||
WLT_CHECK_AND_ASSERT_MES(res, false, "Failed to create block template after kernel hash found!");
|
||||
WLT_CHECK_AND_ASSERT_MES(res, false, "parse_hexstr_to_binbuff() failed after kernel hash found!");
|
||||
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!");
|
||||
WLT_CHECK_AND_ASSERT_MES(res, false, "parse_and_validate_block_from_blob() failed after kernel hash found!");
|
||||
|
||||
if (cxt.last_block_hash != b.prev_id)
|
||||
{
|
||||
|
|
@ -3883,19 +3894,7 @@ bool wallet2::build_minted_block(const mining_context& cxt,
|
|||
else
|
||||
{
|
||||
// old fashioned non-hidden amount PoS scheme
|
||||
const auto& target = boost::get<tx_out_bare>(stake_out_v).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& stake_out_to_key = boost::get<currency::txout_to_key>(target);
|
||||
std::vector<const crypto::public_key*> keys_ptrs;
|
||||
keys_ptrs.push_back(&stake_out_to_key.key);
|
||||
|
||||
|
||||
//sign block
|
||||
res = prepare_and_sign_pos_block(b,
|
||||
pe,
|
||||
get_tx_pub_key_from_extra(m_transfers[pe.wallet_index].m_ptx_wallet_info->m_tx),
|
||||
td.m_internal_output_index,
|
||||
keys_ptrs);
|
||||
res = prepare_and_sign_pos_block(b, tmpl_req.pe);
|
||||
WLT_CHECK_AND_ASSERT_MES(res, false, "Failed to prepare_and_sign_pos_block");
|
||||
}
|
||||
|
||||
|
|
@ -4784,8 +4783,10 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count, std::vector<currency
|
|||
if (td.m_global_output_index == daemon_oe.global_amount_index)
|
||||
continue;
|
||||
tx_output_entry oe = AUTO_VAL_INIT(oe);
|
||||
oe.out_reference = daemon_oe.global_amount_index;
|
||||
oe.stealth_address = daemon_oe.out_key;
|
||||
oe.amount_commitment = daemon_oe.amount_commitment;
|
||||
oe.concealing_point = daemon_oe.concealing_point;
|
||||
oe.out_reference = daemon_oe.global_amount_index;
|
||||
oe.stealth_address = daemon_oe.stealth_address;
|
||||
src.outputs.push_back(oe);
|
||||
if (src.outputs.size() >= fake_outputs_count)
|
||||
break;
|
||||
|
|
@ -6050,7 +6051,7 @@ void wallet2::sweep_below(size_t fake_outs_count, const currency::account_public
|
|||
continue;
|
||||
tx_output_entry oe = AUTO_VAL_INIT(oe);
|
||||
oe.out_reference = daemon_oe.global_amount_index;
|
||||
oe.stealth_address = daemon_oe.out_key;
|
||||
oe.stealth_address = daemon_oe.stealth_address;
|
||||
src.outputs.push_back(oe);
|
||||
if (src.outputs.size() >= fake_outs_count)
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -821,11 +821,7 @@ namespace tools
|
|||
//next functions in public area only becausce of test_generator
|
||||
//TODO: Need refactoring - remove it back to private zone
|
||||
void set_genesis(const crypto::hash& genesis_hash);
|
||||
bool prepare_and_sign_pos_block(currency::block& b,
|
||||
const currency::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);
|
||||
bool prepare_and_sign_pos_block(currency::block& b, const currency::pos_entry& pe) const;
|
||||
void process_new_blockchain_entry(const currency::block& b,
|
||||
const currency::block_direct_data_entry& bche,
|
||||
const crypto::hash& bl_id,
|
||||
|
|
@ -836,8 +832,8 @@ namespace tools
|
|||
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 build_minted_block(const mining_context& cxt);
|
||||
bool build_minted_block(const mining_context& cxt, const currency::account_public_address& miner_address);
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -353,7 +353,7 @@ bool test_generator::sign_block(currency::block& b,
|
|||
const std::vector<const block_info*>& blocks,
|
||||
const outputs_index& oi)
|
||||
{
|
||||
uint64_t h = 0;
|
||||
/*uint64_t h = 0;
|
||||
uint64_t out_i = 0;
|
||||
const transaction * pts = nullptr;
|
||||
crypto::public_key source_tx_pub_key = null_pkey;
|
||||
|
|
@ -368,11 +368,9 @@ bool test_generator::sign_block(currency::block& b,
|
|||
out_i,
|
||||
source_tx_pub_key,
|
||||
out_key);
|
||||
CHECK_AND_ASSERT_THROW_MES(r, "Failed to get_output_details_by_global_index()");
|
||||
CHECK_AND_ASSERT_THROW_MES(r, "Failed to get_output_details_by_global_index()");*/
|
||||
|
||||
std::vector<const crypto::public_key*> keys_ptrs;
|
||||
keys_ptrs.push_back(&out_key);
|
||||
r = w.prepare_and_sign_pos_block(b, pe, source_tx_pub_key, out_i, keys_ptrs);
|
||||
bool r = w.prepare_and_sign_pos_block(b, pe);
|
||||
CHECK_AND_ASSERT_THROW_MES(r,"Failed to prepare_and_sign_pos_block()");
|
||||
|
||||
return true;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue