From e02d15a1707d674aab7c4764daee19cafdfd8e80 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 11 Nov 2022 19:10:50 +0100 Subject: [PATCH] coretests: pos_block_builder now supports Zarcanum --- tests/core_tests/pos_block_builder.cpp | 214 ++----------------------- 1 file changed, 14 insertions(+), 200 deletions(-) diff --git a/tests/core_tests/pos_block_builder.cpp b/tests/core_tests/pos_block_builder.cpp index 99769aae..9231b200 100644 --- a/tests/core_tests/pos_block_builder.cpp +++ b/tests/core_tests/pos_block_builder.cpp @@ -198,7 +198,7 @@ void pos_block_builder::step4_generate_coinbase_tx(size_t median_size, m_step = 4; } - +// supports Zarcanum and mixins void pos_block_builder::step5_sign(const currency::tx_source_entry& se, const currency::account_keys& stakeholder_keys) { bool r = false; @@ -219,22 +219,20 @@ void pos_block_builder::step5_sign(const currency::tx_source_entry& se, const cu stake_input.k_image = m_context.sk.kimage; - for(const auto& oe : se.outputs) + std::vector ring; + for(const auto& el : se.outputs) { - //oe. + stake_input.key_offsets.push_back(el.out_reference); + ring.emplace_back(el.stealth_address, el.amount_commitment, el.concealing_point); } - - - stake_input.key_offsets.push_back(m_pos_stake_output_gindex); // TODO: support decoys + r = absolute_sorted_output_offsets_to_relative_in_place(stake_input.key_offsets); + CHECK_AND_ASSERT_THROW_MES(r, "absolute_sorted_output_offsets_to_relative_in_place failed"); crypto::hash tx_hash_for_sig = get_transaction_hash(m_block.miner_tx); // TODO @#@# change to block hash after the corresponding test is made - std::vector ring; - uint64_t secret_index = 0; // index of the real stake output - uint8_t err = 0; r = crypto::zarcanum_generate_proof(tx_hash_for_sig, m_context.kernel_hash, ring, m_context.last_pow_block_id_hashed, m_context.sk.kimage, - secret_x, m_context.secret_q, secret_index, m_blinding_masks_sum, m_context.stake_amount, m_context.stake_out_blinding_mask, + secret_x, m_context.secret_q, se.real_output, m_blinding_masks_sum, m_context.stake_amount, m_context.stake_out_blinding_mask, static_cast(sig), &err); CHECK_AND_ASSERT_THROW_MES(r, "zarcanum_generate_proof failed, err: " << (int)err); } @@ -261,201 +259,17 @@ void pos_block_builder::step5_sign(const currency::tx_source_entry& se, const cu 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) { - bool r = false; - CHECK_AND_ASSERT_THROW_MES(m_step == 4, "pos_block_builder: incorrect step sequence"); + CHECK_AND_ASSERT_THROW_MES(!m_context.zarcanum, "for zarcanum use another overloading"); - // calculate stake_out_derivation and secret_x (derived ephemeral secret key) - crypto::key_derivation stake_out_derivation = AUTO_VAL_INIT(stake_out_derivation); - r = crypto::generate_key_derivation(stake_tx_pub_key, stakeholder_account.get_keys().view_secret_key, stake_out_derivation); // d = 8 * v * R - CHECK_AND_ASSERT_THROW_MES(r, "generate_key_derivation failed"); - crypto::secret_key secret_x = AUTO_VAL_INIT(secret_x); - crypto::derive_secret_key(stake_out_derivation, stake_tx_out_index, stakeholder_account.get_keys().spend_secret_key, secret_x); // x = Hs(8 * v * R, i) + s + tx_source_entry se{}; - if (m_context.zarcanum) - { - // Zarcanum - zarcanum_sig& sig = boost::get(m_block.miner_tx.signatures[0]); - txin_zc_input& stake_input = boost::get(m_block.miner_tx.vin[1]); + se.real_out_tx_key = stake_tx_pub_key; + se.real_output_in_tx_index = stake_tx_out_index; + se.outputs.emplace_back(m_pos_stake_output_gindex, stake_tx_out_pub_key); - stake_input.k_image = m_context.sk.kimage; - stake_input.key_offsets.push_back(m_pos_stake_output_gindex); // TODO: support decoys - - crypto::hash tx_hash_for_sig = get_transaction_hash(m_block.miner_tx); // TODO @#@# change to block hash after the corresponding test is made - - std::vector ring; - uint64_t secret_index = 0; // index of the real stake output - - uint8_t err = 0; - r = crypto::zarcanum_generate_proof(tx_hash_for_sig, m_context.kernel_hash, ring, m_context.last_pow_block_id_hashed, m_context.sk.kimage, - secret_x, m_context.secret_q, secret_index, m_blinding_masks_sum, m_context.stake_amount, m_context.stake_out_blinding_mask, - static_cast(sig), &err); - CHECK_AND_ASSERT_THROW_MES(r, "zarcanum_generate_proof failed, err: " << (int)err); - } - else - { - // old PoS with non-hidden amounts - NLSAG_sig& sig = boost::get(m_block.miner_tx.signatures[0]); - txin_to_key& stake_input = boost::get(m_block.miner_tx.vin[1]); - - stake_input.k_image = m_context.sk.kimage; - stake_input.amount = m_context.stake_amount; - stake_input.key_offsets.push_back(m_pos_stake_output_gindex); - - crypto::hash block_hash = currency::get_block_hash(m_block); - std::vector keys_ptrs(1, &stake_tx_out_pub_key); - sig.s.resize(1); - crypto::generate_ring_signature(block_hash, m_context.sk.kimage, keys_ptrs, secret_x, 0, sig.s.data()); - } - - m_step = 5; + step5_sign(se, stakeholder_account.get_keys()); } -/* -void pos_block_builder::step5_sign_zarcanum(const crypto::public_key& stake_tx_pub_key, size_t stake_tx_out_index, const currency::account_base& stakeholder_account) -{ - CHECK_AND_ASSERT_THROW_MES(m_step == 4, "pos_block_builder: incorrect step sequence"); - - CHECK_AND_ASSERT_THROW_MES(m_block.miner_tx.signatures.size() == 1, "pos_block_builder: incorrect size of miner_tx signatures: " << m_block.miner_tx.signatures.size()); - zarcanum_sig& sig = boost::get(m_block.miner_tx.signatures[0]); - - crypto::key_derivation pos_coin_derivation{}; - bool r = crypto::generate_key_derivation(stake_tx_pub_key, stakeholder_account.get_keys().view_secret_key, pos_coin_derivation); // v * 8 * R - CHECK_AND_ASSERT_THROW_MES(r, "generate_key_derivation failed"); - crypto::secret_key secret_x{}; - crypto::derive_secret_key(pos_coin_derivation, stake_tx_out_index, stakeholder_account.get_keys().spend_secret_key, secret_x); // x = s + Hs(v * 8 * R, i) - - std::vector ring; - uint64_t secret_index = 0; - crypto::scalar_t blinding_masks_sum; - - - - crypto::hash tx_hash_for_sig = get_transaction_hash(m_block.miner_tx); // TODO @#@# change to currency::get_block_hash(m_block); - uint8_t err = 0; - r = crypto::zarcanum_generate_proof(tx_hash_for_sig, m_context.kernel_hash, ring, m_context.last_pow_block_id_hashed, m_context.sk.kimage, - secret_x, m_context.secret_q, secret_index, blinding_masks_sum, m_context.stake_amount, m_context.stake_out_blinding_mask, - static_cast(sig), &err); - CHECK_AND_ASSERT_THROW_MES(r, "zarcanum_generate_proof failed, err: " << (int)err); - - m_step = 5; -} -*/ - - -/* -bool construct_homemade_pos_miner_tx(bool zarcanum, size_t height, size_t median_size, const boost::multiprecision::uint128_t& already_generated_coins, - size_t current_block_size, - uint64_t fee, - uint64_t pos_stake_amount, - crypto::key_image pos_stake_keyimage, - size_t pos_stake_gindex, - const account_public_address &reward_receiving_address, - const account_public_address &stakeholder_address, - transaction& tx, - const blobdata& extra_nonce, //= blobdata(), - size_t max_outs, //= CURRENCY_MINER_TX_MAX_OUTS, - keypair tx_one_time_key, //= keypair::generate()) -{ - tx = transaction{}; - - tx.version = zarcanum ? TRANSACTION_VERSION_POST_HF4 : TRANSACTION_VERSION_PRE_HF4; - set_tx_unlock_time(tx, height + CURRENCY_MINED_MONEY_UNLOCK_WINDOW); - - // calculate block reward - uint64_t block_reward; - bool r = get_block_reward(true, median_size, current_block_size, already_generated_coins, block_reward, height); - CHECK_AND_ASSERT_MES(r, false, "get_block_reward failed"); - block_reward += fee; - - // - // prepare destinations - // - // 1. split block_reward into out_amounts - std::vector out_amounts; - - if (tx.version > TRANSACTION_VERSION_PRE_HF4) - { - // randomly split into CURRENCY_TX_MIN_ALLOWED_OUTS outputs - decompose_amount_randomly(block_reward, [&](uint64_t a){ out_amounts.push_back(a); }, CURRENCY_TX_MIN_ALLOWED_OUTS); - } - else - { - // non-hidden outs: split into digits - decompose_amount_into_digits(block_reward, DEFAULT_DUST_THRESHOLD, - [&out_amounts](uint64_t a_chunk) { out_amounts.push_back(a_chunk); }, - [&out_amounts](uint64_t a_dust) { out_amounts.push_back(a_dust); }); - - CHECK_AND_ASSERT_MES(1 <= max_outs, false, "max_out must be non-zero"); - while (max_outs < out_amounts.size()) - { - out_amounts[out_amounts.size() - 2] += out_amounts.back(); - out_amounts.resize(out_amounts.size() - 1); - } - } - - // reward - bool burn_money = reward_receiving_address.spend_public_key == null_pkey && reward_receiving_address.view_public_key == null_pkey; // if true, burn reward, so no one on Earth can spend them - for (size_t output_index = 0; output_index < out_amounts.size(); ++output_index) - { - txout_to_key tk; - tk.key = null_pkey; // null means burn money - tk.mix_attr = 0; - - if (!burn_money) - { - r = currency::derive_public_key_from_target_address(reward_receiving_address, tx_one_time_key.sec, output_index, tk.key); // derivation(view_pub; tx_sec).derive(output_index, spend_pub) => output pub key - CHECK_AND_ASSERT_MES(r, false, "failed to derive_public_key_from_target_address"); - } - - tx_out_bare out; - out.amount = out_amounts[output_index]; - out.target = tk; - tx.vout.push_back(out); - } - - // stake - burn_money = stakeholder_address.spend_public_key == null_pkey && stakeholder_address.view_public_key == null_pkey; // if true, burn stake - { - txout_to_key tk; - tk.key = null_pkey; // null means burn money - tk.mix_attr = 0; - - if (!burn_money) - { - r = currency::derive_public_key_from_target_address(stakeholder_address, tx_one_time_key.sec, tx.vout.size(), tk.key); - CHECK_AND_ASSERT_MES(r, false, "failed to derive_public_key_from_target_address"); - } - - tx_out_bare out; - out.amount = pos_stake_amount; - out.target = tk; - tx.vout.push_back(out); - } - - // take care about extra - add_tx_pub_key_to_extra(tx, tx_one_time_key.pub); - if (extra_nonce.size()) - if (!add_tx_extra_userdata(tx, extra_nonce)) - return false; - - // populate ins with 1) money-generating and 2) PoS - txin_gen in; - in.height = height; - tx.vin.push_back(in); - - txin_to_key posin; - posin.amount = pos_stake_amount; - posin.key_offsets.push_back(pos_stake_gindex); - posin.k_image = pos_stake_keyimage; - tx.vin.push_back(posin); - //reserve place for ring signature - tx.signatures.resize(1); - boost::get(tx.signatures[0]).s.resize(posin.key_offsets.size()); - - 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 before_sign_cb, currency::block& output)