Ethereum  PoC-8
The C++ Implementation of Ethereum
StateImporter.cpp
Go to the documentation of this file.
1 /*
2  This file is part of cpp-ethereum.
3 
4  cpp-ethereum is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  cpp-ethereum is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
16 */
17 
18 #include "StateImporter.h"
19 
20 #include <libdevcore/OverlayDB.h>
21 #include <libdevcore/RLP.h>
22 #include <libdevcore/TrieDB.h>
23 
24 namespace dev
25 {
26 namespace eth
27 {
28 
29 namespace
30 {
31 
32 class StateImporter: public StateImporterFace
33 {
34 public:
35  explicit StateImporter(OverlayDB& _stateDb): m_trie(&_stateDb) { m_trie.init(); }
36 
37  void importAccount(h256 const& _addressHash, u256 const& _nonce, u256 const& _balance, std::map<h256, bytes> const& _storage, h256 const& _codeHash) override
38  {
39  RLPStream s(4);
40  s << _nonce << _balance;
41 
42  h256 const storageRoot = isAccountImported(_addressHash) ? accountStorageRoot(_addressHash) : EmptyTrie;
43  if (_storage.empty())
44  s.append(storageRoot);
45  else
46  {
47  SpecificTrieDB<GenericTrieDB<OverlayDB>, h256> storageDB(m_trie.db(), storageRoot);
48  for (auto const& hashAndValue: _storage)
49  storageDB.insert(hashAndValue.first, hashAndValue.second);
50 
51  s.append(storageDB.root());
52  }
53 
54  s << _codeHash;
55 
56  m_trie.insert(_addressHash, &s.out());
57  }
58 
59  h256 importCode(bytesConstRef _code) override
60  {
61  h256 const hash = sha3(_code);
62  m_trie.db()->insert(hash, _code);
63  return hash;
64  }
65 
66  void commitStateDatabase() override { m_trie.db()->commit(); }
67 
68  bool isAccountImported(h256 const& _addressHash) const override { return m_trie.contains(_addressHash); }
69 
70  h256 stateRoot() const override { return m_trie.root(); }
71 
72  std::string lookupCode(h256 const& _hash) const override { return m_trie.db()->lookup(_hash); }
73 
74 private:
75  // can be used only with already imported accounts
76  h256 accountStorageRoot(h256 const& _addressHash) const
77  {
78  std::string const account = m_trie.at(_addressHash);
79  assert(!account.empty());
80 
81  RLP accountRlp(account);
82  if (accountRlp.itemCount() < 3)
83  BOOST_THROW_EXCEPTION(InvalidAccountInTheDatabase());
84 
85  return accountRlp[2].toHash<h256>(RLP::VeryStrict);
86  }
87 
88  SpecificTrieDB<GenericTrieDB<OverlayDB>, h256> m_trie;
89 };
90 
91 }
92 
93 std::unique_ptr<StateImporterFace> createStateImporter(OverlayDB& _stateDb)
94 {
95  return std::unique_ptr<StateImporterFace>(new StateImporter(_stateDb));
96 }
97 
98 }
99 }
dev::EmptyTrie
h256 const EmptyTrie
Definition: TrieCommon.cpp:28
dev::RLP::VeryStrict
@ VeryStrict
Definition: RLP.h:58
dev::sha3
bool sha3(bytesConstRef _input, bytesRef o_output) noexcept
Definition: SHA3.cpp:28
dev::h256
FixedHash< 32 > h256
Definition: FixedHash.h:356
TrieDB.h
StateImporter.h
dev::bytesConstRef
vector_ref< byte const > bytesConstRef
Definition: Common.h:74
dev::OverlayDB
Definition: OverlayDB.h:34
OverlayDB.h
dev::u256
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void > > u256
Definition: Common.h:121
dev
Definition: Address.cpp:21
dev::eth::createStateImporter
std::unique_ptr< StateImporterFace > createStateImporter(OverlayDB &_stateDb)
Definition: StateImporter.cpp:93
RLP.h