@@ -279,31 +279,38 @@ def add_transaction(self, transaction):
279
279
if the transaction was invalid
280
280
"""
281
281
assert self .head_candidate is not None
282
+ head_candidate = self .head_candidate
282
283
log .debug ('new tx' , num_txs = len (self .get_transactions ()), tx_hash = transaction )
283
284
if transaction in self .get_transactions ():
284
285
log .debug ('known tx' )
285
286
return
286
- old_state_root = self . head_candidate .state_root
287
+ old_state_root = head_candidate .state_root
287
288
# revert finalization
288
- self . head_candidate .state_root = self .pre_finalize_state_root
289
+ head_candidate .state_root = self .pre_finalize_state_root
289
290
try :
290
- success , output = processblock .apply_transaction (self . head_candidate , transaction )
291
+ success , output = processblock .apply_transaction (head_candidate , transaction )
291
292
except processblock .InvalidTransaction as e :
292
293
# if unsuccessful the prerequisites were not fullfilled
293
294
# and the tx is invalid, state must not have changed
294
295
log .debug ('invalid tx' , error = e )
295
296
success = False
296
297
298
+ # we might have a new head_candidate (due to ctx switches in pyethapp)
299
+ if self .head_candidate != head_candidate :
300
+ log .debug ('head_candidate changed during validation, trying again' )
301
+ self .add_transaction (transaction )
302
+ return
303
+
297
304
if success :
298
305
assert transaction in self .get_transactions ()
299
- self .pre_finalize_state_root = self . head_candidate .state_root
300
- self . head_candidate .finalize ()
306
+ self .pre_finalize_state_root = head_candidate .state_root
307
+ head_candidate .finalize ()
301
308
log .debug ('tx applied' , result = output )
302
- assert old_state_root != self . head_candidate .state_root
309
+ assert old_state_root != head_candidate .state_root
303
310
return True
304
311
else :
305
312
log .debug ('tx failed' )
306
- self . head_candidate .state_root = old_state_root # reset
313
+ head_candidate .state_root = old_state_root # reset
307
314
return False
308
315
309
316
def get_transactions (self ):
0 commit comments