From 5ca7486eae149bce312f085ef95b3ed1c34e5ae0 Mon Sep 17 00:00:00 2001 From: dimfred Date: Mon, 21 Oct 2019 14:04:41 +0200 Subject: [PATCH] maint counter object added, changed plugin accordingly --- .../maintenance_counter_object.hpp | 109 ++++++++++++++++++ .../voting_stat/voting_stat_plugin.hpp | 3 +- .../voting_stat/voting_statistics_object.hpp | 2 +- .../voting_stat/voting_stat_plugin.cpp | 44 ++++--- 4 files changed, 143 insertions(+), 15 deletions(-) create mode 100644 libraries/plugins/voting_stat/include/graphene/voting_stat/maintenance_counter_object.hpp diff --git a/libraries/plugins/voting_stat/include/graphene/voting_stat/maintenance_counter_object.hpp b/libraries/plugins/voting_stat/include/graphene/voting_stat/maintenance_counter_object.hpp new file mode 100644 index 0000000000..78047223e5 --- /dev/null +++ b/libraries/plugins/voting_stat/include/graphene/voting_stat/maintenance_counter_object.hpp @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2019 Blockchain Projects BV. + * + * The MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#pragma once +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include + +#include + +using graphene::chain::object_id_type; +using graphene::chain::account_id_type; +using graphene::chain::vote_id_type; + +using graphene::db::object; +using graphene::db::abstract_object; +using graphene::db::generic_index; +using graphene::db::by_id; + +using namespace boost::multi_index; +using boost::container::flat_map; +using boost::container::flat_set; + +namespace graphene { namespace voting_stat { + /** + * @brief tracks the number maintenance interval occurences + * @ingroup object + * @ingroup voting_stat_plugin + * + * The number of maintenance intervals to be tracked is set in this object. Since a fork can occur during a + * maintenance interval, it is not sufficient to track the number of intervals through a plugin internal + * variable. In the case of a fork this object will be reverted together with the internal maintenance counter. + * Through the lifetime of the plugin there will be only one of this objects. + * + * @note By default this object are not tracked, the voting_stat_plugin must be loaded for this object to + * be maintained. + */ + class maintenance_counter_object : public abstract_object + { + public: + static const uint8_t space_id = VOTING_STAT_SPACE_ID; + static const uint8_t type_id = voting_stat_object_type_ids::maintenance_counter_object_type_id; + + maintenance_counter_object(){} + + bool counter_reached( chain::database& db ) const + { + if( counter == max_counter ) + { + db.modify( *this, [](maintenance_counter_object& o) { + o.counter = 0; + }); + return true; + } + db.modify( *this, [](maintenance_counter_object& o) { + o.counter += 1; + }); + return false; + } + + uint16_t max_counter = 12; // every 12th maintenance interval vote*_objects will be created + uint16_t counter = 12; + }; + + typedef multi_index_container< maintenance_counter_object, + indexed_by< + ordered_unique< tag, + member< object, object_id_type, &object::id > + > + > + > maintenance_counter_multi_index_type; + + typedef generic_index< + maintenance_counter_object, maintenance_counter_multi_index_type > maintenance_counter_index; + +}} // graphene::chain + +FC_REFLECT_DERIVED( graphene::voting_stat::maintenance_counter_object, (graphene::chain::object), + (max_counter)(counter) ) diff --git a/libraries/plugins/voting_stat/include/graphene/voting_stat/voting_stat_plugin.hpp b/libraries/plugins/voting_stat/include/graphene/voting_stat/voting_stat_plugin.hpp index e5fb54b257..fbd6b14771 100644 --- a/libraries/plugins/voting_stat/include/graphene/voting_stat/voting_stat_plugin.hpp +++ b/libraries/plugins/voting_stat/include/graphene/voting_stat/voting_stat_plugin.hpp @@ -44,7 +44,8 @@ namespace graphene { namespace voting_stat { enum voting_stat_object_type_ids { voting_statistics_object_type_id, - voteable_statistics_object_type_id + voteable_statistics_object_type_id, + maintenance_counter_object_type_id }; namespace detail diff --git a/libraries/plugins/voting_stat/include/graphene/voting_stat/voting_statistics_object.hpp b/libraries/plugins/voting_stat/include/graphene/voting_stat/voting_statistics_object.hpp index 32491ebba1..75d5c1dc0e 100644 --- a/libraries/plugins/voting_stat/include/graphene/voting_stat/voting_statistics_object.hpp +++ b/libraries/plugins/voting_stat/include/graphene/voting_stat/voting_statistics_object.hpp @@ -54,7 +54,7 @@ namespace graphene { namespace voting_stat { /** * @brief tracks the history of the voting stake for an account * @ingroup object - * @ingroup implementation + * @ingroup voting_stat * * The calculation of the voting stake, performed in the maintenance interval, results in the creation or, * if present, in the update of a voting_statistics_object. diff --git a/libraries/plugins/voting_stat/voting_stat_plugin.cpp b/libraries/plugins/voting_stat/voting_stat_plugin.cpp index 447e61876b..ce73204c48 100644 --- a/libraries/plugins/voting_stat/voting_stat_plugin.cpp +++ b/libraries/plugins/voting_stat/voting_stat_plugin.cpp @@ -25,6 +25,8 @@ #include #include +#include + #include #include #include @@ -52,13 +54,10 @@ class voting_stat_plugin_impl boost::signals2::connection _on_voting_stake_calc_conn; std::unique_ptr _on_voting_stake_calc_block; - uint16_t _maint_counter = 0; - /** * plugin parameters */ bool _keep_objects_in_db = true; - uint16_t _track_every_x_maint = 12; bool _track_worker_votes = true; bool _track_witness_votes = true; bool _track_committee_votes = true; @@ -108,14 +107,14 @@ void voting_stat_plugin_impl::on_maintenance_begin(uint32_t block_num) if( !_keep_objects_in_db ) delete_all_statistics_objects(); - if( _maint_counter == _track_every_x_maint ) + auto& db = database(); + const auto& maint_counter_obj = *db.get_index_type().indices().get().begin(); + if( maint_counter_obj.counter_reached( db ) ) { _on_voting_stake_calc_block->unblock(); - _maint_counter = 0; _maint_block = block_num; _create_voteable = true; } - ++_maint_counter; } void voting_stat_plugin_impl::on_maintenance_end() @@ -147,8 +146,6 @@ void voting_stat_plugin_impl::create_voteable_statistics_objects() { auto& db = database(); - // TODO secondary index for workers where current_time < worker_end_time - // will reduce the iteration time if( _track_worker_votes ) { const auto& worker_idx = db.get_index_type().indices().get(); @@ -326,13 +323,34 @@ void voting_stat_plugin::plugin_initialize(const boost::program_options::variabl auto& db = database(); db.add_index< primary_index >(); db.add_index< primary_index >(); + db.add_index< primary_index >(); - if( options.count("voting-stat-track-every-x-maint") ){ - my->_track_every_x_maint = options["voting-stat-track-every-x-maint"].as(); - if( my->_track_every_x_maint == 0 ) - my->_track_every_x_maint = 1; - my->_maint_counter = my->_track_every_x_maint; + if( options.count("voting-stat-track-every-x-maint") ) + { + uint16_t track_every_x_maint = options["voting-stat-track-every-x-maint"].as(); + if( track_every_x_maint == 0 ) + track_every_x_maint = 1; + + const auto& maint_counter_idx = db.get_index_type().indices().get(); + if( maint_counter_idx.empty() ) + { + db.create( [track_every_x_maint]( maintenance_counter_object& o ) { + o.max_counter = track_every_x_maint; + o.counter = track_every_x_maint; + }); + } + else + { + db.modify( *maint_counter_idx.begin(), + [track_every_x_maint]( maintenance_counter_object& o ) + { + o.max_counter = track_every_x_maint; + o.counter = track_every_x_maint; + } + ); + } } + if( options.count("voting-stat-keep-objects-in-db") ){ my->_keep_objects_in_db = options["voting-stat-keep-objects-in-db"].as(); }