Skip to content

Commit 5ddb884

Browse files
committed
Add option to initialise a custom signet.
1 parent 78000dd commit 5ddb884

File tree

2 files changed

+103
-18
lines changed

2 files changed

+103
-18
lines changed

NBitcoin.Tests/NetworkTests.cs

100644100755
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,5 +81,48 @@ public void ReadMagicByteWithFirstByteDuplicated()
8181
Assert.True(found);
8282
}
8383
}
84+
85+
[Fact]
86+
[Trait("UnitTest", "UnitTest")]
87+
public void CanGetDefaultSignet()
88+
{
89+
var signet = Network.GetNetwork("signet");
90+
91+
Assert.NotNull(signet);
92+
93+
var consensusFactory = new ConsensusFactory();
94+
var block = consensusFactory.CreateBlock();
95+
block.ReadWrite(DataEncoders.Encoders.Hex.DecodeData(SignetSettings.DEFAULT_SIGNET_GENESIS_BLOCK), consensusFactory);
96+
97+
Assert.Equal(block.GetHash(), signet.GenesisHash);
98+
}
99+
100+
[Fact]
101+
[Trait("UnitTest", "UnitTest")]
102+
public void CanGetCustomSignet()
103+
{
104+
var customSignetName = "signet-custom";
105+
var customSignetChallenge = "5121033da06bd7068e9859ee902a0608df9b948829718c60c587f2e497ad4d7420e43151AE";
106+
var customSignetGenesisBlock = "0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a008f4d5fae77031e8ad222030101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000";
107+
var customSignetSeeds = new[]
108+
{
109+
"127.0.0.1",
110+
"[::1]"
111+
};
112+
113+
var signetSettings = new SignetSettings(customSignetName, customSignetChallenge, customSignetGenesisBlock, customSignetSeeds);
114+
115+
var initSignet = Bitcoin.Instance.InitCustomSignet(signetSettings);
116+
117+
Assert.NotNull(initSignet);
118+
119+
var customSignet = Network.GetNetwork(customSignetName);
120+
121+
var consensusFactory = new ConsensusFactory();
122+
var block = consensusFactory.CreateBlock();
123+
block.ReadWrite(DataEncoders.Encoders.Hex.DecodeData(customSignetGenesisBlock), consensusFactory);
124+
125+
Assert.Equal(block.GetHash(), customSignet.GenesisHash);
126+
}
84127
}
85128
}

NBitcoin/Bitcoin.Signet.cs

100644100755
Lines changed: 60 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,44 @@
22
using System;
33
using System.IO;
44
using System.Linq;
5+
using System.Net.NetworkInformation;
56

67
namespace NBitcoin
78
{
9+
public record struct SignetSettings(string Name, string Challenge, string GenesisBlock, string[] NetworkSeeds)
10+
{
11+
public const string DEFAULT_SIGNET_NAME = "signet";
12+
13+
public const string DEFAULT_SIGNET_CHALLENGE =
14+
"512103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430210359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c452ae";
15+
16+
public const string DEFAULT_SIGNET_GENESIS_BLOCK = "0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a008f4d5fae77031e8ad222030101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000";
17+
18+
public static readonly string[] DEFAULT_SIGNET_NETWORK_SEEDS = new[]
19+
{
20+
"178.128.221.177",
21+
"2a01:7c8:d005:390::5"
22+
};
23+
24+
public static readonly SignetSettings Default =
25+
new(DEFAULT_SIGNET_NAME, DEFAULT_SIGNET_CHALLENGE, DEFAULT_SIGNET_GENESIS_BLOCK, DEFAULT_SIGNET_NETWORK_SEEDS);
26+
}
27+
828
public partial class Bitcoin
929
{
10-
static readonly ChainName SignetName = new ChainName("Signet");
30+
static readonly ChainName SignetName = new ChainName(SignetSettings.DEFAULT_SIGNET_NAME);
1131

1232
public Network Signet => _Networks[SignetName];
1333

14-
private Network CreateSignet()
34+
private Network CreateSignet(
35+
string name = SignetSettings.DEFAULT_SIGNET_NAME,
36+
string challenge = SignetSettings.DEFAULT_SIGNET_CHALLENGE,
37+
string genesisBlock = SignetSettings.DEFAULT_SIGNET_GENESIS_BLOCK,
38+
string[] networkSeeds = null)
1539
{
40+
networkSeeds ??= SignetSettings.DEFAULT_SIGNET_NETWORK_SEEDS;
1641
NetworkBuilder builder = new NetworkBuilder();
17-
builder.SetChainName(SignetName);
42+
builder.SetChainName(name == SignetSettings.DEFAULT_SIGNET_NAME ? SignetName : new ChainName(name));
1843
builder.SetNetworkSet(this);
1944
builder.SetConsensus(new Consensus()
2045
{
@@ -43,39 +68,45 @@ private Network CreateSignet()
4368
.SetBech32(Bech32Type.WITNESS_PUBKEY_ADDRESS, "tb")
4469
.SetBech32(Bech32Type.WITNESS_SCRIPT_ADDRESS, "tb")
4570
.SetBech32(Bech32Type.TAPROOT_ADDRESS, "tb")
46-
.SetMagic(GetSignetMagic())
71+
.SetMagic(GetSignetMagic(challenge))
4772
.SetPort(38333)
4873
.SetRPCPort(38332)
49-
.SetName("signet")
50-
.AddAlias("bitcoin-signet")
51-
.AddAlias("btc-signet")
74+
.SetName(name)
75+
.SetGenesis(genesisBlock);
76+
77+
if (name == SignetSettings.DEFAULT_SIGNET_NAME)
78+
{
79+
builder.AddAlias("bitcoin-signet");
80+
builder.AddAlias("btc-signet");
81+
}
82+
5283
#if !NOSOCKET
53-
.AddSeeds(new[]
54-
{
55-
"178.128.221.177",
56-
"2a01:7c8:d005:390::5"
57-
}.Select(o => new Protocol.NetworkAddress(System.Net.IPAddress.Parse(o))))
84+
if (networkSeeds != null)
85+
{
86+
builder.AddSeeds(networkSeeds.Select(o => new Protocol.NetworkAddress(System.Net.IPAddress.Parse(o))));
87+
}
88+
else if (name == SignetSettings.DEFAULT_SIGNET_NAME)
89+
{
90+
builder.AddSeeds(SignetSettings.DEFAULT_SIGNET_NETWORK_SEEDS.Select(o => new Protocol.NetworkAddress(System.Net.IPAddress.Parse(o))));
91+
}
5892
#endif
59-
.SetGenesis(
60-
"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a008f4d5fae77031e8ad222030101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000");
6193

6294
var network = builder.BuildAndRegister();
6395
#if !NOFILEIO
6496
var data = Network.GetDefaultDataFolder("bitcoin");
6597
if (data != null)
6698
{
67-
var signetCookie = Path.Combine(data, "signet", ".cookie");
99+
var signetCookie = Path.Combine(data, name, ".cookie");
68100
RPC.RPCClient.RegisterDefaultCookiePath(network, signetCookie);
69101
}
70102
#endif
71103
_Networks.TryAdd(SignetName, network);
72104
return network;
73105
}
74106

75-
private static uint GetSignetMagic()
107+
private static uint GetSignetMagic(string challengeHex)
76108
{
77-
var challengeBytes = DataEncoders.Encoders.Hex.DecodeData(
78-
"512103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430210359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c452ae");
109+
var challengeBytes = DataEncoders.Encoders.Hex.DecodeData(challengeHex);
79110
var challenge = new Script(challengeBytes);
80111
MemoryStream ms = new MemoryStream();
81112
BitcoinStream bitcoinStream = new BitcoinStream(ms, true);
@@ -84,5 +115,16 @@ private static uint GetSignetMagic()
84115
return Utils.ToUInt32(h, true);
85116
}
86117

118+
public Network InitCustomSignet(SignetSettings? settings = null)
119+
{
120+
var s = settings ?? SignetSettings.Default;
121+
122+
if (_Networks.TryGetValue(new ChainName(string.IsNullOrWhiteSpace(s.Name) ? SignetSettings.DEFAULT_SIGNET_NAME : s.Name), out var network))
123+
return network;
124+
125+
var customSignet = CreateSignet(s.Name, s.Challenge, s.GenesisBlock, s.NetworkSeeds);
126+
_Networks.TryAdd(customSignet.ChainName, customSignet);
127+
return customSignet;
128+
}
87129
}
88130
}

0 commit comments

Comments
 (0)