1 // Aleth: Ethereum C++ client, tools and libraries. 2 // Copyright 2014-2019 Aleth Authors. 3 // Licensed under the GNU General Public License, Version 3. 4 5 6 #pragma once 7 8 #include "ChainOperationParams.h" 9 #include "Common.h" 10 #include "Exceptions.h" 11 #include <libdevcore/Common.h> 12 #include <libdevcore/Guards.h> 13 #include <libdevcore/Log.h> 14 #include <libdevcore/RLP.h> 15 #include <libdevcore/SHA3.h> 16 #include <algorithm> 17 18 namespace dev 19 { 20 namespace eth 21 { 22 23 enum IncludeSeal 24 { 25 WithoutSeal = 0, 26 WithSeal = 1, 27 OnlySeal = 2 28 }; 29 30 enum Strictness 31 { 32 CheckEverything, 33 QuickNonce, 34 IgnoreSeal, 35 CheckNothingNew 36 }; 37 38 // TODO: for implementing soon. 39 /*enum Check 40 { 41 CheckBasic, 42 CheckExtended, 43 CheckBlock, 44 CheckParent, 45 CheckSeal, 46 CheckSealQuickly, 47 CheckAll = CheckBasic | CheckExtended | CheckBlock | CheckParent | CheckSeal, 48 }; 49 using Checks = FlagSet<Check>;*/ 50 51 enum BlockDataType 52 { 53 HeaderData, 54 BlockData 55 }; 56 57 DEV_SIMPLE_EXCEPTION(NoHashRecorded); 58 DEV_SIMPLE_EXCEPTION(GenesisBlockCannotBeCalculated); 59 60 /** @brief Encapsulation of a block header. 61 * Class to contain all of a block header's data. It is able to parse a block header and populate 62 * from some given RLP block serialisation with the static fromHeader(), through the method 63 * populate(). This will not conduct any verification above basic formating. In this case extra 64 * verification can be performed through verify(). 65 * 66 * The object may also be populated from an entire block through the explicit 67 * constructor BlockHeader(bytesConstRef) and manually with the populate() method. These will 68 * conduct verification of the header against the other information in the block. 69 * 70 * The object may be populated with a template given a parent BlockHeader object with the 71 * populateFromParent() method. The genesis block info may be retrieved with genesis() and the 72 * corresponding RLP block created with createGenesisBlock(). 73 * 74 * To determine the header hash without the nonce (for sealing), the method hash(WithoutNonce) is 75 * provided. 76 * 77 * The default constructor creates an empty object, which can be tested against with the boolean 78 * conversion operator. 79 */ 80 class BlockHeader 81 { 82 friend class BlockChain; 83 public: 84 static const unsigned BasicFields = 13; 85 86 BlockHeader(); 87 explicit BlockHeader(bytesConstRef _data, BlockDataType _bdt = BlockData, h256 const& _hashWith = h256()); 88 explicit BlockHeader(bytes const& _data, BlockDataType _bdt = BlockData, h256 const& _hashWith = h256()): BlockHeader(&_data, _bdt, _hashWith) {} 89 BlockHeader(BlockHeader const& _other); 90 BlockHeader& operator=(BlockHeader const& _other); 91 headerHashFromBlock(bytes const & _block)92 static h256 headerHashFromBlock(bytes const& _block) { return headerHashFromBlock(&_block); } 93 static h256 headerHashFromBlock(bytesConstRef _block); 94 static RLP extractHeader(bytesConstRef _block); 95 96 explicit operator bool() const { return m_timestamp >= 0; } 97 98 bool operator==(BlockHeader const& _cmp) const 99 { 100 return m_parentHash == _cmp.parentHash() && 101 m_sha3Uncles == _cmp.sha3Uncles() && 102 m_author == _cmp.author() && 103 m_stateRoot == _cmp.stateRoot() && 104 m_transactionsRoot == _cmp.transactionsRoot() && 105 m_receiptsRoot == _cmp.receiptsRoot() && 106 m_logBloom == _cmp.logBloom() && 107 m_difficulty == _cmp.difficulty() && 108 m_number == _cmp.number() && 109 m_gasLimit == _cmp.gasLimit() && 110 m_gasUsed == _cmp.gasUsed() && 111 m_timestamp == _cmp.timestamp() && 112 m_extraData == _cmp.extraData(); 113 } 114 bool operator!=(BlockHeader const& _cmp) const { return !operator==(_cmp); } 115 116 void clear(); noteDirty()117 void noteDirty() const { Guard l(m_hashLock); m_hashWithout = m_hash = h256(); } 118 void populateFromParent(BlockHeader const& parent); 119 120 // TODO: pull out into abstract class Verifier. 121 void verify(Strictness _s = CheckEverything, BlockHeader const& _parent = BlockHeader(), bytesConstRef _block = bytesConstRef()) const; verify(Strictness _s,bytesConstRef _block)122 void verify(Strictness _s, bytesConstRef _block) const { verify(_s, BlockHeader(), _block); } 123 124 h256 hash(IncludeSeal _i = WithSeal) const; 125 void streamRLP(RLPStream& _s, IncludeSeal _i = WithSeal) const; 126 setParentHash(h256 const & _v)127 void setParentHash(h256 const& _v) { m_parentHash = _v; noteDirty(); } setSha3Uncles(h256 const & _v)128 void setSha3Uncles(h256 const& _v) { m_sha3Uncles = _v; noteDirty(); } setTimestamp(int64_t _v)129 void setTimestamp(int64_t _v) { m_timestamp = _v; noteDirty(); } setAuthor(Address const & _v)130 void setAuthor(Address const& _v) { m_author = _v; noteDirty(); } setRoots(h256 const & _t,h256 const & _r,h256 const & _u,h256 const & _s)131 void setRoots(h256 const& _t, h256 const& _r, h256 const& _u, h256 const& _s) { m_transactionsRoot = _t; m_receiptsRoot = _r; m_stateRoot = _s; m_sha3Uncles = _u; noteDirty(); } setGasUsed(u256 const & _v)132 void setGasUsed(u256 const& _v) { m_gasUsed = _v; noteDirty(); } setNumber(int64_t _v)133 void setNumber(int64_t _v) { m_number = _v; noteDirty(); } setGasLimit(u256 const & _v)134 void setGasLimit(u256 const& _v) { m_gasLimit = _v; noteDirty(); } setExtraData(bytes const & _v)135 void setExtraData(bytes const& _v) { m_extraData = _v; noteDirty(); } setLogBloom(LogBloom const & _v)136 void setLogBloom(LogBloom const& _v) { m_logBloom = _v; noteDirty(); } setDifficulty(u256 const & _v)137 void setDifficulty(u256 const& _v) { m_difficulty = _v; noteDirty(); } setSeal(unsigned _offset,T const & _value)138 template <class T> void setSeal(unsigned _offset, T const& _value) { Guard l(m_sealLock); if (m_seal.size() <= _offset) m_seal.resize(_offset + 1); m_seal[_offset] = rlp(_value); noteDirty(); } setSeal(T const & _value)139 template <class T> void setSeal(T const& _value) { setSeal(0, _value); } 140 parentHash()141 h256 const& parentHash() const { return m_parentHash; } sha3Uncles()142 h256 const& sha3Uncles() const { return m_sha3Uncles; } hasUncles()143 bool hasUncles() const { return m_sha3Uncles != EmptyListSHA3; } timestamp()144 int64_t timestamp() const { return m_timestamp; } author()145 Address const& author() const { return m_author; } stateRoot()146 h256 const& stateRoot() const { return m_stateRoot; } transactionsRoot()147 h256 const& transactionsRoot() const { return m_transactionsRoot; } receiptsRoot()148 h256 const& receiptsRoot() const { return m_receiptsRoot; } gasUsed()149 u256 const& gasUsed() const { return m_gasUsed; } number()150 int64_t number() const { return m_number; } gasLimit()151 u256 const& gasLimit() const { return m_gasLimit; } extraData()152 bytes const& extraData() const { return m_extraData; } logBloom()153 LogBloom const& logBloom() const { return m_logBloom; } difficulty()154 u256 const& difficulty() const { return m_difficulty; } 155 template <class T> T seal(unsigned _offset = 0) const { T ret; Guard l(m_sealLock); if (_offset < m_seal.size()) ret = RLP(m_seal[_offset]).convert<T>(RLP::VeryStrict); return ret; } 156 157 private: 158 void populate(RLP const& _header); 159 void streamRLPFields(RLPStream& _s) const; seal()160 std::vector<bytes> seal() const 161 { 162 Guard l(m_sealLock); 163 return m_seal; 164 } hashRawRead()165 h256 hashRawRead() const 166 { 167 Guard l(m_hashLock); 168 return m_hash; 169 } hashWithoutRawRead()170 h256 hashWithoutRawRead() const 171 { 172 Guard l(m_hashLock); 173 return m_hashWithout; 174 } 175 176 h256 m_parentHash; 177 h256 m_sha3Uncles; 178 h256 m_stateRoot; 179 h256 m_transactionsRoot; 180 h256 m_receiptsRoot; 181 LogBloom m_logBloom; 182 int64_t m_number = 0; 183 u256 m_gasLimit; 184 u256 m_gasUsed; 185 bytes m_extraData; 186 int64_t m_timestamp = -1; 187 188 Address m_author; 189 u256 m_difficulty; 190 191 std::vector<bytes> m_seal; ///< Additional (RLP-encoded) header fields. 192 mutable Mutex m_sealLock; 193 194 mutable h256 m_hash; ///< (Memoised) SHA3 hash of the block header with seal. 195 mutable h256 m_hashWithout; ///< (Memoised) SHA3 hash of the block header without seal. 196 mutable Mutex m_hashLock; ///< A lock for both m_hash and m_hashWithout. 197 198 mutable Logger m_logger{createLogger(VerbosityDebug, "blockhdr")}; 199 }; 200 201 inline std::ostream& operator<<(std::ostream& _out, BlockHeader const& _bi) 202 { 203 _out << _bi.hash(WithoutSeal) << " " << _bi.parentHash() << " " << _bi.sha3Uncles() << " " << _bi.author() << " " << _bi.stateRoot() << " " << _bi.transactionsRoot() << " " << 204 _bi.receiptsRoot() << " " << _bi.logBloom() << " " << _bi.difficulty() << " " << _bi.number() << " " << _bi.gasLimit() << " " << 205 _bi.gasUsed() << " " << _bi.timestamp(); 206 return _out; 207 } 208 209 } 210 } 211