Merge branch 'master' into ripple

This commit is contained in:
Arthur Britto
2012-09-04 16:16:13 -07:00
44 changed files with 483 additions and 396 deletions

View File

@@ -21,7 +21,7 @@ AccountState::AccountState(const NewcoinAddress& naAccountID) : mAccountID(naAcc
mValid = true;
}
AccountState::AccountState(const SerializedLedgerEntry::pointer& ledgerEntry, const NewcoinAddress& naAccountID) :
AccountState::AccountState(SLE::ref ledgerEntry, const NewcoinAddress& naAccountID) :
mAccountID(naAccountID), mLedgerEntry(ledgerEntry), mValid(false)
{
if (!mLedgerEntry)

View File

@@ -29,7 +29,7 @@ private:
public:
AccountState(const NewcoinAddress& naAccountID); // For new accounts
AccountState(const SerializedLedgerEntry::pointer& ledgerEntry,const NewcoinAddress& naAccountI); // For accounts in a ledger
AccountState(SLE::ref ledgerEntry,const NewcoinAddress& naAccountI); // For accounts in a ledger
bool bHaveAuthorizedKey()
{

View File

@@ -840,8 +840,8 @@ bool STAmount::applyOffer(
saTakerPaid = saTakerFunds; // Taker paid all he had.
saTakerGot = divide(multiply(saTakerFunds, saOfferPaysAvailable, CURRENCY_ONE, ACCOUNT_ONE), saOfferGetsAvailable, saOfferPays.getCurrency(), saOfferPays.getIssuer());
Log(lsINFO) << "applyOffer: saTakerGot=" << saTakerGot.getFullText();
Log(lsINFO) << "applyOffer: saOfferPaysAvailable=" << saOfferPaysAvailable.getFullText();
Log(lsINFO) << "applyOffer: saTakerGot=" << saTakerGot;
Log(lsINFO) << "applyOffer: saOfferPaysAvailable=" << saOfferPaysAvailable;
}
return saTakerGot >= saOfferPays;

View File

@@ -340,7 +340,7 @@ std::vector<Peer::pointer> ConnectionPool::getPeerVector()
// Now know peer's node public key. Determine if we want to stay connected.
// <-- bNew: false = redundant
bool ConnectionPool::peerConnected(const Peer::pointer& peer, const NewcoinAddress& naPeer,
bool ConnectionPool::peerConnected(Peer::ref peer, const NewcoinAddress& naPeer,
const std::string& strIP, int iPort)
{
bool bNew = false;
@@ -399,7 +399,7 @@ bool ConnectionPool::peerConnected(const Peer::pointer& peer, const NewcoinAddre
}
// We maintain a map of public key to peer for connected and verified peers. Maintain it.
void ConnectionPool::peerDisconnected(const Peer::pointer& peer, const NewcoinAddress& naPeer)
void ConnectionPool::peerDisconnected(Peer::ref peer, const NewcoinAddress& naPeer)
{
if (naPeer.isValid())
{
@@ -486,7 +486,7 @@ bool ConnectionPool::peerScanSet(const std::string& strIp, int iPort)
}
// --> strIp: not empty
void ConnectionPool::peerClosed(const Peer::pointer& peer, const std::string& strIp, int iPort)
void ConnectionPool::peerClosed(Peer::ref peer, const std::string& strIp, int iPort)
{
ipPort ipPeer = make_pair(strIp, iPort);
bool bScanRefresh = false;
@@ -541,7 +541,7 @@ void ConnectionPool::peerClosed(const Peer::pointer& peer, const std::string& st
scanRefresh();
}
void ConnectionPool::peerVerified(const Peer::pointer& peer)
void ConnectionPool::peerVerified(Peer::ref peer)
{
if (mScanning && mScanning == peer)
{

View File

@@ -72,16 +72,16 @@ public:
// We know peers node public key.
// <-- bool: false=reject
bool peerConnected(const Peer::pointer& peer, const NewcoinAddress& naPeer, const std::string& strIP, int iPort);
bool peerConnected(Peer::ref peer, const NewcoinAddress& naPeer, const std::string& strIP, int iPort);
// No longer connected.
void peerDisconnected(const Peer::pointer& peer, const NewcoinAddress& naPeer);
void peerDisconnected(Peer::ref peer, const NewcoinAddress& naPeer);
// As client accepted.
void peerVerified(const Peer::pointer& peer);
void peerVerified(Peer::ref peer);
// As client failed connect and be accepted.
void peerClosed(const Peer::pointer& peer, const std::string& strIp, int iPort);
void peerClosed(Peer::ref peer, const std::string& strIp, int iPort);
Json::Value getPeersJson();
std::vector<Peer::pointer> getPeerVector();

View File

@@ -56,7 +56,7 @@ const char *LedgerDBInit[] = {
LedgerHash CHARACTER(64), \
NodePubKey CHARACTER(56), \
Flags BIGINT UNSIGNED, \
CloseTime BIGINT UNSIGNED, \
SignTime BIGINT UNSIGNED, \
Signature BLOB \
);",
"CREATE INDEX ValidationByHash ON \

View File

@@ -23,7 +23,7 @@ bool HashedObjectStore::store(HashedObjectType type, uint32 index,
if (mCache.touch(hash))
{
#ifdef HS_DEBUG
Log(lsTRACE) << "HOS: " << hash.GetHex() << " store: incache";
Log(lsTRACE) << "HOS: " << hash << " store: incache";
#endif
return false;
}
@@ -94,7 +94,7 @@ HashedObject::pointer HashedObjectStore::retrieve(const uint256& hash)
obj = mCache.fetch(hash);
if (obj)
{
Log(lsTRACE) << "HOS: " << hash.GetHex() << " fetch: incache";
Log(lsTRACE) << "HOS: " << hash << " fetch: incache";
return obj;
}
}
@@ -113,7 +113,7 @@ HashedObject::pointer HashedObjectStore::retrieve(const uint256& hash)
if (!db->executeSQL(sql) || !db->startIterRows())
{
Log(lsTRACE) << "HOS: " << hash.GetHex() << " fetch: not in db";
Log(lsTRACE) << "HOS: " << hash << " fetch: not in db";
return HashedObject::pointer();
}
@@ -145,7 +145,7 @@ HashedObject::pointer HashedObjectStore::retrieve(const uint256& hash)
obj = boost::make_shared<HashedObject>(htype, index, data, hash);
mCache.canonicalize(hash, obj);
}
Log(lsTRACE) << "HOS: " << hash.GetHex() << " fetch: in db";
Log(lsTRACE) << "HOS: " << hash << " fetch: in db";
return obj;
}

View File

@@ -258,7 +258,7 @@ uint256 Ledger::getHash()
return(mHash);
}
void Ledger::saveAcceptedLedger(const Ledger::pointer& ledger)
void Ledger::saveAcceptedLedger(Ledger::ref ledger)
{
static boost::format ledgerExists("SELECT LedgerSeq FROM Ledgers where LedgerSeq = %d;");
static boost::format deleteLedger("DELETE FROM Ledgers WHERE LedgerSeq = %d;");
@@ -508,7 +508,7 @@ void Ledger::setCloseTime(boost::posix_time::ptime ptm)
}
// XXX Use shared locks where possible?
LedgerStateParms Ledger::writeBack(LedgerStateParms parms, const SLE::pointer& entry)
LedgerStateParms Ledger::writeBack(LedgerStateParms parms, SLE::ref entry)
{
ScopedLock l(mAccountStateMap->Lock());
bool create = false;

View File

@@ -41,7 +41,8 @@ class Ledger : public boost::enable_shared_from_this<Ledger>
{ // The basic Ledger structure, can be opened, closed, or synching
friend class TransactionEngine;
public:
typedef boost::shared_ptr<Ledger> pointer;
typedef boost::shared_ptr<Ledger> pointer;
typedef const boost::shared_ptr<Ledger>& ref;
enum TransResult
{
@@ -156,12 +157,12 @@ public:
// high-level functions
AccountState::pointer getAccountState(const NewcoinAddress& acctID);
LedgerStateParms writeBack(LedgerStateParms parms, const SLE::pointer&);
LedgerStateParms writeBack(LedgerStateParms parms, SLE::ref);
SLE::pointer getAccountRoot(const uint160& accountID);
SLE::pointer getAccountRoot(const NewcoinAddress& naAccountID);
// database functions
static void saveAcceptedLedger(const Ledger::pointer&);
static void saveAcceptedLedger(Ledger::ref);
static Ledger::pointer loadByIndex(uint32 ledgerIndex);
static Ledger::pointer loadByHash(const uint256& ledgerHash);

View File

@@ -20,7 +20,7 @@ PeerSet::PeerSet(const uint256& hash, int interval) : mHash(hash), mTimerInterva
assert((mTimerInterval > 10) && (mTimerInterval < 30000));
}
void PeerSet::peerHas(const Peer::pointer& ptr)
void PeerSet::peerHas(Peer::ref ptr)
{
boost::recursive_mutex::scoped_lock sl(mLock);
std::vector< boost::weak_ptr<Peer> >::iterator it = mPeers.begin();
@@ -40,7 +40,7 @@ void PeerSet::peerHas(const Peer::pointer& ptr)
newPeer(ptr);
}
void PeerSet::badPeer(const Peer::pointer& ptr)
void PeerSet::badPeer(Peer::ref ptr)
{
boost::recursive_mutex::scoped_lock sl(mLock);
std::vector< boost::weak_ptr<Peer> >::iterator it = mPeers.begin();
@@ -72,7 +72,7 @@ void PeerSet::invokeOnTimer()
if (!mProgress)
{
++mTimeouts;
Log(lsWARNING) << "Timeout " << mTimeouts << " acquiring " << mHash.GetHex();
Log(lsWARNING) << "Timeout " << mTimeouts << " acquiring " << mHash;
}
else
mProgress = false;
@@ -93,7 +93,7 @@ LedgerAcquire::LedgerAcquire(const uint256& hash) : PeerSet(hash, LEDGER_ACQUIRE
mHaveBase(false), mHaveState(false), mHaveTransactions(false), mAborted(false), mSignaled(false)
{
#ifdef LA_DEBUG
Log(lsTRACE) << "Acquiring ledger " << mHash.GetHex();
Log(lsTRACE) << "Acquiring ledger " << mHash;
#endif
}
@@ -118,7 +118,7 @@ void LedgerAcquire::done()
return;
mSignaled = true;
#ifdef LA_DEBUG
Log(lsTRACE) << "Done acquiring ledger " << mHash.GetHex();
Log(lsTRACE) << "Done acquiring ledger " << mHash;
#endif
std::vector< boost::function<void (LedgerAcquire::pointer)> > triggers;
@@ -142,13 +142,13 @@ void LedgerAcquire::addOnComplete(boost::function<void (LedgerAcquire::pointer)>
mLock.unlock();
}
void LedgerAcquire::trigger(const Peer::pointer& peer, bool timer)
void LedgerAcquire::trigger(Peer::ref peer, bool timer)
{
if (mAborted || mComplete || mFailed)
return;
#ifdef LA_DEBUG
if(peer) Log(lsTRACE) << "Trigger acquiring ledger " << mHash.GetHex() << " from " << peer->getIP();
else Log(lsTRACE) << "Trigger acquiring ledger " << mHash.GetHex();
if(peer) Log(lsTRACE) << "Trigger acquiring ledger " << mHash << " from " << peer->getIP();
else Log(lsTRACE) << "Trigger acquiring ledger " << mHash;
if (mComplete || mFailed)
Log(lsTRACE) << "complete=" << mComplete << " failed=" << mFailed;
else
@@ -257,7 +257,7 @@ void LedgerAcquire::trigger(const Peer::pointer& peer, bool timer)
resetTimer();
}
void PeerSet::sendRequest(const newcoin::TMGetLedger& tmGL, const Peer::pointer& peer)
void PeerSet::sendRequest(const newcoin::TMGetLedger& tmGL, Peer::ref peer)
{
if (!peer)
sendRequest(tmGL);
@@ -290,7 +290,7 @@ void PeerSet::sendRequest(const newcoin::TMGetLedger& tmGL)
bool LedgerAcquire::takeBase(const std::string& data)
{ // Return value: true=normal, false=bad data
#ifdef LA_DEBUG
Log(lsTRACE) << "got base acquiring ledger " << mHash.GetHex();
Log(lsTRACE) << "got base acquiring ledger " << mHash;
#endif
boost::recursive_mutex::scoped_lock sl(mLock);
if (mHaveBase) return true;
@@ -298,7 +298,7 @@ bool LedgerAcquire::takeBase(const std::string& data)
if (mLedger->getHash() != mHash)
{
Log(lsWARNING) << "Acquire hash mismatch";
Log(lsWARNING) << mLedger->getHash().GetHex() << "!=" << mHash.GetHex();
Log(lsWARNING) << mLedger->getHash() << "!=" << mHash;
mLedger = Ledger::pointer();
#ifdef TRUST_NETWORK
assert(false);
@@ -357,7 +357,7 @@ bool LedgerAcquire::takeAsNode(const std::list<SHAMapNode>& nodeIDs,
const std::list< std::vector<unsigned char> >& data)
{
#ifdef LA_DEBUG
Log(lsTRACE) << "got ASdata acquiring ledger " << mHash.GetHex();
Log(lsTRACE) << "got ASdata acquiring ledger " << mHash;
#endif
if (!mHaveBase) return false;
std::list<SHAMapNode>::const_iterator nodeIDit = nodeIDs.begin();
@@ -431,11 +431,11 @@ bool LedgerAcquireMaster::hasLedger(const uint256& hash)
void LedgerAcquireMaster::dropLedger(const uint256& hash)
{
assert(hash.isNonZero());
boost::mutex::scoped_lock sl(mLock);
boost::mutex::scoped_lock sl(mLock);
mLedgers.erase(hash);
}
bool LedgerAcquireMaster::gotLedgerData(newcoin::TMLedgerData& packet, const Peer::pointer& peer)
bool LedgerAcquireMaster::gotLedgerData(newcoin::TMLedgerData& packet, Peer::ref peer)
{
#ifdef LA_DEBUG
Log(lsTRACE) << "got data for acquiring ledger ";
@@ -448,7 +448,7 @@ bool LedgerAcquireMaster::gotLedgerData(newcoin::TMLedgerData& packet, const Pee
}
memcpy(hash.begin(), packet.ledgerhash().data(), 32);
#ifdef LA_DEBUG
Log(lsTRACE) << hash.GetHex();
Log(lsTRACE) << hash;
#endif
LedgerAcquire::pointer ledger = find(hash);

View File

@@ -31,7 +31,7 @@ protected:
virtual ~PeerSet() { ; }
void sendRequest(const newcoin::TMGetLedger& message);
void sendRequest(const newcoin::TMGetLedger& message, const Peer::pointer& peer);
void sendRequest(const newcoin::TMGetLedger& message, Peer::ref peer);
public:
const uint256& getHash() const { return mHash; }
@@ -41,12 +41,12 @@ public:
void progress() { mProgress = true; }
void peerHas(const Peer::pointer&);
void badPeer(const Peer::pointer&);
void peerHas(Peer::ref);
void badPeer(Peer::ref);
void resetTimer();
protected:
virtual void newPeer(const Peer::pointer&) = 0;
virtual void newPeer(Peer::ref) = 0;
virtual void onTimer(void) = 0;
virtual boost::weak_ptr<PeerSet> pmDowncast() = 0;
@@ -72,7 +72,7 @@ protected:
void done();
void onTimer();
void newPeer(const Peer::pointer& peer) { trigger(peer, false); }
void newPeer(Peer::ref peer) { trigger(peer, false); }
boost::weak_ptr<PeerSet> pmDowncast();
@@ -92,7 +92,7 @@ public:
bool takeTxRootNode(const std::vector<unsigned char>& data);
bool takeAsNode(const std::list<SHAMapNode>& IDs, const std::list<std::vector<unsigned char> >& data);
bool takeAsRootNode(const std::vector<unsigned char>& data);
void trigger(const Peer::pointer&, bool timer);
void trigger(Peer::ref, bool timer);
};
class LedgerAcquireMaster
@@ -108,7 +108,7 @@ public:
LedgerAcquire::pointer find(const uint256& hash);
bool hasLedger(const uint256& ledgerHash);
void dropLedger(const uint256& ledgerHash);
bool gotLedgerData(newcoin::TMLedgerData& packet, const Peer::pointer&);
bool gotLedgerData(newcoin::TMLedgerData& packet, Peer::ref);
};
#endif

View File

@@ -33,7 +33,7 @@ void TransactionAcquire::done()
{
if (mFailed)
{
Log(lsWARNING) << "Failed to acqiure TXs " << mHash.GetHex();
Log(lsWARNING) << "Failed to acqiure TXs " << mHash;
theApp->getOPs().mapComplete(mHash, SHAMap::pointer());
}
else
@@ -45,7 +45,7 @@ boost::weak_ptr<PeerSet> TransactionAcquire::pmDowncast()
return boost::shared_polymorphic_downcast<PeerSet, TransactionAcquire>(shared_from_this());
}
void TransactionAcquire::trigger(const Peer::pointer& peer, bool timer)
void TransactionAcquire::trigger(Peer::ref peer, bool timer)
{
if (mComplete || mFailed)
return;
@@ -87,7 +87,7 @@ void TransactionAcquire::trigger(const Peer::pointer& peer, bool timer)
}
bool TransactionAcquire::takeNodes(const std::list<SHAMapNode>& nodeIDs,
const std::list< std::vector<unsigned char> >& data, const Peer::pointer& peer)
const std::list< std::vector<unsigned char> >& data, Peer::ref peer)
{
if (mComplete)
return true;
@@ -136,31 +136,44 @@ void LCTransaction::setVote(const uint160& peer, bool votesYes)
{ // new vote
if (votesYes)
{
Log(lsTRACE) << "Peer " << peer.GetHex() << " votes YES on " << mTransactionID.GetHex();
Log(lsTRACE) << "Peer " << peer << " votes YES on " << mTransactionID;
++mYays;
}
else
{
Log(lsTRACE) << "Peer " << peer.GetHex() << " votes NO on " << mTransactionID.GetHex();
Log(lsTRACE) << "Peer " << peer << " votes NO on " << mTransactionID;
++mNays;
}
}
else if (votesYes && !res.first->second)
{ // changes vote to yes
Log(lsTRACE) << "Peer " << peer.GetHex() << " now votes YES on " << mTransactionID.GetHex();
Log(lsTRACE) << "Peer " << peer << " now votes YES on " << mTransactionID;
--mNays;
++mYays;
res.first->second = true;
}
else if (!votesYes && res.first->second)
{ // changes vote to no
Log(lsTRACE) << "Peer " << peer.GetHex() << " now votes NO on " << mTransactionID.GetHex();
Log(lsTRACE) << "Peer " << peer << " now votes NO on " << mTransactionID;
++mNays;
--mYays;
res.first->second = false;
}
}
void LCTransaction::unVote(const uint160& peer)
{
boost::unordered_map<uint160, bool>::iterator it = mVotes.find(peer);
if (it != mVotes.end())
{
if (it->second)
--mYays;
else
--mNays;
mVotes.erase(it);
}
}
bool LCTransaction::updatePosition(int percentTime, bool proposing)
{ // this many seconds after close, should our position change
if (mOurPosition && (mNays == 0))
@@ -191,19 +204,19 @@ bool LCTransaction::updatePosition(int percentTime, bool proposing)
return false;
}
mOurPosition = newPosition;
Log(lsTRACE) << "We now vote " << (mOurPosition ? "YES" : "NO") << " on " << mTransactionID.GetHex();
Log(lsTRACE) << "We now vote " << (mOurPosition ? "YES" : "NO") << " on " << mTransactionID;
return true;
}
LedgerConsensus::LedgerConsensus(const uint256& prevLCLHash, const Ledger::pointer& previousLedger, uint32 closeTime)
: mState(lcsPRE_CLOSE), mCloseTime(closeTime), mPrevLedgerHash(prevLCLHash), mPreviousLedger(previousLedger),
mCurrentMSeconds(0), mClosePercent(0), mHaveCloseTimeConsensus(false)
LedgerConsensus::LedgerConsensus(const uint256& prevLCLHash, Ledger::ref previousLedger, uint32 closeTime)
: mState(lcsPRE_CLOSE), mCloseTime(closeTime), mPrevLedgerHash(prevLCLHash),
mPreviousLedger(previousLedger), mCurrentMSeconds(0), mClosePercent(0), mHaveCloseTimeConsensus(false)
{
mValSeed = theConfig.VALIDATION_SEED;
mConsensusStartTime = boost::posix_time::microsec_clock::universal_time();
Log(lsDEBUG) << "Creating consensus object";
Log(lsTRACE) << "LCL:" << previousLedger->getHash().GetHex() <<", ct=" << closeTime;
Log(lsTRACE) << "LCL:" << previousLedger->getHash() <<", ct=" << closeTime;
mPreviousProposers = theApp->getOPs().getPreviousProposers();
mPreviousMSeconds = theApp->getOPs().getPreviousConvergeTime();
assert(mPreviousMSeconds);
@@ -226,8 +239,8 @@ LedgerConsensus::LedgerConsensus(const uint256& prevLCLHash, const Ledger::point
handleLCL(prevLCLHash);
if (!mHaveCorrectLCL)
{
Log(lsINFO) << "Entering consensus with: " << previousLedger->getHash().GetHex();
Log(lsINFO) << "Correct LCL is: " << prevLCLHash.GetHex();
Log(lsINFO) << "Entering consensus with: " << previousLedger->getHash();
Log(lsINFO) << "Correct LCL is: " << prevLCLHash;
}
}
@@ -251,6 +264,7 @@ void LedgerConsensus::checkLCL()
if (netLgr != mPrevLedgerHash)
{ // LCL change
Log(lsWARNING) << "View of consensus changed during consensus (" << netLgrCount << ")";
Log(lsWARNING) << mPrevLedgerHash << " to " << netLgr;
if (mHaveCorrectLCL)
theApp->getOPs().consensusViewChange();
handleLCL(netLgr);
@@ -270,11 +284,11 @@ void LedgerConsensus::handleLCL(const uint256& lclHash)
return;
else
{
Log(lsWARNING) << "Need consensus ledger " << mPrevLedgerHash.GetHex();
Log(lsWARNING) << "Need consensus ledger " << mPrevLedgerHash;
mAcquiringLedger = theApp->getMasterLedgerAcquire().findCreate(mPrevLedgerHash);
std::vector<Peer::pointer> peerList = theApp->getConnectionPool().getPeerVector();
bool found = false;
BOOST_FOREACH(Peer::pointer& peer, peerList)
BOOST_FOREACH(Peer::ref peer, peerList)
{
if (peer->hasLedger(mPrevLedgerHash))
{
@@ -284,16 +298,19 @@ void LedgerConsensus::handleLCL(const uint256& lclHash)
}
if (!found)
{
BOOST_FOREACH(Peer::pointer& peer, peerList)
BOOST_FOREACH(Peer::ref peer, peerList)
mAcquiringLedger->peerHas(peer);
}
mHaveCorrectLCL = false;
mProposing = false;
mValidating = false;
mCloseTimes.clear();
mPeerPositions.clear();
mDisputes.clear();
return;
}
Log(lsINFO) << "Acquired the consensus ledger " << mPrevLedgerHash.GetHex();
Log(lsINFO) << "Acquired the consensus ledger " << mPrevLedgerHash;
mHaveCorrectLCL = true;
mAcquiringLedger = LedgerAcquire::pointer();
mCloseResolution = ContinuousLedgerTiming::getNextLedgerTimeResolution(
@@ -306,6 +323,7 @@ void LedgerConsensus::takeInitialPosition(Ledger& initialLedger)
{
SHAMap::pointer initialSet = initialLedger.peekTransactionMap()->snapShot(false);
uint256 txSet = initialSet->getHash();
Log(lsINFO) << "initial position " << txSet;
// if any peers have taken a contrary position, process disputes
boost::unordered_set<uint256> found;
@@ -327,7 +345,7 @@ void LedgerConsensus::takeInitialPosition(Ledger& initialLedger)
mOurPosition = boost::make_shared<LedgerProposal>(initialLedger.getParentHash(), txSet, mCloseTime);
mapComplete(txSet, initialSet, false);
if (mProposing)
propose(std::vector<uint256>(), std::vector<uint256>());
propose();
}
void LedgerConsensus::createDisputes(const SHAMap::pointer& m1, const SHAMap::pointer& m2)
@@ -353,7 +371,7 @@ void LedgerConsensus::createDisputes(const SHAMap::pointer& m1, const SHAMap::po
void LedgerConsensus::mapComplete(const uint256& hash, const SHAMap::pointer& map, bool acquired)
{
if (acquired)
Log(lsINFO) << "We have acquired TXS " << hash.GetHex();
Log(lsINFO) << "We have acquired TXS " << hash;
mAcquiring.erase(hash);
if (!map)
@@ -388,7 +406,7 @@ void LedgerConsensus::mapComplete(const uint256& hash, const SHAMap::pointer& ma
if (!peers.empty())
adjustCount(map, peers);
else if (acquired)
Log(lsWARNING) << "By the time we got the map " << hash.GetHex() << " no peers were proposing it";
Log(lsWARNING) << "By the time we got the map " << hash << " no peers were proposing it";
sendHaveTxSet(hash, true);
}
@@ -442,25 +460,24 @@ void LedgerConsensus::statePreClose()
// This ledger is open. This computes how long since the last ledger closed
int sinceClose;
int ledgerInterval = 0;
int idleInterval = 0;
if (mHaveCorrectLCL && mPreviousLedger->getCloseAgree())
{ // we can use consensus timing
sinceClose = 1000 * (theApp->getOPs().getCloseTimeNC() - mPreviousLedger->getCloseTimeNC());
ledgerInterval = 2 * mPreviousLedger->getCloseResolution();
if (ledgerInterval < LEDGER_IDLE_INTERVAL)
ledgerInterval = LEDGER_IDLE_INTERVAL;
idleInterval = 2 * mPreviousLedger->getCloseResolution();
if (idleInterval < LEDGER_IDLE_INTERVAL)
idleInterval = LEDGER_IDLE_INTERVAL;
}
else
{
sinceClose = theApp->getOPs().getLastCloseTime();
ledgerInterval = LEDGER_IDLE_INTERVAL;
idleInterval = LEDGER_IDLE_INTERVAL;
}
if (sinceClose >= ContinuousLedgerTiming::shouldClose(anyTransactions, mPreviousProposers, proposersClosed,
mPreviousMSeconds, sinceClose, ledgerInterval))
if (ContinuousLedgerTiming::shouldClose(anyTransactions, mPreviousProposers, proposersClosed,
mPreviousMSeconds, sinceClose, idleInterval))
{ // it is time to close the ledger
Log(lsINFO) << "CLC: closing ledger";
mState = lcsESTABLISH;
mConsensusStartTime = boost::posix_time::microsec_clock::universal_time();
mCloseTime = theApp->getOPs().getCloseTimeNC();
@@ -484,7 +501,7 @@ void LedgerConsensus::stateEstablish()
}
if (haveConsensus())
{
Log(lsINFO) << "Converge cutoff";
Log(lsINFO) << "Converge cutoff (" << mPeerPositions.size() << " participants)";
mState = lcsFINISHED;
beginAccept();
}
@@ -503,7 +520,7 @@ void LedgerConsensus::stateAccepted()
void LedgerConsensus::timerEntry()
{
if (!mHaveCorrectLCL)
if ((!mHaveCorrectLCL) || (mState == lcsPRE_CLOSE))
checkLCL();
mCurrentMSeconds =
@@ -512,7 +529,7 @@ void LedgerConsensus::timerEntry()
switch (mState)
{
case lcsPRE_CLOSE: statePreClose(); if (mState != lcsESTABLISH) return; fallthru();
case lcsPRE_CLOSE: statePreClose(); return;
case lcsESTABLISH: stateEstablish(); if (mState != lcsFINISHED) return; fallthru();
case lcsFINISHED: stateFinished(); if (mState != lcsACCEPTED) return; fallthru();
case lcsACCEPTED: stateAccepted(); return;
@@ -522,9 +539,34 @@ void LedgerConsensus::timerEntry()
void LedgerConsensus::updateOurPositions()
{
boost::posix_time::ptime peerCutoff = boost::posix_time::second_clock::universal_time();
boost::posix_time::ptime ourCutoff = peerCutoff - boost::posix_time::seconds(PROPOSE_INTERVAL);
peerCutoff -= boost::posix_time::seconds(PROPOSE_FRESHNESS);
bool changes = false;
SHAMap::pointer ourPosition;
std::vector<uint256> addedTx, removedTx;
// std::vector<uint256> addedTx, removedTx;
// Verify freshness of peer positions and compute close times
std::map<uint32, int> closeTimes;
boost::unordered_map<uint160, LedgerProposal::pointer>::iterator
it = mPeerPositions.begin(), end = mPeerPositions.end();
while (it != end)
{
if (it->second->isStale(peerCutoff))
{ // proposal is stale
uint160 peerID = it->second->getPeerID();
Log(lsWARNING) << "Removing stale proposal from " << peerID;
BOOST_FOREACH(u256_lct_pair& it, mDisputes)
it.second->unVote(peerID);
mPeerPositions.erase(it++);
}
else
{ // proposal is still fresh
++closeTimes[roundCloseTime(it->second->getCloseTime())];
++it;
}
}
BOOST_FOREACH(u256_lct_pair& it, mDisputes)
{
@@ -538,20 +580,16 @@ void LedgerConsensus::updateOurPositions()
if (it.second->getOurPosition()) // now a yes
{
ourPosition->addItem(SHAMapItem(it.first, it.second->peekTransaction()), true, false);
addedTx.push_back(it.first);
// addedTx.push_back(it.first);
}
else // now a no
{
ourPosition->delItem(it.first);
removedTx.push_back(it.first);
// removedTx.push_back(it.first);
}
}
}
std::map<uint32, int> closeTimes;
BOOST_FOREACH(u160_prop_pair& it, mPeerPositions)
++closeTimes[it.second->getCloseTime() - (it.second->getCloseTime() % mCloseResolution)];
int neededWeight;
if (mClosePercent < AV_MID_CONSENSUS_TIME)
@@ -567,13 +605,13 @@ void LedgerConsensus::updateOurPositions()
if (thresh == 0)
{ // no other times
mHaveCloseTimeConsensus = true;
closeTime = mOurPosition->getCloseTime() - (mOurPosition->getCloseTime() % mCloseResolution);
closeTime = roundCloseTime(mOurPosition->getCloseTime());
}
else
{
if (mProposing)
{
++closeTimes[mOurPosition->getCloseTime() - (mOurPosition->getCloseTime() % mCloseResolution)];
++closeTimes[roundCloseTime(mOurPosition->getCloseTime())];
++thresh;
}
thresh = thresh * neededWeight / 100;
@@ -593,13 +631,12 @@ void LedgerConsensus::updateOurPositions()
}
}
if (closeTime != (mOurPosition->getCloseTime() - (mOurPosition->getCloseTime() % mCloseResolution)))
{
if (!changes)
{
ourPosition = mComplete[mOurPosition->getCurrentHash()]->snapShot(true);
changes = true;
}
if ((!changes) &&
((closeTime != (roundCloseTime(mOurPosition->getCloseTime()))) ||
(mOurPosition->isStale(ourCutoff))))
{ // close time changed or our position is stale
ourPosition = mComplete[mOurPosition->getCurrentHash()]->snapShot(true);
changes = true;
}
if (changes)
@@ -607,9 +644,9 @@ void LedgerConsensus::updateOurPositions()
uint256 newHash = ourPosition->getHash();
mOurPosition->changePosition(newHash, closeTime);
if (mProposing)
propose(addedTx, removedTx);
propose();
mapComplete(newHash, ourPosition, false);
Log(lsINFO) << "Position change: CTime " << closeTime << ", tx " << newHash.GetHex();
Log(lsINFO) << "Position change: CTime " << closeTime << ", tx " << newHash;
}
}
@@ -691,9 +728,9 @@ void LedgerConsensus::startAcquiring(const TransactionAcquire::pointer& acquire)
acquire->resetTimer();
}
void LedgerConsensus::propose(const std::vector<uint256>& added, const std::vector<uint256>& removed)
void LedgerConsensus::propose()
{
Log(lsTRACE) << "We propose: " << mOurPosition->getCurrentHash().GetHex();
Log(lsTRACE) << "We propose: " << mOurPosition->getCurrentHash();
newcoin::TMProposeSet prop;
prop.set_currenttxhash(mOurPosition->getCurrentHash().begin(), 256 / 8);
prop.set_proposeseq(mOurPosition->getProposeSeq());
@@ -709,7 +746,7 @@ void LedgerConsensus::propose(const std::vector<uint256>& added, const std::vect
void LedgerConsensus::addDisputedTransaction(const uint256& txID, const std::vector<unsigned char>& tx)
{
Log(lsTRACE) << "Transaction " << txID.GetHex() << " is disputed";
Log(lsTRACE) << "Transaction " << txID << " is disputed";
boost::unordered_map<uint256, LCTransaction::pointer>::iterator it = mDisputes.find(txID);
if (it != mDisputes.end()) return;
@@ -751,8 +788,7 @@ bool LedgerConsensus::peerPosition(const LedgerProposal::pointer& newPosition)
++mCloseTimes[newPosition->getCloseTime()];
}
Log(lsINFO) << "Processing peer proposal " << newPosition->getProposeSeq() << "/"
<< newPosition->getCurrentHash().GetHex();
Log(lsINFO) << "Processing peer proposal " << newPosition->getProposeSeq() << "/" << newPosition->getCurrentHash();
currentPosition = newPosition;
SHAMap::pointer set = getTransactionTree(newPosition->getCurrentHash(), true);
if (set)
@@ -766,7 +802,7 @@ bool LedgerConsensus::peerPosition(const LedgerProposal::pointer& newPosition)
return true;
}
bool LedgerConsensus::peerHasSet(const Peer::pointer& peer, const uint256& hashSet, newcoin::TxSetStatus status)
bool LedgerConsensus::peerHasSet(Peer::ref peer, const uint256& hashSet, newcoin::TxSetStatus status)
{
if (status != newcoin::tsHAVE) // Indirect requests are for future support
return true;
@@ -783,7 +819,7 @@ bool LedgerConsensus::peerHasSet(const Peer::pointer& peer, const uint256& hashS
return true;
}
bool LedgerConsensus::peerGaveNodes(const Peer::pointer& peer, const uint256& setHash,
bool LedgerConsensus::peerGaveNodes(Peer::ref peer, const uint256& setHash,
const std::list<SHAMapNode>& nodeIDs, const std::list< std::vector<unsigned char> >& nodeData)
{
boost::unordered_map<uint256, TransactionAcquire::pointer>::iterator acq = mAcquiring.find(setHash);
@@ -813,33 +849,36 @@ void LedgerConsensus::Saccept(boost::shared_ptr<LedgerConsensus> This, SHAMap::p
void LedgerConsensus::deferProposal(const LedgerProposal::pointer& proposal, const NewcoinAddress& peerPublic)
{
if (!peerPublic.isValid())
return;
std::list<LedgerProposal::pointer>& props = mDeferredProposals[peerPublic.getNodeID()];
if (props.size() > (mPreviousProposers + 10))
if (props.size() >= (mPreviousProposers + 10))
props.pop_front();
props.push_back(proposal);
}
void LedgerConsensus::playbackProposals()
{
for ( boost::unordered_map< uint160, std::list<LedgerProposal::pointer> >::iterator
for (boost::unordered_map< uint160, std::list<LedgerProposal::pointer> >::iterator
it = mDeferredProposals.begin(), end = mDeferredProposals.end(); it != end; ++it)
{
BOOST_FOREACH(const LedgerProposal::pointer& proposal, it->second)
{
proposal->setPrevLedger(mPrevLedgerHash);
if (proposal->checkSign())
{
Log(lsINFO) << "Applying deferred proposal";
peerPosition(proposal);
if (proposal->hasSignature())
{ // old-style
proposal->setPrevLedger(mPrevLedgerHash);
if (proposal->checkSign())
{
Log(lsINFO) << "Applying deferred proposal";
peerPosition(proposal);
}
}
else if (proposal->isPrevLedger(mPrevLedgerHash))
peerPosition(proposal);
}
}
}
void LedgerConsensus::applyTransaction(TransactionEngine& engine, const SerializedTransaction::pointer& txn,
const Ledger::pointer& ledger, CanonicalTXSet& failedTransactions, bool openLedger)
Ledger::ref ledger, CanonicalTXSet& failedTransactions, bool openLedger)
{
TransactionEngineParams parms = openLedger ? tapOPEN_LEDGER : tapNONE;
#ifndef TRUST_NETWORK
@@ -871,8 +910,8 @@ void LedgerConsensus::applyTransaction(TransactionEngine& engine, const Serializ
#endif
}
void LedgerConsensus::applyTransactions(const SHAMap::pointer& set, const Ledger::pointer& applyLedger,
const Ledger::pointer& checkLedger, CanonicalTXSet& failedTransactions, bool openLgr)
void LedgerConsensus::applyTransactions(const SHAMap::pointer& set, Ledger::ref applyLedger,
Ledger::ref checkLedger, CanonicalTXSet& failedTransactions, bool openLgr)
{
TransactionEngineParams parms = openLgr ? tapOPEN_LEDGER : tapNONE;
TransactionEngine engine(applyLedger);
@@ -881,7 +920,7 @@ void LedgerConsensus::applyTransactions(const SHAMap::pointer& set, const Ledger
{
if (!checkLedger->hasTransaction(item->getTag()))
{
Log(lsINFO) << "Processing candidate transaction: " << item->getTag().GetHex();
Log(lsINFO) << "Processing candidate transaction: " << item->getTag();
#ifndef TRUST_NETWORK
try
{
@@ -928,18 +967,22 @@ void LedgerConsensus::applyTransactions(const SHAMap::pointer& set, const Ledger
} while (successes > 0);
}
uint32 LedgerConsensus::roundCloseTime(uint32 closeTime)
{
return closeTime - (closeTime % mCloseResolution);
}
void LedgerConsensus::accept(const SHAMap::pointer& set)
{
assert(set->getHash() == mOurPosition->getCurrentHash());
uint32 closeTime = mOurPosition->getCloseTime() - (mOurPosition->getCloseTime() & mCloseResolution);
uint32 closeTime = roundCloseTime(mOurPosition->getCloseTime());
Log(lsINFO) << "Computing new LCL based on network consensus";
if (mHaveCorrectLCL)
{
Log(lsINFO) << "CNF tx " << mOurPosition->getCurrentHash().GetHex() << ", close " << closeTime;
Log(lsINFO) << "CNF mode " << theApp->getOPs().getOperatingMode()
<< ", oldLCL " << mPrevLedgerHash.GetHex();
Log(lsINFO) << "CNF tx " << mOurPosition->getCurrentHash() << ", close " << closeTime;
Log(lsINFO) << "CNF mode " << theApp->getOPs().getOperatingMode() << ", oldLCL " << mPrevLedgerHash;
}
Ledger::pointer newLCL = boost::make_shared<Ledger>(false, boost::ref(*mPreviousLedger));
@@ -964,9 +1007,9 @@ void LedgerConsensus::accept(const SHAMap::pointer& set)
if (mValidating)
{
SerializedValidation::pointer v = boost::make_shared<SerializedValidation>
(newLCLHash, newLCL->getCloseTimeNC(), mValSeed, mProposing);
(newLCLHash, theApp->getOPs().getValidationTimeNC(), mValSeed, mProposing);
v->setTrusted();
Log(lsINFO) << "CNF Val " << newLCLHash.GetHex();
Log(lsINFO) << "CNF Val " << newLCLHash;
theApp->getValidations().addValidation(v);
std::vector<unsigned char> validation = v->getSigned();
newcoin::TMValidation val;
@@ -974,7 +1017,7 @@ void LedgerConsensus::accept(const SHAMap::pointer& set)
theApp->getConnectionPool().relayMessage(NULL, boost::make_shared<PackedMessage>(val, newcoin::mtVALIDATION));
}
else
Log(lsINFO) << "CNF newLCL " << newLCLHash.GetHex();
Log(lsINFO) << "CNF newLCL " << newLCLHash;
Ledger::pointer newOL = boost::make_shared<Ledger>(true, boost::ref(*newLCL));
ScopedLock sl = theApp->getMasterLedger().getLock();
@@ -1007,14 +1050,13 @@ void LedgerConsensus::accept(const SHAMap::pointer& set)
mState = lcsACCEPTED;
sl.unlock();
if (mValidating && mOurPosition->getCurrentHash().isNonZero())
if (mValidating)
{ // see how close our close time is to other node's close time reports
Log(lsINFO) << "We closed at " << boost::lexical_cast<std::string>(mCloseTime);
uint64 closeTotal = mCloseTime;
int closeCount = 1;
for (std::map<uint32, int>::iterator it = mCloseTimes.begin(), end =
mCloseTimes.end(); it != end; ++it)
{
for (std::map<uint32, int>::iterator it = mCloseTimes.begin(), end = mCloseTimes.end(); it != end; ++it)
{ // FIXME: Use median, not average
Log(lsINFO) << boost::lexical_cast<std::string>(it->second) << " time votes for "
<< boost::lexical_cast<std::string>(it->first);
closeCount += it->second;
@@ -1024,6 +1066,7 @@ void LedgerConsensus::accept(const SHAMap::pointer& set)
closeTotal /= closeCount;
int offset = static_cast<int>(closeTotal) - static_cast<int>(mCloseTime);
Log(lsINFO) << "Our close offset is estimated at " << offset << " (" << closeCount << ")";
theApp->getOPs().closeTimeOffset(offset);
}
#ifdef DEBUG

View File

@@ -27,11 +27,11 @@ protected:
SHAMap::pointer mMap;
bool mHaveRoot;
void onTimer() { trigger(Peer::pointer(), true); }
void newPeer(const Peer::pointer& peer) { trigger(peer, false); }
void onTimer() { trigger(Peer::pointer(), true); }
void newPeer(Peer::ref peer) { trigger(peer, false); }
void done();
void trigger(const Peer::pointer&, bool timer);
void trigger(Peer::ref, bool timer);
boost::weak_ptr<PeerSet> pmDowncast();
public:
@@ -41,7 +41,7 @@ public:
SHAMap::pointer getMap() { return mMap; }
bool takeNodes(const std::list<SHAMapNode>& IDs, const std::list< std::vector<unsigned char> >& data,
const Peer::pointer&);
Peer::ref);
};
class LCTransaction
@@ -64,6 +64,7 @@ public:
Serializer& peekTransaction() { return transaction; }
void setVote(const uint160& peer, bool votesYes);
void unVote(const uint160& peer);
bool updatePosition(int percentTime, bool proposing);
};
@@ -118,22 +119,24 @@ protected:
static void Saccept(boost::shared_ptr<LedgerConsensus> This, SHAMap::pointer txSet);
void accept(const SHAMap::pointer& txSet);
void weHave(const uint256& id, const Peer::pointer& avoidPeer);
void weHave(const uint256& id, Peer::ref avoidPeer);
void startAcquiring(const TransactionAcquire::pointer&);
SHAMap::pointer find(const uint256& hash);
void createDisputes(const SHAMap::pointer&, const SHAMap::pointer&);
void addDisputedTransaction(const uint256&, const std::vector<unsigned char>& transaction);
void adjustCount(const SHAMap::pointer& map, const std::vector<uint160>& peers);
void propose(const std::vector<uint256>& addedTx, const std::vector<uint256>& removedTx);
void propose();
void addPosition(LedgerProposal&, bool ours);
void removePosition(LedgerProposal&, bool ours);
void sendHaveTxSet(const uint256& set, bool direct);
void applyTransactions(const SHAMap::pointer& transactionSet, const Ledger::pointer& targetLedger,
const Ledger::pointer& checkLedger, CanonicalTXSet& failedTransactions, bool openLgr);
void applyTransactions(const SHAMap::pointer& transactionSet, Ledger::ref targetLedger,
Ledger::ref checkLedger, CanonicalTXSet& failedTransactions, bool openLgr);
void applyTransaction(TransactionEngine& engine, const SerializedTransaction::pointer& txn,
const Ledger::pointer& targetLedger, CanonicalTXSet& failedTransactions, bool openLgr);
Ledger::ref targetLedger, CanonicalTXSet& failedTransactions, bool openLgr);
uint32 roundCloseTime(uint32 closeTime);
// manipulating our own position
void statusChange(newcoin::NodeEvent, Ledger& ledger);
@@ -141,11 +144,12 @@ protected:
void updateOurPositions();
void playbackProposals();
int getThreshold();
void beginAccept();
void endConsensus();
public:
LedgerConsensus(const uint256& prevLCLHash, const Ledger::pointer& previousLedger, uint32 closeTime);
LedgerConsensus(const uint256& prevLCLHash, Ledger::ref previousLedger, uint32 closeTime);
int startup();
Json::Value getJson();
@@ -173,9 +177,9 @@ public:
bool peerPosition(const LedgerProposal::pointer&);
void deferProposal(const LedgerProposal::pointer& proposal, const NewcoinAddress& peerPublic);
bool peerHasSet(const Peer::pointer& peer, const uint256& set, newcoin::TxSetStatus status);
bool peerHasSet(Peer::ref peer, const uint256& set, newcoin::TxSetStatus status);
bool peerGaveNodes(const Peer::pointer& peer, const uint256& setHash,
bool peerGaveNodes(Peer::ref peer, const uint256& setHash,
const std::list<SHAMapNode>& nodeIDs, const std::list< std::vector<unsigned char> >& nodeData);
};

View File

@@ -61,7 +61,7 @@ LedgerEntryAction LedgerEntrySet::hasEntry(const uint256& index) const
return it->second.mAction;
}
void LedgerEntrySet::entryCache(const SLE::pointer& sle)
void LedgerEntrySet::entryCache(SLE::ref sle)
{
boost::unordered_map<uint256, LedgerEntrySetEntry>::iterator it = mEntries.find(sle->getIndex());
if (it == mEntries.end())
@@ -82,7 +82,7 @@ void LedgerEntrySet::entryCache(const SLE::pointer& sle)
}
}
void LedgerEntrySet::entryCreate(const SLE::pointer& sle)
void LedgerEntrySet::entryCreate(SLE::ref sle)
{
boost::unordered_map<uint256, LedgerEntrySetEntry>::iterator it = mEntries.find(sle->getIndex());
if (it == mEntries.end())
@@ -112,7 +112,7 @@ void LedgerEntrySet::entryCreate(const SLE::pointer& sle)
}
}
void LedgerEntrySet::entryModify(const SLE::pointer& sle)
void LedgerEntrySet::entryModify(SLE::ref sle)
{
boost::unordered_map<uint256, LedgerEntrySetEntry>::iterator it = mEntries.find(sle->getIndex());
if (it == mEntries.end())
@@ -147,7 +147,7 @@ void LedgerEntrySet::entryModify(const SLE::pointer& sle)
}
}
void LedgerEntrySet::entryDelete(const SLE::pointer& sle, bool unfunded)
void LedgerEntrySet::entryDelete(SLE::ref sle, bool unfunded)
{
boost::unordered_map<uint256, LedgerEntrySetEntry>::iterator it = mEntries.find(sle->getIndex());
if (it == mEntries.end())
@@ -230,7 +230,7 @@ Json::Value LedgerEntrySet::getJson(int) const
return ret;
}
SLE::pointer LedgerEntrySet::getForMod(const uint256& node, Ledger::pointer& ledger,
SLE::pointer LedgerEntrySet::getForMod(const uint256& node, Ledger::ref ledger,
boost::unordered_map<uint256, SLE::pointer>& newMods)
{
boost::unordered_map<uint256, LedgerEntrySetEntry>::iterator it = mEntries.find(node);
@@ -259,7 +259,7 @@ SLE::pointer LedgerEntrySet::getForMod(const uint256& node, Ledger::pointer& led
}
bool LedgerEntrySet::threadTx(TransactionMetaNode& metaNode, const NewcoinAddress& threadTo, Ledger::pointer& ledger,
bool LedgerEntrySet::threadTx(TransactionMetaNode& metaNode, const NewcoinAddress& threadTo, Ledger::ref ledger,
boost::unordered_map<uint256, SLE::pointer>& newMods)
{
SLE::pointer sle = getForMod(Ledger::getAccountRootIndex(threadTo.getAccountID()), ledger, newMods);
@@ -268,7 +268,7 @@ bool LedgerEntrySet::threadTx(TransactionMetaNode& metaNode, const NewcoinAddres
return threadTx(metaNode, sle, ledger, newMods);
}
bool LedgerEntrySet::threadTx(TransactionMetaNode& metaNode, SLE::pointer& threadTo, Ledger::pointer& ledger,
bool LedgerEntrySet::threadTx(TransactionMetaNode& metaNode, SLE::ref threadTo, Ledger::ref ledger,
boost::unordered_map<uint256, SLE::pointer>& newMods)
{ // node = the node that was modified/deleted/created
// threadTo = the node that needs to know
@@ -282,7 +282,7 @@ bool LedgerEntrySet::threadTx(TransactionMetaNode& metaNode, SLE::pointer& threa
return false;
}
bool LedgerEntrySet::threadOwners(TransactionMetaNode& metaNode, SLE::pointer& node, Ledger::pointer& ledger,
bool LedgerEntrySet::threadOwners(TransactionMetaNode& metaNode, SLE::ref node, Ledger::ref ledger,
boost::unordered_map<uint256, SLE::pointer>& newMods)
{ // thread new or modified node to owner or owners
if (node->hasOneOwner()) // thread to owner's account
@@ -295,7 +295,7 @@ bool LedgerEntrySet::threadOwners(TransactionMetaNode& metaNode, SLE::pointer& n
return false;
}
void LedgerEntrySet::calcRawMeta(Serializer& s, Ledger::pointer& origLedger)
void LedgerEntrySet::calcRawMeta(Serializer& s, Ledger::ref origLedger)
{ // calculate the raw meta data and return it. This must be called before the set is committed
// Entries modified only as a result of building the transaction metadata

View File

@@ -24,7 +24,7 @@ public:
LedgerEntryAction mAction;
int mSeq;
LedgerEntrySetEntry(const SLE::pointer& e, LedgerEntryAction a, int s) : mEntry(e), mAction(a), mSeq(s) { ; }
LedgerEntrySetEntry(SLE::ref e, LedgerEntryAction a, int s) : mEntry(e), mAction(a), mSeq(s) { ; }
};
@@ -38,16 +38,16 @@ protected:
LedgerEntrySet(const boost::unordered_map<uint256, LedgerEntrySetEntry> &e, const TransactionMetaSet& s, int m) :
mEntries(e), mSet(s), mSeq(m) { ; }
SLE::pointer getForMod(const uint256& node, Ledger::pointer& ledger,
SLE::pointer getForMod(const uint256& node, Ledger::ref ledger,
boost::unordered_map<uint256, SLE::pointer>& newMods);
bool threadTx(TransactionMetaNode& metaNode, const NewcoinAddress& threadTo, Ledger::pointer& ledger,
bool threadTx(TransactionMetaNode& metaNode, const NewcoinAddress& threadTo, Ledger::ref ledger,
boost::unordered_map<uint256, SLE::pointer>& newMods);
bool threadTx(TransactionMetaNode& metaNode, SLE::pointer& threadTo, Ledger::pointer& ledger,
bool threadTx(TransactionMetaNode& metaNode, SLE::ref threadTo, Ledger::ref ledger,
boost::unordered_map<uint256, SLE::pointer>& newMods);
bool threadOwners(TransactionMetaNode& metaNode, SLE::pointer& node, Ledger::pointer& ledger,
bool threadOwners(TransactionMetaNode& metaNode, SLE::ref node, Ledger::ref ledger,
boost::unordered_map<uint256, SLE::pointer>& newMods);
public:
@@ -66,13 +66,13 @@ public:
// basic entry functions
SLE::pointer getEntry(const uint256& index, LedgerEntryAction&);
LedgerEntryAction hasEntry(const uint256& index) const;
void entryCache(const SLE::pointer&); // Add this entry to the cache
void entryCreate(const SLE::pointer&); // This entry will be created
void entryDelete(const SLE::pointer&, bool unfunded);
void entryModify(const SLE::pointer&); // This entry will be modified
void entryCache(SLE::ref); // Add this entry to the cache
void entryCreate(SLE::ref); // This entry will be created
void entryDelete(SLE::ref, bool unfunded);
void entryModify(SLE::ref); // This entry will be modified
Json::Value getJson(int) const;
void calcRawMeta(Serializer&, Ledger::pointer& originalLedger);
void calcRawMeta(Serializer&, Ledger::ref originalLedger);
// iterator functions
bool isEmpty() const { return mEntries.empty(); }

View File

@@ -19,23 +19,23 @@ bool LedgerMaster::addHeldTransaction(const Transaction::pointer& transaction)
return mHeldTransactionsByID.insert(std::make_pair(transaction->getID(), transaction)).second;
}
void LedgerMaster::pushLedger(const Ledger::pointer& newLedger)
void LedgerMaster::pushLedger(Ledger::ref newLedger)
{
// Caller should already have properly assembled this ledger into "ready-to-close" form --
// all candidate transactions must already be appled
Log(lsINFO) << "PushLedger: " << newLedger->getHash().GetHex();
Log(lsINFO) << "PushLedger: " << newLedger->getHash();
ScopedLock sl(mLock);
if (!!mFinalizedLedger)
{
mFinalizedLedger->setClosed();
Log(lsTRACE) << "Finalizes: " << mFinalizedLedger->getHash().GetHex();
Log(lsTRACE) << "Finalizes: " << mFinalizedLedger->getHash();
}
mFinalizedLedger = mCurrentLedger;
mCurrentLedger = newLedger;
mEngine.setLedger(newLedger);
}
void LedgerMaster::pushLedger(const Ledger::pointer& newLCL, const Ledger::pointer& newOL)
void LedgerMaster::pushLedger(Ledger::ref newLCL, Ledger::ref newOL)
{
assert(newLCL->isClosed() && newLCL->isAccepted());
assert(!newOL->isClosed() && !newOL->isAccepted());
@@ -45,7 +45,7 @@ void LedgerMaster::pushLedger(const Ledger::pointer& newLCL, const Ledger::point
assert(newLCL->isClosed());
assert(newLCL->isImmutable());
mLedgerHistory.addAcceptedLedger(newLCL);
Log(lsINFO) << "StashAccepted: " << newLCL->getHash().GetHex();
Log(lsINFO) << "StashAccepted: " << newLCL->getHash();
}
mFinalizedLedger = newLCL;
@@ -54,7 +54,7 @@ void LedgerMaster::pushLedger(const Ledger::pointer& newLCL, const Ledger::point
mEngine.setLedger(newOL);
}
void LedgerMaster::switchLedgers(const Ledger::pointer& lastClosed, const Ledger::pointer& current)
void LedgerMaster::switchLedgers(Ledger::ref lastClosed, Ledger::ref current)
{
assert(lastClosed && current);
mFinalizedLedger = lastClosed;
@@ -66,7 +66,7 @@ void LedgerMaster::switchLedgers(const Ledger::pointer& lastClosed, const Ledger
mEngine.setLedger(mCurrentLedger);
}
void LedgerMaster::storeLedger(const Ledger::pointer& ledger)
void LedgerMaster::storeLedger(Ledger::ref ledger)
{
mLedgerHistory.addLedger(ledger);
}

View File

@@ -48,11 +48,11 @@ public:
TER doTransaction(const SerializedTransaction& txn, uint32 targetLedger,
TransactionEngineParams params);
void pushLedger(const Ledger::pointer& newLedger);
void pushLedger(const Ledger::pointer& newLCL, const Ledger::pointer& newOL);
void storeLedger(const Ledger::pointer&);
void pushLedger(Ledger::ref newLedger);
void pushLedger(Ledger::ref newLCL, Ledger::ref newOL);
void storeLedger(Ledger::ref);
void switchLedgers(const Ledger::pointer& lastClosed, const Ledger::pointer& newCurrent);
void switchLedgers(Ledger::ref lastClosed, Ledger::ref newCurrent);
Ledger::pointer closeLedger();

View File

@@ -9,14 +9,14 @@
LedgerProposal::LedgerProposal(const uint256& pLgr, uint32 seq, const uint256& tx, uint32 closeTime,
const NewcoinAddress& naPeerPublic) :
mPreviousLedger(pLgr), mCurrentHash(tx), mCloseTime(closeTime), mProposeSeq(seq)
mPreviousLedger(pLgr), mCurrentHash(tx), mCloseTime(closeTime), mProposeSeq(seq), mPublicKey(naPeerPublic)
{
mPublicKey = naPeerPublic;
// XXX Validate key.
// if (!mKey->SetPubKey(pubKey))
// throw std::runtime_error("Invalid public key in proposal");
mPeerID = mPublicKey.getNodeID();
mTime = boost::posix_time::second_clock::universal_time();
}
@@ -27,12 +27,13 @@ LedgerProposal::LedgerProposal(const NewcoinAddress& naSeed, const uint256& prev
mPublicKey = NewcoinAddress::createNodePublic(naSeed);
mPrivateKey = NewcoinAddress::createNodePrivate(naSeed);
mPeerID = mPublicKey.getNodeID();
mTime = boost::posix_time::second_clock::universal_time();
}
LedgerProposal::LedgerProposal(const uint256& prevLgr, const uint256& position, uint32 closeTime) :
mPreviousLedger(prevLgr), mCurrentHash(position), mCloseTime(closeTime), mProposeSeq(0)
{
;
mTime = boost::posix_time::second_clock::universal_time();
}
uint256 LedgerProposal::getSigningHash() const
@@ -55,8 +56,9 @@ bool LedgerProposal::checkSign(const std::string& signature, const uint256& sign
void LedgerProposal::changePosition(const uint256& newPosition, uint32 closeTime)
{
mCurrentHash = newPosition;
mCloseTime = closeTime;
mCurrentHash = newPosition;
mCloseTime = closeTime;
mTime = boost::posix_time::second_clock::universal_time();
++mProposeSeq;
}

View File

@@ -22,7 +22,8 @@ protected:
NewcoinAddress mPublicKey;
NewcoinAddress mPrivateKey; // If ours
std::string mSignature; // set only if needed
std::string mSignature; // set only if needed
boost::posix_time::ptime mTime;
public:
@@ -55,7 +56,11 @@ public:
void setPrevLedger(const uint256& prevLedger) { mPreviousLedger = prevLedger; }
void setSignature(const std::string& signature) { mSignature = signature; }
bool hasSignature() { return !mSignature.empty(); }
bool isPrevLedger(const uint256& pl) { return mPreviousLedger == pl; }
const boost::posix_time::ptime getCreateTime() { return mTime; }
bool isStale(boost::posix_time::ptime cutoff) { return mTime <= cutoff; }
void changePosition(const uint256& newPosition, uint32 newCloseTime);
Json::Value getJson() const;

View File

@@ -12,7 +12,7 @@ int ContinuousLedgerTiming::LedgerTimeResolution[] = { 10, 10, 20, 30, 60, 90, 1
// Called when a ledger is open and no close is in progress -- when a transaction is received and no close
// is in process, or when a close completes. Returns the number of seconds the ledger should be be open.
int ContinuousLedgerTiming::shouldClose(
bool ContinuousLedgerTiming::shouldClose(
bool anyTransactions,
int previousProposers, // proposers in the last closing
int proposersClosed, // proposers who have currently closed this ledgers
@@ -27,16 +27,16 @@ int ContinuousLedgerTiming::shouldClose(
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;
return true;;
}
if (!anyTransactions)
{ // no transactions so far this interval
if (proposersClosed > (previousProposers / 4)) // did we miss a transaction?
{
Log(lsTRACE) << "no transactions, many proposers: now (" << proposersClosed << "closed, "
Log(lsTRACE) << "no transactions, many proposers: now (" << proposersClosed << " closed, "
<< previousProposers << " before)";
return currentMSeconds;
return true;
}
#if 0 // This false triggers on the genesis ledger
if (previousMSeconds > (1000 * (LEDGER_IDLE_INTERVAL + 2))) // the last ledger was very slow to close
@@ -47,11 +47,10 @@ int ContinuousLedgerTiming::shouldClose(
return previousMSeconds - 1000;
}
#endif
return idleInterval * 1000; // normal idle
return currentMSeconds >= (idleInterval * 1000); // normal idle
}
Log(lsTRACE) << "close now";
return currentMSeconds; // this ledger should close now
return true; // this ledger should close now
}
// Returns whether we have a consensus or not. If so, we expect all honest nodes

View File

@@ -28,6 +28,12 @@
// How often we check state or change positions (in milliseconds)
# define LEDGER_GRANULARITY 1000
// How long we consider a proposal fresh
# define PROPOSE_FRESHNESS 20
// How often we force generating a new proposal to keep ours fresh
# define PROPOSE_INTERVAL 12
// Avalanche tuning
#define AV_INIT_CONSENSUS_PCT 50 // percentage of nodes on our UNL that must vote yes
@@ -46,7 +52,7 @@ public:
// Returns the number of seconds the ledger was or should be open
// Call when a consensus is reached and when any transaction is relayed to be added
static int shouldClose(
static bool shouldClose(
bool anyTransactions,
int previousProposers, int proposersClosed,
int previousSeconds, int currentSeconds,

View File

@@ -25,7 +25,7 @@
NetworkOPs::NetworkOPs(boost::asio::io_service& io_service, LedgerMaster* pLedgerMaster) :
mMode(omDISCONNECTED),mNetTimer(io_service), mLedgerMaster(pLedgerMaster), mCloseTimeOffset(0),
mLastCloseProposers(0), mLastCloseConvergeTime(LEDGER_IDLE_INTERVAL)
mLastCloseProposers(0), mLastCloseConvergeTime(LEDGER_IDLE_INTERVAL), mLastValidationTime(0)
{
}
@@ -46,6 +46,22 @@ uint32 NetworkOPs::getCloseTimeNC()
return iToSeconds(getNetworkTimePT() + boost::posix_time::seconds(mCloseTimeOffset));
}
uint32 NetworkOPs::getValidationTimeNC()
{
uint32 vt = getNetworkTimeNC();
if (vt <= mLastValidationTime)
vt = mLastValidationTime + 1;
mLastValidationTime = vt;
return vt;
}
void NetworkOPs::closeTimeOffset(int offset)
{
mCloseTimeOffset += offset / 4;
if (mCloseTimeOffset)
Log(lsINFO) << "Close time offset now " << mCloseTimeOffset;
}
uint32 NetworkOPs::getCurrentLedgerID()
{
return mLedgerMaster->getCurrentLedger()->getLedgerSeq();
@@ -429,8 +445,9 @@ bool NetworkOPs::checkLastClosedLedger(const std::vector<Peer::pointer>& peerLis
{
boost::unordered_map<uint256, int> current = theApp->getValidations().getCurrentValidations();
for (boost::unordered_map<uint256, int>::iterator it = current.begin(), end = current.end(); it != end; ++it)
ledgers[it->first].trustedValidations += it->second;
typedef std::pair<const uint256, int> u256_int_pair;
BOOST_FOREACH(u256_int_pair& it, current)
ledgers[it.first].trustedValidations += it.second;
}
Ledger::pointer ourClosed = mLedgerMaster->getClosedLedger();
@@ -444,7 +461,7 @@ bool NetworkOPs::checkLastClosedLedger(const std::vector<Peer::pointer>& peerLis
ourVC.highNode = theApp->getWallet().getNodePublic();
}
BOOST_FOREACH(const Peer::pointer& it, peerList)
BOOST_FOREACH(Peer::ref it, peerList)
{
if (!it)
{
@@ -460,7 +477,6 @@ bool NetworkOPs::checkLastClosedLedger(const std::vector<Peer::pointer>& peerLis
vc.highNode = it->getNodePublic();
++vc.nodesUsing;
}
else Log(lsTRACE) << "Connected peer announces no LCL " << it->getIP();
}
}
@@ -472,7 +488,7 @@ bool NetworkOPs::checkLastClosedLedger(const std::vector<Peer::pointer>& peerLis
it != end; ++it)
{
bool isDead = theApp->getValidations().isDeadLedger(it->first);
Log(lsTRACE) << "L: " << it->first.GetHex() << ((isDead) ? " dead" : " live") <<
Log(lsTRACE) << "L: " << it->first << ((isDead) ? " dead" : " live") <<
" t=" << it->second.trustedValidations << ", n=" << it->second.nodesUsing;
if ((it->second > bestVC) && !isDead)
{
@@ -502,16 +518,17 @@ bool NetworkOPs::checkLastClosedLedger(const std::vector<Peer::pointer>& peerLis
}
Log(lsWARNING) << "We are not running on the consensus ledger";
Log(lsINFO) << "Our LCL " << ourClosed->getHash().GetHex();
Log(lsINFO) << "Net LCL " << closedLedger.GetHex();
Log(lsINFO) << "Our LCL " << ourClosed->getHash();
Log(lsINFO) << "Net LCL " << closedLedger;
if ((mMode == omTRACKING) || (mMode == omFULL))
setMode(omCONNECTED);
Ledger::pointer consensus = mLedgerMaster->getLedgerByHash(closedLedger);
if (!consensus)
{
Log(lsINFO) << "Acquiring consensus ledger " << closedLedger.GetHex();
LedgerAcquire::pointer mAcquiringLedger = theApp->getMasterLedgerAcquire().findCreate(closedLedger);
Log(lsINFO) << "Acquiring consensus ledger " << closedLedger;
if (!mAcquiringLedger || (mAcquiringLedger->getHash() != closedLedger))
mAcquiringLedger = theApp->getMasterLedgerAcquire().findCreate(closedLedger);
if (!mAcquiringLedger || mAcquiringLedger->isFailed())
{
theApp->getMasterLedgerAcquire().dropLedger(closedLedger);
@@ -522,7 +539,7 @@ bool NetworkOPs::checkLastClosedLedger(const std::vector<Peer::pointer>& peerLis
{ // add more peers
int count = 0;
std::vector<Peer::pointer> peers=theApp->getConnectionPool().getPeerVector();
BOOST_FOREACH(const Peer::pointer& it, peerList)
BOOST_FOREACH(Peer::ref it, peerList)
{
if (it->getClosedLedgerHash() == closedLedger)
{
@@ -532,7 +549,7 @@ bool NetworkOPs::checkLastClosedLedger(const std::vector<Peer::pointer>& peerLis
}
if (!count)
{ // just ask everyone
BOOST_FOREACH(const Peer::pointer& it, peerList)
BOOST_FOREACH(Peer::ref it, peerList)
if (it->isConnected())
mAcquiringLedger->peerHas(it);
}
@@ -552,9 +569,9 @@ void NetworkOPs::switchLastClosedLedger(Ledger::pointer newLedger, bool duringCo
{ // set the newledger as our last closed ledger -- this is abnormal code
if (duringConsensus)
Log(lsERROR) << "JUMPdc last closed ledger to " << newLedger->getHash().GetHex();
Log(lsERROR) << "JUMPdc last closed ledger to " << newLedger->getHash();
else
Log(lsERROR) << "JUMP last closed ledger to " << newLedger->getHash().GetHex();
Log(lsERROR) << "JUMP last closed ledger to " << newLedger->getHash();
newLedger->setClosed();
Ledger::pointer openLedger = boost::make_shared<Ledger>(false, boost::ref(*newLedger));
@@ -575,7 +592,7 @@ void NetworkOPs::switchLastClosedLedger(Ledger::pointer newLedger, bool duringCo
int NetworkOPs::beginConsensus(const uint256& networkClosed, Ledger::pointer closingLedger)
{
Log(lsINFO) << "Consensus time for ledger " << closingLedger->getLedgerSeq();
Log(lsINFO) << " LCL is " << closingLedger->getParentHash().GetHex();
Log(lsINFO) << " LCL is " << closingLedger->getParentHash();
Ledger::pointer prevLedger = mLedgerMaster->getLedgerByHash(closingLedger->getParentHash());
if (!prevLedger)
@@ -598,8 +615,8 @@ int NetworkOPs::beginConsensus(const uint256& networkClosed, Ledger::pointer clo
}
// <-- bool: true to relay
bool NetworkOPs::recvPropose(uint32 proposeSeq, const uint256& proposeHash, uint32 closeTime,
const std::string& pubKey, const std::string& signature, const NewcoinAddress& nodePublic)
bool NetworkOPs::recvPropose(uint32 proposeSeq, const uint256& proposeHash, const uint256& prevLedger,
uint32 closeTime, const std::string& pubKey, const std::string& signature, const NewcoinAddress& nodePublic)
{
// JED: does mConsensus need to be locked?
@@ -607,10 +624,13 @@ bool NetworkOPs::recvPropose(uint32 proposeSeq, const uint256& proposeHash, uint
// XXX Take a vuc for pubkey.
// Get a preliminary hash to use to suppress duplicates
Serializer s(128);
Serializer s(256);
s.add256(proposeHash);
s.add256(prevLedger);
s.add32(proposeSeq);
s.add32(getCurrentLedgerID());
s.add32(closeTime);
s.addRaw(pubKey);
s.addRaw(signature);
if (!theApp->isNew(s.getSHA512Half()))
return false;
@@ -630,7 +650,29 @@ bool NetworkOPs::recvPropose(uint32 proposeSeq, const uint256& proposeHash, uint
if (!mConsensus)
{
Log(lsINFO) << "Received proposal outside consensus window";
return (mMode != omFULL);
return mMode != omFULL;
}
// Is this node on our UNL?
if (!theApp->getUNL().nodeInUNL(naPeerPublic))
{
Log(lsINFO) << "Untrusted proposal: " << naPeerPublic.humanNodePublic() << " " << proposeHash;
return true;
}
if (prevLedger.isNonZero())
{ // new-style
LedgerProposal::pointer proposal =
boost::make_shared<LedgerProposal>(prevLedger, proposeSeq, proposeHash, closeTime, naPeerPublic);
if (!proposal->checkSign(signature))
{
Log(lsWARNING) << "New-style ledger proposal fails signature check";
return false;
}
if (prevLedger == mConsensus->getLCL())
return mConsensus->peerPosition(proposal);
mConsensus->deferProposal(proposal, nodePublic);
return false;
}
LedgerProposal::pointer proposal =
@@ -638,22 +680,10 @@ bool NetworkOPs::recvPropose(uint32 proposeSeq, const uint256& proposeHash, uint
if (!proposal->checkSign(signature))
{ // Note that if the LCL is different, the signature check will fail
Log(lsWARNING) << "Ledger proposal fails signature check";
if ((mMode != omFULL) && (mMode != omTRACKING) && theApp->getUNL().nodeInUNL(proposal->peekPublic()))
{
proposal->setSignature(signature);
mConsensus->deferProposal(proposal, nodePublic);
}
proposal->setSignature(signature);
mConsensus->deferProposal(proposal, nodePublic);
return false;
}
// Is this node on our UNL?
if (!theApp->getUNL().nodeInUNL(proposal->peekPublic()))
{
Log(lsINFO) << "Untrusted proposal: " << naPeerPublic.humanNodePublic() << " " <<
proposal->getCurrentHash().GetHex();
return true;
}
return mConsensus->peerPosition(proposal);
}
@@ -688,10 +718,10 @@ void NetworkOPs::mapComplete(const uint256& hash, const SHAMap::pointer& map)
void NetworkOPs::endConsensus(bool correctLCL)
{
uint256 deadLedger = theApp->getMasterLedger().getClosedLedger()->getParentHash();
Log(lsTRACE) << "Ledger " << deadLedger.GetHex() << " is now dead";
Log(lsTRACE) << "Ledger " << deadLedger << " is now dead";
theApp->getValidations().addDeadLedger(deadLedger);
std::vector<Peer::pointer> peerList = theApp->getConnectionPool().getPeerVector();
BOOST_FOREACH(const Peer::pointer& it, peerList)
BOOST_FOREACH(Peer::ref it, peerList)
if (it && (it->getClosedLedgerHash() == deadLedger))
{
Log(lsTRACE) << "Killing obsolete peer status";
@@ -768,7 +798,7 @@ std::vector<NewcoinAddress>
bool NetworkOPs::recvValidation(const SerializedValidation::pointer& val)
{
Log(lsINFO) << "recvValidation " << val->getLedgerHash().GetHex();
Log(lsINFO) << "recvValidation " << val->getLedgerHash();
return theApp->getValidations().addValidation(val);
}
@@ -798,7 +828,7 @@ Json::Value NetworkOPs::getServerInfo()
// Monitoring: publisher side
//
Json::Value NetworkOPs::pubBootstrapAccountInfo(const Ledger::pointer& lpAccepted, const NewcoinAddress& naAccountID)
Json::Value NetworkOPs::pubBootstrapAccountInfo(Ledger::ref lpAccepted, const NewcoinAddress& naAccountID)
{
Json::Value jvObj(Json::objectValue);
@@ -833,7 +863,7 @@ void NetworkOPs::pubAccountInfo(const NewcoinAddress& naAccountID, const Json::V
}
}
void NetworkOPs::pubLedger(const Ledger::pointer& lpAccepted)
void NetworkOPs::pubLedger(Ledger::ref lpAccepted)
{
{
boost::interprocess::sharable_lock<boost::interprocess::interprocess_upgradable_mutex> sl(mMonitorLock);
@@ -946,7 +976,7 @@ Json::Value NetworkOPs::transJson(const SerializedTransaction& stTxn, TER terRes
return jvObj;
}
void NetworkOPs::pubTransactionAll(const Ledger::pointer& lpCurrent, const SerializedTransaction& stTxn, TER terResult, const char* pState)
void NetworkOPs::pubTransactionAll(Ledger::ref lpCurrent, const SerializedTransaction& stTxn, TER terResult, const char* pState)
{
Json::Value jvObj = transJson(stTxn, terResult, pState, lpCurrent->getLedgerSeq(), "transaction");
@@ -956,7 +986,7 @@ void NetworkOPs::pubTransactionAll(const Ledger::pointer& lpCurrent, const Seria
}
}
void NetworkOPs::pubTransactionAccounts(const Ledger::pointer& lpCurrent, const SerializedTransaction& stTxn, TER terResult, const char* pState)
void NetworkOPs::pubTransactionAccounts(Ledger::ref lpCurrent, const SerializedTransaction& stTxn, TER terResult, const char* pState)
{
boost::unordered_set<InfoSub*> usisNotify;
@@ -991,7 +1021,7 @@ void NetworkOPs::pubTransactionAccounts(const Ledger::pointer& lpCurrent, const
}
}
void NetworkOPs::pubTransaction(const Ledger::pointer& lpCurrent, const SerializedTransaction& stTxn, TER terResult)
void NetworkOPs::pubTransaction(Ledger::ref lpCurrent, const SerializedTransaction& stTxn, TER terResult)
{
boost::interprocess::sharable_lock<boost::interprocess::interprocess_upgradable_mutex> sl(mMonitorLock);

View File

@@ -64,6 +64,7 @@ protected:
int mLastCloseProposers, mLastCloseConvergeTime;
uint256 mLastCloseHash;
uint32 mLastCloseTime;
uint32 mLastValidationTime;
// XXX Split into more locks.
boost::interprocess::interprocess_upgradable_mutex mMonitorLock;
@@ -78,10 +79,10 @@ protected:
void setMode(OperatingMode);
Json::Value transJson(const SerializedTransaction& stTxn, TER terResult, const std::string& strStatus, int iSeq, const std::string& strType);
void pubTransactionAll(const Ledger::pointer& lpCurrent, const SerializedTransaction& stTxn, TER terResult, const char* pState);
void pubTransactionAccounts(const Ledger::pointer& lpCurrent, const SerializedTransaction& stTxn, TER terResult, const char* pState);
void pubTransactionAll(Ledger::ref lpCurrent, const SerializedTransaction& stTxn, TER terResult, const char* pState);
void pubTransactionAccounts(Ledger::ref lpCurrent, const SerializedTransaction& stTxn, TER terResult, const char* pState);
Json::Value pubBootstrapAccountInfo(const Ledger::pointer& lpAccepted, const NewcoinAddress& naAccountID);
Json::Value pubBootstrapAccountInfo(Ledger::ref lpAccepted, const NewcoinAddress& naAccountID);
public:
NetworkOPs(boost::asio::io_service& io_service, LedgerMaster* pLedgerMaster);
@@ -89,6 +90,8 @@ public:
// network information
uint32 getNetworkTimeNC();
uint32 getCloseTimeNC();
uint32 getValidationTimeNC();
void closeTimeOffset(int);
boost::posix_time::ptime getNetworkTimePT();
uint32 getCurrentLedgerID();
OperatingMode getOperatingMode() { return mMode; }
@@ -159,7 +162,7 @@ public:
const std::vector<unsigned char>& myNode, std::list< std::vector<unsigned char> >& newNodes);
// ledger proposal/close functions
bool recvPropose(uint32 proposeSeq, const uint256& proposeHash, uint32 closeTime,
bool recvPropose(uint32 proposeSeq, const uint256& proposeHash, const uint256& prevLedger, uint32 closeTime,
const std::string& pubKey, const std::string& signature, const NewcoinAddress& nodePublic);
bool gotTXData(const boost::shared_ptr<Peer>& peer, const uint256& hash,
const std::list<SHAMapNode>& nodeIDs, const std::list< std::vector<unsigned char> >& nodeData);
@@ -195,8 +198,8 @@ public:
//
void pubAccountInfo(const NewcoinAddress& naAccountID, const Json::Value& jvObj);
void pubLedger(const Ledger::pointer& lpAccepted);
void pubTransaction(const Ledger::pointer& lpLedger, const SerializedTransaction& stTxn, TER terResult);
void pubLedger(Ledger::ref lpAccepted);
void pubTransaction(Ledger::ref lpLedger, const SerializedTransaction& stTxn, TER terResult);
//
// Monitoring: subscriber side

View File

@@ -95,6 +95,15 @@ NewcoinAddress NewcoinAddress::createNodePublic(const std::vector<unsigned char>
return naNew;
}
NewcoinAddress NewcoinAddress::createNodePublic(const std::string& strPublic)
{
NewcoinAddress naNew;
naNew.setNodePublic(strPublic);
return naNew;
}
uint160 NewcoinAddress::getNodeID() const
{
switch (nVersion) {

View File

@@ -46,6 +46,7 @@ public:
static NewcoinAddress createNodePublic(const NewcoinAddress& naSeed);
static NewcoinAddress createNodePublic(const std::vector<unsigned char>& vPublic);
static NewcoinAddress createNodePublic(const std::string& strPublic);
//
// Node Private

View File

@@ -140,7 +140,7 @@ void Peer::handleVerifyTimer(const boost::system::error_code& ecResult)
// Begin trying to connect. We are not connected till we know and accept peer's public key.
// Only takes IP addresses (not domains).
void Peer::connect(const std::string strIp, int iPort)
void Peer::connect(const std::string& strIp, int iPort)
{
int iPortAct = (iPort <= 0) ? SYSTEM_PEER_PORT : iPort;
@@ -586,7 +586,10 @@ void Peer::recvHello(newcoin::TMHello& packet)
if (packet.has_nettime() && ((packet.nettime() < minTime) || (packet.nettime() > maxTime)))
{
Log(lsINFO) << "Recv(Hello): Disconnect: Clock is far off";
if (packet.nettime() > maxTime)
Log(lsINFO) << "Recv(Hello): " << getIP() << " :Clock far off +" << packet.nettime() - ourTime;
else if(packet.nettime() < minTime)
Log(lsINFO) << "Recv(Hello): " << getIP() << " :Clock far off -" << ourTime - packet.nettime();
}
else if (packet.protoversionmin() < MAKE_VERSION_INT(MIN_PROTO_MAJOR, MIN_PROTO_MINOR))
{
@@ -721,11 +724,13 @@ void Peer::recvPropose(newcoin::TMProposeSet& packet)
return;
}
uint32 proposeSeq = packet.proposeseq();
uint256 currentTxHash;
uint256 currentTxHash, prevLedger;
memcpy(currentTxHash.begin(), packet.currenttxhash().data(), 32);
if(theApp->getOPs().recvPropose(proposeSeq, currentTxHash, packet.closetime(),
if ((packet.has_previousledger()) && (packet.previousledger().size() == 32))
memcpy(prevLedger.begin(), packet.previousledger().data(), 32);
if(theApp->getOPs().recvPropose(packet.proposeseq(), currentTxHash, prevLedger, packet.closetime(),
packet.nodepubkey(), packet.signature(), mNodePublic))
{ // FIXME: Not all nodes will want proposals
PackedMessage::pointer message = boost::make_shared<PackedMessage>(packet, newcoin::mtPROPOSE_LEDGER);
@@ -899,15 +904,18 @@ void Peer::recvStatus(newcoin::TMStatusChange& packet)
if (packet.newevent() == newcoin::neLOST_SYNC)
{
Log(lsTRACE) << "peer has lost sync " << getIP();
if (!mClosedLedgerHash.isZero())
{
Log(lsTRACE) << "peer has lost sync " << getIP();
mClosedLedgerHash.zero();
}
mPreviousLedgerHash.zero();
mClosedLedgerHash.zero();
return;
}
if (packet.has_ledgerhash() && (packet.ledgerhash().size() == (256 / 8)))
{ // a peer has changed ledgers
memcpy(mClosedLedgerHash.begin(), packet.ledgerhash().data(), 256 / 8);
Log(lsTRACE) << "peer LCL is " << mClosedLedgerHash.GetHex() << " " << getIP();
Log(lsTRACE) << "peer LCL is " << mClosedLedgerHash << " " << getIP();
}
else
{
@@ -967,6 +975,8 @@ void Peer::recvGetLedger(newcoin::TMGetLedger& packet)
}
memcpy(ledgerhash.begin(), packet.ledgerhash().data(), 32);
ledger = theApp->getMasterLedger().getLedgerByHash(ledgerhash);
if (!ledger)
Log(lsINFO) << "Don't have ledger " << ledgerhash;
}
else if (packet.has_ledgerseq())
ledger = theApp->getMasterLedger().getLedgerBySeq(packet.ledgerseq());
@@ -985,7 +995,7 @@ void Peer::recvGetLedger(newcoin::TMGetLedger& packet)
return;
}
if ((!ledger) || (packet.has_ledgerseq() && (packet.ledgerseq()!=ledger->getLedgerSeq())))
if ((!ledger) || (packet.has_ledgerseq() && (packet.ledgerseq() != ledger->getLedgerSeq())))
{
punishPeer(PP_UNKNOWN_REQUEST);
Log(lsWARNING) << "Can't find the ledger they want";

View File

@@ -24,13 +24,14 @@ typedef std::pair<std::string,int> ipPort;
class Peer : public boost::enable_shared_from_this<Peer>
{
public:
typedef boost::shared_ptr<Peer> pointer;
typedef boost::shared_ptr<Peer> pointer;
typedef const boost::shared_ptr<Peer>& ref;
static const int psbGotHello = 0, psbSentHello = 1, psbInMap = 2, psbTrusted = 3;
static const int psbNoLedgers = 4, psbNoTransactions = 5, psbDownLevel = 6;
void handleConnect(const boost::system::error_code& error, boost::asio::ip::tcp::resolver::iterator it);
static void sHandleConnect(const Peer::pointer& ptr, const boost::system::error_code& error,
static void sHandleConnect(Peer::ref ptr, const boost::system::error_code& error,
boost::asio::ip::tcp::resolver::iterator it)
{ ptr->handleConnect(error, it); }
@@ -50,11 +51,11 @@ private:
boost::asio::deadline_timer mVerifyTimer;
void handleStart(const boost::system::error_code& ecResult);
static void sHandleStart(const Peer::pointer& ptr, const boost::system::error_code& ecResult)
static void sHandleStart(Peer::ref ptr, const boost::system::error_code& ecResult)
{ ptr->handleStart(ecResult); }
void handleVerifyTimer(const boost::system::error_code& ecResult);
static void sHandleVerifyTimer(const Peer::pointer& ptr, const boost::system::error_code& ecResult)
static void sHandleVerifyTimer(Peer::ref ptr, const boost::system::error_code& ecResult)
{ ptr->handleVerifyTimer(ecResult); }
protected:
@@ -68,19 +69,19 @@ protected:
Peer(boost::asio::io_service& io_service, boost::asio::ssl::context& ctx);
void handleShutdown(const boost::system::error_code& error) { ; }
static void sHandleShutdown(const Peer::pointer& ptr, const boost::system::error_code& error)
static void sHandleShutdown(Peer::ref ptr, const boost::system::error_code& error)
{ ptr->handleShutdown(error); }
void handle_write(const boost::system::error_code& error, size_t bytes_transferred);
static void sHandle_write(const Peer::pointer& ptr, const boost::system::error_code& error, size_t bytes_transferred)
static void sHandle_write(Peer::ref ptr, const boost::system::error_code& error, size_t bytes_transferred)
{ ptr->handle_write(error, bytes_transferred); }
void handle_read_header(const boost::system::error_code& error);
static void sHandle_read_header(const Peer::pointer& ptr, const boost::system::error_code& error)
static void sHandle_read_header(Peer::ref ptr, const boost::system::error_code& error)
{ ptr->handle_read_header(error); }
void handle_read_body(const boost::system::error_code& error);
static void sHandle_read_body(const Peer::pointer& ptr, const boost::system::error_code& error)
static void sHandle_read_body(Peer::ref ptr, const boost::system::error_code& error)
{ ptr->handle_read_body(error); }
void processReadBuffer();
@@ -134,26 +135,26 @@ public:
return mSocketSsl.lowest_layer();
}
void connect(const std::string strIp, int iPort);
void connect(const std::string& strIp, int iPort);
void connected(const boost::system::error_code& error);
void detach(const char *);
bool samePeer(const Peer::pointer& p) { return samePeer(*p); }
bool samePeer(const Peer& p) { return this == &p; }
bool samePeer(Peer::ref p) { return samePeer(*p); }
bool samePeer(const Peer& p) { return this == &p; }
void sendPacket(const PackedMessage::pointer& packet);
void sendLedgerProposal(const Ledger::pointer& ledger);
void sendFullLedger(const Ledger::pointer& ledger);
void sendLedgerProposal(Ledger::ref ledger);
void sendFullLedger(Ledger::ref ledger);
void sendGetFullLedger(uint256& hash);
void sendGetPeers();
void punishPeer(PeerPunish pp);
Json::Value getJson();
bool isConnected() const { return mHelloed && !mDetaching; }
bool isConnected() const { return mHelloed && !mDetaching; }
uint256 getClosedLedgerHash() const { return mClosedLedgerHash; }
uint256 getClosedLedgerHash() const { return mClosedLedgerHash; }
bool hasLedger(const uint256& hash) const;
NewcoinAddress getNodePublic() const { return mNodePublic; }
NewcoinAddress getNodePublic() const { return mNodePublic; }
void cycleStatus() { mPreviousLedgerHash = mClosedLedgerHash; mClosedLedgerHash.zero(); }
};

View File

@@ -125,7 +125,7 @@ void SHAMap::dirtyUp(std::stack<SHAMapTreeNode::pointer>& stack, const uint256&
return;
}
#ifdef ST_DEBUG
std::cerr << "dirtyUp sets branch " << branch << " to " << prevHash.GetHex() << std::endl;
std::cerr << "dirtyUp sets branch " << branch << " to " << prevHash << std::endl;
#endif
prevHash = node->getNodeHash();
assert(prevHash.isNonZero());
@@ -187,9 +187,9 @@ SHAMapTreeNode::pointer SHAMap::getNode(const SHAMapNode& id, const uint256& has
if (node->getNodeHash() != hash)
{
std::cerr << "Attempt to get node, hash not in tree" << std::endl;
std::cerr << "ID: " << id.getString() << std::endl;
std::cerr << "TgtHash " << hash.GetHex() << std::endl;
std::cerr << "NodHash " << node->getNodeHash().GetHex() << std::endl;
std::cerr << "ID: " << id << std::endl;
std::cerr << "TgtHash " << hash << std::endl;
std::cerr << "NodHash " << node->getNodeHash() << std::endl;
dump();
throw std::runtime_error("invalid node");
}
@@ -242,7 +242,7 @@ SHAMapItem::pointer SHAMap::firstBelow(SHAMapTreeNode* node)
{
// Return the first item below this node
#ifdef ST_DEBUG
std::cerr << "firstBelow(" << node->getString() << ")" << std::endl;
std::cerr << "firstBelow(" << *node << ")" << std::endl;
#endif
do
{ // Walk down the tree
@@ -253,9 +253,9 @@ SHAMapItem::pointer SHAMap::firstBelow(SHAMapTreeNode* node)
if (!node->isEmptyBranch(i))
{
#ifdef ST_DEBUG
std::cerr << " FB: node " << node->getString() << std::endl;
std::cerr << " FB: node " << *node << std::endl;
std::cerr << " has non-empty branch " << i << " : " <<
node->getChildNodeID(i).getString() << ", " << node->getChildHash(i).GetHex() << std::endl;
node->getChildNodeID(i) << ", " << node->getChildHash(i) << std::endl;
#endif
node = getNodePointer(node->getChildNodeID(i), node->getChildHash(i));
foundNode = true;
@@ -268,7 +268,7 @@ SHAMapItem::pointer SHAMap::firstBelow(SHAMapTreeNode* node)
SHAMapItem::pointer SHAMap::lastBelow(SHAMapTreeNode* node)
{
#ifdef DEBUG
std::cerr << "lastBelow(" << node->getString() << ")" << std::endl;
std::cerr << "lastBelow(" << *node << ")" << std::endl;
#endif
do
@@ -306,7 +306,7 @@ SHAMapItem::pointer SHAMap::onlyBelow(SHAMapTreeNode* node)
if (!found)
{
std::cerr << node->getString() << std::endl;
std::cerr << *node << std::endl;
assert(false);
return SHAMapItem::pointer();
}
@@ -480,7 +480,7 @@ bool SHAMap::delItem(const uint256& id)
{
eraseChildren(node);
#ifdef ST_DEBUG
std::cerr << "Making item node " << node->getString() << std::endl;
std::cerr << "Making item node " << *node << std::endl;
#endif
node->setItem(item, type);
}
@@ -501,7 +501,7 @@ bool SHAMap::delItem(const uint256& id)
bool SHAMap::addGiveItem(const SHAMapItem::pointer& item, bool isTransaction, bool hasMeta)
{ // add the specified item, does not update
#ifdef ST_DEBUG
std::cerr << "aGI " << item->getTag().GetHex() << std::endl;
std::cerr << "aGI " << item->getTag() << std::endl;
#endif
uint256 tag = item->getTag();
@@ -527,7 +527,7 @@ bool SHAMap::addGiveItem(const SHAMapItem::pointer& item, bool isTransaction, bo
if (node->isInner())
{ // easy case, we end on an inner node
#ifdef ST_DEBUG
std::cerr << "aGI inner " << node->getString() << std::endl;
std::cerr << "aGI inner " << *node << std::endl;
#endif
int branch = node->selectBranch(tag);
assert(node->isEmptyBranch(branch));
@@ -535,8 +535,8 @@ bool SHAMap::addGiveItem(const SHAMapItem::pointer& item, bool isTransaction, bo
boost::make_shared<SHAMapTreeNode>(node->getChildNodeID(branch), item, type, mSeq);
if (!mTNByID.insert(std::make_pair(SHAMapNode(*newNode), newNode)).second)
{
std::cerr << "Node: " << node->getString() << std::endl;
std::cerr << "NewNode: " << newNode->getString() << std::endl;
std::cerr << "Node: " << *node << std::endl;
std::cerr << "NewNode: " << *newNode << std::endl;
dump();
assert(false);
throw std::runtime_error("invalid inner node");
@@ -546,8 +546,8 @@ bool SHAMap::addGiveItem(const SHAMapItem::pointer& item, bool isTransaction, bo
else
{ // this is a leaf node that has to be made an inner node holding two items
#ifdef ST_DEBUG
std::cerr << "aGI leaf " << node->getString() << std::endl;
std::cerr << "Existing: " << node->peekItem()->getTag().GetHex() << std::endl;
std::cerr << "aGI leaf " << *node << std::endl;
std::cerr << "Existing: " << node->peekItem()->getTag() << std::endl;
#endif
SHAMapItem::pointer otherItem = node->peekItem();
assert(otherItem && (tag != otherItem->getTag()));
@@ -629,7 +629,7 @@ bool SHAMap::updateGiveItem(const SHAMapItem::pointer& item, bool isTransaction,
void SHAMapItem::dump()
{
std::cerr << "SHAMapItem(" << mTag.GetHex() << ") " << mData.size() << "bytes" << std::endl;
std::cerr << "SHAMapItem(" << mTag << ") " << mData.size() << "bytes" << std::endl;
}
SHAMapTreeNode::pointer SHAMap::fetchNodeExternal(const SHAMapNode& id, const uint256& hash)
@@ -652,7 +652,7 @@ SHAMapTreeNode::pointer SHAMap::fetchNodeExternal(const SHAMapNode& id, const ui
}
catch (...)
{
Log(lsWARNING) << "fetchNodeExternal gets an invalid node: " << hash.GetHex();
Log(lsWARNING) << "fetchNodeExternal gets an invalid node: " << hash;
throw SHAMapMissingNode(id, hash);
}
}
@@ -719,7 +719,7 @@ void SHAMap::dump(bool hash)
SHAMapItem::pointer i=peekFirstItem();
while (i)
{
std::cerr << "Item: id=" << i->getTag().GetHex() << std::endl;
std::cerr << "Item: id=" << i->getTag() << std::endl;
i = peekNextItem(i->getTag());
}
std::cerr << "SHAMap::dump done" << std::endl;
@@ -732,7 +732,7 @@ void SHAMap::dump(bool hash)
{
std::cerr << it->second->getString() << std::endl;
if (hash)
std::cerr << " " << it->second->getNodeHash().GetHex() << std::endl;
std::cerr << " " << it->second->getNodeHash() << std::endl;
}
}

View File

@@ -78,6 +78,8 @@ public:
extern std::size_t hash_value(const SHAMapNode& mn);
inline std::ostream& operator<<(std::ostream& out, const SHAMapNode& node) { return out << node.getString(); }
class SHAMapItem
{ // an item stored in a SHAMap
public:

View File

@@ -73,7 +73,7 @@ bool SHAMapNode::operator!=(const uint256 &s) const
return s != mNodeID;
}
static bool j = SHAMapNode::ClassInit();
bool SMN_j = SHAMapNode::ClassInit();
bool SHAMapNode::ClassInit()
{ // set up the depth masks
@@ -147,7 +147,7 @@ int SHAMapNode::selectBranch(const uint256& hash) const
if ((hash & smMasks[mDepth]) != mNodeID)
{
std::cerr << "selectBranch(" << getString() << std::endl;
std::cerr << " " << hash.GetHex() << " off branch" << std::endl;
std::cerr << " " << hash << " off branch" << std::endl;
assert(false);
return -1; // does not go under this node
}
@@ -464,7 +464,7 @@ void SHAMapTreeNode::makeInner()
void SHAMapTreeNode::dump()
{
Log(lsDEBUG) << "SHAMapTreeNode(" << getNodeID().GetHex() << ")";
Log(lsDEBUG) << "SHAMapTreeNode(" << getNodeID() << ")";
}
std::string SHAMapTreeNode::getString() const

View File

@@ -66,7 +66,7 @@ void SHAMap::getMissingNodes(std::vector<SHAMapNode>& nodeIDs, std::vector<uint2
}
else
{
Log(lsTRACE) << "Got sync node from cache: " << d->getString();
Log(lsTRACE) << "Got sync node from cache: " << *d;
mTNByID[*d] = d;
}
}
@@ -222,8 +222,8 @@ bool SHAMap::addKnownNode(const SHAMapNode& node, const std::vector<unsigned cha
if (iNode->getDepth() != (node.getDepth() - 1))
{ // Either this node is broken or we didn't request it (yet)
Log(lsINFO) << "unable to hook node " << node.getString();
Log(lsINFO) << " stuck at " << iNode->getString();
Log(lsINFO) << "unable to hook node " << node;
Log(lsINFO) << " stuck at " << *iNode;
Log(lsINFO) << "got depth=" << node.getDepth() << ", walked to= " << iNode->getDepth();
return false;
}
@@ -304,7 +304,7 @@ bool SHAMap::deepCompare(SHAMap& other)
return false;
}
// Log(lsTRACE) << "Comparing inner nodes " << node->getString();
// Log(lsTRACE) << "Comparing inner nodes " << *node;
if (node->getNodeHash() != otherNode->getNodeHash())
return false;

View File

@@ -14,8 +14,8 @@
static uint8_t SNTPQueryData[48] =
{ 0x1B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
// NTP query frequency - 5 minutes
#define NTP_QUERY_FREQUENCY (5 * 60)
// NTP query frequency - 4 minutes
#define NTP_QUERY_FREQUENCY (4 * 60)
// NTP minimum interval to query same servers - 3 minutes
#define NTP_MIN_QUERY (3 * 60)
@@ -26,6 +26,9 @@ static uint8_t SNTPQueryData[48] =
// NTP timestamp constant
#define NTP_UNIX_OFFSET 0x83AA7E80
// NTP timestamp validity
#define NTP_TIMESTAMP_VALID ((NTP_QUERY_FREQUENCY + NTP_MIN_QUERY) * 2)
// SNTP packet offsets
#define NTP_OFF_INFO 0
#define NTP_OFF_ROOTDELAY 1
@@ -215,7 +218,7 @@ void SNTPClient::queryAll()
bool SNTPClient::getOffset(int& offset)
{
boost::mutex::scoped_lock sl(mLock);
if ((mLastOffsetUpdate == (time_t) -1) || ((mLastOffsetUpdate + 90) < time(NULL)))
if ((mLastOffsetUpdate == (time_t) -1) || ((mLastOffsetUpdate + NTP_TIMESTAMP_VALID) < time(NULL)))
return false;
offset = mOffset;
return true;

View File

@@ -8,14 +8,15 @@
class SerializedLedgerEntry : public SerializedType
{
public:
typedef boost::shared_ptr<SerializedLedgerEntry> pointer;
typedef boost::shared_ptr<SerializedLedgerEntry> pointer;
typedef const boost::shared_ptr<SerializedLedgerEntry>& ref;
protected:
uint256 mIndex;
LedgerEntryType mType;
STUInt16 mVersion;
STObject mObject;
const LedgerEntryFormat* mFormat;
uint256 mIndex;
LedgerEntryType mType;
STUInt16 mVersion;
STObject mObject;
const LedgerEntryFormat* mFormat;
SerializedLedgerEntry* duplicate() const { return new SerializedLedgerEntry(*this); }

View File

@@ -92,6 +92,7 @@ enum SOE_Field
sfSequence,
sfSignature,
sfSigningKey,
sfSigningTime,
sfSourceTag,
sfTakerGets,
sfTakerPays,

View File

@@ -100,6 +100,7 @@ public:
inline SerializedType* new_clone(const SerializedType& s) { return s.clone().release(); }
inline void delete_clone(const SerializedType* s) { boost::checked_delete(s); }
inline std::ostream& operator<<(std::ostream& out, const SerializedType& t) { return out << t.getFullText(); }
class STUInt8 : public SerializedType
{

View File

@@ -6,7 +6,7 @@
SOElement SerializedValidation::sValidationFormat[] = {
{ sfFlags, "Flags", STI_UINT32, SOE_FLAGS, 0 },
{ sfLedgerHash, "LedgerHash", STI_HASH256, SOE_REQUIRED, 0 },
{ sfCloseTime, "CloseTime", STI_UINT32, SOE_REQUIRED, 0 },
{ sfSigningTime, "SignTime", STI_UINT32, SOE_REQUIRED, 0 },
{ sfSigningKey, "SigningKey", STI_VL, SOE_REQUIRED, 0 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 },
};
@@ -19,12 +19,12 @@ SerializedValidation::SerializedValidation(SerializerIterator& sit, bool checkSi
if (checkSignature && !isValid()) throw std::runtime_error("Invalid validation");
}
SerializedValidation::SerializedValidation(const uint256& ledgerHash, uint32 closeTime,
SerializedValidation::SerializedValidation(const uint256& ledgerHash, uint32 signTime,
const NewcoinAddress& naSeed, bool isFull)
: STObject(sValidationFormat), mSignature("Signature"), mTrusted(false)
{
setValueFieldH256(sfLedgerHash, ledgerHash);
setValueFieldU32(sfCloseTime, closeTime);
setValueFieldU32(sfSigningTime, signTime);
if (naSeed.isValid())
setValueFieldVL(sfSigningKey, NewcoinAddress::createNodePublic(naSeed).getNodePublic());
if (!isFull) setFlag(sFullFlag);
@@ -50,9 +50,9 @@ uint256 SerializedValidation::getLedgerHash() const
return getValueFieldH256(sfLedgerHash);
}
uint32 SerializedValidation::getCloseTime() const
uint32 SerializedValidation::getSignTime() const
{
return getValueFieldU32(sfCloseTime);
return getValueFieldU32(sfSigningTime);
}
uint32 SerializedValidation::getFlags() const

View File

@@ -13,7 +13,8 @@ protected:
void setNode();
public:
typedef boost::shared_ptr<SerializedValidation> pointer;
typedef boost::shared_ptr<SerializedValidation> pointer;
typedef const boost::shared_ptr<SerializedValidation>& ref;
static SOElement sValidationFormat[16];
static const uint32 sFullFlag;
@@ -22,10 +23,10 @@ public:
SerializedValidation(SerializerIterator& sit, bool checkSignature = true);
SerializedValidation(const Serializer& s, bool checkSignature = true);
SerializedValidation(const uint256& ledgerHash, uint32 closeTime, const NewcoinAddress& naSeed, bool isFull);
SerializedValidation(const uint256& ledgerHash, uint32 signTime, const NewcoinAddress& naSeed, bool isFull);
uint256 getLedgerHash() const;
uint32 getCloseTime() const;
uint32 getSignTime() const;
uint32 getFlags() const;
NewcoinAddress getSignerPublic() const;
bool isValid() const;

View File

@@ -1,6 +1,7 @@
#include "Suppression.h"
#include <boost/foreach.hpp>
bool SuppressionTable::addSuppression(const uint160& suppression)
{
boost::mutex::scoped_lock sl(mSuppressionMutex);
@@ -9,15 +10,16 @@ bool SuppressionTable::addSuppression(const uint160& suppression)
return false;
time_t now = time(NULL);
time_t expireTime = now - mHoldTime;
boost::unordered_map< time_t, std::list<uint160> >::iterator it = mSuppressionTimes.begin();
while (it != mSuppressionTimes.end())
boost::unordered_map< time_t, std::list<uint160> >::iterator
it = mSuppressionTimes.begin(), end = mSuppressionTimes.end();
while (it != end)
{
if ((it->first + mHoldTime) < now)
if (it->first <= expireTime)
{
for (std::list<uint160>::iterator lit = it->second.begin(), end = it->second.end();
lit != end; ++lit)
mSuppressionMap.erase(*lit);
BOOST_FOREACH(const uint160& lit, it->second)
mSuppressionMap.erase(lit);
it = mSuppressionTimes.erase(it);
}
else ++it;

View File

@@ -3155,7 +3155,7 @@ TER PathState::pushNode(int iType, uint160 uAccountID, uint160 uCurrencyID, uint
}
PathState::PathState(
const Ledger::pointer& lpLedger,
Ledger::ref lpLedger,
const int iIndex,
const LedgerEntrySet& lesSource,
const STPath& spSourcePath,

View File

@@ -230,7 +230,7 @@ public:
STAmount saOutAct; // Amount actually sent (calc output).
PathState(
const Ledger::pointer& lpLedger,
Ledger::ref lpLedger,
const int iIndex,
const LedgerEntrySet& lesSource,
const STPath& spSourcePath,
@@ -243,7 +243,7 @@ public:
Json::Value getJson() const;
static PathState::pointer createPathState(
const Ledger::pointer& lpLedger,
Ledger::ref lpLedger,
const int iIndex,
const LedgerEntrySet& lesSource,
const STPath& spSourcePath,
@@ -382,10 +382,10 @@ protected:
public:
TransactionEngine() { ; }
TransactionEngine(const Ledger::pointer& ledger) : mLedger(ledger) { assert(mLedger); }
TransactionEngine(Ledger::ref ledger) : mLedger(ledger) { assert(mLedger); }
Ledger::pointer getLedger() { return mLedger; }
void setLedger(const Ledger::pointer& ledger) { assert(ledger); mLedger = ledger; }
Ledger::pointer getLedger() { return mLedger; }
void setLedger(Ledger::ref ledger) { assert(ledger); mLedger = ledger; }
TER applyTransaction(const SerializedTransaction&, TransactionEngineParams);
};

View File

@@ -17,7 +17,7 @@ bool ValidationCollection::addValidation(const SerializedValidation::pointer& va
{
val->setTrusted();
uint32 now = theApp->getOPs().getCloseTimeNC();
uint32 valClose = val->getCloseTime();
uint32 valClose = val->getSignTime();
if ((now > (valClose - LEDGER_EARLY_INTERVAL)) && (now < (valClose + LEDGER_VAL_INTERVAL)))
isCurrent = true;
else
@@ -34,27 +34,21 @@ bool ValidationCollection::addValidation(const SerializedValidation::pointer& va
return false;
if (isCurrent)
{
boost::unordered_map<uint160, ValidationPair>::iterator it = mCurrentValidations.find(node);
if ((it == mCurrentValidations.end()) || (!it->second.newest) ||
(val->getCloseTime() > it->second.newest->getCloseTime()))
boost::unordered_map<uint160, SerializedValidation::pointer>::iterator it = mCurrentValidations.find(node);
if (it == mCurrentValidations.end())
mCurrentValidations.insert(std::make_pair(node, val));
else if (!it->second)
it->second = val;
else if (val->getSignTime() > it->second->getSignTime())
{
if (it != mCurrentValidations.end())
{
if (it->second.oldest)
{
mStaleValidations.push_back(it->second.oldest);
condWrite();
}
it->second.oldest = it->second.newest;
it->second.newest = val;
}
else
mCurrentValidations.insert(std::make_pair(node, ValidationPair(val)));
mStaleValidations.push_back(it->second);
it->second = val;
condWrite();
}
}
}
Log(lsINFO) << "Val for " << hash.GetHex() << " from " << signer.humanNodePublic()
Log(lsINFO) << "Val for " << hash << " from " << signer.humanNodePublic()
<< " added " << (val->isTrusted() ? "trusted/" : "UNtrusted/") << (isCurrent ? "current" : "stale");
return isCurrent;
}
@@ -76,7 +70,7 @@ void ValidationCollection::getValidationCount(const uint256& ledger, bool curren
trusted = untrusted = 0;
boost::mutex::scoped_lock sl(mValidationLock);
boost::unordered_map<uint256, ValidationSet>::iterator it = mValidations.find(ledger);
uint32 now = theApp->getOPs().getCloseTimeNC();
uint32 now = theApp->getOPs().getNetworkTimeNC();
if (it != mValidations.end())
{
for (ValidationSet::iterator vit = it->second.begin(), end = it->second.end(); vit != end; ++vit)
@@ -84,13 +78,13 @@ void ValidationCollection::getValidationCount(const uint256& ledger, bool curren
bool isTrusted = vit->second->isTrusted();
if (isTrusted && currentOnly)
{
uint32 closeTime = vit->second->getCloseTime();
uint32 closeTime = vit->second->getSignTime();
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();
Log(lsINFO) << "VC: Untrusted due to time " << ledger;
#endif
}
}
@@ -101,7 +95,7 @@ void ValidationCollection::getValidationCount(const uint256& ledger, bool curren
}
}
#ifdef VC_DEBUG
Log(lsINFO) << "VC: " << ledger.GetHex() << "t:" << trusted << " u:" << untrusted;
Log(lsINFO) << "VC: " << ledger << "t:" << trusted << " u:" << untrusted;
#endif
}
@@ -125,10 +119,10 @@ int ValidationCollection::getCurrentValidationCount(uint32 afterTime)
{
int count = 0;
boost::mutex::scoped_lock sl(mValidationLock);
for (boost::unordered_map<uint160, ValidationPair>::iterator it = mCurrentValidations.begin(),
for (boost::unordered_map<uint160, SerializedValidation::pointer>::iterator it = mCurrentValidations.begin(),
end = mCurrentValidations.end(); it != end; ++it)
{
if (it->second.newest->isTrusted() && (it->second.newest->getCloseTime() > afterTime))
if (it->second->isTrusted() && (it->second->getSignTime() > afterTime))
++count;
}
return count;
@@ -136,54 +130,26 @@ int ValidationCollection::getCurrentValidationCount(uint32 afterTime)
boost::unordered_map<uint256, int> ValidationCollection::getCurrentValidations()
{
uint32 now = theApp->getOPs().getCloseTimeNC();
uint32 cutoff = theApp->getOPs().getNetworkTimeNC() - LEDGER_VAL_INTERVAL;
boost::unordered_map<uint256, int> ret;
{
boost::mutex::scoped_lock sl(mValidationLock);
boost::unordered_map<uint160, ValidationPair>::iterator it = mCurrentValidations.begin();
boost::unordered_map<uint160, SerializedValidation::pointer>::iterator it = mCurrentValidations.begin();
while (it != mCurrentValidations.end())
{
ValidationPair& pair = it->second;
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();
}
if (!pair.newest && !pair.oldest)
if (!it->second) // contains no record
it = mCurrentValidations.erase(it);
else if (it->second->getSignTime() < cutoff)
{ // contains a stale record
mStaleValidations.push_back(it->second);
it->second = SerializedValidation::pointer();
condWrite();
it = mCurrentValidations.erase(it);
}
else
{
if (pair.oldest)
{
#ifdef VC_DEBUG
Log(lsTRACE) << "VC: OLD " << pair.oldest->getLedgerHash().GetHex() << " " <<
boost::lexical_cast<std::string>(pair.oldest->getCloseTime());
#endif
++ret[pair.oldest->getLedgerHash()];
}
if (pair.newest)
{
#ifdef VC_DEBUG
Log(lsTRACE) << "VC: NEW " << pair.newest->getLedgerHash().GetHex() << " " <<
boost::lexical_cast<std::string>(pair.newest->getCloseTime());
#endif
++ret[pair.newest->getLedgerHash()];
}
{ // contains a live record
++ret[it->second->getLedgerHash()];
++it;
}
}
@@ -213,14 +179,12 @@ void ValidationCollection::addDeadLedger(const uint256& ledger)
void ValidationCollection::flush()
{
boost::mutex::scoped_lock sl(mValidationLock);
boost::unordered_map<uint160, ValidationPair>::iterator it = mCurrentValidations.begin();
boost::unordered_map<uint160, SerializedValidation::pointer>::iterator it = mCurrentValidations.begin();
bool anyNew = false;
while (it != mCurrentValidations.end())
{
if (it->second.oldest)
mStaleValidations.push_back(it->second.oldest);
if (it->second.newest)
mStaleValidations.push_back(it->second.newest);
if (it->second)
mStaleValidations.push_back(it->second);
++it;
anyNew = true;
}
@@ -247,7 +211,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,SignTime,Signature) VALUES ('%s','%s','%u','%u',%s);");
boost::mutex::scoped_lock sl(mValidationLock);
assert(mWriting);
@@ -265,7 +229,7 @@ void ValidationCollection::doWrite()
BOOST_FOREACH(const SerializedValidation::pointer& it, vector)
db->executeSQL(boost::str(insVal % it->getLedgerHash().GetHex()
% it->getSignerPublic().humanNodePublic() % it->getFlags() % it->getCloseTime()
% it->getSignerPublic().humanNodePublic() % it->getFlags() % it->getSignTime()
% db->escape(strCopy(it->getSignature()))));
db->executeSQL("END TRANSACTION;");
}

View File

@@ -12,23 +12,15 @@
typedef boost::unordered_map<uint160, SerializedValidation::pointer> ValidationSet;
class ValidationPair
{
public:
SerializedValidation::pointer oldest, newest;
ValidationPair(const SerializedValidation::pointer& v) : newest(v) { ; }
};
class ValidationCollection
{
protected:
boost::mutex mValidationLock;
boost::unordered_map<uint256, ValidationSet> mValidations;
boost::unordered_map<uint160, ValidationPair> mCurrentValidations;
std::vector<SerializedValidation::pointer> mStaleValidations;
std::list<uint256> mDeadLedgers;
boost::unordered_map<uint256, ValidationSet> mValidations;
boost::unordered_map<uint160, SerializedValidation::pointer> mCurrentValidations;
std::vector<SerializedValidation::pointer> mStaleValidations;
std::list<uint256> mDeadLedgers;
bool mWriting;

View File

@@ -107,8 +107,9 @@ message TMProposeSet {
required bytes nodePubKey = 3;
required uint32 closeTime = 4;
required bytes signature = 5; // signature of above fields
repeated bytes addedTransactions = 6; // not required if number is large
repeated bytes removedTransactions = 7; // not required if number is large
optional bytes previousledger = 6;
repeated bytes addedTransactions = 10; // not required if number is large
repeated bytes removedTransactions = 11; // not required if number is large
}
enum TxSetStatus {

View File

@@ -278,7 +278,7 @@ public:
std::string ToString() const
{
return (GetHex());
return GetHex();
}
unsigned char* begin()
@@ -559,6 +559,11 @@ inline const uint256 operator&(const uint256& a, const uint256& b) { return (b
inline const uint256 operator|(const uint256& a, const uint256& b) { return (base_uint256)a | (base_uint256)b; }
extern std::size_t hash_value(const uint256&);
template<unsigned int BITS> inline std::ostream& operator<<(std::ostream& out, const base_uint<BITS>& u)
{
return out << u.GetHex();
}
inline int Testuint256AdHoc(std::vector<std::string> vArg)
{
uint256 g(0);