dexbot 1.4.3 → 1.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/modules/dexbot_cow_runtime.d.ts +30 -0
  2. package/dist/modules/dexbot_cow_runtime.d.ts.map +1 -1
  3. package/dist/modules/dexbot_cow_runtime.js +192 -0
  4. package/dist/modules/dexbot_cow_runtime.js.map +1 -1
  5. package/dist/modules/dexbot_maintenance_runtime.d.ts.map +1 -1
  6. package/dist/modules/dexbot_maintenance_runtime.js +32 -25
  7. package/dist/modules/dexbot_maintenance_runtime.js.map +1 -1
  8. package/dist/modules/order/accounting.d.ts +2 -2
  9. package/dist/modules/order/accounting.d.ts.map +1 -1
  10. package/dist/modules/order/accounting.js +3 -6
  11. package/dist/modules/order/accounting.js.map +1 -1
  12. package/dist/modules/order/async_lock.d.ts +7 -0
  13. package/dist/modules/order/async_lock.d.ts.map +1 -1
  14. package/dist/modules/order/async_lock.js +31 -1
  15. package/dist/modules/order/async_lock.js.map +1 -1
  16. package/dist/modules/order/grid.d.ts +3 -11
  17. package/dist/modules/order/grid.d.ts.map +1 -1
  18. package/dist/modules/order/grid.js +70 -98
  19. package/dist/modules/order/grid.js.map +1 -1
  20. package/dist/modules/order/grid_reconcile.d.ts +3 -9
  21. package/dist/modules/order/grid_reconcile.d.ts.map +1 -1
  22. package/dist/modules/order/grid_reconcile.js +80 -48
  23. package/dist/modules/order/grid_reconcile.js.map +1 -1
  24. package/dist/modules/order/grid_reconcile_internal.d.ts.map +1 -1
  25. package/dist/modules/order/grid_reconcile_internal.js +29 -1
  26. package/dist/modules/order/grid_reconcile_internal.js.map +1 -1
  27. package/dist/modules/order/manager.d.ts +38 -7
  28. package/dist/modules/order/manager.d.ts.map +1 -1
  29. package/dist/modules/order/manager.js +99 -123
  30. package/dist/modules/order/manager.js.map +1 -1
  31. package/dist/modules/order/strategy.js +0 -1
  32. package/dist/modules/order/strategy.js.map +1 -1
  33. package/dist/modules/order/sync_engine.d.ts.map +1 -1
  34. package/dist/modules/order/sync_engine.js +1 -2
  35. package/dist/modules/order/sync_engine.js.map +1 -1
  36. package/dist/modules/order/utils/math.d.ts +26 -1
  37. package/dist/modules/order/utils/math.d.ts.map +1 -1
  38. package/dist/modules/order/utils/math.js +91 -53
  39. package/dist/modules/order/utils/math.js.map +1 -1
  40. package/dist/modules/order/utils/order.d.ts.map +1 -1
  41. package/dist/modules/order/utils/order.js +10 -20
  42. package/dist/modules/order/utils/order.js.map +1 -1
  43. package/dist/modules/order/utils/system.d.ts +9 -3
  44. package/dist/modules/order/utils/system.d.ts.map +1 -1
  45. package/dist/modules/order/utils/system.js +31 -67
  46. package/dist/modules/order/utils/system.js.map +1 -1
  47. package/dist/modules/order/utils/validate.js +1 -1
  48. package/dist/modules/order/utils/validate.js.map +1 -1
  49. package/package.json +1 -1
@@ -102,6 +102,7 @@ declare class AsyncLock {
102
102
  private _defaultTimeout;
103
103
  private _onContention;
104
104
  private readonly _lockId;
105
+ private _orphaned;
105
106
  constructor(options?: AsyncLockOptions);
106
107
  /**
107
108
  * Acquire the lock and execute callback exclusively
@@ -156,6 +157,12 @@ declare class AsyncLock {
156
157
  * stale callback from interfering with a new acquirer that claimed
157
158
  * the lock after forceRelease.
158
159
  *
160
+ * CONCURRENT EXECUTION GUARD: If a callback is currently executing
161
+ * (_holding is true), forceRelease defers _locked = false to the
162
+ * stale callback's finally block via the _orphaned flag. This
163
+ * prevents a new acquirer from entering while the stale callback
164
+ * is still running, preserving mutual exclusion.
165
+ *
159
166
  * @returns {number} Count of cleared items
160
167
  */
161
168
  forceRelease(): number;
@@ -1 +1 @@
1
- {"version":3,"file":"async_lock.d.ts","sourceRoot":"","sources":["../../../modules/order/async_lock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkFG;AAaH,UAAU,gBAAgB;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B;AAED,UAAU,cAAc;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE;QAAE,WAAW,EAAE,OAAO,CAAA;KAAE,CAAC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B;AAeD,cAAM,SAAS;IACX,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,QAAQ,CAAU;IAC1B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,eAAe,CAAgB;IACvC,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,OAAO,GAAE,gBAAqB;IAU1C;;;;;;;OAOG;IACG,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,CAAC,CAAC;IAmEtF;;;OAGG;YACW,aAAa;IAiD3B;;;OAGG;IACH,QAAQ,IAAI,OAAO;IAInB;;;;OAIG;IACH,WAAW,IAAI,OAAO;IAOtB;;;OAGG;IACH,cAAc,IAAI,MAAM;IAIxB;;;;OAIG;IACH,UAAU,IAAI,MAAM;IASpB;;;;;;;;;;;;;;;;;;OAkBG;IACH,YAAY,IAAI,MAAM;CAezB;AAED,eAAe,SAAS,CAAA"}
1
+ {"version":3,"file":"async_lock.d.ts","sourceRoot":"","sources":["../../../modules/order/async_lock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkFG;AAaH,UAAU,gBAAgB;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B;AAED,UAAU,cAAc;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE;QAAE,WAAW,EAAE,OAAO,CAAA;KAAE,CAAC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B;AAeD,cAAM,SAAS;IACX,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,QAAQ,CAAU;IAC1B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,eAAe,CAAgB;IACvC,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,SAAS,CAAU;gBAEf,OAAO,GAAE,gBAAqB;IAW1C;;;;;;;OAOG;IACG,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,CAAC,CAAC;IAmEtF;;;OAGG;YACW,aAAa;IA2D3B;;;OAGG;IACH,QAAQ,IAAI,OAAO;IAInB;;;;OAIG;IACH,WAAW,IAAI,OAAO;IAOtB;;;OAGG;IACH,cAAc,IAAI,MAAM;IAIxB;;;;OAIG;IACH,UAAU,IAAI,MAAM;IASpB;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,YAAY,IAAI,MAAM;CAyBzB;AAED,eAAe,SAAS,CAAA"}
@@ -106,6 +106,7 @@ class AsyncLock {
106
106
  _defaultTimeout;
107
107
  _onContention;
108
108
  _lockId;
109
+ _orphaned;
109
110
  constructor(options = {}) {
110
111
  this._queue = [];
111
112
  this._locked = false;
@@ -114,6 +115,7 @@ class AsyncLock {
114
115
  this._defaultTimeout = options.timeout || null;
115
116
  this._onContention = options.onContention || null;
116
117
  this._lockId = Symbol('AsyncLock');
118
+ this._orphaned = false;
117
119
  }
118
120
  /**
119
121
  * Acquire the lock and execute callback exclusively
@@ -223,6 +225,17 @@ class AsyncLock {
223
225
  this._locked = false;
224
226
  this._processQueue();
225
227
  }
228
+ else if (this._orphaned) {
229
+ // Stale callback finishing after forceRelease. The
230
+ // forceRelease deferred _locked = false to us via the
231
+ // _orphaned flag. Release the lock so queued callbacks
232
+ // can proceed. This prevents concurrent execution: the
233
+ // stale callback continues to hold _locked until it
234
+ // finishes, blocking any new acquirer.
235
+ this._orphaned = false;
236
+ this._locked = false;
237
+ this._processQueue();
238
+ }
226
239
  // After a callback completes, if there are still queued items
227
240
  // (but the previous _locked=false path already called
228
241
  // _processQueue which started the next one), check whether
@@ -288,6 +301,12 @@ class AsyncLock {
288
301
  * stale callback from interfering with a new acquirer that claimed
289
302
  * the lock after forceRelease.
290
303
  *
304
+ * CONCURRENT EXECUTION GUARD: If a callback is currently executing
305
+ * (_holding is true), forceRelease defers _locked = false to the
306
+ * stale callback's finally block via the _orphaned flag. This
307
+ * prevents a new acquirer from entering while the stale callback
308
+ * is still running, preserving mutual exclusion.
309
+ *
291
310
  * @returns {number} Count of cleared items
292
311
  */
293
312
  forceRelease() {
@@ -296,6 +315,7 @@ class AsyncLock {
296
315
  // finally block — it will see generation mismatch and skip
297
316
  // touching _locked / _processQueue.
298
317
  this._generation++;
318
+ const wasHolding = this._holding;
299
319
  this._holding = false;
300
320
  while (this._queue.length > 0) {
301
321
  const { reject, timer } = this._queue.shift();
@@ -303,7 +323,17 @@ class AsyncLock {
303
323
  clearTimeout(timer);
304
324
  reject(new Error('Lock force-released'));
305
325
  }
306
- this._locked = false;
326
+ if (wasHolding) {
327
+ // A callback is currently executing — defer lock release to
328
+ // the stale callback's finally block, which detects the
329
+ // orphan state via generation mismatch + _orphaned flag and
330
+ // releases _locked when done. This prevents concurrent
331
+ // execution between the stale callback and a new acquirer.
332
+ this._orphaned = true;
333
+ }
334
+ else {
335
+ this._locked = false;
336
+ }
307
337
  return count;
308
338
  }
309
339
  }
@@ -1 +1 @@
1
- {"version":3,"file":"async_lock.js","sourceRoot":"","sources":["../../../modules/order/async_lock.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"async_lock.js","sourceRoot":"","sources":["../../../modules/order/async_lock.ts"],"names":[],"mappings":"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"}
@@ -65,9 +65,8 @@
65
65
  * 21. getDustOrders(manager, partials, side) - Get all dust order IDs (public)
66
66
  * 22. determineOrderSideByFunds(manager, currentMarketPrice) - Determine priority side
67
67
  *
68
- * SPREAD CORRECTION (2 methods)
69
- * 23. calculateGeometricSizeForSpreadCorrection(manager, targetType) - Calculate correction size
70
- * 24. prepareSpreadCorrectionOrders(manager, preferredSide) - Prepare correction orders
68
+ * SPREAD CORRECTION (1 method)
69
+ * 23. prepareSpreadCorrectionOrders(manager, preferredSide) - Prepare correction orders
71
70
  *
72
71
  * DUST DETECTION (1 method - internal)
73
72
  * 25. _getDustOrders(manager, partials, type) - Internal dust detection helper
@@ -431,13 +430,6 @@ export declare function getDustOrders(manager: any, partials: any, side: any): P
431
430
  * @returns {{ side: import('./types').OrderType|null, reason: string }} The side to correct on, or null if insufficient funds.
432
431
  */
433
432
  export declare function determineOrderSideByFunds(manager: any, currentMarketPrice: any): any;
434
- /**
435
- * Calculate the geometric ideal size for a new order being placed during spread correction.
436
- * @param {import('./types').OrderManager} manager - The manager instance.
437
- * @param {import('./types').OrderType} targetType - The type of order being placed (ORDER_TYPES.BUY or ORDER_TYPES.SELL).
438
- * @returns {Promise<number|null>} The calculated geometric size.
439
- */
440
- export declare function calculateGeometricSizeForSpreadCorrection(manager: any, targetType: any): Promise<any>;
441
433
  /**
442
434
  * Prepares one or more orders to correct a wide spread.
443
435
  * @param {import('./types').OrderManager} manager - The OrderManager instance.
@@ -445,5 +437,5 @@ export declare function calculateGeometricSizeForSpreadCorrection(manager: any,
445
437
  * @returns {Promise<import('./types').SpreadCorrectionResult>}
446
438
  * @throws {Error} If preferredSide is invalid.
447
439
  */
448
- export declare function prepareSpreadCorrectionOrders(manager: any, preferredSide: any): Promise<any>;
440
+ export declare function prepareSpreadCorrectionOrders(manager: any, preferredSide: any, outOfSpread?: number): Promise<any>;
449
441
  //# sourceMappingURL=grid.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"grid.d.ts","sourceRoot":"","sources":["../../../modules/order/grid.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"grid.d.ts","sourceRoot":"","sources":["../../../modules/order/grid.ts"],"names":[],"mappings":"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"}
@@ -66,9 +66,8 @@
66
66
  * 21. getDustOrders(manager, partials, side) - Get all dust order IDs (public)
67
67
  * 22. determineOrderSideByFunds(manager, currentMarketPrice) - Determine priority side
68
68
  *
69
- * SPREAD CORRECTION (2 methods)
70
- * 23. calculateGeometricSizeForSpreadCorrection(manager, targetType) - Calculate correction size
71
- * 24. prepareSpreadCorrectionOrders(manager, preferredSide) - Prepare correction orders
69
+ * SPREAD CORRECTION (1 method)
70
+ * 23. prepareSpreadCorrectionOrders(manager, preferredSide) - Prepare correction orders
72
71
  *
73
72
  * DUST DETECTION (1 method - internal)
74
73
  * 25. _getDustOrders(manager, partials, type) - Internal dust detection helper
@@ -151,7 +150,6 @@ exports.checkWindowDust = checkWindowDust;
151
150
  exports.hasAnyDust = hasAnyDust;
152
151
  exports.getDustOrders = getDustOrders;
153
152
  exports.determineOrderSideByFunds = determineOrderSideByFunds;
154
- exports.calculateGeometricSizeForSpreadCorrection = calculateGeometricSizeForSpreadCorrection;
155
153
  exports.prepareSpreadCorrectionOrders = prepareSpreadCorrectionOrders;
156
154
  const constants_1 = require("../constants");
157
155
  const { GRID_COMPARISON } = constants_1.GRID_LIMITS;
@@ -299,9 +297,10 @@ async function _getSizingContext(manager, side, { skipRecalc = false } = {}) {
299
297
  const targetBuy = Math.max(0, manager.config.activeOrders?.buy ?? 1);
300
298
  const targetSell = Math.max(0, manager.config.activeOrders?.sell ?? 1);
301
299
  const totalTarget = targetBuy + targetSell;
302
- const isBtsSide = (isBuy && manager.config.assetB === 'BTS') || (!isBuy && manager.config.assetA === 'BTS');
300
+ const btsOrderType = (0, math_1.getBtsSide)(manager.config?.assetA, manager.config?.assetB);
301
+ const isBtsSide = isBuy ? (btsOrderType === constants_1.ORDER_TYPES.BUY) : (btsOrderType === constants_1.ORDER_TYPES.SELL);
303
302
  const formulaBudget = (0, math_1.calculateOrderCreationFees)(manager.config.assetA, manager.config.assetB, totalTarget, manager.config?.feeParams?.BTS_RESERVATION_MULTIPLIER);
304
- budget = (0, order_1.adjustBudgetForBtsFees)(budget, isBtsSide, formulaBudget, manager.config.min_BTS_value || 0, Format.toFiniteNumber(manager.funds?.btsBalance?.free, 0), Format.toFiniteNumber(isBuy ? (snap.allocatedBuy || 0) : (snap.allocatedSell || 0)), Format.toFiniteNumber(snap.allocatedBuy || 0)
303
+ budget = (0, math_1.adjustBudgetForBtsFees)(budget, isBtsSide, formulaBudget, manager.config.min_BTS_value || 0, Format.toFiniteNumber(manager.funds?.btsBalance?.free, 0), Format.toFiniteNumber(isBuy ? (snap.allocatedBuy || 0) : (snap.allocatedSell || 0)), Format.toFiniteNumber(snap.allocatedBuy || 0)
305
304
  + Format.toFiniteNumber(snap.allocatedSell || 0));
306
305
  }
307
306
  return {
@@ -476,17 +475,6 @@ function createOrderGrid(config) {
476
475
  function _clearOrderCachesLogic(manager) {
477
476
  // Replace frozen master grid with fresh empty frozen Map (COW pattern)
478
477
  manager.orders = Object.freeze(new Map());
479
- // Clear index Sets with fresh empty Sets (mutable for _applyOrderUpdate)
480
- if (manager._ordersByState) {
481
- for (const key of Object.keys(manager._ordersByState)) {
482
- manager._ordersByState[key] = new Set();
483
- }
484
- }
485
- if (manager._ordersByType) {
486
- for (const key of Object.keys(manager._ordersByType)) {
487
- manager._ordersByType[key] = new Set();
488
- }
489
- }
490
478
  }
491
479
  /**
492
480
  * Restore a persisted grid snapshot onto a manager instance.
@@ -512,8 +500,7 @@ async function loadGrid(manager, grid, boundaryIdx = null) {
512
500
  manager.funds.btsFeesOwed = savedBtsFeesOwed;
513
501
  // Restore boundary index for StrategyEngine
514
502
  if (typeof boundaryIdx === 'number') {
515
- manager.boundaryIdx = boundaryIdx;
516
- // FIX: Use consistent optional chaining pattern for logger calls
503
+ manager._restoreBoundary(boundaryIdx);
517
504
  manager.logger?.log?.(`Restored boundary index: ${boundaryIdx}`, 'info');
518
505
  }
519
506
  // Reassign slot types for virtual slots based on current boundary.
@@ -523,7 +510,7 @@ async function loadGrid(manager, grid, boundaryIdx = null) {
523
510
  if (typeof boundaryIdx === 'number') {
524
511
  const gapSlots = calculateGapSlots(manager.config?.incrementPercent, manager.config?.targetSpreadPercent, manager.config?.gridLimits);
525
512
  const buyEndIdx = boundaryIdx;
526
- const sellStartIdx = boundaryIdx + gapSlots + 1;
513
+ const sellStartIdx = (0, math_1.getSellStartIdx)(boundaryIdx, gapSlots);
527
514
  let reassignCount = 0;
528
515
  grid = grid.map((slot, i) => {
529
516
  if (slot.state === constants_1.ORDER_STATES.VIRTUAL && !slot.orderId) {
@@ -799,7 +786,7 @@ async function initializeGrid(manager) {
799
786
  // RC-8: Update boundary with notification to dependent systems
800
787
  // Persist master boundary for StrategyEngine
801
788
  if (manager.boundaryIdx !== boundaryIdx) {
802
- manager.boundaryIdx = boundaryIdx;
789
+ manager._restoreBoundary(boundaryIdx);
803
790
  // RC-8: Notify StrategyEngine of boundary change (if method exists)
804
791
  if (typeof manager.notifyBoundaryUpdate === 'function') {
805
792
  try {
@@ -1184,6 +1171,12 @@ async function updateGridFromBlockchainSnapshot(manager, orderType = 'both', fro
1184
1171
  // included in the correct side's budget allocation. Running assignGridRoles
1185
1172
  // after the size calc means crossers keep their pre-shift sizes, producing
1186
1173
  // an allocation that doesn't match the post-shift grid structure.
1174
+ //
1175
+ // NOTE: syncBoundaryToFunds is a pure computation (no eager write), so
1176
+ // manager.boundaryIdx still carries the pre-shift value here. The
1177
+ // overrideBoundaryIdx !== manager.boundaryIdx check correctly detects
1178
+ // that a shift is needed. The boundary is only written atomically
1179
+ // inside _commitWorkingGrid via _setBoundary.
1187
1180
  if (overrideBoundaryIdx !== null && overrideBoundaryIdx !== manager.boundaryIdx) {
1188
1181
  const gapSlots = calculateGapSlots(manager.config.incrementPercent, manager.config.targetSpreadPercent, manager.config.gridLimits);
1189
1182
  const allSlots = Array.from(workingGrid.values())
@@ -1289,9 +1282,14 @@ async function compareGrids(calculatedGrid, persistedGrid, manager = null) {
1289
1282
  const computeSideIdeals = (activeOrders, type, ctx) => {
1290
1283
  if (!manager || !ctx || ctx.budget <= 0 || activeOrders.length === 0)
1291
1284
  return activeOrders;
1292
- // Identify ALL slots currently assigned to this side.
1293
- // Ideal sizing must use the full slot count to determine geometric share per slot.
1294
- const sideSlots = Array.from(manager.orders.values())
1285
+ // Identify ALL slots currently assigned to this side from the calculated
1286
+ // grid snapshot (not a fresh read from manager.orders). Using the snapshot
1287
+ // avoids TOCTOU races and ensures the slot classification is consistent with
1288
+ // the grid state used for the RMS computation. If a boundary shift is pending
1289
+ // (set via _gridSidesUpdated but not yet committed through the COW pipeline),
1290
+ // the types in manager.orders are stale — reading from the snapshot matches
1291
+ // what the rest of the comparison sees.
1292
+ const sideSlots = calculatedSnap
1295
1293
  .filter((o) => o.type === type)
1296
1294
  .sort((a, b) => (a.price ?? 0) - (b.price ?? 0));
1297
1295
  if (sideSlots.length === 0)
@@ -1438,6 +1436,10 @@ async function checkSpreadCondition(manager, _BitShares, updateOrdersOnChainBatc
1438
1436
  // This prevents concurrent fill processing from modifying funds while we're making decisions
1439
1437
  let correction = null;
1440
1438
  let shouldApplyCorrection = false;
1439
+ if (!manager._gridLock) {
1440
+ manager.logger?.log?.('Spread check skipped: no grid lock available', 'warn');
1441
+ return { ordersPlaced: 0, partialsMoved: 0 };
1442
+ }
1441
1443
  // Derive current market price from the bot's own grid (no blockchain call needed).
1442
1444
  // Grid prices are in B/A format (e.g. BTS/XRP) so no inversion is required.
1443
1445
  // Mid between best bid and best ask is the most current price the bot has.
@@ -1447,7 +1449,7 @@ async function checkSpreadCondition(manager, _BitShares, updateOrdersOnChainBatc
1447
1449
  const lastPrice = (bestBuy !== null && bestSell !== null)
1448
1450
  ? (bestBuy + bestSell) / 2
1449
1451
  : Number(manager.config.startPrice) || 0;
1450
- // FIX: Use optional chaining for lock - if no lock exists, execute synchronously
1452
+ // Lock guard is handled at function entry — if _gridLock is absent we return early.
1451
1453
  let fundSnapshot = null;
1452
1454
  // Detect empty-side condition: when one side has zero on-chain orders,
1453
1455
  // the spread is technically infinite and shouldFlagOutOfSpread's old
@@ -1488,7 +1490,7 @@ async function checkSpreadCondition(manager, _BitShares, updateOrdersOnChainBatc
1488
1490
  const gapSlots = calculateGapSlots(manager.config.incrementPercent, manager.config.targetSpreadPercent, manager.config.gridLimits);
1489
1491
  const railLen = allSlots.length;
1490
1492
  const buyEndIdx = manager.boundaryIdx;
1491
- const sellStartIdx = manager.boundaryIdx + gapSlots + 1;
1493
+ const sellStartIdx = (0, math_1.getSellStartIdx)(manager.boundaryIdx, gapSlots);
1492
1494
  const buySideCount = Math.max(0, Math.min(railLen, buyEndIdx + 1));
1493
1495
  const sellSideCount = Math.max(0, railLen - sellStartIdx);
1494
1496
  // Structural resync: both sides have room but one is empty.
@@ -1514,7 +1516,7 @@ async function checkSpreadCondition(manager, _BitShares, updateOrdersOnChainBatc
1514
1516
  if (!decision.side)
1515
1517
  return false;
1516
1518
  // Perform spread correction by placing orders on the chosen side.
1517
- correction = await prepareSpreadCorrectionOrders(manager, decision.side);
1519
+ correction = await prepareSpreadCorrectionOrders(manager, decision.side, manager.outOfSpread);
1518
1520
  if (!correction)
1519
1521
  return false;
1520
1522
  let placeCount = correction.ordersToPlace?.length || 0;
@@ -1525,7 +1527,7 @@ async function checkSpreadCondition(manager, _BitShares, updateOrdersOnChainBatc
1525
1527
  const oppositeSide = decision.side === constants_1.ORDER_TYPES.BUY ? constants_1.ORDER_TYPES.SELL : constants_1.ORDER_TYPES.BUY;
1526
1528
  manager.logger?.log?.(`[SPREAD] Side ${decision.side} produced zero candidates; ` +
1527
1529
  `trying opposite side ${oppositeSide}.`, 'debug');
1528
- const oppositeCorrection = await prepareSpreadCorrectionOrders(manager, oppositeSide);
1530
+ const oppositeCorrection = await prepareSpreadCorrectionOrders(manager, oppositeSide, manager.outOfSpread);
1529
1531
  if (oppositeCorrection) {
1530
1532
  correction = oppositeCorrection;
1531
1533
  placeCount = correction.ordersToPlace?.length || 0;
@@ -1540,12 +1542,20 @@ async function checkSpreadCondition(manager, _BitShares, updateOrdersOnChainBatc
1540
1542
  shouldApplyCorrection = await manager._gridLock.acquire(executeSpreadCheck);
1541
1543
  }
1542
1544
  catch (err) {
1543
- manager.logger?.log?.(`Error checking spread condition: ${(0, errors_1.getErrorMessage)(err)}`, 'warn');
1545
+ manager.logger?.log?.(`Error checking spread condition: ${(0, errors_1.getErrorMessage)(err)}`, 'error');
1546
+ // Track failure in recovery state for external monitoring.
1547
+ // Do NOT throw — the startup runtime path lacks a try/catch and
1548
+ // a throw would crash startup. The error is symptom of a deeper
1549
+ // issue (lock contention, grid inconsistency) that should be
1550
+ // diagnosed separately.
1551
+ if (manager._recoveryState) {
1552
+ manager._recoveryState = { ...manager._recoveryState, lastFailureAt: Date.now() };
1553
+ }
1544
1554
  return { ordersPlaced: 0, partialsMoved: 0 };
1545
1555
  }
1546
- // FIX: Apply blockchain operations OUTSIDE the lock to reduce lock contention
1547
- // The lock is only needed for fund verification; order placement doesn't need it
1548
- // Pre-flight fund verification to mitigate TOCTOU between lock release and broadcast
1556
+ // Blockchain operations are intentionally OUTSIDE the lock to reduce lock contention.
1557
+ // The lock is only needed for fund verification; order placement doesn't need it.
1558
+ // Pre-flight fund verification mitigates TOCTOU between lock release and broadcast.
1549
1559
  if (shouldApplyCorrection && updateOrdersOnChainBatch && correction && fundSnapshot) {
1550
1560
  const currentFunds = _snapshotFundState(manager);
1551
1561
  const fundChanged = fundSnapshot.buyFree !== currentFunds.buyFree
@@ -1554,28 +1564,27 @@ async function checkSpreadCondition(manager, _BitShares, updateOrdersOnChainBatc
1554
1564
  || fundSnapshot.sellLocked !== currentFunds.sellLocked;
1555
1565
  if (fundChanged) {
1556
1566
  // TOCTOU: fund state changed between lock release and broadcast.
1557
- // Instead of silently aborting, re-plan with fresh funds so the
1558
- // correction still applies on this cycle. The pre-flight check
1559
- // still guards against placing orders based on stale fund snapshots.
1560
- // Re-acquire _gridLock for the re-plan to ensure consistent grid
1561
- // state (the lock is re-entrant for this call chain — the outer
1562
- // acquire's callback completed before we reach here, so there is
1563
- // no nested lock to recurse into). If determineOrderSideByFunds
1564
- // or prepareSpreadCorrectionOrders grow to hold the lock for
1565
- // heavy work, hoist the result to avoid serial re-execution.
1566
- const rePlanResult = await manager._gridLock.acquire(async () => {
1567
- const decision = determineOrderSideByFunds(manager, lastPrice);
1568
- if (!decision.side)
1569
- return { side: false };
1570
- const c = await prepareSpreadCorrectionOrders(manager, decision.side);
1571
- return { side: true, correction: c };
1572
- });
1573
- if (!rePlanResult.side) {
1567
+ // Lock-free re-plan — no _gridLock needed because the fund read
1568
+ // (recalculateFunds) is serialized by _fundLock internally, and
1569
+ // the remaining logic is read-only against COW-frozen state.
1570
+ // All grid-lock-needing work (fund verification, grid reads) is
1571
+ // done under the single outer acquire above; this re-plan runs
1572
+ // after that lock was released.
1573
+ // Refresh lastPrice from current grid state — the grid may
1574
+ // have changed since function entry (TOCTOU).
1575
+ const freshOnChain = _getOnChainOrders(manager);
1576
+ const freshBest = (0, math_1.getGridBestPrices)(freshOnChain.onChainBuys, freshOnChain.onChainSells);
1577
+ const freshPrice = (freshBest.bestBuy !== null && freshBest.bestSell !== null)
1578
+ ? (freshBest.bestBuy + freshBest.bestSell) / 2
1579
+ : Number(manager.config.startPrice) || 0;
1580
+ const rePlanDecision = determineOrderSideByFunds(manager, freshPrice);
1581
+ if (!rePlanDecision.side) {
1574
1582
  manager.logger?.log?.(`[SPREAD] Fund state changed; no side has sufficient funds for re-plan. Skipping cycle.`, 'warn');
1575
1583
  return { ordersPlaced: 0, partialsMoved: 0 };
1576
1584
  }
1577
- correction = rePlanResult.correction;
1578
- if (correction && ((correction.ordersToPlace?.length || 0) + (correction.ordersToUpdate?.length || 0) > 0)) {
1585
+ const rePlanCorrection = await prepareSpreadCorrectionOrders(manager, rePlanDecision.side, manager.outOfSpread);
1586
+ if (rePlanCorrection && ((rePlanCorrection.ordersToPlace?.length || 0) + (rePlanCorrection.ordersToUpdate?.length || 0) > 0)) {
1587
+ correction = rePlanCorrection;
1579
1588
  fundSnapshot = currentFunds;
1580
1589
  manager.logger?.log?.(`[SPREAD] Fund state changed between lock release and broadcast — ` +
1581
1590
  `re-planned with updated funds: ${correction.ordersToPlace?.length || 0} creates, ` +
@@ -1832,40 +1841,6 @@ function determineOrderSideByFunds(manager, currentMarketPrice) {
1832
1841
  }
1833
1842
  return { side, reason: side ? `Choosing ${side}` : 'Insufficient funds or committed inventory' };
1834
1843
  }
1835
- /**
1836
- * Calculate the geometric ideal size for a new order being placed during spread correction.
1837
- * @param {import('./types').OrderManager} manager - The manager instance.
1838
- * @param {import('./types').OrderType} targetType - The type of order being placed (ORDER_TYPES.BUY or ORDER_TYPES.SELL).
1839
- * @returns {Promise<number|null>} The calculated geometric size.
1840
- */
1841
- async function calculateGeometricSizeForSpreadCorrection(manager, targetType) {
1842
- const side = targetType === constants_1.ORDER_TYPES.BUY ? 'buy' : 'sell';
1843
- // Count only on-chain orders (ACTIVE+PARTIAL) to avoid diluting the
1844
- // spread-correction order size across hundreds of virtual slots on a
1845
- // full-rail grid. Virtual slots have their capital tracked separately
1846
- // in funds.virtual and should not compete for the free budget.
1847
- const slotsCount = Array.from(manager.orders.values())
1848
- .filter((o) => o.type === targetType && (o.state === constants_1.ORDER_STATES.ACTIVE || o.state === constants_1.ORDER_STATES.PARTIAL))
1849
- .length + 1;
1850
- // Use centralized sizing context (respects botFunds % allocation)
1851
- const ctx = await _getSizingContext(manager, side);
1852
- if (!ctx || ctx.budget <= 0 || slotsCount < 1)
1853
- return null;
1854
- // ALLOW slotsCount === 1 to enable spread correction even if a side is completely missing
1855
- const dummy = Array.from({ length: slotsCount }, () => ({ type: targetType }));
1856
- try {
1857
- const sized = (0, math_1.calculateOrderSizes)(dummy, manager.config, side === 'sell' ? ctx.budget : 0, side === 'buy' ? ctx.budget : 0, 0, 0, ctx.precision, ctx.precision);
1858
- if (!Array.isArray(sized) || sized.length === 0) {
1859
- manager.logger?.log?.(`calculateOrderSizes returned invalid result for spread correction`, 'warn');
1860
- return null;
1861
- }
1862
- return side === 'sell' ? sized[0].size : sized[sized.length - 1].size;
1863
- }
1864
- catch (e) {
1865
- manager.logger?.log?.(`Error calculating geometric size for spread correction: ${(0, errors_1.getErrorMessage)(e)}`, 'warn');
1866
- return null;
1867
- }
1868
- }
1869
1844
  /**
1870
1845
  * Prepares one or more orders to correct a wide spread.
1871
1846
  * @param {import('./types').OrderManager} manager - The OrderManager instance.
@@ -1873,7 +1848,7 @@ async function calculateGeometricSizeForSpreadCorrection(manager, targetType) {
1873
1848
  * @returns {Promise<import('./types').SpreadCorrectionResult>}
1874
1849
  * @throws {Error} If preferredSide is invalid.
1875
1850
  */
1876
- async function prepareSpreadCorrectionOrders(manager, preferredSide) {
1851
+ async function prepareSpreadCorrectionOrders(manager, preferredSide, outOfSpread = 0) {
1877
1852
  // FIX: Validate preferredSide parameter to prevent silent logic errors
1878
1853
  if (preferredSide !== constants_1.ORDER_TYPES.BUY && preferredSide !== constants_1.ORDER_TYPES.SELL) {
1879
1854
  throw new Error(`Invalid preferredSide: ${preferredSide}. Must be '${constants_1.ORDER_TYPES.BUY}' or '${constants_1.ORDER_TYPES.SELL}'.`);
@@ -1882,7 +1857,7 @@ async function prepareSpreadCorrectionOrders(manager, preferredSide) {
1882
1857
  const ordersToUpdate = [];
1883
1858
  const railType = preferredSide;
1884
1859
  const sideName = railType === constants_1.ORDER_TYPES.BUY ? 'buy' : 'sell';
1885
- const configuredMissingSlots = Number(manager.outOfSpread || 0);
1860
+ const configuredMissingSlots = Number(outOfSpread || 0);
1886
1861
  const missingSlots = configuredMissingSlots > 0
1887
1862
  ? Math.floor(configuredMissingSlots)
1888
1863
  : 1;
@@ -1905,17 +1880,14 @@ async function prepareSpreadCorrectionOrders(manager, preferredSide) {
1905
1880
  .sort((a, b) => a.price - b.price);
1906
1881
  const slotIndexMap = new Map(allSlotsByPrice.map((o, i) => [o.id, i]));
1907
1882
  const gapSlots = calculateGapSlots(manager.config?.incrementPercent, manager.config?.targetSpreadPercent, manager.config?.gridLimits);
1908
- // Sync boundary from current fund state to avoid stale boundaryIdx causing
1909
- // getSlotCorrectType to misclassify slots (e.g. after fills shifted the
1910
- // boundary but the COW commit hasn't updated it yet). This is safe under
1911
- // the grid lock — no concurrent modifications can race with this read.
1912
- const boundarySync = (0, system_1.syncBoundaryToFunds)(manager);
1913
- if (boundarySync.changed && boundarySync.newIdx !== undefined) {
1914
- manager.boundaryIdx = boundarySync.newIdx;
1915
- }
1916
- const bIdx = manager.boundaryIdx ?? 0;
1917
- const buyEndIdx = bIdx;
1918
- const sellStartIdx = bIdx + Number(gapSlots) + 1;
1883
+ // Use the committed boundary for slot classification — never a speculative
1884
+ // value from syncBoundaryToFunds that hasn't been persisted through the COW
1885
+ // pipeline. If the boundary shifts later via _commitWorkingGrid, the next
1886
+ // spread correction cycle will re-classify with the updated committed value.
1887
+ // This prevents TOCTOU-style inconsistency where slot types are chosen
1888
+ // against a boundary that was never atomically committed to manager.orders.
1889
+ const buyEndIdx = manager.boundaryIdx ?? 0;
1890
+ const sellStartIdx = (0, math_1.getSellStartIdx)(manager.boundaryIdx, gapSlots);
1919
1891
  const getSlotCorrectType = (slot) => {
1920
1892
  const idx = slotIndexMap.get(slot.id);
1921
1893
  if (idx === undefined)