Skip to content

dash-spv: support Dash Core's devnet LLMQ routing overrides (-llmqchainlocks / -llmqinstantsenddip0024 / -llmqplatform) #785

Open

Description

@QuantumExplorer

Background

PR #784 adds -llmqdevnetparams=<size>:<threshold> support, which faithfully mirrors Dash Core's flag of the same name. In Dash Core, that flag only adjusts the size/threshold of LLMQ_DEVNET (type 101) — confirmed in chainparams.cpp:

auto params = std::ranges::find_if(consensus.llmqs, [](const auto& llmq){
    return llmq.type == Consensus::LLMQType::LLMQ_DEVNET;});  // only 101

LLMQ_DEVNET_DIP0024 (105) and LLMQ_DEVNET_PLATFORM (107) keep their hardcoded defaults regardless of that flag.

The gap

Dash Core ships three companion flags that small devnets routinely rely on (declared in chainparams.cpp):

-llmqchainlocks=<quorum name>          (default: llmq_devnet)
-llmqinstantsenddip0024=<quorum name>  (default: llmq_devnet_dip0024)
-llmqplatform=<quorum name>            (default: llmq_devnet_platform)

These don't change a quorum's size — they change which LLMQ type fulfills each role. The typical small-devnet recipe is to shrink LLMQ_DEVNET (via -llmqdevnetparams) to fit the masternode count, then reroute ChainLocks / InstantSend DIP24 / Platform onto it, because the default 105/107 quorums (8 and 12 members) can't form on a small MN set.

In rust-dashcore today, the routing is hardcoded in dash/src/sml/llmq_type/network.rs:

fn is_llmq_type(&self) -> LLMQType { ... Network::Devnet => LlmqtypeDevnet, ... }
fn isd_llmq_type(&self) -> LLMQType { ... Network::Devnet => LlmqtypeDevnetDIP0024, ... }
fn chain_locks_type(&self) -> LLMQType { ... Network::Devnet => LlmqtypeDevnet, ... }
fn platform_type(&self) -> LLMQType { ... Network::Devnet => LlmqtypeDevnetPlatform, ... }

Consequence: an SPV client talking to a devnet started with, say, -llmqinstantsenddip0024=llmq_devnet will keep hunting for LlmqtypeDevnetDIP0024 quorums, find none, and silently fail to verify InstantSend locks. Same story for rerouted ChainLocks / Platform.

Proposed solution

Allow per-instance overrides of the four NetworkLLMQExt lookups on devnet, surfaced through ClientConfig and the CLI.

ClientConfig (dash-spv)

pub struct ClientConfig {
    // ...
    pub llmq_devnet_params: Option<LlmqDevnetParams>,         // already in PR #784
    pub llmq_chainlocks_type: Option<LLMQType>,                // new
    pub llmq_instantsend_dip0024_type: Option<LLMQType>,       // new
    pub llmq_platform_type: Option<LLMQType>,                  // new
    // (and a builder method for each — Devnet-only validation, same as llmq_devnet_params)
}

CLI (dash-spv binary)

--llmq-chainlocks=<quorum-name>
--llmq-instantsend-dip0024=<quorum-name>
--llmq-platform=<quorum-name>

Mirroring Dash Core's flag names. Quorum name strings should accept llmq_devnet, llmq_devnet_dip0024, llmq_devnet_platform at minimum (the set of LLMQ types valid on devnet).

Routing change

NetworkLLMQExt currently takes &self (a Network). The cleanest way to thread overrides through is to either:

  • Option A — add a NetworkLLMQContext { network: Network, overrides: DevnetRouting } and have callers use that instead of Network. Clean, but touches many call sites.
  • Option B — apply the same OnceLock global-override pattern PR feat: devnet support for dash-spv #784 introduced for LLMQ_DEVNET params: set_devnet_chainlocks_type(t), set_devnet_isd_type(t), set_devnet_platform_type(t). Smaller diff, idempotent contract is already established. Tradeoff: same process-global limitation as the existing override.

Option B is consistent with what's already there and probably the right pragmatic call.

Out of scope

  • Changes to mainnet/testnet/regtest routing — these flags are devnet-only in Dash Core.
  • Per-quorum size overrides beyond LLMQ_DEVNET — Dash Core itself doesn't expose those.

Acceptance criteria

  • CLI accepts the three flags; rejected on non-devnet networks
  • ClientConfig carries the overrides through to startup
  • chain_locks_type / isd_llmq_type / platform_type return the overridden values when set
  • enabled_llmq_types includes the overridden types
  • Unit tests cover override-set / override-unset / cross-network rejection
  • Existing PR feat: devnet support for dash-spv #784 test (test_llmq_devnet_override_lifecycle) stays green

References

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

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions