Skip to content

Commit

Permalink
Implement smt_set_runtime_parameters_operation steemit#2728
Browse files Browse the repository at this point in the history
  • Loading branch information
mvandeberg committed Nov 16, 2018
1 parent 19b4765 commit 870f51c
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,38 +71,40 @@ class smt_token_object : public object< smt_token_object_type, smt_token_object
}

// id_type is actually oid<smt_token_object>
id_type id;
id_type id;

/**The object represents both liquid and vesting variant of SMT
* To get vesting symbol, call liquid_symbol.get_paired_symbol()
*/
asset_symbol_type liquid_symbol;
account_name_type control_account;
smt_phase phase = smt_phase::account_elevated;
asset_symbol_type liquid_symbol;
account_name_type control_account;
smt_phase phase = smt_phase::account_elevated;

share_type current_supply = 0;
share_type total_vesting_fund_smt = 0;
share_type total_vesting_shares = 0;
share_type pending_rewarded_vesting_shares = 0;
share_type pending_rewarded_vesting_smt = 0;
share_type current_supply = 0;
share_type total_vesting_fund_smt = 0;
share_type total_vesting_shares = 0;
share_type pending_rewarded_vesting_shares = 0;
share_type pending_rewarded_vesting_smt = 0;

smt_market_maker_state market_maker;

/// set_setup_parameters
bool allow_voting = true;
bool allow_voting = true;

/// set_runtime_parameters
uint32_t cashout_window_seconds = 0;
uint32_t reverse_auction_window_seconds = 0;
uint32_t cashout_window_seconds = 0;
uint32_t reverse_auction_window_seconds = 0;

uint32_t vote_regeneration_period_seconds = 0;
uint32_t votes_per_regeneration_period = 0;

uint32_t vote_regeneration_period_seconds = 0;
uint32_t votes_per_regeneration_period = 0;
uint128_t content_constant = 0;
uint16_t percent_curation_rewards = 0;
uint16_t percent_content_rewards = 0;
protocol::curve_id author_reward_curve;
protocol::curve_id curation_reward_curve;

uint128_t content_constant = 0;
uint16_t percent_curation_rewards = 0;
uint16_t percent_content_rewards = 0;
protocol::curve_id author_reward_curve;
protocol::curve_id curation_reward_curve;
bool allow_downvotes = true;

///parameters for 'smt_setup_operation'
int64_t max_supply = 0;
Expand Down Expand Up @@ -267,6 +269,7 @@ FC_REFLECT( steem::chain::smt_token_object,
(total_vesting_shares)
(pending_rewarded_vesting_shares)
(pending_rewarded_vesting_smt)
(allow_downvotes)
(market_maker)
(allow_voting)
(cashout_window_seconds)
Expand Down
60 changes: 29 additions & 31 deletions libraries/chain/smt_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ inline const smt_token_object& get_controlled_smt( const database& db, const acc
// Check against unotherized account trying to access (and alter) SMT. Unotherized means "other than the one that created the SMT".
FC_ASSERT( smt->control_account == control_account, "The account ${account} does NOT control the SMT ${smt}",
("account", control_account)("smt", smt_symbol.to_nai()) );

return *smt;
}

}

namespace {
Expand Down Expand Up @@ -240,7 +240,7 @@ void smt_set_setup_parameters_evaluator::do_apply( const smt_set_setup_parameter
FC_ASSERT( _db.has_hardfork( STEEM_SMT_HARDFORK ), "SMT functionality not enabled until hardfork ${hf}", ("hf", STEEM_SMT_HARDFORK) );

const smt_token_object& smt_token = common_pre_setup_evaluation( _db, o.symbol, o.control_account );

_db.modify( smt_token, [&]( smt_token_object& token )
{
smt_setup_parameters_visitor visitor( token );
Expand All @@ -252,54 +252,52 @@ void smt_set_setup_parameters_evaluator::do_apply( const smt_set_setup_parameter

struct smt_set_runtime_parameters_evaluator_visitor
{
const smt_token_object& _token;
database& _db;
smt_token_object& _token;

smt_set_runtime_parameters_evaluator_visitor( const smt_token_object& token, database& db ): _token( token ), _db( db ){}
smt_set_runtime_parameters_evaluator_visitor( smt_token_object& token ) : _token( token ) {}

typedef void result_type;

void operator()( const smt_param_windows_v1& param_windows ) const
void operator()( const smt_param_windows_v1& param_windows )const
{
_db.modify( _token, [&]( smt_token_object& token )
{
token.cashout_window_seconds = param_windows.cashout_window_seconds;
token.reverse_auction_window_seconds = param_windows.reverse_auction_window_seconds;
});
_token.cashout_window_seconds = param_windows.cashout_window_seconds;
_token.reverse_auction_window_seconds = param_windows.reverse_auction_window_seconds;
}

void operator()( const smt_param_vote_regeneration_period_seconds_v1& vote_regeneration ) const
void operator()( const smt_param_vote_regeneration_period_seconds_v1& vote_regeneration )const
{
_db.modify( _token, [&]( smt_token_object& token )
{
token.vote_regeneration_period_seconds = vote_regeneration.vote_regeneration_period_seconds;
token.votes_per_regeneration_period = vote_regeneration.votes_per_regeneration_period;
});
_token.vote_regeneration_period_seconds = vote_regeneration.vote_regeneration_period_seconds;
_token.votes_per_regeneration_period = vote_regeneration.votes_per_regeneration_period;
}

void operator()( const smt_param_rewards_v1& param_rewards ) const
void operator()( const smt_param_rewards_v1& param_rewards )const
{
_db.modify( _token, [&]( smt_token_object& token )
{
token.content_constant = param_rewards.content_constant;
token.percent_curation_rewards = param_rewards.percent_curation_rewards;
token.percent_content_rewards = param_rewards.percent_content_rewards;
token.author_reward_curve = param_rewards.author_reward_curve;
token.curation_reward_curve = param_rewards.curation_reward_curve;
});
_token.content_constant = param_rewards.content_constant;
_token.percent_curation_rewards = param_rewards.percent_curation_rewards;
_token.percent_content_rewards = param_rewards.percent_content_rewards;
_token.author_reward_curve = param_rewards.author_reward_curve;
_token.curation_reward_curve = param_rewards.curation_reward_curve;
}

void operator()( const smt_param_allow_downvotes& param_allow_downvotes )const
{
_token.allow_downvotes = param_allow_downvotes.value;
}
};

void smt_set_runtime_parameters_evaluator::do_apply( const smt_set_runtime_parameters_operation& o )
{
FC_ASSERT( _db.has_hardfork( STEEM_SMT_HARDFORK ), "SMT functionality not enabled until hardfork ${hf}", ("hf", STEEM_SMT_HARDFORK) );

const smt_token_object& _token = common_pre_setup_evaluation(_db, o.symbol, o.control_account);
const smt_token_object& token = common_pre_setup_evaluation(_db, o.symbol, o.control_account);

smt_set_runtime_parameters_evaluator_visitor visitor( _token, _db );
_db.modify( token, [&]( smt_token_object& t )
{
smt_set_runtime_parameters_evaluator_visitor visitor( t );

for( auto& param: o.runtime_parameters )
param.visit( visitor );
for( auto& param: o.runtime_parameters )
param.visit( visitor );
});
}

} }
Expand Down
2 changes: 2 additions & 0 deletions libraries/protocol/get_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ fc::variant_object get_config()
result["SMT_MAX_VOTABLE_ASSETS"] = SMT_MAX_VOTABLE_ASSETS;
result["SMT_EMISSION_MIN_INTERVAL_SECONDS"] = SMT_EMISSION_MIN_INTERVAL_SECONDS;
result["SMT_EMIT_INDEFINITELY"] = SMT_EMIT_INDEFINITELY;
result["SMT_MAX_NOMINAL_VOTES_PER_DAY"] = SMT_MAX_NOMINAL_VOTES_PER_DAY;
result["SMT_MAX_VOTES_PER_REGENERATION"] = SMT_MAX_VOTES_PER_REGENERATION;
#else
result[ "STEEM_ENABLE_SMT" ] = false;
#endif
Expand Down
3 changes: 3 additions & 0 deletions libraries/protocol/include/steem/protocol/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -323,5 +323,8 @@
#define SMT_UPVOTE_LOCKOUT (60*60*12) /// 12 hours
#define SMT_EMISSION_MIN_INTERVAL_SECONDS (60*60*6) /// 6 hours
#define SMT_EMIT_INDEFINITELY (std::numeric_limits<uint32_t>::max())
#define SMT_MAX_NOMINAL_VOTES_PER_DAY (1000)
#define SMT_MAX_VOTES_PER_REGENERATION ((SMT_MAX_NOMINAL_VOTES_PER_DAY * SMT_VESTING_WITHDRAW_INTERVAL_SECONDS) / 86400)

#endif /// STEEM_ENABLE_SMT

18 changes: 14 additions & 4 deletions libraries/protocol/include/steem/protocol/smt_operations.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,14 +237,20 @@ struct smt_param_rewards_v1
uint128_t content_constant = 0;
uint16_t percent_curation_rewards = 0;
uint16_t percent_content_rewards = 0;
protocol::curve_id author_reward_curve;
protocol::curve_id curation_reward_curve;
protocol::curve_id author_reward_curve;
protocol::curve_id curation_reward_curve;
};

struct smt_param_allow_downvotes
{
bool value = true;
};

typedef static_variant<
smt_param_windows_v1,
smt_param_vote_regeneration_period_seconds_v1,
smt_param_rewards_v1
smt_param_rewards_v1,
smt_param_allow_downvotes
> smt_runtime_parameter;

struct smt_set_setup_parameters_operation : public smt_base_operation
Expand Down Expand Up @@ -394,6 +400,11 @@ FC_REFLECT(
(curation_reward_curve)
)

FC_REFLECT(
steem::protocol::smt_param_allow_downvotes,
(value)
)

FC_REFLECT_TYPENAME(
steem::protocol::smt_runtime_parameter
)
Expand All @@ -411,5 +422,4 @@ FC_REFLECT_DERIVED(
(runtime_parameters)
(extensions)
)

#endif
88 changes: 73 additions & 15 deletions libraries/protocol/smt_operations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ struct validate_visitor
void smt_setup_emissions_operation::validate()const
{
smt_base_operation::validate();

FC_ASSERT( schedule_time > STEEM_GENESIS_TIME );
FC_ASSERT( emissions_unit.token_unit.empty() == false, "Emissions token unit cannot be empty" );

Expand All @@ -229,7 +229,7 @@ void smt_setup_emissions_operation::validate()const
"Interval seconds must be greater than or equal to ${seconds}", ("seconds", SMT_EMISSION_MIN_INTERVAL_SECONDS) );

FC_ASSERT( interval_count > 0, "Interval count must be greater than 0" );

FC_ASSERT( lep_time <= rep_time, "Left endpoint time must be less than or equal to right endpoint time" );

// If time modulation is enabled
Expand Down Expand Up @@ -272,38 +272,96 @@ void smt_setup_operation::validate()const
FC_ASSERT( generation_end_time > generation_begin_time );
FC_ASSERT( announced_launch_time >= generation_end_time );
FC_ASSERT( launch_expiration_time >= announced_launch_time );
}
}

struct smt_set_runtime_parameters_operation_visitor
{
smt_set_runtime_parameters_operation_visitor(){}

typedef void result_type;

void operator()( const smt_param_windows_v1& param_windows ) const
void operator()( const smt_param_windows_v1& param_windows )const
{
// 0 <= reverse_auction_window_seconds + SMT_UPVOTE_LOCKOUT < cashout_window_seconds < SMT_VESTING_WITHDRAW_INTERVAL_SECONDS
uint64_t sum = ( param_windows.reverse_auction_window_seconds + SMT_UPVOTE_LOCKOUT );

FC_ASSERT( param_windows.cashout_window_seconds > ( sum ),
"Cashout window must be greater than 'reverse auction window + upvote lockout' interval. This interval is ${sum} minutes long.",
( "sum", sum/60 ) );
FC_ASSERT( sum >= 0,
"'reverse_auction_window + SMT_UPVOTE_LOCKOUT' interval cannot be negative. Was ${sum} seconds",
("sum", sum) );

FC_ASSERT( sum < param_windows.cashout_window_seconds,
"'reverse auction window + upvote lockout' interval must be less than cashout window (${c}). Was ${sum} seconds.",
("c", param_windows.cashout_window_seconds)
( "sum", sum ) );

FC_ASSERT( param_windows.cashout_window_seconds < SMT_VESTING_WITHDRAW_INTERVAL_SECONDS,
"Cashout window second must be less than 'vesting withdraw' interval. This interval is ${val} minutes long.",
("val", SMT_VESTING_WITHDRAW_INTERVAL_SECONDS/60 ) );
"Cashout window second must be less than 'vesting withdraw' interval (${v}). Was ${val} seconds.",
("v", SMT_VESTING_WITHDRAW_INTERVAL_SECONDS)
("val", param_windows.cashout_window_seconds) );
}

void operator()( const smt_param_vote_regeneration_period_seconds_v1& vote_regeneration ) const
void operator()( const smt_param_vote_regeneration_period_seconds_v1& vote_regeneration )const
{
// 0 < vote_regeneration_seconds < SMT_VESTING_WITHDRAW_INTERVAL_SECONDS
FC_ASSERT( ( vote_regeneration.vote_regeneration_period_seconds > 0 ) &&
( vote_regeneration.vote_regeneration_period_seconds < SMT_VESTING_WITHDRAW_INTERVAL_SECONDS ),
"Vote regeneration period must be greater than 0 and less than 'vesting withdraw' interval. This interval is ${val} minutes long.",
("val", SMT_VESTING_WITHDRAW_INTERVAL_SECONDS/60 ) );
( vote_regeneration.vote_regeneration_period_seconds < SMT_VESTING_WITHDRAW_INTERVAL_SECONDS ),
"Vote regeneration period must be greater than 0 and less than 'vesting withdraw' (${v}) interval. Was ${val} seconds.",
("v", SMT_VESTING_WITHDRAW_INTERVAL_SECONDS )
("val", vote_regeneration.vote_regeneration_period_seconds) );

FC_ASSERT( ( vote_regeneration.votes_per_regeneration_period <= SMT_MAX_VOTES_PER_REGENERATION ),
"Votes per regeneration period exceeds maximum (${max}). Was ${v}",
("max", SMT_MAX_VOTES_PER_REGENERATION)
("v", vote_regeneration.vote_regeneration_period_seconds) );

// With previous assertion, this value will not overflow a 32 bit integer
uint32_t nominal_votes_per_day = ( vote_regeneration.votes_per_regeneration_period * 86400 )
/ vote_regeneration.vote_regeneration_period_seconds;

FC_ASSERT( nominal_votes_per_day <= SMT_MAX_NOMINAL_VOTES_PER_DAY,
"Nominal votes per day exceeds maximum (${max}). Was ${v}",
("max", SMT_MAX_NOMINAL_VOTES_PER_DAY)
("v", nominal_votes_per_day) );
}

void operator()( const smt_param_rewards_v1& param_rewards )const
{

FC_ASSERT( param_rewards.percent_curation_rewards <= STEEM_100_PERCENT,
"Percent Curation Rewards must not exceed 10000. Was ${n}",
("n", param_rewards.percent_curation_rewards) );

FC_ASSERT( param_rewards.percent_content_rewards <= STEEM_100_PERCENT,
"Percent Conntent Rewards must not exceed 10000. Was ${n}",
("n", param_rewards.percent_content_rewards) );

FC_ASSERT( param_rewards.percent_curation_rewards + param_rewards.percent_content_rewards == STEEM_100_PERCENT,
"Curation and Content Rewards must sum to 10000. Was ${n}",
("n", param_rewards.percent_curation_rewards + param_rewards.percent_content_rewards) );

switch( param_rewards.author_reward_curve )
{
case linear:
case quadratic:
break;
default:
FC_ASSERT( false, "Author Reward Curve must be linear or quadratic" );
}

switch( param_rewards.curation_reward_curve )
{
case linear:
case square_root:
case bounded:
break;
default:
FC_ASSERT( false, "Curation Reward Curve must be linear, square-root, or bounded." );
}
}

void operator()( const smt_param_rewards_v1& param_rewards ) const
void operator()( const smt_param_allow_downvotes& )const
{
//Nothing to do.
//Nothing to do
}
};

Expand Down

0 comments on commit 870f51c

Please sign in to comment.