Skip to content

Commit

Permalink
Fix reorg service
Browse files Browse the repository at this point in the history
  • Loading branch information
Uxio0 committed Feb 12, 2020
1 parent 04ad43e commit 3b6f3cf
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 11 deletions.
16 changes: 8 additions & 8 deletions safe_transaction_service/history/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,10 @@ def create_from_block(self, block: Dict[str, Any], current_block_number: Optiona


class EthereumBlockQuerySet(models.QuerySet):
def not_confirmed(self, current_block_number: Optional[int] = None):
def not_confirmed(self, to_block_number: Optional[int] = None):
queryset = self.filter(confirmed=False)
if current_block_number is not None:
queryset = queryset.filter(number__lte=current_block_number - 6)
if to_block_number is not None:
queryset = queryset.filter(number__lte=to_block_number)
return queryset.order_by('number')


Expand All @@ -126,16 +126,16 @@ class EthereumBlock(models.Model):
timestamp = models.DateTimeField()
block_hash = Sha3HashField(unique=True)
parent_hash = Sha3HashField(unique=True)
# For reorgs, True if `current_block_number` - `number` >= MIN_CONFIRMATIONS
confirmed = models.BooleanField(default=False,
db_index=True) # For reorgs, True if `current_block_number` - `number` >= 6
db_index=True)

def __str__(self):
return f'Block number={self.number} on {self.timestamp}'

def set_confirmed(self, current_block_number: int):
if (current_block_number - self.number) >= 6:
self.confirmed = True
self.save()
def set_confirmed(self):
self.confirmed = True
self.save()


class EthereumTxManager(models.Manager):
Expand Down
10 changes: 7 additions & 3 deletions safe_transaction_service/history/services/reorg_service.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging
from typing import Dict, List, NoReturn, Optional

from django.db import models
from django.db import models, transaction

from hexbytes import HexBytes

Expand All @@ -27,6 +27,8 @@ def del_singleton(cls):

# TODO Test ReorgService
class ReorgService:
SAFE_CONFIRMATIONS = 6

def __init__(self, ethereum_client: EthereumClient):
self.ethereum_client = ethereum_client
# Dictionary with Django model and attribute for reorgs
Expand All @@ -41,14 +43,16 @@ def check_reorgs(self) -> Optional[int]:
:return: Number of oldest block with reorg detected. `None` if not reorg found
"""
current_block_number = self.ethereum_client.current_block_number
for database_block in EthereumBlock.objects.not_confirmed(current_block_number=current_block_number):
to_block = current_block_number - self.SAFE_CONFIRMATIONS
for database_block in EthereumBlock.objects.not_confirmed(current_block_number=to_block):
blockchain_block = self.ethereum_client.get_block(database_block.number, full_transactions=False)
if HexBytes(blockchain_block['hash']) == HexBytes(database_block.block_hash):
database_block.set_confirmed(current_block_number)
database_block.set_confirmed()
else:
logger.warning('Reorg found for block-number=%d', database_block.number)
return database_block.number

@transaction.atomic
def recover_from_reorg(self, first_reorg_block_number: int) -> int:
"""
:param first_reorg_block_number:
Expand Down
2 changes: 2 additions & 0 deletions safe_transaction_service/history/tasks.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import signal
import time
from typing import Any, Dict, NoReturn, Optional, Type, Union

from django.conf import settings
Expand Down Expand Up @@ -169,6 +170,7 @@ def check_reorgs_task() -> Optional[int]:
for task_id in redis.lrange(blockchain_running_tasks_key, 0, -1)],
terminate=True, signal=signal.SIGTERM)
redis.delete(blockchain_running_tasks_key)
time.sleep(5)
reorg_service.recover_from_reorg(first_reorg_block_number)
return first_reorg_block_number
except LockError:
Expand Down

0 comments on commit 3b6f3cf

Please sign in to comment.