@@ -32,6 +32,7 @@ import (
3232 "github.com/hyperledger/fabric/orderer/common/msgprocessor"
3333 "github.com/hyperledger/fabric/orderer/common/types"
3434 "github.com/hyperledger/fabric/orderer/consensus"
35+ "github.com/hyperledger/fabric/orderer/consensus/etcdraft"
3536 "github.com/hyperledger/fabric/protoutil"
3637 "github.com/pkg/errors"
3738)
@@ -537,7 +538,10 @@ func (r *Registrar) CreateChain(chainName string) {
537538 if chain != nil {
538539 logger .Infof ("A chain of type %T for channel %s already exists. " +
539540 "Halting it." , chain .Chain , chainName )
541+ r .lock .Lock ()
540542 chain .Halt ()
543+ delete (r .chains , chainName )
544+ r .lock .Unlock ()
541545 }
542546 r .newChain (configTx (lf ))
543547}
@@ -546,6 +550,20 @@ func (r *Registrar) newChain(configtx *cb.Envelope) {
546550 r .lock .Lock ()
547551 defer r .lock .Unlock ()
548552
553+ channelName , err := channelNameFromConfigTx (configtx )
554+ if err != nil {
555+ logger .Warnf ("Failed extracting channel name: %v" , err )
556+ return
557+ }
558+
559+ // fixes https://github.com/hyperledger/fabric/issues/2931
560+ if existingChain , exists := r .chains [channelName ]; exists {
561+ if _ , isRaftChain := existingChain .Chain .(* etcdraft.Chain ); isRaftChain {
562+ logger .Infof ("Channel %s already created, skipping its creation" , channelName )
563+ return
564+ }
565+ }
566+
549567 cs := r .createNewChain (configtx )
550568 cs .start ()
551569 logger .Infof ("Created and started new channel %s" , cs .ChannelID ())
@@ -1113,3 +1131,21 @@ func (r *Registrar) ReportConsensusRelationAndStatusMetrics(channelID string, re
11131131 r .channelParticipationMetrics .reportConsensusRelation (channelID , relation )
11141132 r .channelParticipationMetrics .reportStatus (channelID , status )
11151133}
1134+
1135+ func channelNameFromConfigTx (configtx * cb.Envelope ) (string , error ) {
1136+ payload , err := protoutil .UnmarshalPayload (configtx .Payload )
1137+ if err != nil {
1138+ return "" , errors .WithMessage (err , "error umarshaling envelope to payload" )
1139+ }
1140+
1141+ if payload .Header == nil {
1142+ return "" , errors .New ("missing channel header" )
1143+ }
1144+
1145+ chdr , err := protoutil .UnmarshalChannelHeader (payload .Header .ChannelHeader )
1146+ if err != nil {
1147+ return "" , errors .WithMessage (err , "error unmarshalling channel header" )
1148+ }
1149+
1150+ return chdr .ChannelId , nil
1151+ }
0 commit comments