Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

blacklist on chain #52

Closed
wants to merge 5 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
186 changes: 109 additions & 77 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 @@ -695,76 +694,125 @@ struct controller_impl {
// "bos begin"
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
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.actor_blacklist);
break;
case list_type::resource_greylist_type:
insert_blacklist(gp2.cfg.actor_blacklist);
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.actor_blacklist, conf.contract_blacklist, multisig_blacklists.contract_blacklist);
break;
case list_type::resource_greylist_type:
update_blacklists(gp2o.cfg.actor_blacklist, 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.actor_blacklist);
break;
case list_type::resource_greylist_type:
check_blacklist(multisig_blacklists.actor_blacklist);
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 +1984,12 @@ 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*
}
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;
}
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 +2357,17 @@ 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->conf.resource_greylist.erase(name);

// *bos begin*
my->sync_name_list(list_type::resource_greylist_type);
my->check_msig_blacklist(list_type::resource_greylist_type,name);
// *bos end*

my->conf.resource_greylist.erase(name);


}

bool controller::is_resource_greylisted(const account_name &name) const {
Expand All @@ -2348,11 +2385,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