From 88e938ec50bb0d05a45f01b8375c74587b89c4bd Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 13 Aug 2012 17:10:51 -0700 Subject: [PATCH 01/21] Change TXS acquire timeout. --- src/LedgerAcquire.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LedgerAcquire.cpp b/src/LedgerAcquire.cpp index 2407616bd6..6e13a883c8 100644 --- a/src/LedgerAcquire.cpp +++ b/src/LedgerAcquire.cpp @@ -11,7 +11,7 @@ #include "HashPrefixes.h" // #define LA_DEBUG -#define LEDGER_ACQUIRE_TIMEOUT 2 +#define LEDGER_ACQUIRE_TIMEOUT 1 #define TRUST_NETWORK PeerSet::PeerSet(const uint256& hash, int interval) : mHash(hash), mTimerInterval(interval), mTimeouts(0), From a7f192c989b0062ac07e659c006e593d8e74081c Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 13 Aug 2012 17:11:00 -0700 Subject: [PATCH 02/21] Cleanups. --- src/LedgerConsensus.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/LedgerConsensus.cpp b/src/LedgerConsensus.cpp index 7d9f1c3d6c..b47a19ee67 100644 --- a/src/LedgerConsensus.cpp +++ b/src/LedgerConsensus.cpp @@ -26,7 +26,10 @@ TransactionAcquire::TransactionAcquire(const uint256& hash) : PeerSet(hash, 1), void TransactionAcquire::done() { if (mFailed) + { + Log(lsWARNING) << "Failed to acqiure TXs " << mHash.GetHex(); theApp->getOPs().mapComplete(mHash, SHAMap::pointer()); + } else theApp->getOPs().mapComplete(mHash, mMap); } @@ -48,7 +51,7 @@ void TransactionAcquire::trigger(Peer::pointer peer, bool timer) *(tmGL.add_nodeids()) = SHAMapNode().getRawString(); sendRequest(tmGL, peer); } - if (mHaveRoot) + else { std::vector nodeIDs; std::vector nodeHashes; ConsensusTransSetSF sf; @@ -67,10 +70,7 @@ void TransactionAcquire::trigger(Peer::pointer peer, bool timer) tmGL.set_itype(newcoin::liTS_CANDIDATE); for (std::vector::iterator it = nodeIDs.begin(); it != nodeIDs.end(); ++it) *(tmGL.add_nodeids()) = it->getRawString(); - if (peer) - sendRequest(tmGL, peer); - else - sendRequest(tmGL); + sendRequest(tmGL, peer); return; } } From 4aea8c8dfb7efa8eed6ecfac7ed202e330d416df Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 13 Aug 2012 17:11:15 -0700 Subject: [PATCH 03/21] Use fat root semantics when acquire transaction sets. This might save a pass. --- src/Peer.cpp | 8 +++++--- src/SHAMap.h | 2 +- src/SHAMapSync.cpp | 11 ++++++----- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/Peer.cpp b/src/Peer.cpp index 991d18456b..28b79d5024 100644 --- a/src/Peer.cpp +++ b/src/Peer.cpp @@ -928,7 +928,7 @@ void Peer::recvGetLedger(newcoin::TMGetLedger& packet) { SHAMap::pointer map; newcoin::TMLedgerData reply; - bool fatLeaves = true; + bool fatLeaves = true, fatRoot = false; if (packet.itype() == newcoin::liTS_CANDIDATE) { // Request is for a transaction candidate set @@ -952,6 +952,7 @@ void Peer::recvGetLedger(newcoin::TMGetLedger& packet) reply.set_ledgerhash(txHash.begin(), txHash.size()); reply.set_type(newcoin::liTS_CANDIDATE); fatLeaves = false; // We'll already have most transactions + fatRoot = true; // Save a pass } else { // Figure out what ledger they want @@ -1057,7 +1058,7 @@ void Peer::recvGetLedger(newcoin::TMGetLedger& packet) } std::vector nodeIDs; std::list< std::vector > rawNodes; - if(map->getNodeFat(mn, nodeIDs, rawNodes, fatLeaves)) + if(map->getNodeFat(mn, nodeIDs, rawNodes, fatRoot, fatLeaves)) { std::vector::iterator nodeIDIterator; std::list< std::vector >::iterator rawNodeIterator; @@ -1074,7 +1075,8 @@ void Peer::recvGetLedger(newcoin::TMGetLedger& packet) } } } - if (packet.has_requestcookie()) reply.set_requestcookie(packet.requestcookie()); + if (packet.has_requestcookie()) + reply.set_requestcookie(packet.requestcookie()); PackedMessage::pointer oPacket = boost::make_shared(reply, newcoin::mtLEDGER_DATA); sendPacket(oPacket); } diff --git a/src/SHAMap.h b/src/SHAMap.h index 4bfd7999db..2f9e73d529 100644 --- a/src/SHAMap.h +++ b/src/SHAMap.h @@ -327,7 +327,7 @@ public: void getMissingNodes(std::vector& nodeIDs, std::vector& hashes, int max, SHAMapSyncFilter* filter); bool getNodeFat(const SHAMapNode& node, std::vector& nodeIDs, - std::list >& rawNode, bool fatLeaves); + std::list >& rawNode, bool fatRoot, bool fatLeaves); bool getRootNode(Serializer& s, SHANodeFormat format); bool addRootNode(const uint256& hash, const std::vector& rootNode, SHANodeFormat format); bool addRootNode(const std::vector& rootNode, SHANodeFormat format); diff --git a/src/SHAMapSync.cpp b/src/SHAMapSync.cpp index 25c2d019a0..ed76558906 100644 --- a/src/SHAMapSync.cpp +++ b/src/SHAMapSync.cpp @@ -86,7 +86,7 @@ void SHAMap::getMissingNodes(std::vector& nodeIDs, std::vector& nodeIDs, - std::list >& rawNodes, bool fatLeaves) + std::list >& rawNodes, bool fatRoot, bool fatLeaves) { // Gets a node and some of its children boost::recursive_mutex::scoped_lock sl(mLock); @@ -102,7 +102,7 @@ bool SHAMap::getNodeFat(const SHAMapNode& wanted, std::vector& nodeI node->addRaw(s, snfWIRE); rawNodes.push_back(s.peekData()); - if (node->isRoot() || node->isLeaf()) // don't get a fat root, can't get a fat leaf + if ((!fatRoot && node->isRoot()) || node->isLeaf()) // don't get a fat root, can't get a fat leaf return true; for (int i = 0; i < 16; ++i) @@ -141,7 +141,8 @@ bool SHAMap::addRootNode(const std::vector& rootNode, SHANodeForm } SHAMapTreeNode::pointer node = boost::make_shared(SHAMapNode(), rootNode, 0, format); - if (!node) return false; + if (!node) + return false; #ifdef DEBUG node->dump(); @@ -444,7 +445,7 @@ BOOST_AUTO_TEST_CASE( SHAMapSync_test ) destination.setSynching(); - if (!source.getNodeFat(SHAMapNode(), nodeIDs, gotNodes, (rand() % 2) == 0)) + if (!source.getNodeFat(SHAMapNode(), nodeIDs, gotNodes, (rand() % 2) == 0, (rand() % 2) == 0)) { Log(lsFATAL) << "GetNodeFat(root) fails"; BOOST_FAIL("GetNodeFat"); @@ -481,7 +482,7 @@ BOOST_AUTO_TEST_CASE( SHAMapSync_test ) // get as many nodes as possible based on this information for (nodeIDIterator = nodeIDs.begin(); nodeIDIterator != nodeIDs.end(); ++nodeIDIterator) { - if (!source.getNodeFat(*nodeIDIterator, gotNodeIDs, gotNodes, (rand() % 2) == 0)) + if (!source.getNodeFat(*nodeIDIterator, gotNodeIDs, gotNodes, (rand() % 2) == 0, (rand() % 2) == 0)) { Log(lsFATAL) << "GetNodeFat fails"; BOOST_FAIL("GetNodeFat"); From e3b6ec5080f5d73bbeba136f136f9376a145ce33 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 13 Aug 2012 17:18:58 -0700 Subject: [PATCH 04/21] Don't call newLCL more than once. --- src/LedgerConsensus.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/LedgerConsensus.cpp b/src/LedgerConsensus.cpp index b47a19ee67..a2888f190a 100644 --- a/src/LedgerConsensus.cpp +++ b/src/LedgerConsensus.cpp @@ -441,9 +441,7 @@ void LedgerConsensus::stateEstablish() void LedgerConsensus::stateFinished() { // we are processing the finished ledger // logic of calculating next ledger advances us out of this state - - // CHECKME: Should we count proposers that didn't converge to our consensus set? - theApp->getOPs().newLCL(mPeerPositions.size(), mCurrentMSeconds, mNewLedgerHash); + // nothing to do } void LedgerConsensus::stateAccepted() @@ -770,6 +768,7 @@ void LedgerConsensus::beginAccept() return; } + theApp->getOPs().newLCL(mPeerPositions.size(), mCurrentMSeconds, mNewLedgerHash); boost::thread thread(boost::bind(&LedgerConsensus::Saccept, shared_from_this(), consensusSet)); thread.detach(); } From 524e89f4e1ce0452fea0d40b6e4a949c910a75a4 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 13 Aug 2012 17:35:20 -0700 Subject: [PATCH 05/21] Timing cleanups. --- src/LedgerTiming.h | 9 +++++++-- src/ValidationCollection.cpp | 11 ++++------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/LedgerTiming.h b/src/LedgerTiming.h index 41e85762a1..9f5cfa903f 100644 --- a/src/LedgerTiming.h +++ b/src/LedgerTiming.h @@ -4,8 +4,13 @@ // The number of seconds a ledger may remain idle before closing # define LEDGER_IDLE_INTERVAL 15 -// The number of seconds a validation remains current -# define LEDGER_MAX_INTERVAL (LEDGER_IDLE_INTERVAL * 4) +// The number of seconds a validation remains current after its ledger's close time +// This is a safety to protect against very old validations +# define LEDGER_MAX_INTERVAL (LEDGER_IDLE_INTERVAL * 32) + +// The number of seconds before a close time that we consider a validation acceptable +// This protects against extreme clock errors +# define LEDGER_EARLY_INTERVAL 240 // The number of milliseconds we wait minimum to ensure participation # define LEDGER_MIN_CONSENSUS 2000 diff --git a/src/ValidationCollection.cpp b/src/ValidationCollection.cpp index 466b3d7f2e..68c54fc86e 100644 --- a/src/ValidationCollection.cpp +++ b/src/ValidationCollection.cpp @@ -14,7 +14,7 @@ bool ValidationCollection::addValidation(SerializedValidation::pointer val) val->setTrusted(); uint32 now = theApp->getOPs().getCloseTimeNC(); uint32 valClose = val->getCloseTime(); - if ((now > (valClose - 4)) && (now < (valClose + LEDGER_MAX_INTERVAL))) + if ((now > (valClose - LEDGER_EARLY_INTERVAL)) && (now < (valClose + LEDGER_MAX_INTERVAL))) isCurrent = true; else Log(lsWARNING) << "Received stale validation now=" << now << ", close=" << valClose; @@ -81,7 +81,7 @@ void ValidationCollection::getValidationCount(const uint256& ledger, bool curren if (isTrusted && currentOnly) { uint32 closeTime = vit->second->getCloseTime(); - if ((now < closeTime) || (now > (closeTime + 2 * LEDGER_MAX_INTERVAL))) + if ((now < (closeTime - LEDGER_EARLY_INTERVAL)) || (now > (closeTime + LEDGER_MAX_INTERVAL))) isTrusted = false; } if (isTrusted) @@ -129,7 +129,6 @@ boost::unordered_map ValidationCollection::getCurrentValidations() { boost::mutex::scoped_lock sl(mValidationLock); boost::unordered_map::iterator it = mCurrentValidations.begin(); - bool anyNew = false; while (it != mCurrentValidations.end()) { ValidationPair& pair = it->second; @@ -138,13 +137,13 @@ boost::unordered_map ValidationCollection::getCurrentValidations() { mStaleValidations.push_back(pair.oldest); pair.oldest = SerializedValidation::pointer(); - anyNew = true; + condWrite(); } if (pair.newest && (now > (pair.newest->getCloseTime() + LEDGER_MAX_INTERVAL))) { mStaleValidations.push_back(pair.newest); pair.newest = SerializedValidation::pointer(); - anyNew = true; + condWrite(); } if (!pair.newest && !pair.oldest) it = mCurrentValidations.erase(it); @@ -165,8 +164,6 @@ boost::unordered_map ValidationCollection::getCurrentValidations() ++it; } } - if (anyNew) - condWrite(); } return ret; From d1547998d71d7aa5640d248adc1754924b616fe0 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 13 Aug 2012 17:55:55 -0700 Subject: [PATCH 06/21] Change LEDGER_MAX_INTERVAL to LEDGER_VAL_INTERVAL to more accurately reflect what it now does. Turn this interval way up to ensure we can't lose synch (due to validations seeming too old) if time resolution drops drastically. --- src/LedgerTiming.h | 5 +++-- src/ValidationCollection.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/LedgerTiming.h b/src/LedgerTiming.h index 9f5cfa903f..eb8f2d56c8 100644 --- a/src/LedgerTiming.h +++ b/src/LedgerTiming.h @@ -5,8 +5,9 @@ # define LEDGER_IDLE_INTERVAL 15 // The number of seconds a validation remains current after its ledger's close time -// This is a safety to protect against very old validations -# define LEDGER_MAX_INTERVAL (LEDGER_IDLE_INTERVAL * 32) +// This is a safety to protect against very old validations and the time it takes to adjust +// the close time accuracy window +# define LEDGER_VAL_INTERVAL 600 // The number of seconds before a close time that we consider a validation acceptable // This protects against extreme clock errors diff --git a/src/ValidationCollection.cpp b/src/ValidationCollection.cpp index 68c54fc86e..41c772f819 100644 --- a/src/ValidationCollection.cpp +++ b/src/ValidationCollection.cpp @@ -14,7 +14,7 @@ bool ValidationCollection::addValidation(SerializedValidation::pointer val) val->setTrusted(); uint32 now = theApp->getOPs().getCloseTimeNC(); uint32 valClose = val->getCloseTime(); - if ((now > (valClose - LEDGER_EARLY_INTERVAL)) && (now < (valClose + LEDGER_MAX_INTERVAL))) + if ((now > (valClose - LEDGER_EARLY_INTERVAL)) && (now < (valClose + LEDGER_VAL_INTERVAL))) isCurrent = true; else Log(lsWARNING) << "Received stale validation now=" << now << ", close=" << valClose; @@ -81,7 +81,7 @@ void ValidationCollection::getValidationCount(const uint256& ledger, bool curren if (isTrusted && currentOnly) { uint32 closeTime = vit->second->getCloseTime(); - if ((now < (closeTime - LEDGER_EARLY_INTERVAL)) || (now > (closeTime + LEDGER_MAX_INTERVAL))) + if ((now < (closeTime - LEDGER_EARLY_INTERVAL)) || (now > (closeTime + LEDGER_VAL_INTERVAL))) isTrusted = false; } if (isTrusted) @@ -133,13 +133,13 @@ boost::unordered_map ValidationCollection::getCurrentValidations() { ValidationPair& pair = it->second; - if (pair.oldest && (now > (pair.oldest->getCloseTime() + LEDGER_MAX_INTERVAL))) + if (pair.oldest && (now > (pair.oldest->getCloseTime() + LEDGER_VAL_INTERVAL))) { mStaleValidations.push_back(pair.oldest); pair.oldest = SerializedValidation::pointer(); condWrite(); } - if (pair.newest && (now > (pair.newest->getCloseTime() + LEDGER_MAX_INTERVAL))) + if (pair.newest && (now > (pair.newest->getCloseTime() + LEDGER_VAL_INTERVAL))) { mStaleValidations.push_back(pair.newest); pair.newest = SerializedValidation::pointer(); From ba6e65214b6f7b789130be3f2cbe8916071e443e Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 13 Aug 2012 19:23:49 -0700 Subject: [PATCH 07/21] Log whether a ledger is alive or dead when considering it as LCL. --- src/NetworkOPs.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/NetworkOPs.cpp b/src/NetworkOPs.cpp index 875834a1e5..355318844c 100644 --- a/src/NetworkOPs.cpp +++ b/src/NetworkOPs.cpp @@ -458,9 +458,10 @@ bool NetworkOPs::checkLastClosedLedger(const std::vector& peerLis for (boost::unordered_map::iterator it = ledgers.begin(), end = ledgers.end(); it != end; ++it) { - Log(lsTRACE) << "L: " << it->first.GetHex() << + bool isDead = theApp->getValidations().isDeadLedger(it->first); + Log(lsTRACE) << "L: " << it->first.GetHex() << ((isDead) ? " dead" : " live") << " t=" << it->second.trustedValidations << ", n=" << it->second.nodesUsing; - if ((it->second > bestVC) && !theApp->getValidations().isDeadLedger(it->first)) + if ((it->second > bestVC) && !isDead) { bestVC = it->second; closedLedger = it->first; From 8068e5fbb9b699a300cf4b8898cb840af8c11143 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 13 Aug 2012 22:27:20 -0700 Subject: [PATCH 08/21] Remove chatty debug. --- src/ValidationCollection.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ValidationCollection.cpp b/src/ValidationCollection.cpp index 41c772f819..2f29327140 100644 --- a/src/ValidationCollection.cpp +++ b/src/ValidationCollection.cpp @@ -151,13 +151,13 @@ boost::unordered_map ValidationCollection::getCurrentValidations() { if (pair.oldest) { - Log(lsTRACE) << "OLD " << pair.oldest->getLedgerHash().GetHex() << " " << +// Log(lsTRACE) << "OLD " << pair.oldest->getLedgerHash().GetHex() << " " << boost::lexical_cast(pair.oldest->getCloseTime()); ++ret[pair.oldest->getLedgerHash()]; } if (pair.newest) { - Log(lsTRACE) << "NEW " << pair.newest->getLedgerHash().GetHex() << " " << +// Log(lsTRACE) << "NEW " << pair.newest->getLedgerHash().GetHex() << " " << boost::lexical_cast(pair.newest->getCloseTime()); ++ret[pair.newest->getLedgerHash()]; } From 22237e58ab15a02b257f072c854101dc9f32b9ca Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 13 Aug 2012 22:27:29 -0700 Subject: [PATCH 09/21] Check for network condition during idle time. Switch LCL if needed. --- src/LedgerConsensus.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/LedgerConsensus.cpp b/src/LedgerConsensus.cpp index a2888f190a..6b56b66402 100644 --- a/src/LedgerConsensus.cpp +++ b/src/LedgerConsensus.cpp @@ -224,7 +224,7 @@ LedgerConsensus::LedgerConsensus(const uint256& prevLCLHash, Ledger::pointer pre } else { - Log(lsINFO) << "Entering consensus process, proposing"; + Log(lsINFO) << "Entering consensus process, watching"; mHaveCorrectLCL = true; mProposing = mValidating = false; } @@ -249,6 +249,9 @@ void LedgerConsensus::checkLCL() mPrevLedgerHash = netLgr; mAcquiringLedger = theApp->getMasterLedgerAcquire().findCreate(mPrevLedgerHash); std::vector peerList = theApp->getConnectionPool().getPeerVector(); + mHaveCorrectLCL = false; + mProposing = false; + mValidating = false; bool found = false; for (std::vector::const_iterator it = peerList.begin(), end = peerList.end(); it != end; ++it) if ((*it)->hasLedger(mPrevLedgerHash)) @@ -418,6 +421,8 @@ void LedgerConsensus::statePreClose() statusChange(newcoin::neCLOSING_LEDGER, *mPreviousLedger); takeInitialPosition(*theApp->getMasterLedger().closeLedger()); } + else + checkLCL(); } void LedgerConsensus::stateEstablish() From 6788105b2c72d8b154441e3d0b5b7e90fcebb791 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 13 Aug 2012 23:13:01 -0700 Subject: [PATCH 10/21] Chatty debug. --- src/HashedObject.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/HashedObject.cpp b/src/HashedObject.cpp index 9dc7e6e92c..71730bfb19 100644 --- a/src/HashedObject.cpp +++ b/src/HashedObject.cpp @@ -21,7 +21,9 @@ bool HashedObjectStore::store(HashedObjectType type, uint32 index, if (!theApp->getHashNodeDB()) return true; if (mCache.touch(hash)) { +#ifdef HS_DEBUG Log(lsTRACE) << "HOS: " << hash.GetHex() << " store: incache"; +#endif return false; } From 5eca52497f680377e90a7c5c28cc8942fab35b7e Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 13 Aug 2012 23:13:12 -0700 Subject: [PATCH 11/21] Improve close time synch with no transactions --- src/LedgerConsensus.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/LedgerConsensus.cpp b/src/LedgerConsensus.cpp index 6b56b66402..aba77ea75f 100644 --- a/src/LedgerConsensus.cpp +++ b/src/LedgerConsensus.cpp @@ -408,7 +408,12 @@ void LedgerConsensus::statePreClose() int proposersClosed = mPeerPositions.size(); // This ledger is open. This computes how long since the last ledger closed - int sinceClose = 1000 * (theApp->getOPs().getCloseTimeNC() - theApp->getOPs().getLastCloseNetTime()); + int lastCloseTime; + if (!anyTransactions && mPreviousLedger->getCloseAgree()) + lastCloseTime = mPreviousLedger->getCloseTimeNC(); + else + lastCloseTime = theApp->getOPs().getLastCloseNetTime(); + int sinceClose = 1000 * (theApp->getOPs().getCloseTimeNC() - lastCloseTime); if (sinceClose >= ContinuousLedgerTiming::shouldClose(anyTransactions, mPreviousProposers, proposersClosed, mPreviousMSeconds, sinceClose)) @@ -911,12 +916,12 @@ void LedgerConsensus::accept(SHAMap::pointer set) SerializedValidation::pointer v = boost::make_shared (newLCLHash, newLCL->getCloseTimeNC(), mValSeed, mProposing); v->setTrusted(); + Log(lsINFO) << "CNF Val " << newLCLHash.GetHex(); theApp->getValidations().addValidation(v); std::vector validation = v->getSigned(); newcoin::TMValidation val; val.set_validation(&validation[0], validation.size()); theApp->getConnectionPool().relayMessage(NULL, boost::make_shared(val, newcoin::mtVALIDATION)); - Log(lsINFO) << "CNF Val " << newLCLHash.GetHex(); } else Log(lsINFO) << "CNF newLCL " << newLCLHash.GetHex(); From 227754496e0b995b9920fd80bffa5baff9b0b8b2 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 13 Aug 2012 23:14:39 -0700 Subject: [PATCH 12/21] Fix what is probably *the* bug. We aren't usually in our own UNL, so we specially mark our validations trusted. But that wasn't properly taken into account in one case where we decide if a validation is current. This causes two nodes to each not recognize their own validations, so they tend to exchange ledgers. Cleanups, extra logging. --- src/ValidationCollection.cpp | 34 +++++++++++++++++++++++++++------- src/ValidationCollection.h | 2 +- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/ValidationCollection.cpp b/src/ValidationCollection.cpp index 2f29327140..1502e4b52d 100644 --- a/src/ValidationCollection.cpp +++ b/src/ValidationCollection.cpp @@ -5,11 +5,13 @@ #include "LedgerTiming.h" #include "Log.h" -bool ValidationCollection::addValidation(SerializedValidation::pointer val) +// #define VC_DEBUG + +bool ValidationCollection::addValidation(SerializedValidation::pointer& val) { NewcoinAddress signer = val->getSignerPublic(); bool isCurrent = false; - if (theApp->getUNL().nodeInUNL(signer)) + if (theApp->getUNL().nodeInUNL(signer) || val->isTrusted()) { val->setTrusted(); uint32 now = theApp->getOPs().getCloseTimeNC(); @@ -51,7 +53,7 @@ bool ValidationCollection::addValidation(SerializedValidation::pointer val) } Log(lsINFO) << "Val for " << hash.GetHex() << " from " << signer.humanNodePublic() - << " added " << (val->isTrusted() ? "trusted" : "UNtrusted"); + << " added " << (val->isTrusted() ? "trusted/" : "UNtrusted/") << (isCurrent ? "current" : "stale"); return isCurrent; } @@ -83,6 +85,12 @@ void ValidationCollection::getValidationCount(const uint256& ledger, bool curren uint32 closeTime = vit->second->getCloseTime(); if ((now < (closeTime - LEDGER_EARLY_INTERVAL)) || (now > (closeTime + LEDGER_VAL_INTERVAL))) isTrusted = false; + else + { +#ifdef VC_DEBUG + Log(lsINFO) << "VC: Untrusted due to time " << ledger.GetHex(); +#endif + } } if (isTrusted) ++trusted; @@ -90,6 +98,9 @@ void ValidationCollection::getValidationCount(const uint256& ledger, bool curren ++untrusted; } } +#ifdef VC_DEBUG + Log(lsINFO) << "VC: " << ledger.GetHex() << "t:" << trusted << " u:" << untrusted; +#endif } int ValidationCollection::getTrustedValidationCount(const uint256& ledger) @@ -135,12 +146,18 @@ boost::unordered_map ValidationCollection::getCurrentValidations() if (pair.oldest && (now > (pair.oldest->getCloseTime() + LEDGER_VAL_INTERVAL))) { +#ifdef VC_DEBUG + Log(lsINFO) << "VC: " << it->first.GetHex() << " removeOldestStale"; +#endif mStaleValidations.push_back(pair.oldest); pair.oldest = SerializedValidation::pointer(); condWrite(); } if (pair.newest && (now > (pair.newest->getCloseTime() + LEDGER_VAL_INTERVAL))) { +#ifdef VC_DEBUG + Log(lsINFO) << "VC: " << it->first.GetHex() << " removeNewestStale"; +#endif mStaleValidations.push_back(pair.newest); pair.newest = SerializedValidation::pointer(); condWrite(); @@ -151,14 +168,18 @@ boost::unordered_map ValidationCollection::getCurrentValidations() { if (pair.oldest) { -// Log(lsTRACE) << "OLD " << pair.oldest->getLedgerHash().GetHex() << " " << +#ifdef VC_DEBUG + Log(lsTRACE) << "VC: OLD " << pair.oldest->getLedgerHash().GetHex() << " " << boost::lexical_cast(pair.oldest->getCloseTime()); +#endif ++ret[pair.oldest->getLedgerHash()]; } if (pair.newest) { -// Log(lsTRACE) << "NEW " << pair.newest->getLedgerHash().GetHex() << " " << +#ifdef VC_DEBUG + Log(lsTRACE) << "VC: NEW " << pair.newest->getLedgerHash().GetHex() << " " << boost::lexical_cast(pair.newest->getCloseTime()); +#endif ++ret[pair.newest->getLedgerHash()]; } ++it; @@ -224,8 +245,7 @@ void ValidationCollection::condWrite() void ValidationCollection::doWrite() { static boost::format insVal("INSERT INTO LedgerValidations " - "(LedgerHash,NodePubKey,Flags,CloseTime,Signature) VALUES " - "('%s','%s','%u','%u',%s);"); + "(LedgerHash,NodePubKey,Flags,CloseTime,Signature) VALUES ('%s','%s','%u','%u',%s);"); boost::mutex::scoped_lock sl(mValidationLock); assert(mWriting); diff --git a/src/ValidationCollection.h b/src/ValidationCollection.h index 2198a967fe..1ed522dc54 100644 --- a/src/ValidationCollection.h +++ b/src/ValidationCollection.h @@ -38,7 +38,7 @@ protected: public: ValidationCollection() : mWriting(false) { ; } - bool addValidation(SerializedValidation::pointer); + bool addValidation(SerializedValidation::pointer&); ValidationSet getValidations(const uint256& ledger); void getValidationCount(const uint256& ledger, bool currentOnly, int& trusted, int& untrusted); From 04427b4ad024bc2de694b6555a66a1095c5414ee Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 13 Aug 2012 23:15:50 -0700 Subject: [PATCH 13/21] Cleanups. --- src/NetworkOPs.cpp | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/src/NetworkOPs.cpp b/src/NetworkOPs.cpp index 355318844c..afbf87e32a 100644 --- a/src/NetworkOPs.cpp +++ b/src/NetworkOPs.cpp @@ -322,8 +322,11 @@ public: { if (trustedValidations > v.trustedValidations) return true; if (trustedValidations < v.trustedValidations) return false; - if (nodesUsing > v.nodesUsing) return true; - if (nodesUsing < v.nodesUsing) return false; + if (trustedValidations == 0) + { + if (nodesUsing > v.nodesUsing) return true; + if (nodesUsing < v.nodesUsing) return false; + } return highNode > v.highNode; } }; @@ -332,6 +335,7 @@ void NetworkOPs::checkState(const boost::system::error_code& result) { // Network state machine if (result == boost::asio::error::operation_aborted) return; + setStateTimer(); std::vector peerList = theApp->getConnectionPool().getPeerVector(); @@ -344,7 +348,6 @@ void NetworkOPs::checkState(const boost::system::error_code& result) Log(lsWARNING) << "Node count (" << peerList.size() << ") has fallen below quorum (" << theConfig.NETWORK_QUORUM << ")."; } - setStateTimer(); return; } if (mMode == omDISCONNECTED) @@ -356,7 +359,6 @@ void NetworkOPs::checkState(const boost::system::error_code& result) if (mConsensus) { mConsensus->timerEntry(); - setStateTimer(); return; } @@ -383,15 +385,13 @@ 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() + 4)) + if (theApp->getOPs().getNetworkTimeNC() < theApp->getMasterLedger().getCurrentLedger()->getCloseTimeNC()) setMode(omFULL); - else - Log(lsINFO) << "Will try to go to FULL in consensus window"; } if (mMode == omFULL) { + // WRITEME // check if the ledger is bad enough to go to omTRACKING } @@ -399,7 +399,6 @@ void NetworkOPs::checkState(const boost::system::error_code& result) beginConsensus(networkClosed, theApp->getMasterLedger().getCurrentLedger()); if (mConsensus) mConsensus->timerEntry(); - setStateTimer(); } bool NetworkOPs::checkLastClosedLedger(const std::vector& peerList, uint256& networkClosed) @@ -460,7 +459,7 @@ bool NetworkOPs::checkLastClosedLedger(const std::vector& peerLis { bool isDead = theApp->getValidations().isDeadLedger(it->first); Log(lsTRACE) << "L: " << it->first.GetHex() << ((isDead) ? " dead" : " live") << - " t=" << it->second.trustedValidations << ", n=" << it->second.nodesUsing; + " t=" << it->second.trustedValidations << ", n=" << it->second.nodesUsing; if ((it->second > bestVC) && !isDead) { bestVC = it->second; @@ -633,20 +632,23 @@ bool NetworkOPs::recvPropose(uint32 proposeSeq, const uint256& proposeHash, uint SHAMap::pointer NetworkOPs::getTXMap(const uint256& hash) { - if (!mConsensus) return SHAMap::pointer(); + if (!mConsensus) + return SHAMap::pointer(); return mConsensus->getTransactionTree(hash, false); } bool NetworkOPs::gotTXData(boost::shared_ptr peer, const uint256& hash, const std::list& nodeIDs, const std::list< std::vector >& nodeData) { - if (!mConsensus) return false; + if (!mConsensus) + return false; return mConsensus->peerGaveNodes(peer, hash, nodeIDs, nodeData); } bool NetworkOPs::hasTXSet(boost::shared_ptr peer, const uint256& set, newcoin::TxSetStatus status) { - if (!mConsensus) return false; + if (!mConsensus) + return false; return mConsensus->peerHasSet(peer, set, status); } @@ -677,10 +679,14 @@ void NetworkOPs::setMode(OperatingMode om) if ((om >= omCONNECTED) && (mMode == omDISCONNECTED)) mConnectTime = boost::posix_time::second_clock::universal_time(); Log l((om < mMode) ? lsWARNING : lsINFO); - if (om == omDISCONNECTED) l << "STATE->Disonnected"; - else if (om == omCONNECTED) l << "STATE->Connected"; - else if (om == omTRACKING) l << "STATE->Tracking"; - else l << "STATE->Full"; + if (om == omDISCONNECTED) + l << "STATE->Disonnected"; + else if (om == omCONNECTED) + l << "STATE->Connected"; + else if (om == omTRACKING) + l << "STATE->Tracking"; + else + l << "STATE->Full"; mMode = om; } From 3dcdc3b94a449c7b506b02d917a706e5df2b0508 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 14 Aug 2012 01:51:17 -0700 Subject: [PATCH 14/21] Fire up the aux thread earlier. --- src/Application.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Application.cpp b/src/Application.cpp index daac98dd54..af3b17f9a0 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -70,11 +70,11 @@ void Application::run() if (!theConfig.DEBUG_LOGFILE.empty()) Log::setLogFile(theConfig.DEBUG_LOGFILE); - mSNTPClient.init(theConfig.SNTP_SERVERS); - boost::thread auxThread(boost::bind(&boost::asio::io_service::run, &mAuxService)); auxThread.detach(); + mSNTPClient.init(theConfig.SNTP_SERVERS); + // // Construct databases. // From 046c539d49f0e8cb0b262c08d337cdd1f80040f2 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 14 Aug 2012 01:51:35 -0700 Subject: [PATCH 15/21] Mark a parameter as unused. --- src/Ledger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ledger.cpp b/src/Ledger.cpp index 131e7d3b91..0cd6e2346d 100644 --- a/src/Ledger.cpp +++ b/src/Ledger.cpp @@ -57,7 +57,7 @@ Ledger::Ledger(Ledger& ledger, bool isMutable) : mTotCoins(ledger.mTotCoins), mL } -Ledger::Ledger(bool dummy, Ledger& prevLedger) : +Ledger::Ledger(bool /* dummy */, Ledger& prevLedger) : mTotCoins(prevLedger.mTotCoins), mLedgerSeq(prevLedger.mLedgerSeq + 1), mParentCloseTime(prevLedger.mCloseTime), mCloseResolution(prevLedger.mCloseResolution), mCloseFlags(0), mClosed(false), mValidHash(false), mAccepted(false), mImmutable(false), From 4b2ae556bd29fc31988ed595b8667b530ffbc96f Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 14 Aug 2012 01:51:46 -0700 Subject: [PATCH 16/21] Downgrade a timing issue from fatal to warning. --- src/LedgerTiming.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/LedgerTiming.cpp b/src/LedgerTiming.cpp index ae0d65de19..9243dd6ce0 100644 --- a/src/LedgerTiming.cpp +++ b/src/LedgerTiming.cpp @@ -22,8 +22,8 @@ int ContinuousLedgerTiming::shouldClose( if ((previousMSeconds < -1000) || (previousMSeconds > 600000) || (currentMSeconds < -1000) || (currentMSeconds > 600000)) { - Log(lsFATAL) << - boost::str(boost::format("CLC::shouldClose range error Trans=%s, Prop: %d/%d, Secs: %d (last:%d)") + Log(lsWARNING) << + boost::str(boost::format("CLC::shouldClose range Trans=%s, Prop: %d/%d, Secs: %d (last:%d)") % (anyTransactions ? "yes" : "no") % previousProposers % proposersClosed % currentMSeconds % previousMSeconds); return currentMSeconds; From e473ce84248a4cfc3edfd38ad53910744c023593 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 14 Aug 2012 15:35:30 -0700 Subject: [PATCH 17/21] Support "standalone" mode (-a or --standalone) in which we do not connect to the network and do not close ledgers. This mode makes it much easier to test transactions as they are only applied once to the open ledger. --- src/Application.cpp | 17 +++++++++++++---- src/Config.cpp | 5 +++++ src/Config.h | 2 ++ src/ConnectionPool.cpp | 5 +++++ src/LedgerMaster.h | 2 ++ src/NetworkOPs.cpp | 4 ++-- src/RPCServer.cpp | 3 +++ src/main.cpp | 7 +++++++ 8 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/Application.cpp b/src/Application.cpp index af3b17f9a0..2fe18c161f 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -95,13 +95,14 @@ void Application::run() // // Set up UNL. // - getUNL().nodeBootstrap(); + if (!theConfig.RUN_STANDALONE) + getUNL().nodeBootstrap(); // // Allow peer connections. // - if (!theConfig.PEER_IP.empty() && theConfig.PEER_PORT) + if (!theConfig.RUN_STANDALONE && !theConfig.PEER_IP.empty() && theConfig.PEER_PORT) { mPeerDoor = new PeerDoor(mIOService); } @@ -127,7 +128,8 @@ void Application::run() // // Begin connecting to network. // - mConnectionPool.start(); + if (!theConfig.RUN_STANDALONE) + mConnectionPool.start(); // New stuff. NewcoinAddress rootSeedMaster = NewcoinAddress::createSeedGeneric("masterpassphrase"); @@ -155,7 +157,14 @@ void Application::run() } - mNetOps.setStateTimer(); + if (theConfig.RUN_STANDALONE) + { + Log(lsWARNING) << "Running in standalone mode"; + mNetOps.setStandAlone(); + mMasterLedger.runStandAlone(); + } + else + mNetOps.setStateTimer(); mIOService.run(); // This blocks diff --git a/src/Config.cpp b/src/Config.cpp index cf9c135bfe..ef79cae52a 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -40,6 +40,11 @@ Config theConfig; +void Config::init() +{ + RUN_STANDALONE = false; +} + void Config::setup(const std::string& strConf) { boost::system::error_code ec; diff --git a/src/Config.h b/src/Config.h index 585980b92b..a7828da7b6 100644 --- a/src/Config.h +++ b/src/Config.h @@ -63,6 +63,7 @@ public: int LEDGER_PROPOSAL_DELAY_SECONDS; int LEDGER_AVALANCHE_SECONDS; bool LEDGER_CREATOR; // should be false unless we are starting a new ledger + bool RUN_STANDALONE; // Note: The following parameters do not relate to the UNL or trust at all unsigned int NETWORK_QUORUM; // Minimum number of nodes to consider the network present @@ -100,6 +101,7 @@ public: // Client behavior int ACCOUNT_PROBE_MAX; // How far to scan for accounts. + void init(); void setup(const std::string& strConf); void load(); }; diff --git a/src/ConnectionPool.cpp b/src/ConnectionPool.cpp index 2a7f38bb7e..3d79fbc2ad 100644 --- a/src/ConnectionPool.cpp +++ b/src/ConnectionPool.cpp @@ -42,6 +42,9 @@ ConnectionPool::ConnectionPool(boost::asio::io_service& io_service) : void ConnectionPool::start() { + if (theConfig.RUN_STANDALONE) + return; + // Start running policy. policyEnforce(); @@ -243,6 +246,8 @@ void ConnectionPool::relayMessage(Peer* fromPeer, PackedMessage::pointer msg) // Requires sane IP and port. void ConnectionPool::connectTo(const std::string& strIp, int iPort) { + if (theConfig.RUN_STANDALONE) + return; { Database* db = theApp->getWalletDB()->getDB(); ScopedLock sl(theApp->getWalletDB()->getDBLock()); diff --git a/src/LedgerMaster.h b/src/LedgerMaster.h index 9f9603f1bc..187aaeec13 100644 --- a/src/LedgerMaster.h +++ b/src/LedgerMaster.h @@ -43,6 +43,8 @@ public: // The finalized ledger is the last closed/accepted ledger Ledger::pointer getClosedLedger() { return mFinalizedLedger; } + void runStandAlone() { mFinalizedLedger = mCurrentLedger; } + TransactionEngineResult doTransaction(const SerializedTransaction& txn, uint32 targetLedger, TransactionEngineParams params); diff --git a/src/NetworkOPs.cpp b/src/NetworkOPs.cpp index afbf87e32a..d7180a6ae9 100644 --- a/src/NetworkOPs.cpp +++ b/src/NetworkOPs.cpp @@ -333,7 +333,7 @@ public: void NetworkOPs::checkState(const boost::system::error_code& result) { // Network state machine - if (result == boost::asio::error::operation_aborted) + if ((result == boost::asio::error::operation_aborted) || theConfig.RUN_STANDALONE) return; setStateTimer(); @@ -680,7 +680,7 @@ void NetworkOPs::setMode(OperatingMode om) mConnectTime = boost::posix_time::second_clock::universal_time(); Log l((om < mMode) ? lsWARNING : lsINFO); if (om == omDISCONNECTED) - l << "STATE->Disonnected"; + l << "STATE->Disconnected"; else if (om == omCONNECTED) l << "STATE->Connected"; else if (om == omTRACKING) diff --git a/src/RPCServer.cpp b/src/RPCServer.cpp index 46ea9eda7d..9bf863a356 100644 --- a/src/RPCServer.cpp +++ b/src/RPCServer.cpp @@ -832,6 +832,9 @@ Json::Value RPCServer::doAccountWalletSet(const Json::Value& params) { Json::Value RPCServer::doConnect(const Json::Value& params) { + if (theConfig.RUN_STANDALONE) + return "cannot connect in standalone mode"; + // connect [port] std::string strIp; int iPort = -1; diff --git a/src/main.cpp b/src/main.cpp index 155408170a..c78da1e246 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -84,6 +84,7 @@ int main(int argc, char* argv[]) int iResult = 0; po::variables_map vm; // Map of options. bool bTest = false; + theConfig.init(); // // Set up option parsing. @@ -93,6 +94,7 @@ int main(int argc, char* argv[]) ("help,h", "Display this message.") ("conf", po::value(), "Specify the configuration file.") ("rpc", "Perform rpc command (default).") + ("standalone,a", "Run with no peers.") ("test,t", "Perform unit tests.") ("parameters", po::value< vector >(), "Specify comma separated parameters.") ("verbose,v", "Increase log level") @@ -142,6 +144,11 @@ int main(int argc, char* argv[]) Log::setMinSeverity(lsTRACE); } + if (vm.count("standalone")) + { + theConfig.RUN_STANDALONE = true; + } + if (!iResult) { theConfig.setup(vm.count("conf") ? vm["conf"].as() : ""); From 89c7c26c2f409ec9a62542dfc9887604f4a2847a Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 14 Aug 2012 15:36:50 -0700 Subject: [PATCH 18/21] Oops. --- src/NetworkOPs.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/NetworkOPs.h b/src/NetworkOPs.h index 8e8e45c24c..44eebc0ae4 100644 --- a/src/NetworkOPs.h +++ b/src/NetworkOPs.h @@ -188,6 +188,7 @@ public: bool checkLastClosedLedger(const std::vector&, uint256& networkClosed); int beginConsensus(const uint256& networkClosed, Ledger::pointer closingLedger); void endConsensus(bool correctLCL); + void setStandAlone() { setMode(omFULL); } void setStateTimer(); void newLCL(int proposers, int convergeTime, const uint256& ledgerHash); int getPreviousProposers() { return mLastCloseProposers; } From 36fb085114deadc96ec4aa9f72b7994267fc8601 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 14 Aug 2012 15:59:25 -0700 Subject: [PATCH 19/21] Make this more readable. --- src/NetworkOPs.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/NetworkOPs.cpp b/src/NetworkOPs.cpp index d7180a6ae9..f5458b48d5 100644 --- a/src/NetworkOPs.cpp +++ b/src/NetworkOPs.cpp @@ -678,15 +678,15 @@ void NetworkOPs::setMode(OperatingMode om) if (mMode == om) return; if ((om >= omCONNECTED) && (mMode == omDISCONNECTED)) mConnectTime = boost::posix_time::second_clock::universal_time(); - Log l((om < mMode) ? lsWARNING : lsINFO); + Log lg((om < mMode) ? lsWARNING : lsINFO); if (om == omDISCONNECTED) - l << "STATE->Disconnected"; + lg << "STATE->Disconnected"; else if (om == omCONNECTED) - l << "STATE->Connected"; + lg << "STATE->Connected"; else if (om == omTRACKING) - l << "STATE->Tracking"; + lg << "STATE->Tracking"; else - l << "STATE->Full"; + lg << "STATE->Full"; mMode = om; } From d3bce70e862c9f8a997aa36f0d1874542a8cf1fb Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 14 Aug 2012 16:00:03 -0700 Subject: [PATCH 20/21] Remove Config::init. It's not needed. --- src/Config.cpp | 7 ++----- src/Config.h | 1 - src/main.cpp | 11 +++++------ 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/Config.cpp b/src/Config.cpp index ef79cae52a..4e36f39a1b 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -40,11 +40,6 @@ Config theConfig; -void Config::init() -{ - RUN_STANDALONE = false; -} - void Config::setup(const std::string& strConf) { boost::system::error_code ec; @@ -155,6 +150,8 @@ void Config::setup(const std::string& strConf) VALIDATORS_SITE = DEFAULT_VALIDATORS_SITE; + RUN_STANDALONE = false; + load(); } diff --git a/src/Config.h b/src/Config.h index a7828da7b6..89fb60b3de 100644 --- a/src/Config.h +++ b/src/Config.h @@ -101,7 +101,6 @@ public: // Client behavior int ACCOUNT_PROBE_MAX; // How far to scan for accounts. - void init(); void setup(const std::string& strConf); void load(); }; diff --git a/src/main.cpp b/src/main.cpp index c78da1e246..4499a2c588 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -84,7 +84,6 @@ int main(int argc, char* argv[]) int iResult = 0; po::variables_map vm; // Map of options. bool bTest = false; - theConfig.init(); // // Set up option parsing. @@ -144,16 +143,16 @@ int main(int argc, char* argv[]) Log::setMinSeverity(lsTRACE); } - if (vm.count("standalone")) - { - theConfig.RUN_STANDALONE = true; - } - if (!iResult) { theConfig.setup(vm.count("conf") ? vm["conf"].as() : ""); } + if (vm.count("standalone")) + { + theConfig.RUN_STANDALONE = true; + } + if (iResult) { nothing(); From 64d6f160681c0f01c5332d55138e2ae014fc73f4 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Tue, 14 Aug 2012 16:04:39 -0700 Subject: [PATCH 21/21] Minor cleanup. --- src/main.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 4499a2c588..444231ba3a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -146,11 +146,11 @@ int main(int argc, char* argv[]) if (!iResult) { theConfig.setup(vm.count("conf") ? vm["conf"].as() : ""); - } - if (vm.count("standalone")) - { - theConfig.RUN_STANDALONE = true; + if (vm.count("standalone")) + { + theConfig.RUN_STANDALONE = true; + } } if (iResult)