mirror of
https://git.wownero.com/wownero/wownero.git
synced 2024-08-15 01:03:23 +00:00
Add view tags to outputs to reduce wallet scanning time
Implements view tags as proposed by @UkoeHB in MRL issue https://github.com/monero-project/research-lab/issues/73 At tx construction, the sender adds a 1-byte view tag to each output. The view tag is derived from the sender-receiver shared secret. When scanning for outputs, the receiver can check the view tag for a match, in order to reduce scanning time. When the view tag does not match, the wallet avoids the more expensive EC operations when deriving the output public key using the shared secret.
This commit is contained in:
parent
6694597974
commit
ea87b30f89
39 changed files with 1165 additions and 230 deletions
|
@ -671,3 +671,127 @@ bool gen_block_low_coinbase::generate(std::vector<test_event_entry>& events) con
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool gen_block_miner_tx_out_has_no_view_tag_before_hf_view_tags::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
bool use_view_tags = false;
|
||||
|
||||
BLOCK_VALIDATION_INIT_GENERATE();
|
||||
|
||||
MAKE_MINER_TX_MANUALLY(miner_tx, blk_0);
|
||||
|
||||
CHECK_AND_ASSERT_MES(!cryptonote::get_output_view_tag(miner_tx.vout[0]), false, "output should not have a view tag");
|
||||
|
||||
crypto::public_key output_public_key;
|
||||
crypto::view_tag view_tag;
|
||||
cryptonote::get_output_public_key(miner_tx.vout[0], output_public_key);
|
||||
|
||||
// explicitly call the setter to ensure it does not set a view tag on the miner tx output
|
||||
cryptonote::set_tx_out(miner_tx.vout[0].amount, output_public_key, use_view_tags, view_tag, miner_tx.vout[0]);
|
||||
CHECK_AND_ASSERT_MES(!cryptonote::get_output_view_tag(miner_tx.vout[0]), false, "output should still not have a view tag");
|
||||
|
||||
block blk_1;
|
||||
generator.construct_block_manually(blk_1, blk_0, miner_account, test_generator::bf_miner_tx, 0, 0, 0, crypto::hash(), 0, miner_tx);
|
||||
events.push_back(blk_1);
|
||||
|
||||
DO_CALLBACK(events, "check_block_accepted");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool gen_block_miner_tx_out_has_no_view_tag_from_hf_view_tags::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
bool use_view_tags = false;
|
||||
|
||||
BLOCK_VALIDATION_INIT_GENERATE();
|
||||
|
||||
keypair txkey;
|
||||
MAKE_MINER_TX_AND_KEY_AT_HF_MANUALLY(miner_tx, blk_0, HF_VERSION_VIEW_TAGS+1, &txkey);
|
||||
|
||||
crypto::public_key output_public_key;
|
||||
crypto::view_tag view_tag;
|
||||
cryptonote::get_output_public_key(miner_tx.vout[0], output_public_key);
|
||||
|
||||
// remove the view tag that is currently set on the miner tx output at this point
|
||||
cryptonote::set_tx_out(miner_tx.vout[0].amount, output_public_key, use_view_tags, view_tag, miner_tx.vout[0]);
|
||||
CHECK_AND_ASSERT_MES(!cryptonote::get_output_view_tag(miner_tx.vout[0]), false, "output should not have a view tag");
|
||||
|
||||
block blk_1;
|
||||
generator.construct_block_manually(blk_1, blk_0, miner_account,
|
||||
test_generator::bf_major_ver | test_generator::bf_minor_ver | test_generator::bf_miner_tx,
|
||||
HF_VERSION_VIEW_TAGS+1, HF_VERSION_VIEW_TAGS+1, 0, crypto::hash(), 0, miner_tx);
|
||||
events.push_back(blk_1);
|
||||
|
||||
DO_CALLBACK(events, "check_block_purged");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool gen_block_miner_tx_out_has_view_tag_before_hf_view_tags::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
bool use_view_tags = true;
|
||||
|
||||
BLOCK_VALIDATION_INIT_GENERATE();
|
||||
|
||||
keypair txkey;
|
||||
MAKE_MINER_TX_AND_KEY_MANUALLY(miner_tx, blk_0, &txkey);
|
||||
|
||||
// derive the view tag for the miner tx output
|
||||
crypto::key_derivation derivation;
|
||||
crypto::public_key output_public_key;
|
||||
crypto::view_tag view_tag;
|
||||
crypto::generate_key_derivation(miner_account.get_keys().m_account_address.m_view_public_key, txkey.sec, derivation);
|
||||
crypto::derive_public_key(derivation, 0, miner_account.get_keys().m_account_address.m_spend_public_key, output_public_key);
|
||||
crypto::derive_view_tag(derivation, 0, view_tag);
|
||||
|
||||
// set the view tag on the miner tx output
|
||||
cryptonote::set_tx_out(miner_tx.vout[0].amount, output_public_key, use_view_tags, view_tag, miner_tx.vout[0]);
|
||||
boost::optional<crypto::view_tag> actual_vt = cryptonote::get_output_view_tag(miner_tx.vout[0]);
|
||||
CHECK_AND_ASSERT_MES(actual_vt && *actual_vt == view_tag, false, "unexpected output view tag");
|
||||
|
||||
block blk_1;
|
||||
generator.construct_block_manually(blk_1, blk_0, miner_account, test_generator::bf_miner_tx, 0, 0, 0, crypto::hash(), 0, miner_tx);
|
||||
events.push_back(blk_1);
|
||||
|
||||
DO_CALLBACK(events, "check_block_purged");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool gen_block_miner_tx_out_has_view_tag_from_hf_view_tags::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
bool use_view_tags = true;
|
||||
|
||||
BLOCK_VALIDATION_INIT_GENERATE();
|
||||
|
||||
keypair txkey;
|
||||
MAKE_MINER_TX_AND_KEY_AT_HF_MANUALLY(miner_tx, blk_0, HF_VERSION_VIEW_TAGS, &txkey);
|
||||
|
||||
CHECK_AND_ASSERT_MES(cryptonote::get_output_view_tag(miner_tx.vout[0]), false, "output should have a view tag");
|
||||
|
||||
// derive the view tag for the miner tx output
|
||||
crypto::key_derivation derivation;
|
||||
crypto::public_key output_public_key;
|
||||
crypto::view_tag view_tag;
|
||||
crypto::generate_key_derivation(miner_account.get_keys().m_account_address.m_view_public_key, txkey.sec, derivation);
|
||||
crypto::derive_public_key(derivation, 0, miner_account.get_keys().m_account_address.m_spend_public_key, output_public_key);
|
||||
crypto::derive_view_tag(derivation, 0, view_tag);
|
||||
|
||||
boost::optional<crypto::view_tag> actual_vt = cryptonote::get_output_view_tag(miner_tx.vout[0]);
|
||||
CHECK_AND_ASSERT_MES(actual_vt && *actual_vt == view_tag, false, "unexpected output view tag");
|
||||
|
||||
// set the view tag on the miner tx output
|
||||
cryptonote::set_tx_out(miner_tx.vout[0].amount, output_public_key, use_view_tags, view_tag, miner_tx.vout[0]);
|
||||
boost::optional<crypto::view_tag> actual_vt_after_setting = cryptonote::get_output_view_tag(miner_tx.vout[0]);
|
||||
CHECK_AND_ASSERT_MES(actual_vt_after_setting && *actual_vt_after_setting == view_tag, false, "unexpected output view tag after setting");
|
||||
|
||||
block blk_1;
|
||||
generator.construct_block_manually(blk_1, blk_0, miner_account,
|
||||
test_generator::bf_major_ver | test_generator::bf_minor_ver | test_generator::bf_miner_tx,
|
||||
HF_VERSION_VIEW_TAGS, HF_VERSION_VIEW_TAGS, 0, crypto::hash(), 0, miner_tx);
|
||||
events.push_back(blk_1);
|
||||
|
||||
DO_CALLBACK(events, "check_block_accepted");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -230,3 +230,37 @@ struct get_test_options<gen_block_low_coinbase> {
|
|||
hard_forks, 0
|
||||
};
|
||||
};
|
||||
|
||||
struct gen_block_miner_tx_out_has_no_view_tag_before_hf_view_tags : public gen_block_accepted_base<2>
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
|
||||
struct gen_block_miner_tx_out_has_no_view_tag_from_hf_view_tags : public gen_block_verification_base<1>
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
template<>
|
||||
struct get_test_options<gen_block_miner_tx_out_has_no_view_tag_from_hf_view_tags> {
|
||||
const std::pair<uint8_t, uint64_t> hard_forks[3] = {std::make_pair(1, 0), std::make_pair(HF_VERSION_VIEW_TAGS+1, 1), std::make_pair(0, 0)};
|
||||
const cryptonote::test_options test_options = {
|
||||
hard_forks, 0
|
||||
};
|
||||
};
|
||||
|
||||
struct gen_block_miner_tx_out_has_view_tag_before_hf_view_tags : public gen_block_verification_base<1>
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
|
||||
struct gen_block_miner_tx_out_has_view_tag_from_hf_view_tags : public gen_block_accepted_base<2>
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
template<>
|
||||
struct get_test_options<gen_block_miner_tx_out_has_view_tag_from_hf_view_tags> {
|
||||
const std::pair<uint8_t, uint64_t> hard_forks[3] = {std::make_pair(1, 0), std::make_pair(HF_VERSION_VIEW_TAGS, 1), std::make_pair(0, 0)};
|
||||
const cryptonote::test_options test_options = {
|
||||
hard_forks, 0
|
||||
};
|
||||
};
|
||||
|
|
|
@ -462,7 +462,9 @@ bool init_output_indices(map_output_idx_t& outs, std::map<uint64_t, std::vector<
|
|||
size_t tx_global_idx = outs[out.amount].size() - 1;
|
||||
outs[out.amount][tx_global_idx].idx = tx_global_idx;
|
||||
// Is out to me?
|
||||
if (is_out_to_acc(from.get_keys(), boost::get<txout_to_key>(out.target), get_tx_pub_key_from_extra(tx), get_additional_tx_pub_keys_from_extra(tx), j)) {
|
||||
crypto::public_key output_public_key;
|
||||
cryptonote::get_output_public_key(out, output_public_key);
|
||||
if (is_out_to_acc(from.get_keys(), output_public_key, get_tx_pub_key_from_extra(tx), get_additional_tx_pub_keys_from_extra(tx), j)) {
|
||||
outs_mine[out.amount].push_back(tx_global_idx);
|
||||
}
|
||||
}
|
||||
|
@ -972,7 +974,7 @@ std::vector<cryptonote::tx_destination_entry> build_dsts(std::initializer_list<d
|
|||
|
||||
bool construct_miner_tx_manually(size_t height, uint64_t already_generated_coins,
|
||||
const account_public_address& miner_address, transaction& tx, uint64_t fee,
|
||||
keypair* p_txkey/* = 0*/)
|
||||
uint8_t hf_version/* = 1*/, keypair* p_txkey/* = 0*/)
|
||||
{
|
||||
keypair txkey;
|
||||
txkey = keypair::generate(hw::get_device("default"));
|
||||
|
@ -987,7 +989,7 @@ bool construct_miner_tx_manually(size_t height, uint64_t already_generated_coins
|
|||
|
||||
// This will work, until size of constructed block is less then CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE
|
||||
uint64_t block_reward;
|
||||
if (!get_block_reward(0, 0, already_generated_coins, block_reward, 1))
|
||||
if (!get_block_reward(0, 0, already_generated_coins, block_reward, hf_version))
|
||||
{
|
||||
LOG_PRINT_L0("Block is too big");
|
||||
return false;
|
||||
|
@ -999,12 +1001,20 @@ bool construct_miner_tx_manually(size_t height, uint64_t already_generated_coins
|
|||
crypto::generate_key_derivation(miner_address.m_view_public_key, txkey.sec, derivation);
|
||||
crypto::derive_public_key(derivation, 0, miner_address.m_spend_public_key, out_eph_public_key);
|
||||
|
||||
bool use_view_tags = hf_version >= HF_VERSION_VIEW_TAGS;
|
||||
crypto::view_tag view_tag;
|
||||
if (use_view_tags)
|
||||
crypto::derive_view_tag(derivation, 0, view_tag);
|
||||
|
||||
tx_out out;
|
||||
out.amount = block_reward;
|
||||
out.target = txout_to_key(out_eph_public_key);
|
||||
cryptonote::set_tx_out(block_reward, out_eph_public_key, use_view_tags, view_tag, out);
|
||||
|
||||
tx.vout.push_back(out);
|
||||
|
||||
tx.version = 1;
|
||||
if (hf_version >= HF_VERSION_DYNAMIC_FEE)
|
||||
tx.version = 2;
|
||||
else
|
||||
tx.version = 1;
|
||||
tx.unlock_time = height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW;
|
||||
|
||||
return true;
|
||||
|
|
|
@ -423,7 +423,8 @@ uint64_t sum_amount(const std::vector<cryptonote::tx_source_entry>& sources);
|
|||
|
||||
bool construct_miner_tx_manually(size_t height, uint64_t already_generated_coins,
|
||||
const cryptonote::account_public_address& miner_address, cryptonote::transaction& tx,
|
||||
uint64_t fee, cryptonote::keypair* p_txkey = nullptr);
|
||||
uint64_t fee, uint8_t hf_version = 1,
|
||||
cryptonote::keypair* p_txkey = nullptr);
|
||||
|
||||
bool construct_tx_to_key(const std::vector<test_event_entry>& events, cryptonote::transaction& tx,
|
||||
const cryptonote::block& blk_head, const cryptonote::account_base& from, const var_addr_t& to, uint64_t amount,
|
||||
|
@ -967,12 +968,14 @@ inline bool do_replay_file(const std::string& filename)
|
|||
std::list<cryptonote::transaction> SET_NAME; \
|
||||
MAKE_TX_MIX_LIST_RCT(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, NMIX, HEAD);
|
||||
|
||||
#define MAKE_MINER_TX_AND_KEY_MANUALLY(TX, BLK, KEY) \
|
||||
#define MAKE_MINER_TX_AND_KEY_AT_HF_MANUALLY(TX, BLK, HF_VERSION, KEY) \
|
||||
transaction TX; \
|
||||
if (!construct_miner_tx_manually(get_block_height(BLK) + 1, generator.get_already_generated_coins(BLK), \
|
||||
miner_account.get_keys().m_account_address, TX, 0, KEY)) \
|
||||
miner_account.get_keys().m_account_address, TX, 0, HF_VERSION, KEY)) \
|
||||
return false;
|
||||
|
||||
#define MAKE_MINER_TX_AND_KEY_MANUALLY(TX, BLK, KEY) MAKE_MINER_TX_AND_KEY_AT_HF_MANUALLY(TX, BLK, 1, KEY)
|
||||
|
||||
#define MAKE_MINER_TX_MANUALLY(TX, BLK) MAKE_MINER_TX_AND_KEY_MANUALLY(TX, BLK, 0)
|
||||
|
||||
#define SET_EVENT_VISITOR_SETT(VEC_EVENTS, SETT) VEC_EVENTS.push_back(event_visitor_settings(SETT));
|
||||
|
|
|
@ -133,6 +133,10 @@ int main(int argc, char* argv[])
|
|||
GENERATE_AND_PLAY(gen_block_miner_tx_out_is_big);
|
||||
GENERATE_AND_PLAY(gen_block_miner_tx_has_no_out);
|
||||
GENERATE_AND_PLAY(gen_block_miner_tx_has_out_to_alice);
|
||||
GENERATE_AND_PLAY(gen_block_miner_tx_out_has_no_view_tag_before_hf_view_tags);
|
||||
GENERATE_AND_PLAY(gen_block_miner_tx_out_has_no_view_tag_from_hf_view_tags);
|
||||
GENERATE_AND_PLAY(gen_block_miner_tx_out_has_view_tag_before_hf_view_tags);
|
||||
GENERATE_AND_PLAY(gen_block_miner_tx_out_has_view_tag_from_hf_view_tags);
|
||||
GENERATE_AND_PLAY(gen_block_has_invalid_tx);
|
||||
GENERATE_AND_PLAY(gen_block_is_too_big);
|
||||
GENERATE_AND_PLAY(gen_block_invalid_binary_format); // Takes up to 3 hours, if CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW == 500, up to 30 minutes, if CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW == 10
|
||||
|
@ -219,6 +223,15 @@ int main(int argc, char* argv[])
|
|||
GENERATE_AND_PLAY(gen_rct_tx_pre_rct_increase_vin_and_fee);
|
||||
GENERATE_AND_PLAY(gen_rct_tx_pre_rct_altered_extra);
|
||||
GENERATE_AND_PLAY(gen_rct_tx_rct_altered_extra);
|
||||
GENERATE_AND_PLAY(gen_rct_tx_pre_rct_has_no_view_tag_before_hf_view_tags);
|
||||
// TODO: base test needs to be restructured to handle pre rct outputs after HF v12
|
||||
// GENERATE_AND_PLAY(gen_rct_tx_pre_rct_has_no_view_tag_from_hf_view_tags);
|
||||
GENERATE_AND_PLAY(gen_rct_tx_pre_rct_has_view_tag_before_hf_view_tags);
|
||||
// GENERATE_AND_PLAY(gen_rct_tx_pre_rct_has_view_tag_from_hf_view_tags);
|
||||
GENERATE_AND_PLAY(gen_rct_tx_rct_has_no_view_tag_before_hf_view_tags);
|
||||
GENERATE_AND_PLAY(gen_rct_tx_rct_has_no_view_tag_from_hf_view_tags);
|
||||
GENERATE_AND_PLAY(gen_rct_tx_rct_has_view_tag_before_hf_view_tags);
|
||||
GENERATE_AND_PLAY(gen_rct_tx_rct_has_view_tag_from_hf_view_tags);
|
||||
GENERATE_AND_PLAY(gen_rct_tx_uses_output_too_early);
|
||||
|
||||
GENERATE_AND_PLAY(gen_multisig_tx_valid_22_1_2);
|
||||
|
|
|
@ -41,7 +41,7 @@ using namespace cryptonote;
|
|||
// Tests
|
||||
|
||||
bool gen_rct_tx_validation_base::generate_with_full(std::vector<test_event_entry>& events,
|
||||
const int *out_idx, int mixin, uint64_t amount_paid, size_t second_rewind, uint8_t last_version, const rct::RCTConfig &rct_config, bool valid,
|
||||
const int *out_idx, int mixin, uint64_t amount_paid, size_t second_rewind, uint8_t last_version, const rct::RCTConfig &rct_config, bool use_view_tags, bool valid,
|
||||
const std::function<void(std::vector<tx_source_entry> &sources, std::vector<tx_destination_entry> &destinations)> &pre_tx,
|
||||
const std::function<void(transaction &tx)> &post_tx) const
|
||||
{
|
||||
|
@ -98,7 +98,9 @@ bool gen_rct_tx_validation_base::generate_with_full(std::vector<test_event_entry
|
|||
const size_t index_in_tx = 5;
|
||||
src.amount = 30000000000000;
|
||||
for (int m = 0; m < 4; ++m) {
|
||||
src.push_output(m, boost::get<txout_to_key>(blocks[m].miner_tx.vout[index_in_tx].target).key, src.amount);
|
||||
crypto::public_key output_public_key;
|
||||
cryptonote::get_output_public_key(blocks[m].miner_tx.vout[index_in_tx], output_public_key);
|
||||
src.push_output(m, output_public_key, src.amount);
|
||||
}
|
||||
src.real_out_tx_key = cryptonote::get_tx_pub_key_from_extra(blocks[n].miner_tx);
|
||||
src.real_output = n;
|
||||
|
@ -139,10 +141,13 @@ bool gen_rct_tx_validation_base::generate_with_full(std::vector<test_event_entry
|
|||
rct::decodeRct(rct_txes[n].rct_signatures, rct::sk2rct(amount_key), o, rct_tx_masks[o+n*4], hw::get_device("default"));
|
||||
}
|
||||
|
||||
uint64_t fee = 0;
|
||||
get_tx_fee(rct_txes[n], fee);
|
||||
|
||||
CHECK_AND_ASSERT_MES(generator.construct_block_manually(blk_txes[n], blk_last, miner_account,
|
||||
test_generator::bf_major_ver | test_generator::bf_minor_ver | test_generator::bf_timestamp | test_generator::bf_tx_hashes | test_generator::bf_hf_version | test_generator::bf_max_outs,
|
||||
test_generator::bf_major_ver | test_generator::bf_minor_ver | test_generator::bf_timestamp | test_generator::bf_tx_hashes | test_generator::bf_hf_version | test_generator::bf_max_outs | test_generator::bf_tx_fees,
|
||||
4, 4, blk_last.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long
|
||||
crypto::hash(), 0, transaction(), starting_rct_tx_hashes, 0, 6, 4),
|
||||
crypto::hash(), 0, transaction(), starting_rct_tx_hashes, 0, 6, 4, fee),
|
||||
false, "Failed to generate block");
|
||||
events.push_back(blk_txes[n]);
|
||||
blk_last = blk_txes[n];
|
||||
|
@ -224,7 +229,7 @@ bool gen_rct_tx_validation_base::generate_with_full(std::vector<test_event_entry
|
|||
std::vector<crypto::secret_key> additional_tx_keys;
|
||||
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
|
||||
subaddresses[miner_accounts[0].get_keys().m_account_address.m_spend_public_key] = {0,0};
|
||||
bool r = construct_tx_and_get_tx_key(miner_accounts[0].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), tx, 0, tx_key, additional_tx_keys, true, rct_config);
|
||||
bool r = construct_tx_and_get_tx_key(miner_accounts[0].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), tx, 0, tx_key, additional_tx_keys, true, rct_config, NULL, use_view_tags);
|
||||
CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction");
|
||||
|
||||
if (post_tx)
|
||||
|
@ -244,7 +249,8 @@ bool gen_rct_tx_validation_base::generate_with(std::vector<test_event_entry>& ev
|
|||
const std::function<void(transaction &tx)> &post_tx) const
|
||||
{
|
||||
const rct::RCTConfig rct_config { rct::RangeProofBorromean, 0 };
|
||||
return generate_with_full(events, out_idx, mixin, amount_paid, CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE, 4, rct_config, valid, pre_tx, post_tx);
|
||||
bool use_view_tags = false;
|
||||
return generate_with_full(events, out_idx, mixin, amount_paid, CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE, 4, rct_config, use_view_tags, valid, pre_tx, post_tx);
|
||||
}
|
||||
|
||||
bool gen_rct_tx_valid_from_pre_rct::generate(std::vector<test_event_entry>& events) const
|
||||
|
@ -517,11 +523,99 @@ bool gen_rct_tx_rct_altered_extra::generate(std::vector<test_event_entry>& event
|
|||
NULL, [&failed](transaction &tx) {std::string extra_nonce; crypto::hash pid = crypto::null_hash; set_payment_id_to_tx_extra_nonce(extra_nonce, pid); if (!add_extra_nonce_to_tx_extra(tx.extra, extra_nonce)) failed = true; }) && !failed;
|
||||
}
|
||||
|
||||
bool gen_rct_tx_pre_rct_has_no_view_tag_before_hf_view_tags::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
const int mixin = 2;
|
||||
const int out_idx[] = {0, -1};
|
||||
const uint64_t amount_paid = 10000;
|
||||
bool use_view_tags = false;
|
||||
bool valid = true;
|
||||
return generate_with_full(events, out_idx, mixin, amount_paid, 0, 0, {}, use_view_tags, valid, NULL, NULL);
|
||||
}
|
||||
|
||||
bool gen_rct_tx_pre_rct_has_no_view_tag_from_hf_view_tags::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
const int mixin = 10;
|
||||
const int out_idx[] = {0, -1};
|
||||
const uint64_t amount_paid = 10000;
|
||||
const rct::RCTConfig rct_config { rct::RangeProofPaddedBulletproof, 3 };
|
||||
bool use_view_tags = false;
|
||||
bool valid = false;
|
||||
return generate_with_full(events, out_idx, mixin, amount_paid, CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE, HF_VERSION_VIEW_TAGS, rct_config, use_view_tags, valid, NULL, NULL);
|
||||
}
|
||||
|
||||
bool gen_rct_tx_pre_rct_has_view_tag_before_hf_view_tags::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
const int mixin = 2;
|
||||
const int out_idx[] = {0, -1};
|
||||
const uint64_t amount_paid = 10000;
|
||||
bool use_view_tags = true;
|
||||
bool valid = false;
|
||||
return generate_with_full(events, out_idx, mixin, amount_paid, 0, 0, {}, use_view_tags, valid, NULL, NULL);
|
||||
}
|
||||
|
||||
bool gen_rct_tx_pre_rct_has_view_tag_from_hf_view_tags::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
const int mixin = 10;
|
||||
const int out_idx[] = {0, -1};
|
||||
const uint64_t amount_paid = 10000;
|
||||
const rct::RCTConfig rct_config { rct::RangeProofPaddedBulletproof, 3 };
|
||||
bool use_view_tags = true;
|
||||
bool valid = true;
|
||||
return generate_with_full(events, out_idx, mixin, amount_paid, CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE, HF_VERSION_VIEW_TAGS, rct_config, use_view_tags, valid, NULL, NULL);
|
||||
}
|
||||
|
||||
bool gen_rct_tx_rct_has_no_view_tag_before_hf_view_tags::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
const int mixin = 2;
|
||||
const int out_idx[] = {1, -1};
|
||||
const uint64_t amount_paid = 10000;
|
||||
const rct::RCTConfig rct_config { rct::RangeProofBorromean, 0 };
|
||||
bool use_view_tags = false;
|
||||
bool valid = true;
|
||||
return generate_with_full(events, out_idx, mixin, amount_paid, 0, 0, rct_config, use_view_tags, valid, NULL, NULL);
|
||||
}
|
||||
|
||||
bool gen_rct_tx_rct_has_no_view_tag_from_hf_view_tags::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
const int mixin = 10;
|
||||
const int out_idx[] = {1, -1};
|
||||
const uint64_t amount_paid = 10000;
|
||||
const rct::RCTConfig rct_config { rct::RangeProofPaddedBulletproof, 3 };
|
||||
bool use_view_tags = false;
|
||||
bool valid = false;
|
||||
return generate_with_full(events, out_idx, mixin, amount_paid, CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE, HF_VERSION_VIEW_TAGS+1, rct_config, use_view_tags, valid, NULL, NULL);
|
||||
}
|
||||
|
||||
bool gen_rct_tx_rct_has_view_tag_before_hf_view_tags::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
const int mixin = 2;
|
||||
const int out_idx[] = {1, -1};
|
||||
const uint64_t amount_paid = 10000;
|
||||
const rct::RCTConfig rct_config { rct::RangeProofBorromean, 0 };
|
||||
bool use_view_tags = true;
|
||||
bool valid = false;
|
||||
return generate_with_full(events, out_idx, mixin, amount_paid, 0, 0, rct_config, use_view_tags, valid, NULL, NULL);
|
||||
}
|
||||
|
||||
bool gen_rct_tx_rct_has_view_tag_from_hf_view_tags::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
const int mixin = 10;
|
||||
const int out_idx[] = {1, -1};
|
||||
const uint64_t amount_paid = 10000;
|
||||
const rct::RCTConfig rct_config { rct::RangeProofPaddedBulletproof, 3 };
|
||||
bool use_view_tags = true;
|
||||
bool valid = true;
|
||||
return generate_with_full(events, out_idx, mixin, amount_paid, CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE, HF_VERSION_VIEW_TAGS, rct_config, use_view_tags, valid, NULL, NULL);
|
||||
}
|
||||
|
||||
bool gen_rct_tx_uses_output_too_early::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
const int mixin = 10;
|
||||
const int out_idx[] = {1, -1};
|
||||
const uint64_t amount_paid = 10000;
|
||||
const rct::RCTConfig rct_config { rct::RangeProofPaddedBulletproof, 2 };
|
||||
return generate_with_full(events, out_idx, mixin, amount_paid, CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE-3, HF_VERSION_ENFORCE_MIN_AGE, rct_config, false, NULL, NULL);
|
||||
bool use_view_tags = false;
|
||||
bool valid = false;
|
||||
return generate_with_full(events, out_idx, mixin, amount_paid, CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE-3, HF_VERSION_ENFORCE_MIN_AGE, rct_config, use_view_tags, valid, NULL, NULL);
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ struct gen_rct_tx_validation_base : public test_chain_unit_base
|
|||
}
|
||||
|
||||
bool generate_with_full(std::vector<test_event_entry>& events, const int *out_idx, int mixin,
|
||||
uint64_t amount_paid, size_t second_rewind, uint8_t last_version, const rct::RCTConfig &rct_config, bool valid,
|
||||
uint64_t amount_paid, size_t second_rewind, uint8_t last_version, const rct::RCTConfig &rct_config, bool use_view_tags, bool valid,
|
||||
const std::function<void(std::vector<cryptonote::tx_source_entry> &sources, std::vector<cryptonote::tx_destination_entry> &destinations)> &pre_tx,
|
||||
const std::function<void(cryptonote::transaction &tx)> &post_tx) const;
|
||||
bool generate_with(std::vector<test_event_entry>& events, const int *out_idx, int mixin,
|
||||
|
@ -266,6 +266,74 @@ struct gen_rct_tx_rct_altered_extra : public gen_rct_tx_validation_base
|
|||
};
|
||||
template<> struct get_test_options<gen_rct_tx_rct_altered_extra>: public get_test_options<gen_rct_tx_validation_base> {};
|
||||
|
||||
struct gen_rct_tx_pre_rct_has_no_view_tag_before_hf_view_tags : public gen_rct_tx_validation_base
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
template<> struct get_test_options<gen_rct_tx_pre_rct_has_no_view_tag_before_hf_view_tags>: public get_test_options<gen_rct_tx_validation_base> {};
|
||||
|
||||
struct gen_rct_tx_pre_rct_has_no_view_tag_from_hf_view_tags : public gen_rct_tx_validation_base
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
template<> struct get_test_options<gen_rct_tx_pre_rct_has_no_view_tag_from_hf_view_tags> {
|
||||
const std::pair<uint8_t, uint64_t> hard_forks[5] = {std::make_pair(1, 0), std::make_pair(2, 1), std::make_pair(4, 65), std::make_pair(HF_VERSION_VIEW_TAGS, 69), std::make_pair(0, 0)};
|
||||
const cryptonote::test_options test_options = {
|
||||
hard_forks, 0
|
||||
};
|
||||
};
|
||||
|
||||
struct gen_rct_tx_pre_rct_has_view_tag_before_hf_view_tags : public gen_rct_tx_validation_base
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
template<> struct get_test_options<gen_rct_tx_pre_rct_has_view_tag_before_hf_view_tags>: public get_test_options<gen_rct_tx_validation_base> {};
|
||||
|
||||
struct gen_rct_tx_pre_rct_has_view_tag_from_hf_view_tags : public gen_rct_tx_validation_base
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
template<> struct get_test_options<gen_rct_tx_pre_rct_has_view_tag_from_hf_view_tags> {
|
||||
const std::pair<uint8_t, uint64_t> hard_forks[5] = {std::make_pair(1, 0), std::make_pair(2, 1), std::make_pair(4, 65), std::make_pair(HF_VERSION_VIEW_TAGS, 69), std::make_pair(0, 0)};
|
||||
const cryptonote::test_options test_options = {
|
||||
hard_forks, 0
|
||||
};
|
||||
};
|
||||
|
||||
struct gen_rct_tx_rct_has_no_view_tag_before_hf_view_tags : public gen_rct_tx_validation_base
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
template<> struct get_test_options<gen_rct_tx_rct_has_no_view_tag_before_hf_view_tags>: public get_test_options<gen_rct_tx_validation_base> {};
|
||||
|
||||
struct gen_rct_tx_rct_has_no_view_tag_from_hf_view_tags : public gen_rct_tx_validation_base
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
template<> struct get_test_options<gen_rct_tx_rct_has_no_view_tag_from_hf_view_tags> {
|
||||
const std::pair<uint8_t, uint64_t> hard_forks[5] = {std::make_pair(1, 0), std::make_pair(2, 1), std::make_pair(4, 65), std::make_pair(HF_VERSION_VIEW_TAGS+1, 69), std::make_pair(0, 0)};
|
||||
const cryptonote::test_options test_options = {
|
||||
hard_forks, 0
|
||||
};
|
||||
};
|
||||
|
||||
struct gen_rct_tx_rct_has_view_tag_before_hf_view_tags : public gen_rct_tx_validation_base
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
template<> struct get_test_options<gen_rct_tx_rct_has_view_tag_before_hf_view_tags>: public get_test_options<gen_rct_tx_validation_base> {};
|
||||
|
||||
struct gen_rct_tx_rct_has_view_tag_from_hf_view_tags : public gen_rct_tx_validation_base
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
template<> struct get_test_options<gen_rct_tx_rct_has_view_tag_from_hf_view_tags> {
|
||||
const std::pair<uint8_t, uint64_t> hard_forks[5] = {std::make_pair(1, 0), std::make_pair(2, 1), std::make_pair(4, 65), std::make_pair(HF_VERSION_VIEW_TAGS, 69), std::make_pair(0, 0)};
|
||||
const cryptonote::test_options test_options = {
|
||||
hard_forks, 0
|
||||
};
|
||||
};
|
||||
|
||||
struct gen_rct_tx_uses_output_too_early : public gen_rct_tx_validation_base
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue