1#include <xrpl/shamap/SHAMap.h>
3#include <xrpl/basics/Blob.h>
4#include <xrpl/basics/Buffer.h>
5#include <xrpl/basics/SHAMapHash.h>
6#include <xrpl/basics/base_uint.h>
7#include <xrpl/beast/utility/Journal.h>
8#include <xrpl/beast/utility/Zero.h>
9#include <xrpl/shamap/SHAMapInnerNode.h>
10#include <xrpl/shamap/SHAMapItem.h>
11#include <xrpl/shamap/SHAMapLeafNode.h>
12#include <xrpl/shamap/SHAMapMissingNode.h>
13#include <xrpl/shamap/SHAMapTreeNode.h>
15#include <gtest/gtest.h>
16#include <helpers/TestSink.h>
17#include <shamap/common.h>
31#ifndef __INTELLISENSE__
32static_assert(std::is_nothrow_destructible<SHAMap>{});
33static_assert(!std::is_default_constructible<SHAMap>{});
34static_assert(!std::is_copy_constructible<SHAMap>{});
35static_assert(!std::is_copy_assignable<SHAMap>{});
36static_assert(!std::is_move_constructible<SHAMap>{});
37static_assert(!std::is_move_assignable<SHAMap>{});
39static_assert(std::is_nothrow_destructible<SHAMap::ConstIterator>{});
40static_assert(std::is_copy_constructible<SHAMap::ConstIterator>{});
41static_assert(std::is_copy_assignable<SHAMap::ConstIterator>{});
42static_assert(std::is_move_constructible<SHAMap::ConstIterator>{});
43static_assert(std::is_move_assignable<SHAMap::ConstIterator>{});
45static_assert(std::is_nothrow_destructible<SHAMapItem>{});
46static_assert(!std::is_default_constructible<SHAMapItem>{});
47static_assert(!std::is_copy_constructible<SHAMapItem>{});
49static_assert(std::is_nothrow_destructible<SHAMapNodeID>{});
50static_assert(std::is_default_constructible<SHAMapNodeID>{});
51static_assert(std::is_copy_constructible<SHAMapNodeID>{});
52static_assert(std::is_copy_assignable<SHAMapNodeID>{});
53static_assert(std::is_move_constructible<SHAMapNodeID>{});
54static_assert(std::is_move_assignable<SHAMapNodeID>{});
56static_assert(std::is_nothrow_destructible<SHAMapHash>{});
57static_assert(std::is_default_constructible<SHAMapHash>{});
58static_assert(std::is_copy_constructible<SHAMapHash>{});
59static_assert(std::is_copy_assignable<SHAMapHash>{});
60static_assert(std::is_move_constructible<SHAMapHash>{});
61static_assert(std::is_move_assignable<SHAMapHash>{});
63static_assert(std::is_nothrow_destructible<SHAMapTreeNode>{});
64static_assert(!std::is_default_constructible<SHAMapTreeNode>{});
65static_assert(!std::is_copy_constructible<SHAMapTreeNode>{});
66static_assert(!std::is_copy_assignable<SHAMapTreeNode>{});
67static_assert(!std::is_move_constructible<SHAMapTreeNode>{});
68static_assert(!std::is_move_assignable<SHAMapTreeNode>{});
70static_assert(std::is_nothrow_destructible<SHAMapInnerNode>{});
71static_assert(!std::is_default_constructible<SHAMapInnerNode>{});
72static_assert(!std::is_copy_constructible<SHAMapInnerNode>{});
73static_assert(!std::is_copy_assignable<SHAMapInnerNode>{});
74static_assert(!std::is_move_constructible<SHAMapInnerNode>{});
75static_assert(!std::is_move_assignable<SHAMapInnerNode>{});
77static_assert(std::is_nothrow_destructible<SHAMapLeafNode>{});
78static_assert(!std::is_default_constructible<SHAMapLeafNode>{});
79static_assert(!std::is_copy_constructible<SHAMapLeafNode>{});
80static_assert(!std::is_copy_assignable<SHAMapLeafNode>{});
81static_assert(!std::is_move_constructible<SHAMapLeafNode>{});
82static_assert(!std::is_move_assignable<SHAMapLeafNode>{});
106class SHAMapTest :
public ::testing::TestWithParam<SHAMapBackingMode>
122 auto const testMode = GetParam();
126 constexpr uint256 kH1(
"092891fe4ef6cee585fdc6fda0e09eb4d386363158ec3321b8123e5a772c6ca7");
127 constexpr uint256 kH2(
"436ccbac3347baa1f1e53baeef1f43334da88f1f6d70d963b833afd6dfa289fe");
128 constexpr uint256 kH3(
"b92891fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8");
129 constexpr uint256 kH4(
"b92891fe4ef6cee585fdc6fda2e09eb4d386363158ec3321b8123e5a772c6ca8");
133 if (!testMode.backed)
146 auto i = sMap.
begin();
148 EXPECT_FALSE(i == e || (*i != *i1)) <<
"bad traverse";
150 EXPECT_FALSE(i == e || (*i != *i2)) <<
"bad traverse";
152 EXPECT_EQ(i, e) <<
"bad traverse";
161 EXPECT_FALSE(i == e || (*i != *i1)) <<
"bad traverse";
163 EXPECT_FALSE(i == e || (*i != *i3)) <<
"bad traverse";
165 EXPECT_FALSE(i == e || (*i != *i4)) <<
"bad traverse";
167 EXPECT_EQ(i, e) <<
"bad traverse";
172 EXPECT_EQ(sMap.
getHash(), mapHash) <<
"bad snapshot";
173 EXPECT_EQ(map2->getHash(), mapHash) <<
"bad snapshot";
176 ASSERT_TRUE(sMap.
compare(*map2, delta, 100));
177 EXPECT_TRUE(delta.
empty());
179 EXPECT_TRUE(sMap.
delItem(sMap.
begin()->key())) <<
"bad mod";
181 EXPECT_NE(sMap.
getHash(), mapHash) <<
"bad snapshot";
182 EXPECT_EQ(map2->getHash(), mapHash) <<
"bad snapshot";
184 ASSERT_TRUE(sMap.
compare(*map2, delta, 100));
185 ASSERT_EQ(delta.
size(), 1);
186 EXPECT_EQ(delta.
begin()->first, kH1);
187 EXPECT_EQ(delta.
begin()->second.first,
nullptr);
188 ASSERT_NE(delta.
begin()->second.second,
nullptr);
189 EXPECT_EQ(delta.
begin()->second.second->key(), kH1);
194 uint256{
"b92891fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8"},
195 uint256{
"b92881fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8"},
196 uint256{
"b92691fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8"},
197 uint256{
"b92791fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8"},
198 uint256{
"b91891fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8"},
199 uint256{
"b99891fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8"},
200 uint256{
"f22891fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8"},
201 uint256{
"292891fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8"},
205 uint256{
"B7387CFEA0465759ADC718E8C42B52D2309D179B326E239EB5075C64B6281F7F"},
206 uint256{
"FBC195A9592A54AB44010274163CB6BA95F497EC5BA0A8831845467FB2ECE266"},
207 uint256{
"4E7D2684B65DFD48937FFB775E20175C43AF0C94066F7D5679F51AE756795B75"},
208 uint256{
"7A2F312EB203695FFD164E038E281839EEF06A1B99BFC263F3CECC6C74F93E07"},
209 uint256{
"395A6691A372387A703FB0F2C6D2C405DAF307D0817F8F0E207596462B0E3A3E"},
210 uint256{
"D044C0A696DE3169CC70AE216A1564D69DE96582865796142CE7D98A84D9DDE4"},
211 uint256{
"76DCC77C4027309B5A91AD164083264D70B77B5E43E08AEDA5EBF94361143615"},
212 uint256{
"DF4220E93ADC6F5569063A01B4DC79F8DB9553B6A3222ADE23DEA02BBE7230E5"},
216 if (!testMode.backed)
231 EXPECT_TRUE(map.
delItem(kKeys[k]));
239 uint256{
"f22891fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8"},
240 uint256{
"b99891fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8"},
241 uint256{
"b92891fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8"},
242 uint256{
"b92881fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8"},
243 uint256{
"b92791fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8"},
244 uint256{
"b92691fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8"},
245 uint256{
"b91891fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8"},
246 uint256{
"292891fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8"},
251 if (!testMode.backed)
253 for (
auto const& k : kKeys)
259 auto keyIndex = kKeys.
size();
260 for (
auto const& k : map)
261 EXPECT_EQ(k.key(), kKeys[--keyIndex]);
287 static constexpr unsigned char kFirstKey = 1;
288 static constexpr unsigned char kKeyCount = 100;
289 static constexpr unsigned char kLastKey = kKeyCount - 1;
291 for (
unsigned char c = kFirstKey; c < kKeyCount; ++c)
301 ADD_FAILURE() <<
"Missing proof path";
304 auto& proofPath = *
path;
310 proofPath.insert(proofPath.begin(), proofPath.front());
320 goodPath = std::move(proofPath);
340 badPath.
front().back()--;
A generic endpoint for log messages.
static constexpr std::size_t size()
Like std::vector<char> but better.
void fill(std::uint8_t value) noexcept
Set every byte in the buffer to the given value.
uint256 const & asUInt256() const
uint256 const & key() const
bool addItem(SHAMapNodeType type, boost::intrusive_ptr< SHAMapItem const > item)
static bool verifyProofPath(uint256 const &rootHash, uint256 const &key, std::vector< Blob > const &path)
Verify the proof path.
std::optional< std::vector< Blob > > getProofPath(uint256 const &key) const
Get the proof path of the key.
std::map< uint256, DeltaItem > Delta
void dump(bool withHashes=false) const
bool compare(SHAMap const &otherMap, Delta &differences, int maxCount) const
std::shared_ptr< SHAMap > snapShot(bool isMutable) const
ConstIterator end() const
SHAMapHash getHash() const
ConstIterator begin() const
bool delItem(uint256 const &id)
An immutable linear range of bytes.
static TestSink & instance()
static Buffer intToVuc(std::uint8_t v)
T emplace_back(T... args)
constexpr SHAMapBackingMode kUnbackedMode
constexpr SHAMapBackingMode kBackedMode
TEST_P(SHAMapTest, add_traverse_snapshot_build_tear_and_iterate)
TEST_F(SHAMapPathProof, verify_proof_path)
bool operator!=(SHAMapItem const &a, SHAMapItem const &b)
std::string shamapBackingModeName(::testing::TestParamInfo< SHAMapBackingMode > const &info)
INSTANTIATE_TEST_SUITE_P(BackingMode, SHAMapTest, ::testing::Values(kBackedMode, kUnbackedMode), shamapBackingModeName)
Number root(Number f, unsigned d)
boost::intrusive_ptr< SHAMapItem > makeShamapitem(uint256 const &tag, Slice data)
std::string_view testName