mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Log metadata differences on built ledger mismatch
This commit is contained in:
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include <BeastConfig.h>
|
#include <BeastConfig.h>
|
||||||
#include <ripple/app/ledger/LedgerHistory.h>
|
#include <ripple/app/ledger/LedgerHistory.h>
|
||||||
|
#include <ripple/app/ledger/LedgerToJson.h>
|
||||||
#include <ripple/basics/Log.h>
|
#include <ripple/basics/Log.h>
|
||||||
#include <ripple/basics/chrono.h>
|
#include <ripple/basics/chrono.h>
|
||||||
#include <ripple/json/to_string.h>
|
#include <ripple/json/to_string.h>
|
||||||
@@ -270,6 +271,26 @@ log_metadata_difference(Ledger::pointer builtLedger, Ledger::pointer validLedger
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Return list of leaves sorted by key
|
||||||
|
static
|
||||||
|
std::vector<std::shared_ptr<
|
||||||
|
SHAMapItem const>>
|
||||||
|
leaves (SHAMap const& sm)
|
||||||
|
{
|
||||||
|
std::vector<std::shared_ptr<
|
||||||
|
SHAMapItem const>> v;
|
||||||
|
for (auto const& item : sm)
|
||||||
|
v.push_back(item);
|
||||||
|
std::sort(v.begin(), v.end(),
|
||||||
|
[](std::shared_ptr<SHAMapItem const> const& lhs,
|
||||||
|
std::shared_ptr<SHAMapItem const> const& rhs)
|
||||||
|
{ return lhs->key() < rhs->key(); });
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void LedgerHistory::handleMismatch (LedgerHash const& built, LedgerHash const& valid)
|
void LedgerHistory::handleMismatch (LedgerHash const& built, LedgerHash const& valid)
|
||||||
{
|
{
|
||||||
assert (built != valid);
|
assert (built != valid);
|
||||||
@@ -306,76 +327,51 @@ void LedgerHistory::handleMismatch (LedgerHash const& built, LedgerHash const& v
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find differences between built and valid ledgers
|
// Find differences between built and valid ledgers
|
||||||
using SHAMapItemInfo = std::pair<uint256, Blob>;
|
auto const builtTx = leaves(builtLedger->txMap());
|
||||||
std::vector <SHAMapItemInfo> builtTx, validTx;
|
auto const validTx = leaves(validLedger->txMap());
|
||||||
// Get built ledger hashes and metadata
|
|
||||||
builtLedger->txMap().visitLeaves(
|
|
||||||
[&builtTx](std::shared_ptr<SHAMapItem const> const& item)
|
|
||||||
{
|
|
||||||
builtTx.push_back({item->key(), item->peekData()});
|
|
||||||
});
|
|
||||||
// Get valid ledger hashes and metadata
|
|
||||||
validLedger->txMap().visitLeaves(
|
|
||||||
[&validTx](std::shared_ptr<SHAMapItem const> const& item)
|
|
||||||
{
|
|
||||||
validTx.push_back({item->key(), item->peekData()});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Sort both by hash
|
|
||||||
std::sort (builtTx.begin(), builtTx.end(),
|
|
||||||
[](SHAMapItemInfo const& x, SHAMapItemInfo const& y)
|
|
||||||
{return x.first < y.first;});
|
|
||||||
std::sort (validTx.begin(), validTx.end(),
|
|
||||||
[](SHAMapItemInfo const& x, SHAMapItemInfo const& y)
|
|
||||||
{return x.first < y.first;});
|
|
||||||
|
|
||||||
if (builtTx == validTx)
|
if (builtTx == validTx)
|
||||||
{
|
|
||||||
WriteLog (lsERROR, LedgerMaster) <<
|
WriteLog (lsERROR, LedgerMaster) <<
|
||||||
"MISMATCH with same " << builtTx.size() << " transactions";
|
"MISMATCH with same " << builtTx.size() << " transactions";
|
||||||
return;
|
else
|
||||||
}
|
WriteLog (lsERROR, LedgerMaster) << "MISMATCH with " <<
|
||||||
|
builtTx.size() << " built and " <<
|
||||||
|
validTx.size() << " valid transactions.";
|
||||||
|
|
||||||
WriteLog (lsERROR, LedgerMaster) << "MISMATCH with " <<
|
WriteLog(lsERROR, LedgerMaster) << "built\n" <<
|
||||||
builtTx.size() << " built and " <<
|
getJson(*builtLedger);
|
||||||
validTx.size() << " valid transactions.";
|
WriteLog(lsERROR, LedgerMaster) << "valid\n" <<
|
||||||
|
getJson(*validLedger);
|
||||||
|
|
||||||
// Log all differences between built and valid ledgers
|
// Log all differences between built and valid ledgers
|
||||||
auto b = builtTx.cbegin();
|
auto b = builtTx.begin();
|
||||||
auto be = builtTx.cend();
|
auto v = validTx.begin();
|
||||||
auto v = validTx.cbegin();
|
while(b != builtTx.end() && v != validTx.end())
|
||||||
auto ve = validTx.cend();
|
|
||||||
while (b != be && v != ve)
|
|
||||||
{
|
{
|
||||||
if (b->first < v->first)
|
if ((*b)->key() < (*v)->key())
|
||||||
{
|
{
|
||||||
// b->first in built but not in valid
|
log_one (builtLedger, (*b)->key(), "valid");
|
||||||
log_one(builtLedger, b->first, "valid");
|
|
||||||
++b;
|
++b;
|
||||||
}
|
}
|
||||||
else if (v->first < b->first)
|
else if ((*b)->key() > (*v)->key())
|
||||||
{
|
{
|
||||||
// v->first in valid but not in built
|
log_one(validLedger, (*v)->key(), "built");
|
||||||
log_one(validLedger, v->first, "built");
|
|
||||||
++v;
|
++v;
|
||||||
}
|
}
|
||||||
else // b->first == v->first, same transaction
|
else
|
||||||
{
|
{
|
||||||
if (b->second != v->second)
|
if ((*b)->peekData() != (*v)->peekData())
|
||||||
{
|
{
|
||||||
// Same transaction with different metadata
|
// Same transaction with different metadata
|
||||||
log_metadata_difference(builtLedger, validLedger, b->first);
|
log_metadata_difference(builtLedger, validLedger, (*b)->key());
|
||||||
}
|
}
|
||||||
++b;
|
++b;
|
||||||
++v;
|
++v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// all of these are in built but not in valid
|
for (; b != builtTx.end(); ++b)
|
||||||
for (; b != be; ++b)
|
log_one (builtLedger, (*b)->key(), "valid");
|
||||||
log_one(builtLedger, b->first, "valid");
|
for (; v != validTx.end(); ++v)
|
||||||
// all of these are in valid but not in built
|
log_one (validLedger, (*v)->key(), "built");
|
||||||
for (; v != ve; ++v)
|
|
||||||
log_one(validLedger, v->first, "built");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LedgerHistory::builtLedger (Ledger::ref ledger)
|
void LedgerHistory::builtLedger (Ledger::ref ledger)
|
||||||
|
|||||||
Reference in New Issue
Block a user