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

initial commit

This commit is contained in:
initial commit 2019-09-07 14:03:22 +04:00 committed by vvaltman
commit c2da007f40
1610 changed files with 398047 additions and 0 deletions

View file

@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)
add_executable (validator-engine-console validator-engine-console.cpp
validator-engine-console.h validator-engine-console-query.cpp
validator-engine-console-query.h )
target_link_libraries(validator-engine-console tdutils tdactor adnllite tl_api tl_lite_api tl-lite-utils ton_crypto ton_block terminal)

View file

@ -0,0 +1,657 @@
/*
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 <http://www.gnu.org/licenses/>.
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
*/
#include "validator-engine-console-query.h"
#include "validator-engine-console.h"
#include "terminal/terminal.h"
#include "td/utils/filesystem.h"
#include <cctype>
Tokenizer::Tokenizer(td::BufferSlice data) : data_(std::move(data)) {
remaining_ = data_.as_slice();
}
void Tokenizer::skipspc() {
while (remaining_.size() > 0 && std::isspace(remaining_[0])) {
remaining_.remove_prefix(1);
}
}
bool Tokenizer::endl() {
skipspc();
return remaining_.size() == 0;
}
td::Result<td::Slice> Tokenizer::get_raw_token() {
skipspc();
if (remaining_.size() == 0) {
return td::Status::Error("failed to parse token: EOL");
}
size_t idx = 0;
while (idx < remaining_.size() && !std::isspace(remaining_[idx])) {
idx++;
}
auto r = remaining_.copy().truncate(idx);
remaining_.remove_prefix(idx);
return r;
}
td::Result<td::Slice> Tokenizer::peek_raw_token() {
skipspc();
if (remaining_.size() == 0) {
return td::Status::Error("failed to parse token: EOL");
}
size_t idx = 0;
while (idx < remaining_.size() && !std::isspace(remaining_[idx])) {
idx++;
}
auto r = remaining_.copy().truncate(idx);
return r;
}
void Query::start_up() {
auto R = [&]() -> td::Status {
TRY_STATUS(run());
TRY_STATUS(send());
return td::Status::OK();
}();
if (R.is_error()) {
handle_error(std::move(R));
}
}
void Query::handle_error(td::Status error) {
td::TerminalIO::out() << "Failed " << name() << " query: " << error << "\n";
stop();
}
void Query::receive_wrap(td::BufferSlice R) {
auto S = receive(std::move(R));
if (S.is_error()) {
handle_error(std::move(S));
} else {
td::actor::send_closure(console_, &ValidatorEngineConsole::got_result);
stop();
}
}
td::Status GetTimeQuery::run() {
TRY_STATUS(tokenizer_.check_endl());
return td::Status::OK();
}
td::Status GetTimeQuery::send() {
auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_getTime>();
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
return td::Status::OK();
}
td::Status GetTimeQuery::receive(td::BufferSlice data) {
TRY_RESULT_PREFIX(f, ton::fetch_tl_object<ton::ton_api::engine_validator_time>(std::move(data), true),
"received incorrect answer: ");
td::TerminalIO::out() << "received validator time: time=" << f->time_ << "\n";
return td::Status::OK();
}
td::Status GetHelpQuery::run() {
if (tokenizer_.endl()) {
return td::Status::OK();
}
TRY_RESULT_ASSIGN(command_, tokenizer_.get_token<std::string>());
TRY_STATUS(tokenizer_.check_endl());
return td::Status::OK();
}
td::Status GetHelpQuery::send() {
td::actor::send_closure(console_, &ValidatorEngineConsole::show_help, command_, create_promise());
return td::Status::OK();
}
td::Status GetHelpQuery::receive(td::BufferSlice R) {
CHECK(R.size() == 0);
return td::Status::OK();
}
td::Status GetLicenseQuery::run() {
TRY_STATUS(tokenizer_.check_endl());
return td::Status::OK();
}
td::Status GetLicenseQuery::send() {
td::actor::send_closure(console_, &ValidatorEngineConsole::show_license, create_promise());
return td::Status::OK();
}
td::Status GetLicenseQuery::receive(td::BufferSlice R) {
CHECK(R.size() == 0);
return td::Status::OK();
}
td::Status NewKeyQuery::run() {
TRY_STATUS(tokenizer_.check_endl());
return td::Status::OK();
}
td::Status NewKeyQuery::send() {
auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_generateKeyPair>();
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
return td::Status::OK();
}
td::Status NewKeyQuery::receive(td::BufferSlice data) {
TRY_RESULT_PREFIX(f, ton::fetch_tl_object<ton::ton_api::engine_validator_keyHash>(std::move(data), true),
"received incorrect answer: ");
td::TerminalIO::out() << "created new key " << f->key_hash_.to_hex() << "\n";
return td::Status::OK();
}
td::Status ImportPrivateKeyFileQuery::run() {
TRY_RESULT_ASSIGN(file_name_, tokenizer_.get_token<std::string>());
TRY_STATUS(tokenizer_.check_endl());
return td::Status::OK();
}
td::Status ImportPrivateKeyFileQuery::send() {
TRY_RESULT(data, td::read_file_secure(file_name_));
TRY_RESULT(pk, ton::PrivateKey::import(data.as_slice()));
auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_importPrivateKey>(pk.tl());
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
return td::Status::OK();
}
td::Status ImportPrivateKeyFileQuery::receive(td::BufferSlice data) {
TRY_RESULT_PREFIX(f, ton::fetch_tl_object<ton::ton_api::engine_validator_keyHash>(std::move(data), true),
"received incorrect answer: ");
td::TerminalIO::out() << "imported key " << f->key_hash_.to_hex() << "\n";
return td::Status::OK();
}
td::Status ExportPublicKeyQuery::run() {
TRY_RESULT_ASSIGN(key_hash_, tokenizer_.get_token<ton::PublicKeyHash>());
TRY_STATUS(tokenizer_.check_endl());
return td::Status::OK();
}
td::Status ExportPublicKeyQuery::send() {
auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_exportPublicKey>(key_hash_.tl());
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
return td::Status::OK();
}
td::Status ExportPublicKeyQuery::receive(td::BufferSlice data) {
TRY_RESULT_PREFIX(f, ton::fetch_tl_object<ton::ton_api::PublicKey>(data.as_slice(), true),
"received incorrect answer: ");
td::TerminalIO::out() << "got public key: " << td::base64_encode(data.as_slice()) << "\n";
return td::Status::OK();
}
td::Status ExportPublicKeyFileQuery::run() {
TRY_RESULT_ASSIGN(key_hash_, tokenizer_.get_token<ton::PublicKeyHash>());
TRY_RESULT_ASSIGN(file_name_, tokenizer_.get_token<std::string>());
TRY_STATUS(tokenizer_.check_endl());
return td::Status::OK();
}
td::Status ExportPublicKeyFileQuery::send() {
auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_exportPublicKey>(key_hash_.tl());
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
return td::Status::OK();
}
td::Status ExportPublicKeyFileQuery::receive(td::BufferSlice data) {
TRY_RESULT_PREFIX(f, ton::fetch_tl_object<ton::ton_api::PublicKey>(data.as_slice(), true),
"received incorrect answer: ");
TRY_STATUS(td::write_file(file_name_, data.as_slice()));
td::TerminalIO::out() << "got public key\n";
return td::Status::OK();
}
td::Status SignQuery::run() {
TRY_RESULT_ASSIGN(key_hash_, tokenizer_.get_token<ton::PublicKeyHash>());
TRY_RESULT_ASSIGN(data_, tokenizer_.get_token<td::BufferSlice>());
TRY_STATUS(tokenizer_.check_endl());
return td::Status::OK();
}
td::Status SignQuery::send() {
auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_sign>(key_hash_.tl(), std::move(data_));
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
return td::Status::OK();
}
td::Status SignQuery::receive(td::BufferSlice data) {
TRY_RESULT_PREFIX(f, ton::fetch_tl_object<ton::ton_api::engine_validator_signature>(data.as_slice(), true),
"received incorrect answer: ");
td::TerminalIO::out() << "got signature " << td::base64_encode(f->signature_) << "\n";
return td::Status::OK();
}
td::Status SignFileQuery::run() {
TRY_RESULT_ASSIGN(key_hash_, tokenizer_.get_token<ton::PublicKeyHash>());
TRY_RESULT_ASSIGN(in_file_, tokenizer_.get_token<std::string>());
TRY_RESULT_ASSIGN(out_file_, tokenizer_.get_token<std::string>());
TRY_STATUS(tokenizer_.check_endl());
return td::Status::OK();
}
td::Status SignFileQuery::send() {
TRY_RESULT(data, td::read_file(in_file_));
auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_sign>(key_hash_.tl(), std::move(data));
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
return td::Status::OK();
}
td::Status SignFileQuery::receive(td::BufferSlice data) {
TRY_RESULT_PREFIX(f, ton::fetch_tl_object<ton::ton_api::engine_validator_signature>(data.as_slice(), true),
"received incorrect answer: ");
TRY_STATUS(td::write_file(out_file_, f->signature_.as_slice()));
td::TerminalIO::out() << "got signature\n";
return td::Status::OK();
}
td::Status AddAdnlAddrQuery::run() {
TRY_RESULT_ASSIGN(key_hash_, tokenizer_.get_token<ton::PublicKeyHash>());
TRY_RESULT_ASSIGN(category_, tokenizer_.get_token<td::uint32>());
if (category_ > 15) {
return td::Status::Error("too big category");
}
TRY_STATUS(tokenizer_.check_endl());
return td::Status::OK();
}
td::Status AddAdnlAddrQuery::send() {
auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_addAdnlId>(key_hash_.tl(), category_);
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
return td::Status::OK();
}
td::Status AddAdnlAddrQuery::receive(td::BufferSlice data) {
TRY_RESULT_PREFIX(f, ton::fetch_tl_object<ton::ton_api::engine_validator_success>(data.as_slice(), true),
"received incorrect answer: ");
td::TerminalIO::out() << "success\n";
return td::Status::OK();
}
td::Status AddDhtIdQuery::run() {
TRY_RESULT_ASSIGN(key_hash_, tokenizer_.get_token<ton::PublicKeyHash>());
TRY_STATUS(tokenizer_.check_endl());
return td::Status::OK();
}
td::Status AddDhtIdQuery::send() {
auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_addDhtId>(key_hash_.tl());
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
return td::Status::OK();
}
td::Status AddDhtIdQuery::receive(td::BufferSlice data) {
TRY_RESULT_PREFIX(f, ton::fetch_tl_object<ton::ton_api::engine_validator_success>(data.as_slice(), true),
"received incorrect answer: ");
td::TerminalIO::out() << "success\n";
return td::Status::OK();
}
td::Status AddValidatorPermanentKeyQuery::run() {
TRY_RESULT_ASSIGN(key_hash_, tokenizer_.get_token<ton::PublicKeyHash>());
TRY_RESULT_ASSIGN(election_date_, tokenizer_.get_token<td::uint32>());
TRY_RESULT_ASSIGN(expire_at_, tokenizer_.get_token<td::uint32>());
TRY_STATUS(tokenizer_.check_endl());
return td::Status::OK();
}
td::Status AddValidatorPermanentKeyQuery::send() {
auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_addValidatorPermanentKey>(
key_hash_.tl(), election_date_, expire_at_);
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
return td::Status::OK();
}
td::Status AddValidatorPermanentKeyQuery::receive(td::BufferSlice data) {
TRY_RESULT_PREFIX(f, ton::fetch_tl_object<ton::ton_api::engine_validator_success>(data.as_slice(), true),
"received incorrect answer: ");
td::TerminalIO::out() << "success\n";
return td::Status::OK();
}
td::Status AddValidatorTempKeyQuery::run() {
TRY_RESULT_ASSIGN(perm_key_hash_, tokenizer_.get_token<ton::PublicKeyHash>());
TRY_RESULT_ASSIGN(key_hash_, tokenizer_.get_token<ton::PublicKeyHash>());
TRY_RESULT_ASSIGN(expire_at_, tokenizer_.get_token<td::uint32>());
TRY_STATUS(tokenizer_.check_endl());
return td::Status::OK();
}
td::Status AddValidatorTempKeyQuery::send() {
auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_addValidatorTempKey>(
perm_key_hash_.tl(), key_hash_.tl(), expire_at_);
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
return td::Status::OK();
}
td::Status AddValidatorTempKeyQuery::receive(td::BufferSlice data) {
TRY_RESULT_PREFIX(f, ton::fetch_tl_object<ton::ton_api::engine_validator_success>(data.as_slice(), true),
"received incorrect answer: ");
td::TerminalIO::out() << "success\n";
return td::Status::OK();
}
td::Status ChangeFullNodeAdnlAddrQuery::run() {
TRY_RESULT_ASSIGN(key_hash_, tokenizer_.get_token<ton::PublicKeyHash>());
TRY_STATUS(tokenizer_.check_endl());
return td::Status::OK();
}
td::Status ChangeFullNodeAdnlAddrQuery::send() {
auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_changeFullNodeAdnlAddress>(key_hash_.tl());
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
return td::Status::OK();
}
td::Status ChangeFullNodeAdnlAddrQuery::receive(td::BufferSlice data) {
TRY_RESULT_PREFIX(f, ton::fetch_tl_object<ton::ton_api::engine_validator_success>(data.as_slice(), true),
"received incorrect answer: ");
td::TerminalIO::out() << "success\n";
return td::Status::OK();
}
td::Status AddValidatorAdnlAddrQuery::run() {
TRY_RESULT_ASSIGN(perm_key_hash_, tokenizer_.get_token<ton::PublicKeyHash>());
TRY_RESULT_ASSIGN(key_hash_, tokenizer_.get_token<ton::PublicKeyHash>());
TRY_RESULT_ASSIGN(expire_at_, tokenizer_.get_token<td::uint32>());
TRY_STATUS(tokenizer_.check_endl());
return td::Status::OK();
}
td::Status AddValidatorAdnlAddrQuery::send() {
auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_addValidatorAdnlAddress>(
perm_key_hash_.tl(), key_hash_.tl(), expire_at_);
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
return td::Status::OK();
}
td::Status AddValidatorAdnlAddrQuery::receive(td::BufferSlice data) {
TRY_RESULT_PREFIX(f, ton::fetch_tl_object<ton::ton_api::engine_validator_success>(data.as_slice(), true),
"received incorrect answer: ");
td::TerminalIO::out() << "success\n";
return td::Status::OK();
}
td::Status AddLiteServerQuery::run() {
TRY_RESULT_ASSIGN(port_, tokenizer_.get_token<td::uint16>());
TRY_RESULT_ASSIGN(key_hash_, tokenizer_.get_token<ton::PublicKeyHash>());
TRY_STATUS(tokenizer_.check_endl());
return td::Status::OK();
}
td::Status AddLiteServerQuery::send() {
auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_addLiteserver>(key_hash_.tl(), port_);
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
return td::Status::OK();
}
td::Status AddLiteServerQuery::receive(td::BufferSlice data) {
TRY_RESULT_PREFIX(f, ton::fetch_tl_object<ton::ton_api::engine_validator_success>(data.as_slice(), true),
"received incorrect answer: ");
td::TerminalIO::out() << "success\n";
return td::Status::OK();
}
td::Status DelAdnlAddrQuery::run() {
TRY_RESULT_ASSIGN(key_hash_, tokenizer_.get_token<ton::PublicKeyHash>());
TRY_STATUS(tokenizer_.check_endl());
return td::Status::OK();
}
td::Status DelAdnlAddrQuery::send() {
auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_delAdnlId>(key_hash_.tl());
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
return td::Status::OK();
}
td::Status DelAdnlAddrQuery::receive(td::BufferSlice data) {
TRY_RESULT_PREFIX(f, ton::fetch_tl_object<ton::ton_api::engine_validator_success>(data.as_slice(), true),
"received incorrect answer: ");
td::TerminalIO::out() << "success\n";
return td::Status::OK();
}
td::Status DelDhtIdQuery::run() {
TRY_RESULT_ASSIGN(key_hash_, tokenizer_.get_token<ton::PublicKeyHash>());
TRY_STATUS(tokenizer_.check_endl());
return td::Status::OK();
}
td::Status DelDhtIdQuery::send() {
auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_delDhtId>(key_hash_.tl());
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
return td::Status::OK();
}
td::Status DelDhtIdQuery::receive(td::BufferSlice data) {
TRY_RESULT_PREFIX(f, ton::fetch_tl_object<ton::ton_api::engine_validator_success>(data.as_slice(), true),
"received incorrect answer: ");
td::TerminalIO::out() << "success\n";
return td::Status::OK();
}
td::Status DelValidatorPermanentKeyQuery::run() {
TRY_RESULT_ASSIGN(key_hash_, tokenizer_.get_token<ton::PublicKeyHash>());
TRY_STATUS(tokenizer_.check_endl());
return td::Status::OK();
}
td::Status DelValidatorPermanentKeyQuery::send() {
auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_delValidatorPermanentKey>(key_hash_.tl());
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
return td::Status::OK();
}
td::Status DelValidatorPermanentKeyQuery::receive(td::BufferSlice data) {
TRY_RESULT_PREFIX(f, ton::fetch_tl_object<ton::ton_api::engine_validator_success>(data.as_slice(), true),
"received incorrect answer: ");
td::TerminalIO::out() << "success\n";
return td::Status::OK();
}
td::Status DelValidatorTempKeyQuery::run() {
TRY_RESULT_ASSIGN(perm_key_hash_, tokenizer_.get_token<ton::PublicKeyHash>());
TRY_RESULT_ASSIGN(key_hash_, tokenizer_.get_token<ton::PublicKeyHash>());
TRY_STATUS(tokenizer_.check_endl());
return td::Status::OK();
}
td::Status DelValidatorTempKeyQuery::send() {
auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_delValidatorTempKey>(perm_key_hash_.tl(),
key_hash_.tl());
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
return td::Status::OK();
}
td::Status DelValidatorTempKeyQuery::receive(td::BufferSlice data) {
TRY_RESULT_PREFIX(f, ton::fetch_tl_object<ton::ton_api::engine_validator_success>(data.as_slice(), true),
"received incorrect answer: ");
td::TerminalIO::out() << "success\n";
return td::Status::OK();
}
td::Status DelValidatorAdnlAddrQuery::run() {
TRY_RESULT_ASSIGN(perm_key_hash_, tokenizer_.get_token<ton::PublicKeyHash>());
TRY_RESULT_ASSIGN(key_hash_, tokenizer_.get_token<ton::PublicKeyHash>());
TRY_STATUS(tokenizer_.check_endl());
return td::Status::OK();
}
td::Status DelValidatorAdnlAddrQuery::send() {
auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_delValidatorAdnlAddress>(perm_key_hash_.tl(),
key_hash_.tl());
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
return td::Status::OK();
}
td::Status DelValidatorAdnlAddrQuery::receive(td::BufferSlice data) {
TRY_RESULT_PREFIX(f, ton::fetch_tl_object<ton::ton_api::engine_validator_success>(data.as_slice(), true),
"received incorrect answer: ");
td::TerminalIO::out() << "success\n";
return td::Status::OK();
}
td::Status GetConfigQuery::run() {
TRY_STATUS(tokenizer_.check_endl());
return td::Status::OK();
}
td::Status GetConfigQuery::send() {
auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_getConfig>();
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
return td::Status::OK();
}
td::Status GetConfigQuery::receive(td::BufferSlice data) {
TRY_RESULT_PREFIX(f, ton::fetch_tl_object<ton::ton_api::engine_validator_jsonConfig>(data.as_slice(), true),
"received incorrect answer: ");
td::TerminalIO::out() << "---------\n" << f->data_ << "--------\n";
return td::Status::OK();
}
td::Status SetVerbosityQuery::run() {
TRY_RESULT_ASSIGN(verbosity_, tokenizer_.get_token<td::uint8>());
TRY_STATUS(tokenizer_.check_endl());
return td::Status::OK();
}
td::Status SetVerbosityQuery::send() {
auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_setVerbosity>(verbosity_);
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
return td::Status::OK();
}
td::Status SetVerbosityQuery::receive(td::BufferSlice data) {
TRY_RESULT_PREFIX(f, ton::fetch_tl_object<ton::ton_api::engine_validator_success>(data.as_slice(), true),
"received incorrect answer: ");
td::TerminalIO::out() << "success\n";
return td::Status::OK();
}
td::Status GetStatsQuery::run() {
TRY_STATUS(tokenizer_.check_endl());
return td::Status::OK();
}
td::Status GetStatsQuery::send() {
auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_getStats>();
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
return td::Status::OK();
}
td::Status GetStatsQuery::receive(td::BufferSlice data) {
TRY_RESULT_PREFIX(f, ton::fetch_tl_object<ton::ton_api::engine_validator_stats>(data.as_slice(), true),
"received incorrect answer: ");
for (auto &v : f->stats_) {
td::TerminalIO::out() << v->key_ << "\t\t\t" << v->value_ << "\n";
}
return td::Status::OK();
}
td::Status QuitQuery::send() {
td::actor::send_closure(console_, &ValidatorEngineConsole::close);
return td::Status::OK();
}
td::Status AddNetworkAddressQuery::run() {
TRY_RESULT_ASSIGN(addr_, tokenizer_.get_token<td::IPAddress>());
TRY_RESULT_ASSIGN(cats_, tokenizer_.get_token_vector<td::int32>());
TRY_RESULT_ASSIGN(prio_cats_, tokenizer_.get_token_vector<td::int32>());
TRY_STATUS(tokenizer_.check_endl());
return td::Status::OK();
}
td::Status AddNetworkAddressQuery::send() {
auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_addListeningPort>(
static_cast<td::int32>(addr_.get_ipv4()), addr_.get_port(), std::move(cats_), std::move(prio_cats_));
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
return td::Status::OK();
}
td::Status AddNetworkAddressQuery::receive(td::BufferSlice data) {
TRY_RESULT_PREFIX(f, ton::fetch_tl_object<ton::ton_api::engine_validator_success>(data.as_slice(), true),
"received incorrect answer: ");
td::TerminalIO::out() << "success\n";
return td::Status::OK();
}
td::Status AddNetworkProxyAddressQuery::run() {
TRY_RESULT_ASSIGN(in_addr_, tokenizer_.get_token<td::IPAddress>());
TRY_RESULT_ASSIGN(out_addr_, tokenizer_.get_token<td::IPAddress>());
TRY_RESULT_ASSIGN(shared_secret_, tokenizer_.get_token<td::BufferSlice>());
TRY_RESULT_ASSIGN(cats_, tokenizer_.get_token_vector<td::int32>());
TRY_RESULT_ASSIGN(prio_cats_, tokenizer_.get_token_vector<td::int32>());
TRY_STATUS(tokenizer_.check_endl());
return td::Status::OK();
}
td::Status AddNetworkProxyAddressQuery::send() {
auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_addProxy>(
static_cast<td::int32>(in_addr_.get_ipv4()), in_addr_.get_port(), static_cast<td::int32>(out_addr_.get_ipv4()),
out_addr_.get_port(), ton::create_tl_object<ton::ton_api::adnl_proxy_fast>(std::move(shared_secret_)),
std::move(cats_), std::move(prio_cats_));
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
return td::Status::OK();
}
td::Status AddNetworkProxyAddressQuery::receive(td::BufferSlice data) {
TRY_RESULT_PREFIX(f, ton::fetch_tl_object<ton::ton_api::engine_validator_success>(data.as_slice(), true),
"received incorrect answer: ");
td::TerminalIO::out() << "success\n";
return td::Status::OK();
}
td::Status CreateElectionBidQuery::run() {
TRY_RESULT_ASSIGN(date_, tokenizer_.get_token<td::uint32>());
TRY_RESULT_ASSIGN(elector_addr_, tokenizer_.get_token<std::string>());
TRY_RESULT_ASSIGN(wallet_, tokenizer_.get_token<std::string>());
TRY_RESULT_ASSIGN(fname_, tokenizer_.get_token<std::string>());
TRY_STATUS(tokenizer_.check_endl());
return td::Status::OK();
}
td::Status CreateElectionBidQuery::send() {
auto b =
ton::create_serialize_tl_object<ton::ton_api::engine_validator_createElectionBid>(date_, elector_addr_, wallet_);
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
return td::Status::OK();
}
td::Status CreateElectionBidQuery::receive(td::BufferSlice data) {
TRY_RESULT_PREFIX(f, ton::fetch_tl_object<ton::ton_api::engine_validator_electionBid>(data.as_slice(), true),
"received incorrect answer: ");
td::TerminalIO::out() << "success: permkey=" << f->perm_key_.to_hex() << " adnl=" << f->adnl_addr_.to_hex() << "\n";
TRY_STATUS(td::write_file(fname_, f->to_send_payload_.as_slice()));
return td::Status::OK();
}

View file

@ -0,0 +1,823 @@
/*
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 <http://www.gnu.org/licenses/>.
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 "td/utils/Status.h"
#include "td/utils/buffer.h"
#include "td/utils/misc.h"
#include "td/utils/SharedSlice.h"
#include "td/utils/port/IPAddress.h"
#include "td/actor/actor.h"
#include "keys/keys.hpp"
class ValidatorEngineConsole;
class Tokenizer {
public:
Tokenizer(td::BufferSlice data);
void skipspc();
bool endl();
td::Status check_endl() {
if (!endl()) {
return td::Status::Error("extra data after query");
} else {
return td::Status::OK();
}
}
td::Result<td::Slice> get_raw_token();
td::Result<td::Slice> peek_raw_token();
template <typename T>
inline td::Result<T> get_token() {
TRY_RESULT(S, get_raw_token());
return td::to_integer_safe<T>(S);
}
template <typename T>
inline td::Result<std::vector<T>> get_token_vector();
private:
td::BufferSlice data_;
td::Slice remaining_;
};
template <>
inline td::Result<td::Slice> Tokenizer::get_token() {
return get_raw_token();
}
template <>
inline td::Result<std::string> Tokenizer::get_token() {
TRY_RESULT(S, get_raw_token());
return S.str();
}
template <>
inline td::Result<td::BufferSlice> Tokenizer::get_token() {
TRY_RESULT(S, get_raw_token());
TRY_RESULT(F, td::hex_decode(S));
return td::BufferSlice{F};
}
template <>
inline td::Result<td::SharedSlice> Tokenizer::get_token() {
TRY_RESULT(S, get_raw_token());
TRY_RESULT(F, td::hex_decode(S));
return td::SharedSlice{F};
}
template <>
inline td::Result<ton::PublicKeyHash> Tokenizer::get_token() {
TRY_RESULT(S, get_raw_token());
TRY_RESULT(F, td::hex_decode(S));
if (F.size() == 32) {
return ton::PublicKeyHash{td::Slice{F}};
} else {
return td::Status::Error("cannot parse keyhash: bad length");
}
}
template <>
inline td::Result<td::IPAddress> Tokenizer::get_token() {
TRY_RESULT(S, get_raw_token());
td::IPAddress addr;
TRY_STATUS(addr.init_host_port(S.str()));
return addr;
}
template <typename T>
inline td::Result<std::vector<T>> Tokenizer::get_token_vector() {
TRY_RESULT(word, get_token<std::string>());
if (word != "[") {
return td::Status::Error("'[' expected");
}
std::vector<T> res;
while (true) {
TRY_RESULT(w, peek_raw_token());
if (w == "]") {
get_raw_token();
return res;
}
TRY_RESULT(val, get_token<T>());
res.push_back(std::move(val));
}
}
class QueryRunner {
public:
virtual ~QueryRunner() = default;
virtual std::string name() const = 0;
virtual std::string help() const = 0;
virtual td::Status run(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer) const = 0;
};
template <class T>
class QueryRunnerImpl : public QueryRunner {
public:
std::string name() const override {
return T::get_name();
}
std::string help() const override {
return T::get_help();
}
td::Status run(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer) const override {
td::actor::create_actor<T>(PSTRING() << "query " << name(), std::move(console), std::move(tokenizer)).release();
return td::Status::OK();
}
QueryRunnerImpl() {
}
};
class Query : public td::actor::Actor {
public:
virtual ~Query() = default;
Query(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
: console_(console), tokenizer_(std::move(tokenizer)) {
}
void start_up() override;
virtual td::Status run() = 0;
virtual td::Status send() = 0;
void receive_wrap(td::BufferSlice R);
virtual td::Status receive(td::BufferSlice R) = 0;
auto create_promise() {
return td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::BufferSlice> R) {
if (R.is_error()) {
td::actor::send_closure(SelfId, &Query::handle_error, R.move_as_error());
} else {
td::actor::send_closure(SelfId, &Query::receive_wrap, R.move_as_ok());
}
});
}
virtual std::string name() const = 0;
void handle_error(td::Status error);
protected:
td::actor::ActorId<ValidatorEngineConsole> console_;
Tokenizer tokenizer_;
};
class GetTimeQuery : public Query {
public:
GetTimeQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
: Query(console, std::move(tokenizer)) {
}
td::Status run() override;
td::Status send() override;
td::Status receive(td::BufferSlice R) override;
static std::string get_name() {
return "gettime";
}
static std::string get_help() {
return "gettime\tshows current server unixtime";
}
std::string name() const override {
return get_name();
}
private:
};
class GetHelpQuery : public Query {
public:
GetHelpQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
: Query(console, std::move(tokenizer)) {
}
td::Status run() override;
td::Status send() override;
td::Status receive(td::BufferSlice R) override;
static std::string get_name() {
return "help";
}
static std::string get_help() {
return "help [command]\tshows help";
}
std::string name() const override {
return get_name();
}
private:
std::string command_;
};
class GetLicenseQuery : public Query {
public:
GetLicenseQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
: Query(console, std::move(tokenizer)) {
}
td::Status run() override;
td::Status send() override;
td::Status receive(td::BufferSlice R) override;
static std::string get_name() {
return "license";
}
static std::string get_help() {
return "license\tshows license info";
}
std::string name() const override {
return get_name();
}
private:
std::string command_;
};
class NewKeyQuery : public Query {
public:
NewKeyQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
: Query(console, std::move(tokenizer)) {
}
td::Status run() override;
td::Status send() override;
td::Status receive(td::BufferSlice R) override;
static std::string get_name() {
return "newkey";
}
static std::string get_help() {
return "newkey\tgenerates new key pair on server";
}
std::string name() const override {
return get_name();
}
private:
};
class ImportPrivateKeyFileQuery : public Query {
public:
ImportPrivateKeyFileQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
: Query(console, std::move(tokenizer)) {
}
td::Status run() override;
td::Status send() override;
td::Status receive(td::BufferSlice R) override;
static std::string get_name() {
return "importf";
}
static std::string get_help() {
return "importf <filename>\timport private key";
}
std::string name() const override {
return get_name();
}
private:
std::string file_name_;
};
class ExportPublicKeyQuery : public Query {
public:
ExportPublicKeyQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
: Query(console, std::move(tokenizer)) {
}
td::Status run() override;
td::Status send() override;
td::Status receive(td::BufferSlice R) override;
static std::string get_name() {
return "exportpub";
}
static std::string get_help() {
return "exportpub <keyhash>\texports public key by key hash";
}
std::string name() const override {
return get_name();
}
private:
ton::PublicKeyHash key_hash_;
};
class ExportPublicKeyFileQuery : public Query {
public:
ExportPublicKeyFileQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
: Query(console, std::move(tokenizer)) {
}
td::Status run() override;
td::Status send() override;
td::Status receive(td::BufferSlice R) override;
static std::string get_name() {
return "exportpubf";
}
static std::string get_help() {
return "exportpubf <keyhash> <filename>\texports public key by key hash";
}
std::string name() const override {
return get_name();
}
private:
ton::PublicKeyHash key_hash_;
std::string file_name_;
};
class SignQuery : public Query {
public:
SignQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
: Query(console, std::move(tokenizer)) {
}
td::Status run() override;
td::Status send() override;
td::Status receive(td::BufferSlice data) override;
static std::string get_name() {
return "sign";
}
static std::string get_help() {
return "sign <keyhash> <data>\tsigns bytestring with privkey";
}
std::string name() const override {
return get_name();
}
private:
ton::PublicKeyHash key_hash_;
td::BufferSlice data_;
};
class SignFileQuery : public Query {
public:
SignFileQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
: Query(console, std::move(tokenizer)) {
}
td::Status run() override;
td::Status send() override;
td::Status receive(td::BufferSlice data) override;
static std::string get_name() {
return "signf";
}
static std::string get_help() {
return "signf <keyhash> <infile> <outfile>\tsigns bytestring with privkey";
}
std::string name() const override {
return get_name();
}
private:
ton::PublicKeyHash key_hash_;
std::string in_file_;
std::string out_file_;
};
class AddAdnlAddrQuery : public Query {
public:
AddAdnlAddrQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
: Query(console, std::move(tokenizer)) {
}
td::Status run() override;
td::Status send() override;
td::Status receive(td::BufferSlice data) override;
static std::string get_name() {
return "addadnl";
}
static std::string get_help() {
return "addadnl <keyhash> <category>\tuse key as ADNL addr";
}
std::string name() const override {
return get_name();
}
private:
ton::PublicKeyHash key_hash_;
td::uint32 category_;
};
class AddDhtIdQuery : public Query {
public:
AddDhtIdQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
: Query(console, std::move(tokenizer)) {
}
td::Status run() override;
td::Status send() override;
td::Status receive(td::BufferSlice data) override;
static std::string get_name() {
return "adddht";
}
static std::string get_help() {
return "adddht <keyhash>\tcreate DHT node with specified ADNL addr";
}
std::string name() const override {
return get_name();
}
private:
ton::PublicKeyHash key_hash_;
};
class AddValidatorPermanentKeyQuery : public Query {
public:
AddValidatorPermanentKeyQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
: Query(console, std::move(tokenizer)) {
}
td::Status run() override;
td::Status send() override;
td::Status receive(td::BufferSlice data) override;
static std::string get_name() {
return "addpermkey";
}
static std::string get_help() {
return "addpermkey <keyhash> <election-date> <expire-at>\tadd validator permanent key";
}
std::string name() const override {
return get_name();
}
private:
ton::PublicKeyHash key_hash_;
td::uint32 election_date_;
td::uint32 expire_at_;
};
class AddValidatorTempKeyQuery : public Query {
public:
AddValidatorTempKeyQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
: Query(console, std::move(tokenizer)) {
}
td::Status run() override;
td::Status send() override;
td::Status receive(td::BufferSlice data) override;
static std::string get_name() {
return "addtempkey";
}
static std::string get_help() {
return "addtempkey <permkeyhash> <keyhash> <expireat>\tadd validator temp key";
}
std::string name() const override {
return get_name();
}
private:
ton::PublicKeyHash perm_key_hash_;
ton::PublicKeyHash key_hash_;
td::uint32 expire_at_;
};
class AddValidatorAdnlAddrQuery : public Query {
public:
AddValidatorAdnlAddrQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
: Query(console, std::move(tokenizer)) {
}
td::Status run() override;
td::Status send() override;
td::Status receive(td::BufferSlice data) override;
static std::string get_name() {
return "addvalidatoraddr";
}
static std::string get_help() {
return "addvalidatoraddr <permkeyhash> <keyhash> <expireat>\tadd validator ADNL addr";
}
std::string name() const override {
return get_name();
}
private:
ton::PublicKeyHash perm_key_hash_;
ton::PublicKeyHash key_hash_;
td::uint32 expire_at_;
};
class ChangeFullNodeAdnlAddrQuery : public Query {
public:
ChangeFullNodeAdnlAddrQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
: Query(console, std::move(tokenizer)) {
}
td::Status run() override;
td::Status send() override;
td::Status receive(td::BufferSlice data) override;
static std::string get_name() {
return "changefullnodeaddr";
}
static std::string get_help() {
return "changefullnodeaddr <keyhash>\tchanges fullnode ADNL address";
}
std::string name() const override {
return get_name();
}
private:
ton::PublicKeyHash key_hash_;
};
class AddLiteServerQuery : public Query {
public:
AddLiteServerQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
: Query(console, std::move(tokenizer)) {
}
td::Status run() override;
td::Status send() override;
td::Status receive(td::BufferSlice data) override;
static std::string get_name() {
return "addliteserver";
}
static std::string get_help() {
return "addliteserver <port> <keyhash>\tadd liteserver";
}
std::string name() const override {
return get_name();
}
private:
td::uint16 port_;
ton::PublicKeyHash key_hash_;
};
class DelAdnlAddrQuery : public Query {
public:
DelAdnlAddrQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
: Query(console, std::move(tokenizer)) {
}
td::Status run() override;
td::Status send() override;
td::Status receive(td::BufferSlice data) override;
static std::string get_name() {
return "deladnl";
}
static std::string get_help() {
return "deladnl <keyhash>\tdel unused ADNL addr";
}
std::string name() const override {
return get_name();
}
private:
ton::PublicKeyHash key_hash_;
};
class DelDhtIdQuery : public Query {
public:
DelDhtIdQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
: Query(console, std::move(tokenizer)) {
}
td::Status run() override;
td::Status send() override;
td::Status receive(td::BufferSlice data) override;
static std::string get_name() {
return "deldht";
}
static std::string get_help() {
return "deldht <keyhash>\tdel unused DHT node";
}
std::string name() const override {
return get_name();
}
private:
ton::PublicKeyHash key_hash_;
};
class DelValidatorPermanentKeyQuery : public Query {
public:
DelValidatorPermanentKeyQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
: Query(console, std::move(tokenizer)) {
}
td::Status run() override;
td::Status send() override;
td::Status receive(td::BufferSlice data) override;
static std::string get_name() {
return "delpermkey";
}
static std::string get_help() {
return "delpermkey <keyhash>\tforce del unused validator permanent key";
}
std::string name() const override {
return get_name();
}
private:
ton::PublicKeyHash key_hash_;
};
class DelValidatorTempKeyQuery : public Query {
public:
DelValidatorTempKeyQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
: Query(console, std::move(tokenizer)) {
}
td::Status run() override;
td::Status send() override;
td::Status receive(td::BufferSlice data) override;
static std::string get_name() {
return "deltempkey";
}
static std::string get_help() {
return "deltempkey <permkeyhash> <keyhash>\tforce del unused validator temp key";
}
std::string name() const override {
return get_name();
}
private:
ton::PublicKeyHash perm_key_hash_;
ton::PublicKeyHash key_hash_;
};
class DelValidatorAdnlAddrQuery : public Query {
public:
DelValidatorAdnlAddrQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
: Query(console, std::move(tokenizer)) {
}
td::Status run() override;
td::Status send() override;
td::Status receive(td::BufferSlice data) override;
static std::string get_name() {
return "delvalidatoraddr";
}
static std::string get_help() {
return "delvalidatoraddr <permkeyhash> <keyhash>\tforce del unused validator ADNL addr";
}
std::string name() const override {
return get_name();
}
private:
ton::PublicKeyHash perm_key_hash_;
ton::PublicKeyHash key_hash_;
};
class GetConfigQuery : public Query {
public:
GetConfigQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
: Query(console, std::move(tokenizer)) {
}
td::Status run() override;
td::Status send() override;
td::Status receive(td::BufferSlice data) override;
static std::string get_name() {
return "getconfig";
}
static std::string get_help() {
return "getconfig\tdownloads current config";
}
std::string name() const override {
return get_name();
}
private:
};
class SetVerbosityQuery : public Query {
public:
SetVerbosityQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
: Query(console, std::move(tokenizer)) {
}
td::Status run() override;
td::Status send() override;
td::Status receive(td::BufferSlice data) override;
static std::string get_name() {
return "setverbosity";
}
static std::string get_help() {
return "setverbosity <value>\tchanges verbosity level";
}
std::string name() const override {
return get_name();
}
private:
td::uint32 verbosity_;
};
class GetStatsQuery : public Query {
public:
GetStatsQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
: Query(console, std::move(tokenizer)) {
}
td::Status run() override;
td::Status send() override;
td::Status receive(td::BufferSlice data) override;
static std::string get_name() {
return "getstats";
}
static std::string get_help() {
return "getstats\tprints stats";
}
std::string name() const override {
return get_name();
}
};
class QuitQuery : public Query {
public:
QuitQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
: Query(console, std::move(tokenizer)) {
}
td::Status run() override {
return tokenizer_.check_endl();
}
td::Status send() override;
td::Status receive(td::BufferSlice data) override {
UNREACHABLE();
}
static std::string get_name() {
return "quit";
}
static std::string get_help() {
return "quit\tcloses client";
}
std::string name() const override {
return get_name();
}
private:
};
class AddNetworkAddressQuery : public Query {
public:
AddNetworkAddressQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
: Query(console, std::move(tokenizer)) {
}
td::Status run() override;
td::Status send() override;
td::Status receive(td::BufferSlice data) override;
static std::string get_name() {
return "addaddr";
}
static std::string get_help() {
return "addaddr <ip> {cats...} {priocats...}\tadds ip address to address list";
}
std::string name() const override {
return get_name();
}
private:
td::IPAddress addr_;
std::vector<td::int32> cats_;
std::vector<td::int32> prio_cats_;
};
class AddNetworkProxyAddressQuery : public Query {
public:
AddNetworkProxyAddressQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
: Query(console, std::move(tokenizer)) {
}
td::Status run() override;
td::Status send() override;
td::Status receive(td::BufferSlice data) override;
static std::string get_name() {
return "addproxyaddr";
}
static std::string get_help() {
return "addproxyaddr <inip> <outid> <secret> {cats...} {priocats...}\tadds ip address to address list";
}
std::string name() const override {
return get_name();
}
private:
td::IPAddress in_addr_;
td::IPAddress out_addr_;
td::BufferSlice shared_secret_;
std::vector<td::int32> cats_;
std::vector<td::int32> prio_cats_;
};
class CreateElectionBidQuery : public Query {
public:
CreateElectionBidQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
: Query(console, std::move(tokenizer)) {
}
td::Status run() override;
td::Status send() override;
td::Status receive(td::BufferSlice data) override;
static std::string get_name() {
return "createelectionbid";
}
static std::string get_help() {
return "createelectionbid <date> <elector> <wallet> <fname>\tcreate election bid";
}
std::string name() const override {
return get_name();
}
private:
td::uint32 date_;
std::string elector_addr_;
std::string wallet_;
std::string fname_;
};

View file

@ -0,0 +1,307 @@
/*
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 <http://www.gnu.org/licenses/>.
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
*/
#include "validator-engine-console.h"
#include "adnl/adnl-ext-client.h"
#include "tl-utils/lite-utils.hpp"
#include "auto/tl/ton_api_json.h"
#include "auto/tl/lite_api.h"
#include "td/utils/OptionsParser.h"
#include "td/utils/Time.h"
#include "td/utils/filesystem.h"
#include "td/utils/format.h"
#include "td/utils/Random.h"
#include "td/utils/crypto.h"
#include "td/utils/port/signals.h"
#include "td/utils/port/stacktrace.h"
#include "td/utils/port/StdStreams.h"
#include "td/utils/port/FileFd.h"
#include "terminal/terminal.h"
#include "ton/lite-tl.hpp"
#include "block/block-db.h"
#include "block/block.h"
#include "block/block-parse.h"
#include "block/block-auto.h"
#include "block/mc-config.h"
#include "block/check-proof.h"
#include "vm/boc.h"
#include "vm/cellops.h"
#include "vm/cells/MerkleProof.h"
#include "ton/ton-shard.h"
#if TD_DARWIN || TD_LINUX
#include <unistd.h>
#include <fcntl.h>
#endif
#include <iostream>
#include <sstream>
int verbosity;
std::unique_ptr<ton::adnl::AdnlExtClient::Callback> ValidatorEngineConsole::make_callback() {
class Callback : public ton::adnl::AdnlExtClient::Callback {
public:
void on_ready() override {
td::actor::send_closure(id_, &ValidatorEngineConsole::conn_ready);
}
void on_stop_ready() override {
td::actor::send_closure(id_, &ValidatorEngineConsole::conn_closed);
}
Callback(td::actor::ActorId<ValidatorEngineConsole> id) : id_(std::move(id)) {
}
private:
td::actor::ActorId<ValidatorEngineConsole> id_;
};
return std::make_unique<Callback>(actor_id(this));
}
void ValidatorEngineConsole::run() {
class Cb : public td::TerminalIO::Callback {
public:
void line_cb(td::BufferSlice line) override {
td::actor::send_closure(id_, &ValidatorEngineConsole::parse_line, std::move(line));
}
Cb(td::actor::ActorId<ValidatorEngineConsole> id) : id_(id) {
}
private:
td::actor::ActorId<ValidatorEngineConsole> id_;
};
io_ = td::TerminalIO::create("> ", readline_enabled_, std::make_unique<Cb>(actor_id(this)));
td::actor::send_closure(io_, &td::TerminalIO::set_log_interface);
td::TerminalIO::out() << "connecting to " << remote_addr_ << "\n";
td::TerminalIO::out() << "local key: " << private_key_.compute_short_id().bits256_value().to_hex() << "\n";
td::TerminalIO::out() << "remote key: " << server_public_key_.compute_short_id().bits256_value().to_hex() << "\n";
client_ = ton::adnl::AdnlExtClient::create(ton::adnl::AdnlNodeIdFull{server_public_key_}, private_key_, remote_addr_,
make_callback());
add_query_runner(std::make_unique<QueryRunnerImpl<GetTimeQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<GetHelpQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<GetLicenseQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<NewKeyQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<ImportPrivateKeyFileQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<ExportPublicKeyQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<ExportPublicKeyFileQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<SignQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<SignFileQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<AddAdnlAddrQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<AddDhtIdQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<AddValidatorPermanentKeyQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<AddValidatorTempKeyQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<AddValidatorAdnlAddrQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<ChangeFullNodeAdnlAddrQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<AddLiteServerQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<DelAdnlAddrQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<DelDhtIdQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<DelValidatorPermanentKeyQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<DelValidatorTempKeyQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<DelValidatorAdnlAddrQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<GetConfigQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<SetVerbosityQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<GetStatsQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<QuitQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<AddNetworkAddressQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<AddNetworkProxyAddressQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<CreateElectionBidQuery>>());
}
bool ValidatorEngineConsole::envelope_send_query(td::BufferSlice query, td::Promise<td::BufferSlice> promise) {
if (!ready_ || client_.empty()) {
promise.set_error(td::Status::Error(ton::ErrorCode::notready, "failed to send query to server: not ready"));
return false;
}
auto P = td::PromiseCreator::lambda([promise = std::move(promise)](td::Result<td::BufferSlice> R) mutable {
if (R.is_error()) {
promise.set_error(R.move_as_error());
return;
}
auto data = R.move_as_ok();
auto F = ton::fetch_tl_object<ton::ton_api::engine_validator_controlQueryError>(data.clone(), true);
if (F.is_ok()) {
auto f = F.move_as_ok();
promise.set_error(td::Status::Error(f->code_, f->message_));
return;
}
promise.set_result(std::move(data));
});
td::BufferSlice b = ton::serialize_tl_object(
ton::create_tl_object<ton::ton_api::engine_validator_controlQuery>(std::move(query)), true);
td::actor::send_closure(client_, &ton::adnl::AdnlExtClient::send_query, "query", std::move(b),
td::Timestamp::in(10.0), std::move(P));
return true;
}
void ValidatorEngineConsole::got_result() {
running_queries_--;
if (!running_queries_ && ex_queries_.size() > 0) {
auto data = std::move(ex_queries_[0]);
ex_queries_.erase(ex_queries_.begin());
parse_line(std::move(data));
}
if (ex_mode_ && !running_queries_ && ex_queries_.size() == 0) {
std::_Exit(0);
}
}
void ValidatorEngineConsole::show_help(std::string command, td::Promise<td::BufferSlice> promise) {
if (command.size() == 0) {
td::TerminalIO::out() << "list of available commands:\n";
for (auto& cmd : query_runners_) {
td::TerminalIO::out() << cmd.second->help() << "\n";
}
} else {
auto it = query_runners_.find(command);
if (it != query_runners_.end()) {
td::TerminalIO::out() << it->second->help() << "\n";
} else {
td::TerminalIO::out() << "unknown command '" << command << "'\n";
}
}
promise.set_value(td::BufferSlice{});
}
void ValidatorEngineConsole::show_license(td::Promise<td::BufferSlice> promise) {
td::TerminalIO::out() << R"(Copyright (C) 2019 Telegram Systems LLP.
License GPLv2+: GNU GPL version 2 or later <https://www.gnu.org/licenses/gpl-2.0.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.)"
<< "\n";
promise.set_value(td::BufferSlice{});
}
void ValidatorEngineConsole::parse_line(td::BufferSlice data) {
Tokenizer tokenizer(std::move(data));
if (tokenizer.endl()) {
return;
}
auto name = tokenizer.get_token<std::string>().move_as_ok();
auto it = query_runners_.find(name);
if (it != query_runners_.end()) {
running_queries_++;
it->second->run(actor_id(this), std::move(tokenizer));
} else {
td::TerminalIO::out() << "unknown command '" << name << "'\n";
}
}
void ValidatorEngineConsole::set_private_key(td::BufferSlice file_name) {
auto R = [&]() -> td::Result<ton::PrivateKey> {
TRY_RESULT_PREFIX(conf_data, td::read_file(file_name.as_slice().str()), "failed to read: ");
return ton::PrivateKey::import(conf_data.as_slice());
}();
if (R.is_error()) {
LOG(FATAL) << "bad private key: " << R.move_as_error();
}
private_key_ = R.move_as_ok();
}
void ValidatorEngineConsole::set_public_key(td::BufferSlice file_name) {
auto R = [&]() -> td::Result<ton::PublicKey> {
TRY_RESULT_PREFIX(conf_data, td::read_file(file_name.as_slice().str()), "failed to read: ");
return ton::PublicKey::import(conf_data.as_slice());
}();
if (R.is_error()) {
LOG(FATAL) << "bad server public key: " << R.move_as_error();
}
server_public_key_ = R.move_as_ok();
}
int main(int argc, char* argv[]) {
SET_VERBOSITY_LEVEL(verbosity_INFO);
td::set_default_failure_signal_handler();
td::actor::ActorOwn<ValidatorEngineConsole> x;
td::OptionsParser p;
p.set_description("console for validator for TON Blockchain");
p.add_option('h', "help", "prints_help", [&]() {
char b[10240];
td::StringBuilder sb(td::MutableSlice{b, 10000});
sb << p;
std::cout << sb.as_cslice().c_str();
std::exit(2);
return td::Status::OK();
});
p.add_option('a', "address", "server address", [&](td::Slice arg) {
td::IPAddress addr;
TRY_STATUS(addr.init_host_port(arg.str()));
td::actor::send_closure(x, &ValidatorEngineConsole::set_remote_addr, addr);
return td::Status::OK();
});
p.add_option('k', "key", "private key", [&](td::Slice arg) {
td::actor::send_closure(x, &ValidatorEngineConsole::set_private_key, td::BufferSlice{arg});
return td::Status::OK();
});
p.add_option('p', "pub", "server public key", [&](td::Slice arg) {
td::actor::send_closure(x, &ValidatorEngineConsole::set_public_key, td::BufferSlice{arg});
return td::Status::OK();
});
p.add_option('r', "disable-readline", "disable readline", [&]() {
td::actor::send_closure(x, &ValidatorEngineConsole::set_readline_enabled, false);
return td::Status::OK();
});
p.add_option('R', "enable-readline", "enable readline", [&]() {
td::actor::send_closure(x, &ValidatorEngineConsole::set_readline_enabled, true);
return td::Status::OK();
});
p.add_option('v', "verbosity", "set verbosity level", [&](td::Slice arg) {
verbosity = td::to_integer<int>(arg);
SET_VERBOSITY_LEVEL(VERBOSITY_NAME(FATAL) + verbosity);
return (verbosity >= 0 && verbosity <= 9) ? td::Status::OK() : td::Status::Error("verbosity must be 0..9");
});
p.add_option('c', "cmd", "schedule command", [&](td::Slice arg) {
td::actor::send_closure(x, &ValidatorEngineConsole::add_cmd, td::BufferSlice{arg});
return td::Status::OK();
});
p.add_option('t', "timeout", "timeout in batch mode", [&](td::Slice arg) {
auto d = td::to_double(arg);
td::actor::send_closure(x, &ValidatorEngineConsole::set_fail_timeout, td::Timestamp::in(d));
return td::Status::OK();
});
td::actor::Scheduler scheduler({2});
scheduler.run_in_context([&] {
x = td::actor::create_actor<ValidatorEngineConsole>("console");
auto S = p.run(argc, argv);
if (S.is_error()) {
std::cerr << S.move_as_error().message().str() << std::endl;
std::_Exit(2);
}
td::actor::send_closure(x, &ValidatorEngineConsole::run);
});
scheduler.run();
return 0;
}

View file

@ -0,0 +1,124 @@
/*
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 <http://www.gnu.org/licenses/>.
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-ext-client.h"
#include "tl-utils/tl-utils.hpp"
#include "ton/ton-types.h"
#include "terminal/terminal.h"
#include "vm/cells.h"
#include "validator-engine-console-query.h"
#include <map>
class ValidatorEngineConsole : public td::actor::Actor {
private:
td::actor::ActorOwn<ton::adnl::AdnlExtClient> client_;
td::actor::ActorOwn<td::TerminalIO> io_;
bool readline_enabled_ = true;
td::IPAddress remote_addr_;
ton::PrivateKey private_key_;
ton::PublicKey server_public_key_;
bool ready_ = false;
bool inited_ = false;
td::Timestamp fail_timeout_;
td::uint32 running_queries_ = 0;
bool ex_mode_ = false;
std::vector<td::BufferSlice> ex_queries_;
std::unique_ptr<ton::adnl::AdnlExtClient::Callback> make_callback();
std::map<std::string, std::unique_ptr<QueryRunner>> query_runners_;
void add_query_runner(std::unique_ptr<QueryRunner> runner) {
auto name = runner->name();
query_runners_[name] = std::move(runner);
}
public:
void conn_ready() {
td::TerminalIO::out() << "conn ready\n";
ready_ = true;
running_queries_++;
got_result();
}
void conn_closed() {
td::TerminalIO::out() << "conn failed\n";
ready_ = false;
}
void set_readline_enabled(bool value) {
readline_enabled_ = value;
}
void set_remote_addr(td::IPAddress addr) {
remote_addr_ = addr;
}
void set_private_key(td::BufferSlice file_name);
void set_public_key(td::BufferSlice file_name);
void add_cmd(td::BufferSlice data) {
ex_mode_ = true;
ex_queries_.push_back(std::move(data));
}
void set_fail_timeout(td::Timestamp ts) {
fail_timeout_ = ts;
alarm_timestamp().relax(fail_timeout_);
}
void alarm() override {
if (fail_timeout_.is_in_past()) {
std::_Exit(7);
}
if (ex_mode_ && !running_queries_ && ex_queries_.size() == 0) {
std::_Exit(0);
}
alarm_timestamp().relax(fail_timeout_);
}
void close() {
stop();
}
void tear_down() override {
// FIXME: do not work in windows
//td::actor::SchedulerContext::get()->stop();
io_.reset();
std::_Exit(0);
}
bool envelope_send_query(td::BufferSlice query, td::Promise<td::BufferSlice> promise);
void got_result();
void show_help(std::string command, td::Promise<td::BufferSlice> promise);
void show_license(td::Promise<td::BufferSlice> promise);
void parse_line(td::BufferSlice data);
ValidatorEngineConsole() {
}
void run();
};