Ethereum  PoC-8
The C++ Implementation of Ethereum
ChainParams.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 "ChainParams.h"
23 #include "Account.h"
24 #include "GenesisInfo.h"
25 #include "State.h"
26 #include "ValidationSchemes.h"
28 #include <libdevcore/JsonUtils.h>
29 #include <libdevcore/Log.h>
30 #include <libdevcore/TrieDB.h>
31 #include <libethcore/BlockHeader.h>
32 #include <libethcore/Precompiled.h>
33 #include <libethcore/SealEngine.h>
34 
35 using namespace std;
36 using namespace dev;
37 using namespace eth;
38 using namespace eth::validation;
39 namespace js = json_spirit;
40 
41 ChainParams::ChainParams()
42 {
43  for (unsigned i = 1; i <= 4; ++i)
44  genesisState[Address(i)] = Account(0, 1);
45  // Setup default precompiled contracts as equal to genesis of Frontier.
46  precompiled.insert(make_pair(Address(1), PrecompiledContract(3000, 0, PrecompiledRegistrar::executor("ecrecover"))));
47  precompiled.insert(make_pair(Address(2), PrecompiledContract(60, 12, PrecompiledRegistrar::executor("sha256"))));
48  precompiled.insert(make_pair(Address(3), PrecompiledContract(600, 120, PrecompiledRegistrar::executor("ripemd160"))));
49  precompiled.insert(make_pair(Address(4), PrecompiledContract(15, 3, PrecompiledRegistrar::executor("identity"))));
50 }
51 
52 ChainParams::ChainParams(string const& _json, h256 const& _stateRoot)
53 {
54  *this = loadConfig(_json, _stateRoot);
55 }
56 
57 ChainParams ChainParams::loadConfig(
58  string const& _json, h256 const& _stateRoot, const boost::filesystem::path& _configPath) const
59 {
60  ChainParams cp(*this);
61  js::mValue val;
62  js::read_string_or_throw(_json, val);
63  js::mObject obj = val.get_obj();
64 
65  validateConfigJson(obj);
66  cp.sealEngineName = obj[c_sealEngine].get_str();
67  // params
68  js::mObject params = obj[c_params].get_obj();
69  cp.accountStartNonce = u256(fromBigEndian<u256>(fromHex(params[c_accountStartNonce].get_str())));
70  cp.maximumExtraDataSize = u256(fromBigEndian<u256>(fromHex(params[c_maximumExtraDataSize].get_str())));
71  cp.tieBreakingGas = params.count(c_tieBreakingGas) ? params[c_tieBreakingGas].get_bool() : true;
72  cp.setBlockReward(u256(fromBigEndian<u256>(fromHex(params[c_blockReward].get_str()))));
73 
74  auto setOptionalU256Parameter = [&params](u256 &_destination, string const& _name)
75  {
76  if (params.count(_name))
77  _destination = u256(fromBigEndian<u256>(fromHex(params.at(_name).get_str())));
78  };
79  setOptionalU256Parameter(cp.minGasLimit, c_minGasLimit);
80  setOptionalU256Parameter(cp.maxGasLimit, c_maxGasLimit);
81  setOptionalU256Parameter(cp.gasLimitBoundDivisor, c_gasLimitBoundDivisor);
82  setOptionalU256Parameter(cp.homesteadForkBlock, c_homesteadForkBlock);
83  setOptionalU256Parameter(cp.EIP150ForkBlock, c_EIP150ForkBlock);
84  setOptionalU256Parameter(cp.EIP158ForkBlock, c_EIP158ForkBlock);
85  setOptionalU256Parameter(cp.byzantiumForkBlock, c_byzantiumForkBlock);
86  setOptionalU256Parameter(cp.eWASMForkBlock, c_eWASMForkBlock);
87  setOptionalU256Parameter(cp.constantinopleForkBlock, c_constantinopleForkBlock);
88  setOptionalU256Parameter(cp.daoHardforkBlock, c_daoHardforkBlock);
89  setOptionalU256Parameter(cp.experimentalForkBlock, c_experimentalForkBlock);
90  setOptionalU256Parameter(cp.minimumDifficulty, c_minimumDifficulty);
91  setOptionalU256Parameter(cp.difficultyBoundDivisor, c_difficultyBoundDivisor);
92  setOptionalU256Parameter(cp.durationLimit, c_durationLimit);
93 
94  if (params.count(c_chainID))
95  cp.chainID = int(u256(fromBigEndian<u256>(fromHex(params.at(c_chainID).get_str()))));
96  if (params.count(c_networkID))
97  cp.networkID = int(u256(fromBigEndian<u256>(fromHex(params.at(c_networkID).get_str()))));
98  cp.allowFutureBlocks = params.count(c_allowFutureBlocks);
99 
100  // genesis
101  string genesisStr = js::write_string(obj[c_genesis], false);
102  cp = cp.loadGenesis(genesisStr, _stateRoot);
103  // genesis state
104  string genesisStateStr = js::write_string(obj[c_accounts], false);
105 
107  genesisStateStr, cp.accountStartNonce, nullptr, &cp.precompiled, _configPath);
108 
109  cp.stateRoot = _stateRoot ? _stateRoot : cp.calculateStateRoot(true);
110  return cp;
111 }
112 
113 ChainParams ChainParams::loadGenesis(string const& _json, h256 const& _stateRoot) const
114 {
115  ChainParams cp(*this);
116 
117  js::mValue val;
118  js::read_string(_json, val);
119  js::mObject genesis = val.get_obj();
120 
121  cp.parentHash = h256(0); // required by the YP
122  cp.author = genesis.count(c_coinbase) ? h160(genesis[c_coinbase].get_str()) : h160(genesis[c_author].get_str());
123  cp.difficulty = genesis.count(c_difficulty) ?
124  u256(fromBigEndian<u256>(fromHex(genesis[c_difficulty].get_str()))) :
125  cp.minimumDifficulty;
126  cp.gasLimit = u256(fromBigEndian<u256>(fromHex(genesis[c_gasLimit].get_str())));
127  cp.gasUsed = genesis.count(c_gasUsed) ? u256(fromBigEndian<u256>(fromHex(genesis[c_gasUsed].get_str()))) : 0;
128  cp.timestamp = u256(fromBigEndian<u256>(fromHex(genesis[c_timestamp].get_str())));
129  cp.extraData = bytes(fromHex(genesis[c_extraData].get_str()));
130 
131  // magic code for handling ethash stuff:
132  if (genesis.count(c_mixHash) && genesis.count(c_nonce))
133  {
134  h256 mixHash(genesis[c_mixHash].get_str());
135  h64 nonce(genesis[c_nonce].get_str());
136  cp.sealFields = 2;
137  cp.sealRLP = rlp(mixHash) + rlp(nonce);
138  }
139  cp.stateRoot = _stateRoot ? _stateRoot : cp.calculateStateRoot();
140  return cp;
141 }
142 
143 SealEngineFace* ChainParams::createSealEngine()
144 {
145  SealEngineFace* ret = SealEngineRegistrar::create(sealEngineName);
146  assert(ret && "Seal engine not found");
147  if (!ret)
148  return nullptr;
149  ret->setChainParams(*this);
150  if (sealRLP.empty())
151  {
152  sealFields = ret->sealFields();
153  sealRLP = ret->sealRLP();
154  }
155  return ret;
156 }
157 
158 void ChainParams::populateFromGenesis(bytes const& _genesisRLP, AccountMap const& _state)
159 {
160  BlockHeader bi(_genesisRLP, RLP(&_genesisRLP)[0].isList() ? BlockData : HeaderData);
161  parentHash = bi.parentHash();
162  author = bi.author();
163  difficulty = bi.difficulty();
164  gasLimit = bi.gasLimit();
165  gasUsed = bi.gasUsed();
166  timestamp = bi.timestamp();
167  extraData = bi.extraData();
168  genesisState = _state;
169  RLP r(_genesisRLP);
170  sealFields = r[0].itemCount() - BlockHeader::BasicFields;
171  sealRLP.clear();
172  for (unsigned i = BlockHeader::BasicFields; i < r[0].itemCount(); ++i)
173  sealRLP += r[0][i].data();
174 
175  calculateStateRoot(true);
176 
177  auto b = genesisBlock();
178  if (b != _genesisRLP)
179  {
180  cdebug << "Block passed:" << bi.hash() << bi.hash(WithoutSeal);
181  cdebug << "Genesis now:" << BlockHeader::headerHashFromBlock(b);
182  cdebug << RLP(b);
183  cdebug << RLP(_genesisRLP);
184  throw 0;
185  }
186 }
187 
188 h256 ChainParams::calculateStateRoot(bool _force) const
189 {
190  StateCacheDB db;
192  state.init();
193  if (!stateRoot || _force)
194  {
195  // TODO: use hash256
196  //stateRoot = hash256(toBytesMap(gs));
198  stateRoot = state.root();
199  }
200  return stateRoot;
201 }
202 
203 bytes ChainParams::genesisBlock() const
204 {
205  RLPStream block(3);
206 
207  calculateStateRoot();
208 
209  block.appendList(BlockHeader::BasicFields + sealFields)
210  << parentHash
211  << EmptyListSHA3 // sha3(uncles)
212  << author
213  << stateRoot
214  << EmptyTrie // transactions
215  << EmptyTrie // receipts
216  << LogBloom()
217  << difficulty
218  << 0 // number
219  << gasLimit
220  << gasUsed // gasUsed
221  << timestamp
222  << extraData;
223  block.appendRaw(sealRLP, sealFields);
224  block.appendRaw(RLPEmptyList);
225  block.appendRaw(RLPEmptyList);
226  return block.out();
227 }
virtual unsigned sealFields() const
Definition: SealEngine.h:51
Definition: Address.cpp:20
string const c_accountStartNonce
string const c_byzantiumForkBlock
std::unordered_map< Address, Account > AccountMap
Definition: Account.h:267
bytes rlp(_T _t)
Export a single item in RLP format, returning a byte array.
Definition: RLP.h:453
string const c_daoHardforkBlock
Encapsulation of a block header. Class to contain all of a block header&#39;s data. It is able to parse a...
Definition: BlockHeader.h:96
string const c_gasLimitBoundDivisor
string const c_difficultyBoundDivisor
std::unordered_map< Address, Account > const & genesisState()
h160 Address
Definition: Address.h:30
h256 const EmptyTrie
Definition: TrieCommon.cpp:28
Definition: FixedHash.h:390
string const c_maximumExtraDataSize
virtual bytes sealRLP() const
Definition: SealEngine.h:52
string const c_EIP150ForkBlock
void setBlockReward(u256 const &_newBlockReward)
#define cdebug
bytes fromHex(std::string const &_s, WhenError _throw=WhenError::DontThrow)
Definition: CommonData.cpp:81
string const c_experimentalForkBlock
string const c_minimumDifficulty
h256 stateRoot
Only pre-populate if known equivalent to genesisState&#39;s root. If they&#39;re different Bad Things Will Ha...
Definition: ChainParams.h:55
std::unordered_map< Address, PrecompiledContract > precompiled
Precompiled contracts as specified in the chain params.
std::vector< byte > bytes
Definition: Common.h:72
string const c_EIP158ForkBlock
RLPStream & appendList(size_t _items)
Appends a list.
Definition: RLP.cpp:268
FixedHash< 32 > h256
Definition: FixedHash.h:354
h256 const EmptyListSHA3
Definition: SHA3.cpp:26
AccountMap genesisState
Definition: ChainParams.h:56
bytes const & out() const
Read the byte stream.
Definition: RLP.h:419
string const c_homesteadForkBlock
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void > > u256
Definition: Common.h:121
void validateConfigJson(js::mObject const &_obj)
std::string sealEngineName
The chain sealer name: e.g. Ethash, NoProof, BasicAuthority.
void setChainParams(ChainOperationParams const &_params)
Definition: SealEngine.h:75
FixedHash< 20 > h160
Definition: FixedHash.h:355
h2048 LogBloom
The log bloom&#39;s size (2048-bit).
Definition: Common.h:69
AddressHash commit(AccountMap const &_cache, SecureTrieDB< Address, DB > &_state)
Definition: State.cpp:759
string const c_allowFutureBlocks
AccountMap jsonToAccountMap(std::string const &_json, u256 const &_defaultNonce=0, AccountMaskMap *o_mask=nullptr, PrecompiledContractMap *o_precompiled=nullptr, const boost::filesystem::path &_configPath={})
Class for writing to an RLP bytestream.
Definition: RLP.h:369
string const c_constantinopleForkBlock
RLPStream & appendRaw(bytesConstRef _rlp, size_t _itemCount=1)
Appends raw (pre-serialised) RLP data. Use with caution.
Definition: RLP.cpp:222
h256 calculateStateRoot(bool _force=false) const
Definition: RLP.h:47
bytes RLPEmptyList
The empty list in RLP format.
Definition: RLP.cpp:23