Ton

Форк
0
/
adnl-test-ping.cpp 
240 строк · 9.3 Кб
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-peer-table.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

36
#include <iostream>
37
#include <sstream>
38

39
template <std::size_t size>
40
std::ostream &operator<<(std::ostream &stream, const td::UInt<size> &x) {
41
  for (size_t i = 0; i < size / 8; i++) {
42
    stream << td::format::hex_digit((x.raw[i] >> 4) & 15) << td::format::hex_digit(x.raw[i] & 15);
43
  }
44

45
  return stream;
46
}
47

48
class AdnlNode : public td::actor::Actor {
49
 private:
50
  std::vector<td::UInt256> ping_ids_;
51

52
  td::actor::ActorOwn<ton::AdnlNetworkManager> network_manager_;
53
  td::actor::ActorOwn<ton::AdnlPeerTable> peer_table_;
54

55
  td::UInt256 local_id_;
56
  bool local_id_set_ = false;
57

58
  std::string host_ = "127.0.0.1";
59
  td::uint32 ip_ = 0x7f000001;
60
  td::uint16 port_ = 2380;
61

62
  void receive_message(td::UInt256 src, td::UInt256 dst, td::BufferSlice data) {
63
    std::cout << "MESSAGE FROM " << src << " to " << dst << " of size " << std::to_string(data.size()) << "\n";
64
  }
65

66
  void receive_query(td::UInt256 src, td::UInt256 dst, td::uint64 query_id, td::BufferSlice data) {
67
    std::cout << "QUERY " << std::to_string(query_id) << " FROM " << src << " to " << dst << " of size "
68
              << std::to_string(data.size()) << "\n";
69
    td::actor::send_closure(peer_table_, &ton::AdnlPeerTable::answer_query, dst, src, query_id,
70
                            ton::create_tl_object<ton::ton_api::testObject>());
71
  }
72

73
  std::unique_ptr<ton::AdnlPeerTable::Callback> make_callback() {
74
    class Callback : public ton::AdnlPeerTable::Callback {
75
     public:
76
      void receive_message(td::UInt256 src, td::UInt256 dst, td::BufferSlice data) override {
77
        td::actor::send_closure(id_, &AdnlNode::receive_message, src, dst, std::move(data));
78
      }
79
      void receive_query(td::UInt256 src, td::UInt256 dst, td::uint64 query_id, td::BufferSlice data) override {
80
        td::actor::send_closure(id_, &AdnlNode::receive_query, src, dst, query_id, std::move(data));
81
      }
82
      Callback(td::actor::ActorId<AdnlNode> id) : id_(std::move(id)) {
83
      }
84

85
     private:
86
      td::actor::ActorId<AdnlNode> id_;
87
    };
88

89
    return std::make_unique<Callback>(td::actor::actor_id(this));
90
  }
91

92
 public:
93
  void start_up() override {
94
    alarm_timestamp() = td::Timestamp::in(1);
95
  }
96
  AdnlNode() {
97
    network_manager_ = ton::AdnlNetworkManager::create();
98
    peer_table_ = ton::AdnlPeerTable::create();
99
    td::actor::send_closure(network_manager_, &ton::AdnlNetworkManager::register_peer_table, peer_table_.get());
100
    td::actor::send_closure(peer_table_, &ton::AdnlPeerTable::register_network_manager, network_manager_.get());
101
  }
102
  void listen_udp(td::uint16 port) {
103
    td::actor::send_closure(network_manager_, &ton::AdnlNetworkManager::add_listening_udp_port, "0.0.0.0", port);
104
    port_ = port;
105
  }
106
  void set_host(td::IPAddress ip, std::string host) {
107
    ip_ = ip.get_ipv4();
108
    host_ = host;
109
  }
110
  void send_pings_to(td::UInt256 id) {
111
    std::cout << "send pings to " << id << "\n";
112
    ping_ids_.push_back(id);
113
  }
114
  void add_local_id(ton::tl_object_ptr<ton::ton_api::adnl_id_Pk> pk_) {
115
    auto pub_ = ton::get_public_key(pk_);
116
    local_id_ = ton::adnl_short_id(pub_);
117
    std::cout << "local_id = '" << local_id_ << "'\n";
118
    auto x = ton::create_tl_object<ton::ton_api::adnl_address_udp>(ip_, port_);
119
    auto v = std::vector<ton::tl_object_ptr<ton::ton_api::adnl_Address>>();
120
    v.push_back(ton::move_tl_object_as<ton::ton_api::adnl_Address>(x));
121
    auto y =
122
        ton::create_tl_object<ton::ton_api::adnl_addressList>(std::move(v), static_cast<td::int32>(td::Time::now()));
123

124
    LOG(INFO) << "local_addr_list: " << ton::ton_api::to_string(y);
125
    td::actor::send_closure(peer_table_, &ton::AdnlPeerTable::add_id, std::move(pk_), std::move(y));
126
    td::actor::send_closure(peer_table_, &ton::AdnlPeerTable::subscribe, local_id_, "", make_callback());
127
    local_id_set_ = true;
128
  }
129

130
  void add_foreign(ton::tl_object_ptr<ton::ton_api::adnl_id_Full> id,
131
                   ton::tl_object_ptr<ton::ton_api::adnl_addressList> addr_list) {
132
    std::cout << ton::adnl_short_id(id) << "\n";
133
    td::actor::send_closure(peer_table_, &ton::AdnlPeerTable::add_peer, std::move(id), std::move(addr_list));
134
  }
135

136
  void alarm() override {
137
    std::cout << "alarm\n";
138
    if (local_id_set_) {
139
      for (auto it = ping_ids_.begin(); it != ping_ids_.end(); it++) {
140
        auto P = td::PromiseCreator::lambda([](td::Result<td::BufferSlice> result) {
141
          if (result.is_error()) {
142
            std::cout << "received error " << result.move_as_error().to_string() << "\n";
143
          } else {
144
            auto message = result.move_as_ok();
145
            std::cout << "received answer to query\n";
146
          }
147
        });
148
        td::actor::send_closure(peer_table_, &ton::AdnlPeerTable::send_query, local_id_, *it, std::move(P),
149
                                td::Timestamp::in(5), ton::create_tl_object<ton::ton_api::getTestObject>());
150
      }
151
    }
152

153
    alarm_timestamp() = td::Timestamp::in(1);
154
  }
155
};
156

157
td::Result<td::UInt256> get_uint256(std::string str) {
158
  if (str.size() != 64) {
159
    return td::Status::Error("uint256 must have 64 bytes");
160
  }
161
  td::UInt256 res;
162
  for (size_t i = 0; i < 32; i++) {
163
    res.raw[i] = static_cast<td::uint8>(td::hex_to_int(str[2 * i]) * 16 + td::hex_to_int(str[2 * i + 1]));
164
  }
165
  return res;
166
}
167

168
int main(int argc, char *argv[]) {
169
  td::actor::ActorOwn<AdnlNode> x;
170

171
  td::OptionParser p;
172
  p.set_description("test basic adnl functionality");
173
  p.add_option('h', "help", "prints_help", [&]() {
174
    char b[10240];
175
    td::StringBuilder sb({b, 10000});
176
    sb << p;
177
    std::cout << sb.as_cslice().c_str();
178
    std::exit(2);
179
    return td::Status::OK();
180
  });
181
  p.add_option('p', "port", "sets udp port", [&](td::Slice port) {
182
    td::actor::send_closure(x, &AdnlNode::listen_udp, static_cast<td::uint16>(std::stoi(port.str())));
183
    return td::Status::OK();
184
  });
185
  p.add_option('a', "host", "sets local ip", [&](td::Slice ip) {
186
    td::IPAddress addr;
187
    auto R = addr.init_host_port(ip.str(), 0);
188
    if (R.is_error()) {
189
      return R;
190
    }
191
    td::actor::send_closure(x, &AdnlNode::set_host, addr, ip.str());
192
    return td::Status::OK();
193
  });
194
  p.add_option('i', "id", "sets local id", [&](td::Slice id) {
195
    td::actor::send_closure(x, &AdnlNode::add_local_id,
196
                            ton::create_tl_object<ton::ton_api::adnl_id_pk_unenc>(id.str()));
197
    return td::Status::OK();
198
  });
199
  p.add_option('P', "peer", "adds peer id@host:port", [&](td::Slice id) {
200
    auto pos = id.rfind('@');
201
    if (pos == static_cast<size_t>(-1)) {
202
      return td::Status::Error("--peer expected randomtag@host:port as argument");
203
    }
204
    auto s1 = id.substr(0, pos);
205
    auto f_id = ton::create_tl_object<ton::ton_api::adnl_id_unenc>(s1.str());
206
    td::IPAddress addr;
207
    auto R = addr.init_host_port(td::CSlice(id.substr(pos + 1).str()));
208
    if (R.is_error()) {
209
      return R.move_as_error();
210
    }
211

212
    auto f_addr = ton::create_tl_object<ton::ton_api::adnl_address_udp>(addr.get_ipv4(), addr.get_port());
213
    std::vector<ton::tl_object_ptr<ton::ton_api::adnl_Address>> vv;
214
    vv.push_back(ton::move_tl_object_as<ton::ton_api::adnl_Address>(f_addr));
215

216
    auto f_addr_list =
217
        ton::create_tl_object<ton::ton_api::adnl_addressList>(std::move(vv), static_cast<int>(td::Time::now()));
218

219
    td::actor::send_closure(x, &AdnlNode::add_foreign, ton::move_tl_object_as<ton::ton_api::adnl_id_Full>(f_id),
220
                            std::move(f_addr_list));
221

222
    return td::Status::OK();
223
  });
224
  p.add_option('n', "node", "node to send pings to", [&](td::Slice node) {
225
    auto R = get_uint256(node.str());
226
    if (R.is_error()) {
227
      return R.move_as_error();
228
    }
229

230
    td::actor::send_closure(x, &AdnlNode::send_pings_to, R.move_as_ok());
231
    return td::Status::OK();
232
  });
233

234
  td::actor::Scheduler scheduler({2});
235
  scheduler.run_in_context([&] {
236
    x = td::actor::create_actor<AdnlNode>(td::actor::ActorInfoCreator::Options().with_name("A").with_poll());
237
  });
238
  scheudler.run();
239
  return 0;
240
}
241

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

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

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

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