diff --git a/src/Application.cpp b/src/Application.cpp index 2011ca8e78..b9483a37b8 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -162,7 +162,6 @@ void Application::run() { Log(lsWARNING) << "Running in standalone mode"; mNetOps.setStandAlone(); - mMasterLedger.runStandAlone(); } else mNetOps.setStateTimer(); diff --git a/src/LedgerConsensus.cpp b/src/LedgerConsensus.cpp index bccbd76d14..a07965ae6b 100644 --- a/src/LedgerConsensus.cpp +++ b/src/LedgerConsensus.cpp @@ -527,15 +527,20 @@ void LedgerConsensus::statePreClose() } if (ContinuousLedgerTiming::shouldClose(anyTransactions, mPreviousProposers, proposersClosed, - mPreviousMSeconds, sinceClose, idleInterval)) - { // it is time to close the ledger + mPreviousMSeconds, sinceClose, idleInterval)) + { + closeLedger(); + } +} + +void LedgerConsensus::closeLedger() +{ mState = lcsESTABLISH; mConsensusStartTime = boost::posix_time::microsec_clock::universal_time(); mCloseTime = theApp->getOPs().getCloseTimeNC(); theApp->getOPs().setLastCloseTime(mCloseTime); statusChange(newcoin::neCLOSING_LEDGER, *mPreviousLedger); takeInitialPosition(*theApp->getMasterLedger().closeLedger()); - } } void LedgerConsensus::stateEstablish() @@ -551,7 +556,7 @@ void LedgerConsensus::stateEstablish() { cLog(lsINFO) << "Converge cutoff (" << mPeerPositions.size() << " participants)"; mState = lcsFINISHED; - beginAccept(); + beginAccept(false); } } @@ -929,7 +934,7 @@ bool LedgerConsensus::peerGaveNodes(Peer::ref peer, const uint256& setHash, return set->takeNodes(nodeIDs, nodeData, peer); } -void LedgerConsensus::beginAccept() +void LedgerConsensus::beginAccept(bool synchronous) { SHAMap::pointer consensusSet = mAcquired[mOurPosition->getCurrentHash()]; if (!consensusSet) @@ -940,7 +945,10 @@ void LedgerConsensus::beginAccept() } theApp->getOPs().newLCL(mPeerPositions.size(), mCurrentMSeconds, mNewLedgerHash); - theApp->getIOService().post(boost::bind(&LedgerConsensus::Saccept, shared_from_this(), consensusSet)); + if (synchronous) + accept(consensusSet); + else + theApp->getIOService().post(boost::bind(&LedgerConsensus::Saccept, shared_from_this(), consensusSet)); } void LedgerConsensus::Saccept(boost::shared_ptr This, SHAMap::pointer txSet) @@ -1173,7 +1181,6 @@ void LedgerConsensus::accept(SHAMap::ref set) theApp->getOPs().closeTimeOffset(offset); } -#ifdef DEBUG if (sLog(lsTRACE)) { Log(lsTRACE) << "newLCL"; @@ -1181,7 +1188,6 @@ void LedgerConsensus::accept(SHAMap::ref set) newLCL->addJson(p, LEDGER_JSON_DUMP_TXNS | LEDGER_JSON_DUMP_STATE); Log(lsTRACE) << p; } -#endif } void LedgerConsensus::endConsensus() @@ -1189,6 +1195,16 @@ void LedgerConsensus::endConsensus() theApp->getOPs().endConsensus(mHaveCorrectLCL); } +void LedgerConsensus::simulate() +{ + cLog(lsINFO) << "Simulating consensus"; + closeLedger(); + mCurrentMSeconds = 100; + beginAccept(true); + endConsensus(); + cLog(lsINFO) << "Simulation complete"; +} + Json::Value LedgerConsensus::getJson() { Json::Value ret(Json::objectValue); diff --git a/src/LedgerConsensus.h b/src/LedgerConsensus.h index 44b4db409f..6e5d81a552 100644 --- a/src/LedgerConsensus.h +++ b/src/LedgerConsensus.h @@ -148,8 +148,9 @@ protected: void updateOurPositions(); void playbackProposals(); int getThreshold(); + void closeLedger(); - void beginAccept(); + void beginAccept(bool synchronous); void endConsensus(); public: @@ -189,6 +190,8 @@ public: void swapDefer(boost::unordered_map< uint160, std::list > &n) { mDeferredProposals.swap(n); } + // test/debug + void simulate(); }; diff --git a/src/LedgerMaster.h b/src/LedgerMaster.h index 76e6327381..2f198b8847 100644 --- a/src/LedgerMaster.h +++ b/src/LedgerMaster.h @@ -43,8 +43,6 @@ public: // The finalized ledger is the last closed/accepted ledger Ledger::pointer getClosedLedger() { return mFinalizedLedger; } - void runStandAlone() { mFinalizedLedger = mCurrentLedger; } - TER doTransaction(const SerializedTransaction& txn, TransactionEngineParams params); void pushLedger(Ledger::ref newLedger); diff --git a/src/NetworkOPs.cpp b/src/NetworkOPs.cpp index b2b128cd15..32b9651d23 100644 --- a/src/NetworkOPs.cpp +++ b/src/NetworkOPs.cpp @@ -443,7 +443,7 @@ void NetworkOPs::checkState(const boost::system::error_code& result) // check if the ledger is good enough to go to omFULL // Note: Do not go to omFULL if we don't have the previous ledger // check if the ledger is bad enough to go to omCONNECTED -- TODO - if (theApp->getOPs().getNetworkTimeNC() < theApp->getMasterLedger().getCurrentLedger()->getCloseTimeNC()) + if (theApp->getOPs().getNetworkTimeNC() < mLedgerMaster->getCurrentLedger()->getCloseTimeNC()) setMode(omFULL); } @@ -454,7 +454,7 @@ void NetworkOPs::checkState(const boost::system::error_code& result) } if ((!mConsensus) && (mMode != omDISCONNECTED)) - beginConsensus(networkClosed, theApp->getMasterLedger().getCurrentLedger()); + beginConsensus(networkClosed, mLedgerMaster->getCurrentLedger()); if (mConsensus) mConsensus->timerEntry(); } @@ -650,7 +650,7 @@ int NetworkOPs::beginConsensus(const uint256& networkClosed, Ledger::pointer clo assert(!mConsensus); prevLedger->setImmutable(); mConsensus = boost::make_shared( - networkClosed, prevLedger, theApp->getMasterLedger().getCurrentLedger()->getCloseTimeNC()); + networkClosed, prevLedger, mLedgerMaster->getCurrentLedger()->getCloseTimeNC()); mConsensus->swapDefer(mDeferredProposals); cLog(lsDEBUG) << "Initiating consensus engine"; @@ -670,7 +670,7 @@ bool NetworkOPs::haveConsensusObject() if (!ledgerChange) { cLog(lsWARNING) << "Beginning consensus due to peer action"; - beginConsensus(networkClosed, theApp->getMasterLedger().getCurrentLedger()); + beginConsensus(networkClosed, mLedgerMaster->getCurrentLedger()); } return mConsensus; } @@ -770,7 +770,7 @@ void NetworkOPs::mapComplete(const uint256& hash, SHAMap::ref map) void NetworkOPs::endConsensus(bool correctLCL) { - uint256 deadLedger = theApp->getMasterLedger().getClosedLedger()->getParentHash(); + uint256 deadLedger = mLedgerMaster->getClosedLedger()->getParentHash(); std::vector peerList = theApp->getConnectionPool().getPeerVector(); BOOST_FOREACH(Peer::ref it, peerList) if (it && (it->getClosedLedgerHash() == deadLedger)) @@ -1222,6 +1222,12 @@ void NetworkOPs::newLCL(int proposers, int convergeTime, const uint256& ledgerHa mLastCloseHash = ledgerHash; } +uint32 NetworkOPs::acceptLedger() +{ // accept the current transaction tree, return the new ledger's sequence + beginConsensus(mLedgerMaster->getClosedLedger()->getHash(), mLedgerMaster->getCurrentLedger()); + mConsensus->simulate(); + return mLedgerMaster->getCurrentLedger()->getLedgerSeq(); +} #if 0 void NetworkOPs::subAccountChanges(InfoSub* ispListener, const uint256 uLedgerHash) diff --git a/src/NetworkOPs.h b/src/NetworkOPs.h index 4c64374f17..8f4d3557d1 100644 --- a/src/NetworkOPs.h +++ b/src/NetworkOPs.h @@ -190,6 +190,7 @@ public: uint32 getLastCloseTime() { return mLastCloseTime; } void setLastCloseTime(uint32 t) { mLastCloseTime = t; } Json::Value getServerInfo(); + uint32 acceptLedger(); // client information retrieval functions std::vector< std::pair > diff --git a/src/RPCServer.cpp b/src/RPCServer.cpp index 9aa51033c6..6d669e03f1 100644 --- a/src/RPCServer.cpp +++ b/src/RPCServer.cpp @@ -70,6 +70,7 @@ Json::Value RPCServer::RPCError(int iError) { rpcNO_GEN_DECRPYT, "noGenDectypt", "Password failed to decrypt master public generator." }, { rpcNO_NETWORK, "noNetwork", "Network not available." }, { rpcNO_PERMISSION, "noPermission", "You don't have permission for this command." }, + { rpcNOT_STANDALONE, "notStandAlone", "Operation valid in debug mode only." }, { rpcPASSWD_CHANGED, "passwdChanged", "Wrong key, password changed." }, { rpcPAYS_ACT_MALFORMED, "paysActMalformed", "Pays account malformed." }, { rpcPAYS_AMT_MALFORMED, "paysAmtMalformed", "Pays amount malformed." }, @@ -419,6 +420,16 @@ Json::Value RPCServer::accountFromString(const uint256& uLedger, NewcoinAddress& return Json::Value(Json::objectValue); } +Json::Value RPCServer::doAcceptLedger(const Json::Value ¶ms) +{ + if (!theConfig.RUN_STANDALONE) + return RPCError(rpcNOT_STANDALONE); + + Json::Value obj(Json::objectValue); + obj["newLedger"] = theApp->getOPs().acceptLedger(); + return obj; +} + // account_domain_set [] Json::Value RPCServer::doAccountDomainSet(const Json::Value ¶ms) { @@ -2641,6 +2652,7 @@ Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params bool mAdminRequired; unsigned int iOptions; } commandsA[] = { + { "accept_ledger", &RPCServer::doAcceptLedger, 0, 0, true }, { "account_domain_set", &RPCServer::doAccountDomainSet, 2, 3, false, optCurrent }, { "account_email_set", &RPCServer::doAccountEmailSet, 2, 3, false, optCurrent }, { "account_info", &RPCServer::doAccountInfo, 1, 2, false, optCurrent }, diff --git a/src/RPCServer.h b/src/RPCServer.h index d203cbc3ca..ce859c8431 100644 --- a/src/RPCServer.h +++ b/src/RPCServer.h @@ -23,6 +23,7 @@ public: // Misc failure rpcLOAD_FAILED, rpcNO_PERMISSION, + rpcNOT_STANDALONE, // Networking rpcNO_CLOSED, @@ -128,6 +129,7 @@ private: Json::Value accountFromString(const uint256& uLedger, NewcoinAddress& naAccount, bool& bIndex, const std::string& strIdent, const int iIndex); + Json::Value doAcceptLedger(const Json::Value ¶ms); Json::Value doAccountDomainSet(const Json::Value ¶ms); Json::Value doAccountEmailSet(const Json::Value ¶ms); Json::Value doAccountInfo(const Json::Value& params);