mirror of
https://github.com/ton-blockchain/ton
synced 2025-02-14 12:12:21 +00:00
Improve validator session stats (#982)
* Add list of validators * Fix producer stats * Make round and stats timestamps more meaningful Co-authored-by: SpyCheese <mikle98@yandex.ru>
This commit is contained in:
parent
037053fffe
commit
6fb2019a4f
10 changed files with 99 additions and 21 deletions
|
@ -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---
|
||||
|
|
Binary file not shown.
|
@ -129,7 +129,7 @@ struct ValidatorSessionStats {
|
|||
}
|
||||
};
|
||||
struct Round {
|
||||
td::uint64 timestamp = 0;
|
||||
double timestamp = -1.0;
|
||||
std::vector<Producer> producers;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
@ -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()) {
|
||||
|
@ -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(
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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_ =
|
||||
|
|
|
@ -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_ =
|
||||
|
|
|
@ -2729,7 +2729,7 @@ 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;
|
||||
|
@ -2737,7 +2737,31 @@ void ValidatorManagerImpl::log_validator_session_stats(BlockIdExt block_id,
|
|||
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) {
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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() {
|
||||
|
@ -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));
|
||||
|
|
Loading…
Reference in a new issue