aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/core_tests/chaingen.cpp6
-rwxr-xr-xtests/functional_tests/functional_tests_rpc.py3
-rwxr-xr-xtests/functional_tests/mining.py114
-rwxr-xr-xtests/functional_tests/p2p.py19
-rw-r--r--tests/unit_tests/threadpool.cpp40
5 files changed, 159 insertions, 23 deletions
diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp
index e8f070214..d1aeef488 100644
--- a/tests/core_tests/chaingen.cpp
+++ b/tests/core_tests/chaingen.cpp
@@ -409,9 +409,9 @@ void test_generator::fill_nonce(cryptonote::block& blk, const difficulty_type& d
}
blk.nonce = 0;
- while (!miner::find_nonce_for_given_block([blockchain](const cryptonote::block &b, uint64_t height, unsigned int threads, crypto::hash &hash){
- return cryptonote::get_block_longhash(blockchain, b, hash, height, threads);
- }, blk, diffic, height)) {
+ while (!miner::find_nonce_for_given_block([blockchain](const cryptonote::block &b, uint64_t height, const crypto::hash *seed_hash, unsigned int threads, crypto::hash &hash){
+ return cryptonote::get_block_longhash(blockchain, b, hash, height, seed_hash, threads);
+ }, blk, diffic, height, NULL)) {
blk.timestamp++;
}
}
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):
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)
diff --git a/tests/unit_tests/threadpool.cpp b/tests/unit_tests/threadpool.cpp
index 1307cd738..1017f04ff 100644
--- a/tests/unit_tests/threadpool.cpp
+++ b/tests/unit_tests/threadpool.cpp
@@ -34,46 +34,46 @@
TEST(threadpool, wait_nothing)
{
std::shared_ptr<tools::threadpool> tpool(tools::threadpool::getNewForUnitTests());
- tools::threadpool::waiter waiter;
- waiter.wait(tpool.get());
+ tools::threadpool::waiter waiter(*tpool);;
+ waiter.wait();
}
TEST(threadpool, wait_waits)
{
std::shared_ptr<tools::threadpool> tpool(tools::threadpool::getNewForUnitTests());
- tools::threadpool::waiter waiter;
+ tools::threadpool::waiter waiter(*tpool);
std::atomic<bool> b(false);
tpool->submit(&waiter, [&b](){ epee::misc_utils::sleep_no_w(1000); b = true; });
ASSERT_FALSE(b);
- waiter.wait(tpool.get());
+ waiter.wait();
ASSERT_TRUE(b);
}
TEST(threadpool, one_thread)
{
std::shared_ptr<tools::threadpool> tpool(tools::threadpool::getNewForUnitTests(1));
- tools::threadpool::waiter waiter;
+ tools::threadpool::waiter waiter(*tpool);
std::atomic<unsigned int> counter(0);
for (size_t n = 0; n < 4096; ++n)
{
tpool->submit(&waiter, [&counter](){++counter;});
}
- waiter.wait(tpool.get());
+ waiter.wait();
ASSERT_EQ(counter, 4096);
}
TEST(threadpool, many_threads)
{
std::shared_ptr<tools::threadpool> tpool(tools::threadpool::getNewForUnitTests(256));
- tools::threadpool::waiter waiter;
+ tools::threadpool::waiter waiter(*tpool);
std::atomic<unsigned int> counter(0);
for (size_t n = 0; n < 4096; ++n)
{
tpool->submit(&waiter, [&counter](){++counter;});
}
- waiter.wait(tpool.get());
+ waiter.wait();
ASSERT_EQ(counter, 4096);
}
@@ -82,44 +82,44 @@ static uint64_t fibonacci(std::shared_ptr<tools::threadpool> tpool, uint64_t n)
if (n <= 1)
return n;
uint64_t f1, f2;
- tools::threadpool::waiter waiter;
+ tools::threadpool::waiter waiter(*tpool);
tpool->submit(&waiter, [&tpool, &f1, n](){ f1 = fibonacci(tpool, n-1); });
tpool->submit(&waiter, [&tpool, &f2, n](){ f2 = fibonacci(tpool, n-2); });
- waiter.wait(tpool.get());
+ waiter.wait();
return f1 + f2;
}
TEST(threadpool, reentrency)
{
std::shared_ptr<tools::threadpool> tpool(tools::threadpool::getNewForUnitTests(4));
- tools::threadpool::waiter waiter;
+ tools::threadpool::waiter waiter(*tpool);
uint64_t f = fibonacci(tpool, 13);
- waiter.wait(tpool.get());
+ waiter.wait();
ASSERT_EQ(f, 233);
}
TEST(threadpool, reentrancy)
{
std::shared_ptr<tools::threadpool> tpool(tools::threadpool::getNewForUnitTests(4));
- tools::threadpool::waiter waiter;
+ tools::threadpool::waiter waiter(*tpool);
uint64_t f = fibonacci(tpool, 13);
- waiter.wait(tpool.get());
+ waiter.wait();
ASSERT_EQ(f, 233);
}
TEST(threadpool, leaf_throws)
{
std::shared_ptr<tools::threadpool> tpool(tools::threadpool::getNewForUnitTests());
- tools::threadpool::waiter waiter;
+ tools::threadpool::waiter waiter(*tpool);
bool thrown = false, executed = false;
tpool->submit(&waiter, [&](){
try { tpool->submit(&waiter, [&](){ executed = true; }); }
catch(const std::exception &e) { thrown = true; }
}, true);
- waiter.wait(tpool.get());
+ waiter.wait();
ASSERT_TRUE(thrown);
ASSERT_FALSE(executed);
}
@@ -127,20 +127,20 @@ TEST(threadpool, leaf_throws)
TEST(threadpool, leaf_reentrancy)
{
std::shared_ptr<tools::threadpool> tpool(tools::threadpool::getNewForUnitTests(4));
- tools::threadpool::waiter waiter;
+ tools::threadpool::waiter waiter(*tpool);
std::atomic<int> counter(0);
for (int i = 0; i < 1000; ++i)
{
tpool->submit(&waiter, [&](){
- tools::threadpool::waiter waiter;
+ tools::threadpool::waiter waiter(*tpool);
for (int j = 0; j < 500; ++j)
{
tpool->submit(&waiter, [&](){ ++counter; }, true);
}
- waiter.wait(tpool.get());
+ waiter.wait();
});
}
- waiter.wait(tpool.get());
+ waiter.wait();
ASSERT_EQ(counter, 500000);
}