64 lines
2.0 KiB
Go
64 lines
2.0 KiB
Go
/*
|
|
Copyright IBM Corp. All Rights Reserved.
|
|
|
|
SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
package channelparticipation
|
|
|
|
import (
|
|
"bytes"
|
|
|
|
cb "github.com/hyperledger/fabric-protos-go/common"
|
|
"github.com/hyperledger/fabric/bccsp/factory"
|
|
"github.com/hyperledger/fabric/common/channelconfig"
|
|
"github.com/hyperledger/fabric/orderer/common/types"
|
|
"github.com/hyperledger/fabric/protoutil"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
// ValidateJoinBlock checks whether this block can be used as a join block for the channel participation API.
|
|
// It returns the channel ID.
|
|
// It verifies that it is not a system channel by checking that consortiums config does not exist.
|
|
// It verifies it is an application channel by checking that the application group exists.
|
|
// It returns an error when it cannot be used as a join-block.
|
|
func ValidateJoinBlock(configBlock *cb.Block) (channelID string, err error) {
|
|
if !protoutil.IsConfigBlock(configBlock) {
|
|
return "", errors.New("block is not a config block")
|
|
}
|
|
|
|
if configBlock.Metadata == nil || len(configBlock.Metadata.Metadata) == 0 {
|
|
return "", errors.New("invalid block: does not have metadata")
|
|
}
|
|
|
|
if !bytes.Equal(protoutil.BlockDataHash(configBlock.Data), configBlock.Header.DataHash) {
|
|
return "", errors.New("invalid block: Header.DataHash is different from Hash(block.Data)")
|
|
}
|
|
|
|
envelope, err := protoutil.ExtractEnvelope(configBlock, 0)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
cryptoProvider := factory.GetDefault()
|
|
bundle, err := channelconfig.NewBundleFromEnvelope(envelope, cryptoProvider)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
channelID = bundle.ConfigtxValidator().ChannelID()
|
|
|
|
// Check channel type
|
|
_, isSystemChannel := bundle.ConsortiumsConfig()
|
|
if isSystemChannel {
|
|
return "", errors.WithMessage(types.ErrSystemChannelNotSupported, "invalid config: contains consortiums")
|
|
}
|
|
|
|
_, isAppChannel := bundle.ApplicationConfig()
|
|
if !isAppChannel {
|
|
return "", errors.New("invalid config: must contain application config")
|
|
}
|
|
|
|
return channelID, err
|
|
}
|