mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Merge branch 'master' into ripple
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(); }
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
28
src/Peer.cpp
28
src/Peer.cpp
@@ -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";
|
||||
|
||||
33
src/Peer.h
33
src/Peer.h
@@ -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(); }
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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); }
|
||||
|
||||
|
||||
@@ -92,6 +92,7 @@ enum SOE_Field
|
||||
sfSequence,
|
||||
sfSignature,
|
||||
sfSigningKey,
|
||||
sfSigningTime,
|
||||
sfSourceTag,
|
||||
sfTakerGets,
|
||||
sfTakerPays,
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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;");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user