| 314 | } |
| 315 | |
| 316 | func VerifyTransactionsAreWellFormed(bd *cb.BlockData) error { |
| 317 | if bd == nil || bd.Data == nil || len(bd.Data) == 0 { |
| 318 | return errors.New("empty block") |
| 319 | } |
| 320 | |
| 321 | // If we have a single transaction, and the block is a config block, then no need to check |
| 322 | // well formed-ness, because there cannot be another transaction in the original block. |
| 323 | if HasConfigTx(bd) { |
| 324 | return nil |
| 325 | } |
| 326 | |
| 327 | for i, rawTx := range bd.Data { |
| 328 | env := &cb.Envelope{} |
| 329 | if err := proto.Unmarshal(rawTx, env); err != nil { |
| 330 | return fmt.Errorf("transaction %d is invalid: %v", i, err) |
| 331 | } |
| 332 | |
| 333 | if len(env.Payload) == 0 { |
| 334 | return fmt.Errorf("transaction %d has no payload", i) |
| 335 | } |
| 336 | |
| 337 | if len(env.Signature) == 0 { |
| 338 | return fmt.Errorf("transaction %d has no signature", i) |
| 339 | } |
| 340 | |
| 341 | expected, err := proto.Marshal(env) |
| 342 | if err != nil { |
| 343 | return fmt.Errorf("failed re-marshaling envelope: %v", err) |
| 344 | } |
| 345 | |
| 346 | if len(expected) < len(rawTx) { |
| 347 | return fmt.Errorf("transaction %d has %d trailing bytes", i, len(rawTx)-len(expected)) |
| 348 | } |
| 349 | if !bytes.Equal(expected, rawTx) { |
| 350 | return fmt.Errorf("transaction %d (%s) does not match its raw form (%s)", i, |
| 351 | base64.StdEncoding.EncodeToString(expected), base64.StdEncoding.EncodeToString(rawTx)) |
| 352 | } |
| 353 | } |
| 354 | |
| 355 | return nil |
| 356 | } |