forked from lthn/blockchain
verify_asset_surjection_proof() : first PoC implementation
This commit is contained in:
parent
4d6977b301
commit
6915213eb1
3 changed files with 81 additions and 3 deletions
|
|
@ -1354,10 +1354,12 @@ bool blockchain_storage::validate_miner_transaction(const block& b,
|
|||
return false;
|
||||
}
|
||||
|
||||
crypto::hash tx_id_for_balance_check = b.miner_tx.version > TRANSACTION_VERSION_PRE_HF4 ? get_transaction_hash(b.miner_tx) : null_hash;
|
||||
if (!check_tx_balance(b.miner_tx, tx_id_for_balance_check, base_reward + fee))
|
||||
uint64_t block_reward = base_reward + fee;
|
||||
|
||||
crypto::hash tx_id_for_post_hf4_era = b.miner_tx.version > TRANSACTION_VERSION_PRE_HF4 ? get_transaction_hash(b.miner_tx) : null_hash;
|
||||
if (!check_tx_balance(b.miner_tx, tx_id_for_post_hf4_era, block_reward))
|
||||
{
|
||||
LOG_ERROR("coinbase transaction balance check failed. Block reward is " << print_money_brief(base_reward + fee) << "(" << print_money(base_reward) << "+" << print_money(fee)
|
||||
LOG_ERROR("coinbase transaction balance check failed. Block reward is " << print_money_brief(block_reward) << "(" << print_money(base_reward) << "+" << print_money(fee)
|
||||
<< ", blocks_size_median = " << blocks_size_median
|
||||
<< ", cumulative_block_size = " << cumulative_block_size
|
||||
<< ", fee = " << fee
|
||||
|
|
@ -1367,6 +1369,15 @@ bool blockchain_storage::validate_miner_transaction(const block& b,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (b.miner_tx.version > TRANSACTION_VERSION_PRE_HF4)
|
||||
{
|
||||
if (!verify_asset_surjection_proof(b.miner_tx, tx_id_for_post_hf4_era))
|
||||
{
|
||||
LOG_ERROR("asset surjection proof verification failed for miner tx");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_PRINT_MAGENTA("Mining tx verification ok, blocks_size_median = " << blocks_size_median, LOG_LEVEL_2);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -5914,6 +5925,9 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt
|
|||
|
||||
CHECK_AND_ASSERT_MES_CUSTOM(check_tx_balance(tx, tx_id), false, cleanup(),
|
||||
"block " << id << ", tx " << tx_id << ": check_tx_balance failed");
|
||||
|
||||
CHECK_AND_ASSERT_MES_CUSTOM(verify_asset_surjection_proof(tx, tx_id), false, cleanup(),
|
||||
"block " << id << ", tx " << tx_id << ": verify_asset_surjection_proof failed");
|
||||
}
|
||||
|
||||
TIME_MEASURE_START_PD(tx_add_one_tx_time);
|
||||
|
|
|
|||
|
|
@ -107,6 +107,69 @@ namespace currency
|
|||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
bool verify_asset_surjection_proof(const transaction& tx, const crypto::hash& tx_id)
|
||||
{
|
||||
bool r = false;
|
||||
if (tx.version <= TRANSACTION_VERSION_PRE_HF4)
|
||||
return true;
|
||||
|
||||
size_t outs_count = tx.vout.size();
|
||||
|
||||
bool has_ZC_inputs = false;
|
||||
bool has_non_ZC_inputs = false;
|
||||
for(const auto& in : tx.vin)
|
||||
{
|
||||
if (in.type() == typeid(txin_zc_input))
|
||||
has_ZC_inputs = true;
|
||||
else
|
||||
has_non_ZC_inputs = true;
|
||||
}
|
||||
|
||||
if (!has_ZC_inputs)
|
||||
{
|
||||
// no ZC ins -- just make sure there's only native outputs with explicit asset ids
|
||||
for(size_t j = 0; j < outs_count; ++j)
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(boost::get<tx_out_zarcanum>(tx.vout[j]).blinded_asset_id == native_coin_asset_id_1div8, false, "output #" << j << " has a non explicitly native asset id");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// tx has ZC inputs
|
||||
const zc_asset_surjection_proof& sig = get_type_in_variant_container_by_ref<const zc_asset_surjection_proof>(tx.proofs); // order of proofs and uniqueness of zc_asset_surjection_proof should be check before on prevalidation
|
||||
CHECK_AND_ASSERT_MES(sig.bge_proofs.size() == outs_count, false, "ASP count: " << sig.bge_proofs.size() << ", outputs: " << outs_count << " => missmatch");
|
||||
|
||||
// make a ring
|
||||
std::vector<crypto::point_t> pseudo_outs_blinded_asset_ids;
|
||||
for(const auto& sig : tx.signatures)
|
||||
{
|
||||
if (sig.type() == typeid(ZC_sig))
|
||||
pseudo_outs_blinded_asset_ids.emplace_back(crypto::point_t(boost::get<ZC_sig>(sig).pseudo_out_blinded_asset_id).modify_mul8());
|
||||
}
|
||||
if (has_non_ZC_inputs)
|
||||
pseudo_outs_blinded_asset_ids.emplace_back(currency::native_coin_asset_id_pt); // additional ring member for txs with non-zc inputs
|
||||
|
||||
for(size_t j = 0; j < outs_count; ++j)
|
||||
{
|
||||
crypto::point_t blinded_asset_id(boost::get<tx_out_zarcanum>(tx.vout[j]).blinded_asset_id);
|
||||
blinded_asset_id.modify_mul8();
|
||||
|
||||
// TODO @#@# remove this redundant conversion to pubkey and back
|
||||
std::vector<crypto::public_key> ring(pseudo_outs_blinded_asset_ids.size());
|
||||
std::vector<const crypto::public_key*> ring_pointers(pseudo_outs_blinded_asset_ids.size());
|
||||
for(size_t i = 0, n = pseudo_outs_blinded_asset_ids.size(); i < n; ++i)
|
||||
{
|
||||
ring[i] = ((crypto::c_scalar_1div8 * (pseudo_outs_blinded_asset_ids[i] - blinded_asset_id)).to_public_key());
|
||||
ring_pointers[i] = &ring[i];
|
||||
}
|
||||
|
||||
uint8_t err = 0;
|
||||
CHECK_AND_ASSERT_MES(crypto::verify_BGE_proof(tx_id, ring_pointers, sig.bge_proofs[j], &err), false, "verify_BGE_proof failed, err = " << (int)err);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
bool generate_zc_outs_range_proof(const crypto::hash& context_hash, size_t out_index_start, const outputs_generation_context& outs_gen_context,
|
||||
const std::vector<tx_out_v>& vouts, zc_outs_range_proof& result)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -230,6 +230,7 @@ namespace currency
|
|||
|
||||
bool verify_multiple_zc_outs_range_proofs(const std::vector<zc_outs_range_proofs_with_commitments>& range_proofs);
|
||||
bool generate_asset_surjection_proof(const crypto::hash& context_hash, bool has_non_zc_inputs, outputs_generation_context& ogc, zc_asset_surjection_proof& result);
|
||||
bool verify_asset_surjection_proof(const transaction& tx, const crypto::hash& tx_id);
|
||||
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, zc_balance_proof& proof);
|
||||
bool generate_zc_outs_range_proof(const crypto::hash& context_hash, size_t out_index_start, const outputs_generation_context& outs_gen_context,
|
||||
const std::vector<tx_out_v>& vouts, zc_outs_range_proof& result);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue