feature: Use different datadirs for different signets #34566

pull ekzyis wants to merge 1 commits into bitcoin:master from ekzyis:signet-datadirs changing 6 files +126 −20
  1. ekzyis commented at 7:46 PM on February 11, 2026: none

    closes #27494

    This adds support for syncing multiple signets.

    Each custom signet is stored in a different datadir, using the network magic (message start) as the suffix.

    The default signet is always stored without a suffix for backward compatibility, even if the default challenge is provided explicitly via -signetchallenge.

    This builds upon #29838.

    For those already familiar with #29838, here are the differences between #29838 and this that are visible to the user:

    [^1]: could be something for a follow-up PR, or maybe it's intentional to not mix explicit with implicit options?

    Unlike #29838, this PR does not update tests that didn't break (rpc_bind.py, interface_bitcoin_cli.py). I have found other tests where datadir_path is used in combination with self.chain (regexp: datadir_path.*chain). I considered it inconsistent to update some tests but not all of them. I've decided to not update all of them to keep the scope of this PR low until feedback. I can go through all tests in a follow-up PR to make sure they don't break when they are ever used with (custom) signet, however unlikely that might be.

    I have done some manual testing like this:

    <details> <summary>manual testing</summary>

    1. 'signet' directory is used, IBD:
    $ bitcoind -signet
    
    1. 'signet' directory is used, no IBD without -addnode (see #29838 (comment)) or existing peers.dat:
    $ bitcoind -signet -signetchallenge=512103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430210359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c452ae
    
    1. 'signet' directory is used
    $ bitcoind -conf="signet_default.conf"
    
    # signet_default.conf
    signet=1
    [signet]
    signetchallenge=512103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430210359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c452ae
    
    1. 'signet_f6ac8550' directory is used:
    $ bitcoind -conf="signet_custom.conf"
    
    # signet_custom.conf
    signet=1
    [signet]
    signetchallenge=0014d4528367459d54e1545b0d0a677d2a7d71d648e0
    

    Tested RPC with bitcoin-cli getblockchaininfo with the same options (-signet, -conf, or -signet -signetchallenge)

    </details>

    I'm new to contributing to Bitcoin Core so it's entirely possible that I've missed something obvious.

  2. DrahtBot commented at 7:47 PM on February 11, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    Concept ACK pinheadmz, RandyMcMillan

    If your review is incorrectly listed, please copy-paste <code>&lt;!--meta-tag:bot-skip--&gt;</code> into the comment that the bot should ignore.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #34927 (test: Check that RPCs do not time out, even under load by maflcko)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

  3. ekzyis marked this as a draft on Feb 11, 2026
  4. ekzyis commented at 8:04 PM on February 11, 2026: none

    Will keep this in draft until I fix why tool_signet_miner.py is failing in CI (but not locally for some reason)

    Update: Ah, it's because the CI runs it with --usecli

  5. DrahtBot added the label CI failed on Feb 11, 2026
  6. ekzyis force-pushed on Feb 11, 2026
  7. ekzyis force-pushed on Feb 12, 2026
  8. ekzyis force-pushed on Feb 12, 2026
  9. ekzyis renamed this:
    feature: Use separate datadirs for each signet
    feature: Use different datadirs for different signets
    on Feb 12, 2026
  10. ekzyis force-pushed on Feb 12, 2026
  11. ekzyis force-pushed on Feb 12, 2026
  12. DrahtBot removed the label CI failed on Feb 12, 2026
  13. ekzyis marked this as ready for review on Feb 12, 2026
  14. ekzyis force-pushed on Feb 12, 2026
  15. sedited commented at 5:09 PM on March 8, 2026: contributor

    This hasn't gotten any attention so far. @ajtowns do you want to take a look here since you opened the original issue?

  16. ekzyis force-pushed on Apr 6, 2026
  17. ekzyis commented at 11:12 PM on April 6, 2026: none

    rebased on master (b730dc3301f)

  18. in test/functional/feature_signet.py:125 in c4765b3c3a outdated
     120 | +        self.log.info("Test that the signet data directory with -signetchallenge=51 is 'signet_51'")
     121 | +        assert_node_datadir(self.nodes[0], "signet_51")
     122 | +
     123 | +        self.log.info("Test that the main signet data directory is 'signet'")
     124 | +        assert_node_datadir(self.nodes[3], "signet")
     125 | +
    


    ViniciusCestarii commented at 1:23 PM on April 8, 2026:

    Missing a test that verifies truncation to 16 chars for a longer challenge. The 522103ad5e... signet challenge would work. Just add an assert_node_datadir(self.nodes[4], "signet_522103ad5e0edad1") check.


    ekzyis commented at 1:43 PM on April 8, 2026:

    Oh, right, thanks! Done in a2d755132b4

  19. in src/chainparamsbase.cpp:40 in c4765b3c3a outdated
      32 | @@ -33,6 +33,18 @@ const CBaseChainParams& BaseParams()
      33 |      return *globalChainBaseParams;
      34 |  }
      35 |  
      36 | +std::string GetSignetDataDir()
      37 | +{
      38 | +    std::string base_data_dir = "signet";
      39 | +    const std::string signet_challenge = gArgs.GetArg("-signetchallenge", "");
      40 | +    const std::string default_signet_challenge = "512103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430210359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c452ae";
    


    ViniciusCestarii commented at 1:38 PM on April 8, 2026:

    The default signet challenge string is now duplicated in chainparamsbase.cpp and kernel/chainparams.cpp (and also in the Python test framework). I'm not sure if this is actually a problem, but could this be defined as a shared constant? I'm still learning the codebase, so I'd appreciate some input for better practices here.


    ekzyis commented at 1:46 PM on April 8, 2026:

    I had the same question, and since I’m also new, I was hoping for feedback from more experienced developers as well


    ekzyis commented at 2:19 PM on April 8, 2026:

    I fixed this in 63cf3340748.

    I added test/functional/test_framework/signet.py so test_node.py and feature_signet.py can import the constant from there.

    For the C++ code, I'm now using HexStr(CChainParams::SigNet({})->GetConsensus().signet_challenge).

    Thanks for making me look into it again!


    ekzyis commented at 2:21 PM on April 8, 2026:

    Oh, this introduced a circular dependency:

    A new circular dependency in the form of "chainparams -> chainparamsbase -> chainparams" appears to have been introduced.

    https://github.com/bitcoin/bitcoin/actions/runs/24139839220/job/70438028501?pr=34566


    ekzyis commented at 3:34 PM on April 8, 2026:

    Fixed in 364969087e0. I accidentally included <chainparams.h> in chainparamsbase.cpp instead of <kernel/chainparams.h>.

  20. ekzyis force-pushed on Apr 8, 2026
  21. ekzyis force-pushed on Apr 8, 2026
  22. DrahtBot added the label CI failed on Apr 8, 2026
  23. ekzyis marked this as a draft on Apr 8, 2026
  24. ekzyis force-pushed on Apr 8, 2026
  25. DrahtBot removed the label CI failed on Apr 8, 2026
  26. in test/functional/tool_signet_miner.py:131 in 364969087e outdated
     127 | @@ -121,33 +128,33 @@ def run_test(self):
     128 |          node = self.nodes[0]
     129 |          # import private key needed for signing block
     130 |          wallet_importprivkey(node, bytes_to_wif(CHALLENGE_PRIVATE_KEY), 0)
     131 | -        self.mine_block(node)
     132 | +        self.mine_block(node, self.extra_args[0])
    


    pinheadmz commented at 4:02 PM on April 8, 2026:

    what is the extra_args parameter for?


    ekzyis commented at 5:22 PM on April 8, 2026:

    This passes the signet challenge of the node to mine_block. It's required to pass -signetchallenge to the RPC. Without it, RPC authentication fails because the cookie isn't found. It will look in the default signet datadir:

    $ build/test/functional/test_runner.py tool_signet_miner.py
    Temporary test directory at /tmp/nix-shell-115046-4006075642/test_runner_₿_šŸƒ_20260408_191958
    Remaining jobs: [tool_signet_miner.py]
    1/1 - tool_signet_miner.py failed, Duration: 0 s
    
    stdout:
    2026-04-08T17:19:58.648068Z TestFramework (INFO): PRNG seed is: 8822581970357866232
    2026-04-08T17:19:58.698730Z TestFramework (INFO): Initializing test directory /tmp/nix-shell-115046-4006075642/test_runner_₿_šŸƒ_20260408_191958/tool_signet_miner_0
    2026-04-08T17:19:59.085274Z TestFramework (INFO): Signet node with single signature challenge
    error: Authorization failed: Failed to read cookie file and no rpcpassword was specified. Configuration file: (/tmp/nix-shell-115046-4006075642/test_runner_₿_šŸƒ_20260408_191958/tool_signet_miner_0/node0/bitcoin.conf)
    
  27. pinheadmz commented at 4:03 PM on April 8, 2026: member

    concept ACK, I use a lot of different signets for educational projects and we could really use this. Personally I feel like using the magic bytes (message start) makes more sense and is less likely to collide between signet challenges

  28. ekzyis marked this as ready for review on Apr 8, 2026
  29. ekzyis force-pushed on Apr 8, 2026
  30. ekzyis force-pushed on Apr 8, 2026
  31. DrahtBot added the label CI failed on Apr 8, 2026
  32. ekzyis force-pushed on Apr 8, 2026
  33. ekzyis commented at 8:09 PM on April 8, 2026: none

    concept ACK, I use a lot of different signets for educational projects and we could really use this. Personally I feel like using the magic bytes (message start) makes more sense and is less likely to collide between signet challenges

    Right! 77cd6c99306 uses magic bytes as the suffix. Additionally to what you mentioned, I also like this for these reasons:

    • makes directory names shorter (was also mentioned in #29383 (comment))
    • consistent suffix length, independent of challenge length

    Updated commit message and PR description.

  34. DrahtBot removed the label CI failed on Apr 8, 2026
  35. RandyMcMillan commented at 2:31 PM on April 9, 2026: contributor

    concept ACK

  36. Use different datadirs for different signets
    This adds support for syncing multiple signets.
    
    Each custom signet is stored in a different datadir, using the network magic
    (message start) as the suffix.
    
    The default signet is always stored without a suffix for backward compatibility,
    even if the default challenge is provided explicitly via -signetchallenge.
    
    Co-authored-by: Brandon Odiwuor <brandon.odiwuor@gmail.com>
    f283eaac1d
  37. ekzyis force-pushed on Apr 10, 2026
  38. ekzyis commented at 11:50 AM on April 10, 2026: none

    I think "notable new feature" and "visible change to the end-user experience" from developer-notes.md apply here, so I added release notes in f283eaa.


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-04-13 21:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me