// scanAddressRange scans backwards from end to start many addresses in the // account branch, and return the first index that is found on the blockchain. // If the address doesn't exist, false is returned as the first argument. func (w *Wallet) scanAddressRange(account uint32, branch uint32, start int, end int, chainClient *chain.RPCClient) (bool, int, error) { var addresses []dcrutil.Address err := walletdb.View(w.db, func(tx walletdb.ReadTx) error { addrmgrNs := tx.ReadBucket(waddrmgrNamespaceKey) var err error addresses, err = w.Manager.AddressesDerivedFromDbAcct(addrmgrNs, uint32(start), uint32(end+1), account, branch) if err != nil { return errDerivation } return nil }) if err != nil { return false, 0, err } // Whether or not the addresses exist is encoded as a binary // bitset. exists, err := chainClient.ExistsAddresses(addresses) if err != nil { return false, 0, err } existsB, err := hex.DecodeString(exists) if err != nil { return false, 0, err } set := bitset.Bytes(existsB) // Prevent a panic when an empty message is passed as a response. if len(set) == 0 { return false, 0, nil } // Scan backwards and return if we find an address exists. idx := end itr := len(addresses) - 1 for idx >= start { // If the address exists in the mempool or blockchain according // to the bit set returned, return this index. if set.Get(itr) { return true, idx, nil } itr-- idx-- } return false, 0, nil }