/*
This file is part of TON Blockchain Library.
TON Blockchain Library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
TON Blockchain Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see .
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once
#include "shard.h"
#include "block.h"
#include "proof.h"
#include "external-message.h"
#include "ihr-message.h"
#include "shard-block.h"
#include "message-queue.h"
#include "validator/validator.h"
#include "liteserver.h"
#include "crypto/vm/db/DynamicBagOfCellsDb.h"
#include "validator-session/validator-session-types.h"
#include "auto/tl/lite_api.h"
#include "impl/out-msg-queue-proof.hpp"
namespace ton {
namespace validator {
constexpr int VERBOSITY_NAME(VALIDATOR_WARNING) = verbosity_WARNING;
constexpr int VERBOSITY_NAME(VALIDATOR_NOTICE) = verbosity_INFO;
constexpr int VERBOSITY_NAME(VALIDATOR_INFO) = verbosity_DEBUG;
constexpr int VERBOSITY_NAME(VALIDATOR_DEBUG) = verbosity_DEBUG;
constexpr int VERBOSITY_NAME(VALIDATOR_EXTRA_DEBUG) = verbosity_DEBUG + 1;
struct CandidateReject {
std::string reason;
td::BufferSlice proof;
};
struct AsyncSerializerState {
BlockIdExt last_block_id;
BlockIdExt last_written_block_id;
UnixTime last_written_block_ts;
};
struct CollationStats {
td::uint32 actual_bytes = 0, actual_collated_data_bytes = 0;
td::uint32 estimated_bytes = 0, gas = 0, lt_delta = 0, estimated_collated_data_bytes = 0;
int cat_bytes = 0, cat_gas = 0, cat_lt_delta = 0, cat_collated_data_bytes = 0;
std::string limits_log;
td::uint32 ext_msgs_total = 0;
td::uint32 ext_msgs_filtered = 0;
td::uint32 ext_msgs_accepted = 0;
td::uint32 ext_msgs_rejected = 0;
double work_time = 0.0, cpu_work_time = 0.0;
td::uint32 serialized_size = 0, serialized_size_no_collated_data = 0;
tl_object_ptr tl() const {
return create_tl_object(
actual_bytes, actual_collated_data_bytes, estimated_bytes, gas, lt_delta, estimated_collated_data_bytes,
cat_bytes, cat_gas, cat_lt_delta, cat_collated_data_bytes, limits_log, ext_msgs_total, ext_msgs_filtered,
ext_msgs_accepted, ext_msgs_rejected, work_time, cpu_work_time, serialized_size,
serialized_size_no_collated_data);
}
};
using ValidateCandidateResult = td::Variant;
class ValidatorManager : public ValidatorManagerInterface {
public:
virtual void init_last_masterchain_state(td::Ref state) {
}
virtual void set_block_state(BlockHandle handle, td::Ref state,
td::Promise> promise) = 0;
virtual void get_cell_db_reader(td::Promise> promise) = 0;
virtual void store_persistent_state_file(BlockIdExt block_id, BlockIdExt masterchain_block_id, td::BufferSlice state,
td::Promise promise) = 0;
virtual void store_persistent_state_file_gen(BlockIdExt block_id, BlockIdExt masterchain_block_id,
std::function write_data,
td::Promise promise) = 0;
virtual void store_zero_state_file(BlockIdExt block_id, td::BufferSlice state, td::Promise promise) = 0;
virtual void set_block_data(BlockHandle handle, td::Ref data, td::Promise promise) = 0;
virtual void wait_block_data(BlockHandle handle, td::uint32 priority, td::Timestamp,
td::Promise> promise) = 0;
virtual void wait_block_data_short(BlockIdExt block_id, td::uint32 priority, td::Timestamp,
td::Promise> promise) = 0;
virtual void set_block_proof(BlockHandle handle, td::Ref proof, td::Promise promise) = 0;
virtual void wait_block_proof(BlockHandle handle, td::Timestamp timeout, td::Promise> promise) = 0;
virtual void wait_block_proof_short(BlockIdExt id, td::Timestamp timeout, td::Promise> promise) = 0;
virtual void set_block_proof_link(BlockHandle handle, td::Ref proof, td::Promise promise) = 0;
virtual void wait_block_proof_link(BlockHandle handle, td::Timestamp timeout,
td::Promise> promise) = 0;
virtual void wait_block_proof_link_short(BlockIdExt id, td::Timestamp timeout,
td::Promise> promise) = 0;
virtual void set_block_signatures(BlockHandle handle, td::Ref signatures,
td::Promise promise) = 0;
virtual void wait_block_signatures(BlockHandle handle, td::Timestamp timeout,
td::Promise> promise) = 0;
virtual void wait_block_signatures_short(BlockIdExt id, td::Timestamp timeout,
td::Promise> promise) = 0;
virtual void set_block_candidate(BlockIdExt id, BlockCandidate candidate, CatchainSeqno cc_seqno,
td::uint32 validator_set_hash, td::Promise promise) = 0;
virtual void send_block_candidate_broadcast(BlockIdExt id, CatchainSeqno cc_seqno, td::uint32 validator_set_hash,
td::BufferSlice data) = 0;
virtual void wait_block_state_merge(BlockIdExt left_id, BlockIdExt right_id, td::uint32 priority,
td::Timestamp timeout, td::Promise> promise) = 0;
virtual void wait_prev_block_state(BlockHandle handle, td::uint32 priority, td::Timestamp timeout,
td::Promise> promise) = 0;
virtual void wait_block_message_queue(BlockHandle handle, td::uint32 priority, td::Timestamp timeout,
td::Promise> promise) = 0;
virtual void wait_block_message_queue_short(BlockIdExt id, td::uint32 priority, td::Timestamp timeout,
td::Promise> promise) = 0;
virtual void get_external_messages(ShardIdFull shard,
td::Promise, int>>> promise) = 0;
virtual void get_ihr_messages(ShardIdFull shard, td::Promise>> promise) = 0;
virtual void get_shard_blocks_for_collator(BlockIdExt masterchain_block_id,
td::Promise>> promise) = 0;
virtual void complete_external_messages(std::vector to_delay,
std::vector to_delete) = 0;
virtual void complete_ihr_messages(std::vector to_delay,
std::vector to_delete) = 0;
//virtual void set_first_block(ZeroStateIdExt state, BlockIdExt block, td::Promise promise) = 0;
virtual void set_next_block(BlockIdExt prev, BlockIdExt next, td::Promise promise) = 0;
virtual void new_block(BlockHandle handle, td::Ref state, td::Promise promise) = 0;
virtual void send_get_block_request(BlockIdExt id, td::uint32 priority, td::Promise promise) = 0;
virtual void send_get_zero_state_request(BlockIdExt id, td::uint32 priority,
td::Promise promise) = 0;
virtual void send_get_persistent_state_request(BlockIdExt id, BlockIdExt masterchain_block_id, td::uint32 priority,
td::Promise promise) = 0;
virtual void send_get_block_proof_request(BlockIdExt block_id, td::uint32 priority,
td::Promise promise) = 0;
virtual void send_get_block_proof_link_request(BlockIdExt block_id, td::uint32 priority,
td::Promise promise) = 0;
virtual void send_get_next_key_blocks_request(BlockIdExt block_id, td::uint32 priority,
td::Promise> promise) = 0;
virtual void send_external_message(td::Ref message) = 0;
virtual void send_ihr_message(td::Ref message) = 0;
virtual void send_top_shard_block_description(td::Ref desc) = 0;
virtual void send_block_broadcast(BlockBroadcast broadcast, int mode) = 0;
virtual void send_validator_telemetry(PublicKeyHash key, tl_object_ptr telemetry) = 0;
virtual void send_get_out_msg_queue_proof_request(ShardIdFull dst_shard, std::vector blocks,
block::ImportedMsgQueueLimits limits,
td::Promise>> promise) = 0;
virtual void send_download_archive_request(BlockSeqno mc_seqno, ShardIdFull shard_prefix, std::string tmp_dir,
td::Timestamp timeout, td::Promise promise) = 0;
virtual void update_shard_client_state(BlockIdExt masterchain_block_id, td::Promise promise) = 0;
virtual void get_shard_client_state(bool from_db, td::Promise promise) = 0;
virtual void update_async_serializer_state(AsyncSerializerState state, td::Promise promise) = 0;
virtual void get_async_serializer_state(td::Promise promise) = 0;
virtual void try_get_static_file(FileHash file_hash, td::Promise promise) = 0;
virtual void allow_block_data_gc(BlockIdExt block_id, bool is_archive, td::Promise promise) = 0;
virtual void allow_block_state_gc(BlockIdExt block_id, td::Promise promise) = 0;
virtual void allow_zero_state_file_gc(BlockIdExt block_id, td::Promise promise) = 0;
virtual void allow_persistent_state_file_gc(BlockIdExt block_id, BlockIdExt masterchain_block_id,
td::Promise promise) = 0;
virtual void allow_block_signatures_gc(BlockIdExt block_id, td::Promise promise) = 0;
virtual void allow_block_proof_gc(BlockIdExt block_id, bool is_archive, td::Promise promise) = 0;
virtual void allow_block_proof_link_gc(BlockIdExt block_id, bool is_archive, td::Promise promise) = 0;
virtual void allow_block_candidate_gc(BlockIdExt block_id, td::Promise promise) = 0;
virtual void allow_block_info_gc(BlockIdExt block_id, td::Promise promise) = 0;
virtual void archive(BlockHandle handle, td::Promise promise) = 0;
virtual void check_is_hardfork(BlockIdExt block_id, td::Promise promise) = 0;
virtual void get_vertical_seqno(BlockSeqno seqno, td::Promise promise) = 0;
virtual void update_last_known_key_block(BlockHandle handle, bool send_request) = 0;
virtual void update_gc_block_handle(BlockHandle handle, td::Promise promise) = 0;
virtual void update_shard_client_block_handle(BlockHandle handle, td::Ref state,
td::Promise promise) = 0;
virtual void truncate(BlockSeqno seqno, ConstBlockHandle handle, td::Promise promise) = 0;
virtual void wait_shard_client_state(BlockSeqno seqno, td::Timestamp timeout, td::Promise 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 log_end_validator_group_stats(validatorsession::EndValidatorGroupStats stats) = 0;
virtual void get_block_handle_for_litequery(BlockIdExt block_id, td::Promise promise) = 0;
virtual void get_block_data_for_litequery(BlockIdExt block_id, td::Promise> promise) = 0;
virtual void get_block_state_for_litequery(BlockIdExt block_id, td::Promise> promise) = 0;
virtual void get_block_by_lt_for_litequery(AccountIdPrefixFull account, LogicalTime lt,
td::Promise promise) = 0;
virtual void get_block_by_unix_time_for_litequery(AccountIdPrefixFull account, UnixTime ts,
td::Promise promise) = 0;
virtual void get_block_by_seqno_for_litequery(AccountIdPrefixFull account, BlockSeqno seqno,
td::Promise promise) = 0;
virtual void get_block_candidate_for_litequery(PublicKey source, BlockIdExt block_id, FileHash collated_data_hash,
td::Promise promise) = 0;
virtual void get_validator_groups_info_for_litequery(
td::optional shard,
td::Promise> promise) = 0;
virtual void add_lite_query_stats(int lite_query_id) {
}
virtual void record_collate_query_stats(BlockIdExt block_id, CollationStats stats) {
}
virtual void record_validate_query_stats(BlockIdExt block_id, double work_time, double cpu_work_time) {
}
virtual void add_persistent_state_description(td::Ref desc) = 0;
static bool is_persistent_state(UnixTime ts, UnixTime prev_ts) {
return ts / (1 << 17) != prev_ts / (1 << 17);
}
static UnixTime persistent_state_ttl(UnixTime ts) {
auto x = ts / (1 << 17);
CHECK(x > 0);
auto b = td::count_trailing_zeroes32(x);
return ts + ((1 << 18) << b);
}
};
} // namespace validator
} // namespace ton