SON232 - Avoid duplicate proposals from sidechain plugin (#275)

This commit is contained in:
satyakoneru 2020-01-31 22:58:07 +11:00 committed by GitHub
parent 21c8337753
commit b952522b01
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 36 additions and 5 deletions

View file

@ -179,6 +179,21 @@ std::set<son_id_type> database::get_sons_to_be_deregistered()
return ret;
}
std::set<son_id_type> database::get_sons_being_reported_down()
{
std::set<son_id_type> ret;
const auto& son_proposal_idx = get_index_type<son_proposal_index>().indices().get< by_id >();
for( auto& son_proposal : son_proposal_idx )
{
if(son_proposal.proposal_type == son_proposal_type::son_report_down_proposal)
{
ret.insert(son_proposal.son_id);
}
}
return ret;
}
fc::optional<operation> database::create_son_deregister_proposal(const son_id_type& son_id, const witness_object& current_witness )
{
son_delete_operation son_dereg_op;
@ -235,7 +250,8 @@ void database::process_son_proposals( const witness_object& current_witness, con
void database::remove_son_proposal( const proposal_object& proposal )
{ try {
if( proposal.proposed_transaction.operations.size() == 1 &&
( proposal.proposed_transaction.operations.back().which() == operation::tag<son_delete_operation>::value) )
( proposal.proposed_transaction.operations.back().which() == operation::tag<son_delete_operation>::value ||
proposal.proposed_transaction.operations.back().which() == operation::tag<son_report_down_operation>::value) )
{
const auto& son_proposal_idx = get_index_type<son_proposal_index>().indices().get<by_proposal>();
auto son_proposal_itr = son_proposal_idx.find( proposal.id );

View file

@ -224,6 +224,7 @@ void database::clear_expired_proposals()
elog("Failed to apply proposed transaction on its expiration. Deleting it.\n${proposal}\n${error}",
("proposal", proposal)("error", e.to_detail_string()));
}
remove_son_proposal(proposal);
remove(proposal);
}
}

View file

@ -300,6 +300,7 @@ namespace graphene { namespace chain {
std::vector<uint32_t> get_seeds( asset_id_type for_asset, uint8_t count_winners )const;
uint64_t get_random_bits( uint64_t bound );
std::set<son_id_type> get_sons_being_deregistered();
std::set<son_id_type> get_sons_being_reported_down();
std::set<son_id_type> get_sons_to_be_deregistered();
fc::optional<operation> create_son_deregister_proposal(const son_id_type& son_id, const witness_object& current_witness );
signed_transaction create_signed_transaction( const fc::ecc::private_key& signing_private_key, const operation& op );

View file

@ -43,6 +43,7 @@ namespace graphene { namespace chain {
void operator()( const T &v ) const {}
void operator()( const son_delete_operation &v );
void operator()( const son_report_down_operation &v );
};
class proposal_create_evaluator : public evaluator<proposal_create_evaluator>

View file

@ -8,7 +8,8 @@ namespace graphene { namespace chain {
enum class son_proposal_type
{
son_deregister_proposal
son_deregister_proposal,
son_report_down_proposal
};
class son_proposal_object : public abstract_object<son_proposal_object>
@ -36,6 +37,6 @@ using son_proposal_index = generic_index<son_proposal_object, son_proposal_multi
} } // graphene::chain
FC_REFLECT_ENUM(graphene::chain::son_proposal_type, (son_deregister_proposal) )
FC_REFLECT_ENUM( graphene::chain::son_proposal_type, (son_deregister_proposal)(son_report_down_proposal) )
FC_REFLECT_DERIVED( graphene::chain::son_proposal_object, (graphene::chain::object), (proposal_id)(son_id)(proposal_type) )

View file

@ -176,6 +176,15 @@ void son_hardfork_visitor::operator()( const son_delete_operation &v )
});
}
void son_hardfork_visitor::operator()( const son_report_down_operation &v )
{
db.create<son_proposal_object>([&]( son_proposal_object& son_prop ) {
son_prop.proposal_type = son_proposal_type::son_report_down_proposal;
son_prop.proposal_id = prop_id;
son_prop.son_id = v.son_id;
});
}
void_result proposal_create_evaluator::do_evaluate(const proposal_create_operation& o)
{ try {
const database& d = db();

View file

@ -248,10 +248,12 @@ void peerplays_sidechain_plugin_impl::create_son_down_proposals()
chain::database& d = plugin.database();
const chain::global_property_object& gpo = d.get_global_properties();
const auto& idx = d.get_index_type<chain::son_index>().indices().get<by_id>();
std::set<son_id_type> sons_being_reported_down = d.get_sons_being_reported_down();
chain::son_id_type my_son_id = *(_sons.begin());
for(auto son_inf: gpo.active_sons) {
if(my_son_id == son_inf.son_id)
if(my_son_id == son_inf.son_id || (sons_being_reported_down.find(son_inf.son_id) != sons_being_reported_down.end())){
continue;
}
auto son_obj = idx.find( son_inf.son_id );
auto stats = son_obj->statistics(d);
fc::time_point_sec last_active_ts = stats.last_active_timestamp;
@ -339,7 +341,7 @@ void peerplays_sidechain_plugin_impl::on_objects_new(const vector<object_id_type
if( object_id.is<chain::proposal_object>() ) {
const object* obj = d.find_object(object_id);
const chain::proposal_object* proposal = dynamic_cast<const chain::proposal_object*>(obj);
if(proposal == nullptr) {
if(proposal == nullptr || (proposal->available_active_approvals.find(son_obj->son_account) != proposal->available_active_approvals.end())) {
return;
}