mirror of
https://github.com/XRPLF/rippled.git
synced 2026-04-29 15:37:57 +00:00
Compare commits
16 Commits
develop
...
ximinez/fi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
72c700c3e0 | ||
|
|
4589fcbcfc | ||
|
|
86d840f53d | ||
|
|
741b61cdf3 | ||
|
|
6bb0989c9f | ||
|
|
9120506613 | ||
|
|
3b3de96bd4 | ||
|
|
c9ab6ab25f | ||
|
|
fb0605cfd3 | ||
|
|
156553bb5e | ||
|
|
781b56849b | ||
|
|
278c02bebb | ||
|
|
1d6fedf9a2 | ||
|
|
2e8de499aa | ||
|
|
0bce3639a6 | ||
|
|
8f329e3bc6 |
@@ -20,6 +20,10 @@ removeTokenOffersWithLimit(
|
|||||||
Keylet const& directory,
|
Keylet const& directory,
|
||||||
std::size_t maxDeletableOffers);
|
std::size_t maxDeletableOffers);
|
||||||
|
|
||||||
|
/** Returns tesSUCCESS if NFToken has few enough offers that it can be burned */
|
||||||
|
TER
|
||||||
|
notTooManyOffers(ReadView const& view, uint256 const& nftokenID);
|
||||||
|
|
||||||
/** Finds the specified token in the owner's token directory. */
|
/** Finds the specified token in the owner's token directory. */
|
||||||
std::optional<STObject>
|
std::optional<STObject>
|
||||||
findToken(ReadView const& view, AccountID const& owner, uint256 const& nftokenID);
|
findToken(ReadView const& view, AccountID const& owner, uint256 const& nftokenID);
|
||||||
|
|||||||
@@ -621,6 +621,33 @@ removeTokenOffersWithLimit(ApplyView& view, Keylet const& directory, std::size_t
|
|||||||
return deletedOffersCount;
|
return deletedOffersCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TER
|
||||||
|
notTooManyOffers(ReadView const& view, uint256 const& nftokenID)
|
||||||
|
{
|
||||||
|
std::size_t totalOffers = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
Dir const buys(view, keylet::nft_buys(nftokenID));
|
||||||
|
for (auto iter = buys.begin(); iter != buys.end(); iter.next_page())
|
||||||
|
{
|
||||||
|
totalOffers += iter.page_size();
|
||||||
|
if (totalOffers > maxDeletableTokenOfferEntries)
|
||||||
|
return tefTOO_BIG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Dir const sells(view, keylet::nft_sells(nftokenID));
|
||||||
|
for (auto iter = sells.begin(); iter != sells.end(); iter.next_page())
|
||||||
|
{
|
||||||
|
totalOffers += iter.page_size();
|
||||||
|
if (totalOffers > maxDeletableTokenOfferEntries)
|
||||||
|
return tefTOO_BIG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tesSUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
deleteTokenOffer(ApplyView& view, std::shared_ptr<SLE> const& offer)
|
deleteTokenOffer(ApplyView& view, std::shared_ptr<SLE> const& offer)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -161,7 +161,11 @@ ValidatorSite::load(
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
sites_.emplace_back(uri);
|
// 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);
|
||||||
}
|
}
|
||||||
catch (std::exception const& e)
|
catch (std::exception const& e)
|
||||||
{
|
{
|
||||||
@@ -222,7 +226,17 @@ ValidatorSite::setTimer(
|
|||||||
std::lock_guard<std::mutex> const& site_lock,
|
std::lock_guard<std::mutex> const& site_lock,
|
||||||
std::lock_guard<std::mutex> const& state_lock)
|
std::lock_guard<std::mutex> const& state_lock)
|
||||||
{
|
{
|
||||||
auto next = std::ranges::min_element(
|
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 const next = std::ranges::min_element(
|
||||||
sites_, [](Site const& a, Site const& b) { return a.nextRefresh < b.nextRefresh; });
|
sites_, [](Site const& a, Site const& b) { return a.nextRefresh < b.nextRefresh; });
|
||||||
|
|
||||||
if (next != sites_.end())
|
if (next != sites_.end())
|
||||||
@@ -333,7 +347,7 @@ ValidatorSite::onRequestTimeout(std::size_t siteIdx, error_code const& ec)
|
|||||||
// processes a network error. Usually, this function runs first,
|
// processes a network error. Usually, this function runs first,
|
||||||
// but on extremely rare occasions, the response handler can run
|
// but on extremely rare occasions, the response handler can run
|
||||||
// first, which will leave activeResource empty.
|
// first, which will leave activeResource empty.
|
||||||
auto const& site = sites_[siteIdx];
|
auto& site = sites_[siteIdx];
|
||||||
if (site.activeResource)
|
if (site.activeResource)
|
||||||
{
|
{
|
||||||
JLOG(j_.warn()) << "Request for " << site.activeResource->uri << " took too long";
|
JLOG(j_.warn()) << "Request for " << site.activeResource->uri << " took too long";
|
||||||
@@ -341,6 +355,9 @@ ValidatorSite::onRequestTimeout(std::size_t siteIdx, error_code const& ec)
|
|||||||
else
|
else
|
||||||
JLOG(j_.error()) << "Request took too long, but a response has "
|
JLOG(j_.error()) << "Request took too long, but a response has "
|
||||||
"already been processed";
|
"already been processed";
|
||||||
|
if (!site.lastRefreshStatus)
|
||||||
|
site.lastRefreshStatus.emplace(
|
||||||
|
Site::Status{clock_type::now(), ListDisposition::invalid, "timeout"});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard const lock_state{state_mutex_};
|
std::lock_guard const lock_state{state_mutex_};
|
||||||
|
|||||||
Reference in New Issue
Block a user