From 8c3cab79422d747cfdd8b8042e918eab789e0162 Mon Sep 17 00:00:00 2001 From: jholdstock Date: Thu, 16 Jul 2020 10:11:24 +0100 Subject: [PATCH] API versioning --- docs/api.md | 27 ++++++++++++++++----------- docs/deployment.md | 1 + webapi/getfeeaddress.go | 2 +- webapi/payfee.go | 2 +- webapi/setvotechoices.go | 2 +- webapi/ticketstatus.go | 2 +- webapi/types.go | 1 + webapi/{vspstatus.go => vspinfo.go} | 3 ++- webapi/webapi.go | 2 +- 9 files changed, 25 insertions(+), 17 deletions(-) rename webapi/{vspstatus.go => vspinfo.go} (81%) diff --git a/docs/api.md b/docs/api.md index e0839b3..ce65941 100644 --- a/docs/api.md +++ b/docs/api.md @@ -21,6 +21,11 @@ - Implementation of request and response types can be found in [webapi/types.go](../webapi/types.go). +- The initial version of the vspd API is version 3. This is because the first + version of the vspd API actually represents the third iteration of VSP APIs. + The first and second iterations of VSP API were implemented by + [dcrstakepool](https://github.com/decred/dcrstakepool). + ## Expected usage ### Get VSP info @@ -28,10 +33,10 @@ 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 `/api/feeaddress` or `/api/payfee` +not currently accepting new tickets. Calling `/feeaddress` or `/payfee` when a VSP is closed will result in an error. -- `GET /api/vspinfo` +- `GET /api/v3/vspinfo` No request body. @@ -39,6 +44,7 @@ when a VSP is closed will result in an error. ```json { + "apiversions":[3], "timestamp":1590599436, "pubkey":"SjAmrAqH7LScCUwM1qo5O6Cu7aKhrM1ORszgZwD7HmU=", "feepercentage":3.0, @@ -62,7 +68,7 @@ DCR. Returns an error if the specified ticket is not currently immature or live. This call will return an error if a fee transaction has already been provided for the specified ticket. -- `POST /api/feeaddress` +- `POST /api/v3/feeaddress` Request: @@ -92,7 +98,7 @@ for the specified ticket. Provide the voting key for the ticket, voting preference, and a signed transaction which pays the fee to the specified address. If the fee has expired, this call will return an error and the client will need to request a new fee by -calling `/api/feeaddress` again. Returns an error if the specified ticket is not +calling `/feeaddress` again. Returns an error if the specified ticket is not currently immature or live. The VSP will not broadcast the fee transaction until the ticket purchase has 6 @@ -105,7 +111,7 @@ has 6 confirmations. This call will return an error if a fee transaction has already been provided for the specified ticket. -- `POST /api/payfee` +- `POST /api/v3/payfee` Request: @@ -131,7 +137,7 @@ for the specified ticket. ### Ticket Status Clients can check the status of a ticket at any time after calling -`/api/feeaddress`. +`/feeaddress`. - `ticketconfirmed` is true when the ticket purchase has 6 confirmations. - `feetxstatus` can have the following values: @@ -143,16 +149,15 @@ Clients can check the status of a ticket at any time after calling in the tx was double spent). If `feetxstatus` is `error`, the client needs to provide a new fee transaction -using `/api/payfee`. The VSP will only add a ticket to the voting wallets once +using `/payfee`. The VSP will only add a ticket to the voting wallets once its `feetxstatus` is `confirmed`. -- `POST /api/ticketstatus` +- `POST /api/v3/ticketstatus` Request: ```json { - "timestamp":1590509066, "tickethash":"484a68f7148e55d05f0b64a29fe7b148572cb5272d1ce2438cf15466d347f4f4" } ``` @@ -173,9 +178,9 @@ its `feetxstatus` is `confirmed`. ### Update vote choices Clients can update the voting preferences of their ticket at any time after -after calling `/api/payfee`. +after calling `/payfee`. -- `POST /api/setvotechoices` +- `POST /api/v3/setvotechoices` Request: diff --git a/docs/deployment.md b/docs/deployment.md index 3631151..9d31ee5 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -73,6 +73,7 @@ dcrstakepool deployment. - Run the vspd binary - Configure webserver to proxy requests from the internet to vspd. - Configure vspd to use the newly created dcrwallet instances. + - Web requests for `/api/v3` should be redirected to vspd. ## Monitoring diff --git a/webapi/getfeeaddress.go b/webapi/getfeeaddress.go index b9a30dc..77c2d54 100644 --- a/webapi/getfeeaddress.go +++ b/webapi/getfeeaddress.go @@ -57,7 +57,7 @@ func getCurrentFee(dcrdClient *rpc.DcrdRPC) (dcrutil.Amount, error) { return fee, nil } -// feeAddress is the handler for "POST /feeaddress". +// feeAddress is the handler for "POST /api/v3/feeaddress". func feeAddress(c *gin.Context) { funcName := "feeAddress" diff --git a/webapi/payfee.go b/webapi/payfee.go index f43c604..dffa190 100644 --- a/webapi/payfee.go +++ b/webapi/payfee.go @@ -12,7 +12,7 @@ import ( "github.com/gin-gonic/gin" ) -// payFee is the handler for "POST /payfee". +// payFee is the handler for "POST /api/v3/payfee". func payFee(c *gin.Context) { funcName := "payFee" diff --git a/webapi/setvotechoices.go b/webapi/setvotechoices.go index 2d7aff4..1b94ae3 100644 --- a/webapi/setvotechoices.go +++ b/webapi/setvotechoices.go @@ -8,7 +8,7 @@ import ( "github.com/gin-gonic/gin" ) -// setVoteChoices is the handler for "POST /setvotechoices". +// setVoteChoices is the handler for "POST /api/v3/setvotechoices". func setVoteChoices(c *gin.Context) { funcName := "setVoteChoices" diff --git a/webapi/ticketstatus.go b/webapi/ticketstatus.go index e9afe4d..0f87946 100644 --- a/webapi/ticketstatus.go +++ b/webapi/ticketstatus.go @@ -7,7 +7,7 @@ import ( "github.com/gin-gonic/gin" ) -// ticketStatus is the handler for "POST /ticketstatus". +// ticketStatus is the handler for "POST /api/v3/ticketstatus". func ticketStatus(c *gin.Context) { funcName := "ticketStatus" diff --git a/webapi/types.go b/webapi/types.go index 3b16766..fee243b 100644 --- a/webapi/types.go +++ b/webapi/types.go @@ -1,6 +1,7 @@ package webapi type vspInfoResponse struct { + APIVersions []int64 `json:"apiversions"` Timestamp int64 `json:"timestamp"` PubKey []byte `json:"pubkey"` FeePercentage float64 `json:"feepercentage"` diff --git a/webapi/vspstatus.go b/webapi/vspinfo.go similarity index 81% rename from webapi/vspstatus.go rename to webapi/vspinfo.go index c9f00ba..844717b 100644 --- a/webapi/vspstatus.go +++ b/webapi/vspinfo.go @@ -7,9 +7,10 @@ import ( "github.com/gin-gonic/gin" ) -// vspInfo is the handler for "GET /vspinfo". +// vspInfo is the handler for "GET /api/v3/vspinfo". func vspInfo(c *gin.Context) { sendJSONResponse(vspInfoResponse{ + APIVersions: []int64{3}, Timestamp: time.Now().Unix(), PubKey: signPubKey, FeePercentage: cfg.VSPFee, diff --git a/webapi/webapi.go b/webapi/webapi.go index 9fffd67..fd95b0d 100644 --- a/webapi/webapi.go +++ b/webapi/webapi.go @@ -188,7 +188,7 @@ func router(debugMode bool, cookieSecret []byte, dcrd rpc.DcrdConnect, wallets r // API routes. - api := router.Group("/api") + api := router.Group("/api/v3") api.GET("/vspinfo", vspInfo) api.POST("/feeaddress", withDcrdClient(dcrd), broadcastTicket(), vspAuth(), feeAddress) api.POST("/ticketstatus", withDcrdClient(dcrd), vspAuth(), ticketStatus)