diff --git a/storage/edge/edge.go b/storage/edge/edge.go
index 88cd4f5b87df3777c90e3499c3021c0ea0eae88e..d8ac0acbc083e3d48cb6250becfd7730c08e23e8 100644
--- a/storage/edge/edge.go
+++ b/storage/edge/edge.go
@@ -33,8 +33,9 @@ func NewStore(kv *versioned.KV, baseIdentity *id.ID) (*Store, error) {
 	kv = kv.Prefix(edgeStorePrefix)
 
 	s := &Store{
-		kv:   kv,
-		edge: make(map[id.ID]Preimages),
+		kv:        kv,
+		edge:      make(map[id.ID]Preimages),
+		callbacks: make(map[id.ID][]ListUpdateCallBack),
 	}
 
 	defaultPreimages := newPreimages(baseIdentity)
@@ -49,6 +50,8 @@ func NewStore(kv *versioned.KV, baseIdentity *id.ID) (*Store, error) {
 	return s, s.save()
 }
 
+// Add adds the Preimage to the list of the given identity and calls any
+// associated callbacks.
 func (s *Store) Add(preimage Preimage, identity *id.ID) {
 	s.mux.Lock()
 	defer s.mux.Unlock()
@@ -60,7 +63,7 @@ func (s *Store) Add(preimage Preimage, identity *id.ID) {
 	}
 
 	// Add to the list
-	preimages = preimages.add(preimage)
+	preimages.add(preimage)
 
 	// Store the updated list
 	if err := preimages.save(s.kv, identity); err != nil {
@@ -97,16 +100,16 @@ func (s *Store) Remove(preimage Preimage, identity *id.ID) error {
 			"identity cannot be found", preimage.Data, identity)
 	}
 
-	preimagesNew := preimages.remove(preimage.Data)
+	preimages.remove(preimage.Data)
 
-	if len(preimagesNew) == 0 {
+	if len(preimages) == 0 {
 		delete(s.edge, *identity)
 		if err := s.save(); err != nil {
 			jww.FATAL.Panicf("Failed to store edge store after removing "+
 				"preimage %v to identity %s: %+v", preimage.Data, identity, err)
 		}
 
-		if err := preimagesNew.delete(s.kv, identity); err != nil {
+		if err := preimages.delete(s.kv, identity); err != nil {
 			jww.FATAL.Panicf("Failed to delete preimage list store after "+
 				"removing preimage %v to identity %s: %+v", preimage.Data,
 				identity, err)
@@ -121,12 +124,12 @@ func (s *Store) Remove(preimage Preimage, identity *id.ID) error {
 		return nil
 	}
 
-	if err := preimagesNew.save(s.kv, identity); err != nil {
+	if err := preimages.save(s.kv, identity); err != nil {
 		jww.FATAL.Panicf("Failed to store preimage list store after removing "+
 			"preimage %v to identity %s: %+v", preimage.Data, identity, err)
 	}
 
-	s.edge[*identity] = preimagesNew
+	s.edge[*identity] = preimages
 
 	// Call any callbacks to notify
 	for i := range s.callbacks[*identity] {
@@ -137,7 +140,7 @@ func (s *Store) Remove(preimage Preimage, identity *id.ID) error {
 	return nil
 }
 
-func (s *Store) Get(identity *id.ID) ([]Preimage, bool) {
+func (s *Store) Get(identity *id.ID) (Preimages, bool) {
 	s.mux.RLock()
 	defer s.mux.RUnlock()
 
diff --git a/storage/edge/edge_test.go b/storage/edge/edge_test.go
index 19ce3404c09c25d4d6e27fad7fde5fbaa89c1fa6..6385b6114aae20e6dbfe7061cbb63535939666b7 100644
--- a/storage/edge/edge_test.go
+++ b/storage/edge/edge_test.go
@@ -30,8 +30,9 @@ func TestNewStore(t *testing.T) {
 	kv := versioned.NewKV(make(ekv.Memstore))
 	baseIdentity := id.NewIdFromString("baseIdentity", id.User, t)
 	expected := &Store{
-		kv:   kv.Prefix(edgeStorePrefix),
-		edge: map[id.ID]Preimages{*baseIdentity: newPreimages(baseIdentity)},
+		kv:        kv.Prefix(edgeStorePrefix),
+		edge:      map[id.ID]Preimages{*baseIdentity: newPreimages(baseIdentity)},
+		callbacks: make(map[id.ID][]ListUpdateCallBack),
 	}
 
 	received, err := NewStore(kv, baseIdentity)
@@ -50,6 +51,9 @@ func TestNewStore(t *testing.T) {
 	}
 }
 
+// Adds three Preimage to the store, two with the same identity. It checks that
+// all three exist and that the length of the list is correct. Also checks that
+// the appropriate callbacks are called.
 func TestStore_Add(t *testing.T) {
 	s, _, _ := newTestStore(t)
 	identities := []*id.ID{
@@ -62,10 +66,53 @@ func TestStore_Add(t *testing.T) {
 		{[]byte("ID2"), "default2", []byte("ID2")},
 	}
 
-	// id0Chan := make(chan bool, 2)
-	// s.callbacks[*identities[0]] = []ListUpdateCallBack{func(identity *id.ID, deleted bool) {
-	// 	id0Chan
-	// }}
+	id0Chan := make(chan struct {
+		identity *id.ID
+		deleted  bool
+	}, 2)
+	s.callbacks[*identities[0]] = []ListUpdateCallBack{func(identity *id.ID, deleted bool) {
+		id0Chan <- struct {
+			identity *id.ID
+			deleted  bool
+		}{identity: identity, deleted: deleted}
+	}}
+
+	go func() {
+		for i := 0; i < 2; i++ {
+			select {
+			case <-time.NewTimer(10 * time.Millisecond).C:
+				t.Errorf("Timed out waiting for callback (%d).", i)
+			case r := <-id0Chan:
+				if !identities[0].Cmp(r.identity) {
+					t.Errorf("Received wrong identity (%d).\nexpected: %s"+
+						"\nreceived: %s", i, identities[0], r.identity)
+				}
+			}
+		}
+	}()
+
+	id1Chan := make(chan struct {
+		identity *id.ID
+		deleted  bool
+	})
+	s.callbacks[*identities[1]] = []ListUpdateCallBack{func(identity *id.ID, deleted bool) {
+		id1Chan <- struct {
+			identity *id.ID
+			deleted  bool
+		}{identity: identity, deleted: deleted}
+	}}
+
+	go func() {
+		select {
+		case <-time.NewTimer(10 * time.Millisecond).C:
+			t.Errorf("Timed out waiting for callback.")
+		case r := <-id0Chan:
+			if !identities[0].Cmp(r.identity) {
+				t.Errorf("Received wrong identity.\nexpected: %s\nreceived: %s",
+					identities[0], r.identity)
+			}
+		}
+	}()
 
 	s.Add(preimages[0], identities[0])
 	s.Add(preimages[1], identities[1])
@@ -84,19 +131,19 @@ func TestStore_Add(t *testing.T) {
 	}
 
 	expected := Preimage{identities[0].Bytes(), "default", identities[0].Bytes()}
-	if !reflect.DeepEqual(pis[0], expected) {
+	if !reflect.DeepEqual(pis[expected.key()], expected) {
 		t.Errorf("First Preimage of first Preimages does not match expected."+
-			"\nexpected: %+v\nreceived: %+v", expected, pis[0])
+			"\nexpected: %+v\nreceived: %+v", expected, pis[expected.key()])
 	}
 
-	if !reflect.DeepEqual(pis[1], preimages[0]) {
+	if !reflect.DeepEqual(pis[preimages[0].key()], preimages[0]) {
 		t.Errorf("Second Preimage of first Preimages does not match expected."+
-			"\nexpected: %+v\nreceived: %+v", preimages[0], pis[1])
+			"\nexpected: %+v\nreceived: %+v", preimages[0], pis[preimages[0].key()])
 	}
 
-	if !reflect.DeepEqual(pis[2], preimages[2]) {
+	if !reflect.DeepEqual(pis[preimages[2].key()], preimages[2]) {
 		t.Errorf("Third Preimage of first Preimages does not match expected."+
-			"\nexpected: %+v\nreceived: %+v", preimages[2], pis[2])
+			"\nexpected: %+v\nreceived: %+v", preimages[2], pis[preimages[2].key()])
 	}
 
 	pis = s.edge[*identities[1]]
@@ -107,14 +154,14 @@ func TestStore_Add(t *testing.T) {
 	}
 
 	expected = Preimage{identities[1].Bytes(), "default", identities[1].Bytes()}
-	if !reflect.DeepEqual(pis[0], expected) {
+	if !reflect.DeepEqual(pis[expected.key()], expected) {
 		t.Errorf("First Preimage of second Preimages does not match expected."+
-			"\nexpected: %+v\nreceived: %+v", expected, pis[0])
+			"\nexpected: %+v\nreceived: %+v", expected, pis[expected.key()])
 	}
 
-	if !reflect.DeepEqual(pis[1], preimages[1]) {
+	if !reflect.DeepEqual(pis[preimages[1].key()], preimages[1]) {
 		t.Errorf("Second Preimage of second Preimages does not match expected."+
-			"\nexpected: %+v\nreceived: %+v", preimages[1], pis[1])
+			"\nexpected: %+v\nreceived: %+v", preimages[1], pis[preimages[1].key()])
 	}
 }
 
diff --git a/storage/edge/preimage.go b/storage/edge/preimage.go
index da5ff77d755202fb7e15d9d228e8a6b9049bf17b..0115bbee4b5036fc67a1ed92d4f24f75bdb15626 100644
--- a/storage/edge/preimage.go
+++ b/storage/edge/preimage.go
@@ -1,7 +1,7 @@
 package edge
 
 import (
-	"bytes"
+	"encoding/base64"
 	"encoding/json"
 	"github.com/pkg/errors"
 	"gitlab.com/elixxir/client/storage/versioned"
@@ -20,13 +20,18 @@ type Preimage struct {
 	Source []byte
 }
 
-type Preimages []Preimage
+// key returns the key used to identify the Preimage in a map.
+func (pi Preimage) key() string {
+	return base64.StdEncoding.EncodeToString(pi.Data)
+}
+
+type Preimages map[string]Preimage
 
 // newPreimages makes a Preimages object for the given identity and populates
 // it with the default preimage for the identity. Does not store to disk.
 func newPreimages(identity *id.ID) Preimages {
 	pis := Preimages{
-		{
+		identity.String(): {
 			Data:   identity[:],
 			Type:   "default",
 			Source: identity[:],
@@ -37,19 +42,18 @@ func newPreimages(identity *id.ID) Preimages {
 }
 
 // add adds the preimage to the list.
-func (pis Preimages) add(pimg Preimage) Preimages {
-	return append(pis, pimg)
-}
-
-func (pis Preimages) remove(data []byte) Preimages {
-	for i, preimage := range pis {
-		if bytes.Equal(preimage.Data, data) {
-			pis[i] = pis[len(pis)-1]
-			return pis[:len(pis)-1]
-		}
+func (pis Preimages) add(preimage Preimage) {
+	if _, exists := pis[preimage.key()]; exists {
+		return
 	}
 
-	return pis
+	pis[preimage.key()] = preimage
+}
+
+// remove deletes the Preimage with the matching data from the list.
+func (pis Preimages) remove(data []byte) {
+	key := base64.StdEncoding.EncodeToString(data)
+	delete(pis, key)
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/storage/edge/preimage_test.go b/storage/edge/preimage_test.go
index 173873d7755f8ba48926b0ca99bca6653c9f6a94..208fbd7966aae20da15f0dd2a5a231282e0fa1e6 100644
--- a/storage/edge/preimage_test.go
+++ b/storage/edge/preimage_test.go
@@ -20,11 +20,13 @@ import (
 // Tests that newPreimages returns the expected new Preimages.
 func Test_newPreimages(t *testing.T) {
 	identity := id.NewIdFromString("identity", id.User, t)
-	expected := Preimages{{
-		Data:   identity.Bytes(),
-		Type:   "default",
-		Source: identity.Bytes(),
-	}}
+	expected := Preimages{
+		identity.String(): {
+			Data:   identity.Bytes(),
+			Type:   "default",
+			Source: identity.Bytes(),
+		},
+	}
 
 	received := newPreimages(identity)
 
@@ -38,15 +40,16 @@ func Test_newPreimages(t *testing.T) {
 func TestPreimages_add(t *testing.T) {
 	identity0 := id.NewIdFromString("identity0", id.User, t)
 	identity1 := id.NewIdFromString("identity1", id.User, t)
+	identity2 := id.NewIdFromString("identity3", id.User, t)
 	expected := Preimages{
-		{identity0.Bytes(), "default", identity0.Bytes()},
-		{identity0.Bytes(), "group", identity0.Bytes()},
-		{identity1.Bytes(), "default", identity1.Bytes()},
+		identity0.String(): {identity0.Bytes(), "default", identity0.Bytes()},
+		identity1.String(): {identity1.Bytes(), "group", identity1.Bytes()},
+		identity2.String(): {identity2.Bytes(), "default", identity2.Bytes()},
 	}
 
 	pis := newPreimages(identity0)
-	pis = pis.add(Preimage{identity0.Bytes(), "group", identity0.Bytes()})
-	pis = pis.add(Preimage{identity1.Bytes(), "default", identity1.Bytes()})
+	pis.add(Preimage{identity1.Bytes(), "group", identity1.Bytes()})
+	pis.add(Preimage{identity2.Bytes(), "default", identity2.Bytes()})
 
 	if !reflect.DeepEqual(expected, pis) {
 		t.Errorf("Failed to add expected Preimages."+
@@ -56,7 +59,7 @@ func TestPreimages_add(t *testing.T) {
 
 // Tests that Preimages.remove removes all the correct Preimage from the list.
 func TestPreimages_remove(t *testing.T) {
-	var pis Preimages
+	pis := make(Preimages)
 	var identities [][]byte
 
 	// Add 10 Preimage to the list
@@ -67,14 +70,14 @@ func TestPreimages_remove(t *testing.T) {
 			pisType = "group"
 		}
 
-		pis = pis.add(Preimage{identity.Bytes(), pisType, identity.Bytes()})
+		pis.add(Preimage{identity.Bytes(), pisType, identity.Bytes()})
 		identities = append(identities, identity.Bytes())
 	}
 
 	// Remove each Preimage, check if the length of the list has changed, and
 	// check that the correct Preimage was removed
 	for i, identity := range identities {
-		pis = pis.remove(identity)
+		pis.remove(identity)
 
 		if len(pis) != len(identities)-(i+1) {
 			t.Errorf("Length of Preimages incorrect after removing %d Premiages."+
@@ -101,9 +104,9 @@ func Test_loadPreimages(t *testing.T) {
 	kv := versioned.NewKV(make(ekv.Memstore))
 	identity := id.NewIdFromString("identity", id.User, t)
 	pis := Preimages{
-		{[]byte("identity0"), "default", []byte("identity0")},
-		{[]byte("identity0"), "group", []byte("identity0")},
-		{[]byte("identity1"), "default", []byte("identity1")},
+		"a": {[]byte("identity0"), "default", []byte("identity0")},
+		"b": {[]byte("identity0"), "group", []byte("identity0")},
+		"c": {[]byte("identity1"), "default", []byte("identity1")},
 	}
 
 	err := pis.save(kv, identity)
@@ -128,9 +131,9 @@ func TestPreimages_save(t *testing.T) {
 	kv := versioned.NewKV(make(ekv.Memstore))
 	identity := id.NewIdFromString("identity", id.User, t)
 	pis := Preimages{
-		{[]byte("identity0"), "default", []byte("identity0")},
-		{[]byte("identity0"), "group", []byte("identity0")},
-		{[]byte("identity1"), "default", []byte("identity1")},
+		"a": {[]byte("identity0"), "default", []byte("identity0")},
+		"b": {[]byte("identity0"), "group", []byte("identity0")},
+		"c": {[]byte("identity1"), "default", []byte("identity1")},
 	}
 
 	err := pis.save(kv, identity)
@@ -161,9 +164,9 @@ func TestPreimages_delete(t *testing.T) {
 	kv := versioned.NewKV(make(ekv.Memstore))
 	identity := id.NewIdFromString("identity", id.User, t)
 	pis := Preimages{
-		{[]byte("identity0"), "default", []byte("identity0")},
-		{[]byte("identity0"), "group", []byte("identity0")},
-		{[]byte("identity1"), "default", []byte("identity1")},
+		"a": {[]byte("identity0"), "default", []byte("identity0")},
+		"b": {[]byte("identity0"), "group", []byte("identity0")},
+		"c": {[]byte("identity1"), "default", []byte("identity1")},
 	}
 
 	err := pis.save(kv, identity)