Begin implementing continuous ledger close.

Pretty much all remaining changes should be to LedgerConsensus.cpp
This commit is contained in:
JoelKatz
2012-06-29 16:34:16 -07:00
parent 2cac0cb288
commit 3a77ef5c82
9 changed files with 47 additions and 68 deletions

View File

@@ -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<LedgerProposal>
(mValSeed, initialLedger->getParentHash(), txSet);
(mValSeed, initialLedger->getParentHash(), txSet, mCloseTime);
else
mOurPosition = boost::make_shared<LedgerProposal>(initialLedger->getParentHash(), txSet);
mOurPosition = boost::make_shared<LedgerProposal>(initialLedger->getParentHash(), txSet, mCloseTime);
mapComplete(txSet, initialSet, false);
if (mProposing) propose(std::vector<uint256>(), std::vector<uint256>());
}
@@ -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<uint256>& 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<unsigned char> pubKey = mOurPosition->getPubKey();
std::vector<unsigned char> sig = mOurPosition->sign();

View File

@@ -81,8 +81,9 @@ class LedgerConsensus : public boost::enable_shared_from_this<LedgerConsensus>
{
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();

View File

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

View File

@@ -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<unsigned char> getPubKey() const { return mPublicKey.getNodePublic(); }
std::vector<unsigned char> sign();
void changePosition(const uint256& newPosition);
void changePosition(const uint256& newPosition, uint64 newCloseTime);
};
#endif

View File

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

View File

@@ -511,15 +511,14 @@ int NetworkOPs::beginConsensus(const uint256& networkClosed, Ledger::pointer clo
if (!!mConsensus) mConsensus->abort();
prevLedger->setImmutable();
mConsensus = boost::make_shared<LedgerConsensus>(
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<LedgerProposal>(mConsensus->getLCL(), proposeSeq, proposeHash, naPeerPublic);
boost::make_shared<LedgerProposal>(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() << " " <<

View File

@@ -135,7 +135,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,
bool recvPropose(uint32 proposeSeq, const uint256& proposeHash, uint64 closeTime,
const std::string& pubKey, const std::string& signature);
bool gotTXData(boost::shared_ptr<Peer> peer, const uint256& hash,
const std::list<SHAMapNode>& nodeIDs, const std::list< std::vector<unsigned char> >& nodeData);

View File

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

View File

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