diff --git a/bindings/preimage.go b/bindings/preimage.go new file mode 100644 index 0000000000000000000000000000000000000000..ff9e7571869d8c49cf776b0830db30a1698d7892 --- /dev/null +++ b/bindings/preimage.go @@ -0,0 +1,66 @@ +package bindings + +import ( + "github.com/pkg/errors" + "gitlab.com/elixxir/client/storage/edge" + "gitlab.com/xx_network/primitives/id" +) + + +type PreimageNotification interface{ + Notify(identity []byte, deleted bool) +} + +func (c *Client)RegisterPreimageCallback(identity []byte, pin PreimageNotification){ + + iid := &id.ID{} + copy(iid[:], identity) + + cb := func(localIdentity *id.ID, deleted bool){ + pin.Notify(localIdentity[:],deleted) + } + + c.api.GetStorage().GetEdge().AddUpdateCallback(iid, cb) +} + +func (c *Client)GetPreimages(identity []byte)(*PreimageList, error){ + + iid := &id.ID{} + copy(iid[:], identity) + + list, exist := c.api.GetStorage().GetEdge().Get(iid) + if !exist{ + return nil, errors.Errorf("Could not find a preimage list for %s", iid) + } + + return &PreimageList{list: list}, nil +} + +type Preimage struct{ + pi edge.Preimage +} + +func (pi *Preimage)Get()[]byte{ + return pi.pi.Data +} + +func (pi *Preimage)Type()string{ + return pi.pi.Type +} + +func (pi *Preimage)Source()[]byte{ + return pi.pi.Source +} + + +type PreimageList struct{ + list edge.Preimages +} + +func (pil *PreimageList)Len()int{ + return len(pil.list) +} + +func (pil *PreimageList)Get(index int)*Preimage{ + return &Preimage{pi:pil.list[index]} +} \ No newline at end of file diff --git a/go.mod b/go.mod index dbe4d79a58accf98ee34cc3b003b82eb7dcac69e..3e85ae6017d86c931b6f2e67d120c6fbf012affc 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/spf13/viper v1.7.1 gitlab.com/elixxir/bloomfilter v0.0.0-20200930191214-10e9ac31b228 gitlab.com/elixxir/comms v0.0.4-0.20211014164523-495493efb970 - gitlab.com/elixxir/crypto v0.0.7-0.20211017232951-ba1a65ee7b6e + gitlab.com/elixxir/crypto v0.0.7-0.20211020151749-ff7236fb494a gitlab.com/elixxir/ekv v0.1.5 gitlab.com/elixxir/primitives v0.0.3-0.20211014164029-06022665b576 gitlab.com/xx_network/comms v0.0.4-0.20211014163953-e774276b83ae diff --git a/go.sum b/go.sum index 37d23fd0792d608122530d1b2d168f77b572f356..bc8b979fe868538cf06cd81849f9163543071c43 100644 --- a/go.sum +++ b/go.sum @@ -261,6 +261,8 @@ gitlab.com/elixxir/crypto v0.0.7-0.20211014164205-95915de2ac0d h1:tI3YYoHVb/KViR gitlab.com/elixxir/crypto v0.0.7-0.20211014164205-95915de2ac0d/go.mod h1:teuTEXyqsqo4N/J1sshcTg9xYOt+wNTurop7pkZOiCg= gitlab.com/elixxir/crypto v0.0.7-0.20211017232951-ba1a65ee7b6e h1:JCYcXV9GBvOVRfYhm1e2b52AnvPQrEQLmOR9XbjzE8k= gitlab.com/elixxir/crypto v0.0.7-0.20211017232951-ba1a65ee7b6e/go.mod h1:teuTEXyqsqo4N/J1sshcTg9xYOt+wNTurop7pkZOiCg= +gitlab.com/elixxir/crypto v0.0.7-0.20211020151749-ff7236fb494a h1:8mrk1jGNMAP1xYnvq67mNP6n42Xiu0a5NsYQ3ztXxgM= +gitlab.com/elixxir/crypto v0.0.7-0.20211020151749-ff7236fb494a/go.mod h1:teuTEXyqsqo4N/J1sshcTg9xYOt+wNTurop7pkZOiCg= gitlab.com/elixxir/ekv v0.1.5 h1:R8M1PA5zRU1HVnTyrtwybdABh7gUJSCvt1JZwUSeTzk= gitlab.com/elixxir/ekv v0.1.5/go.mod h1:e6WPUt97taFZe5PFLPb1Dupk7tqmDCTQu1kkstqJvw4= gitlab.com/elixxir/primitives v0.0.0-20200731184040-494269b53b4d/go.mod h1:OQgUZq7SjnE0b+8+iIAT2eqQF+2IFHn73tOo+aV11mg= diff --git a/groupChat/makeGroup.go b/groupChat/makeGroup.go index f3c5544c9e6b46a6a747e6ef96d1f7bc870e7aae..a9aa01838d1c6db25cf71cc79e2631bbb4b01371 100644 --- a/groupChat/makeGroup.go +++ b/groupChat/makeGroup.go @@ -11,6 +11,7 @@ import ( "github.com/pkg/errors" jww "github.com/spf13/jwalterweatherman" gs "gitlab.com/elixxir/client/groupChat/groupStore" + "gitlab.com/elixxir/client/storage/edge" "gitlab.com/elixxir/crypto/contact" "gitlab.com/elixxir/crypto/fastRNG" "gitlab.com/elixxir/crypto/group" @@ -87,6 +88,15 @@ func (m Manager) MakeGroup(membership []*id.ID, name, msg []byte) (gs.Group, // Send all group requests roundIDs, status, err := m.sendRequests(g) + if err==nil{ + edgeStore := m.store.GetEdge() + edgeStore.Add(edge.Preimage{ + Data: g.ID[:], + Type: "group", + Source: g.ID[:], + },m.client.GetUser().ReceptionID) + } + return g, roundIDs, status, err } diff --git a/groupChat/manager.go b/groupChat/manager.go index 92081c060859f180e08c34693d80668b159f3f60..3a2416cd6db0dc90e5bb4f74c80a1fccbceb1c8e 100644 --- a/groupChat/manager.go +++ b/groupChat/manager.go @@ -16,6 +16,7 @@ import ( "gitlab.com/elixxir/client/interfaces/message" "gitlab.com/elixxir/client/stoppable" "gitlab.com/elixxir/client/storage" + "gitlab.com/elixxir/client/storage/edge" "gitlab.com/elixxir/client/storage/versioned" "gitlab.com/elixxir/crypto/cyclic" "gitlab.com/elixxir/crypto/fastRNG" @@ -129,6 +130,13 @@ func (m Manager) JoinGroup(g gs.Group) error { return errors.Errorf(joinGroupErr, g.ID, err) } + edgeStore := m.store.GetEdge() + edgeStore.Add(edge.Preimage{ + Data: g.ID[:], + Type: "group", + Source: g.ID[:], + },m.client.GetUser().ReceptionID) + jww.DEBUG.Printf("Joined group %s.", g.ID) return nil @@ -140,9 +148,16 @@ func (m Manager) LeaveGroup(groupID *id.ID) error { return errors.Errorf(leaveGroupErr, groupID, err) } + edgeStore := m.store.GetEdge() + err := edgeStore.Remove(edge.Preimage{ + Data: groupID[:], + Type: "group", + Source: groupID[:], + },m.client.GetUser().ReceptionID) + jww.DEBUG.Printf("Left group %s.", groupID) - return nil + return err } // GetGroups returns a list of all registered groupChat IDs. diff --git a/groupChat/send.go b/groupChat/send.go index 0ac72527b60e535b07fd553f4d7a2b386e578d32..29941ce8e71fcc1cea9ec900b01be88d4bea0cc0 100644 --- a/groupChat/send.go +++ b/groupChat/send.go @@ -46,7 +46,10 @@ func (m *Manager) Send(groupID *id.ID, message []byte) (id.Round, time.Time, return 0, time.Time{}, errors.Errorf(newCmixMsgErr, err) } - rid, _, err := m.net.SendManyCMIX(messages, params.GetDefaultCMIX()) + param := params.GetDefaultCMIX() + param.IdentityPreimage = groupID[:] + + rid, _, err := m.net.SendManyCMIX(messages, param) if err != nil { return 0, time.Time{}, errors.Errorf(sendManyCmixErr, m.gs.GetUser().ID, groupID, err) diff --git a/interfaces/params/CMIX.go b/interfaces/params/CMIX.go index e4142eb5e509dd8ffce8cfd6b3e7a8d33d4fdc46..ee735d1d96026b416c2790c7a7731e5285ca0801 100644 --- a/interfaces/params/CMIX.go +++ b/interfaces/params/CMIX.go @@ -17,6 +17,9 @@ type CMIX struct { RoundTries uint Timeout time.Duration RetryDelay time.Duration + // an alternate identity preimage to use on send. If not set, the default + // for the sending identity will be used + IdentityPreimage []byte } func GetDefaultCMIX() CMIX { diff --git a/network/follow.go b/network/follow.go index ca0634be7f36a44e00c487046e488ee57525a55b..bdcdf5deb8d5bda9d72c587f2ceae7d20b80a0f8 100644 --- a/network/follow.go +++ b/network/follow.go @@ -321,11 +321,15 @@ func (m *manager) follow(report interfaces.ClientErrorReport, rng csprng.Source, //threshold is the earliest round that will not be excluded from earliest remaining earliestRemaining, roundsWithMessages, roundsUnknown := gwRoundsState.RangeUnchecked(updated, m.param.KnownRoundsThreshold, roundChecker) + jww.DEBUG.Printf("Processed RangeUnchecked, Oldest: %d, firstUnchecked: %d, " + + "last Checked: %d, threshold: %d, NewEarliestRemaning: %d, NumWithMessages: %d, " + + "NumUnknown: %d", updated, gwRoundsState.GetFirstUnchecked(), gwRoundsState.GetLastChecked(), + m.param.KnownRoundsThreshold, earliestRemaining, len(roundsWithMessages), len(roundsUnknown)) _, _, changed := identity.ER.Set(earliestRemaining) if changed { jww.TRACE.Printf("External returns of RangeUnchecked: %d, %v, %v", earliestRemaining, roundsWithMessages, roundsUnknown) - jww.DEBUG.Printf("New Earliest Remaining: %d", earliestRemaining) + jww.DEBUG.Printf("New Earliest Remaining: %d, Gateways last checked: %d", earliestRemaining, gwRoundsState.GetLastChecked()) } roundsWithMessages2 := identity.UR.Iterate(func(rid id.Round) bool { diff --git a/network/message/handler.go b/network/message/handler.go index ed6891a755a885f186cb7352b60c588b61eb6d13..1931dc84cc5ba3df09ccf22428411e9f2b44a7b2 100644 --- a/network/message/handler.go +++ b/network/message/handler.go @@ -12,6 +12,7 @@ import ( jww "github.com/spf13/jwalterweatherman" "gitlab.com/elixxir/client/interfaces/message" "gitlab.com/elixxir/client/stoppable" + "gitlab.com/elixxir/client/storage/edge" "gitlab.com/elixxir/crypto/e2e" fingerprint2 "gitlab.com/elixxir/crypto/fingerprint" "gitlab.com/elixxir/primitives/format" @@ -21,6 +22,7 @@ import ( ) func (m *Manager) handleMessages(stop *stoppable.Single) { + preimageList := m.Session.GetEdge() for { select { case <-stop.Quit(): @@ -28,7 +30,7 @@ func (m *Manager) handleMessages(stop *stoppable.Single) { return case bundle := <-m.messageReception: for _, msg := range bundle.Messages { - m.handleMessage(msg, bundle) + m.handleMessage(msg, bundle, preimageList) } bundle.Finish() } @@ -36,7 +38,7 @@ func (m *Manager) handleMessages(stop *stoppable.Single) { } -func (m *Manager) handleMessage(ecrMsg format.Message, bundle Bundle) { +func (m *Manager) handleMessage(ecrMsg format.Message, bundle Bundle, edge *edge.Store) { // We've done all the networking, now process the message fingerprint := ecrMsg.GetKeyFP() msgDigest := ecrMsg.Digest() @@ -51,14 +53,27 @@ func (m *Manager) handleMessage(ecrMsg format.Message, bundle Bundle) { var relationshipFingerprint []byte //check if the identity fingerprint matches - forMe := fingerprint2.CheckIdentityFP(ecrMsg.GetIdentityFP(), - ecrMsg.GetContents(), identity.Source) + //first check if a list is present in store for the receiving source + forMe := false + preimagelist, exist := edge.Get(identity.Source) + if exist{ + //if it exists, check against all in the list + for i:=0;i<len(preimagelist)&&!forMe;i++{ + forMe = fingerprint2.CheckIdentityFP(ecrMsg.GetIdentityFP(), + ecrMsg.GetContents(), preimagelist[i].Data) + } + }else{ + //if it doesnt exist, check against the default fingerprint for the identity + forMe = fingerprint2.CheckIdentityFP(ecrMsg.GetIdentityFP(), + ecrMsg.GetContents(), identity.Source[:]) + } + if !forMe { if jww.GetLogThreshold() == jww.LevelTrace { expectedFP := fingerprint2.IdentityFP(ecrMsg.GetContents(), - identity.Source) + identity.Source[:]) jww.TRACE.Printf("Message for %d (%s) failed identity "+ - "check: %v (expected) vs %v (received)", identity.EphId, + "check: %v (expected-default) vs %v (received)", identity.EphId, identity.Source, expectedFP, ecrMsg.GetIdentityFP()) } diff --git a/network/message/sendCmix.go b/network/message/sendCmix.go index bfb57a56903cb9f4f23e46cae2c59657c0d06da1..5847e4e15631424d0b4165d11d49e0ec980cf98d 100644 --- a/network/message/sendCmix.go +++ b/network/message/sendCmix.go @@ -135,7 +135,7 @@ func sendCmixHelper(sender *gateway.Sender, msg format.Message, stream := rng.GetStream() wrappedMsg, encMsg, ephID, err := buildSlotMessage(msg, recipient, - firstGateway, stream, senderId, bestRound, roundKeys) + firstGateway, stream, senderId, bestRound, roundKeys, cmixParams) if err != nil { stream.Close() return 0, ephemeral.Id{}, err diff --git a/network/message/sendCmixUtils.go b/network/message/sendCmixUtils.go index 4e71f5731f775386d9ab3afa1d10316214d67b32..7535a66d97f8b66396e92e2c3284e5ff6488a399 100644 --- a/network/message/sendCmixUtils.go +++ b/network/message/sendCmixUtils.go @@ -10,6 +10,7 @@ package message import ( "github.com/pkg/errors" jww "github.com/spf13/jwalterweatherman" + "gitlab.com/elixxir/client/interfaces/params" "gitlab.com/elixxir/client/storage" "gitlab.com/elixxir/client/storage/cmix" pb "gitlab.com/elixxir/comms/mixmessages" @@ -119,7 +120,7 @@ func processRound(instance *network.Instance, session *storage.Session, // the recipient. func buildSlotMessage(msg format.Message, recipient *id.ID, target *id.ID, stream *fastRNG.Stream, senderId *id.ID, bestRound *pb.RoundInfo, - roundKeys *cmix.RoundKeys) (*pb.GatewaySlot, format.Message, ephemeral.Id, + roundKeys *cmix.RoundKeys, param params.CMIX) (*pb.GatewaySlot, format.Message, ephemeral.Id, error) { // Set the ephemeral ID @@ -139,8 +140,14 @@ func buildSlotMessage(msg format.Message, recipient *id.ID, target *id.ID, msg.SetEphemeralRID(ephIdFilled[:]) + // use the alternate identity preimage if it is set + preimage := recipient[:] + if param.IdentityPreimage!=nil{ + preimage = param.IdentityPreimage + } + // Set the identity fingerprint - ifp := fingerprint.IdentityFP(msg.GetContents(), recipient) + ifp := fingerprint.IdentityFP(msg.GetContents(), preimage) msg.SetIdentityFP(ifp) diff --git a/network/message/sendManyCmix.go b/network/message/sendManyCmix.go index 3c212f745846c2b60747517d3759a0d019e5528d..60267b607bb69a008bf2409e85687549c445f8c4 100644 --- a/network/message/sendManyCmix.go +++ b/network/message/sendManyCmix.go @@ -115,7 +115,7 @@ func sendManyCmixHelper(sender *gateway.Sender, msgs map[id.ID]format.Message, i := 0 for recipient, msg := range msgs { slots[i], encMsgs[i], ephemeralIds[i], err = buildSlotMessage( - msg, &recipient, firstGateway, stream, senderId, bestRound, roundKeys) + msg, &recipient, firstGateway, stream, senderId, bestRound, roundKeys, param) if err != nil { return 0, []ephemeral.Id{}, errors.Errorf("failed to build "+ "slot message for %s: %+v", recipient, err) diff --git a/storage/edge/edge.go b/storage/edge/edge.go new file mode 100644 index 0000000000000000000000000000000000000000..8b2a050eda45df5fd5326ae4bc88b8eccb21dde8 --- /dev/null +++ b/storage/edge/edge.go @@ -0,0 +1,215 @@ +package edge + +import ( + "encoding/json" + "github.com/pkg/errors" + jww "github.com/spf13/jwalterweatherman" + "gitlab.com/elixxir/client/storage/versioned" + "gitlab.com/xx_network/primitives/id" + "gitlab.com/xx_network/primitives/netTime" + "sync" +) + +// This stores Preimages which can be used with the identity +// fingerprint system + +const( + edgeStorePrefix = "edgeStore" + edgeStoreKey = "edgeStoreKey" + edgeStoreVersion = 0 +) + + +type ListUpdateCallBack func(identity *id.ID, deleted bool) + +type Store struct{ + kv *versioned.KV + edge map[id.ID]Preimages + callbacks map[id.ID][]ListUpdateCallBack + mux *sync.RWMutex +} + +// NewStore creates a new edge store object and inserts the default +// Preimages for the base identity +func NewStore(kv *versioned.KV, baseIdentity *id.ID)(*Store, error){ + kv = kv.Prefix(edgeStorePrefix) + + s := &Store{ + kv: kv, + edge: make(map[id.ID]Preimages), + } + + defaultPreimages := newPreimages(baseIdentity) + err := defaultPreimages.save(kv,baseIdentity) + if err!=nil{ + return nil, errors.WithMessage(err,"Failed to create preimage store, " + + "failed to create default Preimages") + } + + s.edge[*baseIdentity] = defaultPreimages + + return s, s.save() +} + +func LoadStore(kv *versioned.KV)(*Store, error){ + kv = kv.Prefix(edgeStorePrefix) + + //load the list of identities with preimage lists + obj, err := kv.Get(edgeStoreKey, preimageStoreVersion) + if err != nil { + return nil, errors.WithMessagef(err,"failed to load edge " + + "store") + } + + identities := make([]id.ID, 0) + + err = json.Unmarshal(obj.Data, &identities) + if err != nil { + return nil, errors.WithMessagef(err,"failed to unmarshal edge " + + "store") + } + + s := &Store{ + kv: kv, + edge: make(map[id.ID]Preimages), + } + + //load the preimage lists for all identities + for i := range identities{ + eid := &identities[i] + pimgs, err := loadPreimages(kv,eid) + if err!=nil{ + return nil, err + } + s.edge[*eid] = pimgs + } + + return s, nil +} + +func (s *Store)Add(preimage Preimage, identity *id.ID){ + s.mux.Lock() + defer s.mux.Unlock() + + //get the list to update, create if needed + pimgs, exists := s.edge[*identity] + if !exists{ + pimgs = newPreimages(identity) + } + + //add to the list + pimgs = pimgs.add(preimage) + + //store the updated list + if err := pimgs.save(s.kv,identity); err!=nil{ + jww.FATAL.Panicf("Failed to store preimages list after " + + "adding preimage %v to identity %s: %+v", preimage.Data, identity, err) + } + + //update the map + s.edge[*identity] = pimgs + if !exists{ + err := s.save() + if err!=nil{ + jww.FATAL.Panicf("Failed to store edge store after " + + "adding preimage %v to identity %s: %+v", preimage.Data, identity, err) + } + } + + //call any callbacks to notify + for i := range s.callbacks[*identity]{ + cb := s.callbacks[*identity][i] + go cb(identity, false) + } + return +} + +func (s *Store)Remove(preimage Preimage, identity *id.ID)error{ + s.mux.Lock() + defer s.mux.Unlock() + + pimgs, exists := s.edge[*identity] + if !exists{ + return errors.Errorf("Cannot delete preimage %v from " + + "identity %s, identity cannot be found", preimage.Data, identity) + } + pimgsNew := pimgs.remove(preimage.Data) + if len(pimgsNew)==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 := pimgsNew.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) + } + //call any callbacks to notify + for i := range s.callbacks[*identity]{ + cb := s.callbacks[*identity][i] + go cb(identity, true) + } + return nil + } + + if err := pimgsNew.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] = pimgsNew + + //call any callbacks to notify + for i := range s.callbacks[*identity]{ + cb := s.callbacks[*identity][i] + go cb(identity, false) + } + return nil +} + + +func (s *Store)Get(identity *id.ID)([]Preimage, bool){ + s.mux.RLock() + defer s.mux.RUnlock() + primgs, exists := s.edge[*identity] + return primgs, exists +} + +func (s *Store)AddUpdateCallback(identity *id.ID, lucb ListUpdateCallBack){ + s.mux.Lock() + defer s.mux.Unlock() + list, exists := s.callbacks[*identity] + if !exists{ + list = make([]ListUpdateCallBack, 0, 1) + } + s.callbacks[*identity] = append(list, lucb) +} + +func (s Store)save()error{ + identities := make([]id.ID, 0, len(s.edge)) + + for eid, _ := range s.edge{ + identities = append(identities, eid) + } + + //marshal + data, err := json.Marshal(&identities) + if err!=nil{ + return errors.WithMessagef(err, "Failed to marshal edge list " + + "for stroage") + } + + // Construct versioning object + obj := versioned.Object{ + Version: edgeStoreVersion, + Timestamp: netTime.Now(), + Data: data, + } + + // Save to storage + err = s.kv.Set(edgeStoreKey, preimageStoreVersion, &obj) + if err != nil { + return errors.WithMessagef(err, "Failed to store edge list") + } + + return nil +} \ No newline at end of file diff --git a/storage/edge/preimage.go b/storage/edge/preimage.go new file mode 100644 index 0000000000000000000000000000000000000000..24aa121b37191b67c90d018dbee35075d73648e2 --- /dev/null +++ b/storage/edge/preimage.go @@ -0,0 +1,120 @@ +package edge + +import ( + "bytes" + "encoding/json" + "fmt" + "github.com/pkg/errors" + "gitlab.com/elixxir/client/storage/versioned" + "gitlab.com/xx_network/primitives/id" + "gitlab.com/xx_network/primitives/netTime" +) + + +const ( + preimageStoreKey = "preimageStoreKey" + preimageStoreVersion = 0 +) + +type Preimage struct{ + Data []byte + Type string + Source []byte +} + +type Preimages []Preimage + +// 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 { + var pis Preimages + pis = append(pis, Preimage{ + Data: identity[:], + Type: "default", + Source: identity[:], + }) + return pis +} + +//loads a Preimages object for the given identity +func loadPreimages(kv *versioned.KV, identity *id.ID)(Preimages, error){ + + // Get the data from the kv + obj, err := kv.Get(preimageKey(identity), preimageStoreVersion) + if err != nil { + return nil, errors.WithMessagef(err,"failed to load edge " + + "Preimages for identity %s", identity) + } + + var preimageList Preimages + + err = json.Unmarshal(obj.Data, &preimageList) + if err != nil { + return nil, errors.WithMessagef(err,"failed to unmarshal edge " + + "Preimages for identity %s", identity) + } + + return preimageList, nil +} + +//stores the preimage list to disk +func (pis Preimages)save(kv *versioned.KV, identity *id.ID)error{ + //marshal + data, err := json.Marshal(&pis) + if err!=nil{ + return errors.WithMessagef(err, "Failed to marshal Preimages list " + + "for stroage for identity %s", identity) + } + + // Construct versioning object + obj := versioned.Object{ + Version: preimageStoreVersion, + Timestamp: netTime.Now(), + Data: data, + } + + // Save to storage + err = kv.Set(preimageKey(identity), preimageStoreVersion, &obj) + if err != nil { + return errors.WithMessagef(err, "Failed to store Preimages list " + + "for identity %s", identity) + } + + return nil +} + +//adds the preimage to the +func (pis Preimages)add(pimg Preimage) Preimages { + return append(pis,pimg) +} + +func (pis Preimages)remove(data []byte) Preimages { + + for i:=0;i<len(pis);i++{ + if bytes.Equal(pis[i].Data,data){ + pis[i] = pis[len(pis)-1] + return pis[:len(pis)-1] + } + } + + return pis +} + +func (pis Preimages)delete(kv *versioned.KV, identity *id.ID)error{ + + // Save to storage + err := kv.Delete(preimageKey(identity), preimageStoreVersion) + if err != nil { + return errors.WithMessagef(err, "Failed to delete Preimages list " + + "for identity %s", identity) + } + + return nil +} + +func preimageKey(identity *id.ID)string{ + return fmt.Sprintf("%s:%s",preimageStoreKey,identity) +} + + diff --git a/storage/session.go b/storage/session.go index fd98a85c22e1d1c3aea073ad3d1d9d6a709c6e1c..e43ddac37f0cf7558d67061f707ba5fcce5e5257 100644 --- a/storage/session.go +++ b/storage/session.go @@ -10,6 +10,7 @@ package storage import ( + "gitlab.com/elixxir/client/storage/edge" "gitlab.com/elixxir/client/storage/hostList" "gitlab.com/elixxir/client/storage/rounds" "sync" @@ -68,6 +69,7 @@ type Session struct { clientVersion *clientVersion.Store uncheckedRounds *rounds.UncheckedRoundStore hostList *hostList.Store + edgeCheck *edge.Store } // Initialize a new Session object @@ -154,6 +156,10 @@ func New(baseDir, password string, u userInterface.User, currentVersion version. s.hostList = hostList.NewStore(s.kv) + s.edgeCheck, err = edge.NewStore(s.kv,u.ReceptionID) + if err != nil { + return nil, errors.WithMessage(err, "Failed to edge check store") + } return s, nil } @@ -232,6 +238,11 @@ func Load(baseDir, password string, currentVersion version.Version, s.hostList = hostList.NewStore(s.kv) + s.edgeCheck, err = edge.LoadStore(s.kv) + if err!=nil{ + return nil, errors.WithMessage(err, "Failed to load edge check store") + } + return s, nil } @@ -314,6 +325,13 @@ func (s *Session) HostList() *hostList.Store { return s.hostList } +// GetEdge returns the edge preimage store. +func (s *Session) GetEdge() *edge.Store { + s.mux.RLock() + defer s.mux.RUnlock() + return s.edgeCheck +} + // Get an object from the session func (s *Session) Get(key string) (*versioned.Object, error) { return s.kv.Get(key, currentSessionVersion)