Skip to content

fix(swift-example-app): point regtest+docker SPV at dashmate seed port#3589

Merged
QuantumExplorer merged 1 commit intov3.1-devfrom
fix/swift-example-app-regtest-spv-peer
May 5, 2026
Merged

fix(swift-example-app): point regtest+docker SPV at dashmate seed port#3589
QuantumExplorer merged 1 commit intov3.1-devfrom
fix/swift-example-app-regtest-spv-peer

Conversation

@QuantumExplorer
Copy link
Copy Markdown
Member

Issue being fixed or feature implemented

When the user enables "Use Docker Setup" on regtest, SPV silently fails to connect:

```
INFO dash_spv::network::manager: Reconnecting to exclusive peer: 127.0.0.1:19999
INFO dash_spv::network::peer: Peer 127.0.0.1:19999 closed connection (EOF)
ERROR dash_spv::network::handshake: Error receiving message during handshake: Peer disconnected
WARN dash_spv::network::manager: Handshake failed with 127.0.0.1:19999: Peer disconnected
```

`19999` is testnet's standard P2P port. dashmate's local cluster doesn't run on it — its seed lives at `127.0.0.1:20301` for the default 3-node local preset.

The bug is bleed-through between two mutually-exclusive UI surfaces that share the same `UserDefaults` keys:

  • The OptionsView "Use Custom SPV Peers" toggle (shown only on non-regtest networks) seeds `localCorePeers` with the active network's standard P2P port — `127.0.0.1:19999` for testnet.
  • The OptionsView "Use Docker Setup" toggle (shown only on regtest) flips `useLocalhostCore = true` but doesn't touch `localCorePeers`.
  • `CoreContentView.startSync` reads both keys verbatim. The stale testnet peer string is the result.

What was done?

Replaced the inline `UserDefaults` lookup in `startSync` with a `spvPeerOverride()` helper that selects the peer list based on `(currentNetwork, useDockerSetup)`:

  • regtest + docker → `["127.0.0.1:20301"]`. Ignores `localCorePeers` entirely so the stale testnet/mainnet value can't bleed in. The port comes from dashmate: base 20001 per `getLocalConfigFactory.js` + `i*100` per `setupLocalPresetTaskFactory.js` with seed at `i = nodeCount`, so the 3-node default puts `local_seed` at 20301.
  • non-regtest + `useLocalhostCore` → parses `localCorePeers` as before for the existing custom-peer flow.
  • otherwise → empty list; FFI uses the network's built-in seed nodes.

`startSync` derives `restrictToConfiguredPeers` from whether the override returned anything, so the call site no longer juggles two flags.

How Has This Been Tested?

  • `xcodebuild -project SwiftExampleApp.xcodeproj -scheme SwiftExampleApp -sdk iphonesimulator` passes.
  • Manually on the simulator pointing at a running dashmate local cluster: with the previous bleed-through state (`localCorePeers = 127.0.0.1:19999` from a prior testnet session), switching to regtest + docker and starting SPV used to spin on "Peer disconnected". After the fix the same flow connects to `127.0.0.1:20301`, completes handshake, and syncs headers cleanly. Filter sync also works once dashmate's compact-filter index is on (see feat(dashmate): default-on the BIP158 compact-filter index across all presets #3587).

Breaking Changes

None. The non-regtest custom-peers flow reads `localCorePeers` exactly as before. The regtest+docker flow now uses a hard-coded peer; users with a non-default dashmate `nodeCount` (where the seed lands at a different port) will need either a non-default-aware override or to run the typical 3-node preset. Future PR could surface a "Docker Seed Port" override field in OptionsView for that edge case — not blocking the bug fix.

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have added "!" to the title and described breaking changes in the corresponding section if my code contains any
  • I have made corresponding changes to the documentation if needed

🤖 Generated with Claude Code

`CoreContentView.startSync` previously always read `localCorePeers`
from `UserDefaults` whenever `useLocalhostCore` was set. Both flags
are shared across networks, but the OptionsView UI populates them
through two mutually-exclusive toggles ("Use Docker Setup" on regtest,
"Use Custom SPV Peers" elsewhere) that never sync state. Result:

- Enable Custom SPV Peers on testnet → seeds `localCorePeers =
  "127.0.0.1:19999"`.
- Switch to regtest + Use Docker Setup → flips `useLocalhostCore = true`
  but doesn't touch `localCorePeers`.
- SPV asks dashmate's regtest cluster to handshake on `19999` (testnet's
  port) and silently spins on connection refused.

Replaced the inline lookup with a `spvPeerOverride()` helper that
selects the peer list based on `(currentNetwork, useDockerSetup)`:

- regtest + docker → `["127.0.0.1:20301"]` (dashmate's `local_seed`
  P2P port for the typical 3-node preset: base 20001 from
  `getLocalConfigFactory.js` + `i*100` per setup task with seed at
  `i = nodeCount`). Ignores `localCorePeers` entirely so a stale
  testnet/mainnet value can't bleed in.
- non-regtest + `useLocalhostCore` → parses `localCorePeers` as before
  for the user's custom-peer flow.
- otherwise → empty list, FFI uses the network's built-in seed nodes.

`startSync` derives `restrictToConfiguredPeers` from whether the
override returned anything, so the call site no longer juggles two
flags.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@QuantumExplorer QuantumExplorer requested a review from shumkov as a code owner May 5, 2026 12:27
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 5, 2026

Warning

Rate limit exceeded

@QuantumExplorer has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 58 minutes and 26 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 95e5ef29-7498-4920-af7f-a467e9e3467e

📥 Commits

Reviewing files that changed from the base of the PR and between 318d83b and c86e5ea.

📒 Files selected for processing (1)
  • packages/swift-sdk/SwiftExampleApp/SwiftExampleApp/Core/Views/CoreContentView.swift
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/swift-example-app-regtest-spv-peer

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added this to the v3.1.0 milestone May 5, 2026
@thepastaclaw
Copy link
Copy Markdown
Collaborator

thepastaclaw commented May 5, 2026

Review Gate

Commit: c86e5eaf

  • Debounce: 49m ago (need 30m)

  • CI checks: builds passed, 0/2 tests passed

  • CodeRabbit review: comment found

  • Off-peak hours: peak window (5am-11am PT) — currently 06:16 AM PT Tuesday

  • Run review now (check to override)

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 5, 2026

✅ DashSDKFFI.xcframework built for this PR.

SwiftPM (host the zip at a stable URL, then use):

.binaryTarget(
  name: "DashSDKFFI",
  url: "https://your.cdn.example/DashSDKFFI.xcframework.zip",
  checksum: "e1f796da4fdda0a2f814f455979201f26e47f64b909cbb8e3c757d9bbfa0e78d"
)

Xcode manual integration:

  • Download 'DashSDKFFI.xcframework' artifact from the run link above.
  • Drag it into your app target (Frameworks, Libraries & Embedded Content) and set Embed & Sign.
  • If using the Swift wrapper package, point its binaryTarget to the xcframework location or add the package and place the xcframework at the expected path.

Copy link
Copy Markdown
Member Author

@QuantumExplorer QuantumExplorer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Self Reviewed

@QuantumExplorer QuantumExplorer merged commit 0cacadb into v3.1-dev May 5, 2026
35 checks passed
@QuantumExplorer QuantumExplorer deleted the fix/swift-example-app-regtest-spv-peer branch May 5, 2026 13:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants