refactor: Use LedgerHashesEntry everywhere (#8369)

This commit is contained in:
Mayukha Vadari
2026-10-05 18:15:02 +00:00
committed by GitHub
parent cd633b9ac9
commit 1798262d7a
5 changed files with 45 additions and 15 deletions

View File

@@ -1,11 +1,17 @@
#pragma once
#include <xrpl/basics/base_uint.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/ledger/entries/SLEBase.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/LedgerFormats.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STVector256.h>
#include <cstddef>
#include <optional>
namespace xrpl {
@@ -25,6 +31,31 @@ public:
: Base(keylet::skip(), view, j)
{
}
/**
* Looks up a hash `diff` slots back from the most recent entry in the
* sfHashes vector (diff == 0 is the most recent entry).
*
* Callers decide which skip list entry to read and how to translate a
* target ledger sequence into `diff`; this only does the bounds check
* and vector indexing shared by both the recent (stride 1) and distant
* (stride 256) skip lists.
*
* @param diff how many slots back from the most recent hash to look up;
* 0 is the most recent hash.
* @return the hash at that slot, or std::nullopt if the entry does not
* exist or `diff` is out of range.
*/
[[nodiscard]] std::optional<UInt256>
hashAt(std::size_t diff) const
{
if (!this->exists())
return std::nullopt;
STVector256 const vec = (*this)->getFieldV256(sfHashes);
if (vec.size() > diff)
return vec[vec.size() - diff - 1];
return std::nullopt;
}
};
using LedgerHashesEntryR = LedgerHashesEntry<ReadView>;

View File

@@ -9,6 +9,7 @@
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/ledger/entries/LedgerHashesEntry.h>
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
#include <xrpl/ledger/helpers/CredentialHelpers.h>
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
@@ -361,17 +362,16 @@ hashOfSeq(ReadView const& ledger, LedgerIndex seq, beast::Journal journal)
if (int const diff = ledger.seq() - seq; diff <= 256)
{
// Within 256...
auto const hashIndex = ledger.read(keylet::skip());
LedgerHashesEntryR const hashIndex(ledger, journal);
if (hashIndex)
{
XRPL_ASSERT(
hashIndex->getFieldU32(sfLastLedgerSequence) == (ledger.seq() - 1),
"xrpl::hashOfSeq : matching ledger sequence");
STVector256 vec = hashIndex->getFieldV256(sfHashes);
if (vec.size() >= diff)
return vec[vec.size() - diff];
if (auto const hash = hashIndex.hashAt(diff - 1))
return hash;
JLOG(journal.warn()) << "Ledger " << ledger.seq() << " missing hash for " << seq << " ("
<< vec.size() << "," << diff << ")";
<< hashIndex->getFieldV256(sfHashes).size() << "," << diff << ")";
}
else
{
@@ -387,16 +387,14 @@ hashOfSeq(ReadView const& ledger, LedgerIndex seq, beast::Journal journal)
}
// in skiplist
auto const hashIndex = ledger.read(keylet::skip(seq));
LedgerHashesEntryR const hashIndex(keylet::skip(seq), ledger, journal);
if (hashIndex)
{
auto const lastSeq = hashIndex->getFieldU32(sfLastLedgerSequence);
XRPL_ASSERT(lastSeq >= seq, "xrpl::hashOfSeq : minimum last ledger");
XRPL_ASSERT((lastSeq & 0xff) == 0, "xrpl::hashOfSeq : valid last ledger");
auto const diff = (lastSeq - seq) >> 8;
STVector256 vec = hashIndex->getFieldV256(sfHashes);
if (vec.size() > diff)
return vec[vec.size() - diff - 1];
if (auto const hash = hashIndex.hashAt((lastSeq - seq) >> 8))
return hash;
}
JLOG(journal.warn()) << "Can't get seq " << seq << " from " << ledger.seq() << " error";
return std::nullopt;

View File

@@ -14,7 +14,7 @@
#include <xrpl/core/Job.h>
#include <xrpl/core/JobQueue.h>
#include <xrpl/core/PerfLog.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/ledger/entries/LedgerHashesEntry.h>
#include <xrpl/protocol/PublicKey.h>
#include <xrpl/protocol/RippleLedgerHash.h>
#include <xrpl/protocol/SField.h>
@@ -36,7 +36,7 @@ RCLValidatedLedger::RCLValidatedLedger(
beast::Journal j)
: ledgerID_{ledger->header().hash}, ledgerSeq_{ledger->seq()}, j_{j}
{
auto const hashIndex = ledger->read(keylet::skip());
LedgerHashesEntryR const hashIndex(*ledger, j_);
if (hashIndex)
{
XRPL_ASSERT(

View File

@@ -13,6 +13,7 @@
#include <xrpl/basics/base_uint.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/core/Job.h>
#include <xrpl/ledger/entries/LedgerHashesEntry.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/shamap/SHAMapItem.h>
@@ -183,7 +184,7 @@ SkipListAcquire::getData() const
void
SkipListAcquire::retrieveSkipList(std::shared_ptr<Ledger const> const& ledger, ScopedLockType& sl)
{
if (auto const hashIndex = ledger->read(keylet::skip());
if (LedgerHashesEntryR const hashIndex(*ledger, journal_);
hashIndex && hashIndex->isFieldPresent(sfHashes))
{
auto const& slist = hashIndex->getFieldV256(sfHashes).value();

View File

@@ -8,7 +8,7 @@
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/ledger/Ledger.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/ledger/entries/LedgerHashesEntry.h>
#include <xrpl/protocol/Protocol.h>
#include <xrpl/protocol/PublicKey.h>
#include <xrpl/protocol/SField.h>
@@ -170,7 +170,7 @@ NegativeUNLVote::buildScoreTable(
validations.setSeqToKeep(seq - 1, seq + kFlagLedgerInterval);
// Find FLAG_LEDGER_INTERVAL (i.e. 256) previous ledger hashes
auto const hashIndex = prevLedger->read(keylet::skip());
LedgerHashesEntryR const hashIndex(*prevLedger, j_);
if (!hashIndex || !hashIndex->isFieldPresent(sfHashes))
{
JLOG(j_.debug()) << "N-UNL: ledger " << seq << " no history.";