Delete tickets with no information.

This commit is contained in:
jholdstock 2020-06-15 12:10:10 +01:00 committed by David Hill
parent 9ade20bf1c
commit 29268467f9
4 changed files with 60 additions and 1 deletions

View File

@ -3,6 +3,7 @@ package background
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"errors"
"sync" "sync"
"time" "time"
@ -10,6 +11,7 @@ import (
"github.com/decred/dcrd/chaincfg/v3" "github.com/decred/dcrd/chaincfg/v3"
"github.com/decred/vspd/database" "github.com/decred/vspd/database"
"github.com/decred/vspd/rpc" "github.com/decred/vspd/rpc"
"github.com/jrick/wsrpc/v2"
) )
var ( var (
@ -28,6 +30,9 @@ const (
// requiredConfs is the number of confirmations required to consider a // requiredConfs is the number of confirmations required to consider a
// ticket purchase or a fee transaction to be final. // ticket purchase or a fee transaction to be final.
requiredConfs = 6 requiredConfs = 6
// errNoTxInfo is defined in dcrd/dcrjson. Copying here so we dont need to
// import the whole package.
errNoTxInfo = -5
) )
// Notify is called every time a block notification is received from dcrd. // Notify is called every time a block notification is received from dcrd.
@ -76,9 +81,26 @@ func blockConnected() {
for _, ticket := range unconfirmed { for _, ticket := range unconfirmed {
tktTx, err := dcrdClient.GetRawTransaction(ticket.Hash) tktTx, err := dcrdClient.GetRawTransaction(ticket.Hash)
if err != nil { if err != nil {
// errNoTxInfo here probably indicates a tx which was never mined
// and has been removed from the mempool. For example, a ticket
// purchase tx close to an sdiff change, or a ticket purchase tx
// which expired. Remove it from the db.
var e *wsrpc.Error
if errors.As(err, &e) && e.Code == errNoTxInfo {
log.Infof("Removing unconfirmed ticket from db - no information available "+
"about transaction %s", err.Error())
err = db.DeleteTicket(ticket)
if err != nil {
log.Errorf("DeleteTicket error: %v", err)
}
} else {
log.Errorf("GetRawTransaction error: %v", err) log.Errorf("GetRawTransaction error: %v", err)
}
continue continue
} }
if tktTx.Confirmations >= requiredConfs { if tktTx.Confirmations >= requiredConfs {
ticket.Confirmed = true ticket.Confirmed = true
err = db.UpdateTicket(ticket) err = db.UpdateTicket(ticket)

View File

@ -28,6 +28,7 @@ func TestDatabase(t *testing.T) {
"testTicketFeeExpired": testTicketFeeExpired, "testTicketFeeExpired": testTicketFeeExpired,
"testFilterTickets": testFilterTickets, "testFilterTickets": testFilterTickets,
"testAddressIndex": testAddressIndex, "testAddressIndex": testAddressIndex,
"testDeleteTicket": testDeleteTicket,
} }
for testName, test := range tests { for testName, test := range tests {

View File

@ -103,6 +103,18 @@ func (vdb *VspDatabase) InsertNewTicket(ticket Ticket) error {
}) })
} }
func (vdb *VspDatabase) DeleteTicket(ticket Ticket) error {
return vdb.db.Update(func(tx *bolt.Tx) error {
ticketBkt := tx.Bucket(vspBktK).Bucket(ticketBktK)
err := ticketBkt.Delete([]byte(ticket.Hash))
if err != nil {
return fmt.Errorf("could not delete ticket: %v", err)
}
return nil
})
}
func (vdb *VspDatabase) UpdateTicket(ticket Ticket) error { func (vdb *VspDatabase) UpdateTicket(ticket Ticket) error {
return vdb.db.Update(func(tx *bolt.Tx) error { return vdb.db.Update(func(tx *bolt.Tx) error {
ticketBkt := tx.Bucket(vspBktK).Bucket(ticketBktK) ticketBkt := tx.Bucket(vspBktK).Bucket(ticketBktK)

View File

@ -55,6 +55,30 @@ func testInsertNewTicket(t *testing.T) {
} }
} }
func testDeleteTicket(t *testing.T) {
// Insert a ticket into the database.
ticket := exampleTicket()
err := db.InsertNewTicket(ticket)
if err != nil {
t.Fatalf("error storing ticket in database: %v", err)
}
// Delete ticket
err = db.DeleteTicket(ticket)
if err != nil {
t.Fatalf("error deleting ticket: %v", err)
}
// Nothing should be in the db.
_, found, err := db.GetTicketByHash(ticket.Hash)
if err != nil {
t.Fatalf("error retrieving ticket by ticket hash: %v", err)
}
if found {
t.Fatal("expected found==false")
}
}
func testGetTicketByHash(t *testing.T) { func testGetTicketByHash(t *testing.T) {
ticket := exampleTicket() ticket := exampleTicket()
// Insert a ticket into the database. // Insert a ticket into the database.