aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/CMakeLists.txt2
-rw-r--r--tests/block_weight/CMakeLists.txt45
-rw-r--r--tests/block_weight/block_weight.cpp183
-rwxr-xr-xtests/block_weight/block_weight.py74
-rwxr-xr-xtests/block_weight/compare.py13
-rw-r--r--tests/core_proxy/core_proxy.h2
-rw-r--r--tests/core_tests/bulletproofs.cpp81
-rw-r--r--tests/core_tests/bulletproofs.h4
-rw-r--r--tests/core_tests/multisig.cpp4
-rw-r--r--tests/core_tests/rct.cpp3
-rw-r--r--tests/core_tests/v2_tests.h2
-rw-r--r--tests/crypto/CMakeLists.txt14
-rw-r--r--tests/crypto/cnv4-jit.c119
-rw-r--r--tests/hash/CMakeLists.txt2
-rw-r--r--tests/hash/main.cpp29
-rw-r--r--tests/hash/tests-slow-4.txt10
-rw-r--r--tests/performance_tests/check_tx_signature.h9
-rw-r--r--tests/performance_tests/cn_slow_hash.h15
-rw-r--r--tests/performance_tests/construct_tx.h5
-rw-r--r--tests/performance_tests/main.cpp39
-rw-r--r--tests/unit_tests/CMakeLists.txt4
-rw-r--r--tests/unit_tests/ban.cpp2
-rw-r--r--tests/unit_tests/blockchain_db.cpp12
-rw-r--r--tests/unit_tests/bulletproofs.cpp3
-rw-r--r--tests/unit_tests/device.cpp9
-rw-r--r--tests/unit_tests/epee_utils.cpp22
-rw-r--r--tests/unit_tests/hardfork.cpp41
-rw-r--r--tests/unit_tests/json_serialization.cpp2
-rw-r--r--tests/unit_tests/long_term_block_weight.cpp384
-rw-r--r--tests/unit_tests/mnemonics.cpp36
-rw-r--r--tests/unit_tests/net.cpp745
-rw-r--r--tests/unit_tests/notify.cpp2
-rw-r--r--tests/unit_tests/output_distribution.cpp4
-rw-r--r--tests/unit_tests/pruning.cpp240
-rw-r--r--tests/unit_tests/ringct.cpp42
-rw-r--r--tests/unit_tests/serialization.cpp5
-rw-r--r--tests/unit_tests/test_peerlist.cpp175
-rw-r--r--tests/unit_tests/testdb.h147
38 files changed, 2222 insertions, 308 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 20afd4203..89d77cf32 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -85,6 +85,7 @@ add_subdirectory(performance_tests)
add_subdirectory(core_proxy)
add_subdirectory(unit_tests)
add_subdirectory(difficulty)
+add_subdirectory(block_weight)
add_subdirectory(hash)
add_subdirectory(net_load_tests)
if (BUILD_GUI_DEPS)
@@ -115,6 +116,7 @@ add_test(
set(enabled_tests
core_tests
difficulty
+ block_weight
hash
performance_tests
core_proxy
diff --git a/tests/block_weight/CMakeLists.txt b/tests/block_weight/CMakeLists.txt
new file mode 100644
index 000000000..b0d716ea0
--- /dev/null
+++ b/tests/block_weight/CMakeLists.txt
@@ -0,0 +1,45 @@
+# Copyright (c) 2014-2018, 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.
+
+set(block_weight_sources
+ block_weight.cpp)
+
+set(block_weight_headers)
+
+add_executable(block_weight
+ ${block_weight_sources}
+ ${block_weight_headers})
+target_link_libraries(block_weight
+ PRIVATE
+ cryptonote_core
+ blockchain_db
+ ${EXTRA_LIBRARIES})
+
+add_test(
+ NAME block_weight
+ COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/compare.py ${CMAKE_CURRENT_SOURCE_DIR}/block_weight.py ${CMAKE_CURRENT_BINARY_DIR}/block_weight)
diff --git a/tests/block_weight/block_weight.cpp b/tests/block_weight/block_weight.cpp
new file mode 100644
index 000000000..a67f40f0f
--- /dev/null
+++ b/tests/block_weight/block_weight.cpp
@@ -0,0 +1,183 @@
+// Copyright (c) 2019, 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.
+
+#define IN_UNIT_TESTS
+
+#include <stdio.h>
+#include <math.h>
+#include "cryptonote_core/blockchain.h"
+#include "cryptonote_core/tx_pool.h"
+#include "cryptonote_core/cryptonote_core.h"
+#include "blockchain_db/testdb.h"
+
+#define LONG_TERM_BLOCK_WEIGHT_WINDOW 5000
+
+enum test_t
+{
+ test_max = 0,
+ test_lcg = 1,
+ test_min = 2,
+};
+
+namespace
+{
+
+class TestDB: public cryptonote::BaseTestDB
+{
+private:
+ struct block_t
+ {
+ size_t weight;
+ uint64_t long_term_weight;
+ };
+
+public:
+ TestDB() { m_open = true; }
+
+ virtual void add_block( const cryptonote::block& blk
+ , size_t block_weight
+ , uint64_t long_term_block_weight
+ , const cryptonote::difficulty_type& cumulative_difficulty
+ , const uint64_t& coins_generated
+ , uint64_t num_rct_outs
+ , const crypto::hash& blk_hash
+ ) override {
+ blocks.push_back({block_weight, long_term_block_weight});
+ }
+ virtual uint64_t height() const override { return blocks.size(); }
+ virtual size_t get_block_weight(const uint64_t &h) const override { return blocks[h].weight; }
+ virtual uint64_t get_block_long_term_weight(const uint64_t &h) const override { return blocks[h].long_term_weight; }
+ virtual crypto::hash top_block_hash() const override {
+ uint64_t h = height();
+ crypto::hash top = crypto::null_hash;
+ if (h)
+ *(uint64_t*)&top = h - 1;
+ return top;
+ }
+ virtual void pop_block(cryptonote::block &blk, std::vector<cryptonote::transaction> &txs) override { blocks.pop_back(); }
+ virtual void set_hard_fork_version(uint64_t height, uint8_t version) override { if (height >= hf.size()) hf.resize(height + 1); hf[height] = version; }
+ virtual uint8_t get_hard_fork_version(uint64_t height) const override { if (height >= hf.size()) return 255; return hf[height]; }
+
+private:
+ std::vector<block_t> blocks;
+ std::vector<uint8_t> hf;
+};
+
+}
+
+#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)LONG_TERM_BLOCK_WEIGHT_WINDOW), 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); \
+ if (!r) \
+ { \
+ fprintf(stderr, "Failed to init blockchain\n"); \
+ exit(1); \
+ }
+
+#define PREFIX(hf_version) PREFIX_WINDOW(hf_version, LONG_TERM_BLOCK_WEIGHT_WINDOW)
+
+static uint32_t lcg_seed = 0;
+
+static uint32_t lcg()
+{
+ lcg_seed = (lcg_seed * 0x100000001b3 + 0xcbf29ce484222325) & 0xffffffff;
+ return lcg_seed;
+}
+
+static void test(test_t t, uint64_t blocks)
+{
+ PREFIX(10);
+
+ for (uint64_t h = 0; h < LONG_TERM_BLOCK_WEIGHT_WINDOW; ++h)
+ {
+ cryptonote::block b;
+ b.major_version = 1;
+ b.minor_version = 1;
+ bc->get_db().add_block(b, 300000, 300000, bc->get_db().height(), bc->get_db().height(), {});
+ if (!bc->update_next_cumulative_weight_limit())
+ {
+ fprintf(stderr, "Failed to update cumulative weight limit 1\n");
+ exit(1);
+ }
+ }
+
+ for (uint64_t h = 0; h < blocks; ++h)
+ {
+ uint64_t w;
+ uint64_t effective_block_weight_median = bc->get_current_cumulative_block_weight_median();
+ switch (t)
+ {
+ case test_lcg:
+ {
+ uint32_t r = lcg();
+ int64_t wi = 90 + r % 500000 + 250000 + sin(h / 200.) * 350000;
+ w = wi < 90 ? 90 : wi;
+ break;
+ }
+ case test_max:
+ w = bc->get_current_cumulative_block_weight_limit();
+ break;
+ case test_min:
+ w = 90;
+ break;
+ default:
+ exit(1);
+ }
+ uint64_t ltw = bc->get_next_long_term_block_weight(w);
+ cryptonote::block b;
+ b.major_version = 10;
+ b.minor_version = 10;
+ bc->get_db().add_block(std::move(b), w, ltw, bc->get_db().height(), bc->get_db().height(), {});
+
+ if (!bc->update_next_cumulative_weight_limit())
+ {
+ fprintf(stderr, "Failed to update cumulative weight limit\n");
+ exit(1);
+ }
+ std::cout << "H " << h << ", BW " << w << ", EMBW " << effective_block_weight_median << ", LTBW " << ltw << std::endl;
+ }
+}
+
+int main()
+{
+ test(test_max, 2 * LONG_TERM_BLOCK_WEIGHT_WINDOW);
+ test(test_lcg, 9 * LONG_TERM_BLOCK_WEIGHT_WINDOW);
+ test(test_min, 1 * LONG_TERM_BLOCK_WEIGHT_WINDOW);
+ return 0;
+}
diff --git a/tests/block_weight/block_weight.py b/tests/block_weight/block_weight.py
new file mode 100755
index 000000000..06aaabb02
--- /dev/null
+++ b/tests/block_weight/block_weight.py
@@ -0,0 +1,74 @@
+#!/usr/bin/python
+# Simulate a maximal block attack on the Monero network
+# This uses the scheme proposed by ArticMine
+# Written by Sarang Nother
+# Copyright (c) 2019 The Monero Project
+import sys
+import math
+
+MEDIAN_WINDOW_SMALL = 100 # number of recent blocks for median computation
+MEDIAN_WINDOW_BIG = 5000
+MULTIPLIER_SMALL = 1.4 # multipliers for determining weights
+MULTIPLIER_BIG = 50.0
+MEDIAN_THRESHOLD = 300*1000 # initial value for median (scaled kB -> B)
+lcg_seed = 0
+embw = MEDIAN_THRESHOLD
+ltembw = MEDIAN_THRESHOLD
+
+weights = [MEDIAN_THRESHOLD]*MEDIAN_WINDOW_SMALL # weights of recent blocks (B), with index -1 most recent
+lt_weights = [MEDIAN_THRESHOLD]*MEDIAN_WINDOW_BIG # long-term weights
+
+# Compute the median of a list
+def get_median(vec):
+ #temp = vec
+ temp = sorted(vec)
+ if len(temp) % 2 == 1:
+ return temp[len(temp)/2]
+ else:
+ return int((temp[len(temp)/2]+temp[len(temp)/2-1])/2)
+
+def LCG():
+ global lcg_seed
+ lcg_seed = (lcg_seed * 0x100000001b3 + 0xcbf29ce484222325) & 0xffffffff
+ return lcg_seed
+
+def run(t, blocks):
+ global embw
+ global ltembw
+
+ weights = [MEDIAN_THRESHOLD]*MEDIAN_WINDOW_SMALL # weights of recent blocks (B), with index -1 most recent
+ lt_weights = [MEDIAN_THRESHOLD]*MEDIAN_WINDOW_BIG # long-term weights
+
+ for block in range(blocks):
+ # determine the long-term effective weight
+ ltmedian = get_median(lt_weights[-MEDIAN_WINDOW_BIG:])
+ ltembw = max(MEDIAN_THRESHOLD,ltmedian)
+
+ # determine the effective weight
+ stmedian = get_median(weights[-MEDIAN_WINDOW_SMALL:])
+ embw = min(max(MEDIAN_THRESHOLD,stmedian),int(MULTIPLIER_BIG*ltembw))
+
+ # drop the lowest values
+ weights = weights[1:]
+ lt_weights = lt_weights[1:]
+
+ # add a block of max weight
+ if t == 0:
+ max_weight = 2 * embw
+ elif t == 1:
+ r = LCG()
+ max_weight = int(90 + r % 500000 + 250000 + math.sin(block / 200.) * 350000)
+ if max_weight < 90: max_weight = 90
+ elif t == 2:
+ max_weight = 90
+ else:
+ sys.exit(1)
+ weights.append(max_weight)
+ lt_weights.append(min(max_weight,int(ltembw + int(ltembw * 2 / 5))))
+
+ #print "H %u, r %u, BW %u, EMBW %u, LTBW %u, LTEMBW %u, ltmedian %u" % (block, r, max_weight, embw, lt_weights[-1], ltembw, ltmedian)
+ print "H %u, BW %u, EMBW %u, LTBW %u" % (block, max_weight, embw, lt_weights[-1])
+
+run(0, 2 * MEDIAN_WINDOW_BIG)
+run(1, 9 * MEDIAN_WINDOW_BIG)
+run(2, 1 * MEDIAN_WINDOW_BIG)
diff --git a/tests/block_weight/compare.py b/tests/block_weight/compare.py
new file mode 100755
index 000000000..c6be05206
--- /dev/null
+++ b/tests/block_weight/compare.py
@@ -0,0 +1,13 @@
+#!/usr/bin/python
+
+import sys
+import subprocess
+
+print 'running: ', sys.argv[1]
+S0 = subprocess.check_output(sys.argv[1], stderr=subprocess.STDOUT)
+print 'running: ', sys.argv[2]
+S1 = subprocess.check_output(sys.argv[2], stderr=subprocess.STDOUT)
+print 'comparing'
+if S0 != S1:
+ sys.exit(1)
+sys.exit(0)
diff --git a/tests/core_proxy/core_proxy.h b/tests/core_proxy/core_proxy.h
index 023c220ae..7888540cc 100644
--- a/tests/core_proxy/core_proxy.h
+++ b/tests/core_proxy/core_proxy.h
@@ -105,5 +105,7 @@ namespace tests
bool fluffy_blocks_enabled() const { return false; }
uint64_t prevalidate_block_hashes(uint64_t height, const std::vector<crypto::hash> &hashes) { return 0; }
bool pad_transactions() const { return false; }
+ uint32_t get_blockchain_pruning_seed() const { return 0; }
+ bool prune_blockchain(uint32_t pruning_seed) const { return true; }
};
}
diff --git a/tests/core_tests/bulletproofs.cpp b/tests/core_tests/bulletproofs.cpp
index db875d2a2..3e2db2e29 100644
--- a/tests/core_tests/bulletproofs.cpp
+++ b/tests/core_tests/bulletproofs.cpp
@@ -42,7 +42,7 @@ using namespace cryptonote;
// Tests
bool gen_bp_tx_validation_base::generate_with(std::vector<test_event_entry>& events,
- size_t mixin, size_t n_txes, const uint64_t *amounts_paid, bool valid, const rct::RangeProofType *range_proof_type,
+ size_t mixin, size_t n_txes, const uint64_t *amounts_paid, bool valid, const rct::RCTConfig *rct_config,
const std::function<bool(std::vector<tx_source_entry> &sources, std::vector<tx_destination_entry> &destinations, size_t tx_idx)> &pre_tx,
const std::function<bool(transaction &tx, size_t tx_idx)> &post_tx) const
{
@@ -136,7 +136,7 @@ bool gen_bp_tx_validation_base::generate_with(std::vector<test_event_entry>& eve
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
subaddresses[miner_accounts[n].get_keys().m_account_address.m_spend_public_key] = {0,0};
rct_txes.resize(rct_txes.size() + 1);
- bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), rct_txes.back(), 0, tx_key, additional_tx_keys, true, range_proof_type[n]);
+ bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), rct_txes.back(), 0, tx_key, additional_tx_keys, true, rct_config[n]);
CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction");
if (post_tx && !post_tx(rct_txes.back(), n))
@@ -157,7 +157,8 @@ bool gen_bp_tx_validation_base::generate_with(std::vector<test_event_entry>& eve
crypto::secret_key amount_key;
crypto::derivation_to_scalar(derivation, o, amount_key);
rct::key rct_tx_mask;
- if (rct_txes.back().rct_signatures.type == rct::RCTTypeSimple || rct_txes.back().rct_signatures.type == rct::RCTTypeBulletproof)
+ const uint8_t type = rct_txes.back().rct_signatures.type;
+ if (type == rct::RCTTypeSimple || type == rct::RCTTypeBulletproof || type == rct::RCTTypeBulletproof2)
rct::decodeRctSimple(rct_txes.back().rct_signatures, rct::sk2rct(amount_key), o, rct_tx_mask, hw::get_device("default"));
else
rct::decodeRct(rct_txes.back().rct_signatures, rct::sk2rct(amount_key), o, rct_tx_mask, hw::get_device("default"));
@@ -173,8 +174,8 @@ bool gen_bp_tx_validation_base::generate_with(std::vector<test_event_entry>& eve
CHECK_AND_ASSERT_MES(generator.construct_block_manually(blk_txes, 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,
- 8, 8, blk_last.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long
- crypto::hash(), 0, transaction(), starting_rct_tx_hashes, 0, 6, 8),
+ 10, 10, blk_last.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long
+ crypto::hash(), 0, transaction(), starting_rct_tx_hashes, 0, 6, 10),
false, "Failed to generate block");
if (!valid)
DO_CALLBACK(events, "mark_invalid_block");
@@ -210,16 +211,16 @@ bool gen_bp_tx_valid_1::generate(std::vector<test_event_entry>& events) const
const size_t mixin = 10;
const uint64_t amounts_paid[] = {10000, (uint64_t)-1};
const size_t bp_sizes[] = {1, (size_t)-1};
- const rct::RangeProofType range_proof_type[] = {rct::RangeProofPaddedBulletproof};
- return generate_with(events, mixin, 1, amounts_paid, true, range_proof_type, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_tx_valid_1"); });
+ const rct::RCTConfig rct_config[] = { { rct::RangeProofPaddedBulletproof, 0 } };
+ return generate_with(events, mixin, 1, amounts_paid, true, rct_config, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_tx_valid_1"); });
}
bool gen_bp_tx_invalid_1_1::generate(std::vector<test_event_entry>& events) const
{
const size_t mixin = 10;
const uint64_t amounts_paid[] = {5000, 5000, (uint64_t)-1};
- const rct::RangeProofType range_proof_type[] = { rct::RangeProofBulletproof };
- return generate_with(events, mixin, 1, amounts_paid, false, range_proof_type, NULL, NULL);
+ const rct::RCTConfig rct_config[] = { { rct::RangeProofBulletproof , 0 } };
+ return generate_with(events, mixin, 1, amounts_paid, false, rct_config, NULL, NULL);
}
bool gen_bp_tx_valid_2::generate(std::vector<test_event_entry>& events) const
@@ -227,8 +228,8 @@ bool gen_bp_tx_valid_2::generate(std::vector<test_event_entry>& events) const
const size_t mixin = 10;
const uint64_t amounts_paid[] = {5000, 5000, (uint64_t)-1};
const size_t bp_sizes[] = {2, (size_t)-1};
- const rct::RangeProofType range_proof_type[] = {rct::RangeProofPaddedBulletproof};
- return generate_with(events, mixin, 1, amounts_paid, true, range_proof_type, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_tx_valid_2"); });
+ const rct::RCTConfig rct_config[] = { { rct::RangeProofPaddedBulletproof, 0 } };
+ return generate_with(events, mixin, 1, amounts_paid, true, rct_config, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_tx_valid_2"); });
}
bool gen_bp_tx_valid_3::generate(std::vector<test_event_entry>& events) const
@@ -236,8 +237,8 @@ bool gen_bp_tx_valid_3::generate(std::vector<test_event_entry>& events) const
const size_t mixin = 10;
const uint64_t amounts_paid[] = {5000, 5000, 5000, (uint64_t)-1};
const size_t bp_sizes[] = {4, (size_t)-1};
- const rct::RangeProofType range_proof_type[] = { rct::RangeProofPaddedBulletproof };
- return generate_with(events, mixin, 1, amounts_paid, true, range_proof_type, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_tx_valid_3"); });
+ const rct::RCTConfig rct_config[] = { { rct::RangeProofPaddedBulletproof , 0 } };
+ return generate_with(events, mixin, 1, amounts_paid, true, rct_config, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_tx_valid_3"); });
}
bool gen_bp_tx_valid_16::generate(std::vector<test_event_entry>& events) const
@@ -245,24 +246,24 @@ bool gen_bp_tx_valid_16::generate(std::vector<test_event_entry>& events) const
const size_t mixin = 10;
const uint64_t amounts_paid[] = {500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, (uint64_t)-1};
const size_t bp_sizes[] = {16, (size_t)-1};
- const rct::RangeProofType range_proof_type[] = { rct::RangeProofPaddedBulletproof };
- return generate_with(events, mixin, 1, amounts_paid, true, range_proof_type, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_tx_valid_16"); });
+ const rct::RCTConfig rct_config[] = { { rct::RangeProofPaddedBulletproof , 0 } };
+ return generate_with(events, mixin, 1, amounts_paid, true, rct_config, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_tx_valid_16"); });
}
bool gen_bp_tx_invalid_4_2_1::generate(std::vector<test_event_entry>& events) const
{
const size_t mixin = 10;
const uint64_t amounts_paid[] = {1000, 1000, 1000, 1000, 1000, 1000, 1000, (uint64_t)-1};
- const rct::RangeProofType range_proof_type[] = { rct::RangeProofMultiOutputBulletproof };
- return generate_with(events, mixin, 1, amounts_paid, false, range_proof_type, NULL, NULL);
+ const rct::RCTConfig rct_config[] = { { rct::RangeProofMultiOutputBulletproof , 0 } };
+ return generate_with(events, mixin, 1, amounts_paid, false, rct_config, NULL, NULL);
}
bool gen_bp_tx_invalid_16_16::generate(std::vector<test_event_entry>& events) const
{
const size_t mixin = 10;
const uint64_t amounts_paid[] = {1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, (uint64_t)-1};
- const rct::RangeProofType range_proof_type[] = { rct::RangeProofMultiOutputBulletproof };
- return generate_with(events, mixin, 1, amounts_paid, false, range_proof_type, NULL, NULL);
+ const rct::RCTConfig rct_config[] = { { rct::RangeProofMultiOutputBulletproof , 0 } };
+ return generate_with(events, mixin, 1, amounts_paid, false, rct_config, NULL, NULL);
}
bool gen_bp_txs_valid_2_and_2::generate(std::vector<test_event_entry>& events) const
@@ -270,25 +271,25 @@ bool gen_bp_txs_valid_2_and_2::generate(std::vector<test_event_entry>& events) c
const size_t mixin = 10;
const uint64_t amounts_paid[] = {1000, 1000, (size_t)-1, 1000, 1000, (uint64_t)-1};
const size_t bp_sizes[] = {2, (size_t)-1, 2, (size_t)-1};
- const rct::RangeProofType range_proof_type[] = { rct::RangeProofPaddedBulletproof, rct::RangeProofPaddedBulletproof};
- return generate_with(events, mixin, 2, amounts_paid, true, range_proof_type, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_txs_valid_2_and_2"); });
+ const rct::RCTConfig rct_config[] = { { rct::RangeProofPaddedBulletproof, 0 }, {rct::RangeProofPaddedBulletproof, 0 } };
+ return generate_with(events, mixin, 2, amounts_paid, true, rct_config, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_txs_valid_2_and_2"); });
}
bool gen_bp_txs_invalid_2_and_8_2_and_16_16_1::generate(std::vector<test_event_entry>& events) const
{
const size_t mixin = 10;
const uint64_t amounts_paid[] = {1000, 1000, (uint64_t)-1, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, (uint64_t)-1, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, (uint64_t)-1};
- const rct::RangeProofType range_proof_type[] = {rct::RangeProofMultiOutputBulletproof, rct::RangeProofMultiOutputBulletproof, rct::RangeProofMultiOutputBulletproof};
- return generate_with(events, mixin, 3, amounts_paid, false, range_proof_type, NULL, NULL);
+ const rct::RCTConfig rct_config[] = {{rct::RangeProofMultiOutputBulletproof, 0}, {rct::RangeProofMultiOutputBulletproof, 0}, {rct::RangeProofMultiOutputBulletproof, 0}};
+ return generate_with(events, mixin, 3, amounts_paid, false, rct_config, NULL, NULL);
}
bool gen_bp_txs_valid_2_and_3_and_2_and_4::generate(std::vector<test_event_entry>& events) const
{
const size_t mixin = 10;
const uint64_t amounts_paid[] = {11111115000, 11111115000, (uint64_t)-1, 11111115000, 11111115000, 11111115001, (uint64_t)-1, 11111115000, 11111115002, (uint64_t)-1, 11111115000, 11111115000, 11111115000, 11111115003, (uint64_t)-1};
- const rct::RangeProofType range_proof_type[] = {rct::RangeProofPaddedBulletproof, rct::RangeProofPaddedBulletproof, rct::RangeProofPaddedBulletproof, rct::RangeProofPaddedBulletproof};
+ const rct::RCTConfig rct_config[] = {{rct::RangeProofPaddedBulletproof, 0}, {rct::RangeProofPaddedBulletproof, 0}, {rct::RangeProofPaddedBulletproof, 0}, {rct::RangeProofPaddedBulletproof, 0}};
const size_t bp_sizes[] = {2, (size_t)-1, 4, (size_t)-1, 2, (size_t)-1, 4, (size_t)-1};
- return generate_with(events, mixin, 4, amounts_paid, true, range_proof_type, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx) { return check_bp(tx, tx_idx, bp_sizes, "gen_bp_txs_valid_2_and_3_and_2_and_4"); });
+ return generate_with(events, mixin, 4, amounts_paid, true, rct_config, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx) { return check_bp(tx, tx_idx, bp_sizes, "gen_bp_txs_valid_2_and_3_and_2_and_4"); });
}
bool gen_bp_tx_invalid_not_enough_proofs::generate(std::vector<test_event_entry>& events) const
@@ -296,9 +297,9 @@ bool gen_bp_tx_invalid_not_enough_proofs::generate(std::vector<test_event_entry>
DEFINE_TESTS_ERROR_CONTEXT("gen_bp_tx_invalid_not_enough_proofs");
const size_t mixin = 10;
const uint64_t amounts_paid[] = {5000, 5000, (uint64_t)-1};
- const rct::RangeProofType range_proof_type[] = { rct::RangeProofBulletproof };
- return generate_with(events, mixin, 1, amounts_paid, false, range_proof_type, NULL, [&](cryptonote::transaction &tx, size_t idx){
- CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeBulletproof);
+ const rct::RCTConfig rct_config[] = { { rct::RangeProofBulletproof, 0 } };
+ return generate_with(events, mixin, 1, amounts_paid, false, rct_config, NULL, [&](cryptonote::transaction &tx, size_t idx){
+ CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeBulletproof || tx.rct_signatures.type == rct::RCTTypeBulletproof2);
CHECK_TEST_CONDITION(!tx.rct_signatures.p.bulletproofs.empty());
tx.rct_signatures.p.bulletproofs.pop_back();
CHECK_TEST_CONDITION(!tx.rct_signatures.p.bulletproofs.empty());
@@ -311,9 +312,9 @@ bool gen_bp_tx_invalid_empty_proofs::generate(std::vector<test_event_entry>& eve
DEFINE_TESTS_ERROR_CONTEXT("gen_bp_tx_invalid_empty_proofs");
const size_t mixin = 10;
const uint64_t amounts_paid[] = {50000, 50000, (uint64_t)-1};
- const rct::RangeProofType range_proof_type[] = { rct::RangeProofBulletproof };
- return generate_with(events, mixin, 1, amounts_paid, false, range_proof_type, NULL, [&](cryptonote::transaction &tx, size_t idx){
- CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeBulletproof);
+ const rct::RCTConfig rct_config[] = { { rct::RangeProofBulletproof, 0 } };
+ return generate_with(events, mixin, 1, amounts_paid, false, rct_config, NULL, [&](cryptonote::transaction &tx, size_t idx){
+ CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeBulletproof || tx.rct_signatures.type == rct::RCTTypeBulletproof2);
tx.rct_signatures.p.bulletproofs.clear();
return true;
});
@@ -324,9 +325,9 @@ bool gen_bp_tx_invalid_too_many_proofs::generate(std::vector<test_event_entry>&
DEFINE_TESTS_ERROR_CONTEXT("gen_bp_tx_invalid_too_many_proofs");
const size_t mixin = 10;
const uint64_t amounts_paid[] = {10000, (uint64_t)-1};
- const rct::RangeProofType range_proof_type[] = { rct::RangeProofBulletproof };
- return generate_with(events, mixin, 1, amounts_paid, false, range_proof_type, NULL, [&](cryptonote::transaction &tx, size_t idx){
- CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeBulletproof);
+ const rct::RCTConfig rct_config[] = { { rct::RangeProofBulletproof, 0 } };
+ return generate_with(events, mixin, 1, amounts_paid, false, rct_config, NULL, [&](cryptonote::transaction &tx, size_t idx){
+ CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeBulletproof || tx.rct_signatures.type == rct::RCTTypeBulletproof2);
CHECK_TEST_CONDITION(!tx.rct_signatures.p.bulletproofs.empty());
tx.rct_signatures.p.bulletproofs.push_back(tx.rct_signatures.p.bulletproofs.back());
return true;
@@ -338,9 +339,9 @@ bool gen_bp_tx_invalid_wrong_amount::generate(std::vector<test_event_entry>& eve
DEFINE_TESTS_ERROR_CONTEXT("gen_bp_tx_invalid_wrong_amount");
const size_t mixin = 10;
const uint64_t amounts_paid[] = {10000, (uint64_t)-1};
- const rct::RangeProofType range_proof_type[] = { rct::RangeProofBulletproof };
- return generate_with(events, mixin, 1, amounts_paid, false, range_proof_type, NULL, [&](cryptonote::transaction &tx, size_t idx){
- CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeBulletproof);
+ const rct::RCTConfig rct_config[] = { { rct::RangeProofBulletproof, 0 } };
+ return generate_with(events, mixin, 1, amounts_paid, false, rct_config, NULL, [&](cryptonote::transaction &tx, size_t idx){
+ CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeBulletproof || tx.rct_signatures.type == rct::RCTTypeBulletproof2);
CHECK_TEST_CONDITION(!tx.rct_signatures.p.bulletproofs.empty());
tx.rct_signatures.p.bulletproofs.back() = rct::bulletproof_PROVE(1000, rct::skGen());
return true;
@@ -352,10 +353,8 @@ bool gen_bp_tx_invalid_borromean_type::generate(std::vector<test_event_entry>& e
DEFINE_TESTS_ERROR_CONTEXT("gen_bp_tx_invalid_borromean_type");
const size_t mixin = 10;
const uint64_t amounts_paid[] = {5000, 5000, (uint64_t)-1};
- const rct::RangeProofType range_proof_type[] = {rct::RangeProofPaddedBulletproof};
- return generate_with(events, mixin, 1, amounts_paid, false, range_proof_type, NULL, [&](cryptonote::transaction &tx, size_t tx_idx){
- CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeBulletproof);
- tx.rct_signatures.type = rct::RCTTypeSimple;
+ const rct::RCTConfig rct_config[] = { { rct::RangeProofBorromean, 0 } };
+ return generate_with(events, mixin, 1, amounts_paid, false, rct_config, NULL, [&](cryptonote::transaction &tx, size_t tx_idx){
return true;
});
}
diff --git a/tests/core_tests/bulletproofs.h b/tests/core_tests/bulletproofs.h
index e29b34690..b0289f355 100644
--- a/tests/core_tests/bulletproofs.h
+++ b/tests/core_tests/bulletproofs.h
@@ -82,7 +82,7 @@ struct gen_bp_tx_validation_base : public test_chain_unit_base
}
bool generate_with(std::vector<test_event_entry>& events, size_t mixin,
- size_t n_txes, const uint64_t *amounts_paid, bool valid, const rct::RangeProofType *range_proof_type,
+ size_t n_txes, const uint64_t *amounts_paid, bool valid, const rct::RCTConfig *rct_config,
const std::function<bool(std::vector<cryptonote::tx_source_entry> &sources, std::vector<cryptonote::tx_destination_entry> &destinations, size_t)> &pre_tx,
const std::function<bool(cryptonote::transaction &tx, size_t)> &post_tx) const;
@@ -95,7 +95,7 @@ private:
template<>
struct get_test_options<gen_bp_tx_validation_base> {
- const std::pair<uint8_t, uint64_t> hard_forks[4] = {std::make_pair(1, 0), std::make_pair(2, 1), std::make_pair(8, 73), std::make_pair(0, 0)};
+ const std::pair<uint8_t, uint64_t> hard_forks[4] = {std::make_pair(1, 0), std::make_pair(2, 1), std::make_pair(10, 73), std::make_pair(0, 0)};
const cryptonote::test_options test_options = {
hard_forks
};
diff --git a/tests/core_tests/multisig.cpp b/tests/core_tests/multisig.cpp
index 46ba997be..37fda6643 100644
--- a/tests/core_tests/multisig.cpp
+++ b/tests/core_tests/multisig.cpp
@@ -365,7 +365,7 @@ bool gen_multisig_tx_validation_base::generate_with(std::vector<test_event_entry
#endif
std::vector<crypto::secret_key> additional_tx_secret_keys;
auto sources_copy = sources;
- r = construct_tx_and_get_tx_key(miner_account[creator].get_keys(), subaddresses, sources, destinations, boost::none, std::vector<uint8_t>(), tx, 0, tx_key, additional_tx_secret_keys, true, rct::RangeProofBorromean, msoutp);
+ r = construct_tx_and_get_tx_key(miner_account[creator].get_keys(), subaddresses, sources, destinations, boost::none, std::vector<uint8_t>(), tx, 0, tx_key, additional_tx_secret_keys, true, { rct::RangeProofBorromean, 0 }, msoutp);
CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction");
#ifndef NO_MULTISIG
@@ -455,7 +455,7 @@ bool gen_multisig_tx_validation_base::generate_with(std::vector<test_event_entry
crypto::secret_key scalar1;
crypto::derivation_to_scalar(derivation, n, scalar1);
rct::ecdhTuple ecdh_info = tx.rct_signatures.ecdhInfo[n];
- rct::ecdhDecode(ecdh_info, rct::sk2rct(scalar1));
+ rct::ecdhDecode(ecdh_info, rct::sk2rct(scalar1), tx.rct_signatures.type == rct::RCTTypeBulletproof2);
rct::key C = tx.rct_signatures.outPk[n].mask;
rct::addKeys2(Ctmp, ecdh_info.mask, ecdh_info.amount, rct::H);
CHECK_AND_ASSERT_MES(rct::equalKeys(C, Ctmp), false, "Failed to decode amount");
diff --git a/tests/core_tests/rct.cpp b/tests/core_tests/rct.cpp
index 342c3f1ee..bb7dd013b 100644
--- a/tests/core_tests/rct.cpp
+++ b/tests/core_tests/rct.cpp
@@ -133,7 +133,8 @@ bool gen_rct_tx_validation_base::generate_with(std::vector<test_event_entry>& ev
CHECK_AND_ASSERT_MES(r, false, "Failed to generate key derivation");
crypto::secret_key amount_key;
crypto::derivation_to_scalar(derivation, o, amount_key);
- if (rct_txes[n].rct_signatures.type == rct::RCTTypeSimple || rct_txes[n].rct_signatures.type == rct::RCTTypeBulletproof)
+ const uint8_t type = rct_txes[n].rct_signatures.type;
+ if (type == rct::RCTTypeSimple || type == rct::RCTTypeBulletproof || type == rct::RCTTypeBulletproof2)
rct::decodeRctSimple(rct_txes[n].rct_signatures, rct::sk2rct(amount_key), o, rct_tx_masks[o+n*4], hw::get_device("default"));
else
rct::decodeRct(rct_txes[n].rct_signatures, rct::sk2rct(amount_key), o, rct_tx_masks[o+n*4], hw::get_device("default"));
diff --git a/tests/core_tests/v2_tests.h b/tests/core_tests/v2_tests.h
index ecb23818c..cd2bcb839 100644
--- a/tests/core_tests/v2_tests.h
+++ b/tests/core_tests/v2_tests.h
@@ -81,7 +81,7 @@ template<>
struct get_test_options<gen_v2_tx_validation_base> {
const std::pair<uint8_t, uint64_t> hard_forks[3] = {std::make_pair(1, 0), std::make_pair(2, 1), std::make_pair(0, 0)};
const cryptonote::test_options test_options = {
- hard_forks
+ hard_forks, 0
};
};
diff --git a/tests/crypto/CMakeLists.txt b/tests/crypto/CMakeLists.txt
index df96c57cc..8789cb552 100644
--- a/tests/crypto/CMakeLists.txt
+++ b/tests/crypto/CMakeLists.txt
@@ -52,3 +52,17 @@ set_property(TARGET cncrypto-tests
add_test(
NAME cncrypto
COMMAND cncrypto-tests "${CMAKE_CURRENT_SOURCE_DIR}/tests.txt")
+
+add_executable(cnv4-jit-tests cnv4-jit.c)
+target_link_libraries(cnv4-jit-tests
+ PRIVATE
+ crypto
+ common
+ ${EXTRA_LIBRARIES})
+set_property(TARGET cnv4-jit-tests
+ PROPERTY
+ FOLDER "tests")
+
+add_test(
+ NAME cnv4-jit
+ COMMAND cnv4-jit-tests 1788000 1789000)
diff --git a/tests/crypto/cnv4-jit.c b/tests/crypto/cnv4-jit.c
new file mode 100644
index 000000000..0f11e4393
--- /dev/null
+++ b/tests/crypto/cnv4-jit.c
@@ -0,0 +1,119 @@
+// Copyright (c) 2019, 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.
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include "crypto/hash-ops.h"
+
+extern volatile int use_v4_jit_flag;
+
+static int test(const uint8_t *data, size_t len, uint64_t height)
+{
+ char hash0[32], hash1[32];
+ use_v4_jit_flag = 0;
+ cn_slow_hash(data, len, hash0, 4, 0, height);
+ use_v4_jit_flag = 1;
+ cn_slow_hash(data, len, hash1, 4, 0, height);
+ return memcmp(hash0, hash1, 32);
+}
+
+int main(int argc, char **argv)
+{
+ uint8_t data[64];
+ uint64_t start_height = 1788000;
+ uint64_t end_height = 1788001;
+
+ if (argc != 1 && argc != 2 && argc != 3)
+ {
+ fprintf(stderr, "usage: %s [<start_height> [<end_height>]]\n", argv[0]);
+ return 1;
+ }
+ if (argc > 1)
+ {
+ errno = 0;
+ start_height = strtoull(argv[1], NULL, 10);
+ if ((start_height == 0 && errno) || start_height == ULLONG_MAX)
+ {
+ fprintf(stderr, "invalid start_height\n");
+ return 1;
+ }
+ end_height = start_height;
+ if (argc > 2)
+ {
+ errno = 0;
+ end_height = strtoull(argv[2], NULL, 10);
+ if ((end_height == 0 && errno) || end_height == ULLONG_MAX)
+ {
+ fprintf(stderr, "invalid end_height\n");
+ return 1;
+ }
+ }
+ }
+
+ if (start_height == end_height)
+ {
+ uint64_t counter = 0;
+ while (1)
+ {
+ printf("\r%llu", (unsigned long long)counter);
+ fflush(stdout);
+ size_t offset = 0;
+ while (offset + 8 < sizeof(data))
+ {
+ memcpy(data + offset, &counter, sizeof(counter));
+ offset += 8;
+ }
+ if (test(data, sizeof(data), start_height))
+ {
+ fprintf(stderr, "\nFailure at height %llu, counter %llu\n", (unsigned long long)start_height, (unsigned long long)counter);
+ return 0;
+ }
+ ++counter;
+ }
+ }
+
+ memset(data, 0x42, sizeof(data));
+ for (uint64_t h = start_height; h < end_height; ++h)
+ {
+ printf("\r%llu/%llu", (unsigned long long)(h-start_height), (unsigned long long)(end_height-start_height));
+ fflush(stdout);
+ if (test(data, sizeof(data), h))
+ {
+ fprintf(stderr, "\nFailure at height %llu\n", (unsigned long long)h);
+ return 0;
+ }
+ }
+
+ printf("\r");
+
+ return 0;
+}
diff --git a/tests/hash/CMakeLists.txt b/tests/hash/CMakeLists.txt
index 433cf94e9..105cf2c13 100644
--- a/tests/hash/CMakeLists.txt
+++ b/tests/hash/CMakeLists.txt
@@ -43,7 +43,7 @@ set_property(TARGET hash-tests
PROPERTY
FOLDER "tests")
-foreach (hash IN ITEMS fast slow slow-1 slow-2 tree extra-blake extra-groestl extra-jh extra-skein)
+foreach (hash IN ITEMS fast slow slow-1 slow-2 slow-4 tree extra-blake extra-groestl extra-jh extra-skein)
add_test(
NAME "hash-${hash}"
COMMAND hash-tests "${hash}" "${CMAKE_CURRENT_SOURCE_DIR}/tests-${hash}.txt")
diff --git a/tests/hash/main.cpp b/tests/hash/main.cpp
index 7767d0d3b..acfd99e96 100644
--- a/tests/hash/main.cpp
+++ b/tests/hash/main.cpp
@@ -44,6 +44,13 @@ using namespace std;
using namespace crypto;
typedef crypto::hash chash;
+struct V4_Data
+{
+ const void* data;
+ size_t length;
+ uint64_t height;
+};
+
PUSH_WARNINGS
DISABLE_VS_WARNINGS(4297)
extern "C" {
@@ -54,13 +61,17 @@ extern "C" {
tree_hash((const char (*)[crypto::HASH_SIZE]) data, length >> 5, hash);
}
static void cn_slow_hash_0(const void *data, size_t length, char *hash) {
- return cn_slow_hash(data, length, hash, 0/*variant*/, 0/*prehashed*/);
+ return cn_slow_hash(data, length, hash, 0/*variant*/, 0/*prehashed*/, 0/*height*/);
}
static void cn_slow_hash_1(const void *data, size_t length, char *hash) {
- return cn_slow_hash(data, length, hash, 1/*variant*/, 0/*prehashed*/);
+ return cn_slow_hash(data, length, hash, 1/*variant*/, 0/*prehashed*/, 0/*height*/);
}
static void cn_slow_hash_2(const void *data, size_t length, char *hash) {
- return cn_slow_hash(data, length, hash, 2/*variant*/, 0/*prehashed*/);
+ return cn_slow_hash(data, length, hash, 2/*variant*/, 0/*prehashed*/, 0/*height*/);
+ }
+ static void cn_slow_hash_4(const void *data, size_t, char *hash) {
+ const V4_Data* p = reinterpret_cast<const V4_Data*>(data);
+ return cn_slow_hash(p->data, p->length, hash, 4/*variant*/, 0/*prehashed*/, p->height);
}
}
POP_WARNINGS
@@ -72,7 +83,7 @@ struct hash_func {
} hashes[] = {{"fast", cn_fast_hash}, {"slow", cn_slow_hash_0}, {"tree", hash_tree},
{"extra-blake", hash_extra_blake}, {"extra-groestl", hash_extra_groestl},
{"extra-jh", hash_extra_jh}, {"extra-skein", hash_extra_skein},
- {"slow-1", cn_slow_hash_1}, {"slow-2", cn_slow_hash_2}};
+ {"slow-1", cn_slow_hash_1}, {"slow-2", cn_slow_hash_2}, {"slow-4", cn_slow_hash_4}};
int test_variant2_int_sqrt();
int test_variant2_int_sqrt_ref();
@@ -140,7 +151,15 @@ int main(int argc, char *argv[]) {
input.exceptions(ios_base::badbit | ios_base::failbit | ios_base::eofbit);
input.clear(input.rdstate());
get(input, data);
- f(data.data(), data.size(), (char *) &actual);
+ if (f == cn_slow_hash_4) {
+ V4_Data d;
+ d.data = data.data();
+ d.length = data.size();
+ get(input, d.height);
+ f(&d, 0, (char *) &actual);
+ } else {
+ f(data.data(), data.size(), (char *) &actual);
+ }
if (expected != actual) {
size_t i;
cerr << "Hash mismatch on test " << test << endl << "Input: ";
diff --git a/tests/hash/tests-slow-4.txt b/tests/hash/tests-slow-4.txt
new file mode 100644
index 000000000..06ab52cff
--- /dev/null
+++ b/tests/hash/tests-slow-4.txt
@@ -0,0 +1,10 @@
+f759588ad57e758467295443a9bd71490abff8e9dad1b95b6bf2f5d0d78387bc 5468697320697320612074657374205468697320697320612074657374205468697320697320612074657374 1806260
+5bb833deca2bdd7252a9ccd7b4ce0b6a4854515794b56c207262f7a5b9bdb566 4c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e73656374657475722061646970697363696e67 1806261
+1ee6728da60fbd8d7d55b2b1ade487a3cf52a2c3ac6f520db12c27d8921f6cab 656c69742c2073656420646f20656975736d6f642074656d706f7220696e6369646964756e74207574206c61626f7265 1806262
+6969fe2ddfb758438d48049f302fc2108a4fcc93e37669170e6db4b0b9b4c4cb 657420646f6c6f7265206d61676e6120616c697175612e20557420656e696d206164206d696e696d2076656e69616d2c 1806263
+7f3048b4e90d0cbe7a57c0394f37338a01fae3adfdc0e5126d863a895eb04e02 71756973206e6f737472756420657865726369746174696f6e20756c6c616d636f206c61626f726973206e697369 1806264
+1d290443a4b542af04a82f6b2494a6ee7f20f2754c58e0849032483a56e8e2ef 757420616c697175697020657820656120636f6d6d6f646f20636f6e7365717561742e20447569732061757465 1806265
+c43cc6567436a86afbd6aa9eaa7c276e9806830334b614b2bee23cc76634f6fd 697275726520646f6c6f7220696e20726570726568656e646572697420696e20766f6c7570746174652076656c6974 1806266
+87be2479c0c4e8edfdfaa5603e93f4265b3f8224c1c5946feb424819d18990a4 657373652063696c6c756d20646f6c6f726520657520667567696174206e756c6c612070617269617475722e 1806267
+dd9d6a6d8e47465cceac0877ef889b93e7eba979557e3935d7f86dce11b070f3 4578636570746575722073696e74206f6363616563617420637570696461746174206e6f6e2070726f6964656e742c 1806268
+75c6f2ae49a20521de97285b431e717125847fb8935ed84a61e7f8d36a2c3d8e 73756e7420696e2063756c706120717569206f666669636961206465736572756e74206d6f6c6c697420616e696d20696420657374206c61626f72756d2e 1806269
diff --git a/tests/performance_tests/check_tx_signature.h b/tests/performance_tests/check_tx_signature.h
index ee382d9ad..755d8f941 100644
--- a/tests/performance_tests/check_tx_signature.h
+++ b/tests/performance_tests/check_tx_signature.h
@@ -40,7 +40,7 @@
#include "multi_tx_test_base.h"
-template<size_t a_ring_size, size_t a_outputs, bool a_rct, rct::RangeProofType range_proof_type = rct::RangeProofBorromean>
+template<size_t a_ring_size, size_t a_outputs, bool a_rct, rct::RangeProofType range_proof_type = rct::RangeProofBorromean, int bp_version = 2>
class test_check_tx_signature : private multi_tx_test_base<a_ring_size>
{
static_assert(0 < a_ring_size, "ring_size must be greater than 0");
@@ -71,7 +71,8 @@ public:
std::vector<crypto::secret_key> additional_tx_keys;
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
subaddresses[this->m_miners[this->real_source_idx].get_keys().m_account_address.m_spend_public_key] = {0,0};
- if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_tx, 0, tx_key, additional_tx_keys, rct, range_proof_type))
+ rct::RCTConfig rct_config{range_proof_type, bp_version};
+ if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_tx, 0, tx_key, additional_tx_keys, rct, rct_config))
return false;
get_transaction_prefix_hash(m_tx, m_tx_prefix_hash);
@@ -135,7 +136,7 @@ public:
m_txes.resize(a_num_txes + (extra_outs > 0 ? 1 : 0));
for (size_t n = 0; n < a_num_txes; ++n)
{
- if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_txes[n], 0, tx_key, additional_tx_keys, true, rct::RangeProofPaddedBulletproof))
+ if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_txes[n], 0, tx_key, additional_tx_keys, true, {rct::RangeProofPaddedBulletproof, 2}))
return false;
}
@@ -146,7 +147,7 @@ public:
for (size_t n = 1; n < extra_outs; ++n)
destinations.push_back(tx_destination_entry(1, m_alice.get_keys().m_account_address, false));
- if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_txes.back(), 0, tx_key, additional_tx_keys, true, rct::RangeProofMultiOutputBulletproof))
+ if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_txes.back(), 0, tx_key, additional_tx_keys, true, {rct::RangeProofMultiOutputBulletproof, 2}))
return false;
}
diff --git a/tests/performance_tests/cn_slow_hash.h b/tests/performance_tests/cn_slow_hash.h
index b484afa41..79ebb8778 100644
--- a/tests/performance_tests/cn_slow_hash.h
+++ b/tests/performance_tests/cn_slow_hash.h
@@ -34,6 +34,7 @@
#include "crypto/crypto.h"
#include "cryptonote_basic/cryptonote_basic.h"
+template<unsigned int variant>
class test_cn_slow_hash
{
public:
@@ -42,18 +43,15 @@ public:
#pragma pack(push, 1)
struct data_t
{
- char data[13];
+ char data[43];
};
#pragma pack(pop)
- static_assert(13 == sizeof(data_t), "Invalid structure size");
+ static_assert(43 == sizeof(data_t), "Invalid structure size");
bool init()
{
- if (!epee::string_tools::hex_to_pod("63617665617420656d70746f72", m_data))
- return false;
-
- if (!epee::string_tools::hex_to_pod("bbec2cacf69866a8e740380fe7b818fc78f8571221742d729d9d02d7f8989b87", m_expected_hash))
+ if (!epee::string_tools::hex_to_pod("63617665617420656d70746f763617665617420656d70746f72263617665617420656d70746f7201020304", m_data))
return false;
return true;
@@ -62,11 +60,10 @@ public:
bool test()
{
crypto::hash hash;
- crypto::cn_slow_hash(&m_data, sizeof(m_data), hash);
- return hash == m_expected_hash;
+ crypto::cn_slow_hash(&m_data, sizeof(m_data), hash, variant);
+ return true;
}
private:
data_t m_data;
- crypto::hash m_expected_hash;
};
diff --git a/tests/performance_tests/construct_tx.h b/tests/performance_tests/construct_tx.h
index 378065ddd..71d42073d 100644
--- a/tests/performance_tests/construct_tx.h
+++ b/tests/performance_tests/construct_tx.h
@@ -36,7 +36,7 @@
#include "multi_tx_test_base.h"
-template<size_t a_in_count, size_t a_out_count, bool a_rct, rct::RangeProofType range_proof_type = rct::RangeProofBorromean>
+template<size_t a_in_count, size_t a_out_count, bool a_rct, rct::RangeProofType range_proof_type = rct::RangeProofBorromean, int bp_version = 2>
class test_construct_tx : private multi_tx_test_base<a_in_count>
{
static_assert(0 < a_in_count, "in_count must be greater than 0");
@@ -73,7 +73,8 @@ public:
std::vector<crypto::secret_key> additional_tx_keys;
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
subaddresses[this->m_miners[this->real_source_idx].get_keys().m_account_address.m_spend_public_key] = {0,0};
- return cryptonote::construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, m_destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_tx, 0, tx_key, additional_tx_keys, rct, range_proof_type);
+ rct::RCTConfig rct_config{range_proof_type, bp_version};
+ return cryptonote::construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, m_destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_tx, 0, tx_key, additional_tx_keys, rct, rct_config);
}
private:
diff --git a/tests/performance_tests/main.cpp b/tests/performance_tests/main.cpp
index 6749b71e4..86450760c 100644
--- a/tests/performance_tests/main.cpp
+++ b/tests/performance_tests/main.cpp
@@ -134,17 +134,17 @@ int main(int argc, char** argv)
TEST_PERFORMANCE3(filter, p, test_construct_tx, 100, 2, true);
TEST_PERFORMANCE3(filter, p, test_construct_tx, 100, 10, true);
- TEST_PERFORMANCE4(filter, p, test_construct_tx, 2, 1, true, rct::RangeProofPaddedBulletproof);
- TEST_PERFORMANCE4(filter, p, test_construct_tx, 2, 2, true, rct::RangeProofPaddedBulletproof);
- TEST_PERFORMANCE4(filter, p, test_construct_tx, 2, 10, true, rct::RangeProofPaddedBulletproof);
+ TEST_PERFORMANCE5(filter, p, test_construct_tx, 2, 1, true, rct::RangeProofPaddedBulletproof, 2);
+ TEST_PERFORMANCE5(filter, p, test_construct_tx, 2, 2, true, rct::RangeProofPaddedBulletproof, 2);
+ TEST_PERFORMANCE5(filter, p, test_construct_tx, 2, 10, true, rct::RangeProofPaddedBulletproof, 2);
- TEST_PERFORMANCE4(filter, p, test_construct_tx, 10, 1, true, rct::RangeProofPaddedBulletproof);
- TEST_PERFORMANCE4(filter, p, test_construct_tx, 10, 2, true, rct::RangeProofPaddedBulletproof);
- TEST_PERFORMANCE4(filter, p, test_construct_tx, 10, 10, true, rct::RangeProofPaddedBulletproof);
+ TEST_PERFORMANCE5(filter, p, test_construct_tx, 10, 1, true, rct::RangeProofPaddedBulletproof, 2);
+ TEST_PERFORMANCE5(filter, p, test_construct_tx, 10, 2, true, rct::RangeProofPaddedBulletproof, 2);
+ TEST_PERFORMANCE5(filter, p, test_construct_tx, 10, 10, true, rct::RangeProofPaddedBulletproof, 2);
- TEST_PERFORMANCE4(filter, p, test_construct_tx, 100, 1, true, rct::RangeProofPaddedBulletproof);
- TEST_PERFORMANCE4(filter, p, test_construct_tx, 100, 2, true, rct::RangeProofPaddedBulletproof);
- TEST_PERFORMANCE4(filter, p, test_construct_tx, 100, 10, true, rct::RangeProofPaddedBulletproof);
+ TEST_PERFORMANCE5(filter, p, test_construct_tx, 100, 1, true, rct::RangeProofPaddedBulletproof, 2);
+ TEST_PERFORMANCE5(filter, p, test_construct_tx, 100, 2, true, rct::RangeProofPaddedBulletproof, 2);
+ TEST_PERFORMANCE5(filter, p, test_construct_tx, 100, 10, true, rct::RangeProofPaddedBulletproof, 2);
TEST_PERFORMANCE3(filter, p, test_check_tx_signature, 1, 2, false);
TEST_PERFORMANCE3(filter, p, test_check_tx_signature, 2, 2, false);
@@ -157,14 +157,14 @@ int main(int argc, char** argv)
TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 100, 2, true, rct::RangeProofBorromean);
TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 2, 10, true, rct::RangeProofBorromean);
- TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 2, 2, true, rct::RangeProofPaddedBulletproof);
- TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 2, 2, true, rct::RangeProofMultiOutputBulletproof);
- TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 10, 2, true, rct::RangeProofPaddedBulletproof);
- TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 10, 2, true, rct::RangeProofMultiOutputBulletproof);
- TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 100, 2, true, rct::RangeProofPaddedBulletproof);
- TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 100, 2, true, rct::RangeProofMultiOutputBulletproof);
- TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 2, 10, true, rct::RangeProofPaddedBulletproof);
- TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 2, 10, true, rct::RangeProofMultiOutputBulletproof);
+ TEST_PERFORMANCE5(filter, p, test_check_tx_signature, 2, 2, true, rct::RangeProofPaddedBulletproof, 2);
+ TEST_PERFORMANCE5(filter, p, test_check_tx_signature, 2, 2, true, rct::RangeProofMultiOutputBulletproof, 2);
+ TEST_PERFORMANCE5(filter, p, test_check_tx_signature, 10, 2, true, rct::RangeProofPaddedBulletproof, 2);
+ TEST_PERFORMANCE5(filter, p, test_check_tx_signature, 10, 2, true, rct::RangeProofMultiOutputBulletproof, 2);
+ TEST_PERFORMANCE5(filter, p, test_check_tx_signature, 100, 2, true, rct::RangeProofPaddedBulletproof, 2);
+ TEST_PERFORMANCE5(filter, p, test_check_tx_signature, 100, 2, true, rct::RangeProofMultiOutputBulletproof, 2);
+ TEST_PERFORMANCE5(filter, p, test_check_tx_signature, 2, 10, true, rct::RangeProofPaddedBulletproof, 2);
+ TEST_PERFORMANCE5(filter, p, test_check_tx_signature, 2, 10, true, rct::RangeProofMultiOutputBulletproof, 2);
TEST_PERFORMANCE3(filter, p, test_check_tx_signature_aggregated_bulletproofs, 2, 2, 64);
TEST_PERFORMANCE3(filter, p, test_check_tx_signature_aggregated_bulletproofs, 10, 2, 64);
@@ -193,7 +193,10 @@ int main(int argc, char** argv)
TEST_PERFORMANCE2(filter, p, test_wallet2_expand_subaddresses, 50, 200);
- TEST_PERFORMANCE0(filter, p, test_cn_slow_hash);
+ TEST_PERFORMANCE1(filter, p, test_cn_slow_hash, 0);
+ TEST_PERFORMANCE1(filter, p, test_cn_slow_hash, 1);
+ TEST_PERFORMANCE1(filter, p, test_cn_slow_hash, 2);
+ TEST_PERFORMANCE1(filter, p, test_cn_slow_hash, 4);
TEST_PERFORMANCE1(filter, p, test_cn_fast_hash, 32);
TEST_PERFORMANCE1(filter, p, test_cn_fast_hash, 16384);
diff --git a/tests/unit_tests/CMakeLists.txt b/tests/unit_tests/CMakeLists.txt
index f7012746d..aea82ede2 100644
--- a/tests/unit_tests/CMakeLists.txt
+++ b/tests/unit_tests/CMakeLists.txt
@@ -55,6 +55,7 @@ set(unit_tests_sources
http.cpp
keccak.cpp
logging.cpp
+ long_term_block_weight.cpp
main.cpp
memwipe.cpp
mlocker.cpp
@@ -62,9 +63,11 @@ set(unit_tests_sources
mul_div.cpp
multiexp.cpp
multisig.cpp
+ net.cpp
notify.cpp
output_distribution.cpp
parse_amount.cpp
+ pruning.cpp
random.cpp
serialization.cpp
sha256.cpp
@@ -99,6 +102,7 @@ target_link_libraries(unit_tests
cryptonote_core
blockchain_db
rpc
+ net
serialization
wallet
p2p
diff --git a/tests/unit_tests/ban.cpp b/tests/unit_tests/ban.cpp
index 12625a949..1e764c83e 100644
--- a/tests/unit_tests/ban.cpp
+++ b/tests/unit_tests/ban.cpp
@@ -84,6 +84,8 @@ public:
bool fluffy_blocks_enabled() const { return false; }
uint64_t prevalidate_block_hashes(uint64_t height, const std::vector<crypto::hash> &hashes) { return 0; }
bool pad_transactions() { return false; }
+ uint32_t get_blockchain_pruning_seed() const { return 0; }
+ bool prune_blockchain(uint32_t pruning_seed = 0) { return true; }
void stop() {}
};
diff --git a/tests/unit_tests/blockchain_db.cpp b/tests/unit_tests/blockchain_db.cpp
index 7e7ce9bf7..9cf8c5fbe 100644
--- a/tests/unit_tests/blockchain_db.cpp
+++ b/tests/unit_tests/blockchain_db.cpp
@@ -277,10 +277,10 @@ TYPED_TEST(BlockchainDBTest, AddBlock)
// TODO: need at least one more block to make this reasonable, as the
// BlockchainDB implementation should not check for parent if
// no blocks have been added yet (because genesis has no parent).
- //ASSERT_THROW(this->m_db->add_block(this->m_blocks[1], t_sizes[1], t_diffs[1], t_coins[1], this->m_txs[1]), BLOCK_PARENT_DNE);
+ //ASSERT_THROW(this->m_db->add_block(this->m_blocks[1], t_sizes[1], t_sizes[1], t_diffs[1], t_coins[1], this->m_txs[1]), BLOCK_PARENT_DNE);
- ASSERT_NO_THROW(this->m_db->add_block(this->m_blocks[0], t_sizes[0], t_diffs[0], t_coins[0], this->m_txs[0]));
- ASSERT_NO_THROW(this->m_db->add_block(this->m_blocks[1], t_sizes[1], t_diffs[1], t_coins[1], this->m_txs[1]));
+ ASSERT_NO_THROW(this->m_db->add_block(this->m_blocks[0], t_sizes[0], t_sizes[0], t_diffs[0], t_coins[0], this->m_txs[0]));
+ ASSERT_NO_THROW(this->m_db->add_block(this->m_blocks[1], t_sizes[1], t_sizes[1], t_diffs[1], t_coins[1], this->m_txs[1]));
block b;
ASSERT_TRUE(this->m_db->block_exists(get_block_hash(this->m_blocks[0])));
@@ -293,7 +293,7 @@ TYPED_TEST(BlockchainDBTest, AddBlock)
ASSERT_TRUE(compare_blocks(this->m_blocks[0], b));
// assert that we can't add the same block twice
- ASSERT_THROW(this->m_db->add_block(this->m_blocks[0], t_sizes[0], t_diffs[0], t_coins[0], this->m_txs[0]), TX_EXISTS);
+ ASSERT_THROW(this->m_db->add_block(this->m_blocks[0], t_sizes[0], t_sizes[0], t_diffs[0], t_coins[0], this->m_txs[0]), TX_EXISTS);
for (auto& h : this->m_blocks[0].tx_hashes)
{
@@ -317,14 +317,14 @@ TYPED_TEST(BlockchainDBTest, RetrieveBlockData)
this->get_filenames();
this->init_hard_fork();
- ASSERT_NO_THROW(this->m_db->add_block(this->m_blocks[0], t_sizes[0], t_diffs[0], t_coins[0], this->m_txs[0]));
+ ASSERT_NO_THROW(this->m_db->add_block(this->m_blocks[0], t_sizes[0], t_sizes[0], t_diffs[0], t_coins[0], this->m_txs[0]));
ASSERT_EQ(t_sizes[0], this->m_db->get_block_weight(0));
ASSERT_EQ(t_diffs[0], this->m_db->get_block_cumulative_difficulty(0));
ASSERT_EQ(t_diffs[0], this->m_db->get_block_difficulty(0));
ASSERT_EQ(t_coins[0], this->m_db->get_block_already_generated_coins(0));
- ASSERT_NO_THROW(this->m_db->add_block(this->m_blocks[1], t_sizes[1], t_diffs[1], t_coins[1], this->m_txs[1]));
+ ASSERT_NO_THROW(this->m_db->add_block(this->m_blocks[1], t_sizes[1], t_sizes[1], t_diffs[1], t_coins[1], this->m_txs[1]));
ASSERT_EQ(t_diffs[1] - t_diffs[0], this->m_db->get_block_difficulty(1));
ASSERT_HASH_EQ(get_block_hash(this->m_blocks[0]), this->m_db->get_block_hash_from_height(0));
diff --git a/tests/unit_tests/bulletproofs.cpp b/tests/unit_tests/bulletproofs.cpp
index ac6eaca0b..4f07415b0 100644
--- a/tests/unit_tests/bulletproofs.cpp
+++ b/tests/unit_tests/bulletproofs.cpp
@@ -131,7 +131,8 @@ TEST(bulletproofs, multi_splitting)
}
rct::ctkeyV outSk;
- rct::rctSig s = rct::genRctSimple(rct::zero(), sc, destinations, inamounts, outamounts, available, mixRing, amount_keys, NULL, NULL, index, outSk, rct::RangeProofPaddedBulletproof, hw::get_device("default"));
+ rct::RCTConfig rct_config { rct::RangeProofPaddedBulletproof, 0 };
+ rct::rctSig s = rct::genRctSimple(rct::zero(), sc, destinations, inamounts, outamounts, available, mixRing, amount_keys, NULL, NULL, index, outSk, rct_config, hw::get_device("default"));
ASSERT_TRUE(rct::verRctSimple(s));
for (size_t i = 0; i < n_outputs; ++i)
{
diff --git a/tests/unit_tests/device.cpp b/tests/unit_tests/device.cpp
index 50ccec9fa..c0e8fecc1 100644
--- a/tests/unit_tests/device.cpp
+++ b/tests/unit_tests/device.cpp
@@ -114,18 +114,17 @@ TEST(device, ops)
ASSERT_EQ(ki0, ki1);
}
-TEST(device, ecdh)
+TEST(device, ecdh32)
{
hw::core::device_default dev;
rct::ecdhTuple tuple, tuple2;
rct::key key = rct::skGen();
tuple.mask = rct::skGen();
tuple.amount = rct::skGen();
- tuple.senderPk = rct::pkGen();
tuple2 = tuple;
- dev.ecdhEncode(tuple, key);
- dev.ecdhDecode(tuple, key);
+ dev.ecdhEncode(tuple, key, false);
+ dev.ecdhDecode(tuple, key, false);
ASSERT_EQ(tuple2.mask, tuple.mask);
ASSERT_EQ(tuple2.amount, tuple.amount);
- ASSERT_EQ(tuple2.senderPk, tuple.senderPk);
}
+
diff --git a/tests/unit_tests/epee_utils.cpp b/tests/unit_tests/epee_utils.cpp
index 3d5882d7d..18fb262c2 100644
--- a/tests/unit_tests/epee_utils.cpp
+++ b/tests/unit_tests/epee_utils.cpp
@@ -545,6 +545,8 @@ TEST(StringTools, GetIpInt32)
TEST(NetUtils, IPv4NetworkAddress)
{
+ static_assert(epee::net_utils::ipv4_network_address::get_type_id() == epee::net_utils::address_type::ipv4, "bad ipv4 type id");
+
const auto ip1 = boost::endian::native_to_big(0x330012FFu);
const auto ip_loopback = boost::endian::native_to_big(0x7F000001u);
const auto ip_local = boost::endian::native_to_big(0x0A000000u);
@@ -555,7 +557,7 @@ TEST(NetUtils, IPv4NetworkAddress)
EXPECT_STREQ("51.0.18.255", address1.host_str().c_str());
EXPECT_FALSE(address1.is_loopback());
EXPECT_FALSE(address1.is_local());
- EXPECT_EQ(epee::net_utils::ipv4_network_address::ID, address1.get_type_id());
+ EXPECT_EQ(epee::net_utils::ipv4_network_address::get_type_id(), address1.get_type_id());
EXPECT_EQ(ip1, address1.ip());
EXPECT_EQ(65535, address1.port());
EXPECT_TRUE(epee::net_utils::ipv4_network_address{std::move(address1)} == address1);
@@ -568,7 +570,7 @@ TEST(NetUtils, IPv4NetworkAddress)
EXPECT_STREQ("127.0.0.1", loopback.host_str().c_str());
EXPECT_TRUE(loopback.is_loopback());
EXPECT_FALSE(loopback.is_local());
- EXPECT_EQ(epee::net_utils::ipv4_network_address::ID, address1.get_type_id());
+ EXPECT_EQ(epee::net_utils::ipv4_network_address::get_type_id(), address1.get_type_id());
EXPECT_EQ(ip_loopback, loopback.ip());
EXPECT_EQ(0, loopback.port());
@@ -624,7 +626,9 @@ TEST(NetUtils, NetworkAddress)
constexpr static bool is_local() noexcept { return false; }
static std::string str() { return {}; }
static std::string host_str() { return {}; }
- constexpr static uint8_t get_type_id() noexcept { return uint8_t(-1); }
+ constexpr static epee::net_utils::address_type get_type_id() noexcept { return epee::net_utils::address_type(-1); }
+ constexpr static epee::net_utils::zone get_zone() noexcept { return epee::net_utils::zone::invalid; }
+ constexpr static bool is_blockable() noexcept { return false; }
};
const epee::net_utils::network_address empty;
@@ -634,7 +638,9 @@ TEST(NetUtils, NetworkAddress)
EXPECT_STREQ("<none>", empty.host_str().c_str());
EXPECT_FALSE(empty.is_loopback());
EXPECT_FALSE(empty.is_local());
- EXPECT_EQ(0, empty.get_type_id());
+ EXPECT_EQ(epee::net_utils::address_type::invalid, empty.get_type_id());
+ EXPECT_EQ(epee::net_utils::zone::invalid, empty.get_zone());
+ EXPECT_FALSE(empty.is_blockable());
EXPECT_THROW(empty.as<custom_address>(), std::bad_cast);
epee::net_utils::network_address address1{
@@ -650,7 +656,9 @@ TEST(NetUtils, NetworkAddress)
EXPECT_STREQ("51.0.18.255", address1.host_str().c_str());
EXPECT_FALSE(address1.is_loopback());
EXPECT_FALSE(address1.is_local());
- EXPECT_EQ(epee::net_utils::ipv4_network_address::ID, address1.get_type_id());
+ EXPECT_EQ(epee::net_utils::ipv4_network_address::get_type_id(), address1.get_type_id());
+ EXPECT_EQ(epee::net_utils::zone::public_, address1.get_zone());
+ EXPECT_TRUE(address1.is_blockable());
EXPECT_NO_THROW(address1.as<epee::net_utils::ipv4_network_address>());
EXPECT_THROW(address1.as<custom_address>(), std::bad_cast);
@@ -667,7 +675,9 @@ TEST(NetUtils, NetworkAddress)
EXPECT_STREQ("127.0.0.1", loopback.host_str().c_str());
EXPECT_TRUE(loopback.is_loopback());
EXPECT_FALSE(loopback.is_local());
- EXPECT_EQ(epee::net_utils::ipv4_network_address::ID, address1.get_type_id());
+ EXPECT_EQ(epee::net_utils::ipv4_network_address::get_type_id(), address1.get_type_id());
+ EXPECT_EQ(epee::net_utils::zone::public_, address1.get_zone());
+ EXPECT_EQ(epee::net_utils::ipv4_network_address::get_type_id(), address1.get_type_id());
const epee::net_utils::network_address local{
epee::net_utils::ipv4_network_address{ip_local, 8080}
diff --git a/tests/unit_tests/hardfork.cpp b/tests/unit_tests/hardfork.cpp
index ec8d1d202..12dfde1bc 100644
--- a/tests/unit_tests/hardfork.cpp
+++ b/tests/unit_tests/hardfork.cpp
@@ -34,7 +34,7 @@
#include "blockchain_db/blockchain_db.h"
#include "cryptonote_basic/cryptonote_format_utils.h"
#include "cryptonote_basic/hardfork.h"
-#include "testdb.h"
+#include "blockchain_db/testdb.h"
using namespace cryptonote;
@@ -44,11 +44,12 @@ using namespace cryptonote;
namespace
{
-class TestDB: public BaseTestDB {
+class TestDB: public cryptonote::BaseTestDB {
public:
virtual uint64_t height() const { return blocks.size(); }
virtual void add_block( const block& blk
, size_t block_weight
+ , uint64_t long_term_block_weight
, const difficulty_type& cumulative_difficulty
, const uint64_t& coins_generated
, uint64_t num_rct_outs
@@ -106,20 +107,20 @@ TEST(major, Only)
ASSERT_FALSE(hf.add(mkblock(0, 2), 0));
ASSERT_FALSE(hf.add(mkblock(2, 2), 0));
ASSERT_TRUE(hf.add(mkblock(1, 2), 0));
- db.add_block(mkblock(1, 1), 0, 0, 0, 0, crypto::hash());
+ db.add_block(mkblock(1, 1), 0, 0, 0, 0, 0, crypto::hash());
// block height 1, only version 1 is accepted
ASSERT_FALSE(hf.add(mkblock(0, 2), 1));
ASSERT_FALSE(hf.add(mkblock(2, 2), 1));
ASSERT_TRUE(hf.add(mkblock(1, 2), 1));
- db.add_block(mkblock(1, 1), 0, 0, 0, 0, crypto::hash());
+ db.add_block(mkblock(1, 1), 0, 0, 0, 0, 0, crypto::hash());
// block height 2, only version 2 is accepted
ASSERT_FALSE(hf.add(mkblock(0, 2), 2));
ASSERT_FALSE(hf.add(mkblock(1, 2), 2));
ASSERT_FALSE(hf.add(mkblock(3, 2), 2));
ASSERT_TRUE(hf.add(mkblock(2, 2), 2));
- db.add_block(mkblock(2, 1), 0, 0, 0, 0, crypto::hash());
+ db.add_block(mkblock(2, 1), 0, 0, 0, 0, 0, crypto::hash());
}
TEST(empty_hardforks, Success)
@@ -133,7 +134,7 @@ TEST(empty_hardforks, Success)
ASSERT_TRUE(hf.get_state(time(NULL) + 3600*24*400) == HardFork::Ready);
for (uint64_t h = 0; h <= 10; ++h) {
- db.add_block(mkblock(hf, h, 1), 0, 0, 0, 0, crypto::hash());
+ db.add_block(mkblock(hf, h, 1), 0, 0, 0, 0, 0, crypto::hash());
ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
}
ASSERT_EQ(hf.get(0), 1);
@@ -167,14 +168,14 @@ TEST(check_for_height, Success)
for (uint64_t h = 0; h <= 4; ++h) {
ASSERT_TRUE(hf.check_for_height(mkblock(1, 1), h));
ASSERT_FALSE(hf.check_for_height(mkblock(2, 2), h)); // block version is too high
- db.add_block(mkblock(hf, h, 1), 0, 0, 0, 0, crypto::hash());
+ db.add_block(mkblock(hf, h, 1), 0, 0, 0, 0, 0, crypto::hash());
ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
}
for (uint64_t h = 5; h <= 10; ++h) {
ASSERT_FALSE(hf.check_for_height(mkblock(1, 1), h)); // block version is too low
ASSERT_TRUE(hf.check_for_height(mkblock(2, 2), h));
- db.add_block(mkblock(hf, h, 2), 0, 0, 0, 0, crypto::hash());
+ db.add_block(mkblock(hf, h, 2), 0, 0, 0, 0, 0, crypto::hash());
ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
}
}
@@ -191,19 +192,19 @@ TEST(get, next_version)
for (uint64_t h = 0; h <= 4; ++h) {
ASSERT_EQ(2, hf.get_next_version());
- db.add_block(mkblock(hf, h, 1), 0, 0, 0, 0, crypto::hash());
+ db.add_block(mkblock(hf, h, 1), 0, 0, 0, 0, 0, crypto::hash());
ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
}
for (uint64_t h = 5; h <= 9; ++h) {
ASSERT_EQ(4, hf.get_next_version());
- db.add_block(mkblock(hf, h, 2), 0, 0, 0, 0, crypto::hash());
+ db.add_block(mkblock(hf, h, 2), 0, 0, 0, 0, 0, crypto::hash());
ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
}
for (uint64_t h = 10; h <= 15; ++h) {
ASSERT_EQ(4, hf.get_next_version());
- db.add_block(mkblock(hf, h, 4), 0, 0, 0, 0, crypto::hash());
+ db.add_block(mkblock(hf, h, 4), 0, 0, 0, 0, 0, crypto::hash());
ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
}
}
@@ -244,7 +245,7 @@ TEST(steps_asap, Success)
hf.init();
for (uint64_t h = 0; h < 10; ++h) {
- db.add_block(mkblock(hf, h, 9), 0, 0, 0, 0, crypto::hash());
+ db.add_block(mkblock(hf, h, 9), 0, 0, 0, 0, 0, crypto::hash());
ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
}
@@ -271,7 +272,7 @@ TEST(steps_1, Success)
hf.init();
for (uint64_t h = 0 ; h < 10; ++h) {
- db.add_block(mkblock(hf, h, h+1), 0, 0, 0, 0, crypto::hash());
+ db.add_block(mkblock(hf, h, h+1), 0, 0, 0, 0, 0, crypto::hash());
ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
}
@@ -296,7 +297,7 @@ TEST(reorganize, Same)
// index 0 1 2 3 4 5 6 7 8 9
static const uint8_t block_versions[] = { 1, 1, 4, 4, 7, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
for (uint64_t h = 0; h < 20; ++h) {
- db.add_block(mkblock(hf, h, block_versions[h]), 0, 0, 0, 0, crypto::hash());
+ db.add_block(mkblock(hf, h, block_versions[h]), 0, 0, 0, 0, 0, crypto::hash());
ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
}
@@ -327,7 +328,7 @@ TEST(reorganize, Changed)
static const uint8_t block_versions[] = { 1, 1, 4, 4, 7, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
static const uint8_t expected_versions[] = { 1, 1, 1, 1, 1, 1, 4, 4, 7, 7, 9, 9, 9, 9, 9, 9 };
for (uint64_t h = 0; h < 16; ++h) {
- db.add_block(mkblock(hf, h, block_versions[h]), 0, 0, 0, 0, crypto::hash());
+ db.add_block(mkblock(hf, h, block_versions[h]), 0, 0, 0, 0, 0, crypto::hash());
ASSERT_TRUE (hf.add(db.get_block_from_height(h), h));
}
@@ -347,7 +348,7 @@ TEST(reorganize, Changed)
ASSERT_EQ(db.height(), 3);
hf.reorganize_from_block_height(2);
for (uint64_t h = 3; h < 16; ++h) {
- db.add_block(mkblock(hf, h, block_versions_new[h]), 0, 0, 0, 0, crypto::hash());
+ db.add_block(mkblock(hf, h, block_versions_new[h]), 0, 0, 0, 0, 0, crypto::hash());
bool ret = hf.add(db.get_block_from_height(h), h);
ASSERT_EQ (ret, h < 15);
}
@@ -371,7 +372,7 @@ TEST(voting, threshold)
for (uint64_t h = 0; h <= 8; ++h) {
uint8_t v = 1 + !!(h % 8);
- db.add_block(mkblock(hf, h, v), 0, 0, 0, 0, crypto::hash());
+ db.add_block(mkblock(hf, h, v), 0, 0, 0, 0, 0, crypto::hash());
bool ret = hf.add(db.get_block_from_height(h), h);
if (h >= 8 && threshold == 87) {
// for threshold 87, we reach the treshold at height 7, so from height 8, hard fork to version 2, but 8 tries to add 1
@@ -405,7 +406,7 @@ TEST(voting, different_thresholds)
static const uint8_t expected_versions[] = { 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4 };
for (uint64_t h = 0; h < sizeof(block_versions) / sizeof(block_versions[0]); ++h) {
- db.add_block(mkblock(hf, h, block_versions[h]), 0, 0, 0, 0, crypto::hash());
+ db.add_block(mkblock(hf, h, block_versions[h]), 0, 0, 0, 0, 0, crypto::hash());
bool ret = hf.add(db.get_block_from_height(h), h);
ASSERT_EQ(ret, true);
}
@@ -459,7 +460,7 @@ TEST(voting, info)
ASSERT_EQ(expected_thresholds[h], threshold);
ASSERT_EQ(4, voting);
- db.add_block(mkblock(hf, h, block_versions[h]), 0, 0, 0, 0, crypto::hash());
+ db.add_block(mkblock(hf, h, block_versions[h]), 0, 0, 0, 0, 0, crypto::hash());
ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
}
}
@@ -522,7 +523,7 @@ TEST(reorganize, changed)
#define ADD(v, h, a) \
do { \
cryptonote::block b = mkblock(hf, h, v); \
- db.add_block(b, 0, 0, 0, 0, crypto::hash()); \
+ db.add_block(b, 0, 0, 0, 0, 0, crypto::hash()); \
ASSERT_##a(hf.add(b, h)); \
} while(0)
#define ADD_TRUE(v, h) ADD(v, h, TRUE)
diff --git a/tests/unit_tests/json_serialization.cpp b/tests/unit_tests/json_serialization.cpp
index 234cb2c33..53d9f84c7 100644
--- a/tests/unit_tests/json_serialization.cpp
+++ b/tests/unit_tests/json_serialization.cpp
@@ -75,7 +75,7 @@ namespace
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
subaddresses[from.m_account_address.m_spend_public_key] = {0,0};
- if (!cryptonote::construct_tx_and_get_tx_key(from, subaddresses, actual_sources, to, boost::none, {}, tx, 0, tx_key, extra_keys, rct, bulletproof ? rct::RangeProofBulletproof : rct::RangeProofBorromean))
+ if (!cryptonote::construct_tx_and_get_tx_key(from, subaddresses, actual_sources, to, boost::none, {}, tx, 0, tx_key, extra_keys, rct, { bulletproof ? rct::RangeProofBulletproof : rct::RangeProofBorromean, bulletproof ? 2 : 0 }))
throw std::runtime_error{"transaction construction error"};
return tx;
diff --git a/tests/unit_tests/long_term_block_weight.cpp b/tests/unit_tests/long_term_block_weight.cpp
new file mode 100644
index 000000000..0ee6c5c2b
--- /dev/null
+++ b/tests/unit_tests/long_term_block_weight.cpp
@@ -0,0 +1,384 @@
+// Copyright (c) 2019, 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.
+
+#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"
+
+#define TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW 5000
+
+namespace
+{
+
+class TestDB: public cryptonote::BaseTestDB
+{
+private:
+ struct block_t
+ {
+ size_t weight;
+ uint64_t long_term_weight;
+ };
+
+public:
+ TestDB() { m_open = true; }
+
+ virtual void add_block( const cryptonote::block& blk
+ , size_t block_weight
+ , uint64_t long_term_block_weight
+ , const cryptonote::difficulty_type& cumulative_difficulty
+ , const uint64_t& coins_generated
+ , uint64_t num_rct_outs
+ , const crypto::hash& blk_hash
+ ) override {
+ blocks.push_back({block_weight, long_term_block_weight});
+ }
+ virtual uint64_t height() const override { return blocks.size(); }
+ virtual size_t get_block_weight(const uint64_t &h) const override { return blocks[h].weight; }
+ virtual uint64_t get_block_long_term_weight(const uint64_t &h) const override { return blocks[h].long_term_weight; }
+ virtual crypto::hash top_block_hash() const override {
+ uint64_t h = height();
+ crypto::hash top = crypto::null_hash;
+ if (h)
+ *(uint64_t*)&top = h - 1;
+ return top;
+ }
+ virtual void pop_block(cryptonote::block &blk, std::vector<cryptonote::transaction> &txs) override { blocks.pop_back(); }
+
+private:
+ std::vector<block_t> blocks;
+};
+
+static uint32_t lcg_seed = 0;
+
+static uint32_t lcg()
+{
+ lcg_seed = (lcg_seed * 0x100000001b3 + 0xcbf29ce484222325) & 0xffffffff;
+ return lcg_seed;
+}
+
+}
+
+#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(long_term_block_weight, empty_short)
+{
+ PREFIX(9);
+
+ ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
+
+ ASSERT_EQ(bc->get_current_cumulative_block_weight_median(), CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5);
+ ASSERT_EQ(bc->get_current_cumulative_block_weight_limit(), CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 * 2);
+}
+
+TEST(long_term_block_weight, identical_before_fork)
+{
+ PREFIX(9);
+
+ for (uint64_t h = 1; h < 10 * TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW; ++h)
+ {
+ size_t w = h < CRYPTONOTE_REWARD_BLOCKS_WINDOW ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : bc->get_current_cumulative_block_weight_limit();
+ uint64_t ltw = bc->get_next_long_term_block_weight(w);
+ bc->get_db().add_block(cryptonote::block(), w, ltw, h, h, {});
+ ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
+ }
+ for (uint64_t h = 0; h < 10 * TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW; ++h)
+ {
+ ASSERT_EQ(bc->get_db().get_block_long_term_weight(h), bc->get_db().get_block_weight(h));
+ }
+}
+
+TEST(long_term_block_weight, identical_after_fork_before_long_term_window)
+{
+ PREFIX(10);
+
+ for (uint64_t h = 1; h <= TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW; ++h)
+ {
+ size_t w = h < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : bc->get_current_cumulative_block_weight_limit();
+ uint64_t ltw = bc->get_next_long_term_block_weight(w);
+ bc->get_db().add_block(cryptonote::block(), w, ltw, h, h, {});
+ ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
+ }
+ for (uint64_t h = 0; h < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW; ++h)
+ {
+ ASSERT_EQ(bc->get_db().get_block_long_term_weight(h), bc->get_db().get_block_weight(h));
+ }
+}
+
+TEST(long_term_block_weight, ceiling_at_30000000)
+{
+ PREFIX(10);
+
+ for (uint64_t h = 0; h < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW + TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW / 2 - 1; ++h)
+ {
+ size_t w = h < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : bc->get_current_cumulative_block_weight_limit();
+ uint64_t ltw = bc->get_next_long_term_block_weight(w);
+ bc->get_db().add_block(cryptonote::block(), w, ltw, h, h, {});
+ ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
+ }
+ ASSERT_EQ(bc->get_current_cumulative_block_weight_median(), 15000000);
+ ASSERT_EQ(bc->get_current_cumulative_block_weight_limit(), 30000000);
+}
+
+TEST(long_term_block_weight, multi_pop)
+{
+ PREFIX(10);
+
+ for (uint64_t h = 1; h <= TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW + 20; ++h)
+ {
+ size_t w = h < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : bc->get_current_cumulative_block_weight_limit();
+ uint64_t ltw = bc->get_next_long_term_block_weight(w);
+ bc->get_db().add_block(cryptonote::block(), w, ltw, h, h, {});
+ ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
+ }
+
+ const uint64_t effective_median = bc->get_current_cumulative_block_weight_median();
+ const uint64_t effective_limit = bc->get_current_cumulative_block_weight_limit();
+
+ for (uint64_t h = 0; h < 4; ++h)
+ {
+ size_t w = h < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : bc->get_current_cumulative_block_weight_limit();
+ uint64_t ltw = bc->get_next_long_term_block_weight(w);
+ bc->get_db().add_block(cryptonote::block(), w, ltw, h, h, {});
+ ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
+ }
+
+ cryptonote::block b;
+ std::vector<cryptonote::transaction> txs;
+ bc->get_db().pop_block(b, txs);
+ bc->get_db().pop_block(b, txs);
+ bc->get_db().pop_block(b, txs);
+ bc->get_db().pop_block(b, txs);
+ ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
+
+ ASSERT_EQ(effective_median, bc->get_current_cumulative_block_weight_median());
+ ASSERT_EQ(effective_limit, bc->get_current_cumulative_block_weight_limit());
+}
+
+TEST(long_term_block_weight, multiple_updates)
+{
+ PREFIX(10);
+
+ for (uint64_t h = 1; h <= 3 * TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW; ++h)
+ {
+ size_t w = h < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : bc->get_current_cumulative_block_weight_limit();
+ uint64_t ltw = bc->get_next_long_term_block_weight(w);
+ bc->get_db().add_block(cryptonote::block(), w, ltw, h, h, {});
+ ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
+ const uint64_t effective_median = bc->get_current_cumulative_block_weight_median();
+ const uint64_t effective_limit = bc->get_current_cumulative_block_weight_limit();
+ ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
+ ASSERT_EQ(effective_median, bc->get_current_cumulative_block_weight_median());
+ ASSERT_EQ(effective_limit, bc->get_current_cumulative_block_weight_limit());
+ ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
+ ASSERT_EQ(effective_median, bc->get_current_cumulative_block_weight_median());
+ ASSERT_EQ(effective_limit, bc->get_current_cumulative_block_weight_limit());
+ ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
+ ASSERT_EQ(effective_median, bc->get_current_cumulative_block_weight_median());
+ ASSERT_EQ(effective_limit, bc->get_current_cumulative_block_weight_limit());
+ }
+}
+
+TEST(long_term_block_weight, pop_invariant_max)
+{
+ PREFIX(10);
+
+ for (uint64_t h = 1; h < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW - 10; ++h)
+ {
+ size_t w = bc->get_db().height() < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : bc->get_current_cumulative_block_weight_limit();
+ uint64_t ltw = bc->get_next_long_term_block_weight(w);
+ bc->get_db().add_block(cryptonote::block(), w, ltw, h, h, {});
+ ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
+ }
+
+ for (int n = 0; n < 1000; ++n)
+ {
+ // pop some blocks, then add some more
+ int remove = 1 + (n * 17) % 8;
+ int add = (n * 23) % 12;
+
+ // save long term block weights we're about to remove
+ uint64_t old_ltbw[16], h0 = bc->get_db().height() - remove - 1;
+ for (int i = -2; i < remove; ++i)
+ {
+ old_ltbw[i + 2] = bc->get_db().get_block_long_term_weight(h0 + i);
+ }
+
+ for (int i = 0; i < remove; ++i)
+ {
+ cryptonote::block b;
+ std::vector<cryptonote::transaction> txs;
+ bc->get_db().pop_block(b, txs);
+ ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
+ }
+ for (int i = 0; i < add; ++i)
+ {
+ size_t w = bc->get_db().height() < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : bc->get_current_cumulative_block_weight_limit();
+ uint64_t ltw = bc->get_next_long_term_block_weight(w);
+ bc->get_db().add_block(cryptonote::block(), w, ltw, bc->get_db().height(), bc->get_db().height(), {});
+ ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
+ }
+
+ // check the new values are the same as the old ones
+ for (int i = -2; i < std::min(add, remove); ++i)
+ {
+ ASSERT_EQ(bc->get_db().get_block_long_term_weight(h0 + i), old_ltbw[i + 2]);
+ }
+ }
+}
+
+TEST(long_term_block_weight, pop_invariant_random)
+{
+ PREFIX(10);
+
+ for (uint64_t h = 1; h < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW - 10; ++h)
+ {
+ size_t w = bc->get_db().height() < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : bc->get_current_cumulative_block_weight_limit();
+ uint64_t ltw = bc->get_next_long_term_block_weight(w);
+ bc->get_db().add_block(cryptonote::block(), w, ltw, h, h, {});
+ ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
+ }
+
+ for (int n = 0; n < 1000; ++n)
+ {
+ // pop some blocks, then add some more
+ int remove = 1 + (n * 17) % 8;
+ int add = (n * 23) % 123;
+
+ // save long term block weights we're about to remove
+ uint64_t old_ltbw[16], h0 = bc->get_db().height() - remove - 1;
+ for (int i = -2; i < remove; ++i)
+ {
+ old_ltbw[i + 2] = bc->get_db().get_block_long_term_weight(h0 + i);
+ }
+
+ for (int i = 0; i < remove; ++i)
+ {
+ cryptonote::block b;
+ std::vector<cryptonote::transaction> txs;
+ bc->get_db().pop_block(b, txs);
+ ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
+ const uint64_t effective_median = bc->get_current_cumulative_block_weight_median();
+ const uint64_t effective_limit = bc->get_current_cumulative_block_weight_limit();
+ ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
+ ASSERT_EQ(effective_median, bc->get_current_cumulative_block_weight_median());
+ ASSERT_EQ(effective_limit, bc->get_current_cumulative_block_weight_limit());
+ }
+ for (int i = 0; i < add; ++i)
+ {
+ lcg_seed = bc->get_db().height();
+ uint32_t r = lcg();
+ size_t w = bc->get_db().height() < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : (r % bc->get_current_cumulative_block_weight_limit());
+ uint64_t ltw = bc->get_next_long_term_block_weight(w);
+ bc->get_db().add_block(cryptonote::block(), w, ltw, bc->get_db().height(), bc->get_db().height(), {});
+ ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
+ const uint64_t effective_median = bc->get_current_cumulative_block_weight_median();
+ const uint64_t effective_limit = bc->get_current_cumulative_block_weight_limit();
+ ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
+ ASSERT_EQ(effective_median, bc->get_current_cumulative_block_weight_median());
+ ASSERT_EQ(effective_limit, bc->get_current_cumulative_block_weight_limit());
+ }
+
+ // check the new values are the same as the old ones
+ for (int i = -2; i < std::min(add, remove); ++i)
+ {
+ ASSERT_EQ(bc->get_db().get_block_long_term_weight(h0 + i), old_ltbw[i + 2]);
+ }
+ }
+}
+
+TEST(long_term_block_weight, long_growth_spike_and_drop)
+{
+ PREFIX(10);
+
+ uint64_t long_term_effective_median_block_weight;
+
+ // constant init
+ for (uint64_t h = 0; h < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW; ++h)
+ {
+ size_t w = CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5;
+ uint64_t ltw = bc->get_next_long_term_block_weight(w);
+ bc->get_db().add_block(cryptonote::block(), w, ltw, h, h, {});
+ ASSERT_TRUE(bc->update_next_cumulative_weight_limit(&long_term_effective_median_block_weight));
+ }
+ ASSERT_EQ(long_term_effective_median_block_weight, 300000);
+
+ // slow 10% yearly for a year (scaled down by 100000 / TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW) -> 8% change
+ for (uint64_t h = 0; h < 365 * 720 * TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW / 100000; ++h)
+ {
+ //size_t w = bc->get_current_cumulative_block_weight_median() * rate;
+ float t = h / float(365 * 720 * TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW / 100000);
+ size_t w = 300000 + t * 30000;
+ uint64_t ltw = bc->get_next_long_term_block_weight(w);
+ bc->get_db().add_block(cryptonote::block(), w, ltw, h, h, {});
+ ASSERT_TRUE(bc->update_next_cumulative_weight_limit(&long_term_effective_median_block_weight));
+ }
+ ASSERT_GT(long_term_effective_median_block_weight, 300000 * 1.07);
+ ASSERT_LT(long_term_effective_median_block_weight, 300000 * 1.09);
+
+ // spike over three weeks - does not move much
+ for (uint64_t h = 0; h < 21 * 720 * TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW / 100000; ++h)
+ {
+ size_t w = bc->get_current_cumulative_block_weight_limit();
+ uint64_t ltw = bc->get_next_long_term_block_weight(w);
+ bc->get_db().add_block(cryptonote::block(), w, ltw, h, h, {});
+ ASSERT_TRUE(bc->update_next_cumulative_weight_limit(&long_term_effective_median_block_weight));
+ }
+ ASSERT_GT(long_term_effective_median_block_weight, 300000 * 1.07);
+ ASSERT_LT(long_term_effective_median_block_weight, 300000 * 1.09);
+
+ // drop - does not move much
+ for (uint64_t h = 0; h < 21 * 720 * TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW / 100000; ++h)
+ {
+ size_t w = bc->get_current_cumulative_block_weight_median() * .25;
+ uint64_t ltw = bc->get_next_long_term_block_weight(w);
+ bc->get_db().add_block(cryptonote::block(), w, ltw, h, h, {});
+ ASSERT_TRUE(bc->update_next_cumulative_weight_limit(&long_term_effective_median_block_weight));
+ }
+ ASSERT_GT(long_term_effective_median_block_weight, 300000 * 1.07);
+ ASSERT_LT(long_term_effective_median_block_weight, 300000 * 1.09);
+}
diff --git a/tests/unit_tests/mnemonics.cpp b/tests/unit_tests/mnemonics.cpp
index 4dc2d931e..59642828d 100644
--- a/tests/unit_tests/mnemonics.cpp
+++ b/tests/unit_tests/mnemonics.cpp
@@ -51,6 +51,7 @@
#include "mnemonics/english_old.h"
#include "mnemonics/language_base.h"
#include "mnemonics/singleton.h"
+#include <boost/algorithm/string.hpp>
namespace
{
@@ -221,3 +222,38 @@ TEST(mnemonics, utf8prefix)
ASSERT_TRUE(Language::utf8prefix(epee::wipeable_string("æon"), 3) == "æon");
ASSERT_TRUE(Language::utf8prefix(epee::wipeable_string("æon"), 4) == "æon");
}
+
+TEST(mnemonics, case_tolerance)
+{
+ bool res;
+ //
+ crypto::secret_key key_1;
+ std::string language_name_1;
+ const std::string seed_1 = "Neubau umarmen Abart umarmen Turban feilen Brett Bargeld Episode Milchkuh Substanz Jahr Armband Maibaum Tand Grünalge Tabak erziehen Federboa Lobrede Tenor Leuchter Curry Diskurs Tenor";
+ res = crypto::ElectrumWords::words_to_bytes(seed_1, key_1, language_name_1);
+ ASSERT_EQ(true, res);
+ ASSERT_STREQ(language_name_1.c_str(), "Deutsch");
+ //
+ crypto::secret_key key_2;
+ std::string language_name_2;
+ // neubau is capitalized in the word list, but the language detection code should be able to detect it as Deutsch
+ std::string seed_2 = "neubau umarmen Abart umarmen Turban feilen Brett Bargeld Episode Milchkuh Substanz Jahr Armband Maibaum Tand Grünalge Tabak erziehen Federboa Lobrede Tenor Leuchter Curry Diskurs tenor";
+ boost::algorithm::to_lower(seed_2);
+ res = crypto::ElectrumWords::words_to_bytes(seed_2, key_2, language_name_2);
+ ASSERT_EQ(true, res);
+ ASSERT_STREQ(language_name_2.c_str(), "Deutsch");
+ //
+ ASSERT_TRUE(key_1 == key_2);
+}
+
+TEST(mnemonics, partial_word_tolerance)
+{
+ bool res;
+ //
+ crypto::secret_key key_1;
+ std::string language_name_1;
+ const std::string seed_1 = "crim bam scamp gna limi woma wron tuit birth mundane donuts square cohesive dolphin titans narrate fue saved wrap aloof magic mirr toget upda wra";
+ res = crypto::ElectrumWords::words_to_bytes(seed_1, key_1, language_name_1);
+ ASSERT_EQ(true, res);
+ ASSERT_STREQ(language_name_1.c_str(), "English");
+} \ No newline at end of file
diff --git a/tests/unit_tests/net.cpp b/tests/unit_tests/net.cpp
new file mode 100644
index 000000000..a38ecfe81
--- /dev/null
+++ b/tests/unit_tests/net.cpp
@@ -0,0 +1,745 @@
+// Copyright (c) 2018, 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.
+
+#include <atomic>
+#include <boost/archive/portable_binary_oarchive.hpp>
+#include <boost/archive/portable_binary_iarchive.hpp>
+#include <boost/asio/buffer.hpp>
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/ip/tcp.hpp>
+#include <boost/asio/read.hpp>
+#include <boost/asio/write.hpp>
+#include <boost/endian/conversion.hpp>
+#include <boost/system/error_code.hpp>
+#include <boost/thread/thread.hpp>
+#include <cstring>
+#include <functional>
+#include <gtest/gtest.h>
+#include <memory>
+
+#include "net/error.h"
+#include "net/net_utils_base.h"
+#include "net/socks.h"
+#include "net/parse.h"
+#include "net/tor_address.h"
+#include "p2p/net_peerlist_boost_serialization.h"
+#include "serialization/keyvalue_serialization.h"
+#include "storages/portable_storage.h"
+
+namespace
+{
+ static constexpr const char v2_onion[] =
+ "xmrto2bturnore26.onion";
+ static constexpr const char v3_onion[] =
+ "vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd.onion";
+}
+
+TEST(tor_address, constants)
+{
+ static_assert(!net::tor_address::is_local(), "bad is_local() response");
+ static_assert(!net::tor_address::is_loopback(), "bad is_loopback() response");
+ static_assert(net::tor_address::get_type_id() == epee::net_utils::address_type::tor, "bad get_type_id() response");
+
+ EXPECT_FALSE(net::tor_address::is_local());
+ EXPECT_FALSE(net::tor_address::is_loopback());
+ EXPECT_EQ(epee::net_utils::address_type::tor, net::tor_address::get_type_id());
+ EXPECT_EQ(epee::net_utils::address_type::tor, net::tor_address::get_type_id());
+}
+
+TEST(tor_address, invalid)
+{
+ EXPECT_TRUE(net::tor_address::make("").has_error());
+ EXPECT_TRUE(net::tor_address::make(":").has_error());
+ EXPECT_TRUE(net::tor_address::make(".onion").has_error());
+ EXPECT_TRUE(net::tor_address::make(".onion:").has_error());
+ EXPECT_TRUE(net::tor_address::make(v2_onion + 1).has_error());
+ EXPECT_TRUE(net::tor_address::make(v3_onion + 1).has_error());
+ EXPECT_TRUE(net::tor_address::make(boost::string_ref{v2_onion, sizeof(v2_onion) - 2}).has_error());
+ EXPECT_TRUE(net::tor_address::make(boost::string_ref{v3_onion, sizeof(v3_onion) - 2}).has_error());
+ EXPECT_TRUE(net::tor_address::make(std::string{v2_onion} + ":-").has_error());
+ EXPECT_TRUE(net::tor_address::make(std::string{v2_onion} + ":900a").has_error());
+ EXPECT_TRUE(net::tor_address::make(std::string{v3_onion} + ":65536").has_error());
+ EXPECT_TRUE(net::tor_address::make(std::string{v3_onion} + ":-1").has_error());
+
+ std::string onion{v3_onion};
+ onion.at(10) = 1;
+ EXPECT_TRUE(net::tor_address::make(onion).has_error());
+}
+
+TEST(tor_address, unblockable_types)
+{
+ net::tor_address tor{};
+
+ ASSERT_NE(nullptr, tor.host_str());
+ EXPECT_STREQ("<unknown tor host>", tor.host_str());
+ EXPECT_STREQ("<unknown tor host>", tor.str().c_str());
+ EXPECT_EQ(0u, tor.port());
+ EXPECT_TRUE(tor.is_unknown());
+ EXPECT_FALSE(tor.is_local());
+ EXPECT_FALSE(tor.is_loopback());
+ EXPECT_EQ(epee::net_utils::address_type::tor, tor.get_type_id());
+ EXPECT_EQ(epee::net_utils::zone::tor, tor.get_zone());
+
+ tor = net::tor_address::unknown();
+ ASSERT_NE(nullptr, tor.host_str());
+ EXPECT_STREQ("<unknown tor host>", tor.host_str());
+ EXPECT_STREQ("<unknown tor host>", tor.str().c_str());
+ EXPECT_EQ(0u, tor.port());
+ EXPECT_TRUE(tor.is_unknown());
+ EXPECT_FALSE(tor.is_local());
+ EXPECT_FALSE(tor.is_loopback());
+ EXPECT_EQ(epee::net_utils::address_type::tor, tor.get_type_id());
+ EXPECT_EQ(epee::net_utils::zone::tor, tor.get_zone());
+
+ EXPECT_EQ(net::tor_address{}, net::tor_address::unknown());
+}
+
+TEST(tor_address, valid)
+{
+ const auto address1 = net::tor_address::make(v3_onion);
+
+ ASSERT_TRUE(address1.has_value());
+ EXPECT_EQ(0u, address1->port());
+ EXPECT_STREQ(v3_onion, address1->host_str());
+ EXPECT_STREQ(v3_onion, address1->str().c_str());
+ EXPECT_TRUE(address1->is_blockable());
+
+ net::tor_address address2{*address1};
+
+ EXPECT_EQ(0u, address2.port());
+ EXPECT_STREQ(v3_onion, address2.host_str());
+ EXPECT_STREQ(v3_onion, address2.str().c_str());
+ EXPECT_TRUE(address2.is_blockable());
+ EXPECT_TRUE(address2.equal(*address1));
+ EXPECT_TRUE(address1->equal(address2));
+ EXPECT_TRUE(address2 == *address1);
+ EXPECT_TRUE(*address1 == address2);
+ EXPECT_FALSE(address2 != *address1);
+ EXPECT_FALSE(*address1 != address2);
+ EXPECT_TRUE(address2.is_same_host(*address1));
+ EXPECT_TRUE(address1->is_same_host(address2));
+ EXPECT_FALSE(address2.less(*address1));
+ EXPECT_FALSE(address1->less(address2));
+
+ address2 = MONERO_UNWRAP(net::tor_address::make(std::string{v2_onion} + ":6545"));
+
+ EXPECT_EQ(6545, address2.port());
+ EXPECT_STREQ(v2_onion, address2.host_str());
+ EXPECT_EQ(std::string{v2_onion} + ":6545", address2.str().c_str());
+ EXPECT_TRUE(address2.is_blockable());
+ EXPECT_FALSE(address2.equal(*address1));
+ EXPECT_FALSE(address1->equal(address2));
+ EXPECT_FALSE(address2 == *address1);
+ EXPECT_FALSE(*address1 == address2);
+ EXPECT_TRUE(address2 != *address1);
+ EXPECT_TRUE(*address1 != address2);
+ EXPECT_FALSE(address2.is_same_host(*address1));
+ EXPECT_FALSE(address1->is_same_host(address2));
+ EXPECT_FALSE(address2.less(*address1));
+ EXPECT_TRUE(address1->less(address2));
+
+ address2 = MONERO_UNWRAP(net::tor_address::make(std::string{v3_onion} + ":", 65535));
+
+ EXPECT_EQ(65535, address2.port());
+ EXPECT_STREQ(v3_onion, address2.host_str());
+ EXPECT_EQ(std::string{v3_onion} + ":65535", address2.str().c_str());
+ EXPECT_TRUE(address2.is_blockable());
+ EXPECT_FALSE(address2.equal(*address1));
+ EXPECT_FALSE(address1->equal(address2));
+ EXPECT_FALSE(address2 == *address1);
+ EXPECT_FALSE(*address1 == address2);
+ EXPECT_TRUE(address2 != *address1);
+ EXPECT_TRUE(*address1 != address2);
+ EXPECT_TRUE(address2.is_same_host(*address1));
+ EXPECT_TRUE(address1->is_same_host(address2));
+ EXPECT_FALSE(address2.less(*address1));
+ EXPECT_TRUE(address1->less(address2));
+}
+
+TEST(tor_address, generic_network_address)
+{
+ const epee::net_utils::network_address tor1{MONERO_UNWRAP(net::tor_address::make(v3_onion, 8080))};
+ const epee::net_utils::network_address tor2{MONERO_UNWRAP(net::tor_address::make(v3_onion, 8080))};
+ const epee::net_utils::network_address ip{epee::net_utils::ipv4_network_address{100, 200}};
+
+ EXPECT_EQ(tor1, tor2);
+ EXPECT_NE(ip, tor1);
+ EXPECT_LT(ip, tor1);
+
+ EXPECT_STREQ(v3_onion, tor1.host_str().c_str());
+ EXPECT_EQ(std::string{v3_onion} + ":8080", tor1.str());
+ EXPECT_EQ(epee::net_utils::address_type::tor, tor1.get_type_id());
+ EXPECT_EQ(epee::net_utils::address_type::tor, tor2.get_type_id());
+ EXPECT_EQ(epee::net_utils::address_type::ipv4, ip.get_type_id());
+ EXPECT_EQ(epee::net_utils::zone::tor, tor1.get_zone());
+ EXPECT_EQ(epee::net_utils::zone::tor, tor2.get_zone());
+ EXPECT_EQ(epee::net_utils::zone::public_, ip.get_zone());
+ EXPECT_TRUE(tor1.is_blockable());
+ EXPECT_TRUE(tor2.is_blockable());
+ EXPECT_TRUE(ip.is_blockable());
+}
+
+namespace
+{
+ struct test_command
+ {
+ net::tor_address tor;
+
+ BEGIN_KV_SERIALIZE_MAP()
+ KV_SERIALIZE(tor);
+ END_KV_SERIALIZE_MAP()
+ };
+}
+
+TEST(tor_address, epee_serializev_v2)
+{
+ std::string buffer{};
+ {
+ test_command command{MONERO_UNWRAP(net::tor_address::make(v2_onion, 10))};
+ EXPECT_FALSE(command.tor.is_unknown());
+ EXPECT_NE(net::tor_address{}, command.tor);
+ EXPECT_STREQ(v2_onion, command.tor.host_str());
+ EXPECT_EQ(10u, command.tor.port());
+
+ epee::serialization::portable_storage stg{};
+ EXPECT_TRUE(command.store(stg));
+ EXPECT_TRUE(stg.store_to_binary(buffer));
+ }
+
+ test_command command{};
+ {
+ EXPECT_TRUE(command.tor.is_unknown());
+ EXPECT_EQ(net::tor_address{}, command.tor);
+ EXPECT_STREQ(net::tor_address::unknown_str(), command.tor.host_str());
+ EXPECT_EQ(0u, command.tor.port());
+
+ epee::serialization::portable_storage stg{};
+ EXPECT_TRUE(stg.load_from_binary(buffer));
+ EXPECT_TRUE(command.load(stg));
+ }
+ EXPECT_FALSE(command.tor.is_unknown());
+ EXPECT_NE(net::tor_address{}, command.tor);
+ EXPECT_STREQ(v2_onion, command.tor.host_str());
+ EXPECT_EQ(10u, command.tor.port());
+
+ // make sure that exceeding max buffer doesn't destroy tor_address::_load
+ {
+ epee::serialization::portable_storage stg{};
+ stg.load_from_binary(buffer);
+
+ std::string host{};
+ ASSERT_TRUE(stg.get_value("host", host, stg.open_section("tor", nullptr, false)));
+ EXPECT_EQ(std::strlen(v2_onion), host.size());
+
+ host.push_back('k');
+ EXPECT_TRUE(stg.set_value("host", host, stg.open_section("tor", nullptr, false)));
+ EXPECT_TRUE(command.load(stg)); // poor error reporting from `KV_SERIALIZE`
+ }
+
+ EXPECT_TRUE(command.tor.is_unknown());
+ EXPECT_EQ(net::tor_address{}, command.tor);
+ EXPECT_STREQ(net::tor_address::unknown_str(), command.tor.host_str());
+ EXPECT_EQ(0u, command.tor.port());
+}
+
+TEST(tor_address, epee_serializev_v3)
+{
+ std::string buffer{};
+ {
+ test_command command{MONERO_UNWRAP(net::tor_address::make(v3_onion, 10))};
+ EXPECT_FALSE(command.tor.is_unknown());
+ EXPECT_NE(net::tor_address{}, command.tor);
+ EXPECT_STREQ(v3_onion, command.tor.host_str());
+ EXPECT_EQ(10u, command.tor.port());
+
+ epee::serialization::portable_storage stg{};
+ EXPECT_TRUE(command.store(stg));
+ EXPECT_TRUE(stg.store_to_binary(buffer));
+ }
+
+ test_command command{};
+ {
+ EXPECT_TRUE(command.tor.is_unknown());
+ EXPECT_EQ(net::tor_address{}, command.tor);
+ EXPECT_STREQ(net::tor_address::unknown_str(), command.tor.host_str());
+ EXPECT_EQ(0u, command.tor.port());
+
+ epee::serialization::portable_storage stg{};
+ EXPECT_TRUE(stg.load_from_binary(buffer));
+ EXPECT_TRUE(command.load(stg));
+ }
+ EXPECT_FALSE(command.tor.is_unknown());
+ EXPECT_NE(net::tor_address{}, command.tor);
+ EXPECT_STREQ(v3_onion, command.tor.host_str());
+ EXPECT_EQ(10u, command.tor.port());
+
+ // make sure that exceeding max buffer doesn't destroy tor_address::_load
+ {
+ epee::serialization::portable_storage stg{};
+ stg.load_from_binary(buffer);
+
+ std::string host{};
+ ASSERT_TRUE(stg.get_value("host", host, stg.open_section("tor", nullptr, false)));
+ EXPECT_EQ(std::strlen(v3_onion), host.size());
+
+ host.push_back('k');
+ EXPECT_TRUE(stg.set_value("host", host, stg.open_section("tor", nullptr, false)));
+ EXPECT_TRUE(command.load(stg)); // poor error reporting from `KV_SERIALIZE`
+ }
+
+ EXPECT_TRUE(command.tor.is_unknown());
+ EXPECT_EQ(net::tor_address{}, command.tor);
+ EXPECT_STRNE(v3_onion, command.tor.host_str());
+ EXPECT_EQ(0u, command.tor.port());
+}
+
+TEST(tor_address, epee_serialize_unknown)
+{
+ std::string buffer{};
+ {
+ test_command command{net::tor_address::unknown()};
+ EXPECT_TRUE(command.tor.is_unknown());
+ EXPECT_EQ(net::tor_address{}, command.tor);
+ EXPECT_STREQ(net::tor_address::unknown_str(), command.tor.host_str());
+ EXPECT_EQ(0u, command.tor.port());
+
+ epee::serialization::portable_storage stg{};
+ EXPECT_TRUE(command.store(stg));
+ EXPECT_TRUE(stg.store_to_binary(buffer));
+ }
+
+ test_command command{};
+ {
+ EXPECT_TRUE(command.tor.is_unknown());
+ EXPECT_EQ(net::tor_address{}, command.tor);
+ EXPECT_STRNE(v3_onion, command.tor.host_str());
+ EXPECT_EQ(0u, command.tor.port());
+
+ epee::serialization::portable_storage stg{};
+ EXPECT_TRUE(stg.load_from_binary(buffer));
+ EXPECT_TRUE(command.load(stg));
+ }
+ EXPECT_TRUE(command.tor.is_unknown());
+ EXPECT_EQ(net::tor_address{}, command.tor);
+ EXPECT_STREQ(net::tor_address::unknown_str(), command.tor.host_str());
+ EXPECT_EQ(0u, command.tor.port());
+
+ // make sure that exceeding max buffer doesn't destroy tor_address::_load
+ {
+ epee::serialization::portable_storage stg{};
+ stg.load_from_binary(buffer);
+
+ std::string host{};
+ ASSERT_TRUE(stg.get_value("host", host, stg.open_section("tor", nullptr, false)));
+ EXPECT_EQ(std::strlen(net::tor_address::unknown_str()), host.size());
+
+ host.push_back('k');
+ EXPECT_TRUE(stg.set_value("host", host, stg.open_section("tor", nullptr, false)));
+ EXPECT_TRUE(command.load(stg)); // poor error reporting from `KV_SERIALIZE`
+ }
+
+ EXPECT_TRUE(command.tor.is_unknown());
+ EXPECT_EQ(net::tor_address{}, command.tor);
+ EXPECT_STRNE(v3_onion, command.tor.host_str());
+ EXPECT_EQ(0u, command.tor.port());
+}
+
+TEST(tor_address, boost_serialize_v2)
+{
+ std::string buffer{};
+ {
+ const net::tor_address tor = MONERO_UNWRAP(net::tor_address::make(v2_onion, 10));
+ EXPECT_FALSE(tor.is_unknown());
+ EXPECT_NE(net::tor_address{}, tor);
+ EXPECT_STREQ(v2_onion, tor.host_str());
+ EXPECT_EQ(10u, tor.port());
+
+ std::ostringstream stream{};
+ {
+ boost::archive::portable_binary_oarchive archive{stream};
+ archive << tor;
+ }
+ buffer = stream.str();
+ }
+
+ net::tor_address tor{};
+ {
+ EXPECT_TRUE(tor.is_unknown());
+ EXPECT_EQ(net::tor_address{}, tor);
+ EXPECT_STREQ(net::tor_address::unknown_str(), tor.host_str());
+ EXPECT_EQ(0u, tor.port());
+
+ std::istringstream stream{buffer};
+ boost::archive::portable_binary_iarchive archive{stream};
+ archive >> tor;
+ }
+ EXPECT_FALSE(tor.is_unknown());
+ EXPECT_NE(net::tor_address{}, tor);
+ EXPECT_STREQ(v2_onion, tor.host_str());
+ EXPECT_EQ(10u, tor.port());
+}
+
+TEST(tor_address, boost_serialize_v3)
+{
+ std::string buffer{};
+ {
+ const net::tor_address tor = MONERO_UNWRAP(net::tor_address::make(v3_onion, 10));
+ EXPECT_FALSE(tor.is_unknown());
+ EXPECT_NE(net::tor_address{}, tor);
+ EXPECT_STREQ(v3_onion, tor.host_str());
+ EXPECT_EQ(10u, tor.port());
+
+ std::ostringstream stream{};
+ {
+ boost::archive::portable_binary_oarchive archive{stream};
+ archive << tor;
+ }
+ buffer = stream.str();
+ }
+
+ net::tor_address tor{};
+ {
+ EXPECT_TRUE(tor.is_unknown());
+ EXPECT_EQ(net::tor_address{}, tor);
+ EXPECT_STREQ(net::tor_address::unknown_str(), tor.host_str());
+ EXPECT_EQ(0u, tor.port());
+
+ std::istringstream stream{buffer};
+ boost::archive::portable_binary_iarchive archive{stream};
+ archive >> tor;
+ }
+ EXPECT_FALSE(tor.is_unknown());
+ EXPECT_NE(net::tor_address{}, tor);
+ EXPECT_STREQ(v3_onion, tor.host_str());
+ EXPECT_EQ(10u, tor.port());
+}
+
+TEST(tor_address, boost_serialize_unknown)
+{
+ std::string buffer{};
+ {
+ const net::tor_address tor{};
+ EXPECT_TRUE(tor.is_unknown());
+ EXPECT_EQ(net::tor_address::unknown(), tor);
+ EXPECT_STREQ(net::tor_address::unknown_str(), tor.host_str());
+ EXPECT_EQ(0u, tor.port());
+
+ std::ostringstream stream{};
+ {
+ boost::archive::portable_binary_oarchive archive{stream};
+ archive << tor;
+ }
+ buffer = stream.str();
+ }
+
+ net::tor_address tor{};
+ {
+ EXPECT_TRUE(tor.is_unknown());
+ EXPECT_EQ(net::tor_address{}, tor);
+ EXPECT_STREQ(net::tor_address::unknown_str(), tor.host_str());
+ EXPECT_EQ(0u, tor.port());
+
+ std::istringstream stream{buffer};
+ boost::archive::portable_binary_iarchive archive{stream};
+ archive >> tor;
+ }
+ EXPECT_TRUE(tor.is_unknown());
+ EXPECT_EQ(net::tor_address::unknown(), tor);
+ EXPECT_STREQ(net::tor_address::unknown_str(), tor.host_str());
+ EXPECT_EQ(0u, tor.port());
+}
+
+TEST(get_network_address, onion)
+{
+ expect<epee::net_utils::network_address> address =
+ net::get_network_address("onion", 0);
+ EXPECT_EQ(net::error::unsupported_address, address);
+
+ address = net::get_network_address(".onion", 0);
+ EXPECT_EQ(net::error::invalid_tor_address, address);
+
+ address = net::get_network_address(v3_onion, 1000);
+ ASSERT_TRUE(bool(address));
+ EXPECT_EQ(epee::net_utils::address_type::tor, address->get_type_id());
+ EXPECT_STREQ(v3_onion, address->host_str().c_str());
+ EXPECT_EQ(std::string{v3_onion} + ":1000", address->str());
+
+ address = net::get_network_address(std::string{v3_onion} + ":2000", 1000);
+ ASSERT_TRUE(bool(address));
+ EXPECT_EQ(epee::net_utils::address_type::tor, address->get_type_id());
+ EXPECT_STREQ(v3_onion, address->host_str().c_str());
+ EXPECT_EQ(std::string{v3_onion} + ":2000", address->str());
+
+ address = net::get_network_address(std::string{v3_onion} + ":65536", 1000);
+ EXPECT_EQ(net::error::invalid_port, address);
+}
+
+
+TEST(get_network_address, ipv4)
+{
+ expect<epee::net_utils::network_address> address =
+ net::get_network_address("0.0.0.", 0);
+ EXPECT_EQ(net::error::unsupported_address, address);
+
+ address = net::get_network_address("0.0.0.257", 0);
+ EXPECT_EQ(net::error::unsupported_address, address);
+
+ address = net::get_network_address("0.0.0.254", 1000);
+ ASSERT_TRUE(bool(address));
+ EXPECT_EQ(epee::net_utils::address_type::ipv4, address->get_type_id());
+ EXPECT_STREQ("0.0.0.254", address->host_str().c_str());
+ EXPECT_STREQ("0.0.0.254:1000", address->str().c_str());
+
+ address = net::get_network_address("23.0.0.254:2000", 1000);
+ ASSERT_TRUE(bool(address));
+ EXPECT_EQ(epee::net_utils::address_type::ipv4, address->get_type_id());
+ EXPECT_STREQ("23.0.0.254", address->host_str().c_str());
+ EXPECT_STREQ("23.0.0.254:2000", address->str().c_str());
+}
+
+namespace
+{
+ using stream_type = boost::asio::ip::tcp;
+
+ struct io_thread
+ {
+ boost::asio::io_service io_service;
+ boost::asio::io_service::work work;
+ stream_type::socket server;
+ stream_type::acceptor acceptor;
+ boost::thread io;
+ std::atomic<bool> connected;
+
+ io_thread()
+ : io_service(),
+ work(io_service),
+ server(io_service),
+ acceptor(io_service),
+ io([this] () { try { this->io_service.run(); } catch (const std::exception& e) { MERROR(e.what()); }}),
+ connected(false)
+ {
+ acceptor.open(boost::asio::ip::tcp::v4());
+ acceptor.bind(stream_type::endpoint{boost::asio::ip::tcp::v4(), 0});
+ acceptor.listen();
+ acceptor.async_accept(server, [this] (boost::system::error_code error) {
+ this->connected = true;
+ if (error)
+ throw boost::system::system_error{error};
+ });
+ }
+
+ ~io_thread() noexcept
+ {
+ io_service.stop();
+ if (io.joinable())
+ io.join();
+ }
+ };
+
+ struct checked_client
+ {
+ std::atomic<bool>* called_;
+ bool expected_;
+
+ void operator()(boost::system::error_code error, net::socks::client::stream_type::socket&&) const
+ {
+ EXPECT_EQ(expected_, bool(error)) << "Socks server: " << error.message();
+ ASSERT_TRUE(called_ != nullptr);
+ (*called_) = true;
+ }
+ };
+}
+
+TEST(socks_client, unsupported_command)
+{
+ boost::asio::io_service io_service{};
+ stream_type::socket client{io_service};
+
+ auto test_client = net::socks::make_connect_client(
+ std::move(client), net::socks::version::v4, std::bind( [] {} )
+ );
+ ASSERT_TRUE(bool(test_client));
+ EXPECT_TRUE(test_client->buffer().empty());
+
+ EXPECT_FALSE(test_client->set_connect_command("example.com", 8080));
+ EXPECT_TRUE(test_client->buffer().empty());
+
+ EXPECT_FALSE(test_client->set_resolve_command("example.com"));
+ EXPECT_TRUE(test_client->buffer().empty());
+}
+
+TEST(socks_client, no_command)
+{
+ boost::asio::io_service io_service{};
+ stream_type::socket client{io_service};
+
+ auto test_client = net::socks::make_connect_client(
+ std::move(client), net::socks::version::v4a, std::bind( [] {} )
+ );
+ ASSERT_TRUE(bool(test_client));
+ EXPECT_FALSE(net::socks::client::send(std::move(test_client)));
+}
+
+TEST(socks_client, connect_command)
+{
+ io_thread io{};
+ stream_type::socket client{io.io_service};
+
+ std::atomic<bool> called{false};
+ auto test_client = net::socks::make_connect_client(
+ std::move(client), net::socks::version::v4a, checked_client{std::addressof(called), false}
+ );
+ ASSERT_TRUE(bool(test_client));
+
+ ASSERT_TRUE(test_client->set_connect_command("example.com", 8080));
+ EXPECT_FALSE(test_client->buffer().empty());
+ ASSERT_TRUE(net::socks::client::connect_and_send(std::move(test_client), io.acceptor.local_endpoint()));
+ while (!io.connected);
+
+ const std::uint8_t expected_bytes[] = {
+ 4, 1, 0x1f, 0x90, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm', 0x00
+ };
+
+ std::uint8_t actual_bytes[sizeof(expected_bytes)];
+ boost::asio::read(io.server, boost::asio::buffer(actual_bytes));
+ EXPECT_TRUE(std::memcmp(expected_bytes, actual_bytes, sizeof(actual_bytes)) == 0);
+
+ const std::uint8_t reply_bytes[] = {0, 90, 0, 0, 0, 0, 0, 0};
+ boost::asio::write(io.server, boost::asio::buffer(reply_bytes));
+
+ // yikes!
+ while (!called);
+}
+
+TEST(socks_client, connect_command_failed)
+{
+ io_thread io{};
+ stream_type::socket client{io.io_service};
+
+ std::atomic<bool> called{false};
+ auto test_client = net::socks::make_connect_client(
+ std::move(client), net::socks::version::v4, checked_client{std::addressof(called), true}
+ );
+ ASSERT_TRUE(bool(test_client));
+
+ ASSERT_TRUE(
+ test_client->set_connect_command(
+ epee::net_utils::ipv4_network_address{boost::endian::native_to_big(std::uint32_t(5000)), 3000}
+ )
+ );
+ EXPECT_FALSE(test_client->buffer().empty());
+ ASSERT_TRUE(net::socks::client::connect_and_send(std::move(test_client), io.acceptor.local_endpoint()));
+ while (!io.connected);
+
+ const std::uint8_t expected_bytes[] = {
+ 4, 1, 0x0b, 0xb8, 0x00, 0x00, 0x13, 0x88, 0x00
+ };
+
+ std::uint8_t actual_bytes[sizeof(expected_bytes)];
+ boost::asio::read(io.server, boost::asio::buffer(actual_bytes));
+ EXPECT_TRUE(std::memcmp(expected_bytes, actual_bytes, sizeof(actual_bytes)) == 0);
+
+ const std::uint8_t reply_bytes[] = {0, 91, 0, 0, 0, 0, 0, 0};
+ boost::asio::write(io.server, boost::asio::buffer(reply_bytes));
+
+ // yikes!
+ while (!called);
+}
+
+TEST(socks_client, resolve_command)
+{
+ static std::uint8_t reply_bytes[] = {0, 90, 0, 0, 0xff, 0, 0xad, 0};
+
+ struct resolve_client : net::socks::client
+ {
+ std::atomic<unsigned> called_;
+ bool expected_;
+
+ resolve_client(stream_type::socket&& proxy)
+ : net::socks::client(std::move(proxy), net::socks::version::v4a_tor)
+ , called_(0)
+ , expected_(false)
+ {};
+
+ virtual void done(boost::system::error_code error, std::shared_ptr<client> self) override
+ {
+ EXPECT_EQ(this, self.get());
+ EXPECT_EQ(expected_, bool(error)) << "Resolve failure: " << error.message();
+
+ if (!error)
+ {
+ ASSERT_EQ(sizeof(reply_bytes), buffer().size());
+ EXPECT_EQ(0u, std::memcmp(buffer().data(), reply_bytes, sizeof(reply_bytes)));
+ }
+
+ ++called_;
+ }
+ };
+
+ io_thread io{};
+ stream_type::socket client{io.io_service};
+
+ auto test_client = std::make_shared<resolve_client>(std::move(client));
+ ASSERT_TRUE(bool(test_client));
+
+ ASSERT_TRUE(test_client->set_resolve_command("example.com"));
+ EXPECT_FALSE(test_client->buffer().empty());
+ ASSERT_TRUE(net::socks::client::connect_and_send(test_client, io.acceptor.local_endpoint()));
+ while (!io.connected);
+
+ const std::uint8_t expected_bytes[] = {
+ 4, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm', 0x00
+ };
+
+ std::uint8_t actual_bytes[sizeof(expected_bytes)];
+ boost::asio::read(io.server, boost::asio::buffer(actual_bytes));
+ EXPECT_TRUE(std::memcmp(expected_bytes, actual_bytes, sizeof(actual_bytes)) == 0);
+
+ boost::asio::write(io.server, boost::asio::buffer(reply_bytes));
+
+ // yikes!
+ while (test_client->called_ == 0);
+
+ test_client->expected_ = true;
+ ASSERT_TRUE(test_client->set_resolve_command("example.com"));
+ EXPECT_FALSE(test_client->buffer().empty());
+ ASSERT_TRUE(net::socks::client::send(test_client));
+
+ boost::asio::read(io.server, boost::asio::buffer(actual_bytes));
+ EXPECT_TRUE(std::memcmp(expected_bytes, actual_bytes, sizeof(actual_bytes)) == 0);
+
+ reply_bytes[1] = 91;
+ boost::asio::write(io.server, boost::asio::buffer(reply_bytes));
+
+ // yikes!
+ while (test_client->called_ == 1);
+}
+
+
diff --git a/tests/unit_tests/notify.cpp b/tests/unit_tests/notify.cpp
index cd70b7739..ceeba8649 100644
--- a/tests/unit_tests/notify.cpp
+++ b/tests/unit_tests/notify.cpp
@@ -67,7 +67,7 @@ TEST(notify, works)
+ " " + name_template + " %s";
tools::Notify notify(spec.c_str());
- notify.notify("1111111111111111111111111111111111111111111111111111111111111111");
+ notify.notify("%s", "1111111111111111111111111111111111111111111111111111111111111111", NULL);
bool ok = false;
for (int i = 0; i < 10; ++i)
diff --git a/tests/unit_tests/output_distribution.cpp b/tests/unit_tests/output_distribution.cpp
index 649752ac7..45f2c135b 100644
--- a/tests/unit_tests/output_distribution.cpp
+++ b/tests/unit_tests/output_distribution.cpp
@@ -33,7 +33,7 @@
#include "cryptonote_core/cryptonote_core.h"
#include "cryptonote_core/tx_pool.h"
#include "cryptonote_core/blockchain.h"
-#include "testdb.h"
+#include "blockchain_db/testdb.h"
static const uint64_t test_distribution[32] = {
0, 0, 0, 0, 0, 1, 5, 1, 4, 0, 0, 1, 0, 1, 2, 3, 1, 0, 2, 0, 1, 3, 8, 1, 3, 5, 7, 1, 5, 0, 2, 3
@@ -43,7 +43,7 @@ static const size_t test_distribution_size = sizeof(test_distribution) / sizeof(
namespace
{
-class TestDB: public BaseTestDB
+class TestDB: public cryptonote::BaseTestDB
{
public:
TestDB(size_t bc_height = test_distribution_size): blockchain_height(bc_height) { m_open = true; }
diff --git a/tests/unit_tests/pruning.cpp b/tests/unit_tests/pruning.cpp
new file mode 100644
index 000000000..83c35df68
--- /dev/null
+++ b/tests/unit_tests/pruning.cpp
@@ -0,0 +1,240 @@
+// Copyright (c) 2018, 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.
+
+#include "gtest/gtest.h"
+
+#include "misc_log_ex.h"
+#include "cryptonote_config.h"
+#include "common/pruning.h"
+
+#define ASSERT_EX(x) do { bool ex = false; try { x; } catch(...) { ex = true; } ASSERT_TRUE(ex); } while(0)
+
+TEST(pruning, parts)
+{
+ ASSERT_EQ(tools::get_pruning_stripe(tools::make_pruning_seed(3, 2)), 3);
+ ASSERT_EQ(tools::get_pruning_stripe(tools::make_pruning_seed(1, 2)), 1);
+ ASSERT_EQ(tools::get_pruning_stripe(tools::make_pruning_seed(7, 7)), 7);
+
+ ASSERT_EQ(tools::get_pruning_log_stripes(tools::make_pruning_seed(1, 2)), 2);
+ ASSERT_EQ(tools::get_pruning_log_stripes(tools::make_pruning_seed(1, 0)), 0);
+ ASSERT_EQ(tools::get_pruning_log_stripes(tools::make_pruning_seed(1, 7)), 7);
+ ASSERT_EQ(tools::get_pruning_log_stripes(tools::make_pruning_seed(7, 7)), 7);
+
+ for (uint32_t log_stripes = 1; log_stripes <= tools::PRUNING_SEED_LOG_STRIPES_MASK; ++log_stripes)
+ {
+ for (uint32_t stripe = 1; stripe <= (1 << log_stripes); ++stripe)
+ {
+ ASSERT_EQ(tools::get_pruning_log_stripes(tools::make_pruning_seed(stripe, log_stripes)), log_stripes);
+ ASSERT_EQ(tools::get_pruning_stripe(tools::make_pruning_seed(stripe, log_stripes)), stripe);
+ }
+ }
+}
+
+TEST(pruning, out_of_range)
+{
+ ASSERT_EX(tools::make_pruning_seed(5, 2));
+ ASSERT_EX(tools::make_pruning_seed(0, 2));
+}
+
+TEST(pruning, fits)
+{
+ const uint32_t log_stripes = 3;
+ const uint32_t num_stripes = 1 << log_stripes;
+ for (uint32_t stripe = 1; stripe <= num_stripes; ++stripe)
+ {
+ const uint32_t seed = tools::make_pruning_seed(stripe, log_stripes);
+ ASSERT_NE(seed, 0);
+ ASSERT_EQ(tools::get_pruning_log_stripes(seed), log_stripes);
+ ASSERT_EQ(tools::get_pruning_stripe(seed), stripe);
+ }
+}
+
+TEST(pruning, tip)
+{
+ static constexpr uint64_t H = CRYPTONOTE_PRUNING_TIP_BLOCKS + 1000;
+ static_assert(H >= CRYPTONOTE_PRUNING_TIP_BLOCKS, "H must be >= CRYPTONOTE_PRUNING_TIP_BLOCKS");
+ for (uint64_t h = H - CRYPTONOTE_PRUNING_TIP_BLOCKS; h < H; ++h)
+ {
+ uint32_t pruning_seed = tools::get_pruning_seed(h, H, CRYPTONOTE_PRUNING_LOG_STRIPES);
+ ASSERT_EQ(pruning_seed, 0);
+ for (pruning_seed = 0; pruning_seed <= (1 << CRYPTONOTE_PRUNING_LOG_STRIPES); ++pruning_seed)
+ ASSERT_TRUE(tools::has_unpruned_block(h, H, pruning_seed));
+ }
+}
+
+TEST(pruning, seed)
+{
+ const uint64_t SS = CRYPTONOTE_PRUNING_STRIPE_SIZE;
+ const uint64_t NS = 1 << CRYPTONOTE_PRUNING_LOG_STRIPES;
+ const uint64_t TB = NS * SS;
+
+ for (uint64_t cycle = 0; cycle < 10; ++cycle)
+ {
+ const uint64_t O = TB * cycle;
+ ASSERT_EQ(tools::get_pruning_stripe(O + 0, 10000000, CRYPTONOTE_PRUNING_LOG_STRIPES), 1);
+ ASSERT_EQ(tools::get_pruning_stripe(O + 1, 10000000, CRYPTONOTE_PRUNING_LOG_STRIPES), 1);
+ ASSERT_EQ(tools::get_pruning_stripe(O + SS-1, 10000000, CRYPTONOTE_PRUNING_LOG_STRIPES), 1);
+ ASSERT_EQ(tools::get_pruning_stripe(O + SS, 10000000, CRYPTONOTE_PRUNING_LOG_STRIPES), 2);
+ ASSERT_EQ(tools::get_pruning_stripe(O + SS*2-1, 10000000, CRYPTONOTE_PRUNING_LOG_STRIPES), 2);
+ ASSERT_EQ(tools::get_pruning_stripe(O + SS*2, 10000000, CRYPTONOTE_PRUNING_LOG_STRIPES), 3);
+ ASSERT_EQ(tools::get_pruning_stripe(O + SS*NS-1, 10000000, CRYPTONOTE_PRUNING_LOG_STRIPES), NS);
+ ASSERT_EQ(tools::get_pruning_stripe(O + SS*NS, 10000000, CRYPTONOTE_PRUNING_LOG_STRIPES), 1);
+ }
+}
+
+TEST(pruning, match)
+{
+ static constexpr uint64_t H = CRYPTONOTE_PRUNING_TIP_BLOCKS + 1000;
+ static_assert(H >= CRYPTONOTE_PRUNING_TIP_BLOCKS, "H must be >= CRYPTONOTE_PRUNING_TIP_BLOCKS");
+ for (uint64_t h = 0; h < H - CRYPTONOTE_PRUNING_TIP_BLOCKS; ++h)
+ {
+ uint32_t pruning_seed = tools::get_pruning_seed(h, H, CRYPTONOTE_PRUNING_LOG_STRIPES);
+ uint32_t pruning_stripe = tools::get_pruning_stripe(pruning_seed);
+ ASSERT_TRUE(pruning_stripe > 0 && pruning_stripe <= (1 << CRYPTONOTE_PRUNING_LOG_STRIPES));
+ for (uint32_t other_pruning_stripe = 1; other_pruning_stripe <= (1 << CRYPTONOTE_PRUNING_LOG_STRIPES); ++other_pruning_stripe)
+ {
+ uint32_t other_pruning_seed = tools::make_pruning_seed(other_pruning_stripe, CRYPTONOTE_PRUNING_LOG_STRIPES);
+ ASSERT_TRUE(tools::has_unpruned_block(h, H, other_pruning_seed) == (other_pruning_seed == pruning_seed));
+ }
+ }
+}
+
+TEST(pruning, stripe_size)
+{
+ static constexpr uint64_t H = CRYPTONOTE_PRUNING_TIP_BLOCKS + CRYPTONOTE_PRUNING_STRIPE_SIZE * (1 << CRYPTONOTE_PRUNING_LOG_STRIPES) + 1000;
+ static_assert(H >= CRYPTONOTE_PRUNING_TIP_BLOCKS + CRYPTONOTE_PRUNING_STRIPE_SIZE * (1 << CRYPTONOTE_PRUNING_LOG_STRIPES), "H must be >= that stuff in front");
+ for (uint32_t pruning_stripe = 1; pruning_stripe <= (1 << CRYPTONOTE_PRUNING_LOG_STRIPES); ++pruning_stripe)
+ {
+ uint32_t pruning_seed = tools::make_pruning_seed(pruning_stripe, CRYPTONOTE_PRUNING_LOG_STRIPES);
+ unsigned int current_run = 0, best_run = 0;
+ for (uint64_t h = 0; h < H - CRYPTONOTE_PRUNING_TIP_BLOCKS; ++h)
+ {
+ if (tools::has_unpruned_block(h, H, pruning_seed))
+ {
+ ++current_run;
+ }
+ else if (current_run)
+ {
+ ASSERT_EQ(current_run, CRYPTONOTE_PRUNING_STRIPE_SIZE);
+ best_run = std::max(best_run, current_run);
+ current_run = 0;
+ }
+ }
+ ASSERT_EQ(best_run, CRYPTONOTE_PRUNING_STRIPE_SIZE);
+ }
+}
+
+TEST(pruning, next_unpruned)
+{
+ static_assert((1 << CRYPTONOTE_PRUNING_LOG_STRIPES) >= 4, "CRYPTONOTE_PRUNING_LOG_STRIPES too low");
+
+ const uint64_t SS = CRYPTONOTE_PRUNING_STRIPE_SIZE;
+ const uint64_t NS = 1 << CRYPTONOTE_PRUNING_LOG_STRIPES;
+ const uint64_t TB = NS * SS;
+
+ for (uint64_t h = 0; h < 100; ++h)
+ ASSERT_EQ(tools::get_next_unpruned_block_height(h, 10000000, 0), h);
+
+ const uint32_t seed1 = tools::make_pruning_seed(1, CRYPTONOTE_PRUNING_LOG_STRIPES);
+ const uint32_t seed2 = tools::make_pruning_seed(2, CRYPTONOTE_PRUNING_LOG_STRIPES);
+ const uint32_t seed3 = tools::make_pruning_seed(3, CRYPTONOTE_PRUNING_LOG_STRIPES);
+ const uint32_t seed4 = tools::make_pruning_seed(4, CRYPTONOTE_PRUNING_LOG_STRIPES);
+ const uint32_t seedNS = tools::make_pruning_seed(NS, CRYPTONOTE_PRUNING_LOG_STRIPES);
+
+ ASSERT_EQ(tools::get_next_unpruned_block_height(0, 10000000, seed1), 0);
+ ASSERT_EQ(tools::get_next_unpruned_block_height(1, 10000000, seed1), 1);
+ ASSERT_EQ(tools::get_next_unpruned_block_height(SS-1, 10000000, seed1), SS-1);
+ ASSERT_EQ(tools::get_next_unpruned_block_height(SS, 10000000, seed1), TB);
+ ASSERT_EQ(tools::get_next_unpruned_block_height(TB, 10000000, seed1), TB);
+ ASSERT_EQ(tools::get_next_unpruned_block_height(TB-1, 10000000, seed1), TB);
+
+ ASSERT_EQ(tools::get_next_unpruned_block_height(0, 10000000, seed2), SS);
+ ASSERT_EQ(tools::get_next_unpruned_block_height(1, 10000000, seed2), SS);
+ ASSERT_EQ(tools::get_next_unpruned_block_height(SS-1, 10000000, seed2), SS);
+ ASSERT_EQ(tools::get_next_unpruned_block_height(SS, 10000000, seed2), SS);
+ ASSERT_EQ(tools::get_next_unpruned_block_height(2*SS-1, 10000000, seed2), 2*SS-1);
+ ASSERT_EQ(tools::get_next_unpruned_block_height(2*SS, 10000000, seed2), TB+SS);
+ ASSERT_EQ(tools::get_next_unpruned_block_height(TB+2*SS,10000000, seed2), TB*2+SS);
+
+ ASSERT_EQ(tools::get_next_unpruned_block_height(0, 10000000, seed3), SS*2);
+ ASSERT_EQ(tools::get_next_unpruned_block_height(SS, 10000000, seed3), SS*2);
+ ASSERT_EQ(tools::get_next_unpruned_block_height(2*SS, 10000000, seed3), SS*2);
+ ASSERT_EQ(tools::get_next_unpruned_block_height(3*SS-1, 10000000, seed3), SS*3-1);
+ ASSERT_EQ(tools::get_next_unpruned_block_height(3*SS, 10000000, seed3), TB+SS*2);
+ ASSERT_EQ(tools::get_next_unpruned_block_height(TB+3*SS,10000000, seed3), TB*2+SS*2);
+
+ ASSERT_EQ(tools::get_next_unpruned_block_height(SS, 10000000, seed4), 3*SS);
+ ASSERT_EQ(tools::get_next_unpruned_block_height(4*SS-1, 10000000, seed4), 4*SS-1);
+ ASSERT_EQ(tools::get_next_unpruned_block_height(4*SS, 10000000, seed4), TB+3*SS);
+ ASSERT_EQ(tools::get_next_unpruned_block_height(TB+4*SS,10000000, seed4), TB*2+3*SS);
+
+ ASSERT_EQ(tools::get_next_unpruned_block_height(SS, 10000000, seedNS), (NS-1)*SS);
+ ASSERT_EQ(tools::get_next_unpruned_block_height(NS*SS-1,10000000, seedNS), NS*SS-1);
+ ASSERT_EQ(tools::get_next_unpruned_block_height(NS*SS, 10000000, seedNS), TB+(NS-1)*SS);
+ ASSERT_EQ(tools::get_next_unpruned_block_height(TB+NS*SS, 10000000, seedNS), TB*2+(NS-1)*SS);
+}
+
+TEST(pruning, next_pruned)
+{
+ static_assert((1 << CRYPTONOTE_PRUNING_LOG_STRIPES) >= 4, "CRYPTONOTE_PRUNING_LOG_STRIPES too low");
+
+ const uint64_t SS = CRYPTONOTE_PRUNING_STRIPE_SIZE;
+ const uint64_t NS = 1 << CRYPTONOTE_PRUNING_LOG_STRIPES;
+ const uint64_t TB = NS * SS;
+
+ const uint32_t seed1 = tools::make_pruning_seed(1, CRYPTONOTE_PRUNING_LOG_STRIPES);
+ const uint32_t seed2 = tools::make_pruning_seed(2, CRYPTONOTE_PRUNING_LOG_STRIPES);
+ const uint32_t seedNS_1 = tools::make_pruning_seed(NS-1, CRYPTONOTE_PRUNING_LOG_STRIPES);
+ const uint32_t seedNS = tools::make_pruning_seed(NS, CRYPTONOTE_PRUNING_LOG_STRIPES);
+
+ for (uint64_t h = 0; h < 100; ++h)
+ ASSERT_EQ(tools::get_next_pruned_block_height(h, 10000000, 0), 10000000);
+ for (uint64_t h = 10000000 - 1 - CRYPTONOTE_PRUNING_TIP_BLOCKS; h < 10000000; ++h)
+ ASSERT_EQ(tools::get_next_pruned_block_height(h, 10000000, 0), 10000000);
+
+ ASSERT_EQ(tools::get_next_pruned_block_height(1, 10000000, seed1), SS);
+ ASSERT_EQ(tools::get_next_pruned_block_height(SS-1, 10000000, seed1), SS);
+ ASSERT_EQ(tools::get_next_pruned_block_height(SS, 10000000, seed1), SS);
+ ASSERT_EQ(tools::get_next_pruned_block_height(TB-1, 10000000, seed1), TB-1);
+ ASSERT_EQ(tools::get_next_pruned_block_height(TB, 10000000, seed1), TB+SS);
+
+ ASSERT_EQ(tools::get_next_pruned_block_height(1, 10000000, seed2), 1);
+ ASSERT_EQ(tools::get_next_pruned_block_height(SS-1, 10000000, seed2), SS-1);
+ ASSERT_EQ(tools::get_next_pruned_block_height(SS, 10000000, seed2), 2*SS);
+ ASSERT_EQ(tools::get_next_pruned_block_height(TB-1, 10000000, seed2), TB-1);
+
+ ASSERT_EQ(tools::get_next_pruned_block_height(1, 10000000, seedNS_1), 1);
+ ASSERT_EQ(tools::get_next_pruned_block_height(SS-1, 10000000, seedNS_1), SS-1);
+ ASSERT_EQ(tools::get_next_pruned_block_height(SS, 10000000, seedNS_1), SS);
+ ASSERT_EQ(tools::get_next_pruned_block_height(TB-1, 10000000, seedNS_1), TB-1);
+
+ ASSERT_EQ(tools::get_next_pruned_block_height(1, 10000000, seedNS), 1);
+ ASSERT_EQ(tools::get_next_pruned_block_height(SS-1, 10000000, seedNS), SS-1);
+ ASSERT_EQ(tools::get_next_pruned_block_height(SS, 10000000, seedNS), SS);
+ ASSERT_EQ(tools::get_next_pruned_block_height(TB-1, 10000000, seedNS), TB);
+}
diff --git a/tests/unit_tests/ringct.cpp b/tests/unit_tests/ringct.cpp
index ccef5f3e7..3f302cb83 100644
--- a/tests/unit_tests/ringct.cpp
+++ b/tests/unit_tests/ringct.cpp
@@ -171,8 +171,10 @@ TEST(ringct, range_proofs)
skpkGen(Sk, Pk);
destinations.push_back(Pk);
+ const rct::RCTConfig rct_config { RangeProofBorromean, 0 };
+
//compute rct data with mixin 500
- rctSig s = genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, hw::get_device("default"));
+ rctSig s = genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, rct_config, hw::get_device("default"));
//verify rct data
ASSERT_TRUE(verRct(s));
@@ -189,7 +191,7 @@ TEST(ringct, range_proofs)
//compute rct data with mixin 500
- s = genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, hw::get_device("default"));
+ s = genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, rct_config, hw::get_device("default"));
//verify rct data
ASSERT_FALSE(verRct(s));
@@ -235,8 +237,10 @@ TEST(ringct, range_proofs_with_fee)
skpkGen(Sk, Pk);
destinations.push_back(Pk);
+ const rct::RCTConfig rct_config { RangeProofBorromean, 0 };
+
//compute rct data with mixin 500
- rctSig s = genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, hw::get_device("default"));
+ rctSig s = genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, rct_config, hw::get_device("default"));
//verify rct data
ASSERT_TRUE(verRct(s));
@@ -253,7 +257,7 @@ TEST(ringct, range_proofs_with_fee)
//compute rct data with mixin 500
- s = genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, hw::get_device("default"));
+ s = genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, rct_config, hw::get_device("default"));
//verify rct data
ASSERT_FALSE(verRct(s));
@@ -311,7 +315,8 @@ TEST(ringct, simple)
//compute sig with mixin 2
xmr_amount txnfee = 1;
- rctSig s = genRctSimple(message, sc, pc, destinations,inamounts, outamounts, amount_keys, NULL, NULL, txnfee, 2, hw::get_device("default"));
+ const rct::RCTConfig rct_config { RangeProofBorromean, 0 };
+ rctSig s = genRctSimple(message, sc, pc, destinations,inamounts, outamounts, amount_keys, NULL, NULL, txnfee, 2, rct_config, hw::get_device("default"));
//verify ring ct signature
ASSERT_TRUE(verRctSimple(s));
@@ -345,7 +350,8 @@ static rct::rctSig make_sample_rct_sig(int n_inputs, const uint64_t input_amount
}
}
- return genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, hw::get_device("default"));
+ const rct::RCTConfig rct_config { RangeProofBorromean, 0 };
+ return genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, rct_config, hw::get_device("default"));
}
static rct::rctSig make_sample_simple_rct_sig(int n_inputs, const uint64_t input_amounts[], int n_outputs, const uint64_t output_amounts[], uint64_t fee)
@@ -371,7 +377,8 @@ static rct::rctSig make_sample_simple_rct_sig(int n_inputs, const uint64_t input
destinations.push_back(Pk);
}
- return genRctSimple(rct::zero(), sc, pc, destinations, inamounts, outamounts, amount_keys, NULL, NULL, fee, 3, hw::get_device("default"));
+ const rct::RCTConfig rct_config { RangeProofBorromean, 0 };
+ return genRctSimple(rct::zero(), sc, pc, destinations, inamounts, outamounts, amount_keys, NULL, NULL, fee, 3, rct_config, hw::get_device("default"));
}
static bool range_proof_test(bool expected_valid,
@@ -824,27 +831,6 @@ TEST(ringct, HPow2)
static const xmr_amount test_amounts[]={0, 1, 2, 3, 4, 5, 10000, 10000000000000000000ull, 10203040506070809000ull, 123456789123456789};
-TEST(ringct, ecdh_roundtrip)
-{
- key k;
- ecdhTuple t0, t1;
-
- for (auto amount: test_amounts) {
- skGen(k);
-
- t0.mask = skGen();
- t0.amount = d2h(amount);
-
- t1 = t0;
- ecdhEncode(t1, k);
- ecdhDecode(t1, k);
- ASSERT_TRUE(t0.mask == t1.mask);
- ASSERT_TRUE(equalKeys(t0.mask, t1.mask));
- ASSERT_TRUE(t0.amount == t1.amount);
- ASSERT_TRUE(equalKeys(t0.amount, t1.amount));
- }
-}
-
TEST(ringct, d2h)
{
key k, P1;
diff --git a/tests/unit_tests/serialization.cpp b/tests/unit_tests/serialization.cpp
index b4517af2f..343a11c37 100644
--- a/tests/unit_tests/serialization.cpp
+++ b/tests/unit_tests/serialization.cpp
@@ -550,12 +550,10 @@ TEST(Serialization, serializes_ringct_types)
ecdh0.mask = rct::skGen();
ecdh0.amount = rct::skGen();
- ecdh0.senderPk = rct::skGen();
ASSERT_TRUE(serialization::dump_binary(ecdh0, blob));
ASSERT_TRUE(serialization::parse_binary(blob, ecdh1));
ASSERT_TRUE(!memcmp(&ecdh0.mask, &ecdh1.mask, sizeof(ecdh0.mask)));
ASSERT_TRUE(!memcmp(&ecdh0.amount, &ecdh1.amount, sizeof(ecdh0.amount)));
- // senderPk is not serialized
for (size_t n = 0; n < 64; ++n)
{
@@ -591,7 +589,8 @@ TEST(Serialization, serializes_ringct_types)
rct::skpkGen(Sk, Pk);
destinations.push_back(Pk);
//compute rct data with mixin 500
- s0 = rct::genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, hw::get_device("default"));
+ const rct::RCTConfig rct_config{ rct::RangeProofPaddedBulletproof, 0 };
+ s0 = rct::genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, rct_config, hw::get_device("default"));
mg0 = s0.p.MGs[0];
ASSERT_TRUE(serialization::dump_binary(mg0, blob));
diff --git a/tests/unit_tests/test_peerlist.cpp b/tests/unit_tests/test_peerlist.cpp
index f638c6251..03aa48ea0 100644
--- a/tests/unit_tests/test_peerlist.cpp
+++ b/tests/unit_tests/test_peerlist.cpp
@@ -37,7 +37,7 @@
TEST(peer_list, peer_list_general)
{
nodetool::peerlist_manager plm;
- plm.init(false);
+ plm.init(nodetool::peerlist_types{}, false);
#define MAKE_IPV4_ADDRESS(a,b,c,d,e) epee::net_utils::ipv4_network_address{MAKE_IP(a,b,c,d),e}
#define ADD_GRAY_NODE(addr_, id_, last_seen_) { nodetool::peerlist_entry ple; ple.last_seen=last_seen_;ple.adr = addr_; ple.id = id_;plm.append_with_peer_gray(ple);}
#define ADD_WHITE_NODE(addr_, id_, last_seen_) { nodetool::peerlist_entry ple;ple.last_seen=last_seen_; ple.adr = addr_; ple.id = id_;plm.append_with_peer_white(ple);}
@@ -77,9 +77,180 @@ TEST(peer_list, merge_peer_lists)
//([^ \t]*)\t([^ \t]*):([^ \t]*) \tlast_seen: d(\d+)\.h(\d+)\.m(\d+)\.s(\d+)\n
//ADD_NODE_TO_PL("\2", \3, 0x\1, (1353346618 -(\4*60*60*24+\5*60*60+\6*60+\7 )));\n
nodetool::peerlist_manager plm;
- plm.init(false);
+ plm.init(nodetool::peerlist_types{}, false);
std::vector<nodetool::peerlist_entry> outer_bs;
#define ADD_NODE_TO_PL(ip_, port_, id_, timestamp_) { nodetool::peerlist_entry ple; epee::string_tools::get_ip_int32_from_string(ple.adr.ip, ip_); ple.last_seen = timestamp_; ple.adr.port = port_; ple.id = id_;outer_bs.push_back(ple);}
+}
+
+namespace
+{
+ bool check_empty(nodetool::peerlist_storage& peers, std::initializer_list<epee::net_utils::zone> zones)
+ {
+ bool pass = false;
+ for (const epee::net_utils::zone zone : zones)
+ {
+ const nodetool::peerlist_types types{peers.take_zone(zone)};
+ EXPECT_TRUE(types.white.empty());
+ EXPECT_TRUE(types.gray.empty());
+ EXPECT_TRUE(types.anchor.empty());
+ pass = (types.white.empty() && types.gray.empty() && types.anchor.empty());
+ }
+ return pass;
+ }
+}
+
+TEST(peerlist_storage, store)
+{
+
+ using address_type = epee::net_utils::address_type;
+ using zone = epee::net_utils::zone;
+
+ nodetool::peerlist_storage peers{};
+ EXPECT_TRUE(check_empty(peers, {zone::invalid, zone::public_, zone::tor, zone::i2p}));
+
+ std::string buffer{};
+ {
+ nodetool::peerlist_types types{};
+ types.white.push_back({epee::net_utils::ipv4_network_address{1000, 10}, 44, 55});
+ types.white.push_back({net::tor_address::unknown(), 64, 75});
+ types.gray.push_back({net::tor_address::unknown(), 99, 88});
+ types.gray.push_back({epee::net_utils::ipv4_network_address{2000, 20}, 84, 45});
+ types.anchor.push_back({epee::net_utils::ipv4_network_address{999, 654}, 444, 555});
+ types.anchor.push_back({net::tor_address::unknown(), 14, 33});
+ types.anchor.push_back({net::tor_address::unknown(), 24, 22});
+
+ std::ostringstream stream{};
+ EXPECT_TRUE(peers.store(stream, types));
+ buffer = stream.str();
+ }
+ EXPECT_TRUE(check_empty(peers, {zone::invalid, zone::public_, zone::tor, zone::i2p}));
+ {
+ std::istringstream stream{buffer};
+ boost::optional<nodetool::peerlist_storage> read_peers =
+ nodetool::peerlist_storage::open(stream, true);
+ ASSERT_TRUE(bool(read_peers));
+ peers = std::move(*read_peers);
+ }
+ EXPECT_TRUE(check_empty(peers, {zone::invalid, zone::i2p}));
+
+ nodetool::peerlist_types types = peers.take_zone(zone::public_);
+ EXPECT_TRUE(check_empty(peers, {zone::invalid, zone::public_, zone::i2p}));
+
+ ASSERT_EQ(1u, types.white.size());
+ ASSERT_EQ(address_type::ipv4, types.white[0].adr.get_type_id());
+ EXPECT_EQ(1000u, types.white[0].adr.template as<epee::net_utils::ipv4_network_address>().ip());
+ EXPECT_EQ(10u, types.white[0].adr.template as<epee::net_utils::ipv4_network_address>().port());
+ EXPECT_EQ(44u, types.white[0].id);
+ EXPECT_EQ(55u, types.white[0].last_seen);
+
+ ASSERT_EQ(1u, types.gray.size());
+ ASSERT_EQ(address_type::ipv4, types.gray[0].adr.get_type_id());
+ EXPECT_EQ(2000u, types.gray[0].adr.template as<epee::net_utils::ipv4_network_address>().ip());
+ EXPECT_EQ(20u, types.gray[0].adr.template as<epee::net_utils::ipv4_network_address>().port());
+ EXPECT_EQ(84u, types.gray[0].id);
+ EXPECT_EQ(45u, types.gray[0].last_seen);
+
+ ASSERT_EQ(1u, types.anchor.size());
+ ASSERT_EQ(address_type::ipv4, types.anchor[0].adr.get_type_id());
+ EXPECT_EQ(999u, types.anchor[0].adr.template as<epee::net_utils::ipv4_network_address>().ip());
+ EXPECT_EQ(654u, types.anchor[0].adr.template as<epee::net_utils::ipv4_network_address>().port());
+ EXPECT_EQ(444u, types.anchor[0].id);
+ EXPECT_EQ(555u, types.anchor[0].first_seen);
+ {
+ std::ostringstream stream{};
+ EXPECT_TRUE(peers.store(stream, types));
+ buffer = stream.str();
+ }
+ EXPECT_TRUE(check_empty(peers, {zone::invalid, zone::public_, zone::i2p}));
+
+ types = peers.take_zone(zone::tor);
+ EXPECT_TRUE(check_empty(peers, {zone::invalid, zone::public_, zone::i2p, zone::tor}));
+
+ ASSERT_EQ(1u, types.white.size());
+ ASSERT_EQ(address_type::tor, types.white[0].adr.get_type_id());
+ EXPECT_STREQ(net::tor_address::unknown_str(), types.white[0].adr.template as<net::tor_address>().host_str());
+ EXPECT_EQ(0u, types.white[0].adr.template as<net::tor_address>().port());
+ EXPECT_EQ(64u, types.white[0].id);
+ EXPECT_EQ(75u, types.white[0].last_seen);
+
+ ASSERT_EQ(1u, types.gray.size());
+ ASSERT_EQ(address_type::tor, types.gray[0].adr.get_type_id());
+ EXPECT_STREQ(net::tor_address::unknown_str(), types.gray[0].adr.template as<net::tor_address>().host_str());
+ EXPECT_EQ(0u, types.gray[0].adr.template as<net::tor_address>().port());
+ EXPECT_EQ(99u, types.gray[0].id);
+ EXPECT_EQ(88u, types.gray[0].last_seen);
+
+ ASSERT_EQ(2u, types.anchor.size());
+ ASSERT_EQ(address_type::tor, types.anchor[0].adr.get_type_id());
+ EXPECT_STREQ(net::tor_address::unknown_str(), types.anchor[0].adr.template as<net::tor_address>().host_str());
+ EXPECT_EQ(0u, types.anchor[0].adr.template as<net::tor_address>().port());
+ EXPECT_EQ(14u, types.anchor[0].id);
+ EXPECT_EQ(33u, types.anchor[0].first_seen);
+ ASSERT_EQ(address_type::tor, types.anchor[1].adr.get_type_id());
+ EXPECT_STREQ(net::tor_address::unknown_str(), types.anchor[1].adr.template as<net::tor_address>().host_str());
+ EXPECT_EQ(0u, types.anchor[1].adr.template as<net::tor_address>().port());
+ EXPECT_EQ(24u, types.anchor[1].id);
+ EXPECT_EQ(22u, types.anchor[1].first_seen);
+
+ {
+ std::istringstream stream{buffer};
+ boost::optional<nodetool::peerlist_storage> read_peers =
+ nodetool::peerlist_storage::open(stream, true);
+ ASSERT_TRUE(bool(read_peers));
+ peers = std::move(*read_peers);
+ }
+ EXPECT_TRUE(check_empty(peers, {zone::invalid, zone::i2p}));
+
+ types = peers.take_zone(zone::public_);
+ EXPECT_TRUE(check_empty(peers, {zone::invalid, zone::public_, zone::i2p}));
+
+ ASSERT_EQ(1u, types.white.size());
+ ASSERT_EQ(address_type::ipv4, types.white[0].adr.get_type_id());
+ EXPECT_EQ(1000u, types.white[0].adr.template as<epee::net_utils::ipv4_network_address>().ip());
+ EXPECT_EQ(10u, types.white[0].adr.template as<epee::net_utils::ipv4_network_address>().port());
+ EXPECT_EQ(44u, types.white[0].id);
+ EXPECT_EQ(55u, types.white[0].last_seen);
+
+ ASSERT_EQ(1u, types.gray.size());
+ ASSERT_EQ(address_type::ipv4, types.gray[0].adr.get_type_id());
+ EXPECT_EQ(2000u, types.gray[0].adr.template as<epee::net_utils::ipv4_network_address>().ip());
+ EXPECT_EQ(20u, types.gray[0].adr.template as<epee::net_utils::ipv4_network_address>().port());
+ EXPECT_EQ(84u, types.gray[0].id);
+ EXPECT_EQ(45u, types.gray[0].last_seen);
+
+ ASSERT_EQ(1u, types.anchor.size());
+ ASSERT_EQ(address_type::ipv4, types.anchor[0].adr.get_type_id());
+ EXPECT_EQ(999u, types.anchor[0].adr.template as<epee::net_utils::ipv4_network_address>().ip());
+ EXPECT_EQ(654u, types.anchor[0].adr.template as<epee::net_utils::ipv4_network_address>().port());
+ EXPECT_EQ(444u, types.anchor[0].id);
+ EXPECT_EQ(555u, types.anchor[0].first_seen);
+
+ types = peers.take_zone(zone::tor);
+ EXPECT_TRUE(check_empty(peers, {zone::invalid, zone::public_, zone::i2p, zone::tor}));
+
+ ASSERT_EQ(1u, types.white.size());
+ ASSERT_EQ(address_type::tor, types.white[0].adr.get_type_id());
+ EXPECT_STREQ(net::tor_address::unknown_str(), types.white[0].adr.template as<net::tor_address>().host_str());
+ EXPECT_EQ(0u, types.white[0].adr.template as<net::tor_address>().port());
+ EXPECT_EQ(64u, types.white[0].id);
+ EXPECT_EQ(75u, types.white[0].last_seen);
+ ASSERT_EQ(1u, types.gray.size());
+ ASSERT_EQ(address_type::tor, types.gray[0].adr.get_type_id());
+ EXPECT_STREQ(net::tor_address::unknown_str(), types.gray[0].adr.template as<net::tor_address>().host_str());
+ EXPECT_EQ(0u, types.gray[0].adr.template as<net::tor_address>().port());
+ EXPECT_EQ(99u, types.gray[0].id);
+ EXPECT_EQ(88u, types.gray[0].last_seen);
+ ASSERT_EQ(2u, types.anchor.size());
+ ASSERT_EQ(address_type::tor, types.anchor[0].adr.get_type_id());
+ EXPECT_STREQ(net::tor_address::unknown_str(), types.anchor[0].adr.template as<net::tor_address>().host_str());
+ EXPECT_EQ(0u, types.anchor[0].adr.template as<net::tor_address>().port());
+ EXPECT_EQ(14u, types.anchor[0].id);
+ EXPECT_EQ(33u, types.anchor[0].first_seen);
+ ASSERT_EQ(address_type::tor, types.anchor[1].adr.get_type_id());
+ EXPECT_STREQ(net::tor_address::unknown_str(), types.anchor[1].adr.template as<net::tor_address>().host_str());
+ EXPECT_EQ(0u, types.anchor[1].adr.template as<net::tor_address>().port());
+ EXPECT_EQ(24u, types.anchor[1].id);
+ EXPECT_EQ(22u, types.anchor[1].first_seen);
}
diff --git a/tests/unit_tests/testdb.h b/tests/unit_tests/testdb.h
deleted file mode 100644
index 8f5cf70e8..000000000
--- a/tests/unit_tests/testdb.h
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright (c) 2014-2018, 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 <string>
-#include <vector>
-#include <map>
-#include "gtest/gtest.h"
-
-#include "blockchain_db/blockchain_db.h"
-
-class BaseTestDB: public cryptonote::BlockchainDB {
-public:
- BaseTestDB() {}
- virtual void open(const std::string& filename, const int db_flags = 0) { }
- virtual void close() {}
- virtual void sync() {}
- virtual void safesyncmode(const bool onoff) {}
- virtual void reset() {}
- virtual std::vector<std::string> get_filenames() const { return std::vector<std::string>(); }
- virtual bool remove_data_file(const std::string& folder) const { return true; }
- virtual std::string get_db_name() const { return std::string(); }
- virtual bool lock() { return true; }
- virtual void unlock() { }
- virtual bool batch_start(uint64_t batch_num_blocks=0, uint64_t batch_bytes=0) { return true; }
- virtual void batch_stop() {}
- virtual void set_batch_transactions(bool) {}
- virtual void block_txn_start(bool readonly=false) {}
- virtual void block_txn_stop() {}
- virtual void block_txn_abort() {}
- virtual void drop_hard_fork_info() {}
- virtual bool block_exists(const crypto::hash& h, uint64_t *height) const { return false; }
- virtual cryptonote::blobdata get_block_blob_from_height(const uint64_t& height) const { return cryptonote::t_serializable_object_to_blob(get_block_from_height(height)); }
- virtual cryptonote::blobdata get_block_blob(const crypto::hash& h) const { return cryptonote::blobdata(); }
- virtual bool get_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const { return false; }
- virtual bool get_pruned_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const { return false; }
- virtual bool get_prunable_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const { return false; }
- virtual bool get_prunable_tx_hash(const crypto::hash& tx_hash, crypto::hash &prunable_hash) const { return false; }
- virtual uint64_t get_block_height(const crypto::hash& h) const { return 0; }
- virtual cryptonote::block_header get_block_header(const crypto::hash& h) const { return cryptonote::block_header(); }
- virtual uint64_t get_block_timestamp(const uint64_t& height) const { return 0; }
- virtual std::vector<uint64_t> get_block_cumulative_rct_outputs(const std::vector<uint64_t> &heights) const { return {}; }
- virtual uint64_t get_top_block_timestamp() const { return 0; }
- virtual size_t get_block_weight(const uint64_t& height) const { return 128; }
- virtual cryptonote::difficulty_type get_block_cumulative_difficulty(const uint64_t& height) const { return 10; }
- virtual cryptonote::difficulty_type get_block_difficulty(const uint64_t& height) const { return 0; }
- virtual uint64_t get_block_already_generated_coins(const uint64_t& height) const { return 10000000000; }
- virtual crypto::hash get_block_hash_from_height(const uint64_t& height) const { return crypto::hash(); }
- virtual std::vector<cryptonote::block> get_blocks_range(const uint64_t& h1, const uint64_t& h2) const { return std::vector<cryptonote::block>(); }
- virtual std::vector<crypto::hash> get_hashes_range(const uint64_t& h1, const uint64_t& h2) const { return std::vector<crypto::hash>(); }
- virtual crypto::hash top_block_hash() const { return crypto::hash(); }
- virtual cryptonote::block get_top_block() const { return cryptonote::block(); }
- virtual uint64_t height() const { return 1; }
- virtual bool tx_exists(const crypto::hash& h) const { return false; }
- virtual bool tx_exists(const crypto::hash& h, uint64_t& tx_index) const { return false; }
- virtual uint64_t get_tx_unlock_time(const crypto::hash& h) const { return 0; }
- virtual cryptonote::transaction get_tx(const crypto::hash& h) const { return cryptonote::transaction(); }
- virtual bool get_tx(const crypto::hash& h, cryptonote::transaction &tx) const { return false; }
- virtual uint64_t get_tx_count() const { return 0; }
- virtual std::vector<cryptonote::transaction> get_tx_list(const std::vector<crypto::hash>& hlist) const { return std::vector<cryptonote::transaction>(); }
- virtual uint64_t get_tx_block_height(const crypto::hash& h) const { return 0; }
- virtual uint64_t get_num_outputs(const uint64_t& amount) const { return 1; }
- virtual uint64_t get_indexing_base() const { return 0; }
- virtual cryptonote::output_data_t get_output_key(const uint64_t& amount, const uint64_t& index, bool include_commitmemt) const { return cryptonote::output_data_t(); }
- virtual cryptonote::tx_out_index get_output_tx_and_index_from_global(const uint64_t& index) const { return cryptonote::tx_out_index(); }
- virtual cryptonote::tx_out_index get_output_tx_and_index(const uint64_t& amount, const uint64_t& index) const { return cryptonote::tx_out_index(); }
- virtual void get_output_tx_and_index(const uint64_t& amount, const std::vector<uint64_t> &offsets, std::vector<cryptonote::tx_out_index> &indices) const {}
- virtual void get_output_key(const epee::span<const uint64_t> &amounts, const std::vector<uint64_t> &offsets, std::vector<cryptonote::output_data_t> &outputs, bool allow_partial = false) const {}
- virtual bool can_thread_bulk_indices() const { return false; }
- virtual std::vector<uint64_t> get_tx_output_indices(const crypto::hash& h) const { return std::vector<uint64_t>(); }
- virtual std::vector<std::vector<uint64_t>> get_tx_amount_output_indices(const uint64_t tx_index, size_t n_txes) const { return std::vector<std::vector<uint64_t>>(); }
- virtual bool has_key_image(const crypto::key_image& img) const { return false; }
- virtual void remove_block() { }
- virtual uint64_t add_transaction_data(const crypto::hash& blk_hash, const cryptonote::transaction& tx, const crypto::hash& tx_hash, const crypto::hash& tx_prunable_hash) {return 0;}
- virtual void remove_transaction_data(const crypto::hash& tx_hash, const cryptonote::transaction& tx) {}
- virtual uint64_t add_output(const crypto::hash& tx_hash, const cryptonote::tx_out& tx_output, const uint64_t& local_index, const uint64_t unlock_time, const rct::key *commitment) {return 0;}
- virtual void add_tx_amount_output_indices(const uint64_t tx_index, const std::vector<uint64_t>& amount_output_indices) {}
- virtual void add_spent_key(const crypto::key_image& k_image) {}
- virtual void remove_spent_key(const crypto::key_image& k_image) {}
-
- virtual bool for_all_key_images(std::function<bool(const crypto::key_image&)>) const { return true; }
- virtual bool for_blocks_range(const uint64_t&, const uint64_t&, std::function<bool(uint64_t, const crypto::hash&, const cryptonote::block&)>) const { return true; }
- virtual bool for_all_transactions(std::function<bool(const crypto::hash&, const cryptonote::transaction&)>, bool pruned) const { return true; }
- virtual bool for_all_outputs(std::function<bool(uint64_t amount, const crypto::hash &tx_hash, uint64_t height, size_t tx_idx)> f) const { return true; }
- virtual bool for_all_outputs(uint64_t amount, const std::function<bool(uint64_t height)> &f) const { return true; }
- virtual bool is_read_only() const { return false; }
- virtual std::map<uint64_t, std::tuple<uint64_t, uint64_t, uint64_t>> get_output_histogram(const std::vector<uint64_t> &amounts, bool unlocked, uint64_t recent_cutoff, uint64_t min_count) const { return std::map<uint64_t, std::tuple<uint64_t, uint64_t, uint64_t>>(); }
- virtual bool get_output_distribution(uint64_t amount, uint64_t from_height, uint64_t to_height, std::vector<uint64_t> &distribution, uint64_t &base) const { return false; }
-
- virtual void add_txpool_tx(const crypto::hash &txid, const cryptonote::blobdata &blob, const cryptonote::txpool_tx_meta_t& details) {}
- virtual void update_txpool_tx(const crypto::hash &txid, const cryptonote::txpool_tx_meta_t& details) {}
- virtual uint64_t get_txpool_tx_count(bool include_unrelayed_txes = true) const { return 0; }
- virtual bool txpool_has_tx(const crypto::hash &txid) const { return false; }
- virtual void remove_txpool_tx(const crypto::hash& txid) {}
- virtual bool get_txpool_tx_meta(const crypto::hash& txid, cryptonote::txpool_tx_meta_t &meta) const { return false; }
- virtual bool get_txpool_tx_blob(const crypto::hash& txid, cryptonote::blobdata &bd) const { return false; }
- virtual uint64_t get_database_size() const { return 0; }
- virtual cryptonote::blobdata get_txpool_tx_blob(const crypto::hash& txid) const { return ""; }
- virtual bool for_all_txpool_txes(std::function<bool(const crypto::hash&, const cryptonote::txpool_tx_meta_t&, const cryptonote::blobdata*)>, bool include_blob = false, bool include_unrelayed_txes = false) const { return false; }
-
- virtual void add_block( const cryptonote::block& blk
- , size_t block_weight
- , const cryptonote::difficulty_type& cumulative_difficulty
- , const uint64_t& coins_generated
- , uint64_t num_rct_outs
- , const crypto::hash& blk_hash
- ) { }
- virtual cryptonote::block get_block_from_height(const uint64_t& height) const { return cryptonote::block(); }
- virtual void set_hard_fork_version(uint64_t height, uint8_t version) {}
- virtual uint8_t get_hard_fork_version(uint64_t height) const { return 0; }
- virtual void check_hard_fork_info() {}
-
- virtual uint32_t get_blockchain_pruning_seed() const { return 0; }
- virtual bool prune_blockchain(uint32_t pruning_seed = 0) { return true; }
- virtual bool update_pruning() { return true; }
- virtual bool check_pruning() { return true; }
- virtual void prune_outputs(uint64_t amount) {}
-};
-