/*
This file is part of TON Blockchain source code.
TON Blockchain is free software; you can redistribute it and/or
modify it under the terms of the GNU 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 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with TON Blockchain. If not, see .
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
You must obey the GNU General Public License in all respects for all
of the code used other than OpenSSL. If you modify file(s) with this
exception, you may extend this exception to your version of the file(s),
but you are not obligated to do so. If you do not wish to do so, delete this
exception statement from your version. If you delete this exception statement
from all source files in the program, then also delete it here.
Copyright 2017-2019 Telegram Systems LLP
*/
#pragma once
#include "adnl/adnl.h"
#include "rldp/rldp.h"
#include "dht/dht.h"
#include "validator/manager.h"
#include "validator/validator.h"
#include "validator/full-node.h"
#include "td/actor/MultiPromise.h"
#include "auto/tl/ton_api_json.h"
#include "auto/tl/ton_api.hpp"
enum ValidatorEnginePermissions : td::uint32 { vep_default = 1, vep_modify = 2, vep_unsafe = 4 };
using AdnlCategory = td::int32;
struct Config {
struct Addr {
td::IPAddress addr;
bool operator<(const Addr &with) const {
return addr < with.addr;
}
};
struct AddrCats {
td::IPAddress in_addr;
std::shared_ptr proxy;
std::set cats;
std::set priority_cats;
};
struct Validator {
std::map temp_keys;
std::map adnl_ids;
ton::UnixTime election_date;
ton::UnixTime expire_at;
};
struct Control {
ton::PublicKeyHash key;
std::map clients;
};
std::map keys_refcnt;
td::uint16 out_port;
std::map addrs;
std::map adnl_ids;
std::set dht_ids;
std::map validators;
ton::PublicKeyHash full_node;
std::map liteservers;
std::map controls;
std::set gc;
void decref(ton::PublicKeyHash key);
void incref(ton::PublicKeyHash key) {
keys_refcnt[key]++;
}
td::Result config_add_network_addr(td::IPAddress in_addr, td::IPAddress out_addr,
std::shared_ptr proxy, std::vector cats,
std::vector prio_cats);
td::Result config_add_adnl_addr(ton::PublicKeyHash addr, AdnlCategory cat);
td::Result config_add_dht_node(ton::PublicKeyHash id);
td::Result config_add_validator_permanent_key(ton::PublicKeyHash id, ton::UnixTime election_date,
ton::UnixTime expire_at);
td::Result config_add_validator_temp_key(ton::PublicKeyHash perm_key, ton::PublicKeyHash id,
ton::UnixTime expire_at);
td::Result config_add_validator_adnl_id(ton::PublicKeyHash perm_key, ton::PublicKeyHash adnl_id,
ton::UnixTime expire_at);
td::Result config_add_full_node_adnl_id(ton::PublicKeyHash id);
td::Result config_add_lite_server(ton::PublicKeyHash key, td::int32 port);
td::Result config_add_control_interface(ton::PublicKeyHash key, td::int32 port);
td::Result config_add_control_process(ton::PublicKeyHash key, td::int32 port, ton::PublicKeyHash id,
td::uint32 permissions);
td::Result config_add_gc(ton::PublicKeyHash key);
td::Result config_del_network_addr(td::IPAddress addr, std::vector cats,
std::vector prio_cats);
td::Result config_del_adnl_addr(ton::PublicKeyHash addr);
td::Result config_del_dht_node(ton::PublicKeyHash id);
td::Result config_del_validator_permanent_key(ton::PublicKeyHash id);
td::Result config_del_validator_temp_key(ton::PublicKeyHash perm_id, ton::PublicKeyHash id);
td::Result config_del_validator_adnl_id(ton::PublicKeyHash perm_id, ton::PublicKeyHash adnl_id);
td::Result config_del_full_node_adnl_id();
td::Result config_del_lite_server(td::int32 port);
td::Result config_del_control_interface(td::int32 port);
td::Result config_del_control_process(td::int32 port, ton::PublicKeyHash id);
td::Result config_del_gc(ton::PublicKeyHash key);
ton::tl_object_ptr tl() const;
Config();
Config(ton::ton_api::engine_validator_config &config);
};
class ValidatorEngine : public td::actor::Actor {
private:
td::actor::ActorOwn keyring_;
td::actor::ActorOwn adnl_network_manager_;
td::actor::ActorOwn adnl_;
td::actor::ActorOwn rldp_;
std::map> dht_nodes_;
ton::PublicKeyHash default_dht_node_ = ton::PublicKeyHash::zero();
td::actor::ActorOwn overlay_manager_;
td::actor::ActorOwn validator_manager_;
td::actor::ActorOwn full_node_;
td::actor::ActorOwn control_ext_server_;
std::string local_config_ = "";
std::string global_config_ = "ton-global.config";
std::string config_file_;
std::string fift_dir_ = "";
std::string db_root_ = "/var/ton-work/db/";
std::vector addrs_;
std::vector proxy_addrs_;
ton::adnl::AdnlNodesList adnl_static_nodes_;
std::shared_ptr dht_config_;
td::Ref validator_options_;
Config config_;
std::set running_gc_;
std::map keys_;
td::Ref state_;
td::Promise get_key_promise(td::MultiPromise::InitGuard &ig);
void got_key(ton::PublicKey key);
void deleted_key(ton::PublicKeyHash key);
void got_state(td::Ref state) {
state_ = std::move(state);
}
void write_config(td::Promise promise);
std::map addr_lists_;
std::map prio_addr_lists_;
struct CI_key {
ton::PublicKeyHash id;
td::uint16 port;
ton::PublicKeyHash pub;
bool operator<(const CI_key &with) const {
return id < with.id || (id == with.id && port < with.port) ||
(id == with.id && port == with.port && pub < with.pub);
}
};
std::map control_permissions_;
td::Clocks::Duration state_ttl_ = 0;
td::Clocks::Duration block_ttl_ = 0;
td::Clocks::Duration sync_ttl_ = 0;
bool read_config_ = false;
bool started_keyring_ = false;
bool started_ = false;
public:
static constexpr td::uint32 max_cat() {
return 256;
}
void set_local_config(std::string str);
void set_global_config(std::string str);
void set_fift_dir(std::string str) {
fift_dir_ = str;
}
void set_db_root(std::string db_root);
void set_state_ttl(td::Clocks::Duration t) {
state_ttl_ = t;
}
void set_block_ttl(td::Clocks::Duration t) {
block_ttl_ = t;
}
void set_sync_ttl(td::Clocks::Duration t) {
sync_ttl_ = t;
}
void add_ip(td::IPAddress addr) {
addrs_.push_back(addr);
}
void add_key_to_set(ton::PublicKey key) {
keys_[key.compute_short_id()] = key;
}
void start_up() override;
void got_result();
ValidatorEngine() {
}
// load config
td::Status load_global_config();
void load_empty_local_config(td::Promise promise);
void load_local_config(td::Promise promise);
void load_config(td::Promise promise);
void start();
void start_adnl();
void add_addr(const Config::Addr &addr, const Config::AddrCats &cats);
void add_adnl(ton::PublicKeyHash id, AdnlCategory cat);
void started_adnl();
void start_dht();
void add_dht(ton::PublicKeyHash id);
void started_dht();
void start_rldp();
void started_rldp();
void start_overlays();
void started_overlays();
void start_validator();
void started_validator();
void start_full_node();
void started_full_node();
void add_lite_server(ton::PublicKeyHash id, td::uint16 port);
void start_lite_server();
void started_lite_server();
void add_control_interface(ton::PublicKeyHash id, td::uint16 port);
void add_control_process(ton::PublicKeyHash id, td::uint16 port, ton::PublicKeyHash pub, td::int32 permissions);
void start_control_interface();
void started_control_interface(td::actor::ActorOwn control_ext_server);
void started();
void alarm() override;
void run();
void try_add_adnl_node(ton::PublicKeyHash pub, td::int32 cat, td::Promise promise);
void try_add_dht_node(ton::PublicKeyHash pub, td::Promise promise);
void try_add_validator_permanent_key(ton::PublicKeyHash key_hash, td::uint32 election_date, td::uint32 ttl,
td::Promise promise);
void try_add_validator_temp_key(ton::PublicKeyHash perm_key, ton::PublicKeyHash temp_key, td::uint32 ttl,
td::Promise promise);
void try_add_validator_adnl_addr(ton::PublicKeyHash perm_key, ton::PublicKeyHash adnl_id, td::uint32 ttl,
td::Promise promise);
void try_add_full_node_adnl_addr(ton::PublicKeyHash id, td::Promise promise);
void try_add_liteserver(ton::PublicKeyHash id, td::int32 port, td::Promise promise);
void try_add_control_interface(ton::PublicKeyHash id, td::int32 port, td::Promise promise);
void try_add_control_process(ton::PublicKeyHash id, td::int32 port, ton::PublicKeyHash pub, td::int32 permissions,
td::Promise promise);
void try_del_adnl_node(ton::PublicKeyHash pub, td::Promise promise);
void try_del_dht_node(ton::PublicKeyHash pub, td::Promise promise);
void try_del_validator_permanent_key(ton::PublicKeyHash pub, td::Promise promise);
void try_del_validator_temp_key(ton::PublicKeyHash perm, ton::PublicKeyHash temp_key, td::Promise promise);
void try_del_validator_adnl_addr(ton::PublicKeyHash perm, ton::PublicKeyHash adnl_id, td::Promise promise);
void reload_adnl_addrs();
void try_add_listening_port(td::uint32 ip, td::int32 port, std::vector cats,
std::vector prio_cats, td::Promise promise);
void try_del_listening_port(td::uint32 ip, td::int32 port, std::vector cats,
std::vector prio_cats, td::Promise promise);
void try_add_proxy(td::uint32 in_ip, td::int32 in_port, td::uint32 out_ip, td::int32 out_port,
std::shared_ptr proxy, std::vector cats,
std::vector prio_cats, td::Promise promise);
void try_del_proxy(td::uint32 ip, td::int32 port, std::vector cats, std::vector prio_cats,
td::Promise promise);
void check_key(ton::PublicKeyHash id, td::Promise promise);
static td::BufferSlice create_control_query_error(td::Status error);
void run_control_query(ton::ton_api::engine_validator_getTime &query, td::BufferSlice data, ton::PublicKeyHash src,
td::uint32 perm, td::Promise promise);
void run_control_query(ton::ton_api::engine_validator_importPrivateKey &query, td::BufferSlice data,
ton::PublicKeyHash src, td::uint32 perm, td::Promise promise);
void run_control_query(ton::ton_api::engine_validator_exportPrivateKey &query, td::BufferSlice data,
ton::PublicKeyHash src, td::uint32 perm, td::Promise promise);
void run_control_query(ton::ton_api::engine_validator_exportPublicKey &query, td::BufferSlice data,
ton::PublicKeyHash src, td::uint32 perm, td::Promise promise);
void run_control_query(ton::ton_api::engine_validator_generateKeyPair &query, td::BufferSlice data,
ton::PublicKeyHash src, td::uint32 perm, td::Promise promise);
void run_control_query(ton::ton_api::engine_validator_addAdnlId &query, td::BufferSlice data, ton::PublicKeyHash src,
td::uint32 perm, td::Promise promise);
void run_control_query(ton::ton_api::engine_validator_addDhtId &query, td::BufferSlice data, ton::PublicKeyHash src,
td::uint32 perm, td::Promise promise);
void run_control_query(ton::ton_api::engine_validator_addValidatorPermanentKey &query, td::BufferSlice data,
ton::PublicKeyHash src, td::uint32 perm, td::Promise promise);
void run_control_query(ton::ton_api::engine_validator_addValidatorTempKey &query, td::BufferSlice data,
ton::PublicKeyHash src, td::uint32 perm, td::Promise promise);
void run_control_query(ton::ton_api::engine_validator_addValidatorAdnlAddress &query, td::BufferSlice data,
ton::PublicKeyHash src, td::uint32 perm, td::Promise promise);
void run_control_query(ton::ton_api::engine_validator_changeFullNodeAdnlAddress &query, td::BufferSlice data,
ton::PublicKeyHash src, td::uint32 perm, td::Promise promise);
void run_control_query(ton::ton_api::engine_validator_addLiteserver &query, td::BufferSlice data,
ton::PublicKeyHash src, td::uint32 perm, td::Promise promise);
void run_control_query(ton::ton_api::engine_validator_addControlInterface &query, td::BufferSlice data,
ton::PublicKeyHash src, td::uint32 perm, td::Promise promise);
void run_control_query(ton::ton_api::engine_validator_delAdnlId &query, td::BufferSlice data, ton::PublicKeyHash src,
td::uint32 perm, td::Promise promise);
void run_control_query(ton::ton_api::engine_validator_delDhtId &query, td::BufferSlice data, ton::PublicKeyHash src,
td::uint32 perm, td::Promise promise);
void run_control_query(ton::ton_api::engine_validator_delValidatorPermanentKey &query, td::BufferSlice data,
ton::PublicKeyHash src, td::uint32 perm, td::Promise promise);
void run_control_query(ton::ton_api::engine_validator_delValidatorTempKey &query, td::BufferSlice data,
ton::PublicKeyHash src, td::uint32 perm, td::Promise promise);
void run_control_query(ton::ton_api::engine_validator_delValidatorAdnlAddress &query, td::BufferSlice data,
ton::PublicKeyHash src, td::uint32 perm, td::Promise promise);
void run_control_query(ton::ton_api::engine_validator_addListeningPort &query, td::BufferSlice data,
ton::PublicKeyHash src, td::uint32 perm, td::Promise promise);
void run_control_query(ton::ton_api::engine_validator_delListeningPort &query, td::BufferSlice data,
ton::PublicKeyHash src, td::uint32 perm, td::Promise promise);
void run_control_query(ton::ton_api::engine_validator_addProxy &query, td::BufferSlice data, ton::PublicKeyHash src,
td::uint32 perm, td::Promise promise);
void run_control_query(ton::ton_api::engine_validator_delProxy &query, td::BufferSlice data, ton::PublicKeyHash src,
td::uint32 perm, td::Promise promise);
void run_control_query(ton::ton_api::engine_validator_getConfig &query, td::BufferSlice data, ton::PublicKeyHash src,
td::uint32 perm, td::Promise promise);
void run_control_query(ton::ton_api::engine_validator_sign &query, td::BufferSlice data, ton::PublicKeyHash src,
td::uint32 perm, td::Promise promise);
void run_control_query(ton::ton_api::engine_validator_setVerbosity &query, td::BufferSlice data,
ton::PublicKeyHash src, td::uint32 perm, td::Promise promise);
void run_control_query(ton::ton_api::engine_validator_getStats &query, td::BufferSlice data, ton::PublicKeyHash src,
td::uint32 perm, td::Promise promise);
void run_control_query(ton::ton_api::engine_validator_createElectionBid &query, td::BufferSlice data,
ton::PublicKeyHash src, td::uint32 perm, td::Promise promise);
template
void run_control_query(T &query, td::BufferSlice data, ton::PublicKeyHash src, td::uint32 perm,
td::Promise promise) {
promise.set_value(
create_control_query_error(td::Status::Error(ton::ErrorCode::protoviolation, "query not supported")));
}
void process_control_query(td::uint16 port, ton::adnl::AdnlNodeIdShort src, ton::adnl::AdnlNodeIdShort dst,
td::BufferSlice data, td::Promise promise);
};