75 if (m_root ==
EmptyTrie && !m_db->exists(m_root))
79 if (!node(m_root).size())
80 BOOST_THROW_EXCEPTION(RootNotFound());
84 bool isNull()
const {
return !node(m_root).size(); }
90 if (node(m_root).empty())
95 std::string
at(
bytes const& _key)
const {
return at(&_key); }
137 void setChild(
unsigned _i) { child = _i; }
138 void setFirstChild() { child = 16; }
139 void incrementChild() { child = child == 16 ? 0 : child == 15 ? 17 : (child + 1); }
141 bool operator==(Node
const& _c)
const {
return rlp == _c.rlp && key == _c.key && child == _c.child; }
150 iterator
begin()
const {
return iterator(
this); }
151 iterator
end()
const {
return iterator(); }
161 std::string
const s = node(_k);
168 RLP const& _r,
h256Hash& _keyMask,
bool _wasExt, std::ostream* _out,
int _indent)
const
184 (*_out) << std::string(_indent * 2,
' ') << (_wasExt ?
"!2 " :
"2 ") <<
sha3(_r.
data()) <<
": " << _r <<
"\n";
191 (*_out) << std::string(_indent * 2,
' ') <<
"17 " <<
sha3(_r.
data()) <<
": " << _r <<
"\n";
192 for (
unsigned i = 0; i < 16; ++i)
194 descendEntry(_r[i], _keyMask,
false, _out, _indent + 1);
216 bool check(
bool _requireNoLeftOvers)
const
220 return leftOvers().empty() || !_requireNoLeftOvers;
224 cwarn << boost::current_exception_diagnostic_information();
232 DB const*
db()
const {
return m_db; }
263 bytes cleve(
RLP const& _orig,
unsigned _s);
272 bytes merge(
RLP const& _orig,
byte _i);
284 bool isTwoItemNode(
RLP const& _n)
const;
285 std::string deref(
RLP const& _n)
const;
287 std::string node(
h256 const& _h)
const {
return m_db->lookup(_h); }
292 void forceKillNode(
h256 const& _h) { m_db->kill(_h); }
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); }
308 for (
auto const& i: _db)
309 _out <<
escaped(i.first.toString(),
false) <<
": " <<
escaped(i.second.toString(),
false) << std::endl;
316 template <
class Generic,
class _KeyType>
320 using DB =
typename Generic::DB;
337 using Super =
typename Generic::iterator;
350 iterator
begin()
const {
return this; }
351 iterator
end()
const {
return iterator(); }
355 template <
class Generic,
class KeyType>
358 for (
auto const& i: _db)
359 _out << i.first <<
": " <<
escaped(i.second.toString(),
false) << std::endl;
461 typename Super::value_type
at()
const
465 return std::make_pair(&m_key, std::move(hashed.second));
508 m_trail.push_back({_db->node(_db->m_root), std::string(1,
'\0'), 255});
515 m_trail.push_back({_db->node(_db->m_root), std::string(1,
'\0'), 255});
521 assert(m_trail.size());
522 Node
const& b = m_trail.back();
523 assert(b.key.size());
524 assert(!(b.key[0] & 0x10));
541 Node
const& b = m_trail.back();
544 if (m_trail.back().child == 255)
554 if (!
rlp.isList() || (
rlp.itemCount() != 2 &&
rlp.itemCount() != 17))
557 cwarn <<
"BIG FAT ERROR. STATE TRIE CORRUPTED!!!!!";
560 auto c =
rlp.itemCount();
562 BOOST_THROW_EXCEPTION(InvalidTrie());
568 if (
rlp.itemCount() == 2)
589 k = k.
mid(std::min(k.
size(), keyOfRLP.size()));
596 m_trail.back().child = 0;
606 m_trail.back().rlp = m_that->deref(
rlp[1]);
615 m_trail.back().setChild(k[0]);
619 m_trail.back().setChild(16);
626 if (!(
rlp.isList() &&
rlp.itemCount() == 17))
633 m_trail.back().incrementChild();
637 assert(
rlp.isList() &&
rlp.itemCount() == 17);
638 for (;; m_trail.back().incrementChild())
639 if (m_trail.back().child == 17)
646 else if (!
rlp[m_trail.back().child].isEmpty())
648 if (m_trail.back().child == 16)
654 Node
const& back = m_trail.back();
655 m_trail.push_back(Node{
656 m_that->deref(
rlp[back.child]),
668 template <
class DB>
void GenericTrieDB<DB>::iterator::next()
678 Node
const& b = m_trail.back();
681 if (m_trail.back().child == 255)
689 if (!(
rlp.isList() && (
rlp.itemCount() == 2 ||
rlp.itemCount() == 17)))
692 cwarn <<
"BIG FAT ERROR. STATE TRIE CORRUPTED!!!!!";
695 auto c =
rlp.itemCount();
697 BOOST_THROW_EXCEPTION(InvalidTrie());
703 if (
rlp.itemCount() == 2)
710 m_trail.back().child = 0;
715 m_trail.back().rlp = m_that->deref(
rlp[1]);
722 m_trail.back().setFirstChild();
729 if (!(
rlp.isList() &&
rlp.itemCount() == 17))
735 m_trail.back().incrementChild();
739 assert(
rlp.isList() &&
rlp.itemCount() == 17);
740 for (;; m_trail.back().incrementChild())
741 if (m_trail.back().child == 17)
747 else if (!
rlp[m_trail.back().child].isEmpty())
749 if (m_trail.back().child == 16)
755 Node
const& back = m_trail.back();
756 m_trail.push_back(Node{
757 m_that->deref(
rlp[back.child]),
769 auto p = Super::at();
771 assert(p.first.size() ==
sizeof(
KeyType));
772 memcpy(&ret.first, p.first.data(),
sizeof(
KeyType));
773 ret.second = p.second;
779 std::string rootValue = node(m_root);
780 assert(rootValue.size());
786 if (rootValue.size() < 32)
787 forceKillNode(m_root);
788 m_root = forceInsertNode(&b);
793 return atAux(
RLP(node(m_root)), _key);
800 return std::string();
802 assert(_here.
isList() && (itemCount == 2 || itemCount == 17));
805 auto k =
keyOf(_here);
806 if (_key == k &&
isLeaf(_here))
811 return atAux(_here[1].isList() ? _here[1] :
RLP(node(_here[1].toHash<h256>())), _key.
mid(k.
size()));
814 return std::string();
818 if (_key.
size() == 0)
820 auto n = _here[_key[0]];
822 return std::string();
824 return atAux(n.isList() ? n : RLP(node(n.toHash<
h256>())), _key.mid(1));
828 template <
class DB>
bytes GenericTrieDB<DB>::mergeAt(RLP
const& _orig, NibbleSlice _k,
bytesConstRef _v,
bool _inLine)
830 return mergeAt(_orig,
sha3(_orig.data()), _k, _v, _inLine);
833 template <
class DB>
bytes GenericTrieDB<DB>::mergeAt(RLP
const& _orig,
h256 const& _origHash, NibbleSlice _k,
bytesConstRef _v,
bool _inLine)
841 return place(_orig, _k, _v);
843 unsigned itemCount = _orig.itemCount();
844 assert(_orig.isList() && (itemCount == 2 || itemCount == 17));
848 NibbleSlice k =
keyOf(_orig);
851 if (k == _k &&
isLeaf(_orig))
852 return place(_orig, _k, _v);
855 if (_k.contains(k) && !
isLeaf(_orig))
858 killNode(_orig, _origHash);
861 mergeAtAux(s, _orig[1], _k.mid(k.size()), _v);
865 auto sh = _k.shared(k);
870 auto cleved = cleve(_orig, sh);
871 return mergeAt(RLP(cleved), _k, _v,
true);
876 auto branched = branch(_orig);
877 return mergeAt(RLP(branched), _k, _v,
true);
886 return place(_orig, _k, _v);
890 killNode(_orig, _origHash);
895 for (
byte i = 0; i < 17; ++i)
897 mergeAtAux(r, _orig[i], _k.mid(1), _v);
905 template <
class DB>
void GenericTrieDB<DB>::mergeAtAux(RLPStream& _out, RLP
const& _orig, NibbleSlice _k,
bytesConstRef _v)
910 bool isRemovable =
false;
911 if (!r.isList() && !r.isEmpty())
920 bytes b = mergeAt(r, _k, _v, !isRemovable);
926 std::string rv = node(m_root);
931 forceKillNode(m_root);
932 m_root = forceInsertNode(&b);
942 template <
class DB> std::string GenericTrieDB<DB>::deref(RLP
const& _n)
const
944 return _n.isList() ? _n.data().toString() : node(_n.toHash<
h256>());
947 template <
class DB>
bytes GenericTrieDB<DB>::deleteAt(RLP
const& _orig, NibbleSlice _k)
957 assert(_orig.isList() && (_orig.itemCount() == 2 || _orig.itemCount() == 17));
958 if (_orig.itemCount() == 2)
961 NibbleSlice k =
keyOf(_orig);
964 if (k == _k &&
isLeaf(_orig))
974 s.appendList(2) << _orig[0];
975 if (!deleteAtAux(s, _orig[1], _k.mid(k.size())))
979 if (isTwoItemNode(r[1]))
992 if (_k.size() == 0 && !_orig[16].isEmpty())
999 if (isTwoItemNode(_orig[used]))
1001 auto merged = merge(_orig, used);
1002 return graft(RLP(merged));
1005 return merge(_orig, used);
1009 for (
byte i = 0; i < 16; ++i)
1020 for (
byte i = 0; i < 17; ++i)
1023 if (!deleteAtAux(r, _orig[i], _k.mid(1)))
1039 if (isTwoItemNode(
rlp[used]))
1041 auto merged = merge(
rlp, used);
1042 return graft(RLP(merged));
1045 return merge(
rlp, used);
1051 template <
class DB>
bool GenericTrieDB<DB>::deleteAtAux(RLPStream& _out, RLP
const& _orig, NibbleSlice _k)
1054 bytes b = _orig.isEmpty() ?
bytes() : deleteAt(_orig.isList() ? _orig : RLP(node(_orig.toHash<
h256>())), _k);
1064 streamNode(_out, b);
1068 template <
class DB>
bytes GenericTrieDB<DB>::place(RLP
const& _orig, NibbleSlice _k,
bytesConstRef _s)
1071 if (_orig.isEmpty())
1074 assert(_orig.isList() && (_orig.itemCount() == 2 || _orig.itemCount() == 17));
1075 if (_orig.itemCount() == 2)
1078 auto s = RLPStream(17);
1079 for (
unsigned i = 0; i < 16; ++i)
1093 assert(_orig.isList() && (_orig.itemCount() == 2 || _orig.itemCount() == 17));
1094 if (_orig.itemCount() == 2)
1097 for (
unsigned i = 0; i < 16; ++i)
1103 template <
class DB> RLPStream& GenericTrieDB<DB>::streamNode(RLPStream& _s,
bytes const& _b)
1108 _s.append(forceInsertNode(&_b));
1112 template <
class DB>
bytes GenericTrieDB<DB>::cleve(RLP
const& _orig,
unsigned _s)
1115 assert(_orig.isList() && _orig.itemCount() == 2);
1116 auto k =
keyOf(_orig);
1117 assert(_s && _s <= k.size());
1119 RLPStream bottom(2);
1124 streamNode(top, bottom.out());
1129 template <
class DB>
bytes GenericTrieDB<DB>::graft(RLP
const& _orig)
1131 assert(_orig.isList() && _orig.itemCount() == 2);
1134 if (_orig[1].isList())
1139 auto lh = _orig[1].toHash<
h256>();
1144 assert(n.itemCount() == 2);
1152 template <
class DB>
bytes GenericTrieDB<DB>::merge(RLP
const& _orig,
byte _i)
1154 assert(_orig.isList() && _orig.itemCount() == 17);
1167 template <
class DB>
bytes GenericTrieDB<DB>::branch(RLP
const& _orig)
1169 assert(_orig.isList() && _orig.itemCount() == 2);
1172 auto k =
keyOf(_orig);
1177 for (
unsigned i = 0; i < 16; ++i)
1184 for (
unsigned i = 0; i < 16; ++i)
1186 if (
isLeaf(_orig) || k.size() > 1)