diff --git a/src/Application.h b/src/Application.h index 7d9ada8ea5..ec00b94e89 100644 --- a/src/Application.h +++ b/src/Application.h @@ -14,6 +14,7 @@ #include "NetworkOPs.h" #include "TaggedCache.h" #include "ValidationCollection.h" +#include "Suppression.h" #include "../database/database.h" @@ -46,6 +47,7 @@ class Application NetworkOPs mNetOps; NodeCache mNodeCache; ValidationCollection mValidations; + SuppressionTable mSuppressions; DatabaseCon *mTxnDB, *mLedgerDB, *mWalletDB, *mHashNodeDB, *mNetNodeDB; @@ -77,6 +79,8 @@ public: TransactionMaster& getMasterTransaction() { return mMasterTransaction; } NodeCache& getNodeCache() { return mNodeCache; } ValidationCollection& getValidations() { return mValidations; } + bool suppress(const uint256& s) { return mSuppressions.addSuppression(s); } + bool suppress(const uint160& s) { return mSuppressions.addSuppression(s); } DatabaseCon* getTxnDB() { return mTxnDB; } DatabaseCon* getLedgerDB() { return mLedgerDB; } diff --git a/src/CanonicalTXSet.cpp b/src/CanonicalTXSet.cpp index 93ed79ccd4..c46c089374 100644 --- a/src/CanonicalTXSet.cpp +++ b/src/CanonicalTXSet.cpp @@ -44,10 +44,12 @@ void CanonicalTXSet::push_back(SerializedTransaction::pointer txn) mMap.insert(std::make_pair(CanonicalTXKey(effectiveAccount, txn->getSequence(), txn->getTransactionID()), txn)); } -void CanonicalTXSet::eraseInc(iterator& it) +CanonicalTXSet::iterator CanonicalTXSet::erase(const iterator& it) { - iterator tmp = it++; - mMap.erase(tmp); + iterator tmp = it; + ++tmp; + mMap.erase(it); + return tmp; } diff --git a/src/CanonicalTXSet.h b/src/CanonicalTXSet.h index f78c580cd9..6978859af7 100644 --- a/src/CanonicalTXSet.h +++ b/src/CanonicalTXSet.h @@ -39,8 +39,7 @@ public: CanonicalTXSet(const uint256& lclHash) : mSetHash(lclHash) { ; } void push_back(SerializedTransaction::pointer txn); - void erase(const iterator& it) { mMap.erase(it); } - void eraseInc(iterator& it); + iterator erase(const iterator& it); iterator begin() { return mMap.begin(); } iterator end() { return mMap.end(); } diff --git a/src/ConnectionPool.cpp b/src/ConnectionPool.cpp index d4e5bb7b36..12373a0da6 100644 --- a/src/ConnectionPool.cpp +++ b/src/ConnectionPool.cpp @@ -1,9 +1,5 @@ #include "ConnectionPool.h" -#include "Config.h" -#include "Peer.h" -#include "Application.h" -#include "utils.h" #include #include @@ -11,6 +7,13 @@ #include #include +#include "Config.h" +#include "Peer.h" +#include "Application.h" +#include "utils.h" +#include "Log.h" + + // How often to enforce policies. #define POLICY_INTERVAL_SECONDS 5 @@ -174,7 +177,7 @@ void ConnectionPool::policyEnforce() { boost::posix_time::ptime tpNow = boost::posix_time::second_clock::universal_time(); - std::cerr << "policyEnforce: begin: " << tpNow << std::endl; + Log(lsTRACE) << "policyEnforce: begin: " << tpNow; // Cancel any in progrss timer. (void) mPolicyTimer.cancel(); @@ -187,7 +190,7 @@ void ConnectionPool::policyEnforce() tpNext = boost::posix_time::second_clock::universal_time()+boost::posix_time::seconds(POLICY_INTERVAL_SECONDS); - std::cerr << "policyEnforce: schedule : " << tpNext << std::endl; + Log(lsTRACE) << "policyEnforce: schedule : " << tpNext; mPolicyTimer.expires_at(tpNext); mPolicyTimer.async_wait(boost::bind(&ConnectionPool::policyHandler, this, _1)); @@ -218,7 +221,7 @@ void ConnectionPool::relayMessage(Peer* fromPeer, PackedMessage::pointer msg) Peer::pointer peer = pair.second; if (!peer) std::cerr << "CP::RM null peer in list" << std::endl; - else if (!fromPeer || !(peer.get() == fromPeer)) + else if ((!fromPeer || !(peer.get() == fromPeer)) && peer->isConnected()) peer->sendPacket(msg); } } diff --git a/src/Conversion.cpp b/src/Conversion.cpp index a0ac3c1e91..7f9de9029b 100644 --- a/src/Conversion.cpp +++ b/src/Conversion.cpp @@ -42,13 +42,6 @@ bool u160ToHuman(uint160& buf, std::string& retStr) #endif -base_uint160 uint256::to160() const -{ - uint160 m; - memcpy(m.begin(), begin(), m.size()); - return m; -} - base_uint256 uint160::to256() const { uint256 m; diff --git a/src/Ledger.h b/src/Ledger.h index 64ae24a6d5..1f9c8b6c60 100644 --- a/src/Ledger.h +++ b/src/Ledger.h @@ -99,6 +99,7 @@ public: void setImmutable() { updateHash(); mImmutable = true; } bool isClosed() { return mClosed; } bool isAccepted() { return mAccepted; } + bool isImmutable() { return mImmutable; } // This ledger has closed, will never be accepted, and is accepting // new transactions to be re-repocessed when do accept a new last-closed ledger diff --git a/src/LedgerAcquire.cpp b/src/LedgerAcquire.cpp index be389a4eb1..92e849b18d 100644 --- a/src/LedgerAcquire.cpp +++ b/src/LedgerAcquire.cpp @@ -254,7 +254,7 @@ void PeerSet::sendRequest(const newcoin::TMGetLedger& tmGL) while (it != mPeers.end()) { if (it->expired()) - mPeers.erase(it++); + it = mPeers.erase(it); else { // FIXME: Track last peer sent to and time sent @@ -370,10 +370,10 @@ bool LedgerAcquireMaster::hasLedger(const uint256& hash) return mLedgers.find(hash) != mLedgers.end(); } -bool LedgerAcquireMaster::dropLedger(const uint256& hash) +void LedgerAcquireMaster::dropLedger(const uint256& hash) { boost::mutex::scoped_lock sl(mLock); - return mLedgers.erase(hash); + mLedgers.erase(hash); } bool LedgerAcquireMaster::gotLedgerData(newcoin::TMLedgerData& packet, Peer::pointer peer) diff --git a/src/LedgerAcquire.h b/src/LedgerAcquire.h index 211567d320..681d4bd0e0 100644 --- a/src/LedgerAcquire.h +++ b/src/LedgerAcquire.h @@ -128,7 +128,7 @@ public: LedgerAcquire::pointer findCreate(const uint256& hash); LedgerAcquire::pointer find(const uint256& hash); bool hasLedger(const uint256& ledgerHash); - bool dropLedger(const uint256& ledgerHash); + void dropLedger(const uint256& ledgerHash); bool gotLedgerData(newcoin::TMLedgerData& packet, Peer::pointer); }; diff --git a/src/LedgerConsensus.cpp b/src/LedgerConsensus.cpp index 7c84b258cf..ca556745b1 100644 --- a/src/LedgerConsensus.cpp +++ b/src/LedgerConsensus.cpp @@ -217,7 +217,7 @@ void LedgerConsensus::takeInitialPosition(Ledger::pointer initialLedger) mOurPosition = boost::make_shared (theConfig.VALIDATION_SEED, initialLedger->getParentHash(), txSet); - mapComplete(txSet, initialSet); + mapComplete(txSet, initialSet, false); propose(std::vector(), std::vector()); } @@ -241,9 +241,10 @@ void LedgerConsensus::createDisputes(SHAMap::pointer m1, SHAMap::pointer m2) } } -void LedgerConsensus::mapComplete(const uint256& hash, SHAMap::pointer map) +void LedgerConsensus::mapComplete(const uint256& hash, SHAMap::pointer map, bool acquired) { - Log(lsINFO) << "We have acquired TXS " << hash.GetHex(); + if (acquired) + Log(lsINFO) << "We have acquired TXS " << hash.GetHex(); mAcquiring.erase(hash); if (!map) @@ -254,10 +255,7 @@ void LedgerConsensus::mapComplete(const uint256& hash, SHAMap::pointer map) } if (mComplete.find(hash) != mComplete.end()) - { - Log(lsERROR) << "Which we already had"; return; // we already have this map - } if (mOurPosition && (map->getHash() != mOurPosition->getCurrentHash())) { // this could create disputed transactions @@ -281,8 +279,8 @@ void LedgerConsensus::mapComplete(const uint256& hash, SHAMap::pointer map) } if (!peers.empty()) adjustCount(map, peers); - else if (!hash) - Log(lsWARNING) << "By the time we got the map, no peers were proposing it"; + else if (acquired) + Log(lsWARNING) << "By the time we got the map " << hash.GetHex() << " no peers were proposing it"; sendHaveTxSet(hash, true); } @@ -448,7 +446,7 @@ bool LedgerConsensus::updateOurPositions(int sinceClose) uint256 newHash = ourPosition->getHash(); mOurPosition->changePosition(newHash); propose(addedTx, removedTx); - mapComplete(newHash, ourPosition); + mapComplete(newHash, ourPosition, false); Log(lsINFO) << "We change our position to " << newHash.GetHex(); } @@ -468,7 +466,7 @@ SHAMap::pointer LedgerConsensus::getTransactionTree(const uint256& hash, bool do if (!hash) { SHAMap::pointer empty = boost::make_shared(); - mapComplete(hash, empty); + mapComplete(hash, empty, false); return empty; } acquiring = boost::make_shared(hash); @@ -505,7 +503,7 @@ void LedgerConsensus::startAcquiring(TransactionAcquire::pointer acquire) void LedgerConsensus::propose(const std::vector& added, const std::vector& removed) { - Log(lsDEBUG) << "We propose: " << mOurPosition->getCurrentHash().GetHex(); + Log(lsTRACE) << "We propose: " << mOurPosition->getCurrentHash().GetHex(); newcoin::TMProposeSet prop; prop.set_currenttxhash(mOurPosition->getCurrentHash().begin(), 256 / 8); prop.set_proposeseq(mOurPosition->getProposeSeq()); @@ -642,7 +640,7 @@ void LedgerConsensus::applyTransaction(TransactionEngine& engine, SerializedTran } else if (result == 0) { - Log(lsDEBUG) << " success"; + Log(lsTRACE) << " success"; assert(ledger->hasTransaction(txn->getTransactionID())); } else @@ -696,7 +694,7 @@ void LedgerConsensus::applyTransactions(SHAMap::pointer set, Ledger::pointer led if (result <= 0) { if (result == 0) ++successes; - failedTransactions.eraseInc(it); + it = failedTransactions.erase(it); } else { @@ -706,7 +704,7 @@ void LedgerConsensus::applyTransactions(SHAMap::pointer set, Ledger::pointer led catch (...) { Log(lsWARNING) << " Throws"; - failedTransactions.eraseInc(it); + it = failedTransactions.erase(it); } } } while (successes > 0); @@ -728,7 +726,7 @@ void LedgerConsensus::accept(SHAMap::pointer set) Log(lsTRACE) << "newLCL before transactions"; Json::Value p; newLCL->addJson(p, LEDGER_JSON_DUMP_TXNS | LEDGER_JSON_DUMP_STATE); - ssw.write(std::cerr, p); + ssw.write(Log(lsTRACE).ref(), p); } #endif @@ -746,7 +744,7 @@ void LedgerConsensus::accept(SHAMap::pointer set) Log(lsTRACE) << "newLCL after transactions"; Json::Value p; newLCL->addJson(p, LEDGER_JSON_DUMP_TXNS | LEDGER_JSON_DUMP_STATE); - ssw.write(std::cerr, p); + ssw.write(Log(lsTRACE).ref(), p); } #endif @@ -758,14 +756,14 @@ void LedgerConsensus::accept(SHAMap::pointer set) Log(lsTRACE) << "newOL before transactions"; Json::Value p; newOL->addJson(p, LEDGER_JSON_DUMP_TXNS | LEDGER_JSON_DUMP_STATE); - ssw.write(std::cerr, p); + ssw.write(Log(lsTRACE).ref(), p); } if (1) { Log(lsTRACE) << "current ledger"; Json::Value p; theApp->getMasterLedger().getCurrentLedger()->addJson(p, LEDGER_JSON_DUMP_TXNS | LEDGER_JSON_DUMP_STATE); - ssw.write(std::cerr, p); + ssw.write(Log(lsTRACE).ref(), p); } #endif @@ -803,7 +801,7 @@ void LedgerConsensus::accept(SHAMap::pointer set) Log(lsTRACE) << "newOL after current ledger transactions"; Json::Value p; newOL->addJson(p, LEDGER_JSON_DUMP_TXNS | LEDGER_JSON_DUMP_STATE); - ssw.write(std::cerr, p); + ssw.write(Log(lsTRACE).ref(), p); } #endif diff --git a/src/LedgerConsensus.h b/src/LedgerConsensus.h index a02bbce88a..60d4c27962 100644 --- a/src/LedgerConsensus.h +++ b/src/LedgerConsensus.h @@ -138,7 +138,7 @@ public: SHAMap::pointer getTransactionTree(const uint256& hash, bool doAcquire); TransactionAcquire::pointer getAcquiring(const uint256& hash); - void mapComplete(const uint256& hash, SHAMap::pointer map); + void mapComplete(const uint256& hash, SHAMap::pointer map, bool acquired); void abort(); int timerEntry(); diff --git a/src/LedgerHistory.cpp b/src/LedgerHistory.cpp index ad357139ab..f20a7ae53a 100644 --- a/src/LedgerHistory.cpp +++ b/src/LedgerHistory.cpp @@ -32,6 +32,7 @@ void LedgerHistory::addAcceptedLedger(Ledger::pointer ledger) uint256 h(ledger->getHash()); boost::recursive_mutex::scoped_lock sl(mLedgersByHash.peekMutex()); mLedgersByHash.canonicalize(h, ledger); + assert(ledger && ledger->isAccepted() && ledger->isImmutable()); mLedgersByIndex.insert(std::make_pair(ledger->getLedgerSeq(), ledger)); boost::thread thread(boost::bind(&Ledger::saveAcceptedLedger, ledger)); thread.detach(); @@ -71,6 +72,7 @@ Ledger::pointer LedgerHistory::getLedgerByHash(const uint256& hash) Ledger::pointer LedgerHistory::canonicalizeLedger(Ledger::pointer ledger, bool save) { + assert(ledger->isImmutable()); uint256 h(ledger->getHash()); if (!save) @@ -83,7 +85,7 @@ Ledger::pointer LedgerHistory::canonicalizeLedger(Ledger::pointer ledger, bool s // save input ledger in map if not in map, otherwise return corresponding map ledger boost::recursive_mutex::scoped_lock sl(mLedgersByHash.peekMutex()); mLedgersByHash.canonicalize(h, ledger); - if (ledger->isAccepted()) mLedgersByIndex[ledger->getLedgerSeq()]=ledger; + if (ledger->isAccepted()) mLedgersByIndex[ledger->getLedgerSeq()] = ledger; return ledger; } // vim:ts=4 diff --git a/src/LedgerMaster.cpp b/src/LedgerMaster.cpp index 3d1f1858c3..ea1b4bdce7 100644 --- a/src/LedgerMaster.cpp +++ b/src/LedgerMaster.cpp @@ -40,13 +40,14 @@ void LedgerMaster::pushLedger(Ledger::pointer newLCL, Ledger::pointer newOL) assert(newLCL->isClosed() && newLCL->isAccepted()); assert(!newOL->isClosed() && !newOL->isAccepted()); - ScopedLock sl(mLock); - if (mFinalizedLedger && mFinalizedLedger->isAccepted()) + if (newLCL->isAccepted()) { mLedgerHistory.addAcceptedLedger(mFinalizedLedger); Log(lsINFO) << "StashAccepted: " << mFinalizedLedger->getHash().GetHex(); } + mFinalizedLedger = newLCL; + ScopedLock sl(mLock); mCurrentLedger = newOL; mEngine.setLedger(newOL); } diff --git a/src/Log.cpp b/src/Log.cpp index 5efe21a890..bdd56959b2 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -7,7 +7,7 @@ boost::recursive_mutex Log::sLock; -LogSeverity Log::sMinSeverity = lsWARNING; +LogSeverity Log::sMinSeverity = lsINFO; std::ofstream* Log::outStream = NULL; diff --git a/src/NetworkOPs.cpp b/src/NetworkOPs.cpp index ffe901c1ac..e96a0d4306 100644 --- a/src/NetworkOPs.cpp +++ b/src/NetworkOPs.cpp @@ -98,6 +98,18 @@ Transaction::pointer NetworkOPs::processTransaction(Transaction::pointer trans, } Log(lsDEBUG) << "Status other than success " << r ; + if ((mMode != omFULL) && (theApp->suppress(trans->getID()))) + { + newcoin::TMTransaction tx; + Serializer s; + trans->getSTransaction()->add(s); + tx.set_rawtransaction(&s.getData().front(), s.getLength()); + tx.set_status(newcoin::tsCURRENT); + tx.set_receivetimestamp(getNetworkTimeNC()); + tx.set_ledgerindexpossible(tgtLedger); + PackedMessage::pointer packet = boost::make_shared(tx, newcoin::mtTRANSACTION); + theApp->getConnectionPool().relayMessage(source, packet); + } trans->setStatus(INVALID); return trans; @@ -234,15 +246,17 @@ RippleState::pointer NetworkOPs::getRippleState(const uint256& uLedger, const ui void NetworkOPs::setStateTimer(int sec) { // set timer early if ledger is closing - uint64 consensusTime = mLedgerMaster->getCurrentLedger()->getCloseTimeNC() - LEDGER_WOBBLE_TIME; - uint64 now = getNetworkTimeNC(); - - if ((mMode == omFULL) && !mConsensus) + if (!mConsensus && ((mMode == omFULL) || (mMode == omTRACKING))) { - if (now >= consensusTime) sec = 0; - else if (sec > (consensusTime - now)) sec = (consensusTime - now); - } + uint64 consensusTime = mLedgerMaster->getCurrentLedger()->getCloseTimeNC() - LEDGER_WOBBLE_TIME; + uint64 now = getNetworkTimeNC(); + if ((mMode == omFULL) && !mConsensus) + { + if (now >= consensusTime) sec = 0; + else if (sec > (consensusTime - now)) sec = (consensusTime - now); + } + } mNetTimer.expires_from_now(boost::posix_time::seconds(sec)); mNetTimer.async_wait(boost::bind(&NetworkOPs::checkState, this, boost::asio::placeholders::error)); } @@ -354,9 +368,9 @@ void NetworkOPs::checkState(const boost::system::error_code& result) if (switchLedgers) { Log(lsWARNING) << "We are not running on the consensus ledger"; - Log(lsINFO) << "Our LCL " << currentClosed->getHash().GetHex() ; - Log(lsINFO) << "Net LCL " << closedLedger.GetHex() ; - if ((mMode == omTRACKING) || (mMode == omFULL)) setMode(omTRACKING); + Log(lsINFO) << "Our LCL " << currentClosed->getHash().GetHex(); + Log(lsINFO) << "Net LCL " << closedLedger.GetHex(); + if ((mMode == omTRACKING) || (mMode == omFULL)) setMode(omCONNECTED); Ledger::pointer consensus = mLedgerMaster->getLedgerByHash(closedLedger); if (!consensus) { @@ -400,7 +414,14 @@ 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 ((!switchLedgers) && theConfig.VALIDATION_SEED.isValid()) setMode(omFULL); + if ((!switchLedgers) && theConfig.VALIDATION_SEED.isValid()) + { + if (theApp->getOPs().getNetworkTimeNC() < + (theApp->getMasterLedger().getCurrentLedger()->getCloseTimeNC() + 4)) + setMode(omFULL); + else + Log(lsWARNING) << "Too late to go to full, try next ledger"; + } } if (mMode == omFULL) @@ -408,6 +429,12 @@ void NetworkOPs::checkState(const boost::system::error_code& result) // check if the ledger is bad enough to go to omTRACKING } + if (mMode != omFULL) + { + setStateTimer(4); + return; + } + int secondsToClose = theApp->getMasterLedger().getCurrentLedger()->getCloseTimeNC() - theApp->getOPs().getNetworkTimeNC(); if ((!mConsensus) && (secondsToClose < LEDGER_WOBBLE_TIME)) // pre close wobble @@ -432,12 +459,15 @@ void NetworkOPs::switchLastClosedLedger(Ledger::pointer newLedger) Ledger::pointer openLedger = boost::make_shared(false, boost::ref(*newLedger)); mLedgerMaster->switchLedgers(newLedger, openLedger); - if (getNetworkTimeNC() > openLedger->getCloseTimeNC()) - { // this ledger has already closed - } - + newcoin::TMStatusChange s; + s.set_newevent(newcoin::neSWITCHED_LEDGER); + s.set_ledgerseq(newLedger->getLedgerSeq()); + s.set_networktime(theApp->getOPs().getNetworkTimeNC()); + uint256 plhash = newLedger->getParentHash(); + s.set_previousledgerhash(plhash.begin(), plhash.size()); + PackedMessage::pointer packet = boost::make_shared(s, newcoin::mtSTATUS_CHANGE); + theApp->getConnectionPool().relayMessage(NULL, packet); } -// vim:ts=4 int NetworkOPs::beginConsensus(Ledger::pointer closingLedger) { @@ -472,10 +502,11 @@ bool NetworkOPs::recvPropose(uint32 proposeSeq, const uint256& proposeHash, // XXX Take a vuc for pubkey. NewcoinAddress naPeerPublic = NewcoinAddress::createNodePublic(strCopy(pubKey)); - if (mMode != omFULL) // FIXME: Should we relay? + if (mMode != omFULL) { Log(lsINFO) << "Received proposal when not full: " << mMode; - return false; // FIXME: Need suppression table + Serializer s(signature); + return theApp->suppress(s.getSHA512Half()); } if (!mConsensus) { @@ -528,7 +559,7 @@ bool NetworkOPs::hasTXSet(boost::shared_ptr peer, const uint256& set, newc void NetworkOPs::mapComplete(const uint256& hash, SHAMap::pointer map) { if (mConsensus) - mConsensus->mapComplete(hash, map); + mConsensus->mapComplete(hash, map, true); } void NetworkOPs::endConsensus() @@ -583,4 +614,23 @@ bool NetworkOPs::recvValidation(SerializedValidation::pointer val) return theApp->getValidations().addValidation(val); } +Json::Value NetworkOPs::getServerInfo() +{ + Json::Value info = Json::objectValue; + + switch (mMode) + { + case omDISCONNECTED: info["network_state"] = "disconected"; break; + case omCONNECTED: info["network_state"] = "connected"; break; + case omTRACKING: info["network_state"] = "tracking"; break; + case omFULL: info["network_state"] = "validating"; break; + default: info["network_state"] = "unknown"; + } + + if (!theConfig.VALIDATION_SEED.isValid()) info["validation_seed"] = "none"; + else info["validation_seed"] = NewcoinAddress::createNodePublic(theConfig.VALIDATION_SEED).humanNodePublic(); + + return info; +} + // vim:ts=4 diff --git a/src/NetworkOPs.h b/src/NetworkOPs.h index 5fdea311ed..2e7f1d531c 100644 --- a/src/NetworkOPs.h +++ b/src/NetworkOPs.h @@ -127,6 +127,7 @@ public: int beginConsensus(Ledger::pointer closingLedger); void endConsensus(); void setStateTimer(int seconds); + Json::Value getServerInfo(); // client information retrieval functions std::vector< std::pair > diff --git a/src/Peer.cpp b/src/Peer.cpp index 9ae5c98eb3..66b2e0ae10 100644 --- a/src/Peer.cpp +++ b/src/Peer.cpp @@ -60,7 +60,7 @@ void Peer::handle_write(const boost::system::error_code& error, size_t bytes_tra void Peer::detach(const char *rsn) { #ifdef DEBUG - std::cerr << "DETACHING PEER: " << rsn + Log(lsTRACE) << "DETACHING PEER: " << rsn; << ": " << (mNodePublic.isValid() ? mNodePublic.humanNodePublic() : "-") << " " << getIP() << " " << getPort() << std::endl; @@ -509,6 +509,7 @@ void Peer::processReadBuffer() default: std::cerr << "Unknown Msg: " << type << std::endl; + std::cerr << strHex(&mReadbuf[0], mReadbuf.size()); } } } diff --git a/src/Peer.h b/src/Peer.h index 3a5f20c01c..99c0204af2 100644 --- a/src/Peer.h +++ b/src/Peer.h @@ -126,6 +126,7 @@ public: void punishPeer(PeerPunish pp); Json::Value getJson(); + bool isConnected() const { return mConnected; } //static PackedMessage::pointer createFullLedger(Ledger::pointer ledger); static PackedMessage::pointer createLedgerProposal(Ledger::pointer ledger); diff --git a/src/RPCServer.cpp b/src/RPCServer.cpp index 536de12c8e..eedb3b6882 100644 --- a/src/RPCServer.cpp +++ b/src/RPCServer.cpp @@ -23,6 +23,7 @@ #include "AccountState.h" #include "NicknameState.h" #include "utils.h" +#include "Log.h" RPCServer::RPCServer(boost::asio::io_service& io_service , NetworkOPs* nopNetwork) : mNetOps(nopNetwork), mSocket(io_service) @@ -162,16 +163,10 @@ std::string RPCServer::handleRequest(const std::string& requestStr) else if (!valParams.isArray()) return(HTTPReply(400, "")); -#ifdef DEBUG Json::StyledStreamWriter w; - w.write(std::cerr, valParams); -#endif - + w.write(Log(lsTRACE).ref(), valParams); Json::Value result(doCommand(strMethod, valParams)); - -#ifdef DEBUG - w.write(std::cerr, result); -#endif + w.write(Log(lsTRACE).ref(), result); std::string strReply = JSONRPCReply(result, Json::Value(), id); return( HTTPReply(200, strReply) ); @@ -1236,6 +1231,11 @@ Json::Value RPCServer::doSend(Json::Value& params) } } +Json::Value RPCServer::doServerInfo(Json::Value& params) +{ + return theApp->getOPs().getServerInfo(); +} + // transit_set Json::Value RPCServer::doTransitSet(Json::Value& params) { @@ -1966,7 +1966,7 @@ Json::Value RPCServer::doStop(Json::Value& params) { Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params) { - std::cerr << "RPC:" << command << std::endl; + Log(lsTRACE) << "RPC:" << command; static struct { const char* pCommand; @@ -1993,6 +1993,7 @@ Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params { "password_set", &RPCServer::doPasswordSet, 2, 3, optNetwork }, { "peers", &RPCServer::doPeers, 0, 0, }, { "send", &RPCServer::doSend, 3, 7, optCurrent }, + { "server_info", &RPCServer::doServerInfo, 0, 0, }, { "stop", &RPCServer::doStop, 0, 0, }, { "transit_set", &RPCServer::doTransitSet, 5, 5, optCurrent }, { "tx", &RPCServer::doTx, 1, 1, }, diff --git a/src/RPCServer.h b/src/RPCServer.h index af9274e514..ef5640ea94 100644 --- a/src/RPCServer.h +++ b/src/RPCServer.h @@ -127,6 +127,7 @@ private: Json::Value doPasswordSet(Json::Value& params); Json::Value doPeers(Json::Value& params); Json::Value doSend(Json::Value& params); + Json::Value doServerInfo(Json::Value& params); Json::Value doSessionClose(Json::Value& params); Json::Value doSessionOpen(Json::Value& params); Json::Value doStop(Json::Value& params); diff --git a/src/Suppression.cpp b/src/Suppression.cpp new file mode 100644 index 0000000000..c285d5f349 --- /dev/null +++ b/src/Suppression.cpp @@ -0,0 +1,37 @@ + +#include "Suppression.h" + +bool SuppressionTable::addSuppression(const uint160& suppression) +{ + boost::mutex::scoped_lock sl(mSuppressionMutex); + + if (mSuppressionMap.find(suppression) != mSuppressionMap.end()) + return false; + + time_t now = time(NULL); + + boost::unordered_map< time_t, std::list >::iterator it = mSuppressionTimes.begin(); + while (it != mSuppressionTimes.end()) + { + if ((it->first + mHoldTime) < now) + { + for (std::list::iterator lit = it->second.begin(), end = it->second.end(); + lit != end; ++lit) + mSuppressionMap.erase(*lit); + it = mSuppressionTimes.erase(it); + } + else ++it; + } + + mSuppressionMap[suppression] = now; + mSuppressionTimes[now].push_back(suppression); + + return true; +} + +bool SuppressionTable::addSuppression(const uint256& suppression) +{ + uint160 u; + memcpy(u.begin(), suppression.begin() + (suppression.size() - u.size()), u.size()); + return addSuppression(u); +} diff --git a/src/Suppression.h b/src/Suppression.h new file mode 100644 index 0000000000..608a57d733 --- /dev/null +++ b/src/Suppression.h @@ -0,0 +1,34 @@ +#ifndef __SUPPRESSION__ +#define __SUPPRESSION__ + +#include + +#include +#include + +#include "uint256.h" + +extern std::size_t hash_value(const uint160& u); + +class SuppressionTable +{ +protected: + + boost::mutex mSuppressionMutex; + + // Stores all suppressed hashes and their expiration time + boost::unordered_map mSuppressionMap; + + // Stores all expiration times and the hashes indexed for them + boost::unordered_map< time_t, std::list > mSuppressionTimes; + + int mHoldTime; + +public: + SuppressionTable(int holdTime = 120) : mHoldTime(holdTime) { ; } + + bool addSuppression(const uint256& suppression); + bool addSuppression(const uint160& suppression); +}; + +#endif diff --git a/src/TransactionEngine.cpp b/src/TransactionEngine.cpp index 88b8efe05f..2235ff1bd4 100644 --- a/src/TransactionEngine.cpp +++ b/src/TransactionEngine.cpp @@ -40,12 +40,12 @@ TransactionEngineResult TransactionEngine::dirAdd( sleRoot->setIndex(uRootIndex); - std::cerr << "dirAdd: Creating dir index: " << sleRoot->getIndex().ToString() << std::endl; + Log(lsTRACE) << "dirAdd: Creating dir index: " << sleRoot->getIndex().ToString(); sleRoot->setIFieldU64(sfFirstNode, uNodeDir); sleRoot->setIFieldU64(sfLastNode, uNodeDir); - std::cerr << "dirAdd: first & last: " << strHex(uNodeDir) << std::endl; + Log(lsTRACE) << "dirAdd: first & last: " << strHex(uNodeDir); accounts.push_back(std::make_pair(taaCREATE, sleRoot)); } @@ -64,9 +64,9 @@ TransactionEngineResult TransactionEngine::dirAdd( { // Last node is not full, append. - std::cerr << "dirAdd: appending: PREV: " << svIndexes.peekValue()[0].ToString() << std::endl; - std::cerr << "dirAdd: appending: Node: " << strHex(uNodeDir) << std::endl; - std::cerr << "dirAdd: appending: Entry: " << uLedgerIndex.ToString() << std::endl; + Log(lsTRACE) << "dirAdd: appending: PREV: " << svIndexes.peekValue()[0].ToString(); + Log(lsTRACE) << "dirAdd: appending: Node: " << strHex(uNodeDir); + Log(lsTRACE) << "dirAdd: appending: Entry: " << uLedgerIndex.ToString(); svIndexes.peekValue().push_back(uLedgerIndex); sleNode->setIFieldV256(sfIndexes, svIndexes); @@ -83,7 +83,7 @@ TransactionEngineResult TransactionEngine::dirAdd( // Record new last node. sleNode = SLE::pointer(); - std::cerr << "dirAdd: last: " << strHex(uNodeDir) << std::endl; + Log(lsTRACE) << "dirAdd: last: " << strHex(uNodeDir); sleRoot->setIFieldU64(sfLastNode, uNodeDir); @@ -97,7 +97,7 @@ TransactionEngineResult TransactionEngine::dirAdd( sleNode = boost::make_shared(ltDIR_NODE); sleNode->setIndex(uNodeIndex); - std::cerr << "dirAdd: Creating dir node: " << sleNode->getIndex().ToString() << std::endl; + Log(lsTRACE) << "dirAdd: Creating dir node: " << sleNode->getIndex().ToString(); STVector256 svIndexes; @@ -123,7 +123,7 @@ TransactionEngineResult TransactionEngine::dirDelete( if (!sleNode) { - std::cerr << "dirDelete: no such node" << std::endl; + Log(lsWARNING) << "dirDelete: no such node"; return terNODE_NOT_FOUND; } else @@ -135,7 +135,7 @@ TransactionEngineResult TransactionEngine::dirDelete( it = std::find(vuiIndexes.begin(), vuiIndexes.end(), uLedgerIndex); if (vuiIndexes.end() == it) { - std::cerr << "dirDelete: node not mentioned" << std::endl; + Log(lsWARNING) << "dirDelete: node not mentioned"; return terNODE_NOT_MENTIONED; } else @@ -146,7 +146,7 @@ TransactionEngineResult TransactionEngine::dirDelete( if (!sleRoot) { - std::cerr << "dirDelete: root node is missing" << std::endl; + Log(lsWARNING) << "dirDelete: root node is missing"; return terNODE_NO_ROOT; } @@ -242,7 +242,7 @@ TransactionEngineResult TransactionEngine::setAuthorized(const SerializedTransac if (!naAccountPublic.accountPublicVerify(Serializer::getSHA512Half(vucCipher), vucSignature)) { - std::cerr << "createGenerator: bad signature unauthorized generator claim" << std::endl; + Log(lsWARNING) << "createGenerator: bad signature unauthorized generator claim"; return tenBAD_GEN_AUTH; } @@ -254,7 +254,7 @@ TransactionEngineResult TransactionEngine::setAuthorized(const SerializedTransac SLE::pointer sleGen = mLedger->getGenerator(qry, hGeneratorID); if (!sleGen) { - std::cerr << "createGenerator: creating generator" << std::endl; + Log(lsTRACE) << "createGenerator: creating generator"; // Create the generator. sleGen = boost::make_shared(ltGENERATOR_MAP); @@ -268,7 +268,7 @@ TransactionEngineResult TransactionEngine::setAuthorized(const SerializedTransac { // Doing a claim. Must set generator. // Generator is already in use. Regular passphrases limited to one wallet. - std::cerr << "createGenerator: generator already in use" << std::endl; + Log(lsWARNING) << "createGenerator: generator already in use"; return tenGEN_IN_USE; } @@ -288,7 +288,7 @@ TransactionEngineResult TransactionEngine::setAuthorized(const SerializedTransac TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTransaction& txn, TransactionEngineParams params, uint32 targetLedger) { - std::cerr << "applyTransaction>" << std::endl; + Log(lsTRACE) << "applyTransaction>"; mLedger = mDefaultLedger; assert(mLedger); @@ -308,7 +308,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran SerializedTransaction s2(sit); if (!s2.isEquivalent(txn)) { - std::cerr << "Transaction serdes mismatch" << std::endl; + Log(lsFATAL) << "Transaction serdes mismatch"; Json::StyledStreamWriter ssw; ssw.write(Log(lsINFO).ref(), txn.getJson(0)); ssw.write(Log(lsFATAL).ref(), s2.getJson(0)); @@ -322,7 +322,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran uint256 txID = txn.getTransactionID(); if (!txID) { - std::cerr << "applyTransaction: invalid transaction id" << std::endl; + Log(lsWARNING) << "applyTransaction: invalid transaction id"; result = tenINVALID; } @@ -344,7 +344,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran // Consistency: really signed. if (terSUCCESS == result && !txn.checkSign(naSigningPubKey)) { - std::cerr << "applyTransaction: Invalid transaction: bad signature" << std::endl; + Log(lsWARNING) << "applyTransaction: Invalid transaction: bad signature"; result = tenINVALID; } @@ -389,12 +389,12 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran break; case ttINVALID: - std::cerr << "applyTransaction: Invalid transaction: ttINVALID transaction type" << std::endl; + Log(lsWARNING) << "applyTransaction: Invalid transaction: ttINVALID transaction type"; result = tenINVALID; break; default: - std::cerr << "applyTransaction: Invalid transaction: unknown transaction type" << std::endl; + Log(lsWARNING) << "applyTransaction: Invalid transaction: unknown transaction type"; result = tenUNKNOWN; break; } @@ -408,7 +408,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran { if (saPaid < saCost) { - std::cerr << "applyTransaction: insufficient fee" << std::endl; + Log(lsINFO) << "applyTransaction: insufficient fee"; result = tenINSUF_FEE_P; } @@ -418,7 +418,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran if (!saPaid.isZero()) { // Transaction is malformed. - std::cerr << "applyTransaction: fee not allowed" << std::endl; + Log(lsWARNING) << "applyTransaction: fee not allowed"; result = tenINSUF_FEE_P; } @@ -429,7 +429,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran uint160 srcAccountID = txn.getSourceAccount().getAccountID(); if (terSUCCESS == result && !srcAccountID) { - std::cerr << "applyTransaction: bad source id" << std::endl; + Log(lsWARNING) << "applyTransaction: bad source id"; result = tenINVALID; } @@ -455,7 +455,8 @@ 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; + Log(lsTRACE) << str(boost::format("applyTransaction: Delay transaction: source account does not exist: %s") % + txn.getSourceAccount().humanAccountID()); result = terNO_ACCOUNT; } @@ -473,7 +474,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran case ttCLAIM: if (bHaveAuthKey) { - std::cerr << "applyTransaction: Account already claimed." << std::endl; + Log(lsWARNING) << "applyTransaction: Account already claimed."; result = tenCLAIMED; } @@ -496,8 +497,8 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran if (naSigningPubKey.getAccountID() != srcAccountID) { // 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; + Log(lsWARNING) << "sourceAccountID: " << naSigningPubKey.humanAccountID(); + Log(lsWARNING) << "txn accountID: " << txn.getSourceAccount().humanAccountID(); result = tenBAD_CLAIM_ID; } @@ -509,8 +510,8 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran if (naSigningPubKey.getAccountID() != srcAccountID) { // 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; + Log(lsWARNING) << "sourceAccountID: " << naSigningPubKey.humanAccountID(); + Log(lsWARNING) << "txn accountID: " << txn.getSourceAccount().humanAccountID(); result = tenBAD_SET_ID; } @@ -573,12 +574,12 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran else if (!saCost.isZero()) { uint32 a_seq = sleSrc->getIFieldU32(sfSequence); - Log(lsINFO) << "Aseq=" << a_seq << ", Tseq=" << t_seq; + Log(lsTRACE) << "Aseq=" << a_seq << ", Tseq=" << t_seq; if (t_seq != a_seq) { if (a_seq < t_seq) { - std::cerr << "applyTransaction: future sequence number" << std::endl; + Log(lsTRACE) << "applyTransaction: future sequence number"; result = terPRE_SEQ; } diff --git a/src/rpc.cpp b/src/rpc.cpp index b55ea15672..77a414cc4b 100644 --- a/src/rpc.cpp +++ b/src/rpc.cpp @@ -14,6 +14,7 @@ #include "RPC.h" #include "BitcoinUtil.h" #include "Config.h" +#include "Log.h" using namespace boost; using namespace boost::asio; @@ -71,7 +72,7 @@ std::string rfc1123Time() std::string HTTPReply(int nStatus, const std::string& strMsg) { - std::cout << "HTTP Reply " << nStatus << " " << strMsg << std::endl; + Log(lsTRACE) << "HTTP Reply " << nStatus << " " << strMsg; if (nStatus == 401) return strprintf("HTTP/1.0 401 Authorization Required\r\n" diff --git a/src/uint256.h b/src/uint256.h index 3e89222070..a13c814dc3 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -511,8 +511,6 @@ public: zero(); } } - - base_uint160 to160() const; };