From 35c4740fd8172db90031aaa7d339b669fa7b6d89 Mon Sep 17 00:00:00 2001 From: Nathan Hourt Date: Tue, 8 Aug 2017 16:58:07 -0500 Subject: [PATCH] Ref #123: Add test macros, testing, and fixing Add macros for Link_Authority and Unlink_Authority, write some initial tests of these operations, and fix a bug (unlinkauth didn't require any authority) --- libraries/native_contract/eos_contract.cpp | 3 +++ tests/common/macro_support.hpp | 29 ++++++++++++++++++++++ tests/common/testing_macros.hpp | 22 ++++++++++++++++ tests/tests/native_contract_tests.cpp | 29 ++++++++++++++++++++++ 4 files changed, 83 insertions(+) diff --git a/libraries/native_contract/eos_contract.cpp b/libraries/native_contract/eos_contract.cpp index 73f5a22e0ed..bd551a0d813 100644 --- a/libraries/native_contract/eos_contract.cpp +++ b/libraries/native_contract/eos_contract.cpp @@ -461,6 +461,9 @@ void apply_eos_linkauth(apply_context& context) { void apply_eos_unlinkauth(apply_context& context) { auto& db = context.mutable_db; auto unlink = context.msg.as(); + + context.require_authorization(unlink.account); + auto linkKey = boost::make_tuple(unlink.account, unlink.code, unlink.type); auto link = db.find(linkKey); EOS_ASSERT(link != nullptr, message_precondition_exception, "Attempting to unlink authority, but no link found"); diff --git a/tests/common/macro_support.hpp b/tests/common/macro_support.hpp index 2d3be220f7b..ee9df2096c7 100644 --- a/tests/common/macro_support.hpp +++ b/tests/common/macro_support.hpp @@ -100,6 +100,35 @@ inline std::vector sort_names( std::vector&& names ) { BOOST_TEST_CHECKPOINT("Deleted " << #account << "'s " << authname << " authority."); \ } +#define LINKAUTH5(chain, account, authname, codeacct, messagetype) \ + { \ + eos::chain::SignedTransaction trx; \ + trx.scope = {#account}; \ + trx.emplaceMessage(config::EosContractName, \ + vector{{#account,"active"}}, \ + "linkauth", types::linkauth{#account, #codeacct, messagetype, authname}); \ + trx.expiration = chain.head_block_time() + 100; \ + trx.set_reference_block(chain.head_block_id()); \ + chain.push_transaction(trx, chain_controller::skip_transaction_signatures); \ + BOOST_TEST_CHECKPOINT("Link " << #codeacct << "::" << messagetype << " to " << #account \ + << "'s " << authname << " authority."); \ + } +#define LINKAUTH4(chain, account, authname, codeacct) LINKAUTH5(chain, account, authname, codeacct, "") + +#define UNLINKAUTH4(chain, account, codeacct, messagetype) \ + { \ + eos::chain::SignedTransaction trx; \ + trx.scope = {#account}; \ + trx.emplaceMessage(config::EosContractName, \ + vector{{#account,"active"}}, \ + "unlinkauth", types::unlinkauth{#account, #codeacct, messagetype}); \ + trx.expiration = chain.head_block_time() + 100; \ + trx.set_reference_block(chain.head_block_id()); \ + chain.push_transaction(trx, chain_controller::skip_transaction_signatures); \ + BOOST_TEST_CHECKPOINT("Unlink " << #codeacct << "::" << messagetype << " from " << #account); \ + } +#define LINKAUTH3(chain, account, codeacct) LINKAUTH5(chain, account, codeacct, "") + #define XFER5(chain, sender, recipient, Amount, memo) \ { \ eos::chain::SignedTransaction trx; \ diff --git a/tests/common/testing_macros.hpp b/tests/common/testing_macros.hpp index 3aaab52a7a6..2c1cd368a0b 100644 --- a/tests/common/testing_macros.hpp +++ b/tests/common/testing_macros.hpp @@ -189,6 +189,28 @@ * @endcode */ #define Delete_Authority(...) BOOST_PP_OVERLOAD(DELAUTH, __VA_ARGS__)(__VA_ARGS__) +/** + * @brief Shorthand way to link named authority with a contract/message type + * + * @code{.cpp} + * // Link alice's "money" authority with eos::transfer + * Link_Authority(chain, alice, "money", eos, "transfer"); + * // Set alice's "native" authority as default for eos contract + * Link_Authority(chain, alice, "money", eos); + * @endcode + */ +#define Link_Authority(...) BOOST_PP_OVERLOAD(LINKAUTH, __VA_ARGS__)(__VA_ARGS__) +/** + * @brief Shorthand way to unlink named authority from a contract/message type + * + * @code{.cpp} + * // Unlink alice's authority for eos::transfer + * Unlink_Authority(chain, alice, eos, "transfer"); + * // Unset alice's default authority for eos contract + * Unlink_Authority(chain, alice, eos); + * @endcode + */ +#define Unlink_Authority(...) BOOST_PP_OVERLOAD(UNLINKAUTH, __VA_ARGS__)(__VA_ARGS__) /** * @brief Shorthand way to transfer funds diff --git a/tests/tests/native_contract_tests.cpp b/tests/tests/native_contract_tests.cpp index d0c0230ce73..4ccf99f080a 100644 --- a/tests/tests/native_contract_tests.cpp +++ b/tests/tests/native_contract_tests.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -463,4 +464,32 @@ BOOST_FIXTURE_TEST_CASE(auth_tests, testing_fixture) { } } FC_LOG_AND_RETHROW() } +BOOST_FIXTURE_TEST_CASE(auth_links, testing_fixture) { try { + Make_Blockchain(chain); + Make_Account(chain, alice); + chain.produce_blocks(); + + Make_Key(spending); + Make_Key(scud); + + Set_Authority(chain, alice, "spending", "active", Key_Authority(spending_public_key)); + Set_Authority(chain, alice, "scud", "spending", Key_Authority(scud_public_key)); + Link_Authority(chain, alice, "spending", eos, "transfer"); + + { + auto obj = chain_db.find(boost::make_tuple("alice", "eos", "transfer")); + BOOST_CHECK_NE(obj, nullptr); + BOOST_CHECK_EQUAL(obj->account, "alice"); + BOOST_CHECK_EQUAL(obj->code, "eos"); + BOOST_CHECK_EQUAL(obj->message_type, "transfer"); + } + + Unlink_Authority(chain, alice, eos, "transfer"); + + { + auto obj = chain_db.find(boost::make_tuple("alice", "eos", "transfer")); + BOOST_CHECK_EQUAL(obj, nullptr); + } +} FC_LOG_AND_RETHROW() } + BOOST_AUTO_TEST_SUITE_END()