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