diff --git a/src/cpp/ripple/LedgerAcquire.cpp b/src/cpp/ripple/LedgerAcquire.cpp index 46b48cf74..503a4cbf7 100644 --- a/src/cpp/ripple/LedgerAcquire.cpp +++ b/src/cpp/ripple/LedgerAcquire.cpp @@ -211,23 +211,25 @@ void LedgerAcquire::trigger(Peer::ref peer, bool timer) cLog(lsTRACE) << "base=" << mHaveBase << " tx=" << mHaveTransactions << " as=" << mHaveState; } + ripple::TMGetLedger tmGL; + tmGL.set_ledgerhash(mHash.begin(), mHash.size()); + if (getTimeouts() != 0) + tmGL.set_querytype(ripple::qtINDIRECT); + if (!mHaveBase) { - ripple::TMGetLedger tmGL; - tmGL.set_ledgerhash(mHash.begin(), mHash.size()); tmGL.set_itype(ripple::liBASE); cLog(lsTRACE) << "Sending base request to " << (peer ? "selected peer" : "all peers"); sendRequest(tmGL, peer); } + tmGL.set_ledgerseq(mLedger->getLedgerSeq()); + if (mHaveBase && !mHaveTransactions) { assert(mLedger); if (mLedger->peekTransactionMap()->getHash().isZero()) { // we need the root node - ripple::TMGetLedger tmGL; - tmGL.set_ledgerhash(mHash.begin(), mHash.size()); - tmGL.set_ledgerseq(mLedger->getLedgerSeq()); tmGL.set_itype(ripple::liTX_NODE); *(tmGL.add_nodeids()) = SHAMapNode().getRawString(); cLog(lsTRACE) << "Sending TX root request to " << (peer ? "selected peer" : "all peers"); @@ -251,12 +253,11 @@ void LedgerAcquire::trigger(Peer::ref peer, bool timer) } else { - ripple::TMGetLedger tmGL; - tmGL.set_ledgerhash(mHash.begin(), mHash.size()); - tmGL.set_ledgerseq(mLedger->getLedgerSeq()); tmGL.set_itype(ripple::liTX_NODE); BOOST_FOREACH(SHAMapNode& it, nodeIDs) + { *(tmGL.add_nodeids()) = it.getRawString(); + } cLog(lsTRACE) << "Sending TX node " << nodeIDs.size() << " request to " << (peer ? "selected peer" : "all peers"); sendRequest(tmGL, peer); @@ -269,9 +270,6 @@ void LedgerAcquire::trigger(Peer::ref peer, bool timer) assert(mLedger); if (mLedger->peekAccountStateMap()->getHash().isZero()) { // we need the root node - ripple::TMGetLedger tmGL; - tmGL.set_ledgerhash(mHash.begin(), mHash.size()); - tmGL.set_ledgerseq(mLedger->getLedgerSeq()); tmGL.set_itype(ripple::liAS_NODE); *(tmGL.add_nodeids()) = SHAMapNode().getRawString(); cLog(lsTRACE) << "Sending AS root request to " << (peer ? "selected peer" : "all peers"); @@ -295,9 +293,6 @@ void LedgerAcquire::trigger(Peer::ref peer, bool timer) } else { - ripple::TMGetLedger tmGL; - tmGL.set_ledgerhash(mHash.begin(), mHash.size()); - tmGL.set_ledgerseq(mLedger->getLedgerSeq()); tmGL.set_itype(ripple::liAS_NODE); BOOST_FOREACH(SHAMapNode& it, nodeIDs) *(tmGL.add_nodeids()) = it.getRawString(); diff --git a/src/cpp/ripple/Peer.cpp b/src/cpp/ripple/Peer.cpp index 5aad301fe..d4167994b 100644 --- a/src/cpp/ripple/Peer.cpp +++ b/src/cpp/ripple/Peer.cpp @@ -1179,7 +1179,7 @@ void Peer::recvGetLedger(ripple::TMGetLedger& packet) std::vector usablePeers; BOOST_FOREACH(Peer::ref peer, peerList) { - if (peer->hasTxSet(txHash)) + if (peer->hasTxSet(txHash) && (peer.get() != this)) usablePeers.push_back(peer); } if (usablePeers.empty()) @@ -1218,7 +1218,29 @@ void Peer::recvGetLedger(ripple::TMGetLedger& packet) } memcpy(ledgerhash.begin(), packet.ledgerhash().data(), 32); ledger = theApp->getMasterLedger().getLedgerByHash(ledgerhash); + tLog(!ledger, lsINFO) << "Don't have ledger " << ledgerhash; + if (!ledger && (packet.has_querytype() && !packet.has_requestcookie())) + { + cLog(lsINFO) << "Trying to route ledger request"; + std::vector peerList = theApp->getConnectionPool().getPeerVector(); + std::vector usablePeers; + BOOST_FOREACH(Peer::ref peer, peerList) + { + if (peer->hasLedger(ledgerhash) && (peer.get() != this)) + usablePeers.push_back(peer); + } + if (usablePeers.empty()) + { + cLog(lsINFO) << "Unable to route ledger request"; + return; + } + Peer::ref selectedPeer = usablePeers[rand() % usablePeers.size()]; + packet.set_requestcookie(getPeerId()); + selectedPeer->sendPacket(boost::make_shared(packet, ripple::mtGET_LEDGER)); + cLog(lsDEBUG) << "Ledger request routed"; + return; + } } else if (packet.has_ledgerseq()) { @@ -1357,7 +1379,7 @@ void Peer::recvLedger(ripple::TMLedgerData& packet) } else { - cLog(lsINFO) << "Unable to route TX set reply"; + cLog(lsINFO) << "Unable to route TX/ledger data reply"; punishPeer(PP_UNWANTED_DATA); } return;