github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/tequilapi/contract/connection.go (about) 1 /* 2 * Copyright (C) 2020 The "MysteriumNetwork/node" Authors. 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 package contract 19 20 import ( 21 "math/big" 22 23 "github.com/ethereum/go-ethereum/common" 24 25 "github.com/mysteriumnetwork/go-rest/apierror" 26 "github.com/mysteriumnetwork/node/consumer/bandwidth" 27 "github.com/mysteriumnetwork/node/core/connection" 28 "github.com/mysteriumnetwork/node/core/connection/connectionstate" 29 "github.com/mysteriumnetwork/node/core/quality" 30 "github.com/mysteriumnetwork/node/datasize" 31 "github.com/mysteriumnetwork/payments/crypto" 32 ) 33 34 var emptyAddress = common.Address{} 35 36 // NewConnectionInfoDTO maps to API connection status. 37 func NewConnectionInfoDTO(session connectionstate.Status) ConnectionInfoDTO { 38 response := ConnectionInfoDTO{ 39 Status: string(session.State), 40 ConsumerID: session.ConsumerID.Address, 41 SessionID: string(session.SessionID), 42 } 43 if session.HermesID != emptyAddress { 44 response.HermesID = session.HermesID.Hex() 45 } 46 // None exists, for not started connection 47 if session.Proposal.ProviderID != "" { 48 proposalRes := NewProposalDTO(session.Proposal) 49 response.Proposal = &proposalRes 50 } 51 return response 52 } 53 54 // ConnectionInfoDTO holds partial consumer connection details. 55 // swagger:model ConnectionInfoDTO 56 type ConnectionInfoDTO struct { 57 // example: Connected 58 Status string `json:"status"` 59 60 // example: 0x00 61 ConsumerID string `json:"consumer_id,omitempty"` 62 63 // example: 0x00 64 HermesID string `json:"hermes_id,omitempty"` 65 66 // example: {"id":1,"provider_id":"0x71ccbdee7f6afe85a5bc7106323518518cd23b94","service_type":"openvpn","location":{"country":"CA"}} 67 Proposal *ProposalDTO `json:"proposal,omitempty"` 68 69 // example: 4cfb0324-daf6-4ad8-448b-e61fe0a1f918 70 SessionID string `json:"session_id,omitempty"` 71 } 72 73 // NewConnectionDTO maps to API connection. 74 func NewConnectionDTO(session connectionstate.Status, statistics connectionstate.Statistics, throughput bandwidth.Throughput, invoice crypto.Invoice) ConnectionDTO { 75 dto := ConnectionDTO{ 76 ConnectionInfoDTO: NewConnectionInfoDTO(session), 77 } 78 if !statistics.At.IsZero() { 79 statsDto := NewConnectionStatisticsDTO(session, statistics, throughput, invoice) 80 dto.Statistics = &statsDto 81 } 82 return dto 83 } 84 85 // ConnectionDTO holds full consumer connection details. 86 // swagger:model ConnectionDTO 87 type ConnectionDTO struct { 88 ConnectionInfoDTO 89 Statistics *ConnectionStatisticsDTO `json:"statistics,omitempty"` 90 } 91 92 // NewConnectionStatisticsDTO maps to API connection stats. 93 func NewConnectionStatisticsDTO(session connectionstate.Status, statistics connectionstate.Statistics, throughput bandwidth.Throughput, invoice crypto.Invoice) ConnectionStatisticsDTO { 94 agreementTotal := new(big.Int) 95 if invoice.AgreementTotal != nil { 96 agreementTotal = invoice.AgreementTotal 97 } 98 return ConnectionStatisticsDTO{ 99 Duration: int(session.Duration().Seconds()), 100 BytesSent: statistics.BytesSent, 101 BytesReceived: statistics.BytesReceived, 102 ThroughputSent: datasize.BitSize(throughput.Up).Bits(), 103 ThroughputReceived: datasize.BitSize(throughput.Down).Bits(), 104 TokensSpent: agreementTotal, 105 SpentTokens: NewTokens(agreementTotal), 106 } 107 } 108 109 // ConnectionStatisticsDTO holds consumer connection statistics. 110 // swagger:model ConnectionStatisticsDTO 111 type ConnectionStatisticsDTO struct { 112 // example: 1024 113 BytesSent uint64 `json:"bytes_sent"` 114 115 // example: 1024 116 BytesReceived uint64 `json:"bytes_received"` 117 118 // Upload speed in bits per second 119 // example: 1024 120 ThroughputSent uint64 `json:"throughput_sent"` 121 122 // Download speed in bits per second 123 // example: 1024 124 ThroughputReceived uint64 `json:"throughput_received"` 125 126 // connection duration in seconds 127 // example: 60 128 Duration int `json:"duration"` 129 130 // example: 500000 131 TokensSpent *big.Int `json:"tokens_spent"` 132 133 SpentTokens Tokens `json:"spent_tokens"` 134 } 135 136 // ConnectionTrafficDTO holds consumer connection traffic information. 137 // swagger:model ConnectionTrafficDTO 138 type ConnectionTrafficDTO struct { 139 // example: 1024 140 BytesSent uint64 `json:"bytes_sent"` 141 142 // example: 1024 143 BytesReceived uint64 `json:"bytes_received"` 144 } 145 146 // ConnectionCreateRequest request used to start a connection. 147 // swagger:model ConnectionCreateRequestDTO 148 type ConnectionCreateRequest struct { 149 // consumer identity 150 // required: true 151 // example: 0x0000000000000000000000000000000000000001 152 ConsumerID string `json:"consumer_id"` 153 154 // provider identity 155 // required: true 156 // example: 0x0000000000000000000000000000000000000002 157 ProviderID string `json:"provider_id"` 158 159 Filter ConnectionCreateFilter `json:"filter"` 160 161 // hermes identity 162 // example: 0x0000000000000000000000000000000000000003 163 HermesID string `json:"hermes_id"` 164 165 // service type. Possible values are "openvpn", "wireguard" and "noop" 166 // required: false 167 // default: openvpn 168 // example: openvpn 169 ServiceType string `json:"service_type"` 170 171 // connect options 172 // required: false 173 ConnectOptions ConnectOptions `json:"connect_options,omitempty"` 174 } 175 176 // ConnectionCreateFilter describes filter for the connection request to lookup 177 // for a requested proposals based on specified params. 178 type ConnectionCreateFilter struct { 179 Providers []string `json:"providers,omitempty"` 180 CountryCode string `json:"country_code,omitempty"` 181 IPType string `json:"ip_type,omitempty"` 182 IncludeMonitoringFailed bool `json:"include_monitoring_failed,omitempty"` 183 SortBy string `json:"sort_by,omitempty"` 184 } 185 186 // Validate validates fields in request. 187 func (cr ConnectionCreateRequest) Validate() *apierror.APIError { 188 v := apierror.NewValidator() 189 if len(cr.ConsumerID) == 0 { 190 v.Required("consumer_id") 191 } 192 return v.Err() 193 } 194 195 // Event creates a quality connection event to be send as a quality metric. 196 func (cr ConnectionCreateRequest) Event(stage string, errMsg string) quality.ConnectionEvent { 197 return quality.ConnectionEvent{ 198 ServiceType: cr.ServiceType, 199 ProviderID: cr.ProviderID, 200 ConsumerID: cr.ConsumerID, 201 HermesID: cr.HermesID, 202 Error: errMsg, 203 Stage: stage, 204 } 205 } 206 207 // ConnectOptions holds tequilapi connect options 208 // swagger:model ConnectOptionsDTO 209 type ConnectOptions struct { 210 // kill switch option restricting communication only through VPN 211 // required: false 212 // example: true 213 DisableKillSwitch bool `json:"kill_switch"` 214 // DNS to use 215 // required: false 216 // default: auto 217 // example: auto, provider, system, "1.1.1.1,8.8.8.8" 218 DNS connection.DNSOption `json:"dns"` 219 220 ProxyPort int `json:"proxy_port"` 221 }