提交 4e8d0a1d 编写于 作者: K Khaled Al-Hassanieh

Optimize update_elected_producers

上级 11302d79
......@@ -273,6 +273,7 @@
{"name":"owner", "type":"account_name"},
{"name":"total_votes", "type":"float64"},
{"name":"producer_key", "type":"public_key"},
{"name":"is_active", "type":"bool"},
{"name":"url", "type":"string"},
{"name":"unpaid_blocks", "type":"uint32"},
{"name":"last_claim_time", "type":"uint64"},
......
......@@ -74,6 +74,7 @@ namespace eosiosystem {
account_name owner;
double total_votes = 0;
eosio::public_key producer_key; /// a packed public key object
bool is_active = true;
std::string url;
uint32_t unpaid_blocks = 0;
uint64_t last_claim_time = 0;
......@@ -81,12 +82,13 @@ namespace eosiosystem {
block_timestamp time_became_active;
block_timestamp last_produced_block_time;
uint64_t primary_key()const { return owner; }
double by_votes()const { return -total_votes; }
bool active() const { return producer_key != public_key(); }
uint64_t primary_key()const { return owner; }
double by_votes()const { return is_active ? -total_votes : total_votes; }
bool active()const { return is_active; }
void deactivate() { producer_key = public_key(); is_active = false; }
// explicit serialization macro is not necessary, used here only to improve compilation time
EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(producer_key)(url)
EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(producer_key)(is_active)(url)
(unpaid_blocks)(last_claim_time)(location)
(time_became_active)(last_produced_block_time) )
};
......
......@@ -36,6 +36,7 @@ namespace eosiosystem {
*/
void system_contract::regproducer( const account_name producer, const eosio::public_key& producer_key, const std::string& url, uint16_t location ) {
eosio_assert( url.size() < 512, "url too long" );
eosio_assert( producer_key != eosio::public_key(), "public key should not be the default value" );
require_auth( producer );
auto prod = _producers.find( producer );
......@@ -44,6 +45,7 @@ namespace eosiosystem {
if( producer_key != prod->producer_key ) {
_producers.modify( prod, producer, [&]( producer_info& info ){
info.producer_key = producer_key;
info.is_active = true;
info.url = url;
info.location = location;
});
......@@ -53,6 +55,7 @@ namespace eosiosystem {
info.owner = producer;
info.total_votes = 0;
info.producer_key = producer_key;
info.is_active = true;
info.url = url;
info.location = location;
});
......@@ -65,7 +68,7 @@ namespace eosiosystem {
const auto& prod = _producers.get( producer, "producer not found" );
_producers.modify( prod, 0, [&]( producer_info& info ){
info.producer_key = eosio::public_key();
info.deactivate();
});
}
......@@ -77,8 +80,8 @@ namespace eosiosystem {
std::vector< std::pair<eosio::producer_key,uint16_t> > top_producers;
top_producers.reserve(21);
for ( auto it = idx.cbegin(); it != idx.cend() && top_producers.size() < 21 && 0 < it->total_votes; ++it ) {
if( !it->active() ) continue;
std::vector<decltype(idx.cbegin())> inactive_iters;
for ( auto it = idx.cbegin(); it != idx.cend() && top_producers.size() < 21 && 0 < it->total_votes && it->active(); ++it ) {
/**
If it's the first time or it's been over a day since a producer was last voted in,
......@@ -92,11 +95,8 @@ namespace eosiosystem {
});
} else if ( block_time.slot > (2 * 21 * 12 * 100) + it->time_became_active.slot &&
block_time.slot > it->last_produced_block_time.slot + blocks_per_day ) {
_producers.modify( *it, 0, [&](auto& p) {
p.producer_key = public_key();
p.time_became_active.slot = 0;
});
// save producers that will be deactivated
inactive_iters.push_back(it);
continue;
} else {
_producers.modify( *it, 0, [&](auto& p) {
......@@ -107,7 +107,12 @@ namespace eosiosystem {
top_producers.emplace_back( std::pair<eosio::producer_key,uint16_t>({{it->owner, it->producer_key}, it->location}));
}
for (const auto& it: inactive_iters) {
_producers.modify( *it, 0, [&](auto& p) {
p.deactivate();
p.time_became_active.slot = 0;
});
}
/// sort by producer name
std::sort( top_producers.begin(), top_producers.end() );
......@@ -234,7 +239,7 @@ namespace eosiosystem {
eosio_assert( !voting || pitr->active() || !pd.second.second /* not from new set */, "producer is not currently registered" );
_producers.modify( pitr, 0, [&]( auto& p ) {
p.total_votes += pd.second.first;
if ( p.total_votes < 0 ) { // floating point ariphmetics can give as small negative numbers
if ( p.total_votes < 0 ) { // floating point arithmetics can give small negative numbers
p.total_votes = 0;
}
_gstate.total_producer_vote_weight += pd.second.first;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册