Reprocess accepted ledgers once. Track metadata, transaction data, and affected accounts.

Process to SQL database and publish from this structure.
Include number of transactions in ledger publish info.
Publish transactions in applied order.
This commit is contained in:
JoelKatz
2013-03-04 13:59:53 -08:00
parent dd398b7eb9
commit 51db2d2cd7
14 changed files with 152 additions and 77 deletions

View File

@@ -96,6 +96,7 @@
<ClCompile Include="src\cpp\json\json_reader.cpp" /> <ClCompile Include="src\cpp\json\json_reader.cpp" />
<ClCompile Include="src\cpp\json\json_value.cpp" /> <ClCompile Include="src\cpp\json\json_value.cpp" />
<ClCompile Include="src\cpp\json\json_writer.cpp" /> <ClCompile Include="src\cpp\json\json_writer.cpp" />
<ClCompile Include="src\cpp\ripple\AcceptedLedger.cpp" />
<ClCompile Include="src\cpp\ripple\AccountItems.cpp" /> <ClCompile Include="src\cpp\ripple\AccountItems.cpp" />
<ClCompile Include="src\cpp\ripple\AccountSetTransactor.cpp" /> <ClCompile Include="src\cpp\ripple\AccountSetTransactor.cpp" />
<ClCompile Include="src\cpp\ripple\AccountState.cpp" /> <ClCompile Include="src\cpp\ripple\AccountState.cpp" />
@@ -205,6 +206,7 @@
<ClInclude Include="database\sqlite3.h" /> <ClInclude Include="database\sqlite3.h" />
<ClInclude Include="database\sqlite3ext.h" /> <ClInclude Include="database\sqlite3ext.h" />
<ClInclude Include="database\SqliteDatabase.h" /> <ClInclude Include="database\SqliteDatabase.h" />
<ClInclude Include="src\cpp\ripple\AcceptedLedger.h" />
<ClInclude Include="src\cpp\ripple\AccountItems.h" /> <ClInclude Include="src\cpp\ripple\AccountItems.h" />
<ClInclude Include="src\cpp\ripple\AccountSetTransactor.h" /> <ClInclude Include="src\cpp\ripple\AccountSetTransactor.h" />
<ClInclude Include="src\cpp\ripple\AccountState.h" /> <ClInclude Include="src\cpp\ripple\AccountState.h" />

View File

@@ -345,6 +345,9 @@
<ClCompile Include="src\cpp\ripple\Offer.cpp"> <ClCompile Include="src\cpp\ripple\Offer.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\cpp\ripple\AcceptedLedger.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\cpp\ripple\AccountItems.cpp"> <ClCompile Include="src\cpp\ripple\AccountItems.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
@@ -662,6 +665,9 @@
<ClInclude Include="src\cpp\ripple\Offer.h"> <ClInclude Include="src\cpp\ripple\Offer.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="src\cpp\ripple\AcceptedLedger.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\cpp\ripple\AccountItems.h"> <ClInclude Include="src\cpp\ripple\AccountItems.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>

View File

@@ -94,6 +94,7 @@
<ClCompile Include="src\cpp\json\json_reader.cpp" /> <ClCompile Include="src\cpp\json\json_reader.cpp" />
<ClCompile Include="src\cpp\json\json_value.cpp" /> <ClCompile Include="src\cpp\json\json_value.cpp" />
<ClCompile Include="src\cpp\json\json_writer.cpp" /> <ClCompile Include="src\cpp\json\json_writer.cpp" />
<ClCompile Include="src\cpp\ripple\AcceptedLedger.cpp" />
<ClCompile Include="src\cpp\ripple\AccountItems.cpp" /> <ClCompile Include="src\cpp\ripple\AccountItems.cpp" />
<ClCompile Include="src\cpp\ripple\AccountSetTransactor.cpp" /> <ClCompile Include="src\cpp\ripple\AccountSetTransactor.cpp" />
<ClCompile Include="src\cpp\ripple\AccountState.cpp" /> <ClCompile Include="src\cpp\ripple\AccountState.cpp" />

View File

@@ -345,6 +345,9 @@
<ClCompile Include="src\cpp\ripple\LoadManager.cpp"> <ClCompile Include="src\cpp\ripple\LoadManager.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\cpp\ripple\AcceptedLedger.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\cpp\ripple\AccountItems.cpp"> <ClCompile Include="src\cpp\ripple\AccountItems.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>

View File

@@ -1,13 +1,59 @@
#include "AcceptedLedger.h" #include "AcceptedLedger.h"
#include <boost/foreach.hpp>
TaggedCache<uint256, AcceptedLedger> AcceptedLedger::ALCache("AcceptedLedger", 4, 60);
ALTransaction::ALTransaction(uint32 seq, SerializerIterator& sit) ALTransaction::ALTransaction(uint32 seq, SerializerIterator& sit)
{ {
Serializer txnSer(sit.getVL()); Serializer txnSer(sit.getVL());
SerializerIterator txnIt(txnSer); SerializerIterator txnIt(txnSer);
mTxn = boost::make_shared<SerializedTransaction>(boost::ref(txnIt)); mTxn = boost::make_shared<SerializedTransaction>(boost::ref(txnIt));
mMeta = boost::make_shared<TransactionMetaSet>(mTxn->getTransactionID(), seq, sit.getVL()); mRawMeta= sit.getVL();
mMeta = boost::make_shared<TransactionMetaSet>(mTxn->getTransactionID(), seq, mRawMeta);
mAffected = mMeta->getAffectedAccounts(); mAffected = mMeta->getAffectedAccounts();
mResult = mMeta->getResultTER();
}
ALTransaction::ALTransaction(SerializedTransaction::ref txn, TransactionMetaSet::ref met) :
mTxn(txn), mMeta(met), mAffected(met->getAffectedAccounts())
{
mResult = mMeta->getResultTER();
}
ALTransaction::ALTransaction(SerializedTransaction::ref txn, TER result) :
mTxn(txn), mResult(result), mAffected(txn->getMentionedAccounts())
{ ; }
std::string ALTransaction::getEscMeta() const
{
assert(!mRawMeta.empty());
return sqlEscape(mRawMeta);
}
Json::Value ALTransaction::getJson(int j) const
{
Json::Value ret(Json::objectValue);
ret["transaction"] = mTxn->getJson(j);
if (mMeta)
{
ret["meta"] = mMeta->getJson(j);
ret["raw_meta"] = strHex(mRawMeta);
}
ret["result"] = transHuman(mResult);
if (!mAffected.empty())
{
Json::Value affected(Json::arrayValue);
BOOST_FOREACH(const RippleAddress& ra, mAffected)
{
affected.append(ra.humanAccountID());
}
ret["affected"] = affected;
}
return ret;
} }
AcceptedLedger::AcceptedLedger(Ledger::ref ledger) : mLedger(ledger) AcceptedLedger::AcceptedLedger(Ledger::ref ledger) : mLedger(ledger)
@@ -20,6 +66,16 @@ AcceptedLedger::AcceptedLedger(Ledger::ref ledger) : mLedger(ledger)
} }
} }
AcceptedLedger::pointer AcceptedLedger::makeAcceptedLedger(Ledger::ref ledger)
{
AcceptedLedger::pointer ret = ALCache.fetch(ledger->getHash());
if (ret)
return ret;
ret = AcceptedLedger::pointer(new AcceptedLedger(ledger));
ALCache.canonicalize(ledger->getHash(), ret);
return ret;
}
void AcceptedLedger::insert(const ALTransaction& at) void AcceptedLedger::insert(const ALTransaction& at)
{ {
assert(mMap.find(at.getIndex()) == mMap.end()); assert(mMap.find(at.getIndex()) == mMap.end());
@@ -32,4 +88,4 @@ const ALTransaction* AcceptedLedger::getTxn(int i) const
if (it == mMap.end()) if (it == mMap.end())
return NULL; return NULL;
return &it->second; return &it->second;
} }

View File

@@ -11,25 +11,38 @@ class ALTransaction
protected: protected:
SerializedTransaction::pointer mTxn; SerializedTransaction::pointer mTxn;
TransactionMetaSet::pointer mMeta; TransactionMetaSet::pointer mMeta;
TER mResult;
std::vector<RippleAddress> mAffected; std::vector<RippleAddress> mAffected;
std::vector<unsigned char> mRawMeta;
public: public:
ALTransaction(uint32 ledgerSeq, SerializerIterator& sit); ALTransaction(uint32 ledgerSeq, SerializerIterator& sit);
ALTransaction(SerializedTransaction::ref, TransactionMetaSet::ref);
ALTransaction(SerializedTransaction::ref, TER result);
SerializedTransaction::ref getTxn() const { return mTxn; } SerializedTransaction::ref getTxn() const { return mTxn; }
TransactionMetaSet::ref getMeta() const { return mMeta; } TransactionMetaSet::ref getMeta() const { return mMeta; }
const std::vector<RippleAddress>& getAffected() const { return mAffected; } const std::vector<RippleAddress>& getAffected() const { return mAffected; }
int getIndex() const { return mMeta->getIndex(); }
TER getResult() const { return mMeta->getResultTER(); } uint256 getTransactionID() const { return mTxn->getTransactionID(); }
TransactionType getTxnType() const { return mTxn->getTxnType(); }
TER getResult() const { return mResult; }
bool isApplied() const { return !!mMeta; }
int getIndex() const { return mMeta ? mMeta->getIndex() : 0; }
std::string getEscMeta() const;
Json::Value getJson(int) const;
}; };
class AcceptedLedger class AcceptedLedger
{ {
public: public:
typedef std::map<int, ALTransaction> map_t; typedef boost::shared_ptr<AcceptedLedger> pointer;
typedef map_t::value_type value_type; typedef const pointer& ret;
typedef map_t::const_iterator const_iterator; typedef std::map<int, ALTransaction> map_t;
typedef map_t::value_type value_type;
typedef map_t::const_iterator const_iterator;
protected: protected:
Ledger::pointer mLedger; Ledger::pointer mLedger;
@@ -37,9 +50,14 @@ protected:
void insert(const ALTransaction&); void insert(const ALTransaction&);
public: static TaggedCache<uint256, AcceptedLedger> ALCache;
AcceptedLedger(Ledger::ref ledger); AcceptedLedger(Ledger::ref ledger);
public:
static pointer makeAcceptedLedger(Ledger::ref ledger);
static void sweep() { ALCache.sweep(); }
Ledger::ref getLedger() const { return mLedger; } Ledger::ref getLedger() const { return mLedger; }
const map_t& getMap() const { return mMap; } const map_t& getMap() const { return mMap; }

View File

@@ -1,5 +1,6 @@
#include "Application.h" #include "Application.h"
#include "AcceptedLedger.h"
#include "Config.h" #include "Config.h"
#include "PeerDoor.h" #include "PeerDoor.h"
#include "RPCDoor.h" #include "RPCDoor.h"
@@ -303,6 +304,7 @@ void Application::sweep()
mValidations.sweep(); mValidations.sweep();
getMasterLedgerAcquire().sweep(); getMasterLedgerAcquire().sweep();
mSLECache.sweep(); mSLECache.sweep();
AcceptedLedger::sweep();
mSweepTimer.expires_from_now(boost::posix_time::seconds(theConfig.getSize(siSweepInterval))); mSweepTimer.expires_from_now(boost::posix_time::seconds(theConfig.getSize(siSweepInterval)));
mSweepTimer.async_wait(boost::bind(&Application::sweep, this)); mSweepTimer.async_wait(boost::bind(&Application::sweep, this));
} }

View File

@@ -428,6 +428,8 @@ void Ledger::saveAcceptedLedger(bool fromConsensus, LoadEvent::pointer event)
addRaw(s); addRaw(s);
theApp->getHashedObjectStore().store(hotLEDGER, mLedgerSeq, s.peekData(), mHash); theApp->getHashedObjectStore().store(hotLEDGER, mLedgerSeq, s.peekData(), mHash);
AcceptedLedger::pointer aLedger = AcceptedLedger::makeAcceptedLedger(shared_from_this());
{ {
{ {
ScopedLock sl(theApp->getLedgerDB()->getDBLock()); ScopedLock sl(theApp->getLedgerDB()->getDBLock());
@@ -435,33 +437,22 @@ void Ledger::saveAcceptedLedger(bool fromConsensus, LoadEvent::pointer event)
theApp->getLedgerDB()->getDB()->executeSQL(boost::str(deleteLedger % mLedgerSeq)); theApp->getLedgerDB()->getDB()->executeSQL(boost::str(deleteLedger % mLedgerSeq));
} }
SHAMap& txSet = *peekTransactionMap();
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;");
SHAMapTreeNode::TNType type;
for (SHAMapItem::pointer item = txSet.peekFirstItem(type); !!item; BOOST_FOREACH(const AcceptedLedger::value_type& vt, aLedger->getMap())
item = txSet.peekNextItem(item->getTag(), type))
{ {
assert(type == SHAMapTreeNode::tnTRANSACTION_MD); cLog(lsTRACE) << "Saving: " << vt.second.getJson(0);
SerializerIterator sit(item->peekSerializer()); uint256 txID = vt.second.getTransactionID();
Serializer rawTxn(sit.getVL()); theApp->getMasterTransaction().inLedger(txID, mLedgerSeq);
Serializer rawMeta(sit.getVL());
std::string escMeta(sqlEscape(rawMeta.peekData()));
SerializerIterator txnIt(rawTxn);
SerializedTransaction txn(txnIt);
assert(txn.getTransactionID() == item->getTag());
TransactionMetaSet meta(item->getTag(), mLedgerSeq, rawMeta.peekData());
theApp->getMasterTransaction().inLedger(item->getTag(), mLedgerSeq);
// Make sure transaction is in AccountTransactions. // Make sure transaction is in AccountTransactions.
if (!SQL_EXISTS(db, boost::str(AcctTransExists % item->getTag().GetHex()))) if (!SQL_EXISTS(db, boost::str(AcctTransExists % txID.GetHex())))
{ {
// Transaction not in AccountTransactions // Transaction not in AccountTransactions
const std::vector<RippleAddress> accts = meta.getAffectedAccounts(); const std::vector<RippleAddress>& accts = vt.second.getAffected();
if (!accts.empty()) if (!accts.empty())
{ {
@@ -476,7 +467,7 @@ void Ledger::saveAcceptedLedger(bool fromConsensus, LoadEvent::pointer event)
sql += "('"; sql += "('";
first = false; first = false;
} }
sql += txn.getTransactionID().GetHex(); sql += txID.GetHex();
sql += "','"; sql += "','";
sql += it->humanAccountID(); sql += it->humanAccountID();
sql += "',"; sql += "',";
@@ -491,20 +482,21 @@ void Ledger::saveAcceptedLedger(bool fromConsensus, LoadEvent::pointer event)
cLog(lsWARNING) << "Transaction in ledger " << mLedgerSeq << " affects no accounts"; cLog(lsWARNING) << "Transaction in ledger " << mLedgerSeq << " affects no accounts";
} }
if (SQL_EXISTS(db, boost::str(transExists % txn.getTransactionID().GetHex()))) if (SQL_EXISTS(db, boost::str(transExists % txID.GetHex())))
{ {
// In Transactions, update LedgerSeq, metadata and Status. // In Transactions, update LedgerSeq, metadata and Status.
db->executeSQL(boost::str(updateTx db->executeSQL(boost::str(updateTx
% getLedgerSeq() % getLedgerSeq()
% TXN_SQL_VALIDATED % TXN_SQL_VALIDATED
% escMeta % vt.second.getEscMeta()
% txn.getTransactionID().GetHex())); % txID.GetHex()));
} }
else else
{ {
// Not in Transactions, insert the whole thing.. // Not in Transactions, insert the whole thing..
db->executeSQL( db->executeSQL(
txn.getMetaSQLInsertHeader() + txn.getMetaSQL(getLedgerSeq(), escMeta) + ";"); SerializedTransaction::getMetaSQLInsertHeader() +
vt.second.getTxn()->getMetaSQL(getLedgerSeq(), vt.second.getEscMeta()) + ";");
} }
} }
db->executeSQL("COMMIT TRANSACTION;"); db->executeSQL("COMMIT TRANSACTION;");

View File

@@ -119,11 +119,11 @@ Ledger::pointer LedgerMaster::closeLedger(bool recover)
return closingLedger; return closingLedger;
} }
TER LedgerMaster::doTransaction(const SerializedTransaction& txn, TransactionEngineParams params, bool& didApply) TER LedgerMaster::doTransaction(SerializedTransaction::ref txn, TransactionEngineParams params, bool& didApply)
{ {
TER result = mEngine.applyTransaction(txn, params, didApply); TER result = mEngine.applyTransaction(*txn, params, didApply);
// CHECKME: Should we call this even on gross failures? // if (didApply)
theApp->getOPs().pubProposedTransaction(mEngine.getLedger(), txn, result); theApp->getOPs().pubProposedTransaction(mEngine.getLedger(), txn, result);
return result; return result;
} }

View File

@@ -75,7 +75,7 @@ public:
// The published ledger is the last fully validated ledger // The published ledger is the last fully validated ledger
Ledger::ref getValidatedLedger() { return mPubLedger; } Ledger::ref getValidatedLedger() { return mPubLedger; }
TER doTransaction(const SerializedTransaction& txn, TransactionEngineParams params, bool& didApply); TER doTransaction(SerializedTransaction::ref txn, TransactionEngineParams params, bool& didApply);
void pushLedger(Ledger::ref newLedger); void pushLedger(Ledger::ref newLedger);
void pushLedger(Ledger::ref newLCL, Ledger::ref newOL, bool fromConsensus); void pushLedger(Ledger::ref newLCL, Ledger::ref newOL, bool fromConsensus);

View File

@@ -267,7 +267,7 @@ void NetworkOPs::runTransactionQueue()
assert(dbtx); assert(dbtx);
bool didApply; bool didApply;
TER r = mLedgerMaster->doTransaction(*dbtx->getSTransaction(), TER r = mLedgerMaster->doTransaction(dbtx->getSTransaction(),
tapOPEN_LEDGER | tapNO_CHECK_SIGN, didApply); tapOPEN_LEDGER | tapNO_CHECK_SIGN, didApply);
dbtx->setResult(r); dbtx->setResult(r);
@@ -352,7 +352,7 @@ Transaction::pointer NetworkOPs::processTransaction(Transaction::pointer trans,
boost::recursive_mutex::scoped_lock sl(theApp->getMasterLock()); boost::recursive_mutex::scoped_lock sl(theApp->getMasterLock());
Transaction::pointer dbtx = theApp->getMasterTransaction().fetch(trans->getID(), true); Transaction::pointer dbtx = theApp->getMasterTransaction().fetch(trans->getID(), true);
bool didApply; bool didApply;
TER r = mLedgerMaster->doTransaction(*trans->getSTransaction(), tapOPEN_LEDGER | tapNO_CHECK_SIGN, didApply); TER r = mLedgerMaster->doTransaction(trans->getSTransaction(), tapOPEN_LEDGER | tapNO_CHECK_SIGN, didApply);
trans->setResult(r); trans->setResult(r);
if (isTemMalformed(r)) // malformed, cache bad if (isTemMalformed(r)) // malformed, cache bad
@@ -1289,9 +1289,9 @@ Json::Value NetworkOPs::pubBootstrapAccountInfo(Ledger::ref lpAccepted, const Ri
return jvObj; return jvObj;
} }
void NetworkOPs::pubProposedTransaction(Ledger::ref lpCurrent, const SerializedTransaction& stTxn, TER terResult) void NetworkOPs::pubProposedTransaction(Ledger::ref lpCurrent, SerializedTransaction::ref stTxn, TER terResult)
{ {
Json::Value jvObj = transJson(stTxn, terResult, false, lpCurrent, "transaction"); Json::Value jvObj = transJson(*stTxn, terResult, false, lpCurrent, "transaction");
{ {
boost::recursive_mutex::scoped_lock sl(mMonitorLock); boost::recursive_mutex::scoped_lock sl(mMonitorLock);
@@ -1308,15 +1308,19 @@ void NetworkOPs::pubProposedTransaction(Ledger::ref lpCurrent, const SerializedT
it = mSubRTTransactions.erase(it); it = mSubRTTransactions.erase(it);
} }
} }
TransactionMetaSet::pointer ret; ALTransaction alt(stTxn, terResult);
pubAccountTransaction(lpCurrent,stTxn,terResult,false,ret); cLog(lsTRACE) << "pubProposed: " << alt.getJson(0);
pubAccountTransaction(lpCurrent, ALTransaction(stTxn, terResult));
} }
void NetworkOPs::pubLedger(Ledger::ref lpAccepted) void NetworkOPs::pubLedger(Ledger::ref accepted)
{ {
// Ledgers are published only when they acquire sufficient validations // Ledgers are published only when they acquire sufficient validations
// Holes are filled across connection loss or other catastrophe // Holes are filled across connection loss or other catastrophe
AcceptedLedger::pointer alpAccepted = AcceptedLedger::makeAcceptedLedger(accepted);
Ledger::ref lpAccepted = alpAccepted->getLedger();
{ {
boost::recursive_mutex::scoped_lock sl(mMonitorLock); boost::recursive_mutex::scoped_lock sl(mMonitorLock);
@@ -1334,6 +1338,8 @@ void NetworkOPs::pubLedger(Ledger::ref lpAccepted)
jvObj["reserve_base"] = Json::UInt(lpAccepted->getReserve(0)); jvObj["reserve_base"] = Json::UInt(lpAccepted->getReserve(0));
jvObj["reserve_inc"] = Json::UInt(lpAccepted->getReserveInc()); jvObj["reserve_inc"] = Json::UInt(lpAccepted->getReserveInc());
jvObj["txn_count"] = Json::UInt(alpAccepted->getTxnCount());
NetworkOPs::subMapType::const_iterator it = mSubLedger.begin(); NetworkOPs::subMapType::const_iterator it = mSubLedger.begin();
while (it != mSubLedger.end()) while (it != mSubLedger.end())
{ {
@@ -1352,21 +1358,10 @@ void NetworkOPs::pubLedger(Ledger::ref lpAccepted)
// Don't lock since pubAcceptedTransaction is locking. // Don't lock since pubAcceptedTransaction is locking.
if (!mSubTransactions.empty() || !mSubRTTransactions.empty() || !mSubAccount.empty() || !mSubRTAccount.empty()) if (!mSubTransactions.empty() || !mSubRTTransactions.empty() || !mSubAccount.empty() || !mSubRTAccount.empty())
{ {
SHAMap& txSet = *lpAccepted->peekTransactionMap(); BOOST_FOREACH(const AcceptedLedger::value_type& vt, alpAccepted->getMap())
for (SHAMapItem::pointer item = txSet.peekFirstItem(); !!item; item = txSet.peekNextItem(item->getTag()))
{ {
SerializerIterator it(item->peekSerializer()); cLog(lsTRACE) << "pubAccepted: " << vt.second.getJson(0);
pubAcceptedTransaction(lpAccepted, vt.second);
// OPTIMIZEME: Could get transaction from txn master, but still must call getVL
Serializer txnSer(it.getVL());
SerializerIterator txnIt(txnSer);
SerializedTransaction stTxn(txnIt);
TransactionMetaSet::pointer meta = boost::make_shared<TransactionMetaSet>(
stTxn.getTransactionID(), lpAccepted->getLedgerSeq(), it.getVL());
pubAcceptedTransaction(lpAccepted, stTxn, meta->getResultTER(), meta);
} }
} }
} }
@@ -1407,11 +1402,10 @@ Json::Value NetworkOPs::transJson(const SerializedTransaction& stTxn, TER terRes
return jvObj; return jvObj;
} }
void NetworkOPs::pubAcceptedTransaction(Ledger::ref lpCurrent, const SerializedTransaction& stTxn, TER terResult,TransactionMetaSet::pointer& meta) void NetworkOPs::pubAcceptedTransaction(Ledger::ref alAccepted, const ALTransaction& alTx)
{ {
Json::Value jvObj = transJson(stTxn, terResult, true, lpCurrent, "transaction"); Json::Value jvObj = transJson(*alTx.getTxn(), alTx.getResult(), true, alAccepted, "transaction");
jvObj["meta"] = alTx.getMeta()->getJson(0);
if (meta) jvObj["meta"] = meta->getJson(0);
{ {
boost::recursive_mutex::scoped_lock sl(mMonitorLock); boost::recursive_mutex::scoped_lock sl(mMonitorLock);
@@ -1442,14 +1436,14 @@ void NetworkOPs::pubAcceptedTransaction(Ledger::ref lpCurrent, const SerializedT
it = mSubRTTransactions.erase(it); it = mSubRTTransactions.erase(it);
} }
} }
theApp->getOrderBookDB().processTxn(stTxn, terResult, meta, jvObj); theApp->getOrderBookDB().processTxn(alAccepted, alTx, jvObj);
pubAccountTransaction(alAccepted, alTx);
pubAccountTransaction(lpCurrent, stTxn, terResult, true, meta);
} }
void NetworkOPs::pubAccountTransaction(Ledger::ref lpCurrent, const SerializedTransaction& stTxn, TER terResult, bool bAccepted, TransactionMetaSet::pointer& meta) void NetworkOPs::pubAccountTransaction(Ledger::ref lpCurrent, const ALTransaction& alTx)
{ {
boost::unordered_set<InfoSub::pointer> notify; boost::unordered_set<InfoSub::pointer> notify;
bool bAccepted = alTx.isApplied();
int iProposed = 0; int iProposed = 0;
int iAccepted = 0; int iAccepted = 0;
@@ -1460,8 +1454,7 @@ void NetworkOPs::pubAccountTransaction(Ledger::ref lpCurrent, const SerializedTr
if (!mSubAccount.empty() || (!mSubRTAccount.empty()) ) if (!mSubAccount.empty() || (!mSubRTAccount.empty()) )
{ {
std::vector<RippleAddress> accounts = meta ? meta->getAffectedAccounts() : stTxn.getMentionedAccounts(); BOOST_FOREACH(const RippleAddress& affectedAccount, alTx.getAffected())
BOOST_FOREACH(const RippleAddress& affectedAccount, accounts)
{ {
subInfoMapIterator simiIt = mSubRTAccount.find(affectedAccount.getAccountID()); subInfoMapIterator simiIt = mSubRTAccount.find(affectedAccount.getAccountID());
@@ -1510,9 +1503,10 @@ void NetworkOPs::pubAccountTransaction(Ledger::ref lpCurrent, const SerializedTr
if (!notify.empty()) if (!notify.empty())
{ {
Json::Value jvObj = transJson(stTxn, terResult, bAccepted, lpCurrent, "account"); Json::Value jvObj = transJson(*alTx.getTxn(), alTx.getResult(), bAccepted, lpCurrent, "account");
if (meta) jvObj["meta"] = meta->getJson(0); if (alTx.isApplied())
jvObj["meta"] = alTx.getMeta()->getJson(0);
BOOST_FOREACH(InfoSub::ref isrListener, notify) BOOST_FOREACH(InfoSub::ref isrListener, notify)
{ {

View File

@@ -14,6 +14,7 @@
#include "LedgerAcquire.h" #include "LedgerAcquire.h"
#include "LedgerProposal.h" #include "LedgerProposal.h"
#include "JobQueue.h" #include "JobQueue.h"
#include "AcceptedLedger.h"
// Operations that clients may wish to perform against the network // Operations that clients may wish to perform against the network
// Master operational handler, server sequencer, network tracker // Master operational handler, server sequencer, network tracker
@@ -140,8 +141,8 @@ protected:
Json::Value pubBootstrapAccountInfo(Ledger::ref lpAccepted, const RippleAddress& naAccountID); Json::Value pubBootstrapAccountInfo(Ledger::ref lpAccepted, const RippleAddress& naAccountID);
void pubAcceptedTransaction(Ledger::ref lpCurrent, const SerializedTransaction& stTxn, TER terResult,TransactionMetaSet::pointer& meta); void pubAcceptedTransaction(Ledger::ref alAccepted, const ALTransaction& alTransaction);
void pubAccountTransaction(Ledger::ref lpCurrent, const SerializedTransaction& stTxn, TER terResult,bool accepted,TransactionMetaSet::pointer& meta); void pubAccountTransaction(Ledger::ref lpCurrent, const ALTransaction& alTransaction);
void pubServer(); void pubServer();
@@ -306,7 +307,7 @@ public:
// Monitoring: publisher side // Monitoring: publisher side
// //
void pubLedger(Ledger::ref lpAccepted); void pubLedger(Ledger::ref lpAccepted);
void pubProposedTransaction(Ledger::ref lpCurrent, const SerializedTransaction& stTxn, TER terResult); void pubProposedTransaction(Ledger::ref lpCurrent, SerializedTransaction::ref stTxn, TER terResult);
// //

View File

@@ -187,15 +187,14 @@ BookListeners::pointer OrderBookDB::getBookListeners(const uint160& currencyIn,
*/ */
// Based on the meta, send the meta to the streams that are listening // Based on the meta, send the meta to the streams that are listening
// We need to determine which streams a given meta effects // We need to determine which streams a given meta effects
void OrderBookDB::processTxn(const SerializedTransaction& stTxn, TER terResult, void OrderBookDB::processTxn(Ledger::ref ledger, const ALTransaction& alTx, Json::Value& jvObj)
TransactionMetaSet::pointer& meta, Json::Value& jvObj)
{ {
boost::recursive_mutex::scoped_lock sl(mLock); boost::recursive_mutex::scoped_lock sl(mLock);
if (terResult == tesSUCCESS) if (alTx.getResult() == tesSUCCESS)
{ {
// check if this is an offer or an offer cancel or a payment that consumes an offer // check if this is an offer or an offer cancel or a payment that consumes an offer
//check to see what the meta looks like //check to see what the meta looks like
BOOST_FOREACH(STObject& node, meta->getNodes()) BOOST_FOREACH(STObject& node, alTx.getMeta()->getNodes())
{ {
try try
{ {

View File

@@ -6,6 +6,7 @@
#include <boost/unordered_map.hpp> #include <boost/unordered_map.hpp>
#include "Ledger.h" #include "Ledger.h"
#include "AcceptedLedger.h"
#include "OrderBook.h" #include "OrderBook.h"
@@ -66,7 +67,7 @@ public:
const uint160& issuerIn, const uint160& issuerOut); const uint160& issuerIn, const uint160& issuerOut);
// see if this txn effects any orderbook // see if this txn effects any orderbook
void processTxn(const SerializedTransaction& stTxn, TER terResult,TransactionMetaSet::pointer& meta,Json::Value& jvObj); void processTxn(Ledger::ref ledger, const ALTransaction& alTx, Json::Value& jvObj);
}; };