Refactoring processBlock & adding smart contract plan
This commit is contained in:
parent
1873330b6d
commit
5abd4262e1
29
smart-contract-system-redesign.txt
Normal file
29
smart-contract-system-redesign.txt
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
|
||||||
|
DATABASES
|
||||||
|
* Database operations have to be optimized
|
||||||
|
- in terms of not repeating too often
|
||||||
|
- Save changes only when all business logic is approved, since we are working with multiple databases currently
|
||||||
|
* Too much of repitition in database operations right now
|
||||||
|
* Database model classes, for SQL alchemy, have to be optimized ie. base classes for tokenswap and one-time-event totally different right now
|
||||||
|
* Make all database operations to follow SQLAlchemy, no direct SQL commands
|
||||||
|
* Remove all position based queries
|
||||||
|
|
||||||
|
PROGRAM STRUCTURE
|
||||||
|
* Optimize overall program structure
|
||||||
|
|
||||||
|
NEW FEATURES
|
||||||
|
* Rollback feature
|
||||||
|
* When processing blocks from the websocket API, check the blockheight of the new block vs the latest block in the database | this is to make sure none of the transactions go missing
|
||||||
|
|
||||||
|
|
||||||
|
-----
|
||||||
|
processBlocks
|
||||||
|
|
||||||
|
* find the last scanned block in the database
|
||||||
|
* find the latest block at the API
|
||||||
|
* for loop for lastscannedblock to latestblock
|
||||||
|
* processEach transaction based on business logic
|
||||||
|
* Update system.db to reflect currently scanned block as the latest block
|
||||||
|
|
||||||
|
* Check for local smart contract triggers
|
||||||
|
* Check if any token swap contract deposits have to be returned
|
||||||
@ -52,11 +52,13 @@ def pushData_SSEapi(message):
|
|||||||
print('')
|
print('')
|
||||||
|
|
||||||
|
|
||||||
def processBlock(blockindex):
|
def processBlock(blockindex=None, blockhash=None):
|
||||||
logger.info(f'Processing block {blockindex}')
|
if blockindex is not None and blockhash is None:
|
||||||
# Get block details
|
logger.info(f'Processing block {blockindex}')
|
||||||
response = newMultiRequest(f"block-index/{blockindex}")
|
# Get block details
|
||||||
blockhash = response['blockHash']
|
response = newMultiRequest(f"block-index/{blockindex}")
|
||||||
|
blockhash = response['blockHash']
|
||||||
|
|
||||||
blockinfo = newMultiRequest(f"block/{blockhash}")
|
blockinfo = newMultiRequest(f"block/{blockhash}")
|
||||||
|
|
||||||
# todo Rule 8 - read every transaction from every block to find and parse flodata
|
# todo Rule 8 - read every transaction from every block to find and parse flodata
|
||||||
@ -78,7 +80,7 @@ def processBlock(blockindex):
|
|||||||
current_index = 2
|
current_index = 2
|
||||||
except:
|
except:
|
||||||
logger.info("The API has passed the Block height test but failed transaction_data['floData'] test")
|
logger.info("The API has passed the Block height test but failed transaction_data['floData'] test")
|
||||||
logger.info(f"Block Height : {blockindex}")
|
logger.info(f"Block Height : {blockinfo['height']}")
|
||||||
logger.info(f"Transaction {transaction} data : ")
|
logger.info(f"Transaction {transaction} data : ")
|
||||||
logger.info(transaction_data)
|
logger.info(transaction_data)
|
||||||
logger.info('Program will wait for 1 seconds and try to reconnect')
|
logger.info('Program will wait for 1 seconds and try to reconnect')
|
||||||
@ -110,7 +112,7 @@ def processBlock(blockindex):
|
|||||||
SystemBase.metadata.create_all(bind=engine)
|
SystemBase.metadata.create_all(bind=engine)
|
||||||
session = sessionmaker(bind=engine)()
|
session = sessionmaker(bind=engine)()
|
||||||
entry = session.query(SystemData).filter(SystemData.attribute == 'lastblockscanned').all()[0]
|
entry = session.query(SystemData).filter(SystemData.attribute == 'lastblockscanned').all()[0]
|
||||||
entry.value = str(blockindex)
|
entry.value = str(blockinfo['height'])
|
||||||
session.commit()
|
session.commit()
|
||||||
session.close()
|
session.close()
|
||||||
|
|
||||||
@ -120,53 +122,6 @@ def processBlock(blockindex):
|
|||||||
checkReturnDeposits(blockinfo)
|
checkReturnDeposits(blockinfo)
|
||||||
|
|
||||||
|
|
||||||
def processApiBlock(blockhash):
|
|
||||||
logger.info(config['DEFAULT']['NET'])
|
|
||||||
blockinfo = newMultiRequest('block/{}'.format(str(blockhash)))
|
|
||||||
|
|
||||||
# todo Rule 8 - read every transaction from every block to find and parse flodata
|
|
||||||
counter = 0
|
|
||||||
acceptedTxList = []
|
|
||||||
# Scan every transaction
|
|
||||||
for transaction in blockinfo["tx"]:
|
|
||||||
transaction_data = newMultiRequest(f"tx/{transaction}")
|
|
||||||
text = transaction_data["floData"]
|
|
||||||
text = text.replace("\n", " \n ")
|
|
||||||
|
|
||||||
# todo Rule 9 - Reject all noise transactions. Further rules are in parsing.py
|
|
||||||
returnval = None
|
|
||||||
parsed_data = parsing.parse_flodata(text, blockinfo, config['DEFAULT']['NET'])
|
|
||||||
if parsed_data['type'] != 'noise':
|
|
||||||
logger.info(f"Processing transaction {transaction}")
|
|
||||||
logger.info(f"flodata {text} is parsed to {parsed_data}")
|
|
||||||
returnval = processTransaction(transaction_data, parsed_data)
|
|
||||||
|
|
||||||
if returnval == 1:
|
|
||||||
acceptedTxList.append(transaction)
|
|
||||||
elif returnval == 0:
|
|
||||||
logger.info("Transfer for the transaction %s is illegitimate. Moving on" % transaction)
|
|
||||||
|
|
||||||
if len(acceptedTxList) > 0:
|
|
||||||
tempinfo = blockinfo['tx'].copy()
|
|
||||||
for tx in blockinfo['tx']:
|
|
||||||
if tx not in acceptedTxList:
|
|
||||||
tempinfo.remove(tx)
|
|
||||||
blockinfo['tx'] = tempinfo
|
|
||||||
updateLatestBlock(blockinfo)
|
|
||||||
|
|
||||||
engine = create_engine('sqlite:///system.db')
|
|
||||||
SystemBase.metadata.create_all(bind=engine)
|
|
||||||
session = sessionmaker(bind=engine)()
|
|
||||||
entry = session.query(SystemData).filter(SystemData.attribute == 'lastblockscanned').all()[0]
|
|
||||||
entry.value = str(blockinfo['height'])
|
|
||||||
logger.info('Last scanned block value should be '+ str(entry.value))
|
|
||||||
session.commit()
|
|
||||||
session.close()
|
|
||||||
|
|
||||||
# Check smartContracts which will be triggered locally, and not by the contract committee
|
|
||||||
checkLocaltriggerContracts(blockinfo)
|
|
||||||
|
|
||||||
|
|
||||||
def updateLatestTransaction(transactionData, parsed_data):
|
def updateLatestTransaction(transactionData, parsed_data):
|
||||||
# connect to latest transaction db
|
# connect to latest transaction db
|
||||||
conn = sqlite3.connect('latestCache.db')
|
conn = sqlite3.connect('latestCache.db')
|
||||||
@ -2633,7 +2588,7 @@ def scanBlockchain():
|
|||||||
break
|
break
|
||||||
|
|
||||||
for blockindex in range(startblock, current_index):
|
for blockindex in range(startblock, current_index):
|
||||||
processBlock(blockindex)
|
processBlock(blockindex=blockindex)
|
||||||
|
|
||||||
# At this point the script has updated to the latest block
|
# At this point the script has updated to the latest block
|
||||||
# Now we connect to flosight's websocket API to get information about the latest blocks
|
# Now we connect to flosight's websocket API to get information about the latest blocks
|
||||||
@ -2799,4 +2754,4 @@ def connect_error():
|
|||||||
def on_block(data):
|
def on_block(data):
|
||||||
logger.info('New block received')
|
logger.info('New block received')
|
||||||
logger.info(str(data))
|
logger.info(str(data))
|
||||||
processApiBlock(data)
|
processBlock(blockhash=data)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user