BlockHeader.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*
  2. This file is part of cpp-ethereum.
  3. cpp-ethereum is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. cpp-ethereum is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. /** @file BlockHeader.cpp
  15. * @author Gav Wood <i@gavwood.com>
  16. * @date 2014
  17. */
  18. #include <libdevcore/Common.h>
  19. #include <libdevcore/Log.h>
  20. #include <libdevcore/RLP.h>
  21. #include <libdevcore/TrieDB.h>
  22. #include <libdevcore/TrieHash.h>
  23. #include <libethcore/Common.h>
  24. #include "Exceptions.h"
  25. #include "BlockHeader.h"
  26. using namespace std;
  27. using namespace dev;
  28. using namespace dev::eth;
  29. BlockHeader::BlockHeader()
  30. {
  31. }
  32. BlockHeader::BlockHeader(bytesConstRef _block, BlockDataType _bdt, h256 const& _hashWith)
  33. {
  34. RLP header = _bdt == BlockData ? extractHeader(_block) : RLP(_block);
  35. m_hash = _hashWith ? _hashWith : sha3(header.data());
  36. populate(header);
  37. }
  38. void BlockHeader::clear()
  39. {
  40. m_parentHash = h256();
  41. m_sha3Uncles = EmptyListSHA3;
  42. m_author = Address();
  43. m_stateRoot = EmptyTrie;
  44. m_transactionsRoot = EmptyTrie;
  45. m_receiptsRoot = EmptyTrie;
  46. m_logBloom = LogBloom();
  47. m_difficulty = 0;
  48. m_number = 0;
  49. m_gasLimit = 0;
  50. m_gasUsed = 0;
  51. m_timestamp = Invalid256;
  52. m_extraData.clear();
  53. m_seal.clear();
  54. noteDirty();
  55. }
  56. h256 BlockHeader::hash(IncludeSeal _i) const
  57. {
  58. h256 dummy;
  59. h256& memo = _i == WithSeal ? m_hash : _i == WithoutSeal ? m_hashWithout : dummy;
  60. if (!memo)
  61. {
  62. RLPStream s;
  63. streamRLP(s, _i);
  64. memo = sha3(s.out());
  65. }
  66. return memo;
  67. }
  68. void BlockHeader::streamRLPFields(RLPStream& _s) const
  69. {
  70. _s << m_parentHash << m_sha3Uncles << m_author << m_stateRoot << m_transactionsRoot << m_receiptsRoot << m_logBloom
  71. << m_difficulty << m_number << m_gasLimit << m_gasUsed << m_timestamp << m_extraData;
  72. }
  73. void BlockHeader::streamRLP(RLPStream& _s, IncludeSeal _i) const
  74. {
  75. if (_i != OnlySeal)
  76. {
  77. _s.appendList(BlockHeader::BasicFields + (_i == WithoutSeal ? 0 : m_seal.size()));
  78. BlockHeader::streamRLPFields(_s);
  79. }
  80. if (_i != WithoutSeal)
  81. for (unsigned i = 0; i < m_seal.size(); ++i)
  82. _s.appendRaw(m_seal[i]);
  83. }
  84. h256 BlockHeader::headerHashFromBlock(bytesConstRef _block)
  85. {
  86. return sha3(RLP(_block)[0].data());
  87. }
  88. RLP BlockHeader::extractHeader(bytesConstRef _block)
  89. {
  90. RLP root(_block);
  91. if (!root.isList())
  92. BOOST_THROW_EXCEPTION(InvalidBlockFormat() << errinfo_comment("Block must be a list") << BadFieldError(0, _block.toString()));
  93. RLP header = root[0];
  94. if (!header.isList())
  95. BOOST_THROW_EXCEPTION(InvalidBlockFormat() << errinfo_comment("Block header must be a list") << BadFieldError(0, header.data().toString()));
  96. if (!root[1].isList())
  97. BOOST_THROW_EXCEPTION(InvalidBlockFormat() << errinfo_comment("Block transactions must be a list") << BadFieldError(1, root[1].data().toString()));
  98. if (!root[2].isList())
  99. BOOST_THROW_EXCEPTION(InvalidBlockFormat() << errinfo_comment("Block uncles must be a list") << BadFieldError(2, root[2].data().toString()));
  100. return header;
  101. }
  102. void BlockHeader::populate(RLP const& _header)
  103. {
  104. int field = 0;
  105. try
  106. {
  107. m_parentHash = _header[field = 0].toHash<h256>(RLP::VeryStrict);
  108. m_sha3Uncles = _header[field = 1].toHash<h256>(RLP::VeryStrict);
  109. m_author = _header[field = 2].toHash<Address>(RLP::VeryStrict);
  110. m_stateRoot = _header[field = 3].toHash<h256>(RLP::VeryStrict);
  111. m_transactionsRoot = _header[field = 4].toHash<h256>(RLP::VeryStrict);
  112. m_receiptsRoot = _header[field = 5].toHash<h256>(RLP::VeryStrict);
  113. m_logBloom = _header[field = 6].toHash<LogBloom>(RLP::VeryStrict);
  114. m_difficulty = _header[field = 7].toInt<u256>();
  115. m_number = _header[field = 8].toInt<u256>();
  116. m_gasLimit = _header[field = 9].toInt<u256>();
  117. m_gasUsed = _header[field = 10].toInt<u256>();
  118. m_timestamp = _header[field = 11].toInt<u256>();
  119. m_extraData = _header[field = 12].toBytes();
  120. m_seal.clear();
  121. for (unsigned i = 13; i < _header.itemCount(); ++i)
  122. m_seal.push_back(_header[i].data().toBytes());
  123. }
  124. catch (Exception const& _e)
  125. {
  126. _e << errinfo_name("invalid block header format") << BadFieldError(field, toHex(_header[field].data().toBytes()));
  127. throw;
  128. }
  129. }
  130. struct BlockInfoDiagnosticsChannel: public LogChannel { static const char* name() { return EthBlue "▧" EthWhite " ◌"; } static const int verbosity = 9; };
  131. void BlockHeader::populateFromParent(BlockHeader const& _parent)
  132. {
  133. m_stateRoot = _parent.stateRoot();
  134. m_number = _parent.m_number + 1;
  135. m_parentHash = _parent.m_hash;
  136. m_gasLimit = _parent.m_gasLimit;
  137. m_difficulty = 1;
  138. m_gasUsed = 0;
  139. }
  140. void BlockHeader::verify(Strictness _s, BlockHeader const& _parent, bytesConstRef _block) const
  141. {
  142. if (m_number > ~(unsigned)0)
  143. BOOST_THROW_EXCEPTION(InvalidNumber());
  144. if (_s != CheckNothingNew && m_gasUsed > m_gasLimit)
  145. BOOST_THROW_EXCEPTION(TooMuchGasUsed() << RequirementError(bigint(m_gasLimit), bigint(m_gasUsed)));
  146. if (_parent)
  147. {
  148. if (m_parentHash && _parent.hash() != m_parentHash)
  149. BOOST_THROW_EXCEPTION(InvalidParentHash());
  150. if (m_timestamp <= _parent.m_timestamp)
  151. BOOST_THROW_EXCEPTION(InvalidTimestamp());
  152. if (m_number != _parent.m_number + 1)
  153. BOOST_THROW_EXCEPTION(InvalidNumber());
  154. }
  155. if (_block)
  156. {
  157. RLP root(_block);
  158. auto txList = root[1];
  159. auto expectedRoot = trieRootOver(txList.itemCount(), [&](unsigned i){ return rlp(i); }, [&](unsigned i){ return txList[i].data().toBytes(); });
  160. clog(BlockInfoDiagnosticsChannel) << "Expected trie root:" << toString(expectedRoot);
  161. if (m_transactionsRoot != expectedRoot)
  162. {
  163. MemoryDB tm;
  164. GenericTrieDB<MemoryDB> transactionsTrie(&tm);
  165. transactionsTrie.init();
  166. vector<bytesConstRef> txs;
  167. for (unsigned i = 0; i < txList.itemCount(); ++i)
  168. {
  169. RLPStream k;
  170. k << i;
  171. transactionsTrie.insert(&k.out(), txList[i].data());
  172. txs.push_back(txList[i].data());
  173. cdebug << toHex(k.out()) << toHex(txList[i].data());
  174. }
  175. cdebug << "trieRootOver" << expectedRoot;
  176. cdebug << "orderedTrieRoot" << orderedTrieRoot(txs);
  177. cdebug << "TrieDB" << transactionsTrie.root();
  178. cdebug << "Contents:";
  179. for (auto const& t: txs)
  180. cdebug << toHex(t);
  181. BOOST_THROW_EXCEPTION(InvalidTransactionsRoot() << Hash256RequirementError(expectedRoot, m_transactionsRoot));
  182. }
  183. clog(BlockInfoDiagnosticsChannel) << "Expected uncle hash:" << toString(sha3(root[2].data()));
  184. if (m_sha3Uncles != sha3(root[2].data()))
  185. BOOST_THROW_EXCEPTION(InvalidUnclesHash() << Hash256RequirementError(sha3(root[2].data()), m_sha3Uncles));
  186. }
  187. }