github.com/kaituanwang/hyperledger@v2.0.1+incompatible/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/hyperledger/fabric/common/crypto" 18 "github.com/hyperledger/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 type mockLocalSigner struct { 358 returnError bool 359 } 360 361 func (m *mockLocalSigner) NewSignatureHeader() (*cb.SignatureHeader, error) { 362 if m.returnError { 363 return nil, errors.New("signature header error") 364 } 365 return &cb.SignatureHeader{}, nil 366 } 367 368 func (m *mockLocalSigner) Sign(message []byte) ([]byte, error) { 369 if m.returnError { 370 return nil, errors.New("sign error") 371 } 372 return message, nil 373 } 374 375 func TestChannelHeader(t *testing.T) { 376 makeEnvelope := func(payload *cb.Payload) *cb.Envelope { 377 return &cb.Envelope{ 378 Payload: MarshalOrPanic(payload), 379 } 380 } 381 382 _, err := ChannelHeader(makeEnvelope(&cb.Payload{ 383 Header: &cb.Header{ 384 ChannelHeader: MarshalOrPanic(&cb.ChannelHeader{ 385 ChannelId: "foo", 386 }), 387 }, 388 })) 389 assert.NoError(t, err, "Channel header was present") 390 391 _, err = ChannelHeader(makeEnvelope(&cb.Payload{ 392 Header: &cb.Header{}, 393 })) 394 assert.Error(t, err, "ChannelHeader was missing") 395 396 _, err = ChannelHeader(makeEnvelope(&cb.Payload{})) 397 assert.Error(t, err, "Header was missing") 398 399 _, err = ChannelHeader(&cb.Envelope{}) 400 assert.Error(t, err, "Payload was missing") 401 } 402 403 func TestIsConfigBlock(t *testing.T) { 404 newBlock := func(env *cb.Envelope) *cb.Block { 405 return &cb.Block{ 406 Data: &cb.BlockData{ 407 Data: [][]byte{MarshalOrPanic(env)}, 408 }, 409 } 410 } 411 412 newConfigEnv := func(envType int32) *cb.Envelope { 413 return &cb.Envelope{ 414 Payload: MarshalOrPanic(&cb.Payload{ 415 Header: &cb.Header{ 416 ChannelHeader: MarshalOrPanic(&cb.ChannelHeader{ 417 Type: envType, 418 ChannelId: "test-chain", 419 }), 420 }, 421 Data: []byte("test bytes"), 422 }), // common.Payload 423 } // LastUpdate 424 } 425 426 // scenario 1: CONFIG envelope 427 envType := int32(cb.HeaderType_CONFIG) 428 env := newConfigEnv(envType) 429 block := newBlock(env) 430 431 result := IsConfigBlock(block) 432 assert.True(t, result, "IsConfigBlock returns true for blocks with CONFIG envelope") 433 434 // scenario 2: ORDERER_TRANSACTION envelope 435 envType = int32(cb.HeaderType_ORDERER_TRANSACTION) 436 env = newConfigEnv(envType) 437 block = newBlock(env) 438 439 result = IsConfigBlock(block) 440 assert.True(t, result, "IsConfigBlock returns true for blocks with ORDERER_TRANSACTION envelope") 441 442 // scenario 3: MESSAGE envelope 443 envType = int32(cb.HeaderType_MESSAGE) 444 env = newConfigEnv(envType) 445 block = newBlock(env) 446 447 result = IsConfigBlock(block) 448 assert.False(t, result, "IsConfigBlock returns false for blocks with MESSAGE envelope") 449 } 450 451 func TestEnvelopeToConfigUpdate(t *testing.T) { 452 makeEnv := func(data []byte) *cb.Envelope { 453 return &cb.Envelope{ 454 Payload: MarshalOrPanic(&cb.Payload{ 455 Header: &cb.Header{ 456 ChannelHeader: MarshalOrPanic(&cb.ChannelHeader{ 457 Type: int32(cb.HeaderType_CONFIG_UPDATE), 458 ChannelId: "test-chain", 459 }), 460 }, 461 Data: data, 462 }), // common.Payload 463 } // LastUpdate 464 } 465 466 // scenario 1: for valid envelopes 467 configUpdateEnv := &cb.ConfigUpdateEnvelope{} 468 env := makeEnv(MarshalOrPanic(configUpdateEnv)) 469 result, err := EnvelopeToConfigUpdate(env) 470 471 assert.NoError(t, err, "EnvelopeToConfigUpdate runs without error for valid CONFIG_UPDATE envelope") 472 assert.Equal(t, configUpdateEnv, result, "Correct configUpdateEnvelope returned") 473 474 // scenario 2: for invalid envelopes 475 env = makeEnv([]byte("test bytes")) 476 _, err = EnvelopeToConfigUpdate(env) 477 478 assert.Error(t, err, "EnvelopeToConfigUpdate fails with error for invalid CONFIG_UPDATE envelope") 479 } 480 481 func TestGetRandomNonce(t *testing.T) { 482 key1, err := getRandomNonce() 483 assert.NoErrorf(t, err, "error getting random bytes") 484 assert.Len(t, key1, crypto.NonceSize) 485 }