SON for Hive voting, new vote_id_type

This commit is contained in:
serkixenos 2022-03-08 22:53:53 -04:00
parent 21e13ac4d4
commit c495902795
11 changed files with 652 additions and 432 deletions

View file

@ -2057,61 +2057,61 @@ voters_info database_api::get_voters(const string &account_name_or_id) const {
vector<variant> database_api_impl::lookup_vote_ids(const vector<vote_id_type> &votes) const {
FC_ASSERT(votes.size() < 1000, "Only 1000 votes can be queried at a time");
const auto &witness_idx = _db.get_index_type<witness_index>().indices().get<by_vote_id>();
const auto &committee_idx = _db.get_index_type<committee_member_index>().indices().get<by_vote_id>();
const auto &for_worker_idx = _db.get_index_type<worker_index>().indices().get<by_vote_for>();
const auto &against_worker_idx = _db.get_index_type<worker_index>().indices().get<by_vote_against>();
const auto &son_idx = _db.get_index_type<son_index>().indices().get<by_vote_id>();
//const auto &witness_idx = _db.get_index_type<witness_index>().indices().get<by_vote_id>();
//const auto &committee_idx = _db.get_index_type<committee_member_index>().indices().get<by_vote_id>();
//const auto &for_worker_idx = _db.get_index_type<worker_index>().indices().get<by_vote_for>();
//const auto &against_worker_idx = _db.get_index_type<worker_index>().indices().get<by_vote_against>();
//const auto &son_idx = _db.get_index_type<son_index>().indices().get<by_vote_id>();
vector<variant> result;
result.reserve(votes.size());
for (auto id : votes) {
switch (id.type()) {
case vote_id_type::committee: {
auto itr = committee_idx.find(id);
if (itr != committee_idx.end())
result.emplace_back(variant(*itr, 1));
else
result.emplace_back(variant());
break;
}
case vote_id_type::witness: {
auto itr = witness_idx.find(id);
if (itr != witness_idx.end())
result.emplace_back(variant(*itr, 1));
else
result.emplace_back(variant());
break;
}
case vote_id_type::worker: {
auto itr = for_worker_idx.find(id);
if (itr != for_worker_idx.end()) {
result.emplace_back(variant(*itr, 1));
} else {
auto itr = against_worker_idx.find(id);
if (itr != against_worker_idx.end()) {
result.emplace_back(variant(*itr, 1));
} else {
result.emplace_back(variant());
}
}
break;
}
case vote_id_type::son: {
auto itr = son_idx.find(id);
if (itr != son_idx.end())
result.emplace_back(variant(*itr, 5));
else
result.emplace_back(variant());
break;
}
case vote_id_type::VOTE_TYPE_COUNT:
break; // supress unused enum value warnings
default:
FC_CAPTURE_AND_THROW(fc::out_of_range_exception, (id));
}
}
//result.reserve(votes.size());
//for (auto id : votes) {
// switch (id.type()) {
// case vote_id_type::committee: {
// auto itr = committee_idx.find(id);
// if (itr != committee_idx.end())
// result.emplace_back(variant(*itr, 1));
// else
// result.emplace_back(variant());
// break;
// }
// case vote_id_type::witness: {
// auto itr = witness_idx.find(id);
// if (itr != witness_idx.end())
// result.emplace_back(variant(*itr, 1));
// else
// result.emplace_back(variant());
// break;
// }
// case vote_id_type::worker: {
// auto itr = for_worker_idx.find(id);
// if (itr != for_worker_idx.end()) {
// result.emplace_back(variant(*itr, 1));
// } else {
// auto itr = against_worker_idx.find(id);
// if (itr != against_worker_idx.end()) {
// result.emplace_back(variant(*itr, 1));
// } else {
// result.emplace_back(variant());
// }
// }
// break;
// }
// case vote_id_type::son: {
// auto itr = son_idx.find(id);
// if (itr != son_idx.end())
// result.emplace_back(variant(*itr, 5));
// else
// result.emplace_back(variant());
// break;
// }
//
// case vote_id_type::VOTE_TYPE_COUNT:
// break; // supress unused enum value warnings
// default:
// FC_CAPTURE_AND_THROW(fc::out_of_range_exception, (id));
// }
//}
return result;
}
@ -2130,63 +2130,63 @@ vector<vote_id_type> database_api_impl::get_votes_ids(const string &account_name
votes_info database_api_impl::get_votes(const string &account_name_or_id) const {
votes_info result;
const auto &votes_ids = get_votes_ids(account_name_or_id);
const auto &committee_ids = get_votes_objects<committee_member_index, by_vote_id>(votes_ids);
const auto &witness_ids = get_votes_objects<witness_index, by_vote_id>(votes_ids);
const auto &for_worker_ids = get_votes_objects<worker_index, by_vote_for>(votes_ids);
const auto &against_worker_ids = get_votes_objects<worker_index, by_vote_against>(votes_ids);
const auto &son_ids = get_votes_objects<son_index, by_vote_id>(votes_ids, 5);
//const auto &votes_ids = get_votes_ids(account_name_or_id);
//const auto &committee_ids = get_votes_objects<committee_member_index, by_vote_id>(votes_ids);
//const auto &witness_ids = get_votes_objects<witness_index, by_vote_id>(votes_ids);
//const auto &for_worker_ids = get_votes_objects<worker_index, by_vote_for>(votes_ids);
//const auto &against_worker_ids = get_votes_objects<worker_index, by_vote_against>(votes_ids);
//const auto &son_ids = get_votes_objects<son_index, by_vote_id>(votes_ids, 5);
//! Fill votes info
if (!committee_ids.empty()) {
vector<votes_info_object> votes_for_committee_members;
votes_for_committee_members.reserve(committee_ids.size());
for (const auto &committee : committee_ids) {
const auto &committee_obj = committee.as<committee_member_object>(2);
votes_for_committee_members.emplace_back(votes_info_object{committee_obj.vote_id, committee_obj.id});
}
result.votes_for_committee_members = std::move(votes_for_committee_members);
}
if (!witness_ids.empty()) {
vector<votes_info_object> votes_for_witnesses;
votes_for_witnesses.reserve(witness_ids.size());
for (const auto &witness : witness_ids) {
const auto &witness_obj = witness.as<witness_object>(2);
votes_for_witnesses.emplace_back(votes_info_object{witness_obj.vote_id, witness_obj.id});
}
result.votes_for_witnesses = std::move(votes_for_witnesses);
}
if (!for_worker_ids.empty()) {
vector<votes_info_object> votes_for_workers;
votes_for_workers.reserve(for_worker_ids.size());
for (const auto &for_worker : for_worker_ids) {
const auto &for_worker_obj = for_worker.as<worker_object>(2);
votes_for_workers.emplace_back(votes_info_object{for_worker_obj.vote_for, for_worker_obj.id});
}
result.votes_for_workers = std::move(votes_for_workers);
}
if (!against_worker_ids.empty()) {
vector<votes_info_object> votes_against_workers;
votes_against_workers.reserve(against_worker_ids.size());
for (const auto &against_worker : against_worker_ids) {
const auto &against_worker_obj = against_worker.as<worker_object>(2);
votes_against_workers.emplace_back(votes_info_object{against_worker_obj.vote_against, against_worker_obj.id});
}
result.votes_against_workers = std::move(votes_against_workers);
}
if (!son_ids.empty()) {
vector<votes_info_object> votes_for_sons;
votes_for_sons.reserve(son_ids.size());
for (const auto &son : son_ids) {
const auto &son_obj = son.as<son_object>(6);
votes_for_sons.emplace_back(votes_info_object{son_obj.vote_id, son_obj.id});
}
result.votes_for_sons = std::move(votes_for_sons);
}
////! Fill votes info
//if (!committee_ids.empty()) {
// vector<votes_info_object> votes_for_committee_members;
// votes_for_committee_members.reserve(committee_ids.size());
// for (const auto &committee : committee_ids) {
// const auto &committee_obj = committee.as<committee_member_object>(2);
// votes_for_committee_members.emplace_back(votes_info_object{committee_obj.vote_id, committee_obj.id});
// }
// result.votes_for_committee_members = std::move(votes_for_committee_members);
//}
//
//if (!witness_ids.empty()) {
// vector<votes_info_object> votes_for_witnesses;
// votes_for_witnesses.reserve(witness_ids.size());
// for (const auto &witness : witness_ids) {
// const auto &witness_obj = witness.as<witness_object>(2);
// votes_for_witnesses.emplace_back(votes_info_object{witness_obj.vote_id, witness_obj.id});
// }
// result.votes_for_witnesses = std::move(votes_for_witnesses);
//}
//
//if (!for_worker_ids.empty()) {
// vector<votes_info_object> votes_for_workers;
// votes_for_workers.reserve(for_worker_ids.size());
// for (const auto &for_worker : for_worker_ids) {
// const auto &for_worker_obj = for_worker.as<worker_object>(2);
// votes_for_workers.emplace_back(votes_info_object{for_worker_obj.vote_for, for_worker_obj.id});
// }
// result.votes_for_workers = std::move(votes_for_workers);
//}
//
//if (!against_worker_ids.empty()) {
// vector<votes_info_object> votes_against_workers;
// votes_against_workers.reserve(against_worker_ids.size());
// for (const auto &against_worker : against_worker_ids) {
// const auto &against_worker_obj = against_worker.as<worker_object>(2);
// votes_against_workers.emplace_back(votes_info_object{against_worker_obj.vote_against, against_worker_obj.id});
// }
// result.votes_against_workers = std::move(votes_against_workers);
//}
//
//if (!son_ids.empty()) {
// vector<votes_info_object> votes_for_sons;
// votes_for_sons.reserve(son_ids.size());
// for (const auto &son : son_ids) {
// const auto &son_obj = son.as<son_object>(6);
// votes_for_sons.emplace_back(votes_info_object{son_obj.vote_id, son_obj.id});
// }
// result.votes_for_sons = std::move(votes_for_sons);
//}
return result;
}
@ -2207,165 +2207,165 @@ vector<account_object> database_api_impl::get_voters_by_id(const vote_id_type &v
voters_info database_api_impl::get_voters(const string &account_name_or_id) const {
voters_info result;
//! Find account name
bool owner_account_found = false;
std::string owner_account_id;
//! Check if we have account by name
const auto &account_object = get_account_by_name(account_name_or_id);
if (account_object) {
//! It is account
owner_account_id = object_id_to_string(account_object->get_id());
owner_account_found = true;
} else {
//! Check if we have account id
const auto &account_id = maybe_id<account_id_type>(account_name_or_id);
if (account_id) {
//! It may be account id
const auto &account_objects = get_accounts({account_name_or_id});
if (!account_objects.empty()) {
const auto &account_object = account_objects.front();
if (account_object) {
//! It is account object
owner_account_id = object_id_to_string(account_object->get_id());
owner_account_found = true;
}
}
} else {
//! Check if we have committee member id
const auto &committee_member_id = maybe_id<committee_member_id_type>(account_name_or_id);
if (committee_member_id) {
//! It may be committee member id
const auto &committee_member_objects = get_committee_members({*committee_member_id});
if (!committee_member_objects.empty()) {
const auto &committee_member_object = committee_member_objects.front();
if (committee_member_object) {
//! It is committee member object
owner_account_id = object_id_to_string(committee_member_object->committee_member_account);
owner_account_found = true;
}
}
} else {
//! Check if we have witness id
const auto &witness_id = maybe_id<witness_id_type>(account_name_or_id);
if (witness_id) {
//! It may be witness id
const auto &witness_objects = get_witnesses({*witness_id});
if (!witness_objects.empty()) {
const auto &witness_object = witness_objects.front();
if (witness_object) {
//! It is witness object
owner_account_id = object_id_to_string(witness_object->witness_account);
owner_account_found = true;
}
}
} else {
//! Check if we have worker id
const auto &worker_id = maybe_id<worker_id_type>(account_name_or_id);
if (worker_id) {
//! It may be worker id
const auto &worker_objects = get_workers({*worker_id});
if (!worker_objects.empty()) {
const auto &worker_object = worker_objects.front();
if (worker_object) {
//! It is worker object
owner_account_id = object_id_to_string(worker_object->worker_account);
owner_account_found = true;
}
}
} else {
//! Check if we have son id
const auto &son_id = maybe_id<son_id_type>(account_name_or_id);
if (son_id) {
//! It may be son id
const auto &son_objects = get_sons({*son_id});
if (!son_objects.empty()) {
const auto &son_object = son_objects.front();
if (son_object) {
//! It is son object
owner_account_id = object_id_to_string(son_object->son_account);
owner_account_found = true;
}
}
}
}
}
}
}
}
//! We didn't find who it was
if (!owner_account_found)
FC_THROW_EXCEPTION(database_query_exception, "Wrong account_name_or_id: ${account_name_or_id}", ("account_name_or_id", account_name_or_id));
//! Fill voters_info
const auto &committee_member_object = get_committee_member_by_account(owner_account_id);
const auto &witness_object = get_witness_by_account(owner_account_id);
const auto &worker_objects = get_workers_by_account(owner_account_id);
const auto &son_object = get_son_by_account(owner_account_id);
//! Info for committee member voters
if (committee_member_object) {
const auto &committee_member_voters = get_voters_by_id(committee_member_object->vote_id);
voters_info_object voters_for_committee_member;
voters_for_committee_member.vote_id = committee_member_object->vote_id;
voters_for_committee_member.voters.reserve(committee_member_voters.size());
for (const auto &voter : committee_member_voters) {
voters_for_committee_member.voters.emplace_back(voter.get_id());
}
result.voters_for_committee_member = std::move(voters_for_committee_member);
}
//! Info for witness voters
if (witness_object) {
const auto &witness_voters = get_voters_by_id(witness_object->vote_id);
voters_info_object voters_for_witness;
voters_for_witness.vote_id = witness_object->vote_id;
voters_for_witness.voters.reserve(witness_voters.size());
for (const auto &voter : witness_voters) {
voters_for_witness.voters.emplace_back(voter.get_id());
}
result.voters_for_witness = std::move(voters_for_witness);
}
//! Info for worker voters
if (!worker_objects.empty()) {
vector<voters_info_object> voters_for_workers(worker_objects.size());
vector<voters_info_object> voters_against_workers(worker_objects.size());
for (const auto &worker_object : worker_objects) {
voters_info_object voters_for_worker;
const auto &for_worker_voters = get_voters_by_id(worker_object.vote_for);
voters_for_worker.vote_id = worker_object.vote_for;
voters_for_worker.voters.reserve(for_worker_voters.size());
for (const auto &voter : for_worker_voters) {
voters_for_worker.voters.emplace_back(voter.get_id());
}
voters_for_workers.emplace_back(std::move(voters_for_worker));
voters_info_object voters_against_worker;
const auto &against_worker_voters = get_voters_by_id(worker_object.vote_against);
voters_against_worker.vote_id = worker_object.vote_against;
voters_against_worker.voters.reserve(against_worker_voters.size());
for (const auto &voter : against_worker_voters) {
voters_against_worker.voters.emplace_back(voter.get_id());
}
voters_against_workers.emplace_back(std::move(voters_against_worker));
}
result.voters_for_workers = std::move(voters_for_workers);
result.voters_against_workers = std::move(voters_against_workers);
}
//! Info for son voters
if (son_object) {
const auto &son_voters = get_voters_by_id(son_object->vote_id);
voters_info_object voters_for_son;
voters_for_son.vote_id = son_object->vote_id;
voters_for_son.voters.reserve(son_voters.size());
for (const auto &voter : son_voters) {
voters_for_son.voters.emplace_back(voter.get_id());
}
result.voters_for_son = std::move(voters_for_son);
}
////! Find account name
//bool owner_account_found = false;
//std::string owner_account_id;
//
////! Check if we have account by name
//const auto &account_object = get_account_by_name(account_name_or_id);
//if (account_object) {
// //! It is account
// owner_account_id = object_id_to_string(account_object->get_id());
// owner_account_found = true;
//} else {
// //! Check if we have account id
// const auto &account_id = maybe_id<account_id_type>(account_name_or_id);
// if (account_id) {
// //! It may be account id
// const auto &account_objects = get_accounts({account_name_or_id});
// if (!account_objects.empty()) {
// const auto &account_object = account_objects.front();
// if (account_object) {
// //! It is account object
// owner_account_id = object_id_to_string(account_object->get_id());
// owner_account_found = true;
// }
// }
// } else {
// //! Check if we have committee member id
// const auto &committee_member_id = maybe_id<committee_member_id_type>(account_name_or_id);
// if (committee_member_id) {
// //! It may be committee member id
// const auto &committee_member_objects = get_committee_members({*committee_member_id});
// if (!committee_member_objects.empty()) {
// const auto &committee_member_object = committee_member_objects.front();
// if (committee_member_object) {
// //! It is committee member object
// owner_account_id = object_id_to_string(committee_member_object->committee_member_account);
// owner_account_found = true;
// }
// }
// } else {
// //! Check if we have witness id
// const auto &witness_id = maybe_id<witness_id_type>(account_name_or_id);
// if (witness_id) {
// //! It may be witness id
// const auto &witness_objects = get_witnesses({*witness_id});
// if (!witness_objects.empty()) {
// const auto &witness_object = witness_objects.front();
// if (witness_object) {
// //! It is witness object
// owner_account_id = object_id_to_string(witness_object->witness_account);
// owner_account_found = true;
// }
// }
// } else {
// //! Check if we have worker id
// const auto &worker_id = maybe_id<worker_id_type>(account_name_or_id);
// if (worker_id) {
// //! It may be worker id
// const auto &worker_objects = get_workers({*worker_id});
// if (!worker_objects.empty()) {
// const auto &worker_object = worker_objects.front();
// if (worker_object) {
// //! It is worker object
// owner_account_id = object_id_to_string(worker_object->worker_account);
// owner_account_found = true;
// }
// }
// } else {
// //! Check if we have son id
// const auto &son_id = maybe_id<son_id_type>(account_name_or_id);
// if (son_id) {
// //! It may be son id
// const auto &son_objects = get_sons({*son_id});
// if (!son_objects.empty()) {
// const auto &son_object = son_objects.front();
// if (son_object) {
// //! It is son object
// owner_account_id = object_id_to_string(son_object->son_account);
// owner_account_found = true;
// }
// }
// }
// }
// }
// }
// }
//}
//
////! We didn't find who it was
//if (!owner_account_found)
// FC_THROW_EXCEPTION(database_query_exception, "Wrong account_name_or_id: ${account_name_or_id}", ("account_name_or_id", account_name_or_id));
//
////! Fill voters_info
//const auto &committee_member_object = get_committee_member_by_account(owner_account_id);
//const auto &witness_object = get_witness_by_account(owner_account_id);
//const auto &worker_objects = get_workers_by_account(owner_account_id);
//const auto &son_object = get_son_by_account(owner_account_id);
//
////! Info for committee member voters
//if (committee_member_object) {
// const auto &committee_member_voters = get_voters_by_id(committee_member_object->vote_id);
// voters_info_object voters_for_committee_member;
// voters_for_committee_member.vote_id = committee_member_object->vote_id;
// voters_for_committee_member.voters.reserve(committee_member_voters.size());
// for (const auto &voter : committee_member_voters) {
// voters_for_committee_member.voters.emplace_back(voter.get_id());
// }
// result.voters_for_committee_member = std::move(voters_for_committee_member);
//}
//
////! Info for witness voters
//if (witness_object) {
// const auto &witness_voters = get_voters_by_id(witness_object->vote_id);
// voters_info_object voters_for_witness;
// voters_for_witness.vote_id = witness_object->vote_id;
// voters_for_witness.voters.reserve(witness_voters.size());
// for (const auto &voter : witness_voters) {
// voters_for_witness.voters.emplace_back(voter.get_id());
// }
// result.voters_for_witness = std::move(voters_for_witness);
//}
//
////! Info for worker voters
//if (!worker_objects.empty()) {
// vector<voters_info_object> voters_for_workers(worker_objects.size());
// vector<voters_info_object> voters_against_workers(worker_objects.size());
// for (const auto &worker_object : worker_objects) {
// voters_info_object voters_for_worker;
// const auto &for_worker_voters = get_voters_by_id(worker_object.vote_for);
// voters_for_worker.vote_id = worker_object.vote_for;
// voters_for_worker.voters.reserve(for_worker_voters.size());
// for (const auto &voter : for_worker_voters) {
// voters_for_worker.voters.emplace_back(voter.get_id());
// }
// voters_for_workers.emplace_back(std::move(voters_for_worker));
//
// voters_info_object voters_against_worker;
// const auto &against_worker_voters = get_voters_by_id(worker_object.vote_against);
// voters_against_worker.vote_id = worker_object.vote_against;
// voters_against_worker.voters.reserve(against_worker_voters.size());
// for (const auto &voter : against_worker_voters) {
// voters_against_worker.voters.emplace_back(voter.get_id());
// }
// voters_against_workers.emplace_back(std::move(voters_against_worker));
// }
// result.voters_for_workers = std::move(voters_for_workers);
// result.voters_against_workers = std::move(voters_against_workers);
//}
//
////! Info for son voters
//if (son_object) {
// const auto &son_voters = get_voters_by_id(son_object->vote_id);
// voters_info_object voters_for_son;
// voters_for_son.vote_id = son_object->vote_id;
// voters_for_son.voters.reserve(son_voters.size());
// for (const auto &voter : son_voters) {
// voters_for_son.voters.emplace_back(voter.get_id());
// }
// result.voters_for_son = std::move(voters_for_son);
//}
return result;
}

View file

@ -78,7 +78,7 @@ vector<std::reference_wrapper<const typename Index::object_type>> database::sort
}
template<>
vector<std::reference_wrapper<const son_object>> database::sort_votable_objects<son_index>(size_t count) const
vector<std::reference_wrapper<const son_object>> database::sort_votable_objects<son_index>(sidechain_type sidechain, size_t count) const
{
const auto& all_sons = get_index_type<son_index>().indices().get< by_id >();
std::vector<std::reference_wrapper<const son_object>> refs;
@ -91,13 +91,35 @@ vector<std::reference_wrapper<const son_object>> database::sort_votable_objects<
}
count = std::min(count, refs.size());
std::partial_sort(refs.begin(), refs.begin() + count, refs.end(),
[this](const son_object& a, const son_object& b)->bool {
share_type oa_vote = _vote_tally_buffer[a.vote_id];
share_type ob_vote = _vote_tally_buffer[b.vote_id];
[this, sidechain](const son_object& a, const son_object& b)->bool {
share_type oa_vote = 0;
share_type ob_vote = 0;
switch (sidechain) {
case sidechain_type::bitcoin:
oa_vote = _vote_tally_buffer[a.vote_id_bitcoin];
ob_vote = _vote_tally_buffer[b.vote_id_bitcoin];
break;
case sidechain_type::hive:
oa_vote = _vote_tally_buffer[a.vote_id_hive];
ob_vote = _vote_tally_buffer[b.vote_id_hive];
break;
default:
FC_THROW("Unexpected sidechain type");
};
if( oa_vote != ob_vote )
return oa_vote > ob_vote;
return a.vote_id < b.vote_id;
});
switch (sidechain) {
case sidechain_type::bitcoin:
return a.vote_id_bitcoin < b.vote_id_bitcoin;
case sidechain_type::hive:
return a.vote_id_hive < b.vote_id_hive;
default:
FC_THROW("Unexpected sidechain type");
};
return 0;
});
refs.resize(count, refs.front());
return refs;
@ -182,12 +204,13 @@ void database::pay_sons()
const dynamic_global_property_object& dpo = get_dynamic_global_properties();
// 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()))) {
auto sons = sort_votable_objects<son_index>(get_global_properties().parameters.maximum_son_count());
auto sons = sort_votable_objects<son_index>(sidechain_type::bitcoin, get_global_properties().parameters.maximum_son_count());
// After SON2 HF
uint64_t total_votes = 0;
for( const son_object& son : sons )
{
total_votes += _vote_tally_buffer[son.vote_id];
total_votes += _vote_tally_buffer[son.vote_id_bitcoin];
total_votes += _vote_tally_buffer[son.vote_id_hive];
}
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 ) {
@ -206,9 +229,11 @@ void database::pay_sons()
const son_statistics_object& s = static_cast<const son_statistics_object&>(o);
const auto& idx = get_index_type<son_index>().indices().get<by_id>();
auto son_obj = idx.find( s.owner );
auto son_weight = get_weight(_vote_tally_buffer[son_obj->vote_id]);
auto son_weight = get_weight(_vote_tally_buffer[son_obj->vote_id_bitcoin]) +
get_weight(_vote_tally_buffer[son_obj->vote_id_hive]);
if( now < HARDFORK_SON2_TIME ) {
son_weight = get_weight_before_son2_hf(_vote_tally_buffer[son_obj->vote_id]);
son_weight = get_weight_before_son2_hf(_vote_tally_buffer[son_obj->vote_id_bitcoin]) +
get_weight_before_son2_hf(_vote_tally_buffer[son_obj->vote_id_hive]);
}
uint64_t txs_signed = 0;
for (const auto &ts : s.txs_signed) {
@ -228,9 +253,11 @@ void database::pay_sons()
if(txs_signed > 0){
const auto& idx = get_index_type<son_index>().indices().get<by_id>();
auto son_obj = idx.find( s.owner );
auto son_weight = get_weight(_vote_tally_buffer[son_obj->vote_id]);
auto son_weight = get_weight(_vote_tally_buffer[son_obj->vote_id_bitcoin]) +
get_weight(_vote_tally_buffer[son_obj->vote_id_hive]);
if( now < HARDFORK_SON2_TIME ) {
son_weight = get_weight_before_son2_hf(_vote_tally_buffer[son_obj->vote_id]);
son_weight = get_weight_before_son2_hf(_vote_tally_buffer[son_obj->vote_id_bitcoin]) +
get_weight_before_son2_hf(_vote_tally_buffer[son_obj->vote_id_hive]);
}
share_type pay = (txs_signed * son_weight * son_budget.value)/weighted_total_txs_signed;
modify( *son_obj, [&]( son_object& _son_obj)
@ -680,7 +707,7 @@ void database::update_active_sons()
const global_property_object& gpo = get_global_properties();
const chain_parameters& cp = gpo.parameters;
auto sons = sort_votable_objects<son_index>(cp.maximum_son_count());
auto sons = sort_votable_objects<son_index>(sidechain_type::bitcoin, cp.maximum_son_count());
const auto& all_sons = get_index_type<son_index>().indices();
@ -695,7 +722,7 @@ void database::update_active_sons()
});
}
modify( son, [local_vote_buffer_ref]( son_object& obj ){
obj.total_votes = local_vote_buffer_ref[obj.vote_id];
obj.total_votes = local_vote_buffer_ref[obj.vote_id_bitcoin];
if(obj.status == son_status::request_maintenance)
obj.status = son_status::in_maintenance;
});

View file

@ -513,6 +513,9 @@ namespace graphene { namespace chain {
template<class Index>
vector<std::reference_wrapper<const typename Index::object_type>> sort_votable_objects(size_t count)const;
template<class Index>
vector<std::reference_wrapper<const typename Index::object_type>> sort_votable_objects(sidechain_type sidechain, size_t count)const;
//////////////////// db_block.cpp ////////////////////
public:

View file

@ -59,7 +59,8 @@ struct vote_id_type
committee,
witness,
worker,
son,
son_bitcoin,
son_hive,
VOTE_TYPE_COUNT
};
@ -144,7 +145,7 @@ void from_variant( const fc::variant& var, graphene::chain::vote_id_type& vo, ui
FC_REFLECT_TYPENAME( fc::flat_set<graphene::chain::vote_id_type> )
FC_REFLECT_ENUM( graphene::chain::vote_id_type::vote_type, (witness)(committee)(worker)(son)(VOTE_TYPE_COUNT) )
FC_REFLECT_ENUM( graphene::chain::vote_id_type::vote_type, (witness)(committee)(worker)(son_bitcoin)(son_hive)(VOTE_TYPE_COUNT) )
FC_REFLECT( graphene::chain::vote_id_type, (content) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::vote_id_type )

View file

@ -64,7 +64,8 @@ namespace graphene { namespace chain {
static const uint8_t type_id = son_object_type;
account_id_type son_account;
vote_id_type vote_id;
vote_id_type vote_id_bitcoin;
vote_id_type vote_id_hive;
uint64_t total_votes = 0;
string url;
vesting_balance_id_type deposit;
@ -80,7 +81,8 @@ namespace graphene { namespace chain {
};
struct by_account;
struct by_vote_id;
struct by_vote_id_bitcoin;
struct by_vote_id_hive;
using son_multi_index_type = multi_index_container<
son_object,
indexed_by<
@ -90,8 +92,11 @@ 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>,
member<son_object, vote_id_type, &son_object::vote_id>
ordered_unique< tag<by_vote_id_bitcoin>,
member<son_object, vote_id_type, &son_object::vote_id_bitcoin>
>,
ordered_unique< tag<by_vote_id_hive>,
member<son_object, vote_id_type, &son_object::vote_id_hive>
>
>
>;
@ -117,7 +122,8 @@ FC_REFLECT_ENUM(graphene::chain::son_status, (inactive)(active)(request_maintena
FC_REFLECT_DERIVED( graphene::chain::son_object, (graphene::db::object),
(son_account)
(vote_id)
(vote_id_bitcoin)
(vote_id_hive)
(total_votes)
(url)
(deposit)

View file

@ -174,22 +174,27 @@ void account_options::validate() const
{
auto needed_witnesses = num_witness;
auto needed_committee = num_committee;
auto needed_sons = num_son;
auto needed_sons_bitcoin = num_son;
auto needed_sons_hive = 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 && needed_sons )
--needed_sons;
else if ( id.type() == vote_id_type::son_bitcoin && needed_sons_bitcoin )
--needed_sons_bitcoin;
else if ( id.type() == vote_id_type::son_hive && needed_sons_hive )
--needed_sons_hive;
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 == 0,
"May not specify fewer SONs than the number voted for.");
FC_ASSERT( needed_sons_bitcoin == 0,
"May not specify fewer Bitcoin SONs than the number voted for.");
FC_ASSERT( needed_sons_hive == 0,
"May not specify fewer Hive SONs than the number voted for.");
}
void affiliate_reward_distribution::validate() const

View file

@ -38,14 +38,17 @@ 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;
db().modify(db().get_global_properties(), [&vote_id](global_property_object& p) {
vote_id = get_next_vote_id(p, vote_id_type::son);
vote_id_type vote_id_bitcoin;
vote_id_type vote_id_hive;
db().modify(db().get_global_properties(), [&vote_id_bitcoin, &vote_id_hive](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);
});
const auto& new_son_object = db().create<son_object>( [&]( son_object& obj ){
obj.son_account = op.owner_account;
obj.vote_id = vote_id;
obj.vote_id_bitcoin = vote_id_bitcoin;
obj.vote_id_hive = vote_id_hive;
obj.url = op.url;
obj.deposit = op.deposit;
obj.signing_key = op.signing_key;

View file

@ -1,4 +1,4 @@
# Doxyfile 1.8.9.1
# Doxyfile 1.8.17
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
@ -17,11 +17,11 @@
# Project related configuration options
#---------------------------------------------------------------------------
# This tag specifies the encoding used for all characters in the config file
# that follow. The default is UTF-8 which is also the encoding used for all text
# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
# for the list of possible encodings.
# This tag specifies the encoding used for all characters in the configuration
# file that follow. The default is UTF-8 which is also the encoding used for all
# text before the first occurrence of this tag. Doxygen uses libiconv (or the
# iconv built into libc) for the transcoding. See
# https://www.gnu.org/software/libiconv/ for the list of possible encodings.
# The default value is: UTF-8.
DOXYFILE_ENCODING = UTF-8
@ -93,6 +93,14 @@ ALLOW_UNICODE_NAMES = NO
OUTPUT_LANGUAGE = English
# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all generated output in the proper direction.
# Possible values are: None, LTR, RTL and Context.
# The default value is: None.
OUTPUT_TEXT_DIRECTION = None
# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
# descriptions after the members that are listed in the file and class
# documentation (similar to Javadoc). Set to NO to disable this.
@ -179,6 +187,16 @@ SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = NO
# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line
# such as
# /***************
# as being the beginning of a Javadoc-style comment "banner". If set to NO, the
# Javadoc-style will behave just like regular comments and it will not be
# interpreted by doxygen.
# The default value is: NO.
JAVADOC_BANNER = NO
# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
# line (until the first dot) of a Qt-style comment as the brief description. If
# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
@ -226,7 +244,12 @@ TAB_SIZE = 4
# will allow you to put the command \sideeffect (or @sideeffect) in the
# documentation, which will result in a user-defined paragraph with heading
# "Side Effects:". You can put \n's in the value part of an alias to insert
# newlines.
# newlines (in the resulting output). You can put ^^ in the value part of an
# alias to insert a newline as if a physical newline was in the original file.
# When you need a literal { or } or , in the value part of an alias you have to
# escape them by means of a backslash (\), this can lead to conflicts with the
# commands \{ and \} for these it is advised to use the version @{ and @} or use
# a double escape (\\{ and \\})
ALIASES =
@ -264,17 +287,26 @@ OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO
# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice
# sources only. Doxygen will then generate output that is more tailored for that
# language. For instance, namespaces will be presented as modules, types will be
# separated into more groups, etc.
# The default value is: NO.
OPTIMIZE_OUTPUT_SLICE = NO
# Doxygen selects the parser to use depending on the extension of the files it
# parses. With this tag you can assign which parser to use for a given
# extension. Doxygen has a built-in mapping, but you can override or extend it
# using this tag. The format is ext=language, where ext is a file extension, and
# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
# Fortran. In the later case the parser tries to guess whether the code is fixed
# or free formatted code, this is the default for Fortran type files), VHDL. For
# instance to make doxygen treat .inc files as Fortran files (default is PHP),
# and .f files as C (default is Fortran), use: inc=Fortran f=C.
# language is one of the parsers supported by doxygen: IDL, Java, JavaScript,
# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice,
# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser
# tries to guess whether the code is fixed or free formatted code, this is the
# default for Fortran type files), VHDL, tcl. For instance to make doxygen treat
# .inc files as Fortran files (default is PHP), and .f files as C (default is
# Fortran), use: inc=Fortran f=C.
#
# Note: For files without extension you can use no_extension as a placeholder.
#
@ -285,7 +317,7 @@ EXTENSION_MAPPING =
# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
# according to the Markdown format, which allows for more readable
# documentation. See http://daringfireball.net/projects/markdown/ for details.
# documentation. See https://daringfireball.net/projects/markdown/ for details.
# The output of markdown processing is further processed by doxygen, so you can
# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
# case of backward compatibilities issues.
@ -293,6 +325,15 @@ EXTENSION_MAPPING =
MARKDOWN_SUPPORT = YES
# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up
# to that level are automatically included in the table of contents, even if
# they do not have an id attribute.
# Note: This feature currently applies only to Markdown headings.
# Minimum value: 0, maximum value: 99, default value: 5.
# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
TOC_INCLUDE_HEADINGS = 5
# When enabled doxygen tries to link words that correspond to documented
# classes, or namespaces to their corresponding documentation. Such a link can
# be prevented in individual cases by putting a % sign in front of the word or
@ -318,7 +359,7 @@ BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO
# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen
# will parse them like normal C++ but will assume all classes use public instead
# of private inheritance when no explicit protection keyword is present.
# The default value is: NO.
@ -343,6 +384,13 @@ IDL_PROPERTY_SUPPORT = YES
DISTRIBUTE_GROUP_DOC = NO
# If one adds a struct or class to a group and this option is enabled, then also
# any nested class or struct is added to the same group. By default this option
# is disabled and one has to add nested compounds explicitly via \ingroup.
# The default value is: NO.
GROUP_NESTED_COMPOUNDS = NO
# Set the SUBGROUPING tag to YES to allow class member groups of the same type
# (for instance a group of public functions) to be put as a subgroup of that
# type (e.g. under the Public Functions section). Set it to NO to prevent
@ -417,6 +465,12 @@ EXTRACT_ALL = YES
EXTRACT_PRIVATE = NO
# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual
# methods of a class will be included in the documentation.
# The default value is: NO.
EXTRACT_PRIV_VIRTUAL = NO
# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
# scope will be included in the documentation.
# The default value is: NO.
@ -471,8 +525,8 @@ HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
# (class|struct|union) declarations. If set to NO, these declarations will be
# included in the documentation.
# declarations. If set to NO, these declarations will be included in the
# documentation.
# The default value is: NO.
HIDE_FRIEND_COMPOUNDS = NO
@ -495,7 +549,7 @@ INTERNAL_DOCS = NO
# names in lower-case letters. If set to YES, upper-case letters are also
# allowed. This is useful if you have classes or files whose names only differ
# in case and if your file system supports case sensitive file names. Windows
# and Mac users are advised to set this option to NO.
# (including Cygwin) ands Mac users are advised to set this option to NO.
# The default value is: system dependent.
CASE_SENSE_NAMES = NO
@ -682,7 +736,7 @@ LAYOUT_FILE =
# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
# the reference definitions. This must be a list of .bib files. The .bib
# extension is automatically appended if omitted. This requires the bibtex tool
# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info.
# For LaTeX the style of the bibliography can be controlled using
# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
# search path. See also \cite for info how to create references.
@ -727,11 +781,18 @@ WARN_IF_DOC_ERROR = YES
# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
# are documented, but have no documentation for their parameters or return
# value. If set to NO, doxygen will only warn about wrong or incomplete
# parameter documentation, but not about the absence of documentation.
# parameter documentation, but not about the absence of documentation. If
# EXTRACT_ALL is set to YES then this flag will automatically be disabled.
# The default value is: NO.
WARN_NO_PARAMDOC = NO
# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
# a warning is encountered.
# The default value is: NO.
WARN_AS_ERROR = NO
# The WARN_FORMAT tag determines the format of the warning messages that doxygen
# can produce. The string should contain the $file, $line, and $text tags, which
# will be replaced by the file and line number from which the warning originated
@ -755,7 +816,7 @@ WARN_LOGFILE =
# The INPUT tag is used to specify the files and/or directories that contain
# documented source files. You may enter file names like myfile.cpp or
# directories like /usr/src/myproject. Separate the files or directories with
# spaces.
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched.
INPUT = ${CMAKE_CURRENT_SOURCE_DIR}/include/graphene/wallet/wallet.hpp
@ -763,7 +824,7 @@ INPUT = ${CMAKE_CURRENT_SOURCE_DIR}/include/graphene/wallet/wal
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
# documentation (see: http://www.gnu.org/software/libiconv) for the list of
# documentation (see: https://www.gnu.org/software/libiconv/) for the list of
# possible encodings.
# The default value is: UTF-8.
@ -771,12 +832,19 @@ INPUT_ENCODING = UTF-8
# If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
# *.h) to filter out the source-files in the directories. If left blank the
# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii,
# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp,
# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown,
# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
# *.qsf, *.as and *.js.
# *.h) to filter out the source-files in the directories.
#
# Note that for custom extensions or not directly supported extensions you also
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
# read by doxygen.
#
# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment),
# *.doc (to be provided as doxygen C comment), *.txt (to be provided as doxygen
# C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f, *.for, *.tcl, *.vhd,
# *.vhdl, *.ucf, *.qsf and *.ice.
FILE_PATTERNS =
@ -862,6 +930,10 @@ IMAGE_PATH =
# Note that the filter must not add or remove lines; it is applied before the
# code is scanned, but not when the output code is generated. If lines are added
# or removed, the anchors will not be placed correctly.
#
# Note that for custom extensions or not directly supported extensions you also
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
# properly processed by doxygen.
INPUT_FILTER =
@ -871,6 +943,10 @@ INPUT_FILTER =
# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
# patterns match the file name, INPUT_FILTER is applied.
#
# Note that for custom extensions or not directly supported extensions you also
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
# properly processed by doxygen.
FILTER_PATTERNS =
@ -923,7 +999,7 @@ INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
# function all documented functions referencing it will be listed.
# entity all documented functions referencing it will be listed.
# The default value is: NO.
REFERENCED_BY_RELATION = NO
@ -955,12 +1031,12 @@ SOURCE_TOOLTIPS = YES
# If the USE_HTAGS tag is set to YES then the references to source code will
# point to the HTML generated by the htags(1) tool instead of doxygen built-in
# source browser. The htags tool is part of GNU's global source tagging system
# (see http://www.gnu.org/software/global/global.html). You will need version
# (see https://www.gnu.org/software/global/global.html). You will need version
# 4.8.6 or higher.
#
# To use it do the following:
# - Install the latest version of global
# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file
# - Make sure the INPUT points to the root of the source tree
# - Run doxygen as normal
#
@ -982,6 +1058,35 @@ USE_HTAGS = NO
VERBATIM_HEADERS = YES
# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
# cost of reduced performance. This can be particularly helpful with template
# rich C++ code for which doxygen's built-in parser lacks the necessary type
# information.
# Note: The availability of this option depends on whether or not doxygen was
# generated with the -Duse_libclang=ON option for CMake.
# The default value is: NO.
CLANG_ASSISTED_PARSING = NO
# If clang assisted parsing is enabled you can provide the compiler with command
# line options that you would normally use when invoking the compiler. Note that
# the include paths will already be set by doxygen for the files and directories
# specified with INPUT and INCLUDE_PATH.
# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
CLANG_OPTIONS =
# If clang assisted parsing is enabled you can provide the clang parser with the
# path to the compilation database (see:
# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) used when the files
# were built. This is equivalent to specifying the "-p" option to a clang tool,
# such as clang-check. These options will then be passed to the parser.
# Note: The availability of this option depends on whether or not doxygen was
# generated with the -Duse_libclang=ON option for CMake.
CLANG_DATABASE_PATH =
#---------------------------------------------------------------------------
# Configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
@ -1100,7 +1205,7 @@ HTML_EXTRA_FILES =
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
# will adjust the colors in the style sheet and background images according to
# this color. Hue is specified as an angle on a colorwheel, see
# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
# https://en.wikipedia.org/wiki/Hue for more information. For instance the value
# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
# purple, and 360 is red again.
# Minimum value: 0, maximum value: 359, default value: 220.
@ -1129,12 +1234,24 @@ HTML_COLORSTYLE_GAMMA = 80
# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
# page will contain the date and time when the page was generated. Setting this
# to NO can help when comparing the output of multiple runs.
# The default value is: YES.
# to YES can help to show when doxygen was last run and thus if the
# documentation is up to date.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_TIMESTAMP = YES
# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
# documentation will contain a main index with vertical navigation menus that
# are dynamically created via JavaScript. If disabled, the navigation index will
# consists of multiple levels of tabs that are statically embedded in every HTML
# page. Disable this option to support browsers that do not have JavaScript,
# like the Qt help browser.
# The default value is: YES.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_DYNAMIC_MENUS = YES
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
# documentation will contain sections that can be hidden and shown after the
# page has loaded.
@ -1158,13 +1275,13 @@ HTML_INDEX_NUM_ENTRIES = 100
# If the GENERATE_DOCSET tag is set to YES, additional index files will be
# generated that can be used as input for Apple's Xcode 3 integrated development
# environment (see: http://developer.apple.com/tools/xcode/), introduced with
# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
# environment (see: https://developer.apple.com/xcode/), introduced with OSX
# 10.5 (Leopard). To create a documentation set, doxygen will generate a
# Makefile in the HTML output directory. Running make will produce the docset in
# that directory and running make install will install the docset in
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
# for more information.
# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy
# genXcode/_index.html for more information.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
@ -1203,7 +1320,7 @@ DOCSET_PUBLISHER_NAME = Publisher
# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on
# Windows.
#
# The HTML Help Workshop contains a compiler that can convert all HTML output
@ -1279,7 +1396,7 @@ QCH_FILE =
# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
# Project output. For more information please see Qt Help Project / Namespace
# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
# (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).
# The default value is: org.doxygen.Project.
# This tag requires that the tag GENERATE_QHP is set to YES.
@ -1287,7 +1404,7 @@ QHP_NAMESPACE = org.doxygen.Project
# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
# Help Project output. For more information please see Qt Help Project / Virtual
# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
# Folders (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-
# folders).
# The default value is: doc.
# This tag requires that the tag GENERATE_QHP is set to YES.
@ -1296,7 +1413,7 @@ QHP_VIRTUAL_FOLDER = doc
# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
# filter to add. For more information please see Qt Help Project / Custom
# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
# filters).
# This tag requires that the tag GENERATE_QHP is set to YES.
@ -1304,7 +1421,7 @@ QHP_CUST_FILTER_NAME =
# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
# custom filter to add. For more information please see Qt Help Project / Custom
# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
# filters).
# This tag requires that the tag GENERATE_QHP is set to YES.
@ -1312,7 +1429,7 @@ QHP_CUST_FILTER_ATTRS =
# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
# project's filter section matches. Qt Help Project / Filter Attributes (see:
# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_SECT_FILTER_ATTRS =
@ -1405,7 +1522,7 @@ EXT_LINKS_IN_WINDOW = NO
FORMULA_FONTSIZE = 10
# Use the FORMULA_TRANPARENT tag to determine whether or not the images
# Use the FORMULA_TRANSPARENT tag to determine whether or not the images
# generated for formulas are transparent PNGs. Transparent PNGs are not
# supported properly for IE 6.0, but are supported on all modern browsers.
#
@ -1416,8 +1533,14 @@ FORMULA_FONTSIZE = 10
FORMULA_TRANSPARENT = YES
# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands
# to create new LaTeX commands to be used in formulas as building blocks. See
# the section "Including formulas" for details.
FORMULA_MACROFILE =
# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
# http://www.mathjax.org) which uses client side Javascript for the rendering
# https://www.mathjax.org) which uses client side JavaScript for the rendering
# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
# installed or if you want to formulas look prettier in the HTML output. When
# enabled you may also need to install MathJax separately and configure the path
@ -1444,8 +1567,8 @@ MATHJAX_FORMAT = HTML-CSS
# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
# Content Delivery Network so you can quickly see the result without installing
# MathJax. However, it is strongly recommended to install a local copy of
# MathJax from http://www.mathjax.org before deployment.
# The default value is: http://cdn.mathjax.org/mathjax/latest.
# MathJax from https://www.mathjax.org before deployment.
# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/.
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
@ -1487,7 +1610,7 @@ MATHJAX_CODEFILE =
SEARCHENGINE = YES
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
# implemented using a web server instead of a web client using Javascript. There
# implemented using a web server instead of a web client using JavaScript. There
# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
# setting. When disabled, doxygen will generate a PHP script for searching and
# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
@ -1506,7 +1629,7 @@ SERVER_BASED_SEARCH = NO
#
# Doxygen ships with an example indexer (doxyindexer) and search engine
# (doxysearch.cgi) which are based on the open source search engine library
# Xapian (see: http://xapian.org/).
# Xapian (see: https://xapian.org/).
#
# See the section "External Indexing and Searching" for details.
# The default value is: NO.
@ -1519,7 +1642,7 @@ EXTERNAL_SEARCH = NO
#
# Doxygen ships with an example indexer (doxyindexer) and search engine
# (doxysearch.cgi) which are based on the open source search engine library
# Xapian (see: http://xapian.org/). See the section "External Indexing and
# Xapian (see: https://xapian.org/). See the section "External Indexing and
# Searching" for details.
# This tag requires that the tag SEARCHENGINE is set to YES.
@ -1571,21 +1694,35 @@ LATEX_OUTPUT = latex
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
# invoked.
#
# Note that when enabling USE_PDFLATEX this option is only used for generating
# bitmaps for formulas in the HTML output, but not in the Makefile that is
# written to the output directory.
# The default file is: latex.
# Note that when not enabling USE_PDFLATEX the default is latex when enabling
# USE_PDFLATEX the default is pdflatex and when in the later case latex is
# chosen this is overwritten by pdflatex. For specific output languages the
# default can have been set differently, this depends on the implementation of
# the output language.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_CMD_NAME = latex
# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
# index for LaTeX.
# Note: This tag is used in the Makefile / make.bat.
# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file
# (.tex).
# The default file is: makeindex.
# This tag requires that the tag GENERATE_LATEX is set to YES.
MAKEINDEX_CMD_NAME = makeindex
# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to
# generate index for LaTeX. In case there is no backslash (\) as first character
# it will be automatically added in the LaTeX code.
# Note: This tag is used in the generated output file (.tex).
# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat.
# The default value is: makeindex.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_MAKEINDEX_CMD = makeindex
# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
# documents. This may be useful for small projects and may help to save some
# trees in general.
@ -1604,9 +1741,12 @@ COMPACT_LATEX = NO
PAPER_TYPE = a4
# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
# that should be included in the LaTeX output. To get the times font for
# instance you can specify
# EXTRA_PACKAGES=times
# that should be included in the LaTeX output. The package can be specified just
# by its name or with the correct syntax as to be used with the LaTeX
# \usepackage command. To get the times font for instance you can specify :
# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
# To use the option intlimits with the amsmath package you can specify:
# EXTRA_PACKAGES=[intlimits]{amsmath}
# If left blank no extra packages will be included.
# This tag requires that the tag GENERATE_LATEX is set to YES.
@ -1703,12 +1843,28 @@ LATEX_SOURCE_CODE = NO
# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
# bibliography, e.g. plainnat, or ieeetr. See
# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
# https://en.wikipedia.org/wiki/BibTeX and \cite for more info.
# The default value is: plain.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_BIB_STYLE = plain
# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
# page will contain the date and time when the page was generated. Setting this
# to NO can help when comparing the output of multiple runs.
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_TIMESTAMP = NO
# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute)
# path from which the emoji images will be read. If a relative path is entered,
# it will be relative to the LATEX_OUTPUT directory. If left blank the
# LATEX_OUTPUT directory will be used.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_EMOJI_DIRECTORY =
#---------------------------------------------------------------------------
# Configuration options related to the RTF output
#---------------------------------------------------------------------------
@ -1748,9 +1904,9 @@ COMPACT_RTF = NO
RTF_HYPERLINKS = NO
# Load stylesheet definitions from file. Syntax is similar to doxygen's config
# file, i.e. a series of assignments. You only have to provide replacements,
# missing definitions are set to their default value.
# Load stylesheet definitions from file. Syntax is similar to doxygen's
# configuration file, i.e. a series of assignments. You only have to provide
# replacements, missing definitions are set to their default value.
#
# See also section "Doxygen usage" for information on how to generate the
# default style sheet that doxygen normally uses.
@ -1759,8 +1915,8 @@ RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
# Set optional variables used in the generation of an RTF document. Syntax is
# similar to doxygen's config file. A template extensions file can be generated
# using doxygen -e rtf extensionFile.
# similar to doxygen's configuration file. A template extensions file can be
# generated using doxygen -e rtf extensionFile.
# This tag requires that the tag GENERATE_RTF is set to YES.
RTF_EXTENSIONS_FILE =
@ -1846,6 +2002,13 @@ XML_OUTPUT = xml
XML_PROGRAMLISTING = NO
# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include
# namespace members in file scope as well, matching the HTML output.
# The default value is: NO.
# This tag requires that the tag GENERATE_XML is set to YES.
XML_NS_MEMB_FILE_SCOPE = NO
#---------------------------------------------------------------------------
# Configuration options related to the DOCBOOK output
#---------------------------------------------------------------------------
@ -1878,9 +2041,9 @@ DOCBOOK_PROGRAMLISTING = NO
#---------------------------------------------------------------------------
# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
# AutoGen Definitions (see http://autogen.sf.net) file that captures the
# structure of the code including all documentation. Note that this feature is
# still experimental and incomplete at the moment.
# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures
# the structure of the code including all documentation. Note that this feature
# is still experimental and incomplete at the moment.
# The default value is: NO.
GENERATE_AUTOGEN_DEF = NO
@ -2047,12 +2210,6 @@ EXTERNAL_GROUPS = YES
EXTERNAL_PAGES = YES
# The PERL_PATH should be the absolute path and name of the perl script
# interpreter (i.e. the result of 'which perl').
# The default file (with absolute path) is: /usr/bin/perl.
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
@ -2066,15 +2223,6 @@ PERL_PATH = /usr/bin/perl
CLASS_DIAGRAMS = YES
# You can define message sequence charts within doxygen comments using the \msc
# command. Doxygen will then run the mscgen tool (see:
# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
# documentation. The MSCGEN_PATH tag allows you to specify the directory where
# the mscgen tool resides. If left empty the tool is assumed to be found in the
# default search path.
MSCGEN_PATH =
# You can include diagrams made with dia in doxygen documentation. Doxygen will
# then run dia to produce the diagram and insert it in the documentation. The
# DIA_PATH tag allows you to specify the directory where the dia binary resides.
@ -2093,7 +2241,7 @@ HIDE_UNDOC_RELATIONS = YES
# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
# Bell Labs. The other options in this section have no effect if this option is
# set to NO
# The default value is: NO.
# The default value is: YES.
HAVE_DOT = NO
@ -2207,7 +2355,8 @@ INCLUDED_BY_GRAPH = YES
#
# Note that enabling this option will significantly increase the time of a run.
# So in most cases it will be better to enable call graphs for selected
# functions only using the \callgraph command.
# functions only using the \callgraph command. Disabling a call graph can be
# accomplished by means of the command \hidecallgraph.
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
@ -2218,7 +2367,8 @@ CALL_GRAPH = NO
#
# Note that enabling this option will significantly increase the time of a run.
# So in most cases it will be better to enable caller graphs for selected
# functions only using the \callergraph command.
# functions only using the \callergraph command. Disabling a caller graph can be
# accomplished by means of the command \hidecallergraph.
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
@ -2241,11 +2391,17 @@ GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
# generated by dot.
# generated by dot. For an explanation of the image formats see the section
# output formats in the documentation of the dot tool (Graphviz (see:
# http://www.graphviz.org/)).
# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
# to make the SVG files visible in IE 9+ (other browsers do not have this
# requirement).
# Possible values are: png, jpg, gif and svg.
# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd,
# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo,
# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo,
# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
# png:gdiplus:gdiplus.
# The default value is: png.
# This tag requires that the tag HAVE_DOT is set to YES.
@ -2296,6 +2452,11 @@ DIAFILE_DIRS =
PLANTUML_JAR_PATH =
# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a
# configuration file for plantuml.
PLANTUML_CFG_FILE =
# When using plantuml, the specified paths are searched for files specified by
# the !include statement in a plantuml block.

View file

@ -1743,6 +1743,7 @@ class wallet_api
*
* @param voting_account the name or id of the account who is voting with their shares
* @param son the name or id of the SONs' owner account
* @param sidechain the name of the sidechain
* @param approve true if you wish to vote in favor of that SON, false to
* remove your vote in favor of that SON
* @param broadcast true if you wish to broadcast the transaction
@ -1750,6 +1751,7 @@ class wallet_api
*/
signed_transaction vote_for_son(string voting_account,
string son,
sidechain_type sidechain,
bool approve,
bool broadcast = false);

View file

@ -2743,6 +2743,7 @@ public:
signed_transaction vote_for_son(string voting_account,
string son,
sidechain_type sidechain,
bool approve,
bool broadcast /* = false */)
{ try {
@ -2758,17 +2759,30 @@ public:
fc::optional<son_object> son_obj = _remote_db->get_son_by_account_id(son_account_id);
if (!son_obj)
FC_THROW("Account ${son} is not registered as a son", ("son", son));
vote_id_type sidechain_vote_id;
switch (sidechain) {
case sidechain_type::bitcoin:
sidechain_vote_id = son_obj->vote_id_bitcoin;
break;
case sidechain_type::hive:
sidechain_vote_id = son_obj->vote_id_hive;
break;
default:
FC_THROW("Invalid sidechain type");
};
if (approve)
{
auto insert_result = voting_account_object.options.votes.insert(son_obj->vote_id);
auto insert_result = voting_account_object.options.votes.insert(sidechain_vote_id);
if (!insert_result.second)
FC_THROW("Account ${account} was already voting for son ${son}", ("account", voting_account)("son", son));
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->vote_id);
unsigned votes_removed = voting_account_object.options.votes.erase(sidechain_vote_id);
if (!votes_removed)
FC_THROW("Account ${account} is already not voting for son ${son}", ("account", voting_account)("son", son));
FC_THROW("Account ${account} has already unvoted for son ${son} for sidechain ${sidechain}", ("account", voting_account)("son", son)("sidechain", sidechain));
}
account_update_operation account_update_op;
account_update_op.account = voting_account_object.id;
@ -2788,44 +2802,44 @@ public:
uint16_t desired_number_of_sons,
bool broadcast /* = false */)
{ try {
FC_ASSERT(sons_to_approve.size() || sons_to_reject.size(), "Both accepted and rejected lists can't be empty simultaneously");
std::vector<vesting_balance_object_with_info> vbo_info = get_vesting_balances(voting_account);
std::vector<vesting_balance_object_with_info>::iterator vbo_iter;
vbo_iter = std::find_if(vbo_info.begin(), vbo_info.end(), [](vesting_balance_object_with_info const& obj){return obj.balance_type == vesting_balance_type::gpos;});
if( vbo_info.size() == 0 || vbo_iter == vbo_info.end())
FC_THROW("Account ${account} has no core Token ${TOKEN} vested and will not be allowed to vote for the SON account", ("account", voting_account)("TOKEN", GRAPHENE_SYMBOL));
account_object voting_account_object = get_account(voting_account);
for (const std::string& son : sons_to_approve)
{
account_id_type son_owner_account_id = get_account_id(son);
fc::optional<son_object> son_obj = _remote_db->get_son_by_account_id(son_owner_account_id);
if (!son_obj)
FC_THROW("Account ${son} is not registered as a SON", ("son", son));
auto insert_result = voting_account_object.options.votes.insert(son_obj->vote_id);
if (!insert_result.second)
FC_THROW("Account ${account} was already voting for SON ${son}", ("account", voting_account)("son", son));
}
for (const std::string& son : sons_to_reject)
{
account_id_type son_owner_account_id = get_account_id(son);
fc::optional<son_object> son_obj = _remote_db->get_son_by_account_id(son_owner_account_id);
if (!son_obj)
FC_THROW("Account ${son} is not registered as a SON", ("son", son));
unsigned votes_removed = voting_account_object.options.votes.erase(son_obj->vote_id);
if (!votes_removed)
FC_THROW("Account ${account} is already not voting for SON ${son}", ("account", voting_account)("son", son));
}
voting_account_object.options.num_son = desired_number_of_sons;
account_update_operation account_update_op;
account_update_op.account = voting_account_object.id;
account_update_op.new_options = voting_account_object.options;
//FC_ASSERT(sons_to_approve.size() || sons_to_reject.size(), "Both accepted and rejected lists can't be empty simultaneously");
//std::vector<vesting_balance_object_with_info> vbo_info = get_vesting_balances(voting_account);
//std::vector<vesting_balance_object_with_info>::iterator vbo_iter;
//vbo_iter = std::find_if(vbo_info.begin(), vbo_info.end(), [](vesting_balance_object_with_info const& obj){return obj.balance_type == vesting_balance_type::gpos;});
//if( vbo_info.size() == 0 || vbo_iter == vbo_info.end())
// FC_THROW("Account ${account} has no core Token ${TOKEN} vested and will not be allowed to vote for the SON account", ("account", voting_account)("TOKEN", GRAPHENE_SYMBOL));
//
//account_object voting_account_object = get_account(voting_account);
//for (const std::string& son : sons_to_approve)
//{
// account_id_type son_owner_account_id = get_account_id(son);
// fc::optional<son_object> son_obj = _remote_db->get_son_by_account_id(son_owner_account_id);
// if (!son_obj)
// FC_THROW("Account ${son} is not registered as a SON", ("son", son));
// auto insert_result = voting_account_object.options.votes.insert(son_obj->vote_id);
// if (!insert_result.second)
// FC_THROW("Account ${account} was already voting for SON ${son}", ("account", voting_account)("son", son));
//}
//for (const std::string& son : sons_to_reject)
//{
// account_id_type son_owner_account_id = get_account_id(son);
// fc::optional<son_object> son_obj = _remote_db->get_son_by_account_id(son_owner_account_id);
// if (!son_obj)
// FC_THROW("Account ${son} is not registered as a SON", ("son", son));
// unsigned votes_removed = voting_account_object.options.votes.erase(son_obj->vote_id);
// if (!votes_removed)
// FC_THROW("Account ${account} is already not voting for SON ${son}", ("account", voting_account)("son", son));
//}
//voting_account_object.options.num_son = desired_number_of_sons;
//
//account_update_operation account_update_op;
//account_update_op.account = voting_account_object.id;
//account_update_op.new_options = voting_account_object.options;
signed_transaction tx;
tx.operations.push_back( account_update_op );
set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees);
tx.validate();
//tx.operations.push_back( account_update_op );
//set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees);
//tx.validate();
return sign_transaction( tx, broadcast );
} FC_CAPTURE_AND_RETHROW( (voting_account)(sons_to_approve)(sons_to_reject)(desired_number_of_sons)(broadcast) ) }
@ -5401,10 +5415,11 @@ signed_transaction wallet_api::vote_for_committee_member(string voting_account,
signed_transaction wallet_api::vote_for_son(string voting_account,
string son,
sidechain_type sidechain,
bool approve,
bool broadcast /* = false */)
{
return my->vote_for_son(voting_account, son, approve, broadcast);
return my->vote_for_son(voting_account, son, sidechain, approve, broadcast);
}
signed_transaction wallet_api::update_son_votes(string voting_account,

View file

@ -86,8 +86,7 @@ int main(int argc, char **argv) {
bpo::variables_map options;
try
{
try {
bpo::parsed_options po = bpo::command_line_parser(argc, argv).options(opts).allow_unregistered().run();
std::vector<std::string> unrecognized = bpo::collect_unrecognized(po.options, bpo::include_positional);
if (unrecognized.size() > 0) {
@ -98,9 +97,7 @@ int main(int argc, char **argv) {
return 0;
}
bpo::store(po, options);
}
catch (const boost::program_options::invalid_command_line_syntax & e)
{
} catch (const boost::program_options::invalid_command_line_syntax &e) {
std::cout << e.what() << std::endl;
return 0;
}