提交 26b55521 编写于 作者: A Andrianto Lie

Salvage usable test cases from native_contract_tests

上级 f2bcd951
......@@ -38,9 +38,14 @@ namespace eosio { namespace testing {
for( auto n : names ) create_account(n, config::system_account_name, multisig );
}
void link_authority( account_name account, account_name code, permission_name req, action_name type = "" );
void unlink_authority( account_name account, account_name code, action_name type = "" );
void set_authority( account_name account, permission_name perm, authority auth,
permission_name parent, const vector<permission_level>& auths, const vector<private_key_type>& keys );
void set_authority( account_name account, permission_name perm, authority auth,
permission_name parent = config::owner_name );
void delete_authority( account_name account, permission_name perm, const vector<permission_level>& auths, const vector<private_key_type>& keys );
void delete_authority( account_name account, permission_name perm );
void create_account( account_name name, account_name creator = config::system_account_name, bool multisig = false );
......@@ -50,11 +55,21 @@ namespace eosio { namespace testing {
transaction_trace transfer( account_name from, account_name to, asset amount, string memo, account_name currency );
transaction_trace transfer( account_name from, account_name to, string amount, string memo, account_name currency );
template<typename ObjectType>
const auto& get(const chainbase::oid< ObjectType >& key) {
return control->get_database().get<ObjectType>(key);
}
template<typename ObjectType, typename IndexBy, typename... Args>
const auto& get( Args&&... args ) {
return control->get_database().get<ObjectType,IndexBy>( forward<Args>(args)... );
}
template<typename ObjectType, typename IndexBy, typename... Args>
const auto* find( Args&&... args ) {
return control->get_database().find<ObjectType,IndexBy>( forward<Args>(args)... );
}
public_key_type get_public_key( name keyname, string role = "owner" ) const;
private_key_type get_private_key( name keyname, string role = "owner" ) const;
......
......@@ -136,8 +136,8 @@ namespace eosio { namespace testing {
transaction_trace base_tester::push_action( const account_name& code,
const action_name& acttype,
const account_name& actor,
const variant_object& data
)
const variant_object& data )
{ try {
chain::contracts::abi_serializer abis( control->get_database().get<account_object,by_name>(code).get_abi() );
......@@ -247,12 +247,37 @@ namespace eosio { namespace testing {
return push_transaction( trx );
}
void base_tester::link_authority( account_name account, account_name code, permission_name req, action_name type ) {
signed_transaction trx;
trx.actions.emplace_back( vector<permission_level>{{account, config::active_name}},
contracts::linkauth(account, code, type, req));
set_tapos( trx );
trx.sign( get_private_key( account, "active" ), chain_id_type() );
push_transaction( trx );
}
void base_tester::unlink_authority( account_name account, account_name code, action_name type ) {
signed_transaction trx;
trx.actions.emplace_back( vector<permission_level>{{account, config::active_name}},
contracts::unlinkauth(account, code, type ));
set_tapos( trx );
trx.sign( get_private_key( account, "active" ), chain_id_type() );
push_transaction( trx );
}
void base_tester::set_authority( account_name account,
permission_name perm,
authority auth,
permission_name parent ) { try {
permission_name parent,
const vector<permission_level>& auths,
const vector<private_key_type>& keys) { try {
signed_transaction trx;
trx.actions.emplace_back( vector<permission_level>{{account,perm}},
trx.actions.emplace_back( auths,
contracts::updateauth{
.account = account,
.permission = perm,
......@@ -261,10 +286,42 @@ namespace eosio { namespace testing {
});
set_tapos( trx );
trx.sign( get_private_key( account, "active" ), chain_id_type() );
for (const auto& key: keys) {
trx.sign( key, chain_id_type() );
}
push_transaction( trx );
} FC_CAPTURE_AND_RETHROW( (account)(perm)(auth)(parent) ) }
void base_tester::set_authority( account_name account,
permission_name perm,
authority auth,
permission_name parent) {
set_authority(account, perm, auth, parent, { { account, config::owner_name } }, { get_private_key( account, "owner" ) });
}
void base_tester::delete_authority( account_name account,
permission_name perm,
const vector<permission_level>& auths,
const vector<private_key_type>& keys ) { try {
signed_transaction trx;
trx.actions.emplace_back( auths,
contracts::deleteauth(account, perm) );
set_tapos( trx );
for (const auto& key: keys) {
trx.sign( key, chain_id_type() );
}
push_transaction( trx );
} FC_CAPTURE_AND_RETHROW( (account)(perm) ) }
void base_tester::delete_authority( account_name account,
permission_name perm ) {
delete_authority(account, perm, { permission_level{ account, config::owner_name } }, { get_private_key( account, "owner" ) });
}
void base_tester::set_code( account_name account, const char* wast ) try {
auto wasm = wast_to_wasm(wast);
......
......@@ -69,5 +69,195 @@ BOOST_FIXTURE_TEST_CASE( delegate_auth, tester ) { try {
} FC_LOG_AND_RETHROW() }
BOOST_AUTO_TEST_CASE(update_auths) {
try {
tester chain;
chain.create_account("alice");
// Deleting active or owner should fail
BOOST_CHECK_THROW(chain.delete_authority("alice", "active"), action_validate_exception);
BOOST_CHECK_THROW(chain.delete_authority("alice", "owner"), action_validate_exception);
// Change owner permission
const auto new_owner_priv_key = chain.get_private_key("alice", "new_owner");
const auto new_owner_pub_key = new_owner_priv_key.get_public_key();
chain.set_authority("alice", "owner", authority(new_owner_pub_key), "");
chain.produce_blocks();
// Ensure the permission is updated
permission_object::id_type owner_id;
{
auto obj = chain.find<permission_object, by_owner>(boost::make_tuple("alice", "owner"));
BOOST_TEST(obj != nullptr);
BOOST_TEST(obj->owner == "alice");
BOOST_TEST(obj->name == "owner");
BOOST_TEST(obj->parent == 0);
owner_id = obj->id;
auto auth = obj->auth.to_authority();
BOOST_TEST(auth.threshold == 1);
BOOST_TEST(auth.keys.size() == 1);
BOOST_TEST(auth.accounts.size() == 0);
BOOST_TEST(auth.keys[0].key == new_owner_pub_key);
BOOST_TEST(auth.keys[0].weight == 1);
}
// Change active permission, remember that the owner key has been changed
const auto new_active_priv_key = chain.get_private_key("alice", "new_active");
const auto new_active_pub_key = new_active_priv_key.get_public_key();
chain.set_authority("alice", "active", authority(new_active_pub_key), "owner",
{ permission_level{"alice", "active"} }, { chain.get_private_key("alice", "active") });
chain.produce_blocks();
{
auto obj = chain.find<permission_object, by_owner>(boost::make_tuple("alice", "active"));
BOOST_TEST(obj != nullptr);
BOOST_TEST(obj->owner == "alice");
BOOST_TEST(obj->name == "active");
BOOST_TEST(obj->parent == owner_id);
auto auth = obj->auth.to_authority();
BOOST_TEST(auth.threshold == 1);
BOOST_TEST(auth.keys.size() == 1);
BOOST_TEST(auth.accounts.size() == 0);
BOOST_TEST(auth.keys[0].key == new_active_pub_key);
BOOST_TEST(auth.keys[0].weight == 1);
}
auto spending_priv_key = chain.get_private_key("alice", "spending");
auto spending_pub_key = spending_priv_key.get_public_key();
auto trading_priv_key = chain.get_private_key("alice", "trading");
auto trading_pub_key = trading_priv_key.get_public_key();
// Create new spending auth
chain.set_authority("alice", "spending", authority(spending_pub_key), "active",
{ permission_level{"alice", "active"} }, { new_active_priv_key });
chain.produce_blocks();
{
auto obj = chain.find<permission_object, by_owner>(boost::make_tuple("alice", "spending"));
BOOST_TEST(obj != nullptr);
BOOST_TEST(obj->owner == "alice");
BOOST_TEST(obj->name == "spending");
BOOST_TEST(chain.get<permission_object>(obj->parent).owner == "alice");
BOOST_TEST(chain.get<permission_object>(obj->parent).name == "active");
}
// Update spending auth parent to be its own, should fail
BOOST_CHECK_THROW(chain.set_authority("alice", "spending", spending_pub_key, "spending",
{ permission_level{"alice", "spending"} }, { spending_priv_key }), action_validate_exception);
// Update spending auth parent to be owner, should fail
BOOST_CHECK_THROW(chain.set_authority("alice", "spending", spending_pub_key, "owner",
{ permission_level{"alice", "spending"} }, { spending_priv_key }), action_validate_exception);
// Remove spending auth
chain.delete_authority("alice", "spending", { permission_level{"alice", "active"} }, { new_active_priv_key });
{
auto obj = chain.find<permission_object, by_owner>(boost::make_tuple("alice", "spending"));
BOOST_TEST(obj == nullptr);
}
chain.produce_blocks();
// Create new trading auth
chain.set_authority("alice", "trading", trading_pub_key, "active",
{ permission_level{"alice", "active"} }, { new_active_priv_key });
// Recreate spending auth again, however this time, it's under trading instead of owner
chain.set_authority("alice", "spending", spending_pub_key, "trading",
{ permission_level{"alice", "trading"} }, { trading_priv_key });
chain.produce_blocks();
// Verify correctness of trading and spending
{
const auto* trading = chain.find<permission_object, by_owner>(boost::make_tuple("alice", "trading"));
const auto* spending = chain.find<permission_object, by_owner>(boost::make_tuple("alice", "spending"));
BOOST_TEST(trading != nullptr);
BOOST_TEST(spending != nullptr);
BOOST_TEST(trading->owner == "alice");
BOOST_TEST(spending->owner == "alice");
BOOST_TEST(trading->name == "trading");
BOOST_TEST(spending->name == "spending");
BOOST_TEST(spending->parent == trading->id);
BOOST_TEST(chain.get(trading->parent).owner == "alice");
BOOST_TEST(chain.get(trading->parent).name == "active");
}
// Delete trading, should fail since it has children (spending)
BOOST_CHECK_THROW(chain.delete_authority("alice", "trading",
{ permission_level{"alice", "active"} }, { new_active_priv_key }), action_validate_exception);
// Update trading parent to be spending, should fail since changing parent authority is not supported
BOOST_CHECK_THROW(chain.set_authority("alice", "trading", trading_pub_key, "spending",
{ permission_level{"alice", "trading"} }, { trading_priv_key }), action_validate_exception);
// Delete spending auth
chain.delete_authority("alice", "spending", { permission_level{"alice", "active"} }, { new_active_priv_key });
BOOST_TEST((chain.find<permission_object, by_owner>(boost::make_tuple("alice", "spending"))) == nullptr);
// Delete trading auth, now it should succeed since it doesn't have any children anymore
chain.delete_authority("alice", "trading", { permission_level{"alice", "active"} }, { new_active_priv_key });
BOOST_TEST((chain.find<permission_object, by_owner>(boost::make_tuple("alice", "trading"))) == nullptr);
} FC_LOG_AND_RETHROW() }
BOOST_AUTO_TEST_CASE(link_auths) { try {
tester chain;
chain.create_accounts({"alice","bob"});
const auto spending_priv_key = chain.get_private_key("alice", "spending");
const auto spending_pub_key = spending_priv_key.get_public_key();
const auto scud_priv_key = chain.get_private_key("alice", "scud");
const auto scud_pub_key = scud_priv_key.get_public_key();
chain.set_authority("alice", "spending", spending_pub_key, "active");
chain.set_authority("alice", "scud", scud_pub_key, "spending");
// Send req auth action with alice's spending key, it should fail
BOOST_CHECK_THROW(chain.push_reqauth("alice", { permission_level{N(alice), "spending"} }, { spending_priv_key }), tx_irrelevant_auth);
// Link authority for eosio reqauth action with alice's spending key
chain.link_authority("alice", "eosio", "spending", "reqauth");
// Now, req auth action with alice's spending key should succeed
chain.push_reqauth("alice", { permission_level{N(alice), "spending"} }, { spending_priv_key });
chain.produce_block();
// Relink the same auth should fail
BOOST_CHECK_THROW( chain.link_authority("alice", "eosio", "spending", "reqauth"), action_validate_exception);
// Unlink alice with eosio reqauth
chain.unlink_authority("alice", "eosio", "reqauth");
// Now, req auth action with alice's spending key should fail
BOOST_CHECK_THROW(chain.push_reqauth("alice", { permission_level{N(alice), "spending"} }, { spending_priv_key }), tx_irrelevant_auth);
chain.produce_block();
// Send req auth action with scud key, it should fail
BOOST_CHECK_THROW(chain.push_reqauth("alice", { permission_level{N(alice), "scud"} }, { scud_priv_key }), tx_irrelevant_auth);
// Link authority for any eosio action with alice's scud key
chain.link_authority("alice", "eosio", "scud");
// Now, req auth action with alice's scud key should succeed
chain.push_reqauth("alice", { permission_level{N(alice), "scud"} }, { scud_priv_key });
// req auth action with alice's spending key should also be fine, since it is the parent of alice's scud key
chain.push_reqauth("alice", { permission_level{N(alice), "spending"} }, { spending_priv_key });
} FC_LOG_AND_RETHROW() }
BOOST_AUTO_TEST_CASE(create_account) {
try {
tester chain;
chain.create_account("joe");
chain.produce_block();
// Verify account created properly
const auto& joe_owner_authority = chain.get<permission_object, by_owner>(boost::make_tuple("joe", "owner"));
BOOST_TEST(joe_owner_authority.auth.threshold == 1);
BOOST_TEST(joe_owner_authority.auth.accounts.size() == 0);
BOOST_TEST(joe_owner_authority.auth.keys.size() == 1);
BOOST_TEST(string(joe_owner_authority.auth.keys[0].key) == string(chain.get_public_key("joe", "owner")));
BOOST_TEST(joe_owner_authority.auth.keys[0].weight == 1);
const auto& joe_active_authority = chain.get<permission_object, by_owner>(boost::make_tuple("joe", "active"));
BOOST_TEST(joe_active_authority.auth.threshold == 1);
BOOST_TEST(joe_active_authority.auth.accounts.size() == 0);
BOOST_TEST(joe_active_authority.auth.keys.size() == 1);
BOOST_TEST(string(joe_active_authority.auth.keys[0].key) == string(chain.get_public_key("joe", "active")));
BOOST_TEST(joe_active_authority.auth.keys[0].weight == 1);
} FC_LOG_AND_RETHROW() }
BOOST_AUTO_TEST_SUITE_END()
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册