From af9568a530eaadc53f3f34a1e6b2e92023ad3bc1 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 20 Jun 2026 11:56:56 +0300 Subject: [PATCH] fix(swift-sdk): seed testnet at the per-network protocol-version floor instead of pinning PV11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SDK.init(network:platformVersion:) hardcoded platformVersion 11 for mainnet/testnet when the caller passed 0 (the default). That pinned the SDK via SdkBuilder::with_version(11), disabling auto-detect, so the SDK spoke the V0 getDocuments wire even after testnet rolled forward to Platform v3.1 (PV12). V1-only features — document sum/average aggregation — were then rejected client-side with "select=Sum requires Platform v3.1+ (V1 documents wire)". The 11 pin was a workaround from when the public networks were on pre-v3.1 drive-abci. Previously a construction-time floor clamp in rs-sdk silently raised the sub-floor pin to the network floor, but #3900 made the per-network floor a seed-only default (no longer a runtime clamp), so the stale pin now sticks. Pass platform_version=0 straight through instead of mapping it to a Swift-side per-network constant. apply_version(builder, 0) leaves the builder unpinned, so rs-sdk seeds at the per-network min_protocol_version floor (mainnet 11, testnet/devnet/regtest 12) with auto-detect on and ratchets upward as the network reports newer versions. The network->version decision now lives entirely in rs-sdk. A non-zero platformVersion still pins via with_version, unchanged. Verified on testnet: document sum/average (DOC-13/14) now return proof-verified results in SwiftExampleApp (sum 120, average 30 over a summable fixture) where they previously failed with the V1-wire error. Co-Authored-By: Claude Opus 4.8 --- .../swift-sdk/Sources/SwiftDashSDK/SDK.swift | 41 ++++++------------- 1 file changed, 13 insertions(+), 28 deletions(-) diff --git a/packages/swift-sdk/Sources/SwiftDashSDK/SDK.swift b/packages/swift-sdk/Sources/SwiftDashSDK/SDK.swift index 5f292a1303..8e7c6ec0a1 100644 --- a/packages/swift-sdk/Sources/SwiftDashSDK/SDK.swift +++ b/packages/swift-sdk/Sources/SwiftDashSDK/SDK.swift @@ -247,14 +247,13 @@ public final class SDK: @unchecked Sendable { /// This is suitable for mobile applications where proof verification would be resource-intensive. /// /// `platformVersion`: - /// - `0` (default) — pick a network-appropriate version: PV 11 for the - /// public networks still on pre-v3.1 drive-abci (mainnet, testnet), - /// PV 12 (latest) for the leading-edge networks (devnet, regtest). - /// This avoids the V0/V1 `getDocuments` wire-format mismatch that - /// would otherwise make Platform queries fail with - /// `"decoding error: could not decode data contracts query"` on the - /// public networks until they roll forward. Override by passing an - /// explicit non-zero value. + /// - `0` (default) — let the Rust SDK seed at the per-network minimum + /// protocol version (mainnet 11, testnet/devnet/regtest 12) with + /// auto-detect on, ratcheting up as the network reports newer + /// versions. The per-network floor encodes the V0/V1 `getDocuments` + /// wire format (mainnet floor 11 = V0 until mainnet upgrades; + /// testnet floor 12 = V1), so this picks the right wire without a + /// Swift-side network→version map. /// - non-zero — pin the SDK to this exact `PlatformVersion`. public init(network: Network, platformVersion: UInt32 = 0) throws { var config = DashSDKConfig() @@ -264,26 +263,12 @@ public final class SDK: @unchecked Sendable { config.skip_asset_lock_proof_verification = false config.request_retry_count = 1 config.request_timeout_ms = 8000 // 8 seconds - let resolvedPlatformVersion: UInt32 - if platformVersion != 0 { - resolvedPlatformVersion = platformVersion - } else { - switch network { - case .mainnet, .testnet: - // TODO(platform-version-bump): bump mainnet/testnet to 12 - // (or whatever PV is current) once drive-abci 3.1+ has - // rolled out on those networks and the new - // `getDocuments` V1 wire format is on by default. The - // trigger is: a HardFork shipping the V1 wire format - // becomes active on mainnet/testnet. Until then, pinning - // 11 keeps the SDK speaking the V0 protocol the active - // tenderdash quorums understand. - resolvedPlatformVersion = 11 - case .devnet, .regtest: - resolvedPlatformVersion = 12 - } - } - config.platform_version = resolvedPlatformVersion + // `0` is passed straight through: the FFI `apply_version(builder, 0)` + // returns the builder unchanged, so `SdkBuilder::build()` seeds at the + // per-network `min_protocol_version` floor with auto-detect on + // (version_pinned=false) and ratchets up as the network reports newer + // versions. A non-zero value is an explicit pin via `with_version`. + config.platform_version = platformVersion // Create SDK with trusted setup. DAPI / quorum-URL overrides come from // UserDefaults and apply on: