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

fullnode: support for TCP master/slave replication

This commit is contained in:
ton 2019-09-19 23:15:32 +04:00
parent bfa166d66c
commit f40822b58a
50 changed files with 1109 additions and 244 deletions

View file

@ -111,6 +111,9 @@ set(FULL_NODE_SOURCE
full-node-shard.h
full-node-shard.hpp
full-node-shard.cpp
full-node-master.h
full-node-master.hpp
full-node-master.cpp
net/download-block.hpp
net/download-block.cpp

View file

@ -0,0 +1,357 @@
/*
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/>.
Copyright 2017-2019 Telegram Systems LLP
*/
#include "td/utils/SharedSlice.h"
#include "full-node-master.hpp"
#include "ton/ton-shard.h"
#include "ton/ton-tl.hpp"
#include "adnl/utils.hpp"
#include "common/delay.h"
namespace ton {
namespace validator {
namespace fullnode {
void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_getNextBlockDescription &query,
td::Promise<td::BufferSlice> promise) {
auto P = td::PromiseCreator::lambda([promise = std::move(promise)](td::Result<BlockHandle> R) mutable {
if (R.is_error()) {
auto x = create_serialize_tl_object<ton_api::tonNode_blockDescriptionEmpty>();
promise.set_value(std::move(x));
} else {
auto B = R.move_as_ok();
if (!B->received() || !B->inited_proof()) {
auto x = create_serialize_tl_object<ton_api::tonNode_blockDescriptionEmpty>();
promise.set_value(std::move(x));
} else {
auto x = create_serialize_tl_object<ton_api::tonNode_blockDescription>(create_tl_block_id(B->id()));
promise.set_value(std::move(x));
}
}
});
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_next_block,
create_block_id(query.prev_block_), std::move(P));
}
void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_prepareBlock &query,
td::Promise<td::BufferSlice> promise) {
auto P = td::PromiseCreator::lambda([promise = std::move(promise)](td::Result<BlockHandle> R) mutable {
if (R.is_error()) {
auto x = create_serialize_tl_object<ton_api::tonNode_notFound>();
promise.set_value(std::move(x));
} else {
auto B = R.move_as_ok();
if (!B->received()) {
auto x = create_serialize_tl_object<ton_api::tonNode_notFound>();
promise.set_value(std::move(x));
} else {
auto x = create_serialize_tl_object<ton_api::tonNode_prepared>();
promise.set_value(std::move(x));
}
}
});
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_block_handle,
create_block_id(query.block_), false, std::move(P));
}
void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadBlock &query,
td::Promise<td::BufferSlice> promise) {
auto P = td::PromiseCreator::lambda([validator_manager = validator_manager_,
promise = std::move(promise)](td::Result<BlockHandle> R) mutable {
if (R.is_error()) {
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "unknown block"));
} else {
auto B = R.move_as_ok();
if (!B->received()) {
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "unknown block"));
} else {
td::actor::send_closure(validator_manager, &ValidatorManagerInterface::get_block_data, B, std::move(promise));
}
}
});
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_block_handle,
create_block_id(query.block_), false, std::move(P));
}
void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_prepareBlockProof &query,
td::Promise<td::BufferSlice> promise) {
if (query.block_->seqno_ == 0) {
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "cannot download proof for zero state"));
return;
}
auto P = td::PromiseCreator::lambda([allow_partial = query.allow_partial_, promise = std::move(promise),
validator_manager = validator_manager_](td::Result<BlockHandle> R) mutable {
if (R.is_error()) {
auto x = create_serialize_tl_object<ton_api::tonNode_preparedProofEmpty>();
promise.set_value(std::move(x));
return;
} else {
auto handle = R.move_as_ok();
if (!handle || (!handle->inited_proof() && (!allow_partial || !handle->inited_proof_link()))) {
auto x = create_serialize_tl_object<ton_api::tonNode_preparedProofEmpty>();
promise.set_value(std::move(x));
return;
}
if (handle->inited_proof() && handle->id().is_masterchain()) {
auto x = create_serialize_tl_object<ton_api::tonNode_preparedProof>();
promise.set_value(std::move(x));
} else {
auto x = create_serialize_tl_object<ton_api::tonNode_preparedProofLink>();
promise.set_value(std::move(x));
}
}
});
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_block_handle,
create_block_id(query.block_), false, std::move(P));
}
void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadBlockProof &query,
td::Promise<td::BufferSlice> promise) {
auto P = td::PromiseCreator::lambda(
[promise = std::move(promise), validator_manager = validator_manager_](td::Result<BlockHandle> R) mutable {
if (R.is_error()) {
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "unknown block proof"));
return;
} else {
auto handle = R.move_as_ok();
if (!handle || !handle->inited_proof()) {
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "unknown block proof"));
return;
}
td::actor::send_closure(validator_manager, &ValidatorManagerInterface::get_block_proof, handle,
std::move(promise));
}
});
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_block_handle,
create_block_id(query.block_), false, std::move(P));
}
void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadBlockProofLink &query,
td::Promise<td::BufferSlice> promise) {
auto P = td::PromiseCreator::lambda(
[promise = std::move(promise), validator_manager = validator_manager_](td::Result<BlockHandle> R) mutable {
if (R.is_error()) {
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "unknown block proof"));
return;
} else {
auto handle = R.move_as_ok();
if (!handle || !handle->inited_proof_link()) {
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "unknown block proof"));
return;
}
td::actor::send_closure(validator_manager, &ValidatorManagerInterface::get_block_proof_link, handle,
std::move(promise));
}
});
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_block_handle,
create_block_id(query.block_), false, std::move(P));
}
void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_prepareZeroState &query,
td::Promise<td::BufferSlice> promise) {
auto P =
td::PromiseCreator::lambda([SelfId = actor_id(this), promise = std::move(promise)](td::Result<bool> R) mutable {
if (R.is_error() || !R.move_as_ok()) {
auto x = create_serialize_tl_object<ton_api::tonNode_notFoundState>();
promise.set_value(std::move(x));
return;
}
auto x = create_serialize_tl_object<ton_api::tonNode_preparedState>();
promise.set_value(std::move(x));
});
auto block_id = create_block_id(query.block_);
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::check_zero_state_exists, block_id,
std::move(P));
}
void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_preparePersistentState &query,
td::Promise<td::BufferSlice> promise) {
auto P =
td::PromiseCreator::lambda([SelfId = actor_id(this), promise = std::move(promise)](td::Result<bool> R) mutable {
if (R.is_error() || !R.move_as_ok()) {
auto x = create_serialize_tl_object<ton_api::tonNode_notFoundState>();
promise.set_value(std::move(x));
return;
}
auto x = create_serialize_tl_object<ton_api::tonNode_preparedState>();
promise.set_value(std::move(x));
});
auto block_id = create_block_id(query.block_);
auto masterchain_block_id = create_block_id(query.masterchain_block_);
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::check_persistent_state_exists, block_id,
masterchain_block_id, std::move(P));
}
void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_getNextKeyBlockIds &query,
td::Promise<td::BufferSlice> promise) {
auto cnt = static_cast<td::uint32>(query.max_size_);
if (cnt > 8) {
cnt = 8;
}
auto P =
td::PromiseCreator::lambda([promise = std::move(promise), cnt](td::Result<std::vector<BlockIdExt>> R) mutable {
if (R.is_error()) {
LOG(WARNING) << "getnextkey: " << R.move_as_error();
auto x = create_serialize_tl_object<ton_api::tonNode_keyBlocks>(
std::vector<tl_object_ptr<ton_api::tonNode_blockIdExt>>{}, false, true);
promise.set_value(std::move(x));
return;
}
auto res = R.move_as_ok();
std::vector<tl_object_ptr<ton_api::tonNode_blockIdExt>> v;
for (auto &b : res) {
v.emplace_back(create_tl_block_id(b));
}
auto x = create_serialize_tl_object<ton_api::tonNode_keyBlocks>(std::move(v), res.size() < cnt, false);
promise.set_value(std::move(x));
});
auto block_id = create_block_id(query.block_);
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_next_key_blocks, block_id, cnt,
std::move(P));
}
void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadZeroState &query,
td::Promise<td::BufferSlice> promise) {
auto P = td::PromiseCreator::lambda(
[SelfId = actor_id(this), promise = std::move(promise)](td::Result<td::BufferSlice> R) mutable {
if (R.is_error()) {
promise.set_error(R.move_as_error_prefix("failed to get state from db: "));
return;
}
promise.set_value(R.move_as_ok());
});
auto block_id = create_block_id(query.block_);
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_zero_state, block_id, std::move(P));
}
void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadPersistentState &query,
td::Promise<td::BufferSlice> promise) {
auto P = td::PromiseCreator::lambda(
[SelfId = actor_id(this), promise = std::move(promise)](td::Result<td::BufferSlice> R) mutable {
if (R.is_error()) {
promise.set_error(R.move_as_error_prefix("failed to get state from db: "));
return;
}
promise.set_value(R.move_as_ok());
});
auto block_id = create_block_id(query.block_);
auto masterchain_block_id = create_block_id(query.masterchain_block_);
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_persistent_state, block_id,
masterchain_block_id, std::move(P));
}
void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadPersistentStateSlice &query,
td::Promise<td::BufferSlice> promise) {
auto P = td::PromiseCreator::lambda(
[SelfId = actor_id(this), promise = std::move(promise)](td::Result<td::BufferSlice> R) mutable {
if (R.is_error()) {
promise.set_error(R.move_as_error_prefix("failed to get state from db: "));
return;
}
promise.set_value(R.move_as_ok());
});
auto block_id = create_block_id(query.block_);
auto masterchain_block_id = create_block_id(query.masterchain_block_);
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_persistent_state_slice, block_id,
masterchain_block_id, query.offset_, query.max_size_, std::move(P));
}
void FullNodeMasterImpl::receive_query(adnl::AdnlNodeIdShort src, td::BufferSlice query,
td::Promise<td::BufferSlice> promise) {
auto BX = fetch_tl_prefix<ton_api::tonNode_query>(query, true);
if (BX.is_error()) {
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "cannot parse tonnode query"));
return;
}
auto B = fetch_tl_object<ton_api::Function>(std::move(query), true);
if (B.is_error()) {
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "cannot parse tonnode query"));
return;
}
ton_api::downcast_call(*B.move_as_ok().get(), [&](auto &obj) { this->process_query(src, obj, std::move(promise)); });
}
void FullNodeMasterImpl::start_up() {
class Cb : public adnl::Adnl::Callback {
public:
Cb(td::actor::ActorId<FullNodeMasterImpl> id) : id_(std::move(id)) {
}
void receive_message(adnl::AdnlNodeIdShort src, adnl::AdnlNodeIdShort dst, td::BufferSlice data) override {
}
void receive_query(adnl::AdnlNodeIdShort src, adnl::AdnlNodeIdShort dst, td::BufferSlice data,
td::Promise<td::BufferSlice> promise) override {
td::actor::send_closure(id_, &FullNodeMasterImpl::receive_query, src, std::move(data), std::move(promise));
}
private:
td::actor::ActorId<FullNodeMasterImpl> id_;
};
td::actor::send_closure(adnl_, &adnl::Adnl::subscribe, adnl_id_,
adnl::Adnl::int_to_bytestring(ton_api::tonNode_query::ID),
std::make_unique<Cb>(actor_id(this)));
auto P =
td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::actor::ActorOwn<adnl::AdnlExtServer>> R) {
R.ensure();
R.move_as_ok().release();
});
td::actor::send_closure(adnl_, &adnl::Adnl::create_ext_server, std::vector<adnl::AdnlNodeIdShort>{adnl_id_},
std::vector<td::uint16>{port_}, std::move(P));
}
FullNodeMasterImpl::FullNodeMasterImpl(adnl::AdnlNodeIdShort adnl_id, td::uint16 port, FileHash zero_state_file_hash,
td::actor::ActorId<keyring::Keyring> keyring,
td::actor::ActorId<adnl::Adnl> adnl,
td::actor::ActorId<ValidatorManagerInterface> validator_manager)
: adnl_id_(adnl_id)
, port_(port)
, zero_state_file_hash_(zero_state_file_hash)
, keyring_(keyring)
, adnl_(adnl)
, validator_manager_(validator_manager) {
}
td::actor::ActorOwn<FullNodeMaster> FullNodeMaster::create(
adnl::AdnlNodeIdShort adnl_id, td::uint16 port, FileHash zero_state_file_hash,
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
td::actor::ActorId<ValidatorManagerInterface> validator_manager) {
return td::actor::create_actor<FullNodeMasterImpl>("tonnode", adnl_id, port, zero_state_file_hash, keyring, adnl,
validator_manager);
}
} // namespace fullnode
} // namespace validator
} // namespace ton

View file

@ -0,0 +1,45 @@
/*
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/>.
Copyright 2017-2019 Telegram Systems LLP
*/
#pragma once
#include "full-node.h"
#include "validator/interfaces/block-handle.h"
namespace ton {
namespace validator {
namespace fullnode {
class FullNodeMaster : public td::actor::Actor {
public:
virtual ~FullNodeMaster() = default;
static td::actor::ActorOwn<FullNodeMaster> create(adnl::AdnlNodeIdShort adnl_id, td::uint16 port,
FileHash zero_state_file_hash,
td::actor::ActorId<keyring::Keyring> keyring,
td::actor::ActorId<adnl::Adnl> adnl,
td::actor::ActorId<ValidatorManagerInterface> validator_manager);
};
} // namespace fullnode
} // namespace validator
} // namespace ton

View file

@ -0,0 +1,83 @@
/*
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/>.
Copyright 2017-2019 Telegram Systems LLP
*/
#pragma once
#include "full-node-master.h"
namespace ton {
namespace validator {
namespace fullnode {
class FullNodeMasterImpl : public FullNodeMaster {
public:
void start_up() override;
template <class T>
void process_query(adnl::AdnlNodeIdShort src, T &query, td::Promise<td::BufferSlice> promise) {
promise.set_error(td::Status::Error(ErrorCode::error, "unknown query"));
}
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_getNextBlockDescription &query,
td::Promise<td::BufferSlice> promise);
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_prepareBlockProof &query,
td::Promise<td::BufferSlice> promise);
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadBlockProof &query,
td::Promise<td::BufferSlice> promise);
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadBlockProofLink &query,
td::Promise<td::BufferSlice> promise);
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_prepareBlock &query,
td::Promise<td::BufferSlice> promise);
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadBlock &query,
td::Promise<td::BufferSlice> promise);
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_prepareZeroState &query,
td::Promise<td::BufferSlice> promise);
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_preparePersistentState &query,
td::Promise<td::BufferSlice> promise);
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_getNextKeyBlockIds &query,
td::Promise<td::BufferSlice> promise);
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadZeroState &query,
td::Promise<td::BufferSlice> promise);
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadPersistentState &query,
td::Promise<td::BufferSlice> promise);
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadPersistentStateSlice &query,
td::Promise<td::BufferSlice> promise);
// void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_prepareNextKeyBlockProof &query,
// td::Promise<td::BufferSlice> promise);
void receive_query(adnl::AdnlNodeIdShort src, td::BufferSlice query, td::Promise<td::BufferSlice> promise);
FullNodeMasterImpl(adnl::AdnlNodeIdShort adnl_id, td::uint16 port, FileHash zero_state_file_hash,
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
td::actor::ActorId<ValidatorManagerInterface> validator_manager);
private:
adnl::AdnlNodeIdShort adnl_id_;
td::uint16 port_;
FileHash zero_state_file_hash_;
td::actor::ActorId<keyring::Keyring> keyring_;
td::actor::ActorId<adnl::Adnl> adnl_;
td::actor::ActorId<ValidatorManagerInterface> validator_manager_;
};
} // namespace fullnode
} // namespace validator
} // namespace ton

View file

@ -78,7 +78,8 @@ void FullNodeShardImpl::try_get_next_block(td::Timestamp timeout, td::Promise<Re
return;
}
td::actor::create_actor<DownloadNextBlock>("downloadnext", adnl_id_, overlay_id_, handle_, download_next_priority(),
timeout, validator_manager_, rldp_, overlays_, adnl_, std::move(promise))
timeout, validator_manager_, rldp_, overlays_, adnl_, client_,
std::move(promise))
.release();
}
@ -446,6 +447,10 @@ void FullNodeShardImpl::receive_broadcast(PublicKeyHash src, td::BufferSlice bro
}
void FullNodeShardImpl::send_ihr_message(td::BufferSlice data) {
if (!client_.empty()) {
UNREACHABLE();
return;
}
auto B = create_serialize_tl_object<ton_api::tonNode_ihrMessageBroadcast>(
create_tl_object<ton_api::tonNode_ihrMessage>(std::move(data)));
if (B.size() <= overlay::Overlays::max_simple_broadcast_size()) {
@ -458,6 +463,18 @@ void FullNodeShardImpl::send_ihr_message(td::BufferSlice data) {
}
void FullNodeShardImpl::send_external_message(td::BufferSlice data) {
if (!client_.empty()) {
td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "send_ext_query",
create_serialize_tl_object_suffix<ton_api::tonNode_query>(
create_serialize_tl_object<ton_api::tonNode_slave_sendExtMessage>(
create_tl_object<ton_api::tonNode_externalMessage>(std::move(data)))),
td::Timestamp::in(1.0), [](td::Result<td::BufferSlice> R) {
if (R.is_error()) {
VLOG(FULL_NODE_WARNING) << "failed to send ext message: " << R.move_as_error();
}
});
return;
}
auto B = create_serialize_tl_object<ton_api::tonNode_externalMessageBroadcast>(
create_tl_object<ton_api::tonNode_externalMessage>(std::move(data)));
if (B.size() <= overlay::Overlays::max_simple_broadcast_size()) {
@ -470,6 +487,10 @@ void FullNodeShardImpl::send_external_message(td::BufferSlice data) {
}
void FullNodeShardImpl::send_shard_block_info(BlockIdExt block_id, CatchainSeqno cc_seqno, td::BufferSlice data) {
if (!client_.empty()) {
UNREACHABLE();
return;
}
auto B = create_serialize_tl_object<ton_api::tonNode_newShardBlockBroadcast>(
create_tl_object<ton_api::tonNode_newShardBlock>(create_tl_block_id(block_id), cc_seqno, std::move(data)));
if (B.size() <= overlay::Overlays::max_simple_broadcast_size()) {
@ -482,6 +503,10 @@ void FullNodeShardImpl::send_shard_block_info(BlockIdExt block_id, CatchainSeqno
}
void FullNodeShardImpl::send_broadcast(BlockBroadcast broadcast) {
if (!client_.empty()) {
UNREACHABLE();
return;
}
std::vector<tl_object_ptr<ton_api::tonNode_blockSignature>> sigs;
for (auto &sig : broadcast.signatures) {
sigs.emplace_back(create_tl_object<ton_api::tonNode_blockSignature>(sig.node, sig.signature.clone()));
@ -496,7 +521,7 @@ void FullNodeShardImpl::send_broadcast(BlockBroadcast broadcast) {
void FullNodeShardImpl::download_block(BlockIdExt id, td::uint32 priority, td::Timestamp timeout,
td::Promise<ReceivedBlock> promise) {
td::actor::create_actor<DownloadBlock>("downloadreq", id, adnl_id_, overlay_id_, adnl::AdnlNodeIdShort::zero(),
priority, timeout, validator_manager_, rldp_, overlays_, adnl_,
priority, timeout, validator_manager_, rldp_, overlays_, adnl_, client_,
std::move(promise))
.release();
}
@ -505,7 +530,7 @@ void FullNodeShardImpl::download_zero_state(BlockIdExt id, td::uint32 priority,
td::Promise<td::BufferSlice> promise) {
td::actor::create_actor<DownloadState>("downloadstatereq", id, BlockIdExt{}, adnl_id_, overlay_id_,
adnl::AdnlNodeIdShort::zero(), priority, timeout, validator_manager_, rldp_,
overlays_, adnl_, std::move(promise))
overlays_, adnl_, client_, std::move(promise))
.release();
}
@ -513,7 +538,7 @@ void FullNodeShardImpl::download_persistent_state(BlockIdExt id, BlockIdExt mast
td::Timestamp timeout, td::Promise<td::BufferSlice> promise) {
td::actor::create_actor<DownloadState>("downloadstatereq", id, masterchain_block_id, adnl_id_, overlay_id_,
adnl::AdnlNodeIdShort::zero(), priority, timeout, validator_manager_, rldp_,
overlays_, adnl_, std::move(promise))
overlays_, adnl_, client_, std::move(promise))
.release();
}
@ -521,7 +546,7 @@ void FullNodeShardImpl::download_block_proof(BlockIdExt block_id, td::uint32 pri
td::Promise<td::BufferSlice> promise) {
td::actor::create_actor<DownloadProof>("downloadproofreq", block_id, false, adnl_id_, overlay_id_,
adnl::AdnlNodeIdShort::zero(), priority, timeout, validator_manager_, rldp_,
overlays_, adnl_, std::move(promise))
overlays_, adnl_, client_, std::move(promise))
.release();
}
@ -529,14 +554,15 @@ void FullNodeShardImpl::download_block_proof_link(BlockIdExt block_id, td::uint3
td::Promise<td::BufferSlice> promise) {
td::actor::create_actor<DownloadProof>("downloadproofreq", block_id, true, adnl_id_, overlay_id_,
adnl::AdnlNodeIdShort::zero(), priority, timeout, validator_manager_, rldp_,
overlays_, adnl_, std::move(promise))
overlays_, adnl_, client_, std::move(promise))
.release();
}
void FullNodeShardImpl::get_next_key_blocks(BlockIdExt block_id, td::Timestamp timeout,
td::Promise<std::vector<BlockIdExt>> promise) {
td::actor::create_actor<GetNextKeyBlocks>("next", block_id, 16, adnl_id_, overlay_id_, adnl::AdnlNodeIdShort::zero(),
1, timeout, validator_manager_, rldp_, overlays_, adnl_, std::move(promise))
1, timeout, validator_manager_, rldp_, overlays_, adnl_, client_,
std::move(promise))
.release();
}
@ -570,15 +596,17 @@ void FullNodeShardImpl::alarm() {
}
void FullNodeShardImpl::start_up() {
auto X =
create_hash_tl_object<ton_api::tonNode_shardPublicOverlayId>(get_workchain(), get_shard(), zero_state_file_hash_);
td::BufferSlice b{32};
b.as_slice().copy_from(as_slice(X));
overlay_id_full_ = overlay::OverlayIdFull{std::move(b)};
overlay_id_ = overlay_id_full_.compute_short_id();
rules_ = overlay::OverlayPrivacyRules{overlay::Overlays::max_fec_broadcast_size()};
if (client_.empty()) {
auto X = create_hash_tl_object<ton_api::tonNode_shardPublicOverlayId>(get_workchain(), get_shard(),
zero_state_file_hash_);
td::BufferSlice b{32};
b.as_slice().copy_from(as_slice(X));
overlay_id_full_ = overlay::OverlayIdFull{std::move(b)};
overlay_id_ = overlay_id_full_.compute_short_id();
rules_ = overlay::OverlayPrivacyRules{overlay::Overlays::max_fec_broadcast_size()};
create_overlay();
create_overlay();
}
}
void FullNodeShardImpl::sign_new_certificate(PublicKeyHash sign_by) {
@ -613,6 +641,9 @@ void FullNodeShardImpl::signed_new_certificate(ton::overlay::Certificate cert) {
}
void FullNodeShardImpl::update_validators(std::vector<PublicKeyHash> public_key_hashes, PublicKeyHash local_hash) {
if (!client_.empty()) {
return;
}
bool update_cert = false;
if (!local_hash.is_zero() && local_hash != sign_cert_by_) {
update_cert = true;
@ -638,7 +669,8 @@ FullNodeShardImpl::FullNodeShardImpl(ShardIdFull shard, PublicKeyHash local_id,
FileHash zero_state_file_hash, td::actor::ActorId<keyring::Keyring> keyring,
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<rldp::Rldp> rldp,
td::actor::ActorId<overlay::Overlays> overlays,
td::actor::ActorId<ValidatorManagerInterface> validator_manager)
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
td::actor::ActorId<adnl::AdnlExtClient> client)
: shard_(shard)
, local_id_(local_id)
, adnl_id_(adnl_id)
@ -647,16 +679,17 @@ FullNodeShardImpl::FullNodeShardImpl(ShardIdFull shard, PublicKeyHash local_id,
, adnl_(adnl)
, rldp_(rldp)
, overlays_(overlays)
, validator_manager_(validator_manager) {
, validator_manager_(validator_manager)
, client_(client) {
}
td::actor::ActorOwn<FullNodeShard> FullNodeShard::create(
ShardIdFull shard, PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id, FileHash zero_state_file_hash,
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
td::actor::ActorId<ValidatorManagerInterface> validator_manager) {
td::actor::ActorId<ValidatorManagerInterface> validator_manager, td::actor::ActorId<adnl::AdnlExtClient> client) {
return td::actor::create_actor<FullNodeShardImpl>("tonnode", shard, local_id, adnl_id, zero_state_file_hash, keyring,
adnl, rldp, overlays, validator_manager);
adnl, rldp, overlays, validator_manager, client);
}
} // namespace fullnode

View file

@ -20,6 +20,7 @@
#include "full-node.h"
#include "validator/interfaces/block-handle.h"
#include "adnl/adnl-ext-client.h"
namespace ton {
@ -59,13 +60,11 @@ class FullNodeShard : public td::actor::Actor {
virtual void update_validators(std::vector<PublicKeyHash> public_key_hashes, PublicKeyHash local_hash) = 0;
static td::actor::ActorOwn<FullNodeShard> create(ShardIdFull shard, PublicKeyHash local_id,
adnl::AdnlNodeIdShort adnl_id, FileHash zero_state_file_hash,
td::actor::ActorId<keyring::Keyring> keyring,
td::actor::ActorId<adnl::Adnl> adnl,
td::actor::ActorId<rldp::Rldp> rldp,
td::actor::ActorId<overlay::Overlays> overlays,
td::actor::ActorId<ValidatorManagerInterface> validator_manager);
static td::actor::ActorOwn<FullNodeShard> create(
ShardIdFull shard, PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id, FileHash zero_state_file_hash,
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
td::actor::ActorId<ValidatorManagerInterface> validator_manager, td::actor::ActorId<adnl::AdnlExtClient> client);
};
} // namespace fullnode

View file

@ -54,7 +54,7 @@ class FullNodeShardImpl : public FullNodeShard {
template <class T>
void process_query(adnl::AdnlNodeIdShort src, T &query, td::Promise<td::BufferSlice> promise) {
UNREACHABLE();
promise.set_error(td::Status::Error(ErrorCode::error, "unknown query"));
}
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_getNextBlockDescription &query,
td::Promise<td::BufferSlice> promise);
@ -122,7 +122,8 @@ class FullNodeShardImpl : public FullNodeShard {
FileHash zero_state_file_hash, td::actor::ActorId<keyring::Keyring> keyring,
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<rldp::Rldp> rldp,
td::actor::ActorId<overlay::Overlays> overlays,
td::actor::ActorId<ValidatorManagerInterface> validator_manager);
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
td::actor::ActorId<adnl::AdnlExtClient> client);
private:
ShardIdFull shard_;
@ -138,6 +139,7 @@ class FullNodeShardImpl : public FullNodeShard {
td::actor::ActorId<rldp::Rldp> rldp_;
td::actor::ActorId<overlay::Overlays> overlays_;
td::actor::ActorId<ValidatorManagerInterface> validator_manager_;
td::actor::ActorId<adnl::AdnlExtClient> client_;
td::uint32 attempt_ = 0;

View file

@ -103,7 +103,7 @@ void FullNodeImpl::add_shard(ShardIdFull shard) {
while (true) {
if (shards_.count(shard) == 0) {
shards_.emplace(shard, FullNodeShard::create(shard, local_id_, adnl_id_, zero_state_file_hash_, keyring_, adnl_,
rldp_, overlays_, validator_manager_));
rldp_, overlays_, validator_manager_, client_));
if (all_validators_.size() > 0) {
td::actor::send_closure(shards_[shard], &FullNodeShard::update_validators, all_validators_, sign_cert_by_);
}
@ -413,7 +413,8 @@ FullNodeImpl::FullNodeImpl(PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<dht::Dht> dht,
td::actor::ActorId<overlay::Overlays> overlays,
td::actor::ActorId<ValidatorManagerInterface> validator_manager, std::string db_root)
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
td::actor::ActorId<adnl::AdnlExtClient> client, std::string db_root)
: local_id_(local_id)
, adnl_id_(adnl_id)
, zero_state_file_hash_(zero_state_file_hash)
@ -423,6 +424,7 @@ FullNodeImpl::FullNodeImpl(PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id
, dht_(dht)
, overlays_(overlays)
, validator_manager_(validator_manager)
, client_(client)
, db_root_(db_root) {
add_shard(ShardIdFull{masterchainId});
}
@ -434,9 +436,9 @@ td::actor::ActorOwn<FullNode> FullNode::create(ton::PublicKeyHash local_id, adnl
td::actor::ActorId<dht::Dht> dht,
td::actor::ActorId<overlay::Overlays> overlays,
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
std::string db_root) {
td::actor::ActorId<adnl::AdnlExtClient> client, std::string db_root) {
return td::actor::create_actor<FullNodeImpl>("fullnode", local_id, adnl_id, zero_state_file_hash, keyring, adnl, rldp,
dht, overlays, validator_manager, db_root);
dht, overlays, validator_manager, client, db_root);
}
} // namespace fullnode

View file

@ -30,6 +30,7 @@
#include "dht/dht.h"
#include "overlay/overlays.h"
#include "validator/validator.h"
#include "adnl/adnl-ext-client.h"
namespace ton {
@ -71,7 +72,7 @@ class FullNode : public td::actor::Actor {
td::actor::ActorId<dht::Dht> dht,
td::actor::ActorId<overlay::Overlays> overlays,
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
std::string db_root);
td::actor::ActorId<adnl::AdnlExtClient> client, std::string db_root);
};
} // namespace fullnode

View file

@ -75,7 +75,8 @@ class FullNodeImpl : public FullNode {
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<dht::Dht> dht,
td::actor::ActorId<overlay::Overlays> overlays,
td::actor::ActorId<ValidatorManagerInterface> validator_manager, std::string db_root);
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
td::actor::ActorId<adnl::AdnlExtClient> client, std::string db_root);
private:
PublicKeyHash local_id_;
@ -93,6 +94,7 @@ class FullNodeImpl : public FullNode {
td::actor::ActorId<dht::Dht> dht_;
td::actor::ActorId<overlay::Overlays> overlays_;
td::actor::ActorId<ValidatorManagerInterface> validator_manager_;
td::actor::ActorId<adnl::AdnlExtClient> client_;
std::string db_root_;

View file

@ -74,10 +74,6 @@ void Collator::start_up() {
if (prev_blocks.size() > 1) {
LOG(DEBUG) << "Previous block #2 is " << prev_blocks.at(1).to_str();
}
//if (created_by_.is_zero()) {
// !!FIXME!! remove this debug later
//td::as<td::uint32>(created_by_.data() + 32 - 4) = ((unsigned)std::time(nullptr) >> 8);
//}
// 1. check validity of parameters, especially prev_blocks, shard and min_mc_block_id
if (shard.workchain != ton::masterchainId && shard.workchain != ton::basechainId) {
fatal_error(-667, "can create block candidates only for masterchain (-1) and base workchain (0)");
@ -180,7 +176,7 @@ void Collator::start_up() {
LOG(DEBUG) << "sending wait_block_state() query #" << i << " for " << prev_blocks[i].to_str() << " to Manager";
++pending;
td::actor::send_closure_later(manager, &ValidatorManager::wait_block_state_short, prev_blocks[i], priority(),
timeout, [self = get_self(), i](td::Result<Ref<ShardState>> res) {
timeout, [ self = get_self(), i ](td::Result<Ref<ShardState>> res) {
LOG(DEBUG) << "got answer to wait_block_state query #" << i;
td::actor::send_closure_later(std::move(self), &Collator::after_get_shard_state, i,
std::move(res));
@ -191,7 +187,7 @@ void Collator::start_up() {
LOG(DEBUG) << "sending wait_block_data() query #" << i << " for " << prev_blocks[i].to_str() << " to Manager";
++pending;
td::actor::send_closure_later(manager, &ValidatorManager::wait_block_data_short, prev_blocks[i], priority(),
timeout, [self = get_self(), i](td::Result<Ref<BlockData>> res) {
timeout, [ self = get_self(), i ](td::Result<Ref<BlockData>> res) {
LOG(DEBUG) << "got answer to wait_block_data query #" << i;
td::actor::send_closure_later(std::move(self), &Collator::after_get_block_data, i,
std::move(res));
@ -201,8 +197,8 @@ void Collator::start_up() {
// 4. load external messages
LOG(DEBUG) << "sending get_external_messages() query to Manager";
++pending;
td::actor::send_closure_later(manager, &ValidatorManager::get_external_messages, shard,
[self = get_self()](td::Result<std::vector<Ref<ExtMessage>>> res) -> void {
td::actor::send_closure_later(manager, &ValidatorManager::get_external_messages,
shard, [self = get_self()](td::Result<std::vector<Ref<ExtMessage>>> res)->void {
LOG(DEBUG) << "got answer to get_external_messages() query";
td::actor::send_closure_later(std::move(self), &Collator::after_get_external_messages,
std::move(res));
@ -212,8 +208,8 @@ void Collator::start_up() {
LOG(DEBUG) << "sending get_shard_blocks() query to Manager";
++pending;
td::actor::send_closure_later(
manager, &ValidatorManager::get_shard_blocks, prev_blocks[0],
[self = get_self()](td::Result<std::vector<Ref<ShardTopBlockDescription>>> res) -> void {
manager, &ValidatorManager::get_shard_blocks,
prev_blocks[0], [self = get_self()](td::Result<std::vector<Ref<ShardTopBlockDescription>>> res)->void {
LOG(DEBUG) << "got answer to get_shard_blocks() query";
td::actor::send_closure_later(std::move(self), &Collator::after_get_shard_blocks, std::move(res));
});
@ -330,7 +326,7 @@ bool Collator::request_aux_mc_state(BlockSeqno seqno, Ref<MasterchainStateQ>& st
LOG(DEBUG) << "sending auxiliary wait_block_state() query for " << blkid.to_str() << " to Manager";
++pending;
td::actor::send_closure_later(manager, &ValidatorManager::wait_block_state_short, blkid, priority(), timeout,
[self = get_self(), blkid](td::Result<Ref<ShardState>> res) {
[ self = get_self(), blkid ](td::Result<Ref<ShardState>> res) {
LOG(DEBUG) << "got answer to wait_block_state query for " << blkid.to_str();
td::actor::send_closure_later(std::move(self), &Collator::after_get_aux_shard_state,
blkid, std::move(res));
@ -418,8 +414,8 @@ void Collator::after_get_mc_state(td::Result<std::pair<Ref<MasterchainState>, Bl
// NB. it is needed only for creating a correct ExtBlkRef reference to it, which requires start_lt and end_lt
LOG(DEBUG) << "sending wait_block_data() query #-1 for " << mc_block_id_.to_str() << " to Manager";
++pending;
td::actor::send_closure_later(manager, &ValidatorManager::wait_block_data_short, mc_block_id_, priority(), timeout,
[self = get_self()](td::Result<Ref<BlockData>> res) {
td::actor::send_closure_later(manager, &ValidatorManager::wait_block_data_short, mc_block_id_, priority(),
timeout, [self = get_self()](td::Result<Ref<BlockData>> res) {
LOG(DEBUG) << "got answer to wait_block_data query #-1";
td::actor::send_closure_later(std::move(self), &Collator::after_get_block_data, -1,
std::move(res));
@ -558,7 +554,7 @@ bool Collator::request_neighbor_msg_queues() {
LOG(DEBUG) << "neighbor #" << i << " : " << descr.blk_.to_str();
++pending;
send_closure_later(manager, &ValidatorManager::wait_block_message_queue_short, descr.blk_, priority(), timeout,
[self = get_self(), i](td::Result<Ref<MessageQueue>> res) {
[ self = get_self(), i ](td::Result<Ref<MessageQueue>> res) {
td::actor::send_closure(std::move(self), &Collator::got_neighbor_out_queue, i, std::move(res));
});
++i;
@ -2936,24 +2932,24 @@ bool Collator::update_shard_config(const block::WorkchainSet& wc_set, const bloc
WorkchainId wc_id{ton::workchainInvalid};
Ref<block::WorkchainInfo> wc_info;
ton::BlockSeqno& min_seqno = min_ref_mc_seqno_;
return shard_conf_->process_sibling_shard_hashes(
[&wc_set, &wc_id, &wc_info, &ccvc, &min_seqno, now = now_, update_cc](block::McShardHash& cur,
const block::McShardHash* sibling) {
if (!cur.is_valid()) {
return -2;
}
if (wc_id != cur.workchain()) {
wc_id = cur.workchain();
auto it = wc_set.find(wc_id);
if (it == wc_set.end()) {
wc_info.clear();
} else {
wc_info = it->second;
}
}
min_seqno = std::min(min_seqno, cur.min_ref_mc_seqno_);
return update_one_shard(cur, sibling, wc_info.get(), now, ccvc, update_cc);
});
return shard_conf_->process_sibling_shard_hashes([
&wc_set, &wc_id, &wc_info, &ccvc, &min_seqno, now = now_, update_cc
](block::McShardHash & cur, const block::McShardHash* sibling) {
if (!cur.is_valid()) {
return -2;
}
if (wc_id != cur.workchain()) {
wc_id = cur.workchain();
auto it = wc_set.find(wc_id);
if (it == wc_set.end()) {
wc_info.clear();
} else {
wc_info = it->second;
}
}
min_seqno = std::min(min_seqno, cur.min_ref_mc_seqno_);
return update_one_shard(cur, sibling, wc_info.get(), now, ccvc, update_cc);
});
}
bool Collator::create_mc_state_extra() {
@ -3198,10 +3194,10 @@ bool Collator::update_block_creator_stats() {
return fatal_error("cannot update CreatorStats for "s + p.first.to_hex());
}
}
if (/*!created_by_.is_zero() &&*/ !update_block_creator_count(created_by_.as_bits256().bits(), 0, 1)) {
if (!created_by_.is_zero() && !update_block_creator_count(created_by_.as_bits256().bits(), 0, 1)) {
return fatal_error("cannot update CreatorStats for "s + created_by_.as_bits256().to_hex());
}
if (!update_block_creator_count(td::Bits256::zero().bits(), block_create_total_, 1)) {
if (!update_block_creator_count(td::Bits256::zero().bits(), block_create_total_, !created_by_.is_zero())) {
return fatal_error("cannot update CreatorStats with zero index (representing the sum of other CreatorStats)");
}
int cnt = block_create_stats_->filter([this](vm::CellSlice& cs, td::ConstBitPtr key, int key_len) {
@ -3766,7 +3762,7 @@ bool Collator::create_block_candidate() {
// 4. save block candidate
LOG(INFO) << "saving new BlockCandidate";
td::actor::send_closure_later(manager, &ValidatorManager::set_block_candidate, block_candidate->id,
block_candidate->clone(), [self = get_self()](td::Result<td::Unit> saved) -> void {
block_candidate->clone(), [self = get_self()](td::Result<td::Unit> saved)->void {
LOG(DEBUG) << "got answer to set_block_candidate";
td::actor::send_closure_later(std::move(self), &Collator::return_block_candidate,
std::move(saved));

View file

@ -151,12 +151,7 @@ void ValidateQuery::start_up() {
LOG(INFO) << "validate query for " << block_candidate.id.to_str() << " started";
alarm_timestamp() = timeout;
rand_seed_.set_zero();
created_by_ = block_candidate.pubkey;
if (created_by_.is_zero()) {
// !!FIXME!! remove this debug later
td::as<td::uint32>(created_by_.data() + 32 - 4) = ((unsigned)std::time(nullptr) >> 8);
}
CHECK(id_ == block_candidate.id);
if (ShardIdFull(id_) != shard_) {
@ -5179,7 +5174,7 @@ bool ValidateQuery::check_one_block_creator_update(td::ConstBitPtr key, Ref<vm::
unsigned mc_incr = (created_by_ == key);
unsigned shard_incr = 0;
if (key.is_zero(256)) {
mc_incr = 1;
mc_incr = !created_by_.is_zero();
shard_incr = block_create_total_;
} else {
auto it = block_create_count_.find(td::Bits256{key});

View file

@ -96,7 +96,7 @@ void ValidatorManagerMasterchainReiniter::downloaded_proof_link(td::BufferSlice
LOG(WARNING) << "downloaded proof link failed: " << R.move_as_error();
td::actor::send_closure(SelfId, &ValidatorManagerMasterchainReiniter::download_proof_link);
} else {
td::actor::send_closure(SelfId, &ValidatorManagerMasterchainReiniter::try_download_key_blocks);
td::actor::send_closure(SelfId, &ValidatorManagerMasterchainReiniter::try_download_key_blocks, false);
}
});
@ -104,10 +104,10 @@ void ValidatorManagerMasterchainReiniter::downloaded_proof_link(td::BufferSlice
}
void ValidatorManagerMasterchainReiniter::downloaded_zero_state() {
try_download_key_blocks();
try_download_key_blocks(false);
}
void ValidatorManagerMasterchainReiniter::try_download_key_blocks() {
void ValidatorManagerMasterchainReiniter::try_download_key_blocks(bool try_start) {
if (!download_new_key_blocks_until_) {
if (opts_->allow_blockchain_init()) {
download_new_key_blocks_until_ = td::Timestamp::in(60.0);
@ -115,15 +115,18 @@ void ValidatorManagerMasterchainReiniter::try_download_key_blocks() {
download_new_key_blocks_until_ = td::Timestamp::in(600.0);
}
}
if (key_blocks_.size() > 0) {
if (key_blocks_.size() > 0 && try_start) {
auto h = *key_blocks_.rbegin();
CHECK(h->inited_unix_time());
if (h->unix_time() + opts_->sync_blocks_before() > td::Clocks::system()) {
choose_masterchain_state();
return;
}
if ((opts_->allow_blockchain_init() || h->unix_time() + 2 * 86400 > td::Clocks::system()) &&
download_new_key_blocks_until_.is_in_past()) {
if (h->unix_time() + 2 * opts_->key_block_utime_step() > td::Clocks::system()) {
choose_masterchain_state();
return;
}
if (opts_->allow_blockchain_init() && download_new_key_blocks_until_.is_in_past()) {
choose_masterchain_state();
return;
}
@ -146,7 +149,7 @@ void ValidatorManagerMasterchainReiniter::got_next_key_blocks(std::vector<BlockI
if (!vec.size()) {
delay_action(
[SelfId = actor_id(this)]() {
td::actor::send_closure(SelfId, &ValidatorManagerMasterchainReiniter::try_download_key_blocks);
td::actor::send_closure(SelfId, &ValidatorManagerMasterchainReiniter::try_download_key_blocks, true);
},
td::Timestamp::in(1.0));
return;
@ -181,7 +184,7 @@ void ValidatorManagerMasterchainReiniter::got_key_block_handle(td::uint32 idx, B
key_blocks_[idx] = std::move(handle);
CHECK(pending_ > 0);
if (!--pending_) {
try_download_key_blocks();
try_download_key_blocks(false);
}
}

View file

@ -45,7 +45,7 @@ class ValidatorManagerMasterchainReiniter : public td::actor::Actor {
void downloaded_proof_link(td::BufferSlice data);
void downloaded_zero_state();
void try_download_key_blocks();
void try_download_key_blocks(bool try_start);
void got_next_key_blocks(std::vector<BlockIdExt> vec);
void got_key_block_handle(td::uint32 idx, BlockHandle handle);

View file

@ -34,7 +34,8 @@ DownloadBlock::DownloadBlock(BlockIdExt block_id, adnl::AdnlNodeIdShort local_id
adnl::AdnlNodeIdShort download_from, td::uint32 priority, td::Timestamp timeout,
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
td::actor::ActorId<adnl::Adnl> adnl, td::Promise<ReceivedBlock> promise)
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<adnl::AdnlExtClient> client,
td::Promise<ReceivedBlock> promise)
: block_id_(block_id)
, local_id_(local_id)
, overlay_id_(overlay_id)
@ -45,6 +46,7 @@ DownloadBlock::DownloadBlock(BlockIdExt block_id, adnl::AdnlNodeIdShort local_id
, rldp_(rldp)
, overlays_(overlays)
, adnl_(adnl)
, client_(client)
, promise_(std::move(promise))
, block_{block_id, td::BufferSlice()}
, allow_partial_proof_{!block_id_.is_masterchain()} {
@ -54,7 +56,8 @@ DownloadBlock::DownloadBlock(BlockIdExt block_id, adnl::AdnlNodeIdShort local_id
BlockHandle prev, adnl::AdnlNodeIdShort download_from, td::uint32 priority,
td::Timestamp timeout, td::actor::ActorId<ValidatorManagerInterface> validator_manager,
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
td::actor::ActorId<adnl::Adnl> adnl, td::Promise<ReceivedBlock> promise)
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<adnl::AdnlExtClient> client,
td::Promise<ReceivedBlock> promise)
: block_id_(block_id)
, local_id_(local_id)
, overlay_id_(overlay_id)
@ -66,6 +69,7 @@ DownloadBlock::DownloadBlock(BlockIdExt block_id, adnl::AdnlNodeIdShort local_id
, rldp_(rldp)
, overlays_(overlays)
, adnl_(adnl)
, client_(client)
, promise_(std::move(promise))
, block_{block_id, td::BufferSlice()} {
}
@ -139,7 +143,7 @@ void DownloadBlock::got_block_handle(BlockHandle handle) {
void DownloadBlock::got_download_token(std::unique_ptr<DownloadToken> token) {
token_ = std::move(token);
if (download_from_.is_zero() && !short_) {
if (download_from_.is_zero() && !short_ && client_.empty()) {
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<std::vector<adnl::AdnlNodeIdShort>> R) {
if (R.is_error()) {
td::actor::send_closure(SelfId, &DownloadBlock::abort_query, R.move_as_error());
@ -179,10 +183,16 @@ void DownloadBlock::got_node_to_download(adnl::AdnlNodeIdShort node) {
}
});
td::actor::send_closure(overlays_, &overlay::Overlays::send_query, download_from_, local_id_, overlay_id_,
"get_prepare", std::move(P), td::Timestamp::in(1.0),
create_serialize_tl_object<ton_api::tonNode_prepareBlockProof>(create_tl_block_id(block_id_),
allow_partial_proof_));
auto q = create_serialize_tl_object<ton_api::tonNode_prepareBlockProof>(create_tl_block_id(block_id_),
allow_partial_proof_);
if (client_.empty()) {
td::actor::send_closure(overlays_, &overlay::Overlays::send_query, download_from_, local_id_, overlay_id_,
"get_prepare", std::move(P), td::Timestamp::in(1.0), std::move(q));
} else {
td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "get_prepare",
create_serialize_tl_object_suffix<ton_api::tonNode_query>(std::move(q)),
td::Timestamp::in(1.0), std::move(P));
}
}
void DownloadBlock::got_block_proof_description(td::BufferSlice proof_description) {
@ -207,11 +217,16 @@ void DownloadBlock::got_block_proof_description(td::BufferSlice proof_descriptio
}
});
td::actor::send_closure(
overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_, overlay_id_,
"download block proof", std::move(P), td::Timestamp::in(3.0),
create_serialize_tl_object<ton_api::tonNode_downloadBlockProof>(create_tl_block_id(block_id_)),
FullNode::max_proof_size(), rldp_);
auto q = create_serialize_tl_object<ton_api::tonNode_downloadBlockProof>(create_tl_block_id(block_id_));
if (client_.empty()) {
td::actor::send_closure(overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_,
overlay_id_, "get_proof", std::move(P), td::Timestamp::in(3.0), std::move(q),
FullNode::max_proof_size(), rldp_);
} else {
td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "get_proof",
create_serialize_tl_object_suffix<ton_api::tonNode_query>(std::move(q)),
td::Timestamp::in(3.0), std::move(P));
}
},
[&](ton_api::tonNode_preparedProofLink &obj) {
if (!allow_partial_proof_) {
@ -226,11 +241,16 @@ void DownloadBlock::got_block_proof_description(td::BufferSlice proof_descriptio
}
});
td::actor::send_closure(
overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_, overlay_id_,
"download block proof link", std::move(P), td::Timestamp::in(3.0),
create_serialize_tl_object<ton_api::tonNode_downloadBlockProofLink>(create_tl_block_id(block_id_)),
FullNode::max_proof_size(), rldp_);
auto q = create_serialize_tl_object<ton_api::tonNode_downloadBlockProofLink>(create_tl_block_id(block_id_));
if (client_.empty()) {
td::actor::send_closure(overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_,
overlay_id_, "get_proof_link", std::move(P), td::Timestamp::in(3.0), std::move(q),
FullNode::max_proof_size(), rldp_);
} else {
td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "get_proof_link",
create_serialize_tl_object_suffix<ton_api::tonNode_query>(std::move(q)),
td::Timestamp::in(3.0), std::move(P));
}
},
[&](ton_api::tonNode_preparedProofEmpty &obj) {
abort_query(td::Status::Error(ErrorCode::notready, "proof not found"));
@ -317,9 +337,15 @@ void DownloadBlock::got_block_handle_2(BlockHandle handle) {
}
});
td::actor::send_closure(overlays_, &overlay::Overlays::send_query, download_from_, local_id_, overlay_id_,
"get_prepare", std::move(P), td::Timestamp::in(1.0),
create_serialize_tl_object<ton_api::tonNode_prepareBlock>(create_tl_block_id(block_id_)));
auto q = create_serialize_tl_object<ton_api::tonNode_prepareBlock>(create_tl_block_id(block_id_));
if (client_.empty()) {
td::actor::send_closure(overlays_, &overlay::Overlays::send_query, download_from_, local_id_, overlay_id_,
"get_prepare_block", std::move(P), td::Timestamp::in(1.0), std::move(q));
} else {
td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "get_prepare_block",
create_serialize_tl_object_suffix<ton_api::tonNode_query>(std::move(q)),
td::Timestamp::in(1.0), std::move(P));
}
}
}
@ -333,25 +359,31 @@ void DownloadBlock::got_block_data_description(td::BufferSlice data_description)
auto f = F.move_as_ok();
ton_api::downcast_call(
*f.get(), td::overloaded(
[&, self = this](ton_api::tonNode_prepared &val) {
auto P = td::PromiseCreator::lambda([SelfId = actor_id(self)](td::Result<td::BufferSlice> R) {
if (R.is_error()) {
td::actor::send_closure(SelfId, &DownloadBlock::abort_query, R.move_as_error());
} else {
td::actor::send_closure(SelfId, &DownloadBlock::got_block_data, R.move_as_ok());
}
});
*f.get(),
td::overloaded(
[&, self = this](ton_api::tonNode_prepared &val) {
auto P = td::PromiseCreator::lambda([SelfId = actor_id(self)](td::Result<td::BufferSlice> R) {
if (R.is_error()) {
td::actor::send_closure(SelfId, &DownloadBlock::abort_query, R.move_as_error());
} else {
td::actor::send_closure(SelfId, &DownloadBlock::got_block_data, R.move_as_ok());
}
});
td::actor::send_closure(
overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_, overlay_id_,
"download block", std::move(P), td::Timestamp::in(3.0),
create_serialize_tl_object<ton_api::tonNode_downloadBlock>(create_tl_block_id(block_id_)),
FullNode::max_block_size(), rldp_);
},
[&](ton_api::tonNode_notFound &val) {
abort_query(td::Status::Error(ErrorCode::notready, "dst node does not have block"));
}));
auto q = create_serialize_tl_object<ton_api::tonNode_downloadBlock>(create_tl_block_id(block_id_));
if (client_.empty()) {
td::actor::send_closure(overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_,
overlay_id_, "get_block", std::move(P), td::Timestamp::in(3.0), std::move(q),
FullNode::max_block_size(), rldp_);
} else {
td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "get_block",
create_serialize_tl_object_suffix<ton_api::tonNode_query>(std::move(q)),
td::Timestamp::in(3.0), std::move(P));
}
},
[&](ton_api::tonNode_notFound &val) {
abort_query(td::Status::Error(ErrorCode::notready, "dst node does not have block"));
}));
}
void DownloadBlock::got_block_data(td::BufferSlice data) {

View file

@ -22,6 +22,7 @@
#include "ton/ton-types.h"
#include "validator/validator.h"
#include "rldp/rldp.h"
#include "adnl/adnl-ext-client.h"
namespace ton {
@ -35,12 +36,12 @@ class DownloadBlock : public td::actor::Actor {
adnl::AdnlNodeIdShort download_from, td::uint32 priority, td::Timestamp timeout,
td::actor::ActorId<ValidatorManagerInterface> validator_manager, td::actor::ActorId<rldp::Rldp> rldp,
td::actor::ActorId<overlay::Overlays> overlays, td::actor::ActorId<adnl::Adnl> adnl,
td::Promise<ReceivedBlock> promise);
td::actor::ActorId<adnl::AdnlExtClient> client, td::Promise<ReceivedBlock> promise);
DownloadBlock(BlockIdExt block_id, adnl::AdnlNodeIdShort local_id, overlay::OverlayIdShort overlay_id,
BlockHandle prev, adnl::AdnlNodeIdShort download_from, td::uint32 priority, td::Timestamp timeout,
td::actor::ActorId<ValidatorManagerInterface> validator_manager, td::actor::ActorId<rldp::Rldp> rldp,
td::actor::ActorId<overlay::Overlays> overlays, td::actor::ActorId<adnl::Adnl> adnl,
td::Promise<ReceivedBlock> promise);
td::actor::ActorId<adnl::AdnlExtClient> client, td::Promise<ReceivedBlock> promise);
void abort_query(td::Status reason);
void alarm() override;
@ -75,6 +76,7 @@ class DownloadBlock : public td::actor::Actor {
td::actor::ActorId<rldp::Rldp> rldp_;
td::actor::ActorId<overlay::Overlays> overlays_;
td::actor::ActorId<adnl::Adnl> adnl_;
td::actor::ActorId<adnl::AdnlExtClient> client_;
td::Promise<ReceivedBlock> promise_;
BlockHandle handle_;

View file

@ -33,7 +33,8 @@ DownloadNextBlock::DownloadNextBlock(adnl::AdnlNodeIdShort local_id, overlay::Ov
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
td::actor::ActorId<rldp::Rldp> rldp,
td::actor::ActorId<overlay::Overlays> overlays,
td::actor::ActorId<adnl::Adnl> adnl, td::Promise<ReceivedBlock> promise)
td::actor::ActorId<adnl::Adnl> adnl,
td::actor::ActorId<adnl::AdnlExtClient> client, td::Promise<ReceivedBlock> promise)
: local_id_(local_id)
, overlay_id_(overlay_id)
, prev_(prev)
@ -43,6 +44,7 @@ DownloadNextBlock::DownloadNextBlock(adnl::AdnlNodeIdShort local_id, overlay::Ov
, rldp_(rldp)
, overlays_(overlays)
, adnl_(adnl)
, client_(client)
, promise_(std::move(promise)) {
}
@ -76,6 +78,10 @@ void DownloadNextBlock::start_up() {
false, std::move(P));
return;
}
if (!client_.empty()) {
got_node(node_);
return;
}
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<std::vector<adnl::AdnlNodeIdShort>> R) {
if (R.is_error()) {
@ -107,8 +113,14 @@ void DownloadNextBlock::got_node(adnl::AdnlNodeIdShort id) {
});
auto query = create_serialize_tl_object<ton_api::tonNode_getNextBlockDescription>(create_tl_block_id(prev_->id()));
td::actor::send_closure(overlays_, &overlay::Overlays::send_query, id, local_id_, overlay_id_, "get_prepare",
std::move(P), td::Timestamp::in(1.0), std::move(query));
if (client_.empty()) {
td::actor::send_closure(overlays_, &overlay::Overlays::send_query, id, local_id_, overlay_id_, "get_prepare",
std::move(P), td::Timestamp::in(1.0), std::move(query));
} else {
td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "get_prepare",
create_serialize_tl_object_suffix<ton_api::tonNode_query>(std::move(query)),
td::Timestamp::in(1.0), std::move(P));
}
}
void DownloadNextBlock::got_next_node(td::BufferSlice data) {
@ -138,7 +150,7 @@ void DownloadNextBlock::got_next_node_handle(BlockHandle handle) {
void DownloadNextBlock::finish_query() {
if (promise_) {
td::actor::create_actor<DownloadBlock>("downloadnext", next_block_id_, local_id_, overlay_id_, prev_, node_,
priority_, timeout_, validator_manager_, rldp_, overlays_, adnl_,
priority_, timeout_, validator_manager_, rldp_, overlays_, adnl_, client_,
std::move(promise_))
.release();
}

View file

@ -23,6 +23,7 @@
#include "validator/validator.h"
#include "rldp/rldp.h"
#include "ton/ton-io.hpp"
#include "adnl/adnl-ext-client.h"
namespace ton {
@ -36,7 +37,8 @@ class DownloadNextBlock : public td::actor::Actor {
td::uint32 priority, td::Timestamp timeout,
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
td::actor::ActorId<adnl::Adnl> adnl, td::Promise<ReceivedBlock> promise);
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<adnl::AdnlExtClient> client,
td::Promise<ReceivedBlock> promise);
void abort_query(td::Status reason);
void finish_query();
@ -62,6 +64,7 @@ class DownloadNextBlock : public td::actor::Actor {
td::actor::ActorId<rldp::Rldp> rldp_;
td::actor::ActorId<overlay::Overlays> overlays_;
td::actor::ActorId<adnl::Adnl> adnl_;
td::actor::ActorId<adnl::AdnlExtClient> client_;
td::Promise<ReceivedBlock> promise_;
adnl::AdnlNodeIdShort node_ = adnl::AdnlNodeIdShort::zero();

View file

@ -35,7 +35,8 @@ DownloadProof::DownloadProof(BlockIdExt block_id, bool allow_partial_proof, adnl
td::uint32 priority, td::Timestamp timeout,
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
td::actor::ActorId<adnl::Adnl> adnl, td::Promise<td::BufferSlice> promise)
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<adnl::AdnlExtClient> client,
td::Promise<td::BufferSlice> promise)
: block_id_(block_id)
, allow_partial_proof_(allow_partial_proof)
, local_id_(local_id)
@ -47,6 +48,7 @@ DownloadProof::DownloadProof(BlockIdExt block_id, bool allow_partial_proof, adnl
, rldp_(rldp)
, overlays_(overlays)
, adnl_(adnl)
, client_(client)
, promise_(std::move(promise)) {
}
@ -92,7 +94,7 @@ void DownloadProof::start_up() {
void DownloadProof::got_download_token(std::unique_ptr<DownloadToken> token) {
token_ = std::move(token);
if (download_from_.is_zero()) {
if (download_from_.is_zero() && client_.empty()) {
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<std::vector<adnl::AdnlNodeIdShort>> R) {
if (R.is_error()) {
td::actor::send_closure(SelfId, &DownloadProof::abort_query, R.move_as_error());
@ -126,10 +128,17 @@ void DownloadProof::got_node_to_download(adnl::AdnlNodeIdShort node) {
}
});
td::actor::send_closure(overlays_, &overlay::Overlays::send_query, download_from_, local_id_, overlay_id_,
"get_prepare", std::move(P), td::Timestamp::in(1.0),
create_serialize_tl_object<ton_api::tonNode_prepareBlockProof>(create_tl_block_id(block_id_),
allow_partial_proof_));
auto query = create_serialize_tl_object<ton_api::tonNode_prepareBlockProof>(create_tl_block_id(block_id_),
allow_partial_proof_);
if (client_.empty()) {
td::actor::send_closure(overlays_, &overlay::Overlays::send_query, download_from_, local_id_, overlay_id_,
"get_prepare", std::move(P), td::Timestamp::in(1.0), std::move(query));
} else {
td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "get_prepare",
create_serialize_tl_object_suffix<ton_api::tonNode_query>(std::move(query)),
td::Timestamp::in(1.0), std::move(P));
}
}
void DownloadProof::got_block_proof_description(td::BufferSlice proof_description) {
@ -154,11 +163,16 @@ void DownloadProof::got_block_proof_description(td::BufferSlice proof_descriptio
}
});
td::actor::send_closure(
overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_, overlay_id_,
"download block proof", std::move(P), td::Timestamp::in(3.0),
create_serialize_tl_object<ton_api::tonNode_downloadBlockProof>(create_tl_block_id(block_id_)),
FullNode::max_proof_size(), rldp_);
auto query = create_serialize_tl_object<ton_api::tonNode_downloadBlockProof>(create_tl_block_id(block_id_));
if (client_.empty()) {
td::actor::send_closure(overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_,
overlay_id_, "download block proof", std::move(P), td::Timestamp::in(3.0),
std::move(query), FullNode::max_proof_size(), rldp_);
} else {
td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "get_prepare",
create_serialize_tl_object_suffix<ton_api::tonNode_query>(std::move(query)),
td::Timestamp::in(3.0), std::move(P));
}
},
[&](ton_api::tonNode_preparedProofLink &obj) {
if (!allow_partial_proof_) {
@ -173,11 +187,17 @@ void DownloadProof::got_block_proof_description(td::BufferSlice proof_descriptio
}
});
td::actor::send_closure(
overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_, overlay_id_,
"download block proof link", std::move(P), td::Timestamp::in(3.0),
create_serialize_tl_object<ton_api::tonNode_downloadBlockProofLink>(create_tl_block_id(block_id_)),
FullNode::max_proof_size(), rldp_);
auto query =
create_serialize_tl_object<ton_api::tonNode_downloadBlockProofLink>(create_tl_block_id(block_id_));
if (client_.empty()) {
td::actor::send_closure(overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_,
overlay_id_, "download block proof link", std::move(P), td::Timestamp::in(3.0),
std::move(query), FullNode::max_proof_size(), rldp_);
} else {
td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "download block proof link",
create_serialize_tl_object_suffix<ton_api::tonNode_query>(std::move(query)),
td::Timestamp::in(3.0), std::move(P));
}
},
[&](ton_api::tonNode_preparedProofEmpty &obj) {
abort_query(td::Status::Error(ErrorCode::notready, "proof not found"));

View file

@ -22,6 +22,7 @@
#include "ton/ton-types.h"
#include "validator/validator.h"
#include "rldp/rldp.h"
#include "adnl/adnl-ext-client.h"
namespace ton {
@ -35,7 +36,8 @@ class DownloadProof : public td::actor::Actor {
overlay::OverlayIdShort overlay_id, adnl::AdnlNodeIdShort download_from, td::uint32 priority,
td::Timestamp timeout, td::actor::ActorId<ValidatorManagerInterface> validator_manager,
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
td::actor::ActorId<adnl::Adnl> adnl, td::Promise<td::BufferSlice> promise);
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<adnl::AdnlExtClient> client,
td::Promise<td::BufferSlice> promise);
void abort_query(td::Status reason);
void alarm() override;
@ -63,6 +65,7 @@ class DownloadProof : public td::actor::Actor {
td::actor::ActorId<rldp::Rldp> rldp_;
td::actor::ActorId<overlay::Overlays> overlays_;
td::actor::ActorId<adnl::Adnl> adnl_;
td::actor::ActorId<adnl::AdnlExtClient> client_;
td::Promise<td::BufferSlice> promise_;
td::BufferSlice data_;

View file

@ -33,7 +33,8 @@ DownloadState::DownloadState(BlockIdExt block_id, BlockIdExt masterchain_block_i
td::uint32 priority, td::Timestamp timeout,
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
td::actor::ActorId<adnl::Adnl> adnl, td::Promise<td::BufferSlice> promise)
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<adnl::AdnlExtClient> client,
td::Promise<td::BufferSlice> promise)
: block_id_(block_id)
, masterchain_block_id_(masterchain_block_id)
, local_id_(local_id)
@ -45,6 +46,7 @@ DownloadState::DownloadState(BlockIdExt block_id, BlockIdExt masterchain_block_i
, rldp_(rldp)
, overlays_(overlays)
, adnl_(adnl)
, client_(client)
, promise_(std::move(promise)) {
}
@ -89,7 +91,7 @@ void DownloadState::start_up() {
void DownloadState::got_block_handle(BlockHandle handle) {
handle_ = std::move(handle);
if (!download_from_.is_zero()) {
if (!download_from_.is_zero() || !client_.empty()) {
got_node_to_download(download_from_);
} else {
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<std::vector<adnl::AdnlNodeIdShort>> R) {
@ -130,8 +132,14 @@ void DownloadState::got_node_to_download(adnl::AdnlNodeIdShort node) {
query = create_serialize_tl_object<ton_api::tonNode_prepareZeroState>(create_tl_block_id(block_id_));
}
td::actor::send_closure(overlays_, &overlay::Overlays::send_query, download_from_, local_id_, overlay_id_,
"get_prepare", std::move(P), td::Timestamp::in(1.0), std::move(query));
if (client_.empty()) {
td::actor::send_closure(overlays_, &overlay::Overlays::send_query, download_from_, local_id_, overlay_id_,
"get_prepare", std::move(P), td::Timestamp::in(1.0), std::move(query));
} else {
td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "get_prepare",
create_serialize_tl_object_suffix<ton_api::tonNode_query>(std::move(query)),
td::Timestamp::in(1.0), std::move(P));
}
}
void DownloadState::got_block_state_description(td::BufferSlice data) {
@ -162,9 +170,15 @@ void DownloadState::got_block_state_description(td::BufferSlice data) {
td::BufferSlice query =
create_serialize_tl_object<ton_api::tonNode_downloadZeroState>(create_tl_block_id(block_id_));
td::actor::send_closure(overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_,
overlay_id_, "download state", std::move(P), timeout_, std::move(query),
FullNode::max_state_size(), rldp_);
if (client_.empty()) {
td::actor::send_closure(overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_,
overlay_id_, "download state", std::move(P), timeout_, std::move(query),
FullNode::max_state_size(), rldp_);
} else {
td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "download state",
create_serialize_tl_object_suffix<ton_api::tonNode_query>(std::move(query)),
timeout_, std::move(P));
}
}));
}
@ -197,9 +211,15 @@ void DownloadState::got_block_state_part(td::BufferSlice data, td::uint32 reques
td::BufferSlice query = create_serialize_tl_object<ton_api::tonNode_downloadPersistentStateSlice>(
create_tl_block_id(block_id_), create_tl_block_id(masterchain_block_id_), sum_, part_size);
td::actor::send_closure(overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_, overlay_id_,
"download state", std::move(P), timeout_, std::move(query), FullNode::max_state_size(),
rldp_);
if (client_.empty()) {
td::actor::send_closure(overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_, overlay_id_,
"download state", std::move(P), timeout_, std::move(query), FullNode::max_state_size(),
rldp_);
} else {
td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "download state",
create_serialize_tl_object_suffix<ton_api::tonNode_query>(std::move(query)), timeout_,
std::move(P));
}
}
void DownloadState::got_block_state(td::BufferSlice data) {

View file

@ -22,6 +22,7 @@
#include "ton/ton-types.h"
#include "validator/validator.h"
#include "rldp/rldp.h"
#include "adnl/adnl-ext-client.h"
namespace ton {
@ -35,7 +36,8 @@ class DownloadState : public td::actor::Actor {
overlay::OverlayIdShort overlay_id, adnl::AdnlNodeIdShort download_from, td::uint32 priority,
td::Timestamp timeout, td::actor::ActorId<ValidatorManagerInterface> validator_manager,
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
td::actor::ActorId<adnl::Adnl> adnl, td::Promise<td::BufferSlice> promise);
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<adnl::AdnlExtClient> client,
td::Promise<td::BufferSlice> promise);
void abort_query(td::Status reason);
void alarm() override;
@ -63,6 +65,7 @@ class DownloadState : public td::actor::Actor {
td::actor::ActorId<rldp::Rldp> rldp_;
td::actor::ActorId<overlay::Overlays> overlays_;
td::actor::ActorId<adnl::Adnl> adnl_;
td::actor::ActorId<adnl::AdnlExtClient> client_;
td::Promise<td::BufferSlice> promise_;
BlockHandle handle_;

View file

@ -36,7 +36,8 @@ GetNextKeyBlocks::GetNextKeyBlocks(BlockIdExt block_id, td::uint32 limit, adnl::
td::uint32 priority, td::Timestamp timeout,
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
td::actor::ActorId<adnl::Adnl> adnl, td::Promise<std::vector<BlockIdExt>> promise)
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<adnl::AdnlExtClient> client,
td::Promise<std::vector<BlockIdExt>> promise)
: block_id_(block_id)
, limit_(limit)
, local_id_(local_id)
@ -48,6 +49,7 @@ GetNextKeyBlocks::GetNextKeyBlocks(BlockIdExt block_id, td::uint32 limit, adnl::
, rldp_(rldp)
, overlays_(overlays)
, adnl_(adnl)
, client_(client)
, promise_(std::move(promise)) {
}
@ -97,7 +99,7 @@ void GetNextKeyBlocks::start_up() {
void GetNextKeyBlocks::got_download_token(std::unique_ptr<DownloadToken> token) {
token_ = std::move(token);
if (download_from_.is_zero()) {
if (download_from_.is_zero() && client_.empty()) {
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<std::vector<adnl::AdnlNodeIdShort>> R) {
if (R.is_error()) {
td::actor::send_closure(SelfId, &GetNextKeyBlocks::abort_query, R.move_as_error());
@ -130,11 +132,15 @@ void GetNextKeyBlocks::got_node_to_download(adnl::AdnlNodeIdShort node) {
td::actor::send_closure(SelfId, &GetNextKeyBlocks::got_result, R.move_as_ok());
}
});
td::actor::send_closure(
overlays_, &overlay::Overlays::send_query, download_from_, local_id_, overlay_id_, "get_prepare", std::move(P),
td::Timestamp::in(1.0),
create_serialize_tl_object<ton_api::tonNode_getNextKeyBlockIds>(create_tl_block_id(block_id_), limit_));
auto query = create_serialize_tl_object<ton_api::tonNode_getNextKeyBlockIds>(create_tl_block_id(block_id_), limit_);
if (client_.empty()) {
td::actor::send_closure(overlays_, &overlay::Overlays::send_query, download_from_, local_id_, overlay_id_,
"get_prepare", std::move(P), td::Timestamp::in(1.0), std::move(query));
} else {
td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "get_prepare",
create_serialize_tl_object_suffix<ton_api::tonNode_query>(std::move(query)),
td::Timestamp::in(1.0), std::move(P));
}
}
void GetNextKeyBlocks::got_result(td::BufferSlice data) {
@ -173,7 +179,8 @@ void GetNextKeyBlocks::download_next_proof() {
});
td::actor::create_actor<DownloadProof>("downloadproofreq", block_id, false, local_id_, overlay_id_, download_from_,
priority_, timeout_, validator_manager_, rldp_, overlays_, adnl_, std::move(P))
priority_, timeout_, validator_manager_, rldp_, overlays_, adnl_, client_,
std::move(P))
.release();
}

View file

@ -22,6 +22,7 @@
#include "ton/ton-types.h"
#include "validator/validator.h"
#include "rldp/rldp.h"
#include "adnl/adnl-ext-client.h"
namespace ton {
@ -35,7 +36,8 @@ class GetNextKeyBlocks : public td::actor::Actor {
overlay::OverlayIdShort overlay_id, adnl::AdnlNodeIdShort download_from, td::uint32 priority,
td::Timestamp timeout, td::actor::ActorId<ValidatorManagerInterface> validator_manager,
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
td::actor::ActorId<adnl::Adnl> adnl, td::Promise<std::vector<BlockIdExt>> promise);
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<adnl::AdnlExtClient> client,
td::Promise<std::vector<BlockIdExt>> promise);
void abort_query(td::Status reason);
void alarm() override;
@ -67,6 +69,7 @@ class GetNextKeyBlocks : public td::actor::Actor {
td::actor::ActorId<rldp::Rldp> rldp_;
td::actor::ActorId<overlay::Overlays> overlays_;
td::actor::ActorId<adnl::Adnl> adnl_;
td::actor::ActorId<adnl::AdnlExtClient> client_;
td::Promise<std::vector<BlockIdExt>> promise_;
std::vector<BlockIdExt> pending_;

View file

@ -59,6 +59,9 @@ struct ValidatorManagerOptions : public td::CntObject {
virtual bool is_hardfork(BlockIdExt block_id) const = 0;
virtual td::uint32 get_vertical_height(BlockSeqno seqno) const = 0;
virtual td::uint32 get_filedb_depth() const = 0;
virtual td::uint32 key_block_utime_step() const {
return 86400;
}
virtual void set_zero_block_id(BlockIdExt block_id) = 0;
virtual void set_init_block_id(BlockIdExt block_id) = 0;