mirror of
https://github.com/XRPLF/rippled.git
synced 2026-06-05 01:37:00 +00:00
Structured Overlay support for TTL limited messages:
When the [overlay] configuration key "expire" is set to 1, proposals and validations will include a hops field. The hops is incremented with each relay. Messages with a hop count will be dropped when they exceed the TTL (Time to Live). Messages containing a hops field will not be relayed or broadcast to older versions of rippled that don't understand the field. This change will not affect normal operation of the network or rippled instances that do not set "expire" to 1.
This commit is contained in:
committed by
Tom Ritchford
parent
c77a2f335a
commit
90bb53af20
@@ -988,9 +988,7 @@ private:
|
||||
protocol::TMValidation val;
|
||||
val.set_validation (&validation[0], validation.size ());
|
||||
// Send signed validation to all of our directly connected peers
|
||||
getApp ().overlay ().foreach (send_always (
|
||||
std::make_shared <Message> (
|
||||
val, protocol::mtVALIDATION)));
|
||||
getApp().overlay().send(val);
|
||||
WriteLog (lsINFO, LedgerConsensus)
|
||||
<< "CNF Val " << newLCLHash;
|
||||
}
|
||||
@@ -1256,9 +1254,7 @@ private:
|
||||
Blob sig = mOurPosition->sign ();
|
||||
prop.set_nodepubkey (&pubKey[0], pubKey.size ());
|
||||
prop.set_signature (&sig[0], sig.size ());
|
||||
getApp ().overlay ().foreach (send_always (
|
||||
std::make_shared<Message> (
|
||||
prop, protocol::mtPROPOSE_LEDGER)));
|
||||
getApp().overlay().send(prop);
|
||||
}
|
||||
|
||||
/** Let peers know that we a particular transactions set so they
|
||||
@@ -1681,11 +1677,6 @@ private:
|
||||
Blob validation = v->getSigned ();
|
||||
protocol::TMValidation val;
|
||||
val.set_validation (&validation[0], validation.size ());
|
||||
#if 0
|
||||
getApp ().overlay ().visit (RelayMessage (
|
||||
std::make_shared <Message> (
|
||||
val, protocol::mtVALIDATION)));
|
||||
#endif
|
||||
getApp().getOPs ().setLastValidation (v);
|
||||
WriteLog (lsWARNING, LedgerConsensus) << "Sending partial validation";
|
||||
}
|
||||
|
||||
@@ -1710,21 +1710,10 @@ void NetworkOPsImp::processTrustedProposal (
|
||||
}
|
||||
|
||||
if (relay)
|
||||
{
|
||||
std::set<Peer::id_t> peers;
|
||||
if (getApp().getHashRouter ().swapSet (
|
||||
proposal->getSuppressionID (), peers, SF_RELAYED))
|
||||
{
|
||||
getApp ().overlay ().foreach (send_if_not (
|
||||
std::make_shared<Message> (
|
||||
*set, protocol::mtPROPOSE_LEDGER),
|
||||
peer_in_set(peers)));
|
||||
}
|
||||
}
|
||||
getApp().overlay().relay(*set,
|
||||
proposal->getSuppressionID());
|
||||
else
|
||||
{
|
||||
m_journal.info << "Not relaying trusted proposal";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <beast/container/const_container.h>
|
||||
#include <beast/utility/ci_char_traits.h>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <map>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
@@ -139,6 +140,16 @@ public:
|
||||
std::pair <std::string, bool>
|
||||
find (std::string const& name) const;
|
||||
|
||||
template <class T>
|
||||
boost::optional<T>
|
||||
get (std::string const& name) const
|
||||
{
|
||||
auto const iter = cont().find(name);
|
||||
if (iter == cont().end())
|
||||
return boost::none;
|
||||
return boost::lexical_cast<T>(iter->second);
|
||||
}
|
||||
|
||||
friend
|
||||
std::ostream&
|
||||
operator<< (std::ostream&, Section const& section);
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <beast/cxx14/type_traits.h> // <type_traits>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
namespace boost { namespace asio { namespace ssl { class context; } } }
|
||||
|
||||
@@ -65,6 +66,7 @@ public:
|
||||
bool auto_connect = true;
|
||||
Promote promote = Promote::automatic;
|
||||
std::shared_ptr<boost::asio::ssl::context> context;
|
||||
bool expire = false;
|
||||
};
|
||||
|
||||
typedef std::vector <Peer::ptr> PeerSequence;
|
||||
@@ -131,6 +133,28 @@ public:
|
||||
Peer::ptr
|
||||
findPeerByShortID (Peer::id_t const& id) = 0;
|
||||
|
||||
/** Broadcast a proposal. */
|
||||
virtual
|
||||
void
|
||||
send (protocol::TMProposeSet& m) = 0;
|
||||
|
||||
/** Broadcast a validation. */
|
||||
virtual
|
||||
void
|
||||
send (protocol::TMValidation& m) = 0;
|
||||
|
||||
/** Relay a proposal. */
|
||||
virtual
|
||||
void
|
||||
relay (protocol::TMProposeSet& m,
|
||||
uint256 const& uid) = 0;
|
||||
|
||||
/** Relay a validation. */
|
||||
virtual
|
||||
void
|
||||
relay (protocol::TMValidation& m,
|
||||
uint256 const& uid) = 0;
|
||||
|
||||
/** Visit every active peer and return a value
|
||||
The functor must:
|
||||
- Be callable as:
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
//==============================================================================
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/app/misc/IHashRouter.h>
|
||||
#include <ripple/basics/Log.h>
|
||||
#include <ripple/basics/make_SSLContext.h>
|
||||
#include <ripple/protocol/JsonFields.h>
|
||||
@@ -693,6 +694,75 @@ OverlayImpl::findPeerByShortID (Peer::id_t const& id)
|
||||
return Peer::ptr();
|
||||
}
|
||||
|
||||
void
|
||||
OverlayImpl::send (protocol::TMProposeSet& m)
|
||||
{
|
||||
if (setup_.expire)
|
||||
m.set_hops(0);
|
||||
auto const sm = std::make_shared<Message>(
|
||||
m, protocol::mtPROPOSE_LEDGER);
|
||||
for_each([&](std::shared_ptr<PeerImp> const& p)
|
||||
{
|
||||
if (! m.has_hops() || p->hopsAware())
|
||||
p->send(sm);
|
||||
});
|
||||
}
|
||||
void
|
||||
OverlayImpl::send (protocol::TMValidation& m)
|
||||
{
|
||||
if (setup_.expire)
|
||||
m.set_hops(0);
|
||||
auto const sm = std::make_shared<Message>(
|
||||
m, protocol::mtVALIDATION);
|
||||
for_each([&](std::shared_ptr<PeerImp> const& p)
|
||||
{
|
||||
if (! m.has_hops() || p->hopsAware())
|
||||
p->send(sm);
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
OverlayImpl::relay (protocol::TMProposeSet& m,
|
||||
uint256 const& uid)
|
||||
{
|
||||
if (m.has_hops() && m.hops() >= maxTTL)
|
||||
return;
|
||||
std::set<Peer::id_t> skip;
|
||||
if (! getApp().getHashRouter().swapSet (
|
||||
uid, skip, SF_RELAYED))
|
||||
return;
|
||||
auto const sm = std::make_shared<Message>(
|
||||
m, protocol::mtPROPOSE_LEDGER);
|
||||
for_each([&](std::shared_ptr<PeerImp> const& p)
|
||||
{
|
||||
if (skip.find(p->id()) != skip.end())
|
||||
return;
|
||||
if (! m.has_hops() || p->hopsAware())
|
||||
p->send(sm);
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
OverlayImpl::relay (protocol::TMValidation& m,
|
||||
uint256 const& uid)
|
||||
{
|
||||
if (m.has_hops() && m.hops() >= maxTTL)
|
||||
return;
|
||||
std::set<Peer::id_t> skip;
|
||||
if (! getApp().getHashRouter().swapSet (
|
||||
uid, skip, SF_RELAYED))
|
||||
return;
|
||||
auto const sm = std::make_shared<Message>(
|
||||
m, protocol::mtVALIDATION);
|
||||
for_each([&](std::shared_ptr<PeerImp> const& p)
|
||||
{
|
||||
if (skip.find(p->id()) != skip.end())
|
||||
return;
|
||||
if (! m.has_hops() || p->hopsAware())
|
||||
p->send(sm);
|
||||
});
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
@@ -777,6 +847,7 @@ setup_Overlay (BasicConfig const& config)
|
||||
else
|
||||
setup.promote = Overlay::Promote::automatic;
|
||||
setup.context = make_SSLContext();
|
||||
setup.expire = get<bool>(section, "expire", false);
|
||||
return setup;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,11 @@ namespace ripple {
|
||||
class PeerImp;
|
||||
class BasicConfig;
|
||||
|
||||
enum
|
||||
{
|
||||
maxTTL = 2
|
||||
};
|
||||
|
||||
class OverlayImpl : public Overlay
|
||||
{
|
||||
public:
|
||||
@@ -174,6 +179,20 @@ public:
|
||||
Peer::ptr
|
||||
findPeerByShortID (Peer::id_t const& id) override;
|
||||
|
||||
void
|
||||
send (protocol::TMProposeSet& m) override;
|
||||
|
||||
void
|
||||
send (protocol::TMValidation& m) override;
|
||||
|
||||
void
|
||||
relay (protocol::TMProposeSet& m,
|
||||
uint256 const& uid) override;
|
||||
|
||||
void
|
||||
relay (protocol::TMValidation& m,
|
||||
uint256 const& uid) override;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// OverlayImpl
|
||||
|
||||
@@ -36,8 +36,10 @@
|
||||
#include <ripple/server/ServerHandler.h>
|
||||
#include <ripple/protocol/BuildInfo.h>
|
||||
#include <ripple/protocol/JsonFields.h>
|
||||
#include <beast/module/core/diagnostic/SemanticVersion.h>
|
||||
#include <beast/streams/debug_ostream.h>
|
||||
#include <beast/weak_fn.h>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <functional>
|
||||
#include <beast/cxx14/memory.h> // <memory>
|
||||
@@ -100,6 +102,20 @@ PeerImp::run()
|
||||
if(! strand_.running_in_this_thread())
|
||||
return strand_.post(std::bind (
|
||||
&PeerImp::run, shared_from_this()));
|
||||
{
|
||||
auto s = getVersion();
|
||||
if (boost::starts_with(s, "rippled-"))
|
||||
{
|
||||
s.erase(s.begin(), s.begin() + 8);
|
||||
beast::SemanticVersion v;
|
||||
if (v.parse(s))
|
||||
{
|
||||
beast::SemanticVersion av;
|
||||
av.parse("0.28.0-rc3");
|
||||
hopsAware_ = v >= av;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_inbound)
|
||||
{
|
||||
doAccept();
|
||||
@@ -1008,6 +1024,10 @@ PeerImp::onMessage (std::shared_ptr <protocol::TMProposeSet> const& m)
|
||||
{
|
||||
protocol::TMProposeSet& set = *m;
|
||||
|
||||
if (overlay_.setup().expire &&
|
||||
set.has_hops() && ! slot_->cluster())
|
||||
set.set_hops(set.hops() + 1);
|
||||
|
||||
// VFALCO Magic numbers are bad
|
||||
if ((set.closetime() + 180) < getApp().getOPs().getCloseTimeNC())
|
||||
return;
|
||||
@@ -1276,6 +1296,10 @@ PeerImp::onMessage (std::shared_ptr <protocol::TMValidation> const& m)
|
||||
error_code ec;
|
||||
std::uint32_t closeTime = getApp().getOPs().getCloseTimeNC();
|
||||
|
||||
if (overlay_.setup().expire &&
|
||||
m->has_hops() && ! slot_->cluster())
|
||||
m->set_hops(m->hops() + 1);
|
||||
|
||||
if (m->validation ().size () < 50)
|
||||
{
|
||||
p_journal_.warning << "Validation: Too small";
|
||||
@@ -1651,15 +1675,7 @@ PeerImp::checkPropose (Job& job,
|
||||
// relay untrusted proposal
|
||||
p_journal_.trace <<
|
||||
"relaying UNTRUSTED proposal";
|
||||
std::set<Peer::id_t> peers;
|
||||
|
||||
if (getApp().getHashRouter ().swapSet (
|
||||
proposal->getSuppressionID (), peers, SF_RELAYED))
|
||||
{
|
||||
overlay_.foreach (send_if_not (
|
||||
std::make_shared<Message> (set, protocol::mtPROPOSE_LEDGER),
|
||||
peer_in_set(peers)));
|
||||
}
|
||||
overlay_.relay(set, proposal->getSuppressionID());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1688,15 +1704,9 @@ PeerImp::checkValidation (Job&, STValidation::pointer val,
|
||||
validatorsConnection_->onValidation(*val);
|
||||
#endif
|
||||
|
||||
std::set<Peer::id_t> peers;
|
||||
if (getApp().getOPs ().recvValidation (val, std::to_string(id())) &&
|
||||
getApp().getHashRouter ().swapSet (
|
||||
signingHash, peers, SF_RELAYED))
|
||||
{
|
||||
overlay_.foreach (send_if_not (
|
||||
std::make_shared<Message> (*packet, protocol::mtVALIDATION),
|
||||
peer_in_set(peers)));
|
||||
}
|
||||
if (getApp().getOPs ().recvValidation(
|
||||
val, std::to_string(id())))
|
||||
overlay_.relay(*packet, signingHash);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
||||
@@ -153,6 +153,7 @@ private:
|
||||
bool gracefulClose_ = false;
|
||||
std::unique_ptr <LoadEvent> load_event_;
|
||||
std::unique_ptr<Validators::Connection> validatorsConnection_;
|
||||
bool hopsAware_ = false;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
@@ -237,6 +238,12 @@ public:
|
||||
return slot_->cluster();
|
||||
}
|
||||
|
||||
bool
|
||||
hopsAware() const
|
||||
{
|
||||
return hopsAware_;
|
||||
}
|
||||
|
||||
void
|
||||
check();
|
||||
|
||||
|
||||
@@ -173,6 +173,7 @@ message TMProposeSet
|
||||
optional bool checkedSignature = 7; // node vouches signature is correct
|
||||
repeated bytes addedTransactions = 10; // not required if number is large
|
||||
repeated bytes removedTransactions = 11; // not required if number is large
|
||||
optional uint32 hops = 12; // Number of hops traveled
|
||||
}
|
||||
|
||||
enum TxSetStatus
|
||||
@@ -192,8 +193,9 @@ message TMHaveTransactionSet
|
||||
// Used to sign a final closed ledger after reprocessing
|
||||
message TMValidation
|
||||
{
|
||||
required bytes validation = 1; // in STValidation signed form
|
||||
optional bool checkedSignature = 2; // node vouches signature is correct
|
||||
required bytes validation = 1; // in STValidation signed form
|
||||
optional bool checkedSignature = 2; // node vouches signature is correct
|
||||
optional uint32 hops = 3; // Number of hops traveled
|
||||
}
|
||||
|
||||
message TMGetPeers
|
||||
|
||||
Reference in New Issue
Block a user