Skip to content
This repository has been archived by the owner on May 16, 2019. It is now read-only.

make consistent with other dcr tools and repair web UI #41

Merged
merged 1 commit into from Aug 29, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
103 changes: 49 additions & 54 deletions README.md
Expand Up @@ -40,10 +40,6 @@ run the following:
$ go get -u github.com/Masterminds/glide
```

**NOTE:** If you are using Go 1.5, you must manually enable the vendor
experiment by setting the `GO15VENDOREXPERIMENT` environment variable to `1`.
This step is not required for Go 1.6.

- Run the following commands to obtain dcrticketbuyer, all dependencies, and
install it:

Expand Down Expand Up @@ -82,7 +78,9 @@ prefer for ticket purchase. For reference, these options are given below.

```
-C, --configfile= Path to configuration file
(~/.dcrticketbuyer/ticketbuyer.conf)
(~/.dcrticketbuyer/dcrticketbuyer.conf)
-b, --datadir= Directory to store data
(~/.dcrticketbuyer/data)
-V, --version Display version information and exit
--testnet Use the test network (default mainnet)
--simnet Use the simulation test network (default mainnet)
Expand All @@ -92,80 +90,80 @@ prefer for ticket purchase. For reference, these options are given below.
(~/.dcrticketbuyer/logs)
--httpsvrbind= IP to bind for the HTTP server that tracks ticket
purchase metrics (default: "" or localhost)
(localhost)
--httpsvrport= Server port for the HTTP server that tracks ticket
purchase metrics; disabled if 0 (default: 0)
--httpuipath= Path for the data and JavaScript libraries for
displaying/storing purchase metrics (default: "webui/")
(webui/)
--dcrduser= Daemon RPC user name
--dcrdpass= Daemon RPC password
--dcrdserv= Hostname/IP and port of dcrd RPC server to connect to
(default localhost:9109, testnet: localhost:19109,
simnet: localhost:18556)
--dcrdserv= Hostname/IP and port of dcrd RPC server to connect
to (default localhost:9109, testnet:
localhost:19109, simnet: localhost:19556)
--dcrdcert= File containing the dcrd certificate file
(~/.dcrd/rpc.cert)
--dcrwuser= Wallet RPC user name
--dcrwpass= Wallet RPC password
--dcrwserv= Hostname/IP and port of dcrwallet RPC server to connect
to (default localhost:9110, testnet: localhost:19110,
simnet: localhost:18557)
--dcrwserv= Hostname/IP and port of dcrwallet RPC server to
connect to (default localhost:9110, testnet:
localhost:19110, simnet: localhost:19557)
--dcrwcert= File containing the dcrwallet certificate file
(~/.dcrwallet/rpc.cert)
--noclienttls Disable TLS for the RPC client -- NOTE: This is only
allowed if the RPC client is connecting to localhost
--noclienttls Disable TLS for the RPC client -- NOTE: This is
only allowed if the RPC client is connecting to
localhost
--accountname= Name of the account to buy tickets from (default:
default) (default)
--ticketaddress= Address to give ticket voting rights to
--pooladdress= Address to give pool fees rights to
--poolfees= The pool fee base rate for a given pool as a percentage
(0.01 to 100.00%)
--poolfees= The pool fee base rate for a given pool as a
percentage (0.01 to 100.00%)
--maxpriceabsolute= The absolute maximum price to pay for a ticket
(default: 100.0 Coin) (100)
--maxpricescale= Attempt to prevent the stake difficulty from going
above this multiplier (>1.0) by manipulation (default:
2.0, 0.0 to disable) (2)
above this multiplier (>1.0) by manipulation
(default: 2.0, 0.0 to disable) (2)
--minpricescale= Attempt to prevent the stake difficulty from going
below this multiplier (<1.0) by manipulation (default:
0.7, 0.0 to disable) (0.7)
below this multiplier (<1.0) by manipulation
(default: 0.7, 0.0 to disable) (0.7)
--pricetarget= A target to try to seek setting the stake price to
rather than meeting the average price (default: 0.0,
0.0 to disable)
--avgpricemode= The mode to use for calculating the average price if
pricetarget is disabled (default: dual)
--avgpricevwapdelta= The number of blocks to use from the current block to
calculate the VWAP (default: 2880)
rather than meeting the average price (default:
0.0, 0.0 to disable)
--avgpricemode= The mode to use for calculating the average price
if pricetarget is disabled (default: dual) (vwap)
--avgpricevwapdelta= The number of blocks to use from the current block
to calculate the VWAP (default: 2880) (2880)
--maxfee= Maximum ticket fee per KB (default: 1.0 Coin/KB) (1)
--minfee= Minimum ticket fee per KB (default: 0.01 Coin/KB) (0.01)
--feesource= The fee source to use for ticket fee per KB (median or
mean, default: mean) (mean)
--minfee= Minimum ticket fee per KB (default: 0.01 Coin/KB)
(0.01)
--feesource= The fee source to use for ticket fee per KB (median
or mean, default: mean) (mean)
--txfee= Default regular tx fee per KB, for consolidations
(default: 0.01 Coin/KB) (0.01)
--maxperblock= Maximum tickets per block, with negative numbers
indicating buy one ticket every 1-in-n blocks (default:
3)
--maxperblock= Maximum tickets per block, with negative numbers
indicating buy one ticket every 1-in-n blocks
(default: 3) (3)
--balancetomaintain= Balance to try to maintain in the wallet
--highpricepenalty= The exponential penalty to apply to the number of
tickets to purchase above the ideal ticket pool price
(default: 1.3) (1.3)
tickets to purchase above the ideal ticket pool
price (default: 1.3) (1.3)
--blockstoavg= Number of blocks to average for fees calculation
(default: 11) (11)
--feetargetscaling= The amount above the mean fee in the previous blocks to
purchase tickets with, proportional e.g. 1.05 = 105%
(default: 1.05) (1.05)
--feetargetscaling= The amount above the mean fee in the previous
blocks to purchase tickets with, proportional e.g.
1.05 = 105% (default: 1.05) (1.05)
--dontwaitfortickets Don't wait until your last round of tickets have
entered the blockchain to attempt to purchase more
--maxinmempool= The maximum number of tickets allowed in mempool before
purchasing more tickets (default: 0)
--expirydelta= Number of blocks in the future before the ticket expires
(default: 16) (16)
--maxinmempool= The maximum number of tickets allowed in mempool
before purchasing more tickets (default: 0)
--expirydelta= Number of blocks in the future before the ticket
expires (default: 16) (16)
```

#### Running on Linux/BSD/POSIX after Compilation

It is recommended to use a configuration file to fine tune the software. A
sample configuration file is give below, with explanations about what the
software will do. This is also found in the reposity itself as
"ticketbuyer-example.conf".
software will do. This is also found in the repository itself as
"sample-dcrticketbuyer.conf".

```
#########################################
Expand Down Expand Up @@ -198,12 +196,9 @@ dcrwcert=path/to/.dcrwallet/rpc.cert
## bind the server externally or to another IP.
httpsvrport=7770

## The path to store monitoring logs in along with all
## the libraries/data for the HTTP server. This folder
## must constain the JavaScript libraries d3 and dimple
## for this to function correctly.
## By default, the path is "webui/" in PWD.
httpuipath=webui/
## The path to store CSV data for the Web UI.
## The default path is ~/.dcrticketbuyer/data
#datadir=~/.dcrticketbuyer/data

## Enable testnet. Set to false to use mainnet. Can not
## be used with simnet.
Expand All @@ -227,7 +222,7 @@ simnet=false
# maxperblock=5

## Stop buying tickets if the mempool has more than
## 40 tickets in in.
## 40 tickets in it.
#
# maxinmempool=40

Expand Down Expand Up @@ -363,13 +358,13 @@ simnet=false
The program may then be run with

```bash
$ dcrticketbuyer -C ticketbuyer.conf
$ dcrticketbuyer -C dcrticketbuyer.conf
```

To enable more explicit output, set the debug level
for the ticket buyer subsystem to debug or trace:
```bash
$ dcrticketbuyer -C ticketbuyer.conf -d TKBY=debug
$ dcrticketbuyer -C dcrticketbuyer.conf -d TKBY=debug
```


Expand Down
2 changes: 1 addition & 1 deletion buyer.go
Expand Up @@ -167,7 +167,7 @@ func (t *ticketPurchaser) purchase(height int32) error {
// disk.
var csvData csvUpdateData
csvData.height = height
if t.cfg.HttpSvrPort != 0 {
if t.cfg.HTTPSvrPort != 0 {
// Write ticket fee info for the current block to the
// CSV update data.
oneBlock := uint32(1)
Expand Down
58 changes: 43 additions & 15 deletions config.go
Expand Up @@ -17,17 +17,18 @@ import (
)

const (
defaultConfigFilename = "ticketbuyer.conf"
defaultConfigFilename = "dcrticketbuyer.conf"
defaultDataDirname = "data"
defaultLogLevel = "info"
defaultLogDirname = "logs"
defaultLogFilename = "ticketbuyer.log"
defaultLogFilename = "dcrticketbuyer.log"
)

var activeNet = &netparams.MainNetParams

// csvPath is the default path for web server CSV files to be
// held in and for the JavaScript libraries. It is set to whatever
// HttpUIPath is after loading the configuration.
// held in. It is set to the DataDir after loading the
// configuration.
var csvPath = ""

var (
Expand All @@ -37,13 +38,13 @@ var (
defaultDaemonRPCKeyFile = filepath.Join(dcrdHomeDir, "rpc.key")
defaultDaemonRPCCertFile = filepath.Join(dcrdHomeDir, "rpc.cert")
defaultConfigFile = filepath.Join(dcrticketbuyerHomeDir, defaultConfigFilename)
defaultDataDir = filepath.Join(dcrticketbuyerHomeDir, defaultDataDirname)
defaultWalletRPCKeyFile = filepath.Join(dcrwalletHomeDir, "rpc.key")
defaultWalletRPCCertFile = filepath.Join(dcrwalletHomeDir, "rpc.cert")
defaultLogDir = filepath.Join(dcrticketbuyerHomeDir, defaultLogDirname)
defaultHost = "localhost"
defaultHttpServerBind = "localhost"
defaultHttpServerPort = 0
defaultHttpUIPath = "webui/"
defaultHTTPServerBind = "localhost"
defaultHTTPServerPort = 0

defaultAccountName = "default"
defaultTicketAddress = ""
Expand Down Expand Up @@ -71,14 +72,14 @@ var (
type config struct {
// General application behavior
ConfigFile string `short:"C" long:"configfile" description:"Path to configuration file"`
DataDir string `short:"b" long:"datadir" description:"Directory to store data"`
ShowVersion bool `short:"V" long:"version" description:"Display version information and exit"`
TestNet bool `long:"testnet" description:"Use the test network (default mainnet)"`
SimNet bool `long:"simnet" description:"Use the simulation test network (default mainnet)"`
DebugLevel string `short:"d" long:"debuglevel" description:"Logging level {trace, debug, info, warn, error, critical}"`
LogDir string `long:"logdir" description:"Directory to log output"`
HttpSvrBind string `long:"httpsvrbind" description:"IP to bind for the HTTP server that tracks ticket purchase metrics (default: \"\" or localhost)"`
HttpSvrPort int `long:"httpsvrport" description:"Server port for the HTTP server that tracks ticket purchase metrics; disabled if 0 (default: 0)"`
HttpUIPath string `long:"httpuipath" description:"Path for the data and JavaScript libraries for displaying/storing purchase metrics (default: \"webui/\")"`
HTTPSvrBind string `long:"httpsvrbind" description:"IP to bind for the HTTP server that tracks ticket purchase metrics (default: \"\" or localhost)"`
HTTPSvrPort int `long:"httpsvrport" description:"Server port for the HTTP server that tracks ticket purchase metrics; disabled if 0 (default: 0)"`

// RPC client options
DcrdUser string `long:"dcrduser" description:"Daemon RPC user name"`
Expand Down Expand Up @@ -226,10 +227,10 @@ func loadConfig() (*config, error) {
cfg := config{
DebugLevel: defaultLogLevel,
ConfigFile: defaultConfigFile,
DataDir: defaultDataDir,
LogDir: defaultLogDir,
HttpSvrBind: defaultHttpServerBind,
HttpSvrPort: defaultHttpServerPort,
HttpUIPath: defaultHttpUIPath,
HTTPSvrBind: defaultHTTPServerBind,
HTTPSvrPort: defaultHTTPServerPort,
DcrdCert: defaultDaemonRPCCertFile,
DcrwCert: defaultWalletRPCCertFile,
AccountName: defaultAccountName,
Expand Down Expand Up @@ -359,6 +360,33 @@ func loadConfig() (*config, error) {
return loadConfigError(err)
}

// Append the network type to the data directory so it is "namespaced"
// per network. The CSV files for the web UI will go here.
// 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 = cleanAndExpandPath(cfg.DataDir)
cfg.DataDir = filepath.Join(cfg.DataDir, activeNet.Name)

// Create the data dir if it does not exist.
err = os.MkdirAll(cfg.DataDir, 0700)
if err != nil {
// Show a nicer error message if it's because a symlink is
// linked to a directory that does not exist (probably because
// it's not mounted).
if e, ok := err.(*os.PathError); ok && os.IsExist(err) {
if link, lerr := os.Readlink(e.Path); lerr == nil {
str := "is symlink %s -> %s mounted?"
err = fmt.Errorf(str, e.Path, link)
}
}

str := "%s: Failed to create data directory: %v"
err := fmt.Errorf(str, funcName, err)
fmt.Fprintln(os.Stderr, err)
return loadConfigError(err)
}

// If the user has set a pool address, the pool fees for the
// pool can not be zero.
if cfg.PoolAddress != "" && cfg.PoolFees == 0.0 {
Expand All @@ -379,7 +407,7 @@ func loadConfig() (*config, error) {
}

// The HTTP server port can not be beyond a uint16's size in value.
if cfg.HttpSvrPort > 0xffff {
if cfg.HTTPSvrPort > 0xffff {
str := "%s: Invalid HTTP port number for HTTP server"
err := fmt.Errorf(str, "loadConfig")
fmt.Fprintln(os.Stderr, err)
Expand Down Expand Up @@ -435,7 +463,7 @@ func loadConfig() (*config, error) {
return loadConfigError(err)
}

csvPath = cfg.HttpUIPath
csvPath = cfg.DataDir

return &cfg, nil
}
13 changes: 5 additions & 8 deletions main.go
Expand Up @@ -82,7 +82,7 @@ func main() {
dcrrpcclient.UseLogger(clientLog)

// Initialize the CSV files for the HTTP server if needed.
if cfg.HttpSvrPort != 0 {
if cfg.HTTPSvrPort != 0 {
err := initCsvFiles()
if err != nil {
fmt.Printf("Failed to init https files: %s\n", err.Error())
Expand Down Expand Up @@ -203,15 +203,12 @@ func main() {

// If the HTTP server is enabled, spin it up and begin
// displaying the front page locally.
if cfg.HttpSvrPort > 0 {
if cfg.HTTPSvrPort > 0 {
go func() {
port := strconv.Itoa(cfg.HttpSvrPort)
port := strconv.Itoa(cfg.HTTPSvrPort)
http.HandleFunc("/", writeMainGraphs)
http.HandleFunc("/webui/", func(w http.ResponseWriter,
r *http.Request) {
http.ServeFile(w, r, r.URL.Path[1:])
})
err := http.ListenAndServe(cfg.HttpSvrBind+":"+port, nil)
http.Handle("/csvdata/", http.StripPrefix("/csvdata/", http.FileServer(http.Dir(cfg.DataDir))))
err := http.ListenAndServe(cfg.HTTPSvrBind+":"+port, nil)
if err != nil {
log.Errorf("Failed to bind http server: %s", err.Error())
}
Expand Down
11 changes: 4 additions & 7 deletions ticketbuyer-example.conf → sample-dcrticketbuyer.conf
Expand Up @@ -24,12 +24,9 @@ dcrwcert=path/to/.dcrwallet/rpc.cert
## bind the server externally or to another IP.
httpsvrport=7770

## The path to store monitoring logs in along with all
## the libraries/data for the HTTP server. This folder
## must constain the JavaScript libraries d3 and dimple
## for this to function correctly.
## By default, the path is "webui/" in PWD.
httpuipath=webui/
## The path to store CSV data for the Web UI.
## The default path is ~/.dcrticketbuyer/data
#datadir=~/.dcrticketbuyer/data

## Enable testnet. Set to false to use mainnet. Can not
## be used with simnet.
Expand All @@ -53,7 +50,7 @@ simnet=false
# maxperblock=3

## Stop buying tickets if the mempool has more than
## 40 tickets in in.
## 40 tickets in it.
#
# maxinmempool=40

Expand Down