Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SON related operations, cli_wallet commands and RPC #160

Merged
merged 37 commits into from
Oct 9, 2019
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
988a177
Added SON object
pixelplex-dev Jul 26, 2019
d36168b
Merge commit 'refs/pull/48/head' of https://github.com/peerplays-netw…
oxarbitrage Sep 18, 2019
7d6b215
rename and move stuff
oxarbitrage Sep 19, 2019
38ec553
remove member from operation names
oxarbitrage Sep 19, 2019
52e9c2a
remove not needed library
oxarbitrage Sep 19, 2019
ba77a33
rename object, add update operation skeleton
oxarbitrage Sep 20, 2019
5dcb55c
add modify logic, test case, modify delete
oxarbitrage Sep 21, 2019
6efbf84
change indentation of the son tests
oxarbitrage Sep 21, 2019
0a5d694
add hardfork guards
oxarbitrage Sep 21, 2019
723c802
minor clean
oxarbitrage Sep 21, 2019
3a4445b
add missing SON hardfork file
oxarbitrage Sep 24, 2019
17dfc6a
add protection to delete and modify son object only if owner
oxarbitrage Sep 25, 2019
4d0a5b6
add son vote type to lookup_vote_ids
oxarbitrage Sep 27, 2019
e2c579b
add additional fields to son object and operations
oxarbitrage Sep 28, 2019
3a65102
WIP, SON operations, cli_wallet commands and RPC
obucina Oct 1, 2019
44f185e
WIP, SON operations, cli_wallet commands and RPC
obucina Oct 2, 2019
457c8b9
WIP, SON related operations, cli_wallet commands and RPC
obucina Oct 2, 2019
49564af
WIP, SON related operations, cli_wallet commands and RPC
obucina Oct 2, 2019
53666a9
Merge branch 'feature/SON-operations' of https://github.com/peerplays…
obucina Oct 2, 2019
e0ff813
WIP, SON operations, cli_wallet commands and RPC
obucina Oct 2, 2019
203ee89
WIP, SON operations, cli_wallet commands and RPC
obucina Oct 2, 2019
ecfcd8e
WIP, SON operations, cli_wallet commands and RPC
obucina Oct 3, 2019
4d1bec0
WIP, SON operations, cli_wallet commands and RPC
obucina Oct 3, 2019
5ecbba8
WIP, SON operations, cli_wallet commands and RPC
obucina Oct 3, 2019
e4bf00e
WIP, SON operations, cli_wallet commands and RPC
obucina Oct 3, 2019
8bc204c
WIP, SON operations, cli_wallet commands and RPC
obucina Oct 4, 2019
3e4322b
WIP, SON operations, cli_wallet commands and RPC
obucina Oct 6, 2019
3b167ff
Merge branch 'feature/SONs-base' into feature/SON-operations
obucina Oct 8, 2019
7b6562e
Some renaming to follow existing naming convention, code cleanup
obucina Oct 8, 2019
d06b236
Add newline at the end of SON.hf
obucina Oct 8, 2019
659bfcb
Add missing comma in operations.hpp
obucina Oct 8, 2019
896b4df
Add missing parenthesis in libraries/chain/db_notify.cpp
obucina Oct 8, 2019
54599cc
Add missing parenthesis in ../../libraries/app/impacted.cpp
obucina Oct 8, 2019
bdfbf5c
Minor code cleanup
obucina Oct 9, 2019
388d00b
Fix build error, add missing parameter
obucina Oct 9, 2019
af0e0e4
Add missing #include
obucina Oct 9, 2019
d8e4a9a
Fix build error, remove undeclared field
obucina Oct 9, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion libraries/app/api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,12 @@ namespace graphene { namespace app {
} case balance_object_type:{
/** these are free from any accounts */
break;
}
} case son_object_type:{
const auto& aobj = dynamic_cast<const son_object*>(obj);
assert( aobj != nullptr );
accounts.insert( aobj->son_member_account );
break;
}
case sport_object_type:
case event_group_object_type:
case event_object_type:
Expand Down
92 changes: 92 additions & 0 deletions libraries/app/database_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,12 @@ class database_api_impl : public std::enable_shared_from_this<database_api_impl>
fc::optional<committee_member_object> get_committee_member_by_account(account_id_type account)const;
map<string, committee_member_id_type> lookup_committee_member_accounts(const string& lower_bound_name, uint32_t limit)const;

// SON members
vector<optional<son_object>> get_sons(const vector<son_id_type>& son_ids)const;
fc::optional<son_object> get_son_by_account(account_id_type account)const;
map<string, son_id_type> lookup_son_accounts(const string& lower_bound_name, uint32_t limit)const;
uint64_t get_son_count()const;

// Votes
vector<variant> lookup_vote_ids( const vector<vote_id_type>& votes )const;

Expand Down Expand Up @@ -1577,6 +1583,81 @@ map<string, committee_member_id_type> database_api_impl::lookup_committee_member
return committee_members_by_account_name;
}

//////////////////////////////////////////////////////////////////////
// //
// SON members //
// //
//////////////////////////////////////////////////////////////////////

vector<optional<son_object>> database_api::get_sons(const vector<son_id_type>& son_ids)const
{
return my->get_sons( son_ids );
}

vector<optional<son_object>> database_api_impl::get_sons(const vector<son_id_type>& son_ids)const
{
vector<optional<son_object>> result; result.reserve(son_ids.size());
std::transform(son_ids.begin(), son_ids.end(), std::back_inserter(result),
[this](son_id_type id) -> optional<son_object> {
if(auto o = _db.find(id))
return *o;
return {};
});
return result;
}

fc::optional<son_object> database_api::get_son_by_account(account_id_type account)const
{
return my->get_son_by_account( account );
}

fc::optional<son_object> database_api_impl::get_son_by_account(account_id_type account) const
{
const auto& idx = _db.get_index_type<son_index>().indices().get<by_account>();
auto itr = idx.find(account);
if( itr != idx.end() )
return *itr;
return {};
}

map<string, son_id_type> database_api::lookup_son_accounts(const string& lower_bound_name, uint32_t limit)const
{
return my->lookup_son_accounts( lower_bound_name, limit );
}

map<string, son_id_type> database_api_impl::lookup_son_accounts(const string& lower_bound_name, uint32_t limit)const
{
FC_ASSERT( limit <= 1000 );
const auto& sons_by_id = _db.get_index_type<son_index>().indices().get<by_id>();

// we want to order sons by account name, but that name is in the account object
// so the son_member_index doesn't have a quick way to access it.
// get all the names and look them all up, sort them, then figure out what
// records to return. This could be optimized, but we expect the
// number of witnesses to be few and the frequency of calls to be rare
std::map<std::string, son_id_type> sons_by_account_name;
for (const son_object& son : sons_by_id)
if (auto account_iter = _db.find(son.son_member_account))
if (account_iter->name >= lower_bound_name) // we can ignore anything below lower_bound_name
sons_by_account_name.insert(std::make_pair(account_iter->name, son.id));

auto end_iter = sons_by_account_name.begin();
while (end_iter != sons_by_account_name.end() && limit--)
++end_iter;
sons_by_account_name.erase(end_iter, sons_by_account_name.end());
return sons_by_account_name;
}

uint64_t database_api::get_son_count()const
{
return my->get_son_count();
}

uint64_t database_api_impl::get_son_count()const
{
return _db.get_index_type<son_index>().indices().size();
}

//////////////////////////////////////////////////////////////////////
// //
// Votes //
Expand All @@ -1596,6 +1677,7 @@ vector<variant> database_api_impl::lookup_vote_ids( const vector<vote_id_type>&
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() );
Expand Down Expand Up @@ -1638,6 +1720,16 @@ vector<variant> database_api_impl::lookup_vote_ids( const vector<vote_id_type>&
}
break;
}
case vote_id_type::son:
{
auto itr = son_idx.find( id );
if( itr != son_idx.end() )
result.emplace_back( variant( *itr ) );
else
result.emplace_back( variant() );
break;
}

case vote_id_type::VOTE_TYPE_COUNT: break; // supress unused enum value warnings
}
}
Expand Down
9 changes: 9 additions & 0 deletions libraries/app/impacted.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,15 @@ struct get_impacted_account_visitor
_impacted.insert( op.affiliate );
}
void operator()( const affiliate_referral_payout_operation& op ) { }
void operator()( const son_create_operation& op ){
_impacted.insert( op.owner_account );
}
void operator()( const son_update_operation& op ){
_impacted.insert( op.owner_account );
}
void operator()( const son_delete_operation& op ){
_impacted.insert( op.owner_account );
}
};

void operation_get_impacted_accounts( const operation& op, flat_set<account_id_type>& result )
Expand Down
39 changes: 39 additions & 0 deletions libraries/app/include/graphene/app/database_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include <graphene/chain/event_object.hpp>
#include <graphene/chain/betting_market_object.hpp>
#include <graphene/chain/global_betting_statistics_object.hpp>
#include <graphene/chain/son_object.hpp>

#include <graphene/chain/worker_object.hpp>
#include <graphene/chain/witness_object.hpp>
Expand Down Expand Up @@ -546,6 +547,38 @@ class database_api
*/
map<string, committee_member_id_type> lookup_committee_member_accounts(const string& lower_bound_name, uint32_t limit)const;

/////////////////
// SON members //
/////////////////

/**
* @brief Get a list of SONs by ID
* @param son_ids IDs of the SONs to retrieve
* @return The SONs corresponding to the provided IDs
*
* This function has semantics identical to @ref get_objects
*/
vector<optional<son_object>> get_sons(const vector<son_id_type>& son_ids)const;

/**
* @brief Get the SON owned by a given account
* @param account The ID of the account whose SON should be retrieved
* @return The SON object, or null if the account does not have a SON
*/
fc::optional<son_object> get_son_by_account(account_id_type account)const;

/**
* @brief Get names and IDs for registered SONs
* @param lower_bound_name Lower bound of the first name to return
* @param limit Maximum number of results to return -- must not exceed 1000
* @return Map of SON names to corresponding IDs
*/
map<string, son_id_type> lookup_son_accounts(const string& lower_bound_name, uint32_t limit)const;

/**
* @brief Get the total number of SONs registered with the blockchain
*/
uint64_t get_son_count()const;

/// WORKERS

Expand Down Expand Up @@ -757,6 +790,12 @@ FC_API(graphene::app::database_api,
(get_committee_member_by_account)
(lookup_committee_member_accounts)

// SON members
(get_sons)
(get_son_by_account)
(lookup_son_accounts)
(get_son_count)

// workers
(get_workers_by_account)
// Votes
Expand Down
2 changes: 2 additions & 0 deletions libraries/chain/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ add_library( graphene_chain

affiliate_payout.cpp

son_evaluator.cpp

${HEADERS}
${PROTOCOL_HEADERS}
"${CMAKE_CURRENT_BINARY_DIR}/include/graphene/chain/hardfork.hpp"
Expand Down
8 changes: 6 additions & 2 deletions libraries/chain/db_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,12 @@
#include <graphene/chain/tournament_object.hpp>
#include <graphene/chain/match_object.hpp>
#include <graphene/chain/game_object.hpp>


#include <graphene/chain/sport_object.hpp>
#include <graphene/chain/event_group_object.hpp>
#include <graphene/chain/event_object.hpp>
#include <graphene/chain/betting_market_object.hpp>
#include <graphene/chain/global_betting_statistics_object.hpp>
#include <graphene/chain/son_object.hpp>

#include <graphene/chain/account_evaluator.hpp>
#include <graphene/chain/asset_evaluator.hpp>
Expand All @@ -76,6 +75,7 @@
#include <graphene/chain/event_evaluator.hpp>
#include <graphene/chain/betting_market_evaluator.hpp>
#include <graphene/chain/tournament_evaluator.hpp>
#include <graphene/chain/son_evaluator.hpp>

#include <graphene/chain/protocol/fee_schedule.hpp>

Expand Down Expand Up @@ -237,6 +237,9 @@ void database::initialize_evaluators()
register_evaluator<tournament_join_evaluator>();
register_evaluator<game_move_evaluator>();
register_evaluator<tournament_leave_evaluator>();
register_evaluator<create_son_evaluator>();
register_evaluator<update_son_evaluator>();
register_evaluator<delete_son_evaluator>();
}

void database::initialize_indexes()
Expand All @@ -253,6 +256,7 @@ void database::initialize_indexes()
acnt_index->add_secondary_index<account_referrer_index>();

add_index< primary_index<committee_member_index> >();
add_index< primary_index<son_index> >();
add_index< primary_index<witness_index> >();
add_index< primary_index<limit_order_index > >();
add_index< primary_index<call_order_index > >();
Expand Down
105 changes: 105 additions & 0 deletions libraries/chain/db_maint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,96 @@ void database::update_active_committee_members()
});
} FC_CAPTURE_AND_RETHROW() }

void database::update_active_sons()
{ try {
assert( _son_count_histogram_buffer.size() > 0 );
share_type stake_target = (_total_voting_stake-_witness_count_histogram_buffer[0]) / 2;
obucina marked this conversation as resolved.
Show resolved Hide resolved

/// 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;

size_t son_count = 0;
if( stake_target > 0 )
{
while( (son_count < _son_count_histogram_buffer.size() - 1)
&& (stake_tally <= stake_target) )
{
stake_tally += _son_count_histogram_buffer[++son_count];
}
}

const chain_property_object& cpo = get_chain_properties();
auto sons = sort_votable_objects<son_index>(std::max(son_count*2+1, (size_t)cpo.immutable_parameters.min_son_count));

const global_property_object& gpo = get_global_properties();

const auto& all_sons = get_index_type<son_index>().indices();

for( const son_object& son : all_sons )
{
modify( son, [&]( son_object& obj ){
obj.total_votes = _vote_tally_buffer[son.vote_id];
});
}

// Update SON authority
modify( get(GRAPHENE_SON_ACCOUNT_ID), [&]( account_object& a )
{
if( head_block_time() < HARDFORK_533_TIME )
{
uint64_t total_votes = 0;
map<account_id_type, uint64_t> weights;
a.active.weight_threshold = 0;
a.active.clear();

for( const son_object& son : sons )
{
weights.emplace(son.son_member_account, _vote_tally_buffer[son.vote_id]);
total_votes += _vote_tally_buffer[son.vote_id];
}

// total_votes is 64 bits. Subtract the number of leading low bits from 64 to get the number of useful bits,
// then I want to keep the most significant 16 bits of what's left.
int8_t bits_to_drop = std::max(int(boost::multiprecision::detail::find_msb(total_votes)) - 15, 0);
for( const auto& weight : weights )
{
// Ensure that everyone has at least one vote. Zero weights aren't allowed.
uint16_t votes = std::max((weight.second >> bits_to_drop), uint64_t(1) );
a.active.account_auths[weight.first] += votes;
a.active.weight_threshold += votes;
}

a.active.weight_threshold /= 2;
a.active.weight_threshold += 1;
}
else
{
vote_counter vc;
for( const son_object& son : sons )
vc.add( son.son_member_account, std::max(_vote_tally_buffer[son.vote_id], UINT64_C(1)) );
vc.finish( a.active );
}
} );

modify(gpo, [&]( global_property_object& gp ){
gp.active_sons.clear();
gp.active_sons.reserve(sons.size());
std::transform(sons.begin(), sons.end(),
std::inserter(gp.active_sons, gp.active_sons.end()),
[](const son_object& s) {
return s.id;
});
});

//const witness_schedule_object& wso = witness_schedule_id_type()(*this);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check this

//modify(wso, [&](witness_schedule_object& _wso)
//{
// _wso.scheduler.update(gpo.active_witnesses);
//});
} FC_CAPTURE_AND_RETHROW() }

void database::initialize_budget_record( fc::time_point_sec now, budget_record& rec )const
{
const dynamic_global_property_object& dpo = get_dynamic_global_properties();
Expand Down Expand Up @@ -1401,6 +1491,7 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
d._vote_tally_buffer.resize(props.next_available_vote_id);
d._witness_count_histogram_buffer.resize(props.parameters.maximum_witness_count / 2 + 1);
d._committee_count_histogram_buffer.resize(props.parameters.maximum_committee_count / 2 + 1);
d._son_count_histogram_buffer.resize(props.parameters.maximum_son_count / 2 + 1);
d._total_voting_stake = 0;

auto balance_type = vesting_balance_type::unspecified;
Expand Down Expand Up @@ -1503,6 +1594,18 @@ 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;
}
if( opinion_account.options.num_son <= props.parameters.maximum_son_count )
{
uint16_t offset = std::min(size_t(opinion_account.options.num_son/2),
d._son_count_histogram_buffer.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[offset] += voting_stake;
}

d._total_voting_stake += voting_stake;
}
Expand Down Expand Up @@ -1533,11 +1636,13 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
};
clear_canary a(_witness_count_histogram_buffer),
b(_committee_count_histogram_buffer),
d(_son_count_histogram_buffer),
c(_vote_tally_buffer);

update_top_n_authorities(*this);
update_active_witnesses();
update_active_committee_members();
update_active_sons();
update_worker_votes();

modify(gpo, [this](global_property_object& p) {
Expand Down
Loading