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  }