Fabcoin Core  0.16.2
P2P Digital Currency
TrieDB.h
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 */
22 #pragma once
23 
24 #include <memory>
25 #include "db.h"
26 #include "Common.h"
27 #include "Log.h"
28 #include "Exceptions.h"
29 #include "SHA3.h"
30 #include "MemoryDB.h"
31 #include "TrieCommon.h"
32 
33 namespace dev
34 {
35 
36 struct TrieDBChannel: public LogChannel { static const char* name(); static const int verbosity = 17; };
37 #define tdebug clog(TrieDBChannel)
38 
39 struct InvalidTrie: virtual dev::Exception {};
40 extern const h256 c_shaNull;
41 extern const h256 EmptyTrie;
42 
43 enum class Verification {
44  Skip,
45  Normal
46 };
47 
63 template <class _DB>
65 {
66 public:
67  using DB = _DB;
68 
69  explicit GenericTrieDB(DB* _db = nullptr): m_db(_db) {}
70  GenericTrieDB(DB* _db, h256 const& _root, Verification _v = Verification::Normal) { open(_db, _root, _v); }
72 
73  void open(DB* _db) { m_db = _db; }
74  void open(DB* _db, h256 const& _root, Verification _v = Verification::Normal) { m_db = _db; setRoot(_root, _v); }
75 
76  void init() { setRoot(forceInsertNode(&RLPNull)); assert(node(m_root).size()); }
77 
78  void setRoot(h256 const& _root, Verification _v = Verification::Normal)
79  {
80  m_root = _root;
81  if (_v == Verification::Normal)
82  {
83  if (m_root == c_shaNull && !m_db->exists(m_root))
84  init();
85  }
86  /*std::cout << "Setting root to " << _root << " (patched to " << m_root << ")" << std::endl;*/
87 #if ETH_DEBUG
88  if (_v == Verification::Normal)
89 #endif
90  if (!node(m_root).size())
91  BOOST_THROW_EXCEPTION(RootNotFound());
92  }
93 
95  bool isNull() const { return !node(m_root).size(); }
97  bool isEmpty() const { return m_root == c_shaNull && node(m_root).size(); }
98 
99  h256 const& root() const { if (node(m_root).empty()) BOOST_THROW_EXCEPTION(BadRoot(m_root)); /*std::cout << "Returning root as " << ret << " (really " << m_root << ")" << std::endl;*/ return m_root; } // patch the root in the case of the empty trie. TODO: handle this properly.
100 
101  std::string at(bytes const& _key) const { return at(&_key); }
102  std::string at(bytesConstRef _key) const;
103  void insert(bytes const& _key, bytes const& _value) { insert(&_key, &_value); }
104  void insert(bytesConstRef _key, bytes const& _value) { insert(_key, &_value); }
105  void insert(bytes const& _key, bytesConstRef _value) { insert(&_key, _value); }
106  void insert(bytesConstRef _key, bytesConstRef _value);
107  void remove(bytes const& _key) { remove(&_key); }
108  void remove(bytesConstRef _key);
109  bool contains(bytes const& _key) { return contains(&_key); }
110  bool contains(bytesConstRef _key) { return !at(_key).empty(); }
111 
112  class iterator
113  {
114  public:
115  using value_type = std::pair<bytesConstRef, bytesConstRef>;
116 
117  iterator() {}
118  explicit iterator(GenericTrieDB const* _db);
119  iterator(GenericTrieDB const* _db, bytesConstRef _key);
120 
121  iterator& operator++() { next(); return *this; }
122 
123  value_type operator*() const { return at(); }
124  value_type operator->() const { return at(); }
125 
126  bool operator==(iterator const& _c) const { return _c.m_trail == m_trail; }
127  bool operator!=(iterator const& _c) const { return _c.m_trail != m_trail; }
128 
129  value_type at() const;
130 
131  private:
132  void next();
133  void next(NibbleSlice _key);
134 
135  struct Node
136  {
137  std::string rlp;
138  std::string key; // as hexPrefixEncoding.
139  byte child; // 255 -> entering, 16 -> actually at the node, 17 -> exiting, 0-15 -> actual children.
140 
141  // 255 -> 16 -> 0 -> 1 -> ... -> 15 -> 17
142 
143  void setChild(unsigned _i) { child = _i; }
144  void setFirstChild() { child = 16; }
145  void incrementChild() { child = child == 16 ? 0 : child == 15 ? 17 : (child + 1); }
146 
147  bool operator==(Node const& _c) const { return rlp == _c.rlp && key == _c.key && child == _c.child; }
148  bool operator!=(Node const& _c) const { return !operator==(_c); }
149  };
150 
151  protected:
152  std::vector<Node> m_trail;
154  };
155 
156  iterator begin() const { return iterator(this); }
157  iterator end() const { return iterator(); }
158 
159  iterator lower_bound(bytesConstRef _key) const { return iterator(this, _key); }
160 
162  void descendKey(h256 const& _k, h256Hash& _keyMask, bool _wasExt, std::ostream* _out, int _indent = 0) const
163  {
164  _keyMask.erase(_k);
165  if (_k == m_root && _k == c_shaNull) // root allowed to be empty
166  return;
167  descendList(RLP(node(_k)), _keyMask, _wasExt, _out, _indent); // if not, it must be a list
168  }
169 
171  void descendEntry(RLP const& _r, h256Hash& _keyMask, bool _wasExt, std::ostream* _out, int _indent) const
172  {
173  if (_r.isData() && _r.size() == 32)
174  descendKey(_r.toHash<h256>(), _keyMask, _wasExt, _out, _indent);
175  else if (_r.isList())
176  descendList(_r, _keyMask, _wasExt, _out, _indent);
177  else
178  BOOST_THROW_EXCEPTION(InvalidTrie());
179  }
180 
182  void descendList(RLP const& _r, h256Hash& _keyMask, bool _wasExt, std::ostream* _out, int _indent) const
183  {
184  if (_r.isList() && _r.itemCount() == 2 && (!_wasExt || _out))
185  {
186  if (_out)
187  (*_out) << std::string(_indent * 2, ' ') << (_wasExt ? "!2 " : "2 ") << sha3(_r.data()) << ": " << _r << "\n";
188  if (!isLeaf(_r)) // don't go down leaves
189  descendEntry(_r[1], _keyMask, true, _out, _indent + 1);
190  }
191  else if (_r.isList() && _r.itemCount() == 17)
192  {
193  if (_out)
194  (*_out) << std::string(_indent * 2, ' ') << "17 " << sha3(_r.data()) << ": " << _r << "\n";
195  for (unsigned i = 0; i < 16; ++i)
196  if (!_r[i].isEmpty()) // 16 branches are allowed to be empty
197  descendEntry(_r[i], _keyMask, false, _out, _indent + 1);
198  }
199  else
200  BOOST_THROW_EXCEPTION(InvalidTrie());
201  }
202 
204  h256Hash leftOvers(std::ostream* _out = nullptr) const
205  {
206  h256Hash k = m_db->keys();
207  descendKey(m_root, k, false, _out);
208  return k;
209  }
210 
212  void debugStructure(std::ostream& _out) const
213  {
214  leftOvers(&_out);
215  }
216 
219  bool check(bool _requireNoLeftOvers) const
220  {
221  try
222  {
223  return leftOvers().empty() || !_requireNoLeftOvers;
224  }
225  catch (...)
226  {
227  cwarn << boost::current_exception_diagnostic_information();
228  return false;
229  }
230  }
231 
235  DB const* db() const { return m_db; }
236  DB* db() { return m_db; }
237 
238 private:
239  RLPStream& streamNode(RLPStream& _s, bytes const& _b);
240 
241  std::string atAux(RLP const& _here, NibbleSlice _key) const;
242 
243  void mergeAtAux(RLPStream& _out, RLP const& _replace, NibbleSlice _key, bytesConstRef _value);
244  bytes mergeAt(RLP const& _replace, NibbleSlice _k, bytesConstRef _v, bool _inLine = false);
245  bytes mergeAt(RLP const& _replace, h256 const& _replaceHash, NibbleSlice _k, bytesConstRef _v, bool _inLine = false);
246 
247  bool deleteAtAux(RLPStream& _out, RLP const& _replace, NibbleSlice _key);
248  bytes deleteAt(RLP const& _replace, NibbleSlice _k);
249 
250  // in: null (DEL) -- OR -- [_k, V] (DEL)
251  // out: [_k, _s]
252  // -- OR --
253  // in: [V0, ..., V15, S16] (DEL) AND _k == {}
254  // out: [V0, ..., V15, _s]
255  bytes place(RLP const& _orig, NibbleSlice _k, bytesConstRef _s);
256 
257  // in: [K, S] (DEL)
258  // out: null
259  // -- OR --
260  // in: [V0, ..., V15, S] (DEL)
261  // out: [V0, ..., V15, null]
262  bytes remove(RLP const& _orig);
263 
264  // in: [K1 & K2, V] (DEL) : nibbles(K1) == _s, 0 < _s <= nibbles(K1 & K2)
265  // out: [K1, H] ; [K2, V] => H (INS) (being [K1, [K2, V]] if necessary)
266  bytes cleve(RLP const& _orig, unsigned _s);
267 
268  // in: [K1, H] (DEL) ; H <= [K2, V] (DEL) (being [K1, [K2, V]] (DEL) if necessary)
269  // out: [K1 & K2, V]
270  bytes graft(RLP const& _orig);
271 
272  // in: [V0, ... V15, S] (DEL)
273  // out1: [k{i}, Vi] where i < 16
274  // out2: [k{}, S] where i == 16
275  bytes merge(RLP const& _orig, byte _i);
276 
277  // in: [k{}, S] (DEL)
278  // out: [null ** 16, S]
279  // -- OR --
280  // in: [k{i}, N] (DEL)
281  // out: [null ** i, N, null ** (16 - i)]
282  // -- OR --
283  // in: [k{i}K, V] (DEL)
284  // out: [null ** i, H, null ** (16 - i)] ; [K, V] => H (INS) (being [null ** i, [K, V], null ** (16 - i)] if necessary)
285  bytes branch(RLP const& _orig);
286 
287  bool isTwoItemNode(RLP const& _n) const;
288  std::string deref(RLP const& _n) const;
289 
290  std::string node(h256 const& _h) const { return m_db->lookup(_h); }
291 
292  // These are low-level node insertion functions that just go straight through into the DB.
293  h256 forceInsertNode(bytesConstRef _v) { auto h = sha3(_v); forceInsertNode(h, _v); return h; }
294  void forceInsertNode(h256 const& _h, bytesConstRef _v) { m_db->insert(_h, _v); }
295  void forceKillNode(h256 const& _h) { m_db->kill(_h); }
296 
297  // This are semantically-aware node insertion functions that only kills when the node's
298  // data is < 32 bytes. It can safely be used when pruning the trie but won't work correctly
299  // for the special case of the root (which is always looked up via a hash). In that case,
300  // use forceKillNode().
301  void killNode(RLP const& _d) { if (_d.data().size() >= 32) forceKillNode(sha3(_d.data())); }
302  void killNode(RLP const& _d, h256 const& _h) { if (_d.data().size() >= 32) forceKillNode(_h); }
303 
305  DB* m_db = nullptr;
306 };
307 
308 template <class DB>
309 std::ostream& operator<<(std::ostream& _out, GenericTrieDB<DB> const& _db)
310 {
311  for (auto const& i: _db)
312  _out << escaped(i.first.toString(), false) << ": " << escaped(i.second.toString(), false) << std::endl;
313  return _out;
314 }
315 
319 template <class Generic, class _KeyType>
320 class SpecificTrieDB: public Generic
321 {
322 public:
323  using DB = typename Generic::DB;
324  using KeyType = _KeyType;
325 
326  SpecificTrieDB(DB* _db = nullptr): Generic(_db) {}
327  SpecificTrieDB(DB* _db, h256 _root, Verification _v = Verification::Normal): Generic(_db, _root, _v) {}
328 
329  std::string operator[](KeyType _k) const { return at(_k); }
330 
331  bool contains(KeyType _k) const { return Generic::contains(bytesConstRef((byte const*)&_k, sizeof(KeyType))); }
332  std::string at(KeyType _k) const { return Generic::at(bytesConstRef((byte const*)&_k, sizeof(KeyType))); }
333  void insert(KeyType _k, bytesConstRef _value) { Generic::insert(bytesConstRef((byte const*)&_k, sizeof(KeyType)), _value); }
334  void insert(KeyType _k, bytes const& _value) { insert(_k, bytesConstRef(&_value)); }
335  void remove(KeyType _k) { Generic::remove(bytesConstRef((byte const*)&_k, sizeof(KeyType))); }
336 
337  class iterator: public Generic::iterator
338  {
339  public:
340  using Super = typename Generic::iterator;
341  using value_type = std::pair<KeyType, bytesConstRef>;
342 
343  iterator() {}
344  iterator(Generic const* _db): Super(_db) {}
345  iterator(Generic const* _db, bytesConstRef _k): Super(_db, _k) {}
346 
347  value_type operator*() const { return at(); }
348  value_type operator->() const { return at(); }
349 
350  value_type at() const;
351  };
352 
353  iterator begin() const { return this; }
354  iterator end() const { return iterator(); }
355  iterator lower_bound(KeyType _k) const { return iterator(this, bytesConstRef((byte const*)&_k, sizeof(KeyType))); }
356 };
357 
358 template <class Generic, class KeyType>
359 std::ostream& operator<<(std::ostream& _out, SpecificTrieDB<Generic, KeyType> const& _db)
360 {
361  for (auto const& i: _db)
362  _out << i.first << ": " << escaped(i.second.toString(), false) << std::endl;
363  return _out;
364 }
365 
366 template <class _DB>
367 class HashedGenericTrieDB: private SpecificTrieDB<GenericTrieDB<_DB>, h256>
368 {
370 
371 public:
372  using DB = _DB;
373 
374  HashedGenericTrieDB(DB* _db = nullptr): Super(_db) {}
375  HashedGenericTrieDB(DB* _db, h256 _root, Verification _v = Verification::Normal): Super(_db, _root, _v) {}
376 
377  using Super::open;
378  using Super::init;
379  using Super::setRoot;
380 
382  using Super::isNull;
384  using Super::isEmpty;
385 
386  using Super::root;
387  using Super::db;
388 
389  using Super::leftOvers;
390  using Super::check;
391  using Super::debugStructure;
392 
393  std::string at(bytesConstRef _key) const { return Super::at(sha3(_key)); }
394  bool contains(bytesConstRef _key) { return Super::contains(sha3(_key)); }
395  void insert(bytesConstRef _key, bytesConstRef _value) { Super::insert(sha3(_key), _value); }
396  void remove(bytesConstRef _key) { Super::remove(sha3(_key)); }
397 
398  // empty from the PoV of the iterator interface; still need a basic iterator impl though.
399  class iterator
400  {
401  public:
402  using value_type = std::pair<bytesConstRef, bytesConstRef>;
403 
404  iterator() {}
407 
408  iterator& operator++() { return *this; }
409  value_type operator*() const { return value_type(); }
410  value_type operator->() const { return value_type(); }
411 
412  bool operator==(iterator const&) const { return true; }
413  bool operator!=(iterator const&) const { return false; }
414 
415  value_type at() const { return value_type(); }
416  };
417  iterator begin() const { return iterator(); }
418  iterator end() const { return iterator(); }
420 };
421 
422 // Hashed & Hash-key mapping
423 template <class _DB>
424 class FatGenericTrieDB: private SpecificTrieDB<GenericTrieDB<_DB>, h256>
425 {
427 
428 public:
429  using DB = _DB;
430  FatGenericTrieDB(DB* _db = nullptr): Super(_db) {}
431  FatGenericTrieDB(DB* _db, h256 _root, Verification _v = Verification::Normal): Super(_db, _root, _v) {}
432 
433  using Super::init;
434  using Super::isNull;
435  using Super::isEmpty;
436  using Super::root;
437  using Super::leftOvers;
438  using Super::check;
439  using Super::open;
440  using Super::setRoot;
441  using Super::db;
442  using Super::debugStructure;
443 
444  std::string at(bytesConstRef _key) const { return Super::at(sha3(_key)); }
445  bool contains(bytesConstRef _key) { return Super::contains(sha3(_key)); }
446  void insert(bytesConstRef _key, bytesConstRef _value)
447  {
448  h256 hash = sha3(_key);
449  Super::insert(hash, _value);
450  Super::db()->insertAux(hash, _key);
451  }
452 
453  void remove(bytesConstRef _key) { Super::remove(sha3(_key)); }
454 
455  // iterates over <key, value> pairs
457  {
458  public:
460 
461  iterator() { }
462  iterator(FatGenericTrieDB const* _trie) : Super(_trie) { }
463 
464  typename Super::value_type at() const
465  {
466  auto hashed = Super::at();
467  m_key = static_cast<FatGenericTrieDB const*>(Super::m_that)->db()->lookupAux(h256(hashed.first));
468  return std::make_pair(&m_key, std::move(hashed.second));
469  }
470 
471  private:
472  mutable bytes m_key;
473  };
474 
475  iterator begin() const { return iterator(); }
476  iterator end() const { return iterator(); }
477 
478  // iterates over <hashedKey, value> pairs
480  {
481  public:
483 
485  HashedIterator(FatGenericTrieDB const* _trie) : Super(_trie) {}
486 
487  bytes key() const
488  {
489  auto hashed = Super::at();
490  return static_cast<FatGenericTrieDB const*>(Super::m_that)->db()->lookupAux(h256(hashed.first));
491  }
492  };
493 
494  HashedIterator hashedBegin() const { return HashedIterator(this); }
496 };
497 
498 template <class KeyType, class DB> using TrieDB = SpecificTrieDB<GenericTrieDB<DB>, KeyType>;
499 
500 }
501 
502 // Template implementations...
503 namespace dev
504 {
505 
507 {
508  m_that = _db;
509  m_trail.push_back({_db->node(_db->m_root), std::string(1, '\0'), 255}); // one null byte is the HPE for the empty key.
510  next();
511 }
512 
513 template <class DB> GenericTrieDB<DB>::iterator::iterator(GenericTrieDB const* _db, bytesConstRef _fullKey)
514 {
515  m_that = _db;
516  m_trail.push_back({_db->node(_db->m_root), std::string(1, '\0'), 255}); // one null byte is the HPE for the empty key.
517  next(_fullKey);
518 }
519 
521 {
522  assert(m_trail.size());
523  Node const& b = m_trail.back();
524  assert(b.key.size());
525  assert(!(b.key[0] & 0x10)); // should be an integer number of bytes (i.e. not an odd number of nibbles).
526 
527  RLP rlp(b.rlp);
528  return std::make_pair(bytesConstRef(b.key).cropped(1), rlp[rlp.itemCount() == 2 ? 1 : 16].payload());
529 }
530 
531 template <class DB> void GenericTrieDB<DB>::iterator::next(NibbleSlice _key)
532 {
533  NibbleSlice k = _key;
534  while (true)
535  {
536  if (m_trail.empty())
537  {
538  m_that = nullptr;
539  return;
540  }
541 
542  Node const& b = m_trail.back();
543  RLP rlp(b.rlp);
544 
545  if (m_trail.back().child == 255)
546  {
547  // Entering. Look for first...
548  if (rlp.isEmpty())
549  {
550  // Kill our search as soon as we hit an empty node.
551  k.clear();
552  m_trail.pop_back();
553  continue;
554  }
555  if (!rlp.isList() || (rlp.itemCount() != 2 && rlp.itemCount() != 17))
556  {
557 #if ETH_PARANOIA
558  cwarn << "BIG FAT ERROR. STATE TRIE CORRUPTED!!!!!";
559  cwarn << b.rlp.size() << toHex(b.rlp);
560  cwarn << rlp;
561  auto c = rlp.itemCount();
562  cwarn << c;
563  BOOST_THROW_EXCEPTION(InvalidTrie());
564 #else
565  m_that = nullptr;
566  return;
567 #endif
568  }
569  if (rlp.itemCount() == 2)
570  {
571  // Just turn it into a valid Branch
572  auto keyOfRLP = keyOf(rlp);
573 
574  // TODO: do something different depending on how keyOfRLP compares to k.mid(0, std::min(k.size(), keyOfRLP.size()));
575  // if == all is good - continue descent.
576  // if > discard key and continue descent.
577  // if < discard key and skip node.
578 
579  if (!k.contains(keyOfRLP))
580  {
581  if (!k.isEarlierThan(keyOfRLP))
582  {
583  k.clear();
584  m_trail.pop_back();
585  continue;
586  }
587  k.clear();
588  }
589 
590  k = k.mid(std::min(k.size(), keyOfRLP.size()));
591  m_trail.back().key = hexPrefixEncode(keyOf(m_trail.back().key), keyOfRLP, false);
592  if (isLeaf(rlp))
593  {
594  // leaf - exit now.
595  if (k.empty())
596  {
597  m_trail.back().child = 0;
598  return;
599  }
600  // Still data in key we're supposed to be looking for when we're at a leaf. Go for next one.
601  k.clear();
602  m_trail.pop_back();
603  continue;
604  }
605 
606  // enter child.
607  m_trail.back().rlp = m_that->deref(rlp[1]);
608  // no need to set .child as 255 - it's already done.
609  continue;
610  }
611  else
612  {
613  // Already a branch - look for first valid.
614  if (k.size())
615  {
616  m_trail.back().setChild(k[0]);
617  k = k.mid(1);
618  }
619  else
620  m_trail.back().setChild(16);
621  // run through to...
622  }
623  }
624  else
625  {
626  // Continuing/exiting. Look for next...
627  if (!(rlp.isList() && rlp.itemCount() == 17))
628  {
629  k.clear();
630  m_trail.pop_back();
631  continue;
632  }
633  // else run through to...
634  m_trail.back().incrementChild();
635  }
636 
637  // ...here. should only get here if we're a list.
638  assert(rlp.isList() && rlp.itemCount() == 17);
639  for (;; m_trail.back().incrementChild())
640  if (m_trail.back().child == 17)
641  {
642  // finished here.
643  k.clear();
644  m_trail.pop_back();
645  break;
646  }
647  else if (!rlp[m_trail.back().child].isEmpty())
648  {
649  if (m_trail.back().child == 16)
650  return; // have a value at this node - exit now.
651  else
652  {
653  // lead-on to another node - enter child.
654  // fixed so that Node passed into push_back is constructed *before* m_trail is potentially resized (which invalidates back and rlp)
655  Node const& back = m_trail.back();
656  m_trail.push_back(Node{
657  m_that->deref(rlp[back.child]),
658  hexPrefixEncode(keyOf(back.key), NibbleSlice(bytesConstRef(&back.child, 1), 1), false),
659  255
660  });
661  break;
662  }
663  }
664  else
665  k.clear();
666  }
667 }
668 
669 template <class DB> void GenericTrieDB<DB>::iterator::next()
670 {
671  while (true)
672  {
673  if (m_trail.empty())
674  {
675  m_that = nullptr;
676  return;
677  }
678 
679  Node const& b = m_trail.back();
680  RLP rlp(b.rlp);
681 
682  if (m_trail.back().child == 255)
683  {
684  // Entering. Look for first...
685  if (rlp.isEmpty())
686  {
687  m_trail.pop_back();
688  continue;
689  }
690  if (!(rlp.isList() && (rlp.itemCount() == 2 || rlp.itemCount() == 17)))
691  {
692 #if ETH_PARANOIA
693  cwarn << "BIG FAT ERROR. STATE TRIE CORRUPTED!!!!!";
694  cwarn << b.rlp.size() << toHex(b.rlp);
695  cwarn << rlp;
696  auto c = rlp.itemCount();
697  cwarn << c;
698  BOOST_THROW_EXCEPTION(InvalidTrie());
699 #else
700  m_that = nullptr;
701  return;
702 #endif
703  }
704  if (rlp.itemCount() == 2)
705  {
706  // Just turn it into a valid Branch
707  m_trail.back().key = hexPrefixEncode(keyOf(m_trail.back().key), keyOf(rlp), false);
708  if (isLeaf(rlp))
709  {
710  // leaf - exit now.
711  m_trail.back().child = 0;
712  return;
713  }
714 
715  // enter child.
716  m_trail.back().rlp = m_that->deref(rlp[1]);
717  // no need to set .child as 255 - it's already done.
718  continue;
719  }
720  else
721  {
722  // Already a branch - look for first valid.
723  m_trail.back().setFirstChild();
724  // run through to...
725  }
726  }
727  else
728  {
729  // Continuing/exiting. Look for next...
730  if (!(rlp.isList() && rlp.itemCount() == 17))
731  {
732  m_trail.pop_back();
733  continue;
734  }
735  // else run through to...
736  m_trail.back().incrementChild();
737  }
738 
739  // ...here. should only get here if we're a list.
740  assert(rlp.isList() && rlp.itemCount() == 17);
741  for (;; m_trail.back().incrementChild())
742  if (m_trail.back().child == 17)
743  {
744  // finished here.
745  m_trail.pop_back();
746  break;
747  }
748  else if (!rlp[m_trail.back().child].isEmpty())
749  {
750  if (m_trail.back().child == 16)
751  return; // have a value at this node - exit now.
752  else
753  {
754  // lead-on to another node - enter child.
755  // fixed so that Node passed into push_back is constructed *before* m_trail is potentially resized (which invalidates back and rlp)
756  Node const& back = m_trail.back();
757  m_trail.push_back(Node{
758  m_that->deref(rlp[back.child]),
759  hexPrefixEncode(keyOf(back.key), NibbleSlice(bytesConstRef(&back.child, 1), 1), false),
760  255
761  });
762  break;
763  }
764  }
765  }
766 }
767 
769 {
770  auto p = Super::at();
771  value_type ret;
772  assert(p.first.size() == sizeof(KeyType));
773  memcpy(&ret.first, p.first.data(), sizeof(KeyType));
774  ret.second = p.second;
775  return ret;
776 }
777 
778 template <class DB> void GenericTrieDB<DB>::insert(bytesConstRef _key, bytesConstRef _value)
779 {
780 #if ETH_PARANOIA
781  tdebug << "Insert" << toHex(_key.cropped(0, 4)) << "=>" << toHex(_value);
782 #endif
783 
784  std::string rootValue = node(m_root);
785  assert(rootValue.size());
786  bytes b = mergeAt(RLP(rootValue), m_root, NibbleSlice(_key), _value);
787 
788  // mergeAt won't attempt to delete the node if it's less than 32 bytes
789  // However, we know it's the root node and thus always hashed.
790  // So, if it's less than 32 (and thus should have been deleted but wasn't) then we delete it here.
791  if (rootValue.size() < 32)
792  forceKillNode(m_root);
793  m_root = forceInsertNode(&b);
794 }
795 
796 template <class DB> std::string GenericTrieDB<DB>::at(bytesConstRef _key) const
797 {
798  return atAux(RLP(node(m_root)), _key);
799 }
800 
801 template <class DB> std::string GenericTrieDB<DB>::atAux(RLP const& _here, NibbleSlice _key) const
802 {
803  if (_here.isEmpty() || _here.isNull())
804  // not found.
805  return std::string();
806  unsigned itemCount = _here.itemCount();
807  assert(_here.isList() && (itemCount == 2 || itemCount == 17));
808  if (itemCount == 2)
809  {
810  auto k = keyOf(_here);
811  if (_key == k && isLeaf(_here))
812  // reached leaf and it's us
813  return _here[1].toString();
814  else if (_key.contains(k) && !isLeaf(_here))
815  // not yet at leaf and it might yet be us. onwards...
816  return atAux(_here[1].isList() ? _here[1] : RLP(node(_here[1].toHash<h256>())), _key.mid(k.size()));
817  else
818  // not us.
819  return std::string();
820  }
821  else
822  {
823  if (_key.size() == 0)
824  return _here[16].toString();
825  auto n = _here[_key[0]];
826  if (n.isEmpty())
827  return std::string();
828  else
829  return atAux(n.isList() ? n : RLP(node(n.toHash<h256>())), _key.mid(1));
830  }
831 }
832 
833 template <class DB> bytes GenericTrieDB<DB>::mergeAt(RLP const& _orig, NibbleSlice _k, bytesConstRef _v, bool _inLine)
834 {
835  return mergeAt(_orig, sha3(_orig.data()), _k, _v, _inLine);
836 }
837 
838 template <class DB> bytes GenericTrieDB<DB>::mergeAt(RLP const& _orig, h256 const& _origHash, NibbleSlice _k, bytesConstRef _v, bool _inLine)
839 {
840 #if ETH_PARANOIA
841  tdebug << "mergeAt " << _orig << _k << sha3(_orig.data());
842 #endif
843 
844  // The caller will make sure that the bytes are inserted properly.
845  // - This might mean inserting an entry into m_over
846  // We will take care to ensure that (our reference to) _orig is killed.
847 
848  // Empty - just insert here
849  if (_orig.isEmpty())
850  return place(_orig, _k, _v);
851 
852  unsigned itemCount = _orig.itemCount();
853  assert(_orig.isList() && (itemCount == 2 || itemCount == 17));
854  if (itemCount == 2)
855  {
856  // pair...
857  NibbleSlice k = keyOf(_orig);
858 
859  // exactly our node - place value in directly.
860  if (k == _k && isLeaf(_orig))
861  return place(_orig, _k, _v);
862 
863  // partial key is our key - move down.
864  if (_k.contains(k) && !isLeaf(_orig))
865  {
866  if (!_inLine)
867  killNode(_orig, _origHash);
868  RLPStream s(2);
869  s.append(_orig[0]);
870  mergeAtAux(s, _orig[1], _k.mid(k.size()), _v);
871  return s.out();
872  }
873 
874  auto sh = _k.shared(k);
875 // std::cout << _k << " sh " << k << " = " << sh << std::endl;
876  if (sh)
877  {
878  // shared stuff - cleve at disagreement.
879  auto cleved = cleve(_orig, sh);
880  return mergeAt(RLP(cleved), _k, _v, true);
881  }
882  else
883  {
884  // nothing shared - branch
885  auto branched = branch(_orig);
886  return mergeAt(RLP(branched), _k, _v, true);
887  }
888  }
889  else
890  {
891  // branch...
892 
893  // exactly our node - place value.
894  if (_k.size() == 0)
895  return place(_orig, _k, _v);
896 
897  // Kill the node.
898  if (!_inLine)
899  killNode(_orig, _origHash);
900 
901  // not exactly our node - delve to next level at the correct index.
902  byte n = _k[0];
903  RLPStream r(17);
904  for (byte i = 0; i < 17; ++i)
905  if (i == n)
906  mergeAtAux(r, _orig[i], _k.mid(1), _v);
907  else
908  r.append(_orig[i]);
909  return r.out();
910  }
911 
912 }
913 
914 template <class DB> void GenericTrieDB<DB>::mergeAtAux(RLPStream& _out, RLP const& _orig, NibbleSlice _k, bytesConstRef _v)
915 {
916  RLP r = _orig;
917  std::string s;
918  // _orig is always a segment of a node's RLP - removing it alone is pointless. However, if may be a hash, in which case we deref and we know it is removable.
919  bool isRemovable = false;
920  if (!r.isList() && !r.isEmpty())
921  {
922  s = node(_orig.toHash<h256>());
923  r = RLP(s);
924  assert(!r.isNull());
925  isRemovable = true;
926  }
927  bytes b = mergeAt(r, _k, _v, !isRemovable);
928  streamNode(_out, b);
929 }
930 
931 template <class DB> void GenericTrieDB<DB>::remove(bytesConstRef _key)
932 {
933 #if ETH_PARANOIA
934  tdebug << "Remove" << toHex(_key.cropped(0, 4).toBytes());
935 #endif
936 
937  std::string rv = node(m_root);
938  bytes b = deleteAt(RLP(rv), NibbleSlice(_key));
939  if (b.size())
940  {
941  if (rv.size() < 32)
942  forceKillNode(m_root);
943  m_root = forceInsertNode(&b);
944  }
945 }
946 
947 template <class DB> bool GenericTrieDB<DB>::isTwoItemNode(RLP const& _n) const
948 {
949  return (_n.isData() && RLP(node(_n.toHash<h256>())).itemCount() == 2)
950  || (_n.isList() && _n.itemCount() == 2);
951 }
952 
953 template <class DB> std::string GenericTrieDB<DB>::deref(RLP const& _n) const
954 {
955  return _n.isList() ? _n.data().toString() : node(_n.toHash<h256>());
956 }
957 
958 template <class DB> bytes GenericTrieDB<DB>::deleteAt(RLP const& _orig, NibbleSlice _k)
959 {
960 #if ETH_PARANOIA
961  tdebug << "deleteAt " << _orig << _k << sha3(_orig.data());
962 #endif
963 
964  // The caller will make sure that the bytes are inserted properly.
965  // - This might mean inserting an entry into m_over
966  // We will take care to ensure that (our reference to) _orig is killed.
967 
968  // Empty - not found - no change.
969  if (_orig.isEmpty())
970  return bytes();
971 
972  assert(_orig.isList() && (_orig.itemCount() == 2 || _orig.itemCount() == 17));
973  if (_orig.itemCount() == 2)
974  {
975  // pair...
976  NibbleSlice k = keyOf(_orig);
977 
978  // exactly our node - return null.
979  if (k == _k && isLeaf(_orig))
980  {
981  killNode(_orig);
982  return RLPNull;
983  }
984 
985  // partial key is our key - move down.
986  if (_k.contains(k))
987  {
988  RLPStream s;
989  s.appendList(2) << _orig[0];
990  if (!deleteAtAux(s, _orig[1], _k.mid(k.size())))
991  return bytes();
992  killNode(_orig);
993  RLP r(s.out());
994  if (isTwoItemNode(r[1]))
995  return graft(r);
996  return s.out();
997  }
998  else
999  // not found - no change.
1000  return bytes();
1001  }
1002  else
1003  {
1004  // branch...
1005 
1006  // exactly our node - remove and rejig.
1007  if (_k.size() == 0 && !_orig[16].isEmpty())
1008  {
1009  // Kill the node.
1010  killNode(_orig);
1011 
1012  byte used = uniqueInUse(_orig, 16);
1013  if (used != 255)
1014  if (isTwoItemNode(_orig[used]))
1015  {
1016  auto merged = merge(_orig, used);
1017  return graft(RLP(merged));
1018  }
1019  else
1020  return merge(_orig, used);
1021  else
1022  {
1023  RLPStream r(17);
1024  for (byte i = 0; i < 16; ++i)
1025  r << _orig[i];
1026  r << "";
1027  return r.out();
1028  }
1029  }
1030  else
1031  {
1032  // not exactly our node - delve to next level at the correct index.
1033  RLPStream r(17);
1034  byte n = _k[0];
1035  for (byte i = 0; i < 17; ++i)
1036  if (i == n)
1037  if (!deleteAtAux(r, _orig[i], _k.mid(1))) // bomb out if the key didn't turn up.
1038  return bytes();
1039  else {}
1040  else
1041  r << _orig[i];
1042 
1043  // Kill the node.
1044  killNode(_orig);
1045 
1046  // check if we ended up leaving the node invalid.
1047  RLP rlp(r.out());
1048  byte used = uniqueInUse(rlp, 255);
1049  if (used == 255) // no - all ok.
1050  return r.out();
1051 
1052  // yes; merge
1053  if (isTwoItemNode(rlp[used]))
1054  {
1055  auto merged = merge(rlp, used);
1056  return graft(RLP(merged));
1057  }
1058  else
1059  return merge(rlp, used);
1060  }
1061  }
1062 
1063 }
1064 
1065 template <class DB> bool GenericTrieDB<DB>::deleteAtAux(RLPStream& _out, RLP const& _orig, NibbleSlice _k)
1066 {
1067 
1068  bytes b = _orig.isEmpty() ? bytes() : deleteAt(_orig.isList() ? _orig : RLP(node(_orig.toHash<h256>())), _k);
1069 
1070  if (!b.size()) // not found - no change.
1071  return false;
1072 
1073 /* if (_orig.isList())
1074  killNode(_orig);
1075  else
1076  killNode(_orig.toHash<h256>());*/
1077 
1078  streamNode(_out, b);
1079  return true;
1080 }
1081 
1082 template <class DB> bytes GenericTrieDB<DB>::place(RLP const& _orig, NibbleSlice _k, bytesConstRef _s)
1083 {
1084 #if ETH_PARANOIA
1085  tdebug << "place " << _orig << _k;
1086 #endif
1087 
1088  killNode(_orig);
1089  if (_orig.isEmpty())
1090  return rlpList(hexPrefixEncode(_k, true), _s);
1091 
1092  assert(_orig.isList() && (_orig.itemCount() == 2 || _orig.itemCount() == 17));
1093  if (_orig.itemCount() == 2)
1094  return rlpList(_orig[0], _s);
1095 
1096  auto s = RLPStream(17);
1097  for (unsigned i = 0; i < 16; ++i)
1098  s << _orig[i];
1099  s << _s;
1100  return s.out();
1101 }
1102 
1103 // in1: [K, S] (DEL)
1104 // out1: null
1105 // in2: [V0, ..., V15, S] (DEL)
1106 // out2: [V0, ..., V15, null] iff exists i: !!Vi -- OR -- null otherwise
1107 template <class DB> bytes GenericTrieDB<DB>::remove(RLP const& _orig)
1108 {
1109 #if ETH_PARANOIA
1110  tdebug << "kill " << _orig;
1111 #endif
1112 
1113  killNode(_orig);
1114 
1115  assert(_orig.isList() && (_orig.itemCount() == 2 || _orig.itemCount() == 17));
1116  if (_orig.itemCount() == 2)
1117  return RLPNull;
1118  RLPStream r(17);
1119  for (unsigned i = 0; i < 16; ++i)
1120  r << _orig[i];
1121  r << "";
1122  return r.out();
1123 }
1124 
1125 template <class DB> RLPStream& GenericTrieDB<DB>::streamNode(RLPStream& _s, bytes const& _b)
1126 {
1127  if (_b.size() < 32)
1128  _s.appendRaw(_b);
1129  else
1130  _s.append(forceInsertNode(&_b));
1131  return _s;
1132 }
1133 
1134 template <class DB> bytes GenericTrieDB<DB>::cleve(RLP const& _orig, unsigned _s)
1135 {
1136 #if ETH_PARANOIA
1137  tdebug << "cleve " << _orig << _s;
1138 #endif
1139 
1140  killNode(_orig);
1141  assert(_orig.isList() && _orig.itemCount() == 2);
1142  auto k = keyOf(_orig);
1143  assert(_s && _s <= k.size());
1144 
1145  RLPStream bottom(2);
1146  bottom << hexPrefixEncode(k, isLeaf(_orig), /*ugh*/(int)_s) << _orig[1];
1147 
1148  RLPStream top(2);
1149  top << hexPrefixEncode(k, false, 0, /*ugh*/(int)_s);
1150  streamNode(top, bottom.out());
1151 
1152  return top.out();
1153 }
1154 
1155 template <class DB> bytes GenericTrieDB<DB>::graft(RLP const& _orig)
1156 {
1157 #if ETH_PARANOIA
1158  tdebug << "graft " << _orig;
1159 #endif
1160 
1161  assert(_orig.isList() && _orig.itemCount() == 2);
1162  std::string s;
1163  RLP n;
1164  if (_orig[1].isList())
1165  n = _orig[1];
1166  else
1167  {
1168  // remove second item from the trie after derefrencing it into s & n.
1169  auto lh = _orig[1].toHash<h256>();
1170  s = node(lh);
1171  forceKillNode(lh);
1172  n = RLP(s);
1173  }
1174  assert(n.itemCount() == 2);
1175 
1176  return rlpList(hexPrefixEncode(keyOf(_orig), keyOf(n), isLeaf(n)), n[1]);
1177 // auto ret =
1178 // std::cout << keyOf(_orig) << " ++ " << keyOf(n) << " == " << keyOf(RLP(ret)) << std::endl;
1179 // return ret;
1180 }
1181 
1182 template <class DB> bytes GenericTrieDB<DB>::merge(RLP const& _orig, byte _i)
1183 {
1184 #if ETH_PARANOIA
1185  tdebug << "merge " << _orig << (int)_i;
1186 #endif
1187 
1188  assert(_orig.isList() && _orig.itemCount() == 17);
1189  RLPStream s(2);
1190  if (_i != 16)
1191  {
1192  assert(!_orig[_i].isEmpty());
1193  s << hexPrefixEncode(bytesConstRef(&_i, 1), false, 1, 2, 0);
1194  }
1195  else
1196  s << hexPrefixEncode(bytes(), true);
1197  s << _orig[_i];
1198  return s.out();
1199 }
1200 
1201 template <class DB> bytes GenericTrieDB<DB>::branch(RLP const& _orig)
1202 {
1203 #if ETH_PARANOIA
1204  tdebug << "branch " << _orig;
1205 #endif
1206 
1207  assert(_orig.isList() && _orig.itemCount() == 2);
1208  killNode(_orig);
1209 
1210  auto k = keyOf(_orig);
1211  RLPStream r(17);
1212  if (k.size() == 0)
1213  {
1214  assert(isLeaf(_orig));
1215  for (unsigned i = 0; i < 16; ++i)
1216  r << "";
1217  r << _orig[1];
1218  }
1219  else
1220  {
1221  byte b = k[0];
1222  for (unsigned i = 0; i < 16; ++i)
1223  if (i == b)
1224  if (isLeaf(_orig) || k.size() > 1)
1225  streamNode(r, rlpList(hexPrefixEncode(k.mid(1), isLeaf(_orig)), _orig[1]));
1226  else
1227  r << _orig[1];
1228  else
1229  r << "";
1230  r << "";
1231  }
1232  return r.out();
1233 }
1234 
1235 }
bool check(bool _requireNoLeftOvers) const
Used for debugging, scans the whole trie.
Definition: TrieDB.h:219
union node node
bool operator!=(Node const &_c) const
Definition: TrieDB.h:148
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
Definition: Arith256.cpp:15
value_type operator*() const
Definition: TrieDB.h:347
Verification
Definition: TrieDB.h:43
void killNode(RLP const &_d, h256 const &_h)
Definition: TrieDB.h:302
GenericTrieDB(DB *_db, h256 const &_root, Verification _v=Verification::Normal)
Definition: TrieDB.h:70
std::string toHex(T const &_data, int _w=2, HexPrefix _prefix=HexPrefix::DontAdd)
Definition: CommonData.h:54
void forceInsertNode(h256 const &_h, bytesConstRef _v)
Definition: TrieDB.h:294
bool isNull() const
No value.
Definition: RLP.h:103
std::string at(bytesConstRef _key) const
Definition: TrieDB.h:393
uint8_t byte
Definition: Common.h:57
iterator end() const
Definition: TrieDB.h:354
void debugStructure(std::ostream &_out) const
Used for debugging, scans the whole trie.
Definition: TrieDB.h:212
void descendKey(h256 const &_k, h256Hash &_keyMask, bool _wasExt, std::ostream *_out, int _indent=0) const
Used for debugging, scans the whole trie.
Definition: TrieDB.h:162
iterator(HashedGenericTrieDB const *)
Definition: TrieDB.h:405
bool operator==(Node const &_c) const
Definition: TrieDB.h:147
iterator(Generic const *_db, bytesConstRef _k)
Definition: TrieDB.h:345
bool isList() const
List value.
Definition: RLP.h:112
bytes rlp(_T _t)
Export a single item in RLP format, returning a byte array.
Definition: RLP.h:467
value_type at() const
Definition: TrieDB.h:415
iterator(FatGenericTrieDB const *_trie)
Definition: TrieDB.h:462
bytesConstRef data() const
The bare data of the RLP.
Definition: RLP.h:97
Definition: util.h:95
Merkle Patricia Tree "Trie": a modifed base-16 Radix tree.
Definition: TrieDB.h:64
size_t itemCount() const
Definition: RLP.h:118
RLPStream & append(unsigned _s)
Append given datum to the byte stream.
Definition: RLP.h:395
static const char * name()
Definition: TrieDB.cpp:31
std::string at(bytesConstRef _key) const
Definition: TrieDB.h:444
#define h(i)
Definition: sha.cpp:736
std::string hexPrefixEncode(bytes const &_hexVector, bool _leaf, int _begin, int _end)
Definition: TrieCommon.cpp:43
bytes const & out() const
Read the byte stream.
Definition: RLP.h:433
bool contains(bytesConstRef _key)
Definition: TrieDB.h:445
h256Hash leftOvers(std::ostream *_out=nullptr) const
Used for debugging, scans the whole trie.
Definition: TrieDB.h:204
void mergeAtAux(RLPStream &_out, RLP const &_replace, NibbleSlice _key, bytesConstRef _value)
Definition: TrieDB.h:914
unsigned size() const
Definition: TrieCommon.h:59
void descendEntry(RLP const &_r, h256Hash &_keyMask, bool _wasExt, std::ostream *_out, int _indent) const
Used for debugging, scans the whole trie.
Definition: TrieDB.h:171
bool isNull() const
True if the trie is uninitialised (i.e. that the DB doesn&#39;t contain the root node).
Definition: TrieDB.h:95
std::string atAux(RLP const &_here, NibbleSlice _key) const
Definition: TrieDB.h:801
void open(DB *_db, h256 const &_root, Verification _v=Verification::Normal)
Definition: TrieDB.h:74
typename GenericTrieDB< _DB >::iterator Super
Definition: TrieDB.h:482
bytes merge(RLP const &_orig, byte _i)
Definition: TrieDB.h:1182
#define c(i)
h256 const EmptyTrie
Definition: OverlayDB.cpp:33
bool operator==(iterator const &) const
Definition: TrieDB.h:412
bool operator!=(iterator const &_c) const
Definition: TrieDB.h:127
iterator lower_bound(bytesConstRef) const
Definition: TrieDB.h:419
assert(len-trim+(2 *lenIndices)<=WIDTH)
Different view on a GenericTrieDB that can use different key types.
Definition: TrieDB.h:320
void insert(bytesConstRef _key, bytesConstRef _value)
Definition: TrieDB.h:446
void forceKillNode(h256 const &_h)
Definition: TrieDB.h:295
std::string toString(string32 const &_s)
Make normal string from fixed-length string.
Definition: CommonData.cpp:141
bool isData() const
String value.
Definition: RLP.h:109
vector_ref< _T > cropped(size_t _begin, size_t _count) const
Definition: vector_ref.h:62
ExecStats::duration min
Definition: ExecStats.cpp:35
std::pair< bytesConstRef, bytesConstRef > value_type
Definition: TrieDB.h:402
FatGenericTrieDB(DB *_db=nullptr)
Definition: TrieDB.h:430
const h256 c_shaNull
Definition: TrieDB.cpp:28
HashedGenericTrieDB(DB *_db=nullptr)
Definition: TrieDB.h:374
value_type operator->() const
Definition: TrieDB.h:410
bool isLeaf(RLP const &_twoItem)
Definition: TrieCommon.h:96
bytes graft(RLP const &_orig)
Definition: TrieDB.h:1155
bool operator==(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
Definition: asn.h:558
bool operator==(iterator const &_c) const
Definition: TrieDB.h:126
std::string escaped(std::string const &_s, bool _all=true)
Escapes a string into the C-string representation.
Definition: CommonData.cpp:60
bytes mergeAt(RLP const &_replace, NibbleSlice _k, bytesConstRef _v, bool _inLine=false)
Definition: TrieDB.h:833
void insert(bytesConstRef _key, bytesConstRef _value)
Definition: TrieDB.h:395
bool contains(bytesConstRef _key)
Definition: TrieDB.h:110
bytes RLPNull
The empty string in RLP format.
Definition: RLP.cpp:26
bool deleteAtAux(RLPStream &_out, RLP const &_replace, NibbleSlice _key)
Definition: TrieDB.h:1065
RLPStream & streamNode(RLPStream &_s, bytes const &_b)
Definition: TrieDB.h:1125
bool operator!=(iterator const &) const
Definition: TrieDB.h:413
_N toHash(int _flags=Strict) const
Definition: RLP.h:298
bool isTwoItemNode(RLP const &_n) const
Definition: TrieDB.h:947
bytes branch(RLP const &_orig)
Definition: TrieDB.h:1201
bytes cleve(RLP const &_orig, unsigned _s)
Definition: TrieDB.h:1134
void killNode(RLP const &_d)
Definition: TrieDB.h:301
Base class for all exceptions.
Definition: Exceptions.h:39
HashedGenericTrieDB(DB *_db, h256 _root, Verification _v=Verification::Normal)
Definition: TrieDB.h:375
bool empty() const
Definition: TrieCommon.h:60
NibbleSlice keyOf(bytesConstRef _hpe)
Definition: TrieCommon.h:103
iterator lower_bound(bytesConstRef _key) const
Definition: TrieDB.h:159
bool contains(T const &_t, V const &_v)
Definition: CommonData.h:379
HashedIterator(FatGenericTrieDB const *_trie)
Definition: TrieDB.h:485
std::string deref(RLP const &_n) const
Definition: TrieDB.h:953
bool contains(bytes const &_key)
Definition: TrieDB.h:109
iterator begin() const
Definition: TrieDB.h:417
h256 const & root() const
Definition: TrieDB.h:99
value_type at() const
Definition: TrieDB.h:520
iterator(Generic const *_db)
Definition: TrieDB.h:344
void insert(bytes const &_key, bytesConstRef _value)
Definition: TrieDB.h:105
SpecificTrieDB(DB *_db=nullptr)
Definition: TrieDB.h:326
iterator & operator++()
Definition: TrieDB.h:121
NibbleSlice mid(unsigned _index) const
Definition: TrieCommon.h:61
void insert(KeyType _k, bytesConstRef _value)
Definition: TrieDB.h:333
bytesConstRef payload() const
Definition: RLP.h:321
std::vector< byte > bytes
Definition: Common.h:75
std::vector< unsigned char > toBytes() const
Definition: vector_ref.h:45
vector_ref< byte const > bytesConstRef
Definition: Common.h:77
void open(DB *_db)
Definition: TrieDB.h:73
value_type operator*() const
Definition: TrieDB.h:123
std::string at(bytes const &_key) const
Definition: TrieDB.h:101
RLPStream & appendList(size_t _items)
Appends a list.
Definition: RLP.cpp:276
HashedIterator hashedEnd() const
Definition: TrieDB.h:495
value_type at() const
Definition: TrieDB.h:768
iterator begin() const
Definition: TrieDB.h:353
FixedHash< 32 > h256
Definition: FixedHash.h:340
#define cwarn
Definition: Log.h:304
std::string node(h256 const &_h) const
Definition: TrieDB.h:290
bytes place(RLP const &_orig, NibbleSlice _k, bytesConstRef _s)
Definition: TrieDB.h:1082
bytes deleteAt(RLP const &_replace, NibbleSlice _k)
Definition: TrieDB.h:958
unsigned shared(NibbleSlice _k) const
Definition: TrieCommon.h:67
#define b(i, j)
size_t size() const
Definition: vector_ref.h:55
bytes rlpList()
Export a list of items in RLP format, returning a byte array.
Definition: RLP.h:470
h256 forceInsertNode(bytesConstRef _v)
Definition: TrieDB.h:293
std::pair< bytesConstRef, bytesConstRef > value_type
Definition: TrieDB.h:115
void insert(KeyType _k, bytes const &_value)
Definition: TrieDB.h:334
typename Generic::iterator Super
Definition: TrieDB.h:340
Nibble-based view on a bytesConstRef.
Definition: TrieCommon.h:52
uint8_t const size_t const size
Definition: sha3.h:20
static const int verbosity
Definition: TrieDB.h:36
bool isEmpty() const
True if the trie is initialised but empty (i.e. that the DB contains the root node which is empty)...
Definition: TrieDB.h:97
void * memcpy(void *a, const void *b, size_t c)
#define tdebug
Definition: TrieDB.h:37
void remove(bytes const &_key)
Definition: TrieDB.h:107
byte uniqueInUse(RLP const &_orig, byte except)
Definition: TrieCommon.cpp:113
iterator end() const
Definition: TrieDB.h:418
bool sha3(bytesConstRef _input, bytesRef o_output)
Calculate SHA3-256 hash of the given input and load it into the given output.
Definition: SHA3.cpp:214
value_type operator*() const
Definition: TrieDB.h:409
iterator end() const
Definition: TrieDB.h:157
_KeyType KeyType
Definition: TrieDB.h:324
Super::value_type at() const
Definition: TrieDB.h:464
std::string toString(int _flags=LaissezFaire) const
Converts to string.
Definition: RLP.h:199
SpecificTrieDB(DB *_db, h256 _root, Verification _v=Verification::Normal)
Definition: TrieDB.h:327
iterator end() const
Definition: TrieDB.h:476
void insert(bytesConstRef _key, bytes const &_value)
Definition: TrieDB.h:104
GenericTrieDB< DB > const * m_that
Definition: TrieDB.h:153
void setRoot(h256 const &_root, Verification _v=Verification::Normal)
Definition: TrieDB.h:78
std::string at(KeyType _k) const
Definition: TrieDB.h:332
void descendList(RLP const &_r, h256Hash &_keyMask, bool _wasExt, std::ostream *_out, int _indent) const
Used for debugging, scans the whole trie.
Definition: TrieDB.h:182
bool contains(bytesConstRef _key)
Definition: TrieDB.h:394
The default logging channels.
Definition: Log.h:130
std::unordered_set< h256 > h256Hash
Definition: FixedHash.h:349
DB const * db() const
Get the underlying database.
Definition: TrieDB.h:235
bool isEarlierThan(NibbleSlice _k) const
Determine if we, a full key, are situated prior to a particular key-prefix.
Definition: TrieCommon.h:73
bool isEmpty() const
Contains a zero-length string or zero-length list.
Definition: RLP.h:106
typename GenericTrieDB< _DB >::iterator Super
Definition: TrieDB.h:459
void insert(bytes const &_key, bytes const &_value)
Definition: TrieDB.h:103
std::vector< Node > m_trail
Definition: TrieDB.h:152
value_type operator->() const
Definition: TrieDB.h:348
std::string operator[](KeyType _k) const
Definition: TrieDB.h:329
bool contains(KeyType _k) const
Definition: TrieDB.h:331
iterator begin() const
Definition: TrieDB.h:156
Class for writing to an RLP bytestream.
Definition: RLP.h:383
RLPStream & appendRaw(bytesConstRef _rlp, size_t _itemCount=1)
Appends raw (pre-serialised) RLP data. Use with caution.
Definition: RLP.cpp:230
std::pair< KeyType, bytesConstRef > value_type
Definition: TrieDB.h:341
Class for interpreting Recursive Linear-Prefix Data.
Definition: RLP.h:64
FatGenericTrieDB(DB *_db, h256 _root, Verification _v=Verification::Normal)
Definition: TrieDB.h:431
iterator begin() const
Definition: TrieDB.h:475
value_type operator->() const
Definition: TrieDB.h:124
std::string toString() const
Definition: vector_ref.h:46
GenericTrieDB(DB *_db=nullptr)
Definition: TrieDB.h:69
void setChild(unsigned _i)
Definition: TrieDB.h:143
size_t size() const
Definition: RLP.h:122
bool contains(NibbleSlice _k) const
Definition: TrieCommon.h:65
iterator lower_bound(KeyType _k) const
Definition: TrieDB.h:355
HashedIterator hashedBegin() const
Definition: TrieDB.h:494
iterator(HashedGenericTrieDB const *, bytesConstRef)
Definition: TrieDB.h:406