Add ticket hash to payfee request. (#38)
This commit is contained in:
parent
d31c24b531
commit
cf55092c21
@ -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()
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user