github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/session/pingpong/factory.go (about) 1 /* 2 * Copyright (C) 2019 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 pingpong 19 20 import ( 21 "fmt" 22 "math/big" 23 "time" 24 25 "github.com/ethereum/go-ethereum/common" 26 "github.com/rs/zerolog/log" 27 28 "github.com/mysteriumnetwork/node/config" 29 "github.com/mysteriumnetwork/node/core/connection" 30 "github.com/mysteriumnetwork/node/core/discovery/proposal" 31 "github.com/mysteriumnetwork/node/core/service" 32 "github.com/mysteriumnetwork/node/datasize" 33 "github.com/mysteriumnetwork/node/eventbus" 34 "github.com/mysteriumnetwork/node/identity" 35 "github.com/mysteriumnetwork/node/market" 36 "github.com/mysteriumnetwork/node/p2p" 37 "github.com/mysteriumnetwork/node/pb" 38 "github.com/mysteriumnetwork/node/session" 39 "github.com/mysteriumnetwork/node/session/mbtime" 40 "github.com/mysteriumnetwork/payments/crypto" 41 ) 42 43 const ( 44 // PromiseWaitTimeout is the time that the provider waits for the promise to arrive 45 PromiseWaitTimeout = time.Second * 50 46 47 // InvoiceSendPeriod is how often the provider will send invoice messages to the consumer 48 InvoiceSendPeriod = time.Second * 60 49 50 // DefaultHermesFailureCount defines how many times we're allowed to fail to reach hermes in a row before announcing the failure. 51 DefaultHermesFailureCount uint64 = 10 52 ) 53 54 // InvoiceFactoryCreator returns a payment engine factory. 55 func InvoiceFactoryCreator( 56 channel p2p.Channel, 57 balanceSendPeriod, limitBalanceSendPeriod, promiseTimeout time.Duration, 58 invoiceStorage providerInvoiceStorage, 59 maxHermesFailureCount uint64, 60 maxAllowedHermesFee uint16, 61 maxUnpaidInvoiceValue, limitUnpaidInvoiceValue *big.Int, 62 hermesStatusChecker hermesStatusChecker, 63 eventBus eventbus.EventBus, 64 promiseHandler promiseHandler, 65 addressProvider addressProvider, 66 observer observerApi, 67 ) func(identity.Identity, identity.Identity, int64, common.Address, string, chan crypto.ExchangeMessage, market.Price) (service.PaymentEngine, error) { 68 return func(providerID, consumerID identity.Identity, chainID int64, hermesID common.Address, sessionID string, exchangeChan chan crypto.ExchangeMessage, price market.Price) (service.PaymentEngine, error) { 69 timeTracker := session.NewTracker(mbtime.Now) 70 deps := InvoiceTrackerDeps{ 71 AgreedPrice: price, 72 Peer: consumerID, 73 PeerInvoiceSender: NewInvoiceSender(channel), 74 InvoiceStorage: invoiceStorage, 75 TimeTracker: &timeTracker, 76 ExchangeMessageChan: exchangeChan, 77 ExchangeMessageWaitTimeout: promiseTimeout, 78 ProviderID: providerID, 79 ConsumersHermesID: hermesID, 80 MaxHermesFailureCount: maxHermesFailureCount, 81 MaxAllowedHermesFee: maxAllowedHermesFee, 82 HermesStatusChecker: hermesStatusChecker, 83 EventBus: eventBus, 84 SessionID: sessionID, 85 PromiseHandler: promiseHandler, 86 ChainID: chainID, 87 AddressProvider: addressProvider, 88 MaxNotPaidInvoice: maxUnpaidInvoiceValue, 89 LimitNotPaidInvoice: limitUnpaidInvoiceValue, 90 ChargePeriod: balanceSendPeriod, 91 LimitChargePeriod: limitBalanceSendPeriod, 92 ChargePeriodLeeway: 2 * time.Minute, 93 Observer: observer, 94 } 95 paymentEngine := NewInvoiceTracker(deps) 96 return paymentEngine, nil 97 } 98 } 99 100 // ExchangeFactoryFunc returns a exchange factory. 101 func ExchangeFactoryFunc( 102 keystore hashSigner, 103 signer identity.SignerFactory, 104 totalStorage consumerTotalsStorage, 105 addressProvider addressProvider, 106 eventBus eventbus.EventBus, 107 dataLeewayMegabytes uint64, 108 ) func(senderUUID string, channel p2p.Channel, consumer, provider identity.Identity, hermes common.Address, proposal proposal.PricedServiceProposal, price market.Price) (connection.PaymentIssuer, error) { 109 return func(senderUUID string, channel p2p.Channel, consumer, provider identity.Identity, hermes common.Address, proposal proposal.PricedServiceProposal, price market.Price) (connection.PaymentIssuer, error) { 110 invoices, err := invoiceReceiver(channel) 111 if err != nil { 112 return nil, err 113 } 114 timeTracker := session.NewTracker(mbtime.Now) 115 deps := InvoicePayerDeps{ 116 SenderUUID: senderUUID, 117 InvoiceChan: invoices, 118 PeerExchangeMessageSender: NewExchangeSender(channel), 119 ConsumerTotalsStorage: totalStorage, 120 TimeTracker: &timeTracker, 121 Ks: keystore, 122 Identity: consumer, 123 Peer: provider, 124 AgreedPrice: price, 125 AddressProvider: addressProvider, 126 EventBus: eventBus, 127 HermesAddress: hermes, 128 DataLeeway: datasize.MiB * datasize.BitSize(dataLeewayMegabytes), 129 ChainID: config.GetInt64(config.FlagChainID), 130 } 131 return NewInvoicePayer(deps), nil 132 } 133 } 134 135 func invoiceReceiver(channel p2p.ChannelHandler) (chan crypto.Invoice, error) { 136 invoices := make(chan crypto.Invoice) 137 138 channel.Handle(p2p.TopicPaymentInvoice, func(c p2p.Context) error { 139 var msg pb.Invoice 140 if err := c.Request().UnmarshalProto(&msg); err != nil { 141 return err 142 } 143 if identity.FromAddress(msg.Provider) != c.PeerID() { 144 return fmt.Errorf("wrong provider identity in invoice. Expected: %s, got: %s", 145 c.PeerID().ToCommonAddress(), 146 identity.FromAddress(msg.GetProvider()).ToCommonAddress(), 147 ) 148 } 149 150 log.Debug().Msgf("Received P2P message for %q: %s", p2p.TopicPaymentInvoice, msg.String()) 151 152 agreementID, ok := new(big.Int).SetString(msg.GetAgreementID(), bigIntBase) 153 if !ok { 154 return fmt.Errorf("could not unmarshal field agreementID of value %v", agreementID) 155 } 156 agreementTotal, ok := new(big.Int).SetString(msg.GetAgreementTotal(), bigIntBase) 157 if !ok { 158 return fmt.Errorf("could not unmarshal field agreementTotal of value %v", agreementTotal) 159 } 160 transactorFee, ok := new(big.Int).SetString(msg.GetTransactorFee(), bigIntBase) 161 if !ok { 162 return fmt.Errorf("could not unmarshal field transactorFee of value %v", transactorFee) 163 } 164 165 invoices <- crypto.Invoice{ 166 AgreementID: agreementID, 167 AgreementTotal: agreementTotal, 168 TransactorFee: transactorFee, 169 Hashlock: msg.GetHashlock(), 170 Provider: msg.GetProvider(), 171 ChainID: msg.GetChainID(), 172 } 173 174 return nil 175 }) 176 177 return invoices, nil 178 }