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
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// 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.
|
// Find the oldest block height from confirmed tickets.
|
||||||
oldestHeight := findOldestHeight(votableTickets)
|
oldestHeight := votableTickets.EarliestPurchaseHeight()
|
||||||
|
|
||||||
ticketInfo, err := walletClient.TicketInfo(oldestHeight)
|
ticketInfo, err := walletClient.TicketInfo(oldestHeight)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -319,7 +319,7 @@ func checkWalletConsistency(dcrdRPC rpc.DcrdConnect, walletRPC rpc.WalletConnect
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find the oldest block height from confirmed tickets.
|
// Find the oldest block height from confirmed tickets.
|
||||||
oldestHeight := findOldestHeight(votableTickets)
|
oldestHeight := votableTickets.EarliestPurchaseHeight()
|
||||||
|
|
||||||
// Iterate over each wallet and add any missing tickets.
|
// Iterate over each wallet and add any missing tickets.
|
||||||
for _, walletClient := range walletClients {
|
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
|
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 {
|
func (t *Ticket) FeeExpired() bool {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
return now.After(time.Unix(t.FeeExpiration, 0))
|
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.
|
// GetUnconfirmedTickets returns tickets which are not yet confirmed.
|
||||||
func (vdb *VspDatabase) GetUnconfirmedTickets() ([]Ticket, error) {
|
func (vdb *VspDatabase) GetUnconfirmedTickets() (TicketList, error) {
|
||||||
vdb.ticketsMtx.RLock()
|
vdb.ticketsMtx.RLock()
|
||||||
defer vdb.ticketsMtx.RUnlock()
|
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
|
// GetPendingFees returns tickets which are confirmed and have a fee tx which is
|
||||||
// not yet broadcast.
|
// not yet broadcast.
|
||||||
func (vdb *VspDatabase) GetPendingFees() ([]Ticket, error) {
|
func (vdb *VspDatabase) GetPendingFees() (TicketList, error) {
|
||||||
vdb.ticketsMtx.RLock()
|
vdb.ticketsMtx.RLock()
|
||||||
defer vdb.ticketsMtx.RUnlock()
|
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
|
// GetUnconfirmedFees returns tickets with a fee tx that is broadcast but not
|
||||||
// confirmed yet.
|
// confirmed yet.
|
||||||
func (vdb *VspDatabase) GetUnconfirmedFees() ([]Ticket, error) {
|
func (vdb *VspDatabase) GetUnconfirmedFees() (TicketList, error) {
|
||||||
vdb.ticketsMtx.RLock()
|
vdb.ticketsMtx.RLock()
|
||||||
defer vdb.ticketsMtx.RUnlock()
|
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.
|
// GetVotableTickets returns tickets with a confirmed fee tx and no outcome (ie.
|
||||||
// not expired/voted/missed).
|
// 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 vdb.filterTickets(func(t *bolt.Bucket) bool {
|
||||||
return FeeStatus(t.Get(feeTxStatusK)) == FeeConfirmed && TicketOutcome(t.Get(outcomeK)) == ""
|
return FeeStatus(t.Get(feeTxStatusK)) == FeeConfirmed && TicketOutcome(t.Get(outcomeK)) == ""
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetVotedTickets returns tickets with a confirmed fee tx and outcome == voted.
|
// 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 vdb.filterTickets(func(t *bolt.Bucket) bool {
|
||||||
return FeeStatus(t.Get(feeTxStatusK)) == FeeConfirmed && TicketOutcome(t.Get(outcomeK)) == Voted
|
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
|
// GetMissingPurchaseHeight returns tickets which are confirmed but do not have
|
||||||
// a purchase height.
|
// a purchase height.
|
||||||
func (vdb *VspDatabase) GetMissingPurchaseHeight() ([]Ticket, error) {
|
func (vdb *VspDatabase) GetMissingPurchaseHeight() (TicketList, error) {
|
||||||
return vdb.filterTickets(func(t *bolt.Bucket) bool {
|
return vdb.filterTickets(func(t *bolt.Bucket) bool {
|
||||||
return bytesToBool(t.Get(confirmedK)) && bytesToInt64(t.Get(purchaseHeightK)) == 0
|
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.
|
// database which match the filter.
|
||||||
//
|
//
|
||||||
// This function must be called with the lock held.
|
// This function must be called with the lock held.
|
||||||
func (vdb *VspDatabase) filterTickets(filter func(*bolt.Bucket) bool) ([]Ticket, error) {
|
func (vdb *VspDatabase) filterTickets(filter func(*bolt.Bucket) bool) (TicketList, error) {
|
||||||
var tickets []Ticket
|
var tickets TicketList
|
||||||
err := vdb.db.View(func(tx *bolt.Tx) error {
|
err := vdb.db.View(func(tx *bolt.Tx) error {
|
||||||
ticketBkt := tx.Bucket(vspBktK).Bucket(ticketBktK)
|
ticketBkt := tx.Bucket(vspBktK).Bucket(ticketBktK)
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user