20 #include <ripple/app/consensus/RCLValidations.h>
21 #include <ripple/app/ledger/Ledger.h>
22 #include <ripple/app/misc/NegativeUNLVote.h>
48 for (
auto const& k : unlKeys)
60 auto negUnlKeys = prevLedger->negativeUNL();
61 auto negUnlToDisable = prevLedger->validatorToDisable();
62 auto negUnlToReEnable = prevLedger->validatorToReEnable();
64 negUnlKeys.insert(*negUnlToDisable);
66 negUnlKeys.erase(*negUnlToReEnable);
69 for (
auto const& k : negUnlKeys)
73 if (!nidToKeyMap.
count(nid))
79 auto const seq = prevLedger->info().seq + 1;
83 auto const candidates =
87 if (!candidates.toDisableCandidates.empty())
90 choose(prevLedger->info().hash, candidates.toDisableCandidates);
91 assert(nidToKeyMap.
count(n));
95 if (!candidates.toReEnableCandidates.empty())
98 prevLedger->info().hash, candidates.toReEnableCandidates);
99 assert(nidToKeyMap.
count(n));
118 uint256 txID = negUnlTx.getTransactionID();
121 if (!initialSet->addGiveItem(
122 std::make_shared<SHAMapItem>(txID, s.
peekData()),
true,
false))
124 JLOG(
j_.
warn()) <<
"N-UNL: ledger seq=" << seq
125 <<
", add ttUNL_MODIFY tx failed";
129 JLOG(
j_.
debug()) <<
"N-UNL: ledger seq=" << seq
130 <<
", add a ttUNL_MODIFY Tx with txID: " << txID
131 <<
", the validator to "
132 << (modify ==
ToDisable ?
"disable: " :
"re-enable: ")
142 assert(!candidates.
empty());
145 NodeID txNodeID = candidates[0];
146 for (
int j = 1; j < candidates.
size(); ++j)
148 if ((candidates[j] ^ randomPad) < (txNodeID ^ randomPad))
150 txNodeID = candidates[j];
168 auto const seq = prevLedger->info().seq + 1;
172 auto const hashIndex = prevLedger->read(
keylet::skip());
173 if (!hashIndex || !hashIndex->isFieldPresent(
sfHashes))
175 JLOG(
j_.
debug()) <<
"N-UNL: ledger " << seq <<
" no history.";
178 auto const ledgerAncestors = hashIndex->getFieldV256(
sfHashes).value();
179 auto const numAncestors = ledgerAncestors.size();
182 JLOG(
j_.
debug()) <<
"N-UNL: ledger " << seq
183 <<
" not enough history. Can trace back only "
184 << numAncestors <<
" ledgers.";
190 for (
auto const& k : unl)
200 ledgerAncestors[numAncestors - 1 - i]))
202 if (scoreTable.
count(v->getNodeID()))
203 ++scoreTable[v->getNodeID()];
210 if (
auto const it = scoreTable.
find(
myId_); it != scoreTable.
end())
216 JLOG(
j_.
debug()) <<
"N-UNL: ledger " << seq
217 <<
". Local node only issued " << myValidationCount
220 <<
" The reliability measurement could be wrong.";
233 JLOG(
j_.
error()) <<
"N-UNL: ledger " << seq <<
". Local node issued "
234 << myValidationCount <<
" validations in last "
247 auto const canAdd = [&]() ->
bool {
248 auto const maxNegativeListed =
static_cast<std::size_t>(
251 for (
auto const& n : unl)
256 bool const result = negativeListed < maxNegativeListed;
257 JLOG(
j_.
trace()) <<
"N-UNL: nodeId " <<
myId_ <<
" lowWaterMark "
260 <<
" negativeListed " << negativeListed
261 <<
" maxNegativeListed " << maxNegativeListed;
266 for (
auto const& [nodeId, score] : scoreTable)
268 JLOG(
j_.
trace()) <<
"N-UNL: node " << nodeId <<
" score " << score;
278 JLOG(
j_.
trace()) <<
"N-UNL: toDisable candidate " << nodeId;
287 JLOG(
j_.
trace()) <<
"N-UNL: toReEnable candidate " << nodeId;
304 for (
auto const& n : negUnl)
321 for (
auto const& n : nowTrusted)
325 JLOG(
j_.
trace()) <<
"N-UNL: add a new validator " << n
326 <<
" at ledger seq=" << seq;
void doVoting(std::shared_ptr< Ledger const > const &prevLedger, hash_set< PublicKey > const &unlKeys, RCLValidations &validations, std::shared_ptr< SHAMap > const &initialSet)
Cast our local vote on the NegativeUNL candidates.
NodeID calcNodeID(PublicKey const &pk)
Calculate the 160-bit node ID from a node public key.
Stream trace() const
Severity stream access functions.
Keylet const & skip() noexcept
The index of the "short" skip list.
constexpr std::uint32_t FLAG_LEDGER_INTERVAL
void setSeqToKeep(Seq const &s)
Set the smallest sequence number of validations to keep from expire.
Slice slice() const noexcept
const SF_Blob sfUNLModifyValidator(access, STI_VL, 19, "UNLModifyValidator")
const SF_U8 sfUNLModifyDisabling(access, STI_UINT8, 17, "UNLModifyDisabling")
static constexpr size_t negativeUNLHighWaterMark
An unreliable validator must have more than negativeUNLHighWaterMark validations in the last flag led...
hash_map< NodeID, LedgerIndex > newValidators_
std::vector< NodeID > toDisableCandidates
std::vector< NodeID > toReEnableCandidates
static constexpr std::size_t bytes
const Candidates findAllCandidates(hash_set< NodeID > const &unl, hash_set< NodeID > const &negUnl, hash_map< NodeID, std::uint32_t > const &scoreTable)
Process the score table and find all disabling and re-enabling candidates.
static constexpr float negativeUNLMaxListed
We only want to put 25% of the UNL on the NegativeUNL.
static constexpr size_t negativeUNLMinLocalValsToVote
The minimum number of validations of the local node for it to participate in the voting.
const SF_U32 sfLedgerSequence(access, STI_UINT32, 6, "LedgerSequence")
A generic endpoint for log messages.
std::optional< hash_map< NodeID, std::uint32_t > > buildScoreTable(std::shared_ptr< Ledger const > const &prevLedger, hash_set< NodeID > const &unl, RCLValidations &validations)
Build a reliability measurement score table of validators' validation messages in the last flag ledge...
std::vector< WrappedValidationType > getTrustedForLedger(ID const &ledgerID)
Get trusted full validations for a specific ledger.
void addTx(LedgerIndex seq, PublicKey const &vp, NegativeUNLModify modify, std::shared_ptr< SHAMap > const &initialSet)
Add a ttUNL_MODIFY Tx to the transaction set.
static constexpr size_t newValidatorDisableSkip
We don't want to disable new validators immediately after adding them.
const SF_Vec256 sfHashes(access, STI_VECTOR256, 2, "Hashes")
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
static base_uint fromVoid(void const *data)
Blob const & peekData() const
NegativeUNLModify
A flag indicating whether a UNLModify Tx is to disable or to re-enable a validator.
static constexpr size_t negativeUNLLowWaterMark
A validator is considered unreliable if its validations is less than negativeUNLLowWaterMark in the l...
void purgeNewValidators(LedgerIndex seq)
Purge validators that are not new anymore.
NodeID choose(uint256 const &randomPadData, std::vector< NodeID > const &candidates)
Pick one candidate from a vector of candidates.
NegativeUNLVote(NodeID const &myId, beast::Journal j)
Constructor.
void newValidators(LedgerIndex seq, hash_set< NodeID > const &nowTrusted)
Notify NegativeUNLVote that new validators are added.