@ -31,14 +31,57 @@ using namespace dev::eth;
namespace dev { namespace test {
bytes createBlockRLPFromFields ( mObject & _tObj ) ;
void overwriteBlockHeader ( BlockInfo & _current_BlockHeader , mObject & _blObj ) ;
BlockInfo constructBlock ( mObject & _o ) ;
void updatePoW ( BlockInfo & _bi ) ;
void writeBlockHeaderToJson ( mObject & _o , const BlockInfo & _bi ) ;
RLPStream createFullBlockFromHeader ( const BlockInfo & _bi , const bytes & _txs = RLPEmptyList , const bytes & _uncles = RLPEmptyList ) ;
void doBlockchainTests ( json_spirit : : mValue & _v , bool _fillin )
bytes createBlockRLPFromFields ( mObject & _tObj )
{
RLPStream rlpStream ;
rlpStream . appendList ( _tObj . size ( ) ) ;
if ( _tObj . count ( " parentHash " ) )
rlpStream < < importByteArray ( _tObj [ " parentHash " ] . get_str ( ) ) ;
if ( _tObj . count ( " uncleHash " ) )
rlpStream < < importByteArray ( _tObj [ " uncleHash " ] . get_str ( ) ) ;
if ( _tObj . count ( " coinbase " ) )
rlpStream < < importByteArray ( _tObj [ " coinbase " ] . get_str ( ) ) ;
if ( _tObj . count ( " stateRoot " ) )
rlpStream < < importByteArray ( _tObj [ " stateRoot " ] . get_str ( ) ) ;
if ( _tObj . count ( " transactionsTrie " ) )
rlpStream < < importByteArray ( _tObj [ " transactionsTrie " ] . get_str ( ) ) ;
if ( _tObj . count ( " receiptTrie " ) )
rlpStream < < importByteArray ( _tObj [ " receiptTrie " ] . get_str ( ) ) ;
if ( _tObj . count ( " bloom " ) )
rlpStream < < importByteArray ( _tObj [ " bloom " ] . get_str ( ) ) ;
if ( _tObj . count ( " difficulty " ) )
rlpStream < < bigint ( _tObj [ " difficulty " ] . get_str ( ) ) ;
if ( _tObj . count ( " number " ) )
rlpStream < < bigint ( _tObj [ " number " ] . get_str ( ) ) ;
if ( _tObj . count ( " gasLimit " ) )
rlpStream < < bigint ( _tObj [ " gasLimit " ] . get_str ( ) ) ;
if ( _tObj . count ( " gasUsed " ) )
rlpStream < < bigint ( _tObj [ " gasUsed " ] . get_str ( ) ) ;
if ( _tObj . count ( " timestamp " ) )
rlpStream < < bigint ( _tObj [ " timestamp " ] . get_str ( ) ) ;
if ( _tObj . count ( " extraData " ) )
rlpStream < < importByteArray ( _tObj [ " extraData " ] . get_str ( ) ) ;
if ( _tObj . count ( " nonce " ) )
rlpStream < < importByteArray ( _tObj [ " nonce " ] . get_str ( ) ) ;
return rlpStream . out ( ) ;
}
void doBlockTests ( json_spirit : : mValue & _v , bool _fillin )
{
for ( auto & i : _v . get_obj ( ) )
{
@ -46,48 +89,81 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
mObject & o = i . second . get_obj ( ) ;
BOOST_REQUIRE ( o . count ( " genesisBlockHeader " ) ) ;
BlockInfo biGenesisBlock = constructBlock ( o [ " genesisBlockHeader " ] . get_obj ( ) ) ;
BlockInfo blockFromFields ;
try
{
// construct genesis block
const bytes c_blockRLP = createBlockRLPFromFields ( o [ " genesisBlockHeader " ] . get_obj ( ) ) ;
const RLP c_bRLP ( c_blockRLP ) ;
blockFromFields . populateFromHeader ( c_bRLP , false ) ;
}
catch ( Exception const & _e )
{
cnote < < " block population did throw an exception: " < < diagnostic_information ( _e ) ;
BOOST_ERROR ( " Failed block population with Exception: " < < _e . what ( ) ) ;
continue ;
}
catch ( std : : exception const & _e )
{
BOOST_ERROR ( " Failed block population with Exception: " < < _e . what ( ) ) ;
continue ;
}
catch ( . . . )
{
cnote < < " block population did throw an unknown exception \n " ;
continue ;
}
BOOST_REQUIRE ( o . count ( " pre " ) ) ;
ImportTest importer ( o [ " pre " ] . get_obj ( ) ) ;
State state ( Address ( ) , OverlayDB ( ) , BaseState : : Empty ) ;
importer . importState ( o [ " pre " ] . get_obj ( ) , state ) ;
state . commit ( ) ;
if ( _fillin )
biGenesisBlock . stateRoot = state . rootHash ( ) ;
blockFromFields . stateRoot = state . rootHash ( ) ;
else
BOOST_CHECK_MESSAGE ( biGenesisBlock . stateRoot = = state . rootHash ( ) , " root hash does not match " ) ;
BOOST_CHECK_MESSAGE ( blockFromFields . stateRoot = = state . rootHash ( ) , " root hash does not match " ) ;
if ( _fillin )
{
// find new valid nonce
updatePoW ( biGenesisBlock ) ;
ProofOfWork pow ;
MineInfo ret ;
while ( ! ProofOfWork : : verify ( blockFromFields . headerHash ( WithoutNonce ) , blockFromFields . nonce , blockFromFields . difficulty ) )
tie ( ret , blockFromFields . nonce ) = pow . mine ( blockFromFields . headerHash ( WithoutNonce ) , blockFromFields . difficulty , 1000 , true , true ) ;
//update genesis block in json file
writeBlockHeaderToJson ( o [ " genesisBlockHeader " ] . get_obj ( ) , biGenesisBlock ) ;
o [ " genesisBlockHeader " ] . get_obj ( ) [ " stateRoot " ] = toString ( blockFromFields . stateRoot ) ;
o [ " genesisBlockHeader " ] . get_obj ( ) [ " nonce " ] = toString ( blockFromFields . nonce ) ;
}
// create new "genesis" block
RLPStream rlpGenesisBlock = createFullBlockFromHeader ( biGenesisBlock ) ;
biGenesisBlock . verifyInternals ( & rlpGenesisBlock . out ( ) ) ;
RLPStream rlpStream ;
blockFromFields . streamRLP ( rlpStream , WithNonce ) ;
RLPStream block ( 3 ) ;
block . appendRaw ( rlpStream . out ( ) ) ;
block . appendRaw ( RLPEmptyList ) ;
block . appendRaw ( RLPEmptyList ) ;
blockFromFields . verifyInternals ( & block . out ( ) ) ;
// construct blockchain
BlockChain bc ( rlpGenesisBlock . out ( ) , string ( ) , true ) ;
BlockChain bc ( b lock. out ( ) , string ( ) , true ) ;
if ( _fillin )
{
BOOST_REQUIRE ( o . count ( " blocks " ) ) ;
mArray blArray ;
vector < BlockInfo > vBiBlocks ;
vBiBlocks . push_back ( biGenesisBlock ) ;
for ( auto const & bl : o [ " blocks " ] . get_array ( ) )
{
mObject blObj = bl . get_obj ( ) ;
BOOST_REQUIRE ( blObj . count ( " transactions " ) ) ;
// get txs
TransactionQueue txs ;
BOOST_REQUIRE ( blObj . count ( " transactions " ) ) ;
for ( auto const & txObj : blObj [ " transactions " ] . get_array ( ) )
{
mObject tx = txObj . get_obj ( ) ;
@ -96,38 +172,6 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
cnote < < " failed importing transaction \n " ;
}
// write uncle list
BlockQueue uncleBlockQueue ;
mArray aUncleList ;
vector < BlockInfo > vBiUncles ;
for ( auto const & uHObj : blObj [ " uncleHeaders " ] . get_array ( ) )
{
mObject uncleHeaderObj = uHObj . get_obj ( ) ;
BlockInfo uncleBlockFromFields = constructBlock ( uncleHeaderObj ) ;
// make uncle header valid
uncleBlockFromFields . timestamp = ( u256 ) time ( 0 ) ;
if ( vBiBlocks . size ( ) > 2 )
uncleBlockFromFields . populateFromParent ( vBiBlocks [ vBiBlocks . size ( ) - 2 ] ) ;
else
continue ;
updatePoW ( uncleBlockFromFields ) ;
writeBlockHeaderToJson ( uncleHeaderObj , uncleBlockFromFields ) ;
aUncleList . push_back ( uncleHeaderObj ) ;
vBiUncles . push_back ( uncleBlockFromFields ) ;
cnote < < " import uncle in blockQueue " ;
RLPStream uncle = createFullBlockFromHeader ( uncleBlockFromFields ) ;
uncleBlockQueue . import ( & uncle . out ( ) , bc ) ;
}
blObj [ " uncleHeaders " ] = aUncleList ;
bc . sync ( uncleBlockQueue , state . db ( ) , 4 ) ;
state . commitToMine ( bc ) ;
try
{
state . sync ( bc ) ;
@ -148,8 +192,6 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
return ;
}
blObj [ " rlp " ] = " 0x " + toHex ( state . blockData ( ) ) ;
// write valid txs
mArray txArray ;
Transactions txList ;
@ -159,32 +201,118 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
txList . push_back ( tx ) ;
mObject txObject ;
txObject [ " nonce " ] = toString ( tx . nonce ( ) ) ;
txObject [ " data " ] = " 0x " + toHex ( tx . data ( ) ) ;
txObject [ " data " ] = toHex ( tx . data ( ) ) ;
txObject [ " gasLimit " ] = toString ( tx . gas ( ) ) ;
txObject [ " gasPrice " ] = toString ( tx . gasPrice ( ) ) ;
txObject [ " r " ] = " 0x " + toString ( tx . signature ( ) . r ) ;
txObject [ " s " ] = " 0x " + toString ( tx . signature ( ) . s ) ;
txObject [ " v " ] = to_string ( tx . signature ( ) . v + 27 ) ;
txObject [ " to " ] = tx . isCreation ( ) ? " " : t oString ( tx . receiveAddress ( ) ) ;
txObject [ " to " ] = toString ( tx . receiveAddress ( ) ) ;
txObject [ " value " ] = toString ( tx . value ( ) ) ;
txArray . push_back ( txObject ) ;
}
blObj [ " transactions " ] = txArray ;
blObj [ " rlp " ] = " 0x " + toHex ( state . blockData ( ) ) ;
BlockInfo current_BlockHeader = state . info ( ) ;
// overwrite blockheader with (possible wrong) data from "blockheader" in filler;
if ( blObj . count ( " blockHeader " ) )
overwriteBlockHeader ( current_BlockHeader , blObj ) ;
{
if ( blObj [ " blockHeader " ] . get_obj ( ) . size ( ) ! = 14 )
{
BlockInfo tmp = current_BlockHeader ;
if ( blObj [ " blockHeader " ] . get_obj ( ) . count ( " parentHash " ) )
tmp . parentHash = h256 ( blObj [ " blockHeader " ] . get_obj ( ) [ " parentHash " ] . get_str ( ) ) ;
if ( blObj [ " blockHeader " ] . get_obj ( ) . count ( " uncleHash " ) )
tmp . sha3Uncles = h256 ( blObj [ " blockHeader " ] . get_obj ( ) [ " uncleHash " ] . get_str ( ) ) ;
if ( blObj [ " blockHeader " ] . get_obj ( ) . count ( " coinbase " ) )
tmp . coinbaseAddress = Address ( blObj [ " blockHeader " ] . get_obj ( ) [ " coinbase " ] . get_str ( ) ) ;
if ( blObj [ " blockHeader " ] . get_obj ( ) . count ( " stateRoot " ) )
tmp . stateRoot = h256 ( blObj [ " blockHeader " ] . get_obj ( ) [ " stateRoot " ] . get_str ( ) ) ;
if ( blObj [ " blockHeader " ] . get_obj ( ) . count ( " transactionsTrie " ) )
tmp . transactionsRoot = h256 ( blObj [ " blockHeader " ] . get_obj ( ) [ " transactionsTrie " ] . get_str ( ) ) ;
if ( blObj [ " blockHeader " ] . get_obj ( ) . count ( " receiptTrie " ) )
tmp . receiptsRoot = h256 ( blObj [ " blockHeader " ] . get_obj ( ) [ " receiptTrie " ] . get_str ( ) ) ;
if ( blObj [ " blockHeader " ] . get_obj ( ) . count ( " bloom " ) )
tmp . logBloom = LogBloom ( blObj [ " blockHeader " ] . get_obj ( ) [ " bloom " ] . get_str ( ) ) ;
if ( blObj [ " blockHeader " ] . get_obj ( ) . count ( " difficulty " ) )
tmp . difficulty = toInt ( blObj [ " blockHeader " ] . get_obj ( ) [ " difficulty " ] ) ;
if ( blObj [ " blockHeader " ] . get_obj ( ) . count ( " number " ) )
tmp . number = toInt ( blObj [ " blockHeader " ] . get_obj ( ) [ " number " ] ) ;
if ( blObj [ " blockHeader " ] . get_obj ( ) . count ( " gasLimit " ) )
tmp . gasLimit = toInt ( blObj [ " blockHeader " ] . get_obj ( ) [ " gasLimit " ] ) ;
if ( blObj [ " blockHeader " ] . get_obj ( ) . count ( " gasUsed " ) )
tmp . gasUsed = toInt ( blObj [ " blockHeader " ] . get_obj ( ) [ " gasUsed " ] ) ;
if ( blObj [ " blockHeader " ] . get_obj ( ) . count ( " timestamp " ) )
tmp . timestamp = toInt ( blObj [ " blockHeader " ] . get_obj ( ) [ " timestamp " ] ) ;
if ( blObj [ " blockHeader " ] . get_obj ( ) . count ( " extraData " ) )
tmp . extraData = importByteArray ( blObj [ " blockHeader " ] . get_obj ( ) [ " extraData " ] . get_str ( ) ) ;
// find new valid nonce
if ( tmp ! = current_BlockHeader )
{
current_BlockHeader = tmp ;
cout < < " new header! \n " ;
ProofOfWork pow ;
MineInfo ret ;
while ( ! ProofOfWork : : verify ( current_BlockHeader . headerHash ( WithoutNonce ) , current_BlockHeader . nonce , current_BlockHeader . difficulty ) )
tie ( ret , current_BlockHeader . nonce ) = pow . mine ( current_BlockHeader . headerHash ( WithoutNonce ) , current_BlockHeader . difficulty , 10000 , true , true ) ;
}
}
else
{
// take the blockheader as is
const bytes c_blockRLP = createBlockRLPFromFields ( blObj [ " blockHeader " ] . get_obj ( ) ) ;
const RLP c_bRLP ( c_blockRLP ) ;
current_BlockHeader . populateFromHeader ( c_bRLP , false ) ;
}
}
// write block header
mObject oBlockHeader ;
writeBlockHeaderToJson ( oBlockHeader , current_BlockHeader ) ;
oBlockHeader [ " parentHash " ] = toString ( current_BlockHeader . parentHash ) ;
oBlockHeader [ " uncleHash " ] = toString ( current_BlockHeader . sha3Uncles ) ;
oBlockHeader [ " coinbase " ] = toString ( current_BlockHeader . coinbaseAddress ) ;
oBlockHeader [ " stateRoot " ] = toString ( current_BlockHeader . stateRoot ) ;
oBlockHeader [ " transactionsTrie " ] = toString ( current_BlockHeader . transactionsRoot ) ;
oBlockHeader [ " receiptTrie " ] = toString ( current_BlockHeader . receiptsRoot ) ;
oBlockHeader [ " bloom " ] = toString ( current_BlockHeader . logBloom ) ;
oBlockHeader [ " difficulty " ] = toString ( current_BlockHeader . difficulty ) ;
oBlockHeader [ " number " ] = toString ( current_BlockHeader . number ) ;
oBlockHeader [ " gasLimit " ] = toString ( current_BlockHeader . gasLimit ) ;
oBlockHeader [ " gasUsed " ] = toString ( current_BlockHeader . gasUsed ) ;
oBlockHeader [ " timestamp " ] = toString ( current_BlockHeader . timestamp ) ;
oBlockHeader [ " extraData " ] = toHex ( current_BlockHeader . extraData ) ;
oBlockHeader [ " nonce " ] = toString ( current_BlockHeader . nonce ) ;
blObj [ " blockHeader " ] = oBlockHeader ;
vBiBlocks . push_back ( current_BlockHeader ) ;
// compare blocks from state and from rlp
// write uncle list
mArray aUncleList ; // as of now, our parent is always the genesis block, so we can not have uncles.
blObj [ " uncleHeaders " ] = aUncleList ;
//txs:
RLPStream txStream ;
txStream . appendList ( txList . size ( ) ) ;
for ( unsigned i = 0 ; i < txList . size ( ) ; + + i )
@ -194,16 +322,13 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
txStream . appendRaw ( txrlp . out ( ) ) ;
}
RLPStream uncleStream ;
uncleStream . appendList ( vBiUncles . size ( ) ) ;
for ( unsigned i = 0 ; i < vBiUncles . size ( ) ; + + i )
{
RLPStream uncleRlp ;
vBiUncles [ i ] . streamRLP ( uncleRlp , WithNonce ) ;
uncleStream . appendRaw ( uncleRlp . out ( ) ) ;
}
RLPStream rlpStream2 ;
current_BlockHeader . streamRLP ( rlpStream2 , WithNonce ) ;
RLPStream block2 = createFullBlockFromHeader ( current_BlockHeader , txStream . out ( ) , uncleStream . out ( ) ) ;
RLPStream block2 ( 3 ) ;
block2 . appendRaw ( rlpStream2 . out ( ) ) ;
block2 . appendRaw ( txStream . out ( ) ) ;
block2 . appendRaw ( RLPEmptyList ) ;
blObj [ " rlp " ] = " 0x " + toHex ( block2 . out ( ) ) ;
@ -214,14 +339,18 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
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 ( ) ;
cnote < < " uncle list mismatch \n " ;
try
{
state . sync ( bc ) ;
bc . import ( block2 . out ( ) , state . db ( ) ) ;
state . sync ( bc ) ;
state . commit ( ) ;
ImportTest importerTmp ( o [ " pre " ] . get_obj ( ) ) ;
State stateTmp ( Address ( ) , OverlayDB ( ) , BaseState : : Empty ) ;
importerTmp . importState ( o [ " pre " ] . get_obj ( ) , stateTmp ) ;
stateTmp . commit ( ) ;
BlockChain bcTmp ( block . out ( ) , getDataDir ( ) + " /tmpBlockChain.bc " , true ) ;
stateTmp . sync ( bcTmp ) ;
bc . import ( block2 . out ( ) , stateTmp . db ( ) ) ;
stateTmp . sync ( bcTmp ) ;
}
// if exception is thrown, RLP is invalid and no blockHeader, Transaction list, or Uncle list should be given
catch ( . . . )
@ -300,8 +429,6 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
BOOST_CHECK_MESSAGE ( blockHeaderFromFields . gasUsed = = blockFromRlp . gasUsed , " gasUsed in given RLP not matching the block gasUsed! " ) ;
BOOST_CHECK_MESSAGE ( blockHeaderFromFields . timestamp = = blockFromRlp . timestamp , " timestamp in given RLP not matching the block timestamp! " ) ;
BOOST_CHECK_MESSAGE ( blockHeaderFromFields . extraData = = blockFromRlp . extraData , " extraData in given RLP not matching the block extraData! " ) ;
BOOST_CHECK_MESSAGE ( blockHeaderFromFields . mixHash = = blockFromRlp . mixHash , " mixHash in given RLP not matching the block mixHash! " ) ;
BOOST_CHECK_MESSAGE ( blockHeaderFromFields . seedHash = = blockFromRlp . seedHash , " transactionsRoot in given RLP not matching the block transactionsRoot! " ) ;
BOOST_CHECK_MESSAGE ( blockHeaderFromFields . nonce = = blockFromRlp . nonce , " nonce in given RLP not matching the block nonce! " ) ;
BOOST_CHECK_MESSAGE ( blockHeaderFromFields = = blockFromRlp , " However, blockHeaderFromFields != blockFromRlp! " ) ;
@ -361,258 +488,16 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
BOOST_CHECK_MESSAGE ( txsFromField [ i ] . receiveAddress ( ) = = txsFromRlp [ i ] . receiveAddress ( ) , " transaction receiveAddress in rlp and in field do not match " ) ;
BOOST_CHECK_MESSAGE ( txsFromField [ i ] . value ( ) = = txsFromRlp [ i ] . value ( ) , " transaction receiveAddress in rlp and in field do not match " ) ;
BOOST_CHECK_MESSAGE ( txsFromField [ i ] = = txsFromRlp [ i ] , " transactions from rlp and transaction from field do not match " ) ;
BOOST_CHECK_MESSAGE ( txsFromField [ i ] . rlp ( ) = = txsFromRlp [ i ] . rlp ( ) , " transactions rlp do not match " ) ;
BOOST_CHECK_MESSAGE ( txsFromField [ i ] = = txsFromRlp [ i ] , " transactions in rlp and in transaction field do not match " ) ;
}
// check uncle list
// uncles from uncle list field
vector < BlockInfo > uBlHsFromField ;
if ( blObj [ " uncleHeaders " ] . type ( ) ! = json_spirit : : null_type )
for ( auto const & uBlHeaderObj : blObj [ " uncleHeaders " ] . get_array ( ) )
{
mObject uBlH = uBlHeaderObj . get_obj ( ) ;
cout < < " uBlH.size(): " < < uBlH . size ( ) < < endl ;
BOOST_REQUIRE ( uBlH . size ( ) = = 17 ) ;
bytes uncleRLP = createBlockRLPFromFields ( uBlH ) ;
const RLP c_uRLP ( uncleRLP ) ;
BlockInfo uncleBlockHeader ;
try
{
uncleBlockHeader . populateFromHeader ( c_uRLP , true ) ;
}
catch ( . . . )
{
BOOST_ERROR ( " invalid uncle header " ) ;
}
uBlHsFromField . push_back ( uncleBlockHeader ) ;
}
// uncles from block RLP
vector < BlockInfo > uBlHsFromRlp ;
for ( auto const & uRLP : root [ 2 ] )
{
BlockInfo uBl ;
uBl . populateFromHeader ( uRLP , true ) ;
uBlHsFromRlp . push_back ( uBl ) ;
}
BOOST_REQUIRE_EQUAL ( uBlHsFromField . size ( ) , uBlHsFromRlp . size ( ) ) ;
for ( size_t i = 0 ; i < uBlHsFromField . size ( ) ; + + i )
BOOST_CHECK_MESSAGE ( uBlHsFromField [ i ] = = uBlHsFromRlp [ i ] , " block header in rlp and in field do not match " ) ;
}
}
}
}
// helping functions
bytes createBlockRLPFromFields ( mObject & _tObj )
{
RLPStream rlpStream ;
rlpStream . appendList ( _tObj . count ( " hash " ) > 0 ? ( _tObj . size ( ) - 1 ) : _tObj . size ( ) ) ;
if ( _tObj . count ( " parentHash " ) )
rlpStream < < importByteArray ( _tObj [ " parentHash " ] . get_str ( ) ) ;
if ( _tObj . count ( " uncleHash " ) )
rlpStream < < importByteArray ( _tObj [ " uncleHash " ] . get_str ( ) ) ;
if ( _tObj . count ( " coinbase " ) )
rlpStream < < importByteArray ( _tObj [ " coinbase " ] . get_str ( ) ) ;
if ( _tObj . count ( " stateRoot " ) )
rlpStream < < importByteArray ( _tObj [ " stateRoot " ] . get_str ( ) ) ;
if ( _tObj . count ( " transactionsTrie " ) )
rlpStream < < importByteArray ( _tObj [ " transactionsTrie " ] . get_str ( ) ) ;
if ( _tObj . count ( " receiptTrie " ) )
rlpStream < < importByteArray ( _tObj [ " receiptTrie " ] . get_str ( ) ) ;
if ( _tObj . count ( " bloom " ) )
rlpStream < < importByteArray ( _tObj [ " bloom " ] . get_str ( ) ) ;
if ( _tObj . count ( " difficulty " ) )
rlpStream < < bigint ( _tObj [ " difficulty " ] . get_str ( ) ) ;
if ( _tObj . count ( " number " ) )
rlpStream < < bigint ( _tObj [ " number " ] . get_str ( ) ) ;
if ( _tObj . count ( " gasLimit " ) )
rlpStream < < bigint ( _tObj [ " gasLimit " ] . get_str ( ) ) ;
if ( _tObj . count ( " gasUsed " ) )
rlpStream < < bigint ( _tObj [ " gasUsed " ] . get_str ( ) ) ;
if ( _tObj . count ( " timestamp " ) )
rlpStream < < bigint ( _tObj [ " timestamp " ] . get_str ( ) ) ;
if ( _tObj . count ( " extraData " ) )
rlpStream < < fromHex ( _tObj [ " extraData " ] . get_str ( ) ) ;
if ( _tObj . count ( " seedHash " ) )
rlpStream < < importByteArray ( _tObj [ " seedHash " ] . get_str ( ) ) ;
if ( _tObj . count ( " mixHash " ) )
rlpStream < < importByteArray ( _tObj [ " mixHash " ] . get_str ( ) ) ;
if ( _tObj . count ( " nonce " ) )
rlpStream < < importByteArray ( _tObj [ " nonce " ] . get_str ( ) ) ;
return rlpStream . out ( ) ;
}
void overwriteBlockHeader ( BlockInfo & _current_BlockHeader , mObject & _blObj )
{
if ( _blObj [ " blockHeader " ] . get_obj ( ) . size ( ) ! = 14 )
{
BlockInfo tmp = _current_BlockHeader ;
if ( _blObj [ " blockHeader " ] . get_obj ( ) . count ( " parentHash " ) )
tmp . parentHash = h256 ( _blObj [ " blockHeader " ] . get_obj ( ) [ " parentHash " ] . get_str ( ) ) ;
if ( _blObj [ " blockHeader " ] . get_obj ( ) . count ( " uncleHash " ) )
tmp . sha3Uncles = h256 ( _blObj [ " blockHeader " ] . get_obj ( ) [ " uncleHash " ] . get_str ( ) ) ;
if ( _blObj [ " blockHeader " ] . get_obj ( ) . count ( " coinbase " ) )
tmp . coinbaseAddress = Address ( _blObj [ " blockHeader " ] . get_obj ( ) [ " coinbase " ] . get_str ( ) ) ;
if ( _blObj [ " blockHeader " ] . get_obj ( ) . count ( " stateRoot " ) )
tmp . stateRoot = h256 ( _blObj [ " blockHeader " ] . get_obj ( ) [ " stateRoot " ] . get_str ( ) ) ;
if ( _blObj [ " blockHeader " ] . get_obj ( ) . count ( " transactionsTrie " ) )
tmp . transactionsRoot = h256 ( _blObj [ " blockHeader " ] . get_obj ( ) [ " transactionsTrie " ] . get_str ( ) ) ;
if ( _blObj [ " blockHeader " ] . get_obj ( ) . count ( " receiptTrie " ) )
tmp . receiptsRoot = h256 ( _blObj [ " blockHeader " ] . get_obj ( ) [ " receiptTrie " ] . get_str ( ) ) ;
if ( _blObj [ " blockHeader " ] . get_obj ( ) . count ( " bloom " ) )
tmp . logBloom = LogBloom ( _blObj [ " blockHeader " ] . get_obj ( ) [ " bloom " ] . get_str ( ) ) ;
if ( _blObj [ " blockHeader " ] . get_obj ( ) . count ( " difficulty " ) )
tmp . difficulty = toInt ( _blObj [ " blockHeader " ] . get_obj ( ) [ " difficulty " ] ) ;
if ( _blObj [ " blockHeader " ] . get_obj ( ) . count ( " number " ) )
tmp . number = toInt ( _blObj [ " blockHeader " ] . get_obj ( ) [ " number " ] ) ;
if ( _blObj [ " blockHeader " ] . get_obj ( ) . count ( " gasLimit " ) )
tmp . gasLimit = toInt ( _blObj [ " blockHeader " ] . get_obj ( ) [ " gasLimit " ] ) ;
if ( _blObj [ " blockHeader " ] . get_obj ( ) . count ( " gasUsed " ) )
tmp . gasUsed = toInt ( _blObj [ " blockHeader " ] . get_obj ( ) [ " gasUsed " ] ) ;
if ( _blObj [ " blockHeader " ] . get_obj ( ) . count ( " timestamp " ) )
tmp . timestamp = toInt ( _blObj [ " blockHeader " ] . get_obj ( ) [ " timestamp " ] ) ;
if ( _blObj [ " blockHeader " ] . get_obj ( ) . count ( " extraData " ) )
tmp . extraData = importByteArray ( _blObj [ " blockHeader " ] . get_obj ( ) [ " extraData " ] . get_str ( ) ) ;
if ( _blObj [ " blockHeader " ] . get_obj ( ) . count ( " mixHash " ) )
tmp . mixHash = h256 ( _blObj [ " blockHeader " ] . get_obj ( ) [ " mixHash " ] . get_str ( ) ) ;
if ( _blObj [ " blockHeader " ] . get_obj ( ) . count ( " seedHash " ) )
tmp . seedHash = h256 ( _blObj [ " blockHeader " ] . get_obj ( ) [ " seedHash " ] . get_str ( ) ) ;
// find new valid nonce
if ( tmp ! = _current_BlockHeader )
{
_current_BlockHeader = tmp ;
ProofOfWork pow ;
std : : pair < MineInfo , Ethash : : Proof > ret ;
while ( ! ProofOfWork : : verify ( _current_BlockHeader ) )
{
ret = pow . mine ( _current_BlockHeader , 1000 , true , true ) ; // tie(ret, blockFromFields.nonce)
Ethash : : assignResult ( ret . second , _current_BlockHeader ) ;
BOOST_CHECK_MESSAGE ( ( blObj [ " uncleList " ] . type ( ) = = json_spirit : : null_type ? 0 : blObj [ " uncleList " ] . get_array ( ) . size ( ) ) = = 0 , " Uncle list is not empty, but the genesis block can not have uncles " ) ;
}
}
}
else
{
// take the blockheader as is
const bytes c_blockRLP = createBlockRLPFromFields ( _blObj [ " blockHeader " ] . get_obj ( ) ) ;
const RLP c_bRLP ( c_blockRLP ) ;
_current_BlockHeader . populateFromHeader ( c_bRLP , false ) ;
}
}
BlockInfo constructBlock ( mObject & _o )
{
BlockInfo ret ;
try
{
// construct genesis block
const bytes c_blockRLP = createBlockRLPFromFields ( _o ) ;
const RLP c_bRLP ( c_blockRLP ) ;
ret . populateFromHeader ( c_bRLP , false ) ;
}
catch ( Exception const & _e )
{
cnote < < " block population did throw an exception: " < < diagnostic_information ( _e ) ;
BOOST_ERROR ( " Failed block population with Exception: " < < _e . what ( ) ) ;
}
catch ( std : : exception const & _e )
{
BOOST_ERROR ( " Failed block population with Exception: " < < _e . what ( ) ) ;
}
catch ( . . . )
{
BOOST_ERROR ( " block population did throw an unknown exception \n " ) ;
}
return ret ;
}
void updatePoW ( BlockInfo & _bi )
{
ProofOfWork pow ;
std : : pair < MineInfo , Ethash : : Proof > ret ;
while ( ! ProofOfWork : : verify ( _bi ) )
{
ret = pow . mine ( _bi , 10000 , true , true ) ; // tie(ret, blockFromFields.nonce)
Ethash : : assignResult ( ret . second , _bi ) ;
}
}
void writeBlockHeaderToJson ( mObject & _o , const BlockInfo & _bi )
{
_o [ " parentHash " ] = toString ( _bi . parentHash ) ;
_o [ " uncleHash " ] = toString ( _bi . sha3Uncles ) ;
_o [ " coinbase " ] = toString ( _bi . coinbaseAddress ) ;
_o [ " stateRoot " ] = toString ( _bi . stateRoot ) ;
_o [ " transactionsTrie " ] = toString ( _bi . transactionsRoot ) ;
_o [ " receiptTrie " ] = toString ( _bi . receiptsRoot ) ;
_o [ " bloom " ] = toString ( _bi . logBloom ) ;
_o [ " difficulty " ] = toString ( _bi . difficulty ) ;
_o [ " number " ] = toString ( _bi . number ) ;
_o [ " gasLimit " ] = toString ( _bi . gasLimit ) ;
_o [ " gasUsed " ] = toString ( _bi . gasUsed ) ;
_o [ " timestamp " ] = toString ( _bi . timestamp ) ;
_o [ " extraData " ] = " 0x " + toHex ( _bi . extraData ) ;
_o [ " mixHash " ] = toString ( _bi . mixHash ) ;
_o [ " seedHash " ] = toString ( _bi . seedHash ) ;
_o [ " nonce " ] = toString ( _bi . nonce ) ;
_o [ " hash " ] = toString ( _bi . hash ) ;
}
RLPStream createFullBlockFromHeader ( const BlockInfo & _bi , const bytes & _txs , const bytes & _uncles )
{
RLPStream rlpStream ;
_bi . streamRLP ( rlpStream , WithNonce ) ;
RLPStream ret ( 3 ) ;
ret . appendRaw ( rlpStream . out ( ) ) ;
ret . appendRaw ( _txs ) ;
ret . appendRaw ( _uncles ) ;
return ret ;
}
} } // Namespace Close
@ -620,27 +505,32 @@ BOOST_AUTO_TEST_SUITE(BlockChainTests)
BOOST_AUTO_TEST_CASE ( bcBlockChainTest )
{
dev : : test : : executeTests ( " bcBlockChainTest " , " /BlockTests " , dev : : test : : doBlockchain Tests ) ;
dev : : test : : executeTests ( " bcBlockChainTest " , " /BlockTests " , dev : : test : : doBlockTests ) ;
}
BOOST_AUTO_TEST_CASE ( bcValidBlockTest )
{
dev : : test : : executeTests ( " bcValidBlockTest " , " /BlockTests " , dev : : test : : doBlockchainTests ) ;
}
//BOOST_AUTO_TEST_CASE(blValidBlockTest)
//{
// dev::test::executeTests("blValidBlockTest", "/BlockTests", dev::test::doBlockTests);
//}
BOOST_AUTO_TEST_CASE ( bcInvalidHeaderTest )
{
dev : : test : : executeTests ( " bcInvalidHeaderTest " , " /BlockTests " , dev : : test : : doBlockchainTests ) ;
}
//BOOST_AUTO_TEST_CASE(blInvalidTransactionRLP)
//{
// dev::test::executeTests("blInvalidTransactionRLP", "/BlockTests", dev::test::doBlockTests);
//}
BOOST_AUTO_TEST_CASE ( bcUncleTest )
{
dev : : test : : executeTests ( " bcUncleTest " , " /BlockTests " , dev : : test : : doBlockchainTests ) ;
}
//BOOST_AUTO_TEST_CASE(blInvalidHeaderTest)
//{
// dev::test::executeTests("blInvalidHeaderTest", "/BlockTests", dev::test::doBlockTests);
//}
//BOOST_AUTO_TEST_CASE(blForkBlocks)
//{
// dev::test::executeTests("blForkBlocks", "/BlockTests", dev::test::doBlockTests);
//}
BOOST_AUTO_TEST_CASE ( userDefinedFileBc )
BOOST_AUTO_TEST_CASE ( userDefinedFileBl )
{
dev : : test : : userDefinedTest ( " --bctest " , dev : : test : : doBlockchainTests ) ;
dev : : test : : userDefinedTest ( " --bl test " , dev : : test : : doBlockTests ) ;
}
BOOST_AUTO_TEST_SUITE_END ( )