github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/peer/channel/create.go (about)

     1  /*
     2  Copyright IBM Corp. 2017 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8                   http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package channel
    18  
    19  import (
    20  	"fmt"
    21  	"io/ioutil"
    22  	"time"
    23  
    24  	"github.com/golang/protobuf/proto"
    25  	"github.com/hyperledger/fabric/common/configtx"
    26  	configtxtest "github.com/hyperledger/fabric/common/configtx/test"
    27  	"github.com/hyperledger/fabric/common/configtx/tool/provisional"
    28  	mspmgmt "github.com/hyperledger/fabric/msp/mgmt"
    29  	"github.com/hyperledger/fabric/peer/common"
    30  	cb "github.com/hyperledger/fabric/protos/common"
    31  	"github.com/hyperledger/fabric/protos/utils"
    32  	"github.com/spf13/cobra"
    33  )
    34  
    35  //ConfigTxFileNotFound channel create configuration tx file not found
    36  type ConfigTxFileNotFound string
    37  
    38  func (e ConfigTxFileNotFound) Error() string {
    39  	return fmt.Sprintf("channel create configuration tx file not found %s", string(e))
    40  }
    41  
    42  //InvalidCreateTx invalid channel create transaction
    43  type InvalidCreateTx string
    44  
    45  func (e InvalidCreateTx) Error() string {
    46  	return fmt.Sprintf("Invalid channel create transaction : %s", string(e))
    47  }
    48  
    49  func createCmd(cf *ChannelCmdFactory) *cobra.Command {
    50  	createCmd := &cobra.Command{
    51  		Use:   "create",
    52  		Short: "Create a chain.",
    53  		Long:  `Create a chain.`,
    54  		RunE: func(cmd *cobra.Command, args []string) error {
    55  			return create(cmd, args, cf)
    56  		},
    57  	}
    58  
    59  	return createCmd
    60  }
    61  
    62  func createChannelFromDefaults(cf *ChannelCmdFactory) (*cb.Envelope, error) {
    63  	chCrtTemp := configtxtest.CompositeTemplate()
    64  
    65  	signer, err := mspmgmt.GetLocalMSP().GetDefaultSigningIdentity()
    66  	if err != nil {
    67  		return nil, err
    68  	}
    69  
    70  	chCrtEnv, err := configtx.MakeChainCreationTransaction(provisional.AcceptAllPolicyKey, chainID, signer, chCrtTemp)
    71  
    72  	if err != nil {
    73  		return nil, err
    74  	}
    75  
    76  	return chCrtEnv, nil
    77  }
    78  
    79  func createChannelFromConfigTx(configTxFileName string) (*cb.Envelope, error) {
    80  	cftx, err := ioutil.ReadFile(configTxFileName)
    81  	if err != nil {
    82  		return nil, ConfigTxFileNotFound(err.Error())
    83  	}
    84  
    85  	env := utils.UnmarshalEnvelopeOrPanic(cftx)
    86  
    87  	payload := utils.ExtractPayloadOrPanic(env)
    88  
    89  	if payload.Header == nil || payload.Header.ChannelHeader == nil {
    90  		return nil, InvalidCreateTx("bad header")
    91  	}
    92  
    93  	ch, err := utils.UnmarshalChannelHeader(payload.Header.ChannelHeader)
    94  	if err != nil {
    95  		return nil, InvalidCreateTx("could not unmarshall channel header")
    96  	}
    97  
    98  	if ch.Type != int32(cb.HeaderType_CONFIG_UPDATE) {
    99  		return nil, InvalidCreateTx("bad type")
   100  	}
   101  
   102  	if ch.ChannelId == "" {
   103  		return nil, InvalidCreateTx("empty channel id")
   104  	}
   105  
   106  	if ch.ChannelId != chainID {
   107  		return nil, InvalidCreateTx(fmt.Sprintf("mismatched channel ID %s != %s", ch.ChannelId, chainID))
   108  	}
   109  
   110  	return env, nil
   111  }
   112  
   113  func sendCreateChainTransaction(cf *ChannelCmdFactory) error {
   114  	var err error
   115  	var chCrtEnv *cb.Envelope
   116  
   117  	if channelTxFile != "" {
   118  		if chCrtEnv, err = createChannelFromConfigTx(channelTxFile); err != nil {
   119  			return err
   120  		}
   121  	} else {
   122  		if chCrtEnv, err = createChannelFromDefaults(cf); err != nil {
   123  			return err
   124  		}
   125  	}
   126  	var broadcastClient common.BroadcastClient
   127  	broadcastClient, err = cf.BroadcastFactory()
   128  	if err != nil {
   129  		return err
   130  	}
   131  
   132  	defer broadcastClient.Close()
   133  	err = broadcastClient.Send(chCrtEnv)
   134  
   135  	return err
   136  }
   137  
   138  func executeCreate(cf *ChannelCmdFactory) error {
   139  	var err error
   140  
   141  	if err = sendCreateChainTransaction(cf); err != nil {
   142  		return err
   143  	}
   144  
   145  	time.Sleep(2 * time.Second)
   146  
   147  	var block *cb.Block
   148  	if block, err = cf.DeliverClient.getBlock(); err != nil {
   149  		return err
   150  	}
   151  
   152  	b, err := proto.Marshal(block)
   153  	if err != nil {
   154  		return err
   155  	}
   156  
   157  	file := chainID + ".block"
   158  	if err = ioutil.WriteFile(file, b, 0644); err != nil {
   159  		return err
   160  	}
   161  
   162  	return nil
   163  }
   164  
   165  func create(cmd *cobra.Command, args []string, cf *ChannelCmdFactory) error {
   166  	//the global chainID filled by the "-c" command
   167  	if chainID == common.UndefinedParamValue {
   168  		return fmt.Errorf("Must supply channel ID .\n")
   169  	}
   170  
   171  	var err error
   172  	if cf == nil {
   173  		cf, err = InitCmdFactory(false)
   174  		if err != nil {
   175  			return err
   176  		}
   177  	}
   178  	return executeCreate(cf)
   179  }