Skip to content

Commit 8df0219

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

9 files changed

+123
-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

+6-1
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,12 @@ LiveBucketIndex::getContractEntryRange() const
188188
{
189189
if (mDiskIndex)
190190
{
191-
// Get the smallest and largest possible contract entry keys
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
195+
// CONTRACT_CODE. and one for TTL. Get the smallest and largest possible
196+
// contract entry keys
192197
LedgerKey upperBound(TTL /*9*/);
193198
upperBound.ttl().keyHash.fill(std::numeric_limits<uint8_t>::max());
194199

src/catchup/PopulateLedgerCacheWork.cpp

+46-29
Original file line numberDiff line numberDiff line change
@@ -69,45 +69,62 @@ 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;
94+
++iter)
95+
{
96+
if (iter.pos() < lowerBound)
97+
{
98+
iter.seek(lowerBound);
99+
}
100+
BucketEntry const& entry = *iter;
101+
if (entry.type() == LIVEENTRY || entry.type() == INITENTRY)
102+
{
103+
auto const& e = entry.liveEntry();
104+
auto const& k = LedgerEntryKey(e);
105+
if (!cache->supportedKeyType(k.type()))
88106
{
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-
}
107+
continue;
97108
}
98-
else if (entry.type() == DEADENTRY)
109+
// If the key is not in the dead keys set and not already in the
110+
// cache, add it.
111+
if (mDeadKeys.find(k) == mDeadKeys.end() && !cache->getEntry(k))
99112
{
100-
if (!cache->getEntry(entry.deadEntry()))
101-
{
102-
mDeadKeys.insert(entry.deadEntry());
103-
}
113+
cache->addEntry(e);
104114
}
105-
else
115+
}
116+
else if (entry.type() == DEADENTRY)
117+
{
118+
if (!cache->getEntry(entry.deadEntry()))
106119
{
107-
releaseAssert(false);
108-
continue;
120+
mDeadKeys.insert(entry.deadEntry());
109121
}
110122
}
123+
else
124+
{
125+
releaseAssert(false);
126+
continue;
127+
}
111128
}
112129
return advance();
113130
}

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

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

3333
class LedgerStateCache
3434
{
35+
enum class Mode
36+
{
37+
ALL_ENTRIES,
38+
SOROBAN_ONLY
39+
};
40+
3541
private:
42+
Mode mMode;
3643
std::unordered_set<LedgerEntry, LedgerEntryHash, LedgerEntryEqual> mState;
3744
mutable std::shared_mutex mMutex;
3845

@@ -51,15 +58,17 @@ class LedgerStateCache
5158
void addEntry(LedgerEntry const& entry);
5259

5360
public:
54-
LedgerStateCache() = default;
61+
LedgerStateCache(Mode mode) : mMode(mode)
62+
{
63+
}
5564

5665
// Read an entry from the cache
5766
// Acquires a shared lock on the cache.
5867
std::optional<LedgerEntry> getEntry(LedgerKey const& key) const;
5968

6069
size_t size() const;
61-
// TODO support other types
62-
static bool supportedKeyType(LedgerEntryType type);
70+
Mode getMode() const;
71+
bool supportedKeyType(LedgerEntryType type) const;
6372

6473
// TODO Find a way to limit access to just the methods we need
6574
// 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

+4-2
Original file line numberDiff line numberDiff line change
@@ -202,9 +202,11 @@ 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+
// Whether to use an in-memory ledger state cache for Soroban state.
209+
bool USE_SOROBAN_LEDGER_STATE_CACHE;
208210

209211
// Interval between automatic maintenance executions
210212
std::chrono::seconds AUTOMATIC_MAINTENANCE_PERIOD;

src/util/types.cpp

+26-1
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,30 @@ 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 =
101+
k.liquidityPool().liquidityPoolID;
102+
break;
82103
case CONTRACT_DATA:
83104
e.data.contractData().contract = k.contractData().contract;
84105
e.data.contractData().key = k.contractData().key;
@@ -87,6 +108,10 @@ KeyToDummyLedgerEntry(LedgerKey const& k)
87108
case CONTRACT_CODE:
88109
e.data.contractCode().hash = k.contractCode().hash;
89110
break;
111+
case CONFIG_SETTING:
112+
e.data.configSetting().configSettingID(
113+
k.configSetting().configSettingID);
114+
break;
90115
case TTL:
91116
e.data.ttl().keyHash = k.ttl().keyHash;
92117
break;

0 commit comments

Comments
 (0)