diff --git a/src/LedgerConsensus.cpp b/src/LedgerConsensus.cpp index 8da8844529..1eb44014be 100644 --- a/src/LedgerConsensus.cpp +++ b/src/LedgerConsensus.cpp @@ -195,7 +195,7 @@ int LCTransaction::getAgreeLevel() return (mNays * 100 + 100) / (mYays + mNays + 1); } -LedgerConsensus::LedgerConsensus(const uint256& prevLCLHash, Ledger::pointer previousLedger, uint32 closeTime) +LedgerConsensus::LedgerConsensus(const uint256& prevLCLHash, Ledger::pointer previousLedger, uint64 closeTime) : mState(lcsPRE_CLOSE), mCloseTime(closeTime), mPrevLedgerHash(prevLCLHash), mPreviousLedger(previousLedger) { mValSeed = theConfig.VALIDATION_SEED; @@ -233,9 +233,9 @@ void LedgerConsensus::takeInitialPosition(Ledger::pointer initialLedger) if (mValidating) mOurPosition = boost::make_shared - (mValSeed, initialLedger->getParentHash(), txSet); + (mValSeed, initialLedger->getParentHash(), txSet, mCloseTime); else - mOurPosition = boost::make_shared(initialLedger->getParentHash(), txSet); + mOurPosition = boost::make_shared(initialLedger->getParentHash(), txSet, mCloseTime); mapComplete(txSet, initialSet, false); if (mProposing) propose(std::vector(), std::vector()); } @@ -483,7 +483,7 @@ bool LedgerConsensus::updateOurPositions(int sinceClose) if (changes) { uint256 newHash = ourPosition->getHash(); - mOurPosition->changePosition(newHash); + mOurPosition->changePosition(newHash, mCloseTime); if (mProposing) propose(addedTx, removedTx); mapComplete(newHash, ourPosition, false); Log(lsINFO) << "We change our position to " << newHash.GetHex(); @@ -546,6 +546,7 @@ void LedgerConsensus::propose(const std::vector& added, const std::vect newcoin::TMProposeSet prop; prop.set_currenttxhash(mOurPosition->getCurrentHash().begin(), 256 / 8); prop.set_proposeseq(mOurPosition->getProposeSeq()); + prop.set_closetime(mOurPosition->getCloseTime()); std::vector pubKey = mOurPosition->getPubKey(); std::vector sig = mOurPosition->sign(); diff --git a/src/LedgerConsensus.h b/src/LedgerConsensus.h index 8db236487e..adf94642ee 100644 --- a/src/LedgerConsensus.h +++ b/src/LedgerConsensus.h @@ -81,8 +81,9 @@ class LedgerConsensus : public boost::enable_shared_from_this { protected: LCState mState; - uint32 mCloseTime; + uint64 mCloseTime; // The wall time this ledger closed uint256 mPrevLedgerHash; + int previousClose; // The number of seconds the previous ledger took to close Ledger::pointer mPreviousLedger; LedgerProposal::pointer mOurPosition; NewcoinAddress mValSeed; @@ -131,7 +132,7 @@ protected: void endConsensus(); public: - LedgerConsensus(const uint256& prevLCLHash, Ledger::pointer previousLedger, uint32 closeTime); + LedgerConsensus(const uint256& prevLCLHash, Ledger::pointer previousLedger, uint64 closeTime); int startup(); diff --git a/src/LedgerProposal.cpp b/src/LedgerProposal.cpp index 4de5d37f4f..0e6d305d58 100644 --- a/src/LedgerProposal.cpp +++ b/src/LedgerProposal.cpp @@ -7,8 +7,9 @@ #include "Application.h" #include "HashPrefixes.h" -LedgerProposal::LedgerProposal(const uint256& pLgr, uint32 seq, const uint256& tx, const NewcoinAddress& naPeerPublic) : - mPreviousLedger(pLgr), mCurrentHash(tx), mProposeSeq(seq) +LedgerProposal::LedgerProposal(const uint256& pLgr, uint32 seq, const uint256& tx, uint64 closeTime, + const NewcoinAddress& naPeerPublic) : + mPreviousLedger(pLgr), mCurrentHash(tx), mCloseTime(closeTime), mProposeSeq(seq) { mPublicKey = naPeerPublic; // XXX Validate key. @@ -20,28 +21,30 @@ LedgerProposal::LedgerProposal(const uint256& pLgr, uint32 seq, const uint256& t } -LedgerProposal::LedgerProposal(const NewcoinAddress& naSeed, const uint256& prevLgr, const uint256& position) : - mPreviousLedger(prevLgr), mCurrentHash(position), mProposeSeq(0) +LedgerProposal::LedgerProposal(const NewcoinAddress& naSeed, const uint256& prevLgr, + const uint256& position, uint64 closeTime) : + mPreviousLedger(prevLgr), mCurrentHash(position), mCloseTime(closeTime), mProposeSeq(0) { mPublicKey = NewcoinAddress::createNodePublic(naSeed); mPrivateKey = NewcoinAddress::createNodePrivate(naSeed); mPeerID = mPublicKey.getNodeID(); } -LedgerProposal::LedgerProposal(const uint256& prevLgr, const uint256& position) : - mPreviousLedger(prevLgr), mCurrentHash(position), mProposeSeq(0) +LedgerProposal::LedgerProposal(const uint256& prevLgr, const uint256& position, uint64 closeTime) : + mPreviousLedger(prevLgr), mCurrentHash(position), mCloseTime(closeTime), mProposeSeq(0) { ; } uint256 LedgerProposal::getSigningHash() const { - Serializer s(72); + Serializer s((32 + 32 + 256 + 256 + 64) / 8); s.add32(sHP_Proposal); s.add32(mProposeSeq); s.add256(mPreviousLedger); s.add256(mCurrentHash); + s.add64(mCloseTime); return s.getSHA512Half(); } @@ -51,9 +54,10 @@ bool LedgerProposal::checkSign(const std::string& signature, const uint256& sign return mPublicKey.verifyNodePublic(signingHash, signature); } -void LedgerProposal::changePosition(const uint256& newPosition) +void LedgerProposal::changePosition(const uint256& newPosition, uint64 closeTime) { mCurrentHash = newPosition; + mCloseTime = closeTime; ++mProposeSeq; } diff --git a/src/LedgerProposal.h b/src/LedgerProposal.h index 6e924734ed..79f3a67b63 100644 --- a/src/LedgerProposal.h +++ b/src/LedgerProposal.h @@ -13,6 +13,7 @@ class LedgerProposal protected: uint256 mPreviousLedger, mCurrentHash; + uint64 mCloseTime; uint32 mProposeSeq; uint160 mPeerID; @@ -25,13 +26,14 @@ public: // proposal from peer LedgerProposal(const uint256& prevLgr, uint32 proposeSeq, const uint256& propose, - const NewcoinAddress& naPeerPublic); + uint64 closeTime, const NewcoinAddress& naPeerPublic); // our first proposal - LedgerProposal(const NewcoinAddress& privKey, const uint256& prevLedger, const uint256& position); + LedgerProposal(const NewcoinAddress& privKey, const uint256& prevLedger, const uint256& position, + uint64 closeTime); - // an unsigned proposal - LedgerProposal(const uint256& prevLedger, const uint256& position); + // an unsigned "dummy" proposal for nodes not validating + LedgerProposal(const uint256& prevLedger, const uint256& position, uint64 closeTime); uint256 getSigningHash() const; bool checkSign(const std::string& signature, const uint256& signingHash); @@ -41,11 +43,12 @@ public: const uint256& getCurrentHash() const { return mCurrentHash; } const uint256& getPrevLedger() const { return mPreviousLedger; } uint32 getProposeSeq() const { return mProposeSeq; } + uint64 getCloseTime() const { return mCloseTime; } const NewcoinAddress& peekPublic() const { return mPublicKey; } std::vector getPubKey() const { return mPublicKey.getNodePublic(); } std::vector sign(); - void changePosition(const uint256& newPosition); + void changePosition(const uint256& newPosition, uint64 newCloseTime); }; #endif diff --git a/src/LedgerTiming.h b/src/LedgerTiming.h index 5431443282..90be3584a8 100644 --- a/src/LedgerTiming.h +++ b/src/LedgerTiming.h @@ -1,45 +1,20 @@ #ifndef __LEDGERTIMING__ #define __LEDGERTIMING__ -#define LEDGER_CLOSE_FAST -// #define LEDGER_CLOSE_SLOW - -#ifdef LEDGER_CLOSE_FAST - -// Time between one ledger close and the next ledger close -# define LEDGER_INTERVAL 30 - -// Time before we take a position -# define LEDGER_WOBBLE_TIME 1 - -// Time we acceleratet avalanche -# define LEDGER_ACCEL_CONVERGE 10 - -// Time we permit avalanche to finish -# define LEDGER_CONVERGE 14 - -// Maximum converge time -# define LEDGER_MAX_CONVERGE 20 - -#define AV_PCT_STOP 85 - -#endif - - - -// BEGIN LEDGER_CLOSE_CONTINUOUS - // The number of seconds a ledger may remain idle before closing # define LEDGER_IDLE_INTERVAL 15 // How long we wait to transition from inactive to active # define LEDGER_IDLE_SPIN_TIME 2 -// Avalance tuning (percent of UNL voting yes for us to vote yes) -#define AV_MIN_CONSENSUS 55 -#define AV_AVG_CONSENSUS 65 -#define AV_MAX_CONSENSUS 70 +// Avalanche tuning +#define AV_INIT_CONSENSUS_PCT 50 // percentage of nodes on our UNL that must vote yes +#define AV_MID_CONSENSUS_TIME 50 // percentage of previous close time before we advance +#define AV_MID_CONSENSUS_PCT 65 // percentage of nodes that most vote yes after advancing + +#define AV_LATE_CONSENSUS_TIME 85 // percentage of previous close time before we advance +#define AV_LATE_CONSENSUS_PCT 70 // percentage of nodes that most vote yes after advancing class ContinuousLedgerTiming { @@ -59,8 +34,4 @@ public: }; -// END LEDGER_CLOSE_CONTINUOUS - - - #endif diff --git a/src/NetworkOPs.cpp b/src/NetworkOPs.cpp index 5195ab28d9..a76fc9d82f 100644 --- a/src/NetworkOPs.cpp +++ b/src/NetworkOPs.cpp @@ -511,15 +511,14 @@ int NetworkOPs::beginConsensus(const uint256& networkClosed, Ledger::pointer clo if (!!mConsensus) mConsensus->abort(); prevLedger->setImmutable(); mConsensus = boost::make_shared( - networkClosed, - prevLedger, theApp->getMasterLedger().getCurrentLedger()->getCloseTimeNC()); + networkClosed, prevLedger, theApp->getMasterLedger().getCurrentLedger()->getCloseTimeNC()); Log(lsDEBUG) << "Pre-close time, initiating consensus engine"; return mConsensus->startup(); } // <-- bool: true to relay -bool NetworkOPs::recvPropose(uint32 proposeSeq, const uint256& proposeHash, +bool NetworkOPs::recvPropose(uint32 proposeSeq, const uint256& proposeHash, uint64 closeTime, const std::string& pubKey, const std::string& signature) { // JED: does mConsensus need to be locked? @@ -528,7 +527,7 @@ bool NetworkOPs::recvPropose(uint32 proposeSeq, const uint256& proposeHash, // XXX Take a vuc for pubkey. // Get a preliminary hash to use to suppress duplicates - Serializer s; + Serializer s(128); s.add32(proposeSeq); s.add32(getCurrentLedgerID()); s.addRaw(pubKey); @@ -549,7 +548,7 @@ bool NetworkOPs::recvPropose(uint32 proposeSeq, const uint256& proposeHash, NewcoinAddress naPeerPublic = NewcoinAddress::createNodePublic(strCopy(pubKey)); LedgerProposal::pointer proposal = - boost::make_shared(mConsensus->getLCL(), proposeSeq, proposeHash, naPeerPublic); + boost::make_shared(mConsensus->getLCL(), proposeSeq, proposeHash, closeTime, naPeerPublic); if (!proposal->checkSign(signature)) { // Note that if the LCL is different, the signature check will fail Log(lsWARNING) << "Ledger proposal fails signature check"; @@ -557,7 +556,6 @@ bool NetworkOPs::recvPropose(uint32 proposeSeq, const uint256& proposeHash, } // Is this node on our UNL? - // XXX Is this right? if (!theApp->getUNL().nodeInUNL(proposal->peekPublic())) { Log(lsINFO) << "Untrusted proposal: " << naPeerPublic.humanNodePublic() << " " << diff --git a/src/NetworkOPs.h b/src/NetworkOPs.h index cd2d570b7e..ab16713dd0 100644 --- a/src/NetworkOPs.h +++ b/src/NetworkOPs.h @@ -137,7 +137,7 @@ public: const std::vector& myNode, std::list< std::vector >& newNodes); // ledger proposal/close functions - bool recvPropose(uint32 proposeSeq, const uint256& proposeHash, + bool recvPropose(uint32 proposeSeq, const uint256& proposeHash, uint64 closeTime, const std::string& pubKey, const std::string& signature); bool gotTXData(boost::shared_ptr peer, const uint256& hash, const std::list& nodeIDs, const std::list< std::vector >& nodeData); diff --git a/src/Peer.cpp b/src/Peer.cpp index 35da711dad..d5262dd0bf 100644 --- a/src/Peer.cpp +++ b/src/Peer.cpp @@ -709,7 +709,8 @@ void Peer::recvPropose(newcoin::TMProposeSet& packet) uint256 currentTxHash; memcpy(currentTxHash.begin(), packet.currenttxhash().data(), 32); - if(theApp->getOPs().recvPropose(proposeSeq, currentTxHash, packet.nodepubkey(), packet.signature())) + if(theApp->getOPs().recvPropose(proposeSeq, currentTxHash, packet.closetime(), + packet.nodepubkey(), packet.signature())) { // FIXME: Not all nodes will want proposals PackedMessage::pointer message = boost::make_shared(packet, newcoin::mtPROPOSE_LEDGER); theApp->getConnectionPool().relayMessage(this, message); diff --git a/src/Version.h b/src/Version.h index 27cec8c5a2..2762c59384 100644 --- a/src/Version.h +++ b/src/Version.h @@ -4,7 +4,7 @@ #ifndef SERVER_VERSION_MAJOR #define SERVER_VERSION_MAJOR 0 -#define SERVER_VERSION_MINOR 1 +#define SERVER_VERSION_MINOR 2 #define SERVER_VERSION_SUB "-a" #define SERVER_NAME "NewCoin" @@ -14,10 +14,10 @@ (SERVER_NAME "-" SV_STRINGIZE(SERVER_VERSION_MAJOR) "." SV_STRINGIZE(SERVER_VERSION_MINOR) SERVER_VERSION_SUB) #define PROTO_VERSION_MAJOR 0 -#define PROTO_VERSION_MINOR 1 +#define PROTO_VERSION_MINOR 2 #define MIN_PROTO_MAJOR 0 -#define MIN_PROTO_MINOR 1 +#define MIN_PROTO_MINOR 2 #define MAKE_VERSION_INT(maj,min) ((maj << 16) | min) #define GET_VERSION_MAJOR(ver) (ver >> 16) diff --git a/src/newcoin.proto b/src/newcoin.proto index d902073f4f..af81caeaf2 100644 --- a/src/newcoin.proto +++ b/src/newcoin.proto @@ -105,9 +105,10 @@ message TMProposeSet { required uint32 proposeSeq = 1; required bytes currentTxHash = 2; // the hash of the ledger we are proposing required bytes nodePubKey = 3; - required bytes signature = 4; // signature of above fields - repeated bytes addedTransactions = 5; // not required if number is large - repeated bytes removedTransactions = 6; // not required if number is large + required uint64 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 } enum TxSetStatus {