1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-02-15 04:32:21 +00:00
ton/tonlib/tonlib/Config.cpp
2020-04-30 15:04:47 +04:00

146 lines
5.9 KiB
C++

/*
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 "Config.h"
#include "adnl/adnl-node-id.hpp"
#include "td/utils/JsonBuilder.h"
namespace tonlib {
td::Result<ton::BlockIdExt> parse_block_id_ext(td::JsonObject &obj) {
ton::WorkchainId zero_workchain_id;
{
TRY_RESULT(wc, td::get_json_object_int_field(obj, "workchain"));
zero_workchain_id = wc;
}
ton::ShardId zero_shard_id; // uint64
{
TRY_RESULT(shard_id, td::get_json_object_long_field(obj, "shard"));
zero_shard_id = static_cast<ton::ShardId>(shard_id);
}
ton::BlockSeqno zero_seqno;
{
TRY_RESULT(seqno, td::get_json_object_int_field(obj, "seqno"));
zero_seqno = seqno;
}
ton::RootHash zero_root_hash;
{
TRY_RESULT(hash_b64, td::get_json_object_string_field(obj, "root_hash"));
TRY_RESULT(hash, td::base64_decode(hash_b64));
if (hash.size() * 8 != ton::RootHash::size()) {
return td::Status::Error("Invalid config (8)");
}
zero_root_hash = ton::RootHash(td::ConstBitPtr(td::Slice(hash).ubegin()));
}
ton::FileHash zero_file_hash;
{
TRY_RESULT(hash_b64, td::get_json_object_string_field(obj, "file_hash"));
TRY_RESULT(hash, td::base64_decode(hash_b64));
if (hash.size() * 8 != ton::FileHash::size()) {
return td::Status::Error("Invalid config (9)");
}
zero_file_hash = ton::RootHash(td::ConstBitPtr(td::Slice(hash).ubegin()));
}
return ton::BlockIdExt(zero_workchain_id, zero_shard_id, zero_seqno, std::move(zero_root_hash),
std::move(zero_file_hash));
}
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)");
}
//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)");
//}
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));
}
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 hardfork : res.hardforks) {
if (!res.init_block_id.is_valid() || hardfork.seqno() > res.init_block_id.seqno()) {
LOG(INFO) << "Replace init_block with hardfork: " << res.init_block_id.to_str() << " -> " << hardfork.to_str();
res.init_block_id = hardfork;
}
}
return res;
}
} // namespace tonlib