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

Merge branch 'testnet' into block-generation

This commit is contained in:
SpyCheese 2024-02-01 19:29:25 +03:00
commit f4fd3ff3be
246 changed files with 7895 additions and 5430 deletions

View file

@ -629,6 +629,12 @@ void ValidatorManagerImpl::wait_block_state(BlockHandle handle, td::uint32 prior
return promise.set_error(
td::Status::Error(PSTRING() << "not monitoring shard " << handle->id().shard_full().to_str()));
}
auto it0 = block_state_cache_.find(handle->id());
if (it0 != block_state_cache_.end()) {
it0->second.ttl_ = td::Timestamp::in(30.0);
promise.set_result(it0->second.state_);
return;
}
auto it = wait_state_.find(handle->id());
if (it == wait_state_.end()) {
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), handle](td::Result<td::Ref<ShardState>> R) {
@ -889,6 +895,8 @@ void ValidatorManagerImpl::wait_block_message_queue_short(BlockIdExt block_id, t
void ValidatorManagerImpl::get_external_messages(ShardIdFull shard,
td::Promise<std::vector<td::Ref<ExtMessage>>> promise) {
td::Timer t;
size_t processed = 0, deleted = 0;
std::vector<td::Ref<ExtMessage>> res;
MessageId<ExtMessage> left{AccountIdPrefixFull{shard.workchain, shard.shard & (shard.shard - 1)}, Bits256::zero()};
auto it = ext_messages_.lower_bound(left);
@ -897,10 +905,12 @@ void ValidatorManagerImpl::get_external_messages(ShardIdFull shard,
if (!shard_contains(shard, s.dst)) {
break;
}
++processed;
if (it->second->expired()) {
ext_addr_messages_[it->second->address()].erase(it->first.hash);
ext_messages_hashes_.erase(it->first.hash);
it = ext_messages_.erase(it);
++deleted;
continue;
}
if (it->second->is_active()) {
@ -908,6 +918,9 @@ void ValidatorManagerImpl::get_external_messages(ShardIdFull shard,
}
it++;
}
LOG(WARNING) << "get_external_messages to shard " << shard.to_str() << " : time=" << t.elapsed()
<< " result_size=" << res.size() << " processed=" << processed << " expired=" << deleted
<< " total_size=" << ext_messages_.size();
promise.set_value(std::move(res));
}
@ -1102,6 +1115,9 @@ void ValidatorManagerImpl::get_block_by_seqno_from_db(AccountIdPrefixFull accoun
}
void ValidatorManagerImpl::finished_wait_state(BlockHandle handle, td::Result<td::Ref<ShardState>> R) {
if (R.is_ok()) {
block_state_cache_[handle->id()] = {R.ok(), td::Timestamp::in(30.0)};
}
auto it = wait_state_.find(handle->id());
if (it != wait_state_.end()) {
if (R.is_error()) {
@ -1461,7 +1477,18 @@ td::Ref<MasterchainState> ValidatorManagerImpl::do_get_last_liteserver_state() {
if (last_masterchain_state_.is_null()) {
return {};
}
if (last_liteserver_state_.is_null() || last_liteserver_state_->get_unix_time() < td::Clocks::system() - 30) {
if (last_liteserver_state_.is_null()) {
last_liteserver_state_ = last_masterchain_state_;
return last_liteserver_state_;
}
if (last_liteserver_state_->get_seqno() == last_masterchain_state_->get_seqno()) {
return last_liteserver_state_;
}
// If liteserver seqno (i.e. shard client) lags then use last masterchain state for liteserver
// Allowed lag depends on the block rate
double time_per_block = double(last_masterchain_state_->get_unix_time() - last_liteserver_state_->get_unix_time()) /
double(last_masterchain_state_->get_seqno() - last_liteserver_state_->get_seqno());
if (td::Clocks::system() - double(last_liteserver_state_->get_unix_time()) > std::min(time_per_block * 8, 180.0)) {
last_liteserver_state_ = last_masterchain_state_;
}
return last_liteserver_state_;
@ -1562,7 +1589,7 @@ void ValidatorManagerImpl::send_get_out_msg_queue_proof_request(
}
void ValidatorManagerImpl::start_up() {
db_ = create_db_actor(actor_id(this), db_root_);
db_ = create_db_actor(actor_id(this), db_root_, opts_);
lite_server_cache_ = create_liteserver_cache_actor(actor_id(this), db_root_);
token_manager_ = td::actor::create_actor<TokenManager>("tokenmanager");
td::mkdir(db_root_ + "/tmp/").ensure();
@ -2448,7 +2475,15 @@ void ValidatorManagerImpl::allow_block_info_gc(BlockIdExt block_id, td::Promise<
void ValidatorManagerImpl::got_next_gc_masterchain_handle(BlockHandle handle) {
CHECK(gc_advancing_);
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), handle](td::Result<td::Ref<ShardState>> R) {
R.ensure();
if (R.is_error()) {
if (R.error().code() == ErrorCode::timeout) {
LOG(ERROR) << "Failed to get gc masterchain state, retrying: " << R.move_as_error();
td::actor::send_closure(SelfId, &ValidatorManagerImpl::got_next_gc_masterchain_handle, std::move(handle));
} else {
LOG(FATAL) << "Failed to get gc masterchain state: " << R.move_as_error();
}
return;
}
td::actor::send_closure(SelfId, &ValidatorManagerImpl::got_next_gc_masterchain_state, std::move(handle),
td::Ref<MasterchainState>{R.move_as_ok()});
});
@ -2479,8 +2514,11 @@ void ValidatorManagerImpl::update_shard_client_block_handle(BlockHandle handle,
td::Promise<td::Unit> promise) {
shard_client_handle_ = std::move(handle);
auto seqno = shard_client_handle_->id().seqno();
if (last_liteserver_state_.is_null() || last_liteserver_state_->get_block_id().seqno() < seqno) {
last_liteserver_state_ = std::move(state);
if (state.not_null()) {
shard_client_shards_ = state->get_shards();
if (last_liteserver_state_.is_null() || last_liteserver_state_->get_block_id().seqno() < seqno) {
last_liteserver_state_ = std::move(state);
}
}
shard_client_update(seqno);
promise.set_value(td::Unit());
@ -2519,15 +2557,15 @@ void ValidatorManagerImpl::alarm() {
}
if (log_status_at_.is_in_past()) {
if (last_masterchain_block_handle_) {
LOG(INFO) << "STATUS: last_masterchain_block_ago="
<< td::format::as_time(td::Clocks::system() - last_masterchain_block_handle_->unix_time())
<< " last_known_key_block_ago="
<< td::format::as_time(td::Clocks::system() - (last_known_key_block_handle_->inited_unix_time()
? last_known_key_block_handle_->unix_time()
: 0))
<< " shard_client_ago="
<< td::format::as_time(td::Clocks::system() -
(shard_client_handle_ ? shard_client_handle_->unix_time() : 0));
LOG(ERROR) << "STATUS: last_masterchain_block_ago="
<< td::format::as_time(td::Clocks::system() - last_masterchain_block_handle_->unix_time())
<< " last_known_key_block_ago="
<< td::format::as_time(td::Clocks::system() - (last_known_key_block_handle_->inited_unix_time()
? last_known_key_block_handle_->unix_time()
: 0))
<< " shard_client_ago="
<< td::format::as_time(td::Clocks::system() -
(shard_client_handle_ ? shard_client_handle_->unix_time() : 0));
}
log_status_at_ = td::Timestamp::in(60.0);
}
@ -2553,6 +2591,31 @@ void ValidatorManagerImpl::alarm() {
for (auto &w : shard_client_waiters_) {
w.second.check_timers();
}
for (auto it = block_state_cache_.begin(); it != block_state_cache_.end();) {
bool del = it->second.ttl_.is_in_past();
if (del) {
auto block_id = it->first;
if (block_id.is_masterchain()) {
if (block_id.seqno() == last_masterchain_seqno_) {
it->second.ttl_ = td::Timestamp::in(30.0);
del = false;
}
} else if (last_masterchain_state_.not_null()) {
auto shard = last_masterchain_state_->get_shard_from_config(block_id.shard_full());
if (shard.not_null()) {
if (block_id.seqno() == shard->top_block_id().seqno()) {
it->second.ttl_ = td::Timestamp::in(30.0);
del = false;
}
}
}
}
if (del) {
it = block_state_cache_.erase(it);
} else {
++it;
}
}
}
alarm_timestamp().relax(check_waiters_at_);
if (check_shard_clients_.is_in_past()) {
@ -2577,8 +2640,8 @@ void ValidatorManagerImpl::update_shard_client_state(BlockIdExt masterchain_bloc
}
void ValidatorManagerImpl::get_shard_client_state(bool from_db, td::Promise<BlockIdExt> promise) {
if (!shard_client_.empty() && !from_db) {
td::actor::send_closure(shard_client_, &ShardClient::get_processed_masterchain_block_id, std::move(promise));
if (shard_client_handle_ && !from_db) {
promise.set_result(shard_client_handle_->id());
} else {
td::actor::send_closure(db_, &Db::get_shard_client_state, std::move(promise));
}
@ -2776,18 +2839,19 @@ void ValidatorManagerImpl::log_validator_session_stats(BlockIdExt block_id,
}
std::vector<tl_object_ptr<ton_api::validatorSession_statsRound>> rounds;
for (const auto& round : stats.rounds) {
for (const auto &round : stats.rounds) {
std::vector<tl_object_ptr<ton_api::validatorSession_statsProducer>> producers;
for (const auto& producer : round.producers) {
for (const auto &producer : round.producers) {
producers.push_back(create_tl_object<ton_api::validatorSession_statsProducer>(
producer.id.bits256_value(), producer.block_status, producer.block_timestamp));
producer.id.bits256_value(), producer.candidate_id, producer.block_status, producer.block_timestamp,
producer.comment));
}
rounds.push_back(create_tl_object<ton_api::validatorSession_statsRound>(round.timestamp, std::move(producers)));
}
auto obj = create_tl_object<ton_api::validatorSession_stats>(
create_tl_block_id_simple(block_id.id), stats.timestamp, stats.self.bits256_value(),
stats.creator.bits256_value(), stats.total_validators, stats.total_weight, stats.signatures,
stats.success, create_tl_block_id(block_id), stats.timestamp, stats.self.bits256_value(), stats.session_id,
stats.cc_seqno, stats.creator.bits256_value(), stats.total_validators, stats.total_weight, stats.signatures,
stats.signatures_weight, stats.approve_signatures, stats.approve_signatures_weight, stats.first_round,
std::move(rounds));
std::string s = td::json_encode<std::string>(td::ToJson(*obj), false);
@ -2801,6 +2865,143 @@ void ValidatorManagerImpl::log_validator_session_stats(BlockIdExt block_id,
LOG(INFO) << "Writing validator session stats for " << block_id.id;
}
void ValidatorManagerImpl::get_block_handle_for_litequery(BlockIdExt block_id, td::Promise<ConstBlockHandle> promise) {
get_block_handle(
block_id, false,
[SelfId = actor_id(this), block_id, promise = std::move(promise)](td::Result<BlockHandle> R) mutable {
if (R.is_ok() && R.ok()->is_applied()) {
promise.set_value(R.move_as_ok());
} else {
td::actor::send_closure(SelfId, &ValidatorManagerImpl::process_block_handle_for_litequery_error, block_id,
std::move(R), std::move(promise));
}
});
}
void ValidatorManagerImpl::get_block_by_lt_from_db_for_litequery(AccountIdPrefixFull account, LogicalTime lt,
td::Promise<ConstBlockHandle> promise) {
get_block_by_lt_from_db(
account, lt, [=, SelfId = actor_id(this), promise = std::move(promise)](td::Result<ConstBlockHandle> R) mutable {
if (R.is_ok() && R.ok()->is_applied()) {
promise.set_value(R.move_as_ok());
} else {
td::actor::send_closure(SelfId, &ValidatorManagerImpl::process_lookup_block_for_litequery_error, account, 0,
lt, std::move(R), std::move(promise));
}
});
}
void ValidatorManagerImpl::get_block_by_unix_time_from_db_for_litequery(AccountIdPrefixFull account, UnixTime ts,
td::Promise<ConstBlockHandle> promise) {
get_block_by_unix_time_from_db(
account, ts, [=, SelfId = actor_id(this), promise = std::move(promise)](td::Result<ConstBlockHandle> R) mutable {
if (R.is_ok() && R.ok()->is_applied()) {
promise.set_value(R.move_as_ok());
} else {
td::actor::send_closure(SelfId, &ValidatorManagerImpl::process_lookup_block_for_litequery_error, account, 1,
ts, std::move(R), std::move(promise));
}
});
}
void ValidatorManagerImpl::get_block_by_seqno_from_db_for_litequery(AccountIdPrefixFull account, BlockSeqno seqno,
td::Promise<ConstBlockHandle> promise) {
get_block_by_seqno_from_db(
account, seqno,
[=, SelfId = actor_id(this), promise = std::move(promise)](td::Result<ConstBlockHandle> R) mutable {
if (R.is_ok() && R.ok()->is_applied()) {
promise.set_value(R.move_as_ok());
} else {
td::actor::send_closure(SelfId, &ValidatorManagerImpl::process_lookup_block_for_litequery_error, account, 2,
seqno, std::move(R), std::move(promise));
}
});
}
void ValidatorManagerImpl::process_block_handle_for_litequery_error(BlockIdExt block_id,
td::Result<BlockHandle> r_handle,
td::Promise<ConstBlockHandle> promise) {
td::Status err;
if (r_handle.is_error()) {
err = r_handle.move_as_error();
} else {
auto handle = r_handle.move_as_ok();
if (handle->is_applied()) {
promise.set_value(std::move(handle));
return;
}
if (!handle->received() || !handle->received_state()) {
err = td::Status::Error(ErrorCode::notready, PSTRING() << "block " << block_id.id.to_str() << " is not in db");
} else {
err = td::Status::Error(ErrorCode::notready, PSTRING() << "block " << block_id.id.to_str() << " is not applied");
}
}
if (block_id.is_masterchain()) {
if (block_id.seqno() > last_masterchain_seqno_) {
err = err.move_as_error_suffix(PSTRING() << " (last known masterchain block: " << last_masterchain_seqno_ << ")");
}
} else {
for (auto &shard : shard_client_shards_) {
if (shard_intersects(shard->shard(), block_id.shard_full())) {
if (block_id.seqno() > shard->top_block_id().seqno()) {
err = err.move_as_error_suffix(
PSTRING() << " (possibly out of sync: shard_client_seqno="
<< (shard_client_handle_ ? shard_client_handle_->id().seqno() : 0) << " ls_seqno="
<< (last_liteserver_state_.not_null() ? last_liteserver_state_->get_seqno() : 0) << ")");
}
break;
}
}
}
promise.set_error(std::move(err));
}
void ValidatorManagerImpl::process_lookup_block_for_litequery_error(AccountIdPrefixFull account, int type,
td::uint64 value,
td::Result<ConstBlockHandle> r_handle,
td::Promise<ConstBlockHandle> promise) {
td::Status err;
if (r_handle.is_error()) {
err = r_handle.move_as_error();
} else {
auto handle = r_handle.move_as_ok();
if (handle->is_applied()) {
promise.set_value(std::move(handle));
return;
}
if (!handle->received() || !handle->received_state()) {
err = td::Status::Error(ErrorCode::notready, PSTRING() << "block " << handle->id().to_str() << " is not in db");
} else {
err = td::Status::Error(ErrorCode::notready, PSTRING() << "block " << handle->id().to_str() << " is not applied");
}
}
if (account.is_masterchain()) {
if (value > (type == 0
? last_masterchain_state_->get_logical_time()
: (type == 1 ? last_masterchain_state_->get_unix_time() : last_masterchain_state_->get_seqno()))) {
err = err.move_as_error_suffix(PSTRING() << " (last known masterchain block: " << last_masterchain_seqno_ << ")");
}
} else {
for (auto &shard : shard_client_shards_) {
if (shard_intersects(shard->shard(), account.as_leaf_shard())) {
if (value > (type == 0 ? shard->end_lt()
: (type == 1 ? (shard_client_handle_ ? shard_client_handle_->unix_time() : 0)
: shard->top_block_id().seqno()))) {
err = err.move_as_error_suffix(
PSTRING() << " (possibly out of sync: shard_client_seqno="
<< (shard_client_handle_ ? shard_client_handle_->id().seqno() : 0) << " ls_seqno="
<< (last_liteserver_state_.not_null() ? last_liteserver_state_->get_seqno() : 0) << ")");
}
break;
}
}
}
static std::string names[3] = {"lt", "utime", "seqno"};
err = err.move_as_error_prefix(PSTRING() << "cannot find block " << account.to_str() << " " << names[type] << "="
<< value << ": ");
promise.set_error(std::move(err));
}
void ValidatorManagerImpl::get_validator_sessions_info(
td::Promise<tl_object_ptr<ton_api::engine_validator_validatorSessionsInfo>> promise) {
std::vector<td::actor::ActorId<ValidatorGroup>> groups;