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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
*.lib
*.user
*.xdr
!test-lcm/**/*.xdr
*.cache
*.tlog
*.lastbuildstate
Expand Down
13 changes: 13 additions & 0 deletions docs/software/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,11 +201,24 @@ Command options can only by placed after command.
multiple times (default latest)
* `--base-instance <N>` : run tests with instance numbers offset by N,
used to run tests in parallel
* `--capture-lcm` : capture `LedgerCloseMeta` XDR from every
`closeLedger`/`closeLedgerOn` call during tests. Files are written
automatically at leaf-section boundaries (or test-case boundaries for
tests without sections) to `test-lcm/<TestFileBaseName>/`. Each file
is named after the test case and section path
(e.g. `test_name-section-subsection.xdr`) and contains
stream-framed `LedgerCloseMeta` entries that can be decoded with
`stellar-xdr decode --type LedgerCloseMeta --input stream-framed`.
Meta is normalized (sorted) before writing so that output is
deterministic given a fixed `--rng-seed`.
* The network passphrase is set to `(V) (;,,;) (V)` for all captured meta.
* For [further info](https://github.com/philsquared/Catch/blob/master/docs/command-line.md)
on possible options for test.
* For example this will run just the tests tagged with `[tx]` using protocol
versions 9 and 10 and stop after the first failure:
`stellar-core test -a --version 9 --version 10 "[tx]"`
* To capture LCM for tests with a fixed seed:
`stellar-core test --capture-lcm --rng-seed 12345 "[soroban]"`
* **upgrade-db**: Upgrades local database to current schema version. This is
usually done automatically during stellar-core run or other command.
* **verify-checkpoints**: Listens to the network until it observes a consensus
Expand Down
15 changes: 10 additions & 5 deletions src/ledger/LedgerManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1742,6 +1742,16 @@ LedgerManagerImpl::applyLedger(LedgerCloseData const& ledgerData,
throw std::runtime_error("Local node's ledger corrupted during close");
}

#ifdef BUILD_TESTS
if (ledgerCloseMeta)
{
ledgerCloseMeta->ledgerHeader() =
appliedLedgerState->getLastClosedLedgerHeader();
// Copy this before we move it into mNextMetaToEmit below
mLastLedgerCloseMeta = *ledgerCloseMeta;
}
#endif

if (mMetaStream || mMetaDebugStream)
{
releaseAssert(ledgerCloseMeta);
Expand Down Expand Up @@ -2604,11 +2614,6 @@ LedgerManagerImpl::applyTransactions(
mApplyState.getMetrics().mStagesPerLedger.set_count(applyStages.size());
}

#ifdef BUILD_TESTS
releaseAssert(ledgerCloseMeta);
mLastLedgerCloseMeta = *ledgerCloseMeta;
#endif

logTxApplyMetrics(ltx, numTxs, numOps);
return txResultSet;
}
Expand Down
3 changes: 2 additions & 1 deletion src/ledger/test/LedgerCloseMetaStreamTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,8 @@ TEST_CASE_VERSIONS("meta stream contains reasonable meta", "[ledgerclosemeta]")
// Close ledgers until out contract expires. These ledgers won't
// emit meta
for (uint32_t i =
test.getApp().getLedgerManager().getLastClosedLedgerNum();
test.getApp().getLedgerManager().getLastClosedLedgerNum() +
1;
i <= liveUntilLedger + 1; ++i)
{
closeLedgerOn(test.getApp(), i, 2, 1, 2016);
Expand Down
2 changes: 2 additions & 0 deletions src/test/TestUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,8 @@ modifySorobanNetworkConfig(Application& app,
{upgrade});
app.getRoot()->loadSequenceNumber();

txtest::captureLastClosedLedgerLcm(app);

// Check that the upgrade was actually applied.
auto postUpgradeCfg =
app.getLedgerManager().getLastClosedSorobanNetworkConfig();
Expand Down
50 changes: 50 additions & 0 deletions src/test/TxTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "database/Database.h"
#include "herder/Herder.h"
#include "invariant/InvariantManager.h"
#include "ledger/LedgerCloseMetaFrame.h"
#include "ledger/LedgerTxn.h"
#include "ledger/LedgerTxnEntry.h"
#include "ledger/LedgerTxnHeader.h"
Expand All @@ -24,10 +25,12 @@
#include "transactions/TransactionBridge.h"
#include "transactions/TransactionFrame.h"
#include "transactions/TransactionUtils.h"
#include "util/Fs.h"
#include "util/GlobalChecks.h"
#include "util/Logging.h"
#include "util/ProtocolVersion.h"
#include "util/XDROperators.h"
#include "util/XDRStream.h"
#include "util/types.h"
#include "xdrpp/autocheck.h"

Expand All @@ -43,6 +46,44 @@ namespace stellar
namespace txtest
{

static std::vector<LedgerCloseMeta> gAccumulatedLcm;

std::vector<LedgerCloseMeta> const&
getAccumulatedLcm()
{
return gAccumulatedLcm;
}

void
clearAccumulatedLcm()
{
gAccumulatedLcm.clear();
}

void
appendToAccumulatedLcm(LedgerCloseMeta const& lcm)
{
gAccumulatedLcm.emplace_back(lcm);
}

void
captureLastClosedLedgerLcm(Application& app)
{
// TODO: In-memory mode uses applyCheck which closes an empty ledger
// then applies the tx directly, so txs never appear in LCM. Fix this
// by restructuring applyCheck to use closeLedger(app, {tx}) when
// capturing LCM.
if (isLcmCaptureEnabled() && !app.getConfig().MODE_USES_IN_MEMORY_LEDGER)
{
auto const& closeMeta =
app.getLedgerManager().getLastClosedLedgerCloseMeta();
if (closeMeta.has_value())
{
appendToAccumulatedLcm(closeMeta->getXDR());
}
}
}

ExpectedOpResult::ExpectedOpResult(OperationResultCode code)
{
mOperationResult.code(code);
Expand Down Expand Up @@ -546,6 +587,9 @@ closeLedgerOn(Application& app, uint32 ledgerSeq, TimePoint closeTime,
// Ensure that parallelSorobanOrder is only used with strictOrder
releaseAssert((parallelSorobanOrder.empty() || strictOrder));

// Ensure we're not trying to close a ledger that's already closed
releaseAssert(ledgerSeq > app.getLedgerManager().getLastClosedLedgerNum());

auto lastCloseTime = app.getLedgerManager()
.getLastClosedLedgerHeader()
.header.scpValue.closeTime;
Expand Down Expand Up @@ -600,6 +644,7 @@ closeLedgerOn(Application& app, uint32 ledgerSeq, TimePoint closeTime,
}
releaseAssert(app.getLedgerManager().getLastClosedLedgerNum() == ledgerSeq);
auto& lm = static_cast<LedgerManagerImpl&>(app.getLedgerManager());
captureLastClosedLedgerLcm(app);
return lm.mLatestTxResultSet;
}

Expand All @@ -625,6 +670,8 @@ closeLedgerOn(Application& app, uint32 ledgerSeq, time_t closeTime,

REQUIRE(app.getLedgerManager().getLastClosedLedgerNum() == ledgerSeq);

captureLastClosedLedgerLcm(app);

return z1;
}

Expand Down Expand Up @@ -1938,6 +1985,9 @@ executeUpgrades(Application& app, xdr::xvector<UpgradeType, 6> const& upgrades,
auto lastCloseTime = lcl.header.scpValue.closeTime;
app.getHerder().externalizeValue(txSet, lcl.header.ledgerSeq + 1,
lastCloseTime, upgrades);

captureLastClosedLedgerLcm(app);

if (upgradesIgnored)
{
auto const& newHeader = lm.getLastClosedLedgerHeader().header;
Expand Down
9 changes: 9 additions & 0 deletions src/test/TxTests.h
Original file line number Diff line number Diff line change
Expand Up @@ -380,5 +380,14 @@ bool isSuccessResult(TransactionResult const& res);

TestAccount getGenesisAccount(Application& app, uint32_t accountIndex);

// Accumulated LedgerCloseMeta from closeLedger/closeLedgerOn calls.
// Only accumulates when --capture-lcm is passed on the test command line.
// Note: LCM capture does not cover BucketTestUtils::closeLedger or direct
// externalizeValue calls (e.g. genesis ledger from app->start()).
std::vector<LedgerCloseMeta> const& getAccumulatedLcm();
void clearAccumulatedLcm();
void appendToAccumulatedLcm(LedgerCloseMeta const& lcm);
void captureLastClosedLedgerLcm(Application& app);

} // end txtest namespace
}
Loading
Loading