提交 5812c402 编写于 作者: W Wang Zhi

new data structure for new BP election algorithm

上级 d319e965
......@@ -31,6 +31,15 @@
{"name":"key", "type":"public_key"},
{"name":"weight", "type":"weight_type"}
]
},{
"name": "prod_meta",
"base": "",
"fields": [
{"name":"owner", "type":"account_name"},
{"name":"total_votes", "type":"float64"},
{"name":"all_stake", "type":"int64"},
{"name":"is_active", "type":"bool"}
]
},{
"name": "bidname",
"base": "",
......@@ -278,6 +287,27 @@
{"name":"unpaid_blocks", "type":"uint32"},
{"name":"last_claim_time", "type":"uint64"},
{"name":"location", "type":"uint16"}
]
},{
"name": "producer_info_ext",
"base": "",
"fields": [
{"name":"owner", "type":"account_name"},
{"name":"seq_num", "type":"uint16"},
{"name":"all_stake", "type":"int64"}
]
},{
"name": "producers_seq",
"base": "",
"fields": [
{"name":"seq_num", "type":"uint16"},
{"name":"prods_l1", "type":"prod_meta"},
{"name":"prods_l2", "type":"prod_meta[]"},
{"name":"prods_l3", "type":"prod_meta[]"},
{"name":"prods_all", "type":"prod_meta[]"},
]
},{
"name": "regproducer",
......@@ -294,6 +324,18 @@
"fields": [
{"name":"producer", "type":"account_name"}
]
},{
"name": "clsprods2",
"base": "",
"fields": []
},{
"name": "seqproducer",
"base": "",
"fields": [
{"name":"producer", "type":"account_name"},
{"name":"seq", "type":"uint16"},
{"name":"level", "type":"uint8"}
]
},{
"name": "setram",
"base": "",
......@@ -488,6 +530,14 @@
"name": "unregprod",
"type": "unregprod",
"ricardian_contract": ""
},{
"name": "clsprods2",
"type": "clsprods2",
"ricardian_contract": ""
},{
"name": "seqproducer",
"type": "seqproducer",
"ricardian_contract": ""
},{
"name": "regproxy",
"type": "regproxy",
......@@ -535,6 +585,18 @@
"index_type": "i64",
"key_names" : ["owner"],
"key_types" : ["uint64"]
},{
"name": "producers2",
"type": "producer_info_ext",
"index_type": "i64",
"key_names" : ["owner"],
"key_types" : ["uint64"]
},{
"name": "produderseq",
"type": "producers_seq",
"index_type": "i64",
"key_names" : ["seq_num"],
"key_types" : ["uint64"]
},{
"name": "global",
"type": "eosio_global_state",
......
......@@ -13,6 +13,7 @@ namespace eosiosystem {
:native(s),
_voters(_self,_self),
_producers(_self,_self),
_producers2(_self,_self),
_global(_self,_self),
_rammarket(_self,_self)
{
......@@ -203,7 +204,7 @@ EOSIO_ABI( eosiosystem::system_contract,
// delegate_bandwidth.cpp
(buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund)
// voting.cpp
(regproducer)(unregprod)(voteproducer)(regproxy)
(regproducer)(unregprod)(voteproducer)(regproxy)(clsprods2)(seqproducer)
// producer_pay.cpp
(onblock)(claimrewards)
)
......@@ -89,6 +89,40 @@ namespace eosiosystem {
(unpaid_blocks)(last_claim_time)(location) )
};
//##YTA-Change start:
struct producer_info_ext {
account_name owner;
uint16_t seq_num = 1; // from 1 to 21
int64_t all_stake = 0;
uint64_t primary_key()const { return owner; }
EOSLIB_SERIALIZE( producer_info_ext, (owner)(seq_num) )
};
struct prod_meta {
account_name owner;
double total_votes = 0;
int64_t all_stake = 0;
bool is_active = true;
EOSLIB_SERIALIZE( prod_meta, (owner)(total_votes)(all_stake)(is_active) )
};
struct producers_seq {
uint16_t seq_num = 1; // from 1 to 21
prod_meta prods_l1; // only one
std::vector<prod_meta> prods_l2; //max 5
std::vector<prod_meta> prods_l3;
std::vector<prod_meta> prods_all;
uint64_t primary_key()const { return seq_num; }
EOSLIB_SERIALIZE( producers_seq, (seq_num)(prods_l1)(prods_l2)(prods_l3)(prods_all) )
};
//##YTA-Change end:
struct voter_info {
account_name owner = 0; /// the voter
account_name proxy = 0; /// the proxy set by the voter, if any
......@@ -127,6 +161,12 @@ namespace eosiosystem {
indexed_by<N(prototalvote), const_mem_fun<producer_info, double, &producer_info::by_votes> >
> producers_table;
//##YTA-Change start:
typedef eosio::multi_index< N(producers2), producer_info_ext> producers_ext_table;
typedef eosio::multi_index< N(produderseq), producers_seq> producers_seq_table;
//##YTA-Change end:
typedef eosio::singleton<N(global), eosio_global_state> global_state_singleton;
//##YTA-Change start:
......@@ -141,6 +181,9 @@ namespace eosiosystem {
private:
voters_table _voters;
producers_table _producers;
//##YTA-Change start:
producers_ext_table _producers2;
//##YTA-Change end:
global_state_singleton _global;
eosio_global_state _gstate;
......@@ -211,6 +254,22 @@ namespace eosiosystem {
void unregprod( const account_name producer );
//##YTA-Change start:
void clsprods2();
void seqproducer( const account_name producer, uint16_t seq , uint8_t level );
void rm_producer_seq( const account_name producer, uint16_t seq );
void add_producer_seq( const account_name producer, uint16_t seq , uint8_t level );
void active_producer_seq( const account_name producer, bool isactive);
void update_producers_seq_totalvotes( uint16_t seq_num, account_name owner, double total_votes);
//##YTA-Change end:
void setram( uint64_t max_ram_size );
void voteproducer( const account_name voter, const account_name proxy, const std::vector<account_name>& producers );
......@@ -230,6 +289,7 @@ namespace eosiosystem {
private:
void update_elected_producers( block_timestamp timestamp );
// Implementation details:
//defind in delegate_bandwidth.cpp
......
......@@ -48,6 +48,8 @@ namespace eosiosystem {
info.url = url;
info.location = location;
});
active_producer_seq(producer, true);
} else {
_producers.emplace( producer, [&]( producer_info& info ){
info.owner = producer;
......@@ -68,8 +70,202 @@ namespace eosiosystem {
_producers.modify( prod, 0, [&]( producer_info& info ){
info.deactivate();
});
active_producer_seq(producer, false);
}
//##YTA-Change start:
void system_contract::clsprods2() {
require_auth( _self );
while (_producers2.begin() != _producers2.end())
_producers2.erase(_producers2.begin());
for( uint16_t seq = 1; seq <= 21; seq++ ) {
producers_seq_table _prod_seq( _self, seq );
if( _prod_seq.begin() != _prod_seq.end() )
_prod_seq.erase(_prod_seq.begin());
}
}
void system_contract::seqproducer( const account_name producer, uint16_t seq , uint8_t level ) {
require_auth( _self );
eosio_assert(seq >= 1 && seq <= 21 , "invalidate seq number");
eosio_assert(level >= 1 && level <= 3 , "invalidate level number");
//const auto& prod = _producers.get( producer, "producer not found" );
auto it = _producers2.find(producer);
if (it == _producers2.end()) {
_producers2.emplace(_self, [&](auto &row) {
row.owner = producer;
row.seq_num = seq;
});
add_producer_seq(producer, seq, level);
} else {
uint16_t old_seq = it->seq_num;
_producers2.modify(it, _self, [&](auto &row) {
row.seq_num = seq;
});
rm_producer_seq(producer, old_seq);
add_producer_seq(producer, seq, level);
}
}
void system_contract::rm_producer_seq(const account_name producer, uint16_t seq) {
producers_seq_table _prodseq(_self, seq);
auto ps_itr = _prodseq.find (seq);
if( ps_itr == _prodseq.end() )
return;
_prodseq.modify( ps_itr, _self, [&]( producers_seq& info ){
if(info.prods_l1.owner == producer) {
info.prods_l1.owner = 0;
info.prods_l1.all_stake = 0;
info.prods_l1.total_votes = 0;
info.prods_l1.is_active = false;
}
for( auto it2 = info.prods_l2.begin(); it2 != info.prods_l2.end(); it2++ ) {
if(it2->owner == producer) {
info.prods_l2.erase(it2);
break;
}
}
for( auto it3 = info.prods_l3.begin(); it3 != info.prods_l3.end(); it3++ ) {
if(it3->owner == producer) {
info.prods_l3.erase(it3);
break;
}
}
for( auto itall = info.prods_all.begin(); itall != info.prods_all.end(); itall++ ) {
if(itall->owner == producer) {
info.prods_all.erase(itall);
break;
}
}
});
}
void system_contract::add_producer_seq( const account_name producer, uint16_t seq , uint8_t level ) {
producers_seq_table _prodseq(_self, seq);
prod_meta prodm;
//need retrive from system producers table
const auto& prod = _producers.get( producer, "producer not found" );
prodm.owner = producer;
prodm.all_stake = 0;
prodm.total_votes = prod.total_votes;
prodm.is_active = prod.is_active;
auto ps_itr = _prodseq.find (seq);
if( ps_itr == _prodseq.end() ) {
_prodseq.emplace(_self, [&](auto &row) {
row.seq_num = seq;
row.prods_all.push_back(prodm);
if(level == 1) {
row.prods_l1 = prodm;
} else if(level == 2) {
row.prods_l2.push_back(prodm);
} else if(level == 3) {
row.prods_l3.push_back(prodm);
}
});
} else {
_prodseq.modify(ps_itr, _self, [&](auto &row) {
row.prods_all.push_back(prodm);
if(level == 1) {
row.prods_l1 = prodm;
} else if(level == 2) {
row.prods_l2.push_back(prodm);
} else if(level == 3) {
row.prods_l3.push_back(prodm);
}
});
}
}
void system_contract::active_producer_seq( const account_name producer, bool isactive) {
auto it = _producers2.find(producer);
if (it == _producers2.end())
return;
uint16_t seq = it->seq_num;
producers_seq_table _prodseq(_self, seq);
auto ps_itr = _prodseq.find (seq);
if( ps_itr == _prodseq.end() )
return;
_prodseq.modify( ps_itr, _self, [&]( producers_seq& info ){
if(info.prods_l1.owner == producer) {
info.prods_l1.is_active = isactive;
}
for( auto it2 = info.prods_l2.begin(); it2 != info.prods_l2.end(); it2++ ) {
if(it2->owner == producer) {
it2->is_active = isactive;
break;
}
}
for( auto it3 = info.prods_l3.begin(); it3 != info.prods_l3.end(); it3++ ) {
if(it3->owner == producer) {
it3->is_active = isactive;
break;
}
}
for( auto itall = info.prods_all.begin(); itall != info.prods_all.end(); itall++ ) {
if(itall->owner == producer) {
itall->is_active = isactive;
break;
}
}
});
}
void system_contract::update_producers_seq_totalvotes( uint16_t seq_num, account_name owner, double total_votes) {
producers_seq_table _prodseq(_self, seq_num);
auto ps_itr = _prodseq.find (seq_num);
if( ps_itr == _prodseq.end() )
return;
_prodseq.modify( ps_itr, _self, [&]( producers_seq& info ){
if( info.prods_l1.owner == owner ) {
info.prods_l1.total_votes = total_votes;
//return;
}
for(auto it = info.prods_l2.begin(); it != info.prods_l2.end(); it++) {
if(it->owner == owner) {
it->total_votes = total_votes;
break;
}
}
for(auto it = info.prods_l3.begin(); it != info.prods_l3.end(); it++) {
if(it->owner == owner) {
it->total_votes = total_votes;
break;
}
}
for(auto it = info.prods_all.begin(); it != info.prods_all.end(); it++) {
if(it->owner == owner) {
it->total_votes = total_votes;
break;
}
}
});
}
//##YTA-Change ens:
void system_contract::update_elected_producers( block_timestamp block_time ) {
_gstate.last_producer_schedule_update = block_time;
......@@ -135,7 +331,11 @@ namespace eosiosystem {
eosio_assert( voter_name != proxy, "cannot proxy to self" );
require_recipient( proxy );
} else {
eosio_assert( producers.size() <= 30, "attempt to vote for too many producers" );
//##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" );
//##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" );
}
......@@ -201,6 +401,7 @@ namespace eosiosystem {
}
for( const auto& pd : producer_deltas ) {
double total_votes = 0;
auto pitr = _producers.find( pd.first );
if( pitr != _producers.end() ) {
eosio_assert( !voting || pitr->active() || !pd.second.second /* not from new set */, "producer is not currently registered" );
......@@ -211,10 +412,22 @@ namespace eosiosystem {
}
_gstate.total_producer_vote_weight += pd.second.first;
//eosio_assert( p.total_votes >= 0, "something bad happened" );
total_votes = p.total_votes;
});
} else {
eosio_assert( !pd.second.second /* not from new set */, "producer is not registered" ); //data corruption
}
//##YTA-Change start:
auto pitr2 = _producers2.find( pd.first );
if( pitr2 != _producers2.end() ) {
//pitr2->seq_num
update_producers_seq_totalvotes(pitr2->seq_num, pd.first, total_votes);
} else {
eosio_assert( !pd.second.second /* not from new set */, "producer is not registered" ); //data corruption
}
//##YTA-Change end:
}
_voters.modify( voter, 0, [&]( auto& av ) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册