20#ifndef RIPPLE_OVERLAY_PROTOCOLMESSAGE_H_INCLUDED
21#define RIPPLE_OVERLAY_PROTOCOLMESSAGE_H_INCLUDED
23#include <xrpld/overlay/Compression.h>
24#include <xrpld/overlay/Message.h>
25#include <xrpld/overlay/detail/ZeroCopyStream.h>
26#include <xrpl/basics/ByteUtilities.h>
27#include <xrpl/beast/utility/instrumentation.h>
28#include <xrpl/protocol/messages.h>
29#include <boost/asio/buffer.hpp>
30#include <boost/asio/buffers_iterator.hpp>
31#include <boost/system/error_code.hpp>
40inline protocol::MessageType
43 return protocol::mtGET_LEDGER;
46inline protocol::MessageType
49 return protocol::mtLEDGER_DATA;
52inline protocol::MessageType
55 return protocol::mtREPLAY_DELTA_REQ;
58inline protocol::MessageType
61 return protocol::mtPROOF_PATH_REQ;
65template <
class =
void>
71 case protocol::mtMANIFESTS:
73 case protocol::mtPING:
75 case protocol::mtCLUSTER:
77 case protocol::mtENDPOINTS:
79 case protocol::mtTRANSACTION:
81 case protocol::mtGET_LEDGER:
83 case protocol::mtLEDGER_DATA:
85 case protocol::mtPROPOSE_LEDGER:
87 case protocol::mtSTATUS_CHANGE:
89 case protocol::mtHAVE_SET:
91 case protocol::mtVALIDATORLIST:
92 return "validator_list";
93 case protocol::mtVALIDATORLISTCOLLECTION:
94 return "validator_list_collection";
95 case protocol::mtVALIDATION:
97 case protocol::mtGET_OBJECTS:
99 case protocol::mtHAVE_TRANSACTIONS:
100 return "have_transactions";
101 case protocol::mtTRANSACTIONS:
102 return "transactions";
103 case protocol::mtSQUELCH:
105 case protocol::mtPROOF_PATH_REQ:
106 return "proof_path_request";
107 case protocol::mtPROOF_PATH_RESPONSE:
108 return "proof_path_response";
109 case protocol::mtREPLAY_DELTA_REQ:
110 return "replay_delta_request";
111 case protocol::mtREPLAY_DELTA_RESPONSE:
112 return "replay_delta_response";
148template <
typename BufferSequence>
152 return boost::asio::buffers_iterator<BufferSequence, std::uint8_t>::begin(
156template <
typename BufferSequence>
160 return boost::asio::buffers_iterator<BufferSequence, std::uint8_t>::end(
173template <
class BufferSequence>
176 boost::system::error_code& ec,
177 BufferSequence
const& bufs,
186 "ripple::detail::parseMessageHeader : non-empty buffer");
218 for (
int i = 0; i != 4; ++i)
226 for (
int i = 0; i != 2; ++i)
229 for (
int i = 0; i != 4; ++i)
238 if ((*iter & 0xFC) == 0)
250 for (
int i = 0; i != 4; ++i)
256 for (
int i = 0; i != 2; ++i)
274 auto const m = std::make_shared<T>();
291 if (payloadSize == 0 || !m->ParseFromArray(payload.
data(), payloadSize))
294 else if (!m->ParseFromZeroCopyStream(&stream))
309 auto const m = parseMessageContent<T>(header, buffers);
314 handler.onMessageBegin(
320 handler.onMessage(m);
340template <
class Buffers,
class Handler>
343 Buffers
const& buffers,
349 auto const size = boost::asio::buffer_size(buffers);
376 if (!handler.compressionEnabled() &&
385 if (header->total_wire_size > size)
387 hint = header->total_wire_size - size;
393 switch (header->message_type)
395 case protocol::mtMANIFESTS:
396 success = detail::invoke<protocol::TMManifests>(
397 *header, buffers, handler);
399 case protocol::mtPING:
401 detail::invoke<protocol::TMPing>(*header, buffers, handler);
403 case protocol::mtCLUSTER:
405 detail::invoke<protocol::TMCluster>(*header, buffers, handler);
407 case protocol::mtENDPOINTS:
408 success = detail::invoke<protocol::TMEndpoints>(
409 *header, buffers, handler);
411 case protocol::mtTRANSACTION:
412 success = detail::invoke<protocol::TMTransaction>(
413 *header, buffers, handler);
415 case protocol::mtGET_LEDGER:
416 success = detail::invoke<protocol::TMGetLedger>(
417 *header, buffers, handler);
419 case protocol::mtLEDGER_DATA:
420 success = detail::invoke<protocol::TMLedgerData>(
421 *header, buffers, handler);
423 case protocol::mtPROPOSE_LEDGER:
424 success = detail::invoke<protocol::TMProposeSet>(
425 *header, buffers, handler);
427 case protocol::mtSTATUS_CHANGE:
428 success = detail::invoke<protocol::TMStatusChange>(
429 *header, buffers, handler);
431 case protocol::mtHAVE_SET:
432 success = detail::invoke<protocol::TMHaveTransactionSet>(
433 *header, buffers, handler);
435 case protocol::mtVALIDATION:
436 success = detail::invoke<protocol::TMValidation>(
437 *header, buffers, handler);
439 case protocol::mtVALIDATORLIST:
440 success = detail::invoke<protocol::TMValidatorList>(
441 *header, buffers, handler);
443 case protocol::mtVALIDATORLISTCOLLECTION:
444 success = detail::invoke<protocol::TMValidatorListCollection>(
445 *header, buffers, handler);
447 case protocol::mtGET_OBJECTS:
448 success = detail::invoke<protocol::TMGetObjectByHash>(
449 *header, buffers, handler);
451 case protocol::mtHAVE_TRANSACTIONS:
452 success = detail::invoke<protocol::TMHaveTransactions>(
453 *header, buffers, handler);
455 case protocol::mtTRANSACTIONS:
456 success = detail::invoke<protocol::TMTransactions>(
457 *header, buffers, handler);
459 case protocol::mtSQUELCH:
461 detail::invoke<protocol::TMSquelch>(*header, buffers, handler);
463 case protocol::mtPROOF_PATH_REQ:
464 success = detail::invoke<protocol::TMProofPathRequest>(
465 *header, buffers, handler);
467 case protocol::mtPROOF_PATH_RESPONSE:
468 success = detail::invoke<protocol::TMProofPathResponse>(
469 *header, buffers, handler);
471 case protocol::mtREPLAY_DELTA_REQ:
472 success = detail::invoke<protocol::TMReplayDeltaRequest>(
473 *header, buffers, handler);
475 case protocol::mtREPLAY_DELTA_RESPONSE:
476 success = detail::invoke<protocol::TMReplayDeltaResponse>(
477 *header, buffers, handler);
480 handler.onMessageUnknown(header->message_type);
485 result.
first = header->total_wire_size;
497template <
class Hasher>
503 hash_append(h, safe_cast<int>(protocolMessageType(msg)));
508 if (msg.has_ledgerhash())
511 if (msg.has_ledgerseq())
514 for (
auto const& nodeId : msg.nodeids())
523 if (msg.has_querytype())
526 if (msg.has_querydepth())
530template <
class Hasher>
536 hash_append(h, safe_cast<int>(protocolMessageType(msg)));
540 for (
auto const& node : msg.nodes())
543 if (node.has_nodeid())
547 if (msg.has_requestcookie())
std::enable_if_t< is_contiguously_hashable< T, Hasher >::value > hash_append(Hasher &h, T const &t) noexcept
Logically concatenate input data to a Hasher.
void hash_append(Hasher &h, TMValidatorList const &msg)
std::size_t decompress(InputStream &in, std::size_t inSize, std::uint8_t *decompressed, std::size_t decompressedSize, Algorithm algorithm=Algorithm::LZ4)
Decompress input stream.
std::shared_ptr< T > parseMessageContent(MessageHeader const &header, Buffers const &buffers)
bool invoke(MessageHeader const &header, Buffers const &buffers, Handler &handler)
auto buffersBegin(BufferSequence const &bufs)
std::optional< MessageHeader > parseMessageHeader(boost::system::error_code &ec, BufferSequence const &bufs, std::size_t size)
Parse a message header.
auto buffersEnd(BufferSequence const &bufs)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
std::string protocolMessageName(int type)
Returns the name of a protocol message given its type.
protocol::MessageType protocolMessageType(protocol::TMGetLedger const &)
std::pair< std::size_t, boost::system::error_code > invokeProtocolMessage(Buffers const &buffers, Handler &handler, std::size_t &hint)
Calls the handler for up to one protocol message in the passed buffers.
std::error_code make_error_code(ripple::TokenCodecErrc e)
constexpr std::size_t maximiumMessageSize