BlockChainHelper.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589
  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 BlockChainHelper.cpp
  15. * @author Dimitry Khokhlov <dimitry@ethdev.com>
  16. * @date 2015
  17. */
  18. #include <libdevcore/TransientDirectory.h>
  19. #include <libethereum/Block.h>
  20. #include <libethereum/BlockChain.h>
  21. #include <libethereum/TransactionQueue.h>
  22. #include <libethereum/GenesisInfo.h>
  23. #include <libethashseal/GenesisInfo.h>
  24. #include <test/BlockChainHelper.h>
  25. #include <test/TestHelper.h>
  26. using namespace std;
  27. using namespace json_spirit;
  28. using namespace dev;
  29. using namespace dev::eth;
  30. namespace dev
  31. {
  32. namespace test
  33. {
  34. TestTransaction::TestTransaction(mObject const& _o):
  35. m_jsonTransaction(_o)
  36. {
  37. ImportTest::importTransaction(_o, m_transaction); //check that json structure is valid
  38. }
  39. TestBlock::TestBlock()
  40. {
  41. m_dirty = false;
  42. }
  43. TestBlock::TestBlock(mObject const& _blockObj, mObject const& _stateObj):
  44. TestBlock()
  45. {
  46. m_tempDirState = std::unique_ptr<TransientDirectory>(new TransientDirectory());
  47. m_state = std::unique_ptr<State>(new State(0, OverlayDB(State::openDB(m_tempDirState.get()->path(), h256{}, WithExisting::Kill)), BaseState::Empty));
  48. ImportTest::importState(_stateObj, *m_state.get());
  49. m_state.get()->commit(State::CommitBehaviour::KeepEmptyAccounts);
  50. json_spirit::mObject state = _stateObj;
  51. dev::test::replaceLLLinState(state);
  52. m_accountMap = jsonToAccountMap(json_spirit::write_string(json_spirit::mValue(state), false));
  53. m_blockHeader = constructBlock(_blockObj, _stateObj.size() ? m_state.get()->rootHash() : h256{});
  54. recalcBlockHeaderBytes();
  55. }
  56. TestBlock::TestBlock(std::string const& _blockRLP):
  57. TestBlock()
  58. {
  59. m_bytes = importByteArray(_blockRLP);
  60. RLP root(m_bytes);
  61. m_blockHeader = BlockHeader(m_bytes);
  62. m_transactionQueue.clear();
  63. m_testTransactions.clear();
  64. for (auto const& tr: root[1])
  65. {
  66. Transaction tx(tr.data(), CheckTransaction::Everything);
  67. TestTransaction testTx(tx);
  68. m_transactionQueue.import(tx.rlp());
  69. m_testTransactions.push_back(testTx);
  70. }
  71. for (auto const& uRLP: root[2])
  72. {
  73. BlockHeader uBl(uRLP.data(), HeaderData);
  74. TestBlock uncle;
  75. uncle.setBlockHeader(uBl);
  76. m_uncles.push_back(uncle);
  77. }
  78. }
  79. TestBlock::TestBlock(TestBlock const& _original)
  80. {
  81. populateFrom(_original);
  82. }
  83. TestBlock& TestBlock::operator=(TestBlock const& _original)
  84. {
  85. populateFrom(_original);
  86. return *this;
  87. }
  88. void TestBlock::setState(State const& _state)
  89. {
  90. copyStateFrom(_state);
  91. }
  92. void TestBlock::addTransaction(TestTransaction const& _tr)
  93. {
  94. try
  95. {
  96. m_testTransactions.push_back(_tr);
  97. if (m_transactionQueue.import(_tr.transaction().rlp()) != ImportResult::Success)
  98. cnote << TestOutputHelper::testName() + "Test block failed importing transaction\n";
  99. }
  100. catch (Exception const& _e)
  101. {
  102. BOOST_ERROR(TestOutputHelper::testName() + "Failed transaction constructor with Exception: " << diagnostic_information(_e));
  103. }
  104. catch (exception const& _e)
  105. {
  106. cnote << _e.what();
  107. }
  108. recalcBlockHeaderBytes();
  109. }
  110. void TestBlock::addUncle(TestBlock const& _uncle)
  111. {
  112. m_uncles.push_back(_uncle);
  113. recalcBlockHeaderBytes();
  114. }
  115. void TestBlock::setUncles(vector<TestBlock> const& _uncles)
  116. {
  117. m_uncles.clear();
  118. m_uncles = _uncles;
  119. recalcBlockHeaderBytes();
  120. }
  121. void TestBlock::premineUpdate(BlockHeader& _blockInfo)
  122. {
  123. //alter blockheader with defined fields before actual mining
  124. if (m_premineUpdate.count("parentHash") > 0)
  125. _blockInfo.setParentHash(m_blockHeader.parentHash());
  126. if (m_premineUpdate.count("coinbase") > 0)
  127. _blockInfo.setAuthor(m_blockHeader.author());
  128. if (m_premineUpdate.count("uncleHash") > 0 || m_premineUpdate.count("stateRoot") > 0 ||
  129. m_premineUpdate.count("transactionsTrie") > 0 || m_premineUpdate.count("receiptTrie") > 0)
  130. _blockInfo.setRoots(m_premineUpdate.count("transactionsTrie") > 0 ? m_blockHeader.transactionsRoot() : _blockInfo.transactionsRoot(),
  131. m_premineUpdate.count("receiptTrie") > 0 ? m_blockHeader.receiptsRoot() : _blockInfo.receiptsRoot(),
  132. m_premineUpdate.count("uncleHash") > 0 ? m_blockHeader.sha3Uncles() : _blockInfo.sha3Uncles(),
  133. m_premineUpdate.count("stateRoot") > 0 ? m_blockHeader.stateRoot() : _blockInfo.stateRoot());
  134. if (m_premineUpdate.count("bloom") > 0)
  135. _blockInfo.setLogBloom(m_blockHeader.logBloom());
  136. if (m_premineUpdate.count("difficulty") > 0)
  137. _blockInfo.setDifficulty(m_blockHeader.difficulty());
  138. if (m_premineUpdate.count("number") > 0)
  139. _blockInfo.setNumber(m_blockHeader.number());
  140. if (m_premineUpdate.count("gasLimit") > 0)
  141. _blockInfo.setGasLimit(m_blockHeader.gasLimit());
  142. if (m_premineUpdate.count("gasUsed") > 0)
  143. _blockInfo.setGasUsed(m_blockHeader.gasUsed());
  144. if (m_premineUpdate.count("timestamp") > 0)
  145. _blockInfo.setTimestamp(m_blockHeader.timestamp());
  146. if (m_premineUpdate.count("extraData") > 0)
  147. _blockInfo.setExtraData(m_blockHeader.extraData());
  148. m_premineHeader = _blockInfo; //needed for check that any altered fields are altered in mined block as well
  149. }
  150. void TestBlock::mine(TestBlockChain const& _bc)
  151. {
  152. TestBlock const& genesisBlock = _bc.testGenesis();
  153. OverlayDB const& genesisDB = genesisBlock.state().db();
  154. BlockChain const& blockchain = _bc.interface();
  155. Block block = blockchain.genesisBlock(genesisDB);
  156. block.setAuthor(genesisBlock.beneficiary());
  157. //set some header data before mining from original blockheader
  158. BlockHeader& blockInfo = *const_cast<BlockHeader*>(&block.info());
  159. try
  160. {
  161. ZeroGasPricer gp;
  162. block.sync(blockchain); //sync block with blockchain
  163. premineUpdate(blockInfo);
  164. size_t transactionsOnImport = m_transactionQueue.topTransactions(100).size();
  165. block.sync(blockchain, m_transactionQueue, gp); //!!! Invalid transactions are dropped here
  166. if (transactionsOnImport > m_transactionQueue.topTransactions(100).size())
  167. cnote << "Dropped invalid Transactions when mining!";
  168. dev::eth::mine(block, blockchain, blockchain.sealEngine());
  169. blockchain.sealEngine()->verify(JustSeal, block.info());
  170. }
  171. catch (Exception const& _e)
  172. {
  173. cnote << TestOutputHelper::testName() + "block sync or mining did throw an exception: " << diagnostic_information(_e);
  174. return;
  175. }
  176. catch (std::exception const& _e)
  177. {
  178. cnote << TestOutputHelper::testName() + "block sync or mining did throw an exception: " << _e.what();
  179. return;
  180. }
  181. size_t validTransactions = m_transactionQueue.topTransactions(100).size();
  182. m_receipts = RLPStream(validTransactions);
  183. for (size_t i = 0; i < validTransactions; i++)
  184. {
  185. const dev::bytes receipt = block.receipt(i).rlp();
  186. m_receipts.appendRaw(receipt);
  187. }
  188. m_blockHeader = BlockHeader(block.blockData()); // NOTE no longer checked at this point in new API. looks like it was unimportant anyway
  189. cnote << "Mined TrRoot: " << m_blockHeader.transactionsRoot();
  190. copyStateFrom(block.state());
  191. //Invalid uncles are dropped when mining. but we restore the hash to produce block with invalid uncles (for later test when importing to blockchain)
  192. if (m_uncles.size())
  193. {
  194. //Fill info with uncles
  195. RLPStream uncleStream;
  196. uncleStream.appendList(m_uncles.size());
  197. for (unsigned i = 0; i < m_uncles.size(); ++i)
  198. {
  199. RLPStream uncleRlp;
  200. m_uncles[i].blockHeader().streamRLP(uncleRlp);
  201. uncleStream.appendRaw(uncleRlp.out());
  202. }
  203. m_blockHeader.setSha3Uncles(sha3(uncleStream.out()));
  204. updateNonce(_bc);
  205. }
  206. else
  207. recalcBlockHeaderBytes();
  208. }
  209. void TestBlock::setBlockHeader(BlockHeader const& _header)
  210. {
  211. m_blockHeader = _header;
  212. recalcBlockHeaderBytes();
  213. }
  214. ///Test Block Private
  215. BlockHeader TestBlock::constructBlock(mObject const& _o, h256 const& _stateRoot)
  216. {
  217. BlockHeader ret;
  218. try
  219. {
  220. const dev::bytes c_blockRLP = createBlockRLPFromFields(_o, _stateRoot);
  221. ret = BlockHeader(c_blockRLP, HeaderData);
  222. // cdebug << "Block constructed of hash" << ret.hash() << "(without:" << ret.hash(WithoutSeal) << ")";
  223. }
  224. catch (Exception const& _e)
  225. {
  226. cnote << TestOutputHelper::testName() + "block population did throw an exception: " << diagnostic_information(_e);
  227. }
  228. catch (std::exception const& _e)
  229. {
  230. BOOST_ERROR(TestOutputHelper::testName() + "Failed block population with Exception: " << _e.what());
  231. }
  232. catch(...)
  233. {
  234. BOOST_ERROR(TestOutputHelper::testName() + "block population did throw an unknown exception\n");
  235. }
  236. return ret;
  237. }
  238. dev::bytes TestBlock::createBlockRLPFromFields(mObject const& _tObj, h256 const& _stateRoot)
  239. {
  240. RLPStream rlpStream;
  241. rlpStream.appendList(_tObj.count("hash") > 0 ? (_tObj.size() - 1) : _tObj.size());
  242. if (_tObj.count("parentHash"))
  243. rlpStream << importByteArray(_tObj.at("parentHash").get_str());
  244. if (_tObj.count("uncleHash"))
  245. rlpStream << importByteArray(_tObj.at("uncleHash").get_str());
  246. if (_tObj.count("coinbase"))
  247. rlpStream << importByteArray(_tObj.at("coinbase").get_str());
  248. if (_stateRoot)
  249. rlpStream << _stateRoot;
  250. else if (_tObj.count("stateRoot"))
  251. rlpStream << importByteArray(_tObj.at("stateRoot").get_str());
  252. if (_tObj.count("transactionsTrie"))
  253. rlpStream << importByteArray(_tObj.at("transactionsTrie").get_str());
  254. if (_tObj.count("receiptTrie"))
  255. rlpStream << importByteArray(_tObj.at("receiptTrie").get_str());
  256. if (_tObj.count("bloom"))
  257. rlpStream << importByteArray(_tObj.at("bloom").get_str());
  258. if (_tObj.count("difficulty"))
  259. rlpStream << bigint(_tObj.at("difficulty").get_str());
  260. if (_tObj.count("number"))
  261. rlpStream << bigint(_tObj.at("number").get_str());
  262. if (_tObj.count("gasLimit"))
  263. rlpStream << bigint(_tObj.at("gasLimit").get_str());
  264. if (_tObj.count("gasUsed"))
  265. rlpStream << bigint(_tObj.at("gasUsed").get_str());
  266. if (_tObj.count("timestamp"))
  267. rlpStream << bigint(_tObj.at("timestamp").get_str());
  268. if (_tObj.count("extraData"))
  269. rlpStream << fromHex(_tObj.at("extraData").get_str());
  270. if (_tObj.count("mixHash"))
  271. rlpStream << importByteArray(_tObj.at("mixHash").get_str());
  272. if (_tObj.count("nonce"))
  273. rlpStream << importByteArray(_tObj.at("nonce").get_str());
  274. return rlpStream.out();
  275. }
  276. void TestBlock::updateNonce(TestBlockChain const& _bc)
  277. {
  278. if (((BlockHeader)m_blockHeader).difficulty() == 0)
  279. BOOST_TEST_MESSAGE("Trying to mine a block with 0 difficulty! " + TestOutputHelper::testName());
  280. else
  281. {
  282. //do not verify blockheader for validity here
  283. dev::eth::mine(m_blockHeader, _bc.interface().sealEngine(), false);
  284. }
  285. recalcBlockHeaderBytes();
  286. }
  287. void TestBlock::verify(TestBlockChain const& _bc) const
  288. {
  289. if (m_dirty) //TestBlock have incorrect blockheader for testing purposes
  290. return;
  291. try
  292. {
  293. _bc.interface().sealEngine()->verify(CheckNothingNew, m_blockHeader, BlockHeader(), &m_bytes);
  294. }
  295. catch (Exception const& _e)
  296. {
  297. u256 daoHardfork = _bc.interface().sealEngine()->chainParams().u256Param("daoHardforkBlock");
  298. if ((m_blockHeader.number() >= daoHardfork && m_blockHeader.number() <= daoHardfork + 9) || m_blockHeader.number() == 0)
  299. {
  300. string exWhat { _e.what() };
  301. string exExpect = "InvalidTransactionsRoot";
  302. BOOST_REQUIRE_MESSAGE(exWhat.find(exExpect) != string::npos, TestOutputHelper::testName() + "block import expected another exeption: " + exExpect);
  303. }
  304. else
  305. BOOST_ERROR(TestOutputHelper::testName() + toString(m_blockHeader.number()) + " BlockHeader Verification failed: " << boost::current_exception_diagnostic_information());
  306. }
  307. catch (...)
  308. {
  309. BOOST_ERROR(TestOutputHelper::testName() + "BlockHeader Verification failed: " << boost::current_exception_diagnostic_information());
  310. }
  311. }
  312. //Form bytestream of a block with [header transactions uncles]
  313. void TestBlock::recalcBlockHeaderBytes()
  314. {
  315. Transactions txList;
  316. for (auto const& txi: m_transactionQueue.topTransactions(std::numeric_limits<unsigned>::max()))
  317. txList.push_back(txi);
  318. RLPStream txStream;
  319. txStream.appendList(txList.size());
  320. for (unsigned i = 0; i < txList.size(); ++i)
  321. {
  322. RLPStream txrlp;
  323. txList[i].streamRLP(txrlp);
  324. txStream.appendRaw(txrlp.out());
  325. }
  326. RLPStream uncleStream;
  327. uncleStream.appendList(m_uncles.size());
  328. for (unsigned i = 0; i < m_uncles.size(); ++i)
  329. {
  330. RLPStream uncleRlp;
  331. m_uncles[i].blockHeader().streamRLP(uncleRlp);
  332. uncleStream.appendRaw(uncleRlp.out());
  333. }
  334. RLPStream blHeaderStream;
  335. m_blockHeader.streamRLP(blHeaderStream, WithSeal);
  336. RLPStream ret(3);
  337. ret.appendRaw(blHeaderStream.out()); //block header
  338. ret.appendRaw(txStream.out()); //transactions
  339. ret.appendRaw(uncleStream.out()); //uncles
  340. m_bytes = ret.out();
  341. }
  342. void TestBlock::copyStateFrom(State const& _state)
  343. {
  344. //WEIRD WAY TO COPY STATE AS COPY CONSTRUCTOR FOR STATE NOT IMPLEMENTED CORRECTLY (they would share the same DB)
  345. m_tempDirState.reset(new TransientDirectory());
  346. m_state.reset(new State(0, OverlayDB(State::openDB(m_tempDirState.get()->path(), h256{}, WithExisting::Kill)), BaseState::Empty));
  347. json_spirit::mObject obj = fillJsonWithState(_state);
  348. ImportTest::importState(obj, *m_state.get());
  349. }
  350. void TestBlock::clearState()
  351. {
  352. m_state.reset(0);
  353. m_tempDirState.reset(0);
  354. for (size_t i = 0; i < m_uncles.size(); i++)
  355. m_uncles.at(i).clearState();
  356. }
  357. void TestBlock::populateFrom(TestBlock const& _original)
  358. {
  359. try
  360. {
  361. copyStateFrom(_original.state()); //copy state if it is defined in _original
  362. }
  363. catch (BlockStateUndefined const& _ex)
  364. {
  365. if (g_logVerbosity > 6)
  366. cnote << _ex.what() << "copying block with null state";
  367. }
  368. m_testTransactions = _original.testTransactions();
  369. m_transactionQueue.clear();
  370. TransactionQueue const& trQueue = _original.transactionQueue();
  371. for (auto const& txi: trQueue.topTransactions(std::numeric_limits<unsigned>::max()))
  372. m_transactionQueue.import(txi.rlp());
  373. m_uncles = _original.uncles();
  374. m_blockHeader = _original.blockHeader();
  375. m_bytes = _original.bytes();
  376. m_accountMap = _original.accountMap();
  377. m_dirty = false;
  378. }
  379. TestBlockChain::TestBlockChain(TestBlock const& _genesisBlock, bool _noProof)
  380. {
  381. reset(_genesisBlock, _noProof);
  382. }
  383. void TestBlockChain::reset(TestBlock const& _genesisBlock, bool _noProof)
  384. {
  385. (void)_noProof;
  386. m_tempDirBlockchain.reset(new TransientDirectory);
  387. ChainParams p = //_noProof ? ChainParams(genesisInfo(Network::FrontierTest), _genesisBlock.bytes(), _genesisBlock.accountMap()) :
  388. ChainParams(genesisInfo(TestBlockChain::s_sealEngineNetwork), _genesisBlock.bytes(), _genesisBlock.accountMap());
  389. m_blockChain.reset(new BlockChain(p, m_tempDirBlockchain.get()->path(), WithExisting::Kill));
  390. if (!m_blockChain->isKnown(BlockHeader::headerHashFromBlock(_genesisBlock.bytes())))
  391. {
  392. cdebug << "Not known:" << BlockHeader::headerHashFromBlock(_genesisBlock.bytes()) << BlockHeader(p.genesisBlock()).hash();
  393. cdebug << "Genesis block not known!";
  394. cdebug << "This should never happen.";
  395. assert(false);
  396. }
  397. m_lastBlock = m_genesisBlock = _genesisBlock;
  398. }
  399. bool TestBlockChain::addBlock(TestBlock const& _block)
  400. {
  401. while (true)
  402. {
  403. try
  404. {
  405. _block.verify(*this); //check that block header match TestBlock contents
  406. m_blockChain.get()->import(_block.bytes(), m_genesisBlock.state().db());
  407. break;
  408. }
  409. catch (FutureTime)
  410. {
  411. this_thread::sleep_for(chrono::milliseconds(100));
  412. break;
  413. }
  414. }
  415. //Imported and best
  416. if (_block.bytes() == m_blockChain.get()->block())
  417. {
  418. m_lastBlock = _block;
  419. //overwrite state in case _block had no State defined (e.x. created from RLP)
  420. OverlayDB const& genesisDB = m_genesisBlock.state().db();
  421. Block block = (m_blockChain.get()->genesisBlock(genesisDB));
  422. block.sync(*m_blockChain.get());
  423. //BOOST_REQUIRE(m_lastBlock.blockHeader().hash() == BlockHeader(block.blockData()).hash());
  424. m_lastBlock.setState(block.fromPending(10000));
  425. return true;
  426. }
  427. return false;
  428. }
  429. vector<TestBlock> TestBlockChain::syncUncles(vector<TestBlock> const& uncles)
  430. {
  431. vector<TestBlock> validUncles;
  432. if (uncles.size() == 0)
  433. return validUncles;
  434. BlockQueue uncleBlockQueue;
  435. BlockChain& blockchain = *m_blockChain.get();
  436. uncleBlockQueue.setChain(blockchain);
  437. for (size_t i = 0; i < uncles.size(); i++)
  438. {
  439. try
  440. {
  441. uncleBlockQueue.import(&uncles.at(i).bytes(), false);
  442. this_thread::sleep_for(chrono::seconds(1)); // wait until block is verified
  443. validUncles.push_back(uncles.at(i));
  444. }
  445. catch(...)
  446. {
  447. cnote << "error in importing uncle! This produces an invalid block (May be by purpose for testing).";
  448. }
  449. }
  450. blockchain.sync(uncleBlockQueue, m_genesisBlock.state().db(), (unsigned)4);
  451. return validUncles;
  452. }
  453. TestTransaction TestTransaction::defaultTransaction(u256 const& _nonce, u256 const& _gasPrice, u256 const& _gasLimit, bytes const& _data)
  454. {
  455. json_spirit::mObject txObj;
  456. txObj["data"] = toHex(_data);
  457. txObj["gasLimit"] = toString(_gasLimit);
  458. txObj["gasPrice"] = toString(_gasPrice);
  459. txObj["nonce"] = toString(_nonce);
  460. txObj["secretKey"] = "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8";
  461. txObj["to"] = "095e7baea6a6c7c4c2dfeb977efac326af552d87";
  462. txObj["value"] = "100";
  463. return TestTransaction(txObj);
  464. }
  465. AccountMap TestBlockChain::defaultAccountMap()
  466. {
  467. AccountMap ret;
  468. ret[Address("a94f5374fce5edbc8e2a8697c15331677e6ebf0b")] = Account(0, 10000000000);
  469. return ret;
  470. }
  471. TestBlock TestBlockChain::defaultGenesisBlock(u256 const& _gasLimit)
  472. {
  473. json_spirit::mObject blockObj;
  474. blockObj["bloom"] = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
  475. blockObj["coinbase"] = "0x8888f1f195afa192cfee860698584c030f4c9db1";
  476. blockObj["difficulty"] = "131072";
  477. blockObj["extraData"] = "0x42";
  478. blockObj["gasLimit"] = toString(_gasLimit);
  479. blockObj["gasUsed"] = "0";
  480. blockObj["mixHash"] = "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421";
  481. blockObj["nonce"] = "0x0102030405060708";
  482. blockObj["number"] = "0";
  483. blockObj["parentHash"] = "0x0000000000000000000000000000000000000000000000000000000000000000";
  484. blockObj["receiptTrie"] = "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421";
  485. blockObj["stateRoot"] = "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a";
  486. blockObj["timestamp"] = "0x54c98c81";
  487. blockObj["transactionsTrie"] = "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421";
  488. blockObj["uncleHash"] = "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347";
  489. json_spirit::mObject accountObj;
  490. accountObj["balance"] = "10000000000";
  491. accountObj["nonce"] = "1"; //=1for nonce too low exception check
  492. accountObj["code"] = "";
  493. accountObj["storage"] = json_spirit::mObject();
  494. json_spirit::mObject accountMapObj;
  495. accountMapObj["a94f5374fce5edbc8e2a8697c15331677e6ebf0b"] = accountObj;
  496. return TestBlock(blockObj, accountMapObj);
  497. }
  498. }}