Ethereum  PoC-8
The C++ Implementation of Ethereum
StateCacheDB.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 "StateCacheDB.h"
19 #include "Common.h"
20 #include "CommonData.h"
21 using namespace std;
22 using namespace dev;
23 
24 namespace dev
25 {
26 
27 std::unordered_map<h256, std::string> StateCacheDB::get() const
28 {
29 #if DEV_GUARDED_DB
30  ReadGuard l(x_this);
31 #endif
32  std::unordered_map<h256, std::string> ret;
33  for (auto const& i: m_main)
34  if (!m_enforceRefs || i.second.second > 0)
35  ret.insert(make_pair(i.first, i.second.first));
36  return ret;
37 }
38 
39 StateCacheDB& StateCacheDB::operator=(StateCacheDB const& _c)
40 {
41  if (this == &_c)
42  return *this;
43 #if DEV_GUARDED_DB
44  ReadGuard l(_c.x_this);
45  WriteGuard l2(x_this);
46 #endif
47  m_main = _c.m_main;
48  m_aux = _c.m_aux;
49  return *this;
50 }
51 
52 std::string StateCacheDB::lookup(h256 const& _h) const
53 {
54 #if DEV_GUARDED_DB
55  ReadGuard l(x_this);
56 #endif
57  auto it = m_main.find(_h);
58  if (it != m_main.end())
59  {
60  if (!m_enforceRefs || it->second.second > 0)
61  return it->second.first;
62  else
63  cwarn << "Lookup required for value with refcount == 0. This is probably a critical trie issue" << _h;
64  }
65  return std::string();
66 }
67 
68 bool StateCacheDB::exists(h256 const& _h) const
69 {
70 #if DEV_GUARDED_DB
71  ReadGuard l(x_this);
72 #endif
73  auto it = m_main.find(_h);
74  if (it != m_main.end() && (!m_enforceRefs || it->second.second > 0))
75  return true;
76  return false;
77 }
78 
79 void StateCacheDB::insert(h256 const& _h, bytesConstRef _v)
80 {
81 #if DEV_GUARDED_DB
82  WriteGuard l(x_this);
83 #endif
84  auto it = m_main.find(_h);
85  if (it != m_main.end())
86  {
87  it->second.first = _v.toString();
88  it->second.second++;
89  }
90  else
91  m_main[_h] = make_pair(_v.toString(), 1);
92 #if ETH_PARANOIA
93  cdebug << "INST" << _h << "=>" << m_main[_h].second;
94 #endif
95 }
96 
97 bool StateCacheDB::kill(h256 const& _h)
98 {
99 #if DEV_GUARDED_DB
100  ReadGuard l(x_this);
101 #endif
102  if (m_main.count(_h))
103  {
104  if (m_main[_h].second > 0)
105  {
106  m_main[_h].second--;
107  return true;
108  }
109 #if ETH_PARANOIA
110  else
111  {
112  // If we get to this point, then there was probably a node in the level DB which we need to remove and which we have previously
113  // used as part of the memory-based StateCacheDB. Nothing to be worried about *as long as the node exists in the DB*.
114  cdebug << "NOKILL-WAS" << _h;
115  }
116  cdebug << "KILL" << _h << "=>" << m_main[_h].second;
117  }
118  else
119  {
120  cdebug << "NOKILL" << _h;
121 #endif
122  }
123  return false;
124 }
125 
126 bytes StateCacheDB::lookupAux(h256 const& _h) const
127 {
128 #if DEV_GUARDED_DB
129  ReadGuard l(x_this);
130 #endif
131  auto it = m_aux.find(_h);
132  if (it != m_aux.end() && (!m_enforceRefs || it->second.second))
133  return it->second.first;
134  return bytes();
135 }
136 
137 void StateCacheDB::removeAux(h256 const& _h)
138 {
139 #if DEV_GUARDED_DB
140  WriteGuard l(x_this);
141 #endif
142  m_aux[_h].second = false;
143 }
144 
145 void StateCacheDB::insertAux(h256 const& _h, bytesConstRef _v)
146 {
147 #if DEV_GUARDED_DB
148  WriteGuard l(x_this);
149 #endif
150  m_aux[_h] = make_pair(_v.toBytes(), true);
151 }
152 
153 void StateCacheDB::purge()
154 {
155 #if DEV_GUARDED_DB
156  WriteGuard l(x_this);
157 #endif
158  // purge m_main
159  for (auto it = m_main.begin(); it != m_main.end(); )
160  if (it->second.second)
161  ++it;
162  else
163  it = m_main.erase(it);
164 
165  // purge m_aux
166  for (auto it = m_aux.begin(); it != m_aux.end(); )
167  if (it->second.second)
168  ++it;
169  else
170  it = m_aux.erase(it);
171 }
172 
173 h256Hash StateCacheDB::keys() const
174 {
175 #if DEV_GUARDED_DB
176  ReadGuard l(x_this);
177 #endif
178  h256Hash ret;
179  for (auto const& i: m_main)
180  if (i.second.second)
181  ret.insert(i.first);
182  return ret;
183 }
184 
185 }
dev::vector_ref< byte const >
dev::FixedHash< 32 >
StateCacheDB.h
dev::WriteGuard
boost::unique_lock< boost::shared_mutex > WriteGuard
Definition: Guards.h:47
Common.h
dev::h256Hash
std::unordered_set< h256 > h256Hash
Definition: FixedHash.h:365
dev::bytes
std::vector< byte > bytes
Definition: Common.h:72
dev::vector_ref::toString
std::string toString() const
Definition: vector_ref.h:44
dev::ReadGuard
boost::shared_lock< boost::shared_mutex > ReadGuard
Definition: Guards.h:44
cdebug
#define cdebug
CommonData.h
dev::StateCacheDB::m_aux
std::unordered_map< h256, std::pair< bytes, bool > > m_aux
Definition: StateCacheDB.h:62
dev::vector_ref::toBytes
std::vector< unsigned char > toBytes() const
Definition: vector_ref.h:43
std
Definition: FixedHash.h:393
dev::StateCacheDB::m_main
std::unordered_map< h256, std::pair< std::string, unsigned > > m_main
Definition: StateCacheDB.h:61
dev::StateCacheDB
Definition: StateCacheDB.h:27
dev
Definition: Address.cpp:21
cwarn
#define cwarn