mirror of
				https://github.com/ton-blockchain/ton
				synced 2025-03-09 15:40:10 +00:00 
			
		
		
		
	Add network id to dht (#559)
Co-authored-by: SpyCheese <mikle98@yandex.ru>
This commit is contained in:
		
							parent
							
								
									15cdfb0462
								
							
						
					
					
						commit
						3ff50f5f47
					
				
					 15 changed files with 231 additions and 172 deletions
				
			
		| 
						 | 
				
			
			@ -66,7 +66,7 @@ td::uint32 DhtBucket::active_cnt() {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
td::Status DhtBucket::add_full_node(DhtKeyId id, DhtNode newnode, td::actor::ActorId<adnl::Adnl> adnl,
 | 
			
		||||
                                    adnl::AdnlNodeIdShort self_id) {
 | 
			
		||||
                                    adnl::AdnlNodeIdShort self_id, td::int32 our_network_id) {
 | 
			
		||||
  for (auto &node : active_nodes_) {
 | 
			
		||||
    if (node && node->get_key() == id) {
 | 
			
		||||
      return node->update_value(std::move(newnode), adnl, self_id);
 | 
			
		||||
| 
						 | 
				
			
			@ -78,7 +78,8 @@ td::Status DhtBucket::add_full_node(DhtKeyId id, DhtNode newnode, td::actor::Act
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  TRY_RESULT_PREFIX(N, DhtRemoteNode::create(std::move(newnode), max_missed_pings_), "failed to add new node: ");
 | 
			
		||||
  TRY_RESULT_PREFIX(N, DhtRemoteNode::create(std::move(newnode), max_missed_pings_, our_network_id),
 | 
			
		||||
                    "failed to add new node: ");
 | 
			
		||||
 | 
			
		||||
  for (auto &node : backup_nodes_) {
 | 
			
		||||
    if (node == nullptr) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -51,7 +51,7 @@ class DhtBucket {
 | 
			
		|||
  }
 | 
			
		||||
  td::uint32 active_cnt();
 | 
			
		||||
  td::Status add_full_node(DhtKeyId id, DhtNode node, td::actor::ActorId<adnl::Adnl> adnl,
 | 
			
		||||
                           adnl::AdnlNodeIdShort self_id);
 | 
			
		||||
                           adnl::AdnlNodeIdShort self_id, td::int32 our_network_id);
 | 
			
		||||
  void check(bool client_only, td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<DhtMember> node,
 | 
			
		||||
             adnl::AdnlNodeIdShort src);
 | 
			
		||||
  void receive_ping(DhtKeyId id, DhtNode result, td::actor::ActorId<adnl::Adnl> adnl, adnl::AdnlNodeIdShort self_id);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,6 +46,7 @@ class DhtMemberImpl : public DhtMember {
 | 
			
		|||
  DhtKeyId key_;
 | 
			
		||||
  td::uint32 k_;
 | 
			
		||||
  td::uint32 a_;
 | 
			
		||||
  td::int32 network_id_{-1};
 | 
			
		||||
  td::uint32 max_cache_time_ = 60;
 | 
			
		||||
  td::uint32 max_cache_size_ = 100;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -138,8 +139,17 @@ class DhtMemberImpl : public DhtMember {
 | 
			
		|||
 | 
			
		||||
 public:
 | 
			
		||||
  DhtMemberImpl(adnl::AdnlNodeIdShort id, std::string db_root, td::actor::ActorId<keyring::Keyring> keyring,
 | 
			
		||||
                td::actor::ActorId<adnl::Adnl> adnl, td::uint32 k, td::uint32 a = 3, bool client_only = false)
 | 
			
		||||
      : id_(id), key_{id_}, k_(k), a_(a), db_root_(db_root), keyring_(keyring), adnl_(adnl), client_only_(client_only) {
 | 
			
		||||
                td::actor::ActorId<adnl::Adnl> adnl, td::int32 network_id, td::uint32 k, td::uint32 a = 3,
 | 
			
		||||
                bool client_only = false)
 | 
			
		||||
      : id_(id)
 | 
			
		||||
      , key_{id_}
 | 
			
		||||
      , k_(k)
 | 
			
		||||
      , a_(a)
 | 
			
		||||
      , network_id_(network_id)
 | 
			
		||||
      , db_root_(db_root)
 | 
			
		||||
      , keyring_(keyring)
 | 
			
		||||
      , adnl_(adnl)
 | 
			
		||||
      , client_only_(client_only) {
 | 
			
		||||
    for (size_t i = 0; i < 256; i++) {
 | 
			
		||||
      buckets_.emplace_back(k_);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,31 +23,46 @@ namespace ton {
 | 
			
		|||
 | 
			
		||||
namespace dht {
 | 
			
		||||
 | 
			
		||||
td::Status DhtNode::update(tl_object_ptr<ton_api::dht_node> obj) {
 | 
			
		||||
td::Status DhtNode::update(tl_object_ptr<ton_api::dht_node> obj, td::int32 our_network_id) {
 | 
			
		||||
  if (version_ && obj->version_ <= version_) {
 | 
			
		||||
    return td::Status::Error(ErrorCode::notready, "too old version");
 | 
			
		||||
  }
 | 
			
		||||
  auto signature = std::move(obj->signature_);
 | 
			
		||||
  auto B = serialize_tl_object(obj, true);
 | 
			
		||||
 | 
			
		||||
  td::BufferSlice signature;
 | 
			
		||||
  td::int32 network_id = -1;
 | 
			
		||||
  if (obj->signature_.size() == 64) {
 | 
			
		||||
    signature = std::move(obj->signature_);
 | 
			
		||||
  } else if (obj->signature_.size() == 64 + 4) {
 | 
			
		||||
    signature = td::BufferSlice{obj->signature_.as_slice().remove_prefix(4)};
 | 
			
		||||
    network_id = *(td::uint32 *)obj->signature_.as_slice().remove_suffix(64).data();
 | 
			
		||||
  } else {
 | 
			
		||||
    return td::Status::Error(ErrorCode::notready, "invalid length of signature");
 | 
			
		||||
  }
 | 
			
		||||
  if (network_id != our_network_id && network_id != -1 && our_network_id != -1) {
 | 
			
		||||
    // Remove (network_id != -1 && our_network_id != -1) after network update
 | 
			
		||||
    return td::Status::Error(ErrorCode::notready, PSTRING() << "wrong network id (expected " << our_network_id
 | 
			
		||||
                                                            << ", found " << network_id << ")");
 | 
			
		||||
  }
 | 
			
		||||
  TRY_RESULT(pub, adnl::AdnlNodeIdFull::create(obj->id_));
 | 
			
		||||
  TRY_RESULT(addr_list, adnl::AdnlAddressList::create(std::move(obj->addr_list_)));
 | 
			
		||||
 | 
			
		||||
  if (!addr_list.public_only()) {
 | 
			
		||||
    return td::Status::Error(ErrorCode::notready, "dht node must have only public addresses");
 | 
			
		||||
  }
 | 
			
		||||
  if (!addr_list.size()) {
 | 
			
		||||
    return td::Status::Error(ErrorCode::notready, "dht node must have >0 addresses");
 | 
			
		||||
  }
 | 
			
		||||
  DhtNode new_node{std::move(pub), std::move(addr_list), obj->version_, network_id, std::move(signature)};
 | 
			
		||||
  TRY_STATUS(new_node.check_signature());
 | 
			
		||||
 | 
			
		||||
  TRY_RESULT(E, pub.pubkey().create_encryptor());
 | 
			
		||||
  TRY_STATUS(E->check_signature(B.as_slice(), signature.as_slice()));
 | 
			
		||||
 | 
			
		||||
  id_ = pub;
 | 
			
		||||
  addr_list_ = addr_list;
 | 
			
		||||
  version_ = obj->version_;
 | 
			
		||||
  signature_ = td::SharedSlice(signature.as_slice());
 | 
			
		||||
  *this = std::move(new_node);
 | 
			
		||||
  return td::Status::OK();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
td::Status DhtNode::check_signature() const {
 | 
			
		||||
  TRY_RESULT(enc, id_.pubkey().create_encryptor());
 | 
			
		||||
  auto node2 = clone();
 | 
			
		||||
  node2.signature_ = {};
 | 
			
		||||
  TRY_STATUS_PREFIX(enc->check_signature(serialize_tl_object(node2.tl(), true).as_slice(), signature_.as_slice()),
 | 
			
		||||
                    "bad node signature: ");
 | 
			
		||||
  return td::Status::OK();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,6 +22,8 @@
 | 
			
		|||
#include "adnl/adnl-address-list.hpp"
 | 
			
		||||
 | 
			
		||||
#include "dht-types.h"
 | 
			
		||||
#include "auto/tl/ton_api.hpp"
 | 
			
		||||
#include "td/utils/overloaded.h"
 | 
			
		||||
 | 
			
		||||
namespace ton {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -32,26 +34,26 @@ class DhtNode {
 | 
			
		|||
  adnl::AdnlNodeIdFull id_;
 | 
			
		||||
  adnl::AdnlAddressList addr_list_;
 | 
			
		||||
  td::int32 version_{0};
 | 
			
		||||
  td::int32 network_id_{-1};
 | 
			
		||||
  td::SharedSlice signature_;
 | 
			
		||||
 | 
			
		||||
 public:
 | 
			
		||||
  DhtNode() {
 | 
			
		||||
  DhtNode() = default;
 | 
			
		||||
  DhtNode(adnl::AdnlNodeIdFull id, adnl::AdnlAddressList addr_list, td::int32 version, td::int32 network_id, td::BufferSlice signature)
 | 
			
		||||
      : id_(id), addr_list_(addr_list), version_(version), network_id_(network_id), signature_(signature.as_slice()) {
 | 
			
		||||
  }
 | 
			
		||||
  DhtNode(adnl::AdnlNodeIdFull id, adnl::AdnlAddressList addr_list, td::int32 version, td::BufferSlice signature)
 | 
			
		||||
      : id_(id), addr_list_(addr_list), version_(version), signature_(signature.as_slice()) {
 | 
			
		||||
  DhtNode(adnl::AdnlNodeIdFull id, adnl::AdnlAddressList addr_list, td::int32 version, td::int32 network_id, td::SharedSlice signature)
 | 
			
		||||
      : id_(id), addr_list_(addr_list), version_(version), network_id_(network_id), signature_(std::move(signature)) {
 | 
			
		||||
  }
 | 
			
		||||
  DhtNode(adnl::AdnlNodeIdFull id, adnl::AdnlAddressList addr_list, td::int32 version, td::SharedSlice signature)
 | 
			
		||||
      : id_(id), addr_list_(addr_list), version_(version), signature_(std::move(signature)) {
 | 
			
		||||
  }
 | 
			
		||||
  static td::Result<DhtNode> create(tl_object_ptr<ton_api::dht_node> obj) {
 | 
			
		||||
  static td::Result<DhtNode> create(tl_object_ptr<ton_api::dht_node> obj, td::int32 our_network_id) {
 | 
			
		||||
    if (obj->version_ == 0) {
 | 
			
		||||
      return td::Status::Error(ErrorCode::protoviolation, "zero version");
 | 
			
		||||
    }
 | 
			
		||||
    DhtNode n;
 | 
			
		||||
    TRY_STATUS(n.update(std::move(obj)));
 | 
			
		||||
    TRY_STATUS(n.update(std::move(obj), our_network_id));
 | 
			
		||||
    return std::move(n);
 | 
			
		||||
  }
 | 
			
		||||
  td::Status update(tl_object_ptr<ton_api::dht_node> obj);
 | 
			
		||||
  td::Status update(tl_object_ptr<ton_api::dht_node> obj, td::int32 our_network_id);
 | 
			
		||||
  DhtKeyId get_key() const {
 | 
			
		||||
    CHECK(!id_.empty());
 | 
			
		||||
    return DhtKeyId{id_.compute_short_id()};
 | 
			
		||||
| 
						 | 
				
			
			@ -68,20 +70,30 @@ class DhtNode {
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  tl_object_ptr<ton_api::dht_node> tl() const {
 | 
			
		||||
    return create_tl_object<ton_api::dht_node>(id_.tl(), addr_list_.tl(), version_, signature_.clone_as_buffer_slice());
 | 
			
		||||
    td::BufferSlice signature_ext;
 | 
			
		||||
    if (network_id_ == -1) {
 | 
			
		||||
      signature_ext = signature_.clone_as_buffer_slice();
 | 
			
		||||
    } else {
 | 
			
		||||
      signature_ext = td::BufferSlice{4 + signature_.size()};
 | 
			
		||||
      td::MutableSlice s = signature_ext.as_slice();
 | 
			
		||||
      s.copy_from(td::Slice(reinterpret_cast<const td::uint8 *>(&network_id_), 4));
 | 
			
		||||
      s.remove_prefix(4);
 | 
			
		||||
      s.copy_from(signature_.as_slice());
 | 
			
		||||
    }
 | 
			
		||||
    return create_tl_object<ton_api::dht_node>(id_.tl(), addr_list_.tl(), version_, std::move(signature_ext));
 | 
			
		||||
  }
 | 
			
		||||
  DhtNode clone() const {
 | 
			
		||||
    return DhtNode{id_, addr_list_, version_, signature_.clone()};
 | 
			
		||||
    return DhtNode{id_, addr_list_, version_, network_id_, signature_.clone()};
 | 
			
		||||
  }
 | 
			
		||||
  td::Status check_signature() const;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class DhtNodesList {
 | 
			
		||||
 public:
 | 
			
		||||
  DhtNodesList() {
 | 
			
		||||
  }
 | 
			
		||||
  DhtNodesList(tl_object_ptr<ton_api::dht_nodes> R) {
 | 
			
		||||
  DhtNodesList() = default;
 | 
			
		||||
  DhtNodesList(tl_object_ptr<ton_api::dht_nodes> R, td::int32 our_network_id) {
 | 
			
		||||
    for (auto &n : R->nodes_) {
 | 
			
		||||
      auto N = DhtNode::create(std::move(n));
 | 
			
		||||
      auto N = DhtNode::create(std::move(n), our_network_id);
 | 
			
		||||
      if (N.is_ok()) {
 | 
			
		||||
        list_.emplace_back(N.move_as_ok());
 | 
			
		||||
      } else {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,14 +20,11 @@
 | 
			
		|||
 | 
			
		||||
#include "td/utils/tl_storers.h"
 | 
			
		||||
#include "td/utils/crypto.h"
 | 
			
		||||
#include "td/utils/tl_parsers.h"
 | 
			
		||||
#include "td/utils/Random.h"
 | 
			
		||||
#include "td/utils/overloaded.h"
 | 
			
		||||
 | 
			
		||||
#include "td/utils/format.h"
 | 
			
		||||
 | 
			
		||||
#include "keys/encryptor.h"
 | 
			
		||||
 | 
			
		||||
#include "auto/tl/ton_api.hpp"
 | 
			
		||||
 | 
			
		||||
#include "dht-query.hpp"
 | 
			
		||||
| 
						 | 
				
			
			@ -123,7 +120,7 @@ void DhtQueryFindNodes::on_result(td::Result<td::BufferSlice> R, adnl::AdnlNodeI
 | 
			
		|||
    VLOG(DHT_WARNING) << this << ": incorrect result on dht.findNodes query from " << dst << ": "
 | 
			
		||||
                      << Res.move_as_error();
 | 
			
		||||
  } else {
 | 
			
		||||
    add_nodes(DhtNodesList{Res.move_as_ok()});
 | 
			
		||||
    add_nodes(DhtNodesList{Res.move_as_ok(), our_network_id()});
 | 
			
		||||
  }
 | 
			
		||||
  finish_query();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -185,27 +182,29 @@ void DhtQueryFindValue::on_result(td::Result<td::BufferSlice> R, adnl::AdnlNodeI
 | 
			
		|||
 | 
			
		||||
  auto A = Res.move_as_ok();
 | 
			
		||||
  ton_api::downcast_call(
 | 
			
		||||
      *A.get(), td::overloaded(
 | 
			
		||||
                    [&](ton_api::dht_valueFound &v) {
 | 
			
		||||
                      auto valueR = DhtValue::create(std::move(v.value_), true);
 | 
			
		||||
                      if (valueR.is_error()) {
 | 
			
		||||
                        VLOG(DHT_WARNING) << this << ": received incorrect dht answer on find value query from " << dst
 | 
			
		||||
                                          << ": " << valueR.move_as_error();
 | 
			
		||||
                        return;
 | 
			
		||||
                      }
 | 
			
		||||
                      auto value = valueR.move_as_ok();
 | 
			
		||||
                      if (value.key_id() != key_) {
 | 
			
		||||
                        VLOG(DHT_WARNING) << this << ": received value for bad key on find value query from " << dst;
 | 
			
		||||
                        return;
 | 
			
		||||
                      }
 | 
			
		||||
                      if (!value.check_is_acceptable()) {
 | 
			
		||||
                        send_get_nodes = true;
 | 
			
		||||
                        return;
 | 
			
		||||
                      }
 | 
			
		||||
                      promise_.set_value(std::move(value));
 | 
			
		||||
                      need_stop = true;
 | 
			
		||||
                    },
 | 
			
		||||
                    [&](ton_api::dht_valueNotFound &v) { add_nodes(DhtNodesList{std::move(v.nodes_)}); }));
 | 
			
		||||
      *A, td::overloaded(
 | 
			
		||||
              [&](ton_api::dht_valueFound &v) {
 | 
			
		||||
                auto valueR = DhtValue::create(std::move(v.value_), true);
 | 
			
		||||
                if (valueR.is_error()) {
 | 
			
		||||
                  VLOG(DHT_WARNING) << this << ": received incorrect dht answer on find value query from " << dst
 | 
			
		||||
                                    << ": " << valueR.move_as_error();
 | 
			
		||||
                  return;
 | 
			
		||||
                }
 | 
			
		||||
                auto value = valueR.move_as_ok();
 | 
			
		||||
                if (value.key_id() != key_) {
 | 
			
		||||
                  VLOG(DHT_WARNING) << this << ": received value for bad key on find value query from " << dst;
 | 
			
		||||
                  return;
 | 
			
		||||
                }
 | 
			
		||||
                if (!value.check_is_acceptable()) {
 | 
			
		||||
                  send_get_nodes = true;
 | 
			
		||||
                  return;
 | 
			
		||||
                }
 | 
			
		||||
                promise_.set_value(std::move(value));
 | 
			
		||||
                need_stop = true;
 | 
			
		||||
              },
 | 
			
		||||
              [&](ton_api::dht_valueNotFound &v) {
 | 
			
		||||
                add_nodes(DhtNodesList{std::move(v.nodes_), our_network_id()});
 | 
			
		||||
              }));
 | 
			
		||||
  if (need_stop) {
 | 
			
		||||
    stop();
 | 
			
		||||
  } else if (send_get_nodes) {
 | 
			
		||||
| 
						 | 
				
			
			@ -229,7 +228,7 @@ void DhtQueryFindValue::on_result_nodes(td::Result<td::BufferSlice> R, adnl::Adn
 | 
			
		|||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  auto r = Res.move_as_ok();
 | 
			
		||||
  add_nodes(DhtNodesList{create_tl_object<ton_api::dht_nodes>(std::move(r->nodes_))});
 | 
			
		||||
  add_nodes(DhtNodesList{create_tl_object<ton_api::dht_nodes>(std::move(r->nodes_)), our_network_id()});
 | 
			
		||||
  finish_query();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -238,12 +237,13 @@ void DhtQueryFindValue::finish(DhtNodesList list) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
DhtQueryStore::DhtQueryStore(DhtValue key_value, DhtMember::PrintId print_id, adnl::AdnlNodeIdShort src,
 | 
			
		||||
                             DhtNodesList list, td::uint32 k, td::uint32 a, DhtNode self, bool client_only,
 | 
			
		||||
                             td::actor::ActorId<DhtMember> node, td::actor::ActorId<adnl::Adnl> adnl,
 | 
			
		||||
                             DhtNodesList list, td::uint32 k, td::uint32 a, td::int32 our_network_id, DhtNode self,
 | 
			
		||||
                             bool client_only, td::actor::ActorId<DhtMember> node, td::actor::ActorId<adnl::Adnl> adnl,
 | 
			
		||||
                             td::Promise<td::Unit> promise)
 | 
			
		||||
    : print_id_(print_id)
 | 
			
		||||
    , k_(k)
 | 
			
		||||
    , a_(a)
 | 
			
		||||
    , our_network_id_(our_network_id)
 | 
			
		||||
    , promise_(std::move(promise))
 | 
			
		||||
    , value_(std::move(key_value))
 | 
			
		||||
    , list_(std::move(list))
 | 
			
		||||
| 
						 | 
				
			
			@ -261,7 +261,8 @@ void DhtQueryStore::start_up() {
 | 
			
		|||
 | 
			
		||||
  auto key = value_.key_id();
 | 
			
		||||
  auto A = td::actor::create_actor<DhtQueryFindNodes>("FindNodesQuery", key, print_id_, src_, std::move(list_), k_, a_,
 | 
			
		||||
                                                      self_.clone(), client_only_, node_, adnl_, std::move(P));
 | 
			
		||||
                                                      our_network_id_, self_.clone(), client_only_, node_, adnl_,
 | 
			
		||||
                                                      std::move(P));
 | 
			
		||||
  A.release();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -323,12 +324,13 @@ void DhtQueryStore::store_ready(td::Result<td::BufferSlice> R) {
 | 
			
		|||
 | 
			
		||||
DhtQueryRegisterReverseConnection::DhtQueryRegisterReverseConnection(
 | 
			
		||||
    DhtKeyId key_id, adnl::AdnlNodeIdFull client, td::uint32 ttl, td::BufferSlice signature,
 | 
			
		||||
    DhtMember::PrintId print_id, adnl::AdnlNodeIdShort src, DhtNodesList list, td::uint32 k, td::uint32 a, DhtNode self,
 | 
			
		||||
    bool client_only, td::actor::ActorId<DhtMember> node, td::actor::ActorId<adnl::Adnl> adnl,
 | 
			
		||||
    td::Promise<td::Unit> promise)
 | 
			
		||||
    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<DhtMember> node,
 | 
			
		||||
    td::actor::ActorId<adnl::Adnl> adnl, td::Promise<td::Unit> promise)
 | 
			
		||||
    : print_id_(print_id)
 | 
			
		||||
    , k_(k)
 | 
			
		||||
    , a_(a)
 | 
			
		||||
    , our_network_id_(our_network_id)
 | 
			
		||||
    , promise_(std::move(promise))
 | 
			
		||||
    , key_id_(key_id)
 | 
			
		||||
    , list_(std::move(list))
 | 
			
		||||
| 
						 | 
				
			
			@ -346,7 +348,8 @@ void DhtQueryRegisterReverseConnection::start_up() {
 | 
			
		|||
  });
 | 
			
		||||
 | 
			
		||||
  auto A = td::actor::create_actor<DhtQueryFindNodes>("FindNodesQuery", key_id_, print_id_, src_, std::move(list_), k_,
 | 
			
		||||
                                                      a_, self_.clone(), client_only_, node_, adnl_, std::move(P));
 | 
			
		||||
                                                      a_, our_network_id_, self_.clone(), client_only_, node_, adnl_,
 | 
			
		||||
                                                      std::move(P));
 | 
			
		||||
  A.release();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -437,7 +440,7 @@ void DhtQueryRequestReversePing::on_result(td::Result<td::BufferSlice> R, adnl::
 | 
			
		|||
                                   stop();
 | 
			
		||||
                                 },
 | 
			
		||||
                                 [&](ton_api::dht_clientNotFound &v) {
 | 
			
		||||
                                   add_nodes(DhtNodesList{std::move(v.nodes_)});
 | 
			
		||||
                                   add_nodes(DhtNodesList{std::move(v.nodes_), our_network_id()});
 | 
			
		||||
                                   finish_query();
 | 
			
		||||
                                 }));
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,7 +45,7 @@ class DhtQuery : public td::actor::Actor {
 | 
			
		|||
 | 
			
		||||
 public:
 | 
			
		||||
  DhtQuery(DhtKeyId key, DhtMember::PrintId print_id, adnl::AdnlNodeIdShort src, DhtNodesList list, td::uint32 k,
 | 
			
		||||
           td::uint32 a, DhtNode self, bool client_only, td::actor::ActorId<DhtMember> node,
 | 
			
		||||
           td::uint32 a, td::int32 our_network_id, DhtNode self, bool client_only, td::actor::ActorId<DhtMember> node,
 | 
			
		||||
           td::actor::ActorId<adnl::Adnl> adnl)
 | 
			
		||||
      : key_(key)
 | 
			
		||||
      , self_(std::move(self))
 | 
			
		||||
| 
						 | 
				
			
			@ -54,6 +54,7 @@ class DhtQuery : public td::actor::Actor {
 | 
			
		|||
      , src_(src)
 | 
			
		||||
      , k_(k)
 | 
			
		||||
      , a_(a)
 | 
			
		||||
      , our_network_id_(our_network_id)
 | 
			
		||||
      , node_(node)
 | 
			
		||||
      , adnl_(adnl) {
 | 
			
		||||
    add_nodes(std::move(list));
 | 
			
		||||
| 
						 | 
				
			
			@ -77,6 +78,9 @@ class DhtQuery : public td::actor::Actor {
 | 
			
		|||
  td::uint32 get_k() const {
 | 
			
		||||
    return k_;
 | 
			
		||||
  }
 | 
			
		||||
  td::int32 our_network_id() const {
 | 
			
		||||
    return our_network_id_;
 | 
			
		||||
  }
 | 
			
		||||
  void start_up() override {
 | 
			
		||||
    send_queries();
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -91,6 +95,7 @@ class DhtQuery : public td::actor::Actor {
 | 
			
		|||
  std::set<DhtKeyId> pending_ids_;
 | 
			
		||||
  td::uint32 k_;
 | 
			
		||||
  td::uint32 a_;
 | 
			
		||||
  td::int32 our_network_id_;
 | 
			
		||||
  td::actor::ActorId<DhtMember> node_;
 | 
			
		||||
  td::uint32 active_queries_ = 0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -104,9 +109,10 @@ class DhtQueryFindNodes : public DhtQuery {
 | 
			
		|||
 | 
			
		||||
 public:
 | 
			
		||||
  DhtQueryFindNodes(DhtKeyId key, DhtMember::PrintId print_id, adnl::AdnlNodeIdShort src, DhtNodesList list,
 | 
			
		||||
                    td::uint32 k, td::uint32 a, DhtNode self, bool client_only, td::actor::ActorId<DhtMember> node,
 | 
			
		||||
                    td::actor::ActorId<adnl::Adnl> adnl, td::Promise<DhtNodesList> promise)
 | 
			
		||||
      : DhtQuery(key, print_id, src, std::move(list), k, a, std::move(self), client_only, node, adnl)
 | 
			
		||||
                    td::uint32 k, td::uint32 a, td::int32 our_network_id, DhtNode self, bool client_only,
 | 
			
		||||
                    td::actor::ActorId<DhtMember> node, td::actor::ActorId<adnl::Adnl> adnl,
 | 
			
		||||
                    td::Promise<DhtNodesList> promise)
 | 
			
		||||
      : DhtQuery(key, print_id, src, std::move(list), k, a, our_network_id, std::move(self), client_only, node, adnl)
 | 
			
		||||
      , promise_(std::move(promise)) {
 | 
			
		||||
  }
 | 
			
		||||
  void send_one_query(adnl::AdnlNodeIdShort id) override;
 | 
			
		||||
| 
						 | 
				
			
			@ -123,9 +129,10 @@ class DhtQueryFindValue : public DhtQuery {
 | 
			
		|||
 | 
			
		||||
 public:
 | 
			
		||||
  DhtQueryFindValue(DhtKeyId key, DhtMember::PrintId print_id, adnl::AdnlNodeIdShort src, DhtNodesList list,
 | 
			
		||||
                    td::uint32 k, td::uint32 a, DhtNode self, bool client_only, td::actor::ActorId<DhtMember> node,
 | 
			
		||||
                    td::actor::ActorId<adnl::Adnl> adnl, td::Promise<DhtValue> promise)
 | 
			
		||||
      : DhtQuery(key, print_id, src, std::move(list), k, a, std::move(self), client_only, node, adnl)
 | 
			
		||||
                    td::uint32 k, td::uint32 a, td::int32 our_network_id, DhtNode self, bool client_only,
 | 
			
		||||
                    td::actor::ActorId<DhtMember> node, td::actor::ActorId<adnl::Adnl> adnl,
 | 
			
		||||
                    td::Promise<DhtValue> promise)
 | 
			
		||||
      : DhtQuery(key, print_id, src, std::move(list), k, a, our_network_id, std::move(self), client_only, node, adnl)
 | 
			
		||||
      , promise_(std::move(promise)) {
 | 
			
		||||
  }
 | 
			
		||||
  void send_one_query(adnl::AdnlNodeIdShort id) override;
 | 
			
		||||
| 
						 | 
				
			
			@ -143,6 +150,7 @@ class DhtQueryStore : public td::actor::Actor {
 | 
			
		|||
  DhtMember::PrintId print_id_;
 | 
			
		||||
  td::uint32 k_;
 | 
			
		||||
  td::uint32 a_;
 | 
			
		||||
  td::int32 our_network_id_;
 | 
			
		||||
  td::Promise<td::Unit> promise_;
 | 
			
		||||
  td::actor::ActorId<DhtMember> node_;
 | 
			
		||||
  td::actor::ActorId<adnl::Adnl> adnl_;
 | 
			
		||||
| 
						 | 
				
			
			@ -157,7 +165,7 @@ class DhtQueryStore : public td::actor::Actor {
 | 
			
		|||
 | 
			
		||||
 public:
 | 
			
		||||
  DhtQueryStore(DhtValue key_value, DhtMember::PrintId print_id, adnl::AdnlNodeIdShort src, DhtNodesList list,
 | 
			
		||||
                td::uint32 k, td::uint32 a, DhtNode self, bool client_only, td::actor::ActorId<DhtMember> node,
 | 
			
		||||
                td::uint32 k, td::uint32 a, td::int32 our_network_id, DhtNode self, bool client_only, td::actor::ActorId<DhtMember> node,
 | 
			
		||||
                td::actor::ActorId<adnl::Adnl> adnl, td::Promise<td::Unit> promise);
 | 
			
		||||
  void send_stores(td::Result<DhtNodesList> res);
 | 
			
		||||
  void store_ready(td::Result<td::BufferSlice> res);
 | 
			
		||||
| 
						 | 
				
			
			@ -172,6 +180,7 @@ class DhtQueryRegisterReverseConnection : public td::actor::Actor {
 | 
			
		|||
  DhtMember::PrintId print_id_;
 | 
			
		||||
  td::uint32 k_;
 | 
			
		||||
  td::uint32 a_;
 | 
			
		||||
  td::int32 our_network_id_;
 | 
			
		||||
  td::Promise<td::Unit> promise_;
 | 
			
		||||
  td::actor::ActorId<DhtMember> node_;
 | 
			
		||||
  td::actor::ActorId<adnl::Adnl> adnl_;
 | 
			
		||||
| 
						 | 
				
			
			@ -188,9 +197,9 @@ class DhtQueryRegisterReverseConnection : public td::actor::Actor {
 | 
			
		|||
 public:
 | 
			
		||||
  DhtQueryRegisterReverseConnection(DhtKeyId key_id, adnl::AdnlNodeIdFull client, td::uint32 ttl,
 | 
			
		||||
                                    td::BufferSlice signature, DhtMember::PrintId print_id, adnl::AdnlNodeIdShort src,
 | 
			
		||||
                                    DhtNodesList list, td::uint32 k, td::uint32 a, DhtNode self, bool client_only,
 | 
			
		||||
                                    td::actor::ActorId<DhtMember> node, td::actor::ActorId<adnl::Adnl> adnl,
 | 
			
		||||
                                    td::Promise<td::Unit> promise);
 | 
			
		||||
                                    DhtNodesList list, td::uint32 k, td::uint32 a, td::int32 our_network_id,
 | 
			
		||||
                                    DhtNode self, bool client_only, td::actor::ActorId<DhtMember> node,
 | 
			
		||||
                                    td::actor::ActorId<adnl::Adnl> adnl, td::Promise<td::Unit> promise);
 | 
			
		||||
  void send_queries(td::Result<DhtNodesList> R);
 | 
			
		||||
  void ready(td::Result<td::BufferSlice> R);
 | 
			
		||||
  void start_up() override;
 | 
			
		||||
| 
						 | 
				
			
			@ -207,10 +216,11 @@ class DhtQueryRequestReversePing : public DhtQuery {
 | 
			
		|||
 public:
 | 
			
		||||
  DhtQueryRequestReversePing(adnl::AdnlNodeIdShort client, adnl::AdnlNode target, td::BufferSlice signature,
 | 
			
		||||
                             DhtMember::PrintId print_id, adnl::AdnlNodeIdShort src, DhtNodesList list, td::uint32 k,
 | 
			
		||||
                             td::uint32 a, DhtNode self, bool client_only, td::actor::ActorId<DhtMember> node,
 | 
			
		||||
                             td::actor::ActorId<adnl::Adnl> adnl, td::Promise<td::Unit> promise)
 | 
			
		||||
                             td::uint32 a, td::int32 our_network_id, DhtNode self, bool client_only,
 | 
			
		||||
                             td::actor::ActorId<DhtMember> node, td::actor::ActorId<adnl::Adnl> adnl,
 | 
			
		||||
                             td::Promise<td::Unit> promise)
 | 
			
		||||
      : DhtQuery(DhtMember::get_reverse_connection_key(client).compute_key_id(), print_id, src, std::move(list), k, a,
 | 
			
		||||
                 std::move(self), client_only, node, adnl)
 | 
			
		||||
                 our_network_id, std::move(self), client_only, node, adnl)
 | 
			
		||||
      , promise_(std::move(promise))
 | 
			
		||||
      , query_(create_serialize_tl_object<ton_api::dht_requestReversePing>(target.tl(), std::move(signature),
 | 
			
		||||
                                                                           client.bits256_value(), k)) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,13 +20,10 @@
 | 
			
		|||
 | 
			
		||||
#include "td/utils/tl_storers.h"
 | 
			
		||||
#include "td/utils/crypto.h"
 | 
			
		||||
#include "td/utils/tl_parsers.h"
 | 
			
		||||
#include "td/utils/Random.h"
 | 
			
		||||
 | 
			
		||||
#include "td/utils/format.h"
 | 
			
		||||
 | 
			
		||||
#include "keys/encryptor.h"
 | 
			
		||||
 | 
			
		||||
#include "auto/tl/ton_api.hpp"
 | 
			
		||||
 | 
			
		||||
#include "dht-remote-node.hpp"
 | 
			
		||||
| 
						 | 
				
			
			@ -51,12 +48,7 @@ td::Status DhtRemoteNode::update_value(DhtNode node, td::actor::ActorId<adnl::Ad
 | 
			
		|||
  if (node.version() <= node_.version()) {
 | 
			
		||||
    return td::Status::OK();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  TRY_RESULT(enc, node.adnl_id().pubkey().create_encryptor());
 | 
			
		||||
  auto tl = node.tl();
 | 
			
		||||
  auto sig = std::move(tl->signature_);
 | 
			
		||||
  TRY_STATUS_PREFIX(enc->check_signature(serialize_tl_object(tl, true).as_slice(), sig.as_slice()),
 | 
			
		||||
                    "bad node signature: ");
 | 
			
		||||
  TRY_STATUS(node.check_signature());
 | 
			
		||||
 | 
			
		||||
  node_ = std::move(node);
 | 
			
		||||
  td::actor::send_closure(adnl, &adnl::Adnl::add_peer, self_id, node_.adnl_id(), node_.addr_list());
 | 
			
		||||
| 
						 | 
				
			
			@ -75,13 +67,13 @@ void DhtRemoteNode::send_ping(bool client_only, td::actor::ActorId<adnl::Adnl> a
 | 
			
		|||
 | 
			
		||||
  td::actor::send_closure(adnl, &adnl::Adnl::add_peer, src, node_.adnl_id(), node_.addr_list());
 | 
			
		||||
 | 
			
		||||
  auto P = td::PromiseCreator::lambda([key = id_, id = node_.adnl_id().compute_short_id(), client_only, node, src,
 | 
			
		||||
                                       adnl](td::Result<DhtNode> R) mutable {
 | 
			
		||||
  auto P = td::PromiseCreator::lambda([key = id_, id = node_.adnl_id().compute_short_id(), client_only, node, src, adnl,
 | 
			
		||||
                                       our_network_id = our_network_id_](td::Result<DhtNode> R) mutable {
 | 
			
		||||
    if (R.is_error()) {
 | 
			
		||||
      LOG(ERROR) << "[dht]: failed to get self node";
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    auto P = td::PromiseCreator::lambda([key, node, adnl](td::Result<td::BufferSlice> R) {
 | 
			
		||||
    auto P = td::PromiseCreator::lambda([key, node, adnl, our_network_id](td::Result<td::BufferSlice> R) {
 | 
			
		||||
      if (R.is_error()) {
 | 
			
		||||
        VLOG(DHT_INFO) << "[dht]: received error for query to " << key << ": " << R.move_as_error();
 | 
			
		||||
        return;
 | 
			
		||||
| 
						 | 
				
			
			@ -89,7 +81,7 @@ void DhtRemoteNode::send_ping(bool client_only, td::actor::ActorId<adnl::Adnl> a
 | 
			
		|||
      auto F = fetch_tl_object<ton_api::dht_node>(R.move_as_ok(), true);
 | 
			
		||||
 | 
			
		||||
      if (F.is_ok()) {
 | 
			
		||||
        auto N = DhtNode::create(F.move_as_ok());
 | 
			
		||||
        auto N = DhtNode::create(F.move_as_ok(), our_network_id);
 | 
			
		||||
        if (N.is_ok()) {
 | 
			
		||||
          td::actor::send_closure(node, &DhtMember::receive_ping, key, N.move_as_ok());
 | 
			
		||||
        } else {
 | 
			
		||||
| 
						 | 
				
			
			@ -123,7 +115,8 @@ adnl::AdnlNodeIdFull DhtRemoteNode::get_full_id() const {
 | 
			
		|||
  return node_.adnl_id();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
td::Result<std::unique_ptr<DhtRemoteNode>> DhtRemoteNode::create(DhtNode node, td::uint32 max_missed_pings) {
 | 
			
		||||
td::Result<std::unique_ptr<DhtRemoteNode>> DhtRemoteNode::create(DhtNode node, td::uint32 max_missed_pings,
 | 
			
		||||
                                                                 td::int32 our_network_id) {
 | 
			
		||||
  TRY_RESULT(enc, node.adnl_id().pubkey().create_encryptor());
 | 
			
		||||
  auto tl = node.tl();
 | 
			
		||||
  auto sig = std::move(tl->signature_);
 | 
			
		||||
| 
						 | 
				
			
			@ -131,7 +124,7 @@ td::Result<std::unique_ptr<DhtRemoteNode>> DhtRemoteNode::create(DhtNode node, t
 | 
			
		|||
  TRY_STATUS_PREFIX(enc->check_signature(serialize_tl_object(tl, true).as_slice(), sig.as_slice()),
 | 
			
		||||
                    "bad node signature: ");
 | 
			
		||||
 | 
			
		||||
  return std::make_unique<DhtRemoteNode>(std::move(node), max_missed_pings);
 | 
			
		||||
  return std::make_unique<DhtRemoteNode>(std::move(node), max_missed_pings, our_network_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // namespace dht
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,6 +40,7 @@ class DhtRemoteNode {
 | 
			
		|||
  DhtNode node_;
 | 
			
		||||
 | 
			
		||||
  td::uint32 max_missed_pings_;
 | 
			
		||||
  td::int32 our_network_id_;
 | 
			
		||||
  td::uint32 missed_pings_ = 0;
 | 
			
		||||
  double last_ping_at_ = 0;
 | 
			
		||||
  double ready_from_ = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -47,12 +48,13 @@ class DhtRemoteNode {
 | 
			
		|||
  td::int32 version_;
 | 
			
		||||
 | 
			
		||||
 public:
 | 
			
		||||
  DhtRemoteNode(DhtNode node, td::uint32 max_missed_pings)
 | 
			
		||||
      : node_(std::move(node)), max_missed_pings_(max_missed_pings) {
 | 
			
		||||
  DhtRemoteNode(DhtNode node, td::uint32 max_missed_pings, td::int32 our_network_id)
 | 
			
		||||
      : node_(std::move(node)), max_missed_pings_(max_missed_pings), our_network_id_(our_network_id) {
 | 
			
		||||
    failed_from_ = td::Time::now_cached();
 | 
			
		||||
    id_ = node_.get_key();
 | 
			
		||||
  }
 | 
			
		||||
  static td::Result<std::unique_ptr<DhtRemoteNode>> create(DhtNode node, td::uint32 max_missed_pings);
 | 
			
		||||
  static td::Result<std::unique_ptr<DhtRemoteNode>> create(DhtNode node, td::uint32 max_missed_pings,
 | 
			
		||||
                                                           td::int32 our_network_id);
 | 
			
		||||
  DhtNode get_node() const {
 | 
			
		||||
    return node_.clone();
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										141
									
								
								dht/dht.cpp
									
										
									
									
									
								
							
							
						
						
									
										141
									
								
								dht/dht.cpp
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -20,7 +20,6 @@
 | 
			
		|||
 | 
			
		||||
#include "td/utils/tl_storers.h"
 | 
			
		||||
#include "td/utils/crypto.h"
 | 
			
		||||
#include "td/utils/tl_parsers.h"
 | 
			
		||||
#include "td/utils/Random.h"
 | 
			
		||||
#include "td/utils/base64.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -28,9 +27,6 @@
 | 
			
		|||
 | 
			
		||||
#include "td/db/RocksDb.h"
 | 
			
		||||
 | 
			
		||||
#include "keys/encryptor.h"
 | 
			
		||||
#include "adnl/utils.hpp"
 | 
			
		||||
 | 
			
		||||
#include "auto/tl/ton_api.hpp"
 | 
			
		||||
 | 
			
		||||
#include "dht.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -44,10 +40,9 @@ namespace dht {
 | 
			
		|||
 | 
			
		||||
td::actor::ActorOwn<DhtMember> DhtMember::create(adnl::AdnlNodeIdShort id, std::string db_root,
 | 
			
		||||
                                                 td::actor::ActorId<keyring::Keyring> keyring,
 | 
			
		||||
                                                 td::actor::ActorId<adnl::Adnl> adnl, td::uint32 k, td::uint32 a,
 | 
			
		||||
                                                 bool client_only) {
 | 
			
		||||
  return td::actor::ActorOwn<DhtMember>(
 | 
			
		||||
      td::actor::create_actor<DhtMemberImpl>("dht", id, db_root, keyring, adnl, k, a, client_only));
 | 
			
		||||
                                                 td::actor::ActorId<adnl::Adnl> adnl, td::int32 network_id,
 | 
			
		||||
                                                 td::uint32 k, td::uint32 a, bool client_only) {
 | 
			
		||||
  return td::actor::create_actor<DhtMemberImpl>("dht", id, db_root, keyring, adnl, network_id, k, a, client_only);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
td::Result<td::actor::ActorOwn<Dht>> Dht::create(adnl::AdnlNodeIdShort id, std::string db_root,
 | 
			
		||||
| 
						 | 
				
			
			@ -57,7 +52,7 @@ td::Result<td::actor::ActorOwn<Dht>> Dht::create(adnl::AdnlNodeIdShort id, std::
 | 
			
		|||
  CHECK(conf->get_k() > 0);
 | 
			
		||||
  CHECK(conf->get_a() > 0);
 | 
			
		||||
 | 
			
		||||
  auto D = DhtMember::create(id, db_root, keyring, adnl, conf->get_k(), conf->get_a());
 | 
			
		||||
  auto D = DhtMember::create(id, db_root, keyring, adnl, conf->get_network_id(), conf->get_k(), conf->get_a());
 | 
			
		||||
  auto &nodes = conf->nodes();
 | 
			
		||||
 | 
			
		||||
  for (auto &node : nodes.list()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -74,7 +69,7 @@ td::Result<td::actor::ActorOwn<Dht>> Dht::create_client(adnl::AdnlNodeIdShort id
 | 
			
		|||
  CHECK(conf->get_k() > 0);
 | 
			
		||||
  CHECK(conf->get_a() > 0);
 | 
			
		||||
 | 
			
		||||
  auto D = DhtMember::create(id, db_root, keyring, adnl, conf->get_k(), conf->get_a(), true);
 | 
			
		||||
  auto D = DhtMember::create(id, db_root, keyring, adnl, conf->get_network_id(), conf->get_k(), conf->get_a(), true);
 | 
			
		||||
  auto &nodes = conf->nodes();
 | 
			
		||||
 | 
			
		||||
  for (auto &node : nodes.list()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -115,12 +110,12 @@ void DhtMemberImpl::start_up() {
 | 
			
		|||
        V.ensure();
 | 
			
		||||
        auto nodes = std::move(V.move_as_ok()->nodes_);
 | 
			
		||||
        auto s = nodes->nodes_.size();
 | 
			
		||||
        DhtNodesList list{std::move(nodes)};
 | 
			
		||||
        DhtNodesList list{std::move(nodes), network_id_};
 | 
			
		||||
        CHECK(list.size() == s);
 | 
			
		||||
        auto &B = buckets_[bit];
 | 
			
		||||
        for (auto &node : list.list()) {
 | 
			
		||||
          auto key = node.get_key();
 | 
			
		||||
          B.add_full_node(key, std::move(node), adnl_, id_);
 | 
			
		||||
          B.add_full_node(key, std::move(node), adnl_, id_, network_id_);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -368,7 +363,7 @@ void DhtMemberImpl::receive_query(adnl::AdnlNodeIdShort src, td::BufferSlice dat
 | 
			
		|||
  {
 | 
			
		||||
    auto R = fetch_tl_prefix<ton_api::dht_query>(data, true);
 | 
			
		||||
    if (R.is_ok()) {
 | 
			
		||||
      auto N = DhtNode::create(std::move(R.move_as_ok()->node_));
 | 
			
		||||
      auto N = DhtNode::create(std::move(R.move_as_ok()->node_), network_id_);
 | 
			
		||||
      if (N.is_ok()) {
 | 
			
		||||
        auto node = N.move_as_ok();
 | 
			
		||||
        auto key = node.get_key();
 | 
			
		||||
| 
						 | 
				
			
			@ -396,7 +391,7 @@ void DhtMemberImpl::receive_query(adnl::AdnlNodeIdShort src, td::BufferSlice dat
 | 
			
		|||
 | 
			
		||||
  VLOG(DHT_EXTRA_DEBUG) << this << ": query to DHT from " << src << ": " << ton_api::to_string(Q);
 | 
			
		||||
 | 
			
		||||
  ton_api::downcast_call(*Q.get(), [&](auto &object) { this->process_query(src, object, std::move(promise)); });
 | 
			
		||||
  ton_api::downcast_call(*Q, [&](auto &object) { this->process_query(src, object, std::move(promise)); });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DhtMemberImpl::add_full_node(DhtKeyId key, DhtNode node) {
 | 
			
		||||
| 
						 | 
				
			
			@ -411,7 +406,7 @@ void DhtMemberImpl::add_full_node(DhtKeyId key, DhtNode node) {
 | 
			
		|||
#endif
 | 
			
		||||
  if (bit < 256) {
 | 
			
		||||
    CHECK(key.get_bit(bit) != key_.get_bit(bit));
 | 
			
		||||
    buckets_[bit].add_full_node(key, std::move(node), adnl_, id_);
 | 
			
		||||
    buckets_[bit].add_full_node(key, std::move(node), adnl_, id_, network_id_);
 | 
			
		||||
  } else {
 | 
			
		||||
    CHECK(key == key_);
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -467,10 +462,11 @@ void DhtMemberImpl::set_value(DhtValue value, td::Promise<td::Unit> promise) {
 | 
			
		|||
 | 
			
		||||
void DhtMemberImpl::get_value_in(DhtKeyId key, td::Promise<DhtValue> result) {
 | 
			
		||||
  auto P = td::PromiseCreator::lambda([key, promise = std::move(result), SelfId = actor_id(this), print_id = print_id(),
 | 
			
		||||
                                       adnl = adnl_, list = get_nearest_nodes(key, k_), k = k_, a = a_, id = id_,
 | 
			
		||||
                                       adnl = adnl_, list = get_nearest_nodes(key, k_), k = k_, a = a_,
 | 
			
		||||
                                       network_id = network_id_, id = id_,
 | 
			
		||||
                                       client_only = client_only_](td::Result<DhtNode> R) mutable {
 | 
			
		||||
    R.ensure();
 | 
			
		||||
    td::actor::create_actor<DhtQueryFindValue>("FindValueQuery", key, print_id, id, std::move(list), k, a,
 | 
			
		||||
    td::actor::create_actor<DhtQueryFindValue>("FindValueQuery", key, print_id, id, std::move(list), k, a, network_id,
 | 
			
		||||
                                               R.move_as_ok(), client_only, SelfId, adnl, std::move(promise))
 | 
			
		||||
        .release();
 | 
			
		||||
  });
 | 
			
		||||
| 
						 | 
				
			
			@ -495,7 +491,7 @@ void DhtMemberImpl::register_reverse_connection(adnl::AdnlNodeIdFull client, td:
 | 
			
		|||
                                                      td::actor::create_actor<DhtQueryRegisterReverseConnection>(
 | 
			
		||||
                                                          "RegisterReverseQuery", key_id, std::move(client), ttl,
 | 
			
		||||
                                                          std::move(signature), print_id, id_, std::move(list), k_, a_,
 | 
			
		||||
                                                          R.move_as_ok(), client_only_, SelfId, adnl_,
 | 
			
		||||
                                                          network_id_, R.move_as_ok(), client_only_, SelfId, adnl_,
 | 
			
		||||
                                                          std::move(promise))
 | 
			
		||||
                                                          .release();
 | 
			
		||||
                                                    });
 | 
			
		||||
| 
						 | 
				
			
			@ -535,9 +531,9 @@ void DhtMemberImpl::request_reverse_ping_cont(adnl::AdnlNode target, td::BufferS
 | 
			
		|||
                 SelfId = actor_id(this), print_id = print_id(), list = get_nearest_nodes(key_id, k_),
 | 
			
		||||
                 client_only = client_only_](td::Result<DhtNode> R) mutable {
 | 
			
		||||
    R.ensure();
 | 
			
		||||
    td::actor::create_actor<DhtQueryRequestReversePing>("RequestReversePing", client, std::move(target),
 | 
			
		||||
                                                        std::move(signature), print_id, id_, std::move(list), k_, a_,
 | 
			
		||||
                                                        R.move_as_ok(), client_only, SelfId, adnl_, std::move(promise))
 | 
			
		||||
    td::actor::create_actor<DhtQueryRequestReversePing>(
 | 
			
		||||
        "RequestReversePing", client, std::move(target), std::move(signature), print_id, id_, std::move(list), k_, a_,
 | 
			
		||||
        network_id_, R.move_as_ok(), client_only, SelfId, adnl_, std::move(promise))
 | 
			
		||||
        .release();
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -652,9 +648,10 @@ void DhtMemberImpl::check() {
 | 
			
		|||
    DhtKeyId key{x};
 | 
			
		||||
    auto P = td::PromiseCreator::lambda([key, promise = std::move(promise), SelfId = actor_id(this),
 | 
			
		||||
                                         print_id = print_id(), adnl = adnl_, list = get_nearest_nodes(key, k_), k = k_,
 | 
			
		||||
                                         a = a_, id = id_, client_only = client_only_](td::Result<DhtNode> R) mutable {
 | 
			
		||||
                                         a = a_, network_id = network_id_, id = id_,
 | 
			
		||||
                                         client_only = client_only_](td::Result<DhtNode> R) mutable {
 | 
			
		||||
      R.ensure();
 | 
			
		||||
      td::actor::create_actor<DhtQueryFindNodes>("FindNodesQuery", key, print_id, id, std::move(list), k, a,
 | 
			
		||||
      td::actor::create_actor<DhtQueryFindNodes>("FindNodesQuery", key, print_id, id, std::move(list), k, a, network_id,
 | 
			
		||||
                                                 R.move_as_ok(), client_only, SelfId, adnl, std::move(promise))
 | 
			
		||||
          .release();
 | 
			
		||||
    });
 | 
			
		||||
| 
						 | 
				
			
			@ -675,63 +672,71 @@ void DhtMemberImpl::send_store(DhtValue value, td::Promise<td::Unit> promise) {
 | 
			
		|||
  value.check().ensure();
 | 
			
		||||
  auto key_id = value.key_id();
 | 
			
		||||
 | 
			
		||||
  auto P =
 | 
			
		||||
      td::PromiseCreator::lambda([value = std::move(value), print_id = print_id(), id = id_, client_only = client_only_,
 | 
			
		||||
                                  list = get_nearest_nodes(key_id, k_), k = k_, a = a_, SelfId = actor_id(this),
 | 
			
		||||
                                  adnl = adnl_, promise = std::move(promise)](td::Result<DhtNode> R) mutable {
 | 
			
		||||
        R.ensure();
 | 
			
		||||
        td::actor::create_actor<DhtQueryStore>("StoreQuery", std::move(value), print_id, id, std::move(list), k, a,
 | 
			
		||||
                                               R.move_as_ok(), client_only, SelfId, adnl, std::move(promise))
 | 
			
		||||
            .release();
 | 
			
		||||
      });
 | 
			
		||||
  auto P = td::PromiseCreator::lambda([value = std::move(value), print_id = print_id(), id = id_,
 | 
			
		||||
                                       client_only = client_only_, list = get_nearest_nodes(key_id, k_), k = k_, a = a_,
 | 
			
		||||
                                       network_id = network_id_, SelfId = actor_id(this), adnl = adnl_,
 | 
			
		||||
                                       promise = std::move(promise)](td::Result<DhtNode> R) mutable {
 | 
			
		||||
    R.ensure();
 | 
			
		||||
    td::actor::create_actor<DhtQueryStore>("StoreQuery", std::move(value), print_id, id, std::move(list), k, a,
 | 
			
		||||
                                           network_id, R.move_as_ok(), client_only, SelfId, adnl, std::move(promise))
 | 
			
		||||
        .release();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  get_self_node(std::move(P));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DhtMemberImpl::get_self_node(td::Promise<DhtNode> promise) {
 | 
			
		||||
  auto P =
 | 
			
		||||
      td::PromiseCreator::lambda([promise = std::move(promise), print_id = print_id(), id = id_, keyring = keyring_,
 | 
			
		||||
                                  client_only = client_only_](td::Result<adnl::AdnlNode> R) mutable {
 | 
			
		||||
        R.ensure();
 | 
			
		||||
        auto node = R.move_as_ok();
 | 
			
		||||
        auto version = static_cast<td::int32>(td::Clocks::system());
 | 
			
		||||
        auto B = create_serialize_tl_object<ton_api::dht_node>(node.pub_id().tl(), node.addr_list().tl(), version,
 | 
			
		||||
                                                               td::BufferSlice());
 | 
			
		||||
        if (!client_only) {
 | 
			
		||||
          CHECK(node.addr_list().size() > 0);
 | 
			
		||||
        }
 | 
			
		||||
        auto P = td::PromiseCreator::lambda(
 | 
			
		||||
            [promise = std::move(promise), node = std::move(node), version](td::Result<td::BufferSlice> R) mutable {
 | 
			
		||||
              R.ensure();
 | 
			
		||||
              DhtNode n{node.pub_id(), node.addr_list(), version, R.move_as_ok()};
 | 
			
		||||
              promise.set_result(std::move(n));
 | 
			
		||||
            });
 | 
			
		||||
        td::actor::send_closure(keyring, &keyring::Keyring::sign_message, id.pubkey_hash(), std::move(B), std::move(P));
 | 
			
		||||
      });
 | 
			
		||||
  auto P = td::PromiseCreator::lambda([promise = std::move(promise), print_id = print_id(), id = id_,
 | 
			
		||||
                                       keyring = keyring_, client_only = client_only_,
 | 
			
		||||
                                       network_id = network_id_](td::Result<adnl::AdnlNode> R) mutable {
 | 
			
		||||
    R.ensure();
 | 
			
		||||
    auto node = R.move_as_ok();
 | 
			
		||||
    auto version = static_cast<td::int32>(td::Clocks::system());
 | 
			
		||||
    td::BufferSlice B = serialize_tl_object(
 | 
			
		||||
        DhtNode{node.pub_id(), node.addr_list(), version, network_id, td::BufferSlice{}}.tl(), true);
 | 
			
		||||
    if (!client_only) {
 | 
			
		||||
      CHECK(node.addr_list().size() > 0);
 | 
			
		||||
    }
 | 
			
		||||
    auto P = td::PromiseCreator::lambda([promise = std::move(promise), node = std::move(node), version,
 | 
			
		||||
                                         network_id](td::Result<td::BufferSlice> R) mutable {
 | 
			
		||||
      R.ensure();
 | 
			
		||||
      DhtNode n{node.pub_id(), node.addr_list(), version, network_id, R.move_as_ok()};
 | 
			
		||||
      promise.set_result(std::move(n));
 | 
			
		||||
    });
 | 
			
		||||
    td::actor::send_closure(keyring, &keyring::Keyring::sign_message, id.pubkey_hash(), std::move(B), std::move(P));
 | 
			
		||||
  });
 | 
			
		||||
  td::actor::send_closure(adnl_, &adnl::Adnl::get_self_node, id_, std::move(P));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
td::Result<std::shared_ptr<DhtGlobalConfig>> Dht::create_global_config(tl_object_ptr<ton_api::dht_config_global> conf) {
 | 
			
		||||
  td::uint32 k;
 | 
			
		||||
  if (conf->k_ == 0) {
 | 
			
		||||
td::Result<std::shared_ptr<DhtGlobalConfig>> Dht::create_global_config(tl_object_ptr<ton_api::dht_config_Global> conf) {
 | 
			
		||||
  td::uint32 k = 0, a = 0;
 | 
			
		||||
  td::int32 network_id = -1;
 | 
			
		||||
  tl_object_ptr<ton_api::dht_nodes> static_nodes;
 | 
			
		||||
  ton_api::downcast_call(*conf, td::overloaded(
 | 
			
		||||
                                    [&](ton_api::dht_config_global &f) {
 | 
			
		||||
                                      k = f.k_;
 | 
			
		||||
                                      a = f.a_;
 | 
			
		||||
                                      network_id = -1;
 | 
			
		||||
                                      static_nodes = std::move(f.static_nodes_);
 | 
			
		||||
                                    },
 | 
			
		||||
                                    [&](ton_api::dht_config_global_v2 &f) {
 | 
			
		||||
                                      k = f.k_;
 | 
			
		||||
                                      a = f.a_;
 | 
			
		||||
                                      network_id = f.network_id_;
 | 
			
		||||
                                      static_nodes = std::move(f.static_nodes_);
 | 
			
		||||
                                    }));
 | 
			
		||||
  if (k == 0) {
 | 
			
		||||
    k = DhtMember::default_k();
 | 
			
		||||
  } else if (conf->k_ > 0 && static_cast<td::uint32>(conf->k_) <= DhtMember::max_k()) {
 | 
			
		||||
    k = conf->k_;
 | 
			
		||||
  } else {
 | 
			
		||||
    return td::Status::Error(ErrorCode::protoviolation, PSTRING() << "bad value k=" << conf->k_);
 | 
			
		||||
  } else if (k > DhtMember::max_k()) {
 | 
			
		||||
    return td::Status::Error(ErrorCode::protoviolation, PSTRING() << "bad value k=" << k);
 | 
			
		||||
  }
 | 
			
		||||
  td::uint32 a;
 | 
			
		||||
  if (conf->a_ == 0) {
 | 
			
		||||
  if (a == 0) {
 | 
			
		||||
    a = DhtMember::default_a();
 | 
			
		||||
  } else if (conf->a_ > 0 && static_cast<td::uint32>(conf->a_) <= DhtMember::max_a()) {
 | 
			
		||||
    a = conf->a_;
 | 
			
		||||
  } else {
 | 
			
		||||
    return td::Status::Error(ErrorCode::protoviolation, PSTRING() << "bad value a=" << conf->a_);
 | 
			
		||||
  } else if (a > DhtMember::max_a()) {
 | 
			
		||||
    return td::Status::Error(ErrorCode::protoviolation, PSTRING() << "bad value a=" << a);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  DhtNodesList l{std::move(conf->static_nodes_)};
 | 
			
		||||
 | 
			
		||||
  return std::make_shared<DhtGlobalConfig>(k, a, std::move(l));
 | 
			
		||||
  DhtNodesList l{std::move(static_nodes), network_id};
 | 
			
		||||
  return std::make_shared<DhtGlobalConfig>(k, a, network_id, std::move(l));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // namespace dht
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,7 +47,7 @@ class Dht : public td::actor::Actor {
 | 
			
		|||
                                                            td::actor::ActorId<keyring::Keyring> keyring,
 | 
			
		||||
                                                            td::actor::ActorId<adnl::Adnl> adnl);
 | 
			
		||||
  static td::Result<std::shared_ptr<DhtGlobalConfig>> create_global_config(
 | 
			
		||||
      tl_object_ptr<ton_api::dht_config_global> conf);
 | 
			
		||||
      tl_object_ptr<ton_api::dht_config_Global> conf);
 | 
			
		||||
 | 
			
		||||
  virtual adnl::AdnlNodeIdShort get_id() const = 0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										11
									
								
								dht/dht.hpp
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								dht/dht.hpp
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -52,15 +52,20 @@ class DhtGlobalConfig {
 | 
			
		|||
  auto get_a() const {
 | 
			
		||||
    return a_;
 | 
			
		||||
  }
 | 
			
		||||
  auto get_network_id() const {
 | 
			
		||||
    return network_id_;
 | 
			
		||||
  }
 | 
			
		||||
  const auto &nodes() const {
 | 
			
		||||
    return static_nodes_;
 | 
			
		||||
  }
 | 
			
		||||
  DhtGlobalConfig(td::uint32 k, td::uint32 a, DhtNodesList nodes) : k_(k), a_(a), static_nodes_(std::move(nodes)) {
 | 
			
		||||
  DhtGlobalConfig(td::uint32 k, td::uint32 a, td::int32 network_id, DhtNodesList nodes)
 | 
			
		||||
      : k_(k), a_(a), network_id_(network_id), static_nodes_(std::move(nodes)) {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  td::uint32 k_;
 | 
			
		||||
  td::uint32 a_;
 | 
			
		||||
  td::int32 network_id_;
 | 
			
		||||
  DhtNodesList static_nodes_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -85,8 +90,8 @@ class DhtMember : public Dht {
 | 
			
		|||
 | 
			
		||||
  static td::actor::ActorOwn<DhtMember> create(adnl::AdnlNodeIdShort id, std::string db_root,
 | 
			
		||||
                                               td::actor::ActorId<keyring::Keyring> keyring,
 | 
			
		||||
                                               td::actor::ActorId<adnl::Adnl> adnl, td::uint32 k = 10, td::uint32 a = 3,
 | 
			
		||||
                                               bool client_only = false);
 | 
			
		||||
                                               td::actor::ActorId<adnl::Adnl> adnl, td::int32 network_id,
 | 
			
		||||
                                               td::uint32 k = 10, td::uint32 a = 3, bool client_only = false);
 | 
			
		||||
 | 
			
		||||
  //virtual void update_addr_list(tl_object_ptr<ton_api::adnl_addressList> addr_list) = 0;
 | 
			
		||||
  //virtual void add_node(adnl::AdnlNodeIdShort id) = 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -132,7 +132,9 @@ class Resolver : public td::actor::Actor {
 | 
			
		|||
    if (!conf.dht_) {
 | 
			
		||||
      return td::Status::Error(ton::ErrorCode::error, "does not contain [dht] section");
 | 
			
		||||
    }
 | 
			
		||||
    auto &nodes = conf.dht_->static_nodes_->nodes_;
 | 
			
		||||
    ton::ton_api::dht_nodes* static_nodes = nullptr;
 | 
			
		||||
    ton::ton_api::downcast_call(*conf.dht_, [&](auto &f) { static_nodes = f.static_nodes_.get(); });
 | 
			
		||||
    auto &nodes = static_nodes->nodes_;
 | 
			
		||||
    if (server_idx_ >= 0) {
 | 
			
		||||
      CHECK(server_idx_ < (int)nodes.size());
 | 
			
		||||
      LOG(INFO) << "Using server #" << server_idx_;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -562,11 +562,12 @@ control.config.local priv:PrivateKey pub:int256 port:int = control.config.Local;
 | 
			
		|||
config.local local_ids:(vector id.config.local) dht:(vector dht.config.Local) validators:(vector validator.config.Local) liteservers:(vector liteserver.config.Local) control:(vector control.config.local) = config.Local;
 | 
			
		||||
 | 
			
		||||
dht.config.global static_nodes:dht.nodes k:int a:int = dht.config.Global;
 | 
			
		||||
dht.config.global_v2 static_nodes:dht.nodes k:int a:int network_id:int = dht.config.Global;
 | 
			
		||||
adnl.config.global static_nodes:adnl.nodes = adnl.config.Global;
 | 
			
		||||
catchain.config.global tag:int256 nodes:(vector PublicKey) = catchain.config.Global;
 | 
			
		||||
dummyworkchain0.config.global zero_state_hash:int256 = dummyworkchain0.config.Global;
 | 
			
		||||
validator.config.global zero_state:tonNode.blockIdExt init_block:tonNode.blockIdExt hardforks:(vector tonNode.blockIdExt) = validator.config.Global;
 | 
			
		||||
config.global adnl:adnl.config.global dht:dht.config.global validator:validator.config.global = config.Global;
 | 
			
		||||
config.global adnl:adnl.config.global dht:dht.config.Global validator:validator.config.global = config.Global;
 | 
			
		||||
 | 
			
		||||
liteserver.desc id:PublicKey ip:int port:int = liteserver.Desc;
 | 
			
		||||
liteclient.config.global liteservers:(vector liteserver.desc) validator:validator.config.global = liteclient.config.Global;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											Binary file not shown.
										
									
								
							
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue