github.com/hashgraph/hedera-sdk-go/v2@v2.48.0/node.go (about) 1 package hedera 2 3 /*- 4 * 5 * Hedera Go SDK 6 * 7 * Copyright (C) 2020 - 2024 Hedera Hashgraph, LLC 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 */ 22 23 import ( 24 "bytes" 25 "crypto/sha512" 26 "crypto/tls" 27 "crypto/x509" 28 "encoding/hex" 29 "encoding/pem" 30 "sync" 31 "time" 32 33 "google.golang.org/grpc" 34 "google.golang.org/grpc/codes" 35 "google.golang.org/grpc/credentials" 36 "google.golang.org/grpc/keepalive" 37 "google.golang.org/grpc/status" 38 ) 39 40 // _Node represents a node on the network 41 type _Node struct { 42 *_ManagedNode 43 accountID AccountID 44 channel *_Channel 45 addressBook *NodeAddress 46 verifyCertificate bool 47 channelMutex sync.Mutex 48 } 49 50 func _NewNode(accountID AccountID, address string, minBackoff time.Duration) (node *_Node, err error) { 51 node = &_Node{ 52 accountID: accountID, 53 verifyCertificate: true, 54 } 55 node._ManagedNode, err = _NewManagedNode(address, minBackoff) 56 return node, err 57 } 58 59 func (node *_Node) _GetKey() string { 60 return node.accountID.String() 61 } 62 63 func (node *_Node) _SetMinBackoff(waitTime time.Duration) { 64 node._ManagedNode._SetMinBackoff(waitTime) 65 } 66 67 func (node *_Node) _GetMinBackoff() time.Duration { 68 return node._ManagedNode._GetMinBackoff() 69 } 70 71 func (node *_Node) _SetMaxBackoff(waitTime time.Duration) { 72 node._ManagedNode._SetMaxBackoff(waitTime) 73 } 74 75 func (node *_Node) _GetMaxBackoff() time.Duration { 76 return node._ManagedNode._GetMaxBackoff() 77 } 78 79 func (node *_Node) _InUse() { 80 node._ManagedNode._InUse() 81 } 82 83 func (node *_Node) _IsHealthy() bool { 84 return node._ManagedNode._IsHealthy() 85 } 86 87 func (node *_Node) _IncreaseBackoff() { 88 node._ManagedNode._IncreaseBackoff() 89 } 90 91 func (node *_Node) _DecreaseBackoff() { 92 node._ManagedNode._DecreaseBackoff() 93 } 94 95 func (node *_Node) _Wait() time.Duration { 96 return node._ManagedNode._Wait() 97 } 98 99 func (node *_Node) _GetUseCount() int64 { 100 return node._ManagedNode._GetUseCount() 101 } 102 103 func (node *_Node) _GetLastUsed() time.Time { 104 return node._ManagedNode._GetLastUsed() 105 } 106 107 func (node *_Node) _GetManagedNode() *_ManagedNode { 108 return node._ManagedNode 109 } 110 111 func (node *_Node) _GetAttempts() int64 { 112 return node._ManagedNode._GetAttempts() 113 } 114 115 func (node *_Node) _GetAddress() string { 116 return node._ManagedNode._GetAddress() 117 } 118 119 func (node *_Node) _GetReadmitTime() *time.Time { 120 return node._ManagedNode._GetReadmitTime() 121 } 122 123 func (node *_Node) _GetChannel(logger Logger) (*_Channel, error) { 124 node.channelMutex.Lock() 125 defer node.channelMutex.Unlock() 126 127 if node.channel != nil { 128 return node.channel, nil 129 } 130 131 var kacp = keepalive.ClientParameters{ 132 Time: 10 * time.Second, 133 Timeout: 2 * time.Second, 134 PermitWithoutStream: true, 135 } 136 137 var conn *grpc.ClientConn 138 var err error 139 security := grpc.WithInsecure() //nolint 140 if !node.verifyCertificate { 141 println("skipping certificate check") 142 } 143 if node._ManagedNode.address._IsTransportSecurity() { 144 security = grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{ 145 InsecureSkipVerify: true, // nolint 146 VerifyPeerCertificate: func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { 147 if node.addressBook == nil { 148 logger.Warn("skipping certificate check since no cert hash was found") 149 return nil 150 } 151 152 if !node.verifyCertificate { 153 return nil 154 } 155 156 for _, cert := range rawCerts { 157 var certHash []byte 158 159 block := &pem.Block{ 160 Type: "CERTIFICATE", 161 Bytes: cert, 162 } 163 164 var encodedBuf bytes.Buffer 165 _ = pem.Encode(&encodedBuf, block) 166 digest := sha512.New384() 167 168 if _, err = digest.Write(encodedBuf.Bytes()); err != nil { 169 return err 170 } 171 172 certHash = digest.Sum(nil) 173 174 if string(node.addressBook.CertHash) == hex.EncodeToString(certHash) { 175 return nil 176 } 177 } 178 179 return x509.CertificateInvalidError{ 180 Cert: nil, 181 Reason: x509.Expired, 182 Detail: "", 183 } 184 }, 185 })) 186 } 187 188 conn, err = grpc.NewClient(node._ManagedNode.address._String(), security, grpc.WithKeepaliveParams(kacp)) 189 if err != nil { 190 return nil, status.Error(codes.ResourceExhausted, "dial timeout of 10sec exceeded") 191 } 192 193 ch := _NewChannel(conn) 194 node.channel = &ch 195 196 return node.channel, nil 197 } 198 199 func (node *_Node) _Close() error { 200 node.channelMutex.Lock() 201 defer node.channelMutex.Unlock() 202 203 if node.channel != nil { 204 err := node.channel.client.Close() 205 node.channel = nil 206 return err 207 } 208 209 return nil 210 } 211 212 func (node *_Node) _ToSecure() _IManagedNode { 213 managed := _ManagedNode{ 214 address: node.address._ToSecure(), 215 currentBackoff: node.currentBackoff, 216 lastUsed: node.lastUsed, 217 readmitTime: node.readmitTime, 218 useCount: node.useCount, 219 minBackoff: node.minBackoff, 220 badGrpcStatusCount: node.badGrpcStatusCount, 221 } 222 223 return &_Node{ 224 _ManagedNode: &managed, 225 accountID: node.accountID, 226 channel: node.channel, 227 addressBook: node.addressBook, 228 verifyCertificate: node.verifyCertificate, 229 } 230 } 231 232 func (node *_Node) _ToInsecure() _IManagedNode { 233 managed := _ManagedNode{ 234 address: node.address._ToInsecure(), 235 currentBackoff: node.currentBackoff, 236 lastUsed: node.lastUsed, 237 readmitTime: node.readmitTime, 238 useCount: node.useCount, 239 minBackoff: node.minBackoff, 240 badGrpcStatusCount: node.badGrpcStatusCount, 241 } 242 243 return &_Node{ 244 _ManagedNode: &managed, 245 accountID: node.accountID, 246 channel: node.channel, 247 addressBook: node.addressBook, 248 verifyCertificate: node.verifyCertificate, 249 } 250 } 251 252 func (node *_Node) _SetVerifyCertificate(verify bool) { 253 node.verifyCertificate = verify 254 } 255 256 func (node *_Node) _GetVerifyCertificate() bool { 257 return node.verifyCertificate 258 }