diff --git a/ud/addFact.go b/ud/addFact.go index ae52b1f197b586f49ac75c2f39656c435ced63c8..a20626303b0baebe980bfe02777ad2ecebf9af76 100644 --- a/ud/addFact.go +++ b/ud/addFact.go @@ -9,6 +9,7 @@ import ( "gitlab.com/elixxir/primitives/fact" "gitlab.com/xx_network/comms/connect" "gitlab.com/xx_network/crypto/signature/rsa" + "gitlab.com/xx_network/primitives/id" ) type addFactComms interface { @@ -16,10 +17,11 @@ type addFactComms interface { } func (m *Manager) SendRegisterFact(fact fact.Fact) (*pb.FactRegisterResponse, error) { - return m.addFact(fact, m.comms) + uid := m.storage.User().GetCryptographicIdentity().GetUserID() + return m.addFact(fact, uid, m.comms) } -func (m *Manager) addFact(inFact fact.Fact, aFC addFactComms) (*pb.FactRegisterResponse, error) { +func (m *Manager) addFact(inFact fact.Fact, uid *id.ID, aFC addFactComms) (*pb.FactRegisterResponse, error) { if !m.IsRegistered() { return nil, errors.New("Failed to add fact: " + "client is not registered") @@ -40,8 +42,6 @@ func (m *Manager) addFact(inFact fact.Fact, aFC addFactComms) (*pb.FactRegisterR return &pb.FactRegisterResponse{}, err } - uid := m.storage.User().GetCryptographicIdentity().GetUserID() - // Create our Fact Removal Request message data remFactMsg := pb.FactRegisterRequest{ UID: uid.Marshal(), diff --git a/ud/addFact_test.go b/ud/addFact_test.go index 16392f29820666effc76037fa19ce94f61c916ba..3e1ce5ad31464a042d70a1de251d8b8668a3e8fa 100644 --- a/ud/addFact_test.go +++ b/ud/addFact_test.go @@ -53,9 +53,9 @@ func TestAddFact(t *testing.T) { // This way we don't need to run UDB just to check that this // function works. tafc := testAFC{} - + uid := &id.ID{} // Run addFact and see if it returns without an error! - _, err = m.addFact(f, &tafc) + _, err = m.addFact(f, uid, &tafc) if err != nil { t.Fatal(err) } diff --git a/ud/lookup.go b/ud/lookup.go index 7733a15237bda55bf713700af19633343b774e21..5b5eeff81844ae3db871a102e60739dbffa695fc 100644 --- a/ud/lookup.go +++ b/ud/lookup.go @@ -1,6 +1,7 @@ package ud import ( + "fmt" "github.com/golang/protobuf/proto" "github.com/pkg/errors" jww "github.com/spf13/jwalterweatherman" @@ -22,7 +23,6 @@ func (m *Manager) lookupProcess(c chan message.Receive, quitCh <-chan struct{}) return case response := <-c: - // Unmarshal the message lookupResponse := &LookupResponse{} if err := proto.Unmarshal(response.Payload, lookupResponse); err != nil { @@ -101,7 +101,8 @@ func (m *Manager) Lookup(uid *id.ID, callback lookupCallback, timeout time.Durat // Subtract a millisecond to ensure this timeout will trigger before the // one below m.net.GetInstance().GetRoundEvents().AddRoundEventChan(round, - roundFailChan, timeout-1*time.Millisecond, states.FAILED) + roundFailChan, timeout-1*time.Millisecond, states.FAILED, + states.COMPLETED) } // Start the go routine which will trigger the callback @@ -111,30 +112,44 @@ func (m *Manager) Lookup(uid *id.ID, callback lookupCallback, timeout time.Durat var err error var c contact.Contact - select { - // Return an error if the round fails - case <-roundFailChan: - err = errors.New("One or more rounds failed to resolve; " + - "lookup not delivered") - - // Return an error if the timeout is reached - case <-timer.C: - err = errors.New("Response from User Discovery did not come " + - "before timeout") - - // Return the contact if one is returned - case response := <-responseChan: - if response.Error != "" { - err = errors.Errorf("User Discovery returned an error on "+ - "lookup: %s", response.Error) - } else { - pubkey := m.grp.NewIntFromBytes(response.PubKey) - c = contact.Contact{ - ID: uid, - DhPubKey: pubkey, - OwnershipProof: nil, - Facts: nil, + done := false + for !done { + select { + // Return an error if the round fails + case fail := <-roundFailChan: + if states.Round(fail.RoundInfo.State)==states.FAILED{ + fType := "" + if fail.TimedOut{ + fType = "timeout" + }else{ + fType = fmt.Sprintf("round failure: %v", fail.RoundInfo.ID) + } + err = errors.Errorf("One or more rounds (%v) failed to " + + "resolve due to: %s; search not delivered", rounds, fType) + done = true + } + + // Return an error if the timeout is reached + case <-timer.C: + err = errors.New("Response from User Discovery did not come " + + "before timeout") + done = true + + // Return the contact if one is returned + case response := <-responseChan: + if response.Error != "" { + err = errors.Errorf("User Discovery returned an error on "+ + "lookup: %s", response.Error) + } else { + pubkey := m.grp.NewIntFromBytes(response.PubKey) + c = contact.Contact{ + ID: uid, + DhPubKey: pubkey, + OwnershipProof: nil, + Facts: nil, + } } + done = true } } diff --git a/ud/search.go b/ud/search.go index 7dfcc34e028d5ebd535eea172a70db6ce2dccfcd..2933ca983323e124603a3d0ce580a2f53e349c26 100644 --- a/ud/search.go +++ b/ud/search.go @@ -104,7 +104,8 @@ func (m *Manager) Search(list fact.FactList, callback searchCallback, timeout ti // Subtract a millisecond to ensure this timeout will trigger before the // one below m.net.GetInstance().GetRoundEvents().AddRoundEventChan(round, - roundFailChan, timeout-1*time.Millisecond, states.FAILED) + roundFailChan, timeout-1*time.Millisecond, states.FAILED, + states.COMPLETED) } // Start the go routine which will trigger the callback @@ -114,33 +115,42 @@ func (m *Manager) Search(list fact.FactList, callback searchCallback, timeout ti var err error var c []contact.Contact - select { - // Return an error if the round fails - case fail := <-roundFailChan: - fType := "" - if fail.TimedOut{ - fType = "timeout" - }else{ - fType = fmt.Sprintf("round failure: %v", fail.RoundInfo.ID) - } - err = errors.Errorf("One or more rounds (%v) failed to " + - "resolve due to: %s; search not delivered", rounds, fType) - - // Return an error if the timeout is reached - case <-timer.C: - err = errors.New("Response from User Discovery did not come " + - "before timeout") - - // Return the contacts if one is returned - case response := <-responseChan: - if response.Error != "" { - err = errors.Errorf("User Discovery returned an error on "+ - "search: %s", response.Error) - } else { - c, err = m.parseContacts(response.Contacts, factMap) + done := false + for !done{ + select { + // Return an error if the round fails + case fail := <-roundFailChan: + if states.Round(fail.RoundInfo.State)==states.FAILED{ + fType := "" + if fail.TimedOut{ + fType = "timeout" + }else{ + fType = fmt.Sprintf("round failure: %v", fail.RoundInfo.ID) + } + err = errors.Errorf("One or more rounds (%v) failed to " + + "resolve due to: %s; search not delivered", rounds, fType) + done = true + } + + // Return an error if the timeout is reached + case <-timer.C: + err = errors.New("Response from User Discovery did not come " + + "before timeout") + done = true + + // Return the contacts if one is returned + case response := <-responseChan: + if response.Error != "" { + err = errors.Errorf("User Discovery returned an error on "+ + "search: %s", response.Error) + } else { + c, err = m.parseContacts(response.Contacts, factMap) + } + done = true } } + // Delete the response channel from the map m.inProgressSearchMux.Lock() delete(m.inProgressSearch, commID)