diff --git a/unittests/block_tests.cpp b/unittests/block_tests.cpp index aa9733a15c..48e962e763 100644 --- a/unittests/block_tests.cpp +++ b/unittests/block_tests.cpp @@ -7,9 +7,9 @@ using namespace chain; BOOST_AUTO_TEST_SUITE(block_tests) -BOOST_AUTO_TEST_CASE(block_with_invalid_tx_test) +BOOST_AUTO_TEST_CASE_TEMPLATE( block_with_invalid_tx_test, T, testers ) { - tester main; + T main; // First we create a valid block with valid transaction main.create_account("newacc"_n); @@ -19,7 +19,7 @@ BOOST_AUTO_TEST_CASE(block_with_invalid_tx_test) auto copy_b = std::make_shared(std::move(*b)); auto signed_tx = std::get(copy_b->transactions.back().trx).get_signed_transaction(); auto& act = signed_tx.actions.back(); - auto act_data = act.data_as(); + auto act_data = act.template data_as(); // Make the transaction invalid by having the new account name the same as the creator name act_data.name = act_data.creator; act.data = fc::raw::pack(act_data); @@ -35,15 +35,23 @@ BOOST_AUTO_TEST_CASE(block_with_invalid_tx_test) const auto& trxs = copy_b->transactions; for( const auto& a : trxs ) trx_digests.emplace_back( a.digest() ); - copy_b->transaction_mroot = calculate_merkle_legacy( std::move(trx_digests) ); + if constexpr (std::is_same_v) { + copy_b->transaction_mroot = calculate_merkle( std::move(trx_digests) ); + } else { + copy_b->transaction_mroot = calculate_merkle_legacy( std::move(trx_digests) ); + } // Re-sign the block - auto header_bmroot = digest_type::hash( std::make_pair( copy_b->digest(), main.control->head_block_state_legacy()->blockroot_merkle.get_root() ) ); - auto sig_digest = digest_type::hash( std::make_pair(header_bmroot, main.control->head_block_state_legacy()->pending_schedule.schedule_hash) ); - copy_b->producer_signature = main.get_private_key(config::system_account_name, "active").sign(sig_digest); + if constexpr (std::is_same_v) { + copy_b->producer_signature = main.get_private_key(config::system_account_name, "active").sign(copy_b->calculate_id()); + } else { + auto header_bmroot = digest_type::hash( std::make_pair( copy_b->digest(), main.control->head_block_state_legacy()->blockroot_merkle.get_root() ) ); + auto sig_digest = digest_type::hash( std::make_pair(header_bmroot, main.control->head_block_state_legacy()->pending_schedule.schedule_hash) ); + copy_b->producer_signature = main.get_private_key(config::system_account_name, "active").sign(sig_digest); + } // Push block with invalid transaction to other chain - tester validator; + T validator; auto btf = validator.control->create_block_handle_future( copy_b->calculate_id(), copy_b ); validator.control->abort_block(); controller::block_report br; @@ -54,9 +62,9 @@ BOOST_AUTO_TEST_CASE(block_with_invalid_tx_test) } -BOOST_AUTO_TEST_CASE(block_with_invalid_tx_mroot_test) +BOOST_AUTO_TEST_CASE_TEMPLATE( block_with_invalid_tx_mroot_test, T, testers ) { - tester main; + T main; // First we create a valid block with valid transaction main.create_account("newacc"_n); @@ -77,12 +85,16 @@ BOOST_AUTO_TEST_CASE(block_with_invalid_tx_mroot_test) copy_b->transactions.back().trx = std::move(invalid_packed_tx); // Re-sign the block - auto header_bmroot = digest_type::hash( std::make_pair( copy_b->digest(), main.control->head_block_state_legacy()->blockroot_merkle.get_root() ) ); - auto sig_digest = digest_type::hash( std::make_pair(header_bmroot, main.control->head_block_state_legacy()->pending_schedule.schedule_hash) ); - copy_b->producer_signature = main.get_private_key(config::system_account_name, "active").sign(sig_digest); + if constexpr (std::is_same_v) { + copy_b->producer_signature = main.get_private_key(config::system_account_name, "active").sign(copy_b->calculate_id()); + } else { + auto header_bmroot = digest_type::hash( std::make_pair( copy_b->digest(), main.control->head_block_state_legacy()->blockroot_merkle.get_root() ) ); + auto sig_digest = digest_type::hash( std::make_pair(header_bmroot, main.control->head_block_state_legacy()->pending_schedule.schedule_hash) ); + copy_b->producer_signature = main.get_private_key(config::system_account_name, "active").sign(sig_digest); + } // Push block with invalid transaction to other chain - tester validator; + T validator; auto btf = validator.control->create_block_handle_future( copy_b->calculate_id(), copy_b ); validator.control->abort_block(); controller::block_report br; @@ -93,6 +105,7 @@ BOOST_AUTO_TEST_CASE(block_with_invalid_tx_mroot_test) }) ; } +template std::pair corrupt_trx_in_block(validating_tester& main, account_name act_name) { // First we create a valid block with valid transaction main.create_account(act_name); @@ -115,20 +128,29 @@ std::pair corrupt_trx_in_block(validating_te const auto& trxs = copy_b->transactions; for( const auto& a : trxs ) trx_digests.emplace_back( a.digest() ); - copy_b->transaction_mroot = calculate_merkle_legacy( std::move(trx_digests) ); + if constexpr (std::is_same_v) { + copy_b->transaction_mroot = calculate_merkle( std::move(trx_digests) ); + } else { + copy_b->transaction_mroot = calculate_merkle_legacy( std::move(trx_digests) ); + } // Re-sign the block - auto header_bmroot = digest_type::hash( std::make_pair( copy_b->digest(), main.control->head_block_state_legacy()->blockroot_merkle.get_root() ) ); - auto sig_digest = digest_type::hash( std::make_pair(header_bmroot, main.control->head_block_state_legacy()->pending_schedule.schedule_hash) ); - copy_b->producer_signature = main.get_private_key(b->producer, "active").sign(sig_digest); + if constexpr (std::is_same_v) { + copy_b->producer_signature = main.get_private_key(b->producer, "active").sign(copy_b->calculate_id()); + } else { + auto header_bmroot = digest_type::hash( std::make_pair( copy_b->digest(), main.control->head_block_state_legacy()->blockroot_merkle.get_root() ) ); + auto sig_digest = digest_type::hash( std::make_pair(header_bmroot, main.control->head_block_state_legacy()->pending_schedule.schedule_hash) ); + copy_b->producer_signature = main.get_private_key(b->producer, "active").sign(sig_digest); + } + return std::pair(b, copy_b); } // verify that a block with a transaction with an incorrect signature, is blindly accepted from a trusted producer -BOOST_AUTO_TEST_CASE(trusted_producer_test) +BOOST_AUTO_TEST_CASE_TEMPLATE( trusted_producer_test, T, validating_testers ) { flat_set trusted_producers = { "defproducera"_n, "defproducerc"_n }; - validating_tester main(trusted_producers); + T main(trusted_producers); // only using validating_tester to keep the 2 chains in sync, not to validate that the validating_node matches the main node, // since it won't be main.skip_validate = true; @@ -146,15 +168,15 @@ BOOST_AUTO_TEST_CASE(trusted_producer_test) b = main.produce_block(); } - auto blocks = corrupt_trx_in_block(main, "tstproducera"_n); + auto blocks = corrupt_trx_in_block(main, "tstproducera"_n); main.validate_push_block( blocks.second ); } // like trusted_producer_test, except verify that any entry in the trusted_producer list is accepted -BOOST_AUTO_TEST_CASE(trusted_producer_verify_2nd_test) +BOOST_AUTO_TEST_CASE_TEMPLATE( trusted_producer_verify_2nd_test, T, validating_testers ) { flat_set trusted_producers = { "defproducera"_n, "defproducerc"_n }; - validating_tester main(trusted_producers); + T main(trusted_producers); // only using validating_tester to keep the 2 chains in sync, not to validate that the validating_node matches the main node, // since it won't be main.skip_validate = true; @@ -172,15 +194,15 @@ BOOST_AUTO_TEST_CASE(trusted_producer_verify_2nd_test) b = main.produce_block(); } - auto blocks = corrupt_trx_in_block(main, "tstproducera"_n); + auto blocks = corrupt_trx_in_block(main, "tstproducera"_n); main.validate_push_block( blocks.second ); } // verify that a block with a transaction with an incorrect signature, is rejected if it is not from a trusted producer -BOOST_AUTO_TEST_CASE(untrusted_producer_test) +BOOST_AUTO_TEST_CASE_TEMPLATE( untrusted_producer_test, T, validating_testers ) { flat_set trusted_producers = { "defproducera"_n, "defproducerc"_n }; - validating_tester main(trusted_producers); + T main(trusted_producers); // only using validating_tester to keep the 2 chains in sync, not to validate that the validating_node matches the main node, // since it won't be main.skip_validate = true; @@ -198,7 +220,7 @@ BOOST_AUTO_TEST_CASE(untrusted_producer_test) b = main.produce_block(); } - auto blocks = corrupt_trx_in_block(main, "tstproducera"_n); + auto blocks = corrupt_trx_in_block(main, "tstproducera"_n); BOOST_REQUIRE_EXCEPTION(main.validate_push_block( blocks.second ), fc::exception , [] (const fc::exception &e)->bool { return e.code() == unsatisfied_authorization::code_value ; @@ -208,11 +230,11 @@ BOOST_AUTO_TEST_CASE(untrusted_producer_test) /** * Ensure that the block broadcasted by producing node and receiving node is identical */ -BOOST_AUTO_TEST_CASE(broadcasted_block_test) +BOOST_AUTO_TEST_CASE_TEMPLATE( broadcasted_block_test, T, testers ) { - tester producer_node; - tester receiving_node; + T producer_node; + T receiving_node; signed_block_ptr bcasted_blk_by_prod_node; signed_block_ptr bcasted_blk_by_recv_node; diff --git a/unittests/chain_tests.cpp b/unittests/chain_tests.cpp index dc6a63914c..fea86efa53 100644 --- a/unittests/chain_tests.cpp +++ b/unittests/chain_tests.cpp @@ -40,7 +40,7 @@ BOOST_AUTO_TEST_CASE( replace_producer_keys ) try { BOOST_REQUIRE(old_version == pending_version); BOOST_REQUIRE(pending_version == old_pending_version); - const auto& gpo = tester.control->db().get(); + const auto& gpo = tester.control->db().template get(); BOOST_REQUIRE(!gpo.proposed_schedule_block_num); BOOST_REQUIRE(gpo.proposed_schedule.version == 0); BOOST_REQUIRE(gpo.proposed_schedule.producers.empty()); @@ -57,12 +57,12 @@ BOOST_AUTO_TEST_CASE( replace_producer_keys ) try { } } FC_LOG_AND_RETHROW() -BOOST_AUTO_TEST_CASE( replace_account_keys ) try { - validating_tester tester; +BOOST_AUTO_TEST_CASE_TEMPLATE( replace_account_keys, T, validating_testers ) try { + T tester; const name usr = config::system_account_name; const name active_permission = config::active_name; const auto& rlm = tester.control->get_resource_limits_manager(); - const auto* perm = tester.control->db().find(boost::make_tuple(usr, active_permission)); + const auto* perm = tester.control->db().template find(boost::make_tuple(usr, active_permission)); BOOST_REQUIRE(perm != NULL); const int64_t old_size = (int64_t)(chain::config::billable_size_v + perm->auth.get_billable_size()); @@ -81,8 +81,8 @@ BOOST_AUTO_TEST_CASE( replace_account_keys ) try { } FC_LOG_AND_RETHROW() -BOOST_AUTO_TEST_CASE( decompressed_size_over_limit ) try { - tester chain; +BOOST_AUTO_TEST_CASE_TEMPLATE( decompressed_size_over_limit, T, testers ) try { + T chain; // build a transaction, add cf data, sign cf_action cfa; @@ -116,8 +116,8 @@ BOOST_AUTO_TEST_CASE( decompressed_size_over_limit ) try { }); } FC_LOG_AND_RETHROW() -BOOST_AUTO_TEST_CASE( decompressed_size_under_limit ) try { - tester chain; +BOOST_AUTO_TEST_CASE_TEMPLATE( decompressed_size_under_limit, T, testers ) try { + T chain; // build a transaction, add cf data, sign cf_action cfa; @@ -150,9 +150,9 @@ BOOST_AUTO_TEST_CASE( decompressed_size_under_limit ) try { } FC_LOG_AND_RETHROW() // verify accepted_block signals validated blocks -BOOST_AUTO_TEST_CASE( signal_validated_blocks ) try { - tester chain; - tester validator; +BOOST_AUTO_TEST_CASE_TEMPLATE( signal_validated_blocks, T, testers ) try { + T chain; + T validator; signed_block_ptr accepted_block; block_id_type accepted_id; diff --git a/unittests/database_tests.cpp b/unittests/database_tests.cpp index 1f0ba01ca7..b28a557b4c 100644 --- a/unittests/database_tests.cpp +++ b/unittests/database_tests.cpp @@ -11,9 +11,9 @@ using namespace eosio::testing; BOOST_AUTO_TEST_SUITE(database_tests) // Simple tests of undo infrastructure - BOOST_AUTO_TEST_CASE(undo_test) { + BOOST_AUTO_TEST_CASE_TEMPLATE( undo_test, T, validating_testers ) { try { - validating_tester test; + T test; // Bypass read-only restriction on state DB access for this unit test which really needs to mutate the DB to properly conduct its test. eosio::chain::database& db = const_cast( test.control->db() ); @@ -39,9 +39,9 @@ BOOST_AUTO_TEST_SUITE(database_tests) } // Test the block fetching methods on database, fetch_bock_by_id, and fetch_block_by_number - BOOST_AUTO_TEST_CASE(get_blocks) { + BOOST_AUTO_TEST_CASE_TEMPLATE( get_blocks, T, validating_testers ) { try { - validating_tester test; + T test; vector block_ids; const uint32_t num_of_blocks_to_prod = 200; diff --git a/unittests/restart_chain_tests.cpp b/unittests/restart_chain_tests.cpp index fbd845a164..915e37e429 100644 --- a/unittests/restart_chain_tests.cpp +++ b/unittests/restart_chain_tests.cpp @@ -54,10 +54,14 @@ FC_REFLECT(cf_action, (payload)(cfd_idx)) #define DUMMY_ACTION_DEFAULT_B 0xab11cd1244556677 #define DUMMY_ACTION_DEFAULT_C 0x7451ae12 +template class replay_tester : public base_tester { public: template replay_tester(controller::config config, const genesis_state& genesis, OnAppliedTrx&& on_applied_trx) { + if constexpr (std::is_same_v) { + is_savanna = true; + } cfg = config; base_tester::open(make_protocol_feature_set(), genesis.compute_chain_id(), [&genesis,&control=this->control, &on_applied_trx]() { control->applied_transaction().connect(on_applied_trx); @@ -86,15 +90,15 @@ class replay_tester : public base_tester { BOOST_AUTO_TEST_SUITE(restart_chain_tests) -BOOST_AUTO_TEST_CASE(test_existing_state_without_block_log) { - tester chain; +BOOST_AUTO_TEST_CASE_TEMPLATE( test_existing_state_without_block_log, T, testers ) { + T chain; std::vector blocks; blocks.push_back(chain.produce_block()); blocks.push_back(chain.produce_block()); blocks.push_back(chain.produce_block()); - tester other; + T other; for (const auto& new_block : blocks) { other.push_block(new_block); } @@ -116,15 +120,15 @@ BOOST_AUTO_TEST_CASE(test_existing_state_without_block_log) { } } -BOOST_AUTO_TEST_CASE(test_restart_with_different_chain_id) { - tester chain; +BOOST_AUTO_TEST_CASE_TEMPLATE( test_restart_with_different_chain_id, T, testers ) { + T chain; std::vector blocks; blocks.push_back(chain.produce_block()); blocks.push_back(chain.produce_block()); blocks.push_back(chain.produce_block()); - tester other; + T other; for (const auto& new_block : blocks) { other.push_block(new_block); } @@ -139,8 +143,8 @@ BOOST_AUTO_TEST_CASE(test_restart_with_different_chain_id) { fc_exception_message_starts_with("chain ID in state ")); } -BOOST_AUTO_TEST_CASE(test_restart_from_block_log) { - tester chain; +BOOST_AUTO_TEST_CASE_TEMPLATE( test_restart_from_block_log, T, testers ) { + T chain; chain.create_account("replay1"_n); chain.produce_blocks(1); @@ -169,8 +173,8 @@ BOOST_AUTO_TEST_CASE(test_restart_from_block_log) { BOOST_REQUIRE_NO_THROW(from_block_log_chain.control->get_account("replay3"_n)); } -BOOST_AUTO_TEST_CASE(test_light_validation_restart_from_block_log) { - tester chain(setup_policy::full); +BOOST_AUTO_TEST_CASE_TEMPLATE( test_light_validation_restart_from_block_log, T, testers ) { + T chain(setup_policy::full); chain.create_account("testapi"_n); chain.create_account("dummy"_n); @@ -214,7 +218,7 @@ BOOST_AUTO_TEST_CASE(test_light_validation_restart_from_block_log) { remove_existing_states(copied_config); transaction_trace_ptr other_trace; - replay_tester from_block_log_chain(copied_config, *genesis, + replay_tester from_block_log_chain(copied_config, *genesis, [&](std::tuple x) { auto& t = std::get<0>(x); if (t && t->id == trace->id) { @@ -232,7 +236,9 @@ BOOST_AUTO_TEST_CASE(test_light_validation_restart_from_block_log) { auto check_action_traces = [](const auto& t, const auto& ot) { BOOST_CHECK_EQUAL("", ot.console); // cfa not executed for replay BOOST_CHECK_EQUAL(t.receipt->global_sequence, ot.receipt->global_sequence); - BOOST_CHECK_EQUAL(t.digest_legacy(), ot.digest_legacy()); // digest_legacy because test doesn't switch to Savanna + // both legacy and savanna digests should be the same + BOOST_CHECK_EQUAL(t.digest_legacy(), ot.digest_legacy()); + BOOST_CHECK_EQUAL(t.digest_savanna(), ot.digest_savanna()); }; BOOST_CHECK(other_trace->action_traces.at(0).context_free); // cfa