github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/core/discovery/priced_repository.go (about) 1 /* 2 * Copyright (C) 2021 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 discovery 19 20 import ( 21 "github.com/rs/zerolog/log" 22 23 "github.com/mysteriumnetwork/node/core/discovery/proposal" 24 "github.com/mysteriumnetwork/node/market" 25 ) 26 27 // PricedServiceProposalRepository enriches proposals with price data as pricing data is not available on raw proposals. 28 type PricedServiceProposalRepository struct { 29 baseRepo proposal.Repository 30 pip PriceInfoProvider 31 filterPresets proposal.FilterPresetRepository 32 } 33 34 // PriceInfoProvider allows to fetch the current pricing for services. 35 type PriceInfoProvider interface { 36 GetCurrentPrice(nodeType string, country string, serviceType string) (market.Price, error) 37 } 38 39 // NewPricedServiceProposalRepository returns a new instance of PricedServiceProposalRepository. 40 func NewPricedServiceProposalRepository(baseRepo proposal.Repository, pip PriceInfoProvider, filterPresets proposal.FilterPresetRepository) *PricedServiceProposalRepository { 41 return &PricedServiceProposalRepository{ 42 baseRepo: baseRepo, 43 pip: pip, 44 filterPresets: filterPresets, 45 } 46 } 47 48 // Proposal fetches the proposal from base repository and enriches it with pricing data. 49 func (pspr *PricedServiceProposalRepository) Proposal(id market.ProposalID) (*proposal.PricedServiceProposal, error) { 50 prop, err := pspr.baseRepo.Proposal(id) 51 if err != nil { 52 return nil, err 53 } 54 55 // base repo can sometimes return nil proposals. 56 if prop == nil { 57 return nil, nil 58 } 59 60 priced, err := pspr.toPricedProposal(*prop) 61 return &priced, err 62 } 63 64 // Proposals fetches proposals from base repository and enriches them with pricing data. 65 func (pspr *PricedServiceProposalRepository) Proposals(filter *proposal.Filter) ([]proposal.PricedServiceProposal, error) { 66 proposals, err := pspr.baseRepo.Proposals(filter) 67 if err != nil { 68 return nil, err 69 } 70 priced := pspr.toPricedProposals(proposals) 71 72 if filter != nil && filter.PresetID != 0 { 73 preset, err := pspr.filterPresets.Get(filter.PresetID) 74 if err != nil { 75 return nil, err 76 } 77 priced = preset.Filter(priced) 78 } 79 80 return priced, nil 81 } 82 83 // Countries fetches number of proposals per country from base repository. 84 func (pspr *PricedServiceProposalRepository) Countries(filter *proposal.Filter) (map[string]int, error) { 85 return pspr.baseRepo.Countries(filter) 86 } 87 88 // EnrichProposalWithPrice adds pricing info to service proposal. 89 func (pspr *PricedServiceProposalRepository) EnrichProposalWithPrice(in market.ServiceProposal) (proposal.PricedServiceProposal, error) { 90 return pspr.toPricedProposal(in) 91 } 92 93 func (pspr *PricedServiceProposalRepository) toPricedProposals(in []market.ServiceProposal) []proposal.PricedServiceProposal { 94 res := make([]proposal.PricedServiceProposal, 0) 95 for i := range in { 96 priced, err := pspr.toPricedProposal(in[i]) 97 if err != nil { 98 log.Warn().Err(err).Msgf("could not add pricing info to proposal %v(%v)", in[i].ProviderID, in[i].ServiceType) 99 continue 100 } 101 res = append(res, priced) 102 } 103 104 return res 105 } 106 107 func (pspr *PricedServiceProposalRepository) toPricedProposal(in market.ServiceProposal) (proposal.PricedServiceProposal, error) { 108 price, err := pspr.pip.GetCurrentPrice(in.Location.IPType, in.Location.Country, in.ServiceType) 109 if err != nil { 110 return proposal.PricedServiceProposal{}, err 111 } 112 113 return proposal.PricedServiceProposal{ 114 ServiceProposal: in, 115 Price: price, 116 }, nil 117 }