diff --git a/go.mod b/go.mod
index 5b2d27eab8195cbb24839d4614c6571d5aa883bd..20aa686ea726c7a04ebe1b861dd8f0171c3933b9 100644
--- a/go.mod
+++ b/go.mod
@@ -6,7 +6,7 @@ require (
 	github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3
 	github.com/golang/protobuf v1.4.3
 	github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 // indirect
-	github.com/liyue201/goqr v0.0.0-20200803022322-df443203d4ea // indirect
+	github.com/liyue201/goqr v0.0.0-20200803022322-df443203d4ea
 	github.com/magiconair/properties v1.8.4 // indirect
 	github.com/mitchellh/mapstructure v1.4.0 // indirect
 	github.com/pelletier/go-toml v1.8.1 // indirect
@@ -23,7 +23,7 @@ require (
 	gitlab.com/elixxir/crypto v0.0.7-0.20210319231554-b73b6e62ddbc
 	gitlab.com/elixxir/ekv v0.1.4
 	gitlab.com/elixxir/primitives v0.0.3-0.20210309193003-ef42ebb4800b
-	gitlab.com/xx_network/comms v0.0.4-0.20210323205910-f01316c830dd
+	gitlab.com/xx_network/comms v0.0.4-0.20210331153942-daf17c8b6b47
 	gitlab.com/xx_network/crypto v0.0.5-0.20210319231335-249c6b1aa323
 	gitlab.com/xx_network/primitives v0.0.4-0.20210309173740-eb8cd411334a
 	golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
diff --git a/go.sum b/go.sum
index b6e88d3cda43ab0ff4237f50ff7d3315075d9d9a..773bc4faf55be9478d3257fb88146c846b19c918 100644
--- a/go.sum
+++ b/go.sum
@@ -292,6 +292,12 @@ gitlab.com/xx_network/comms v0.0.4-0.20210323140408-2b2613abb5a3 h1:Mh+YiOX89vG9
 gitlab.com/xx_network/comms v0.0.4-0.20210323140408-2b2613abb5a3/go.mod h1:0Hx+zO3Pr4uYw4RZXFnPM3ocjY6bPIKDiHCjWTZLOSI=
 gitlab.com/xx_network/comms v0.0.4-0.20210323205910-f01316c830dd h1:WZn6y52gqigTXBAdsDRM3KWNBwnPEnYoGcBrsSAuphI=
 gitlab.com/xx_network/comms v0.0.4-0.20210323205910-f01316c830dd/go.mod h1:0Hx+zO3Pr4uYw4RZXFnPM3ocjY6bPIKDiHCjWTZLOSI=
+gitlab.com/xx_network/comms v0.0.4-0.20210329190058-55f9bdf16249 h1:dDcesEGcAzN1C6PP7Y8T0Ky5c4mpRfhVFMZJKBrbQzk=
+gitlab.com/xx_network/comms v0.0.4-0.20210329190058-55f9bdf16249/go.mod h1:0Hx+zO3Pr4uYw4RZXFnPM3ocjY6bPIKDiHCjWTZLOSI=
+gitlab.com/xx_network/comms v0.0.4-0.20210330224545-2d0e07fb64c6 h1:LsxlArrT5mIM5rRbMuNp+PQPWrCbPKhunHO2MfznbsE=
+gitlab.com/xx_network/comms v0.0.4-0.20210330224545-2d0e07fb64c6/go.mod h1:0Hx+zO3Pr4uYw4RZXFnPM3ocjY6bPIKDiHCjWTZLOSI=
+gitlab.com/xx_network/comms v0.0.4-0.20210331153942-daf17c8b6b47 h1:r8qBdMtuQouVylWl5RPctlXzPldcbhI2bvYkeUB1Ia0=
+gitlab.com/xx_network/comms v0.0.4-0.20210331153942-daf17c8b6b47/go.mod h1:0Hx+zO3Pr4uYw4RZXFnPM3ocjY6bPIKDiHCjWTZLOSI=
 gitlab.com/xx_network/crypto v0.0.3/go.mod h1:DF2HYvvCw9wkBybXcXAgQMzX+MiGbFPjwt3t17VRqRE=
 gitlab.com/xx_network/crypto v0.0.4 h1:lpKOL5mTJ2awWMfgBy30oD/UvJVrWZzUimSHlOdZZxo=
 gitlab.com/xx_network/crypto v0.0.4/go.mod h1:+lcQEy+Th4eswFgQDwT0EXKp4AXrlubxalwQFH5O0Mk=
diff --git a/network/follow.go b/network/follow.go
index 88857b59846ed601b33226d59bc690cbcddc7867..3c05519620d7dce05140d7958f779ab8940f6ade 100644
--- a/network/follow.go
+++ b/network/follow.go
@@ -189,8 +189,8 @@ func (m *manager) follow(report interfaces.ClientErrorReport, rng csprng.Source,
 					update.State = uint32(states.FAILED)
 					rnd, err := m.Instance.GetWrappedRound(id.Round(update.ID))
 					if err != nil {
-						jww.ERROR.Printf("Failed to report client error: " +
-							"Could not get round for event triggering: " +
+						jww.ERROR.Printf("Failed to report client error: "+
+							"Could not get round for event triggering: "+
 							"Unable to get round %d from instance: %+v",
 							id.Round(update.ID), err)
 						break
diff --git a/network/gateway/hostPool.go b/network/gateway/hostPool.go
index 3e520daba3ecd68e99af1eb8a84f0807ff73f99d..e8ab9f17102eaca390a2e013fe31f7495cdc8e54 100644
--- a/network/gateway/hostPool.go
+++ b/network/gateway/hostPool.go
@@ -115,7 +115,6 @@ func (h *HostPool) GetAny(length int) []*connect.Host {
 		length = int(h.poolParams.poolSize)
 	}
 	result := make([]*connect.Host, length)
-
 	h.hostMux.RLock()
 	for i := 0; i < length; {
 		gwIdx := readRangeUint32(0, h.poolParams.poolSize, h.rng)
@@ -212,9 +211,8 @@ func (h *HostPool) pruneHostPool() error {
 
 	for poolIdx := uint32(0); poolIdx < h.poolParams.poolSize; {
 		host := h.hostList[poolIdx]
-
 		// Check the Host for errors
-		if host == nil || *host.GetMetrics().ErrCounter >= h.poolParams.errThreshold {
+		if host == nil || host.GetMetrics().GetErrorCounter() >= h.poolParams.errThreshold {
 
 			// If errors occurred, randomly select a new Gw by index in the NDF
 			ndfIdx := readRangeUint32(0, uint32(len(h.ndf.Gateways)), h.rng)
@@ -227,6 +225,7 @@ func (h *HostPool) pruneHostPool() error {
 
 			// Verify the GwId is not already in the hostMap
 			if _, ok := h.hostMap[*gwId]; !ok {
+
 				// If it is a new GwId, replace the old Host with the new Host
 				err = h.replaceHost(gwId, poolIdx)
 				if err != nil {
diff --git a/network/gateway/hostpool_test.go b/network/gateway/hostpool_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..83be2608fa2226140e2dbc1bb5453d1a7608c42d
--- /dev/null
+++ b/network/gateway/hostpool_test.go
@@ -0,0 +1,811 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright © 2020 xx network SEZC                                          //
+//                                                                           //
+// Use of this source code is governed by a license that can be found in the //
+// LICENSE file                                                              //
+///////////////////////////////////////////////////////////////////////////////
+
+package gateway
+
+import (
+	jww "github.com/spf13/jwalterweatherman"
+	"gitlab.com/elixxir/client/storage"
+	"gitlab.com/elixxir/comms/network"
+	"gitlab.com/xx_network/comms/connect"
+	"gitlab.com/xx_network/crypto/csprng"
+	"gitlab.com/xx_network/primitives/id"
+	"gitlab.com/xx_network/primitives/ndf"
+	"reflect"
+	"testing"
+	"time"
+)
+
+// Unit test
+func TestNewHostPool(t *testing.T) {
+	manager := newMockManager()
+	rng := csprng.NewSystemRNG()
+	testNdf := getTestNdf(t)
+	testStorage := storage.InitTestingSession(t)
+	addGwChan := make(chan network.NodeGateway)
+	params := DefaultPoolParams()
+	params.poolSize = uint32(len(testNdf.Gateways))
+
+	// Pull all gateways from ndf into host manager
+	for _, gw := range testNdf.Gateways {
+
+		gwId, err := id.Unmarshal(gw.ID)
+		if err != nil {
+			t.Errorf("Failed to unmarshal ID in mock ndf: %v", err)
+		}
+		// Add mock gateway to manager
+		_, err = manager.AddHost(gwId, "", nil, connect.GetDefaultHostParams())
+		if err != nil {
+			t.Errorf("Could not add mock host to manager: %v", err)
+			t.FailNow()
+		}
+
+	}
+
+	// Call the constructor
+	_, err := NewHostPool(params, rng, testNdf, manager,
+		testStorage, addGwChan)
+	if err != nil {
+		t.Errorf("Failed to create mock host pool: %v", err)
+	}
+}
+
+// Unit test
+func TestHostPool_ManageHostPool(t *testing.T) {
+	manager := newMockManager()
+	rng := csprng.NewSystemRNG()
+	testNdf := getTestNdf(t)
+	testStorage := storage.InitTestingSession(t)
+	addGwChan := make(chan network.NodeGateway)
+
+	// Construct custom params
+	params := DefaultPoolParams()
+	params.poolSize = uint32(len(testNdf.Gateways))
+	params.pruneInterval = 1 * time.Second
+
+	// Pull all gateways from ndf into host manager
+	for _, gw := range testNdf.Gateways {
+
+		gwId, err := id.Unmarshal(gw.ID)
+		if err != nil {
+			t.Errorf("Failed to unmarshal ID in mock ndf: %v", err)
+		}
+		// Add mock gateway to manager
+		_, err = manager.AddHost(gwId, gw.Address, nil, connect.GetDefaultHostParams())
+		if err != nil {
+			t.Errorf("Could not add mock host to manager: %v", err)
+			t.FailNow()
+		}
+
+	}
+
+	// Call the constructor
+	testPool, err := NewHostPool(params, rng, testNdf, manager,
+		testStorage, addGwChan)
+	if err != nil {
+		t.Errorf("Failed to create mock host pool: %v", err)
+	}
+
+	stopper := testPool.StartHostPool()
+	stopper.Close(3 * time.Second)
+
+	// Construct a list of new gateways/nodes to add to ndf
+	newGatewayLen := len(testNdf.Gateways)
+	newGateways := make([]ndf.Gateway, newGatewayLen)
+	newNodes := make([]ndf.Node, newGatewayLen)
+	for i := 0; i < newGatewayLen; i++ {
+		// Construct gateways
+		gwId := id.NewIdFromUInt(uint64(100+i), id.Gateway, t)
+		newGateways[i] = ndf.Gateway{ID: gwId.Bytes()}
+		// Construct nodes
+		nodeId := gwId.DeepCopy()
+		nodeId.SetType(id.Node)
+		newNodes[i] = ndf.Node{ID: nodeId.Bytes()}
+
+	}
+
+	newNdf := getTestNdf(t)
+	// Update the ndf, removing some gateways at a cutoff
+	newNdf.Gateways = newGateways
+	newNdf.Nodes = newNodes
+
+	testPool.UpdateNdf(newNdf)
+
+	time.Sleep(2 * time.Second)
+
+	// Check that old gateways are not in pool
+	for _, ndfGw := range testNdf.Gateways {
+		gwId, err := id.Unmarshal(ndfGw.ID)
+		if err != nil {
+			t.Errorf("Failed to marshal gateway id for %v", ndfGw)
+		}
+		if _, ok := testPool.hostMap[*gwId]; ok {
+			t.Errorf("Expected gateway %v to be removed from pool", gwId)
+		}
+	}
+}
+
+// Full happy path test
+func TestHostPool_ReplaceHost(t *testing.T) {
+	manager := newMockManager()
+	testNdf := getTestNdf(t)
+	newIndex := uint32(20)
+
+	// Construct a manager (bypass business logic in constructor)
+	hostPool := &HostPool{
+		manager:  manager,
+		hostList: make([]*connect.Host, newIndex+1),
+		hostMap:  make(map[id.ID]uint32),
+		ndf:      testNdf,
+	}
+
+	/* "Replace" a host with no entry */
+
+	// Pull a gateway ID from the ndf
+	gwIdOne, err := id.Unmarshal(testNdf.Gateways[0].ID)
+	if err != nil {
+		t.Errorf("Failed to unmarshal ID in mock ndf: %v", err)
+	}
+
+	// Add mock gateway to manager
+	_, err = manager.AddHost(gwIdOne, "", nil, connect.GetDefaultHostParams())
+	if err != nil {
+		t.Errorf("Could not add mock host to manager: %v", err)
+	}
+
+	// "Replace" (insert) the host
+	err = hostPool.replaceHost(gwIdOne, newIndex)
+	if err != nil {
+		t.Errorf("Could not replace host: %v", err)
+	}
+
+	// Check the state of the map has been correctly updated
+	retrievedIndex, ok := hostPool.hostMap[*gwIdOne]
+	if !ok {
+		t.Errorf("Expected insertion of gateway ID into map")
+	}
+	if retrievedIndex != newIndex {
+		t.Errorf("Index pulled from map not expected value."+
+			"\n\tExpected: %d"+
+			"\n\tReceived: %d", newIndex, retrievedIndex)
+	}
+
+	// Check that the state of the list list been correctly updated
+	retrievedHost := hostPool.hostList[newIndex]
+	if !gwIdOne.Cmp(retrievedHost.GetId()) {
+		t.Errorf("Id pulled from list is not expected."+
+			"\n\tExpected: %s"+
+			"\n\tReceived: %s", gwIdOne, retrievedHost.GetId())
+	}
+
+	/* Replace the initial host with a new host */
+
+	// Pull a different gateway ID from the ndf
+	gwIdTwo, err := id.Unmarshal(testNdf.Gateways[1].ID)
+	if err != nil {
+		t.Errorf("Failed to unmarshal ID in mock ndf: %v", err)
+	}
+
+	// Add second mock gateway to manager
+	_, err = manager.AddHost(gwIdTwo, "", nil, connect.GetDefaultHostParams())
+	if err != nil {
+		t.Errorf("Could not add mock host to manager: %v", err)
+	}
+
+	// Replace the old host
+	err = hostPool.replaceHost(gwIdTwo, newIndex)
+	if err != nil {
+		t.Errorf("Could not replace host: %v", err)
+	}
+
+	// Check that the state of the list been correctly updated for new host
+	retrievedHost = hostPool.hostList[newIndex]
+	if !gwIdTwo.Cmp(retrievedHost.GetId()) {
+		t.Errorf("Id pulled from list is not expected."+
+			"\n\tExpected: %s"+
+			"\n\tReceived: %s", gwIdTwo, retrievedHost.GetId())
+	}
+
+	// Check the state of the map has been correctly removed for the old gateway
+	retrievedOldIndex, ok := hostPool.hostMap[*gwIdOne]
+	if ok {
+		t.Errorf("Exoected old gateway to be cleared from map")
+	}
+	if retrievedOldIndex != 0 {
+		t.Errorf("Index pulled from map with old gateway as the key "+
+			"was not cleared."+
+			"\n\tExpected: %d"+
+			"\n\tReceived: %d", 0, retrievedOldIndex)
+	}
+
+	// Check the state of the map has been correctly updated for the old gateway
+	retrievedIndex, ok = hostPool.hostMap[*gwIdTwo]
+	if !ok {
+		t.Errorf("Expected insertion of gateway ID into map")
+	}
+	if retrievedIndex != newIndex {
+		t.Errorf("Index pulled from map using new gateway as the key "+
+			"was not updated."+
+			"\n\tExpected: %d"+
+			"\n\tReceived: %d", newIndex, retrievedIndex)
+	}
+
+}
+
+// Error path, could not get host
+func TestHostPool_ReplaceHost_Error(t *testing.T) {
+	manager := newMockManager()
+
+	// Construct a manager (bypass business logic in constructor)
+	hostPool := &HostPool{
+		manager:  manager,
+		hostList: make([]*connect.Host, 1),
+		hostMap:  make(map[id.ID]uint32),
+	}
+
+	// Construct an unknown gateway ID to the manager
+	gatewayId := id.NewIdFromString("BadGateway", id.Gateway, t)
+
+	err := hostPool.replaceHost(gatewayId, 0)
+	if err == nil {
+		t.Errorf("Expected error in happy path: Should not be able to find a host")
+	}
+
+}
+
+// Happy path
+func TestHostPool_PruneHostPool(t *testing.T) {
+	manager := newMockManager()
+	testNdf := getTestNdf(t)
+	newIndex := uint32(20)
+	params := DefaultPoolParams()
+	params.poolSize = uint32(len(testNdf.Gateways))
+	rng := csprng.NewSystemRNG()
+
+	// Construct a manager (bypass business logic in constructor)
+	hostPool := &HostPool{
+		manager:    manager,
+		hostList:   make([]*connect.Host, newIndex+1),
+		hostMap:    make(map[id.ID]uint32),
+		ndf:        testNdf,
+		poolParams: params,
+		rng:        rng,
+	}
+
+	// Pull all gateways from ndf into host manager
+	hostList := make([]*connect.Host, 0)
+	for _, gw := range testNdf.Gateways {
+
+		gwId, err := id.Unmarshal(gw.ID)
+		if err != nil {
+			t.Errorf("Failed to unmarshal ID in mock ndf: %v", err)
+		}
+		// Add mock gateway to manager
+		h, err := manager.AddHost(gwId, "", nil, connect.GetDefaultHostParams())
+		if err != nil {
+			t.Errorf("Could not add mock host to manager: %v", err)
+			t.FailNow()
+		}
+
+		hostList = append(hostList, h)
+
+	}
+
+	// Construct a host past the error threshold
+	errorThresholdIndex := 0
+	overThreshold := params.errThreshold + 25
+	hostList[errorThresholdIndex].SetMetricsTesting(connect.NewMetricTesting(overThreshold, t), t)
+	oldHost := hostList[0]
+
+	// Call prune host pool
+	err := hostPool.pruneHostPool()
+	if err != nil {
+		t.Errorf("Unexpected error in happy path: %v", err)
+	}
+
+	// Check that the host map has been properly updated
+	for _, h := range hostList {
+		_, ok := hostPool.hostMap[*h.GetId()]
+		if !ok {
+			t.Errorf("Gateway %s was not placed in host map after pruning", h.GetId().String())
+		}
+	}
+
+	// Check that the host list has been has been properly updated
+	// at the index with a host past the error threshold
+	retrievedHost := hostPool.hostList[errorThresholdIndex]
+	if reflect.DeepEqual(oldHost, retrievedHost) {
+		t.Errorf("Expected host list to have it's bad host replaced. " +
+			"Contains old host information after pruning")
+	}
+
+}
+
+// Error path: not enough gateways in ndf compared to
+// required pool size
+func TestHostPool_PruneHostPool_Error(t *testing.T) {
+	manager := newMockManager()
+	testNdf := getTestNdf(t)
+	newIndex := uint32(20)
+	params := DefaultPoolParams()
+
+	// Trigger the case where the Ndf doesn't have enough gateways
+	params.poolSize = uint32(len(testNdf.Gateways)) + 1
+	rng := csprng.NewSystemRNG()
+
+	// Construct a manager (bypass business logic in constructor)
+	hostPool := &HostPool{
+		manager:    manager,
+		hostList:   make([]*connect.Host, newIndex+1),
+		hostMap:    make(map[id.ID]uint32),
+		ndf:        testNdf,
+		poolParams: params,
+		rng:        rng,
+	}
+
+	// Call prune
+	err := hostPool.pruneHostPool()
+	if err == nil {
+		t.Errorf("Gateways should not be available: " +
+			"not enough gateways in ndf compared to param's pool size")
+	}
+
+}
+
+// Unit test
+func TestHostPool_UpdateNdf(t *testing.T) {
+	manager := newMockManager()
+	testNdf := getTestNdf(t)
+	newIndex := uint32(20)
+
+	// Construct a manager (bypass business logic in constructor)
+	hostPool := &HostPool{
+		manager:  manager,
+		hostList: make([]*connect.Host, newIndex+1),
+		hostMap:  make(map[id.ID]uint32),
+		ndf:      testNdf,
+	}
+
+	// Construct a new Ndf different from original one above
+	newNdf := getTestNdf(t)
+	newGateway := ndf.Gateway{
+		ID: id.NewIdFromUInt(27, id.Gateway, t).Bytes(),
+	}
+	newNdf.Gateways = append(newNdf.Gateways, newGateway)
+
+	// Update pool with the new Ndf
+	hostPool.UpdateNdf(newNdf)
+
+	// Check that the ndf update flag has been set
+	if !hostPool.isNdfUpdated {
+		t.Errorf("Expected ndf updated flag to be set after updateNdf call")
+	}
+
+	// Check that the host pool's ndf has been modified properly
+	if !reflect.DeepEqual(newNdf, hostPool.ndf) {
+		t.Errorf("Host pool ndf not updated to new ndf.")
+	}
+}
+
+// Full test
+func TestHostPool_GetPreferred(t *testing.T) {
+	manager := newMockManager()
+	rng := csprng.NewSystemRNG()
+	testNdf := getTestNdf(t)
+	testStorage := storage.InitTestingSession(t)
+	addGwChan := make(chan network.NodeGateway)
+	params := DefaultPoolParams()
+	params.poolSize = uint32(len(testNdf.Gateways))
+
+	// Pull all gateways from ndf into host manager
+	hostMap := make(map[id.ID]bool, 0)
+	targets := make([]*id.ID, 0)
+	for _, gw := range testNdf.Gateways {
+
+		gwId, err := id.Unmarshal(gw.ID)
+		if err != nil {
+			t.Errorf("Failed to unmarshal ID in mock ndf: %v", err)
+		}
+		// Add mock gateway to manager
+		_, err = manager.AddHost(gwId, gw.Address, nil, connect.GetDefaultHostParams())
+		if err != nil {
+			t.Errorf("Could not add mock host to manager: %v", err)
+			t.FailNow()
+		}
+
+		hostMap[*gwId] = true
+		targets = append(targets, gwId)
+
+	}
+
+	// Call the constructor
+	testPool, err := NewHostPool(params, rng, testNdf, manager,
+		testStorage, addGwChan)
+	if err != nil {
+		t.Errorf("Failed to create mock host pool: %v", err)
+	}
+
+	retrievedList := testPool.GetPreferred(targets)
+	if len(retrievedList) != len(targets) {
+		t.Errorf("Requested list did not output requested length."+
+			"\n\tExpected: %d"+
+			"\n\tReceived: %v", len(targets), len(retrievedList))
+	}
+
+	// In case where all requested gateways are present
+	// ensure requested hosts were returned
+	for _, h := range retrievedList {
+		if !hostMap[*h.GetId()] {
+			t.Errorf("A target gateways which should have been returned was not."+
+				"\n\tExpected: %v", h.GetId())
+		}
+	}
+
+	// Replace a request with a gateway not in pool
+	targets[3] = id.NewIdFromUInt(74, id.Gateway, t)
+	retrievedList = testPool.GetPreferred(targets)
+	if len(retrievedList) != len(targets) {
+		t.Errorf("Requested list did not output requested length."+
+			"\n\tExpected: %d"+
+			"\n\tReceived: %v", len(targets), len(retrievedList))
+	}
+
+	// In case where a requested gateway is not present
+	for _, h := range retrievedList {
+		if h.GetId().Cmp(targets[3]) {
+			t.Errorf("Should not have returned ID not in pool")
+		}
+	}
+
+}
+
+// Unit test
+func TestHostPool_GetAny(t *testing.T) {
+	manager := newMockManager()
+	rng := csprng.NewSystemRNG()
+	testNdf := getTestNdf(t)
+	testStorage := storage.InitTestingSession(t)
+	addGwChan := make(chan network.NodeGateway)
+	params := DefaultPoolParams()
+	params.poolSize = uint32(len(testNdf.Gateways))
+
+	// Pull all gateways from ndf into host manager
+	for _, gw := range testNdf.Gateways {
+
+		gwId, err := id.Unmarshal(gw.ID)
+		if err != nil {
+			t.Errorf("Failed to unmarshal ID in mock ndf: %v", err)
+		}
+		// Add mock gateway to manager
+		_, err = manager.AddHost(gwId, gw.Address, nil, connect.GetDefaultHostParams())
+		if err != nil {
+			t.Errorf("Could not add mock host to manager: %v", err)
+			t.FailNow()
+		}
+
+	}
+
+	// Call the constructor
+	testPool, err := NewHostPool(params, rng, testNdf, manager,
+		testStorage, addGwChan)
+	if err != nil {
+		t.Errorf("Failed to create mock host pool: %v", err)
+	}
+
+	requested := 3
+	anyList := testPool.GetAny(requested)
+	if len(anyList) != requested {
+		t.Errorf("GetAnyList did not get requested length."+
+			"\n\tExpected: %v"+
+			"\n\tReceived: %v", requested, len(anyList))
+	}
+
+	for _, h := range anyList {
+		_, ok := manager.GetHost(h.GetId())
+		if !ok {
+			t.Errorf("Host %s in retrieved list not in manager", h)
+		}
+	}
+
+	// Request more than are in host list
+	largeRequest := requested * 1000
+	largeRetrieved := testPool.GetAny(largeRequest)
+	if len(largeRetrieved) != len(testPool.hostList) {
+		t.Errorf("Large request should result in a list of all in host list")
+	}
+
+}
+
+// Unit test
+func TestHostPool_ForceAdd(t *testing.T) {
+	manager := newMockManager()
+	rng := csprng.NewSystemRNG()
+	testNdf := getTestNdf(t)
+	testStorage := storage.InitTestingSession(t)
+	addGwChan := make(chan network.NodeGateway)
+	params := DefaultPoolParams()
+	params.poolSize = uint32(len(testNdf.Gateways))
+
+	// Pull all gateways from ndf into host manager
+	for _, gw := range testNdf.Gateways {
+
+		gwId, err := id.Unmarshal(gw.ID)
+		if err != nil {
+			t.Errorf("Failed to unmarshal ID in mock ndf: %v", err)
+		}
+		// Add mock gateway to manager
+		_, err = manager.AddHost(gwId, gw.Address, nil, connect.GetDefaultHostParams())
+		if err != nil {
+			t.Errorf("Could not add mock host to manager: %v", err)
+			t.FailNow()
+		}
+
+	}
+
+	// Call the constructor
+	testPool, err := NewHostPool(params, rng, testNdf, manager,
+		testStorage, addGwChan)
+	if err != nil {
+		t.Errorf("Failed to create mock host pool: %v", err)
+	}
+
+	// Construct a list of new gateways to add
+	newGatewayLen := 10
+	newGateways := make([]*id.ID, newGatewayLen)
+	for i := 0; i < newGatewayLen; i++ {
+		gwId := id.NewIdFromUInt(uint64(100+i), id.Gateway, t)
+		// Add mock gateway to manager
+		_, err = manager.AddHost(gwId, "", nil, connect.GetDefaultHostParams())
+		if err != nil {
+			t.Errorf("Could not add mock host to manager: %v", err)
+			t.FailNow()
+		}
+		newGateways[i] = gwId
+	}
+
+	// ForceAdd list of gateways
+	err = testPool.ForceAdd(newGateways)
+	if err != nil {
+		t.Errorf("Could not add gateways: %v", err)
+	}
+
+	for _, gw := range newGateways {
+		if _, ok := testPool.hostMap[*gw]; !ok {
+			t.Errorf("Failed to forcefully add new gateway ID: %v", gw)
+		}
+	}
+
+}
+
+// Unit test which only adds information to ndf
+func TestHostPool_UpdateConns_AddGateways(t *testing.T) {
+	manager := newMockManager()
+	rng := csprng.NewSystemRNG()
+	testNdf := getTestNdf(t)
+	testStorage := storage.InitTestingSession(t)
+	addGwChan := make(chan network.NodeGateway)
+	params := DefaultPoolParams()
+	params.poolSize = uint32(len(testNdf.Gateways))
+
+	// Pull all gateways from ndf into host manager
+	for _, gw := range testNdf.Gateways {
+
+		gwId, err := id.Unmarshal(gw.ID)
+		if err != nil {
+			t.Errorf("Failed to unmarshal ID in mock ndf: %v", err)
+		}
+		// Add mock gateway to manager
+		_, err = manager.AddHost(gwId, gw.Address, nil, connect.GetDefaultHostParams())
+		if err != nil {
+			t.Errorf("Could not add mock host to manager: %v", err)
+			t.FailNow()
+		}
+
+	}
+
+	// Call the constructor
+	testPool, err := NewHostPool(params, rng, testNdf, manager,
+		testStorage, addGwChan)
+	if err != nil {
+		t.Errorf("Failed to create mock host pool: %v", err)
+	}
+
+	// Construct a list of new gateways/nodes to add to ndf
+	newGatewayLen := 10
+	newGateways := make([]ndf.Gateway, newGatewayLen)
+	newNodes := make([]ndf.Node, newGatewayLen)
+	for i := 0; i < newGatewayLen; i++ {
+		// Construct gateways
+		gwId := id.NewIdFromUInt(uint64(100+i), id.Gateway, t)
+		newGateways[i] = ndf.Gateway{ID: gwId.Bytes()}
+		// Construct nodes
+		nodeId := gwId.DeepCopy()
+		nodeId.SetType(id.Node)
+		newNodes[i] = ndf.Node{ID: nodeId.Bytes()}
+
+	}
+
+	// Update the ndf
+	newNdf := getTestNdf(t)
+	newNdf.Gateways = append(newNdf.Gateways, newGateways...)
+	newNdf.Nodes = append(newNdf.Nodes, newNodes...)
+
+	testPool.UpdateNdf(newNdf)
+
+	// Update the connections
+	err = testPool.updateConns()
+	if err != nil {
+		t.Errorf("Failed to update connections: %v", err)
+	}
+
+	// Check that new gateways are in manager
+	for _, ndfGw := range newGateways {
+		gwId, err := id.Unmarshal(ndfGw.ID)
+		if err != nil {
+			t.Errorf("Failed to marshal gateway id for %v", ndfGw)
+		}
+		_, ok := testPool.GetSpecific(gwId)
+		if !ok {
+			t.Errorf("Failed to find gateway %v in manager", gwId)
+		}
+	}
+
+}
+
+// Unit test which only adds information to ndf
+func TestHostPool_UpdateConns_RemoveGateways(t *testing.T) {
+	manager := newMockManager()
+	rng := csprng.NewSystemRNG()
+	testNdf := getTestNdf(t)
+	testStorage := storage.InitTestingSession(t)
+	addGwChan := make(chan network.NodeGateway)
+	params := DefaultPoolParams()
+	params.poolSize = uint32(len(testNdf.Gateways))
+
+	// Pull all gateways from ndf into host manager
+	for _, gw := range testNdf.Gateways {
+
+		gwId, err := id.Unmarshal(gw.ID)
+		if err != nil {
+			t.Errorf("Failed to unmarshal ID in mock ndf: %v", err)
+		}
+		// Add mock gateway to manager
+		_, err = manager.AddHost(gwId, gw.Address, nil, connect.GetDefaultHostParams())
+		if err != nil {
+			t.Errorf("Could not add mock host to manager: %v", err)
+			t.FailNow()
+		}
+
+	}
+
+	// Call the constructor
+	testPool, err := NewHostPool(params, rng, testNdf, manager,
+		testStorage, addGwChan)
+	if err != nil {
+		t.Errorf("Failed to create mock host pool: %v", err)
+	}
+
+	// Construct a list of new gateways/nodes to add to ndf
+	newGatewayLen := len(testNdf.Gateways)
+	newGateways := make([]ndf.Gateway, newGatewayLen)
+	newNodes := make([]ndf.Node, newGatewayLen)
+	for i := 0; i < newGatewayLen; i++ {
+		// Construct gateways
+		gwId := id.NewIdFromUInt(uint64(100+i), id.Gateway, t)
+		newGateways[i] = ndf.Gateway{ID: gwId.Bytes()}
+		// Construct nodes
+		nodeId := gwId.DeepCopy()
+		nodeId.SetType(id.Node)
+		newNodes[i] = ndf.Node{ID: nodeId.Bytes()}
+
+	}
+
+	// Update the ndf, replacing old data entirely
+	newNdf := getTestNdf(t)
+	newNdf.Gateways = newGateways
+	newNdf.Nodes = newNodes
+
+	testPool.UpdateNdf(newNdf)
+
+	// Update the connections
+	err = testPool.updateConns()
+	if err != nil {
+		t.Errorf("Failed to update connections: %v", err)
+	}
+
+	// Check that old gateways are not in pool
+	for _, ndfGw := range testNdf.Gateways {
+		gwId, err := id.Unmarshal(ndfGw.ID)
+		if err != nil {
+			t.Errorf("Failed to marshal gateway id for %v", ndfGw)
+		}
+		if _, ok := testPool.hostMap[*gwId]; ok {
+			t.Errorf("Expected gateway %v to be removed from pool", gwId)
+		}
+	}
+}
+
+// Unit test
+func TestHostPool_AddGateway(t *testing.T) {
+	manager := newMockManager()
+	testNdf := getTestNdf(t)
+	newIndex := uint32(20)
+	params := DefaultPoolParams()
+	params.poolSize = uint32(len(testNdf.Gateways))
+
+	// Construct a manager (bypass business logic in constructor)
+	hostPool := &HostPool{
+		manager:        manager,
+		hostList:       make([]*connect.Host, newIndex+1),
+		hostMap:        make(map[id.ID]uint32),
+		ndf:            testNdf,
+		addGatewayChan: make(chan network.NodeGateway),
+		storage:        storage.InitTestingSession(t),
+	}
+
+	ndfIndex := 0
+
+	gwId, err := id.Unmarshal(testNdf.Gateways[ndfIndex].ID)
+	if err != nil {
+		t.Errorf("Failed to unmarshal ID in mock ndf: %v", err)
+	}
+
+	hostPool.addGateway(gwId, ndfIndex)
+
+	_, ok := manager.GetHost(gwId)
+	if !ok {
+		t.Errorf("Unsuccessfully added host to manager")
+	}
+}
+
+// Unit test
+func TestHostPool_RemoveGateway(t *testing.T) {
+	manager := newMockManager()
+	testNdf := getTestNdf(t)
+	newIndex := uint32(20)
+	params := DefaultPoolParams()
+	params.poolSize = uint32(len(testNdf.Gateways))
+
+	// Construct a manager (bypass business logic in constructor)
+	hostPool := &HostPool{
+		manager:        manager,
+		hostList:       make([]*connect.Host, newIndex+1),
+		hostMap:        make(map[id.ID]uint32),
+		ndf:            testNdf,
+		addGatewayChan: make(chan network.NodeGateway),
+		storage:        storage.InitTestingSession(t),
+	}
+
+	ndfIndex := 0
+
+	gwId, err := id.Unmarshal(testNdf.Gateways[ndfIndex].ID)
+	if err != nil {
+		t.Errorf("Failed to unmarshal ID in mock ndf: %v", err)
+	}
+
+	// Add the new gateway host
+	h, err := hostPool.manager.AddHost(gwId, "", nil, params.hostParams)
+	if err != nil {
+		jww.ERROR.Printf("Could not add gateway host %s: %+v", gwId, err)
+	}
+
+	// Manually add host information
+	hostPool.hostMap[*gwId] = uint32(ndfIndex)
+	hostPool.hostList[ndfIndex] = h
+
+	// Call the removal
+	hostPool.removeGateway(gwId)
+
+	// Check that the map and list have been updated
+	if hostPool.hostList[ndfIndex] != nil {
+		t.Errorf("Host list index was not set to nil after removal")
+	}
+
+	if _, ok := hostPool.hostMap[*gwId]; ok {
+		t.Errorf("Host map did not delete host entry")
+	}
+}
diff --git a/network/gateway/utils_test.go b/network/gateway/utils_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..9cb76c7834e9c8f51bde01f50e3e42e209ef412e
--- /dev/null
+++ b/network/gateway/utils_test.go
@@ -0,0 +1,120 @@
+package gateway
+
+import (
+	"gitlab.com/xx_network/comms/connect"
+	"gitlab.com/xx_network/primitives/id"
+	"gitlab.com/xx_network/primitives/ndf"
+)
+
+// Mock structure adhering to HostManager to be used for happy path
+type mockManager struct {
+	hosts map[string]*connect.Host
+}
+
+// Constructor for mockManager
+func newMockManager() *mockManager {
+	return &mockManager{
+		hosts: make(map[string]*connect.Host),
+	}
+}
+
+func (mhp *mockManager) GetHost(hostId *id.ID) (*connect.Host, bool) {
+	h, ok := mhp.hosts[hostId.String()]
+	return h, ok
+}
+
+func (mhp *mockManager) AddHost(hid *id.ID, address string,
+	cert []byte, params connect.HostParams) (host *connect.Host, err error) {
+	host, err = connect.NewHost(hid, address, cert, params)
+	if err != nil {
+		return nil, err
+	}
+
+	mhp.hosts[hid.String()] = host
+
+	return
+}
+
+func (mhp *mockManager) RemoveHost(hid *id.ID) {
+	delete(mhp.hosts, hid.String())
+}
+
+// Returns a mock
+func getTestNdf(face interface{}) *ndf.NetworkDefinition {
+	return &ndf.NetworkDefinition{
+		Gateways: []ndf.Gateway{{
+			ID:      id.NewIdFromUInt(0, id.Gateway, face)[:],
+			Address: "0.0.0.1",
+		}, {
+			ID:      id.NewIdFromUInt(1, id.Gateway, face)[:],
+			Address: "0.0.0.2",
+		}, {
+			ID:      id.NewIdFromUInt(2, id.Gateway, face)[:],
+			Address: "0.0.0.3",
+		}, {
+			ID:      id.NewIdFromUInt(3, id.Gateway, face)[:],
+			Address: "0.0.0.1",
+		}, {
+			ID:      id.NewIdFromUInt(4, id.Gateway, face)[:],
+			Address: "0.0.0.2",
+		}, {
+			ID:      id.NewIdFromUInt(5, id.Gateway, face)[:],
+			Address: "0.0.0.3",
+		}, {
+			ID:      id.NewIdFromUInt(6, id.Gateway, face)[:],
+			Address: "0.0.0.1",
+		}, {
+			ID:      id.NewIdFromUInt(7, id.Gateway, face)[:],
+			Address: "0.0.0.2",
+		}, {
+			ID:      id.NewIdFromUInt(8, id.Gateway, face)[:],
+			Address: "0.0.0.3",
+		}, {
+			ID:      id.NewIdFromUInt(9, id.Gateway, face)[:],
+			Address: "0.0.0.1",
+		}, {
+			ID:      id.NewIdFromUInt(10, id.Gateway, face)[:],
+			Address: "0.0.0.2",
+		}, {
+			ID:      id.NewIdFromUInt(11, id.Gateway, face)[:],
+			Address: "0.0.0.3",
+		}},
+		Nodes: []ndf.Node{{
+			ID:      id.NewIdFromUInt(0, id.Node, face)[:],
+			Address: "0.0.0.1",
+		}, {
+			ID:      id.NewIdFromUInt(1, id.Node, face)[:],
+			Address: "0.0.0.2",
+		}, {
+			ID:      id.NewIdFromUInt(2, id.Node, face)[:],
+			Address: "0.0.0.3",
+		}, {
+			ID:      id.NewIdFromUInt(3, id.Node, face)[:],
+			Address: "0.0.0.1",
+		}, {
+			ID:      id.NewIdFromUInt(4, id.Node, face)[:],
+			Address: "0.0.0.2",
+		}, {
+			ID:      id.NewIdFromUInt(5, id.Node, face)[:],
+			Address: "0.0.0.3",
+		}, {
+			ID:      id.NewIdFromUInt(6, id.Node, face)[:],
+			Address: "0.0.0.1",
+		}, {
+			ID:      id.NewIdFromUInt(7, id.Node, face)[:],
+			Address: "0.0.0.2",
+		}, {
+			ID:      id.NewIdFromUInt(8, id.Node, face)[:],
+			Address: "0.0.0.3",
+		}, {
+			ID:      id.NewIdFromUInt(9, id.Node, face)[:],
+			Address: "0.0.0.1",
+		}, {
+			ID:      id.NewIdFromUInt(10, id.Node, face)[:],
+			Address: "0.0.0.2",
+		}, {
+			ID:      id.NewIdFromUInt(11, id.Node, face)[:],
+			Address: "0.0.0.3",
+		}},
+	}
+}
diff --git a/network/node/register.go b/network/node/register.go
index 2b59d1e7ffd23853705541c46eb14242e8c3ca76..a27529b6eb612e9c3ae49a4e07393dbe67d8c347 100644
--- a/network/node/register.go
+++ b/network/node/register.go
@@ -45,7 +45,7 @@ func StartRegistration(instance *network.Instance, session *storage.Session, rng
 
 	multi := stoppable.NewMulti("NodeRegistrations")
 
-	for i:=uint(0);i<numParallel;i++{
+	for i := uint(0); i < numParallel; i++ {
 		stop := stoppable.NewSingle(fmt.Sprintf("NodeRegistration %d", i))
 
 		go registerNodes(session, rngGen, comms, stop, c)
diff --git a/network/rounds/utils_test.go b/network/rounds/utils_test.go
index f8f14e32778574850519b02fcd73da6d2171e2e5..6a5a6b2cadcc80436c55023e657bc7be1aefee34 100644
--- a/network/rounds/utils_test.go
+++ b/network/rounds/utils_test.go
@@ -39,6 +39,7 @@ const ReturningGateway = "GetMessageRequest"
 const FalsePositive = "FalsePositive"
 const PayloadMessage = "Payload"
 const ErrorGateway = "Error"
+
 type mockMessageRetrievalComms struct {
 	testingSignature *testing.T
 }