Skip to content

Commit

Permalink
Bdev5 (EOSIO#61)
Browse files Browse the repository at this point in the history
* update blacklist logic
  • Loading branch information
vlbos authored and Thaipanda committed Mar 22, 2019
1 parent d21e72a commit 4874ef0
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 81 deletions.
195 changes: 117 additions & 78 deletions libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ struct controller_impl {
resource_limits_manager resource_limits;
authorization_manager authorization;
controller::config conf;
controller::config multisig_blacklists;///< multisig blacklists in memory
chain_id_type chain_id;
bool replaying= false;
optional<fc::time_point> replay_head_time;
Expand Down Expand Up @@ -406,9 +407,7 @@ struct controller_impl {
}

//*bos begin*
sync_name_list(list_type::actor_blacklist_type,true);
sync_name_list(list_type::contract_blacklist_type,true);
sync_name_list(list_type::resource_greylist_type,true);
merge_msig_blacklist_into_conf();
//*bos end*
}

Expand Down Expand Up @@ -693,78 +692,137 @@ struct controller_impl {
}

// "bos begin"
// contract wasm interface api set_name_list function
// insert action db_list U msig_list -> msig_list db_list U conf_list -> conf_list
// name_list U msig_list -> msig_list name_list U conf_list -> conf_list msig_list->db_list
// remove action db_list U msig_list -> msig_list db_list U conf_list -> conf_list
// msig_list-name_list -> msig_list conf_list - name_list -> conf_list msig_list->db_list
// producer api set_whitelist_blacklist
// blacklst -> conf.xxx_blacklist conf_list U msig_list -> conf_list
// remove_grey_list
// check if remove acount in msig_list then assert fail could not remove account in msig blacklist
void set_name_list(list_type list, list_action_type action, std::vector<account_name> name_list)
{
int64_t lst = static_cast<int64_t>(list);
//set list from set_name_list action in system contract
EOS_ASSERT(action >= list_action_type::insert_type && action < list_action_type::list_action_type_count, transaction_exception, "unknown action: ${action}", ("action", static_cast<int64_t>(action)));
int64_t blacklist_type = static_cast<int64_t>(list);
const auto &gp2o = db.get<global_property2_object>();
auto update_blacklists = [&](const shared_vector<account_name> &db_blacklist, flat_set<account_name> &conf_blacklist, flat_set<account_name> &msig_blacklist){
for (auto &a : db_blacklist){
conf_blacklist.insert(a);
msig_blacklist.insert(a);
}

EOS_ASSERT(list >= list_type::actor_blacklist_type && list < list_type::list_type_count, transaction_exception, "unknown list type : ${l}, action: ${n}", ("l", static_cast<int64_t>(list))("n", static_cast<int64_t>(action)));
vector<flat_set<account_name> *> lists = {&conf.actor_blacklist, &conf.contract_blacklist, &conf.resource_greylist};
EOS_ASSERT(lists.size() == static_cast<int64_t>(list_type::list_type_count) - 1, transaction_exception, " list size wrong : ${l}, action: ${n}", ("l", static_cast<int64_t>(list))("n", static_cast<int64_t>(action)));
auto update_blacklist = [&](auto &blacklist) {
if (action == list_action_type::insert_type){
blacklist.insert(name_list.begin(), name_list.end());
}
else if (action == list_action_type::remove_type){
flat_set<account_name> name_set(name_list.begin(), name_list.end());
flat_set<account_name> results;
results.reserve(blacklist.size());
set_difference(blacklist.begin(), blacklist.end(),
name_set.begin(), name_set.end(),
std::inserter(results, results.begin()));

blacklist = results;
}
};

flat_set<account_name> &lo = *lists[lst - 1];
update_blacklist(conf_blacklist);
update_blacklist(msig_blacklist);

if (action == list_action_type::insert_type)
{
lo.insert(name_list.begin(), name_list.end());
}
else if (action == list_action_type::remove_type)
{
flat_set<account_name> name_set(name_list.begin(), name_list.end());
auto insert_blacklists = [&](auto &gp2) {
auto insert_blacklist = [&](shared_vector<account_name> &blacklist) {
blacklist.clear();

for (auto &a : msig_blacklist){
blacklist.push_back(a);
}
};

switch (list){
case list_type::actor_blacklist_type:
insert_blacklist(gp2.cfg.actor_blacklist);
break;
case list_type::contract_blacklist_type:
insert_blacklist(gp2.cfg.contract_blacklist);
break;
case list_type::resource_greylist_type:
insert_blacklist(gp2.cfg.resource_greylist);
break;
default:
EOS_ASSERT(false, transaction_exception,
"unknown list type : ${blklsttype}", ("blklsttype", blacklist_type));
}
};

flat_set<account_name> results;
results.reserve(lo.size());
set_difference(lo.begin(), lo.end(),
name_set.begin(), name_set.end(),
std::inserter(results,results.begin()));
db.modify(gp2o, [&](auto &gp2) {
insert_blacklists(gp2);
});
};

lo = results;
switch (list){
case list_type::actor_blacklist_type:
update_blacklists(gp2o.cfg.actor_blacklist, conf.actor_blacklist, multisig_blacklists.actor_blacklist);
break;
case list_type::contract_blacklist_type:
update_blacklists(gp2o.cfg.contract_blacklist, conf.contract_blacklist, multisig_blacklists.contract_blacklist);
break;
case list_type::resource_greylist_type:
update_blacklists(gp2o.cfg.resource_greylist, conf.resource_greylist, multisig_blacklists.resource_greylist);
break;
default:
EOS_ASSERT(false, transaction_exception,
"unknown list type : ${blklsttype}", ("blklsttype", blacklist_type));
}
}

sync_name_list(list);
void check_msig_blacklist(list_type blacklist_type,account_name account)
{
auto check_blacklist = [&](const flat_set<account_name>& msig_blacklist){
EOS_ASSERT(msig_blacklist.find(account) == msig_blacklist.end(), transaction_exception,
" do not remove account in multisig blacklist , account: ${account}", ("account", account));
};

switch (blacklist_type)
{
case list_type::actor_blacklist_type:
check_blacklist(multisig_blacklists.actor_blacklist);
break;
case list_type::contract_blacklist_type:
check_blacklist(multisig_blacklists.contract_blacklist);
break;
case list_type::resource_greylist_type:
check_blacklist(multisig_blacklists.resource_greylist);
break;
default:
EOS_ASSERT(false, transaction_exception,
"unknown list type : ${blklsttype}, account: ${account}", ("blklsttype",static_cast<uint64_t>(blacklist_type))("account", account));
}
}

void sync_list_and_db(list_type list, global_property2_object &gprops2,bool isMerge=false)
void merge_msig_blacklist_into_conf()
{
int64_t lst = static_cast<int64_t>(list);
EOS_ASSERT( list >= list_type::actor_blacklist_type && list < list_type::list_type_count, transaction_exception, "unknown list type : ${l}, ismerge: ${n}", ("l", static_cast<int64_t>(list))("n", isMerge));
vector<shared_vector<account_name> *> lists = {&gprops2.cfg.actor_blacklist, &gprops2.cfg.contract_blacklist, &gprops2.cfg.resource_greylist};
vector<flat_set<account_name> *> conflists = {&conf.actor_blacklist, &conf.contract_blacklist, &conf.resource_greylist};
EOS_ASSERT(lists.size() == static_cast<int64_t>(list_type::list_type_count) - 1, transaction_exception, " list size wrong : ${l}, ismerge: ${n}", ("l", static_cast<int64_t>(list))("n", isMerge));
shared_vector<account_name> &lo = *lists[lst - 1];
flat_set<account_name> &clo = *conflists[lst - 1];

if (isMerge)
{
//initialize, merge elements and deduplication between list and db.result save to list
for (auto &a : lo)
try{
auto merge_blacklist = [&](const shared_vector<account_name>& msig_blacklist_in_db,flat_set<account_name>& conf_blacklist){

for (auto& a : msig_blacklist_in_db)
{
clo.insert(a);
conf_blacklist.insert(a);
}
}
};

//clear list from db and save merge result to db object
lo.clear();
for (auto &a : clo)
{
lo.push_back(a);
}
}

void sync_name_list(list_type list,bool isMerge=false)
{
try
{
const auto &gpo2 = db.get<global_property2_object>();
db.modify(gpo2, [&](auto &gprops2) {
sync_list_and_db(list, gprops2, isMerge);
});
const auto &gp2o = db.get<global_property2_object>();
merge_blacklist(gp2o.cfg.actor_blacklist,conf.actor_blacklist);
merge_blacklist(gp2o.cfg.contract_blacklist,conf.contract_blacklist);
merge_blacklist(gp2o.cfg.resource_greylist,conf.resource_greylist);
}
catch (...)
{
wlog("plugin initialize sync list ignore before initialize database");
wlog("when plugin initialize,execute merge multsig blacklist to ignore exception before create global property2 object");
}
}

// "bos end"

/**
Expand Down Expand Up @@ -1936,21 +1994,15 @@ void controller::set_actor_whitelist( const flat_set<account_name>& new_actor_wh
}
void controller::set_actor_blacklist( const flat_set<account_name>& new_actor_blacklist ) {
my->conf.actor_blacklist = new_actor_blacklist;

// *bos begin*
my->sync_name_list(list_type::actor_blacklist_type);
// *bos end*
my->merge_msig_blacklist_into_conf(); ///bos merge multisig blacklist into conf after api reset blacklist
}
void controller::set_contract_whitelist( const flat_set<account_name>& new_contract_whitelist ) {
my->conf.contract_whitelist = new_contract_whitelist;
}
void controller::set_contract_blacklist( const flat_set<account_name>& new_contract_blacklist ) {
my->conf.contract_blacklist = new_contract_blacklist;

// *bos begin*
my->sync_name_list(list_type::contract_blacklist_type);
// *bos end*

my->conf.contract_blacklist = new_contract_blacklist;
my->merge_msig_blacklist_into_conf(); ///bos merge multisig blacklist into conf after api reset blacklist
}
void controller::set_action_blacklist( const flat_set< pair<account_name, action_name> >& new_action_blacklist ) {
for (auto& act: new_action_blacklist) {
Expand Down Expand Up @@ -2318,19 +2370,11 @@ void controller::set_subjective_cpu_leeway(fc::microseconds leeway) {

void controller::add_resource_greylist(const account_name &name) {
my->conf.resource_greylist.insert(name);

// *bos begin*
my->sync_name_list(list_type::resource_greylist_type);
// *bos end*
}

void controller::remove_resource_greylist(const account_name &name) {

my->check_msig_blacklist(list_type::resource_greylist_type, name);///bos
my->conf.resource_greylist.erase(name);

// *bos begin*
my->sync_name_list(list_type::resource_greylist_type);
// *bos end*
}

bool controller::is_resource_greylisted(const account_name &name) const {
Expand All @@ -2348,11 +2392,6 @@ const global_property2_object& controller::get_global_properties2()const {

void controller::set_name_list(int64_t list, int64_t action, std::vector<account_name> name_list)
{
//redundant sync
my->sync_name_list(list_type::actor_blacklist_type, true);
my->sync_name_list(list_type::contract_blacklist_type, true);
my->sync_name_list(list_type::resource_greylist_type, true);

my->set_name_list(static_cast<list_type>(list), static_cast<list_action_type>(action), name_list);
}
// *bos end*
Expand Down
4 changes: 1 addition & 3 deletions libraries/chain/include/eosio/chain/controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,9 +229,7 @@ namespace eosio { namespace chain {
// *bos begin*
const global_property2_object& get_global_properties2()const; // *bos*
void set_name_list(int64_t list, int64_t action, std::vector<account_name> name_list);

// void list_add_name(const int list, const account_name &name);
// void list_remove_name(const int list, const account_name &name);

// *bos end*

bool is_resource_greylisted(const account_name &name) const;
Expand Down

0 comments on commit 4874ef0

Please sign in to comment.