mirror of
https://github.com/XRPLF/rippled.git
synced 2026-01-20 06:35:22 +00:00
Compare commits
29 Commits
ximinez/fi
...
ximinez/di
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa4ddfa9b8 | ||
|
|
f254d398b1 | ||
|
|
01ef2a1e98 | ||
|
|
7608778a9f | ||
|
|
69c1ade7d5 | ||
|
|
8ad0d43744 | ||
|
|
039b8b90fd | ||
|
|
b9bda49134 | ||
|
|
69cb14c832 | ||
|
|
2ec85c2a98 | ||
|
|
6208a3aa9a | ||
|
|
e70b95195b | ||
|
|
2cc40a1647 | ||
|
|
238735d18b | ||
|
|
e5cdeab184 | ||
|
|
2acb3fc306 | ||
|
|
f3a9a9362d | ||
|
|
91c5ad2388 | ||
|
|
ced186ae6a | ||
|
|
e1b5945077 | ||
|
|
a2b4b06918 | ||
|
|
54d528868f | ||
|
|
6dd31bdef6 | ||
|
|
d411e38615 | ||
|
|
730ac9b763 | ||
|
|
39715d6915 | ||
|
|
fbeae82d61 | ||
|
|
429c15ac0d | ||
|
|
9382fe1c82 |
@@ -16,6 +16,7 @@
|
||||
// Add new amendments to the top of this list.
|
||||
// Keep it sorted in reverse chronological order.
|
||||
|
||||
XRPL_FEATURE(DefragDirectories, Supported::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (BatchInnerSigs, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(LendingProtocol, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(PermissionDelegationV1_1, Supported::no, VoteBehavior::DefaultNo)
|
||||
|
||||
@@ -10,6 +10,14 @@ namespace xrpl {
|
||||
|
||||
namespace directory {
|
||||
|
||||
struct Gap
|
||||
{
|
||||
uint64_t const page;
|
||||
SLE::pointer node;
|
||||
uint64_t const nextPage;
|
||||
SLE::pointer next;
|
||||
};
|
||||
|
||||
std::uint64_t
|
||||
createRoot(
|
||||
ApplyView& view,
|
||||
@@ -112,7 +120,9 @@ insertPage(
|
||||
return std::nullopt;
|
||||
if (!view.rules().enabled(fixDirectoryLimit) &&
|
||||
page >= dirNodeMaxPages) // Old pages limit
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// We are about to create a new node; we'll link it to
|
||||
// the chain first:
|
||||
@@ -134,13 +144,8 @@ insertPage(
|
||||
// it's the default.
|
||||
if (page != 1)
|
||||
node->setFieldU64(sfIndexPrevious, page - 1);
|
||||
XRPL_ASSERT_PARTS(
|
||||
!nextPage, "xrpl::directory::insertPage", "nextPage has default value");
|
||||
/* Reserved for future use when directory pages may be inserted in
|
||||
* between two other pages instead of only at the end of the chain.
|
||||
if (nextPage)
|
||||
node->setFieldU64(sfIndexNext, nextPage);
|
||||
*/
|
||||
describe(node);
|
||||
view.insert(node);
|
||||
|
||||
@@ -156,7 +161,7 @@ ApplyView::dirAdd(
|
||||
uint256 const& key,
|
||||
std::function<void(std::shared_ptr<SLE> const&)> const& describe)
|
||||
{
|
||||
auto root = peek(directory);
|
||||
auto const root = peek(directory);
|
||||
|
||||
if (!root)
|
||||
{
|
||||
@@ -167,6 +172,44 @@ ApplyView::dirAdd(
|
||||
auto [page, node, indexes] =
|
||||
directory::findPreviousPage(*this, directory, root);
|
||||
|
||||
if (rules().enabled(featureDefragDirectories))
|
||||
{
|
||||
// If there are more nodes than just the root, and there's no space in
|
||||
// the last one, walk backwards to find one with space, or to find one
|
||||
// missing.
|
||||
std::optional<directory::Gap> gapPages;
|
||||
while (page && indexes.size() >= dirNodeMaxEntries)
|
||||
{
|
||||
// Find a page with space, or a gap in pages.
|
||||
auto [prevPage, prevNode, prevIndexes] =
|
||||
directory::findPreviousPage(*this, directory, node);
|
||||
if (!gapPages && prevPage != page - 1)
|
||||
gapPages.emplace(prevPage, prevNode, page, node);
|
||||
page = prevPage;
|
||||
node = prevNode;
|
||||
indexes = prevIndexes;
|
||||
}
|
||||
// We looped through all the pages back to the root.
|
||||
if (!page)
|
||||
{
|
||||
// If we found a gap, use it.
|
||||
if (gapPages)
|
||||
{
|
||||
return directory::insertPage(
|
||||
*this,
|
||||
gapPages->page,
|
||||
gapPages->node,
|
||||
gapPages->nextPage,
|
||||
gapPages->next,
|
||||
key,
|
||||
directory,
|
||||
describe);
|
||||
}
|
||||
std::tie(page, node, indexes) =
|
||||
directory::findPreviousPage(*this, directory, root);
|
||||
}
|
||||
}
|
||||
|
||||
// If there's space, we use it:
|
||||
if (indexes.size() < dirNodeMaxEntries)
|
||||
{
|
||||
|
||||
@@ -129,12 +129,7 @@ ValidatorSite::load(
|
||||
{
|
||||
try
|
||||
{
|
||||
// This is not super efficient, but it doesn't happen often.
|
||||
bool found = std::ranges::any_of(sites_, [&uri](auto const& site) {
|
||||
return site.loadedResource->uri == uri;
|
||||
});
|
||||
if (!found)
|
||||
sites_.emplace_back(uri);
|
||||
sites_.emplace_back(uri);
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
@@ -196,17 +191,6 @@ ValidatorSite::setTimer(
|
||||
std::lock_guard<std::mutex> const& site_lock,
|
||||
std::lock_guard<std::mutex> const& state_lock)
|
||||
{
|
||||
if (!sites_.empty() && //
|
||||
std::ranges::all_of(sites_, [](auto const& site) {
|
||||
return site.lastRefreshStatus.has_value();
|
||||
}))
|
||||
{
|
||||
// If all of the sites have been handled at least once (including
|
||||
// errors and timeouts), call missingSite, which will load the cache
|
||||
// files for any lists that are still unavailable.
|
||||
missingSite(site_lock);
|
||||
}
|
||||
|
||||
auto next = std::min_element(
|
||||
sites_.begin(), sites_.end(), [](Site const& a, Site const& b) {
|
||||
return a.nextRefresh < b.nextRefresh;
|
||||
@@ -319,16 +303,13 @@ ValidatorSite::onRequestTimeout(std::size_t siteIdx, error_code const& ec)
|
||||
// processes a network error. Usually, this function runs first,
|
||||
// but on extremely rare occasions, the response handler can run
|
||||
// first, which will leave activeResource empty.
|
||||
auto& site = sites_[siteIdx];
|
||||
auto const& site = sites_[siteIdx];
|
||||
if (site.activeResource)
|
||||
JLOG(j_.warn()) << "Request for " << site.activeResource->uri
|
||||
<< " took too long";
|
||||
else
|
||||
JLOG(j_.error()) << "Request took too long, but a response has "
|
||||
"already been processed";
|
||||
if (!site.lastRefreshStatus)
|
||||
site.lastRefreshStatus.emplace(Site::Status{
|
||||
clock_type::now(), ListDisposition::invalid, "timeout"});
|
||||
}
|
||||
|
||||
std::lock_guard lock_state{state_mutex_};
|
||||
|
||||
Reference in New Issue
Block a user