Fabcoin Core  0.16.2
P2P Digital Currency
trie.cpp
Go to the documentation of this file.
1 /*
2  This file is part of cpp-ethereum.
3 
4  cpp-ethereum is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  cpp-ethereum is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
16 */
17 
18 #include <fstream>
19 #include <boost/test/unit_test.hpp>
21 #include <libdevcore/CommonIO.h>
22 #include <libdevcore/TrieDB.h>
23 #include <libdevcore/TrieHash.h>
24 #include "MemTrie.h"
26 
27 using namespace std;
28 using namespace dev;
29 using namespace dev::test;
30 
31 namespace js = json_spirit;
32 
33 static unsigned fac(unsigned _i)
34 {
35  return _i > 2 ? _i * fac(_i - 1) : _i;
36 }
37 
38 using dev::operator <<;
39 
40 BOOST_AUTO_TEST_SUITE(Crypto)
41 
43 
45 {
46  h256 r;
47  MemoryDB fm;
48  {
50  ft.init();
51  ft.insert(h256("69", h256::FromHex, h256::AlignRight).ref(), h256("414243", h256::FromHex, h256::AlignRight).ref());
52  for (auto i: ft)
53  cnote << i.first << i.second;
54  r = ft.root();
55  }
56  {
58  ft.setRoot(r);
59  for (auto i: ft)
60  cnote << i.first << i.second;
61  }
62 }
63 
64 BOOST_AUTO_TEST_CASE(hex_encoded_securetrie_test)
65 {
66  string testPath = test::getTestPath();
67 
68  testPath += "/TrieTests";
69 
70  cnote << "Testing Secure Trie...";
71  js::mValue v;
72  string s = contentsString(testPath + "/hex_encoded_securetrie_test.json");
73  BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of 'hex_encoded_securetrie_test.json' is empty. Have you cloned the 'tests' repo branch develop?");
74  js::read_string(s, v);
75  for (auto& i: v.get_obj())
76  {
77  cnote << i.first;
78  js::mObject& o = i.second.get_obj();
79  vector<pair<string, string>> ss;
80  for (auto i: o["in"].get_obj())
81  {
82  ss.push_back(make_pair(i.first, i.second.get_str()));
83  if (!ss.back().first.find("0x"))
84  ss.back().first = asString(fromHex(ss.back().first.substr(2)));
85  if (!ss.back().second.find("0x"))
86  ss.back().second = asString(fromHex(ss.back().second.substr(2)));
87  }
88  for (unsigned j = 0; j < min(1000000000u, fac((unsigned)ss.size())); ++j)
89  {
90  next_permutation(ss.begin(), ss.end());
91  MemoryDB m;
92  EnforceRefs r(m, true);
94  MemoryDB hm;
95  EnforceRefs hr(hm, true);
97  MemoryDB fm;
98  EnforceRefs fr(fm, true);
100  t.init();
101  ht.init();
102  ft.init();
103  BOOST_REQUIRE(t.check(true));
104  BOOST_REQUIRE(ht.check(true));
105  BOOST_REQUIRE(ft.check(true));
106  for (auto const& k: ss)
107  {
108  t.insert(k.first, k.second);
109  ht.insert(k.first, k.second);
110  ft.insert(k.first, k.second);
111  BOOST_REQUIRE(t.check(true));
112  BOOST_REQUIRE(ht.check(true));
113  BOOST_REQUIRE(ft.check(true));
114  auto i = ft.begin();
115  auto j = t.begin();
116  for (; i != ft.end() && j != t.end(); ++i, ++j)
117  {
118  BOOST_CHECK_EQUAL(i == ft.end(), j == t.end());
119  BOOST_REQUIRE((*i).first.toBytes() == (*j).first.toBytes());
120  BOOST_REQUIRE((*i).second.toBytes() == (*j).second.toBytes());
121  }
122  BOOST_CHECK_EQUAL(ht.root(), ft.root());
123  }
124  BOOST_REQUIRE(!o["root"].is_null());
125  BOOST_CHECK_EQUAL(o["root"].get_str(), "0x" + toHex(ht.root().asArray()));
126  BOOST_CHECK_EQUAL(o["root"].get_str(), "0x" + toHex(ft.root().asArray()));
127  }
128  }
129 }
130 
131 BOOST_AUTO_TEST_CASE(trie_test_anyorder)
132 {
133  string testPath = test::getTestPath();
134 
135  testPath += "/TrieTests";
136 
137  cnote << "Testing Trie...";
138  js::mValue v;
139  string s = contentsString(testPath + "/trieanyorder.json");
140  BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of 'trieanyorder.json' is empty. Have you cloned the 'tests' repo branch develop?");
141  js::read_string(s, v);
142  for (auto& i: v.get_obj())
143  {
144  cnote << i.first;
145  js::mObject& o = i.second.get_obj();
146  vector<pair<string, string>> ss;
147  for (auto i: o["in"].get_obj())
148  {
149  ss.push_back(make_pair(i.first, i.second.get_str()));
150  if (!ss.back().first.find("0x"))
151  ss.back().first = asString(fromHex(ss.back().first.substr(2)));
152  if (!ss.back().second.find("0x"))
153  ss.back().second = asString(fromHex(ss.back().second.substr(2)));
154  }
155  for (unsigned j = 0; j < min(1000u, fac((unsigned)ss.size())); ++j)
156  {
157  next_permutation(ss.begin(), ss.end());
158  MemoryDB m;
159  EnforceRefs r(m, true);
161  MemoryDB hm;
162  EnforceRefs hr(hm, true);
164  MemoryDB fm;
165  EnforceRefs fr(fm, true);
167  t.init();
168  ht.init();
169  ft.init();
170  BOOST_REQUIRE(t.check(true));
171  BOOST_REQUIRE(ht.check(true));
172  BOOST_REQUIRE(ft.check(true));
173  for (auto const& k: ss)
174  {
175  t.insert(k.first, k.second);
176  ht.insert(k.first, k.second);
177  ft.insert(k.first, k.second);
178  BOOST_REQUIRE(t.check(true));
179  BOOST_REQUIRE(ht.check(true));
180  BOOST_REQUIRE(ft.check(true));
181  auto i = ft.begin();
182  auto j = t.begin();
183  for (; i != ft.end() && j != t.end(); ++i, ++j)
184  {
185  BOOST_CHECK_EQUAL(i == ft.end(), j == t.end());
186  BOOST_REQUIRE((*i).first.toBytes() == (*j).first.toBytes());
187  BOOST_REQUIRE((*i).second.toBytes() == (*j).second.toBytes());
188  }
189  BOOST_CHECK_EQUAL(ht.root(), ft.root());
190  }
191  BOOST_REQUIRE(!o["root"].is_null());
192  BOOST_CHECK_EQUAL(o["root"].get_str(), "0x" + toHex(t.root().asArray()));
193  BOOST_CHECK_EQUAL(ht.root(), ft.root());
194  }
195  }
196 }
197 
198 BOOST_AUTO_TEST_CASE(trie_tests_ordered)
199 {
200  string testPath = test::getTestPath();
201 
202  testPath += "/TrieTests";
203 
204  cnote << "Testing Trie...";
205  js::mValue v;
206  string s = contentsString(testPath + "/trietest.json");
207  BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of 'trietest.json' is empty. Have you cloned the 'tests' repo branch develop?");
208  js::read_string(s, v);
209 
210  for (auto& i: v.get_obj())
211  {
212  cnote << i.first;
213  js::mObject& o = i.second.get_obj();
214  vector<pair<string, string>> ss;
215  vector<string> keysToBeDeleted;
216  for (auto& i: o["in"].get_array())
217  {
218  vector<string> values;
219  for (auto& s: i.get_array())
220  {
221  if (s.type() == json_spirit::str_type)
222  values.push_back(s.get_str());
223  else if (s.type() == json_spirit::null_type)
224  {
225  // mark entry for deletion
226  values.push_back("");
227  if (!values[0].find("0x"))
228  values[0] = asString(fromHex(values[0].substr(2)));
229  keysToBeDeleted.push_back(values[0]);
230  }
231  else
232  BOOST_FAIL("Bad type (expected string)");
233  }
234 
235  BOOST_REQUIRE(values.size() == 2);
236  ss.push_back(make_pair(values[0], values[1]));
237  if (!ss.back().first.find("0x"))
238  ss.back().first = asString(fromHex(ss.back().first.substr(2)));
239  if (!ss.back().second.find("0x"))
240  ss.back().second = asString(fromHex(ss.back().second.substr(2)));
241  }
242 
243  MemoryDB m;
244  EnforceRefs r(m, true);
246  MemoryDB hm;
247  EnforceRefs hr(hm, true);
249  MemoryDB fm;
250  EnforceRefs fr(fm, true);
252  t.init();
253  ht.init();
254  ft.init();
255  BOOST_REQUIRE(t.check(true));
256  BOOST_REQUIRE(ht.check(true));
257  BOOST_REQUIRE(ft.check(true));
258 
259  for (auto const& k: ss)
260  {
261  if (find(keysToBeDeleted.begin(), keysToBeDeleted.end(), k.first) != keysToBeDeleted.end() && k.second.empty())
262  t.remove(k.first), ht.remove(k.first), ft.remove(k.first);
263  else
264  t.insert(k.first, k.second), ht.insert(k.first, k.second), ft.insert(k.first, k.second);
265  BOOST_REQUIRE(t.check(true));
266  BOOST_REQUIRE(ht.check(true));
267  BOOST_REQUIRE(ft.check(true));
268  auto i = ft.begin();
269  auto j = t.begin();
270  for (; i != ft.end() && j != t.end(); ++i, ++j)
271  {
272  BOOST_CHECK_EQUAL(i == ft.end(), j == t.end());
273  BOOST_REQUIRE((*i).first.toBytes() == (*j).first.toBytes());
274  BOOST_REQUIRE((*i).second.toBytes() == (*j).second.toBytes());
275  }
276  BOOST_CHECK_EQUAL(ht.root(), ft.root());
277  }
278 
279  BOOST_REQUIRE(!o["root"].is_null());
280  BOOST_CHECK_EQUAL(o["root"].get_str(), "0x" + toHex(t.root().asArray()));
281  }
282 }
283 
285 {
286  BytesMap bytesMap;
287  for (auto const& _v: _s)
288  bytesMap.insert(std::make_pair(bytes(_v.first.begin(), _v.first.end()), bytes(_v.second.begin(), _v.second.end())));
289  return hash256(bytesMap);
290 }
291 
293 {
294  BytesMap bytesMap;
295  for (auto const& _v: _s)
296  bytesMap.insert(std::make_pair(bytes(_v.first.begin(), _v.first.end()), bytes(_v.second.begin(), _v.second.end())));
297  return rlp256(bytesMap);
298 }
299 
300 BOOST_AUTO_TEST_CASE(moreTrieTests)
301 {
302  cnote << "Testing Trie more...";
303  // More tests...
304  {
305  MemoryDB m;
307  t.init(); // initialise as empty tree.
308  cnote << t;
309  cnote << m;
310  cnote << t.root();
312 
313  t.insert(string("tesz"), string("test"));
314  cnote << t;
315  cnote << m;
316  cnote << t.root();
317  cnote << stringMapHash256({{"test", "test"}});
318 
319  t.insert(string("tesa"), string("testy"));
320  cnote << t;
321  cnote << m;
322  cnote << t.root();
323  cnote << stringMapHash256({{"test", "test"}, {"te", "testy"}});
324  cnote << t.at(string("test"));
325  cnote << t.at(string("te"));
326  cnote << t.at(string("t"));
327 
328  t.remove(string("te"));
329  cnote << m;
330  cnote << t.root();
331  cnote << stringMapHash256({{"test", "test"}});
332 
333  t.remove(string("test"));
334  cnote << m;
335  cnote << t.root();
337  }
338  {
339  MemoryDB m;
341  t.init(); // initialise as empty tree.
342  t.insert(string("a"), string("A"));
343  t.insert(string("b"), string("B"));
344  cnote << t;
345  cnote << m;
346  cnote << t.root();
347  cnote << stringMapHash256({{"b", "B"}, {"a", "A"}});
348  bytes r(stringMapRlp256({{"b", "B"}, {"a", "A"}}));
349  cnote << RLP(r);
350  }
351  {
352  MemTrie t;
353  t.insert("dog", "puppy");
354  cnote << hex << t.hash256();
355  bytes r(t.rlp());
356  cnote << RLP(r);
357  }
358  {
359  MemTrie t;
360  t.insert("bed", "d");
361  t.insert("be", "e");
362  cnote << hex << t.hash256();
363  bytes r(t.rlp());
364  cnote << RLP(r);
365  }
366  {
367  cnote << hex << stringMapHash256({{"dog", "puppy"}, {"doe", "reindeer"}});
368  MemTrie t;
369  t.insert("dog", "puppy");
370  t.insert("doe", "reindeer");
371  cnote << hex << t.hash256();
372  bytes r(t.rlp());
373  cnote << RLP(r);
374  cnote << toHex(t.rlp());
375  }
376  {
377  MemoryDB m;
378  EnforceRefs r(m, true);
380  d.init(); // initialise as empty tree.
381  MemTrie t;
382  StringMap s;
383 
384  auto add = [&](char const* a, char const* b)
385  {
386  d.insert(string(a), string(b));
387  t.insert(a, b);
388  s[a] = b;
389 
390  cnote << "/n-------------------------------";
391  cnote << a << " -> " << b;
392  cnote << d;
393  cnote << m;
394  cnote << d.root();
395  cnote << stringMapHash256(s);
396 
397  BOOST_REQUIRE(d.check(true));
398  BOOST_REQUIRE_EQUAL(t.hash256(), stringMapHash256(s));
399  BOOST_REQUIRE_EQUAL(d.root(), stringMapHash256(s));
400  for (auto const& i: s)
401  {
402  (void)i;
403  BOOST_REQUIRE_EQUAL(t.at(i.first), i.second);
404  BOOST_REQUIRE_EQUAL(d.at(i.first), i.second);
405  }
406  };
407 
408  auto remove = [&](char const* a)
409  {
410  s.erase(a);
411  t.remove(a);
412  d.remove(string(a));
413 
414  /*cnote << endl << "-------------------------------";
415  cnote << "X " << a;
416  cnote << d;
417  cnote << m;
418  cnote << d.root();
419  cnote << hash256(s);*/
420 
421  BOOST_REQUIRE(d.check(true));
422  BOOST_REQUIRE(t.at(a).empty());
423  BOOST_REQUIRE(d.at(string(a)).empty());
424  BOOST_REQUIRE_EQUAL(t.hash256(), stringMapHash256(s));
425  BOOST_REQUIRE_EQUAL(d.root(), stringMapHash256(s));
426  for (auto const& i: s)
427  {
428  (void)i;
429  BOOST_REQUIRE_EQUAL(t.at(i.first), i.second);
430  BOOST_REQUIRE_EQUAL(d.at(i.first), i.second);
431  }
432  };
433 
434  add("dogglesworth", "cat");
435  add("doe", "reindeer");
436  remove("dogglesworth");
437  add("horse", "stallion");
438  add("do", "verb");
439  add("doge", "coin");
440  remove("horse");
441  remove("do");
442  remove("doge");
443  remove("doe");
444  }
445 }
446 
447 BOOST_AUTO_TEST_CASE(trieLowerBound)
448 {
449  cnote << "Stress-testing Trie.lower_bound...";
450  if (0)
451  {
452  MemoryDB dm;
453  EnforceRefs e(dm, true);
455  d.init(); // initialise as empty tree.
456  for (int a = 0; a < 20; ++a)
457  {
458  StringMap m;
459  for (int i = 0; i < 50; ++i)
460  {
461  auto k = randomWord();
462  auto v = toString(i);
463  m[k] = v;
464  d.insert(k, v);
465  }
466 
467  for (auto i: d)
468  {
469  auto it = d.lower_bound(i.first);
470  for (auto iit = d.begin(); iit != d.end(); ++iit)
471  if ((*iit).first.toString() >= i.first.toString())
472  {
473  BOOST_REQUIRE(it == iit);
474  break;
475  }
476  }
477  for (unsigned i = 0; i < 100; ++i)
478  {
479  auto k = randomWord();
480  auto it = d.lower_bound(k);
481  for (auto iit = d.begin(); iit != d.end(); ++iit)
482  if ((*iit).first.toString() >= k)
483  {
484  BOOST_REQUIRE(it == iit);
485  break;
486  }
487  }
488 
489  }
490  }
491 }
492 
494 {
495  cnote << "Stress-testing Trie...";
496  {
497  MemoryDB m;
498  MemoryDB dm;
499  EnforceRefs e(dm, true);
501  d.init(); // initialise as empty tree.
502  MemTrie t;
503  BOOST_REQUIRE(d.check(true));
504  for (int a = 0; a < 20; ++a)
505  {
506  StringMap m;
507  for (int i = 0; i < 50; ++i)
508  {
509  auto k = randomWord();
510  auto v = toString(i);
511  m[k] = v;
512  t.insert(k, v);
513  d.insert(k, v);
514  BOOST_REQUIRE_EQUAL(stringMapHash256(m), t.hash256());
515  BOOST_REQUIRE_EQUAL(stringMapHash256(m), d.root());
516  BOOST_REQUIRE(d.check(true));
517  }
518  while (!m.empty())
519  {
520  auto k = m.begin()->first;
521  auto v = m.begin()->second;
522  d.remove(k);
523  t.remove(k);
524  m.erase(k);
525  if (!d.check(true))
526  {
527  // cwarn << m;
528  for (auto i: d)
529  cwarn << i.first.toString() << i.second.toString();
530 
531  MemoryDB dm2;
532  EnforceRefs e2(dm2, true);
533  GenericTrieDB<MemoryDB> d2(&dm2);
534  d2.init(); // initialise as empty tree.
535  for (auto i: d)
536  d2.insert(i.first, i.second);
537 
538  cwarn << "Good:" << d2.root();
539 // for (auto i: dm2.get())
540 // cwarn << i.first << ": " << RLP(i.second);
541  d2.debugStructure(cerr);
542  cwarn << "Broken:" << d.root(); // Leaves an extension -> extension (3c1... -> 742...)
543 // for (auto i: dm.get())
544 // cwarn << i.first << ": " << RLP(i.second);
545  d.debugStructure(cerr);
546 
547  d2.insert(k, v);
548  cwarn << "Pres:" << d2.root();
549 // for (auto i: dm2.get())
550 // cwarn << i.first << ": " << RLP(i.second);
551  d2.debugStructure(cerr);
552  if (g_logVerbosity != -1)
553  g_logVerbosity = 99;
554  d2.remove(k);
555  if (g_logVerbosity != -1)
556  g_logVerbosity = 4;
557 
558  cwarn << "Good?" << d2.root();
559  }
560  BOOST_REQUIRE(d.check(true));
561  BOOST_REQUIRE_EQUAL(stringMapHash256(m), t.hash256());
562  BOOST_REQUIRE_EQUAL(stringMapHash256(m), d.root());
563  }
564  }
565  }
566 }
567 
568 template<typename Trie> void perfTestTrie(char const* _name)
569 {
570  for (size_t p = 1000; p != 1000000; p*=10)
571  {
572  MemoryDB dm;
573  Trie d(&dm);
574  d.init();
575  cnote << "TriePerf " << _name << p;
576  std::vector<h256> keys(1000);
577  Timer t;
578  size_t ki = 0;
579  for (size_t i = 0; i < p; ++i)
580  {
581  auto k = h256::random();
582  auto v = toString(i);
583  d.insert(k, v);
584 
585  if (i % (p / 1000) == 0)
586  keys[ki++] = k;
587  }
588  cnote << "Insert " << p << "values: " << t.elapsed();
589  t.restart();
590  for (auto k: keys)
591  d.at(k);
592  cnote << "Query 1000 values: " << t.elapsed();
593  t.restart();
594  size_t i = 0;
595  for (auto it = d.begin(); i < 1000 && it != d.end(); ++it, ++i)
596  *it;
597  cnote << "Iterate 1000 values: " << t.elapsed();
598  t.restart();
599  for (auto k: keys)
600  d.remove(k);
601  cnote << "Remove 1000 values:" << t.elapsed() << "\n";
602  }
603 }
604 
606 {
607  if (test::Options::get().performance)
608  {
609  perfTestTrie<SpecificTrieDB<GenericTrieDB<MemoryDB>, h256>>("GenericTrieDB");
610  perfTestTrie<SpecificTrieDB<HashedGenericTrieDB<MemoryDB>, h256>>("HashedGenericTrieDB");
611  perfTestTrie<SpecificTrieDB<FatGenericTrieDB<MemoryDB>, h256>>("FatGenericTrieDB");
612  }
613 }
614 
Merkle Patricia Tree "Trie": a modifed base-16 Radix tree.
Definition: MemTrie.h:35
bool check(bool _requireNoLeftOvers) const
Used for debugging, scans the whole trie.
Definition: TrieDB.h:219
const Object & get_obj() const
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
Definition: Arith256.cpp:15
std::string toHex(T const &_data, int _w=2, HexPrefix _prefix=HexPrefix::DontAdd)
Definition: CommonData.h:54
std::map< bytes, bytes > BytesMap
Definition: Common.h:138
vector_ref< _T const > ref(_T const &_t)
Definition: vector_ref.h:115
void debugStructure(std::ostream &_out) const
Used for debugging, scans the whole trie.
Definition: TrieDB.h:212
Merkle Patricia Tree "Trie": a modifed base-16 Radix tree.
Definition: TrieDB.h:64
void hash256(RaIter first, RaIter last, OutIter first2, OutIter last2)
Definition: picosha2.h:304
std::string randomWord()
Creates a random, printable, word.
Definition: CommonData.cpp:88
std::hash for asio::adress
Definition: Common.h:323
std::string contentsString(std::string const &_file)
Retrieve and returns the contents of the given file as a std::string.
void perfTestTrie(char const *_name)
Definition: trie.cpp:568
void insert(bytesConstRef _key, bytesConstRef _value)
Definition: TrieDB.h:446
std::string toString(string32 const &_s)
Make normal string from fixed-length string.
Definition: CommonData.cpp:141
ExecStats::duration min
Definition: ExecStats.cpp:35
void insert(bytesConstRef _key, bytesConstRef _value)
Definition: TrieDB.h:395
#define a(i)
bytes fromHex(std::string const &_s, WhenError _throw=WhenError::DontThrow)
Definition: CommonData.cpp:99
double elapsed() const
Definition: Common.h:280
bool read_string(const String_type &s, Value_type &value)
h256 stringMapHash256(StringMap const &_s)
Definition: trie.cpp:284
h256 const & root() const
Definition: TrieDB.h:99
void remove(std::string const &_key)
Definition: MemTrie.cpp:470
std::vector< byte > bytes
Definition: Common.h:75
std::string getTestPath()
Definition: Common.cpp:35
std::string at(bytes const &_key) const
Definition: TrieDB.h:101
void restart()
Definition: Common.h:281
h256 hash256() const
Definition: MemTrie.cpp:436
FixedHash< 32 > h256
Definition: FixedHash.h:340
#define cwarn
Definition: Log.h:304
void remove(bytesConstRef _key)
Definition: TrieDB.h:396
#define b(i, j)
mConfig::Object_type mObject
bytes stringMapRlp256(StringMap const &_s)
Definition: trie.cpp:292
int g_logVerbosity
The logging system&#39;s current verbosity.
Definition: Log.cpp:37
#define cnote
Definition: Log.h:303
#define BOOST_FIXTURE_TEST_SUITE(a, b)
Definition: object.cpp:14
bytes rlp256(BytesMap const &_s)
Definition: TrieHash.cpp:161
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:18
void insert(std::string const &_key, std::string const &_value)
Definition: MemTrie.cpp:462
bytes rlp() const
Definition: MemTrie.cpp:441
void remove(bytes const &_key)
Definition: TrieDB.h:107
iterator end() const
Definition: TrieDB.h:157
std::string const & at(std::string const &_key) const
Definition: MemTrie.cpp:454
#define BOOST_AUTO_TEST_SUITE_END()
Definition: object.cpp:16
iterator end() const
Definition: TrieDB.h:476
void setRoot(h256 const &_root, Verification _v=Verification::Normal)
Definition: TrieDB.h:78
#define e(i)
Definition: sha.cpp:733
#define d(i)
Definition: sha.cpp:732
std::array< byte, N > & asArray()
Definition: FixedHash.h:148
void insert(bytes const &_key, bytes const &_value)
Definition: TrieDB.h:103
std::string get_str(std::string::const_iterator begin, std::string::const_iterator end)
std::map< std::string, std::string > StringMap
Definition: Common.h:137
iterator begin() const
Definition: TrieDB.h:156
Class for interpreting Recursive Linear-Prefix Data.
Definition: RLP.h:64
iterator begin() const
Definition: TrieDB.h:475
std::string asString(bytes const &_b)
Converts byte array to a string containing the same (binary) data.
Definition: CommonData.h:79
BOOST_AUTO_TEST_CASE(fat_trie)
Definition: trie.cpp:44
Helper functions to work with json::spirit and test files.
void remove(bytesConstRef _key)
Definition: TrieDB.h:453