Skip to content

Commit b929322

Browse files
authored
Merge pull request #1244 from AntelopeIO/GH-1227-auto-bp-peer
P2P: Update p2p-auto-bp-peer for Savanna
2 parents ab69249 + a1f55d6 commit b929322

File tree

4 files changed

+124
-186
lines changed

4 files changed

+124
-186
lines changed

plugins/net_plugin/include/eosio/net_plugin/auto_bp_peering.hpp

+37-81
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,9 @@
77
namespace eosio::auto_bp_peering {
88

99
///
10-
/// This file implements the functionality for block producers automatically establishing p2p connections to their
11-
/// neighbors on the producer schedule.
10+
/// This file implements the functionality for block producers automatically establishing p2p connections to other bps.
1211
///
1312

14-
15-
1613
template <typename Derived, typename Connection>
1714
class bp_connection_manager {
1815
#ifdef BOOST_TEST
@@ -31,8 +28,8 @@ class bp_connection_manager {
3128
} config; // thread safe only because modified at plugin startup currently
3229

3330
// the following member are only accessed from main thread
34-
flat_set<account_name> pending_neighbors;
35-
flat_set<account_name> active_neighbors;
31+
flat_set<account_name> pending_configured_bps;
32+
flat_set<account_name> active_configured_bps;
3633
uint32_t pending_schedule_version = 0;
3734
uint32_t active_schedule_version = 0;
3835

@@ -44,56 +41,21 @@ class bp_connection_manager {
4441
return boost::algorithm::join(peers | boost::adaptors::transformed([](auto& p) { return p.to_string(); }), ",");
4542
}
4643

47-
class neighbor_finder_type {
48-
49-
const config_t& config;
50-
const std::vector<chain::producer_authority>& schedule;
51-
chain::flat_set<std::size_t> my_schedule_indices;
52-
53-
public:
54-
neighbor_finder_type(const config_t& config,
55-
const std::vector<chain::producer_authority>& schedule)
56-
: config(config), schedule(schedule) {
57-
for (auto account : config.my_bp_accounts) {
58-
auto itr = std::find_if(schedule.begin(), schedule.end(),
59-
[account](auto& e) { return e.producer_name == account; });
60-
if (itr != schedule.end())
61-
my_schedule_indices.insert(itr - schedule.begin());
62-
}
63-
}
64-
65-
void add_neighbors_with_distance(chain::flat_set<account_name>& result, int distance) const {
66-
for (auto schedule_index : my_schedule_indices) {
67-
auto i = (schedule_index + distance) % schedule.size();
68-
if (!my_schedule_indices.count(i)) {
69-
auto name = schedule[i].producer_name;
70-
if (config.bp_peer_addresses.count(name))
71-
result.insert(name);
72-
}
44+
// Only called from main thread
45+
chain::flat_set<account_name> configured_bp_accounts(const config_t& config,
46+
const std::vector<chain::producer_authority>& schedule) const
47+
{
48+
chain::flat_set<account_name> result;
49+
for (const auto& auth : schedule) {
50+
if (config.bp_peer_addresses.contains(auth.producer_name)) {
51+
result.insert(auth.producer_name);
7352
}
7453
}
75-
76-
flat_set<account_name> downstream_neighbors() const {
77-
chain::flat_set<account_name> result;
78-
for (std::size_t i = 0; i < proximity_count; ++i) { add_neighbors_with_distance(result, i + 1); }
79-
return result;
80-
}
81-
82-
void add_upstream_neighbors(chain::flat_set<account_name>& result) const {
83-
for (std::size_t i = 0; i < proximity_count; ++i) { add_neighbors_with_distance(result, -1 - i); }
84-
}
85-
86-
flat_set<account_name> neighbors() const {
87-
flat_set<account_name> result = downstream_neighbors();
88-
add_upstream_neighbors(result);
89-
return result;
90-
}
91-
};
54+
return result;
55+
}
9256

9357
public:
94-
const static std::size_t proximity_count = 2;
95-
96-
bool auto_bp_peering_enabled() const { return config.bp_peer_addresses.size() && config.my_bp_accounts.size(); }
58+
bool auto_bp_peering_enabled() const { return !config.bp_peer_addresses.empty(); }
9759

9860
// Only called at plugin startup
9961
void set_producer_accounts(const std::set<account_name>& accounts) {
@@ -117,6 +79,7 @@ class bp_connection_manager {
11779

11880
config.bp_peer_accounts[addr] = account;
11981
config.bp_peer_addresses[account] = std::move(addr);
82+
fc_dlog(self()->get_logger(), "Setting auto-bp-peer ${a} -> ${d}", ("a", account)("d", config.bp_peer_addresses[account]));
12083
}
12184
} catch (eosio::chain::name_type_exception&) {
12285
EOS_ASSERT(false, chain::plugin_config_exception, "the account supplied by --auto-bp-peer option is invalid");
@@ -167,67 +130,60 @@ class bp_connection_manager {
167130
established_client_connection(new_connection) && num_established_clients() > self()->connections.get_max_client_count();
168131
}
169132

170-
// Only called from main thread
171-
neighbor_finder_type neighbor_finder(const std::vector<chain::producer_authority>& schedule) const {
172-
return neighbor_finder_type(config, schedule);
173-
}
174-
175133
// Only called from main thread
176134
void on_pending_schedule(const chain::producer_authority_schedule& schedule) {
177-
if (auto_bp_peering_enabled() && self()->in_sync()) {
135+
if (auto_bp_peering_enabled() && !self()->is_lib_catchup()) {
178136
if (schedule.producers.size()) {
179137
if (pending_schedule_version != schedule.version) {
180-
/// establish connection to the BPs within our pending scheduling proximity
138+
/// establish connection to our configured BPs, resolve_and_connect ignored if already connected
181139

182140
fc_dlog(self()->get_logger(), "pending producer schedule switches from version ${old} to ${new}",
183141
("old", pending_schedule_version)("new", schedule.version));
184142

185-
auto finder = neighbor_finder(schedule.producers);
186-
auto pending_downstream_neighbors = finder.downstream_neighbors();
143+
auto pending_connections = configured_bp_accounts(config, schedule.producers);
187144

188-
fc_dlog(self()->get_logger(), "pending_downstream_neighbors: ${pending_downstream_neighbors}",
189-
("pending_downstream_neighbors", to_string(pending_downstream_neighbors)));
190-
for (auto neighbor : pending_downstream_neighbors) { self()->connections.resolve_and_connect(config.bp_peer_addresses[neighbor], self()->get_first_p2p_address() ); }
145+
fc_dlog(self()->get_logger(), "pending_connections: ${c}", ("c", to_string(pending_connections)));
146+
for (const auto& i : pending_connections) {
147+
self()->connections.resolve_and_connect(config.bp_peer_addresses[i], self()->get_first_p2p_address() );
148+
}
191149

192-
pending_neighbors = std::move(pending_downstream_neighbors);
193-
finder.add_upstream_neighbors(pending_neighbors);
150+
pending_configured_bps = std::move(pending_connections);
194151

195152
pending_schedule_version = schedule.version;
196153
}
197154
} else {
198-
fc_dlog(self()->get_logger(), "pending producer schedule version ${v} has being cleared",
199-
("v", schedule.version));
200-
pending_neighbors.clear();
155+
fc_dlog(self()->get_logger(), "pending producer schedule version ${v} is being cleared", ("v", schedule.version));
156+
pending_configured_bps.clear();
201157
}
202158
}
203159
}
204160

205161
// Only called from main thread
206162
void on_active_schedule(const chain::producer_authority_schedule& schedule) {
207-
if (auto_bp_peering_enabled() && active_schedule_version != schedule.version && self()->in_sync()) {
163+
if (auto_bp_peering_enabled() && active_schedule_version != schedule.version && !self()->is_lib_catchup()) {
208164
/// drops any BP connection which is no longer within our scheduling proximity
209-
210165
fc_dlog(self()->get_logger(), "active producer schedule switches from version ${old} to ${new}",
211166
("old", active_schedule_version)("new", schedule.version));
212167

213-
auto old_neighbors = std::move(active_neighbors);
214-
active_neighbors = neighbor_finder(schedule.producers).neighbors();
168+
auto old_bps = std::move(active_configured_bps);
169+
active_configured_bps = configured_bp_accounts(config, schedule.producers);
215170

216-
fc_dlog(self()->get_logger(), "active_neighbors: ${active_neighbors}",
217-
("active_neighbors", to_string(active_neighbors)));
171+
fc_dlog(self()->get_logger(), "active_configured_bps: ${a}", ("a", to_string(active_configured_bps)));
218172

219173
flat_set<account_name> peers_to_stay;
220-
std::set_union(active_neighbors.begin(), active_neighbors.end(), pending_neighbors.begin(),
221-
pending_neighbors.end(), std::inserter(peers_to_stay, peers_to_stay.begin()));
174+
std::set_union(active_configured_bps.begin(), active_configured_bps.end(), pending_configured_bps.begin(), pending_configured_bps.end(),
175+
std::inserter(peers_to_stay, peers_to_stay.begin()));
222176

223-
fc_dlog(self()->get_logger(), "peers_to_stay: ${peers_to_stay}", ("peers_to_stay", to_string(peers_to_stay)));
177+
fc_dlog(self()->get_logger(), "peers_to_stay: ${p}", ("p", to_string(peers_to_stay)));
224178

225179
std::vector<account_name> peers_to_drop;
226-
std::set_difference(old_neighbors.begin(), old_neighbors.end(), peers_to_stay.begin(), peers_to_stay.end(),
180+
std::set_difference(old_bps.begin(), old_bps.end(), peers_to_stay.begin(), peers_to_stay.end(),
227181
std::back_inserter(peers_to_drop));
228-
fc_dlog(self()->get_logger(), "peers to drop: ${peers_to_drop}", ("peers_to_drop", to_string(peers_to_drop)));
182+
fc_dlog(self()->get_logger(), "peers to drop: ${p}", ("p", to_string(peers_to_drop)));
229183

230-
for (auto account : peers_to_drop) { self()->connections.disconnect(config.bp_peer_addresses[account]); }
184+
for (const auto& account : peers_to_drop) {
185+
self()->connections.disconnect(config.bp_peer_addresses[account]);
186+
}
231187
active_schedule_version = schedule.version;
232188
}
233189
}

plugins/net_plugin/net_plugin.cpp

+10-6
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ namespace eosio {
189189
static void send_handshakes();
190190
static void send_block_nack_resets();
191191
bool syncing_from_peer() const { return sync_state == lib_catchup; }
192-
bool is_in_sync() const { return sync_state == in_sync; }
192+
bool is_lib_catchup() const { return sync_state == lib_catchup; }
193193
void sync_reset_fork_db_root_num( const connection_ptr& conn, bool closing );
194194
void sync_timeout(const connection_ptr& c, const boost::system::error_code& ec);
195195
void sync_wait(const connection_ptr& c);
@@ -523,7 +523,11 @@ namespace eosio {
523523
void plugin_initialize(const variables_map& options);
524524
void plugin_startup();
525525
void plugin_shutdown();
526-
bool in_sync() const;
526+
527+
// Conceptually interested if node is synced. Checking against in_sync is not recommended as a node can temporarily
528+
// switch to head_catchup on delayed blocks. Better to check not in lib_catchup.
529+
bool is_lib_catchup() const;
530+
527531
fc::logger& get_logger() { return logger; }
528532

529533
void create_session(tcp::socket&& socket, const string listen_address, size_t limit);
@@ -2647,7 +2651,7 @@ namespace eosio {
26472651
}
26482652
} else {
26492653
set_state( in_sync );
2650-
fc_dlog(logger, "Switching to in_sync, will send handshakes when caught up");
2654+
fc_dlog(logger, "Switching to not lib_catchup, will send handshakes when caught up");
26512655
send_handshakes_when_synced = true;
26522656
}
26532657
} else if( state == lib_catchup ) {
@@ -2709,7 +2713,7 @@ namespace eosio {
27092713
}
27102714
}
27112715
}
2712-
} else { // in_sync
2716+
} else { // not lib_catchup
27132717
if (blk_applied) {
27142718
send_handshakes_if_synced(blk_latency);
27152719
}
@@ -4722,8 +4726,8 @@ namespace eosio {
47224726
return 0;
47234727
}
47244728

4725-
bool net_plugin_impl::in_sync() const {
4726-
return sync_master->is_in_sync();
4729+
bool net_plugin_impl::is_lib_catchup() const {
4730+
return sync_master->is_lib_catchup();
47274731
}
47284732

47294733
void net_plugin::register_update_p2p_connection_metrics(std::function<void(net_plugin::p2p_connections_metrics)>&& fun){

0 commit comments

Comments
 (0)