aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorluigi1111 <luigi1111w@gmail.com>2020-10-13 10:48:00 -0500
committerluigi1111 <luigi1111w@gmail.com>2020-10-13 10:48:00 -0500
commit94a86cf8552505e4a46be6764bdf0387d904d935 (patch)
treed8d1ae4cbffa40cf3b1c7702f50a4a9edfe8306c /src
parentMerge pull request #6883 (diff)
parentDandelion++: skip desynced peers in stem phase (diff)
downloadmonero-94a86cf8552505e4a46be6764bdf0387d904d935.tar.xz
Merge pull request #6884
6352090 Dandelion++: skip desynced peers in stem phase (xiphon)
Diffstat (limited to 'src')
-rw-r--r--src/cryptonote_core/cryptonote_core.h2
-rw-r--r--src/cryptonote_core/i_core_events.h1
-rw-r--r--src/cryptonote_protocol/cryptonote_protocol_handler.inl2
-rw-r--r--src/cryptonote_protocol/levin_notify.cpp40
-rw-r--r--src/cryptonote_protocol/levin_notify.h6
-rw-r--r--src/p2p/net_node.h2
-rw-r--r--src/p2p/net_node.inl10
-rw-r--r--src/p2p/net_node_common.h4
8 files changed, 37 insertions, 30 deletions
diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h
index c9d26e0ed..7c578ac51 100644
--- a/src/cryptonote_core/cryptonote_core.h
+++ b/src/cryptonote_core/cryptonote_core.h
@@ -663,7 +663,7 @@ namespace cryptonote
*
* @param target_blockchain_height the target height
*/
- uint64_t get_target_blockchain_height() const;
+ virtual uint64_t get_target_blockchain_height() const override;
/**
* @brief returns the newest hardfork version known to the blockchain
diff --git a/src/cryptonote_core/i_core_events.h b/src/cryptonote_core/i_core_events.h
index 03394d785..addb659ab 100644
--- a/src/cryptonote_core/i_core_events.h
+++ b/src/cryptonote_core/i_core_events.h
@@ -39,6 +39,7 @@ namespace cryptonote
virtual ~i_core_events() noexcept
{}
+ virtual uint64_t get_target_blockchain_height() const = 0;
virtual void on_transactions_relayed(epee::span<const cryptonote::blobdata> tx_blobs, relay_method tx_relay) = 0;
};
}
diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl
index 337885509..a8073e091 100644
--- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl
+++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl
@@ -2538,7 +2538,7 @@ skip:
local mempool before doing the relay. The code was already updating the
DB twice on received transactions - it is difficult to workaround this
due to the internal design. */
- return m_p2p->send_txs(std::move(arg.txs), zone, source, m_core, tx_relay) != epee::net_utils::zone::invalid;
+ return m_p2p->send_txs(std::move(arg.txs), zone, source, tx_relay) != epee::net_utils::zone::invalid;
}
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
diff --git a/src/cryptonote_protocol/levin_notify.cpp b/src/cryptonote_protocol/levin_notify.cpp
index 7c482156f..dbd11e7d0 100644
--- a/src/cryptonote_protocol/levin_notify.cpp
+++ b/src/cryptonote_protocol/levin_notify.cpp
@@ -105,8 +105,8 @@ namespace levin
return std::chrono::steady_clock::duration{crypto::rand_range(rep(0), range.count())};
}
- //! \return All outgoing connections supporting fragments in `connections`.
- std::vector<boost::uuids::uuid> get_out_connections(connections& p2p)
+ //! \return Outgoing connections supporting fragments in `connections` filtered by remote blockchain height.
+ std::vector<boost::uuids::uuid> get_out_connections(connections& p2p, uint64_t min_blockchain_height)
{
std::vector<boost::uuids::uuid> outs;
outs.reserve(connection_id_reserve_size);
@@ -115,8 +115,8 @@ namespace levin
the reserve call so a strand is not used. Investigate if there is lots
of waiting in here. */
- p2p.foreach_connection([&outs] (detail::p2p_context& context) {
- if (!context.m_is_income)
+ p2p.foreach_connection([&outs, min_blockchain_height] (detail::p2p_context& context) {
+ if (!context.m_is_income && context.m_remote_blockchain_height >= min_blockchain_height)
outs.emplace_back(context.m_connection_id);
return true;
});
@@ -544,7 +544,7 @@ namespace levin
}
// connection list may be outdated, try again
- update_channels::run(zone_, get_out_connections(*zone_->p2p));
+ update_channels::run(zone_, get_out_connections(*zone_->p2p, core_->get_target_blockchain_height()));
}
MERROR("Unable to send transaction(s) via Dandelion++ stem");
@@ -591,8 +591,9 @@ namespace levin
{
std::shared_ptr<detail::zone> zone_;
const std::size_t channel_;
+ const i_core_events* core_;
- static void wait(const std::chrono::steady_clock::time_point start, std::shared_ptr<detail::zone> zone, const std::size_t index)
+ static void wait(const std::chrono::steady_clock::time_point start, std::shared_ptr<detail::zone> zone, const std::size_t index, const i_core_events* core)
{
if (!zone)
return;
@@ -600,7 +601,7 @@ namespace levin
noise_channel& channel = zone->channels.at(index);
channel.next_noise.expires_at(start + noise_min_delay + random_duration(noise_delay_range));
channel.next_noise.async_wait(
- channel.strand.wrap(send_noise{std::move(zone), index})
+ channel.strand.wrap(send_noise{std::move(zone), index, core})
);
}
@@ -645,7 +646,7 @@ namespace levin
channel.active = nullptr;
channel.connection = boost::uuids::nil_uuid();
- auto connections = get_out_connections(*zone_->p2p);
+ auto connections = get_out_connections(*zone_->p2p, core_->get_target_blockchain_height());
if (connections.empty())
MWARNING("Lost all outbound connections to anonymity network - currently unable to send transaction(s)");
@@ -653,7 +654,7 @@ namespace levin
}
}
- wait(start, std::move(zone_), channel_);
+ wait(start, std::move(zone_), channel_, core_);
}
};
@@ -665,6 +666,7 @@ namespace levin
std::chrono::seconds min_epoch_;
std::chrono::seconds epoch_range_;
std::size_t count_;
+ const i_core_events* core_;
//! \pre Should not be invoked within any strand to prevent blocking.
void operator()(const boost::system::error_code error = {})
@@ -677,8 +679,9 @@ namespace levin
const bool fluffing = crypto::rand_idx(unsigned(100)) < CRYPTONOTE_DANDELIONPP_FLUFF_PROBABILITY;
const auto start = std::chrono::steady_clock::now();
+ auto connections = get_out_connections(*(zone_->p2p), core_->get_target_blockchain_height());
zone_->strand.dispatch(
- change_channels{zone_, net::dandelionpp::connection_map{get_out_connections(*(zone_->p2p)), count_}, fluffing}
+ change_channels{zone_, net::dandelionpp::connection_map{std::move(connections), count_}, fluffing}
);
detail::zone& alias = *zone_;
@@ -688,8 +691,9 @@ namespace levin
};
} // anonymous
- notify::notify(boost::asio::io_service& service, std::shared_ptr<connections> p2p, epee::byte_slice noise, const bool is_public, const bool pad_txs)
+ notify::notify(boost::asio::io_service& service, std::shared_ptr<connections> p2p, epee::byte_slice noise, const bool is_public, const bool pad_txs, i_core_events& core)
: zone_(std::make_shared<detail::zone>(service, std::move(p2p), std::move(noise), is_public, pad_txs))
+ , core_(std::addressof(core))
{
if (!zone_->p2p)
throw std::logic_error{"cryptonote::levin::notify cannot have nullptr p2p argument"};
@@ -702,10 +706,10 @@ namespace levin
const auto epoch_range = noise_enabled ? noise_epoch_range : dandelionpp_epoch_range;
const std::size_t out_count = noise_enabled ? CRYPTONOTE_NOISE_CHANNELS : CRYPTONOTE_DANDELIONPP_STEMS;
- start_epoch{zone_, min_epoch, epoch_range, out_count}();
+ start_epoch{zone_, min_epoch, epoch_range, out_count, core_}();
for (std::size_t channel = 0; channel < zone_->channels.size(); ++channel)
- send_noise::wait(now, zone_, channel);
+ send_noise::wait(now, zone_, channel, core_);
}
}
@@ -726,7 +730,7 @@ namespace levin
return;
zone_->strand.dispatch(
- update_channels{zone_, get_out_connections(*(zone_->p2p))}
+ update_channels{zone_, get_out_connections(*(zone_->p2p), core_->get_target_blockchain_height())}
);
}
@@ -753,7 +757,7 @@ namespace levin
zone_->flush_txs.cancel();
}
- bool notify::send_txs(std::vector<blobdata> txs, const boost::uuids::uuid& source, i_core_events& core, relay_method tx_relay)
+ bool notify::send_txs(std::vector<blobdata> txs, const boost::uuids::uuid& source, relay_method tx_relay)
{
if (txs.empty())
return true;
@@ -785,7 +789,7 @@ namespace levin
tx_relay = relay_method::local; // do not put into stempool embargo (hopefully not there already!).
}
- core.on_transactions_relayed(epee::to_span(txs), tx_relay);
+ core_->on_transactions_relayed(epee::to_span(txs), tx_relay);
// Padding is not useful when using noise mode. Send as stem so receiver
// forwards in Dandelion++ mode.
@@ -821,7 +825,7 @@ namespace levin
{
// this will change a local/forward tx to stem or fluff ...
zone_->strand.dispatch(
- dandelionpp_notify{zone_, std::addressof(core), std::move(txs), source}
+ dandelionpp_notify{zone_, core_, std::move(txs), source}
);
break;
}
@@ -832,7 +836,7 @@ namespace levin
routine. A "fluff" over i2p/tor is not the same as a "fluff" over
ipv4/6. Marking it as "fluff" here will make the tx immediately
visible externally from this node, which is not desired. */
- core.on_transactions_relayed(epee::to_span(txs), tx_relay);
+ core_->on_transactions_relayed(epee::to_span(txs), tx_relay);
zone_->strand.dispatch(fluff_notify{zone_, std::move(txs), source});
break;
}
diff --git a/src/cryptonote_protocol/levin_notify.h b/src/cryptonote_protocol/levin_notify.h
index 957794b12..43b61aead 100644
--- a/src/cryptonote_protocol/levin_notify.h
+++ b/src/cryptonote_protocol/levin_notify.h
@@ -69,6 +69,7 @@ namespace levin
class notify
{
std::shared_ptr<detail::zone> zone_;
+ i_core_events* core_;
public:
struct status
@@ -80,10 +81,11 @@ namespace levin
//! Construct an instance that cannot notify.
notify() noexcept
: zone_(nullptr)
+ , core_(nullptr)
{}
//! Construct an instance with available notification `zones`.
- explicit notify(boost::asio::io_service& service, std::shared_ptr<connections> p2p, epee::byte_slice noise, bool is_public, bool pad_txs);
+ explicit notify(boost::asio::io_service& service, std::shared_ptr<connections> p2p, epee::byte_slice noise, bool is_public, bool pad_txs, i_core_events& core);
notify(const notify&) = delete;
notify(notify&&) = default;
@@ -123,7 +125,7 @@ namespace levin
particular stem.
\return True iff the notification is queued for sending. */
- bool send_txs(std::vector<blobdata> txs, const boost::uuids::uuid& source, i_core_events& core, relay_method tx_relay);
+ bool send_txs(std::vector<blobdata> txs, const boost::uuids::uuid& source, relay_method tx_relay);
};
} // levin
} // net
diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h
index e81371783..97835edd4 100644
--- a/src/p2p/net_node.h
+++ b/src/p2p/net_node.h
@@ -334,7 +334,7 @@ namespace nodetool
virtual void callback(p2p_connection_context& context);
//----------------- i_p2p_endpoint -------------------------------------------------------------
virtual bool relay_notify_to_list(int command, const epee::span<const uint8_t> data_buff, std::vector<std::pair<epee::net_utils::zone, boost::uuids::uuid>> connections);
- virtual epee::net_utils::zone send_txs(std::vector<cryptonote::blobdata> txs, const epee::net_utils::zone origin, const boost::uuids::uuid& source, cryptonote::i_core_events& core, cryptonote::relay_method tx_relay);
+ virtual epee::net_utils::zone send_txs(std::vector<cryptonote::blobdata> txs, const epee::net_utils::zone origin, const boost::uuids::uuid& source, cryptonote::relay_method tx_relay);
virtual bool invoke_command_to_peer(int command, const epee::span<const uint8_t> req_buff, std::string& resp_buff, const epee::net_utils::connection_context_base& context);
virtual bool invoke_notify_to_peer(int command, const epee::span<const uint8_t> req_buff, const epee::net_utils::connection_context_base& context);
virtual bool drop_connection(const epee::net_utils::connection_context_base& context);
diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl
index 175741146..aa16e93d5 100644
--- a/src/p2p/net_node.inl
+++ b/src/p2p/net_node.inl
@@ -386,7 +386,7 @@ namespace nodetool
m_use_ipv6 = command_line::get_arg(vm, arg_p2p_use_ipv6);
m_require_ipv4 = !command_line::get_arg(vm, arg_p2p_ignore_ipv4);
public_zone.m_notifier = cryptonote::levin::notify{
- public_zone.m_net_server.get_io_service(), public_zone.m_net_server.get_config_shared(), nullptr, true, pad_txs
+ public_zone.m_net_server.get_io_service(), public_zone.m_net_server.get_config_shared(), nullptr, true, pad_txs, m_payload_handler.get_core()
};
if (command_line::has_arg(vm, arg_p2p_add_peer))
@@ -499,7 +499,7 @@ namespace nodetool
}
zone.m_notifier = cryptonote::levin::notify{
- zone.m_net_server.get_io_service(), zone.m_net_server.get_config_shared(), std::move(this_noise), false, pad_txs
+ zone.m_net_server.get_io_service(), zone.m_net_server.get_config_shared(), std::move(this_noise), false, pad_txs, m_payload_handler.get_core()
};
}
@@ -1994,13 +1994,13 @@ namespace nodetool
}
//-----------------------------------------------------------------------------------
template<class t_payload_net_handler>
- epee::net_utils::zone node_server<t_payload_net_handler>::send_txs(std::vector<cryptonote::blobdata> txs, const epee::net_utils::zone origin, const boost::uuids::uuid& source, cryptonote::i_core_events& core, const cryptonote::relay_method tx_relay)
+ epee::net_utils::zone node_server<t_payload_net_handler>::send_txs(std::vector<cryptonote::blobdata> txs, const epee::net_utils::zone origin, const boost::uuids::uuid& source, const cryptonote::relay_method tx_relay)
{
namespace enet = epee::net_utils;
- const auto send = [&txs, &source, &core, tx_relay] (std::pair<const enet::zone, network_zone>& network)
+ const auto send = [&txs, &source, tx_relay] (std::pair<const enet::zone, network_zone>& network)
{
- if (network.second.m_notifier.send_txs(std::move(txs), source, core, tx_relay))
+ if (network.second.m_notifier.send_txs(std::move(txs), source, tx_relay))
return network.first;
return enet::zone::invalid;
};
diff --git a/src/p2p/net_node_common.h b/src/p2p/net_node_common.h
index 393d38e0a..2ace5987f 100644
--- a/src/p2p/net_node_common.h
+++ b/src/p2p/net_node_common.h
@@ -50,7 +50,7 @@ namespace nodetool
struct i_p2p_endpoint
{
virtual bool relay_notify_to_list(int command, const epee::span<const uint8_t> data_buff, std::vector<std::pair<epee::net_utils::zone, boost::uuids::uuid>> connections)=0;
- virtual epee::net_utils::zone send_txs(std::vector<cryptonote::blobdata> txs, const epee::net_utils::zone origin, const boost::uuids::uuid& source, cryptonote::i_core_events& core, cryptonote::relay_method tx_relay)=0;
+ virtual epee::net_utils::zone send_txs(std::vector<cryptonote::blobdata> txs, const epee::net_utils::zone origin, const boost::uuids::uuid& source, cryptonote::relay_method tx_relay)=0;
virtual bool invoke_command_to_peer(int command, const epee::span<const uint8_t> req_buff, std::string& resp_buff, const epee::net_utils::connection_context_base& context)=0;
virtual bool invoke_notify_to_peer(int command, const epee::span<const uint8_t> req_buff, const epee::net_utils::connection_context_base& context)=0;
virtual bool drop_connection(const epee::net_utils::connection_context_base& context)=0;
@@ -75,7 +75,7 @@ namespace nodetool
{
return false;
}
- virtual epee::net_utils::zone send_txs(std::vector<cryptonote::blobdata> txs, const epee::net_utils::zone origin, const boost::uuids::uuid& source, cryptonote::i_core_events& core, cryptonote::relay_method tx_relay)
+ virtual epee::net_utils::zone send_txs(std::vector<cryptonote::blobdata> txs, const epee::net_utils::zone origin, const boost::uuids::uuid& source, cryptonote::relay_method tx_relay)
{
return epee::net_utils::zone::invalid;
}