Skip to content

Core that switches exchange keeps its old exchange in the terminal until Reconnect or terminal restart #734

Description

@Alena-Selezneva

What the user saw

@sasha_kot (MoonTerminal chat, 2026-09-26): "поменял api ключ в боте на HL, теперь в мунтерминале биржа не определяется как HL" — they switched a running MoonBot core to Hyperliquid by entering new API keys, and the terminal still does not show that core as Hyperliquid.

MoonBot allows switching the exchange on a live, logged-in bot without restarting the process, so from the terminal's side the core simply keeps running (or at most restarts) on the same address.

Why

The terminal learns a core's exchange exactly once per MoonProto client:

  • crates/moon-core/src/feed/live/mod.rs: FeedMsg::Identity is published from client.server_info().exchange_code and then latched by identity_sent = true. Nothing ever resets identity_sent for the life of that client — not Reconnecting, not Connected { fresh: false }, not ServerRestart.
  • MoonProto fills ServerInfo only in the init state machine (BaseCheck). On an internal reconnect or a detected ServerRestart init is not repeated, so the snapshot keeps the old exchange code anyway.

The gap is already known for the build number: crates/moon-core/src/session/core_update.rs (doc of the Verifying phase) says a core that restarts for any reason other than a terminal-commanded update "still shows its pre-restart build, because MoonProto's internal reconnect keeps the snapshot". The exchange identity rides the same snapshot, so it goes stale the same way.

The stale identity is not just a caption: the same FeedMsg::Identity drives core_venue (logo, label, grouping, market-name parsing) and set_orderbook_kind (spot vs futures book), and ExchangeId is the key market-data providers are elected by. What a wrong venue does to provider election for the old exchange has not been checked.

Workaround today

Settings → «Подключения» → the ↻ button («Переподключить») on that core's row, or restart the terminal. Both create a fresh MoonProto client, which runs BaseCheck again and publishes the new exchange.

Possible fix (terminal side)

MoonProto has no public way to re-run BaseCheck, so the only route in the terminal is the existing respawn (the same one ↻ and the post-update Verifying phase use):

  • respawn the client on LifecycleEvent::ServerRestart — covers a restarted core;
  • a hot exchange switch with no restart may not produce ServerRestart at all; it needs its own signal (e.g. the core's market list being replaced wholesale). Which signal a hot switch actually produces on the wire has not been checked.

Until then, a hint near the core row ("exchange changed on the core? press ↻") would at least tell the user what to do.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions