rbac1 - evaluators and op validators added
This commit is contained in:
parent
d8ca4d4625
commit
2a7c8749d3
18 changed files with 731 additions and 1 deletions
|
|
@ -61,6 +61,8 @@ add_library( graphene_chain
|
||||||
protocol/vote.cpp
|
protocol/vote.cpp
|
||||||
protocol/tournament.cpp
|
protocol/tournament.cpp
|
||||||
protocol/small_ops.cpp
|
protocol/small_ops.cpp
|
||||||
|
protocol/custom_permission.cpp
|
||||||
|
protocol/custom_account_authority.cpp
|
||||||
|
|
||||||
genesis_state.cpp
|
genesis_state.cpp
|
||||||
get_config.cpp
|
get_config.cpp
|
||||||
|
|
@ -112,6 +114,8 @@ add_library( graphene_chain
|
||||||
betting_market_evaluator.cpp
|
betting_market_evaluator.cpp
|
||||||
betting_market_object.cpp
|
betting_market_object.cpp
|
||||||
betting_market_group_object.cpp
|
betting_market_group_object.cpp
|
||||||
|
custom_permission_evaluator.cpp
|
||||||
|
custom_account_authority_evaluator.cpp
|
||||||
|
|
||||||
affiliate_payout.cpp
|
affiliate_payout.cpp
|
||||||
|
|
||||||
|
|
|
||||||
150
libraries/chain/custom_account_authority_evaluator.cpp
Normal file
150
libraries/chain/custom_account_authority_evaluator.cpp
Normal file
|
|
@ -0,0 +1,150 @@
|
||||||
|
#include <graphene/chain/custom_account_authority_evaluator.hpp>
|
||||||
|
|
||||||
|
#include <graphene/chain/database.hpp>
|
||||||
|
#include <graphene/chain/custom_account_authority_object.hpp>
|
||||||
|
#include <graphene/chain/custom_permission_object.hpp>
|
||||||
|
#include <graphene/chain/hardfork.hpp>
|
||||||
|
|
||||||
|
namespace graphene
|
||||||
|
{
|
||||||
|
namespace chain
|
||||||
|
{
|
||||||
|
|
||||||
|
struct rbac_operation_hardfork_visitor
|
||||||
|
{
|
||||||
|
typedef void result_type;
|
||||||
|
const fc::time_point_sec block_time;
|
||||||
|
|
||||||
|
rbac_operation_hardfork_visitor( const fc::time_point_sec bt ) : block_time(bt) {}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void operator()(const T &v) const {}
|
||||||
|
|
||||||
|
void operator()(const custom_permission_create_operation &op) const {
|
||||||
|
FC_ASSERT( block_time >= HARDFORK_RBAC_TIME, "custom_permission_create_operation not allowed yet!" );
|
||||||
|
}
|
||||||
|
void operator()(const custom_permission_update_operation &op) const {
|
||||||
|
FC_ASSERT( block_time >= HARDFORK_RBAC_TIME, "custom_permission_update_operation not allowed yet!" );
|
||||||
|
}
|
||||||
|
void operator()(const custom_permission_delete_operation &op) const {
|
||||||
|
FC_ASSERT( block_time >= HARDFORK_RBAC_TIME, "custom_permission_delete_operation not allowed yet!" );
|
||||||
|
}
|
||||||
|
void operator()(const custom_account_authority_create_operation &op) const {
|
||||||
|
FC_ASSERT( block_time >= HARDFORK_RBAC_TIME, "custom_account_authority_create_operation not allowed yet!" );
|
||||||
|
}
|
||||||
|
void operator()(const custom_account_authority_update_operation &op) const {
|
||||||
|
FC_ASSERT( block_time >= HARDFORK_RBAC_TIME, "custom_account_authority_update_operation not allowed yet!" );
|
||||||
|
}
|
||||||
|
void operator()(const custom_account_authority_delete_operation &op) const {
|
||||||
|
FC_ASSERT( block_time >= HARDFORK_RBAC_TIME, "custom_account_authority_delete_operation not allowed yet!" );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void_result create_custom_account_authority_evaluator::do_evaluate(const custom_account_authority_create_operation &op)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const database &d = db();
|
||||||
|
auto now = d.head_block_time();
|
||||||
|
FC_ASSERT(now >= HARDFORK_RBAC_TIME, "Not allowed until RBAC HF");
|
||||||
|
op.owner_account(d);
|
||||||
|
const custom_permission_object& pobj = op.permission_id(d);
|
||||||
|
FC_ASSERT(pobj.account == op.owner_account, "Only owner account can update account authority object");
|
||||||
|
FC_ASSERT(op.valid_to > now, "valid_to expiry should be in future");
|
||||||
|
return void_result();
|
||||||
|
}
|
||||||
|
FC_CAPTURE_AND_RETHROW((op))
|
||||||
|
}
|
||||||
|
|
||||||
|
object_id_type create_custom_account_authority_evaluator::do_apply(const custom_account_authority_create_operation &op)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
database &d = db();
|
||||||
|
return d.create<custom_account_authority_object>([&op](custom_account_authority_object &obj) mutable {
|
||||||
|
obj.permission_id = op.permission_id;
|
||||||
|
obj.operation_type = op.operation_type;
|
||||||
|
obj.valid_from = op.valid_from;
|
||||||
|
obj.valid_to = op.valid_to;
|
||||||
|
}).id;
|
||||||
|
}
|
||||||
|
FC_CAPTURE_AND_RETHROW((op))
|
||||||
|
}
|
||||||
|
|
||||||
|
void_result update_custom_account_authority_evaluator::do_evaluate(const custom_account_authority_update_operation &op)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const database &d = db();
|
||||||
|
auto now = d.head_block_time();
|
||||||
|
FC_ASSERT(now >= HARDFORK_RBAC_TIME, "Not allowed until RBAC HF");
|
||||||
|
op.owner_account(d);
|
||||||
|
const custom_account_authority_object& aobj = op.auth_id(d);
|
||||||
|
const custom_permission_object& pobj = aobj.permission_id(d);
|
||||||
|
FC_ASSERT(pobj.account == op.owner_account, "Only owner account can update account authority object");
|
||||||
|
auto valid_from = aobj.valid_from;
|
||||||
|
auto valid_to = aobj.valid_to;
|
||||||
|
if (op.new_valid_from) {
|
||||||
|
FC_ASSERT(*op.new_valid_from != aobj.valid_from,
|
||||||
|
"New valid_from provided is not different from old valid_from");
|
||||||
|
valid_from = *op.new_valid_from;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op.new_valid_to) {
|
||||||
|
FC_ASSERT(*op.new_valid_to != aobj.valid_to,
|
||||||
|
"New valid_to provided is not different from old valid_to");
|
||||||
|
FC_ASSERT(*op.new_valid_to > now, "New valid_to expiry should be in the future");
|
||||||
|
valid_to = *op.new_valid_to;
|
||||||
|
}
|
||||||
|
FC_ASSERT(valid_from < valid_to, "valid_from should be before valid_to");
|
||||||
|
return void_result();
|
||||||
|
}
|
||||||
|
FC_CAPTURE_AND_RETHROW((op))
|
||||||
|
}
|
||||||
|
|
||||||
|
object_id_type update_custom_account_authority_evaluator::do_apply(const custom_account_authority_update_operation &op)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
database& d = db();
|
||||||
|
const custom_account_authority_object& aobj = op.auth_id(d);
|
||||||
|
d.modify(aobj, [&op](custom_account_authority_object &obj) {
|
||||||
|
if (op.new_valid_from)
|
||||||
|
obj.valid_from = *op.new_valid_from;
|
||||||
|
if (op.new_valid_to)
|
||||||
|
obj.valid_to = *op.new_valid_to;
|
||||||
|
});
|
||||||
|
return op.auth_id;
|
||||||
|
}
|
||||||
|
FC_CAPTURE_AND_RETHROW((op))
|
||||||
|
}
|
||||||
|
|
||||||
|
void_result delete_custom_account_authority_evaluator::do_evaluate(const custom_account_authority_delete_operation &op)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const database &d = db();
|
||||||
|
auto now = d.head_block_time();
|
||||||
|
FC_ASSERT(now >= HARDFORK_RBAC_TIME, "Not allowed until RBAC HF");
|
||||||
|
op.owner_account(d);
|
||||||
|
const custom_account_authority_object& aobj = op.auth_id(d);
|
||||||
|
const custom_permission_object& pobj = aobj.permission_id(d);
|
||||||
|
FC_ASSERT(pobj.account == op.owner_account, "Only owner account can delete account authority object");
|
||||||
|
return void_result();
|
||||||
|
}
|
||||||
|
FC_CAPTURE_AND_RETHROW((op))
|
||||||
|
}
|
||||||
|
|
||||||
|
object_id_type delete_custom_account_authority_evaluator::do_apply(const custom_account_authority_delete_operation &op)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
database &d = db();
|
||||||
|
const custom_account_authority_object& aobj = op.auth_id(d);
|
||||||
|
d.remove(aobj);
|
||||||
|
}
|
||||||
|
FC_CAPTURE_AND_RETHROW((op))
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace chain
|
||||||
|
} // namespace graphene
|
||||||
115
libraries/chain/custom_permission_evaluator.cpp
Normal file
115
libraries/chain/custom_permission_evaluator.cpp
Normal file
|
|
@ -0,0 +1,115 @@
|
||||||
|
#include <graphene/chain/custom_permission_evaluator.hpp>
|
||||||
|
|
||||||
|
#include <graphene/chain/database.hpp>
|
||||||
|
#include <graphene/chain/custom_permission_object.hpp>
|
||||||
|
#include <graphene/chain/hardfork.hpp>
|
||||||
|
|
||||||
|
namespace graphene
|
||||||
|
{
|
||||||
|
namespace chain
|
||||||
|
{
|
||||||
|
|
||||||
|
void_result create_custom_permission_evaluator::do_evaluate(const custom_permission_create_operation &op)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const database &d = db();
|
||||||
|
auto now = d.head_block_time();
|
||||||
|
FC_ASSERT(now >= HARDFORK_RBAC_TIME, "Not allowed until RBAC HF");
|
||||||
|
op.owner_account(d);
|
||||||
|
for (const auto &account_weight_pair : op.auth.account_auths)
|
||||||
|
{
|
||||||
|
account_weight_pair.first(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto &pindex = d.get_index_type<custom_permission_index>().indices().get<by_account_and_permission>();
|
||||||
|
auto pitr = pindex.find(boost::make_tuple(op.owner_account, op.permission_name));
|
||||||
|
FC_ASSERT(pitr == pindex.end(), "Permission name already exists for the given account");
|
||||||
|
return void_result();
|
||||||
|
}
|
||||||
|
FC_CAPTURE_AND_RETHROW((op))
|
||||||
|
}
|
||||||
|
|
||||||
|
object_id_type create_custom_permission_evaluator::do_apply(const custom_permission_create_operation &op)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
database &d = db();
|
||||||
|
return d.create<custom_permission_object>([&op](custom_permission_object &obj) mutable {
|
||||||
|
obj.account = op.owner_account;
|
||||||
|
obj.permission_name = op.permission_name;
|
||||||
|
obj.auth = op.auth;
|
||||||
|
}).id;
|
||||||
|
}
|
||||||
|
FC_CAPTURE_AND_RETHROW((op))
|
||||||
|
}
|
||||||
|
|
||||||
|
void_result update_custom_permission_evaluator::do_evaluate(const custom_permission_update_operation &op)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const database &d = db();
|
||||||
|
auto now = d.head_block_time();
|
||||||
|
FC_ASSERT(now >= HARDFORK_RBAC_TIME, "Not allowed until RBAC HF");
|
||||||
|
op.owner_account(d);
|
||||||
|
const custom_permission_object& pobj = op.permission_id(d);
|
||||||
|
FC_ASSERT(pobj.account == op.owner_account, "Only owner account can update permission object");
|
||||||
|
if (op.new_auth)
|
||||||
|
{
|
||||||
|
FC_ASSERT(!(*op.new_auth == pobj.auth), "New authority provided is not different from old authority");
|
||||||
|
for (const auto &account_weight_pair : op.new_auth->account_auths)
|
||||||
|
{
|
||||||
|
account_weight_pair.first(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return void_result();
|
||||||
|
}
|
||||||
|
FC_CAPTURE_AND_RETHROW((op))
|
||||||
|
}
|
||||||
|
|
||||||
|
object_id_type update_custom_permission_evaluator::do_apply(const custom_permission_update_operation &op)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
database &d = db();
|
||||||
|
const custom_permission_object& pobj = op.permission_id(d);
|
||||||
|
d.modify(pobj, [&op](custom_permission_object &obj) {
|
||||||
|
if (op.new_auth)
|
||||||
|
obj.auth = *op.new_auth;
|
||||||
|
});
|
||||||
|
|
||||||
|
return op.permission_id;
|
||||||
|
}
|
||||||
|
FC_CAPTURE_AND_RETHROW((op))
|
||||||
|
}
|
||||||
|
|
||||||
|
void_result delete_custom_permission_evaluator::do_evaluate(const custom_permission_delete_operation &op)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const database &d = db();
|
||||||
|
auto now = d.head_block_time();
|
||||||
|
FC_ASSERT(now >= HARDFORK_RBAC_TIME, "Not allowed until RBAC HF");
|
||||||
|
op.owner_account(d);
|
||||||
|
const custom_permission_object& pobj = op.permission_id(d);
|
||||||
|
FC_ASSERT(pobj.account == op.owner_account, "Only owner account can delete permission object");
|
||||||
|
return void_result();
|
||||||
|
}
|
||||||
|
FC_CAPTURE_AND_RETHROW((op))
|
||||||
|
}
|
||||||
|
|
||||||
|
void_result delete_custom_permission_evaluator::do_apply(const custom_permission_delete_operation &op)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
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.
|
||||||
|
d.remove(pobj);
|
||||||
|
return void_result();
|
||||||
|
}
|
||||||
|
FC_CAPTURE_AND_RETHROW((op))
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace chain
|
||||||
|
} // namespace graphene
|
||||||
|
|
@ -49,6 +49,8 @@
|
||||||
#include <graphene/chain/tournament_object.hpp>
|
#include <graphene/chain/tournament_object.hpp>
|
||||||
#include <graphene/chain/match_object.hpp>
|
#include <graphene/chain/match_object.hpp>
|
||||||
#include <graphene/chain/game_object.hpp>
|
#include <graphene/chain/game_object.hpp>
|
||||||
|
#include <graphene/chain/custom_permission_object.hpp>
|
||||||
|
#include <graphene/chain/custom_account_authority_object.hpp>
|
||||||
|
|
||||||
|
|
||||||
#include <graphene/chain/sport_object.hpp>
|
#include <graphene/chain/sport_object.hpp>
|
||||||
|
|
@ -77,6 +79,8 @@
|
||||||
#include <graphene/chain/event_evaluator.hpp>
|
#include <graphene/chain/event_evaluator.hpp>
|
||||||
#include <graphene/chain/betting_market_evaluator.hpp>
|
#include <graphene/chain/betting_market_evaluator.hpp>
|
||||||
#include <graphene/chain/tournament_evaluator.hpp>
|
#include <graphene/chain/tournament_evaluator.hpp>
|
||||||
|
#include <graphene/chain/custom_permission_evaluator.hpp>
|
||||||
|
#include <graphene/chain/custom_account_authority_evaluator.hpp>
|
||||||
|
|
||||||
#include <graphene/chain/protocol/fee_schedule.hpp>
|
#include <graphene/chain/protocol/fee_schedule.hpp>
|
||||||
|
|
||||||
|
|
@ -243,6 +247,12 @@ void database::initialize_evaluators()
|
||||||
register_evaluator<lottery_reward_evaluator>();
|
register_evaluator<lottery_reward_evaluator>();
|
||||||
register_evaluator<lottery_end_evaluator>();
|
register_evaluator<lottery_end_evaluator>();
|
||||||
register_evaluator<sweeps_vesting_claim_evaluator>();
|
register_evaluator<sweeps_vesting_claim_evaluator>();
|
||||||
|
register_evaluator<create_custom_permission_evaluator>();
|
||||||
|
register_evaluator<update_custom_permission_evaluator>();
|
||||||
|
register_evaluator<delete_custom_permission_evaluator>();
|
||||||
|
register_evaluator<create_custom_account_authority_evaluator>();
|
||||||
|
register_evaluator<update_custom_account_authority_evaluator>();
|
||||||
|
register_evaluator<delete_custom_account_authority_evaluator>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void database::initialize_indexes()
|
void database::initialize_indexes()
|
||||||
|
|
@ -284,6 +294,8 @@ void database::initialize_indexes()
|
||||||
tournament_details_idx->add_secondary_index<tournament_players_index>();
|
tournament_details_idx->add_secondary_index<tournament_players_index>();
|
||||||
add_index< primary_index<match_index> >();
|
add_index< primary_index<match_index> >();
|
||||||
add_index< primary_index<game_index> >();
|
add_index< primary_index<game_index> >();
|
||||||
|
add_index< primary_index<custom_permission_index> >();
|
||||||
|
add_index< primary_index<custom_account_authority_index> >();
|
||||||
|
|
||||||
//Implementation object indexes
|
//Implementation object indexes
|
||||||
add_index< primary_index<transaction_index > >();
|
add_index< primary_index<transaction_index > >();
|
||||||
|
|
|
||||||
|
|
@ -293,6 +293,25 @@ struct get_impacted_account_visitor
|
||||||
void operator()( const sweeps_vesting_claim_operation& op ) {
|
void operator()( const sweeps_vesting_claim_operation& op ) {
|
||||||
_impacted.insert( op.account );
|
_impacted.insert( op.account );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void operator()( const custom_permission_create_operation& op ){
|
||||||
|
_impacted.insert( op.owner_account );
|
||||||
|
}
|
||||||
|
void operator()( const custom_permission_update_operation& op ){
|
||||||
|
_impacted.insert( op.owner_account );
|
||||||
|
}
|
||||||
|
void operator()( const custom_permission_delete_operation& op ){
|
||||||
|
_impacted.insert( op.owner_account );
|
||||||
|
}
|
||||||
|
void operator()( const custom_account_authority_create_operation& op ){
|
||||||
|
_impacted.insert( op.owner_account );
|
||||||
|
}
|
||||||
|
void operator()( const custom_account_authority_update_operation& op ){
|
||||||
|
_impacted.insert( op.owner_account );
|
||||||
|
}
|
||||||
|
void operator()( const custom_account_authority_delete_operation& op ){
|
||||||
|
_impacted.insert( op.owner_account );
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void graphene::chain::operation_get_impacted_accounts( const operation& op, flat_set<account_id_type>& result )
|
void graphene::chain::operation_get_impacted_accounts( const operation& op, flat_set<account_id_type>& result )
|
||||||
|
|
|
||||||
4
libraries/chain/hardfork.d/RBAC.hf
Normal file
4
libraries/chain/hardfork.d/RBAC.hf
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
// RBAC HARDFORK Wednesday, 20-May-20 00:00:00 UTC
|
||||||
|
#ifndef HARDFORK_RBAC_TIME
|
||||||
|
#define HARDFORK_RBAC_TIME (fc::time_point_sec( 1589932800 ))
|
||||||
|
#endif
|
||||||
|
|
@ -234,3 +234,6 @@
|
||||||
#define GPOS_PERIOD (60*60*24*30*6) // 6 months
|
#define GPOS_PERIOD (60*60*24*30*6) // 6 months
|
||||||
#define GPOS_SUBPERIOD (60*60*24*30) // 1 month
|
#define GPOS_SUBPERIOD (60*60*24*30) // 1 month
|
||||||
#define GPOS_VESTING_LOCKIN_PERIOD (60*60*24*30) // 1 month
|
#define GPOS_VESTING_LOCKIN_PERIOD (60*60*24*30) // 1 month
|
||||||
|
|
||||||
|
#define RBAC_MIN_PERMISSION_NAME_LENGTH 3
|
||||||
|
#define RBAC_MAX_PERMISSION_NAME_LENGTH 10
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
#pragma once
|
||||||
|
#include <graphene/chain/evaluator.hpp>
|
||||||
|
#include <graphene/chain/protocol/custom_account_authority.hpp>
|
||||||
|
|
||||||
|
namespace graphene { namespace chain {
|
||||||
|
|
||||||
|
class create_custom_account_authority_evaluator : public evaluator<create_custom_account_authority_evaluator>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef custom_account_authority_create_operation operation_type;
|
||||||
|
|
||||||
|
void_result do_evaluate(const custom_account_authority_create_operation& o);
|
||||||
|
object_id_type do_apply(const custom_account_authority_create_operation& o);
|
||||||
|
};
|
||||||
|
|
||||||
|
class update_custom_account_authority_evaluator : public evaluator<update_custom_account_authority_evaluator>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef custom_account_authority_update_operation operation_type;
|
||||||
|
|
||||||
|
void_result do_evaluate(const custom_account_authority_update_operation& o);
|
||||||
|
object_id_type do_apply(const custom_account_authority_update_operation& o);
|
||||||
|
};
|
||||||
|
|
||||||
|
class delete_custom_account_authority_evaluator : public evaluator<delete_custom_account_authority_evaluator>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef custom_account_authority_delete_operation operation_type;
|
||||||
|
|
||||||
|
void_result do_evaluate(const custom_account_authority_delete_operation& o);
|
||||||
|
object_id_type do_apply(const custom_account_authority_delete_operation& o);
|
||||||
|
};
|
||||||
|
|
||||||
|
} } // namespace graphene::chain
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
#pragma once
|
||||||
|
#include <graphene/chain/protocol/types.hpp>
|
||||||
|
#include <graphene/db/object.hpp>
|
||||||
|
#include <graphene/db/generic_index.hpp>
|
||||||
|
|
||||||
|
namespace graphene { namespace chain {
|
||||||
|
using namespace graphene::db;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class custom_account_authority_object
|
||||||
|
* @brief Tracks the mappings between permission and operation types.
|
||||||
|
* @ingroup object
|
||||||
|
*/
|
||||||
|
class custom_account_authority_object : public abstract_object<custom_account_authority_object>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const uint8_t space_id = protocol_ids;
|
||||||
|
static const uint8_t type_id = custom_account_authority_object_type;
|
||||||
|
|
||||||
|
custom_permission_id_type permission_id;
|
||||||
|
int operation_type;
|
||||||
|
time_point_sec valid_from;
|
||||||
|
time_point_sec valid_to;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct by_id;
|
||||||
|
struct by_permission_and_op;
|
||||||
|
struct by_expiration;
|
||||||
|
using custom_account_authority_multi_index_type = multi_index_container<
|
||||||
|
custom_account_authority_object,
|
||||||
|
indexed_by<
|
||||||
|
ordered_unique< tag<by_id>,
|
||||||
|
member<object, object_id_type, &object::id>
|
||||||
|
>,
|
||||||
|
ordered_unique< tag<by_permission_and_op>,
|
||||||
|
composite_key<custom_account_authority_object,
|
||||||
|
member<custom_account_authority_object, custom_permission_id_type, &custom_account_authority_object::permission_id>,
|
||||||
|
member<custom_account_authority_object, int, &custom_account_authority_object::operation_type>,
|
||||||
|
member<object, object_id_type, &object::id>
|
||||||
|
>
|
||||||
|
>,
|
||||||
|
ordered_unique<tag<by_expiration>,
|
||||||
|
composite_key<custom_account_authority_object,
|
||||||
|
member<custom_account_authority_object, time_point_sec, &custom_account_authority_object::valid_to>,
|
||||||
|
member<object, object_id_type, &object::id>
|
||||||
|
>
|
||||||
|
>
|
||||||
|
>
|
||||||
|
>;
|
||||||
|
using custom_account_authority_index = generic_index<custom_account_authority_object, custom_account_authority_multi_index_type>;
|
||||||
|
|
||||||
|
} } // graphene::chain
|
||||||
|
|
||||||
|
FC_REFLECT_DERIVED( graphene::chain::custom_account_authority_object, (graphene::db::object),
|
||||||
|
(permission_id)(operation_type)(valid_from)(valid_to) )
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
#pragma once
|
||||||
|
#include <graphene/chain/evaluator.hpp>
|
||||||
|
#include <graphene/chain/protocol/custom_permission.hpp>
|
||||||
|
|
||||||
|
namespace graphene { namespace chain {
|
||||||
|
|
||||||
|
class create_custom_permission_evaluator : public evaluator<create_custom_permission_evaluator>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef custom_permission_create_operation operation_type;
|
||||||
|
|
||||||
|
void_result do_evaluate(const custom_permission_create_operation& o);
|
||||||
|
object_id_type do_apply(const custom_permission_create_operation& o);
|
||||||
|
};
|
||||||
|
|
||||||
|
class update_custom_permission_evaluator : public evaluator<update_custom_permission_evaluator>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef custom_permission_update_operation operation_type;
|
||||||
|
|
||||||
|
void_result do_evaluate(const custom_permission_update_operation& o);
|
||||||
|
object_id_type do_apply(const custom_permission_update_operation& o);
|
||||||
|
};
|
||||||
|
|
||||||
|
class delete_custom_permission_evaluator : public evaluator<delete_custom_permission_evaluator>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef custom_permission_delete_operation operation_type;
|
||||||
|
|
||||||
|
void_result do_evaluate(const custom_permission_delete_operation& o);
|
||||||
|
void_result do_apply(const custom_permission_delete_operation& o);
|
||||||
|
};
|
||||||
|
|
||||||
|
} } // namespace graphene::chain
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
#pragma once
|
||||||
|
#include <graphene/chain/protocol/types.hpp>
|
||||||
|
#include <graphene/db/object.hpp>
|
||||||
|
#include <graphene/db/generic_index.hpp>
|
||||||
|
|
||||||
|
namespace graphene { namespace chain {
|
||||||
|
using namespace graphene::db;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class custom_permission_object
|
||||||
|
* @brief Tracks all the custom permission of an account.
|
||||||
|
* @ingroup object
|
||||||
|
*/
|
||||||
|
class custom_permission_object : public abstract_object<custom_permission_object>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const uint8_t space_id = protocol_ids;
|
||||||
|
static const uint8_t type_id = custom_permission_object_type;
|
||||||
|
|
||||||
|
// Account for which this permission is being created
|
||||||
|
account_id_type account;
|
||||||
|
// Permission name
|
||||||
|
string permission_name;
|
||||||
|
// Authority required for this permission
|
||||||
|
authority auth;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct by_id;
|
||||||
|
struct by_account_and_permission;
|
||||||
|
using custom_permission_multi_index_type = multi_index_container<
|
||||||
|
custom_permission_object,
|
||||||
|
indexed_by<
|
||||||
|
ordered_unique< tag<by_id>,
|
||||||
|
member<object, object_id_type, &object::id>
|
||||||
|
>,
|
||||||
|
ordered_unique< tag<by_account_and_permission>,
|
||||||
|
composite_key<custom_permission_object,
|
||||||
|
member<custom_permission_object, account_id_type, &custom_permission_object::account>,
|
||||||
|
member<custom_permission_object, string, &custom_permission_object::permission_name>
|
||||||
|
>
|
||||||
|
>
|
||||||
|
>
|
||||||
|
>;
|
||||||
|
using custom_permission_index = generic_index<custom_permission_object, custom_permission_multi_index_type>;
|
||||||
|
|
||||||
|
} } // graphene::chain
|
||||||
|
|
||||||
|
FC_REFLECT_DERIVED( graphene::chain::custom_permission_object, (graphene::db::object),
|
||||||
|
(account)(permission_name)(auth) )
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
#pragma once
|
||||||
|
#include <graphene/chain/protocol/base.hpp>
|
||||||
|
|
||||||
|
namespace graphene { namespace chain {
|
||||||
|
|
||||||
|
struct custom_account_authority_create_operation : public base_operation
|
||||||
|
{
|
||||||
|
struct fee_parameters_type { uint64_t fee = 0; };
|
||||||
|
|
||||||
|
asset fee;
|
||||||
|
custom_permission_id_type permission_id;
|
||||||
|
int operation_type;
|
||||||
|
time_point_sec valid_from;
|
||||||
|
time_point_sec valid_to;
|
||||||
|
account_id_type owner_account;
|
||||||
|
|
||||||
|
account_id_type fee_payer()const { return owner_account; }
|
||||||
|
void validate() const;
|
||||||
|
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct custom_account_authority_update_operation : public base_operation
|
||||||
|
{
|
||||||
|
struct fee_parameters_type { uint64_t fee = 0; };
|
||||||
|
|
||||||
|
asset fee;
|
||||||
|
custom_account_authority_id_type auth_id;
|
||||||
|
optional<time_point_sec> new_valid_from;
|
||||||
|
optional<time_point_sec> new_valid_to;
|
||||||
|
account_id_type owner_account;
|
||||||
|
|
||||||
|
account_id_type fee_payer()const { return owner_account; }
|
||||||
|
void validate() const;
|
||||||
|
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct custom_account_authority_delete_operation : public base_operation
|
||||||
|
{
|
||||||
|
struct fee_parameters_type { uint64_t fee = 0; };
|
||||||
|
|
||||||
|
asset fee;
|
||||||
|
custom_account_authority_id_type auth_id;
|
||||||
|
account_id_type owner_account;
|
||||||
|
|
||||||
|
account_id_type fee_payer()const { return owner_account; }
|
||||||
|
void validate() const;
|
||||||
|
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} } // namespace graphene::chain
|
||||||
|
|
||||||
|
FC_REFLECT(graphene::chain::custom_account_authority_create_operation::fee_parameters_type, (fee) )
|
||||||
|
FC_REFLECT(graphene::chain::custom_account_authority_create_operation, (fee)(permission_id)(operation_type)(valid_from)(valid_to)(owner_account) )
|
||||||
|
|
||||||
|
FC_REFLECT(graphene::chain::custom_account_authority_update_operation::fee_parameters_type, (fee) )
|
||||||
|
FC_REFLECT(graphene::chain::custom_account_authority_update_operation, (fee)(auth_id)(new_valid_from)(new_valid_to)(owner_account) )
|
||||||
|
|
||||||
|
FC_REFLECT(graphene::chain::custom_account_authority_delete_operation::fee_parameters_type, (fee) )
|
||||||
|
FC_REFLECT(graphene::chain::custom_account_authority_delete_operation, (fee)(auth_id)(owner_account) )
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
#pragma once
|
||||||
|
#include <graphene/chain/protocol/base.hpp>
|
||||||
|
|
||||||
|
namespace graphene { namespace chain {
|
||||||
|
|
||||||
|
struct custom_permission_create_operation : public base_operation
|
||||||
|
{
|
||||||
|
struct fee_parameters_type { uint64_t fee = 0; };
|
||||||
|
|
||||||
|
asset fee;
|
||||||
|
account_id_type owner_account;
|
||||||
|
string permission_name;
|
||||||
|
authority auth;
|
||||||
|
|
||||||
|
account_id_type fee_payer()const { return owner_account; }
|
||||||
|
void validate() const;
|
||||||
|
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct custom_permission_update_operation : public base_operation
|
||||||
|
{
|
||||||
|
struct fee_parameters_type { uint64_t fee = 0; };
|
||||||
|
|
||||||
|
asset fee;
|
||||||
|
custom_permission_id_type permission_id;
|
||||||
|
optional<authority> new_auth;
|
||||||
|
account_id_type owner_account;
|
||||||
|
|
||||||
|
account_id_type fee_payer()const { return owner_account; }
|
||||||
|
void validate() const;
|
||||||
|
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct custom_permission_delete_operation : public base_operation
|
||||||
|
{
|
||||||
|
struct fee_parameters_type { uint64_t fee = 0; };
|
||||||
|
|
||||||
|
asset fee;
|
||||||
|
custom_permission_id_type permission_id;
|
||||||
|
account_id_type owner_account;
|
||||||
|
|
||||||
|
account_id_type fee_payer()const { return owner_account; }
|
||||||
|
void validate() const;
|
||||||
|
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} } // namespace graphene::chain
|
||||||
|
|
||||||
|
FC_REFLECT(graphene::chain::custom_permission_create_operation::fee_parameters_type, (fee) )
|
||||||
|
FC_REFLECT(graphene::chain::custom_permission_create_operation, (fee)(owner_account)(permission_name)(auth) )
|
||||||
|
|
||||||
|
FC_REFLECT(graphene::chain::custom_permission_update_operation::fee_parameters_type, (fee) )
|
||||||
|
FC_REFLECT(graphene::chain::custom_permission_update_operation, (fee)(permission_id)(new_auth)(owner_account) )
|
||||||
|
|
||||||
|
FC_REFLECT(graphene::chain::custom_permission_delete_operation::fee_parameters_type, (fee) )
|
||||||
|
FC_REFLECT(graphene::chain::custom_permission_delete_operation, (fee)(permission_id)(owner_account) )
|
||||||
|
|
@ -45,6 +45,8 @@
|
||||||
#include <graphene/chain/protocol/event.hpp>
|
#include <graphene/chain/protocol/event.hpp>
|
||||||
#include <graphene/chain/protocol/betting_market.hpp>
|
#include <graphene/chain/protocol/betting_market.hpp>
|
||||||
#include <graphene/chain/protocol/tournament.hpp>
|
#include <graphene/chain/protocol/tournament.hpp>
|
||||||
|
#include <graphene/chain/protocol/custom_permission.hpp>
|
||||||
|
#include <graphene/chain/protocol/custom_account_authority.hpp>
|
||||||
|
|
||||||
namespace graphene { namespace chain {
|
namespace graphene { namespace chain {
|
||||||
|
|
||||||
|
|
@ -135,7 +137,13 @@ namespace graphene { namespace chain {
|
||||||
ticket_purchase_operation,
|
ticket_purchase_operation,
|
||||||
lottery_reward_operation,
|
lottery_reward_operation,
|
||||||
lottery_end_operation,
|
lottery_end_operation,
|
||||||
sweeps_vesting_claim_operation
|
sweeps_vesting_claim_operation,
|
||||||
|
custom_permission_create_operation,
|
||||||
|
custom_permission_update_operation,
|
||||||
|
custom_permission_delete_operation,
|
||||||
|
custom_account_authority_create_operation,
|
||||||
|
custom_account_authority_update_operation,
|
||||||
|
custom_account_authority_delete_operation
|
||||||
> operation;
|
> operation;
|
||||||
|
|
||||||
/// @} // operations group
|
/// @} // operations group
|
||||||
|
|
|
||||||
|
|
@ -171,6 +171,8 @@ namespace graphene { namespace chain {
|
||||||
betting_market_group_object_type,
|
betting_market_group_object_type,
|
||||||
betting_market_object_type,
|
betting_market_object_type,
|
||||||
bet_object_type,
|
bet_object_type,
|
||||||
|
custom_permission_object_type,
|
||||||
|
custom_account_authority_object_type,
|
||||||
OBJECT_TYPE_COUNT ///< Sentry value which contains the number of different object types
|
OBJECT_TYPE_COUNT ///< Sentry value which contains the number of different object types
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -230,6 +232,8 @@ namespace graphene { namespace chain {
|
||||||
class betting_market_group_object;
|
class betting_market_group_object;
|
||||||
class betting_market_object;
|
class betting_market_object;
|
||||||
class bet_object;
|
class bet_object;
|
||||||
|
class custom_permission_object;
|
||||||
|
class custom_account_authority_object;
|
||||||
|
|
||||||
typedef object_id< protocol_ids, account_object_type, account_object> account_id_type;
|
typedef object_id< protocol_ids, account_object_type, account_object> account_id_type;
|
||||||
typedef object_id< protocol_ids, asset_object_type, asset_object> asset_id_type;
|
typedef object_id< protocol_ids, asset_object_type, asset_object> asset_id_type;
|
||||||
|
|
@ -256,6 +260,8 @@ namespace graphene { namespace chain {
|
||||||
typedef object_id< protocol_ids, betting_market_group_object_type, betting_market_group_object> betting_market_group_id_type;
|
typedef object_id< protocol_ids, betting_market_group_object_type, betting_market_group_object> betting_market_group_id_type;
|
||||||
typedef object_id< protocol_ids, betting_market_object_type, betting_market_object> betting_market_id_type;
|
typedef object_id< protocol_ids, betting_market_object_type, betting_market_object> betting_market_id_type;
|
||||||
typedef object_id< protocol_ids, bet_object_type, bet_object> bet_id_type;
|
typedef object_id< protocol_ids, bet_object_type, bet_object> bet_id_type;
|
||||||
|
typedef object_id< protocol_ids, custom_permission_object_type, custom_permission_object> custom_permission_id_type;
|
||||||
|
typedef object_id< protocol_ids, custom_account_authority_object_type, custom_account_authority_object> custom_account_authority_id_type;
|
||||||
|
|
||||||
// implementation types
|
// implementation types
|
||||||
class global_property_object;
|
class global_property_object;
|
||||||
|
|
@ -436,6 +442,8 @@ FC_REFLECT_ENUM( graphene::chain::object_type,
|
||||||
(betting_market_group_object_type)
|
(betting_market_group_object_type)
|
||||||
(betting_market_object_type)
|
(betting_market_object_type)
|
||||||
(bet_object_type)
|
(bet_object_type)
|
||||||
|
(custom_permission_object_type)
|
||||||
|
(custom_account_authority_object_type)
|
||||||
(OBJECT_TYPE_COUNT)
|
(OBJECT_TYPE_COUNT)
|
||||||
)
|
)
|
||||||
FC_REFLECT_ENUM( graphene::chain::impl_object_type,
|
FC_REFLECT_ENUM( graphene::chain::impl_object_type,
|
||||||
|
|
@ -505,6 +513,8 @@ FC_REFLECT_TYPENAME( graphene::chain::fba_accumulator_id_type )
|
||||||
FC_REFLECT_TYPENAME( graphene::chain::betting_market_position_id_type )
|
FC_REFLECT_TYPENAME( graphene::chain::betting_market_position_id_type )
|
||||||
FC_REFLECT_TYPENAME( graphene::chain::global_betting_statistics_id_type )
|
FC_REFLECT_TYPENAME( graphene::chain::global_betting_statistics_id_type )
|
||||||
FC_REFLECT_TYPENAME( graphene::chain::tournament_details_id_type )
|
FC_REFLECT_TYPENAME( graphene::chain::tournament_details_id_type )
|
||||||
|
FC_REFLECT_TYPENAME( graphene::chain::custom_permission_id_type )
|
||||||
|
FC_REFLECT_TYPENAME( graphene::chain::custom_account_authority_id_type )
|
||||||
|
|
||||||
FC_REFLECT( graphene::chain::void_t, )
|
FC_REFLECT( graphene::chain::void_t, )
|
||||||
|
|
||||||
|
|
|
||||||
39
libraries/chain/protocol/custom_account_authority.cpp
Normal file
39
libraries/chain/protocol/custom_account_authority.cpp
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
#include <graphene/chain/protocol/custom_account_authority.hpp>
|
||||||
|
#include <graphene/chain/protocol/operations.hpp>
|
||||||
|
|
||||||
|
namespace graphene { namespace chain {
|
||||||
|
|
||||||
|
void custom_account_authority_create_operation::validate()const {
|
||||||
|
FC_ASSERT(fee.amount >= 0, "Fee must not be negative");
|
||||||
|
FC_ASSERT(owner_account != GRAPHENE_TEMP_ACCOUNT
|
||||||
|
&& owner_account != GRAPHENE_COMMITTEE_ACCOUNT
|
||||||
|
&& owner_account != GRAPHENE_WITNESS_ACCOUNT
|
||||||
|
&& owner_account != GRAPHENE_RELAXED_COMMITTEE_ACCOUNT,
|
||||||
|
"Custom permissions and account auths cannot be created for special accounts");
|
||||||
|
FC_ASSERT(valid_from < valid_to, "valid_from should be earlier than valid_to");
|
||||||
|
FC_ASSERT(operation_type >= 0 && operation_type < operation::count(), "operation_type is not valid");
|
||||||
|
}
|
||||||
|
|
||||||
|
void custom_account_authority_update_operation::validate()const {
|
||||||
|
FC_ASSERT(fee.amount >= 0, "Fee must not be negative");
|
||||||
|
FC_ASSERT(owner_account != GRAPHENE_TEMP_ACCOUNT
|
||||||
|
&& owner_account != GRAPHENE_COMMITTEE_ACCOUNT
|
||||||
|
&& owner_account != GRAPHENE_WITNESS_ACCOUNT
|
||||||
|
&& owner_account != GRAPHENE_RELAXED_COMMITTEE_ACCOUNT,
|
||||||
|
"Custom permissions and account auths cannot be created for special accounts");
|
||||||
|
FC_ASSERT(new_valid_from.valid() || new_valid_to.valid(), "Something must be updated");
|
||||||
|
if (new_valid_from && new_valid_to) {
|
||||||
|
FC_ASSERT(*new_valid_from < *new_valid_to, "valid_from should be earlier than valid_to");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void custom_account_authority_delete_operation::validate()const {
|
||||||
|
FC_ASSERT(fee.amount >= 0, "Fee must not be negative");
|
||||||
|
FC_ASSERT(owner_account != GRAPHENE_TEMP_ACCOUNT
|
||||||
|
&& owner_account != GRAPHENE_COMMITTEE_ACCOUNT
|
||||||
|
&& owner_account != GRAPHENE_WITNESS_ACCOUNT
|
||||||
|
&& owner_account != GRAPHENE_RELAXED_COMMITTEE_ACCOUNT,
|
||||||
|
"Custom permissions and account auths cannot be created for special accounts");
|
||||||
|
}
|
||||||
|
|
||||||
|
} } // graphene::chain
|
||||||
77
libraries/chain/protocol/custom_permission.cpp
Normal file
77
libraries/chain/protocol/custom_permission.cpp
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
#include <graphene/chain/protocol/custom_permission.hpp>
|
||||||
|
#include <graphene/chain/protocol/operations.hpp>
|
||||||
|
|
||||||
|
namespace graphene { namespace chain {
|
||||||
|
|
||||||
|
bool is_valid_permission_name( const string& name )
|
||||||
|
{ try {
|
||||||
|
const size_t len = name.size();
|
||||||
|
// RBAC_MIN_PERMISSION_NAME_LENGTH <= len minimum length check
|
||||||
|
if( len < RBAC_MIN_PERMISSION_NAME_LENGTH )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// len <= RBAC_MAX_PERMISSION_NAME_LENGTH max length check
|
||||||
|
if( len > RBAC_MAX_PERMISSION_NAME_LENGTH )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// First character should be a letter between a-z
|
||||||
|
if( !(name[0] >= 'a' && name[0] <= 'z') )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Any character of a permission name should either be a small case letter a-z or a digit 0-9
|
||||||
|
for( const auto& ch: name)
|
||||||
|
{
|
||||||
|
if( !((ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Don't accept active and owner permissions as we already have them by default
|
||||||
|
// This is for removing ambiguity for users, accepting them doesn't create any problems
|
||||||
|
if( name == "active" || name == "owner" )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} FC_CAPTURE_AND_RETHROW( (name) ) }
|
||||||
|
|
||||||
|
void custom_permission_create_operation::validate()const {
|
||||||
|
FC_ASSERT(fee.amount >= 0, "Fee must not be negative");
|
||||||
|
FC_ASSERT(is_valid_permission_name( permission_name ), "Invalid permission name provided");
|
||||||
|
FC_ASSERT(owner_account != GRAPHENE_TEMP_ACCOUNT
|
||||||
|
&& owner_account != GRAPHENE_COMMITTEE_ACCOUNT
|
||||||
|
&& owner_account != GRAPHENE_WITNESS_ACCOUNT
|
||||||
|
&& owner_account != GRAPHENE_RELAXED_COMMITTEE_ACCOUNT,
|
||||||
|
"Custom permissions and account auths cannot be created for special accounts");
|
||||||
|
FC_ASSERT(!auth.is_impossible(), "Impossible authority threshold auth provided");
|
||||||
|
FC_ASSERT(auth.address_auths.size() == 0, "Only account and key auths supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
void custom_permission_update_operation::validate()const {
|
||||||
|
FC_ASSERT(fee.amount >= 0, "Fee must not be negative");
|
||||||
|
FC_ASSERT(owner_account != GRAPHENE_TEMP_ACCOUNT
|
||||||
|
&& owner_account != GRAPHENE_COMMITTEE_ACCOUNT
|
||||||
|
&& owner_account != GRAPHENE_WITNESS_ACCOUNT
|
||||||
|
&& owner_account != GRAPHENE_RELAXED_COMMITTEE_ACCOUNT,
|
||||||
|
"Custom permissions and account auths cannot be created for special accounts");
|
||||||
|
FC_ASSERT( new_auth.valid(), "Something must be updated");
|
||||||
|
if (new_auth) {
|
||||||
|
FC_ASSERT(!new_auth->is_impossible(), "Impossible authority threshold auth provided");
|
||||||
|
FC_ASSERT(new_auth->address_auths.size() == 0, "Only account and key auths supported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void custom_permission_delete_operation::validate()const {
|
||||||
|
FC_ASSERT(fee.amount >= 0, "Fee must not be negative");
|
||||||
|
FC_ASSERT(owner_account != GRAPHENE_TEMP_ACCOUNT
|
||||||
|
&& owner_account != GRAPHENE_COMMITTEE_ACCOUNT
|
||||||
|
&& owner_account != GRAPHENE_WITNESS_ACCOUNT
|
||||||
|
&& owner_account != GRAPHENE_RELAXED_COMMITTEE_ACCOUNT,
|
||||||
|
"Custom permissions and account auths cannot be created for special accounts");
|
||||||
|
}
|
||||||
|
|
||||||
|
} } // graphene::chain
|
||||||
|
|
@ -43,6 +43,8 @@
|
||||||
#include <graphene/chain/tournament_object.hpp>
|
#include <graphene/chain/tournament_object.hpp>
|
||||||
#include <graphene/chain/match_object.hpp>
|
#include <graphene/chain/match_object.hpp>
|
||||||
#include <graphene/chain/game_object.hpp>
|
#include <graphene/chain/game_object.hpp>
|
||||||
|
#include <graphene/chain/custom_permission_object.hpp>
|
||||||
|
#include <graphene/chain/custom_account_authority_object.hpp>
|
||||||
|
|
||||||
#include <fc/smart_ref_impl.hpp>
|
#include <fc/smart_ref_impl.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue