Fix replay blockchain
This commit is contained in:
parent
559769db2b
commit
da3a858aa6
41 changed files with 629 additions and 369 deletions
|
|
@ -196,8 +196,8 @@ public:
|
|||
fc::optional<son_object> get_son_by_account(const std::string account_id_or_name) const;
|
||||
map<string, son_id_type> lookup_son_accounts(const string &lower_bound_name, uint32_t limit) const;
|
||||
uint64_t get_son_count() const;
|
||||
flat_map<sidechain_type, vector<son_info>> get_active_sons();
|
||||
vector<son_info> get_active_sons_by_sidechain(sidechain_type sidechain);
|
||||
flat_map<sidechain_type, vector<son_sidechain_info>> get_active_sons();
|
||||
vector<son_sidechain_info> get_active_sons_by_sidechain(sidechain_type sidechain);
|
||||
map<sidechain_type, map<son_id_type, string>> get_son_network_status();
|
||||
map<son_id_type, string> get_son_network_status_by_sidechain(sidechain_type sidechain);
|
||||
|
||||
|
|
@ -1877,22 +1877,22 @@ uint64_t database_api_impl::get_son_count() const {
|
|||
return _db.get_index_type<son_index>().indices().size();
|
||||
}
|
||||
|
||||
flat_map<sidechain_type, vector<son_info>> database_api::get_active_sons() {
|
||||
flat_map<sidechain_type, vector<son_sidechain_info>> database_api::get_active_sons() {
|
||||
return my->get_active_sons();
|
||||
}
|
||||
|
||||
flat_map<sidechain_type, vector<son_info>> database_api_impl::get_active_sons() {
|
||||
flat_map<sidechain_type, vector<son_sidechain_info>> database_api_impl::get_active_sons() {
|
||||
return get_global_properties().active_sons;
|
||||
}
|
||||
|
||||
vector<son_info> database_api::get_active_sons_by_sidechain(sidechain_type sidechain) {
|
||||
vector<son_sidechain_info> database_api::get_active_sons_by_sidechain(sidechain_type sidechain) {
|
||||
return my->get_active_sons_by_sidechain(sidechain);
|
||||
}
|
||||
|
||||
vector<son_info> database_api_impl::get_active_sons_by_sidechain(sidechain_type sidechain) {
|
||||
vector<son_sidechain_info> database_api_impl::get_active_sons_by_sidechain(sidechain_type sidechain) {
|
||||
const global_property_object &gpo = get_global_properties();
|
||||
|
||||
vector<son_info> result;
|
||||
vector<son_sidechain_info> result;
|
||||
|
||||
if (gpo.active_sons.find(sidechain) != gpo.active_sons.end()) {
|
||||
result = gpo.active_sons.at(sidechain);
|
||||
|
|
@ -1908,7 +1908,7 @@ map<sidechain_type, map<son_id_type, string>> database_api::get_son_network_stat
|
|||
map<sidechain_type, map<son_id_type, string>> database_api_impl::get_son_network_status() {
|
||||
map<sidechain_type, map<son_id_type, string>> result;
|
||||
|
||||
for (auto active_sidechain_type : active_sidechain_types) {
|
||||
for (auto active_sidechain_type : active_sidechain_types(_db.head_block_time())) {
|
||||
result[active_sidechain_type] = get_son_network_status_by_sidechain(active_sidechain_type);
|
||||
}
|
||||
|
||||
|
|
@ -2340,7 +2340,9 @@ votes_info database_api_impl::get_votes(const string &account_name_or_id) const
|
|||
votes_for_sons[sidechain].reserve(sidechain_ids.size());
|
||||
for (const auto &son : sidechain_ids) {
|
||||
const auto &son_obj = son.as<son_object>(6);
|
||||
votes_for_sons[sidechain].emplace_back(votes_info_object{son_obj.get_sidechain_vote_id(sidechain), son_obj.id});
|
||||
if(son_obj.get_sidechain_vote_id(sidechain).valid()) {
|
||||
votes_for_sons[sidechain].emplace_back(votes_info_object{*son_obj.get_sidechain_vote_id(sidechain), son_obj.id});
|
||||
}
|
||||
}
|
||||
}
|
||||
result.votes_for_sons = std::move(votes_for_sons);
|
||||
|
|
|
|||
|
|
@ -695,14 +695,14 @@ public:
|
|||
* @brief Get list of active sons
|
||||
* @return List of active SONs
|
||||
*/
|
||||
flat_map<sidechain_type, vector<son_info>> get_active_sons();
|
||||
flat_map<sidechain_type, vector<son_sidechain_info>> get_active_sons();
|
||||
|
||||
/**
|
||||
* @brief Get list of active sons
|
||||
* @param sidechain Sidechain type [bitcoin|ethereum|hive]
|
||||
* @return List of active SONs
|
||||
*/
|
||||
vector<son_info> get_active_sons_by_sidechain(sidechain_type sidechain);
|
||||
vector<son_sidechain_info> get_active_sons_by_sidechain(sidechain_type sidechain);
|
||||
|
||||
/**
|
||||
* @brief Get SON network status
|
||||
|
|
|
|||
|
|
@ -69,11 +69,13 @@ void verify_account_votes( const database& db, const account_options& options )
|
|||
FC_ASSERT( options.num_committee <= chain_params.maximum_committee_count,
|
||||
"Voted for more committee members than currently allowed (${c})", ("c", chain_params.maximum_committee_count) );
|
||||
FC_ASSERT( chain_params.extensions.value.maximum_son_count.valid() , "Invalid maximum son count" );
|
||||
FC_ASSERT( options.extensions.value.num_son.valid() , "Invalid son number" );
|
||||
for(const auto& num_sons : *options.extensions.value.num_son)
|
||||
if ( options.extensions.value.num_son.valid() )
|
||||
{
|
||||
FC_ASSERT( num_sons.second <= *chain_params.extensions.value.maximum_son_count,
|
||||
"Voted for more sons than currently allowed (${c})", ("c", *chain_params.extensions.value.maximum_son_count) );
|
||||
for(const auto& num_sons : *options.extensions.value.num_son)
|
||||
{
|
||||
FC_ASSERT( num_sons.second <= *chain_params.extensions.value.maximum_son_count,
|
||||
"Voted for more sons than currently allowed (${c})", ("c", *chain_params.extensions.value.maximum_son_count) );
|
||||
}
|
||||
}
|
||||
FC_ASSERT( db.find_object(options.voting_account), "Invalid proxy account specified." );
|
||||
|
||||
|
|
@ -188,6 +190,12 @@ object_id_type account_create_evaluator::do_apply( const account_create_operatio
|
|||
obj.owner = o.owner;
|
||||
obj.active = o.active;
|
||||
obj.options = o.options;
|
||||
|
||||
if (!obj.options.extensions.value.num_son.valid())
|
||||
{
|
||||
obj.options.extensions.value = account_options::ext();
|
||||
}
|
||||
|
||||
obj.statistics = d.create<account_statistics_object>([&obj](account_statistics_object& s){
|
||||
s.owner = obj.id;
|
||||
s.name = obj.name;
|
||||
|
|
|
|||
|
|
@ -784,7 +784,7 @@ void database::_apply_block( const signed_block& next_block )
|
|||
update_witness_schedule();
|
||||
|
||||
bool need_update_son_schedule = false;
|
||||
for(const auto& active_sidechain_type : active_sidechain_types) {
|
||||
for(const auto& active_sidechain_type : active_sidechain_types(dynamic_global_props.time)) {
|
||||
if(global_props.active_sons.at(active_sidechain_type).size() > 0) {
|
||||
need_update_son_schedule = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -342,7 +342,7 @@ bool database::is_son_active( sidechain_type type, son_id_type son_id )
|
|||
active_son_ids.reserve(gpo_as.size());
|
||||
std::transform(gpo_as.cbegin(), gpo_as.cend(),
|
||||
std::inserter(active_son_ids, active_son_ids.end()),
|
||||
[](const son_info& swi) {
|
||||
[](const son_sidechain_info& swi) {
|
||||
return swi.son_id;
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -365,7 +365,7 @@ void database::initialize_hardforks()
|
|||
_hardfork_times.emplace_back(HARDFORK_SON_FOR_HIVE_TIME);
|
||||
_hardfork_times.emplace_back(HARDFORK_SON_TIME);
|
||||
_hardfork_times.emplace_back(HARDFORK_SON2_TIME);
|
||||
_hardfork_times.emplace_back(HARDFORK_SON3_TIME);
|
||||
_hardfork_times.emplace_back(HARDFORK_SON_FOR_ETHEREUM_TIME);
|
||||
_hardfork_times.emplace_back(HARDFORK_SWEEPS_TIME);
|
||||
|
||||
std::sort(_hardfork_times.begin(), _hardfork_times.end());
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ vector<std::reference_wrapper<const son_object>> database::sort_votable_objects<
|
|||
std::vector<std::reference_wrapper<const son_object>> refs;
|
||||
for( auto& son : all_sons )
|
||||
{
|
||||
if(son.has_valid_config(head_block_time()) && son.statuses.at(sidechain) != son_status::deregistered)
|
||||
if(son.has_valid_config(head_block_time(), sidechain) && son.statuses.at(sidechain) != son_status::deregistered)
|
||||
{
|
||||
refs.push_back(std::cref(son));
|
||||
}
|
||||
|
|
@ -97,8 +97,10 @@ vector<std::reference_wrapper<const son_object>> database::sort_votable_objects<
|
|||
sidechain == sidechain_type::hive,
|
||||
"Unexpected sidechain type");
|
||||
|
||||
const share_type oa_vote = _vote_tally_buffer[a.get_sidechain_vote_id(sidechain)];
|
||||
const share_type ob_vote = _vote_tally_buffer[b.get_sidechain_vote_id(sidechain)];
|
||||
FC_ASSERT(a.get_sidechain_vote_id(sidechain).valid(), "Invalid vote id, sidechain: ${sidechain}, son: ${son}", ("sidechain", sidechain)("son", a));
|
||||
FC_ASSERT(b.get_sidechain_vote_id(sidechain).valid(), "Invalid vote id, sidechain: ${sidechain}, son: ${son}", ("sidechain", sidechain)("son", b));
|
||||
const share_type oa_vote = _vote_tally_buffer.size() > *a.get_sidechain_vote_id(sidechain) ? _vote_tally_buffer[*a.get_sidechain_vote_id(sidechain)] : 0;
|
||||
const share_type ob_vote = _vote_tally_buffer.size() > *b.get_sidechain_vote_id(sidechain) ? _vote_tally_buffer[*b.get_sidechain_vote_id(sidechain)] : 0;
|
||||
|
||||
if( oa_vote != ob_vote )
|
||||
return oa_vote > ob_vote;
|
||||
|
|
@ -190,7 +192,7 @@ void database::pay_sons()
|
|||
// Current requirement is that we have to pay every 24 hours, so the following check
|
||||
if( dpo.son_budget.value > 0 && ((now - dpo.last_son_payout_time) >= fc::seconds(get_global_properties().parameters.son_pay_time())))
|
||||
{
|
||||
for(const auto& active_sidechain_type : active_sidechain_types)
|
||||
for(const auto& active_sidechain_type : active_sidechain_types(now))
|
||||
{
|
||||
assert( _son_count_histogram_buffer.at(active_sidechain_type).size() > 0 );
|
||||
const share_type stake_target = (_total_voting_stake-_son_count_histogram_buffer.at(active_sidechain_type)[0]) / 2;
|
||||
|
|
@ -207,7 +209,14 @@ void database::pay_sons()
|
|||
}
|
||||
}
|
||||
|
||||
const auto sons = sort_votable_objects<son_index>(active_sidechain_type,
|
||||
const sidechain_type st = [&now, &active_sidechain_type]{
|
||||
if( now < HARDFORK_SON_FOR_ETHEREUM_TIME )
|
||||
return sidechain_type::bitcoin;
|
||||
else
|
||||
return active_sidechain_type;
|
||||
}();
|
||||
|
||||
const auto sons = sort_votable_objects<son_index>(st,
|
||||
(std::max(son_count*2+1, (size_t)get_chain_properties().immutable_parameters.min_son_count))
|
||||
);
|
||||
|
||||
|
|
@ -215,7 +224,8 @@ void database::pay_sons()
|
|||
uint64_t total_votes = 0;
|
||||
for( const son_object& son : sons )
|
||||
{
|
||||
total_votes += _vote_tally_buffer[son.sidechain_vote_ids.at(active_sidechain_type)];
|
||||
FC_ASSERT(son.get_sidechain_vote_id(st).valid(), "Invalid vote id, sidechain: ${sidechain}, son: ${son}", ("sidechain", st)("son", son));
|
||||
total_votes += _vote_tally_buffer[*son.get_sidechain_vote_id(st)];
|
||||
}
|
||||
const int8_t bits_to_drop = std::max(int(boost::multiprecision::detail::find_msb(total_votes)) - 15, 0);
|
||||
auto get_weight = [&bits_to_drop]( uint64_t son_votes ) {
|
||||
|
|
@ -230,35 +240,37 @@ void database::pay_sons()
|
|||
};
|
||||
uint64_t weighted_total_txs_signed = 0;
|
||||
const share_type son_budget = dpo.son_budget;
|
||||
get_index_type<son_stats_index>().inspect_all_objects([this, &weighted_total_txs_signed, &get_weight, &now, &get_weight_before_son2_hf, &active_sidechain_type](const object& o) {
|
||||
get_index_type<son_stats_index>().inspect_all_objects([this, &weighted_total_txs_signed, &get_weight, &now, &get_weight_before_son2_hf, &active_sidechain_type, &st](const object& o) {
|
||||
const son_statistics_object& s = static_cast<const son_statistics_object&>(o);
|
||||
const auto& idx = get_index_type<son_index>().indices().get<by_id>();
|
||||
const auto son_obj = idx.find( s.owner );
|
||||
uint16_t son_weight = 0;
|
||||
FC_ASSERT(son_obj->get_sidechain_vote_id(st).valid(), "Invalid vote id, sidechain: ${sidechain}, son: ${son}", ("sidechain", st)("son", *son_obj));
|
||||
if( now >= HARDFORK_SON2_TIME ) {
|
||||
son_weight += get_weight(_vote_tally_buffer[son_obj->sidechain_vote_ids.at(active_sidechain_type)]);
|
||||
son_weight += get_weight(_vote_tally_buffer[*son_obj->get_sidechain_vote_id(st)]);
|
||||
}
|
||||
else {
|
||||
son_weight += get_weight_before_son2_hf(_vote_tally_buffer[son_obj->sidechain_vote_ids.at(active_sidechain_type)]);
|
||||
son_weight += get_weight_before_son2_hf(_vote_tally_buffer[*son_obj->get_sidechain_vote_id(st)]);
|
||||
}
|
||||
const uint64_t txs_signed = s.txs_signed.contains(active_sidechain_type) ? s.txs_signed.at(active_sidechain_type) : 0;
|
||||
weighted_total_txs_signed += (txs_signed * son_weight);
|
||||
});
|
||||
|
||||
// Now pay off each SON proportional to the number of transactions signed.
|
||||
get_index_type<son_stats_index>().inspect_all_objects([this, &weighted_total_txs_signed, &dpo, &son_budget, &get_weight, &get_weight_before_son2_hf, &now, &active_sidechain_type](const object& o) {
|
||||
get_index_type<son_stats_index>().inspect_all_objects([this, &weighted_total_txs_signed, &dpo, &son_budget, &get_weight, &get_weight_before_son2_hf, &now, &active_sidechain_type, &st](const object& o) {
|
||||
const son_statistics_object& s = static_cast<const son_statistics_object&>(o);
|
||||
const uint64_t txs_signed = s.txs_signed.contains(active_sidechain_type) ? s.txs_signed.at(active_sidechain_type) : 0;
|
||||
|
||||
if(txs_signed > 0){
|
||||
if(txs_signed > 0) {
|
||||
const auto& idx = get_index_type<son_index>().indices().get<by_id>();
|
||||
auto son_obj = idx.find( s.owner );
|
||||
uint16_t son_weight = 0;
|
||||
FC_ASSERT(son_obj->get_sidechain_vote_id(st).valid(), "Invalid vote id, sidechain: ${sidechain}, son: ${son}", ("sidechain", st)("son", *son_obj));
|
||||
if( now >= HARDFORK_SON2_TIME ) {
|
||||
son_weight += get_weight(_vote_tally_buffer[son_obj->sidechain_vote_ids.at(active_sidechain_type)]);
|
||||
son_weight += get_weight(_vote_tally_buffer[*son_obj->get_sidechain_vote_id(st)]);
|
||||
}
|
||||
else {
|
||||
son_weight += get_weight_before_son2_hf(_vote_tally_buffer[son_obj->sidechain_vote_ids.at(active_sidechain_type)]);
|
||||
son_weight += get_weight_before_son2_hf(_vote_tally_buffer[*son_obj->get_sidechain_vote_id(st)]);
|
||||
}
|
||||
const share_type pay = (txs_signed * son_weight * son_budget.value)/weighted_total_txs_signed;
|
||||
modify( *son_obj, [&]( son_object& _son_obj)
|
||||
|
|
@ -287,7 +299,7 @@ void database::pay_sons()
|
|||
}
|
||||
}
|
||||
|
||||
void database::update_son_metrics(const flat_map<sidechain_type, vector<son_info> >& curr_active_sons)
|
||||
void database::update_son_metrics(const flat_map<sidechain_type, vector<son_sidechain_info> >& curr_active_sons)
|
||||
{
|
||||
for(const auto& curr_active_sidechain_sons : curr_active_sons) {
|
||||
const auto& sidechain = curr_active_sidechain_sons.first;
|
||||
|
|
@ -298,7 +310,7 @@ void database::update_son_metrics(const flat_map<sidechain_type, vector<son_info
|
|||
current_sons.reserve(_curr_active_sidechain_sons.size());
|
||||
std::transform(_curr_active_sidechain_sons.cbegin(), _curr_active_sidechain_sons.cend(),
|
||||
std::inserter(current_sons, current_sons.end()),
|
||||
[](const son_info &swi) {
|
||||
[](const son_sidechain_info &swi) {
|
||||
return swi.son_id;
|
||||
});
|
||||
|
||||
|
|
@ -321,8 +333,8 @@ void database::update_son_metrics(const flat_map<sidechain_type, vector<son_info
|
|||
}
|
||||
}
|
||||
|
||||
void database::update_son_statuses( const flat_map<sidechain_type, vector<son_info> >& curr_active_sons,
|
||||
const flat_map<sidechain_type, vector<son_info> >& new_active_sons )
|
||||
void database::update_son_statuses( const flat_map<sidechain_type, vector<son_sidechain_info> >& curr_active_sons,
|
||||
const flat_map<sidechain_type, vector<son_sidechain_info> >& new_active_sons )
|
||||
{
|
||||
for(const auto& new_active_sidechain_sons : new_active_sons) {
|
||||
const auto& sidechain = new_active_sidechain_sons.first;
|
||||
|
|
@ -335,7 +347,7 @@ void database::update_son_statuses( const flat_map<sidechain_type, vector<son_in
|
|||
current_sons.reserve(curr_active_sons.at(sidechain).size());
|
||||
std::transform(curr_active_sons.at(sidechain).cbegin(), curr_active_sons.at(sidechain).cend(),
|
||||
std::inserter(current_sons, current_sons.end()),
|
||||
[](const son_info &swi) {
|
||||
[](const son_sidechain_info &swi) {
|
||||
return swi.son_id;
|
||||
});
|
||||
}
|
||||
|
|
@ -343,7 +355,7 @@ void database::update_son_statuses( const flat_map<sidechain_type, vector<son_in
|
|||
new_sons.reserve(new_active_sons.at(sidechain).size());
|
||||
std::transform(new_active_sons.at(sidechain).cbegin(), new_active_sons.at(sidechain).cend(),
|
||||
std::inserter(new_sons, new_sons.end()),
|
||||
[](const son_info &swi) {
|
||||
[](const son_sidechain_info &swi) {
|
||||
return swi.son_id;
|
||||
});
|
||||
|
||||
|
|
@ -379,7 +391,7 @@ void database::update_son_statuses( const flat_map<sidechain_type, vector<son_in
|
|||
|
||||
for (const auto &sid : sons_to_add) {
|
||||
auto son = idx.find(sid);
|
||||
FC_ASSERT(son != idx.end(), "Invalid SON in active list, id={sonid}.", ("sonid", sid));
|
||||
FC_ASSERT(son != idx.end(), "Invalid SON in active list, id = ${sonid}.", ("sonid", sid));
|
||||
// keep maintenance status for new nodes
|
||||
if (son->statuses.at(sidechain) == son_status::inactive) {
|
||||
modify(*son, [&](son_object &obj) {
|
||||
|
|
@ -414,7 +426,7 @@ void database::update_son_statuses( const flat_map<sidechain_type, vector<son_in
|
|||
}
|
||||
}
|
||||
|
||||
void database::update_son_wallet(const flat_map<sidechain_type, vector<son_info> >& new_active_sons)
|
||||
void database::update_son_wallet(const flat_map<sidechain_type, vector<son_sidechain_info> >& new_active_sons)
|
||||
{
|
||||
bool should_recreate_pw = true;
|
||||
|
||||
|
|
@ -729,39 +741,22 @@ void database::update_active_sons()
|
|||
}
|
||||
#endif
|
||||
|
||||
const flat_map<sidechain_type, share_type> stake_target = [this]{
|
||||
flat_map<sidechain_type, share_type> stake_target;
|
||||
for( const auto& son_count_histogram_buffer : _son_count_histogram_buffer ){
|
||||
const auto sidechain = son_count_histogram_buffer.first;
|
||||
stake_target[sidechain] = (_total_voting_stake-son_count_histogram_buffer.second[0]) / 2;
|
||||
}
|
||||
return stake_target;
|
||||
}();
|
||||
const auto supported_active_sidechain_types = active_sidechain_types(head_block_time());
|
||||
flat_map<sidechain_type, size_t> son_count;
|
||||
for(const auto& active_sidechain_type : supported_active_sidechain_types)
|
||||
{
|
||||
const share_type stake_target = (_total_voting_stake-_son_count_histogram_buffer.at(active_sidechain_type)[0]) / 2;
|
||||
|
||||
/// accounts that vote for 0 or 1 son do not get to express an opinion on
|
||||
/// the number of sons to have (they abstain and are non-voting accounts)
|
||||
flat_map<sidechain_type, share_type> stake_tally = []{
|
||||
flat_map<sidechain_type, share_type> stake_tally;
|
||||
for(const auto& active_sidechain_type : active_sidechain_types){
|
||||
stake_tally[active_sidechain_type] = 0;
|
||||
}
|
||||
return stake_tally;
|
||||
}();
|
||||
flat_map<sidechain_type, size_t> son_count = []{
|
||||
flat_map<sidechain_type, size_t> son_count;
|
||||
for(const auto& active_sidechain_type : active_sidechain_types){
|
||||
son_count[active_sidechain_type] = 0;
|
||||
}
|
||||
return son_count;
|
||||
}();
|
||||
for( const auto& stake_target_sidechain : stake_target ){
|
||||
const auto sidechain = stake_target_sidechain.first;
|
||||
if( stake_target_sidechain.second > 0 )
|
||||
/// accounts that vote for 0 or 1 son do not get to express an opinion on
|
||||
/// the number of sons to have (they abstain and are non-voting accounts)
|
||||
share_type stake_tally = 0;
|
||||
son_count[active_sidechain_type] = 0;
|
||||
if( stake_target > 0 )
|
||||
{
|
||||
while( (son_count[sidechain] < _son_count_histogram_buffer.at(sidechain).size() - 1)
|
||||
&& (stake_tally[sidechain] <= stake_target_sidechain.second) )
|
||||
while( (son_count.at(active_sidechain_type) < _son_count_histogram_buffer.at(active_sidechain_type).size() - 1)
|
||||
&& (stake_tally <= stake_target) )
|
||||
{
|
||||
stake_tally[sidechain] += _son_count_histogram_buffer.at(sidechain)[ ++son_count[sidechain] ];
|
||||
stake_tally += _son_count_histogram_buffer.at(active_sidechain_type)[ ++son_count[active_sidechain_type] ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -770,18 +765,17 @@ void database::update_active_sons()
|
|||
const chain_property_object& cpo = get_chain_properties();
|
||||
const auto& all_sons = get_index_type<son_index>().indices();
|
||||
flat_map<sidechain_type, vector<std::reference_wrapper<const son_object> > > sons;
|
||||
for(const auto& active_sidechain_type : active_sidechain_types)
|
||||
for(const auto& active_sidechain_type : supported_active_sidechain_types)
|
||||
{
|
||||
if(head_block_time() >= HARDFORK_SON3_TIME) {
|
||||
if(head_block_time() >= HARDFORK_SON_FOR_ETHEREUM_TIME) {
|
||||
sons[active_sidechain_type] = sort_votable_objects<son_index>(active_sidechain_type,
|
||||
(std::max(son_count.at(active_sidechain_type) * 2 + 1, (size_t)cpo.immutable_parameters.min_son_count)));
|
||||
}
|
||||
else {
|
||||
sons[active_sidechain_type] = sort_votable_objects<son_index>(active_sidechain_type, get_global_properties().parameters.maximum_son_count());
|
||||
sons[active_sidechain_type] = sort_votable_objects<son_index>(sidechain_type::bitcoin, get_global_properties().parameters.maximum_son_count());
|
||||
}
|
||||
}
|
||||
|
||||
auto& local_vote_buffer_ref = _vote_tally_buffer;
|
||||
for( const son_object& son : all_sons )
|
||||
{
|
||||
for(const auto& status: son.statuses)
|
||||
|
|
@ -796,9 +790,9 @@ void database::update_active_sons()
|
|||
}
|
||||
}
|
||||
|
||||
modify( son, [local_vote_buffer_ref]( son_object& obj ){
|
||||
modify( son, [this]( son_object& obj ){
|
||||
for(const auto& sidechain_vote_id : obj.sidechain_vote_ids ){
|
||||
obj.total_votes[sidechain_vote_id.first] = local_vote_buffer_ref[sidechain_vote_id.second];
|
||||
obj.total_votes[sidechain_vote_id.first] = _vote_tally_buffer.size() > sidechain_vote_id.second ? _vote_tally_buffer[sidechain_vote_id.second] : 0;
|
||||
}
|
||||
for(auto& status: obj.statuses)
|
||||
{
|
||||
|
|
@ -853,7 +847,7 @@ void database::update_active_sons()
|
|||
|
||||
// Compare current and to-be lists of active sons
|
||||
const auto cur_active_sons = gpo.active_sons;
|
||||
flat_map<sidechain_type, vector<son_info> > new_active_sons;
|
||||
flat_map<sidechain_type, vector<son_sidechain_info> > new_active_sons;
|
||||
const auto &acc = get(gpo.parameters.son_account());
|
||||
for( const auto& sidechain_sons : sons ){
|
||||
const auto& sidechain = sidechain_sons.first;
|
||||
|
|
@ -861,11 +855,12 @@ void database::update_active_sons()
|
|||
|
||||
new_active_sons[sidechain].reserve(sons_array.size());
|
||||
for( const son_object& son : sons_array ) {
|
||||
son_info swi;
|
||||
son_sidechain_info swi;
|
||||
swi.son_id = son.id;
|
||||
swi.weight = acc.active.account_auths.at(son.son_account);
|
||||
swi.signing_key = son.signing_key;
|
||||
swi.public_key = son.sidechain_public_keys.at(sidechain);
|
||||
if (son.sidechain_public_keys.find(sidechain) != son.sidechain_public_keys.end())
|
||||
swi.public_key = son.sidechain_public_keys.at(sidechain);
|
||||
new_active_sons[sidechain].push_back(swi);
|
||||
}
|
||||
}
|
||||
|
|
@ -905,7 +900,7 @@ void database::update_active_sons()
|
|||
}
|
||||
});
|
||||
|
||||
for(const auto& active_sidechain_type : active_sidechain_types)
|
||||
for(const auto& active_sidechain_type : supported_active_sidechain_types)
|
||||
{
|
||||
const son_schedule_object& sidechain_sso = son_schedule_id_type(get_son_schedule_id(active_sidechain_type))(*this);
|
||||
modify(sidechain_sso, [&](son_schedule_object& _sso)
|
||||
|
|
@ -914,12 +909,13 @@ void database::update_active_sons()
|
|||
active_sons.reserve(gpo.active_sons.at(active_sidechain_type).size());
|
||||
std::transform(gpo.active_sons.at(active_sidechain_type).cbegin(), gpo.active_sons.at(active_sidechain_type).cend(),
|
||||
std::inserter(active_sons, active_sons.end()),
|
||||
[](const son_info& swi) {
|
||||
[](const son_sidechain_info& swi) {
|
||||
return swi.son_id;
|
||||
});
|
||||
_sso.scheduler.update(active_sons);
|
||||
// similar to witness, produce schedule for sons
|
||||
if(cur_active_sons.at(active_sidechain_type).size() == 0 && new_active_sons.at(active_sidechain_type).size() > 0)
|
||||
if( ((cur_active_sons.contains(active_sidechain_type) && cur_active_sons.at(active_sidechain_type).size() == 0) ||
|
||||
!cur_active_sons.contains(active_sidechain_type)) && new_active_sons.at(active_sidechain_type).size() > 0 )
|
||||
{
|
||||
witness_scheduler_rng rng(_sso.rng_seed.begin(), GRAPHENE_NEAR_SCHEDULE_CTR_IV);
|
||||
for( size_t i=0; i<new_active_sons.at(active_sidechain_type).size(); ++i )
|
||||
|
|
@ -2189,6 +2185,7 @@ void database::perform_son_tasks()
|
|||
gpo.pending_parameters->extensions.value.hive_asset = hive_asset.get_id();
|
||||
});
|
||||
}
|
||||
|
||||
// Pay the SONs
|
||||
if (head_block_time() >= HARDFORK_SON_TIME)
|
||||
{
|
||||
|
|
@ -2197,18 +2194,57 @@ void database::perform_son_tasks()
|
|||
// and modify the global son funds accordingly, whatever is left is passed on to next budget
|
||||
pay_sons();
|
||||
}
|
||||
|
||||
// Split vote_ids
|
||||
if (head_block_time() >= HARDFORK_SON_FOR_ETHEREUM_TIME) {
|
||||
// Get SON 1.33.0 and check if it has HIVE vote_id
|
||||
const son_id_type sid = son_id_type(0);
|
||||
const auto p_son = find(sid);
|
||||
if(p_son != nullptr) {
|
||||
if (p_son->sidechain_vote_ids.find(sidechain_type::hive) == p_son->sidechain_vote_ids.end()) {
|
||||
// Add vote_ids for HIVE and ETHEREUM to all existing SONs
|
||||
const auto &all_sons = get_index_type<son_index>().indices().get<by_id>();
|
||||
for (const son_object &son : all_sons) {
|
||||
vote_id_type existing_vote_id_bitcoin;
|
||||
vote_id_type new_vote_id_hive;
|
||||
vote_id_type new_vote_id_eth;
|
||||
|
||||
modify(gpo, [&new_vote_id_hive, &new_vote_id_eth](global_property_object &p) {
|
||||
new_vote_id_hive = get_next_vote_id(p, vote_id_type::son_hive);
|
||||
new_vote_id_eth = get_next_vote_id(p, vote_id_type::son_ethereum);
|
||||
});
|
||||
|
||||
modify(son, [new_vote_id_hive, new_vote_id_eth](son_object &obj) {
|
||||
obj.sidechain_vote_ids[sidechain_type::hive] = new_vote_id_hive;
|
||||
obj.sidechain_vote_ids[sidechain_type::ethereum] = new_vote_id_eth;
|
||||
});
|
||||
|
||||
// Duplicate all votes from bitcoin to hive
|
||||
const auto &all_accounts = get_index_type<account_index>().indices().get<by_id>();
|
||||
for (const auto &account : all_accounts) {
|
||||
if (account.options.votes.count(existing_vote_id_bitcoin) != 0) {
|
||||
modify(account, [new_vote_id_hive](account_object &a) {
|
||||
a.options.votes.insert(new_vote_id_hive);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void update_son_params(database& db)
|
||||
{
|
||||
if( (db.head_block_time() >= HARDFORK_SON2_TIME) && (db.head_block_time() < HARDFORK_SON3_TIME) )
|
||||
if( (db.head_block_time() >= HARDFORK_SON2_TIME) && (db.head_block_time() < HARDFORK_SON_FOR_ETHEREUM_TIME) )
|
||||
{
|
||||
const auto& gpo = db.get_global_properties();
|
||||
db.modify( gpo, []( global_property_object& gpo ) {
|
||||
gpo.parameters.extensions.value.maximum_son_count = 7;
|
||||
});
|
||||
}
|
||||
else
|
||||
|
||||
if( (db.head_block_time() >= HARDFORK_SON_FOR_ETHEREUM_TIME) )
|
||||
{
|
||||
const auto& gpo = db.get_global_properties();
|
||||
db.modify( gpo, []( global_property_object& gpo ) {
|
||||
|
|
@ -2343,20 +2379,23 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
|
|||
// same rationale as for witnesses
|
||||
d._committee_count_histogram_buffer[offset] += voting_stake;
|
||||
}
|
||||
FC_ASSERT( opinion_account.options.extensions.value.num_son.valid() , "Invalid son number" );
|
||||
for(const auto& num_sidechain_son : *opinion_account.options.extensions.value.num_son) {
|
||||
const auto sidechain = num_sidechain_son.first;
|
||||
const auto& num_son = num_sidechain_son.second;
|
||||
if (num_son <= props.parameters.maximum_son_count()) {
|
||||
uint16_t offset = std::min(size_t(num_son / 2),
|
||||
d._son_count_histogram_buffer.at(sidechain).size() - 1);
|
||||
// votes for a number greater than maximum_son_count
|
||||
// are turned into votes for maximum_son_count.
|
||||
//
|
||||
// in particular, this takes care of the case where a
|
||||
// member was voting for a high number, then the
|
||||
// parameter was lowered.
|
||||
d._son_count_histogram_buffer.at(sidechain)[offset] += voting_stake;
|
||||
|
||||
if ( opinion_account.options.extensions.value.num_son.valid() )
|
||||
{
|
||||
for(const auto& num_sidechain_son : *opinion_account.options.extensions.value.num_son) {
|
||||
const auto sidechain = num_sidechain_son.first;
|
||||
const auto& num_son = num_sidechain_son.second;
|
||||
if (num_son <= props.parameters.maximum_son_count()) {
|
||||
uint16_t offset = std::min(size_t(num_son / 2),
|
||||
d._son_count_histogram_buffer.at(sidechain).size() - 1);
|
||||
// votes for a number greater than maximum_son_count
|
||||
// are turned into votes for maximum_son_count.
|
||||
//
|
||||
// in particular, this takes care of the case where a
|
||||
// member was voting for a high number, then the
|
||||
// parameter was lowered.
|
||||
d._son_count_histogram_buffer.at(sidechain)[offset] += voting_stake;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -112,7 +112,6 @@ void database::reindex( fc::path data_dir )
|
|||
uint32_t undo_point = last_block_num < 50 ? 0 : last_block_num - 50;
|
||||
|
||||
ilog( "Replaying blocks, starting at ${next}...", ("next",head_block_num() + 1) );
|
||||
const std::lock_guard<std::mutex> undo_db_lock{_undo_db_mutex};
|
||||
auto_undo_enabler undo(_slow_replays, _undo_db);
|
||||
if( head_block_num() >= undo_point )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -204,17 +204,18 @@ void database::update_son_schedule()
|
|||
{
|
||||
const global_property_object& gpo = get_global_properties();
|
||||
|
||||
for(const auto& active_sidechain_type : active_sidechain_types)
|
||||
for(const auto& active_sidechain_type : active_sidechain_types(head_block_time()))
|
||||
{
|
||||
const son_schedule_object& sidechain_sso = get(son_schedule_id_type(get_son_schedule_id(active_sidechain_type)));
|
||||
if( head_block_num() % gpo.active_sons.at(active_sidechain_type).size() == 0)
|
||||
if( gpo.active_sons.at(active_sidechain_type).size() != 0 &&
|
||||
head_block_num() % gpo.active_sons.at(active_sidechain_type).size() == 0)
|
||||
{
|
||||
modify( sidechain_sso, [&]( son_schedule_object& _sso )
|
||||
{
|
||||
_sso.current_shuffled_sons.clear();
|
||||
_sso.current_shuffled_sons.reserve( gpo.active_sons.at(active_sidechain_type).size() );
|
||||
|
||||
for ( const son_info &w : gpo.active_sons.at(active_sidechain_type) ) {
|
||||
for ( const auto &w : gpo.active_sons.at(active_sidechain_type) ) {
|
||||
_sso.current_shuffled_sons.push_back(w.son_id);
|
||||
}
|
||||
|
||||
|
|
@ -350,7 +351,7 @@ void database::update_son_schedule(const signed_block& next_block)
|
|||
assert( dpo.random.data_size() == witness_scheduler_rng::seed_length );
|
||||
assert( witness_scheduler_rng::seed_length == sso.rng_seed.size() );
|
||||
|
||||
for(const auto& active_sidechain_type : active_sidechain_types)
|
||||
for(const auto& active_sidechain_type : active_sidechain_types(head_block_time()))
|
||||
{
|
||||
const son_schedule_object& sidechain_sso = get(son_schedule_id_type(get_son_schedule_id(active_sidechain_type)));
|
||||
son_id_type first_son;
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
#ifndef HARDFORK_SON3_TIME
|
||||
#ifdef BUILD_PEERPLAYS_TESTNET
|
||||
#define HARDFORK_SON3_TIME (fc::time_point_sec::from_iso_string("2022-07-16T00:00:00"))
|
||||
#else
|
||||
#define HARDFORK_SON3_TIME (fc::time_point_sec::from_iso_string("2022-07-16T00:00:00"))
|
||||
#endif
|
||||
#endif
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef HARDFORK_SON_FOR_ETHEREUM_TIME
|
||||
#ifdef BUILD_PEERPLAYS_TESTNET
|
||||
#define HARDFORK_SON_FOR_ETHEREUM_TIME (fc::time_point_sec::from_iso_string("2022-07-01T00:00:00"))
|
||||
#define HARDFORK_SON_FOR_ETHEREUM_TIME (fc::time_point_sec::from_iso_string("2023-01-24T00:00:00"))
|
||||
#else
|
||||
#define HARDFORK_SON_FOR_ETHEREUM_TIME (fc::time_point_sec::from_iso_string("2022-07-01T00:00:00"))
|
||||
#define HARDFORK_SON_FOR_ETHEREUM_TIME (fc::time_point_sec::from_iso_string("2023-03-24T00:00:00"))
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -584,14 +584,14 @@ namespace graphene { namespace chain {
|
|||
void perform_chain_maintenance(const signed_block& next_block, const global_property_object& global_props);
|
||||
void update_active_witnesses();
|
||||
void update_active_committee_members();
|
||||
void update_son_metrics( const flat_map<sidechain_type, vector<son_info> >& curr_active_sons );
|
||||
void update_son_metrics( const flat_map<sidechain_type, vector<son_sidechain_info> >& curr_active_sons );
|
||||
void update_active_sons();
|
||||
void remove_son_proposal( const proposal_object& proposal );
|
||||
void remove_inactive_son_down_proposals( const vector<son_id_type>& son_ids_to_remove );
|
||||
void remove_inactive_son_proposals( const vector<son_id_type>& son_ids_to_remove );
|
||||
void update_son_statuses( const flat_map<sidechain_type, vector<son_info> >& curr_active_sons,
|
||||
const flat_map<sidechain_type, vector<son_info> >& new_active_sons );
|
||||
void update_son_wallet( const flat_map<sidechain_type, vector<son_info> >& new_active_sons );
|
||||
void update_son_statuses( const flat_map<sidechain_type, vector<son_sidechain_info> >& curr_active_sons,
|
||||
const flat_map<sidechain_type, vector<son_sidechain_info> >& new_active_sons );
|
||||
void update_son_wallet( const flat_map<sidechain_type, vector<son_sidechain_info> >& new_active_sons );
|
||||
void update_worker_votes();
|
||||
|
||||
public:
|
||||
|
|
@ -636,7 +636,7 @@ namespace graphene { namespace chain {
|
|||
vector<uint64_t> _committee_count_histogram_buffer;
|
||||
flat_map<sidechain_type, vector<uint64_t> > _son_count_histogram_buffer = []{
|
||||
flat_map<sidechain_type, vector<uint64_t> > son_count_histogram_buffer;
|
||||
for(const auto& active_sidechain_type : active_sidechain_types){
|
||||
for(const auto& active_sidechain_type : all_sidechain_types){
|
||||
son_count_histogram_buffer[active_sidechain_type] = vector<uint64_t>{};
|
||||
}
|
||||
return son_count_histogram_buffer;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
#include <graphene/chain/protocol/chain_parameters.hpp>
|
||||
#include <graphene/chain/protocol/types.hpp>
|
||||
#include <graphene/chain/database.hpp>
|
||||
#include <graphene/chain/son_info.hpp>
|
||||
#include <graphene/chain/son_sidechain_info.hpp>
|
||||
#include <graphene/db/object.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
|
@ -49,15 +49,15 @@ namespace graphene { namespace chain {
|
|||
chain_parameters parameters;
|
||||
optional<chain_parameters> pending_parameters;
|
||||
|
||||
uint32_t next_available_vote_id = 0;
|
||||
vector<committee_member_id_type> active_committee_members; // updated once per maintenance interval
|
||||
flat_set<witness_id_type> active_witnesses; // updated once per maintenance interval
|
||||
flat_map<sidechain_type, vector<son_info> > active_sons = []() // updated once per maintenance interval
|
||||
uint32_t next_available_vote_id = 0;
|
||||
vector<committee_member_id_type> active_committee_members; // updated once per maintenance interval
|
||||
flat_set<witness_id_type> active_witnesses; // updated once per maintenance interval
|
||||
flat_map<sidechain_type, vector<son_sidechain_info> > active_sons = []() // updated once per maintenance interval
|
||||
{
|
||||
flat_map<sidechain_type, vector<son_info> > active_sons;
|
||||
for(const auto& active_sidechain_type : active_sidechain_types)
|
||||
flat_map<sidechain_type, vector<son_sidechain_info> > active_sons;
|
||||
for(const auto& active_sidechain_type : all_sidechain_types)
|
||||
{
|
||||
active_sons[active_sidechain_type] = vector<son_info>();
|
||||
active_sons[active_sidechain_type] = vector<son_sidechain_info>();
|
||||
}
|
||||
return active_sons;
|
||||
}();
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ namespace graphene { namespace chain {
|
|||
/// Must not exceed the actual number of son members voted for in @ref votes
|
||||
optional< flat_map<sidechain_type, uint16_t> > num_son = []{
|
||||
flat_map<sidechain_type, uint16_t> num_son;
|
||||
for(const auto& active_sidechain_type : active_sidechain_types){
|
||||
for(const auto& active_sidechain_type : all_sidechain_types){
|
||||
num_son[active_sidechain_type] = 0;
|
||||
}
|
||||
return num_son;
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ FC_REFLECT( graphene::chain::sidechain_transaction_create_operation, (fee)(payer
|
|||
(sidechain)
|
||||
(object_id)
|
||||
(transaction)
|
||||
(signers) )
|
||||
(signers))
|
||||
|
||||
FC_REFLECT( graphene::chain::sidechain_transaction_sign_operation::fee_parameters_type, (fee) )
|
||||
FC_REFLECT( graphene::chain::sidechain_transaction_sign_operation, (fee)(signer)(payer)
|
||||
|
|
|
|||
|
|
@ -1,40 +1,47 @@
|
|||
#pragma once
|
||||
#include <graphene/chain/protocol/base.hpp>
|
||||
#include <graphene/chain/son_info.hpp>
|
||||
#include <graphene/chain/son_sidechain_info.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
struct son_wallet_recreate_operation : public base_operation
|
||||
{
|
||||
struct fee_parameters_type { uint64_t fee = 0; };
|
||||
struct son_wallet_recreate_operation : public base_operation
|
||||
{
|
||||
struct fee_parameters_type { uint64_t fee = 0; };
|
||||
struct ext
|
||||
{
|
||||
optional<flat_map<sidechain_type, vector<son_sidechain_info> > > sidechain_sons;
|
||||
};
|
||||
|
||||
asset fee;
|
||||
account_id_type payer;
|
||||
asset fee;
|
||||
account_id_type payer;
|
||||
|
||||
flat_map<sidechain_type, vector<son_info> > sons;
|
||||
vector<son_info> sons;
|
||||
extension< ext > extensions;
|
||||
|
||||
account_id_type fee_payer()const { return payer; }
|
||||
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
||||
};
|
||||
account_id_type fee_payer()const { return payer; }
|
||||
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
||||
};
|
||||
|
||||
struct son_wallet_update_operation : public base_operation
|
||||
{
|
||||
struct fee_parameters_type { uint64_t fee = 0; };
|
||||
struct son_wallet_update_operation : public base_operation
|
||||
{
|
||||
struct fee_parameters_type { uint64_t fee = 0; };
|
||||
|
||||
asset fee;
|
||||
account_id_type payer;
|
||||
asset fee;
|
||||
account_id_type payer;
|
||||
|
||||
son_wallet_id_type son_wallet_id;
|
||||
sidechain_type sidechain;
|
||||
string address;
|
||||
son_wallet_id_type son_wallet_id;
|
||||
sidechain_type sidechain;
|
||||
string address;
|
||||
|
||||
account_id_type fee_payer()const { return payer; }
|
||||
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
||||
};
|
||||
account_id_type fee_payer()const { return payer; }
|
||||
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
||||
};
|
||||
|
||||
} } // namespace graphene::chain
|
||||
|
||||
FC_REFLECT(graphene::chain::son_wallet_recreate_operation::fee_parameters_type, (fee) )
|
||||
FC_REFLECT(graphene::chain::son_wallet_recreate_operation, (fee)(payer)(sons) )
|
||||
FC_REFLECT(graphene::chain::son_wallet_recreate_operation::ext, (sidechain_sons))
|
||||
FC_REFLECT(graphene::chain::son_wallet_recreate_operation, (fee)(payer)(sons)(extensions) )
|
||||
FC_REFLECT(graphene::chain::son_wallet_update_operation::fee_parameters_type, (fee) )
|
||||
FC_REFLECT(graphene::chain::son_wallet_update_operation, (fee)(payer)(son_wallet_id)(sidechain)(address) )
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <set>
|
||||
|
||||
#include <graphene/chain/hardfork.hpp>
|
||||
|
||||
#include <fc/reflect/reflect.hpp>
|
||||
#include <fc/time.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
|
|
@ -14,9 +18,23 @@ enum class sidechain_type {
|
|||
hive
|
||||
};
|
||||
|
||||
static const std::set<sidechain_type> active_sidechain_types = {sidechain_type::bitcoin, sidechain_type::ethereum, sidechain_type::hive};
|
||||
static const std::set<sidechain_type> all_sidechain_types = {sidechain_type::bitcoin, sidechain_type::ethereum, sidechain_type::hive};
|
||||
|
||||
} }
|
||||
inline std::set<sidechain_type> active_sidechain_types(const fc::time_point_sec block_time) {
|
||||
std::set<sidechain_type> active_sidechain_types{};
|
||||
|
||||
if (block_time >= HARDFORK_SON_TIME)
|
||||
active_sidechain_types.insert(sidechain_type::bitcoin);
|
||||
if (block_time >= HARDFORK_SON_FOR_HIVE_TIME)
|
||||
active_sidechain_types.insert(sidechain_type::hive);
|
||||
if (block_time >= HARDFORK_SON_FOR_ETHEREUM_TIME)
|
||||
active_sidechain_types.insert(sidechain_type::ethereum);
|
||||
|
||||
return active_sidechain_types;
|
||||
}
|
||||
|
||||
} // namespace chain
|
||||
} // namespace graphene
|
||||
|
||||
FC_REFLECT_ENUM(graphene::chain::sidechain_type,
|
||||
(unknown)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#include <boost/multi_index/composite_key.hpp>
|
||||
#include <graphene/chain/protocol/types.hpp>
|
||||
#include <graphene/chain/sidechain_defs.hpp>
|
||||
#include <graphene/chain/son_info.hpp>
|
||||
#include <graphene/chain/son_sidechain_info.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
using namespace graphene::db;
|
||||
|
|
@ -30,7 +30,7 @@ namespace graphene { namespace chain {
|
|||
sidechain_type sidechain = sidechain_type::unknown;
|
||||
object_id_type object_id;
|
||||
std::string transaction;
|
||||
std::vector<son_info> signers;
|
||||
std::vector<son_sidechain_info> signers;
|
||||
std::vector<std::pair<son_id_type, std::string>> signatures;
|
||||
std::string sidechain_transaction;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,34 +3,40 @@
|
|||
#include <graphene/chain/sidechain_defs.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
using namespace graphene::db;
|
||||
|
||||
/**
|
||||
* @class son_info
|
||||
* @brief tracks information about a SON info required to re/create primary wallet
|
||||
* @ingroup object
|
||||
* @class son_info
|
||||
* @brief tracks information about a SON info required to re/create primary wallet
|
||||
* @ingroup object
|
||||
*/
|
||||
struct son_info {
|
||||
son_id_type son_id;
|
||||
weight_type weight = 0;
|
||||
public_key_type signing_key;
|
||||
string public_key;
|
||||
flat_map<sidechain_type, string> sidechain_public_keys;
|
||||
|
||||
bool operator==(const son_info& rhs) const {
|
||||
bool operator==(const son_info& rhs) {
|
||||
bool son_sets_equal =
|
||||
(son_id == rhs.son_id) &&
|
||||
(weight == rhs.weight) &&
|
||||
(signing_key == rhs.signing_key) &&
|
||||
(public_key == rhs.public_key);
|
||||
(sidechain_public_keys.size() == rhs.sidechain_public_keys.size());
|
||||
|
||||
if (son_sets_equal) {
|
||||
bool sidechain_public_keys_equal = true;
|
||||
for (size_t i = 0; i < sidechain_public_keys.size(); i++) {
|
||||
const auto lhs_scpk = sidechain_public_keys.nth(i);
|
||||
const auto rhs_scpk = rhs.sidechain_public_keys.nth(i);
|
||||
sidechain_public_keys_equal = sidechain_public_keys_equal &&
|
||||
(lhs_scpk->first == rhs_scpk->first) &&
|
||||
(lhs_scpk->second == rhs_scpk->second);
|
||||
}
|
||||
son_sets_equal = son_sets_equal && sidechain_public_keys_equal;
|
||||
}
|
||||
return son_sets_equal;
|
||||
}
|
||||
};
|
||||
|
||||
} }
|
||||
|
||||
FC_REFLECT( graphene::chain::son_info,
|
||||
(son_id)
|
||||
(weight)
|
||||
(signing_key)
|
||||
(public_key) )
|
||||
FC_REFLECT( graphene::chain::son_info, (son_id) (weight) (signing_key) (sidechain_public_keys) )
|
||||
|
|
|
|||
|
|
@ -65,7 +65,15 @@ namespace graphene { namespace chain {
|
|||
|
||||
account_id_type son_account;
|
||||
flat_map<sidechain_type, vote_id_type> sidechain_vote_ids;
|
||||
flat_map<sidechain_type, uint64_t> total_votes;
|
||||
flat_map<sidechain_type, uint64_t> total_votes = []()
|
||||
{
|
||||
flat_map<sidechain_type, uint64_t> total_votes;
|
||||
for(const auto& active_sidechain_type : all_sidechain_types)
|
||||
{
|
||||
total_votes[active_sidechain_type] = 0;
|
||||
}
|
||||
return total_votes;
|
||||
}();
|
||||
string url;
|
||||
vesting_balance_id_type deposit;
|
||||
public_key_type signing_key;
|
||||
|
|
@ -74,7 +82,7 @@ namespace graphene { namespace chain {
|
|||
flat_map<sidechain_type, son_status> statuses = []()
|
||||
{
|
||||
flat_map<sidechain_type, son_status> statuses;
|
||||
for(const auto& active_sidechain_type : active_sidechain_types)
|
||||
for(const auto& active_sidechain_type : all_sidechain_types)
|
||||
{
|
||||
statuses[active_sidechain_type] = son_status::inactive;
|
||||
}
|
||||
|
|
@ -83,13 +91,15 @@ namespace graphene { namespace chain {
|
|||
flat_map<sidechain_type, string> sidechain_public_keys;
|
||||
|
||||
void pay_son_fee(share_type pay, database& db);
|
||||
bool has_valid_config()const;
|
||||
bool has_valid_config(time_point_sec head_block_time)const;
|
||||
bool has_valid_config(time_point_sec head_block_time, sidechain_type sidechain) const;
|
||||
|
||||
inline vote_id_type get_sidechain_vote_id(sidechain_type sidechain) const { return sidechain_vote_ids.at(sidechain); }
|
||||
inline vote_id_type get_bitcoin_vote_id() const { return get_sidechain_vote_id(sidechain_type::bitcoin); }
|
||||
inline vote_id_type get_hive_vote_id() const { return get_sidechain_vote_id(sidechain_type::hive); }
|
||||
inline vote_id_type get_ethereum_vote_id() const { return get_sidechain_vote_id(sidechain_type::ethereum); }
|
||||
inline optional<vote_id_type> get_sidechain_vote_id(sidechain_type sidechain) const { return sidechain_vote_ids.contains(sidechain) ? sidechain_vote_ids.at(sidechain) : optional<vote_id_type>{}; }
|
||||
inline optional<vote_id_type> get_bitcoin_vote_id() const { return get_sidechain_vote_id(sidechain_type::bitcoin); }
|
||||
inline optional<vote_id_type> get_hive_vote_id() const { return get_sidechain_vote_id(sidechain_type::hive); }
|
||||
inline optional<vote_id_type> get_ethereum_vote_id() const { return get_sidechain_vote_id(sidechain_type::ethereum); }
|
||||
|
||||
private:
|
||||
bool has_valid_config(sidechain_type sidechain) const;
|
||||
};
|
||||
|
||||
struct by_account;
|
||||
|
|
@ -105,14 +115,14 @@ namespace graphene { namespace chain {
|
|||
ordered_unique< tag<by_account>,
|
||||
member<son_object, account_id_type, &son_object::son_account>
|
||||
>,
|
||||
ordered_unique< tag<by_vote_id_bitcoin>,
|
||||
const_mem_fun<son_object, vote_id_type, &son_object::get_bitcoin_vote_id>
|
||||
ordered_non_unique< tag<by_vote_id_bitcoin>,
|
||||
const_mem_fun<son_object, optional<vote_id_type>, &son_object::get_bitcoin_vote_id>
|
||||
>,
|
||||
ordered_unique< tag<by_vote_id_hive>,
|
||||
const_mem_fun<son_object, vote_id_type, &son_object::get_hive_vote_id>
|
||||
ordered_non_unique< tag<by_vote_id_hive>,
|
||||
const_mem_fun<son_object, optional<vote_id_type>, &son_object::get_hive_vote_id>
|
||||
>,
|
||||
ordered_unique< tag<by_vote_id_ethereum>,
|
||||
const_mem_fun<son_object, vote_id_type, &son_object::get_ethereum_vote_id>
|
||||
ordered_non_unique< tag<by_vote_id_ethereum>,
|
||||
const_mem_fun<son_object, optional<vote_id_type>, &son_object::get_ethereum_vote_id>
|
||||
>
|
||||
>
|
||||
>;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
#pragma once
|
||||
#include <graphene/chain/protocol/types.hpp>
|
||||
#include <graphene/chain/sidechain_defs.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
/**
|
||||
* @class son_sidechain_info
|
||||
* @brief tracks information about a SON info required to re/create primary wallet
|
||||
* @ingroup object
|
||||
*/
|
||||
struct son_sidechain_info {
|
||||
son_id_type son_id;
|
||||
weight_type weight = 0;
|
||||
public_key_type signing_key;
|
||||
string public_key;
|
||||
|
||||
bool operator==(const son_sidechain_info& rhs) const {
|
||||
bool son_sets_equal =
|
||||
(son_id == rhs.son_id) &&
|
||||
(weight == rhs.weight) &&
|
||||
(signing_key == rhs.signing_key) &&
|
||||
(public_key == rhs.public_key);
|
||||
|
||||
return son_sets_equal;
|
||||
}
|
||||
};
|
||||
|
||||
} }
|
||||
|
||||
FC_REFLECT( graphene::chain::son_sidechain_info, (son_id) (weight) (signing_key) (public_key) )
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
#include <graphene/chain/protocol/types.hpp>
|
||||
#include <graphene/chain/son_info.hpp>
|
||||
#include <graphene/chain/son_sidechain_info.hpp>
|
||||
#include <graphene/chain/sidechain_defs.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
|
@ -21,7 +21,7 @@ namespace graphene { namespace chain {
|
|||
time_point_sec expires;
|
||||
|
||||
flat_map<sidechain_type, string> addresses;
|
||||
flat_map<sidechain_type, vector<son_info> > sons;
|
||||
flat_map<sidechain_type, vector<son_sidechain_info> > sons;
|
||||
};
|
||||
|
||||
struct by_valid_from;
|
||||
|
|
|
|||
|
|
@ -174,31 +174,37 @@ void account_options::validate() const
|
|||
{
|
||||
auto needed_witnesses = num_witness;
|
||||
auto needed_committee = num_committee;
|
||||
FC_ASSERT( extensions.value.num_son.valid() , "Invalid son number" );
|
||||
flat_map<sidechain_type, uint16_t> needed_sons = *extensions.value.num_son;
|
||||
|
||||
for( vote_id_type id : votes )
|
||||
if( id.type() == vote_id_type::witness && needed_witnesses )
|
||||
--needed_witnesses;
|
||||
else if ( id.type() == vote_id_type::committee && needed_committee )
|
||||
--needed_committee;
|
||||
else if ( id.type() == vote_id_type::son_bitcoin && needed_sons[sidechain_type::bitcoin] )
|
||||
--needed_sons[sidechain_type::bitcoin];
|
||||
else if ( id.type() == vote_id_type::son_hive && needed_sons[sidechain_type::hive] )
|
||||
--needed_sons[sidechain_type::hive];
|
||||
else if ( id.type() == vote_id_type::son_ethereum && needed_sons[sidechain_type::ethereum] )
|
||||
--needed_sons[sidechain_type::ethereum];
|
||||
|
||||
FC_ASSERT( needed_witnesses == 0,
|
||||
"May not specify fewer witnesses than the number voted for.");
|
||||
FC_ASSERT( needed_committee == 0,
|
||||
"May not specify fewer committee members than the number voted for.");
|
||||
FC_ASSERT( needed_sons[sidechain_type::bitcoin] == 0,
|
||||
"May not specify fewer Bitcoin SONs than the number voted for.");
|
||||
FC_ASSERT( needed_sons[sidechain_type::hive] == 0,
|
||||
"May not specify fewer Hive SONs than the number voted for.");
|
||||
FC_ASSERT( needed_sons[sidechain_type::ethereum] == 0,
|
||||
"May not specify fewer Ethereum SONs than the number voted for.");
|
||||
|
||||
if ( extensions.value.num_son.valid() )
|
||||
{
|
||||
flat_map<sidechain_type, uint16_t> needed_sons = *extensions.value.num_son;
|
||||
|
||||
for( vote_id_type id : votes )
|
||||
if ( id.type() == vote_id_type::son_bitcoin && needed_sons[sidechain_type::bitcoin] )
|
||||
--needed_sons[sidechain_type::bitcoin];
|
||||
else if ( id.type() == vote_id_type::son_hive && needed_sons[sidechain_type::hive] )
|
||||
--needed_sons[sidechain_type::hive];
|
||||
else if ( id.type() == vote_id_type::son_ethereum && needed_sons[sidechain_type::ethereum] )
|
||||
--needed_sons[sidechain_type::ethereum];
|
||||
|
||||
FC_ASSERT( needed_sons[sidechain_type::bitcoin] == 0,
|
||||
"May not specify fewer Bitcoin SONs than the number voted for.");
|
||||
FC_ASSERT( needed_sons[sidechain_type::hive] == 0,
|
||||
"May not specify fewer Hive SONs than the number voted for.");
|
||||
FC_ASSERT( needed_sons[sidechain_type::ethereum] == 0,
|
||||
"May not specify fewer Ethereum SONs than the number voted for.");
|
||||
}
|
||||
}
|
||||
|
||||
void affiliate_reward_distribution::validate() const
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ namespace graphene { namespace chain {
|
|||
void_result sidechain_transaction_create_evaluator::do_evaluate(const sidechain_transaction_create_operation &op)
|
||||
{ try {
|
||||
FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK");
|
||||
FC_ASSERT( op.payer == db().get_global_properties().parameters.son_account(), "SON paying account must be set as payer." );
|
||||
FC_ASSERT(op.payer == db().get_global_properties().parameters.son_account(), "SON paying account must be set as payer.");
|
||||
|
||||
FC_ASSERT((op.object_id.is<son_wallet_id_type>() || op.object_id.is<son_wallet_deposit_id_type>() || op.object_id.is<son_wallet_withdraw_id_type>()), "Invalid object id");
|
||||
|
||||
|
|
@ -28,15 +28,27 @@ void_result sidechain_transaction_create_evaluator::do_evaluate(const sidechain_
|
|||
object_id_type sidechain_transaction_create_evaluator::do_apply(const sidechain_transaction_create_operation &op)
|
||||
{ try {
|
||||
const auto &new_sidechain_transaction_object = db().create<sidechain_transaction_object>([&](sidechain_transaction_object &sto) {
|
||||
|
||||
sto.timestamp = db().head_block_time();
|
||||
sto.sidechain = op.sidechain;
|
||||
sto.object_id = op.object_id;
|
||||
sto.transaction = op.transaction;
|
||||
sto.signers = op.signers;
|
||||
std::transform(op.signers.begin(), op.signers.end(), std::inserter(sto.signatures, sto.signatures.end()), [](const son_info &si) {
|
||||
std::vector<son_sidechain_info> signers;
|
||||
signers.resize(op.signers.size());
|
||||
for(const auto& signer : op.signers){
|
||||
son_sidechain_info ssi;
|
||||
ssi.son_id = signer.son_id;
|
||||
ssi.weight = signer.weight;
|
||||
ssi.signing_key = signer.signing_key;
|
||||
ssi.public_key = signer.sidechain_public_keys.at(op.sidechain);
|
||||
signers.emplace_back(std::move(ssi));
|
||||
}
|
||||
sto.signers = std::move(signers);
|
||||
|
||||
std::transform(sto.signers.begin(), sto.signers.end(), std::inserter(sto.signatures, sto.signatures.end()), [](const son_sidechain_info &si) {
|
||||
return std::make_pair(si.son_id, std::string());
|
||||
});
|
||||
for (const auto &si : op.signers) {
|
||||
for (const auto &si : sto.signers) {
|
||||
sto.total_weight = sto.total_weight + si.weight;
|
||||
}
|
||||
sto.sidechain_transaction = "";
|
||||
|
|
|
|||
|
|
@ -38,20 +38,29 @@ void_result create_son_evaluator::do_evaluate(const son_create_operation& op)
|
|||
|
||||
object_id_type create_son_evaluator::do_apply(const son_create_operation& op)
|
||||
{ try {
|
||||
vote_id_type vote_id_bitcoin;
|
||||
vote_id_type vote_id_hive;
|
||||
vote_id_type vote_id_ethereum;
|
||||
db().modify(db().get_global_properties(), [&vote_id_bitcoin, &vote_id_hive, &vote_id_ethereum](global_property_object& p) {
|
||||
vote_id_bitcoin = get_next_vote_id(p, vote_id_type::son_bitcoin);
|
||||
vote_id_hive = get_next_vote_id(p, vote_id_type::son_hive);
|
||||
vote_id_ethereum = get_next_vote_id(p, vote_id_type::son_ethereum);
|
||||
});
|
||||
vote_id_type vote_id;
|
||||
flat_map<sidechain_type, vote_id_type> vote_ids;
|
||||
|
||||
const auto& new_son_object = db().create<son_object>( [&]( son_object& obj ){
|
||||
const auto now = db().head_block_time();
|
||||
if( now < HARDFORK_SON_FOR_ETHEREUM_TIME ) {
|
||||
db().modify(db().get_global_properties(), [&vote_id](global_property_object &p) {
|
||||
vote_id = get_next_vote_id(p, vote_id_type::son_bitcoin);
|
||||
});
|
||||
}
|
||||
else {
|
||||
db().modify(db().get_global_properties(), [&vote_ids](global_property_object &p) {
|
||||
vote_ids[sidechain_type::bitcoin] = get_next_vote_id(p, vote_id_type::son_bitcoin);
|
||||
vote_ids[sidechain_type::hive] = get_next_vote_id(p, vote_id_type::son_hive);
|
||||
vote_ids[sidechain_type::ethereum] = get_next_vote_id(p, vote_id_type::son_ethereum);
|
||||
});
|
||||
}
|
||||
|
||||
const auto& new_son_object = db().create<son_object>( [&]( son_object& obj ) {
|
||||
obj.son_account = op.owner_account;
|
||||
obj.sidechain_vote_ids[sidechain_type::bitcoin] = vote_id_bitcoin;
|
||||
obj.sidechain_vote_ids[sidechain_type::hive] = vote_id_hive;
|
||||
obj.sidechain_vote_ids[sidechain_type::ethereum] = vote_id_ethereum;
|
||||
if( now < HARDFORK_SON_FOR_ETHEREUM_TIME )
|
||||
obj.sidechain_vote_ids[sidechain_type::bitcoin] = vote_id;
|
||||
else
|
||||
obj.sidechain_vote_ids = vote_ids;
|
||||
obj.url = op.url;
|
||||
obj.deposit = op.deposit;
|
||||
obj.signing_key = op.signing_key;
|
||||
|
|
@ -168,7 +177,7 @@ void_result son_heartbeat_evaluator::do_evaluate(const son_heartbeat_operation&
|
|||
fc::time_point_sec min_ts = db().head_block_time() - fc::seconds(5 * db().block_interval());
|
||||
// Account for server ntp sync difference
|
||||
fc::time_point_sec max_ts = db().head_block_time() + fc::seconds(5 * db().block_interval());
|
||||
for(const auto& active_sidechain_type : active_sidechain_types) {
|
||||
for(const auto& active_sidechain_type : active_sidechain_types(db().head_block_time())) {
|
||||
if(stats.last_active_timestamp.contains(active_sidechain_type))
|
||||
FC_ASSERT(op.ts > stats.last_active_timestamp.at(active_sidechain_type), "Heartbeat sent for sidechain = ${sidechain} without waiting minimum time", ("sidechain", active_sidechain_type));
|
||||
if(stats.last_down_timestamp.contains(active_sidechain_type))
|
||||
|
|
@ -195,7 +204,7 @@ object_id_type son_heartbeat_evaluator::do_apply(const son_heartbeat_operation&
|
|||
active_son_ids.reserve(active_sons.size());
|
||||
std::transform(active_sons.cbegin(), active_sons.cend(),
|
||||
std::inserter(active_son_ids, active_son_ids.end()),
|
||||
[](const son_info &swi) {
|
||||
[](const son_sidechain_info &swi) {
|
||||
return swi.son_id;
|
||||
});
|
||||
|
||||
|
|
@ -244,7 +253,7 @@ void_result son_report_down_evaluator::do_evaluate(const son_report_down_operati
|
|||
status_need_to_report_down = true;
|
||||
}
|
||||
FC_ASSERT(status_need_to_report_down, "Inactive/Deregistered/in_maintenance SONs cannot be reported on as down");
|
||||
for(const auto& active_sidechain_type : active_sidechain_types) {
|
||||
for(const auto& active_sidechain_type : active_sidechain_types(db().head_block_time())) {
|
||||
if(stats.last_active_timestamp.contains(active_sidechain_type))
|
||||
FC_ASSERT(op.down_ts >= stats.last_active_timestamp.at(active_sidechain_type), "sidechain = ${sidechain} down_ts should be greater than last_active_timestamp", ("sidechain", active_sidechain_type));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,24 +6,22 @@ namespace graphene { namespace chain {
|
|||
db.adjust_balance(son_account, pay);
|
||||
}
|
||||
|
||||
bool son_object::has_valid_config()const {
|
||||
return ((std::string(signing_key).length() > 0) &&
|
||||
(sidechain_public_keys.size() > 0) &&
|
||||
(sidechain_public_keys.find( sidechain_type::bitcoin ) != sidechain_public_keys.end()) &&
|
||||
(sidechain_public_keys.at(sidechain_type::bitcoin).length() > 0));
|
||||
bool son_object::has_valid_config(sidechain_type sidechain) const {
|
||||
return (sidechain_public_keys.find( sidechain ) != sidechain_public_keys.end()) &&
|
||||
(sidechain_public_keys.at(sidechain).length() > 0);
|
||||
}
|
||||
|
||||
bool son_object::has_valid_config(time_point_sec head_block_time)const {
|
||||
bool retval = has_valid_config();
|
||||
bool son_object::has_valid_config(time_point_sec head_block_time, sidechain_type sidechain) const {
|
||||
bool retval = (std::string(signing_key).length() > 0) && (sidechain_public_keys.size() > 0);
|
||||
|
||||
if (head_block_time >= HARDFORK_SON_FOR_HIVE_TIME) {
|
||||
retval = retval &&
|
||||
(sidechain_public_keys.find( sidechain_type::hive ) != sidechain_public_keys.end()) &&
|
||||
(sidechain_public_keys.at(sidechain_type::hive).length() > 0);
|
||||
|
||||
retval = retval &&
|
||||
(sidechain_public_keys.find( sidechain_type::ethereum ) != sidechain_public_keys.end()) &&
|
||||
(sidechain_public_keys.at(sidechain_type::ethereum).length() > 0);
|
||||
if (head_block_time < HARDFORK_SON_FOR_HIVE_TIME) {
|
||||
retval = retval && has_valid_config(sidechain_type::bitcoin);
|
||||
}
|
||||
if (head_block_time >= HARDFORK_SON_FOR_HIVE_TIME && head_block_time < HARDFORK_SON_FOR_ETHEREUM_TIME) {
|
||||
retval = retval && has_valid_config(sidechain_type::bitcoin) && has_valid_config(sidechain_type::hive);
|
||||
}
|
||||
else if (head_block_time >= HARDFORK_SON_FOR_ETHEREUM_TIME) {
|
||||
retval = retval && has_valid_config(sidechain);
|
||||
}
|
||||
|
||||
return retval;
|
||||
|
|
|
|||
|
|
@ -7,8 +7,9 @@ namespace graphene { namespace chain {
|
|||
|
||||
void_result recreate_son_wallet_evaluator::do_evaluate(const son_wallet_recreate_operation& op)
|
||||
{ try{
|
||||
FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK");
|
||||
FC_ASSERT( op.payer == db().get_global_properties().parameters.son_account(), "SON paying account must be set as payer." );
|
||||
const auto now = db().head_block_time();
|
||||
FC_ASSERT(now >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK");
|
||||
FC_ASSERT(op.payer == db().get_global_properties().parameters.son_account(), "SON paying account must be set as payer.");
|
||||
|
||||
const auto& idx = db().get_index_type<son_wallet_index>().indices().get<by_id>();
|
||||
auto itr = idx.rbegin();
|
||||
|
|
@ -16,7 +17,23 @@ void_result recreate_son_wallet_evaluator::do_evaluate(const son_wallet_recreate
|
|||
{
|
||||
// Compare current wallet SONs and to-be lists of active sons
|
||||
auto cur_wallet_sons = (*itr).sons;
|
||||
auto new_wallet_sons = op.sons;
|
||||
flat_map<sidechain_type, vector<son_sidechain_info> > new_wallet_sons;
|
||||
if( now < HARDFORK_SON_FOR_ETHEREUM_TIME ) {
|
||||
for(const auto& son : op.sons){
|
||||
for(const auto& active_sidechain_type : active_sidechain_types(db().head_block_time())){
|
||||
son_sidechain_info ssi;
|
||||
ssi.son_id = son.son_id;
|
||||
ssi.weight = son.weight;
|
||||
ssi.signing_key = son.signing_key;
|
||||
ssi.public_key = son.sidechain_public_keys.at(active_sidechain_type);
|
||||
new_wallet_sons[active_sidechain_type].emplace_back(std::move(ssi));
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
FC_ASSERT(op.extensions.value.sidechain_sons.valid(), "Sons is not valid");
|
||||
new_wallet_sons = *op.extensions.value.sidechain_sons;
|
||||
}
|
||||
|
||||
bool son_sets_equal = (cur_wallet_sons.size() == new_wallet_sons.size());
|
||||
if (son_sets_equal) {
|
||||
|
|
@ -51,9 +68,26 @@ object_id_type recreate_son_wallet_evaluator::do_apply(const son_wallet_recreate
|
|||
}
|
||||
|
||||
const auto& new_son_wallet_object = db().create<son_wallet_object>( [&]( son_wallet_object& obj ){
|
||||
obj.valid_from = db().head_block_time();
|
||||
const auto now = db().head_block_time();
|
||||
obj.valid_from = now;
|
||||
obj.expires = time_point_sec::maximum();
|
||||
obj.sons = op.sons;
|
||||
if( now < HARDFORK_SON_FOR_ETHEREUM_TIME ) {
|
||||
flat_map<sidechain_type, vector<son_sidechain_info> > sons;
|
||||
for(const auto& son : op.sons){
|
||||
for(const auto& active_sidechain_type : active_sidechain_types(db().head_block_time())){
|
||||
son_sidechain_info ssi;
|
||||
ssi.son_id = son.son_id;
|
||||
ssi.weight = son.weight;
|
||||
ssi.signing_key = son.signing_key;
|
||||
ssi.public_key = son.sidechain_public_keys.at(active_sidechain_type);
|
||||
sons[active_sidechain_type].emplace_back(std::move(ssi));
|
||||
}
|
||||
}
|
||||
obj.sons = std::move(sons);
|
||||
}
|
||||
else{
|
||||
obj.sons = *op.extensions.value.sidechain_sons;
|
||||
}
|
||||
});
|
||||
return new_son_wallet_object.id;
|
||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||
|
|
|
|||
|
|
@ -10,12 +10,13 @@ namespace graphene { namespace chain {
|
|||
|
||||
void_result create_son_wallet_withdraw_evaluator::do_evaluate(const son_wallet_withdraw_create_operation& op)
|
||||
{ try {
|
||||
FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK");
|
||||
|
||||
const auto now = db().head_block_time();
|
||||
FC_ASSERT(now >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK");
|
||||
const auto &son_idx = db().get_index_type<son_index>().indices().get<by_id>();
|
||||
const auto so = son_idx.find(op.son_id);
|
||||
FC_ASSERT(so != son_idx.end(), "SON not found");
|
||||
FC_ASSERT(so->son_account == op.payer, "Payer is not SON account owner");
|
||||
FC_ASSERT(!(op.sidechain == sidechain_type::peerplays && now >= HARDFORK_SON_FOR_ETHEREUM_TIME), "Peerplays sidechain type is not allowed");
|
||||
|
||||
const auto &ss_idx = db().get_index_type<son_stats_index>().indices().get<by_owner>();
|
||||
FC_ASSERT(ss_idx.find(op.son_id) != ss_idx.end(), "Statistic object for a given SON ID does not exists");
|
||||
|
|
@ -23,9 +24,17 @@ void_result create_son_wallet_withdraw_evaluator::do_evaluate(const son_wallet_w
|
|||
const auto &swwo_idx = db().get_index_type<son_wallet_withdraw_index>().indices().get<by_peerplays_uid>();
|
||||
const auto swwo = swwo_idx.find(op.peerplays_uid);
|
||||
if (swwo == swwo_idx.end()) {
|
||||
const sidechain_type sidechain = [&op]{
|
||||
if(op.sidechain == sidechain_type::peerplays){
|
||||
return op.withdraw_sidechain;
|
||||
}
|
||||
else
|
||||
return op.sidechain;
|
||||
}();
|
||||
|
||||
const auto &gpo = db().get_global_properties();
|
||||
bool expected = false;
|
||||
for (auto &si : gpo.active_sons.at(op.sidechain)) {
|
||||
for (auto &si : gpo.active_sons.at(sidechain)) {
|
||||
if (op.son_id == si.son_id) {
|
||||
expected = true;
|
||||
break;
|
||||
|
|
@ -76,8 +85,16 @@ object_id_type create_son_wallet_withdraw_evaluator::do_apply(const son_wallet_w
|
|||
swwo.withdraw_currency = op.withdraw_currency;
|
||||
swwo.withdraw_amount = op.withdraw_amount;
|
||||
|
||||
const sidechain_type sidechain = [&op]{
|
||||
if(op.sidechain == sidechain_type::peerplays){
|
||||
return op.withdraw_sidechain;
|
||||
}
|
||||
else
|
||||
return op.sidechain;
|
||||
}();
|
||||
|
||||
const auto &gpo = db().get_global_properties();
|
||||
for (auto &si : gpo.active_sons.at(op.sidechain)) {
|
||||
for (auto &si : gpo.active_sons.at(sidechain)) {
|
||||
swwo.expected_reports.insert(std::make_pair(si.son_id, si.weight));
|
||||
|
||||
auto stats_itr = db().get_index_type<son_stats_index>().indices().get<by_owner>().find(si.son_id);
|
||||
|
|
@ -138,13 +155,17 @@ object_id_type create_son_wallet_withdraw_evaluator::do_apply(const son_wallet_w
|
|||
|
||||
void_result process_son_wallet_withdraw_evaluator::do_evaluate(const son_wallet_withdraw_process_operation& op)
|
||||
{ try{
|
||||
FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK");
|
||||
const auto now = db().head_block_time();
|
||||
FC_ASSERT(now >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK");
|
||||
FC_ASSERT( op.payer == db().get_global_properties().parameters.son_account(), "SON paying account must be set as payer." );
|
||||
|
||||
const auto& idx = db().get_index_type<son_wallet_withdraw_index>().indices().get<by_id>();
|
||||
const auto& itr = idx.find(op.son_wallet_withdraw_id);
|
||||
FC_ASSERT(itr != idx.end(), "Son wallet withdraw not found");
|
||||
FC_ASSERT(db().get_global_properties().active_sons.at(itr->sidechain).size() >= db().get_chain_properties().immutable_parameters.min_son_count, "Min required voted SONs not present");
|
||||
FC_ASSERT(!(itr->sidechain == sidechain_type::peerplays && now >= HARDFORK_SON_FOR_ETHEREUM_TIME), "Peerplays sidechain type is not allowed");
|
||||
if(itr->sidechain != sidechain_type::peerplays) {
|
||||
FC_ASSERT(db().get_global_properties().active_sons.at(itr->sidechain).size() >= db().get_chain_properties().immutable_parameters.min_son_count, "Min required voted SONs not present");
|
||||
}
|
||||
FC_ASSERT(!itr->processed, "Son wallet withdraw is already processed");
|
||||
return void_result();
|
||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ private:
|
|||
std::mutex event_handler_mutex;
|
||||
typedef std::lock_guard<decltype(event_handler_mutex)> scoped_lock;
|
||||
|
||||
std::string create_primary_wallet_address(const std::vector<son_info> &son_pubkeys);
|
||||
std::string create_primary_wallet_address(const std::vector<son_sidechain_info> &son_pubkeys);
|
||||
|
||||
std::string create_primary_wallet_transaction(const son_wallet_object &prev_swo, std::string new_sw_address);
|
||||
std::string create_deposit_transaction(const son_wallet_deposit_object &swdo);
|
||||
|
|
|
|||
|
|
@ -68,7 +68,8 @@ private:
|
|||
ethereum::chain_id_type chain_id;
|
||||
ethereum::network_id_type network_id;
|
||||
|
||||
std::string create_primary_wallet_transaction(const std::vector<son_info> &son_pubkeys, const std::string &object_id);
|
||||
std::string create_primary_wallet_transaction(const std::vector<son_sidechain_info> &son_pubkeys, const std::string &object_id);
|
||||
std::string create_deposit_transaction(const son_wallet_deposit_object &swdo);
|
||||
std::string create_withdrawal_transaction(const son_wallet_withdraw_object &swwo);
|
||||
|
||||
std::string sign_transaction(const sidechain_transaction_object &sto);
|
||||
|
|
|
|||
|
|
@ -116,21 +116,21 @@ peerplays_sidechain_plugin_impl::peerplays_sidechain_plugin_impl(peerplays_sidec
|
|||
sidechain_enabled_peerplays(false),
|
||||
current_son_id([] {
|
||||
std::map<sidechain_type, son_id_type> current_son_id;
|
||||
for (const auto &active_sidechain_type : active_sidechain_types) {
|
||||
for (const auto &active_sidechain_type : all_sidechain_types) {
|
||||
current_son_id.emplace(active_sidechain_type, son_id_type(std::numeric_limits<uint32_t>().max()));
|
||||
}
|
||||
return current_son_id;
|
||||
}()),
|
||||
sidechain_enabled([] {
|
||||
std::map<sidechain_type, bool> sidechain_enabled;
|
||||
for (const auto &active_sidechain_type : active_sidechain_types) {
|
||||
for (const auto &active_sidechain_type : all_sidechain_types) {
|
||||
sidechain_enabled.emplace(active_sidechain_type, false);
|
||||
}
|
||||
return sidechain_enabled;
|
||||
}()),
|
||||
net_handlers([] {
|
||||
std::map<sidechain_type, std::unique_ptr<sidechain_net_handler>> net_handlers;
|
||||
for (const auto &active_sidechain_type : active_sidechain_types) {
|
||||
for (const auto &active_sidechain_type : all_sidechain_types) {
|
||||
net_handlers.emplace(active_sidechain_type, nullptr);
|
||||
}
|
||||
return net_handlers;
|
||||
|
|
@ -149,7 +149,7 @@ peerplays_sidechain_plugin_impl::~peerplays_sidechain_plugin_impl() {
|
|||
}
|
||||
|
||||
try {
|
||||
for (const auto &active_sidechain_type : active_sidechain_types) {
|
||||
for (const auto &active_sidechain_type : all_sidechain_types) {
|
||||
if (_son_processing_task.count(active_sidechain_type) != 0 && _son_processing_task.at(active_sidechain_type).valid())
|
||||
_son_processing_task.at(active_sidechain_type).wait();
|
||||
}
|
||||
|
|
@ -362,7 +362,7 @@ bool peerplays_sidechain_plugin_impl::is_active_son(sidechain_type sidechain, so
|
|||
set<son_id_type> active_son_ids;
|
||||
std::transform(gpo.active_sons.at(sidechain).cbegin(), gpo.active_sons.at(sidechain).cend(),
|
||||
std::inserter(active_son_ids, active_son_ids.end()),
|
||||
[](const son_info &swi) {
|
||||
[](const son_sidechain_info &swi) {
|
||||
return swi.son_id;
|
||||
});
|
||||
|
||||
|
|
@ -415,7 +415,7 @@ bool peerplays_sidechain_plugin_impl::is_son_down_op_valid(const chain::operatio
|
|||
status_son_down_op_valid = false;
|
||||
}
|
||||
if (status_son_down_op_valid) {
|
||||
for (const auto &active_sidechain_type : active_sidechain_types) {
|
||||
for (const auto &active_sidechain_type : active_sidechain_types(d.head_block_time())) {
|
||||
if (stats.last_active_timestamp.contains(active_sidechain_type)) {
|
||||
const fc::time_point_sec last_active_ts = ((stats.last_active_timestamp.at(active_sidechain_type) > last_maintenance_time) ? stats.last_active_timestamp.at(active_sidechain_type) : last_maintenance_time);
|
||||
if (((fc::time_point::now() - last_active_ts) <= fc::seconds(down_threshold))) {
|
||||
|
|
@ -468,7 +468,7 @@ void peerplays_sidechain_plugin_impl::heartbeat_loop() {
|
|||
|
||||
//! Check that son is active (at least for one sidechain_type)
|
||||
bool is_son_active = false;
|
||||
for (const auto &active_sidechain_type : active_sidechain_types) {
|
||||
for (const auto &active_sidechain_type : active_sidechain_types(d.head_block_time())) {
|
||||
if (sidechain_enabled.at(active_sidechain_type)) {
|
||||
if (is_active_son(active_sidechain_type, son_id))
|
||||
is_son_active = true;
|
||||
|
|
@ -506,7 +506,7 @@ void peerplays_sidechain_plugin_impl::schedule_son_processing() {
|
|||
|
||||
const auto next_wakeup = now + std::chrono::microseconds(time_to_next_son_processing);
|
||||
|
||||
for (const auto &active_sidechain_type : active_sidechain_types) {
|
||||
for (const auto &active_sidechain_type : active_sidechain_types(plugin.database().head_block_time())) {
|
||||
if (_son_processing_task.count(active_sidechain_type) != 0 && _son_processing_task.at(active_sidechain_type).wait_for(std::chrono::seconds{0}) != std::future_status::ready) {
|
||||
wlog("Son doesn't process in time for sidechain: ${active_sidechain_type}", ("active_sidechain_type", active_sidechain_type));
|
||||
_son_processing_task.at(active_sidechain_type).wait();
|
||||
|
|
@ -623,7 +623,7 @@ bool peerplays_sidechain_plugin_impl::can_son_participate(sidechain_type sidecha
|
|||
|
||||
std::map<sidechain_type, std::vector<std::string>> peerplays_sidechain_plugin_impl::get_son_listener_log() {
|
||||
std::map<sidechain_type, std::vector<std::string>> result;
|
||||
for (const auto &active_sidechain_type : active_sidechain_types) {
|
||||
for (const auto &active_sidechain_type : active_sidechain_types(plugin.database().head_block_time())) {
|
||||
if (net_handlers.at(active_sidechain_type)) {
|
||||
result.emplace(active_sidechain_type, net_handlers.at(active_sidechain_type)->get_son_listener_log());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
#include <graphene/chain/account_object.hpp>
|
||||
#include <graphene/chain/protocol/son_wallet.hpp>
|
||||
#include <graphene/chain/sidechain_transaction_object.hpp>
|
||||
#include <graphene/chain/son_info.hpp>
|
||||
#include <graphene/chain/son_sidechain_info.hpp>
|
||||
#include <graphene/chain/son_wallet_object.hpp>
|
||||
#include <graphene/peerplays_sidechain/bitcoin/bitcoin_address.hpp>
|
||||
#include <graphene/peerplays_sidechain/bitcoin/bitcoin_transaction.hpp>
|
||||
|
|
@ -453,7 +453,7 @@ bool sidechain_net_handler_bitcoin::process_proposal(const proposal_object &po)
|
|||
if (swo != idx.end()) {
|
||||
|
||||
const auto &active_sons = gpo.active_sons.at(sidechain);
|
||||
vector<son_info> wallet_sons = swo->sons.at(sidechain);
|
||||
const auto &wallet_sons = swo->sons.at(sidechain);
|
||||
|
||||
bool son_sets_equal = (active_sons.size() == wallet_sons.size());
|
||||
|
||||
|
|
@ -466,7 +466,7 @@ bool sidechain_net_handler_bitcoin::process_proposal(const proposal_object &po)
|
|||
if (son_sets_equal) {
|
||||
const auto &active_sons = gpo.active_sons.at(sidechain);
|
||||
vector<string> son_pubkeys_bitcoin;
|
||||
for (const son_info &si : active_sons) {
|
||||
for (const auto &si : active_sons) {
|
||||
son_pubkeys_bitcoin.push_back(si.public_key);
|
||||
}
|
||||
|
||||
|
|
@ -758,7 +758,14 @@ void sidechain_net_handler_bitcoin::process_primary_wallet() {
|
|||
stc_op.object_id = prev_sw->id;
|
||||
stc_op.sidechain = sidechain;
|
||||
stc_op.transaction = tx_str;
|
||||
stc_op.signers = prev_sw->sons.at(sidechain);
|
||||
for (const auto &signer : prev_sw->sons.at(sidechain)) {
|
||||
son_info si;
|
||||
si.son_id = signer.son_id;
|
||||
si.weight = signer.weight;
|
||||
si.signing_key = signer.signing_key;
|
||||
si.sidechain_public_keys[sidechain] = signer.public_key;
|
||||
stc_op.signers.emplace_back(std::move(si));
|
||||
}
|
||||
proposal_op.proposed_ops.emplace_back(stc_op);
|
||||
}
|
||||
}
|
||||
|
|
@ -861,7 +868,14 @@ bool sidechain_net_handler_bitcoin::process_deposit(const son_wallet_deposit_obj
|
|||
stc_op.object_id = swdo.id;
|
||||
stc_op.sidechain = sidechain;
|
||||
stc_op.transaction = tx_str;
|
||||
stc_op.signers = gpo.active_sons.at(sidechain);
|
||||
for (const auto &signer : gpo.active_sons.at(sidechain)) {
|
||||
son_info si;
|
||||
si.son_id = signer.son_id;
|
||||
si.weight = signer.weight;
|
||||
si.signing_key = signer.signing_key;
|
||||
si.sidechain_public_keys[sidechain] = signer.public_key;
|
||||
stc_op.signers.emplace_back(std::move(si));
|
||||
}
|
||||
proposal_op.proposed_ops.emplace_back(stc_op);
|
||||
|
||||
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id(sidechain)), proposal_op);
|
||||
|
|
@ -905,7 +919,14 @@ bool sidechain_net_handler_bitcoin::process_withdrawal(const son_wallet_withdraw
|
|||
stc_op.object_id = swwo.id;
|
||||
stc_op.sidechain = sidechain;
|
||||
stc_op.transaction = tx_str;
|
||||
stc_op.signers = gpo.active_sons.at(sidechain);
|
||||
for (const auto &signer : gpo.active_sons.at(sidechain)) {
|
||||
son_info si;
|
||||
si.son_id = signer.son_id;
|
||||
si.weight = signer.weight;
|
||||
si.signing_key = signer.signing_key;
|
||||
si.sidechain_public_keys[sidechain] = signer.public_key;
|
||||
stc_op.signers.emplace_back(std::move(si));
|
||||
}
|
||||
proposal_op.proposed_ops.emplace_back(stc_op);
|
||||
|
||||
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id(sidechain)), proposal_op);
|
||||
|
|
@ -1007,7 +1028,7 @@ optional<asset> sidechain_net_handler_bitcoin::estimate_withdrawal_transaction_f
|
|||
return optional<asset>{};
|
||||
}
|
||||
|
||||
std::string sidechain_net_handler_bitcoin::create_primary_wallet_address(const std::vector<son_info> &son_pubkeys) {
|
||||
std::string sidechain_net_handler_bitcoin::create_primary_wallet_address(const std::vector<son_sidechain_info> &son_pubkeys) {
|
||||
using namespace bitcoin;
|
||||
|
||||
std::vector<std::pair<fc::ecc::public_key, uint16_t>> pubkey_weights;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
#include <graphene/chain/account_object.hpp>
|
||||
#include <graphene/chain/protocol/son_wallet.hpp>
|
||||
#include <graphene/chain/sidechain_transaction_object.hpp>
|
||||
#include <graphene/chain/son_info.hpp>
|
||||
#include <graphene/chain/son_sidechain_info.hpp>
|
||||
#include <graphene/chain/son_wallet_object.hpp>
|
||||
#include <graphene/peerplays_sidechain/ethereum/decoders.hpp>
|
||||
#include <graphene/peerplays_sidechain/ethereum/encoders.hpp>
|
||||
|
|
@ -239,7 +239,7 @@ bool sidechain_net_handler_ethereum::process_proposal(const proposal_object &po)
|
|||
if (swo != idx.end()) {
|
||||
|
||||
const auto active_sons = gpo.active_sons.at(sidechain);
|
||||
const vector<son_info> wallet_sons = swo->sons.at(sidechain);
|
||||
const vector<son_sidechain_info> wallet_sons = swo->sons.at(sidechain);
|
||||
|
||||
bool son_sets_equal = (active_sons.size() == wallet_sons.size());
|
||||
|
||||
|
|
@ -474,7 +474,7 @@ void sidechain_net_handler_ethereum::process_primary_wallet() {
|
|||
proposal_op.proposed_ops.emplace_back(swu_op);
|
||||
|
||||
const auto signers = [this, &prev_sw, &active_sw, &swi] {
|
||||
std::vector<son_info> signers;
|
||||
std::vector<son_sidechain_info> signers;
|
||||
//! Check if we don't have any previous set of active SONs use the current one
|
||||
if (prev_sw != swi.rend()) {
|
||||
if (!prev_sw->sons.at(sidechain).empty())
|
||||
|
|
@ -495,7 +495,14 @@ void sidechain_net_handler_ethereum::process_primary_wallet() {
|
|||
stc_op.object_id = active_sw->id;
|
||||
stc_op.sidechain = sidechain;
|
||||
stc_op.transaction = tx_str;
|
||||
stc_op.signers = signers;
|
||||
for (const auto &signer : signers) {
|
||||
son_info si;
|
||||
si.son_id = signer.son_id;
|
||||
si.weight = signer.weight;
|
||||
si.signing_key = signer.signing_key;
|
||||
si.sidechain_public_keys[sidechain] = signer.public_key;
|
||||
stc_op.signers.emplace_back(std::move(si));
|
||||
}
|
||||
proposal_op.proposed_ops.emplace_back(stc_op);
|
||||
}
|
||||
|
||||
|
|
@ -593,7 +600,14 @@ bool sidechain_net_handler_ethereum::process_withdrawal(const son_wallet_withdra
|
|||
stc_op.object_id = swwo.id;
|
||||
stc_op.sidechain = sidechain;
|
||||
stc_op.transaction = tx_str;
|
||||
stc_op.signers = gpo.active_sons.at(sidechain);
|
||||
for (const auto &signer : gpo.active_sons.at(sidechain)) {
|
||||
son_info si;
|
||||
si.son_id = signer.son_id;
|
||||
si.weight = signer.weight;
|
||||
si.signing_key = signer.signing_key;
|
||||
si.sidechain_public_keys[sidechain] = signer.public_key;
|
||||
stc_op.signers.emplace_back(std::move(si));
|
||||
}
|
||||
proposal_op.proposed_ops.emplace_back(stc_op);
|
||||
|
||||
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id(sidechain)), proposal_op);
|
||||
|
|
@ -773,7 +787,7 @@ optional<asset> sidechain_net_handler_ethereum::estimate_withdrawal_transaction_
|
|||
return asset.amount_from_string(std::to_string(eth_gas_fee));
|
||||
}
|
||||
|
||||
std::string sidechain_net_handler_ethereum::create_primary_wallet_transaction(const std::vector<son_info> &son_pubkeys, const std::string &object_id) {
|
||||
std::string sidechain_net_handler_ethereum::create_primary_wallet_transaction(const std::vector<son_sidechain_info> &son_pubkeys, const std::string &object_id) {
|
||||
std::vector<std::pair<std::string, uint16_t>> owners_weights;
|
||||
for (auto &son : son_pubkeys) {
|
||||
const std::string pub_key_str = son.public_key;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
#include <graphene/chain/account_object.hpp>
|
||||
#include <graphene/chain/protocol/fee_schedule.hpp>
|
||||
#include <graphene/chain/protocol/son_wallet.hpp>
|
||||
#include <graphene/chain/son_info.hpp>
|
||||
#include <graphene/chain/son_sidechain_info.hpp>
|
||||
#include <graphene/chain/son_wallet_object.hpp>
|
||||
#include <graphene/peerplays_sidechain/common/utils.hpp>
|
||||
#include <graphene/peerplays_sidechain/hive/asset.hpp>
|
||||
|
|
@ -213,8 +213,8 @@ bool sidechain_net_handler_hive::process_proposal(const proposal_object &po) {
|
|||
const auto swo = idx.find(swo_id);
|
||||
if (swo != idx.end()) {
|
||||
|
||||
auto active_sons = gpo.active_sons.at(sidechain);
|
||||
vector<son_info> wallet_sons = swo->sons.at(sidechain);
|
||||
const auto &active_sons = gpo.active_sons.at(sidechain);
|
||||
const auto &wallet_sons = swo->sons.at(sidechain);
|
||||
|
||||
bool son_sets_equal = (active_sons.size() == wallet_sons.size());
|
||||
|
||||
|
|
@ -549,7 +549,7 @@ void sidechain_net_handler_hive::process_primary_wallet() {
|
|||
proposal_op.proposed_ops.emplace_back(swu_op);
|
||||
|
||||
const auto signers = [this, &prev_sw, &active_sw, &swi] {
|
||||
std::vector<son_info> signers;
|
||||
std::vector<son_sidechain_info> signers;
|
||||
//! Check if we don't have any previous set of active SONs use the current one
|
||||
if (prev_sw != swi.rend()) {
|
||||
if (!prev_sw->sons.at(sidechain).empty())
|
||||
|
|
@ -568,8 +568,14 @@ void sidechain_net_handler_hive::process_primary_wallet() {
|
|||
stc_op.object_id = active_sw->id;
|
||||
stc_op.sidechain = sidechain;
|
||||
stc_op.transaction = tx_str;
|
||||
stc_op.signers = signers;
|
||||
|
||||
for (const auto &signer : gpo.active_sons.at(sidechain)) {
|
||||
son_info si;
|
||||
si.son_id = signer.son_id;
|
||||
si.weight = signer.weight;
|
||||
si.signing_key = signer.signing_key;
|
||||
si.sidechain_public_keys[sidechain] = signer.public_key;
|
||||
stc_op.signers.emplace_back(std::move(si));
|
||||
}
|
||||
proposal_op.proposed_ops.emplace_back(stc_op);
|
||||
|
||||
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id(sidechain)), proposal_op);
|
||||
|
|
@ -725,7 +731,14 @@ bool sidechain_net_handler_hive::process_withdrawal(const son_wallet_withdraw_ob
|
|||
stc_op.object_id = swwo.id;
|
||||
stc_op.sidechain = sidechain;
|
||||
stc_op.transaction = tx_str;
|
||||
stc_op.signers = gpo.active_sons.at(sidechain);
|
||||
for (const auto &signer : gpo.active_sons.at(sidechain)) {
|
||||
son_info si;
|
||||
si.son_id = signer.son_id;
|
||||
si.weight = signer.weight;
|
||||
si.signing_key = signer.signing_key;
|
||||
si.sidechain_public_keys[sidechain] = signer.public_key;
|
||||
stc_op.signers.emplace_back(std::move(si));
|
||||
}
|
||||
proposal_op.proposed_ops.emplace_back(stc_op);
|
||||
|
||||
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id(sidechain)), proposal_op);
|
||||
|
|
|
|||
|
|
@ -197,7 +197,14 @@ bool sidechain_net_handler_peerplays::process_deposit(const son_wallet_deposit_o
|
|||
stc_op.object_id = swdo.id;
|
||||
stc_op.sidechain = sidechain;
|
||||
stc_op.transaction = tx_str;
|
||||
stc_op.signers = gpo.active_sons.at(sidechain);
|
||||
for (const auto &signer : gpo.active_sons.at(sidechain)) {
|
||||
son_info si;
|
||||
si.son_id = signer.son_id;
|
||||
si.weight = signer.weight;
|
||||
si.signing_key = signer.signing_key;
|
||||
si.sidechain_public_keys[sidechain] = signer.public_key;
|
||||
stc_op.signers.emplace_back(std::move(si));
|
||||
}
|
||||
|
||||
proposal_create_operation proposal_op;
|
||||
proposal_op.fee_paying_account = plugin.get_current_son_object(sidechain).son_account;
|
||||
|
|
|
|||
|
|
@ -1559,14 +1559,14 @@ class wallet_api
|
|||
* @brief Get list of active sons
|
||||
* @return List of active SONs
|
||||
*/
|
||||
flat_map<sidechain_type, vector<son_info>> get_active_sons();
|
||||
flat_map<sidechain_type, vector<son_sidechain_info>> get_active_sons();
|
||||
|
||||
/**
|
||||
* @brief Get list of active sons
|
||||
* @param sidechain Sidechain type [bitcoin|ethereum|hive]
|
||||
* @return List of active SONs
|
||||
*/
|
||||
vector<son_info> get_active_sons_by_sidechain(sidechain_type sidechain);
|
||||
vector<son_sidechain_info> get_active_sons_by_sidechain(sidechain_type sidechain);
|
||||
|
||||
/**
|
||||
* @brief Get SON network status
|
||||
|
|
|
|||
|
|
@ -2230,12 +2230,12 @@ public:
|
|||
return sign_transaction( tx, broadcast );
|
||||
} FC_CAPTURE_AND_RETHROW( (owner_account) ) }
|
||||
|
||||
flat_map<sidechain_type, vector<son_info>> get_active_sons()
|
||||
flat_map<sidechain_type, vector<son_sidechain_info>> get_active_sons()
|
||||
{ try {
|
||||
return _remote_db->get_active_sons();
|
||||
} FC_CAPTURE_AND_RETHROW() }
|
||||
|
||||
vector<son_info> get_active_sons_by_sidechain(sidechain_type sidechain)
|
||||
vector<son_sidechain_info> get_active_sons_by_sidechain(sidechain_type sidechain)
|
||||
{ try {
|
||||
return _remote_db->get_active_sons_by_sidechain(sidechain);
|
||||
} FC_CAPTURE_AND_RETHROW() }
|
||||
|
|
@ -2775,13 +2775,15 @@ public:
|
|||
|
||||
if (approve)
|
||||
{
|
||||
auto insert_result = voting_account_object.options.votes.insert(son_obj->get_sidechain_vote_id(sidechain));
|
||||
FC_ASSERT(son_obj->get_sidechain_vote_id(sidechain).valid(), "Invalid vote id, sidechain: ${sidechain}, son: ${son}", ("sidechain", sidechain)("son", *son_obj));
|
||||
auto insert_result = voting_account_object.options.votes.insert(*son_obj->get_sidechain_vote_id(sidechain));
|
||||
if (!insert_result.second)
|
||||
FC_THROW("Account ${account} has already voted for son ${son} for sidechain ${sidechain}", ("account", voting_account)("son", son)("sidechain", sidechain));
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned votes_removed = voting_account_object.options.votes.erase(son_obj->get_sidechain_vote_id(sidechain));
|
||||
FC_ASSERT(son_obj->get_sidechain_vote_id(sidechain).valid(), "Invalid vote id, sidechain: ${sidechain}, son: ${son}", ("sidechain", sidechain)("son", *son_obj));
|
||||
unsigned votes_removed = voting_account_object.options.votes.erase(*son_obj->get_sidechain_vote_id(sidechain));
|
||||
if (!votes_removed)
|
||||
FC_THROW("Account ${account} has already unvoted for son ${son} for sidechain ${sidechain}", ("account", voting_account)("son", son)("sidechain", sidechain));
|
||||
}
|
||||
|
|
@ -2819,7 +2821,8 @@ public:
|
|||
FC_ASSERT(son_obj, "Account ${son} is not registered as a son", ("son", son));
|
||||
FC_ASSERT(sidechain == sidechain_type::bitcoin || sidechain == sidechain_type::hive || sidechain == sidechain_type::ethereum, "Unexpected sidechain type");
|
||||
|
||||
auto insert_result = voting_account_object.options.votes.insert(son_obj->get_sidechain_vote_id(sidechain));
|
||||
FC_ASSERT(son_obj->get_sidechain_vote_id(sidechain).valid(), "Invalid vote id, sidechain: ${sidechain}, son: ${son}", ("sidechain", sidechain)("son", *son_obj));
|
||||
auto insert_result = voting_account_object.options.votes.insert(*son_obj->get_sidechain_vote_id(sidechain));
|
||||
if (!insert_result.second)
|
||||
FC_THROW("Account ${account} was already voting for SON ${son}", ("account", voting_account)("son", son));
|
||||
}
|
||||
|
|
@ -2830,7 +2833,8 @@ public:
|
|||
FC_ASSERT(son_obj, "Account ${son} is not registered as a son", ("son", son));
|
||||
FC_ASSERT(sidechain == sidechain_type::bitcoin || sidechain == sidechain_type::hive || sidechain == sidechain_type::ethereum, "Unexpected sidechain type");
|
||||
|
||||
unsigned votes_removed = voting_account_object.options.votes.erase(son_obj->get_sidechain_vote_id(sidechain));
|
||||
FC_ASSERT(son_obj->get_sidechain_vote_id(sidechain).valid(), "Invalid vote id, sidechain: ${sidechain}, son: ${son}", ("sidechain", sidechain)("son", *son_obj));
|
||||
unsigned votes_removed = voting_account_object.options.votes.erase(*son_obj->get_sidechain_vote_id(sidechain));
|
||||
if (!votes_removed)
|
||||
FC_THROW("Account ${account} is already not voting for SON ${son}", ("account", voting_account)("son", son));
|
||||
}
|
||||
|
|
@ -5294,12 +5298,12 @@ map<string, son_id_type> wallet_api::list_sons(const string& lowerbound, uint32_
|
|||
return my->_remote_db->lookup_son_accounts(lowerbound, limit);
|
||||
}
|
||||
|
||||
flat_map<sidechain_type, vector<son_info>> wallet_api::get_active_sons()
|
||||
flat_map<sidechain_type, vector<son_sidechain_info>> wallet_api::get_active_sons()
|
||||
{
|
||||
return my->get_active_sons();
|
||||
}
|
||||
|
||||
vector<son_info> wallet_api::get_active_sons_by_sidechain(sidechain_type sidechain)
|
||||
vector<son_sidechain_info> wallet_api::get_active_sons_by_sidechain(sidechain_type sidechain)
|
||||
{
|
||||
return my->get_active_sons_by_sidechain(sidechain);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ public:
|
|||
fixture_(fixture)
|
||||
{
|
||||
fixture_.init_nathan();
|
||||
fixture_.generate_blocks(HARDFORK_SON3_TIME);
|
||||
fixture_.generate_blocks(HARDFORK_SON_FOR_ETHEREUM_TIME);
|
||||
fixture_.generate_block();
|
||||
}
|
||||
|
||||
|
|
@ -143,9 +143,12 @@ BOOST_AUTO_TEST_CASE( create_sons )
|
|||
BOOST_CHECK_EQUAL(son1_obj.sidechain_public_keys[sidechain_type::bitcoin], "bitcoin_address 1");
|
||||
BOOST_CHECK_EQUAL(son1_obj.sidechain_public_keys[sidechain_type::hive], "hive account 1");
|
||||
BOOST_CHECK_EQUAL(son1_obj.sidechain_public_keys[sidechain_type::ethereum], "ethereum address 1");
|
||||
BOOST_CHECK_EQUAL(son1_obj.get_sidechain_vote_id(sidechain_type::bitcoin).instance(), 22);
|
||||
BOOST_CHECK_EQUAL(son1_obj.get_sidechain_vote_id(sidechain_type::hive).instance(), 23);
|
||||
BOOST_CHECK_EQUAL(son1_obj.get_sidechain_vote_id(sidechain_type::ethereum).instance(), 24);
|
||||
BOOST_REQUIRE(son1_obj.get_sidechain_vote_id(sidechain_type::bitcoin));
|
||||
BOOST_CHECK_EQUAL(son1_obj.get_sidechain_vote_id(sidechain_type::bitcoin)->instance(), 22);
|
||||
BOOST_REQUIRE(son1_obj.get_sidechain_vote_id(sidechain_type::hive));
|
||||
BOOST_CHECK_EQUAL(son1_obj.get_sidechain_vote_id(sidechain_type::hive)->instance(), 23);
|
||||
BOOST_REQUIRE(son1_obj.get_sidechain_vote_id(sidechain_type::ethereum));
|
||||
BOOST_CHECK_EQUAL(son1_obj.get_sidechain_vote_id(sidechain_type::ethereum)->instance(), 24);
|
||||
|
||||
auto son2_obj = con.wallet_api_ptr->get_son("son2account");
|
||||
BOOST_CHECK(son2_obj.son_account == con.wallet_api_ptr->get_account_id("son2account"));
|
||||
|
|
@ -153,9 +156,12 @@ BOOST_AUTO_TEST_CASE( create_sons )
|
|||
BOOST_CHECK_EQUAL(son2_obj.sidechain_public_keys[sidechain_type::bitcoin], "bitcoin_address 2");
|
||||
BOOST_CHECK_EQUAL(son2_obj.sidechain_public_keys[sidechain_type::hive], "hive account 2");
|
||||
BOOST_CHECK_EQUAL(son2_obj.sidechain_public_keys[sidechain_type::ethereum], "ethereum address 2");
|
||||
BOOST_CHECK_EQUAL(son2_obj.get_sidechain_vote_id(sidechain_type::bitcoin).instance(), 25);
|
||||
BOOST_CHECK_EQUAL(son2_obj.get_sidechain_vote_id(sidechain_type::hive).instance(), 26);
|
||||
BOOST_CHECK_EQUAL(son2_obj.get_sidechain_vote_id(sidechain_type::ethereum).instance(), 27);
|
||||
BOOST_REQUIRE(son2_obj.get_sidechain_vote_id(sidechain_type::bitcoin));
|
||||
BOOST_CHECK_EQUAL(son2_obj.get_sidechain_vote_id(sidechain_type::bitcoin)->instance(), 25);
|
||||
BOOST_REQUIRE(son2_obj.get_sidechain_vote_id(sidechain_type::hive));
|
||||
BOOST_CHECK_EQUAL(son2_obj.get_sidechain_vote_id(sidechain_type::hive)->instance(), 26);
|
||||
BOOST_REQUIRE(son2_obj.get_sidechain_vote_id(sidechain_type::ethereum));
|
||||
BOOST_CHECK_EQUAL(son2_obj.get_sidechain_vote_id(sidechain_type::ethereum)->instance(), 27);
|
||||
|
||||
} catch( fc::exception& e ) {
|
||||
BOOST_TEST_MESSAGE("SON cli wallet tests exception");
|
||||
|
|
@ -190,9 +196,12 @@ BOOST_AUTO_TEST_CASE( cli_update_son )
|
|||
BOOST_CHECK_EQUAL(son_data.sidechain_public_keys[sidechain_type::bitcoin], "bitcoin_address 1");
|
||||
BOOST_CHECK_EQUAL(son_data.sidechain_public_keys[sidechain_type::hive], "hive account 1");
|
||||
BOOST_CHECK_EQUAL(son_data.sidechain_public_keys[sidechain_type::ethereum], "ethereum address 1");
|
||||
BOOST_CHECK_EQUAL(son_data.get_sidechain_vote_id(sidechain_type::bitcoin).instance(), 22);
|
||||
BOOST_CHECK_EQUAL(son_data.get_sidechain_vote_id(sidechain_type::hive).instance(), 23);
|
||||
BOOST_CHECK_EQUAL(son_data.get_sidechain_vote_id(sidechain_type::ethereum).instance(), 24);
|
||||
BOOST_REQUIRE(son_data.get_sidechain_vote_id(sidechain_type::bitcoin));
|
||||
BOOST_CHECK_EQUAL(son_data.get_sidechain_vote_id(sidechain_type::bitcoin)->instance(), 22);
|
||||
BOOST_REQUIRE(son_data.get_sidechain_vote_id(sidechain_type::hive));
|
||||
BOOST_CHECK_EQUAL(son_data.get_sidechain_vote_id(sidechain_type::hive)->instance(), 23);
|
||||
BOOST_REQUIRE(son_data.get_sidechain_vote_id(sidechain_type::ethereum));
|
||||
BOOST_CHECK_EQUAL(son_data.get_sidechain_vote_id(sidechain_type::ethereum)->instance(), 24);
|
||||
|
||||
// update SON
|
||||
sidechain_public_keys.clear();
|
||||
|
|
@ -1400,7 +1409,7 @@ BOOST_FIXTURE_TEST_CASE( get_son_network_status_by_sidechain, cli_fixture )
|
|||
|
||||
// Check Network Status Before sending Heartbeats
|
||||
BOOST_CHECK(generate_maintenance_block());
|
||||
for(sidechain_type sidechain:active_sidechain_types)
|
||||
for(sidechain_type sidechain : all_sidechain_types)
|
||||
{
|
||||
auto network_status_obj = con.wallet_api_ptr->get_son_network_status_by_sidechain(sidechain);
|
||||
for(map<son_id_type, string>::iterator iter=network_status_obj.begin(); iter!=network_status_obj.end(); ++iter)
|
||||
|
|
@ -1448,7 +1457,7 @@ BOOST_FIXTURE_TEST_CASE( get_son_network_status_by_sidechain, cli_fixture )
|
|||
generate_blocks(50);
|
||||
|
||||
BOOST_TEST_MESSAGE("Checking Network Status");
|
||||
for(sidechain_type sidechain:active_sidechain_types)
|
||||
for(sidechain_type sidechain : all_sidechain_types)
|
||||
{
|
||||
auto network_status_obj = con.wallet_api_ptr->get_son_network_status_by_sidechain(sidechain);
|
||||
for(map<son_id_type, string>::iterator iter=network_status_obj.begin(); iter!=network_status_obj.end(); ++iter)
|
||||
|
|
@ -1479,7 +1488,7 @@ BOOST_FIXTURE_TEST_CASE( get_son_network_status_by_sidechain, cli_fixture )
|
|||
con.wallet_api_ptr->sign_transaction(trx2, true);
|
||||
|
||||
generate_blocks(50);
|
||||
for(sidechain_type sidechain:active_sidechain_types)
|
||||
for(sidechain_type sidechain : all_sidechain_types)
|
||||
{
|
||||
auto network_status_obj = con.wallet_api_ptr->get_son_network_status_by_sidechain(sidechain);
|
||||
for(map<son_id_type, string>::iterator iter=network_status_obj.begin(); iter!=network_status_obj.end(); ++iter)
|
||||
|
|
@ -1507,7 +1516,7 @@ BOOST_FIXTURE_TEST_CASE( get_son_network_status_by_sidechain, cli_fixture )
|
|||
|
||||
generate_blocks(db->head_block_time() + gpo.parameters.son_heartbeat_frequency(), false);
|
||||
BOOST_TEST_MESSAGE("Checking Network Status");
|
||||
for(sidechain_type sidechain:active_sidechain_types)
|
||||
for(sidechain_type sidechain : all_sidechain_types)
|
||||
{
|
||||
auto network_status_obj = con.wallet_api_ptr->get_son_network_status_by_sidechain(sidechain);
|
||||
for(map<son_id_type, string>::iterator iter=network_status_obj.begin(); iter!=network_status_obj.end(); ++iter)
|
||||
|
|
@ -1535,7 +1544,7 @@ BOOST_FIXTURE_TEST_CASE( get_son_network_status_by_sidechain, cli_fixture )
|
|||
|
||||
generate_blocks(db->head_block_time() + gpo.parameters.son_heartbeat_frequency() + gpo.parameters.son_down_time(), false);;
|
||||
BOOST_TEST_MESSAGE("Checking Network Status");
|
||||
for(sidechain_type sidechain:active_sidechain_types)
|
||||
for(sidechain_type sidechain : all_sidechain_types)
|
||||
{
|
||||
auto network_status_obj = con.wallet_api_ptr->get_son_network_status_by_sidechain(sidechain);
|
||||
for(map<son_id_type, string>::iterator iter=network_status_obj.begin(); iter!=network_status_obj.end(); ++iter)
|
||||
|
|
|
|||
|
|
@ -1038,7 +1038,7 @@ BOOST_FIXTURE_TEST_CASE( hardfork_son2_time, database_fixture )
|
|||
generate_block(); // get the maintenance skip slots out of the way*/
|
||||
BOOST_CHECK_EQUAL(db.get_global_properties().parameters.maximum_son_count(), 7);
|
||||
|
||||
generate_blocks(HARDFORK_SON3_TIME);
|
||||
generate_blocks(HARDFORK_SON_FOR_ETHEREUM_TIME);
|
||||
// after this hardfork maximum son account should not reset the value
|
||||
// on 7 after maintenance interval anymore. It must be HARDFORK_SON2_TIME
|
||||
BOOST_CHECK_EQUAL(db.get_global_properties().parameters.maximum_son_count(), GRAPHENE_DEFAULT_MAX_SONS);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ using namespace graphene::chain::test;
|
|||
BOOST_FIXTURE_TEST_SUITE( son_operation_tests, database_fixture )
|
||||
|
||||
BOOST_AUTO_TEST_CASE( create_son_test ) {
|
||||
generate_blocks(HARDFORK_SON_TIME);
|
||||
generate_blocks(HARDFORK_SON_FOR_ETHEREUM_TIME);
|
||||
generate_block();
|
||||
set_expiration(db, trx);
|
||||
|
||||
|
|
@ -314,7 +314,7 @@ BOOST_AUTO_TEST_CASE( son_pay_test )
|
|||
const dynamic_global_property_object& dpo = db.get_dynamic_global_properties();
|
||||
const auto block_interval = db.get_global_properties().parameters.block_interval;
|
||||
BOOST_CHECK( dpo.son_budget.value == 0);
|
||||
generate_blocks(HARDFORK_SON_TIME);
|
||||
generate_blocks(HARDFORK_SON_FOR_ETHEREUM_TIME);
|
||||
while (db.head_block_time() <= HARDFORK_SON_TIME) {
|
||||
generate_block();
|
||||
}
|
||||
|
|
@ -634,16 +634,18 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) {
|
|||
// Modify SON's status to active
|
||||
db.modify( *obj, [&]( son_object& _s)
|
||||
{
|
||||
_s.statuses[sidechain_type::bitcoin] = son_status::active;
|
||||
_s.statuses[sidechain_type::hive] = son_status::active;
|
||||
_s.statuses[sidechain_type::ethereum] = son_status::active;
|
||||
for (const auto& active_sidechain_type : active_sidechain_types(db.head_block_time()))
|
||||
{
|
||||
_s.statuses[active_sidechain_type] = son_status::active;
|
||||
}
|
||||
});
|
||||
|
||||
db.modify( *son_stats_obj, [&]( son_statistics_object& _s)
|
||||
{
|
||||
_s.last_down_timestamp[sidechain_type::bitcoin] = fc::time_point_sec(db.head_block_time());
|
||||
_s.last_down_timestamp[sidechain_type::hive] = fc::time_point_sec(db.head_block_time());
|
||||
_s.last_down_timestamp[sidechain_type::ethereum] = fc::time_point_sec(db.head_block_time());
|
||||
for (const auto& active_sidechain_type : active_sidechain_types(db.head_block_time()))
|
||||
{
|
||||
_s.last_down_timestamp[active_sidechain_type] = fc::time_point_sec(db.head_block_time());
|
||||
}
|
||||
});
|
||||
|
||||
{
|
||||
|
|
@ -660,9 +662,10 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) {
|
|||
PUSH_TX( db, trx, ~0);
|
||||
generate_block();
|
||||
trx.clear();
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::bitcoin) == son_status::request_maintenance);
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::hive) == son_status::request_maintenance);
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::ethereum) == son_status::request_maintenance);
|
||||
for (const auto& active_sidechain_type : active_sidechain_types(db.head_block_time()))
|
||||
{
|
||||
BOOST_CHECK( obj->statuses.at(active_sidechain_type) == son_status::request_maintenance);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
|
@ -679,23 +682,26 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) {
|
|||
PUSH_TX( db, trx, ~0);
|
||||
generate_block();
|
||||
trx.clear();
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::bitcoin) == son_status::active);
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::hive) == son_status::active);
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::ethereum) == son_status::active);
|
||||
for (const auto& active_sidechain_type : active_sidechain_types(db.head_block_time()))
|
||||
{
|
||||
BOOST_CHECK( obj->statuses.at(active_sidechain_type) == son_status::active);
|
||||
}
|
||||
}
|
||||
|
||||
// Modify SON's status to in_maintenance
|
||||
db.modify( *obj, [&]( son_object& _s)
|
||||
{
|
||||
_s.statuses[sidechain_type::bitcoin] = son_status::in_maintenance;
|
||||
_s.statuses[sidechain_type::hive] = son_status::in_maintenance;
|
||||
_s.statuses[sidechain_type::ethereum] = son_status::in_maintenance;
|
||||
for (const auto& active_sidechain_type : active_sidechain_types(db.head_block_time()))
|
||||
{
|
||||
_s.statuses[active_sidechain_type] = son_status::in_maintenance;
|
||||
}
|
||||
});
|
||||
|
||||
flat_map<sidechain_type, uint64_t> downtime;
|
||||
downtime[sidechain_type::bitcoin] = 0;
|
||||
downtime[sidechain_type::hive] = 0;
|
||||
downtime[sidechain_type::ethereum] = 0;
|
||||
for (const auto& active_sidechain_type : active_sidechain_types(db.head_block_time()))
|
||||
{
|
||||
downtime[active_sidechain_type] = 0;
|
||||
}
|
||||
|
||||
{
|
||||
generate_block();
|
||||
|
|
@ -711,36 +717,34 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) {
|
|||
PUSH_TX( db, trx, ~0);
|
||||
generate_block();
|
||||
trx.clear();
|
||||
BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(sidechain_type::bitcoin), op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.at(sidechain_type::bitcoin).sec_since_epoch());
|
||||
BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(sidechain_type::hive), op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.at(sidechain_type::hive).sec_since_epoch());
|
||||
BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(sidechain_type::ethereum), op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.at(sidechain_type::ethereum).sec_since_epoch());
|
||||
downtime[sidechain_type::bitcoin] += op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.at(sidechain_type::bitcoin).sec_since_epoch();
|
||||
downtime[sidechain_type::hive] += op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.at(sidechain_type::hive).sec_since_epoch();
|
||||
downtime[sidechain_type::ethereum] += op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.at(sidechain_type::ethereum).sec_since_epoch();
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::bitcoin) == son_status::inactive);
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::hive) == son_status::inactive);
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::ethereum) == son_status::inactive);
|
||||
BOOST_CHECK( son_stats_obj->last_active_timestamp.at(sidechain_type::bitcoin) == op.ts);
|
||||
BOOST_CHECK( son_stats_obj->last_active_timestamp.at(sidechain_type::hive) == op.ts);
|
||||
BOOST_CHECK( son_stats_obj->last_active_timestamp.at(sidechain_type::ethereum) == op.ts);
|
||||
|
||||
for (const auto& active_sidechain_type : active_sidechain_types(db.head_block_time()))
|
||||
{
|
||||
BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(active_sidechain_type), op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.at(active_sidechain_type).sec_since_epoch());
|
||||
downtime[active_sidechain_type] += op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.at(active_sidechain_type).sec_since_epoch();
|
||||
BOOST_CHECK( obj->statuses.at(active_sidechain_type) == son_status::inactive);
|
||||
BOOST_CHECK( son_stats_obj->last_active_timestamp.at(active_sidechain_type) == op.ts);
|
||||
}
|
||||
}
|
||||
|
||||
// Modify SON's status to in_maintenance
|
||||
db.modify( *obj, [&]( son_object& _s)
|
||||
{
|
||||
_s.statuses[sidechain_type::bitcoin] = son_status::in_maintenance;
|
||||
_s.statuses[sidechain_type::hive] = son_status::in_maintenance;
|
||||
_s.statuses[sidechain_type::ethereum] = son_status::in_maintenance;
|
||||
for (const auto& active_sidechain_type : active_sidechain_types(db.head_block_time()))
|
||||
{
|
||||
_s.statuses[active_sidechain_type] = son_status::in_maintenance;
|
||||
}
|
||||
});
|
||||
|
||||
// SON is selected as one of the active SONs
|
||||
db.modify( db.get_global_properties(), [&]( global_property_object& _gpo )
|
||||
{
|
||||
son_info son_inf;
|
||||
son_sidechain_info son_inf;
|
||||
son_inf.son_id = son_id_type(0);
|
||||
_gpo.active_sons[sidechain_type::bitcoin].push_back(son_inf);
|
||||
_gpo.active_sons[sidechain_type::hive].push_back(son_inf);
|
||||
_gpo.active_sons[sidechain_type::ethereum].push_back(son_inf);
|
||||
for (const auto& active_sidechain_type : active_sidechain_types(db.head_block_time()))
|
||||
{
|
||||
_gpo.active_sons[active_sidechain_type].push_back(son_inf);
|
||||
}
|
||||
});
|
||||
|
||||
{
|
||||
|
|
@ -758,18 +762,13 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) {
|
|||
generate_block();
|
||||
trx.clear();
|
||||
|
||||
BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(sidechain_type::bitcoin), downtime.at(sidechain_type::bitcoin) + op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.at(sidechain_type::bitcoin).sec_since_epoch());
|
||||
BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(sidechain_type::hive), downtime.at(sidechain_type::hive) + op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.at(sidechain_type::hive).sec_since_epoch());
|
||||
BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(sidechain_type::ethereum), downtime.at(sidechain_type::ethereum) + op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.at(sidechain_type::ethereum).sec_since_epoch());
|
||||
downtime[sidechain_type::bitcoin] += op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.at(sidechain_type::bitcoin).sec_since_epoch();
|
||||
downtime[sidechain_type::hive] += op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.at(sidechain_type::hive).sec_since_epoch();
|
||||
downtime[sidechain_type::ethereum] += op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.at(sidechain_type::ethereum).sec_since_epoch();
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::bitcoin) == son_status::active);
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::hive) == son_status::active);
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::ethereum) == son_status::active);
|
||||
BOOST_CHECK( son_stats_obj->last_active_timestamp.at(sidechain_type::bitcoin) == op.ts);
|
||||
BOOST_CHECK( son_stats_obj->last_active_timestamp.at(sidechain_type::hive) == op.ts);
|
||||
BOOST_CHECK( son_stats_obj->last_active_timestamp.at(sidechain_type::ethereum) == op.ts);
|
||||
for (const auto& active_sidechain_type : active_sidechain_types(db.head_block_time()))
|
||||
{
|
||||
BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(active_sidechain_type), downtime.at(active_sidechain_type) + op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.at(active_sidechain_type).sec_since_epoch());
|
||||
downtime[active_sidechain_type] += op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.at(active_sidechain_type).sec_since_epoch();
|
||||
BOOST_CHECK( obj->statuses.at(active_sidechain_type) == son_status::active);
|
||||
BOOST_CHECK( son_stats_obj->last_active_timestamp.at(active_sidechain_type) == op.ts);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
|
@ -786,15 +785,13 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) {
|
|||
PUSH_TX( db, trx, ~0);
|
||||
generate_block();
|
||||
trx.clear();
|
||||
BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(sidechain_type::bitcoin), downtime.at(sidechain_type::bitcoin));
|
||||
BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(sidechain_type::hive), downtime.at(sidechain_type::hive));
|
||||
BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(sidechain_type::ethereum), downtime.at(sidechain_type::ethereum));
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::bitcoin) == son_status::active);
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::hive) == son_status::active);
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::ethereum) == son_status::active);
|
||||
BOOST_CHECK( son_stats_obj->last_active_timestamp.at(sidechain_type::bitcoin) == op.ts);
|
||||
BOOST_CHECK( son_stats_obj->last_active_timestamp.at(sidechain_type::hive) == op.ts);
|
||||
BOOST_CHECK( son_stats_obj->last_active_timestamp.at(sidechain_type::ethereum) == op.ts);
|
||||
|
||||
for (const auto& active_sidechain_type : active_sidechain_types(db.head_block_time()))
|
||||
{
|
||||
BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(active_sidechain_type), downtime.at(active_sidechain_type));
|
||||
BOOST_CHECK( obj->statuses.at(active_sidechain_type) == son_status::active);
|
||||
BOOST_CHECK( son_stats_obj->last_active_timestamp.at(active_sidechain_type) == op.ts);
|
||||
}
|
||||
}
|
||||
} FC_LOG_AND_RETHROW()
|
||||
}
|
||||
|
|
@ -819,9 +816,10 @@ BOOST_AUTO_TEST_CASE( son_report_down_test ) {
|
|||
auto son_stats_obj = sidx.find( obj->statistics );
|
||||
BOOST_REQUIRE( son_stats_obj != sidx.end() );
|
||||
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::bitcoin) == son_status::active);
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::hive) == son_status::active);
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::ethereum) == son_status::active);
|
||||
for (const auto& active_sidechain_type : active_sidechain_types(db.head_block_time()))
|
||||
{
|
||||
BOOST_CHECK( obj->statuses.at(active_sidechain_type) == son_status::active);
|
||||
}
|
||||
|
||||
{
|
||||
// Check that transaction fails if down_ts < last_active_timestamp
|
||||
|
|
@ -873,12 +871,11 @@ BOOST_AUTO_TEST_CASE( son_report_down_test ) {
|
|||
generate_block();
|
||||
trx.clear();
|
||||
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::bitcoin) == son_status::in_maintenance);
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::hive) == son_status::in_maintenance);
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::ethereum) == son_status::in_maintenance);
|
||||
BOOST_CHECK( son_stats_obj->last_down_timestamp.at(sidechain_type::bitcoin) == op.down_ts);
|
||||
BOOST_CHECK( son_stats_obj->last_down_timestamp.at(sidechain_type::hive) == op.down_ts);
|
||||
BOOST_CHECK( son_stats_obj->last_down_timestamp.at(sidechain_type::ethereum) == op.down_ts);
|
||||
for (const auto& active_sidechain_type : active_sidechain_types(db.head_block_time()))
|
||||
{
|
||||
BOOST_CHECK( obj->statuses.at(active_sidechain_type) == son_status::in_maintenance);
|
||||
BOOST_CHECK( son_stats_obj->last_down_timestamp.at(active_sidechain_type) == op.down_ts);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
|||
|
|
@ -160,8 +160,8 @@ BOOST_AUTO_TEST_CASE( son_wallet_recreate_test ) {
|
|||
si.son_id = son_id_type(0);
|
||||
si.weight = 1000;
|
||||
si.signing_key = alice_public_key;
|
||||
si.public_key = "";
|
||||
op.sons[sidechain_type::bitcoin].push_back(si);
|
||||
si.sidechain_public_keys[sidechain_type::bitcoin] = "";
|
||||
op.sons.push_back(si);
|
||||
}
|
||||
|
||||
{
|
||||
|
|
@ -169,8 +169,8 @@ BOOST_AUTO_TEST_CASE( son_wallet_recreate_test ) {
|
|||
si.son_id = son_id_type(1);
|
||||
si.weight = 1000;
|
||||
si.signing_key = bob_public_key;
|
||||
si.public_key = "";
|
||||
op.sons[sidechain_type::bitcoin].push_back(si);
|
||||
si.sidechain_public_keys[sidechain_type::bitcoin] = "";
|
||||
op.sons.push_back(si);
|
||||
}
|
||||
|
||||
trx.operations.push_back(op);
|
||||
|
|
|
|||
Loading…
Reference in a new issue