Ton

Форк
0
/
dht-ping-servers.cpp 
214 строк · 7.9 Кб
1
/* 
2
    This file is part of TON Blockchain source code.
3

4
    TON Blockchain is free software; you can redistribute it and/or
5
    modify it under the terms of the GNU General Public License
6
    as published by the Free Software Foundation; either version 2
7
    of the License, or (at your option) any later version.
8

9
    TON Blockchain is distributed in the hope that it will be useful,
10
    but WITHOUT ANY WARRANTY; without even the implied warranty of
11
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
    GNU General Public License for more details.
13

14
    You should have received a copy of the GNU General Public License
15
    along with TON Blockchain.  If not, see <http://www.gnu.org/licenses/>.
16

17
    In addition, as a special exception, the copyright holders give permission 
18
    to link the code of portions of this program with the OpenSSL library. 
19
    You must obey the GNU General Public License in all respects for all 
20
    of the code used other than OpenSSL. If you modify file(s) with this 
21
    exception, you may extend this exception to your version of the file(s), 
22
    but you are not obligated to do so. If you do not wish to do so, delete this 
23
    exception statement from your version. If you delete this exception statement 
24
    from all source files in the program, then also delete it here.
25

26
    Copyright 2017-2020 Telegram Systems LLP
27
*/
28
#include "adnl/adnl-network-manager.h"
29
#include "adnl/adnl.h"
30
#include "adnl/utils.hpp"
31
#include "keys/encryptor.h"
32
#include "td/utils/Time.h"
33
#include "td/utils/format.h"
34
#include "td/utils/OptionParser.h"
35
#include "td/utils/filesystem.h"
36
#include "dht/dht.hpp"
37
#include "auto/tl/ton_api_json.h"
38
#include "common/delay.h"
39
#include "td/utils/Random.h"
40
#include "terminal/terminal.h"
41

42
#include <iostream>
43

44
class AdnlNode : public td::actor::Actor {
45
 private:
46
  td::actor::ActorOwn<ton::adnl::AdnlNetworkManager> network_manager_;
47
  td::actor::ActorOwn<ton::adnl::Adnl> adnl_;
48
  td::actor::ActorOwn<ton::keyring::Keyring> keyring_;
49
  ton::adnl::AdnlNodeIdShort local_id_;
50

51
  std::string host_ = "127.0.0.1";
52
  td::uint16 port_ = 2380;
53

54
  std::string global_config_ = "ton-global.config";
55

56
  struct NodeInfo {
57
    ton::adnl::AdnlNodeIdShort id;
58
    td::uint32 sent = 0, received = 0;
59
    double sum_time = 0.0;
60
    explicit NodeInfo(ton::adnl::AdnlNodeIdShort id) : id(id) {
61
    }
62
  };
63
  std::vector<NodeInfo> nodes_;
64

65
  td::uint32 pings_remaining_ = 4;
66
  td::uint32 pending_ = 1;
67

68
 public:
69
  void set_global_config(std::string str) {
70
    global_config_ = str;
71
  }
72
  void listen_udp(td::uint16 port) {
73
    port_ = port;
74
  }
75

76
  AdnlNode() {
77
  }
78

79
  void run() {
80
    network_manager_ = ton::adnl::AdnlNetworkManager::create(port_);
81
    keyring_ = ton::keyring::Keyring::create("");
82
    adnl_ = ton::adnl::Adnl::create("", keyring_.get());
83
    td::actor::send_closure(adnl_, &ton::adnl::Adnl::register_network_manager, network_manager_.get());
84

85
    td::IPAddress addr;
86
    addr.init_host_port(host_, port_).ensure();
87
    ton::adnl::AdnlCategoryMask mask;
88
    mask[0] = true;
89
    td::actor::send_closure(network_manager_, &ton::adnl::AdnlNetworkManager::add_self_addr, addr, mask, 0);
90
    auto pk = ton::privkeys::Ed25519::random();
91
    td::actor::send_closure(keyring_, &ton::keyring::Keyring::add_key, pk, true, [](td::Result<td::Unit>) {});
92
    ton::adnl::AdnlNodeIdFull local_id_full(pk.pub());
93
    ton::adnl::AdnlAddressList addr_list;
94
    addr_list.set_version(static_cast<td::int32>(td::Clocks::system()));
95
    addr_list.set_reinit_date(ton::adnl::Adnl::adnl_start_time());
96
    td::actor::send_closure(adnl_, &ton::adnl::Adnl::add_id, local_id_full, std::move(addr_list), (td::uint8)0);
97
    local_id_ = local_id_full.compute_short_id();
98

99
    auto r_dht = get_dht_config();
100
    if (r_dht.is_error()) {
101
      LOG(FATAL) << "Cannot get dht config: " << r_dht.move_as_error();
102
    }
103
    auto dht = r_dht.move_as_ok();
104
    ton::adnl::AdnlNodesList static_nodes;
105
    for (const auto &node : dht->nodes().list()) {
106
      LOG(INFO) << "Node #" << nodes_.size() << " : " << node.adnl_id().compute_short_id();
107
      nodes_.emplace_back(node.adnl_id().compute_short_id());
108
      static_nodes.push(ton::adnl::AdnlNode(node.adnl_id(), node.addr_list()));
109
    }
110
    td::actor::send_closure(adnl_, &ton::adnl::Adnl::add_static_nodes_from_config, std::move(static_nodes));
111

112
    ton::delay_action([SelfId = actor_id(this)]() { td::actor::send_closure(SelfId, &AdnlNode::send_pings); },
113
                      td::Timestamp::in(1.0));
114
  }
115

116
  td::Result<std::shared_ptr<ton::dht::DhtGlobalConfig>> get_dht_config() {
117
    TRY_RESULT_PREFIX(conf_data, td::read_file(global_config_), "failed to read: ");
118
    TRY_RESULT_PREFIX(conf_json, td::json_decode(conf_data.as_slice()), "failed to parse json: ");
119
    ton::ton_api::config_global conf;
120
    TRY_STATUS_PREFIX(ton::ton_api::from_json(conf, conf_json.get_object()), "json does not fit TL scheme: ");
121
    if (!conf.dht_) {
122
      return td::Status::Error(ton::ErrorCode::error, "does not contain [dht] section");
123
    }
124
    TRY_RESULT_PREFIX(dht, ton::dht::Dht::create_global_config(std::move(conf.dht_)), "bad [dht] section: ");
125
    return std::move(dht);
126
  }
127

128
  void send_pings() {
129
    CHECK(pings_remaining_);
130
    --pings_remaining_;
131
    for (size_t i = 0; i < nodes_.size(); ++i) {
132
      auto id = nodes_[i].id;
133
      LOG(INFO) << "Sending ping to " << id;
134
      ++pending_;
135
      td::actor::send_closure(
136
          adnl_, &ton::adnl::Adnl::send_query, local_id_, id, "ping",
137
          [SelfId = actor_id(this), i, timer = td::Timer()](td::Result<td::BufferSlice> R) {
138
            td::actor::send_closure(SelfId, &AdnlNode::on_pong, i, timer.elapsed(), R.is_ok());
139
          }, td::Timestamp::in(5.0),
140
          ton::create_serialize_tl_object<ton::ton_api::dht_ping>(td::Random::fast_uint64()));
141
    }
142

143
    if (pings_remaining_ == 0) {
144
      --pending_;
145
      try_finish();
146
    } else {
147
      ton::delay_action([SelfId = actor_id(this)]() { td::actor::send_closure(SelfId, &AdnlNode::send_pings); },
148
                        td::Timestamp::in(1.0));
149
    }
150
  }
151

152
  void on_pong(size_t i, double time, bool success) {
153
    auto &node = nodes_[i];
154
    ++node.sent;
155
    if (success) {
156
      ++node.received;
157
      node.sum_time += time;
158
      LOG(INFO) << "Pong from " << node.id << " in " << time << "s";
159
    } else {
160
      LOG(INFO) << "Pong from " << node.id << " : timeout";
161
    }
162
    --pending_;
163
    try_finish();
164
  }
165

166
  void try_finish() {
167
    if (pending_) {
168
      return;
169
    }
170
    td::TerminalIO::out() << "Pinged " << nodes_.size() << " nodes:\n";
171
    for (const auto& node : nodes_) {
172
      td::TerminalIO::out() << node.id << " : " << node.received << "/" << node.sent;
173
      if (node.received > 0) {
174
        td::TerminalIO::out() << " (avg. time = " << node.sum_time / node.received << ")";
175
      }
176
      td::TerminalIO::out() << "\n";
177
    }
178
    std::exit(0);
179
  }
180
};
181

182
int main(int argc, char *argv[]) {
183
  td::actor::ActorOwn<AdnlNode> x;
184

185
  td::OptionParser p;
186
  p.set_description("ping dht servers from config");
187
  p.add_option('h', "help", "print help", [&]() {
188
    char b[10240];
189
    td::StringBuilder sb(td::MutableSlice{b, 10000});
190
    sb << p;
191
    std::cout << sb.as_cslice().c_str();
192
    std::exit(2);
193
  });
194
  p.add_option('p', "port", "set udp port", [&](td::Slice port) {
195
    td::actor::send_closure(x, &AdnlNode::listen_udp, static_cast<td::uint16>(std::stoi(port.str())));
196
  });
197
  p.add_option('C', "global-config", "file to read global config from",
198
               [&](td::Slice fname) { td::actor::send_closure(x, &AdnlNode::set_global_config, fname.str()); });
199
  p.add_option('v', "verbosity", "set verbosity", [&](td::Slice arg) {
200
    int v = VERBOSITY_NAME(FATAL) + (td::to_integer<int>(arg));
201
    SET_VERBOSITY_LEVEL(v);
202
  });
203

204
  td::actor::Scheduler scheduler({2});
205

206
  scheduler.run_in_context([&] { x = td::actor::create_actor<AdnlNode>("AdnlNode"); });
207

208
  scheduler.run_in_context([&] { p.run(argc, argv).ensure(); });
209
  scheduler.run_in_context([&] { td::actor::send_closure(x, &AdnlNode::run); });
210

211
  scheduler.run();
212

213
  return 0;
214
}
215

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.