Skip to content

Commit f0b5988

Browse files
committed
WIP - spike on hot archive adaptation
1 parent bbd2113 commit f0b5988

11 files changed

+951
-514
lines changed

src/ledger/LedgerManagerImpl.cpp

+57-4
Original file line numberDiff line numberDiff line change
@@ -1617,7 +1617,7 @@ LedgerManagerImpl::collectEntries(AppConnector& app, AbstractLedgerTxn& ltx,
16171617
return entryMap;
16181618
}
16191619

1620-
void
1620+
RestoredKeys
16211621
LedgerManagerImpl::applyThread(AppConnector& app, ThreadEntryMap& entryMap,
16221622
Thread const& thread, Config const& config,
16231623
SorobanNetworkConfig const& sorobanConfig,
@@ -1629,6 +1629,7 @@ LedgerManagerImpl::applyThread(AppConnector& app, ThreadEntryMap& entryMap,
16291629
// we accumulate the RO extensions until we need to apply them.
16301630
UnorderedMap<LedgerKey, uint32_t> readOnlyTtlExtensions;
16311631

1632+
RestoredKeys threadRestoredKeys;
16321633
for (auto const& txBundle : thread)
16331634
{
16341635
releaseAssertOrThrow(txBundle.getResPayload());
@@ -1676,7 +1677,7 @@ LedgerManagerImpl::applyThread(AppConnector& app, ThreadEntryMap& entryMap,
16761677
txBundle.getResPayload(), sorobanMetrics, txSubSeed,
16771678
txBundle.getEffects());
16781679

1679-
if (res.mSuccess)
1680+
if (res.getSuccess())
16801681
{
16811682
UnorderedMap<LedgerKey, bool> isReadOnlyTTLMap;
16821683
for (auto const& ro :
@@ -1699,7 +1700,7 @@ LedgerManagerImpl::applyThread(AppConnector& app, ThreadEntryMap& entryMap,
16991700
}
17001701

17011702
// now apply the entry changes to entryMap
1702-
for (auto const& entry : res.mModifiedEntryMap)
1703+
for (auto const& entry : res.getModifiedEntryMap())
17031704
{
17041705
auto const& lk = entry.first;
17051706
auto const& updatedLe = entry.second;
@@ -1738,11 +1739,24 @@ LedgerManagerImpl::applyThread(AppConnector& app, ThreadEntryMap& entryMap,
17381739
it->second = {updatedLe, true};
17391740
}
17401741
}
1742+
1743+
for (auto const& key : res.getRestoredKeys().hotArchive)
1744+
{
1745+
auto [_, inserted] = threadRestoredKeys.hotArchive.emplace(key);
1746+
releaseAssertOrThrow(inserted);
1747+
}
1748+
for (auto const& key : res.getRestoredKeys().liveBucketList)
1749+
{
1750+
auto [_, inserted] =
1751+
threadRestoredKeys.liveBucketList.emplace(key);
1752+
releaseAssertOrThrow(inserted);
1753+
}
17411754
}
17421755
else
17431756
{
17441757
releaseAssertOrThrow(!txBundle.getResPayload()->isSuccess());
17451758
}
1759+
return threadRestoredKeys;
17461760
}
17471761

17481762
for (auto kvp : readOnlyTtlExtensions)
@@ -1798,6 +1812,8 @@ LedgerManagerImpl::applySorobanStage(AppConnector& app, AbstractLedgerTxn& ltx,
17981812
entryMapsByThread.emplace_back(collectEntries(app, ltx, thread));
17991813
}
18001814

1815+
std::vector<std::future<RestoredKeys>> threadRestoredKeyFutures;
1816+
18011817
auto ledgerInfo = getParallelLedgerInfo(app, ltx);
18021818
std::vector<std::thread> threads;
18031819
for (size_t i = 0; i < stage.size(); ++i)
@@ -1806,19 +1822,51 @@ LedgerManagerImpl::applySorobanStage(AppConnector& app, AbstractLedgerTxn& ltx,
18061822

18071823
auto const& thread = stage.at(i);
18081824

1809-
threads.emplace_back(&LedgerManagerImpl::applyThread, this,
1825+
/* threads.emplace_back(&LedgerManagerImpl::applyThread, this,
18101826
std::ref(app), std::ref(entryMapByThread),
18111827
std::ref(thread), config, sorobanConfig,
18121828
std::ref(ledgerInfo), sorobanBasePrngSeed,
18131829
std::ref(sorobanMetrics));
1830+
*/
1831+
threadRestoredKeyFutures.emplace_back(std::async(
1832+
std::launch::async, &LedgerManagerImpl::applyThread, this,
1833+
std::ref(app), std::ref(entryMapByThread), std::ref(thread), config,
1834+
sorobanConfig, std::ref(ledgerInfo), sorobanBasePrngSeed,
1835+
std::ref(sorobanMetrics)));
18141836
}
18151837

18161838
for (auto& thread : threads)
18171839
{
18181840
thread.join();
18191841
}
18201842

1843+
std::vector<RestoredKeys> threadRestoredKeys;
1844+
for (auto& restoredKeysFutures : threadRestoredKeyFutures)
1845+
{
1846+
threadRestoredKeys.emplace_back(restoredKeysFutures.get());
1847+
}
1848+
18211849
LedgerTxn ltxInner(ltx);
1850+
for (auto const& restoredKeys : threadRestoredKeys)
1851+
{
1852+
// We filter out the TTL keys here because LedgerTxn will add the ttl
1853+
// key
1854+
for (auto const& key : restoredKeys.hotArchive)
1855+
{
1856+
if (key.type() != TTL)
1857+
{
1858+
ltxInner.addRestoredFromHotArchiveKey(key);
1859+
}
1860+
}
1861+
for (auto const& key : restoredKeys.liveBucketList)
1862+
{
1863+
if (key.type() != TTL)
1864+
{
1865+
ltxInner.addRestoredFromLiveBucketListKey(key);
1866+
}
1867+
}
1868+
}
1869+
18221870
for (auto const& thread : stage)
18231871
{
18241872
for (auto const& txBundle : thread)
@@ -1886,6 +1934,11 @@ LedgerManagerImpl::applySorobanStage(AppConnector& app, AbstractLedgerTxn& ltx,
18861934
auto newLiveUntil =
18871935
updatedEntry.data.ttl().liveUntilLedgerSeq;
18881936

1937+
// The only scenario where we accept a reduction in TTL
1938+
// is one where an entry was deleted, and then
1939+
// recreated. This can only happen if the key was in the
1940+
// readWrite set, so if it's not then this is just a
1941+
// parallel readOnly bump that we can ignore here.
18891942
if (newLiveUntil <= currLiveUntil &&
18901943
isInReadWriteSet.count(entry.first) == 0)
18911944
{

src/ledger/LedgerManagerImpl.h

+7-6
Original file line numberDiff line numberDiff line change
@@ -122,12 +122,13 @@ class LedgerManagerImpl : public LedgerManager
122122
ThreadEntryMap collectEntries(AppConnector& app, AbstractLedgerTxn& ltx,
123123
Thread const& txs);
124124

125-
void applyThread(AppConnector& app, ThreadEntryMap& entryMapByCluster,
126-
Thread const& thread, Config const& config,
127-
SorobanNetworkConfig const& sorobanConfig,
128-
ParallelLedgerInfo const& ledgerInfo,
129-
Hash const& sorobanBasePrngSeed,
130-
SorobanMetrics& sorobanMetrics);
125+
RestoredKeys applyThread(AppConnector& app,
126+
ThreadEntryMap& entryMapByCluster,
127+
Thread const& thread, Config const& config,
128+
SorobanNetworkConfig const& sorobanConfig,
129+
ParallelLedgerInfo const& ledgerInfo,
130+
Hash const& sorobanBasePrngSeed,
131+
SorobanMetrics& sorobanMetrics);
131132

132133
void applySorobanStage(AppConnector& app, AbstractLedgerTxn& ltx,
133134
ApplyStage const& stage,

src/ledger/LedgerTxn.cpp

+62
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,68 @@ LedgerTxn::Impl::erase(InternalLedgerKey const& key)
825825
}
826826
}
827827

828+
void
829+
LedgerTxn::addRestoredFromHotArchiveKey(LedgerKey const& key)
830+
{
831+
getImpl()->addRestoredFromHotArchiveKey(key);
832+
}
833+
834+
void
835+
LedgerTxn::Impl::addRestoredFromHotArchiveKey(LedgerKey const& key)
836+
{
837+
throwIfSealed();
838+
throwIfChild();
839+
840+
if (!isPersistentEntry(key))
841+
{
842+
throw std::runtime_error("Key type not supported in Hot Archive");
843+
}
844+
845+
auto ttlKey = getTTLKey(key);
846+
847+
// Mark the keys as restored
848+
auto addKey = [this](LedgerKey const& key) {
849+
auto [_, inserted] = mRestoredKeys.hotArchive.insert(key);
850+
if (!inserted)
851+
{
852+
throw std::runtime_error("Key already removed from hot archive");
853+
}
854+
};
855+
addKey(key);
856+
addKey(ttlKey);
857+
}
858+
859+
void
860+
LedgerTxn::addRestoredFromLiveBucketListKey(LedgerKey const& key)
861+
{
862+
getImpl()->addRestoredFromLiveBucketListKey(key);
863+
}
864+
865+
void
866+
LedgerTxn::Impl::addRestoredFromLiveBucketListKey(LedgerKey const& key)
867+
{
868+
throwIfSealed();
869+
throwIfChild();
870+
871+
if (!isPersistentEntry(key))
872+
{
873+
throw std::runtime_error("Key type not supported for restoration");
874+
}
875+
876+
auto ttlKey = getTTLKey(key);
877+
878+
auto addKey = [this](LedgerKey const& key) {
879+
auto [_, inserted] = mRestoredKeys.liveBucketList.insert(key);
880+
if (!inserted)
881+
{
882+
throw std::runtime_error(
883+
"Key already restored from Live BucketList");
884+
}
885+
};
886+
addKey(key);
887+
addKey(ttlKey);
888+
}
889+
828890
void
829891
LedgerTxn::restoreFromHotArchive(LedgerEntry const& entry, uint32_t ttl)
830892
{

src/ledger/LedgerTxn.h

+4
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,8 @@ class AbstractLedgerTxn : public AbstractLedgerTxnParent
595595
uint32_t ttl) = 0;
596596
virtual void restoreFromLiveBucketList(LedgerKey const& key,
597597
uint32_t ttl) = 0;
598+
virtual void addRestoredFromHotArchiveKey(LedgerKey const& key) = 0;
599+
virtual void addRestoredFromLiveBucketListKey(LedgerKey const& key) = 0;
598600
virtual LedgerTxnEntry load(InternalLedgerKey const& key) = 0;
599601
virtual ConstLedgerTxnEntry
600602
loadWithoutRecord(InternalLedgerKey const& key) = 0;
@@ -742,6 +744,8 @@ class LedgerTxn : public AbstractLedgerTxn
742744
void erase(InternalLedgerKey const& key) override;
743745
void restoreFromHotArchive(LedgerEntry const& entry, uint32_t ttl) override;
744746
void restoreFromLiveBucketList(LedgerKey const& key, uint32_t ttl) override;
747+
void addRestoredFromHotArchiveKey(LedgerKey const& key) override;
748+
void addRestoredFromLiveBucketListKey(LedgerKey const& key) override;
745749

746750
UnorderedMap<LedgerKey, LedgerEntry> getAllOffers() override;
747751

src/ledger/LedgerTxnImpl.h

+12
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,18 @@ class LedgerTxn::Impl
361361
// - the entry cache may be, but is not guaranteed to be, cleared.
362362
void erase(InternalLedgerKey const& key);
363363

364+
// addRestoredFromHotArchiveKey has the basic exception safety guarantee. If
365+
// it throws an exception, then
366+
// - the prepared statement cache may be, but is not guaranteed to be,
367+
// modified
368+
void addRestoredFromHotArchiveKey(LedgerKey const& key);
369+
370+
// addRestoredFromLiveBucketListKey has the basic exception safety
371+
// guarantee. If it throws an exception, then
372+
// - the prepared statement cache may be, but is not guaranteed to be,
373+
// modified
374+
void addRestoredFromLiveBucketListKey(LedgerKey const& key);
375+
364376
// restoreFromHotArchive has the basic exception safety guarantee. If it
365377
// throws an exception, then
366378
// - the prepared statement cache may be, but is not guaranteed to be,

src/ledger/test/LedgerCloseMetaStreamTests.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -421,8 +421,8 @@ TEST_CASE_VERSIONS("meta stream contains reasonable meta", "[ledgerclosemeta]")
421421
.bucketListWindowSamplePeriod = 1;
422422
});
423423

424-
// Modify Soroban network config closes a ledger
425-
++targetSeq;
424+
// Modify Soroban network config closes 2 ledgers
425+
targetSeq += 2;
426426
}
427427

428428
auto root = TestAccount::createRoot(*app);

0 commit comments

Comments
 (0)