Update: Time triggers, TimeActions

1. Consolidated all time triggers into one function - new logic in main script, TimeAction table added to system.db
2. Changes in code to convert RAW SQL to SQL Alchemy queries
This commit is contained in:
Vivek Teega 2022-02-16 12:24:54 +00:00
parent cf70cfd066
commit d63495a878
2 changed files with 1377 additions and 882 deletions

View File

@ -123,6 +123,30 @@ class ContractTransactionHistory(ContractBase):
parsedFloData = Column('parsedFloData', String) parsedFloData = Column('parsedFloData', String)
class ContractDeposits(ContractBase):
__tablename__ = "contractdeposits"
id = Column('id', Integer, primary_key=True)
depositorAddress = Column('depositorAddress', String)
depositAmount = Column('depositAmount', Float)
depositBalance = Column('depositBalance', Float)
expiryTime = Column('expiryTime', String)
unix_expiryTime = Column('unix_expiryTime', Integer)
status = Column('status', String)
transactionHash = Column('transactionHash', String)
blockNumber = Column('blockNumber', Integer)
blockHash = Column('blockHash', String)
class ConsumedInfo(ContractBase):
__tablename__ = "consumedinfo"
id = Column('id', Integer, primary_key=True)
id_activetable = Column('id_activetable', Integer)
transactionHash = Column('transactionHash', String)
blocknumber = Column('blockNumber', Integer)
class RejectedContractTransactionHistory(SystemBase): class RejectedContractTransactionHistory(SystemBase):
__tablename__ = "rejectedContractTransactionHistory" __tablename__ = "rejectedContractTransactionHistory"
@ -223,21 +247,39 @@ class DatabaseTypeMapping(SystemBase):
object_format = Column ('object_format', String) object_format = Column ('object_format', String)
blockNumber = Column('blockNumber', Integer) blockNumber = Column('blockNumber', Integer)
class TimeActions(SystemBase):
__tablename__ = "time_actions"
id = Column('id', Integer, primary_key=True)
time = Column('time', String)
activity = Column('activity', String)
status = Column('status', String)
contractName = Column('contractName', String)
contractAddress = Column('contractAddress', String)
contractType = Column('contractType', String)
tokens_db = Column('tokens_db', String)
parsed_data = Column('parsed_data', String)
transactionHash = Column('transactionHash', String)
blockNumber = Column('blockNumber', Integer)
class LatestTransactions(LatestCacheBase): class LatestTransactions(LatestCacheBase):
__tablename__ = "latestTransactions" __tablename__ = "latestTransactions"
id = Column('id', Integer, primary_key=True) id = Column('id', Integer, primary_key=True)
transactionHash = Column('transactionHash', String) transactionHash = Column('transactionHash', String)
blockNumber = Column('blockNumber', String) blockNumber = Column('blockNumber', Integer)
jsonData = Column('jsonData', String) jsonData = Column('jsonData', String)
transactionType = Column('transactionType', String) transactionType = Column('transactionType', String)
parsedFloData = Column('parsedFloData', String) parsedFloData = Column('parsedFloData', String)
class LatestBlocks(LatestCacheBase): class LatestBlocks(LatestCacheBase):
__tablename__ = "latestBlocks" __tablename__ = "latestBlocks"
id = Column('id', Integer, primary_key=True) id = Column('id', Integer, primary_key=True)
blockNumber = Column('blockNumber', String) blockNumber = Column('blockNumber', Integer)
blockHash = Column('blockHash', String) blockHash = Column('blockHash', String)
jsonData = Column('jsonData', String) jsonData = Column('jsonData', String)
@ -269,6 +311,7 @@ class ContractDeposits1(ContinuosContractBase):
depositorAddress = Column('depositorAddress', String) depositorAddress = Column('depositorAddress', String)
depositAmount = Column('depositAmount', Float) depositAmount = Column('depositAmount', Float)
expiryTime = Column('expiryTime', String) expiryTime = Column('expiryTime', String)
status = Column('status', String)
transactionHash = Column('transactionHash', String) transactionHash = Column('transactionHash', String)
blockNumber = Column('blockNumber', Integer) blockNumber = Column('blockNumber', Integer)
blockHash = Column('blockHash', String) blockHash = Column('blockHash', String)

View File

@ -17,7 +17,7 @@ from config import *
from datetime import datetime from datetime import datetime
from ast import literal_eval from ast import literal_eval
import pdb import pdb
from models import SystemData, ActiveTable, ConsumedTable, TransferLogs, TransactionHistory, RejectedTransactionHistory, Base, ContractStructure, ContractBase, ContractParticipants, SystemBase, ActiveContracts, ContractAddressMapping, LatestCacheBase, ContractTransactionHistory, RejectedContractTransactionHistory, TokenContractAssociation, ContinuosContractBase, ContractStructure1, ContractParticipants1, ContractDeposits1, ContractTransactionHistory1, DatabaseTypeMapping from models import SystemData, ActiveTable, ConsumedTable, TransferLogs, TransactionHistory, RejectedTransactionHistory, Base, ContractStructure, ContractBase, ContractParticipants, SystemBase, ActiveContracts, ContractAddressMapping, LatestCacheBase, ContractTransactionHistory, RejectedContractTransactionHistory, TokenContractAssociation, ContinuosContractBase, ContractStructure1, ContractParticipants1, ContractDeposits, ContractTransactionHistory1, DatabaseTypeMapping, TimeActions
goodblockset = {} goodblockset = {}
@ -92,11 +92,26 @@ def create_database_session_orm(type, parameters, base):
return session return session
def convert_datetime_to_arrowobject(expiryTime):
expirytime_split = expiryTime.split(' ')
parse_string = '{}/{}/{} {}'.format(expirytime_split[3], parsing.months[expirytime_split[1]],
expirytime_split[2], expirytime_split[4])
expirytime_object = parsing.arrow.get(parse_string, 'YYYY/M/D HH:mm:ss').replace(
tzinfo=expirytime_split[5][3:])
return expirytime_object
def check_if_contract_address(floAddress):
# check contract address mapping db if the address is present, and return True or False based on that
system_db = create_database_session_orm('system_dbs', {'db_name':'system'}, SystemBase)
contract_number = system_db.query(func.sum(ContractAddressMapping.contractAddress)).filter(ContractAddressMapping.contractAddress == floAddress).all()[0][0]
if contract_number is None:
return False
else:
return True
def processBlock(blockindex=None, blockhash=None): def processBlock(blockindex=None, blockhash=None):
# Check smartContracts which will be triggered locally, and not by the contract committee
checkLocaltriggerContracts(blockinfo)
# Check if any deposits have to be returned
checkReturnDeposits(blockinfo)
if blockindex is not None and blockhash is None: if blockindex is not None and blockhash is None:
logger.info(f'Processing block {blockindex}') logger.info(f'Processing block {blockindex}')
@ -106,6 +121,11 @@ def processBlock(blockindex=None, blockhash=None):
blockinfo = newMultiRequest(f"block/{blockhash}") blockinfo = newMultiRequest(f"block/{blockhash}")
# Check smartContracts which will be triggered locally, and not by the contract committee
checkLocaltriggerContracts(blockinfo)
# Check if any deposits have to be returned
checkReturnDeposits(blockinfo)
# 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
counter = 0 counter = 0
acceptedTxList = [] acceptedTxList = []
@ -117,6 +137,10 @@ def processBlock(blockindex=None, blockhash=None):
logger.info(f"Transaction {counter} {transaction}") logger.info(f"Transaction {counter} {transaction}")
current_index = -1 current_index = -1
if transaction in ['77c92bcf40a86cd2e2ba9fa678249a9f4753c98c8038b1b9e9a74008f0ec93e8', '9110512d1696dae01701d8d156264a48ca1100f96c3551904ac3941b363138a1', 'b3e5c6343e3fc989e1d563b703573a21e0d409eb2ca7a9392dff7c7c522b1551', '1e5d1cb60449f15b0e9d44db177605d7e86999ba149effcc1d276c2178ceac3d',
'1586711334961abea5c0b9769cbc626cbc016a59c9c8a423a03e401da834083a']:
pdb.set_trace()
while(current_index == -1): while(current_index == -1):
transaction_data = newMultiRequest(f"tx/{transaction}") transaction_data = newMultiRequest(f"tx/{transaction}")
try: try:
@ -353,7 +377,7 @@ def transferToken(tokenIdentification, tokenAmount, inputAddress, outputAddress,
def checkLocaltriggerContracts(blockinfo): def checkLocaltriggerContracts(blockinfo):
connection = create_database_connection('system_dbs', {'db_name':"system"}) connection = create_database_connection('system_dbs', {'db_name':"system"})
# todo : filter activeContracts which only have local triggers # todo : filter activeContracts which only have local triggers
activeContracts = connection.execute('select contractName, contractAddress from activecontracts where status=="active" ').fetchall() activeContracts = connection.execute('select contractName, contractAddress from activecontracts where status=="active"').fetchall()
connection.close() connection.close()
for contract in activeContracts: for contract in activeContracts:
@ -582,7 +606,301 @@ def checkLocaltriggerContracts(blockinfo):
def checkReturnDeposits(blockinfo): def checkReturnDeposits(blockinfo):
pass # Connect to system.db with a session
blocktime = parsing.arrow.get(blockinfo['time']).to('Asia/Kolkata')
systemdb_session = create_database_session_orm('system_dbs', {'db_name':'system'}, SystemBase)
timeactions_tx_hashes = []
txhash_queries = systemdb_session.query(TimeActions.transactionHash).all()
for query in txhash_queries:
timeactions_tx_hashes.append(query[0])
for txhash in timeactions_tx_hashes:
time_action_txs = systemdb_session.query(TimeActions).filter(TimeActions.transactionHash == txhash).all()
if len(time_action_txs) == 1 and time_action_txs[0].status == 'active':
query = time_action_txs[0]
query_time = convert_datetime_to_arrowobject(query.time)
if blocktime > query_time:
if query.activity == 'contract-deposit':
# find the status of the deposit
# the deposit is unique
# find the total sum to be returned from the smart contract's participation table
contract_db = create_database_session_orm('smart_contract', {'contract_name': query.contractName, 'contract_address': query.contractAddress}, ContractBase)
deposit_query = contract_db.query(ContractDeposits).filter(ContractDeposits.transactionHash == query.transactionHash).first()
depositorAddress = deposit_query.depositorAddress
total_deposit_amount = deposit_query.depositAmount
amount_participated = contract_db.query(func.sum(ContractParticipants.tokenAmount)).all()[0][0]
if amount_participated is None:
amount_participated = 0
returnAmount = float(total_deposit_amount) - float(amount_participated)
# Do a token transfer back to the deposit address
sellingToken = contract_db.query(ContractStructure.value).filter(ContractStructure.attribute == 'selling_token').first()[0]
tx_block_string = f"{query.transactionHash}{blockinfo['height']}".encode('utf-8').hex()
parsed_data = {}
parsed_data['type'] = 'expired_deposit'
transaction_data = {}
transaction_data['txid'] = pybtc.sha256(tx_block_string).hex()
transaction_data['blockheight'] = blockinfo['height']
returnval = transferToken(sellingToken, returnAmount, query.contractAddress, depositorAddress, transaction_data=transaction_data, parsed_data=parsed_data, blockinfo=blockinfo)
if returnval is None:
logger.critical("Something went wrong in the token transfer method while return contract deposit. THIS IS CRITICAL ERROR")
return
else:
old_depositBalance = contract_db.query(ContractDeposits.depositBalance).order_by(ContractDeposits.id.desc()).first()
if old_depositBalance is None:
logger.info('Something is wrong in the databases. Cannot do a deposit return without any previously available deposits in the database')
return 0
else:
old_depositBalance = old_depositBalance[0]
contract_db.add(ContractDeposits(
depositorAddress = deposit_query.depositorAddress,
depositAmount = returnAmount,
depositBalance = old_depositBalance - returnAmount,
expiryTime = deposit_query.expiryTime,
unix_expiryTime = 0,
status = 'deposit-return',
transactionHash = deposit_query.transactionHash,
blockNumber = blockinfo['height'],
blockHash = blockinfo['hash']
))
contract_db.add(ContractTransactionHistory(
transactionType = 'smartContractDepositReturn',
transactionSubType = '',
sourceFloAddress = query.contractAddress,
destFloAddress = depositorAddress,
transferAmount = returnAmount,
blockNumber = blockinfo['height'],
blockHash = blockinfo['hash'],
time = blockinfo['time'],
transactionHash = deposit_query.transactionHash,
blockchainReference = '',
jsonData = '',
parsedFloData = ''
))
systemdb_session.add(TimeActions(
time = query.time,
activity = query.activity,
status = 'returned',
contractName = query.contractName,
contractAddress = query.contractAddress,
contractType = query.contractType,
tokens_db = query.tokens_db,
parsed_data = query.parsed_data,
transactionHash = query.transactionHash,
blockNumber = blockinfo['height']
))
contract_db.commit()
systemdb_session.commit()
updateLatestTransaction(transaction_data, parsed_data)
elif query.activity == 'contract-time-trigger':
# Find out the status of the contract
# check if the conditions for the trigger are met
# Do token transfers
#if query.status ==
# pull out the contract structure into a dictionary
connection = create_database_session_orm('smart_contract', {'contract_name': query.contractName, 'contract_address': query.contractAddress}, ContractBase)
# todo : filter activeContracts which only have local triggers
attributevaluepair = connection.execute("select attribute, value from contractstructure where attribute != 'contractName' and attribute != 'flodata' and attribute != 'contractAddress'").fetchall()
contractStructure = {}
conditionDict = {}
counter = 0
for item in attributevaluepair:
if list(item)[0] == 'exitconditions':
conditionDict[counter] = list(item)[1]
counter = counter + 1
else:
contractStructure[list(item)[0]] = list(item)[1]
if len(conditionDict) > 0:
contractStructure['exitconditions'] = conditionDict
del counter, conditionDict
if contractStructure['contractType'] == 'one-time-event':
# Check if the contract has blockchain trigger or committee trigger
if 'exitconditions' in contractStructure:
# This is a committee trigger contract
expiryTime = contractStructure['expiryTime']
expirytime_split = expiryTime.split(' ')
parse_string = '{}/{}/{} {}'.format(expirytime_split[3], parsing.months[expirytime_split[1]],
expirytime_split[2], expirytime_split[4])
expirytime_object = parsing.arrow.get(parse_string, 'YYYY/M/D HH:mm:ss').replace(tzinfo=expirytime_split[5][3:])
blocktime_object = parsing.arrow.get(blockinfo['time']).to('Asia/Kolkata')
if blocktime_object > expirytime_object:
if 'minimumsubscriptionamount' in contractStructure:
minimumsubscriptionamount = contractStructure['minimumsubscriptionamount']
tokenAmount_sum = connection.execute('select sum(tokenAmount) from contractparticipants').fetchall()[0][0]
if tokenAmount_sum < minimumsubscriptionamount:
# Initialize payback to contract participants
contractParticipants = connection.execute('select participantAddress, tokenAmount, transactionHash from contractparticipants').fetchall()[0][0]
for participant in contractParticipants:
tokenIdentification = contractStructure['tokenIdentification']
contractAddress = connection.execute('select * from contractstructure where attribute="contractAddress"').fetchall()[0][0]
returnval = transferToken(tokenIdentification, participant[1], contractAddress, participant[0], blockinfo = blockinfo)
if returnval is None:
logger.critical("Something went wrong in the token transfer method while doing local Smart Contract Trigger. THIS IS CRITICAL ERROR")
return
connection.execute('update contractparticipants set winningAmount="{}" where participantAddress="{}" and transactionHash="{}"'.format(
(participant[1], participant[0], participant[2])))
# add transaction to ContractTransactionHistory
session = create_database_session_orm('smart_contract', {'contract_name': f"{contract[0]}", 'contract_address': f"{contract[1]}"}, ContractBase)
session.add(ContractTransactionHistory(transactionType='trigger',
transactionSubType='minimumsubscriptionamount-payback',
transferAmount=None,
blockNumber=blockinfo['height'],
blockHash=blockinfo['hash'],
time=blockinfo['time']))
session.commit()
session.close()
connection = create_database_connection('system_dbs', {'db_name':'system'})
connection.execute(
'update activecontracts set status="closed" where contractName="{}" and contractAddress="{}"'.format(
contract[0], contract[1]))
connection.execute(
'update activecontracts set closeDate="{}" where contractName="{}" and contractAddress="{}"'.format(
blockinfo['time'],
contract[0], contract[1]))
connection.close()
connection = create_database_connection('system_dbs', {'db_name':'system'})
connection.execute(
'update activecontracts set status="expired" where contractName="{}" and contractAddress="{}"'.format(
contract[0], contract[1]))
connection.execute(
'update activecontracts set expirydate="{}" where contractName="{}" and contractAddress="{}"'.format(
blockinfo['time'],
contract[0], contract[1]))
connection.close()
elif 'payeeAddress' in contractStructure:
# This is a local trigger contract
if 'maximumsubscriptionamount' in contractStructure:
maximumsubscriptionamount = connection.execute('select value from contractstructure where attribute=="maximumsubscriptionamount"').fetchall()[0][0]
tokenAmount_sum = connection.execute('select sum(tokenAmount) from contractparticipants').fetchall()[0][0]
if tokenAmount_sum >= maximumsubscriptionamount:
# Trigger the contract
payeeAddress = contractStructure['payeeAddress']
tokenIdentification = contractStructure['tokenIdentification']
contractAddress = contractStructure['contractAddress']
returnval = transferToken(tokenIdentification, tokenAmount_sum, contractAddress, payeeAddress, blockinfo = blockinfo)
if returnval is None:
logger.critical("Something went wrong in the token transfer method while doing local Smart Contract Trigger")
return
connection.execute('update contractparticipants set winningAmount="{}"'.format((0)))
# add transaction to ContractTransactionHistory
session = create_database_session_orm('smart_contract', {'contract_name': f"{contract[0]}", 'contract_address': f"{contract[1]}"}, ContractBase)
session.add(ContractTransactionHistory(transactionType='trigger',
transactionSubType='maximumsubscriptionamount',
sourceFloAddress=contractAddress,
destFloAddress=payeeAddress,
transferAmount=tokenAmount_sum,
blockNumber=blockinfo['height'],
blockHash=blockinfo['hash'],
time=blockinfo['time']))
session.commit()
session.close()
connection = create_database_connection('system_dbs', {'db_name':'system'})
connection.execute(
'update activecontracts set status="closed" where contractName="{}" and contractAddress="{}"'.format(
contract[0], contract[1]))
connection.execute(
'update activecontracts set closeDate="{}" where contractName="{}" and contractAddress="{}"'.format(
blockinfo['time'], contract[0], contract[1]))
connection.execute(
'update activecontracts set expiryDate="{}" where contractName="{}" and contractAddress="{}"'.format(
blockinfo['time'], contract[0], contract[1]))
connection.close()
return
expiryTime = contractStructure['expiryTime']
expirytime_split = expiryTime.split(' ')
parse_string = '{}/{}/{} {}'.format(expirytime_split[3], parsing.months[expirytime_split[1]],
expirytime_split[2], expirytime_split[4])
expirytime_object = parsing.arrow.get(parse_string, 'YYYY/M/D HH:mm:ss').replace(tzinfo=expirytime_split[5][3:])
blocktime_object = parsing.arrow.get(blockinfo['time']).to('Asia/Kolkata')
if blocktime_object > expirytime_object:
if 'minimumsubscriptionamount' in contractStructure:
minimumsubscriptionamount = contractStructure['minimumsubscriptionamount']
tokenAmount_sum = connection.execute('select sum(tokenAmount) from contractparticipants').fetchall()[0][0]
if tokenAmount_sum < minimumsubscriptionamount:
# Initialize payback to contract participants
contractParticipants = connection.execute('select participantAddress, tokenAmount, transactionHash from contractparticipants').fetchall()[0][0]
for participant in contractParticipants:
tokenIdentification = connection.execute(
'select * from contractstructure where attribute="tokenIdentification"').fetchall()[0][0]
contractAddress = connection.execute(
'select * from contractstructure where attribute="contractAddress"').fetchall()[0][0]
returnval = transferToken(tokenIdentification, participant[1], contractAddress, participant[0], blockinfo = blockinfo)
if returnval is None:
logger.critical(
"Something went wrong in the token transfer method while doing local Smart Contract Trigger")
return
connection.execute(
'update contractparticipants set winningAmount="{}" where participantAddress="{}" and transactionHash="{}"'.format(
(participant[1], participant[0], participant[2])))
# add transaction to ContractTransactionHistory
session = create_database_session_orm('smart_contract', {'contract_name': f"{contract[0]}", 'contract_address': f"{contract[1]}"}, ContractBase)
session.add(ContractTransactionHistory(transactionType='trigger',
transactionSubType='minimumsubscriptionamount-payback',
transferAmount=None,
blockNumber=blockinfo['height'],
blockHash=blockinfo['hash'],
time=blockinfo['time']))
session.commit()
session.close()
connection = create_database_connection('system_dbs', {'db_name':'system'})
connection.execute('update activecontracts set status="closed" where contractName="{}" and contractAddress="{}"'.format(
contract[0], contract[1]))
connection.execute('update activecontracts set closeDate="{}" where contractName="{}" and contractAddress="{}"'.format(
blockinfo['time'], contract[0], contract[1]))
connection.execute('update activecontracts set expiryDate="{}" where contractName="{}" and contractAddress="{}"'.format(
blockinfo['time'], contract[0], contract[1]))
connection.close()
return
# Trigger the contract
payeeAddress = contractStructure['payeeAddress']
tokenIdentification = contractStructure['tokenIdentification']
contractAddress = contractStructure['contractAddress']
connection = create_database_connection('smart_contract', {'contract_name':f"{contract[0]}", 'contract_address':f"{contract[1]}"})
tokenAmount_sum = connection.execute('select sum(tokenAmount) from contractparticipants').fetchall()[0][0]
returnval = transferToken(tokenIdentification, tokenAmount_sum, contractAddress, payeeAddress, blockinfo = blockinfo)
if returnval is None:
logger.critical("Something went wrong in the token transfer method while doing local Smart Contract Trigger")
return
connection.execute('update contractparticipants set winningAmount="{}"'.format(0))
# add transaction to ContractTransactionHistory
session = create_database_session_orm('smart_contract', {'contract_name': f"{contract[0]}", 'contract_address': f"{contract[1]}"}, ContractBase)
session.add(ContractTransactionHistory(transactionType='trigger',
transactionSubType='expiryTime',
sourceFloAddress=contractAddress,
destFloAddress=payeeAddress,
transferAmount=tokenAmount_sum,
blockNumber=blockinfo['height'],
blockHash=blockinfo['hash'],
time=blockinfo['time']))
session.commit()
session.close()
connection = create_database_connection('system_dbs', {'db_name':'system'})
connection.execute('update activecontracts set status="closed" where contractName="{}" and contractAddress="{}"'.format(contract[0], contract[1]))
connection.execute('update activecontracts set closeDate="{}" where contractName="{}" and contractAddress="{}"'.format(blockinfo['time'], contract[0], contract[1]))
connection.execute('update activecontracts set expiryDate="{}" where contractName="{}" and contractAddress="{}"'.format(blockinfo['time'], contract[0], contract[1]))
connection.close()
return
def processTransaction(transaction_data, parsed_data, blockinfo): def processTransaction(transaction_data, parsed_data, blockinfo):
@ -601,25 +919,10 @@ def processTransaction(transaction_data, parsed_data, blockinfo):
vinlist = [] vinlist = []
querylist = [] querylist = []
# todo Rule 39 - Create a list of vins for a given transaction id
'''for obj in transaction_data["vin"]:
if 'coinbase' in obj.keys():
return 0
querylist.append([obj["txid"], obj["vout"]])'''
#totalinputval = 0 #totalinputval = 0
#inputadd = '' #inputadd = ''
# todo Rule 40 - For each vin, find the feeding address and the fed value. Make an inputlist containing [inputaddress, n value] # todo Rule 40 - For each vin, find the feeding address and the fed value. Make an inputlist containing [inputaddress, n value]
'''for query in querylist:
content = newMultiRequest('tx/{}'.format(str(query[0])))
for objec in content["vout"]:
if objec["n"] == query[1]:
inputadd = objec["scriptPubKey"]["addresses"][0]
pdb.set_trace()
totalinputval = totalinputval + float(objec["value"])
vinlist.append([inputadd, objec["value"]]) '''
for vin in transaction_data["vin"]: for vin in transaction_data["vin"]:
vinlist.append([vin["addr"], float(vin["value"])]) vinlist.append([vin["addr"], float(vin["value"])])
@ -677,6 +980,7 @@ def processTransaction(transaction_data, parsed_data, blockinfo):
# todo Rule 45 - If the transfer type is token, then call the function transferToken to adjust the balances # todo Rule 45 - If the transfer type is token, then call the function transferToken to adjust the balances
if parsed_data['transferType'] == 'token': if parsed_data['transferType'] == 'token':
if not check_if_contract_address(inputlist[0]) and not check_if_contract_address(outputlist[0]):
# check if the token exists in the database # check if the token exists in the database
if check_database_existence('token', {'token_name':f"{parsed_data['tokenIdentification']}"}): if check_database_existence('token', {'token_name':f"{parsed_data['tokenIdentification']}"}):
# Pull details of the token type from system.db database # Pull details of the token type from system.db database
@ -746,11 +1050,39 @@ def processTransaction(transaction_data, parsed_data, blockinfo):
pushData_SSEapi(f"Error | Token transfer at transaction {transaction_data['txid']} rejected as a token with the name {parsed_data['tokenIdentification']} doesnt not exist") pushData_SSEapi(f"Error | Token transfer at transaction {transaction_data['txid']} rejected as a token with the name {parsed_data['tokenIdentification']} doesnt not exist")
return 0 return 0
else:
logger.info(f"Token transfer at transaction {transaction_data['txid']} rejected as either the input address or the output address is part of a contract address")
session = create_database_session_orm('system_dbs', {'db_name': "system"}, Base)
blockchainReference = neturl + 'tx/' + transaction_data['txid']
session.add(RejectedTransactionHistory(tokenIdentification=parsed_data['tokenIdentification'],
sourceFloAddress=inputadd, destFloAddress=outputlist[0],
transferAmount=parsed_data['tokenAmount'],
blockNumber=transaction_data['blockheight'],
blockHash=transaction_data['blockhash'],
time=transaction_data['blocktime'],
transactionHash=transaction_data['txid'],
blockchainReference=blockchainReference,
jsonData=json.dumps(transaction_data),
rejectComment=f"Token transfer at transaction {transaction_data['txid']} rejected as either the input address or the output address is part of a contract address",
transactionType=parsed_data['type'],
parsedFloData=json.dumps(parsed_data)
))
session.commit()
session.close()
pushData_SSEapi(f"Token transfer at transaction {transaction_data['txid']} rejected as either the input address or the output address is part of a contract address")
return 0
# todo Rule 46 - If the transfer type is smart contract, then call the function transferToken to do sanity checks & lock the balance # todo Rule 46 - If the transfer type is smart contract, then call the function transferToken to do sanity checks & lock the balance
elif parsed_data['transferType'] == 'smartContract': elif parsed_data['transferType'] == 'smartContract':
if check_database_existence('smart_contract', {'contract_name':f"{parsed_data['contractName']}", 'contract_address':f"{outputlist[0]}"}): if check_database_existence('smart_contract', {'contract_name':f"{parsed_data['contractName']}", 'contract_address':f"{outputlist[0]}"}):
# Check if the transaction hash already exists in the contract db (Safety check) # Check type of contract and categorize between into ote-participation or continuous-event participation
# todo - replace all connection queries with session queries
connection = create_database_connection('smart_contract', {'contract_name':f"{parsed_data['contractName']}", 'contract_address':f"{outputlist[0]}"}) connection = create_database_connection('smart_contract', {'contract_name':f"{parsed_data['contractName']}", 'contract_address':f"{outputlist[0]}"})
contract_session = create_database_session_orm('smart_contract', {'contract_name':f"{parsed_data['contractName']}", 'contract_address':f"{outputlist[0]}"})
contract_type = contract_session.query(ContractStructure.value).filter(ContractStructure.attribute == 'contractType').first()[0]
if contract_type == 'one-time-event':
# Check if the transaction hash already exists in the contract db (Safety check)
participantAdd_txhash = connection.execute('select participantAddress, transactionHash from contractparticipants').fetchall() participantAdd_txhash = connection.execute('select participantAddress, transactionHash from contractparticipants').fetchall()
participantAdd_txhash_T = list(zip(*participantAdd_txhash)) participantAdd_txhash_T = list(zip(*participantAdd_txhash))
@ -840,8 +1172,7 @@ def processTransaction(transaction_data, parsed_data, blockinfo):
blocktime_object = parsing.arrow.get(transaction_data['blocktime']).to('Asia/Kolkata') blocktime_object = parsing.arrow.get(transaction_data['blocktime']).to('Asia/Kolkata')
if blocktime_object > expirytime_object: if blocktime_object > expirytime_object:
logger.info( logger.info(f"Transaction {transaction_data['txid']} rejected as Smart contract {parsed_data['contractName']}-{outputlist[0]} has expired and will not accept any user participation")
f"Transaction {transaction_data['txid']} rejected as Smart contract {parsed_data['contractName']}-{outputlist[0]} has expired and will not accept any user participation")
# Store transfer as part of RejectedContractTransactionHistory # Store transfer as part of RejectedContractTransactionHistory
session = create_database_session_orm('system_dbs', {'db_name': "system"}, SystemBase) session = create_database_session_orm('system_dbs', {'db_name': "system"}, SystemBase)
blockchainReference = neturl + 'tx/' + transaction_data['txid'] blockchainReference = neturl + 'tx/' + transaction_data['txid']
@ -1293,41 +1624,19 @@ def processTransaction(transaction_data, parsed_data, blockinfo):
'''r = requests.post(tokenapi_sse_url, json={'message': f"Error | Transaction {transaction_data['txid']} rejected as the participation doesn't belong to any valid contract type"}, headers=headers)''' '''r = requests.post(tokenapi_sse_url, json={'message': f"Error | Transaction {transaction_data['txid']} rejected as the participation doesn't belong to any valid contract type"}, headers=headers)'''
return 0 return 0
else: elif contract_type == 'continuos-event':
logger.info(f"Transaction {transaction_data['txid']} rejected as a Smart Contract with the name {parsed_data['contractName']} at address {outputlist[0]} doesnt exist") contract_subtype = contract_session.query(ContractStructure.value).filter(ContractStructure.attribute == 'subtype').first()[0]
# Store transfer as part of RejectedContractTransactionHistory if contract_subtype == 'tokenswap':
session = create_database_session_orm('system_dbs', {'db_name': "system"}, SystemBase) pdb.set_trace()
blockchainReference = neturl + 'tx/' + transaction_data['txid']
session.add(RejectedContractTransactionHistory(transactionType='participation',
contractName=parsed_data['contractName'],
contractAddress=outputlist[0],
sourceFloAddress=inputadd,
destFloAddress=outputlist[0],
transferAmount=None,
blockNumber=transaction_data['blockheight'],
blockHash=transaction_data['blockhash'],
time=transaction_data['blocktime'],
transactionHash=transaction_data['txid'],
blockchainReference=blockchainReference,
jsonData=json.dumps(transaction_data),
rejectComment=f"Transaction {transaction_data['txid']} rejected as a Smart Contract with the name {parsed_data['contractName']} at address {outputlist[0]} doesnt exist",
parsedFloData=json.dumps(parsed_data)
))
session.commit()
session.close()
headers = {'Accept': 'application/json', 'Content-Type': 'application/json'}
'''r = requests.post(tokenapi_sse_url, json={'message': f"Error | Contract transaction {transaction_data['txid']} rejected as a smartcontract with same name {parsed_data['contractName']}-{parsed_data['contractAddress']} dosent exist "}, headers=headers)'''
return 0
elif parsed_data['transferType'] == 'swapParticipaton':
if check_database_existence('smart_contract', {'contract_name':f"{parsed_data['contractName']}", 'contract_address':f"{outputlist[0]}"}):
# Check if the transaction hash already exists in the contract db (Safety check) # Check if the transaction hash already exists in the contract db (Safety check)
connection = create_database_connection('smart_contract', {'contract_name':f"{parsed_data['contractName']}", 'contract_address':f"{outputlist[0]}"})
participantAdd_txhash = connection.execute('select participantAddress, transactionHash from contractparticipants').fetchall() participantAdd_txhash = connection.execute('select participantAddress, transactionHash from contractparticipants').fetchall()
participantAdd_txhash_T = list(zip(*participantAdd_txhash)) participantAdd_txhash_T = list(zip(*participantAdd_txhash))
if len(participantAdd_txhash) != 0 and transaction_data['txid'] in list(participantAdd_txhash_T[1]):
logger.warning(f"Transaction {transaction_data['txid']} rejected as it already exists in the Smart Contract db. This is unusual, please check your code")
pushData_SSEapi(f"Error | Transaction {transaction_data['txid']} rejected as it already exists in the Smart Contract db. This is unusual, please check your code")
return 0
# if contractAddress was passed, then check if it matches the output address of this contract # if contractAddress was passed, then check if it matches the output address of this contract
if 'contractAddress' in parsed_data: if 'contractAddress' in parsed_data:
if parsed_data['contractAddress'] != outputlist[0]: if parsed_data['contractAddress'] != outputlist[0]:
@ -1348,33 +1657,73 @@ def processTransaction(transaction_data, parsed_data, blockinfo):
blockchainReference=blockchainReference, blockchainReference=blockchainReference,
jsonData=json.dumps(transaction_data), jsonData=json.dumps(transaction_data),
rejectComment=f"Contract participation at transaction {transaction_data['txid']} rejected as contractAddress specified in flodata, {parsed_data['contractAddress']}, doesnt not match with transaction's output address {outputlist[0]}", rejectComment=f"Contract participation at transaction {transaction_data['txid']} rejected as contractAddress specified in flodata, {parsed_data['contractAddress']}, doesnt not match with transaction's output address {outputlist[0]}",
parsedFloData=json.dumps(parsed_data))) parsedFloData=json.dumps(parsed_data)))
session.commit() session.commit()
session.close() session.close()
headers = {'Accept': 'application/json', 'Content-Type': 'application/json'} headers = {'Accept': 'application/json', 'Content-Type': 'application/json'}
'''r = requests.post(tokenapi_sse_url, json={'message': f"Error | Contract participation at transaction {transaction_data['txid']} rejected as contractAddress specified in flodata, {parsed_data['contractAddress']}, doesnt not match with transaction's output address {outputlist[0]}"}, '''r = requests.post(tokenapi_sse_url, json={'message': f"Error | Contract participation at transaction {transaction_data['txid']} rejected as contractAddress specified in flodata, {parsed_data['contractAddress']}, doesnt not match with transaction's output address {outputlist[0]}"}, headers=headers)'''
headers=headers)'''
# Pass information to SSE channel # Pass information to SSE channel
pushData_SSEapi('Error| Mismatch in contract address specified in flodata and the output address of the transaction {}'.format(transaction_data['txid'])) pushData_SSEapi('Error| Mismatch in contract address specified in flodata and the output address of the transaction {}'.format(transaction_data['txid']))
return 0 return 0
# pull out the contract structure into a dictionary # pull out the contract structure into a dictionary
connection = create_database_connection('smart_contract', {'contract_name':f"{parsed_data['contractName']}", 'contract_address':f"{outputlist[0]}"}) attributevaluepair = contract_session.query(ContractStructure.attribute, ContractStructure.value).filter(ContractStructure.attribute != 'contractType', ContractStructure.attribute != 'flodata', ContractStructure.attribute != 'contractAddress').all()
attributevaluepair = connection.execute("select attribute, value from contractstructure where attribute != 'contractName' and attribute != 'flodata' and attribute != 'contractAddress'").fetchall()
contractStructure = {} contractStructure = {}
conditionDict = {} conditionDict = {}
counter = 0 counter = 0
for attribute in attributevaluepair:
contractStructure[item[0]] = item[1]
del counter, conditionDict del counter, conditionDict
if contractStructure['pricetype'] in ['predetermined','determined']: if contractStructure['pricetype'] in ['predetermined','determined']:
swapPrice = contractStructure['price'] swapPrice = float(contractStructure['price'])
elif contractStructure['pricetype'] == 'dynamic': elif contractStructure['pricetype'] == 'dynamic':
pass pass
returnval = transferToken(contractStructure['accepting_token'], swapPrice, inputlist[0],outputlist[0], transaction_data, parsed_data, blockinfo = blockinfo) swapAmount = float(parsed_data['tokenAmount'])/swapPrice
# Check if the swap amount is available in the deposits of the selling token
# if yes do the transfers, otherwise reject the transaction
#
depositAmount = connection.execute('SELECT depositBalance FROM contractdeposits WHERE id=(SELECT max(id) FROM contractdeposits);').fetchall()
#depositAmount = contract_session.query(ContractDeposits.depositBalance).filter()
if depositAmount is None:
depositAmount = 0
else:
depositAmount = depositAmount[0][0]
pdb.set_trace()
if depositAmount >= swapAmount:
'''
todo - Find the pids and address pairs of the deposits being consumed
Find all the pids/entries which will be used for the deposit
Recursively go from the last line to the top
'''
deposit_balance_counter = 0
deposit_pid_dict = {}
max_id = connection.execute("SELECT max(id) FROM contractdeposits").fetchall()[0][0]
while(True):
# Get the last entry from the deposit table
deposit_entry = connection.execute('SELECT * FROM contractdeposits WHERE id=?',(max_id)).fetchall()[0]
deposit_balance_counter = deposit_balance_counter + float(deposit_entry[2])
deposit_pid_dict[deposit_entry[0]] = deposit_entry[2]
max_id = max_id - 1
# Code for adding the input line
connection.execute("INSERT INTO contract_deposits (depositorAddress, depositAmount, depositBalance, expiryTime, status, transactionHash, blockNumber, blockHash) VALUES (?,?,?,?,?,?,?,?);",(deposit_entry[1], depositAmount, depositBalance, expiryTime, status, transactionHash, blockNumber, blockHash))
# Code for breaking the loop
if deposit_balance_counter >= swapAmount:
break
pdb.set_trace()
returnval = transferToken(contractStructure['accepting_token'], parsed_data['tokenAmount'], inputlist[0],outputlist[0], transaction_data, parsed_data, blockinfo = blockinfo)
if returnval is None: if returnval is None:
logger.info("Something went wrong in the token transfer method") logger.info("Something went wrong in the token transfer method")
pushData_SSEapi(f"Error | Something went wrong while doing the internal db transactions for {transaction_data['txid']}") pushData_SSEapi(f"Error | Something went wrong while doing the internal db transactions for {transaction_data['txid']}")
@ -1382,20 +1731,8 @@ def processTransaction(transaction_data, parsed_data, blockinfo):
else: else:
updateLatestTransaction(transaction_data, parsed_data) updateLatestTransaction(transaction_data, parsed_data)
# If this is the first interaction of the outputlist's address with the given token name, add it to token mapping
connection = create_database_connection('system_dbs', {'db_name':'system'})
firstInteractionCheck = connection.execute(f"select * from tokenAddressMapping where tokenAddress='{outputlist[0]}' and token='{parsed_data['tokenIdentification']}'").fetchall()
if len(firstInteractionCheck) == 0: returnval = transferToken(contractStructure['selling_token'], swapAmount, outputlist[0], inputlist[0], transaction_data, parsed_data, blockinfo = blockinfo)
connection.execute(f"INSERT INTO tokenAddressMapping (tokenAddress, token, transactionHash, blockNumber, blockHash) VALUES ('{outputlist[0]}', '{parsed_data['tokenIdentification']}', '{transaction_data['txid']}', '{transaction_data['blockheight']}', '{transaction_data['blockhash']}')")
connection.close()
# Pass information to SSE channel
headers = {'Accept': 'application/json', 'Content-Type': 'application/json'}
# r = requests.post(tokenapi_sse_url, json={f"message': 'Token Transfer | name:{parsed_data['tokenIdentification']} | transactionHash:{transaction_data['txid']}"}, headers=headers)
returnval = transferToken(contractStructure['selling_token'], swapPrice, outputlist[0], inputlist[0], transaction_data, parsed_data, blockinfo = blockinfo)
if returnval is None: if returnval is None:
logger.info("Something went wrong in the token transfer method") logger.info("Something went wrong in the token transfer method")
pushData_SSEapi(f"Error | Something went wrong while doing the internal db transactions for {transaction_data['txid']}") pushData_SSEapi(f"Error | Something went wrong while doing the internal db transactions for {transaction_data['txid']}")
@ -1403,30 +1740,29 @@ def processTransaction(transaction_data, parsed_data, blockinfo):
else: else:
updateLatestTransaction(transaction_data, parsed_data) updateLatestTransaction(transaction_data, parsed_data)
# If this is the first interaction of the outputlist's address with the given token name, add it to token mapping # If this is the first interaction of the outputlist's address with the given token name, add it to token mapping
connection = create_database_connection('system_dbs', {'db_name':'system'}) connection = create_database_connection('system_dbs', {'db_name':'system'})
firstInteractionCheck = connection.execute(f"select * from tokenAddressMapping where tokenAddress='{outputlist[0]}' and token='{parsed_data['tokenIdentification']}'").fetchall() firstInteractionCheck = connection.execute(f"select * from tokenAddressMapping where tokenAddress='{outputlist[0]}' and token='{parsed_data['tokenIdentification']}'").fetchall()
if len(firstInteractionCheck) == 0: if len(firstInteractionCheck) == 0:
connection.execute(f"INSERT INTO tokenAddressMapping (tokenAddress, token, transactionHash, blockNumber, blockHash) VALUES ('{outputlist[0]}', '{parsed_data['tokenIdentification']}', '{transaction_data['txid']}', '{transaction_data['blockheight']}', '{transaction_data['blockhash']}')") connection.execute(f"INSERT INTO tokenAddressMapping (tokenAddress, token, transactionHash, blockNumber, blockHash) VALUES ('{outputlist[0]}', '{parsed_data['tokenIdentification']}', '{transaction_data['txid']}', '{transaction_data['blockheight']}', '{transaction_data['blockhash']}')")
connection.close() connection.close()
# Push the Swap Participation transaction into contract database # Push the Swap Participation transaction into contract database
session = create_database_session_orm('smart_contract', {'contract_name': f"{parsed_data['contractName']}", 'contract_address': f"{outputlist[0]}"}, ContinuosContractBase) session = create_database_session_orm('smart_contract', {'contract_name': f"{parsed_data['contractName']}", 'contract_address': f"{outputlist[0]}"}, ContractBase)
blockchainReference = neturl + 'tx/' + transaction_data['txid'] blockchainReference = neturl + 'tx/' + transaction_data['txid']
session.add(ContractParticipants(participantAddress = inputadd,
session.add(ContractParticipants1(participantAddress = inputadd,
tokenAmount = swapPrice, tokenAmount = swapPrice,
transactionHash = transaction_data['txid'], transactionHash = transaction_data['txid'],
blockNumber = transaction_data['blockheight'], blockNumber = transaction_data['blockheight'],
blockHash = transaction_data['blockhash'] blockHash = transaction_data['blockhash']
)) ))
session.add(ContractTransactionHistory1(transactionType = 'smartContractDeposit', session.add(ContractTransactionHistory(transactionType = 'smartContractDeposit',
transactionSubType = None, transactionSubType = None,
sourceFloAddress = inputadd, sourceFloAddress = inputadd,
destFloAddress = outputlist[0], destFloAddress = outputlist[0],
transferAmount = parsed_data['depositAmount'], transferAmount = parsed_data['tokenAmount'],
blockNumber = transaction_data['blockheight'], blockNumber = transaction_data['blockheight'],
blockHash = transaction_data['blockhash'], blockHash = transaction_data['blockhash'],
time = transaction_data['blocktime'], time = transaction_data['blocktime'],
@ -1443,9 +1779,33 @@ def processTransaction(transaction_data, parsed_data, blockinfo):
# Pass information to SSE channel # Pass information to SSE channel
headers = {'Accept': 'application/json', 'Content-Type': 'application/json'} headers = {'Accept': 'application/json', 'Content-Type': 'application/json'}
# r = requests.post(tokenapi_sse_url, json={f"message': 'Token Transfer | name:{parsed_data['tokenIdentification']} | transactionHash:{transaction_data['txid']}"}, headers=headers) # r = requests.post(tokenapi_sse_url, json={f"message': 'Token Transfer | name:{parsed_data['tokenIdentification']} | transactionHash:{transaction_data['txid']}"}, headers=headers)
return 1 return 1
else:
logger.info(f"Transaction {transaction_data['txid']} rejected as Smart Contract {parsed_data['contractName']} at address {outputlist[0]} does not have the deposit amount asked for")
# Store transfer as part of RejectedContractTransactionHistory
session = create_database_session_orm('system_dbs', {'db_name': "system"}, SystemBase)
blockchainReference = neturl + 'tx/' + transaction_data['txid']
session.add(RejectedContractTransactionHistory(transactionType='participation',
contractName=parsed_data['contractName'],
contractAddress=outputlist[0],
sourceFloAddress=inputadd,
destFloAddress=outputlist[0],
transferAmount=None,
blockNumber=transaction_data['blockheight'],
blockHash=transaction_data['blockhash'],
time=transaction_data['blocktime'],
transactionHash=transaction_data['txid'],
blockchainReference=blockchainReference,
jsonData=json.dumps(transaction_data),
rejectComment=f"Transaction {transaction_data['txid']} rejected as Smart Contract {parsed_data['contractName']} at address {outputlist[0]} does not have the deposit amount asked for",
parsedFloData=json.dumps(parsed_data)
))
session.commit()
session.close()
headers = {'Accept': 'application/json', 'Content-Type': 'application/json'}
'''r = requests.post(tokenapi_sse_url, json={'message': f"Error | Contract transaction {transaction_data['txid']} rejected as a smartcontract with same name {parsed_data['contractName']}-{parsed_data['contractAddress']} dosent exist "}, headers=headers)'''
return 0
else: else:
logger.info(f"Transaction {transaction_data['txid']} rejected as a Smart Contract with the name {parsed_data['contractName']} at address {outputlist[0]} doesnt exist") logger.info(f"Transaction {transaction_data['txid']} rejected as a Smart Contract with the name {parsed_data['contractName']} at address {outputlist[0]} doesnt exist")
@ -1471,9 +1831,7 @@ def processTransaction(transaction_data, parsed_data, blockinfo):
session.close() session.close()
headers = {'Accept': 'application/json', 'Content-Type': 'application/json'} headers = {'Accept': 'application/json', 'Content-Type': 'application/json'}
'''r = requests.post(tokenapi_sse_url, json={ '''r = requests.post(tokenapi_sse_url, json={'message': f"Error | Contract transaction {transaction_data['txid']} rejected as a smartcontract with same name {parsed_data['contractName']}-{parsed_data['contractAddress']} dosent exist "}, headers=headers)'''
'message': f"Error | Contract transaction {transaction_data['txid']} rejected as a smartcontract with same name {parsed_data['contractName']}-{parsed_data['contractAddress']} dosent exist "},
headers=headers)'''
return 0 return 0
elif parsed_data['transferType'] == 'nft': elif parsed_data['transferType'] == 'nft':
@ -1482,6 +1840,7 @@ def processTransaction(transaction_data, parsed_data, blockinfo):
# todo Rule 47 - If the parsed data type is token incorporation, then check if the name hasn't been taken already # todo Rule 47 - If the parsed data type is token incorporation, then check if the name hasn't been taken already
# if it has been taken then reject the incorporation. Else incorporate it # if it has been taken then reject the incorporation. Else incorporate it
elif parsed_data['type'] == 'tokenIncorporation': elif parsed_data['type'] == 'tokenIncorporation':
if not check_if_contract_address(inputlist[0]):
if not check_database_existence('token', {'token_name':f"{parsed_data['tokenIdentification']}"}): if not check_database_existence('token', {'token_name':f"{parsed_data['tokenIdentification']}"}):
session = create_database_session_orm('token', {'token_name': f"{parsed_data['tokenIdentification']}"}, Base) session = create_database_session_orm('token', {'token_name': f"{parsed_data['tokenIdentification']}"}, Base)
session.add(ActiveTable(address=inputlist[0], parentid=0, transferBalance=parsed_data['tokenAmount'], addressBalance=parsed_data['tokenAmount'], blockNumber=blockinfo['height'])) session.add(ActiveTable(address=inputlist[0], parentid=0, transferBalance=parsed_data['tokenAmount'], addressBalance=parsed_data['tokenAmount'], blockNumber=blockinfo['height']))
@ -1532,6 +1891,27 @@ def processTransaction(transaction_data, parsed_data, blockinfo):
session.close() session.close()
pushData_SSEapi(f"Error | Token incorporation rejected at transaction {transaction_data['txid']} as token {parsed_data['tokenIdentification']} already exists") pushData_SSEapi(f"Error | Token incorporation rejected at transaction {transaction_data['txid']} as token {parsed_data['tokenIdentification']} already exists")
return 0 return 0
else:
logger.info(f"Token incorporation at transaction {transaction_data['txid']} rejected as either the input address is part of a contract address")
session = create_database_session_orm('system_dbs', {'db_name': "system"}, Base)
blockchainReference = neturl + 'tx/' + transaction_data['txid']
session.add(RejectedTransactionHistory(tokenIdentification=parsed_data['tokenIdentification'],
sourceFloAddress=inputadd, destFloAddress=outputlist[0],
transferAmount=parsed_data['tokenAmount'],
blockNumber=transaction_data['blockheight'],
blockHash=transaction_data['blockhash'],
time=transaction_data['blocktime'],
transactionHash=transaction_data['txid'],
blockchainReference=blockchainReference,
jsonData=json.dumps(transaction_data),
rejectComment=f"Token incorporation at transaction {transaction_data['txid']} rejected as either the input address is part of a contract address",
transactionType=parsed_data['type'],
parsedFloData=json.dumps(parsed_data)
))
session.commit()
session.close()
pushData_SSEapi(f"Token incorporation at transaction {transaction_data['txid']} rejected as either the input address is part of a contract address")
return 0
# todo Rule 48 - If the parsed data type if smart contract incorporation, then check if the name hasn't been taken already # todo Rule 48 - If the parsed data type if smart contract incorporation, then check if the name hasn't been taken already
# if it has been taken then reject the incorporation. # if it has been taken then reject the incorporation.
@ -1561,7 +1941,6 @@ def processTransaction(transaction_data, parsed_data, blockinfo):
blockchainReference=blockchainReference, blockchainReference=blockchainReference,
jsonData=json.dumps(transaction_data), jsonData=json.dumps(transaction_data),
rejectComment=f"Either userchoice or payeeAddress should be part of the Contract conditions.\nSmart contract incorporation on transaction {transaction_data['txid']} rejected", rejectComment=f"Either userchoice or payeeAddress should be part of the Contract conditions.\nSmart contract incorporation on transaction {transaction_data['txid']} rejected",
parsedFloData=json.dumps(parsed_data) parsedFloData=json.dumps(parsed_data)
)) ))
session.commit() session.commit()
@ -1587,7 +1966,6 @@ def processTransaction(transaction_data, parsed_data, blockinfo):
blockchainReference=blockchainReference, blockchainReference=blockchainReference,
jsonData=json.dumps(transaction_data), jsonData=json.dumps(transaction_data),
rejectComment=f"Both userchoice and payeeAddress provided as part of the Contract conditions.\nSmart contract incorporation on transaction {transaction_data['txid']} rejected", rejectComment=f"Both userchoice and payeeAddress provided as part of the Contract conditions.\nSmart contract incorporation on transaction {transaction_data['txid']} rejected",
parsedFloData=json.dumps(parsed_data) parsedFloData=json.dumps(parsed_data)
)) ))
session.commit() session.commit()
@ -1618,6 +1996,7 @@ def processTransaction(transaction_data, parsed_data, blockinfo):
session.add( session.add(
ContractStructure(attribute='maximumsubscriptionamount', index=0, ContractStructure(attribute='maximumsubscriptionamount', index=0,
value=parsed_data['contractConditions']['maximumsubscriptionamount'])) value=parsed_data['contractConditions']['maximumsubscriptionamount']))
if 'userchoices' in parsed_data['contractConditions']: if 'userchoices' in parsed_data['contractConditions']:
for key, value in parsed_data['contractConditions']['userchoices'].items(): for key, value in parsed_data['contractConditions']['userchoices'].items():
session.add(ContractStructure(attribute='exitconditions', index=key, value=value)) session.add(ContractStructure(attribute='exitconditions', index=key, value=value))
@ -1686,14 +2065,24 @@ def processTransaction(transaction_data, parsed_data, blockinfo):
keyword='', keyword='',
object_format='', object_format='',
blockNumber=transaction_data['blockheight'])) blockNumber=transaction_data['blockheight']))
session.commit() if 'payeeAddress' in parsed_data['contractConditions']:
session.add(TimeActions(time=parsed_data['contractConditions']['expiryTime'],
activity='contract-trigger',
status='active',
contractName=parsed_data['contractName'],
contractAddress=inputadd,
contractType='one-time-event-trigger',
tokens_db=[parsed_data['tokenIdentification']],
parsed_data=json.dumps(parsed_data),
transactionHash=transaction_data['txid'],
blockNumber=transaction_data['blockheight']))
session.commit()
session.close() session.close()
updateLatestTransaction(transaction_data, parsed_data) updateLatestTransaction(transaction_data, parsed_data)
pushData_SSEapi('Contract | Contract incorporated at transaction {} with name {}-{}'.format( pushData_SSEapi('Contract | Contract incorporated at transaction {} with name {}-{}'.format(transaction_data['txid'], parsed_data['contractName'], parsed_data['contractAddress']))
transaction_data['txid'], parsed_data['contractName'], parsed_data['contractAddress']))
return 1 return 1
else: else:
logger.info( logger.info(
@ -1729,26 +2118,26 @@ def processTransaction(transaction_data, parsed_data, blockinfo):
logger.debug("Smart contract is of the type continuous-event") logger.debug("Smart contract is of the type continuous-event")
# Add checks to reject the creation of contract # Add checks to reject the creation of contract
if parsed_data['contractAddress'] == inputadd: if parsed_data['contractAddress'] == inputadd:
session = create_database_session_orm('smart_contract', {'contract_name': f"{parsed_data['contractName']}", 'contract_address': f"{parsed_data['contractAddress']}"}, ContinuosContractBase) session = create_database_session_orm('smart_contract', {'contract_name': f"{parsed_data['contractName']}", 'contract_address': f"{parsed_data['contractAddress']}"}, ContractBase)
session.add(ContractStructure1(attribute='contractType', index=0, value=parsed_data['contractType'])) session.add(ContractStructure(attribute='contractType', index=0, value=parsed_data['contractType']))
session.add(ContractStructure1(attribute='contractName', index=0, value=parsed_data['contractName'])) session.add(ContractStructure(attribute='contractName', index=0, value=parsed_data['contractName']))
session.add(ContractStructure1(attribute='contractAddress', index=0, value=parsed_data['contractAddress'])) session.add(ContractStructure(attribute='contractAddress', index=0, value=parsed_data['contractAddress']))
session.add(ContractStructure1(attribute='flodata', index=0, value=parsed_data['flodata'])) session.add(ContractStructure(attribute='flodata', index=0, value=parsed_data['flodata']))
if 'subtype' in parsed_data['contractConditions']: if 'subtype' in parsed_data['contractConditions']:
# todo: Check if the both the tokens mentioned exist if its a token swap # todo: Check if the both the tokens mentioned exist if its a token swap
if (parsed_data['contractConditions']['subtype'] == 'tokenswap') and (check_database_existence('token', {'token_name':f"{parsed_data['contractConditions']['accepting_token'].split('#')[0]}"})) and (check_database_existence('token', {'token_name':f"{parsed_data['contractConditions']['selling_token'].split('#')[0]}"})): if (parsed_data['contractConditions']['subtype'] == 'tokenswap') and (check_database_existence('token', {'token_name':f"{parsed_data['contractConditions']['accepting_token'].split('#')[0]}"})) and (check_database_existence('token', {'token_name':f"{parsed_data['contractConditions']['selling_token'].split('#')[0]}"})):
#if (parsed_data['contractConditions']['subtype'] == 'tokenswap'): #if (parsed_data['contractConditions']['subtype'] == 'tokenswap'):
if parsed_data['contractConditions']['pricetype'] in ['predetermined','determined']: if parsed_data['contractConditions']['pricetype'] in ['predetermined','determined']:
session.add(ContractStructure1(attribute='subtype', index=0, value=parsed_data['contractConditions']['subtype'])) session.add(ContractStructure(attribute='subtype', index=0, value=parsed_data['contractConditions']['subtype']))
session.add(ContractStructure1(attribute='accepting_token', index=0, value=parsed_data['contractConditions']['accepting_token'])) session.add(ContractStructure(attribute='accepting_token', index=0, value=parsed_data['contractConditions']['accepting_token']))
session.add(ContractStructure1(attribute='selling_token', index=0, value=parsed_data['contractConditions']['selling_token'])) session.add(ContractStructure(attribute='selling_token', index=0, value=parsed_data['contractConditions']['selling_token']))
# determine price # determine price
session.add(ContractStructure1(attribute='pricetype', index=0, value=parsed_data['contractConditions']['pricetype'])) session.add(ContractStructure(attribute='pricetype', index=0, value=parsed_data['contractConditions']['pricetype']))
session.add(ContractStructure1(attribute='price', index=0, value=parsed_data['contractConditions']['price'])) session.add(ContractStructure(attribute='price', index=0, value=parsed_data['contractConditions']['price']))
# Store transfer as part of ContractTransactionHistory # Store transfer as part of ContractTransactionHistory
blockchainReference = neturl + 'tx/' + transaction_data['txid'] blockchainReference = neturl + 'tx/' + transaction_data['txid']
session.add(ContractTransactionHistory1(transactionType='incorporation', sourceFloAddress=inputadd, session.add(ContractTransactionHistory(transactionType='incorporation', sourceFloAddress=inputadd,
destFloAddress=outputlist[0], destFloAddress=outputlist[0],
transferAmount=None, transferAmount=None,
blockNumber=transaction_data['blockheight'], blockNumber=transaction_data['blockheight'],
@ -1812,7 +2201,6 @@ def processTransaction(transaction_data, parsed_data, blockinfo):
session.close() session.close()
updateLatestTransaction(transaction_data, parsed_data) updateLatestTransaction(transaction_data, parsed_data)
pdb.set_trace()
pushData_SSEapi('Contract | Contract incorporated at transaction {} with name {}-{}'.format(transaction_data['txid'], parsed_data['contractName'], parsed_data['contractAddress'])) pushData_SSEapi('Contract | Contract incorporated at transaction {} with name {}-{}'.format(transaction_data['txid'], parsed_data['contractName'], parsed_data['contractAddress']))
return 1 return 1
@ -1863,11 +2251,9 @@ def processTransaction(transaction_data, parsed_data, blockinfo):
time=transaction_data['blocktime'], time=transaction_data['blocktime'],
transactionHash=transaction_data['txid'], transactionHash=transaction_data['txid'],
blockchainReference=blockchainReference, blockchainReference=blockchainReference,
jsonData=json.dumps( jsonData=json.dumps(transaction_data),
transaction_data),
rejectComment=f"No subtype provided for the Contract of type continuos event.\nSmart contract incorporation on transaction {transaction_data['txid']} rejected", rejectComment=f"No subtype provided for the Contract of type continuos event.\nSmart contract incorporation on transaction {transaction_data['txid']} rejected",
parsedFloData=json.dumps( parsedFloData=json.dumps(parsed_data)
parsed_data)
)) ))
session.commit() session.commit()
session.close() session.close()
@ -2254,7 +2640,6 @@ def processTransaction(transaction_data, parsed_data, blockinfo):
blockchainReference=blockchainReference, blockchainReference=blockchainReference,
jsonData=json.dumps(transaction_data), jsonData=json.dumps(transaction_data),
rejectComment=f"Transaction {transaction_data['txid']} rejected as Smart Contract named {parsed_data['contractName']} at the address {outputlist[0]} doesn't exist", rejectComment=f"Transaction {transaction_data['txid']} rejected as Smart Contract named {parsed_data['contractName']} at the address {outputlist[0]} doesn't exist",
parsedFloData=json.dumps(parsed_data) parsedFloData=json.dumps(parsed_data)
)) ))
session.commit() session.commit()
@ -2280,7 +2665,6 @@ def processTransaction(transaction_data, parsed_data, blockinfo):
blockchainReference=blockchainReference, blockchainReference=blockchainReference,
jsonData=json.dumps(transaction_data), jsonData=json.dumps(transaction_data),
rejectComment=f"Transaction {transaction_data['txid']} rejected as input address, {inputlist[0]}, is not part of the committee address list", rejectComment=f"Transaction {transaction_data['txid']} rejected as input address, {inputlist[0]}, is not part of the committee address list",
parsedFloData=json.dumps(parsed_data) parsedFloData=json.dumps(parsed_data)
)) ))
session.commit() session.commit()
@ -2303,7 +2687,7 @@ def processTransaction(transaction_data, parsed_data, blockinfo):
# if contractAddress was passed, then check if it matches the output address of this contract # if contractAddress was passed, then check if it matches the output address of this contract
if 'contractAddress' in parsed_data: if 'contractAddress' in parsed_data:
if parsed_data['contractAddress'] != outputlist[0]: if parsed_data['contractAddress'] != outputlist[0]:
logger.info(f"Contract participation at transaction {transaction_data['txid']} rejected as contractAddress specified in flodata, {parsed_data['contractAddress']}, doesnt not match with transaction's output address {outputlist[0]}") logger.info(f"Contract deposit at transaction {transaction_data['txid']} rejected as contractAddress specified in flodata, {parsed_data['contractAddress']}, doesnt not match with transaction's output address {outputlist[0]}")
# Store transfer as part of RejectedContractTransactionHistory # Store transfer as part of RejectedContractTransactionHistory
session = create_database_session_orm('system_dbs', {'db_name': "system"}, SystemBase) session = create_database_session_orm('system_dbs', {'db_name': "system"}, SystemBase)
blockchainReference = neturl + 'tx/' + transaction_data['txid'] blockchainReference = neturl + 'tx/' + transaction_data['txid']
@ -2319,7 +2703,7 @@ def processTransaction(transaction_data, parsed_data, blockinfo):
transactionHash=transaction_data['txid'], transactionHash=transaction_data['txid'],
blockchainReference=blockchainReference, blockchainReference=blockchainReference,
jsonData=json.dumps(transaction_data), jsonData=json.dumps(transaction_data),
rejectComment=f"Contract participation at transaction {transaction_data['txid']} rejected as contractAddress specified in flodata, {parsed_data['contractAddress']}, doesnt not match with transaction's output address {outputlist[0]}", rejectComment=f"Contract deposit at transaction {transaction_data['txid']} rejected as contractAddress specified in flodata, {parsed_data['contractAddress']}, doesnt not match with transaction's output address {outputlist[0]}",
parsedFloData=json.dumps(parsed_data))) parsedFloData=json.dumps(parsed_data)))
session.commit() session.commit()
session.close() session.close()
@ -2347,18 +2731,31 @@ def processTransaction(transaction_data, parsed_data, blockinfo):
contractStructure['exitconditions'] = conditionDict contractStructure['exitconditions'] = conditionDict
del counter, conditionDict del counter, conditionDict
# Transfer the token
returnval = transferToken(parsed_data['tokenIdentification'], parsed_data['depositAmount'], inputlist[0], outputlist[0], transaction_data, parsed_data, blockinfo=blockinfo)
if returnval is None:
logger.info("Something went wrong in the token transfer method")
pushData_SSEapi(f"Error | Something went wrong while doing the internal db transactions for {transaction_data['txid']}")
return 0
# Push the deposit transaction into deposit database contract database # Push the deposit transaction into deposit database contract database
session = create_database_session_orm('smart_contract', {'contract_name': f"{parsed_data['contractName']}", 'contract_address': f"{outputlist[0]}"}, ContinuosContractBase) session = create_database_session_orm('smart_contract', {'contract_name': f"{parsed_data['contractName']}", 'contract_address': f"{outputlist[0]}"}, ContractBase)
blockchainReference = neturl + 'tx/' + transaction_data['txid'] blockchainReference = neturl + 'tx/' + transaction_data['txid']
session.add(ContractDeposits1(depositorAddress = inputadd, old_depositBalance = session.query(ContractDeposits.depositBalance).order_by(ContractDeposits.id.desc()).first()
if old_depositBalance is None:
old_depositBalance = 0
else:
old_depositBalance = old_depositBalance[0]
session.add(ContractDeposits( depositorAddress = inputadd,
depositAmount = parsed_data['depositAmount'], depositAmount = parsed_data['depositAmount'],
depositBalance = old_depositBalance + parsed_data['depositAmount'],
expiryTime = parsed_data['depositConditions']['expiryTime'], expiryTime = parsed_data['depositConditions']['expiryTime'],
status = 'active',
transactionHash = transaction_data['txid'], transactionHash = transaction_data['txid'],
blockNumber = transaction_data['blockheight'], blockNumber = transaction_data['blockheight'],
blockHash = transaction_data['blockhash'] blockHash = transaction_data['blockhash']
)) ))
session.add(ContractTransactionHistory1(transactionType = 'smartContractDeposit', session.add(ContractTransactionHistory(transactionType = 'smartContractDeposit',
transactionSubType = None, transactionSubType = None,
sourceFloAddress = inputadd, sourceFloAddress = inputadd,
destFloAddress = outputlist[0], destFloAddress = outputlist[0],
@ -2373,8 +2770,22 @@ def processTransaction(transaction_data, parsed_data, blockinfo):
)) ))
session.commit() session.commit()
session.close() session.close()
pushData_SSEapi(f"Deposit Smart Contract Transaction {transaction_data['txid']} rejected as maximum subscription amount has been reached for the Smart contract named {parsed_data['contractName']} at the address {outputlist[0]}")
return 0 session = create_database_session_orm('system_dbs', {'db_name': f"system"}, SystemBase)
session.add(TimeActions(time=parsed_data['depositConditions']['expiryTime'],
activity='contract-deposit',
status='active',
contractName=parsed_data['contractName'],
contractAddress=outputlist[0],
contractType='continuos-event-swap',
tokens_db=f"{parsed_data['tokenIdentification']}",
parsed_data=json.dumps(parsed_data),
transactionHash=transaction_data['txid'],
blockNumber=transaction_data['blockheight']))
session.commit()
pushData_SSEapi(f"Deposit Smart Contract Transaction {transaction_data['txid']} for the Smart contract named {parsed_data['contractName']} at the address {outputlist[0]}")
updateLatestTransaction(transaction_data, parsed_data)
return 1
else: else:
logger.info(f"Transaction {transaction_data['txid']} rejected as a Smart Contract with the name {parsed_data['contractName']} at address {outputlist[0]} doesnt exist") logger.info(f"Transaction {transaction_data['txid']} rejected as a Smart Contract with the name {parsed_data['contractName']} at address {outputlist[0]} doesnt exist")
@ -2394,7 +2805,6 @@ def processTransaction(transaction_data, parsed_data, blockinfo):
blockchainReference=blockchainReference, blockchainReference=blockchainReference,
jsonData=json.dumps(transaction_data), jsonData=json.dumps(transaction_data),
rejectComment=f"Transaction {transaction_data['txid']} rejected as a Smart Contract with the name {parsed_data['contractName']} at address {outputlist[0]} doesnt exist", rejectComment=f"Transaction {transaction_data['txid']} rejected as a Smart Contract with the name {parsed_data['contractName']} at address {outputlist[0]} doesnt exist",
parsedFloData=json.dumps(parsed_data) parsedFloData=json.dumps(parsed_data)
)) ))
session.commit() session.commit()
@ -2413,6 +2823,7 @@ def processTransaction(transaction_data, parsed_data, blockinfo):
Creation and transfer amount .. only integer parts will be taken Creation and transfer amount .. only integer parts will be taken
Keyword nft must be present in both creation and transfer Keyword nft must be present in both creation and transfer
''' '''
if not check_if_contract_address(inputlist[0]):
if not check_database_existence('token', {'token_name':f"{parsed_data['tokenIdentification']}"}): if not check_database_existence('token', {'token_name':f"{parsed_data['tokenIdentification']}"}):
session = create_database_session_orm('token', {'token_name': f"{parsed_data['tokenIdentification']}"}, Base) session = create_database_session_orm('token', {'token_name': f"{parsed_data['tokenIdentification']}"}, Base)
session.add(ActiveTable(address=inputlist[0], parentid=0, transferBalance=parsed_data['tokenAmount'], blockNumber=blockinfo['height'])) session.add(ActiveTable(address=inputlist[0], parentid=0, transferBalance=parsed_data['tokenAmount'], blockNumber=blockinfo['height']))
@ -2464,8 +2875,30 @@ def processTransaction(transaction_data, parsed_data, blockinfo):
session.close() session.close()
pushData_SSEapi(f"Error | Token incorporation rejected at transaction {transaction_data['txid']} as token {parsed_data['tokenIdentification']} already exists") pushData_SSEapi(f"Error | Token incorporation rejected at transaction {transaction_data['txid']} as token {parsed_data['tokenIdentification']} already exists")
return 0 return 0
else:
logger.info(f"NFT incorporation at transaction {transaction_data['txid']} rejected as either the input address is part of a contract address")
session = create_database_session_orm('system_dbs', {'db_name': "system"}, Base)
blockchainReference = neturl + 'tx/' + transaction_data['txid']
session.add(RejectedTransactionHistory(tokenIdentification=parsed_data['tokenIdentification'],
sourceFloAddress=inputadd, destFloAddress=outputlist[0],
transferAmount=parsed_data['tokenAmount'],
blockNumber=transaction_data['blockheight'],
blockHash=transaction_data['blockhash'],
time=transaction_data['blocktime'],
transactionHash=transaction_data['txid'],
blockchainReference=blockchainReference,
jsonData=json.dumps(transaction_data),
rejectComment=f"NFT incorporation at transaction {transaction_data['txid']} rejected as either the input address is part of a contract address",
transactionType=parsed_data['type'],
parsedFloData=json.dumps(parsed_data)
))
session.commit()
session.close()
pushData_SSEapi(f"NFT incorporation at transaction {transaction_data['txid']} rejected as either the input address is part of a contract address")
return 0
elif parsed_data['type'] == 'infiniteTokenIncorporation': elif parsed_data['type'] == 'infiniteTokenIncorporation':
if not check_if_contract_address(inputlist[0]) and not check_if_contract_address(outputlist[0]):
if not check_database_existence('token', {'token_name':f"{parsed_data['tokenIdentification']}"}): if not check_database_existence('token', {'token_name':f"{parsed_data['tokenIdentification']}"}):
parsed_data['tokenAmount'] = 0 parsed_data['tokenAmount'] = 0
session = create_database_session_orm('token', {'token_name': f"{parsed_data['tokenIdentification']}"}, Base) session = create_database_session_orm('token', {'token_name': f"{parsed_data['tokenIdentification']}"}, Base)
@ -2518,9 +2951,27 @@ def processTransaction(transaction_data, parsed_data, blockinfo):
session.close() session.close()
pushData_SSEapi(f"Error | Token incorporation rejected at transaction {transaction_data['txid']} as token {parsed_data['tokenIdentification']} already exists") pushData_SSEapi(f"Error | Token incorporation rejected at transaction {transaction_data['txid']} as token {parsed_data['tokenIdentification']} already exists")
return 0 return 0
else:
logger.info(f"Infinite token incorporation at transaction {transaction_data['txid']} rejected as either the input address is part of a contract address")
''' {'type': 'smartContractDeposit', 'tokenIdentification': hashList[0][:-1], 'contractName': atList[0][:-1], 'flodata': string, 'depositConditions': deposit_conditions} ''' session = create_database_session_orm('system_dbs', {'db_name': "system"}, Base)
blockchainReference = neturl + 'tx/' + transaction_data['txid']
session.add(RejectedTransactionHistory(tokenIdentification=parsed_data['tokenIdentification'],
sourceFloAddress=inputadd, destFloAddress=outputlist[0],
transferAmount=parsed_data['tokenAmount'],
blockNumber=transaction_data['blockheight'],
blockHash=transaction_data['blockhash'],
time=transaction_data['blocktime'],
transactionHash=transaction_data['txid'],
blockchainReference=blockchainReference,
jsonData=json.dumps(transaction_data),
rejectComment=f"NFT incorporation at transaction {transaction_data['txid']} rejected as either the input address is part of a contract address",
transactionType=parsed_data['type'],
parsedFloData=json.dumps(parsed_data)
))
session.commit()
session.close()
pushData_SSEapi(f"Infinite token incorporation at transaction {transaction_data['txid']} rejected as either the input address is part of a contract address")
return 0
def scanBlockchain(): def scanBlockchain():
@ -2671,6 +3122,7 @@ if args.reset == 1:
session.commit() session.commit()
session.close() session.close()
# Determine API source for block and transaction information # Determine API source for block and transaction information
if __name__ == "__main__": if __name__ == "__main__":
# MAIN LOGIC STARTS # MAIN LOGIC STARTS