Fix the package recipe for consumers of libxrpl (#4631)

- "Rename" the type `LedgerInfo` to `LedgerHeader` (but leave an alias
  for `LedgerInfo` to not yet disturb existing uses). Put it in its own
  public header, named after itself, so that it is more easily found.
- Move the type `Fees` and NFT serialization functions into public
  (installed) headers.
- Compile the XRPL and gRPC protocol buffers directly into `libxrpl` and
  install their headers. Fix the Conan recipe to correctly export these
  types.

Addresses change (2) in
https://github.com/XRPLF/XRPL-Standards/discussions/121.

For context: This work supports Clio's dependence on libxrpl. Clio is
just an example consumer. These changes should benefit all current and
future consumers.

---------

Co-authored-by: cyan317 <120398799+cindyyan317@users.noreply.github.com>
Signed-off-by: Manoj Doshi <mdoshi@ripple.com>
This commit is contained in:
John Freeman
2023-07-18 12:09:51 -05:00
committed by Manoj Doshi
parent b28f62bbd9
commit 91e9658217
38 changed files with 528 additions and 381 deletions

View File

@@ -85,6 +85,7 @@ target_sources (xrpl_core PRIVATE
src/ripple/protocol/impl/STIssue.cpp
src/ripple/protocol/impl/Keylet.cpp
src/ripple/protocol/impl/LedgerFormats.cpp
src/ripple/protocol/impl/LedgerHeader.cpp
src/ripple/protocol/impl/PublicKey.cpp
src/ripple/protocol/impl/Quality.cpp
src/ripple/protocol/impl/QualityFunction.cpp
@@ -116,6 +117,9 @@ target_sources (xrpl_core PRIVATE
src/ripple/protocol/impl/UintTypes.cpp
src/ripple/protocol/impl/digest.cpp
src/ripple/protocol/impl/tokens.cpp
src/ripple/protocol/impl/NFTSyntheticSerializer.cpp
src/ripple/protocol/impl/NFTokenID.cpp
src/ripple/protocol/impl/NFTokenOfferID.cpp
#[===============================[
main sources:
subdir: crypto
@@ -232,6 +236,7 @@ install (
src/ripple/protocol/BuildInfo.h
src/ripple/protocol/ErrorCodes.h
src/ripple/protocol/Feature.h
src/ripple/protocol/Fees.h
src/ripple/protocol/HashPrefix.h
src/ripple/protocol/Indexes.h
src/ripple/protocol/InnerObjectFormats.h
@@ -240,6 +245,10 @@ install (
src/ripple/protocol/Keylet.h
src/ripple/protocol/KnownFormats.h
src/ripple/protocol/LedgerFormats.h
src/ripple/protocol/LedgerHeader.h
src/ripple/protocol/NFTSyntheticSerializer.h
src/ripple/protocol/NFTokenID.h
src/ripple/protocol/NFTokenOfferID.h
src/ripple/protocol/Protocol.h
src/ripple/protocol/PublicKey.h
src/ripple/protocol/Quality.h
@@ -277,6 +286,9 @@ install (
src/ripple/protocol/UintTypes.h
src/ripple/protocol/digest.h
src/ripple/protocol/jss.h
src/ripple/protocol/serialize.h
src/ripple/protocol/nft.h
src/ripple/protocol/nftPageMask.h
src/ripple/protocol/tokens.h
DESTINATION include/ripple/protocol)
install (
@@ -296,6 +308,7 @@ install (
DESTINATION include/ripple/beast/clock)
install (
FILES
src/ripple/beast/core/CurrentThreadName.h
src/ripple/beast/core/LexicalCast.h
src/ripple/beast/core/List.h
src/ripple/beast/core/SemanticVersion.h
@@ -309,6 +322,14 @@ install (
install (
FILES src/ripple/beast/hash/impl/xxhash.h
DESTINATION include/ripple/beast/hash/impl)
install (
FILES
src/ripple/beast/net/IPAddress.h
src/ripple/beast/net/IPAddressConversion.h
src/ripple/beast/net/IPAddressV4.h
src/ripple/beast/net/IPAddressV6.h
src/ripple/beast/net/IPEndpoint.h
DESTINATION include/ripple/beast/net)
install (
FILES
src/ripple/beast/rfc2616.h
@@ -714,9 +735,6 @@ target_sources (rippled PRIVATE
src/ripple/rpc/impl/ShardVerificationScheduler.cpp
src/ripple/rpc/impl/Status.cpp
src/ripple/rpc/impl/TransactionSign.cpp
src/ripple/rpc/impl/NFTokenID.cpp
src/ripple/rpc/impl/NFTokenOfferID.cpp
src/ripple/rpc/impl/NFTSyntheticSerializer.cpp
#[===============================[
main sources:
subdir: perflog

View File

@@ -14,7 +14,7 @@ if (is_multiconfig)
file(GLOB md_files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} CONFIGURE_DEPENDS
*.md)
LIST(APPEND all_sources ${md_files})
foreach (_target secp256k1::secp256k1 ed25519::ed25519 pbufs xrpl_core rippled)
foreach (_target secp256k1::secp256k1 ed25519::ed25519 xrpl_core rippled)
get_target_property (_type ${_target} TYPE)
if(_type STREQUAL "INTERFACE_LIBRARY")
continue()

View File

@@ -1,22 +1,27 @@
find_package(Protobuf 3.8)
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/proto_gen)
set(output_dir ${CMAKE_BINARY_DIR}/proto_gen)
file(MAKE_DIRECTORY ${output_dir})
set(ccbd ${CMAKE_CURRENT_BINARY_DIR})
set(CMAKE_CURRENT_BINARY_DIR ${CMAKE_BINARY_DIR}/proto_gen)
set(CMAKE_CURRENT_BINARY_DIR ${output_dir})
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS src/ripple/proto/ripple.proto)
set(CMAKE_CURRENT_BINARY_DIR ${ccbd})
add_library(pbufs STATIC ${PROTO_SRCS} ${PROTO_HDRS})
target_include_directories(pbufs SYSTEM PUBLIC
${CMAKE_BINARY_DIR}/proto_gen
${CMAKE_BINARY_DIR}/proto_gen/src/ripple/proto
target_include_directories(xrpl_core SYSTEM PUBLIC
# The generated implementation imports the header relative to the output
# directory.
$<BUILD_INTERFACE:${output_dir}>
$<BUILD_INTERFACE:${output_dir}/src>
)
target_link_libraries(pbufs protobuf::libprotobuf)
target_compile_options(pbufs
target_sources(xrpl_core PRIVATE ${output_dir}/src/ripple/proto/ripple.pb.cc)
install(
FILES ${output_dir}/src/ripple/proto/ripple.pb.h
DESTINATION include/ripple/proto)
target_link_libraries(xrpl_core PUBLIC protobuf::libprotobuf)
target_compile_options(xrpl_core
PUBLIC
$<$<BOOL:${XCODE}>:
--system-header-prefix="google/protobuf"
-Wno-deprecated-dynamic-exception-spec
>
)
add_library(Ripple::pbufs ALIAS pbufs)

View File

@@ -5,21 +5,30 @@ find_package(gRPC 1.23)
grpc defs and bundle into a
static lib
#]=================================]
set(GRPC_GEN_DIR "${CMAKE_BINARY_DIR}/proto_gen_grpc")
set(output_dir "${CMAKE_BINARY_DIR}/proto_gen_grpc")
set(GRPC_GEN_DIR "${output_dir}/ripple/proto")
file(MAKE_DIRECTORY ${GRPC_GEN_DIR})
set(GRPC_PROTO_SRCS)
set(GRPC_PROTO_HDRS)
set(GRPC_PROTO_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/src/ripple/proto/org")
file(GLOB_RECURSE GRPC_DEFINITION_FILES LIST_DIRECTORIES false "${GRPC_PROTO_ROOT}/*.proto")
file(GLOB_RECURSE GRPC_DEFINITION_FILES "${GRPC_PROTO_ROOT}/*.proto")
foreach(file ${GRPC_DEFINITION_FILES})
# /home/user/rippled/src/ripple/proto/org/.../v1/get_ledger.proto
get_filename_component(_abs_file ${file} ABSOLUTE)
# /home/user/rippled/src/ripple/proto/org/.../v1
get_filename_component(_abs_dir ${_abs_file} DIRECTORY)
# get_ledger
get_filename_component(_basename ${file} NAME_WE)
# /home/user/rippled/src/ripple/proto
get_filename_component(_proto_inc ${GRPC_PROTO_ROOT} DIRECTORY) # updir one level
# org/.../v1/get_ledger.proto
file(RELATIVE_PATH _rel_root_file ${_proto_inc} ${_abs_file})
# org/.../v1
get_filename_component(_rel_root_dir ${_rel_root_file} DIRECTORY)
# src/ripple/proto/org/.../v1
file(RELATIVE_PATH _rel_dir ${CMAKE_CURRENT_SOURCE_DIR} ${_abs_dir})
# .cmake/proto_gen_grpc/ripple/proto/org/.../v1/get_ledger.grpc.pb.cc
set(src_1 "${GRPC_GEN_DIR}/${_rel_root_dir}/${_basename}.grpc.pb.cc")
set(src_2 "${GRPC_GEN_DIR}/${_rel_root_dir}/${_basename}.pb.cc")
set(hdr_1 "${GRPC_GEN_DIR}/${_rel_root_dir}/${_basename}.grpc.pb.h")
@@ -36,20 +45,32 @@ foreach(file ${GRPC_DEFINITION_FILES})
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Running gRPC C++ protocol buffer compiler on ${file}"
VERBATIM)
set_source_files_properties(${src_1} ${src_2} ${hdr_1} ${hdr_2} PROPERTIES GENERATED TRUE)
set_source_files_properties(${src_1} ${src_2} ${hdr_1} ${hdr_2} PROPERTIES
GENERATED TRUE
SKIP_UNITY_BUILD_INCLUSION ON
)
list(APPEND GRPC_PROTO_SRCS ${src_1} ${src_2})
list(APPEND GRPC_PROTO_HDRS ${hdr_1} ${hdr_2})
endforeach()
add_library(grpc_pbufs STATIC ${GRPC_PROTO_SRCS} ${GRPC_PROTO_HDRS})
#target_include_directories(grpc_pbufs PRIVATE src)
target_include_directories(grpc_pbufs SYSTEM PUBLIC ${GRPC_GEN_DIR})
target_link_libraries(grpc_pbufs
target_include_directories(xrpl_core SYSTEM PUBLIC
$<BUILD_INTERFACE:${output_dir}>
$<BUILD_INTERFACE:${output_dir}/ripple/proto>
# The generated sources include headers relative to this path. Fix it later.
$<INSTALL_INTERFACE:include/ripple/proto>
)
target_sources(xrpl_core PRIVATE ${GRPC_PROTO_SRCS})
install(
DIRECTORY ${output_dir}/ripple
DESTINATION include/
FILES_MATCHING PATTERN "*.h"
)
target_link_libraries(xrpl_core PUBLIC
"gRPC::grpc++"
# libgrpc is missing references.
absl::random_random
)
target_compile_options(grpc_pbufs
target_compile_options(xrpl_core
PRIVATE
$<$<BOOL:${MSVC}>:-wd4065>
$<$<NOT:$<BOOL:${MSVC}>>:-Wno-deprecated-declarations>
@@ -59,4 +80,3 @@ target_compile_options(grpc_pbufs
--system-header-prefix="google/protobuf"
-Wno-deprecated-dynamic-exception-spec
>)
add_library(Ripple::grpc_pbufs ALIAS grpc_pbufs)

View File

@@ -93,8 +93,6 @@ endif()
find_package(nudb REQUIRED)
find_package(date REQUIRED)
include(deps/Protobuf)
include(deps/gRPC)
target_link_libraries(ripple_libs INTERFACE
ed25519::ed25519
@@ -102,8 +100,6 @@ target_link_libraries(ripple_libs INTERFACE
lz4::lz4
OpenSSL::Crypto
OpenSSL::SSL
Ripple::grpc_pbufs
Ripple::pbufs
secp256k1::secp256k1
soci::soci
SQLite::SQLite3
@@ -131,6 +127,8 @@ endif()
###
include(RippledCore)
include(deps/Protobuf)
include(deps/gRPC)
include(RippledInstall)
include(RippledCov)
include(RippledMultiConfig)

View File

@@ -151,9 +151,12 @@ class Xrpl(ConanFile):
'libed25519.a',
'libsecp256k1.a',
]
libxrpl.includedirs = ['include']
# TODO: Fix the protobufs to include each other relative to
# `include/`, not `include/ripple/proto/`.
libxrpl.includedirs = ['include', 'include/ripple/proto']
libxrpl.requires = [
'boost::boost',
'openssl::crypto',
'date::date',
'grpc::grpc++',
]

View File

@@ -197,14 +197,6 @@ private:
std::unique_ptr<PeerSet> mPeerSet;
};
/** Deserialize a ledger header from a byte array. */
LedgerInfo
deserializeHeader(Slice data, bool hasHash = false);
/** Deserialize a ledger header (prefixed with 4 bytes) from a byte array. */
LedgerInfo
deserializePrefixedHeader(Slice data, bool hasHash = false);
} // namespace ripple
#endif

View File

@@ -26,6 +26,7 @@
#include <ripple/json/Object.h>
#include <ripple/protocol/STTx.h>
#include <ripple/protocol/jss.h>
#include <ripple/protocol/serialize.h>
#include <ripple/rpc/Context.h>
namespace ripple {
@@ -70,22 +71,6 @@ addJson(Json::Value&, LedgerFill const&);
Json::Value
getJson(LedgerFill const&);
/** Serialize an object to a blob. */
template <class Object>
Blob
serializeBlob(Object const& o)
{
Serializer s;
o.add(s);
return s.peekData();
}
/** Serialize an object to a hex string. */
inline std::string
serializeHex(STObject const& o)
{
return strHex(serializeBlob(o));
}
} // namespace ripple
#endif

View File

@@ -271,36 +271,6 @@ InboundLedger::neededStateHashes(int max, SHAMapSyncFilter* filter) const
mLedger->info().accountHash, mLedger->stateMap(), max, filter);
}
LedgerInfo
deserializeHeader(Slice data, bool hasHash)
{
SerialIter sit(data.data(), data.size());
LedgerInfo info;
info.seq = sit.get32();
info.drops = sit.get64();
info.parentHash = sit.get256();
info.txHash = sit.get256();
info.accountHash = sit.get256();
info.parentCloseTime =
NetClock::time_point{NetClock::duration{sit.get32()}};
info.closeTime = NetClock::time_point{NetClock::duration{sit.get32()}};
info.closeTimeResolution = NetClock::duration{sit.get8()};
info.closeFlags = sit.get8();
if (hasHash)
info.hash = sit.get256();
return info;
}
LedgerInfo
deserializePrefixedHeader(Slice data, bool hasHash)
{
return deserializeHeader(data + 4, hasHash);
}
// See how much of the ledger data is stored locally
// Data found in a fetch pack will be stored
void
@@ -568,10 +538,9 @@ InboundLedger::trigger(std::shared_ptr<Peer> const& peer, TriggerReason reason)
if (auto stream = journal_.trace())
{
stream << "Trigger acquiring ledger " << hash_;
if (peer)
stream << "Trigger acquiring ledger " << hash_ << " from " << peer;
else
stream << "Trigger acquiring ledger " << hash_;
stream << " from " << peer;
if (complete_ || failed_)
stream << "complete=" << complete_ << " failed=" << failed_;

View File

@@ -21,6 +21,7 @@
#include <ripple/app/ledger/LedgerReplayer.h>
#include <ripple/app/ledger/impl/LedgerReplayMsgHandler.h>
#include <ripple/app/main/Application.h>
#include <ripple/protocol/LedgerHeader.h>
#include <memory>

View File

@@ -21,6 +21,7 @@
#define RIPPLE_APP_REPORTING_ETLSOURCE_H_INCLUDED
#include <ripple/app/main/Application.h>
#include <ripple/app/reporting/ETLHelpers.h>
#include <ripple/proto/org/xrpl/rpc/v1/xrp_ledger.grpc.pb.h>
#include <ripple/protocol/STLedgerEntry.h>
#include <ripple/rpc/Context.h>
@@ -29,7 +30,6 @@
#include <boost/beast/core/string.hpp>
#include <boost/beast/websocket.hpp>
#include "org/xrpl/rpc/v1/xrp_ledger.grpc.pb.h"
#include <grpcpp/grpcpp.h>
namespace ripple {

View File

@@ -21,12 +21,11 @@
#define RIPPLE_APP_REPORTING_P2PPROXY_H_INCLUDED
#include <ripple/app/main/Application.h>
#include <ripple/proto/org/xrpl/rpc/v1/xrp_ledger.grpc.pb.h>
#include <ripple/rpc/Context.h>
#include <ripple/rpc/impl/Handler.h>
#include <boost/beast/websocket.hpp>
#include "org/xrpl/rpc/v1/xrp_ledger.grpc.pb.h"
#include <grpcpp/grpcpp.h>
namespace ripple {

View File

@@ -25,34 +25,12 @@
#include <ripple/ledger/ApplyView.h>
#include <ripple/protocol/AccountID.h>
#include <ripple/protocol/TER.h>
#include <ripple/protocol/nft.h>
namespace ripple {
namespace nft {
// Separate taxons from regular integers.
struct TaxonTag
{
};
using Taxon = tagged_integer<std::uint32_t, TaxonTag>;
inline Taxon
toTaxon(std::uint32_t i)
{
return static_cast<Taxon>(i);
}
inline std::uint32_t
toUInt32(Taxon t)
{
return static_cast<std::uint32_t>(t);
}
constexpr std::uint16_t const flagBurnable = 0x0001;
constexpr std::uint16_t const flagOnlyXRP = 0x0002;
constexpr std::uint16_t const flagCreateTrustLines = 0x0004;
constexpr std::uint16_t const flagTransferable = 0x0008;
/** Delete up to a specified number of offers from the specified token offer
* directory. */
std::size_t
@@ -116,72 +94,6 @@ removeToken(
bool
deleteTokenOffer(ApplyView& view, std::shared_ptr<SLE> const& offer);
inline std::uint16_t
getFlags(uint256 const& id)
{
std::uint16_t flags;
memcpy(&flags, id.begin(), 2);
return boost::endian::big_to_native(flags);
}
inline std::uint16_t
getTransferFee(uint256 const& id)
{
std::uint16_t fee;
memcpy(&fee, id.begin() + 2, 2);
return boost::endian::big_to_native(fee);
}
inline std::uint32_t
getSerial(uint256 const& id)
{
std::uint32_t seq;
memcpy(&seq, id.begin() + 28, 4);
return boost::endian::big_to_native(seq);
}
inline Taxon
cipheredTaxon(std::uint32_t tokenSeq, Taxon taxon)
{
// An issuer may issue several NFTs with the same taxon; to ensure that NFTs
// are spread across multiple pages we lightly mix the taxon up by using the
// sequence (which is not under the issuer's direct control) as the seed for
// a simple linear congruential generator.
//
// From the Hull-Dobell theorem we know that f(x)=(m*x+c) mod n will yield a
// permutation of [0, n) when n is a power of 2 if m is congruent to 1 mod 4
// and c is odd.
//
// Here we use m = 384160001 and c = 2459. The modulo is implicit because we
// use 2^32 for n and the arithmetic gives it to us for "free".
//
// Note that the scramble value we calculate is not cryptographically secure
// but that's fine since all we're looking for is some dispersion.
//
// **IMPORTANT** Changing these numbers would be a breaking change requiring
// an amendment along with a way to distinguish token IDs that
// were generated with the old code.
return taxon ^ toTaxon(((384160001 * tokenSeq) + 2459));
}
inline Taxon
getTaxon(uint256 const& id)
{
std::uint32_t taxon;
memcpy(&taxon, id.begin() + 24, 4);
taxon = boost::endian::big_to_native(taxon);
// The taxon cipher is just an XOR, so it is reversible by applying the
// XOR a second time.
return cipheredTaxon(getSerial(id), toTaxon(taxon));
}
inline AccountID
getIssuer(uint256 const& id)
{
return AccountID::fromVoid(id.data() + 4);
}
bool
compareTokens(uint256 const& a, uint256 const& b);

View File

@@ -27,7 +27,9 @@
#include <ripple/beast/hash/uhash.h>
#include <ripple/beast/utility/Journal.h>
#include <ripple/ledger/detail/ReadViewFwdRange.h>
#include <ripple/protocol/Fees.h>
#include <ripple/protocol/Indexes.h>
#include <ripple/protocol/LedgerHeader.h>
#include <ripple/protocol/Protocol.h>
#include <ripple/protocol/Rules.h>
#include <ripple/protocol/STAmount.h>
@@ -41,79 +43,6 @@
namespace ripple {
/** Reflects the fee settings for a particular ledger.
The fees are always the same for any transactions applied
to a ledger. Changes to fees occur in between ledgers.
*/
struct Fees
{
XRPAmount base{0}; // Reference tx cost (drops)
XRPAmount reserve{0}; // Reserve base (drops)
XRPAmount increment{0}; // Reserve increment (drops)
explicit Fees() = default;
Fees(Fees const&) = default;
Fees&
operator=(Fees const&) = default;
/** Returns the account reserve given the owner count, in drops.
The reserve is calculated as the reserve base plus
the reserve increment times the number of increments.
*/
XRPAmount
accountReserve(std::size_t ownerCount) const
{
return reserve + ownerCount * increment;
}
};
//------------------------------------------------------------------------------
/** Information about the notional ledger backing the view. */
struct LedgerInfo
{
explicit LedgerInfo() = default;
//
// For all ledgers
//
LedgerIndex seq = 0;
NetClock::time_point parentCloseTime = {};
//
// For closed ledgers
//
// Closed means "tx set already determined"
uint256 hash = beast::zero;
uint256 txHash = beast::zero;
uint256 accountHash = beast::zero;
uint256 parentHash = beast::zero;
XRPAmount drops = beast::zero;
// If validated is false, it means "not yet validated."
// Once validated is true, it will never be set false at a later time.
// VFALCO TODO Make this not mutable
bool mutable validated = false;
bool accepted = false;
// flags indicating how this ledger close took place
int closeFlags = 0;
// the resolution for this ledger close time (2-120 seconds)
NetClock::duration closeTimeResolution = {};
// For closed ledgers, the time the ledger
// closed. For open ledgers, the time the ledger
// will close if there's no transactions.
//
NetClock::time_point closeTime = {};
};
//------------------------------------------------------------------------------
/** A view into a ledger.
@@ -344,18 +273,6 @@ public:
//------------------------------------------------------------------------------
// ledger close flags
static std::uint32_t const sLCF_NoConsensusTime = 0x01;
inline bool
getCloseAgree(LedgerInfo const& info)
{
return (info.closeFlags & sLCF_NoConsensusTime) == 0;
}
void
addRaw(LedgerInfo const&, Serializer&, bool includeHash = false);
Rules
makeRulesGivenLedger(DigestAwareReadView const& ledger, Rules const& current);

View File

@@ -158,23 +158,6 @@ cdirNext(
//
//------------------------------------------------------------------------------
void
addRaw(LedgerInfo const& info, Serializer& s, bool includeHash)
{
s.add32(info.seq);
s.add64(info.drops.drops());
s.addBitString(info.parentHash);
s.addBitString(info.txHash);
s.addBitString(info.accountHash);
s.add32(info.parentCloseTime.time_since_epoch().count());
s.add32(info.closeTime.time_since_epoch().count());
s.add8(info.closeTimeResolution.count());
s.add8(info.closeFlags);
if (includeHash)
s.addBitString(info.hash);
}
bool
hasExpired(ReadView const& view, std::optional<std::uint32_t> const& exp)
{

View File

@@ -31,6 +31,7 @@
#include <ripple/overlay/Overlay.h>
#include <ripple/overlay/predicates.h>
#include <ripple/protocol/HashPrefix.h>
#include <ripple/protocol/LedgerHeader.h>
#include <ripple/protocol/digest.h>
#include <boost/algorithm/string/predicate.hpp>

View File

@@ -25,6 +25,7 @@
#include <ripple/nodestore/Manager.h>
#include <ripple/nodestore/impl/DeterministicShard.h>
#include <ripple/nodestore/impl/Shard.h>
#include <ripple/protocol/LedgerHeader.h>
#include <ripple/protocol/digest.h>
namespace ripple {

View File

@@ -28,7 +28,7 @@
#include <ripple/overlay/ReduceRelayCommon.h>
#include <ripple/overlay/Squelch.h>
#include <ripple/protocol/PublicKey.h>
#include <ripple.pb.h>
#include <ripple/protocol/messages.h>
#include <algorithm>
#include <memory>

View File

@@ -32,7 +32,6 @@
#include <cstdint>
#include <memory>
#include <optional>
#include <ripple.pb.h>
#include <type_traits>
#include <vector>

View File

@@ -0,0 +1,57 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2023 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_PROTOCOL_FEES_H_INCLUDED
#define RIPPLE_PROTOCOL_FEES_H_INCLUDED
#include <ripple/basics/XRPAmount.h>
namespace ripple {
/** Reflects the fee settings for a particular ledger.
The fees are always the same for any transactions applied
to a ledger. Changes to fees occur in between ledgers.
*/
struct Fees
{
XRPAmount base{0}; // Reference tx cost (drops)
XRPAmount reserve{0}; // Reserve base (drops)
XRPAmount increment{0}; // Reserve increment (drops)
explicit Fees() = default;
Fees(Fees const&) = default;
Fees&
operator=(Fees const&) = default;
/** Returns the account reserve given the owner count, in drops.
The reserve is calculated as the reserve base plus
the reserve increment times the number of increments.
*/
XRPAmount
accountReserve(std::size_t ownerCount) const
{
return reserve + ownerCount * increment;
}
};
} // namespace ripple
#endif

View File

@@ -0,0 +1,103 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2023 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_PROTOCOL_LEDGERHEADER_H_INCLUDED
#define RIPPLE_PROTOCOL_LEDGERHEADER_H_INCLUDED
#include <ripple/basics/Slice.h>
#include <ripple/basics/XRPAmount.h>
#include <ripple/basics/base_uint.h>
#include <ripple/basics/chrono.h>
#include <ripple/protocol/Protocol.h>
#include <ripple/protocol/Serializer.h>
namespace ripple {
/** Information about the notional ledger backing the view. */
struct LedgerHeader
{
explicit LedgerHeader() = default;
//
// For all ledgers
//
LedgerIndex seq = 0;
NetClock::time_point parentCloseTime = {};
//
// For closed ledgers
//
// Closed means "tx set already determined"
uint256 hash = beast::zero;
uint256 txHash = beast::zero;
uint256 accountHash = beast::zero;
uint256 parentHash = beast::zero;
XRPAmount drops = beast::zero;
// If validated is false, it means "not yet validated."
// Once validated is true, it will never be set false at a later time.
// VFALCO TODO Make this not mutable
bool mutable validated = false;
bool accepted = false;
// flags indicating how this ledger close took place
int closeFlags = 0;
// the resolution for this ledger close time (2-120 seconds)
NetClock::duration closeTimeResolution = {};
// For closed ledgers, the time the ledger
// closed. For open ledgers, the time the ledger
// will close if there's no transactions.
//
NetClock::time_point closeTime = {};
};
// We call them "headers" in conversation
// but "info" in code. Unintuitive.
// This alias lets us give the "correct" name to the class
// without yet disturbing existing uses.
using LedgerInfo = LedgerHeader;
// ledger close flags
static std::uint32_t const sLCF_NoConsensusTime = 0x01;
inline bool
getCloseAgree(LedgerHeader const& info)
{
return (info.closeFlags & sLCF_NoConsensusTime) == 0;
}
void
addRaw(LedgerHeader const&, Serializer&, bool includeHash = false);
/** Deserialize a ledger header from a byte array. */
LedgerHeader
deserializeHeader(Slice data, bool hasHash = false);
/** Deserialize a ledger header (prefixed with 4 bytes) from a byte array. */
LedgerHeader
deserializePrefixedHeader(Slice data, bool hasHash = false);
} // namespace ripple
#endif

View File

@@ -17,28 +17,17 @@
*/
//==============================================================================
#ifndef RIPPLE_RPC_NFTSYNTHETICSERIALIZER_H_INCLUDED
#define RIPPLE_RPC_NFTSYNTHETICSERIALIZER_H_INCLUDED
#ifndef RIPPLE_PROTOCOL_NFTSYNTHETICSERIALIZER_H_INCLUDED
#define RIPPLE_PROTOCOL_NFTSYNTHETICSERIALIZER_H_INCLUDED
#include <ripple/protocol/Protocol.h>
#include <ripple/protocol/STBase.h>
#include <ripple/json/json_forwards.h>
#include <ripple/protocol/STTx.h>
#include <ripple/protocol/TxMeta.h>
#include <functional>
#include <memory>
namespace Json {
class Value;
}
namespace ripple {
class TxMeta;
class STTx;
namespace RPC {
struct JsonContext;
/**
Adds common synthetic fields to transaction-related JSON responses
@@ -47,12 +36,10 @@ struct JsonContext;
void
insertNFTSyntheticInJson(
Json::Value&,
RPC::JsonContext const&,
std::shared_ptr<STTx const> const&,
TxMeta const&);
/** @} */
} // namespace RPC
} // namespace ripple
#endif

View File

@@ -17,25 +17,20 @@
*/
//==============================================================================
#ifndef RIPPLE_RPC_NFTOKENID_H_INCLUDED
#define RIPPLE_RPC_NFTOKENID_H_INCLUDED
#ifndef RIPPLE_PROTOCOL_NFTOKENID_H_INCLUDED
#define RIPPLE_PROTOCOL_NFTOKENID_H_INCLUDED
#include <ripple/protocol/Protocol.h>
#include <ripple/basics/base_uint.h>
#include <ripple/json/json_forwards.h>
#include <ripple/protocol/STTx.h>
#include <ripple/protocol/TxMeta.h>
#include <functional>
#include <memory>
namespace Json {
class Value;
}
#include <optional>
#include <vector>
namespace ripple {
class TxMeta;
class STTx;
namespace RPC {
/**
Add a `nftoken_ids` field to the `meta` output parameter.
The field is only added to successful NFTokenMint, NFTokenAcceptOffer,
@@ -62,7 +57,6 @@ insertNFTokenID(
TxMeta const& transactionMeta);
/** @} */
} // namespace RPC
} // namespace ripple
#endif

View File

@@ -17,25 +17,19 @@
*/
//==============================================================================
#ifndef RIPPLE_RPC_NFTOKENOFFERID_H_INCLUDED
#define RIPPLE_RPC_NFTOKENOFFERID_H_INCLUDED
#ifndef RIPPLE_PROTOCOL_NFTOKENOFFERID_H_INCLUDED
#define RIPPLE_PROTOCOL_NFTOKENOFFERID_H_INCLUDED
#include <ripple/protocol/Protocol.h>
#include <ripple/basics/base_uint.h>
#include <ripple/json/json_forwards.h>
#include <ripple/protocol/STTx.h>
#include <ripple/protocol/TxMeta.h>
#include <functional>
#include <memory>
namespace Json {
class Value;
}
#include <optional>
namespace ripple {
class TxMeta;
class STTx;
namespace RPC {
/**
Add an `offer_id` field to the `meta` output parameter.
The field is only added to successful NFTokenCreateOffer transactions.
@@ -58,7 +52,6 @@ insertNFTokenOfferID(
TxMeta const& transactionMeta);
/** @} */
} // namespace RPC
} // namespace ripple
#endif

View File

@@ -26,6 +26,7 @@
#include <ripple/basics/base_uint.h>
#include <ripple/basics/contract.h>
#include <ripple/basics/safe_cast.h>
#include <ripple/basics/strHex.h>
#include <ripple/protocol/HashPrefix.h>
#include <ripple/protocol/SField.h>
#include <cassert>

View File

@@ -0,0 +1,71 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2023 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <ripple/protocol/LedgerHeader.h>
namespace ripple {
void
addRaw(LedgerHeader const& info, Serializer& s, bool includeHash)
{
s.add32(info.seq);
s.add64(info.drops.drops());
s.addBitString(info.parentHash);
s.addBitString(info.txHash);
s.addBitString(info.accountHash);
s.add32(info.parentCloseTime.time_since_epoch().count());
s.add32(info.closeTime.time_since_epoch().count());
s.add8(info.closeTimeResolution.count());
s.add8(info.closeFlags);
if (includeHash)
s.addBitString(info.hash);
}
LedgerHeader
deserializeHeader(Slice data, bool hasHash)
{
SerialIter sit(data.data(), data.size());
LedgerHeader header;
header.seq = sit.get32();
header.drops = sit.get64();
header.parentHash = sit.get256();
header.txHash = sit.get256();
header.accountHash = sit.get256();
header.parentCloseTime =
NetClock::time_point{NetClock::duration{sit.get32()}};
header.closeTime = NetClock::time_point{NetClock::duration{sit.get32()}};
header.closeTimeResolution = NetClock::duration{sit.get8()};
header.closeFlags = sit.get8();
if (hasHash)
header.hash = sit.get256();
return header;
}
LedgerHeader
deserializePrefixedHeader(Slice data, bool hasHash)
{
return deserializeHeader(data + 4, hasHash);
}
} // namespace ripple

View File

@@ -17,28 +17,16 @@
*/
//==============================================================================
#include <ripple/rpc/NFTSyntheticSerializer.h>
#include <ripple/app/ledger/LedgerMaster.h>
#include <ripple/app/ledger/OpenLedger.h>
#include <ripple/app/misc/Transaction.h>
#include <ripple/ledger/View.h>
#include <ripple/net/RPCErr.h>
#include <ripple/protocol/AccountID.h>
#include <ripple/protocol/Feature.h>
#include <ripple/rpc/Context.h>
#include <ripple/rpc/NFTokenID.h>
#include <ripple/rpc/NFTokenOfferID.h>
#include <ripple/rpc/impl/RPCHelpers.h>
#include <boost/algorithm/string/case_conv.hpp>
#include <ripple/protocol/NFTSyntheticSerializer.h>
#include <ripple/protocol/NFTokenID.h>
#include <ripple/protocol/NFTokenOfferID.h>
#include <ripple/protocol/jss.h>
namespace ripple {
namespace RPC {
void
insertNFTSyntheticInJson(
Json::Value& response,
RPC::JsonContext const& context,
std::shared_ptr<STTx const> const& transaction,
TxMeta const& transactionMeta)
{
@@ -46,5 +34,4 @@ insertNFTSyntheticInJson(
insertNFTokenOfferID(response[jss::meta], transaction, transactionMeta);
}
} // namespace RPC
} // namespace ripple

View File

@@ -17,21 +17,10 @@
*/
//==============================================================================
#include <ripple/rpc/NFTokenID.h>
#include <ripple/app/ledger/LedgerMaster.h>
#include <ripple/app/ledger/OpenLedger.h>
#include <ripple/app/misc/Transaction.h>
#include <ripple/ledger/View.h>
#include <ripple/net/RPCErr.h>
#include <ripple/protocol/AccountID.h>
#include <ripple/protocol/Feature.h>
#include <ripple/rpc/Context.h>
#include <ripple/rpc/impl/RPCHelpers.h>
#include <boost/algorithm/string/case_conv.hpp>
#include <ripple/protocol/NFTokenID.h>
#include <ripple/protocol/jss.h>
namespace ripple {
namespace RPC {
bool
canHaveNFTokenID(
@@ -198,5 +187,4 @@ insertNFTokenID(
}
}
} // namespace RPC
} // namespace ripple

View File

@@ -17,21 +17,10 @@
*/
//==============================================================================
#include <ripple/rpc/NFTokenOfferID.h>
#include <ripple/app/ledger/LedgerMaster.h>
#include <ripple/app/ledger/OpenLedger.h>
#include <ripple/app/misc/Transaction.h>
#include <ripple/ledger/View.h>
#include <ripple/net/RPCErr.h>
#include <ripple/protocol/AccountID.h>
#include <ripple/protocol/Feature.h>
#include <ripple/rpc/Context.h>
#include <ripple/rpc/impl/RPCHelpers.h>
#include <boost/algorithm/string/case_conv.hpp>
#include <ripple/protocol/NFTokenOfferID.h>
#include <ripple/protocol/jss.h>
namespace ripple {
namespace RPC {
bool
canHaveNFTokenOfferID(
@@ -81,5 +70,4 @@ insertNFTokenOfferID(
response[jss::offer_id] = to_string(result.value());
}
} // namespace RPC
} // namespace ripple

View File

@@ -31,6 +31,6 @@
#undef TYPE_BOOL
#endif
#include "ripple.pb.h"
#include <ripple/proto/ripple.pb.h>
#endif

127
src/ripple/protocol/nft.h Normal file
View File

@@ -0,0 +1,127 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2023 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_PROTOCOL_NFT_H_INCLUDED
#define RIPPLE_PROTOCOL_NFT_H_INCLUDED
#include <ripple/basics/base_uint.h>
#include <ripple/basics/tagged_integer.h>
#include <ripple/protocol/AccountID.h>
#include <boost/endian/conversion.hpp>
#include <cstdint>
#include <cstring>
namespace ripple {
namespace nft {
// Separate taxons from regular integers.
struct TaxonTag
{
};
using Taxon = tagged_integer<std::uint32_t, TaxonTag>;
inline Taxon
toTaxon(std::uint32_t i)
{
return static_cast<Taxon>(i);
}
inline std::uint32_t
toUInt32(Taxon t)
{
return static_cast<std::uint32_t>(t);
}
constexpr std::uint16_t const flagBurnable = 0x0001;
constexpr std::uint16_t const flagOnlyXRP = 0x0002;
constexpr std::uint16_t const flagCreateTrustLines = 0x0004;
constexpr std::uint16_t const flagTransferable = 0x0008;
inline std::uint16_t
getFlags(uint256 const& id)
{
std::uint16_t flags;
memcpy(&flags, id.begin(), 2);
return boost::endian::big_to_native(flags);
}
inline std::uint16_t
getTransferFee(uint256 const& id)
{
std::uint16_t fee;
memcpy(&fee, id.begin() + 2, 2);
return boost::endian::big_to_native(fee);
}
inline std::uint32_t
getSerial(uint256 const& id)
{
std::uint32_t seq;
memcpy(&seq, id.begin() + 28, 4);
return boost::endian::big_to_native(seq);
}
inline Taxon
cipheredTaxon(std::uint32_t tokenSeq, Taxon taxon)
{
// An issuer may issue several NFTs with the same taxon; to ensure that NFTs
// are spread across multiple pages we lightly mix the taxon up by using the
// sequence (which is not under the issuer's direct control) as the seed for
// a simple linear congruential generator.
//
// From the Hull-Dobell theorem we know that f(x)=(m*x+c) mod n will yield a
// permutation of [0, n) when n is a power of 2 if m is congruent to 1 mod 4
// and c is odd.
//
// Here we use m = 384160001 and c = 2459. The modulo is implicit because we
// use 2^32 for n and the arithmetic gives it to us for "free".
//
// Note that the scramble value we calculate is not cryptographically secure
// but that's fine since all we're looking for is some dispersion.
//
// **IMPORTANT** Changing these numbers would be a breaking change requiring
// an amendment along with a way to distinguish token IDs that
// were generated with the old code.
return taxon ^ toTaxon(((384160001 * tokenSeq) + 2459));
}
inline Taxon
getTaxon(uint256 const& id)
{
std::uint32_t taxon;
memcpy(&taxon, id.begin() + 24, 4);
taxon = boost::endian::big_to_native(taxon);
// The taxon cipher is just an XOR, so it is reversible by applying the
// XOR a second time.
return cipheredTaxon(getSerial(id), toTaxon(taxon));
}
inline AccountID
getIssuer(uint256 const& id)
{
return AccountID::fromVoid(id.data() + 4);
}
} // namespace nft
} // namespace ripple
#endif

View File

@@ -0,0 +1,48 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2023 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_PROTOCOL_SERIALIZE_H_INCLUDED
#define RIPPLE_PROTOCOL_SERIALIZE_H_INCLUDED
#include <ripple/basics/strHex.h>
#include <ripple/protocol/STObject.h>
#include <ripple/protocol/Serializer.h>
namespace ripple {
/** Serialize an object to a blob. */
template <class Object>
Blob
serializeBlob(Object const& o)
{
Serializer s;
o.add(s);
return s.peekData();
}
/** Serialize an object to a hex string. */
inline std::string
serializeHex(STObject const& o)
{
return strHex(serializeBlob(o));
}
} // namespace ripple
#endif

View File

@@ -20,9 +20,9 @@
#ifndef RIPPLE_RPC_GRPCHANDLER_H_INCLUDED
#define RIPPLE_RPC_GRPCHANDLER_H_INCLUDED
#include <ripple/proto/org/xrpl/rpc/v1/xrp_ledger.pb.h>
#include <ripple/rpc/Context.h>
#include <grpcpp/grpcpp.h>
#include <org/xrpl/rpc/v1/xrp_ledger.pb.h>
namespace ripple {

View File

@@ -29,12 +29,12 @@
#include <ripple/ledger/ReadView.h>
#include <ripple/net/RPCErr.h>
#include <ripple/protocol/ErrorCodes.h>
#include <ripple/protocol/NFTSyntheticSerializer.h>
#include <ripple/protocol/UintTypes.h>
#include <ripple/protocol/jss.h>
#include <ripple/resource/Fees.h>
#include <ripple/rpc/Context.h>
#include <ripple/rpc/DeliveredAmount.h>
#include <ripple/rpc/NFTSyntheticSerializer.h>
#include <ripple/rpc/Role.h>
#include <ripple/rpc/impl/RPCHelpers.h>
@@ -334,7 +334,7 @@ populateJsonResponse(
insertDeliveredAmount(
jvObj[jss::meta], context, txn, *txnMeta);
insertNFTSyntheticInJson(
jvObj, context, txn->getSTransaction(), *txnMeta);
jvObj, txn->getSTransaction(), *txnMeta);
}
}
}

View File

@@ -24,12 +24,12 @@
#include <ripple/basics/ToString.h>
#include <ripple/net/RPCErr.h>
#include <ripple/protocol/ErrorCodes.h>
#include <ripple/protocol/NFTSyntheticSerializer.h>
#include <ripple/protocol/jss.h>
#include <ripple/rpc/CTID.h>
#include <ripple/rpc/Context.h>
#include <ripple/rpc/DeliveredAmount.h>
#include <ripple/rpc/GRPCHandlers.h>
#include <ripple/rpc/NFTSyntheticSerializer.h>
#include <ripple/rpc/impl/RPCHelpers.h>
#include <charconv>
#include <regex>
@@ -328,7 +328,7 @@ populateJsonResponse(
insertDeliveredAmount(
response[jss::meta], context, result.txn, *meta);
insertNFTSyntheticInJson(
response, context, result.txn->getSTransaction(), *meta);
response, result.txn->getSTransaction(), *meta);
}
}
response[jss::validated] = result.validated;

View File

@@ -21,6 +21,7 @@
#define RIPPLE_RPC_RPCHELPERS_H_INCLUDED
#include <ripple/beast/core/SemanticVersion.h>
#include <ripple/proto/org/xrpl/rpc/v1/xrp_ledger.pb.h>
#include <ripple/protocol/TxMeta.h>
#include <ripple/app/misc/NetworkOPs.h>
@@ -30,7 +31,6 @@
#include <ripple/rpc/Status.h>
#include <ripple/rpc/impl/Tuning.h>
#include <optional>
#include <org/xrpl/rpc/v1/xrp_ledger.pb.h>
#include <variant>
namespace Json {

View File

@@ -34,12 +34,12 @@
#include <ripple/protocol/Sign.h>
#include <ripple/protocol/digest.h>
#include <ripple/protocol/jss.h>
#include <ripple/protocol/messages.h>
#include <ripple/shamap/SHAMapNodeID.h>
#include <boost/asio/ip/address_v4.hpp>
#include <boost/beast/core/multi_buffer.hpp>
#include <boost/endian/conversion.hpp>
#include <algorithm>
#include <ripple.pb.h>
#include <test/jtx/Account.h>
#include <test/jtx/Env.h>
#include <test/jtx/WSClient.h>

View File

@@ -23,7 +23,7 @@
#include <ripple/overlay/Slot.h>
#include <ripple/overlay/impl/Handshake.h>
#include <ripple/protocol/SecretKey.h>
#include <ripple.pb.h>
#include <ripple/protocol/messages.h>
#include <test/jtx/Env.h>
#include <boost/thread.hpp>
@@ -1597,4 +1597,4 @@ BEAST_DEFINE_TESTSUITE_MANUAL(reduce_relay_simulate, ripple_data, ripple);
} // namespace test
} // namespace ripple
} // namespace ripple