From 8464d48b0a3eedfbb23ed331cc92e22f7f30e4a2 Mon Sep 17 00:00:00 2001 From: Sai Raj <39055732+sairajzero@users.noreply.github.com> Date: Sun, 7 Jul 2024 01:21:55 -0400 Subject: [PATCH] Adding utility fns for reorg Adding functions for auto-rollback on blockchain reorg --- tracktokens_smartcontracts.py | 35 +++++++++++++++++++++++++++++++++++ util_rollback.py | 11 +++++++++-- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/tracktokens_smartcontracts.py b/tracktokens_smartcontracts.py index b2af77f..b7cee97 100755 --- a/tracktokens_smartcontracts.py +++ b/tracktokens_smartcontracts.py @@ -22,6 +22,7 @@ import asyncio import websockets from decimal import Decimal import pdb +from util_rollback import rollback_to_block def newMultiRequest(apicall): @@ -954,6 +955,40 @@ def checkLocal_expiry_trigger_deposit(blockinfo): updateLatestTransaction(transaction_data, parsed_data, f"{query.contractName}-{query.contractAddress}") +def check_reorg(): + connection = create_database_connection('system_dbs') + blockbook_api_url = 'https://blockbook.ranchimall.net/' + BACK_TRACK_BLOCKS = 1000 + + # find latest block number in local database + latest_block = list(connection.execute("SELECT max(blockNumber) from latestBlocks").fetchone())[0] + block_number = latest_block + + while block_number > 0: + # get the block hash + block_hash = list(connection.execute(f"SELECT blockHash from latestBlocks WHERE blockNumber = {block_number}").fetchone())[0] + + # Check if the block is in blockbook (i.e, not dropped in reorg) + response = requests.get(f'{blockbook_api_url}api/block/{block_number}', verify=API_VERIFY) + if response.status_code == 200: + response = response.json() + if response['hash'] == block_hash: # local blockhash matches with blockbook hash + break + else: # check for older blocks to trace where reorg has happened + block_number -= BACK_TRACK_BLOCKS + continue + else: + logger.info('Response from the Blockbook API failed') + sys.exit(0) + + connection.close() + + # rollback if needed + if block_number != latest_block: + rollback_to_block(block_number) + + return block_number + def extract_contractStructure(contractName, contractAddress): connection = create_database_connection('smart_contract', {'contract_name':f"{contractName}", 'contract_address':f"{contractAddress}"}) attributevaluepair = connection.execute("SELECT attribute, value FROM contractstructure WHERE attribute != 'flodata'").fetchall() diff --git a/util_rollback.py b/util_rollback.py index 1a66f94..09e3f73 100644 --- a/util_rollback.py +++ b/util_rollback.py @@ -465,12 +465,19 @@ def initiate_rollback_process(): systemdb_session.commit() systemdb_session.close() +def rollback_to_block(block_number): + global rollback_block + rollback_block = block_number + start_rollback_process() -if __name__ == "__main__": +def start_rollback_process(): systemdb_session = create_database_session_orm('system_dbs', {'db_name': 'system'}, SystemBase) lastblockscanned_query = systemdb_session.query(SystemData).filter(SystemData.attribute=='lastblockscanned').first() if(rollback_block > int(lastblockscanned_query.value)): print('Rollback block is greater than the last scanned block\n Exiting ....') sys.exit(0) else: - initiate_rollback_process() \ No newline at end of file + initiate_rollback_process() + +if __name__ == "__main__": + start_rollback_process() \ No newline at end of file