Allow a ledger close to be replayed for debug. Syntax: rippled -a --load --ledger=<seq> --replay

This commit is contained in:
JoelKatz
2013-07-17 03:31:23 -07:00
parent 00b0663e50
commit 65d46752df
5 changed files with 48 additions and 8 deletions

View File

@@ -14,7 +14,8 @@ DatabaseCon::DatabaseCon (const std::string& strName, const char* initStrings[],
// responsibility to pass in the path. Add a member function to Application
// or Config to compute this path.
//
boost::filesystem::path pPath = (theConfig.RUN_STANDALONE && (theConfig.START_UP != Config::LOAD))
boost::filesystem::path pPath = (theConfig.RUN_STANDALONE &&
((theConfig.START_UP != Config::LOAD) && (theConfig.START_UP != Config::REPLAY)))
? "" // Use temporary files.
: (theConfig.DATA_DIR / strName); // Use regular db files.

View File

@@ -101,6 +101,7 @@ public:
FRESH,
NORMAL,
LOAD,
REPLAY,
NETWORK
};
StartUpType START_UP;

View File

@@ -1132,6 +1132,10 @@ Json::Value RPCHandler::doAccountLines (Json::Value params, LoadType* loadType,
jPeer["limit_peer"] = saLimitPeer.getText ();
jPeer["quality_in"] = static_cast<Json::UInt> (line->getQualityIn ());
jPeer["quality_out"] = static_cast<Json::UInt> (line->getQualityOut ());
if (line->getAuth())
jPeer["authorized"] = true;
if (line->getAuthPeer())
jPeer["peer_authorized"] = true;
}
}
@@ -3681,7 +3685,7 @@ Json::Value RPCHandler::doCommand (const Json::Value& params, int iRole, LoadTyp
return rpcError (rpcNO_NETWORK);
}
if ((commandsA[i].iOptions & optCurrent) && (getApp().getLedgerMaster().getValidatedLedgerAge() > 120))
if (!theConfig.RUN_STANDALONE && (commandsA[i].iOptions & optCurrent) && (getApp().getLedgerMaster().getValidatedLedgerAge() > 120))
{
return rpcError (rpcNO_CURRENT);
}

View File

@@ -281,7 +281,7 @@ public:
private:
void updateTables ();
void startNewLedger ();
bool loadOldLedger (const std::string&);
bool loadOldLedger (const std::string&, bool);
private:
boost::asio::io_service mIOService;
@@ -478,11 +478,11 @@ void ApplicationImp::setup ()
startNewLedger ();
}
else if (theConfig.START_UP == Config::LOAD)
else if ((theConfig.START_UP == Config::LOAD) || (theConfig.START_UP == Config::REPLAY))
{
WriteLog (lsINFO, Application) << "Loading specified Ledger";
if (!loadOldLedger (theConfig.START_LEDGER))
if (!loadOldLedger (theConfig.START_LEDGER, theConfig.START_UP == Config::REPLAY))
{
getApp().stop ();
exit (-1);
@@ -733,11 +733,11 @@ void ApplicationImp::startNewLedger ()
}
}
bool ApplicationImp::loadOldLedger (const std::string& l)
bool ApplicationImp::loadOldLedger (const std::string& l, bool bReplay)
{
try
{
Ledger::pointer loadLedger;
Ledger::pointer loadLedger, replayLedger;
if (l.empty () || (l == "latest"))
loadLedger = Ledger::getLastFullLedger ();
@@ -757,6 +757,18 @@ bool ApplicationImp::loadOldLedger (const std::string& l)
return false;
}
if (bReplay)
{ // Replay a ledger close with same prior ledger and transactions
replayLedger = loadLedger; // this ledger holds the transactions we want to replay
loadLedger = Ledger::loadByIndex (replayLedger->getLedgerSeq() - 1); // this is the prior ledger
if (!loadLedger || (replayLedger->getParentHash() != loadLedger->getHash()))
{
WriteLog (lsFATAL, Application) << "Replay ledger missing/damaged";
assert (false);
return false;
}
}
loadLedger->setClosed ();
WriteLog (lsINFO, Application) << "Loading ledger " << loadLedger->getHash () << " seq:" << loadLedger->getLedgerSeq ();
@@ -785,6 +797,24 @@ bool ApplicationImp::loadOldLedger (const std::string& l)
Ledger::pointer openLedger = boost::make_shared<Ledger> (false, boost::ref (*loadLedger));
mLedgerMaster.switchLedgers (loadLedger, openLedger);
mNetOps.setLastCloseTime (loadLedger->getCloseTimeNC ());
if (bReplay)
{ // inject transaction from replayLedger into consensus set
SHAMap::ref txns = replayLedger->peekTransactionMap();
Ledger::ref cur = getLedgerMaster().getCurrentLedger();
for (SHAMapItem::pointer it = txns->peekFirstItem(); it != nullptr; it = txns->peekNextItem(it->getTag()))
{
Transaction::pointer txn = replayLedger->getTransaction(it->getTag());
WriteLog (lsINFO, Application) << txn->getJson(0);
Serializer s;
txn->getSTransaction()->add(s);
if (!cur->addTransaction(it->getTag(), s))
{
WriteLog (lsWARNING, Application) << "Unable to add transaction " << it->getTag();
}
}
}
}
catch (SHAMapMissingNode&)
{

View File

@@ -237,6 +237,7 @@ int rippleMain (int argc, char** argv)
("quiet,q", "Reduce diagnotics.")
("verbose,v", "Verbose logging.")
("load", "Load the current ledger from the local DB.")
("replay","Replay a ledger close.")
("ledger", po::value<std::string> (), "Load the specified ledger and start from .")
("start", "Start from a fresh Ledger.")
("net", "Get the initial ledger from the network.")
@@ -356,6 +357,9 @@ int rippleMain (int argc, char** argv)
if (vm.count ("ledger"))
{
theConfig.START_LEDGER = vm["ledger"].as<std::string> ();
if (vm.count("replay"))
theConfig.START_UP = Config::REPLAY;
else
theConfig.START_UP = Config::LOAD;
}
else if (vm.count ("load"))