Skip to content

Commit

Permalink
non-existent entries should not be metered (#4428)
Browse files Browse the repository at this point in the history
# Description

Resolves stellar/stellar-core-internal#282

Remove optimization that checks whether there is quota remaining for a
ledger key before attempting to load the entry from the bucketlist. This
ensures that non-existent entries are not metered and result in a
`nullptr` entry in the cache. This will prevent point loads when writing
newly created entries post-contract invocation.
  • Loading branch information
SirTyson authored Aug 21, 2024
2 parents 4ede196 + 687038b commit 0e1cf94
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 18 deletions.
18 changes: 0 additions & 18 deletions src/bucket/BucketSnapshot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,24 +101,6 @@ BucketSnapshot::loadKeysWithLimits(std::set<LedgerKey, LedgerEntryIdCmp>& keys,
auto indexIter = index.begin();
while (currKeyIt != keys.end() && indexIter != index.end())
{
if (lkMeter)
{
auto keySize = xdr::xdr_size(*currKeyIt);
if (!lkMeter->canLoad(*currKeyIt, keySize))
{
// If the transactions containing this key have a remaining
// quota less than the size of the key, we cannot load the
// entry, as xdr_size(key) <= xdr_size(entry). Here we consume
// keySize bytes from the quotas of transactions containing the
// key so that they will have zero remaining quota and
// additional entries belonging to only those same transactions
// will not be loaded even if they would fit in the remaining
// quota before this update.
lkMeter->updateReadQuotasForKey(*currKeyIt, keySize);
currKeyIt = keys.erase(currKeyIt);
continue;
}
}
auto [offOp, newIndexIter] = index.scan(indexIter, *currKeyIt);
indexIter = newIndexIter;
if (offOp)
Expand Down
13 changes: 13 additions & 0 deletions src/ledger/test/LedgerTxnTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2975,6 +2975,19 @@ TEST_CASE("LedgerTxnRoot prefetch soroban entries", "[ledgertxn]")
expectedSuccessKeys.emplace(LedgerEntryKey(classicEntry));
checkPrefetch(expectedSuccessKeys);
}
SECTION("non existent entries should not affect quota")
{
// Prefetch an entry which has not been added to the database.
auto nonExistentEntry =
LedgerTestUtils::generateValidLedgerEntryOfType(CONTRACT_DATA);
// Both should succeed, as the non-existent entry is not metered and
// should result in a null entry in the cache.
addTxn(false /* not enough */, {contractDataEntry, nonExistentEntry});
std::set<LedgerKey> expectedSuccessKeys{
LedgerEntryKey(contractDataEntry),
LedgerEntryKey(nonExistentEntry)};
checkPrefetch(expectedSuccessKeys);
}
}

TEST_CASE("LedgerKeyMeter tests")
Expand Down

0 comments on commit 0e1cf94

Please sign in to comment.