fix amendment to add PreviousTxnID/PreviousTxnLgrSequence (#4751)

This amendment, `fixPreviousTxnID`, adds `PreviousTxnID` and
`PreviousTxnLgrSequence` as fields to all ledger objects that did
not already have them included (`DirectoryNode`, `Amendments`,
`FeeSettings`, `NegativeUNL`, and `AMM`). This makes it much easier
to go through the history of these ledger objects.
This commit is contained in:
Mayukha Vadari
2024-04-18 10:41:25 -04:00
committed by GitHub
parent c88166e055
commit 659bd99a67
12 changed files with 164 additions and 34 deletions

View File

@@ -396,6 +396,96 @@ struct Directory_test : public beast::unit_test::suite
}
}
void
testPreviousTxnID()
{
testcase("fixPreviousTxnID");
using namespace jtx;
auto const gw = Account{"gateway"};
auto const alice = Account{"alice"};
auto const USD = gw["USD"];
auto ledger_data = [this](Env& env) {
Json::Value params;
params[jss::type] = jss::directory;
params[jss::ledger_index] = "validated";
auto const result =
env.rpc("json", "ledger_data", to_string(params))[jss::result];
BEAST_EXPECT(!result.isMember(jss::marker));
return result;
};
// fixPreviousTxnID is disabled.
Env env(*this, supported_amendments() - fixPreviousTxnID);
env.fund(XRP(10000), alice, gw);
env.close();
env.trust(USD(1000), alice);
env(pay(gw, alice, USD(1000)));
env.close();
{
auto const jrr = ledger_data(env);
auto const& jstate = jrr[jss::state];
BEAST_EXPECTS(checkArraySize(jstate, 2), jrr.toStyledString());
for (auto const& directory : jstate)
{
BEAST_EXPECT(
directory["LedgerEntryType"] ==
jss::DirectoryNode); // sanity check
// The PreviousTxnID and PreviousTxnLgrSeq fields should not be
// on the DirectoryNode object when the amendment is disabled
BEAST_EXPECT(!directory.isMember("PreviousTxnID"));
BEAST_EXPECT(!directory.isMember("PreviousTxnLgrSeq"));
}
}
// Now enable the amendment so the directory node is updated.
env.enableFeature(fixPreviousTxnID);
env.close();
// Make sure the `PreviousTxnID` and `PreviousTxnLgrSeq` fields now
// exist
env(offer(alice, XRP(1), USD(1)));
auto const txID = to_string(env.tx()->getTransactionID());
auto const ledgerSeq = env.current()->info().seq;
env.close();
// Make sure the fields only exist if the object is touched
env(noop(gw));
env.close();
{
auto const jrr = ledger_data(env);
auto const& jstate = jrr[jss::state];
BEAST_EXPECTS(checkArraySize(jstate, 3), jrr.toStyledString());
for (auto const& directory : jstate)
{
BEAST_EXPECT(
directory["LedgerEntryType"] ==
jss::DirectoryNode); // sanity check
if (directory[jss::Owner] == gw.human())
{
// gw's directory did not get touched, so it
// should not have those fields populated
BEAST_EXPECT(!directory.isMember("PreviousTxnID"));
BEAST_EXPECT(!directory.isMember("PreviousTxnLgrSeq"));
}
else
{
// All of the other directories, including the order
// book, did get touched, so they should have those
// fields
BEAST_EXPECT(
directory.isMember("PreviousTxnID") &&
directory["PreviousTxnID"].asString() == txID);
BEAST_EXPECT(
directory.isMember("PreviousTxnLgrSeq") &&
directory["PreviousTxnLgrSeq"].asUInt() == ledgerSeq);
}
}
}
}
void
run() override
{
@@ -403,6 +493,7 @@ struct Directory_test : public beast::unit_test::suite
testDirIsEmpty();
testRipd1353();
testEmptyChain();
testPreviousTxnID();
}
};