Configurable handling of untrusted validations and proposals

This commit is contained in:
Richard Holland
2021-11-17 09:45:21 +00:00
committed by Nik Bougalis
parent bf013c02ad
commit 6746b863b3
5 changed files with 54 additions and 20 deletions

View File

@@ -622,18 +622,28 @@
#
# [relay_proposals]
#
# Controls the relaying behavior for proposals received by this server that
# are issued by validators that are not on the server's UNL.
# Controls the relay and processing behavior for proposals received by this
# server that are issued by validators that are not on the server's UNL.
#
# Legal values are: "trusted" and "all". The default is "trusted".
# Legal values are:
# "all" - Relay and process all incoming proposals
# "trusted" - Relay only trusted proposals, but locally process all
# "drop_untrusted" - Relay only trusted proposals, do not process untrusted
#
# The default is "trusted".
#
#
# [relay_validations]
#
# Controls the relaying behavior for validations received by this server that
# are issued by validators that are not on the server's UNL.
# Controls the relay and processing behavior for validations received by this
# server that are issued by validators that are not on the server's UNL.
#
# Legal values are: "trusted" and "all". The default is "all".
# Legal values are:
# "all" - Relay and process all incoming validations
# "trusted" - Relay only trusted validations, but locally process all
# "drop_untrusted" - Relay only trusted validations, do not process untrusted
#
# The default is "all".
#
#
#

View File

@@ -2250,7 +2250,7 @@ NetworkOPsImp::recvValidation(
// We will always relay trusted validations; if configured, we will
// also relay all untrusted validations.
return app_.config().RELAY_UNTRUSTED_VALIDATIONS || val->isTrusted();
return app_.config().RELAY_UNTRUSTED_VALIDATIONS == 1 || val->isTrusted();
}
Json::Value

View File

@@ -146,8 +146,10 @@ public:
std::size_t NETWORK_QUORUM = 1;
// Peer networking parameters
bool RELAY_UNTRUSTED_VALIDATIONS = true;
bool RELAY_UNTRUSTED_PROPOSALS = false;
// 1 = relay, 0 = do not relay (but process), -1 = drop completely (do NOT
// process)
int RELAY_UNTRUSTED_VALIDATIONS = 1;
int RELAY_UNTRUSTED_PROPOSALS = 0;
// True to ask peers not to relay current IP.
bool PEER_PRIVATE = false;

View File

@@ -553,9 +553,11 @@ Config::loadFromString(std::string const& fileContents)
if (getSingleSection(secConfig, SECTION_RELAY_VALIDATIONS, strTemp, j_))
{
if (boost::iequals(strTemp, "all"))
RELAY_UNTRUSTED_VALIDATIONS = true;
RELAY_UNTRUSTED_VALIDATIONS = 1;
else if (boost::iequals(strTemp, "trusted"))
RELAY_UNTRUSTED_VALIDATIONS = false;
RELAY_UNTRUSTED_VALIDATIONS = 0;
else if (boost::iequals(strTemp, "drop_untrusted"))
RELAY_UNTRUSTED_VALIDATIONS = -1;
else
Throw<std::runtime_error>(
"Invalid value specified in [" SECTION_RELAY_VALIDATIONS
@@ -565,9 +567,11 @@ Config::loadFromString(std::string const& fileContents)
if (getSingleSection(secConfig, SECTION_RELAY_PROPOSALS, strTemp, j_))
{
if (boost::iequals(strTemp, "all"))
RELAY_UNTRUSTED_PROPOSALS = true;
RELAY_UNTRUSTED_PROPOSALS = 1;
else if (boost::iequals(strTemp, "trusted"))
RELAY_UNTRUSTED_PROPOSALS = false;
RELAY_UNTRUSTED_PROPOSALS = 0;
else if (boost::iequals(strTemp, "drop_untrusted"))
RELAY_UNTRUSTED_PROPOSALS = -1;
else
Throw<std::runtime_error>(
"Invalid value specified in [" SECTION_RELAY_PROPOSALS

View File

@@ -1929,10 +1929,21 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMProposeSet> const& m)
return;
}
// RH TODO: when isTrusted = false we should probably also cache a key
// suppression for 30 seconds to avoid doing a relatively expensive lookup
// every time a spam packet is received
PublicKey const publicKey{makeSlice(set.nodepubkey())};
auto const isTrusted = app_.validators().trusted(publicKey);
// If the operator has specified that untrusted proposals be dropped then
// this happens here I.e. before further wasting CPU verifying the signature
// of an untrusted key
if (!isTrusted && app_.config().RELAY_UNTRUSTED_PROPOSALS == -1)
return;
uint256 const proposeHash{set.currenttxhash()};
uint256 const prevLedger{set.previousledger()};
PublicKey const publicKey{makeSlice(set.nodepubkey())};
NetClock::time_point const closeTime{NetClock::duration{set.closetime()}};
uint256 const suppression = proposalUniqueId(
@@ -1957,8 +1968,6 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMProposeSet> const& m)
return;
}
auto const isTrusted = app_.validators().trusted(publicKey);
if (!isTrusted)
{
if (tracking_.load() == Tracking::diverged)
@@ -2543,6 +2552,18 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMValidation> const& m)
return;
}
// RH TODO: when isTrusted = false we should probably also cache a key
// suppression for 30 seconds to avoid doing a relatively expensive
// lookup every time a spam packet is received
auto const isTrusted =
app_.validators().trusted(val->getSignerPublic());
// If the operator has specified that untrusted validations be dropped
// then this happens here I.e. before further wasting CPU verifying the
// signature of an untrusted key
if (!isTrusted && app_.config().RELAY_UNTRUSTED_VALIDATIONS == -1)
return;
auto key = sha512Half(makeSlice(m->validation()));
if (auto [added, relayed] =
app_.getHashRouter().addSuppressionPeerWithStatus(key, id_);
@@ -2560,9 +2581,6 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMValidation> const& m)
return;
}
auto const isTrusted =
app_.validators().trusted(val->getSignerPublic());
if (!isTrusted && (tracking_.load() == Tracking::diverged))
{
JLOG(p_journal_.debug())
@@ -3106,7 +3124,7 @@ PeerImp::checkPropose(
if (isTrusted)
relay = app_.getOPs().processTrustedProposal(peerPos);
else
relay = app_.config().RELAY_UNTRUSTED_PROPOSALS || cluster();
relay = app_.config().RELAY_UNTRUSTED_PROPOSALS == 1 || cluster();
if (relay)
{