chaincfg: add TestNet4 params

This commit is contained in:
Oleg Bondar 2025-02-10 15:47:31 +00:00 committed by Olaoluwa Osuntokun
parent ac1399f0d3
commit 70a9a8e58a
4 changed files with 311 additions and 0 deletions

View file

@ -143,6 +143,77 @@ var testNet3GenesisBlock = wire.MsgBlock{
Transactions: []*wire.MsgTx{&genesisCoinbaseTx},
}
// testNet4GenesisTx is the transaction for the genesis blocks for test network (version 4).
var testNet4GenesisTx = wire.MsgTx{
Version: 1,
TxIn: []*wire.TxIn{
{
PreviousOutPoint: wire.OutPoint{
Hash: chainhash.Hash{},
Index: 0xffffffff,
},
SignatureScript: []byte{
// Message: `03/May/2024 000000000000000000001ebd58c244970b3aa9d783bb001011fbe8ea8e98e00e`
0x4, 0xff, 0xff, 0x0, 0x1d, 0x1, 0x4, 0x4c,
0x4c, 0x30, 0x33, 0x2f, 0x4d, 0x61, 0x79, 0x2f,
0x32, 0x30, 0x32, 0x34, 0x20, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x31, 0x65, 0x62, 0x64, 0x35, 0x38, 0x63,
0x32, 0x34, 0x34, 0x39, 0x37, 0x30, 0x62, 0x33,
0x61, 0x61, 0x39, 0x64, 0x37, 0x38, 0x33, 0x62,
0x62, 0x30, 0x30, 0x31, 0x30, 0x31, 0x31, 0x66,
0x62, 0x65, 0x38, 0x65, 0x61, 0x38, 0x65, 0x39,
0x38, 0x65, 0x30, 0x30, 0x65},
Sequence: 0xffffffff,
},
},
TxOut: []*wire.TxOut{
{
Value: 0x12a05f200,
PkScript: []byte{
0x21, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0xac},
},
},
LockTime: 0,
}
// testNet4GenesisHash is the hash of the first block in the block chain for the
// test network (version 4).
var testNet4GenesisHash = chainhash.Hash([chainhash.HashSize]byte{
0x43, 0xf0, 0x8b, 0xda, 0xb0, 0x50, 0xe3, 0x5b,
0x56, 0x7c, 0x86, 0x4b, 0x91, 0xf4, 0x7f, 0x50,
0xae, 0x72, 0x5a, 0xe2, 0xde, 0x53, 0xbc, 0xfb,
0xba, 0xf2, 0x84, 0xda, 0x00, 0x00, 0x00, 0x00})
// testNet4GenesisMerkleRoot is the hash of the first transaction in the genesis
// block for the test network (version 4). It is the same as the merkle root
// for the main network.
var testNet4GenesisMerkleRoot = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy.
0x4e, 0x7b, 0x2b, 0x91, 0x28, 0xfe, 0x02, 0x91,
0xdb, 0x06, 0x93, 0xaf, 0x2a, 0xe4, 0x18, 0xb7,
0x67, 0xe6, 0x57, 0xcd, 0x40, 0x7e, 0x80, 0xcb,
0x14, 0x34, 0x22, 0x1e, 0xae, 0xa7, 0xa0, 0x7a,
})
// testNet4GenesisBlock defines the genesis block of the block chain which
// serves as the public transaction ledger for the test network (version 3).
var testNet4GenesisBlock = wire.MsgBlock{
Header: wire.BlockHeader{
Version: 1,
PrevBlock: chainhash.Hash{}, // 0000000000000000000000000000000000000000000000000000000000000000
MerkleRoot: testNet4GenesisMerkleRoot, // 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
Timestamp: time.Unix(1714777860, 0), // 2024-05-03 23:11:00 +0000 UTC
Bits: 0x1d00ffff, // 486604799 [00000000ffff0000000000000000000000000000000000000000000000000000]
Nonce: 0x17780cbb, // 393743547
},
Transactions: []*wire.MsgTx{&testNet4GenesisTx},
}
// simNetGenesisHash is the hash of the first block in the block chain for the
// simulation test network.
var simNetGenesisHash = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy.

View file

@ -9,6 +9,7 @@ import (
"testing"
"github.com/davecgh/go-spew/spew"
"github.com/stretchr/testify/require"
)
// TestGenesisBlock tests the genesis block of the main network for validity by
@ -91,6 +92,34 @@ func TestTestNet3GenesisBlock(t *testing.T) {
}
}
// TestTestNet4GenesisBlock tests the genesis block of the test network (version
// 4) for validity by checking the encoded bytes and hashes.
func TestTestNet4GenesisBlock(t *testing.T) {
// Encode the genesis block to raw bytes.
var buf bytes.Buffer
err := TestNet4Params.GenesisBlock.Serialize(&buf)
require.NoError(t, err)
// Ensure the encoded block matches the expected bytes.
if !bytes.Equal(buf.Bytes(), testNet4GenesisBlockBytes) {
t.Fatalf("TestTestNet4GenesisBlock: Genesis block does not "+
"appear valid - got %v, want %v",
spew.Sdump(buf.Bytes()),
spew.Sdump(testNet4GenesisBlockBytes))
}
// Check hash of the block against expected hash.
hash := TestNet4Params.GenesisBlock.BlockHash()
if !TestNet4Params.GenesisHash.IsEqual(&hash) {
t.Fatalf("TestTestNet4GenesisBlock: Genesis block hash does "+
"not appear valid - got %v, want %v", spew.Sdump(hash),
spew.Sdump(TestNet4Params.GenesisHash))
}
expectedHash := "00000000da84f2bafbbc53dee25a72ae507ff4914b867c565be3" +
"50b0da8bf043"
require.Equal(t, expectedHash, hash.String())
}
// TestSimNetGenesisBlock tests the genesis block of the simulation test network
// for validity by checking the encoded bytes and hashes.
func TestSimNetGenesisBlock(t *testing.T) {
@ -268,6 +297,44 @@ var testNet3GenesisBlockBytes = []byte{
0xac, 0x00, 0x00, 0x00, 0x00, /* |.....| */
}
// testNet4GenesisBlockBytes are the wire encoded bytes for the genesis block of
// the test network (version 4)
var testNet4GenesisBlockBytes = []byte{
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
0x00, 0x00, 0x00, 0x00, 0x4e, 0x7b, 0x2b, 0x91, /* |....N{+.| */
0x28, 0xfe, 0x02, 0x91, 0xdb, 0x06, 0x93, 0xaf, /* |(.......| */
0x2a, 0xe4, 0x18, 0xb7, 0x67, 0xe6, 0x57, 0xcd, /* |*...g.W.| */
0x40, 0x7e, 0x80, 0xcb, 0x14, 0x34, 0x22, 0x1e, /* |@~...4".| */
0xae, 0xa7, 0xa0, 0x7a, 0x04, 0x6f, 0x35, 0x66, /* |...z.o5f| */
0xff, 0xff, 0x00, 0x1d, 0xbb, 0x0c, 0x78, 0x17, /* |......x.| */
0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* |........| */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* |........| */
0xff, 0xff, 0x55, 0x04, 0xff, 0xff, 0x00, 0x1d, /* |..U.....| */
0x01, 0x04, 0x4c, 0x4c, 0x30, 0x33, 0x2f, 0x4d, /* |..LL03/M| */
0x61, 0x79, 0x2f, 0x32, 0x30, 0x32, 0x34, 0x20, /* |ay/2024 | */
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, /* |00000000| */
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, /* |00000000| */
0x30, 0x30, 0x30, 0x30, 0x31, 0x65, 0x62, 0x64, /* |00001ebd| */
0x35, 0x38, 0x63, 0x32, 0x34, 0x34, 0x39, 0x37, /* |58c24497| */
0x30, 0x62, 0x33, 0x61, 0x61, 0x39, 0x64, 0x37, /* |0b3aa9d7| */
0x38, 0x33, 0x62, 0x62, 0x30, 0x30, 0x31, 0x30, /* |83bb0010| */
0x31, 0x31, 0x66, 0x62, 0x65, 0x38, 0x65, 0x61, /* |11fbe8ea| */
0x38, 0x65, 0x39, 0x38, 0x65, 0x30, 0x30, 0x65, /* |8e98e00e| */
0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0xf2, 0x05, /* |........| */
0x2a, 0x01, 0x00, 0x00, 0x00, 0x23, 0x21, 0x00, /* |*....#!.| */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
0xac, 0x00, 0x00, 0x00, 0x00, /* |..... | */
}
// simNetGenesisBlockBytes are the wire encoded bytes for the genesis block of
// the simulation test network as of protocol version 70002.
var simNetGenesisBlockBytes = []byte{

View file

@ -189,6 +189,10 @@ type Params struct {
// regtest like networks.
PoWNoRetargeting bool
// EnforceBIP94 enforces timewarp attack mitigation and on testnet4
// this also enforces the block storm mitigation.
EnforceBIP94 bool
// These fields define the block heights at which the specified softfork
// BIP became active.
BIP0034Height int32
@ -673,6 +677,118 @@ var TestNet3Params = Params{
HDCoinType: 1,
}
// TestNet4Params defines the network parameters for the test Bitcoin network
// (version 4).
var TestNet4Params = Params{
Name: "testnet4",
Net: wire.TestNet4,
DefaultPort: "48333",
DNSSeeds: []DNSSeed{
{"seed.testnet4.bitcoin.sprovoost.nl", true},
{"seed.testnet4.wiz.biz", true},
},
// Chain parameters
GenesisBlock: &testNet4GenesisBlock,
GenesisHash: &testNet4GenesisHash,
PowLimit: testNet3PowLimit,
PowLimitBits: 0x1d00ffff,
EnforceBIP94: true,
BIP0034Height: 1,
BIP0065Height: 1,
BIP0066Height: 1,
CoinbaseMaturity: 100,
SubsidyReductionInterval: 210000,
TargetTimespan: time.Hour * 24 * 14, // 14 days
TargetTimePerBlock: time.Minute * 10, // 10 minutes
RetargetAdjustmentFactor: 4, // 25% less, 400% more
ReduceMinDifficulty: true,
MinDiffReductionTime: time.Minute * 20, // TargetTimePerBlock * 2
GenerateSupported: false,
// Checkpoints ordered from oldest to newest.
Checkpoints: []Checkpoint{},
// Consensus rule change deployments.
//
// The miner confirmation window is defined as:
// target proof of work timespan / target proof of work spacing
RuleChangeActivationThreshold: 1512, // 75% of MinerConfirmationWindow
MinerConfirmationWindow: 2016,
Deployments: [DefinedDeployments]ConsensusDeployment{
DeploymentTestDummy: {
BitNumber: 28,
DeploymentStarter: NewMedianTimeDeploymentStarter(
time.Unix(1199145601, 0), // January 1, 2008 UTC
),
DeploymentEnder: NewMedianTimeDeploymentEnder(
time.Unix(1230767999, 0), // December 31, 2008 UTC
),
},
DeploymentTestDummyMinActivation: {
BitNumber: 22,
CustomActivationThreshold: 1815, // Only needs 90% hash rate.
MinActivationHeight: 10_0000, // Can only activate after height 10k.
DeploymentStarter: NewMedianTimeDeploymentStarter(
time.Time{}, // Always available for vote
),
DeploymentEnder: NewMedianTimeDeploymentEnder(
time.Time{}, // Never expires
),
},
DeploymentCSV: {
BitNumber: 29,
DeploymentStarter: NewMedianTimeDeploymentStarter(
time.Time{}, // Always available for vote
),
DeploymentEnder: NewMedianTimeDeploymentEnder(
time.Time{}, // Never expires
),
},
DeploymentSegwit: {
BitNumber: 29,
DeploymentStarter: NewMedianTimeDeploymentStarter(
time.Time{}, // Always available for vote
),
DeploymentEnder: NewMedianTimeDeploymentEnder(
time.Time{}, // Never expires
),
},
DeploymentTaproot: {
BitNumber: 2,
DeploymentStarter: NewMedianTimeDeploymentStarter(
time.Time{}, // Always available for vote
),
DeploymentEnder: NewMedianTimeDeploymentEnder(
time.Time{}, // Never expires
),
MinActivationHeight: 0,
},
},
// Mempool parameters
RelayNonStdTxs: true,
// Human-readable part for Bech32 encoded segwit addresses, as defined in
// BIP 173.
Bech32HRPSegwit: "tb", // always tb for test net
// Address encoding magics
PubKeyHashAddrID: 0x6f, // starts with m or n
ScriptHashAddrID: 0xc4, // starts with 2
WitnessPubKeyHashAddrID: 0x03, // starts with QW
WitnessScriptHashAddrID: 0x28, // starts with T7n
PrivateKeyID: 0xef, // starts with 9 (uncompressed) or c (compressed)
// BIP32 hierarchical deterministic extended key magics
HDPrivateKeyID: [4]byte{0x04, 0x35, 0x83, 0x94}, // starts with tprv
HDPublicKeyID: [4]byte{0x04, 0x35, 0x87, 0xcf}, // starts with tpub
// BIP44 coin type used in the hierarchical deterministic path for
// address generation.
HDCoinType: 1,
}
// SimNetParams defines the network parameters for the simulation test Bitcoin
// network. This network is similar to the normal test network except it is
// intended for private use within a group of individuals doing simulation
@ -1075,6 +1191,7 @@ func init() {
// Register all default networks when the package is initialized.
mustRegister(&MainNetParams)
mustRegister(&TestNet3Params)
mustRegister(&TestNet4Params)
mustRegister(&RegressionNetParams)
mustRegister(&SimNetParams)
}

View file

@ -68,6 +68,11 @@ func TestRegister(t *testing.T) {
params: &TestNet3Params,
err: ErrDuplicateNet,
},
{
name: "duplicate testnet4",
params: &TestNet4Params,
err: ErrDuplicateNet,
},
{
name: "duplicate simnet",
params: &SimNetParams,
@ -83,6 +88,10 @@ func TestRegister(t *testing.T) {
magic: TestNet3Params.PubKeyHashAddrID,
valid: true,
},
{
magic: TestNet4Params.PubKeyHashAddrID,
valid: true,
},
{
magic: RegressionNetParams.PubKeyHashAddrID,
valid: true,
@ -109,6 +118,10 @@ func TestRegister(t *testing.T) {
magic: TestNet3Params.ScriptHashAddrID,
valid: true,
},
{
magic: TestNet4Params.ScriptHashAddrID,
valid: true,
},
{
magic: RegressionNetParams.ScriptHashAddrID,
valid: true,
@ -135,6 +148,10 @@ func TestRegister(t *testing.T) {
prefix: TestNet3Params.Bech32HRPSegwit + "1",
valid: true,
},
{
prefix: TestNet4Params.Bech32HRPSegwit + "1",
valid: true,
},
{
prefix: RegressionNetParams.Bech32HRPSegwit + "1",
valid: true,
@ -175,6 +192,11 @@ func TestRegister(t *testing.T) {
want: TestNet3Params.HDPublicKeyID[:],
err: nil,
},
{
priv: TestNet4Params.HDPrivateKeyID[:],
want: TestNet4Params.HDPublicKeyID[:],
err: nil,
},
{
priv: RegressionNetParams.HDPrivateKeyID[:],
want: RegressionNetParams.HDPublicKeyID[:],
@ -217,6 +239,10 @@ func TestRegister(t *testing.T) {
magic: TestNet3Params.PubKeyHashAddrID,
valid: true,
},
{
magic: TestNet4Params.PubKeyHashAddrID,
valid: true,
},
{
magic: RegressionNetParams.PubKeyHashAddrID,
valid: true,
@ -243,6 +269,10 @@ func TestRegister(t *testing.T) {
magic: TestNet3Params.ScriptHashAddrID,
valid: true,
},
{
magic: TestNet4Params.ScriptHashAddrID,
valid: true,
},
{
magic: RegressionNetParams.ScriptHashAddrID,
valid: true,
@ -269,6 +299,10 @@ func TestRegister(t *testing.T) {
prefix: TestNet3Params.Bech32HRPSegwit + "1",
valid: true,
},
{
prefix: TestNet4Params.Bech32HRPSegwit + "1",
valid: true,
},
{
prefix: RegressionNetParams.Bech32HRPSegwit + "1",
valid: true,
@ -324,6 +358,11 @@ func TestRegister(t *testing.T) {
params: &TestNet3Params,
err: ErrDuplicateNet,
},
{
name: "duplicate testnet4",
params: &TestNet4Params,
err: ErrDuplicateNet,
},
{
name: "duplicate simnet",
params: &SimNetParams,
@ -344,6 +383,10 @@ func TestRegister(t *testing.T) {
magic: TestNet3Params.PubKeyHashAddrID,
valid: true,
},
{
magic: TestNet4Params.PubKeyHashAddrID,
valid: true,
},
{
magic: RegressionNetParams.PubKeyHashAddrID,
valid: true,
@ -370,6 +413,10 @@ func TestRegister(t *testing.T) {
magic: TestNet3Params.ScriptHashAddrID,
valid: true,
},
{
magic: TestNet4Params.ScriptHashAddrID,
valid: true,
},
{
magic: RegressionNetParams.ScriptHashAddrID,
valid: true,
@ -396,6 +443,10 @@ func TestRegister(t *testing.T) {
prefix: TestNet3Params.Bech32HRPSegwit + "1",
valid: true,
},
{
prefix: TestNet4Params.Bech32HRPSegwit + "1",
valid: true,
},
{
prefix: RegressionNetParams.Bech32HRPSegwit + "1",
valid: true,
@ -436,6 +487,11 @@ func TestRegister(t *testing.T) {
want: TestNet3Params.HDPublicKeyID[:],
err: nil,
},
{
priv: TestNet4Params.HDPrivateKeyID[:],
want: TestNet4Params.HDPublicKeyID[:],
err: nil,
},
{
priv: RegressionNetParams.HDPrivateKeyID[:],
want: RegressionNetParams.HDPublicKeyID[:],