rippled
compression_test.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright 2020 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #include <ripple/app/ledger/Ledger.h>
21 #include <ripple/app/ledger/LedgerMaster.h>
22 #include <ripple/app/misc/Manifest.h>
23 #include <ripple/beast/unit_test.h>
24 #include <ripple/beast/utility/Journal.h>
25 #include <ripple/core/TimeKeeper.h>
26 #include <ripple/overlay/Compression.h>
27 #include <ripple/overlay/Message.h>
28 #include <ripple/overlay/impl/ProtocolMessage.h>
29 #include <ripple/overlay/impl/ZeroCopyStream.h>
30 #include <ripple/protocol/HashPrefix.h>
31 #include <ripple/protocol/PublicKey.h>
32 #include <ripple/protocol/SecretKey.h>
33 #include <ripple/protocol/Sign.h>
34 #include <ripple/protocol/digest.h>
35 #include <ripple/protocol/jss.h>
36 #include <ripple/shamap/SHAMapNodeID.h>
37 #include <boost/asio/ip/address_v4.hpp>
38 #include <boost/beast/core/multi_buffer.hpp>
39 #include <boost/endian/conversion.hpp>
40 #include <algorithm>
41 #include <ripple.pb.h>
42 #include <test/jtx/Account.h>
43 #include <test/jtx/Env.h>
44 #include <test/jtx/WSClient.h>
45 #include <test/jtx/amount.h>
46 #include <test/jtx/pay.h>
47 
48 namespace ripple {
49 
50 namespace test {
51 
52 using namespace ripple::test;
53 using namespace ripple::test::jtx;
54 
55 static uint256
56 ledgerHash(LedgerInfo const& info)
57 {
58  return ripple::sha512Half(
60  std::uint32_t(info.seq),
61  std::uint64_t(info.drops.drops()),
62  info.parentHash,
63  info.txHash,
64  info.accountHash,
68  std::uint8_t(info.closeFlags));
69 }
70 
71 class compression_test : public beast::unit_test::suite
72 {
75 
76 public:
78  {
79  }
80 
81  template <typename T>
82  void
84  std::shared_ptr<T> proto,
85  protocol::MessageType mt,
86  uint16_t nbuffers,
87  std::string msg)
88  {
89  testcase("Compress/Decompress: " + msg);
90 
91  Message m(*proto, mt);
92 
93  auto& buffer = m.getBuffer(Compressed::On);
94 
95  boost::beast::multi_buffer buffers;
96 
97  // simulate multi-buffer
98  auto sz = buffer.size() / nbuffers;
99  for (int i = 0; i < nbuffers; i++)
100  {
101  auto start = buffer.begin() + sz * i;
102  auto end = i < nbuffers - 1 ? (buffer.begin() + sz * (i + 1))
103  : buffer.end();
104  std::vector<std::uint8_t> slice(start, end);
105  buffers.commit(boost::asio::buffer_copy(
106  buffers.prepare(slice.size()), boost::asio::buffer(slice)));
107  }
108 
109  boost::system::error_code ec;
111  ec, buffers.data(), buffer.size());
112 
113  BEAST_EXPECT(header);
114 
115  if (header->algorithm == Algorithm::None)
116  return;
117 
118  std::vector<std::uint8_t> decompressed;
119  decompressed.resize(header->uncompressed_size);
120 
121  BEAST_EXPECT(
122  header->payload_wire_size == buffer.size() - header->header_size);
123 
124  ZeroCopyInputStream stream(buffers.data());
125  stream.Skip(header->header_size);
126 
127  auto decompressedSize = ripple::compression::decompress(
128  stream,
129  header->payload_wire_size,
130  decompressed.data(),
131  header->uncompressed_size);
132  BEAST_EXPECT(decompressedSize == header->uncompressed_size);
133  auto const proto1 = std::make_shared<T>();
134 
135  BEAST_EXPECT(
136  proto1->ParseFromArray(decompressed.data(), decompressedSize));
137  auto uncompressed = m.getBuffer(Compressed::Off);
138  BEAST_EXPECT(std::equal(
139  uncompressed.begin() + ripple::compression::headerBytes,
140  uncompressed.end(),
141  decompressed.begin()));
142  }
143 
146  {
147  auto manifests = std::make_shared<protocol::TMManifests>();
148  manifests->mutable_list()->Reserve(n);
149  for (int i = 0; i < n; i++)
150  {
151  auto master = randomKeyPair(KeyType::ed25519);
152  auto signing = randomKeyPair(KeyType::ed25519);
153  STObject st(sfGeneric);
154  st[sfSequence] = i;
155  st[sfPublicKey] = std::get<0>(master);
156  st[sfSigningPubKey] = std::get<0>(signing);
157  st[sfDomain] = makeSlice(
158  std::string("example") + std::to_string(i) +
159  std::string(".com"));
160  sign(
161  st,
164  std::get<1>(master),
166  sign(
167  st,
170  std::get<1>(signing));
171  Serializer s;
172  st.add(s);
173  auto* manifest = manifests->add_list();
174  manifest->set_stobject(s.data(), s.size());
175  }
176  return manifests;
177  }
178 
181  {
182  auto endpoints = std::make_shared<protocol::TMEndpoints>();
183  endpoints->mutable_endpoints_v2()->Reserve(n);
184  for (int i = 0; i < n; i++)
185  {
186  auto ep = endpoints->add_endpoints_v2();
187  ep->set_endpoint(std::string("10.0.1.") + std::to_string(i));
188  ep->set_hops(i);
189  }
190  endpoints->set_version(2);
191 
192  return endpoints;
193  }
194 
197  {
198  Env env(*this, envconfig());
199  int fund = 10000;
200  auto const alice = Account("alice");
201  auto const bob = Account("bob");
202  env.fund(XRP(fund), "alice", "bob");
203  env.trust(bob["USD"](fund), alice);
204  env.close();
205 
206  auto toBinary = [this](std::string const& text) {
207  auto blob = strUnHex(text);
208  BEAST_EXPECT(blob);
209  return std::string{
210  reinterpret_cast<char const*>(blob->data()), blob->size()};
211  };
212 
213  std::string usdTxBlob = "";
214  auto wsc = makeWSClient(env.app().config());
215  {
216  Json::Value jrequestUsd;
217  jrequestUsd[jss::secret] = toBase58(generateSeed("bob"));
218  jrequestUsd[jss::tx_json] =
219  pay("bob", "alice", bob["USD"](fund / 2));
220  Json::Value jreply_usd = wsc->invoke("sign", jrequestUsd);
221 
222  usdTxBlob =
223  toBinary(jreply_usd[jss::result][jss::tx_blob].asString());
224  }
225 
226  auto transaction = std::make_shared<protocol::TMTransaction>();
227  transaction->set_rawtransaction(usdTxBlob);
228  transaction->set_status(protocol::tsNEW);
229  auto tk = make_TimeKeeper(logs.journal("TimeKeeper"));
230  transaction->set_receivetimestamp(tk->now().time_since_epoch().count());
231  transaction->set_deferred(true);
232 
233  return transaction;
234  }
235 
238  {
239  auto getLedger = std::make_shared<protocol::TMGetLedger>();
240  getLedger->set_itype(protocol::liTS_CANDIDATE);
241  getLedger->set_ltype(protocol::TMLedgerType::ltACCEPTED);
242  uint256 const hash(ripple::sha512Half(123456789));
243  getLedger->set_ledgerhash(hash.begin(), hash.size());
244  getLedger->set_ledgerseq(123456789);
245  ripple::SHAMapNodeID sha(17, hash);
246  getLedger->add_nodeids(sha.getRawString());
247  getLedger->set_requestcookie(123456789);
248  getLedger->set_querytype(protocol::qtINDIRECT);
249  getLedger->set_querydepth(3);
250  return getLedger;
251  }
252 
254  buildLedgerData(uint32_t n, Logs& logs)
255  {
256  auto ledgerData = std::make_shared<protocol::TMLedgerData>();
257  uint256 const hash(ripple::sha512Half(12356789));
258  ledgerData->set_ledgerhash(hash.data(), hash.size());
259  ledgerData->set_ledgerseq(123456789);
260  ledgerData->set_type(protocol::TMLedgerInfoType::liAS_NODE);
261  ledgerData->set_requestcookie(123456789);
262  ledgerData->set_error(protocol::TMReplyError::reNO_LEDGER);
263  ledgerData->mutable_nodes()->Reserve(n);
264  uint256 parentHash(0);
265  for (int i = 0; i < n; i++)
266  {
267  LedgerInfo info;
268  auto tk = make_TimeKeeper(logs.journal("TimeKeeper"));
269  info.seq = i;
270  info.parentCloseTime = tk->now();
271  info.hash = ripple::sha512Half(i);
272  info.txHash = ripple::sha512Half(i + 1);
273  info.accountHash = ripple::sha512Half(i + 2);
274  info.parentHash = parentHash;
275  info.drops = XRPAmount(10);
276  info.closeTimeResolution = tk->now().time_since_epoch();
277  info.closeTime = tk->now();
278  parentHash = ledgerHash(info);
279  Serializer nData;
280  ripple::addRaw(info, nData);
281  ledgerData->add_nodes()->set_nodedata(
282  nData.getDataPtr(), nData.getLength());
283  }
284 
285  return ledgerData;
286  }
287 
290  {
291  auto getObject = std::make_shared<protocol::TMGetObjectByHash>();
292 
293  getObject->set_type(protocol::TMGetObjectByHash_ObjectType::
294  TMGetObjectByHash_ObjectType_otTRANSACTION);
295  getObject->set_query(true);
296  getObject->set_seq(123456789);
297  uint256 hash(ripple::sha512Half(123456789));
298  getObject->set_ledgerhash(hash.data(), hash.size());
299  getObject->set_fat(true);
300  for (int i = 0; i < 100; i++)
301  {
302  uint256 hash(ripple::sha512Half(i));
303  auto object = getObject->add_objects();
304  object->set_hash(hash.data(), hash.size());
305  ripple::SHAMapNodeID sha(i % 55, hash);
306  object->set_nodeid(sha.getRawString());
307  object->set_index("");
308  object->set_data("");
309  object->set_ledgerseq(i);
310  }
311  return getObject;
312  }
313 
316  {
317  auto list = std::make_shared<protocol::TMValidatorList>();
318 
319  auto master = randomKeyPair(KeyType::ed25519);
320  auto signing = randomKeyPair(KeyType::ed25519);
321  STObject st(sfGeneric);
322  st[sfSequence] = 0;
323  st[sfPublicKey] = std::get<0>(master);
324  st[sfSigningPubKey] = std::get<0>(signing);
325  st[sfDomain] = makeSlice(std::string("example.com"));
326  sign(
327  st,
330  std::get<1>(master),
332  sign(st, HashPrefix::manifest, KeyType::ed25519, std::get<1>(signing));
333  Serializer s;
334  st.add(s);
335  list->set_manifest(s.data(), s.size());
336  list->set_version(3);
337  STObject signature(sfSignature);
338  ripple::sign(
339  st, HashPrefix::manifest, KeyType::ed25519, std::get<1>(signing));
340  Serializer s1;
341  st.add(s1);
342  list->set_signature(s1.data(), s1.size());
343  list->set_blob(strHex(s.getString()));
344  return list;
345  }
346 
347  void
349  {
350  testcase("Message Compression");
351 
352  auto thresh = beast::severities::Severity::kInfo;
353  auto logs = std::make_unique<Logs>(thresh);
354 
355  protocol::TMManifests manifests;
356  protocol::TMEndpoints endpoints;
357  protocol::TMTransaction transaction;
358  protocol::TMGetLedger get_ledger;
359  protocol::TMLedgerData ledger_data;
360  protocol::TMGetObjectByHash get_object;
361  protocol::TMValidatorList validator_list;
362 
363  // 4.5KB
364  doTest(buildManifests(20), protocol::mtMANIFESTS, 4, "TMManifests20");
365  // 22KB
366  doTest(buildManifests(100), protocol::mtMANIFESTS, 4, "TMManifests100");
367  // 131B
368  doTest(buildEndpoints(10), protocol::mtENDPOINTS, 4, "TMEndpoints10");
369  // 1.3KB
370  doTest(buildEndpoints(100), protocol::mtENDPOINTS, 4, "TMEndpoints100");
371  // 242B
372  doTest(
373  buildTransaction(*logs),
374  protocol::mtTRANSACTION,
375  1,
376  "TMTransaction");
377  // 87B
378  doTest(buildGetLedger(), protocol::mtGET_LEDGER, 1, "TMGetLedger");
379  // 61KB
380  doTest(
381  buildLedgerData(500, *logs),
382  protocol::mtLEDGER_DATA,
383  10,
384  "TMLedgerData500");
385  // 122 KB
386  doTest(
387  buildLedgerData(1000, *logs),
388  protocol::mtLEDGER_DATA,
389  20,
390  "TMLedgerData1000");
391  // 1.2MB
392  doTest(
393  buildLedgerData(10000, *logs),
394  protocol::mtLEDGER_DATA,
395  50,
396  "TMLedgerData10000");
397  // 12MB
398  doTest(
399  buildLedgerData(100000, *logs),
400  protocol::mtLEDGER_DATA,
401  100,
402  "TMLedgerData100000");
403  // 61MB
404  doTest(
405  buildLedgerData(500000, *logs),
406  protocol::mtLEDGER_DATA,
407  100,
408  "TMLedgerData500000");
409  // 7.7KB
410  doTest(
411  buildGetObjectByHash(),
412  protocol::mtGET_OBJECTS,
413  4,
414  "TMGetObjectByHash");
415  // 895B
416  doTest(
417  buildValidatorList(),
418  protocol::mtVALIDATORLIST,
419  4,
420  "TMValidatorList");
421  }
422 
423  void
424  run() override
425  {
426  testProtocol();
427  }
428 };
429 
430 BEAST_DEFINE_TESTSUITE_MANUAL_PRIO(compression, ripple_data, ripple, 20);
431 
432 } // namespace test
433 } // namespace ripple
ripple::test::ledgerHash
static uint256 ledgerHash(LedgerInfo const &info)
Definition: compression_test.cpp:56
std::vector::resize
T resize(T... args)
ripple::HashPrefix::ledgerMaster
@ ledgerMaster
ledger master data for signing
ripple::test::jtx::XRP
const XRP_t XRP
Converts to XRP Issue or STAmount.
Definition: amount.cpp:105
ripple::Message::getBuffer
std::vector< uint8_t > const & getBuffer(Compressed tryCompressed)
Retrieve the packed message data.
Definition: Message.cpp:187
ripple::makeSlice
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)
Definition: Slice.h:240
std::string
STL class.
std::equal
T equal(T... args)
std::shared_ptr
STL class.
ripple::LedgerInfo::parentHash
uint256 parentHash
Definition: ReadView.h:103
ripple::test::compression_test::doTest
void doTest(std::shared_ptr< T > proto, protocol::MessageType mt, uint16_t nbuffers, std::string msg)
Definition: compression_test.cpp:83
ripple::Logs
Manages partitions for logging.
Definition: Log.h:48
ripple::test::compression_test::buildEndpoints
std::shared_ptr< protocol::TMEndpoints > buildEndpoints(int n)
Definition: compression_test.cpp:180
ripple::sfGeneric
const SField sfGeneric(access, 0)
Definition: SField.h:332
ripple::test::compression_test::testProtocol
void testProtocol()
Definition: compression_test.cpp:348
ripple::test::compression_test::buildLedgerData
std::shared_ptr< protocol::TMLedgerData > buildLedgerData(uint32_t n, Logs &logs)
Definition: compression_test.cpp:254
ripple::LedgerInfo::hash
uint256 hash
Definition: ReadView.h:100
ripple::XRPAmount::drops
constexpr value_type drops() const
Returns the number of drops.
Definition: XRPAmount.h:172
ripple::sfSequence
const SF_UINT32 sfSequence
ripple::HashPrefix::manifest
@ manifest
Manifest.
std::vector
STL class.
std::vector::size
T size(T... args)
ripple::Serializer::getString
std::string getString() const
Definition: Serializer.h:202
ripple::compression::headerBytes
constexpr std::size_t headerBytes
Definition: Compression.h:31
ripple::sfSigningPubKey
const SF_VL sfSigningPubKey
ripple::toBase58
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition: AccountID.cpp:29
ripple::test::compression_test::buildValidatorList
std::shared_ptr< protocol::TMValidatorList > buildValidatorList()
Definition: compression_test.cpp:315
ripple::test::compression_test::compression_test
compression_test()
Definition: compression_test.cpp:77
ripple::strUnHex
boost::optional< Blob > strUnHex(std::size_t strSize, Iterator begin, Iterator end)
Definition: StringUtilities.h:49
ripple::addRaw
void addRaw(LedgerInfo const &info, Serializer &s)
Definition: View.cpp:43
ripple::ZeroCopyInputStream
Implements ZeroCopyInputStream around a buffer sequence.
Definition: ZeroCopyStream.h:35
ripple::test::jtx::Env::app
Application & app()
Definition: Env.h:240
ripple::LedgerInfo::seq
LedgerIndex seq
Definition: ReadView.h:92
ripple::test::compression_test::buildGetObjectByHash
std::shared_ptr< protocol::TMGetObjectByHash > buildGetObjectByHash()
Definition: compression_test.cpp:289
ripple::SHAMapNodeID
Identifies a node inside a SHAMap.
Definition: SHAMapNodeID.h:33
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:49
ripple::test::jtx::sign
void sign(Json::Value &jv, Account const &account)
Sign automatically.
Definition: utility.cpp:44
ripple::test::compression_test
Definition: compression_test.cpp:71
ripple::LedgerInfo::txHash
uint256 txHash
Definition: ReadView.h:101
ripple::base_uint::data
pointer data()
Definition: base_uint.h:113
ripple::test::jtx::Env::trust
void trust(STAmount const &amount, Account const &account)
Establish trust lines.
Definition: Env.cpp:250
algorithm
ripple::base_uint::size
constexpr static std::size_t size()
Definition: base_uint.h:426
ripple::Serializer::data
void const * data() const noexcept
Definition: Serializer.h:75
ripple::uint256
base_uint< 256 > uint256
Definition: base_uint.h:457
ripple::LedgerInfo::closeTime
NetClock::time_point closeTime
Definition: ReadView.h:123
ripple::KeyType::ed25519
@ ed25519
ripple::base_uint< 256 >
ripple::test::compression_test::run
void run() override
Definition: compression_test.cpp:424
std::chrono::time_point::time_since_epoch
T time_since_epoch(T... args)
ripple::test::BEAST_DEFINE_TESTSUITE_MANUAL_PRIO
BEAST_DEFINE_TESTSUITE_MANUAL_PRIO(CrossingLimits, tx, ripple, 10)
ripple::Serializer::getDataPtr
const void * getDataPtr() const
Definition: Serializer.h:187
ripple::sfMasterSignature
const SF_VL sfMasterSignature
ripple::Application::config
virtual Config & config()=0
ripple::detail::parseMessageHeader
boost::optional< MessageHeader > parseMessageHeader(boost::system::error_code &ec, BufferSequence const &bufs, std::size_t size)
Parse a message header.
Definition: ProtocolMessage.h:134
ripple::SHAMapNodeID::getRawString
std::string getRawString() const
Definition: SHAMapNodeID.cpp:65
ripple::LedgerInfo::closeFlags
int closeFlags
Definition: ReadView.h:114
std::to_string
T to_string(T... args)
ripple::compression::Compressed
Compressed
Definition: Compression.h:38
std::uint32_t
ripple::compression::Algorithm
Algorithm
Definition: Compression.h:36
ripple::test::compression_test::buildTransaction
std::shared_ptr< protocol::TMTransaction > buildTransaction(Logs &logs)
Definition: compression_test.cpp:196
ripple::LedgerInfo::drops
XRPAmount drops
Definition: ReadView.h:105
ripple::Serializer
Definition: Serializer.h:39
ripple::Message
Definition: overlay/Message.h:50
ripple::randomKeyPair
std::pair< PublicKey, SecretKey > randomKeyPair(KeyType type)
Create a key pair using secure random numbers.
Definition: SecretKey.cpp:260
ripple::generateSeed
Seed generateSeed(std::string const &passPhrase)
Generate a seed deterministically.
Definition: Seed.cpp:69
ripple::test::compression_test::buildGetLedger
std::shared_ptr< protocol::TMGetLedger > buildGetLedger()
Definition: compression_test.cpp:237
ripple::STObject
Definition: STObject.h:51
ripple::compression::decompress
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.
Definition: Compression.h:50
ripple::test::jtx
Definition: Check_test.cpp:26
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::test
Definition: NegativeUNLVote.h:38
ripple::Serializer::size
std::size_t size() const noexcept
Definition: Serializer.h:69
ripple::Logs::journal
beast::Journal journal(std::string const &name)
Definition: Log.cpp:144
ripple::STObject::add
virtual void add(Serializer &s) const override
Definition: STObject.h:352
ripple::base_uint::begin
iterator begin()
Definition: base_uint.h:124
ripple::test::jtx::pay
Json::Value pay(Account const &account, Account const &to, AnyAmount amount)
Create a payment.
Definition: pay.cpp:29
ripple::sign
Buffer sign(PublicKey const &pk, SecretKey const &sk, Slice const &m)
Generate a signature for a message.
Definition: SecretKey.cpp:124
ripple::test::jtx::Env::close
bool close(NetClock::time_point closeTime, boost::optional< std::chrono::milliseconds > consensusDelay=boost::none)
Close and advance the ledger.
Definition: Env.cpp:121
std::vector::begin
T begin(T... args)
ripple::LedgerInfo::closeTimeResolution
NetClock::duration closeTimeResolution
Definition: ReadView.h:117
ripple::sha512Half
sha512_half_hasher::result_type sha512Half(Args const &... args)
Returns the SHA512-Half of a series of objects.
Definition: digest.h:216
ripple::test::jtx::Env::fund
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition: Env.cpp:219
ripple::make_TimeKeeper
std::unique_ptr< TimeKeeper > make_TimeKeeper(beast::Journal j)
Definition: TimeKeeper.cpp:119
ripple::sfSignature
const SF_VL sfSignature
std::chrono::duration::count
T count(T... args)
ripple::test::compression_test::buildManifests
std::shared_ptr< protocol::TMManifests > buildManifests(int n)
Definition: compression_test.cpp:145
ripple::test::makeWSClient
std::unique_ptr< WSClient > makeWSClient(Config const &cfg, bool v2, unsigned rpc_version, std::unordered_map< std::string, std::string > const &headers)
Returns a client operating through WebSockets/S.
Definition: WSClient.cpp:300
ripple::test::jtx::Account
Immutable cryptographic account descriptor.
Definition: Account.h:37
ripple::LedgerInfo
Information about the notional ledger backing the view.
Definition: ReadView.h:84
ripple::strHex
std::string strHex(FwdIt begin, FwdIt end)
Definition: strHex.h:45
ripple::Serializer::getLength
int getLength() const
Definition: Serializer.h:197
ripple::sfDomain
const SF_VL sfDomain
std::vector::data
T data(T... args)
ripple::sfPublicKey
const SF_VL sfPublicKey
ripple::LedgerInfo::accountHash
uint256 accountHash
Definition: ReadView.h:102
ripple::test::jtx::Env
A transaction testing environment.
Definition: Env.h:115
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::XRPAmount
Definition: XRPAmount.h:46
ripple::LedgerInfo::parentCloseTime
NetClock::time_point parentCloseTime
Definition: ReadView.h:93