Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions NBitcoin.Tests/NetworkTests.cs
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -81,5 +81,48 @@ public void ReadMagicByteWithFirstByteDuplicated()
Assert.True(found);
}
}

[Fact]
[Trait("UnitTest", "UnitTest")]
public void CanGetDefaultSignet()
{
var signet = Network.GetNetwork("signet");

Assert.NotNull(signet);

var consensusFactory = new ConsensusFactory();
var block = consensusFactory.CreateBlock();
block.ReadWrite(DataEncoders.Encoders.Hex.DecodeData(SignetSettings.DEFAULT_SIGNET_GENESIS_BLOCK), consensusFactory);

Assert.Equal(block.GetHash(), signet.GenesisHash);
}

[Fact]
[Trait("UnitTest", "UnitTest")]
public void CanGetCustomSignet()
{
var customSignetName = "signet-custom";
var customSignetChallenge = "5121033da06bd7068e9859ee902a0608df9b948829718c60c587f2e497ad4d7420e43151AE";
var customSignetGenesisBlock = "0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a008f4d5fae77031e8ad222030101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000";
var customSignetSeeds = new[]
{
"127.0.0.1",
"[::1]"
};

var signetSettings = new SignetSettings(customSignetName, customSignetChallenge, customSignetGenesisBlock, customSignetSeeds);

var initSignet = Bitcoin.Instance.InitCustomSignet(signetSettings);

Assert.NotNull(initSignet);

var customSignet = Network.GetNetwork(customSignetName);

var consensusFactory = new ConsensusFactory();
var block = consensusFactory.CreateBlock();
block.ReadWrite(DataEncoders.Encoders.Hex.DecodeData(customSignetGenesisBlock), consensusFactory);

Assert.Equal(block.GetHash(), customSignet.GenesisHash);
}
}
}
77 changes: 59 additions & 18 deletions NBitcoin/Bitcoin.Signet.cs
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,40 @@

namespace NBitcoin
{
public record struct SignetSettings(string Name, string Challenge, string GenesisBlock, string[] NetworkSeeds)
{
public const string DEFAULT_SIGNET_NAME = "signet";

public const string DEFAULT_SIGNET_CHALLENGE =
"512103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430210359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c452ae";

public const string DEFAULT_SIGNET_GENESIS_BLOCK = "0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a008f4d5fae77031e8ad222030101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000";

public static readonly string[] DEFAULT_SIGNET_NETWORK_SEEDS = new[]
{
"178.128.221.177",
"2a01:7c8:d005:390::5"
};

public static readonly SignetSettings Default =
new(DEFAULT_SIGNET_NAME, DEFAULT_SIGNET_CHALLENGE, DEFAULT_SIGNET_GENESIS_BLOCK, DEFAULT_SIGNET_NETWORK_SEEDS);
}

public partial class Bitcoin
{
static readonly ChainName SignetName = new ChainName("Signet");
static readonly ChainName SignetName = new ChainName(SignetSettings.DEFAULT_SIGNET_NAME);

public Network Signet => _Networks[SignetName];

private Network CreateSignet()
private Network CreateSignet(
string name = SignetSettings.DEFAULT_SIGNET_NAME,
string challenge = SignetSettings.DEFAULT_SIGNET_CHALLENGE,
string genesisBlock = SignetSettings.DEFAULT_SIGNET_GENESIS_BLOCK,
string[] networkSeeds = null)
{
networkSeeds ??= SignetSettings.DEFAULT_SIGNET_NETWORK_SEEDS;
NetworkBuilder builder = new NetworkBuilder();
builder.SetChainName(SignetName);
builder.SetChainName(name == SignetSettings.DEFAULT_SIGNET_NAME ? SignetName : new ChainName(name));
builder.SetNetworkSet(this);
builder.SetConsensus(new Consensus()
{
Copy link
Contributor

Choose a reason for hiding this comment

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

(GitHub doesn't allow me to comment on line 38 so I leave this comment here, the closest I could)

Bitcoin Knots supports -signetblocktime, which is a very useful flag for a custom signet. Maybe PowTargetSpacing could also be parameterized while keeping the default value of 10*60.

Expand Down Expand Up @@ -43,39 +67,45 @@ private Network CreateSignet()
.SetBech32(Bech32Type.WITNESS_PUBKEY_ADDRESS, "tb")
.SetBech32(Bech32Type.WITNESS_SCRIPT_ADDRESS, "tb")
.SetBech32(Bech32Type.TAPROOT_ADDRESS, "tb")
.SetMagic(GetSignetMagic())
.SetMagic(GetSignetMagic(challenge))
.SetPort(38333)
.SetRPCPort(38332)
.SetName("signet")
.AddAlias("bitcoin-signet")
.AddAlias("btc-signet")
.SetName(name)
.SetGenesis(genesisBlock);

if (name == SignetSettings.DEFAULT_SIGNET_NAME)
{
builder.AddAlias("bitcoin-signet");
builder.AddAlias("btc-signet");
}

#if !NOSOCKET
.AddSeeds(new[]
{
"178.128.221.177",
"2a01:7c8:d005:390::5"
}.Select(o => new Protocol.NetworkAddress(System.Net.IPAddress.Parse(o))))
if (networkSeeds != null)
{
builder.AddSeeds(networkSeeds.Select(o => new Protocol.NetworkAddress(System.Net.IPAddress.Parse(o))));
}
else if (name == SignetSettings.DEFAULT_SIGNET_NAME)
{
builder.AddSeeds(SignetSettings.DEFAULT_SIGNET_NETWORK_SEEDS.Select(o => new Protocol.NetworkAddress(System.Net.IPAddress.Parse(o))));
}
#endif
.SetGenesis(
"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a008f4d5fae77031e8ad222030101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000");

var network = builder.BuildAndRegister();
#if !NOFILEIO
var data = Network.GetDefaultDataFolder("bitcoin");
if (data != null)
{
var signetCookie = Path.Combine(data, "signet", ".cookie");
var signetCookie = Path.Combine(data, name, ".cookie");
RPC.RPCClient.RegisterDefaultCookiePath(network, signetCookie);
}
#endif
_Networks.TryAdd(SignetName, network);
return network;
}

private static uint GetSignetMagic()
private static uint GetSignetMagic(string challengeHex)
{
var challengeBytes = DataEncoders.Encoders.Hex.DecodeData(
"512103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430210359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c452ae");
var challengeBytes = DataEncoders.Encoders.Hex.DecodeData(challengeHex);
var challenge = new Script(challengeBytes);
MemoryStream ms = new MemoryStream();
BitcoinStream bitcoinStream = new BitcoinStream(ms, true);
Expand All @@ -84,5 +114,16 @@ private static uint GetSignetMagic()
return Utils.ToUInt32(h, true);
}

public Network InitCustomSignet(SignetSettings? settings = null)
{
var s = settings ?? SignetSettings.Default;

if (_Networks.TryGetValue(new ChainName(string.IsNullOrWhiteSpace(s.Name) ? SignetSettings.DEFAULT_SIGNET_NAME : s.Name), out var network))
return network;

var customSignet = CreateSignet(s.Name, s.Challenge, s.GenesisBlock, s.NetworkSeeds);
_Networks.TryAdd(customSignet.ChainName, customSignet);
return customSignet;
}
}
}
Loading