@@ -621,6 +621,150 @@ namespace golos { namespace chain {
621621 }
622622 }
623623
624+ struct comment_bandwidth final {
625+ database& db;
626+ const time_point_sec& now;
627+ const comment_operation& op;
628+ const chain_properties& mprops;
629+ const account_object& auth;
630+ mutable const account_bandwidth_object* band = nullptr ;
631+
632+ uint16_t calc_reward_weight () const {
633+ band = db.find <account_bandwidth_object, by_account_bandwidth_type>(
634+ std::make_tuple (op.author , bandwidth_type::post ));
635+
636+ if (nullptr == band) {
637+ band = &db.create <account_bandwidth_object>([&](account_bandwidth_object &b) {
638+ b.account = op.author ;
639+ b.type = bandwidth_type::post ;
640+ });
641+ }
642+
643+ if (db.has_hardfork (STEEMIT_HARDFORK_0_19__533_1002 )) {
644+ hf19 ();
645+ } else if (db.has_hardfork (STEEMIT_HARDFORK_0_12__176 )) {
646+ hf12 ();
647+ } else if (db.has_hardfork (STEEMIT_HARDFORK_0_6__113 )) {
648+ hf6 ();
649+ } else {
650+ hf0 ();
651+ }
652+
653+ return calculate ();
654+ }
655+
656+ private:
657+ uint16_t calculate () const {
658+ uint16_t reward_weight = STEEMIT_100_PERCENT ;
659+
660+ if (op.parent_author == STEEMIT_ROOT_POST_PARENT ) {
661+ auto pb = band->average_bandwidth ;
662+
663+ if (db.has_hardfork (STEEMIT_HARDFORK_0_12__176 )) {
664+ auto post_delta_time = std::min (
665+ now.sec_since_epoch () - band->last_bandwidth_update .sec_since_epoch (),
666+ STEEMIT_POST_AVERAGE_WINDOW );
667+
668+ auto old_weight =
669+ (pb * (STEEMIT_POST_AVERAGE_WINDOW - post_delta_time)) /
670+ STEEMIT_POST_AVERAGE_WINDOW ;
671+
672+ pb = (old_weight + STEEMIT_100_PERCENT );
673+
674+ reward_weight = uint16_t (std::min (
675+ (STEEMIT_POST_WEIGHT_CONSTANT * STEEMIT_100_PERCENT ) / (pb.value * pb.value ),
676+ uint64_t (STEEMIT_100_PERCENT )));
677+ }
678+
679+ db.modify (*band, [&](account_bandwidth_object &b) {
680+ b.last_bandwidth_update = now;
681+ b.average_bandwidth = pb;
682+ });
683+ }
684+
685+ return reward_weight;
686+ }
687+
688+ void hf19 () const {
689+ auto elapsed_seconds = (now - auth.last_post ).to_seconds ();
690+
691+ if (op.parent_author == STEEMIT_ROOT_POST_PARENT ) {
692+ auto consumption = mprops.posts_window / mprops.posts_per_window ;
693+
694+ auto regenerated_capacity = std::min (
695+ uint32_t (mprops.posts_window ),
696+ uint32_t (elapsed_seconds));
697+
698+ auto current_capacity = std::min (
699+ uint16_t (auth.posts_capacity + regenerated_capacity),
700+ mprops.posts_window );
701+
702+ GOLOS_CHECK_BANDWIDTH (current_capacity + 1 , consumption,
703+ bandwidth_exception::post_bandwidth,
704+ " You may only post ${posts_per_window} times in ${posts_window} seconds." ,
705+ (" posts_per_window" , mprops.posts_per_window )
706+ (" posts_window" , mprops.posts_window ));
707+
708+
709+ db.modify (auth, [&](account_object& a) {
710+ a.posts_capacity = current_capacity - consumption;
711+ });
712+
713+ } else {
714+ auto consumption = mprops.comments_window / mprops.comments_per_window ;
715+
716+ auto regenerated_capacity = std::min (
717+ uint32_t (mprops.comments_window ),
718+ uint32_t (elapsed_seconds));
719+
720+ auto current_capacity = std::min (
721+ uint16_t (auth.comments_capacity + regenerated_capacity),
722+ mprops.comments_window );
723+
724+ GOLOS_CHECK_BANDWIDTH (current_capacity + 1 , consumption,
725+ bandwidth_exception::comment_bandwidth,
726+ " You may only comment ${comments_per_window} times in ${comments_window} seconds." ,
727+ (" comments_per_window" , mprops.comments_per_window )
728+ (" comments_window" , mprops.comments_window ));
729+
730+ db.modify (auth, [&](account_object& a) {
731+ a.comments_capacity = current_capacity - consumption;
732+ });
733+ }
734+ }
735+
736+ void hf12 () const {
737+ if (op.parent_author == STEEMIT_ROOT_POST_PARENT ) {
738+ GOLOS_CHECK_BANDWIDTH (now, band->last_bandwidth_update + STEEMIT_MIN_ROOT_COMMENT_INTERVAL ,
739+ bandwidth_exception::post_bandwidth,
740+ " You may only post once every 5 minutes." );
741+ } else {
742+ GOLOS_CHECK_BANDWIDTH (now, auth.last_post + STEEMIT_MIN_REPLY_INTERVAL ,
743+ golos::bandwidth_exception::comment_bandwidth,
744+ " You may only comment once every 20 seconds." );
745+ }
746+ }
747+
748+ void hf6 () const {
749+ if (op.parent_author == STEEMIT_ROOT_POST_PARENT ) {
750+ GOLOS_CHECK_BANDWIDTH (now, auth.last_post + STEEMIT_MIN_ROOT_COMMENT_INTERVAL ,
751+ bandwidth_exception::post_bandwidth,
752+ " You may only post once every 5 minutes." );
753+ } else {
754+ GOLOS_CHECK_BANDWIDTH (now, auth.last_post + STEEMIT_MIN_REPLY_INTERVAL ,
755+ bandwidth_exception::comment_bandwidth,
756+ " You may only comment once every 20 seconds." );
757+ }
758+ }
759+
760+ void hf0 () const {
761+ GOLOS_CHECK_BANDWIDTH (now, auth.last_post + 60 ,
762+ bandwidth_exception::post_bandwidth,
763+ " You may only post once per minute." );
764+ }
765+
766+ }; // struct check_comment_bandwidth
767+
624768 void comment_evaluator::do_apply (const comment_operation &o) {
625769 try {
626770 if (_db.is_producing () ||
@@ -667,86 +811,7 @@ namespace golos { namespace chain {
667811 " The parent comment has disabled replies." );
668812 }
669813
670- auto band = _db.find <account_bandwidth_object, by_account_bandwidth_type>(std::make_tuple (o.author , bandwidth_type::post ));
671- if (band == nullptr ) {
672- band = &_db.create <account_bandwidth_object>([&](account_bandwidth_object &b) {
673- b.account = o.author ;
674- b.type = bandwidth_type::post ;
675- });
676- }
677-
678- auto elapsed_seconds = (now - auth.last_post ).to_seconds ();
679-
680- if (_db.has_hardfork (STEEMIT_HARDFORK_0_19__533 )) {
681- auto consumption = mprops.comments_window / mprops.comments_per_window ;
682-
683- auto regenerated_capacity = std::min (uint32_t (mprops.comments_window ), uint32_t (elapsed_seconds));
684- auto current_capacity = std::min (uint16_t (auth.comments_capacity + regenerated_capacity), mprops.comments_window );
685-
686- if (o.parent_author == STEEMIT_ROOT_POST_PARENT ) {
687- GOLOS_CHECK_BANDWIDTH (now, band->last_bandwidth_update + STEEMIT_MIN_ROOT_COMMENT_INTERVAL ,
688- bandwidth_exception::post_bandwidth,
689- " You may only post once every 5 minutes." );
690- } else {
691- GOLOS_CHECK_BANDWIDTH (current_capacity, consumption,
692- bandwidth_exception::comment_bandwidth,
693- " You may only comment ${comments_per_window} times in ${comments_window} seconds." ,
694- (" comments_per_window" , mprops.comments_per_window )(" comments_window" , mprops.comments_window ));
695- }
696-
697- db ().modify (auth, [&](account_object &a) {
698- a.comments_capacity = current_capacity - consumption;
699- });
700- } else if (_db.has_hardfork (STEEMIT_HARDFORK_0_12__176 )) {
701- if (o.parent_author == STEEMIT_ROOT_POST_PARENT )
702- GOLOS_CHECK_BANDWIDTH (now, band->last_bandwidth_update + STEEMIT_MIN_ROOT_COMMENT_INTERVAL ,
703- bandwidth_exception::post_bandwidth,
704- " You may only post once every 5 minutes." );
705- else
706- GOLOS_CHECK_BANDWIDTH (now, auth.last_post + STEEMIT_MIN_REPLY_INTERVAL ,
707- golos::bandwidth_exception::comment_bandwidth,
708- " You may only comment once every 20 seconds." );
709- } else if (_db.has_hardfork (STEEMIT_HARDFORK_0_6__113 )) {
710- if (o.parent_author == STEEMIT_ROOT_POST_PARENT )
711- GOLOS_CHECK_BANDWIDTH (now, auth.last_post + STEEMIT_MIN_ROOT_COMMENT_INTERVAL ,
712- bandwidth_exception::post_bandwidth,
713- " You may only post once every 5 minutes." );
714- else
715- GOLOS_CHECK_BANDWIDTH (now, auth.last_post + STEEMIT_MIN_REPLY_INTERVAL ,
716- bandwidth_exception::comment_bandwidth,
717- " You may only comment once every 20 seconds." );
718- } else {
719- GOLOS_CHECK_BANDWIDTH (now, auth.last_post + 60 ,
720- bandwidth_exception::post_bandwidth,
721- " You may only post once per minute." );
722- }
723-
724- uint16_t reward_weight = STEEMIT_100_PERCENT ;
725-
726- if (o.parent_author == STEEMIT_ROOT_POST_PARENT ) {
727- auto post_bandwidth = band->average_bandwidth ;
728-
729- if (_db.has_hardfork (STEEMIT_HARDFORK_0_12__176 )) {
730- auto post_delta_time = std::min (
731- now.sec_since_epoch () -
732- band->last_bandwidth_update .sec_since_epoch (), STEEMIT_POST_AVERAGE_WINDOW );
733- auto old_weight = (post_bandwidth *
734- (STEEMIT_POST_AVERAGE_WINDOW -
735- post_delta_time)) /
736- STEEMIT_POST_AVERAGE_WINDOW ;
737- post_bandwidth = (old_weight + STEEMIT_100_PERCENT );
738- reward_weight = uint16_t (std::min (
739- (STEEMIT_POST_WEIGHT_CONSTANT *
740- STEEMIT_100_PERCENT ) /
741- (post_bandwidth.value *
742- post_bandwidth.value ), uint64_t (STEEMIT_100_PERCENT )));
743- }
744-
745- _db.modify (*band, [&](account_bandwidth_object &b) {
746- b.last_bandwidth_update = now;
747- b.average_bandwidth = post_bandwidth;
748- });
749- }
814+ uint16_t reward_weight = comment_bandwidth{_db, now, o, mprops, auth}.calc_reward_weight ();
750815
751816 db ().modify (auth, [&](account_object &a) {
752817 a.last_post = now;
@@ -1378,13 +1443,13 @@ namespace golos { namespace chain {
13781443
13791444 auto elapsed_seconds = (_db.head_block_time () - voter.last_vote_time ).to_seconds ();
13801445
1381- if (_db.has_hardfork (STEEMIT_HARDFORK_0_19__533 )) {
1446+ if (_db.has_hardfork (STEEMIT_HARDFORK_0_19__533_1002 )) {
13821447 auto consumption = mprops.votes_window / mprops.votes_per_window ;
13831448
13841449 auto regenerated_capacity = std::min (uint32_t (mprops.votes_window ), uint32_t (elapsed_seconds));
13851450 auto current_capacity = std::min (uint16_t (voter.voting_capacity + regenerated_capacity), mprops.votes_window );
13861451
1387- GOLOS_CHECK_BANDWIDTH (current_capacity, consumption,
1452+ GOLOS_CHECK_BANDWIDTH (current_capacity + 1 , consumption,
13881453 bandwidth_exception::vote_bandwidth,
13891454 " Can only vote ${votes_per_window} times in ${votes_window} seconds." ,
13901455 (" votes_per_window" , mprops.votes_per_window )(" votes_window" , mprops.votes_window ));
0 commit comments