// LiveTicketHashes returns the hashes of live tickets that have been purchased // by the wallet. func (w *Wallet) LiveTicketHashes(rpcClient *chain.RPCClient, includeImmature bool) ([]chainhash.Hash, error) { // This was mostly copied from an older version of the legacy RPC server // implementation, hence the overall weirdness, inefficiencies, and the // direct dependency on the consensus server RPC client. var blk waddrmgr.BlockStamp var ticketHashes []chainhash.Hash var stakeMgrTickets []chainhash.Hash err := walletdb.View(w.db, func(tx walletdb.ReadTx) error { txmgrNs := tx.ReadBucket(wtxmgrNamespaceKey) blk = w.Manager.SyncedTo() // UnspentTickets collects all the tickets that pay out to a // public key hash for a public key owned by this wallet. var err error ticketHashes, err = w.TxStore.UnspentTickets(txmgrNs, blk.Height, includeImmature) if err != nil { return err } // Access the stake manager and see if there are any extra tickets // there. Likely they were either pruned because they failed to get // into the blockchain or they are P2SH for some script we own. stakeMgrTickets, err = w.StakeMgr.DumpSStxHashes() return err }) if err != nil { return nil, err } for _, h := range stakeMgrTickets { if sliceContainsHash(ticketHashes, h) { continue } // Get the raw transaction information from daemon and add // any relevant tickets. The ticket output is always the // zeroeth output. spent, err := rpcClient.GetTxOut(&h, 0, true) if err != nil { continue } // This returns nil if the output is spent. if spent == nil { continue } ticketTx, err := rpcClient.GetRawTransactionVerbose(&h) if err != nil { continue } txHeight := ticketTx.BlockHeight unconfirmed := (txHeight == 0) immature := (blk.Height-int32(txHeight) < int32(w.ChainParams().TicketMaturity)) if includeImmature { ticketHashes = append(ticketHashes, h) } else { if !(unconfirmed || immature) { ticketHashes = append(ticketHashes, h) } } } return ticketHashes, nil }