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

Add methods to sign and import certificates

This commit is contained in:
OmicronTau 2021-11-30 15:11:14 +03:00 committed by EmelyanenkoK
parent 3384d204d2
commit cb31a20206
20 changed files with 682 additions and 18 deletions

View file

@ -26,9 +26,12 @@
Copyright 2017-2020 Telegram Systems LLP
*/
#include "validator-engine-console-query.h"
#include "auto/tl/ton_api.h"
#include "td/utils/StringBuilder.h"
#include "validator-engine-console.h"
#include "terminal/terminal.h"
#include "td/utils/filesystem.h"
#include "overlay/overlays.h"
#include <cctype>
@ -720,3 +723,193 @@ td::Status CheckDhtServersQuery::receive(td::BufferSlice data) {
}
return td::Status::OK();
}
td::Status SignCertificateQuery::run() {
TRY_RESULT_ASSIGN(overlay_, tokenizer_.get_token<td::Bits256>());
TRY_RESULT_ASSIGN(id_, tokenizer_.get_token<td::Bits256>());
TRY_RESULT_ASSIGN(expire_at_, tokenizer_.get_token<td::int32>());
TRY_RESULT_ASSIGN(max_size_, tokenizer_.get_token<td::uint32>());
TRY_RESULT_ASSIGN(signer_, tokenizer_.get_token<ton::PublicKeyHash>());
TRY_RESULT_ASSIGN(out_file_, tokenizer_.get_token<std::string>());
return td::Status::OK();
}
td::Status SignCertificateQuery::send() {
auto cid = ton::create_serialize_tl_object<ton::ton_api::overlay_certificateId>(overlay_, id_, expire_at_, max_size_);
auto sign = ton::create_serialize_tl_object<ton::ton_api::engine_validator_sign>(signer_.tl(), std::move(cid));
auto pub = ton::create_serialize_tl_object<ton::ton_api::engine_validator_exportPublicKey>(signer_.tl());
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(pub),
td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::BufferSlice> R) {
if (R.is_error()) {
td::actor::send_closure(SelfId, &SignCertificateQuery::handle_error, R.move_as_error());
} else {
td::actor::send_closure(SelfId, &SignCertificateQuery::receive_pubkey, R.move_as_ok());
}
}));
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(sign),
td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::BufferSlice> R) {
if (R.is_error()) {
td::actor::send_closure(SelfId, &SignCertificateQuery::handle_error, R.move_as_error());
} else {
td::actor::send_closure(SelfId, &SignCertificateQuery::receive_signature, R.move_as_ok());
}
}));
return td::Status::OK();
}
void SignCertificateQuery::receive_pubkey(td::BufferSlice R) {
auto f = ton::fetch_tl_object<ton::ton_api::PublicKey>(R.as_slice(), true);
if (f.is_error()) {
handle_error(f.move_as_error_prefix("Failed to get pubkey: "));
return;
}
pubkey_ = f.move_as_ok();
has_pubkey_ = true;
if(has_signature_) {
save_certificate();
}
}
td::Status SignCertificateQuery::receive(td::BufferSlice data) {
UNREACHABLE();
}
void SignCertificateQuery::receive_signature(td::BufferSlice R) {
auto f = ton::fetch_tl_object<ton::ton_api::engine_validator_signature>(R.as_slice(), true);
if(f.is_error()){
handle_error(f.move_as_error_prefix("Failed to get signature: "));
return;
}
signature_ = std::move(f.move_as_ok()->signature_);
if(has_pubkey_) {
save_certificate();
}
}
void SignCertificateQuery::save_certificate() {
auto c = ton::create_serialize_tl_object<ton::ton_api::overlay_certificate>(
std::move(pubkey_), expire_at_, max_size_, std::move(signature_));
auto w = td::write_file(out_file_, c.as_slice());
if(w.is_error()) {
handle_error(w.move_as_error_prefix("Failed to write certificate to file: "));
return;
}
td::TerminalIO::out() << "saved certificate\n";
stop();
}
td::Status ImportCertificateQuery::run() {
TRY_RESULT_ASSIGN(overlay_, tokenizer_.get_token<td::Bits256>());
TRY_RESULT_ASSIGN(id_, tokenizer_.get_token<td::Bits256>());
TRY_RESULT_ASSIGN(kh_, tokenizer_.get_token<ton::PublicKeyHash>());
TRY_RESULT_ASSIGN(in_file_, tokenizer_.get_token<std::string>());
return td::Status::OK();
}
td::Status ImportCertificateQuery::send() {
TRY_RESULT(data, td::read_file(in_file_));
TRY_RESULT_PREFIX(cert, ton::fetch_tl_object<ton::ton_api::overlay_Certificate>(data.as_slice(), true),
"incorrect certificate");
auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_importCertificate>(
overlay_,
ton::create_tl_object<ton::ton_api::adnl_id_short>(id_),
ton::create_tl_object<ton::ton_api::engine_validator_keyHash>(kh_.tl()),
std::move(cert)
);
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
return td::Status::OK();
}
td::Status GetOverlaysStatsQuery::run() {
return td::Status::OK();
}
td::Status GetOverlaysStatsQuery::send() {
auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_getOverlaysStats>();
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
return td::Status::OK();
}
td::Status GetOverlaysStatsQuery::receive(td::BufferSlice data) {
TRY_RESULT_PREFIX(f, ton::fetch_tl_object<ton::ton_api::engine_validator_overlaysStats>(data.as_slice(), true),
"received incorrect answer: ");
for (auto &s : f->overlays_) {
td::StringBuilder sb;
sb << "overlay_id=" << s->overlay_id_ << " adnl_id=" << s->adnl_id_ << "\n";
sb << " nodes:";
for (auto &n : s->nodes_) {
sb << " " << n->id_ << "\n";
}
sb << " stats:\n";
for (auto &t : s->stats_) {
sb << " " << t->key_ << "\t" << t->value_ << "\n";
}
td::TerminalIO::output(sb.as_cslice());
}
return td::Status::OK();
}
td::Status ImportCertificateQuery::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() << "successfully sent certificate to overlay manager\n";
return td::Status::OK();
}
td::Status SignShardOverlayCertificateQuery::run() {
TRY_RESULT_ASSIGN(wc_, tokenizer_.get_token<td::int32>());
TRY_RESULT_ASSIGN(shard_, tokenizer_.get_token<td::int64>() );
TRY_RESULT_ASSIGN(key_, tokenizer_.get_token<ton::PublicKeyHash>());
TRY_RESULT_ASSIGN(expire_at_, tokenizer_.get_token<td::int32>());
TRY_RESULT_ASSIGN(max_size_, tokenizer_.get_token<td::uint32>());
TRY_RESULT_ASSIGN(out_file_, tokenizer_.get_token<std::string>());
return td::Status::OK();
}
td::Status SignShardOverlayCertificateQuery::send() {
auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_signShardOverlayCertificate>
(wc_, shard_, ton::create_tl_object<ton::ton_api::engine_validator_keyHash>(key_.tl()), expire_at_, max_size_);
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
return td::Status::OK();
}
td::Status SignShardOverlayCertificateQuery::receive(td::BufferSlice data) {
TRY_RESULT_PREFIX(c, ton::fetch_tl_object<ton::ton_api::overlay_certificate>(data.as_slice(), true),
"received incorrect cert: ");
auto w = td::write_file(out_file_, data.as_slice());
if(w.is_error()) {
return w.move_as_error_prefix("Failed to write certificate to file: ");
}
td::TerminalIO::out() << "saved certificate\n";
return td::Status::OK();
}
td::Status ImportShardOverlayCertificateQuery::run() {
TRY_RESULT_ASSIGN(wc_, tokenizer_.get_token<td::int32>());
TRY_RESULT_ASSIGN(shard_, tokenizer_.get_token<td::int64>() );
TRY_RESULT_ASSIGN(key_, tokenizer_.get_token<ton::PublicKeyHash>());
TRY_RESULT_ASSIGN(in_file_, tokenizer_.get_token<std::string>());
return td::Status::OK();
}
td::Status ImportShardOverlayCertificateQuery::send() {
TRY_RESULT(data, td::read_file(in_file_));
TRY_RESULT_PREFIX(cert, ton::fetch_tl_object<ton::ton_api::overlay_Certificate>(data.as_slice(), true),
"incorrect certificate");
auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_importShardOverlayCertificate>
(wc_, shard_, ton::create_tl_object<ton::ton_api::engine_validator_keyHash>(key_.tl()), std::move(cert));
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
return td::Status::OK();
}
td::Status ImportShardOverlayCertificateQuery::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() << "successfully sent certificate to overlay manager\n";
return td::Status::OK();
}

View file

@ -903,3 +903,139 @@ class CheckDhtServersQuery : public Query {
private:
ton::PublicKeyHash id_;
};
class GetOverlaysStatsQuery : public Query {
public:
GetOverlaysStatsQuery(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 "getoverlaysstats";
}
static std::string get_help() {
return "getoverlaysstats\tgets stats for all overlays";
}
std::string name() const override {
return get_name();
}
};
class SignCertificateQuery : public Query {
public:
SignCertificateQuery(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 "signcert";
}
static std::string get_help() {
return "signcert <overlayid> <adnlid> <expireat> <maxsize> <signwith> <outfile>\tsign overlay certificate by <signwith> key";
}
std::string name() const override {
return get_name();
}
void receive_pubkey(td::BufferSlice R);
void receive_signature(td::BufferSlice R);
private:
void save_certificate();
td::Bits256 overlay_;
td::Bits256 id_;
td::int32 expire_at_;
td::uint32 max_size_;
std::string out_file_;
ton::PublicKeyHash signer_;
td::BufferSlice signature_;
std::unique_ptr<ton::ton_api::PublicKey> pubkey_;
bool has_signature_{0};
bool has_pubkey_{0};
};
class ImportCertificateQuery : public Query {
public:
ImportCertificateQuery(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 "importcert";
}
static std::string get_help() {
return "importcert <overlayid> <adnlid> <key> <certfile>\timport overlay certificate for specific key";
}
std::string name() const override {
return get_name();
}
private:
td::Bits256 overlay_;
td::Bits256 id_;
ton::PublicKeyHash kh_;
std::string in_file_;
};
class SignShardOverlayCertificateQuery : public Query {
public:
SignShardOverlayCertificateQuery(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 "signshardoverlaycert";
}
static std::string get_help() {
return "signshardoverlaycert <workchain> <shardprefix> <key> <expireat> <maxsize> <outfile>\tsign certificate for <key> in currently active shard overlay";
}
std::string name() const override {
return get_name();
}
private:
td::int32 wc_;
td::int64 shard_;
td::int32 expire_at_;
ton::PublicKeyHash key_;
td::uint32 max_size_;
std::string out_file_;
};
class ImportShardOverlayCertificateQuery : public Query {
public:
ImportShardOverlayCertificateQuery(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 "importshardoverlaycert";
}
static std::string get_help() {
return "importshardoverlaycert <workchain> <shardprefix> <key> <certfile>\timport certificate for <key> in currently active shard overlay";
}
std::string name() const override {
return get_name();
}
private:
td::int32 wc_;
td::int64 shard_;
ton::PublicKeyHash key_;
std::string in_file_;
};

View file

@ -134,6 +134,11 @@ void ValidatorEngineConsole::run() {
add_query_runner(std::make_unique<QueryRunnerImpl<CreateProposalVoteQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<CreateComplaintVoteQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<CheckDhtServersQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<SignCertificateQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<ImportCertificateQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<GetOverlaysStatsQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<ImportShardOverlayCertificateQuery>>());
add_query_runner(std::make_unique<QueryRunnerImpl<SignShardOverlayCertificateQuery>>());
}
bool ValidatorEngineConsole::envelope_send_query(td::BufferSlice query, td::Promise<td::BufferSlice> promise) {
@ -258,7 +263,8 @@ int main(int argc, char* argv[]) {
std::exit(2);
});
p.add_option('V', "version", "shows validator-engine-console build information", [&]() {
std::cout << "validator-engine-console build information: [ Commit: " << GitMetadata::CommitSHA1() << ", Date: " << GitMetadata::CommitDate() << "]\n";
std::cout << "validator-engine-console build information: [ Commit: " << GitMetadata::CommitSHA1()
<< ", Date: " << GitMetadata::CommitDate() << "]\n";
std::exit(0);
});
p.add_checked_option('a', "address", "server address", [&](td::Slice arg) {