database: Add TicketList struct.
This enables a func to find the earliest purchase height to be reused in multiple packages.
This commit is contained in:
parent
8b50fe619a
commit
bca2a32a30
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2020-2022 The Decred developers
|
||||
// Copyright (c) 2020-2023 The Decred developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
@ -239,7 +239,7 @@ func blockConnected(dcrdRPC rpc.DcrdConnect, walletRPC rpc.WalletConnect, db *da
|
||||
}
|
||||
|
||||
// Find the oldest block height from confirmed tickets.
|
||||
oldestHeight := findOldestHeight(votableTickets)
|
||||
oldestHeight := votableTickets.EarliestPurchaseHeight()
|
||||
|
||||
ticketInfo, err := walletClient.TicketInfo(oldestHeight)
|
||||
if err != nil {
|
||||
@ -319,7 +319,7 @@ func checkWalletConsistency(dcrdRPC rpc.DcrdConnect, walletRPC rpc.WalletConnect
|
||||
}
|
||||
|
||||
// Find the oldest block height from confirmed tickets.
|
||||
oldestHeight := findOldestHeight(votableTickets)
|
||||
oldestHeight := votableTickets.EarliestPurchaseHeight()
|
||||
|
||||
// Iterate over each wallet and add any missing tickets.
|
||||
for _, walletClient := range walletClients {
|
||||
@ -440,17 +440,3 @@ func checkWalletConsistency(dcrdRPC rpc.DcrdConnect, walletRPC rpc.WalletConnect
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func findOldestHeight(tickets []database.Ticket) int64 {
|
||||
var oldestHeight int64
|
||||
for _, ticket := range tickets {
|
||||
// skip unconfirmed tickets
|
||||
if ticket.PurchaseHeight == 0 {
|
||||
continue
|
||||
}
|
||||
if oldestHeight == 0 || oldestHeight > ticket.PurchaseHeight {
|
||||
oldestHeight = ticket.PurchaseHeight
|
||||
}
|
||||
}
|
||||
return oldestHeight
|
||||
}
|
||||
|
||||
@ -91,6 +91,25 @@ type Ticket struct {
|
||||
Outcome TicketOutcome
|
||||
}
|
||||
|
||||
type TicketList []Ticket
|
||||
|
||||
// EarliestPurchaseHeight returns the lowest non-zero purchase height in the
|
||||
// list of tickets. Zero will be returned if the list is empty, or if every
|
||||
// ticket in the list has zero purchase height.
|
||||
func (t TicketList) EarliestPurchaseHeight() int64 {
|
||||
var oldestHeight int64
|
||||
for _, ticket := range t {
|
||||
// Skip unconfirmed tickets.
|
||||
if ticket.PurchaseHeight == 0 {
|
||||
continue
|
||||
}
|
||||
if oldestHeight == 0 || oldestHeight > ticket.PurchaseHeight {
|
||||
oldestHeight = ticket.PurchaseHeight
|
||||
}
|
||||
}
|
||||
return oldestHeight
|
||||
}
|
||||
|
||||
func (t *Ticket) FeeExpired() bool {
|
||||
now := time.Now()
|
||||
return now.After(time.Unix(t.FeeExpiration, 0))
|
||||
@ -315,7 +334,7 @@ func (vdb *VspDatabase) CountTickets() (int64, int64, int64, error) {
|
||||
}
|
||||
|
||||
// GetUnconfirmedTickets returns tickets which are not yet confirmed.
|
||||
func (vdb *VspDatabase) GetUnconfirmedTickets() ([]Ticket, error) {
|
||||
func (vdb *VspDatabase) GetUnconfirmedTickets() (TicketList, error) {
|
||||
vdb.ticketsMtx.RLock()
|
||||
defer vdb.ticketsMtx.RUnlock()
|
||||
|
||||
@ -326,7 +345,7 @@ func (vdb *VspDatabase) GetUnconfirmedTickets() ([]Ticket, error) {
|
||||
|
||||
// GetPendingFees returns tickets which are confirmed and have a fee tx which is
|
||||
// not yet broadcast.
|
||||
func (vdb *VspDatabase) GetPendingFees() ([]Ticket, error) {
|
||||
func (vdb *VspDatabase) GetPendingFees() (TicketList, error) {
|
||||
vdb.ticketsMtx.RLock()
|
||||
defer vdb.ticketsMtx.RUnlock()
|
||||
|
||||
@ -337,7 +356,7 @@ func (vdb *VspDatabase) GetPendingFees() ([]Ticket, error) {
|
||||
|
||||
// GetUnconfirmedFees returns tickets with a fee tx that is broadcast but not
|
||||
// confirmed yet.
|
||||
func (vdb *VspDatabase) GetUnconfirmedFees() ([]Ticket, error) {
|
||||
func (vdb *VspDatabase) GetUnconfirmedFees() (TicketList, error) {
|
||||
vdb.ticketsMtx.RLock()
|
||||
defer vdb.ticketsMtx.RUnlock()
|
||||
|
||||
@ -348,14 +367,14 @@ func (vdb *VspDatabase) GetUnconfirmedFees() ([]Ticket, error) {
|
||||
|
||||
// GetVotableTickets returns tickets with a confirmed fee tx and no outcome (ie.
|
||||
// not expired/voted/missed).
|
||||
func (vdb *VspDatabase) GetVotableTickets() ([]Ticket, error) {
|
||||
func (vdb *VspDatabase) GetVotableTickets() (TicketList, error) {
|
||||
return vdb.filterTickets(func(t *bolt.Bucket) bool {
|
||||
return FeeStatus(t.Get(feeTxStatusK)) == FeeConfirmed && TicketOutcome(t.Get(outcomeK)) == ""
|
||||
})
|
||||
}
|
||||
|
||||
// GetVotedTickets returns tickets with a confirmed fee tx and outcome == voted.
|
||||
func (vdb *VspDatabase) GetVotedTickets() ([]Ticket, error) {
|
||||
func (vdb *VspDatabase) GetVotedTickets() (TicketList, error) {
|
||||
return vdb.filterTickets(func(t *bolt.Bucket) bool {
|
||||
return FeeStatus(t.Get(feeTxStatusK)) == FeeConfirmed && TicketOutcome(t.Get(outcomeK)) == Voted
|
||||
})
|
||||
@ -363,7 +382,7 @@ func (vdb *VspDatabase) GetVotedTickets() ([]Ticket, error) {
|
||||
|
||||
// GetMissingPurchaseHeight returns tickets which are confirmed but do not have
|
||||
// a purchase height.
|
||||
func (vdb *VspDatabase) GetMissingPurchaseHeight() ([]Ticket, error) {
|
||||
func (vdb *VspDatabase) GetMissingPurchaseHeight() (TicketList, error) {
|
||||
return vdb.filterTickets(func(t *bolt.Bucket) bool {
|
||||
return bytesToBool(t.Get(confirmedK)) && bytesToInt64(t.Get(purchaseHeightK)) == 0
|
||||
})
|
||||
@ -373,8 +392,8 @@ func (vdb *VspDatabase) GetMissingPurchaseHeight() ([]Ticket, error) {
|
||||
// database which match the filter.
|
||||
//
|
||||
// This function must be called with the lock held.
|
||||
func (vdb *VspDatabase) filterTickets(filter func(*bolt.Bucket) bool) ([]Ticket, error) {
|
||||
var tickets []Ticket
|
||||
func (vdb *VspDatabase) filterTickets(filter func(*bolt.Bucket) bool) (TicketList, error) {
|
||||
var tickets TicketList
|
||||
err := vdb.db.View(func(tx *bolt.Tx) error {
|
||||
ticketBkt := tx.Bucket(vspBktK).Bucket(ticketBktK)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user