From c6294f7cb6f1b5a8dfaae5a47877beb3ab16f416 Mon Sep 17 00:00:00 2001 From: sowle Date: Thu, 16 Mar 2023 23:59:52 +0100 Subject: [PATCH] Zarcanum & assets balance proof refactoring: work in progress --- src/currency_core/blockchain_storage.cpp | 8 +- src/currency_core/blockchain_storage.h | 2 +- src/currency_core/blockchain_storage_basic.h | 8 +- src/currency_core/currency_format_utils.cpp | 64 ++-------------- src/currency_core/currency_format_utils.h | 3 +- .../currency_format_utils_transactions.h | 75 ++++++++++++++++++- src/rpc/core_rpc_server.cpp | 2 +- src/rpc/core_rpc_server_commands_defs.h | 4 +- src/wallet/wallet2.cpp | 6 +- src/wallet/wallet2.h | 2 +- 10 files changed, 99 insertions(+), 75 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index f6b42939..cc945e17 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -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 diff --git a/src/currency_core/blockchain_storage.h b/src/currency_core/blockchain_storage.h index 019ec7de..6262a815 100644 --- a/src/currency_core/blockchain_storage.h +++ b/src/currency_core/blockchain_storage.h @@ -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; diff --git a/src/currency_core/blockchain_storage_basic.h b/src/currency_core/blockchain_storage_basic.h index c0a1a181..72170005 100644 --- a/src/currency_core/blockchain_storage_basic.h +++ b/src/currency_core/blockchain_storage_basic.h @@ -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 transactions_map; @@ -157,4 +159,4 @@ namespace currency -} \ No newline at end of file +} // namespace currency diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index b82bfe51..916e3466 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -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 asset_ids; - std::vector blinded_asset_ids; - std::vector 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; } diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index 164c4288..26a3fa98 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -238,6 +238,7 @@ namespace currency }; bool verify_multiple_zc_outs_range_proofs(const std::vector& 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); diff --git a/src/currency_core/currency_format_utils_transactions.h b/src/currency_core/currency_format_utils_transactions.h index f27f2ce0..af4597ed 100644 --- a/src/currency_core/currency_format_utils_transactions.h +++ b/src/currency_core/currency_format_utils_transactions.h @@ -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 prepare_outputs_entries_for_key_offsets(const std::vector& 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 asset_ids; + std::vector blinded_asset_ids; // generate_zc_outs_range_proof + std::vector 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 diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 42112077..0dd8b111 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -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)); diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index b99e5752..13f5fb49 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -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() }; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 2035310a..1859aaba 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -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(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"); //} diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index d54a0ca2..1b2d436c 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -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,