Skip to content

Commit

Permalink
Introduce TestNet version 4
Browse files Browse the repository at this point in the history
  • Loading branch information
Coding-Enthusiast committed Sep 14, 2024
1 parent 117a056 commit 8c8c43a
Show file tree
Hide file tree
Showing 13 changed files with 134 additions and 25 deletions.
36 changes: 34 additions & 2 deletions Src/Autarkysoft.Bitcoin/Blockchain/Consensus.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public Consensus(NetworkType netType) : this(0, netType)
/// <param name="netType">Network type</param>
public Consensus(int height, NetworkType netType)
{
// https://github.com/bitcoin/bitcoin/blob/544709763e1f45148d1926831e07ff03487673ee/src/chainparams.cpp
// https://github.com/bitcoin/bitcoin/blob/349632e022da22a457a85650360b5be41fa500dc/src/kernel/chainparams.cpp
switch (netType)
{
case NetworkType.MainNet:
Expand Down Expand Up @@ -76,13 +76,26 @@ public Consensus(int height, NetworkType netType)
seg = 834624;
tap = 2064268;
break;
case NetworkType.TestNet4:
PowLimit = Digest256.ParseHex("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
AllowMinDifficultyBlocks = true;
MaxSigOpCount = 80000;
HalvingInterval = 210000;
bip16 = 1;
bip34 = 1;
bip65 = 1;
bip66 = 1;
bip112 = 1;
seg = 1;
tap = 1;
break;
case NetworkType.RegTest:
PowLimit = Digest256.ParseHex("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
AllowMinDifficultyBlocks = true;
MaxSigOpCount = 80000;
HalvingInterval = 150;
bip16 = 0;
bip34 = 500;
bip34 = 1;
bip65 = 1351;
bip66 = 1251;
bip112 = 432;
Expand Down Expand Up @@ -206,11 +219,30 @@ public IBlock GetGenesisBlock()
{
NetworkType.MainNet => CreateGenesisBlock(1231006505, 2083236893, 0x1d00ffff, 1, 50_0000_0000),
NetworkType.TestNet => CreateGenesisBlock(1296688602, 414098458, 0x1d00ffff, 1, 50_0000_0000),
NetworkType.TestNet4 => CreateTestNet4GenesisBlock(1714777860, 393743547, 0x1d00ffff, 1, 50_0000_0000),
NetworkType.RegTest => CreateGenesisBlock(1296688602, 2, 0x207fffff, 1, 50_0000_0000),
_ => throw new ArgumentException(Errors.InvalidNetwork.Convert()),
};
}

private Block CreateTestNet4GenesisBlock(uint time, uint nonce, Target nbits, int version, ulong reward)
{
string timestamp = "03/May/2024 000000000000000000001ebd58c244970b3aa9d783bb001011fbe8ea8e98e00e";
byte[] tsBytes = Encoding.UTF8.GetBytes(timestamp);
byte[] sigData = new byte[9 + tsBytes.Length];
Buffer.BlockCopy(Base16.Decode("04ffff001d01044c4c"), 0, sigData, 0, 9);
Buffer.BlockCopy(tsBytes, 0, sigData, 9, tsBytes.Length);
var sigScr = new SignatureScript(sigData);

var pubOps = new IOperation[]
{
new PushDataOp(new byte[33]),
new CheckSigOp()
};
var pubScr = new PubkeyScript(pubOps);
return CreateGenesisBlock(version, time, nbits, nonce, 1, sigScr, reward, pubScr);
}

/// <inheritdoc/>
public Block CreateGenesisBlock(uint time, uint nonce, Target nbits, int version, ulong reward)
{
Expand Down
2 changes: 2 additions & 0 deletions Src/Autarkysoft.Bitcoin/Clients/ClientSettingsBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public ClientSettingsBase(NetworkType netType, int maxConnection, NodePool nodes
{
NetworkType.MainNet => Constants.MainNetPort,
NetworkType.TestNet => Constants.TestNetPort,
NetworkType.TestNet4 => Constants.TestNet4Port,
NetworkType.RegTest => Constants.RegTestPort,
_ => throw new ArgumentException("Undefined network"),
};
Expand Down Expand Up @@ -85,6 +86,7 @@ public string UserAgent
set => _ua = value ?? string.Empty;
}

// TODO: make this readonly?
/// <inheritdoc/>
public NetworkType Network { get; set; }
/// <inheritdoc/>
Expand Down
28 changes: 25 additions & 3 deletions Src/Autarkysoft.Bitcoin/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,14 @@ public struct Constants
/// </summary>
public const ushort MainNetPort = 8333;
/// <summary>
/// Default test network port
/// Default test network v3 port
/// </summary>
public const ushort TestNetPort = 18333;
/// <summary>
/// Default test network v4 port
/// </summary>
public const ushort TestNet4Port = 48333;
/// <summary>
/// Default regtest network port
/// </summary>
public const ushort RegTestPort = 18444;
Expand All @@ -126,10 +130,14 @@ public struct Constants
/// </summary>
public const string MainNetMagic = "f9beb4d9";
/// <summary>
/// 4 byte "magic" value used in P2P message headers for test-net
/// 4 byte "magic" value used in P2P message headers for test-net v3
/// </summary>
public const string TestNetMagic = "0b110907";
/// <summary>
/// 4 byte "magic" value used in P2P message headers for test-net v4
/// </summary>
public const string TestNet4Magic = "1c163f28";
/// <summary>
/// 4 byte "magic" value used in P2P message headers for reg-test
/// </summary>
public const string RegTestMagic = "fabfb5da";
Expand Down Expand Up @@ -201,7 +209,7 @@ public static string[] GetMainNetDnsSeeds()
}

/// <summary>
/// Returns a list of DNS seeds used for initial peer discovery on TestNet.
/// Returns a list of DNS seeds used for initial peer discovery on TestNet v3.
/// </summary>
/// <returns>List of TestNet DNS seeds</returns>
public static string[] GetTestNetDnsSeeds()
Expand All @@ -215,6 +223,20 @@ public static string[] GetTestNetDnsSeeds()
"testnet-seed.bluematt.me", // Just a static list of stable node(s), only supports x9
};
}

/// <summary>
/// Returns a list of DNS seeds used for initial peer discovery on TestNet.
/// </summary>
/// <returns>List of TestNet DNS seeds</returns>
public static string[] GetTestNet4DnsSeeds()
{
// https://github.com/bitcoin/bitcoin/blob/00ac1b963d08f2779d2197edcdb1e76392993378/src/kernel/chainparams.cpp#L245-L248
return new string[]
{
"seed.testnet4.bitcoin.sprovoost.nl", // Sjors Provoost
"seed.testnet4.wiz.biz", // Jason Maurice
};
}
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ public PrivateKey(string wif, NetworkType netType = NetworkType.MainNet)
private const int KeyByteSize = 32;
private const byte MainNetByte = 128;
private const byte TestNetByte = 239;
private const byte TestNet4Byte = 239;
private const byte RegTestByte = 239;
private const byte CompressedByte = 1;
// Don't rename, used by tests with reflection.
Expand Down Expand Up @@ -177,6 +178,7 @@ protected byte GetWifFirstByte(NetworkType netType)
{
NetworkType.MainNet => MainNetByte,
NetworkType.TestNet => TestNetByte,
NetworkType.TestNet4 => TestNet4Byte,
NetworkType.RegTest => RegTestByte,
_ => throw new ArgumentException("Network type is not defined!"),
};
Expand Down
33 changes: 27 additions & 6 deletions Src/Autarkysoft.Bitcoin/Encoders/Address.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,17 @@ public static class Address
{
private const byte P2pkhVerMainNet = 0;
private const byte P2pkhVerTestNet = 111;
private const byte P2pkhVerRegTest = 0;
private const byte P2pkhVerTestNet4 = 111;
private const byte P2pkhVerRegTest = 111;

private const byte P2shVerMainNet = 5;
private const byte P2shVerTestNet = 196;
private const byte P2shVerRegTest = 5;
private const byte P2shVerTestNet4 = 196;
private const byte P2shVerRegTest = 196;

private const string HrpMainNet = "bc";
private const string HrpTestNet = "tb";
private const string HrpTestNet4 = "tb";
private const string HrpRegTest = "bcrt";


Expand Down Expand Up @@ -55,13 +58,15 @@ public static AddressType GetAddressType(string address, NetworkType netType, ou
{
if ((netType == NetworkType.MainNet && decoded[0] == P2pkhVerMainNet) ||
(netType == NetworkType.TestNet && decoded[0] == P2pkhVerTestNet) ||
(netType == NetworkType.TestNet4 && decoded[0] == P2pkhVerTestNet4) ||
(netType == NetworkType.RegTest && decoded[0] == P2pkhVerRegTest))
{
data = decoded.SubArray(1);
return AddressType.P2PKH;
}
else if ((netType == NetworkType.MainNet && decoded[0] == P2shVerMainNet) ||
(netType == NetworkType.TestNet && decoded[0] == P2shVerTestNet) ||
(netType == NetworkType.TestNet4 && decoded[0] == P2shVerTestNet4) ||
(netType == NetworkType.RegTest && decoded[0] == P2shVerRegTest))
{
data = decoded.SubArray(1);
Expand All @@ -79,6 +84,7 @@ public static AddressType GetAddressType(string address, NetworkType netType, ou
TransactionVerifier.IsNotZero20(decoded) &&
((netType == NetworkType.MainNet && hrp == HrpMainNet) ||
(netType == NetworkType.TestNet && hrp == HrpTestNet) ||
(netType == NetworkType.TestNet4 && hrp == HrpTestNet4) ||
(netType == NetworkType.RegTest && hrp == HrpRegTest)))
{
data = decoded;
Expand All @@ -88,6 +94,7 @@ public static AddressType GetAddressType(string address, NetworkType netType, ou
TransactionVerifier.IsNotZero32(decoded) &&
((netType == NetworkType.MainNet && hrp == HrpMainNet) ||
(netType == NetworkType.TestNet && hrp == HrpTestNet) ||
(netType == NetworkType.TestNet4 && hrp == HrpTestNet4) ||
(netType == NetworkType.RegTest && hrp == HrpRegTest)))
{
data = decoded;
Expand Down Expand Up @@ -127,6 +134,7 @@ public static AddressType GetAddressType(string address, NetworkType netType, ou
if (TransactionVerifier.IsNotZero32(decoded) &&
((netType == NetworkType.MainNet && hrp == HrpMainNet) ||
(netType == NetworkType.TestNet && hrp == HrpTestNet) ||
(netType == NetworkType.TestNet4 && hrp == HrpTestNet4) ||
(netType == NetworkType.RegTest && hrp == HrpRegTest)))
{
data = decoded;
Expand Down Expand Up @@ -174,6 +182,7 @@ public static string GetP2pkh(in Point pubk, bool useCompressed = true, NetworkT
{
NetworkType.MainNet => P2pkhVerMainNet,
NetworkType.TestNet => P2pkhVerTestNet,
NetworkType.TestNet4 => P2pkhVerTestNet4,
NetworkType.RegTest => P2pkhVerRegTest,
_ => throw new ArgumentException(Errors.InvalidNetwork.Convert())
};
Expand Down Expand Up @@ -202,6 +211,7 @@ public static string GetP2sh(IScript redeem, NetworkType netType = NetworkType.M
{
NetworkType.MainNet => P2shVerMainNet,
NetworkType.TestNet => P2shVerTestNet,
NetworkType.TestNet4 => P2shVerTestNet4,
NetworkType.RegTest => P2shVerRegTest,
_ => throw new ArgumentException(Errors.InvalidNetwork.Convert())
};
Expand Down Expand Up @@ -231,6 +241,7 @@ public static string GetP2wpkh(in Point pubk, bool useCompressed = true, Network
{
NetworkType.MainNet => HrpMainNet,
NetworkType.TestNet => HrpTestNet,
NetworkType.TestNet4 => HrpTestNet4,
NetworkType.RegTest => HrpRegTest,
_ => throw new ArgumentException(Errors.InvalidNetwork.Convert()),
};
Expand Down Expand Up @@ -259,8 +270,11 @@ public static string GetP2wpkh(in Point pubk, bool useCompressed = true, Network
/// <returns>The resulting address</returns>
public static string GetP2sh_P2wpkh(in Point pubk, bool useCompressed = true, NetworkType netType = NetworkType.MainNet)
{
if (netType != NetworkType.MainNet && netType != NetworkType.TestNet && netType != NetworkType.RegTest)
if (netType != NetworkType.MainNet && netType != NetworkType.TestNet &&
netType != NetworkType.TestNet4 && netType != NetworkType.RegTest)
{
throw new ArgumentException(Errors.InvalidNetwork.Convert());
}

var rdm = new RedeemScript();
rdm.SetToP2SH_P2WPKH(pubk, useCompressed);
Expand All @@ -285,6 +299,7 @@ public static string GetP2wsh(IScript script, NetworkType netType = NetworkType.
{
NetworkType.MainNet => HrpMainNet,
NetworkType.TestNet => HrpTestNet,
NetworkType.TestNet4 => HrpTestNet4,
NetworkType.RegTest => HrpRegTest,
_ => throw new ArgumentException(Errors.InvalidNetwork.Convert()),
};
Expand All @@ -311,8 +326,11 @@ public static string GetP2sh_P2wsh(IScript script, NetworkType netType = Network
{
if (script is null)
throw new ArgumentNullException(nameof(script), "Script can not be null.");
if (netType != NetworkType.MainNet && netType != NetworkType.TestNet && netType != NetworkType.RegTest)
if (netType != NetworkType.MainNet && netType != NetworkType.TestNet &&
netType != NetworkType.TestNet4 && netType != NetworkType.RegTest)
{
throw new ArgumentException(Errors.InvalidNetwork.Convert());
}

RedeemScript rdm = new RedeemScript();
rdm.SetToP2SH_P2WSH(script);
Expand Down Expand Up @@ -342,6 +360,7 @@ public static string GetP2tr(byte[] data32, NetworkType netType = NetworkType.Ma
{
NetworkType.MainNet => HrpMainNet,
NetworkType.TestNet => HrpTestNet,
NetworkType.TestNet4 => HrpTestNet4,
NetworkType.RegTest => HrpRegTest,
_ => throw new ArgumentException(Errors.InvalidNetwork.Convert()),
};
Expand Down Expand Up @@ -388,6 +407,7 @@ public static bool VerifyType(string address, PubkeyScriptType scrType, out byte
if (decoded.Length == 21 &&
(decoded[0] == P2pkhVerMainNet ||
decoded[0] == P2pkhVerTestNet ||
decoded[0] == P2pkhVerTestNet4 ||
decoded[0] == P2pkhVerRegTest))
{
hash = decoded.SubArray(1);
Expand All @@ -402,6 +422,7 @@ public static bool VerifyType(string address, PubkeyScriptType scrType, out byte
if (decoded.Length == 21 &&
(decoded[0] == P2shVerMainNet ||
decoded[0] == P2shVerTestNet ||
decoded[0] == P2shVerTestNet4 ||
decoded[0] == P2shVerRegTest))
{
hash = decoded.SubArray(1);
Expand All @@ -414,7 +435,7 @@ public static bool VerifyType(string address, PubkeyScriptType scrType, out byte
if (Bech32.TryDecode(address, Bech32.Mode.B32, out decoded, out byte witVer, out string hrp))
{
if (witVer == 0 && decoded.Length == 20 &&
(hrp == HrpMainNet || hrp == HrpTestNet || hrp == HrpRegTest))
(hrp == HrpMainNet || hrp == HrpTestNet || hrp == HrpTestNet4 || hrp == HrpRegTest))
{
if (!TransactionVerifier.IsNotZero20(decoded))
{
Expand All @@ -431,7 +452,7 @@ public static bool VerifyType(string address, PubkeyScriptType scrType, out byte
if (Bech32.TryDecode(address, Bech32.Mode.B32, out decoded, out witVer, out hrp))
{
if (witVer == 0 && decoded.Length == 32 &&
(hrp == HrpMainNet || hrp == HrpTestNet || hrp == HrpRegTest))
(hrp == HrpMainNet || hrp == HrpTestNet || hrp == HrpTestNet4 || hrp == HrpRegTest))
{
if (!TransactionVerifier.IsNotZero32(decoded))
{
Expand Down
1 change: 1 addition & 0 deletions Src/Autarkysoft.Bitcoin/ImprovementProposals/BIP0178.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ protected byte GetWifFirstByte(NetworkType netType)
{
NetworkType.MainNet => MainNetByte,
NetworkType.TestNet => TestNetByte,
NetworkType.TestNet4 => TestNetByte, // TODO: should this be different?
NetworkType.RegTest => RegTestByte,
_ => throw new ArgumentException("Network type is not defined."),
};
Expand Down
6 changes: 5 additions & 1 deletion Src/Autarkysoft.Bitcoin/NetworkType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,14 @@ public enum NetworkType
/// </summary>
MainNet,
/// <summary>
/// The test network
/// The test network (v3)
/// </summary>
TestNet,
/// <summary>
/// The test network (v4)
/// </summary>
TestNet4,
/// <summary>
/// The alternate network for testing
/// </summary>
RegTest
Expand Down
1 change: 1 addition & 0 deletions Src/Autarkysoft.Bitcoin/P2PNetwork/MessageManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public MessageManager(IClientSettings cs, IReplyManager repMan, INodeStatus ns)
{
NetworkType.MainNet => Base16.Decode(Constants.MainNetMagic),
NetworkType.TestNet => Base16.Decode(Constants.TestNetMagic),
NetworkType.TestNet4 => Base16.Decode(Constants.TestNet4Magic),
NetworkType.RegTest => Base16.Decode(Constants.RegTestMagic),
_ => throw new ArgumentException(Errors.InvalidNetwork.Convert())
};
Expand Down
3 changes: 2 additions & 1 deletion Src/Autarkysoft.Bitcoin/P2PNetwork/Messages/Message.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ public Message(NetworkType netType)
{
networkMagic = netType switch
{
// https://github.com/bitcoin/bitcoin/blob/b1b173994406158e5faa3c83b113da9d971ac104/src/chainparams.cpp
// https://github.com/bitcoin/bitcoin/blob/349632e022da22a457a85650360b5be41fa500dc/src/kernel/chainparams.cpp#L128-L131
// (pchMessageStart)
NetworkType.MainNet => new byte[] { 0xf9, 0xbe, 0xb4, 0xd9 },
NetworkType.TestNet => new byte[] { 0x0b, 0x11, 0x09, 0x07 },
NetworkType.TestNet4 => new byte[] { 0x1c, 0x16, 0x3f, 0x28 },
NetworkType.RegTest => new byte[] { 0xfa, 0xbf, 0xb5, 0xda },
_ => throw new ArgumentException("Invalid network type.")
};
Expand Down
4 changes: 4 additions & 0 deletions Src/Denovo/App.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ public override void OnFrameworkInitializationCompleted()
{
network = NetworkType.TestNet;
}
else if (value == "testnet4")
{
network = NetworkType.TestNet4;
}
else if (value == "regtest")
{
network = NetworkType.RegTest;
Expand Down
Loading

0 comments on commit 8c8c43a

Please sign in to comment.