Skip to content

Commit f611ebe

Browse files
art-gorkamilsa
andauthored
Gossip pr 3 (#48)
* gossip: wire protocol * gossip: peer set and wire protocol utilities revised * gossip: msg cache w/expiration * data structures for gossip: fixes and unittest * changes due to pr 1 feedback * one more fix due to PR requests * one more try against ci * gossip part 2 * gossip: pr1 reflects pr2 * gossip: pr1 reflects pr2 * Fix/gossip pr 1 (#46) * Fix build for macos * Improvements * deprecated logic removed * gossip: cleanups and renamings * gossip: renmings * gossip serialization method signature changed * gossip: serialization signature changed * Gossip pr 1 (#37) * gossip: wire protocol * gossip: peer set and wire protocol utilities revised * gossip: msg cache w/expiration * data structures for gossip: fixes and unittest * changes due to pr 1 feedback * one more fix due to PR requests * one more try against ci * gossip: pr1 reflects pr2 * gossip: pr1 reflects pr2 * Fix/gossip pr 1 (#46) * Fix build for macos * Improvements * deprecated logic removed * gossip: cleanups and renamings * gossip: renmings * gossip serialization method signature changed Co-authored-by: kamilsa <[email protected]> * refactorings * typo fixed * minor fixes * +gossip-example * +gossip-example * fixes and example * debug things * gossip: subscriptions test and bugfixes * dont forward messages back to their origins * injectors made parametric (to build examples) * gossip: fixes * more fixes in pub-sub * fixes in gossip example * sublogger can set new instance name * message cache fix exp times * chat example * logs and traces added for debug purposes * README.md for gossip examples * small patch for older stdlibs support * more logs and traces * more logs and traces * new inbound protocol streams are allowed for all connections * streams issues fixed * gossip injector fixed * gossip new example * boost_program_options in dependencies * scheduler with config param (strong type for injector) * tests fixed due to recent changes * cleanup in yamux and dialer-listener hotfixes * hotfixes to yamux and dialer * yamux changes * parametrized netork and host injectors * streams regression test * patched mplex connections/streams so that streams get notified about EOF Co-authored-by: kamilsa <[email protected]>
1 parent 06a70df commit f611ebe

File tree

80 files changed

+5303
-260
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+5303
-260
lines changed

cmake/dependencies.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ find_package(GTest CONFIG REQUIRED)
44
find_package(GMock CONFIG REQUIRED)
55

66
# https://docs.hunter.sh/en/latest/packages/pkg/Boost.html
7-
hunter_add_package(Boost COMPONENTS random filesystem)
8-
find_package(Boost CONFIG REQUIRED random filesystem)
7+
hunter_add_package(Boost COMPONENTS random filesystem program_options)
8+
find_package(Boost CONFIG REQUIRED random filesystem program_options)
99

1010
# added from hunter_config
1111
hunter_add_package(GSL)

example/02-kad/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ target_link_libraries(kad_peer_discovery_example
1717
p2p_inmem_protocol_repository
1818
p2p_literals
1919
p2p_kad
20+
asio_scheduler
2021
)

example/02-kad/factory.cpp

Lines changed: 30 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -3,80 +3,44 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

6-
#include <boost/di.hpp>
7-
#include "boost/di/extension/scopes/shared.hpp"
8-
9-
// implementations
10-
#include <libp2p/crypto/crypto_provider/crypto_provider_impl.hpp>
11-
#include <libp2p/crypto/ecdsa_provider/ecdsa_provider_impl.hpp>
12-
#include <libp2p/crypto/ed25519_provider/ed25519_provider_impl.hpp>
13-
#include <libp2p/crypto/hmac_provider/hmac_provider_impl.hpp>
14-
#include <libp2p/crypto/key_marshaller/key_marshaller_impl.hpp>
15-
#include <libp2p/crypto/key_validator/key_validator_impl.hpp>
16-
#include <libp2p/crypto/random_generator/boost_generator.hpp>
17-
#include <libp2p/crypto/rsa_provider/rsa_provider_impl.hpp>
18-
#include <libp2p/crypto/secp256k1_provider/secp256k1_provider_impl.hpp>
19-
#include <libp2p/host/basic_host.hpp>
20-
#include <libp2p/muxer/mplex.hpp>
21-
#include <libp2p/muxer/yamux.hpp>
22-
#include <libp2p/network/impl/connection_manager_impl.hpp>
23-
#include <libp2p/network/impl/dialer_impl.hpp>
24-
#include <libp2p/network/impl/listener_manager_impl.hpp>
25-
#include <libp2p/network/impl/network_impl.hpp>
26-
#include <libp2p/network/impl/router_impl.hpp>
27-
#include <libp2p/network/impl/transport_manager_impl.hpp>
28-
#include <libp2p/peer/address_repository/inmem_address_repository.hpp>
29-
#include <libp2p/peer/impl/identity_manager_impl.hpp>
30-
#include <libp2p/peer/impl/peer_repository_impl.hpp>
31-
#include <libp2p/peer/key_repository/inmem_key_repository.hpp>
32-
#include <libp2p/peer/protocol_repository/inmem_protocol_repository.hpp>
33-
#include <libp2p/protocol_muxer/multiselect.hpp>
34-
#include <libp2p/security/plaintext.hpp>
35-
#include <libp2p/security/plaintext/exchange_message_marshaller_impl.hpp>
36-
#include <libp2p/transport/impl/upgrader_impl.hpp>
37-
#include <libp2p/transport/tcp.hpp>
386

39-
#include <libp2p/protocol/kademlia/impl/routing_table_impl.hpp>
7+
#include "factory.hpp"
408

41-
#include <iostream>
9+
#include <boost/di/extension/scopes/shared.hpp>
4210

43-
#include "factory.hpp"
11+
#include <libp2p/injector/host_injector.hpp>
12+
#include <libp2p/protocol/kademlia/impl/routing_table_impl.hpp>
4413

4514
namespace libp2p::protocol::kademlia::example {
4615

4716
boost::optional<libp2p::peer::PeerInfo> str2peerInfo(const std::string &str) {
48-
using R = boost::optional<libp2p::peer::PeerInfo>;
49-
5017
auto server_ma_res = libp2p::multi::Multiaddress::create(str);
5118
if (!server_ma_res) {
52-
std::cerr << "unable to create server multiaddress: "
53-
<< server_ma_res.error().message() << std::endl;
54-
return R();
19+
fmt::print("unable to create server multiaddress: {}\n",
20+
server_ma_res.error().message());
21+
return boost::none;
5522
}
5623
auto server_ma = std::move(server_ma_res.value());
5724

5825
auto server_peer_id_str = server_ma.getPeerId();
5926
if (!server_peer_id_str) {
60-
std::cerr << "unable to get peer id" << std::endl;
61-
return R();
27+
fmt::print("unable to extract peer id from multiaddress\n");
28+
return boost::none;
6229
}
6330

64-
auto server_peer_id_res =
65-
libp2p::peer::PeerId::fromBase58(*server_peer_id_str);
31+
auto server_peer_id_res = peer::PeerId::fromBase58(*server_peer_id_str);
6632
if (!server_peer_id_res) {
67-
std::cerr << "Unable to decode peer id from base 58: "
68-
<< server_peer_id_res.error().message() << std::endl;
69-
return R();
33+
fmt::print("Unable to decode peer id from base 58: {}\n",
34+
server_peer_id_res.error().message());
35+
return boost::none;
7036
}
7137

72-
return libp2p::peer::PeerInfo{server_peer_id_res.value(), {server_ma}};
38+
return peer::PeerInfo{server_peer_id_res.value(), {server_ma}};
7339
}
7440

7541
namespace {
7642
template <typename... Ts>
7743
auto makeInjector(Ts &&... args) {
78-
using namespace boost; // NOLINT
79-
8044
auto csprng = std::make_shared<crypto::random::BoostRandomGenerator>();
8145
auto ed25519_provider =
8246
std::make_shared<crypto::ed25519::Ed25519ProviderImpl>();
@@ -98,47 +62,23 @@ namespace libp2p::protocol::kademlia::example {
9862
auto keypair =
9963
crypto_provider->generateKeys(crypto::Key::Type::Ed25519).value();
10064

101-
// clang-format off
102-
return di::make_injector<boost::di::extension::shared_config>(
103-
di::bind<crypto::CryptoProvider>().to(crypto_provider)[boost::di::override],
104-
di::bind<crypto::KeyPair>().template to(std::move(keypair)),
105-
di::bind<crypto::random::CSPRNG>().template to(std::move(csprng)),
106-
di::bind<crypto::marshaller::KeyMarshaller>().template to<crypto::marshaller::KeyMarshallerImpl>(),
107-
di::bind<peer::IdentityManager>().template to<peer::IdentityManagerImpl>(),
108-
di::bind<crypto::validator::KeyValidator>().template to<crypto::validator::KeyValidatorImpl>(),
109-
di::bind<security::plaintext::ExchangeMessageMarshaller>().template to<security::plaintext::ExchangeMessageMarshallerImpl>(),
110-
111-
// internal
112-
di::bind<network::Router>().template to<network::RouterImpl>(),
113-
di::bind<network::ConnectionManager>().template to<network::ConnectionManagerImpl>(),
114-
di::bind<network::ListenerManager>().template to<network::ListenerManagerImpl>(),
115-
di::bind<network::Dialer>().template to<network::DialerImpl>(),
116-
di::bind<network::Network>().template to<network::NetworkImpl>(),
117-
di::bind<network::TransportManager>().template to<network::TransportManagerImpl>(),
118-
di::bind<transport::Upgrader>().template to<transport::UpgraderImpl>(),
119-
di::bind<protocol_muxer::ProtocolMuxer>().template to<protocol_muxer::Multiselect>(),
120-
121-
// default adaptors
122-
di::bind<security::SecurityAdaptor *[]>().template to<security::Plaintext>(), // NOLINT
123-
di::bind<muxer::MuxerAdaptor *[]>().template to<muxer::Yamux, muxer::Mplex>(), // NOLINT
124-
di::bind<transport::TransportAdaptor *[]>().template to<transport::TcpTransport>(), // NOLINT
125-
126-
di::bind<event::Bus>.template to<event::Bus>(),
127-
di::bind<Host>.template to<host::BasicHost>(),
128-
129-
di::bind<muxer::MuxedConnectionConfig>.to(muxer::MuxedConnectionConfig()),
130-
131-
// repositories
132-
di::bind<peer::PeerRepository>.template to<peer::PeerRepositoryImpl>(),
133-
di::bind<peer::AddressRepository>.template to<peer::InmemAddressRepository>(),
134-
di::bind<peer::KeyRepository>.template to<peer::InmemKeyRepository>(),
135-
di::bind<peer::ProtocolRepository>.template to<peer::InmemProtocolRepository>(),
136-
137-
// user-defined overrides...
138-
std::forward<decltype(args)>(args)...
139-
);
140-
// clang-format on
65+
return libp2p::injector::makeHostInjector<
66+
boost::di::extension::shared_config>(
67+
boost::di::bind<crypto::CryptoProvider>().to(
68+
crypto_provider)[boost::di::override],
69+
boost::di::bind<crypto::KeyPair>().template to(
70+
std::move(keypair))[boost::di::override],
71+
boost::di::bind<crypto::random::CSPRNG>().template to(
72+
std::move(csprng))[boost::di::override],
73+
boost::di::bind<crypto::marshaller::KeyMarshaller>()
74+
.template to<
75+
crypto::marshaller::KeyMarshallerImpl>()[boost::di::override],
76+
boost::di::bind<crypto::validator::KeyValidator>().template to(
77+
std::move(validator))[boost::di::override],
78+
79+
std::forward<decltype(args)>(args)...);
14180
}
81+
14282
} // namespace
14383

14484
void createPerHostObjects(PerHostObjects &objects,

example/02-kad/factory.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#include <libp2p/crypto/crypto_provider.hpp>
1010
#include <libp2p/crypto/key_marshaller.hpp>
1111
#include <libp2p/host/host.hpp>
12-
#include <memory>
12+
#include <libp2p/protocol/kademlia/routing_table.hpp>
1313

1414
namespace libp2p::protocol::kademlia::example {
1515
std::shared_ptr<boost::asio::io_context> createIOContext();

example/02-kad/kad_peer_discovery_example.cpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
#include <libp2p/common/literals.hpp>
1010
#include <libp2p/network/connection_manager.hpp>
11-
#include <libp2p/protocol/kademlia/impl/asio_scheduler_impl.hpp>
11+
#include <libp2p/protocol/common/asio/asio_scheduler.hpp>
1212
#include <libp2p/protocol/kademlia/impl/kad_impl.hpp>
1313
#include <libp2p/protocol/kademlia/node_id.hpp>
1414

@@ -52,12 +52,9 @@ namespace libp2p::protocol::kademlia::example {
5252
bool verbose = true;
5353
bool request_sent = false;
5454

55-
Host(size_t i, std::shared_ptr<Scheduler> sch, PerHostObjects obj)
56-
: index(i),
57-
o(std::move(obj))
58-
59-
{
60-
kad = std::make_shared<KadImpl>(o.host, std::move(sch), o.routing_table,
55+
Host(size_t i, const std::shared_ptr<Scheduler> &sch, PerHostObjects obj)
56+
: index(i), o(std::move(obj)) {
57+
kad = std::make_shared<KadImpl>(o.host, sch, o.routing_table,
6158
createDefaultValueStoreBackend(),
6259
getConfig());
6360
}
@@ -259,8 +256,8 @@ namespace libp2p::protocol::kademlia::example {
259256
} // namespace libp2p::protocol::kademlia::example
260257

261258
int main(int argc, char *argv[]) {
262-
namespace k = libp2p::protocol::kademlia;
263-
namespace x = k::example;
259+
namespace p = libp2p::protocol;
260+
namespace x = libp2p::protocol::kademlia::example;
264261
try {
265262
size_t hosts_count = 6;
266263
bool kad_log_debug = false;
@@ -272,7 +269,9 @@ int main(int argc, char *argv[]) {
272269
x::setupLoggers(kad_log_debug);
273270

274271
auto io = x::createIOContext();
275-
auto scheduler = k::AsioSchedulerImpl::create(*io, 1000);
272+
273+
auto scheduler = std::make_shared<libp2p::protocol::AsioScheduler>(
274+
*io, libp2p::protocol::SchedulerConfig{});
276275

277276
x::Hosts hosts(hosts_count, scheduler);
278277

example/03-gossip/CMakeLists.txt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#
2+
# Copyright Soramitsu Co., Ltd. All Rights Reserved.
3+
# SPDX-License-Identifier: Apache-2.0
4+
#
5+
6+
libp2p_add_library(gossip_example_common
7+
utility.cpp
8+
console_async_reader.cpp
9+
)
10+
11+
target_link_libraries(gossip_example_common
12+
p2p_basic_host
13+
p2p_default_network
14+
p2p_peer_repository
15+
p2p_inmem_address_repository
16+
p2p_inmem_key_repository
17+
p2p_inmem_protocol_repository
18+
p2p_gossip
19+
asio_scheduler
20+
Boost::program_options
21+
)
22+
23+
add_executable(gossip_chat_example
24+
gossip_chat_example.cpp
25+
)
26+
27+
target_link_libraries(gossip_chat_example
28+
gossip_example_common
29+
)

example/03-gossip/README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Gossip pub-sub examples
2+
## General description
3+
4+
* `gossip_chat_example.cpp` shows how to use Gossip pub-sub
5+
* `utility.cpp` and `console_async_reader.*` contain common things related to examples
6+
7+
## Launching
8+
9+
### gossip_chat_example
10+
11+
`./gossip_chat_example -p PORT [-t TOPIC] [-r REMOTE] [-l LOG_LEVEL]`
12+
13+
Longer strings for options are available, respectively `--port`, `--topic`, `--remote`, and `--log`
14+
15+
* `PORT` : port the local node is going to listen to
16+
* `TOPIC` : topic name for chat messages
17+
* `REMOTE` : p2p URI of bootstrap peer to connect to
18+
* `LOG_LEVEL`: verbosity level of log output, possible values are `d`, `i`, `w`, or `e` (self explained)
19+
20+
After launching, you may type messages into console, which are being published into the topic.
21+
Log messages are printed into`stdout`. Chat output is written to `stderr`. So logs may be redirected if needed
22+
23+
Explanation by example: `./gossip_chat_example --log=d -p 1300 -r /ip4/192.168.0.104/tcp/10000/p2p/12D3KooWLm1CRdj8DBhwAfMGEcNGCEm3ZWxL6jD6uC6BizqXGcP6` means that
24+
25+
* Logs will be printed with `debug` verbosity level
26+
* local node will listen to port 1300 and try to connect to remote peer given by uri
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#include "console_async_reader.hpp"
7+
8+
namespace libp2p::protocol::example::utility {
9+
10+
ConsoleAsyncReader::ConsoleAsyncReader(boost::asio::io_context &io,
11+
Handler handler)
12+
: in_(io, STDIN_FILENO), handler_(std::move(handler)) {
13+
read();
14+
}
15+
16+
void ConsoleAsyncReader::stop() {
17+
stopped_ = true;
18+
}
19+
20+
void ConsoleAsyncReader::read() {
21+
input_.consume(input_.data().size());
22+
boost::asio::async_read_until(
23+
in_, input_, "\n",
24+
[this](const boost::system::error_code &e, std::size_t size) {
25+
onRead(e, size);
26+
});
27+
}
28+
29+
void ConsoleAsyncReader::onRead(const boost::system::error_code &e,
30+
std::size_t size) {
31+
if (stopped_) {
32+
return;
33+
}
34+
if (!e && size != 0) {
35+
line_.assign(buffers_begin(input_.data()), buffers_end(input_.data()));
36+
line_.erase(line_.find_first_of("\r\n"));
37+
handler_(line_);
38+
}
39+
read();
40+
}
41+
42+
} // namespace libp2p::protocol::example::utility
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/**
2+
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#ifndef LIBP2P_CONSOLE_ASYNC_READER_HPP
7+
#define LIBP2P_CONSOLE_ASYNC_READER_HPP
8+
9+
#include <string>
10+
#include <functional>
11+
12+
#include <boost/asio.hpp>
13+
14+
namespace libp2p::protocol::example::utility {
15+
16+
/// Asio-based asynchronous line reader from stdin
17+
class ConsoleAsyncReader {
18+
public:
19+
/// lines read from the console come into this callback
20+
using Handler = std::function<void(const std::string &)>;
21+
22+
/// starts the reader
23+
ConsoleAsyncReader(boost::asio::io_context &io, Handler handler);
24+
25+
/// stops the reader: no more callbacks after this call
26+
void stop();
27+
28+
private:
29+
/// begins read operation
30+
void read();
31+
32+
/// read callback from asio
33+
void onRead(const boost::system::error_code &e, std::size_t size);
34+
35+
boost::asio::posix::stream_descriptor in_;
36+
boost::asio::streambuf input_;
37+
std::string line_;
38+
Handler handler_;
39+
bool stopped_ = false;
40+
};
41+
42+
} //namespace libp2p::protocol::example::utility
43+
44+
#endif // LIBP2P_CONSOLE_ASYNC_READER_HPP

0 commit comments

Comments
 (0)