aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/core_tests/block_validation.cpp124
-rw-r--r--tests/core_tests/block_validation.h34
-rw-r--r--tests/core_tests/chaingen.cpp22
-rw-r--r--tests/core_tests/chaingen.h9
-rw-r--r--tests/core_tests/chaingen_main.cpp13
-rw-r--r--tests/core_tests/rct.cpp108
-rw-r--r--tests/core_tests/rct.h70
-rw-r--r--tests/crypto/main.cpp10
-rw-r--r--tests/crypto/tests.txt56
-rwxr-xr-xtests/functional_tests/blockchain.py8
-rwxr-xr-xtests/functional_tests/cold_signing.py4
-rw-r--r--tests/functional_tests/main.cpp2
-rwxr-xr-xtests/functional_tests/multisig.py4
-rwxr-xr-xtests/functional_tests/transfer.py16
-rw-r--r--tests/performance_tests/CMakeLists.txt1
-rw-r--r--tests/performance_tests/derive_view_tag.h62
-rw-r--r--tests/performance_tests/is_out_to_acc.h5
-rw-r--r--tests/performance_tests/main.cpp6
-rw-r--r--tests/performance_tests/out_can_be_to_acc.h103
-rw-r--r--tests/unit_tests/CMakeLists.txt1
-rw-r--r--tests/unit_tests/epee_utils.cpp1
-rw-r--r--tests/unit_tests/rolling_median.cpp18
-rw-r--r--tests/unit_tests/scaling_2021.cpp187
23 files changed, 827 insertions, 37 deletions
diff --git a/tests/core_tests/block_validation.cpp b/tests/core_tests/block_validation.cpp
index 28f1de7d0..711f67b41 100644
--- a/tests/core_tests/block_validation.cpp
+++ b/tests/core_tests/block_validation.cpp
@@ -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;
+}
diff --git a/tests/core_tests/block_validation.h b/tests/core_tests/block_validation.h
index 2535039fb..3a157aaa9 100644
--- a/tests/core_tests/block_validation.h
+++ b/tests/core_tests/block_validation.h
@@ -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
+ };
+};
diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp
index 689b6801b..61195c7b0 100644
--- a/tests/core_tests/chaingen.cpp
+++ b/tests/core_tests/chaingen.cpp
@@ -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;
diff --git a/tests/core_tests/chaingen.h b/tests/core_tests/chaingen.h
index c1e592b86..5c8c9f79f 100644
--- a/tests/core_tests/chaingen.h
+++ b/tests/core_tests/chaingen.h
@@ -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));
diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp
index 2e2d170ff..b89dff445 100644
--- a/tests/core_tests/chaingen_main.cpp
+++ b/tests/core_tests/chaingen_main.cpp
@@ -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);
diff --git a/tests/core_tests/rct.cpp b/tests/core_tests/rct.cpp
index 3a26de4c2..0926483fe 100644
--- a/tests/core_tests/rct.cpp
+++ b/tests/core_tests/rct.cpp
@@ -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);
}
diff --git a/tests/core_tests/rct.h b/tests/core_tests/rct.h
index dee074e4c..c20e8a580 100644
--- a/tests/core_tests/rct.h
+++ b/tests/core_tests/rct.h
@@ -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;
diff --git a/tests/crypto/main.cpp b/tests/crypto/main.cpp
index 59a2a7d77..045ffc08d 100644
--- a/tests/crypto/main.cpp
+++ b/tests/crypto/main.cpp
@@ -260,7 +260,6 @@ int main(int argc, char *argv[]) {
goto error;
}
} else if (cmd == "check_ge_p3_identity") {
- cerr << "Testing: " << cmd << endl;
public_key point;
bool expected_bad, expected_good, result_badfunc, result_goodfunc;
get(input, point, expected_bad, expected_good);
@@ -269,6 +268,15 @@ int main(int argc, char *argv[]) {
if (expected_bad != result_badfunc || expected_good != result_goodfunc) {
goto error;
}
+ } else if (cmd == "derive_view_tag") {
+ key_derivation derivation;
+ size_t output_index;
+ view_tag expected, actual;
+ get(input, derivation, output_index, expected);
+ derive_view_tag(derivation, output_index, actual);
+ if (expected != actual) {
+ goto error;
+ }
} else {
throw ios_base::failure("Unknown function: " + cmd);
}
diff --git a/tests/crypto/tests.txt b/tests/crypto/tests.txt
index 3a7fe5453..d387aa09d 100644
--- a/tests/crypto/tests.txt
+++ b/tests/crypto/tests.txt
@@ -5473,3 +5473,59 @@ check_ge_p3_identity 046e1450f147f3ade34d149973913cc75d4e7b9669eb1ed61da0f1d4a0b
check_ge_p3_identity ca8a2f621cfc7aa3efcd7ddf55dce5352e757b38aca0869b050c0a27824e5c5e true true
check_ge_p3_identity 64a247eef6087d86e1e9fa048a3c181fdb1728431f29ba738634bdc38f02a859 true true
check_ge_p3_identity cff0c7170a41395b0658ee42b76545c45360736b973ab2f31f6f227b9415df67 true true
+derive_view_tag 0fc47054f355ced4d67de73bfa12e4c78ff19089548fffa7d07a674741860f97 0 76
+derive_view_tag 0fc47054f355ced4d67de73bfa12e4c78ff19089548fffa7d07a674741860f97 1 d6
+derive_view_tag 0fc47054f355ced4d67de73bfa12e4c78ff19089548fffa7d07a674741860f97 2 87
+derive_view_tag 0fc47054f355ced4d67de73bfa12e4c78ff19089548fffa7d07a674741860f97 3 1b
+derive_view_tag 0fc47054f355ced4d67de73bfa12e4c78ff19089548fffa7d07a674741860f97 12 d6
+derive_view_tag 0fc47054f355ced4d67de73bfa12e4c78ff19089548fffa7d07a674741860f97 13 e9
+derive_view_tag 0fc47054f355ced4d67de73bfa12e4c78ff19089548fffa7d07a674741860f97 14 12
+derive_view_tag 0fc47054f355ced4d67de73bfa12e4c78ff19089548fffa7d07a674741860f97 15 26
+derive_view_tag a36ba7b4d31349ad278a6df8f77adb76748b59f4929348e67dd92adb9fa174dc 0 70
+derive_view_tag a36ba7b4d31349ad278a6df8f77adb76748b59f4929348e67dd92adb9fa174dc 1 81
+derive_view_tag a36ba7b4d31349ad278a6df8f77adb76748b59f4929348e67dd92adb9fa174dc 2 a0
+derive_view_tag a36ba7b4d31349ad278a6df8f77adb76748b59f4929348e67dd92adb9fa174dc 3 ec
+derive_view_tag a36ba7b4d31349ad278a6df8f77adb76748b59f4929348e67dd92adb9fa174dc 12 22
+derive_view_tag a36ba7b4d31349ad278a6df8f77adb76748b59f4929348e67dd92adb9fa174dc 13 0a
+derive_view_tag a36ba7b4d31349ad278a6df8f77adb76748b59f4929348e67dd92adb9fa174dc 14 87
+derive_view_tag a36ba7b4d31349ad278a6df8f77adb76748b59f4929348e67dd92adb9fa174dc 15 76
+derive_view_tag 7498d5bf0b69e08653f6d420a17f866dd2bd490ab43074f46065cb501fe7e2d8 0 93
+derive_view_tag 7498d5bf0b69e08653f6d420a17f866dd2bd490ab43074f46065cb501fe7e2d8 1 67
+derive_view_tag 7498d5bf0b69e08653f6d420a17f866dd2bd490ab43074f46065cb501fe7e2d8 2 9d
+derive_view_tag 7498d5bf0b69e08653f6d420a17f866dd2bd490ab43074f46065cb501fe7e2d8 3 2d
+derive_view_tag 7498d5bf0b69e08653f6d420a17f866dd2bd490ab43074f46065cb501fe7e2d8 12 63
+derive_view_tag 7498d5bf0b69e08653f6d420a17f866dd2bd490ab43074f46065cb501fe7e2d8 13 cf
+derive_view_tag 7498d5bf0b69e08653f6d420a17f866dd2bd490ab43074f46065cb501fe7e2d8 14 ef
+derive_view_tag 7498d5bf0b69e08653f6d420a17f866dd2bd490ab43074f46065cb501fe7e2d8 15 10
+derive_view_tag fe7770c4b076e95ddb8026affcfab39d31c7c4a2266e0e25e343bc4badc907d0 0 90
+derive_view_tag fe7770c4b076e95ddb8026affcfab39d31c7c4a2266e0e25e343bc4badc907d0 1 5a
+derive_view_tag fe7770c4b076e95ddb8026affcfab39d31c7c4a2266e0e25e343bc4badc907d0 2 de
+derive_view_tag fe7770c4b076e95ddb8026affcfab39d31c7c4a2266e0e25e343bc4badc907d0 3 21
+derive_view_tag fe7770c4b076e95ddb8026affcfab39d31c7c4a2266e0e25e343bc4badc907d0 12 57
+derive_view_tag fe7770c4b076e95ddb8026affcfab39d31c7c4a2266e0e25e343bc4badc907d0 13 52
+derive_view_tag fe7770c4b076e95ddb8026affcfab39d31c7c4a2266e0e25e343bc4badc907d0 14 6f
+derive_view_tag fe7770c4b076e95ddb8026affcfab39d31c7c4a2266e0e25e343bc4badc907d0 15 eb
+derive_view_tag ea9337d0ddf480abdc4fc56a0cb223702729cb230ae7b9de50243ad25ce90e8d 0 c6
+derive_view_tag ea9337d0ddf480abdc4fc56a0cb223702729cb230ae7b9de50243ad25ce90e8d 1 60
+derive_view_tag ea9337d0ddf480abdc4fc56a0cb223702729cb230ae7b9de50243ad25ce90e8d 2 f0
+derive_view_tag ea9337d0ddf480abdc4fc56a0cb223702729cb230ae7b9de50243ad25ce90e8d 3 71
+derive_view_tag ea9337d0ddf480abdc4fc56a0cb223702729cb230ae7b9de50243ad25ce90e8d 12 0e
+derive_view_tag ea9337d0ddf480abdc4fc56a0cb223702729cb230ae7b9de50243ad25ce90e8d 13 42
+derive_view_tag ea9337d0ddf480abdc4fc56a0cb223702729cb230ae7b9de50243ad25ce90e8d 14 b2
+derive_view_tag ea9337d0ddf480abdc4fc56a0cb223702729cb230ae7b9de50243ad25ce90e8d 15 61
+derive_view_tag 25d538315bcb81aff9574189ea65f418aeb0392f5cbbc84cd8a33c7ade31ef0a 0 4c
+derive_view_tag 25d538315bcb81aff9574189ea65f418aeb0392f5cbbc84cd8a33c7ade31ef0a 1 9b
+derive_view_tag 25d538315bcb81aff9574189ea65f418aeb0392f5cbbc84cd8a33c7ade31ef0a 2 64
+derive_view_tag 25d538315bcb81aff9574189ea65f418aeb0392f5cbbc84cd8a33c7ade31ef0a 3 ff
+derive_view_tag 25d538315bcb81aff9574189ea65f418aeb0392f5cbbc84cd8a33c7ade31ef0a 12 e3
+derive_view_tag 25d538315bcb81aff9574189ea65f418aeb0392f5cbbc84cd8a33c7ade31ef0a 13 24
+derive_view_tag 25d538315bcb81aff9574189ea65f418aeb0392f5cbbc84cd8a33c7ade31ef0a 14 ea
+derive_view_tag 25d538315bcb81aff9574189ea65f418aeb0392f5cbbc84cd8a33c7ade31ef0a 15 3b
+derive_view_tag 8edfabada2b24ef4d8d915826c9ff0245910e4b835b59c2cf8ed8fc991b2e1e8 0 74
+derive_view_tag 8edfabada2b24ef4d8d915826c9ff0245910e4b835b59c2cf8ed8fc991b2e1e8 1 77
+derive_view_tag 8edfabada2b24ef4d8d915826c9ff0245910e4b835b59c2cf8ed8fc991b2e1e8 2 a9
+derive_view_tag 8edfabada2b24ef4d8d915826c9ff0245910e4b835b59c2cf8ed8fc991b2e1e8 3 44
+derive_view_tag 8edfabada2b24ef4d8d915826c9ff0245910e4b835b59c2cf8ed8fc991b2e1e8 12 75
+derive_view_tag 8edfabada2b24ef4d8d915826c9ff0245910e4b835b59c2cf8ed8fc991b2e1e8 13 05
+derive_view_tag 8edfabada2b24ef4d8d915826c9ff0245910e4b835b59c2cf8ed8fc991b2e1e8 14 ca
+derive_view_tag 8edfabada2b24ef4d8d915826c9ff0245910e4b835b59c2cf8ed8fc991b2e1e8 15 00
diff --git a/tests/functional_tests/blockchain.py b/tests/functional_tests/blockchain.py
index 4c8f367c0..328c225ff 100755
--- a/tests/functional_tests/blockchain.py
+++ b/tests/functional_tests/blockchain.py
@@ -81,10 +81,10 @@ class BlockchainTest():
assert ok
res = daemon.get_fee_estimate()
- assert res.fee == 234562
+ assert res.fee == 1200000
assert res.quantization_mask == 10000
res = daemon.get_fee_estimate(10)
- assert res.fee <= 234562
+ assert res.fee <= 1200000
# generate blocks
res_generateblocks = daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', blocks)
@@ -243,10 +243,10 @@ class BlockchainTest():
assert res.histogram[i].recent_instances == 0
res = daemon.get_fee_estimate()
- assert res.fee == 234560
+ assert res.fee == 1200000
assert res.quantization_mask == 10000
res = daemon.get_fee_estimate(10)
- assert res.fee <= 234560
+ assert res.fee <= 1200000
def _test_alt_chains(self):
print('Testing alt chains')
diff --git a/tests/functional_tests/cold_signing.py b/tests/functional_tests/cold_signing.py
index 2233f19e7..31d5780bb 100755
--- a/tests/functional_tests/cold_signing.py
+++ b/tests/functional_tests/cold_signing.py
@@ -101,7 +101,7 @@ class ColdSigningTest():
res = self.cold_wallet.export_key_images(True)
self.hot_wallet.import_key_images(res.signed_key_images, offset = res.offset)
- res = self.hot_wallet.transfer([dst], ring_size = 11, get_tx_key = False)
+ res = self.hot_wallet.transfer([dst], ring_size = 16, get_tx_key = False)
assert len(res.tx_hash) == 32*2
txid = res.tx_hash
assert len(res.tx_key) == 0
@@ -121,7 +121,7 @@ class ColdSigningTest():
desc = res.desc[0]
assert desc.amount_in >= amount + fee
assert desc.amount_out == desc.amount_in - fee
- assert desc.ring_size == 11
+ assert desc.ring_size == 16
assert desc.unlock_time == 0
assert desc.payment_id in ['', '0000000000000000']
assert desc.change_amount == desc.amount_in - 1000000000000 - fee
diff --git a/tests/functional_tests/main.cpp b/tests/functional_tests/main.cpp
index d3b7a9592..41c55e4d4 100644
--- a/tests/functional_tests/main.cpp
+++ b/tests/functional_tests/main.cpp
@@ -51,7 +51,7 @@ namespace
const command_line::arg_descriptor<std::string> arg_daemon_addr_b = {"daemon-addr-b", "", "127.0.0.1:8082"};
const command_line::arg_descriptor<uint64_t> arg_transfer_amount = {"transfer_amount", "", 60000000000000};
- const command_line::arg_descriptor<size_t> arg_mix_in_factor = {"mix-in-factor", "", 10};
+ const command_line::arg_descriptor<size_t> arg_mix_in_factor = {"mix-in-factor", "", 15};
const command_line::arg_descriptor<size_t> arg_tx_count = {"tx-count", "", 100};
const command_line::arg_descriptor<size_t> arg_tx_per_second = {"tx-per-second", "", 20};
const command_line::arg_descriptor<size_t> arg_test_repeat_count = {"test_repeat_count", "", 1};
diff --git a/tests/functional_tests/multisig.py b/tests/functional_tests/multisig.py
index 17b94494a..c1b50b1e2 100755
--- a/tests/functional_tests/multisig.py
+++ b/tests/functional_tests/multisig.py
@@ -44,7 +44,7 @@ class MultisigTest():
self.mine('41mro238grj56GnrWkakAKTkBy2yDcXYsUZ2iXCM9pe5Ueajd2RRc6Fhh3uBXT2UAKhAsUJ7Fg5zjjF2U1iGciFk5ief4ZP', 5)
self.mine('44vZSprQKJQRFe6t1VHgU4ESvq2dv7TjBLVGE7QscKxMdFSiyyPCEV64NnKUQssFPyWxc2meyt7j63F2S2qtCTRL6dakeff', 5)
self.mine('47puypSwsV1gvUDratmX4y58fSwikXVehEiBhVLxJA1gRCxHyrRgTDr4NnKUQssFPyWxc2meyt7j63F2S2qtCTRL6aRPj5U', 5)
- self.mine('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 60)
+ self.mine('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 80)
self.test_states()
@@ -261,7 +261,7 @@ class MultisigTest():
desc = res.desc[0]
assert desc.amount_in >= amount + fee
assert desc.amount_out == desc.amount_in - fee
- assert desc.ring_size == 11
+ assert desc.ring_size == 16
assert desc.unlock_time == 0
assert not 'payment_id' in desc or desc.payment_id in ['', '0000000000000000']
assert desc.change_amount == desc.amount_in - 1000000000000 - fee
diff --git a/tests/functional_tests/transfer.py b/tests/functional_tests/transfer.py
index 5314b045d..dd15369d3 100755
--- a/tests/functional_tests/transfer.py
+++ b/tests/functional_tests/transfer.py
@@ -82,11 +82,11 @@ class TransferTest():
res = daemon.get_info()
height = res.height
- daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 80)
+ daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 100)
for i in range(len(self.wallet)):
self.wallet[i].refresh()
res = self.wallet[i].get_height()
- assert res.height == height + 80
+ assert res.height == height + 100
def transfer(self):
daemon = Daemon()
@@ -110,23 +110,23 @@ class TransferTest():
print ('Checking short payment IDs cannot be used when not in an integrated address')
ok = False
- try: self.wallet[0].transfer([dst], ring_size = 11, payment_id = '1234567812345678', get_tx_key = False)
+ try: self.wallet[0].transfer([dst], ring_size = 16, payment_id = '1234567812345678', get_tx_key = False)
except: ok = True
assert ok
print ('Checking long payment IDs are rejected')
ok = False
- try: self.wallet[0].transfer([dst], ring_size = 11, payment_id = payment_id, get_tx_key = False, get_tx_hex = True)
+ try: self.wallet[0].transfer([dst], ring_size = 16, payment_id = payment_id, get_tx_key = False, get_tx_hex = True)
except: ok = True
assert ok
print ('Checking empty destination is rejected')
ok = False
- try: self.wallet[0].transfer([], ring_size = 11, get_tx_key = False)
+ try: self.wallet[0].transfer([], ring_size = 16, get_tx_key = False)
except: ok = True
assert ok
- res = self.wallet[0].transfer([dst], ring_size = 11, get_tx_key = False, get_tx_hex = True)
+ res = self.wallet[0].transfer([dst], ring_size = 16, get_tx_key = False, get_tx_hex = True)
assert len(res.tx_hash) == 32*2
txid = res.tx_hash
assert len(res.tx_key) == 0
@@ -231,7 +231,7 @@ class TransferTest():
print("Creating transfer to another, manual relay")
dst = {'address': '44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW', 'amount': 1000000000000}
- res = self.wallet[0].transfer([dst], ring_size = 11, get_tx_key = True, do_not_relay = True, get_tx_hex = True)
+ res = self.wallet[0].transfer([dst], ring_size = 16, get_tx_key = True, do_not_relay = True, get_tx_hex = True)
assert len(res.tx_hash) == 32*2
txid = res.tx_hash
assert len(res.tx_key) == 32*2
@@ -321,7 +321,7 @@ class TransferTest():
dst0 = {'address': '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 'amount': 1000000000000}
dst1 = {'address': '44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW', 'amount': 1100000000000}
dst2 = {'address': '46r4nYSevkfBUMhuykdK3gQ98XDqDTYW1hNLaXNvjpsJaSbNtdXh1sKMsdVgqkaihChAzEy29zEDPMR3NHQvGoZCLGwTerK', 'amount': 1200000000000}
- res = self.wallet[0].transfer([dst0, dst1, dst2], ring_size = 11, get_tx_key = True)
+ res = self.wallet[0].transfer([dst0, dst1, dst2], ring_size = 16, get_tx_key = True)
assert len(res.tx_hash) == 32*2
txid = res.tx_hash
assert len(res.tx_key) == 32*2
diff --git a/tests/performance_tests/CMakeLists.txt b/tests/performance_tests/CMakeLists.txt
index 03b124981..c079afe3a 100644
--- a/tests/performance_tests/CMakeLists.txt
+++ b/tests/performance_tests/CMakeLists.txt
@@ -43,6 +43,7 @@ set(performance_tests_headers
generate_keypair.h
signature.h
is_out_to_acc.h
+ out_can_be_to_acc.h
subaddress_expand.h
range_proof.h
bulletproof.h
diff --git a/tests/performance_tests/derive_view_tag.h b/tests/performance_tests/derive_view_tag.h
new file mode 100644
index 000000000..ee4efb16d
--- /dev/null
+++ b/tests/performance_tests/derive_view_tag.h
@@ -0,0 +1,62 @@
+// Copyright (c) 2014-2021, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
+
+#pragma once
+
+#include "crypto/crypto.h"
+#include "cryptonote_basic/cryptonote_basic.h"
+
+#include "single_tx_test_base.h"
+
+class test_derive_view_tag : public single_tx_test_base
+{
+public:
+ static const size_t loop_count = 10000;
+
+ bool init()
+ {
+ if (!single_tx_test_base::init())
+ return false;
+
+ crypto::generate_key_derivation(m_tx_pub_key, m_bob.get_keys().m_view_secret_key, m_key_derivation);
+
+ return true;
+ }
+
+ bool test()
+ {
+ crypto::view_tag view_tag;
+ crypto::derive_view_tag(m_key_derivation, 0, view_tag);
+ return true;
+ }
+
+private:
+ crypto::key_derivation m_key_derivation;
+};
diff --git a/tests/performance_tests/is_out_to_acc.h b/tests/performance_tests/is_out_to_acc.h
index d1204ee68..75d4a5c46 100644
--- a/tests/performance_tests/is_out_to_acc.h
+++ b/tests/performance_tests/is_out_to_acc.h
@@ -43,8 +43,9 @@ public:
bool test()
{
- const cryptonote::txout_to_key& tx_out = boost::get<cryptonote::txout_to_key>(m_tx.vout[0].target);
- return cryptonote::is_out_to_acc(m_bob.get_keys(), tx_out, m_tx_pub_key, m_additional_tx_pub_keys, 0);
+ crypto::public_key output_public_key;
+ cryptonote::get_output_public_key(m_tx.vout[0], output_public_key);
+ return cryptonote::is_out_to_acc(m_bob.get_keys(), output_public_key, m_tx_pub_key, m_additional_tx_pub_keys, 0);
}
};
diff --git a/tests/performance_tests/main.cpp b/tests/performance_tests/main.cpp
index 8bd1008cb..71c736977 100644
--- a/tests/performance_tests/main.cpp
+++ b/tests/performance_tests/main.cpp
@@ -42,6 +42,7 @@
#include "cn_slow_hash.h"
#include "derive_public_key.h"
#include "derive_secret_key.h"
+#include "derive_view_tag.h"
#include "ge_frombytes_vartime.h"
#include "ge_tobytes.h"
#include "generate_key_derivation.h"
@@ -50,6 +51,7 @@
#include "generate_keypair.h"
#include "signature.h"
#include "is_out_to_acc.h"
+#include "out_can_be_to_acc.h"
#include "subaddress_expand.h"
#include "sc_reduce32.h"
#include "sc_check.h"
@@ -194,6 +196,9 @@ int main(int argc, char** argv)
TEST_PERFORMANCE0(filter, p, test_is_out_to_acc);
TEST_PERFORMANCE0(filter, p, test_is_out_to_acc_precomp);
+ TEST_PERFORMANCE2(filter, p, test_out_can_be_to_acc, false, true); // no view tag, owned
+ TEST_PERFORMANCE2(filter, p, test_out_can_be_to_acc, true, false); // use view tag, not owned
+ TEST_PERFORMANCE2(filter, p, test_out_can_be_to_acc, true, true); // use view tag, owned
TEST_PERFORMANCE0(filter, p, test_generate_key_image_helper);
TEST_PERFORMANCE0(filter, p, test_generate_key_derivation);
TEST_PERFORMANCE0(filter, p, test_generate_key_image);
@@ -206,6 +211,7 @@ int main(int argc, char** argv)
TEST_PERFORMANCE0(filter, p, test_sc_check);
TEST_PERFORMANCE1(filter, p, test_signature, false);
TEST_PERFORMANCE1(filter, p, test_signature, true);
+ TEST_PERFORMANCE0(filter, p, test_derive_view_tag);
TEST_PERFORMANCE2(filter, p, test_wallet2_expand_subaddresses, 50, 200);
diff --git a/tests/performance_tests/out_can_be_to_acc.h b/tests/performance_tests/out_can_be_to_acc.h
new file mode 100644
index 000000000..86e236b7b
--- /dev/null
+++ b/tests/performance_tests/out_can_be_to_acc.h
@@ -0,0 +1,103 @@
+// Copyright (c) 2014-2021, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
+
+#pragma once
+
+#include "crypto/crypto.h"
+#include "cryptonote_basic/cryptonote_basic.h"
+
+#include "single_tx_test_base.h"
+
+using namespace crypto;
+
+// use_view_tags: whether to enable view tag checking
+// is_owned: whether the output is owned by us
+template<bool use_view_tags, bool is_owned>
+class test_out_can_be_to_acc : public single_tx_test_base
+{
+ public:
+ static const size_t loop_count = 1000;
+
+ bool init()
+ {
+ if (!single_tx_test_base::init())
+ return false;
+
+ crypto::key_derivation key_derivation;
+ crypto::view_tag vt;
+
+ m_output_index = 0;
+ m_view_secret_key = m_bob.get_keys().m_view_secret_key;
+ m_spend_public_key = m_bob.get_keys().m_account_address.m_spend_public_key;
+
+ cryptonote::get_output_public_key(m_tx.vout[m_output_index], m_output_public_key);
+
+ if (use_view_tags)
+ {
+ crypto::generate_key_derivation(m_tx_pub_key, m_view_secret_key, key_derivation);
+ crypto::derive_view_tag(key_derivation, m_output_index, vt);
+ m_view_tag_opt = vt;
+ }
+ else
+ m_view_tag_opt = boost::optional<crypto::view_tag>();
+
+ return true;
+ }
+
+ bool test()
+ {
+ // include key derivation to demonstrate performance improvement when using view tags
+ crypto::key_derivation key_derivation;
+ crypto::generate_key_derivation(m_tx_pub_key, m_view_secret_key, key_derivation);
+
+ // if using view tags, this ensures we computed the view tag properly
+ if (!cryptonote::out_can_be_to_acc(m_view_tag_opt, key_derivation, m_output_index))
+ return false;
+
+ // if user owns output, this tests the output public key matches the derived
+ if (is_owned)
+ {
+ crypto::public_key output_public_key;
+ crypto::derive_public_key(key_derivation, m_output_index, m_spend_public_key, output_public_key);
+
+ if (m_output_public_key != output_public_key)
+ return false;
+ }
+
+ return true;
+ }
+
+ private:
+ size_t m_output_index;
+ crypto::secret_key m_view_secret_key;
+ crypto::public_key m_spend_public_key;
+ crypto::public_key m_output_public_key;
+ boost::optional<crypto::view_tag> m_view_tag_opt;
+};
diff --git a/tests/unit_tests/CMakeLists.txt b/tests/unit_tests/CMakeLists.txt
index b5ee7af01..55818dc93 100644
--- a/tests/unit_tests/CMakeLists.txt
+++ b/tests/unit_tests/CMakeLists.txt
@@ -77,6 +77,7 @@ set(unit_tests_sources
pruning.cpp
random.cpp
rolling_median.cpp
+ scaling_2021.cpp
serialization.cpp
sha256.cpp
slow_memmem.cpp
diff --git a/tests/unit_tests/epee_utils.cpp b/tests/unit_tests/epee_utils.cpp
index 1ba0e49ab..1c756e77c 100644
--- a/tests/unit_tests/epee_utils.cpp
+++ b/tests/unit_tests/epee_utils.cpp
@@ -31,6 +31,7 @@
#include <boost/endian/conversion.hpp>
#include <boost/range/algorithm/equal.hpp>
#include <boost/range/algorithm_ext/iota.hpp>
+#include <boost/range/iterator_range.hpp>
#include <cstdint>
#include <gtest/gtest.h>
#include <iterator>
diff --git a/tests/unit_tests/rolling_median.cpp b/tests/unit_tests/rolling_median.cpp
index 4d99bbb0d..07da0f0ef 100644
--- a/tests/unit_tests/rolling_median.cpp
+++ b/tests/unit_tests/rolling_median.cpp
@@ -211,3 +211,21 @@ TEST(rolling_median, size)
ASSERT_EQ(m.size(), std::min<int>(10, i + 2));
}
}
+
+TEST(rolling_median, copy)
+{
+ epee::misc_utils::rolling_median_t<uint64_t> m(100);
+
+ for (int i = 0; i < 100; ++i)
+ m.insert(rand());
+
+ epee::misc_utils::rolling_median_t<uint64_t> copy(m);
+
+ for (int i = 0; i < 5000; ++i)
+ {
+ uint64_t v = rand();
+ m.insert(v);
+ copy.insert(v);
+ ASSERT_EQ(m.median(), copy.median());
+ }
+}
diff --git a/tests/unit_tests/scaling_2021.cpp b/tests/unit_tests/scaling_2021.cpp
new file mode 100644
index 000000000..9e8d15544
--- /dev/null
+++ b/tests/unit_tests/scaling_2021.cpp
@@ -0,0 +1,187 @@
+// Copyright (c) 2019-2020, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// References:
+// - https://github.com/ArticMine/Monero-Documents/blob/master/MoneroScaling2021.pdf
+// - https://github.com/monero-project/research-lab/issues/70
+
+#define IN_UNIT_TESTS
+
+#include "gtest/gtest.h"
+#include "cryptonote_core/blockchain.h"
+#include "cryptonote_core/tx_pool.h"
+#include "cryptonote_core/cryptonote_core.h"
+#include "blockchain_db/testdb.h"
+
+namespace
+{
+
+class TestDB: public cryptonote::BaseTestDB
+{
+public:
+ TestDB() { m_open = true; }
+};
+
+}
+
+#define PREFIX_WINDOW(hf_version,window) \
+ std::unique_ptr<cryptonote::Blockchain> bc; \
+ cryptonote::tx_memory_pool txpool(*bc); \
+ bc.reset(new cryptonote::Blockchain(txpool)); \
+ struct get_test_options { \
+ const std::pair<uint8_t, uint64_t> hard_forks[3]; \
+ const cryptonote::test_options test_options = { \
+ hard_forks, \
+ window, \
+ }; \
+ get_test_options(): hard_forks{std::make_pair(1, (uint64_t)0), std::make_pair((uint8_t)hf_version, (uint64_t)1), std::make_pair((uint8_t)0, (uint64_t)0)} {} \
+ } opts; \
+ cryptonote::Blockchain *blockchain = bc.get(); \
+ bool r = blockchain->init(new TestDB(), cryptonote::FAKECHAIN, true, &opts.test_options, 0, NULL); \
+ ASSERT_TRUE(r)
+
+#define PREFIX(hf_version) PREFIX_WINDOW(hf_version, TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW)
+
+TEST(fee_2021_scaling, relay_fee_cases_from_pdf)
+{
+ PREFIX_WINDOW(HF_VERSION_2021_SCALING, CRYPTONOTE_LONG_TERM_BLOCK_WEIGHT_WINDOW_SIZE);
+
+ ASSERT_EQ(bc->get_dynamic_base_fee(1200000000000, 300000, HF_VERSION_2021_SCALING-1), 8000);
+ ASSERT_EQ(bc->get_dynamic_base_fee(1200000000000, 300000, HF_VERSION_2021_SCALING), 38000);
+ ASSERT_EQ(bc->get_dynamic_base_fee(1200000000000, 1425000, HF_VERSION_2021_SCALING-1), 1684 /*1680*/);
+ ASSERT_EQ(bc->get_dynamic_base_fee(1200000000000, 1425000, HF_VERSION_2021_SCALING), 1684 /*1680*/);
+ ASSERT_EQ(bc->get_dynamic_base_fee(1200000000000, 1500000, HF_VERSION_2021_SCALING-1), 1600);
+ ASSERT_EQ(bc->get_dynamic_base_fee(1200000000000, 1500000, HF_VERSION_2021_SCALING), 1520);
+
+ ASSERT_EQ(bc->get_dynamic_base_fee(600000000000, 300000, HF_VERSION_2021_SCALING-1), 4000);
+ ASSERT_EQ(bc->get_dynamic_base_fee(600000000000, 300000, HF_VERSION_2021_SCALING), 19000);
+ ASSERT_EQ(bc->get_dynamic_base_fee(600000000000, 1425000, HF_VERSION_2021_SCALING-1), 842 /*840*/);
+ ASSERT_EQ(bc->get_dynamic_base_fee(600000000000, 1425000, HF_VERSION_2021_SCALING), 842 /*840*/);
+ ASSERT_EQ(bc->get_dynamic_base_fee(600000000000, 1500000, HF_VERSION_2021_SCALING-1), 800);
+ ASSERT_EQ(bc->get_dynamic_base_fee(600000000000, 1500000, HF_VERSION_2021_SCALING), 760);
+}
+
+TEST(fee_2021_scaling, wallet_fee_cases_from_pdf)
+{
+ PREFIX_WINDOW(HF_VERSION_2021_SCALING, CRYPTONOTE_LONG_TERM_BLOCK_WEIGHT_WINDOW_SIZE);
+ std::vector<uint64_t> fees;
+
+ fees.clear();
+ bc->get_dynamic_base_fee_estimate_2021_scaling(10, 600000000000, 300000, 300000, fees);
+ ASSERT_EQ(fees.size(), 4);
+ ASSERT_EQ(fees[0], 20000);
+ ASSERT_EQ(fees[1], 80000);
+ ASSERT_EQ(fees[2], 320000);
+ ASSERT_EQ(fees[3], 4000000);
+
+ fees.clear();
+ bc->get_dynamic_base_fee_estimate_2021_scaling(10, 600000000000, 15000000, 300000, fees);
+ ASSERT_EQ(fees.size(), 4);
+ ASSERT_EQ(fees[0], 20000);
+ ASSERT_EQ(fees[1], 80000);
+ ASSERT_EQ(fees[2], 320000);
+ ASSERT_EQ(fees[3], 1300000);
+
+ fees.clear();
+ bc->get_dynamic_base_fee_estimate_2021_scaling(10, 600000000000, 1425000, 1425000, fees);
+ ASSERT_EQ(fees.size(), 4);
+ ASSERT_EQ(fees[0], 890);
+ ASSERT_EQ(fees[1], 3600);
+ ASSERT_EQ(fees[2], 68000);
+ ASSERT_EQ(fees[3], 850000 /* 842000 */);
+
+ fees.clear();
+ bc->get_dynamic_base_fee_estimate_2021_scaling(10, 600000000000, 1500000, 1500000, fees);
+ ASSERT_EQ(fees.size(), 4);
+ ASSERT_EQ(fees[0], 800);
+ ASSERT_EQ(fees[1], 3200);
+ ASSERT_EQ(fees[2], 64000);
+ ASSERT_EQ(fees[3], 800000);
+
+ fees.clear();
+ bc->get_dynamic_base_fee_estimate_2021_scaling(10, 600000000000, 75000000, 1500000, fees);
+ ASSERT_EQ(fees.size(), 4);
+ ASSERT_EQ(fees[0], 800);
+ ASSERT_EQ(fees[1], 3200);
+ ASSERT_EQ(fees[2], 64000);
+ ASSERT_EQ(fees[3], 260000);
+}
+
+TEST(fee_2021_scaling, rounding)
+{
+ ASSERT_EQ(cryptonote::round_money_up("27810", 3), "27900.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("37.94", 3), "38.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("0.5555", 3), "0.556000000000");
+ ASSERT_EQ(cryptonote::round_money_up("0.002342", 3), "0.002350000000");
+
+ ASSERT_EQ(cryptonote::round_money_up("27810", 2), "28000.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("37.94", 2), "38.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("0.5555", 2), "0.560000000000");
+ ASSERT_EQ(cryptonote::round_money_up("0.002342", 2), "0.002400000000");
+
+ ASSERT_EQ(cryptonote::round_money_up("0", 8), "0.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("0.0", 8), "0.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("50.0", 8), "50.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("0.002342", 8), "0.002342000000");
+ ASSERT_EQ(cryptonote::round_money_up("0.002342", 1), "0.003000000000");
+ ASSERT_EQ(cryptonote::round_money_up("12345", 8), "12345.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("45678", 1), "50000.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("1.234", 1), "2.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("1.0000001", 4), "1.001000000000");
+ ASSERT_EQ(cryptonote::round_money_up("1.0020001", 4), "1.003000000000");
+
+ ASSERT_EQ(cryptonote::round_money_up("1.999999", 1), "2.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("1.999999", 2), "2.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("1.999999", 3), "2.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("1.999999", 4), "2.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("1.999999", 5), "2.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("1.999999", 6), "2.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("1.999999", 7), "1.999999000000");
+ ASSERT_EQ(cryptonote::round_money_up("1.999999", 8), "1.999999000000");
+ ASSERT_EQ(cryptonote::round_money_up("1.999999", 9), "1.999999000000");
+
+ ASSERT_EQ(cryptonote::round_money_up("2.000001", 1), "3.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("2.000001", 2), "2.100000000000");
+ ASSERT_EQ(cryptonote::round_money_up("2.000001", 3), "2.010000000000");
+ ASSERT_EQ(cryptonote::round_money_up("2.000001", 4), "2.001000000000");
+ ASSERT_EQ(cryptonote::round_money_up("2.000001", 5), "2.000100000000");
+ ASSERT_EQ(cryptonote::round_money_up("2.000001", 6), "2.000010000000");
+ ASSERT_EQ(cryptonote::round_money_up("2.000001", 7), "2.000001000000");
+ ASSERT_EQ(cryptonote::round_money_up("2.000001", 8), "2.000001000000");
+ ASSERT_EQ(cryptonote::round_money_up("2.000001", 9), "2.000001000000");
+ ASSERT_EQ(cryptonote::round_money_up("2.000001", 4000), "2.000001000000");
+
+ ASSERT_EQ(cryptonote::round_money_up("999", 2), "1000.000000000000");
+
+ ASSERT_THROW(cryptonote::round_money_up("1.23", 0), std::runtime_error);
+ ASSERT_THROW(cryptonote::round_money_up("18446744.073709551615", 1), std::runtime_error);
+ ASSERT_THROW(cryptonote::round_money_up("18446744.073709551615", 2), std::runtime_error);
+ ASSERT_THROW(cryptonote::round_money_up("18446744.073709551615", 12), std::runtime_error);
+ ASSERT_THROW(cryptonote::round_money_up("18446744.073709551615", 19), std::runtime_error);
+ ASSERT_EQ(cryptonote::round_money_up("18446744.073709551615", 20), "18446744.073709551615");
+}