mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
commit
3ff951c225
54 changed files with 827 additions and 301 deletions
|
@ -526,10 +526,12 @@ void CatChainReceiverImpl::start_up() {
|
||||||
for (td::uint32 i = 0; i < get_sources_cnt(); i++) {
|
for (td::uint32 i = 0; i < get_sources_cnt(); i++) {
|
||||||
root_keys.emplace(get_source(i)->get_hash(), OVERLAY_MAX_ALLOWED_PACKET_SIZE);
|
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),
|
get_source(local_idx_)->get_adnl_id(), overlay_full_id_.clone(), std::move(ids),
|
||||||
make_callback(), overlay::OverlayPrivacyRules{0, 0, std::move(root_keys)},
|
make_callback(), overlay::OverlayPrivacyRules{0, 0, std::move(root_keys)},
|
||||||
R"({ "type": "catchain" })");
|
R"({ "type": "catchain" })", std::move(overlay_options));
|
||||||
|
|
||||||
CHECK(root_block_);
|
CHECK(root_block_);
|
||||||
|
|
||||||
|
|
|
@ -360,7 +360,6 @@ MsgProcessedUptoCollection::MsgProcessedUptoCollection(ton::ShardIdFull _owner,
|
||||||
z.shard = key.get_uint(64);
|
z.shard = key.get_uint(64);
|
||||||
z.mc_seqno = (unsigned)((key + 64).get_uint(32));
|
z.mc_seqno = (unsigned)((key + 64).get_uint(32));
|
||||||
z.last_inmsg_lt = value.write().fetch_ulong(64);
|
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);
|
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_ =
|
out_msg_queue_ =
|
||||||
std::make_unique<vm::AugmentedDictionary>(std::move(qinfo.out_queue), 352, block::tlb::aug_OutMsgQueue);
|
std::make_unique<vm::AugmentedDictionary>(std::move(qinfo.out_queue), 352, block::tlb::aug_OutMsgQueue);
|
||||||
if (verbosity >= 3 * 1) {
|
if (verbosity >= 3 * 1) {
|
||||||
LOG(DEBUG) << "unpacking ProcessedUpto of our previous block " << id_.to_str();
|
FLOG(DEBUG) {
|
||||||
block::gen::t_ProcessedInfo.print(std::cerr, qinfo.proc_info);
|
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)) {
|
if (!block::gen::t_ProcessedInfo.validate_csr(1024, qinfo.proc_info)) {
|
||||||
return td::Status::Error(
|
return td::Status::Error(
|
||||||
|
|
|
@ -163,8 +163,11 @@ td::Status ConfigInfo::unpack() {
|
||||||
}
|
}
|
||||||
gen::McStateExtra::Record extra_info;
|
gen::McStateExtra::Record extra_info;
|
||||||
if (!tlb::unpack_cell(state_extra_root_, extra_info)) {
|
if (!tlb::unpack_cell(state_extra_root_, extra_info)) {
|
||||||
vm::load_cell_slice(state_extra_root_).print_rec(std::cerr);
|
FLOG(WARNING) {
|
||||||
block::gen::t_McStateExtra.print_ref(std::cerr, state_extra_root_);
|
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");
|
return td::Status::Error("state extra information is invalid");
|
||||||
}
|
}
|
||||||
gen::ValidatorInfo::Record validator_info;
|
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;
|
ton::ShardIdFull true_id;
|
||||||
vm::CellSlice cs;
|
vm::CellSlice cs;
|
||||||
if (get_shard_hash_raw(cs, id, true_id, exact)) {
|
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);
|
return McShardHash::unpack(cs, true_id);
|
||||||
} else {
|
} else {
|
||||||
return {};
|
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)) {
|
if (!gen::t_BinTree_ShardDescr.validate_ref(1024, value)) {
|
||||||
LOG(ERROR) << "attempting to store an invalid (BinTree ShardDescr) at shard configuration position "
|
LOG(ERROR) << "attempting to store an invalid (BinTree ShardDescr) at shard configuration position "
|
||||||
<< shard.to_str();
|
<< shard.to_str();
|
||||||
gen::t_BinTree_ShardDescr.print_ref(std::cerr, value);
|
FLOG(WARNING) {
|
||||||
vm::load_cell_slice(value).print_rec(std::cerr);
|
gen::t_BinTree_ShardDescr.print_ref(sb, value);
|
||||||
|
vm::load_cell_slice(value).print_rec(sb);
|
||||||
|
};
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto root = shard_hashes_dict_->lookup_ref(td::BitArray<32>{shard.workchain});
|
auto root = shard_hashes_dict_->lookup_ref(td::BitArray<32>{shard.workchain});
|
||||||
|
|
|
@ -138,7 +138,6 @@ bool OutputQueueMerger::add_root(int src, Ref<vm::Cell> outmsg_root) {
|
||||||
if (outmsg_root.is_null()) {
|
if (outmsg_root.is_null()) {
|
||||||
return true;
|
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));
|
auto kv = std::make_unique<MsgKeyValue>(src, std::move(outmsg_root));
|
||||||
if (kv->replace_by_prefix(common_pfx.cbits(), common_pfx_len)) {
|
if (kv->replace_by_prefix(common_pfx.cbits(), common_pfx_len)) {
|
||||||
heap.push_back(std::move(kv));
|
heap.push_back(std::move(kv));
|
||||||
|
|
|
@ -446,8 +446,10 @@ bool Account::unpack(Ref<vm::CellSlice> shard_account, ton::UnixTime now, bool s
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (verbosity > 2) {
|
if (verbosity > 2) {
|
||||||
shard_account->print_rec(std::cerr, 2);
|
FLOG(INFO) {
|
||||||
block::gen::t_ShardAccount.print(std::cerr, *shard_account);
|
shard_account->print_rec(sb, 2);
|
||||||
|
block::gen::t_ShardAccount.print(sb, shard_account);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
block::gen::ShardAccount::Record acc_info;
|
block::gen::ShardAccount::Record acc_info;
|
||||||
if (!(block::tlb::t_ShardAccount.validate_csr(shard_account) && tlb::unpack_exact(shard_account.write(), 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;
|
return false;
|
||||||
}
|
}
|
||||||
if (verbosity > 2) {
|
if (verbosity > 2) {
|
||||||
fprintf(stderr, "unpacking inbound message for a new transaction: ");
|
FLOG(INFO) {
|
||||||
block::gen::t_Message_Any.print_ref(std::cerr, in_msg);
|
sb << "unpacking inbound message for a new transaction: ";
|
||||||
load_cell_slice(in_msg).print_rec(std::cerr);
|
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);
|
auto cs = vm::load_cell_slice(in_msg);
|
||||||
int tag = block::gen::t_CommonMsgInfo.get_tag(cs);
|
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();
|
cp.actions = impl.get_c5();
|
||||||
int out_act_num = output_actions_count(cp.actions);
|
int out_act_num = output_actions_count(cp.actions);
|
||||||
if (verbosity > 2) {
|
if (verbosity > 2) {
|
||||||
std::cerr << "new smart contract data: ";
|
FLOG(INFO) {
|
||||||
bool can_be_special = true;
|
sb << "new smart contract data: ";
|
||||||
load_cell_slice_special(cp.new_data, can_be_special).print_rec(std::cerr);
|
bool can_be_special = true;
|
||||||
std::cerr << "output actions: ";
|
load_cell_slice_special(cp.new_data, can_be_special).print_rec(sb);
|
||||||
block::gen::OutList{out_act_num}.print_ref(std::cerr, cp.actions);
|
sb << "output actions: ";
|
||||||
|
block::gen::OutList{out_act_num}.print_ref(sb, cp.actions);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cp.mode = 0;
|
cp.mode = 0;
|
||||||
|
@ -1619,7 +1625,6 @@ bool Transaction::prepare_compute_phase(const ComputePhaseConfig& cfg) {
|
||||||
if (in_msg_state.not_null()) {
|
if (in_msg_state.not_null()) {
|
||||||
LOG(DEBUG) << "HASH(in_msg_state) = " << in_msg_state->get_hash().bits().to_hex(256)
|
LOG(DEBUG) << "HASH(in_msg_state) = " << in_msg_state->get_hash().bits().to_hex(256)
|
||||||
<< ", account_state_hash = " << account.state_hash.to_hex();
|
<< ", account_state_hash = " << account.state_hash.to_hex();
|
||||||
// vm::load_cell_slice(in_msg_state).print_rec(std::cerr);
|
|
||||||
} else {
|
} else {
|
||||||
LOG(DEBUG) << "in_msg_state is null";
|
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
|
cp.actions = vm.get_committed_state().c5; // c5 -> action list
|
||||||
int out_act_num = output_actions_count(cp.actions);
|
int out_act_num = output_actions_count(cp.actions);
|
||||||
if (verbosity > 2) {
|
if (verbosity > 2) {
|
||||||
std::cerr << "new smart contract data: ";
|
FLOG(INFO) {
|
||||||
bool can_be_special = true;
|
sb << "new smart contract data: ";
|
||||||
load_cell_slice_special(cp.new_data, can_be_special).print_rec(std::cerr);
|
bool can_be_special = true;
|
||||||
std::cerr << "output actions: ";
|
load_cell_slice_special(cp.new_data, can_be_special).print_rec(sb);
|
||||||
block::gen::OutList{out_act_num}.print_ref(std::cerr, cp.actions);
|
sb << "output actions: ";
|
||||||
|
block::gen::OutList{out_act_num}.print_ref(sb, cp.actions);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cp.mode = 0;
|
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)) {
|
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";
|
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);
|
FLOG(INFO) {
|
||||||
vm::load_cell_slice(new_msg).print_rec(std::cerr);
|
block::gen::t_Message_Any.print_ref(sb, new_msg);
|
||||||
|
vm::load_cell_slice(new_msg).print_rec(sb);
|
||||||
|
};
|
||||||
collect_fine();
|
collect_fine();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (verbosity > 2) {
|
if (verbosity > 2) {
|
||||||
std::cerr << "converted outbound message: ";
|
FLOG(INFO) {
|
||||||
block::gen::t_Message_Any.print_ref(std::cerr, new_msg);
|
sb << "converted outbound message: ";
|
||||||
|
block::gen::t_Message_Any.print_ref(sb, new_msg);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
ap.msgs_created++;
|
ap.msgs_created++;
|
||||||
|
@ -3045,8 +3056,10 @@ bool Transaction::prepare_bounce_phase(const ActionPhaseConfig& cfg) {
|
||||||
}
|
}
|
||||||
CHECK(cb.finalize_to(bp.out_msg));
|
CHECK(cb.finalize_to(bp.out_msg));
|
||||||
if (verbosity > 2) {
|
if (verbosity > 2) {
|
||||||
LOG(INFO) << "generated bounced message: ";
|
FLOG(INFO) {
|
||||||
block::gen::t_Message_Any.print_ref(std::cerr, bp.out_msg);
|
sb << "generated bounced message: ";
|
||||||
|
block::gen::t_Message_Any.print_ref(sb, bp.out_msg);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
out_msgs.push_back(bp.out_msg);
|
out_msgs.push_back(bp.out_msg);
|
||||||
bp.ok = true;
|
bp.ok = true;
|
||||||
|
@ -3167,11 +3180,13 @@ bool Transaction::compute_state() {
|
||||||
auto frozen_state = cb2.finalize();
|
auto frozen_state = cb2.finalize();
|
||||||
frozen_hash = frozen_state->get_hash().bits();
|
frozen_hash = frozen_state->get_hash().bits();
|
||||||
if (verbosity >= 3 * 1) { // !!!DEBUG!!!
|
if (verbosity >= 3 * 1) { // !!!DEBUG!!!
|
||||||
std::cerr << "freezing state of smart contract: ";
|
FLOG(INFO) {
|
||||||
block::gen::t_StateInit.print_ref(std::cerr, frozen_state);
|
sb << "freezing state of smart contract: ";
|
||||||
CHECK(block::gen::t_StateInit.validate_ref(frozen_state));
|
block::gen::t_StateInit.print_ref(sb, frozen_state);
|
||||||
CHECK(block::tlb::t_StateInit.validate_ref(frozen_state));
|
CHECK(block::gen::t_StateInit.validate_ref(frozen_state));
|
||||||
std::cerr << "with hash " << frozen_hash.to_hex() << std::endl;
|
CHECK(block::tlb::t_StateInit.validate_ref(frozen_state));
|
||||||
|
sb << "with hash " << frozen_hash.to_hex();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
new_code.clear();
|
new_code.clear();
|
||||||
|
@ -3229,8 +3244,10 @@ bool Transaction::compute_state() {
|
||||||
CHECK(cb.append_data_cell_bool(std::move(storage)));
|
CHECK(cb.append_data_cell_bool(std::move(storage)));
|
||||||
new_total_state = cb.finalize();
|
new_total_state = cb.finalize();
|
||||||
if (verbosity > 2) {
|
if (verbosity > 2) {
|
||||||
std::cerr << "new account state: ";
|
FLOG(INFO) {
|
||||||
block::gen::t_Account.print_ref(std::cerr, new_total_state);
|
sb << "new account state: ";
|
||||||
|
block::gen::t_Account.print_ref(sb, new_total_state);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
CHECK(block::tlb::t_Account.validate_ref(new_total_state));
|
CHECK(block::tlb::t_Account.validate_ref(new_total_state));
|
||||||
return true;
|
return true;
|
||||||
|
@ -3322,22 +3339,28 @@ bool Transaction::serialize() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (verbosity >= 3 * 1) {
|
if (verbosity >= 3 * 1) {
|
||||||
std::cerr << "new transaction: ";
|
FLOG(INFO) {
|
||||||
block::gen::t_Transaction.print_ref(std::cerr, root);
|
sb << "new transaction: ";
|
||||||
vm::load_cell_slice(root).print_rec(std::cerr);
|
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)) {
|
if (!block::gen::t_Transaction.validate_ref(4096, root)) {
|
||||||
LOG(ERROR) << "newly-generated transaction failed to pass automated validation:";
|
LOG(ERROR) << "newly-generated transaction failed to pass automated validation:";
|
||||||
vm::load_cell_slice(root).print_rec(std::cerr);
|
FLOG(INFO) {
|
||||||
block::gen::t_Transaction.print_ref(std::cerr, root);
|
vm::load_cell_slice(root).print_rec(sb);
|
||||||
|
block::gen::t_Transaction.print_ref(sb, root);
|
||||||
|
};
|
||||||
root.clear();
|
root.clear();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!block::tlb::t_Transaction.validate_ref(4096, root)) {
|
if (!block::tlb::t_Transaction.validate_ref(4096, root)) {
|
||||||
LOG(ERROR) << "newly-generated transaction failed to pass hand-written validation:";
|
LOG(ERROR) << "newly-generated transaction failed to pass hand-written validation:";
|
||||||
vm::load_cell_slice(root).print_rec(std::cerr);
|
FLOG(INFO) {
|
||||||
block::gen::t_Transaction.print_ref(std::cerr, root);
|
vm::load_cell_slice(root).print_rec(sb);
|
||||||
|
block::gen::t_Transaction.print_ref(sb, root);
|
||||||
|
};
|
||||||
root.clear();
|
root.clear();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)));
|
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::string TLB::as_string_skip(vm::CellSlice& cs, int indent) const {
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
print_skip(os, cs, indent);
|
print_skip(os, cs, indent);
|
||||||
|
|
|
@ -246,7 +246,14 @@ class TLB {
|
||||||
bool print(std::ostream& os, Ref<vm::CellSlice> cs_ref, int indent = 0, int rec_limit = 0) const {
|
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);
|
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(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 {
|
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);
|
return print_ref(os, std::move(cell_ref), indent, rec_limit);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1026,6 +1026,13 @@ bool CellSlice::print_rec(std::ostream& os, int indent) const {
|
||||||
return print_rec(os, &limit, indent);
|
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 {
|
bool CellSlice::print_rec(int limit, std::ostream& os, int indent) const {
|
||||||
return print_rec(os, &limit, indent);
|
return print_rec(os, &limit, indent);
|
||||||
}
|
}
|
||||||
|
|
|
@ -257,6 +257,7 @@ class CellSlice : public td::CntObject {
|
||||||
void dump(std::ostream& os, int level = 0, bool endl = true) const;
|
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;
|
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(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(std::ostream& os, int* limit, int indent = 0) const;
|
||||||
bool print_rec(int limit, std::ostream& os, int indent = 0) const;
|
bool print_rec(int limit, std::ostream& os, int indent = 0) const;
|
||||||
void error() const {
|
void error() const {
|
||||||
|
|
|
@ -32,7 +32,7 @@ void OverlayOutboundFecBroadcast::alarm() {
|
||||||
fec_type_.size(), flags_, std::move(X.data), X.id, fec_type_, date_);
|
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_) {
|
if (seqno_ >= to_send_) {
|
||||||
stop();
|
stop();
|
||||||
|
@ -46,8 +46,9 @@ void OverlayOutboundFecBroadcast::start_up() {
|
||||||
|
|
||||||
OverlayOutboundFecBroadcast::OverlayOutboundFecBroadcast(td::BufferSlice data, td::uint32 flags,
|
OverlayOutboundFecBroadcast::OverlayOutboundFecBroadcast(td::BufferSlice data, td::uint32 flags,
|
||||||
td::actor::ActorId<OverlayImpl> overlay,
|
td::actor::ActorId<OverlayImpl> overlay,
|
||||||
PublicKeyHash local_id)
|
PublicKeyHash local_id, double speed_multiplier)
|
||||||
: flags_(flags) {
|
: flags_(flags) {
|
||||||
|
delay_ /= speed_multiplier;
|
||||||
CHECK(data.size() <= (1 << 27));
|
CHECK(data.size() <= (1 << 27));
|
||||||
local_id_ = local_id;
|
local_id_ = local_id;
|
||||||
overlay_ = std::move(overlay);
|
overlay_ = std::move(overlay);
|
||||||
|
@ -63,9 +64,10 @@ OverlayOutboundFecBroadcast::OverlayOutboundFecBroadcast(td::BufferSlice data, t
|
||||||
}
|
}
|
||||||
|
|
||||||
td::actor::ActorId<OverlayOutboundFecBroadcast> OverlayOutboundFecBroadcast::create(
|
td::actor::ActorId<OverlayOutboundFecBroadcast> OverlayOutboundFecBroadcast::create(
|
||||||
td::BufferSlice data, td::uint32 flags, td::actor::ActorId<OverlayImpl> overlay, PublicKeyHash local_id) {
|
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"),
|
double speed_multiplier) {
|
||||||
std::move(data), flags, overlay, local_id)
|
return td::actor::create_actor<OverlayOutboundFecBroadcast>(
|
||||||
|
td::actor::ActorOptions().with_name("bcast"), std::move(data), flags, overlay, local_id, speed_multiplier)
|
||||||
.release();
|
.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ class OverlayOutboundFecBroadcast : public td::actor::Actor {
|
||||||
PublicKeyHash local_id_;
|
PublicKeyHash local_id_;
|
||||||
Overlay::BroadcastDataHash data_hash_;
|
Overlay::BroadcastDataHash data_hash_;
|
||||||
td::uint32 flags_ = 0;
|
td::uint32 flags_ = 0;
|
||||||
|
double delay_ = 0.010;
|
||||||
td::int32 date_;
|
td::int32 date_;
|
||||||
std::unique_ptr<td::fec::Encoder> encoder_;
|
std::unique_ptr<td::fec::Encoder> encoder_;
|
||||||
td::actor::ActorId<OverlayImpl> overlay_;
|
td::actor::ActorId<OverlayImpl> overlay_;
|
||||||
|
@ -45,9 +46,9 @@ class OverlayOutboundFecBroadcast : public td::actor::Actor {
|
||||||
public:
|
public:
|
||||||
static td::actor::ActorId<OverlayOutboundFecBroadcast> create(td::BufferSlice data, td::uint32 flags,
|
static td::actor::ActorId<OverlayOutboundFecBroadcast> create(td::BufferSlice data, td::uint32 flags,
|
||||||
td::actor::ActorId<OverlayImpl> overlay,
|
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,
|
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 alarm() override;
|
||||||
void start_up() override;
|
void start_up() override;
|
||||||
|
|
|
@ -63,7 +63,7 @@ td::actor::ActorOwn<Overlay> Overlay::create_private(
|
||||||
return td::actor::create_actor<OverlayImpl>(
|
return td::actor::create_actor<OverlayImpl>(
|
||||||
overlay_actor_name(overlay_id), keyring, adnl, manager, dht_node, local_id, std::move(overlay_id),
|
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{},
|
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(
|
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();
|
overlay_id_ = id_full_.compute_short_id();
|
||||||
frequent_dht_lookup_ = opts_.frequent_dht_lookup_;
|
frequent_dht_lookup_ = opts_.frequent_dht_lookup_;
|
||||||
peer_list_.local_member_flags_ = opts_.local_overlay_member_flags_;
|
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";
|
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";
|
VLOG(OVERLAY_WARNING) << "broadcast source certificate is invalid";
|
||||||
return;
|
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) {
|
void OverlayImpl::print(td::StringBuilder &sb) {
|
||||||
|
|
|
@ -269,6 +269,7 @@ struct OverlayOptions {
|
||||||
td::uint32 nodes_to_send_ = 4;
|
td::uint32 nodes_to_send_ = 4;
|
||||||
td::uint32 propagate_broadcast_to_ = 5;
|
td::uint32 propagate_broadcast_to_ = 5;
|
||||||
td::uint32 default_permanent_members_flags_ = 0;
|
td::uint32 default_permanent_members_flags_ = 0;
|
||||||
|
double broadcast_speed_multiplier_ = 1.0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Overlays : public td::actor::Actor {
|
class Overlays : public td::actor::Actor {
|
||||||
|
|
|
@ -128,6 +128,10 @@ inline Timestamp &operator+=(Timestamp &a, double b) {
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline double operator-(const Timestamp &a, const Timestamp &b) {
|
||||||
|
return a.at() - b.at();
|
||||||
|
}
|
||||||
|
|
||||||
template <class StorerT>
|
template <class StorerT>
|
||||||
void store(const Timestamp ×tamp, StorerT &storer) {
|
void store(const Timestamp ×tamp, StorerT &storer) {
|
||||||
storer.store_binary(timestamp.at() - Time::now() + Clocks::system());
|
storer.store_binary(timestamp.at() - Time::now() + Clocks::system());
|
||||||
|
|
|
@ -264,8 +264,8 @@ class Logger {
|
||||||
sb_ << other;
|
sb_ << other;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
LambdaPrintHelper<td::Logger> operator<<(const LambdaPrint &) {
|
LambdaPrintHelper<td::StringBuilder> operator<<(const LambdaPrint &) {
|
||||||
return LambdaPrintHelper<td::Logger>{*this};
|
return LambdaPrintHelper<td::StringBuilder>{sb_};
|
||||||
}
|
}
|
||||||
|
|
||||||
MutableCSlice as_cslice() {
|
MutableCSlice as_cslice() {
|
||||||
|
|
|
@ -493,6 +493,7 @@ struct CatChainOptions {
|
||||||
td::uint64 max_block_height_coeff = 0;
|
td::uint64 max_block_height_coeff = 0;
|
||||||
|
|
||||||
bool debug_disable_db = false;
|
bool debug_disable_db = false;
|
||||||
|
double broadcast_speed_multiplier = 1.0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ValidatorSessionConfig {
|
struct ValidatorSessionConfig {
|
||||||
|
|
|
@ -1504,6 +1504,7 @@ td::Status ValidatorEngine::load_global_config() {
|
||||||
}
|
}
|
||||||
validator_options_.write().set_hardforks(std::move(h));
|
validator_options_.write().set_hardforks(std::move(h));
|
||||||
validator_options_.write().set_fast_state_serializer_enabled(fast_state_serializer_enabled_);
|
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();
|
return td::Status::OK();
|
||||||
}
|
}
|
||||||
|
@ -1957,7 +1958,8 @@ void ValidatorEngine::started_overlays() {
|
||||||
|
|
||||||
void ValidatorEngine::start_validator() {
|
void ValidatorEngine::start_validator() {
|
||||||
validator_options_.write().set_allow_blockchain_init(config_.validators.size() > 0);
|
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();
|
load_collator_options();
|
||||||
|
|
||||||
validator_manager_ = ton::validator::ValidatorManagerFactory::create(
|
validator_manager_ = ton::validator::ValidatorManagerFactory::create(
|
||||||
|
@ -2003,9 +2005,13 @@ void ValidatorEngine::start_full_node() {
|
||||||
R.ensure();
|
R.ensure();
|
||||||
td::actor::send_closure(SelfId, &ValidatorEngine::started_full_node);
|
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(
|
full_node_ = ton::validator::fullnode::FullNode::create(
|
||||||
short_id, ton::adnl::AdnlNodeIdShort{config_.full_node}, validator_options_->zero_block_id().file_hash,
|
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(),
|
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));
|
overlay_manager_.get(), validator_manager_.get(), full_node_client_.get(), db_root_, std::move(P));
|
||||||
for (auto &v : config_.validators) {
|
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>());
|
promise.set_value(ton::create_serialize_tl_object<ton::ton_api::engine_validator_success>());
|
||||||
return;
|
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,
|
td::actor::send_closure(validator_manager_, &ton::validator::ValidatorManagerInterface::update_options,
|
||||||
validator_options_);
|
validator_options_);
|
||||||
config_.state_serializer_enabled = query.enabled_;
|
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);
|
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);
|
auto S = p.run(argc, argv);
|
||||||
if (S.is_error()) {
|
if (S.is_error()) {
|
||||||
LOG(ERROR) << "failed to parse options: " << S.move_as_error();
|
LOG(ERROR) << "failed to parse options: " << S.move_as_error();
|
||||||
|
|
|
@ -228,6 +228,10 @@ class ValidatorEngine : public td::actor::Actor {
|
||||||
std::string validator_telemetry_filename_;
|
std::string validator_telemetry_filename_;
|
||||||
bool not_all_shards_ = false;
|
bool not_all_shards_ = false;
|
||||||
std::vector<ton::ShardIdFull> add_shard_cmds_;
|
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::set<ton::CatchainSeqno> unsafe_catchains_;
|
||||||
std::map<ton::BlockSeqno, std::pair<ton::CatchainSeqno, td::uint32>> unsafe_catchain_rotations_;
|
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) {
|
void add_shard_cmd(ton::ShardIdFull shard) {
|
||||||
add_shard_cmds_.push_back(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;
|
void start_up() override;
|
||||||
ValidatorEngine() {
|
ValidatorEngine() {
|
||||||
|
|
|
@ -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) {
|
void ArchiveManager::truncate(BlockSeqno masterchain_seqno, ConstBlockHandle handle, td::Promise<td::Unit> promise) {
|
||||||
index_->begin_transaction().ensure();
|
index_->begin_transaction().ensure();
|
||||||
td::MultiPromise mp;
|
td::MultiPromise mp;
|
||||||
|
|
|
@ -81,6 +81,8 @@ class ArchiveManager : public td::actor::Actor {
|
||||||
cur_shard_split_depth_ = value;
|
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() {
|
static constexpr td::uint32 archive_size() {
|
||||||
return 20000;
|
return 20000;
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,6 +158,17 @@ void CellDbIn::start_up() {
|
||||||
},
|
},
|
||||||
td::Timestamp::now());
|
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) {
|
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();
|
cell_db_->erase(get_key(key_hash)).ensure();
|
||||||
set_block(F.prev, std::move(P));
|
set_block(F.prev, std::move(P));
|
||||||
set_block(F.next, std::move(N));
|
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();
|
cell_db_->commit_write_batch().ensure();
|
||||||
alarm_timestamp() = td::Timestamp::now();
|
alarm_timestamp() = td::Timestamp::now();
|
||||||
timer_write_batch.reset();
|
timer_write_batch.reset();
|
||||||
|
@ -475,9 +491,6 @@ void CellDbIn::gc_cont2(BlockHandle handle) {
|
||||||
if (!opts_->get_disable_rocksdb_stats()) {
|
if (!opts_->get_disable_rocksdb_stats()) {
|
||||||
cell_db_statistics_.gc_cell_time_.insert(timer.elapsed() * 1e6);
|
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();
|
LOG(DEBUG) << "Deleted state " << handle->id().to_str();
|
||||||
timer_finish.reset();
|
timer_finish.reset();
|
||||||
timer_all.reset();
|
timer_all.reset();
|
||||||
|
|
|
@ -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) {
|
void RootDb::prepare_stats(td::Promise<std::vector<std::pair<std::string, std::string>>> promise) {
|
||||||
auto merger = StatsMerger::create(std::move(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(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) {
|
void RootDb::truncate(BlockSeqno seqno, ConstBlockHandle handle, td::Promise<td::Unit> promise) {
|
||||||
|
|
|
@ -38,6 +38,7 @@ DownloadShardState::DownloadShardState(BlockIdExt block_id, BlockIdExt mastercha
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadShardState::start_up() {
|
void DownloadShardState::start_up() {
|
||||||
|
status_ = ProcessStatus(manager_, "process.download_state");
|
||||||
alarm_timestamp() = timeout_;
|
alarm_timestamp() = timeout_;
|
||||||
|
|
||||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<BlockHandle> R) {
|
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_,
|
td::actor::send_closure(manager_, &ValidatorManager::send_get_block_proof_link_request, block_id_, priority_,
|
||||||
std::move(P));
|
std::move(P));
|
||||||
|
status_.set_status(PSTRING() << block_id_.id.to_str() << " : downloading proof");
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadShardState::downloaded_proof_link(td::BufferSlice data) {
|
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_,
|
td::actor::send_closure(manager_, &ValidatorManager::send_get_persistent_state_request, block_id_,
|
||||||
masterchain_block_id_, priority_, std::move(P));
|
masterchain_block_id_, priority_, std::move(P));
|
||||||
}
|
}
|
||||||
|
status_.set_status(PSTRING() << block_id_.id.to_str() << " : downloading state");
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadShardState::download_zero_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) {
|
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());
|
auto S = create_shard_state(block_id_, data.clone());
|
||||||
if (S.is_error()) {
|
if (S.is_error()) {
|
||||||
fail_handler(actor_id(this), S.move_as_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() {
|
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();
|
LOG(WARNING) << "checked shard state " << block_id_.to_str();
|
||||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||||
R.ensure();
|
R.ensure();
|
||||||
|
@ -189,6 +194,7 @@ void DownloadShardState::checked_shard_state() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadShardState::written_shard_state_file() {
|
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();
|
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) {
|
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<ShardState>> R) {
|
||||||
R.ensure();
|
R.ensure();
|
||||||
|
@ -198,6 +204,7 @@ void DownloadShardState::written_shard_state_file() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadShardState::written_shard_state(td::Ref<ShardState> state) {
|
void DownloadShardState::written_shard_state(td::Ref<ShardState> state) {
|
||||||
|
status_.set_status(PSTRING() << block_id_.id.to_str() << " : finishing");
|
||||||
state_ = std::move(state);
|
state_ = std::move(state);
|
||||||
handle_->set_unix_time(state_->get_unix_time());
|
handle_->set_unix_time(state_->get_unix_time());
|
||||||
handle_->set_is_key_block(block_id_.is_masterchain());
|
handle_->set_is_key_block(block_id_.is_masterchain());
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "validator/interfaces/validator-manager.h"
|
#include "validator/interfaces/validator-manager.h"
|
||||||
|
#include "stats-provider.h"
|
||||||
|
|
||||||
namespace ton {
|
namespace ton {
|
||||||
|
|
||||||
|
@ -67,6 +68,8 @@ class DownloadShardState : public td::actor::Actor {
|
||||||
|
|
||||||
td::BufferSlice data_;
|
td::BufferSlice data_;
|
||||||
td::Ref<ShardState> state_;
|
td::Ref<ShardState> state_;
|
||||||
|
|
||||||
|
ProcessStatus status_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace validator
|
} // namespace validator
|
||||||
|
|
|
@ -264,8 +264,11 @@ void FullNodePrivateBlockOverlay::init() {
|
||||||
overlay::OverlayPrivacyRules rules{overlay::Overlays::max_fec_broadcast_size(),
|
overlay::OverlayPrivacyRules rules{overlay::Overlays::max_fec_broadcast_size(),
|
||||||
overlay::CertificateFlags::AllowFec | overlay::CertificateFlags::Trusted,
|
overlay::CertificateFlags::AllowFec | overlay::CertificateFlags::Trusted,
|
||||||
{}};
|
{}};
|
||||||
td::actor::send_closure(overlays_, &overlay::Overlays::create_private_overlay, local_id_, overlay_id_full_.clone(),
|
overlay::OverlayOptions overlay_options;
|
||||||
nodes_, std::make_unique<Callback>(actor_id(this)), rules, R"({ "type": "private-blocks" })");
|
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(rldp_, &rldp::Rldp::add_id, local_id_);
|
||||||
td::actor::send_closure(rldp2_, &rldp2::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) {
|
void FullNodeCustomOverlay::send_external_message(td::BufferSlice data) {
|
||||||
if (!inited_ || config_.ext_messages_broadcast_disabled_) {
|
if (!inited_ || opts_.config_.ext_messages_broadcast_disabled_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
VLOG(FULL_NODE_DEBUG) << "Sending external message to custom overlay \"" << name_ << "\"";
|
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();
|
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::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(
|
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,
|
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(rldp_, &rldp::Rldp::add_id, local_id_);
|
||||||
td::actor::send_closure(rldp2_, &rldp2::Rldp::add_id, local_id_);
|
td::actor::send_closure(rldp2_, &rldp2::Rldp::add_id, local_id_);
|
||||||
|
|
|
@ -50,14 +50,14 @@ class FullNodePrivateBlockOverlay : public td::actor::Actor {
|
||||||
void collect_validator_telemetry(std::string filename);
|
void collect_validator_telemetry(std::string filename);
|
||||||
|
|
||||||
void set_config(FullNodeConfig config) {
|
void set_config(FullNodeConfig config) {
|
||||||
config_ = std::move(config);
|
opts_.config_ = std::move(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
void start_up() override;
|
void start_up() override;
|
||||||
void tear_down() override;
|
void tear_down() override;
|
||||||
|
|
||||||
FullNodePrivateBlockOverlay(adnl::AdnlNodeIdShort local_id, std::vector<adnl::AdnlNodeIdShort> nodes,
|
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<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
|
||||||
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<rldp2::Rldp> rldp2,
|
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<rldp2::Rldp> rldp2,
|
||||||
td::actor::ActorId<overlay::Overlays> overlays,
|
td::actor::ActorId<overlay::Overlays> overlays,
|
||||||
|
@ -66,7 +66,7 @@ class FullNodePrivateBlockOverlay : public td::actor::Actor {
|
||||||
: local_id_(local_id)
|
: local_id_(local_id)
|
||||||
, nodes_(std::move(nodes))
|
, nodes_(std::move(nodes))
|
||||||
, zero_state_file_hash_(zero_state_file_hash)
|
, zero_state_file_hash_(zero_state_file_hash)
|
||||||
, config_(config)
|
, opts_(opts)
|
||||||
, keyring_(keyring)
|
, keyring_(keyring)
|
||||||
, adnl_(adnl)
|
, adnl_(adnl)
|
||||||
, rldp_(rldp)
|
, rldp_(rldp)
|
||||||
|
@ -80,7 +80,7 @@ class FullNodePrivateBlockOverlay : public td::actor::Actor {
|
||||||
adnl::AdnlNodeIdShort local_id_;
|
adnl::AdnlNodeIdShort local_id_;
|
||||||
std::vector<adnl::AdnlNodeIdShort> nodes_;
|
std::vector<adnl::AdnlNodeIdShort> nodes_;
|
||||||
FileHash zero_state_file_hash_;
|
FileHash zero_state_file_hash_;
|
||||||
FullNodeConfig config_;
|
FullNodeOptions opts_;
|
||||||
bool enable_compression_ = true;
|
bool enable_compression_ = true;
|
||||||
|
|
||||||
td::actor::ActorId<keyring::Keyring> keyring_;
|
td::actor::ActorId<keyring::Keyring> keyring_;
|
||||||
|
@ -126,14 +126,14 @@ class FullNodeCustomOverlay : public td::actor::Actor {
|
||||||
td::BufferSlice data);
|
td::BufferSlice data);
|
||||||
|
|
||||||
void set_config(FullNodeConfig config) {
|
void set_config(FullNodeConfig config) {
|
||||||
config_ = std::move(config);
|
opts_.config_ = std::move(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
void start_up() override;
|
void start_up() override;
|
||||||
void tear_down() override;
|
void tear_down() override;
|
||||||
|
|
||||||
FullNodeCustomOverlay(adnl::AdnlNodeIdShort local_id, CustomOverlayParams params, FileHash zero_state_file_hash,
|
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<adnl::Adnl> adnl, td::actor::ActorId<rldp::Rldp> rldp,
|
||||||
td::actor::ActorId<rldp2::Rldp> rldp2, td::actor::ActorId<overlay::Overlays> overlays,
|
td::actor::ActorId<rldp2::Rldp> rldp2, td::actor::ActorId<overlay::Overlays> overlays,
|
||||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
|
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
|
||||||
|
@ -144,7 +144,7 @@ class FullNodeCustomOverlay : public td::actor::Actor {
|
||||||
, msg_senders_(std::move(params.msg_senders_))
|
, msg_senders_(std::move(params.msg_senders_))
|
||||||
, block_senders_(std::move(params.block_senders_))
|
, block_senders_(std::move(params.block_senders_))
|
||||||
, zero_state_file_hash_(zero_state_file_hash)
|
, zero_state_file_hash_(zero_state_file_hash)
|
||||||
, config_(config)
|
, opts_(opts)
|
||||||
, keyring_(keyring)
|
, keyring_(keyring)
|
||||||
, adnl_(adnl)
|
, adnl_(adnl)
|
||||||
, rldp_(rldp)
|
, rldp_(rldp)
|
||||||
|
@ -161,7 +161,7 @@ class FullNodeCustomOverlay : public td::actor::Actor {
|
||||||
std::map<adnl::AdnlNodeIdShort, int> msg_senders_;
|
std::map<adnl::AdnlNodeIdShort, int> msg_senders_;
|
||||||
std::set<adnl::AdnlNodeIdShort> block_senders_;
|
std::set<adnl::AdnlNodeIdShort> block_senders_;
|
||||||
FileHash zero_state_file_hash_;
|
FileHash zero_state_file_hash_;
|
||||||
FullNodeConfig config_;
|
FullNodeOptions opts_;
|
||||||
|
|
||||||
td::actor::ActorId<keyring::Keyring> keyring_;
|
td::actor::ActorId<keyring::Keyring> keyring_;
|
||||||
td::actor::ActorId<adnl::Adnl> adnl_;
|
td::actor::ActorId<adnl::Adnl> adnl_;
|
||||||
|
|
|
@ -105,6 +105,7 @@ void FullNodeShardImpl::create_overlay() {
|
||||||
};
|
};
|
||||||
overlay::OverlayOptions opts;
|
overlay::OverlayOptions opts;
|
||||||
opts.announce_self_ = active_;
|
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(),
|
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_,
|
std::make_unique<Callback>(actor_id(this)), rules_,
|
||||||
PSTRING() << "{ \"type\": \"shard\", \"shard_id\": " << get_shard()
|
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) {
|
if (!processed_ext_msg_broadcasts_.insert(hash).second) {
|
||||||
return promise.set_error(td::Status::Error("duplicate external message broadcast"));
|
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.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 {
|
promise = [manager = validator_manager_, message = q->message_->data_.clone()](td::Result<td::Unit> R) mutable {
|
||||||
if (R.is_ok()) {
|
if (R.is_ok()) {
|
||||||
|
@ -850,7 +851,7 @@ void FullNodeShardImpl::send_ihr_message(td::BufferSlice data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FullNodeShardImpl::send_external_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;
|
return;
|
||||||
}
|
}
|
||||||
if (!client_.empty()) {
|
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,
|
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<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
|
||||||
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<rldp2::Rldp> rldp2,
|
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<rldp2::Rldp> rldp2,
|
||||||
td::actor::ActorId<overlay::Overlays> overlays,
|
td::actor::ActorId<overlay::Overlays> overlays,
|
||||||
|
@ -1387,17 +1388,17 @@ FullNodeShardImpl::FullNodeShardImpl(ShardIdFull shard, PublicKeyHash local_id,
|
||||||
, client_(client)
|
, client_(client)
|
||||||
, full_node_(full_node)
|
, full_node_(full_node)
|
||||||
, active_(active)
|
, active_(active)
|
||||||
, config_(config) {
|
, opts_(opts) {
|
||||||
}
|
}
|
||||||
|
|
||||||
td::actor::ActorOwn<FullNodeShard> FullNodeShard::create(
|
td::actor::ActorOwn<FullNodeShard> FullNodeShard::create(
|
||||||
ShardIdFull shard, PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id, FileHash zero_state_file_hash,
|
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<rldp::Rldp> rldp, td::actor::ActorId<rldp2::Rldp> rldp2,
|
||||||
td::actor::ActorId<overlay::Overlays> overlays, td::actor::ActorId<ValidatorManagerInterface> validator_manager,
|
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) {
|
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,
|
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);
|
validator_manager, client, full_node, active);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ class FullNodeShard : public td::actor::Actor {
|
||||||
|
|
||||||
static td::actor::ActorOwn<FullNodeShard> create(
|
static td::actor::ActorOwn<FullNodeShard> create(
|
||||||
ShardIdFull shard, PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id, FileHash zero_state_file_hash,
|
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<rldp::Rldp> rldp, td::actor::ActorId<rldp2::Rldp> rldp2,
|
||||||
td::actor::ActorId<overlay::Overlays> overlays, td::actor::ActorId<ValidatorManagerInterface> validator_manager,
|
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);
|
td::actor::ActorId<adnl::AdnlExtClient> client, td::actor::ActorId<FullNode> full_node, bool active);
|
||||||
|
|
|
@ -86,7 +86,7 @@ class FullNodeShardImpl : public FullNodeShard {
|
||||||
void set_active(bool active) override;
|
void set_active(bool active) override;
|
||||||
|
|
||||||
void set_config(FullNodeConfig config) override {
|
void set_config(FullNodeConfig config) override {
|
||||||
config_ = config;
|
opts_.config_ = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
void try_get_next_block(td::Timestamp timestamp, td::Promise<ReceivedBlock> promise);
|
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,
|
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<adnl::Adnl> adnl, td::actor::ActorId<rldp::Rldp> rldp,
|
||||||
td::actor::ActorId<rldp2::Rldp> rldp2, td::actor::ActorId<overlay::Overlays> overlays,
|
td::actor::ActorId<rldp2::Rldp> rldp2, td::actor::ActorId<overlay::Overlays> overlays,
|
||||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
|
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
|
||||||
|
@ -269,7 +269,7 @@ class FullNodeShardImpl : public FullNodeShard {
|
||||||
|
|
||||||
bool active_;
|
bool active_;
|
||||||
|
|
||||||
FullNodeConfig config_;
|
FullNodeOptions opts_;
|
||||||
|
|
||||||
std::set<td::Bits256> my_ext_msg_broadcasts_;
|
std::set<td::Bits256> my_ext_msg_broadcasts_;
|
||||||
std::set<td::Bits256> processed_ext_msg_broadcasts_;
|
std::set<td::Bits256> processed_ext_msg_broadcasts_;
|
||||||
|
|
|
@ -139,7 +139,7 @@ void FullNodeImpl::update_adnl_id(adnl::AdnlNodeIdShort adnl_id, td::Promise<td:
|
||||||
}
|
}
|
||||||
|
|
||||||
void FullNodeImpl::set_config(FullNodeConfig config) {
|
void FullNodeImpl::set_config(FullNodeConfig config) {
|
||||||
config_ = config;
|
opts_.config_ = config;
|
||||||
for (auto& s : shards_) {
|
for (auto& s : shards_) {
|
||||||
if (!s.second.actor.empty()) {
|
if (!s.second.actor.empty()) {
|
||||||
td::actor::send_closure(s.second.actor, &FullNodeShard::set_config, config);
|
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) {
|
void FullNodeImpl::update_shard_actor(ShardIdFull shard, bool active) {
|
||||||
ShardInfo &info = shards_[shard];
|
ShardInfo &info = shards_[shard];
|
||||||
if (info.actor.empty()) {
|
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);
|
rldp2_, overlays_, validator_manager_, client_, actor_id(this), active);
|
||||||
if (!all_validators_.empty()) {
|
if (!all_validators_.empty()) {
|
||||||
td::actor::send_closure(info.actor, &FullNodeShard::update_validators, all_validators_, sign_cert_by_);
|
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);
|
nodes.push_back(p.second);
|
||||||
}
|
}
|
||||||
private_block_overlays_[key] = td::actor::create_actor<FullNodePrivateBlockOverlay>(
|
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));
|
adnl_, rldp_, rldp2_, overlays_, validator_manager_, actor_id(this));
|
||||||
update_validator_telemetry_collector();
|
update_validator_telemetry_collector();
|
||||||
}
|
}
|
||||||
|
@ -735,7 +735,7 @@ void FullNodeImpl::update_custom_overlay(CustomOverlayInfo &overlay) {
|
||||||
old_actors.erase(it);
|
old_actors.erase(it);
|
||||||
} else {
|
} else {
|
||||||
overlay.actors_[local_id] = td::actor::create_actor<FullNodeCustomOverlay>(
|
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));
|
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,
|
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<adnl::Adnl> adnl, td::actor::ActorId<rldp::Rldp> rldp,
|
||||||
td::actor::ActorId<rldp2::Rldp> rldp2, td::actor::ActorId<dht::Dht> dht,
|
td::actor::ActorId<rldp2::Rldp> rldp2, td::actor::ActorId<dht::Dht> dht,
|
||||||
td::actor::ActorId<overlay::Overlays> overlays,
|
td::actor::ActorId<overlay::Overlays> overlays,
|
||||||
|
@ -814,16 +814,16 @@ FullNodeImpl::FullNodeImpl(PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id
|
||||||
, client_(client)
|
, client_(client)
|
||||||
, db_root_(db_root)
|
, db_root_(db_root)
|
||||||
, started_promise_(std::move(started_promise))
|
, started_promise_(std::move(started_promise))
|
||||||
, config_(config) {
|
, opts_(opts) {
|
||||||
}
|
}
|
||||||
|
|
||||||
td::actor::ActorOwn<FullNode> FullNode::create(
|
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<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<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<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) {
|
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,
|
adnl, rldp, rldp2, dht, overlays, validator_manager, client, db_root,
|
||||||
std::move(started_promise));
|
std::move(started_promise));
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,12 @@ struct FullNodeConfig {
|
||||||
bool ext_messages_broadcast_disabled_ = false;
|
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 {
|
struct CustomOverlayParams {
|
||||||
std::string name_;
|
std::string name_;
|
||||||
std::vector<adnl::AdnlNodeIdShort> nodes_;
|
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 };
|
enum { broadcast_mode_public = 1, broadcast_mode_private_block = 2, broadcast_mode_custom = 4 };
|
||||||
|
|
||||||
static td::actor::ActorOwn<FullNode> create(
|
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<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<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<overlay::Overlays> overlays, td::actor::ActorId<ValidatorManagerInterface> validator_manager,
|
||||||
|
|
|
@ -98,7 +98,7 @@ class FullNodeImpl : public FullNode {
|
||||||
void start_up() override;
|
void start_up() override;
|
||||||
|
|
||||||
FullNodeImpl(PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id, FileHash zero_state_file_hash,
|
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<rldp::Rldp> rldp, td::actor::ActorId<rldp2::Rldp> rldp2,
|
||||||
td::actor::ActorId<dht::Dht> dht, td::actor::ActorId<overlay::Overlays> overlays,
|
td::actor::ActorId<dht::Dht> dht, td::actor::ActorId<overlay::Overlays> overlays,
|
||||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
|
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
|
||||||
|
@ -141,7 +141,7 @@ class FullNodeImpl : public FullNode {
|
||||||
std::set<PublicKeyHash> local_keys_;
|
std::set<PublicKeyHash> local_keys_;
|
||||||
|
|
||||||
td::Promise<td::Unit> started_promise_;
|
td::Promise<td::Unit> started_promise_;
|
||||||
FullNodeConfig config_;
|
FullNodeOptions opts_;
|
||||||
|
|
||||||
std::map<PublicKeyHash, td::actor::ActorOwn<FullNodePrivateBlockOverlay>> private_block_overlays_;
|
std::map<PublicKeyHash, td::actor::ActorOwn<FullNodePrivateBlockOverlay>> private_block_overlays_;
|
||||||
bool broadcast_block_candidates_in_public_overlay_ = false;
|
bool broadcast_block_candidates_in_public_overlay_ = false;
|
||||||
|
|
|
@ -308,8 +308,11 @@ bool AcceptBlockQuery::create_new_proof() {
|
||||||
}
|
}
|
||||||
// 10. check resulting object
|
// 10. check resulting object
|
||||||
if (!block::gen::t_BlockProof.validate_ref(bs_cell)) {
|
if (!block::gen::t_BlockProof.validate_ref(bs_cell)) {
|
||||||
block::gen::t_BlockProof.print_ref(std::cerr, bs_cell);
|
FLOG(WARNING) {
|
||||||
vm::load_cell_slice(bs_cell).print_rec(std::cerr);
|
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");
|
return fatal_error("BlockProof object just created failed to pass automated consistency checks");
|
||||||
}
|
}
|
||||||
// 11. create a proof object from this cell
|
// 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))) {
|
&& (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());
|
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)) {
|
if (!block::gen::t_TopBlockDescr.validate_ref(td_cell)) {
|
||||||
block::gen::t_TopBlockDescr.print_ref(std::cerr, td_cell);
|
FLOG(WARNING) {
|
||||||
vm::load_cell_slice(td_cell).print_rec(std::cerr);
|
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");
|
return fatal_error("just created ShardTopBlockDescription for "s + id_.to_str() + " is invalid");
|
||||||
}
|
}
|
||||||
auto res = vm::std_boc_serialize(td_cell, 0);
|
auto res = vm::std_boc_serialize(td_cell, 0);
|
||||||
|
|
|
@ -50,7 +50,7 @@ class Collator final : public td::actor::Actor {
|
||||||
using LtCellRef = block::LtCellRef;
|
using LtCellRef = block::LtCellRef;
|
||||||
using NewOutMsg = block::NewOutMsg;
|
using NewOutMsg = block::NewOutMsg;
|
||||||
const ShardIdFull shard_;
|
const ShardIdFull shard_;
|
||||||
ton::BlockId new_id;
|
ton::BlockId new_id{workchainInvalid, 0, 0};
|
||||||
bool busy_{false};
|
bool busy_{false};
|
||||||
bool before_split_{false};
|
bool before_split_{false};
|
||||||
bool after_split_{false};
|
bool after_split_{false};
|
||||||
|
|
|
@ -53,16 +53,6 @@ static constexpr int HIGH_PRIORITY_EXTERNAL = 10; // don't skip high priority e
|
||||||
|
|
||||||
static constexpr int MAX_ATTEMPTS = 5;
|
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.
|
* Constructs a Collator object.
|
||||||
*
|
*
|
||||||
|
@ -362,6 +352,8 @@ bool Collator::fatal_error(td::Status error) {
|
||||||
attempt_idx_ + 1);
|
attempt_idx_ + 1);
|
||||||
} else {
|
} else {
|
||||||
main_promise(std::move(error));
|
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;
|
busy_ = false;
|
||||||
}
|
}
|
||||||
|
@ -761,8 +753,6 @@ bool Collator::unpack_last_mc_state() {
|
||||||
<< " (upgrade validator software?)";
|
<< " (upgrade validator software?)";
|
||||||
}
|
}
|
||||||
// TODO: extract start_lt and end_lt from prev_mc_block as well
|
// 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -888,8 +878,10 @@ void Collator::got_neighbor_out_queue(int i, td::Result<Ref<MessageQueue>> res)
|
||||||
// unpack ProcessedUpto
|
// unpack ProcessedUpto
|
||||||
LOG(DEBUG) << "unpacking ProcessedUpto of neighbor " << descr.blk_.to_str();
|
LOG(DEBUG) << "unpacking ProcessedUpto of neighbor " << descr.blk_.to_str();
|
||||||
if (verbosity >= 2) {
|
if (verbosity >= 2) {
|
||||||
block::gen::t_ProcessedInfo.print(std::cerr, qinfo.proc_info);
|
FLOG(INFO) {
|
||||||
qinfo.proc_info->print_rec(std::cerr);
|
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);
|
descr.processed_upto = block::MsgProcessedUptoCollection::unpack(descr.shard(), qinfo.proc_info);
|
||||||
if (!descr.processed_upto) {
|
if (!descr.processed_upto) {
|
||||||
|
@ -1756,9 +1748,11 @@ bool Collator::import_new_shard_top_blocks() {
|
||||||
shard_conf_adjusted_ = true;
|
shard_conf_adjusted_ = true;
|
||||||
}
|
}
|
||||||
if (tb_act && verbosity >= 0) { // DEBUG
|
if (tb_act && verbosity >= 0) { // DEBUG
|
||||||
LOG(INFO) << "updated shard block configuration to ";
|
FLOG(INFO) {
|
||||||
auto csr = shard_conf_->get_root_csr();
|
sb << "updated shard block configuration to ";
|
||||||
block::gen::t_ShardHashes.print(std::cerr, csr.write());
|
auto csr = shard_conf_->get_root_csr();
|
||||||
|
block::gen::t_ShardHashes.print(sb, csr);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
block::gen::ShardFeeCreated::Record fc;
|
block::gen::ShardFeeCreated::Record fc;
|
||||||
if (!(tlb::csr_unpack(fees_import_dict_->get_root_extra(),
|
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() {
|
bool Collator::out_msg_queue_cleanup() {
|
||||||
LOG(INFO) << "cleaning outbound queue from messages already imported by neighbors";
|
LOG(INFO) << "cleaning outbound queue from messages already imported by neighbors";
|
||||||
if (verbosity >= 2) {
|
if (verbosity >= 2) {
|
||||||
auto rt = out_msg_queue_->get_root();
|
FLOG(INFO) {
|
||||||
std::cerr << "old out_msg_queue is ";
|
auto rt = out_msg_queue_->get_root();
|
||||||
block::gen::t_OutMsgQueue.print(std::cerr, *rt);
|
sb << "old out_msg_queue is ";
|
||||||
rt->print_rec(std::cerr);
|
block::gen::t_OutMsgQueue.print(sb, rt);
|
||||||
|
rt->print_rec(sb);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (after_merge_) {
|
if (after_merge_) {
|
||||||
|
@ -2422,10 +2418,12 @@ bool Collator::out_msg_queue_cleanup() {
|
||||||
<< out_msg_queue_size_;
|
<< out_msg_queue_size_;
|
||||||
}
|
}
|
||||||
if (verbosity >= 2) {
|
if (verbosity >= 2) {
|
||||||
auto rt = out_msg_queue_->get_root();
|
FLOG(INFO) {
|
||||||
std::cerr << "new out_msg_queue is ";
|
auto rt = out_msg_queue_->get_root();
|
||||||
block::gen::t_OutMsgQueue.print(std::cerr, *rt);
|
sb << "new out_msg_queue is ";
|
||||||
rt->print_rec(std::cerr);
|
block::gen::t_OutMsgQueue.print(sb, rt);
|
||||||
|
rt->print_rec(sb);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
return register_out_msg_queue_op(true);
|
return register_out_msg_queue_op(true);
|
||||||
}
|
}
|
||||||
|
@ -2524,19 +2522,27 @@ bool Collator::combine_account_transactions() {
|
||||||
auto cell = cb.finalize();
|
auto cell = cb.finalize();
|
||||||
auto csr = vm::load_cell_slice_ref(cell);
|
auto csr = vm::load_cell_slice_ref(cell);
|
||||||
if (verbosity > 2) {
|
if (verbosity > 2) {
|
||||||
std::cerr << "new AccountBlock for " << z.first.to_hex() << ": ";
|
FLOG(INFO) {
|
||||||
block::gen::t_AccountBlock.print_ref(std::cerr, cell);
|
sb << "new AccountBlock for " << z.first.to_hex() << ": ";
|
||||||
csr->print_rec(std::cerr);
|
block::gen::t_AccountBlock.print_ref(sb, cell);
|
||||||
|
csr->print_rec(sb);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
if (!block::gen::t_AccountBlock.validate_ref(100000, cell)) {
|
if (!block::gen::t_AccountBlock.validate_ref(100000, cell)) {
|
||||||
block::gen::t_AccountBlock.print_ref(std::cerr, cell);
|
FLOG(WARNING) {
|
||||||
csr->print_rec(std::cerr);
|
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() +
|
return fatal_error(std::string{"new AccountBlock for "} + z.first.to_hex() +
|
||||||
" failed to pass automatic validation tests");
|
" failed to pass automatic validation tests");
|
||||||
}
|
}
|
||||||
if (!block::tlb::t_AccountBlock.validate_ref(100000, cell)) {
|
if (!block::tlb::t_AccountBlock.validate_ref(100000, cell)) {
|
||||||
block::gen::t_AccountBlock.print_ref(std::cerr, cell);
|
FLOG(WARNING) {
|
||||||
csr->print_rec(std::cerr);
|
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() +
|
return fatal_error(std::string{"new AccountBlock for "} + z.first.to_hex() +
|
||||||
" failed to pass handwritten validation tests");
|
" failed to pass handwritten validation tests");
|
||||||
}
|
}
|
||||||
|
@ -2561,8 +2567,10 @@ bool Collator::combine_account_transactions() {
|
||||||
} else if (acc.status == block::Account::acc_nonexist) {
|
} else if (acc.status == block::Account::acc_nonexist) {
|
||||||
// account deleted
|
// account deleted
|
||||||
if (verbosity > 2) {
|
if (verbosity > 2) {
|
||||||
std::cerr << "deleting account " << acc.addr.to_hex() << " with empty new value ";
|
FLOG(INFO) {
|
||||||
block::gen::t_Account.print_ref(std::cerr, acc.total_state);
|
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()) {
|
if (account_dict->lookup_delete(acc.addr).is_null()) {
|
||||||
return fatal_error(std::string{"cannot delete account "} + acc.addr.to_hex() + " from ShardAccounts");
|
return fatal_error(std::string{"cannot delete account "} + acc.addr.to_hex() + " from ShardAccounts");
|
||||||
|
@ -2570,8 +2578,10 @@ bool Collator::combine_account_transactions() {
|
||||||
} else {
|
} else {
|
||||||
// existing account modified
|
// existing account modified
|
||||||
if (verbosity > 4) {
|
if (verbosity > 4) {
|
||||||
std::cerr << "modifying account " << acc.addr.to_hex() << " to ";
|
FLOG(INFO) {
|
||||||
block::gen::t_Account.print_ref(std::cerr, acc.total_state);
|
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
|
if (!(cb.store_ref_bool(acc.total_state) // account_descr$_ account:^Account
|
||||||
&& cb.store_bits_bool(acc.last_trans_hash_) // last_trans_hash:bits256
|
&& 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");
|
return fatal_error("cannot serialize ShardAccountBlocks");
|
||||||
}
|
}
|
||||||
if (verbosity > 2) {
|
if (verbosity > 2) {
|
||||||
std::cerr << "new ShardAccountBlocks: ";
|
FLOG(INFO) {
|
||||||
block::gen::t_ShardAccountBlocks.print_ref(std::cerr, shard_account_blocks_);
|
sb << "new ShardAccountBlocks: ";
|
||||||
vm::load_cell_slice(shard_account_blocks_).print_rec(std::cerr);
|
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_)) {
|
if (!block::gen::t_ShardAccountBlocks.validate_ref(100000, shard_account_blocks_)) {
|
||||||
return fatal_error("new ShardAccountBlocks failed to pass automatic validity tests");
|
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();
|
auto shard_accounts = account_dict->get_root();
|
||||||
if (verbosity > 2) {
|
if (verbosity > 2) {
|
||||||
std::cerr << "new ShardAccounts: ";
|
FLOG(INFO) {
|
||||||
block::gen::t_ShardAccounts.print(std::cerr, *shard_accounts);
|
sb << "new ShardAccounts: ";
|
||||||
shard_accounts->print_rec(std::cerr);
|
block::gen::t_ShardAccounts.print(sb, shard_accounts);
|
||||||
|
shard_accounts->print_rec(sb);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
if (verify >= 2) {
|
if (verify >= 2) {
|
||||||
LOG(INFO) << "verifying new ShardAccounts";
|
LOG(INFO) << "verifying new ShardAccounts";
|
||||||
|
@ -2659,7 +2673,9 @@ bool Collator::create_special_transaction(block::CurrencyCollection amount, Ref<
|
||||||
addr.to_hex());
|
addr.to_hex());
|
||||||
}
|
}
|
||||||
if (verbosity >= 4) {
|
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::gen::t_Message_Any.validate_ref(msg));
|
||||||
CHECK(block::tlb::t_Message.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;
|
Ref<vm::Cell> msg_env;
|
||||||
CHECK(block::tlb::pack_cell(msg_env, msg_env_rec));
|
CHECK(block::tlb::pack_cell(msg_env, msg_env_rec));
|
||||||
if (verbosity > 2) {
|
if (verbosity > 2) {
|
||||||
std::cerr << "new (processed outbound) message envelope: ";
|
FLOG(INFO) {
|
||||||
block::gen::t_MsgEnvelope.print_ref(std::cerr, msg_env);
|
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
|
// 3. create InMsg, referring to this MsgEnvelope and this Transaction
|
||||||
vm::CellBuilder cb;
|
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();
|
Ref<vm::Cell> out_msg = cb.finalize();
|
||||||
// 4.1. insert OutMsg into OutMsgDescr
|
// 4.1. insert OutMsg into OutMsgDescr
|
||||||
if (verbosity > 2) {
|
if (verbosity > 2) {
|
||||||
std::cerr << "OutMsg for a transit message: ";
|
FLOG(INFO) {
|
||||||
block::gen::t_OutMsg.print_ref(std::cerr, out_msg);
|
sb << "OutMsg for a transit message: ";
|
||||||
|
block::gen::t_OutMsg.print_ref(sb, out_msg);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
if (!insert_out_msg(out_msg)) {
|
if (!insert_out_msg(out_msg)) {
|
||||||
return fatal_error("cannot insert a new OutMsg into OutMsgDescr");
|
return fatal_error("cannot insert a new OutMsg into OutMsgDescr");
|
||||||
}
|
}
|
||||||
// 4.2. insert InMsg into InMsgDescr
|
// 4.2. insert InMsg into InMsgDescr
|
||||||
if (verbosity > 2) {
|
if (verbosity > 2) {
|
||||||
std::cerr << "InMsg for a transit message: ";
|
FLOG(INFO) {
|
||||||
block::gen::t_InMsg.print_ref(std::cerr, in_msg);
|
sb << "InMsg for a transit message: ";
|
||||||
|
block::gen::t_InMsg.print_ref(sb, in_msg);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
if (!insert_in_msg(in_msg)) {
|
if (!insert_in_msg(in_msg)) {
|
||||||
return fatal_error("cannot insert a new InMsg into InMsgDescr");
|
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 ||
|
if (enq_msg.is_null() || enq_msg->size_ext() != 0x10040 ||
|
||||||
(enqueued_lt = enq_msg->prefetch_ulong(64)) < /* 0 */ 1 * lt) { // DEBUG
|
(enqueued_lt = enq_msg->prefetch_ulong(64)) < /* 0 */ 1 * lt) { // DEBUG
|
||||||
if (enq_msg.not_null()) {
|
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 "
|
LOG(ERROR) << "inbound internal message is not a valid EnqueuedMsg (created lt " << lt << ", enqueued "
|
||||||
<< enqueued_lt << ")";
|
<< 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()
|
LOG(DEBUG) << "processing inbound message with (lt,hash)=(" << kv->lt << "," << kv->key.to_hex()
|
||||||
<< ") from neighbor #" << kv->source;
|
<< ") from neighbor #" << kv->source;
|
||||||
if (verbosity > 2) {
|
if (verbosity > 2) {
|
||||||
std::cerr << "inbound message: lt=" << kv->lt << " from=" << kv->source << " key=" << kv->key.to_hex() << " msg=";
|
FLOG(INFO) {
|
||||||
block::gen::t_EnqueuedMsg.print(std::cerr, *(kv->msg));
|
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 (!process_inbound_message(kv->msg, kv->lt, kv->key.cbits(), neighbors_.at(kv->source))) {
|
||||||
if (verbosity > 1) {
|
if (verbosity > 1) {
|
||||||
std::cerr << "invalid inbound message: lt=" << kv->lt << " from=" << kv->source << " key=" << kv->key.to_hex()
|
FLOG(INFO) {
|
||||||
<< " msg=";
|
sb << "invalid inbound message: lt=" << kv->lt << " from=" << kv->source << " key=" << kv->key.to_hex()
|
||||||
block::gen::t_EnqueuedMsg.print(std::cerr, *(kv->msg));
|
<< " msg=";
|
||||||
|
block::gen::t_EnqueuedMsg.print(sb, kv->msg);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
return fatal_error("error processing inbound internal message");
|
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;
|
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.is_null() || enq_msg->size_ext() != 0x10040 || (enqueued_lt = enq_msg->prefetch_ulong(64)) != lt) {
|
||||||
if (enq_msg.not_null()) {
|
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 "
|
LOG(ERROR) << "internal message in DispatchQueue is not a valid EnqueuedMsg (created lt " << lt << ", enqueued "
|
||||||
<< enqueued_lt << ")";
|
<< 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) {
|
bool Collator::insert_in_msg(Ref<vm::Cell> in_msg) {
|
||||||
if (verbosity > 2) {
|
if (verbosity > 2) {
|
||||||
std::cerr << "InMsg being inserted into InMsgDescr: ";
|
FLOG(INFO) {
|
||||||
block::gen::t_InMsg.print_ref(std::cerr, in_msg);
|
sb << "InMsg being inserted into InMsgDescr: ";
|
||||||
|
block::gen::t_InMsg.print_ref(sb, in_msg);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
auto cs = load_cell_slice(in_msg);
|
auto cs = load_cell_slice(in_msg);
|
||||||
if (!cs.size_refs()) {
|
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) {
|
bool Collator::insert_out_msg(Ref<vm::Cell> out_msg) {
|
||||||
if (verbosity > 2) {
|
if (verbosity > 2) {
|
||||||
std::cerr << "OutMsg being inserted into OutMsgDescr: ";
|
FLOG(INFO) {
|
||||||
block::gen::t_OutMsg.print_ref(std::cerr, out_msg);
|
sb << "OutMsg being inserted into OutMsgDescr: ";
|
||||||
|
block::gen::t_OutMsg.print_ref(sb, out_msg);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
auto cs = load_cell_slice(out_msg);
|
auto cs = load_cell_slice(out_msg);
|
||||||
if (!cs.size_refs()) {
|
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
|
// 4. insert OutMsg into OutMsgDescr
|
||||||
if (verbosity > 2) {
|
if (verbosity > 2) {
|
||||||
std::cerr << "OutMsg for a newly-generated message: ";
|
FLOG(INFO) {
|
||||||
block::gen::t_OutMsg.print_ref(std::cerr, out_msg);
|
sb << "OutMsg for a newly-generated message: ";
|
||||||
|
block::gen::t_OutMsg.print_ref(sb, out_msg);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
if (!insert_out_msg(out_msg)) {
|
if (!insert_out_msg(out_msg)) {
|
||||||
return fatal_error("cannot insert a new OutMsg into OutMsgDescr");
|
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;
|
bool ignore_cfg_changes = false;
|
||||||
Ref<vm::Cell> cfg0;
|
Ref<vm::Cell> cfg0;
|
||||||
if (!block::valid_config_data(cfg_smc_config, config_addr, true, true, old_mparams_)) {
|
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() +
|
LOG(ERROR) << "configuration smart contract "s + config_addr.to_hex() +
|
||||||
" contains an invalid configuration in its data, IGNORING CHANGES";
|
" 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;
|
ignore_cfg_changes = true;
|
||||||
} else {
|
} else {
|
||||||
cfg0 = cfg_dict.lookup_ref(td::BitArray<32>{(long long)0});
|
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());
|
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);
|
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)) {
|
if (!update_shard_config(wset_res.move_as_ok(), ccvc, update_shard_cc)) {
|
||||||
auto csr = shard_conf_->get_root_csr();
|
auto csr = shard_conf_->get_root_csr();
|
||||||
if (csr.is_null()) {
|
if (csr.is_null()) {
|
||||||
LOG(WARNING) << "new shard configuration is null (!)";
|
LOG(WARNING) << "new shard configuration is null (!)";
|
||||||
} else {
|
} else {
|
||||||
LOG(WARNING) << "invalid new shard configuration is";
|
LOG(WARNING) << "invalid new shard configuration is";
|
||||||
std::ostringstream os;
|
FLOG(WARNING) {
|
||||||
csr->print_rec(os);
|
csr->print_rec(sb);
|
||||||
block::gen::t_ShardHashes.print(os, csr.write());
|
block::gen::t_ShardHashes.print(sb, csr);
|
||||||
LOG(WARNING) << os.str();
|
};
|
||||||
}
|
}
|
||||||
return fatal_error("cannot post-process shard configuration");
|
return fatal_error("cannot post-process shard configuration");
|
||||||
}
|
}
|
||||||
// 3. save new shard_hashes
|
// 3. save new shard_hashes
|
||||||
state_extra.shard_hashes = shard_conf_->get_root_csr();
|
state_extra.shard_hashes = shard_conf_->get_root_csr();
|
||||||
if (verbosity >= 3 * 0) { // DEBUG
|
if (verbosity >= 3) {
|
||||||
std::cerr << "updated shard configuration to ";
|
FLOG(INFO) {
|
||||||
block::gen::t_ShardHashes.print(std::cerr, *state_extra.shard_hashes);
|
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)) {
|
if (!block::gen::t_ShardHashes.validate_upto(10000, *state_extra.shard_hashes)) {
|
||||||
return fatal_error("new ShardHashes is invalid");
|
return fatal_error("new ShardHashes is invalid");
|
||||||
|
@ -4587,13 +4620,18 @@ bool Collator::create_mc_state_extra() {
|
||||||
if (verify >= 2) {
|
if (verify >= 2) {
|
||||||
LOG(INFO) << "verifying new BlockCreateStats";
|
LOG(INFO) << "verifying new BlockCreateStats";
|
||||||
if (!block::gen::t_BlockCreateStats.validate_csr(100000, cs)) {
|
if (!block::gen::t_BlockCreateStats.validate_csr(100000, cs)) {
|
||||||
cs->print_rec(std::cerr);
|
FLOG(WARNING) {
|
||||||
block::gen::t_BlockCreateStats.print(std::cerr, *cs);
|
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");
|
return fatal_error("BlockCreateStats in the new masterchain state failed to pass automated validity checks");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (verbosity >= 4 * 1) {
|
if (verbosity >= 4 * 1) {
|
||||||
block::gen::t_BlockCreateStats.print(std::cerr, *cs);
|
FLOG(INFO) {
|
||||||
|
block::gen::t_BlockCreateStats.print(sb, cs);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
state_extra.r1.block_create_stats.clear();
|
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)) {
|
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");
|
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_)) {
|
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)
|
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() << ")");
|
<< " by " << mc_incr << " (old value is " << mc_cnt.to_str() << ")");
|
||||||
|
@ -4999,9 +5036,11 @@ bool Collator::update_public_libraries() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (libraries_changed_ && verbosity >= 2) {
|
if (libraries_changed_ && verbosity >= 2) {
|
||||||
std::cerr << "New public libraries: ";
|
FLOG(INFO) {
|
||||||
block::gen::t_HashmapE_256_LibDescr.print(std::cerr, shard_libraries_->get_root());
|
sb << "New public libraries: ";
|
||||||
shard_libraries_->get_root()->print_rec(std::cerr);
|
block::gen::t_HashmapE_256_LibDescr.print(sb, shard_libraries_->get_root());
|
||||||
|
shard_libraries_->get_root()->print_rec(sb);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -5124,9 +5163,11 @@ bool Collator::create_shard_state() {
|
||||||
}
|
}
|
||||||
LOG(DEBUG) << "min_ref_mc_seqno is " << min_ref_mc_seqno_;
|
LOG(DEBUG) << "min_ref_mc_seqno is " << min_ref_mc_seqno_;
|
||||||
if (verbosity > 2) {
|
if (verbosity > 2) {
|
||||||
std::cerr << "new ShardState: ";
|
FLOG(INFO) {
|
||||||
block::gen::t_ShardState.print_ref(std::cerr, state_root);
|
sb << "new ShardState: ";
|
||||||
vm::load_cell_slice(state_root).print_rec(std::cerr);
|
block::gen::t_ShardState.print_ref(sb, state_root);
|
||||||
|
vm::load_cell_slice(state_root).print_rec(sb);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
if (verify >= 2) {
|
if (verify >= 2) {
|
||||||
LOG(INFO) << "verifying new ShardState";
|
LOG(INFO) << "verifying new ShardState";
|
||||||
|
@ -5139,9 +5180,11 @@ bool Collator::create_shard_state() {
|
||||||
return fatal_error("cannot create Merkle update for ShardState");
|
return fatal_error("cannot create Merkle update for ShardState");
|
||||||
}
|
}
|
||||||
if (verbosity > 2) {
|
if (verbosity > 2) {
|
||||||
std::cerr << "Merkle Update for ShardState: ";
|
FLOG(INFO) {
|
||||||
vm::CellSlice cs{vm::NoVm{}, state_update};
|
sb << "Merkle Update for ShardState: ";
|
||||||
cs.print_rec(std::cerr);
|
vm::CellSlice cs{vm::NoVm{}, state_update};
|
||||||
|
cs.print_rec(sb);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
LOG(INFO) << "updating block profile statistics";
|
LOG(INFO) << "updating block profile statistics";
|
||||||
block_limit_status_->add_proof(state_root);
|
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) {
|
bool Collator::compute_out_msg_queue_info(Ref<vm::Cell>& out_msg_queue_info) {
|
||||||
if (verbosity >= 2) {
|
if (verbosity >= 2) {
|
||||||
auto rt = out_msg_queue_->get_root();
|
FLOG(INFO) {
|
||||||
std::cerr << "resulting out_msg_queue is ";
|
auto rt = out_msg_queue_->get_root();
|
||||||
block::gen::t_OutMsgQueue.print(std::cerr, *rt);
|
sb << "resulting out_msg_queue is ";
|
||||||
rt->print_rec(std::cerr);
|
block::gen::t_OutMsgQueue.print(sb, rt);
|
||||||
|
rt->print_rec(sb);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
vm::CellBuilder cb;
|
vm::CellBuilder cb;
|
||||||
// out_msg_queue_extra#0 dispatch_queue:DispatchQueue out_queue_size:(Maybe uint48) = OutMsgQueueExtra;
|
// 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())};
|
vm::CellSlice cs{*(in_msg_dict->get_root_extra())};
|
||||||
if (verbosity > 2) {
|
if (verbosity > 2) {
|
||||||
block::gen::t_ImportFees.print(std::cerr, vm::CellSlice{*(in_msg_dict->get_root_extra())});
|
FLOG(INFO) {
|
||||||
cs.print_rec(std::cerr);
|
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);
|
auto new_import_fees = block::tlb::t_Grams.as_integer_skip(cs);
|
||||||
if (new_import_fees.is_null()) {
|
if (new_import_fees.is_null()) {
|
||||||
|
@ -5468,9 +5515,11 @@ bool Collator::create_block() {
|
||||||
return fatal_error("cannot create new Block");
|
return fatal_error("cannot create new Block");
|
||||||
}
|
}
|
||||||
if (verbosity >= 3 * 1) {
|
if (verbosity >= 3 * 1) {
|
||||||
std::cerr << "new Block: ";
|
FLOG(INFO) {
|
||||||
block::gen::t_Block.print_ref(std::cerr, new_block);
|
sb << "new Block: ";
|
||||||
vm::load_cell_slice(new_block).print_rec(std::cerr);
|
block::gen::t_Block.print_ref(sb, new_block);
|
||||||
|
vm::load_cell_slice(new_block).print_rec(sb);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
if (verify >= 1) {
|
if (verify >= 1) {
|
||||||
LOG(INFO) << "verifying new Block";
|
LOG(INFO) << "verifying new Block";
|
||||||
|
@ -5508,9 +5557,11 @@ Ref<vm::Cell> Collator::collate_shard_block_descr_set() {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
if (verbosity >= 4 * 1) {
|
if (verbosity >= 4 * 1) {
|
||||||
std::cerr << "serialized TopBlockDescrSet for collated data is: ";
|
FLOG(INFO) {
|
||||||
block::gen::t_TopBlockDescrSet.print_ref(std::cerr, cell);
|
sb << "serialized TopBlockDescrSet for collated data is: ";
|
||||||
vm::load_cell_slice(cell).print_rec(std::cerr);
|
block::gen::t_TopBlockDescrSet.print_ref(sb, cell);
|
||||||
|
vm::load_cell_slice(cell).print_rec(sb);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
return cell;
|
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");
|
return td::Status::Error("inbound external message has destination address not in this shard");
|
||||||
}
|
}
|
||||||
if (verbosity > 2) {
|
if (verbosity > 2) {
|
||||||
std::cerr << "registered external message: ";
|
FLOG(INFO) {
|
||||||
block::gen::t_Message_Any.print_ref(std::cerr, ext_msg);
|
sb << "registered external message: ";
|
||||||
|
block::gen::t_Message_Any.print_ref(sb, ext_msg);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
ext_msg_map.emplace(hash, 1);
|
ext_msg_map.emplace(hash, 1);
|
||||||
ext_msg_list_.push_back({std::move(ext_msg), ext_hash, priority});
|
ext_msg_list_.push_back({std::move(ext_msg), ext_hash, priority});
|
||||||
|
|
|
@ -85,19 +85,13 @@ void LiteQuery::abort_query(td::Status reason) {
|
||||||
if (acc_state_promise_) {
|
if (acc_state_promise_) {
|
||||||
acc_state_promise_.set_error(std::move(reason));
|
acc_state_promise_.set_error(std::move(reason));
|
||||||
} else if (promise_) {
|
} 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));
|
promise_.set_error(std::move(reason));
|
||||||
}
|
}
|
||||||
stop();
|
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) {
|
bool LiteQuery::fatal_error(td::Status error) {
|
||||||
abort_query(std::move(error));
|
abort_query(std::move(error));
|
||||||
return false;
|
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());
|
td::actor::send_closure(cache_, &LiteServerCache::update, cache_key_, result.clone());
|
||||||
}
|
}
|
||||||
if (promise_) {
|
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));
|
promise_.set_result(std::move(result));
|
||||||
stop();
|
stop();
|
||||||
return true;
|
return true;
|
||||||
|
@ -139,7 +135,6 @@ void LiteQuery::start_up() {
|
||||||
|
|
||||||
auto F = fetch_tl_object<ton::lite_api::Function>(query_, true);
|
auto F = fetch_tl_object<ton::lite_api::Function>(query_, true);
|
||||||
if (F.is_error()) {
|
if (F.is_error()) {
|
||||||
td::actor::send_closure(manager_, &ValidatorManager::add_lite_query_stats, 0); // unknown
|
|
||||||
abort_query(F.move_as_error());
|
abort_query(F.move_as_error());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -192,7 +187,6 @@ bool LiteQuery::use_cache() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LiteQuery::perform() {
|
void LiteQuery::perform() {
|
||||||
td::actor::send_closure(manager_, &ValidatorManager::add_lite_query_stats, query_obj_->get_id());
|
|
||||||
lite_api::downcast_call(
|
lite_api::downcast_call(
|
||||||
*query_obj_,
|
*query_obj_,
|
||||||
td::overloaded(
|
td::overloaded(
|
||||||
|
|
|
@ -97,7 +97,6 @@ class LiteQuery : public td::actor::Actor {
|
||||||
bool fatal_error(std::string err_msg, int err_code = -400);
|
bool fatal_error(std::string err_msg, int err_code = -400);
|
||||||
bool fatal_error(int err_code, std::string err_msg = "");
|
bool fatal_error(int err_code, std::string err_msg = "");
|
||||||
void abort_query(td::Status reason);
|
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);
|
bool finish_query(td::BufferSlice result, bool skip_cache_update = false);
|
||||||
void alarm() override;
|
void alarm() override;
|
||||||
void start_up() override;
|
void start_up() override;
|
||||||
|
|
|
@ -42,9 +42,6 @@ td::BufferSlice BlockSignatureSetQ::serialize() const {
|
||||||
}
|
}
|
||||||
Ref<vm::Cell> root;
|
Ref<vm::Cell> root;
|
||||||
CHECK(serialize_to(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));
|
auto res = vm::std_boc_serialize(std::move(root));
|
||||||
LOG_CHECK(res.is_ok()) << res.move_as_error();
|
LOG_CHECK(res.is_ok()) << res.move_as_error();
|
||||||
return res.move_as_ok();
|
return res.move_as_ok();
|
||||||
|
|
|
@ -175,9 +175,11 @@ td::Status ShardTopBlockDescrQ::unpack() {
|
||||||
block::gen::TopBlockDescr::Record rec;
|
block::gen::TopBlockDescr::Record rec;
|
||||||
if (!(block::gen::t_TopBlockDescr.force_validate_ref(root_) && tlb::unpack_cell(root_, 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_))) {
|
block::tlb::t_BlockIdExt.unpack(rec.proof_for.write(), block_id_))) {
|
||||||
std::cerr << "invalid ShardTopBlockDescr: ";
|
FLOG(INFO) {
|
||||||
block::gen::t_TopBlockDescr.print_ref(std::cerr, root_);
|
sb << "invalid ShardTopBlockDescr: ";
|
||||||
vm::load_cell_slice(root_).print_rec(std::cerr);
|
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");
|
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";
|
LOG(DEBUG) << "unpacking a ShardTopBlockDescr for " << block_id_.to_str() << " with " << rec.len << " links";
|
||||||
|
|
|
@ -115,7 +115,7 @@ bool ValidateQuery::reject_query(std::string error, td::BufferSlice reason) {
|
||||||
error = error_ctx() + error;
|
error = error_ctx() + error;
|
||||||
LOG(ERROR) << "REJECT: aborting validation of block candidate for " << shard_.to_str() << " : " << error;
|
LOG(ERROR) << "REJECT: aborting validation of block candidate for " << shard_.to_str() << " : " << error;
|
||||||
if (main_promise) {
|
if (main_promise) {
|
||||||
record_stats();
|
record_stats(false);
|
||||||
errorlog::ErrorLog::log(PSTRING() << "REJECT: aborting validation of block candidate for " << shard_.to_str()
|
errorlog::ErrorLog::log(PSTRING() << "REJECT: aborting validation of block candidate for " << shard_.to_str()
|
||||||
<< " : " << error << ": data=" << block_candidate.id.file_hash.to_hex()
|
<< " : " << error << ": data=" << block_candidate.id.file_hash.to_hex()
|
||||||
<< " collated_data=" << block_candidate.collated_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;
|
error = error_ctx() + error;
|
||||||
LOG(ERROR) << "SOFT REJECT: aborting validation of block candidate for " << shard_.to_str() << " : " << error;
|
LOG(ERROR) << "SOFT REJECT: aborting validation of block candidate for " << shard_.to_str() << " : " << error;
|
||||||
if (main_promise) {
|
if (main_promise) {
|
||||||
record_stats();
|
record_stats(false);
|
||||||
errorlog::ErrorLog::log(PSTRING() << "SOFT REJECT: aborting validation of block candidate for " << shard_.to_str()
|
errorlog::ErrorLog::log(PSTRING() << "SOFT REJECT: aborting validation of block candidate for " << shard_.to_str()
|
||||||
<< " : " << error << ": data=" << block_candidate.id.file_hash.to_hex()
|
<< " : " << error << ": data=" << block_candidate.id.file_hash.to_hex()
|
||||||
<< " collated_data=" << block_candidate.collated_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();
|
error.ensure_error();
|
||||||
LOG(ERROR) << "aborting validation of block candidate for " << shard_.to_str() << " : " << error.to_string();
|
LOG(ERROR) << "aborting validation of block candidate for " << shard_.to_str() << " : " << error.to_string();
|
||||||
if (main_promise) {
|
if (main_promise) {
|
||||||
record_stats();
|
record_stats(false);
|
||||||
auto c = error.code();
|
auto c = error.code();
|
||||||
if (c <= -667 && c >= -670) {
|
if (c <= -667 && c >= -670) {
|
||||||
errorlog::ErrorLog::log(PSTRING() << "FATAL ERROR: aborting validation of block candidate for " << shard_.to_str()
|
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() {
|
void ValidateQuery::finish_query() {
|
||||||
if (main_promise) {
|
if (main_promise) {
|
||||||
record_stats();
|
record_stats(true);
|
||||||
LOG(WARNING) << "validate query done";
|
LOG(WARNING) << "validate query done";
|
||||||
main_promise.set_result(now_);
|
main_promise.set_result(now_);
|
||||||
}
|
}
|
||||||
|
@ -1553,8 +1553,10 @@ void ValidateQuery::got_neighbor_out_queue(int i, td::Result<Ref<MessageQueue>>
|
||||||
// unpack ProcessedUpto
|
// unpack ProcessedUpto
|
||||||
LOG(DEBUG) << "unpacking ProcessedUpto of neighbor " << descr.blk_.to_str();
|
LOG(DEBUG) << "unpacking ProcessedUpto of neighbor " << descr.blk_.to_str();
|
||||||
if (verbosity >= 2) {
|
if (verbosity >= 2) {
|
||||||
block::gen::t_ProcessedInfo.print(std::cerr, qinfo.proc_info);
|
FLOG(INFO) {
|
||||||
qinfo.proc_info->print_rec(std::cerr);
|
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);
|
descr.processed_upto = block::MsgProcessedUptoCollection::unpack(descr.shard(), qinfo.proc_info);
|
||||||
if (!descr.processed_upto) {
|
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());
|
" but the sum over all accounts present in the new state is " + cc.to_str());
|
||||||
}
|
}
|
||||||
auto msg_extra = in_msg_dict_->get_root_extra();
|
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)))) {
|
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");
|
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);
|
auto acc_blk_root = account_blocks_dict_->lookup(acc_id, 256);
|
||||||
if (acc_blk_root.is_null()) {
|
if (acc_blk_root.is_null()) {
|
||||||
if (verbosity >= 3 * 0) {
|
if (verbosity >= 3 * 0) {
|
||||||
std::cerr << "state of account " << workchain() << ":" << acc_id.to_hex(256)
|
FLOG(INFO) {
|
||||||
<< " in the old shardchain state:" << std::endl;
|
sb << "state of account " << workchain() << ":" << acc_id.to_hex(256)
|
||||||
if (old_value.not_null()) {
|
<< " in the old shardchain state:" << "\n";
|
||||||
block::gen::t_ShardAccount.print(std::cerr, *old_value);
|
if (old_value.not_null()) {
|
||||||
} else {
|
block::gen::t_ShardAccount.print(sb, old_value);
|
||||||
std::cerr << "<absent>" << std::endl;
|
} else {
|
||||||
}
|
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)
|
||||||
if (new_value.not_null()) {
|
<< " in the new shardchain state:" << "\n";
|
||||||
block::gen::t_ShardAccount.print(std::cerr, *new_value);
|
if (new_value.not_null()) {
|
||||||
} else {
|
block::gen::t_ShardAccount.print(sb, new_value);
|
||||||
std::cerr << "<absent>" << std::endl;
|
} else {
|
||||||
}
|
sb << "<absent>" << "\n";
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
return reject_query("the state of account "s + acc_id.to_hex(256) +
|
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 "
|
" 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());
|
" not belonging to the block's shard " + shard_.to_str());
|
||||||
}
|
}
|
||||||
CHECK(acc_blk_root.not_null());
|
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::AccountBlock::Record acc_blk;
|
||||||
block::gen::HASH_UPDATE::Record hash_upd;
|
block::gen::HASH_UPDATE::Record hash_upd;
|
||||||
if (!(tlb::csr_unpack(acc_blk_root, acc_blk) &&
|
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;
|
ton::LogicalTime trans_lt;
|
||||||
CHECK(block::get_transaction_id(transaction, trans_addr, trans_lt));
|
CHECK(block::get_transaction_id(transaction, trans_addr, trans_lt));
|
||||||
if (dest_addr != trans_addr) {
|
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)
|
return reject_query(PSTRING() << "InMsg corresponding to inbound message with hash " << key.to_hex(256)
|
||||||
<< " and destination address " << dest_addr.to_hex()
|
<< " and destination address " << dest_addr.to_hex()
|
||||||
<< " claims that the message is processed by transaction " << trans_lt
|
<< " 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;
|
ton::LogicalTime trans_lt;
|
||||||
CHECK(block::get_transaction_id(transaction, trans_addr, trans_lt));
|
CHECK(block::get_transaction_id(transaction, trans_addr, trans_lt));
|
||||||
if (src_addr != trans_addr) {
|
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)
|
return reject_query(PSTRING() << "OutMsg corresponding to outbound message with hash " << key.to_hex(256)
|
||||||
<< " and source address " << src_addr.to_hex()
|
<< " and source address " << src_addr.to_hex()
|
||||||
<< " claims that the message was created by transaction " << trans_lt
|
<< " 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()
|
LOG(DEBUG) << "processing inbound message with (lt,hash)=(" << kv->lt << "," << kv->key.to_hex()
|
||||||
<< ") from neighbor #" << kv->source;
|
<< ") from neighbor #" << kv->source;
|
||||||
if (verbosity > 3) {
|
if (verbosity > 3) {
|
||||||
std::cerr << "inbound message: lt=" << kv->lt << " from=" << kv->source << " key=" << kv->key.to_hex() << " msg=";
|
FLOG(INFO) {
|
||||||
block::gen::t_EnqueuedMsg.print(std::cerr, *(kv->msg));
|
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;
|
bool unprocessed = false;
|
||||||
if (!check_neighbor_outbound_message(kv->msg, kv->lt, kv->key.cbits(), neighbors_.at(kv->source), unprocessed)) {
|
if (!check_neighbor_outbound_message(kv->msg, kv->lt, kv->key.cbits(), neighbors_.at(kv->source), unprocessed)) {
|
||||||
if (verbosity > 1) {
|
if (verbosity > 1) {
|
||||||
std::cerr << "invalid neighbor outbound message: lt=" << kv->lt << " from=" << kv->source
|
FLOG(INFO) {
|
||||||
<< " key=" << kv->key.to_hex() << " msg=";
|
sb << "invalid neighbor outbound message: lt=" << kv->lt << " from=" << kv->source
|
||||||
block::gen::t_EnqueuedMsg.print(std::cerr, *(kv->msg));
|
<< " key=" << kv->key.to_hex() << " msg=";
|
||||||
|
block::gen::t_EnqueuedMsg.print(sb, kv->msg);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
return reject_query("error processing outbound internal message "s + kv->key.to_hex() + " of neighbor " +
|
return reject_query("error processing outbound internal message "s + kv->key.to_hex() + " of neighbor " +
|
||||||
neighbors_.at(kv->source).blk_.to_str());
|
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
|
// now compare the re-created transaction with the one we have
|
||||||
if (trans_root2->get_hash() != trans_root->get_hash()) {
|
if (trans_root2->get_hash() != trans_root->get_hash()) {
|
||||||
if (verbosity >= 3 * 0) {
|
if (verbosity >= 3 * 0) {
|
||||||
std::cerr << "original transaction " << lt << " of " << addr.to_hex() << ": ";
|
FLOG(INFO) {
|
||||||
block::gen::t_Transaction.print_ref(std::cerr, trans_root);
|
sb << "original transaction " << lt << " of " << addr.to_hex() << ": ";
|
||||||
std::cerr << "re-created transaction " << lt << " of " << addr.to_hex() << ": ";
|
block::gen::t_Transaction.print_ref(sb, trans_root);
|
||||||
block::gen::t_Transaction.print_ref(std::cerr, trans_root2);
|
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 "
|
return reject_query(PSTRING() << "the transaction " << lt << " of " << addr.to_hex() << " has hash "
|
||||||
<< trans_root->get_hash().to_hex()
|
<< trans_root->get_hash().to_hex()
|
||||||
|
@ -6917,13 +6928,13 @@ void ValidateQuery::written_candidate() {
|
||||||
/**
|
/**
|
||||||
* Sends validation work time to manager.
|
* Sends validation work time to manager.
|
||||||
*/
|
*/
|
||||||
void ValidateQuery::record_stats() {
|
void ValidateQuery::record_stats(bool success) {
|
||||||
double work_time = work_timer_.elapsed();
|
double work_time = work_timer_.elapsed();
|
||||||
double cpu_work_time = cpu_work_timer_.elapsed();
|
double cpu_work_time = cpu_work_timer_.elapsed();
|
||||||
LOG(WARNING) << "validation took " << perf_timer_.elapsed() << "s";
|
LOG(WARNING) << "validation took " << perf_timer_.elapsed() << "s";
|
||||||
LOG(WARNING) << "Validate query work time = " << work_time << "s, cpu time = " << cpu_work_time << "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,
|
td::actor::send_closure(manager, &ValidatorManager::record_validate_query_stats, block_candidate.id, work_time,
|
||||||
cpu_work_time);
|
cpu_work_time, success);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace validator
|
} // namespace validator
|
||||||
|
|
|
@ -400,7 +400,7 @@ class ValidateQuery : public td::actor::Actor {
|
||||||
|
|
||||||
td::Timer work_timer_{true};
|
td::Timer work_timer_{true};
|
||||||
td::ThreadCpuTimer cpu_work_timer_{true};
|
td::ThreadCpuTimer cpu_work_timer_{true};
|
||||||
void record_stats();
|
void record_stats(bool success);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace validator
|
} // namespace validator
|
||||||
|
|
|
@ -205,13 +205,13 @@ class ValidatorManager : public ValidatorManagerInterface {
|
||||||
td::optional<ShardIdFull> shard,
|
td::optional<ShardIdFull> shard,
|
||||||
td::Promise<tl_object_ptr<lite_api::liteServer_nonfinal_validatorGroups>> promise) = 0;
|
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,
|
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;
|
virtual void add_persistent_state_description(td::Ref<PersistentStateDescription> desc) = 0;
|
||||||
|
|
|
@ -32,6 +32,8 @@ namespace ton {
|
||||||
namespace validator {
|
namespace validator {
|
||||||
|
|
||||||
void ValidatorManagerMasterchainReiniter::start_up() {
|
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_;
|
LOG(INFO) << "init_block_id=" << block_id_;
|
||||||
CHECK(block_id_.is_masterchain());
|
CHECK(block_id_.is_masterchain());
|
||||||
CHECK(block_id_.id.shard == shardIdAll);
|
CHECK(block_id_.id.shard == shardIdAll);
|
||||||
|
@ -58,6 +60,7 @@ void ValidatorManagerMasterchainReiniter::got_masterchain_handle(BlockHandle han
|
||||||
key_blocks_.push_back(handle_);
|
key_blocks_.push_back(handle_);
|
||||||
|
|
||||||
if (opts_->initial_sync_disabled()) {
|
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) {
|
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<ShardState>> R) {
|
||||||
R.ensure();
|
R.ensure();
|
||||||
td::actor::send_closure(SelfId, &ValidatorManagerMasterchainReiniter::download_masterchain_state);
|
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];
|
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());
|
auto s = static_cast<td::uint32>(key_blocks_.size());
|
||||||
key_blocks_.resize(key_blocks_.size() + vec.size(), nullptr);
|
key_blocks_.resize(key_blocks_.size() + vec.size(), nullptr);
|
||||||
|
|
||||||
|
@ -247,6 +251,7 @@ void ValidatorManagerMasterchainReiniter::choose_masterchain_state() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ValidatorManagerMasterchainReiniter::download_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) {
|
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<ShardState>> R) {
|
||||||
if (R.is_error()) {
|
if (R.is_error()) {
|
||||||
LOG(WARNING) << "failed to download masterchain state: " << R.move_as_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);
|
td::actor::send_closure(SelfId, &ValidatorManagerMasterchainReiniter::downloaded_all_shards);
|
||||||
});
|
});
|
||||||
client_ = td::actor::create_actor<ShardClient>("shardclient", opts_, handle_, state_, manager_, std::move(P));
|
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() {
|
void ValidatorManagerMasterchainReiniter::downloaded_all_shards() {
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
|
|
||||||
#include "manager-init.h"
|
#include "manager-init.h"
|
||||||
|
|
||||||
|
#include <stats-provider.h>
|
||||||
|
|
||||||
namespace ton {
|
namespace ton {
|
||||||
|
|
||||||
namespace validator {
|
namespace validator {
|
||||||
|
@ -77,6 +79,8 @@ class ValidatorManagerMasterchainReiniter : public td::actor::Actor {
|
||||||
|
|
||||||
td::uint32 pending_ = 0;
|
td::uint32 pending_ = 0;
|
||||||
td::actor::ActorOwn<ShardClient> client_;
|
td::actor::ActorOwn<ShardClient> client_;
|
||||||
|
|
||||||
|
ProcessStatus status_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ValidatorManagerMasterchainStarter : public td::actor::Actor {
|
class ValidatorManagerMasterchainStarter : public td::actor::Actor {
|
||||||
|
|
|
@ -430,6 +430,10 @@ void ValidatorManagerImpl::add_external_message(td::Ref<ExtMessage> msg, int pri
|
||||||
ext_messages_hashes_[id.hash] = {priority, id};
|
ext_messages_hashes_[id.hash] = {priority, id};
|
||||||
}
|
}
|
||||||
void ValidatorManagerImpl::check_external_message(td::BufferSlice data, td::Promise<td::Ref<ExtMessage>> promise) {
|
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();
|
auto state = do_get_last_liteserver_state();
|
||||||
if (state.is_null()) {
|
if (state.is_null()) {
|
||||||
promise.set_error(td::Status::Error(ErrorCode::notready, "not ready"));
|
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),
|
promise = [self = this, wc, addr, promise = std::move(promise),
|
||||||
SelfId = actor_id(this)](td::Result<td::Ref<ExtMessage>> R) mutable {
|
SelfId = actor_id(this)](td::Result<td::Ref<ExtMessage>> R) mutable {
|
||||||
if (R.is_error()) {
|
td::actor::send_lambda(SelfId, [=, promise = std::move(promise), R = std::move(R)]() mutable {
|
||||||
promise.set_error(R.move_as_error());
|
++(R.is_ok() ? self->total_check_ext_messages_ok_ : self->total_check_ext_messages_error_);
|
||||||
return;
|
TRY_RESULT_PROMISE(promise, message, std::move(R));
|
||||||
}
|
|
||||||
td::actor::send_lambda(SelfId, [=, promise = std::move(promise), message = R.move_as_ok()]() mutable {
|
|
||||||
if (self->checked_ext_msg_counter_.inc_msg_count(wc, addr) > max_ext_msg_per_addr()) {
|
if (self->checked_ext_msg_counter_.inc_msg_count(wc, addr) > max_ext_msg_per_addr()) {
|
||||||
promise.set_error(
|
promise.set_error(
|
||||||
td::Status::Error(PSTRING() << "too many external messages to address " << wc << ":" << addr.to_hex()));
|
td::Status::Error(PSTRING() << "too many external messages to address " << wc << ":" << addr.to_hex()));
|
||||||
|
@ -698,11 +700,10 @@ 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) {
|
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));
|
td::actor::send_closure(SelfId, &ValidatorManagerImpl::finished_wait_state, handle, std::move(R));
|
||||||
});
|
});
|
||||||
auto id =
|
auto id = td::actor::create_actor<WaitBlockState>("waitstate", handle, priority, actor_id(this),
|
||||||
td::actor::create_actor<WaitBlockState>("waitstate", handle, priority, actor_id(this),
|
td::Timestamp::at(timeout.at() + 10.0), std::move(P),
|
||||||
td::Timestamp::at(timeout.at() + 10.0), std::move(P),
|
get_block_persistent_state_to_download(handle->id()))
|
||||||
get_block_persistent_state(handle->id()))
|
.release();
|
||||||
.release();
|
|
||||||
wait_state_[handle->id()].actor_ = id;
|
wait_state_[handle->id()].actor_ = id;
|
||||||
it = wait_state_.find(handle->id());
|
it = wait_state_.find(handle->id());
|
||||||
}
|
}
|
||||||
|
@ -1148,9 +1149,10 @@ 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) {
|
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));
|
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,
|
auto id =
|
||||||
std::move(P), get_block_persistent_state(handle->id()))
|
td::actor::create_actor<WaitBlockState>("waitstate", handle, X.second, actor_id(this), X.first,
|
||||||
.release();
|
std::move(P), get_block_persistent_state_to_download(handle->id()))
|
||||||
|
.release();
|
||||||
it->second.actor_ = id;
|
it->second.actor_ = id;
|
||||||
return;
|
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_) {
|
if (allow_validate_) {
|
||||||
for (auto &desc : new_shards) {
|
for (auto &desc : new_shards) {
|
||||||
auto shard = desc.first;
|
auto shard = desc.first;
|
||||||
|
@ -2148,9 +2150,7 @@ void ValidatorManagerImpl::update_shards() {
|
||||||
auto validator_id = get_validator(shard, val_set);
|
auto validator_id = get_validator(shard, val_set);
|
||||||
|
|
||||||
if (!validator_id.is_zero()) {
|
if (!validator_id.is_zero()) {
|
||||||
if (shard.is_masterchain()) {
|
++(shard.is_masterchain() ? active_validator_groups_master_ : active_validator_groups_shard_);
|
||||||
validating_masterchain = true;
|
|
||||||
}
|
|
||||||
auto val_group_id = get_validator_set_id(shard, val_set, opts_hash, key_seqno, opts);
|
auto val_group_id = get_validator_set_id(shard, val_set, opts_hash, key_seqno, opts);
|
||||||
|
|
||||||
if (force_recover) {
|
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("knownkeymasterchainblock", last_known_key_block_handle_->id().to_str());
|
||||||
vec.emplace_back("rotatemasterchainblock", last_rotate_block_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("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) {
|
td::NamedThreadSafeCounter::get_default().for_each([&](auto key, auto value) {
|
||||||
vec.emplace_back("counter." + key, PSTRING() << 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));
|
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));
|
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."));
|
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) {
|
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);
|
auto it = persistent_state_blocks_.find(block_id);
|
||||||
if (it == persistent_state_blocks_.end()) {
|
if (it == persistent_state_blocks_.end()) {
|
||||||
return {};
|
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;
|
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,
|
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);
|
auto &record = new_block_stats_record(block_id);
|
||||||
record.collator_work_time_ = work_time;
|
record.collator_work_time_ = work_time;
|
||||||
record.collator_cpu_work_time_ = cpu_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);
|
auto &record = new_block_stats_record(block_id);
|
||||||
record.validator_work_time_ = work_time;
|
record.validator_work_time_ = work_time;
|
||||||
record.validator_cpu_work_time_ = cpu_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) {
|
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];
|
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) {
|
size_t ValidatorManagerImpl::CheckedExtMsgCounter::get_msg_count(WorkchainId wc, StdSmcAddress addr) {
|
||||||
before_query();
|
before_query();
|
||||||
auto it1 = counter_cur_.find({wc, addr});
|
auto it1 = counter_cur_.find({wc, addr});
|
||||||
|
|
|
@ -655,8 +655,9 @@ class ValidatorManagerImpl : public ValidatorManager {
|
||||||
td::optional<ShardIdFull> shard,
|
td::optional<ShardIdFull> shard,
|
||||||
td::Promise<tl_object_ptr<lite_api::liteServer_nonfinal_validatorGroups>> promise) override;
|
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];
|
++ls_stats_[lite_query_id];
|
||||||
|
++(success ? total_ls_queries_ok_ : total_ls_queries_error_)[lite_query_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -733,7 +734,7 @@ class ValidatorManagerImpl : public ValidatorManager {
|
||||||
|
|
||||||
void got_persistent_state_descriptions(std::vector<td::Ref<PersistentStateDescription>> descs);
|
void got_persistent_state_descriptions(std::vector<td::Ref<PersistentStateDescription>> descs);
|
||||||
void add_persistent_state_description_impl(td::Ref<PersistentStateDescription> desc);
|
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:
|
private:
|
||||||
bool need_monitor(ShardIdFull shard) const {
|
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
|
std::map<int, td::uint32> ls_stats_; // lite_api ID -> count, 0 for unknown
|
||||||
td::uint32 ls_stats_check_ext_messages_{0};
|
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_;
|
td::actor::ActorOwn<CandidatesBuffer> candidates_buffer_;
|
||||||
|
|
||||||
struct RecordedBlockStats {
|
struct RecordedBlockStats {
|
||||||
|
@ -760,16 +771,25 @@ class ValidatorManagerImpl : public ValidatorManager {
|
||||||
std::queue<BlockIdExt> recorded_block_stats_lru_;
|
std::queue<BlockIdExt> recorded_block_stats_lru_;
|
||||||
|
|
||||||
void record_collate_query_stats(BlockIdExt block_id, double work_time, double cpu_work_time,
|
void record_collate_query_stats(BlockIdExt block_id, double work_time, double cpu_work_time,
|
||||||
CollationStats stats) override;
|
td::optional<CollationStats> stats) override;
|
||||||
void record_validate_query_stats(BlockIdExt block_id, double work_time, double cpu_work_time) 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);
|
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_;
|
std::map<PublicKeyHash, td::actor::ActorOwn<ValidatorTelemetry>> validator_telemetry_;
|
||||||
|
|
||||||
void init_validator_telemetry();
|
void init_validator_telemetry();
|
||||||
|
|
||||||
std::map<BlockSeqno, td::Ref<PersistentStateDescription>> persistent_state_descriptions_;
|
std::map<BlockSeqno, td::Ref<PersistentStateDescription>> persistent_state_descriptions_;
|
||||||
std::map<BlockIdExt, td::Ref<PersistentStateDescription>> persistent_state_blocks_;
|
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
|
} // namespace validator
|
||||||
|
|
|
@ -70,6 +70,7 @@ void DownloadState::finish_query() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadState::start_up() {
|
void DownloadState::start_up() {
|
||||||
|
status_ = ProcessStatus(validator_manager_, "process.download_state_net");
|
||||||
alarm_timestamp() = timeout_;
|
alarm_timestamp() = timeout_;
|
||||||
|
|
||||||
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_persistent_state, block_id_,
|
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));
|
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) {
|
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));
|
parts_.push_back(std::move(data));
|
||||||
|
|
||||||
double elapsed = prev_logged_timer_.elapsed();
|
double elapsed = prev_logged_timer_.elapsed();
|
||||||
if (elapsed > 10.0) {
|
if (elapsed > 5.0) {
|
||||||
prev_logged_timer_ = td::Timer();
|
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_) << " ("
|
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_;
|
prev_logged_sum_ = sum_;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (last_part) {
|
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_)};
|
td::BufferSlice res{td::narrow_cast<std::size_t>(sum_)};
|
||||||
auto S = res.as_slice();
|
auto S = res.as_slice();
|
||||||
for (auto &p : parts_) {
|
for (auto &p : parts_) {
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
#include "validator/validator.h"
|
#include "validator/validator.h"
|
||||||
#include "adnl/adnl-ext-client.h"
|
#include "adnl/adnl-ext-client.h"
|
||||||
|
|
||||||
|
#include <stats-provider.h>
|
||||||
|
|
||||||
namespace ton {
|
namespace ton {
|
||||||
|
|
||||||
namespace validator {
|
namespace validator {
|
||||||
|
@ -75,6 +77,8 @@ class DownloadState : public td::actor::Actor {
|
||||||
|
|
||||||
td::uint64 prev_logged_sum_ = 0;
|
td::uint64 prev_logged_sum_ = 0;
|
||||||
td::Timer prev_logged_timer_;
|
td::Timer prev_logged_timer_;
|
||||||
|
|
||||||
|
ProcessStatus status_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace fullnode
|
} // namespace fullnode
|
||||||
|
|
|
@ -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));
|
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) {
|
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::actor::send_closure(SelfId, &AsyncStateSerializer::request_previous_state_files);
|
||||||
},
|
},
|
||||||
td::Timestamp::in(delay));
|
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;
|
return;
|
||||||
}
|
}
|
||||||
if (next_idx_ < shards_.size()) {
|
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(),
|
td::actor::send_closure(manager_, &ValidatorManager::store_persistent_state_file_gen, masterchain_handle_->id(),
|
||||||
masterchain_handle_->id(), write_data, std::move(P));
|
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() {
|
void AsyncStateSerializer::stored_masterchain_state() {
|
||||||
|
current_status_ = "pending";
|
||||||
|
current_status_ts_ = {};
|
||||||
LOG(ERROR) << "finished serializing masterchain state " << masterchain_handle_->id().id.to_str();
|
LOG(ERROR) << "finished serializing masterchain state " << masterchain_handle_->id().id.to_str();
|
||||||
running_ = false;
|
running_ = false;
|
||||||
next_iteration();
|
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(),
|
td::actor::send_closure(manager_, &ValidatorManager::store_persistent_state_file_gen, handle->id(),
|
||||||
masterchain_handle_->id(), write_data, std::move(P));
|
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) {
|
void AsyncStateSerializer::fail_handler(td::Status reason) {
|
||||||
|
current_status_ = PSTRING() << "pending, " << reason;
|
||||||
|
current_status_ts_ = {};
|
||||||
VLOG(VALIDATOR_NOTICE) << "failure: " << reason;
|
VLOG(VALIDATOR_NOTICE) << "failure: " << reason;
|
||||||
attempt_++;
|
attempt_++;
|
||||||
delay_action(
|
delay_action(
|
||||||
|
@ -460,6 +479,8 @@ void AsyncStateSerializer::fail_handler_cont() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AsyncStateSerializer::success_handler() {
|
void AsyncStateSerializer::success_handler() {
|
||||||
|
current_status_ = "pending";
|
||||||
|
current_status_ts_ = {};
|
||||||
running_ = false;
|
running_ = false;
|
||||||
next_iteration();
|
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) {
|
bool AsyncStateSerializer::need_serialize(BlockHandle handle) {
|
||||||
if (handle->id().id.seqno == 0 || !handle->is_key_block()) {
|
if (handle->id().id.seqno == 0 || !handle->is_key_block()) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -36,6 +36,9 @@ class AsyncStateSerializer : public td::actor::Actor {
|
||||||
UnixTime last_key_block_ts_ = 0;
|
UnixTime last_key_block_ts_ = 0;
|
||||||
bool saved_to_db_ = true;
|
bool saved_to_db_ = true;
|
||||||
|
|
||||||
|
bool inited_block_id_ = false;
|
||||||
|
std::vector<td::Promise<td::Unit>> wait_init_block_id_;
|
||||||
|
|
||||||
td::Ref<ValidatorManagerOptions> opts_;
|
td::Ref<ValidatorManagerOptions> opts_;
|
||||||
bool auto_disabled_ = false;
|
bool auto_disabled_ = false;
|
||||||
td::CancellationTokenSource cancellation_token_source_;
|
td::CancellationTokenSource cancellation_token_source_;
|
||||||
|
@ -95,6 +98,8 @@ class AsyncStateSerializer : public td::actor::Actor {
|
||||||
promise.set_result(last_block_id_.id.seqno);
|
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) {
|
void update_last_known_key_block_ts(UnixTime ts) {
|
||||||
last_known_key_block_ts_ = std::max(last_known_key_block_ts_, 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 update_options(td::Ref<ValidatorManagerOptions> opts);
|
||||||
void auto_disable_serializer(bool disabled);
|
void auto_disable_serializer(bool disabled);
|
||||||
|
|
||||||
|
std::string current_status_ = "pending";
|
||||||
|
td::Timestamp current_status_ts_ = td::Timestamp::never();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace validator
|
} // namespace validator
|
||||||
|
|
105
validator/stats-provider.h
Normal file
105
validator/stats-provider.h
Normal 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
|
|
@ -373,6 +373,7 @@ void ValidatorGroup::create_session() {
|
||||||
}
|
}
|
||||||
CHECK(found);
|
CHECK(found);
|
||||||
|
|
||||||
|
config_.catchain_opts.broadcast_speed_multiplier = opts_->get_catchain_broadcast_speed_multiplier();
|
||||||
if (!config_.new_catchain_ids) {
|
if (!config_.new_catchain_ids) {
|
||||||
session_ = validatorsession::ValidatorSession::create(session_id_, config_, local_id_, std::move(vec),
|
session_ = validatorsession::ValidatorSession::create(session_id_, config_, local_id_, std::move(vec),
|
||||||
make_validator_session_callback(), keyring_, adnl_, rldp_,
|
make_validator_session_callback(), keyring_, adnl_, rldp_,
|
||||||
|
|
|
@ -154,6 +154,9 @@ struct ValidatorManagerOptionsImpl : public ValidatorManagerOptions {
|
||||||
bool get_fast_state_serializer_enabled() const override {
|
bool get_fast_state_serializer_enabled() const override {
|
||||||
return fast_state_serializer_enabled_;
|
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 {
|
void set_zero_block_id(BlockIdExt block_id) override {
|
||||||
zero_block_id_ = block_id;
|
zero_block_id_ = block_id;
|
||||||
|
@ -249,6 +252,9 @@ struct ValidatorManagerOptionsImpl : public ValidatorManagerOptions {
|
||||||
void set_fast_state_serializer_enabled(bool value) override {
|
void set_fast_state_serializer_enabled(bool value) override {
|
||||||
fast_state_serializer_enabled_ = value;
|
fast_state_serializer_enabled_ = value;
|
||||||
}
|
}
|
||||||
|
void set_catchain_broadcast_speed_multiplier(double value) override {
|
||||||
|
catchain_broadcast_speed_multipliers_ = value;
|
||||||
|
}
|
||||||
|
|
||||||
ValidatorManagerOptionsImpl *make_copy() const override {
|
ValidatorManagerOptionsImpl *make_copy() const override {
|
||||||
return new ValidatorManagerOptionsImpl(*this);
|
return new ValidatorManagerOptionsImpl(*this);
|
||||||
|
@ -302,6 +308,7 @@ struct ValidatorManagerOptionsImpl : public ValidatorManagerOptions {
|
||||||
bool state_serializer_enabled_ = true;
|
bool state_serializer_enabled_ = true;
|
||||||
td::Ref<CollatorOptions> collator_options_{true};
|
td::Ref<CollatorOptions> collator_options_{true};
|
||||||
bool fast_state_serializer_enabled_ = false;
|
bool fast_state_serializer_enabled_ = false;
|
||||||
|
double catchain_broadcast_speed_multipliers_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace validator
|
} // namespace validator
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#include "td/actor/actor.h"
|
#include "td/actor/actor.h"
|
||||||
|
|
||||||
|
@ -115,6 +116,7 @@ struct ValidatorManagerOptions : public td::CntObject {
|
||||||
virtual bool get_state_serializer_enabled() const = 0;
|
virtual bool get_state_serializer_enabled() const = 0;
|
||||||
virtual td::Ref<CollatorOptions> get_collator_options() const = 0;
|
virtual td::Ref<CollatorOptions> get_collator_options() const = 0;
|
||||||
virtual bool get_fast_state_serializer_enabled() 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_zero_block_id(BlockIdExt block_id) = 0;
|
||||||
virtual void set_init_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_state_serializer_enabled(bool value) = 0;
|
||||||
virtual void set_collator_options(td::Ref<CollatorOptions> 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_fast_state_serializer_enabled(bool value) = 0;
|
||||||
|
virtual void set_catchain_broadcast_speed_multiplier(double value) = 0;
|
||||||
|
|
||||||
static td::Ref<ValidatorManagerOptions> create(
|
static td::Ref<ValidatorManagerOptions> create(
|
||||||
BlockIdExt zero_block_id, BlockIdExt init_block_id,
|
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 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 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
|
} // namespace validator
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue