From cd51036d04ef487ab47431d3fd27ab26c6194abb Mon Sep 17 00:00:00 2001
From: "Richard T. Carback III" <rick.carback@gmail.com>
Date: Mon, 18 Jul 2022 20:33:27 +0000
Subject: [PATCH] add a V0 upgrade path for previous negotiations... there are
 other components that may also need anupgrade path here

---
 auth/store/previousNegotiations.go | 54 +++++++++++++++++++++++++++---
 1 file changed, 50 insertions(+), 4 deletions(-)

diff --git a/auth/store/previousNegotiations.go b/auth/store/previousNegotiations.go
index 6b0c0d6dd..30aa710d7 100644
--- a/auth/store/previousNegotiations.go
+++ b/auth/store/previousNegotiations.go
@@ -12,17 +12,18 @@ import (
 	"encoding/base64"
 	"encoding/binary"
 	"encoding/json"
+	"strings"
+
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/storage/versioned"
 	"gitlab.com/elixxir/crypto/e2e/auth"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
-	"strings"
 )
 
 const (
 	negotiationPartnersKey                = "NegotiationPartners"
-	negotiationPartnersVersion            = 0
+	negotiationPartnersVersion            = 1
 	negotiationFingerprintsKeyPrefix      = "NegotiationFingerprints/"
 	currentNegotiationFingerprintsVersion = 0
 )
@@ -125,9 +126,11 @@ func (s *Store) newOrLoadPreviousNegotiations() (map[id.ID]bool, error) {
 			obj := &versioned.Object{
 				Version:   negotiationPartnersVersion,
 				Timestamp: netTime.Now(),
-				Data:      marshalPreviousNegotiations(newPreviousNegotiations),
+				Data: marshalPreviousNegotiations(
+					newPreviousNegotiations),
 			}
-			err = s.kv.Set(negotiationPartnersKey, negotiationPartnersVersion, obj)
+			err = s.kv.Set(negotiationPartnersKey,
+				negotiationPartnersVersion, obj)
 			if err != nil {
 				return nil, err
 			}
@@ -136,6 +139,26 @@ func (s *Store) newOrLoadPreviousNegotiations() (map[id.ID]bool, error) {
 		return nil, err
 	}
 
+	// Upgrade V0 entries
+	if obj.Version == 0 {
+		old := unmarshalPreviousNegotiationsV0(obj.Data)
+		newPrevNegotiations := make(map[id.ID]bool)
+		for id := range old {
+			newPrevNegotiations[id] = true
+		}
+		obj := &versioned.Object{
+			Version:   negotiationPartnersVersion,
+			Timestamp: netTime.Now(),
+			Data: marshalPreviousNegotiations(
+				newPrevNegotiations),
+		}
+		err = s.kv.Set(negotiationPartnersKey,
+			negotiationPartnersVersion, obj)
+		if err != nil {
+			return nil, err
+		}
+	}
+
 	return unmarshalPreviousNegotiations(obj.Data)
 }
 
@@ -242,3 +265,26 @@ func makeNegotiationFingerprintsKey(partner *id.ID) string {
 	return negotiationFingerprintsKeyPrefix +
 		string(base64.StdEncoding.EncodeToString(partner.Marshal()))
 }
+
+// Historical functions
+
+// unmarshalPreviousNegotiations unmarshalls the marshalled byte slice into a
+// list of partner IDs.
+func unmarshalPreviousNegotiationsV0(buf []byte) map[id.ID]struct{} {
+	buff := bytes.NewBuffer(buf)
+
+	numberOfPartners := binary.LittleEndian.Uint64(buff.Next(8))
+	partners := make(map[id.ID]struct{}, numberOfPartners)
+
+	for i := uint64(0); i < numberOfPartners; i++ {
+		partner, err := id.Unmarshal(buff.Next(id.ArrIDLen))
+		if err != nil {
+			jww.FATAL.Panicf(
+				"Failed to unmarshal negotiation partner ID: %+v", err)
+		}
+
+		partners[*partner] = struct{}{}
+	}
+
+	return partners
+}
-- 
GitLab