@@ -374,3 +374,131 @@ func TestGetLastConfigIndexFromBlock(t *testing.T) {
374374		}, "Expected panic with malformed last config metadata" )
375375	})
376376}
377+ 
378+ func  TestVerifyTransactionsAreWellFormed (t  * testing.T ) {
379+ 	originalBlock  :=  & cb.Block {
380+ 		Data : & cb.BlockData {
381+ 			Data : [][]byte {
382+ 				marshalOrPanic (& cb.Envelope {
383+ 					Payload :   []byte {1 , 2 , 3 },
384+ 					Signature : []byte {4 , 5 , 6 },
385+ 				}),
386+ 				marshalOrPanic (& cb.Envelope {
387+ 					Payload :   []byte {7 , 8 , 9 },
388+ 					Signature : []byte {10 , 11 , 12 },
389+ 				}),
390+ 			},
391+ 		},
392+ 	}
393+ 
394+ 	forgedBlock  :=  proto .Clone (originalBlock ).(* cb.Block )
395+ 	tmp  :=  make ([]byte , len (forgedBlock .Data .Data [0 ])+ len (forgedBlock .Data .Data [1 ]))
396+ 	copy (tmp , forgedBlock .Data .Data [0 ])
397+ 	copy (tmp [len (forgedBlock .Data .Data [0 ]):], forgedBlock .Data .Data [1 ])
398+ 	forgedBlock .Data .Data  =  [][]byte {tmp } // Replace transactions {0,1} with transaction {0 || 1} 
399+ 
400+ 	for  _ , tst  :=  range  []struct  {
401+ 		name           string 
402+ 		expectedError  string 
403+ 		block          * cb.Block 
404+ 	}{
405+ 		{
406+ 			name : "config block" ,
407+ 			block : & cb.Block {Data : & cb.BlockData {
408+ 				Data : [][]byte {
409+ 					protoutil .MarshalOrPanic (
410+ 						& cb.Envelope {
411+ 							Payload : protoutil .MarshalOrPanic (& cb.Payload {
412+ 								Header : & cb.Header {
413+ 									ChannelHeader : protoutil .MarshalOrPanic (& cb.ChannelHeader {
414+ 										Type : int32 (cb .HeaderType_CONFIG ),
415+ 									}),
416+ 								},
417+ 							}),
418+ 						}),
419+ 				},
420+ 			}},
421+ 		},
422+ 		{
423+ 			name :          "empty block" ,
424+ 			expectedError : "empty block" ,
425+ 		},
426+ 		{
427+ 			name :          "no block data" ,
428+ 			block :         & cb.Block {},
429+ 			expectedError : "empty block" ,
430+ 		},
431+ 		{
432+ 			name :          "no transactions" ,
433+ 			block :         & cb.Block {Data : & cb.BlockData {}},
434+ 			expectedError : "empty block" ,
435+ 		},
436+ 		{
437+ 			name : "single transaction" ,
438+ 			block : & cb.Block {Data : & cb.BlockData {Data : [][]byte {marshalOrPanic (& cb.Envelope {
439+ 				Payload :   []byte {1 , 2 , 3 },
440+ 				Signature : []byte {4 , 5 , 6 },
441+ 			})}}},
442+ 		},
443+ 
444+ 		{
445+ 			name :  "good block" ,
446+ 			block : originalBlock ,
447+ 		},
448+ 		{
449+ 			name :          "forged block" ,
450+ 			block :         forgedBlock ,
451+ 			expectedError : "transaction 0 has 10 trailing bytes" ,
452+ 		},
453+ 		{
454+ 			name :          "no signature" ,
455+ 			expectedError : "transaction 0 has no signature" ,
456+ 			block : & cb.Block {
457+ 				Data : & cb.BlockData {
458+ 					Data : [][]byte {
459+ 						marshalOrPanic (& cb.Envelope {
460+ 							Payload : []byte {1 , 2 , 3 },
461+ 						}),
462+ 					},
463+ 				},
464+ 			},
465+ 		},
466+ 		{
467+ 			name :          "no payload" ,
468+ 			expectedError : "transaction 0 has no payload" ,
469+ 			block : & cb.Block {
470+ 				Data : & cb.BlockData {
471+ 					Data : [][]byte {
472+ 						marshalOrPanic (& cb.Envelope {
473+ 							Signature : []byte {4 , 5 , 6 },
474+ 						}),
475+ 					},
476+ 				},
477+ 			},
478+ 		},
479+ 		{
480+ 			name :          "transaction invalid" ,
481+ 			expectedError : "cannot parse invalid wire-format data" ,
482+ 			block : & cb.Block {
483+ 				Data : & cb.BlockData {
484+ 					Data : [][]byte {
485+ 						marshalOrPanic (& cb.Envelope {
486+ 							Payload :   []byte {1 , 2 , 3 },
487+ 							Signature : []byte {4 , 5 , 6 },
488+ 						})[9 :],
489+ 					},
490+ 				},
491+ 			},
492+ 		},
493+ 	} {
494+ 		tst  :=  tst 
495+ 		t .Run (tst .name , func (t  * testing.T ) {
496+ 			err  :=  protoutil .VerifyTransactionsAreWellFormed (tst .block )
497+ 			if  tst .expectedError  ==  ""  {
498+ 				require .NoError (t , err )
499+ 			} else  {
500+ 				require .Contains (t , err .Error (), tst .expectedError )
501+ 			}
502+ 		})
503+ 	}
504+ }
0 commit comments