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

updated tonlib, fixed bugs

updated tonlib
fixed bugs in func
validator: partial support for hardforks
liteserver: support for waitMasterchainBlock prefix
transactions: support for gas flat rate
This commit is contained in:
ton 2019-10-03 17:04:52 +04:00
parent 841d5ebac2
commit 7ea00ebfcf
89 changed files with 1922 additions and 608 deletions

View file

@ -52,29 +52,52 @@ void ValidatorManagerImpl::validate_block_is_next_proof(BlockIdExt prev_block_id
td::Status::Error(ErrorCode::protoviolation, "validate_block_is_next_proof() can only work for masterchain"));
return;
}
if (prev_block_id.seqno() + 1 != next_block_id.seqno()) {
VLOG(VALIDATOR_NOTICE) << "prev=" << prev_block_id << " next=" << next_block_id;
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "validate_block_is_next_proof(): bad seqno"));
return;
}
CHECK(last_masterchain_state_.not_null());
auto pp = create_proof(next_block_id, std::move(proof));
if (pp.is_error()) {
promise.set_error(pp.move_as_error_prefix("failed to create proof: "));
return;
}
auto P =
td::PromiseCreator::lambda([promise = std::move(promise), id = prev_block_id](td::Result<BlockHandle> R) mutable {
if (R.is_error()) {
promise.set_error(R.move_as_error());
return;
}
auto handle = R.move_as_ok();
CHECK(!handle->merge_before());
if (handle->one_prev(true) != id) {
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "prev block mismatch"));
return;
}
promise.set_value(td::Unit());
});
if (last_masterchain_seqno_ == prev_block_id.seqno()) {
CHECK(last_masterchain_block_id_ == prev_block_id);
run_check_proof_query(next_block_id, pp.move_as_ok(), actor_id(this), td::Timestamp::in(2.0), std::move(P),
opts_->is_hardfork(next_block_id));
auto P = td::PromiseCreator::lambda(
[promise = std::move(promise), id = prev_block_id](td::Result<BlockHandle> R) mutable {
if (R.is_error()) {
promise.set_error(R.move_as_error());
return;
}
auto handle = R.move_as_ok();
CHECK(!handle->merge_before());
if (handle->one_prev(true) != id) {
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "prev block mismatch"));
return;
}
promise.set_value(td::Unit());
});
run_check_proof_query(next_block_id, pp.move_as_ok(), actor_id(this), td::Timestamp::in(2.0), std::move(P),
last_masterchain_state_, opts_->is_hardfork(next_block_id));
} else {
auto P =
td::PromiseCreator::lambda([promise = std::move(promise), next_block_id](td::Result<BlockHandle> R) mutable {
R.ensure();
auto handle = R.move_as_ok();
CHECK(handle->inited_next_left());
if (handle->one_next(true) == next_block_id) {
promise.set_value(td::Unit());
} else {
promise.set_error(td::Status::Error("next block id mismatch"));
}
});
get_block_handle(prev_block_id, false, std::move(P));
}
}
void ValidatorManagerImpl::validate_block_proof(BlockIdExt block_id, td::BufferSlice proof,
@ -468,7 +491,27 @@ void ValidatorManagerImpl::run_ext_query(td::BufferSlice data, td::Promise<td::B
promise.set_value(std::move(data));
});
run_liteserver_query(std::move(data), actor_id(this), lite_server_cache_.get(), std::move(P));
auto E = fetch_tl_prefix<lite_api::liteServer_waitMasterchainSeqno>(data, true);
if (E.is_error()) {
run_liteserver_query(std::move(data), actor_id(this), lite_server_cache_.get(), std::move(P));
} else {
auto e = E.move_as_ok();
if (static_cast<BlockSeqno>(e->seqno_) <= min_confirmed_masterchain_seqno_) {
run_liteserver_query(std::move(data), actor_id(this), lite_server_cache_.get(), std::move(P));
} else {
auto t = e->timeout_ms_ < 10000 ? e->timeout_ms_ * 0.001 : 10.0;
auto Q =
td::PromiseCreator::lambda([data = std::move(data), SelfId = actor_id(this), cache = lite_server_cache_.get(),
promise = std::move(P)](td::Result<td::Unit> R) mutable {
if (R.is_error()) {
promise.set_error(R.move_as_error());
return;
}
run_liteserver_query(std::move(data), SelfId, cache, std::move(promise));
});
wait_shard_client_state(e->seqno_, td::Timestamp::in(t), std::move(Q));
}
}
}
void ValidatorManagerImpl::wait_block_state(BlockHandle handle, td::uint32 priority, td::Timestamp timeout,
@ -1387,7 +1430,8 @@ void ValidatorManagerImpl::new_masterchain_block() {
}
void ValidatorManagerImpl::update_shards() {
if (last_masterchain_state_->rotated_all_shards() || last_masterchain_seqno_ == 0) {
if ((last_masterchain_state_->rotated_all_shards() || last_masterchain_seqno_ == 0) &&
opts_->get_last_fork_masterchain_seqno() <= last_masterchain_seqno_) {
allow_validate_ = true;
}
auto exp_vec = last_masterchain_state_->get_shards();
@ -1468,7 +1512,7 @@ void ValidatorManagerImpl::update_shards() {
auto val_set = last_masterchain_state_->get_validator_set(shard);
auto x = val_set->export_vector();
auto validator_id = get_validator(val_set);
auto validator_id = get_validator(shard, val_set);
if (!validator_id.is_zero()) {
auto val_group_id = get_validator_set_id(shard, val_set, opts_hash);
@ -1499,7 +1543,7 @@ void ValidatorManagerImpl::update_shards() {
for (auto &shard : future_shards) {
auto val_set = last_masterchain_state_->get_next_validator_set(shard);
auto validator_id = get_validator(val_set);
auto validator_id = get_validator(shard, val_set);
if (!validator_id.is_zero()) {
auto val_group_id = get_validator_set_id(shard, val_set, opts_hash);
auto it = next_validator_groups_.find(val_group_id);
@ -1548,7 +1592,7 @@ void ValidatorManagerImpl::update_shards() {
});
td::actor::send_closure(db_, &Db::update_destroyed_validator_sessions, gc_list_, std::move(P));
}
}
} // namespace validator
void ValidatorManagerImpl::written_destroyed_validator_sessions(std::vector<td::actor::ActorId<ValidatorGroup>> list) {
for (auto &v : list) {
@ -1609,7 +1653,7 @@ td::actor::ActorOwn<ValidatorGroup> ValidatorManagerImpl::create_validator_group
if (check_gc_list_.count(session_id) == 1) {
return td::actor::ActorOwn<ValidatorGroup>{};
} else {
auto validator_id = get_validator(validator_set);
auto validator_id = get_validator(shard, validator_set);
CHECK(!validator_id.is_zero());
auto G = td::actor::create_actor<ValidatorGroup>("validatorgroup", shard, validator_id, session_id, validator_set,
opts, keyring_, adnl_, rldp_, overlays_, db_root_, actor_id(this),
@ -1827,10 +1871,26 @@ void ValidatorManagerImpl::advance_gc(BlockHandle handle, td::Ref<MasterchainSta
try_advance_gc_masterchain_block();
}
void ValidatorManagerImpl::update_shard_client_block_handle(BlockHandle handle, td::Promise<td::Unit> promise) {
auto seqno = handle->id().seqno();
shard_client_update(seqno);
promise.set_value(td::Unit());
}
void ValidatorManagerImpl::shard_client_update(BlockSeqno seqno) {
if (min_confirmed_masterchain_seqno_ < seqno) {
min_confirmed_masterchain_seqno_ = seqno;
}
while (shard_client_waiters_.size() > 0) {
auto it = shard_client_waiters_.begin();
if (it->first > seqno) {
break;
}
for (auto &y : it->second.waiting_) {
y.promise.set_value(td::Unit());
}
shard_client_waiters_.erase(it);
}
}
void ValidatorManagerImpl::state_serializer_update(BlockSeqno seqno) {
@ -1870,6 +1930,9 @@ void ValidatorManagerImpl::alarm() {
for (auto &w : wait_state_) {
w.second.check_timers();
}
for (auto &w : shard_client_waiters_) {
w.second.check_timers();
}
}
alarm_timestamp().relax(check_waiters_at_);
if (check_shard_clients_.is_in_past()) {
@ -1904,8 +1967,12 @@ void ValidatorManagerImpl::update_shard_client_state(BlockIdExt masterchain_bloc
td::actor::send_closure(db_, &Db::update_shard_client_state, masterchain_block_id, std::move(promise));
}
void ValidatorManagerImpl::get_shard_client_state(td::Promise<BlockIdExt> promise) {
td::actor::send_closure(db_, &Db::get_shard_client_state, std::move(promise));
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));
} else {
td::actor::send_closure(db_, &Db::get_shard_client_state, std::move(promise));
}
}
void ValidatorManagerImpl::subscribe_to_shard(ShardIdFull shard) {
@ -1928,7 +1995,10 @@ bool ValidatorManagerImpl::is_validator() {
return temp_keys_.size() > 0 || permanent_keys_.size() > 0;
}
PublicKeyHash ValidatorManagerImpl::get_validator(td::Ref<ValidatorSet> val_set) {
PublicKeyHash ValidatorManagerImpl::get_validator(ShardIdFull shard, td::Ref<ValidatorSet> val_set) {
if (!opts_->need_validate(shard)) {
return PublicKeyHash::zero();
}
for (auto &key : temp_keys_) {
if (val_set->is_validator(key.bits256_value())) {
return key;
@ -2017,6 +2087,28 @@ void ValidatorManagerImpl::prepare_stats(td::Promise<std::vector<std::pair<std::
td::actor::send_closure(db_, &Db::prepare_stats, merger.make_promise("db."));
}
void ValidatorManagerImpl::truncate(td::Ref<MasterchainState> state, td::Promise<td::Unit> promise) {
td::actor::send_closure(db_, &Db::truncate, std::move(state), std::move(promise));
}
void ValidatorManagerImpl::wait_shard_client_state(BlockSeqno seqno, td::Timestamp timeout,
td::Promise<td::Unit> promise) {
if (seqno <= min_confirmed_masterchain_seqno_) {
promise.set_value(td::Unit());
return;
}
if (timeout.is_in_past()) {
promise.set_error(td::Status::Error(ErrorCode::timeout, "timeout"));
return;
}
if (seqno > min_confirmed_masterchain_seqno_ + 100) {
promise.set_error(td::Status::Error(ErrorCode::notready, "too big masterchain block seqno"));
return;
}
shard_client_waiters_[seqno].waiting_.emplace_back(timeout, 0, std::move(promise));
}
td::actor::ActorOwn<ValidatorManagerInterface> ValidatorManagerFactory::create(
td::Ref<ValidatorManagerOptions> opts, std::string db_root, td::actor::ActorId<keyring::Keyring> keyring,
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<rldp::Rldp> rldp,