diff --git a/Makefile b/Makefile
index bd6383ff69c75244eaf1b62ef3cc9c0fb91c5154..7cd635a516d953f796d6073610b0f4d6693e00db 100644
--- a/Makefile
+++ b/Makefile
@@ -20,12 +20,12 @@ build:
 	go mod tidy
 
 update_release:
-	GOFLAGS="" go get -u gitlab.com/xx_network/primitives@release
-	GOFLAGS="" go get -u gitlab.com/elixxir/primitives@release
-	GOFLAGS="" go get -u gitlab.com/xx_network/crypto@release
-	GOFLAGS="" go get -u gitlab.com/elixxir/crypto@release
-	GOFLAGS="" go get -u gitlab.com/xx_network/comms@release
-	GOFLAGS="" go get -u gitlab.com/elixxir/comms@release
+	GOFLAGS="" go get gitlab.com/xx_network/primitives@release
+	GOFLAGS="" go get gitlab.com/elixxir/primitives@release
+	GOFLAGS="" go get gitlab.com/xx_network/crypto@release
+	GOFLAGS="" go get gitlab.com/elixxir/crypto@release
+	GOFLAGS="" go get gitlab.com/xx_network/comms@release
+	GOFLAGS="" go get gitlab.com/elixxir/comms@release
 
 update_master:
 	GOFLAGS="" go get gitlab.com/xx_network/primitives@master
@@ -35,6 +35,6 @@ update_master:
 	GOFLAGS="" go get gitlab.com/xx_network/comms@master
 	GOFLAGS="" go get gitlab.com/elixxir/comms@master
 
-master: clean update_master build version
+master: update_master clean build version
 
-release: clean update_release build version
+release: update_release clean build version
diff --git a/api/version_vars.go b/api/version_vars.go
index 75d1adeef89b0d9ed44699e42d0bb7e6306fbbb6..ca2d8ad8f10537b86812b3f19044bfcac0d65aa3 100644
--- a/api/version_vars.go
+++ b/api/version_vars.go
@@ -1,10 +1,10 @@
 // Code generated by go generate; DO NOT EDIT.
 // This file was generated by robots at
-// 2021-05-07 09:33:37.4750421 -0700 PDT m=+0.043142701
+// 2021-05-14 10:03:16.0139753 -0700 PDT m=+0.207946701
 package api
 
-const GITVERSION = `51fdae45 made stop network follower always allow restart`
-const SEMVER = "2.5.0"
+const GITVERSION = `88379de9 Merge branch 'release' of gitlab.com:elixxir/client into XX-3278/fixTimestampSizeInE2eMessage`
+const SEMVER = "2.6.0"
 const DEPENDENCIES = `module gitlab.com/elixxir/client
 
 go 1.13
@@ -28,7 +28,7 @@ require (
 	gitlab.com/elixxir/crypto v0.0.7-0.20210506223047-3196e4301110
 	gitlab.com/elixxir/ekv v0.1.5
 	gitlab.com/elixxir/primitives v0.0.3-0.20210504210415-34cf31c2816e
-	gitlab.com/xx_network/comms v0.0.4-0.20210505205155-48daa8448ad7
+	gitlab.com/xx_network/comms v0.0.4-0.20210507215532-38ed97bd9365
 	gitlab.com/xx_network/crypto v0.0.5-0.20210504210244-9ddabbad25fd
 	gitlab.com/xx_network/primitives v0.0.4-0.20210504205835-db68f11de78a
 	golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
diff --git a/cmd/version.go b/cmd/version.go
index 67b545b53c3ed7e36e85abccbeadf817bc52dc25..68e3f78210a7de2e059d35d4a877204fc1c56f38 100644
--- a/cmd/version.go
+++ b/cmd/version.go
@@ -18,7 +18,7 @@ import (
 )
 
 // Change this value to set the version for this build
-const currentVersion = "2.5.0"
+const currentVersion = "2.6.0"
 
 func Version() string {
 	out := fmt.Sprintf("Elixxir Client v%s -- %s\n\n", api.SEMVER,
diff --git a/go.mod b/go.mod
index 7142c43f2d9fa81eacd6878befdc445e5d8f8a1f..cbfed7d5389b4db18f6e83ce6a832d0f17cce7da 100644
--- a/go.mod
+++ b/go.mod
@@ -21,7 +21,7 @@ require (
 	gitlab.com/elixxir/crypto v0.0.7-0.20210506223047-3196e4301110
 	gitlab.com/elixxir/ekv v0.1.5
 	gitlab.com/elixxir/primitives v0.0.3-0.20210504210415-34cf31c2816e
-	gitlab.com/xx_network/comms v0.0.4-0.20210505205155-48daa8448ad7
+	gitlab.com/xx_network/comms v0.0.4-0.20210507215532-38ed97bd9365
 	gitlab.com/xx_network/crypto v0.0.5-0.20210504210244-9ddabbad25fd
 	gitlab.com/xx_network/primitives v0.0.4-0.20210504205835-db68f11de78a
 	golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
diff --git a/go.sum b/go.sum
index c02d426f81e92c2cecddcaabb483586a412caa9e..ac55a9633bfd5d22a5ac7b040a45cde945743035 100644
--- a/go.sum
+++ b/go.sum
@@ -253,18 +253,12 @@ github.com/zeebo/pcg v1.0.0 h1:dt+dx+HvX8g7Un32rY9XWoYnd0NmKmrIzpHF7qiTDj0=
 github.com/zeebo/pcg v1.0.0/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
 gitlab.com/elixxir/bloomfilter v0.0.0-20200930191214-10e9ac31b228 h1:Gi6rj4mAlK0BJIk1HIzBVMjWNjIUfstrsXC2VqLYPcA=
 gitlab.com/elixxir/bloomfilter v0.0.0-20200930191214-10e9ac31b228/go.mod h1:H6jztdm0k+wEV2QGK/KYA+MY9nj9Zzatux/qIvDDv3k=
-gitlab.com/elixxir/comms v0.0.4-0.20210505205202-1d4c18a7fcb2 h1:8aL4V7FaKkDb5iPdJ1rlFFhrHrLWUtbmBjw4BysXzEA=
-gitlab.com/elixxir/comms v0.0.4-0.20210505205202-1d4c18a7fcb2/go.mod h1:VN0fNE7GFMrkZwRGnqA7fNNRAXDA4CCP6su/FQQ68RI=
-gitlab.com/elixxir/comms v0.0.4-0.20210506161214-6371db79ce6f h1:0hvU+6Y+JGFnBu8ZSMk0ukNuYg+GAnVKD8Yo4VwSdao=
-gitlab.com/elixxir/comms v0.0.4-0.20210506161214-6371db79ce6f/go.mod h1:7ff+A4Nom55mKiRW7qWsN7LDjGay4OZwiaaIVXZ4hdk=
 gitlab.com/elixxir/comms v0.0.4-0.20210506225017-37485f5ba063 h1:9A2FT1IDzb9E0HaEEcRMAZEVRM4SMXpklYvS6owSyIk=
 gitlab.com/elixxir/comms v0.0.4-0.20210506225017-37485f5ba063/go.mod h1:KHV+lNKhcsXoor1KQizUHhCuHugnquldrAR8UU5PNKU=
 gitlab.com/elixxir/crypto v0.0.0-20200804182833-984246dea2c4 h1:28ftZDeYEko7xptCZzeFWS1Iam95dj46TWFVVlKmw6A=
 gitlab.com/elixxir/crypto v0.0.0-20200804182833-984246dea2c4/go.mod h1:ucm9SFKJo+K0N2GwRRpaNr+tKXMIOVWzmyUD0SbOu2c=
 gitlab.com/elixxir/crypto v0.0.3 h1:znCt/x2bL4y8czTPaaFkwzdgSgW3BJc/1+dxyf1jqVw=
 gitlab.com/elixxir/crypto v0.0.3/go.mod h1:ZNgBOblhYToR4m8tj4cMvJ9UsJAUKq+p0gCp07WQmhA=
-gitlab.com/elixxir/crypto v0.0.7-0.20210504210535-3077ddf9984d h1:E16E+gM2jJosFc8YmT2ISGxcfBThG2KAgsAcQXtxSIc=
-gitlab.com/elixxir/crypto v0.0.7-0.20210504210535-3077ddf9984d/go.mod h1:pbq80k+R7XXvjyWDqanD2eCJi1ClfESdKS0K8NndoLs=
 gitlab.com/elixxir/crypto v0.0.7-0.20210506223047-3196e4301110 h1:4KWUbx1RI5TABBM2omWl5MLW16dwySglz895X2rhSFQ=
 gitlab.com/elixxir/crypto v0.0.7-0.20210506223047-3196e4301110/go.mod h1:pbq80k+R7XXvjyWDqanD2eCJi1ClfESdKS0K8NndoLs=
 gitlab.com/elixxir/ekv v0.1.5 h1:R8M1PA5zRU1HVnTyrtwybdABh7gUJSCvt1JZwUSeTzk=
@@ -277,9 +271,10 @@ gitlab.com/elixxir/primitives v0.0.1/go.mod h1:kNp47yPqja2lHSiS4DddTvFpB/4D9dB2Y
 gitlab.com/elixxir/primitives v0.0.3-0.20210504210415-34cf31c2816e h1:6Z5qAqI/xoWYPMVcItUDYEkOe84YWS1FJa+qjWGcJ2c=
 gitlab.com/elixxir/primitives v0.0.3-0.20210504210415-34cf31c2816e/go.mod h1:4pNgiFEQQ11hHCXBRQJN1w9AIuKa1HTlPTxs9UYOXFA=
 gitlab.com/xx_network/comms v0.0.0-20200805174823-841427dd5023/go.mod h1:owEcxTRl7gsoM8c3RQ5KAm5GstxrJp5tn+6JfQ4z5Hw=
-gitlab.com/xx_network/comms v0.0.4-0.20210505204621-a93ded09b1ff/go.mod h1:RkNZ0CjeXKRhEFdUeAdCAF6QuK8sO1j2bUg9oqK0OEA=
 gitlab.com/xx_network/comms v0.0.4-0.20210505205155-48daa8448ad7 h1:0oQfe8YZ51kYKEj1w9UN2ls0Kp2AHRO6CUbkF/T/UH4=
 gitlab.com/xx_network/comms v0.0.4-0.20210505205155-48daa8448ad7/go.mod h1:RkNZ0CjeXKRhEFdUeAdCAF6QuK8sO1j2bUg9oqK0OEA=
+gitlab.com/xx_network/comms v0.0.4-0.20210507215532-38ed97bd9365 h1:VjeUUy4hcc2uTOO5qZ0roJlGHySWJxN/G7bf1VnLfFM=
+gitlab.com/xx_network/comms v0.0.4-0.20210507215532-38ed97bd9365/go.mod h1:RkNZ0CjeXKRhEFdUeAdCAF6QuK8sO1j2bUg9oqK0OEA=
 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/message/garbled_test.go b/network/message/garbled_test.go
index 9d021ae488ed26717aade2d76d87ba688c7f9001..ab4919f16d674ea10a609ca6d0e46a442259789f 100644
--- a/network/message/garbled_test.go
+++ b/network/message/garbled_test.go
@@ -105,6 +105,7 @@ func TestManager_CheckGarbledMessages(t *testing.T) {
 	contents := make([]byte, msg.ContentsSize())
 	prng := rand.New(rand.NewSource(42))
 	prng.Read(contents)
+	contents[len(contents)-1] = 0
 	fmp := parse.FirstMessagePartFromBytes(contents)
 	binary.BigEndian.PutUint32(fmp.Type, uint32(message.Raw))
 	fmp.NumParts[0] = uint8(1)
diff --git a/network/message/parse/firstMessagePart.go b/network/message/parse/firstMessagePart.go
index 958a386992f161f007921476f52eb9749ea628bf..fa67b64411e0f2272178452eeb0a8deb91612271 100644
--- a/network/message/parse/firstMessagePart.go
+++ b/network/message/parse/firstMessagePart.go
@@ -9,92 +9,123 @@ package parse
 
 import (
 	"encoding/binary"
-	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/interfaces/message"
 	"time"
 )
 
-const numPartsLen = 1
-const typeLen = message.TypeLen
-const timestampLen = 15
-const firstHeaderLen = headerLen + numPartsLen + typeLen + timestampLen
+// Sizes of message parts, in bytes.
+const (
+	numPartsLen     = 1
+	typeLen         = message.TypeLen
+	timestampLen    = 8
+	firstPartVerLen = 1
+	firstHeaderLen  = headerLen + numPartsLen + typeLen + timestampLen + firstPartVerLen
+)
+
+// The current version of the firstMessagePart message format.
+const firstMessagePartCurrentVersion = 0
 
 type firstMessagePart struct {
 	messagePart
 	NumParts  []byte
 	Type      []byte
 	Timestamp []byte
+	Version   []byte // Version of the message format; always the last bit
 }
 
-//creates a new first message part for the passed in contents. Does no length checks
+// newFirstMessagePart creates a new firstMessagePart for the passed in
+// contents. Does no length checks.
 func newFirstMessagePart(mt message.Type, id uint32, numParts uint8,
 	timestamp time.Time, contents []byte) firstMessagePart {
-	//create the message structure
-	data := make([]byte, len(contents)+firstHeaderLen)
-	m := FirstMessagePartFromBytes(data)
 
-	//Put the message type in the message
+	// Create the message structure
+	m := FirstMessagePartFromBytes(make([]byte, len(contents)+firstHeaderLen))
+
+	// Set the message type
 	binary.BigEndian.PutUint32(m.Type, uint32(mt))
 
-	//Add the message ID
+	// Set the message ID
 	binary.BigEndian.PutUint32(m.Id, id)
 
-	// Add the part number to the message, its always zero because this is the
-	// first part. Because the default is zero this step could be skipped, but\
-	// keep it in the code for clarity
+	// Set the part number. It is always zero because this is the first part.
+	// Because the default is zero this step could be skipped, but keep it in
+	// the code for clarity.
 	m.Part[0] = 0
 
-	// Add the number of parts to the message
+	// Set the number of parts to the message
 	m.NumParts[0] = numParts
 
-	//Serialize and add the timestamp to the payload
-	timestampBytes, err := timestamp.MarshalBinary()
-	if err != nil {
-		jww.FATAL.Panicf("Failed to create firstMessagePart: %s", err.Error())
-	}
-	copy(m.Timestamp, timestampBytes)
+	// Set the timestamp as unix nano
+	binary.BigEndian.PutUint64(m.Timestamp, uint64(timestamp.UnixNano()))
 
-	//set the contents length
+	// Set the length of the contents
 	binary.BigEndian.PutUint16(m.Len, uint16(len(contents)))
 
-	//add the contents to the payload
+	// Set the contents
 	copy(m.Contents[:len(contents)], contents)
 
+	// Set the version number
+	m.Version[0] = firstMessagePartCurrentVersion
+
 	return m
 }
 
-// Builds a first message part mapped to the passed in data slice. Mapped by
-// reference, a copy is not made.
+// Map of firstMessagePart encoding version numbers to their map functions.
+var firstMessagePartFromBytesVersions = map[uint8]func([]byte) firstMessagePart{
+	firstMessagePartCurrentVersion: firstMessagePartFromBytesVer0,
+}
+
+// FirstMessagePartFromBytes builds a firstMessagePart mapped to the passed in
+// data slice. Mapped by reference; a copy is not made.
 func FirstMessagePartFromBytes(data []byte) firstMessagePart {
-	m := firstMessagePart{
+
+	// Map the data according to its version
+	version := data[len(data)-1]
+	mapFunc, exists := firstMessagePartFromBytesVersions[version]
+	if exists {
+		return mapFunc(data)
+	}
+
+	return firstMessagePart{}
+}
+
+func firstMessagePartFromBytesVer0(data []byte) firstMessagePart {
+	return firstMessagePart{
 		messagePart: messagePart{
 			Data:     data,
 			Id:       data[:idLen],
 			Part:     data[idLen : idLen+partLen],
 			Len:      data[idLen+partLen : idLen+partLen+lenLen],
-			Contents: data[idLen+partLen+numPartsLen+typeLen+timestampLen+lenLen:],
+			Contents: data[idLen+partLen+lenLen+numPartsLen+typeLen+timestampLen : len(data)-firstPartVerLen-1],
 		},
-		NumParts:  data[idLen+partLen+lenLen : idLen+partLen+numPartsLen+lenLen],
-		Type:      data[idLen+partLen+numPartsLen+lenLen : idLen+partLen+numPartsLen+typeLen+lenLen],
-		Timestamp: data[idLen+partLen+numPartsLen+typeLen+lenLen : idLen+partLen+numPartsLen+typeLen+timestampLen+lenLen],
+		NumParts:  data[idLen+partLen+lenLen : idLen+partLen+lenLen+numPartsLen],
+		Type:      data[idLen+partLen+lenLen+numPartsLen : idLen+partLen+lenLen+numPartsLen+typeLen],
+		Timestamp: data[idLen+partLen+lenLen+numPartsLen+typeLen : idLen+partLen+lenLen+numPartsLen+typeLen+timestampLen],
+		Version:   data[len(data)-firstPartVerLen:],
 	}
-	return m
 }
 
+// GetType returns the message type.
 func (m firstMessagePart) GetType() message.Type {
 	return message.Type(binary.BigEndian.Uint32(m.Type))
 }
 
+// GetNumParts returns the number of message parts.
 func (m firstMessagePart) GetNumParts() uint8 {
 	return m.NumParts[0]
 }
 
-func (m firstMessagePart) GetTimestamp() (time.Time, error) {
-	var t time.Time
-	err := t.UnmarshalBinary(m.Timestamp)
-	return t, err
+// GetTimestamp returns the timestamp as a time.Time.
+func (m firstMessagePart) GetTimestamp() time.Time {
+	return time.Unix(0, int64(binary.BigEndian.Uint64(m.Timestamp)))
+}
+
+// GetVersion returns the version number of the data encoding.
+func (m firstMessagePart) GetVersion() uint8 {
+	return m.Version[0]
 }
 
+// Bytes returns the serialised message data.
 func (m firstMessagePart) Bytes() []byte {
 	return m.Data
 }
diff --git a/network/message/parse/firstMessagePart_test.go b/network/message/parse/firstMessagePart_test.go
index 676723247fec562607d43f9a29dec827890c76a8..2411dd4a6896453f08d2fd02ae2dd15946f0f76c 100644
--- a/network/message/parse/firstMessagePart_test.go
+++ b/network/message/parse/firstMessagePart_test.go
@@ -18,16 +18,19 @@ import (
 // Expected firstMessagePart for checking against, generated by fmp in TestNewFirstMessagePart
 var efmp = firstMessagePart{
 	messagePart: messagePart{
-		Data: []byte{0, 0, 4, 53, 0, 0, 13, 2, 0, 0, 0, 2, 1, 0, 0, 0, 14, 215, 133, 90, 117, 0, 0, 0, 0, 255, 255,
-			116, 101, 115, 116, 105, 110, 103, 115, 116, 114, 105, 110, 103},
-		Id:       []byte{0, 0, 4, 53},
-		Part:     []byte{0},
-		Len:      []byte{0, 13},
-		Contents: []byte{116, 101, 115, 116, 105, 110, 103, 115, 116, 114, 105, 110, 103},
+		Data: []byte{0, 0, 4, 53, 0, 0, 13, 2, 0, 0, 0, 2, 22, 87, 28, 11, 215,
+			220, 82, 0, 116, 101, 115, 116, 105, 110, 103, 115, 116, 114, 105,
+			110, 103, 0, firstMessagePartCurrentVersion},
+		Id:   []byte{0, 0, 4, 53},
+		Part: []byte{0},
+		Len:  []byte{0, 13},
+		Contents: []byte{116, 101, 115, 116, 105, 110, 103, 115, 116, 114, 105,
+			110, 103},
 	},
 	NumParts:  []byte{2},
 	Type:      []byte{0, 0, 0, 2},
-	Timestamp: []byte{1, 0, 0, 0, 14, 215, 133, 90, 117, 0, 0, 0, 0, 255, 255},
+	Timestamp: []byte{22, 87, 28, 11, 215, 220, 82, 0},
+	Version:   []byte{firstMessagePartCurrentVersion},
 }
 
 // Test that newFirstMessagePart returns a correctly made firstMessagePart
@@ -37,24 +40,19 @@ func TestNewFirstMessagePart(t *testing.T) {
 		1077,
 		2,
 		time.Unix(1609786229, 0).UTC(),
-		[]byte{'t', 'e', 's', 't', 'i', 'n', 'g',
-			's', 't', 'r', 'i', 'n', 'g'},
+		[]byte{'t', 'e', 's', 't', 'i', 'n', 'g', 's', 't', 'r', 'i', 'n', 'g'},
 	)
 
-	gotTime, err := fmp.GetTimestamp()
-	if err != nil {
-		t.Error(err)
-	}
-	expectedTime, err := fmp.GetTimestamp()
-	if err != nil {
-		t.Error(err)
-	}
+	gotTime := fmp.GetTimestamp()
+	expectedTime := time.Unix(1609786229, 0).UTC()
 	if !gotTime.Equal(expectedTime) {
-		t.Errorf("Got time: %v, expected time: %v", gotTime, expectedTime)
+		t.Errorf("Failed to get expected timestamp."+
+			"\nexpected: %s\nreceived: %s", expectedTime, gotTime)
 	}
 
 	if !reflect.DeepEqual(fmp, efmp) {
-		t.Errorf("Expected and got firstMessagePart did not match.\n\tGot: %#v\n\tExpected: %#v", fmp, efmp)
+		t.Errorf("Expected and got firstMessagePart did not match."+
+			"\nexpected: %+v\nrecieved: %+v", efmp, fmp)
 	}
 }
 
@@ -83,10 +81,7 @@ func TestFirstMessagePart_GetNumParts(t *testing.T) {
 
 // Test that GetTimestamp returns the correct timestamp for a firstMessagePart
 func TestFirstMessagePart_GetTimestamp(t *testing.T) {
-	et, err := efmp.GetTimestamp()
-	if err != nil {
-		t.Error(err)
-	}
+	et := efmp.GetTimestamp()
 	if !time.Unix(1609786229, 0).Equal(et) {
 		t.Errorf("Got %v, expected %v", et, time.Unix(1609786229, 0))
 	}
diff --git a/network/message/parse/messagePart.go b/network/message/parse/messagePart.go
index 815544be80370e2c4f66482c903ae0cbe9e9ad92..01c514d7c33fe1654534a67aeaf8671744d93982 100644
--- a/network/message/parse/messagePart.go
+++ b/network/message/parse/messagePart.go
@@ -11,10 +11,17 @@ import (
 	"encoding/binary"
 )
 
-const idLen = 4
-const partLen = 1
-const lenLen = 2
-const headerLen = idLen + partLen + lenLen
+// Sizes of message parts, in bytes.
+const (
+	idLen      = 4
+	partLen    = 1
+	lenLen     = 2
+	partVerLen = 1
+	headerLen  = idLen + partLen + lenLen + partVerLen
+)
+
+// The current version of the messagePart message format.
+const messagePartCurrentVersion = 0
 
 type messagePart struct {
 	Data     []byte
@@ -22,62 +29,90 @@ type messagePart struct {
 	Part     []byte
 	Len      []byte
 	Contents []byte
+	Version  []byte // Version of the message format; always the last bit
 }
 
-//creates a new message part for the passed in contents. Does no length checks
+// newMessagePart creates a new messagePart for the passed in contents. Does no
+// length checks.
 func newMessagePart(id uint32, part uint8, contents []byte) messagePart {
-	//create the message structure
+	// Create the message structure
 	data := make([]byte, len(contents)+headerLen)
-	m := MessagePartFromBytes(data)
+	m := messagePartFromBytes(data)
 
-	//add the message ID to the message
+	// Set the message ID
 	binary.BigEndian.PutUint32(m.Id, id)
 
-	//set the message part number
+	// Set the message part number
 	m.Part[0] = part
 
-	//set the contents length
+	// Set the contents length
 	binary.BigEndian.PutUint16(m.Len, uint16(len(contents)))
 
-	//copy the contents into the message
+	// Copy the contents into the message
 	copy(m.Contents[:len(contents)], contents)
+
+	// Set the version number
+	m.Version[0] = messagePartCurrentVersion
+
 	return m
 }
 
-// Builds a Message part mapped to the passed in data slice. Mapped by
-// reference, a copy is not made.
-func MessagePartFromBytes(data []byte) messagePart {
-	m := messagePart{
+// Map of messagePart encoding version numbers to their map functions.
+var messagePartFromBytesVersions = map[uint8]func([]byte) messagePart{
+	messagePartCurrentVersion: messagePartFromBytesVer0,
+}
+
+// messagePartFromBytes builds a messagePart mapped to the passed in data slice.
+// Mapped by reference; a copy is not made.
+func messagePartFromBytes(data []byte) messagePart {
+
+	// Map the data according to its version
+	version := data[len(data)-1]
+	mapFunc, exists := messagePartFromBytesVersions[version]
+	if exists {
+		return mapFunc(data)
+	}
+
+	return messagePart{}
+}
+
+func messagePartFromBytesVer0(data []byte) messagePart {
+	return messagePart{
 		Data:     data,
 		Id:       data[:idLen],
 		Part:     data[idLen : idLen+partLen],
 		Len:      data[idLen+partLen : idLen+partLen+lenLen],
-		Contents: data[idLen+partLen+lenLen:],
+		Contents: data[idLen+partLen+lenLen : len(data)-partVerLen],
+		Version:  data[len(data)-partVerLen:],
 	}
-	return m
 }
 
+// GetID returns the message ID.
 func (m messagePart) GetID() uint32 {
 	return binary.BigEndian.Uint32(m.Id)
 }
 
+// GetPart returns the message part number.
 func (m messagePart) GetPart() uint8 {
 	return m.Part[0]
 }
 
+// GetContents returns the entire contents slice.
 func (m messagePart) GetContents() []byte {
 	return m.Contents
 }
 
+// GetSizedContents returns the contents truncated to include only stored data.
 func (m messagePart) GetSizedContents() []byte {
-	size := m.GetContentsLength()
-	return m.Contents[:size]
+	return m.Contents[:m.GetContentsLength()]
 }
 
+// GetContentsLength returns the length of the data in the contents.
 func (m messagePart) GetContentsLength() int {
 	return int(binary.BigEndian.Uint16(m.Len))
 }
 
+// Bytes returns the serialised message data.
 func (m messagePart) Bytes() []byte {
 	return m.Data
 }
diff --git a/network/message/parse/messagePart_test.go b/network/message/parse/messagePart_test.go
index 5ab1db0213c05a18f7615a836e627350a5879616..61ecc7467ff5c95dd2cf89830cacbb319cf9660f 100644
--- a/network/message/parse/messagePart_test.go
+++ b/network/message/parse/messagePart_test.go
@@ -15,17 +15,19 @@ import (
 
 // Expected messagePart for checking against, generated by gotmp in Test_newMessagePart
 var emp = messagePart{
-	Data: []uint8{0x0, 0x0, 0x0, 0x20, 0x6, 0x0, 0x7, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67},
+	Data: []uint8{0x0, 0x0, 0x0, 0x20, 0x6, 0x0, 0x7, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, messagePartCurrentVersion},
 	Id:   []uint8{0x0, 0x0, 0x0, 0x20}, Part: []uint8{0x6},
 	Len:      []uint8{0x0, 0x7},
 	Contents: []uint8{0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67},
+	Version:  []uint8{messagePartCurrentVersion},
 }
 
 // This tests that a new function part is successfully created
 func Test_newMessagePart(t *testing.T) {
 	gotmp := newMessagePart(32, 6, []byte{'t', 'e', 's', 't', 'i', 'n', 'g'})
 	if !reflect.DeepEqual(gotmp, emp) {
-		t.Errorf("MessagePart received and MessagePart expected do not match.\n\tGot: %#v\n\tExpected: %#v", gotmp, emp)
+		t.Errorf("MessagePart received and MessagePart expected do not match."+
+			"\nexpected: %#v\nreceived: %#v", emp, gotmp)
 	}
 }
 
diff --git a/network/message/parse/partition.go b/network/message/parse/partition.go
index 0b690a5bef804dd269cd62cbcc0ecac6d2667439..e7fbbfd313379570d3ec522d23053fbd025456cf 100644
--- a/network/message/parse/partition.go
+++ b/network/message/parse/partition.go
@@ -9,7 +9,6 @@ package parse
 
 import (
 	"github.com/pkg/errors"
-	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/interfaces/message"
 	"gitlab.com/elixxir/client/storage"
 	"gitlab.com/xx_network/primitives/id"
@@ -44,23 +43,23 @@ func (p Partitioner) Partition(recipient *id.ID, mt message.Type,
 
 	if len(payload) > p.maxSize {
 		return nil, 0, errors.Errorf("Payload is too long, max payload "+
-			"length is %v, received %v", p.maxSize, len(payload))
+			"length is %d, received %d", p.maxSize, len(payload))
 	}
 
-	//Get the ID of the sent message
+	// Get the ID of the sent message
 	fullMessageID, messageID := p.session.Conversations().Get(recipient).GetNextSendID()
 
-	// get the number of parts of the message. This equates to just a linear
+	// Get the number of parts of the message; this equates to just a linear
 	// equation
 	numParts := uint8((len(payload) + p.deltaFirstPart + p.partContentsSize - 1) / p.partContentsSize)
 	parts := make([][]byte, numParts)
 
-	//Create the first message part
+	// Create the first message part
 	var sub []byte
 	sub, payload = splitPayload(payload, p.firstContentsSize)
 	parts[0] = newFirstMessagePart(mt, messageID, numParts, timestamp, sub).Bytes()
 
-	//create all subsiquent message parts
+	// Create all subsequent message parts
 	for i := uint8(1); i < numParts; i++ {
 		sub, payload = splitPayload(payload, p.partContentsSize)
 		parts[i] = newMessagePart(messageID, i, sub).Bytes()
@@ -69,31 +68,25 @@ func (p Partitioner) Partition(recipient *id.ID, mt message.Type,
 	return parts, fullMessageID, nil
 }
 
-func (p Partitioner) HandlePartition(sender *id.ID, e message.EncryptionType,
+func (p Partitioner) HandlePartition(sender *id.ID, _ message.EncryptionType,
 	contents []byte, relationshipFingerprint []byte) (message.Receive, bool) {
 
-	//If it is the first message in a set, handle it as so
 	if isFirst(contents) {
-		//decode the message structure
+		// If it is the first message in a set, then handle it as so
+
+		// Decode the message structure
 		fm := FirstMessagePartFromBytes(contents)
-		timestamp, err := fm.GetTimestamp()
-		if err != nil {
-			jww.FATAL.Panicf("Failed Handle Partition, failed to get "+
-				"timestamp message from %s messageID %v: %s", sender,
-				fm.Timestamp, err)
-		}
-
-		//Handle the message ID
+
+		// Handle the message ID
 		messageID := p.session.Conversations().Get(sender).
 			ProcessReceivedMessageID(fm.GetID())
 
-		//Return the
 		return p.session.Partition().AddFirst(sender, fm.GetType(),
-			messageID, fm.GetPart(), fm.GetNumParts(), timestamp,
+			messageID, fm.GetPart(), fm.GetNumParts(), fm.GetTimestamp(),
 			fm.GetSizedContents(), relationshipFingerprint)
-		//If it is a subsiquent message part, handle it as so
 	} else {
-		mp := MessagePartFromBytes(contents)
+		// If it is a subsequent message part, handle it as so
+		mp := messagePartFromBytes(contents)
 		messageID := p.session.Conversations().Get(sender).
 			ProcessReceivedMessageID(mp.GetID())
 
diff --git a/network/message/parse/partition_test.go b/network/message/parse/partition_test.go
index 933db1a01d4e95605d44d7cf5f5dce4429f2a9b5..9351a1e77b7e80dfc74938fefe01203dd4f0b705 100644
--- a/network/message/parse/partition_test.go
+++ b/network/message/parse/partition_test.go
@@ -32,28 +32,28 @@ func TestNewPartitioner(t *testing.T) {
 			4096, p.baseMessageSize)
 	}
 
-	if p.deltaFirstPart != 20 {
+	if p.deltaFirstPart != firstHeaderLen-headerLen {
 		t.Errorf("deltaFirstPart content mismatch"+
 			"\n\texpected: %v\n\treceived: %v",
-			20, p.deltaFirstPart)
+			firstHeaderLen-headerLen, p.deltaFirstPart)
 	}
 
-	if p.firstContentsSize != 4069 {
+	if p.firstContentsSize != 4096-firstHeaderLen {
 		t.Errorf("firstContentsSize content mismatch"+
 			"\n\texpected: %v\n\treceived: %v",
-			4069, p.firstContentsSize)
+			4096-firstHeaderLen, p.firstContentsSize)
 	}
 
-	if p.maxSize != 1042675 {
+	if p.maxSize != (4096-firstHeaderLen)+(MaxMessageParts-1)*(4096-headerLen) {
 		t.Errorf("maxSize content mismatch"+
 			"\n\texpected: %v\n\treceived: %v",
-			1042675, p.maxSize)
+			(4096-firstHeaderLen)+(MaxMessageParts-1)*(4096-headerLen), p.maxSize)
 	}
 
-	if p.partContentsSize != 4089 {
+	if p.partContentsSize != 4088 {
 		t.Errorf("partContentsSize content mismatch"+
 			"\n\texpected: %v\n\treceived: %v",
-			4089, p.partContentsSize)
+			4088, p.partContentsSize)
 	}
 
 	if p.session != storeSession {