Skip to content

Commit

Permalink
Merge pull request steemit#3344 from steemit/3336-downvote-pool
Browse files Browse the repository at this point in the history
Downvote Pool
  • Loading branch information
Michael Vandeberg authored Jun 10, 2019
2 parents 69dfc3b + 66e9ea0 commit 4c1224e
Show file tree
Hide file tree
Showing 9 changed files with 226 additions and 34 deletions.
21 changes: 13 additions & 8 deletions libraries/chain/database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1271,10 +1271,11 @@ asset create_vesting2( database& db, const account_object& to_account, asset liq
{
db.modify( to_account, [&]( account_object& a )
{
util::manabar_params params( util::get_effective_vesting_shares( a ), STEEM_VOTING_MANA_REGENERATION_SECONDS );
FC_TODO( "Set skip_cap_regen=true without breaking consensus" );
a.voting_manabar.regenerate_mana( params, db.head_block_time() );
a.voting_manabar.use_mana( -new_vesting.amount.value );
util::update_manabar(
cprops,
a,
db.has_hardfork( STEEM_HARDFORK_0_21__3336 ),
new_vesting.amount.value );
});
}

Expand Down Expand Up @@ -4286,6 +4287,8 @@ void database::clear_expired_delegations()
auto now = head_block_time();
const auto& delegations_by_exp = get_index< vesting_delegation_expiration_index, by_expiration >();
auto itr = delegations_by_exp.begin();
const auto& gpo = get_dynamic_global_properties();

while( itr != delegations_by_exp.end() && itr->expiration < now )
{
operation vop = return_vesting_delegation_operation( itr->delegator, itr->vesting_shares );
Expand All @@ -4295,10 +4298,11 @@ void database::clear_expired_delegations()
{
if( has_hardfork( STEEM_HARDFORK_0_20__2539 ) )
{
util::manabar_params params( util::get_effective_vesting_shares( a ), STEEM_VOTING_MANA_REGENERATION_SECONDS );
FC_TODO( "Set skip_cap_regen=true without breaking consensus" );
a.voting_manabar.regenerate_mana( params, head_block_time() );
a.voting_manabar.use_mana( -itr->vesting_shares.amount.value );
util::update_manabar(
gpo,
a,
has_hardfork( STEEM_HARDFORK_0_21__3336 ),
itr->vesting_shares.amount.value );
}

a.delegated_vesting_shares -= itr->vesting_shares;
Expand Down Expand Up @@ -5199,6 +5203,7 @@ void database::apply_hardfork( uint32_t hardfork )
modify( get_dynamic_global_properties(), [&]( dynamic_global_property_object& gpo )
{
gpo.sbd_stop_adjust = STEEM_SBD_STOP_ADJUST;
gpo.downvote_pool_percent = STEEM_DOWNVOTE_POOL_PERCENT_HF21;
});

auto account_auth = find< account_authority_object, by_account >( STEEM_TREASURY_ACCOUNT );
Expand Down
3 changes: 2 additions & 1 deletion libraries/chain/include/steem/chain/account_object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ namespace steem { namespace chain {

bool can_vote = true;
util::manabar voting_manabar;
util::manabar downvote_manabar;

asset balance = asset( 0, STEEM_SYMBOL ); ///< total liquid shares held by this account
asset savings_balance = asset( 0, STEEM_SYMBOL ); ///< total liquid shares held by this account
Expand Down Expand Up @@ -439,7 +440,7 @@ FC_REFLECT( steem::chain::account_object,
(id)(name)(memo_key)(proxy)(last_account_update)
(created)(mined)
(recovery_account)(last_account_recovery)(reset_account)
(comment_count)(lifetime_vote_count)(post_count)(can_vote)(voting_manabar)
(comment_count)(lifetime_vote_count)(post_count)(can_vote)(voting_manabar)(downvote_manabar)
(balance)
(savings_balance)
(sbd_balance)(sbd_seconds)(sbd_seconds_last_update)(sbd_last_interest_payment)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ namespace steem { namespace chain {
time_point_sec next_maintenance_time;
time_point_sec last_budget_time;

uint16_t downvote_pool_percent = 0;

#ifdef STEEM_ENABLE_SMT
asset smt_creation_fee = asset( 1000, SBD_SYMBOL );
#endif
Expand Down Expand Up @@ -201,6 +203,7 @@ FC_REFLECT( steem::chain::dynamic_global_property_object,
(sbd_stop_adjust)
(next_maintenance_time)
(last_budget_time)
(downvote_pool_percent)
#ifdef STEEM_ENABLE_SMT
(smt_creation_fee)
#endif
Expand Down
18 changes: 18 additions & 0 deletions libraries/chain/include/steem/chain/util/manabar.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,24 @@ int64_t get_effective_vesting_shares( const T& account )
return effective_vesting_shares;
}

template< typename PropType, typename AccountType >
void update_manabar( const PropType& gpo, AccountType& account, bool downvote_mana = false, int64_t new_mana = 0 )
{
auto effective_vests = util::get_effective_vesting_shares( account );
manabar_params params( effective_vests, STEEM_VOTING_MANA_REGENERATION_SECONDS );
account.voting_manabar.regenerate_mana( params, gpo.time );
account.voting_manabar.use_mana( -new_mana );

FC_TODO( "This hardfork check should not be needed. Remove after HF21 if that is the case." );
// This is used as a hardfork check. Can be replaced with if( gpo.downvote_pool_percent ). Leaving as a hard check to be safe until after HF 21
if( downvote_mana )
{
util::manabar_params params( ( effective_vests * gpo.downvote_pool_percent ) / STEEM_100_PERCENT, STEEM_VOTING_MANA_REGENERATION_SECONDS );
account.downvote_manabar.regenerate_mana( params, gpo.time );
account.downvote_manabar.use_mana( ( -new_mana * gpo.downvote_pool_percent ) / STEEM_100_PERCENT );
}
}

} } } // steem::chain::util

FC_REFLECT( steem::chain::util::manabar,
Expand Down
141 changes: 121 additions & 20 deletions libraries/chain/steem_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ void initialize_account_object( account_object& acc, const account_name_type& na
acc.memo_key = key;
acc.created = props.time;
acc.voting_manabar.last_update_time = props.time.sec_since_epoch();
acc.downvote_manabar.last_update_time = props.time.sec_since_epoch();
acc.mined = mined;

if( hardfork < STEEM_HARDFORK_0_20__2539 )
Expand Down Expand Up @@ -1840,6 +1841,7 @@ void hf20_vote_evaluator( const vote_operation& o, database& _db )
{
const auto& comment = _db.get_comment( o.author, o.permlink );
const auto& voter = _db.get_account( o.voter );
const auto& dgpo = _db.get_dynamic_global_properties();

FC_ASSERT( voter.can_vote, "Voter has declined their voting rights." );

Expand Down Expand Up @@ -1891,8 +1893,7 @@ void hf20_vote_evaluator( const vote_operation& o, database& _db )

_db.modify( voter, [&]( account_object& a )
{
util::manabar_params params( util::get_effective_vesting_shares( a ), STEEM_VOTING_MANA_REGENERATION_SECONDS );
a.voting_manabar.regenerate_mana( params, now );
util::update_manabar( _db.get_dynamic_global_properties(), a, _db.has_hardfork( STEEM_HARDFORK_0_21__3336 ) );
});

if ( _db.has_hardfork( STEEM_HARDFORK_0_21__3004 ) )
Expand All @@ -1905,17 +1906,36 @@ void hf20_vote_evaluator( const vote_operation& o, database& _db )
}

int16_t abs_weight = abs( o.weight );
uint128_t used_mana = ( uint128_t( voter.voting_manabar.current_mana ) * abs_weight * 60 * 60 * 24 ) / STEEM_100_PERCENT;
uint128_t used_mana = 0;

const dynamic_global_property_object& dgpo = _db.get_dynamic_global_properties();
FC_TODO( "This hardfork check should not be needed. Remove after HF21 if that is the case." );
if( _db.has_hardfork( STEEM_HARDFORK_0_21__3336 ) && dgpo.downvote_pool_percent && o.weight < 0 )
{
used_mana = ( std::max( ( uint128_t( voter.downvote_manabar.current_mana * STEEM_100_PERCENT ) / dgpo.downvote_pool_percent ),
uint128_t( voter.voting_manabar.current_mana ) )
* abs_weight * 60 * 60 * 24 ) / STEEM_100_PERCENT;
}
else
{
used_mana = ( uint128_t( voter.voting_manabar.current_mana ) * abs_weight * 60 * 60 * 24 ) / STEEM_100_PERCENT;
}

int64_t max_vote_denom = dgpo.vote_power_reserve_rate * STEEM_VOTING_MANA_REGENERATION_SECONDS;
FC_ASSERT( max_vote_denom > 0 );

used_mana = ( used_mana + max_vote_denom - 1 ) / max_vote_denom;
FC_ASSERT( voter.voting_manabar.has_mana( used_mana.to_uint64() ), "Account does not have enough mana to vote." );
if( _db.has_hardfork( STEEM_HARDFORK_0_21__3336 ) && dgpo.downvote_pool_percent && o.weight < 0 )
{
FC_ASSERT( voter.voting_manabar.current_mana + voter.downvote_manabar.current_mana > used_mana.to_int64(),
"Account does not have enough mana to downvote. voting_mana: ${v} downvote_mana: ${d} required_mana: ${r}",
("v", voter.voting_manabar.current_mana)("d", voter.downvote_manabar.current_mana)("r", used_mana.to_int64()) );
}
else
{
FC_ASSERT( voter.voting_manabar.has_mana( used_mana.to_int64() ), "Account does not have enough mana to vote." );
}

int64_t abs_rshares = used_mana.to_uint64();
int64_t abs_rshares = used_mana.to_int64();

abs_rshares -= STEEM_VOTE_DUST_THRESHOLD;
abs_rshares = std::max( int64_t(0), abs_rshares );
Expand All @@ -1936,7 +1956,30 @@ void hf20_vote_evaluator( const vote_operation& o, database& _db )

_db.modify( voter, [&]( account_object& a )
{
a.voting_manabar.use_mana( used_mana.to_uint64() );
if( _db.has_hardfork( STEEM_HARDFORK_0_21__3336 ) && dgpo.downvote_pool_percent > 0 && o.weight < 0 )
{
if( used_mana.to_int64() > a.downvote_manabar.current_mana )
{
/* used mana is always less than downvote_mana + voting_mana because the amount used
* is a fraction of max( downvote_mana, voting_mana ). If more mana is consumed than
* there is downvote_mana, then it is because voting_mana is greater, and used_mana
* is strictly smaller than voting_mana. This is the same reason why a check is not
* required when using voting mana on its own as an upvote.
*/
auto remainder = used_mana.to_int64() - a.downvote_manabar.current_mana;
a.downvote_manabar.use_mana( a.downvote_manabar.current_mana );
a.voting_manabar.use_mana( remainder );
}
else
{
a.downvote_manabar.use_mana( used_mana.to_int64() );
}
}
else
{
a.voting_manabar.use_mana( used_mana.to_int64() );
}

a.last_vote_time = _db.head_block_time();
});

Expand Down Expand Up @@ -2046,7 +2089,30 @@ void hf20_vote_evaluator( const vote_operation& o, database& _db )

_db.modify( voter, [&]( account_object& a )
{
a.voting_manabar.use_mana( used_mana.to_uint64() );
if( _db.has_hardfork( STEEM_HARDFORK_0_21__3336 ) && dgpo.downvote_pool_percent > 0 && o.weight < 0 )
{
if( used_mana.to_int64() > a.downvote_manabar.current_mana )
{
/* used mana is always less than downvote_mana + voting_mana because the amount used
* is a fraction of max( downvote_mana, voting_mana ). If more mana is consumed than
* there is downvote_mana, then it is because voting_mana is greater, and used_mana
* is strictly smaller than voting_mana. This is the same reason why a check is not
* required when using voting mana on its own as an upvote.
*/
auto remainder = used_mana.to_int64() - a.downvote_manabar.current_mana;
a.downvote_manabar.use_mana( a.downvote_manabar.current_mana );
a.voting_manabar.use_mana( remainder );
}
else
{
a.downvote_manabar.use_mana( used_mana.to_int64() );
}
}
else
{
a.voting_manabar.use_mana( used_mana.to_int64() );
}

a.last_vote_time = _db.head_block_time();
});

Expand Down Expand Up @@ -2889,9 +2955,7 @@ void claim_reward_balance_evaluator::do_apply( const claim_reward_balance_operat
{
if( _db.has_hardfork( STEEM_HARDFORK_0_20__2539 ) )
{
util::manabar_params params( util::get_effective_vesting_shares( a ), STEEM_VOTING_MANA_REGENERATION_SECONDS );
a.voting_manabar.regenerate_mana( params, _db.head_block_time() );
a.voting_manabar.use_mana( -op.reward_vests.amount.value );
util::update_manabar( _db.get_dynamic_global_properties(), a, _db.has_hardfork( STEEM_HARDFORK_0_21__3336 ), op.reward_vests.amount.value );
}

a.vesting_shares += op.reward_vests;
Expand Down Expand Up @@ -2989,22 +3053,35 @@ void delegate_vesting_shares_evaluator::do_apply( const delegate_vesting_shares_
const auto& delegatee = _db.get_account( op.delegatee );
auto delegation = _db.find< vesting_delegation_object, by_delegation >( boost::make_tuple( op.delegator, op.delegatee ) );

const auto& gpo = _db.get_dynamic_global_properties();

asset available_shares;
asset available_downvote_shares;

if( _db.has_hardfork( STEEM_HARDFORK_0_20__2539 ) )
{
auto max_mana = util::get_effective_vesting_shares( delegator );

_db.modify( delegator, [&]( account_object& a )
{
util::manabar_params params( max_mana, STEEM_VOTING_MANA_REGENERATION_SECONDS );
a.voting_manabar.regenerate_mana( params, _db.head_block_time() );
util::update_manabar( gpo, a, _db.has_hardfork( STEEM_HARDFORK_0_21__3336 ) );
});

available_shares = asset( delegator.voting_manabar.current_mana, VESTS_SYMBOL );
if( gpo.downvote_pool_percent )
{
available_downvote_shares = asset(
( delegator.downvote_manabar.current_mana * STEEM_100_PERCENT ) / gpo.downvote_pool_percent
+ ( STEEM_100_PERCENT / gpo.downvote_pool_percent ) - 1, VESTS_SYMBOL );
}
else
{
available_downvote_shares = available_shares;
}

// Assume delegated VESTS are used first when consuming mana. You cannot delegate received vesting shares
available_shares.amount = std::min( available_shares.amount, max_mana - delegator.received_vesting_shares.amount );
available_downvote_shares.amount = std::min( available_downvote_shares.amount, max_mana - delegator.received_vesting_shares.amount );

if( delegator.next_vesting_withdrawal < fc::time_point_sec::maximum()
&& delegator.to_withdraw - delegator.withdrawn > delegator.vesting_withdraw_rate.amount )
Expand All @@ -3027,6 +3104,7 @@ void delegate_vesting_shares_evaluator::do_apply( const delegate_vesting_shares_
), VESTS_SYMBOL );

available_shares += weekly_withdraw - asset( delegator.to_withdraw - delegator.withdrawn, VESTS_SYMBOL );
available_downvote_shares += weekly_withdraw - asset( delegator.to_withdraw - delegator.withdrawn, VESTS_SYMBOL );
}
}
else
Expand All @@ -3035,7 +3113,6 @@ void delegate_vesting_shares_evaluator::do_apply( const delegate_vesting_shares_
}

const auto& wso = _db.get_witness_schedule_object();
const auto& gpo = _db.get_dynamic_global_properties();

// HF 20 increase fee meaning by 30x, reduce these thresholds to compensate.
auto min_delegation = _db.has_hardfork( STEEM_HARDFORK_0_20__1761 ) ?
Expand All @@ -3050,6 +3127,10 @@ void delegate_vesting_shares_evaluator::do_apply( const delegate_vesting_shares_
{
FC_ASSERT( available_shares >= op.vesting_shares, "Account ${acc} does not have enough mana to delegate. required: ${r} available: ${a}",
("acc", op.delegator)("r", op.vesting_shares)("a", available_shares) );
FC_TODO( "This hardfork check should not be needed. Remove after HF21 if that is the case." );
if( _db.has_hardfork( STEEM_HARDFORK_0_21__3336 ) )
FC_ASSERT( available_downvote_shares >= op.vesting_shares, "Account ${acc} does not have enough downvote mana to delegate. required: ${r} available: ${a}",
("acc", op.delegator)("r", op.vesting_shares)("a", available_downvote_shares) );
FC_ASSERT( op.vesting_shares >= min_delegation, "Account must delegate a minimum of ${v}", ("v", min_delegation) );

_db.create< vesting_delegation_object >( [&]( vesting_delegation_object& obj )
Expand All @@ -3067,16 +3148,19 @@ void delegate_vesting_shares_evaluator::do_apply( const delegate_vesting_shares_
if( _db.has_hardfork( STEEM_HARDFORK_0_20__2539 ) )
{
a.voting_manabar.use_mana( op.vesting_shares.amount.value );

if( _db.has_hardfork( STEEM_HARDFORK_0_21__3336 ) )
{
a.downvote_manabar.use_mana( op.vesting_shares.amount.value );
}
}
});

_db.modify( delegatee, [&]( account_object& a )
{
if( _db.has_hardfork( STEEM_HARDFORK_0_20__2539 ) )
{
util::manabar_params params( util::get_effective_vesting_shares( a ), STEEM_VOTING_MANA_REGENERATION_SECONDS );
a.voting_manabar.regenerate_mana( params, _db.head_block_time() );
a.voting_manabar.use_mana( -op.vesting_shares.amount.value );
util::update_manabar( gpo, a, _db.has_hardfork( STEEM_HARDFORK_0_21__3336 ), op.vesting_shares.amount.value );
}

a.received_vesting_shares += op.vesting_shares;
Expand All @@ -3090,6 +3174,10 @@ void delegate_vesting_shares_evaluator::do_apply( const delegate_vesting_shares_
FC_ASSERT( delta >= min_update, "Steem Power increase is not enough of a difference. min_update: ${min}", ("min", min_update) );
FC_ASSERT( available_shares >= delta, "Account ${acc} does not have enough mana to delegate. required: ${r} available: ${a}",
("acc", op.delegator)("r", delta)("a", available_shares) );
FC_TODO( "This hardfork check should not be needed. Remove after HF21 if that is the case." );
if( _db.has_hardfork( STEEM_HARDFORK_0_21__3336 ) )
FC_ASSERT( available_shares >= delta, "Account ${acc} does not have enough downvote mana to delegate. required: ${r} available: ${a}",
("acc", op.delegator)("r", delta)("a", available_downvote_shares) );

_db.modify( delegator, [&]( account_object& a )
{
Expand All @@ -3098,16 +3186,19 @@ void delegate_vesting_shares_evaluator::do_apply( const delegate_vesting_shares_
if( _db.has_hardfork( STEEM_HARDFORK_0_20__2539 ) )
{
a.voting_manabar.use_mana( delta.amount.value );

if( _db.has_hardfork( STEEM_HARDFORK_0_21__3336 ) )
{
a.downvote_manabar.use_mana( delta.amount.value );
}
}
});

_db.modify( delegatee, [&]( account_object& a )
{
if( _db.has_hardfork( STEEM_HARDFORK_0_20__2539 ) )
{
util::manabar_params params( util::get_effective_vesting_shares( a ), STEEM_VOTING_MANA_REGENERATION_SECONDS );
a.voting_manabar.regenerate_mana( params, _db.head_block_time() );
a.voting_manabar.use_mana( -delta.amount.value );
util::update_manabar( gpo, a, _db.has_hardfork( STEEM_HARDFORK_0_21__3336 ), delta.amount.value );
}

a.received_vesting_shares += delta;
Expand Down Expand Up @@ -3152,6 +3243,16 @@ void delegate_vesting_shares_evaluator::do_apply( const delegate_vesting_shares_
{
a.voting_manabar.current_mana = 0;
}

if( _db.has_hardfork( STEEM_HARDFORK_0_21__3336 ) )
{
a.downvote_manabar.use_mana( op.vesting_shares.amount.value );

if( a.downvote_manabar.current_mana < 0 )
{
a.downvote_manabar.current_mana = 0;
}
}
}
});

Expand Down
1 change: 1 addition & 0 deletions libraries/protocol/get_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ fc::variant_object get_config()
result["STEEM_CUSTOM_OP_DATA_MAX_LENGTH"] = STEEM_CUSTOM_OP_DATA_MAX_LENGTH;
result["STEEM_CUSTOM_OP_ID_MAX_LENGTH"] = STEEM_CUSTOM_OP_ID_MAX_LENGTH;
result["STEEM_DEFAULT_SBD_INTEREST_RATE"] = STEEM_DEFAULT_SBD_INTEREST_RATE;
result["STEEM_DOWNVOTE_POOL_PERCENT_HF21"] = STEEM_DOWNVOTE_POOL_PERCENT_HF21;
result["STEEM_EQUIHASH_K"] = STEEM_EQUIHASH_K;
result["STEEM_EQUIHASH_N"] = STEEM_EQUIHASH_N;
result["STEEM_FEED_HISTORY_WINDOW"] = STEEM_FEED_HISTORY_WINDOW;
Expand Down
Loading

0 comments on commit 4c1224e

Please sign in to comment.