Ethereum  PoC-8
The C++ Implementation of Ethereum
OverlayDB.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 <thread>
19 #include <libdevcore/db.h>
20 #include <libdevcore/Common.h>
21 #include "SHA3.h"
22 #include "OverlayDB.h"
23 #include "TrieDB.h"
24 
25 namespace dev
26 {
27 namespace
28 {
29 inline db::Slice toSlice(h256 const& _h)
30 {
31  return db::Slice(reinterpret_cast<char const*>(_h.data()), _h.size);
32 }
33 
34 inline db::Slice toSlice(std::string const& _str)
35 {
36  return db::Slice(_str.data(), _str.size());
37 }
38 
39 inline db::Slice toSlice(bytes const& _b)
40 {
41  return db::Slice(reinterpret_cast<char const*>(&_b[0]), _b.size());
42 }
43 
44 } // namespace
45 
46 OverlayDB::~OverlayDB() = default;
47 
49 {
50  if (m_db)
51  {
52  auto writeBatch = m_db->createWriteBatch();
53 // cnote << "Committing nodes to disk DB:";
54 #if DEV_GUARDED_DB
55  DEV_READ_GUARDED(x_this)
56 #endif
57  {
58  for (auto const& i: m_main)
59  {
60  if (i.second.second)
61  writeBatch->insert(toSlice(i.first), toSlice(i.second.first));
62 // cnote << i.first << "#" << m_main[i.first].second;
63  }
64  for (auto const& i: m_aux)
65  if (i.second.second)
66  {
67  bytes b = i.first.asBytes();
68  b.push_back(255); // for aux
69  writeBatch->insert(toSlice(b), toSlice(i.second.first));
70  }
71  }
72 
73  for (unsigned i = 0; i < 10; ++i)
74  {
75  try
76  {
77  m_db->commit(std::move(writeBatch));
78  break;
79  }
80  catch (boost::exception const& ex)
81  {
82  if (i == 9)
83  {
84  cwarn << "Fail writing to state database. Bombing out.";
85  exit(-1);
86  }
87  cwarn << "Error writing to state database: " << boost::diagnostic_information(ex);
88  cwarn << "Sleeping for" << (i + 1) << "seconds, then retrying.";
89  std::this_thread::sleep_for(std::chrono::seconds(i + 1));
90  }
91  }
92 #if DEV_GUARDED_DB
93  DEV_WRITE_GUARDED(x_this)
94 #endif
95  {
96  m_aux.clear();
97  m_main.clear();
98  }
99  }
100 }
101 
103 {
104  bytes ret = StateCacheDB::lookupAux(_h);
105  if (!ret.empty() || !m_db)
106  return ret;
107 
108  bytes b = _h.asBytes();
109  b.push_back(255); // for aux
110  std::string const v = m_db->lookup(toSlice(b));
111  if (v.empty())
112  cwarn << "Aux not found: " << _h;
113 
114  return asBytes(v);
115 }
116 
118 {
119 #if DEV_GUARDED_DB
120  WriteGuard l(x_this);
121 #endif
122  m_main.clear();
123 }
124 
125 std::string OverlayDB::lookup(h256 const& _h) const
126 {
127  std::string ret = StateCacheDB::lookup(_h);
128  if (!ret.empty() || !m_db)
129  return ret;
130 
131  return m_db->lookup(toSlice(_h));
132 }
133 
134 bool OverlayDB::exists(h256 const& _h) const
135 {
136  if (StateCacheDB::exists(_h))
137  return true;
138  return m_db && m_db->exists(toSlice(_h));
139 }
140 
141 void OverlayDB::kill(h256 const& _h)
142 {
143 #if ETH_PARANOIA || 1
144  if (!StateCacheDB::kill(_h))
145  {
146  if (m_db)
147  {
148  if (!m_db->exists(toSlice(_h)))
149  {
150  // No point node ref decreasing for EmptyTrie since we never bother incrementing it
151  // in the first place for empty storage tries.
152  if (_h != EmptyTrie)
153  cnote << "Decreasing DB node ref count below zero with no DB node. Probably "
154  "have a corrupt Trie."
155  << _h;
156  // TODO: for 1.1: ref-counted triedb.
157  }
158  }
159  }
160 #else
161  StateCacheDB::kill(_h);
162 #endif
163 }
164 
165 }
dev::EmptyTrie
h256 const EmptyTrie
Definition: TrieCommon.cpp:28
dev::OverlayDB::rollback
void rollback()
Definition: OverlayDB.cpp:117
dev::OverlayDB::~OverlayDB
~OverlayDB()
dev::StateCacheDB::exists
bool exists(h256 const &_h) const
Definition: StateCacheDB.cpp:68
dev::h256
FixedHash< 32 > h256
Definition: FixedHash.h:356
dev::StateCacheDB::lookup
std::string lookup(h256 const &_h) const
Definition: StateCacheDB.cpp:52
dev::OverlayDB::exists
bool exists(h256 const &_h) const
Definition: OverlayDB.cpp:134
db.h
dev::FixedHash< 32 >
dev::OverlayDB::commit
void commit()
Definition: OverlayDB.cpp:48
dev::OverlayDB::lookupAux
bytes lookupAux(h256 const &_h) const
Definition: OverlayDB.cpp:102
dev::WriteGuard
boost::unique_lock< boost::shared_mutex > WriteGuard
Definition: Guards.h:47
TrieDB.h
cnote
#define cnote
Common.h
dev::OverlayDB::lookup
std::string lookup(h256 const &_h) const
Definition: OverlayDB.cpp:125
DEV_WRITE_GUARDED
#define DEV_WRITE_GUARDED(MUTEX)
Definition: Guards.h:136
dev::bytes
std::vector< byte > bytes
Definition: Common.h:72
SHA3.h
dev::StateCacheDB::kill
bool kill(h256 const &_h)
Definition: StateCacheDB.cpp:97
dev::OverlayDB::kill
void kill(h256 const &_h)
Definition: OverlayDB.cpp:141
dev::StateCacheDB::m_aux
std::unordered_map< h256, std::pair< bytes, bool > > m_aux
Definition: StateCacheDB.h:62
DEV_READ_GUARDED
#define DEV_READ_GUARDED(MUTEX)
Definition: Guards.h:134
dev::asBytes
bytes asBytes(std::string const &_b)
Converts a string to a byte array containing the string's (byte) data.
Definition: CommonData.h:106
OverlayDB.h
dev::StateCacheDB::m_main
std::unordered_map< h256, std::pair< std::string, unsigned > > m_main
Definition: StateCacheDB.h:61
dev::StateCacheDB::lookupAux
bytes lookupAux(h256 const &_h) const
Definition: StateCacheDB.cpp:126
dev
Definition: Address.cpp:21
cwarn
#define cwarn
dev::FixedHash::asBytes
bytes asBytes() const
Definition: FixedHash.h:150
dev::eth::toSlice
db::Slice toSlice(h256 const &_h, unsigned _sub=0)
Definition: BlockChain.cpp:78
dev::db::Slice
vector_ref< char const > Slice
Definition: dbfwd.h:26