From 6a0b3b1f8a5f96e8906e4a6746ad2b0358bb3d64 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Fri, 8 Nov 2019 17:30:51 +0000 Subject: functional_tests: add randomx tests --- tests/functional_tests/functional_tests_rpc.py | 3 + tests/functional_tests/mining.py | 114 +++++++++++++++++++++++++ 2 files changed, 117 insertions(+) (limited to 'tests/functional_tests') diff --git a/tests/functional_tests/functional_tests_rpc.py b/tests/functional_tests/functional_tests_rpc.py index 3be62c0ca..79e04b8a6 100755 --- a/tests/functional_tests/functional_tests_rpc.py +++ b/tests/functional_tests/functional_tests_rpc.py @@ -92,6 +92,9 @@ try: os.environ['PYTHONIOENCODING'] = 'utf-8' os.environ['DIFFICULTY'] = str(DIFFICULTY) os.environ['MAKE_TEST_SIGNATURE'] = builddir + '/tests/functional_tests/make_test_signature' + os.environ['SEEDHASH_EPOCH_BLOCKS'] = "8" + os.environ['SEEDHASH_EPOCH_LAG'] = "4" + for i in range(len(command_lines)): #print('Running: ' + str(command_lines[i])) processes.append(subprocess.Popen(command_lines[i], stdout = outputs[i])) diff --git a/tests/functional_tests/mining.py b/tests/functional_tests/mining.py index d067c25e1..c60bf8396 100755 --- a/tests/functional_tests/mining.py +++ b/tests/functional_tests/mining.py @@ -30,6 +30,7 @@ from __future__ import print_function import time +import os """Test daemon mining RPC calls @@ -49,6 +50,8 @@ class MiningTest(): self.mine(True) self.mine(False) self.submitblock() + self.reset() + self.test_randomx() def reset(self): print('Resetting blockchain') @@ -169,6 +172,117 @@ class MiningTest(): assert res.height == height + i + 1 assert res.hash == block_hash + def test_randomx(self): + print("Test RandomX") + + daemon = Daemon() + wallet = Wallet() + + res = daemon.get_height() + daemon.pop_blocks(res.height - 1) + daemon.flush_txpool() + + epoch = int(os.environ['SEEDHASH_EPOCH_BLOCKS']) + lag = int(os.environ['SEEDHASH_EPOCH_LAG']) + address = '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm' + + # check we can generate blocks, and that the seed hash changes when expected + res = daemon.getblocktemplate(address) + first_seed_hash = res.seed_hash + daemon.generateblocks(address, 1 + lag) + res = daemon.mining_status() + assert res.active == False + assert res.pow_algorithm == 'RandomX' + res = daemon.getblocktemplate(address) + seed_hash = res.seed_hash + t0 = time.time() + daemon.generateblocks(address, epoch - 3) + t0 = time.time() - t0 + res = daemon.get_info() + assert res.height == lag + epoch - 1 + res = daemon.getblocktemplate(address) + assert seed_hash == res.seed_hash + t0 = time.time() + daemon.generateblocks(address, 1) + t0 = time.time() - t0 + res = daemon.get_info() + assert res.height == lag + epoch + daemon.generateblocks(address, 1) + res = daemon.getblocktemplate(address) + assert seed_hash != res.seed_hash + new_seed_hash = res.seed_hash + t0 = time.time() + daemon.generateblocks(address, epoch - 1) + t0 = time.time() - t0 + res = daemon.getblocktemplate(address) + assert new_seed_hash == res.seed_hash + daemon.generateblocks(address, 1) + res = daemon.getblocktemplate(address) + assert new_seed_hash != res.seed_hash + new_seed_hash = res.seed_hash + t0 = time.time() + daemon.generateblocks(address, epoch - 1) + t0 = time.time() - t0 + res = daemon.getblocktemplate(address) + assert new_seed_hash == res.seed_hash + daemon.generateblocks(address, 1) + res = daemon.getblocktemplate(address) + assert new_seed_hash != res.seed_hash + #print('First mining: ' + str(t0)) + + # pop all these blocks, and feed them again to monerod + print('Recreating the chain') + res = daemon.get_info() + height = res.height + assert height == lag + epoch * 3 + 1 + block_hashes = [x.hash for x in daemon.getblockheadersrange(0, height - 1).headers] + assert len(block_hashes) == height + blocks = [] + for i in range(len(block_hashes)): + res = daemon.getblock(height = i) + assert res.block_header.hash == block_hashes[i] + blocks.append(res.blob) + daemon.pop_blocks(height) + res = daemon.get_info() + assert res.height == 1 + res = daemon.getblocktemplate(address) + assert first_seed_hash == res.seed_hash + t0 = time.time() + for h in range(len(block_hashes)): + res = daemon.submitblock(blocks[h]) + t0 = time.time() - t0 + res = daemon.get_info() + assert height == res.height + res = daemon.getblocktemplate(address) + assert new_seed_hash != res.seed_hash + res = daemon.pop_blocks(1) + res = daemon.getblocktemplate(address) + assert new_seed_hash == res.seed_hash + #print('Submit: ' + str(t0)) + + # start mining from the genesis block again + print('Mining from genesis block again') + res = daemon.get_height() + top_hash = res.hash + res = daemon.getblockheaderbyheight(0) + genesis_block_hash = res.block_header.hash + t0 = time.time() + daemon.generateblocks(address, height - 2, prev_block = genesis_block_hash) + t0 = time.time() - t0 + res = daemon.get_info() + assert res.height == height - 1 + assert res.top_block_hash == top_hash + #print('Second mining: ' + str(t0)) + + # that one will cause a huge reorg + print('Adding one to reorg') + res = daemon.generateblocks(address, 1) + assert len(res.blocks) == 1 + new_top_hash = res.blocks[0] + res = daemon.get_info() + assert res.height == height + assert res.top_block_hash == new_top_hash + class Guard: def __enter__(self): -- cgit v1.2.3 From d20ff4f648ea3b716825ea34db05b98ad24239b4 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Fri, 19 Jun 2020 19:55:19 +0000 Subject: functional_tests: add a large (many randomx epochs) p2p reorg test --- src/cryptonote_core/cryptonote_core.cpp | 39 +++++++++++++++++++++++++++++---- tests/functional_tests/p2p.py | 19 ++++++++++++++++ 2 files changed, 54 insertions(+), 4 deletions(-) (limited to 'tests/functional_tests') diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index 3715440fe..f27bf8aba 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -1181,11 +1181,42 @@ namespace cryptonote size_t core::get_block_sync_size(uint64_t height) const { static const uint64_t quick_height = m_nettype == TESTNET ? 801219 : m_nettype == MAINNET ? 1220516 : 0; + size_t res = 0; if (block_sync_size > 0) - return block_sync_size; - if (height >= quick_height) - return BLOCKS_SYNCHRONIZING_DEFAULT_COUNT; - return BLOCKS_SYNCHRONIZING_DEFAULT_COUNT_PRE_V4; + res = block_sync_size; + else if (height >= quick_height) + res = BLOCKS_SYNCHRONIZING_DEFAULT_COUNT; + else + res = BLOCKS_SYNCHRONIZING_DEFAULT_COUNT_PRE_V4; + + static size_t max_block_size = 0; + if (max_block_size == 0) + { + const char *env = getenv("SEEDHASH_EPOCH_BLOCKS"); + if (env) + { + int n = atoi(env); + if (n <= 0) + n = BLOCKS_SYNCHRONIZING_MAX_COUNT; + size_t p = 1; + while (p < (size_t)n) + p <<= 1; + max_block_size = p; + } + else + max_block_size = BLOCKS_SYNCHRONIZING_MAX_COUNT; + } + if (res > max_block_size) + { + static bool warned = false; + if (!warned) + { + MWARNING("Clamping block sync size to " << max_block_size); + warned = true; + } + res = max_block_size; + } + return res; } //----------------------------------------------------------------------------------------------- bool core::are_key_images_spent_in_pool(const std::vector& key_im, std::vector &spent) const diff --git a/tests/functional_tests/p2p.py b/tests/functional_tests/p2p.py index f36e9c0b1..0b33411f9 100755 --- a/tests/functional_tests/p2p.py +++ b/tests/functional_tests/p2p.py @@ -139,6 +139,25 @@ class P2PTest(): assert res.height == height + 6 assert res.top_block_hash == daemon2_top_block_hash + # disconnect and mine a lot on daemon3 + daemon2.out_peers(0) + daemon3.out_peers(0) + res = daemon3.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 500) + + # reconnect and wait for sync + daemon2.out_peers(8) + daemon3.out_peers(8) + loops = 100 + while True: + res2 = daemon2.get_info() + res3 = daemon3.get_info() + if res2.top_block_hash == res3.top_block_hash: + break + time.sleep(10) + loops -= 1 + assert loops >= 0 + + def test_p2p_tx_propagation(self): print('Testing P2P tx propagation') daemon2 = Daemon(idx = 2) -- cgit v1.2.3