mirror of
https://github.com/monero-project/monero.git
synced 2025-08-07 09:22:19 -04: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
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue