// TicketsWithAddress returns a slice of ticket hashes that are currently live // corresponding to the given address. // // This function is safe for concurrent access. func (b *BlockChain) TicketsWithAddress(address dcrutil.Address) ([]chainhash.Hash, error) { b.chainLock.RLock() sn := b.bestNode.stakeNode b.chainLock.RUnlock() tickets := sn.LiveTickets() var ticketsWithAddr []chainhash.Hash err := b.db.View(func(dbTx database.Tx) error { var err error for _, hash := range tickets { utxo, err := dbFetchUtxoEntry(dbTx, &hash) if err != nil { return err } _, addrs, _, err := txscript.ExtractPkScriptAddrs(txscript.DefaultScriptVersion, utxo.PkScriptByIndex(0), b.chainParams) if addrs[0].EncodeAddress() == address.EncodeAddress() { ticketsWithAddr = append(ticketsWithAddr, hash) } } return err }) if err != nil { return nil, err } return ticketsWithAddr, nil }
// SearchRawTransactionsAsync returns an instance of a type that can be used to // get the result of the RPC at some future time by invoking the Receive // function on the returned instance. // // See SearchRawTransactions for the blocking version and more details. func (c *Client) SearchRawTransactionsAsync(address dcrutil.Address, skip, count int, reverse bool, filterAddrs []string) FutureSearchRawTransactionsResult { addr := address.EncodeAddress() verbose := dcrjson.Int(0) cmd := dcrjson.NewSearchRawTransactionsCmd(addr, verbose, &skip, &count, nil, &reverse, &filterAddrs) return c.sendCmd(cmd) }
// stakePoolUserInfo returns the stake pool user information for a given stake // pool user, keyed to their P2SH voting address. func (s *StakeStore) stakePoolUserInfo(ns walletdb.ReadBucket, user dcrutil.Address) (*StakePoolUser, error) { _, isScriptHash := user.(*dcrutil.AddressScriptHash) _, isP2PKH := user.(*dcrutil.AddressPubKeyHash) if !(isScriptHash || isP2PKH) { str := fmt.Sprintf("user %v is invalid", user.EncodeAddress()) return nil, stakeStoreError(ErrBadPoolUserAddr, str, nil) } scriptHashB := user.ScriptAddress() scriptHash := new([20]byte) copy(scriptHash[:], scriptHashB) stakePoolUser := new(StakePoolUser) // Catch missing user errors below and blank out the stake // pool user information for the section if the user has // no entries. missingValidTickets, missingInvalidTickets := false, false userTickets, fetchErrVal := fetchStakePoolUserTickets(ns, *scriptHash) if fetchErrVal != nil { stakeMgrErr, is := fetchErrVal.(StakeStoreError) if is { missingValidTickets = stakeMgrErr.ErrorCode == ErrPoolUserTicketsNotFound } else { return nil, fetchErrVal } } if missingValidTickets { userTickets = make([]*PoolTicket, 0) } invalTickets, fetchErrInval := fetchStakePoolUserInvalTickets(ns, *scriptHash) if fetchErrInval != nil { stakeMgrErr, is := fetchErrInval.(StakeStoreError) if is { missingInvalidTickets = stakeMgrErr.ErrorCode == ErrPoolUserInvalTcktsNotFound } else { return nil, fetchErrInval } } if missingInvalidTickets { invalTickets = make([]*chainhash.Hash, 0) } stakePoolUser.Tickets = userTickets stakePoolUser.InvalidTickets = invalTickets return stakePoolUser, nil }
// updateStakePoolUserInvalTickets updates the list of invalid stake pool // tickets for a given user. If the ticket does not currently exist in the // database, it adds it. func (s *StakeStore) updateStakePoolUserInvalTickets(ns walletdb.ReadWriteBucket, user dcrutil.Address, ticket *chainhash.Hash) error { _, isScriptHash := user.(*dcrutil.AddressScriptHash) _, isP2PKH := user.(*dcrutil.AddressPubKeyHash) if !(isScriptHash || isP2PKH) { str := fmt.Sprintf("user %v is invalid", user.EncodeAddress()) return stakeStoreError(ErrBadPoolUserAddr, str, nil) } scriptHashB := user.ScriptAddress() scriptHash := new([20]byte) copy(scriptHash[:], scriptHashB) return updateStakePoolInvalUserTickets(ns, *scriptHash, ticket) }
// SearchRawTransactionsVerboseAsync returns an instance of a type that can be // used to get the result of the RPC at some future time by invoking the Receive // function on the returned instance. // // See SearchRawTransactionsVerbose for the blocking version and more details. func (c *Client) SearchRawTransactionsVerboseAsync(address dcrutil.Address, skip, count int, includePrevOut bool, reverse bool, filterAddrs *[]string) FutureSearchRawTransactionsVerboseResult { addr := address.EncodeAddress() verbose := dcrjson.Int(1) var prevOut *int if includePrevOut { prevOut = dcrjson.Int(1) } cmd := dcrjson.NewSearchRawTransactionsCmd(addr, verbose, &skip, &count, prevOut, &reverse, filterAddrs) return c.sendCmd(cmd) }
func (s *walletServer) NextAddress(ctx context.Context, req *pb.NextAddressRequest) ( *pb.NextAddressResponse, error) { var ( addr dcrutil.Address err error ) switch req.Kind { case pb.NextAddressRequest_BIP0044_EXTERNAL: addr, err = s.wallet.NewAddress(req.Account, waddrmgr.ExternalBranch) if err != nil { return nil, translateError(err) } case pb.NextAddressRequest_BIP0044_INTERNAL: addr, err = s.wallet.NewAddress(req.Account, waddrmgr.InternalBranch) if err != nil { return nil, translateError(err) } default: return nil, grpc.Errorf(codes.InvalidArgument, "kind=%v", req.Kind) } if err != nil { return nil, translateError(err) } pubKey, err := s.wallet.PubKeyForAddress(addr) if err != nil { return nil, translateError(err) } pubKeyAddr, err := dcrutil.NewAddressSecpPubKey(pubKey.Serialize(), s.wallet.ChainParams()) if err != nil { return nil, translateError(err) } return &pb.NextAddressResponse{ Address: addr.EncodeAddress(), PublicKey: pubKeyAddr.String(), }, nil }
// SearchRawTransactionsVerboseAsync returns an instance of a type that can be // used to get the result of the RPC at some future time by invoking the Receive // function on the returned instance. // // See SearchRawTransactionsVerbose for the blocking version and more details. func (c *Client) SearchRawTransactionsVerboseAsync(address dcrutil.Address, skip, count int) FutureSearchRawTransactionsVerboseResult { addr := address.EncodeAddress() verbose := dcrjson.Int(1) cmd := dcrjson.NewSearchRawTransactionsCmd(addr, verbose, &skip, &count) return c.sendCmd(cmd) }
// ExistsAddressAsync returns an instance of a type that can be used to get the // result of the RPC at some future time by invoking the Receive function on the // returned instance. func (c *Client) ExistsAddressAsync(address dcrutil.Address) FutureExistsAddressResult { cmd := dcrjson.NewExistsAddressCmd(address.EncodeAddress()) return c.sendCmd(cmd) }