From cf55092c216019bedad4f90a688b5035b9b7656f Mon Sep 17 00:00:00 2001 From: Jamie Holdstock Date: Wed, 20 May 2020 08:09:07 +0100 Subject: [PATCH] Add ticket hash to payfee request. (#38) --- database/database_test.go | 74 --------------------------------------- database/ticket.go | 55 ----------------------------- webapi/methods.go | 33 ++++++----------- webapi/responses.go | 9 ++--- 4 files changed, 16 insertions(+), 155 deletions(-) diff --git a/database/database_test.go b/database/database_test.go index 4b2edc5..04b0620 100644 --- a/database/database_test.go +++ b/database/database_test.go @@ -36,9 +36,7 @@ func TestDatabase(t *testing.T) { tests := map[string]func(*testing.T){ "testInsertFeeAddress": testInsertFeeAddress, "testGetTicketByHash": testGetTicketByHash, - "testGetFeesByFeeAddress": testGetFeesByFeeAddress, "testInsertFeeAddressVotingKey": testInsertFeeAddressVotingKey, - "testGetInactiveFeeAddresses": testGetInactiveFeeAddresses, "testUpdateExpireAndFee": testUpdateExpireAndFee, "testUpdateVoteBits": testUpdateVoteBits, } @@ -121,45 +119,6 @@ func testGetTicketByHash(t *testing.T) { } } -func testGetFeesByFeeAddress(t *testing.T) { - // Insert a ticket into the database. - ticket := exampleTicket() - err := db.InsertFeeAddress(ticket) - if err != nil { - t.Fatalf("error storing ticket in database: %v", err) - } - - // Retrieve ticket using its fee address. - retrieved, err := db.GetTicketByFeeAddress(ticket.FeeAddress) - if err != nil { - t.Fatalf("error retrieving ticket by fee address: %v", err) - } - - // Check it is the correct ticket. - if retrieved.FeeAddress != ticket.FeeAddress { - t.Fatal("retrieved ticket FeeAddress didnt match expected") - } - - // Error if non-existent ticket requested. - _, err = db.GetTicketByFeeAddress("Not a real fee address") - if err == nil { - t.Fatal("expected an error while retrieving a non-existent ticket") - } - - // Insert another ticket into the database with the same fee address. - ticket.Hash = ticket.Hash + "2" - err = db.InsertFeeAddress(ticket) - if err != nil { - t.Fatalf("error storing ticket in database: %v", err) - } - - // Error when more than one ticket matches - _, err = db.GetTicketByFeeAddress(ticket.FeeAddress) - if err == nil { - t.Fatal("expected an error when multiple tickets are found") - } -} - func testInsertFeeAddressVotingKey(t *testing.T) { // Insert a ticket into the database. ticket := exampleTicket() @@ -189,39 +148,6 @@ func testInsertFeeAddressVotingKey(t *testing.T) { } } -func testGetInactiveFeeAddresses(t *testing.T) { - // Insert a ticket into the database. - ticket := exampleTicket() - err := db.InsertFeeAddress(ticket) - if err != nil { - t.Fatalf("error storing ticket in database: %v", err) - } - - // Insert a ticket with empty voting key into the database. - ticket.Hash = ticket.Hash + "2" - newFeeAddr := ticket.FeeAddress + "2" - ticket.FeeAddress = newFeeAddr - ticket.VotingKey = "" - err = db.InsertFeeAddress(ticket) - if err != nil { - t.Fatalf("error storing ticket in database: %v", err) - } - - // Retrieve unused fee address from database. - feeAddrs, err := db.GetInactiveFeeAddresses() - if err != nil { - t.Fatalf("error retrieving inactive fee addresses: %v", err) - } - - // Check we have one value, and its the expected one. - if len(feeAddrs) != 1 { - t.Fatal("expected 1 unused fee address") - } - if feeAddrs[0] != newFeeAddr { - t.Fatal("fee address didnt match expected") - } -} - func testUpdateExpireAndFee(t *testing.T) { // Insert a ticket into the database. ticket := exampleTicket() diff --git a/database/ticket.go b/database/ticket.go index 4d72c2d..d19a157 100644 --- a/database/ticket.go +++ b/database/ticket.go @@ -73,61 +73,6 @@ func (vdb *VspDatabase) InsertFeeAddressVotingKey(address, votingKey string, vot }) } -func (vdb *VspDatabase) GetInactiveFeeAddresses() ([]string, error) { - var addrs []string - err := vdb.db.View(func(tx *bolt.Tx) error { - ticketBkt := tx.Bucket(vspBktK).Bucket(ticketBktK) - c := ticketBkt.Cursor() - - for k, v := c.First(); k != nil; k, v = c.Next() { - var ticket Ticket - err := json.Unmarshal(v, &ticket) - if err != nil { - return fmt.Errorf("could not unmarshal ticket: %v", err) - } - - if ticket.VotingKey == "" { - addrs = append(addrs, ticket.FeeAddress) - } - } - - return nil - }) - - return addrs, err -} - -func (vdb *VspDatabase) GetTicketByFeeAddress(feeAddr string) (*Ticket, error) { - var tickets []Ticket - err := vdb.db.View(func(tx *bolt.Tx) error { - ticketBkt := tx.Bucket(vspBktK).Bucket(ticketBktK) - c := ticketBkt.Cursor() - - for k, v := c.First(); k != nil; k, v = c.Next() { - var ticket Ticket - err := json.Unmarshal(v, &ticket) - if err != nil { - return fmt.Errorf("could not unmarshal ticket: %v", err) - } - - if ticket.FeeAddress == feeAddr { - tickets = append(tickets, ticket) - } - } - - return nil - }) - if err != nil { - return nil, err - } - - if len(tickets) != 1 { - return nil, fmt.Errorf("expected 1 ticket with fee address %s, found %d", feeAddr, len(tickets)) - } - - return &tickets[0], nil -} - func (vdb *VspDatabase) GetTicketByHash(hash string) (Ticket, error) { var ticket Ticket err := vdb.db.View(func(tx *bolt.Tx) error { diff --git a/webapi/methods.go b/webapi/methods.go index 54b3973..21d3923 100644 --- a/webapi/methods.go +++ b/webapi/methods.go @@ -262,7 +262,7 @@ func payFee(c *gin.Context) { voteBits := payFeeRequest.VoteBits - feeTxBytes, err := hex.DecodeString(payFeeRequest.Hex) + feeTxBytes, err := hex.DecodeString(payFeeRequest.FeeTx) if err != nil { log.Warnf("Failed to decode tx: %v", err) sendErrorResponse("failed to decode transaction", http.StatusBadRequest, c) @@ -279,14 +279,12 @@ func payFee(c *gin.Context) { // TODO: DB - check expiration given during fee address request - validFeeAddrs, err := db.GetInactiveFeeAddresses() + ticket, err := db.GetTicketByHash(payFeeRequest.TicketHash) if err != nil { - log.Errorf("GetInactiveFeeAddresses error: %v", err) - sendErrorResponse("database error", http.StatusInternalServerError, c) + log.Warnf("Invalid ticket from %s", c.ClientIP()) + sendErrorResponse("invalid ticket", http.StatusBadRequest, c) return } - - var feeAddr string var feeAmount dcrutil.Amount const scriptVersion = 0 @@ -300,28 +298,19 @@ findAddress: return } for _, addr := range addresses { - addrStr := addr.Address() - for _, validFeeAddr := range validFeeAddrs { - if addrStr == validFeeAddr { - feeAddr = validFeeAddr - feeAmount = dcrutil.Amount(txOut.Value) - break findAddress - } + if addr.Address() == ticket.FeeAddress { + feeAmount = dcrutil.Amount(txOut.Value) + break findAddress } } } - if feeAddr == "" { - log.Warnf("feeTx did not include any payments") - sendErrorResponse("feeTx did not include any payments", http.StatusBadRequest, c) + + if feeAmount == 0 { + log.Warnf("FeeTx for ticket %s did not include any payments for address %s", ticket.Hash, ticket.FeeAddress) + sendErrorResponse("feetx did not include any payments for fee address", http.StatusBadRequest, c) return } - ticket, err := db.GetTicketByFeeAddress(feeAddr) - if err != nil { - log.Errorf("GetFeeByAddress: %v", err) - sendErrorResponse("database error", http.StatusInternalServerError, c) - return - } voteAddr, err := dcrutil.DecodeAddress(ticket.CommitmentAddress, cfg.NetParams) if err != nil { log.Errorf("DecodeAddress: %v", err) diff --git a/webapi/responses.go b/webapi/responses.go index 0e2517b..78ed8b6 100644 --- a/webapi/responses.go +++ b/webapi/responses.go @@ -25,10 +25,11 @@ type feeAddressResponse struct { } type PayFeeRequest struct { - Timestamp int64 `json:"timestamp" binding:"required"` - Hex string `json:"feetx" binding:"required"` - VotingKey string `json:"votingkey" binding:"required"` - VoteBits uint16 `json:"votebits" binding:"required"` + Timestamp int64 `json:"timestamp" binding:"required"` + TicketHash string `json:"tickethash" binding:"required"` + FeeTx string `json:"feetx" binding:"required"` + VotingKey string `json:"votingkey" binding:"required"` + VoteBits uint16 `json:"votebits" binding:"required"` } type payFeeResponse struct {