diff --git a/src/LedgerConsensus.cpp b/src/LedgerConsensus.cpp index 916290d6dd..980e0be376 100644 --- a/src/LedgerConsensus.cpp +++ b/src/LedgerConsensus.cpp @@ -813,7 +813,12 @@ void LedgerConsensus::Saccept(boost::shared_ptr This, SHAMap::p void LedgerConsensus::deferProposal(const LedgerProposal::pointer& proposal, const NewcoinAddress& peerPublic) { - /**/ + if (!peerPublic.isValid()) + return; + std::list& props = mDeferredProposals[peerPublic.getNodeID()]; + if (props.size() > (mPreviousProposers + 10)) + props.pop_front(); + props.push_back(proposal); } void LedgerConsensus::playbackProposals() @@ -821,7 +826,15 @@ void LedgerConsensus::playbackProposals() for ( boost::unordered_map< uint160, std::list >::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); + } + } } } diff --git a/src/LedgerConsensus.h b/src/LedgerConsensus.h index eae19d222b..31ffdf06c9 100644 --- a/src/LedgerConsensus.h +++ b/src/LedgerConsensus.h @@ -171,7 +171,7 @@ public: bool haveConsensus(); bool peerPosition(const LedgerProposal::pointer&); - void deferProposal(const LedgerProposal::pointer& proposal, const NewcoinAddress& peerPublic); + void deferProposal(const LedgerProposal::pointer& proposal, const NewcoinAddress& peerPublic); bool peerHasSet(const Peer::pointer& peer, const uint256& set, newcoin::TxSetStatus status); diff --git a/src/LedgerProposal.h b/src/LedgerProposal.h index 790b61fb4d..70d4bbbe7a 100644 --- a/src/LedgerProposal.h +++ b/src/LedgerProposal.h @@ -2,6 +2,7 @@ #define __PROPOSELEDEGR__ #include +#include #include @@ -21,6 +22,8 @@ protected: NewcoinAddress mPublicKey; NewcoinAddress mPrivateKey; // If ours + std::string mSignature; // set only if needed + public: typedef boost::shared_ptr pointer; @@ -39,16 +42,21 @@ public: uint256 getSigningHash() const; bool checkSign(const std::string& signature, const uint256& signingHash); bool checkSign(const std::string& signature) { return checkSign(signature, getSigningHash()); } + bool checkSign() { return checkSign(mSignature, getSigningHash()); } const uint160& getPeerID() const { return mPeerID; } const uint256& getCurrentHash() const { return mCurrentHash; } const uint256& getPrevLedger() const { return mPreviousLedger; } uint32 getProposeSeq() const { return mProposeSeq; } uint32 getCloseTime() const { return mCloseTime; } - const NewcoinAddress& peekPublic() const { return mPublicKey; } - std::vector getPubKey() const { return mPublicKey.getNodePublic(); } + const NewcoinAddress& peekPublic() const { return mPublicKey; } + std::vector getPubKey() const { return mPublicKey.getNodePublic(); } std::vector sign(); + void setPrevLedger(const uint256& prevLedger) { mPreviousLedger = prevLedger; } + void setSignature(const std::string& signature) { mSignature = signature; } + + void changePosition(const uint256& newPosition, uint32 newCloseTime); Json::Value getJson() const; }; diff --git a/src/NetworkOPs.cpp b/src/NetworkOPs.cpp index 642877bd95..06d4b64a5f 100644 --- a/src/NetworkOPs.cpp +++ b/src/NetworkOPs.cpp @@ -639,7 +639,10 @@ bool NetworkOPs::recvPropose(uint32 proposeSeq, const uint256& proposeHash, uint { // 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); + } return false; }