Skip to content

Commit

Permalink
Improve validator session stats (ton-blockchain#982)
Browse files Browse the repository at this point in the history
* Add list of validators
* Fix producer stats
* Make round and stats timestamps more meaningful

Co-authored-by: SpyCheese <[email protected]>
  • Loading branch information
EmelyanenkoK and SpyCheese authored May 8, 2024
1 parent 037053f commit 6fb2019
Show file tree
Hide file tree
Showing 10 changed files with 99 additions and 21 deletions.
8 changes: 6 additions & 2 deletions tl/generate/scheme/ton_api.tl
Original file line number Diff line number Diff line change
Expand Up @@ -761,13 +761,17 @@ validatorSession.statsProducer id:int256 candidate_id:int256 block_status:int co
signed_weight:long signed_33pct_at:double signed_66pct_at:double
serialize_time:double deserialize_time:double serialized_size:int = validatorSession.StatsProducer;

validatorSession.statsRound timestamp:long producers:(vector validatorSession.statsProducer) = validatorSession.StatsRound;
validatorSession.statsRound timestamp:double producers:(vector validatorSession.statsProducer) = validatorSession.StatsRound;

validatorSession.stats success:Bool id:tonNode.blockIdExt timestamp:long self:int256 session_id:int256 cc_seqno:int
validatorSession.stats success:Bool id:tonNode.blockIdExt timestamp:double self:int256 session_id:int256 cc_seqno:int
creator:int256 total_validators:int total_weight:long
signatures:int signatures_weight:long approve_signatures:int approve_signatures_weight:long
first_round:int rounds:(vector validatorSession.statsRound) = validatorSession.Stats;

validatorSession.newValidatorGroupStats.node id:int256 weight:long = validatorSession.newValidatorGroupStats.Node;
validatorSession.newValidatorGroupStats session_id:int256 workchain:int shard:long cc_seqno:int timestamp:double
self_idx:int nodes:(vector validatorSession.newValidatorGroupStats.node) = validatorSession.NewValidatorGroupStats;

---functions---

---types---
Expand Down
Binary file modified tl/generate/scheme/ton_api.tlo
Binary file not shown.
18 changes: 16 additions & 2 deletions validator-session/validator-session-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ struct ValidatorSessionStats {
}
};
struct Round {
td::uint64 timestamp = 0;
double timestamp = -1.0;
std::vector<Producer> producers;
};

Expand All @@ -139,7 +139,7 @@ struct ValidatorSessionStats {
bool success = false;
ValidatorSessionId session_id = ValidatorSessionId::zero();
CatchainSeqno cc_seqno = 0;
td::uint64 timestamp = 0;
double timestamp = -1.0;
PublicKeyHash self = PublicKeyHash::zero();
PublicKeyHash creator = PublicKeyHash::zero();
td::uint32 total_validators = 0;
Expand All @@ -150,6 +150,20 @@ struct ValidatorSessionStats {
ValidatorWeight approve_signatures_weight = 0;
};

struct NewValidatorGroupStats {
struct Node {
PublicKeyHash id = PublicKeyHash::zero();
ValidatorWeight weight = 0;
};

ValidatorSessionId session_id = ValidatorSessionId::zero();
ShardIdFull shard{masterchainId};
CatchainSeqno cc_seqno = 0;
double timestamp = -1.0;
td::uint32 self_idx = 0;
std::vector<Node> nodes;
};

} // namespace validatorsession

} // namespace ton
39 changes: 24 additions & 15 deletions validator-session/validator-session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -871,7 +871,7 @@ void ValidatorSessionImpl::on_new_round(td::uint32 round) {
callback_->on_block_skipped(cur_round_);
} else {
cur_stats_.success = true;
cur_stats_.timestamp = (td::uint64)td::Clocks::system();
cur_stats_.timestamp = td::Clocks::system();
cur_stats_.signatures = (td::uint32)export_sigs.size();
cur_stats_.signatures_weight = signatures_weight;
cur_stats_.approve_signatures = (td::uint32)export_approve_sigs.size();
Expand Down Expand Up @@ -899,6 +899,12 @@ void ValidatorSessionImpl::on_new_round(td::uint32 round) {
cur_round_++;
if (have_block) {
stats_init();
} else {
size_t round_idx = cur_round_ - cur_stats_.first_round;
while (round_idx >= cur_stats_.rounds.size()) {
stats_add_round();
}
cur_stats_.rounds[round_idx].timestamp = td::Clocks::system();
}
auto it2 = blocks_.begin();
while (it2 != blocks_.end()) {
Expand Down Expand Up @@ -988,9 +994,7 @@ void ValidatorSessionImpl::destroy() {
}

void ValidatorSessionImpl::get_current_stats(td::Promise<ValidatorSessionStats> promise) {
ValidatorSessionStats stats = cur_stats_;
stats.timestamp = (td::uint64)td::Clocks::system();
promise.set_result(std::move(stats));
promise.set_result(cur_stats_);
}

void ValidatorSessionImpl::get_validator_group_info_for_litequery(
Expand Down Expand Up @@ -1084,26 +1088,31 @@ void ValidatorSessionImpl::stats_init() {
++it;
}
}

if (cur_stats_.rounds.empty()) {
stats_add_round();
}
cur_stats_.rounds[0].timestamp = td::Clocks::system();
stats_inited_ = true;
}

void ValidatorSessionImpl::stats_add_round() {
td::uint32 round = cur_stats_.first_round + cur_stats_.rounds.size();
cur_stats_.rounds.emplace_back();
auto& round = cur_stats_.rounds.back();
round.timestamp = (td::uint64)td::Clocks::system();
round.producers.resize(description().get_max_priority() + 1);
auto& stat = cur_stats_.rounds.back();
stat.producers.resize(description().get_max_priority() + 1);
for (td::uint32 i = 0; i < description().get_total_nodes(); i++) {
td::int32 priority = description().get_node_priority(i, cur_round_);
td::int32 priority = description().get_node_priority(i, round);
if (priority >= 0) {
CHECK((size_t)priority < round.producers.size());
round.producers[priority].id = description().get_source_id(i);
round.producers[priority].is_ours = (local_idx() == i);
round.producers[priority].approvers.resize(description().get_total_nodes(), false);
round.producers[priority].signers.resize(description().get_total_nodes(), false);
CHECK((size_t)priority < stat.producers.size());
stat.producers[priority].id = description().get_source_id(i);
stat.producers[priority].is_ours = (local_idx() == i);
stat.producers[priority].approvers.resize(description().get_total_nodes(), false);
stat.producers[priority].signers.resize(description().get_total_nodes(), false);
}
}
while (!round.producers.empty() && round.producers.back().id.is_zero()) {
round.producers.pop_back();
while (!stat.producers.empty() && stat.producers.back().id.is_zero()) {
stat.producers.pop_back();
}
}

Expand Down
1 change: 1 addition & 0 deletions validator/interfaces/validator-manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ class ValidatorManager : public ValidatorManagerInterface {
virtual void wait_shard_client_state(BlockSeqno seqno, td::Timestamp timeout, td::Promise<td::Unit> promise) = 0;

virtual void log_validator_session_stats(BlockIdExt block_id, validatorsession::ValidatorSessionStats stats) = 0;
virtual void log_new_validator_group_stats(validatorsession::NewValidatorGroupStats stats) = 0;

virtual void get_block_handle_for_litequery(BlockIdExt block_id, td::Promise<ConstBlockHandle> promise) = 0;
virtual void get_block_data_for_litequery(BlockIdExt block_id, td::Promise<td::Ref<BlockData>> promise) = 0;
Expand Down
3 changes: 3 additions & 0 deletions validator/manager-disk.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,9 @@ class ValidatorManagerImpl : public ValidatorManager {
void log_validator_session_stats(BlockIdExt block_id, validatorsession::ValidatorSessionStats stats) override {
UNREACHABLE();
}
void log_new_validator_group_stats(validatorsession::NewValidatorGroupStats stats) override {
UNREACHABLE();
}
void get_out_msg_queue_size(BlockIdExt block_id, td::Promise<td::uint32> promise) override {
if (queue_size_counter_.empty()) {
queue_size_counter_ =
Expand Down
3 changes: 3 additions & 0 deletions validator/manager-hardfork.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,9 @@ class ValidatorManagerImpl : public ValidatorManager {
void log_validator_session_stats(BlockIdExt block_id, validatorsession::ValidatorSessionStats stats) override {
UNREACHABLE();
}
void log_new_validator_group_stats(validatorsession::NewValidatorGroupStats stats) override {
UNREACHABLE();
}
void get_out_msg_queue_size(BlockIdExt block_id, td::Promise<td::uint32> promise) override {
if (queue_size_counter_.empty()) {
queue_size_counter_ =
Expand Down
28 changes: 26 additions & 2 deletions validator/manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2729,15 +2729,39 @@ void ValidatorManagerImpl::log_validator_session_stats(BlockIdExt block_id,
stats.cc_seqno, stats.creator.bits256_value(), stats.total_validators, stats.total_weight, stats.signatures,
stats.signatures_weight, stats.approve_signatures, stats.approve_signatures_weight, stats.first_round,
std::move(rounds));
std::string s = td::json_encode<std::string>(td::ToJson(*obj.get()), false);
auto s = td::json_encode<std::string>(td::ToJson(*obj.get()), false);
s.erase(std::remove_if(s.begin(), s.end(), [](char c) { return c == '\n' || c == '\r'; }), s.end());

std::ofstream file;
file.open(fname, std::ios_base::app);
file << s << "\n";
file.close();

LOG(INFO) << "Writing validator session stats for " << block_id.id;
LOG(INFO) << "Writing validator session stats for " << block_id.id.to_str();
}

void ValidatorManagerImpl::log_new_validator_group_stats(validatorsession::NewValidatorGroupStats stats) {
std::string fname = opts_->get_session_logs_file();
if (fname.empty()) {
return;
}
std::vector<tl_object_ptr<ton_api::validatorSession_newValidatorGroupStats_node>> nodes;
for (const auto &node : stats.nodes) {
nodes.push_back(
create_tl_object<ton_api::validatorSession_newValidatorGroupStats_node>(node.id.bits256_value(), node.weight));
}
auto obj = create_tl_object<ton_api::validatorSession_newValidatorGroupStats>(
stats.session_id, stats.shard.workchain, stats.shard.shard, stats.cc_seqno, stats.timestamp, stats.self_idx,
std::move(nodes));
auto s = td::json_encode<std::string>(td::ToJson(*obj.get()), false);
s.erase(std::remove_if(s.begin(), s.end(), [](char c) { return c == '\n' || c == '\r'; }), s.end());

std::ofstream file;
file.open(fname, std::ios_base::app);
file << s << "\n";
file.close();

LOG(INFO) << "Writing new validator group stats for " << stats.shard.to_str();
}

void ValidatorManagerImpl::get_block_handle_for_litequery(BlockIdExt block_id, td::Promise<ConstBlockHandle> promise) {
Expand Down
1 change: 1 addition & 0 deletions validator/manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,7 @@ class ValidatorManagerImpl : public ValidatorManager {
void wait_shard_client_state(BlockSeqno seqno, td::Timestamp timeout, td::Promise<td::Unit> promise) override;

void log_validator_session_stats(BlockIdExt block_id, validatorsession::ValidatorSessionStats stats) override;
void log_new_validator_group_stats(validatorsession::NewValidatorGroupStats stats) override;

void get_out_msg_queue_size(BlockIdExt block_id, td::Promise<td::uint32> promise) override {
if (queue_size_counter_.empty()) {
Expand Down
19 changes: 19 additions & 0 deletions validator/validator-group.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,22 @@ void ValidatorGroup::start(std::vector<BlockIdExt> prev, BlockIdExt min_masterch
prev_block_ids_ = std::vector<BlockIdExt>{next_block_id};
}
postponed_accept_.clear();

validatorsession::NewValidatorGroupStats stats;
stats.session_id = session_id_;
stats.shard = shard_;
stats.cc_seqno = validator_set_->get_catchain_seqno();
stats.timestamp = td::Clocks::system();
td::uint32 idx = 0;
for (const auto& node : validator_set_->export_vector()) {
PublicKeyHash id = ValidatorFullId{node.key}.compute_short_id();
if (id == local_id_) {
stats.self_idx = idx;
}
stats.nodes.push_back(validatorsession::NewValidatorGroupStats::Node{id, node.weight});
++idx;
}
td::actor::send_closure(manager_, &ValidatorManager::log_new_validator_group_stats, std::move(stats));
}

void ValidatorGroup::destroy() {
Expand All @@ -390,6 +406,9 @@ void ValidatorGroup::destroy() {
return;
}
auto stats = R.move_as_ok();
if (stats.rounds.empty()) {
return;
}
stats.cc_seqno = cc_seqno;
td::actor::send_closure(manager, &ValidatorManager::log_validator_session_stats, block_id,
std::move(stats));
Expand Down

0 comments on commit 6fb2019

Please sign in to comment.