22#include < golos/api/comment_api_object.hpp>
33#include < golos/chain/account_object.hpp>
44#include < golos/chain/steem_objects.hpp>
5+ #include < golos/chain/curation_info.hpp>
56#include < fc/io/json.hpp>
67#include < boost/algorithm/string.hpp>
78
@@ -34,12 +35,11 @@ namespace golos { namespace api {
3435
3536 discussion create_discussion (const comment_object& o) const ;
3637
37- void select_active_votes (
38- std::vector<vote_state>& result, uint32_t & total_count,
39- const std::string& author, const std::string& permlink, uint32_t limit
40- ) const ;
38+ std::vector<vote_state> select_active_votes (
39+ const std::string& author, const std::string& permlink, uint32_t limit, uint32_t offset
40+ ) const ;
4141
42- share_type get_curator_unclaimed_rewards (const discussion& d, share_type max_rewards ) const ;
42+ std::vector<vote_state> select_active_votes (const comment_curation_info&, uint32_t limit, uint32_t offset ) const ;
4343
4444 void set_pending_payout (discussion& d) const ;
4545
@@ -55,10 +55,13 @@ namespace golos { namespace api {
5555
5656 comment_api_object create_comment_api_object (const comment_object& o) const ;
5757
58- discussion get_discussion (const comment_object& c, uint32_t vote_limit) const ;
58+ discussion get_discussion (const comment_object& c, uint32_t vote_limit, uint32_t offset ) const ;
5959
6060 void fill_comment_api_object (const comment_object& o, comment_api_object& d) const ;
6161
62+ private:
63+ void distribute_auction_tokens (discussion& d, share_type& curator_tokens, share_type& author_tokens) const ;
64+
6265 private:
6366 golos::chain::database& database_;
6467 std::function<void (const golos::chain::database&, const account_name_type&, fc::optional<share_type>&)> fill_reputation_;
@@ -102,7 +105,6 @@ namespace golos { namespace api {
102105 d.children_abs_rshares = o.children_abs_rshares ;
103106 d.cashout_time = o.cashout_time ;
104107 d.max_cashout_time = o.max_cashout_time ;
105- d.total_vote_weight = o.total_vote_weight ;
106108 d.reward_weight = o.reward_weight ;
107109 d.net_votes = o.net_votes ;
108110 d.mode = o.mode ;
@@ -112,6 +114,9 @@ namespace golos { namespace api {
112114 d.allow_replies = o.allow_replies ;
113115 d.allow_votes = o.allow_votes ;
114116 d.allow_curation_rewards = o.allow_curation_rewards ;
117+ d.auction_window_reward_destination = o.auction_window_reward_destination ;
118+ d.auction_window_size = o.auction_window_size ;
119+ d.curation_rewards_percent = o.curation_rewards_percent ;
115120
116121 for (auto & route : o.beneficiaries ) {
117122 d.beneficiaries .push_back (route);
@@ -129,84 +134,101 @@ namespace golos { namespace api {
129134 }
130135
131136// get_discussion
132- discussion discussion_helper::impl::get_discussion (const comment_object& c , uint32_t vote_limit) const {
133- discussion d = create_discussion (c );
137+ discussion discussion_helper::impl::get_discussion (const comment_object& comment , uint32_t vote_limit, uint32_t offset ) const {
138+ discussion d = create_discussion (comment );
134139 set_url (d);
140+
141+ d.active_votes_count = comment.total_votes ;
142+
143+ comment_curation_info c{database_, comment, true };
144+
145+ d.curation_reward_curve = c.curve ;
146+ d.total_vote_weight = c.total_vote_weight ;
147+ d.auction_window_weight = c.auction_window_weight ;
148+ d.votes_in_auction_window_weight = c.votes_in_auction_window_weight ;
149+ d.active_votes = select_active_votes (c, vote_limit, offset);
150+
135151 set_pending_payout (d);
136- select_active_votes (d. active_votes , d. active_votes_count , d. author , d. permlink , vote_limit);
152+
137153 return d;
138154 }
139155
140- discussion discussion_helper::get_discussion (const comment_object& c, uint32_t vote_limit) const {
141- return pimpl->get_discussion (c, vote_limit);
156+ discussion discussion_helper::get_discussion (const comment_object& c, uint32_t vote_limit, uint32_t offset ) const {
157+ return pimpl->get_discussion (c, vote_limit, offset );
142158 }
143159//
144160
145161// select_active_votes
146- void discussion_helper::impl::select_active_votes (
147- std::vector<vote_state>& result, uint32_t & total_count,
148- const std::string& author, const std::string& permlink, uint32_t limit
162+ std::vector<vote_state> discussion_helper::impl::select_active_votes (
163+ const std::string& author, const std::string& permlink, uint32_t limit, uint32_t offset
149164 ) const {
150- const auto & comment = database ().get_comment (author, permlink);
151- const auto & idx = database ().get_index <comment_vote_index>().indices ().get <by_comment_voter>();
152- comment_object::id_type cid (comment.id );
153- total_count = 0 ;
154- result.clear ();
155- for (auto itr = idx.lower_bound (cid); itr != idx.end () && itr->comment == cid; ++itr, ++total_count) {
156- if (result.size () < limit) {
157- const auto & vo = database ().get (itr->voter );
158- vote_state vstate;
159- vstate.voter = vo.name ;
160- vstate.weight = itr->weight ;
161- vstate.rshares = itr->rshares ;
162- vstate.percent = itr->vote_percent ;
163- vstate.time = itr->last_update ;
164- fill_reputation_ (database (), vo.name , vstate.reputation );
165- result.emplace_back (vstate);
166- }
167- }
165+ const auto & comment = database_.get_comment (author, permlink);
166+ comment_curation_info c{database_, comment, true };
167+
168+ return select_active_votes (c, limit, offset);
168169 }
169170
170- void discussion_helper::select_active_votes (
171- std::vector<vote_state>& result, uint32_t & total_count,
172- const std::string& author, const std::string& permlink, uint32_t limit
171+ std::vector<vote_state> discussion_helper::impl::select_active_votes (
172+ const comment_curation_info& c, uint32_t limit, uint32_t offset
173173 ) const {
174- pimpl-> select_active_votes (result, total_count, author, permlink, limit );
175- }
174+ offset = std::min (offset, uint32_t (c. vote_list . size ()) );
175+ limit = std::min (limit, uint32_t (c. vote_list . size () - offset));
176176
177- share_type discussion_helper::impl::get_curator_unclaimed_rewards (const discussion& d, share_type max_rewards) const {
178- share_type unclaimed_rewards = max_rewards;
179- auto & db = database ();
180- try {
181- uint128_t total_weight (d.total_vote_weight );
177+ if (limit == 0 ) {
178+ return {};
179+ }
182180
183- if (d.allow_curation_rewards ) {
184- if (d.total_vote_weight > 0 ) {
185- const auto &cvidx = db.get_index <comment_vote_index>().indices ().get <by_comment_weight_voter>();
186- for (auto itr = cvidx.lower_bound (d.id ); itr != cvidx.end () && itr->comment == d.id ; ++itr) {
187- auto claim = ((max_rewards.value * uint128_t (itr->weight )) / total_weight).to_uint64 ();
188- if (claim > 0 ) { // min_amt is non-zero satoshis
189- unclaimed_rewards -= claim;
190- } else {
191- break ;
192- }
193- }
194- }
195- } else {
196- unclaimed_rewards = 0 ;
197- }
181+ auto itr = c.vote_list .begin ();
182+ std::advance (itr, offset);
183+
184+ std::vector<vote_state> result;
185+ result.reserve (limit);
186+
187+ for (; itr != c.vote_list .end () && result.size () < limit; ++itr) {
188+ const auto & vo = database ().get (itr->vote ->voter );
189+ vote_state vstate;
190+ vstate.voter = vo.name ;
191+ vstate.weight = itr->weight ;
192+ vstate.rshares = itr->vote ->rshares ;
193+ vstate.percent = itr->vote ->vote_percent ;
194+ vstate.time = itr->vote ->last_update ;
195+ fill_reputation_ (database (), vo.name , vstate.reputation );
196+ result.emplace_back (std::move (vstate));
197+ }
198+ return result;
199+ }
198200
199- return unclaimed_rewards;
200- } FC_CAPTURE_AND_RETHROW ()
201+ std::vector<vote_state> discussion_helper::select_active_votes (
202+ const std::string& author, const std::string& permlink, uint32_t limit, uint32_t offset
203+ ) const {
204+ return pimpl->select_active_votes (author, permlink, limit, offset);
201205 }
202206
203207//
204208// set_pending_payout
209+
210+ void discussion_helper::impl::distribute_auction_tokens (discussion& d, share_type& curators_tokens, share_type& author_tokens) const {
211+ const auto auction_window_reward = curators_tokens.value * d.auction_window_weight / d.total_vote_weight ;
212+
213+ curators_tokens -= auction_window_reward;
214+
215+ if (d.auction_window_reward_destination == to_author) {
216+ author_tokens += auction_window_reward;
217+ } else if (d.auction_window_reward_destination == to_curators &&
218+ d.total_vote_weight != d.votes_in_auction_window_weight + d.auction_window_weight ) {
219+ curators_tokens += auction_window_reward;
220+ }
221+ }
222+
205223 void discussion_helper::impl::set_pending_payout (discussion& d) const {
206224 auto & db = database ();
207225
208226 fill_promoted_ (db, d);
209227
228+ if (d.total_vote_weight == 0 ) {
229+ return ;
230+ }
231+
210232 const auto & props = db.get_dynamic_global_properties ();
211233 const auto & hist = db.get_feed_history ();
212234 asset pot = props.total_reward_fund_steem ;
@@ -225,27 +247,25 @@ namespace golos { namespace api {
225247 r2 *= pot.amount .value ;
226248 r2 /= total_r2;
227249
228- uint64_t payout = static_cast < uint64_t >(r2 );
250+ const share_type reward_tokens = std::min ( share_type (r2), d. max_accepted_payout . amount );
229251
230- payout = std::min (payout, uint64_t (d. max_accepted_payout . amount . value )) ;
252+ share_type curation_tokens = reward_tokens * d. curation_rewards_percent / STEEMIT_100_PERCENT ;
231253
232- uint128_t reward_tokens = uint128_t (payout) ;
254+ share_type author_tokens = reward_tokens - curation_tokens ;
233255
234- share_type curation_tokens = ((reward_tokens * db.get_curation_rewards_percent ())
235- / STEEMIT_100_PERCENT ).to_uint64 ();
236- auto crs_unclaimed = get_curator_unclaimed_rewards (d, curation_tokens);
237- auto crs_claim = curation_tokens - crs_unclaimed;
238- share_type author_tokens = reward_tokens.to_uint64 () - crs_claim;
239256 if (d.allow_curation_rewards ) {
240- d.pending_curator_payout_value = db.to_sbd (asset (crs_claim, STEEM_SYMBOL ));
241- d.pending_curator_payout_gests_value = asset (crs_claim, STEEM_SYMBOL ) * props.get_vesting_share_price ();
257+ distribute_auction_tokens (d, curation_tokens, author_tokens);
258+
259+ d.pending_curator_payout_value = db.to_sbd (asset (curation_tokens, STEEM_SYMBOL ));
260+ d.pending_curator_payout_gests_value = asset (curation_tokens, STEEM_SYMBOL ) * props.get_vesting_share_price ();
242261 d.pending_payout_value += d.pending_curator_payout_value ;
243262 }
244263
245264 uint32_t benefactor_weights = 0 ;
246265 for (auto &b : d.beneficiaries ) {
247266 benefactor_weights += b.weight ;
248267 }
268+
249269 if (benefactor_weights != 0 ) {
250270 auto total_beneficiary = (author_tokens * benefactor_weights) / STEEMIT_100_PERCENT ;
251271 author_tokens -= total_beneficiary;
@@ -276,10 +296,6 @@ namespace golos { namespace api {
276296
277297 fill_reputation_ (db, d.author , d.author_reputation );
278298
279- if (d.parent_author != STEEMIT_ROOT_POST_PARENT ) {
280- d.cashout_time = db.calculate_discussion_payout_time (db.get_comment (d.id ));
281- }
282-
283299 if (d.body .size () > 1024 * 128 ) {
284300 d.body = " body pruned due to size" ;
285301 }
@@ -341,7 +357,7 @@ namespace golos { namespace api {
341357 pimpl = std::make_unique<impl>(db, fill_reputation, fill_promoted, fill_comment_info);
342358 }
343359
344- discussion_helper::~discussion_helper () = default ;
360+ discussion_helper::~discussion_helper () {}
345361
346362//
347363} } // golos::api
0 commit comments