Simplify and fix possible bugs in the way accepted ledgers are written

to SQL. Set up for ledger scraping.
This commit is contained in:
JoelKatz
2013-03-11 23:20:26 -07:00
parent 01655f4fe1
commit 1cd65213d8

View File

@@ -405,7 +405,9 @@ void Ledger::saveAcceptedLedger(Job&, bool fromConsensus)
cLog(lsTRACE) << "saveAcceptedLedger " << (fromConsensus ? "fromConsensus " : "fromAcquire ") << getLedgerSeq(); cLog(lsTRACE) << "saveAcceptedLedger " << (fromConsensus ? "fromConsensus " : "fromAcquire ") << getLedgerSeq();
static boost::format ledgerExists("SELECT LedgerSeq FROM Ledgers INDEXED BY SeqLedger where LedgerSeq = %u;"); static boost::format ledgerExists("SELECT LedgerSeq FROM Ledgers INDEXED BY SeqLedger where LedgerSeq = %u;");
static boost::format deleteLedger("DELETE FROM Ledgers WHERE LedgerSeq = %u;"); static boost::format deleteLedger("DELETE FROM Ledgers WHERE LedgerSeq = %u;");
static boost::format AcctTransExists("SELECT LedgerSeq FROM AccountTransactions WHERE TransID = '%s';"); static boost::format deleteTrans1("DELETE FROM Transactions WHERE LedgerSeq = %u;");
static boost::format deleteTrans2("DELETE FROM AccountTransactions WHERE LedgerSeq = %u;");
static boost::format deleteAcctTrans("DELTEE FROM AccountTransactions WHERE TransID = '%s';");
static boost::format transExists("SELECT Status FROM Transactions WHERE TransID = '%s';"); static boost::format transExists("SELECT Status FROM Transactions WHERE TransID = '%s';");
static boost::format static boost::format
updateTx("UPDATE Transactions SET LedgerSeq = %u, Status = '%c', TxnMeta = %s WHERE TransID = '%s';"); updateTx("UPDATE Transactions SET LedgerSeq = %u, Status = '%c', TxnMeta = %s WHERE TransID = '%s';");
@@ -431,88 +433,83 @@ void Ledger::saveAcceptedLedger(Job&, bool fromConsensus)
AcceptedLedger::pointer aLedger = AcceptedLedger::makeAcceptedLedger(shared_from_this()); AcceptedLedger::pointer aLedger = AcceptedLedger::makeAcceptedLedger(shared_from_this());
{ {
{ ScopedLock sl(theApp->getLedgerDB()->getDBLock());
ScopedLock sl(theApp->getLedgerDB()->getDBLock()); theApp->getLedgerDB()->getDB()->executeSQL(boost::str(deleteLedger % mLedgerSeq));
if (SQL_EXISTS(theApp->getLedgerDB()->getDB(), boost::str(ledgerExists % mLedgerSeq))) }
theApp->getLedgerDB()->getDB()->executeSQL(boost::str(deleteLedger % mLedgerSeq));
}
{
Database *db = theApp->getTxnDB()->getDB(); Database *db = theApp->getTxnDB()->getDB();
{ ScopedLock dbLock(theApp->getTxnDB()->getDBLock());
ScopedLock dbLock(theApp->getTxnDB()->getDBLock()); db->executeSQL("BEGIN TRANSACTION;");
db->executeSQL("BEGIN TRANSACTION;");
BOOST_FOREACH(const AcceptedLedger::value_type& vt, aLedger->getMap()) db->executeSQL(boost::str(deleteTrans1 % mLedgerSeq));
db->executeSQL(boost::str(deleteTrans2 % mLedgerSeq));
BOOST_FOREACH(const AcceptedLedger::value_type& vt, aLedger->getMap())
{
uint256 txID = vt.second.getTransactionID();
theApp->getMasterTransaction().inLedger(txID, mLedgerSeq);
db->executeSQL(boost::str(deleteAcctTrans % txID.GetHex()));
const std::vector<RippleAddress>& accts = vt.second.getAffected();
if (!accts.empty())
{ {
cLog(lsTRACE) << "Saving: " << vt.second.getJson(0); std::string sql = "INSERT OR REPLACE INTO AccountTransactions (TransID, Account, LedgerSeq) VALUES ";
uint256 txID = vt.second.getTransactionID(); bool first = true;
theApp->getMasterTransaction().inLedger(txID, mLedgerSeq); for (std::vector<RippleAddress>::const_iterator it = accts.begin(), end = accts.end(); it != end; ++it)
// Make sure transaction is in AccountTransactions.
if (!SQL_EXISTS(db, boost::str(AcctTransExists % txID.GetHex())))
{ {
// Transaction not in AccountTransactions if (!first)
const std::vector<RippleAddress>& accts = vt.second.getAffected(); sql += ", ('";
if (!accts.empty())
{
std::string sql = "INSERT OR REPLACE INTO AccountTransactions (TransID, Account, LedgerSeq) VALUES ";
bool first = true;
for (std::vector<RippleAddress>::const_iterator it = accts.begin(), end = accts.end(); it != end; ++it)
{
if (!first)
sql += ", ('";
else
{
sql += "('";
first = false;
}
sql += txID.GetHex();
sql += "','";
sql += it->humanAccountID();
sql += "',";
sql += boost::lexical_cast<std::string>(getLedgerSeq());
sql += ")";
}
sql += ";";
Log(lsTRACE) << "ActTx: " << sql;
db->executeSQL(sql); // may already be in there
}
else else
cLog(lsWARNING) << "Transaction in ledger " << mLedgerSeq << " affects no accounts"; {
} sql += "('";
first = false;
if (SQL_EXISTS(db, boost::str(transExists % txID.GetHex()))) }
{ sql += txID.GetHex();
// In Transactions, update LedgerSeq, metadata and Status. sql += "','";
db->executeSQL(boost::str(updateTx sql += it->humanAccountID();
% getLedgerSeq() sql += "',";
% TXN_SQL_VALIDATED sql += boost::lexical_cast<std::string>(getLedgerSeq());
% vt.second.getEscMeta() sql += ")";
% txID.GetHex()));
}
else
{
// Not in Transactions, insert the whole thing..
db->executeSQL(
SerializedTransaction::getMetaSQLInsertHeader() +
vt.second.getTxn()->getMetaSQL(getLedgerSeq(), vt.second.getEscMeta()) + ";");
} }
sql += ";";
Log(lsTRACE) << "ActTx: " << sql;
db->executeSQL(sql); // may already be in there
} }
db->executeSQL("COMMIT TRANSACTION;"); else
} cLog(lsWARNING) << "Transaction in ledger " << mLedgerSeq << " affects no accounts";
if (!theConfig.RUN_STANDALONE) if (SQL_EXISTS(db, boost::str(transExists % txID.GetHex())))
theApp->getHashedObjectStore().waitWrite(); // wait until all nodes are written {
// In Transactions, update LedgerSeq, metadata and Status.
{ db->executeSQL(boost::str(updateTx
ScopedLock sl(theApp->getLedgerDB()->getDBLock()); % getLedgerSeq()
theApp->getLedgerDB()->getDB()->executeSQL(boost::str(addLedger % % TXN_SQL_VALIDATED
getHash().GetHex() % mLedgerSeq % mParentHash.GetHex() % % vt.second.getEscMeta()
boost::lexical_cast<std::string>(mTotCoins) % mCloseTime % mParentCloseTime % % txID.GetHex()));
mCloseResolution % mCloseFlags % }
mAccountHash.GetHex() % mTransHash.GetHex())); else
{
// Not in Transactions, insert the whole thing..
db->executeSQL(
SerializedTransaction::getMetaSQLInsertHeader() +
vt.second.getTxn()->getMetaSQL(getLedgerSeq(), vt.second.getEscMeta()) + ";");
}
} }
db->executeSQL("COMMIT TRANSACTION;");
}
if (!theConfig.RUN_STANDALONE)
theApp->getHashedObjectStore().waitWrite(); // wait until all nodes are written
{
ScopedLock sl(theApp->getLedgerDB()->getDBLock());
theApp->getLedgerDB()->getDB()->executeSQL(boost::str(addLedger %
getHash().GetHex() % mLedgerSeq % mParentHash.GetHex() %
boost::lexical_cast<std::string>(mTotCoins) % mCloseTime % mParentCloseTime %
mCloseResolution % mCloseFlags %
mAccountHash.GetHex() % mTransHash.GetHex()));
} }
if (!fromConsensus) if (!fromConsensus)