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 }