Fabcoin Core  0.16.2
P2P Digital Currency
BlockChainTests.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 */
23 #include <boost/filesystem/operations.hpp>
24 #include <boost/test/unit_test.hpp>
25 #include <boost/filesystem.hpp>
26 #include <libdevcore/FileSystem.h>
27 #include <libethashseal/Ethash.h>
32 using namespace std;
33 using namespace json_spirit;
34 using namespace dev;
35 using namespace dev::eth;
36 
37 
38 namespace dev {
39 
40 namespace test {
41 
42 eth::Network TestBlockChain::s_sealEngineNetwork = eth::Network::FrontierTest;
43 
45 {
46  ChainBranch(TestBlock const& _genesis): blockchain(_genesis) { importedBlocks.push_back(_genesis); }
47  void reset() { blockchain.reset(importedBlocks.at(0)); }
48  void restoreFromHistory(size_t _importBlockNumber)
49  {
50  //Restore blockchain up to block.number to start new block mining after specific block
51  for (size_t i = 1; i < importedBlocks.size(); i++) //0 block is genesis
52  if (i < _importBlockNumber)
53  blockchain.addBlock(importedBlocks.at(i));
54  else
55  break;
56 
57  //Drop old blocks as we would construct new history
58  size_t originalSize = importedBlocks.size();
59  for (size_t i = _importBlockNumber; i < originalSize; i++)
60  importedBlocks.pop_back();
61  }
63  vector<TestBlock> importedBlocks;
64 
65  static void forceBlockchain(string const& chainname)
66  {
67  s_tempBlockchainNetwork = dev::test::TestBlockChain::s_sealEngineNetwork;
68  if (chainname == "Frontier")
69  dev::test::TestBlockChain::s_sealEngineNetwork = eth::Network::FrontierTest;
70  else if (chainname == "Homestead")
71  dev::test::TestBlockChain::s_sealEngineNetwork = eth::Network::HomesteadTest;
72  else if (chainname == "EIP150")
73  dev::test::TestBlockChain::s_sealEngineNetwork = eth::Network::EIP150Test;
74  else if (chainname == "TestFtoH5")
75  dev::test::TestBlockChain::s_sealEngineNetwork = eth::Network::TransitionnetTest;
76  else if (chainname == "Metropolis")
77  dev::test::TestBlockChain::s_sealEngineNetwork = eth::Network::MetropolisTest;
78  }
79 
80  static void resetBlockchain()
81  {
82  dev::test::TestBlockChain::s_sealEngineNetwork = s_tempBlockchainNetwork;
83  }
84 
85 private:
87 };
88 
89 eth::Network ChainBranch::s_tempBlockchainNetwork = eth::Network::MainNetwork;
90 
91 //Functions that working with test json
92 void compareBlocks(TestBlock const& _a, TestBlock const& _b);
95 void overwriteBlockHeaderForTest(mObject const& _blObj, TestBlock& _block, ChainBranch const& _chainBranch);
96 void overwriteUncleHeaderForTest(mObject& _uncleHeaderObj, TestBlock& _uncle, vector<TestBlock> const& _uncles, ChainBranch const& _chainBranch);
99 void checkExpectedException(mObject& _blObj, Exception const& _e);
100 void checkBlocks(TestBlock const& _blockFromFields, TestBlock const& _blockFromRlp, string const& _testname);
101 
102 void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
103 {
104  if (!Options::get().fillchain) //fill blockchain through state tests
105  TestOutputHelper::initTest(_v);
106  for (auto& i: _v.get_obj())
107  {
108  string testname = i.first;
109  json_spirit::mObject& o = i.second.get_obj();
110 
111  if (!Options::get().fillchain)
112  if (!TestOutputHelper::passTest(o, testname))
113  continue;
114 
115  BOOST_REQUIRE(o.count("genesisBlockHeader"));
116  BOOST_REQUIRE(o.count("pre"));
117  if (o.count("network"))
119 
120  TestBlock genesisBlock(o["genesisBlockHeader"].get_obj(), o["pre"].get_obj());
121  if (_fillin)
122  genesisBlock.setBlockHeader(genesisBlock.blockHeader());
123 
124  //TODO: genesis POW ???
125  TestBlockChain testChain(genesisBlock);
126  assert(testChain.interface().isKnown(genesisBlock.blockHeader().hash(WithSeal)));
127 
128  if (_fillin)
129  {
130  o["genesisBlockHeader"] = writeBlockHeaderToJson(genesisBlock.blockHeader());
131  o["genesisRLP"] = toHex(genesisBlock.bytes(), 2, HexPrefix::Add);
132  BOOST_REQUIRE(o.count("blocks"));
133 
134  mArray blArray;
135  size_t importBlockNumber = 0;
136  string chainname = "default";
137  string chainnetwork = "default";
138  std::map<string, ChainBranch*> chainMap = { {chainname , new ChainBranch(genesisBlock)}};
139 
140  for (auto const& bl: o["blocks"].get_array())
141  {
142  mObject blObj = bl.get_obj();
143  if (blObj.count("blocknumber") > 0)
144  importBlockNumber = max((int)toInt(blObj["blocknumber"]), 1);
145  else
146  importBlockNumber++;
147 
148  if (blObj.count("chainname") > 0)
149  chainname = blObj["chainname"].get_str();
150  else
151  chainname = "default";
152 
153  if (blObj.count("chainnetwork") > 0)
154  chainnetwork = blObj["chainnetwork"].get_str();
155  else
156  chainnetwork = "default";
157 
158  if (chainMap.count(chainname) > 0)
159  {
160  if (o.count("noBlockChainHistory") == 0)
161  {
162  ChainBranch::forceBlockchain(chainnetwork);
163  chainMap[chainname]->reset();
164  ChainBranch::resetBlockchain();
165  chainMap[chainname]->restoreFromHistory(importBlockNumber);
166  }
167  }
168  else
169  {
170  ChainBranch::forceBlockchain(chainnetwork);
171  chainMap[chainname] = new ChainBranch(genesisBlock);
172  ChainBranch::resetBlockchain();
173  }
174 
175  TestBlock block;
176  TestBlockChain& blockchain = chainMap[chainname]->blockchain;
177  vector<TestBlock>& importedBlocks = chainMap[chainname]->importedBlocks;
178 
179  //Import Transactions
180  BOOST_REQUIRE(blObj.count("transactions"));
181  for (auto const& txObj: blObj["transactions"].get_array())
182  {
183  TestTransaction transaction(txObj.get_obj());
184  block.addTransaction(transaction);
185  }
186 
187  //Import Uncles
188  for (auto const& uHObj: blObj.at("uncleHeaders").get_array())
189  {
190  cnote << "Generating uncle block at test " << testname;
191  TestBlock uncle;
192  mObject uncleHeaderObj = uHObj.get_obj();
193  string uncleChainName = chainname;
194  if (uncleHeaderObj.count("chainname") > 0)
195  uncleChainName = uncleHeaderObj["chainname"].get_str();
196 
197  overwriteUncleHeaderForTest(uncleHeaderObj, uncle, block.uncles(), *chainMap[uncleChainName]);
198  block.addUncle(uncle);
199  }
200 
201  vector<TestBlock> validUncles = blockchain.syncUncles(block.uncles());
202  block.setUncles(validUncles);
203 
204  if (blObj.count("blockHeaderPremine"))
205  {
206  overwriteBlockHeaderForTest(blObj.at("blockHeaderPremine").get_obj(), block, *chainMap[chainname]);
207  blObj.erase("blockHeaderPremine");
208  }
209 
210  cnote << "Mining block" << importBlockNumber << "for chain" << chainname << "at test " << testname;
211  block.mine(blockchain);
212  cnote << "Block mined with...";
213  cnote << "Transactions: " << block.transactionQueue().topTransactions(100).size();
214  cnote << "Uncles: " << block.uncles().size();
215 
216  TestBlock alterBlock(block);
217  checkBlocks(block, alterBlock, testname);
218 
219  if (blObj.count("blockHeader"))
220  overwriteBlockHeaderForTest(blObj.at("blockHeader").get_obj(), alterBlock, *chainMap[chainname]);
221 
222  blObj["rlp"] = toHex(alterBlock.bytes(), 2, HexPrefix::Add);
223  blObj["blockHeader"] = writeBlockHeaderToJson(alterBlock.blockHeader());
224 
225  mArray aUncleList;
226  for (size_t i = 0; i < alterBlock.uncles().size(); i++)
227  {
228  mObject uncleHeaderObj = writeBlockHeaderToJson(alterBlock.uncles().at(i).blockHeader());
229  aUncleList.push_back(uncleHeaderObj);
230  }
231  blObj["uncleHeaders"] = aUncleList;
232  blObj["transactions"] = writeTransactionsToJson(alterBlock.transactionQueue());
233 
234  compareBlocks(block, alterBlock);
235  try
236  {
237  blockchain.addBlock(alterBlock);
238  if (testChain.addBlock(alterBlock))
239  cnote << "The most recent best Block now is " << importBlockNumber << "in chain" << chainname << "at test " << testname;
240 
241  if (test::Options::get().checkstate == true)
242  BOOST_REQUIRE_MESSAGE(blObj.count("expectException") == 0, "block import expected exception, but no exeption was thrown!");
243  if (o.count("noBlockChainHistory") == 0)
244  {
245  importedBlocks.push_back(alterBlock);
246  importedBlocks.at(importedBlocks.size()-1).clearState(); //close the state as it wont be needed. too many open states would lead to exception.
247  }
248  }
249  catch (Exception const& _e)
250  {
251  cnote << testname + "block import throw an exception: " << diagnostic_information(_e);
252  checkExpectedException(blObj, _e);
254  }
255  catch (std::exception const& _e)
256  {
257  cnote << testname + "block import throw an exception: " << _e.what();
258  cout << testname + "block import thrown std exeption" << std::endl;
260  }
261  catch (...)
262  {
263  cout << testname + "block import thrown unknown exeption" << std::endl;
265  }
266 
267  blArray.push_back(blObj); //json data
268  this_thread::sleep_for(chrono::seconds(1));
269  }//each blocks
270 
271  if (o.count("expect") > 0)
272  {
273  AccountMaskMap expectStateMap;
274  State stateExpect(State::Null);
275  ImportTest::importState(o["expect"].get_obj(), stateExpect, expectStateMap);
276  if (ImportTest::compareStates(stateExpect, testChain.topBlock().state(), expectStateMap, Options::get().checkstate ? WhenError::Throw : WhenError::DontThrow))
277  if (Options::get().checkstate)
278  cerr << testname << endl;
279  o.erase(o.find("expect"));
280  }
281 
282  o["blocks"] = blArray;
283  o["postState"] = fillJsonWithState(testChain.topBlock().state());
284  o["lastblockhash"] = toString(testChain.topBlock().blockHeader().hash(WithSeal));
285 
286  //make all values hex in pre section
287  State prestate(State::Null);
288  ImportTest::importState(o["pre"].get_obj(), prestate);
289  o["pre"] = fillJsonWithState(prestate);
290 
291  for (auto iterator = chainMap.begin(); iterator != chainMap.end(); iterator++)
292  delete iterator->second;
293 
294  }//fillin
295  else
296  {
297  TestBlockChain blockchain(genesisBlock);
298 
299  if (o.count("genesisRLP") > 0)
300  {
301  TestBlock genesisFromRLP(o["genesisRLP"].get_str());
302  checkBlocks(genesisBlock, genesisFromRLP, testname);
303  }
304 
305  for (auto const& bl: o["blocks"].get_array())
306  {
307  mObject blObj = bl.get_obj();
308  TestBlock blockFromRlp;
309  try
310  {
311  TestBlock blRlp(blObj["rlp"].get_str());
312  blockFromRlp = blRlp;
313  if (blObj.count("blockHeader") == 0)
314  blockFromRlp.noteDirty(); //disable blockHeader check in TestBlock
315  testChain.addBlock(blockFromRlp);
316  }
317  // if exception is thrown, RLP is invalid and no blockHeader, Transaction list, or Uncle list should be given
318  catch (Exception const& _e)
319  {
320  cnote << testname + "state sync or block import did throw an exception: " << diagnostic_information(_e);
322  continue;
323  }
324  catch (std::exception const& _e)
325  {
326  cnote << testname + "state sync or block import did throw an exception: " << _e.what();
328  continue;
329  }
330  catch (...)
331  {
332  cnote << testname + "state sync or block import did throw an exception\n";
334  continue;
335  }
336 
337  //block from RLP successfully imported. now compare this rlp to test sections
338  BOOST_REQUIRE(blObj.count("blockHeader"));
339 
340  //Check Provided Header against block in RLP
341  mObject emptyState;
342  TestBlock blockFromFields(blObj["blockHeader"].get_obj(), emptyState);
343  //ImportTransactions
344  BOOST_REQUIRE(blObj.count("transactions"));
345  for (auto const& txObj: blObj["transactions"].get_array())
346  {
347  TestTransaction transaction(txObj.get_obj());
348  blockFromFields.addTransaction(transaction);
349  }
350 
351  // ImportUncles
352  if (blObj["uncleHeaders"].type() != json_spirit::null_type)
353  for (auto const& uBlHeaderObj: blObj["uncleHeaders"].get_array())
354  {
355  mObject uBlH = uBlHeaderObj.get_obj();
356  BOOST_REQUIRE((uBlH.size() == 16));
357 
358  mObject emptyState;
359  TestBlock uncle(uBlH, emptyState);
360  blockFromFields.addUncle(uncle);
361  }
362 
363  checkBlocks(blockFromFields, blockFromRlp, testname);
364 
365  try
366  {
367  blockchain.addBlock(blockFromFields);
368  }
369  catch (Exception const& _e)
370  {
371  cerr << testname + "Error importing block from fields to blockchain: " << diagnostic_information(_e);
372  break;
373  }
374 
375  //Check that imported block to the chain is equal to declared block from test
376  bytes importedblock = testChain.interface().block(blockFromFields.blockHeader().hash(WithSeal));
377  TestBlock inchainBlock(toHex(importedblock));
378  checkBlocks(inchainBlock, blockFromFields, testname);
379 
380  string blockNumber = toString(testChain.interface().number());
381  string blockChainName = "default";
382  if (blObj.count("chainname") > 0)
383  blockChainName = blObj["chainname"].get_str();
384  if (blObj.count("blocknumber") > 0)
385  blockNumber = blObj["blocknumber"].get_str();
386 
387  cnote << "Tested topblock number" << blockNumber << "for chain " << blockChainName << testname;
388 
389  }//allBlocks
390 
391  //Check lastblock hash
392  BOOST_REQUIRE((o.count("lastblockhash") > 0));
393  string lastTrueBlockHash = toString(testChain.topBlock().blockHeader().hash(WithSeal));
394  BOOST_CHECK_MESSAGE(lastTrueBlockHash == o["lastblockhash"].get_str(),
395  testname + "Boost check: lastblockhash does not match " + lastTrueBlockHash + " expected: " + o["lastblockhash"].get_str());
396 
397  //Check final state (just to be sure)
398  BOOST_CHECK_MESSAGE(toString(testChain.topBlock().state().rootHash()) ==
399  toString(blockchain.topBlock().state().rootHash()),
400  testname + "State root in chain from RLP blocks != State root in chain from Field blocks!");
401 
402  State postState(State::Null); //Compare post states
403  BOOST_REQUIRE((o.count("postState") > 0));
404  ImportTest::importState(o["postState"].get_obj(), postState);
405  ImportTest::compareStates(postState, testChain.topBlock().state());
406  ImportTest::compareStates(postState, blockchain.topBlock().state());
407  }
408  }//for tests
409  TestOutputHelper::finishTest();
410 }
411 
412 //TestFunction
413 void overwriteBlockHeaderForTest(mObject const& _blObj, TestBlock& _block, ChainBranch const& _chainBranch)
414 {
415  //_blObj - json object with header data
416  //_block - which header would be overwritten
417  //_parentHeader - parent blockheader
418 
419  vector<TestBlock> const& importedBlocks = _chainBranch.importedBlocks;
420  const SealEngineFace* sealEngine = _chainBranch.blockchain.interface().sealEngine();
421 
422  BlockHeader tmp;
423  BlockHeader const& header = _block.blockHeader();
424  auto ho = _blObj;
425  if (ho.size() != 14)
426  {
427  tmp = constructHeader(
428  ho.count("parentHash") ? h256(ho["parentHash"].get_str()) : header.parentHash(),
429  ho.count("uncleHash") ? h256(ho["uncleHash"].get_str()) : header.sha3Uncles(),
430  ho.count("coinbase") ? Address(ho["coinbase"].get_str()) : header.author(),
431  ho.count("stateRoot") ? h256(ho["stateRoot"].get_str()): header.stateRoot(),
432  ho.count("transactionsTrie") ? h256(ho["transactionsTrie"].get_str()) : header.transactionsRoot(),
433  ho.count("receiptTrie") ? h256(ho["receiptTrie"].get_str()) : header.receiptsRoot(),
434  ho.count("bloom") ? LogBloom(ho["bloom"].get_str()) : header.logBloom(),
435  ho.count("difficulty") ? toInt(ho["difficulty"]) :
436  ho.count("relDifficulty") ? header.difficulty() + toInt(ho["relDifficulty"]) : header.difficulty(),
437  ho.count("number") ? toInt(ho["number"]) : header.number(),
438  ho.count("gasLimit") ? toInt(ho["gasLimit"]) : header.gasLimit(),
439  ho.count("gasUsed") ? toInt(ho["gasUsed"]) : header.gasUsed(),
440  ho.count("timestamp") ? toInt(ho["timestamp"]) : header.timestamp(),
441  ho.count("extraData") ? importByteArray(ho["extraData"].get_str()) : header.extraData());
442 
443  //Set block to update this parameters before mining the actual block
444  _block.setPremine(ho.count("parentHash") ? "parentHash" : "");
445  _block.setPremine(ho.count("uncleHash") ? "uncleHash" : "");
446  _block.setPremine(ho.count("coinbase") ? "coinbase" : "");
447  _block.setPremine(ho.count("stateRoot") ? "stateRoot" : "");
448  _block.setPremine(ho.count("transactionsTrie") ? "transactionsTrie" : "");
449  _block.setPremine(ho.count("receiptTrie") ? "receiptTrie" : "");
450  _block.setPremine(ho.count("bloom") ? "bloom" : "");
451  _block.setPremine(ho.count("difficulty") ? "difficulty" : "");
452  _block.setPremine(ho.count("number") ? "number" : "");
453  _block.setPremine(ho.count("gasLimit") ? "gasLimit" : "");
454  _block.setPremine(ho.count("gasUsed") ? "gasUsed" : "");
455  _block.setPremine(ho.count("timestamp") ? "timestamp" : "");
456  _block.setPremine(ho.count("extraData") ? "extraData" : "");
457 
458  if (ho.count("RelTimestamp"))
459  {
460  BlockHeader parentHeader = importedBlocks.at(importedBlocks.size() - 1).blockHeader();
461  tmp.setTimestamp(toInt(ho["RelTimestamp"]) + parentHeader.timestamp());
462  tmp.setDifficulty(((const Ethash*)sealEngine)->calculateDifficulty(tmp, parentHeader));
463  this_thread::sleep_for(chrono::seconds((int)toInt(ho["RelTimestamp"])));
464  }
465 
466  Ethash::setMixHash(tmp, ho.count("mixHash") ? h256(ho["mixHash"].get_str()) : Ethash::mixHash(header));
467  Ethash::setNonce(tmp, ho.count("nonce") ? Nonce(ho["nonce"].get_str()) : Ethash::nonce(header));
468  tmp.noteDirty();
469  }
470  else
471  {
472  // take the blockheader as is
473  mObject emptyState;
474  tmp = TestBlock(ho, emptyState).blockHeader();
475  }
476 
477  if (ho.count("populateFromBlock"))
478  {
479  size_t number = (size_t)toInt(ho.at("populateFromBlock"));
480  ho.erase("populateFromBlock");
481  if (number < importedBlocks.size())
482  {
483  BlockHeader parentHeader = importedBlocks.at(number).blockHeader();
484  sealEngine->populateFromParent(tmp, parentHeader);
485  }
486  else
487  {
488  cerr << TestOutputHelper::testName() + "Could not populate blockHeader from block: there are no block with number!" << TestOutputHelper::testName() << endl;
489  }
490  }
491 
492  if (ho.count("mixHash") || ho.count("nonce") || !ho.count("updatePoW"))
493  {
494  _block.setBlockHeader(tmp);
495  _block.noteDirty(); //disable integrity check in test block
496  }
497  else
498  {
499  _block.setBlockHeader(tmp);
500  _block.updateNonce(_chainBranch.blockchain);
501  }
502 }
503 
504 void overwriteUncleHeaderForTest(mObject& uncleHeaderObj, TestBlock& uncle, std::vector<TestBlock> const& uncles, ChainBranch const& _chainBranch)
505 {
506  //uncleHeaderObj - json Uncle header with additional option fields
507  //uncle - uncle Block to overwrite
508  //uncles - previously imported uncles
509  //importedBlocks - blocks already included in BlockChain
510  vector<TestBlock> const& importedBlocks = _chainBranch.importedBlocks;
511  const SealEngineFace* sealEngine = _chainBranch.blockchain.interface().sealEngine();
512 
513  if (uncleHeaderObj.count("sameAsPreviousSibling"))
514  {
515  uncleHeaderObj.erase("sameAsPreviousSibling");
516  if (uncles.size())
517  uncle = uncles.at(uncles.size() - 1);
518  else
519  cerr << TestOutputHelper::testName() + "Could not create uncle sameAsPreviousSibling: there are no siblings!";
520  return;
521  }
522 
523  if (uncleHeaderObj.count("sameAsBlock"))
524  {
525  size_t number = (size_t)toInt(uncleHeaderObj.at("sameAsBlock"));
526  uncleHeaderObj.erase("sameAsBlock");
527 
528  if (number < importedBlocks.size())
529  uncle = importedBlocks.at(number);
530  else
531  cerr << TestOutputHelper::testName() + "Could not create uncle sameAsBlock: there are no block with number " << number;
532  return;
533  }
534 
535  if (uncleHeaderObj.count("sameAsPreviousBlockUncle"))
536  {
537  size_t number = (size_t)toInt(uncleHeaderObj.at("sameAsPreviousBlockUncle"));
538  uncleHeaderObj.erase("sameAsPreviousBlockUncle");
539  if (number < importedBlocks.size())
540  {
541  vector<TestBlock> prevBlockUncles = importedBlocks.at(number).uncles();
542  if (prevBlockUncles.size())
543  uncle = prevBlockUncles[0]; //exact uncle??
544  else
545  cerr << TestOutputHelper::testName() + "Could not create uncle sameAsPreviousBlockUncle: previous block has no uncles!" << TestOutputHelper::testName() << endl;
546  }
547  else
548  cerr << TestOutputHelper::testName() + "Could not create uncle sameAsPreviousBlockUncle: there are no block imported!" << TestOutputHelper::testName() << endl;
549  return;
550  }
551 
552  string overwrite = "false";
553  if (uncleHeaderObj.count("overwriteAndRedoPoW"))
554  {
555  overwrite = uncleHeaderObj.at("overwriteAndRedoPoW").get_str();
556  uncleHeaderObj.erase("overwriteAndRedoPoW");
557  }
558 
559  //construct actual block
560  BlockHeader uncleHeader;
561  if (uncleHeaderObj.count("populateFromBlock"))
562  {
563  uncleHeader.setTimestamp((u256)time(0));
564  size_t number = (size_t)toInt(uncleHeaderObj.at("populateFromBlock"));
565  uncleHeaderObj.erase("populateFromBlock");
566  if (number < importedBlocks.size())
567  {
568  sealEngine->populateFromParent(uncleHeader, importedBlocks.at(number).blockHeader());
569  //Set Default roots for empty block
570  //m_transactionsRoot = _t; m_receiptsRoot = _r; m_sha3Uncles = _u; m_stateRoot = _s;
571  uncleHeader.setRoots((h256)fromHex("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"),
572  (h256)fromHex("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"),
573  (h256)fromHex("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"),
574  uncleHeader.stateRoot()
575  );
576 
577  if (uncleHeaderObj.count("RelTimestamp"))
578  {
579  BlockHeader parentHeader = importedBlocks.at(number).blockHeader();
580  uncleHeader.setTimestamp(toInt(uncleHeaderObj["RelTimestamp"]) + parentHeader.timestamp());
581  uncleHeader.setDifficulty(((const Ethash*)sealEngine)->calculateDifficulty(uncleHeader, parentHeader));
582  //this_thread::sleep_for(chrono::seconds((int)toInt(uncleHeaderObj["RelTimestamp"])));
583  uncleHeaderObj.erase("RelTimestamp");
584  }
585  }
586  else
587  cerr << TestOutputHelper::testName() + "Could not create uncle populateFromBlock: there are no block with number " << number << TestOutputHelper::testName() << endl;
588  }
589  else
590  {
591  mObject emptyState;
592  uncle = TestBlock(uncleHeaderObj, emptyState);
593  uncleHeader = uncle.blockHeader();
594  }
595 
596  if (overwrite != "false")
597  {
598  uncleHeader = constructHeader(
599  overwrite == "parentHash" ? h256(uncleHeaderObj.at("parentHash").get_str()) : uncleHeader.parentHash(),
600  uncleHeader.sha3Uncles(),
601  overwrite == "coinbase" ? Address(uncleHeaderObj.at("coinbase").get_str()) : uncleHeader.author(),
602  overwrite == "stateRoot" ? h256(uncleHeaderObj.at("stateRoot").get_str()) : uncleHeader.stateRoot(),
603  uncleHeader.transactionsRoot(),
604  uncleHeader.receiptsRoot(),
605  uncleHeader.logBloom(),
606  overwrite == "difficulty" ? toInt(uncleHeaderObj.at("difficulty"))
607  : overwrite == "timestamp" ? ((const Ethash*)sealEngine)->calculateDifficulty(uncleHeader, importedBlocks.at((size_t)uncleHeader.number() - 1).blockHeader())
608  : uncleHeader.difficulty(),
609  overwrite == "number" ? toInt(uncleHeaderObj.at("number")) : uncleHeader.number(),
610  overwrite == "gasLimit" ? toInt(uncleHeaderObj.at("gasLimit")) : uncleHeader.gasLimit(),
611  overwrite == "gasUsed" ? toInt(uncleHeaderObj.at("gasUsed")) : uncleHeader.gasUsed(),
612  overwrite == "timestamp" ? toInt(uncleHeaderObj.at("timestamp")) : uncleHeader.timestamp(),
613  overwrite == "extraData" ? fromHex(uncleHeaderObj.at("extraData").get_str()) : uncleHeader.extraData());
614  }
615 
616  uncle.setBlockHeader(uncleHeader);
617  uncle.updateNonce(_chainBranch.blockchain);
618 
619  if (overwrite == "nonce" || overwrite == "mixHash")
620  {
621  if (overwrite == "nonce")
622  Ethash::setNonce(uncleHeader, Nonce(uncleHeaderObj["nonce"].get_str()));
623  if (overwrite == "mixHash")
624  Ethash::setMixHash(uncleHeader, h256(uncleHeaderObj["mixHash"].get_str()));
625 
626  uncle.setBlockHeader(uncleHeader);
627  }
628 }
629 
630 void compareBlocks(TestBlock const& _a, TestBlock const& _b)
631 {
632  if (sha3(RLP(_a.bytes())[0].data()) != sha3(RLP(_b.bytes())[0].data()))
633  {
634  cnote << "block header mismatch\n";
635  cnote << toHex(RLP(_a.bytes())[0].data()) << "vs" << toHex(RLP(_b.bytes())[0].data());
636  }
637 
638  if (sha3(RLP(_a.bytes())[1].data()) != sha3(RLP(_b.bytes())[1].data()))
639  cnote << "txs mismatch\n";
640 
641  if (sha3(RLP(_a.bytes())[2].data()) != sha3(RLP(_b.bytes())[2].data()))
642  cnote << "uncle list mismatch\n" << RLP(_a.bytes())[2].data() << "\n" << RLP(_b.bytes())[2].data();
643 }
644 
646 {
648  mArray txArray;
649  for (auto const& txi: txs)
650  {
651  mObject txObject = fillJsonWithTransaction(txi);
652  txArray.push_back(txObject);
653  }
654  return txArray;
655 }
656 
658 {
659  mObject o;
660  o["parentHash"] = toString(_bi.parentHash());
661  o["uncleHash"] = toString(_bi.sha3Uncles());
662  o["coinbase"] = toString(_bi.author());
663  o["stateRoot"] = toString(_bi.stateRoot());
664  o["transactionsTrie"] = toString(_bi.transactionsRoot());
665  o["receiptTrie"] = toString(_bi.receiptsRoot());
666  o["bloom"] = toString(_bi.logBloom());
667  o["difficulty"] = toCompactHex(_bi.difficulty(), HexPrefix::Add, 1);
668  o["number"] = toCompactHex(_bi.number(), HexPrefix::Add, 1);
669  o["gasLimit"] = toCompactHex(_bi.gasLimit(), HexPrefix::Add, 1);
670  o["gasUsed"] = toCompactHex(_bi.gasUsed(), HexPrefix::Add, 1);
671  o["timestamp"] = toCompactHex(_bi.timestamp(), HexPrefix::Add, 1);
672  o["extraData"] = toHex(_bi.extraData(), 2, HexPrefix::Add);
673  o["mixHash"] = toString(Ethash::mixHash(_bi));
674  o["nonce"] = toString(Ethash::nonce(_bi));
675  o["hash"] = toString(_bi.hash());
676  return o;
677 }
678 
679 void checkExpectedException(mObject& _blObj, Exception const& _e)
680 {
681  if (!test::Options::get().checkstate)
682  return;
683 
684  string exWhat { _e.what() };
685  BOOST_REQUIRE_MESSAGE(_blObj.count("expectException") > 0, TestOutputHelper::testName() + "block import thrown unexpected Excpetion! (" + exWhat + ")");
686 
687  string exExpect = _blObj.at("expectException").get_str();
688  BOOST_REQUIRE_MESSAGE(exWhat.find(exExpect) != string::npos, TestOutputHelper::testName() + "block import expected another exeption: " + exExpect);
689  _blObj.erase(_blObj.find("expectException"));
690 }
691 
693 {
694  BOOST_CHECK(_blObj.count("blockHeader") == 0);
695  BOOST_CHECK(_blObj.count("transactions") == 0);
696  BOOST_CHECK(_blObj.count("uncleHeaders") == 0);
697 }
698 
700 {
701  // if exception is thrown, RLP is invalid and no blockHeader, Transaction list, or Uncle list should be given
702  cnote << TestOutputHelper::testName() + "block is invalid!\n";
703  _blObj.erase(_blObj.find("blockHeader"));
704  _blObj.erase(_blObj.find("uncleHeaders"));
705  _blObj.erase(_blObj.find("transactions"));
706 }
707 
708 void checkBlocks(TestBlock const& _blockFromFields, TestBlock const& _blockFromRlp, string const& _testname)
709 {
710  BlockHeader const& blockHeaderFromFields = _blockFromFields.blockHeader();
711  BlockHeader const& blockFromRlp = _blockFromRlp.blockHeader();
712 
713  BOOST_CHECK_MESSAGE(blockHeaderFromFields.hash(WithoutSeal) == blockFromRlp.hash(WithoutSeal), _testname + "hash in given RLP not matching the block hash!");
714  BOOST_CHECK_MESSAGE(blockHeaderFromFields.parentHash() == blockFromRlp.parentHash(), _testname + "parentHash in given RLP not matching the block parentHash!");
715  BOOST_CHECK_MESSAGE(blockHeaderFromFields.sha3Uncles() == blockFromRlp.sha3Uncles(), _testname + "sha3Uncles in given RLP not matching the block sha3Uncles!");
716  BOOST_CHECK_MESSAGE(blockHeaderFromFields.author() == blockFromRlp.author(), _testname + "author in given RLP not matching the block author!");
717  BOOST_CHECK_MESSAGE(blockHeaderFromFields.stateRoot() == blockFromRlp.stateRoot(), _testname + "stateRoot in given RLP not matching the block stateRoot!");
718  BOOST_CHECK_MESSAGE(blockHeaderFromFields.transactionsRoot() == blockFromRlp.transactionsRoot(), _testname + "transactionsRoot in given RLP not matching the block transactionsRoot!");
719  BOOST_CHECK_MESSAGE(blockHeaderFromFields.receiptsRoot() == blockFromRlp.receiptsRoot(), _testname + "receiptsRoot in given RLP not matching the block receiptsRoot!");
720  BOOST_CHECK_MESSAGE(blockHeaderFromFields.logBloom() == blockFromRlp.logBloom(), _testname + "logBloom in given RLP not matching the block logBloom!");
721  BOOST_CHECK_MESSAGE(blockHeaderFromFields.difficulty() == blockFromRlp.difficulty(), _testname + "difficulty in given RLP not matching the block difficulty!");
722  BOOST_CHECK_MESSAGE(blockHeaderFromFields.number() == blockFromRlp.number(), _testname + "number in given RLP not matching the block number!");
723  BOOST_CHECK_MESSAGE(blockHeaderFromFields.gasLimit() == blockFromRlp.gasLimit(),"testname + gasLimit in given RLP not matching the block gasLimit!");
724  BOOST_CHECK_MESSAGE(blockHeaderFromFields.gasUsed() == blockFromRlp.gasUsed(), _testname + "gasUsed in given RLP not matching the block gasUsed!");
725  BOOST_CHECK_MESSAGE(blockHeaderFromFields.timestamp() == blockFromRlp.timestamp(), _testname + "timestamp in given RLP not matching the block timestamp!");
726  BOOST_CHECK_MESSAGE(blockHeaderFromFields.extraData() == blockFromRlp.extraData(), _testname + "extraData in given RLP not matching the block extraData!");
727  //BOOST_CHECK_MESSAGE(Ethash::mixHash(blockHeaderFromFields) == Ethash::mixHash(blockFromRlp), _testname + "mixHash in given RLP not matching the block mixHash!");
728  //BOOST_CHECK_MESSAGE(Ethash::nonce(blockHeaderFromFields) == Ethash::nonce(blockFromRlp), _testname + "nonce in given RLP not matching the block nonce!");
729 
730  BOOST_CHECK_MESSAGE(blockHeaderFromFields == blockFromRlp, _testname + "However, blockHeaderFromFields != blockFromRlp!");
731 
732  vector<TestTransaction> const& txsFromField = _blockFromFields.testTransactions();
733  vector<TestTransaction> const& txsFromRlp = _blockFromRlp.testTransactions();
734  BOOST_CHECK_MESSAGE(txsFromRlp.size() == txsFromField.size(), _testname + "transaction list size does not match");
735 
736  for (size_t i = 0; i < txsFromField.size(); ++i)
737  {
738  Transaction const& trField = txsFromField.at(i).transaction();
739  Transaction const& trRlp = txsFromRlp.at(i).transaction();
740 
741  BOOST_CHECK_MESSAGE(trField.data() == trRlp.data(), _testname + "transaction data in rlp and in field do not match");
742  BOOST_CHECK_MESSAGE(trField.gas() == trRlp.gas(), _testname + "transaction gasLimit in rlp and in field do not match");
743  BOOST_CHECK_MESSAGE(trField.gasPrice() == trRlp.gasPrice(), _testname + "transaction gasPrice in rlp and in field do not match");
744  BOOST_CHECK_MESSAGE(trField.nonce() == trRlp.nonce(), _testname + "transaction nonce in rlp and in field do not match");
745  BOOST_CHECK_MESSAGE(trField.signature().r == trRlp.signature().r, _testname + "transaction r in rlp and in field do not match");
746  BOOST_CHECK_MESSAGE(trField.signature().s == trRlp.signature().s, _testname + "transaction s in rlp and in field do not match");
747  BOOST_CHECK_MESSAGE(trField.signature().v == trRlp.signature().v, _testname + "transaction v in rlp and in field do not match");
748  BOOST_CHECK_MESSAGE(trField.receiveAddress() == trRlp.receiveAddress(), _testname + "transaction receiveAddress in rlp and in field do not match");
749  BOOST_CHECK_MESSAGE(trField.value() == trRlp.value(), _testname + "transaction receiveAddress in rlp and in field do not match");
750 
751  BOOST_CHECK_MESSAGE(trField == trRlp, _testname + "transactions from rlp and transaction from field do not match");
752  BOOST_CHECK_MESSAGE(trField.rlp() == trRlp.rlp(), _testname + "transactions rlp do not match");
753  }
754 
755  vector<TestBlock> const& unclesFromField = _blockFromFields.uncles();
756  vector<TestBlock> const& unclesFromRlp = _blockFromRlp.uncles();
757  BOOST_REQUIRE_EQUAL(unclesFromField.size(), unclesFromRlp.size());
758  for (size_t i = 0; i < unclesFromField.size(); ++i)
759  BOOST_CHECK_MESSAGE(unclesFromField.at(i).blockHeader() == unclesFromRlp.at(i).blockHeader(), _testname + "block header in rlp and in field do not match at uncles");
760 }
761 
762 //namespaces
763 }
764 }
void checkExpectedException(mObject &_blObj, Exception const &_e)
const Object & get_obj() const
std::string toCompactHex(u256 val, HexPrefix prefix=HexPrefix::DontAdd, unsigned _min=0)
Definition: CommonData.h:175
void compareBlocks(TestBlock const &_a, TestBlock const &_b)
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
Definition: Arith256.cpp:15
TestBlock const & topBlock()
vector< TestBlock > importedBlocks
std::string toHex(T const &_data, int _w=2, HexPrefix _prefix=HexPrefix::DontAdd)
Definition: CommonData.h:54
LogBloom const & logBloom() const
Definition: BlockHeader.h:165
u256 const & number() const
Definition: BlockHeader.h:162
A queue of Transactions, each stored as RLP.
void checkBlocks(TestBlock const &_blockFromFields, TestBlock const &_blockFromRlp, string const &_testname)
void overwriteUncleHeaderForTest(mObject &uncleHeaderObj, TestBlock &uncle, std::vector< TestBlock > const &uncles, ChainBranch const &_chainBranch)
h256 const & stateRoot() const
Definition: BlockHeader.h:158
Network
The network id.
Definition: GenesisInfo.h:34
h256 hash(IncludeSeal _i=WithSeal) const
Definition: BlockHeader.cpp:64
Encapsulation of a block header.
Definition: BlockHeader.h:95
BlockChain const & interface() const
h256 const & transactionsRoot() const
Definition: BlockHeader.h:159
const char * what() const noexceptoverride
Definition: Exceptions.h:42
h160 Address
An Ethereum address: 20 bytes.
Definition: Common.h:62
std::vector< Transaction > Transactions
Nice name for vector of Transaction.
Definition: Transaction.h:121
std::hash for asio::adress
Definition: Common.h:323
assert(len-trim+(2 *lenIndices)<=WIDTH)
h256 const & sha3Uncles() const
Definition: BlockHeader.h:155
int Add(word *C, const word *A, const word *B, size_t N)
Definition: integer.cpp:2143
std::string toString(string32 const &_s)
Make normal string from fixed-length string.
Definition: CommonData.cpp:141
BlockHeader const & blockHeader() const
mObject writeBlockHeaderToJson(BlockHeader const &_bi)
static eth::Network s_sealEngineNetwork
Model of an Ethereum state, essentially a facade for the trie.
Definition: State.h:161
void noteDirty() const
Definition: BlockHeader.h:130
void eraseJsonSectionForInvalidBlock(mObject &_blObj)
SignatureStruct const & signature() const
Definition: Transaction.h:143
h256 const & parentHash() const
Definition: BlockHeader.h:154
json_spirit::mObject fillJsonWithTransaction(Transaction const &_txn)
Definition: TestHelper.cpp:124
void updateNonce(TestBlockChain const &_bc)
bytes rlp(IncludeSignature _sig=WithSignature) const
Definition: Transaction.h:107
Transactions topTransactions(unsigned _limit, h256Hash const &_avoid=h256Hash()) const
Get top transactions from the queue.
void setTimestamp(u256 const &_v)
Definition: BlockHeader.h:142
bytes fromHex(std::string const &_s, WhenError _throw=WhenError::DontThrow)
Definition: CommonData.cpp:99
Base class for all exceptions.
Definition: Exceptions.h:39
mConfig::Array_type mArray
dev::eth::BlockHeader constructHeader(h256 const &_parentHash, h256 const &_sha3Uncles, Address const &_author, h256 const &_stateRoot, h256 const &_transactionsRoot, h256 const &_receiptsRoot, dev::eth::LogBloom const &_logBloom, u256 const &_difficulty, u256 const &_number, u256 const &_gasLimit, u256 const &_gasUsed, u256 const &_timestamp, bytes const &_extraData)
Definition: TestHelper.cpp:552
vector< TestTransaction > const & testTransactions() const
unsigned number(h256 const &_hash) const
Get a number for the given hash (or the most recent mined if none given). Thread-safe.
Definition: BlockChain.h:225
ExecStats::duration max
Definition: ExecStats.cpp:36
bytes const & extraData() const
Definition: BlockHeader.h:164
std::vector< byte > bytes
Definition: Common.h:75
void overwriteBlockHeaderForTest(mObject const &_blObj, TestBlock &_block, ChainBranch const &_chainBranch)
static void forceBlockchain(string const &chainname)
bytes const & data() const
Definition: Transaction.h:131
FixedHash< 32 > h256
Definition: FixedHash.h:340
json_spirit::mObject fillJsonWithState(State const &_state)
Definition: TestHelper.cpp:139
static eth::Network s_tempBlockchainNetwork
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void >> u256
Definition: Common.h:125
bool isKnown(h256 const &_hash, bool _isCurrent=true) const
Returns true if the given block is known (though not necessarily a part of the canon chain)...
Encodes a transaction, ready to be exported to or freshly imported from RLP.
Definition: Transaction.h:84
mArray writeTransactionsToJson(TransactionQueue const &_txsQueue)
std::unordered_map< Address, AccountMask > AccountMaskMap
Definition: Account.h:240
u256 const & timestamp() const
Definition: BlockHeader.h:156
mConfig::Object_type mObject
void restoreFromHistory(size_t _importBlockNumber)
bool addBlock(TestBlock const &_block)
h256 rootHash() const
The hash of the root of our state tree.
Definition: State.h:288
void setPremine(std::string const &_parameter)
void mine(TestBlockChain const &_bc)
void checkJsonSectionForInvalidBlock(mObject &_blObj)
h256 const & receiptsRoot() const
Definition: BlockHeader.h:160
TransactionQueue const & transactionQueue() const
State const & state() const
Address const & author() const
Definition: BlockHeader.h:157
vector< TestBlock > const & uncles() const
dev::bytes const & bytes() const
#define cnote
Definition: Log.h:303
PlatformStyle::TableColorType type
Definition: rpcconsole.cpp:61
void setUncles(vector< TestBlock > const &_uncles)
u256 const & gasLimit() const
Definition: BlockHeader.h:163
bool sha3(bytesConstRef _input, bytesRef o_output)
Calculate SHA3-256 hash of the given input and load it into the given output.
Definition: SHA3.cpp:214
void addTransaction(TestTransaction const &_tr)
virtual void populateFromParent(BlockHeader &_bi, BlockHeader const &_parent) const
Don&#39;t forget to call Super::populateFromParent when subclassing & overriding.
Definition: SealEngine.cpp:41
void doBlockchainTests(json_spirit::mValue &_v, bool _fillin)
h2048 LogBloom
The log bloom&#39;s size (2048-bit).
Definition: Common.h:58
bytes block(h256 const &_hash) const
Get a block (RLP format) for the given hash (or the most recent mined if none given). Thread-safe.
dev::WithExisting max(dev::WithExisting _a, dev::WithExisting _b)
Definition: Common.h:326
void setRoots(h256 const &_t, h256 const &_r, h256 const &_u, h256 const &_s)
Definition: BlockHeader.h:144
static void resetBlockchain()
bytes importByteArray(std::string const &_str)
Definition: TestHelper.cpp:221
vector< TestBlock > syncUncles(vector< TestBlock > const &_uncles)
u256 const & gasUsed() const
Definition: BlockHeader.h:161
void addUncle(TestBlock const &_uncle)
std::string get_str(std::string::const_iterator begin, std::string::const_iterator end)
eth::Network stringToNetId(string const &_netname)
Definition: TestHelper.cpp:107
u256 const & difficulty() const
Definition: BlockHeader.h:166
uint8_t const * data
Definition: sha3.h:19
Class for interpreting Recursive Linear-Prefix Data.
Definition: RLP.h:64
void setBlockHeader(BlockHeader const &_header)
void setDifficulty(u256 const &_v)
Definition: BlockHeader.h:150
h64 Nonce
Definition: Common.h:70
u256 toInt(json_spirit::mValue const &_v)
Definition: TestHelper.cpp:195
SealEngineFace * sealEngine() const
Definition: BlockChain.h:309
Helper functions to work with json::spirit and test files.
#define BOOST_CHECK(expr)
Definition: object.cpp:17
Address receiveAddress() const
Definition: Transaction.h:122
ChainBranch(TestBlock const &_genesis)