mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Improve directory insertion & deletion (RIPD-1353, RIPD-1488):
This commit introduces the "SortedDirectories" amendment, which addresses two distinct issues: First, it corrects a technical flaw that could, in some edge cases, prevent an empty intermediate page from being deleted. Second, it sorts directory entries within a page (other than order book page entries, which remain strictly FIFO). This makes insert operations deterministic, instead of pseudo-random and reliant on temporal ordering. Lastly, it removes the ability to perform a "soft delete" where the page number of the item to delete need not be known if the item is in the first 20 pages, and enforces a maximum limit to the number of pages that a directory can span.
This commit is contained in:
@@ -835,107 +835,8 @@ class GetAmendments_test
|
||||
}
|
||||
};
|
||||
|
||||
class DirIsEmpty_test
|
||||
: public beast::unit_test::suite
|
||||
{
|
||||
void
|
||||
testDirIsEmpty()
|
||||
{
|
||||
using namespace jtx;
|
||||
auto const alice = Account("alice");
|
||||
auto const bogie = Account("bogie");
|
||||
|
||||
Env env(*this, with_features(featureMultiSign));
|
||||
|
||||
env.fund(XRP(10000), alice);
|
||||
env.close();
|
||||
|
||||
// alice should have an empty directory.
|
||||
BEAST_EXPECT(dirIsEmpty (*env.closed(), keylet::ownerDir(alice)));
|
||||
|
||||
// Give alice a signer list, then there will be stuff in the directory.
|
||||
env(signers(alice, 1, { { bogie, 1} }));
|
||||
env.close();
|
||||
BEAST_EXPECT(! dirIsEmpty (*env.closed(), keylet::ownerDir(alice)));
|
||||
|
||||
env(signers(alice, jtx::none));
|
||||
env.close();
|
||||
BEAST_EXPECT(dirIsEmpty (*env.closed(), keylet::ownerDir(alice)));
|
||||
|
||||
// The next test is a bit awkward. It tests the case where alice
|
||||
// uses 3 directory pages and then deletes all entries from the
|
||||
// first 2 pages. dirIsEmpty() should still return false in this
|
||||
// circumstance.
|
||||
//
|
||||
// Fill alice's directory with implicit trust lines (produced by
|
||||
// taking offers) and then remove all but the last one.
|
||||
auto const becky = Account ("becky");
|
||||
auto const gw = Account ("gw");
|
||||
env.fund(XRP(10000), becky, gw);
|
||||
env.close();
|
||||
|
||||
static_assert (64 >= (2 * dirNodeMaxEntries), "");
|
||||
|
||||
// Generate 64 currencies named AAA -> AAP and ADA -> ADP.
|
||||
std::vector<IOU> currencies;
|
||||
currencies.reserve(64);
|
||||
for (char b = 'A'; b <= 'D'; ++b)
|
||||
{
|
||||
for (char c = 'A'; c <= 'P'; ++c)
|
||||
{
|
||||
currencies.push_back(gw[std::string("A") + b + c]);
|
||||
IOU const& currency = currencies.back();
|
||||
|
||||
// Establish trust lines.
|
||||
env(trust(becky, currency(50)));
|
||||
env.close();
|
||||
env(pay(gw, becky, currency(50)));
|
||||
env.close();
|
||||
env(offer(alice, currency(50), XRP(10)));
|
||||
env(offer(becky, XRP(10), currency(50)));
|
||||
env.close();
|
||||
}
|
||||
}
|
||||
|
||||
// Set up one more currency that alice will hold onto. We expect
|
||||
// this one to go in the third directory page.
|
||||
IOU const lastCurrency = gw["ZZZ"];
|
||||
env(trust(becky, lastCurrency(50)));
|
||||
env.close();
|
||||
env(pay(gw, becky, lastCurrency(50)));
|
||||
env.close();
|
||||
env(offer(alice, lastCurrency(50), XRP(10)));
|
||||
env(offer(becky, XRP(10), lastCurrency(50)));
|
||||
env.close();
|
||||
|
||||
BEAST_EXPECT(! dirIsEmpty (*env.closed(), keylet::ownerDir(alice)));
|
||||
|
||||
// Now alice gives all the currencies except the last one back to becky.
|
||||
for (auto currency : currencies)
|
||||
{
|
||||
env(pay(alice, becky, currency(50)));
|
||||
env.close();
|
||||
}
|
||||
|
||||
// This is the crux of the test.
|
||||
BEAST_EXPECT(! dirIsEmpty (*env.closed(), keylet::ownerDir(alice)));
|
||||
|
||||
// Give the last currency to becky. Now alice's directory is empty.
|
||||
env(pay(alice, becky, lastCurrency(50)));
|
||||
env.close();
|
||||
|
||||
BEAST_EXPECT(dirIsEmpty (*env.closed(), keylet::ownerDir(alice)));
|
||||
}
|
||||
|
||||
void run() override
|
||||
{
|
||||
testDirIsEmpty();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(View,ledger,ripple);
|
||||
BEAST_DEFINE_TESTSUITE(GetAmendments,ledger,ripple);
|
||||
BEAST_DEFINE_TESTSUITE(DirIsEmpty, ledger,ripple);
|
||||
|
||||
} // test
|
||||
} // ripple
|
||||
|
||||
Reference in New Issue
Block a user