go_study/fabric-main/orderer/common/channelparticipation/validator_test.go

191 lines
5.0 KiB
Go

/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package channelparticipation_test
import (
"errors"
"math"
"testing"
"github.com/golang/protobuf/proto"
cb "github.com/hyperledger/fabric-protos-go/common"
"github.com/hyperledger/fabric/bccsp"
"github.com/hyperledger/fabric/orderer/common/channelparticipation"
"github.com/hyperledger/fabric/protoutil"
"github.com/stretchr/testify/require"
)
func TestValidateJoinBlock(t *testing.T) {
validJoinBlock := blockWithGroups(
map[string]*cb.ConfigGroup{
"Application": {},
},
"my-channel",
)
tests := []struct {
testName string
joinBlock *cb.Block
expectedChannelID string
expectedErr error
}{
{
testName: "Valid application channel join block",
joinBlock: validJoinBlock,
expectedChannelID: "my-channel",
expectedErr: nil,
},
{
testName: "Invalid block data hash",
joinBlock: func() *cb.Block {
b := proto.Clone(validJoinBlock).(*cb.Block)
b.Header.DataHash = []byte("bogus")
return b
}(),
expectedChannelID: "",
expectedErr: errors.New("invalid block: Header.DataHash is different from Hash(block.Data)"),
},
{
testName: "Invalid block metadata",
joinBlock: func() *cb.Block {
b := proto.Clone(validJoinBlock).(*cb.Block)
b.Metadata = nil
return b
}(),
expectedChannelID: "",
expectedErr: errors.New("invalid block: does not have metadata"),
},
{
testName: "Not supported: system channel join block",
joinBlock: blockWithGroups(
map[string]*cb.ConfigGroup{
"Consortiums": {},
},
"my-channel",
),
expectedChannelID: "",
expectedErr: errors.New("invalid config: contains consortiums: system channel not supported"),
},
{
testName: "Join block not a config block",
joinBlock: nonConfigBlock(),
expectedChannelID: "",
expectedErr: errors.New("block is not a config block"),
},
{
testName: "block ChannelID not valid",
joinBlock: blockWithGroups(
map[string]*cb.ConfigGroup{
"Consortiums": {},
},
"My-Channel",
),
expectedChannelID: "",
expectedErr: errors.New("initializing configtx manager failed: bad channel ID: 'My-Channel' contains illegal characters"),
},
{
testName: "Invalid bundle",
joinBlock: blockWithGroups(
map[string]*cb.ConfigGroup{
"InvalidGroup": {},
},
"my-channel",
),
expectedChannelID: "",
expectedErr: errors.New("initializing channelconfig failed: Disallowed channel group: "),
},
{
testName: "Join block has no application or consortiums group",
joinBlock: blockWithGroups(
map[string]*cb.ConfigGroup{},
"my-channel",
),
expectedChannelID: "",
expectedErr: errors.New("invalid config: must contain application config"),
},
}
for _, test := range tests {
t.Run(test.testName, func(t *testing.T) {
channelID, err := channelparticipation.ValidateJoinBlock(test.joinBlock)
require.Equal(t, test.expectedChannelID, channelID)
if test.expectedErr != nil {
require.EqualError(t, err, test.expectedErr.Error())
} else {
require.NoError(t, err)
}
})
}
}
func blockWithGroups(groups map[string]*cb.ConfigGroup, channelID string) *cb.Block {
block := protoutil.NewBlock(0, []byte{})
block.Data = &cb.BlockData{
Data: [][]byte{
protoutil.MarshalOrPanic(&cb.Envelope{
Payload: protoutil.MarshalOrPanic(&cb.Payload{
Data: protoutil.MarshalOrPanic(&cb.ConfigEnvelope{
Config: &cb.Config{
ChannelGroup: &cb.ConfigGroup{
Groups: groups,
Values: map[string]*cb.ConfigValue{
"HashingAlgorithm": {
Value: protoutil.MarshalOrPanic(&cb.HashingAlgorithm{
Name: bccsp.SHA256,
}),
},
"BlockDataHashingStructure": {
Value: protoutil.MarshalOrPanic(&cb.BlockDataHashingStructure{
Width: math.MaxUint32,
}),
},
"OrdererAddresses": {
Value: protoutil.MarshalOrPanic(&cb.OrdererAddresses{
Addresses: []string{"localhost"},
}),
},
},
},
},
}),
Header: &cb.Header{
ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
Type: int32(cb.HeaderType_CONFIG),
ChannelId: channelID,
}),
},
}),
}),
},
}
block.Header.DataHash = protoutil.BlockDataHash(block.Data)
protoutil.InitBlockMetadata(block)
return block
}
func nonConfigBlock() *cb.Block {
block := protoutil.NewBlock(0, []byte{})
block.Data = &cb.BlockData{
Data: [][]byte{
protoutil.MarshalOrPanic(&cb.Envelope{
Payload: protoutil.MarshalOrPanic(&cb.Payload{
Header: &cb.Header{
ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
Type: int32(cb.HeaderType_ENDORSER_TRANSACTION),
}),
},
}),
}),
},
}
block.Header.DataHash = protoutil.BlockDataHash(block.Data)
protoutil.InitBlockMetadata(block)
return block
}