Skip to content
This repository was archived by the owner on May 23, 2023. It is now read-only.

Commit c8669e2

Browse files
committed
fix add_transaction concurrency issue
1 parent 765c7b5 commit c8669e2

File tree

1 file changed

+14
-7
lines changed

1 file changed

+14
-7
lines changed

ethereum/chain.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -279,31 +279,38 @@ def add_transaction(self, transaction):
279279
if the transaction was invalid
280280
"""
281281
assert self.head_candidate is not None
282+
head_candidate = self.head_candidate
282283
log.debug('new tx', num_txs=len(self.get_transactions()), tx_hash=transaction)
283284
if transaction in self.get_transactions():
284285
log.debug('known tx')
285286
return
286-
old_state_root = self.head_candidate.state_root
287+
old_state_root = head_candidate.state_root
287288
# revert finalization
288-
self.head_candidate.state_root = self.pre_finalize_state_root
289+
head_candidate.state_root = self.pre_finalize_state_root
289290
try:
290-
success, output = processblock.apply_transaction(self.head_candidate, transaction)
291+
success, output = processblock.apply_transaction(head_candidate, transaction)
291292
except processblock.InvalidTransaction as e:
292293
# if unsuccessful the prerequisites were not fullfilled
293294
# and the tx is invalid, state must not have changed
294295
log.debug('invalid tx', error=e)
295296
success = False
296297

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+
297304
if success:
298305
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()
301308
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
303310
return True
304311
else:
305312
log.debug('tx failed')
306-
self.head_candidate.state_root = old_state_root # reset
313+
head_candidate.state_root = old_state_root # reset
307314
return False
308315

309316
def get_transactions(self):

0 commit comments

Comments
 (0)