diff --git a/config.go b/config.go index f5890a1..07713fb 100644 --- a/config.go +++ b/config.go @@ -29,6 +29,7 @@ var ( defaultWalletHost = "127.0.0.1" defaultWebServerDebug = false defaultBackupInterval = time.Minute * 3 + defaultVspClosed = false ) // config defines the configuration options for the VSP. @@ -51,6 +52,7 @@ type config struct { WebServerDebug bool `long:"webserverdebug" ini-name:"webserverdebug" description:"Enable web server debug mode (verbose logging to terminal and live-reloading templates)."` SupportEmail string `long:"supportemail" ini-name:"supportemail" description:"Email address for users in need of support."` BackupInterval time.Duration `long:"backupinterval" ini-name:"backupinterval" description:"Time period between automatic database backups. Valid time units are {s,m,h}. Minimum 30 seconds."` + VspClosed bool `long:"vspclosed" ini-name:"vspclosed" description:"Closed prevents the VSP from accepting new tickets."` dbPath string netParams *netParams @@ -156,6 +158,7 @@ func loadConfig() (*config, error) { WalletHost: defaultWalletHost, WebServerDebug: defaultWebServerDebug, BackupInterval: defaultBackupInterval, + VspClosed: defaultVspClosed, } // Pre-parse the command line options to see if an alternative config diff --git a/docs/api.md b/docs/api.md index d31cb58..9c5059a 100644 --- a/docs/api.md +++ b/docs/api.md @@ -15,13 +15,15 @@ ## Expected usage -### Get VSP public key +### Get VSP info -Clients should first retrieve the VSP's public key so they can check the -signature on later API responses. A VSP should never change their public key so -it can be requested once and cached indefinitely. +Clients should retrieve the VSP's public key so they can check the signature on +future API responses. A VSP should never change their public key so it can be +requested once and cached indefinitely. `vspclosed` indicates that the VSP is +not currently accepting new tickets. Calling `/feeaddress` when a VSP is closed +will result in an error. -- `GET /api/pubkey` +- `GET /api/vspinfo` No request body. @@ -29,8 +31,11 @@ it can be requested once and cached indefinitely. ```json { - "timestamp":1590509065, - "pubkey":"bLNwVVcda3LqRLv+m0J5sjd60+twjO/fuhcx8RUErDQ=" + "timestamp":1590599436, + "pubkey":"SjAmrAqH7LScCUwM1qo5O6Cu7aKhrM1ORszgZwD7HmU=", + "feepercentage":0.05, + "vspclosed":false, + "network":"testnet3" } ``` @@ -101,11 +106,7 @@ has 6 confirmations. } ``` -### Information requests - -Clients can check the status of the server at any time. - -// TODO +### Ticket Status Clients can check the status of a ticket at any time after calling `/feeaddress`. diff --git a/main.go b/main.go index 3120be1..6b8def8 100644 --- a/main.go +++ b/main.go @@ -44,6 +44,11 @@ func run(ctx context.Context) error { return err } + if cfg.VspClosed { + log.Warnf("Config --vspclosed is set. This will prevent vspd from " + + "accepting new tickets.") + } + // Waitgroup for services to signal when they have shutdown cleanly. var shutdownWg sync.WaitGroup defer log.Info("Shutdown complete") @@ -117,6 +122,7 @@ func run(ctx context.Context) error { NetParams: cfg.netParams.Params, FeeAddressExpiration: defaultFeeAddressExpiration, SupportEmail: cfg.SupportEmail, + VspClosed: cfg.VspClosed, } err = webapi.Start(ctx, shutdownRequestChannel, &shutdownWg, cfg.Listen, db, dcrdConnect, walletConnect, cfg.WebServerDebug, cfg.FeeXPub, apiCfg) diff --git a/webapi/getfeeaddress.go b/webapi/getfeeaddress.go index abc13f9..db3202a 100644 --- a/webapi/getfeeaddress.go +++ b/webapi/getfeeaddress.go @@ -69,6 +69,11 @@ func feeAddress(c *gin.Context) { commitmentAddress := c.MustGet("CommitmentAddress").(string) dcrdClient := c.MustGet("DcrdClient").(*rpc.DcrdRPC) + if cfg.VspClosed { + sendErrorResponse("pool is not accepting new tickets", http.StatusBadRequest, c) + return + } + var feeAddressRequest FeeAddressRequest if err := binding.JSON.BindBody(rawRequest, &feeAddressRequest); err != nil { log.Warnf("Bad feeaddress request from %s: %v", c.ClientIP(), err) diff --git a/webapi/homepage.go b/webapi/homepage.go new file mode 100644 index 0000000..156adb5 --- /dev/null +++ b/webapi/homepage.go @@ -0,0 +1,44 @@ +package webapi + +import ( + "net/http" + "time" + + "github.com/jholdstock/vspd/database" + + "github.com/gin-gonic/gin" +) + +type vspStats struct { + PubKey []byte + TotalTickets int + FeePaidTickets int + VSPFee float64 + Network string + UpdateTime string + SupportEmail string + VspClosed bool +} + +var stats *vspStats + +func updateVSPStats(db *database.VspDatabase, cfg Config) (*vspStats, error) { + total, feePaid, err := db.CountTickets() + if err != nil { + return nil, err + } + return &vspStats{ + PubKey: signPubKey, + TotalTickets: total, + FeePaidTickets: feePaid, + VSPFee: cfg.VSPFee, + Network: cfg.NetParams.Name, + UpdateTime: time.Now().Format("Mon Jan _2 15:04:05 2006"), + SupportEmail: cfg.SupportEmail, + VspClosed: cfg.VspClosed, + }, nil +} + +func homepage(c *gin.Context) { + c.HTML(http.StatusOK, "homepage.html", stats) +} diff --git a/webapi/status.go b/webapi/status.go deleted file mode 100644 index e48aa05..0000000 --- a/webapi/status.go +++ /dev/null @@ -1,23 +0,0 @@ -package webapi - -import ( - "time" - - "github.com/gin-gonic/gin" -) - -// pubKey is the handler for "GET /pubkey". -func pubKey(c *gin.Context) { - sendJSONResponse(pubKeyResponse{ - Timestamp: time.Now().Unix(), - PubKey: signPubKey, - }, c) -} - -// fee is the handler for "GET /fee". -func fee(c *gin.Context) { - sendJSONResponse(feeResponse{ - Timestamp: time.Now().Unix(), - FeePercentage: cfg.VSPFee, - }, c) -} diff --git a/webapi/templates/homepage.html b/webapi/templates/homepage.html index 37d46a8..20ab7c2 100644 --- a/webapi/templates/homepage.html +++ b/webapi/templates/homepage.html @@ -48,6 +48,7 @@
Last updated: {{.UpdateTime}}