Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/bitcoin/network/net.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ class BCT_API net
virtual void fetch(address_handler&& handler) NOEXCEPT;
virtual void save(const address_cptr& message,
count_handler&& complete) NOEXCEPT;
virtual void seed() NOEXCEPT;

/// P2P loopback detection.
virtual bool store_nonce(const channel_peer& channel) NOEXCEPT;
Expand Down Expand Up @@ -344,6 +345,7 @@ class BCT_API net
void do_fetch(const address_handler& handler) NOEXCEPT;
void do_save(const address_cptr& message,
const count_handler& handler) NOEXCEPT;
void do_seed() NOEXCEPT;

// P2P diagnostic accumulators.
void do_fetch_totals(const totals_handler& handler) NOEXCEPT;
Expand All @@ -362,6 +364,7 @@ class BCT_API net

// These are protected by strand.
session_manual::ptr manual_{};
session_seed::ptr seed_{};
threadpool threadpool_;

// This is thread safe.
Expand Down
3 changes: 3 additions & 0 deletions include/bitcoin/network/sessions/session_peer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ class BCT_API session_peer
virtual void save(const address_cptr& message,
count_handler&& handler) const NOEXCEPT;

/// Seed the address pool if below minimum, unless seeding or backing off.
virtual void seed() const NOEXCEPT;

/// Properties.
/// -----------------------------------------------------------------------

Expand Down
11 changes: 11 additions & 0 deletions include/bitcoin/network/sessions/session_seed.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ class BCT_API session_seed
/// Seeding is complete invocation of the handler.
void start(result_handler&& handler) NOEXCEPT override;

/// Seed connections are running (call from network strand).
virtual bool seeding() const NOEXCEPT;

/// Time seed connections last completed, zero if never (call from network
/// strand).
virtual steady_clock::time_point completed() const NOEXCEPT;

protected:
/// The configured options for this peer session (covariant).
const options_t& options() const NOEXCEPT override;
Expand Down Expand Up @@ -77,6 +84,10 @@ class BCT_API session_seed
const channel::ptr& channel) NOEXCEPT;
void handle_channel_stop(const code& ec,
const channel::ptr& channel, const race::ptr& racer) NOEXCEPT;

// These are protected by strand.
steady_clock::time_point completed_{};
bool seeding_{};
};

} // namespace network
Expand Down
42 changes: 40 additions & 2 deletions src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ using namespace system;
using namespace std::placeholders;
constexpr auto encryption = messages::peer::service::node_encrypted_transport;

// Seeding is not repeated within this many seeding timeouts of completion.
constexpr auto seed_backoff = 10;

net::net(const settings& settings, const logger& log,
uint64_t required_services, uint64_t provided_services) NOEXCEPT
: settings_(settings),
Expand Down Expand Up @@ -217,7 +220,8 @@ void net::handle_start(const code& ec, const result_handler& handler) NOEXCEPT
return;
}

attach_seed_session()->start(move_copy(handler));
seed_ = attach_seed_session();
seed_->start(move_copy(handler));
}

// Run sequence (seeding may be ongoing after its handler is invoked).
Expand Down Expand Up @@ -296,8 +300,9 @@ void net::do_close() NOEXCEPT
{
BC_ASSERT(stranded());

// Release reference to manual session (also held by stop subscriber).
// Release session references (also held by stop subscriber).
if (manual_) manual_.reset();
if (seed_) seed_.reset();

// Notify and delete all stop subscribers (all sessions).
stop_subscriber_.stop(error::service_stopped);
Expand Down Expand Up @@ -703,6 +708,39 @@ void net::do_save(const address_cptr& message,
hosts_.save(message, move_copy(handler));
}

void net::seed() NOEXCEPT
{
boost::asio::post(strand_,
std::bind(&net::do_seed, this));
}

void net::do_seed() NOEXCEPT
{
BC_ASSERT(stranded());

// address_not_found may only mean that no pooled address suits the slot,
// so seed only below the minimum (and never without seeds).
const auto& outbound = network_settings().outbound;
if (closed() || outbound.seeds.empty() ||
address_count() >= outbound.minimum_address_count())
return;

// The startup seed session is retained before outbound can seed.
BC_ASSERT(seed_);

// One seed session at a time, and none soon after one completes.
const auto completed = seed_->completed();
const auto backoff = outbound.seeding_timeout() * seed_backoff;

if (seed_->seeding() || (completed != steady_clock::time_point{} &&
(steady_clock::now() - completed) < backoff))
return;

// The handler signals sufficiency, seeding ends upon completion.
seed_ = attach_seed_session();
seed_->start([](const code&) NOEXCEPT {});
}

// P2P self address.
// ----------------------------------------------------------------------------

Expand Down
1 change: 1 addition & 0 deletions src/sessions/session_outbound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ void session_outbound::handle_connect(const code& ec,
if (ec == error::address_not_found)
{
LOGS("Address pool is empty.");
seed();
defer(network_settings().connect_timeout(options()),
BIND(start_connect, _1, slot));
return;
Expand Down
5 changes: 5 additions & 0 deletions src/sessions/session_peer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,11 @@ void session_peer::save(const address_cptr& message,
network_.save(message, std::move(handler));
}

void session_peer::seed() const NOEXCEPT
{
network_.seed();
}

BC_POP_WARNING()
BC_POP_WARNING()
BC_POP_WARNING()
Expand Down
16 changes: 16 additions & 0 deletions src/sessions/session_seed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,18 @@ const session_seed::options_t& session_seed::options() const NOEXCEPT
return static_cast<const options_t&>(session_peer::options());
}

bool session_seed::seeding() const NOEXCEPT
{
BC_ASSERT(stranded());
return seeding_;
}

steady_clock::time_point session_seed::completed() const NOEXCEPT
{
BC_ASSERT(stranded());
return completed_;
}

// Start/stop sequence.
// ----------------------------------------------------------------------------

Expand Down Expand Up @@ -122,6 +134,8 @@ void session_seed::handle_started(const code& ec,
const auto racer = std::make_shared<race>(seeds, required);
BC_POP_WARNING()

seeding_ = true;

// Invoke sufficient on count, invoke complete with all seeds stopped.
racer->start(move_copy(handler), BIND(stop_seed, _1));

Expand Down Expand Up @@ -278,6 +292,8 @@ void session_seed::stop_seed(const code&) NOEXCEPT
BC_ASSERT(stranded());

LOGN("Seed session complete.");
completed_ = steady_clock::now();
seeding_ = false;
unsubscribe_close();
}

Expand Down
Loading
Loading