github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/core/peer/config.go (about) 1 /* 2 Copyright IBM Corp. 2016 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 // The 'viper' package for configuration handling is very flexible, but has 18 // been found to have extremely poor performance when configuration values are 19 // accessed repeatedly. The function CacheConfiguration() defined here caches 20 // all configuration values that are accessed frequently. These parameters 21 // are now presented as function calls that access local configuration 22 // variables. This seems to be the most robust way to represent these 23 // parameters in the face of the numerous ways that configuration files are 24 // loaded and used (e.g, normal usage vs. test cases). 25 26 // The CacheConfiguration() function is allowed to be called globally to 27 // ensure that the correct values are always cached; See for example how 28 // certain parameters are forced in 'ChaincodeDevMode' in main.go. 29 30 package peer 31 32 import ( 33 "fmt" 34 "io/ioutil" 35 "net" 36 37 "github.com/spf13/viper" 38 39 "github.com/hyperledger/fabric/core/comm" 40 "github.com/hyperledger/fabric/core/config" 41 pb "github.com/hyperledger/fabric/protos/peer" 42 ) 43 44 // Is the configuration cached? 45 var configurationCached = false 46 47 // Cached values and error values of the computed constants getLocalAddress(), 48 // getValidatorStreamAddress(), and getPeerEndpoint() 49 var localAddress string 50 var localAddressError error 51 var peerEndpoint *pb.PeerEndpoint 52 var peerEndpointError error 53 54 // Cached values of commonly used configuration constants. 55 var syncStateSnapshotChannelSize int 56 var syncStateDeltasChannelSize int 57 var syncBlocksChannelSize int 58 59 // Note: There is some kind of circular import issue that prevents us from 60 // importing the "core" package into the "peer" package. The 61 // 'peer.SecurityEnabled' bit is a duplicate of the 'core.SecurityEnabled' 62 // bit. 63 var securityEnabled bool 64 65 // CacheConfiguration computes and caches commonly-used constants and 66 // computed constants as package variables. Routines which were previously 67 // global have been embedded here to preserve the original abstraction. 68 func CacheConfiguration() (err error) { 69 70 // getLocalAddress returns the address:port the local peer is operating on. Affected by env:peer.addressAutoDetect 71 getLocalAddress := func() (peerAddress string, err error) { 72 if viper.GetBool("peer.addressAutoDetect") { 73 // Need to get the port from the peer.address setting, and append to the determined host IP 74 _, port, err := net.SplitHostPort(viper.GetString("peer.address")) 75 if err != nil { 76 err = fmt.Errorf("Error auto detecting Peer's address: %s", err) 77 return "", err 78 } 79 peerAddress = net.JoinHostPort(GetLocalIP(), port) 80 peerLogger.Infof("Auto detected peer address: %s", peerAddress) 81 } else { 82 peerAddress = viper.GetString("peer.address") 83 } 84 return 85 } 86 87 // getPeerEndpoint returns the PeerEndpoint for this Peer instance. Affected by env:peer.addressAutoDetect 88 getPeerEndpoint := func() (*pb.PeerEndpoint, error) { 89 var peerAddress string 90 peerAddress, err := getLocalAddress() 91 if err != nil { 92 return nil, err 93 } 94 return &pb.PeerEndpoint{Id: &pb.PeerID{Name: viper.GetString("peer.id")}, Address: peerAddress}, nil 95 } 96 97 localAddress, localAddressError = getLocalAddress() 98 peerEndpoint, peerEndpointError = getPeerEndpoint() 99 100 syncStateSnapshotChannelSize = viper.GetInt("peer.sync.state.snapshot.channelSize") 101 syncStateDeltasChannelSize = viper.GetInt("peer.sync.state.deltas.channelSize") 102 syncBlocksChannelSize = viper.GetInt("peer.sync.blocks.channelSize") 103 104 securityEnabled = true 105 106 configurationCached = true 107 108 if localAddressError != nil { 109 return localAddressError 110 } else if peerEndpointError != nil { 111 return peerEndpointError 112 } 113 return 114 } 115 116 // cacheConfiguration logs an error if error checks have failed. 117 func cacheConfiguration() { 118 if err := CacheConfiguration(); err != nil { 119 peerLogger.Errorf("Execution continues after CacheConfiguration() failure : %s", err) 120 } 121 } 122 123 //Functional forms 124 125 // GetLocalAddress returns the peer.address property 126 func GetLocalAddress() (string, error) { 127 if !configurationCached { 128 cacheConfiguration() 129 } 130 return localAddress, localAddressError 131 } 132 133 // GetPeerEndpoint returns peerEndpoint from cached configuration 134 func GetPeerEndpoint() (*pb.PeerEndpoint, error) { 135 if !configurationCached { 136 cacheConfiguration() 137 } 138 return peerEndpoint, peerEndpointError 139 } 140 141 // SyncStateSnapshotChannelSize returns the peer.sync.state.snapshot.channelSize property 142 func SyncStateSnapshotChannelSize() int { 143 if !configurationCached { 144 cacheConfiguration() 145 } 146 return syncStateSnapshotChannelSize 147 } 148 149 // SyncStateDeltasChannelSize returns the peer.sync.state.deltas.channelSize property 150 func SyncStateDeltasChannelSize() int { 151 if !configurationCached { 152 cacheConfiguration() 153 } 154 return syncStateDeltasChannelSize 155 } 156 157 // SyncBlocksChannelSize returns the peer.sync.blocks.channelSize property 158 func SyncBlocksChannelSize() int { 159 if !configurationCached { 160 cacheConfiguration() 161 } 162 return syncBlocksChannelSize 163 } 164 165 // SecurityEnabled returns the securityEnabled property from cached configuration 166 func SecurityEnabled() bool { 167 if !configurationCached { 168 cacheConfiguration() 169 } 170 return securityEnabled 171 } 172 173 // GetSecureConfig returns the secure server configuration for the peer 174 func GetSecureConfig() (comm.SecureServerConfig, error) { 175 secureConfig := comm.SecureServerConfig{ 176 UseTLS: viper.GetBool("peer.tls.enabled"), 177 } 178 if secureConfig.UseTLS { 179 // get the certs from the file system 180 serverKey, err := ioutil.ReadFile(config.GetPath("peer.tls.key.file")) 181 serverCert, err := ioutil.ReadFile(config.GetPath("peer.tls.cert.file")) 182 // must have both key and cert file 183 if err != nil { 184 return secureConfig, fmt.Errorf("Error loading TLS key and/or certificate (%s)", err) 185 } 186 secureConfig.ServerCertificate = serverCert 187 secureConfig.ServerKey = serverKey 188 // check for root cert 189 if config.GetPath("peer.tls.rootcert.file") != "" { 190 rootCert, err := ioutil.ReadFile(config.GetPath("peer.tls.rootcert.file")) 191 if err != nil { 192 return secureConfig, fmt.Errorf("Error loading TLS root certificate (%s)", err) 193 } 194 secureConfig.ServerRootCAs = [][]byte{rootCert} 195 } 196 return secureConfig, nil 197 } 198 return secureConfig, nil 199 }