From 533534b95ea76b0403703b1a365bc4c145dbfbcd Mon Sep 17 00:00:00 2001 From: maslenitsa93 Date: Tue, 4 Jun 2019 12:47:38 +0300 Subject: [PATCH] Allow curator promote author with rate of his reward #1014 --- libraries/chain/database.cpp | 26 +++++++++---- libraries/chain/hardfork.d/0_21.hf | 3 +- .../include/golos/chain/comment_object.hpp | 2 + .../chain/include/golos/chain/database.hpp | 2 +- .../include/golos/chain/steem_evaluator.hpp | 1 + libraries/chain/steem_evaluator.cpp | 35 ++++++++++++++++++ .../include/golos/protocol/config.hpp | 6 +++ .../include/golos/protocol/operations.hpp | 1 + .../golos/protocol/steem_operations.hpp | 37 +++++++++++++++++++ libraries/protocol/steem_operations.cpp | 26 +++++++++++++ plugins/account_history/plugin.cpp | 4 ++ .../plugins/mongo_db/mongo_db_operations.hpp | 1 + .../golos/plugins/mongo_db/mongo_db_state.hpp | 1 + plugins/mongo_db/mongo_db_operations.cpp | 6 +++ plugins/mongo_db/mongo_db_state.cpp | 4 ++ 15 files changed, 145 insertions(+), 10 deletions(-) diff --git a/libraries/chain/database.cpp b/libraries/chain/database.cpp index 6031af2c76..b345331a59 100644 --- a/libraries/chain/database.cpp +++ b/libraries/chain/database.cpp @@ -2331,21 +2331,31 @@ namespace golos { namespace chain { return delegators_reward; } - void database::pay_curator(const comment_vote_object& cvo, const uint64_t& claim, const account_name_type& author, const std::string& permlink) { + uint64_t database::pay_curator(const comment_vote_object& cvo, uint64_t claim, const account_name_type& author, const std::string& permlink) { const auto &voter = get(cvo.voter); - auto voter_claim = claim; + + uint64_t to_author = 0; + if (has_hardfork(STEEMIT_HARDFORK_0_21__1014)) { + to_author = (uint128_t(claim) * cvo.author_promote_rate / STEEMIT_100_PERCENT).to_uint64(); + claim -= to_author; + if (claim == 0) { + return to_author; + } + } if (has_hardfork(STEEMIT_HARDFORK_0_19__756)) { - voter_claim -= pay_delegators(voter, cvo, claim); + claim -= pay_delegators(voter, cvo, claim); } - auto voter_reward = create_vesting(voter, asset(voter_claim, STEEM_SYMBOL)); + auto voter_reward = create_vesting(voter, asset(claim, STEEM_SYMBOL)); push_virtual_operation(curation_reward_operation(voter.name, voter_reward, author, permlink)); modify(voter, [&](account_object &a) { - a.curation_rewards += voter_claim; + a.curation_rewards += claim; }); + + return to_author; } /** * This method will iterate through all comment_vote_objects and give them @@ -2384,7 +2394,7 @@ namespace golos { namespace chain { if (claim > 0) { // min_amt is non-zero satoshis unclaimed_rewards -= claim; - pay_curator(*itr->vote, claim, c.comment.author, to_string(c.comment.permlink)); + unclaimed_rewards += pay_curator(*itr->vote, claim, c.comment.author, to_string(c.comment.permlink)); } else { break; } @@ -2393,8 +2403,7 @@ namespace golos { namespace chain { // pay needed claim + rest unclaimed tokens (close to zero value) to curator with greates weight // BTW: it has to be unclaimed_rewards.value not heaviest_vote_after_auw_weight + unclaimed_rewards.value, coz // unclaimed_rewards already contains this. - pay_curator(*heaviest_itr->vote, unclaimed_rewards.value, c.comment.author, to_string(c.comment.permlink)); - unclaimed_rewards = 0; + unclaimed_rewards = pay_curator(*heaviest_itr->vote, unclaimed_rewards.value, c.comment.author, to_string(c.comment.permlink)); } } if (!c.comment.allow_curation_rewards) { @@ -3090,6 +3099,7 @@ namespace golos { namespace chain { _my->_evaluator_registry.register_evaluator(); _my->_evaluator_registry.register_evaluator(); _my->_evaluator_registry.register_evaluator(); + _my->_evaluator_registry.register_evaluator(); _my->_evaluator_registry.register_evaluator(); _my->_evaluator_registry.register_evaluator(); _my->_evaluator_registry.register_evaluator(); diff --git a/libraries/chain/hardfork.d/0_21.hf b/libraries/chain/hardfork.d/0_21.hf index 27c1d8053e..c5cf4e1e3f 100644 --- a/libraries/chain/hardfork.d/0_21.hf +++ b/libraries/chain/hardfork.d/0_21.hf @@ -1,11 +1,12 @@ #ifndef STEEMIT_HARDFORK_0_21 #define STEEMIT_HARDFORK_0_21 21 #define STEEMIT_HARDFORK_0_21__1013 (STEEMIT_HARDFORK_0_21) // Workers +#define STEEMIT_HARDFORK_0_21__1107 (STEEMIT_HARDFORK_0_21) // Worker fund operation #define STEEMIT_HARDFORK_0_21__1008 (STEEMIT_HARDFORK_0_21) // Remove limit on max delegate interest witness prop #define STEEMIT_HARDFORK_0_21__1009 (STEEMIT_HARDFORK_0_21) // Remove limit on min curation percent witness prop #define STEEMIT_HARDFORK_0_21__1010 (STEEMIT_HARDFORK_0_21) // Fix post bandwidth #define STEEMIT_HARDFORK_0_21__1045 (STEEMIT_HARDFORK_0_21) // Two payout strategies for vesting delegations with interest -#define STEEMIT_HARDFORK_0_21__1107 (STEEMIT_HARDFORK_0_21) // Worker fund operation +#define STEEMIT_HARDFORK_0_21__1014 (STEEMIT_HARDFORK_0_21) // Vote author promote rate #ifdef STEEMIT_BUILD_TESTNET #define STEEMIT_HARDFORK_0_21_TIME 1547787600 // 18 jan 2019 12:00:00 MSK diff --git a/libraries/chain/include/golos/chain/comment_object.hpp b/libraries/chain/include/golos/chain/comment_object.hpp index c7b0cbb856..9a6b72df4f 100644 --- a/libraries/chain/include/golos/chain/comment_object.hpp +++ b/libraries/chain/include/golos/chain/comment_object.hpp @@ -147,6 +147,8 @@ namespace golos { int8_t num_changes = 0; ///< Count of vote changes (while consensus). If = -1 then related post is archived & vote no more needed for consensus bip::vector> delegator_vote_interest_rates; + + uint16_t author_promote_rate = GOLOS_MIN_VOTE_AUTHOR_PROMOTE_RATE; }; struct by_comment_voter; diff --git a/libraries/chain/include/golos/chain/database.hpp b/libraries/chain/include/golos/chain/database.hpp index 749d3e6a8b..e71da65dd7 100644 --- a/libraries/chain/include/golos/chain/database.hpp +++ b/libraries/chain/include/golos/chain/database.hpp @@ -632,7 +632,7 @@ namespace golos { namespace chain { bool _resize(uint32_t block_num); - void pay_curator(const comment_vote_object& cvo, const uint64_t& claim, const account_name_type& author, const std::string& permlink); + uint64_t pay_curator(const comment_vote_object& cvo, uint64_t claim, const account_name_type& author, const std::string& permlink); void adjust_sbd_balance(const account_object &a, const asset &delta); diff --git a/libraries/chain/include/golos/chain/steem_evaluator.hpp b/libraries/chain/include/golos/chain/steem_evaluator.hpp index 34aba77ff0..db59207db3 100644 --- a/libraries/chain/include/golos/chain/steem_evaluator.hpp +++ b/libraries/chain/include/golos/chain/steem_evaluator.hpp @@ -55,6 +55,7 @@ namespace golos { namespace chain { DEFINE_EVALUATOR(break_free_referral) DEFINE_EVALUATOR(delegate_vesting_shares_with_interest) DEFINE_EVALUATOR(reject_vesting_shares_delegation) + DEFINE_EVALUATOR(vote_options) class proposal_create_evaluator: public evaluator_impl { public: diff --git a/libraries/chain/steem_evaluator.cpp b/libraries/chain/steem_evaluator.cpp index 0e0c7ebbc9..44562580ff 100644 --- a/libraries/chain/steem_evaluator.cpp +++ b/libraries/chain/steem_evaluator.cpp @@ -1786,6 +1786,41 @@ namespace golos { namespace chain { } FC_CAPTURE_AND_RETHROW((o)) } + struct vote_options_extension_visitor { + vote_options_extension_visitor(const comment_vote_object& vote, database& db) + : _vote(vote), _db(db) { + } + + const comment_vote_object& _vote; + database& _db; + + using result_type = void; + + void operator()(const vote_author_promote_rate& vapr) const { + _db.modify(_vote, [&](comment_vote_object& c) { + c.author_promote_rate = vapr.rate; + }); + } + }; + + void vote_options_evaluator::do_apply(const vote_options_operation& o) { + ASSERT_REQ_HF(STEEMIT_HARDFORK_0_21__1014, "vote_options_operation"); + + const auto& comment = _db.get_comment(o.author, o.permlink); + const auto& voter = _db.get_account(o.voter); + + const auto& vote_idx = _db.get_index(); + const auto vote_itr = vote_idx.find(std::make_tuple(comment.id, voter.id)); + + if (vote_itr == vote_idx.end()) { + GOLOS_THROW_MISSING_OBJECT("comment_vote_object", fc::mutable_variant_object()("voter",o.voter)("author",o.author)("permlink",o.permlink)); + } + + for (auto& e : o.extensions) { + e.visit(vote_options_extension_visitor(*vote_itr, _db)); + } + } + void custom_evaluator::do_apply(const custom_operation &o) { } diff --git a/libraries/protocol/include/golos/protocol/config.hpp b/libraries/protocol/include/golos/protocol/config.hpp index 395321b673..e946a8556d 100644 --- a/libraries/protocol/include/golos/protocol/config.hpp +++ b/libraries/protocol/include/golos/protocol/config.hpp @@ -167,6 +167,9 @@ #define STEEMIT_DEF_CURATION_PERCENT (25*STEEMIT_1_PERCENT) // 25% #define STEEMIT_MAX_CURATION_PERCENT STEEMIT_100_PERCENT +#define GOLOS_MIN_VOTE_AUTHOR_PROMOTE_RATE (0*STEEMIT_1_PERCENT) +#define GOLOS_MAX_VOTE_AUTHOR_PROMOTE_RATE (100*STEEMIT_1_PERCENT) + #define STEEMIT_ACTIVE_CHALLENGE_FEE asset(2000, STEEM_SYMBOL) #define STEEMIT_OWNER_CHALLENGE_FEE asset(30000, STEEM_SYMBOL) #define STEEMIT_ACTIVE_CHALLENGE_COOLDOWN fc::days(1) @@ -410,6 +413,9 @@ #define STEEMIT_DEF_CURATION_PERCENT (25*STEEMIT_1_PERCENT) // 25% #define STEEMIT_MAX_CURATION_PERCENT STEEMIT_100_PERCENT +#define GOLOS_MIN_VOTE_AUTHOR_PROMOTE_RATE (0*STEEMIT_1_PERCENT) +#define GOLOS_MAX_VOTE_AUTHOR_PROMOTE_RATE (100*STEEMIT_1_PERCENT) + #define STEEMIT_ACTIVE_CHALLENGE_FEE asset(2000, STEEM_SYMBOL) #define STEEMIT_OWNER_CHALLENGE_FEE asset(30000, STEEM_SYMBOL) #define STEEMIT_ACTIVE_CHALLENGE_COOLDOWN fc::days(1) diff --git a/libraries/protocol/include/golos/protocol/operations.hpp b/libraries/protocol/include/golos/protocol/operations.hpp index 3771b0b6cb..f0a47e741b 100644 --- a/libraries/protocol/include/golos/protocol/operations.hpp +++ b/libraries/protocol/include/golos/protocol/operations.hpp @@ -70,6 +70,7 @@ namespace golos { namespace protocol { break_free_referral_operation, delegate_vesting_shares_with_interest_operation, reject_vesting_shares_delegation_operation, + vote_options_operation, worker_proposal_operation, worker_proposal_delete_operation, worker_techspec_operation, diff --git a/libraries/protocol/include/golos/protocol/steem_operations.hpp b/libraries/protocol/include/golos/protocol/steem_operations.hpp index 20cef98702..e9151663c5 100644 --- a/libraries/protocol/include/golos/protocol/steem_operations.hpp +++ b/libraries/protocol/include/golos/protocol/steem_operations.hpp @@ -265,6 +265,38 @@ namespace golos { namespace protocol { } }; + struct vote_author_promote_rate { + vote_author_promote_rate() { + } + + vote_author_promote_rate(uint16_t r) + : rate(r) { + } + + uint16_t rate = GOLOS_MIN_VOTE_AUTHOR_PROMOTE_RATE; + + void validate() const; + }; + + using vote_options_extension = static_variant < + vote_author_promote_rate + >; + + using vote_options_extensions_type = flat_set; + + struct vote_options_operation : public base_operation { + account_name_type voter; + account_name_type author; + string permlink; + vote_options_extensions_type extensions; + + void validate() const; + + void get_required_posting_authorities(flat_set &a) const { + a.insert(voter); + } + }; + /** * @ingroup operations @@ -1476,6 +1508,11 @@ FC_REFLECT((golos::protocol::account_witness_vote_operation), (account)(witness) FC_REFLECT((golos::protocol::account_witness_proxy_operation), (account)(proxy)) FC_REFLECT((golos::protocol::comment_operation), (parent_author)(parent_permlink)(author)(permlink)(title)(body)(json_metadata)) FC_REFLECT((golos::protocol::vote_operation), (voter)(author)(permlink)(weight)) + +FC_REFLECT((golos::protocol::vote_author_promote_rate), (rate)); +FC_REFLECT_TYPENAME((golos::protocol::vote_options_extension)); +FC_REFLECT((golos::protocol::vote_options_operation), (voter)(author)(permlink)(extensions)) + FC_REFLECT((golos::protocol::custom_operation), (required_auths)(id)(data)) FC_REFLECT((golos::protocol::custom_json_operation), (required_auths)(required_posting_auths)(id)(json)) FC_REFLECT((golos::protocol::custom_binary_operation), (required_owner_auths)(required_active_auths)(required_posting_auths)(required_auths)(id)(data)) diff --git a/libraries/protocol/steem_operations.cpp b/libraries/protocol/steem_operations.cpp index a9b66ed265..ba7b59b462 100644 --- a/libraries/protocol/steem_operations.cpp +++ b/libraries/protocol/steem_operations.cpp @@ -212,6 +212,32 @@ namespace golos { namespace protocol { GOLOS_CHECK_PARAM(permlink, validate_permlink(permlink)); } + struct vote_options_extension_validate_visitor { + vote_options_extension_validate_visitor() { + } + + using result_type = void; + + void operator()(const vote_author_promote_rate& vapr) const { + vapr.validate(); + } + }; + + void vote_author_promote_rate::validate() const { + GOLOS_CHECK_PARAM(rate, { + GOLOS_CHECK_VALUE_LEGE(rate, GOLOS_MIN_VOTE_AUTHOR_PROMOTE_RATE, GOLOS_MAX_VOTE_AUTHOR_PROMOTE_RATE); + }); + } + + void vote_options_operation::validate() const { + GOLOS_CHECK_PARAM(voter, validate_account_name(voter)); + GOLOS_CHECK_PARAM(author, validate_account_name(author)); + GOLOS_CHECK_PARAM(permlink, validate_permlink(permlink)); + for (auto& e : extensions) { + e.visit(vote_options_extension_validate_visitor()); + } + } + void transfer_operation::validate() const { try { GOLOS_CHECK_PARAM(from, validate_account_name(from)); diff --git a/plugins/account_history/plugin.cpp b/plugins/account_history/plugin.cpp index 7819fa7e33..9be234d019 100644 --- a/plugins/account_history/plugin.cpp +++ b/plugins/account_history/plugin.cpp @@ -328,6 +328,10 @@ if (options.count(name)) { \ insert_pair(op.voter, op.author); } + void operator()(const vote_options_operation& op) { + insert_pair(op.voter, op.author); + } + void operator()(const author_reward_operation& op) { insert_receiver(op.author); } diff --git a/plugins/mongo_db/include/golos/plugins/mongo_db/mongo_db_operations.hpp b/plugins/mongo_db/include/golos/plugins/mongo_db/mongo_db_operations.hpp index b729a4bbfa..08878b167a 100644 --- a/plugins/mongo_db/include/golos/plugins/mongo_db/mongo_db_operations.hpp +++ b/plugins/mongo_db/include/golos/plugins/mongo_db/mongo_db_operations.hpp @@ -17,6 +17,7 @@ namespace mongo_db { operation_writer(); result_type operator()(const vote_operation& op); + result_type operator()(const vote_options_operation& op); result_type operator()(const comment_operation& op); result_type operator()(const transfer_operation& op); result_type operator()(const transfer_to_vesting_operation& op); diff --git a/plugins/mongo_db/include/golos/plugins/mongo_db/mongo_db_state.hpp b/plugins/mongo_db/include/golos/plugins/mongo_db/mongo_db_state.hpp index d57171fbb9..2c1fd81377 100644 --- a/plugins/mongo_db/include/golos/plugins/mongo_db/mongo_db_state.hpp +++ b/plugins/mongo_db/include/golos/plugins/mongo_db/mongo_db_state.hpp @@ -23,6 +23,7 @@ namespace mongo_db { state_writer(db_map& bmi_to_add, const signed_block& block); result_type operator()(const vote_operation& op); + result_type operator()(const vote_options_operation& op); result_type operator()(const comment_operation& op); result_type operator()(const transfer_operation& op); result_type operator()(const transfer_to_vesting_operation& op); diff --git a/plugins/mongo_db/mongo_db_operations.cpp b/plugins/mongo_db/mongo_db_operations.cpp index 3bfa0bfe8b..1acfccc256 100644 --- a/plugins/mongo_db/mongo_db_operations.cpp +++ b/plugins/mongo_db/mongo_db_operations.cpp @@ -77,6 +77,12 @@ namespace mongo_db { return body; } + auto operation_writer::operator()(const vote_options_operation& op) -> result_type { + result_type body; + + return body; + } + auto operation_writer::operator()(const comment_operation& op) -> result_type { result_type body; diff --git a/plugins/mongo_db/mongo_db_state.cpp b/plugins/mongo_db/mongo_db_state.cpp index 02aa32f21c..4ce6791012 100644 --- a/plugins/mongo_db/mongo_db_state.cpp +++ b/plugins/mongo_db/mongo_db_state.cpp @@ -789,6 +789,10 @@ namespace mongo_db { } } + auto state_writer::operator()(const vote_options_operation& op) -> result_type { + + } + auto state_writer::operator()(const comment_operation& op) -> result_type { format_comment(op.author, op.permlink); format_account(op.author);