13 #include <scorum/rewards_math/formulas.hpp>
20 , _account_service(services.account_service())
21 , _comment_service(services.comment_service())
22 , _comment_vote_service(services.comment_vote_service())
23 , _dgp_service(services.dynamic_global_property_service())
24 , _hardfork_service(services.hardfork_property_service())
37 FC_ASSERT(abs(o.
weight) <= 100,
"Weight is not a SCORUM percentage");
49 FC_ASSERT(!(voter.owner_challenged || voter.active_challenged),
50 "Operation cannot be processed because the account is currently challenged.");
52 FC_ASSERT(voter.can_vote,
"Voter has declined their voting rights.");
57 FC_ASSERT(comment.allow_votes,
"Votes are not allowed on the comment.");
59 if (comment.cashout_time == fc::time_point_sec::maximum())
62 if (!_comment_vote_service.
is_exists(comment.id, voter.id))
64 _comment_vote_service.
create([&](comment_vote_object& cvo) {
66 cvo.comment = comment.id;
67 cvo.vote_percent = weight;
73 const comment_vote_object& comment_vote = _comment_vote_service.
get(comment.id, voter.id);
74 _comment_vote_service.
update(comment_vote, [&](comment_vote_object& cvo) {
75 cvo.vote_percent = weight;
84 int64_t elapsed_seconds = (_dgp_service.
head_block_time() - voter.last_vote_time).to_seconds();
88 uint16_t current_power = rewards_math::calculate_restoring_power(
90 FC_ASSERT(current_power > 0,
"Account currently does not have voting power.");
93 = rewards_math::calculate_used_power(current_power, weight, SCORUM_VOTING_POWER_DECAY_PERCENT);
95 FC_ASSERT(used_power <= current_power,
"Account does not have enough power to vote.");
98 = rewards_math::calculate_abs_reward_shares(used_power, voter.effective_scorumpower().amount);
101 "Voting weight is too small, please accumulate more voting power or scorum power.");
104 share_type rshares = weight < 0 ? -abs_rshares : abs_rshares;
106 if (!_comment_vote_service.
is_exists(comment.id, voter.id))
108 FC_ASSERT(weight != 0,
"Vote weight cannot be 0.");
113 "Cannot increase payout within last twelve hours before payout.");
118 const auto& root_comment = _comment_service.
get(comment.root_comment);
120 FC_ASSERT(abs_rshares > 0,
"Cannot vote with 0 rshares.");
122 auto old_vote_rshares = comment.vote_rshares;
124 _comment_service.
update(comment, [&](comment_object& c) {
125 c.net_rshares += rshares;
126 c.abs_rshares += abs_rshares;
128 c.vote_rshares += rshares;
135 _comment_service.
update(root_comment, [&](comment_object& c) { c.children_abs_rshares += abs_rshares; });
137 uint64_t max_vote_weight = 0;
139 _comment_vote_service.
create([&](comment_vote_object& cv) {
141 cv.comment = comment.id;
142 cv.rshares = rshares;
143 cv.vote_percent = weight;
146 bool curation_reward_eligible
147 = rshares > 0 && (comment.last_payout == fc::time_point_sec()) && comment.allow_curation_rewards;
149 if (curation_reward_eligible)
151 const auto& reward_fund =
db().content_reward_fund_scr_service().get();
152 max_vote_weight = rewards_math::calculate_max_vote_weight(comment.vote_rshares, old_vote_rshares,
153 reward_fund.curation_reward_curve);
154 cv.weight = rewards_math::calculate_vote_weight(max_vote_weight, cv.last_update, comment.created,
166 =
db().account_blogging_statistic_service();
168 const auto& voter_stat = account_blogging_statistic_service.
obtain(voter.id);
169 account_blogging_statistic_service.
add_vote(voter_stat);
175 _comment_service.
update(comment, [&](comment_object& c) { c.total_vote_weight += max_vote_weight; });
180 const comment_vote_object& comment_vote = _comment_vote_service.
get(comment.id, voter.id);
182 FC_ASSERT(comment_vote.num_changes != -1,
"Cannot vote again on a comment after payout.");
185 "Voter has used the maximum number of vote changes on this comment.");
187 FC_ASSERT(comment_vote.vote_percent != weight,
"You have already voted in a similar way.");
189 if (comment_vote.rshares < rshares)
192 "Cannot increase payout within last twelve hours before payout.");
197 const auto& root_comment = _comment_service.
get(comment.root_comment);
199 _comment_service.
update(comment, [&](comment_object& c) {
200 c.net_rshares -= comment_vote.rshares;
201 c.net_rshares += rshares;
202 c.abs_rshares += abs_rshares;
205 if (rshares > 0 && comment_vote.rshares < 0)
207 else if (rshares > 0 && comment_vote.rshares == 0)
209 else if (rshares == 0 && comment_vote.rshares < 0)
211 else if (rshares == 0 && comment_vote.rshares > 0)
213 else if (rshares < 0 && comment_vote.rshares == 0)
215 else if (rshares < 0 && comment_vote.rshares > 0)
219 _comment_service.
update(root_comment, [&](comment_object& c) { c.children_abs_rshares += abs_rshares; });
221 _comment_service.
update(comment, [&](comment_object& c) { c.total_vote_weight -= comment_vote.weight; });
223 _comment_vote_service.
update(comment_vote, [&](comment_vote_object& cv) {
224 cv.rshares = rshares;
225 cv.vote_percent = weight;
232 FC_CAPTURE_AND_RETHROW()
data_service_factory_i & db() const
vote_evaluator(data_service_factory_i &services)
void do_apply(const operation_type &op)
protocol::vote_weight_type get_weigth(const operation_type &o) const
#define SCORUM_MIN_VOTE_INTERVAL_SEC
#define SCORUM_VOTE_REGENERATION_SECONDS
#define SCORUM_UPVOTE_LOCKOUT
#define SCORUM_100_PERCENT
#define SCORUM_MAX_VOTE_CHANGES
#define SCORUM_REVERSE_AUCTION_WINDOW_SECONDS
#define SCORUM_VOTE_DUST_THRESHOLD
fc::safe< share_value_type > share_type
virtual const account_blogging_statistic_object & obtain(const account_id_type &account_id)=0
virtual void add_vote(const account_blogging_statistic_object &stat)=0
virtual const account_object & get_account(const account_name_type &) const =0
virtual void update_voting_power(const account_object &account, uint16_t voting_power)=0
virtual void update(const modifier_type &modifier)=0
virtual const object_type & create(const modifier_type &modifier)=0
virtual fc::time_point_sec head_block_time() const =0
virtual bool has_hardfork(uint32_t hardfork) const =0