Browse Source

Merge pull request #2850 from winsvega/block2

BlockchainTests mining
cl-refactor
Gav Wood 10 years ago
parent
commit
545531e6a2
  1. 2
      test/TestHelper.cpp
  2. 2
      test/libethereum/BlockchainTestsFiller/bcValidBlockTestFiller.json
  3. 270
      test/libethereum/blockchain.cpp
  4. 1
      test/libethereum/state.cpp

2
test/TestHelper.cpp

@ -269,7 +269,7 @@ int ImportTest::compareStates(State const& _stateExpect, State const& _statePost
for (auto const& a: _stateExpect.addresses())
{
CHECK(_statePost.addressInUse(a.first), "Filling Test: " << a.first << " missing expected address!");
CHECK(_statePost.addressInUse(a.first), "Check State: " << a.first << " missing expected address!");
if (_statePost.addressInUse(a.first))
{
AccountMask addressOptions(true);

2
test/libethereum/BlockchainTestsFiller/bcValidBlockTestFiller.json

@ -167,7 +167,7 @@
},
"expect" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "100"
"balance" : "5100"
}
},
"pre" : {

270
test/libethereum/blockchain.cpp

@ -45,7 +45,7 @@ BlockHeader constructBlock(mObject& _o, h256 const& _stateRoot = h256{});
bytes createBlockRLPFromFields(mObject& _tObj, h256 const& _stateRoot = h256{});
RLPStream createFullBlockFromHeader(BlockHeader const& _bi, bytes const& _txs = RLPEmptyList, bytes const& _uncles = RLPEmptyList);
mArray writeTransactionsToJson(Transactions const& txs);
mArray writeTransactionsToJson(Transactions const& _txs);
mObject writeBlockHeaderToJson(mObject& _o, BlockHeader const& _bi);
void overwriteBlockHeader(BlockHeader& _current_BlockHeader, mObject& _blObj, const BlockHeader& _parent);
void updatePoW(BlockHeader& _bi);
@ -69,16 +69,16 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
TBOOST_REQUIRE(o.count("pre"));
ImportTest importer(o, _fillin, testType::BlockChainTests);
TransientDirectory td_stateDB_tmp;
TransientDirectory tdStateDB;
BlockHeader biGenesisBlock = constructBlock(o["genesisBlockHeader"].get_obj(), h256{});
State trueState(OverlayDB(State::openDB(td_stateDB_tmp.path(), h256{}, WithExisting::Kill)), BaseState::Empty);
importer.importState(o["pre"].get_obj(), trueState);
State trueState(OverlayDB(State::openDB(tdStateDB.path(), h256{}, WithExisting::Kill)), BaseState::Empty);
ImportTest::importState(o["pre"].get_obj(), trueState);
o["pre"] = fillJsonWithState(trueState); //convert all fields to hex
trueState.commit();
//Imported blocks from the start
std::vector<blockSet> blockSets; //Block(bytes) => UncleList(Blocks(bytes))
vector<blockSet> blockSets; //Block(bytes) => UncleList(Blocks(bytes))
if (_fillin)
biGenesisBlock = constructBlock(o["genesisBlockHeader"].get_obj(), trueState.rootHash());
@ -120,7 +120,7 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
{
mObject blObj = bl.get_obj();
if (blObj.count("blocknumber") > 0)
importBlockNumber = std::max((int)toInt(blObj["blocknumber"]), 1);
importBlockNumber = max((int)toInt(blObj["blocknumber"]), 1);
else
importBlockNumber++;
@ -128,13 +128,13 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
vBiBlocks.clear();
vBiBlocks.push_back(biGenesisBlock);
TransientDirectory td_stateDB, td_bc;
FullBlockChain<Ethash> bc(rlpGenesisBlock.out(), AccountMap(), td_bc.path(), WithExisting::Kill);
TransientDirectory tdBc;
TransientDirectory tdStateDB;
FullBlockChain<Ethash> bc(rlpGenesisBlock.out(), AccountMap(), tdBc.path(), WithExisting::Kill);
OverlayDB database (State::openDB(td_stateDB.path(), h256{}, WithExisting::Kill));
State state(database, BaseState::Empty);
Block block(database, BaseState::Empty, biGenesisBlock.beneficiary());
state = importer.m_statePre;
//OverlayDB database (State::openDB(td_stateDB.path(), h256{}, WithExisting::Kill));
State state(OverlayDB(State::openDB(tdStateDB.path(), h256{}, WithExisting::Kill)), BaseState::Empty); //= importer.m_statePre;
ImportTest::importState(o["pre"].get_obj(), state);
state.commit();
//import previous blocks
@ -150,7 +150,6 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
bc.sync(uncleQueue, state.db(), 4);
bc.attemptImport(blockFromSet, state.db());
vBiBlocks.push_back(BlockHeader(blockFromSet));
//state.sync(bc);
}
// get txs
@ -188,10 +187,11 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
cnote << "error in importing uncle! This produces an invalid block (May be by purpose for testing).";
}
}
bc.sync(uncleBlockQueue, state.db(), 4);
block.commitToSeal(bc);
//mine a new block on top of previously imported
Block block = bc.genesisBlock(state.db()); //NOT CLEAR WHAT IT RETURNS IF bc INITIALIZED WITH CUSTOM GENESIS BLOCK
block.setBeneficiary(biGenesisBlock.beneficiary());
try
{
block.sync(bc);
@ -209,126 +209,127 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
return;
}
blObj["rlp"] = toHex(block.blockData(), 2, HexPrefix::Add);
//get valid transactions
Transactions txList;
for (auto const& txi: txs.topTransactions(std::numeric_limits<unsigned>::max()))
txList.push_back(txi);
blObj["transactions"] = writeTransactionsToJson(txList);
BlockHeader current_BlockHeader(block.blockData());
RLPStream uncleStream;
uncleStream.appendList(vBiUncles.size());
for (unsigned i = 0; i < vBiUncles.size(); ++i)
{
RLPStream uncleRlp;
vBiUncles[i].streamRLP(uncleRlp);
uncleStream.appendRaw(uncleRlp.out());
}
if (blObj.count("blockHeader"))
overwriteBlockHeader(current_BlockHeader, blObj, bc.info());
if (blObj.count("blockHeader") && blObj["blockHeader"].get_obj().count("bruncle"))
current_BlockHeader.populateFromParent(vBiBlocks[vBiBlocks.size() -1]);
if (vBiUncles.size())
{
// update unclehash in case of invalid uncles
current_BlockHeader.setSha3Uncles(sha3(uncleStream.out()));
updatePoW(current_BlockHeader);
}
// write block header
mObject oBlockHeader;
writeBlockHeaderToJson(oBlockHeader, current_BlockHeader);
blObj["blockHeader"] = oBlockHeader;
vBiBlocks.push_back(current_BlockHeader);
// compare blocks from state and from rlp
RLPStream txStream;
txStream.appendList(txList.size());
for (unsigned i = 0; i < txList.size(); ++i)
{
RLPStream txrlp;
txList[i].streamRLP(txrlp);
txStream.appendRaw(txrlp.out());
}
RLPStream blockRLP = createFullBlockFromHeader(current_BlockHeader, txStream.out(), uncleStream.out());
blObj["rlp"] = toHex(blockRLP.out(), 2, HexPrefix::Add);
if (sha3(RLP(block.blockData())[0].data()) != sha3(RLP(blockRLP.out())[0].data()))
{
cnote << "block header mismatch block.blockData() vs updated block.info()\n";
cnote << toHex(RLP(block.blockData())[0].data()) << "vs" << toHex(RLP(blockRLP.out())[0].data());
}
if (sha3(RLP(block.blockData())[1].data()) != sha3(RLP(blockRLP.out())[1].data()))
cnote << "txs mismatch\n";
if (sha3(RLP(block.blockData())[2].data()) != sha3(RLP(blockRLP.out())[2].data()))
cnote << "uncle list mismatch\n" << RLP(block.blockData())[2].data() << "\n" << RLP(blockRLP.out())[2].data();
try
{
block.sync(bc);
bc.import(blockRLP.out(), block.db());
block.sync(bc);
//there we get new blockchain status in state which could have more difficulty than we have in trueState
//attempt to import new block to the true blockchain
trueBc.sync(uncleBlockQueue, trueState.db(), 4);
trueBc.attemptImport(blockRLP.out(), trueState.db());
// blObj["rlp"] = toHex(state.blockData(), 2, HexPrefix::Add);
// //get valid transactions
// Transactions txList;
// for (auto const& txi: txs.topTransactions(std::numeric_limits<unsigned>::max()))
// txList.push_back(txi);
// blObj["transactions"] = writeTransactionsToJson(txList);
// BlockHeader current_BlockHeader = state.info();
// RLPStream uncleStream;
// uncleStream.appendList(vBiUncles.size());
// for (unsigned i = 0; i < vBiUncles.size(); ++i)
// {
// RLPStream uncleRlp;
// vBiUncles[i].streamRLP(uncleRlp);
// uncleStream.appendRaw(uncleRlp.out());
// }
// if (blObj.count("blockHeader"))
// overwriteBlockHeader(current_BlockHeader, blObj);
// if (blObj.count("blockHeader") && blObj["blockHeader"].get_obj().count("bruncle"))
// current_BlockHeader.populateFromParent(vBiBlocks[vBiBlocks.size() -1]);
// if (vBiUncles.size())
// {
// // update unclehash in case of invalid uncles
// current_BlockHeader.setSha3Uncles(sha3(uncleStream.out()));
// updatePoW(current_BlockHeader);
// }
// // write block header
// mObject oBlockHeader;
// writeBlockHeaderToJson(oBlockHeader, current_BlockHeader);
// blObj["blockHeader"] = oBlockHeader;
// vBiBlocks.push_back(current_BlockHeader);
// // compare blocks from state and from rlp
// RLPStream txStream;
// txStream.appendList(txList.size());
// for (unsigned i = 0; i < txList.size(); ++i)
// {
// RLPStream txrlp;
// txList[i].streamRLP(txrlp);
// txStream.appendRaw(txrlp.out());
// }
// RLPStream block2 = createFullBlockFromHeader(current_BlockHeader, txStream.out(), uncleStream.out());
// blObj["rlp"] = toHex(block2.out(), 2, HexPrefix::Add);
// if (sha3(RLP(state.blockData())[0].data()) != sha3(RLP(block2.out())[0].data()))
// {
// cnote << "block header mismatch state.blockData() vs updated state.info()\n";
// cerr << toHex(state.blockData()) << "vs" << toHex(block2.out());
// }
// if (sha3(RLP(state.blockData())[1].data()) != sha3(RLP(block2.out())[1].data()))
// cnote << "txs mismatch\n";
// if (sha3(RLP(state.blockData())[2].data()) != sha3(RLP(block2.out())[2].data()))
// cnote << "uncle list mismatch\n" << RLP(state.blockData())[2].data() << "\n" << RLP(block2.out())[2].data();
// try
// {
// state.sync(bc);
// bc.import(block2.out(), state.db());
// state.sync(bc);
// state.commit();
// //there we get new blockchain status in state which could have more difficulty than we have in trueState
// //attempt to import new block to the true blockchain
// trueBc.sync(uncleBlockQueue, trueState.db(), 4);
// trueBc.attemptImport(block2.out(), trueState.db());
// trueState.sync(trueBc);
// blockSet newBlock;
// newBlock.first = block2.out();
// newBlock.second = uncleBlockQueueList;
// if (importBlockNumber < blockSets.size())
// {
// //make new correct history of imported blocks
// blockSets[importBlockNumber] = newBlock;
// for (size_t i = importBlockNumber + 1; i < blockSets.size(); i++)
// blockSets.pop_back();
// }
// else
// blockSets.push_back(newBlock);
// }
// // if exception is thrown, RLP is invalid and no blockHeader, Transaction list, or Uncle list should be given
// catch (...)
// {
// cnote << "block is invalid!\n";
// blObj.erase(blObj.find("blockHeader"));
// blObj.erase(blObj.find("uncleHeaders"));
// blObj.erase(blObj.find("transactions"));
// }
// blArray.push_back(blObj);
// this_thread::sleep_for(chrono::seconds(1));
if (block.blockData() == trueBc.block())
trueState = block.state();
blockSet newBlock;
newBlock.first = blockRLP.out();
newBlock.second = uncleBlockQueueList;
if (importBlockNumber < blockSets.size())
{
//make new correct history of imported blocks
blockSets[importBlockNumber] = newBlock;
for (size_t i = importBlockNumber + 1; i < blockSets.size(); i++)
blockSets.pop_back();
}
else
blockSets.push_back(newBlock);
}
// if exception is thrown, RLP is invalid and no blockHeader, Transaction list, or Uncle list should be given
catch (...)
{
cnote << "block is invalid!\n";
blObj.erase(blObj.find("blockHeader"));
blObj.erase(blObj.find("uncleHeaders"));
blObj.erase(blObj.find("transactions"));
}
blArray.push_back(blObj);
this_thread::sleep_for(chrono::seconds(1));
} //for blocks
// if (o.count("expect") > 0)
// {
// AccountMaskMap expectStateMap;
// State stateExpect(OverlayDB(), BaseState::Empty, biGenesisBlock.beneficiary());
// ImportTest::importState(o["expect"].get_obj(), stateExpect, expectStateMap);
// ImportTest::checkExpectedState(stateExpect, trueState, expectStateMap, Options::get().checkState ? WhenError::Throw : WhenError::DontThrow);
// o.erase(o.find("expect"));
// }
// o["blocks"] = blArray;
// o["postState"] = fillJsonWithState(trueState);
// o["lastblockhash"] = toString(trueBc.info().hash());
// //make all values hex in pre section
// State prestate(OverlayDB(), BaseState::Empty);
// ImportTest::importState(o["pre"].get_obj(), prestate);
// o["pre"] = fillJsonWithState(prestate);
if (o.count("expect") > 0)
{
AccountMaskMap expectStateMap;
State stateExpect(OverlayDB(), BaseState::Empty);
ImportTest::importState(o["expect"].get_obj(), stateExpect, expectStateMap);
if (ImportTest::compareStates(stateExpect, trueState, expectStateMap, Options::get().checkState ? WhenError::Throw : WhenError::DontThrow))
cerr << testname << endl;
o.erase(o.find("expect"));
}
o["blocks"] = blArray;
o["postState"] = fillJsonWithState(trueState);
o["lastblockhash"] = toString(trueBc.info().hash());
//make all values hex in pre section
State prestate(OverlayDB(), BaseState::Empty);
ImportTest::importState(o["pre"].get_obj(), prestate);
o["pre"] = fillJsonWithState(prestate);
}//_fillin
else
{
@ -561,7 +562,6 @@ mArray importUncles(mObject const& _blObj, vector<BlockHeader>& _vBiUncles, vect
// make uncle header valid
uncleBlockFromFields.setTimestamp((u256)time(0));
cnote << "uncle block n = " << toString(uncleBlockFromFields.number());
if (_vBiBlocks.size() > 2)
{
if (uncleBlockFromFields.number() - 1 < _vBiBlocks.size())
@ -747,10 +747,10 @@ void updatePoW(BlockHeader& _bi)
_bi.noteDirty();
}
mArray writeTransactionsToJson(Transactions const& txs)
mArray writeTransactionsToJson(Transactions const& _txs)
{
mArray txArray;
for (auto const& txi: txs)
for (auto const& txi: _txs)
{
mObject txObject = fillJsonWithTransaction(txi);
txArray.push_back(txObject);

1
test/libethereum/state.cpp

@ -62,7 +62,6 @@ void doStateTests(json_spirit::mValue& v, bool _fillin)
const State importedStatePost = importer.m_statePost;
bytes output;
// execute transaction
Listener::ExecTimeGuard guard{i.first};
output = importer.executeTest();

Loading…
Cancel
Save