diff --git a/adnl/adnl-peer.cpp b/adnl/adnl-peer.cpp index febbdac6..d82486fe 100644 --- a/adnl/adnl-peer.cpp +++ b/adnl/adnl-peer.cpp @@ -269,7 +269,11 @@ void AdnlPeerPairImpl::send_messages_in(std::vector message size_t ptr = 0; bool first = true; do { + respond_with_nop_after_ = td::Timestamp::in(td::Random::fast(1.0, 2.0)); bool try_reinit = try_reinit_at_ && try_reinit_at_.is_in_past(); + if (try_reinit) { + try_reinit_at_ = td::Timestamp::in(td::Random::fast(0.5, 1.5)); + } bool via_channel = channel_ready_ && !try_reinit; size_t s = (via_channel ? channel_packet_header_max_size() : packet_header_max_size()); if (first) { @@ -504,12 +508,6 @@ void AdnlPeerPairImpl::create_channel(pubkeys::Ed25519 pub, td::uint32 date) { void AdnlPeerPairImpl::process_message(const adnlmessage::AdnlMessageCreateChannel &message) { create_channel(message.key(), message.date()); - if (respond_to_channel_create_after_.is_in_past()) { - respond_to_channel_create_after_ = td::Timestamp::in(td::Random::fast(1.0, 2.0)); - std::vector messages; - messages.emplace_back(adnlmessage::AdnlMessageNop{}, 0); - send_messages(std::move(messages)); - } } void AdnlPeerPairImpl::process_message(const adnlmessage::AdnlMessageConfirmChannel &message) { @@ -526,6 +524,7 @@ void AdnlPeerPairImpl::process_message(const adnlmessage::AdnlMessageConfirmChan } void AdnlPeerPairImpl::process_message(const adnlmessage::AdnlMessageCustom &message) { + respond_with_nop(); td::actor::send_closure(local_actor_, &AdnlLocalId::deliver, peer_id_short_, message.data()); } @@ -538,6 +537,7 @@ void AdnlPeerPairImpl::process_message(const adnlmessage::AdnlMessageReinit &mes } void AdnlPeerPairImpl::process_message(const adnlmessage::AdnlMessageQuery &message) { + respond_with_nop(); auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), query_id = message.query_id(), flags = static_cast(0)](td::Result R) { if (R.is_error()) { @@ -556,6 +556,7 @@ void AdnlPeerPairImpl::process_message(const adnlmessage::AdnlMessageQuery &mess } void AdnlPeerPairImpl::process_message(const adnlmessage::AdnlMessageAnswer &message) { + respond_with_nop(); auto Q = out_queries_.find(message.query_id()); if (Q == out_queries_.end()) { @@ -573,6 +574,7 @@ void AdnlPeerPairImpl::process_message(const adnlmessage::AdnlMessageAnswer &mes } void AdnlPeerPairImpl::process_message(const adnlmessage::AdnlMessagePart &message) { + respond_with_nop(); auto size = message.total_size(); if (size > huge_packet_max_size()) { VLOG(ADNL_WARNING) << this << ": dropping too big huge message: size=" << size; @@ -635,6 +637,14 @@ void AdnlPeerPairImpl::delete_query(AdnlQueryId id) { } } +void AdnlPeerPairImpl::respond_with_nop() { + if (respond_with_nop_after_.is_in_past()) { + std::vector messages; + messages.emplace_back(adnlmessage::AdnlMessageNop{}, 0); + send_messages(std::move(messages)); + } +} + void AdnlPeerPairImpl::reinit(td::int32 date) { if (reinit_date_ == 0) { reinit_date_ = date; diff --git a/adnl/adnl-peer.hpp b/adnl/adnl-peer.hpp index e9a5d428..40c9eb08 100644 --- a/adnl/adnl-peer.hpp +++ b/adnl/adnl-peer.hpp @@ -122,6 +122,7 @@ class AdnlPeerPairImpl : public AdnlPeerPair { } private: + void respond_with_nop(); void reinit(td::int32 date); td::Result, bool>> get_conn(bool direct_only); void create_channel(pubkeys::Ed25519 pub, td::uint32 date); @@ -214,7 +215,7 @@ class AdnlPeerPairImpl : public AdnlPeerPair { pubkeys::Ed25519 channel_pub_; td::int32 channel_pk_date_; td::actor::ActorOwn channel_; - td::Timestamp respond_to_channel_create_after_; + td::Timestamp respond_with_nop_after_; td::uint64 in_seqno_ = 0; td::uint64 out_seqno_ = 0; diff --git a/crypto/vm/bls.cpp b/crypto/vm/bls.cpp index f6ccc275..ff5179c7 100644 --- a/crypto/vm/bls.cpp +++ b/crypto/vm/bls.cpp @@ -93,12 +93,13 @@ bool aggregate_verify(const std::vector> &pubs_ms return false; } std::unique_ptr pairing = std::make_unique(true, DST); + blst::P2_Affine p2_zero; for (const auto &p : pubs_msgs) { blst::P1_Affine p1(p.first.data(), P1_SIZE); if (!p1.in_group() || p1.is_inf()) { return false; } - pairing->aggregate(&p1, nullptr, (const td::uint8 *)p.second.data(), p.second.size()); + pairing->aggregate(&p1, &p2_zero, (const td::uint8 *)p.second.data(), p.second.size()); } pairing->commit(); blst::P2_Affine p2(sig.data(), P2_SIZE); diff --git a/dht/dht-in.hpp b/dht/dht-in.hpp index c2d20455..0d668d43 100644 --- a/dht/dht-in.hpp +++ b/dht/dht-in.hpp @@ -179,6 +179,7 @@ class DhtMemberImpl : public DhtMember { void get_value(DhtKey key, td::Promise result) override { get_value_in(key.compute_key_id(), std::move(result)); } + void get_value_many(DhtKey key, std::function callback, td::Promise promise) override; void alarm() override { alarm_timestamp() = td::Timestamp::in(1.0); diff --git a/dht/dht-query.cpp b/dht/dht-query.cpp index b84ef8c3..3d43b106 100644 --- a/dht/dht-query.cpp +++ b/dht/dht-query.cpp @@ -210,8 +210,11 @@ void DhtQueryFindValue::on_result(td::Result R, adnl::AdnlNodeI send_get_nodes = true; return; } - promise_.set_value(std::move(value)); - need_stop = true; + if (on_value_found(std::move(value))) { + send_get_nodes = true; + } else { + need_stop = true; + } }, [&](ton_api::dht_valueNotFound &v) { add_nodes(DhtNodesList{std::move(v.nodes_), our_network_id()}); @@ -244,7 +247,32 @@ void DhtQueryFindValue::on_result_nodes(td::Result R, adnl::Adn } void DhtQueryFindValue::finish(DhtNodesList list) { - promise_.set_error(td::Status::Error(ErrorCode::notready, "dht key not found")); +} + +bool DhtQueryFindValueSingle::on_value_found(DhtValue value) { + promise_.set_value(std::move(value)); + found_ = true; + return false; +} + +void DhtQueryFindValueSingle::tear_down() { + if (!found_) { + promise_.set_error(td::Status::Error(ErrorCode::notready, "dht key not found")); + } +} + +bool DhtQueryFindValueMany::on_value_found(DhtValue value) { + callback_(std::move(value)); + found_ = true; + return true; +} + +void DhtQueryFindValueMany::tear_down() { + if (found_) { + promise_.set_value(td::Unit()); + } else { + promise_.set_error(td::Status::Error(ErrorCode::notready, "dht key not found")); + } } DhtQueryStore::DhtQueryStore(DhtValue key_value, DhtMember::PrintId print_id, adnl::AdnlNodeIdShort src, diff --git a/dht/dht-query.hpp b/dht/dht-query.hpp index e4740361..e305f107 100644 --- a/dht/dht-query.hpp +++ b/dht/dht-query.hpp @@ -126,16 +126,11 @@ class DhtQueryFindNodes : public DhtQuery { }; class DhtQueryFindValue : public DhtQuery { - private: - td::Promise promise_; - public: DhtQueryFindValue(DhtKeyId key, DhtMember::PrintId print_id, adnl::AdnlNodeIdShort src, DhtNodesList list, td::uint32 k, td::uint32 a, td::int32 our_network_id, DhtNode self, bool client_only, - td::actor::ActorId node, td::actor::ActorId adnl, - td::Promise promise) - : DhtQuery(key, print_id, src, k, a, our_network_id, std::move(self), client_only, node, adnl) - , promise_(std::move(promise)) { + td::actor::ActorId node, td::actor::ActorId adnl) + : DhtQuery(key, print_id, src, k, a, our_network_id, std::move(self), client_only, node, adnl) { add_nodes(std::move(list)); } void send_one_query(adnl::AdnlNodeIdShort id) override; @@ -146,6 +141,48 @@ class DhtQueryFindValue : public DhtQuery { std::string get_name() const override { return "find value"; } + + virtual bool on_value_found(DhtValue value) = 0; +}; + +class DhtQueryFindValueSingle : public DhtQueryFindValue { + public: + DhtQueryFindValueSingle(DhtKeyId key, DhtMember::PrintId print_id, adnl::AdnlNodeIdShort src, DhtNodesList list, + td::uint32 k, td::uint32 a, td::int32 our_network_id, DhtNode self, bool client_only, + td::actor::ActorId node, td::actor::ActorId adnl, + td::Promise promise) + : DhtQueryFindValue(key, print_id, src, std::move(list), k, a, our_network_id, std::move(self), client_only, node, + adnl) + , promise_(std::move(promise)) { + add_nodes(std::move(list)); + } + bool on_value_found(DhtValue value) override; + void tear_down() override; + + private: + td::Promise promise_; + bool found_ = false; +}; + +class DhtQueryFindValueMany : public DhtQueryFindValue { + public: + DhtQueryFindValueMany(DhtKeyId key, DhtMember::PrintId print_id, adnl::AdnlNodeIdShort src, DhtNodesList list, + td::uint32 k, td::uint32 a, td::int32 our_network_id, DhtNode self, bool client_only, + td::actor::ActorId node, td::actor::ActorId adnl, + std::function callback, td::Promise promise) + : DhtQueryFindValue(key, print_id, src, std::move(list), k, a, our_network_id, std::move(self), client_only, node, + adnl) + , callback_(std::move(callback)) + , promise_(std::move(promise)) { + add_nodes(std::move(list)); + } + bool on_value_found(DhtValue value) override; + void tear_down() override; + + private: + std::function callback_; + td::Promise promise_; + bool found_ = false; }; class DhtQueryStore : public td::actor::Actor { diff --git a/dht/dht.cpp b/dht/dht.cpp index 8d7b02b7..b774b5f9 100644 --- a/dht/dht.cpp +++ b/dht/dht.cpp @@ -470,7 +470,7 @@ void DhtMemberImpl::get_value_in(DhtKeyId key, td::Promise result) { network_id = network_id_, id = id_, client_only = client_only_](td::Result R) mutable { R.ensure(); - td::actor::create_actor("FindValueQuery", key, print_id, id, std::move(list), k, a, network_id, + td::actor::create_actor("FindValueQuery", key, print_id, id, std::move(list), k, a, network_id, R.move_as_ok(), client_only, SelfId, adnl, std::move(promise)) .release(); }); @@ -478,6 +478,21 @@ void DhtMemberImpl::get_value_in(DhtKeyId key, td::Promise result) { get_self_node(std::move(P)); } +void DhtMemberImpl::get_value_many(DhtKey key, std::function callback, td::Promise promise) { + DhtKeyId key_id = key.compute_key_id(); + auto P = td::PromiseCreator::lambda( + [key = key_id, callback = std::move(callback), promise = std::move(promise), SelfId = actor_id(this), + print_id = print_id(), adnl = adnl_, list = get_nearest_nodes(key_id, k_ * 2), k = k_, a = a_, + network_id = network_id_, id = id_, client_only = client_only_](td::Result R) mutable { + R.ensure(); + td::actor::create_actor("FindValueManyQuery", key, print_id, id, std::move(list), k, a, + network_id, R.move_as_ok(), client_only, SelfId, adnl, + std::move(callback), std::move(promise)) + .release(); + }); + get_self_node(std::move(P)); +} + void DhtMemberImpl::register_reverse_connection(adnl::AdnlNodeIdFull client, td::Promise promise) { auto client_short = client.compute_short_id(); td::uint32 ttl = (td::uint32)td::Clocks::system() + 300; diff --git a/dht/dht.h b/dht/dht.h index b9c65c8a..5abff94a 100644 --- a/dht/dht.h +++ b/dht/dht.h @@ -53,6 +53,7 @@ class Dht : public td::actor::Actor { virtual void set_value(DhtValue key_value, td::Promise result) = 0; virtual void get_value(DhtKey key, td::Promise result) = 0; + virtual void get_value_many(DhtKey key, std::function callback, td::Promise promise) = 0; virtual void register_reverse_connection(adnl::AdnlNodeIdFull client, td::Promise promise) = 0; virtual void request_reverse_ping(adnl::AdnlNode target, adnl::AdnlNodeIdShort client, diff --git a/keyring/keyring.cpp b/keyring/keyring.cpp index 529a6b8b..0f45879d 100644 --- a/keyring/keyring.cpp +++ b/keyring/keyring.cpp @@ -27,6 +27,16 @@ namespace ton { namespace keyring { +KeyringImpl::PrivateKeyDescr::PrivateKeyDescr(PrivateKey private_key, bool is_temp) + : public_key(private_key.compute_public_key()), is_temp(is_temp) { + auto D = private_key.create_decryptor_async(); + D.ensure(); + decryptor_sign = D.move_as_ok(); + D = private_key.create_decryptor_async(); + D.ensure(); + decryptor_decrypt = D.move_as_ok(); +} + void KeyringImpl::start_up() { if (db_root_.size() > 0) { td::mkdir(db_root_).ensure(); @@ -45,23 +55,19 @@ td::Result KeyringImpl::load_key(PublicKeyHash k auto name = db_root_ + "/" + key_hash.bits256_value().to_hex(); - auto R = td::read_file(td::CSlice{name}); + auto R = td::read_file_secure(td::CSlice{name}); if (R.is_error()) { return R.move_as_error_prefix("key not in db: "); } auto data = R.move_as_ok(); - auto R2 = PrivateKey::import(td::SecureString(data)); + auto R2 = PrivateKey::import(data); R2.ensure(); auto key = R2.move_as_ok(); - auto pub = key.compute_public_key(); - auto short_id = pub.compute_short_id(); + auto desc = std::make_unique(key, false); + auto short_id = desc->public_key.compute_short_id(); CHECK(short_id == key_hash); - - auto D = key.create_decryptor_async(); - D.ensure(); - - return map_.emplace(short_id, std::make_unique(D.move_as_ok(), pub, false)).first->second.get(); + return map_.emplace(short_id, std::move(desc)).first->second.get(); } void KeyringImpl::add_key(PrivateKey key, bool is_temp, td::Promise promise) { @@ -76,10 +82,7 @@ void KeyringImpl::add_key(PrivateKey key, bool is_temp, td::Promise pr if (db_root_.size() == 0) { CHECK(is_temp); } - auto D = key.create_decryptor_async(); - D.ensure(); - - map_.emplace(short_id, std::make_unique(D.move_as_ok(), pub, is_temp)); + map_.emplace(short_id, std::make_unique(key, is_temp)); if (!is_temp && key.exportable()) { auto S = key.export_as_slice(); @@ -139,7 +142,7 @@ void KeyringImpl::sign_message(PublicKeyHash key_hash, td::BufferSlice data, td: if (S.is_error()) { promise.set_error(S.move_as_error()); } else { - td::actor::send_closure(S.move_as_ok()->decryptor, &DecryptorAsync::sign, std::move(data), std::move(promise)); + td::actor::send_closure(S.move_as_ok()->decryptor_sign, &DecryptorAsync::sign, std::move(data), std::move(promise)); } } @@ -161,7 +164,7 @@ void KeyringImpl::sign_add_get_public_key(PublicKeyHash key_hash, td::BufferSlic } promise.set_value(std::pair{R.move_as_ok(), id}); }); - td::actor::send_closure(D->decryptor, &DecryptorAsync::sign, std::move(data), std::move(P)); + td::actor::send_closure(D->decryptor_sign, &DecryptorAsync::sign, std::move(data), std::move(P)); } void KeyringImpl::sign_messages(PublicKeyHash key_hash, std::vector data, @@ -171,7 +174,7 @@ void KeyringImpl::sign_messages(PublicKeyHash key_hash, std::vectordecryptor, &DecryptorAsync::sign_batch, std::move(data), + td::actor::send_closure(S.move_as_ok()->decryptor_sign, &DecryptorAsync::sign_batch, std::move(data), std::move(promise)); } } @@ -182,7 +185,8 @@ void KeyringImpl::decrypt_message(PublicKeyHash key_hash, td::BufferSlice data, if (S.is_error()) { promise.set_error(S.move_as_error()); } else { - td::actor::send_closure(S.move_as_ok()->decryptor, &DecryptorAsync::decrypt, std::move(data), std::move(promise)); + td::actor::send_closure(S.move_as_ok()->decryptor_decrypt, &DecryptorAsync::decrypt, std::move(data), + std::move(promise)); } } diff --git a/keyring/keyring.hpp b/keyring/keyring.hpp index fc67bd0f..ec658305 100644 --- a/keyring/keyring.hpp +++ b/keyring/keyring.hpp @@ -30,12 +30,11 @@ namespace keyring { class KeyringImpl : public Keyring { private: struct PrivateKeyDescr { - td::actor::ActorOwn decryptor; + td::actor::ActorOwn decryptor_sign; + td::actor::ActorOwn decryptor_decrypt; PublicKey public_key; bool is_temp; - PrivateKeyDescr(td::actor::ActorOwn decryptor, PublicKey public_key, bool is_temp) - : decryptor(std::move(decryptor)), public_key(public_key), is_temp(is_temp) { - } + PrivateKeyDescr(PrivateKey private_key, bool is_temp); }; public: diff --git a/keys/encryptor.cpp b/keys/encryptor.cpp index 0b93d36f..8fef9a09 100644 --- a/keys/encryptor.cpp +++ b/keys/encryptor.cpp @@ -29,28 +29,6 @@ namespace ton { -td::Result> Encryptor::create(const ton_api::PublicKey *id) { - td::Result> res; - ton_api::downcast_call( - *const_cast(id), - td::overloaded([&](const ton_api::pub_unenc &obj) { res = std::make_unique(); }, - [&](const ton_api::pub_ed25519 &obj) { res = std::make_unique(obj.key_); }, - [&](const ton_api::pub_overlay &obj) { res = std::make_unique(); }, - [&](const ton_api::pub_aes &obj) { res = std::make_unique(obj.key_); })); - return res; -} - -td::Result> Decryptor::create(const ton_api::PrivateKey *id) { - td::Result> res; - ton_api::downcast_call( - *const_cast(id), - td::overloaded([&](const ton_api::pk_unenc &obj) { res = std::make_unique(); }, - [&](const ton_api::pk_ed25519 &obj) { res = std::make_unique(obj.key_); }, - [&](const ton_api::pk_overlay &obj) { res = std::make_unique(); }, - [&](const ton_api::pk_aes &obj) { res = std::make_unique(obj.key_); })); - return res; -} - td::Result EncryptorEd25519::encrypt(td::Slice data) { TRY_RESULT_PREFIX(pk, td::Ed25519::generate_private_key(), "failed to generate private key: "); TRY_RESULT_PREFIX(pubkey, pk.get_public_key(), "failed to get public key from private: "); diff --git a/keys/encryptor.h b/keys/encryptor.h index 3035a0ce..818c97d6 100644 --- a/keys/encryptor.h +++ b/keys/encryptor.h @@ -31,7 +31,6 @@ class Encryptor { virtual td::Result encrypt(td::Slice data) = 0; virtual td::Status check_signature(td::Slice message, td::Slice signature) = 0; virtual ~Encryptor() = default; - static td::Result> create(const ton_api::PublicKey *id); }; class Decryptor { @@ -40,7 +39,6 @@ class Decryptor { virtual td::Result sign(td::Slice data) = 0; virtual std::vector> sign_batch(std::vector data); virtual ~Decryptor() = default; - static td::Result> create(const ton_api::PrivateKey *id); }; class EncryptorAsync : public td::actor::Actor { @@ -61,16 +59,6 @@ class EncryptorAsync : public td::actor::Actor { void encrypt(td::BufferSlice data, td::Promise promise) { promise.set_result(encryptor_->encrypt(data.as_slice())); } - template - static td::Result> create(T &id) { - TRY_RESULT(d, Encryptor::create(id)); - return td::actor::create_actor("encryptor", std::move(d)); - } - template - static td::Result> create(T *id) { - TRY_RESULT(d, Encryptor::create(id)); - return td::actor::create_actor("encryptor", std::move(d)); - } }; class DecryptorAsync : public td::actor::Actor { @@ -94,16 +82,6 @@ class DecryptorAsync : public td::actor::Actor { } return decryptor_->sign_batch(v); } - template - static td::Result> create(T &id) { - TRY_RESULT(d, Decryptor::create(id)); - return td::actor::create_actor("decryptor", std::move(d)); - } - template - static td::Result> create(T *id) { - TRY_RESULT(d, Decryptor::create(id)); - return td::actor::create_actor("decryptor", std::move(d)); - } }; } // namespace ton diff --git a/keys/encryptor.hpp b/keys/encryptor.hpp index dbe88239..bcc841dc 100644 --- a/keys/encryptor.hpp +++ b/keys/encryptor.hpp @@ -83,7 +83,7 @@ class EncryptorEd25519 : public Encryptor { td::Result encrypt(td::Slice data) override; td::Status check_signature(td::Slice message, td::Slice signature) override; - EncryptorEd25519(td::Bits256 key) : pub_(td::SecureString(as_slice(key))) { + EncryptorEd25519(const td::Bits256& key) : pub_(td::SecureString(as_slice(key))) { } }; @@ -94,7 +94,7 @@ class DecryptorEd25519 : public Decryptor { public: td::Result decrypt(td::Slice data) override; td::Result sign(td::Slice data) override; - DecryptorEd25519(td::Bits256 key) : pk_(td::SecureString(as_slice(key))) { + DecryptorEd25519(const td::Bits256& key) : pk_(td::SecureString(as_slice(key))) { } }; @@ -129,12 +129,15 @@ class EncryptorAES : public Encryptor { td::Bits256 shared_secret_; public: + ~EncryptorAES() override { + shared_secret_.set_zero_s(); + } td::Result encrypt(td::Slice data) override; td::Status check_signature(td::Slice message, td::Slice signature) override { return td::Status::Error("can no sign channel messages"); } - EncryptorAES(td::Bits256 shared_secret) : shared_secret_(shared_secret) { + EncryptorAES(const td::Bits256& shared_secret) : shared_secret_(shared_secret) { } }; @@ -143,11 +146,14 @@ class DecryptorAES : public Decryptor { td::Bits256 shared_secret_; public: + ~DecryptorAES() override { + shared_secret_.set_zero_s(); + } td::Result decrypt(td::Slice data) override; td::Result sign(td::Slice data) override { return td::Status::Error("can no sign channel messages"); } - DecryptorAES(td::Bits256 shared_secret) : shared_secret_(shared_secret) { + DecryptorAES(const td::Bits256& shared_secret) : shared_secret_(shared_secret) { } }; diff --git a/keys/keys.cpp b/keys/keys.cpp index 7d6c0c2c..01afb26d 100644 --- a/keys/keys.cpp +++ b/keys/keys.cpp @@ -21,6 +21,7 @@ #include "td/utils/overloaded.h" #include "tl-utils/tl-utils.hpp" #include "encryptor.h" +#include "encryptor.hpp" #include "crypto/Ed25519.h" namespace ton { @@ -63,12 +64,31 @@ td::Result PublicKey::import(td::Slice s) { return PublicKey{x}; } +td::Result> pubkeys::Ed25519::create_encryptor() const { + return std::make_unique(data_); +} + +td::Result> pubkeys::AES::create_encryptor() const { + return std::make_unique(data_); +} + +td::Result> pubkeys::Unenc::create_encryptor() const { + return std::make_unique(); +} + +td::Result> pubkeys::Overlay::create_encryptor() const { + return std::make_unique(); +} + td::Result> PublicKey::create_encryptor() const { - return Encryptor::create(tl().get()); + td::Result> res; + pub_key_.visit([&](auto &obj) { res = obj.create_encryptor(); }); + return res; } td::Result> PublicKey::create_encryptor_async() const { - return EncryptorAsync::create(tl().get()); + TRY_RESULT(encryptor, create_encryptor()); + return td::actor::create_actor("encryptor", std::move(encryptor)); } bool PublicKey::empty() const { @@ -109,6 +129,22 @@ privkeys::Ed25519::Ed25519(td::Ed25519::PrivateKey key) { data_.as_slice().copy_from(td::Slice(s)); } +td::Result> privkeys::Ed25519::create_decryptor() const { + return std::make_unique(data_); +} + +td::Result> privkeys::AES::create_decryptor() const { + return std::make_unique(data_); +} + +td::Result> privkeys::Unenc::create_decryptor() const { + return std::make_unique(); +} + +td::Result> privkeys::Overlay::create_decryptor() const { + return std::make_unique(); +} + pubkeys::Ed25519::Ed25519(td::Ed25519::PublicKey key) { auto s = key.as_octet_string(); CHECK(s.length() == 32); @@ -188,11 +224,14 @@ tl_object_ptr PrivateKey::tl() const { } td::Result> PrivateKey::create_decryptor() const { - return Decryptor::create(tl().get()); + td::Result> res; + priv_key_.visit([&](auto &obj) { res = obj.create_decryptor(); }); + return res; } td::Result> PrivateKey::create_decryptor_async() const { - return DecryptorAsync::create(tl().get()); + TRY_RESULT(decryptor, create_decryptor()); + return td::actor::create_actor("decryptor", std::move(decryptor)); } } // namespace ton diff --git a/keys/keys.hpp b/keys/keys.hpp index 6ed51f08..2e517b2e 100644 --- a/keys/keys.hpp +++ b/keys/keys.hpp @@ -110,6 +110,7 @@ class Ed25519 { tl_object_ptr tl() const { return create_tl_object(data_); } + td::Result> create_encryptor() const; bool operator==(const Ed25519 &with) const { return data_ == with.data_; } @@ -141,6 +142,7 @@ class AES { tl_object_ptr tl() const { return create_tl_object(data_); } + td::Result> create_encryptor() const; bool operator==(const AES &with) const { return data_ == with.data_; } @@ -172,6 +174,7 @@ class Unenc { tl_object_ptr tl() const { return create_tl_object(data_.clone_as_buffer_slice()); } + td::Result> create_encryptor() const; bool operator==(const Unenc &with) const { return data_.as_slice() == with.data_.as_slice(); } @@ -203,6 +206,7 @@ class Overlay { tl_object_ptr tl() const { return create_tl_object(data_.clone_as_buffer_slice()); } + td::Result> create_encryptor() const; bool operator==(const Overlay &with) const { return data_.as_slice() == with.data_.as_slice(); } @@ -223,6 +227,9 @@ class PublicKey { td::uint32 serialized_size() const { UNREACHABLE(); } + td::Result> create_encryptor() const { + UNREACHABLE(); + } bool operator==(const Empty &with) const { return false; } @@ -320,6 +327,7 @@ class Ed25519 { } tl_object_ptr pub_tl() const; pubkeys::Ed25519 pub() const; + td::Result> create_decryptor() const; static Ed25519 random(); }; @@ -363,6 +371,7 @@ class AES { pubkeys::AES pub() const { return pubkeys::AES{data_}; } + td::Result> create_decryptor() const; }; class Unenc { @@ -397,6 +406,7 @@ class Unenc { pubkeys::Unenc pub() const { return pubkeys::Unenc{data_.clone()}; } + td::Result> create_decryptor() const; }; class Overlay { @@ -431,6 +441,7 @@ class Overlay { pubkeys::Overlay pub() const { return pubkeys::Overlay{data_.clone()}; } + td::Result> create_decryptor() const; }; } // namespace privkeys @@ -454,6 +465,9 @@ class PrivateKey { PublicKey pub() const { UNREACHABLE(); } + td::Result> create_decryptor() const { + UNREACHABLE(); + } }; td::Variant priv_key_{Empty{}}; diff --git a/overlay/overlay.cpp b/overlay/overlay.cpp index e93d698a..345d18e6 100644 --- a/overlay/overlay.cpp +++ b/overlay/overlay.cpp @@ -321,11 +321,14 @@ void OverlayImpl::alarm() { } if (next_dht_query_ && next_dht_query_.is_in_past() && overlay_type_ == OverlayType::Public) { next_dht_query_ = td::Timestamp::never(); - auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result res) { - td::actor::send_closure(SelfId, &OverlayImpl::receive_dht_nodes, std::move(res), true); - }); - td::actor::send_closure(dht_node_, &dht::Dht::get_value, dht::DhtKey{overlay_id_.pubkey_hash(), "nodes", 0}, - std::move(P)); + std::function callback = [SelfId = actor_id(this)](dht::DhtValue value) { + td::actor::send_closure(SelfId, &OverlayImpl::receive_dht_nodes, std::move(value)); + }; + td::Promise on_finish = [SelfId = actor_id(this)](td::Result R) { + td::actor::send_closure(SelfId, &OverlayImpl::dht_lookup_finished, R.move_as_status()); + }; + td::actor::send_closure(dht_node_, &dht::Dht::get_value_many, dht::DhtKey{overlay_id_.pubkey_hash(), "nodes", 0}, + std::move(callback), std::move(on_finish)); } if (update_db_at_.is_in_past() && overlay_type_ == OverlayType::Public) { std::vector vec; @@ -350,30 +353,30 @@ void OverlayImpl::alarm() { } } -void OverlayImpl::receive_dht_nodes(td::Result res, bool dummy) { +void OverlayImpl::receive_dht_nodes(dht::DhtValue v) { CHECK(overlay_type_ == OverlayType::Public); - if (res.is_ok()) { - auto v = res.move_as_ok(); - auto R = fetch_tl_object(v.value().clone(), true); - if (R.is_ok()) { - auto r = R.move_as_ok(); - VLOG(OVERLAY_INFO) << this << ": received " << r->nodes_.size() << " nodes from overlay"; - VLOG(OVERLAY_EXTRA_DEBUG) << this << ": nodes: " << ton_api::to_string(r); - std::vector nodes; - for (auto &n : r->nodes_) { - auto N = OverlayNode::create(n); - if (N.is_ok()) { - nodes.emplace_back(N.move_as_ok()); - } + auto R = fetch_tl_object(v.value().clone(), true); + if (R.is_ok()) { + auto r = R.move_as_ok(); + VLOG(OVERLAY_INFO) << this << ": received " << r->nodes_.size() << " nodes from overlay"; + VLOG(OVERLAY_EXTRA_DEBUG) << this << ": nodes: " << ton_api::to_string(r); + std::vector nodes; + for (auto &n : r->nodes_) { + auto N = OverlayNode::create(n); + if (N.is_ok()) { + nodes.emplace_back(N.move_as_ok()); } - add_peers(std::move(nodes)); - } else { - VLOG(OVERLAY_WARNING) << this << ": incorrect value in DHT for overlay nodes: " << R.move_as_error(); } + add_peers(std::move(nodes)); } else { - VLOG(OVERLAY_NOTICE) << this << ": can not get value from DHT: " << res.move_as_error(); + VLOG(OVERLAY_WARNING) << this << ": incorrect value in DHT for overlay nodes: " << R.move_as_error(); } +} +void OverlayImpl::dht_lookup_finished(td::Status S) { + if (S.is_error()) { + VLOG(OVERLAY_NOTICE) << this << ": can not get value from DHT: " << S; + } if (!(next_dht_store_query_ && next_dht_store_query_.is_in_past())) { finish_dht_query(); return; diff --git a/overlay/overlay.hpp b/overlay/overlay.hpp index 8cf9e9b0..b08aaf46 100644 --- a/overlay/overlay.hpp +++ b/overlay/overlay.hpp @@ -206,7 +206,8 @@ class OverlayImpl : public Overlay { } void update_member_certificate(OverlayMemberCertificate cert) override; - void receive_dht_nodes(td::Result res, bool dummy); + void receive_dht_nodes(dht::DhtValue v); + void dht_lookup_finished(td::Status S); void update_dht_nodes(OverlayNode node); void update_neighbours(td::uint32 nodes_to_change); diff --git a/tdutils/td/utils/Status.h b/tdutils/td/utils/Status.h index 9c4f1b7d..8bc210db 100644 --- a/tdutils/td/utils/Status.h +++ b/tdutils/td/utils/Status.h @@ -555,6 +555,12 @@ class Result { }; return status_.move_as_error_suffix(suffix); } + Status move_as_status() TD_WARN_UNUSED_RESULT { + if (status_.is_error()) { + return move_as_error(); + } + return Status::OK(); + } const T &ok() const { LOG_CHECK(status_.is_ok()) << status_; return value_;