dexbot 1.4.10 → 1.4.12
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.
- package/README.md +6 -5
- package/dist/analysis/chart_utils.d.ts.map +1 -1
- package/dist/analysis/chart_utils.js +9 -18
- package/dist/analysis/chart_utils.js.map +1 -1
- package/dist/analysis/math_utils.d.ts.map +1 -1
- package/dist/analysis/math_utils.js +6 -16
- package/dist/analysis/math_utils.js.map +1 -1
- package/dist/analysis/tradingview/tradingview_uplot_chart_generator.d.ts +1 -1
- package/dist/analysis/tradingview/tradingview_uplot_chart_generator.d.ts.map +1 -1
- package/dist/analysis/tradingview/tradingview_uplot_chart_generator.js +31 -38
- package/dist/analysis/tradingview/tradingview_uplot_chart_generator.js.map +1 -1
- package/dist/analysis/trend_detection/hurst_analyzer.js +7 -10
- package/dist/analysis/trend_detection/hurst_analyzer.js.map +1 -1
- package/dist/analysis/trend_detection/kalman_trend_analyzer.js +10 -14
- package/dist/analysis/trend_detection/kalman_trend_analyzer.js.map +1 -1
- package/dist/analysis/trend_detection/kalman_velocity_smoothing.js +10 -15
- package/dist/analysis/trend_detection/kalman_velocity_smoothing.js.map +1 -1
- package/dist/analysis/trend_detection/permutation_entropy_analyzer.js +7 -10
- package/dist/analysis/trend_detection/permutation_entropy_analyzer.js.map +1 -1
- package/dist/bot.d.ts.map +1 -1
- package/dist/bot.js +4 -12
- package/dist/bot.js.map +1 -1
- package/dist/credential-daemon.d.ts +0 -1
- package/dist/credential-daemon.d.ts.map +1 -1
- package/dist/credential-daemon.js +3 -123
- package/dist/credential-daemon.js.map +1 -1
- package/dist/dexbot.d.ts +0 -87
- package/dist/dexbot.d.ts.map +1 -1
- package/dist/dexbot.js +54 -23
- package/dist/dexbot.js.map +1 -1
- package/dist/market_adapter/ama_signal_runner.js +8 -9
- package/dist/market_adapter/ama_signal_runner.js.map +1 -1
- package/dist/market_adapter/candle_utils.js +1 -7
- package/dist/market_adapter/candle_utils.js.map +1 -1
- package/dist/market_adapter/core/asymmetric_bounds.js +1 -4
- package/dist/market_adapter/core/asymmetric_bounds.js.map +1 -1
- package/dist/market_adapter/core/config_normalizers.js +5 -9
- package/dist/market_adapter/core/config_normalizers.js.map +1 -1
- package/dist/market_adapter/core/kibana_candles.js +8 -15
- package/dist/market_adapter/core/kibana_candles.js.map +1 -1
- package/dist/market_adapter/core/kibana_client.js +7 -13
- package/dist/market_adapter/core/kibana_client.js.map +1 -1
- package/dist/market_adapter/core/kibana_market_candles.js +6 -12
- package/dist/market_adapter/core/kibana_market_candles.js.map +1 -1
- package/dist/market_adapter/core/market_adapter_service.d.ts +2 -0
- package/dist/market_adapter/core/market_adapter_service.d.ts.map +1 -1
- package/dist/market_adapter/core/market_adapter_service.js +100 -101
- package/dist/market_adapter/core/market_adapter_service.js.map +1 -1
- package/dist/market_adapter/core/strategies/ama.js +5 -10
- package/dist/market_adapter/core/strategies/ama.js.map +1 -1
- package/dist/market_adapter/core/strategies/ama_slope_model.js +21 -24
- package/dist/market_adapter/core/strategies/ama_slope_model.js.map +1 -1
- package/dist/market_adapter/core/strategies/atr/calculator.js +3 -5
- package/dist/market_adapter/core/strategies/atr/calculator.js.map +1 -1
- package/dist/market_adapter/core/strategies/collateral_manager.js +4 -6
- package/dist/market_adapter/core/strategies/collateral_manager.js.map +1 -1
- package/dist/market_adapter/core/strategies/regime_gate.js +15 -22
- package/dist/market_adapter/core/strategies/regime_gate.js.map +1 -1
- package/dist/market_adapter/index.d.ts +23 -23
- package/dist/market_adapter/index.d.ts.map +1 -1
- package/dist/market_adapter/index.js +24 -82
- package/dist/market_adapter/index.js.map +1 -1
- package/dist/market_adapter/inputs/fetch_cex_synthetic_data.js +2 -1
- package/dist/market_adapter/inputs/fetch_cex_synthetic_data.js.map +1 -1
- package/dist/market_adapter/inputs/fetch_lp_data.d.ts.map +1 -1
- package/dist/market_adapter/inputs/fetch_lp_data.js +59 -98
- package/dist/market_adapter/inputs/fetch_lp_data.js.map +1 -1
- package/dist/market_adapter/inputs/kibana_source.js +11 -17
- package/dist/market_adapter/inputs/kibana_source.js.map +1 -1
- package/dist/market_adapter/interval_utils.js +1 -2
- package/dist/market_adapter/interval_utils.js.map +1 -1
- package/dist/market_adapter/log_format.js +1 -7
- package/dist/market_adapter/log_format.js.map +1 -1
- package/dist/market_adapter/lp_chart_core.js +20 -22
- package/dist/market_adapter/lp_chart_core.js.map +1 -1
- package/dist/market_adapter/lp_chart_runner.d.ts +1 -1
- package/dist/market_adapter/lp_chart_runner.d.ts.map +1 -1
- package/dist/market_adapter/lp_chart_runner.js +41 -57
- package/dist/market_adapter/lp_chart_runner.js.map +1 -1
- package/dist/market_adapter/lp_chart_strategy_loader.js +30 -34
- package/dist/market_adapter/lp_chart_strategy_loader.js.map +1 -1
- package/dist/market_adapter/market_adapter.d.ts +2 -2
- package/dist/market_adapter/market_adapter.d.ts.map +1 -1
- package/dist/market_adapter/market_adapter.js +163 -222
- package/dist/market_adapter/market_adapter.js.map +1 -1
- package/dist/market_adapter/merge_lp_data.js +17 -18
- package/dist/market_adapter/merge_lp_data.js.map +1 -1
- package/dist/market_adapter/test_helpers.js +3 -14
- package/dist/market_adapter/test_helpers.js.map +1 -1
- package/dist/market_adapter/utils/adapter_client.js +7 -16
- package/dist/market_adapter/utils/adapter_client.js.map +1 -1
- package/dist/market_adapter/utils/atomic_write.js +3 -5
- package/dist/market_adapter/utils/atomic_write.js.map +1 -1
- package/dist/market_adapter/utils/chain.d.ts.map +1 -1
- package/dist/market_adapter/utils/chain.js +9 -17
- package/dist/market_adapter/utils/chain.js.map +1 -1
- package/dist/market_adapter/utils/data_discovery.js +8 -10
- package/dist/market_adapter/utils/data_discovery.js.map +1 -1
- package/dist/market_adapter/utils/dynamic_grid_snapshot.d.ts.map +1 -1
- package/dist/market_adapter/utils/dynamic_grid_snapshot.js +11 -14
- package/dist/market_adapter/utils/dynamic_grid_snapshot.js.map +1 -1
- package/dist/market_adapter/utils/file_lock.js +14 -19
- package/dist/market_adapter/utils/file_lock.js.map +1 -1
- package/dist/market_adapter/utils/native_history.js +8 -14
- package/dist/market_adapter/utils/native_history.js.map +1 -1
- package/dist/market_adapter/utils/paths.js +3 -6
- package/dist/market_adapter/utils/paths.js.map +1 -1
- package/dist/modules/account_bots.d.ts +1 -1
- package/dist/modules/account_bots.d.ts.map +1 -1
- package/dist/modules/account_bots.js +90 -97
- package/dist/modules/account_bots.js.map +1 -1
- package/dist/modules/account_orders.d.ts +0 -9
- package/dist/modules/account_orders.d.ts.map +1 -1
- package/dist/modules/account_orders.js +26 -121
- package/dist/modules/account_orders.js.map +1 -1
- package/dist/modules/authority_resolver.js +12 -18
- package/dist/modules/authority_resolver.js.map +1 -1
- package/dist/modules/bitshares-native/chain_client.js +16 -21
- package/dist/modules/bitshares-native/chain_client.js.map +1 -1
- package/dist/modules/bitshares-native/crypto/ecc.browser.js +12 -72
- package/dist/modules/bitshares-native/crypto/ecc.browser.js.map +1 -1
- package/dist/modules/bitshares-native/crypto/ecc.js +13 -40
- package/dist/modules/bitshares-native/crypto/ecc.js.map +1 -1
- package/dist/modules/bitshares-native/crypto/ecc_selector.d.ts.map +1 -1
- package/dist/modules/bitshares-native/crypto/ecc_selector.js +5 -6
- package/dist/modules/bitshares-native/crypto/ecc_selector.js.map +1 -1
- package/dist/modules/bitshares-native/index.d.ts +8 -8
- package/dist/modules/bitshares-native/index.d.ts.map +1 -1
- package/dist/modules/bitshares-native/index.js +11 -68
- package/dist/modules/bitshares-native/index.js.map +1 -1
- package/dist/modules/bitshares-native/lru_cache.js +3 -6
- package/dist/modules/bitshares-native/lru_cache.js.map +1 -1
- package/dist/modules/bitshares-native/resolvers.js +9 -11
- package/dist/modules/bitshares-native/resolvers.js.map +1 -1
- package/dist/modules/bitshares-native/serial/chain_constants.js +3 -28
- package/dist/modules/bitshares-native/serial/chain_constants.js.map +1 -1
- package/dist/modules/bitshares-native/serial/index.d.ts +4 -4
- package/dist/modules/bitshares-native/serial/index.d.ts.map +1 -1
- package/dist/modules/bitshares-native/serial/index.js +5 -46
- package/dist/modules/bitshares-native/serial/index.js.map +1 -1
- package/dist/modules/bitshares-native/serial/operations.d.ts +98 -98
- package/dist/modules/bitshares-native/serial/operations.d.ts.map +1 -1
- package/dist/modules/bitshares-native/serial/operations.js +372 -473
- package/dist/modules/bitshares-native/serial/operations.js.map +1 -1
- package/dist/modules/bitshares-native/serial/serializer.js +3 -8
- package/dist/modules/bitshares-native/serial/serializer.js.map +1 -1
- package/dist/modules/bitshares-native/serial/types.js +9 -74
- package/dist/modules/bitshares-native/serial/types.js.map +1 -1
- package/dist/modules/bitshares-native/signing_client.d.ts.map +1 -1
- package/dist/modules/bitshares-native/signing_client.js +11 -48
- package/dist/modules/bitshares-native/signing_client.js.map +1 -1
- package/dist/modules/bitshares-native/subscriptions.d.ts.map +1 -1
- package/dist/modules/bitshares-native/subscriptions.js +24 -27
- package/dist/modules/bitshares-native/subscriptions.js.map +1 -1
- package/dist/modules/bitshares-native/transport.d.ts.map +1 -1
- package/dist/modules/bitshares-native/transport.js +14 -26
- package/dist/modules/bitshares-native/transport.js.map +1 -1
- package/dist/modules/bitshares-native/tx/builder.js +29 -72
- package/dist/modules/bitshares-native/tx/builder.js.map +1 -1
- package/dist/modules/bitshares-native/tx/tx_cache.js +12 -21
- package/dist/modules/bitshares-native/tx/tx_cache.js.map +1 -1
- package/dist/modules/bitshares_client.d.ts +21 -0
- package/dist/modules/bitshares_client.d.ts.map +1 -1
- package/dist/modules/bitshares_client.js +32 -86
- package/dist/modules/bitshares_client.js.map +1 -1
- package/dist/modules/bot_settings.d.ts.map +1 -1
- package/dist/modules/bot_settings.js +30 -49
- package/dist/modules/bot_settings.js.map +1 -1
- package/dist/modules/bots_file_lock.d.ts.map +1 -1
- package/dist/modules/bots_file_lock.js +5 -13
- package/dist/modules/bots_file_lock.js.map +1 -1
- package/dist/modules/broadcast_failure.js +1 -3
- package/dist/modules/broadcast_failure.js.map +1 -1
- package/dist/modules/chain_keys.d.ts +4 -9
- package/dist/modules/chain_keys.d.ts.map +1 -1
- package/dist/modules/chain_keys.js +77 -182
- package/dist/modules/chain_keys.js.map +1 -1
- package/dist/modules/chain_orders.d.ts +2 -2
- package/dist/modules/chain_orders.d.ts.map +1 -1
- package/dist/modules/chain_orders.js +81 -144
- package/dist/modules/chain_orders.js.map +1 -1
- package/dist/modules/config.d.ts.map +1 -1
- package/dist/modules/config.js +23 -28
- package/dist/modules/config.js.map +1 -1
- package/dist/modules/constants.d.ts +4 -14
- package/dist/modules/constants.d.ts.map +1 -1
- package/dist/modules/constants.js +46 -78
- package/dist/modules/constants.js.map +1 -1
- package/dist/modules/cr_planner.js +15 -26
- package/dist/modules/cr_planner.js.map +1 -1
- package/dist/modules/credential_policy.d.ts +3 -6
- package/dist/modules/credential_policy.d.ts.map +1 -1
- package/dist/modules/credential_policy.js +62 -153
- package/dist/modules/credential_policy.js.map +1 -1
- package/dist/modules/credential_runtime.d.ts +1 -1
- package/dist/modules/credential_runtime.d.ts.map +1 -1
- package/dist/modules/credential_runtime.js +34 -41
- package/dist/modules/credential_runtime.js.map +1 -1
- package/dist/modules/credential_session_cache.d.ts +1 -1
- package/dist/modules/credential_session_cache.d.ts.map +1 -1
- package/dist/modules/credential_session_cache.js +5 -42
- package/dist/modules/credential_session_cache.js.map +1 -1
- package/dist/modules/credit_runtime.d.ts.map +1 -1
- package/dist/modules/credit_runtime.js +126 -162
- package/dist/modules/credit_runtime.js.map +1 -1
- package/dist/modules/crypto/browser_provider.d.ts +1 -1
- package/dist/modules/crypto/browser_provider.d.ts.map +1 -1
- package/dist/modules/crypto/browser_provider.js +7 -11
- package/dist/modules/crypto/browser_provider.js.map +1 -1
- package/dist/modules/crypto/index.d.ts +6 -6
- package/dist/modules/crypto/index.d.ts.map +1 -1
- package/dist/modules/crypto/index.js +12 -30
- package/dist/modules/crypto/index.js.map +1 -1
- package/dist/modules/crypto/node_provider.d.ts +1 -1
- package/dist/modules/crypto/node_provider.d.ts.map +1 -1
- package/dist/modules/crypto/node_provider.js +3 -5
- package/dist/modules/crypto/node_provider.js.map +1 -1
- package/dist/modules/crypto/provider.js +1 -2
- package/dist/modules/crypto/pure_ripemd160.js +1 -3
- package/dist/modules/crypto/pure_ripemd160.js.map +1 -1
- package/dist/modules/crypto/pure_scrypt.js +1 -4
- package/dist/modules/crypto/pure_scrypt.js.map +1 -1
- package/dist/modules/crypto/pure_secp256k1.d.ts +1 -1
- package/dist/modules/crypto/pure_secp256k1.d.ts.map +1 -1
- package/dist/modules/crypto/pure_secp256k1.js +1 -16
- package/dist/modules/crypto/pure_secp256k1.js.map +1 -1
- package/dist/modules/crypto/sync.d.ts.map +1 -1
- package/dist/modules/crypto/sync.js +16 -17
- package/dist/modules/crypto/sync.js.map +1 -1
- package/dist/modules/daemon_node_health.js +14 -16
- package/dist/modules/daemon_node_health.js.map +1 -1
- package/dist/modules/dexbot_class.d.ts +19 -14
- package/dist/modules/dexbot_class.d.ts.map +1 -1
- package/dist/modules/dexbot_class.js +127 -164
- package/dist/modules/dexbot_class.js.map +1 -1
- package/dist/modules/dexbot_cow_runtime.d.ts +28 -27
- package/dist/modules/dexbot_cow_runtime.d.ts.map +1 -1
- package/dist/modules/dexbot_cow_runtime.js +55 -45
- package/dist/modules/dexbot_cow_runtime.js.map +1 -1
- package/dist/modules/dexbot_credential_client.d.ts +6 -2
- package/dist/modules/dexbot_credential_client.d.ts.map +1 -1
- package/dist/modules/dexbot_credential_client.js +21 -31
- package/dist/modules/dexbot_credential_client.js.map +1 -1
- package/dist/modules/dexbot_fill_runtime.d.ts +23 -23
- package/dist/modules/dexbot_fill_runtime.d.ts.map +1 -1
- package/dist/modules/dexbot_fill_runtime.js +119 -77
- package/dist/modules/dexbot_fill_runtime.js.map +1 -1
- package/dist/modules/dexbot_maintenance_runtime.d.ts +46 -38
- package/dist/modules/dexbot_maintenance_runtime.d.ts.map +1 -1
- package/dist/modules/dexbot_maintenance_runtime.js +81 -81
- package/dist/modules/dexbot_maintenance_runtime.js.map +1 -1
- package/dist/modules/dexbot_startup_runtime.d.ts +3 -3
- package/dist/modules/dexbot_startup_runtime.d.ts.map +1 -1
- package/dist/modules/dexbot_startup_runtime.js +43 -81
- package/dist/modules/dexbot_startup_runtime.js.map +1 -1
- package/dist/modules/dexbot_state_recovery.d.ts +11 -11
- package/dist/modules/dexbot_state_recovery.js +32 -78
- package/dist/modules/dexbot_state_recovery.js.map +1 -1
- package/dist/modules/env.js +3 -7
- package/dist/modules/env.js.map +1 -1
- package/dist/modules/fund_registry.d.ts.map +1 -1
- package/dist/modules/fund_registry.js +12 -24
- package/dist/modules/fund_registry.js.map +1 -1
- package/dist/modules/general_settings.js +10 -16
- package/dist/modules/general_settings.js.map +1 -1
- package/dist/modules/graceful_shutdown.d.ts.map +1 -1
- package/dist/modules/graceful_shutdown.js +12 -19
- package/dist/modules/graceful_shutdown.js.map +1 -1
- package/dist/modules/key_store.d.ts.map +1 -1
- package/dist/modules/key_store.js +27 -65
- package/dist/modules/key_store.js.map +1 -1
- package/dist/modules/launcher/bot_supervisor.d.ts +1 -1
- package/dist/modules/launcher/bot_supervisor.d.ts.map +1 -1
- package/dist/modules/launcher/bot_supervisor.js +89 -118
- package/dist/modules/launcher/bot_supervisor.js.map +1 -1
- package/dist/modules/launcher/child_env.js +1 -5
- package/dist/modules/launcher/child_env.js.map +1 -1
- package/dist/modules/launcher/credential_bootstrap.js +22 -31
- package/dist/modules/launcher/credential_bootstrap.js.map +1 -1
- package/dist/modules/launcher/credential_daemon.js +37 -75
- package/dist/modules/launcher/credential_daemon.js.map +1 -1
- package/dist/modules/launcher/credential_secret.js +2 -37
- package/dist/modules/launcher/credential_secret.js.map +1 -1
- package/dist/modules/launcher/foreign_cred_daemon.js +25 -31
- package/dist/modules/launcher/foreign_cred_daemon.js.map +1 -1
- package/dist/modules/launcher/headless_password.js +10 -12
- package/dist/modules/launcher/headless_password.js.map +1 -1
- package/dist/modules/launcher/launch_modes.js +3 -9
- package/dist/modules/launcher/launch_modes.js.map +1 -1
- package/dist/modules/launcher/market_adapter_runtime.d.ts +1 -1
- package/dist/modules/launcher/market_adapter_runtime.d.ts.map +1 -1
- package/dist/modules/launcher/market_adapter_runtime.js +25 -35
- package/dist/modules/launcher/market_adapter_runtime.js.map +1 -1
- package/dist/modules/launcher/market_adapter_watchdog.d.ts.map +1 -1
- package/dist/modules/launcher/market_adapter_watchdog.js +42 -45
- package/dist/modules/launcher/market_adapter_watchdog.js.map +1 -1
- package/dist/modules/launcher/monolithic_runtime.d.ts +3 -2
- package/dist/modules/launcher/monolithic_runtime.d.ts.map +1 -1
- package/dist/modules/launcher/monolithic_runtime.js +97 -138
- package/dist/modules/launcher/monolithic_runtime.js.map +1 -1
- package/dist/modules/launcher/runtime_entry.d.ts +1 -11
- package/dist/modules/launcher/runtime_entry.d.ts.map +1 -1
- package/dist/modules/launcher/runtime_entry.js +12 -15
- package/dist/modules/launcher/runtime_entry.js.map +1 -1
- package/dist/modules/launcher/status_reporting.d.ts +1 -1
- package/dist/modules/launcher/status_reporting.d.ts.map +1 -1
- package/dist/modules/launcher/status_reporting.js +15 -36
- package/dist/modules/launcher/status_reporting.js.map +1 -1
- package/dist/modules/launcher/supervisor_control.js +4 -9
- package/dist/modules/launcher/supervisor_control.js.map +1 -1
- package/dist/modules/logger.d.ts +1 -1
- package/dist/modules/logger.d.ts.map +1 -1
- package/dist/modules/logger.js +3 -38
- package/dist/modules/logger.js.map +1 -1
- package/dist/modules/market_adapter_whitelist.js +9 -18
- package/dist/modules/market_adapter_whitelist.js.map +1 -1
- package/dist/modules/node_failure_ledger.js +1 -3
- package/dist/modules/node_failure_ledger.js.map +1 -1
- package/dist/modules/node_health_cache.d.ts.map +1 -1
- package/dist/modules/node_health_cache.js +15 -25
- package/dist/modules/node_health_cache.js.map +1 -1
- package/dist/modules/node_manager.d.ts +1 -1
- package/dist/modules/node_manager.d.ts.map +1 -1
- package/dist/modules/node_manager.js +44 -43
- package/dist/modules/node_manager.js.map +1 -1
- package/dist/modules/order/accounting.d.ts.map +1 -1
- package/dist/modules/order/accounting.js +102 -118
- package/dist/modules/order/accounting.js.map +1 -1
- package/dist/modules/order/async_lock.d.ts +3 -15
- package/dist/modules/order/async_lock.d.ts.map +1 -1
- package/dist/modules/order/async_lock.js +6 -26
- package/dist/modules/order/async_lock.js.map +1 -1
- package/dist/modules/order/export.js +34 -75
- package/dist/modules/order/export.js.map +1 -1
- package/dist/modules/order/format.d.ts +1 -3
- package/dist/modules/order/format.d.ts.map +1 -1
- package/dist/modules/order/format.js +4 -24
- package/dist/modules/order/format.js.map +1 -1
- package/dist/modules/order/grid.d.ts +8 -8
- package/dist/modules/order/grid.d.ts.map +1 -1
- package/dist/modules/order/grid.js +254 -266
- package/dist/modules/order/grid.js.map +1 -1
- package/dist/modules/order/grid_reconcile.d.ts.map +1 -1
- package/dist/modules/order/grid_reconcile.js +77 -94
- package/dist/modules/order/grid_reconcile.js.map +1 -1
- package/dist/modules/order/grid_reconcile_internal.d.ts.map +1 -1
- package/dist/modules/order/grid_reconcile_internal.js +117 -149
- package/dist/modules/order/grid_reconcile_internal.js.map +1 -1
- package/dist/modules/order/index.d.ts.map +1 -1
- package/dist/modules/order/index.js +11 -45
- package/dist/modules/order/index.js.map +1 -1
- package/dist/modules/order/logger.d.ts +0 -8
- package/dist/modules/order/logger.d.ts.map +1 -1
- package/dist/modules/order/logger.js +28 -141
- package/dist/modules/order/logger.js.map +1 -1
- package/dist/modules/order/logger_state.d.ts.map +1 -1
- package/dist/modules/order/logger_state.js +3 -4
- package/dist/modules/order/logger_state.js.map +1 -1
- package/dist/modules/order/manager.d.ts +10 -79
- package/dist/modules/order/manager.d.ts.map +1 -1
- package/dist/modules/order/manager.js +131 -247
- package/dist/modules/order/manager.js.map +1 -1
- package/dist/modules/order/processed_fill_store.js +2 -7
- package/dist/modules/order/processed_fill_store.js.map +1 -1
- package/dist/modules/order/strategy.js +23 -25
- package/dist/modules/order/strategy.js.map +1 -1
- package/dist/modules/order/sync_engine.d.ts +27 -0
- package/dist/modules/order/sync_engine.d.ts.map +1 -1
- package/dist/modules/order/sync_engine.js +232 -181
- package/dist/modules/order/sync_engine.js.map +1 -1
- package/dist/modules/order/utils/math.d.ts +1 -25
- package/dist/modules/order/utils/math.d.ts.map +1 -1
- package/dist/modules/order/utils/math.js +49 -172
- package/dist/modules/order/utils/math.js.map +1 -1
- package/dist/modules/order/utils/order.d.ts +46 -2
- package/dist/modules/order/utils/order.d.ts.map +1 -1
- package/dist/modules/order/utils/order.js +165 -143
- package/dist/modules/order/utils/order.js.map +1 -1
- package/dist/modules/order/utils/system.d.ts +3 -1
- package/dist/modules/order/utils/system.d.ts.map +1 -1
- package/dist/modules/order/utils/system.js +152 -211
- package/dist/modules/order/utils/system.js.map +1 -1
- package/dist/modules/order/utils/timeout.js +1 -4
- package/dist/modules/order/utils/timeout.js.map +1 -1
- package/dist/modules/order/utils/validate.js +91 -142
- package/dist/modules/order/utils/validate.js.map +1 -1
- package/dist/modules/order/utils/withPoolRef.js +21 -61
- package/dist/modules/order/utils/withPoolRef.js.map +1 -1
- package/dist/modules/order/working_grid.js +6 -9
- package/dist/modules/order/working_grid.js.map +1 -1
- package/dist/modules/path_api.d.ts.map +1 -1
- package/dist/modules/path_api.js +8 -11
- package/dist/modules/path_api.js.map +1 -1
- package/dist/modules/paths.d.ts.map +1 -1
- package/dist/modules/paths.js +61 -67
- package/dist/modules/paths.js.map +1 -1
- package/dist/modules/process_discovery.d.ts.map +1 -1
- package/dist/modules/process_discovery.js +14 -23
- package/dist/modules/process_discovery.js.map +1 -1
- package/dist/modules/runtime.js +7 -11
- package/dist/modules/runtime.js.map +1 -1
- package/dist/modules/runtime_settings.d.ts.map +1 -1
- package/dist/modules/runtime_settings.js +14 -16
- package/dist/modules/runtime_settings.js.map +1 -1
- package/dist/modules/settings_merge.js +1 -3
- package/dist/modules/settings_merge.js.map +1 -1
- package/dist/modules/socket_json_client.js +3 -5
- package/dist/modules/socket_json_client.js.map +1 -1
- package/dist/modules/storage/browser_adapter.js +1 -4
- package/dist/modules/storage/browser_adapter.js.map +1 -1
- package/dist/modules/storage/index.d.ts +3 -2
- package/dist/modules/storage/index.d.ts.map +1 -1
- package/dist/modules/storage/index.js +5 -8
- package/dist/modules/storage/index.js.map +1 -1
- package/dist/modules/storage/node_adapter.d.ts +3 -4
- package/dist/modules/storage/node_adapter.d.ts.map +1 -1
- package/dist/modules/storage/node_adapter.js +12 -16
- package/dist/modules/storage/node_adapter.js.map +1 -1
- package/dist/modules/storage/types.js +1 -2
- package/dist/modules/types.d.ts +0 -6
- package/dist/modules/types.d.ts.map +1 -1
- package/dist/modules/types.js +1 -2
- package/dist/modules/types.js.map +1 -1
- package/dist/modules/utils/base58check.js +8 -15
- package/dist/modules/utils/base58check.js.map +1 -1
- package/dist/modules/utils/build_dir.js +3 -7
- package/dist/modules/utils/build_dir.js.map +1 -1
- package/dist/modules/utils/errors.js +1 -5
- package/dist/modules/utils/errors.js.map +1 -1
- package/dist/modules/utils/math_utils.d.ts +1 -1
- package/dist/modules/utils/math_utils.d.ts.map +1 -1
- package/dist/modules/utils/math_utils.js +2 -7
- package/dist/modules/utils/math_utils.js.map +1 -1
- package/dist/modules/validate_profiles.d.ts.map +1 -1
- package/dist/modules/validate_profiles.js +18 -25
- package/dist/modules/validate_profiles.js.map +1 -1
- package/dist/pm2.d.ts +4 -70
- package/dist/pm2.d.ts.map +1 -1
- package/dist/pm2.js +106 -132
- package/dist/pm2.js.map +1 -1
- package/dist/scripts/analyze-git.js +13 -17
- package/dist/scripts/analyze-git.js.map +1 -1
- package/dist/scripts/analyze-orders.d.ts.map +1 -1
- package/dist/scripts/analyze-orders.js +48 -63
- package/dist/scripts/analyze-orders.js.map +1 -1
- package/dist/scripts/diagnose-kibana-candles.d.ts.map +1 -1
- package/dist/scripts/diagnose-kibana-candles.js +2 -1
- package/dist/scripts/diagnose-kibana-candles.js.map +1 -1
- package/dist/scripts/diagnose-pool-history.d.ts.map +1 -1
- package/dist/scripts/diagnose-pool-history.js +2 -1
- package/dist/scripts/diagnose-pool-history.js.map +1 -1
- package/dist/scripts/divergence-calc.d.ts.map +1 -1
- package/dist/scripts/divergence-calc.js +2 -2
- package/dist/scripts/divergence-calc.js.map +1 -1
- package/dist/scripts/fix-err-message.js +17 -22
- package/dist/scripts/fix-err-message.js.map +1 -1
- package/dist/scripts/generate_lp_chart.d.ts.map +1 -1
- package/dist/scripts/generate_lp_chart.js +7 -15
- package/dist/scripts/generate_lp_chart.js.map +1 -1
- package/dist/scripts/generate_mainnet_corpus_report.d.ts.map +1 -1
- package/dist/scripts/generate_mainnet_corpus_report.js +3 -2
- package/dist/scripts/generate_mainnet_corpus_report.js.map +1 -1
- package/dist/scripts/generate_market_adapter_whitelist.d.ts.map +1 -1
- package/dist/scripts/generate_market_adapter_whitelist.js +18 -24
- package/dist/scripts/generate_market_adapter_whitelist.js.map +1 -1
- package/dist/scripts/native_release_gates.js +15 -19
- package/dist/scripts/native_release_gates.js.map +1 -1
- package/dist/scripts/print_grid.d.ts.map +1 -1
- package/dist/scripts/print_grid.js +2 -2
- package/dist/scripts/print_grid.js.map +1 -1
- package/dist/scripts/run-tests.js +12 -17
- package/dist/scripts/run-tests.js.map +1 -1
- package/dist/scripts/runner.d.ts.map +1 -1
- package/dist/scripts/runner.js +18 -20
- package/dist/scripts/runner.js.map +1 -1
- package/dist/scripts/sync-version.js +2 -2
- package/dist/scripts/sync-version.js.map +1 -1
- package/dist/scripts/test-credit-renewal.d.ts.map +1 -1
- package/dist/scripts/test-credit-renewal.js +4 -3
- package/dist/scripts/test-credit-renewal.js.map +1 -1
- package/dist/scripts/update.js +93 -95
- package/dist/scripts/update.js.map +1 -1
- package/dist/scripts/validate_bots.d.ts.map +1 -1
- package/dist/scripts/validate_bots.js +2 -2
- package/dist/scripts/validate_bots.js.map +1 -1
- package/dist/scripts/verify-browser-bundle.js +12 -17
- package/dist/scripts/verify-browser-bundle.js.map +1 -1
- package/dist/unlock.d.ts +0 -30
- package/dist/unlock.d.ts.map +1 -1
- package/dist/unlock.js +258 -222
- package/dist/unlock.js.map +1 -1
- package/package.json +5 -8
- package/scripts/README.md +1 -1
- package/scripts/create-bot-symlinks.sh +2 -2
- package/dist/modules/utils/fs_utils.d.ts +0 -18
- package/dist/modules/utils/fs_utils.d.ts.map +0 -1
- package/dist/modules/utils/fs_utils.js +0 -32
- package/dist/modules/utils/fs_utils.js.map +0 -1
- package/dist/scripts/migrate_bot_keys.d.ts +0 -3
- package/dist/scripts/migrate_bot_keys.d.ts.map +0 -1
- package/dist/scripts/migrate_bot_keys.js +0 -225
- package/dist/scripts/migrate_bot_keys.js.map +0 -1
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* modules/order/sync_engine.ts - SyncEngine
|
|
4
3
|
*
|
|
@@ -94,71 +93,37 @@
|
|
|
94
93
|
*
|
|
95
94
|
* ===============================================================================
|
|
96
95
|
*/
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}
|
|
103
|
-
Object.defineProperty(o, k2, desc);
|
|
104
|
-
}) : (function(o, m, k, k2) {
|
|
105
|
-
if (k2 === undefined) k2 = k;
|
|
106
|
-
o[k2] = m[k];
|
|
107
|
-
}));
|
|
108
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
109
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
110
|
-
}) : function(o, v) {
|
|
111
|
-
o["default"] = v;
|
|
112
|
-
});
|
|
113
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
114
|
-
var ownKeys = function(o) {
|
|
115
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
116
|
-
var ar = [];
|
|
117
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
118
|
-
return ar;
|
|
119
|
-
};
|
|
120
|
-
return ownKeys(o);
|
|
121
|
-
};
|
|
122
|
-
return function (mod) {
|
|
123
|
-
if (mod && mod.__esModule) return mod;
|
|
124
|
-
var result = {};
|
|
125
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
126
|
-
__setModuleDefault(result, mod);
|
|
127
|
-
return result;
|
|
128
|
-
};
|
|
129
|
-
})();
|
|
130
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
131
|
-
const constants_1 = require("../constants");
|
|
132
|
-
const Format = __importStar(require("./format"));
|
|
133
|
-
const system_1 = require("./utils/system");
|
|
134
|
-
const chainOrders = __importStar(require("../chain_orders"));
|
|
135
|
-
const client = __importStar(require("../bitshares_client"));
|
|
96
|
+
import { ORDER_TYPES, ORDER_STATES, TIMING, BTS_PRECISION } from '../constants.js';
|
|
97
|
+
import * as Format from './format.js';
|
|
98
|
+
import { lookupAsset } from './utils/system.js';
|
|
99
|
+
import * as chainOrders from '../chain_orders.js';
|
|
100
|
+
import * as client from '../bitshares_client.js';
|
|
136
101
|
const { BitShares } = client;
|
|
137
|
-
|
|
102
|
+
import { NATIVE_CLIENT } from '../constants.js';
|
|
138
103
|
const { toFiniteNumber } = Format;
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
104
|
+
import { blockchainToFloat, floatToBlockchainInt, calculatePriceTolerance, getAssetFees, getBtsSide } from './utils/math.js';
|
|
105
|
+
import { parseChainOrder, findMatchingGridOrderByOpenOrder, applyChainSizeToGridOrder, convertToSpreadPlaceholder, virtualizeOrder, buildFillKey, isOrderPlaced, hasOnChainId, isOrderVirtual, resolveSpreadOrderSide, duplicateOrphanLogInfo } from './utils/order.js';
|
|
106
|
+
import { resolveProcessedFillPersistenceMode } from './processed_fill_store.js';
|
|
107
|
+
import { getErrorMessage } from '../utils/errors.js';
|
|
143
108
|
function describeNearestAdoptionCandidates(mgr, chainOrder, precision, calcTolerance, matchedGridOrderIds = null) {
|
|
144
109
|
if (!mgr?.orders || !chainOrder || typeof precision !== 'number')
|
|
145
110
|
return 'candidate diagnostics unavailable';
|
|
146
111
|
const chainPrice = toFiniteNumber(chainOrder.price);
|
|
147
112
|
const chainSize = toFiniteNumber(chainOrder.size);
|
|
148
|
-
const chainInt =
|
|
113
|
+
const chainInt = floatToBlockchainInt(chainSize, precision);
|
|
149
114
|
const candidates = [];
|
|
150
115
|
for (const slot of mgr.orders.values()) {
|
|
151
|
-
if (!slot || ![
|
|
116
|
+
if (!slot || ![ORDER_STATES.ACTIVE, ORDER_STATES.PARTIAL, ORDER_STATES.VIRTUAL].includes(slot.state))
|
|
152
117
|
continue;
|
|
153
118
|
const typeMatch = slot.type === chainOrder.type;
|
|
154
|
-
const spreadMatch = slot.type ===
|
|
119
|
+
const spreadMatch = slot.type === ORDER_TYPES.SPREAD;
|
|
155
120
|
if (!typeMatch && !spreadMatch)
|
|
156
121
|
continue;
|
|
157
122
|
const price = toFiniteNumber(slot.price);
|
|
158
123
|
const priceDiff = Math.abs(price - chainPrice);
|
|
159
124
|
const effectiveSize = slot.size > 0 ? toFiniteNumber(slot.size) : chainSize;
|
|
160
125
|
const tolerance = calcTolerance(price, effectiveSize, chainOrder.type) || 0;
|
|
161
|
-
const gridInt =
|
|
126
|
+
const gridInt = floatToBlockchainInt(toFiniteNumber(slot.size), precision);
|
|
162
127
|
const sizeDiffInt = chainInt - gridInt;
|
|
163
128
|
const hasOrderId = Boolean(slot.orderId);
|
|
164
129
|
const alreadyMatched = Boolean(matchedGridOrderIds?.has?.(slot.id));
|
|
@@ -239,17 +204,17 @@ function computeOutOfToleranceDriftTag(mgr, chainOrder, calcToleranceFn) {
|
|
|
239
204
|
return null;
|
|
240
205
|
const chainSize = toFiniteNumber(chainOrder.size);
|
|
241
206
|
const orderType = chainOrder.type;
|
|
242
|
-
if (orderType !==
|
|
207
|
+
if (orderType !== ORDER_TYPES.BUY && orderType !== ORDER_TYPES.SELL)
|
|
243
208
|
return null;
|
|
244
209
|
let bestDrift = null;
|
|
245
210
|
for (const slot of mgr.orders.values()) {
|
|
246
211
|
if (!slot)
|
|
247
212
|
continue;
|
|
248
|
-
if (slot.type !== orderType && slot.type !==
|
|
213
|
+
if (slot.type !== orderType && slot.type !== ORDER_TYPES.SPREAD)
|
|
249
214
|
continue;
|
|
250
215
|
if (slot.orderId)
|
|
251
216
|
continue;
|
|
252
|
-
if (![
|
|
217
|
+
if (![ORDER_STATES.ACTIVE, ORDER_STATES.PARTIAL, ORDER_STATES.VIRTUAL].includes(slot.state))
|
|
253
218
|
continue;
|
|
254
219
|
const slotPrice = toFiniteNumber(slot.price);
|
|
255
220
|
if (!Number.isFinite(slotPrice))
|
|
@@ -359,17 +324,18 @@ class SyncEngine {
|
|
|
359
324
|
mgr.logger?.log?.('Error: syncLock not initialized', 'error');
|
|
360
325
|
return { filledOrders: [], updatedOrders: [], ordersNeedingCorrection: [], unmatchedChainOrders: [] };
|
|
361
326
|
}
|
|
362
|
-
//
|
|
363
|
-
//
|
|
364
|
-
//
|
|
365
|
-
//
|
|
327
|
+
// CRITICAL: The gate below is the recursion breaker. syncFromOpenOrders
|
|
328
|
+
// re-invokes itself as the acquire() callback, so without this check the
|
|
329
|
+
// acquire() re-entrant short-circuit alone would recurse forever (each
|
|
330
|
+
// nested call is re-entrant and runs the body again). Only run through
|
|
331
|
+
// the lock when the caller does NOT already hold it.
|
|
366
332
|
if (mgr._fillProcessingLock && !mgr._fillProcessingLock.isReentrant()) {
|
|
367
333
|
return mgr._fillProcessingLock.acquire(async () => {
|
|
368
334
|
return this.syncFromOpenOrders(chainOrders, options);
|
|
369
335
|
});
|
|
370
336
|
}
|
|
371
|
-
const timeoutMs =
|
|
372
|
-
const forceReleaseMs =
|
|
337
|
+
const timeoutMs = TIMING.SYNC_LOCK_TIMEOUT_MS;
|
|
338
|
+
const forceReleaseMs = TIMING.SYNC_LOCK_FORCE_RELEASE_AGE_MS;
|
|
373
339
|
let timedOut = false;
|
|
374
340
|
let timeoutHandle;
|
|
375
341
|
let forceReleaseHandle;
|
|
@@ -401,7 +367,7 @@ class SyncEngine {
|
|
|
401
367
|
await mgr.fetchAccountTotals(mgr.accountId || mgr.config?.accountId);
|
|
402
368
|
}
|
|
403
369
|
catch (fetchErr) {
|
|
404
|
-
mgr.logger?.log?.(`[SYNC] Stale-totals refresh failed: ${
|
|
370
|
+
mgr.logger?.log?.(`[SYNC] Stale-totals refresh failed: ${getErrorMessage(fetchErr)}`, 'warn');
|
|
405
371
|
}
|
|
406
372
|
}
|
|
407
373
|
const innerResult = await this._doSyncFromOpenOrders(chainOrders, options);
|
|
@@ -449,7 +415,7 @@ class SyncEngine {
|
|
|
449
415
|
catch (err) {
|
|
450
416
|
clearTimeout(timeoutHandle);
|
|
451
417
|
clearTimeout(forceReleaseHandle);
|
|
452
|
-
if (
|
|
418
|
+
if (getErrorMessage(err)?.includes('timed out')) {
|
|
453
419
|
// Gap 3: Schedule a force-release of the sync lock if the inner
|
|
454
420
|
// operation doesn't complete within the grace window. This prevents
|
|
455
421
|
// a single stuck sync from permanently blocking all subsequent syncs.
|
|
@@ -466,7 +432,7 @@ class SyncEngine {
|
|
|
466
432
|
}
|
|
467
433
|
mgr.logger?.log?.('[SYNC] Lock may be held by orphan after timeout; will release when inner work completes', 'warn');
|
|
468
434
|
}
|
|
469
|
-
mgr.logger?.log?.(`Sync lock error: ${
|
|
435
|
+
mgr.logger?.log?.(`Sync lock error: ${getErrorMessage(err)}`, 'error');
|
|
470
436
|
throw err;
|
|
471
437
|
}
|
|
472
438
|
}
|
|
@@ -530,7 +496,7 @@ class SyncEngine {
|
|
|
530
496
|
const rawChainOrders = new Map();
|
|
531
497
|
for (const order of chainOrders) {
|
|
532
498
|
try {
|
|
533
|
-
const parsed =
|
|
499
|
+
const parsed = parseChainOrder(order, mgr.assets);
|
|
534
500
|
if (!parsed)
|
|
535
501
|
continue;
|
|
536
502
|
// Store parsed (converted) data in parsedChainOrders
|
|
@@ -539,7 +505,7 @@ class SyncEngine {
|
|
|
539
505
|
rawChainOrders.set(order.id, order);
|
|
540
506
|
}
|
|
541
507
|
catch (e) {
|
|
542
|
-
mgr.logger?.log?.(`Warning: Error parsing chain order ${order.id}: ${
|
|
508
|
+
mgr.logger?.log?.(`Warning: Error parsing chain order ${order.id}: ${getErrorMessage(e)}`, 'warn');
|
|
543
509
|
continue;
|
|
544
510
|
}
|
|
545
511
|
}
|
|
@@ -554,7 +520,7 @@ class SyncEngine {
|
|
|
554
520
|
orderIdsToLock.add(gridOrder.orderId);
|
|
555
521
|
}
|
|
556
522
|
// Also lock ACTIVE/PARTIAL orders that might transition to/from SPREAD
|
|
557
|
-
if (gridOrder.state ===
|
|
523
|
+
if (gridOrder.state === ORDER_STATES.ACTIVE || gridOrder.state === ORDER_STATES.PARTIAL) {
|
|
558
524
|
orderIdsToLock.add(gridOrder.id);
|
|
559
525
|
}
|
|
560
526
|
}
|
|
@@ -582,9 +548,9 @@ class SyncEngine {
|
|
|
582
548
|
// Lock orders before reconciliation
|
|
583
549
|
mgr.lockOrders(orderIdsToLockFinal);
|
|
584
550
|
// Keep lock leases alive during long reconciliation runs.
|
|
585
|
-
const refreshEveryMs = Math.max(
|
|
551
|
+
const refreshEveryMs = Math.max(TIMING.LOCK_REFRESH_MIN_MS, Math.floor(TIMING.LOCK_TIMEOUT_MS / 3));
|
|
586
552
|
const refreshLockLeases = () => {
|
|
587
|
-
const expiresAt = Date.now() +
|
|
553
|
+
const expiresAt = Date.now() + TIMING.LOCK_TIMEOUT_MS;
|
|
588
554
|
for (const id of orderIdsToLockFinal) {
|
|
589
555
|
mgr.shadowOrderIds.set(id, expiresAt);
|
|
590
556
|
}
|
|
@@ -680,7 +646,7 @@ class SyncEngine {
|
|
|
680
646
|
continue;
|
|
681
647
|
}
|
|
682
648
|
else {
|
|
683
|
-
const priceTolerance =
|
|
649
|
+
const priceTolerance = calculatePriceTolerance(gridOrder.price, gridOrder.size, gridOrder.type, mgr.assets);
|
|
684
650
|
const normalizedTolerance = (priceTolerance === null) ? 0 : priceTolerance;
|
|
685
651
|
// Null tolerance is strict mode (0).
|
|
686
652
|
if (Math.abs(chainOrder.price - gridOrder.price) > normalizedTolerance) {
|
|
@@ -695,14 +661,14 @@ class SyncEngine {
|
|
|
695
661
|
}
|
|
696
662
|
}
|
|
697
663
|
// Chain side determines which precision applies to for_sale.
|
|
698
|
-
const precision = (chainOrder.type ===
|
|
699
|
-
const currentSizeInt =
|
|
700
|
-
const chainSizeInt =
|
|
664
|
+
const precision = (chainOrder.type === ORDER_TYPES.SELL) ? assetAPrecision : assetBPrecision;
|
|
665
|
+
const currentSizeInt = floatToBlockchainInt(gridOrder.size, precision);
|
|
666
|
+
const chainSizeInt = floatToBlockchainInt(chainOrder.size, precision);
|
|
701
667
|
if (currentSizeInt !== chainSizeInt) {
|
|
702
|
-
const newSize =
|
|
703
|
-
const newInt =
|
|
668
|
+
const newSize = blockchainToFloat(chainSizeInt, precision);
|
|
669
|
+
const newInt = floatToBlockchainInt(newSize, precision);
|
|
704
670
|
if (newInt > 0) {
|
|
705
|
-
const nextOrder = await
|
|
671
|
+
const nextOrder = await applyChainSizeToGridOrder(mgr, updatedOrder, newSize);
|
|
706
672
|
if (nextOrder) {
|
|
707
673
|
// Merge updated state if size actually changed
|
|
708
674
|
updatedOrder = { ...updatedOrder, ...nextOrder };
|
|
@@ -712,12 +678,12 @@ class SyncEngine {
|
|
|
712
678
|
// downtime fills detected during open-orders sync must also update
|
|
713
679
|
// state so that checkWindowDust can identify dust orders.
|
|
714
680
|
updatedOrder.state = (chainSizeInt < currentSizeInt)
|
|
715
|
-
?
|
|
681
|
+
? ORDER_STATES.PARTIAL
|
|
716
682
|
: gridOrder.state;
|
|
717
683
|
await mgr._applyOrderUpdate(updatedOrder, 'sync-pass1-partial', { skipAccounting: skipAccounting, fee: 0 });
|
|
718
684
|
}
|
|
719
685
|
else {
|
|
720
|
-
const spreadOrder =
|
|
686
|
+
const spreadOrder = convertToSpreadPlaceholder(gridOrder);
|
|
721
687
|
await mgr._applyOrderUpdate(spreadOrder, 'sync-pass1-filled', { skipAccounting: skipAccounting, fee: 0 });
|
|
722
688
|
// Push the filled order with its REAL side (chain order
|
|
723
689
|
// type), not the SPREAD placeholder: downstream fill
|
|
@@ -729,19 +695,19 @@ class SyncEngine {
|
|
|
729
695
|
}
|
|
730
696
|
}
|
|
731
697
|
}
|
|
732
|
-
else if (gridOrder.state ===
|
|
698
|
+
else if (gridOrder.state === ORDER_STATES.ACTIVE || gridOrder.state === ORDER_STATES.PARTIAL) {
|
|
733
699
|
// Don't virtualize orders placed by a successful COW commit.
|
|
734
700
|
// The chain snapshot may lag behind confirmed transactions,
|
|
735
701
|
// causing correctly-placed orders to appear missing. _committedOrderIds
|
|
736
702
|
// is atomically rebuilt from every successful COW commit
|
|
737
|
-
// (manager.ts:
|
|
703
|
+
// (manager.ts:_commitWorkingGrid) and is always active for all sync
|
|
738
704
|
// paths — previously gated on options.protectCommittedOrders.
|
|
739
705
|
// Always-on is safe because committed IDs are self-cleaning:
|
|
740
706
|
// filled/virtualized orders are absent from the next commit's
|
|
741
707
|
// finalMap, so their IDs drop out on the next atomic rebuild.
|
|
742
708
|
//
|
|
743
709
|
// SAFETY: _committedOrderIds is replaced atomically (reference swap)
|
|
744
|
-
// by
|
|
710
|
+
// by _commitWorkingGrid. The sync reads has(gridOrder.orderId) against the
|
|
745
711
|
// current reference. If a concurrent COW commit replaces the set mid-sync,
|
|
746
712
|
// the new set is a superset (only adds entries for newly committed orders).
|
|
747
713
|
// An order in the superset was just committed, so it is genuinely on-chain
|
|
@@ -765,14 +731,14 @@ class SyncEngine {
|
|
|
765
731
|
// this open-orders sync.
|
|
766
732
|
if (mgr._committedOrderIds?.has(gridOrder.orderId)) {
|
|
767
733
|
const commitAge = Date.now() - (mgr._committedOrderIdsBuiltAt || 0);
|
|
768
|
-
const isGhost = gridOrder.size <= 0 && gridOrder.state ===
|
|
769
|
-
if (!isGhost && commitAge <
|
|
734
|
+
const isGhost = gridOrder.size <= 0 && gridOrder.state === ORDER_STATES.PARTIAL;
|
|
735
|
+
if (!isGhost && commitAge < TIMING.SYNC_LOCK_TIMEOUT_MS) {
|
|
770
736
|
continue;
|
|
771
737
|
}
|
|
772
738
|
}
|
|
773
739
|
const currentGridOrder = mgr.orders.get(gridOrder.id) || gridOrder;
|
|
774
740
|
const hadOrderId = Boolean(currentGridOrder?.orderId);
|
|
775
|
-
const spreadOrder =
|
|
741
|
+
const spreadOrder = convertToSpreadPlaceholder(currentGridOrder);
|
|
776
742
|
await mgr._applyOrderUpdate(spreadOrder, 'sync-cleanup-phantom', { skipAccounting: skipAccounting, fee: 0 });
|
|
777
743
|
// Only genuine disappearances (had orderId) count as fills.
|
|
778
744
|
if (hadOrderId) {
|
|
@@ -784,8 +750,8 @@ class SyncEngine {
|
|
|
784
750
|
// as the funds check (manager.ts) since no chain order remains
|
|
785
751
|
// to resolve the side from.
|
|
786
752
|
let resolvedType = currentGridOrder.type;
|
|
787
|
-
if (resolvedType ===
|
|
788
|
-
resolvedType =
|
|
753
|
+
if (resolvedType === ORDER_TYPES.SPREAD) {
|
|
754
|
+
resolvedType = resolveSpreadOrderSide(currentGridOrder.price, mgr.config.startPrice);
|
|
789
755
|
}
|
|
790
756
|
filledOrders.push({ ...currentGridOrder, type: resolvedType });
|
|
791
757
|
}
|
|
@@ -807,9 +773,9 @@ class SyncEngine {
|
|
|
807
773
|
const duplicatePriceOrder = Array.from(mgr.orders.values()).find((o) => {
|
|
808
774
|
const co = chainOrder;
|
|
809
775
|
return o.type === co.type &&
|
|
810
|
-
|
|
776
|
+
isOrderPlaced(o) &&
|
|
811
777
|
co != null &&
|
|
812
|
-
Math.abs(o.price - co.price) <=
|
|
778
|
+
Math.abs(o.price - co.price) <= calculatePriceTolerance(Math.min(o.price, co.price), Math.max(o.size, co.size), o.type, mgr.assets);
|
|
813
779
|
});
|
|
814
780
|
if (duplicatePriceOrder) {
|
|
815
781
|
unmatchedChainOrders.push({
|
|
@@ -821,9 +787,10 @@ class SyncEngine {
|
|
|
821
787
|
reason: 'duplicate-price-level',
|
|
822
788
|
candidateSlotId: duplicatePriceOrder.id,
|
|
823
789
|
});
|
|
790
|
+
const { level, suffix } = duplicateOrphanLogInfo(chainOrderId);
|
|
824
791
|
mgr.logger?.log?.(`[SYNC] Orphaned chain order ${chainOrderId} (${chainOrder.type}, price=${chainOrder.price}, ` +
|
|
825
792
|
`size=${chainOrder.size}) — NOT adopted: duplicates price level of active ` +
|
|
826
|
-
`${duplicatePriceOrder.id} (${duplicatePriceOrder.orderId} at ${duplicatePriceOrder.price})`,
|
|
793
|
+
`${duplicatePriceOrder.id} (${duplicatePriceOrder.orderId} at ${duplicatePriceOrder.price})${suffix}`, level);
|
|
827
794
|
// Gap 2: Queue duplicate chain order for cancellation via the correction
|
|
828
795
|
// mechanism (called from _performSyncFromOpenOrders). Duplicate price levels
|
|
829
796
|
// block new placements. Cancelling proactively unblocks CREATEs.
|
|
@@ -838,10 +805,10 @@ class SyncEngine {
|
|
|
838
805
|
});
|
|
839
806
|
continue;
|
|
840
807
|
}
|
|
841
|
-
const match =
|
|
808
|
+
const match = findMatchingGridOrderByOpenOrder({ orderId: chainOrderId, type: chainOrder.type, price: chainOrder.price, size: chainOrder.size }, {
|
|
842
809
|
orders: mgr.orders,
|
|
843
810
|
assets: mgr.assets,
|
|
844
|
-
calcToleranceFn: (p, s, t) =>
|
|
811
|
+
calcToleranceFn: (p, s, t) => calculatePriceTolerance(p, s, t, mgr.assets),
|
|
845
812
|
logger: mgr.logger,
|
|
846
813
|
allowSmallerChainSize: true,
|
|
847
814
|
requireAvailableSlot: true,
|
|
@@ -849,10 +816,10 @@ class SyncEngine {
|
|
|
849
816
|
});
|
|
850
817
|
if (match && !matchedGridOrderIds.has(match.id)) {
|
|
851
818
|
let bestMatch = { ...match };
|
|
852
|
-
const wasVirtual = match.state ===
|
|
853
|
-
const wasPartial = match.state ===
|
|
819
|
+
const wasVirtual = match.state === ORDER_STATES.VIRTUAL;
|
|
820
|
+
const wasPartial = match.state === ORDER_STATES.PARTIAL;
|
|
854
821
|
bestMatch.orderId = chainOrderId;
|
|
855
|
-
bestMatch.state = wasVirtual ?
|
|
822
|
+
bestMatch.state = wasVirtual ? ORDER_STATES.ACTIVE : match.state;
|
|
856
823
|
const bestMatchRaw = rawChainOrders.get(chainOrderId);
|
|
857
824
|
bestMatch.rawOnChain = bestMatchRaw
|
|
858
825
|
? { ...bestMatchRaw, fetchedAt: Date.now() }
|
|
@@ -869,41 +836,41 @@ class SyncEngine {
|
|
|
869
836
|
if (bestMatch.rawOnChain) {
|
|
870
837
|
const rawDeferredFee = toFiniteNumber(bestMatch.rawOnChain.deferred_fee, undefined);
|
|
871
838
|
if (rawDeferredFee !== null && rawDeferredFee > 0) {
|
|
872
|
-
bestMatch.btsFeeState = { deferredFee:
|
|
839
|
+
bestMatch.btsFeeState = { deferredFee: blockchainToFloat(rawDeferredFee, BTS_PRECISION) };
|
|
873
840
|
}
|
|
874
841
|
else if (wasVirtual && rawDeferredFee !== null && rawDeferredFee <= 0 && bestMatch.rawOnChain.for_sale > 0) {
|
|
875
842
|
// Core zeros deferred_fee on every fill (fill_limit_order db_market.cpp:1895).
|
|
876
843
|
// If deferred_fee is 0 while for_sale > 0, the order was partially filled.
|
|
877
|
-
bestMatch.state =
|
|
844
|
+
bestMatch.state = ORDER_STATES.PARTIAL;
|
|
878
845
|
}
|
|
879
846
|
}
|
|
880
|
-
const precision = (bestMatch.type ===
|
|
881
|
-
const targetInt =
|
|
882
|
-
const chainInt =
|
|
847
|
+
const precision = (bestMatch.type === ORDER_TYPES.SELL) ? assetAPrecision : assetBPrecision;
|
|
848
|
+
const targetInt = floatToBlockchainInt(match.size, precision);
|
|
849
|
+
const chainInt = floatToBlockchainInt(chainOrder.size, precision);
|
|
883
850
|
if (targetInt !== chainInt) {
|
|
884
|
-
const updated = await
|
|
851
|
+
const updated = await applyChainSizeToGridOrder(mgr, bestMatch, chainOrder.size);
|
|
885
852
|
if (updated)
|
|
886
853
|
bestMatch = { ...bestMatch, ...updated };
|
|
887
854
|
if (chainInt > 0) {
|
|
888
855
|
if (wasVirtual) {
|
|
889
856
|
// Only override to ACTIVE if partial-fill check above didn't already
|
|
890
857
|
// set PARTIAL via deferred_fee === 0. Skip override to preserve signal.
|
|
891
|
-
if (bestMatch.state !==
|
|
892
|
-
bestMatch.state =
|
|
858
|
+
if (bestMatch.state !== ORDER_STATES.PARTIAL) {
|
|
859
|
+
bestMatch.state = ORDER_STATES.ACTIVE;
|
|
893
860
|
}
|
|
894
861
|
}
|
|
895
862
|
else if (chainInt < targetInt) {
|
|
896
|
-
bestMatch.state =
|
|
863
|
+
bestMatch.state = ORDER_STATES.PARTIAL;
|
|
897
864
|
}
|
|
898
865
|
else if (wasPartial) {
|
|
899
|
-
bestMatch.state =
|
|
866
|
+
bestMatch.state = ORDER_STATES.PARTIAL;
|
|
900
867
|
}
|
|
901
868
|
else {
|
|
902
|
-
bestMatch.state =
|
|
869
|
+
bestMatch.state = ORDER_STATES.ACTIVE;
|
|
903
870
|
}
|
|
904
871
|
}
|
|
905
872
|
else {
|
|
906
|
-
const spreadOrder =
|
|
873
|
+
const spreadOrder = convertToSpreadPlaceholder(bestMatch);
|
|
907
874
|
filledOrders.push({ ...bestMatch });
|
|
908
875
|
await mgr._applyOrderUpdate(spreadOrder, 'sync-pass2-filled', { skipAccounting: skipAccounting, fee: 0 });
|
|
909
876
|
updatedOrders.push(spreadOrder);
|
|
@@ -912,7 +879,7 @@ class SyncEngine {
|
|
|
912
879
|
}
|
|
913
880
|
}
|
|
914
881
|
else if (wasPartial) {
|
|
915
|
-
bestMatch.state =
|
|
882
|
+
bestMatch.state = ORDER_STATES.PARTIAL;
|
|
916
883
|
}
|
|
917
884
|
await mgr._applyOrderUpdate(bestMatch, 'sync-pass2-orphan', { skipAccounting: skipAccounting, fee: 0 });
|
|
918
885
|
updatedOrders.push(bestMatch);
|
|
@@ -949,23 +916,23 @@ class SyncEngine {
|
|
|
949
916
|
// orphan becomes visible to checkWindowDust for dust auto-cancel.
|
|
950
917
|
// The duplicate-price-level guard already ran above so it is not
|
|
951
918
|
// repeated here.
|
|
952
|
-
const adoptedSlot =
|
|
919
|
+
const adoptedSlot = findMatchingGridOrderByOpenOrder({ orderId: chainOrderId, type: chainOrder.type, price: chainOrder.price, size: chainOrder.size }, {
|
|
953
920
|
orders: mgr.orders,
|
|
954
921
|
assets: mgr.assets,
|
|
955
|
-
calcToleranceFn: (p, s, t) =>
|
|
922
|
+
calcToleranceFn: (p, s, t) => calculatePriceTolerance(p, s, t, mgr.assets),
|
|
956
923
|
allowSpreadType: true,
|
|
957
924
|
skipSizeMatch: true,
|
|
958
925
|
requireAvailableSlot: true,
|
|
959
926
|
excludeGridOrderIds: matchedGridOrderIds
|
|
960
927
|
});
|
|
961
928
|
if (adoptedSlot && !matchedGridOrderIds.has(adoptedSlot.id) && !adoptedSlot.orderId) {
|
|
962
|
-
const precision = (chainOrder.type ===
|
|
963
|
-
const chainInt =
|
|
929
|
+
const precision = (chainOrder.type === ORDER_TYPES.SELL) ? assetAPrecision : assetBPrecision;
|
|
930
|
+
const chainInt = floatToBlockchainInt(chainOrder.size, precision);
|
|
964
931
|
const adoptedRaw = rawChainOrders.get(chainOrderId);
|
|
965
|
-
const adoptedState = chainInt > 0 ?
|
|
932
|
+
const adoptedState = chainInt > 0 ? ORDER_STATES.PARTIAL : ORDER_STATES.VIRTUAL;
|
|
966
933
|
const adoptedBtsFeeState = (adoptedRaw) ? (() => {
|
|
967
934
|
const rawFee = toFiniteNumber(adoptedRaw.deferred_fee, undefined);
|
|
968
|
-
return rawFee !== null && rawFee > 0 ? { deferredFee:
|
|
935
|
+
return rawFee !== null && rawFee > 0 ? { deferredFee: blockchainToFloat(rawFee, BTS_PRECISION) } : undefined;
|
|
969
936
|
})() : undefined;
|
|
970
937
|
const adoptedOrder = {
|
|
971
938
|
...adoptedSlot,
|
|
@@ -987,9 +954,9 @@ class SyncEngine {
|
|
|
987
954
|
`size=${chainOrder.size}) adopted into slot ${adoptedSlot.id} (was ${adoptedSlot.type})`, 'warn');
|
|
988
955
|
}
|
|
989
956
|
else {
|
|
990
|
-
const precision = (chainOrder.type ===
|
|
991
|
-
const candidateDiagnostics = describeNearestAdoptionCandidates(mgr, chainOrder, precision, (p, s, t) =>
|
|
992
|
-
const driftTag = computeOutOfToleranceDriftTag(mgr, chainOrder, (p, s, t) =>
|
|
957
|
+
const precision = (chainOrder.type === ORDER_TYPES.SELL) ? assetAPrecision : assetBPrecision;
|
|
958
|
+
const candidateDiagnostics = describeNearestAdoptionCandidates(mgr, chainOrder, precision, (p, s, t) => calculatePriceTolerance(p, s, t, mgr.assets), matchedGridOrderIds);
|
|
959
|
+
const driftTag = computeOutOfToleranceDriftTag(mgr, chainOrder, (p, s, t) => calculatePriceTolerance(p, s, t, mgr.assets));
|
|
993
960
|
const unmatchedEntry = {
|
|
994
961
|
chainOrderId,
|
|
995
962
|
type: chainOrder.type,
|
|
@@ -1021,7 +988,7 @@ class SyncEngine {
|
|
|
1021
988
|
// ------------------------------------------------------------------
|
|
1022
989
|
_findMatchingGridOrder(mgr, orderId) {
|
|
1023
990
|
for (const gridOrder of mgr.orders.values()) {
|
|
1024
|
-
if (gridOrder.orderId === orderId && (gridOrder.state ===
|
|
991
|
+
if (gridOrder.orderId === orderId && (gridOrder.state === ORDER_STATES.ACTIVE || gridOrder.state === ORDER_STATES.PARTIAL)) {
|
|
1025
992
|
return gridOrder;
|
|
1026
993
|
}
|
|
1027
994
|
}
|
|
@@ -1036,26 +1003,26 @@ class SyncEngine {
|
|
|
1036
1003
|
// the price-vs-startPrice convention so the type can never leak SPREAD
|
|
1037
1004
|
// into a fill result (which would drop the boundary shift downstream).
|
|
1038
1005
|
let orderType = matchedGridOrder.type;
|
|
1039
|
-
if (orderType ===
|
|
1006
|
+
if (orderType === ORDER_TYPES.SPREAD) {
|
|
1040
1007
|
if (paysAssetId === mgr.assets.assetB.id)
|
|
1041
|
-
orderType =
|
|
1008
|
+
orderType = ORDER_TYPES.BUY;
|
|
1042
1009
|
else if (paysAssetId === mgr.assets.assetA.id)
|
|
1043
|
-
orderType =
|
|
1010
|
+
orderType = ORDER_TYPES.SELL;
|
|
1044
1011
|
else
|
|
1045
|
-
orderType =
|
|
1012
|
+
orderType = resolveSpreadOrderSide(matchedGridOrder.price, mgr.config.startPrice);
|
|
1046
1013
|
}
|
|
1047
1014
|
const currentSize = toFiniteNumber(matchedGridOrder.size);
|
|
1048
|
-
const precision = (orderType ===
|
|
1015
|
+
const precision = (orderType === ORDER_TYPES.SELL) ? mgr.assets.assetA.precision : mgr.assets.assetB.precision;
|
|
1049
1016
|
let filledAmount = 0;
|
|
1050
|
-
if (orderType ===
|
|
1017
|
+
if (orderType === ORDER_TYPES.SELL) {
|
|
1051
1018
|
if (paysAssetId === mgr.assets.assetA.id)
|
|
1052
|
-
filledAmount =
|
|
1019
|
+
filledAmount = blockchainToFloat(paysAmountRaw, precision);
|
|
1053
1020
|
}
|
|
1054
1021
|
else {
|
|
1055
1022
|
if (paysAssetId === mgr.assets.assetB.id)
|
|
1056
|
-
filledAmount =
|
|
1023
|
+
filledAmount = blockchainToFloat(paysAmountRaw, precision);
|
|
1057
1024
|
}
|
|
1058
|
-
const currentSizeIntFromGrid =
|
|
1025
|
+
const currentSizeIntFromGrid = floatToBlockchainInt(currentSize, precision);
|
|
1059
1026
|
const rawForSale = matchedGridOrder?.rawOnChain?.for_sale;
|
|
1060
1027
|
const rawForSaleInt = rawForSale !== undefined && rawForSale !== null ? toFiniteNumber(rawForSale) : NaN;
|
|
1061
1028
|
const driftSignal = Number.isFinite(rawForSaleInt) && Math.round(rawForSaleInt) < currentSizeIntFromGrid;
|
|
@@ -1071,40 +1038,86 @@ class SyncEngine {
|
|
|
1071
1038
|
? Math.max(0, Math.round(effectiveRawForSale))
|
|
1072
1039
|
: currentSizeIntFromGrid;
|
|
1073
1040
|
const newSizeInt = Math.max(0, currentSizeInt - filledAmountInt);
|
|
1074
|
-
const newSize =
|
|
1041
|
+
const newSize = blockchainToFloat(newSizeInt, precision);
|
|
1075
1042
|
if (Number.isFinite(effectiveRawForSale) && currentSizeInt !== currentSizeIntFromGrid) {
|
|
1076
1043
|
mgr.logger.log(`[SYNC] Using rawOnChain.for_sale baseline for ${matchedGridOrder.orderId}: raw=${currentSizeInt}, grid=${currentSizeIntFromGrid}` +
|
|
1077
1044
|
(chainRefetched ? ' (refetched)' : ''), 'debug');
|
|
1078
1045
|
}
|
|
1079
1046
|
const gridAlsoEmpty = currentSizeIntFromGrid <= 0;
|
|
1080
1047
|
let isEffectivelyFull = resolvedChainConfirmsEmpty || gridAlsoEmpty;
|
|
1048
|
+
// If the chain retains a real residual order after this fill, the bot
|
|
1049
|
+
// must cancel it explicitly. The chain only auto-culls ("culls small")
|
|
1050
|
+
// an order when its residual value in the QUOTE asset truncates to 0
|
|
1051
|
+
// (amount_to_receive() == 0, i.e. for_sale × price == 0 in quote units,
|
|
1052
|
+
// see maybe_cull_small_order in bitshares-core). A residual of >= 1 base
|
|
1053
|
+
// unit whose quote value is non-zero is NOT culled — it would be
|
|
1054
|
+
// orphaned on-chain once the slot is converted to a SPREAD placeholder.
|
|
1055
|
+
// Verified fills stay authoritative (rotation proceeds), but the leftover
|
|
1056
|
+
// dust is handled by an explicit cancel rather than trusting the chain to
|
|
1057
|
+
// sweep it.
|
|
1058
|
+
let residualCancel = null;
|
|
1081
1059
|
if (!isEffectivelyFull) {
|
|
1082
|
-
const otherPrecision = (orderType ===
|
|
1060
|
+
const otherPrecision = (orderType === ORDER_TYPES.SELL) ? mgr.assets.assetB.precision : mgr.assets.assetA.precision;
|
|
1083
1061
|
const otherSidePrice = matchedGridOrder.price;
|
|
1084
|
-
const otherSize = (orderType ===
|
|
1085
|
-
if (
|
|
1062
|
+
const otherSize = (orderType === ORDER_TYPES.SELL) ? newSize * otherSidePrice : newSize / otherSidePrice;
|
|
1063
|
+
if (floatToBlockchainInt(otherSize, otherPrecision) <= 0) {
|
|
1086
1064
|
// A fill event is authoritative: the order WAS on-chain and this
|
|
1087
1065
|
// fill consumed the tradeable remainder. A fill is a fill — we do
|
|
1088
1066
|
// not need to preserve the orderId as a "ghost" PARTIAL to block
|
|
1089
|
-
// a duplicate CREATE.
|
|
1090
|
-
//
|
|
1091
|
-
//
|
|
1092
|
-
//
|
|
1093
|
-
//
|
|
1094
|
-
//
|
|
1095
|
-
//
|
|
1096
|
-
//
|
|
1097
|
-
//
|
|
1098
|
-
|
|
1099
|
-
|
|
1067
|
+
// a duplicate CREATE. Treating every sub-dust other-side fill as
|
|
1068
|
+
// a real full fill lets rotation immediately plan the opposite-side
|
|
1069
|
+
// replacement, preserving the grid invariant (each filled side
|
|
1070
|
+
// produces a new order on the other side). This replaces the legacy
|
|
1071
|
+
// ghost mechanism whose preserved orderIds caused instantly-filled
|
|
1072
|
+
// replacement orders to deadlock the COW create pipeline.
|
|
1073
|
+
//
|
|
1074
|
+
// However, the chain does NOT reliably cull the leftover residual:
|
|
1075
|
+
// maybe_cull_small_order only removes an order whose QUOTE-side
|
|
1076
|
+
// value rounds to zero. Verify the order against the chain; if it
|
|
1077
|
+
// still exists with for_sale > 0, schedule an explicit cancel so
|
|
1078
|
+
// the dust is not stranded on the book (previously it could remain
|
|
1079
|
+
// forever because the slot was virtualized and nothing referenced
|
|
1080
|
+
// the orderId anymore).
|
|
1100
1081
|
isEffectivelyFull = true;
|
|
1082
|
+
// Reuse a drift-refetch result when present: it is a live
|
|
1083
|
+
// post-fill read, so for_sale > 0 already proves a real residual
|
|
1084
|
+
// remains. Avoids a second RPC for the same order in the exact
|
|
1085
|
+
// scenario that triggered this branch.
|
|
1086
|
+
let residualForSale = null;
|
|
1087
|
+
if (chainRefetched && Number.isFinite(effectiveRawForSale)) {
|
|
1088
|
+
residualForSale = Math.round(effectiveRawForSale);
|
|
1089
|
+
}
|
|
1090
|
+
else {
|
|
1091
|
+
try {
|
|
1092
|
+
const residualOrder = await chainOrders.readSingleOrder(matchedGridOrder.orderId, 3000);
|
|
1093
|
+
residualForSale = residualOrder ? toFiniteNumber(residualOrder.for_sale, undefined) : null;
|
|
1094
|
+
}
|
|
1095
|
+
catch (residualErr) {
|
|
1096
|
+
// The read is best-effort: if it fails, fall back to the old
|
|
1097
|
+
// behavior (rely on reconciliation) rather than blocking the
|
|
1098
|
+
// authoritative fill transition.
|
|
1099
|
+
mgr.logger.log(`[SYNC] Order ${matchedGridOrder.orderId} (slot ${matchedGridOrder.id}) other-side (${otherSize}) rounds to 0. ` +
|
|
1100
|
+
`Fill is authoritative: treating as full fill for rotation. Residual verification read failed (${getErrorMessage(residualErr)}); ` +
|
|
1101
|
+
`relying on reconciliation for any residual.`, 'warn');
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
if (Number.isFinite(residualForSale) && Math.round(residualForSale) > 0) {
|
|
1105
|
+
residualCancel = { orderId: matchedGridOrder.orderId, id: matchedGridOrder.id };
|
|
1106
|
+
mgr.logger.log(`[SYNC] Order ${matchedGridOrder.orderId} (slot ${matchedGridOrder.id}) other-side (${otherSize}) rounds to 0. ` +
|
|
1107
|
+
`Fill is authoritative: treating as full fill for rotation, but chain still holds residual for_sale=${residualForSale} ` +
|
|
1108
|
+
`(not culled); scheduling explicit cancel.`, 'warn');
|
|
1109
|
+
}
|
|
1110
|
+
else {
|
|
1111
|
+
mgr.logger.log(`[SYNC] Order ${matchedGridOrder.orderId} (slot ${matchedGridOrder.id}) other-side (${otherSize}) rounds to 0. ` +
|
|
1112
|
+
`Fill is authoritative: treating as full fill for rotation; chain confirms residual gone (for_sale=0), no cancel needed.`, 'info');
|
|
1113
|
+
}
|
|
1101
1114
|
}
|
|
1102
1115
|
}
|
|
1103
1116
|
let fullUpdate;
|
|
1104
1117
|
let partialUpdate;
|
|
1105
1118
|
let filledOrderResult;
|
|
1106
1119
|
if (isEffectivelyFull) {
|
|
1107
|
-
fullUpdate =
|
|
1120
|
+
fullUpdate = convertToSpreadPlaceholder(matchedGridOrder);
|
|
1108
1121
|
filledOrderResult = {
|
|
1109
1122
|
...matchedGridOrder,
|
|
1110
1123
|
type: orderType,
|
|
@@ -1124,7 +1137,7 @@ class SyncEngine {
|
|
|
1124
1137
|
isMaker
|
|
1125
1138
|
};
|
|
1126
1139
|
const { btsFeeState, ...matchedWithoutDeferredFee } = matchedGridOrder;
|
|
1127
|
-
let updatedOrder = { ...matchedWithoutDeferredFee, type: orderType, state:
|
|
1140
|
+
let updatedOrder = { ...matchedWithoutDeferredFee, type: orderType, state: ORDER_STATES.PARTIAL };
|
|
1128
1141
|
if (updatedOrder.rawOnChain && updatedOrder.rawOnChain.for_sale !== undefined) {
|
|
1129
1142
|
const baselineForSale = (chainRefetched && Number.isFinite(effectiveRawForSale))
|
|
1130
1143
|
? effectiveRawForSale
|
|
@@ -1136,7 +1149,7 @@ class SyncEngine {
|
|
|
1136
1149
|
fetchedAt: Date.now()
|
|
1137
1150
|
};
|
|
1138
1151
|
}
|
|
1139
|
-
const nextOrder = await
|
|
1152
|
+
const nextOrder = await applyChainSizeToGridOrder(mgr, updatedOrder, newSize);
|
|
1140
1153
|
if (nextOrder) {
|
|
1141
1154
|
updatedOrder = { ...updatedOrder, ...nextOrder };
|
|
1142
1155
|
}
|
|
@@ -1147,7 +1160,8 @@ class SyncEngine {
|
|
|
1147
1160
|
filledOrder: filledOrderResult,
|
|
1148
1161
|
fullUpdate,
|
|
1149
1162
|
partialUpdate,
|
|
1150
|
-
newSize
|
|
1163
|
+
newSize,
|
|
1164
|
+
residualCancel
|
|
1151
1165
|
};
|
|
1152
1166
|
}
|
|
1153
1167
|
/**
|
|
@@ -1158,7 +1172,7 @@ class SyncEngine {
|
|
|
1158
1172
|
*/
|
|
1159
1173
|
async syncFromFillHistory(fill, options = {}) {
|
|
1160
1174
|
const mgr = this.manager;
|
|
1161
|
-
const persistenceMode =
|
|
1175
|
+
const persistenceMode = resolveProcessedFillPersistenceMode(options);
|
|
1162
1176
|
if (!fill || !fill.op || !fill.op[1])
|
|
1163
1177
|
return { filledOrders: [], updatedOrders: [], partialFill: false };
|
|
1164
1178
|
const fillOp = fill.op[1];
|
|
@@ -1169,7 +1183,7 @@ class SyncEngine {
|
|
|
1169
1183
|
mgr.logger.log(`[SYNC] is_maker flag missing from fill data for order ${orderId}; defaulting to maker`, 'warn');
|
|
1170
1184
|
}
|
|
1171
1185
|
const isMaker = fillOp.is_maker !== false;
|
|
1172
|
-
const fillKey =
|
|
1186
|
+
const fillKey = buildFillKey({ orderId, blockNum, historyId });
|
|
1173
1187
|
const paysAmountRaw = toFiniteNumber(fillOp.pays?.amount);
|
|
1174
1188
|
const paysAssetId = fillOp.pays ? fillOp.pays.asset_id : null;
|
|
1175
1189
|
const receivesAmountRaw = toFiniteNumber(fillOp.receives?.amount);
|
|
@@ -1244,7 +1258,7 @@ class SyncEngine {
|
|
|
1244
1258
|
orderType: ctx.orderType,
|
|
1245
1259
|
precision: ctx.precision,
|
|
1246
1260
|
filledAmount: ctx.filledAmount,
|
|
1247
|
-
filledAmountInt:
|
|
1261
|
+
filledAmountInt: floatToBlockchainInt(ctx.filledAmount, ctx.precision),
|
|
1248
1262
|
currentSizeIntFromGrid: ctx.currentSizeIntFromGrid,
|
|
1249
1263
|
rawForSaleInt: ctx.rawForSaleInt,
|
|
1250
1264
|
chainRefetched,
|
|
@@ -1279,7 +1293,12 @@ class SyncEngine {
|
|
|
1279
1293
|
// after the fill's optimistic accounting + grid update (see
|
|
1280
1294
|
// syncFromFillHistoryBatch for rationale).
|
|
1281
1295
|
await mgr.reanchorAccountTotals('fill-sync');
|
|
1282
|
-
return {
|
|
1296
|
+
return {
|
|
1297
|
+
filledOrders,
|
|
1298
|
+
updatedOrders,
|
|
1299
|
+
partialFill: result.isFull ? false : true,
|
|
1300
|
+
residualCancels: result.residualCancel ? [result.residualCancel] : []
|
|
1301
|
+
};
|
|
1283
1302
|
}
|
|
1284
1303
|
finally {
|
|
1285
1304
|
// Lower the guard before the final consolidated recalc so the
|
|
@@ -1310,7 +1329,7 @@ class SyncEngine {
|
|
|
1310
1329
|
*/
|
|
1311
1330
|
async syncFromFillHistoryBatch(fills, options = {}) {
|
|
1312
1331
|
const mgr = this.manager;
|
|
1313
|
-
const persistenceMode =
|
|
1332
|
+
const persistenceMode = resolveProcessedFillPersistenceMode(options);
|
|
1314
1333
|
if (!Array.isArray(fills) || fills.length === 0) {
|
|
1315
1334
|
return { filledOrders: [], updatedOrders: [], partialFill: false };
|
|
1316
1335
|
}
|
|
@@ -1328,7 +1347,7 @@ class SyncEngine {
|
|
|
1328
1347
|
mgr.logger.log(`[SYNC] is_maker flag missing from fill data for order ${orderId}; defaulting to maker`, 'warn');
|
|
1329
1348
|
}
|
|
1330
1349
|
const isMaker = fillOp.is_maker !== false;
|
|
1331
|
-
const fillKey =
|
|
1350
|
+
const fillKey = buildFillKey({ orderId, blockNum, historyId });
|
|
1332
1351
|
if (!fillKey) {
|
|
1333
1352
|
mgr.logger.log(`[SYNC] Missing replay-safe fill key for order ${orderId} block ${blockNum}; deferring to open-orders sync`, 'warn');
|
|
1334
1353
|
anyRequiresSync = true;
|
|
@@ -1379,7 +1398,7 @@ class SyncEngine {
|
|
|
1379
1398
|
validEntries.push(entry);
|
|
1380
1399
|
}
|
|
1381
1400
|
catch (acctErr) {
|
|
1382
|
-
mgr.logger.log(`[SYNC] Accounting error for fill ${entry.fillKey}: ${
|
|
1401
|
+
mgr.logger.log(`[SYNC] Accounting error for fill ${entry.fillKey}: ${getErrorMessage(acctErr)}`, 'error');
|
|
1383
1402
|
continue;
|
|
1384
1403
|
}
|
|
1385
1404
|
}
|
|
@@ -1413,7 +1432,7 @@ class SyncEngine {
|
|
|
1413
1432
|
orderType: ctx.orderType,
|
|
1414
1433
|
precision: ctx.precision,
|
|
1415
1434
|
filledAmount: ctx.filledAmount,
|
|
1416
|
-
filledAmountInt:
|
|
1435
|
+
filledAmountInt: floatToBlockchainInt(ctx.filledAmount, ctx.precision),
|
|
1417
1436
|
currentSizeIntFromGrid: ctx.currentSizeIntFromGrid,
|
|
1418
1437
|
rawForSaleInt: ctx.rawForSaleInt
|
|
1419
1438
|
});
|
|
@@ -1462,14 +1481,44 @@ class SyncEngine {
|
|
|
1462
1481
|
mgr.logger.log(`[SYNC] Batch drift refetch failed for ${driftOrderIds.size} orders; falling back to cache: ${refetchErr?.message || refetchErr}`, 'warn');
|
|
1463
1482
|
}
|
|
1464
1483
|
}
|
|
1465
|
-
// Phase 6: Compute state transitions and collect grid updates
|
|
1484
|
+
// Phase 6: Compute state transitions and collect grid updates.
|
|
1485
|
+
// Multiple fills for the SAME order inside one batch are
|
|
1486
|
+
// aggregated into a single cumulative transition. Each fill is
|
|
1487
|
+
// still accounted individually (Phase 3), but the grid mutation
|
|
1488
|
+
// must reflect the COMBINED consumption. Without aggregation every
|
|
1489
|
+
// fill recomputes newSize from the same stale pre-batch baseline
|
|
1490
|
+
// and the last update wins (`applyGridUpdateBatch` is last-wins
|
|
1491
|
+
// per slot), leaving a phantom residual equal to the earlier
|
|
1492
|
+
// fills' sum — exactly the fund-invariant CRITICAL seen in the
|
|
1493
|
+
// XRP-BTS log whenever a batch contained 2+ fills of one order.
|
|
1466
1494
|
const gridUpdates = [];
|
|
1467
1495
|
const filledOrders = [];
|
|
1468
1496
|
const updatedOrders = [];
|
|
1497
|
+
const residualCancels = [];
|
|
1469
1498
|
let anyPartialFill = false;
|
|
1499
|
+
const fillContextsBySlot = new Map();
|
|
1470
1500
|
for (const ctx of entryContexts) {
|
|
1471
|
-
const
|
|
1472
|
-
const
|
|
1501
|
+
const slotId = ctx.matchedGridOrder.id;
|
|
1502
|
+
const group = fillContextsBySlot.get(slotId);
|
|
1503
|
+
if (group)
|
|
1504
|
+
group.push(ctx);
|
|
1505
|
+
else
|
|
1506
|
+
fillContextsBySlot.set(slotId, [ctx]);
|
|
1507
|
+
}
|
|
1508
|
+
for (const group of fillContextsBySlot.values()) {
|
|
1509
|
+
const lastCtx = group[group.length - 1];
|
|
1510
|
+
const { matchedGridOrder, orderType, precision, currentSizeIntFromGrid, rawForSaleInt } = lastCtx;
|
|
1511
|
+
const { orderId } = lastCtx.entry;
|
|
1512
|
+
// Sum the integer filled amounts across this order's fills so
|
|
1513
|
+
// the single transition reflects the total consumption.
|
|
1514
|
+
let totalFilledAmountInt = 0;
|
|
1515
|
+
for (const ctx of group) {
|
|
1516
|
+
totalFilledAmountInt += ctx.filledAmountInt;
|
|
1517
|
+
}
|
|
1518
|
+
const totalFilledAmount = blockchainToFloat(totalFilledAmountInt, precision);
|
|
1519
|
+
if (group.length > 1) {
|
|
1520
|
+
mgr.logger.log(`[SYNC] Aggregated ${group.length} fill(s) for order ${orderId} (slot ${matchedGridOrder.id}): total filled=${totalFilledAmount}`, 'debug');
|
|
1521
|
+
}
|
|
1473
1522
|
const refetchInfo = refetchMap.get(orderId);
|
|
1474
1523
|
const chainRefetched = refetchInfo?.chainRefetched || false;
|
|
1475
1524
|
const chainConfirmsEmpty = refetchInfo?.chainConfirmsEmpty || false;
|
|
@@ -1478,21 +1527,23 @@ class SyncEngine {
|
|
|
1478
1527
|
matchedGridOrder,
|
|
1479
1528
|
orderType,
|
|
1480
1529
|
precision,
|
|
1481
|
-
filledAmount,
|
|
1482
|
-
filledAmountInt,
|
|
1530
|
+
filledAmount: totalFilledAmount,
|
|
1531
|
+
filledAmountInt: totalFilledAmountInt,
|
|
1483
1532
|
currentSizeIntFromGrid,
|
|
1484
1533
|
rawForSaleInt,
|
|
1485
1534
|
chainRefetched,
|
|
1486
1535
|
chainConfirmsEmpty,
|
|
1487
1536
|
effectiveRawForSale,
|
|
1488
|
-
blockNum,
|
|
1489
|
-
historyId,
|
|
1490
|
-
isMaker
|
|
1537
|
+
blockNum: lastCtx.entry.blockNum,
|
|
1538
|
+
historyId: lastCtx.entry.historyId,
|
|
1539
|
+
isMaker: lastCtx.entry.isMaker
|
|
1491
1540
|
});
|
|
1492
1541
|
if (result.isFull) {
|
|
1493
1542
|
mgr.logger.log(`[SYNC] Full fill for order ${orderId} (slot ${matchedGridOrder.id}).`, 'info');
|
|
1494
1543
|
gridUpdates.push({ id: matchedGridOrder.id, ...result.fullUpdate, context: 'handle-fill-full' });
|
|
1495
1544
|
filledOrders.push(result.filledOrder);
|
|
1545
|
+
if (result.residualCancel)
|
|
1546
|
+
residualCancels.push(result.residualCancel);
|
|
1496
1547
|
}
|
|
1497
1548
|
else {
|
|
1498
1549
|
mgr.logger.log(`[SYNC] Partial fill for order ${orderId} (slot ${matchedGridOrder.id}): newSize=${result.newSize}`, 'info');
|
|
@@ -1522,7 +1573,7 @@ class SyncEngine {
|
|
|
1522
1573
|
// authoritative values and hands re-commitments
|
|
1523
1574
|
// (tryDeductFromChainFree) a fresh snapshot.
|
|
1524
1575
|
await mgr.reanchorAccountTotals('fill-batch');
|
|
1525
|
-
return { filledOrders, updatedOrders, partialFill: anyPartialFill, requiresOpenOrdersSync: anyRequiresSync };
|
|
1576
|
+
return { filledOrders, updatedOrders, partialFill: anyPartialFill, requiresOpenOrdersSync: anyRequiresSync, residualCancels };
|
|
1526
1577
|
}
|
|
1527
1578
|
finally {
|
|
1528
1579
|
// Lower the guard before the final consolidated recalc so the
|
|
@@ -1612,33 +1663,33 @@ class SyncEngine {
|
|
|
1612
1663
|
const isRotation = !!existingOrder;
|
|
1613
1664
|
// For rotation: transition the old order to VIRTUAL, freeing its capital
|
|
1614
1665
|
if (isRotation && existingOrder) {
|
|
1615
|
-
if (!
|
|
1616
|
-
const oldVirtualOrder =
|
|
1666
|
+
if (!isOrderVirtual(existingOrder)) {
|
|
1667
|
+
const oldVirtualOrder = convertToSpreadPlaceholder(existingOrder);
|
|
1617
1668
|
await mgr._applyOrderUpdate(oldVirtualOrder, 'rotation-cleanup', {
|
|
1618
1669
|
skipAccounting: chainData.skipAccounting || false,
|
|
1619
1670
|
fee: 0
|
|
1620
1671
|
});
|
|
1621
1672
|
}
|
|
1622
|
-
else if (
|
|
1673
|
+
else if (hasOnChainId(existingOrder)) {
|
|
1623
1674
|
// Already VIRTUAL but still has orderId (from rebalance)
|
|
1624
1675
|
// Just clear the orderId to reflect blockchain state
|
|
1625
|
-
const clearedOrder =
|
|
1676
|
+
const clearedOrder = convertToSpreadPlaceholder(existingOrder);
|
|
1626
1677
|
await mgr._applyOrderUpdate(clearedOrder, 'fill-cleanup', {
|
|
1627
1678
|
skipAccounting: chainData.skipAccounting || false,
|
|
1628
1679
|
fee: 0
|
|
1629
1680
|
});
|
|
1630
1681
|
}
|
|
1631
1682
|
}
|
|
1632
|
-
const newState = isPartialPlacement ?
|
|
1633
|
-
let normalizedExpectedType = (expectedType ===
|
|
1683
|
+
const newState = isPartialPlacement ? ORDER_STATES.PARTIAL : ORDER_STATES.ACTIVE;
|
|
1684
|
+
let normalizedExpectedType = (expectedType === ORDER_TYPES.BUY || expectedType === ORDER_TYPES.SELL)
|
|
1634
1685
|
? expectedType
|
|
1635
1686
|
: null;
|
|
1636
1687
|
// Defensive: a SPREAD slot must never transition to an on-chain
|
|
1637
1688
|
// state (validateOrder rejects SPREAD+ACTIVE/PARTIAL as fatal).
|
|
1638
1689
|
// Derive the side from the slot price vs start price — same
|
|
1639
1690
|
// convention as the funds check (manager.ts).
|
|
1640
|
-
if (!normalizedExpectedType && gridOrder.type ===
|
|
1641
|
-
normalizedExpectedType =
|
|
1691
|
+
if (!normalizedExpectedType && gridOrder.type === ORDER_TYPES.SPREAD) {
|
|
1692
|
+
normalizedExpectedType = resolveSpreadOrderSide(gridOrder.price, mgr.config.startPrice);
|
|
1642
1693
|
}
|
|
1643
1694
|
const updatedOrder = {
|
|
1644
1695
|
...gridOrder,
|
|
@@ -1679,10 +1730,10 @@ class SyncEngine {
|
|
|
1679
1730
|
const clearSize = !!chainData.clearSize;
|
|
1680
1731
|
let btsFeeData;
|
|
1681
1732
|
try {
|
|
1682
|
-
btsFeeData =
|
|
1733
|
+
btsFeeData = getAssetFees('BTS');
|
|
1683
1734
|
}
|
|
1684
1735
|
catch (err) {
|
|
1685
|
-
mgr.logger?.log?.(`[FILL-FEE] Failed to load BTS cancel fee cache: ${
|
|
1736
|
+
mgr.logger?.log?.(`[FILL-FEE] Failed to load BTS cancel fee cache: ${getErrorMessage(err)}. Using zero-fee fallback.`, 'warn');
|
|
1686
1737
|
btsFeeData = {
|
|
1687
1738
|
total: 0,
|
|
1688
1739
|
createFee: 0,
|
|
@@ -1695,7 +1746,7 @@ class SyncEngine {
|
|
|
1695
1746
|
};
|
|
1696
1747
|
}
|
|
1697
1748
|
const runCancel = async () => {
|
|
1698
|
-
const gridOrder =
|
|
1749
|
+
const gridOrder = findMatchingGridOrderByOpenOrder({ orderId }, { orders: mgr.orders, assets: mgr.assets, calcToleranceFn: (p, s, t) => calculatePriceTolerance(p, s, t, mgr.assets), logger: mgr.logger });
|
|
1699
1750
|
if (gridOrder) {
|
|
1700
1751
|
// Lock both chain orderId and grid order ID to prevent concurrent modifications
|
|
1701
1752
|
const orderIds = [orderId, gridOrder.id].filter(Boolean);
|
|
@@ -1705,8 +1756,8 @@ class SyncEngine {
|
|
|
1705
1756
|
const currentGridOrder = mgr.orders.get(gridOrder.id);
|
|
1706
1757
|
if (currentGridOrder && currentGridOrder.orderId === orderId) {
|
|
1707
1758
|
const nextOrder = clearSize
|
|
1708
|
-
?
|
|
1709
|
-
:
|
|
1759
|
+
? convertToSpreadPlaceholder(currentGridOrder)
|
|
1760
|
+
: virtualizeOrder(currentGridOrder);
|
|
1710
1761
|
await mgr._applyOrderUpdate(nextOrder, 'cancel-order', {
|
|
1711
1762
|
skipAccounting: false,
|
|
1712
1763
|
fee: btsFeeData?.cancelFee || 0
|
|
@@ -1720,7 +1771,7 @@ class SyncEngine {
|
|
|
1720
1771
|
else {
|
|
1721
1772
|
// CRITICAL: Even if order not in grid, the cancellation fee was still paid on blockchain
|
|
1722
1773
|
// Deduct it from account totals to prevent drift.
|
|
1723
|
-
const btsSide =
|
|
1774
|
+
const btsSide = getBtsSide(mgr.config?.assetA, mgr.config?.assetB);
|
|
1724
1775
|
if (btsSide && btsFeeData?.cancelFee > 0) {
|
|
1725
1776
|
await mgr.accountant.adjustTotalBalance(btsSide, -btsFeeData.cancelFee, 'cancel-order-unmatched-fee');
|
|
1726
1777
|
}
|
|
@@ -1814,7 +1865,7 @@ class SyncEngine {
|
|
|
1814
1865
|
await this.initializeAssets();
|
|
1815
1866
|
}
|
|
1816
1867
|
catch (err) {
|
|
1817
|
-
mgr.logger.log(`[SYNC] initializeAssets failed: ${
|
|
1868
|
+
mgr.logger.log(`[SYNC] initializeAssets failed: ${getErrorMessage(err)}`, 'warn');
|
|
1818
1869
|
}
|
|
1819
1870
|
const assetAId = mgr.assets?.assetA?.id;
|
|
1820
1871
|
const assetBId = mgr.assets?.assetB?.id;
|
|
@@ -1823,7 +1874,7 @@ class SyncEngine {
|
|
|
1823
1874
|
const assetList = [assetAId, assetBId];
|
|
1824
1875
|
// For non-BTS pairs, also fetch core asset (BTS) balance for fee management
|
|
1825
1876
|
if (mgr.config.assetA !== 'BTS' && mgr.config.assetB !== 'BTS') {
|
|
1826
|
-
assetList.push(
|
|
1877
|
+
assetList.push(NATIVE_CLIENT.CHAIN.CORE_ASSET_ID);
|
|
1827
1878
|
}
|
|
1828
1879
|
const lookup = await chainOrders.getOnChainAssetBalances(accountIdOrName, assetList);
|
|
1829
1880
|
const aInfo = lookup?.[assetAId] || lookup?.[mgr.config.assetA];
|
|
@@ -1833,14 +1884,14 @@ class SyncEngine {
|
|
|
1833
1884
|
}
|
|
1834
1885
|
// Store BTS balance for non-BTS pairs
|
|
1835
1886
|
if (mgr.config.assetA !== 'BTS' && mgr.config.assetB !== 'BTS') {
|
|
1836
|
-
const btsInfo = lookup?.[
|
|
1887
|
+
const btsInfo = lookup?.[NATIVE_CLIENT.CHAIN.CORE_ASSET_ID];
|
|
1837
1888
|
if (btsInfo) {
|
|
1838
1889
|
mgr.btsBalance = { free: btsInfo.free, total: btsInfo.total, locked: 0 };
|
|
1839
1890
|
}
|
|
1840
1891
|
}
|
|
1841
1892
|
}
|
|
1842
1893
|
catch (err) {
|
|
1843
|
-
mgr.logger.log(`Failed to fetch on-chain balances: ${
|
|
1894
|
+
mgr.logger.log(`Failed to fetch on-chain balances: ${getErrorMessage(err)}`, 'warn');
|
|
1844
1895
|
}
|
|
1845
1896
|
}
|
|
1846
1897
|
/**
|
|
@@ -1894,7 +1945,7 @@ class SyncEngine {
|
|
|
1894
1945
|
return;
|
|
1895
1946
|
const fetchAssetWithFallback = async (symbol, side) => {
|
|
1896
1947
|
try {
|
|
1897
|
-
return await
|
|
1948
|
+
return await lookupAsset(BitShares, symbol);
|
|
1898
1949
|
}
|
|
1899
1950
|
catch (err) {
|
|
1900
1951
|
// If blockchain lookup fails, check for persisted fallback
|
|
@@ -1902,7 +1953,7 @@ class SyncEngine {
|
|
|
1902
1953
|
const persistedAssets = mgr.accountOrders.loadPersistedAssets();
|
|
1903
1954
|
const assetData = (side === 'A') ? persistedAssets?.assetA : persistedAssets?.assetB;
|
|
1904
1955
|
if (assetData && assetData.symbol === symbol && typeof assetData.precision === 'number') {
|
|
1905
|
-
mgr.logger.log(`Blockchain lookup failed for ${symbol}: ${
|
|
1956
|
+
mgr.logger.log(`Blockchain lookup failed for ${symbol}: ${getErrorMessage(err)}. Persisted data: id=${assetData.id}, precision=${assetData.precision} — refusing stale fallback`, 'error');
|
|
1906
1957
|
}
|
|
1907
1958
|
}
|
|
1908
1959
|
throw err;
|
|
@@ -1915,10 +1966,10 @@ class SyncEngine {
|
|
|
1915
1966
|
};
|
|
1916
1967
|
}
|
|
1917
1968
|
catch (err) {
|
|
1918
|
-
mgr.logger.log(`Asset metadata lookup failed: ${
|
|
1969
|
+
mgr.logger.log(`Asset metadata lookup failed: ${getErrorMessage(err)}`, 'error');
|
|
1919
1970
|
throw err;
|
|
1920
1971
|
}
|
|
1921
1972
|
}
|
|
1922
1973
|
}
|
|
1923
|
-
|
|
1974
|
+
export default SyncEngine;
|
|
1924
1975
|
//# sourceMappingURL=sync_engine.js.map
|