From f67e59916a64967d8beb297080761b30aa6db111 Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 28 Mar 2024 22:44:40 -0400 Subject: [PATCH] order completion fixes --- .gitignore | 1 + src/dexorder/__init__.py | 3 +++ src/dexorder/bin/mirror.py | 5 +++++ src/dexorder/event_handler.py | 8 +++++--- src/dexorder/order/orderstate.py | 6 +++++- src/dexorder/order/triggers.py | 29 +++++++++++------------------ 6 files changed, 30 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index cc0926a..9a5cd72 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ __pycache__ .vscode ohlc/ /metadata.json +orders.log diff --git a/src/dexorder/__init__.py b/src/dexorder/__init__.py index e9c652d..32055b3 100644 --- a/src/dexorder/__init__.py +++ b/src/dexorder/__init__.py @@ -1,3 +1,4 @@ +import logging # noinspection PyPackageRequirements from contextvars import ContextVar from datetime import datetime, timezone @@ -6,6 +7,8 @@ from typing import Callable, Any from web3 import AsyncWeb3 +order_log = logging.getLogger('dexorder.order') + dec = Decimal def now(): return datetime.now(timezone.utc) diff --git a/src/dexorder/bin/mirror.py b/src/dexorder/bin/mirror.py index 14fb2cc..99f3cf3 100644 --- a/src/dexorder/bin/mirror.py +++ b/src/dexorder/bin/mirror.py @@ -83,6 +83,11 @@ async def get_pool_info( pool ): t0, t1 = await asyncio.gather(p.token0(), p.token1()) amount0, amount1, (price,*_), fee = \ await asyncio.gather(ERC20(t0).balanceOf(pool), ERC20(t1).balanceOf(pool), p.slot0(), p.fee()) + + token0 = await get_token(t0) + token1 = await get_token(t1) + log.debug(f'pool has {amount0/10**token0["decimals"]} {token0["name"]} and {amount1/10**token1["decimals"]} {token1["name"]}') + return [pool, t0, t1, fee, price, amount0, amount1] async def write_metadata( pools, mirror_pools ): diff --git a/src/dexorder/event_handler.py b/src/dexorder/event_handler.py index 6f48c70..2c770fc 100644 --- a/src/dexorder/event_handler.py +++ b/src/dexorder/event_handler.py @@ -85,9 +85,10 @@ def handle_swap_filled(event: EventData): return try: triggers = OrderTriggers.instances[order.key] - triggers.fill(tranche_index, amount_in, amount_out) except KeyError: log.warning(f'No order triggers for fill of {TrancheKey(order.key.vault, order.key.order_index, tranche_index)}') + else: + triggers.fill(tranche_index, amount_in, amount_out) async def handle_order_canceled(event: EventData): # event DexorderCanceled (uint64 orderIndex); @@ -212,7 +213,8 @@ async def process_active_tranches(): if await has_funds(tk): log.info(f'execution request for {tk}') execution_requests[tk] = ExecutionRequest(height, proof) - else: log.debug(f'underfunded tranche {tk}') + else: + log.debug(f'underfunded tranche {tk}') async def has_funds(tk: TrancheKey): @@ -227,7 +229,7 @@ async def has_funds(tk: TrancheKey): token_balance = balances[token_addr] = await ERC20(token_addr).balanceOf(tk.vault) log.debug(f'queried token balance {token_addr}.balanceOf({tk.vault}) = {token_balance}') await adjust_balance(tk.vault, token_addr, token_balance) - # log.debug(f'minimum {minimum} balances {balances}') + # log.debug(f'minimum {minimum} balances {token_addr} {balances}') return token_balance > minimum diff --git a/src/dexorder/order/orderstate.py b/src/dexorder/order/orderstate.py index 20b7cbd..43779f2 100644 --- a/src/dexorder/order/orderstate.py +++ b/src/dexorder/order/orderstate.py @@ -3,7 +3,7 @@ import logging from dataclasses import dataclass from typing import overload -from dexorder import DELETE, db +from dexorder import DELETE, db, order_log from dexorder.base.chain import current_chain from dexorder.base.order import OrderKey, TrancheKey from dexorder.base.orderlib import SwapOrderStatus, SwapOrderState @@ -88,6 +88,7 @@ class Order: # Start with a filled value of 0 even if the chain says otherwise, because we will process the fill events later and add them in tranche_filled = [Filled(0,0) for _ in range(len(status.trancheFilledIn))] Order.order_filled[key] = OrderFilled(Filled(0,0), tranche_filled) + order_log.debug(f'order created {key}') return order @overload @@ -154,12 +155,14 @@ class Order: def add_fill(self, tranche_index: int, filled_in: int, filled_out: int): + order_log.debug(f'tranche fill {self.key}|{tranche_index} in:{filled_in} out:{filled_out}') old = Order.order_filled[self.key] new = copy.deepcopy(old) new.filled.filled_in += filled_in new.filled.filled_out += filled_out new.tranche_filled[tranche_index].filled_in += filled_in new.tranche_filled[tranche_index].filled_out += filled_out + order_log.debug(f'post-fill order: {new}') Order.order_filled[self.key] = new @@ -181,6 +184,7 @@ class Order: status.trancheFilledOut[i] += of.tranche_filled[i].filled_out Order.order_statuses[self.key] = status # set the status in order to save it Order.order_statuses.unload(self.key) # but then unload from memory after root promotion + order_log.debug(f'order completed {status}') @staticmethod def pub_order_status(_s, k, v): diff --git a/src/dexorder/order/triggers.py b/src/dexorder/order/triggers.py index e560ad2..b23aeb0 100644 --- a/src/dexorder/order/triggers.py +++ b/src/dexorder/order/triggers.py @@ -8,7 +8,7 @@ from dexorder.blockstate import BlockSet, BlockDict from dexorder.base.orderlib import SwapOrderState, PriceProof, DISTANT_FUTURE, DISTANT_PAST from dexorder.util import defaultdictk from .orderstate import Order -from .. import dec +from .. import dec, order_log from ..base.chain import current_clock from ..base.order import OrderKey, TrancheKey, ExecutionRequest from ..pools import ensure_pool_price, pool_prices, get_pool @@ -73,7 +73,7 @@ class TrancheTrigger: assert order.key.vault == tranche_key.vault and order.key.order_index == tranche_key.order_index self.order = order self.tk = tranche_key - self._status = TrancheStatus.Early + self.status = TrancheStatus.Early tranche = order.order.tranches[self.tk.tranche_index] tranche_amount = tranche.fraction_of(order.amount) @@ -97,28 +97,18 @@ class TrancheTrigger: # compute status and set relevant triggers if tranche_remaining == 0 or tranche_remaining < self.order.min_fill_amount: # min_fill_amount could be 0 (disabled) so we also check for the 0 case separately - self._status = TrancheStatus.Filled + self.status = TrancheStatus.Filled return timestamp = current_clock.get().timestamp - self._status = \ + self.status = \ TrancheStatus.Pricing if self.time_constraint is None else \ TrancheStatus.Early if timestamp < self.time_constraint[0] else \ TrancheStatus.Expired if timestamp > self.time_constraint[1] else \ TrancheStatus.Pricing self.enable_time_trigger() - if self._status == TrancheStatus.Pricing: + if self.status == TrancheStatus.Pricing: self.enable_price_trigger() - @property - def status(self): - return self._status - - @status.setter - def status(self, value): - self._status = value - if value in (TrancheStatus.Filled, TrancheStatus.Expired): - OrderTriggers.instances[self.order.key].check_complete() - def enable_time_trigger(self): if self.time_constraint: log.debug(f'enable_time_trigger') @@ -134,11 +124,11 @@ class TrancheTrigger: log.debug(f'price trigger ignored because trigger status is {self.status}') return if now >= self.time_constraint[1]: - log.debug(f'tranche expired {self.tk}') + order_log.debug(f'tranche expired {self.tk}') self.status = TrancheStatus.Expired self.disable() elif self.status == TrancheStatus.Early and now >= self.time_constraint[0]: - log.debug(f'tranche time enabled {self.tk}') + order_log.debug(f'tranche time enabled {self.tk}') self.status = TrancheStatus.Pricing self.enable_price_trigger() @@ -180,9 +170,11 @@ class TrancheTrigger: remaining = self.order.tranche_remaining(self.tk.tranche_index) filled = remaining == 0 or remaining < self.order.min_fill_amount if filled: - log.debug(f'tranche filled {self.tk}') + order_log.debug(f'tranche filled {self.tk}') self.status = TrancheStatus.Filled self.disable() + else: + order_log.debug(f'tranche part-filled {self.tk} in:{_amount_in} out:{_amount_out} remaining:{remaining}') return filled def disable(self): @@ -216,6 +208,7 @@ class OrderTriggers: for t in self.triggers: t.disable() del OrderTriggers.instances[self.order.key] + log.debug(f'disabled OrderTriggers for {self.order.key}') @property def closed(self):