mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Prepare for deferring ledger proposals to the job queue.
Fix an exploitable defect in the way redundant ledger proposals were suppressed. Fix a bug where the wrong node public key was used.
This commit is contained in:
@@ -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<LedgerProposal>(prevLedger, proposeSeq, proposeHash, closeTime, naPeerPublic);
|
||||
boost::make_shared<LedgerProposal>(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<LedgerProposal>(mConsensus->getLCL(), proposeSeq, proposeHash, closeTime, naPeerPublic);
|
||||
boost::make_shared<LedgerProposal>(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";
|
||||
|
||||
@@ -168,8 +168,8 @@ public:
|
||||
const std::vector<unsigned char>& myNode, std::list< std::vector<unsigned char> >& 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>& peer, const uint256& hash,
|
||||
const std::list<SHAMapNode>& nodeIDs, const std::list< std::vector<unsigned char> >& nodeData);
|
||||
bool recvValidation(const SerializedValidation::pointer& val);
|
||||
|
||||
29
src/Peer.cpp
29
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<PackedMessage>(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<uint64> peers;
|
||||
if (theApp->getOPs().recvValidation(val) && theApp->getSuppression().swapSet(signingHash, peers, SF_RELAYED))
|
||||
{
|
||||
Peer::pointer pp = peer.lock();
|
||||
PackedMessage::pointer message = boost::make_shared<PackedMessage>(*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<ripple::TMValidation>& 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<Peer>(shared_from_this())));
|
||||
boost::weak_ptr<Peer>(shared_from_this())));
|
||||
}
|
||||
#ifndef TRUST_NETWORK
|
||||
catch (...)
|
||||
|
||||
Reference in New Issue
Block a user