Skip to content

Commit

Permalink
Basic Host (#189)
Browse files Browse the repository at this point in the history
* Add impl of basic host

Signed-off-by: Bogdan Vaneev <warchantua@gmail.com>

* Fix

Signed-off-by: Bogdan Vaneev <warchantua@gmail.com>

* Fix tests

Signed-off-by: Bogdan Vaneev <warchantua@gmail.com>

* Fix

Signed-off-by: Bogdan Vaneev <warchantua@gmail.com>
  • Loading branch information
Warchant committed Jul 18, 2019
1 parent f9dab96 commit 2221acb
Show file tree
Hide file tree
Showing 19 changed files with 476 additions and 114 deletions.
15 changes: 1 addition & 14 deletions core/libp2p/CMakeLists.txt
Expand Up @@ -20,18 +20,5 @@ add_library(libp2p
libp2p.cpp
)
target_link_libraries(libp2p INTERFACE
libp2p_network
libp2p_tcp
libp2p_yamux
libp2p_plaintext
libp2p_connection_manager
libp2p_transport_manager
libp2p_listener_manager
libp2p_identity_manager
libp2p_dialer
libp2p_router
multiselect
random_generator
key_generator
marshaller
libp2p_default_network
)
2 changes: 1 addition & 1 deletion core/libp2p/event/bus.hpp
Expand Up @@ -190,7 +190,7 @@ namespace libp2p::event {
/**
* Event bus, containing channels and providing a convenient access to them
*/
class Bus {
class Bus : private boost::noncopyable {
public:
/**
* Fetch a reference to the channel declared by the passed in type. This
Expand Down
1 change: 1 addition & 0 deletions core/libp2p/host/CMakeLists.txt
@@ -1,3 +1,4 @@
# Copyright Soramitsu Co., Ltd. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

add_subdirectory(basic_host)
9 changes: 9 additions & 0 deletions core/libp2p/host/basic_host/CMakeLists.txt
@@ -0,0 +1,9 @@
# Copyright Soramitsu Co., Ltd. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

add_library(libp2p_basic_host
basic_host.cpp
)
target_link_libraries(libp2p_basic_host
outcome
)
116 changes: 116 additions & 0 deletions core/libp2p/host/basic_host/basic_host.cpp
@@ -0,0 +1,116 @@
/**
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

#include "libp2p/host/basic_host/basic_host.hpp"

namespace libp2p::host {

BasicHost::BasicHost(std::shared_ptr<peer::IdentityManager> idmgr,
std::unique_ptr<network::Network> network,
std::unique_ptr<peer::PeerRepository> repo)
: idmgr_(std::move(idmgr)),
network_(std::move(network)),
repo_(std::move(repo)) {
BOOST_ASSERT(idmgr_ != nullptr);
BOOST_ASSERT(network_ != nullptr);
BOOST_ASSERT(repo_ != nullptr);
}

std::string_view BasicHost::getLibp2pVersion() const {
return "0.0.0";
}

std::string_view BasicHost::getLibp2pClientVersion() const {
return "kagome";
}

peer::PeerId BasicHost::getId() const {
return idmgr_->getId();
}

peer::PeerInfo BasicHost::getPeerInfo() const {
return {getId(), getObservedAddresses()};
}

std::vector<multi::Multiaddress> BasicHost::getAddresses() const {
return network_->getListener().getListenAddresses();
}

std::vector<multi::Multiaddress> BasicHost::getAddressesInterfaces() const {
return network_->getListener().getListenAddressesInterfaces();
}

std::vector<multi::Multiaddress> BasicHost::getObservedAddresses() const {
auto r = repo_->getAddressRepository().getAddresses(getId());
if (r) {
return r.value();
}

// we don't know our addresses
return {};
}

void BasicHost::setProtocolHandler(
const peer::Protocol &proto,
const std::function<connection::Stream::Handler> &handler) {
network_->getListener().getRouter().setProtocolHandler(proto, handler);
}

void BasicHost::setProtocolHandler(
const peer::Protocol &proto,
const std::function<connection::Stream::Handler> &handler,
const std::function<bool(const peer::Protocol &)> &predicate) {
network_->getListener().getRouter().setProtocolHandler(proto, handler,
predicate);
}

void BasicHost::newStream(const peer::PeerInfo &p,
const peer::Protocol &protocol,
const Host::StreamResultHandler &handler) {
network_->getDialer().newStream(p, protocol, handler);
}

outcome::result<void> BasicHost::listen(const multi::Multiaddress &ma) {
return network_->getListener().listen(ma);
}

outcome::result<void> BasicHost::closeListener(
const multi::Multiaddress &ma) {
return network_->getListener().closeListener(ma);
}

outcome::result<void> BasicHost::removeListener(
const multi::Multiaddress &ma) {
return network_->getListener().removeListener(ma);
}

void BasicHost::start() {
network_->getListener().stop();
}

void BasicHost::stop() {
network_->getListener().start();
}

network::Network &BasicHost::getNetwork() {
return *network_;
}

peer::PeerRepository &BasicHost::getPeerRepository() {
return *repo_;
}

network::Router &BasicHost::getRouter() {
return network_->getListener().getRouter();
}

event::Bus &BasicHost::getBus() {
return bus_;
}

void BasicHost::connect(const peer::PeerInfo &p) {
network_->getDialer().dial(p, [](auto && /* ignored */) {});
}
} // namespace libp2p::host
87 changes: 87 additions & 0 deletions core/libp2p/host/basic_host/basic_host.hpp
@@ -0,0 +1,87 @@
/**
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef KAGOME_BASIC_HOST_HPP
#define KAGOME_BASIC_HOST_HPP

#include "libp2p/event/bus.hpp"
#include "libp2p/host/host.hpp"
#include "libp2p/peer/identity_manager.hpp"

namespace libp2p::host {

/**
* @brief Basic host is a Host, which:
* - has identity
* - has access to a network
* - has event bus
* - has peer repository
*/
class BasicHost : public Host {
public:
~BasicHost() override = default;

BasicHost(std::shared_ptr<peer::IdentityManager> idmgr,
std::unique_ptr<network::Network> network,
std::unique_ptr<peer::PeerRepository> repo);

std::string_view getLibp2pVersion() const override;

std::string_view getLibp2pClientVersion() const override;

peer::PeerId getId() const override;

peer::PeerInfo getPeerInfo() const override;

std::vector<multi::Multiaddress> getAddresses() const override;

std::vector<multi::Multiaddress> getAddressesInterfaces() const override;

std::vector<multi::Multiaddress> getObservedAddresses() const override;

void connect(const peer::PeerInfo &p) override;

void setProtocolHandler(
const peer::Protocol &proto,
const std::function<connection::Stream::Handler> &handler) override;

void setProtocolHandler(
const peer::Protocol &proto,
const std::function<connection::Stream::Handler> &handler,
const std::function<bool(const peer::Protocol &)> &predicate) override;

void newStream(const peer::PeerInfo &p, const peer::Protocol &protocol,
const StreamResultHandler &handler) override;

outcome::result<void> listen(const multi::Multiaddress &ma) override;

outcome::result<void> closeListener(const multi::Multiaddress &ma) override;

outcome::result<void> removeListener(
const multi::Multiaddress &ma) override;

void start() override;

void stop() override;

network::Network &getNetwork() override;

peer::PeerRepository &getPeerRepository() override;

network::Router &getRouter() override;

event::Bus &getBus() override;

private:
std::shared_ptr<peer::IdentityManager> idmgr_;
std::unique_ptr<network::Network> network_;
std::unique_ptr<peer::PeerRepository> repo_;

event::Bus bus_;
};

} // namespace libp2p::host

#endif // KAGOME_BASIC_HOST_HPP
30 changes: 8 additions & 22 deletions core/libp2p/host/host.hpp
Expand Up @@ -76,7 +76,7 @@ namespace libp2p {
*
* May return 0 addresses if we don't know our observed addresses.
*/
virtual std::vector<multi::Multiaddress> getObservedAddreses() const = 0;
virtual std::vector<multi::Multiaddress> getObservedAddresses() const = 0;

/**
* @brief Let Host handle given {@param proto} protocol
Expand All @@ -89,31 +89,17 @@ namespace libp2p {
const std::function<connection::Stream::Handler> &handler) = 0;

/**
* @brief Let Host handle all protocols with prefix={@param prefix}, for
* which predicate {@param predicate} is true.
* param prefix prefix for the protocol. Example:
* You want all streams, which came to Ping protocol with versions
* between 1.5 and 2.0 to be handled by your handler; so, you may pass
* - prefix=/ping/1.
* - predicate=[](proto){return proto.version >= 1.5
* && proto.version < 2.0;}
* @brief Let Host handle given protocol, and use matcher to check if we
* support given remote protocol.
* @param handler of the arrived stream
* @param predicate function that takes received protocol (/ping/1.0.0) and
* should return true, if this protocol can be handled.
*/
virtual void setProtocolHandler(
std::string_view prefix,
const peer::Protocol &protocol,
const std::function<connection::Stream::Handler> &handler,
const std::function<bool(const peer::Protocol &)> &predicate) = 0;

/**
* @brief Register {@param protocol} for this host. User MUST transfer
* ownership on protocol to the Host.
* @param protocol protocol instance
*/
virtual void handleProtocol(
std::unique_ptr<protocol::BaseProtocol> protocol) = 0;

/**
* @brief Initiates connection to the peer {@param p}. If connection exists,
* does nothing.
Expand Down Expand Up @@ -168,22 +154,22 @@ namespace libp2p {
/**
* @brief Getter for a network.
*/
virtual network::Network &getNetwork() const = 0;
virtual network::Network &getNetwork() = 0;

/**
* @brief Getter for a peer repository.
*/
virtual peer::PeerRepository &getPeerRepository() const = 0;
virtual peer::PeerRepository &getPeerRepository() = 0;

/**
* @brief Getter for a router.
*/
virtual network::Router &getRouter() const = 0;
virtual network::Router &getRouter() = 0;

/**
* @brief Getter for event bus.
*/
virtual event::Bus &getBus() const = 0;
virtual event::Bus &getBus() = 0;
};
} // namespace libp2p

Expand Down
28 changes: 19 additions & 9 deletions core/libp2p/network/impl/listener_manager_impl.cpp
Expand Up @@ -65,6 +65,17 @@ namespace libp2p::network {
return std::errc::invalid_argument;
}

outcome::result<void> ListenerManagerImpl::removeListener(
const multi::Multiaddress &ma) {
auto it = listeners_.find(ma);
if (it != listeners_.end()) {
listeners_.erase(it);
return outcome::success();
}

return std::errc::invalid_argument;
};

// starts listening on all provided multiaddresses
void ListenerManagerImpl::start() {
BOOST_ASSERT(!started);
Expand Down Expand Up @@ -137,14 +148,17 @@ namespace libp2p::network {
return mas;
}

outcome::result<std::vector<multi::Multiaddress>>
std::vector<multi::Multiaddress>
ListenerManagerImpl::getListenAddressesInterfaces() const {
std::vector<multi::Multiaddress> mas;
mas.reserve(listeners_.size());

for (auto &&e : listeners_) {
OUTCOME_TRY(addr, e.second->getListenMultiaddr());
mas.push_back(addr);
auto addr = e.second->getListenMultiaddr();
// ignore failed sockets
if (addr) {
mas.push_back(std::move(addr.value()));
}
}

return mas;
Expand Down Expand Up @@ -203,7 +217,6 @@ namespace libp2p::network {
}

void ListenerManagerImpl::setProtocolHandler(const peer::Protocol &protocol,

StreamResultFunc cb) {
this->router_->setProtocolHandler(protocol, std::move(cb));
}
Expand All @@ -214,11 +227,8 @@ namespace libp2p::network {
this->router_->setProtocolHandler(protocol, std::move(cb), predicate);
}

void ListenerManagerImpl::handleProtocol(
std::shared_ptr<protocol::BaseProtocol> protocol) {
this->setProtocolHandler(
protocol->getProtocolId(),
[protocol](StreamResult res) { protocol->handle(std::move(res)); });
Router &ListenerManagerImpl::getRouter() {
return *router_;
}

} // namespace libp2p::network

0 comments on commit 2221acb

Please sign in to comment.