forked from lthn/blockchain
pos_block_builder & zarcanum adaptation: WIP
This commit is contained in:
parent
078a7bf8b5
commit
b570ca81ef
7 changed files with 107 additions and 69 deletions
|
|
@ -46,7 +46,7 @@ namespace crypto
|
|||
if (!(cond)) { LOG_PRINT_RED("zarcanum_generate_proof: \"" << #cond << "\" is false at " << LOCATION_SS << ENDL << "error code = " << err_code, LOG_LEVEL_3); \
|
||||
if (p_err) { *p_err = err_code; } return false; }
|
||||
|
||||
bool zarcanum_generate_proof(const hash& m, const hash& kernel_hash, const std::vector<CLSAG_GGXG_input_ref_t>& ring, const point_t& pseudo_out_amount_commitment,
|
||||
bool zarcanum_generate_proof(const hash& m, const hash& kernel_hash, const std::vector<CLSAG_GGXG_input_ref_t>& ring,
|
||||
const scalar_t& last_pow_block_id_hashed, const key_image& stake_ki,
|
||||
const scalar_t& secret_x, const scalar_t& secret_q, uint64_t secret_index, const scalar_t& pseudo_out_blinding_mask, uint64_t stake_amount, const scalar_t& stake_blinding_mask,
|
||||
zarcanum_proof& result, uint8_t* p_err /* = nullptr */)
|
||||
|
|
@ -144,6 +144,7 @@ namespace crypto
|
|||
// layer 3 secret (with respect to G)
|
||||
// secret_q
|
||||
|
||||
point_t pseudo_out_amount_commitment = a * crypto::c_point_H + pseudo_out_blinding_mask * crypto::c_point_G;
|
||||
result.pseudo_out_amount_commitment = (crypto::c_scalar_1div8 * pseudo_out_amount_commitment).to_public_key();
|
||||
|
||||
TRY_ENTRY()
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ namespace crypto
|
|||
CLSAG_GGXG_signature clsag_ggxg;
|
||||
};
|
||||
|
||||
bool zarcanum_generate_proof(const hash& m, const hash& kernel_hash, const std::vector<crypto::CLSAG_GGXG_input_ref_t>& ring, const point_t& pseudo_out_amount_commitment,
|
||||
bool zarcanum_generate_proof(const hash& m, const hash& kernel_hash, const std::vector<crypto::CLSAG_GGXG_input_ref_t>& ring,
|
||||
const scalar_t& last_pow_block_id_hashed, const key_image& stake_ki,
|
||||
const scalar_t& secret_x, const scalar_t& secret_q, uint64_t secret_index, const scalar_t& pseudo_out_blinding_mask, uint64_t stake_amount, const scalar_t& stake_blinding_mask,
|
||||
zarcanum_proof& result, uint8_t* p_err = nullptr);
|
||||
|
|
|
|||
|
|
@ -2114,37 +2114,13 @@ namespace currency
|
|||
}
|
||||
|
||||
LOG_PRINT2("construct_tx.log", "transaction_created: " << get_transaction_hash(tx) << ENDL << obj_to_json_str(tx) << ENDL << ss_ring_s.str(), LOG_LEVEL_3);
|
||||
|
||||
//input_index++;
|
||||
//in_context_index++;
|
||||
}
|
||||
/*
|
||||
for(const tx_source_entry& source_entry : sources)
|
||||
{
|
||||
crypto::hash tx_hash_for_signature = prepare_prefix_hash_for_sign(tx, input_index, tx_prefix_hash);
|
||||
CHECK_AND_ASSERT_MES(tx_hash_for_signature != null_hash, false, "prepare_prefix_hash_for_sign failed");
|
||||
std::stringstream ss_ring_s;
|
||||
|
||||
if (source_entry.is_zarcanum())
|
||||
{
|
||||
// ZC
|
||||
// blinding_masks_sum is supposed to be sum(mask of all tx output) - sum(masks of all pseudo out commitments)
|
||||
r = generate_ZC_sig(tx_hash_for_signature, input_index, source_entry, in_contexts[in_context_index], sender_account_keys, blinding_masks_sum, flags, local_blinding_masks_sum, tx);
|
||||
CHECK_AND_ASSERT_MES(r, false, "generate_ZC_sigs failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
// NLSAG
|
||||
r = generate_NLSAG_sig(tx_hash_for_signature, tx_prefix_hash, input_index, source_entry, sender_account_keys, in_contexts[in_context_index], txkey, flags, tx, &ss_ring_s);
|
||||
CHECK_AND_ASSERT_MES(r, false, "generate_NLSAG_sig failed");
|
||||
}
|
||||
//size_t prefix_size = get_object_blobsize(static_cast<const transaction_prefix&>(tx));
|
||||
//size_t full_blob_size = t_serializable_object_to_blob(tx).size();
|
||||
//size_t estimated_blob_size = get_object_blobsize(tx);
|
||||
//CHECK_AND_ASSERT_MES(full_blob_size == estimated_blob_size, false, "!");
|
||||
|
||||
LOG_PRINT2("construct_tx.log", "transaction_created: " << get_transaction_hash(tx) << ENDL << obj_to_json_str(tx) << ENDL << ss_ring_s.str(), LOG_LEVEL_3);
|
||||
|
||||
input_index++;
|
||||
in_context_index++;
|
||||
}
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,18 +9,17 @@ namespace currency
|
|||
|
||||
struct pos_mining_context
|
||||
{
|
||||
wide_difficulty_type basic_diff;
|
||||
// Zarcanum notation:
|
||||
wide_difficulty_type basic_diff; // D
|
||||
stake_kernel sk;
|
||||
crypto::scalar_t last_pow_block_id_hashed; // f'
|
||||
crypto::scalar_t secret_q; // q
|
||||
boost::multiprecision::uint256_t z_l_div_z_D; // z * floor( l / (z * D) ) (max possible value (assuming z=2^64) : z * 2^252 / (z * 1) ~= 2^252)
|
||||
crypto::hash kernel_hash; // h
|
||||
crypto::scalar_t stake_out_blinding_mask; // f
|
||||
uint64_t stake_amount; // a
|
||||
|
||||
crypto::scalar_t last_pow_block_id_hashed; // Zarcanum notation: f'
|
||||
crypto::scalar_t secret_q; // Zarcanum notation: q
|
||||
boost::multiprecision::uint256_t z_l_div_z_D; // Zarcanum notation: z * floor( l / (z * D) ) (max possible value (assuming z=2^64) : z * 2^252 / (z * 1) ~= 2^252)
|
||||
crypto::hash kernel_hash; // Zarcanum notation: h
|
||||
crypto::scalar_t stake_out_blinding_mask; // Zarcanum notation: f
|
||||
|
||||
uint64_t stake_amount;
|
||||
|
||||
bool zarcanum;
|
||||
bool zarcanum; // false for pre-HF4 classic PoS with explicit amounts
|
||||
|
||||
void init(const wide_difficulty_type& pos_diff, const stake_modifier_type& sm, bool is_zarcanum);
|
||||
|
||||
|
|
|
|||
|
|
@ -3799,21 +3799,17 @@ bool wallet2::prepare_and_sign_pos_block(const mining_context& cxt, currency::bl
|
|||
}
|
||||
#endif
|
||||
|
||||
crypto::scalar_t pseudo_out_blinding_mask = blinding_masks_sum;
|
||||
//process_type_in_variant_container<tx_out_zarcanum>(b.miner_tx.vout, [&](tx_out_zarcanum& o){ pseudo_out_blinding_mask += o. });
|
||||
crypto::point_t pseudo_out_amount_commitment = td.m_amount * crypto::c_point_H + pseudo_out_blinding_mask * crypto::c_point_G;
|
||||
|
||||
crypto::hash tx_hash_for_sig = get_transaction_hash(b.miner_tx);
|
||||
|
||||
crypto::key_derivation derivation = AUTO_VAL_INIT(derivation);
|
||||
r = crypto::generate_key_derivation(source_tx_pub_key, m_account.get_keys().view_secret_key, derivation);
|
||||
WLT_CHECK_AND_ASSERT_MES(r, false, "generate_key_derivation failed, tid: " << pe.wallet_index << ", pe.tx_id: " << pe.tx_id);
|
||||
crypto::secret_key secret_x = AUTO_VAL_INIT(secret_x);
|
||||
crypto::derive_secret_key(derivation, pe.tx_out_index, m_account.get_keys().spend_secret_key, secret_x);
|
||||
|
||||
crypto::hash tx_hash_for_sig = get_transaction_hash(b.miner_tx); // TODO @#@# consider adding more input data to this hash
|
||||
|
||||
uint8_t err = 0;
|
||||
r = crypto::zarcanum_generate_proof(tx_hash_for_sig, cxt.kernel_hash, ring, pseudo_out_amount_commitment, cxt.last_pow_block_id_hashed,
|
||||
pe.keyimage, secret_x, cxt.secret_q, secret_index, pseudo_out_blinding_mask, td.m_amount, *td.m_opt_blinding_mask,
|
||||
r = crypto::zarcanum_generate_proof(tx_hash_for_sig, cxt.kernel_hash, ring, cxt.last_pow_block_id_hashed, pe.keyimage,
|
||||
secret_x, cxt.secret_q, secret_index, blinding_masks_sum, td.m_amount, *td.m_opt_blinding_mask,
|
||||
static_cast<crypto::zarcanum_proof&>(sig), &err);
|
||||
WLT_CHECK_AND_ASSERT_MES(r, false, "zarcanum_generate_proof failed, err: " << (int)err);
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ void pos_block_builder::clear()
|
|||
*this = pos_block_builder{};
|
||||
}
|
||||
|
||||
|
||||
void pos_block_builder::step1_init_header(const hard_forks_descriptor& hardforks, size_t block_height, crypto::hash& prev_block_hash)
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(m_step == 0, "pos_block_builder: incorrect step sequence");
|
||||
|
|
@ -26,9 +27,12 @@ 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_step = 1;
|
||||
}
|
||||
|
||||
|
||||
void pos_block_builder::step2_set_txs(const std::vector<currency::transaction>& txs)
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(m_step == 1, "pos_block_builder: incorrect step sequence");
|
||||
|
|
@ -50,6 +54,7 @@ void pos_block_builder::step2_set_txs(const std::vector<currency::transaction>&
|
|||
m_step = 2;
|
||||
}
|
||||
|
||||
|
||||
void pos_block_builder::step3_build_stake_kernel(
|
||||
uint64_t stake_output_amount,
|
||||
size_t stake_output_gindex,
|
||||
|
|
@ -61,44 +66,81 @@ void pos_block_builder::step3_build_stake_kernel(
|
|||
uint64_t timestamp_window,
|
||||
uint64_t timestamp_step)
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(m_step == 2, "pos_block_builder: incorrect step sequence");
|
||||
m_pos_stake_amount = stake_output_amount;
|
||||
m_pos_stake_output_gindex = stake_output_gindex;
|
||||
step3a(difficulty, last_pow_block_hash, last_pos_block_kernel_hash);
|
||||
|
||||
m_stake_kernel.kimage = stake_output_key_image;
|
||||
m_stake_kernel.block_timestamp = 0;
|
||||
m_stake_kernel.stake_modifier.last_pow_id = last_pow_block_hash;
|
||||
m_stake_kernel.stake_modifier.last_pos_kernel_id = last_pos_block_kernel_hash;
|
||||
crypto::public_key stake_source_tx_pub_key {};
|
||||
uint64_t stake_out_in_tx_index = UINT64_MAX;
|
||||
crypto::scalar_t stake_out_blinding_mask {};
|
||||
crypto::secret_key view_secret {};
|
||||
|
||||
step3b(stake_output_amount, stake_output_key_image, stake_source_tx_pub_key, stake_out_in_tx_index, stake_out_blinding_mask, view_secret, stake_output_gindex,
|
||||
timestamp_lower_bound, timestamp_window, timestamp_step);
|
||||
}
|
||||
|
||||
|
||||
void pos_block_builder::step3a(
|
||||
currency::wide_difficulty_type difficulty,
|
||||
const crypto::hash& last_pow_block_hash,
|
||||
const crypto::hash& last_pos_block_kernel_hash
|
||||
)
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(m_step == 2, "pos_block_builder: incorrect step sequence");
|
||||
|
||||
stake_modifier_type sm{};
|
||||
sm.last_pow_id = last_pow_block_hash;
|
||||
sm.last_pos_kernel_id = last_pos_block_kernel_hash;
|
||||
if (last_pos_block_kernel_hash == null_hash)
|
||||
{
|
||||
bool r = string_tools::parse_tpod_from_hex_string(POS_STARTER_KERNEL_HASH, m_stake_kernel.stake_modifier.last_pos_kernel_id);
|
||||
bool r = string_tools::parse_tpod_from_hex_string(POS_STARTER_KERNEL_HASH, sm.last_pos_kernel_id);
|
||||
CHECK_AND_ASSERT_THROW_MES(r, "Failed to parse POS_STARTER_KERNEL_HASH");
|
||||
}
|
||||
|
||||
wide_difficulty_type stake_difficulty = difficulty / stake_output_amount;
|
||||
m_context.init(difficulty, sm, m_context.zarcanum);
|
||||
m_step = 31;
|
||||
}
|
||||
|
||||
|
||||
void pos_block_builder::step3b(
|
||||
uint64_t stake_output_amount,
|
||||
const crypto::key_image& stake_output_key_image,
|
||||
const crypto::public_key& stake_source_tx_pub_key, // zarcanum only
|
||||
uint64_t stake_out_in_tx_index, // zarcanum only
|
||||
const crypto::scalar_t& stake_out_blinding_mask, // zarcanum only
|
||||
const crypto::secret_key& view_secret, // zarcanum only
|
||||
size_t stake_output_gindex,
|
||||
uint64_t timestamp_lower_bound,
|
||||
uint64_t timestamp_window,
|
||||
uint64_t timestamp_step)
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(m_step == 31, "pos_block_builder: incorrect step sequence");
|
||||
|
||||
m_pos_stake_output_gindex = stake_output_gindex;
|
||||
|
||||
m_context.prepare_entry(stake_output_amount, stake_output_key_image, stake_source_tx_pub_key, stake_out_in_tx_index, stake_out_blinding_mask, view_secret);
|
||||
|
||||
// align timestamp_lower_bound up to timestamp_step boundary if needed
|
||||
if (timestamp_lower_bound % timestamp_step != 0)
|
||||
timestamp_lower_bound = timestamp_lower_bound - (timestamp_lower_bound % timestamp_step) + timestamp_step;
|
||||
bool sk_found = false;
|
||||
for (uint64_t ts = timestamp_lower_bound; !sk_found && ts < timestamp_lower_bound + timestamp_window; ts += timestamp_step)
|
||||
{
|
||||
m_stake_kernel.block_timestamp = ts;
|
||||
crypto::hash sk_hash = crypto::cn_fast_hash(&m_stake_kernel, sizeof(m_stake_kernel));
|
||||
if (check_hash(sk_hash, stake_difficulty))
|
||||
{
|
||||
if (m_context.do_iteration(ts))
|
||||
sk_found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sk_found)
|
||||
ASSERT_MES_AND_THROW("Could't build stake kernel");
|
||||
|
||||
// update block header with found timestamp
|
||||
m_block.timestamp = m_stake_kernel.block_timestamp;
|
||||
m_block.timestamp = m_context.sk.block_timestamp;
|
||||
|
||||
m_step = 3;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void pos_block_builder::step4_generate_coinbase_tx(size_t median_size,
|
||||
const boost::multiprecision::uint128_t& already_generated_coins,
|
||||
const account_public_address &reward_and_stake_receiver_address,
|
||||
|
|
@ -110,6 +152,7 @@ void pos_block_builder::step4_generate_coinbase_tx(size_t median_size,
|
|||
step4_generate_coinbase_tx(median_size, already_generated_coins, reward_and_stake_receiver_address, reward_and_stake_receiver_address, extra_nonce, max_outs, alias, tx_one_time_key);
|
||||
}
|
||||
|
||||
|
||||
void pos_block_builder::step4_generate_coinbase_tx(size_t median_size,
|
||||
const boost::multiprecision::uint128_t& already_generated_coins,
|
||||
const account_public_address &reward_receiver_address,
|
||||
|
|
@ -123,7 +166,7 @@ void pos_block_builder::step4_generate_coinbase_tx(size_t median_size,
|
|||
|
||||
// generate miner tx using incorrect current_block_size only for size estimation
|
||||
size_t estimated_block_size = m_txs_total_size;
|
||||
bool r = construct_homemade_pos_miner_tx(m_height, median_size, already_generated_coins, estimated_block_size, m_total_fee, m_pos_stake_amount, m_stake_kernel.kimage,
|
||||
bool r = construct_homemade_pos_miner_tx(m_height, median_size, already_generated_coins, estimated_block_size, m_total_fee, m_context.stake_amount, m_context.sk.kimage,
|
||||
m_pos_stake_output_gindex, reward_receiver_address, stakeholder_address, m_block.miner_tx, extra_nonce, max_outs, tx_one_time_key);
|
||||
CHECK_AND_ASSERT_THROW_MES(r, "construct_homemade_pos_miner_tx failed");
|
||||
|
||||
|
|
@ -131,7 +174,7 @@ void pos_block_builder::step4_generate_coinbase_tx(size_t median_size,
|
|||
size_t cumulative_size = 0;
|
||||
for (size_t try_count = 0; try_count != 10; ++try_count)
|
||||
{
|
||||
r = construct_homemade_pos_miner_tx(m_height, median_size, already_generated_coins, estimated_block_size, m_total_fee, m_pos_stake_amount, m_stake_kernel.kimage,
|
||||
r = construct_homemade_pos_miner_tx(m_height, median_size, already_generated_coins, estimated_block_size, m_total_fee, m_context.stake_amount, m_context.sk.kimage,
|
||||
m_pos_stake_output_gindex, reward_receiver_address, stakeholder_address, m_block.miner_tx, extra_nonce, max_outs, tx_one_time_key);
|
||||
CHECK_AND_ASSERT_THROW_MES(r, "construct_homemade_pos_miner_tx failed");
|
||||
|
||||
|
|
@ -152,6 +195,7 @@ void pos_block_builder::step4_generate_coinbase_tx(size_t median_size,
|
|||
m_step = 4;
|
||||
}
|
||||
|
||||
|
||||
void pos_block_builder::step5_sign(const crypto::public_key& stake_tx_pub_key, size_t stake_tx_out_index, const crypto::public_key& stake_tx_out_pub_key, const currency::account_base& stakeholder_account)
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(m_step == 4, "pos_block_builder: incorrect step sequence");
|
||||
|
|
@ -166,11 +210,12 @@ void pos_block_builder::step5_sign(const crypto::public_key& stake_tx_pub_key, s
|
|||
// sign block actually in coinbase transaction
|
||||
crypto::hash block_hash = currency::get_block_hash(m_block);
|
||||
std::vector<const crypto::public_key*> keys_ptrs(1, &stake_tx_out_pub_key);
|
||||
crypto::generate_ring_signature(block_hash, m_stake_kernel.kimage, keys_ptrs, derived_secret_ephemeral_key, 0, &boost::get<currency::NLSAG_sig>(m_block.miner_tx.signatures[0]).s[0]);
|
||||
crypto::generate_ring_signature(block_hash, m_context.sk.kimage, keys_ptrs, derived_secret_ephemeral_key, 0, &boost::get<currency::NLSAG_sig>(m_block.miner_tx.signatures[0]).s[0]);
|
||||
|
||||
m_step = 5;
|
||||
}
|
||||
|
||||
|
||||
bool construct_homemade_pos_miner_tx(size_t height, size_t median_size, const boost::multiprecision::uint128_t& already_generated_coins,
|
||||
size_t current_block_size,
|
||||
uint64_t fee,
|
||||
|
|
@ -271,6 +316,7 @@ bool construct_homemade_pos_miner_tx(size_t height, size_t median_size, const bo
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool mine_next_pos_block_in_playtime_sign_cb(currency::core& c, const currency::block& prev_block, const currency::block& coinstake_scr_block, const currency::account_base& acc,
|
||||
std::function<bool(currency::block&)> before_sign_cb, currency::block& output)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -27,6 +27,26 @@ struct pos_block_builder
|
|||
uint64_t timestamp_lower_bound,
|
||||
uint64_t timestamp_window = POS_SCAN_WINDOW,
|
||||
uint64_t timestamp_step = POS_SCAN_STEP);
|
||||
|
||||
|
||||
void pos_block_builder::step3a(
|
||||
currency::wide_difficulty_type difficulty,
|
||||
const crypto::hash& last_pow_block_hash,
|
||||
const crypto::hash& last_pos_block_kernel_hash
|
||||
);
|
||||
|
||||
void pos_block_builder::step3b(
|
||||
uint64_t stake_output_amount,
|
||||
const crypto::key_image& stake_output_key_image,
|
||||
const crypto::public_key& stake_source_tx_pub_key,
|
||||
uint64_t stake_out_in_tx_index,
|
||||
const crypto::scalar_t& stake_out_blinding_mask,
|
||||
const crypto::secret_key& view_secret,
|
||||
size_t stake_output_gindex,
|
||||
uint64_t timestamp_lower_bound,
|
||||
uint64_t timestamp_window,
|
||||
uint64_t timestamp_step);
|
||||
|
||||
|
||||
void step4_generate_coinbase_tx(size_t median_size,
|
||||
const boost::multiprecision::uint128_t& already_generated_coins,
|
||||
|
|
@ -51,12 +71,12 @@ struct pos_block_builder
|
|||
size_t m_step = 0;
|
||||
size_t m_txs_total_size = 0;
|
||||
uint64_t m_total_fee = 0;
|
||||
currency::stake_kernel m_stake_kernel {};
|
||||
//currency::stake_kernel m_stake_kernel {};
|
||||
size_t m_height = 0;
|
||||
size_t m_pos_stake_output_gindex = 0;
|
||||
uint64_t m_pos_stake_amount = 0;
|
||||
//uint64_t m_pos_stake_amount = 0;
|
||||
|
||||
bool m_zarcanum = false;
|
||||
currency::pos_mining_context m_context {};
|
||||
};
|
||||
|
||||
bool construct_homemade_pos_miner_tx(size_t height, size_t median_size, const boost::multiprecision::uint128_t& already_generated_coins,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue