github.com/osdi23p228/fabric@v0.0.0-20221218062954-77808885f5db/protoutil/commonutils_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package protoutil 8 9 import ( 10 "bytes" 11 "errors" 12 "testing" 13 14 "github.com/golang/protobuf/proto" 15 cb "github.com/hyperledger/fabric-protos-go/common" 16 pb "github.com/hyperledger/fabric-protos-go/peer" 17 "github.com/osdi23p228/fabric/common/crypto" 18 "github.com/osdi23p228/fabric/protoutil/fakes" 19 "github.com/stretchr/testify/assert" 20 ) 21 22 //go:generate counterfeiter -o fakes/signer_serializer.go --fake-name SignerSerializer . signerSerializer 23 24 type signerSerializer interface { 25 Signer 26 } 27 28 func TestNonceRandomness(t *testing.T) { 29 n1, err := CreateNonce() 30 if err != nil { 31 t.Fatal(err) 32 } 33 n2, err := CreateNonce() 34 if err != nil { 35 t.Fatal(err) 36 } 37 if bytes.Equal(n1, n2) { 38 t.Fatalf("Expected nonces to be different, got %x and %x", n1, n2) 39 } 40 } 41 42 func TestNonceLength(t *testing.T) { 43 n, err := CreateNonce() 44 if err != nil { 45 t.Fatal(err) 46 } 47 actual := len(n) 48 expected := crypto.NonceSize 49 if actual != expected { 50 t.Fatalf("Expected nonce to be of size %d, got %d instead", expected, actual) 51 } 52 53 } 54 55 func TestUnmarshalPayload(t *testing.T) { 56 var payload *cb.Payload 57 good, _ := proto.Marshal(&cb.Payload{ 58 Data: []byte("payload"), 59 }) 60 payload, err := UnmarshalPayload(good) 61 assert.NoError(t, err, "Unexpected error unmarshaling payload") 62 assert.NotNil(t, payload, "Payload should not be nil") 63 payload = UnmarshalPayloadOrPanic(good) 64 assert.NotNil(t, payload, "Payload should not be nil") 65 66 bad := []byte("bad payload") 67 assert.Panics(t, func() { 68 _ = UnmarshalPayloadOrPanic(bad) 69 }, "Expected panic unmarshaling malformed payload") 70 71 } 72 73 func TestUnmarshalSignatureHeader(t *testing.T) { 74 t.Run("invalid header", func(t *testing.T) { 75 sighdrBytes := []byte("invalid signature header") 76 _, err := UnmarshalSignatureHeader(sighdrBytes) 77 assert.Error(t, err, "Expected unmarshaling error") 78 }) 79 80 t.Run("valid empty header", func(t *testing.T) { 81 sighdr := &cb.SignatureHeader{} 82 sighdrBytes := MarshalOrPanic(sighdr) 83 sighdr, err := UnmarshalSignatureHeader(sighdrBytes) 84 assert.NoError(t, err, "Unexpected error unmarshaling signature header") 85 assert.Nil(t, sighdr.Creator) 86 assert.Nil(t, sighdr.Nonce) 87 }) 88 89 t.Run("valid header", func(t *testing.T) { 90 sighdr := &cb.SignatureHeader{ 91 Creator: []byte("creator"), 92 Nonce: []byte("nonce"), 93 } 94 sighdrBytes := MarshalOrPanic(sighdr) 95 sighdr, err := UnmarshalSignatureHeader(sighdrBytes) 96 assert.NoError(t, err, "Unexpected error unmarshaling signature header") 97 assert.Equal(t, []byte("creator"), sighdr.Creator) 98 assert.Equal(t, []byte("nonce"), sighdr.Nonce) 99 }) 100 } 101 102 func TestUnmarshalSignatureHeaderOrPanic(t *testing.T) { 103 104 t.Run("panic due to invalid header", func(t *testing.T) { 105 sighdrBytes := []byte("invalid signature header") 106 assert.Panics(t, func() { 107 UnmarshalSignatureHeaderOrPanic(sighdrBytes) 108 }, "Expected panic with invalid header") 109 }) 110 111 t.Run("no panic as the header is valid", func(t *testing.T) { 112 sighdr := &cb.SignatureHeader{} 113 sighdrBytes := MarshalOrPanic(sighdr) 114 sighdr = UnmarshalSignatureHeaderOrPanic(sighdrBytes) 115 assert.Nil(t, sighdr.Creator) 116 assert.Nil(t, sighdr.Nonce) 117 }) 118 } 119 120 func TestUnmarshalEnvelope(t *testing.T) { 121 var env *cb.Envelope 122 good, _ := proto.Marshal(&cb.Envelope{}) 123 env, err := UnmarshalEnvelope(good) 124 assert.NoError(t, err, "Unexpected error unmarshaling envelope") 125 assert.NotNil(t, env, "Envelope should not be nil") 126 env = UnmarshalEnvelopeOrPanic(good) 127 assert.NotNil(t, env, "Envelope should not be nil") 128 129 bad := []byte("bad envelope") 130 assert.Panics(t, func() { 131 _ = UnmarshalEnvelopeOrPanic(bad) 132 }, "Expected panic unmarshaling malformed envelope") 133 134 } 135 136 func TestUnmarshalBlock(t *testing.T) { 137 var env *cb.Block 138 good, _ := proto.Marshal(&cb.Block{}) 139 env, err := UnmarshalBlock(good) 140 assert.NoError(t, err, "Unexpected error unmarshaling block") 141 assert.NotNil(t, env, "Block should not be nil") 142 env = UnmarshalBlockOrPanic(good) 143 assert.NotNil(t, env, "Block should not be nil") 144 145 bad := []byte("bad block") 146 assert.Panics(t, func() { 147 _ = UnmarshalBlockOrPanic(bad) 148 }, "Expected panic unmarshaling malformed block") 149 150 } 151 152 func TestUnmarshalEnvelopeOfType(t *testing.T) { 153 env := &cb.Envelope{} 154 155 env.Payload = []byte("bad payload") 156 _, err := UnmarshalEnvelopeOfType(env, cb.HeaderType_CONFIG, nil) 157 assert.Error(t, err, "Expected error unmarshaling malformed envelope") 158 159 payload, _ := proto.Marshal(&cb.Payload{ 160 Header: nil, 161 }) 162 env.Payload = payload 163 _, err = UnmarshalEnvelopeOfType(env, cb.HeaderType_CONFIG, nil) 164 assert.Error(t, err, "Expected error with missing payload header") 165 166 payload, _ = proto.Marshal(&cb.Payload{ 167 Header: &cb.Header{ 168 ChannelHeader: []byte("bad header"), 169 }, 170 }) 171 env.Payload = payload 172 _, err = UnmarshalEnvelopeOfType(env, cb.HeaderType_CONFIG, nil) 173 assert.Error(t, err, "Expected error for malformed channel header") 174 175 chdr, _ := proto.Marshal(&cb.ChannelHeader{ 176 Type: int32(cb.HeaderType_CHAINCODE_PACKAGE), 177 }) 178 payload, _ = proto.Marshal(&cb.Payload{ 179 Header: &cb.Header{ 180 ChannelHeader: chdr, 181 }, 182 }) 183 env.Payload = payload 184 _, err = UnmarshalEnvelopeOfType(env, cb.HeaderType_CONFIG, nil) 185 assert.Error(t, err, "Expected error for wrong channel header type") 186 187 chdr, _ = proto.Marshal(&cb.ChannelHeader{ 188 Type: int32(cb.HeaderType_CONFIG), 189 }) 190 payload, _ = proto.Marshal(&cb.Payload{ 191 Header: &cb.Header{ 192 ChannelHeader: chdr, 193 }, 194 Data: []byte("bad data"), 195 }) 196 env.Payload = payload 197 _, err = UnmarshalEnvelopeOfType(env, cb.HeaderType_CONFIG, &cb.ConfigEnvelope{}) 198 assert.Error(t, err, "Expected error for malformed payload data") 199 200 chdr, _ = proto.Marshal(&cb.ChannelHeader{ 201 Type: int32(cb.HeaderType_CONFIG), 202 }) 203 configEnv, _ := proto.Marshal(&cb.ConfigEnvelope{}) 204 payload, _ = proto.Marshal(&cb.Payload{ 205 Header: &cb.Header{ 206 ChannelHeader: chdr, 207 }, 208 Data: configEnv, 209 }) 210 env.Payload = payload 211 _, err = UnmarshalEnvelopeOfType(env, cb.HeaderType_CONFIG, &cb.ConfigEnvelope{}) 212 assert.NoError(t, err, "Unexpected error unmarshaling envelope") 213 214 } 215 216 func TestExtractEnvelopeNilData(t *testing.T) { 217 block := &cb.Block{} 218 _, err := ExtractEnvelope(block, 0) 219 assert.Error(t, err, "Nil data") 220 } 221 222 func TestExtractEnvelopeWrongIndex(t *testing.T) { 223 block := testBlock() 224 if _, err := ExtractEnvelope(block, len(block.GetData().Data)); err == nil { 225 t.Fatal("Expected envelope extraction to fail (wrong index)") 226 } 227 } 228 229 func TestExtractEnvelopeWrongIndexOrPanic(t *testing.T) { 230 defer func() { 231 if r := recover(); r == nil { 232 t.Fatal("Expected envelope extraction to panic (wrong index)") 233 } 234 }() 235 236 block := testBlock() 237 ExtractEnvelopeOrPanic(block, len(block.GetData().Data)) 238 } 239 240 func TestExtractEnvelope(t *testing.T) { 241 if envelope, err := ExtractEnvelope(testBlock(), 0); err != nil { 242 t.Fatalf("Expected envelop extraction to succeed: %s", err) 243 } else if !proto.Equal(envelope, testEnvelope()) { 244 t.Fatal("Expected extracted envelope to match test envelope") 245 } 246 } 247 248 func TestExtractEnvelopeOrPanic(t *testing.T) { 249 defer func() { 250 if r := recover(); r != nil { 251 t.Fatal("Expected envelope extraction to succeed") 252 } 253 }() 254 255 if !proto.Equal(ExtractEnvelopeOrPanic(testBlock(), 0), testEnvelope()) { 256 t.Fatal("Expected extracted envelope to match test envelope") 257 } 258 } 259 260 func TestExtractPayload(t *testing.T) { 261 if payload, err := UnmarshalPayload(testEnvelope().Payload); err != nil { 262 t.Fatalf("Expected payload extraction to succeed: %s", err) 263 } else if !proto.Equal(payload, testPayload()) { 264 t.Fatal("Expected extracted payload to match test payload") 265 } 266 } 267 268 func TestExtractPayloadOrPanic(t *testing.T) { 269 defer func() { 270 if r := recover(); r != nil { 271 t.Fatal("Expected payload extraction to succeed") 272 } 273 }() 274 275 if !proto.Equal(UnmarshalPayloadOrPanic(testEnvelope().Payload), testPayload()) { 276 t.Fatal("Expected extracted payload to match test payload") 277 } 278 } 279 280 func TestUnmarshalChaincodeID(t *testing.T) { 281 ccname := "mychaincode" 282 ccversion := "myversion" 283 ccidbytes, _ := proto.Marshal(&pb.ChaincodeID{ 284 Name: ccname, 285 Version: ccversion, 286 }) 287 ccid, err := UnmarshalChaincodeID(ccidbytes) 288 assert.NoError(t, err) 289 assert.Equal(t, ccname, ccid.Name, "Expected ccid names to match") 290 assert.Equal(t, ccversion, ccid.Version, "Expected ccid versions to match") 291 292 _, err = UnmarshalChaincodeID([]byte("bad chaincodeID")) 293 assert.Error(t, err, "Expected error marshaling malformed chaincode ID") 294 } 295 296 func TestNewSignatureHeaderOrPanic(t *testing.T) { 297 var sigHeader *cb.SignatureHeader 298 299 id := &fakes.SignerSerializer{} 300 id.SerializeReturnsOnCall(0, []byte("serialized"), nil) 301 id.SerializeReturnsOnCall(1, nil, errors.New("serialize failed")) 302 sigHeader = NewSignatureHeaderOrPanic(id) 303 assert.NotNil(t, sigHeader, "Signature header should not be nil") 304 305 assert.Panics(t, func() { 306 _ = NewSignatureHeaderOrPanic(nil) 307 }, "Expected panic with nil signer") 308 309 assert.Panics(t, func() { 310 _ = NewSignatureHeaderOrPanic(id) 311 }, "Expected panic with signature header error") 312 } 313 314 func TestSignOrPanic(t *testing.T) { 315 msg := []byte("sign me") 316 signer := &fakes.SignerSerializer{} 317 signer.SignReturnsOnCall(0, msg, nil) 318 signer.SignReturnsOnCall(1, nil, errors.New("bad signature")) 319 sig := SignOrPanic(signer, msg) 320 // mock signer returns message to be signed 321 assert.Equal(t, msg, sig, "Signature does not match expected value") 322 323 assert.Panics(t, func() { 324 _ = SignOrPanic(nil, []byte("sign me")) 325 }, "Expected panic with nil signer") 326 327 assert.Panics(t, func() { 328 _ = SignOrPanic(signer, []byte("sign me")) 329 }, "Expected panic with sign error") 330 } 331 332 // Helper functions 333 334 func testPayload() *cb.Payload { 335 return &cb.Payload{ 336 Header: MakePayloadHeader( 337 MakeChannelHeader(cb.HeaderType_MESSAGE, int32(1), "test", 0), 338 MakeSignatureHeader([]byte("creator"), []byte("nonce"))), 339 Data: []byte("test"), 340 } 341 } 342 343 func testEnvelope() *cb.Envelope { 344 // No need to set the signature 345 return &cb.Envelope{Payload: MarshalOrPanic(testPayload())} 346 } 347 348 func testBlock() *cb.Block { 349 // No need to set the block's Header, or Metadata 350 return &cb.Block{ 351 Data: &cb.BlockData{ 352 Data: [][]byte{MarshalOrPanic(testEnvelope())}, 353 }, 354 } 355 } 356 357 func TestChannelHeader(t *testing.T) { 358 makeEnvelope := func(payload *cb.Payload) *cb.Envelope { 359 return &cb.Envelope{ 360 Payload: MarshalOrPanic(payload), 361 } 362 } 363 364 _, err := ChannelHeader(makeEnvelope(&cb.Payload{ 365 Header: &cb.Header{ 366 ChannelHeader: MarshalOrPanic(&cb.ChannelHeader{ 367 ChannelId: "foo", 368 }), 369 }, 370 })) 371 assert.NoError(t, err, "Channel header was present") 372 373 _, err = ChannelHeader(makeEnvelope(&cb.Payload{ 374 Header: &cb.Header{}, 375 })) 376 assert.Error(t, err, "ChannelHeader was missing") 377 378 _, err = ChannelHeader(makeEnvelope(&cb.Payload{})) 379 assert.Error(t, err, "Header was missing") 380 381 _, err = ChannelHeader(&cb.Envelope{}) 382 assert.Error(t, err, "Payload was missing") 383 } 384 385 func TestIsConfigBlock(t *testing.T) { 386 newBlock := func(env *cb.Envelope) *cb.Block { 387 return &cb.Block{ 388 Data: &cb.BlockData{ 389 Data: [][]byte{MarshalOrPanic(env)}, 390 }, 391 } 392 } 393 394 newConfigEnv := func(envType int32) *cb.Envelope { 395 return &cb.Envelope{ 396 Payload: MarshalOrPanic(&cb.Payload{ 397 Header: &cb.Header{ 398 ChannelHeader: MarshalOrPanic(&cb.ChannelHeader{ 399 Type: envType, 400 ChannelId: "test-chain", 401 }), 402 }, 403 Data: []byte("test bytes"), 404 }), // common.Payload 405 } // LastUpdate 406 } 407 408 // scenario 1: CONFIG envelope 409 envType := int32(cb.HeaderType_CONFIG) 410 env := newConfigEnv(envType) 411 block := newBlock(env) 412 413 result := IsConfigBlock(block) 414 assert.True(t, result, "IsConfigBlock returns true for blocks with CONFIG envelope") 415 416 // scenario 2: ORDERER_TRANSACTION envelope 417 envType = int32(cb.HeaderType_ORDERER_TRANSACTION) 418 env = newConfigEnv(envType) 419 block = newBlock(env) 420 421 result = IsConfigBlock(block) 422 assert.True(t, result, "IsConfigBlock returns true for blocks with ORDERER_TRANSACTION envelope") 423 424 // scenario 3: MESSAGE envelope 425 envType = int32(cb.HeaderType_MESSAGE) 426 env = newConfigEnv(envType) 427 block = newBlock(env) 428 429 result = IsConfigBlock(block) 430 assert.False(t, result, "IsConfigBlock returns false for blocks with MESSAGE envelope") 431 } 432 433 func TestEnvelopeToConfigUpdate(t *testing.T) { 434 makeEnv := func(data []byte) *cb.Envelope { 435 return &cb.Envelope{ 436 Payload: MarshalOrPanic(&cb.Payload{ 437 Header: &cb.Header{ 438 ChannelHeader: MarshalOrPanic(&cb.ChannelHeader{ 439 Type: int32(cb.HeaderType_CONFIG_UPDATE), 440 ChannelId: "test-chain", 441 }), 442 }, 443 Data: data, 444 }), // common.Payload 445 } // LastUpdate 446 } 447 448 // scenario 1: for valid envelopes 449 configUpdateEnv := &cb.ConfigUpdateEnvelope{} 450 env := makeEnv(MarshalOrPanic(configUpdateEnv)) 451 result, err := EnvelopeToConfigUpdate(env) 452 453 assert.NoError(t, err, "EnvelopeToConfigUpdate runs without error for valid CONFIG_UPDATE envelope") 454 assert.Equal(t, configUpdateEnv, result, "Correct configUpdateEnvelope returned") 455 456 // scenario 2: for invalid envelopes 457 env = makeEnv([]byte("test bytes")) 458 _, err = EnvelopeToConfigUpdate(env) 459 460 assert.Error(t, err, "EnvelopeToConfigUpdate fails with error for invalid CONFIG_UPDATE envelope") 461 } 462 463 func TestGetRandomNonce(t *testing.T) { 464 key1, err := getRandomNonce() 465 assert.NoErrorf(t, err, "error getting random bytes") 466 assert.Len(t, key1, crypto.NonceSize) 467 }