forked from btcsuite/btcd
-
Notifications
You must be signed in to change notification settings - Fork 1
/
config.go
150 lines (134 loc) · 4.9 KB
/
config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// Copyright (c) 2013 Conformal Systems LLC.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package main
import (
"fmt"
"os"
"path/filepath"
"github.com/PointCoin/pointcoind/database"
_ "github.com/PointCoin/pointcoind/database/ldb"
"github.com/PointCoin/btcnet"
"github.com/PointCoin/btcutil"
"github.com/PointCoin/btcwire"
flags "github.com/PointCoin/go-flags"
)
const (
minCandidates = 1
maxCandidates = 20
defaultNumCandidates = 5
defaultDbType = "leveldb"
)
var (
pointcoindHomeDir = btcutil.AppDataDir("pointcoind", false)
defaultDataDir = filepath.Join(pointcoindHomeDir, "data")
knownDbTypes = database.SupportedDBs()
activeNetParams = &btcnet.MainNetParams
)
// config defines the configuration options for findcheckpoint.
//
// See loadConfig for details on the configuration load process.
type config struct {
DataDir string `short:"b" long:"datadir" description:"Location of the pointcoind data directory"`
DbType string `long:"dbtype" description:"Database backend to use for the Block Chain"`
TestNet3 bool `long:"testnet" description:"Use the test network"`
RegressionTest bool `long:"regtest" description:"Use the regression test network"`
SimNet bool `long:"simnet" description:"Use the simulation test network"`
NumCandidates int `short:"n" long:"numcandidates" description:"Max num of checkpoint candidates to show {1-20}"`
UseGoOutput bool `short:"g" long:"gooutput" description:"Display the candidates using Go syntax that is ready to insert into the btcchain checkpoint list"`
}
// validDbType returns whether or not dbType is a supported database type.
func validDbType(dbType string) bool {
for _, knownType := range knownDbTypes {
if dbType == knownType {
return true
}
}
return false
}
// netName returns the name used when referring to a bitcoin network. At the
// time of writing, pointcoind 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 *btcnet.Params) string {
switch netParams.Net {
case btcwire.TestNet3:
return "testnet"
default:
return netParams.Name
}
}
// loadConfig initializes and parses the config using command line options.
func loadConfig() (*config, []string, error) {
// Default config.
cfg := config{
DataDir: defaultDataDir,
DbType: defaultDbType,
NumCandidates: defaultNumCandidates,
}
// Parse command line options.
parser := flags.NewParser(&cfg, flags.Default)
remainingArgs, err := parser.Parse()
if err != nil {
if e, ok := err.(*flags.Error); !ok || e.Type != flags.ErrHelp {
parser.WriteHelp(os.Stderr)
}
return nil, nil, err
}
// Multiple networks can't be selected simultaneously.
funcName := "loadConfig"
numNets := 0
// Count number of network flags passed; assign active network params
// while we're at it
if cfg.TestNet3 {
numNets++
activeNetParams = &btcnet.TestNet3Params
}
if cfg.RegressionTest {
numNets++
activeNetParams = &btcnet.RegressionNetParams
}
if cfg.SimNet {
numNets++
activeNetParams = &btcnet.SimNetParams
}
if numNets > 1 {
str := "%s: The testnet, regtest, and simnet params can't be " +
"used together -- choose one of the three"
err := fmt.Errorf(str, funcName)
fmt.Fprintln(os.Stderr, err)
parser.WriteHelp(os.Stderr)
return nil, nil, err
}
// Validate database type.
if !validDbType(cfg.DbType) {
str := "%s: The specified database type [%v] is invalid -- " +
"supported types %v"
err := fmt.Errorf(str, "loadConfig", cfg.DbType, knownDbTypes)
fmt.Fprintln(os.Stderr, err)
parser.WriteHelp(os.Stderr)
return nil, nil, err
}
// Append the network type to the data directory so it is "namespaced"
// per network. In addition to the block database, there are other
// pieces of data that are saved to disk such as address manager state.
// All data is specific to a network, so namespacing the data directory
// means each individual piece of serialized data does not have to
// worry about changing names per network and such.
cfg.DataDir = filepath.Join(cfg.DataDir, netName(activeNetParams))
// Validate the number of candidates.
if cfg.NumCandidates < minCandidates || cfg.NumCandidates > maxCandidates {
str := "%s: The specified number of candidates is out of " +
"range -- parsed [%v]"
err = fmt.Errorf(str, "loadConfig", cfg.NumCandidates)
fmt.Fprintln(os.Stderr, err)
parser.WriteHelp(os.Stderr)
return nil, nil, err
}
return &cfg, remainingArgs, nil
}