diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/core_tests/chaingen.cpp | 6 | ||||
-rwxr-xr-x | tests/functional_tests/functional_tests_rpc.py | 3 | ||||
-rwxr-xr-x | tests/functional_tests/mining.py | 114 | ||||
-rwxr-xr-x | tests/functional_tests/p2p.py | 19 | ||||
-rw-r--r-- | tests/trezor/daemon.cpp | 2 | ||||
-rw-r--r-- | tests/trezor/trezor_tests.cpp | 40 | ||||
-rw-r--r-- | tests/unit_tests/threadpool.cpp | 40 |
7 files changed, 191 insertions, 33 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/trezor/daemon.cpp b/tests/trezor/daemon.cpp index aba835ae2..dd9fd49ee 100644 --- a/tests/trezor/daemon.cpp +++ b/tests/trezor/daemon.cpp @@ -247,7 +247,7 @@ bool mock_daemon::run_main() if (m_start_zmq) { - if (!zmq_server.addTCPSocket("127.0.0.1", m_zmq_bind_port)) + if (!zmq_server.init_rpc("127.0.0.1", m_zmq_bind_port)) { MERROR("Failed to add TCP Socket (127.0.0.1:" << m_zmq_bind_port << ") to ZMQ RPC Server"); diff --git a/tests/trezor/trezor_tests.cpp b/tests/trezor/trezor_tests.cpp index 6a92868cf..972a588f3 100644 --- a/tests/trezor/trezor_tests.cpp +++ b/tests/trezor/trezor_tests.cpp @@ -139,7 +139,7 @@ int main(int argc, char* argv[]) // Bootstrapping common chain & accounts const uint8_t initial_hf = (uint8_t)get_env_long("TEST_MIN_HF", 12); - const uint8_t max_hf = (uint8_t)get_env_long("TEST_MAX_HF", 12); + const uint8_t max_hf = (uint8_t)get_env_long("TEST_MAX_HF", HF_VERSION_CLSAG); auto sync_test = get_env_long("TEST_KI_SYNC", 1); MINFO("Test versions " << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")"); MINFO("Testing hardforks [" << (int)initial_hf << ", " << (int)max_hf << "], sync-test: " << sync_test); @@ -546,7 +546,7 @@ static void expand_tsx(cryptonote::transaction &tx) for (size_t n = 0; n < tx.vin.size(); ++n) rv.p.MGs[0].II[n] = rct::ki2rct(boost::get<txin_to_key>(tx.vin[n]).k_image); } - else if (rv.type == rct::RCTTypeSimple || rv.type == rct::RCTTypeBulletproof || rv.type == rct::RCTTypeBulletproof2 || rv.type == rct::RCTTypeCLSAG) + else if (rv.type == rct::RCTTypeSimple || rv.type == rct::RCTTypeBulletproof || rv.type == rct::RCTTypeBulletproof2) { CHECK_AND_ASSERT_THROW_MES(rv.p.MGs.size() == tx.vin.size(), "Bad MGs size"); for (size_t n = 0; n < tx.vin.size(); ++n) @@ -555,6 +555,21 @@ static void expand_tsx(cryptonote::transaction &tx) rv.p.MGs[n].II[0] = rct::ki2rct(boost::get<txin_to_key>(tx.vin[n]).k_image); } } + else if (rv.type == rct::RCTTypeCLSAG) + { + if (!tx.pruned) + { + CHECK_AND_ASSERT_THROW_MES(rv.p.CLSAGs.size() == tx.vin.size(), "Bad CLSAGs size"); + for (size_t n = 0; n < tx.vin.size(); ++n) + { + rv.p.CLSAGs[n].I = rct::ki2rct(boost::get<txin_to_key>(tx.vin[n]).k_image); + } + } + } + else + { + CHECK_AND_ASSERT_THROW_MES(false, "Unsupported rct tx type: " + boost::lexical_cast<std::string>(rv.type)); + } } static std::vector<tools::wallet2*> vct_wallets(tools::wallet2* w1=nullptr, tools::wallet2* w2=nullptr, tools::wallet2* w3=nullptr, tools::wallet2* w4=nullptr, tools::wallet2* w5=nullptr) @@ -708,7 +723,9 @@ bool gen_trezor_base::generate(std::vector<test_event_entry>& events) std::vector<size_t> block_weights; generate_genesis_block(blk_gen, get_config(m_network_type).GENESIS_TX, get_config(m_network_type).GENESIS_NONCE); events.push_back(blk_gen); - generator.add_block(blk_gen, 0, block_weights, 0); + uint64_t rew = 0; + cryptonote::get_block_reward(0, get_transaction_weight(blk_gen.miner_tx), 0, rew, 1); + generator.add_block(blk_gen, 0, block_weights, 0, rew); // First event has to be the genesis block m_bob_account.generate(); @@ -926,7 +943,7 @@ void gen_trezor_base::fix_hf(std::vector<test_event_entry>& events) // If current test requires higher hard-fork, move it up auto current_hf = m_hard_forks.back().first; CHECK_AND_ASSERT_THROW_MES(current_hf <= m_top_hard_fork, "Generated chain hardfork is higher than desired maximum"); - CHECK_AND_ASSERT_THROW_MES(m_rct_config.bp_version != 2 || m_top_hard_fork >= 10, "Desired maximum is too low for BPv2"); + CHECK_AND_ASSERT_THROW_MES(m_rct_config.bp_version < 2 || m_top_hard_fork >= 10, "Desired maximum is too low for BPv2"); for(;current_hf < m_top_hard_fork; current_hf+=1) { @@ -1014,9 +1031,10 @@ void gen_trezor_base::test_trezor_tx(std::vector<test_event_entry>& events, std: setup_shim(&wallet_shim); aux_data.tx_recipients = dsts_info; aux_data.bp_version = m_rct_config.bp_version; + aux_data.hard_fork = m_top_hard_fork; dev_cold->tx_sign(&wallet_shim, txs, exported_txs, aux_data); - MDEBUG("Signed tx data from hw: " << exported_txs.ptx.size() << " transactions"); + MDEBUG("Signed tx data from hw: " << exported_txs.ptx.size() << " transactions, hf: " << (int)m_top_hard_fork << ", bpv: " << m_rct_config.bp_version); CHECK_AND_ASSERT_THROW_MES(exported_txs.ptx.size() == ptxs.size(), "Invalid transaction sizes"); for (size_t i = 0; i < exported_txs.ptx.size(); ++i){ @@ -1245,10 +1263,14 @@ void gen_trezor_base::set_hard_fork(uint8_t hf) m_top_hard_fork = hf; if (hf < 9){ throw std::runtime_error("Minimal supported Hardfork is 9"); - } else if (hf == 9){ + } else if (hf <= 11){ rct_config({rct::RangeProofPaddedBulletproof, 1}); - } else { + } else if (hf == 12){ rct_config({rct::RangeProofPaddedBulletproof, 2}); + } else if (hf == HF_VERSION_CLSAG){ + rct_config({rct::RangeProofPaddedBulletproof, 3}); + } else { + throw std::runtime_error("Unsupported HF"); } } @@ -1844,7 +1866,7 @@ bool wallet_api_tests::generate(std::vector<test_event_entry>& events) CHECK_AND_ASSERT_THROW_MES(w->refresh(), "Refresh fail"); uint64_t balance = w->balance(0); MDEBUG("Balance: " << balance); - CHECK_AND_ASSERT_THROW_MES(w->status() == Monero::PendingTransaction::Status_Ok, "Status nok"); + CHECK_AND_ASSERT_THROW_MES(w->status() == Monero::PendingTransaction::Status_Ok, "Status nok, " << w->errorString()); auto addr = get_address(m_eve_account); auto recepient_address = cryptonote::get_account_address_as_str(m_network_type, false, addr); @@ -1855,7 +1877,7 @@ bool wallet_api_tests::generate(std::vector<test_event_entry>& events) Monero::PendingTransaction::Priority_Medium, 0, std::set<uint32_t>{}); - CHECK_AND_ASSERT_THROW_MES(transaction->status() == Monero::PendingTransaction::Status_Ok, "Status nok"); + CHECK_AND_ASSERT_THROW_MES(transaction->status() == Monero::PendingTransaction::Status_Ok, "Status nok: " << transaction->status() << ", msg: " << transaction->errorString()); w->refresh(); CHECK_AND_ASSERT_THROW_MES(w->balance(0) == balance, "Err"); 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); } |