Transport loopback channel (#2970)
* Transport loopback channel Adds `nano::transport::loopback_channel` as the initial effort towards removing UDP. A loopback UDP channel is currently used when processing local votes, and the rep crawler can receive and use that channel if by chance the hash was active. This seems to occur in `node.aggressive_flooding` and sometimes lead to failures. Now, by being explicit about the channel type, these channels are not inserted as peer representatives. Those making use of an abstract channel to send data must ensure data is not sent to a loopback_channel. This is enforced with a release_assert. * Improve network.loopback_channel test
This commit is contained in:
parent
abf9014568
commit
537ba91587
15 changed files with 137 additions and 34 deletions
|
|
@ -181,7 +181,7 @@ TEST (active_transactions, inactive_votes_cache)
|
|||
.work (*system.work.generate (latest))
|
||||
.build_shared ();
|
||||
auto vote (std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 0, std::vector<nano::block_hash> (1, send->hash ())));
|
||||
node.vote_processor.vote (vote, std::make_shared<nano::transport::channel_udp> (node.network.udp_channels, node.network.endpoint (), node.network_params.protocol.protocol_version));
|
||||
node.vote_processor.vote (vote, std::make_shared<nano::transport::channel_loopback> (node));
|
||||
ASSERT_TIMELY (5s, node.active.inactive_votes_cache_size () == 1);
|
||||
node.process_active (send);
|
||||
node.block_processor.flush ();
|
||||
|
|
@ -211,7 +211,7 @@ TEST (active_transactions, inactive_votes_cache_fork)
|
|||
.work (*system.work.generate (latest))
|
||||
.build_shared ();
|
||||
auto vote (std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 0, std::vector<nano::block_hash> (1, send1->hash ())));
|
||||
node.vote_processor.vote (vote, std::make_shared<nano::transport::channel_udp> (node.network.udp_channels, node.network.endpoint (), node.network_params.protocol.protocol_version));
|
||||
node.vote_processor.vote (vote, std::make_shared<nano::transport::channel_loopback> (node));
|
||||
auto channel1 (node.network.udp_channels.create (node.network.endpoint ()));
|
||||
ASSERT_TIMELY (5s, node.active.inactive_votes_cache_size () == 1);
|
||||
node.network.process_message (nano::publish (send2), channel1);
|
||||
|
|
@ -264,7 +264,7 @@ TEST (active_transactions, inactive_votes_cache_existing_vote)
|
|||
ASSERT_GT (node.weight (key.pub), node.minimum_principal_weight ());
|
||||
// Insert vote
|
||||
auto vote1 (std::make_shared<nano::vote> (key.pub, key.prv, 1, std::vector<nano::block_hash> (1, send->hash ())));
|
||||
node.vote_processor.vote (vote1, std::make_shared<nano::transport::channel_udp> (node.network.udp_channels, node.network.endpoint (), node.network_params.protocol.protocol_version));
|
||||
node.vote_processor.vote (vote1, std::make_shared<nano::transport::channel_loopback> (node));
|
||||
system.deadline_set (5s);
|
||||
ASSERT_TIMELY (5s, election->votes ().size () == 2)
|
||||
ASSERT_EQ (1, node.stats.count (nano::stat::type::election, nano::stat::detail::vote_new));
|
||||
|
|
@ -325,9 +325,9 @@ TEST (active_transactions, inactive_votes_cache_multiple_votes)
|
|||
node.block_processor.flush ();
|
||||
// Process votes
|
||||
auto vote1 (std::make_shared<nano::vote> (key1.pub, key1.prv, 0, std::vector<nano::block_hash> (1, send1->hash ())));
|
||||
node.vote_processor.vote (vote1, std::make_shared<nano::transport::channel_udp> (node.network.udp_channels, node.network.endpoint (), node.network_params.protocol.protocol_version));
|
||||
node.vote_processor.vote (vote1, std::make_shared<nano::transport::channel_loopback> (node));
|
||||
auto vote2 (std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 0, std::vector<nano::block_hash> (1, send1->hash ())));
|
||||
node.vote_processor.vote (vote2, std::make_shared<nano::transport::channel_udp> (node.network.udp_channels, node.network.endpoint (), node.network_params.protocol.protocol_version));
|
||||
node.vote_processor.vote (vote2, std::make_shared<nano::transport::channel_loopback> (node));
|
||||
system.deadline_set (5s);
|
||||
while (true)
|
||||
{
|
||||
|
|
@ -470,23 +470,23 @@ TEST (active_transactions, inactive_votes_cache_election_start)
|
|||
// Inactive votes
|
||||
std::vector<nano::block_hash> hashes{ open1->hash (), open2->hash (), open3->hash (), open4->hash (), open5->hash (), send7->hash () };
|
||||
auto vote1 (std::make_shared<nano::vote> (key1.pub, key1.prv, 0, hashes));
|
||||
node.vote_processor.vote (vote1, std::make_shared<nano::transport::channel_udp> (node.network.udp_channels, node.network.endpoint (), node.network_params.protocol.protocol_version));
|
||||
node.vote_processor.vote (vote1, std::make_shared<nano::transport::channel_loopback> (node));
|
||||
auto vote2 (std::make_shared<nano::vote> (key2.pub, key2.prv, 0, hashes));
|
||||
node.vote_processor.vote (vote2, std::make_shared<nano::transport::channel_udp> (node.network.udp_channels, node.network.endpoint (), node.network_params.protocol.protocol_version));
|
||||
node.vote_processor.vote (vote2, std::make_shared<nano::transport::channel_loopback> (node));
|
||||
auto vote3 (std::make_shared<nano::vote> (key3.pub, key3.prv, 0, hashes));
|
||||
node.vote_processor.vote (vote3, std::make_shared<nano::transport::channel_udp> (node.network.udp_channels, node.network.endpoint (), node.network_params.protocol.protocol_version));
|
||||
node.vote_processor.vote (vote3, std::make_shared<nano::transport::channel_loopback> (node));
|
||||
auto vote4 (std::make_shared<nano::vote> (key4.pub, key4.prv, 0, hashes));
|
||||
node.vote_processor.vote (vote4, std::make_shared<nano::transport::channel_udp> (node.network.udp_channels, node.network.endpoint (), node.network_params.protocol.protocol_version));
|
||||
node.vote_processor.vote (vote4, std::make_shared<nano::transport::channel_loopback> (node));
|
||||
ASSERT_TIMELY (5s, node.active.inactive_votes_cache_size () == 6);
|
||||
ASSERT_TRUE (node.active.empty ());
|
||||
ASSERT_EQ (1, node.ledger.cache.cemented_count);
|
||||
// 5 votes are required to start election
|
||||
auto vote5 (std::make_shared<nano::vote> (key5.pub, key5.prv, 0, hashes));
|
||||
node.vote_processor.vote (vote5, std::make_shared<nano::transport::channel_udp> (node.network.udp_channels, node.network.endpoint (), node.network_params.protocol.protocol_version));
|
||||
node.vote_processor.vote (vote5, std::make_shared<nano::transport::channel_loopback> (node));
|
||||
ASSERT_TIMELY (5s, 5 == node.active.size ());
|
||||
// Confirm elections with weight quorum
|
||||
auto vote0 (std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 0, hashes));
|
||||
node.vote_processor.vote (vote0, std::make_shared<nano::transport::channel_udp> (node.network.udp_channels, node.network.endpoint (), node.network_params.protocol.protocol_version));
|
||||
node.vote_processor.vote (vote0, std::make_shared<nano::transport::channel_loopback> (node));
|
||||
ASSERT_TIMELY (5s, node.active.empty ());
|
||||
ASSERT_TIMELY (5s, 11 == node.ledger.cache.cemented_count);
|
||||
// A late block arrival also checks the inactive votes cache
|
||||
|
|
|
|||
|
|
@ -770,10 +770,10 @@ TEST (votes, check_signature)
|
|||
ASSERT_EQ (1, election1.election->votes ().size ());
|
||||
auto vote1 (std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 1, send1));
|
||||
vote1->signature.bytes[0] ^= 1;
|
||||
ASSERT_EQ (nano::vote_code::invalid, node1.vote_processor.vote_blocking (vote1, std::make_shared<nano::transport::channel_udp> (node1.network.udp_channels, nano::endpoint (boost::asio::ip::address_v6 (), 0), node1.network_params.protocol.protocol_version)));
|
||||
ASSERT_EQ (nano::vote_code::invalid, node1.vote_processor.vote_blocking (vote1, std::make_shared<nano::transport::channel_loopback> (node1)));
|
||||
vote1->signature.bytes[0] ^= 1;
|
||||
ASSERT_EQ (nano::vote_code::vote, node1.vote_processor.vote_blocking (vote1, std::make_shared<nano::transport::channel_udp> (node1.network.udp_channels, nano::endpoint (boost::asio::ip::address_v6 (), 0), node1.network_params.protocol.protocol_version)));
|
||||
ASSERT_EQ (nano::vote_code::replay, node1.vote_processor.vote_blocking (vote1, std::make_shared<nano::transport::channel_udp> (node1.network.udp_channels, nano::endpoint (boost::asio::ip::address_v6 (), 0), node1.network_params.protocol.protocol_version)));
|
||||
ASSERT_EQ (nano::vote_code::vote, node1.vote_processor.vote_blocking (vote1, std::make_shared<nano::transport::channel_loopback> (node1)));
|
||||
ASSERT_EQ (nano::vote_code::replay, node1.vote_processor.vote_blocking (vote1, std::make_shared<nano::transport::channel_loopback> (node1)));
|
||||
}
|
||||
|
||||
TEST (votes, add_one)
|
||||
|
|
@ -891,7 +891,7 @@ TEST (votes, add_old)
|
|||
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send1).code);
|
||||
auto election1 = node1.active.insert (send1);
|
||||
auto vote1 (std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 2, send1));
|
||||
auto channel (std::make_shared<nano::transport::channel_udp> (node1.network.udp_channels, node1.network.endpoint (), node1.network_params.protocol.protocol_version));
|
||||
auto channel (std::make_shared<nano::transport::channel_loopback> (node1));
|
||||
node1.vote_processor.vote_blocking (vote1, channel);
|
||||
nano::keypair key2;
|
||||
auto send2 (std::make_shared<nano::send_block> (genesis.hash (), key2.pub, 0, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0));
|
||||
|
|
@ -931,7 +931,7 @@ TEST (votes, add_old_different_account)
|
|||
ASSERT_EQ (1, election1->votes ().size ());
|
||||
ASSERT_EQ (1, election2->votes ().size ());
|
||||
auto vote1 (std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 2, send1));
|
||||
auto channel (std::make_shared<nano::transport::channel_udp> (node1.network.udp_channels, node1.network.endpoint (), node1.network_params.protocol.protocol_version));
|
||||
auto channel (std::make_shared<nano::transport::channel_loopback> (node1));
|
||||
auto vote_result1 (node1.vote_processor.vote_blocking (vote1, channel));
|
||||
ASSERT_EQ (nano::vote_code::vote, vote_result1);
|
||||
ASSERT_EQ (2, election1->votes ().size ());
|
||||
|
|
@ -964,7 +964,7 @@ TEST (votes, add_cooldown)
|
|||
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send1).code);
|
||||
auto election1 = node1.active.insert (send1);
|
||||
auto vote1 (std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 1, send1));
|
||||
auto channel (std::make_shared<nano::transport::channel_udp> (node1.network.udp_channels, node1.network.endpoint (), node1.network_params.protocol.protocol_version));
|
||||
auto channel (std::make_shared<nano::transport::channel_loopback> (node1));
|
||||
node1.vote_processor.vote_blocking (vote1, channel);
|
||||
nano::keypair key2;
|
||||
auto send2 (std::make_shared<nano::send_block> (genesis.hash (), key2.pub, 0, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0));
|
||||
|
|
|
|||
|
|
@ -1145,3 +1145,22 @@ TEST (network, cleanup_purge)
|
|||
node1.network.cleanup (std::chrono::steady_clock::now ());
|
||||
ASSERT_EQ (0, node1.network.size ());
|
||||
}
|
||||
|
||||
TEST (network, loopback_channel)
|
||||
{
|
||||
nano::system system (2);
|
||||
auto & node1 = *system.nodes[0];
|
||||
auto & node2 = *system.nodes[1];
|
||||
nano::transport::channel_loopback channel1 (node1);
|
||||
ASSERT_EQ (channel1.get_type (), nano::transport::transport_type::loopback);
|
||||
ASSERT_EQ (channel1.get_endpoint (), node1.network.endpoint ());
|
||||
ASSERT_EQ (channel1.get_tcp_endpoint (), nano::transport::map_endpoint_to_tcp (node1.network.endpoint ()));
|
||||
ASSERT_EQ (channel1.get_network_version (), node1.network_params.protocol.protocol_version);
|
||||
ASSERT_EQ (channel1.get_node_id (), node1.node_id.pub);
|
||||
ASSERT_EQ (channel1.get_node_id_optional ().value_or (0), node1.node_id.pub);
|
||||
nano::transport::channel_loopback channel2 (node2);
|
||||
ASSERT_TRUE (channel1 == channel1);
|
||||
ASSERT_FALSE (channel1 == channel2);
|
||||
++node1.network.port;
|
||||
ASSERT_NE (channel1.get_endpoint (), node1.network.endpoint ());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2796,7 +2796,7 @@ TEST (node, vote_republish)
|
|||
auto vote (std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 0, send2));
|
||||
ASSERT_TRUE (node1.active.active (*send1));
|
||||
ASSERT_TRUE (node2.active.active (*send1));
|
||||
node1.vote_processor.vote (vote, std::make_shared<nano::transport::channel_udp> (node1.network.udp_channels, node1.network.endpoint (), node1.network_params.protocol.protocol_version));
|
||||
node1.vote_processor.vote (vote, std::make_shared<nano::transport::channel_loopback> (node1));
|
||||
ASSERT_TIMELY (10s, node1.block (send2->hash ()));
|
||||
ASSERT_TIMELY (10s, node2.block (send2->hash ()));
|
||||
ASSERT_FALSE (node1.block (send1->hash ()));
|
||||
|
|
@ -2872,7 +2872,7 @@ TEST (node, vote_by_hash_republish)
|
|||
auto vote (std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 0, vote_blocks));
|
||||
ASSERT_TRUE (node1.active.active (*send1));
|
||||
ASSERT_TRUE (node2.active.active (*send1));
|
||||
node1.vote_processor.vote (vote, std::make_shared<nano::transport::channel_udp> (node1.network.udp_channels, node1.network.endpoint (), node1.network_params.protocol.protocol_version));
|
||||
node1.vote_processor.vote (vote, std::make_shared<nano::transport::channel_loopback> (node1));
|
||||
ASSERT_TIMELY (10s, node1.block (send2->hash ()));
|
||||
ASSERT_TIMELY (10s, node2.block (send2->hash ()));
|
||||
ASSERT_FALSE (node1.block (send1->hash ()));
|
||||
|
|
@ -2914,7 +2914,7 @@ TEST (node, vote_by_hash_epoch_block_republish)
|
|||
auto vote (std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 0, vote_blocks));
|
||||
ASSERT_TRUE (node1.active.active (*send1));
|
||||
ASSERT_TRUE (node2.active.active (*send1));
|
||||
node1.vote_processor.vote (vote, std::make_shared<nano::transport::channel_udp> (node1.network.udp_channels, node1.network.endpoint (), node1.network_params.protocol.protocol_version));
|
||||
node1.vote_processor.vote (vote, std::make_shared<nano::transport::channel_loopback> (node1));
|
||||
ASSERT_TIMELY (10s, node1.block (epoch1->hash ()));
|
||||
ASSERT_TIMELY (10s, node2.block (epoch1->hash ()));
|
||||
ASSERT_FALSE (node1.block (send1->hash ()));
|
||||
|
|
@ -3394,7 +3394,7 @@ TEST (node, confirm_back)
|
|||
std::vector<nano::block_hash> vote_blocks;
|
||||
vote_blocks.push_back (send2->hash ());
|
||||
auto vote (std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 0, vote_blocks));
|
||||
node.vote_processor.vote_blocking (vote, std::make_shared<nano::transport::channel_udp> (node.network.udp_channels, node.network.endpoint (), node.network_params.protocol.protocol_version));
|
||||
node.vote_processor.vote_blocking (vote, std::make_shared<nano::transport::channel_loopback> (node));
|
||||
ASSERT_TIMELY (10s, node.active.empty ());
|
||||
}
|
||||
|
||||
|
|
@ -4458,6 +4458,26 @@ TEST (rep_crawler, recently_confirmed)
|
|||
ASSERT_TIMELY (3s, node1.rep_crawler.representative_count () == 1);
|
||||
}
|
||||
|
||||
namespace nano
|
||||
{
|
||||
TEST (rep_crawler, local)
|
||||
{
|
||||
nano::system system;
|
||||
nano::node_flags flags;
|
||||
flags.disable_rep_crawler = true;
|
||||
auto & node = *system.add_node (flags);
|
||||
auto loopback = std::make_shared<nano::transport::channel_loopback> (node);
|
||||
auto vote = std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 0, std::vector{ nano::genesis_hash });
|
||||
{
|
||||
nano::lock_guard<std::mutex> guard (node.rep_crawler.probable_reps_mutex);
|
||||
node.rep_crawler.active.insert (nano::genesis_hash);
|
||||
node.rep_crawler.responses.emplace_back (loopback, vote);
|
||||
}
|
||||
node.rep_crawler.validate ();
|
||||
ASSERT_EQ (0, node.rep_crawler.representative_count ());
|
||||
}
|
||||
}
|
||||
|
||||
TEST (online_reps, backup)
|
||||
{
|
||||
nano::logger_mt logger;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ TEST (vote_processor, codes)
|
|||
auto vote (std::make_shared<nano::vote> (key.pub, key.prv, 1, std::vector<nano::block_hash>{ genesis.open->hash () }));
|
||||
auto vote_invalid = std::make_shared<nano::vote> (*vote);
|
||||
vote_invalid->signature.bytes[0] ^= 1;
|
||||
auto channel (std::make_shared<nano::transport::channel_udp> (node.network.udp_channels, node.network.endpoint (), node.network_params.protocol.protocol_version));
|
||||
auto channel (std::make_shared<nano::transport::channel_loopback> (node));
|
||||
|
||||
// Invalid signature
|
||||
ASSERT_EQ (nano::vote_code::invalid, node.vote_processor.vote_blocking (vote_invalid, channel, false));
|
||||
|
|
@ -55,7 +55,7 @@ TEST (vote_processor, flush)
|
|||
auto & node (*system.nodes[0]);
|
||||
nano::genesis genesis;
|
||||
auto vote (std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 1, std::vector<nano::block_hash>{ genesis.open->hash () }));
|
||||
auto channel (std::make_shared<nano::transport::channel_udp> (node.network.udp_channels, node.network.endpoint (), node.network_params.protocol.protocol_version));
|
||||
auto channel (std::make_shared<nano::transport::channel_loopback> (node));
|
||||
for (unsigned i = 0; i < 2000; ++i)
|
||||
{
|
||||
auto new_vote (std::make_shared<nano::vote> (*vote));
|
||||
|
|
@ -75,7 +75,7 @@ TEST (vote_processor, invalid_signature)
|
|||
auto vote (std::make_shared<nano::vote> (key.pub, key.prv, 1, std::vector<nano::block_hash>{ genesis.open->hash () }));
|
||||
auto vote_invalid = std::make_shared<nano::vote> (*vote);
|
||||
vote_invalid->signature.bytes[0] ^= 1;
|
||||
auto channel (std::make_shared<nano::transport::channel_udp> (node.network.udp_channels, node.network.endpoint (), node.network_params.protocol.protocol_version));
|
||||
auto channel (std::make_shared<nano::transport::channel_loopback> (node));
|
||||
|
||||
genesis.open->sideband_set (nano::block_sideband (nano::genesis_account, 0, nano::genesis_amount, 1, nano::seconds_since_epoch (), nano::epoch::epoch_0, false, false, false, nano::epoch::epoch_0));
|
||||
auto election (node.active.insert (genesis.open));
|
||||
|
|
@ -98,7 +98,7 @@ TEST (vote_processor, no_capacity)
|
|||
nano::genesis genesis;
|
||||
nano::keypair key;
|
||||
auto vote (std::make_shared<nano::vote> (key.pub, key.prv, 1, std::vector<nano::block_hash>{ genesis.open->hash () }));
|
||||
auto channel (std::make_shared<nano::transport::channel_udp> (node.network.udp_channels, node.network.endpoint (), node.network_params.protocol.protocol_version));
|
||||
auto channel (std::make_shared<nano::transport::channel_loopback> (node));
|
||||
ASSERT_TRUE (node.vote_processor.vote (vote, channel));
|
||||
}
|
||||
|
||||
|
|
@ -111,7 +111,7 @@ TEST (vote_processor, overflow)
|
|||
nano::genesis genesis;
|
||||
nano::keypair key;
|
||||
auto vote (std::make_shared<nano::vote> (key.pub, key.prv, 1, std::vector<nano::block_hash>{ genesis.open->hash () }));
|
||||
auto channel (std::make_shared<nano::transport::channel_udp> (node.network.udp_channels, node.network.endpoint (), node.network_params.protocol.protocol_version));
|
||||
auto channel (std::make_shared<nano::transport::channel_loopback> (node));
|
||||
|
||||
// No way to lock the processor, but queueing votes in quick succession must result in overflow
|
||||
size_t not_processed{ 0 };
|
||||
|
|
|
|||
|
|
@ -1129,7 +1129,7 @@ TEST (work_watcher, removed_after_lose)
|
|||
node.block_processor.flush ();
|
||||
auto vote (std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 0, fork1));
|
||||
nano::confirm_ack message (vote);
|
||||
node.network.process_message (message, nullptr);
|
||||
node.network.process_message (message, std::make_shared<nano::transport::channel_loopback> (node));
|
||||
ASSERT_TIMELY (5s, !node.wallets.watcher->is_watched (block1->qualified_root ()));
|
||||
ASSERT_EQ (0, node.wallets.watcher->size ());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1112,7 +1112,7 @@ int main (int argc, char * const * argv)
|
|||
while (!votes.empty ())
|
||||
{
|
||||
auto vote (votes.front ());
|
||||
auto channel (std::make_shared<nano::transport::channel_udp> (node->network.udp_channels, node->network.endpoint (), node->network_params.protocol.protocol_version));
|
||||
auto channel (std::make_shared<nano::transport::channel_loopback> (*node));
|
||||
node->vote_processor.vote (vote, channel);
|
||||
votes.pop_front ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -807,11 +807,12 @@ void nano::network::erase_below_version (uint8_t cutoff_version_a)
|
|||
|
||||
void nano::network::erase (nano::transport::channel const & channel_a)
|
||||
{
|
||||
if (channel_a.get_type () == nano::transport::transport_type::tcp)
|
||||
auto const channel_type = channel_a.get_type ();
|
||||
if (channel_type == nano::transport::transport_type::tcp)
|
||||
{
|
||||
tcp_channels.erase (channel_a.get_tcp_endpoint ());
|
||||
}
|
||||
else
|
||||
else if (channel_type != nano::transport::transport_type::loopback)
|
||||
{
|
||||
udp_channels.erase (channel_a.get_endpoint ());
|
||||
udp_channels.clean_node_id (channel_a.get_node_id ());
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ void nano::rep_crawler::validate ()
|
|||
auto & channel = i.first;
|
||||
debug_assert (channel != nullptr);
|
||||
nano::uint128_t rep_weight = node.ledger.weight (vote->account);
|
||||
if (rep_weight > minimum)
|
||||
if (rep_weight > minimum && channel->get_type () != nano::transport::transport_type::loopback)
|
||||
{
|
||||
auto updated_or_inserted = false;
|
||||
nano::unique_lock<std::mutex> lock (probable_reps_mutex);
|
||||
|
|
|
|||
|
|
@ -149,6 +149,7 @@ private:
|
|||
|
||||
friend class active_transactions_confirm_active_Test;
|
||||
friend class active_transactions_confirm_frontier_Test;
|
||||
friend class rep_crawler_local_Test;
|
||||
|
||||
std::deque<std::pair<std::shared_ptr<nano::transport::channel>, std::shared_ptr<nano::vote>>> responses;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -116,6 +116,34 @@ void nano::transport::channel::send (nano::message const & message_a, std::funct
|
|||
}
|
||||
}
|
||||
|
||||
nano::transport::channel_loopback::channel_loopback (nano::node & node_a) :
|
||||
channel (node_a), endpoint (node_a.network.endpoint ())
|
||||
{
|
||||
set_node_id (node_a.node_id.pub);
|
||||
set_network_version (node_a.network_params.protocol.protocol_version);
|
||||
}
|
||||
|
||||
size_t nano::transport::channel_loopback::hash_code () const
|
||||
{
|
||||
std::hash<::nano::endpoint> hash;
|
||||
return hash (endpoint);
|
||||
}
|
||||
|
||||
bool nano::transport::channel_loopback::operator== (nano::transport::channel const & other_a) const
|
||||
{
|
||||
return endpoint == other_a.get_endpoint ();
|
||||
}
|
||||
|
||||
void nano::transport::channel_loopback::send_buffer (nano::shared_const_buffer const & buffer_a, std::function<void(boost::system::error_code const &, size_t)> const & callback_a, nano::buffer_drop_policy drop_policy_a)
|
||||
{
|
||||
release_assert (false && "sending to a loopback channel is not supported");
|
||||
}
|
||||
|
||||
std::string nano::transport::channel_loopback::to_string () const
|
||||
{
|
||||
return boost::str (boost::format ("%1%") % endpoint);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
boost::asio::ip::address_v6 mapped_from_v4_bytes (unsigned long address_a)
|
||||
|
|
|
|||
|
|
@ -32,7 +32,8 @@ namespace transport
|
|||
{
|
||||
undefined = 0,
|
||||
udp = 1,
|
||||
tcp = 2
|
||||
tcp = 2,
|
||||
loopback = 3
|
||||
};
|
||||
class channel
|
||||
{
|
||||
|
|
@ -131,6 +132,38 @@ namespace transport
|
|||
protected:
|
||||
nano::node & node;
|
||||
};
|
||||
|
||||
class channel_loopback final : public nano::transport::channel
|
||||
{
|
||||
public:
|
||||
channel_loopback (nano::node &);
|
||||
size_t hash_code () const override;
|
||||
bool operator== (nano::transport::channel const &) const override;
|
||||
void send_buffer (nano::shared_const_buffer const &, std::function<void(boost::system::error_code const &, size_t)> const & = nullptr, nano::buffer_drop_policy = nano::buffer_drop_policy::limiter) override;
|
||||
std::string to_string () const override;
|
||||
bool operator== (nano::transport::channel_loopback const & other_a) const
|
||||
{
|
||||
return endpoint == other_a.get_endpoint ();
|
||||
}
|
||||
|
||||
nano::endpoint get_endpoint () const override
|
||||
{
|
||||
return endpoint;
|
||||
}
|
||||
|
||||
nano::tcp_endpoint get_tcp_endpoint () const override
|
||||
{
|
||||
return nano::transport::map_endpoint_to_tcp (endpoint);
|
||||
}
|
||||
|
||||
nano::transport::transport_type get_type () const override
|
||||
{
|
||||
return nano::transport::transport_type::loopback;
|
||||
}
|
||||
|
||||
private:
|
||||
nano::endpoint const endpoint;
|
||||
};
|
||||
} // namespace transport
|
||||
} // namespace nano
|
||||
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ void nano::vote_processor::process_loop ()
|
|||
|
||||
bool nano::vote_processor::vote (std::shared_ptr<nano::vote> vote_a, std::shared_ptr<nano::transport::channel> channel_a)
|
||||
{
|
||||
debug_assert (channel_a != nullptr);
|
||||
bool process (false);
|
||||
nano::unique_lock<std::mutex> lock (mutex);
|
||||
if (!stopped)
|
||||
|
|
|
|||
|
|
@ -300,7 +300,7 @@ void nano::vote_generator::broadcast_action (std::shared_ptr<nano::vote> const &
|
|||
{
|
||||
network.flood_vote_pr (vote_a);
|
||||
network.flood_vote (vote_a, 2.0f);
|
||||
vote_processor.vote (vote_a, std::make_shared<nano::transport::channel_udp> (network.udp_channels, network.endpoint (), network_params.protocol.protocol_version));
|
||||
vote_processor.vote (vote_a, std::make_shared<nano::transport::channel_loopback> (network.node));
|
||||
}
|
||||
|
||||
void nano::vote_generator::run ()
|
||||
|
|
|
|||
|
|
@ -413,7 +413,7 @@ TEST (store, vote_load)
|
|||
for (auto i (0); i < 1000000; ++i)
|
||||
{
|
||||
auto vote (std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, i, block));
|
||||
node.vote_processor.vote (vote, std::make_shared<nano::transport::channel_udp> (system.nodes[0]->network.udp_channels, system.nodes[0]->network.endpoint (), system.nodes[0]->network_params.protocol.protocol_version));
|
||||
node.vote_processor.vote (vote, std::make_shared<nano::transport::channel_loopback> (node));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue