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-16] SON voting and voting result #49

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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_member_object_type:{
const auto& son_object = dynamic_cast<const son_member_object*>(obj);
assert( son_object != nullptr );
accounts.insert( son_object->son_member_account );
break;
}
case sport_object_type:
case event_group_object_type:
case event_object_type:
Expand Down
23 changes: 23 additions & 0 deletions libraries/app/database_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ 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
fc::optional<son_member_object> get_son_member_by_account(account_id_type account)const;

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

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

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

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

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

//////////////////////////////////////////////////////////////////////
// //
// Votes //
Expand Down
6 changes: 6 additions & 0 deletions libraries/app/impacted.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,12 @@ struct get_impacted_account_visitor
_impacted.insert( op.affiliate );
}
void operator()( const affiliate_referral_payout_operation& op ) { }
void operator()( const son_member_create_operation& op ){
_impacted.insert( op.owner_account );
}
void operator()( const son_member_delete_operation& op ){
_impacted.insert( op.owner_account );
}
};

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

#include <graphene/chain/btc-sidechain/son.hpp>

#include <graphene/chain/worker_object.hpp>
#include <graphene/chain/witness_object.hpp>
#include <graphene/chain/tournament_object.hpp>
Expand Down Expand Up @@ -546,6 +548,17 @@ 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 the son_member owned by a given account
* @param account The ID of the account whose son_member should be retrieved
* @return The son_member object, or null if the account does not have a son_member
*/
fc::optional<son_member_object> get_son_member_by_account(account_id_type account)const;


/// WORKERS

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

// SON members
(get_son_member_by_account)

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

btc-sidechain/son_operations_evaluator.cpp

${HEADERS}
${PROTOCOL_HEADERS}
"${CMAKE_CURRENT_BINARY_DIR}/include/graphene/chain/hardfork.hpp"
Expand Down
45 changes: 45 additions & 0 deletions libraries/chain/btc-sidechain/son_operations_evaluator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include <graphene/chain/btc-sidechain/son_operations_evaluator.hpp>

#include <graphene/chain/database.hpp>
#include <graphene/chain/btc-sidechain/son.hpp>

namespace graphene { namespace chain {

void_result create_son_member_evaluator::do_evaluate(const son_member_create_operation& op)
{ try{
FC_ASSERT(db().get(op.owner_account).is_lifetime_member(), "Only Lifetime members may register a SON.");
return void_result();
} FC_CAPTURE_AND_RETHROW( (op) ) }

object_id_type create_son_member_evaluator::do_apply(const son_member_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);
});

const auto& new_son_object = db().create<son_member_object>( [&]( son_member_object& obj ){
obj.son_member_account = op.owner_account;
obj.vote_id = vote_id;
obj.url = op.url;
});
return new_son_object.id;
} FC_CAPTURE_AND_RETHROW( (op) ) }

void_result delete_son_member_evaluator::do_evaluate(const son_member_delete_operation& op)
{ try {
database& d = db();
const auto& idx = d.get_index_type<son_member_index>().indices().get<by_account>();
FC_ASSERT( idx.find(op.owner_account) != idx.end() );
return void_result();
} FC_CAPTURE_AND_RETHROW( (op) ) }

void_result delete_son_member_evaluator::do_apply(const son_member_delete_operation& op)
{ try {
const auto& idx = db().get_index_type<son_member_index>().indices().get<by_account>();
db().remove(*idx.find(op.owner_account));
return void_result();
} FC_CAPTURE_AND_RETHROW( (op) ) }

} } // namespace graphene::chain

9 changes: 9 additions & 0 deletions libraries/chain/db_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,12 @@
#include <graphene/chain/betting_market_evaluator.hpp>
#include <graphene/chain/tournament_evaluator.hpp>

#include <graphene/chain/btc-sidechain/son_operations_evaluator.hpp>

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

#include <graphene/chain/btc-sidechain/son.hpp>

#include <fc/smart_ref_impl.hpp>
#include <fc/uint128.hpp>
#include <fc/crypto/digest.hpp>
Expand Down Expand Up @@ -237,6 +241,9 @@ void database::initialize_evaluators()
register_evaluator<tournament_join_evaluator>();
register_evaluator<game_move_evaluator>();
register_evaluator<tournament_leave_evaluator>();

register_evaluator<create_son_member_evaluator>();
register_evaluator<delete_son_member_evaluator>();
}

void database::initialize_indexes()
Expand Down Expand Up @@ -301,6 +308,8 @@ void database::initialize_indexes()
//add_index< primary_index<distributed_dividend_balance_object_index > >();
add_index< primary_index<pending_dividend_payout_balance_for_holder_object_index > >();
add_index< primary_index<total_distributed_dividend_balance_object_index > >();

add_index< primary_index<son_member_index> >();
}

void database::init_genesis(const genesis_state_type& genesis_state)
Expand Down
46 changes: 45 additions & 1 deletion libraries/chain/db_maint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ void database::update_active_witnesses()
void database::update_active_committee_members()
{ try {
assert( _committee_count_histogram_buffer.size() > 0 );
share_type stake_target = (_total_voting_stake-_witness_count_histogram_buffer[0]) / 2;
share_type stake_target = (_total_voting_stake - _committee_count_histogram_buffer[0]) / 2;

/// accounts that vote for 0 or 1 witness do not get to express an opinion on
/// the number of witnesses to have (they abstain and are non-voting accounts)
Expand Down Expand Up @@ -326,6 +326,37 @@ void database::update_active_committee_members()
});
} FC_CAPTURE_AND_RETHROW() }

void database::update_active_son_members()
{ try {
share_type stake_target = (_total_voting_stake-_son_count_histogram_buffer[0]) / 2;

/// accounts that vote for 0 or 1 sons do not get to express an opinion on
/// the number of sons to have (they abstain and are non-voting accounts)
uint64_t stake_tally = 0; // _son_count_histogram_buffer[0];
size_t son_member_count = 0;

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

const chain_property_object& cpo = get_chain_properties();
auto son_members = sort_votable_objects<son_member_index>(std::max(son_member_count*2+1, (size_t)cpo.immutable_parameters.min_son_member_count));

for( const son_member_object& son : son_members )
{
modify( son, [&]( son_member_object& obj ) {
obj.total_votes = _vote_tally_buffer[son.vote_id];
});
}
modify(get_global_properties(), [&](global_property_object& gp) {
gp.active_son_members.clear();
std::transform(son_members.begin(), son_members.end(),
std::inserter(gp.active_son_members, gp.active_son_members.begin()),
[](const son_member_object& s) { return s.id; });
});
} 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 +1432,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 +1535,16 @@ 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.
//
// same rationale as for witnesses
d._son_count_histogram_buffer[offset] += voting_stake;
}

d._total_voting_stake += voting_stake;
}
Expand Down Expand Up @@ -1533,11 +1575,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_son_members();
update_worker_votes();

modify(gpo, [this](global_property_object& p) {
Expand Down
11 changes: 11 additions & 0 deletions libraries/chain/db_notify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,12 @@ struct get_impacted_account_visitor
_impacted.insert( op.affiliate );
}
void operator()( const affiliate_referral_payout_operation& op ) { }
void operator()( const son_member_create_operation& op ) {
_impacted.insert( op.owner_account );
}
void operator()( const son_member_delete_operation& op ) {
_impacted.insert( op.owner_account );
}
};

void operation_get_impacted_accounts( const operation& op, flat_set<account_id_type>& result )
Expand Down Expand Up @@ -357,6 +363,11 @@ void get_relevant_accounts( const object* obj, flat_set<account_id_type>& accoun
} case balance_object_type:{
/** these are free from any accounts */
break;
} case son_member_object_type:{
const auto& son_object = dynamic_cast<const son_member_object*>(obj);
assert( son_object != nullptr );
accounts.insert( son_object->son_member_account );
break;
}
}
}
Expand Down
49 changes: 49 additions & 0 deletions libraries/chain/include/graphene/chain/btc-sidechain/son.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp>

namespace graphene { namespace chain {
using namespace graphene::db;

/**
* @class son_member_object
* @brief tracks information about a son_member account.
* @ingroup object
*/
class son_member_object : public abstract_object<son_member_object>
{
public:
static const uint8_t space_id = protocol_ids;
static const uint8_t type_id = son_member_object_type;

account_id_type son_member_account;
vote_id_type vote_id;
uint64_t total_votes = 0;
string url;

son_member_id_type get_id()const { return id; }

};

struct by_account;
struct by_vote_id;
using son_member_multi_index_type = multi_index_container<
son_member_object,
indexed_by<
ordered_unique< tag<by_id>,
member<object, object_id_type, &object::id>
>,
ordered_unique< tag<by_account>,
member<son_member_object, account_id_type, &son_member_object::son_member_account>
>,
ordered_unique< tag<by_vote_id>,
member<son_member_object, vote_id_type, &son_member_object::vote_id>
>
>
>;
using son_member_index = generic_index<son_member_object, son_member_multi_index_type>;
} } // graphene::chain

FC_REFLECT_DERIVED( graphene::chain::son_member_object, (graphene::db::object),
(son_member_account)(vote_id)(total_votes)(url) )
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#pragma once
#include <graphene/chain/protocol/base.hpp>

namespace graphene { namespace chain {

struct son_member_create_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = 0; };

asset fee;
account_id_type owner_account;
std::string url;

account_id_type fee_payer()const { return owner_account; }
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }

void validate()const {
FC_ASSERT( fee.amount >= 0 );
FC_ASSERT( url.size() < GRAPHENE_MAX_URL_LENGTH );
}
};

struct son_member_delete_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = 0; };

asset fee;
account_id_type owner_account;

account_id_type fee_payer()const { return owner_account; }
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }

void validate()const {
FC_ASSERT( fee.amount >= 0 );
}
};

} } // namespace graphene::chain

FC_REFLECT( graphene::chain::son_member_create_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::son_member_create_operation, (fee)(owner_account)(url) )

FC_REFLECT( graphene::chain::son_member_delete_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::son_member_delete_operation, (fee)(owner_account) )
Loading