mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
Accelerator: partial fullnodes (#1393)
* Accelerator: partial fullnodes 1) Node can monitor a subset of shards 2) New archive slice format (sharded) 3) Validators are still required to have all shards 4) Support partial liteservers in lite-client, blockchain explorer, tonlib 5) Proxy liteserver * Fix compilation error
This commit is contained in:
parent
62444100f5
commit
954a96a077
83 changed files with 3213 additions and 1113 deletions
|
@ -10,7 +10,6 @@ set(TONLIB_SOURCE
|
|||
tonlib/Client.cpp
|
||||
tonlib/Config.cpp
|
||||
tonlib/ExtClient.cpp
|
||||
tonlib/ExtClientLazy.cpp
|
||||
tonlib/ExtClientOutbound.cpp
|
||||
tonlib/KeyStorage.cpp
|
||||
tonlib/KeyValue.cpp
|
||||
|
@ -25,7 +24,6 @@ set(TONLIB_SOURCE
|
|||
tonlib/Client.h
|
||||
tonlib/Config.h
|
||||
tonlib/ExtClient.h
|
||||
tonlib/ExtClientLazy.h
|
||||
tonlib/ExtClientOutbound.h
|
||||
tonlib/KeyStorage.h
|
||||
tonlib/KeyValue.h
|
||||
|
|
|
@ -659,11 +659,12 @@ TEST(Tonlib, ConfigCache) {
|
|||
],
|
||||
"validator": {
|
||||
"@type": "validator.config.global",
|
||||
"zero_state": {
|
||||
"init_block": {
|
||||
"workchain": -1,
|
||||
"shard": -9223372036854775808,
|
||||
"seqno": 0,
|
||||
"file_hash": "eh9yveSz1qMdJ7mOsO+I+H77jkLr9NpAuEkoJuseXBo="
|
||||
"root_hash": "ZXSXxDHhTALFxReyTZRd8E4Ya3ySOmpOWAS4rBX9XBY=",
|
||||
}
|
||||
}
|
||||
})abc";
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#include "Config.h"
|
||||
#include "adnl/adnl-node-id.hpp"
|
||||
#include "td/utils/JsonBuilder.h"
|
||||
#include "auto/tl/ton_api_json.h"
|
||||
#include "ton/ton-tl.hpp"
|
||||
|
||||
namespace tonlib {
|
||||
td::Result<ton::BlockIdExt> parse_block_id_ext(td::JsonObject &obj) {
|
||||
|
@ -63,75 +65,26 @@ td::Result<ton::BlockIdExt> parse_block_id_ext(td::JsonObject &obj) {
|
|||
td::Result<Config> Config::parse(std::string str) {
|
||||
TRY_RESULT(json, td::json_decode(str));
|
||||
if (json.type() != td::JsonValue::Type::Object) {
|
||||
return td::Status::Error("Invalid config (1)");
|
||||
return td::Status::Error("Invalid config: json is not an object");
|
||||
}
|
||||
//TRY_RESULT(main_type, td::get_json_object_string_field(json.get_object(), "@type", false));
|
||||
//if (main_type != "config.global") {
|
||||
//return td::Status::Error("Invalid config (3)");
|
||||
//}
|
||||
TRY_RESULT(lite_clients_obj,
|
||||
td::get_json_object_field(json.get_object(), "liteservers", td::JsonValue::Type::Array, false));
|
||||
auto &lite_clients = lite_clients_obj.get_array();
|
||||
|
||||
Config res;
|
||||
for (auto &value : lite_clients) {
|
||||
if (value.type() != td::JsonValue::Type::Object) {
|
||||
return td::Status::Error("Invalid config (2)");
|
||||
}
|
||||
auto &object = value.get_object();
|
||||
//TRY_RESULT(value_type, td::get_json_object_string_field(object, "@type", false));
|
||||
//if (value_type != "liteclient.config.global") {
|
||||
//return td::Status::Error("Invalid config (4)");
|
||||
//}
|
||||
ton::ton_api::liteclient_config_global conf;
|
||||
TRY_STATUS(ton::ton_api::from_json(conf, json.get_object()));
|
||||
TRY_RESULT_ASSIGN(res.lite_servers, liteclient::LiteServerConfig::parse_global_config(conf));
|
||||
|
||||
TRY_RESULT(ip, td::get_json_object_long_field(object, "ip", false));
|
||||
TRY_RESULT(port, td::get_json_object_int_field(object, "port", false));
|
||||
Config::LiteClient client;
|
||||
TRY_STATUS(client.address.init_host_port(td::IPAddress::ipv4_to_str(static_cast<td::int32>(ip)), port));
|
||||
|
||||
TRY_RESULT(id_obj, td::get_json_object_field(object, "id", td::JsonValue::Type::Object, false));
|
||||
auto &id = id_obj.get_object();
|
||||
TRY_RESULT(id_type, td::get_json_object_string_field(id, "@type", false));
|
||||
if (id_type != "pub.ed25519") {
|
||||
return td::Status::Error("Invalid config (5)");
|
||||
}
|
||||
TRY_RESULT(key_base64, td::get_json_object_string_field(id, "key", false));
|
||||
TRY_RESULT(key, td::base64_decode(key_base64));
|
||||
if (key.size() != 32) {
|
||||
return td::Status::Error("Invalid config (6)");
|
||||
}
|
||||
|
||||
client.adnl_id = ton::adnl::AdnlNodeIdFull(ton::pubkeys::Ed25519(td::Bits256(td::Slice(key).ubegin())));
|
||||
res.lite_clients.push_back(std::move(client));
|
||||
if (!conf.validator_) {
|
||||
return td::Status::Error("Invalid config: no 'validator' section");
|
||||
}
|
||||
if (!conf.validator_->zero_state_) {
|
||||
return td::Status::Error("Invalid config: no zerostate");
|
||||
}
|
||||
res.zero_state_id = ton::create_block_id(conf.validator_->zero_state_);
|
||||
if (conf.validator_->init_block_) {
|
||||
res.init_block_id = ton::create_block_id(conf.validator_->init_block_);
|
||||
}
|
||||
|
||||
TRY_RESULT(validator_obj,
|
||||
td::get_json_object_field(json.get_object(), "validator", td::JsonValue::Type::Object, false));
|
||||
auto &validator = validator_obj.get_object();
|
||||
TRY_RESULT(validator_type, td::get_json_object_string_field(validator, "@type", false));
|
||||
if (validator_type != "validator.config.global") {
|
||||
return td::Status::Error("Invalid config (7)");
|
||||
}
|
||||
TRY_RESULT(zero_state_obj, td::get_json_object_field(validator, "zero_state", td::JsonValue::Type::Object, false));
|
||||
TRY_RESULT(zero_state_id, parse_block_id_ext(zero_state_obj.get_object()));
|
||||
res.zero_state_id = zero_state_id;
|
||||
auto r_init_block_obj = td::get_json_object_field(validator, "init_block", td::JsonValue::Type::Object, false);
|
||||
if (r_init_block_obj.is_ok()) {
|
||||
TRY_RESULT(init_block_id, parse_block_id_ext(r_init_block_obj.move_as_ok().get_object()));
|
||||
res.init_block_id = init_block_id;
|
||||
}
|
||||
|
||||
auto r_hardforks = td::get_json_object_field(validator, "hardforks", td::JsonValue::Type::Array, false);
|
||||
if (r_hardforks.is_ok()) {
|
||||
auto hardforks_obj = r_hardforks.move_as_ok();
|
||||
auto &hardforks = hardforks_obj.get_array();
|
||||
for (auto &fork : hardforks) {
|
||||
if (fork.type() != td::JsonValue::Type::Object) {
|
||||
return td::Status::Error("Invalid config (8)");
|
||||
}
|
||||
TRY_RESULT(fork_block, parse_block_id_ext(fork.get_object()));
|
||||
res.hardforks.push_back(std::move(fork_block));
|
||||
}
|
||||
for (auto &fork : conf.validator_->hardforks_) {
|
||||
res.hardforks.push_back(ton::create_block_id(fork));
|
||||
}
|
||||
|
||||
for (auto hardfork : res.hardforks) {
|
||||
|
|
|
@ -20,17 +20,14 @@
|
|||
#include "adnl/adnl-node-id.hpp"
|
||||
#include "td/utils/port/IPAddress.h"
|
||||
#include "ton/ton-types.h"
|
||||
#include "lite-client/ext-client.h"
|
||||
|
||||
namespace tonlib {
|
||||
struct Config {
|
||||
struct LiteClient {
|
||||
ton::adnl::AdnlNodeIdFull adnl_id;
|
||||
td::IPAddress address;
|
||||
};
|
||||
ton::BlockIdExt zero_state_id;
|
||||
ton::BlockIdExt init_block_id;
|
||||
std::vector<ton::BlockIdExt> hardforks;
|
||||
std::vector<LiteClient> lite_clients;
|
||||
std::vector<liteclient::LiteServerConfig> lite_servers;
|
||||
std::string name;
|
||||
static td::Result<Config> parse(std::string str);
|
||||
};
|
||||
|
|
|
@ -65,7 +65,7 @@ void ExtClient::send_raw_query(td::BufferSlice query, td::Promise<td::BufferSlic
|
|||
if (client_.adnl_ext_client_.empty()) {
|
||||
return P.set_error(TonlibError::NoLiteServers());
|
||||
}
|
||||
td::actor::send_closure(client_.adnl_ext_client_, &ton::adnl::AdnlExtClient::send_query, "query", std::move(query),
|
||||
td::actor::send_closure(client_.adnl_ext_client_, &liteclient::ExtClient::send_query, "query", std::move(query),
|
||||
td::Timestamp::in(10.0), std::move(P));
|
||||
}
|
||||
} // namespace tonlib
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include "td/utils/Container.h"
|
||||
#include "td/utils/Random.h"
|
||||
|
||||
#include "ExtClientLazy.h"
|
||||
#include "lite-client/ext-client.h"
|
||||
#include "TonlibError.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
@ -38,7 +38,7 @@ class LastConfig;
|
|||
struct LastBlockState;
|
||||
struct LastConfigState;
|
||||
struct ExtClientRef {
|
||||
td::actor::ActorId<ExtClientLazy> adnl_ext_client_;
|
||||
td::actor::ActorId<liteclient::ExtClient> adnl_ext_client_;
|
||||
td::actor::ActorId<LastBlock> last_block_actor_;
|
||||
td::actor::ActorId<LastConfig> last_config_actor_;
|
||||
};
|
||||
|
@ -97,7 +97,7 @@ class ExtClient {
|
|||
|
||||
void force_change_liteserver() {
|
||||
if (!client_.adnl_ext_client_.empty()) {
|
||||
td::actor::send_closure(client_.adnl_ext_client_, &ExtClientLazy::force_change_liteserver);
|
||||
td::actor::send_closure(client_.adnl_ext_client_, &liteclient::ExtClient::reset_servers);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,152 +0,0 @@
|
|||
/*
|
||||
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-2020 Telegram Systems LLP
|
||||
*/
|
||||
#include "ExtClientLazy.h"
|
||||
#include "TonlibError.h"
|
||||
#include "td/utils/Random.h"
|
||||
namespace tonlib {
|
||||
|
||||
class ExtClientLazyImp : public ExtClientLazy {
|
||||
public:
|
||||
ExtClientLazyImp(std::vector<std::pair<ton::adnl::AdnlNodeIdFull, td::IPAddress>> servers,
|
||||
td::unique_ptr<ExtClientLazy::Callback> callback)
|
||||
: servers_(std::move(servers)), callback_(std::move(callback)) {
|
||||
CHECK(!servers_.empty());
|
||||
}
|
||||
|
||||
void start_up() override {
|
||||
td::Random::Fast rnd;
|
||||
td::random_shuffle(td::as_mutable_span(servers_), rnd);
|
||||
}
|
||||
|
||||
void check_ready(td::Promise<td::Unit> promise) override {
|
||||
before_query();
|
||||
if (client_.empty()) {
|
||||
return promise.set_error(TonlibError::Cancelled());
|
||||
}
|
||||
send_closure(client_, &ton::adnl::AdnlExtClient::check_ready, std::move(promise));
|
||||
}
|
||||
|
||||
void send_query(std::string name, td::BufferSlice data, td::Timestamp timeout,
|
||||
td::Promise<td::BufferSlice> promise) override {
|
||||
before_query();
|
||||
if (client_.empty()) {
|
||||
return promise.set_error(TonlibError::Cancelled());
|
||||
}
|
||||
td::Promise<td::BufferSlice> P = [SelfId = actor_id(this), idx = cur_server_idx_,
|
||||
promise = std::move(promise)](td::Result<td::BufferSlice> R) mutable {
|
||||
if (R.is_error() &&
|
||||
(R.error().code() == ton::ErrorCode::timeout || R.error().code() == ton::ErrorCode::cancelled)) {
|
||||
td::actor::send_closure(SelfId, &ExtClientLazyImp::set_server_bad, idx, true);
|
||||
}
|
||||
promise.set_result(std::move(R));
|
||||
};
|
||||
send_closure(client_, &ton::adnl::AdnlExtClient::send_query, std::move(name), std::move(data), timeout,
|
||||
std::move(P));
|
||||
}
|
||||
|
||||
void force_change_liteserver() override {
|
||||
if (servers_.size() == 1) {
|
||||
return;
|
||||
}
|
||||
cur_server_bad_ = cur_server_bad_force_ = true;
|
||||
}
|
||||
|
||||
private:
|
||||
void before_query() {
|
||||
if (is_closing_) {
|
||||
return;
|
||||
}
|
||||
alarm_timestamp() = td::Timestamp::in(MAX_NO_QUERIES_TIMEOUT);
|
||||
if (cur_server_bad_) {
|
||||
++cur_server_idx_;
|
||||
} else if (!client_.empty()) {
|
||||
return;
|
||||
}
|
||||
class Callback : public ton::adnl::AdnlExtClient::Callback {
|
||||
public:
|
||||
explicit Callback(td::actor::ActorShared<ExtClientLazyImp> parent, size_t idx)
|
||||
: parent_(std::move(parent)), idx_(idx) {
|
||||
}
|
||||
void on_ready() override {
|
||||
td::actor::send_closure(parent_, &ExtClientLazyImp::set_server_bad, idx_, false);
|
||||
}
|
||||
void on_stop_ready() override {
|
||||
td::actor::send_closure(parent_, &ExtClientLazyImp::set_server_bad, idx_, true);
|
||||
}
|
||||
|
||||
private:
|
||||
td::actor::ActorShared<ExtClientLazyImp> parent_;
|
||||
size_t idx_;
|
||||
};
|
||||
ref_cnt_++;
|
||||
cur_server_bad_ = false;
|
||||
cur_server_bad_force_ = false;
|
||||
const auto& s = servers_[cur_server_idx_ % servers_.size()];
|
||||
LOG(INFO) << "Connecting to liteserver " << s.second;
|
||||
client_ = ton::adnl::AdnlExtClient::create(
|
||||
s.first, s.second, std::make_unique<Callback>(td::actor::actor_shared(this), cur_server_idx_));
|
||||
}
|
||||
|
||||
std::vector<std::pair<ton::adnl::AdnlNodeIdFull, td::IPAddress>> servers_;
|
||||
size_t cur_server_idx_ = 0;
|
||||
bool cur_server_bad_ = false;
|
||||
bool cur_server_bad_force_ = false;
|
||||
|
||||
td::actor::ActorOwn<ton::adnl::AdnlExtClient> client_;
|
||||
td::unique_ptr<ExtClientLazy::Callback> callback_;
|
||||
static constexpr double MAX_NO_QUERIES_TIMEOUT = 100;
|
||||
|
||||
bool is_closing_{false};
|
||||
td::uint32 ref_cnt_{1};
|
||||
|
||||
void set_server_bad(size_t idx, bool bad) {
|
||||
if (idx == cur_server_idx_ && servers_.size() > 1 && !cur_server_bad_force_) {
|
||||
cur_server_bad_ = bad;
|
||||
}
|
||||
}
|
||||
void alarm() override {
|
||||
client_.reset();
|
||||
}
|
||||
void hangup_shared() override {
|
||||
ref_cnt_--;
|
||||
try_stop();
|
||||
}
|
||||
void hangup() override {
|
||||
is_closing_ = true;
|
||||
ref_cnt_--;
|
||||
client_.reset();
|
||||
try_stop();
|
||||
}
|
||||
void try_stop() {
|
||||
if (is_closing_ && ref_cnt_ == 0) {
|
||||
stop();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
td::actor::ActorOwn<ExtClientLazy> ExtClientLazy::create(ton::adnl::AdnlNodeIdFull dst, td::IPAddress dst_addr,
|
||||
td::unique_ptr<Callback> callback) {
|
||||
return create({std::make_pair(dst, dst_addr)}, std::move(callback));
|
||||
}
|
||||
|
||||
td::actor::ActorOwn<ExtClientLazy> ExtClientLazy::create(
|
||||
std::vector<std::pair<ton::adnl::AdnlNodeIdFull, td::IPAddress>> servers, td::unique_ptr<Callback> callback) {
|
||||
return td::actor::create_actor<ExtClientLazyImp>("ExtClientLazy", std::move(servers), std::move(callback));
|
||||
}
|
||||
} // namespace tonlib
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
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-2020 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
#include "td/actor/actor.h"
|
||||
|
||||
#include "adnl/adnl-ext-client.h"
|
||||
|
||||
namespace tonlib {
|
||||
class ExtClientLazy : public ton::adnl::AdnlExtClient {
|
||||
public:
|
||||
class Callback {
|
||||
public:
|
||||
virtual ~Callback() {
|
||||
}
|
||||
};
|
||||
|
||||
virtual void force_change_liteserver() = 0;
|
||||
|
||||
static td::actor::ActorOwn<ExtClientLazy> create(ton::adnl::AdnlNodeIdFull dst, td::IPAddress dst_addr,
|
||||
td::unique_ptr<Callback> callback);
|
||||
static td::actor::ActorOwn<ExtClientLazy> create(
|
||||
std::vector<std::pair<ton::adnl::AdnlNodeIdFull, td::IPAddress>> servers, td::unique_ptr<Callback> callback);
|
||||
};
|
||||
|
||||
} // namespace tonlib
|
|
@ -20,15 +20,12 @@
|
|||
#include "ExtClientOutbound.h"
|
||||
#include "TonlibError.h"
|
||||
#include <map>
|
||||
|
||||
namespace tonlib {
|
||||
|
||||
class ExtClientOutboundImp : public ExtClientOutbound {
|
||||
class ExtClientOutboundImpl : public ExtClientOutbound {
|
||||
public:
|
||||
ExtClientOutboundImp(td::unique_ptr<ExtClientOutbound::Callback> callback) : callback_(std::move(callback)) {
|
||||
}
|
||||
|
||||
void check_ready(td::Promise<td::Unit> promise) override {
|
||||
promise.set_error(td::Status::Error("Not supported"));
|
||||
ExtClientOutboundImpl(td::unique_ptr<ExtClientOutbound::Callback> callback) : callback_(std::move(callback)) {
|
||||
}
|
||||
|
||||
void send_query(std::string name, td::BufferSlice data, td::Timestamp timeout,
|
||||
|
@ -38,9 +35,6 @@ class ExtClientOutboundImp : public ExtClientOutbound {
|
|||
callback_->request(query_id, data.as_slice().str());
|
||||
}
|
||||
|
||||
void force_change_liteserver() override {
|
||||
}
|
||||
|
||||
void on_query_result(td::int64 id, td::Result<td::BufferSlice> r_data, td::Promise<td::Unit> promise) override {
|
||||
auto it = queries_.find(id);
|
||||
if (it == queries_.end()) {
|
||||
|
@ -66,6 +60,6 @@ class ExtClientOutboundImp : public ExtClientOutbound {
|
|||
};
|
||||
|
||||
td::actor::ActorOwn<ExtClientOutbound> ExtClientOutbound::create(td::unique_ptr<Callback> callback) {
|
||||
return td::actor::create_actor<ExtClientOutboundImp>("ExtClientOutbound", std::move(callback));
|
||||
return td::actor::create_actor<ExtClientOutboundImpl>("ExtClientOutbound", std::move(callback));
|
||||
}
|
||||
} // namespace tonlib
|
||||
|
|
|
@ -18,11 +18,10 @@
|
|||
*/
|
||||
#pragma once
|
||||
#include "td/actor/actor.h"
|
||||
|
||||
#include "ExtClientLazy.h"
|
||||
#include "lite-client/ext-client.h"
|
||||
|
||||
namespace tonlib {
|
||||
class ExtClientOutbound : public ExtClientLazy {
|
||||
class ExtClientOutbound : public liteclient::ExtClient {
|
||||
public:
|
||||
class Callback {
|
||||
public:
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
#include "TonlibClient.h"
|
||||
|
||||
#include "tonlib/ExtClientLazy.h"
|
||||
#include "tonlib/ExtClientOutbound.h"
|
||||
#include "tonlib/LastBlock.h"
|
||||
#include "tonlib/LastConfig.h"
|
||||
|
@ -2184,21 +2183,8 @@ void TonlibClient::init_ext_client() {
|
|||
ext_client_outbound_ = client.get();
|
||||
raw_client_ = std::move(client);
|
||||
} else {
|
||||
std::vector<std::pair<ton::adnl::AdnlNodeIdFull, td::IPAddress>> servers;
|
||||
for (const auto& s : config_.lite_clients) {
|
||||
servers.emplace_back(s.adnl_id, s.address);
|
||||
}
|
||||
class Callback : public ExtClientLazy::Callback {
|
||||
public:
|
||||
explicit Callback(td::actor::ActorShared<> parent) : parent_(std::move(parent)) {
|
||||
}
|
||||
|
||||
private:
|
||||
td::actor::ActorShared<> parent_;
|
||||
};
|
||||
ext_client_outbound_ = {};
|
||||
ref_cnt_++;
|
||||
raw_client_ = ExtClientLazy::create(std::move(servers), td::make_unique<Callback>(td::actor::actor_shared()));
|
||||
raw_client_ = liteclient::ExtClient::create(config_.lite_servers, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2860,7 +2846,7 @@ td::Result<TonlibClient::FullConfig> TonlibClient::validate_config(tonlib_api::o
|
|||
TRY_RESULT_PREFIX(new_config, Config::parse(std::move(config->config_)),
|
||||
TonlibError::InvalidConfig("can't parse config"));
|
||||
|
||||
if (new_config.lite_clients.empty() && !config->use_callbacks_for_network_) {
|
||||
if (new_config.lite_servers.empty() && !config->use_callbacks_for_network_) {
|
||||
return TonlibError::InvalidConfig("no lite clients");
|
||||
}
|
||||
td::optional<Config> o_master_config;
|
||||
|
@ -4613,7 +4599,7 @@ td::Status TonlibClient::do_request(const tonlib_api::smc_getLibraries& request,
|
|||
if (query_context_.block_id) {
|
||||
get_libraries(query_context_.block_id.value(), request.library_list_, std::move(promise));
|
||||
} else {
|
||||
client_.with_last_block([this, promise = std::move(promise), library_list = request.library_list_](td::Result<LastBlockState> r_last_block) mutable {
|
||||
client_.with_last_block([this, promise = std::move(promise), library_list = request.library_list_](td::Result<LastBlockState> r_last_block) mutable {
|
||||
if (r_last_block.is_error()) {
|
||||
promise.set_error(r_last_block.move_as_error_prefix(TonlibError::Internal("get last block failed ")));
|
||||
} else {
|
||||
|
@ -4647,7 +4633,7 @@ void TonlibClient::get_libraries(ton::BlockIdExt blkid, std::vector<td::Bits256>
|
|||
|
||||
client_.send_query(ton::lite_api::liteServer_getLibrariesWithProof(ton::create_tl_lite_block_id(blkid), 1, std::move(not_cached_hashes)),
|
||||
promise.wrap([self=this, blkid, result_entries = std::move(result_entries), not_cached_hashes]
|
||||
(td::Result<ton::lite_api::object_ptr<ton::lite_api::liteServer_libraryResultWithProof>> r_libraries) mutable
|
||||
(td::Result<ton::lite_api::object_ptr<ton::lite_api::liteServer_libraryResultWithProof>> r_libraries) mutable
|
||||
-> td::Result<tonlib_api::object_ptr<tonlib_api::smc_libraryResult>> {
|
||||
if (r_libraries.is_error()) {
|
||||
LOG(WARNING) << "cannot obtain found libraries: " << r_libraries.move_as_error().to_string();
|
||||
|
@ -4674,7 +4660,7 @@ void TonlibClient::get_libraries(ton::BlockIdExt blkid, std::vector<td::Bits256>
|
|||
auto csr = libraries_dict.lookup(hash.bits(), 256);
|
||||
if (csr.is_null()) {
|
||||
LOG(WARNING) << "library " << hash.to_hex() << " not found in config";
|
||||
if (std::any_of(libraries->result_.begin(), libraries->result_.end(),
|
||||
if (std::any_of(libraries->result_.begin(), libraries->result_.end(),
|
||||
[&hash](const auto& lib) { return lib->hash_.bits().equals(hash.cbits(), 256); })) {
|
||||
return TonlibError::Internal("library is included in response but it's not found in proof");
|
||||
}
|
||||
|
@ -4685,7 +4671,7 @@ void TonlibClient::get_libraries(ton::BlockIdExt blkid, std::vector<td::Bits256>
|
|||
return TonlibError::Internal("cannot unpack LibDescr record");
|
||||
}
|
||||
|
||||
auto lib_it = std::find_if(libraries->result_.begin(), libraries->result_.end(),
|
||||
auto lib_it = std::find_if(libraries->result_.begin(), libraries->result_.end(),
|
||||
[&hash](const auto& lib) { return lib->hash_.bits().equals(hash.cbits(), 256); });
|
||||
if (lib_it == libraries->result_.end()) {
|
||||
return TonlibError::Internal("library is found in proof but not in response");
|
||||
|
@ -4703,7 +4689,7 @@ void TonlibClient::get_libraries(ton::BlockIdExt blkid, std::vector<td::Bits256>
|
|||
if (contents.ok()->get_hash() != libdescr.lib->get_hash()) {
|
||||
return TonlibError::Internal(PSLICE() << "library hash mismatch data " << lib->hash_.to_hex() << " != proof " << libdescr.lib->get_hash().to_hex());
|
||||
}
|
||||
|
||||
|
||||
result_entries.push_back(tonlib_api::make_object<tonlib_api::smc_libraryEntry>(lib->hash_, lib->data_.as_slice().str()));
|
||||
self->libraries.set_ref(lib->hash_, contents.move_as_ok());
|
||||
LOG(DEBUG) << "registered library " << lib->hash_.to_hex();
|
||||
|
@ -5667,14 +5653,14 @@ td::Status TonlibClient::do_request(const tonlib_api::blocks_lookupBlock& reques
|
|||
auto blkid = ton::BlockId(request.id_->workchain_, request.id_->shard_, request.id_->seqno_);
|
||||
client_.with_last_block(
|
||||
[self = this, blkid, lite_block = std::move(lite_block), mode = request.mode_, lt = (td::uint64)request.lt_,
|
||||
utime = (td::uint32)request.utime_, promise = std::move(promise)](td::Result<LastBlockState> r_last_block) mutable {
|
||||
utime = (td::uint32)request.utime_, promise = std::move(promise)](td::Result<LastBlockState> r_last_block) mutable {
|
||||
if (r_last_block.is_error()) {
|
||||
promise.set_error(r_last_block.move_as_error_prefix(TonlibError::Internal("get last block failed ")));
|
||||
return;
|
||||
}
|
||||
|
||||
self->client_.send_query(ton::lite_api::liteServer_lookupBlockWithProof(mode, std::move(lite_block), ton::create_tl_lite_block_id(r_last_block.ok().last_block_id), lt, utime),
|
||||
promise.wrap([blkid, mode, utime, lt, last_block = r_last_block.ok().last_block_id](lite_api_ptr<ton::lite_api::liteServer_lookupBlockResult>&& result)
|
||||
promise.wrap([blkid, mode, utime, lt, last_block = r_last_block.ok().last_block_id](lite_api_ptr<ton::lite_api::liteServer_lookupBlockResult>&& result)
|
||||
-> td::Result<object_ptr<tonlib_api::ton_blockIdExt>> {
|
||||
TRY_STATUS(check_lookup_block_proof(result, mode, blkid, last_block, lt, utime));
|
||||
return to_tonlib_api(*result->id_);
|
||||
|
@ -5706,7 +5692,7 @@ td::Status check_lookup_block_proof(lite_api_ptr<ton::lite_api::liteServer_looku
|
|||
if (state.is_error()) {
|
||||
LOG(WARNING) << "cannot check state proof: " << state.move_as_error().to_string();
|
||||
return state.move_as_error();
|
||||
}
|
||||
}
|
||||
auto state_root = state.move_as_ok();
|
||||
auto prev_blocks_dict = block::get_prev_blocks_dict(state_root);
|
||||
if (!prev_blocks_dict) {
|
||||
|
@ -5816,7 +5802,7 @@ td::Status check_lookup_block_proof(lite_api_ptr<ton::lite_api::liteServer_looku
|
|||
if (!(tlb::unpack_cell(prev_root, prev_blk) && tlb::unpack_cell(prev_blk.info, prev_info))) {
|
||||
return td::Status::Error("prev header unpack failed");
|
||||
}
|
||||
|
||||
|
||||
if (mode & 2) {
|
||||
if (prev_info.end_lt > lt) {
|
||||
return td::Status::Error("prev header end_lt > lt");
|
||||
|
@ -5831,7 +5817,7 @@ td::Status check_lookup_block_proof(lite_api_ptr<ton::lite_api::liteServer_looku
|
|||
if (info.gen_utime < utime) {
|
||||
return td::Status::Error("header end_lt < lt");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (vm::VmError& err) {
|
||||
return td::Status::Error(PSLICE() << "error while checking lookupBlock proof: " << err.get_msg());
|
||||
|
@ -5937,7 +5923,7 @@ td::Status TonlibClient::do_request(const tonlib_api::blocks_getTransactions& re
|
|||
bool check_proof = request.mode_ & ton::lite_api::liteServer_listBlockTransactions::WANT_PROOF_MASK;
|
||||
bool reverse_mode = request.mode_ & ton::lite_api::liteServer_listBlockTransactions::REVERSE_ORDER_MASK;
|
||||
bool has_starting_tx = request.mode_ & ton::lite_api::liteServer_listBlockTransactions::AFTER_MASK;
|
||||
|
||||
|
||||
td::Bits256 start_addr;
|
||||
ton::LogicalTime start_lt;
|
||||
ton::lite_api::object_ptr<ton::lite_api::liteServer_transactionId3> after;
|
||||
|
@ -5945,7 +5931,7 @@ td::Status TonlibClient::do_request(const tonlib_api::blocks_getTransactions& re
|
|||
if (!request.after_) {
|
||||
return td::Status::Error("Missing field `after`");
|
||||
}
|
||||
TRY_RESULT_ASSIGN(start_addr, to_bits256(request.after_->account_, "account"));
|
||||
TRY_RESULT_ASSIGN(start_addr, to_bits256(request.after_->account_, "account"));
|
||||
start_lt = request.after_->lt_;
|
||||
after = ton::lite_api::make_object<ton::lite_api::liteServer_transactionId3>(start_addr, start_lt);
|
||||
} else {
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "td/utils/optional.h"
|
||||
|
||||
#include "smc-envelope/ManualDns.h"
|
||||
#include "lite-client/ext-client.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
|
@ -113,7 +114,7 @@ class TonlibClient : public td::actor::Actor {
|
|||
vm::Dictionary libraries{256};
|
||||
|
||||
// network
|
||||
td::actor::ActorOwn<ExtClientLazy> raw_client_;
|
||||
td::actor::ActorOwn<liteclient::ExtClient> raw_client_;
|
||||
td::actor::ActorId<ExtClientOutbound> ext_client_outbound_;
|
||||
td::actor::ActorOwn<LastBlock> raw_last_block_;
|
||||
td::actor::ActorOwn<LastConfig> raw_last_config_;
|
||||
|
|
|
@ -47,8 +47,6 @@
|
|||
#include "tonlib/TonlibClient.h"
|
||||
#include "tonlib/TonlibCallback.h"
|
||||
|
||||
#include "tonlib/ExtClientLazy.h"
|
||||
|
||||
#include "smc-envelope/ManualDns.h"
|
||||
#include "smc-envelope/PaymentChannel.h"
|
||||
|
||||
|
@ -57,6 +55,7 @@
|
|||
#include "crypto/util/Miner.h"
|
||||
#include "vm/boc.h"
|
||||
#include "vm/cells/CellBuilder.h"
|
||||
#include "lite-client/ext-client.h"
|
||||
|
||||
#include <cinttypes>
|
||||
#include <iostream>
|
||||
|
@ -174,7 +173,7 @@ class TonlibCli : public td::actor::Actor {
|
|||
|
||||
std::map<std::uint64_t, td::Promise<tonlib_api::object_ptr<tonlib_api::Object>>> query_handlers_;
|
||||
|
||||
td::actor::ActorOwn<tonlib::ExtClientLazy> raw_client_;
|
||||
td::actor::ActorOwn<liteclient::ExtClient> raw_client_;
|
||||
|
||||
bool is_closing_{false};
|
||||
td::uint32 ref_cnt_{1};
|
||||
|
@ -223,11 +222,7 @@ class TonlibCli : public td::actor::Actor {
|
|||
|
||||
if (options_.use_callbacks_for_network) {
|
||||
auto config = tonlib::Config::parse(options_.config).move_as_ok();
|
||||
auto lite_clients_size = config.lite_clients.size();
|
||||
CHECK(lite_clients_size != 0);
|
||||
auto lite_client_id = td::Random::fast(0, td::narrow_cast<int>(lite_clients_size) - 1);
|
||||
auto& lite_client = config.lite_clients[lite_client_id];
|
||||
class Callback : public tonlib::ExtClientLazy::Callback {
|
||||
class Callback : public liteclient::ExtClient::Callback {
|
||||
public:
|
||||
explicit Callback(td::actor::ActorShared<> parent) : parent_(std::move(parent)) {
|
||||
}
|
||||
|
@ -236,14 +231,14 @@ class TonlibCli : public td::actor::Actor {
|
|||
td::actor::ActorShared<> parent_;
|
||||
};
|
||||
ref_cnt_++;
|
||||
raw_client_ = tonlib::ExtClientLazy::create(lite_client.adnl_id, lite_client.address,
|
||||
raw_client_ = liteclient::ExtClient::create(config.lite_servers,
|
||||
td::make_unique<Callback>(td::actor::actor_shared()));
|
||||
}
|
||||
|
||||
auto config = !options_.config.empty()
|
||||
? make_object<tonlib_api::config>(options_.config, options_.name,
|
||||
options_.use_callbacks_for_network, options_.ignore_cache)
|
||||
: nullptr;
|
||||
? make_object<tonlib_api::config>(options_.config, options_.name,
|
||||
options_.use_callbacks_for_network, options_.ignore_cache)
|
||||
: nullptr;
|
||||
|
||||
tonlib_api::object_ptr<tonlib_api::KeyStoreType> ks_type;
|
||||
if (options_.in_memory) {
|
||||
|
@ -1545,7 +1540,7 @@ class TonlibCli : public td::actor::Actor {
|
|||
auto update = tonlib_api::move_object_as<tonlib_api::updateSendLiteServerQuery>(std::move(result));
|
||||
CHECK(!raw_client_.empty());
|
||||
snd_bytes_ += update->data_.size();
|
||||
send_closure(raw_client_, &ton::adnl::AdnlExtClient::send_query, "query", td::BufferSlice(update->data_),
|
||||
send_closure(raw_client_, &liteclient::ExtClient::send_query, "query", td::BufferSlice(update->data_),
|
||||
td::Timestamp::in(5),
|
||||
[actor_id = actor_id(this), id = update->id_](td::Result<td::BufferSlice> res) {
|
||||
send_closure(actor_id, &TonlibCli::on_adnl_result, id, std::move(res));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue