From fbd30bad1afabf0bdedaf329a809e6d1ae172685 Mon Sep 17 00:00:00 2001 From: Wang Zhi Date: Fri, 19 Jul 2019 12:45:06 +0800 Subject: [PATCH] implement YTA chain BP election policy --- contracts/eosio.system/eosio.system.hpp | 29 ++++++ contracts/eosio.system/voting.cpp | 130 +++++++++++++++++++++++- 2 files changed, 156 insertions(+), 3 deletions(-) diff --git a/contracts/eosio.system/eosio.system.hpp b/contracts/eosio.system/eosio.system.hpp index 528cfec5c..e635e497b 100644 --- a/contracts/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/eosio.system.hpp @@ -136,6 +136,33 @@ namespace eosiosystem { }; //##YTA-Change end: + //##YTA-Change start: + struct yta_prod_info { + account_name owner; + double total_votes = 0; // total votes + eosio::public_key producer_key; /// a packed public key object + int64_t all_stake = 0; // total original votes (buy yta amount) + bool is_active = true; + std::string url; + uint16_t location = 0; + bool is_in_grace; //是否处在补齐投票的宽限期 + uint64_t grace_start_time = 0; //宽限期的开始时间 + + EOSLIB_SERIALIZE( yta_prod_info, (owner)(total_votes)(producer_key)(all_stake)(is_active)(url)(location)(is_in_grace)(grace_start_time) ) + + }; + + struct all_prods_level { + std::vector prods_l1; //max 21 + std::vector prods_l2; //max 105 + std::vector prods_l3; + + EOSLIB_SERIALIZE( all_prods_level, (prods_l1)(prods_l2)(prods_l3) ) + }; + typedef eosio::singleton all_prods_singleton; + + //##YTA-Change end: + struct voter_info { account_name owner = 0; /// the voter account_name proxy = 0; /// the proxy set by the voter, if any @@ -300,6 +327,8 @@ namespace eosiosystem { void update_elected_producers( block_timestamp timestamp ); //##YTA-Change start: + void update_elected_producers_yta2( block_timestamp timestamp ); + void update_elected_producers_yta( block_timestamp timestamp ); std::pair getProducerForSeq(uint64_t seq_num ); diff --git a/contracts/eosio.system/voting.cpp b/contracts/eosio.system/voting.cpp index 554d0016e..60cdfb490 100644 --- a/contracts/eosio.system/voting.cpp +++ b/contracts/eosio.system/voting.cpp @@ -401,6 +401,130 @@ namespace eosiosystem { } + const uint64_t useconds_per_day_v = 24 * 3600 * uint64_t(1000000); + + void system_contract::update_elected_producers_yta2( block_timestamp block_time ) { + + all_prods_singleton _all_prods(_self, _self); + all_prods_level _all_prods_state; + + if (!_all_prods.exists()) + return; + + for( auto it =_all_prods_state.prods_l1.begin(); it != _all_prods_state.prods_l1.end(); it++ ) { + bool is_remove = false; + if(!it->is_active) + is_remove = true; + if(it->total_votes < 50000000000) { + if(it->is_in_grace) { + if(current_time() - it->grace_start_time > useconds_per_day_v) { + is_remove = true; + it->is_in_grace = false; + } + + } else { + it->is_in_grace = true; + auto ct = current_time(); + it->grace_start_time = ct; + } + } else { + it->is_in_grace = false; + } + + if(is_remove) { + _all_prods_state.prods_l3.push_back(*it); + _all_prods_state.prods_l1.erase(it); + } + } + + for( auto it =_all_prods_state.prods_l2.begin(); it != _all_prods_state.prods_l2.end(); it++ ) { + bool is_remove = false; + if(!it->is_active) + is_remove = true; + if(it->total_votes < 20000000000) { + if(it->is_in_grace) { + if(current_time() - it->grace_start_time > useconds_per_day_v) { + is_remove = true; + it->is_in_grace = false; + } + + } else { + it->is_in_grace = true; + auto ct = current_time(); + it->grace_start_time = ct; + } + } else { + it->is_in_grace = false; + } + + if(is_remove) { + _all_prods_state.prods_l3.push_back(*it); + _all_prods_state.prods_l2.erase(it); + } + } + + std::sort(_all_prods_state.prods_l2.begin(), _all_prods_state.prods_l2.end(), [&](yta_prod_info lhs, yta_prod_info rhs){return lhs.total_votes > rhs.total_votes;}); + for( auto it =_all_prods_state.prods_l2.begin(); it != _all_prods_state.prods_l2.end(); it++ ) { + if(it->total_votes >= 50000000000) { + if(_all_prods_state.prods_l1.size() < 21) { + _all_prods_state.prods_l1.push_back(*it); + _all_prods_state.prods_l2.erase(it); + } else { + break; + } + } + } + + std::sort(_all_prods_state.prods_l3.begin(), _all_prods_state.prods_l3.end(), [&](yta_prod_info lhs, yta_prod_info rhs){return lhs.total_votes > rhs.total_votes;}); + for( auto it =_all_prods_state.prods_l3.begin(); it != _all_prods_state.prods_l3.end(); it++ ) { + if(it->total_votes >= 20000000000) { + if(_all_prods_state.prods_l3.size() < 105) { + _all_prods_state.prods_l2.push_back(*it); + _all_prods_state.prods_l3.erase(it); + } else { + break; + } + } + } + + _all_prods.set(_all_prods_state, _self); + + ///--------------------------------------------------- + + _gstate.last_producer_schedule_update = block_time; + + std::vector< std::pair > top_producers; + top_producers.reserve(21); + + for( auto it =_all_prods_state.prods_l1.begin(); it != _all_prods_state.prods_l1.end(); it++ ) { + top_producers.emplace_back( std::pair({{it->owner, it->producer_key}, it->location}) ); + } + + if ( top_producers.size() < _gstate.last_producer_schedule_size ) { + if(top_producers.size() < 7) + return; + } + + /// sort by producer name + std::sort( top_producers.begin(), top_producers.end() ); + + std::vector producers; + + producers.reserve(top_producers.size()); + for( const auto& item : top_producers ) + producers.push_back(item.first); + + bytes packed_schedule = pack(producers); + + + if( set_proposed_producers( packed_schedule.data(), packed_schedule.size() ) >= 0 ) { + _gstate.last_producer_schedule_size = static_cast( top_producers.size() ); + } + + + } + + void system_contract::update_elected_producers_yta( block_timestamp block_time ) { _gstate.last_producer_schedule_update = block_time; @@ -536,8 +660,8 @@ namespace eosiosystem { void system_contract::voteproducer( const account_name voter_name, const account_name proxy, const std::vector& producers ) { require_auth( voter_name ); ///@@@@@@@@@@@@@@@@@@@@@ - eosio_assert(1 == 2, "can not vote now."); - return; + //eosio_assert(1 == 2, "can not vote now."); + //return; ///@@@@@@@@@@@@@@@@@@@@ update_votes( voter_name, proxy, producers, true ); @@ -553,7 +677,7 @@ namespace eosiosystem { //##YTA-Change start: //eosio_assert( producers.size() <= 30, "attempt to vote for too many producers" ); // One voter can only vote for one producer - eosio_assert( producers.size() <= 1, "attempt to vote for too many producers" ); + eosio_assert( producers.size() <= 30, "attempt to vote for too many producers" ); //##YTA-Change end: for( size_t i = 1; i < producers.size(); ++i ) { eosio_assert( producers[i-1] < producers[i], "producer votes must be unique and sorted" ); -- GitLab