Skip to content

Commit

Permalink
Merge pull request #251 from adityajoshi12/kubectl_hlf_3_0_channel
Browse files Browse the repository at this point in the history
(kubectl-hlf) fabric v3.0 channel creation
  • Loading branch information
adityajoshi12 authored Jan 19, 2025
2 parents bf7bf33 + 1d3ea5f commit 6475da6
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 30 deletions.
116 changes: 86 additions & 30 deletions controllers/testutils/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import (
"github.com/hyperledger/fabric-config/configtx/membership"
"github.com/hyperledger/fabric-config/configtx/orderer"
cb "github.com/hyperledger/fabric-protos-go/common"
sb "github.com/hyperledger/fabric-protos-go/orderer/smartbft"
"github.com/kfsoftware/hlf-operator/controllers/utils"
hlfv1alpha1 "github.com/kfsoftware/hlf-operator/pkg/apis/hlf.kungfusoftware.es/v1alpha1"
"github.com/pkg/errors"
"time"
)
Expand All @@ -25,9 +28,11 @@ type PeerOrg struct {
}

type Consenter struct {
host string
port int
tlsCert *x509.Certificate
host string
port int
tlsCert *x509.Certificate
signCert *x509.Certificate
mspId string
}
type channelStore struct {
}
Expand All @@ -38,6 +43,7 @@ type CreateChannelOptions struct {
name string
batchSize *orderer.BatchSize
batchDuration *time.Duration
consensus hlfv1alpha1.OrdererConsensusType
}

func (o CreateChannelOptions) validate() error {
Expand Down Expand Up @@ -87,11 +93,18 @@ func WithPeerOrgs(peerOrgs ...PeerOrg) ChannelOption {
o.peerOrgs = peerOrgs
}
}
func CreateConsenter(host string, port int, tlsCert *x509.Certificate) Consenter {
func WithConsensus(consensus hlfv1alpha1.OrdererConsensusType) ChannelOption {
return func(o *CreateChannelOptions) {
o.consensus = consensus
}
}
func CreateConsenter(host string, port int, tlsCert, signCert *x509.Certificate, mspId string) Consenter {
return Consenter{
host: host,
port: port,
tlsCert: tlsCert,
host: host,
port: port,
tlsCert: tlsCert,
signCert: signCert,
mspId: mspId,
}
}
func CreateOrdererOrg(mspID string, tlsRootCert *x509.Certificate, signRootCert *x509.Certificate, ordererUrls []string) OrdererOrg {
Expand Down Expand Up @@ -145,32 +158,75 @@ func (s channelStore) GetApplicationChannelBlock(ctx context.Context, opts ...Ch
}
peerOrgs = append(peerOrgs, genesisOrdererOrg)
}
var consenters []orderer.Consenter
for _, consenter := range o.consenters {
genesisConsenter := orderer.Consenter{
Address: orderer.EtcdAddress{
Host: consenter.host,
Port: consenter.port,
var consenters []orderer.Consenter // raft consenter
consenterMapping := []cb.Consenter{} // bft consenter
var etcdRaft orderer.EtcdRaft
var smartBFTOptions *sb.Options
var ordererType string
channelCapabilities := []string{"V2_0"}
if o.consensus == hlfv1alpha1.OrdererConsensusEtcdraft {
ordererType = orderer.ConsensusTypeEtcdRaft
for _, consenter := range o.consenters {
genesisConsenter := orderer.Consenter{
Address: orderer.EtcdAddress{
Host: consenter.host,
Port: consenter.port,
},
ClientTLSCert: consenter.tlsCert,
ServerTLSCert: consenter.tlsCert,
}
consenters = append(consenters, genesisConsenter)
}
etcdRaft = orderer.EtcdRaft{
Consenters: consenters,
Options: orderer.EtcdRaftOptions{
TickInterval: "500ms",
ElectionTick: 10,
HeartbeatTick: 1,
MaxInflightBlocks: 5,
SnapshotIntervalSize: 16 * 1024 * 1024, // 16 MB
},
ClientTLSCert: consenter.tlsCert,
ServerTLSCert: consenter.tlsCert,
}
consenters = append(consenters, genesisConsenter)
} else if o.consensus == hlfv1alpha1.OrdererConsensusBFT {
ordererType = orderer.ConsensusTypeBFT
channelCapabilities = append(channelCapabilities, "V3_0")
for i, consenter := range o.consenters {
consenterMapping = append(consenterMapping, cb.Consenter{
Host: consenter.host,
Port: uint32(consenter.port),
MspId: consenter.mspId,
Id: uint32(i + 1),
Identity: utils.EncodeX509Certificate(consenter.signCert),
ClientTlsCert: utils.EncodeX509Certificate(consenter.tlsCert),
ServerTlsCert: utils.EncodeX509Certificate(consenter.tlsCert),
})
}
smartBFTOptions = &sb.Options{
RequestBatchMaxCount: 100,
RequestBatchMaxInterval: "50ms",
RequestForwardTimeout: "2s",
RequestComplainTimeout: "20s",
RequestAutoRemoveTimeout: "3m0s",
ViewChangeResendInterval: "5s",
ViewChangeTimeout: "20s",
LeaderHeartbeatTimeout: "1m0s",
CollectTimeout: "1s",
RequestBatchMaxBytes: 10485760,
IncomingMessageBufferSize: 200,
RequestPoolSize: 100000,
LeaderHeartbeatCount: 10,
}
} else {
return nil, fmt.Errorf("orderer type %s not supported", ordererType)
}

channelConfig := configtx.Channel{
Orderer: configtx.Orderer{
OrdererType: "etcdraft",
Organizations: ordererOrgs,
EtcdRaft: orderer.EtcdRaft{
Consenters: consenters,
Options: orderer.EtcdRaftOptions{
TickInterval: "500ms",
ElectionTick: 10,
HeartbeatTick: 1,
MaxInflightBlocks: 5,
SnapshotIntervalSize: 16 * 1024 * 1024, // 16 MB
},
},
ConsenterMapping: consenterMapping,
OrdererType: ordererType,
Organizations: ordererOrgs,
EtcdRaft: etcdRaft,
SmartBFT: smartBFTOptions,
Policies: map[string]configtx.Policy{
"Readers": {
Type: "ImplicitMeta",
Expand All @@ -196,7 +252,7 @@ func (s channelStore) GetApplicationChannelBlock(ctx context.Context, opts ...Ch
PreferredMaxBytes: 512 * 1024,
},
BatchTimeout: 2 * time.Second,
State: "STATE_NORMAL",
State: orderer.ConsensusStateNormal,
},
Application: configtx.Application{
Organizations: peerOrgs,
Expand Down Expand Up @@ -225,7 +281,7 @@ func (s channelStore) GetApplicationChannelBlock(ctx context.Context, opts ...Ch
},
ACLs: defaultACLs(),
},
Capabilities: []string{"V2_0"},
Capabilities: channelCapabilities,
Policies: map[string]configtx.Policy{
"Readers": {
Type: "ImplicitMeta",
Expand Down
17 changes: 17 additions & 0 deletions kubectl-hlf/cmd/channel/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@ package channel

import (
"context"
"fmt"
"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric-config/configtx/orderer"
"github.com/kfsoftware/hlf-operator/controllers/testutils"
"github.com/kfsoftware/hlf-operator/controllers/utils"
"github.com/kfsoftware/hlf-operator/kubectl-hlf/cmd/helpers"
hlfv1alpha1 "github.com/kfsoftware/hlf-operator/pkg/apis/hlf.kungfusoftware.es/v1alpha1"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"io"
"io/ioutil"
"strings"
"time"
)

type generateChannelCmd struct {
Expand All @@ -24,8 +27,12 @@ type generateChannelCmd struct {
maxMessageCount int
absoluteMaxBytes int
preferredMaxBytes int
batchTimeout int
consensus hlfv1alpha1.OrdererConsensusType
}

var validConsensusTypes = []hlfv1alpha1.OrdererConsensusType{hlfv1alpha1.OrdererConsensusBFT, hlfv1alpha1.OrdererConsensusEtcdraft}

func (c generateChannelCmd) validate() error {
if c.channelName == "" {
return errors.Errorf("--channelName is required")
Expand Down Expand Up @@ -82,6 +89,10 @@ func (c generateChannelCmd) run() error {
if err != nil {
return err
}
signCert, err := utils.ParseX509Certificate([]byte(consenter.Status.SignCert))
if err != nil {
return err
}
consenterHost, consenterPort, err := helpers.GetOrdererHostAndPort(
clientSet,
consenter.Spec,
Expand All @@ -94,6 +105,8 @@ func (c generateChannelCmd) run() error {
consenterHost,
consenterPort,
tlsCert,
signCert,
consenter.Spec.MspID,
)
consenters = append(consenters, createConsenter)
_, ok := ordererMap[consenter.Spec.MspID]
Expand Down Expand Up @@ -189,6 +202,8 @@ func (c generateChannelCmd) run() error {
AbsoluteMaxBytes: uint32(c.absoluteMaxBytes),
PreferredMaxBytes: uint32(c.preferredMaxBytes),
}),
testutils.WithBatchTimeout(time.Duration(c.batchTimeout)*time.Second),
testutils.WithConsensus(c.consensus),
)
if err != nil {
return err
Expand Down Expand Up @@ -223,6 +238,8 @@ func newGenerateChannelCMD(io.Writer, io.Writer) *cobra.Command {
persistentFlags.IntVarP(&c.maxMessageCount, "maxMessageCount", "", 100, "Max transactions per block")
persistentFlags.IntVarP(&c.absoluteMaxBytes, "absoluteMaxBytes", "", 1024*1024, "Max size per block")
persistentFlags.IntVarP(&c.preferredMaxBytes, "preferredMaxBytes", "", 512*1024, "Max size per block")
persistentFlags.IntVarP(&c.batchTimeout, "batchTimeout", "", 2, "Batch timeout in seconds")
persistentFlags.Var(hlfv1alpha1.NewConsensusTypeValue(hlfv1alpha1.OrdererConsensusEtcdraft, validConsensusTypes, &c.consensus), "consensus", fmt.Sprintf("Consensus type ( %s, %s), default etcdraft", hlfv1alpha1.OrdererConsensusBFT, hlfv1alpha1.OrdererConsensusEtcdraft))
cmd.MarkPersistentFlagRequired("name")
cmd.MarkPersistentFlagRequired("organizations")
cmd.MarkPersistentFlagRequired("ordererOrganizations")
Expand Down
43 changes: 43 additions & 0 deletions pkg/apis/hlf.kungfusoftware.es/v1alpha1/hlf_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package v1alpha1

import (
"fmt"
"strings"

sb "github.com/hyperledger/fabric-protos-go/orderer/smartbft"
"github.com/kfsoftware/hlf-operator/pkg/status"
Expand Down Expand Up @@ -2579,6 +2580,48 @@ const (
ConsensusStateMaintenance FabricMainChannelConsensusState = "STATE_MAINTENANCE"
)

type ConsensusTypeValue struct {
value *OrdererConsensusType
allowed []OrdererConsensusType
}

func (c *ConsensusTypeValue) String() string {
if c.value == nil {
return ""
}
return string(*c.value)
}

func (c *ConsensusTypeValue) Set(s string) error {
for _, v := range c.allowed {
if string(v) == s {
*c.value = v
return nil
}
}
return fmt.Errorf("invalid consensus type: %s. Valid types are: %s", s, strings.Join(c.allowedStrings(), ", "))
}

func (c *ConsensusTypeValue) Type() string {
return "ConsensusType"
}

func (c *ConsensusTypeValue) allowedStrings() []string {
var allowedStrs []string
for _, v := range c.allowed {
allowedStrs = append(allowedStrs, string(v))
}
return allowedStrs
}

func NewConsensusTypeValue(val OrdererConsensusType, allowed []OrdererConsensusType, p *OrdererConsensusType) *ConsensusTypeValue {
*p = val
return &ConsensusTypeValue{
value: p,
allowed: allowed,
}
}

type FabricMainChannelOrdererBatchSize struct {
// The number of transactions that can fit in a block.
// +kubebuilder:default:=100
Expand Down

0 comments on commit 6475da6

Please sign in to comment.