mirror of
https://github.com/XRPLF/rippled.git
synced 2026-04-28 15:07:54 +00:00
Compare commits
15 Commits
bthomee/lo
...
ximinez/fi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4589fcbcfc | ||
|
|
86d840f53d | ||
|
|
741b61cdf3 | ||
|
|
6bb0989c9f | ||
|
|
9120506613 | ||
|
|
3b3de96bd4 | ||
|
|
c9ab6ab25f | ||
|
|
fb0605cfd3 | ||
|
|
156553bb5e | ||
|
|
781b56849b | ||
|
|
278c02bebb | ||
|
|
1d6fedf9a2 | ||
|
|
2e8de499aa | ||
|
|
0bce3639a6 | ||
|
|
8f329e3bc6 |
@@ -20,6 +20,10 @@ removeTokenOffersWithLimit(
|
||||
Keylet const& directory,
|
||||
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. */
|
||||
std::optional<STObject>
|
||||
findToken(ReadView const& view, AccountID const& owner, uint256 const& nftokenID);
|
||||
|
||||
@@ -493,14 +493,14 @@ void
|
||||
Ledger::rawErase(std::shared_ptr<SLE> const& sle)
|
||||
{
|
||||
if (!stateMap_.delItem(sle->key()))
|
||||
LogicError("Ledger::rawErase: key not found");
|
||||
Throw<std::logic_error>("Ledger::rawErase: key not found");
|
||||
}
|
||||
|
||||
void
|
||||
Ledger::rawErase(uint256 const& key)
|
||||
{
|
||||
if (!stateMap_.delItem(key))
|
||||
LogicError("Ledger::rawErase: key not found");
|
||||
Throw<std::logic_error>("Ledger::rawErase: key not found");
|
||||
}
|
||||
|
||||
void
|
||||
@@ -510,7 +510,7 @@ Ledger::rawInsert(std::shared_ptr<SLE> const& sle)
|
||||
sle->add(ss);
|
||||
if (!stateMap_.addGiveItem(
|
||||
SHAMapNodeType::tnACCOUNT_STATE, make_shamapitem(sle->key(), ss.slice())))
|
||||
LogicError("Ledger::rawInsert: key already exists");
|
||||
Throw<std::logic_error>("Ledger::rawInsert: key already exists");
|
||||
}
|
||||
|
||||
void
|
||||
@@ -520,7 +520,7 @@ Ledger::rawReplace(std::shared_ptr<SLE> const& sle)
|
||||
sle->add(ss);
|
||||
if (!stateMap_.updateGiveItem(
|
||||
SHAMapNodeType::tnACCOUNT_STATE, make_shamapitem(sle->key(), ss.slice())))
|
||||
LogicError("Ledger::rawReplace: key not found");
|
||||
Throw<std::logic_error>("Ledger::rawReplace: key not found");
|
||||
}
|
||||
|
||||
void
|
||||
@@ -536,7 +536,7 @@ Ledger::rawTxInsert(
|
||||
s.addVL(txn->peekData());
|
||||
s.addVL(metaData->peekData());
|
||||
if (!txMap_.addGiveItem(SHAMapNodeType::tnTRANSACTION_MD, make_shamapitem(key, s.slice())))
|
||||
LogicError("duplicate_tx: " + to_string(key));
|
||||
Throw<std::logic_error>("duplicate_tx: " + to_string(key));
|
||||
}
|
||||
|
||||
uint256
|
||||
|
||||
@@ -621,6 +621,33 @@ removeTokenOffersWithLimit(ApplyView& view, Keylet const& directory, std::size_t
|
||||
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
|
||||
deleteTokenOffer(ApplyView& view, std::shared_ptr<SLE> const& offer)
|
||||
{
|
||||
|
||||
@@ -161,7 +161,11 @@ ValidatorSite::load(
|
||||
{
|
||||
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)
|
||||
{
|
||||
@@ -222,7 +226,17 @@ ValidatorSite::setTimer(
|
||||
std::lock_guard<std::mutex> const& site_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; });
|
||||
|
||||
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,
|
||||
// but on extremely rare occasions, the response handler can run
|
||||
// first, which will leave activeResource empty.
|
||||
auto const& site = sites_[siteIdx];
|
||||
auto& site = sites_[siteIdx];
|
||||
if (site.activeResource)
|
||||
{
|
||||
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
|
||||
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 const lock_state{state_mutex_};
|
||||
|
||||
Reference in New Issue
Block a user