github.com/kaleido-io/firefly@v0.0.0-20210622132723-8b4b6aacb971/pkg/fftypes/message_test.go (about) 1 // Copyright © 2021 Kaleido, Inc. 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 17 package fftypes 18 19 import ( 20 "context" 21 "crypto/sha256" 22 "encoding/json" 23 "testing" 24 25 "github.com/stretchr/testify/assert" 26 ) 27 28 func TestSealBareMessage(t *testing.T) { 29 msg := Message{} 30 err := msg.Seal(context.Background()) 31 assert.NoError(t, err) 32 assert.NotNil(t, msg.Header.ID) 33 assert.NotNil(t, msg.Header.DataHash) 34 assert.NotNil(t, msg.Hash) 35 } 36 37 func TestVerifyEmptyTopicString(t *testing.T) { 38 msg := Message{ 39 Header: MessageHeader{ 40 Topics: []string{""}, 41 }, 42 } 43 err := msg.Verify(context.Background()) 44 assert.Regexp(t, `FF10131.*header.topics\[0\]`, err) 45 } 46 47 func TestVerifyBadTagString(t *testing.T) { 48 msg := Message{ 49 Header: MessageHeader{ 50 Tag: "!wrong", 51 }, 52 } 53 err := msg.Verify(context.Background()) 54 assert.Regexp(t, `FF10131.*header.tag`, err) 55 } 56 57 func TestSealNilDataID(t *testing.T) { 58 msg := Message{ 59 Data: DataRefs{ 60 {}, 61 }, 62 } 63 err := msg.Seal(context.Background()) 64 assert.Regexp(t, "FF10144.*0", err) 65 } 66 67 func TestVerifyNilDataHash(t *testing.T) { 68 msg := Message{ 69 Data: DataRefs{ 70 {ID: NewUUID()}, 71 }, 72 } 73 err := msg.Verify(context.Background()) 74 assert.Regexp(t, "FF10144.*0", err) 75 } 76 77 func TestSeaDupDataID(t *testing.T) { 78 id1 := NewUUID() 79 hash1 := NewRandB32() 80 hash2 := NewRandB32() 81 msg := Message{ 82 Data: DataRefs{ 83 {ID: id1, Hash: hash1}, 84 {ID: id1, Hash: hash2}, 85 }, 86 } 87 err := msg.Seal(context.Background()) 88 assert.Regexp(t, "FF10145.*1", err) 89 } 90 91 func TestVerifylDupDataHash(t *testing.T) { 92 id1 := NewUUID() 93 id2 := NewUUID() 94 hash1 := NewRandB32() 95 msg := Message{ 96 Data: DataRefs{ 97 {ID: id1, Hash: hash1}, 98 {ID: id2, Hash: hash1}, 99 }, 100 } 101 err := msg.Verify(context.Background()) 102 assert.Regexp(t, "FF10145.*1", err) 103 } 104 105 func TestVerifyNilHashes(t *testing.T) { 106 msg := Message{} 107 err := msg.Verify(context.Background()) 108 assert.Regexp(t, "FF10147", err) 109 } 110 111 func TestVerifyNilMisMatchedHashes(t *testing.T) { 112 msg := Message{ 113 Header: MessageHeader{ 114 DataHash: NewRandB32(), 115 }, 116 Hash: NewRandB32(), 117 } 118 err := msg.Verify(context.Background()) 119 assert.Regexp(t, "FF10146", err) 120 } 121 122 func TestSealKnownMessage(t *testing.T) { 123 msgid := MustParseUUID("2cd37805-5f40-4e12-962e-67868cde3049") 124 cid := MustParseUUID("39296b6e-91b9-4a61-b279-833c85b04d94") 125 data1 := MustParseUUID("e3a3b714-7e49-4c73-a4ea-87a50b19961a") 126 data2 := MustParseUUID("cc66b23f-d340-4333-82d5-b63adc1c3c07") 127 data3 := MustParseUUID("189c8185-2b92-481a-847a-e57595ab3541") 128 var gid Bytes32 129 gid.UnmarshalText([]byte("3fcc7e07069e441f07c9f6b26f16fcb2dc896222d72888675082fd308440d9ae")) 130 var hash1, hash2, hash3 Bytes32 131 hash1.UnmarshalText([]byte("3fcc7e07069e441f07c9f6b26f16fcb2dc896222d72888675082fd308440d9ae")) 132 hash2.UnmarshalText([]byte("1d1462e02d7acee49a8448267c65067e0bec893c9a0c050b9835efa376fec046")) 133 hash3.UnmarshalText([]byte("284b535da66aa0734af56c708426d756331baec3bce3079e508003bcf4738ee6")) 134 msg := Message{ 135 Header: MessageHeader{ 136 ID: msgid, 137 CID: cid, 138 Type: MessageTypePrivate, 139 TxType: TransactionTypeBatchPin, 140 Author: "0x12345", 141 Namespace: "ns1", 142 Topics: []string{"topic1", "topic2"}, 143 Tag: "tag1", 144 Created: UnixTime(1620104103123456789), 145 Group: &gid, 146 }, 147 Data: DataRefs{ 148 {ID: data1, Hash: &hash1}, 149 {Hash: &hash2, ID: data2}, // Demonstrating we hash in order id,hash order, even if Go definition is re-ordered 150 {ID: data3, Hash: &hash3}, 151 }, 152 } 153 err := msg.Seal(context.Background()) 154 assert.NoError(t, err) 155 156 // Data IDs are hashed the the sequence of the message - that is preserved as the message moves through 157 dataHashData, _ := json.Marshal(&msg.Data) 158 var dataHash Bytes32 = sha256.Sum256([]byte(dataHashData)) 159 assert.Equal(t, `[{"id":"e3a3b714-7e49-4c73-a4ea-87a50b19961a","hash":"3fcc7e07069e441f07c9f6b26f16fcb2dc896222d72888675082fd308440d9ae"},{"id":"cc66b23f-d340-4333-82d5-b63adc1c3c07","hash":"1d1462e02d7acee49a8448267c65067e0bec893c9a0c050b9835efa376fec046"},{"id":"189c8185-2b92-481a-847a-e57595ab3541","hash":"284b535da66aa0734af56c708426d756331baec3bce3079e508003bcf4738ee6"}]`, string(dataHashData)) 160 assert.Equal(t, `2468d5c26cc85968acaf8b96d09476453916ea4eab41632a31d09efc7ab297d2`, dataHash.String()) 161 assert.Equal(t, dataHash, *msg.Header.DataHash) 162 163 // Header contains the data hash, and is hashed into the message hash 164 actualHeader, _ := json.Marshal(&msg.Header) 165 expectedHeader := `{"id":"2cd37805-5f40-4e12-962e-67868cde3049","cid":"39296b6e-91b9-4a61-b279-833c85b04d94","type":"private","txtype":"batch_pin","author":"0x12345","created":"2021-05-04T04:55:03.123456789Z","namespace":"ns1","group":"3fcc7e07069e441f07c9f6b26f16fcb2dc896222d72888675082fd308440d9ae","topic":["topic1","topic2"],"tag":"tag1","datahash":"2468d5c26cc85968acaf8b96d09476453916ea4eab41632a31d09efc7ab297d2"}` 166 var msgHash Bytes32 = sha256.Sum256([]byte(expectedHeader)) 167 assert.Equal(t, expectedHeader, string(actualHeader)) 168 assert.Equal(t, `95f0a6a16ba67df7f24c5403733faebb89c304d66d55c21e149213d8ec7e2633`, msgHash.String()) 169 assert.Equal(t, msgHash, *msg.Hash) 170 171 // Verify also returns good 172 err = msg.Verify(context.Background()) 173 assert.NoError(t, err) 174 175 msg.Sequence = 12345 176 var ls LocallySequenced = &msg 177 assert.Equal(t, int64(12345), ls.LocalSequence()) 178 }