1
0
Fork 0
forked from lthn/blockchain

Zarcanum & assets balance proof refactoring: work in progress

This commit is contained in:
sowle 2023-03-16 23:59:52 +01:00
parent 2f91a2b7f3
commit c6294f7cb6
No known key found for this signature in database
GPG key ID: C07A24B2D89D49FC
10 changed files with 99 additions and 75 deletions

View file

@ -1427,7 +1427,7 @@ bool blockchain_storage::create_block_template(const account_public_address& min
block& b,
wide_difficulty_type& diffic,
uint64_t& height,
crypto::scalar_t* blinding_mask_sum_ptr /* = nullptr */) const
outputs_generation_context* miner_tx_ogc_ptr /* = nullptr */) const
{
create_block_template_params params = AUTO_VAL_INIT(params);
params.miner_address = miner_address;
@ -1442,8 +1442,8 @@ bool blockchain_storage::create_block_template(const account_public_address& min
b = resp.b;
diffic = resp.diffic;
height = resp.height;
if (blinding_mask_sum_ptr)
*blinding_mask_sum_ptr = resp.blinding_mask_sum;
if (miner_tx_ogc_ptr)
*miner_tx_ogc_ptr = resp.miner_tx_ogc;
return r;
}
@ -1528,7 +1528,7 @@ bool blockchain_storage::create_block_template(const create_block_template_param
CURRENCY_MINER_TX_MAX_OUTS,
pos,
pe,
&resp.blinding_mask_sum);
&resp.miner_tx_ogc);
CHECK_AND_ASSERT_MES(r, false, "Failed to construc miner tx, first chance");
uint64_t coinbase_size = get_object_blobsize(b.miner_tx);
// "- 100" - to reserve room for PoS additions into miner tx

View file

@ -261,7 +261,7 @@ namespace currency
bool create_block_template(const account_public_address& miner_address, const blobdata& ex_nonce, block& b, wide_difficulty_type& di, uint64_t& height) const;
bool create_block_template(const account_public_address& miner_address, const account_public_address& stakeholder_address, const blobdata& ex_nonce, bool pos, const pos_entry& pe, fill_block_template_func_t custom_fill_block_template_func, block& b, wide_difficulty_type& di, uint64_t& height, crypto::scalar_t* blinding_mask_sum_ptr = nullptr) const;
bool create_block_template(const account_public_address& miner_address, const account_public_address& stakeholder_address, const blobdata& ex_nonce, bool pos, const pos_entry& pe, fill_block_template_func_t custom_fill_block_template_func, block& b, wide_difficulty_type& di, uint64_t& height, outputs_generation_context* miner_tx_ogc_ptr = nullptr) const;
bool create_block_template(const create_block_template_params& params, create_block_template_response& resp) const;
bool have_block(const crypto::hash& id) const;

View file

@ -1,4 +1,4 @@
// Copyright (c) 2014-2018 Zano Project
// Copyright (c) 2014-2023 Zano Project
// Copyright (c) 2014-2018 The Louisdor Project
// Copyright (c) 2012-2013 The Cryptonote developers
// Copyright (c) 2012-2013 The Boolberry developers
@ -19,6 +19,8 @@
#include "currency_basic.h"
#include "difficulty.h"
#include "currency_protocol/blobdatatype.h"
#include "currency_format_utils_transactions.h" // only for output_generation_context
namespace currency
{
@ -144,7 +146,7 @@ namespace currency
block b;
wide_difficulty_type diffic;
uint64_t height;
crypto::scalar_t blinding_mask_sum; // sum of all the outputs' blinding masks
outputs_generation_context miner_tx_ogc; // bad design, a lot of copying, consider redesign -- sowle
};
typedef std::unordered_map<crypto::hash, transaction> transactions_map;
@ -157,4 +159,4 @@ namespace currency
}
} // namespace currency

View file

@ -70,53 +70,6 @@ namespace currency
pos_entry());
}*/
//--------------------------------------------------------------------------------
struct outputs_generation_context
{
outputs_generation_context(size_t outs_count)
: asset_ids(outs_count)
, blinded_asset_ids(outs_count)
, amount_commitments(outs_count)
, asset_id_blinding_masks(outs_count)
, amounts(outs_count)
, amount_blinding_masks(outs_count)
{}
bool check_sizes(size_t outs_count) const
{
return
asset_ids.size() == outs_count &&
blinded_asset_ids.size() == outs_count &&
amount_commitments.size() == outs_count &&
asset_id_blinding_masks.size() == outs_count &&
amounts.size() == outs_count &&
amount_blinding_masks.size() == outs_count;
}
// per output data
std::vector<crypto::point_t> asset_ids;
std::vector<crypto::point_t> blinded_asset_ids;
std::vector<crypto::point_t> amount_commitments;
crypto::scalar_vec_t asset_id_blinding_masks;
crypto::scalar_vec_t amounts;
crypto::scalar_vec_t amount_blinding_masks;
// common data: inputs
crypto::point_t pseudo_out_amount_commitments_sum = crypto::c_point_0;
crypto::scalar_t pseudo_out_amount_blinding_masks_sum = 0;
crypto::scalar_t real_in_asset_id_blinding_mask_x_amount_sum = 0; // = sum( real_out_blinding_mask[i] * amount[i] )
// common data: outputs
crypto::point_t amount_commitments_sum = crypto::c_point_0;
crypto::scalar_t amount_blinding_masks_sum = 0;
crypto::scalar_t asset_id_blinding_mask_x_amount_sum = 0; // = sum( blinding_mask[j] * amount[j] )
// data for ongoing asset operation in tx (if applicable, tx extra should contain asset_descriptor_operation)
crypto::public_key ao_asset_id {};
crypto::point_t ao_asset_id_pt = crypto::c_point_0;
crypto::point_t ao_amount_commitment = crypto::c_point_0;
crypto::scalar_t ao_amount_blinding_mask {};
};
//--------------------------------------------------------------------------------
bool generate_asset_surjection_proof(const crypto::hash& context_hash, zc_asset_surjection_proof& result)
{
@ -289,7 +242,7 @@ namespace currency
size_t max_outs /* = CURRENCY_MINER_TX_MAX_OUTS */,
bool pos /* = false */,
const pos_entry& pe /* = pos_entry() */, // only pe.stake_unlock_time and pe.stake_amount are used now, TODO: consider refactoring -- sowle
crypto::scalar_t* blinding_masks_sum_ptr /* = nullptr */,
outputs_generation_context* ogc_ptr /* = nullptr */,
const keypair* tx_one_time_key_to_use /* = nullptr */
)
{
@ -435,17 +388,14 @@ namespace currency
CHECK_AND_ASSERT_MES(r, false, "Failed to generate zc_outs_range_proof()");
tx.proofs.emplace_back(std::move(range_proofs));
if (!pos)
{
currency::zc_balance_proof balance_proof{};
r = generate_tx_balance_proof(tx, tx_id, outs_gen_context, block_reward, balance_proof);
CHECK_AND_ASSERT_MES(r, false, "generate_tx_balance_proof failed");
tx.proofs.emplace_back(std::move(balance_proof));
}
currency::zc_balance_proof balance_proof{};
r = generate_tx_balance_proof(tx, tx_id, outs_gen_context, block_reward, balance_proof);
CHECK_AND_ASSERT_MES(r, false, "generate_tx_balance_proof failed");
tx.proofs.emplace_back(std::move(balance_proof));
}
if (blinding_masks_sum_ptr)
*blinding_masks_sum_ptr = outs_gen_context.amount_blinding_masks_sum; // TODO @#@#
if (ogc_ptr)
*ogc_ptr = outs_gen_context; // TODO @#@# consider refactoring (a lot of copying) -- sowle
return true;
}

View file

@ -238,6 +238,7 @@ namespace currency
};
bool verify_multiple_zc_outs_range_proofs(const std::vector<zc_outs_range_proofs_with_commitments>& range_proofs);
bool generate_tx_balance_proof(const transaction &tx, const crypto::hash& tx_id, const outputs_generation_context& ogc, uint64_t block_reward_for_miner_tx, currency::zc_balance_proof& proof);
bool check_tx_bare_balance(const transaction& tx, uint64_t additional_inputs_amount_and_fees_for_mining_tx = 0);
bool check_tx_balance(const transaction& tx, const crypto::hash& tx_id, uint64_t additional_inputs_amount_and_fees_for_mining_tx = 0);
bool validate_asset_operation(const transaction& tx, const crypto::hash& tx_id, const asset_descriptor_operation& ado, crypto::public_key& asset_id);
@ -253,7 +254,7 @@ namespace currency
size_t max_outs = CURRENCY_MINER_TX_MAX_OUTS,
bool pos = false,
const pos_entry& pe = pos_entry(),
crypto::scalar_t* blinding_masks_sum_ptr = nullptr,
outputs_generation_context* ogc_ptr = nullptr,
const keypair* tx_one_time_key_to_use = nullptr);
//---------------------------------------------------------------
uint64_t get_string_uint64_hash(const std::string& str);

View file

@ -1,4 +1,4 @@
// Copyright (c) 2018-2022 Zano Project
// Copyright (c) 2018-2023 Zano Project
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -172,4 +172,75 @@ namespace currency
bool validate_inputs_sorting(const transaction& tx);
std::vector<tx_source_entry::output_entry> prepare_outputs_entries_for_key_offsets(const std::vector<tx_source_entry::output_entry>& outputs, size_t old_real_index, size_t& new_real_index) noexcept;
}
struct outputs_generation_context
{
outputs_generation_context() = default;
outputs_generation_context(size_t outs_count)
: asset_ids(outs_count)
, blinded_asset_ids(outs_count)
, amount_commitments(outs_count)
, asset_id_blinding_masks(outs_count)
, amounts(outs_count)
, amount_blinding_masks(outs_count)
{}
bool check_sizes(size_t outs_count) const
{
return
asset_ids.size() == outs_count &&
blinded_asset_ids.size() == outs_count &&
amount_commitments.size() == outs_count &&
asset_id_blinding_masks.size() == outs_count &&
amounts.size() == outs_count &&
amount_blinding_masks.size() == outs_count;
}
// per output data
std::vector<crypto::point_t> asset_ids;
std::vector<crypto::point_t> blinded_asset_ids; // generate_zc_outs_range_proof
std::vector<crypto::point_t> amount_commitments; // generate_zc_outs_range_proof construct_tx_out
crypto::scalar_vec_t asset_id_blinding_masks; // construct_tx_out
crypto::scalar_vec_t amounts; // generate_zc_outs_range_proof
crypto::scalar_vec_t amount_blinding_masks; // generate_zc_outs_range_proof
// common data: inputs
crypto::point_t pseudo_out_amount_commitments_sum = crypto::c_point_0; // generate_tx_balance_proof generate_ZC_sig
crypto::scalar_t pseudo_out_amount_blinding_masks_sum = 0; // generate_ZC_sig
crypto::scalar_t real_in_asset_id_blinding_mask_x_amount_sum = 0; // = sum( real_out_blinding_mask[i] * amount[i] ) generate_tx_balance_proof generate_ZC_sig
// common data: outputs
crypto::point_t amount_commitments_sum = crypto::c_point_0; // generate_tx_balance_proof
crypto::scalar_t amount_blinding_masks_sum = 0; // construct_tx_out generate_tx_balance_proof generate_ZC_sig
crypto::scalar_t asset_id_blinding_mask_x_amount_sum = 0; // = sum( blinding_mask[j] * amount[j] ) generate_tx_balance_proof
// data for ongoing asset operation in tx (if applicable, tx extra should contain asset_descriptor_operation)
crypto::public_key ao_asset_id {};
crypto::point_t ao_asset_id_pt = crypto::c_point_0;
crypto::point_t ao_amount_commitment = crypto::c_point_0;
crypto::scalar_t ao_amount_blinding_mask {}; // generate_tx_balance_proof generate_ZC_sig
// consider redesign
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(asset_ids);
KV_SERIALIZE(blinded_asset_ids);
KV_SERIALIZE(amount_commitments);
KV_SERIALIZE(asset_id_blinding_masks);
KV_SERIALIZE(amounts);
KV_SERIALIZE(amount_blinding_masks);
KV_SERIALIZE(pseudo_out_amount_commitments_sum);
KV_SERIALIZE(pseudo_out_amount_blinding_masks_sum);
KV_SERIALIZE(real_in_asset_id_blinding_mask_x_amount_sum);
KV_SERIALIZE(amount_commitments_sum);
KV_SERIALIZE(amount_blinding_masks_sum);
KV_SERIALIZE(asset_id_blinding_mask_x_amount_sum);
KV_SERIALIZE(ao_asset_id);
KV_SERIALIZE(ao_asset_id_pt);
KV_SERIALIZE(ao_amount_commitment);
KV_SERIALIZE(ao_amount_blinding_mask);
END_KV_SERIALIZE_MAP()
};
} // namespace currency

View file

@ -875,7 +875,7 @@ namespace currency
blobdata block_blob = t_serializable_object_to_blob(resp.b);
res.blocktemplate_blob = string_tools::buff_to_hex_nodelimer(block_blob);
res.prev_hash = string_tools::pod_to_hex(resp.b.prev_id);
res.blinding_masks_sum = resp.blinding_mask_sum;
res.miner_tx_ogc = resp.miner_tx_ogc;
res.height = resp.height;
//calculate epoch seed
res.seed = currency::ethash_epoch_to_seed(currency::ethash_height_to_epoch(res.height));

View file

@ -860,7 +860,7 @@ namespace currency
crypto::hash seed;
blobdata blocktemplate_blob;
std::string prev_hash;
crypto::scalar_t blinding_masks_sum; // sum of outputs' blinding masks (for zc outs)
outputs_generation_context miner_tx_ogc;
std::string status;
BEGIN_KV_SERIALIZE_MAP()
@ -869,7 +869,7 @@ namespace currency
KV_SERIALIZE_POD_AS_HEX_STRING(seed)
KV_SERIALIZE(blocktemplate_blob)
KV_SERIALIZE(prev_hash)
KV_SERIALIZE(blinding_masks_sum)
KV_SERIALIZE(miner_tx_ogc)
KV_SERIALIZE(status)
END_KV_SERIALIZE_MAP()
};

View file

@ -3831,7 +3831,7 @@ 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(const mining_context& cxt, currency::block& b, const pos_entry& pe, const crypto::scalar_t& blinding_masks_sum) const
bool wallet2::prepare_and_sign_pos_block(const mining_context& cxt, currency::block& b, const pos_entry& pe, const currency::outputs_generation_context& miner_tx_ogc) const
{
bool r = false;
WLT_CHECK_AND_ASSERT_MES(pe.wallet_index < m_transfers.size(), false, "invalid pe.wallet_index: " << pe.wallet_index);
@ -3978,7 +3978,7 @@ bool wallet2::prepare_and_sign_pos_block(const mining_context& cxt, currency::bl
uint8_t err = 0;
r = crypto::zarcanum_generate_proof(tx_hash_for_sig, cxt.kernel_hash, ring, cxt.last_pow_block_id_hashed, cxt.sk.kimage,
secret_x, cxt.secret_q, secret_index, -blinding_masks_sum, cxt.stake_amount, cxt.stake_out_blinding_mask,
secret_x, cxt.secret_q, secret_index, -miner_tx_ogc.amount_blinding_masks_sum, cxt.stake_amount, cxt.stake_out_blinding_mask,
static_cast<crypto::zarcanum_proof&>(sig), &err);
WLT_CHECK_AND_ASSERT_MES(r, false, "zarcanum_generate_proof failed, err: " << (int)err);
@ -4139,7 +4139,7 @@ bool wallet2::build_minted_block(const mining_context& cxt, const currency::acco
//else
//{
// old fashioned non-hidden amount PoS scheme
res = prepare_and_sign_pos_block(cxt, b, tmpl_req.pe, tmpl_rsp.blinding_masks_sum);
res = prepare_and_sign_pos_block(cxt, b, tmpl_req.pe, tmpl_rsp.miner_tx_ogc);
WLT_CHECK_AND_ASSERT_MES(res, false, "Failed to prepare_and_sign_pos_block");
//}

View file

@ -856,7 +856,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(const mining_context& cxt, currency::block& b, const currency::pos_entry& pe, const crypto::scalar_t& blinding_masks_sum) const;
bool prepare_and_sign_pos_block(const mining_context& cxt, currency::block& b, const currency::pos_entry& pe, const currency::outputs_generation_context& miner_tx_ogc) const;
void process_new_blockchain_entry(const currency::block& b,
const currency::block_direct_data_entry& bche,
const crypto::hash& bl_id,