@ -114,7 +114,7 @@ State::State(OverlayDB const& _db, BlockChain const& _bc, h256 _h):
m_ourAddress = bi . coinbaseAddress ;
m_ourAddress = bi . coinbaseAddress ;
sync ( _bc , bi . parentHash , bip ) ;
sync ( _bc , bi . parentHash , bip ) ;
enact ( & b ) ;
enact ( & b , _bc ) ;
}
}
State : : State ( State const & _s ) :
State : : State ( State const & _s ) :
@ -319,7 +319,7 @@ bool State::sync(BlockChain const& _bc, h256 _block, BlockInfo const& _bi)
for ( auto it = chain . rbegin ( ) ; it ! = chain . rend ( ) ; + + it )
for ( auto it = chain . rbegin ( ) ; it ! = chain . rend ( ) ; + + it )
{
{
auto b = _bc . block ( * it ) ;
auto b = _bc . block ( * it ) ;
enact ( & b ) ;
enact ( & b , _bc ) ;
cleanup ( true ) ;
cleanup ( true ) ;
}
}
}
}
@ -348,7 +348,7 @@ u256 State::enactOn(bytesConstRef _block, BlockInfo const& _bi, BlockChain const
sync ( _bc , _bi . parentHash ) ;
sync ( _bc , _bi . parentHash ) ;
resetCurrent ( ) ;
resetCurrent ( ) ;
m_previousBlock = biParent ;
m_previousBlock = biParent ;
return enact ( _block , & _bc ) ;
return enact ( _block , _bc ) ;
}
}
map < Address , u256 > State : : addresses ( ) const
map < Address , u256 > State : : addresses ( ) const
@ -412,12 +412,14 @@ bool State::cull(TransactionQueue& _tq) const
return ret ;
return ret ;
}
}
h512s State : : sync ( TransactionQueue & _tq , bool * o_transactionQueueChanged )
h512s State : : sync ( BlockChain const & _bc , TransactionQueue & _tq , bool * o_transactionQueueChanged )
{
{
// TRANSACTIONS
// TRANSACTIONS
h512s ret ;
h512s ret ;
auto ts = _tq . transactions ( ) ;
auto ts = _tq . transactions ( ) ;
auto lh = getLastHashes ( _bc ) ;
for ( int goodTxs = 1 ; goodTxs ; )
for ( int goodTxs = 1 ; goodTxs ; )
{
{
goodTxs = 0 ;
goodTxs = 0 ;
@ -429,7 +431,7 @@ h512s State::sync(TransactionQueue& _tq, bool* o_transactionQueueChanged)
{
{
uncommitToMine ( ) ;
uncommitToMine ( ) ;
// boost::timer t;
// boost::timer t;
execute ( i . second ) ;
execute ( lh , i . second ) ;
ret . push_back ( m_receipts . back ( ) . bloom ( ) ) ;
ret . push_back ( m_receipts . back ( ) . bloom ( ) ) ;
_tq . noteGood ( i ) ;
_tq . noteGood ( i ) ;
+ + goodTxs ;
+ + goodTxs ;
@ -467,7 +469,7 @@ h512s State::sync(TransactionQueue& _tq, bool* o_transactionQueueChanged)
return ret ;
return ret ;
}
}
u256 State : : enact ( bytesConstRef _block , BlockChain const * _bc , bool _checkNonce )
u256 State : : enact ( bytesConstRef _block , BlockChain const & _bc , bool _checkNonce )
{
{
// m_currentBlock is assumed to be prepopulated and reset.
// m_currentBlock is assumed to be prepopulated and reset.
@ -496,6 +498,8 @@ u256 State::enact(bytesConstRef _block, BlockChain const* _bc, bool _checkNonce)
GenericTrieDB < MemoryDB > receiptsTrie ( & rm ) ;
GenericTrieDB < MemoryDB > receiptsTrie ( & rm ) ;
receiptsTrie . init ( ) ;
receiptsTrie . init ( ) ;
LastHashes lh = getLastHashes ( _bc ) ;
// All ok with the block generally. Play back the transactions now...
// All ok with the block generally. Play back the transactions now...
unsigned i = 0 ;
unsigned i = 0 ;
for ( auto const & tr : RLP ( _block ) [ 1 ] )
for ( auto const & tr : RLP ( _block ) [ 1 ] )
@ -504,26 +508,11 @@ u256 State::enact(bytesConstRef _block, BlockChain const* _bc, bool _checkNonce)
k < < i ;
k < < i ;
transactionsTrie . insert ( & k . out ( ) , tr . data ( ) ) ;
transactionsTrie . insert ( & k . out ( ) , tr . data ( ) ) ;
execute ( lh , tr . data ( ) ) ;
// cnote << m_state.root() << m_state;
// cnote << *this;
execute ( tr . data ( ) ) ;
RLPStream receiptrlp ;
RLPStream receiptrlp ;
m_receipts . back ( ) . streamRLP ( receiptrlp ) ;
m_receipts . back ( ) . streamRLP ( receiptrlp ) ;
receiptsTrie . insert ( & k . out ( ) , & receiptrlp . out ( ) ) ;
receiptsTrie . insert ( & k . out ( ) , & receiptrlp . out ( ) ) ;
/*
if ( tr [ 1 ] . toHash < h256 > ( ) ! = m_state . root ( ) )
{
// Invalid state root
cnote < < m_state . root ( ) < < " \n " < < m_state ;
cnote < < * this ;
cnote < < " INVALID: " < < tr [ 1 ] . toHash < h256 > ( ) ;
BOOST_THROW_EXCEPTION ( InvalidTransactionStateRoot ( ) ) ;
}
if ( tr [ 2 ] . toInt < u256 > ( ) ! = gasUsed ( ) )
BOOST_THROW_EXCEPTION ( InvalidTransactionGasUsed ( ) ) ;
*/
+ + i ;
+ + i ;
}
}
@ -535,7 +524,20 @@ u256 State::enact(bytesConstRef _block, BlockChain const* _bc, bool _checkNonce)
if ( receiptsTrie . root ( ) ! = m_currentBlock . receiptsRoot )
if ( receiptsTrie . root ( ) ! = m_currentBlock . receiptsRoot )
{
{
cwarn < < " Bad receipts state root! " ;
cwarn < < " Bad receipts state root. " ;
cwarn < < " Block: " < < toHex ( _block ) ;
cwarn < < " Block RLP: " < < RLP ( _block ) ;
cwarn < < " Want: " < < receiptsTrie . root ( ) < < " , got: " < < m_currentBlock . receiptsRoot ;
for ( unsigned j = 0 ; j < i ; + + j )
{
RLPStream k ;
k < < j ;
auto b = asBytes ( receiptsTrie . at ( & k . out ( ) ) ) ;
cwarn < < j < < " : " ;
cwarn < < " RLP: " < < RLP ( b ) ;
cwarn < < " Hex: " < < toHex ( b ) ;
cwarn < < TransactionReceipt ( & b ) ;
}
BOOST_THROW_EXCEPTION ( InvalidReceiptsStateRoot ( ) ) ;
BOOST_THROW_EXCEPTION ( InvalidReceiptsStateRoot ( ) ) ;
}
}
@ -551,7 +553,7 @@ u256 State::enact(bytesConstRef _block, BlockChain const* _bc, bool _checkNonce)
// Check uncles & apply their rewards to state.
// Check uncles & apply their rewards to state.
set < h256 > nonces = { m_currentBlock . nonce } ;
set < h256 > nonces = { m_currentBlock . nonce } ;
Addresses rewarded ;
Addresses rewarded ;
set < h256 > knownUncles = _bc ? _bc - > allUnclesFrom ( m_currentBlock . parentHash ) : set < h256 > ( ) ;
set < h256 > knownUncles = _bc . allUnclesFrom ( m_currentBlock . parentHash ) ;
for ( auto const & i : RLP ( _block ) [ 2 ] )
for ( auto const & i : RLP ( _block ) [ 2 ] )
{
{
if ( knownUncles . count ( sha3 ( i . data ( ) ) ) )
if ( knownUncles . count ( sha3 ( i . data ( ) ) ) )
@ -560,13 +562,11 @@ u256 State::enact(bytesConstRef _block, BlockChain const* _bc, bool _checkNonce)
BlockInfo uncle = BlockInfo : : fromHeader ( i . data ( ) ) ;
BlockInfo uncle = BlockInfo : : fromHeader ( i . data ( ) ) ;
if ( nonces . count ( uncle . nonce ) )
if ( nonces . count ( uncle . nonce ) )
BOOST_THROW_EXCEPTION ( DuplicateUncleNonce ( ) ) ;
BOOST_THROW_EXCEPTION ( DuplicateUncleNonce ( ) ) ;
if ( _bc )
{
BlockInfo uncleParent ( _bc . block ( uncle . parentHash ) ) ;
BlockInfo uncleParent ( _bc - > block ( uncle . parentHash ) ) ;
if ( ( bigint ) uncleParent . number < ( bigint ) m_currentBlock . number - 7 )
if ( ( bigint ) uncleParent . number < ( bigint ) m_currentBlock . number - 6 )
BOOST_THROW_EXCEPTION ( UncleTooOld ( ) ) ;
BOOST_THROW_EXCEPTION ( UncleTooOld ( ) ) ;
uncle . verifyParent ( uncleParent ) ;
uncle . verifyParent ( uncleParent ) ;
}
nonces . insert ( uncle . nonce ) ;
nonces . insert ( uncle . nonce ) ;
tdIncrease + = uncle . difficulty ;
tdIncrease + = uncle . difficulty ;
@ -648,7 +648,7 @@ bool State::amIJustParanoid(BlockChain const& _bc)
cnote < < " PARANOIA root: " < < s . rootHash ( ) ;
cnote < < " PARANOIA root: " < < s . rootHash ( ) ;
// s.m_currentBlock.populate(&block.out(), false);
// s.m_currentBlock.populate(&block.out(), false);
// s.m_currentBlock.verifyInternals(&block.out());
// s.m_currentBlock.verifyInternals(&block.out());
s . enact ( & block . out ( ) , & _bc , false ) ; // don't check nonce for this since we haven't mined it yet.
s . enact ( & block . out ( ) , _bc , false ) ; // don't check nonce for this since we haven't mined it yet.
s . cleanup ( false ) ;
s . cleanup ( false ) ;
return true ;
return true ;
}
}
@ -993,9 +993,21 @@ bool State::isTrieGood(bool _enforceRefs, bool _requireNoLeftOvers) const
return true ;
return true ;
}
}
// TODO: maintain node overlay revisions for stateroots -> each commit gives a stateroot + OverlayDB; allow overlay copying for rewind operations.
LastHashes State : : getLastHashes ( BlockChain const & _bc ) const
{
LastHashes ret ;
ret . resize ( 256 ) ;
if ( c_protocolVersion > 49 )
{
unsigned n = ( unsigned ) m_previousBlock . number ;
for ( unsigned i = 0 ; i < 256 ; + + i )
ret [ i ] = _bc . numberHash ( std : : max < unsigned > ( n , i ) - i ) ;
}
return ret ;
}
u256 State : : execute ( bytesConstRef _rlp , bytes * o_output , bool _commit )
// TODO: maintain node overlay revisions for stateroots -> each commit gives a stateroot + OverlayDB; allow overlay copying for rewind operations.
u256 State : : execute ( LastHashes const & _lh , bytesConstRef _rlp , bytes * o_output , bool _commit )
{
{
# ifndef ETH_RELEASE
# ifndef ETH_RELEASE
commit ( ) ; // get an updated hash
commit ( ) ; // get an updated hash
@ -1008,7 +1020,7 @@ u256 State::execute(bytesConstRef _rlp, bytes* o_output, bool _commit)
auto h = rootHash ( ) ;
auto h = rootHash ( ) ;
# endif
# endif
Executive e ( * this , 0 ) ;
Executive e ( * this , _lh , 0 ) ;
e . setup ( _rlp ) ;
e . setup ( _rlp ) ;
u256 startGasUsed = gasUsed ( ) ;
u256 startGasUsed = gasUsed ( ) ;