// Copyright (c) 2014-2016 The btcsuite developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. package dagconfig import ( "errors" "math" "math/big" "time" "github.com/daglabs/btcd/util" "github.com/daglabs/btcd/util/hdkeychain" "github.com/daglabs/btcd/util/daghash" "github.com/daglabs/btcd/wire" ) // These variables are the chain proof-of-work limit parameters for each default // network. var ( // bigOne is 1 represented as a big.Int. It is defined here to avoid // the overhead of creating it multiple times. bigOne = big.NewInt(1) // mainPowLimit is the highest proof of work value a Bitcoin block can // have for the main network. It is the value 2^255 - 1. mainPowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 255), bigOne) // regressionPowLimit is the highest proof of work value a Bitcoin block // can have for the regression test network. It is the value 2^255 - 1. regressionPowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 255), bigOne) // testNet3PowLimit is the highest proof of work value a Bitcoin block // can have for the test network (version 3). It is the value // 2^255 - 1. testNet3PowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 255), bigOne) // 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. simNetPowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 255), bigOne) // devNetPowLimit is the highest proof of work value a Bitcoin block // can have for the development network. It is the value // 2^239 - 1. devNetPowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 239), bigOne) ) const phantomK = 10 // Checkpoint identifies a known good point in the block chain. Using // checkpoints allows a few optimizations for old blocks during initial download // and also prevents forks from old blocks. // // Each checkpoint is selected based upon several factors. See the // documentation for blockchain.IsCheckpointCandidate for details on the // selection criteria. type Checkpoint struct { Height uint64 Hash *daghash.Hash } // ConsensusDeployment defines details related to a specific consensus rule // change that is voted in. This is part of BIP0009. type ConsensusDeployment struct { // BitNumber defines the specific bit number within the block version // this particular soft-fork deployment refers to. BitNumber uint8 // StartTime is the median block time after which voting on the // deployment starts. StartTime uint64 // ExpireTime is the median block time after which the attempted // deployment expires. ExpireTime uint64 } // Constants that define the deployment offset in the deployments field of the // parameters for each deployment. This is useful to be able to get the details // of a specific deployment by name. const ( // DeploymentTestDummy defines the rule change deployment ID for testing // purposes. DeploymentTestDummy = iota // NOTE: DefinedDeployments must always come last since it is used to // determine how many defined deployments there currently are. // DefinedDeployments is the number of currently defined deployments. DefinedDeployments ) // Params defines a Bitcoin network by its parameters. These parameters may be // used by Bitcoin applications to differentiate networks as well as addresses // and keys for one network from those intended for use on another network. type Params struct { K uint32 // Name defines a human-readable identifier for the network. Name string // Net defines the magic bytes used to identify the network. Net wire.BitcoinNet // RPCPort defines the rpc server port RPCPort string // DefaultPort defines the default peer-to-peer port for the network. DefaultPort string // DNSSeeds defines a list of DNS seeds for the network that are used // as one method to discover peers. DNSSeeds []string // GenesisBlock defines the first block of the chain. GenesisBlock *wire.MsgBlock // GenesisHash is the starting block hash. GenesisHash *daghash.Hash // PowLimit defines the highest allowed proof of work value for a block // as a uint256. PowLimit *big.Int // PowLimitBits defines the highest allowed proof of work value for a // block in compact form. PowLimitBits uint32 // BlockRewardMaturity is the number of blocks required before newly mined // coins (coinbase or fee transactions) can be spent. BlockRewardMaturity uint64 // SubsidyReductionInterval is the interval of blocks before the subsidy // is reduced. SubsidyReductionInterval uint64 // TargetTimespan is the desired amount of time that should elapse // before the block difficulty requirement is examined to determine how // it should be changed in order to maintain the desired block // generation rate. TargetTimespan time.Duration // TargetTimePerBlock is the desired amount of time to generate each // block. TargetTimePerBlock time.Duration // RetargetAdjustmentFactor is the adjustment factor used to limit // the minimum and maximum amount of adjustment that can occur between // difficulty retargets. RetargetAdjustmentFactor int64 // ReduceMinDifficulty defines whether the network should reduce the // minimum required difficulty after a long enough period of time has // passed without finding a block. This is really only useful for test // networks and should not be set on a main network. ReduceMinDifficulty bool // MinDiffReductionTime is the amount of time after which the minimum // required difficulty should be reduced when a block hasn't been found. // // NOTE: This only applies if ReduceMinDifficulty is true. MinDiffReductionTime time.Duration // GenerateSupported specifies whether or not CPU mining is allowed. GenerateSupported bool // Checkpoints ordered from oldest to newest. Checkpoints []Checkpoint // These fields are related to voting on consensus rule changes as // defined by BIP0009. // // RuleChangeActivationThreshold is the number of blocks in a threshold // state retarget window for which a positive vote for a rule change // must be cast in order to lock in a rule change. It should typically // be 95% for the main network and 75% for test networks. // // MinerConfirmationWindow is the number of blocks in each threshold // state retarget window. // // Deployments define the specific consensus rule changes to be voted // on. RuleChangeActivationThreshold uint64 MinerConfirmationWindow uint64 Deployments [DefinedDeployments]ConsensusDeployment // Mempool parameters RelayNonStdTxs bool // AcceptUnroutable specifies whether this network accepts unroutable // IP addresses, such as 10.0.0.0/8 AcceptUnroutable bool // Human-readable prefix for Bech32 encoded addresses Prefix util.Bech32Prefix // Address encoding magics PrivateKeyID byte // First byte of a WIF private key // BIP32 hierarchical deterministic extended key magics HDKeyIDPair hdkeychain.HDKeyIDPair // BIP44 coin type used in the hierarchical deterministic path for // address generation. HDCoinType uint32 } // MainNetParams defines the network parameters for the main Bitcoin network. var MainNetParams = Params{ K: phantomK, Name: "mainnet", Net: wire.MainNet, RPCPort: "8334", DefaultPort: "8333", DNSSeeds: []string{}, // DAG parameters GenesisBlock: &genesisBlock, GenesisHash: &genesisHash, PowLimit: mainPowLimit, PowLimitBits: 0x207fffff, BlockRewardMaturity: 100, SubsidyReductionInterval: 210000, TargetTimespan: time.Hour * 1, // 1 hour TargetTimePerBlock: time.Second * 1, // 1 second RetargetAdjustmentFactor: 4, // 25% less, 400% more ReduceMinDifficulty: false, MinDiffReductionTime: 0, 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 MinerConfirmationWindow MinerConfirmationWindow: 2016, // Deployments: [DefinedDeployments]ConsensusDeployment{ DeploymentTestDummy: { BitNumber: 28, StartTime: 1199145601, // January 1, 2008 UTC ExpireTime: 1230767999, // December 31, 2008 UTC }, }, // Mempool parameters RelayNonStdTxs: false, // AcceptUnroutable specifies whether this network accepts unroutable // IP addresses, such as 10.0.0.0/8 AcceptUnroutable: false, // Human-readable part for Bech32 encoded addresses Prefix: util.Bech32PrefixDAGCoin, // Address encoding magics PrivateKeyID: 0x80, // starts with 5 (uncompressed) or K (compressed) // BIP32 hierarchical deterministic extended key magics HDKeyIDPair: hdkeychain.HDKeyPairMainNet, // BIP44 coin type used in the hierarchical deterministic path for // address generation. HDCoinType: 0, } // RegressionNetParams defines the network parameters for the regression test // Bitcoin network. Not to be confused with the test Bitcoin network (version // 3), this network is sometimes simply called "testnet". var RegressionNetParams = Params{ K: phantomK, Name: "regtest", Net: wire.TestNet, RPCPort: "18334", DefaultPort: "18444", DNSSeeds: []string{}, // Chain parameters GenesisBlock: ®TestGenesisBlock, GenesisHash: ®TestGenesisHash, PowLimit: regressionPowLimit, PowLimitBits: 0x207fffff, BlockRewardMaturity: 100, SubsidyReductionInterval: 150, TargetTimespan: time.Hour * 1, // 1 hour TargetTimePerBlock: time.Second * 1, // 1 second RetargetAdjustmentFactor: 4, // 25% less, 400% more ReduceMinDifficulty: true, MinDiffReductionTime: time.Minute * 20, // TargetTimePerBlock * 2 GenerateSupported: true, // 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: 108, // 75% of MinerConfirmationWindow MinerConfirmationWindow: 144, Deployments: [DefinedDeployments]ConsensusDeployment{ DeploymentTestDummy: { BitNumber: 28, StartTime: 0, // Always available for vote ExpireTime: math.MaxInt64, // Never expires }, }, // Mempool parameters RelayNonStdTxs: true, // AcceptUnroutable specifies whether this network accepts unroutable // IP addresses, such as 10.0.0.0/8 AcceptUnroutable: false, // Human-readable part for Bech32 encoded addresses Prefix: util.Bech32PrefixDAGReg, // Address encoding magics PrivateKeyID: 0xef, // starts with 9 (uncompressed) or c (compressed) // BIP32 hierarchical deterministic extended key magics HDKeyIDPair: hdkeychain.HDKeyPairRegressionNet, // BIP44 coin type used in the hierarchical deterministic path for // address generation. HDCoinType: 1, } // TestNet3Params defines the network parameters for the test Bitcoin network // (version 3). Not to be confused with the regression test network, this // network is sometimes simply called "testnet". var TestNet3Params = Params{ K: phantomK, Name: "testnet3", Net: wire.TestNet3, RPCPort: "18334", DefaultPort: "18333", DNSSeeds: []string{}, // Chain parameters GenesisBlock: &testNet3GenesisBlock, GenesisHash: &testNet3GenesisHash, PowLimit: testNet3PowLimit, PowLimitBits: 0x207fffff, BlockRewardMaturity: 100, SubsidyReductionInterval: 210000, TargetTimespan: time.Hour * 1, // 1 hour TargetTimePerBlock: time.Second * 1, // 1 second RetargetAdjustmentFactor: 4, // 25% less, 400% more ReduceMinDifficulty: true, MinDiffReductionTime: time.Minute * 20, // TargetTimePerBlock * 2 GenerateSupported: true, // 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: 1512, // 75% of MinerConfirmationWindow MinerConfirmationWindow: 2016, Deployments: [DefinedDeployments]ConsensusDeployment{ DeploymentTestDummy: { BitNumber: 28, StartTime: 1199145601, // January 1, 2008 UTC ExpireTime: 1230767999, // December 31, 2008 UTC }, }, // Mempool parameters RelayNonStdTxs: true, // AcceptUnroutable specifies whether this network accepts unroutable // IP addresses, such as 10.0.0.0/8 AcceptUnroutable: false, // Human-readable part for Bech32 encoded addresses Prefix: util.Bech32PrefixDAGTest, // Address encoding magics PrivateKeyID: 0xef, // starts with 9 (uncompressed) or c (compressed) // BIP32 hierarchical deterministic extended key magics HDKeyIDPair: hdkeychain.HDKeyPairTestNet, // 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 // testing. The functionality is intended to differ in that the only nodes // which are specifically specified are used to create the network rather than // following normal discovery rules. This is important as otherwise it would // just turn into another public testnet. var SimNetParams = Params{ K: phantomK, Name: "simnet", Net: wire.SimNet, RPCPort: "18556", DefaultPort: "18555", DNSSeeds: []string{}, // NOTE: There must NOT be any seeds. // Chain parameters GenesisBlock: &simNetGenesisBlock, GenesisHash: &simNetGenesisHash, PowLimit: simNetPowLimit, PowLimitBits: 0x207fffff, BlockRewardMaturity: 100, SubsidyReductionInterval: 210000, TargetTimespan: time.Hour * 1, // 1 hour TargetTimePerBlock: time.Second * 1, // 1 second RetargetAdjustmentFactor: 4, // 25% less, 400% more ReduceMinDifficulty: true, MinDiffReductionTime: time.Minute * 20, // TargetTimePerBlock * 2 GenerateSupported: true, // 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: 75, // 75% of MinerConfirmationWindow MinerConfirmationWindow: 100, Deployments: [DefinedDeployments]ConsensusDeployment{ DeploymentTestDummy: { BitNumber: 28, StartTime: 0, // Always available for vote ExpireTime: math.MaxInt64, // Never expires }, }, // Mempool parameters RelayNonStdTxs: true, // AcceptUnroutable specifies whether this network accepts unroutable // IP addresses, such as 10.0.0.0/8 AcceptUnroutable: false, PrivateKeyID: 0x64, // starts with 4 (uncompressed) or F (compressed) // Human-readable part for Bech32 encoded addresses Prefix: util.Bech32PrefixDAGSim, // BIP32 hierarchical deterministic extended key magics HDKeyIDPair: hdkeychain.HDKeyPairSimNet, // BIP44 coin type used in the hierarchical deterministic path for // address generation. HDCoinType: 115, // ASCII for s } // DevNetParams defines the network parameters for the development Bitcoin network. var DevNetParams = Params{ K: phantomK, Name: "devnet", Net: wire.DevNet, RPCPort: "18334", DefaultPort: "18333", DNSSeeds: []string{"devnet-dnsseed.daglabs.com"}, // Chain parameters GenesisBlock: &devNetGenesisBlock, GenesisHash: &devNetGenesisHash, PowLimit: devNetPowLimit, PowLimitBits: util.BigToCompact(devNetPowLimit), // 0x1e7fffff BlockRewardMaturity: 100, SubsidyReductionInterval: 210000, TargetTimespan: time.Hour * 1, // 1 hour TargetTimePerBlock: time.Second * 1, // 1 second RetargetAdjustmentFactor: 4, // 25% less, 400% more ReduceMinDifficulty: true, MinDiffReductionTime: time.Minute * 20, // TargetTimePerBlock * 2 GenerateSupported: true, // 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: 1512, // 75% of MinerConfirmationWindow MinerConfirmationWindow: 2016, Deployments: [DefinedDeployments]ConsensusDeployment{ DeploymentTestDummy: { BitNumber: 28, StartTime: 1199145601, // January 1, 2008 UTC ExpireTime: 1230767999, // December 31, 2008 UTC }, }, // Mempool parameters RelayNonStdTxs: true, // AcceptUnroutable specifies whether this network accepts unroutable // IP addresses, such as 10.0.0.0/8 AcceptUnroutable: true, // Human-readable part for Bech32 encoded addresses Prefix: util.Bech32PrefixDAGTest, // Address encoding magics PrivateKeyID: 0xef, // starts with 9 (uncompressed) or c (compressed) // BIP32 hierarchical deterministic extended key magics HDKeyIDPair: hdkeychain.HDKeyPairDevNet, // BIP44 coin type used in the hierarchical deterministic path for // address generation. HDCoinType: 1, } var ( // ErrDuplicateNet describes an error where the parameters for a Bitcoin // network could not be set due to the network already being a standard // network or previously-registered into this package. ErrDuplicateNet = errors.New("duplicate Bitcoin network") ) var ( registeredNets = make(map[wire.BitcoinNet]struct{}) ) // Register registers the network parameters for a Bitcoin network. This may // error with ErrDuplicateNet if the network is already registered (either // due to a previous Register call, or the network being one of the default // networks). // // Network parameters should be registered into this package by a main package // as early as possible. Then, library packages may lookup networks or network // parameters based on inputs and work regardless of the network being standard // or not. func Register(params *Params) error { if _, ok := registeredNets[params.Net]; ok { return ErrDuplicateNet } registeredNets[params.Net] = struct{}{} return nil } // mustRegister performs the same function as Register except it panics if there // is an error. This should only be called from package init functions. func mustRegister(params *Params) { if err := Register(params); err != nil { panic("failed to register network: " + err.Error()) } } // newHashFromStr converts the passed big-endian hex string into a // daghash.Hash. It only differs from the one available in daghash in that // it panics on an error since it will only (and must only) be called with // hard-coded, and therefore known good, hashes. func newHashFromStr(hexStr string) *daghash.Hash { hash, err := daghash.NewHashFromStr(hexStr) if err != nil { // Ordinarily I don't like panics in library code since it // can take applications down without them having a chance to // recover which is extremely annoying, however an exception is // being made in this case because the only way this can panic // is if there is an error in the hard-coded hashes. Thus it // will only ever potentially panic on init and therefore is // 100% predictable. panic(err) } return hash } func init() { // Register all default networks when the package is initialized. mustRegister(&MainNetParams) mustRegister(&TestNet3Params) mustRegister(&RegressionNetParams) mustRegister(&SimNetParams) }