Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow configuring target block time for a signet #27446

Closed

Conversation

benthecarman
Copy link
Contributor

@benthecarman benthecarman commented Apr 11, 2023

This pull request introduces the ability to configure the block time of a custom Bitcoin signet network, allowing people to have a signet that is easier to test with. The change helps to improve the flexibility of signet, making it more useful for diverse testing purposes. For example, I am trying to setup a signet with a 30 second block time and this caused a bunch of difficulty adjustments to happen making the network inconsistent. Regtest isn't a real viable alternative to me here because we would like defaults to use our custom signet if configured, without hindering of local regtest development.

@DrahtBot
Copy link
Contributor

DrahtBot commented Apr 11, 2023

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

Code Coverage

For detailed information about the code coverage, see the test coverage report.

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK rsafier, RandyMcMillan, ekzyis
Concept ACK stickies-v, ghost, kristapsk, litch, dangershony
Approach NACK TheCharlatan

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

Conflicts

No conflicts as of last run.

@ajtowns
Copy link
Contributor

ajtowns commented Apr 11, 2023

Configurable consensus parameters seems like a great way to make the network inconsistent in general (in particular, if you get the parameter wrong, you'll end up marking valid blocks invalid, with various consequences).

What's the actual problem you're trying to solve here? Would it work to have the signet miner only generate blocks when the mempool has entries, and sit idle when it's empty, for instance? If you're trying to generate many blocks, then regtest is already better as it doesn't require a baseline proof of work, and simply having multiple regtest configs probably makes more sense.

src/chainparamsbase.cpp Outdated Show resolved Hide resolved
@RandyMcMillan
Copy link
Contributor

Concept ACK

Having more control over custom signet parameters/conditions seems really useful IMO.

@ghost
Copy link

ghost commented Apr 11, 2023

Concept ACK

To address the concern in #27446 (comment) maybe this works only for custom signet.

How?

Maybe if bitcoin.conf has signetchallenge=xxx in it?

@benthecarman
Copy link
Contributor Author

Configurable consensus parameters seems like a great way to make the network inconsistent in general (in particular, if you get the parameter wrong, you'll end up marking valid blocks invalid, with various consequences).

I don't know if that is a really fair criticism for signet, -signetchallenge is a consensus param as well.

If you're trying to generate many blocks, then regtest is already better as it doesn't require a baseline proof of work, and simply having multiple regtest configs probably makes more sense.

This doesn't really fit our usecase because we can't have app defaults that differ between different regtests.

@benthecarman
Copy link
Contributor Author

benthecarman commented Apr 11, 2023

Maybe if bitcoin.conf has signetchallenge=xxx in it?

Yes, this currently will throw an error if you don't have signet challenge set.

@benthecarman benthecarman force-pushed the configure-signet-blockitme branch from 1bdb26a to 15ca24b Compare April 11, 2023 17:15
Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

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

utACK 15ca24b

@earonesty
Copy link

concept ack. signet is for tinkering

@rsafier
Copy link

rsafier commented Apr 11, 2023

Concept ACK. Been wanting this for a while

src/chainparams.cpp Outdated Show resolved Hide resolved
src/chainparams.cpp Outdated Show resolved Hide resolved
@benthecarman benthecarman force-pushed the configure-signet-blockitme branch from 15ca24b to 2a599a3 Compare April 11, 2023 21:34
@benthecarman benthecarman changed the title Allow configuirng target block time for a signet Allow configuring target block time for a signet Apr 12, 2023
src/chainparams.cpp Outdated Show resolved Hide resolved
Copy link
Contributor

@stickies-v stickies-v left a comment

Choose a reason for hiding this comment

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

Concept ACK, I've seen the need for signet custom block times come up quite often and I think it makes sense.

Comment on lines 35 to 33
if (!args.IsArgSet("-signetchallenge")) {
throw std::runtime_error(strprintf("%s: -signetblocktime cannot be set without -signetchallenge", __func__));
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Would InitParameterInteraction() (init.cpp) be a better place for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Looks like it is only networking settings in there and all of them only print error logs, I think we'd want to explicitly throw in this case

Copy link
Contributor

Choose a reason for hiding this comment

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

You're right, we do want to throw. AppInitParameterInteraction() does seem to raise InitError based on bad parameter interaction. I'm not sure why we have both AppInitParameterInteraction() and InitParameterInteraction() and which needs to be used when, it just seems like since this effectively is parameter interaction we'd like to raise that somewhere in here. Hopefully someone else can chime in?

src/chainparams.cpp Outdated Show resolved Hide resolved
src/kernel/chainparams.h Outdated Show resolved Hide resolved
@@ -25,6 +25,7 @@ void SetupChainParamsBaseOptions(ArgsManager& argsman)
argsman.AddArg("-vbparams=deployment:start:end[:min_activation_height]", "Use given start/end times and min_activation_height for specified version bits deployment (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
argsman.AddArg("-signet", "Use the signet chain. Equivalent to -chain=signet. Note that the network is defined by the -signetchallenge parameter", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
argsman.AddArg("-signetchallenge", "Blocks must satisfy the given script to be considered valid (only for signet networks; defaults to the global default signet test network challenge)", ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_NEGATION, OptionsCategory::CHAINPARAMS);
argsman.AddArg("-signetblocktime", "Difficulty adjustment will target a block time of the given amount in seconds (only for signet networks; defaults to 10 minutes)", ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_NEGATION, OptionsCategory::CHAINPARAMS);
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: I'd define the default in a variable and use it here to avoid hardcoding the default here so it doesn't go out of sync

Copy link
Contributor

Choose a reason for hiding this comment

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

I think the doc also needs to specify that -signetchallenge is required when using this option

src/kernel/chainparams.cpp Outdated Show resolved Hide resolved
@carnhofdaki
Copy link
Contributor

How does it work in Elements (Blockstream Liquid)? Is the 1-minute block time hardwired there?

I agree with @ajtowns this may cause inconsistencies (and I would add "confusion"). For example nodes that will not set the parameter to the same value as miners will simply refuse the blocks which do not fit their point-of-view. So in the end the parameter would need to be distributed the same way as signetchallenge (which is a once and for all setting) and can not be changed on-the-fly on an already-running custom Signet network with uncountable number of nodes.

@stickies-v
Copy link
Contributor

So in the end the parameter would need to be distributed the same way as signetchallenge

I had similar thoughts and think eventually we may want to introduce a more encompassing (and upgradeable) parameter such as -signetconfig in which all signet consensus parameters are encoded (currently just challenge and blocktime), but I think starting with the current modular approach is fine given that it's signet.

@ajtowns
Copy link
Contributor

ajtowns commented Apr 12, 2023

Configurable consensus parameters seems like a great way to make the network inconsistent in general (in particular, if you get the parameter wrong, you'll end up marking valid blocks invalid, with various consequences).
I don't know if that is a really fair criticism for signet, -signetchallenge is a consensus param as well.

Two nodes with different signetchallenges will immediately realise they don't want to talk to each other -- at the p2p (and wallet, iirc) level their network MessageStart values will disagree, and at the consensus level they won't agree on the validity as of the first block after genesis.

If you're trying to generate many blocks, then regtest is already better as it doesn't require a baseline proof of work, and simply having multiple regtest configs probably makes more sense.
This doesn't really fit our usecase because we can't have app defaults that differ between different regtests.

That doesn't sound like it makes sense; there isn't a global regtest, so simply by supporting regtest at all you already can handle different regtests... (I would have expected the objection to be that you want this to be shared with random users, and that you don't want those random users to be able to trigger an unwanted reorg by creating their own regtest blocks)

But if you're demoing to users what it's like to use bitcoin, just without the risk of losing real money, then 30s blocks is pretty misleading (by a factor of 20x even without taking variance into account) -- not that that's a bad thing in an of itself (eth and liquid do fine with blocks around that frequency) but the code in bitcoind is for bitcoin, and it's hard enough to get that right, without adding other random features...

@benthecarman benthecarman force-pushed the configure-signet-blockitme branch from 2a599a3 to 922aa7a Compare April 12, 2023 17:55
@benthecarman
Copy link
Contributor Author

Pushed up some changes to respond to @stickies-v and @MarcoFalke's review

@benthecarman
Copy link
Contributor Author

benthecarman commented Apr 12, 2023

@ajtowns I don't think I am properly communicating my usecase correctly, but there are lots of concept acks from other developers that run signets as well. People want to use custom signets to have their own test networks, I don't see why we should disallow having custom block times. The main concern being people don't copy-paste the param into their conf and have troubles syncing, doesn't seem like a valid one given that they could do the same for -signetchallenge. I understand that it would cause a failure on block 1 vs block 2016, but normally those blocks are synced near instantly anyways.

src/chainparams.cpp Outdated Show resolved Hide resolved
@benthecarman benthecarman force-pushed the configure-signet-blockitme branch from 922aa7a to d8434da Compare April 12, 2023 18:54
@benthecarman
Copy link
Contributor Author

If anyone is interested in testing, I am running this for a custom signet.

[signet]
signetchallenge=512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae
signetblocktime=30
addnode=45.79.52.207:38333
dnsseed=0

Block explorer: https://mutinynet.com
faucet: https://faucet.mutinynet.com

There is also a rapid gossip sync server and some lightning nodes as well

@rsafier
Copy link

rsafier commented Apr 12, 2023

I made some quick mods to have working docker for this PR: https://github.com/rsafier/bitcoin_signet/tree/carman-blocktime-adjustable

I used it to get my 10Msats.

@rsafier
Copy link

rsafier commented Apr 15, 2023

ACK d8434da
Tested against parameters for Mutinynet above, Plebnet Playground, ZBD signet as a client, synced up no issues.
Tested mining on throw away random signet at 1s block time target for 2300 blocks, seems good, didn't suddenly get harder.

@RandyMcMillan
Copy link
Contributor

utACK d8434da

@luke-jr
Copy link
Member

luke-jr commented Jul 31, 2023

...the purpose of including signet in this repo is about making it easier to test bitcoin, not about building your own altcoin with different parameters. How does using a 30s signet do anything but encourage developers to build software that will only work well on altcoins (like liquid...

Just thought I should point out that Liquid is Bitcoin, not an altcoin.

@bitcoin bitcoin deleted a comment from BvsCapitalpay Jul 31, 2023
@chrisguida
Copy link

#27446 (comment)

How does using a 30s signet do anything but encourage developers to build software that will only work well on altcoins (like liquid and ethereum) with more frequent blocks than bitcoin?

I don't understand the above criticism at all.. obviously people using the 30s signet are using it only for development purposes. It helps with development, especially for second-layer protocols and apps, because it vastly reduces the time you need to wait for things to happen.

I don't think any developer using 30-second block times would be unaware that mainnet has 10-minute block times, and I very much doubt any developers will fail to consider mainnet block times in their apps. If somehow they do, they'll quickly discover their error as soon as they deploy to mainnet. In this case it's obviously the fault of the developers themselves, or at most the fault of the signet operators. I don't see how this could possibly lead to people creating issues in this repo.

But perhaps I'm missing something...

@cmdruid
Copy link

cmdruid commented Nov 6, 2023

Regtest is not an option if you want to host your own test network for other users to test your software, as anyone can grief the network by generating blocks. Default testnet/signet is too slow for actual testing.

I'd like the ability to host a test network that outside users can use, but not grief, while having fast block times (or even no time restriction at all) so that I can incorporate it into CI/CD for different projects.

This seems like a real obvious tool to have for development of bitcoin infrastructure, and it is kind of crazy the only two options are regtest where everyone has god mode, or you are stuck with normal block times for testing.

I'll just download and use the mutiny-net fork, which is fine for me, but if people are worried about fragmentation, I think having to use multiple forks of bitcoin for tooling is more dangerous than having multiple params for signet.

@DrahtBot DrahtBot requested a review from stickies-v November 6, 2023 01:12
@jsarenik
Copy link

jsarenik commented Nov 6, 2023

@ajtowns wrote:

What's the actual problem you're trying to solve here? Would it work to have the signet miner only generate blocks when the mempool has entries, and sit idle when it's empty, for instance? If you're trying to generate many blocks, then regtest is already better as it doesn't require a baseline proof of work, and simply having multiple regtest configs probably makes more sense.

The last comment above makes a point. It really is hard when anyone can spam the regtest with blocks. Could that be somehow prevented? E.g. a signet-mode in regtest (only permissioned keys can mine)?

@cmdruid Thanks for comment! IMHO it sheds new light on this.

EDIT: The original link to comment wanted to refer to cmdruid's comment. Apologies for unrelated link.

@achow101
Copy link
Member

Closing as there is continued disagreement over the approach and no further changes have been made to this PR. This seems to be at a stalemate and unlikely to go anywhere.

@achow101 achow101 closed this Jan 10, 2024
@starius
Copy link
Contributor

starius commented Jan 31, 2024

Approach NACK.
I get this - wasting time waiting for confirmations is more than annoying. Its effect usually lingers, because you loose context in the meantime and it slows down development in your entire organization. However, I also think supporting options that might lead to clients running disagreeing consensus rules on the same network is dangerous and might annoy developers in fresh ways. I would support the approach laid out by ajtowns in this comment.

If someone wants to do this, feel free to make it. I think that this approach is much simpler. It is already being used by multiple companies and individuals with no issues.

I want to do this. I implemented the code proposed in this comment and managed to sync with mutinynet. I'm writing tests. Expect a PR soon :)

starius added a commit to starius/bitcoin that referenced this pull request Feb 1, 2024
Inspired by bitcoin#27446, this commit
implements the proposal detailed in the comment
bitcoin#27446 (comment).

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.

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 commit 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:

signet=1
[signet]
signetchallenge=6a4c09011e000000000000004c25512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae
addnode=45.79.52.207:38333
dnsseed=0

The content of this wrapped challenge:

6a OP_RETURN
4c OP_PUSHDATA1
09 (length of signet params = 9)
011e00000000000000 (signet params: 0x01, pow_target_spacing=30)
4c OP_PUSHDATA1
25 (length of challenge = 37)
512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae
(original Mutinynet challenge, can be found here:
https://blog.mutinywallet.com/mutinynet/ )
starius added a commit to starius/bitcoin that referenced this pull request Feb 1, 2024
Inspired by bitcoin#27446, this commit
implements the proposal detailed in the comment
bitcoin#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.

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 commit 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:

signet=1
[signet]
signetchallenge=6a4c09011e000000000000004c25512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae
addnode=45.79.52.207:38333
dnsseed=0

The content of this wrapped challenge:

6a OP_RETURN
4c OP_PUSHDATA1
09 (length of signet params = 9)
011e00000000000000 (signet params: 0x01, pow_target_spacing=30)
4c OP_PUSHDATA1
25 (length of challenge = 37)
512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae
(original Mutinynet challenge, can be found here:
https://blog.mutinywallet.com/mutinynet/ )
starius added a commit to starius/bitcoin that referenced this pull request Feb 1, 2024
Inspired by bitcoin#27446, this commit
implements the proposal detailed in the comment
bitcoin#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.

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 commit 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:

signet=1
[signet]
signetchallenge=6a4c09011e000000000000004c25512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae
addnode=45.79.52.207:38333
dnsseed=0

The content of this wrapped challenge:

6a OP_RETURN
4c OP_PUSHDATA1
09 (length of signet params = 9)
011e00000000000000 (signet params: 0x01, pow_target_spacing=30)
4c OP_PUSHDATA1
25 (length of challenge = 37)
512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae
(original Mutinynet challenge, can be found here:
https://blog.mutinywallet.com/mutinynet/ )
starius added a commit to starius/bitcoin that referenced this pull request Feb 1, 2024
Inspired by bitcoin#27446, this commit
implements the proposal detailed in the comment
bitcoin#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 commit 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:

signet=1
[signet]
signetchallenge=6a4c09011e000000000000004c25512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae
addnode=45.79.52.207:38333
dnsseed=0

The content of this wrapped challenge:

6a OP_RETURN
4c OP_PUSHDATA1
09 (length of signet params = 9)
011e00000000000000 (signet params: 0x01, pow_target_spacing=30)
4c OP_PUSHDATA1
25 (length of challenge = 37)
512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae
(original Mutinynet challenge, can be found here:
https://blog.mutinywallet.com/mutinynet/ )
starius added a commit to starius/bitcoin that referenced this pull request Feb 1, 2024
Inspired by bitcoin#27446, this commit
implements the proposal detailed in the comment
bitcoin#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 commit 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:

signet=1
[signet]
signetchallenge=6a4c09011e000000000000004c25512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae
addnode=45.79.52.207:38333
dnsseed=0

The content of this wrapped challenge:

6a OP_RETURN
4c OP_PUSHDATA1
09 (length of signet params = 9)
011e00000000000000 (signet params: 0x01, pow_target_spacing=30)
4c OP_PUSHDATA1
25 (length of challenge = 37)
512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae
(original Mutinynet challenge, can be found here:
https://blog.mutinywallet.com/mutinynet/ )
starius added a commit to starius/bitcoin that referenced this pull request Feb 26, 2024
Inspired by bitcoin#27446, this commit
implements the proposal detailed in the comment
bitcoin#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 commit 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:

signet=1
[signet]
signetchallenge=6a4c09011e000000000000004c25512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae
addnode=45.79.52.207:38333
dnsseed=0

The content of this wrapped challenge:

6a OP_RETURN
4c OP_PUSHDATA1
09 (length of signet params = 9)
011e00000000000000 (signet params: 0x01, pow_target_spacing=30)
4c OP_PUSHDATA1
25 (length of challenge = 37)
512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae
(original Mutinynet challenge, can be found here:
https://blog.mutinywallet.com/mutinynet/ )
starius added a commit to starius/bitcoin that referenced this pull request Sep 29, 2024
Inspired by bitcoin#27446, this commit
implements the proposal detailed in the comment
bitcoin#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 commit 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:

signet=1
[signet]
signetchallenge=6a4c09011e000000000000004c25512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae
addnode=45.79.52.207:38333
dnsseed=0

The content of this wrapped challenge:

6a OP_RETURN
4c OP_PUSHDATA1
09 (length of signet params = 9)
011e00000000000000 (signet params: 0x01, pow_target_spacing=30)
4c OP_PUSHDATA1
25 (length of challenge = 37)
512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae
(original Mutinynet challenge, can be found here:
https://blog.mutinywallet.com/mutinynet/ )
starius added a commit to starius/bitcoin that referenced this pull request Dec 31, 2024
Inspired by bitcoin#27446, this commit
implements the proposal detailed in the comment
bitcoin#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, a test case was added with the value
of -signetchallenge set to the wrapped challenge, setting spacing to 30 seconds
and having the 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 commit 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:

signet=1
[signet]
signetchallenge=6a4c09011e000000000000004c25512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae
addnode=45.79.52.207:38333
dnsseed=0

The content of this wrapped challenge:

6a OP_RETURN
4c OP_PUSHDATA1
09 (length of signet params = 9)
011e00000000000000 (signet params: 0x01, pow_target_spacing=30)
4c OP_PUSHDATA1
25 (length of challenge = 37)
512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae
(original Mutinynet challenge, can be found here:
https://blog.mutinywallet.com/mutinynet/ )
starius added a commit to starius/bitcoin that referenced this pull request Dec 31, 2024
Inspired by bitcoin#27446, this commit
implements the proposal detailed in the comment
bitcoin#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, a test case was added with the value
of -signetchallenge set to the wrapped challenge, setting spacing to 30 seconds
and having the 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 commit 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:

signet=1
[signet]
signetchallenge=6a4c09011e000000000000004c25512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae
addnode=45.79.52.207:38333
dnsseed=0

The content of this wrapped challenge:

6a OP_RETURN
4c OP_PUSHDATA1
09 (length of signet params = 9)
011e00000000000000 (signet params: 0x01, pow_target_spacing=30)
4c OP_PUSHDATA1
25 (length of challenge = 37)
512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae
(original Mutinynet challenge, can be found here:
https://blog.mutinywallet.com/mutinynet/ )
starius added a commit to starius/bitcoin that referenced this pull request Dec 31, 2024
Inspired by bitcoin#27446, this commit
implements the proposal detailed in the comment
bitcoin#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, a test case was added with the value
of -signetchallenge set to the wrapped challenge, setting spacing to 30 seconds
and having the 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 commit 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:

signet=1
[signet]
signetchallenge=6a4c09011e000000000000004c25512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae
addnode=45.79.52.207:38333
dnsseed=0

The content of this wrapped challenge:

6a OP_RETURN
4c OP_PUSHDATA1
09 (length of signet params = 9)
011e00000000000000 (signet params: 0x01, pow_target_spacing=30)
4c OP_PUSHDATA1
25 (length of challenge = 37)
512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae
(original Mutinynet challenge, can be found here:
https://blog.mutinywallet.com/mutinynet/ )
starius added a commit to starius/bitcoin that referenced this pull request Dec 31, 2024
Inspired by bitcoin#27446, this commit
implements the proposal detailed in the comment
bitcoin#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, a test case was added with the value
of -signetchallenge set to the wrapped challenge, setting spacing to 30 seconds
and having the 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 commit 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:

signet=1
[signet]
signetchallenge=6a4c09011e000000000000004c25512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae
addnode=45.79.52.207:38333
dnsseed=0

The content of this wrapped challenge:

6a OP_RETURN
4c OP_PUSHDATA1
09 (length of signet params = 9)
011e00000000000000 (signet params: 0x01, pow_target_spacing=30)
4c OP_PUSHDATA1
25 (length of challenge = 37)
512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae
(original Mutinynet challenge, can be found here:
https://blog.mutinywallet.com/mutinynet/ )
starius added a commit to starius/bitcoin that referenced this pull request Dec 31, 2024
Inspired by bitcoin#27446, this commit
implements the proposal detailed in the comment
bitcoin#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, a test case was added with the value
of -signetchallenge set to the wrapped challenge, setting spacing to 30 seconds
and having the 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 commit 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:

signet=1
[signet]
signetchallenge=6a4c09011e000000000000004c25512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae
addnode=45.79.52.207:38333
dnsseed=0

The content of this wrapped challenge:

6a OP_RETURN
4c OP_PUSHDATA1
09 (length of signet params = 9)
011e00000000000000 (signet params: 0x01, pow_target_spacing=30)
4c OP_PUSHDATA1
25 (length of challenge = 37)
512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae
(original Mutinynet challenge, can be found here:
https://blog.mutinywallet.com/mutinynet/ )
starius added a commit to starius/bitcoin that referenced this pull request Jan 2, 2025
Inspired by bitcoin#27446, this commit
implements the proposal detailed in the comment
bitcoin#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.

Under the previous rules, such a signet challenge would always evaluate to
false, suggesting that it is likely not in use by anyone. Updating bitcoind to a
version that includes this change will not cause any disruptions - existing
signet challenges will retain their original meaning without alteration.

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, a test case was added with the value
of -signetchallenge set to the wrapped challenge, setting spacing to 30 seconds
and having the 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 commit 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:

signet=1
[signet]
signetchallenge=6a4c09011e000000000000004c25512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae
addnode=45.79.52.207:38333
dnsseed=0

The content of this wrapped challenge:

6a OP_RETURN
4c OP_PUSHDATA1
09 (length of signet params = 9)
011e00000000000000 (signet params: 0x01, pow_target_spacing=30)
4c OP_PUSHDATA1
25 (length of challenge = 37)
512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae
(original Mutinynet challenge, can be found here:
https://blog.mutinywallet.com/mutinynet/ )
@bitcoin bitcoin locked and limited conversation to collaborators Jan 30, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.