Kagome
Polkadot Runtime Engine in C++17
router_libp2p.cpp
Go to the documentation of this file.
1 
7 
8 namespace kagome::network {
10  std::shared_ptr<application::AppStateManager> app_state_manager,
11  libp2p::Host &host,
12  const application::AppConfiguration &app_config,
13  const OwnPeerInfo &own_info,
14  const BootstrapNodes &bootstrap_nodes,
15  std::shared_ptr<libp2p::protocol::Ping> ping_proto,
16  std::shared_ptr<network::ProtocolFactory> protocol_factory)
17  : app_state_manager_{app_state_manager},
18  host_{host},
19  app_config_(app_config),
20  own_info_{own_info},
21  log_{log::createLogger("RouterLibp2p", "network")},
22  ping_protocol_{std::move(ping_proto)},
23  protocol_factory_{std::move(protocol_factory)} {
24  BOOST_ASSERT(app_state_manager_ != nullptr);
25  BOOST_ASSERT(ping_protocol_ != nullptr);
26  BOOST_ASSERT(protocol_factory_ != nullptr);
27 
28  SL_DEBUG(log_, "Own peer id: {}", own_info.id.toBase58());
29  if (!bootstrap_nodes.empty()) {
30  for (const auto &peer_info : bootstrap_nodes) {
31  for (auto &addr : peer_info.addresses) {
32  SL_DEBUG(log_, "Bootstrap node: {}", addr.getStringAddress());
33  }
34  }
35  } else if (app_config_.isRunInDevMode()) {
36  SL_DEBUG(log_, "No bootstrap node. Dev mode.");
37  } else {
38  log_->error("No bootstrap node");
39  }
40 
41  app_state_manager_->takeControl(*this);
42  }
43 
45  host_.setProtocolHandler(
46  {ping_protocol_->getProtocolId()},
47  [wp = weak_from_this()](auto &&stream_and_proto) {
48  if (auto self = wp.lock()) {
49  auto &stream = stream_and_proto.stream;
50  if (auto peer_id = stream->remotePeerId()) {
51  SL_TRACE(self->log_,
52  "Handled {} protocol stream from: {}",
53  self->ping_protocol_->getProtocolId(),
54  peer_id.value().toBase58());
55  self->ping_protocol_->handle(
56  std::forward<decltype(stream_and_proto)>(stream_and_proto));
57  }
58  }
59  });
60 
61  block_announce_protocol_ = protocol_factory_->makeBlockAnnounceProtocol();
62  if (not block_announce_protocol_) {
63  return false;
64  }
65 
66  collation_protocol_ = protocol_factory_->makeCollationProtocol();
67  if (not collation_protocol_) {
68  return false;
69  }
70 
71  req_collation_protocol_ = protocol_factory_->makeReqCollationProtocol();
72  if (not req_collation_protocol_) {
73  return false;
74  }
75 
76  grandpa_protocol_ = protocol_factory_->makeGrandpaProtocol();
77  if (not grandpa_protocol_) {
78  return false;
79  }
80 
82  protocol_factory_->makePropagateTransactionsProtocol();
84  return false;
85  }
86 
87  state_protocol_ = protocol_factory_->makeStateProtocol();
88  if (not state_protocol_) {
89  return false;
90  }
91 
92  sync_protocol_ = protocol_factory_->makeSyncProtocol();
93  if (not sync_protocol_) {
94  return false;
95  }
96 
97  block_announce_protocol_->start();
98  grandpa_protocol_->start();
99  propagate_transaction_protocol_->start();
100  state_protocol_->start();
101  sync_protocol_->start();
102  collation_protocol_->start();
103  req_collation_protocol_->start();
104 
105  return true;
106  }
107 
109  auto listen_addresses = app_config_.listenAddresses();
110  for (auto &listen_address : listen_addresses) {
111  // fully formatted listen address is used inside Kademlia
112  auto append_res = appendPeerIdToAddress(listen_address);
113  if (not append_res) {
114  log_->error("Cannot append peer id info to listen addr {}. Error: {}",
115  listen_address.getStringAddress(),
116  append_res.error().message());
117  // despite the possible failure of address reformatting we still
118  // intentionally try to start listening the interface
119  }
120  auto res = host_.listen(listen_address);
121  if (not res) {
122  log_->error("Cannot listen on address {}. Error: {}",
123  listen_address.getStringAddress(),
124  res.error().message());
125  }
126  }
127 
128  auto &addr_repo = host_.getPeerRepository().getAddressRepository();
129  // here we put our known public addresses to the repository
130  auto upsert_res = addr_repo.upsertAddresses(
131  own_info_.id, own_info_.addresses, libp2p::peer::ttl::kPermanent);
132  if (!upsert_res) {
133  log_->error("Cannot add own addresses to repo: {}",
134  upsert_res.error().message());
135  }
136 
137  host_.start();
138 
139  const auto &host_addresses = host_.getAddresses();
140  if (host_addresses.empty()) {
141  log_->critical("Host addresses is empty");
142  return false;
143  }
144 
145  log_->info("Started with peer id: {}", host_.getId().toBase58());
146  for (const auto &addr : host_addresses) {
147  log_->info("Started listening on address: {}", addr.getStringAddress());
148  }
149 
150  return true;
151  }
152 
154  if (host_.getNetwork().getListener().isStarted()) {
155  host_.stop();
156  }
157  }
158 
159  std::shared_ptr<BlockAnnounceProtocol>
162  }
163 
164  std::shared_ptr<CollationProtocol> RouterLibp2p::getCollationProtocol()
165  const {
166  return collation_protocol_;
167  }
168 
169  std::shared_ptr<ReqCollationProtocol> RouterLibp2p::getReqCollationProtocol()
170  const {
172  }
173 
174  std::shared_ptr<PropagateTransactionsProtocol>
177  }
178 
179  std::shared_ptr<StateProtocol> RouterLibp2p::getStateProtocol() const {
180  return state_protocol_;
181  }
182 
183  std::shared_ptr<SyncProtocol> RouterLibp2p::getSyncProtocol() const {
184  return sync_protocol_;
185  }
186 
187  std::shared_ptr<GrandpaProtocol> RouterLibp2p::getGrandpaProtocol() const {
188  return grandpa_protocol_;
189  }
190 
191  std::shared_ptr<libp2p::protocol::Ping> RouterLibp2p::getPingProtocol()
192  const {
193  return ping_protocol_;
194  }
195 
196  outcome::result<void> RouterLibp2p::appendPeerIdToAddress(
197  libp2p::multi::Multiaddress &address) const {
198  using P = libp2p::multi::Protocol::Code;
199 
200  if (address.getProtocols().size()
201  < 3 // does not have /p2p or alternative part
202  and (address.hasProtocol(P::IP4) or address.hasProtocol(P::IP6))
203  and address.hasProtocol(P::TCP)) {
204  // PeerId is already initialized in both cases - when it is predefined or
205  // autogenerated
206 
207  auto ma_res = libp2p::multi::Multiaddress::create(
208  std::string(address.getStringAddress()) + "/p2p/"
209  + own_info_.id.toBase58());
210  if (not ma_res) {
211  return ma_res.error();
212  }
213  address = ma_res.value();
214  }
215  return outcome::success();
216  }
217 
218 } // namespace kagome::network
std::shared_ptr< libp2p::protocol::Ping > ping_protocol_
std::shared_ptr< GrandpaProtocol > getGrandpaProtocol() const override
std::shared_ptr< libp2p::protocol::Ping > getPingProtocol() const override
std::shared_ptr< SyncProtocol > sync_protocol_
virtual const std::vector< libp2p::multi::Multiaddress > & listenAddresses() const =0
std::shared_ptr< SyncProtocol > getSyncProtocol() const override
std::shared_ptr< BlockAnnounceProtocol > getBlockAnnounceProtocol() const override
std::shared_ptr< StateProtocol > getStateProtocol() const override
const application::AppConfiguration & app_config_
std::shared_ptr< BlockAnnounceProtocol > block_announce_protocol_
std::shared_ptr< CollationProtocol > getCollationProtocol() const override
std::shared_ptr< ReqCollationProtocol > req_collation_protocol_
std::shared_ptr< PropagateTransactionsProtocol > getPropagateTransactionsProtocol() const override
virtual bool isRunInDevMode() const =0
RouterLibp2p(std::shared_ptr< application::AppStateManager > app_state_manager, libp2p::Host &host, const application::AppConfiguration &app_config, const OwnPeerInfo &own_info, const BootstrapNodes &bootstrap_nodes, std::shared_ptr< libp2p::protocol::Ping > ping_proto, std::shared_ptr< network::ProtocolFactory > protocol_factory)
std::shared_ptr< CollationProtocol > collation_protocol_
const OwnPeerInfo & own_info_
std::shared_ptr< PropagateTransactionsProtocol > propagate_transaction_protocol_
outcome::result< void > appendPeerIdToAddress(libp2p::multi::Multiaddress &address) const
std::shared_ptr< application::AppStateManager > app_state_manager_
std::shared_ptr< GrandpaProtocol > grandpa_protocol_
std::shared_ptr< ReqCollationProtocol > getReqCollationProtocol() const override
Logger createLogger(const std::string &tag)
Definition: logger.cpp:112
std::shared_ptr< StateProtocol > state_protocol_
std::shared_ptr< network::ProtocolFactory > protocol_factory_