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:
commit
f4fd3ff3be
246 changed files with 7895 additions and 5430 deletions
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue