diff --git a/libraries/testing/include/eosio/testing/tester.hpp b/libraries/testing/include/eosio/testing/tester.hpp index 3ad61e8c96..e9279ee704 100644 --- a/libraries/testing/include/eosio/testing/tester.hpp +++ b/libraries/testing/include/eosio/testing/tester.hpp @@ -618,6 +618,14 @@ namespace eosio::testing { }; + class savanna_tester : public tester { + public: + savanna_tester(); + }; + + using legacy_tester = tester; + using testers = boost::mpl::list; + class tester_no_disable_deferred_trx : public tester { public: tester_no_disable_deferred_trx(): tester(setup_policy::full_except_do_not_disable_deferred_trx) { @@ -757,6 +765,14 @@ namespace eosio::testing { } }; + class savanna_validating_tester : public validating_tester { + public: + savanna_validating_tester(); + }; + + using legacy_validating_tester = validating_tester; + using validating_testers = boost::mpl::list; + // ------------------------------------------------------------------------------------- // creates and manages a set of `bls_public_key` used for finalizers voting and policies // Supports initial transition to Savanna. @@ -865,6 +881,12 @@ namespace eosio::testing { return finalizer_policy{}.apply_diff(*fin_policy_diff); } + void activate_savanna(size_t first_key_idx) { + set_node_finalizers(first_key_idx, pubkeys.size()); + set_finalizer_policy(first_key_idx); + transition_to_savanna(); + } + Tester& t; vector key_names; vector pubkeys; diff --git a/libraries/testing/tester.cpp b/libraries/testing/tester.cpp index 2f3cd42636..6cc9527e42 100644 --- a/libraries/testing/tester.cpp +++ b/libraries/testing/tester.cpp @@ -1396,6 +1396,12 @@ namespace eosio::testing { execute_setup_policy(policy); } + savanna_tester::savanna_tester() { + // Activate Savanna consensus + finalizer_keys fin_keys(*this, 4u /* num_keys */, 4u /* finset_size */); + fin_keys.activate_savanna(0u /* first_key_idx */); + } + unique_ptr validating_tester::create_validating_node(controller::config vcfg, const genesis_state& genesis, bool use_genesis, deep_mind_handler* dmlog) { unique_ptr validating_node = std::make_unique(vcfg, make_protocol_feature_set(), genesis.compute_chain_id()); validating_node->add_indices(); @@ -1413,6 +1419,12 @@ namespace eosio::testing { return validating_node; } + savanna_validating_tester::savanna_validating_tester() { + // Activate Savanna consensus + finalizer_keys fin_keys(*this, 4u /* num_keys */, 4u /* finset_size */); + fin_keys.activate_savanna(0u /* first_key_idx */); + } + bool fc_exception_message_is::operator()( const fc::exception& ex ) { auto message = ex.get_log().at( 0 ).get_message(); bool match = (message == expected); diff --git a/unittests/auth_tests.cpp b/unittests/auth_tests.cpp index 02fa619866..74296c1f4a 100644 --- a/unittests/auth_tests.cpp +++ b/unittests/auth_tests.cpp @@ -17,37 +17,43 @@ using namespace eosio::testing; BOOST_AUTO_TEST_SUITE(auth_tests) -BOOST_FIXTURE_TEST_CASE( missing_sigs, validating_tester ) { try { - create_accounts( {"alice"_n} ); - produce_block(); +BOOST_AUTO_TEST_CASE_TEMPLATE( missing_sigs, TESTER, validating_testers ) { try { + TESTER chain; - BOOST_REQUIRE_THROW( push_reqauth( "alice"_n, {permission_level{"alice"_n, config::active_name}}, {} ), unsatisfied_authorization ); - auto trace = push_reqauth("alice"_n, "owner"); + chain.create_accounts( {"alice"_n} ); + chain.produce_block(); + + BOOST_REQUIRE_THROW( chain.push_reqauth( "alice"_n, {permission_level{"alice"_n, config::active_name}}, {} ), unsatisfied_authorization ); + auto trace = chain.push_reqauth("alice"_n, "owner"); - produce_block(); - BOOST_REQUIRE_EQUAL(true, chain_has_transaction(trace->id)); + chain.produce_block(); + BOOST_REQUIRE_EQUAL(true, chain.chain_has_transaction(trace->id)); } FC_LOG_AND_RETHROW() } /// missing_sigs -BOOST_FIXTURE_TEST_CASE( missing_multi_sigs, validating_tester ) { try { - produce_block(); - create_account("alice"_n, config::system_account_name, true); - produce_block(); +BOOST_AUTO_TEST_CASE_TEMPLATE( missing_multi_sigs, TESTER, validating_testers ) { try { + TESTER chain; + + chain.produce_block(); + chain.create_account("alice"_n, config::system_account_name, true); + chain.produce_block(); - BOOST_REQUIRE_THROW(push_reqauth("alice"_n, "owner"), unsatisfied_authorization); // without multisig - auto trace = push_reqauth("alice"_n, "owner", true); // with multisig + BOOST_REQUIRE_THROW(chain.push_reqauth("alice"_n, "owner"), unsatisfied_authorization); // without multisig + auto trace = chain.push_reqauth("alice"_n, "owner", true); // with multisig - produce_block(); - BOOST_REQUIRE_EQUAL(true, chain_has_transaction(trace->id)); + chain.produce_block(); + BOOST_REQUIRE_EQUAL(true, chain.chain_has_transaction(trace->id)); } FC_LOG_AND_RETHROW() } /// missing_multi_sigs -BOOST_FIXTURE_TEST_CASE( missing_auths, validating_tester ) { try { - create_accounts( {"alice"_n, "bob"_n} ); - produce_block(); +BOOST_AUTO_TEST_CASE_TEMPLATE( missing_auths, TESTER, validating_testers ) { try { + TESTER chain; + + chain.create_accounts( {"alice"_n, "bob"_n} ); + chain.produce_block(); /// action not provided from authority - BOOST_REQUIRE_THROW( push_reqauth( "alice"_n, {permission_level{"bob"_n, config::active_name}}, { get_private_key("bob"_n, "active") } ), missing_auth_exception); + BOOST_REQUIRE_THROW( chain.push_reqauth( "alice"_n, {permission_level{"bob"_n, config::active_name}}, { chain.get_private_key("bob"_n, "active") } ), missing_auth_exception); } FC_LOG_AND_RETHROW() } /// transfer_test @@ -55,43 +61,45 @@ BOOST_FIXTURE_TEST_CASE( missing_auths, validating_tester ) { try { * This test case will attempt to allow one account to transfer on behalf * of another account by updating the active authority. */ -BOOST_FIXTURE_TEST_CASE( delegate_auth, validating_tester ) { try { - create_accounts( {"alice"_n,"bob"_n}); - produce_block(); +BOOST_AUTO_TEST_CASE_TEMPLATE( delegate_auth, TESTER, validating_testers ) { try { + TESTER chain; + + chain.create_accounts( {"alice"_n,"bob"_n}); + chain.produce_block(); auto delegated_auth = authority( 1, {}, { { .permission = {"bob"_n,config::active_name}, .weight = 1} }); - auto original_auth = control->get_authorization_manager().get_permission({"alice"_n, config::active_name}).auth.to_authority(); + auto original_auth = chain.control->get_authorization_manager().get_permission({"alice"_n, config::active_name}).auth.to_authority(); wdump((original_auth)); - set_authority( "alice"_n, config::active_name, delegated_auth ); + chain.set_authority( "alice"_n, config::active_name, delegated_auth ); - auto new_auth = control->get_authorization_manager().get_permission({"alice"_n, config::active_name}).auth.to_authority(); + auto new_auth = chain.control->get_authorization_manager().get_permission({"alice"_n, config::active_name}).auth.to_authority(); wdump((new_auth)); BOOST_CHECK_EQUAL((new_auth == delegated_auth), true); - produce_block(); - produce_block(); + chain.produce_block(); + chain.produce_block(); - auto auth = control->get_authorization_manager().get_permission({"alice"_n, config::active_name}).auth.to_authority(); + auto auth = chain.control->get_authorization_manager().get_permission({"alice"_n, config::active_name}).auth.to_authority(); wdump((auth)); BOOST_CHECK_EQUAL((new_auth == auth), true); /// execute nonce from alice signed by bob - auto trace = push_reqauth("alice"_n, {permission_level{"alice"_n, config::active_name}}, { get_private_key("bob"_n, "active") } ); + auto trace = chain.push_reqauth("alice"_n, {permission_level{"alice"_n, config::active_name}}, { chain.get_private_key("bob"_n, "active") } ); - produce_block(); + chain.produce_block(); //todoBOOST_REQUIRE_EQUAL(true, chain_has_transaction(trace->id)); } FC_LOG_AND_RETHROW() } -BOOST_AUTO_TEST_CASE(update_auths) { -try { - validating_tester chain; +BOOST_AUTO_TEST_CASE_TEMPLATE( update_auths, TESTER, validating_testers ) { try { + TESTER chain; + chain.create_account(name("alice")); chain.create_account(name("bob")); @@ -108,7 +116,7 @@ try { // Ensure the permission is updated permission_object::id_type owner_id; { - auto obj = chain.find(boost::make_tuple(name("alice"), name("owner"))); + auto obj = chain.template find(boost::make_tuple(name("alice"), name("owner"))); BOOST_TEST(obj != nullptr); BOOST_TEST(obj->owner == name("alice")); BOOST_TEST(obj->name == name("owner")); @@ -131,7 +139,7 @@ try { chain.produce_blocks(); { - auto obj = chain.find(boost::make_tuple(name("alice"), name("active"))); + auto obj = chain.template find(boost::make_tuple(name("alice"), name("active"))); BOOST_TEST(obj != nullptr); BOOST_TEST(obj->owner == name("alice")); BOOST_TEST(obj->name == name("active")); @@ -160,12 +168,12 @@ try { { permission_level{name("alice"), name("active")} }, { new_active_priv_key }); chain.produce_blocks(); { - auto obj = chain.find(boost::make_tuple(name("alice"), name("spending"))); + auto obj = chain.template find(boost::make_tuple(name("alice"), name("spending"))); BOOST_TEST(obj != nullptr); BOOST_TEST(obj->owner == name("alice")); BOOST_TEST(obj->name == name("spending")); - BOOST_TEST(chain.get(obj->parent).owner == name("alice")); - BOOST_TEST(chain.get(obj->parent).name == name("active")); + BOOST_TEST(chain.template get(obj->parent).owner == name("alice")); + BOOST_TEST(chain.template get(obj->parent).name == name("active")); } // Update spending auth parent to be its own, should fail @@ -178,7 +186,7 @@ try { // Remove spending auth chain.delete_authority(name("alice"), name("spending"), { permission_level{name("alice"), name("active")} }, { new_active_priv_key }); { - auto obj = chain.find(boost::make_tuple(name("alice"), name("spending"))); + auto obj = chain.template find(boost::make_tuple(name("alice"), name("spending"))); BOOST_TEST(obj == nullptr); } chain.produce_blocks(); @@ -193,8 +201,8 @@ try { // Verify correctness of trading and spending { - const auto* trading = chain.find(boost::make_tuple(name("alice"), name("trading"))); - const auto* spending = chain.find(boost::make_tuple(name("alice"), name("spending"))); + const auto* trading = chain.template find(boost::make_tuple(name("alice"), name("trading"))); + const auto* spending = chain.template find(boost::make_tuple(name("alice"), name("spending"))); BOOST_TEST(trading != nullptr); BOOST_TEST(spending != nullptr); BOOST_TEST(trading->owner == name("alice")); @@ -202,8 +210,8 @@ try { BOOST_TEST(trading->name == name("trading")); BOOST_TEST(spending->name == name("spending")); BOOST_TEST(spending->parent == trading->id); - BOOST_TEST(chain.get(trading->parent).owner == name("alice")); - BOOST_TEST(chain.get(trading->parent).name == name("active")); + BOOST_TEST(chain.template get(trading->parent).owner == name("alice")); + BOOST_TEST(chain.template get(trading->parent).name == name("active")); } @@ -216,16 +224,15 @@ try { // Delete spending auth chain.delete_authority(name("alice"), name("spending"), { permission_level{name("alice"), name("active")} }, { new_active_priv_key }); - BOOST_TEST((chain.find(boost::make_tuple(name("alice"), name("spending")))) == nullptr); + BOOST_TEST((chain.template find(boost::make_tuple(name("alice"), name("spending")))) == nullptr); // Delete trading auth, now it should succeed since it doesn't have any children anymore chain.delete_authority(name("alice"), name("trading"), { permission_level{name("alice"), name("active")} }, { new_active_priv_key }); - BOOST_TEST((chain.find(boost::make_tuple(name("alice"), name("trading")))) == nullptr); + BOOST_TEST((chain.template find(boost::make_tuple(name("alice"), name("trading")))) == nullptr); } FC_LOG_AND_RETHROW() } -BOOST_AUTO_TEST_CASE(update_auth_unknown_private_key) { - try { - validating_tester chain; +BOOST_AUTO_TEST_CASE_TEMPLATE( update_auth_unknown_private_key, TESTER, validating_testers ) { try { + TESTER chain; chain.create_account(name("alice")); // public key with no corresponding private key @@ -242,7 +249,7 @@ BOOST_AUTO_TEST_CASE(update_auth_unknown_private_key) { // Ensure the permission is updated permission_object::id_type owner_id; { - auto obj = chain.find(boost::make_tuple(name("alice"), name("owner"))); + auto obj = chain.template find(boost::make_tuple(name("alice"), name("owner"))); BOOST_TEST(obj != nullptr); BOOST_TEST(obj->owner == name("alice")); BOOST_TEST(obj->name == name("owner")); @@ -258,8 +265,8 @@ BOOST_AUTO_TEST_CASE(update_auth_unknown_private_key) { } FC_LOG_AND_RETHROW() } -BOOST_AUTO_TEST_CASE(link_auths) { try { - validating_tester chain; +BOOST_AUTO_TEST_CASE_TEMPLATE( link_auths, TESTER, validating_testers ) { try { + TESTER chain; chain.create_accounts({name("alice"),name("bob")}); @@ -301,8 +308,8 @@ BOOST_AUTO_TEST_CASE(link_auths) { try { } FC_LOG_AND_RETHROW() } -BOOST_AUTO_TEST_CASE(link_then_update_auth) { try { - validating_tester chain; +BOOST_AUTO_TEST_CASE_TEMPLATE( link_then_update_auth, TESTER, validating_testers ) { try { + TESTER chain; chain.create_account(name("alice")); @@ -327,21 +334,20 @@ BOOST_AUTO_TEST_CASE(link_then_update_auth) { try { } FC_LOG_AND_RETHROW() } -BOOST_AUTO_TEST_CASE(create_account) { -try { - validating_tester chain; +BOOST_AUTO_TEST_CASE_TEMPLATE( create_account, TESTER, validating_testers ) { try { + TESTER chain; chain.create_account(name("joe")); chain.produce_block(); // Verify account created properly - const auto& joe_owner_authority = chain.get(boost::make_tuple(name("joe"), name("owner"))); + const auto& joe_owner_authority = chain.template get(boost::make_tuple(name("joe"), name("owner"))); BOOST_TEST(joe_owner_authority.auth.threshold == 1u); BOOST_TEST(joe_owner_authority.auth.accounts.size() == 1u); BOOST_TEST(joe_owner_authority.auth.keys.size() == 1u); BOOST_TEST(joe_owner_authority.auth.keys[0].key.to_string({}) == chain.get_public_key(name("joe"), "owner").to_string({})); BOOST_TEST(joe_owner_authority.auth.keys[0].weight == 1u); - const auto& joe_active_authority = chain.get(boost::make_tuple(name("joe"), name("active"))); + const auto& joe_active_authority = chain.template get(boost::make_tuple(name("joe"), name("active"))); BOOST_TEST(joe_active_authority.auth.threshold == 1u); BOOST_TEST(joe_active_authority.auth.accounts.size() == 1u); BOOST_TEST(joe_active_authority.auth.keys.size() == 1u); @@ -366,8 +372,8 @@ try { } FC_LOG_AND_RETHROW() } -BOOST_AUTO_TEST_CASE( any_auth ) { try { - validating_tester chain; +BOOST_AUTO_TEST_CASE_TEMPLATE( any_auth, TESTER, validating_testers ) { try { + TESTER chain; chain.create_accounts( {name("alice"), name("bob")} ); chain.produce_block(); @@ -401,7 +407,9 @@ BOOST_AUTO_TEST_CASE( any_auth ) { try { } FC_LOG_AND_RETHROW() } -BOOST_AUTO_TEST_CASE(no_double_billing) { +// This test does not apply to Savanna testing for now, as setup_policy::preactivate_feature_and_new_bios +// does not load up bios contract for setfinalizer +BOOST_AUTO_TEST_CASE( no_double_billing ) { try { fc::temp_directory tempdir; validating_tester chain( tempdir, true ); @@ -461,9 +469,9 @@ try { } FC_LOG_AND_RETHROW() } -BOOST_AUTO_TEST_CASE(stricter_auth) { +BOOST_AUTO_TEST_CASE_TEMPLATE( stricter_auth, TESTER, validating_testers ) { try { - validating_tester chain; + TESTER chain; chain.produce_block(); @@ -511,8 +519,8 @@ try { } FC_LOG_AND_RETHROW() } -BOOST_AUTO_TEST_CASE( linkauth_special ) { try { - validating_tester chain; +BOOST_AUTO_TEST_CASE_TEMPLATE( linkauth_special, TESTER, validating_testers ) { try { + TESTER chain; const auto& tester_account = "tester"_n; std::vector ids; @@ -552,8 +560,8 @@ BOOST_AUTO_TEST_CASE( linkauth_special ) { try { } FC_LOG_AND_RETHROW() } -BOOST_AUTO_TEST_CASE(delete_auth) { try { - validating_tester chain; +BOOST_AUTO_TEST_CASE_TEMPLATE( delete_auth, TESTER, validating_testers ) { try { + TESTER chain; const auto& tester_account = "tester"_n;