20 #include <ripple/app/ledger/InboundLedger.h>
21 #include <ripple/shamap/SHAMapNodeID.h>
22 #include <ripple/app/ledger/AccountStateSF.h>
23 #include <ripple/app/ledger/InboundLedgers.h>
24 #include <ripple/app/ledger/LedgerMaster.h>
25 #include <ripple/app/ledger/TransactionStateSF.h>
26 #include <ripple/app/main/Application.h>
27 #include <ripple/app/misc/NetworkOPs.h>
28 #include <ripple/basics/Log.h>
29 #include <ripple/core/JobQueue.h>
30 #include <ripple/overlay/Overlay.h>
31 #include <ripple/resource/Fees.h>
32 #include <ripple/protocol/HashPrefix.h>
33 #include <ripple/protocol/jss.h>
34 #include <ripple/nodestore/DatabaseShard.h>
40 using namespace std::chrono_literals;
72 app.journal(
"InboundLedger"))
75 , mHaveTransactions (false)
80 , mReceiveDispatched (false)
101 "Acquiring shard with no shard store available";
113 else if (shardStore &&
mSeq >= shardStore->earliestLedgerSeq())
115 if (
auto l = shardStore->fetchLedger(
mHash,
mSeq))
133 "Acquiring ledger we already have in " <<
134 " local store. " <<
mHash;
152 "Deferring InboundLedger timer due to load";
161 ptr->invokeOnTimer ();
169 if ((seq != 0) && (
mSeq == 0))
202 if (entry.second->type () == protocol::liAS_NODE)
208 "Acquire " <<
mHash <<
" abort " <<
222 if (
mLedger->info().txHash.isNonZero ())
224 if (
mLedger->txMap().getHash().isZero ())
227 ret =
mLedger->txMap().getNeededHashes (max, filter);
239 if (
mLedger->info().accountHash.isNonZero ())
241 if (
mLedger->stateMap().getHash().isZero ())
244 ret =
mLedger->stateMap().getNeededHashes (max, filter);
282 auto makeLedger = [&,
this](
Blob const& data)
285 "Ledger header found in fetch pack";
286 mLedger = std::make_shared<Ledger>(
296 " cannot be a ledger";
310 "Ledger header found in fetch pack";
319 "Ledger header found in node store";
320 makeLedger(node->getData());
333 if (
mLedger->info().txHash.isZero())
342 if (
mLedger->txMap().fetchRoot(
348 "Had full txn map locally";
357 if (
mLedger->info().accountHash.isZero())
360 "We are acquiring a ledger with a zero account hash";
366 if (
mLedger->stateMap().fetchRoot(
367 SHAMapHash{mLedger->info().accountHash}, &filter))
372 "Had full AS map locally";
381 "Had everything locally";
396 "Already done " <<
mHash;
425 "No progress(" << pc <<
426 ") for ledger " <<
mHash;
462 "Acquire " <<
mHash <<
493 if (self->mComplete && !self->mFailed)
495 self->app().getLedgerMaster().checkAccept(
497 self->app().getLedgerMaster().tryAdvance();
500 self->app().getInboundLedgers().logFailure (
501 self->getHash(), self->getSeq());
514 "Trigger on ledger: " <<
mHash <<
524 "Trigger acquiring ledger " <<
mHash <<
" from " << peer;
527 "Trigger acquiring ledger " <<
mHash;
545 " failed local for " <<
mHash;
550 protocol::TMGetLedger tmGL;
555 tmGL.set_querytype (protocol::qtINDIRECT);
564 protocol::TMGetObjectByHash tmBH;
565 bool typeSet =
false;
566 tmBH.set_query (
true);
568 for (
auto const& p : need)
571 "Want: " << p.second;
575 tmBH.set_type (p.first);
579 if (p.first == tmBH.type ())
581 protocol::TMIndexedObject* io = tmBH.add_objects ();
582 io->set_hash (p.second.begin (), p.second.size ());
584 io->set_ledgerseq(
mSeq);
588 auto packet = std::make_shared <Message> (
589 tmBH, protocol::mtGET_OBJECTS);
603 "getNeededHashes says acquire is complete";
616 tmGL.set_itype (protocol::liBASE);
618 tmGL.set_ledgerseq (
mSeq);
620 "Sending header request to " <<
621 (peer ?
"selected peer" :
"all peers");
627 tmGL.set_ledgerseq (
mLedger->info().seq);
632 tmGL.set_querydepth (0);
634 else if (peer && peer->isHighLatency ())
637 tmGL.set_querydepth (2);
640 tmGL.set_querydepth (1);
648 if (!
mLedger->stateMap().isValid ())
652 else if (
mLedger->stateMap().getHash ().isZero ())
655 tmGL.set_itype (protocol::liAS_NODE);
658 "Sending AS root request to " <<
659 (peer ?
"selected peer" :
"all peers");
670 auto nodes =
mLedger->stateMap().getMissingNodes (
679 if (!
mLedger->stateMap().isValid ())
695 tmGL.set_itype (protocol::liAS_NODE);
696 for (
auto const&
id : nodes)
698 * (tmGL.add_nodeids ()) =
id.first.getRawString ();
702 "Sending AS node request (" <<
703 nodes.size () <<
") to " <<
704 (peer ?
"selected peer" :
"all peers");
711 "All AS nodes filtered";
722 if (!
mLedger->txMap().isValid ())
726 else if (
mLedger->txMap().getHash ().isZero ())
729 tmGL.set_itype (protocol::liTX_NODE);
732 "Sending TX root request to " << (
733 peer ?
"selected peer" :
"all peers");
742 auto nodes =
mLedger->txMap().getMissingNodes (
747 if (!
mLedger->txMap().isValid ())
763 tmGL.set_itype (protocol::liTX_NODE);
764 for (
auto const& n : nodes)
766 * (tmGL.add_nodeids ()) = n.first.getRawString ();
769 "Sending TX node request (" <<
770 nodes.size () <<
") to " <<
771 (peer ?
"selected peer" :
"all peers");
778 "All TX nodes filtered";
787 "Done:" << (
mComplete ?
" complete" :
"") <<
788 (
mFailed ?
" failed " :
" ") <<
802 nodes.begin(), nodes.end(),
803 [
this](
auto const& item)
805 return mRecentNodes.count (item.second) == 0;
811 if (dup == nodes.begin ())
814 "filterNodes: all duplicates";
825 "filterNodes: pruning duplicates";
827 nodes.erase (dup, nodes.end());
834 if (nodes.size () > limit)
835 nodes.resize (limit);
837 for (
auto const& n : nodes)
849 "got header acquiring ledger " <<
mHash;
862 "Acquire hash mismatch: " <<
mLedger->info().hash <<
875 s.
addRaw (data.data(), data.size());
878 if (
mLedger->info().txHash.isZero ())
881 if (
mLedger->info().accountHash.isZero ())
884 mLedger->txMap().setSynching ();
885 mLedger->stateMap().setSynching ();
899 "TX node without header";
910 auto nodeIDit = nodeIDs.
cbegin ();
911 auto nodeDatait = data.begin ();
915 while (nodeIDit != nodeIDs.
cend ())
917 if (nodeIDit->isRoot ())
919 san +=
mLedger->txMap().addRootNode (
927 san +=
mLedger->txMap().addKnownNode (
928 *nodeIDit,
makeSlice(*nodeDatait), &filter);
937 if (!
mLedger->txMap().isSynching ())
958 "got ASdata (" << nodeIDs.
size () <<
959 ") acquiring ledger " <<
mHash;
960 if (nodeIDs.
size () == 1)
963 "got AS node: " << nodeIDs.
front ();
971 "Don't have ledger header";
982 auto nodeIDit = nodeIDs.
cbegin ();
983 auto nodeDatait = data.begin ();
987 while (nodeIDit != nodeIDs.
cend ())
989 if (nodeIDit->isRoot ())
991 san +=
mLedger->stateMap().addRootNode (
1003 san +=
mLedger->stateMap().addKnownNode (
1004 *nodeIDit,
makeSlice(*nodeDatait), &filter);
1008 "Unable to add AS node";
1017 if (!
mLedger->stateMap().isSynching ())
1050 san +=
mLedger->stateMap().addRootNode (
1074 san +=
mLedger->txMap().addRootNode (
1087 protocol::TMGetObjectByHash::otLEDGER,
mHash));
1098 protocol::TMGetObjectByHash::otSTATE_NODE, h));
1109 protocol::TMGetObjectByHash::otTRANSACTION_NODE, h));
1146 protocol::TMLedgerData& packet)
1150 if (packet.type () == protocol::liBASE)
1152 if (packet.nodes_size () < 1)
1155 "Got empty header data";
1164 if (
takeHeader (packet.nodes (0).nodedata ()))
1169 "Got invalid header data";
1176 if (!
mHaveState && (packet.nodes ().size () > 1) &&
1180 "Included AS root invalid";
1187 "Included TX root invalid";
1197 if ((packet.type () == protocol::liTX_NODE) || (
1198 packet.type () == protocol::liAS_NODE))
1200 if (packet.nodes ().size () == 0)
1203 "Got response with no nodes";
1209 nodeIDs.
reserve(packet.nodes().size());
1211 nodeData.
reserve(packet.nodes().size());
1213 for (
int i = 0; i < packet.nodes ().size (); ++i)
1215 const protocol::TMLedgerNode& node = packet.nodes (i);
1217 if (!node.has_nodeid () || !node.has_nodedata ())
1226 node.nodeid ().size ()));
1228 node.nodedata ().end ()));
1233 if (packet.type () == protocol::liTX_NODE)
1237 "Ledger TX node stats: " << san.
get();
1243 "Ledger AS node stats: " << san.
get();
1262 int chosenPeerCount = -1;
1283 for (
auto& entry : data)
1285 if (
auto peer = entry.first.lock())
1288 if (count > chosenPeerCount)
1290 chosenPeerCount = count;
1291 chosenPeer = std::move (peer);
1310 ret[jss::complete] =
true;
1313 ret[jss::failed] =
true;
1316 ret[jss::peers] =
static_cast<int>(
mPeers.size());
1335 ret[jss::needed_state_hashes] = hv;
1345 ret[jss::needed_transaction_hashes] = hv;