wire+chaincfg: add signet params

This commit adds all necessary chain parameters for connecting to the
public signet network.
Reference: https://github.com/bitcoin/bitcoin/pull/18267
This commit is contained in:
Oliver Gugger 2020-12-24 16:51:59 +01:00
parent 2d7825cf70
commit 73ecb5997b
No known key found for this signature in database
GPG key ID: 8E4256593F177720
4 changed files with 277 additions and 0 deletions

View file

@ -170,3 +170,31 @@ var simNetGenesisBlock = wire.MsgBlock{
}, },
Transactions: []*wire.MsgTx{&genesisCoinbaseTx}, Transactions: []*wire.MsgTx{&genesisCoinbaseTx},
} }
// sigNetGenesisHash is the hash of the first block in the block chain for the
// signet test network.
var sigNetGenesisHash = chainhash.Hash{
0xf6, 0x1e, 0xee, 0x3b, 0x63, 0xa3, 0x80, 0xa4,
0x77, 0xa0, 0x63, 0xaf, 0x32, 0xb2, 0xbb, 0xc9,
0x7c, 0x9f, 0xf9, 0xf0, 0x1f, 0x2c, 0x42, 0x25,
0xe9, 0x73, 0x98, 0x81, 0x08, 0x00, 0x00, 0x00,
}
// sigNetGenesisMerkleRoot is the hash of the first transaction in the genesis
// block for the signet test network. It is the same as the merkle root for
// the main network.
var sigNetGenesisMerkleRoot = genesisMerkleRoot
// sigNetGenesisBlock defines the genesis block of the block chain which serves
// as the public transaction ledger for the signet test network.
var sigNetGenesisBlock = wire.MsgBlock{
Header: wire.BlockHeader{
Version: 1,
PrevBlock: chainhash.Hash{}, // 0000000000000000000000000000000000000000000000000000000000000000
MerkleRoot: sigNetGenesisMerkleRoot, // 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
Timestamp: time.Unix(1598918400, 0), // 2020-09-01 00:00:00 +0000 UTC
Bits: 0x1e0377ae, // 503543726 [00000377ae000000000000000000000000000000000000000000000000000000]
Nonce: 52613770,
},
Transactions: []*wire.MsgTx{&genesisCoinbaseTx},
}

View file

@ -118,6 +118,33 @@ func TestSimNetGenesisBlock(t *testing.T) {
} }
} }
// TestSigNetGenesisBlock tests the genesis block of the signet test network for
// validity by checking the encoded bytes and hashes.
func TestSigNetGenesisBlock(t *testing.T) {
// Encode the genesis block to raw bytes.
var buf bytes.Buffer
err := SigNetParams.GenesisBlock.Serialize(&buf)
if err != nil {
t.Fatalf("TestSigNetGenesisBlock: %v", err)
}
// Ensure the encoded block matches the expected bytes.
if !bytes.Equal(buf.Bytes(), sigNetGenesisBlockBytes) {
t.Fatalf("TestSigNetGenesisBlock: Genesis block does not "+
"appear valid - got %v, want %v",
spew.Sdump(buf.Bytes()),
spew.Sdump(sigNetGenesisBlockBytes))
}
// Check hash of the block against expected hash.
hash := SigNetParams.GenesisBlock.BlockHash()
if !SigNetParams.GenesisHash.IsEqual(&hash) {
t.Fatalf("TestSigNetGenesisBlock: Genesis block hash does "+
"not appear valid - got %v, want %v", spew.Sdump(hash),
spew.Sdump(SigNetParams.GenesisHash))
}
}
// genesisBlockBytes are the wire encoded bytes for the genesis block of the // genesisBlockBytes are the wire encoded bytes for the genesis block of the
// main network as of protocol version 60002. // main network as of protocol version 60002.
var genesisBlockBytes = []byte{ var genesisBlockBytes = []byte{
@ -281,3 +308,44 @@ var simNetGenesisBlockBytes = []byte{
0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d, 0x5f, /* |.Lp+k.._|*/ 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d, 0x5f, /* |.Lp+k.._|*/
0xac, 0x00, 0x00, 0x00, 0x00, /* |.....| */ 0xac, 0x00, 0x00, 0x00, 0x00, /* |.....| */
} }
// sigNetGenesisBlockBytes are the wire encoded bytes for the genesis block of
// the signet test network as of protocol version 70002.
var sigNetGenesisBlockBytes = []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, 0x3b, 0xa3, 0xed, 0xfd, /* |........| */
0x7a, 0x7b, 0x12, 0xb2, 0x7a, 0xc7, 0x2c, 0x3e, /* |....;...| */
0x67, 0x76, 0x8f, 0x61, 0x7f, 0xc8, 0x1b, 0xc3, /* |z{..z.,>| */
0x88, 0x8a, 0x51, 0x32, 0x3a, 0x9f, 0xb8, 0xaa, /* |gv.a....| */
0x4b, 0x1e, 0x5e, 0x4a, 0x00, 0x8f, 0x4d, 0x5f, /* |..Q2:...| */
0xae, 0x77, 0x03, 0x1e, 0x8a, 0xd2, 0x22, 0x03, /* |K.^J..M_| */
0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* |.w....".| */
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, 0x4d, 0x04, 0xff, 0xff, 0x00, 0x1d, /* |........| */
0x01, 0x04, 0x45, 0x54, 0x68, 0x65, 0x20, 0x54, /* |..M.....| */
0x69, 0x6d, 0x65, 0x73, 0x20, 0x30, 0x33, 0x2f, /* |..EThe T| */
0x4a, 0x61, 0x6e, 0x2f, 0x32, 0x30, 0x30, 0x39, /* |imes 03/| */
0x20, 0x43, 0x68, 0x61, 0x6e, 0x63, 0x65, 0x6c, /* |Jan/2009| */
0x6c, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x20, 0x62, /* | Chancel| */
0x72, 0x69, 0x6e, 0x6b, 0x20, 0x6f, 0x66, 0x20, /* |lor on b| */
0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x62, /* |rink of| */
0x61, 0x69, 0x6c, 0x6f, 0x75, 0x74, 0x20, 0x66, /* |second b| */
0x6f, 0x72, 0x20, 0x62, 0x61, 0x6e, 0x6b, 0x73, /* |ailout f| */
0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0xf2, 0x05, /* |or banks| */
0x2a, 0x01, 0x00, 0x00, 0x00, 0x43, 0x41, 0x04, /* |........| */
0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, /* |*....CA.| */
0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7, 0x10, /* |g....UH'| */
0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, /* |.g..q0..| */
0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde, 0xb6, /* |\..(.9..| */
0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, 0x38, 0xc4, /* |yb...a..| */
0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, 0x12, 0xde, /* |I..?L.8.| */
0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d, 0x57, /* |.U......| */
0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d, 0x5f, /* |\8M....W| */
0xac, 0x00, 0x00, 0x00, 0x00, /* |.....| */
}

View file

@ -5,6 +5,8 @@
package chaincfg package chaincfg
import ( import (
"encoding/binary"
"encoding/hex"
"errors" "errors"
"math" "math"
"math/big" "math/big"
@ -38,6 +40,30 @@ var (
// simNetPowLimit is the highest proof of work value a Bitcoin block // simNetPowLimit is the highest proof of work value a Bitcoin block
// can have for the simulation test network. It is the value 2^255 - 1. // can have for the simulation test network. It is the value 2^255 - 1.
simNetPowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 255), bigOne) simNetPowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 255), bigOne)
// sigNetPowLimit is the highest proof of work value a bitcoin block can
// have for the signet test network. It is the value 0x0377ae << 216.
sigNetPowLimit = new(big.Int).Lsh(new(big.Int).SetInt64(0x0377ae), 216)
// DefaultSignetChallenge is the byte representation of the signet
// challenge for the default (public, Taproot enabled) signet network.
// This is the binary equivalent of the bitcoin script
// 1 03ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430
// 0359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c4 2
// OP_CHECKMULTISIG
DefaultSignetChallenge, _ = hex.DecodeString(
"512103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d" +
"1e086be430210359ef5021964fe22d6f8e05b2463c9540ce9688" +
"3fe3b278760f048f5189f2e6c452ae",
)
// DefaultSignetDNSSeeds is the list of seed nodes for the default
// (public, Taproot enabled) signet network.
DefaultSignetDNSSeeds = []DNSSeed{
{"178.128.221.177", false},
{"2a01:7c8:d005:390::5", false},
{"v7ajjeirttkbnt32wpy3c6w3emwnfr3fkla7hpxcfokr3ysd3kqtzmqd.onion:38333", false},
}
) )
// Checkpoint identifies a known good point in the block chain. Using // Checkpoint identifies a known good point in the block chain. Using
@ -96,6 +122,11 @@ const (
// includes the deployment of BIPS 141, 142, 144, 145, 147 and 173. // includes the deployment of BIPS 141, 142, 144, 145, 147 and 173.
DeploymentSegwit DeploymentSegwit
// DeploymentTaproot defines the rule change deployment ID for the
// Taproot (+Schnorr) soft-fork package. The taproot package includes
// the deployment of BIPS 340, 341 and 342.
DeploymentTaproot
// NOTE: DefinedDeployments must always come last since it is used to // NOTE: DefinedDeployments must always come last since it is used to
// determine how many defined deployments there currently are. // determine how many defined deployments there currently are.
@ -578,6 +609,107 @@ var SimNetParams = Params{
HDCoinType: 115, // ASCII for s HDCoinType: 115, // ASCII for s
} }
// SigNetParams defines the network parameters for the default public signet
// Bitcoin network. Not to be confused with the regression test network, this
// network is sometimes simply called "signet" or "taproot signet".
var SigNetParams = CustomSignetParams(
DefaultSignetChallenge, DefaultSignetDNSSeeds,
)
// CustomSignetParams creates network parameters for a custom signet network
// from a challenge. The challenge is the binary compiled version of the block
// challenge script.
func CustomSignetParams(challenge []byte, dnsSeeds []DNSSeed) Params {
// The message start is defined as the first four bytes of the sha256d
// of the challenge script, as a single push (i.e. prefixed with the
// challenge script length).
challengeLength := byte(len(challenge))
hashDouble := chainhash.DoubleHashB(
append([]byte{challengeLength}, challenge...),
)
// We use little endian encoding of the hash prefix to be in line with
// the other wire network identities.
net := binary.LittleEndian.Uint32(hashDouble[0:4])
return Params{
Name: "signet",
Net: wire.BitcoinNet(net),
DefaultPort: "38333",
DNSSeeds: dnsSeeds,
// Chain parameters
GenesisBlock: &sigNetGenesisBlock,
GenesisHash: &sigNetGenesisHash,
PowLimit: sigNetPowLimit,
PowLimitBits: 0x1e0377ae,
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: false,
MinDiffReductionTime: time.Minute * 20, // TargetTimePerBlock * 2
GenerateSupported: false,
// Checkpoints ordered from oldest to newest.
Checkpoints: nil,
// Consensus rule change deployments.
//
// The miner confirmation window is defined as:
// target proof of work timespan / target proof of work spacing
RuleChangeActivationThreshold: 1916, // 95% of 2016
MinerConfirmationWindow: 2016,
Deployments: [DefinedDeployments]ConsensusDeployment{
DeploymentTestDummy: {
BitNumber: 28,
StartTime: 1199145601, // January 1, 2008 UTC
ExpireTime: 1230767999, // December 31, 2008 UTC
},
DeploymentCSV: {
BitNumber: 0,
StartTime: 0, // Always available for vote
ExpireTime: math.MaxInt64, // Never expires
},
DeploymentSegwit: {
BitNumber: 1,
StartTime: 0, // Always available for vote
ExpireTime: math.MaxInt64, // Never expires.
},
DeploymentTaproot: {
BitNumber: 2,
StartTime: 0, // Always available for vote
ExpireTime: math.MaxInt64, // Never expires.
},
},
// Mempool parameters
RelayNonStdTxs: false,
// 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,
}
}
var ( var (
// ErrDuplicateNet describes an error where the parameters for a Bitcoin // ErrDuplicateNet describes an error where the parameters for a Bitcoin
// network could not be set due to the network already being a standard // network could not be set due to the network already being a standard

View file

@ -6,6 +6,8 @@ package chaincfg
import ( import (
"bytes" "bytes"
"encoding/hex"
"math/big"
"testing" "testing"
) )
@ -84,3 +86,50 @@ func TestInvalidHDKeyID(t *testing.T) {
t.Fatalf("HDPrivateKeyToPublicKeyID: want err ErrUnknownHDKeyID, got %v", err) t.Fatalf("HDPrivateKeyToPublicKeyID: want err ErrUnknownHDKeyID, got %v", err)
} }
} }
func TestSigNetPowLimit(t *testing.T) {
sigNetPowLimitHex, _ := hex.DecodeString(
"00000377ae000000000000000000000000000000000000000000000000000000",
)
powLimit := new(big.Int).SetBytes(sigNetPowLimitHex)
if sigNetPowLimit.Cmp(powLimit) != 0 {
t.Fatalf("Signet PoW limit bits (%s) not equal to big int (%s)",
sigNetPowLimit.Text(16), powLimit.Text(16))
}
if compactToBig(sigNetGenesisBlock.Header.Bits).Cmp(powLimit) != 0 {
t.Fatalf("Signet PoW limit header bits (%d) not equal to big "+
"int (%s)", sigNetGenesisBlock.Header.Bits,
powLimit.Text(16))
}
}
// compactToBig is a copy of the blockchain.CompactToBig function. We copy it
// here so we don't run into a circular dependency just because of a test.
func compactToBig(compact uint32) *big.Int {
// Extract the mantissa, sign bit, and exponent.
mantissa := compact & 0x007fffff
isNegative := compact&0x00800000 != 0
exponent := uint(compact >> 24)
// Since the base for the exponent is 256, the exponent can be treated
// as the number of bytes to represent the full 256-bit number. So,
// treat the exponent as the number of bytes and shift the mantissa
// right or left accordingly. This is equivalent to:
// N = mantissa * 256^(exponent-3)
var bn *big.Int
if exponent <= 3 {
mantissa >>= 8 * (3 - exponent)
bn = big.NewInt(int64(mantissa))
} else {
bn = big.NewInt(int64(mantissa))
bn.Lsh(bn, 8*(exponent-3))
}
// Make it negative if the sign bit is set.
if isNegative {
bn = bn.Neg(bn)
}
return bn
}