1#include <xrpld/app/ledger/LedgerMaster.h> 
    2#include <xrpld/app/ledger/LedgerReplayer.h> 
    3#include <xrpld/app/ledger/detail/LedgerReplayMsgHandler.h> 
    4#include <xrpld/app/main/Application.h> 
    6#include <xrpl/protocol/LedgerHeader.h> 
   16    , journal_(app.journal(
"LedgerReplayMsgHandler"))
 
 
   20protocol::TMProofPathResponse
 
   24    protocol::TMProofPathRequest& packet = *msg;
 
   25    protocol::TMProofPathResponse reply;
 
   27    if (!packet.has_key() || !packet.has_ledgerhash() || !packet.has_type() ||
 
   30        !protocol::TMLedgerMapType_IsValid(packet.type()))
 
   33        reply.set_error(protocol::TMReplyError::reBAD_REQUEST);
 
   36    reply.set_key(packet.key());
 
   37    reply.set_ledgerhash(packet.ledgerhash());
 
   38    reply.set_type(packet.type());
 
   40    uint256 const key(packet.key());
 
   41    uint256 const ledgerHash(packet.ledgerhash());
 
   46            << 
"getProofPath: Don't have ledger " << ledgerHash;
 
   47        reply.set_error(protocol::TMReplyError::reNO_LEDGER);
 
   52        switch (packet.type())
 
   54            case protocol::lmACCOUNT_STATE:
 
   55                return ledger->stateMap().getProofPath(key);
 
   56            case protocol::lmTRANASCTION:
 
   57                return ledger->txMap().getProofPath(key);
 
   67        JLOG(
journal_.
debug()) << 
"getProofPath: Don't have the node " << key
 
   68                               << 
" of ledger " << ledgerHash;
 
   69        reply.set_error(protocol::TMReplyError::reNO_NODE);
 
   75    addRaw(ledger->info(), nData);
 
   78    for (
auto const& b : *path)
 
   79        reply.add_path(b.data(), b.size());
 
   82                           << 
" of ledger " << ledgerHash << 
" path length " 
 
   91    protocol::TMProofPathResponse& reply = *msg;
 
   92    if (reply.has_error() || !reply.has_key() || !reply.has_ledgerhash() ||
 
   93        !reply.has_type() || !reply.has_ledgerheader() ||
 
   94        reply.path_size() == 0)
 
  100    if (reply.type() != protocol::lmACCOUNT_STATE)
 
  103            << 
"Bad message: we only support the state ShaMap for now";
 
  109        {reply.ledgerheader().data(), reply.ledgerheader().size()});
 
  110    uint256 replyHash(reply.ledgerhash());
 
  116    info.hash = replyHash;
 
  122            << 
"Bad message: we only support the short skip list for now. " 
  130    path.reserve(reply.path_size());
 
  131    for (
int i = 0; i < reply.path_size(); ++i)
 
  133        path.emplace_back(reply.path(i).begin(), reply.path(i).end());
 
  138        JLOG(
journal_.
debug()) << 
"Bad message: Proof path verify failed";
 
  144    if (!node || !node->isLeaf())
 
  156    JLOG(
journal_.
debug()) << 
"Bad message: Cannot get ShaMapItem";
 
 
  160protocol::TMReplayDeltaResponse
 
  164    protocol::TMReplayDeltaRequest& packet = *msg;
 
  165    protocol::TMReplayDeltaResponse reply;
 
  167    if (!packet.has_ledgerhash() ||
 
  171        reply.set_error(protocol::TMReplyError::reBAD_REQUEST);
 
  174    reply.set_ledgerhash(packet.ledgerhash());
 
  176    uint256 const ledgerHash{packet.ledgerhash()};
 
  178    if (!ledger || !ledger->isImmutable())
 
  181            << 
"getReplayDelta: Don't have ledger " << ledgerHash;
 
  182        reply.set_error(protocol::TMReplyError::reNO_LEDGER);
 
  188    addRaw(ledger->info(), nData);
 
  191    auto const& txMap = ledger->txMap();
 
  193        [&](boost::intrusive_ptr<SHAMapItem const> 
const& 
txNode) {
 
  197    JLOG(
journal_.
debug()) << 
"getReplayDelta for ledger " << ledgerHash
 
  198                           << 
" txMap hash " << txMap.getHash().as_uint256();
 
 
  206    protocol::TMReplayDeltaResponse& reply = *msg;
 
  207    if (reply.has_error() || !reply.has_ledgerheader())
 
  214        {reply.ledgerheader().data(), reply.ledgerheader().size()});
 
  215    uint256 replyHash(reply.ledgerhash());
 
  221    info.hash = replyHash;
 
  223    auto numTxns = reply.transaction_size();
 
  228        for (
int i = 0; i < numTxns; ++i)
 
  235                reply.transaction(i).data(), reply.transaction(i).size());
 
  247            auto tid = tx->getTransactionID();
 
  249            orderedTxns.
emplace(meta[sfTransactionIndex], std::move(tx));
 
  268        JLOG(
journal_.
debug()) << 
"Bad message: Transactions verify failed";
 
 
virtual Family & getNodeFamily()=0
 
virtual LedgerMaster & getLedgerMaster()=0
 
std::shared_ptr< Ledger const > getLedgerByHash(uint256 const &hash)
 
protocol::TMReplayDeltaResponse processReplayDeltaRequest(std::shared_ptr< protocol::TMReplayDeltaRequest > const &msg)
Process TMReplayDeltaRequest and return TMReplayDeltaResponse.
 
bool processProofPathResponse(std::shared_ptr< protocol::TMProofPathResponse > const &msg)
Process TMProofPathResponse.
 
LedgerReplayer & replayer_
 
bool processReplayDeltaResponse(std::shared_ptr< protocol::TMReplayDeltaResponse > const &msg)
Process TMReplayDeltaResponse.
 
protocol::TMProofPathResponse processProofPathRequest(std::shared_ptr< protocol::TMProofPathRequest > const &msg)
Process TMProofPathRequest and return TMProofPathResponse.
 
LedgerReplayMsgHandler(Application &app, LedgerReplayer &replayer)
 
Manages the lifetime of ledger replay tasks.
 
void gotReplayDelta(LedgerInfo const &info, std::map< std::uint32_t, std::shared_ptr< STTx const > > &&txns)
Process a ledger delta (extracted from a TMReplayDeltaResponse message)
 
void gotSkipList(LedgerInfo const &info, boost::intrusive_ptr< SHAMapItem const > const &data)
Process a skip list (extracted from a TMProofPathResponse message)
 
uint256 const & as_uint256() const
 
boost::intrusive_ptr< SHAMapItem const > const & peekItem() const
 
static intr_ptr::SharedPtr< SHAMapTreeNode > makeFromWire(Slice rawNode)
 
A SHAMap is both a radix tree with a fan-out of 16 and a Merkle tree.
 
bool addGiveItem(SHAMapNodeType type, boost::intrusive_ptr< SHAMapItem const > item)
 
SHAMapHash getHash() const
 
static bool verifyProofPath(uint256 const &rootHash, uint256 const &key, std::vector< Blob > const &path)
Verify the proof path.
 
Slice getSlice(std::size_t bytes)
 
Slice slice() const noexcept
 
void const * getDataPtr() const
 
static constexpr std::size_t size()
 
Keylet const & skip() noexcept
The index of the "short" skip list.
 
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
 
uint256 calculateLedgerHash(LedgerInfo const &info)
 
std::enable_if_t< std::is_same< T, char >::value||std::is_same< T, unsigned char >::value, Slice > makeSlice(std::array< T, N > const &a)
 
boost::intrusive_ptr< SHAMapItem > make_shamapitem(uint256 const &tag, Slice data)
 
@ txNode
transaction plus metadata
 
void addRaw(LedgerHeader const &, Serializer &, bool includeHash=false)
 
LedgerHeader deserializeHeader(Slice data, bool hasHash=false)
Deserialize a ledger header from a byte array.