-
Notifications
You must be signed in to change notification settings - Fork 977
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
381 additions
and
95 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,240 @@ | ||
#include "simulation/ApplyLoad.h" | ||
#include "herder/Herder.h" | ||
#include "ledger/LedgerManager.h" | ||
#include "test/TxTests.h" | ||
#include "transactions/TransactionBridge.h" | ||
#include "transactions/TransactionUtils.h" | ||
|
||
#include "medida/meter.h" | ||
#include "medida/metrics_registry.h" | ||
|
||
#include "util/XDRCereal.h" | ||
#include <crypto/SHA.h> | ||
|
||
namespace stellar | ||
{ | ||
|
||
uint64_t NUM_ACCOUNTS = 400; | ||
|
||
ApplyLoad::ApplyLoad(Application& app) : TxGenerator(app) | ||
{ | ||
// TODO: add command line options to set these values? | ||
mUpgradeConfig.maxContractSizeBytes = 65536; | ||
mUpgradeConfig.maxContractDataKeySizeBytes = 250; | ||
mUpgradeConfig.maxContractDataEntrySizeBytes = 65536; | ||
mUpgradeConfig.ledgerMaxInstructions = 500000000; | ||
mUpgradeConfig.txMaxInstructions = 100000000; | ||
mUpgradeConfig.txMemoryLimit = 41943040; | ||
mUpgradeConfig.ledgerMaxReadLedgerEntries = 200; | ||
mUpgradeConfig.ledgerMaxReadBytes = 500000; | ||
mUpgradeConfig.ledgerMaxWriteLedgerEntries = 125; | ||
mUpgradeConfig.ledgerMaxWriteBytes = 70000; | ||
mUpgradeConfig.ledgerMaxTxCount = 100; | ||
mUpgradeConfig.txMaxReadLedgerEntries = 40; | ||
mUpgradeConfig.txMaxReadBytes = 200000; | ||
mUpgradeConfig.txMaxWriteLedgerEntries = 25; | ||
mUpgradeConfig.txMaxWriteBytes = 66560; | ||
mUpgradeConfig.txMaxContractEventsSizeBytes = 8198; | ||
mUpgradeConfig.ledgerMaxTransactionsSizeBytes = 71680; | ||
mUpgradeConfig.txMaxSizeBytes = 71680; | ||
mUpgradeConfig.bucketListSizeWindowSampleSize = 30; | ||
mUpgradeConfig.evictionScanSize = 100000; | ||
mUpgradeConfig.startingEvictionScanLevel = 7; | ||
|
||
createRootAccount(); | ||
updateMinBalance(); | ||
|
||
releaseAssert(mRoot); | ||
|
||
setupAccountsAndUpgradeProtocol(); | ||
|
||
setupUpgradeContract(); | ||
|
||
upgradeSettings(); | ||
|
||
setupLoadContracts(); | ||
|
||
// One contract per account | ||
releaseAssert(mApplySorobanSuccess.count() == NUM_ACCOUNTS + 4); | ||
releaseAssert(mApplySorobanFailure.count() == 0); | ||
} | ||
|
||
void | ||
ApplyLoad::closeLedger(std::vector<TransactionFrameBasePtr> const& txs, | ||
xdr::xvector<UpgradeType, 6> const& upgrades) | ||
{ | ||
auto txSet = makeTxSetFromTransactions(txs, mApp, 0, UINT64_MAX); | ||
|
||
auto sv = | ||
mApp.getHerder().makeStellarValue(txSet.first->getContentsHash(), 1, | ||
upgrades, mApp.getConfig().NODE_SEED); | ||
|
||
auto& lm = mApp.getLedgerManager(); | ||
LedgerCloseData lcd(lm.getLastClosedLedgerNum() + 1, txSet.first, sv); | ||
lm.closeLedger(lcd); | ||
} | ||
|
||
void | ||
ApplyLoad::setupAccountsAndUpgradeProtocol() | ||
{ | ||
auto const& lm = mApp.getLedgerManager(); | ||
std::vector<Operation> creationOps = | ||
createAccounts(0, NUM_ACCOUNTS, lm.getLastClosedLedgerNum() + 1, true); | ||
|
||
auto initTx = | ||
createTransactionFramePtr(mRoot, creationOps, false, std::nullopt); | ||
|
||
// Upgrade to latest protocol as well | ||
auto upgrade = xdr::xvector<UpgradeType, 6>{}; | ||
auto ledgerUpgrade = LedgerUpgrade{LEDGER_UPGRADE_VERSION}; | ||
ledgerUpgrade.newLedgerVersion() = Config::CURRENT_LEDGER_PROTOCOL_VERSION; | ||
auto v = xdr::xdr_to_opaque(ledgerUpgrade); | ||
upgrade.push_back(UpgradeType{v.begin(), v.end()}); | ||
|
||
closeLedger({initTx}, upgrade); | ||
} | ||
|
||
void | ||
ApplyLoad::setupUpgradeContract() | ||
{ | ||
auto wasm = rust_bridge::get_write_bytes(); | ||
xdr::opaque_vec<> wasmBytes; | ||
wasmBytes.assign(wasm.data.begin(), wasm.data.end()); | ||
|
||
LedgerKey contractCodeLedgerKey; | ||
contractCodeLedgerKey.type(CONTRACT_CODE); | ||
contractCodeLedgerKey.contractCode().hash = sha256(wasmBytes); | ||
|
||
mUpgradeCodeKey = contractCodeLedgerKey; | ||
|
||
auto const& lm = mApp.getLedgerManager(); | ||
auto uploadTx = createUploadWasmTransaction( | ||
lm.getLastClosedLedgerNum() + 1, 0, wasmBytes, contractCodeLedgerKey, | ||
std::nullopt); | ||
|
||
closeLedger({uploadTx.second}); | ||
|
||
auto salt = sha256("upgrade contract salt preimage"); | ||
|
||
auto createTx = createContractTransaction( | ||
lm.getLastClosedLedgerNum() + 1, 0, contractCodeLedgerKey, | ||
wasmBytes.size() + 160, salt, std::nullopt); | ||
closeLedger({createTx.second}); | ||
|
||
mUpgradeInstanceKey = | ||
createTx.second->sorobanResources().footprint.readWrite.back(); | ||
} | ||
|
||
// To upgrade settings, just modify mUpgradeConfig and then call | ||
// upgradeSettings() | ||
void | ||
ApplyLoad::upgradeSettings() | ||
{ | ||
auto const& lm = mApp.getLedgerManager(); | ||
auto upgradeBytes = getConfigUpgradeSetFromLoadConfig(mUpgradeConfig); | ||
|
||
auto invokeTx = invokeSorobanCreateUpgradeTransaction( | ||
lm.getLastClosedLedgerNum() + 1, 0, upgradeBytes, mUpgradeCodeKey, | ||
mUpgradeInstanceKey, std::nullopt); | ||
|
||
auto upgradeSetKey = getConfigUpgradeSetKey( | ||
mUpgradeConfig, | ||
mUpgradeInstanceKey.contractData().contract.contractId()); | ||
|
||
auto upgrade = xdr::xvector<UpgradeType, 6>{}; | ||
auto ledgerUpgrade = LedgerUpgrade{LEDGER_UPGRADE_CONFIG}; | ||
ledgerUpgrade.newConfig() = upgradeSetKey; | ||
auto v = xdr::xdr_to_opaque(ledgerUpgrade); | ||
upgrade.push_back(UpgradeType{v.begin(), v.end()}); | ||
|
||
closeLedger({invokeTx.second}, upgrade); | ||
} | ||
|
||
void | ||
ApplyLoad::setupLoadContracts() | ||
{ | ||
auto wasm = rust_bridge::get_test_wasm_loadgen(); | ||
xdr::opaque_vec<> wasmBytes; | ||
wasmBytes.assign(wasm.data.begin(), wasm.data.end()); | ||
|
||
LedgerKey contractCodeLedgerKey; | ||
contractCodeLedgerKey.type(CONTRACT_CODE); | ||
contractCodeLedgerKey.contractCode().hash = sha256(wasmBytes); | ||
|
||
mLoadCodeKey = contractCodeLedgerKey; | ||
|
||
auto const& lm = mApp.getLedgerManager(); | ||
auto uploadTx = createUploadWasmTransaction( | ||
lm.getLastClosedLedgerNum() + 1, 0, wasmBytes, contractCodeLedgerKey, | ||
std::nullopt); | ||
|
||
closeLedger({uploadTx.second}); | ||
|
||
for (auto kvp : mAccounts) | ||
{ | ||
auto salt = sha256("Load contract " + std::to_string(kvp.first)); | ||
|
||
auto createTx = createContractTransaction( | ||
lm.getLastClosedLedgerNum() + 1, 0, contractCodeLedgerKey, | ||
wasmBytes.size() + 160, salt, std::nullopt); | ||
closeLedger({createTx.second}); | ||
|
||
auto instanceKey = | ||
createTx.second->sorobanResources().footprint.readWrite.back(); | ||
|
||
ContractInstance instance; | ||
instance.readOnlyKeys.emplace_back(mLoadCodeKey); | ||
instance.readOnlyKeys.emplace_back(instanceKey); | ||
instance.contractID = instanceKey.contractData().contract; | ||
mLoadInstances.emplace(kvp.first, instance); | ||
} | ||
} | ||
|
||
void | ||
ApplyLoad::benchmark() | ||
{ | ||
auto& lm = mApp.getLedgerManager(); | ||
std::vector<TransactionFrameBasePtr> txs; | ||
|
||
auto resources = | ||
multiplyByDouble(lm.maxLedgerResources(true), | ||
2 /*TODO: use TRANSACTION_QUEUE_SIZE_MULTIPLIER*/); | ||
|
||
std::vector<uint64_t> shuffledAccounts(mAccounts.size()); | ||
std::iota(shuffledAccounts.begin(), shuffledAccounts.end(), 0); | ||
stellar::shuffle(std::begin(shuffledAccounts), std::end(shuffledAccounts), | ||
gRandomEngine); | ||
|
||
for (auto accountIndex : shuffledAccounts) | ||
{ | ||
auto it = mAccounts.find(accountIndex); | ||
releaseAssert(it != mAccounts.end()); | ||
|
||
auto instanceIter = mLoadInstances.find(it->first); | ||
releaseAssert(instanceIter != mLoadInstances.end()); | ||
auto const& instance = instanceIter->second; | ||
auto tx = invokeSorobanLoadTransaction( | ||
lm.getLastClosedLedgerNum() + 1, it->first, instance, | ||
rust_bridge::get_write_bytes().data.size() + 160, std::nullopt); | ||
|
||
if (!anyGreater(tx.second->getResources(false), resources)) | ||
{ | ||
resources -= tx.second->getResources(false); | ||
} | ||
else | ||
{ | ||
break; | ||
} | ||
|
||
txs.emplace_back(tx.second); | ||
} | ||
|
||
closeLedger(txs); | ||
|
||
CLOG_INFO(Perf, "mApplySorobanSuccess count {}", | ||
mApplySorobanSuccess.count()); | ||
CLOG_INFO(Perf, "mApplySorobanFailure count {}", | ||
mApplySorobanFailure.count()); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#include "main/Application.h" | ||
#include "simulation/TxGenerator.h" | ||
#include "test/TestAccount.h" | ||
|
||
namespace stellar | ||
{ | ||
class ApplyLoad : public TxGenerator | ||
{ | ||
public: | ||
ApplyLoad(Application& app); | ||
void benchmark(); | ||
|
||
private: | ||
void closeLedger(std::vector<TransactionFrameBasePtr> const& txs, | ||
xdr::xvector<UpgradeType, 6> const& upgrades = {}); | ||
|
||
void setupAccountsAndUpgradeProtocol(); | ||
void setupUpgradeContract(); | ||
void setupLoadContracts(); | ||
|
||
// Upgrades using mUpgradeConfig | ||
void upgradeSettings(); | ||
|
||
LedgerKey mUpgradeCodeKey; | ||
LedgerKey mUpgradeInstanceKey; | ||
|
||
LedgerKey mLoadCodeKey; | ||
UnorderedMap<uint64_t, ContractInstance> mLoadInstances; | ||
|
||
SorobanUpgradeConfig mUpgradeConfig; | ||
}; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.