/** We got some data for a ledger we are no longer acquiring Since we paid the price to receive it, we might as well stash it in case we need it. Nodes are received in wire format and must be stashed/hashed in prefix format */ void gotStaleData (std::shared_ptr<protocol::TMLedgerData> packet_ptr) override { const uint256 uZero; Serializer s; try { for (int i = 0; i < packet_ptr->nodes ().size (); ++i) { auto const& node = packet_ptr->nodes (i); if (!node.has_nodeid () || !node.has_nodedata ()) return; auto id_string = node.nodeid(); auto newNode = SHAMapAbstractNode::make( makeSlice(node.nodedata()), 0, snfWIRE, SHAMapHash{uZero}, false, app_.journal ("SHAMapNodeID"), SHAMapNodeID(id_string.data(), id_string.size())); if (!newNode) return; s.erase(); newNode->addRaw(s, snfPREFIX); auto blob = std::make_shared<Blob> (s.begin(), s.end()); app_.getLedgerMaster().addFetchPack( newNode->getNodeHash().as_uint256(), blob); } } catch (std::exception const&) { } }
/** We got some data for a ledger we are no longer acquiring Since we paid the price to receive it, we might as well stash it in case we need it. Nodes are received in wire format and must be stashed/hashed in prefix format */ void gotStaleData (std::shared_ptr<protocol::TMLedgerData> packet_ptr) { const uint256 uZero; Serializer s; try { for (int i = 0; i < packet_ptr->nodes ().size (); ++i) { auto const& node = packet_ptr->nodes (i); if (!node.has_nodeid () || !node.has_nodedata ()) return; auto newNode = SHAMapAbstractNode::make( Blob (node.nodedata().begin(), node.nodedata().end()), 0, snfWIRE, uZero, false); if (!newNode) return; s.erase(); newNode->addRaw(s, snfPREFIX); auto blob = std::make_shared<Blob> (s.begin(), s.end()); getApp().getOPs().addFetchPack (newNode->getNodeHash(), blob); } } catch (...) { } }
void SHAMapTreeNode::addRaw (Serializer& s, SHANodeFormat format) { assert ((format == snfPREFIX) || (format == snfWIRE) || (format == snfHASH)); if (mType == tnERROR) throw std::runtime_error ("invalid I node type"); if (format == snfHASH) { s.add256 (getNodeHash ()); } else if (mType == tnINNER) { assert (!isEmpty ()); if (format == snfPREFIX) { s.add32 (HashPrefix::innerNode); for (int i = 0; i < 16; ++i) s.add256 (mHashes[i]); } else { if (getBranchCount () < 12) { // compressed node for (int i = 0; i < 16; ++i) if (!isEmptyBranch (i)) { s.add256 (mHashes[i]); s.add8 (i); } s.add8 (3); } else { for (int i = 0; i < 16; ++i) s.add256 (mHashes[i]); s.add8 (2); } } } else if (mType == tnACCOUNT_STATE) { if (format == snfPREFIX) { s.add32 (HashPrefix::leafNode); s.addRaw (mItem->peekData ()); s.add256 (mItem->getTag ()); } else { s.addRaw (mItem->peekData ()); s.add256 (mItem->getTag ()); s.add8 (1); } } else if (mType == tnTRANSACTION_NM) { if (format == snfPREFIX) { s.add32 (HashPrefix::transactionID); s.addRaw (mItem->peekData ()); } else { s.addRaw (mItem->peekData ()); s.add8 (0); } } else if (mType == tnTRANSACTION_MD) { if (format == snfPREFIX) { s.add32 (HashPrefix::txNode); s.addRaw (mItem->peekData ()); s.add256 (mItem->getTag ()); } else { s.addRaw (mItem->peekData ()); s.add256 (mItem->getTag ()); s.add8 (4); } } else assert (false); }