@ -158,6 +158,7 @@ State::State(State const& _s):
m_transactions ( _s . m_transactions ) ,
m_receipts ( _s . m_receipts ) ,
m_transactionSet ( _s . m_transactionSet ) ,
m_touched ( _s . m_touched ) ,
m_cache ( _s . m_cache ) ,
m_previousBlock ( _s . m_previousBlock ) ,
m_currentBlock ( _s . m_currentBlock ) ,
@ -206,7 +207,7 @@ State::~State()
{
}
StateDiff State : : diff ( State const & _c ) const
StateDiff State : : diff ( State const & _c , bool _quick ) const
{
StateDiff ret ;
@ -217,19 +218,29 @@ StateDiff State::diff(State const& _c) const
auto trie = SecureTrieDB < Address , OverlayDB > ( const_cast < OverlayDB * > ( & m_db ) , rootHash ( ) ) ;
auto trieD = SecureTrieDB < Address , OverlayDB > ( const_cast < OverlayDB * > ( & _c . m_db ) , _c . rootHash ( ) ) ;
for ( auto i : trie )
if ( _quick )
{
trieAds = m_touched ;
trieAdsD = _c . m_touched ;
( ads + = m_touched ) + = _c . m_touched ;
}
else
{
for ( auto const & i : trie )
ads . insert ( i . first ) , trieAds . insert ( i . first ) ;
for ( auto i : trieD )
for ( auto const & i : trieD )
ads . insert ( i . first ) , trieAdsD . insert ( i . first ) ;
for ( auto i : m_cache )
}
for ( auto const & i : m_cache )
ads . insert ( i . first ) ;
for ( auto i : _c . m_cache )
for ( auto const & i : _c . m_cache )
ads . insert ( i . first ) ;
// cnote << *this;
// cnote << _c;
for ( auto i : ads )
for ( auto const & i : ads )
{
auto it = m_cache . find ( i ) ;
auto itD = _c . m_cache . find ( i ) ;
@ -272,7 +283,7 @@ void State::ensureCached(std::unordered_map<Address, Account>& _cache, Address _
void State : : commit ( )
{
dev : : eth : : commit ( m_cache , m_db , m_state ) ;
m_touched + = dev : : eth : : commit ( m_cache , m_db , m_state ) ;
m_cache . clear ( ) ;
}
@ -450,6 +461,7 @@ void State::resetCurrent()
m_receipts . clear ( ) ;
m_transactionSet . clear ( ) ;
m_cache . clear ( ) ;
m_touched . clear ( ) ;
m_currentBlock = BlockInfo ( ) ;
m_currentBlock . coinbaseAddress = m_ourAddress ;
m_currentBlock . timestamp = max ( m_previousBlock . timestamp + 1 , ( u256 ) time ( 0 ) ) ;
@ -577,19 +589,20 @@ string State::vmTrace(bytesConstRef _block, BlockChain const& _bc, ImportRequire
LastHashes lh = _bc . lastHashes ( ( unsigned ) m_previousBlock . number ) ;
vector < bytes > receipts ;
ostringstream ss ;
string ret ;
unsigned i = 0 ;
for ( auto const & tr : rlp [ 1 ] )
{
ss < < " VM Execution of transaction " < < i < < " : " < < endl ;
execute ( lh , Transaction ( tr . data ( ) , CheckTransaction : : Everything ) , Permanence : : Committed , Executive : : standardTrace ( ss ) ) ;
StandardTrace st ;
execute ( lh , Transaction ( tr . data ( ) , CheckTransaction : : Everything ) , Permanence : : Committed , [ & ] ( uint64_t _steps , Instruction _inst , bigint _newMemSize , bigint _gasCost , bigint _gas , VM * _vm , ExtVMFace const * _extVM ) { st ( _steps , _inst , _newMemSize , _gasCost , _gas , _vm , _extVM ) ; } ) ;
ret + = ( ret . empty ( ) ? " [ " : " , " ) + st . json ( ) ;
RLPStream receiptRLP ;
m_receipts . back ( ) . streamRLP ( receiptRLP ) ;
receipts . push_back ( receiptRLP . out ( ) ) ;
+ + i ;
ss < < endl ;
}
return ss . str ( ) ;
return ret . empty ( ) ? " [] " : ( ret + " ] " ) ;
}
u256 State : : enact ( bytesConstRef _block , BlockChain const & _bc , ImportRequirements : : value _ir )
@ -605,6 +618,7 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, ImportRequirement
# endif
if ( m_currentBlock . parentHash ! = m_previousBlock . hash ( ) )
// Internal client error.
BOOST_THROW_EXCEPTION ( InvalidParentHash ( ) ) ;
// Populate m_currentBlock with the correct values.
@ -624,16 +638,19 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, ImportRequirement
unsigned i = 0 ;
for ( auto const & tr : rlp [ 1 ] )
{
try {
try
{
LogOverride < ExecutiveWarnChannel > o ( false ) ;
execute ( lh , Transaction ( tr . data ( ) , CheckTransaction : : Everything ) ) ;
}
catch ( . . . )
catch ( Exception & ex )
{
badBlock ( _block , " Invalid transaction " ) ;
badBlock ( _block , " Invalid transaction: " + toString ( toTransactionException ( ex ) ) ) ;
cwarn < < " Transaction Index: " < < i ;
LogOverride < ExecutiveWarnChannel > o ( true ) ;
execute ( lh , Transaction ( tr . data ( ) , CheckTransaction : : Everything ) ) ;
DEV_IGNORE_EXCEPTIONS ( execute ( lh , Transaction ( tr . data ( ) , CheckTransaction : : Everything ) ) ) ;
ex < < errinfo_transactionIndex ( i ) ;
throw ;
}
@ -658,7 +675,12 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, ImportRequirement
cwarn < < " " < < TransactionReceipt ( & b ) ;
}
cwarn < < " VMTrace: \n " < < vmTrace ( _block , _bc , _ir ) ;
BOOST_THROW_EXCEPTION ( InvalidReceiptsStateRoot ( ) ) ;
InvalidReceiptsStateRoot ex ;
ex < < Hash256RequirementError ( receiptsRoot , m_currentBlock . receiptsRoot ) ;
ex < < errinfo_receipts ( receipts ) ;
ex < < errinfo_vmtrace ( vmTrace ( _block , _bc , _ir ) ) ;
BOOST_THROW_EXCEPTION ( ex ) ;
}
if ( m_currentBlock . logBloom ! = logBloom ( ) )
@ -671,7 +693,10 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, ImportRequirement
cwarn < < " " < < j < < " : " < < TransactionReceipt ( & b ) . bloom ( ) . hex ( ) ;
}
cwarn < < " Final bloom: " < < m_currentBlock . logBloom . hex ( ) ;
BOOST_THROW_EXCEPTION ( InvalidLogBloom ( ) ) ;
InvalidLogBloom ex ;
ex < < LogBloomRequirementError ( logBloom ( ) , m_currentBlock . logBloom ) ;
ex < < errinfo_receipts ( receipts ) ;
BOOST_THROW_EXCEPTION ( ex ) ;
}
// Initialise total difficulty calculation.
@ -681,32 +706,47 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, ImportRequirement
if ( rlp [ 2 ] . itemCount ( ) > 2 )
{
badBlock ( _block , " Too many uncles " ) ;
BOOST_THROW_EXCEPTION ( TooManyUncles ( ) ) ;
BOOST_THROW_EXCEPTION ( TooManyUncles ( ) < < errinfo_max ( 2 ) < < errinfo_got ( rlp [ 2 ] . itemCount ( ) ) ) ;
}
vector < BlockInfo > rewarded ;
h256Hash excluded = _bc . allKinFrom ( m_currentBlock . parentHash , 6 ) ;
excluded . insert ( m_currentBlock . hash ( ) ) ;
unsigned ii = 0 ;
for ( auto const & i : rlp [ 2 ] )
{
try
{
auto h = sha3 ( i . data ( ) ) ;
if ( excluded . count ( h ) )
{
badBlock ( _block , " Invalid uncle included " ) ;
BOOST_THROW_EXCEPTION ( UncleInChain ( ) < < errinfo_comment ( " Uncle in block already mentioned " ) < < errinfo_data ( toString ( excluded ) ) < < errinfo_hash256 ( sha3 ( i . data ( ) ) ) ) ;
UncleInChain ex ;
ex < < errinfo_comment ( " Uncle in block already mentioned " ) ;
ex < < errinfo_unclesExcluded ( excluded ) ;
ex < < errinfo_hash256 ( sha3 ( i . data ( ) ) ) ;
BOOST_THROW_EXCEPTION ( ex ) ;
}
excluded . insert ( h ) ;
BlockInfo uncle = BlockInfo : : fromHeader ( i . data ( ) , ( _ir & ImportRequirements : : CheckUncles ) ? CheckEverything : IgnoreNonce , h ) ;
BlockInfo uncleParent ( _bc . block ( uncle . parentHash ) ) ;
BlockInfo uncle ;
BlockInfo uncleParent ;
uncle = BlockInfo : : fromHeader ( i . data ( ) , ( _ir & ImportRequirements : : CheckUncles ) ? CheckEverything : IgnoreNonce , h ) ;
if ( ! _bc . isKnown ( uncle . parentHash ) )
BOOST_THROW_EXCEPTION ( UnknownParent ( ) ) ;
uncleParent = BlockInfo ( _bc . block ( uncle . parentHash ) ) ;
if ( ( bigint ) uncleParent . number < ( bigint ) m_currentBlock . number - 7 )
{
badBlock ( _block , " Uncle too old " ) ;
cwarn < < " Uncle number: " < < uncle . number ;
cwarn < < " Uncle parent number: " < < uncleParent . number ;
cwarn < < " Block number: " < < m_currentBlock . number ;
BOOST_THROW_EXCEPTION ( UncleTooOld ( ) ) ;
UncleTooOld ex ;
ex < < errinfo_uncleNumber ( uncle . number ) ;
ex < < errinfo_currentNumber ( m_currentBlock . number ) ;
BOOST_THROW_EXCEPTION ( ex ) ;
}
else if ( uncle . number = = m_currentBlock . number )
{
@ -714,12 +754,22 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, ImportRequirement
cwarn < < " Uncle number: " < < uncle . number ;
cwarn < < " Uncle parent number: " < < uncleParent . number ;
cwarn < < " Block number: " < < m_currentBlock . number ;
BOOST_THROW_EXCEPTION ( UncleIsBrother ( ) ) ;
UncleIsBrother ex ;
ex < < errinfo_uncleNumber ( uncle . number ) ;
ex < < errinfo_currentNumber ( m_currentBlock . number ) ;
BOOST_THROW_EXCEPTION ( ex ) ;
}
uncle . verifyParent ( uncleParent ) ;
// tdIncrease += uncle.difficulty;
rewarded . push_back ( uncle ) ;
+ + ii ;
}
catch ( Exception & ex )
{
ex < < errinfo_uncleIndex ( ii ) ;
throw ;
}
}
applyRewards ( rewarded ) ;
@ -731,15 +781,8 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, ImportRequirement
if ( m_currentBlock . stateRoot ! = m_previousBlock . stateRoot & & m_currentBlock . stateRoot ! = rootHash ( ) )
{
badBlock ( _block , " Bad state root " ) ;
cnote < < " Given to be: " < < m_currentBlock . stateRoot ;
// TODO: Fix
// cnote << SecureTrieDB<Address, OverlayDB>(&m_db, m_currentBlock.stateRoot);
cnote < < " Calculated to be: " < < rootHash ( ) ;
cwarn < < " VMTrace: \n " < < vmTrace ( _block , _bc , _ir ) ;
// cnote << m_state;
// Rollback the trie.
m_db . rollback ( ) ;
BOOST_THROW_EXCEPTION ( InvalidStateRoot ( ) ) ;
BOOST_THROW_EXCEPTION ( InvalidStateRoot ( ) < < Hash256RequirementError ( rootHash ( ) , m_currentBlock . stateRoot ) ) ;
}
if ( m_currentBlock . gasUsed ! = gasUsed ( ) )
@ -1188,8 +1231,10 @@ ExecutionResult State::execute(LastHashes const& _lh, Transaction const& _t, Per
if ( ! e . execute ( ) )
# if ETH_VMTRACE
{
( void ) _onOp ;
if ( isChannelVisible < VMTraceChannel > ( ) )
e . go ( e . simpleTrace ( ) ) ;
else
e . go ( _onOp ) ;
}
# else
e . go ( _onOp ) ;