Cache peers in database (#1608)

* Cache peers implementation

* Add --debug_peers CLI command

* Fix test and formartting

* Store port in network byte order. Added an appropriate interface similar to boost's endpoint for nano::endpoint_key

* Formatting

* Fix rebase

* Update stopped (removed in merge)

* Formatting
This commit is contained in:
Wesley Shillingford 2019-01-29 21:24:22 +00:00 committed by GitHub
commit ea192aa708
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 346 additions and 68 deletions

View file

@ -1417,3 +1417,74 @@ TEST (block_store, upgrade_sideband_epoch)
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, block2).code);
ASSERT_EQ (nano::epoch::epoch_1, store.block_version (transaction, block2.hash ()));
}
TEST (block_store, peers)
{
nano::logging logging;
auto init (false);
nano::mdb_store store (init, logging, nano::unique_path ());
ASSERT_TRUE (!init);
auto transaction (store.tx_begin_write ());
nano::endpoint_key endpoint (boost::asio::ip::address_v6::any ().to_bytes (), 100);
// Confirm that the store is empty
ASSERT_FALSE (store.peer_exists (transaction, endpoint));
ASSERT_EQ (store.peer_count (transaction), 0);
// Add one, confirm that it can be found
store.peer_put (transaction, endpoint);
ASSERT_TRUE (store.peer_exists (transaction, endpoint));
ASSERT_EQ (store.peer_count (transaction), 1);
// Add another one and check that it (and the existing one) can be found
nano::endpoint_key endpoint1 (boost::asio::ip::address_v6::any ().to_bytes (), 101);
store.peer_put (transaction, endpoint1);
ASSERT_TRUE (store.peer_exists (transaction, endpoint1)); // Check new peer is here
ASSERT_TRUE (store.peer_exists (transaction, endpoint)); // Check first peer is still here
ASSERT_EQ (store.peer_count (transaction), 2);
// Delete the first one
store.peer_del (transaction, endpoint1);
ASSERT_FALSE (store.peer_exists (transaction, endpoint1)); // Confirm it no longer exists
ASSERT_TRUE (store.peer_exists (transaction, endpoint)); // Check first peer is still here
ASSERT_EQ (store.peer_count (transaction), 1);
// Delete original one
store.peer_del (transaction, endpoint);
ASSERT_EQ (store.peer_count (transaction), 0);
ASSERT_FALSE (store.peer_exists (transaction, endpoint));
}
TEST (block_store, endpoint_key_byte_order)
{
boost::asio::ip::address_v6 address (boost::asio::ip::address_v6::from_string ("::ffff:127.0.0.1"));
auto port = 100;
nano::endpoint_key endpoint_key (address.to_bytes (), port);
std::vector<uint8_t> bytes;
{
nano::vectorstream stream (bytes);
nano::write (stream, endpoint_key);
}
// This checks that the endpoint is serialized as expected, with a size
// of 18 bytes (16 for ipv6 address and 2 for port), both in network byte order.
ASSERT_EQ (bytes.size (), 18);
ASSERT_EQ (bytes[10], 0xff);
ASSERT_EQ (bytes[11], 0xff);
ASSERT_EQ (bytes[12], 127);
ASSERT_EQ (bytes[bytes.size () - 2], 0);
ASSERT_EQ (bytes.back (), 100);
// Deserialize the same stream bytes
nano::bufferstream stream1 (bytes.data (), bytes.size ());
nano::endpoint_key endpoint_key1;
nano::read (stream1, endpoint_key1);
// This should be in network bytes order
ASSERT_EQ (address.to_bytes (), endpoint_key1.address_bytes ());
// This should be in host byte order
ASSERT_EQ (port, endpoint_key1.port ());
}

View file

@ -2128,6 +2128,60 @@ TEST (node, confirm_back)
}
}
TEST (node, peers)
{
nano::system system (24000, 1);
auto list (system.nodes.front ()->peers.list ());
ASSERT_TRUE (list.empty ());
nano::node_init init;
auto node (std::make_shared<nano::node> (init, system.io_ctx, 24001, nano::unique_path (), system.alarm, system.logging, system.work));
system.nodes.push_back (node);
auto endpoint = system.nodes.front ()->network.endpoint ();
nano::endpoint_key endpoint_key{ endpoint.address ().to_v6 ().to_bytes (), endpoint.port () };
auto & store = system.nodes.back ()->store;
{
// Add a peer to the database
auto transaction (store.tx_begin_write ());
store.peer_put (transaction, endpoint_key);
// Add a peer which is not contactable
store.peer_put (transaction, nano::endpoint_key{ boost::asio::ip::address_v6::any ().to_bytes (), 55555 });
}
node->start ();
system.deadline_set (10s);
while (system.nodes.back ()->peers.empty ())
{
ASSERT_NO_ERROR (system.poll ());
}
// Confirm that the peers match with the endpoints we are expecting
ASSERT_EQ (1, system.nodes.front ()->peers.list ().size ());
ASSERT_EQ (system.nodes.front ()->peers.list ().front (), system.nodes.back ()->network.endpoint ());
ASSERT_EQ (1, node->peers.list ().size ());
ASSERT_EQ (system.nodes.back ()->peers.list ().front (), system.nodes.front ()->network.endpoint ());
// Stop the peer node and check that it is removed from the store
system.nodes.front ()->stop ();
system.deadline_set (10s);
while (system.nodes.back ()->peers.size () == 1)
{
ASSERT_NO_ERROR (system.poll ());
}
ASSERT_TRUE (system.nodes.back ()->peers.empty ());
// Uncontactable peer should not be stored
auto transaction (store.tx_begin_read ());
ASSERT_EQ (store.peer_count (transaction), 1);
ASSERT_TRUE (store.peer_exists (transaction, endpoint_key));
node->stop ();
}
namespace
{
void add_required_children_node_config_tree (nano::jsonconfig & tree)

View file

@ -18,14 +18,14 @@ using stream = std::basic_streambuf<uint8_t>;
template <typename T>
bool read (nano::stream & stream_a, T & value)
{
static_assert (std::is_pod<T>::value, "Can't stream read non-standard layout types");
static_assert (std::is_standard_layout<T>::value, "Can't stream read non-standard layout types");
auto amount_read (stream_a.sgetn (reinterpret_cast<uint8_t *> (&value), sizeof (value)));
return amount_read != sizeof (value);
}
template <typename T>
void write (nano::stream & stream_a, T const & value)
{
static_assert (std::is_pod<T>::value, "Can't stream write non-standard layout types");
static_assert (std::is_standard_layout<T>::value, "Can't stream write non-standard layout types");
auto amount_written (stream_a.sputn (reinterpret_cast<uint8_t const *> (&value), sizeof (value)));
assert (amount_written == sizeof (value));
}

View file

@ -45,6 +45,7 @@ int main (int argc, char * const * argv)
("debug_profile_votes", "Profile votes processing (only for nano_test_network)")
("debug_rpc", "Read an RPC command from stdin and invoke it. Network operations will have no effect.")
("debug_validate_blocks", "Check all blocks for correct hash, signature, work value")
("debug_peers", "Display peer IPv6:port connections")
("platform", boost::program_options::value<std::string> (), "Defines the <platform> for OpenCL commands")
("device", boost::program_options::value<std::string> (), "Defines <device> for OpenCL command")
("threads", boost::program_options::value<std::string> (), "Defines <threads> count for OpenCL command");
@ -813,6 +814,16 @@ int main (int argc, char * const * argv)
nano::remove_temporary_directories ();
std::cout << boost::str (boost::format ("%|1$ 12d| seconds \n%2% blocks per second") % seconds % (block_count / seconds)) << std::endl;
}
else if (vm.count ("debug_peers"))
{
nano::inactive_node node (data_path);
auto transaction (node.node->store.tx_begin ());
for (auto i (node.node->store.peers_begin (transaction)), n (node.node->store.peers_end ()); i != n; ++i)
{
std::cout << boost::str (boost::format ("%1%\n") % nano::endpoint (boost::asio::ip::address_v6 (i->first.address_bytes ()), i->first.port ()));
}
}
else if (vm.count ("version"))
{
std::cout << "Version " << NANO_VERSION_MAJOR << "." << NANO_VERSION_MINOR << std::endl;

View file

@ -115,6 +115,11 @@ mdb_val (sizeof (val_a), const_cast<nano::block_info *> (&val_a))
{
}
nano::mdb_val::mdb_val (nano::endpoint_key const & val_a) :
mdb_val (sizeof (val_a), const_cast<nano::endpoint_key *> (&val_a))
{
}
nano::mdb_val::mdb_val (std::shared_ptr<nano::block> const & val_a) :
buffer (std::make_shared<std::vector<uint8_t>> ())
{
@ -194,7 +199,14 @@ nano::mdb_val::operator std::array<char, 64> () const
return result;
}
nano::mdb_val::operator no_value () const
nano::mdb_val::operator nano::endpoint_key () const
{
nano::endpoint_key result;
std::copy (reinterpret_cast<uint8_t const *> (value.mv_data), reinterpret_cast<uint8_t const *> (value.mv_data) + sizeof (result), reinterpret_cast<uint8_t *> (&result));
return result;
}
nano::mdb_val::operator nano::no_value () const
{
return no_value::dummy;
}
@ -657,7 +669,7 @@ template class nano::mdb_iterator<nano::uint256_union, nano::uint256_union>;
template class nano::mdb_iterator<nano::uint256_union, std::shared_ptr<nano::block>>;
template class nano::mdb_iterator<nano::uint256_union, std::shared_ptr<nano::vote>>;
template class nano::mdb_iterator<nano::uint256_union, nano::wallet_value>;
template class nano::mdb_iterator<std::array<char, 64>, nano::mdb_val::no_value>;
template class nano::mdb_iterator<std::array<char, 64>, nano::no_value>;
nano::store_iterator<nano::account, nano::uint128_union> nano::mdb_store::representation_begin (nano::transaction const & transaction_a)
{
@ -701,24 +713,7 @@ nano::store_iterator<nano::account, std::shared_ptr<nano::vote>> nano::mdb_store
nano::mdb_store::mdb_store (bool & error_a, nano::logging & logging_a, boost::filesystem::path const & path_a, int lmdb_max_dbs) :
logging (logging_a),
env (error_a, path_a, lmdb_max_dbs),
frontiers (0),
accounts_v0 (0),
accounts_v1 (0),
send_blocks (0),
receive_blocks (0),
open_blocks (0),
change_blocks (0),
state_blocks_v0 (0),
state_blocks_v1 (0),
pending_v0 (0),
pending_v1 (0),
blocks_info (0),
representation (0),
unchecked (0),
vote (0),
meta (0),
stopped (false)
env (error_a, path_a, lmdb_max_dbs)
{
auto slow_upgrade (false);
if (!error_a)
@ -739,6 +734,7 @@ stopped (false)
error_a |= mdb_dbi_open (env.tx (transaction), "unchecked", MDB_CREATE, &unchecked) != 0;
error_a |= mdb_dbi_open (env.tx (transaction), "vote", MDB_CREATE, &vote) != 0;
error_a |= mdb_dbi_open (env.tx (transaction), "meta", MDB_CREATE, &meta) != 0;
error_a |= mdb_dbi_open (env.tx (transaction), "peers", MDB_CREATE, &peers) != 0;
if (!full_sideband (transaction))
{
error_a |= mdb_dbi_open (env.tx (transaction), "blocks_info", MDB_CREATE, &blocks_info) != 0;
@ -859,6 +855,53 @@ void nano::mdb_store::delete_node_id (nano::transaction const & transaction_a)
assert (!error || error == MDB_NOTFOUND);
}
void nano::mdb_store::peer_put (nano::transaction const & transaction_a, nano::endpoint_key const & endpoint_a)
{
nano::mdb_val junk;
auto status (mdb_put (env.tx (transaction_a), peers, nano::mdb_val (endpoint_a), junk, 0));
release_assert (status == 0);
}
void nano::mdb_store::peer_del (nano::transaction const & transaction_a, nano::endpoint_key const & endpoint_a)
{
auto status (mdb_del (env.tx (transaction_a), peers, nano::mdb_val (endpoint_a), nullptr));
release_assert (status == 0);
}
bool nano::mdb_store::peer_exists (nano::transaction const & transaction_a, nano::endpoint_key const & endpoint_a) const
{
nano::mdb_val junk;
auto status (mdb_get (env.tx (transaction_a), peers, nano::mdb_val (endpoint_a), junk));
release_assert (status == 0 || status == MDB_NOTFOUND);
return (status == 0);
}
size_t nano::mdb_store::peer_count (nano::transaction const & transaction_a) const
{
MDB_stat stats;
auto status (mdb_stat (env.tx (transaction_a), peers, &stats));
release_assert (status == 0);
return stats.ms_entries;
}
void nano::mdb_store::peer_clear (nano::transaction const & transaction_a)
{
auto status (mdb_drop (env.tx (transaction_a), peers, 0));
release_assert (status == 0);
}
nano::store_iterator<nano::endpoint_key, nano::no_value> nano::mdb_store::peers_begin (nano::transaction const & transaction_a)
{
nano::store_iterator<nano::endpoint_key, nano::no_value> result (std::make_unique<nano::mdb_iterator<nano::endpoint_key, nano::no_value>> (transaction_a, peers));
return result;
}
nano::store_iterator<nano::endpoint_key, nano::no_value> nano::mdb_store::peers_end ()
{
nano::store_iterator<nano::endpoint_key, nano::no_value> result (nano::store_iterator<nano::endpoint_key, nano::no_value> (nullptr));
return result;
}
void nano::mdb_store::do_upgrades (nano::transaction const & transaction_a, bool & slow_upgrade)
{
switch (version_get (transaction_a))

View file

@ -46,10 +46,6 @@ public:
class mdb_val
{
public:
enum class no_value
{
dummy
};
mdb_val (nano::epoch = nano::epoch::unspecified);
mdb_val (nano::account_info const &);
mdb_val (nano::block_info const &);
@ -59,6 +55,7 @@ public:
mdb_val (size_t, void *);
mdb_val (nano::uint128_union const &);
mdb_val (nano::uint256_union const &);
mdb_val (nano::endpoint_key const &);
mdb_val (std::shared_ptr<nano::block> const &);
mdb_val (std::shared_ptr<nano::vote> const &);
void * data () const;
@ -70,7 +67,8 @@ public:
explicit operator nano::uint128_union () const;
explicit operator nano::uint256_union () const;
explicit operator std::array<char, 64> () const;
explicit operator no_value () const;
explicit operator nano::endpoint_key () const;
explicit operator nano::no_value () const;
explicit operator std::shared_ptr<nano::block> () const;
explicit operator std::shared_ptr<nano::send_block> () const;
explicit operator std::shared_ptr<nano::receive_block> () const;
@ -264,6 +262,15 @@ public:
/** Deletes the node ID from the store */
void delete_node_id (nano::transaction const &) override;
void peer_put (nano::transaction const & transaction_a, nano::endpoint_key const & endpoint_a);
bool peer_exists (nano::transaction const & transaction_a, nano::endpoint_key const & endpoint_a) const;
void peer_del (nano::transaction const & transaction_a, nano::endpoint_key const & endpoint_a);
size_t peer_count (nano::transaction const & transaction_a) const;
void peer_clear (nano::transaction const & transaction_a);
nano::store_iterator<nano::endpoint_key, nano::no_value> peers_begin (nano::transaction const & transaction_a);
nano::store_iterator<nano::endpoint_key, nano::no_value> peers_end ();
void stop ();
nano::logging & logging;
@ -274,97 +281,103 @@ public:
* Maps head block to owning account
* nano::block_hash -> nano::account
*/
MDB_dbi frontiers;
MDB_dbi frontiers{ 0 };
/**
* Maps account v1 to account information, head, rep, open, balance, timestamp and block count.
* nano::account -> nano::block_hash, nano::block_hash, nano::block_hash, nano::amount, uint64_t, uint64_t
*/
MDB_dbi accounts_v0;
MDB_dbi accounts_v0{ 0 };
/**
* Maps account v0 to account information, head, rep, open, balance, timestamp and block count.
* nano::account -> nano::block_hash, nano::block_hash, nano::block_hash, nano::amount, uint64_t, uint64_t
*/
MDB_dbi accounts_v1;
MDB_dbi accounts_v1{ 0 };
/**
* Maps block hash to send block.
* nano::block_hash -> nano::send_block
*/
MDB_dbi send_blocks;
MDB_dbi send_blocks{ 0 };
/**
* Maps block hash to receive block.
* nano::block_hash -> nano::receive_block
*/
MDB_dbi receive_blocks;
MDB_dbi receive_blocks{ 0 };
/**
* Maps block hash to open block.
* nano::block_hash -> nano::open_block
*/
MDB_dbi open_blocks;
MDB_dbi open_blocks{ 0 };
/**
* Maps block hash to change block.
* nano::block_hash -> nano::change_block
*/
MDB_dbi change_blocks;
MDB_dbi change_blocks{ 0 };
/**
* Maps block hash to v0 state block.
* nano::block_hash -> nano::state_block
*/
MDB_dbi state_blocks_v0;
MDB_dbi state_blocks_v0{ 0 };
/**
* Maps block hash to v1 state block.
* nano::block_hash -> nano::state_block
*/
MDB_dbi state_blocks_v1;
MDB_dbi state_blocks_v1{ 0 };
/**
* Maps min_version 0 (destination account, pending block) to (source account, amount).
* nano::account, nano::block_hash -> nano::account, nano::amount
*/
MDB_dbi pending_v0;
MDB_dbi pending_v0{ 0 };
/**
* Maps min_version 1 (destination account, pending block) to (source account, amount).
* nano::account, nano::block_hash -> nano::account, nano::amount
*/
MDB_dbi pending_v1;
MDB_dbi pending_v1{ 0 };
/**
* Maps block hash to account and balance.
* block_hash -> nano::account, nano::amount
*/
MDB_dbi blocks_info;
MDB_dbi blocks_info{ 0 };
/**
* Representative weights.
* nano::account -> nano::uint128_t
*/
MDB_dbi representation;
MDB_dbi representation{ 0 };
/**
* Unchecked bootstrap blocks.
* nano::block_hash -> nano::block
*/
MDB_dbi unchecked;
MDB_dbi unchecked{ 0 };
/**
* Highest vote observed for account.
* nano::account -> uint64_t
*/
MDB_dbi vote;
MDB_dbi vote{ 0 };
/**
* Meta information about block store, such as versions.
* nano::uint256_union (arbitrary key) -> blob
*/
MDB_dbi meta;
MDB_dbi meta{ 0 };
/*
* Endpoints for peers
* nano::endpoint_key -> no_value
*/
MDB_dbi peers{ 0 };
private:
bool entry_has_sideband (MDB_val, nano::block_type);
@ -377,7 +390,7 @@ private:
boost::optional<MDB_val> block_raw_get_by_type (nano::transaction const &, nano::block_hash const &, nano::block_type &);
void block_raw_put (nano::transaction const &, MDB_dbi, nano::block_hash const &, MDB_val);
void clear (MDB_dbi);
bool stopped;
bool stopped{ false };
std::thread upgrades;
};
class wallet_value

View file

@ -21,6 +21,8 @@ std::chrono::seconds constexpr nano::node::cutoff;
std::chrono::seconds constexpr nano::node::syn_cookie_cutoff;
std::chrono::minutes constexpr nano::node::backup_interval;
std::chrono::seconds constexpr nano::node::search_pending_interval;
std::chrono::seconds constexpr nano::node::peer_interval;
int constexpr nano::port_mapping::mapping_timeout;
int constexpr nano::port_mapping::check_timeout;
unsigned constexpr nano::active_transactions::request_interval_ms;
@ -2279,6 +2281,7 @@ nano::process_return nano::node::process (nano::block const & block_a)
void nano::node::start ()
{
network.start ();
add_initial_peers ();
ongoing_keepalive ();
ongoing_syn_cookie_cleanup ();
if (!flags.disable_legacy_bootstrap)
@ -2288,6 +2291,7 @@ void nano::node::start ()
ongoing_store_flush ();
ongoing_rep_crawl ();
ongoing_rep_calculation ();
ongoing_peer_store ();
if (!flags.disable_bootstrap_listener)
{
bootstrap.start ();
@ -2307,7 +2311,6 @@ void nano::node::start ()
}
online_reps.recalculate_stake ();
port_mapping.start ();
add_initial_peers ();
}
void nano::node::stop ()
@ -2477,6 +2480,30 @@ void nano::node::ongoing_store_flush ()
});
}
void nano::node::ongoing_peer_store ()
{
auto endpoint_peers = peers.list ();
if (!endpoint_peers.empty ())
{
// Clear all peers then refresh with the current list of peers
auto transaction (store.tx_begin_write ());
store.peer_clear (transaction);
for (const auto & endpoint : endpoint_peers)
{
nano::endpoint_key endpoint_key (endpoint.address ().to_v6 ().to_bytes (), endpoint.port ());
store.peer_put (transaction, std::move (endpoint_key));
}
}
std::weak_ptr<nano::node> node_w (shared_from_this ());
alarm.add (std::chrono::steady_clock::now () + peer_interval, [node_w]() {
if (auto node_l = node_w.lock ())
{
node_l->ongoing_peer_store ();
}
});
}
void nano::node::backup_wallet ()
{
auto transaction (wallets.tx_begin_read ());
@ -2847,6 +2874,15 @@ uint64_t nano::node::work_generate_blocking (nano::uint256_union const & hash_a,
void nano::node::add_initial_peers ()
{
auto transaction (store.tx_begin_read ());
for (auto i (store.peers_begin (transaction)), n (store.peers_end ()); i != n; ++i)
{
nano::endpoint endpoint (boost::asio::ip::address_v6 (i->first.address_bytes ()), i->first.port ());
if (!peers.reachout (endpoint))
{
send_keepalive (endpoint);
}
}
}
void nano::node::block_confirm (std::shared_ptr<nano::block> block_a)

View file

@ -521,6 +521,7 @@ public:
void ongoing_rep_calculation ();
void ongoing_bootstrap ();
void ongoing_store_flush ();
void ongoing_peer_store ();
void backup_wallet ();
void search_pending ();
void bootstrap_wallet ();
@ -570,11 +571,12 @@ public:
const std::chrono::steady_clock::time_point startup_time;
static double constexpr price_max = 16.0;
static double constexpr free_cutoff = 1024.0;
static std::chrono::seconds constexpr period = std::chrono::seconds (60);
static std::chrono::seconds constexpr period = (nano::nano_network == nano::nano_networks::nano_test_network) ? std::chrono::seconds (1) : std::chrono::seconds (60);
static std::chrono::seconds constexpr cutoff = period * 5;
static std::chrono::seconds constexpr syn_cookie_cutoff = std::chrono::seconds (5);
static std::chrono::minutes constexpr backup_interval = std::chrono::minutes (5);
static std::chrono::seconds constexpr search_pending_interval = (nano::nano_network == nano::nano_networks::nano_test_network) ? std::chrono::seconds (1) : std::chrono::seconds (5 * 60);
static std::chrono::seconds constexpr peer_interval = search_pending_interval;
};
class thread_runner
{

View file

@ -15,10 +15,7 @@ endpoint (endpoint_a),
ip_address (endpoint_a.address ()),
last_contact (std::chrono::steady_clock::now ()),
last_attempt (last_contact),
last_bootstrap_attempt (std::chrono::steady_clock::time_point ()),
last_rep_request (std::chrono::steady_clock::time_point ()),
last_rep_response (std::chrono::steady_clock::time_point ()),
rep_weight (0),
network_version (network_version_a),
node_id (node_id_a)
{
@ -28,13 +25,7 @@ nano::peer_information::peer_information (nano::endpoint const & endpoint_a, std
endpoint (endpoint_a),
ip_address (endpoint_a.address ()),
last_contact (last_contact_a),
last_attempt (last_attempt_a),
last_bootstrap_attempt (std::chrono::steady_clock::time_point ()),
last_rep_request (std::chrono::steady_clock::time_point ()),
last_rep_response (std::chrono::steady_clock::time_point ()),
rep_weight (0),
network_version (nano::protocol_version),
node_id ()
last_attempt (last_attempt_a)
{
}

View file

@ -50,12 +50,12 @@ public:
boost::asio::ip::address ip_address;
std::chrono::steady_clock::time_point last_contact;
std::chrono::steady_clock::time_point last_attempt;
std::chrono::steady_clock::time_point last_bootstrap_attempt;
std::chrono::steady_clock::time_point last_rep_request;
std::chrono::steady_clock::time_point last_rep_response;
nano::amount rep_weight;
std::chrono::steady_clock::time_point last_bootstrap_attempt{ std::chrono::steady_clock::time_point () };
std::chrono::steady_clock::time_point last_rep_request{ std::chrono::steady_clock::time_point () };
std::chrono::steady_clock::time_point last_rep_response{ std::chrono::steady_clock::time_point () };
nano::amount rep_weight{ 0 };
nano::account probable_rep_account;
unsigned network_version;
unsigned network_version{ nano::protocol_version };
boost::optional<nano::account> node_id;
bool operator< (nano::peer_information const &) const;
};

View file

@ -1325,8 +1325,8 @@ thread ([this]() {
assert (status == 0);
std::string beginning (nano::uint256_union (0).to_string ());
std::string end ((nano::uint256_union (nano::uint256_t (0) - nano::uint256_t (1))).to_string ());
nano::store_iterator<std::array<char, 64>, nano::mdb_val::no_value> i (std::make_unique<nano::mdb_iterator<std::array<char, 64>, nano::mdb_val::no_value>> (transaction, handle, nano::mdb_val (beginning.size (), const_cast<char *> (beginning.c_str ()))));
nano::store_iterator<std::array<char, 64>, nano::mdb_val::no_value> n (std::make_unique<nano::mdb_iterator<std::array<char, 64>, nano::mdb_val::no_value>> (transaction, handle, nano::mdb_val (end.size (), const_cast<char *> (end.c_str ()))));
nano::store_iterator<std::array<char, 64>, nano::no_value> i (std::make_unique<nano::mdb_iterator<std::array<char, 64>, nano::no_value>> (transaction, handle, nano::mdb_val (beginning.size (), const_cast<char *> (beginning.c_str ()))));
nano::store_iterator<std::array<char, 64>, nano::no_value> n (std::make_unique<nano::mdb_iterator<std::array<char, 64>, nano::no_value>> (transaction, handle, nano::mdb_val (end.size (), const_cast<char *> (end.c_str ()))));
for (; i != n; ++i)
{
nano::uint256_union id;
@ -1427,8 +1427,8 @@ void nano::wallets::reload ()
std::unordered_set<nano::uint256_union> stored_items;
std::string beginning (nano::uint256_union (0).to_string ());
std::string end ((nano::uint256_union (nano::uint256_t (0) - nano::uint256_t (1))).to_string ());
nano::store_iterator<std::array<char, 64>, nano::mdb_val::no_value> i (std::make_unique<nano::mdb_iterator<std::array<char, 64>, nano::mdb_val::no_value>> (transaction, handle, nano::mdb_val (beginning.size (), const_cast<char *> (beginning.c_str ()))));
nano::store_iterator<std::array<char, 64>, nano::mdb_val::no_value> n (std::make_unique<nano::mdb_iterator<std::array<char, 64>, nano::mdb_val::no_value>> (transaction, handle, nano::mdb_val (end.size (), const_cast<char *> (end.c_str ()))));
nano::store_iterator<std::array<char, 64>, nano::no_value> i (std::make_unique<nano::mdb_iterator<std::array<char, 64>, nano::no_value>> (transaction, handle, nano::mdb_val (beginning.size (), const_cast<char *> (beginning.c_str ()))));
nano::store_iterator<std::array<char, 64>, nano::no_value> n (std::make_unique<nano::mdb_iterator<std::array<char, 64>, nano::no_value>> (transaction, handle, nano::mdb_val (end.size (), const_cast<char *> (end.c_str ()))));
for (; i != n; ++i)
{
nano::uint256_union id;
@ -1591,8 +1591,8 @@ void nano::wallets::split_if_needed (nano::transaction & transaction_destination
MDB_txn * tx_destination (*boost::polymorphic_downcast<nano::mdb_txn *> (transaction_destination.impl.get ()));
std::string beginning (nano::uint256_union (0).to_string ());
std::string end ((nano::uint256_union (nano::uint256_t (0) - nano::uint256_t (1))).to_string ());
nano::store_iterator<std::array<char, 64>, nano::mdb_val::no_value> i (std::make_unique<nano::mdb_iterator<std::array<char, 64>, nano::mdb_val::no_value>> (transaction_source, handle, nano::mdb_val (beginning.size (), const_cast<char *> (beginning.c_str ()))));
nano::store_iterator<std::array<char, 64>, nano::mdb_val::no_value> n (std::make_unique<nano::mdb_iterator<std::array<char, 64>, nano::mdb_val::no_value>> (transaction_source, handle, nano::mdb_val (end.size (), const_cast<char *> (end.c_str ()))));
nano::store_iterator<std::array<char, 64>, nano::no_value> i (std::make_unique<nano::mdb_iterator<std::array<char, 64>, nano::no_value>> (transaction_source, handle, nano::mdb_val (beginning.size (), const_cast<char *> (beginning.c_str ()))));
nano::store_iterator<std::array<char, 64>, nano::no_value> n (std::make_unique<nano::mdb_iterator<std::array<char, 64>, nano::no_value>> (transaction_source, handle, nano::mdb_val (end.size (), const_cast<char *> (end.c_str ()))));
for (; i != n; ++i)
{
nano::uint256_union id;

View file

@ -290,6 +290,14 @@ public:
virtual void version_put (nano::transaction const &, int) = 0;
virtual int version_get (nano::transaction const &) = 0;
virtual void peer_put (nano::transaction const & transaction_a, nano::endpoint_key const & endpoint_a) = 0;
virtual void peer_del (nano::transaction const & transaction_a, nano::endpoint_key const & endpoint_a) = 0;
virtual bool peer_exists (nano::transaction const & transaction_a, nano::endpoint_key const & endpoint_a) const = 0;
virtual size_t peer_count (nano::transaction const & transaction_a) const = 0;
virtual void peer_clear (nano::transaction const & transaction_a) = 0;
virtual nano::store_iterator<nano::endpoint_key, nano::no_value> peers_begin (nano::transaction const & transaction_a) = 0;
virtual nano::store_iterator<nano::endpoint_key, nano::no_value> peers_end () = 0;
// Requires a write transaction
virtual nano::raw_key get_node_id (nano::transaction const &) = 0;

View file

@ -6,6 +6,7 @@
#include <nano/secure/blockstore.hpp>
#include <nano/secure/versioning.hpp>
#include <boost/endian/conversion.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <queue>
@ -304,6 +305,21 @@ nano::block_hash nano::pending_key::key () const
return account;
}
nano::endpoint_key::endpoint_key (const std::array<uint8_t, 16> & address_a, uint16_t port_a) :
address (address_a), network_port (boost::endian::native_to_big (port_a))
{
}
const std::array<uint8_t, 16> & nano::endpoint_key::address_bytes () const
{
return address;
}
uint16_t nano::endpoint_key::port () const
{
return boost::endian::big_to_native (network_port);
}
nano::block_info::block_info () :
account (0),
balance (0)

View file

@ -122,6 +122,39 @@ public:
nano::block_hash hash;
nano::block_hash key () const;
};
class endpoint_key
{
public:
endpoint_key () = default;
/*
* @param address_a This should be in network byte order
* @param port_a This should be in host byte order
*/
endpoint_key (const std::array<uint8_t, 16> & address_a, uint16_t port_a);
/*
* @return The ipv6 address in network byte order
*/
const std::array<uint8_t, 16> & address_bytes () const;
/*
* @return The port in host byte order
*/
uint16_t port () const;
private:
// Both stored internally in network byte order
std::array<uint8_t, 16> address;
uint16_t network_port{ 0 };
};
enum class no_value
{
dummy
};
// Internally unchecked_key is equal to pending_key (2x uint256_union)
using unchecked_key = pending_key;