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

New liteserver config format

* Specify shards and seqno/utime/lt limits for liteservers in global config
* Support in lite-client, tonlib, blockchain-explorer
* Rework proxy-liteserver
This commit is contained in:
SpyCheese 2024-06-12 18:12:45 +03:00
parent 38ab70c037
commit 007f1fb1d7
26 changed files with 1187 additions and 1130 deletions

View file

@ -19,6 +19,7 @@
#include "Config.h"
#include "adnl/adnl-node-id.hpp"
#include "td/utils/JsonBuilder.h"
#include "auto/tl/ton_api_json.h"
namespace tonlib {
td::Result<ton::BlockIdExt> parse_block_id_ext(td::JsonObject &obj) {
@ -65,67 +66,11 @@ td::Result<Config> Config::parse(std::string str) {
if (json.type() != td::JsonValue::Type::Object) {
return td::Status::Error("Invalid config (1)");
}
td::JsonArray empty_array;
TRY_RESULT(lite_servers_obj,
td::get_json_object_field(json.get_object(), "liteservers", td::JsonValue::Type::Array, true));
auto &lite_servers =
lite_servers_obj.type() == td::JsonValue::Type::Array ? lite_servers_obj.get_array() : empty_array;
TRY_RESULT(lite_servers_v2_obj,
td::get_json_object_field(json.get_object(), "liteservers_v2", td::JsonValue::Type::Array, true));
auto &lite_servers_v2 =
lite_servers_v2_obj.type() == td::JsonValue::Type::Array ? lite_servers_v2_obj.get_array() : empty_array;
auto parse_desc = [&](td::JsonValue &value) -> td::Result<Config::LiteServer> {
if (value.type() != td::JsonValue::Type::Object) {
return td::Status::Error("Invalid config (2)");
}
auto &object = value.get_object();
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::LiteServer server;
TRY_STATUS(server.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 (3)");
}
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 (4)");
}
server.adnl_id = ton::adnl::AdnlNodeIdFull(ton::pubkeys::Ed25519(td::Bits256(td::Slice(key).ubegin())));
return server;
};
Config res;
for (auto &value : lite_servers) {
TRY_RESULT(server, parse_desc(value));
res.lite_servers.push_back(std::move(server));
}
for (auto &value : lite_servers_v2) {
TRY_RESULT(server, parse_desc(value));
server.is_full = false;
TRY_RESULT(shards_obj, td::get_json_object_field(value.get_object(), "shards", td::JsonValue::Type::Array, false));
for (auto &shard : shards_obj.get_array()) {
if (shard.type() != td::JsonValue::Type::Object) {
return td::Status::Error("Invalid config (5)");
}
auto &shard_obj = shard.get_object();
TRY_RESULT(workchain, td::get_json_object_int_field(shard_obj, "workchain", false));
TRY_RESULT(shard_id, td::get_json_object_long_field(shard_obj, "shard", false));
if (shard_id == 0) {
return td::Status::Error("Invalid config (6)");
}
server.shards.emplace_back(workchain, shard_id);
}
res.lite_servers.push_back(std::move(server));
}
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(validator_obj,
td::get_json_object_field(json.get_object(), "validator", td::JsonValue::Type::Object, false));

View file

@ -24,11 +24,10 @@
namespace tonlib {
struct Config {
using LiteServer = liteclient::ExtClient::LiteServer;
ton::BlockIdExt zero_state_id;
ton::BlockIdExt init_block_id;
std::vector<ton::BlockIdExt> hardforks;
std::vector<LiteServer> lite_servers;
std::vector<liteclient::LiteServerConfig> lite_servers;
std::string name;
static td::Result<Config> parse(std::string str);
};

View file

@ -54,7 +54,7 @@ void ExtClient::with_last_block(td::Promise<LastBlockState> promise) {
td::actor::send_closure(client_.last_block_actor_, &LastBlock::get_last_block, std::move(P));
}
void ExtClient::send_raw_query(td::BufferSlice query, ton::ShardIdFull shard, td::Promise<td::BufferSlice> promise) {
void ExtClient::send_raw_query(td::BufferSlice query, td::Promise<td::BufferSlice> promise) {
auto query_id = queries_.create(std::move(promise));
td::Promise<td::BufferSlice> P = [query_id, self = this,
actor_id = td::actor::actor_id()](td::Result<td::BufferSlice> result) {
@ -66,6 +66,6 @@ void ExtClient::send_raw_query(td::BufferSlice query, ton::ShardIdFull shard, td
return P.set_error(TonlibError::NoLiteServers());
}
td::actor::send_closure(client_.adnl_ext_client_, &liteclient::ExtClient::send_query, "query", std::move(query),
shard, td::Timestamp::in(10.0), std::move(P));
td::Timestamp::in(10.0), std::move(P));
}
} // namespace tonlib

View file

@ -31,7 +31,6 @@
#include "lite-client/ext-client.h"
#include "TonlibError.h"
#include "utils.h"
#include "lite-client/QueryTraits.h"
namespace tonlib {
class LastBlock;
@ -65,7 +64,6 @@ class ExtClient {
template <class QueryT>
void send_query(QueryT query, td::Promise<typename QueryT::ReturnType> promise, td::int32 seq_no = -1) {
ton::ShardIdFull shard = liteclient::QueryTraits<QueryT>::get_shard(query);
auto raw_query = ton::serialize_tl_object(&query, true);
td::uint32 tag = td::Random::fast_uint32();
VLOG(lite_server) << "send query to liteserver: " << tag << " " << to_string(query);
@ -79,7 +77,7 @@ class ExtClient {
ton::serialize_tl_object(ton::create_tl_object<ton::lite_api::liteServer_query>(std::move(raw_query)), true);
send_raw_query(
std::move(liteserver_query), shard, [promise = std::move(promise), tag](td::Result<td::BufferSlice> R) mutable {
std::move(liteserver_query), [promise = std::move(promise), tag](td::Result<td::BufferSlice> R) mutable {
auto res = [&]() -> td::Result<typename QueryT::ReturnType> {
TRY_RESULT_PREFIX(data, std::move(R), TonlibError::LiteServerNetwork());
auto r_error = ton::fetch_tl_object<ton::lite_api::liteServer_error>(data.clone(), true);
@ -99,7 +97,7 @@ class ExtClient {
void force_change_liteserver() {
if (!client_.adnl_ext_client_.empty()) {
td::actor::send_closure(client_.adnl_ext_client_, &liteclient::ExtClient::force_change_liteserver);
td::actor::send_closure(client_.adnl_ext_client_, &liteclient::ExtClient::reset_servers);
}
}
@ -109,6 +107,6 @@ class ExtClient {
td::Container<td::Promise<LastBlockState>> last_block_queries_;
td::Container<td::Promise<LastConfigState>> last_config_queries_;
void send_raw_query(td::BufferSlice query, ton::ShardIdFull shard, td::Promise<td::BufferSlice> promise);
void send_raw_query(td::BufferSlice query, td::Promise<td::BufferSlice> promise);
};
} // namespace tonlib

View file

@ -28,14 +28,11 @@ class ExtClientOutboundImpl : public ExtClientOutbound {
ExtClientOutboundImpl(td::unique_ptr<ExtClientOutbound::Callback> callback) : callback_(std::move(callback)) {
}
void send_query(std::string name, td::BufferSlice data, ton::ShardIdFull shard, td::Timestamp timeout,
void send_query(std::string name, td::BufferSlice data, td::Timestamp timeout,
td::Promise<td::BufferSlice> promise) override {
auto query_id = next_query_id_++;
queries_[query_id] = std::move(promise);
callback_->request(query_id, data.as_slice().str(), shard);
}
void force_change_liteserver() override {
callback_->request(query_id, data.as_slice().str());
}
void on_query_result(td::int64 id, td::Result<td::BufferSlice> r_data, td::Promise<td::Unit> promise) override {

View file

@ -27,9 +27,8 @@ class ExtClientOutbound : public liteclient::ExtClient {
public:
virtual ~Callback() {
}
virtual void request(td::int64 id, std::string data, ton::ShardIdFull shard) = 0;
virtual void request(td::int64 id, std::string data) = 0;
};
virtual void on_query_result(td::int64 id, td::Result<td::BufferSlice> r_data, td::Promise<td::Unit> promise) = 0;
static td::actor::ActorOwn<ExtClientOutbound> create(td::unique_ptr<Callback> callback);
};

View file

@ -2078,9 +2078,8 @@ ExtClientRef TonlibClient::get_client_ref() {
return ref;
}
void TonlibClient::proxy_request(td::int64 query_id, std::string data, ton::ShardIdFull shard) {
on_update(
tonlib_api::make_object<tonlib_api::updateSendLiteServerQuery>(query_id, data, shard.workchain, shard.shard));
void TonlibClient::proxy_request(td::int64 query_id, std::string data) {
on_update(tonlib_api::make_object<tonlib_api::updateSendLiteServerQuery>(query_id, data));
}
void TonlibClient::init_ext_client() {
@ -2091,9 +2090,9 @@ void TonlibClient::init_ext_client() {
: parent_(std::move(parent)), config_generation_(config_generation) {
}
void request(td::int64 id, std::string data, ton::ShardIdFull shard) override {
send_closure(parent_, &TonlibClient::proxy_request, (id << 16) | (config_generation_ & 0xffff), std::move(data),
shard);
void request(td::int64 id, std::string data) override {
send_closure(parent_, &TonlibClient::proxy_request, (id << 16) | (config_generation_ & 0xffff),
std::move(data));
}
private:
@ -2106,17 +2105,8 @@ void TonlibClient::init_ext_client() {
ext_client_outbound_ = client.get();
raw_client_ = std::move(client);
} else {
class Callback : public liteclient::ExtClient::Callback {
public:
explicit Callback(td::actor::ActorShared<> parent) : parent_(std::move(parent)) {
}
private:
td::actor::ActorShared<> parent_;
};
ext_client_outbound_ = {};
ref_cnt_++;
raw_client_ = liteclient::ExtClient::create(config_.lite_servers, td::make_unique<Callback>(td::actor::actor_shared()));
raw_client_ = liteclient::ExtClient::create(config_.lite_servers, nullptr);
}
}
@ -4491,8 +4481,8 @@ void deep_library_search(std::set<td::Bits256>& set, std::set<vm::Cell::Hash>& v
}
return;
}
for (unsigned int i = 0; i < loaded_cell.data_cell->get_refs_cnt(); i++) {
deep_library_search(set, visited, libs, loaded_cell.data_cell->get_ref(i), depth - 1);
for (unsigned int i=0; i<loaded_cell.data_cell->get_refs_cnt(); i++) {
deep_library_search(set, visited, libs, loaded_cell.data_cell->get_ref(i), depth - 1, max_libs);
}
}

View file

@ -401,7 +401,7 @@ class TonlibClient : public td::actor::Actor {
td::Status do_request(const tonlib_api::getConfigAll& request,
td::Promise<object_ptr<tonlib_api::configInfo>>&& promise);
void proxy_request(td::int64 query_id, std::string data, ton::ShardIdFull shard);
void proxy_request(td::int64 query_id, std::string data);
void load_libs_from_disk();
void store_libs_to_disk();

View file

@ -1541,7 +1541,7 @@ class TonlibCli : public td::actor::Actor {
CHECK(!raw_client_.empty());
snd_bytes_ += update->data_.size();
send_closure(raw_client_, &liteclient::ExtClient::send_query, "query", td::BufferSlice(update->data_),
ton::ShardIdFull(update->workchain_, update->shard_), td::Timestamp::in(5),
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));
});