20
20
#include " history/HistoryManager.h"
21
21
#include " ledger/FlushAndRotateMetaDebugWork.h"
22
22
#include " ledger/LedgerHeaderUtils.h"
23
+ #include " ledger/LedgerManager.h"
23
24
#include " ledger/LedgerTxn.h"
24
25
#include " ledger/LedgerTxnEntry.h"
25
26
#include " ledger/LedgerTxnHeader.h"
27
+ #include " ledger/SharedModuleCacheCompiler.h"
26
28
#include " main/Application.h"
27
29
#include " main/Config.h"
28
30
#include " main/ErrorMessages.h"
31
+ #include " rust/RustBridge.h"
29
32
#include " transactions/MutableTransactionResult.h"
30
33
#include " transactions/OperationFrame.h"
31
34
#include " transactions/TransactionFrameBase.h"
41
44
#include " util/XDRCereal.h"
42
45
#include " util/XDRStream.h"
43
46
#include " work/WorkScheduler.h"
47
+ #include " xdr/Stellar-ledger-entries.h"
44
48
#include " xdrpp/printer.h"
45
49
50
+ #include < cstdint>
46
51
#include < fmt/format.h>
47
52
48
53
#include " xdr/Stellar-ledger-entries.h"
@@ -125,6 +130,27 @@ LedgerManager::ledgerAbbrev(LedgerHeaderHistoryEntry const& he)
125
130
return ledgerAbbrev (he.header , he.hash );
126
131
}
127
132
133
+ static std::vector<uint32_t >
134
+ getModuleCacheProtocols ()
135
+ {
136
+ std::vector<uint32_t > ledgerVersions;
137
+ for (uint32_t i = (uint32_t )REUSABLE_SOROBAN_MODULE_CACHE_PROTOCOL_VERSION;
138
+ i <= Config::CURRENT_LEDGER_PROTOCOL_VERSION; i++)
139
+ {
140
+ ledgerVersions.push_back (i);
141
+ }
142
+ auto extra = getenv (" SOROBAN_TEST_EXTRA_PROTOCOL" );
143
+ if (extra)
144
+ {
145
+ uint32_t proto = static_cast <uint32_t >(atoi (extra));
146
+ if (proto > 0 )
147
+ {
148
+ ledgerVersions.push_back (proto);
149
+ }
150
+ }
151
+ return ledgerVersions;
152
+ }
153
+
128
154
LedgerManagerImpl::LedgerManagerImpl (Application& app)
129
155
: mApp (app)
130
156
, mSorobanMetrics (app.getMetrics())
@@ -157,6 +183,8 @@ LedgerManagerImpl::LedgerManagerImpl(Application& app)
157
183
, mCatchupDuration (
158
184
app.getMetrics().NewTimer({" ledger" , " catchup" , " duration" }))
159
185
, mState (LM_BOOTING_STATE)
186
+ , mModuleCache (::rust_bridge::new_module_cache())
187
+ , mModuleCacheProtocols (getModuleCacheProtocols())
160
188
161
189
{
162
190
setupLedgerCloseMetaStream ();
@@ -405,6 +433,9 @@ LedgerManagerImpl::loadLastKnownLedger(bool restoreBucketlist)
405
433
updateNetworkConfig (ltx);
406
434
mSorobanNetworkConfigReadOnly = mSorobanNetworkConfigForApply ;
407
435
}
436
+
437
+ // Prime module cache with ledger content.
438
+ compileAllContractsInLedger (latestLedgerHeader->ledgerVersion );
408
439
}
409
440
410
441
Database&
@@ -568,6 +599,30 @@ LedgerManagerImpl::getSorobanMetrics()
568
599
return mSorobanMetrics ;
569
600
}
570
601
602
+ rust_bridge::SorobanModuleCache&
603
+ LedgerManagerImpl::getModuleCache ()
604
+ {
605
+ return *mModuleCache ;
606
+ }
607
+
608
+ void
609
+ LedgerManagerImpl::compileAllContractsInLedger (uint32_t minLedgerVersion)
610
+ {
611
+ auto & moduleCache = getModuleCache ();
612
+ moduleCache.clear ();
613
+ std::vector<uint32_t > versions;
614
+ for (auto const & v : mModuleCacheProtocols )
615
+ {
616
+ if (v >= minLedgerVersion)
617
+ {
618
+ versions.push_back (v);
619
+ }
620
+ }
621
+ auto compiler = std::make_shared<SharedModuleCacheCompiler>(
622
+ mApp , moduleCache, versions);
623
+ compiler->run ();
624
+ }
625
+
571
626
void
572
627
LedgerManagerImpl::publishSorobanMetrics ()
573
628
{
@@ -1812,6 +1867,8 @@ LedgerManagerImpl::transferLedgerEntriesToBucketList(
1812
1867
ledgerCloseMeta->populateEvictedEntries (evictedState);
1813
1868
}
1814
1869
1870
+ evictFromModuleCache (lh.ledgerVersion , evictedState);
1871
+
1815
1872
ltxEvictions.commit ();
1816
1873
}
1817
1874
@@ -1822,6 +1879,8 @@ LedgerManagerImpl::transferLedgerEntriesToBucketList(
1822
1879
ltx.getAllEntries (initEntries, liveEntries, deadEntries);
1823
1880
if (blEnabled)
1824
1881
{
1882
+ addAnyContractsToModuleCache (lh.ledgerVersion , initEntries);
1883
+ addAnyContractsToModuleCache (lh.ledgerVersion , liveEntries);
1825
1884
mApp .getBucketManager ().addLiveBatch (mApp , lh, initEntries, liveEntries,
1826
1885
deadEntries);
1827
1886
}
@@ -1882,4 +1941,43 @@ LedgerManagerImpl::ledgerClosed(
1882
1941
1883
1942
return res;
1884
1943
}
1944
+
1945
+ void
1946
+ LedgerManagerImpl::evictFromModuleCache (uint32_t ledgerVersion,
1947
+ EvictedStateVectors const & evictedState)
1948
+ {
1949
+ ::rust::Vec<CxxBuf> contractCodeKeys;
1950
+ for (auto const & entry : evictedState.archivedEntries )
1951
+ {
1952
+ if (entry.data .type () == CONTRACT_CODE)
1953
+ {
1954
+ Hash const & hash = entry.data .contractCode ().hash ;
1955
+ ::rust::Slice<uint8_t const > slice{hash.data (), hash.size ()};
1956
+ mModuleCache ->evict_contract_code (slice);
1957
+ }
1958
+ }
1959
+ }
1960
+
1961
+ void
1962
+ LedgerManagerImpl::addAnyContractsToModuleCache (
1963
+ uint32_t ledgerVersion, std::vector<LedgerEntry> const & le)
1964
+ {
1965
+ for (auto const & e : le)
1966
+ {
1967
+ if (e.data .type () == CONTRACT_CODE)
1968
+ {
1969
+ for (auto const & v : mModuleCacheProtocols )
1970
+ {
1971
+ if (v >= ledgerVersion)
1972
+ {
1973
+ auto const & wasm = e.data .contractCode ().code ;
1974
+ auto slice =
1975
+ rust::Slice<const uint8_t >(wasm.data (), wasm.size ());
1976
+ mModuleCache ->compile (ledgerVersion, slice);
1977
+ }
1978
+ }
1979
+ }
1980
+ }
1981
+ }
1982
+
1885
1983
}
0 commit comments