async def record_trade(event_name, event): logger = logging.getLogger("contract_events") insert_statement = """INSERT INTO trades ( "block_number", "transaction_hash", "log_index", "token_give", "amount_give", "token_get", "amount_get", "addr_give", "addr_get", "date" ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) ON CONFLICT ON CONSTRAINT index_trades_on_event_identifier DO NOTHING;""" insert_args = (event["blockNumber"] if isinstance(event["blockNumber"], int) else Web3.toInt( hexstr=event["blockNumber"]), Web3.toBytes(hexstr=event["transactionHash"]), event["logIndex"] if isinstance(event["logIndex"], int) else Web3.toInt(hexstr=event["logIndex"]), Web3.toBytes(hexstr=event["args"]["tokenGive"]), event["args"]["amountGive"], Web3.toBytes(hexstr=event["args"]["tokenGet"]), event["args"]["amountGet"], Web3.toBytes(hexstr=event["args"]["give"]), Web3.toBytes(hexstr=event["args"]["get"]), datetime.fromtimestamp(block_timestamp( App().web3, event["blockNumber"]), tz=None)) async with App().db.acquire_connection() as connection: await connection.execute(insert_statement, *insert_args) logger.debug( "recorded trade txid=%s, logidx=%i", event["transactionHash"], event["logIndex"] if isinstance( event["logIndex"], int) else Web3.toInt(hexstr=event["logIndex"]))
async def record_transfer(transfer_direction, event): insert_statement = """ INSERT INTO transfers ( "block_number", "transaction_hash", "log_index", "direction", "token", "user", "amount", "balance_after", "date" ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) ON CONFLICT ON CONSTRAINT index_transfers_on_event_identifier DO NOTHING;""" insert_args = (event["blockNumber"] if isinstance(event["blockNumber"], int) else Web3.toInt( hexstr=event["blockNumber"]), Web3.toBytes(hexstr=event["transactionHash"]), event["logIndex"] if isinstance(event["logIndex"], int) else Web3.toInt(hexstr=event["logIndex"]), transfer_direction, Web3.toBytes(hexstr=event["args"]["token"]), Web3.toBytes(hexstr=event["args"]["user"]), event["args"]["amount"], event["args"]["balance"], datetime.fromtimestamp(block_timestamp( App().web3, event["blockNumber"]), tz=None)) async with App().db.acquire_connection() as connection: await connection.execute(insert_statement, *insert_args)
async def main(token_addr): async with App().db.acquire_connection() as conn: orders = await conn.fetch(SELECT_ORDERS_STMT, Web3.toBytes(hexstr=token_addr)) for order in orders: side = "buy" if order["token_give"] == ZERO_ADDR_BYTES else "sell" order_maker = order["user"] signature = make_order_hash( dict(tokenGet=Web3.toHex(order["token_get"]), amountGet=order["amount_get"], tokenGive=Web3.toHex(order["token_give"]), amountGive=order["amount_give"], expires=order["expires"], nonce=order["nonce"])) updated_at = datetime.fromtimestamp(block_timestamp( App().web3, "latest"), tz=None) amount_fill = contract.call().orderFills( order_maker, Web3.toBytes(hexstr=signature)) amount_available = contract.call(v).availableVolume( Web3.toHex(order["token_get"]), Web3.toInt(order["amount_get"]), Web3.toHex(order["token_give"]), Web3.toInt(order["amount_give"]), Web3.toInt(order["expires"]), Web3.toInt(order["nonce"]), Web3.toHex(order["user"]), order["v"], order["r"], order["s"]) print( "side={}, signature={}, amount={}, fill={}, available={}; amounts match={}" .format(side, signature, order["amount_get"], amount_fill, Decimal(amount_available), amount_fill + amount_available == order["amount_get"])) update_args = (amount_fill, updated_at, Web3.toBytes(hexstr=signature))
async def record_order(order): order_maker = order["user"] signature = make_order_hash(order) insert_args = (OrderSource.OFFCHAIN.name, Web3.toBytes(hexstr=signature), Web3.toBytes(hexstr=order["tokenGive"]), Decimal(order["amountGive"]), Web3.toBytes(hexstr=order["tokenGet"]), Decimal(order["amountGet"]), int(order["expires"]), int(order["nonce"]), Web3.toBytes(hexstr=order["user"]), OrderState.OPEN.name, int(order["v"]), Web3.toBytes(hexstr=order["r"]), Web3.toBytes(hexstr=order["s"]), datetime.utcnow()) async with App().db.acquire_connection() as connection: insert_retval = await connection.execute(INSERT_ORDER_STMT, *insert_args) _, _, did_insert = parse_insert_status(insert_retval) if did_insert: logger.info("recorded order signature=%s, user=%s, expires=%i", signature, order["user"], int(order["expires"])) updated_at = datetime.fromtimestamp(block_timestamp( App().web3, "latest"), tz=None) amount_fill = contract.call().orderFills( order_maker, Web3.toBytes(hexstr=signature)) update_args = (amount_fill, updated_at, Web3.toBytes(hexstr=signature)) async with App().db.acquire_connection() as conn: await conn.execute(UPDATE_ORDER_FILL_STMT, *update_args) logger.info("update order signature=%s fill=%i", signature, amount_fill) else: logger.debug("duplicate order signature=%s", signature)
def log_latency(event): block_ts = block_timestamp(App().web3, coerce_to_int(event["blockNumber"])) latency = time() - block_ts if latency < ACCEPTABLE_LATENCY: logger.debug("Received event with %is latency", latency) elif latency < 2 * ACCEPTABLE_LATENCY: logger.info("Received event with %is latency", latency) elif latency < 8 * ACCEPTABLE_LATENCY: logger.warn("Received event with %is latency", latency) else: logger.critical("Received event with %is latency", latency)