diff --git a/api/client.go b/api/client.go index 4ae049f7232a4eb679945826b37be534279d67ef..2c83ad2af5a5bd43f43b76ebf84e0eedccae57aa 100644 --- a/api/client.go +++ b/api/client.go @@ -485,6 +485,26 @@ func (c *Client) GetNetworkInterface() interfaces.NetworkManager { return c.network } +// GetNodeRegistrationStatus gets the current status of node registration. It +// returns the number of nodes that the client is registered and the number of +// in progress node registrations. An error is returned if the network is not +// healthy. +func (c *Client) GetNodeRegistrationStatus() (int, int, error) { + // Return an error if the network is not healthy + if !c.GetHealth().IsHealthy() { + return 0, 0, errors.New("Cannot get number of node registrations when " + + "network is not healthy") + } + + // Get the number of nodes that client is registered with + registeredNodes := c.storage.Cmix().Count() + + // Get the number of in progress node registrations + inProgress := c.network.InProgressRegistrations() + + return registeredNodes, inProgress, nil +} + // ----- Utility Functions ----- // parseNDF parses the initial ndf string for the client. do not check the // signature, it is deprecated. diff --git a/api/utilsInterfaces_test.go b/api/utilsInterfaces_test.go index 6eb4c466a51845e756f275483271a785b643feaa..95ba3b1e62115fa45f2f67aabf542aab2f29bf83 100644 --- a/api/utilsInterfaces_test.go +++ b/api/utilsInterfaces_test.go @@ -115,3 +115,7 @@ func (t *testNetworkManagerGeneric) GetRemoteVersion() (string, error) { func (t *testNetworkManagerGeneric) GetStoppable() stoppable.Stoppable { return &stoppable.Multi{} } + +func (t *testNetworkManagerGeneric) InProgressRegistrations() int { + return 0 +} diff --git a/bindings/client.go b/bindings/client.go index 431c860834a81d33950887726f33ff1be07631bc..8cd54bf7a6b9f068313517f9fcaca81618193313 100644 --- a/bindings/client.go +++ b/bindings/client.go @@ -338,6 +338,14 @@ func (c *Client) GetUser() *User { return &User{u: &u} } +// GetNodeRegistrationStatus returns a struct with the number of nodes the +// client is registered with and the number of in progress registrations. +func (c *Client) GetNodeRegistrationStatus() (*NodeRegistrationsStatus, error) { + registered, inProgress, err := c.api.GetNodeRegistrationStatus() + + return &NodeRegistrationsStatus{registered, inProgress}, err +} + /* // SearchWithHandler is a non-blocking search that also registers // a callback interface for user disovery events. diff --git a/bindings/registrationStatus.go b/bindings/registrationStatus.go new file mode 100644 index 0000000000000000000000000000000000000000..22446376436a0a8145c97e20e868073e1984d0a0 --- /dev/null +++ b/bindings/registrationStatus.go @@ -0,0 +1,25 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright © 2020 xx network SEZC // +// // +// Use of this source code is governed by a license that can be found in the // +// LICENSE file // +/////////////////////////////////////////////////////////////////////////////// + +package bindings + +// NodeRegistrationsStatus structure for returning node registration statuses +// for bindings. +type NodeRegistrationsStatus struct { + registered int + inProgress int +} + +// GetRegistered returns the number of nodes registered with the client. +func (nrs *NodeRegistrationsStatus) GetRegistered() int { + return nrs.registered +} + +// GetInProgress return the number of nodes currently registering. +func (nrs *NodeRegistrationsStatus) GetInProgress() int { + return nrs.inProgress +} diff --git a/interfaces/networkManager.go b/interfaces/networkManager.go index b7ff3a886346a0d23934b6ef359db4e872101415..9e652e536a9973512e0ba803c7980a70ff03f9cd 100644 --- a/interfaces/networkManager.go +++ b/interfaces/networkManager.go @@ -26,6 +26,7 @@ type NetworkManager interface { GetHealthTracker() HealthTracker Follow() (stoppable.Stoppable, error) CheckGarbledMessages() + InProgressRegistrations() int } //for use in key exchange which needs to be callable inside of network diff --git a/keyExchange/utils_test.go b/keyExchange/utils_test.go index bda05f0b822888261f8f61f460840536dd9ddbc5..1b61b84c122b438839198722dd661f647b24438c 100644 --- a/keyExchange/utils_test.go +++ b/keyExchange/utils_test.go @@ -99,6 +99,10 @@ func (t *testNetworkManagerGeneric) GetStoppable() stoppable.Stoppable { return &stoppable.Multi{} } +func (t *testNetworkManagerGeneric) InProgressRegistrations() int { + return 0 +} + func InitTestingContextGeneric(i interface{}) (*storage.Session, interfaces.NetworkManager) { switch i.(type) { case *testing.T, *testing.M, *testing.B, *testing.PB: @@ -202,6 +206,10 @@ func (t *testNetworkManagerFullExchange) GetStoppable() stoppable.Stoppable { return &stoppable.Multi{} } +func (t *testNetworkManagerFullExchange) InProgressRegistrations() int { + return 0 +} + func InitTestingContextFullExchange(i interface{}) (*storage.Session, *switchboard.Switchboard, interfaces.NetworkManager) { switch i.(type) { case *testing.T, *testing.M, *testing.B, *testing.PB: diff --git a/network/ephemeral/testutil.go b/network/ephemeral/testutil.go index 1691ae8bd450fd70cd03e0f8f8c00733c16ec828..18d82e6fc9d07c26ba4cdc559016c32017638c0a 100644 --- a/network/ephemeral/testutil.go +++ b/network/ephemeral/testutil.go @@ -74,6 +74,10 @@ func (t *testNetworkManager) Follow() (stoppable.Stoppable, error) { func (t *testNetworkManager) CheckGarbledMessages() {} +func (t *testNetworkManager) InProgressRegistrations() int { + return 0 +} + func NewTestNetworkManager(i interface{}) interfaces.NetworkManager { switch i.(type) { case *testing.T, *testing.M, *testing.B: diff --git a/network/manager.go b/network/manager.go index 7df9c58d93d0b7eacc8c19185807c4cf6a3c85b2..c37089497e16affd29d14c7d2ca56e2f29a8e4c3 100644 --- a/network/manager.go +++ b/network/manager.go @@ -167,3 +167,8 @@ func (m *manager) GetInstance() *network.Instance { func (m *manager) CheckGarbledMessages() { m.message.CheckGarbledMessages() } + +// InProgressRegistrations returns the number of in progress node registrations. +func (m *manager) InProgressRegistrations() int { + return len(m.Internal.NodeRegistration) + 1 +} diff --git a/single/manager_test.go b/single/manager_test.go index 33427010d53d967a2a2dd52fb1971b661974e2d9..b8dc30e6d1fd2fd674263f29745760e4761f0df5 100644 --- a/single/manager_test.go +++ b/single/manager_test.go @@ -318,6 +318,10 @@ func (tnm *testNetworkManager) Follow() (stoppable.Stoppable, error) { func (tnm *testNetworkManager) CheckGarbledMessages() {} +func (tnm *testNetworkManager) InProgressRegistrations() int { + return 0 +} + func getNDF() *ndf.NetworkDefinition { return &ndf.NetworkDefinition{ E2E: ndf.Group{ diff --git a/storage/cmix/store.go b/storage/cmix/store.go index cc03ebcf37ee3f795fc36037327de1cc038cb74e..47e1503a6edc71f7312bd8e75b5fffac9896ea26 100644 --- a/storage/cmix/store.go +++ b/storage/cmix/store.go @@ -185,6 +185,13 @@ func (s *Store) IsRegistered(nid *id.ID) bool { return ok } +// Count returns the number of registered nodes. +func (s *Store) Count() int { + s.mux.RLock() + defer s.mux.RUnlock() + return len(s.nodes) +} + // save stores the cMix store. func (s *Store) save() error { now := time.Now() diff --git a/storage/cmix/store_test.go b/storage/cmix/store_test.go index 92d8754db617c36194dba6c00338adf50cf47131..8e05e0c39438f1b22b63ea6ff1d3f3b3648b2b73 100644 --- a/storage/cmix/store_test.go +++ b/storage/cmix/store_test.go @@ -160,7 +160,33 @@ func TestStore_GetRoundKeys_Missing(t *testing.T) { } } -// Main testing function +// Happy path. +func TestStore_Count(t *testing.T) { + vkv := versioned.NewKV(make(ekv.Memstore)) + grp := cyclic.NewGroup(large.NewInt(173), large.NewInt(2)) + + store, err := NewStore(grp, vkv, grp.NewInt(2)) + if err != nil { + t.Fatalf("Failed to generate new Store: %+v", err) + } + + if store.Count() != 0 { + t.Errorf("Count() did not return the expected value for a new Store."+ + "\nexpected: %d\nreceived: %d", 0, store.Count()) + } + + count := 50 + for i := 0; i < count; i++ { + store.Add(id.NewIdFromUInt(uint64(i), id.Node, t), grp.NewInt(int64(42+i))) + } + + if store.Count() != count { + t.Errorf("Count() did not return the expected value."+ + "\nexpected: %d\nreceived: %d", count, store.Count()) + } +} + +// Main testing function. func makeTestStore() (*Store, *versioned.KV) { kv := make(ekv.Memstore)