Skip to content

Commit c1f11fd

Browse files
committed
Add non-soroban testonly ledgerstateconfig mode
1 parent 294e77b commit c1f11fd

9 files changed

+116
-48
lines changed

src/bucket/InMemoryIndex.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,9 @@ InMemoryIndex::InMemoryIndex(BucketManager const& bm,
162162
mOfferRange = std::nullopt;
163163
}
164164

165+
// TODO These bounds include config setting entries,
166+
// which are not contract entries.
167+
// Possibly consider adding more granular ranges for each contract type.
165168
if (firstContractEntry)
166169
{
167170
if (lastContractEntry)

src/bucket/LiveBucketIndex.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,11 @@ LiveBucketIndex::getContractEntryRange() const
188188
{
189189
if (mDiskIndex)
190190
{
191+
// TODO These bounds include config setting entries,
192+
// which are not contract entries.
193+
// Possibly consider adding a function to get the range of
194+
// each contract type individually, or one for CONTRACT_DATA and CONTRACT_CODE.
195+
// and one for TTL.
191196
// Get the smallest and largest possible contract entry keys
192197
LedgerKey upperBound(TTL /*9*/);
193198
upperBound.ttl().keyHash.fill(std::numeric_limits<uint8_t>::max());

src/catchup/PopulateLedgerCacheWork.cpp

+45-29
Original file line numberDiff line numberDiff line change
@@ -69,45 +69,61 @@ PopulateLedgerCacheWork::doWork()
6969
mBucketToProcessIndex);
7070
return advance();
7171
}
72-
73-
auto contractEntryRange = bucket->getContractEntryRange();
7472
auto ledgerStateCache = mApp.getLedgerManager().getLedgerStateCache();
75-
if (ledgerStateCache && contractEntryRange)
73+
if (!ledgerStateCache)
7674
{
77-
auto cache = ledgerStateCache.value();
78-
auto [lowerBound, upperBound] = *contractEntryRange;
79-
for (LiveBucketInputIterator iter(bucket);
80-
iter && iter.pos() < upperBound; ++iter)
75+
CLOG_DEBUG(Ledger, "LedgerStateCache is not enabled");
76+
return State::WORK_FAILURE;
77+
}
78+
79+
auto cache = ledgerStateCache.value();
80+
std::streamoff upperBound = 0;
81+
std::streamoff lowerBound = std::numeric_limits<std::streamoff>::max();
82+
if (cache->getMode() == LedgerStateCache::Mode::SOROBAN_ONLY)
83+
{
84+
// Update the bounds to only iterate over soroban state.
85+
auto contractEntryRange = bucket->getContractEntryRange();
86+
if (contractEntryRange)
8187
{
82-
if (iter.pos() < lowerBound)
83-
{
84-
iter.seek(lowerBound);
85-
}
86-
BucketEntry const& entry = *iter;
87-
if (entry.type() == LIVEENTRY || entry.type() == INITENTRY)
88+
lowerBound = std::get<0>(*contractEntryRange);
89+
upperBound = std::get<1>(*contractEntryRange);
90+
}
91+
}
92+
93+
for (LiveBucketInputIterator iter(bucket); iter && iter.pos() < upperBound; ++iter)
94+
{
95+
if (iter.pos() < lowerBound)
96+
{
97+
iter.seek(lowerBound);
98+
}
99+
BucketEntry const& entry = *iter;
100+
if (entry.type() == LIVEENTRY || entry.type() == INITENTRY)
101+
{
102+
auto const& e = entry.liveEntry();
103+
auto const& k = LedgerEntryKey(e);
104+
if (!cache->supportedKeyType(k.type()))
88105
{
89-
auto const& e = entry.liveEntry();
90-
auto const& k = LedgerEntryKey(e);
91-
// If the key is not in the dead keys set and not already in the
92-
// cache, add it.
93-
if (mDeadKeys.find(k) == mDeadKeys.end() && !cache->getEntry(k))
94-
{
95-
cache->addEntry(e);
96-
}
106+
continue;
97107
}
98-
else if (entry.type() == DEADENTRY)
108+
// If the key is not in the dead keys set and not already in the
109+
// cache, add it.
110+
if (mDeadKeys.find(k) == mDeadKeys.end() && !cache->getEntry(k))
99111
{
100-
if (!cache->getEntry(entry.deadEntry()))
101-
{
102-
mDeadKeys.insert(entry.deadEntry());
103-
}
112+
cache->addEntry(e);
104113
}
105-
else
114+
}
115+
else if (entry.type() == DEADENTRY)
116+
{
117+
if (!cache->getEntry(entry.deadEntry()))
106118
{
107-
releaseAssert(false);
108-
continue;
119+
mDeadKeys.insert(entry.deadEntry());
109120
}
110121
}
122+
else
123+
{
124+
releaseAssert(false);
125+
continue;
126+
}
111127
}
112128
return advance();
113129
}

src/ledger/LedgerManagerImpl.cpp

+11-5
Original file line numberDiff line numberDiff line change
@@ -158,14 +158,20 @@ LedgerManagerImpl::LedgerManagerImpl(Application& app)
158158
, mLastClose(mApp.getClock().now())
159159
, mCatchupDuration(
160160
app.getMetrics().NewTimer({"ledger", "catchup", "duration"}))
161+
, mLedgerStateCache{
161162
#ifdef BUILD_TESTS
162-
, mLedgerStateCache
163-
{
164-
app.getConfig().IN_MEMORY_SOROBAN_STATE_FOR_TESTING
165-
? std::make_shared<LedgerStateCache>()
163+
app.getConfig().USE_LEDGER_STATE_CACHE_FOR_TESTING
164+
? std::make_shared<LedgerStateCache>(LedgerStateCache::Mode::ALL_ENTRIES)
165+
: (app.getConfig().USE_SOROBAN_LEDGER_STATE_CACHE
166+
? std::make_shared<LedgerStateCache>(
167+
LedgerStateCache::Mode::SOROBAN_ONLY)
168+
: std::optional<std::shared_ptr<LedgerStateCache>>(std::nullopt))
169+
#else
170+
app.getConfig().USE_SOROBAN_LEDGER_STATE_CACHE
171+
? std::make_shared<LedgerStateCache>(LedgerStateCache::Mode::SOROBAN_ONLY)
166172
: std::optional<std::shared_ptr<LedgerStateCache>>(std::nullopt)
167-
}
168173
#endif
174+
}
169175
, mState(LM_BOOTING_STATE)
170176
{
171177
setupLedgerCloseMetaStream();

src/ledger/LedgerStateCache.cpp

+12-5
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ LedgerEntryHash::operator()(LedgerEntry const& entry) const
2222
std::optional<LedgerEntry>
2323
LedgerStateCache::getEntry(LedgerKey const& key) const
2424
{
25-
// TODO support other types, for test mode.
2625
if (!supportedKeyType(key.type()))
2726
{
2827
return std::nullopt;
@@ -104,12 +103,20 @@ LedgerStateCache::size() const
104103
return mState.size();
105104
}
106105

106+
LedgerStateCache::Mode
107+
LedgerStateCache::getMode() const
108+
{
109+
return mMode;
110+
}
111+
107112
bool
108-
LedgerStateCache::supportedKeyType(LedgerEntryType type)
113+
LedgerStateCache::supportedKeyType(LedgerEntryType type) const
109114
{
110-
// TODO support other types
111-
// possibly do something more sophisticated here
112-
return type == CONTRACT_DATA || type == CONTRACT_CODE || type == TTL;
115+
if (mMode == Mode::SOROBAN_ONLY)
116+
{
117+
return type == CONTRACT_DATA || type == CONTRACT_CODE || type == TTL;
118+
}
119+
return true;
113120
}
114121

115122
}

src/ledger/LedgerStateCache.h

+8-3
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,12 @@ class PopulateLedgerCacheWork;
3232

3333
class LedgerStateCache
3434
{
35+
enum class Mode {
36+
ALL_ENTRIES,
37+
SOROBAN_ONLY
38+
};
3539
private:
40+
Mode mMode;
3641
std::unordered_set<LedgerEntry, LedgerEntryHash, LedgerEntryEqual> mState;
3742
mutable std::shared_mutex mMutex;
3843

@@ -51,15 +56,15 @@ class LedgerStateCache
5156
void addEntry(LedgerEntry const& entry);
5257

5358
public:
54-
LedgerStateCache() = default;
59+
LedgerStateCache(Mode mode) : mMode(mode) {}
5560

5661
// Read an entry from the cache
5762
// Acquires a shared lock on the cache.
5863
std::optional<LedgerEntry> getEntry(LedgerKey const& key) const;
5964

6065
size_t size() const;
61-
// TODO support other types
62-
static bool supportedKeyType(LedgerEntryType type);
66+
Mode getMode() const;
67+
bool supportedKeyType(LedgerEntryType type) const;
6368

6469
// TODO Find a way to limit access to just the methods we need
6570
// PopulateLedgerCacheWork::doWork() / addEntry() and

src/main/Config.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ static const std::unordered_set<std::string> TESTING_ONLY_OPTIONS = {
6666
"ARTIFICIALLY_SLEEP_MAIN_THREAD_FOR_TESTING",
6767
"ARTIFICIALLY_SKIP_CONNECTION_ADJUSTMENT_FOR_TESTING",
6868
"ARTIFICIALLY_DELAY_LEDGER_CLOSE_FOR_TESTING",
69-
"IN_MEMORY_SOROBAN_STATE_FOR_TESTING"};
69+
"USE_LEDGER_STATE_CACHE_FOR_TESTING"};
7070

7171
// Options that should only be used for testing
7272
static const std::unordered_set<std::string> TESTING_SUGGESTED_OPTIONS = {
@@ -283,8 +283,9 @@ Config::Config() : NODE_SEED(SecretKey::random())
283283
ENTRY_CACHE_SIZE = 100000;
284284
PREFETCH_BATCH_SIZE = 1000;
285285
#ifdef BUILD_TESTS
286-
IN_MEMORY_SOROBAN_STATE_FOR_TESTING = true;
286+
USE_LEDGER_STATE_CACHE_FOR_TESTING = true;
287287
#endif
288+
USE_SOROBAN_LEDGER_STATE_CACHE = true;
288289

289290
HISTOGRAM_WINDOW_SIZE = std::chrono::seconds(30);
290291

src/main/Config.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -202,10 +202,12 @@ class Config : public std::enable_shared_from_this<Config>
202202
// successful transactions.
203203
bool CATCHUP_SKIP_KNOWN_RESULTS_FOR_TESTING;
204204

205-
// Whether to use an in-memory ledger state cache for Soroban state.
206-
bool IN_MEMORY_SOROBAN_STATE_FOR_TESTING;
205+
// Whether to use an in-memory ledger state cache for testing.
206+
bool USE_LEDGER_STATE_CACHE_FOR_TESTING;
207207
#endif // BUILD_TESTS
208-
208+
// Whether to use an in-memory ledger state cache for Soroban state.
209+
bool USE_SOROBAN_LEDGER_STATE_CACHE;
210+
209211
// Interval between automatic maintenance executions
210212
std::chrono::seconds AUTOMATIC_MAINTENANCE_PERIOD;
211213

src/util/types.cpp

+24-1
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,29 @@ KeyToDummyLedgerEntry(LedgerKey const& k)
7676
{
7777
LedgerEntry e;
7878
e.data.type(k.type());
79-
// TODO support other types
8079
switch (k.type())
8180
{
81+
case ACCOUNT:
82+
e.data.account().accountID = k.account().accountID;
83+
break;
84+
case TRUSTLINE:
85+
e.data.trustLine().accountID = k.trustLine().accountID;
86+
e.data.trustLine().asset = k.trustLine().asset;
87+
break;
88+
case OFFER:
89+
e.data.offer().sellerID = k.offer().sellerID;
90+
e.data.offer().offerID = k.offer().offerID;
91+
break;
92+
case DATA:
93+
e.data.data().accountID = k.data().accountID;
94+
e.data.data().dataName = k.data().dataName;
95+
break;
96+
case CLAIMABLE_BALANCE:
97+
e.data.claimableBalance().balanceID = k.claimableBalance().balanceID;
98+
break;
99+
case LIQUIDITY_POOL:
100+
e.data.liquidityPool().liquidityPoolID = k.liquidityPool().liquidityPoolID;
101+
break;
82102
case CONTRACT_DATA:
83103
e.data.contractData().contract = k.contractData().contract;
84104
e.data.contractData().key = k.contractData().key;
@@ -87,6 +107,9 @@ KeyToDummyLedgerEntry(LedgerKey const& k)
87107
case CONTRACT_CODE:
88108
e.data.contractCode().hash = k.contractCode().hash;
89109
break;
110+
case CONFIG_SETTING:
111+
e.data.configSetting().configSettingID(k.configSetting().configSettingID);
112+
break;
90113
case TTL:
91114
e.data.ttl().keyHash = k.ttl().keyHash;
92115
break;

0 commit comments

Comments
 (0)