From d35bb54c06d7e2613ba2b81403e391e32b29a822 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Sun, 3 Jun 2012 12:24:10 -0700 Subject: [PATCH] Structures to correctly handle both pre and post close wobble. --- src/LedgerConsensus.cpp | 15 +++++---------- src/LedgerConsensus.h | 1 - src/LedgerMaster.h | 7 +++++-- src/TransactionEngine.cpp | 36 ++++++++++++++++++++++++++---------- src/TransactionEngine.h | 14 ++++++++++---- 5 files changed, 46 insertions(+), 27 deletions(-) diff --git a/src/LedgerConsensus.cpp b/src/LedgerConsensus.cpp index eb3c9ec6f8..01dc99b49e 100644 --- a/src/LedgerConsensus.cpp +++ b/src/LedgerConsensus.cpp @@ -291,8 +291,10 @@ int LedgerConsensus::statePreClose(int secondsSinceClose) { // it is shortly before ledger close time if (secondsSinceClose >= 0) { // it is time to close the ledger + Log(lsINFO) << "Closing ledger"; mState = lcsPOST_CLOSE; - closeLedger(); + Ledger::pointer initial = theApp->getMasterLedger().getCurrentLedger(); + statusChange(newcoin::neCLOSING_LEDGER, mPreviousLedger); } return 1; } @@ -429,13 +431,6 @@ SHAMap::pointer LedgerConsensus::getTransactionTree(const uint256& hash, bool do return it->second; } -void LedgerConsensus::closeLedger() -{ - Log(lsINFO) << "Closing ledger"; - Ledger::pointer initial = theApp->getMasterLedger().getCurrentLedger(); - statusChange(newcoin::neCLOSING_LEDGER, mPreviousLedger); -} - void LedgerConsensus::startAcquiring(TransactionAcquire::pointer acquire) { boost::unordered_map< uint256, std::vector< boost::weak_ptr > >::iterator it = @@ -602,7 +597,7 @@ void LedgerConsensus::applyTransactions(SHAMap::pointer set, Ledger::pointer led #endif SerializerIterator sit(item->peekSerializer()); SerializedTransaction::pointer txn = boost::make_shared(boost::ref(sit)); - TransactionEngineResult result = engine.applyTransaction(*txn, tepNO_CHECK_FEE | tepUPDATE_TOTAL); + TransactionEngineResult result = engine.applyTransaction(*txn, tepNO_CHECK_FEE | tepUPDATE_TOTAL, 0); if (result > 0) { Log(lsINFO) << " retry"; @@ -638,7 +633,7 @@ void LedgerConsensus::applyTransactions(SHAMap::pointer set, Ledger::pointer led { try { - TransactionEngineResult result = engine.applyTransaction(**it, tepNO_CHECK_FEE | tepUPDATE_TOTAL); + TransactionEngineResult result = engine.applyTransaction(**it, tepNO_CHECK_FEE | tepUPDATE_TOTAL, 0); if (result <= 0) { if (result == 0) ++successes; diff --git a/src/LedgerConsensus.h b/src/LedgerConsensus.h index 3463149870..9c21973fee 100644 --- a/src/LedgerConsensus.h +++ b/src/LedgerConsensus.h @@ -112,7 +112,6 @@ protected: void addPosition(LedgerProposal&, bool ours); void removePosition(LedgerProposal&, bool ours); void sendHaveTxSet(const std::vector& txSetHashes); - void closeLedger(); void applyTransactions(SHAMap::pointer transactionSet, Ledger::pointer targetLedger, std::deque& failedTransactions); diff --git a/src/LedgerMaster.h b/src/LedgerMaster.h index 8f049b1363..47ee5320b3 100644 --- a/src/LedgerMaster.h +++ b/src/LedgerMaster.h @@ -19,6 +19,7 @@ class LedgerMaster TransactionEngine mEngine; Ledger::pointer mCurrentLedger; // The ledger we are currently processiong + Ledger::pointer mWobbleLedger; // A ledger past its close time Ledger::pointer mFinalizedLedger; // The ledger that most recently closed LedgerHistory mLedgerHistory; @@ -38,14 +39,16 @@ public: ScopedLock getLock() { return ScopedLock(mLock); } Ledger::pointer getCurrentLedger() { return mCurrentLedger; } + Ledger::pointer getWobbleLedger() { return mWobbleLedger; } Ledger::pointer getClosedLedger() { return mFinalizedLedger; } TransactionEngineResult doTransaction(const SerializedTransaction& txn, uint32 targetLedger, - TransactionEngineParams params) // FIXME: wobble - { return mEngine.applyTransaction(txn, params); } + TransactionEngineParams params) + { return mEngine.applyTransaction(txn, params, targetLedger); } void pushLedger(Ledger::pointer newLedger); void pushLedger(Ledger::pointer newLCL, Ledger::pointer newOL); + void switchLedgers(Ledger::pointer lastClosed, Ledger::pointer newCurrent); Ledger::pointer getLedgerBySeq(uint32 index) diff --git a/src/TransactionEngine.cpp b/src/TransactionEngine.cpp index e8ae14ec53..ccfc88be41 100644 --- a/src/TransactionEngine.cpp +++ b/src/TransactionEngine.cpp @@ -232,10 +232,18 @@ TransactionEngineResult TransactionEngine::dirDelete( } TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTransaction& txn, - TransactionEngineParams params) + TransactionEngineParams params, uint32 targetLedger) { std::cerr << "applyTransaction>" << std::endl; + mLedger = mDefaultLedger; + if (mAlternateLedger && (targetLedger != 0) && + (targetLedger != mLedger->getLedgerSeq()) && (targetLedger == mAlternateLedger->getLedgerSeq())) + { + Log(lsINFO) << "Transaction goes into wobble ledger"; + mLedger = mAlternateLedger; + } + #ifdef DEBUG if (1) { @@ -260,6 +268,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran if (!txID) { std::cerr << "applyTransaction: invalid transaction id" << std::endl; + mLedger = Ledger::pointer(); return tenINVALID; } @@ -278,6 +287,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran if (!txn.checkSign(naSigningPubKey)) { std::cerr << "applyTransaction: Invalid transaction: bad signature" << std::endl; + mLedger = Ledger::pointer(); return tenINVALID; } @@ -318,7 +328,10 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran } if (terSUCCESS != result) + { + mLedger = Ledger::pointer(); return result; + } STAmount saPaid = txn.getTransactionFee(); if ((params & tepNO_CHECK_FEE) == tepNONE) @@ -328,6 +341,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran if (saPaid < saCost) { std::cerr << "applyTransaction: insufficient fee" << std::endl; + mLedger = Ledger::pointer(); return tenINSUF_FEE_P; } } @@ -337,6 +351,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran { // Transaction is malformed. std::cerr << "applyTransaction: fee not allowed" << std::endl; + mLedger = Ledger::pointer(); return tenINSUF_FEE_P; } } @@ -359,7 +374,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran if (!sleSrc) { std::cerr << str(boost::format("applyTransaction: Delay transaction: source account does not exisit: %s") % txn.getSourceAccount().humanAccountID()) << std::endl; - + mLedger = Ledger::pointer(); return terNO_ACCOUNT; } @@ -372,7 +387,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran // Signing Pub Key must be for Source Account ID. std::cerr << "sourceAccountID: " << naSigningPubKey.humanAccountID() << std::endl; std::cerr << "txn accountID: " << txn.getSourceAccount().humanAccountID() << std::endl; - + mLedger = Ledger::pointer(); return tenINVALID; } break; @@ -381,13 +396,13 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran if (!sleSrc->getIFieldPresent(sfAuthorizedKey)) { std::cerr << "applyTransaction: Can not use unclaimed account." << std::endl; - + mLedger = Ledger::pointer(); return tenUNCLAIMED; } else if (naSigningPubKey.getAccountID() != sleSrc->getIValueFieldAccount(sfAuthorizedKey).getAccountID()) { std::cerr << "applyTransaction: Not authorized to use account." << std::endl; - + mLedger = Ledger::pointer(); return tenBAD_AUTH; } break; @@ -406,6 +421,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran % saSrcBalance % saPaid) << std::endl; + mLedger = Ledger::pointer(); return terINSUF_FEE_B; } @@ -425,18 +441,18 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran if (a_seq < t_seq) { std::cerr << "applyTransaction: future sequence number" << std::endl; - + mLedger = Ledger::pointer(); return terPRE_SEQ; } if (mLedger->hasTransaction(txID)) { std::cerr << "applyTransaction: duplicate sequence number" << std::endl; - + mLedger = Ledger::pointer(); return terALREADY; } std::cerr << "applyTransaction: past sequence number" << std::endl; - + mLedger = Ledger::pointer(); return terPAST_SEQ; } else sleSrc->setIFieldU32(sfSequence, t_seq); @@ -446,7 +462,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran if (t_seq) { std::cerr << "applyTransaction: bad sequence for pre-paid transaction" << std::endl; - + mLedger = Ledger::pointer(); return terPAST_SEQ; } } @@ -528,7 +544,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran if ((params & tepUPDATE_TOTAL) != tepNONE) mLedger->destroyCoins(saPaid.getNValue()); } - + mLedger = Ledger::pointer(); return result; } diff --git a/src/TransactionEngine.h b/src/TransactionEngine.h index aa1b23247e..6db706735e 100644 --- a/src/TransactionEngine.h +++ b/src/TransactionEngine.h @@ -92,6 +92,7 @@ private: const uint256& uLedgerIndex); // Item being deleted protected: + Ledger::pointer mDefaultLedger, mAlternateLedger; Ledger::pointer mLedger; TransactionEngineResult doAccountSet(const SerializedTransaction& txn, std::vector& accounts); @@ -110,12 +111,17 @@ protected: public: TransactionEngine() { ; } - TransactionEngine(Ledger::pointer ledger) : mLedger(ledger) { ; } + TransactionEngine(Ledger::pointer ledger) : mDefaultLedger(ledger) { ; } - Ledger::pointer getLedger() { return mLedger; } - void setLedger(Ledger::pointer ledger) { mLedger = ledger; } + Ledger::pointer getDefaultLedger() { return mDefaultLedger; } + void setDefaultLedger(Ledger::pointer ledger) { mDefaultLedger = ledger; } + Ledger::pointer getAlternateLedger() { return mAlternateLedger; } + void setAlternateLedger(Ledger::pointer ledger) { mDefaultLedger = ledger; } + void setLedger(Ledger::pointer ledger) { mDefaultLedger = ledger; + mAlternateLedger = Ledger::pointer(); } - TransactionEngineResult applyTransaction(const SerializedTransaction&, TransactionEngineParams); + TransactionEngineResult applyTransaction(const SerializedTransaction&, TransactionEngineParams, + uint32 targetLedger); }; inline TransactionEngineParams operator|(const TransactionEngineParams& l1, const TransactionEngineParams& l2)