mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
Rework session stats
This commit is contained in:
parent
392cf64758
commit
71342bdcd4
24 changed files with 436 additions and 334 deletions
|
@ -23,6 +23,8 @@
|
|||
#include "adnl/adnl-node-id.hpp"
|
||||
#include "ton/ton-types.h"
|
||||
|
||||
#include <ton/ton-tl.hpp>
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validatorsession {
|
||||
|
@ -73,24 +75,25 @@ struct ValidatorSessionStats {
|
|||
enum { status_none = 0, status_received = 1, status_rejected = 2, status_approved = 3 };
|
||||
|
||||
struct Producer {
|
||||
PublicKeyHash id = PublicKeyHash::zero();
|
||||
ValidatorSessionCandidateId candidate_id = ValidatorSessionCandidateId::zero();
|
||||
int block_status = status_none;
|
||||
double block_timestamp = -1.0;
|
||||
td::Bits256 root_hash = td::Bits256::zero();
|
||||
td::Bits256 file_hash = td::Bits256::zero();
|
||||
std::string comment;
|
||||
|
||||
PublicKeyHash validator_id = PublicKeyHash::zero();
|
||||
ValidatorSessionCandidateId candidate_id = ValidatorSessionCandidateId::zero();
|
||||
BlockIdExt block_id{workchainIdNotYet, 0, 0, td::Bits256::zero(), td::Bits256::zero()};
|
||||
td::Bits256 collated_data_hash = td::Bits256::zero();
|
||||
bool is_accepted = false;
|
||||
bool is_ours = false;
|
||||
double got_block_at = -1.0;
|
||||
double got_submit_at = -1.0;
|
||||
double collation_time = -1.0;
|
||||
double validation_time = -1.0;
|
||||
double collated_at = -1.0;
|
||||
double validated_at = -1.0;
|
||||
td::int32 gen_utime = -1;
|
||||
std::string comment;
|
||||
|
||||
double collation_time = -1.0, collated_at = -1.0;
|
||||
bool collation_cached = false;
|
||||
bool self_collated = false;
|
||||
td::Bits256 collator_node_id = td::Bits256::zero();
|
||||
|
||||
double validation_time = -1.0, validated_at = -1.0;
|
||||
bool validation_cached = false;
|
||||
double gen_utime = -1.0;
|
||||
|
||||
std::vector<bool> approvers, signers;
|
||||
ValidatorWeight approved_weight = 0;
|
||||
|
@ -129,20 +132,52 @@ struct ValidatorSessionStats {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
tl_object_ptr<ton_api::validatorStats_stats_producer> tl() const {
|
||||
std::string approvers_str(approvers.size(), '0');
|
||||
for (size_t i = 0; i < approvers.size(); ++i) {
|
||||
approvers_str[i] = '0' + approvers[i];
|
||||
}
|
||||
std::string signers_str(signers.size(), '0');
|
||||
for (size_t i = 0; i < signers.size(); ++i) {
|
||||
signers_str[i] = '0' + signers[i];
|
||||
}
|
||||
int flags =
|
||||
(block_status != status_none ? ton_api::validatorStats_stats_producer::Flags::BLOCK_ID_MASK : 0) |
|
||||
(collated_at >= 0.0 ? ton_api::validatorStats_stats_producer::Flags::COLLATED_AT_MASK : 0) |
|
||||
(!collator_node_id.is_zero() ? ton_api::validatorStats_stats_producer::Flags::COLLATOR_NODE_ID_MASK : 0) |
|
||||
(validated_at >= 0.0 ? ton_api::validatorStats_stats_producer::Flags::VALIDATED_AT_MASK : 0) |
|
||||
(serialize_time >= 0.0 || deserialize_time >= 0.0 || serialized_size >= 0
|
||||
? ton_api::validatorStats_stats_producer::Flags::SERIALIZE_TIME_MASK
|
||||
: 0);
|
||||
return create_tl_object<ton_api::validatorStats_stats_producer>(
|
||||
flags, validator_id.bits256_value(), block_status, candidate_id, create_tl_block_id(block_id),
|
||||
collated_data_hash, is_accepted, is_ours, got_block_at, got_submit_at, gen_utime, comment, collation_time,
|
||||
collated_at, collation_cached, self_collated, collator_node_id, validation_time, validated_at,
|
||||
validation_cached, approved_weight, approved_33pct_at, approved_66pct_at, std::move(approvers_str),
|
||||
signed_weight, signed_33pct_at, signed_66pct_at, std::move(signers_str), serialize_time, deserialize_time,
|
||||
serialized_size);
|
||||
}
|
||||
};
|
||||
struct Round {
|
||||
double timestamp = -1.0;
|
||||
double started_at = -1.0;
|
||||
std::vector<Producer> producers;
|
||||
|
||||
tl_object_ptr<ton_api::validatorStats_stats_round> tl() const {
|
||||
std::vector<tl_object_ptr<ton_api::validatorStats_stats_producer>> producers_tl;
|
||||
for (const auto &producer : producers) {
|
||||
producers_tl.push_back(producer.tl());
|
||||
}
|
||||
return create_tl_object<ton_api::validatorStats_stats_round>(started_at, std::move(producers_tl));
|
||||
}
|
||||
};
|
||||
|
||||
td::uint32 first_round;
|
||||
std::vector<Round> rounds;
|
||||
|
||||
bool success = false;
|
||||
ValidatorSessionId session_id = ValidatorSessionId::zero();
|
||||
CatchainSeqno cc_seqno = 0;
|
||||
double timestamp = -1.0;
|
||||
PublicKeyHash self = PublicKeyHash::zero();
|
||||
BlockIdExt block_id{workchainIdNotYet, 0, 0, td::Bits256::zero(), td::Bits256::zero()};
|
||||
CatchainSeqno cc_seqno = 0;
|
||||
bool success = false;
|
||||
double timestamp = -1.0;
|
||||
PublicKeyHash creator = PublicKeyHash::zero();
|
||||
td::uint32 total_validators = 0;
|
||||
ValidatorWeight total_weight = 0;
|
||||
|
@ -150,6 +185,29 @@ struct ValidatorSessionStats {
|
|||
ValidatorWeight signatures_weight = 0;
|
||||
td::uint32 approve_signatures = 0;
|
||||
ValidatorWeight approve_signatures_weight = 0;
|
||||
|
||||
td::uint32 first_round = 0;
|
||||
std::vector<Round> rounds;
|
||||
|
||||
void fix_block_ids() {
|
||||
for (auto &round : rounds) {
|
||||
for (auto &producer : round.producers) {
|
||||
producer.block_id.id = block_id.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tl_object_ptr<ton_api::validatorStats_stats> tl() const {
|
||||
std::vector<tl_object_ptr<ton_api::validatorStats_stats_round>> rounds_tl;
|
||||
for (const auto &round : rounds) {
|
||||
rounds_tl.push_back(round.tl());
|
||||
}
|
||||
int flags = success ? ton_api::validatorStats_stats::Flags::CREATOR_MASK : 0;
|
||||
return create_tl_object<ton_api::validatorStats_stats>(
|
||||
flags, session_id, self.bits256_value(), create_tl_block_id(block_id), cc_seqno, success, timestamp,
|
||||
creator.bits256_value(), total_validators, total_weight, signatures, signatures_weight, approve_signatures,
|
||||
approve_signatures_weight, first_round, std::move(rounds_tl));
|
||||
}
|
||||
};
|
||||
|
||||
struct NewValidatorGroupStats {
|
||||
|
@ -162,9 +220,20 @@ struct NewValidatorGroupStats {
|
|||
ShardIdFull shard{masterchainId};
|
||||
CatchainSeqno cc_seqno = 0;
|
||||
BlockSeqno last_key_block_seqno = 0;
|
||||
double timestamp = -1.0;
|
||||
double started_at = -1.0;
|
||||
td::uint32 self_idx = 0;
|
||||
std::vector<Node> nodes;
|
||||
|
||||
tl_object_ptr<ton_api::validatorStats_newValidatorGroup> tl() const {
|
||||
std::vector<tl_object_ptr<ton_api::validatorStats_newValidatorGroup_node>> nodes_arr;
|
||||
for (const auto &node : nodes) {
|
||||
nodes_arr.push_back(
|
||||
create_tl_object<ton_api::validatorStats_newValidatorGroup_node>(node.id.bits256_value(), node.weight));
|
||||
}
|
||||
return create_tl_object<ton_api::validatorStats_newValidatorGroup>(session_id, create_tl_shard_id(shard), cc_seqno,
|
||||
last_key_block_seqno, started_at, self_idx,
|
||||
std::move(nodes_arr));
|
||||
}
|
||||
};
|
||||
|
||||
struct EndValidatorGroupStats {
|
||||
|
@ -176,6 +245,15 @@ struct EndValidatorGroupStats {
|
|||
ValidatorSessionId session_id = ValidatorSessionId::zero();
|
||||
double timestamp = -1.0;
|
||||
std::vector<Node> nodes;
|
||||
|
||||
tl_object_ptr<ton_api::validatorStats_endValidatorGroup> tl() const {
|
||||
std::vector<tl_object_ptr<ton_api::validatorStats_endValidatorGroup_node>> nodes_arr;
|
||||
for (const auto &node : nodes) {
|
||||
nodes_arr.push_back(create_tl_object<ton_api::validatorStats_endValidatorGroup_node>(node.id.bits256_value(),
|
||||
node.catchain_blocks));
|
||||
}
|
||||
return create_tl_object<ton_api::validatorStats_endValidatorGroup>(session_id, timestamp, std::move(nodes_arr));
|
||||
}
|
||||
};
|
||||
|
||||
struct BlockSourceInfo {
|
||||
|
|
|
@ -266,13 +266,14 @@ void ValidatorSessionImpl::process_broadcast(PublicKeyHash src, td::BufferSlice
|
|||
if (stat->block_status == ValidatorSessionStats::status_none) {
|
||||
stat->block_status = ValidatorSessionStats::status_received;
|
||||
}
|
||||
if (stat->block_timestamp <= 0.0) {
|
||||
stat->block_timestamp = td::Clocks::system();
|
||||
if (stat->got_block_at <= 0.0) {
|
||||
stat->got_block_at = td::Clocks::system();
|
||||
}
|
||||
stat->deserialize_time = deserialize_time;
|
||||
stat->serialized_size = data.size();
|
||||
stat->root_hash = candidate->root_hash_;
|
||||
stat->file_hash = file_hash;
|
||||
stat->block_id.root_hash = candidate->root_hash_;
|
||||
stat->block_id.file_hash = file_hash;
|
||||
stat->collated_data_hash = collated_data_file_hash;
|
||||
}
|
||||
|
||||
if ((td::int32)block_round < (td::int32)cur_round_ - MAX_PAST_ROUND_BLOCK ||
|
||||
|
@ -451,35 +452,36 @@ void ValidatorSessionImpl::candidate_approved_signed(td::uint32 round, Validator
|
|||
}
|
||||
}
|
||||
|
||||
void ValidatorSessionImpl::generated_block(td::uint32 round, ValidatorSessionCandidateId root_hash,
|
||||
td::BufferSlice data, td::BufferSlice collated_data, double collation_time,
|
||||
bool collation_cached) {
|
||||
if (data.size() > description().opts().max_block_size ||
|
||||
collated_data.size() > description().opts().max_collated_data_size) {
|
||||
LOG(ERROR) << this << ": generated candidate is too big. Dropping. size=" << data.size() << " "
|
||||
<< collated_data.size();
|
||||
void ValidatorSessionImpl::generated_block(td::uint32 round, GeneratedCandidate c, double collation_time) {
|
||||
if (c.candidate.data.size() > description().opts().max_block_size ||
|
||||
c.candidate.collated_data.size() > description().opts().max_collated_data_size) {
|
||||
LOG(ERROR) << this << ": generated candidate is too big. Dropping. size=" << c.candidate.data.size() << " "
|
||||
<< c.candidate.collated_data.size();
|
||||
return;
|
||||
}
|
||||
auto file_hash = sha256_bits256(data.as_slice());
|
||||
auto collated_data_file_hash = sha256_bits256(collated_data.as_slice());
|
||||
auto block_id = description().candidate_id(local_idx(), root_hash, file_hash, collated_data_file_hash);
|
||||
auto file_hash = sha256_bits256(c.candidate.data.as_slice());
|
||||
auto collated_data_file_hash = sha256_bits256(c.candidate.collated_data.as_slice());
|
||||
auto block_id = description().candidate_id(local_idx(), c.candidate.id.root_hash, file_hash, collated_data_file_hash);
|
||||
|
||||
auto stat = stats_get_candidate_stat(round, local_id(), block_id);
|
||||
if (stat) {
|
||||
stat->block_status = ValidatorSessionStats::status_received;
|
||||
stat->collation_time = collation_time;
|
||||
stat->collated_at = td::Clocks::system();
|
||||
stat->block_timestamp = td::Clocks::system();
|
||||
stat->collation_cached = collation_cached;
|
||||
stat->root_hash = root_hash;
|
||||
stat->file_hash = file_hash;
|
||||
stat->got_block_at = td::Clocks::system();
|
||||
stat->collation_cached = c.is_cached;
|
||||
stat->self_collated = c.self_collated;
|
||||
stat->collator_node_id = c.collator_node_id;
|
||||
stat->block_id = c.candidate.id;
|
||||
stat->collated_data_hash = collated_data_file_hash;
|
||||
}
|
||||
if (round != cur_round_) {
|
||||
return;
|
||||
}
|
||||
td::Timer serialize_timer;
|
||||
auto b = create_tl_object<ton_api::validatorSession_candidate>(local_id().tl(), round, root_hash, std::move(data),
|
||||
std::move(collated_data));
|
||||
auto b = create_tl_object<ton_api::validatorSession_candidate>(local_id().tl(), round, c.candidate.id.root_hash,
|
||||
std::move(c.candidate.data),
|
||||
std::move(c.candidate.collated_data));
|
||||
auto B = serialize_candidate(b, compress_block_candidates_).move_as_ok();
|
||||
if (stat) {
|
||||
stat->serialize_time = serialize_timer.elapsed();
|
||||
|
@ -546,9 +548,8 @@ void ValidatorSessionImpl::check_generate_slot() {
|
|||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), print_id = print_id(), timer = std::move(timer),
|
||||
round = cur_round_](td::Result<GeneratedCandidate> R) {
|
||||
if (R.is_ok()) {
|
||||
auto c = std::move(R.ok_ref().candidate);
|
||||
td::actor::send_closure(SelfId, &ValidatorSessionImpl::generated_block, round, c.id.root_hash,
|
||||
c.data.clone(), c.collated_data.clone(), timer.elapsed(), R.ok().is_cached);
|
||||
td::actor::send_closure(SelfId, &ValidatorSessionImpl::generated_block, round, R.move_as_ok(),
|
||||
timer.elapsed());
|
||||
} else {
|
||||
LOG(WARNING) << print_id << ": failed to generate block candidate: " << R.move_as_error();
|
||||
}
|
||||
|
@ -606,11 +607,12 @@ void ValidatorSessionImpl::try_approve_block(const SentBlock *block) {
|
|||
if (stat->block_status == ValidatorSessionStats::status_none) {
|
||||
stat->block_status = ValidatorSessionStats::status_received;
|
||||
}
|
||||
if (stat->block_timestamp <= 0.0) {
|
||||
stat->block_timestamp = td::Clocks::system();
|
||||
if (stat->got_block_at <= 0.0) {
|
||||
stat->got_block_at = td::Clocks::system();
|
||||
}
|
||||
stat->root_hash = B->root_hash_;
|
||||
stat->file_hash = td::sha256_bits256(B->data_);
|
||||
stat->block_id.root_hash = B->root_hash_;
|
||||
stat->block_id.file_hash = td::sha256_bits256(B->data_);
|
||||
stat->collated_data_hash = td::sha256_bits256(B->collated_data_);
|
||||
}
|
||||
|
||||
auto P = td::PromiseCreator::lambda([round = cur_round_, hash = block_id, root_hash = block->get_root_hash(),
|
||||
|
@ -933,7 +935,7 @@ void ValidatorSessionImpl::on_new_round(td::uint32 round) {
|
|||
while (round_idx >= cur_stats_.rounds.size()) {
|
||||
stats_add_round();
|
||||
}
|
||||
cur_stats_.rounds[round_idx].timestamp = td::Clocks::system();
|
||||
cur_stats_.rounds[round_idx].started_at = td::Clocks::system();
|
||||
}
|
||||
auto it2 = blocks_.begin();
|
||||
while (it2 != blocks_.end()) {
|
||||
|
@ -1034,9 +1036,7 @@ void ValidatorSessionImpl::get_end_stats(td::Promise<EndValidatorGroupStats> pro
|
|||
promise.set_error(td::Status::Error(ErrorCode::notready, "not started"));
|
||||
return;
|
||||
}
|
||||
EndValidatorGroupStats stats;
|
||||
stats.session_id = unique_hash_;
|
||||
stats.timestamp = td::Clocks::system();
|
||||
EndValidatorGroupStats stats{.session_id = unique_hash_, .timestamp = td::Clocks::system()};
|
||||
stats.nodes.resize(description().get_total_nodes());
|
||||
for (size_t i = 0; i < stats.nodes.size(); ++i) {
|
||||
stats.nodes[i].id = description().get_source_id(i);
|
||||
|
@ -1145,7 +1145,7 @@ void ValidatorSessionImpl::stats_init() {
|
|||
if (cur_stats_.rounds.empty()) {
|
||||
stats_add_round();
|
||||
}
|
||||
cur_stats_.rounds[0].timestamp = td::Clocks::system();
|
||||
cur_stats_.rounds[0].started_at = td::Clocks::system();
|
||||
stats_inited_ = true;
|
||||
}
|
||||
|
||||
|
@ -1158,13 +1158,13 @@ void ValidatorSessionImpl::stats_add_round() {
|
|||
td::int32 priority = description().get_node_priority(i, round);
|
||||
if (priority >= 0) {
|
||||
CHECK((size_t)priority < stat.producers.size());
|
||||
stat.producers[priority].id = description().get_source_id(i);
|
||||
stat.producers[priority].validator_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 (!stat.producers.empty() && stat.producers.back().id.is_zero()) {
|
||||
while (!stat.producers.empty() && stat.producers.back().validator_id.is_zero()) {
|
||||
stat.producers.pop_back();
|
||||
}
|
||||
}
|
||||
|
@ -1179,7 +1179,7 @@ ValidatorSessionStats::Producer *ValidatorSessionImpl::stats_get_candidate_stat(
|
|||
}
|
||||
auto &stats_round = cur_stats_.rounds[round - cur_stats_.first_round];
|
||||
auto it = std::find_if(stats_round.producers.begin(), stats_round.producers.end(),
|
||||
[&](const ValidatorSessionStats::Producer &p) { return p.id == src; });
|
||||
[&](const ValidatorSessionStats::Producer &p) { return p.validator_id == src; });
|
||||
if (it == stats_round.producers.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -78,11 +78,6 @@ class ValidatorSession : public td::actor::Actor {
|
|||
bool is_cached_ = false;
|
||||
};
|
||||
|
||||
struct GeneratedCandidate {
|
||||
BlockCandidate candidate;
|
||||
bool is_cached = false;
|
||||
};
|
||||
|
||||
class Callback {
|
||||
public:
|
||||
virtual void on_candidate(BlockSourceInfo source_info, ValidatorSessionRootHash root_hash, td::BufferSlice data,
|
||||
|
|
|
@ -217,8 +217,7 @@ class ValidatorSessionImpl : public ValidatorSession {
|
|||
void candidate_approved_signed(td::uint32 round, ValidatorSessionCandidateId hash, td::uint32 ok_from,
|
||||
td::BufferSlice signature);
|
||||
|
||||
void generated_block(td::uint32 round, ValidatorSessionRootHash root_hash, td::BufferSlice data,
|
||||
td::BufferSlice collated, double collation_time, bool collation_cached);
|
||||
void generated_block(td::uint32 round, GeneratedCandidate c, double collation_time);
|
||||
void signed_block(td::uint32 round, ValidatorSessionCandidateId hash, td::BufferSlice signature);
|
||||
|
||||
void end_request(td::uint32 round, ValidatorSessionCandidateId block_id) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue