diff --git a/src/NetworkOPs.cpp b/src/NetworkOPs.cpp index 7bb4c6705..966570be6 100644 --- a/src/NetworkOPs.cpp +++ b/src/NetworkOPs.cpp @@ -695,50 +695,38 @@ bool NetworkOPs::haveConsensusObject() } // <-- bool: true to relay -bool NetworkOPs::recvPropose(uint64 peerId, uint32 proposeSeq, const uint256& proposeHash, const uint256& prevLedger, - uint32 closeTime, const std::string& pubKey, const std::string& signature, const RippleAddress& nodePublic) +bool NetworkOPs::recvPropose(const uint256& suppression, uint32 proposeSeq, const uint256& proposeHash, + const uint256& prevLedger, uint32 closeTime, const std::string& signature, + const RippleAddress& nodePublic) { // JED: does mConsensus need to be locked? // XXX Validate key. // XXX Take a vuc for pubkey. - // Get a preliminary hash to use to suppress duplicates - Serializer s(256); - s.add256(proposeHash); - s.add256(prevLedger); - s.add32(proposeSeq); - s.add32(closeTime); - s.addRaw(pubKey); - s.addRaw(signature); - if (!theApp->isNew(s.getSHA512Half(), peerId)) - return false; - - RippleAddress naPeerPublic = RippleAddress::createNodePublic(strCopy(pubKey)); - if (!haveConsensusObject()) { cLog(lsINFO) << "Received proposal outside consensus window"; return mMode != omFULL; } - if (mConsensus->isOurPubKey(naPeerPublic)) + if (mConsensus->isOurPubKey(nodePublic)) { cLog(lsTRACE) << "Received our own validation"; return false; } // Is this node on our UNL? - if (!theApp->getUNL().nodeInUNL(naPeerPublic)) + if (!theApp->getUNL().nodeInUNL(nodePublic)) { - cLog(lsINFO) << "Untrusted proposal: " << naPeerPublic.humanNodePublic() << " " << proposeHash; + cLog(lsINFO) << "Untrusted proposal: " << nodePublic.humanNodePublic() << " " << proposeHash; return true; } if (prevLedger.isNonZero()) { // proposal includes a previous ledger LedgerProposal::pointer proposal = - boost::make_shared(prevLedger, proposeSeq, proposeHash, closeTime, naPeerPublic); + boost::make_shared(prevLedger, proposeSeq, proposeHash, closeTime, nodePublic); if (!proposal->checkSign(signature)) { cLog(lsWARNING) << "New-style ledger proposal fails signature check"; @@ -751,7 +739,7 @@ bool NetworkOPs::recvPropose(uint64 peerId, uint32 proposeSeq, const uint256& pr } LedgerProposal::pointer proposal = - boost::make_shared(mConsensus->getLCL(), proposeSeq, proposeHash, closeTime, naPeerPublic); + boost::make_shared(mConsensus->getLCL(), proposeSeq, proposeHash, closeTime, nodePublic); if (!proposal->checkSign(signature)) { // Note that if the LCL is different, the signature check will fail cLog(lsWARNING) << "Ledger proposal fails signature check"; diff --git a/src/NetworkOPs.h b/src/NetworkOPs.h index e2d476c43..cd5243b26 100644 --- a/src/NetworkOPs.h +++ b/src/NetworkOPs.h @@ -168,8 +168,8 @@ public: const std::vector& myNode, std::list< std::vector >& newNodes); // ledger proposal/close functions - bool recvPropose(uint64 peerId, uint32 proposeSeq, const uint256& proposeHash, const uint256& prevLedger, - uint32 closeTime, const std::string& pubKey, const std::string& signature, const RippleAddress& nodePublic); + bool recvPropose(const uint256& suppression, uint32 proposeSeq, const uint256& proposeHash, + const uint256& prevLedger, uint32 closeTime, const std::string& signature, const RippleAddress& nodePublic); bool gotTXData(const boost::shared_ptr& peer, const uint256& hash, const std::list& nodeIDs, const std::list< std::vector >& nodeData); bool recvValidation(const SerializedValidation::pointer& val); diff --git a/src/Peer.cpp b/src/Peer.cpp index d441876dc..15a7b0b4f 100644 --- a/src/Peer.cpp +++ b/src/Peer.cpp @@ -740,7 +740,7 @@ void Peer::recvTransaction(ripple::TMTransaction& packet) void Peer::recvPropose(ripple::TMProposeSet& packet) { if ((packet.currenttxhash().size() != 32) || (packet.nodepubkey().size() < 28) || - (packet.signature().size() < 56)) + (packet.signature().size() < 56) || (packet.nodepubkey().size() > 128) || (packet.signature().size() > 128)) { cLog(lsWARNING) << "Received proposal is malformed"; return; @@ -752,8 +752,23 @@ void Peer::recvPropose(ripple::TMProposeSet& packet) if ((packet.has_previousledger()) && (packet.previousledger().size() == 32)) memcpy(prevLedger.begin(), packet.previousledger().data(), 32); - if(theApp->getOPs().recvPropose(mPeerId, packet.proposeseq(), currentTxHash, prevLedger, packet.closetime(), - packet.nodepubkey(), packet.signature(), mNodePublic)) + Serializer s(512); + s.add256(currentTxHash); + s.add256(prevLedger); + s.add32(packet.proposeseq()); + s.add32(packet.closetime()); + s.addVL(packet.nodepubkey()); + s.addVL(packet.signature()); + uint256 suppression = s.getSHA512Half(); + + if (!theApp->isNew(suppression, mPeerId)) + return; + + RippleAddress nodePublic = RippleAddress::createNodePublic(strCopy(packet.nodepubkey())); +// bool isTrusted = theApp->getUNL().nodeInUNL(nodePublic); + + if(theApp->getOPs().recvPropose(suppression, packet.proposeseq(), currentTxHash, prevLedger, packet.closetime(), + packet.signature(), nodePublic)) { // FIXME: Not all nodes will want proposals PackedMessage::pointer message = boost::make_shared(packet, ripple::mtPROPOSE_LEDGER); theApp->getConnectionPool().relayMessage(this, message); @@ -792,11 +807,11 @@ static void checkValidation(Job&, SerializedValidation::pointer val, uint256 sig return; } - if (theApp->getOPs().recvValidation(val)) + std::set peers; + if (theApp->getOPs().recvValidation(val) && theApp->getSuppression().swapSet(signingHash, peers, SF_RELAYED)) { - Peer::pointer pp = peer.lock(); PackedMessage::pointer message = boost::make_shared(*packet, ripple::mtVALIDATION); - theApp->getConnectionPool().relayMessage(pp ? pp.get() : NULL, message); + theApp->getConnectionPool().relayMessageBut(peers, message); } } #ifndef TRUST_NETWORK @@ -835,7 +850,7 @@ void Peer::recvValidation(const boost::shared_ptr& packet) bool isTrusted = theApp->getUNL().nodeInUNL(val->getSignerPublic()); theApp->getJobQueue().addJob(isTrusted ? jtVALIDATION_t : jtVALIDATION_ut, boost::bind(&checkValidation, _1, val, signingHash, isTrusted, packet, - boost::weak_ptr(shared_from_this()))); + boost::weak_ptr(shared_from_this()))); } #ifndef TRUST_NETWORK catch (...)