diff --git a/cmd/vspd/main.go b/cmd/vspd/main.go index 2dd6bae..50fe3be 100644 --- a/cmd/vspd/main.go +++ b/cmd/vspd/main.go @@ -9,6 +9,7 @@ import ( "os" "runtime" "sync" + "time" "github.com/decred/dcrd/wire" "github.com/decred/vspd/database" @@ -108,13 +109,28 @@ func run() int { }() // Start vspd. - vspd := newVspd(cfg, log, db, dcrd, wallets, blockNotifChan) + vspd := newVspd(cfg.network, log, db, dcrd, wallets, blockNotifChan) shutdownWg.Add(1) go func() { vspd.run(ctx) shutdownWg.Done() }() + // Periodically write a database backup file. + shutdownWg.Add(1) + go func() { + select { + case <-ctx.Done(): + shutdownWg.Done() + return + case <-time.After(cfg.BackupInterval): + err := db.WriteHotBackupFile() + if err != nil { + log.Errorf("Failed to write database backup: %v", err) + } + } + }() + // Wait for shutdown tasks to complete before running deferred tasks and // returning. shutdownWg.Wait() diff --git a/cmd/vspd/spentticket.go b/cmd/vspd/spentticket.go index 9c61c98..c130a54 100644 --- a/cmd/vspd/spentticket.go +++ b/cmd/vspd/spentticket.go @@ -66,8 +66,6 @@ func (s *spentTicket) missed() bool { // height of the most recent scanned block. func (v *vspd) findSpentTickets(ctx context.Context, toCheck database.TicketList, startHeight int64) ([]spentTicket, int64, error) { - network := v.cfg.network - dcrdClient, _, err := v.dcrd.Client() if err != nil { return nil, 0, err @@ -102,7 +100,7 @@ func (v *vspd) findSpentTickets(ctx context.Context, toCheck database.TicketList tickets := make([]ticketTuple, 0, len(toCheck)) scripts := make([][]byte, 0, len(toCheck)) for _, ticket := range toCheck { - parsedAddr, err := stdaddr.DecodeAddress(ticket.CommitmentAddress, network) + parsedAddr, err := stdaddr.DecodeAddress(ticket.CommitmentAddress, v.network) if err != nil { return nil, 0, err } @@ -135,7 +133,7 @@ func (v *vspd) findSpentTickets(ctx context.Context, toCheck database.TicketList return nil, 0, err } - verifyProof := network.DCP5Active(iHeight) + verifyProof := v.network.DCP5Active(iHeight) key, filter, err := dcrdClient.GetCFilterV2(iHeader, verifyProof) if err != nil { return nil, 0, err @@ -165,10 +163,12 @@ func (v *vspd) findSpentTickets(ctx context.Context, toCheck database.TicketList // Confirmed - ticket is spent in block. spent = append(spent, spentTicket{ - dbTicket: tickets[i].dbTicket, - expiryHeight: tickets[i].dbTicket.PurchaseHeight + int64(network.TicketMaturity) + int64(network.TicketExpiry), - heightSpent: iHeight, - spendingTx: blkTx, + dbTicket: tickets[i].dbTicket, + expiryHeight: tickets[i].dbTicket.PurchaseHeight + + int64(v.network.TicketMaturity) + + int64(v.network.TicketExpiry), + heightSpent: iHeight, + spendingTx: blkTx, }) // Remove this ticket and its script before continuing with the diff --git a/cmd/vspd/vspd.go b/cmd/vspd/vspd.go index cd83ed7..a7dedd6 100644 --- a/cmd/vspd/vspd.go +++ b/cmd/vspd/vspd.go @@ -14,6 +14,7 @@ import ( "github.com/decred/dcrd/wire" "github.com/decred/slog" "github.com/decred/vspd/database" + "github.com/decred/vspd/internal/config" "github.com/decred/vspd/rpc" "github.com/jrick/wsrpc/v2" ) @@ -37,7 +38,7 @@ const ( ) type vspd struct { - cfg *vspdConfig + network *config.Network log slog.Logger db *database.VspDatabase dcrd rpc.DcrdConnect @@ -50,11 +51,11 @@ type vspd struct { lastScannedBlock int64 } -func newVspd(cfg *vspdConfig, log slog.Logger, db *database.VspDatabase, +func newVspd(network *config.Network, log slog.Logger, db *database.VspDatabase, dcrd rpc.DcrdConnect, wallets rpc.WalletConnect, blockNotifChan chan *wire.BlockHeader) *vspd { v := &vspd{ - cfg: cfg, + network: network, log: log, db: db, dcrd: dcrd, @@ -104,8 +105,6 @@ func (v *vspd) run(ctx context.Context) { } // Start all background tasks and notification handlers. - backupTicker := time.NewTicker(v.cfg.BackupInterval) - defer backupTicker.Stop() consistencyTicker := time.NewTicker(consistencyInterval) defer consistencyTicker.Stop() dcrdTicker := time.NewTicker(dcrdInterval) @@ -113,14 +112,6 @@ func (v *vspd) run(ctx context.Context) { for { select { - - // Periodically write a database backup file. - case <-backupTicker.C: - err := v.db.WriteHotBackupFile() - if err != nil { - v.log.Errorf("Failed to write database backup: %v", err) - } - // Run voting wallet consistency check periodically. case <-consistencyTicker.C: v.checkWalletConsistency(ctx) @@ -223,7 +214,7 @@ func (v *vspd) checkRevoked(ctx context.Context) error { // Search for the transactions which spend these tickets, starting at the // earliest height one of them matured. - startHeight := revoked.EarliestPurchaseHeight() + int64(v.cfg.network.TicketMaturity) + startHeight := revoked.EarliestPurchaseHeight() + int64(v.network.TicketMaturity) spent, _, err := v.findSpentTickets(ctx, revoked, startHeight) if err != nil { @@ -492,7 +483,7 @@ func (v *vspd) blockConnected(ctx context.Context) { // Use the earliest height at which a votable ticket matured if vspd has // not performed a scan for spent tickets since it started. This will // catch any tickets which were spent whilst vspd was offline. - startHeight = votableTickets.EarliestPurchaseHeight() + int64(v.cfg.network.TicketMaturity) + startHeight = votableTickets.EarliestPurchaseHeight() + int64(v.network.TicketMaturity) } else { startHeight = v.lastScannedBlock }