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

Merge pull request #1530 from ton-blockchain/node-patch

Node patch
This commit is contained in:
EmelyanenkoK 2025-02-21 11:50:15 +03:00 committed by GitHub
commit 3ff951c225
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
54 changed files with 827 additions and 301 deletions

View file

@ -526,10 +526,12 @@ void CatChainReceiverImpl::start_up() {
for (td::uint32 i = 0; i < get_sources_cnt(); i++) {
root_keys.emplace(get_source(i)->get_hash(), OVERLAY_MAX_ALLOWED_PACKET_SIZE);
}
td::actor::send_closure(overlay_manager_, &overlay::Overlays::create_private_overlay,
overlay::OverlayOptions overlay_options;
overlay_options.broadcast_speed_multiplier_ = opts_.broadcast_speed_multiplier;
td::actor::send_closure(overlay_manager_, &overlay::Overlays::create_private_overlay_ex,
get_source(local_idx_)->get_adnl_id(), overlay_full_id_.clone(), std::move(ids),
make_callback(), overlay::OverlayPrivacyRules{0, 0, std::move(root_keys)},
R"({ "type": "catchain" })");
R"({ "type": "catchain" })", std::move(overlay_options));
CHECK(root_block_);

View file

@ -360,7 +360,6 @@ MsgProcessedUptoCollection::MsgProcessedUptoCollection(ton::ShardIdFull _owner,
z.shard = key.get_uint(64);
z.mc_seqno = (unsigned)((key + 64).get_uint(32));
z.last_inmsg_lt = value.write().fetch_ulong(64);
// std::cerr << "ProcessedUpto shard " << std::hex << z.shard << std::dec << std::endl;
return value.write().fetch_bits_to(z.last_inmsg_hash) && z.shard && ton::shard_contains(owner.shard, z.shard);
});
}
@ -862,8 +861,10 @@ td::Status ShardState::unpack_out_msg_queue_info(Ref<vm::Cell> out_msg_queue_inf
out_msg_queue_ =
std::make_unique<vm::AugmentedDictionary>(std::move(qinfo.out_queue), 352, block::tlb::aug_OutMsgQueue);
if (verbosity >= 3 * 1) {
LOG(DEBUG) << "unpacking ProcessedUpto of our previous block " << id_.to_str();
block::gen::t_ProcessedInfo.print(std::cerr, qinfo.proc_info);
FLOG(DEBUG) {
sb << "unpacking ProcessedUpto of our previous block " << id_.to_str();
block::gen::t_ProcessedInfo.print(sb, qinfo.proc_info);
};
}
if (!block::gen::t_ProcessedInfo.validate_csr(1024, qinfo.proc_info)) {
return td::Status::Error(

View file

@ -163,8 +163,11 @@ td::Status ConfigInfo::unpack() {
}
gen::McStateExtra::Record extra_info;
if (!tlb::unpack_cell(state_extra_root_, extra_info)) {
vm::load_cell_slice(state_extra_root_).print_rec(std::cerr);
block::gen::t_McStateExtra.print_ref(std::cerr, state_extra_root_);
FLOG(WARNING) {
sb << "state extra information is invalid: ";
vm::load_cell_slice(state_extra_root_).print_rec(sb);
block::gen::t_McStateExtra.print_ref(sb, state_extra_root_);
};
return td::Status::Error("state extra information is invalid");
}
gen::ValidatorInfo::Record validator_info;
@ -1067,7 +1070,6 @@ Ref<McShardHash> ShardConfig::get_shard_hash(ton::ShardIdFull id, bool exact) co
ton::ShardIdFull true_id;
vm::CellSlice cs;
if (get_shard_hash_raw(cs, id, true_id, exact)) {
// block::gen::t_ShardDescr.print(std::cerr, vm::CellSlice{cs});
return McShardHash::unpack(cs, true_id);
} else {
return {};
@ -1637,8 +1639,10 @@ bool ShardConfig::set_shard_info(ton::ShardIdFull shard, Ref<vm::Cell> value) {
if (!gen::t_BinTree_ShardDescr.validate_ref(1024, value)) {
LOG(ERROR) << "attempting to store an invalid (BinTree ShardDescr) at shard configuration position "
<< shard.to_str();
gen::t_BinTree_ShardDescr.print_ref(std::cerr, value);
vm::load_cell_slice(value).print_rec(std::cerr);
FLOG(WARNING) {
gen::t_BinTree_ShardDescr.print_ref(sb, value);
vm::load_cell_slice(value).print_rec(sb);
};
return false;
}
auto root = shard_hashes_dict_->lookup_ref(td::BitArray<32>{shard.workchain});

View file

@ -138,7 +138,6 @@ bool OutputQueueMerger::add_root(int src, Ref<vm::Cell> outmsg_root) {
if (outmsg_root.is_null()) {
return true;
}
//block::gen::HashmapAug{352, block::gen::t_EnqueuedMsg, block::gen::t_uint64}.print_ref(std::cerr, outmsg_root);
auto kv = std::make_unique<MsgKeyValue>(src, std::move(outmsg_root));
if (kv->replace_by_prefix(common_pfx.cbits(), common_pfx_len)) {
heap.push_back(std::move(kv));

View file

@ -446,8 +446,10 @@ bool Account::unpack(Ref<vm::CellSlice> shard_account, ton::UnixTime now, bool s
return false;
}
if (verbosity > 2) {
shard_account->print_rec(std::cerr, 2);
block::gen::t_ShardAccount.print(std::cerr, *shard_account);
FLOG(INFO) {
shard_account->print_rec(sb, 2);
block::gen::t_ShardAccount.print(sb, shard_account);
};
}
block::gen::ShardAccount::Record acc_info;
if (!(block::tlb::t_ShardAccount.validate_csr(shard_account) && tlb::unpack_exact(shard_account.write(), acc_info))) {
@ -737,9 +739,11 @@ bool Transaction::unpack_input_msg(bool ihr_delivered, const ActionPhaseConfig*
return false;
}
if (verbosity > 2) {
fprintf(stderr, "unpacking inbound message for a new transaction: ");
block::gen::t_Message_Any.print_ref(std::cerr, in_msg);
load_cell_slice(in_msg).print_rec(std::cerr);
FLOG(INFO) {
sb << "unpacking inbound message for a new transaction: ";
block::gen::t_Message_Any.print_ref(sb, in_msg);
load_cell_slice(in_msg).print_rec(sb);
};
}
auto cs = vm::load_cell_slice(in_msg);
int tag = block::gen::t_CommonMsgInfo.get_tag(cs);
@ -1550,11 +1554,13 @@ bool Transaction::run_precompiled_contract(const ComputePhaseConfig& cfg, precom
cp.actions = impl.get_c5();
int out_act_num = output_actions_count(cp.actions);
if (verbosity > 2) {
std::cerr << "new smart contract data: ";
FLOG(INFO) {
sb << "new smart contract data: ";
bool can_be_special = true;
load_cell_slice_special(cp.new_data, can_be_special).print_rec(std::cerr);
std::cerr << "output actions: ";
block::gen::OutList{out_act_num}.print_ref(std::cerr, cp.actions);
load_cell_slice_special(cp.new_data, can_be_special).print_rec(sb);
sb << "output actions: ";
block::gen::OutList{out_act_num}.print_ref(sb, cp.actions);
};
}
}
cp.mode = 0;
@ -1619,7 +1625,6 @@ bool Transaction::prepare_compute_phase(const ComputePhaseConfig& cfg) {
if (in_msg_state.not_null()) {
LOG(DEBUG) << "HASH(in_msg_state) = " << in_msg_state->get_hash().bits().to_hex(256)
<< ", account_state_hash = " << account.state_hash.to_hex();
// vm::load_cell_slice(in_msg_state).print_rec(std::cerr);
} else {
LOG(DEBUG) << "in_msg_state is null";
}
@ -1775,11 +1780,13 @@ bool Transaction::prepare_compute_phase(const ComputePhaseConfig& cfg) {
cp.actions = vm.get_committed_state().c5; // c5 -> action list
int out_act_num = output_actions_count(cp.actions);
if (verbosity > 2) {
std::cerr << "new smart contract data: ";
FLOG(INFO) {
sb << "new smart contract data: ";
bool can_be_special = true;
load_cell_slice_special(cp.new_data, can_be_special).print_rec(std::cerr);
std::cerr << "output actions: ";
block::gen::OutList{out_act_num}.print_ref(std::cerr, cp.actions);
load_cell_slice_special(cp.new_data, can_be_special).print_rec(sb);
sb << "output actions: ";
block::gen::OutList{out_act_num}.print_ref(sb, cp.actions);
};
}
}
cp.mode = 0;
@ -2725,14 +2732,18 @@ int Transaction::try_action_send_msg(const vm::CellSlice& cs0, ActionPhase& ap,
}
if (!block::gen::t_Message_Any.validate_ref(new_msg)) {
LOG(ERROR) << "generated outbound message is not a valid (Message Any) according to automated check";
block::gen::t_Message_Any.print_ref(std::cerr, new_msg);
vm::load_cell_slice(new_msg).print_rec(std::cerr);
FLOG(INFO) {
block::gen::t_Message_Any.print_ref(sb, new_msg);
vm::load_cell_slice(new_msg).print_rec(sb);
};
collect_fine();
return -1;
}
if (verbosity > 2) {
std::cerr << "converted outbound message: ";
block::gen::t_Message_Any.print_ref(std::cerr, new_msg);
FLOG(INFO) {
sb << "converted outbound message: ";
block::gen::t_Message_Any.print_ref(sb, new_msg);
};
}
ap.msgs_created++;
@ -3045,8 +3056,10 @@ bool Transaction::prepare_bounce_phase(const ActionPhaseConfig& cfg) {
}
CHECK(cb.finalize_to(bp.out_msg));
if (verbosity > 2) {
LOG(INFO) << "generated bounced message: ";
block::gen::t_Message_Any.print_ref(std::cerr, bp.out_msg);
FLOG(INFO) {
sb << "generated bounced message: ";
block::gen::t_Message_Any.print_ref(sb, bp.out_msg);
};
}
out_msgs.push_back(bp.out_msg);
bp.ok = true;
@ -3167,11 +3180,13 @@ bool Transaction::compute_state() {
auto frozen_state = cb2.finalize();
frozen_hash = frozen_state->get_hash().bits();
if (verbosity >= 3 * 1) { // !!!DEBUG!!!
std::cerr << "freezing state of smart contract: ";
block::gen::t_StateInit.print_ref(std::cerr, frozen_state);
FLOG(INFO) {
sb << "freezing state of smart contract: ";
block::gen::t_StateInit.print_ref(sb, frozen_state);
CHECK(block::gen::t_StateInit.validate_ref(frozen_state));
CHECK(block::tlb::t_StateInit.validate_ref(frozen_state));
std::cerr << "with hash " << frozen_hash.to_hex() << std::endl;
sb << "with hash " << frozen_hash.to_hex();
};
}
}
new_code.clear();
@ -3229,8 +3244,10 @@ bool Transaction::compute_state() {
CHECK(cb.append_data_cell_bool(std::move(storage)));
new_total_state = cb.finalize();
if (verbosity > 2) {
std::cerr << "new account state: ";
block::gen::t_Account.print_ref(std::cerr, new_total_state);
FLOG(INFO) {
sb << "new account state: ";
block::gen::t_Account.print_ref(sb, new_total_state);
};
}
CHECK(block::tlb::t_Account.validate_ref(new_total_state));
return true;
@ -3322,22 +3339,28 @@ bool Transaction::serialize() {
return false;
}
if (verbosity >= 3 * 1) {
std::cerr << "new transaction: ";
block::gen::t_Transaction.print_ref(std::cerr, root);
vm::load_cell_slice(root).print_rec(std::cerr);
FLOG(INFO) {
sb << "new transaction: ";
block::gen::t_Transaction.print_ref(sb, root);
vm::load_cell_slice(root).print_rec(sb);
};
}
if (!block::gen::t_Transaction.validate_ref(4096, root)) {
LOG(ERROR) << "newly-generated transaction failed to pass automated validation:";
vm::load_cell_slice(root).print_rec(std::cerr);
block::gen::t_Transaction.print_ref(std::cerr, root);
FLOG(INFO) {
vm::load_cell_slice(root).print_rec(sb);
block::gen::t_Transaction.print_ref(sb, root);
};
root.clear();
return false;
}
if (!block::tlb::t_Transaction.validate_ref(4096, root)) {
LOG(ERROR) << "newly-generated transaction failed to pass hand-written validation:";
vm::load_cell_slice(root).print_rec(std::cerr);
block::gen::t_Transaction.print_ref(std::cerr, root);
FLOG(INFO) {
vm::load_cell_slice(root).print_rec(sb);
block::gen::t_Transaction.print_ref(sb, root);
};
root.clear();
return false;
}

View file

@ -196,6 +196,13 @@ bool TLB::print_ref(std::ostream& os, Ref<vm::Cell> cell_ref, int indent, int re
return pp.fail_unless(print_ref(pp, std::move(cell_ref)));
}
bool TLB::print_ref(td::StringBuilder& sb, Ref<vm::Cell> cell_ref, int indent, int rec_limit) const {
std::ostringstream ss;
auto result = print_ref(ss, std::move(cell_ref), indent, rec_limit);
sb << ss.str();
return result;
}
std::string TLB::as_string_skip(vm::CellSlice& cs, int indent) const {
std::ostringstream os;
print_skip(os, cs, indent);

View file

@ -246,7 +246,14 @@ class TLB {
bool print(std::ostream& os, Ref<vm::CellSlice> cs_ref, int indent = 0, int rec_limit = 0) const {
return print(os, *cs_ref, indent, rec_limit);
}
bool print(td::StringBuilder& sb, Ref<vm::CellSlice> cs_ref, int indent = 0, int rec_limit = 0) const {
std::ostringstream ss;
auto result = print(ss, *cs_ref, indent, rec_limit);
sb << ss.str();
return result;
}
bool print_ref(std::ostream& os, Ref<vm::Cell> cell_ref, int indent = 0, int rec_limit = 0) const;
bool print_ref(td::StringBuilder& sb, Ref<vm::Cell> cell_ref, int indent = 0, int rec_limit = 0) const;
bool print_ref(int rec_limit, std::ostream& os, Ref<vm::Cell> cell_ref, int indent = 0) const {
return print_ref(os, std::move(cell_ref), indent, rec_limit);
}

View file

@ -1026,6 +1026,13 @@ bool CellSlice::print_rec(std::ostream& os, int indent) const {
return print_rec(os, &limit, indent);
}
bool CellSlice::print_rec(td::StringBuilder& sb, int indent) const {
std::ostringstream ss;
auto result = print_rec(ss, indent);
sb << ss.str();
return result;
}
bool CellSlice::print_rec(int limit, std::ostream& os, int indent) const {
return print_rec(os, &limit, indent);
}

View file

@ -257,6 +257,7 @@ class CellSlice : public td::CntObject {
void dump(std::ostream& os, int level = 0, bool endl = true) const;
void dump_hex(std::ostream& os, int mode = 0, bool endl = false) const;
bool print_rec(std::ostream& os, int indent = 0) const;
bool print_rec(td::StringBuilder& sb, int indent = 0) const;
bool print_rec(std::ostream& os, int* limit, int indent = 0) const;
bool print_rec(int limit, std::ostream& os, int indent = 0) const;
void error() const {

View file

@ -32,7 +32,7 @@ void OverlayOutboundFecBroadcast::alarm() {
fec_type_.size(), flags_, std::move(X.data), X.id, fec_type_, date_);
}
alarm_timestamp() = td::Timestamp::in(0.010);
alarm_timestamp() = td::Timestamp::in(delay_);
if (seqno_ >= to_send_) {
stop();
@ -46,8 +46,9 @@ void OverlayOutboundFecBroadcast::start_up() {
OverlayOutboundFecBroadcast::OverlayOutboundFecBroadcast(td::BufferSlice data, td::uint32 flags,
td::actor::ActorId<OverlayImpl> overlay,
PublicKeyHash local_id)
PublicKeyHash local_id, double speed_multiplier)
: flags_(flags) {
delay_ /= speed_multiplier;
CHECK(data.size() <= (1 << 27));
local_id_ = local_id;
overlay_ = std::move(overlay);
@ -63,9 +64,10 @@ OverlayOutboundFecBroadcast::OverlayOutboundFecBroadcast(td::BufferSlice data, t
}
td::actor::ActorId<OverlayOutboundFecBroadcast> OverlayOutboundFecBroadcast::create(
td::BufferSlice data, td::uint32 flags, td::actor::ActorId<OverlayImpl> overlay, PublicKeyHash local_id) {
return td::actor::create_actor<OverlayOutboundFecBroadcast>(td::actor::ActorOptions().with_name("bcast"),
std::move(data), flags, overlay, local_id)
td::BufferSlice data, td::uint32 flags, td::actor::ActorId<OverlayImpl> overlay, PublicKeyHash local_id,
double speed_multiplier) {
return td::actor::create_actor<OverlayOutboundFecBroadcast>(
td::actor::ActorOptions().with_name("bcast"), std::move(data), flags, overlay, local_id, speed_multiplier)
.release();
}

View file

@ -37,6 +37,7 @@ class OverlayOutboundFecBroadcast : public td::actor::Actor {
PublicKeyHash local_id_;
Overlay::BroadcastDataHash data_hash_;
td::uint32 flags_ = 0;
double delay_ = 0.010;
td::int32 date_;
std::unique_ptr<td::fec::Encoder> encoder_;
td::actor::ActorId<OverlayImpl> overlay_;
@ -45,9 +46,9 @@ class OverlayOutboundFecBroadcast : public td::actor::Actor {
public:
static td::actor::ActorId<OverlayOutboundFecBroadcast> create(td::BufferSlice data, td::uint32 flags,
td::actor::ActorId<OverlayImpl> overlay,
PublicKeyHash local_id);
PublicKeyHash local_id, double speed_multiplier = 1.0);
OverlayOutboundFecBroadcast(td::BufferSlice data, td::uint32 flags, td::actor::ActorId<OverlayImpl> overlay,
PublicKeyHash local_id);
PublicKeyHash local_id, double speed_multiplier = 1.0);
void alarm() override;
void start_up() override;

View file

@ -63,7 +63,7 @@ td::actor::ActorOwn<Overlay> Overlay::create_private(
return td::actor::create_actor<OverlayImpl>(
overlay_actor_name(overlay_id), keyring, adnl, manager, dht_node, local_id, std::move(overlay_id),
OverlayType::FixedMemberList, std::move(nodes), std::vector<PublicKeyHash>(), OverlayMemberCertificate{},
std::move(callback), std::move(rules), std::move(scope));
std::move(callback), std::move(rules), std::move(scope), std::move(opts));
}
td::actor::ActorOwn<Overlay> Overlay::create_semiprivate(
@ -99,6 +99,7 @@ OverlayImpl::OverlayImpl(td::actor::ActorId<keyring::Keyring> keyring, td::actor
overlay_id_ = id_full_.compute_short_id();
frequent_dht_lookup_ = opts_.frequent_dht_lookup_;
peer_list_.local_member_flags_ = opts_.local_overlay_member_flags_;
opts_.broadcast_speed_multiplier_ = std::max(opts_.broadcast_speed_multiplier_, 1e-9);
VLOG(OVERLAY_INFO) << this << ": creating";
@ -490,7 +491,8 @@ void OverlayImpl::send_broadcast_fec(PublicKeyHash send_as, td::uint32 flags, td
VLOG(OVERLAY_WARNING) << "broadcast source certificate is invalid";
return;
}
OverlayOutboundFecBroadcast::create(std::move(data), flags, actor_id(this), send_as);
OverlayOutboundFecBroadcast::create(std::move(data), flags, actor_id(this), send_as,
opts_.broadcast_speed_multiplier_);
}
void OverlayImpl::print(td::StringBuilder &sb) {

View file

@ -269,6 +269,7 @@ struct OverlayOptions {
td::uint32 nodes_to_send_ = 4;
td::uint32 propagate_broadcast_to_ = 5;
td::uint32 default_permanent_members_flags_ = 0;
double broadcast_speed_multiplier_ = 1.0;
};
class Overlays : public td::actor::Actor {

View file

@ -128,6 +128,10 @@ inline Timestamp &operator+=(Timestamp &a, double b) {
return a;
}
inline double operator-(const Timestamp &a, const Timestamp &b) {
return a.at() - b.at();
}
template <class StorerT>
void store(const Timestamp &timestamp, StorerT &storer) {
storer.store_binary(timestamp.at() - Time::now() + Clocks::system());

View file

@ -264,8 +264,8 @@ class Logger {
sb_ << other;
return *this;
}
LambdaPrintHelper<td::Logger> operator<<(const LambdaPrint &) {
return LambdaPrintHelper<td::Logger>{*this};
LambdaPrintHelper<td::StringBuilder> operator<<(const LambdaPrint &) {
return LambdaPrintHelper<td::StringBuilder>{sb_};
}
MutableCSlice as_cslice() {

View file

@ -493,6 +493,7 @@ struct CatChainOptions {
td::uint64 max_block_height_coeff = 0;
bool debug_disable_db = false;
double broadcast_speed_multiplier = 1.0;
};
struct ValidatorSessionConfig {

View file

@ -1504,6 +1504,7 @@ td::Status ValidatorEngine::load_global_config() {
}
validator_options_.write().set_hardforks(std::move(h));
validator_options_.write().set_fast_state_serializer_enabled(fast_state_serializer_enabled_);
validator_options_.write().set_catchain_broadcast_speed_multiplier(broadcast_speed_multiplier_catchain_);
return td::Status::OK();
}
@ -1957,7 +1958,8 @@ void ValidatorEngine::started_overlays() {
void ValidatorEngine::start_validator() {
validator_options_.write().set_allow_blockchain_init(config_.validators.size() > 0);
validator_options_.write().set_state_serializer_enabled(config_.state_serializer_enabled);
validator_options_.write().set_state_serializer_enabled(config_.state_serializer_enabled &&
!state_serializer_disabled_flag_);
load_collator_options();
validator_manager_ = ton::validator::ValidatorManagerFactory::create(
@ -2003,9 +2005,13 @@ void ValidatorEngine::start_full_node() {
R.ensure();
td::actor::send_closure(SelfId, &ValidatorEngine::started_full_node);
});
ton::validator::fullnode::FullNodeOptions full_node_options{
.config_ = config_.full_node_config,
.public_broadcast_speed_multiplier_ = broadcast_speed_multiplier_public_,
.private_broadcast_speed_multiplier_ = broadcast_speed_multiplier_private_};
full_node_ = ton::validator::fullnode::FullNode::create(
short_id, ton::adnl::AdnlNodeIdShort{config_.full_node}, validator_options_->zero_block_id().file_hash,
config_.full_node_config, keyring_.get(), adnl_.get(), rldp_.get(), rldp2_.get(),
full_node_options, keyring_.get(), adnl_.get(), rldp_.get(), rldp2_.get(),
default_dht_node_.is_zero() ? td::actor::ActorId<ton::dht::Dht>{} : dht_nodes_[default_dht_node_].get(),
overlay_manager_.get(), validator_manager_.get(), full_node_client_.get(), db_root_, std::move(P));
for (auto &v : config_.validators) {
@ -3973,7 +3979,7 @@ void ValidatorEngine::run_control_query(ton::ton_api::engine_validator_setStateS
promise.set_value(ton::create_serialize_tl_object<ton::ton_api::engine_validator_success>());
return;
}
validator_options_.write().set_state_serializer_enabled(query.enabled_);
validator_options_.write().set_state_serializer_enabled(query.enabled_ && !state_serializer_disabled_flag_);
td::actor::send_closure(validator_manager_, &ton::validator::ValidatorManagerInterface::update_options,
validator_options_);
config_.state_serializer_enabled = query.enabled_;
@ -4556,6 +4562,47 @@ int main(int argc, char *argv[]) {
td::actor::send_closure(x, &ValidatorEngine::set_validator_telemetry_filename, s);
});
});
p.add_option(
'\0', "disable-state-serializer",
"disable persistent state serializer (similar to set-state-serializer-enabled 0 in validator console)", [&]() {
acts.push_back([&x]() { td::actor::send_closure(x, &ValidatorEngine::set_state_serializer_disabled_flag); });
});
p.add_checked_option(
'\0', "broadcast-speed-catchain",
"multiplier for broadcast speed in catchain overlays (experimental, default is 1.0, which is ~300 KB/s)",
[&](td::Slice s) -> td::Status {
auto v = td::to_double(s);
if (v <= 0.0) {
return td::Status::Error("broadcast-speed-catchain should be positive");
}
acts.push_back(
[&x, v]() { td::actor::send_closure(x, &ValidatorEngine::set_broadcast_speed_multiplier_catchain, v); });
return td::Status::OK();
});
p.add_checked_option(
'\0', "broadcast-speed-public",
"multiplier for broadcast speed in public shard overlays (experimental, default is 1.0, which is ~300 KB/s)",
[&](td::Slice s) -> td::Status {
auto v = td::to_double(s);
if (v <= 0.0) {
return td::Status::Error("broadcast-speed-public should be positive");
}
acts.push_back(
[&x, v]() { td::actor::send_closure(x, &ValidatorEngine::set_broadcast_speed_multiplier_public, v); });
return td::Status::OK();
});
p.add_checked_option(
'\0', "broadcast-speed-private",
"multiplier for broadcast speed in private block overlays (experimental, default is 1.0, which is ~300 KB/s)",
[&](td::Slice s) -> td::Status {
auto v = td::to_double(s);
if (v <= 0.0) {
return td::Status::Error("broadcast-speed-private should be positive");
}
acts.push_back(
[&x, v]() { td::actor::send_closure(x, &ValidatorEngine::set_broadcast_speed_multiplier_private, v); });
return td::Status::OK();
});
auto S = p.run(argc, argv);
if (S.is_error()) {
LOG(ERROR) << "failed to parse options: " << S.move_as_error();

View file

@ -228,6 +228,10 @@ class ValidatorEngine : public td::actor::Actor {
std::string validator_telemetry_filename_;
bool not_all_shards_ = false;
std::vector<ton::ShardIdFull> add_shard_cmds_;
bool state_serializer_disabled_flag_ = false;
double broadcast_speed_multiplier_catchain_ = 1.0;
double broadcast_speed_multiplier_public_ = 1.0;
double broadcast_speed_multiplier_private_ = 1.0;
std::set<ton::CatchainSeqno> unsafe_catchains_;
std::map<ton::BlockSeqno, std::pair<ton::CatchainSeqno, td::uint32>> unsafe_catchain_rotations_;
@ -325,6 +329,18 @@ class ValidatorEngine : public td::actor::Actor {
void add_shard_cmd(ton::ShardIdFull shard) {
add_shard_cmds_.push_back(shard);
}
void set_state_serializer_disabled_flag() {
state_serializer_disabled_flag_ = true;
}
void set_broadcast_speed_multiplier_catchain(double value) {
broadcast_speed_multiplier_catchain_ = value;
}
void set_broadcast_speed_multiplier_public(double value) {
broadcast_speed_multiplier_public_ = value;
}
void set_broadcast_speed_multiplier_private(double value) {
broadcast_speed_multiplier_private_ = value;
}
void start_up() override;
ValidatorEngine() {

View file

@ -1196,6 +1196,30 @@ void ArchiveManager::set_async_mode(bool mode, td::Promise<td::Unit> promise) {
}
}
void ArchiveManager::prepare_stats(td::Promise<std::vector<std::pair<std::string, std::string>>> promise) {
std::vector<std::pair<std::string, std::string>> stats;
{
std::map<BlockSeqno, td::uint64> states;
for (auto &[key, file] : perm_states_) {
BlockSeqno seqno = key.first;
auto r_stat = td::stat(db_root_ + "/archive/states/" + file.filename_short());
if (r_stat.is_error()) {
LOG(WARNING) << "Cannot stat persistent state file " << file.filename_short() << " : " << r_stat.move_as_error();
} else {
states[seqno] += r_stat.move_as_ok().size_;
}
}
td::StringBuilder sb;
for (auto &[seqno, size] : states) {
sb << seqno << ":" << td::format::as_size(size) << " ";
}
if (!sb.as_cslice().empty()) {
stats.emplace_back("persistent_states", sb.as_cslice().str());
}
}
promise.set_value(std::move(stats));
}
void ArchiveManager::truncate(BlockSeqno masterchain_seqno, ConstBlockHandle handle, td::Promise<td::Unit> promise) {
index_->begin_transaction().ensure();
td::MultiPromise mp;

View file

@ -81,6 +81,8 @@ class ArchiveManager : public td::actor::Actor {
cur_shard_split_depth_ = value;
}
void prepare_stats(td::Promise<std::vector<std::pair<std::string, std::string>>> promise);
static constexpr td::uint32 archive_size() {
return 20000;
}

View file

@ -158,6 +158,17 @@ void CellDbIn::start_up() {
},
td::Timestamp::now());
}
{
std::string key = "stats.last_deleted_mc_seqno", value;
auto R = cell_db_->get(td::as_slice(key), value);
R.ensure();
if (R.ok() == td::KeyValue::GetStatus::Ok) {
auto r_value = td::to_integer_safe<BlockSeqno>(value);
r_value.ensure();
last_deleted_mc_state_ = r_value.move_as_ok();
}
}
}
void CellDbIn::load_cell(RootHash hash, td::Promise<td::Ref<vm::DataCell>> promise) {
@ -452,6 +463,11 @@ void CellDbIn::gc_cont2(BlockHandle handle) {
cell_db_->erase(get_key(key_hash)).ensure();
set_block(F.prev, std::move(P));
set_block(F.next, std::move(N));
if (handle->id().is_masterchain()) {
last_deleted_mc_state_ = handle->id().seqno();
std::string key = "stats.last_deleted_mc_seqno", value = td::to_string(last_deleted_mc_state_);
cell_db_->set(td::as_slice(key), td::as_slice(value));
}
cell_db_->commit_write_batch().ensure();
alarm_timestamp() = td::Timestamp::now();
timer_write_batch.reset();
@ -475,9 +491,6 @@ void CellDbIn::gc_cont2(BlockHandle handle) {
if (!opts_->get_disable_rocksdb_stats()) {
cell_db_statistics_.gc_cell_time_.insert(timer.elapsed() * 1e6);
}
if (handle->id().is_masterchain()) {
last_deleted_mc_state_ = handle->id().seqno();
}
LOG(DEBUG) << "Deleted state " << handle->id().to_str();
timer_finish.reset();
timer_all.reset();

View file

@ -438,6 +438,7 @@ void RootDb::allow_block_gc(BlockIdExt block_id, td::Promise<bool> promise) {
void RootDb::prepare_stats(td::Promise<std::vector<std::pair<std::string, std::string>>> promise) {
auto merger = StatsMerger::create(std::move(promise));
td::actor::send_closure(cell_db_, &CellDb::prepare_stats, merger.make_promise("celldb."));
td::actor::send_closure(archive_db_, &ArchiveManager::prepare_stats, merger.make_promise("archive."));
}
void RootDb::truncate(BlockSeqno seqno, ConstBlockHandle handle, td::Promise<td::Unit> promise) {

View file

@ -38,6 +38,7 @@ DownloadShardState::DownloadShardState(BlockIdExt block_id, BlockIdExt mastercha
}
void DownloadShardState::start_up() {
status_ = ProcessStatus(manager_, "process.download_state");
alarm_timestamp() = timeout_;
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<BlockHandle> R) {
@ -81,6 +82,7 @@ void DownloadShardState::download_state() {
});
td::actor::send_closure(manager_, &ValidatorManager::send_get_block_proof_link_request, block_id_, priority_,
std::move(P));
status_.set_status(PSTRING() << block_id_.id.to_str() << " : downloading proof");
}
void DownloadShardState::downloaded_proof_link(td::BufferSlice data) {
@ -123,6 +125,7 @@ void DownloadShardState::checked_proof_link() {
td::actor::send_closure(manager_, &ValidatorManager::send_get_persistent_state_request, block_id_,
masterchain_block_id_, priority_, std::move(P));
}
status_.set_status(PSTRING() << block_id_.id.to_str() << " : downloading state");
}
void DownloadShardState::download_zero_state() {
@ -152,6 +155,7 @@ void DownloadShardState::downloaded_zero_state(td::BufferSlice data) {
}
void DownloadShardState::downloaded_shard_state(td::BufferSlice data) {
status_.set_status(PSTRING() << block_id_.id.to_str() << " : processing downloaded state");
auto S = create_shard_state(block_id_, data.clone());
if (S.is_error()) {
fail_handler(actor_id(this), S.move_as_error());
@ -174,6 +178,7 @@ void DownloadShardState::downloaded_shard_state(td::BufferSlice data) {
}
void DownloadShardState::checked_shard_state() {
status_.set_status(PSTRING() << block_id_.id.to_str() << " : storing state file");
LOG(WARNING) << "checked shard state " << block_id_.to_str();
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
R.ensure();
@ -189,6 +194,7 @@ void DownloadShardState::checked_shard_state() {
}
void DownloadShardState::written_shard_state_file() {
status_.set_status(PSTRING() << block_id_.id.to_str() << " : storing state to celldb");
LOG(WARNING) << "written shard state file " << block_id_.to_str();
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<ShardState>> R) {
R.ensure();
@ -198,6 +204,7 @@ void DownloadShardState::written_shard_state_file() {
}
void DownloadShardState::written_shard_state(td::Ref<ShardState> state) {
status_.set_status(PSTRING() << block_id_.id.to_str() << " : finishing");
state_ = std::move(state);
handle_->set_unix_time(state_->get_unix_time());
handle_->set_is_key_block(block_id_.is_masterchain());

View file

@ -19,6 +19,7 @@
#pragma once
#include "validator/interfaces/validator-manager.h"
#include "stats-provider.h"
namespace ton {
@ -67,6 +68,8 @@ class DownloadShardState : public td::actor::Actor {
td::BufferSlice data_;
td::Ref<ShardState> state_;
ProcessStatus status_;
};
} // namespace validator

View file

@ -264,8 +264,11 @@ void FullNodePrivateBlockOverlay::init() {
overlay::OverlayPrivacyRules rules{overlay::Overlays::max_fec_broadcast_size(),
overlay::CertificateFlags::AllowFec | overlay::CertificateFlags::Trusted,
{}};
td::actor::send_closure(overlays_, &overlay::Overlays::create_private_overlay, local_id_, overlay_id_full_.clone(),
nodes_, std::make_unique<Callback>(actor_id(this)), rules, R"({ "type": "private-blocks" })");
overlay::OverlayOptions overlay_options;
overlay_options.broadcast_speed_multiplier_ = opts_.private_broadcast_speed_multiplier_;
td::actor::send_closure(overlays_, &overlay::Overlays::create_private_overlay_ex, local_id_, overlay_id_full_.clone(),
nodes_, std::make_unique<Callback>(actor_id(this)), rules, R"({ "type": "private-blocks" })",
overlay_options);
td::actor::send_closure(rldp_, &rldp::Rldp::add_id, local_id_);
td::actor::send_closure(rldp2_, &rldp2::Rldp::add_id, local_id_);
@ -366,7 +369,7 @@ void FullNodeCustomOverlay::receive_broadcast(PublicKeyHash src, td::BufferSlice
}
void FullNodeCustomOverlay::send_external_message(td::BufferSlice data) {
if (!inited_ || config_.ext_messages_broadcast_disabled_) {
if (!inited_ || opts_.config_.ext_messages_broadcast_disabled_) {
return;
}
VLOG(FULL_NODE_DEBUG) << "Sending external message to custom overlay \"" << name_ << "\"";
@ -472,10 +475,13 @@ void FullNodeCustomOverlay::init() {
authorized_keys[sender.pubkey_hash()] = overlay::Overlays::max_fec_broadcast_size();
}
overlay::OverlayPrivacyRules rules{overlay::Overlays::max_fec_broadcast_size(), 0, std::move(authorized_keys)};
overlay::OverlayOptions overlay_options;
overlay_options.broadcast_speed_multiplier_ = opts_.private_broadcast_speed_multiplier_;
td::actor::send_closure(
overlays_, &overlay::Overlays::create_private_overlay, local_id_, overlay_id_full_.clone(), nodes_,
overlays_, &overlay::Overlays::create_private_overlay_ex, local_id_, overlay_id_full_.clone(), nodes_,
std::make_unique<Callback>(actor_id(this)), rules,
PSTRING() << R"({ "type": "custom-overlay", "name": ")" << td::format::Escaped{name_} << R"(" })");
PSTRING() << R"({ "type": "custom-overlay", "name": ")" << td::format::Escaped{name_} << R"(" })",
overlay_options);
td::actor::send_closure(rldp_, &rldp::Rldp::add_id, local_id_);
td::actor::send_closure(rldp2_, &rldp2::Rldp::add_id, local_id_);

View file

@ -50,14 +50,14 @@ class FullNodePrivateBlockOverlay : public td::actor::Actor {
void collect_validator_telemetry(std::string filename);
void set_config(FullNodeConfig config) {
config_ = std::move(config);
opts_.config_ = std::move(config);
}
void start_up() override;
void tear_down() override;
FullNodePrivateBlockOverlay(adnl::AdnlNodeIdShort local_id, std::vector<adnl::AdnlNodeIdShort> nodes,
FileHash zero_state_file_hash, FullNodeConfig config,
FileHash zero_state_file_hash, FullNodeOptions opts,
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<rldp2::Rldp> rldp2,
td::actor::ActorId<overlay::Overlays> overlays,
@ -66,7 +66,7 @@ class FullNodePrivateBlockOverlay : public td::actor::Actor {
: local_id_(local_id)
, nodes_(std::move(nodes))
, zero_state_file_hash_(zero_state_file_hash)
, config_(config)
, opts_(opts)
, keyring_(keyring)
, adnl_(adnl)
, rldp_(rldp)
@ -80,7 +80,7 @@ class FullNodePrivateBlockOverlay : public td::actor::Actor {
adnl::AdnlNodeIdShort local_id_;
std::vector<adnl::AdnlNodeIdShort> nodes_;
FileHash zero_state_file_hash_;
FullNodeConfig config_;
FullNodeOptions opts_;
bool enable_compression_ = true;
td::actor::ActorId<keyring::Keyring> keyring_;
@ -126,14 +126,14 @@ class FullNodeCustomOverlay : public td::actor::Actor {
td::BufferSlice data);
void set_config(FullNodeConfig config) {
config_ = std::move(config);
opts_.config_ = std::move(config);
}
void start_up() override;
void tear_down() override;
FullNodeCustomOverlay(adnl::AdnlNodeIdShort local_id, CustomOverlayParams params, FileHash zero_state_file_hash,
FullNodeConfig config, td::actor::ActorId<keyring::Keyring> keyring,
FullNodeOptions opts, td::actor::ActorId<keyring::Keyring> keyring,
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<rldp::Rldp> rldp,
td::actor::ActorId<rldp2::Rldp> rldp2, td::actor::ActorId<overlay::Overlays> overlays,
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
@ -144,7 +144,7 @@ class FullNodeCustomOverlay : public td::actor::Actor {
, msg_senders_(std::move(params.msg_senders_))
, block_senders_(std::move(params.block_senders_))
, zero_state_file_hash_(zero_state_file_hash)
, config_(config)
, opts_(opts)
, keyring_(keyring)
, adnl_(adnl)
, rldp_(rldp)
@ -161,7 +161,7 @@ class FullNodeCustomOverlay : public td::actor::Actor {
std::map<adnl::AdnlNodeIdShort, int> msg_senders_;
std::set<adnl::AdnlNodeIdShort> block_senders_;
FileHash zero_state_file_hash_;
FullNodeConfig config_;
FullNodeOptions opts_;
td::actor::ActorId<keyring::Keyring> keyring_;
td::actor::ActorId<adnl::Adnl> adnl_;

View file

@ -105,6 +105,7 @@ void FullNodeShardImpl::create_overlay() {
};
overlay::OverlayOptions opts;
opts.announce_self_ = active_;
opts.broadcast_speed_multiplier_ = opts_.public_broadcast_speed_multiplier_;
td::actor::send_closure(overlays_, &overlay::Overlays::create_public_overlay_ex, adnl_id_, overlay_id_full_.clone(),
std::make_unique<Callback>(actor_id(this)), rules_,
PSTRING() << "{ \"type\": \"shard\", \"shard_id\": " << get_shard()
@ -132,7 +133,7 @@ void FullNodeShardImpl::check_broadcast(PublicKeyHash src, td::BufferSlice broad
if (!processed_ext_msg_broadcasts_.insert(hash).second) {
return promise.set_error(td::Status::Error("duplicate external message broadcast"));
}
if (config_.ext_messages_broadcast_disabled_) {
if (opts_.config_.ext_messages_broadcast_disabled_) {
promise.set_error(td::Status::Error("rebroadcasting external messages is disabled"));
promise = [manager = validator_manager_, message = q->message_->data_.clone()](td::Result<td::Unit> R) mutable {
if (R.is_ok()) {
@ -850,7 +851,7 @@ void FullNodeShardImpl::send_ihr_message(td::BufferSlice data) {
}
void FullNodeShardImpl::send_external_message(td::BufferSlice data) {
if (config_.ext_messages_broadcast_disabled_) {
if (opts_.config_.ext_messages_broadcast_disabled_) {
return;
}
if (!client_.empty()) {
@ -1367,7 +1368,7 @@ void FullNodeShardImpl::get_stats_extra(td::Promise<std::string> promise) {
}
FullNodeShardImpl::FullNodeShardImpl(ShardIdFull shard, PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id,
FileHash zero_state_file_hash, FullNodeConfig config,
FileHash zero_state_file_hash, FullNodeOptions opts,
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<rldp2::Rldp> rldp2,
td::actor::ActorId<overlay::Overlays> overlays,
@ -1387,17 +1388,17 @@ FullNodeShardImpl::FullNodeShardImpl(ShardIdFull shard, PublicKeyHash local_id,
, client_(client)
, full_node_(full_node)
, active_(active)
, config_(config) {
, opts_(opts) {
}
td::actor::ActorOwn<FullNodeShard> FullNodeShard::create(
ShardIdFull shard, PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id, FileHash zero_state_file_hash,
FullNodeConfig config, td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
FullNodeOptions opts, td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<rldp2::Rldp> rldp2,
td::actor::ActorId<overlay::Overlays> overlays, td::actor::ActorId<ValidatorManagerInterface> validator_manager,
td::actor::ActorId<adnl::AdnlExtClient> client, td::actor::ActorId<FullNode> full_node, bool active) {
return td::actor::create_actor<FullNodeShardImpl>(PSTRING() << "tonnode" << shard.to_str(), shard, local_id, adnl_id,
zero_state_file_hash, config, keyring, adnl, rldp, rldp2, overlays,
zero_state_file_hash, opts, keyring, adnl, rldp, rldp2, overlays,
validator_manager, client, full_node, active);
}

View file

@ -76,7 +76,7 @@ class FullNodeShard : public td::actor::Actor {
static td::actor::ActorOwn<FullNodeShard> create(
ShardIdFull shard, PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id, FileHash zero_state_file_hash,
FullNodeConfig config, td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
FullNodeOptions opts, td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<rldp2::Rldp> rldp2,
td::actor::ActorId<overlay::Overlays> overlays, td::actor::ActorId<ValidatorManagerInterface> validator_manager,
td::actor::ActorId<adnl::AdnlExtClient> client, td::actor::ActorId<FullNode> full_node, bool active);

View file

@ -86,7 +86,7 @@ class FullNodeShardImpl : public FullNodeShard {
void set_active(bool active) override;
void set_config(FullNodeConfig config) override {
config_ = config;
opts_.config_ = config;
}
void try_get_next_block(td::Timestamp timestamp, td::Promise<ReceivedBlock> promise);
@ -222,7 +222,7 @@ class FullNodeShardImpl : public FullNodeShard {
}
FullNodeShardImpl(ShardIdFull shard, PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id,
FileHash zero_state_file_hash, FullNodeConfig config, td::actor::ActorId<keyring::Keyring> keyring,
FileHash zero_state_file_hash, FullNodeOptions opts, td::actor::ActorId<keyring::Keyring> keyring,
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<rldp::Rldp> rldp,
td::actor::ActorId<rldp2::Rldp> rldp2, td::actor::ActorId<overlay::Overlays> overlays,
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
@ -269,7 +269,7 @@ class FullNodeShardImpl : public FullNodeShard {
bool active_;
FullNodeConfig config_;
FullNodeOptions opts_;
std::set<td::Bits256> my_ext_msg_broadcasts_;
std::set<td::Bits256> processed_ext_msg_broadcasts_;

View file

@ -139,7 +139,7 @@ void FullNodeImpl::update_adnl_id(adnl::AdnlNodeIdShort adnl_id, td::Promise<td:
}
void FullNodeImpl::set_config(FullNodeConfig config) {
config_ = config;
opts_.config_ = config;
for (auto& s : shards_) {
if (!s.second.actor.empty()) {
td::actor::send_closure(s.second.actor, &FullNodeShard::set_config, config);
@ -256,7 +256,7 @@ void FullNodeImpl::on_new_masterchain_block(td::Ref<MasterchainState> state, std
void FullNodeImpl::update_shard_actor(ShardIdFull shard, bool active) {
ShardInfo &info = shards_[shard];
if (info.actor.empty()) {
info.actor = FullNodeShard::create(shard, local_id_, adnl_id_, zero_state_file_hash_, config_, keyring_, adnl_, rldp_,
info.actor = FullNodeShard::create(shard, local_id_, adnl_id_, zero_state_file_hash_, opts_, keyring_, adnl_, rldp_,
rldp2_, overlays_, validator_manager_, client_, actor_id(this), active);
if (!all_validators_.empty()) {
td::actor::send_closure(info.actor, &FullNodeShard::update_validators, all_validators_, sign_cert_by_);
@ -717,7 +717,7 @@ void FullNodeImpl::create_private_block_overlay(PublicKeyHash key) {
nodes.push_back(p.second);
}
private_block_overlays_[key] = td::actor::create_actor<FullNodePrivateBlockOverlay>(
"BlocksPrivateOverlay", current_validators_[key], std::move(nodes), zero_state_file_hash_, config_, keyring_,
"BlocksPrivateOverlay", current_validators_[key], std::move(nodes), zero_state_file_hash_, opts_, keyring_,
adnl_, rldp_, rldp2_, overlays_, validator_manager_, actor_id(this));
update_validator_telemetry_collector();
}
@ -735,7 +735,7 @@ void FullNodeImpl::update_custom_overlay(CustomOverlayInfo &overlay) {
old_actors.erase(it);
} else {
overlay.actors_[local_id] = td::actor::create_actor<FullNodeCustomOverlay>(
"CustomOverlay", local_id, params, zero_state_file_hash_, config_, keyring_, adnl_, rldp_, rldp2_,
"CustomOverlay", local_id, params, zero_state_file_hash_, opts_, keyring_, adnl_, rldp_, rldp2_,
overlays_, validator_manager_, actor_id(this));
}
}
@ -794,7 +794,7 @@ void FullNodeImpl::send_block_candidate_broadcast_to_custom_overlays(const Block
}
FullNodeImpl::FullNodeImpl(PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id, FileHash zero_state_file_hash,
FullNodeConfig config, td::actor::ActorId<keyring::Keyring> keyring,
FullNodeOptions opts, td::actor::ActorId<keyring::Keyring> keyring,
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<rldp::Rldp> rldp,
td::actor::ActorId<rldp2::Rldp> rldp2, td::actor::ActorId<dht::Dht> dht,
td::actor::ActorId<overlay::Overlays> overlays,
@ -814,16 +814,16 @@ FullNodeImpl::FullNodeImpl(PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id
, client_(client)
, db_root_(db_root)
, started_promise_(std::move(started_promise))
, config_(config) {
, opts_(opts) {
}
td::actor::ActorOwn<FullNode> FullNode::create(
ton::PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id, FileHash zero_state_file_hash, FullNodeConfig config,
ton::PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id, FileHash zero_state_file_hash, FullNodeOptions opts,
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<rldp2::Rldp> rldp2, td::actor::ActorId<dht::Dht> dht,
td::actor::ActorId<overlay::Overlays> overlays, td::actor::ActorId<ValidatorManagerInterface> validator_manager,
td::actor::ActorId<adnl::AdnlExtClient> client, std::string db_root, td::Promise<td::Unit> started_promise) {
return td::actor::create_actor<FullNodeImpl>("fullnode", local_id, adnl_id, zero_state_file_hash, config, keyring,
return td::actor::create_actor<FullNodeImpl>("fullnode", local_id, adnl_id, zero_state_file_hash, opts, keyring,
adnl, rldp, rldp2, dht, overlays, validator_manager, client, db_root,
std::move(started_promise));
}

View file

@ -55,6 +55,12 @@ struct FullNodeConfig {
bool ext_messages_broadcast_disabled_ = false;
};
struct FullNodeOptions {
FullNodeConfig config_;
double public_broadcast_speed_multiplier_ = 1.0;
double private_broadcast_speed_multiplier_ = 1.0;
};
struct CustomOverlayParams {
std::string name_;
std::vector<adnl::AdnlNodeIdShort> nodes_;
@ -107,7 +113,7 @@ class FullNode : public td::actor::Actor {
enum { broadcast_mode_public = 1, broadcast_mode_private_block = 2, broadcast_mode_custom = 4 };
static td::actor::ActorOwn<FullNode> create(
ton::PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id, FileHash zero_state_file_hash, FullNodeConfig config,
ton::PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id, FileHash zero_state_file_hash, FullNodeOptions opts,
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<rldp2::Rldp> rldp2, td::actor::ActorId<dht::Dht> dht,
td::actor::ActorId<overlay::Overlays> overlays, td::actor::ActorId<ValidatorManagerInterface> validator_manager,

View file

@ -98,7 +98,7 @@ class FullNodeImpl : public FullNode {
void start_up() override;
FullNodeImpl(PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id, FileHash zero_state_file_hash,
FullNodeConfig config, td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
FullNodeOptions opts, td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<rldp2::Rldp> rldp2,
td::actor::ActorId<dht::Dht> dht, td::actor::ActorId<overlay::Overlays> overlays,
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
@ -141,7 +141,7 @@ class FullNodeImpl : public FullNode {
std::set<PublicKeyHash> local_keys_;
td::Promise<td::Unit> started_promise_;
FullNodeConfig config_;
FullNodeOptions opts_;
std::map<PublicKeyHash, td::actor::ActorOwn<FullNodePrivateBlockOverlay>> private_block_overlays_;
bool broadcast_block_candidates_in_public_overlay_ = false;

View file

@ -308,8 +308,11 @@ bool AcceptBlockQuery::create_new_proof() {
}
// 10. check resulting object
if (!block::gen::t_BlockProof.validate_ref(bs_cell)) {
block::gen::t_BlockProof.print_ref(std::cerr, bs_cell);
vm::load_cell_slice(bs_cell).print_rec(std::cerr);
FLOG(WARNING) {
sb << "BlockProof object just created failed to pass automated consistency checks: ";
block::gen::t_BlockProof.print_ref(sb, bs_cell);
vm::load_cell_slice(bs_cell).print_rec(sb);
};
return fatal_error("BlockProof object just created failed to pass automated consistency checks");
}
// 11. create a proof object from this cell
@ -851,15 +854,12 @@ bool AcceptBlockQuery::create_top_shard_block_description() {
&& (root.is_null() || cb.store_ref_bool(std::move(root))) && cb.finalize_to(td_cell))) {
return fatal_error("cannot serialize ShardTopBlockDescription for the newly-accepted block "s + id_.to_str());
}
if (false) {
// debug output
std::cerr << "new ShardTopBlockDescription: ";
block::gen::t_TopBlockDescr.print_ref(std::cerr, td_cell);
vm::load_cell_slice(td_cell).print_rec(std::cerr);
}
if (!block::gen::t_TopBlockDescr.validate_ref(td_cell)) {
block::gen::t_TopBlockDescr.print_ref(std::cerr, td_cell);
vm::load_cell_slice(td_cell).print_rec(std::cerr);
FLOG(WARNING) {
sb << "just created ShardTopBlockDescription is invalid: ";
block::gen::t_TopBlockDescr.print_ref(sb, td_cell);
vm::load_cell_slice(td_cell).print_rec(sb);
};
return fatal_error("just created ShardTopBlockDescription for "s + id_.to_str() + " is invalid");
}
auto res = vm::std_boc_serialize(td_cell, 0);

View file

@ -50,7 +50,7 @@ class Collator final : public td::actor::Actor {
using LtCellRef = block::LtCellRef;
using NewOutMsg = block::NewOutMsg;
const ShardIdFull shard_;
ton::BlockId new_id;
ton::BlockId new_id{workchainInvalid, 0, 0};
bool busy_{false};
bool before_split_{false};
bool after_split_{false};

View file

@ -53,16 +53,6 @@ static constexpr int HIGH_PRIORITY_EXTERNAL = 10; // don't skip high priority e
static constexpr int MAX_ATTEMPTS = 5;
#define DBG(__n) dbg(__n)&&
#define DSTART int __dcnt = 0;
#define DEB DBG(++__dcnt)
static inline bool dbg(int c) TD_UNUSED;
static inline bool dbg(int c) {
std::cerr << '[' << (char)('0' + c / 10) << (char)('0' + c % 10) << ']';
return true;
}
/**
* Constructs a Collator object.
*
@ -362,6 +352,8 @@ bool Collator::fatal_error(td::Status error) {
attempt_idx_ + 1);
} else {
main_promise(std::move(error));
td::actor::send_closure(manager, &ValidatorManager::record_collate_query_stats, BlockIdExt{new_id, RootHash::zero(), FileHash::zero()},
work_timer_.elapsed(), cpu_work_timer_.elapsed(), td::optional<CollationStats>{});
}
busy_ = false;
}
@ -761,8 +753,6 @@ bool Collator::unpack_last_mc_state() {
<< " (upgrade validator software?)";
}
// TODO: extract start_lt and end_lt from prev_mc_block as well
// std::cerr << " block::gen::ShardState::print_ref(mc_state_root) = ";
// block::gen::t_ShardState.print_ref(std::cerr, mc_state_root, 2);
return true;
}
@ -888,8 +878,10 @@ void Collator::got_neighbor_out_queue(int i, td::Result<Ref<MessageQueue>> res)
// unpack ProcessedUpto
LOG(DEBUG) << "unpacking ProcessedUpto of neighbor " << descr.blk_.to_str();
if (verbosity >= 2) {
block::gen::t_ProcessedInfo.print(std::cerr, qinfo.proc_info);
qinfo.proc_info->print_rec(std::cerr);
FLOG(INFO) {
block::gen::t_ProcessedInfo.print(sb, qinfo.proc_info);
qinfo.proc_info->print_rec(sb);
};
}
descr.processed_upto = block::MsgProcessedUptoCollection::unpack(descr.shard(), qinfo.proc_info);
if (!descr.processed_upto) {
@ -1756,9 +1748,11 @@ bool Collator::import_new_shard_top_blocks() {
shard_conf_adjusted_ = true;
}
if (tb_act && verbosity >= 0) { // DEBUG
LOG(INFO) << "updated shard block configuration to ";
FLOG(INFO) {
sb << "updated shard block configuration to ";
auto csr = shard_conf_->get_root_csr();
block::gen::t_ShardHashes.print(std::cerr, csr.write());
block::gen::t_ShardHashes.print(sb, csr);
};
}
block::gen::ShardFeeCreated::Record fc;
if (!(tlb::csr_unpack(fees_import_dict_->get_root_extra(),
@ -2279,10 +2273,12 @@ bool Collator::dequeue_message(Ref<vm::Cell> msg_envelope, ton::LogicalTime deli
bool Collator::out_msg_queue_cleanup() {
LOG(INFO) << "cleaning outbound queue from messages already imported by neighbors";
if (verbosity >= 2) {
FLOG(INFO) {
auto rt = out_msg_queue_->get_root();
std::cerr << "old out_msg_queue is ";
block::gen::t_OutMsgQueue.print(std::cerr, *rt);
rt->print_rec(std::cerr);
sb << "old out_msg_queue is ";
block::gen::t_OutMsgQueue.print(sb, rt);
rt->print_rec(sb);
};
}
if (after_merge_) {
@ -2422,10 +2418,12 @@ bool Collator::out_msg_queue_cleanup() {
<< out_msg_queue_size_;
}
if (verbosity >= 2) {
FLOG(INFO) {
auto rt = out_msg_queue_->get_root();
std::cerr << "new out_msg_queue is ";
block::gen::t_OutMsgQueue.print(std::cerr, *rt);
rt->print_rec(std::cerr);
sb << "new out_msg_queue is ";
block::gen::t_OutMsgQueue.print(sb, rt);
rt->print_rec(sb);
};
}
return register_out_msg_queue_op(true);
}
@ -2524,19 +2522,27 @@ bool Collator::combine_account_transactions() {
auto cell = cb.finalize();
auto csr = vm::load_cell_slice_ref(cell);
if (verbosity > 2) {
std::cerr << "new AccountBlock for " << z.first.to_hex() << ": ";
block::gen::t_AccountBlock.print_ref(std::cerr, cell);
csr->print_rec(std::cerr);
FLOG(INFO) {
sb << "new AccountBlock for " << z.first.to_hex() << ": ";
block::gen::t_AccountBlock.print_ref(sb, cell);
csr->print_rec(sb);
};
}
if (!block::gen::t_AccountBlock.validate_ref(100000, cell)) {
block::gen::t_AccountBlock.print_ref(std::cerr, cell);
csr->print_rec(std::cerr);
FLOG(WARNING) {
sb << "AccountBlock failed to pass automatic validation tests: ";
block::gen::t_AccountBlock.print_ref(sb, cell);
csr->print_rec(sb);
};
return fatal_error(std::string{"new AccountBlock for "} + z.first.to_hex() +
" failed to pass automatic validation tests");
}
if (!block::tlb::t_AccountBlock.validate_ref(100000, cell)) {
block::gen::t_AccountBlock.print_ref(std::cerr, cell);
csr->print_rec(std::cerr);
FLOG(WARNING) {
sb << "AccountBlock failed to pass handwritten validation tests: ";
block::gen::t_AccountBlock.print_ref(sb, cell);
csr->print_rec(sb);
};
return fatal_error(std::string{"new AccountBlock for "} + z.first.to_hex() +
" failed to pass handwritten validation tests");
}
@ -2561,8 +2567,10 @@ bool Collator::combine_account_transactions() {
} else if (acc.status == block::Account::acc_nonexist) {
// account deleted
if (verbosity > 2) {
std::cerr << "deleting account " << acc.addr.to_hex() << " with empty new value ";
block::gen::t_Account.print_ref(std::cerr, acc.total_state);
FLOG(INFO) {
sb << "deleting account " << acc.addr.to_hex() << " with empty new value ";
block::gen::t_Account.print_ref(sb, acc.total_state);
};
}
if (account_dict->lookup_delete(acc.addr).is_null()) {
return fatal_error(std::string{"cannot delete account "} + acc.addr.to_hex() + " from ShardAccounts");
@ -2570,8 +2578,10 @@ bool Collator::combine_account_transactions() {
} else {
// existing account modified
if (verbosity > 4) {
std::cerr << "modifying account " << acc.addr.to_hex() << " to ";
block::gen::t_Account.print_ref(std::cerr, acc.total_state);
FLOG(INFO) {
sb << "modifying account " << acc.addr.to_hex() << " to ";
block::gen::t_Account.print_ref(sb, acc.total_state);
};
}
if (!(cb.store_ref_bool(acc.total_state) // account_descr$_ account:^Account
&& cb.store_bits_bool(acc.last_trans_hash_) // last_trans_hash:bits256
@ -2594,9 +2604,11 @@ bool Collator::combine_account_transactions() {
return fatal_error("cannot serialize ShardAccountBlocks");
}
if (verbosity > 2) {
std::cerr << "new ShardAccountBlocks: ";
block::gen::t_ShardAccountBlocks.print_ref(std::cerr, shard_account_blocks_);
vm::load_cell_slice(shard_account_blocks_).print_rec(std::cerr);
FLOG(INFO) {
sb << "new ShardAccountBlocks: ";
block::gen::t_ShardAccountBlocks.print_ref(sb, shard_account_blocks_);
vm::load_cell_slice(shard_account_blocks_).print_rec(sb);
};
}
if (!block::gen::t_ShardAccountBlocks.validate_ref(100000, shard_account_blocks_)) {
return fatal_error("new ShardAccountBlocks failed to pass automatic validity tests");
@ -2606,9 +2618,11 @@ bool Collator::combine_account_transactions() {
}
auto shard_accounts = account_dict->get_root();
if (verbosity > 2) {
std::cerr << "new ShardAccounts: ";
block::gen::t_ShardAccounts.print(std::cerr, *shard_accounts);
shard_accounts->print_rec(std::cerr);
FLOG(INFO) {
sb << "new ShardAccounts: ";
block::gen::t_ShardAccounts.print(sb, shard_accounts);
shard_accounts->print_rec(sb);
};
}
if (verify >= 2) {
LOG(INFO) << "verifying new ShardAccounts";
@ -2659,7 +2673,9 @@ bool Collator::create_special_transaction(block::CurrencyCollection amount, Ref<
addr.to_hex());
}
if (verbosity >= 4) {
block::gen::t_Message_Any.print_ref(std::cerr, msg);
FLOG(INFO) {
block::gen::t_Message_Any.print_ref(sb, msg);
};
}
CHECK(block::gen::t_Message_Any.validate_ref(msg));
CHECK(block::tlb::t_Message.validate_ref(msg));
@ -3163,8 +3179,10 @@ int Collator::process_one_new_message(block::NewOutMsg msg, bool enqueue_only, R
Ref<vm::Cell> msg_env;
CHECK(block::tlb::pack_cell(msg_env, msg_env_rec));
if (verbosity > 2) {
std::cerr << "new (processed outbound) message envelope: ";
block::gen::t_MsgEnvelope.print_ref(std::cerr, msg_env);
FLOG(INFO) {
sb << "new (processed outbound) message envelope: ";
block::gen::t_MsgEnvelope.print_ref(sb, msg_env);
};
}
// 3. create InMsg, referring to this MsgEnvelope and this Transaction
vm::CellBuilder cb;
@ -3286,16 +3304,20 @@ bool Collator::enqueue_transit_message(Ref<vm::Cell> msg, Ref<vm::Cell> old_msg_
Ref<vm::Cell> out_msg = cb.finalize();
// 4.1. insert OutMsg into OutMsgDescr
if (verbosity > 2) {
std::cerr << "OutMsg for a transit message: ";
block::gen::t_OutMsg.print_ref(std::cerr, out_msg);
FLOG(INFO) {
sb << "OutMsg for a transit message: ";
block::gen::t_OutMsg.print_ref(sb, out_msg);
};
}
if (!insert_out_msg(out_msg)) {
return fatal_error("cannot insert a new OutMsg into OutMsgDescr");
}
// 4.2. insert InMsg into InMsgDescr
if (verbosity > 2) {
std::cerr << "InMsg for a transit message: ";
block::gen::t_InMsg.print_ref(std::cerr, in_msg);
FLOG(INFO) {
sb << "InMsg for a transit message: ";
block::gen::t_InMsg.print_ref(sb, in_msg);
};
}
if (!insert_in_msg(in_msg)) {
return fatal_error("cannot insert a new InMsg into InMsgDescr");
@ -3366,7 +3388,10 @@ bool Collator::process_inbound_message(Ref<vm::CellSlice> enq_msg, ton::LogicalT
if (enq_msg.is_null() || enq_msg->size_ext() != 0x10040 ||
(enqueued_lt = enq_msg->prefetch_ulong(64)) < /* 0 */ 1 * lt) { // DEBUG
if (enq_msg.not_null()) {
block::gen::t_EnqueuedMsg.print(std::cerr, *enq_msg);
FLOG(WARNING) {
sb << "inbound internal message is not a valid EnqueuedMsg: ";
block::gen::t_EnqueuedMsg.print(sb, enq_msg);
};
}
LOG(ERROR) << "inbound internal message is not a valid EnqueuedMsg (created lt " << lt << ", enqueued "
<< enqueued_lt << ")";
@ -3590,14 +3615,18 @@ bool Collator::process_inbound_internal_messages() {
LOG(DEBUG) << "processing inbound message with (lt,hash)=(" << kv->lt << "," << kv->key.to_hex()
<< ") from neighbor #" << kv->source;
if (verbosity > 2) {
std::cerr << "inbound message: lt=" << kv->lt << " from=" << kv->source << " key=" << kv->key.to_hex() << " msg=";
block::gen::t_EnqueuedMsg.print(std::cerr, *(kv->msg));
FLOG(INFO) {
sb << "inbound message: lt=" << kv->lt << " from=" << kv->source << " key=" << kv->key.to_hex() << " msg=";
block::gen::t_EnqueuedMsg.print(sb, kv->msg);
};
}
if (!process_inbound_message(kv->msg, kv->lt, kv->key.cbits(), neighbors_.at(kv->source))) {
if (verbosity > 1) {
std::cerr << "invalid inbound message: lt=" << kv->lt << " from=" << kv->source << " key=" << kv->key.to_hex()
FLOG(INFO) {
sb << "invalid inbound message: lt=" << kv->lt << " from=" << kv->source << " key=" << kv->key.to_hex()
<< " msg=";
block::gen::t_EnqueuedMsg.print(std::cerr, *(kv->msg));
block::gen::t_EnqueuedMsg.print(sb, kv->msg);
};
}
return fatal_error("error processing inbound internal message");
}
@ -3884,7 +3913,10 @@ bool Collator::process_deferred_message(Ref<vm::CellSlice> enq_msg, StdSmcAddres
LogicalTime enqueued_lt = 0;
if (enq_msg.is_null() || enq_msg->size_ext() != 0x10040 || (enqueued_lt = enq_msg->prefetch_ulong(64)) != lt) {
if (enq_msg.not_null()) {
block::gen::t_EnqueuedMsg.print(std::cerr, *enq_msg);
FLOG(WARNING) {
sb << "internal message in DispatchQueue is not a valid EnqueuedMsg: ";
block::gen::t_EnqueuedMsg.print(sb, enq_msg);
};
}
LOG(ERROR) << "internal message in DispatchQueue is not a valid EnqueuedMsg (created lt " << lt << ", enqueued "
<< enqueued_lt << ")";
@ -3986,8 +4018,10 @@ bool Collator::process_deferred_message(Ref<vm::CellSlice> enq_msg, StdSmcAddres
*/
bool Collator::insert_in_msg(Ref<vm::Cell> in_msg) {
if (verbosity > 2) {
std::cerr << "InMsg being inserted into InMsgDescr: ";
block::gen::t_InMsg.print_ref(std::cerr, in_msg);
FLOG(INFO) {
sb << "InMsg being inserted into InMsgDescr: ";
block::gen::t_InMsg.print_ref(sb, in_msg);
};
}
auto cs = load_cell_slice(in_msg);
if (!cs.size_refs()) {
@ -4028,8 +4062,10 @@ bool Collator::insert_in_msg(Ref<vm::Cell> in_msg) {
*/
bool Collator::insert_out_msg(Ref<vm::Cell> out_msg) {
if (verbosity > 2) {
std::cerr << "OutMsg being inserted into OutMsgDescr: ";
block::gen::t_OutMsg.print_ref(std::cerr, out_msg);
FLOG(INFO) {
sb << "OutMsg being inserted into OutMsgDescr: ";
block::gen::t_OutMsg.print_ref(sb, out_msg);
};
}
auto cs = load_cell_slice(out_msg);
if (!cs.size_refs()) {
@ -4125,8 +4161,10 @@ bool Collator::enqueue_message(block::NewOutMsg msg, td::RefInt256 fwd_fees_rema
}
// 4. insert OutMsg into OutMsgDescr
if (verbosity > 2) {
std::cerr << "OutMsg for a newly-generated message: ";
block::gen::t_OutMsg.print_ref(std::cerr, out_msg);
FLOG(INFO) {
sb << "OutMsg for a newly-generated message: ";
block::gen::t_OutMsg.print_ref(sb, out_msg);
};
}
if (!insert_out_msg(out_msg)) {
return fatal_error("cannot insert a new OutMsg into OutMsgDescr");
@ -4419,9 +4457,12 @@ bool Collator::create_mc_state_extra() {
bool ignore_cfg_changes = false;
Ref<vm::Cell> cfg0;
if (!block::valid_config_data(cfg_smc_config, config_addr, true, true, old_mparams_)) {
block::gen::t_Hashmap_32_Ref_Cell.print_ref(std::cerr, cfg_smc_config);
LOG(ERROR) << "configuration smart contract "s + config_addr.to_hex() +
" contains an invalid configuration in its data, IGNORING CHANGES";
FLOG(WARNING) {
sb << "ignored configuration: ";
block::gen::t_Hashmap_32_Ref_Cell.print_ref(sb, cfg_smc_config);
};
ignore_cfg_changes = true;
} else {
cfg0 = cfg_dict.lookup_ref(td::BitArray<32>{(long long)0});
@ -4459,34 +4500,26 @@ bool Collator::create_mc_state_extra() {
return fatal_error(wset_res.move_as_error());
}
bool update_shard_cc = is_key_block_ || (now_ / ccvc.shard_cc_lifetime > prev_now_ / ccvc.shard_cc_lifetime);
// temp debug
if (verbosity >= 3 * 1) {
auto csr = shard_conf_->get_root_csr();
LOG(INFO) << "new shard configuration before post-processing is";
std::ostringstream os;
csr->print_rec(os);
block::gen::t_ShardHashes.print(os, csr.write());
LOG(INFO) << os.str();
}
// end (temp debug)
if (!update_shard_config(wset_res.move_as_ok(), ccvc, update_shard_cc)) {
auto csr = shard_conf_->get_root_csr();
if (csr.is_null()) {
LOG(WARNING) << "new shard configuration is null (!)";
} else {
LOG(WARNING) << "invalid new shard configuration is";
std::ostringstream os;
csr->print_rec(os);
block::gen::t_ShardHashes.print(os, csr.write());
LOG(WARNING) << os.str();
FLOG(WARNING) {
csr->print_rec(sb);
block::gen::t_ShardHashes.print(sb, csr);
};
}
return fatal_error("cannot post-process shard configuration");
}
// 3. save new shard_hashes
state_extra.shard_hashes = shard_conf_->get_root_csr();
if (verbosity >= 3 * 0) { // DEBUG
std::cerr << "updated shard configuration to ";
block::gen::t_ShardHashes.print(std::cerr, *state_extra.shard_hashes);
if (verbosity >= 3) {
FLOG(INFO) {
sb << "updated shard configuration to ";
block::gen::t_ShardHashes.print(sb, state_extra.shard_hashes);
};
}
if (!block::gen::t_ShardHashes.validate_upto(10000, *state_extra.shard_hashes)) {
return fatal_error("new ShardHashes is invalid");
@ -4587,13 +4620,18 @@ bool Collator::create_mc_state_extra() {
if (verify >= 2) {
LOG(INFO) << "verifying new BlockCreateStats";
if (!block::gen::t_BlockCreateStats.validate_csr(100000, cs)) {
cs->print_rec(std::cerr);
block::gen::t_BlockCreateStats.print(std::cerr, *cs);
FLOG(WARNING) {
sb << "BlockCreateStats in the new masterchain state failed to pass automated validity checks: ";
cs->print_rec(sb);
block::gen::t_BlockCreateStats.print(sb, cs);
};
return fatal_error("BlockCreateStats in the new masterchain state failed to pass automated validity checks");
}
}
if (verbosity >= 4 * 1) {
block::gen::t_BlockCreateStats.print(std::cerr, *cs);
FLOG(INFO) {
block::gen::t_BlockCreateStats.print(sb, cs);
};
}
} else {
state_extra.r1.block_create_stats.clear();
@ -4628,7 +4666,6 @@ bool Collator::update_block_creator_count(td::ConstBitPtr key, unsigned shard_in
if (!block::unpack_CreatorStats(std::move(cs), mc_cnt, shard_cnt)) {
return fatal_error("cannot unpack CreatorStats for "s + key.to_hex(256) + " from previous masterchain state");
}
// std::cerr << mc_cnt.to_str() << " " << shard_cnt.to_str() << std::endl;
if (mc_incr && !mc_cnt.increase_by(mc_incr, now_)) {
return fatal_error(PSTRING() << "cannot increase masterchain block counter in CreatorStats for " << key.to_hex(256)
<< " by " << mc_incr << " (old value is " << mc_cnt.to_str() << ")");
@ -4999,9 +5036,11 @@ bool Collator::update_public_libraries() {
}
}
if (libraries_changed_ && verbosity >= 2) {
std::cerr << "New public libraries: ";
block::gen::t_HashmapE_256_LibDescr.print(std::cerr, shard_libraries_->get_root());
shard_libraries_->get_root()->print_rec(std::cerr);
FLOG(INFO) {
sb << "New public libraries: ";
block::gen::t_HashmapE_256_LibDescr.print(sb, shard_libraries_->get_root());
shard_libraries_->get_root()->print_rec(sb);
};
}
return true;
}
@ -5124,9 +5163,11 @@ bool Collator::create_shard_state() {
}
LOG(DEBUG) << "min_ref_mc_seqno is " << min_ref_mc_seqno_;
if (verbosity > 2) {
std::cerr << "new ShardState: ";
block::gen::t_ShardState.print_ref(std::cerr, state_root);
vm::load_cell_slice(state_root).print_rec(std::cerr);
FLOG(INFO) {
sb << "new ShardState: ";
block::gen::t_ShardState.print_ref(sb, state_root);
vm::load_cell_slice(state_root).print_rec(sb);
};
}
if (verify >= 2) {
LOG(INFO) << "verifying new ShardState";
@ -5139,9 +5180,11 @@ bool Collator::create_shard_state() {
return fatal_error("cannot create Merkle update for ShardState");
}
if (verbosity > 2) {
std::cerr << "Merkle Update for ShardState: ";
FLOG(INFO) {
sb << "Merkle Update for ShardState: ";
vm::CellSlice cs{vm::NoVm{}, state_update};
cs.print_rec(std::cerr);
cs.print_rec(sb);
};
}
LOG(INFO) << "updating block profile statistics";
block_limit_status_->add_proof(state_root);
@ -5186,10 +5229,12 @@ bool Collator::update_processed_upto() {
*/
bool Collator::compute_out_msg_queue_info(Ref<vm::Cell>& out_msg_queue_info) {
if (verbosity >= 2) {
FLOG(INFO) {
auto rt = out_msg_queue_->get_root();
std::cerr << "resulting out_msg_queue is ";
block::gen::t_OutMsgQueue.print(std::cerr, *rt);
rt->print_rec(std::cerr);
sb << "resulting out_msg_queue is ";
block::gen::t_OutMsgQueue.print(sb, rt);
rt->print_rec(sb);
};
}
vm::CellBuilder cb;
// out_msg_queue_extra#0 dispatch_queue:DispatchQueue out_queue_size:(Maybe uint48) = OutMsgQueueExtra;
@ -5239,8 +5284,10 @@ bool Collator::compute_total_balance() {
}
vm::CellSlice cs{*(in_msg_dict->get_root_extra())};
if (verbosity > 2) {
block::gen::t_ImportFees.print(std::cerr, vm::CellSlice{*(in_msg_dict->get_root_extra())});
cs.print_rec(std::cerr);
FLOG(INFO) {
block::gen::t_ImportFees.print(sb, in_msg_dict->get_root_extra());
cs.print_rec(sb);
};
}
auto new_import_fees = block::tlb::t_Grams.as_integer_skip(cs);
if (new_import_fees.is_null()) {
@ -5468,9 +5515,11 @@ bool Collator::create_block() {
return fatal_error("cannot create new Block");
}
if (verbosity >= 3 * 1) {
std::cerr << "new Block: ";
block::gen::t_Block.print_ref(std::cerr, new_block);
vm::load_cell_slice(new_block).print_rec(std::cerr);
FLOG(INFO) {
sb << "new Block: ";
block::gen::t_Block.print_ref(sb, new_block);
vm::load_cell_slice(new_block).print_rec(sb);
};
}
if (verify >= 1) {
LOG(INFO) << "verifying new Block";
@ -5508,9 +5557,11 @@ Ref<vm::Cell> Collator::collate_shard_block_descr_set() {
return {};
}
if (verbosity >= 4 * 1) {
std::cerr << "serialized TopBlockDescrSet for collated data is: ";
block::gen::t_TopBlockDescrSet.print_ref(std::cerr, cell);
vm::load_cell_slice(cell).print_rec(std::cerr);
FLOG(INFO) {
sb << "serialized TopBlockDescrSet for collated data is: ";
block::gen::t_TopBlockDescrSet.print_ref(sb, cell);
vm::load_cell_slice(cell).print_rec(sb);
};
}
return cell;
}
@ -5717,8 +5768,10 @@ td::Result<bool> Collator::register_external_message_cell(Ref<vm::Cell> ext_msg,
return td::Status::Error("inbound external message has destination address not in this shard");
}
if (verbosity > 2) {
std::cerr << "registered external message: ";
block::gen::t_Message_Any.print_ref(std::cerr, ext_msg);
FLOG(INFO) {
sb << "registered external message: ";
block::gen::t_Message_Any.print_ref(sb, ext_msg);
};
}
ext_msg_map.emplace(hash, 1);
ext_msg_list_.push_back({std::move(ext_msg), ext_hash, priority});

View file

@ -85,19 +85,13 @@ void LiteQuery::abort_query(td::Status reason) {
if (acc_state_promise_) {
acc_state_promise_.set_error(std::move(reason));
} else if (promise_) {
td::actor::send_closure(manager_, &ValidatorManager::add_lite_query_stats, query_obj_ ? query_obj_->get_id() : 0,
false);
promise_.set_error(std::move(reason));
}
stop();
}
void LiteQuery::abort_query_ext(td::Status reason, std::string comment) {
LOG(INFO) << "aborted liteserver query: " << comment << " : " << reason.to_string();
if (promise_) {
promise_.set_error(reason.move_as_error_prefix(comment + " : "));
}
stop();
}
bool LiteQuery::fatal_error(td::Status error) {
abort_query(std::move(error));
return false;
@ -120,6 +114,8 @@ bool LiteQuery::finish_query(td::BufferSlice result, bool skip_cache_update) {
td::actor::send_closure(cache_, &LiteServerCache::update, cache_key_, result.clone());
}
if (promise_) {
td::actor::send_closure(manager_, &ValidatorManager::add_lite_query_stats, query_obj_ ? query_obj_->get_id() : 0,
true);
promise_.set_result(std::move(result));
stop();
return true;
@ -139,7 +135,6 @@ void LiteQuery::start_up() {
auto F = fetch_tl_object<ton::lite_api::Function>(query_, true);
if (F.is_error()) {
td::actor::send_closure(manager_, &ValidatorManager::add_lite_query_stats, 0); // unknown
abort_query(F.move_as_error());
return;
}
@ -192,7 +187,6 @@ bool LiteQuery::use_cache() {
}
void LiteQuery::perform() {
td::actor::send_closure(manager_, &ValidatorManager::add_lite_query_stats, query_obj_->get_id());
lite_api::downcast_call(
*query_obj_,
td::overloaded(

View file

@ -97,7 +97,6 @@ class LiteQuery : public td::actor::Actor {
bool fatal_error(std::string err_msg, int err_code = -400);
bool fatal_error(int err_code, std::string err_msg = "");
void abort_query(td::Status reason);
void abort_query_ext(td::Status reason, std::string err_msg);
bool finish_query(td::BufferSlice result, bool skip_cache_update = false);
void alarm() override;
void start_up() override;

View file

@ -42,9 +42,6 @@ td::BufferSlice BlockSignatureSetQ::serialize() const {
}
Ref<vm::Cell> root;
CHECK(serialize_to(root));
//std::cerr << "serializing BlockSignatureSet: ";
//vm::CellSlice{vm::NoVm{}, root}.print_rec(std::cerr);
//std::cerr << std::endl;
auto res = vm::std_boc_serialize(std::move(root));
LOG_CHECK(res.is_ok()) << res.move_as_error();
return res.move_as_ok();

View file

@ -175,9 +175,11 @@ td::Status ShardTopBlockDescrQ::unpack() {
block::gen::TopBlockDescr::Record rec;
if (!(block::gen::t_TopBlockDescr.force_validate_ref(root_) && tlb::unpack_cell(root_, rec) &&
block::tlb::t_BlockIdExt.unpack(rec.proof_for.write(), block_id_))) {
std::cerr << "invalid ShardTopBlockDescr: ";
block::gen::t_TopBlockDescr.print_ref(std::cerr, root_);
vm::load_cell_slice(root_).print_rec(std::cerr);
FLOG(INFO) {
sb << "invalid ShardTopBlockDescr: ";
block::gen::t_TopBlockDescr.print_ref(sb, root_);
vm::load_cell_slice(root_).print_rec(sb);
};
return td::Status::Error(-666, "Shard top block description is not a valid TopBlockDescr TL-B object");
}
LOG(DEBUG) << "unpacking a ShardTopBlockDescr for " << block_id_.to_str() << " with " << rec.len << " links";

View file

@ -115,7 +115,7 @@ bool ValidateQuery::reject_query(std::string error, td::BufferSlice reason) {
error = error_ctx() + error;
LOG(ERROR) << "REJECT: aborting validation of block candidate for " << shard_.to_str() << " : " << error;
if (main_promise) {
record_stats();
record_stats(false);
errorlog::ErrorLog::log(PSTRING() << "REJECT: aborting validation of block candidate for " << shard_.to_str()
<< " : " << error << ": data=" << block_candidate.id.file_hash.to_hex()
<< " collated_data=" << block_candidate.collated_file_hash.to_hex());
@ -153,7 +153,7 @@ bool ValidateQuery::soft_reject_query(std::string error, td::BufferSlice reason)
error = error_ctx() + error;
LOG(ERROR) << "SOFT REJECT: aborting validation of block candidate for " << shard_.to_str() << " : " << error;
if (main_promise) {
record_stats();
record_stats(false);
errorlog::ErrorLog::log(PSTRING() << "SOFT REJECT: aborting validation of block candidate for " << shard_.to_str()
<< " : " << error << ": data=" << block_candidate.id.file_hash.to_hex()
<< " collated_data=" << block_candidate.collated_file_hash.to_hex());
@ -176,7 +176,7 @@ bool ValidateQuery::fatal_error(td::Status error) {
error.ensure_error();
LOG(ERROR) << "aborting validation of block candidate for " << shard_.to_str() << " : " << error.to_string();
if (main_promise) {
record_stats();
record_stats(false);
auto c = error.code();
if (c <= -667 && c >= -670) {
errorlog::ErrorLog::log(PSTRING() << "FATAL ERROR: aborting validation of block candidate for " << shard_.to_str()
@ -234,7 +234,7 @@ bool ValidateQuery::fatal_error(std::string err_msg, int err_code) {
*/
void ValidateQuery::finish_query() {
if (main_promise) {
record_stats();
record_stats(true);
LOG(WARNING) << "validate query done";
main_promise.set_result(now_);
}
@ -1553,8 +1553,10 @@ void ValidateQuery::got_neighbor_out_queue(int i, td::Result<Ref<MessageQueue>>
// unpack ProcessedUpto
LOG(DEBUG) << "unpacking ProcessedUpto of neighbor " << descr.blk_.to_str();
if (verbosity >= 2) {
block::gen::t_ProcessedInfo.print(std::cerr, qinfo.proc_info);
qinfo.proc_info->print_rec(std::cerr);
FLOG(INFO) {
block::gen::t_ProcessedInfo.print(sb, qinfo.proc_info);
qinfo.proc_info->print_rec(sb);
};
}
descr.processed_upto = block::MsgProcessedUptoCollection::unpack(descr.shard(), qinfo.proc_info);
if (!descr.processed_upto) {
@ -2656,7 +2658,6 @@ bool ValidateQuery::unpack_precheck_value_flow(Ref<vm::Cell> value_flow_root) {
" but the sum over all accounts present in the new state is " + cc.to_str());
}
auto msg_extra = in_msg_dict_->get_root_extra();
// block::gen::t_ImportFees.print(std::cerr, msg_extra);
if (!(block::tlb::t_Grams.as_integer_skip_to(msg_extra.write(), import_fees_) && cc.unpack(std::move(msg_extra)))) {
return reject_query("cannot unpack ImportFees from the augmentation of the InMsgDescr dictionary");
}
@ -2760,20 +2761,22 @@ bool ValidateQuery::precheck_one_account_update(td::ConstBitPtr acc_id, Ref<vm::
auto acc_blk_root = account_blocks_dict_->lookup(acc_id, 256);
if (acc_blk_root.is_null()) {
if (verbosity >= 3 * 0) {
std::cerr << "state of account " << workchain() << ":" << acc_id.to_hex(256)
<< " in the old shardchain state:" << std::endl;
FLOG(INFO) {
sb << "state of account " << workchain() << ":" << acc_id.to_hex(256)
<< " in the old shardchain state:" << "\n";
if (old_value.not_null()) {
block::gen::t_ShardAccount.print(std::cerr, *old_value);
block::gen::t_ShardAccount.print(sb, old_value);
} else {
std::cerr << "<absent>" << std::endl;
sb << "<absent>" << "\n";
}
std::cerr << "state of account " << workchain() << ":" << acc_id.to_hex(256)
<< " in the new shardchain state:" << std::endl;
sb << "state of account " << workchain() << ":" << acc_id.to_hex(256)
<< " in the new shardchain state:" << "\n";
if (new_value.not_null()) {
block::gen::t_ShardAccount.print(std::cerr, *new_value);
block::gen::t_ShardAccount.print(sb, new_value);
} else {
std::cerr << "<absent>" << std::endl;
sb << "<absent>" << "\n";
}
};
}
return reject_query("the state of account "s + acc_id.to_hex(256) +
" changed in the new state with respect to the old state, but the block contains no "
@ -2931,8 +2934,6 @@ bool ValidateQuery::precheck_one_account_block(td::ConstBitPtr acc_id, Ref<vm::C
" not belonging to the block's shard " + shard_.to_str());
}
CHECK(acc_blk_root.not_null());
// acc_blk_root->print_rec(std::cerr);
// block::gen::t_AccountBlock.print(std::cerr, acc_blk_root);
block::gen::AccountBlock::Record acc_blk;
block::gen::HASH_UPDATE::Record hash_upd;
if (!(tlb::csr_unpack(acc_blk_root, acc_blk) &&
@ -3860,7 +3861,9 @@ bool ValidateQuery::check_in_msg(td::ConstBitPtr key, Ref<vm::CellSlice> in_msg)
ton::LogicalTime trans_lt;
CHECK(block::get_transaction_id(transaction, trans_addr, trans_lt));
if (dest_addr != trans_addr) {
block::gen::t_InMsg.print(std::cerr, *in_msg);
FLOG(INFO) {
block::gen::t_InMsg.print(sb, in_msg);
};
return reject_query(PSTRING() << "InMsg corresponding to inbound message with hash " << key.to_hex(256)
<< " and destination address " << dest_addr.to_hex()
<< " claims that the message is processed by transaction " << trans_lt
@ -4408,7 +4411,9 @@ bool ValidateQuery::check_out_msg(td::ConstBitPtr key, Ref<vm::CellSlice> out_ms
ton::LogicalTime trans_lt;
CHECK(block::get_transaction_id(transaction, trans_addr, trans_lt));
if (src_addr != trans_addr) {
block::gen::t_OutMsg.print(std::cerr, *out_msg);
FLOG(INFO) {
block::gen::t_OutMsg.print(sb, out_msg);
};
return reject_query(PSTRING() << "OutMsg corresponding to outbound message with hash " << key.to_hex(256)
<< " and source address " << src_addr.to_hex()
<< " claims that the message was created by transaction " << trans_lt
@ -5022,15 +5027,19 @@ bool ValidateQuery::check_in_queue() {
LOG(DEBUG) << "processing inbound message with (lt,hash)=(" << kv->lt << "," << kv->key.to_hex()
<< ") from neighbor #" << kv->source;
if (verbosity > 3) {
std::cerr << "inbound message: lt=" << kv->lt << " from=" << kv->source << " key=" << kv->key.to_hex() << " msg=";
block::gen::t_EnqueuedMsg.print(std::cerr, *(kv->msg));
FLOG(INFO) {
sb << "inbound message: lt=" << kv->lt << " from=" << kv->source << " key=" << kv->key.to_hex() << " msg=";
block::gen::t_EnqueuedMsg.print(sb, kv->msg);
};
}
bool unprocessed = false;
if (!check_neighbor_outbound_message(kv->msg, kv->lt, kv->key.cbits(), neighbors_.at(kv->source), unprocessed)) {
if (verbosity > 1) {
std::cerr << "invalid neighbor outbound message: lt=" << kv->lt << " from=" << kv->source
FLOG(INFO) {
sb << "invalid neighbor outbound message: lt=" << kv->lt << " from=" << kv->source
<< " key=" << kv->key.to_hex() << " msg=";
block::gen::t_EnqueuedMsg.print(std::cerr, *(kv->msg));
block::gen::t_EnqueuedMsg.print(sb, kv->msg);
};
}
return reject_query("error processing outbound internal message "s + kv->key.to_hex() + " of neighbor " +
neighbors_.at(kv->source).blk_.to_str());
@ -5636,10 +5645,12 @@ bool ValidateQuery::check_one_transaction(block::Account& account, ton::LogicalT
// now compare the re-created transaction with the one we have
if (trans_root2->get_hash() != trans_root->get_hash()) {
if (verbosity >= 3 * 0) {
std::cerr << "original transaction " << lt << " of " << addr.to_hex() << ": ";
block::gen::t_Transaction.print_ref(std::cerr, trans_root);
std::cerr << "re-created transaction " << lt << " of " << addr.to_hex() << ": ";
block::gen::t_Transaction.print_ref(std::cerr, trans_root2);
FLOG(INFO) {
sb << "original transaction " << lt << " of " << addr.to_hex() << ": ";
block::gen::t_Transaction.print_ref(sb, trans_root);
sb << "re-created transaction " << lt << " of " << addr.to_hex() << ": ";
block::gen::t_Transaction.print_ref(sb, trans_root2);
};
}
return reject_query(PSTRING() << "the transaction " << lt << " of " << addr.to_hex() << " has hash "
<< trans_root->get_hash().to_hex()
@ -6917,13 +6928,13 @@ void ValidateQuery::written_candidate() {
/**
* Sends validation work time to manager.
*/
void ValidateQuery::record_stats() {
void ValidateQuery::record_stats(bool success) {
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);
cpu_work_time, success);
}
} // namespace validator

View file

@ -400,7 +400,7 @@ class ValidateQuery : public td::actor::Actor {
td::Timer work_timer_{true};
td::ThreadCpuTimer cpu_work_timer_{true};
void record_stats();
void record_stats(bool success);
};
} // namespace validator

View file

@ -205,13 +205,13 @@ class ValidatorManager : public ValidatorManagerInterface {
td::optional<ShardIdFull> shard,
td::Promise<tl_object_ptr<lite_api::liteServer_nonfinal_validatorGroups>> promise) = 0;
virtual void add_lite_query_stats(int lite_query_id) {
virtual void add_lite_query_stats(int lite_query_id, bool success) {
}
virtual void record_collate_query_stats(BlockIdExt block_id, double work_time, double cpu_work_time,
CollationStats stats) {
td::optional<CollationStats> stats) {
}
virtual void record_validate_query_stats(BlockIdExt block_id, double work_time, double cpu_work_time) {
virtual void record_validate_query_stats(BlockIdExt block_id, double work_time, double cpu_work_time, bool success) {
}
virtual void add_persistent_state_description(td::Ref<PersistentStateDescription> desc) = 0;

View file

@ -32,6 +32,8 @@ namespace ton {
namespace validator {
void ValidatorManagerMasterchainReiniter::start_up() {
status_ = ProcessStatus(manager_, "process.initial_sync");
status_.set_status(PSTRING() << "starting, init block seqno " << block_id_.seqno());
LOG(INFO) << "init_block_id=" << block_id_;
CHECK(block_id_.is_masterchain());
CHECK(block_id_.id.shard == shardIdAll);
@ -58,6 +60,7 @@ void ValidatorManagerMasterchainReiniter::got_masterchain_handle(BlockHandle han
key_blocks_.push_back(handle_);
if (opts_->initial_sync_disabled()) {
status_.set_status(PSTRING() << "downloading masterchain state " << handle_->id().seqno());
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<ShardState>> R) {
R.ensure();
td::actor::send_closure(SelfId, &ValidatorManagerMasterchainReiniter::download_masterchain_state);
@ -181,6 +184,7 @@ void ValidatorManagerMasterchainReiniter::got_next_key_blocks(std::vector<BlockI
}
}
LOG(WARNING) << "last key block is " << vec[vec.size() - 1];
status_.set_status(PSTRING() << "last key block is " << vec.back().seqno());
auto s = static_cast<td::uint32>(key_blocks_.size());
key_blocks_.resize(key_blocks_.size() + vec.size(), nullptr);
@ -247,6 +251,7 @@ void ValidatorManagerMasterchainReiniter::choose_masterchain_state() {
}
void ValidatorManagerMasterchainReiniter::download_masterchain_state() {
status_.set_status(PSTRING() << "downloading masterchain state " << block_id_.seqno());
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<ShardState>> R) {
if (R.is_error()) {
LOG(WARNING) << "failed to download masterchain state: " << R.move_as_error();
@ -274,6 +279,7 @@ void ValidatorManagerMasterchainReiniter::downloaded_masterchain_state(td::Ref<S
td::actor::send_closure(SelfId, &ValidatorManagerMasterchainReiniter::downloaded_all_shards);
});
client_ = td::actor::create_actor<ShardClient>("shardclient", opts_, handle_, state_, manager_, std::move(P));
status_.set_status(PSTRING() << "downloading all shard states, mc seqno " << block_id_.seqno());
}
void ValidatorManagerMasterchainReiniter::downloaded_all_shards() {

View file

@ -27,6 +27,8 @@
#include "manager-init.h"
#include <stats-provider.h>
namespace ton {
namespace validator {
@ -77,6 +79,8 @@ class ValidatorManagerMasterchainReiniter : public td::actor::Actor {
td::uint32 pending_ = 0;
td::actor::ActorOwn<ShardClient> client_;
ProcessStatus status_;
};
class ValidatorManagerMasterchainStarter : public td::actor::Actor {

View file

@ -430,6 +430,10 @@ void ValidatorManagerImpl::add_external_message(td::Ref<ExtMessage> msg, int pri
ext_messages_hashes_[id.hash] = {priority, id};
}
void ValidatorManagerImpl::check_external_message(td::BufferSlice data, td::Promise<td::Ref<ExtMessage>> promise) {
if (!started_) {
promise.set_error(td::Status::Error(ErrorCode::notready, "node not synced"));
return;
}
auto state = do_get_last_liteserver_state();
if (state.is_null()) {
promise.set_error(td::Status::Error(ErrorCode::notready, "not ready"));
@ -451,11 +455,9 @@ void ValidatorManagerImpl::check_external_message(td::BufferSlice data, td::Prom
promise = [self = this, wc, addr, promise = std::move(promise),
SelfId = actor_id(this)](td::Result<td::Ref<ExtMessage>> R) mutable {
if (R.is_error()) {
promise.set_error(R.move_as_error());
return;
}
td::actor::send_lambda(SelfId, [=, promise = std::move(promise), message = R.move_as_ok()]() mutable {
td::actor::send_lambda(SelfId, [=, promise = std::move(promise), R = std::move(R)]() mutable {
++(R.is_ok() ? self->total_check_ext_messages_ok_ : self->total_check_ext_messages_error_);
TRY_RESULT_PROMISE(promise, message, std::move(R));
if (self->checked_ext_msg_counter_.inc_msg_count(wc, addr) > max_ext_msg_per_addr()) {
promise.set_error(
td::Status::Error(PSTRING() << "too many external messages to address " << wc << ":" << addr.to_hex()));
@ -698,10 +700,9 @@ void ValidatorManagerImpl::wait_block_state(BlockHandle handle, td::uint32 prior
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), handle](td::Result<td::Ref<ShardState>> R) {
td::actor::send_closure(SelfId, &ValidatorManagerImpl::finished_wait_state, handle, std::move(R));
});
auto id =
td::actor::create_actor<WaitBlockState>("waitstate", handle, priority, actor_id(this),
auto id = td::actor::create_actor<WaitBlockState>("waitstate", handle, priority, actor_id(this),
td::Timestamp::at(timeout.at() + 10.0), std::move(P),
get_block_persistent_state(handle->id()))
get_block_persistent_state_to_download(handle->id()))
.release();
wait_state_[handle->id()].actor_ = id;
it = wait_state_.find(handle->id());
@ -1148,8 +1149,9 @@ void ValidatorManagerImpl::finished_wait_state(BlockHandle handle, td::Result<td
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), handle](td::Result<td::Ref<ShardState>> R) {
td::actor::send_closure(SelfId, &ValidatorManagerImpl::finished_wait_state, handle, std::move(R));
});
auto id = td::actor::create_actor<WaitBlockState>("waitstate", handle, X.second, actor_id(this), X.first,
std::move(P), get_block_persistent_state(handle->id()))
auto id =
td::actor::create_actor<WaitBlockState>("waitstate", handle, X.second, actor_id(this), X.first,
std::move(P), get_block_persistent_state_to_download(handle->id()))
.release();
it->second.actor_ = id;
return;
@ -2131,7 +2133,7 @@ void ValidatorManagerImpl::update_shards() {
}
}
bool validating_masterchain = false;
active_validator_groups_master_ = active_validator_groups_shard_ = 0;
if (allow_validate_) {
for (auto &desc : new_shards) {
auto shard = desc.first;
@ -2148,9 +2150,7 @@ void ValidatorManagerImpl::update_shards() {
auto validator_id = get_validator(shard, val_set);
if (!validator_id.is_zero()) {
if (shard.is_masterchain()) {
validating_masterchain = true;
}
++(shard.is_masterchain() ? active_validator_groups_master_ : active_validator_groups_shard_);
auto val_group_id = get_validator_set_id(shard, val_set, opts_hash, key_seqno, opts);
if (force_recover) {
@ -2845,8 +2845,8 @@ void ValidatorManagerImpl::prepare_stats(td::Promise<std::vector<std::pair<std::
vec.emplace_back("knownkeymasterchainblock", last_known_key_block_handle_->id().to_str());
vec.emplace_back("rotatemasterchainblock", last_rotate_block_id_.to_str());
//vec.emplace_back("shardclientmasterchainseqno", td::to_string(min_confirmed_masterchain_seqno_));
vec.emplace_back("stateserializermasterchainseqno", td::to_string(state_serializer_masterchain_seqno_));
}
td::NamedThreadSafeCounter::get_default().for_each([&](auto key, auto value) {
vec.emplace_back("counter." + key, PSTRING() << value);
});
@ -2864,9 +2864,48 @@ void ValidatorManagerImpl::prepare_stats(td::Promise<std::vector<std::pair<std::
td::actor::send_closure(shard_client_, &ShardClient::get_processed_masterchain_block, std::move(P));
}
vec.emplace_back("start_time", td::to_string(started_at_));
for (int iter = 0; iter < 2; ++iter) {
td::StringBuilder sb;
td::uint32 total = 0;
for (const auto &p : (iter ? total_ls_queries_error_ : total_ls_queries_ok_)) {
sb << lite_query_name_by_id(p.first) << ":" << p.second << " ";
total += p.second;
}
sb << "TOTAL:" << total;
vec.emplace_back(PSTRING() << "total.ls_queries_" << (iter ? "error" : "ok"), sb.as_cslice().str());
}
vec.emplace_back("total.ext_msg_check",
PSTRING() << "ok:" << total_check_ext_messages_ok_ << " error:" << total_check_ext_messages_error_);
vec.emplace_back("total.collated_blocks.master", PSTRING() << "ok:" << total_collated_blocks_master_ok_
<< " error:" << total_collated_blocks_master_error_);
vec.emplace_back("total.collated_blocks.shard", PSTRING() << "ok:" << total_collated_blocks_shard_ok_
<< " error:" << total_collated_blocks_shard_error_);
vec.emplace_back("total.validated_blocks.master", PSTRING() << "ok:" << total_validated_blocks_master_ok_
<< " error:" << total_validated_blocks_master_error_);
vec.emplace_back("total.validated_blocks.shard", PSTRING() << "ok:" << total_validated_blocks_shard_ok_
<< " error:" << total_validated_blocks_shard_error_);
if (is_validator()) {
vec.emplace_back("active_validator_groups", PSTRING() << "master:" << active_validator_groups_master_
<< " shard:" << active_validator_groups_shard_);
}
bool serializer_enabled = opts_->get_state_serializer_enabled();
if (is_validator() && last_masterchain_state_->get_global_id() == -239) {
serializer_enabled = false;
}
vec.emplace_back("stateserializerenabled", serializer_enabled ? "true" : "false");
merger.make_promise("").set_value(std::move(vec));
if (!serializer_.empty()) {
td::actor::send_closure(serializer_, &AsyncStateSerializer::prepare_stats, merger.make_promise(""));
}
td::actor::send_closure(db_, &Db::prepare_stats, merger.make_promise("db."));
for (auto &[_, p] : stats_providers_) {
p.second(merger.make_promise(p.first));
}
}
void ValidatorManagerImpl::prepare_perf_timer_stats(td::Promise<std::vector<PerfTimerStats>> promise) {
@ -3336,11 +3375,18 @@ void ValidatorManagerImpl::got_persistent_state_descriptions(std::vector<td::Ref
}
}
td::Ref<PersistentStateDescription> ValidatorManagerImpl::get_block_persistent_state(BlockIdExt block_id) {
td::Ref<PersistentStateDescription> ValidatorManagerImpl::get_block_persistent_state_to_download(BlockIdExt block_id) {
if (block_id.is_masterchain()) {
return {};
}
auto it = persistent_state_blocks_.find(block_id);
if (it == persistent_state_blocks_.end()) {
return {};
}
if (it->second->masterchain_id.seqno() + 16 >= min_confirmed_masterchain_seqno_) {
// Do not download persistent states during ordinary shard client sync
return {};
}
return it->second;
}
@ -3353,17 +3399,28 @@ td::actor::ActorOwn<ValidatorManagerInterface> ValidatorManagerFactory::create(
}
void ValidatorManagerImpl::record_collate_query_stats(BlockIdExt block_id, double work_time, double cpu_work_time,
CollationStats stats) {
td::optional<CollationStats> stats) {
if (!stats) {
++(block_id.is_masterchain() ? total_collated_blocks_master_error_ : total_collated_blocks_shard_error_);
return;
}
auto &record = new_block_stats_record(block_id);
record.collator_work_time_ = work_time;
record.collator_cpu_work_time_ = cpu_work_time;
record.collator_stats_ = std::move(stats);
record.collator_stats_ = std::move(stats.value());
++(block_id.is_masterchain() ? total_collated_blocks_master_ok_ : total_collated_blocks_shard_ok_);
}
void ValidatorManagerImpl::record_validate_query_stats(BlockIdExt block_id, double work_time, double cpu_work_time) {
void ValidatorManagerImpl::record_validate_query_stats(BlockIdExt block_id, double work_time, double cpu_work_time,
bool success) {
auto &record = new_block_stats_record(block_id);
record.validator_work_time_ = work_time;
record.validator_cpu_work_time_ = cpu_work_time;
if (success) {
++(block_id.is_masterchain() ? total_validated_blocks_master_ok_ : total_validated_blocks_shard_ok_);
} else {
++(block_id.is_masterchain() ? total_validated_blocks_master_error_ : total_validated_blocks_shard_error_);
}
}
ValidatorManagerImpl::RecordedBlockStats &ValidatorManagerImpl::new_block_stats_record(BlockIdExt block_id) {
@ -3377,6 +3434,16 @@ ValidatorManagerImpl::RecordedBlockStats &ValidatorManagerImpl::new_block_stats_
return recorded_block_stats_[block_id];
}
void ValidatorManagerImpl::register_stats_provider(
td::uint64 idx, std::string prefix,
std::function<void(td::Promise<std::vector<std::pair<std::string, std::string>>>)> callback) {
stats_providers_[idx] = {std::move(prefix), std::move(callback)};
}
void ValidatorManagerImpl::unregister_stats_provider(td::uint64 idx) {
stats_providers_.erase(idx);
}
size_t ValidatorManagerImpl::CheckedExtMsgCounter::get_msg_count(WorkchainId wc, StdSmcAddress addr) {
before_query();
auto it1 = counter_cur_.find({wc, addr});

View file

@ -655,8 +655,9 @@ class ValidatorManagerImpl : public ValidatorManager {
td::optional<ShardIdFull> shard,
td::Promise<tl_object_ptr<lite_api::liteServer_nonfinal_validatorGroups>> promise) override;
void add_lite_query_stats(int lite_query_id) override {
void add_lite_query_stats(int lite_query_id, bool success) override {
++ls_stats_[lite_query_id];
++(success ? total_ls_queries_ok_ : total_ls_queries_error_)[lite_query_id];
}
private:
@ -733,7 +734,7 @@ class ValidatorManagerImpl : public ValidatorManager {
void got_persistent_state_descriptions(std::vector<td::Ref<PersistentStateDescription>> descs);
void add_persistent_state_description_impl(td::Ref<PersistentStateDescription> desc);
td::Ref<PersistentStateDescription> get_block_persistent_state(BlockIdExt block_id);
td::Ref<PersistentStateDescription> get_block_persistent_state_to_download(BlockIdExt block_id);
private:
bool need_monitor(ShardIdFull shard) const {
@ -747,6 +748,16 @@ class ValidatorManagerImpl : public ValidatorManager {
std::map<int, td::uint32> ls_stats_; // lite_api ID -> count, 0 for unknown
td::uint32 ls_stats_check_ext_messages_{0};
UnixTime started_at_ = (UnixTime)td::Clocks::system();
std::map<int, td::uint64> total_ls_queries_ok_, total_ls_queries_error_; // lite_api ID -> count, 0 for unknown
td::uint64 total_check_ext_messages_ok_{0}, total_check_ext_messages_error_{0};
td::uint64 total_collated_blocks_master_ok_{0}, total_collated_blocks_master_error_{0};
td::uint64 total_validated_blocks_master_ok_{0}, total_validated_blocks_master_error_{0};
td::uint64 total_collated_blocks_shard_ok_{0}, total_collated_blocks_shard_error_{0};
td::uint64 total_validated_blocks_shard_ok_{0}, total_validated_blocks_shard_error_{0};
size_t active_validator_groups_master_{0}, active_validator_groups_shard_{0};
td::actor::ActorOwn<CandidatesBuffer> candidates_buffer_;
struct RecordedBlockStats {
@ -760,16 +771,25 @@ class ValidatorManagerImpl : public ValidatorManager {
std::queue<BlockIdExt> recorded_block_stats_lru_;
void record_collate_query_stats(BlockIdExt block_id, double work_time, double cpu_work_time,
CollationStats stats) override;
void record_validate_query_stats(BlockIdExt block_id, double work_time, double cpu_work_time) override;
td::optional<CollationStats> stats) override;
void record_validate_query_stats(BlockIdExt block_id, double work_time, double cpu_work_time, bool success) override;
RecordedBlockStats &new_block_stats_record(BlockIdExt block_id);
void register_stats_provider(
td::uint64 idx, std::string prefix,
std::function<void(td::Promise<std::vector<std::pair<std::string, std::string>>>)> callback) override;
void unregister_stats_provider(td::uint64 idx) override;
std::map<PublicKeyHash, td::actor::ActorOwn<ValidatorTelemetry>> validator_telemetry_;
void init_validator_telemetry();
std::map<BlockSeqno, td::Ref<PersistentStateDescription>> persistent_state_descriptions_;
std::map<BlockIdExt, td::Ref<PersistentStateDescription>> persistent_state_blocks_;
std::map<td::uint64,
std::pair<std::string, std::function<void(td::Promise<std::vector<std::pair<std::string, std::string>>>)>>>
stats_providers_;
};
} // namespace validator

View file

@ -70,6 +70,7 @@ void DownloadState::finish_query() {
}
void DownloadState::start_up() {
status_ = ProcessStatus(validator_manager_, "process.download_state_net");
alarm_timestamp() = timeout_;
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_persistent_state, block_id_,
@ -190,6 +191,7 @@ void DownloadState::got_block_state_description(td::BufferSlice data) {
td::Timestamp::in(3.0), std::move(P));
}
}));
status_.set_status(PSTRING() << block_id_.id.to_str() << " : 0 bytes, 0B/s");
}
void DownloadState::got_block_state_part(td::BufferSlice data, td::uint32 requested_size) {
@ -198,14 +200,18 @@ void DownloadState::got_block_state_part(td::BufferSlice data, td::uint32 reques
parts_.push_back(std::move(data));
double elapsed = prev_logged_timer_.elapsed();
if (elapsed > 10.0) {
if (elapsed > 5.0) {
prev_logged_timer_ = td::Timer();
auto speed = (td::uint64)((double)(sum_ - prev_logged_sum_) / elapsed);
LOG(WARNING) << "downloading state " << block_id_.to_str() << ": " << td::format::as_size(sum_) << " ("
<< td::format::as_size((td::uint64)(double(sum_ - prev_logged_sum_) / elapsed)) << "/s)";
<< td::format::as_size(speed) << "/s)";
status_.set_status(PSTRING() << block_id_.id.to_str() << " : " << sum_ << " bytes, " << td::format::as_size(speed)
<< "/s");
prev_logged_sum_ = sum_;
}
if (last_part) {
status_.set_status(PSTRING() << block_id_.id.to_str() << " : " << sum_ << " bytes, finishing");
td::BufferSlice res{td::narrow_cast<std::size_t>(sum_)};
auto S = res.as_slice();
for (auto &p : parts_) {

View file

@ -23,6 +23,8 @@
#include "validator/validator.h"
#include "adnl/adnl-ext-client.h"
#include <stats-provider.h>
namespace ton {
namespace validator {
@ -75,6 +77,8 @@ class DownloadState : public td::actor::Actor {
td::uint64 prev_logged_sum_ = 0;
td::Timer prev_logged_timer_;
ProcessStatus status_;
};
} // namespace fullnode

View file

@ -58,6 +58,12 @@ void AsyncStateSerializer::got_self_state(AsyncSerializerState state) {
});
td::actor::send_closure(manager_, &ValidatorManager::get_block_handle, last_block_id_, true, std::move(P));
}
inited_block_id_ = true;
for (auto& promise : wait_init_block_id_) {
promise.set_value(td::Unit());
}
wait_init_block_id_.clear();
}
void AsyncStateSerializer::got_init_handle(BlockHandle handle) {
@ -186,6 +192,9 @@ void AsyncStateSerializer::next_iteration() {
td::actor::send_closure(SelfId, &AsyncStateSerializer::request_previous_state_files);
},
td::Timestamp::in(delay));
current_status_ = PSTRING() << "delay before serializing seqno=" << masterchain_handle_->id().seqno() << " "
<< (int)delay << "s";
current_status_ts_ = td::Timestamp::now();
return;
}
if (next_idx_ < shards_.size()) {
@ -379,9 +388,14 @@ void AsyncStateSerializer::got_masterchain_state(td::Ref<MasterchainState> state
td::actor::send_closure(manager_, &ValidatorManager::store_persistent_state_file_gen, masterchain_handle_->id(),
masterchain_handle_->id(), write_data, std::move(P));
current_status_ = PSTRING() << "serializing masterchain state " << state->get_block_id().id.to_str();
current_status_ts_ = td::Timestamp::now();
}
void AsyncStateSerializer::stored_masterchain_state() {
current_status_ = "pending";
current_status_ts_ = {};
LOG(ERROR) << "finished serializing masterchain state " << masterchain_handle_->id().id.to_str();
running_ = false;
next_iteration();
@ -444,9 +458,14 @@ void AsyncStateSerializer::got_shard_state(BlockHandle handle, td::Ref<ShardStat
});
td::actor::send_closure(manager_, &ValidatorManager::store_persistent_state_file_gen, handle->id(),
masterchain_handle_->id(), write_data, std::move(P));
current_status_ = PSTRING() << "serializing shard state " << next_idx_ << "/" << shards_.size() << " "
<< state->get_block_id().id.to_str();
current_status_ts_ = td::Timestamp::now();
}
void AsyncStateSerializer::fail_handler(td::Status reason) {
current_status_ = PSTRING() << "pending, " << reason;
current_status_ts_ = {};
VLOG(VALIDATOR_NOTICE) << "failure: " << reason;
attempt_++;
delay_action(
@ -460,6 +479,8 @@ void AsyncStateSerializer::fail_handler_cont() {
}
void AsyncStateSerializer::success_handler() {
current_status_ = "pending";
current_status_ts_ = {};
running_ = false;
next_iteration();
}
@ -478,6 +499,29 @@ void AsyncStateSerializer::auto_disable_serializer(bool disabled) {
}
}
void AsyncStateSerializer::prepare_stats(td::Promise<std::vector<std::pair<std::string, std::string>>> promise) {
if (!inited_block_id_) {
wait_init_block_id_.push_back(
[SelfId = actor_id(this), promise = std::move(promise)](td::Result<td::Unit> R) mutable {
TRY_STATUS_PROMISE(promise, R.move_as_status());
td::actor::send_closure(SelfId, &AsyncStateSerializer::prepare_stats, std::move(promise));
});
return;
}
std::vector<std::pair<std::string, std::string>> vec;
vec.emplace_back("stateserializermasterchainseqno", td::to_string(last_block_id_.seqno()));
td::StringBuilder sb;
sb << current_status_;
if (current_status_ts_) {
sb << " (started " << (int)(td::Timestamp::now() - current_status_ts_) << "s ago)";
}
if (!opts_->get_state_serializer_enabled() || auto_disabled_) {
sb << " (disabled)";
}
vec.emplace_back("stateserializerstatus", sb.as_cslice().str());
promise.set_result(std::move(vec));
}
bool AsyncStateSerializer::need_serialize(BlockHandle handle) {
if (handle->id().id.seqno == 0 || !handle->is_key_block()) {
return false;

View file

@ -36,6 +36,9 @@ class AsyncStateSerializer : public td::actor::Actor {
UnixTime last_key_block_ts_ = 0;
bool saved_to_db_ = true;
bool inited_block_id_ = false;
std::vector<td::Promise<td::Unit>> wait_init_block_id_;
td::Ref<ValidatorManagerOptions> opts_;
bool auto_disabled_ = false;
td::CancellationTokenSource cancellation_token_source_;
@ -95,6 +98,8 @@ class AsyncStateSerializer : public td::actor::Actor {
promise.set_result(last_block_id_.id.seqno);
}
void prepare_stats(td::Promise<std::vector<std::pair<std::string, std::string>>> promise);
void update_last_known_key_block_ts(UnixTime ts) {
last_known_key_block_ts_ = std::max(last_known_key_block_ts_, ts);
}
@ -111,6 +116,9 @@ class AsyncStateSerializer : public td::actor::Actor {
void update_options(td::Ref<ValidatorManagerOptions> opts);
void auto_disable_serializer(bool disabled);
std::string current_status_ = "pending";
td::Timestamp current_status_ts_ = td::Timestamp::never();
};
} // namespace validator

105
validator/stats-provider.h Normal file
View file

@ -0,0 +1,105 @@
/*
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/>.
*/
#pragma once
#include "validator.h"
#include "common/AtomicRef.h"
#include <atomic>
namespace ton {
namespace validator {
class StatsProvider {
public:
StatsProvider() = default;
StatsProvider(td::actor::ActorId<ValidatorManagerInterface> manager, std::string prefix,
std::function<void(td::Promise<std::vector<std::pair<std::string, std::string>>>)> callback)
: inited_(true), manager_(std::move(manager)) {
static std::atomic<td::uint64> cur_idx{0};
idx_ = cur_idx.fetch_add(1);
td::actor::send_closure(manager_, &ValidatorManagerInterface::register_stats_provider, idx_, std::move(prefix),
std::move(callback));
}
StatsProvider(const StatsProvider&) = delete;
StatsProvider(StatsProvider&& other) noexcept
: inited_(other.inited_), idx_(other.idx_), manager_(std::move(other.manager_)) {
other.inited_ = false;
}
~StatsProvider() {
if (inited_) {
td::actor::send_closure(manager_, &ValidatorManagerInterface::unregister_stats_provider, idx_);
}
}
StatsProvider& operator=(const StatsProvider&) = delete;
StatsProvider& operator=(StatsProvider&& other) noexcept {
if (this != &other) {
inited_ = other.inited_;
idx_ = other.idx_;
manager_ = std::move(other.manager_);
other.inited_ = false;
}
return *this;
}
bool inited() const {
return inited_;
}
private:
bool inited_ = false;
td::uint64 idx_ = 0;
td::actor::ActorId<ValidatorManagerInterface> manager_;
};
class ProcessStatus {
public:
ProcessStatus() = default;
ProcessStatus(td::actor::ActorId<ValidatorManagerInterface> manager, std::string name)
: stats_provider_(std::move(manager), std::move(name), [value = value_](auto promise) {
auto status = value->load();
if (status.is_null()) {
promise.set_error(td::Status::Error("empty"));
return;
}
std::vector<std::pair<std::string, std::string>> vec;
vec.emplace_back("", *status);
promise.set_value(std::move(vec));
}) {
}
ProcessStatus(const ProcessStatus&) = delete;
ProcessStatus(ProcessStatus&& other) noexcept = default;
ProcessStatus& operator=(const ProcessStatus&) = delete;
ProcessStatus& operator=(ProcessStatus&& other) noexcept = default;
void set_status(std::string s) {
if (!value_) {
return;
}
value_->store(td::Ref<td::Cnt<std::string>>(true, std::move(s)));
}
private:
std::shared_ptr<td::AtomicRef<td::Cnt<std::string>>> value_ = std::make_shared<td::AtomicRef<td::Cnt<std::string>>>();
StatsProvider stats_provider_;
};
} // namespace validator
} // namespace ton

View file

@ -373,6 +373,7 @@ void ValidatorGroup::create_session() {
}
CHECK(found);
config_.catchain_opts.broadcast_speed_multiplier = opts_->get_catchain_broadcast_speed_multiplier();
if (!config_.new_catchain_ids) {
session_ = validatorsession::ValidatorSession::create(session_id_, config_, local_id_, std::move(vec),
make_validator_session_callback(), keyring_, adnl_, rldp_,

View file

@ -154,6 +154,9 @@ struct ValidatorManagerOptionsImpl : public ValidatorManagerOptions {
bool get_fast_state_serializer_enabled() const override {
return fast_state_serializer_enabled_;
}
double get_catchain_broadcast_speed_multiplier() const override {
return catchain_broadcast_speed_multipliers_;
}
void set_zero_block_id(BlockIdExt block_id) override {
zero_block_id_ = block_id;
@ -249,6 +252,9 @@ struct ValidatorManagerOptionsImpl : public ValidatorManagerOptions {
void set_fast_state_serializer_enabled(bool value) override {
fast_state_serializer_enabled_ = value;
}
void set_catchain_broadcast_speed_multiplier(double value) override {
catchain_broadcast_speed_multipliers_ = value;
}
ValidatorManagerOptionsImpl *make_copy() const override {
return new ValidatorManagerOptionsImpl(*this);
@ -302,6 +308,7 @@ struct ValidatorManagerOptionsImpl : public ValidatorManagerOptions {
bool state_serializer_enabled_ = true;
td::Ref<CollatorOptions> collator_options_{true};
bool fast_state_serializer_enabled_ = false;
double catchain_broadcast_speed_multipliers_;
};
} // namespace validator

View file

@ -20,6 +20,7 @@
#include <vector>
#include <deque>
#include <functional>
#include "td/actor/actor.h"
@ -115,6 +116,7 @@ struct ValidatorManagerOptions : public td::CntObject {
virtual bool get_state_serializer_enabled() const = 0;
virtual td::Ref<CollatorOptions> get_collator_options() const = 0;
virtual bool get_fast_state_serializer_enabled() const = 0;
virtual double get_catchain_broadcast_speed_multiplier() const = 0;
virtual void set_zero_block_id(BlockIdExt block_id) = 0;
virtual void set_init_block_id(BlockIdExt block_id) = 0;
@ -147,6 +149,7 @@ struct ValidatorManagerOptions : public td::CntObject {
virtual void set_state_serializer_enabled(bool value) = 0;
virtual void set_collator_options(td::Ref<CollatorOptions> value) = 0;
virtual void set_fast_state_serializer_enabled(bool value) = 0;
virtual void set_catchain_broadcast_speed_multiplier(double value) = 0;
static td::Ref<ValidatorManagerOptions> create(
BlockIdExt zero_block_id, BlockIdExt init_block_id,
@ -292,6 +295,13 @@ class ValidatorManagerInterface : public td::actor::Actor {
virtual void get_out_msg_queue_size(BlockIdExt block_id, td::Promise<td::uint64> promise) = 0;
virtual void update_options(td::Ref<ValidatorManagerOptions> opts) = 0;
virtual void register_stats_provider(
td::uint64 idx, std::string prefix,
std::function<void(td::Promise<std::vector<std::pair<std::string, std::string>>>)> callback) {
}
virtual void unregister_stats_provider(td::uint64 idx) {
}
};
} // namespace validator