Skip to content

Commit 5ca7486

Browse files
committed
maint counter object added, changed plugin accordingly
1 parent 72587d3 commit 5ca7486

File tree

4 files changed

+143
-15
lines changed

4 files changed

+143
-15
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
* Copyright (c) 2019 Blockchain Projects BV.
3+
*
4+
* The MIT License
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
#pragma once
25+
#include <boost/range/numeric.hpp>
26+
#include <boost/range/adaptor/map.hpp>
27+
#include <boost/container/flat_map.hpp>
28+
#include <boost/container/flat_set.hpp>
29+
#include <boost/multi_index/composite_key.hpp>
30+
31+
#include <fc/optional.hpp>
32+
33+
#include <graphene/chain/database.hpp>
34+
#include <graphene/voting_stat/voting_stat_plugin.hpp>
35+
36+
#include <graphene/protocol/types.hpp>
37+
#include <graphene/protocol/vote.hpp>
38+
39+
#include <graphene/db/generic_index.hpp>
40+
41+
using graphene::chain::object_id_type;
42+
using graphene::chain::account_id_type;
43+
using graphene::chain::vote_id_type;
44+
45+
using graphene::db::object;
46+
using graphene::db::abstract_object;
47+
using graphene::db::generic_index;
48+
using graphene::db::by_id;
49+
50+
using namespace boost::multi_index;
51+
using boost::container::flat_map;
52+
using boost::container::flat_set;
53+
54+
namespace graphene { namespace voting_stat {
55+
/**
56+
* @brief tracks the number maintenance interval occurences
57+
* @ingroup object
58+
* @ingroup voting_stat_plugin
59+
*
60+
* The number of maintenance intervals to be tracked is set in this object. Since a fork can occur during a
61+
* maintenance interval, it is not sufficient to track the number of intervals through a plugin internal
62+
* variable. In the case of a fork this object will be reverted together with the internal maintenance counter.
63+
* Through the lifetime of the plugin there will be only one of this objects.
64+
*
65+
* @note By default this object are not tracked, the voting_stat_plugin must be loaded for this object to
66+
* be maintained.
67+
*/
68+
class maintenance_counter_object : public abstract_object<maintenance_counter_object>
69+
{
70+
public:
71+
static const uint8_t space_id = VOTING_STAT_SPACE_ID;
72+
static const uint8_t type_id = voting_stat_object_type_ids::maintenance_counter_object_type_id;
73+
74+
maintenance_counter_object(){}
75+
76+
bool counter_reached( chain::database& db ) const
77+
{
78+
if( counter == max_counter )
79+
{
80+
db.modify<maintenance_counter_object>( *this, [](maintenance_counter_object& o) {
81+
o.counter = 0;
82+
});
83+
return true;
84+
}
85+
db.modify<maintenance_counter_object>( *this, [](maintenance_counter_object& o) {
86+
o.counter += 1;
87+
});
88+
return false;
89+
}
90+
91+
uint16_t max_counter = 12; // every 12th maintenance interval vote*_objects will be created
92+
uint16_t counter = 12;
93+
};
94+
95+
typedef multi_index_container< maintenance_counter_object,
96+
indexed_by<
97+
ordered_unique< tag<by_id>,
98+
member< object, object_id_type, &object::id >
99+
>
100+
>
101+
> maintenance_counter_multi_index_type;
102+
103+
typedef generic_index<
104+
maintenance_counter_object, maintenance_counter_multi_index_type > maintenance_counter_index;
105+
106+
}} // graphene::chain
107+
108+
FC_REFLECT_DERIVED( graphene::voting_stat::maintenance_counter_object, (graphene::chain::object),
109+
(max_counter)(counter) )

libraries/plugins/voting_stat/include/graphene/voting_stat/voting_stat_plugin.hpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ namespace graphene { namespace voting_stat {
4444
enum voting_stat_object_type_ids
4545
{
4646
voting_statistics_object_type_id,
47-
voteable_statistics_object_type_id
47+
voteable_statistics_object_type_id,
48+
maintenance_counter_object_type_id
4849
};
4950

5051
namespace detail

libraries/plugins/voting_stat/include/graphene/voting_stat/voting_statistics_object.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ namespace graphene { namespace voting_stat {
5454
/**
5555
* @brief tracks the history of the voting stake for an account
5656
* @ingroup object
57-
* @ingroup implementation
57+
* @ingroup voting_stat
5858
*
5959
* The calculation of the voting stake, performed in the maintenance interval, results in the creation or,
6060
* if present, in the update of a voting_statistics_object.

libraries/plugins/voting_stat/voting_stat_plugin.cpp

+31-13
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525

2626
#include <graphene/voting_stat/voting_statistics_object.hpp>
2727
#include <graphene/voting_stat/voteable_statistics_object.hpp>
28+
#include <graphene/voting_stat/maintenance_counter_object.hpp>
29+
2830
#include <graphene/chain/worker_object.hpp>
2931
#include <graphene/chain/witness_object.hpp>
3032
#include <graphene/chain/committee_member_object.hpp>
@@ -52,13 +54,10 @@ class voting_stat_plugin_impl
5254
boost::signals2::connection _on_voting_stake_calc_conn;
5355
std::unique_ptr<boost::signals2::shared_connection_block> _on_voting_stake_calc_block;
5456

55-
uint16_t _maint_counter = 0;
56-
5757
/**
5858
* plugin parameters
5959
*/
6060
bool _keep_objects_in_db = true;
61-
uint16_t _track_every_x_maint = 12;
6261
bool _track_worker_votes = true;
6362
bool _track_witness_votes = true;
6463
bool _track_committee_votes = true;
@@ -108,14 +107,14 @@ void voting_stat_plugin_impl::on_maintenance_begin(uint32_t block_num)
108107
if( !_keep_objects_in_db )
109108
delete_all_statistics_objects();
110109

111-
if( _maint_counter == _track_every_x_maint )
110+
auto& db = database();
111+
const auto& maint_counter_obj = *db.get_index_type<maintenance_counter_index>().indices().get<by_id>().begin();
112+
if( maint_counter_obj.counter_reached( db ) )
112113
{
113114
_on_voting_stake_calc_block->unblock();
114-
_maint_counter = 0;
115115
_maint_block = block_num;
116116
_create_voteable = true;
117117
}
118-
++_maint_counter;
119118
}
120119

121120
void voting_stat_plugin_impl::on_maintenance_end()
@@ -147,8 +146,6 @@ void voting_stat_plugin_impl::create_voteable_statistics_objects()
147146
{
148147
auto& db = database();
149148

150-
// TODO secondary index for workers where current_time < worker_end_time
151-
// will reduce the iteration time
152149
if( _track_worker_votes )
153150
{
154151
const auto& worker_idx = db.get_index_type<worker_index>().indices().get<by_id>();
@@ -326,13 +323,34 @@ void voting_stat_plugin::plugin_initialize(const boost::program_options::variabl
326323
auto& db = database();
327324
db.add_index< primary_index<voting_statistics_index> >();
328325
db.add_index< primary_index<voteable_statistics_index> >();
326+
db.add_index< primary_index<maintenance_counter_index> >();
329327

330-
if( options.count("voting-stat-track-every-x-maint") ){
331-
my->_track_every_x_maint = options["voting-stat-track-every-x-maint"].as<uint16_t>();
332-
if( my->_track_every_x_maint == 0 )
333-
my->_track_every_x_maint = 1;
334-
my->_maint_counter = my->_track_every_x_maint;
328+
if( options.count("voting-stat-track-every-x-maint") )
329+
{
330+
uint16_t track_every_x_maint = options["voting-stat-track-every-x-maint"].as<uint16_t>();
331+
if( track_every_x_maint == 0 )
332+
track_every_x_maint = 1;
333+
334+
const auto& maint_counter_idx = db.get_index_type<maintenance_counter_index>().indices().get<by_id>();
335+
if( maint_counter_idx.empty() )
336+
{
337+
db.create<maintenance_counter_object>( [track_every_x_maint]( maintenance_counter_object& o ) {
338+
o.max_counter = track_every_x_maint;
339+
o.counter = track_every_x_maint;
340+
});
341+
}
342+
else
343+
{
344+
db.modify<maintenance_counter_object>( *maint_counter_idx.begin(),
345+
[track_every_x_maint]( maintenance_counter_object& o )
346+
{
347+
o.max_counter = track_every_x_maint;
348+
o.counter = track_every_x_maint;
349+
}
350+
);
351+
}
335352
}
353+
336354
if( options.count("voting-stat-keep-objects-in-db") ){
337355
my->_keep_objects_in_db = options["voting-stat-keep-objects-in-db"].as<bool>();
338356
}

0 commit comments

Comments
 (0)