Merge branch 'master' of github.com:jedmccaleb/NewCoin

Conflicts:
	src/ConnectionPool.cpp
	src/Peer.cpp
This commit is contained in:
Arthur Britto
2012-06-19 12:29:06 -07:00
24 changed files with 238 additions and 109 deletions

View File

@@ -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; }

View File

@@ -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;
}

View File

@@ -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(); }

View File

@@ -1,9 +1,5 @@
#include "ConnectionPool.h"
#include "Config.h"
#include "Peer.h"
#include "Application.h"
#include "utils.h"
#include <boost/asio.hpp>
#include <boost/bind.hpp>
@@ -11,6 +7,13 @@
#include <boost/format.hpp>
#include <boost/algorithm/string.hpp>
#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);
}
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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)

View File

@@ -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);
};

View File

@@ -217,7 +217,7 @@ void LedgerConsensus::takeInitialPosition(Ledger::pointer initialLedger)
mOurPosition = boost::make_shared<LedgerProposal>
(theConfig.VALIDATION_SEED, initialLedger->getParentHash(), txSet);
mapComplete(txSet, initialSet);
mapComplete(txSet, initialSet, false);
propose(std::vector<uint256>(), std::vector<uint256>());
}
@@ -241,8 +241,9 @@ 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)
{
if (acquired)
Log(lsINFO) << "We have acquired TXS " << hash.GetHex();
mAcquiring.erase(hash);
@@ -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<SHAMap>();
mapComplete(hash, empty);
mapComplete(hash, empty, false);
return empty;
}
acquiring = boost::make_shared<TransactionAcquire>(hash);
@@ -505,7 +503,7 @@ void LedgerConsensus::startAcquiring(TransactionAcquire::pointer acquire)
void LedgerConsensus::propose(const std::vector<uint256>& added, const std::vector<uint256>& 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

View File

@@ -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();

View File

@@ -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)

View File

@@ -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);
}

View File

@@ -7,7 +7,7 @@
boost::recursive_mutex Log::sLock;
LogSeverity Log::sMinSeverity = lsWARNING;
LogSeverity Log::sMinSeverity = lsINFO;
std::ofstream* Log::outStream = NULL;

View File

@@ -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<PackedMessage>(tx, newcoin::mtTRANSACTION);
theApp->getConnectionPool().relayMessage(source, packet);
}
trans->setStatus(INVALID);
return trans;
@@ -234,6 +246,8 @@ RippleState::pointer NetworkOPs::getRippleState(const uint256& uLedger, const ui
void NetworkOPs::setStateTimer(int sec)
{ // set timer early if ledger is closing
if (!mConsensus && ((mMode == omFULL) || (mMode == omTRACKING)))
{
uint64 consensusTime = mLedgerMaster->getCurrentLedger()->getCloseTimeNC() - LEDGER_WOBBLE_TIME;
uint64 now = getNetworkTimeNC();
@@ -242,7 +256,7 @@ void NetworkOPs::setStateTimer(int sec)
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));
}
@@ -356,7 +370,7 @@ void NetworkOPs::checkState(const boost::system::error_code& result)
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);
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,13 +459,16 @@ void NetworkOPs::switchLastClosedLedger(Ledger::pointer newLedger)
Ledger::pointer openLedger = boost::make_shared<Ledger>(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<PackedMessage>(s, newcoin::mtSTATUS_CHANGE);
theApp->getConnectionPool().relayMessage(NULL, packet);
}
}
// vim:ts=4
int NetworkOPs::beginConsensus(Ledger::pointer closingLedger)
{
Log(lsINFO) << "Ledger close time for ledger " << closingLedger->getLedgerSeq() ;
@@ -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> 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

View File

@@ -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<uint32, uint256> >

View File

@@ -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());
}
}
}

View File

@@ -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);

View File

@@ -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 <seed> <paying_account> <transit_rate> <starts> <expires>
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, },

View File

@@ -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);

37
src/Suppression.cpp Normal file
View File

@@ -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<uint160> >::iterator it = mSuppressionTimes.begin();
while (it != mSuppressionTimes.end())
{
if ((it->first + mHoldTime) < now)
{
for (std::list<uint160>::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);
}

34
src/Suppression.h Normal file
View File

@@ -0,0 +1,34 @@
#ifndef __SUPPRESSION__
#define __SUPPRESSION__
#include <list>
#include <boost/unordered_map.hpp>
#include <boost/thread/mutex.hpp>
#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<uint160, time_t> mSuppressionMap;
// Stores all expiration times and the hashes indexed for them
boost::unordered_map< time_t, std::list<uint160> > mSuppressionTimes;
int mHoldTime;
public:
SuppressionTable(int holdTime = 120) : mHoldTime(holdTime) { ; }
bool addSuppression(const uint256& suppression);
bool addSuppression(const uint160& suppression);
};
#endif

View File

@@ -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<SerializedLedgerEntry>(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<SerializedLedgerEntry>(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;
}

View File

@@ -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"

View File

@@ -511,8 +511,6 @@ public:
zero();
}
}
base_uint160 to160() const;
};