Select Git revision
search.go 4.46 KiB
package ud
import (
"fmt"
"github.com/golang/protobuf/proto"
"github.com/pkg/errors"
jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/crypto/contact"
"gitlab.com/elixxir/crypto/factID"
"gitlab.com/elixxir/primitives/fact"
"gitlab.com/xx_network/primitives/id"
"time"
)
// SearchTag specifies which callback to trigger when UD receives a search
// request.
const SearchTag = "xxNetwork_UdSearch"
// TODO: reconsider where this comes from
const maxSearchMessages = 20
type searchCallback func([]contact.Contact, error)
// Search searches for the passed Facts. The searchCallback will return a list
// of contacts, each having the facts it hit against. This is NOT intended to be
// used to search for multiple users at once; that can have a privacy reduction.
// Instead, it is intended to be used to search for a user where multiple pieces
// of information is known.
func (m *Manager) Search(list fact.FactList, callback searchCallback, timeout time.Duration) error {
jww.INFO.Printf("ud.Search(%s, %s)", list.Stringify(), timeout)
factHashes, factMap := hashFactList(list)
// Build the request and marshal it
request := &SearchSend{Fact: factHashes}
requestMarshaled, err := proto.Marshal(request)
if err != nil {
return errors.WithMessage(err, "Failed to form outgoing search request.")
}
f := func(payload []byte, err error) {
m.searchResponseHandler(factMap, callback, payload, err)
}
// Get UD contact
c, err := m.getContact()
if err != nil {
return err
}
err = m.single.TransmitSingleUse(c, requestMarshaled, SearchTag,
maxSearchMessages, f, timeout)
if err != nil {
return errors.WithMessage(err, "Failed to transmit search request.")
}
if m.client != nil {
m.client.ReportEvent(1, "UserDiscovery", "SearchRequest",
fmt.Sprintf("Sent: %+v", request))
}
return nil
}
func (m *Manager) searchResponseHandler(factMap map[string]fact.Fact,
callback searchCallback, payload []byte, err error) {
if err != nil {
go callback(nil, errors.WithMessage(err, "Failed to search."))
return