-
Notifications
You must be signed in to change notification settings - Fork 979
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reusable module cache #4621
base: master
Are you sure you want to change the base?
Reusable module cache #4621
Changes from 5 commits
d7136b5
dd5b7eb
29fc42d
d22b2e8
16bbb07
b4650b1
067694a
38ffb61
391976a
60bfd4e
d2fbace
c7f1c1b
0e78326
cd8cda3
88f6387
7927396
1bac031
1ffbe99
8a20d28
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,12 +20,15 @@ | |
#include "history/HistoryManager.h" | ||
#include "ledger/FlushAndRotateMetaDebugWork.h" | ||
#include "ledger/LedgerHeaderUtils.h" | ||
#include "ledger/LedgerManager.h" | ||
#include "ledger/LedgerTxn.h" | ||
#include "ledger/LedgerTxnEntry.h" | ||
#include "ledger/LedgerTxnHeader.h" | ||
#include "ledger/SharedModuleCacheCompiler.h" | ||
#include "main/Application.h" | ||
#include "main/Config.h" | ||
#include "main/ErrorMessages.h" | ||
#include "rust/RustBridge.h" | ||
#include "transactions/MutableTransactionResult.h" | ||
#include "transactions/OperationFrame.h" | ||
#include "transactions/TransactionFrameBase.h" | ||
|
@@ -41,8 +44,10 @@ | |
#include "util/XDRCereal.h" | ||
#include "util/XDRStream.h" | ||
#include "work/WorkScheduler.h" | ||
#include "xdr/Stellar-ledger-entries.h" | ||
#include "xdrpp/printer.h" | ||
|
||
#include <cstdint> | ||
#include <fmt/format.h> | ||
|
||
#include "xdr/Stellar-ledger-entries.h" | ||
|
@@ -125,6 +130,27 @@ LedgerManager::ledgerAbbrev(LedgerHeaderHistoryEntry const& he) | |
return ledgerAbbrev(he.header, he.hash); | ||
} | ||
|
||
static std::vector<uint32_t> | ||
getModuleCacheProtocols() | ||
{ | ||
std::vector<uint32_t> ledgerVersions; | ||
for (uint32_t i = (uint32_t)REUSABLE_SOROBAN_MODULE_CACHE_PROTOCOL_VERSION; | ||
i <= Config::CURRENT_LEDGER_PROTOCOL_VERSION; i++) | ||
{ | ||
ledgerVersions.push_back(i); | ||
} | ||
auto extra = getenv("SOROBAN_TEST_EXTRA_PROTOCOL"); | ||
if (extra) | ||
{ | ||
uint32_t proto = static_cast<uint32_t>(atoi(extra)); | ||
if (proto > 0) | ||
{ | ||
ledgerVersions.push_back(proto); | ||
} | ||
} | ||
return ledgerVersions; | ||
} | ||
|
||
LedgerManagerImpl::LedgerManagerImpl(Application& app) | ||
: mApp(app) | ||
, mSorobanMetrics(app.getMetrics()) | ||
|
@@ -157,6 +183,8 @@ LedgerManagerImpl::LedgerManagerImpl(Application& app) | |
, mCatchupDuration( | ||
app.getMetrics().NewTimer({"ledger", "catchup", "duration"})) | ||
, mState(LM_BOOTING_STATE) | ||
, mModuleCache(::rust_bridge::new_module_cache()) | ||
, mModuleCacheProtocols(getModuleCacheProtocols()) | ||
|
||
{ | ||
setupLedgerCloseMetaStream(); | ||
|
@@ -405,6 +433,9 @@ LedgerManagerImpl::loadLastKnownLedger(bool restoreBucketlist) | |
updateNetworkConfig(ltx); | ||
mSorobanNetworkConfigReadOnly = mSorobanNetworkConfigForApply; | ||
} | ||
|
||
// Prime module cache with ledger content. | ||
compileAllContractsInLedger(latestLedgerHeader->ledgerVersion); | ||
} | ||
|
||
Database& | ||
|
@@ -568,6 +599,30 @@ LedgerManagerImpl::getSorobanMetrics() | |
return mSorobanMetrics; | ||
} | ||
|
||
rust_bridge::SorobanModuleCache& | ||
LedgerManagerImpl::getModuleCache() | ||
{ | ||
return *mModuleCache; | ||
} | ||
|
||
void | ||
LedgerManagerImpl::compileAllContractsInLedger(uint32_t minLedgerVersion) | ||
{ | ||
auto& moduleCache = getModuleCache(); | ||
moduleCache.clear(); | ||
std::vector<uint32_t> versions; | ||
for (auto const& v : mModuleCacheProtocols) | ||
{ | ||
if (v >= minLedgerVersion) | ||
{ | ||
versions.push_back(v); | ||
} | ||
} | ||
auto compiler = std::make_shared<SharedModuleCacheCompiler>( | ||
mApp, moduleCache, versions); | ||
compiler->run(); | ||
} | ||
|
||
void | ||
LedgerManagerImpl::publishSorobanMetrics() | ||
{ | ||
|
@@ -1812,6 +1867,8 @@ LedgerManagerImpl::transferLedgerEntriesToBucketList( | |
ledgerCloseMeta->populateEvictedEntries(evictedState); | ||
} | ||
|
||
evictFromModuleCache(lh.ledgerVersion, evictedState); | ||
|
||
ltxEvictions.commit(); | ||
} | ||
|
||
|
@@ -1822,6 +1879,8 @@ LedgerManagerImpl::transferLedgerEntriesToBucketList( | |
ltx.getAllEntries(initEntries, liveEntries, deadEntries); | ||
if (blEnabled) | ||
{ | ||
addAnyContractsToModuleCache(lh.ledgerVersion, initEntries); | ||
dmkozh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
addAnyContractsToModuleCache(lh.ledgerVersion, liveEntries); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this expected to be a no-op now, or do we have the restored entries in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know -- I figured it'd be fairly future-proof to just assume both live and init might carry contracts. @SirTyson do you know off hand? |
||
mApp.getBucketManager().addLiveBatch(mApp, lh, initEntries, liveEntries, | ||
deadEntries); | ||
} | ||
|
@@ -1882,4 +1941,43 @@ LedgerManagerImpl::ledgerClosed( | |
|
||
return res; | ||
} | ||
|
||
void | ||
LedgerManagerImpl::evictFromModuleCache(uint32_t ledgerVersion, | ||
EvictedStateVectors const& evictedState) | ||
{ | ||
::rust::Vec<CxxBuf> contractCodeKeys; | ||
for (auto const& entry : evictedState.archivedEntries) | ||
{ | ||
if (entry.data.type() == CONTRACT_CODE) | ||
{ | ||
Hash const& hash = entry.data.contractCode().hash; | ||
::rust::Slice<uint8_t const> slice{hash.data(), hash.size()}; | ||
mModuleCache->evict_contract_code(slice); | ||
} | ||
} | ||
} | ||
|
||
void | ||
LedgerManagerImpl::addAnyContractsToModuleCache( | ||
uint32_t ledgerVersion, std::vector<LedgerEntry> const& le) | ||
{ | ||
for (auto const& e : le) | ||
{ | ||
if (e.data.type() == CONTRACT_CODE) | ||
{ | ||
for (auto const& v : mModuleCacheProtocols) | ||
{ | ||
if (v >= ledgerVersion) | ||
{ | ||
auto const& wasm = e.data.contractCode().code; | ||
auto slice = | ||
rust::Slice<const uint8_t>(wasm.data(), wasm.size()); | ||
mModuleCache->compile(v, slice); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: This should be no longer necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.