orderstate unload() bugfix
This commit is contained in:
@@ -30,7 +30,7 @@ datefmt='%Y-%m-%d %H:%M:%S'
|
|||||||
# Uncomment this block to enable an orders.log file that records only dexorder.order logs
|
# Uncomment this block to enable an orders.log file that records only dexorder.order logs
|
||||||
#
|
#
|
||||||
|
|
||||||
#[loggers.'dexorder.order']
|
#[loggers.'dexorder.order.log']
|
||||||
#level='DEBUG'
|
#level='DEBUG'
|
||||||
#handlers=['ordersfile',]
|
#handlers=['ordersfile',]
|
||||||
#propagate=true
|
#propagate=true
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from typing import Callable, Any
|
|||||||
|
|
||||||
from web3 import AsyncWeb3
|
from web3 import AsyncWeb3
|
||||||
|
|
||||||
order_log = logging.getLogger('dexorder.order')
|
order_log = logging.getLogger('dexorder.order.log')
|
||||||
|
|
||||||
dec = Decimal
|
dec = Decimal
|
||||||
def now():
|
def now():
|
||||||
|
|||||||
@@ -80,14 +80,9 @@ class BlockData (Generic[T]):
|
|||||||
used when lazy_getitem is set
|
used when lazy_getitem is set
|
||||||
"""
|
"""
|
||||||
assert self.lazy_getitem is not None
|
assert self.lazy_getitem is not None
|
||||||
try:
|
state = current_blockstate.get()
|
||||||
value = self.getitem(item)
|
fork = current_fork.get()
|
||||||
except KeyError:
|
state.unload(fork, self.series, item)
|
||||||
pass # no key exists to unload
|
|
||||||
else:
|
|
||||||
value = copy.deepcopy(value)
|
|
||||||
value.__dexorder_unload = True # mark value with magic attr
|
|
||||||
self.setitem(item, value)
|
|
||||||
|
|
||||||
def contains(self, item):
|
def contains(self, item):
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ class BlockState:
|
|||||||
# diffs_by_hash holds the diff items generated by each block
|
# diffs_by_hash holds the diff items generated by each block
|
||||||
self.diffs_by_hash: dict[bytes, list[DiffEntryItem]] = defaultdict(list)
|
self.diffs_by_hash: dict[bytes, list[DiffEntryItem]] = defaultdict(list)
|
||||||
self.ancestors: dict[bytes, Block] = {}
|
self.ancestors: dict[bytes, Block] = {}
|
||||||
|
self.unloads: dict[bytes, list] = defaultdict(list)
|
||||||
BlockState.by_chain[root_block.chain] = self
|
BlockState.by_chain[root_block.chain] = self
|
||||||
|
|
||||||
def add_block(self, block: Block) -> Optional[Fork]:
|
def add_block(self, block: Block) -> Optional[Fork]:
|
||||||
@@ -127,7 +128,7 @@ class BlockState:
|
|||||||
|
|
||||||
def _get_from_diffs(self, fork, diffs):
|
def _get_from_diffs(self, fork, diffs):
|
||||||
for diff in reversed(diffs):
|
for diff in reversed(diffs):
|
||||||
if diff.height <= self.root_block.height or fork is not None and diff in fork and not hasattr(diff.value, '__dexorder_unload'):
|
if diff.height <= self.root_block.height or fork is not None and diff in fork:
|
||||||
if diff.value is DELETE:
|
if diff.value is DELETE:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
@@ -146,6 +147,9 @@ class BlockState:
|
|||||||
self.diffs_by_hash[fork.hash].append(DiffEntryItem(series, key, diff))
|
self.diffs_by_hash[fork.hash].append(DiffEntryItem(series, key, diff))
|
||||||
diffs.add(diff)
|
diffs.add(diff)
|
||||||
|
|
||||||
|
def unload(self, fork: Optional[Fork], series, key):
|
||||||
|
self.unloads[fork.hash].append((series, key))
|
||||||
|
|
||||||
def iteritems(self, fork: Optional[Fork], series):
|
def iteritems(self, fork: Optional[Fork], series):
|
||||||
for k, difflist in self.diffs_by_series.get(series, {}).items():
|
for k, difflist in self.diffs_by_series.get(series, {}).items():
|
||||||
for diff in reversed(difflist):
|
for diff in reversed(difflist):
|
||||||
@@ -179,7 +183,6 @@ class BlockState:
|
|||||||
# walk the by_height list to delete any aged-out block data
|
# walk the by_height list to delete any aged-out block data
|
||||||
# in order to prune diffs_by_series, updated_keys remembers all the keys that were touched by any aged-out block
|
# in order to prune diffs_by_series, updated_keys remembers all the keys that were touched by any aged-out block
|
||||||
series_deletions = []
|
series_deletions = []
|
||||||
key_unloads: list[tuple[Any,Any]] = []
|
|
||||||
updated_keys = set()
|
updated_keys = set()
|
||||||
while self.by_height and self.by_height[0].height <= block.height:
|
while self.by_height and self.by_height[0].height <= block.height:
|
||||||
dead = self.by_height.pop(0)
|
dead = self.by_height.pop(0)
|
||||||
@@ -193,8 +196,6 @@ class BlockState:
|
|||||||
for d in block_diffs:
|
for d in block_diffs:
|
||||||
if d.key == BlockState._DELETE_SERIES_KEY and dead.hash in new_root_fork:
|
if d.key == BlockState._DELETE_SERIES_KEY and dead.hash in new_root_fork:
|
||||||
series_deletions.append(d.series)
|
series_deletions.append(d.series)
|
||||||
elif hasattr(d.value, '__dexorder_unload') and dead in new_root_fork:
|
|
||||||
key_unloads.append((d.series, d.key))
|
|
||||||
else:
|
else:
|
||||||
updated_keys.add((d.series, d.key))
|
updated_keys.add((d.series, d.key))
|
||||||
del self.diffs_by_hash[dead.hash]
|
del self.diffs_by_hash[dead.hash]
|
||||||
@@ -223,6 +224,8 @@ class BlockState:
|
|||||||
# if only one diff remains, and it's old, and it's a delete, then we can actually delete the diff list
|
# if only one diff remains, and it's old, and it's a delete, then we can actually delete the diff list
|
||||||
if not difflist or len(difflist) == 1 and difflist[0].value == DELETE and difflist[0].height <= new_root_fork.height:
|
if not difflist or len(difflist) == 1 and difflist[0].value == DELETE and difflist[0].height <= new_root_fork.height:
|
||||||
del self.diffs_by_series[s][k]
|
del self.diffs_by_series[s][k]
|
||||||
|
if block.hash in self.unloads:
|
||||||
|
key_unloads = self.unloads.pop(block.hash)
|
||||||
for s,k in key_unloads:
|
for s,k in key_unloads:
|
||||||
try:
|
try:
|
||||||
del self.diffs_by_series[s][k]
|
del self.diffs_by_series[s][k]
|
||||||
|
|||||||
@@ -188,6 +188,7 @@ class Order:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def pub_order_status(_s, k, v):
|
def pub_order_status(_s, k, v):
|
||||||
|
log.debug(f'pub order status {_s} {k} {v}')
|
||||||
# publish status updates (on placing and completion) to web clients
|
# publish status updates (on placing and completion) to web clients
|
||||||
try:
|
try:
|
||||||
chain_id = current_chain.get().chain_id
|
chain_id = current_chain.get().chain_id
|
||||||
|
|||||||
Reference in New Issue
Block a user