Skip to content
This repository has been archived by the owner on Mar 3, 2020. It is now read-only.

Commit

Permalink
KEP-1318 SwarmDB to use the ESR to bootstrap the peerslist
Browse files Browse the repository at this point in the history
  • Loading branch information
rnistuk authored and rnistuk committed May 18, 2019
1 parent 3ed5a4e commit 2b40ae9
Show file tree
Hide file tree
Showing 22 changed files with 628 additions and 56 deletions.
31 changes: 30 additions & 1 deletion bootstrap/bootstrap_peers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,19 @@
#include <utils/blacklist.hpp>
#include <utils/crypto.hpp>
#include <utils/http_get.hpp>
#include <utils/ESR_Peers_List.h>
#include <bootstrap/bootstrap_peers.hpp>
#include <fstream>
#include <sstream>
#include <json/json.h>
#include <algorithm>
#include <iostream>

using namespace bzn;


bool bootstrap_peers::fetch_peers_from_file(const std::string& filename)
bool
bootstrap_peers::fetch_peers_from_file(const std::string& filename)
{
std::ifstream file(filename);
if (file.fail())
Expand Down Expand Up @@ -52,6 +56,31 @@ bootstrap_peers::fetch_peers_from_url(const std::string& url)
}


bool
bootstrap_peers::fetch_peers_from_ESR_contract(const std::string& esr_address, const bzn::uuid_t &swarm_id)
{
auto peer_ids = bzn::utils::ESR::get_peer_ids(swarm_id, esr_address);
for (const auto& peer_id : peer_ids)
{
bzn::peer_address_t peer_info{bzn::utils::ESR::get_peer_info(swarm_id, peer_id, esr_address)};
if (peer_info.host.empty()
|| peer_info.port == 0
//|| peer_info.name.empty() // is it important that a peer have a name?
|| peer_info.http_port == 0
|| peer_info.uuid.empty()
)
{
LOG(warning) << "Invalid peer information found in ESR contract, ignoring info for peer: " << peer_id << " in swarm: " << swarm_id;
}
else
{
this->peer_addresses.emplace(peer_info);
}
}
return true;
}


const bzn::peers_list_t&
bootstrap_peers::get_peers() const
{
Expand Down
2 changes: 2 additions & 0 deletions bootstrap/bootstrap_peers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ namespace bzn

bool fetch_peers_from_url(const std::string& url) override;

bool fetch_peers_from_ESR_contract( const std::string& esr_address, const bzn::uuid_t &swarm_id) override;

const bzn::peers_list_t& get_peers() const override;

private:
Expand Down
8 changes: 8 additions & 0 deletions bootstrap/bootstrap_peers_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ namespace bzn
*/
virtual bool fetch_peers_from_url(const std::string& url) = 0;

/**
* Given a swarm id, fetch the peer info for the peers in that swarm
* @param esr_address a string containing the Etherium address of the get peer info contract o
* @param swarm_id a string containing the unique identifier of the swarm containing the peers of interest
* @return true - note that it is possible that the contract does not return any peers
*/
virtual bool fetch_peers_from_ESR_contract(const std::string& esr_address, const bzn::uuid_t &swarm_id) = 0;

/**
* @return a reference to the initial set of peers
*/
Expand Down
9 changes: 9 additions & 0 deletions bootstrap/test/bootstrap_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,12 @@ TEST(bootstrap_net_test, DISABLED_test_fetch_data_with_protocol)
ASSERT_TRUE(bootstrap_peers.fetch_peers_from_url(sample_peers_url_with_protocol));
ASSERT_EQ(bootstrap_peers.get_peers().size(), 1U);
}


TEST(bootstrap_net_test, test_fetch_peers_from_solidity)
{
bzn::bootstrap_peers bootstrap_peers;
bzn::uuid_t swarm_id{"BluzelleSwarm"};
ASSERT_TRUE(bootstrap_peers.fetch_peers_from_ESR_contract(bzn::utils::DEFAULT_SWARM_INFO_ESR_ADDRESS, swarm_id));
ASSERT_EQ(bootstrap_peers.get_peers().size(), 7U);
}
4 changes: 4 additions & 0 deletions include/bluzelle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ namespace bzn::utils
{
return path.substr(path.rfind('/') + 1);
}

const std::string ROPSTEN_URL{"https://ropsten.infura.io"};

const std::string DEFAULT_SWARM_INFO_ESR_ADDRESS{"D5B3d7C061F817ab05aF9Fab3b61EEe036e4f4fc"};
} // bzn::utils


Expand Down
2 changes: 2 additions & 0 deletions mocks/mock_options_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ class mock_options_base : public options_base {
std::string());
MOCK_CONST_METHOD0(get_owner_public_key,
std::string());
MOCK_CONST_METHOD0(get_swarm_info_esr_address,
std::string());
};

} // namespace bzn
2 changes: 1 addition & 1 deletion node/session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ session::open(std::shared_ptr<bzn::beast::websocket_base> ws_factory)
{
self->activity = true;

if(ec)
if (ec)
{
LOG(error) << "failed to connect to: " << self->ep.address().to_string() << ":" << self->ep.port() << " - " << ec.message();
return;
Expand Down
7 changes: 7 additions & 0 deletions options/options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,3 +248,10 @@ options::get_owner_public_key() const
{
return this->raw_opts.has(OWNER_PUBLIC_KEY) ? this->raw_opts.get<std::string>(OWNER_PUBLIC_KEY) : "";
}


std::string
options::get_swarm_info_esr_address() const
{
return this->raw_opts.has(SWARM_INFO_ESR_ADDRESS) ? this->raw_opts.get<std::string>(SWARM_INFO_ESR_ADDRESS) : bzn::utils::DEFAULT_SWARM_INFO_ESR_ADDRESS;
}
2 changes: 2 additions & 0 deletions options/options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ namespace bzn

std::string get_owner_public_key() const override;

std::string get_swarm_info_esr_address() const override;

private:
size_t parse_size(const std::string& key) const;

Expand Down
7 changes: 7 additions & 0 deletions options/options_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,5 +188,12 @@ namespace bzn
* @return string containing the path to the Bluzelle publi key pem file
*/
virtual std::string get_owner_public_key() const = 0;


/**
* Retrieve the address of the ESR where the contract to return the swarm info is
* @return string containing the address of the swarm info contract
*/
virtual std::string get_swarm_info_esr_address() const = 0;
};
} // bzn
5 changes: 4 additions & 1 deletion options/simple_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,10 @@ simple_options::build_options()
"number of worker threads to run (default is automatic based on hardware")
(WS_IDLE_TIMEOUT.c_str(),
po::value<uint64_t>()->default_value(300000),
"websocket idle timeout (ms)");
"websocket idle timeout (ms)")
(SWARM_INFO_ESR_ADDRESS.c_str(),
po::value<std::string>()->default_value(bzn::utils::DEFAULT_SWARM_INFO_ESR_ADDRESS),
"ESR");

po::options_description logging("Logging");
logging.add_options()
Expand Down
2 changes: 2 additions & 0 deletions options/simple_options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ namespace bzn::option_names

const std::string MONITOR_MAX_TIMERS = "monitor_max_timers";
const std::string OVERRIDE_NUM_THREADS = "override_num_threads";

const std::string SWARM_INFO_ESR_ADDRESS = "swarm_info_esr_address";
}

namespace bzn
Expand Down
6 changes: 5 additions & 1 deletion options/test/options_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ namespace
" \"logfile_dir\" : \".\","
" \"signed_key\" : \"Oo8ZlDQcMlZF4hqnhN/2D...hoEgc0jRUl1b9mHSY7E4puk=\","
" \"owner_public_key\" : \"MCwwDQYJKoZIhvcNAQEBBQADGwAwGAIRAKb7PX3Pr+LgaqIAyhcXgTMCAwEAAQ==\","
" \"mem_storage\" : false";
" \"mem_storage\" : false,"
" \"swarm_info_esr_address\" : \"this_would_be_a_good_ESR_address\"";

const std::string DEFAULT_CONFIG_DATA = "{" + DEFAULT_CONFIG_CONTENT + "}";

Expand Down Expand Up @@ -154,6 +155,7 @@ TEST_F(options_file_test, test_that_loading_of_default_config_file)
EXPECT_FALSE(options.get_mem_storage());
EXPECT_EQ("Oo8ZlDQcMlZF4hqnhN/2D...hoEgc0jRUl1b9mHSY7E4puk=",options.get_signed_key());
EXPECT_EQ("MCwwDQYJKoZIhvcNAQEBBQADGwAwGAIRAKb7PX3Pr+LgaqIAyhcXgTMCAwEAAQ==", options.get_owner_public_key());
EXPECT_EQ("this_would_be_a_good_ESR_address", options.get_swarm_info_esr_address());

// defaults..
{
Expand All @@ -169,6 +171,7 @@ TEST_F(options_file_test, test_that_loading_of_default_config_file)
EXPECT_EQ("logs/", options.get_logfile_dir());
EXPECT_TRUE(options.get_mem_storage());
EXPECT_EQ("", options.get_swarm_id());
EXPECT_EQ(bzn::utils::DEFAULT_SWARM_INFO_ESR_ADDRESS, options.get_swarm_info_esr_address());
}
}

Expand Down Expand Up @@ -262,6 +265,7 @@ TEST_F(options_file_test, test_that_command_line_options_work)
EXPECT_EQ(".", options.get_logfile_dir());
EXPECT_FALSE(options.peer_validation_enabled());
EXPECT_EQ("MCwwDQYJKoZIhvcNAQEBBQADGwAwGAIRAKb7PX3Pr+LgaqIAyhcXgTMCAwEAAQ==", options.get_owner_public_key());
EXPECT_EQ("this_would_be_a_good_ESR_address", options.get_swarm_info_esr_address());
}

TEST_F(options_file_test, test_that_no_monitor_endpoint_when_not_specified)
Expand Down
19 changes: 15 additions & 4 deletions swarm/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,24 @@ init_logging(const bzn::options& options)


bool
init_peers(bzn::bootstrap_peers& peers, const std::string& peers_file, const std::string& peers_url)
init_peers(bzn::bootstrap_peers& peers, const std::string& peers_file, const std::string& peers_url, const std::string &swarm_info_esr_address, const bzn::uuid_t& swarm_id)
{
if (peers_file.empty() && peers_url.empty())
if (peers_file.empty() && peers_url.empty() && swarm_id.empty())
{
LOG(error) << "Bootstrap peers must be specified options (bootstrap_file or bootstrap_url)";
LOG(error) << "Bootstrap peers must be specified options (bootstrap_file, bootstrap_url or swarm_id)";
return false;
}

if (!swarm_id.empty())
{
peers.fetch_peers_from_ESR_contract(swarm_info_esr_address, swarm_id);
if (!peers.get_peers().empty())
{
return true;
};
LOG(warning) << "Etherium Smart Contract Registry contained no peer listing for the swarm with id " << swarm_id << " checking other sources";
}

if (!peers_file.empty())
{
peers.fetch_peers_from_file(peers_file);
Expand Down Expand Up @@ -253,7 +263,8 @@ main(int argc, const char* argv[])
}

bzn::bootstrap_peers peers(options->peer_validation_enabled());
if (!init_peers(peers, options->get_bootstrap_peers_file(), options->get_bootstrap_peers_url()))
if (!init_peers(peers, options->get_bootstrap_peers_file(), options->get_bootstrap_peers_url(),
options->get_swarm_info_esr_address(), options->get_swarm_id()))
throw std::runtime_error("Bootstrap peers initialization failed.");

auto io_context = std::make_shared<bzn::asio::io_context>();
Expand Down
2 changes: 1 addition & 1 deletion utils/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ add_library(utils STATIC
bytes_to_debug_string.cpp
bytes_to_debug_string.hpp
crypto.cpp
crypto.hpp)
crypto.hpp ESR_Peers_List.cpp ESR_Peers_List.h curl.cpp curl.hpp)

target_link_libraries(utils ${CURL_LIBRARIES} ${JSONCPP_LIBRARIES} ${OPENSSL_LIBRARIES})

Expand Down

0 comments on commit 2b40ae9

Please sign in to comment.