Ethereum  PoC-8
The C++ Implementation of Ethereum
BlockHeader.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 */
22 #include <libdevcore/Common.h>
23 #include <libdevcore/Log.h>
24 #include <libdevcore/RLP.h>
25 #include <libdevcore/TrieDB.h>
27 #include <libdevcore/TrieHash.h>
28 #include <libethcore/Common.h>
29 #include "Exceptions.h"
30 #include "BlockHeader.h"
31 using namespace std;
32 using namespace dev;
33 using namespace dev::eth;
34 
35 BlockHeader::BlockHeader()
36 {
37 }
38 
39 BlockHeader::BlockHeader(bytesConstRef _block, BlockDataType _bdt, h256 const& _hashWith)
40 {
41  RLP header = _bdt == BlockData ? extractHeader(_block) : RLP(_block);
42  m_hash = _hashWith ? _hashWith : sha3(header.data());
43  populate(header);
44 }
45 
46 BlockHeader::BlockHeader(BlockHeader const& _other) :
47  m_parentHash(_other.parentHash()),
48  m_sha3Uncles(_other.sha3Uncles()),
49  m_stateRoot(_other.stateRoot()),
50  m_transactionsRoot(_other.transactionsRoot()),
51  m_receiptsRoot(_other.receiptsRoot()),
52  m_logBloom(_other.logBloom()),
53  m_number(_other.number()),
54  m_gasLimit(_other.gasLimit()),
55  m_gasUsed(_other.gasUsed()),
56  m_extraData(_other.extraData()),
57  m_timestamp(_other.timestamp()),
58  m_author(_other.author()),
59  m_difficulty(_other.difficulty()),
60  m_seal(_other.seal()),
61  m_hash(_other.hashRawRead()),
62  m_hashWithout(_other.hashWithoutRawRead())
63 {
64  assert(*this == _other);
65 }
66 
68 {
69  if (this == &_other)
70  return *this;
71  m_parentHash = _other.parentHash();
72  m_sha3Uncles = _other.sha3Uncles();
73  m_stateRoot = _other.stateRoot();
74  m_transactionsRoot = _other.transactionsRoot();
75  m_receiptsRoot = _other.receiptsRoot();
76  m_logBloom = _other.logBloom();
77  m_number = _other.number();
78  m_gasLimit = _other.gasLimit();
79  m_gasUsed = _other.gasUsed();
80  m_extraData = _other.extraData();
81  m_timestamp = _other.timestamp();
82  m_author = _other.author();
83  m_difficulty = _other.difficulty();
84  std::vector<bytes> seal = _other.seal();
85  {
86  Guard l(m_sealLock);
87  m_seal = std::move(seal);
88  }
89  h256 hash = _other.hashRawRead();
90  h256 hashWithout = _other.hashWithoutRawRead();
91  {
92  Guard l(m_hashLock);
93  m_hash = std::move(hash);
94  m_hashWithout = std::move(hashWithout);
95  }
96  assert(*this == _other);
97  return *this;
98 }
99 
101 {
102  m_parentHash = h256();
103  m_sha3Uncles = EmptyListSHA3;
104  m_author = Address();
105  m_stateRoot = EmptyTrie;
106  m_transactionsRoot = EmptyTrie;
107  m_receiptsRoot = EmptyTrie;
108  m_logBloom = LogBloom();
109  m_difficulty = 0;
110  m_number = 0;
111  m_gasLimit = 0;
112  m_gasUsed = 0;
113  m_timestamp = -1;
114  m_extraData.clear();
115  m_seal.clear();
116  noteDirty();
117 }
118 
120 {
121  h256 dummy;
122  Guard l(m_hashLock);
123  h256& memo = _i == WithSeal ? m_hash : _i == WithoutSeal ? m_hashWithout : dummy;
124  if (!memo)
125  {
126  RLPStream s;
127  streamRLP(s, _i);
128  memo = sha3(s.out());
129  }
130  return memo;
131 }
132 
133 void BlockHeader::streamRLPFields(RLPStream& _s) const
134 {
135  _s << m_parentHash << m_sha3Uncles << m_author << m_stateRoot << m_transactionsRoot << m_receiptsRoot << m_logBloom
136  << m_difficulty << m_number << m_gasLimit << m_gasUsed << m_timestamp << m_extraData;
137 }
138 
140 {
141  if (_i != OnlySeal)
142  {
143  _s.appendList(BlockHeader::BasicFields + (_i == WithoutSeal ? 0 : m_seal.size()));
144  BlockHeader::streamRLPFields(_s);
145  }
146  if (_i != WithoutSeal)
147  for (unsigned i = 0; i < m_seal.size(); ++i)
148  _s.appendRaw(m_seal[i]);
149 }
150 
152 {
153  return sha3(RLP(_block)[0].data());
154 }
155 
157 {
158  RLP root(_block);
159  if (!root.isList())
160  BOOST_THROW_EXCEPTION(InvalidBlockFormat() << errinfo_comment("Block must be a list") << BadFieldError(0, _block.toString()));
161  RLP header = root[0];
162  if (!header.isList())
163  BOOST_THROW_EXCEPTION(InvalidBlockFormat() << errinfo_comment("Block header must be a list") << BadFieldError(0, header.data().toString()));
164  if (!root[1].isList())
165  BOOST_THROW_EXCEPTION(InvalidBlockFormat() << errinfo_comment("Block transactions must be a list") << BadFieldError(1, root[1].data().toString()));
166  if (!root[2].isList())
167  BOOST_THROW_EXCEPTION(InvalidBlockFormat() << errinfo_comment("Block uncles must be a list") << BadFieldError(2, root[2].data().toString()));
168  return header;
169 }
170 
171 void BlockHeader::populate(RLP const& _header)
172 {
173  int field = 0;
174  try
175  {
176  m_parentHash = _header[field = 0].toHash<h256>(RLP::VeryStrict);
177  m_sha3Uncles = _header[field = 1].toHash<h256>(RLP::VeryStrict);
178  m_author = _header[field = 2].toHash<Address>(RLP::VeryStrict);
179  m_stateRoot = _header[field = 3].toHash<h256>(RLP::VeryStrict);
180  m_transactionsRoot = _header[field = 4].toHash<h256>(RLP::VeryStrict);
181  m_receiptsRoot = _header[field = 5].toHash<h256>(RLP::VeryStrict);
182  m_logBloom = _header[field = 6].toHash<LogBloom>(RLP::VeryStrict);
183  m_difficulty = _header[field = 7].toInt<u256>();
184  m_number = _header[field = 8].toPositiveInt64();
185  m_gasLimit = _header[field = 9].toInt<u256>();
186  m_gasUsed = _header[field = 10].toInt<u256>();
187  m_timestamp = _header[field = 11].toPositiveInt64();
188  m_extraData = _header[field = 12].toBytes();
189  m_seal.clear();
190  for (unsigned i = 13; i < _header.itemCount(); ++i)
191  m_seal.push_back(_header[i].data().toBytes());
192  }
193  catch (Exception const& _e)
194  {
195  _e << errinfo_name("invalid block header format") << BadFieldError(field, toHex(_header[field].data().toBytes()));
196  throw;
197  }
198 }
199 
201 {
202  m_stateRoot = _parent.stateRoot();
203  m_number = _parent.m_number + 1;
204  m_parentHash = _parent.m_hash;
205  m_gasLimit = _parent.m_gasLimit;
206  m_difficulty = _parent.m_difficulty;
207  m_gasUsed = 0;
208 }
209 
210 void BlockHeader::verify(Strictness _s, BlockHeader const& _parent, bytesConstRef _block) const
211 {
212  if (m_number > ~(unsigned)0)
213  BOOST_THROW_EXCEPTION(InvalidNumber());
214 
215  if (_s != CheckNothingNew && m_gasUsed > m_gasLimit)
216  BOOST_THROW_EXCEPTION(TooMuchGasUsed() << RequirementError(bigint(m_gasLimit), bigint(m_gasUsed)));
217 
218  if (_parent)
219  {
220  if (m_parentHash && _parent.hash() != m_parentHash)
221  BOOST_THROW_EXCEPTION(InvalidParentHash());
222 
223  if (m_timestamp <= _parent.m_timestamp)
224  BOOST_THROW_EXCEPTION(InvalidTimestamp());
225 
226  if (m_number != _parent.m_number + 1)
227  BOOST_THROW_EXCEPTION(InvalidNumber());
228  }
229 
230  if (_block)
231  {
232  RLP root(_block);
233 
234  auto txList = root[1];
235  auto expectedRoot = trieRootOver(txList.itemCount(), [&](unsigned i){ return rlp(i); }, [&](unsigned i){ return txList[i].data().toBytes(); });
236 
237  LOG(m_logger) << "Expected trie root: " << toString(expectedRoot);
238  if (m_transactionsRoot != expectedRoot)
239  {
240  StateCacheDB tm;
241  GenericTrieDB<StateCacheDB> transactionsTrie(&tm);
242  transactionsTrie.init();
243 
244  vector<bytesConstRef> txs;
245 
246  for (unsigned i = 0; i < txList.itemCount(); ++i)
247  {
248  RLPStream k;
249  k << i;
250 
251  transactionsTrie.insert(&k.out(), txList[i].data());
252 
253  txs.push_back(txList[i].data());
254  cdebug << toHex(k.out()) << toHex(txList[i].data());
255  }
256  cdebug << "trieRootOver" << expectedRoot;
257  cdebug << "orderedTrieRoot" << orderedTrieRoot(txs);
258  cdebug << "TrieDB" << transactionsTrie.root();
259  cdebug << "Contents:";
260  for (auto const& t: txs)
261  cdebug << toHex(t);
262 
263  BOOST_THROW_EXCEPTION(InvalidTransactionsRoot() << Hash256RequirementError(expectedRoot, m_transactionsRoot));
264  }
265  LOG(m_logger) << "Expected uncle hash: " << toString(sha3(root[2].data()));
266  if (m_sha3Uncles != sha3(root[2].data()))
267  BOOST_THROW_EXCEPTION(InvalidUnclesHash() << Hash256RequirementError(sha3(root[2].data()), m_sha3Uncles));
268  }
269 }
dev::EmptyTrie
h256 const EmptyTrie
Definition: TrieCommon.cpp:28
dev::RLP::VeryStrict
@ VeryStrict
Definition: RLP.h:58
dev::eth::BlockHeader::hash
h256 hash(IncludeSeal _i=WithSeal) const
Definition: BlockHeader.cpp:119
dev::vector_ref< byte const >
dev::eth::BlockHeader
Encapsulation of a block header. Class to contain all of a block header's data. It is able to parse a...
Definition: BlockHeader.h:97
dev::GenericTrieDB::init
void init()
Definition: TrieDB.h:68
dev::eth::BlockHeader::sha3Uncles
h256 const & sha3Uncles() const
Definition: BlockHeader.h:158
dev::eth::BlockHeader::extraData
bytes const & extraData() const
Definition: BlockHeader.h:168
dev::sha3
bool sha3(bytesConstRef _input, bytesRef o_output) noexcept
Definition: SHA3.cpp:28
dev::trieRootOver
h256 trieRootOver(unsigned _itemCount, T const &_getKey, U const &_getValue)
Definition: TrieHash.h:36
dev::Guard
std::lock_guard< std::mutex > Guard
Definition: Guards.h:41
dev::eth::BlockHeader::stateRoot
h256 const & stateRoot() const
Definition: BlockHeader.h:162
dev::eth::BlockHeader::logBloom
LogBloom const & logBloom() const
Definition: BlockHeader.h:169
dev::h256
FixedHash< 32 > h256
Definition: FixedHash.h:356
dev::orderedTrieRoot
h256 orderedTrieRoot(std::vector< bytes > const &_data)
Definition: TrieHash.cpp:112
dev::RLPStream::out
bytes const & out() const
Read the byte stream.
Definition: RLP.h:419
Exceptions.h
dev::eth::BlockHeader::BasicFields
static const unsigned BasicFields
Definition: BlockHeader.h:100
dev::eth
Definition: BasicAuthority.h:32
dev::eth::BlockData
@ BlockData
Definition: BlockHeader.h:70
dev::eth::BlockHeader::clear
void clear()
Definition: BlockHeader.cpp:100
dev::eth::BlockHeader::verify
void verify(Strictness _s=CheckEverything, BlockHeader const &_parent=BlockHeader(), bytesConstRef _block=bytesConstRef()) const
Definition: BlockHeader.cpp:210
dev::toString
std::string toString(std::chrono::time_point< T > const &_e, std::string const &_format="%F %T")
Definition: CommonIO.h:86
BlockHeader.h
dev::RLP::isList
bool isList() const
List value.
Definition: RLP.h:95
dev::FixedHash< 32 >
dev::eth::BlockHeader::seal
T seal(unsigned _offset=0) const
Definition: BlockHeader.h:171
StateCacheDB.h
dev::eth::errinfo_name
boost::error_info< struct tag_field, std::string > errinfo_name
Definition: Exceptions.h:33
dev::Exception
Base class for all exceptions.
Definition: Exceptions.h:39
LOG
#define LOG
Definition: Log.h:63
Common.h
dev::GenericTrieDB::root
h256 const & root() const
Definition: TrieDB.h:88
dev::eth::LogBloom
h2048 LogBloom
The log bloom's size (2048-bit).
Definition: Common.h:50
TrieDB.h
Common.h
dev::eth::BadFieldError
boost::tuple< errinfo_field, errinfo_data > BadFieldError
Definition: Exceptions.h:43
dev::eth::BlockHeader::parentHash
h256 const & parentHash() const
Definition: BlockHeader.h:157
dev::eth::BlockHeader::extractHeader
static RLP extractHeader(bytesConstRef _block)
Definition: BlockHeader.cpp:156
dev::vector_ref::toString
std::string toString() const
Definition: vector_ref.h:44
dev::eth::BlockHeader::number
int64_t number() const
Definition: BlockHeader.h:166
dev::eth::BlockHeader::noteDirty
void noteDirty() const
Definition: BlockHeader.h:133
dev::eth::BlockHeader::streamRLP
void streamRLP(RLPStream &_s, IncludeSeal _i=WithSeal) const
Definition: BlockHeader.cpp:139
TrieHash.h
dev::GenericTrieDB
Merkle Patricia Tree "Trie": a modifed base-16 Radix tree. This version uses a database backend....
Definition: TrieDB.h:57
cdebug
#define cdebug
dev::GenericTrieDB::insert
void insert(bytes const &_key, bytes const &_value)
Definition: TrieDB.h:97
dev::RLP::data
bytesConstRef data() const
The bare data of the RLP.
Definition: RLP.h:80
dev::RLPStream
Class for writing to an RLP bytestream.
Definition: RLP.h:370
dev::eth::BlockHeader::transactionsRoot
h256 const & transactionsRoot() const
Definition: BlockHeader.h:163
dev::eth::BlockHeader::populateFromParent
void populateFromParent(BlockHeader const &parent)
Definition: BlockHeader.cpp:200
dev::bigint
boost::multiprecision::number< boost::multiprecision::cpp_int_backend<> > bigint
Definition: Common.h:118
dev::eth::BlockHeader::operator=
BlockHeader & operator=(BlockHeader const &_other)
Definition: BlockHeader.cpp:67
dev::RLP::itemCount
size_t itemCount() const
Definition: RLP.h:101
std
Definition: FixedHash.h:393
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::RLP::toInt
_T toInt(int _flags=Strict) const
Converts to int of type given; if isData(), decodes as big-endian bytestream.
Definition: RLP.h:257
dev::RLP::toHash
_N toHash(int _flags=Strict) const
Definition: RLP.h:288
dev::StateCacheDB
Definition: StateCacheDB.h:27
dev::Hash256RequirementError
boost::tuple< errinfo_required_h256, errinfo_got_h256 > Hash256RequirementError
Definition: Exceptions.h:92
dev::eth::BlockHeader::author
Address const & author() const
Definition: BlockHeader.h:161
dev
Definition: Address.cpp:21
dev::eth::WithSeal
@ WithSeal
Definition: BlockHeader.h:42
dev::RequirementError
boost::tuple< errinfo_required, errinfo_got > RequirementError
Definition: Exceptions.h:87
dev::eth::CheckNothingNew
@ CheckNothingNew
Definition: BlockHeader.h:51
dev::EmptyListSHA3
h256 const EmptyListSHA3
Definition: SHA3.cpp:26
dev::eth::IncludeSeal
IncludeSeal
Definition: BlockHeader.h:40
dev::eth::BlockHeader::gasLimit
u256 const & gasLimit() const
Definition: BlockHeader.h:167
dev::eth::BlockHeader::receiptsRoot
h256 const & receiptsRoot() const
Definition: BlockHeader.h:164
dev::RLP::toPositiveInt64
int64_t toPositiveInt64(int _flags=Strict) const
Definition: RLP.h:280
dev::RLPStream::appendRaw
RLPStream & appendRaw(bytesConstRef _rlp, size_t _itemCount=1)
Appends raw (pre-serialised) RLP data. Use with caution.
Definition: RLP.cpp:222
dev::eth::Strictness
Strictness
Definition: BlockHeader.h:47
dev::toHex
std::string toHex(Iterator _it, Iterator _end, std::string const &_prefix)
Definition: CommonData.h:46
dev::eth::BlockHeader::headerHashFromBlock
static h256 headerHashFromBlock(bytes const &_block)
Definition: BlockHeader.h:108
dev::RLP
Definition: RLP.h:48
dev::eth::OnlySeal
@ OnlySeal
Definition: BlockHeader.h:43
dev::Address
h160 Address
Definition: Address.h:30
dev::eth::BlockHeader::difficulty
u256 const & difficulty() const
Definition: BlockHeader.h:170
Log.h
RLP.h
dev::eth::BlockDataType
BlockDataType
Definition: BlockHeader.h:68
dev::RLPStream::appendList
RLPStream & appendList(size_t _items)
Appends a list.
Definition: RLP.cpp:268
dev::errinfo_comment
boost::error_info< struct tag_comment, std::string > errinfo_comment
Definition: Assertions.h:69
dev::eth::BlockHeader::gasUsed
u256 const & gasUsed() const
Definition: BlockHeader.h:165
dev::eth::WithoutSeal
@ WithoutSeal
Definition: BlockHeader.h:41
dev::eth::BlockHeader::timestamp
int64_t timestamp() const
Definition: BlockHeader.h:160
dev::RLP::toBytes
bytes toBytes(int _flags=LaissezFaire) const
Converts to bytearray.
Definition: RLP.h:177