Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Builds/VisualStudio/stellar-core.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,7 @@ exit /b 0
<ClCompile Include="..\..\src\util\BinaryFuseFilter.cpp" />
<ClCompile Include="..\..\src\util\DebugMetaUtils.cpp" />
<ClCompile Include="..\..\src\util\FileSystemException.cpp" />
<ClCompile Include="..\..\src\util\MetricsRegistry.cpp" />
<ClCompile Include="..\..\src\util\ProtocolVersion.cpp" />
<ClCompile Include="..\..\src\util\LogSlowExecution.cpp" />
<ClCompile Include="..\..\src\util\RandHasher.cpp" />
Expand Down Expand Up @@ -1175,6 +1176,7 @@ exit /b 0
<ClInclude Include="..\..\src\util\BufferedAsioCerealOutputArchive.h" />
<ClInclude Include="..\..\src\util\DebugMetaUtils.h" />
<ClInclude Include="..\..\src\util\Decoder.h" />
<ClInclude Include="..\..\src\util\MetricsRegistry.h" />
<ClInclude Include="..\..\src\util\ProtocolVersion.h" />
<ClInclude Include="..\..\src\util\numeric128.h" />
<ClInclude Include="..\..\src\util\RandHasher.h" />
Expand Down
6 changes: 6 additions & 0 deletions Builds/VisualStudio/stellar-core.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -1432,6 +1432,9 @@
<ClCompile Include="..\..\src\util\SimpleTimer.cpp">
<Filter>util</Filter>
</ClCompile>
<ClCompile Include="..\..\src\util\MetricsRegistry.cpp">
<Filter>util</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\lib\util\cpptoml.h">
Expand Down Expand Up @@ -2542,6 +2545,9 @@
<ClInclude Include="..\..\src\util\SimpleTimer.h">
<Filter>util</Filter>
</ClInclude>
<ClInclude Include="..\..\src\util\MetricsRegistry.h">
<Filter>util</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\AUTHORS" />
Expand Down
114 changes: 114 additions & 0 deletions docs/apply-load-limits-for-model-tx.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# This is the Stellar Core configuration example for using the load generation
# (apply-load) tool for finding the maximum ledger limits by applying a number
# of the equivalent 'model' transactions.
#
# The mode will find the maximum value of N, such that closing a ledger
# with N 'model' transactions takes less than a certain target time. Then
# it will find the actual ledger limits by multiplying the 'model' transaction
# dimensions by N.
#
# This is not meant to be used in any production contexts.
#
# The core with this configuration should be run using `./stellar-core apply-load --mode limits-for-model-tx`

# Enable load generation
ARTIFICIALLY_GENERATE_LOAD_FOR_TESTING=true

# Diagnostic events should generally be disabled, but can be enabled for debug
ENABLE_SOROBAN_DIAGNOSTIC_EVENTS = false

# Target average ledger close time.
APPLY_LOAD_TARGET_CLOSE_TIME_MS = 600

# Network configuration section

# Most of the network configuration will be inferred automatically from the 'model'
# transaction (for transaction limits) and from the search itself (for the ledger)
# limits. Only the following limits need to be set:

# Maximum number of Soroban transactions to apply. This is the upper bound for the
# search.
APPLY_LOAD_MAX_SOROBAN_TX_COUNT = 2000

# Number of the transaction clusters and thus apply threads. This will stay constant
# during the search, unlike all the other ledger limits.
APPLY_LOAD_LEDGER_MAX_DEPENDENT_TX_CLUSTERS = 8

# The following section contains various parameters for the generated load.

# Number of ledgers to close for benchmarking each iteration of search.
# The average close time will then be compared to APPLY_LOAD_TARGET_CLOSE_TIME_MS.
APPLY_LOAD_NUM_LEDGERS = 10

# Generate that many simple Classic payment transactions in every benchmark ledger.
# Note, that this will affect the close time.
APPLY_LOAD_CLASSIC_TXS_PER_LEDGER = 0

# Size of every synthetic data entry generated.
# This setting affects both the size of the pre-generated Bucket List entries,
# and the size of every entry that a Soroban transaction reads/writes.
APPLY_LOAD_DATA_ENTRY_SIZE = 250

# Bucket list pre-generation

# The benchmark will pre-generate ledger entries using the simplified ledger
# close process; the generated ledgers won't be reflected in the meta or
# history checkpoints.

# Faster settings, more shallow BL (up to level 6)
# Number of ledgers to close
APPLY_LOAD_BL_SIMULATED_LEDGERS = 10000
# Write a batch of entries every that many ledgers
APPLY_LOAD_BL_WRITE_FREQUENCY = 1000
# Write that many entries in every batch
APPLY_LOAD_BL_BATCH_SIZE = 1000
# Write entry batches in every ledger of this many last ledgers
APPLY_LOAD_BL_LAST_BATCH_SIZE = 100
# Write that many entries in every 'last' ledger
APPLY_LOAD_BL_LAST_BATCH_LEDGERS = 300

# Slower settings, deeper BL (up to level 9)
#APPLY_LOAD_BL_SIMULATED_LEDGERS = 300000
#APPLY_LOAD_BL_WRITE_FREQUENCY = 10000
#APPLY_LOAD_BL_BATCH_SIZE = 10000
#APPLY_LOAD_BL_LAST_BATCH_LEDGERS = 300
#APPLY_LOAD_BL_LAST_BATCH_SIZE = 100

# Settings for the generated 'model' transaction.
# Unlike the 'limit-based' apply-load mode, only a single value
# with `[1]` as distribution is allowed, thus only a single kind
# of transaction will be generated.

# Number of *disk* reads a transaction performs. Every disk read is restoration,
# so it's also a write (accounted for in NUM_RW_ENTRIES).
APPLY_LOAD_NUM_DISK_READ_ENTRIES = [1]
APPLY_LOAD_NUM_DISK_READ_ENTRIES_DISTRIBUTION = [1]

# Number of writes a transaction performs.
APPLY_LOAD_NUM_RW_ENTRIES = [5]
APPLY_LOAD_NUM_RW_ENTRIES_DISTRIBUTION = [1]

# Number of 80-byte events a transaction emits.
APPLY_LOAD_EVENT_COUNT = [15]
APPLY_LOAD_EVENT_COUNT_DISTRIBUTION = [1]

# Size of a generated transaction.
APPLY_LOAD_TX_SIZE_BYTES = [1650]
APPLY_LOAD_TX_SIZE_BYTES_DISTRIBUTION = [1]

# Number of instructions a transaction will use.
APPLY_LOAD_INSTRUCTIONS = [4250000]
APPLY_LOAD_INSTRUCTIONS_DISTRIBUTION = [1]


# Minimal core config boilerplate

RUN_STANDALONE=true
NODE_IS_VALIDATOR=true
UNSAFE_QUORUM=true
NETWORK_PASSPHRASE="Standalone Network ; February 2017"
NODE_SEED="SDQVDISRYN2JXBS7ICL7QJAEKB3HWBJFP2QECXG7GZICAHBK4UNJCWK2 self"

[QUORUM_SET]
THRESHOLD_PERCENT=100
VALIDATORS=["$self"]
13 changes: 9 additions & 4 deletions docs/software/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,18 @@ Command options can only by placed after command.
synthetic ledger close metadata emitted during the benchmark, and then use
it for benchmarking the meta consumers.
* This can only be used when `ARTIFICIALLY_GENERATE_LOAD_FOR_TESTING=true`
* The command supports several modes:
- **--mode limit-based**: the default mode that measures the
ledger close time for applying transactions.
- **--mode max-sac-tps**: determines maximum TPS for the load consisting
only of fast SAC transfer
- **--mode limits-for-model-tx**: determines maximum ledger limits for the
load consisting only of a customizable 'model' transaction.
* Load generation is configured in the Core config file. The relevant settings
all begin with `APPLY_LOAD_`. See full example configurations with
per-setting documentation in the `docs` directory
(`apply-load.cfg`, `apply-load-for-meta.cfg`).
* The command also supports the special mode for determining max apply 'TPS'
using SAC transfers. It can be invoked by passing `max-sac-tps` as
`apply-load` argument.
(all the `apply-load-*.cfg` files demonstrate different modes and use
cases).

* **calculate-asset-supply**: Calculates total supply of an asset from the live and hot archive bucket lists IF the total supply fits in a 64 bit signed integer. Also validates against totalCoins for the native asset. Uses `--code <CODE>` and `--issuer <ISSUER>` to specify the asset. Uses the native asset if neither `--code` nor `--issuer` is given.
* **catchup <DESTINATION-LEDGER/LEDGER-COUNT>**: Perform catchup from history
Expand Down
115 changes: 11 additions & 104 deletions src/main/CommandLine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1903,6 +1903,11 @@ applyLoadModeParser(std::string& modeArg, ApplyLoadMode& mode)
mode = ApplyLoadMode::MAX_SAC_TPS;
return "";
}
if (iequals(modeArg, "limits-for-model-tx"))
{
mode = ApplyLoadMode::FIND_LIMITS_FOR_MODEL_TX;
return "";
}
return "Unrecognized apply-load mode. Please select 'ledger-limits' "
"or 'max-sac-tps'.";
};
Expand Down Expand Up @@ -1931,7 +1936,11 @@ runApplyLoad(CommandLineArgs const& args)
config.TESTING_UPGRADE_MAX_TX_SET_SIZE = 1000;
config.LEDGER_PROTOCOL_VERSION =
Config::CURRENT_LEDGER_PROTOCOL_VERSION;

if (config.APPLY_LOAD_NUM_LEDGERS == 0)
{
throw std::runtime_error(
"APPLY_LOAD_NUM_LEDGERS must be greater than 0");
}
if (mode == ApplyLoadMode::MAX_SAC_TPS)
{
if (config.APPLY_LOAD_MAX_SAC_TPS_MIN_TPS >=
Expand Down Expand Up @@ -2024,109 +2033,7 @@ runApplyLoad(CommandLineArgs const& args)
{"ledger", "transaction", "total-apply"});
totalTxApplyTime.Clear();

if (mode == ApplyLoadMode::MAX_SAC_TPS)
{
al.findMaxSacTps();
return 0;
}

if (config.APPLY_LOAD_NUM_LEDGERS == 0)
{
throw std::runtime_error(
"APPLY_LOAD_NUM_LEDGERS must be greater than 0");
}

for (size_t i = 0; i < config.APPLY_LOAD_NUM_LEDGERS; ++i)
{
app.getBucketManager()
.getLiveBucketList()
.resolveAllFutures();
releaseAssert(app.getBucketManager()
.getLiveBucketList()
.futuresAllResolved());
al.benchmark();
}

CLOG_INFO(Perf, "Max ledger close: {} milliseconds",
ledgerClose.max());
CLOG_INFO(Perf, "Min ledger close: {} milliseconds",
ledgerClose.min());
CLOG_INFO(Perf, "Mean ledger close: {} milliseconds",
ledgerClose.mean());
CLOG_INFO(Perf, "stddev ledger close: {} milliseconds",
ledgerClose.std_dev());

CLOG_INFO(Perf, "Max CPU ins ratio: {}",
cpuInsRatio.max() / 1000000);
CLOG_INFO(Perf, "Mean CPU ins ratio: {}",
cpuInsRatio.mean() / 1000000);

CLOG_INFO(Perf, "Max CPU ins ratio excl VM: {}",
cpuInsRatioExclVm.max() / 1000000);
CLOG_INFO(Perf, "Mean CPU ins ratio excl VM: {}",
cpuInsRatioExclVm.mean() / 1000000);
CLOG_INFO(Perf, "stddev CPU ins ratio excl VM: {}",
cpuInsRatioExclVm.std_dev() / 1000000);

CLOG_INFO(Perf, "Ledger Max CPU ins ratio: {}",
ledgerCpuInsRatio.max() / 1000000);
CLOG_INFO(Perf, "Ledger Mean CPU ins ratio: {}",
ledgerCpuInsRatio.mean() / 1000000);
CLOG_INFO(Perf, "Ledger stddev CPU ins ratio: {}",
ledgerCpuInsRatio.std_dev() / 1000000);

CLOG_INFO(Perf, "Ledger Max CPU ins ratio excl VM: {}",
ledgerCpuInsRatioExclVm.max() / 1000000);
CLOG_INFO(Perf, "Ledger Mean CPU ins ratio excl VM: {}",
ledgerCpuInsRatioExclVm.mean() / 1000000);
CLOG_INFO(
Perf,
"Ledger stddev CPU ins ratio excl VM: {} milliseconds",
ledgerCpuInsRatioExclVm.std_dev() / 1000000);
// Utilization metrics are relevant only in limit-based
// mode.
if (mode == ApplyLoadMode::LIMIT_BASED)
{
CLOG_INFO(Perf,
"Tx count utilization min/avg/max {}/{}/{}%",
al.getTxCountUtilization().min() / 1000.0,
al.getTxCountUtilization().mean() / 1000.0,
al.getTxCountUtilization().max() / 1000.0);
CLOG_INFO(Perf,
"Instruction utilization min/avg/max {}/{}/{}%",
al.getInstructionUtilization().min() / 1000.0,
al.getInstructionUtilization().mean() / 1000.0,
al.getInstructionUtilization().max() / 1000.0);
CLOG_INFO(Perf, "Tx size utilization min/avg/max {}/{}/{}%",
al.getTxSizeUtilization().min() / 1000.0,
al.getTxSizeUtilization().mean() / 1000.0,
al.getTxSizeUtilization().max() / 1000.0);
CLOG_INFO(
Perf,
"Disk read bytes utilization min/avg/max {}/{}/{}%",
al.getDiskReadByteUtilization().min() / 1000.0,
al.getDiskReadByteUtilization().mean() / 1000.0,
al.getDiskReadByteUtilization().max() / 1000.0);
CLOG_INFO(Perf,
"Write bytes utilization min/avg/max {}/{}/{}%",
al.getDiskWriteByteUtilization().min() / 1000.0,
al.getDiskWriteByteUtilization().mean() / 1000.0,
al.getDiskWriteByteUtilization().max() / 1000.0);
CLOG_INFO(
Perf,
"Disk read entry utilization min/avg/max {}/{}/{}%",
al.getDiskReadEntryUtilization().min() / 1000.0,
al.getDiskReadEntryUtilization().mean() / 1000.0,
al.getDiskReadEntryUtilization().max() / 1000.0);
CLOG_INFO(Perf,
"Write entry utilization min/avg/max {}/{}/{}%",
al.getWriteEntryUtilization().min() / 1000.0,
al.getWriteEntryUtilization().mean() / 1000.0,
al.getWriteEntryUtilization().max() / 1000.0);
}

CLOG_INFO(Perf, "Tx Success Rate: {:f}%",
al.successRate() * 100);
al.execute();
}

return 0;
Expand Down
17 changes: 8 additions & 9 deletions src/main/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1742,19 +1742,18 @@ Config::processConfig(std::shared_ptr<cpptoml::table> t)
}},
{"APPLY_LOAD_NUM_LEDGERS",
[&]() { APPLY_LOAD_NUM_LEDGERS = readInt<uint32_t>(item); }},
{"APPLY_LOAD_MAX_SAC_TPS_TARGET_CLOSE_TIME_MS",
{"APPLY_LOAD_TARGET_CLOSE_TIME_MS",
[&]() {
APPLY_LOAD_MAX_SAC_TPS_TARGET_CLOSE_TIME_MS =
APPLY_LOAD_TARGET_CLOSE_TIME_MS =
readInt<uint32_t>(item, 1);
if (APPLY_LOAD_MAX_SAC_TPS_TARGET_CLOSE_TIME_MS %
ApplyLoad::MAX_SAC_TPS_TIME_STEP_MS !=
if (APPLY_LOAD_TARGET_CLOSE_TIME_MS %
ApplyLoad::TARGET_CLOSE_TIME_STEP_MS !=
0)
{
throw std::invalid_argument(
fmt::format(FMT_STRING("APPLY_LOAD_MAX_SAC_TPS_"
"TARGET_CLOSE_TIME_MS must "
"be a multiple of {}."),
ApplyLoad::MAX_SAC_TPS_TIME_STEP_MS));
throw std::invalid_argument(fmt::format(
FMT_STRING("APPLY_LOAD_TARGET_CLOSE_TIME_MS "
"must be a multiple of {}."),
ApplyLoad::TARGET_CLOSE_TIME_STEP_MS));
}
}},
{"APPLY_LOAD_MAX_SAC_TPS_MIN_TPS",
Expand Down
9 changes: 8 additions & 1 deletion src/main/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -386,8 +386,16 @@ class Config : public std::enable_shared_from_this<Config>

uint32_t APPLY_LOAD_LEDGER_MAX_DEPENDENT_TX_CLUSTERS = 1;

// Number of ledgers to apply in apply-load.
// Depending on the mode this represents either the total number of ledgers
// to close for benchmarking, or the number of ledgers to apply per
// iteration of binary search for modes that perform search.
uint32_t APPLY_LOAD_NUM_LEDGERS = 100;

// Target ledger close time in milliseconds for modes that perform binary
// search of TPS or limits.
uint32_t APPLY_LOAD_TARGET_CLOSE_TIME_MS = 1000;

// Number of classic transactions to include in each ledger in ledger limit
// based apply-load mode.
uint32_t APPLY_LOAD_CLASSIC_TXS_PER_LEDGER = 0;
Expand All @@ -412,7 +420,6 @@ class Config : public std::enable_shared_from_this<Config>
std::vector<uint32_t> APPLY_LOAD_EVENT_COUNT_DISTRIBUTION;

// MAX_SAC_TPS mode specific parameters
uint32_t APPLY_LOAD_MAX_SAC_TPS_TARGET_CLOSE_TIME_MS = 1000;
uint32_t APPLY_LOAD_MAX_SAC_TPS_MIN_TPS = 100;
uint32_t APPLY_LOAD_MAX_SAC_TPS_MAX_TPS = 50000;

Expand Down
Loading
Loading