Skip to content

Commit 9639711

Browse files
Merge pull request #967 from cyberway/witness-last-update
Witness last update
2 parents 97c4f1b + 59629ea commit 9639711

File tree

4 files changed

+40
-22
lines changed

4 files changed

+40
-22
lines changed

golos.ctrl/golos.ctrl.abi

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,8 @@
137137
{"name": "url", "type": "string"},
138138
{"name": "active", "type": "bool"},
139139
{"name": "total_weight", "type": "uint64"},
140-
{"name": "counter_votes", "type": "uint64"}
140+
{"name": "counter_votes", "type": "uint64"},
141+
{"name": "last_update", "type": "time_point_sec$"}
141142
]
142143
}, {
143144
"name": "witness_voter", "base": "",
@@ -150,7 +151,8 @@
150151
"fields": [
151152
{"name": "witness", "type": "name"},
152153
{"name": "weight", "type": "uint64"},
153-
{"name": "active", "type": "bool"}
154+
{"name": "active", "type": "bool"},
155+
{"name": "last_update", "type": "time_point_sec"}
154156
]
155157
}
156158
],

golos.ctrl/include/golos.ctrl/config.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@ namespace golos { namespace config {
55

66
static const auto witness_max_url_size = 256;
77

8+
static const auto witness_expiration_sec = 30*24*60*60;
9+
810
} } // golos::config

golos.ctrl/include/golos.ctrl/golos.ctrl.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <eosio/asset.hpp>
88
#include <eosio/singleton.hpp>
99
#include <eosio/crypto.hpp>
10+
#include <eosio/binary_extension.hpp>
1011
#include <vector>
1112
#include <string>
1213
#include <common/dispatchers.hpp>
@@ -25,6 +26,10 @@ struct witness_info {
2526
uint64_t total_weight;
2627
uint64_t counter_votes;
2728

29+
// binary_extension is for compatibility with old DB before contract upgraded
30+
// note: it can be added only to end of table
31+
eosio::binary_extension<time_point_sec, eosio::write_strategy::no_value> last_update;
32+
2833
uint64_t primary_key() const {
2934
return name.value;
3035
}
@@ -125,10 +130,10 @@ class [[eosio::contract("golos.ctrl")]] control: public contract {
125130
name witness;
126131
uint64_t weight;
127132
bool active;
133+
time_point_sec last_update;
128134
};
129135

130136
void send_witness_event(const witness_info& wi);
131-
void active_witness(golos::name witness, bool flag);
132137
};
133138

134139

golos.ctrl/src/golos.ctrl.cpp

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ void control::regwitness(name witness, string url) {
144144
w.name = witness;
145145
w.url = url;
146146
w.active = true;
147+
w.last_update.emplace(eosio::current_time_point());
147148
};
148149
});
149150

@@ -166,15 +167,38 @@ void control::unregwitness(name witness) {
166167

167168
void control::stopwitness(name witness) {
168169
assert_started();
169-
require_auth(witness);
170-
active_witness(witness, false);
170+
const auto now = eosio::current_time_point();
171+
172+
// TODO: simplify upsert to allow passing just inner lambda
173+
bool exists = upsert_tbl<witness_tbl>(witness, [&](bool) {
174+
return [&](witness_info& w) {
175+
eosio::check(w.active, "active flag not updated");
176+
if (!has_auth(witness)) {
177+
eosio::check(now - w.last_update.value_or() > eosio::seconds(config::witness_expiration_sec), "recently updated witness can be stopped only by itself");
178+
}
179+
w.active = false;
180+
send_witness_event(w);
181+
};
182+
}, false);
183+
eosio::check(exists, "witness not found");
184+
update_auths();
171185
}
172186

173187
void control::startwitness(name witness) {
174188
eosio::check(!control::is_blocking(config::control_name, witness), "You are blocked.");
175189
assert_started();
176190
require_auth(witness);
177-
active_witness(witness, true);
191+
192+
// TODO: simplify upsert to allow passing just inner lambda
193+
bool exists = upsert_tbl<witness_tbl>(witness, [&](bool) {
194+
return [&](witness_info& w) {
195+
w.active = true;
196+
w.last_update.emplace(eosio::current_time_point());
197+
send_witness_event(w);
198+
};
199+
}, false);
200+
eosio::check(exists, "witness not found");
201+
update_auths();
178202
}
179203

180204
// Note: if not weighted, it's possible to pass all witnesses in vector like in BP actions
@@ -386,25 +410,10 @@ void control::update_auths() {
386410
}
387411

388412
void control::send_witness_event(const witness_info& wi) {
389-
witnessstate data{wi.name, wi.total_weight, wi.active};
413+
witnessstate data{wi.name, wi.total_weight, wi.active, wi.last_update.value_or()};
390414
eosio::event(_self, "witnessstate"_n, data).send();
391415
}
392416

393-
void control::active_witness(name witness, bool flag) {
394-
// TODO: simplify upsert to allow passing just inner lambda
395-
bool exists = upsert_tbl<witness_tbl>(witness, [&](bool) {
396-
return [&](witness_info& w) {
397-
eosio::check(flag != w.active, "active flag not updated");
398-
w.active = flag;
399-
400-
send_witness_event(w);
401-
};
402-
}, false);
403-
eosio::check(exists, "witness not found");
404-
405-
update_auths();
406-
}
407-
408417
vector<witness_info> control::top_witness_info() {
409418
vector<witness_info> top;
410419
const auto l = props().witnesses.max;

0 commit comments

Comments
 (0)