Skip to content
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

Add new command line option to make replaying transactions easier #5027

Merged
merged 8 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from 6 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
32 changes: 29 additions & 3 deletions src/ripple/app/main/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ class ApplicationImp : public Application, public BasicApp
std::unique_ptr<RelationalDatabase> mRelationalDatabase;
std::unique_ptr<DatabaseCon> mWalletDB;
std::unique_ptr<Overlay> overlay_;
std::optional<uint256> trapTxID_;

boost::asio::signal_set m_signals;

Expand Down Expand Up @@ -1254,6 +1255,12 @@ class ApplicationImp : public Application, public BasicApp
return maxDisallowedLedger_;
}

virtual const std::optional<uint256>&
trapTxID() const override
{
return trapTxID_;
}

private:
// For a newly-started validator, this is the greatest persisted ledger
// and new validations must be greater than this.
Expand All @@ -1272,7 +1279,11 @@ class ApplicationImp : public Application, public BasicApp
loadLedgerFromFile(std::string const& ledgerID);

bool
loadOldLedger(std::string const& ledgerID, bool replay, bool isFilename);
loadOldLedger(
std::string const& ledgerID,
bool replay,
bool isFilename,
std::optional<uint256> trapTxID);

void
setMaxDisallowedLedger();
Expand Down Expand Up @@ -1404,7 +1415,8 @@ ApplicationImp::setup(boost::program_options::variables_map const& cmdline)
if (!loadOldLedger(
config_->START_LEDGER,
startUp == Config::REPLAY,
startUp == Config::LOAD_FILE))
startUp == Config::LOAD_FILE,
config_->TRAP_TX_HASH))
{
JLOG(m_journal.error())
<< "The specified ledger could not be loaded.";
Expand Down Expand Up @@ -2086,7 +2098,8 @@ bool
ApplicationImp::loadOldLedger(
std::string const& ledgerID,
bool replay,
bool isFileName)
bool isFileName,
std::optional<uint256> trapTxID)
{
try
{
Expand Down Expand Up @@ -2233,6 +2246,11 @@ ApplicationImp::loadOldLedger(
{
(void)_;
auto txID = tx->getTransactionID();
if (trapTxID == txID)
{
trapTxID_ = txID;
JLOG(m_journal.debug()) << "Trap transaction set: " << txID;
}

auto s = std::make_shared<Serializer>();
tx->add(*s);
Expand All @@ -2247,6 +2265,14 @@ ApplicationImp::loadOldLedger(
}

m_ledgerMaster->takeReplay(std::move(replayData));

if (trapTxID && !trapTxID_)
{
JLOG(m_journal.fatal())
<< "Ledger " << replayLedger->info().seq
<< " does not contain the transaction hash " << *trapTxID;
return false;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we return false in this case or just log? The semantics of this call is to return false if the ledger fails to load.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's intentional - you only use this functionality when replaying a transaction, and failing a little earlier (still need several minutes to load that ledger) will save your time.

}
}
}
catch (SHAMapMissingNode const& mn)
Expand Down
3 changes: 3 additions & 0 deletions src/ripple/app/main/Application.h
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,9 @@ class Application : public beast::PropertyStream::Source
* than the last ledger it persisted. */
virtual LedgerIndex
getMaxDisallowedLedger() = 0;

virtual const std::optional<uint256>&
trapTxID() const = 0;
};

std::unique_ptr<Application>
Expand Down
30 changes: 30 additions & 0 deletions src/ripple/app/main/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,9 @@ run(int argc, char** argv)
"net", "Get the initial ledger from the network.")(
"nodetoshard", "Import node store into shards")(
"replay", "Replay a ledger close.")(
"trap_tx_hash",
po::value<std::string>(),
"Trap a specific transaction during replay.")(
"start", "Start from a fresh Ledger.")(
"startReporting",
po::value<std::string>(),
Expand Down Expand Up @@ -558,6 +561,7 @@ run(int argc, char** argv)
argc,
argv);
}
// LCOV_EXCL_START
else
{
if (vm.count("unittest-jobs"))
Expand Down Expand Up @@ -679,7 +683,25 @@ run(int argc, char** argv)
{
config->START_LEDGER = vm["ledger"].as<std::string>();
if (vm.count("replay"))
{
config->START_UP = Config::REPLAY;
if (vm.count("trap_tx_hash"))
{
uint256 tmp = {};
auto hash = vm["trap_tx_hash"].as<std::string>();
if (tmp.parseHex(hash))
{
config->TRAP_TX_HASH = tmp;
}
else
{
std::cerr << "Trap parameter was ill-formed, expected "
"valid transaction hash but received: "
<< hash << std::endl;
return -1;
}
}
}
else
config->START_UP = Config::LOAD;
}
Expand All @@ -693,6 +715,13 @@ run(int argc, char** argv)
config->START_UP = Config::LOAD;
}

if (vm.count("trap_tx_hash") && vm.count("replay") == 0)
{
std::cerr << "Cannot use trap option without replay option"
<< std::endl;
return -1;
}

if (vm.count("net") && !config->FAST_LOAD)
{
if ((config->START_UP == Config::LOAD) ||
Expand Down Expand Up @@ -828,6 +857,7 @@ run(int argc, char** argv)
beast::setCurrentThreadName("rippled: rpc");
return RPCCall::fromCommandLine(
*config, vm["parameters"].as<std::vector<std::string>>(), *logs);
// LCOV_EXCL_STOP
}

} // namespace ripple
Expand Down
6 changes: 6 additions & 0 deletions src/ripple/app/tx/impl/Transactor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,12 @@ Transactor::operator()()
}
#endif

if (auto const& trap = ctx_.app.trapTxID();
trap && *trap == ctx_.tx.getTransactionID())
{
JLOG(j_.debug()) << "Transaction trapped: " << *trap;
}

auto result = ctx_.preclaimResult;
if (result == tesSUCCESS)
result = apply();
Expand Down
2 changes: 2 additions & 0 deletions src/ripple/core/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ class Config : public BasicConfig

std::string START_LEDGER;

std::optional<uint256> TRAP_TX_HASH = {};
Bronek marked this conversation as resolved.
Show resolved Hide resolved

// Network parameters
uint32_t NETWORK_ID = 0;

Expand Down
Loading
Loading