feat(relayer): цена закрытия из истории на момент экспирации — окно выбора времени закрыто
Проблема: handleClose брал getPrice() (текущую цену), поэтому игрок мог подождать выгодного момента и закрыть ставку тогда, когда ему надо (эксплуатировалось вживую: ставка висела open >2 мин после экспирации 15с). Решение (только шлюз, контракт не тронут): - src/priceHistory.ts (новый) — локальная история цены на встроенном node:sqlite (Node 22, без новых зависимостей). Запись только при изменении цены (~300 строк/сутки вместо 92k тиков), ретеншен 24ч, prune одним DELETE. - natsPrice: в PriceTick добавлено eventTime (время сделки у Binance) — источник истины по времени; ts не тронут. - config: SMART_PRICE_HISTORY_PATH (/app/data/price-history.db), SMART_PRICE_RETENTION_HOURS (24). - gateway: каждый тик пишется в историю; handleClose берёт history.priceAtOrBefore(expireTime*1000) — последняя цена НЕ ПОЗЖЕ экспирации. Отказ 400 'bet not expired yet' до экспирации, 400 на уже закрытую, 503 если истории нет (не выдумываем цену). - helm: env SMART_PRICE_HISTORY_PATH / SMART_PRICE_RETENTION_HOURS. - check.ts: 10 проверок истории, включая ключевую «НЕ отдаёт цену позже момента». Верификация: typecheck 0 ошибок; npm test 34/34; мутационная приёмка — подмена <= на >=/ASC роняет 4 проверки, снятие дедупа и смена ретеншена роняют свои. Живой стенд: exitPrice = цена на момент экспирации (9977000000), тогда как текущая цена в момент клика была 9976000000 — взята история, не 'сейчас'.
This commit is contained in:
@@ -26,6 +26,8 @@ smart:
|
||||
multiplierBps: 13000
|
||||
expirySeconds: 15
|
||||
startBalance: 10000000000
|
||||
priceHistory: '/app/data/price-history.db'
|
||||
priceRetentionHours: 24
|
||||
|
||||
nats:
|
||||
url: 'nats://192.168.88.93:4222'
|
||||
|
||||
Reference in New Issue
Block a user