Skip to content

Commit 7180ed7

Browse files
committed
Enforce pre and post load invariants for LedgerTxnRoot::Impl::getNewestVersion for both BucketsDB and SQL path.
1 parent 5633088 commit 7180ed7

File tree

1 file changed

+48
-2
lines changed

1 file changed

+48
-2
lines changed

src/ledger/LedgerTxn.cpp

+48-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,44 @@
2626

2727
namespace stellar
2828
{
29-
29+
namespace
30+
{
31+
void
32+
enforceBucketListPreLoadInvariants(LedgerKey const& key, uint32_t ledgerVersion)
33+
{
34+
if (key.type() == TRUSTLINE)
35+
{
36+
validateTrustLineKey(ledgerVersion, key);
37+
}
38+
// Note: There are additional invariants that are enforced when
39+
// loading offers by account and asset. This type of query is only
40+
// performed on the SQL backend, so we do not enforce those invariants here.
41+
// See LedgerTxnOfferSQL.cpp::loadOffersByAccountAndAsset.
42+
}
43+
void
44+
enforceBucketListPostLoadInvariants(
45+
LedgerKey const& key, std::shared_ptr<LedgerEntry const> const& entry)
46+
{
47+
if (!entry)
48+
{
49+
return;
50+
}
51+
releaseAssert(key.type() == entry->data.type());
52+
if (key.type() == ACCOUNT)
53+
{
54+
// LedgerTxnRoot::loadAccount SQL enforces
55+
// invariants post-load.
56+
// It decodes the result of the query and ensures
57+
// the account signers are sorted in ascending order.
58+
releaseAssert(
59+
std::adjacent_find(entry->data.account().signers.begin(),
60+
entry->data.account().signers.end(),
61+
[](Signer const& lhs, Signer const& rhs) {
62+
return !(lhs.key < rhs.key);
63+
}) == entry->data.account().signers.end());
64+
}
65+
};
66+
}
3067
LedgerEntryPtr
3168
LedgerEntryPtr::Init(std::shared_ptr<InternalLedgerEntry> const& lePtr)
3269
{
@@ -2985,10 +3022,16 @@ LedgerTxnRoot::Impl::prefetch(UnorderedSet<LedgerKey> const& keys)
29853022
for (auto const& key : keys)
29863023
{
29873024
insertIfNotLoaded(keysToSearch, key);
3025+
enforceBucketListPreLoadInvariants(key, mHeader->ledgerVersion);
29883026
}
29893027

29903028
auto blLoad = mApp.getBucketManager().loadKeys(keysToSearch);
2991-
cacheResult(populateLoadedEntries(keysToSearch, blLoad));
3029+
auto loadedEntries = populateLoadedEntries(keysToSearch, blLoad);
3030+
for (auto const& entry : loadedEntries)
3031+
{
3032+
enforceBucketListPostLoadInvariants(entry.first, entry.second);
3033+
}
3034+
cacheResult(loadedEntries);
29923035
}
29933036
else
29943037
{
@@ -3620,11 +3663,14 @@ LedgerTxnRoot::Impl::getNewestVersion(InternalLedgerKey const& gkey) const
36203663
}
36213664

36223665
std::shared_ptr<LedgerEntry const> entry;
3666+
36233667
try
36243668
{
36253669
if (mApp.getConfig().isUsingBucketListDB() && key.type() != OFFER)
36263670
{
3671+
enforceBucketListPreLoadInvariants(key, mHeader->ledgerVersion);
36273672
entry = mApp.getBucketManager().getLedgerEntry(key);
3673+
enforceBucketListPostLoadInvariants(key, entry);
36283674
}
36293675
else
36303676
{

0 commit comments

Comments
 (0)