1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-03-09 15:40:10 +00:00

Accelerator, part 1 (#1119)

This commit contains some parts of https://github.com/ton-blockchain/ton/tree/accelerator
This is auxiliary code that mostly does not change node behavior.

1) Semiprivate overlays and other improvements in overlays code
2) Rename actual_min_split -> monitor_min_split, fix building shard overlays
3) Loading block candidates by block id from DB, fix accept_block after validator restart
4) Cells: ProofStorageStat and changes in CellUsageTree
5) Remove some unused code, other minor changes
This commit is contained in:
SpyCheese 2024-08-23 11:46:40 +03:00 committed by GitHub
parent 9a10f79fba
commit 908415d00b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
66 changed files with 2221 additions and 638 deletions

View file

@ -27,7 +27,6 @@ set(TON_VALIDATOR_SOURCE
block.hpp
candidates-buffer.hpp
check-proof.hpp
collate-query-impl.h
collator-impl.h
collator.h
config.hpp

View file

@ -413,7 +413,36 @@ void AcceptBlockQuery::got_block_handle(BlockHandle handle) {
: handle_->inited_proof_link())) {
finish_query();
return;
}
if (data_.is_null()) {
td::actor::send_closure(manager_, &ValidatorManager::get_candidate_data_by_block_id_from_db, id_, [SelfId = actor_id(this)](td::Result<td::BufferSlice> R) {
if (R.is_ok()) {
td::actor::send_closure(SelfId, &AcceptBlockQuery::got_block_candidate_data, R.move_as_ok());
} else {
td::actor::send_closure(SelfId, &AcceptBlockQuery::got_block_handle_cont);
}
});
} else {
got_block_handle_cont();
}
}
void AcceptBlockQuery::got_block_candidate_data(td::BufferSlice data) {
auto r_block = create_block(id_, std::move(data));
if (r_block.is_error()) {
fatal_error("invalid block candidate data in db: " + r_block.error().to_string());
return;
}
data_ = r_block.move_as_ok();
VLOG(VALIDATOR_DEBUG) << "got block candidate data from db";
if (data_.not_null() && !precheck_header()) {
fatal_error("invalid block header in AcceptBlock");
return;
}
got_block_handle_cont();
}
void AcceptBlockQuery::got_block_handle_cont() {
if (data_.not_null() && !handle_->received()) {
td::actor::send_closure(
manager_, &ValidatorManager::set_block_data, handle_, data_, [SelfId = actor_id(this)](td::Result<td::Unit> R) {

View file

@ -71,6 +71,8 @@ class AcceptBlockQuery : public td::actor::Actor {
void written_block_data();
void written_block_signatures();
void got_block_handle(BlockHandle handle);
void got_block_candidate_data(td::BufferSlice data);
void got_block_handle_cont();
void written_block_info();
void got_block_data(td::Ref<BlockData> data);
void got_prev_state(td::Ref<ShardState> state);

View file

@ -1,63 +0,0 @@
/*
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 <http://www.gnu.org/licenses/>.
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once
#include "validator/interfaces/validator-manager.h"
namespace ton {
namespace validator {
class CollateQuery : public td::actor::Actor {
public:
CollateQuery(ShardIdFull shard, td::uint32 min_ts, BlockIdExt min_masterchain_block_id, std::vector<BlockIdExt> prev,
td::Ref<ValidatorSet> validator_set, td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
td::Promise<BlockCandidate> promise);
CollateQuery(ShardIdFull shard, td::uint32 min_ts, BlockIdExt min_masterchain_block_id, ZeroStateIdExt zero_state_id,
td::Ref<ValidatorSet> validator_set, td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
td::Promise<BlockCandidate> promise);
void alarm() override;
void abort_query(td::Status reason);
void finish_query();
void start_up() override;
void got_prev_state(td::Ref<MasterchainState> state);
void written_block_data();
void written_block_collated_data();
private:
ShardIdFull shard_;
UnixTime min_ts_;
BlockIdExt min_masterchain_block_id_;
std::vector<BlockIdExt> prev_;
ZeroStateIdExt zero_state_id_;
td::Ref<ValidatorSet> validator_set_;
td::actor::ActorId<ValidatorManager> manager_;
td::Timestamp timeout_;
td::Promise<BlockCandidate> promise_;
BlockCandidate candidate_;
UnixTime ts_;
};
} // namespace validator
} // namespace ton

View file

@ -65,7 +65,6 @@ class Collator final : public td::actor::Actor {
bool libraries_changed_{false};
bool prev_key_block_exists_{false};
bool is_hardfork_{false};
UnixTime min_ts;
BlockIdExt min_mc_block_id;
std::vector<BlockIdExt> prev_blocks;
std::vector<Ref<ShardState>> prev_states;
@ -89,10 +88,9 @@ class Collator final : public td::actor::Actor {
static constexpr bool shard_splitting_enabled = true;
public:
Collator(ShardIdFull shard, bool is_hardfork, td::uint32 min_ts, BlockIdExt min_masterchain_block_id,
std::vector<BlockIdExt> prev, Ref<ValidatorSet> validator_set, Ed25519_PublicKey collator_id,
Ref<CollatorOptions> collator_opts, td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
td::Promise<BlockCandidate> promise);
Collator(ShardIdFull shard, bool is_hardfork, BlockIdExt min_masterchain_block_id, std::vector<BlockIdExt> prev,
Ref<ValidatorSet> validator_set, Ed25519_PublicKey collator_id, Ref<CollatorOptions> collator_opts,
td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout, td::Promise<BlockCandidate> promise);
~Collator() override = default;
bool is_busy() const {
return busy_;

View file

@ -1,7 +1,7 @@
/*
This file is part of TON Blockchain Library.
This file is part of TON Blockchain Library.
TON Blockchain Library is free software: you can redistribute it and/or modify
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.
@ -66,7 +66,6 @@ static inline bool dbg(int c) {
*
* @param shard The shard of the new block.
* @param is_hardfork A boolean indicating whether the new block is a hardfork.
* @param min_ts The minimum UnixTime for the new block.
* @param min_masterchain_block_id The the minimum reference masterchain block.
* @param prev A vector of BlockIdExt representing the previous blocks.
* @param validator_set A reference to the ValidatorSet.
@ -76,13 +75,12 @@ static inline bool dbg(int c) {
* @param timeout The timeout for the collator.
* @param promise The promise to return the result.
*/
Collator::Collator(ShardIdFull shard, bool is_hardfork, UnixTime min_ts, BlockIdExt min_masterchain_block_id,
std::vector<BlockIdExt> prev, Ref<ValidatorSet> validator_set, Ed25519_PublicKey collator_id,
Collator::Collator(ShardIdFull shard, bool is_hardfork, BlockIdExt min_masterchain_block_id,
std::vector<BlockIdExt> prev, td::Ref<ValidatorSet> validator_set, Ed25519_PublicKey collator_id,
Ref<CollatorOptions> collator_opts, td::actor::ActorId<ValidatorManager> manager,
td::Timestamp timeout, td::Promise<BlockCandidate> promise)
: shard_(shard)
, is_hardfork_(is_hardfork)
, min_ts(min_ts)
, min_mc_block_id{min_masterchain_block_id}
, prev_blocks(std::move(prev))
, created_by_(collator_id)

View file

@ -24,26 +24,7 @@
#include "vm/cells.h"
namespace ton {
using td::Ref;
extern int collator_settings; // +1 = force want_split, +2 = force want_merge
class Collator : public td::actor::Actor {
protected:
Collator() = default;
public:
virtual ~Collator() = default;
static td::actor::ActorOwn<Collator> create_collator(
td::actor::ActorId<block::BlockDb> block_db,
ShardIdFull shard /* , td::actor::ActorId<ValidatorManager> validator_manager */);
virtual void generate_block_candidate(ShardIdFull shard, td::Promise<BlockCandidate> promise) = 0;
virtual td::Result<bool> register_external_message_cell(Ref<vm::Cell> ext_msg) = 0;
virtual td::Result<bool> register_external_message(td::Slice ext_msg_boc) = 0;
virtual td::Result<bool> register_ihr_message_cell(Ref<vm::Cell> ihr_msg) = 0;
virtual td::Result<bool> register_ihr_message(td::Slice ihr_msg_boc) = 0;
virtual td::Result<bool> register_shard_signatures_cell(Ref<vm::Cell> shard_blk_signatures) = 0;
virtual td::Result<bool> register_shard_signatures(td::Slice shard_blk_signatures_boc) = 0;
};
} // namespace ton

View file

@ -133,9 +133,9 @@ void run_accept_block_query(BlockIdExt id, td::Ref<BlockData> data, std::vector<
td::Ref<ValidatorSet> validator_set, td::Ref<BlockSignatureSet> signatures,
td::Ref<BlockSignatureSet> approve_signatures, bool send_broadcast,
td::actor::ActorId<ValidatorManager> manager, td::Promise<td::Unit> promise) {
td::actor::create_actor<AcceptBlockQuery>("accept", id, std::move(data), prev, std::move(validator_set),
std::move(signatures), std::move(approve_signatures), send_broadcast,
manager, std::move(promise))
td::actor::create_actor<AcceptBlockQuery>(PSTRING() << "accept" << id.id.to_str(), id, std::move(data), prev,
std::move(validator_set), std::move(signatures),
std::move(approve_signatures), send_broadcast, manager, std::move(promise))
.release();
}
@ -192,7 +192,7 @@ void run_check_proof_link_query(BlockIdExt id, td::Ref<ProofLink> proof, td::act
.release();
}
void run_validate_query(ShardIdFull shard, UnixTime min_ts, BlockIdExt min_masterchain_block_id,
void run_validate_query(ShardIdFull shard, BlockIdExt min_masterchain_block_id,
std::vector<BlockIdExt> prev, BlockCandidate candidate, td::Ref<ValidatorSet> validator_set,
td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
td::Promise<ValidateCandidateResult> promise, bool is_fake) {
@ -205,14 +205,14 @@ void run_validate_query(ShardIdFull shard, UnixTime min_ts, BlockIdExt min_maste
static std::atomic<size_t> idx;
td::actor::create_actor<ValidateQuery>(PSTRING() << (is_fake ? "fakevalidate" : "validateblock") << shard.to_str()
<< ":" << (seqno + 1) << "#" << idx.fetch_add(1),
shard, min_ts, min_masterchain_block_id, std::move(prev), std::move(candidate),
shard, min_masterchain_block_id, std::move(prev), std::move(candidate),
std::move(validator_set), std::move(manager), timeout, std::move(promise),
is_fake)
.release();
}
void run_collate_query(ShardIdFull shard, td::uint32 min_ts, const BlockIdExt& min_masterchain_block_id,
std::vector<BlockIdExt> prev, Ed25519_PublicKey collator_id, td::Ref<ValidatorSet> validator_set,
void run_collate_query(ShardIdFull shard, const BlockIdExt& min_masterchain_block_id, std::vector<BlockIdExt> prev,
Ed25519_PublicKey creator, td::Ref<ValidatorSet> validator_set,
td::Ref<CollatorOptions> collator_opts, td::actor::ActorId<ValidatorManager> manager,
td::Timestamp timeout, td::Promise<BlockCandidate> promise) {
BlockSeqno seqno = 0;
@ -222,9 +222,8 @@ void run_collate_query(ShardIdFull shard, td::uint32 min_ts, const BlockIdExt& m
}
}
td::actor::create_actor<Collator>(PSTRING() << "collate" << shard.to_str() << ":" << (seqno + 1), shard, false,
min_ts, min_masterchain_block_id, std::move(prev), std::move(validator_set),
collator_id, std::move(collator_opts), std::move(manager), timeout,
std::move(promise))
min_masterchain_block_id, std::move(prev), std::move(validator_set), creator,
std::move(collator_opts), std::move(manager), timeout, std::move(promise))
.release();
}
@ -237,7 +236,7 @@ void run_collate_hardfork(ShardIdFull shard, const BlockIdExt& min_masterchain_b
seqno = p.seqno();
}
}
td::actor::create_actor<Collator>(PSTRING() << "collate" << shard.to_str() << ":" << (seqno + 1), shard, true, 0,
td::actor::create_actor<Collator>(PSTRING() << "collate" << shard.to_str() << ":" << (seqno + 1), shard, true,
min_masterchain_block_id, std::move(prev), td::Ref<ValidatorSet>{},
Ed25519_PublicKey{Bits256::zero()}, td::Ref<CollatorOptions>{true},
std::move(manager), timeout, std::move(promise))

View file

@ -373,7 +373,8 @@ td::Status MasterchainStateQ::mc_init() {
td::Status MasterchainStateQ::mc_reinit() {
auto res = block::ConfigInfo::extract_config(
root_cell(), block::ConfigInfo::needStateRoot | block::ConfigInfo::needValidatorSet |
block::ConfigInfo::needShardHashes | block::ConfigInfo::needPrevBlocks);
block::ConfigInfo::needShardHashes | block::ConfigInfo::needPrevBlocks |
block::ConfigInfo::needWorkchainInfo);
cur_validators_.reset();
next_validators_.reset();
if (res.is_error()) {
@ -519,15 +520,15 @@ bool MasterchainStateQ::check_old_mc_block_id(const ton::BlockIdExt& blkid, bool
return config_ && config_->check_old_mc_block_id(blkid, strict);
}
td::uint32 MasterchainStateQ::min_split_depth(WorkchainId workchain_id) const {
td::uint32 MasterchainStateQ::monitor_min_split_depth(WorkchainId workchain_id) const {
if (!config_) {
return 0;
}
auto wc_info = config_->get_workchain_info(workchain_id);
return wc_info.not_null() ? wc_info->actual_min_split : 0;
return wc_info.not_null() ? wc_info->monitor_min_split : 0;
}
td::uint32 MasterchainStateQ::soft_min_split_depth(WorkchainId workchain_id) const {
td::uint32 MasterchainStateQ::min_split_depth(WorkchainId workchain_id) const {
if (!config_) {
return 0;
}
@ -564,5 +565,9 @@ BlockIdExt MasterchainStateQ::prev_key_block_id(BlockSeqno seqno) const {
return block_id;
}
bool MasterchainStateQ::is_key_state() const {
return config_ ? config_->is_key_state() : false;
}
} // namespace validator
} // namespace ton

View file

@ -120,8 +120,8 @@ class MasterchainStateQ : public MasterchainState, public ShardStateQ {
bool has_workchain(WorkchainId workchain) const {
return config_ && config_->has_workchain(workchain);
}
td::uint32 monitor_min_split_depth(WorkchainId workchain_id) const override;
td::uint32 min_split_depth(WorkchainId workchain_id) const override;
td::uint32 soft_min_split_depth(WorkchainId workchain_id) const override;
BlockSeqno min_ref_masterchain_seqno() const override;
td::Status prepare() override;
ZeroStateIdExt get_zerostate_id() const {
@ -137,6 +137,7 @@ class MasterchainStateQ : public MasterchainState, public ShardStateQ {
BlockIdExt last_key_block_id() const override;
BlockIdExt next_key_block_id(BlockSeqno seqno) const override;
BlockIdExt prev_key_block_id(BlockSeqno seqno) const override;
bool is_key_state() const override;
MasterchainStateQ* make_copy() const override;
static td::Result<Ref<MasterchainStateQ>> fetch(const BlockIdExt& _id, td::BufferSlice _data,

View file

@ -57,7 +57,6 @@ std::string ErrorCtx::as_string() const {
* Constructs a ValidateQuery object.
*
* @param shard The shard of the block being validated.
* @param min_ts The minimum allowed UnixTime for the block.
* @param min_masterchain_block_id The minimum allowed masterchain block reference for the block.
* @param prev A vector of BlockIdExt representing the previous blocks.
* @param candidate The BlockCandidate to be validated.
@ -67,13 +66,12 @@ std::string ErrorCtx::as_string() const {
* @param promise The Promise to return the ValidateCandidateResult to.
* @param is_fake A boolean indicating if the validation is fake (performed when creating a hardfork).
*/
ValidateQuery::ValidateQuery(ShardIdFull shard, UnixTime min_ts, BlockIdExt min_masterchain_block_id,
std::vector<BlockIdExt> prev, BlockCandidate candidate, Ref<ValidatorSet> validator_set,
ValidateQuery::ValidateQuery(ShardIdFull shard, BlockIdExt min_masterchain_block_id, std::vector<BlockIdExt> prev,
BlockCandidate candidate, Ref<ValidatorSet> validator_set,
td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
td::Promise<ValidateCandidateResult> promise, bool is_fake)
: shard_(shard)
, id_(candidate.id)
, min_ts(min_ts)
, min_mc_block_id(min_masterchain_block_id)
, prev_blocks(std::move(prev))
, block_candidate(std::move(candidate))
@ -87,7 +85,6 @@ ValidateQuery::ValidateQuery(ShardIdFull shard, UnixTime min_ts, BlockIdExt min_
, perf_timer_("validateblock", 0.1, [manager](double duration) {
send_closure(manager, &ValidatorManager::add_perf_timer_stat, "validateblock", duration);
}) {
proc_hash_.zero();
}
/**
@ -709,7 +706,7 @@ void ValidateQuery::after_get_latest_mc_state(td::Result<std::pair<Ref<Mastercha
/**
* Callback function called after retrieving the masterchain state referenced int the block.
*
*
* @param res The result of the masterchain state retrieval.
*/
void ValidateQuery::after_get_mc_state(td::Result<Ref<ShardState>> res) {
@ -1333,7 +1330,7 @@ bool ValidateQuery::compute_next_state() {
* Unpacks and merges the states of two previous blocks.
* Used if the block is after_merge.
* Similar to Collator::unpack_merge_last_state()
*
*
* @returns True if the unpacking and merging was successful, false otherwise.
*/
bool ValidateQuery::unpack_merge_prev_state() {
@ -2334,7 +2331,7 @@ bool ValidateQuery::fix_all_processed_upto() {
* Adds trivials neighbor after merging two shards.
* Trivial neighbors are the two previous blocks.
* Almost the same as in Collator.
*
*
* @returns True if the operation is successful, false otherwise.
*/
bool ValidateQuery::add_trivial_neighbor_after_merge() {
@ -2810,7 +2807,7 @@ bool ValidateQuery::precheck_one_account_update(td::ConstBitPtr acc_id, Ref<vm::
/**
* Pre-validates all account updates between the old and new state.
*
*
* @returns True if the pre-check is successful, False otherwise.
*/
bool ValidateQuery::precheck_account_updates() {
@ -3257,7 +3254,7 @@ bool ValidateQuery::precheck_one_message_queue_update(td::ConstBitPtr out_msg_id
/**
* Performs a pre-check on the difference between the old and new outbound message queues.
*
*
* @returns True if the pre-check is successful, false otherwise.
*/
bool ValidateQuery::precheck_message_queue_update() {
@ -5033,12 +5030,10 @@ bool ValidateQuery::check_in_queue() {
neighbors_.at(kv->source).blk_.to_str());
}
if (unprocessed) {
inbound_queues_empty_ = false;
return true;
}
nb_out_msgs.next();
}
inbound_queues_empty_ = true;
return true;
}
@ -5777,7 +5772,7 @@ bool ValidateQuery::scan_account_libraries(Ref<vm::Cell> orig_libs, Ref<vm::Cell
/**
* Checks if all necessary tick-tock smart contracts have been created.
* Used in masterchain validation.
*
*
* @returns True if all necessary tick-tock transactions have been created, false otherwise.
*/
bool ValidateQuery::check_all_ticktock_processed() {
@ -6919,6 +6914,7 @@ void ValidateQuery::written_candidate() {
void ValidateQuery::record_stats() {
double work_time = work_timer_.elapsed();
double cpu_work_time = cpu_work_timer_.elapsed();
LOG(WARNING) << "validation took " << perf_timer_.elapsed() << "s";
LOG(WARNING) << "Validate query work time = " << work_time << "s, cpu time = " << cpu_work_time << "s";
td::actor::send_closure(manager, &ValidatorManager::record_validate_query_stats, block_candidate.id, work_time,
cpu_work_time);

View file

@ -117,7 +117,7 @@ class ValidateQuery : public td::actor::Actor {
}
public:
ValidateQuery(ShardIdFull shard, UnixTime min_ts, BlockIdExt min_masterchain_block_id, std::vector<BlockIdExt> prev,
ValidateQuery(ShardIdFull shard, BlockIdExt min_masterchain_block_id, std::vector<BlockIdExt> prev,
BlockCandidate candidate, td::Ref<ValidatorSet> validator_set,
td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
td::Promise<ValidateCandidateResult> promise, bool is_fake = false);
@ -127,7 +127,6 @@ class ValidateQuery : public td::actor::Actor {
int pending{0};
const ShardIdFull shard_;
const BlockIdExt id_;
UnixTime min_ts;
BlockIdExt min_mc_block_id;
std::vector<BlockIdExt> prev_blocks;
std::vector<Ref<ShardState>> prev_states;
@ -224,8 +223,7 @@ class ValidateQuery : public td::actor::Actor {
td::RefInt256 import_fees_;
ton::LogicalTime proc_lt_{0}, claimed_proc_lt_{0}, min_enq_lt_{~0ULL};
ton::Bits256 proc_hash_, claimed_proc_hash_, min_enq_hash_;
bool inbound_queues_empty_{false};
ton::Bits256 proc_hash_ = ton::Bits256::zero(), claimed_proc_hash_, min_enq_hash_;
std::vector<std::tuple<Bits256, LogicalTime, LogicalTime>> msg_proc_lt_;
std::vector<std::tuple<Bits256, LogicalTime, LogicalTime>> msg_emitted_lt_;