require canonical multi output bulletproof layout
This commit is contained in:
parent
7e67c52fa2
commit
c444b1b229
|
@ -745,6 +745,25 @@ namespace cryptonote
|
||||||
bad_semantics_txes_lock.unlock();
|
bad_semantics_txes_lock.unlock();
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------
|
||||||
|
static bool is_canonical_bulletproof_layout(const std::vector<rct::Bulletproof> &proofs)
|
||||||
|
{
|
||||||
|
size_t n_amounts = rct::n_bulletproof_amounts(proofs), amounts_proved = 0;
|
||||||
|
size_t n = 0;
|
||||||
|
while (amounts_proved < n_amounts)
|
||||||
|
{
|
||||||
|
if (n >= proofs.size())
|
||||||
|
return false;
|
||||||
|
size_t batch_size = 1;
|
||||||
|
while (batch_size * 2 + amounts_proved <= n_amounts && batch_size * 2 <= BULLETPROOF_MAX_OUTPUTS)
|
||||||
|
batch_size *= 2;
|
||||||
|
if (rct::n_bulletproof_amounts(proofs[n]) != batch_size)
|
||||||
|
return false;
|
||||||
|
amounts_proved += batch_size;
|
||||||
|
++n;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------------------------
|
||||||
bool core::handle_incoming_tx_accumulated_batch(std::vector<tx_verification_batch_info> &tx_info, bool keeped_by_block)
|
bool core::handle_incoming_tx_accumulated_batch(std::vector<tx_verification_batch_info> &tx_info, bool keeped_by_block)
|
||||||
{
|
{
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
|
@ -797,6 +816,16 @@ namespace cryptonote
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case rct::RCTTypeBulletproof:
|
case rct::RCTTypeBulletproof:
|
||||||
|
// in addition to valid bulletproofs, we want multi-out
|
||||||
|
// proofs to be in decreasing power of 2 constituents
|
||||||
|
if (!is_canonical_bulletproof_layout(rv.p.bulletproofs))
|
||||||
|
{
|
||||||
|
MERROR_VER("Bulletproof does not use decreasing power of 2 rule");
|
||||||
|
set_semantics_failed(tx_info[n].tx_hash);
|
||||||
|
tx_info[n].tvc.m_verifivation_failed = true;
|
||||||
|
tx_info[n].result = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
rvv.push_back(&rv); // delayed batch verification
|
rvv.push_back(&rv); // delayed batch verification
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -215,14 +215,14 @@ bool gen_bp_tx_valid_1::generate(std::vector<test_event_entry>& events) const
|
||||||
return generate_with(events, out_idx, mixin, 1, amounts_paid, true, multi_out, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_tx_valid_1"); });
|
return generate_with(events, out_idx, mixin, 1, amounts_paid, true, multi_out, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_tx_valid_1"); });
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gen_bp_tx_valid_1_1::generate(std::vector<test_event_entry>& events) const
|
bool gen_bp_tx_invalid_1_1::generate(std::vector<test_event_entry>& events) const
|
||||||
{
|
{
|
||||||
const int mixin = 6;
|
const int mixin = 6;
|
||||||
const int out_idx[] = {1, -1};
|
const int out_idx[] = {1, -1};
|
||||||
const uint64_t amounts_paid[] = {5000, 5000, (uint64_t)-1};
|
const uint64_t amounts_paid[] = {5000, 5000, (uint64_t)-1};
|
||||||
const size_t bp_sizes[] = {1, 1, (size_t)-1};
|
const size_t bp_sizes[] = {1, 1, (size_t)-1};
|
||||||
const bool multi_out[] = {false};
|
const bool multi_out[] = {false};
|
||||||
return generate_with(events, out_idx, mixin, 1, amounts_paid, true, multi_out, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_tx_valid_1_1"); });
|
return generate_with(events, out_idx, mixin, 1, amounts_paid, false, multi_out, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_tx_invalid_1_1"); });
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gen_bp_tx_valid_2::generate(std::vector<test_event_entry>& events) const
|
bool gen_bp_tx_valid_2::generate(std::vector<test_event_entry>& events) const
|
||||||
|
@ -265,13 +265,13 @@ bool gen_bp_txs_valid_2_and_2::generate(std::vector<test_event_entry>& events) c
|
||||||
return generate_with(events, out_idx, mixin, 2, amounts_paid, true, multi_out, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_txs_valid_2_2"); });
|
return generate_with(events, out_idx, mixin, 2, amounts_paid, true, multi_out, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_txs_valid_2_2"); });
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gen_bp_txs_valid_1_1_and_8_2_and_16_16_1::generate(std::vector<test_event_entry>& events) const
|
bool gen_bp_txs_valid_2_and_8_2_and_16_16_1::generate(std::vector<test_event_entry>& events) const
|
||||||
{
|
{
|
||||||
const int mixin = 6;
|
const int mixin = 6;
|
||||||
const int out_idx[] = {1, -1};
|
const int out_idx[] = {1, -1};
|
||||||
const uint64_t amounts_paid[] = {1000, 1000, (uint64_t)-1, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, (uint64_t)-1, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, (uint64_t)-1};
|
const uint64_t amounts_paid[] = {1000, 1000, (uint64_t)-1, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, (uint64_t)-1, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, (uint64_t)-1};
|
||||||
const bool multi_out[] = {false, true, true};
|
const bool multi_out[] = {true, true, true};
|
||||||
const size_t bp_sizes[] = {1, 1, (size_t)-1, 8, 2, (size_t)-1, 16, 16, 1, (size_t)-1};
|
const size_t bp_sizes[] = {2, (size_t)-1, 8, 2, (size_t)-1, 16, 16, 1, (size_t)-1};
|
||||||
return generate_with(events, out_idx, mixin, 3, amounts_paid, true, multi_out, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_txs_valid_1_1_and_8_2_and_16_16_1"); });
|
return generate_with(events, out_idx, mixin, 3, amounts_paid, true, multi_out, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_txs_valid_1_1_and_8_2_and_16_16_1"); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,8 +325,8 @@ bool gen_bp_tx_invalid_switched::generate(std::vector<test_event_entry>& events)
|
||||||
DEFINE_TESTS_ERROR_CONTEXT("gen_bp_tx_invalid_switched");
|
DEFINE_TESTS_ERROR_CONTEXT("gen_bp_tx_invalid_switched");
|
||||||
const int mixin = 6;
|
const int mixin = 6;
|
||||||
const int out_idx[] = {1, -1};
|
const int out_idx[] = {1, -1};
|
||||||
const uint64_t amounts_paid[] = {5000, 5000, (uint64_t)-1};
|
const uint64_t amounts_paid[] = {1001, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, (uint64_t)-1};
|
||||||
const bool multi_out[] = {false};
|
const bool multi_out[] = {true};
|
||||||
return generate_with(events, out_idx, mixin, 1, amounts_paid, false, multi_out, NULL, [&](cryptonote::transaction &tx, size_t tx_idx){
|
return generate_with(events, out_idx, mixin, 1, amounts_paid, false, multi_out, NULL, [&](cryptonote::transaction &tx, size_t tx_idx){
|
||||||
CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeBulletproof);
|
CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeBulletproof);
|
||||||
CHECK_TEST_CONDITION(tx.rct_signatures.p.bulletproofs.size() == 2);
|
CHECK_TEST_CONDITION(tx.rct_signatures.p.bulletproofs.size() == 2);
|
||||||
|
|
|
@ -108,11 +108,11 @@ struct gen_bp_tx_valid_1 : public gen_bp_tx_validation_base
|
||||||
};
|
};
|
||||||
template<> struct get_test_options<gen_bp_tx_valid_1>: public get_test_options<gen_bp_tx_validation_base> {};
|
template<> struct get_test_options<gen_bp_tx_valid_1>: public get_test_options<gen_bp_tx_validation_base> {};
|
||||||
|
|
||||||
struct gen_bp_tx_valid_1_1 : public gen_bp_tx_validation_base
|
struct gen_bp_tx_invalid_1_1 : public gen_bp_tx_validation_base
|
||||||
{
|
{
|
||||||
bool generate(std::vector<test_event_entry>& events) const;
|
bool generate(std::vector<test_event_entry>& events) const;
|
||||||
};
|
};
|
||||||
template<> struct get_test_options<gen_bp_tx_valid_1_1>: public get_test_options<gen_bp_tx_validation_base> {};
|
template<> struct get_test_options<gen_bp_tx_invalid_1_1>: public get_test_options<gen_bp_tx_validation_base> {};
|
||||||
|
|
||||||
struct gen_bp_tx_valid_2 : public gen_bp_tx_validation_base
|
struct gen_bp_tx_valid_2 : public gen_bp_tx_validation_base
|
||||||
{
|
{
|
||||||
|
@ -138,11 +138,11 @@ struct gen_bp_txs_valid_2_and_2 : public gen_bp_tx_validation_base
|
||||||
};
|
};
|
||||||
template<> struct get_test_options<gen_bp_txs_valid_2_and_2>: public get_test_options<gen_bp_tx_validation_base> {};
|
template<> struct get_test_options<gen_bp_txs_valid_2_and_2>: public get_test_options<gen_bp_tx_validation_base> {};
|
||||||
|
|
||||||
struct gen_bp_txs_valid_1_1_and_8_2_and_16_16_1 : public gen_bp_tx_validation_base
|
struct gen_bp_txs_valid_2_and_8_2_and_16_16_1 : public gen_bp_tx_validation_base
|
||||||
{
|
{
|
||||||
bool generate(std::vector<test_event_entry>& events) const;
|
bool generate(std::vector<test_event_entry>& events) const;
|
||||||
};
|
};
|
||||||
template<> struct get_test_options<gen_bp_txs_valid_1_1_and_8_2_and_16_16_1>: public get_test_options<gen_bp_tx_validation_base> {};
|
template<> struct get_test_options<gen_bp_txs_valid_2_and_8_2_and_16_16_1>: public get_test_options<gen_bp_tx_validation_base> {};
|
||||||
|
|
||||||
struct gen_bp_tx_invalid_not_enough_proofs : public gen_bp_tx_validation_base
|
struct gen_bp_tx_invalid_not_enough_proofs : public gen_bp_tx_validation_base
|
||||||
{
|
{
|
||||||
|
|
|
@ -225,12 +225,12 @@ int main(int argc, char* argv[])
|
||||||
GENERATE_AND_PLAY(gen_multisig_tx_invalid_33_1_3_no_threshold);
|
GENERATE_AND_PLAY(gen_multisig_tx_invalid_33_1_3_no_threshold);
|
||||||
|
|
||||||
GENERATE_AND_PLAY(gen_bp_tx_valid_1);
|
GENERATE_AND_PLAY(gen_bp_tx_valid_1);
|
||||||
GENERATE_AND_PLAY(gen_bp_tx_valid_1_1);
|
GENERATE_AND_PLAY(gen_bp_tx_invalid_1_1);
|
||||||
GENERATE_AND_PLAY(gen_bp_tx_valid_2);
|
GENERATE_AND_PLAY(gen_bp_tx_valid_2);
|
||||||
GENERATE_AND_PLAY(gen_bp_tx_valid_4_2_1);
|
GENERATE_AND_PLAY(gen_bp_tx_valid_4_2_1);
|
||||||
GENERATE_AND_PLAY(gen_bp_tx_valid_16_16);
|
GENERATE_AND_PLAY(gen_bp_tx_valid_16_16);
|
||||||
GENERATE_AND_PLAY(gen_bp_txs_valid_2_and_2);
|
GENERATE_AND_PLAY(gen_bp_txs_valid_2_and_2);
|
||||||
GENERATE_AND_PLAY(gen_bp_txs_valid_1_1_and_8_2_and_16_16_1);
|
GENERATE_AND_PLAY(gen_bp_txs_valid_2_and_8_2_and_16_16_1);
|
||||||
GENERATE_AND_PLAY(gen_bp_tx_invalid_not_enough_proofs);
|
GENERATE_AND_PLAY(gen_bp_tx_invalid_not_enough_proofs);
|
||||||
GENERATE_AND_PLAY(gen_bp_tx_invalid_too_many_proofs);
|
GENERATE_AND_PLAY(gen_bp_tx_invalid_too_many_proofs);
|
||||||
GENERATE_AND_PLAY(gen_bp_tx_invalid_wrong_amount);
|
GENERATE_AND_PLAY(gen_bp_tx_invalid_wrong_amount);
|
||||||
|
|
Loading…
Reference in New Issue