@ -15,7 +15,6 @@
along with cpp - ethereum . If not , see < http : //www.gnu.org/licenses/>.
*/
/** @file MixClient.cpp
* @ author Yann yann @ ethdev . com
* @ author Arkadiy Paronyan arkadiy @ ethdev . com
* @ date 2015
* Ethereum IDE client .
@ -90,11 +89,10 @@ void MixClient::resetState(u256 _balance)
m_state = eth : : State ( m_userAccount . address ( ) , m_stateDB , BaseState : : Empty ) ;
m_state . sync ( bc ( ) ) ;
m_startState = m_state ;
m_pendingExecutions . clear ( ) ;
m_executions . clear ( ) ;
}
void MixClient : : executeTransaction ( Transaction const & _t , State & _state )
void MixClient : : executeTransaction ( Transaction const & _t , State & _state , bool _call )
{
bytes rlp = _t . rlp ( ) ;
@ -171,30 +169,33 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state)
d . value = _t . value ( ) ;
if ( _t . isCreation ( ) )
d . contractAddress = right160 ( sha3 ( rlpList ( _t . sender ( ) , _t . nonce ( ) ) ) ) ;
d . receipt = TransactionReceipt ( execState . rootHash ( ) , execution . gasUsed ( ) , execution . logs ( ) ) ; //TODO: track gas usage
m_pendingExecutions . emplace_back ( std : : move ( d ) ) ;
if ( ! _call )
d . transactionIndex = m_state . pending ( ) . size ( ) ;
m_executions . emplace_back ( std : : move ( d ) ) ;
// execute on a state
_state . execute ( lastHashes , rlp , nullptr , true ) ;
// collect watches
h256Set changed ;
Guard l ( m_filterLock ) ;
for ( std : : pair < h256 const , eth : : InstalledFilter > & i : m_filters )
if ( ( unsigned ) i . second . filter . latest ( ) > bc ( ) . number ( ) )
{
// acceptable number.
auto m = i . second . filter . matches ( _state . receipt ( _state . pending ( ) . size ( ) - 1 ) ) ;
if ( m . size ( ) )
if ( ! _call )
{
_state . execute ( lastHashes , rlp , nullptr , true ) ;
// collect watches
h256Set changed ;
Guard l ( m_filterLock ) ;
for ( std : : pair < h256 const , eth : : InstalledFilter > & i : m_filters )
if ( ( unsigned ) i . second . filter . latest ( ) > bc ( ) . number ( ) )
{
// filter catches them
for ( LogEntry const & l : m )
i . second . changes . push_back ( LocalisedLogEntry ( l , bc ( ) . number ( ) + 1 ) ) ;
changed . insert ( i . first ) ;
// acceptable number.
auto m = i . second . filter . matches ( _state . receipt ( _state . pending ( ) . size ( ) - 1 ) ) ;
if ( m . size ( ) )
{
// filter catches them
for ( LogEntry const & l : m )
i . second . changes . push_back ( LocalisedLogEntry ( l , bc ( ) . number ( ) + 1 ) ) ;
changed . insert ( i . first ) ;
}
}
}
changed . insert ( dev : : eth : : PendingChangedFilter ) ;
noteChanged ( changed ) ;
changed . insert ( dev : : eth : : PendingChangedFilter ) ;
noteChanged ( changed ) ;
}
}
void MixClient : : mine ( )
@ -206,28 +207,18 @@ void MixClient::mine()
bc ( ) . import ( m_state . blockData ( ) , m_stateDB ) ;
m_state . sync ( bc ( ) ) ;
m_startState = m_state ;
m_executions . emplace_back ( std : : move ( m_pendingExecutions ) ) ;
h256Set changed { dev : : eth : : PendingChangedFilter , dev : : eth : : ChainChangedFilter } ;
noteChanged ( changed ) ;
}
ExecutionResult const & MixClient : : execution ( unsigned _block , unsigned _transaction ) const
{
if ( _block = = bc ( ) . number ( ) + 1 )
return m_pendingExecutions . at ( _transaction ) ;
return m_executions . at ( _block - 1 ) . at ( _transaction ) ;
}
ExecutionResult const & MixClient : : lastExecution ( ) const
{
if ( m_pendingExecutions . size ( ) > 0 )
return m_pendingExecutions . back ( ) ;
return m_executions . back ( ) . back ( ) ;
return m_executions . back ( ) ;
}
ExecutionResults const & MixClient : : p endingE xecutions( ) const
ExecutionResults const & MixClient : : executions ( ) const
{
return m_p endingE xecutions ;
return m_executions ;
}
State MixClient : : asOf ( int _block ) const
@ -246,7 +237,7 @@ void MixClient::transact(Secret _secret, u256 _value, Address _dest, bytes const
WriteGuard l ( x_state ) ;
u256 n = m_state . transactionsFrom ( toAddress ( _secret ) ) ;
Transaction t ( _value , _gasPrice , _gas , _dest , _data , n , _secret ) ;
executeTransaction ( t , m_state ) ;
executeTransaction ( t , m_state , false ) ;
}
Address MixClient : : transact ( Secret _secret , u256 _endowment , bytes const & _init , u256 _gas , u256 _gasPrice )
@ -254,7 +245,7 @@ Address MixClient::transact(Secret _secret, u256 _endowment, bytes const& _init,
WriteGuard l ( x_state ) ;
u256 n = m_state . transactionsFrom ( toAddress ( _secret ) ) ;
eth : : Transaction t ( _endowment , _gasPrice , _gas , _init , n , _secret ) ;
executeTransaction ( t , m_state ) ;
executeTransaction ( t , m_state , false ) ;
Address address = right160 ( sha3 ( rlpList ( t . sender ( ) , t . nonce ( ) ) ) ) ;
return address ;
}
@ -263,7 +254,7 @@ void MixClient::inject(bytesConstRef _rlp)
{
WriteGuard l ( x_state ) ;
eth : : Transaction t ( _rlp , CheckSignature : : None ) ;
executeTransaction ( t , m_state ) ;
executeTransaction ( t , m_state , false ) ;
}
void MixClient : : flushTransactions ( )
@ -282,8 +273,8 @@ bytes MixClient::call(Secret _secret, u256 _value, Address _dest, bytes const& _
Transaction t ( _value , _gasPrice , _gas , _dest , _data , n , _secret ) ;
bytes rlp = t . rlp ( ) ;
WriteGuard lw ( x_state ) ; //TODO: lock is required only for last execution state
executeTransaction ( t , temp ) ;
return m_pendingExecutions . back ( ) . returnValue ;
executeTransaction ( t , temp , true ) ;
return lastExecution ( ) . returnValue ;
}
u256 MixClient : : balanceAt ( Address _a , int _block ) const