rbac5 - clear expired and deleted permission linked auths
This commit is contained in:
parent
4c2efdb871
commit
88a8753a60
3 changed files with 110 additions and 60 deletions
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <graphene/chain/database.hpp>
|
||||
#include <graphene/chain/custom_permission_object.hpp>
|
||||
#include <graphene/chain/custom_account_authority_object.hpp>
|
||||
#include <graphene/chain/hardfork.hpp>
|
||||
|
||||
namespace graphene
|
||||
|
|
@ -105,7 +106,21 @@ void_result delete_custom_permission_evaluator::do_apply(const custom_permission
|
|||
{
|
||||
database &d = db();
|
||||
const custom_permission_object &pobj = op.permission_id(d);
|
||||
// TODO: Remove all the custom_account_authority_object linked to this permission object.
|
||||
// Remove the account authority objects linked to this permission
|
||||
const auto& cindex = d.get_index_type<custom_account_authority_index>().indices().get<by_permission_and_op>();
|
||||
vector<std::reference_wrapper<const custom_account_authority_object>> custom_auths;
|
||||
auto crange = cindex.equal_range(boost::make_tuple(pobj.id));
|
||||
// Store the references to the account authorities
|
||||
for(const custom_account_authority_object& cobj : boost::make_iterator_range(crange.first, crange.second))
|
||||
{
|
||||
custom_auths.push_back(cobj);
|
||||
}
|
||||
// Now remove the account authorities
|
||||
for(const auto& cauth : custom_auths)
|
||||
{
|
||||
d.remove(cauth);
|
||||
}
|
||||
// Now finally remove the permission
|
||||
d.remove(pobj);
|
||||
return void_result();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
#include <graphene/chain/witness_object.hpp>
|
||||
#include <graphene/chain/witness_schedule_object.hpp>
|
||||
#include <graphene/chain/worker_object.hpp>
|
||||
#include <graphene/chain/custom_account_authority_object.hpp>
|
||||
|
||||
#define USE_VESTING_OBJECT_BY_ASSET_BALANCE_INDEX // vesting_balance_object by_asset_balance index needed
|
||||
|
||||
|
|
@ -933,6 +934,15 @@ void rolling_period_start(database& db)
|
|||
}
|
||||
}
|
||||
|
||||
void clear_expired_custom_account_authorities(database& db)
|
||||
{
|
||||
const auto& cindex = db.get_index_type<custom_account_authority_index>().indices().get<by_expiration>();
|
||||
while(!cindex.empty() && cindex.begin()->valid_to < db.head_block_time())
|
||||
{
|
||||
db.remove(*cindex.begin());
|
||||
}
|
||||
}
|
||||
|
||||
// Schedules payouts from a dividend distribution account to the current holders of the
|
||||
// dividend-paying asset. This takes any deposits made to the dividend distribution account
|
||||
// since the last time it was called, and distributes them to the current owners of the
|
||||
|
|
@ -1707,7 +1717,10 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
|
|||
//for( const asset_bitasset_data_object* d : get_index_type<asset_bitasset_data_index>() )
|
||||
for( const auto& d : get_index_type<asset_bitasset_data_index>().indices() )
|
||||
modify( d, [](asset_bitasset_data_object& o) { o.force_settled_volume = 0; });
|
||||
|
||||
// Ideally we have to do this after every block but that leads to longer block applicaiton/replay times.
|
||||
// So keep it here as it is not critical. valid_to check ensures
|
||||
// these custom account auths are not usable.
|
||||
clear_expired_custom_account_authorities(*this);
|
||||
// process_budget needs to run at the bottom because
|
||||
// it needs to know the next_maintenance_time
|
||||
process_budget();
|
||||
|
|
|
|||
|
|
@ -93,11 +93,17 @@ BOOST_AUTO_TEST_CASE(permission_create_success_test)
|
|||
generate_blocks(HARDFORK_RBAC_TIME);
|
||||
generate_block();
|
||||
set_expiration(db, trx);
|
||||
ACTORS((alice)(bob));
|
||||
ACTORS((alice)(bob)(charlie)(dave)(erin));
|
||||
upgrade_to_lifetime_member(alice);
|
||||
upgrade_to_lifetime_member(bob);
|
||||
upgrade_to_lifetime_member(charlie);
|
||||
upgrade_to_lifetime_member(dave);
|
||||
upgrade_to_lifetime_member(erin);
|
||||
transfer(committee_account, alice_id, asset(1000 * GRAPHENE_BLOCKCHAIN_PRECISION));
|
||||
transfer(committee_account, bob_id, asset(1000 * GRAPHENE_BLOCKCHAIN_PRECISION));
|
||||
transfer(committee_account, charlie_id, asset(1000 * GRAPHENE_BLOCKCHAIN_PRECISION));
|
||||
transfer(committee_account, dave_id, asset(1000 * GRAPHENE_BLOCKCHAIN_PRECISION));
|
||||
transfer(committee_account, erin_id, asset(1000 * GRAPHENE_BLOCKCHAIN_PRECISION));
|
||||
const auto &pidx = db.get_index_type<custom_permission_index>().indices().get<by_id>();
|
||||
// Alice creates a permission abc
|
||||
{
|
||||
|
|
@ -138,7 +144,7 @@ BOOST_AUTO_TEST_CASE(permission_update_test)
|
|||
INVOKE(permission_create_success_test);
|
||||
GET_ACTOR(alice);
|
||||
GET_ACTOR(bob);
|
||||
ACTORS((charlie));
|
||||
GET_ACTOR(charlie);
|
||||
const auto &pidx = db.get_index_type<custom_permission_index>().indices().get<by_id>();
|
||||
BOOST_REQUIRE(pidx.size() == 1);
|
||||
BOOST_REQUIRE(custom_permission_id_type(0)(db).permission_name == "abc");
|
||||
|
|
@ -210,56 +216,6 @@ BOOST_AUTO_TEST_CASE(permission_update_test)
|
|||
FC_LOG_AND_RETHROW()
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(permission_delete_test)
|
||||
{
|
||||
try
|
||||
{
|
||||
INVOKE(permission_create_success_test);
|
||||
GET_ACTOR(alice);
|
||||
GET_ACTOR(bob);
|
||||
const auto &pidx = db.get_index_type<custom_permission_index>().indices().get<by_id>();
|
||||
BOOST_REQUIRE(pidx.size() == 1);
|
||||
BOOST_REQUIRE(custom_permission_id_type(0)(db).permission_name == "abc");
|
||||
BOOST_REQUIRE(custom_permission_id_type(0)(db).auth == authority(1, bob_id, 1));
|
||||
// Alice tries to delete permission abc with wrong owner_account
|
||||
{
|
||||
custom_permission_delete_operation op;
|
||||
op.permission_id = custom_permission_id_type(0);
|
||||
op.owner_account = bob_id;
|
||||
trx.operations.push_back(op);
|
||||
sign(trx, bob_private_key);
|
||||
BOOST_CHECK_THROW(PUSH_TX(db, trx), fc::exception);
|
||||
trx.clear();
|
||||
BOOST_REQUIRE(pidx.size() == 1);
|
||||
}
|
||||
// Alice tries to delete permission abc with wrong permission_id
|
||||
{
|
||||
custom_permission_delete_operation op;
|
||||
op.permission_id = custom_permission_id_type(1);
|
||||
op.owner_account = alice_id;
|
||||
trx.operations.push_back(op);
|
||||
sign(trx, alice_private_key);
|
||||
BOOST_CHECK_THROW(PUSH_TX(db, trx), fc::exception);
|
||||
trx.clear();
|
||||
BOOST_REQUIRE(pidx.size() == 1);
|
||||
}
|
||||
// Alice deletes permission abc
|
||||
{
|
||||
BOOST_REQUIRE(custom_permission_id_type(0)(db).permission_name == "abc");
|
||||
BOOST_REQUIRE(custom_permission_id_type(0)(db).auth == authority(1, bob_id, 1));
|
||||
custom_permission_delete_operation op;
|
||||
op.permission_id = custom_permission_id_type(0);
|
||||
op.owner_account = alice_id;
|
||||
trx.operations.push_back(op);
|
||||
sign(trx, alice_private_key);
|
||||
PUSH_TX(db, trx);
|
||||
trx.clear();
|
||||
BOOST_REQUIRE(pidx.size() == 0);
|
||||
}
|
||||
}
|
||||
FC_LOG_AND_RETHROW()
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(account_authority_create_test)
|
||||
{
|
||||
try
|
||||
|
|
@ -279,7 +235,7 @@ BOOST_AUTO_TEST_CASE(account_authority_create_test)
|
|||
op.permission_id = custom_permission_id_type(0);
|
||||
op.valid_from = db.head_block_time();
|
||||
op.valid_to = db.head_block_time() + fc::seconds(10 * db.block_interval());
|
||||
op.operation_type = 0;
|
||||
op.operation_type = operation::tag<transfer_operation>::value;
|
||||
op.owner_account = alice_id;
|
||||
trx.operations.push_back(op);
|
||||
sign(trx, alice_private_key);
|
||||
|
|
@ -294,7 +250,7 @@ BOOST_AUTO_TEST_CASE(account_authority_create_test)
|
|||
op.permission_id = custom_permission_id_type(0);
|
||||
op.valid_from = db.head_block_time();
|
||||
op.valid_to = db.head_block_time() + fc::seconds(11 * db.block_interval());
|
||||
op.operation_type = 0;
|
||||
op.operation_type = operation::tag<transfer_operation>::value;
|
||||
op.owner_account = alice_id;
|
||||
trx.operations.push_back(op);
|
||||
sign(trx, alice_private_key);
|
||||
|
|
@ -379,6 +335,57 @@ BOOST_AUTO_TEST_CASE(account_authority_delete_test)
|
|||
FC_LOG_AND_RETHROW()
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(permission_delete_test)
|
||||
{
|
||||
try
|
||||
{
|
||||
INVOKE(account_authority_create_test);
|
||||
GET_ACTOR(alice);
|
||||
GET_ACTOR(bob);
|
||||
const auto &pidx = db.get_index_type<custom_permission_index>().indices().get<by_id>();
|
||||
const auto &cidx = db.get_index_type<custom_account_authority_index>().indices().get<by_id>();
|
||||
BOOST_REQUIRE(pidx.size() == 1);
|
||||
BOOST_REQUIRE(custom_permission_id_type(0)(db).permission_name == "abc");
|
||||
BOOST_REQUIRE(custom_permission_id_type(0)(db).auth == authority(1, bob_id, 1));
|
||||
BOOST_REQUIRE(cidx.size() == 2);
|
||||
// Alice tries to delete permission abc with wrong owner_account
|
||||
{
|
||||
custom_permission_delete_operation op;
|
||||
op.permission_id = custom_permission_id_type(0);
|
||||
op.owner_account = bob_id;
|
||||
trx.operations.push_back(op);
|
||||
sign(trx, bob_private_key);
|
||||
BOOST_CHECK_THROW(PUSH_TX(db, trx), fc::exception);
|
||||
trx.clear();
|
||||
BOOST_REQUIRE(pidx.size() == 1);
|
||||
}
|
||||
// Alice tries to delete permission abc with wrong permission_id
|
||||
{
|
||||
custom_permission_delete_operation op;
|
||||
op.permission_id = custom_permission_id_type(1);
|
||||
op.owner_account = alice_id;
|
||||
trx.operations.push_back(op);
|
||||
sign(trx, alice_private_key);
|
||||
BOOST_CHECK_THROW(PUSH_TX(db, trx), fc::exception);
|
||||
trx.clear();
|
||||
BOOST_REQUIRE(pidx.size() == 1);
|
||||
}
|
||||
// Alice deletes permission abc
|
||||
{
|
||||
custom_permission_delete_operation op;
|
||||
op.permission_id = custom_permission_id_type(0);
|
||||
op.owner_account = alice_id;
|
||||
trx.operations.push_back(op);
|
||||
sign(trx, alice_private_key);
|
||||
PUSH_TX(db, trx);
|
||||
trx.clear();
|
||||
BOOST_REQUIRE(pidx.size() == 0);
|
||||
BOOST_REQUIRE(cidx.size() == 0);
|
||||
}
|
||||
}
|
||||
FC_LOG_AND_RETHROW()
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(transfer_op_custom_permission_test)
|
||||
{
|
||||
try
|
||||
|
|
@ -390,6 +397,7 @@ BOOST_AUTO_TEST_CASE(transfer_op_custom_permission_test)
|
|||
const auto &cidx = db.get_index_type<custom_account_authority_index>().indices().get<by_id>();
|
||||
BOOST_REQUIRE(pidx.size() == 1);
|
||||
BOOST_REQUIRE(cidx.size() == 2);
|
||||
// alice->bob transfer_operation op with active auth, success
|
||||
generate_block();
|
||||
{
|
||||
transfer_operation op;
|
||||
|
|
@ -404,7 +412,7 @@ BOOST_AUTO_TEST_CASE(transfer_op_custom_permission_test)
|
|||
trx.clear();
|
||||
generate_block();
|
||||
}
|
||||
|
||||
// alice->bob transfer_operation op with the created custom account auth, success
|
||||
{
|
||||
transfer_operation op;
|
||||
op.amount.asset_id = asset_id_type(0);
|
||||
|
|
@ -418,7 +426,7 @@ BOOST_AUTO_TEST_CASE(transfer_op_custom_permission_test)
|
|||
trx.clear();
|
||||
generate_block();
|
||||
}
|
||||
|
||||
// alice->bob transfer_operation op with extra unnecessary sigs (both active and the custom auth), fails
|
||||
{
|
||||
transfer_operation op;
|
||||
op.amount.asset_id = asset_id_type(0);
|
||||
|
|
@ -433,7 +441,7 @@ BOOST_AUTO_TEST_CASE(transfer_op_custom_permission_test)
|
|||
trx.clear();
|
||||
generate_block();
|
||||
}
|
||||
|
||||
// bob->alice transfer_operation op with alice active auth sig, fails
|
||||
{
|
||||
transfer_operation op;
|
||||
op.amount.asset_id = asset_id_type(0);
|
||||
|
|
@ -447,6 +455,20 @@ BOOST_AUTO_TEST_CASE(transfer_op_custom_permission_test)
|
|||
trx.clear();
|
||||
generate_block();
|
||||
}
|
||||
// bob->alice transfer_operation op with bob active auth sig, success
|
||||
{
|
||||
transfer_operation op;
|
||||
op.amount.asset_id = asset_id_type(0);
|
||||
op.amount.amount = 100 * GRAPHENE_BLOCKCHAIN_PRECISION;
|
||||
op.from = bob_id;
|
||||
op.to = alice_id;
|
||||
op.fee.asset_id = asset_id_type(0);
|
||||
trx.operations.push_back(op);
|
||||
sign(trx, bob_private_key);
|
||||
PUSH_TX(db, trx);
|
||||
trx.clear();
|
||||
generate_block();
|
||||
}
|
||||
}
|
||||
FC_LOG_AND_RETHROW()
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue