diff --git a/cmd/vspd/vspd.go b/cmd/vspd/vspd.go index bd5a0ca..fc5111c 100644 --- a/cmd/vspd/vspd.go +++ b/cmd/vspd/vspd.go @@ -109,11 +109,12 @@ func (v *vspd) run() int { v.db.WritePeriodicBackups(shutdownCtx, &shutdownWg, v.cfg.BackupInterval) - // Ensure all data in database is present and up-to-date. - err := v.db.CheckIntegrity(v.dcrd) + // Run database integrity checks to ensure all data in database is present + // and up-to-date. + err := v.checkDatabaseIntegrity() if err != nil { // vspd should still start if this fails, so just log an error. - v.log.Errorf("Could not check database integrity: %v", err) + v.log.Errorf("Database integrity check failed: %v", err) } // Run the block connected handler now to catch up with any blocks mined @@ -206,6 +207,62 @@ func (v *vspd) run() int { return 0 } +// checkDatabaseIntegrity starts the process of ensuring that all data expected +// to be in the database is present and up to date. +func (v *vspd) checkDatabaseIntegrity() error { + err := v.checkPurchaseHeights() + if err != nil { + return err + } + + return nil +} + +// checkPurchaseHeights ensures a purchase height is recorded for all confirmed +// tickets in the database. This is necessary because of an old bug which, in +// some circumstances, would prevent purchase height from being stored. +func (v *vspd) checkPurchaseHeights() error { + missing, err := v.db.GetMissingPurchaseHeight() + if err != nil { + // Cannot proceed if this fails, return. + return fmt.Errorf("db.GetMissingPurchaseHeight error: %w", err) + } + + if len(missing) == 0 { + // Nothing to do, return. + return nil + } + + v.log.Warnf("%d tickets are missing purchase heights", len(missing)) + + dcrdClient, _, err := v.dcrd.Client() + if err != nil { + // Cannot proceed if this fails, return. + return err + } + + fixed := 0 + for _, ticket := range missing { + tktTx, err := dcrdClient.GetRawTransaction(ticket.Hash) + if err != nil { + // Just log and continue, other tickets might succeed. + v.log.Errorf("Could not get raw tx for ticket %s: %v", ticket.Hash, err) + continue + } + ticket.PurchaseHeight = tktTx.BlockHeight + err = v.db.UpdateTicket(ticket) + if err != nil { + // Just log and continue, other tickets might succeed. + v.log.Errorf("Could not insert purchase height for ticket %s: %v", ticket.Hash, err) + continue + } + fixed++ + } + + v.log.Infof("Added missing purchase height to %d tickets", fixed) + return nil +} + // blockConnected is called once when vspd starts up, and once each time a // blockconnected notification is received from dcrd. func (v *vspd) blockConnected() { diff --git a/database/database.go b/database/database.go index 170a854..c1e2882 100644 --- a/database/database.go +++ b/database/database.go @@ -17,7 +17,6 @@ import ( "time" "github.com/decred/slog" - "github.com/decred/vspd/rpc" bolt "go.etcd.io/bbolt" ) @@ -405,52 +404,3 @@ func (vdb *VspDatabase) BackupDB(w http.ResponseWriter) error { return err } - -// CheckIntegrity will ensure that all data expected to be in the database is -// present and up to date. -func (vdb *VspDatabase) CheckIntegrity(dcrd rpc.DcrdConnect) error { - - // Ensure a purchase height is recorded for all confirmed tickets in the - // database. This is necessary because of an old bug which, in some - // circumstances, would prevent purchase height from being stored. - - missing, err := vdb.GetMissingPurchaseHeight() - if err != nil { - // Cannot proceed if this fails, return. - return fmt.Errorf("db.GetMissingPurchaseHeight error: %w", err) - } - - if len(missing) == 0 { - // Nothing to do, return. - return nil - } - - vdb.log.Warnf("%d tickets are missing purchase heights", len(missing)) - - dcrdClient, _, err := dcrd.Client() - if err != nil { - // Cannot proceed if this fails, return. - return err - } - - fixed := 0 - for _, ticket := range missing { - tktTx, err := dcrdClient.GetRawTransaction(ticket.Hash) - if err != nil { - // Just log and continue, other tickets might succeed. - vdb.log.Errorf("Could not get raw tx for ticket %s: %v", ticket.Hash, err) - continue - } - ticket.PurchaseHeight = tktTx.BlockHeight - err = vdb.UpdateTicket(ticket) - if err != nil { - // Just log and continue, other tickets might succeed. - vdb.log.Errorf("Could not insert purchase height for ticket %s: %v", ticket.Hash, err) - continue - } - fixed++ - } - - vdb.log.Infof("Added missing purchase height to %d tickets", fixed) - return nil -}