diff --git a/blockmanager.go b/blockmanager.go index f328cf3e15..d9d3b3b3d4 100644 --- a/blockmanager.go +++ b/blockmanager.go @@ -1487,14 +1487,14 @@ func loadBlockDB() (btcdb.Db, error) { // Insert the appropriate genesis block for the bitcoin network being // connected to if needed. if height == -1 { - genesis := btcutil.NewBlock(activeNetParams.genesisBlock) + genesis := btcutil.NewBlock(activeNetParams.GenesisBlock) _, err := db.InsertBlock(genesis) if err != nil { db.Close() return nil, err } btcdLog.Infof("Inserted genesis block %v", - activeNetParams.genesisHash) + activeNetParams.GenesisHash) height = 0 } diff --git a/btcd.go b/btcd.go index 064721b649..b41c9bfb26 100644 --- a/btcd.go +++ b/btcd.go @@ -87,7 +87,7 @@ func btcdMain(serverChan chan<- *server) error { }) // Create server and start it. - server, err := newServer(cfg.Listeners, db, activeNetParams.btcnet) + server, err := newServer(cfg.Listeners, db, activeNetParams.Params) if err != nil { // TODO(oga) this logging could do with some beautifying. btcdLog.Errorf("Unable to start server on %v: %v", diff --git a/config.go b/config.go index b5b2b46bfd..3e944e4667 100644 --- a/config.go +++ b/config.go @@ -30,7 +30,6 @@ const ( defaultLogLevel = "info" defaultLogDirname = "logs" defaultLogFilename = "btcd.log" - defaultBtcnet = btcwire.MainNet defaultMaxPeers = 125 defaultBanDuration = time.Hour * 24 defaultMaxRPCClients = 10 @@ -49,7 +48,6 @@ var ( btcdHomeDir = btcutil.AppDataDir("btcd", false) defaultConfigFile = filepath.Join(btcdHomeDir, defaultConfigFilename) defaultDataDir = filepath.Join(btcdHomeDir, defaultDataDirname) - defaultListener = net.JoinHostPort("", netParams(defaultBtcnet).listenPort) knownDbTypes = btcdb.SupportedDBs() defaultRPCKeyFile = filepath.Join(btcdHomeDir, "rpc.key") defaultRPCCertFile = filepath.Join(btcdHomeDir, "rpc.cert") @@ -389,9 +387,9 @@ func loadConfig() (*config, []string, error) { // Choose the active network params based on the testnet and regression // test net flags. if cfg.TestNet3 { - activeNetParams = netParams(btcwire.TestNet3) + activeNetParams = &testNet3Params } else if cfg.RegressionTest { - activeNetParams = netParams(btcwire.TestNet) + activeNetParams = ®ressionNetParams } // Append the network type to the data directory so it is "namespaced" @@ -401,12 +399,12 @@ func loadConfig() (*config, []string, error) { // means each individual piece of serialized data does not have to // worry about changing names per network and such. cfg.DataDir = cleanAndExpandPath(cfg.DataDir) - cfg.DataDir = filepath.Join(cfg.DataDir, activeNetParams.netName) + cfg.DataDir = filepath.Join(cfg.DataDir, netName(activeNetParams)) // Append the network type to the log directory so it is "namespaced" // per network in the same fashion as the data directory. cfg.LogDir = cleanAndExpandPath(cfg.LogDir) - cfg.LogDir = filepath.Join(cfg.LogDir, activeNetParams.netName) + cfg.LogDir = filepath.Join(cfg.LogDir, netName(activeNetParams)) // Special show command to list supported subsystems and exit. if cfg.DebugLevel == "show" { @@ -526,7 +524,7 @@ func loadConfig() (*config, []string, error) { // Check keys are valid and saved parsed versions. cfg.miningKeys = make([]btcutil.Address, 0, len(cfg.GetWorkKeys)) for _, strAddr := range cfg.GetWorkKeys { - addr, err := btcutil.DecodeAddress(strAddr, activeNetParams.btcnet) + addr, err := btcutil.DecodeAddress(strAddr, activeNetParams.Net) if err != nil { str := "%s: the specified getworkkey '%s' failed to decode: %v" err := fmt.Errorf(str, "loadConfig", strAddr, err) @@ -534,7 +532,7 @@ func loadConfig() (*config, []string, error) { parser.WriteHelp(os.Stderr) return nil, nil, err } - if !addr.IsForNet(activeNetParams.btcnet) { + if !addr.IsForNet(activeNetParams.Net) { str := "%s: the specified getworkkey '%s' is on the wrong network" err := fmt.Errorf(str, "loadConfig", strAddr) fmt.Fprintln(os.Stderr, err) diff --git a/mempool.go b/mempool.go index cf609d1cea..84f6dc0564 100644 --- a/mempool.go +++ b/mempool.go @@ -778,8 +778,9 @@ func (mp *txMemPool) maybeAcceptTransaction(tx *btcutil.Tx, isOrphan *bool, isNe } nextBlockHeight := curHeight + 1 - // Don't allow non-standard transactions on the main network. - if activeNetParams.btcnet == btcwire.MainNet { + // Don't allow non-standard transactions if the network parameters + // forbid their relaying. + if !activeNetParams.RelayNonStdTxs { err := checkTransactionStandard(tx, nextBlockHeight) if err != nil { str := fmt.Sprintf("transaction %v is not a standard "+ @@ -844,9 +845,9 @@ func (mp *txMemPool) maybeAcceptTransaction(tx *btcutil.Tx, isOrphan *bool, isNe return err } - // Don't allow transactions with non-standard inputs on the main - // network. - if activeNetParams.btcnet == btcwire.MainNet { + // Don't allow transactions with non-standard inputs if the network + // parameters forbid their relaying. + if !activeNetParams.RelayNonStdTxs { err := checkInputsStandard(tx, txStore) if err != nil { str := fmt.Sprintf("transaction %v has a non-standard "+ diff --git a/mining.go b/mining.go index d33c1a490d..77789c65e2 100644 --- a/mining.go +++ b/mining.go @@ -215,7 +215,7 @@ func createCoinbaseTx(coinbaseScript []byte, nextBlockHeight int64, addr btcutil }) tx.AddTxOut(&btcwire.TxOut{ Value: btcchain.CalcBlockSubsidy(nextBlockHeight, - activeNetParams.btcnet), + activeNetParams.Net), PkScript: pkScript, }) return btcutil.NewTx(tx), nil @@ -787,11 +787,9 @@ func UpdateBlockTime(msgBlock *btcwire.MsgBlock, bManager *blockManager) error { } msgBlock.Header.Timestamp = newTimestamp - // Recalculate the required difficulty for the test networks since it - // can change based on time. - if activeNetParams.btcnet == btcwire.TestNet || - activeNetParams.btcnet == btcwire.TestNet3 { - + // If running on a network that requires recalculating the difficulty, + // do so now. + if activeNetParams.ResetMinDifficulty { difficulty, err := bManager.CalcNextRequiredDifficulty(newTimestamp) if err != nil { return err diff --git a/params.go b/params.go index 51c7603327..8f29a839f8 100644 --- a/params.go +++ b/params.go @@ -5,28 +5,22 @@ package main import ( - "github.com/conformal/btcchain" + "github.com/conformal/btcnet" "github.com/conformal/btcwire" - "math/big" ) // activeNetParams is a pointer to the parameters specific to the // currently active bitcoin network. -var activeNetParams = netParams(defaultBtcnet) +var activeNetParams = &mainNetParams // params is used to group parameters for various networks such as the main // network and test networks. type params struct { - netName string - btcnet btcwire.BitcoinNet - genesisBlock *btcwire.MsgBlock - genesisHash *btcwire.ShaHash - powLimit *big.Int - powLimitBits uint32 - peerPort string - listenPort string - rpcPort string - dnsSeeds []string + *btcnet.Params + peerPort string + listenPort string + rpcPort string + dnsSeeds []string } // mainNetParams contains parameters specific to the main network @@ -36,15 +30,10 @@ type params struct { // it does not handle on to btcd. This approach allows the wallet process // to emulate the full reference implementation RPC API. var mainNetParams = params{ - netName: "mainnet", - btcnet: btcwire.MainNet, - genesisBlock: btcchain.ChainParams(btcwire.MainNet).GenesisBlock, - genesisHash: btcchain.ChainParams(btcwire.MainNet).GenesisHash, - powLimit: btcchain.ChainParams(btcwire.MainNet).PowLimit, - powLimitBits: btcchain.ChainParams(btcwire.MainNet).PowLimitBits, - listenPort: btcwire.MainPort, - peerPort: btcwire.MainPort, - rpcPort: "8334", + Params: &btcnet.MainNetParams, + listenPort: btcwire.MainPort, + peerPort: btcwire.MainPort, + rpcPort: "8334", dnsSeeds: []string{ "seed.bitcoin.sipa.be", "dnsseed.bluematt.me", @@ -55,54 +44,46 @@ var mainNetParams = params{ }, } -// regressionParams contains parameters specific to the regression test network -// (btcwire.TestNet). NOTE: The RPC port is intentionally different than the -// reference implementation - see the mainNetParams comment for details. -var regressionParams = params{ - netName: "regtest", - btcnet: btcwire.TestNet, - genesisBlock: btcchain.ChainParams(btcwire.TestNet).GenesisBlock, - genesisHash: btcchain.ChainParams(btcwire.TestNet).GenesisHash, - powLimit: btcchain.ChainParams(btcwire.TestNet).PowLimit, - powLimitBits: btcchain.ChainParams(btcwire.TestNet).PowLimitBits, - listenPort: btcwire.RegressionTestPort, - peerPort: btcwire.TestNetPort, - rpcPort: "18334", - dnsSeeds: []string{}, +// regressionNetParams contains parameters specific to the regression test +// network (btcwire.TestNet). NOTE: The RPC port is intentionally different +// than the reference implementation - see the mainNetParams comment for +// details. +var regressionNetParams = params{ + Params: &btcnet.RegressionNetParams, + listenPort: btcwire.RegressionTestPort, + peerPort: btcwire.TestNetPort, + rpcPort: "18334", + dnsSeeds: []string{}, } // testNet3Params contains parameters specific to the test network (version 3) // (btcwire.TestNet3). NOTE: The RPC port is intentionally different than the // reference implementation - see the mainNetParams comment for details. var testNet3Params = params{ - netName: "testnet", - btcnet: btcwire.TestNet3, - genesisBlock: btcchain.ChainParams(btcwire.TestNet3).GenesisBlock, - genesisHash: btcchain.ChainParams(btcwire.TestNet3).GenesisHash, - powLimit: btcchain.ChainParams(btcwire.TestNet3).PowLimit, - powLimitBits: btcchain.ChainParams(btcwire.TestNet3).PowLimitBits, - listenPort: btcwire.TestNetPort, - peerPort: btcwire.TestNetPort, - rpcPort: "18334", + Params: &btcnet.TestNet3Params, + listenPort: btcwire.TestNetPort, + peerPort: btcwire.TestNetPort, + rpcPort: "18334", dnsSeeds: []string{ "testnet-seed.bitcoin.petertodd.org", "testnet-seed.bluematt.me", }, } -// netParams returns parameters specific to the passed bitcoin network. -func netParams(btcnet btcwire.BitcoinNet) *params { - switch btcnet { - case btcwire.TestNet: - return ®ressionParams - +// netName returns the name used when referring to a bitcoin network. At the +// time of writing, btcd currently places blocks for testnet version 3 in the +// data and log directory "testnet", which does not match the Name field of the +// btcnet parameters. This function can be used to override this directory name +// as "testnet" when the passed active network matches btcwire.TestNet3. +// +// A proper upgrade to move the data and log directories for this network to +// "testnet3" is planned for the future, at which point this function can be +// removed and the network parameter's name used instead. +func netName(netParams *params) string { + switch netParams.Net { case btcwire.TestNet3: - return &testNet3Params - - // Return main net by default. - case btcwire.MainNet: - fallthrough + return "testnet" default: - return &mainNetParams + return netParams.Name } } diff --git a/rpcserver.go b/rpcserver.go index 8bada7a83a..e3cd4efbe6 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -588,7 +588,7 @@ func handleCreateRawTransaction(s *rpcServer, cmd btcjson.Cmd) (interface{}, err // Decode the provided address. addr, err := btcutil.DecodeAddress(encodedAddr, - activeNetParams.btcnet) + activeNetParams.Net) if err != nil { return nil, btcjson.Error{ Code: btcjson.ErrInvalidAddressOrKey.Code, @@ -1710,7 +1710,7 @@ func handleGetWorkSubmission(s *rpcServer, hexData string) (interface{}, error) msgBlock.Header.MerkleRoot = *merkles[len(merkles)-1] // Ensure the submitted block hash is less than the target difficulty. - err = btcchain.CheckProofOfWork(block, activeNetParams.powLimit) + err = btcchain.CheckProofOfWork(block, activeNetParams.PowLimit) if err != nil { // Anything other than a rule violation is an unexpected error, // so return that error as an internal error. @@ -1998,7 +1998,7 @@ func verifyChain(db btcdb.Db, level, depth int32) error { // Level 1 does basic chain sanity checks. if level > 0 { err := btcchain.CheckBlockSanity(block, - activeNetParams.powLimit) + activeNetParams.PowLimit) if err != nil { rpcsLog.Errorf("Verify is unable to "+ "validate block at sha %v height "+ @@ -2088,7 +2088,7 @@ func getDifficultyRatio(bits uint32) float64 { // converted back to a number. Note this is not the same as the the // proof of work limit directly because the block difficulty is encoded // in a block with the compact form which loses precision. - max := btcchain.CompactToBig(activeNetParams.powLimitBits) + max := btcchain.CompactToBig(activeNetParams.PowLimitBits) target := btcchain.CompactToBig(bits) difficulty := new(big.Rat).SetFrac(max, target) diff --git a/rpcwebsocket.go b/rpcwebsocket.go index 07d8e1d7fa..96511d873c 100644 --- a/rpcwebsocket.go +++ b/rpcwebsocket.go @@ -1433,7 +1433,7 @@ func handleNotifyReceived(wsc *wsClient, icmd btcjson.Cmd) (interface{}, *btcjso } for _, addrStr := range cmd.Addresses { - addr, err := btcutil.DecodeAddress(addrStr, activeNetParams.btcnet) + addr, err := btcutil.DecodeAddress(addrStr, activeNetParams.Net) if err != nil { e := btcjson.Error{ Code: btcjson.ErrInvalidAddressOrKey.Code, @@ -1630,7 +1630,7 @@ func handleRescan(wsc *wsClient, icmd btcjson.Cmd) (interface{}, *btcjson.Error) var compressedPubkey [33]byte var uncompressedPubkey [65]byte for _, addrStr := range cmd.Addresses { - addr, err := btcutil.DecodeAddress(addrStr, activeNetParams.btcnet) + addr, err := btcutil.DecodeAddress(addrStr, activeNetParams.Net) if err != nil { jsonErr := btcjson.Error{ Code: btcjson.ErrInvalidAddressOrKey.Code, diff --git a/server.go b/server.go index 5592912cd2..4dd9a02788 100644 --- a/server.go +++ b/server.go @@ -12,6 +12,7 @@ import ( "fmt" "github.com/conformal/btcdb" "github.com/conformal/btcjson" + "github.com/conformal/btcnet" "github.com/conformal/btcwire" "math" "net" @@ -1003,9 +1004,9 @@ out: } // newServer returns a new btcd server configured to listen on addr for the -// bitcoin network type specified in btcnet. Use start to begin accepting +// bitcoin network type specified by netParams. Use start to begin accepting // connections from peers. -func newServer(listenAddrs []string, db btcdb.Db, btcnet btcwire.BitcoinNet) (*server, error) { +func newServer(listenAddrs []string, db btcdb.Db, netParams *btcnet.Params) (*server, error) { nonce, err := btcwire.RandomUint64() if err != nil { return nil, err @@ -1128,7 +1129,7 @@ func newServer(listenAddrs []string, db btcdb.Db, btcnet btcwire.BitcoinNet) (*s s := server{ nonce: nonce, listeners: listeners, - btcnet: btcnet, + btcnet: netParams.Net, addrManager: amgr, newPeers: make(chan *peer, cfg.MaxPeers), donePeers: make(chan *peer, cfg.MaxPeers),