Inspired by #27446, this PR implements the proposal detailed in the comment #27446 (comment).
Rationale
Introduce the ability to configure a custom target time between blocks in a custom Bitcoin signet network. This enhancement enables users to create a signet that is more conducive to testing. The change enhances the flexibility of signet, rendering it more versatile for various testing scenarios. For instance, I am currently working on setting up a signet with a 30-second block time. However, this caused numerous difficulty adjustments, resulting in an inconsistent network state. Regtest isn’t a viable alternative for me in this context since we prefer defaults to utilize our custom signet when configured, without impeding local regtest development.
Implementation
If the challenge format is OP_RETURN PUSHDATA<params> PUSHDATA<actual challenge>
, the actual challenge from the second data push is used as the signet challenge, and the parameters from the first push are used to configure the network. Otherwise the challenge is used as is.
This change is backward-compatible, as per the old rules, such a signet challenge would always evaluate to false, rendering it unused.
The only parameter currently available is “target_spacing” (default 600 seconds). To set it, place 0x01<target_spacing as uint64_t, little endian>
in the params. Empty params are also valid. If other network parameters are added in the future, they should use 0x02<option 2 value>
, 0x03<option 3 value>
, etc., following the protobuf style.
Two public functions were added to chainparams.h
:
ParseWrappedSignetChallenge
: Extracts signet params and signet challenge from a wrapped signet challenge.ParseSignetParams
: Parses<params>
bytes of the first data push.
Function ReadSigNetArgs
calls ParseWrappedSignetChallenge
and ParseSignetParams
to implement the new meaning of signetchallenge.
The description of the flag -signetchallenge
was updated to reflect the changes.
A new unit tests file, chainparams_tests.cpp
, was added, containing tests for ParseWrappedSignetChallenge
and ParseSignetParams
.
The test signet_parse_tests
from the file validation_tests.cpp
was modified to ensure proper understanding of the new logic.
In the functional test feature_signet.py
, the value of -signetchallenge
was changed from OP_TRUE
to the wrapped challenge, setting spacing to 30 seconds and having the same actual challenge OP_TRUE
.
The Signet miner was updated, introducing a new option --target-spacing
with a default of 600 seconds. It must be set to the value used by the network.
Example
I tested this PR against Mutinynet, a signet running on a custom fork of Bitcoin Core, implementing 30s target spacing. I successfully synchronized the blockchain using the following config:
0signet=1
1[signet]
2signetchallenge=6a4c09011e000000000000004c25512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae
3addnode=45.79.52.207:38333
4dnsseed=0
The content of this wrapped challenge:
06a OP_RETURN
14c OP_PUSHDATA1
209 (length of signet params = 9)
3011e00000000000000 (signet params: 0x01, pow_target_spacing=30)
44c OP_PUSHDATA1
525 (length of challenge = 37)
6512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae
7(original Mutinynet challenge)