2021-02-18 06:04:30 +01:00
# standard imports
import logging
import datetime
2021-05-01 15:20:14 +02:00
# external imports
2021-02-18 06:04:30 +01:00
from cic_cache . db . models . base import SessionBase
2021-05-01 15:20:14 +02:00
from sqlalchemy import text
2021-02-18 06:04:30 +01:00
logg = logging . getLogger ( )
def list_transactions_mined (
session ,
offset ,
limit ,
) :
""" Executes db query to return all confirmed transactions according to the specified offset and limit.
: param offset : Offset in data set to return transactions from
: type offset : int
: param limit : Max number of transactions to retrieve
: type limit : int
: result : Result set
: rtype : SQLAlchemy . ResultProxy
"""
s = " SELECT block_number, tx_index FROM tx ORDER BY block_number DESC, tx_index DESC LIMIT {} OFFSET {} " . format ( limit , offset )
r = session . execute ( s )
return r
2021-05-18 19:13:57 +02:00
def list_transactions_mined_with_data (
session ,
offset ,
end ,
) :
""" Executes db query to return all confirmed transactions according to the specified offset and limit.
: param offset : Offset in data set to return transactions from
: type offset : int
: param limit : Max number of transactions to retrieve
: type limit : int
: result : Result set
: rtype : SQLAlchemy . ResultProxy
"""
2021-05-19 16:47:22 +02:00
s = " SELECT tx_hash, block_number, date_block, sender, recipient, from_value, to_value, source_token, destination_token, success, domain, value FROM tx LEFT JOIN tag_tx_link ON tx.id = tag_tx_link.tx_id LEFT JOIN tag ON tag_tx_link.tag_id = tag.id WHERE block_number >= {} AND block_number <= {} ORDER BY block_number ASC, tx_index ASC " . format ( offset , end )
2021-05-18 19:13:57 +02:00
r = session . execute ( s )
return r
2021-02-18 06:04:30 +01:00
def list_transactions_account_mined (
session ,
address ,
offset ,
limit ,
) :
""" Same as list_transactions_mined(...), but only retrieves transaction where the specified account address is sender or recipient.
: param address : Address to retrieve transactions for .
: type address : str , 0 x - hex
: param offset : Offset in data set to return transactions from
: type offset : int
: param limit : Max number of transactions to retrieve
: type limit : int
: result : Result set
: rtype : SQLAlchemy . ResultProxy
"""
s = " SELECT block_number, tx_index FROM tx WHERE sender = ' {} ' OR recipient = ' {} ' ORDER BY block_number DESC, tx_index DESC LIMIT {} OFFSET {} " . format ( address , address , limit , offset )
r = session . execute ( s )
return r
def add_transaction (
2021-05-01 15:20:14 +02:00
session ,
tx_hash ,
2021-02-18 06:04:30 +01:00
block_number ,
tx_index ,
sender ,
receiver ,
source_token ,
destination_token ,
from_value ,
to_value ,
success ,
timestamp ,
) :
2021-05-01 15:20:14 +02:00
""" Adds a single transaction to the cache persistent storage. Sensible interpretation of all fields is the responsibility of the caller.
: param session : Persistent storage session object
: type session : SQLAlchemy session
: param tx_hash : Transaction hash
: type tx_hash : str , 0 x - hex
: param block_number : Block number
: type block_number : int
: param tx_index : Transaction index in block
: type tx_index : int
: param sender : Ethereum address of effective sender
: type sender : str , 0 x - hex
: param receiver : Ethereum address of effective recipient
: type receiver : str , 0 x - hex
: param source_token : Ethereum address of token used by sender
: type source_token : str , 0 x - hex
: param destination_token : Ethereum address of token received by recipient
: type destination_token : str , 0 x - hex
: param from_value : Source token value spent in transaction
: type from_value : int
: param to_value : Destination token value received in transaction
: type to_value : int
: param success : True if code execution on network was successful
: type success : bool
: param date_block : Block timestamp
: type date_block : datetime
"""
2021-02-18 06:04:30 +01:00
date_block = datetime . datetime . fromtimestamp ( timestamp )
s = " INSERT INTO tx (tx_hash, block_number, tx_index, sender, recipient, source_token, destination_token, from_value, to_value, success, date_block) VALUES ( ' {} ' , {} , {} , ' {} ' , ' {} ' , ' {} ' , ' {} ' , {} , {} , {} , ' {} ' ) " . format (
tx_hash ,
block_number ,
tx_index ,
sender ,
receiver ,
source_token ,
destination_token ,
from_value ,
to_value ,
success ,
date_block ,
)
session . execute ( s )
2021-05-01 15:20:14 +02:00
def tag_transaction (
session ,
tx_hash ,
name ,
domain = None ,
) :
""" Tag a single transaction with a single tag.
Tag must already exist in storage .
: param session : Persistent storage session object
: type session : SQLAlchemy session
: param tx_hash : Transaction hash
: type tx_hash : str , 0 x - hex
: param name : Tag value
: type name : str
: param domain : Tag domain
: type domain : str
: raises ValueError : Unknown tag or transaction hash
"""
s = text ( " SELECT id from tx where tx_hash = :a " )
r = session . execute ( s , { ' a ' : tx_hash } ) . fetchall ( )
tx_id = r [ 0 ] . values ( ) [ 0 ]
if tx_id == None :
raise ValueError ( ' unknown tx hash {} ' . format ( tx_hash ) )
#s = text("SELECT id from tag where value = :a and domain = :b")
if domain == None :
s = text ( " SELECT id from tag where value = :a " )
else :
s = text ( " SELECT id from tag where value = :a and domain = :b " )
r = session . execute ( s , { ' a ' : name , ' b ' : domain } ) . fetchall ( )
tag_id = r [ 0 ] . values ( ) [ 0 ]
logg . debug ( ' type {} {} ' . format ( type ( tag_id ) , type ( tx_id ) ) )
if tag_id == None :
raise ValueError ( ' unknown tag name {} domain {} ' . format ( name , domain ) )
s = text ( " INSERT INTO tag_tx_link (tag_id, tx_id) VALUES (:a, :b) " )
r = session . execute ( s , { ' a ' : int ( tag_id ) , ' b ' : int ( tx_id ) } )
def add_tag (
session ,
name ,
domain = None ,
) :
""" Add a single tag to storage.
: param session : Persistent storage session object
: type session : SQLAlchemy session
: param name : Tag value
: type name : str
: param domain : Tag domain
: type domain : str
: raises sqlalchemy . exc . IntegrityError : Tag already exists
"""
s = None
if domain == None :
s = text ( " INSERT INTO tag (value) VALUES (:b) " )
else :
s = text ( " INSERT INTO tag (domain, value) VALUES (:a, :b) " )
session . execute ( s , { ' a ' : domain , ' b ' : name } )