mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
emergency update
This commit is contained in:
parent
5d846e0aaf
commit
9f351fc29f
87 changed files with 2486 additions and 655 deletions
|
@ -79,8 +79,8 @@ void ApplyBlock::got_block_handle(BlockHandle handle) {
|
|||
}
|
||||
|
||||
if (handle_->is_applied()) {
|
||||
auto P = td::PromiseCreator::lambda(
|
||||
[ SelfId = actor_id(this), seqno = handle_->id().id.seqno ](td::Result<BlockIdExt> R) {
|
||||
auto P =
|
||||
td::PromiseCreator::lambda([SelfId = actor_id(this), seqno = handle_->id().id.seqno](td::Result<BlockIdExt> R) {
|
||||
R.ensure();
|
||||
auto h = R.move_as_ok();
|
||||
if (h.id.seqno < seqno) {
|
||||
|
@ -119,15 +119,14 @@ void ApplyBlock::got_block_handle(BlockHandle handle) {
|
|||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_block_data, handle_, block_, std::move(P));
|
||||
} else {
|
||||
auto P =
|
||||
td::PromiseCreator::lambda([ SelfId = actor_id(this), handle = handle_ ](td::Result<td::Ref<BlockData>> R) {
|
||||
CHECK(handle->received());
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &ApplyBlock::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &ApplyBlock::written_block_data);
|
||||
}
|
||||
});
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), handle = handle_](td::Result<td::Ref<BlockData>> R) {
|
||||
CHECK(handle->received());
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &ApplyBlock::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &ApplyBlock::written_block_data);
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::wait_block_data, handle_, apply_block_priority(), timeout_,
|
||||
std::move(P));
|
||||
|
@ -136,19 +135,25 @@ void ApplyBlock::got_block_handle(BlockHandle handle) {
|
|||
|
||||
void ApplyBlock::written_block_data() {
|
||||
VLOG(VALIDATOR_DEBUG) << "apply block: written block data for " << id_;
|
||||
if (handle_->id().is_masterchain() && !handle_->inited_proof()) {
|
||||
abort_query(td::Status::Error(ErrorCode::notready, "proof is absent"));
|
||||
return;
|
||||
if (!handle_->id().seqno()) {
|
||||
CHECK(handle_->inited_split_after());
|
||||
CHECK(handle_->inited_state_root_hash());
|
||||
CHECK(handle_->inited_logical_time());
|
||||
} else {
|
||||
if (handle_->id().is_masterchain() && !handle_->inited_proof()) {
|
||||
abort_query(td::Status::Error(ErrorCode::notready, "proof is absent"));
|
||||
return;
|
||||
}
|
||||
if (!handle_->id().is_masterchain() && !handle_->inited_proof_link()) {
|
||||
abort_query(td::Status::Error(ErrorCode::notready, "proof link is absent"));
|
||||
return;
|
||||
}
|
||||
CHECK(handle_->inited_merge_before());
|
||||
CHECK(handle_->inited_split_after());
|
||||
CHECK(handle_->inited_prev());
|
||||
CHECK(handle_->inited_state_root_hash());
|
||||
CHECK(handle_->inited_logical_time());
|
||||
}
|
||||
if (!handle_->id().is_masterchain() && !handle_->inited_proof_link()) {
|
||||
abort_query(td::Status::Error(ErrorCode::notready, "proof link is absent"));
|
||||
return;
|
||||
}
|
||||
CHECK(handle_->inited_merge_before());
|
||||
CHECK(handle_->inited_split_after());
|
||||
CHECK(handle_->inited_prev());
|
||||
CHECK(handle_->inited_state_root_hash());
|
||||
CHECK(handle_->inited_logical_time());
|
||||
if (handle_->is_applied() && handle_->processed()) {
|
||||
finish_query();
|
||||
} else {
|
||||
|
|
|
@ -39,6 +39,9 @@ namespace validator {
|
|||
using td::Ref;
|
||||
|
||||
class Collator final : public td::actor::Actor {
|
||||
static constexpr int supported_version = 1;
|
||||
static constexpr long long supported_capabilities =
|
||||
ton::capCreateStatsEnabled | ton::capBounceMsgBody | ton::capReportVersion;
|
||||
using LtCellRef = block::LtCellRef;
|
||||
using NewOutMsg = block::NewOutMsg;
|
||||
const ShardIdFull shard;
|
||||
|
@ -137,6 +140,7 @@ class Collator final : public td::actor::Actor {
|
|||
bool shard_conf_adjusted_{false};
|
||||
bool ihr_enabled_{false};
|
||||
bool create_stats_enabled_{false};
|
||||
bool report_version_{false};
|
||||
td::uint64 overload_history_{0}, underload_history_{0};
|
||||
td::uint64 block_size_estimate_{};
|
||||
Ref<block::WorkchainInfo> wc_info_;
|
||||
|
@ -286,6 +290,7 @@ class Collator final : public td::actor::Actor {
|
|||
bool store_master_ref(vm::CellBuilder& cb);
|
||||
bool store_prev_blk_ref(vm::CellBuilder& cb, bool after_merge);
|
||||
bool store_zero_state_ref(vm::CellBuilder& cb);
|
||||
bool store_version(vm::CellBuilder& cb) const;
|
||||
bool create_block_info(Ref<vm::Cell>& block_info);
|
||||
bool check_value_flow();
|
||||
bool create_block_extra(Ref<vm::Cell>& block_extra);
|
||||
|
|
|
@ -510,6 +510,7 @@ bool Collator::unpack_last_mc_state() {
|
|||
global_id_ = config_->get_global_blockchain_id();
|
||||
ihr_enabled_ = config_->ihr_enabled();
|
||||
create_stats_enabled_ = config_->create_stats_enabled();
|
||||
report_version_ = config_->has_capability(ton::capReportVersion);
|
||||
shard_conf_ = std::make_unique<block::ShardConfig>(*config_);
|
||||
prev_key_block_exists_ = config_->get_last_key_block(prev_key_block_, prev_key_block_lt_);
|
||||
if (prev_key_block_exists_) {
|
||||
|
@ -529,6 +530,16 @@ bool Collator::unpack_last_mc_state() {
|
|||
<< ", " << block_limits_->bytes.hard() << "]";
|
||||
LOG(DEBUG) << "block limits: gas [" << block_limits_->gas.underload() << ", " << block_limits_->gas.soft() << ", "
|
||||
<< block_limits_->gas.hard() << "]";
|
||||
if (config_->has_capabilities() && (config_->get_capabilities() & ~supported_capabilities)) {
|
||||
LOG(ERROR) << "block generation capabilities " << config_->get_capabilities()
|
||||
<< " have been enabled in global configuration, but we support only " << supported_capabilities
|
||||
<< " (upgrade validator software?)";
|
||||
}
|
||||
if (config_->get_global_version() > supported_version) {
|
||||
LOG(ERROR) << "block version " << config_->get_global_version()
|
||||
<< " have been enabled in global configuration, but we support only " << supported_version
|
||||
<< " (upgrade validator software?)";
|
||||
}
|
||||
// TODO: extract start_lt and end_lt from prev_mc_block as well
|
||||
// std::cerr << " block::gen::ShardState::print_ref(mc_state_root) = ";
|
||||
// block::gen::t_ShardState.print_ref(std::cerr, mc_state_root, 2);
|
||||
|
@ -1502,6 +1513,7 @@ bool Collator::fetch_config_params() {
|
|||
block::MsgPrices{rec.lump_price, rec.bit_price, rec.cell_price, rec.ihr_price_factor,
|
||||
(unsigned)rec.first_frac, (unsigned)rec.next_frac};
|
||||
action_phase_cfg_.workchains = &config_->get_workchain_list();
|
||||
action_phase_cfg_.bounce_msg_body = (config_->has_capability(ton::capBounceMsgBody) ? 256 : 0);
|
||||
}
|
||||
{
|
||||
// fetch block_grams_created
|
||||
|
@ -3571,7 +3583,7 @@ bool Collator::create_block_info(Ref<vm::Cell>& block_info) {
|
|||
&& cb.store_bool_bool(want_split_) // want_split:Bool
|
||||
&& cb.store_bool_bool(want_merge_) // want_merge:Bool
|
||||
&& cb.store_bool_bool(is_key_block_) // key_block:Bool
|
||||
&& cb.store_long_bool(0, 9) // vert_seqno_incr:(## 1) flags:(## 8)
|
||||
&& cb.store_long_bool((int)report_version_, 9) // vert_seqno_incr:(## 1) flags:(## 8)
|
||||
&& cb.store_long_bool(new_block_seqno, 32) // seq_no:#
|
||||
&& cb.store_long_bool(vert_seqno_, 32) // vert_seq_no:#
|
||||
&& block::ShardId{shard}.serialize(cb) // shard:ShardIdent
|
||||
|
@ -3582,6 +3594,7 @@ bool Collator::create_block_info(Ref<vm::Cell>& block_info) {
|
|||
&& cb.store_long_bool(cc_seqno, 32) // gen_catchain_seqno:uint32
|
||||
&& cb.store_long_bool(min_ref_mc_seqno_, 32) // min_ref_mc_seqno:uint32
|
||||
&& cb.store_long_bool(prev_key_block_seqno_, 32) // prev_key_block_seqno:uint32
|
||||
&& (!report_version_ || store_version(cb)) // gen_software:flags . 0?GlobalVersion
|
||||
&& (mc || (store_master_ref(cb2) // master_ref:not_master?
|
||||
&& cb.store_builder_ref_bool(std::move(cb2)))) // .. ^BlkMasterInfo
|
||||
&& store_prev_blk_ref(cb2, after_merge_) // prev_ref:..
|
||||
|
@ -3589,6 +3602,10 @@ bool Collator::create_block_info(Ref<vm::Cell>& block_info) {
|
|||
&& cb.finalize_to(block_info);
|
||||
}
|
||||
|
||||
bool Collator::store_version(vm::CellBuilder& cb) const {
|
||||
return block::gen::t_GlobalVersion.pack_capabilities(cb, supported_version, supported_capabilities);
|
||||
}
|
||||
|
||||
bool Collator::store_zero_state_ref(vm::CellBuilder& cb) {
|
||||
CHECK(prev_state_root_.not_null());
|
||||
RootHash root_hash = prev_state_root_->get_hash().bits();
|
||||
|
|
|
@ -679,6 +679,17 @@ bool ValidateQuery::try_unpack_mc_state() {
|
|||
config_->set_block_id_ext(mc_blkid_);
|
||||
ihr_enabled_ = config_->ihr_enabled();
|
||||
create_stats_enabled_ = config_->create_stats_enabled();
|
||||
if (config_->has_capabilities() && (config_->get_capabilities() & ~supported_capabilities)) {
|
||||
LOG(ERROR) << "block generation capabilities " << config_->get_capabilities()
|
||||
<< " have been enabled in global configuration, but we support only " << supported_capabilities
|
||||
<< " (upgrade validator software?)";
|
||||
}
|
||||
if (config_->get_global_version() > supported_version) {
|
||||
LOG(ERROR) << "block version " << config_->get_global_version()
|
||||
<< " have been enabled in global configuration, but we support only " << supported_version
|
||||
<< " (upgrade validator software?)";
|
||||
}
|
||||
|
||||
old_shard_conf_ = std::make_unique<block::ShardConfig>(*config_);
|
||||
if (!is_masterchain()) {
|
||||
new_shard_conf_ = std::make_unique<block::ShardConfig>(*config_);
|
||||
|
@ -772,6 +783,7 @@ bool ValidateQuery::fetch_config_params() {
|
|||
block::MsgPrices{rec.lump_price, rec.bit_price, rec.cell_price, rec.ihr_price_factor,
|
||||
(unsigned)rec.first_frac, (unsigned)rec.next_frac};
|
||||
action_phase_cfg_.workchains = &config_->get_workchain_list();
|
||||
action_phase_cfg_.bounce_msg_body = (config_->has_capability(ton::capBounceMsgBody) ? 256 : 0);
|
||||
}
|
||||
{
|
||||
// fetch block_grams_created
|
||||
|
@ -4832,7 +4844,7 @@ bool ValidateQuery::check_config_update(Ref<vm::CellSlice> old_conf_params, Ref<
|
|||
}
|
||||
if (!block::valid_config_data(ocfg_root, old_cfg_addr, true, true, old_mparams_)) {
|
||||
return reject_query("configuration extracted from (old) configuration smart contract "s + old_cfg_addr.to_hex() +
|
||||
" failed to pass per-parameted validity checks, or one of mandatory parameters is missing");
|
||||
" failed to pass per-parameter validity checks, or one of mandatory parameters is missing");
|
||||
}
|
||||
if (block::important_config_parameters_changed(new_cfg_root, old_cfg_root)) {
|
||||
// same as the check in Collator::create_mc_state_extra()
|
||||
|
|
|
@ -107,6 +107,10 @@ inline ErrorCtxSet ErrorCtx::set_guard(std::vector<std::string> str_list) {
|
|||
*/
|
||||
|
||||
class ValidateQuery : public td::actor::Actor {
|
||||
static constexpr int supported_version = 1;
|
||||
static constexpr long long supported_capabilities =
|
||||
ton::capCreateStatsEnabled | ton::capBounceMsgBody | ton::capReportVersion;
|
||||
|
||||
public:
|
||||
ValidateQuery(ShardIdFull shard, UnixTime min_ts, BlockIdExt min_masterchain_block_id, std::vector<BlockIdExt> prev,
|
||||
BlockCandidate candidate, td::Ref<ValidatorSet> validator_set,
|
||||
|
|
|
@ -382,7 +382,6 @@ void ArchiveImporter::finish_query() {
|
|||
if (promise_) {
|
||||
promise_.set_value(
|
||||
std::vector<BlockSeqno>{state_->get_seqno(), std::min<BlockSeqno>(state_->get_seqno(), shard_client_seqno_)});
|
||||
td::unlink(path_).ensure();
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
|
|
@ -1393,6 +1393,39 @@ void ValidatorManagerImpl::start_up() {
|
|||
td::actor::send_closure(SelfId, &ValidatorManagerImpl::started, R.move_as_ok());
|
||||
});
|
||||
|
||||
auto to_import_dir = db_root_ + "/import";
|
||||
auto S = td::WalkPath::run(to_import_dir, [&](td::CSlice cfname, td::WalkPath::Type t) -> void {
|
||||
auto fname = td::Slice(cfname);
|
||||
if (t == td::WalkPath::Type::NotDir) {
|
||||
auto d = fname.rfind('/');
|
||||
if (d != td::Slice::npos) {
|
||||
fname = fname.substr(d + 1);
|
||||
}
|
||||
if (fname.size() <= 13) {
|
||||
return;
|
||||
}
|
||||
if (fname.substr(fname.size() - 5) != ".pack") {
|
||||
return;
|
||||
}
|
||||
fname = fname.substr(0, fname.size() - 5);
|
||||
if (fname.substr(0, 8) != "archive.") {
|
||||
return;
|
||||
}
|
||||
fname = fname.substr(8);
|
||||
|
||||
auto v = td::to_integer_safe<BlockSeqno>(fname);
|
||||
if (v.is_error()) {
|
||||
return;
|
||||
}
|
||||
auto pos = v.move_as_ok();
|
||||
LOG(INFO) << "found archive slice '" << cfname << "' for position " << pos;
|
||||
to_import_[pos] = std::make_pair(cfname.str(), true);
|
||||
}
|
||||
});
|
||||
if (S.is_error()) {
|
||||
LOG(INFO) << "failed to load blocks from import dir: " << S;
|
||||
}
|
||||
|
||||
validator_manager_init(opts_, actor_id(this), db_.get(), std::move(P));
|
||||
|
||||
check_waiters_at_ = td::Timestamp::in(1.0);
|
||||
|
@ -1475,23 +1508,35 @@ void ValidatorManagerImpl::download_next_archive() {
|
|||
finish_prestart_sync();
|
||||
return;
|
||||
}
|
||||
|
||||
auto seqno = std::min(last_masterchain_seqno_, shard_client_handle_->id().seqno());
|
||||
auto it = to_import_.upper_bound(seqno);
|
||||
if (it != to_import_.begin()) {
|
||||
it--;
|
||||
if (it->second.second) {
|
||||
it->second.second = false;
|
||||
downloaded_archive_slice(it->second.first, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<std::string> R) {
|
||||
if (R.is_error()) {
|
||||
LOG(INFO) << "failed to download archive slice: " << R.error();
|
||||
delay_action([SelfId]() { td::actor::send_closure(SelfId, &ValidatorManagerImpl::download_next_archive); },
|
||||
td::Timestamp::in(2.0));
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &ValidatorManagerImpl::downloaded_archive_slice, R.move_as_ok());
|
||||
td::actor::send_closure(SelfId, &ValidatorManagerImpl::downloaded_archive_slice, R.move_as_ok(), true);
|
||||
}
|
||||
});
|
||||
|
||||
auto seqno = std::min(last_masterchain_seqno_, shard_client_handle_->id().seqno());
|
||||
callback_->download_archive(seqno + 1, db_root_ + "/tmp/", td::Timestamp::in(3600.0), std::move(P));
|
||||
}
|
||||
|
||||
void ValidatorManagerImpl::downloaded_archive_slice(std::string name) {
|
||||
void ValidatorManagerImpl::downloaded_archive_slice(std::string name, bool is_tmp) {
|
||||
LOG(INFO) << "downloaded archive slice: " << name;
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<std::vector<BlockSeqno>> R) {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), name, is_tmp](td::Result<std::vector<BlockSeqno>> R) {
|
||||
if (is_tmp) {
|
||||
td::unlink(name).ensure();
|
||||
}
|
||||
if (R.is_error()) {
|
||||
LOG(INFO) << "failed to check downloaded archive slice: " << R.error();
|
||||
delay_action([SelfId]() { td::actor::send_closure(SelfId, &ValidatorManagerImpl::download_next_archive); },
|
||||
|
@ -1539,6 +1584,8 @@ void ValidatorManagerImpl::checked_archive_slice(std::vector<BlockSeqno> seqno)
|
|||
}
|
||||
|
||||
void ValidatorManagerImpl::finish_prestart_sync() {
|
||||
to_import_.clear();
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
R.ensure();
|
||||
td::actor::send_closure(SelfId, &ValidatorManagerImpl::completed_prestart_sync);
|
||||
|
@ -1665,6 +1712,16 @@ void ValidatorManagerImpl::update_shards() {
|
|||
|
||||
if (!validator_id.is_zero()) {
|
||||
auto val_group_id = get_validator_set_id(shard, val_set, opts_hash);
|
||||
|
||||
// DIRTY. But we don't want to create hardfork now
|
||||
// TODO! DELETE IT LATER
|
||||
if (last_masterchain_seqno_ >= 2904932 && val_set->get_catchain_seqno() == 44896) {
|
||||
if (opts_->zero_block_id().file_hash.to_hex() ==
|
||||
"5E994FCF4D425C0A6CE6A792594B7173205F740A39CD56F537DEFD28B48A0F6E") {
|
||||
val_group_id[0] = !val_group_id[0];
|
||||
}
|
||||
}
|
||||
|
||||
VLOG(VALIDATOR_DEBUG) << "validating group " << val_group_id;
|
||||
auto it = validator_groups_.find(val_group_id);
|
||||
if (it != validator_groups_.end()) {
|
||||
|
|
|
@ -264,7 +264,7 @@ class ValidatorManagerImpl : public ValidatorManager {
|
|||
bool out_of_sync();
|
||||
void prestart_sync();
|
||||
void download_next_archive();
|
||||
void downloaded_archive_slice(std::string name);
|
||||
void downloaded_archive_slice(std::string name, bool is_tmp);
|
||||
void checked_archive_slice(std::vector<BlockSeqno> seqno);
|
||||
void finish_prestart_sync();
|
||||
void completed_prestart_sync();
|
||||
|
@ -556,6 +556,8 @@ class ValidatorManagerImpl : public ValidatorManager {
|
|||
|
||||
td::actor::ActorOwn<AsyncStateSerializer> serializer_;
|
||||
|
||||
std::map<BlockSeqno, std::pair<std::string, bool>> to_import_;
|
||||
|
||||
private:
|
||||
std::unique_ptr<Callback> callback_;
|
||||
td::actor::ActorOwn<Db> db_;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue