mirror of
https://github.com/XRPLF/rippled.git
synced 2026-04-27 22:47:55 +00:00
Compare commits
4 Commits
ximinez/fi
...
mvadari/fi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a7d3fb2c8 | ||
|
|
0039ab8ce6 | ||
|
|
a6d9060218 | ||
|
|
6afe1ba64c |
@@ -20,10 +20,6 @@ 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);
|
||||
|
||||
@@ -621,33 +621,6 @@ 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)
|
||||
{
|
||||
|
||||
@@ -100,7 +100,7 @@ SField::SField(private_access_tag_t, int fc, char const* fn)
|
||||
, fieldName(fn)
|
||||
, fieldMeta(sMD_Never)
|
||||
, fieldNum(++num)
|
||||
, signingField(IsSigning::yes)
|
||||
, signingField(IsSigning::no)
|
||||
, jsonName(fieldName.c_str())
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
#include <xrpl/protocol/TxFlags.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
class ServerDefinitions_test : public beast::unit_test::suite
|
||||
@@ -37,20 +40,23 @@ public:
|
||||
|
||||
{
|
||||
auto const firstField = result[jss::result][jss::FIELDS][0u];
|
||||
BEAST_EXPECT(firstField[0u].asString() == "Generic");
|
||||
BEAST_EXPECT(firstField[0u].asString() == "Invalid");
|
||||
BEAST_EXPECT(firstField[1][jss::isSerialized].asBool() == false);
|
||||
BEAST_EXPECT(firstField[1][jss::isSigningField].asBool() == false);
|
||||
BEAST_EXPECT(firstField[1][jss::isVLEncoded].asBool() == false);
|
||||
BEAST_EXPECT(firstField[1][jss::nth].asUInt() == 0);
|
||||
BEAST_EXPECT(firstField[1][jss::nth].asInt() == -1);
|
||||
BEAST_EXPECT(firstField[1][jss::type].asString() == "Unknown");
|
||||
}
|
||||
|
||||
BEAST_EXPECT(
|
||||
result[jss::result][jss::LEDGER_ENTRY_TYPES]["AccountRoot"].asUInt() == 97);
|
||||
BEAST_EXPECT(
|
||||
result[jss::result][jss::TRANSACTION_RESULTS]["tecDIR_FULL"].asUInt() == 121);
|
||||
BEAST_EXPECT(result[jss::result][jss::TRANSACTION_TYPES]["Payment"].asUInt() == 0);
|
||||
BEAST_EXPECT(result[jss::result][jss::TYPES]["AccountID"].asUInt() == 8);
|
||||
{
|
||||
auto const field = result[jss::result][jss::FIELDS][6u];
|
||||
BEAST_EXPECT(field[0u].asString() == "LedgerEntryType");
|
||||
BEAST_EXPECT(field[1][jss::isSerialized].asBool() == true);
|
||||
BEAST_EXPECT(field[1][jss::isSigningField].asBool() == true);
|
||||
BEAST_EXPECT(field[1][jss::isVLEncoded].asBool() == false);
|
||||
BEAST_EXPECT(field[1][jss::nth].asUInt() == 1);
|
||||
BEAST_EXPECT(field[1][jss::type].asString() == "UInt16");
|
||||
}
|
||||
|
||||
// check exception SFields
|
||||
{
|
||||
@@ -74,17 +80,34 @@ public:
|
||||
BEAST_EXPECT(fieldExists("index"));
|
||||
}
|
||||
|
||||
// verify no duplicate field names in FIELDS array
|
||||
{
|
||||
std::set<std::string> fieldNames;
|
||||
for (auto const& field : result[jss::result][jss::FIELDS])
|
||||
{
|
||||
auto const name = field[0u].asString();
|
||||
BEAST_EXPECT(fieldNames.insert(name).second);
|
||||
}
|
||||
}
|
||||
|
||||
// test that base_uint types are replaced with "Hash" prefix
|
||||
{
|
||||
auto const types = result[jss::result][jss::TYPES];
|
||||
BEAST_EXPECT(types["Hash128"].asUInt() == 4);
|
||||
BEAST_EXPECT(types["Hash160"].asUInt() == 17);
|
||||
BEAST_EXPECT(types["Hash192"].asUInt() == 21);
|
||||
BEAST_EXPECT(types["Hash256"].asUInt() == 5);
|
||||
BEAST_EXPECT(types["Hash384"].asUInt() == 22);
|
||||
BEAST_EXPECT(types["Hash512"].asUInt() == 23);
|
||||
BEAST_EXPECT(types.isMember("Hash128") && types["Hash128"].asUInt() == 4);
|
||||
BEAST_EXPECT(types.isMember("Hash160") && types["Hash160"].asUInt() == 17);
|
||||
BEAST_EXPECT(types.isMember("Hash192") && types["Hash192"].asUInt() == 21);
|
||||
BEAST_EXPECT(types.isMember("Hash256") && types["Hash256"].asUInt() == 5);
|
||||
BEAST_EXPECT(types.isMember("Hash384") && types["Hash384"].asUInt() == 22);
|
||||
BEAST_EXPECT(types.isMember("Hash512") && types["Hash512"].asUInt() == 23);
|
||||
}
|
||||
|
||||
BEAST_EXPECT(
|
||||
result[jss::result][jss::LEDGER_ENTRY_TYPES]["AccountRoot"].asUInt() == 97);
|
||||
BEAST_EXPECT(
|
||||
result[jss::result][jss::TRANSACTION_RESULTS]["tecDIR_FULL"].asUInt() == 121);
|
||||
BEAST_EXPECT(result[jss::result][jss::TRANSACTION_TYPES]["Payment"].asUInt() == 0);
|
||||
BEAST_EXPECT(result[jss::result][jss::TYPES]["AccountID"].asUInt() == 8);
|
||||
|
||||
// test the properties of the LEDGER_ENTRY_FLAGS section
|
||||
{
|
||||
BEAST_EXPECT(result[jss::result].isMember(jss::LEDGER_ENTRY_FLAGS));
|
||||
|
||||
@@ -161,11 +161,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)
|
||||
{
|
||||
@@ -226,17 +222,7 @@ 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 const next = std::ranges::min_element(
|
||||
auto next = std::ranges::min_element(
|
||||
sites_, [](Site const& a, Site const& b) { return a.nextRefresh < b.nextRefresh; });
|
||||
|
||||
if (next != sites_.end())
|
||||
@@ -347,7 +333,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& site = sites_[siteIdx];
|
||||
auto const& site = sites_[siteIdx];
|
||||
if (site.activeResource)
|
||||
{
|
||||
JLOG(j_.warn()) << "Request for " << site.activeResource->uri << " took too long";
|
||||
@@ -355,9 +341,6 @@ 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_};
|
||||
|
||||
@@ -149,18 +149,6 @@ ServerDefinitions::ServerDefinitions() : defs_{Json::objectValue}
|
||||
defs_[jss::FIELDS] = Json::arrayValue;
|
||||
|
||||
uint32_t i = 0;
|
||||
{
|
||||
Json::Value a = Json::arrayValue;
|
||||
a[0U] = "Generic";
|
||||
Json::Value v = Json::objectValue;
|
||||
v[jss::nth] = 0;
|
||||
v[jss::isVLEncoded] = false;
|
||||
v[jss::isSerialized] = false;
|
||||
v[jss::isSigningField] = false;
|
||||
v[jss::type] = "Unknown";
|
||||
a[1U] = v;
|
||||
defs_[jss::FIELDS][i++] = a;
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value a = Json::arrayValue;
|
||||
@@ -227,21 +215,25 @@ ServerDefinitions::ServerDefinitions() : defs_{Json::objectValue}
|
||||
defs_[jss::FIELDS][i++] = a;
|
||||
}
|
||||
|
||||
for (auto const& [code, field] : xrpl::SField::getKnownCodeToField())
|
||||
// copy into a sorted map to ensure deterministic output order (sorted by fieldCode)
|
||||
static std::map<int, SField const*> const sortedFields(
|
||||
xrpl::SField::getKnownCodeToField().begin(), xrpl::SField::getKnownCodeToField().end());
|
||||
|
||||
for (auto const& [code, field] : sortedFields)
|
||||
{
|
||||
if (field->fieldName.empty())
|
||||
continue;
|
||||
|
||||
Json::Value innerObj = Json::objectValue;
|
||||
|
||||
uint32_t type = field->fieldType;
|
||||
int32_t const type = field->fieldType;
|
||||
|
||||
innerObj[jss::nth] = field->fieldValue;
|
||||
|
||||
// whether the field is variable-length encoded this means that the length is included
|
||||
// before the content
|
||||
innerObj[jss::isVLEncoded] =
|
||||
(type == 7U /* Blob */ || type == 8U /* AccountID */ || type == 19U /* Vector256 */);
|
||||
(type == STI_VL || type == STI_ACCOUNT || type == STI_VECTOR256);
|
||||
|
||||
// whether the field is included in serialization
|
||||
innerObj[jss::isSerialized] =
|
||||
|
||||
Reference in New Issue
Block a user