github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/core/service/subscription.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 service 19 20 import ( 21 "fmt" 22 "math/big" 23 "time" 24 25 "github.com/mysteriumnetwork/node/identity" 26 "github.com/mysteriumnetwork/node/p2p" 27 "github.com/mysteriumnetwork/node/pb" 28 "github.com/mysteriumnetwork/node/session/connectivity" 29 "github.com/mysteriumnetwork/payments/crypto" 30 "github.com/rs/zerolog/log" 31 ) 32 33 func subscribeSessionCreate(mng *SessionManager, ch p2p.ChannelHandler) { 34 ch.Handle(p2p.TopicSessionCreate, func(c p2p.Context) error { 35 var request pb.SessionRequest 36 if err := c.Request().UnmarshalProto(&request); err != nil { 37 return err 38 } 39 if identity.FromAddress(request.GetConsumer().GetId()) != c.PeerID() { 40 return fmt.Errorf("wrong consumer identity in session create request. Expected: %s, got: %s", 41 c.PeerID().ToCommonAddress(), 42 identity.FromAddress(request.GetConsumer().GetId()), 43 ) 44 } 45 46 log.Debug().Msgf("Received P2P message for %q: %s", p2p.TopicSessionCreate, request.String()) 47 48 response, err := mng.Start(&request) 49 if err != nil { 50 return fmt.Errorf("cannot start session: %s: %w", response.ID, err) 51 } 52 53 return c.OkWithReply(p2p.ProtoMessage(&response)) 54 }) 55 } 56 57 func subscribeSessionStatus(ch p2p.ChannelHandler, statusStorage connectivity.StatusStorage) { 58 ch.Handle(p2p.TopicSessionStatus, func(c p2p.Context) error { 59 var ss pb.SessionStatus 60 if err := c.Request().UnmarshalProto(&ss); err != nil { 61 return err 62 } 63 if identity.FromAddress(ss.GetConsumerID()) != c.PeerID() { 64 return fmt.Errorf("wrong consumer identity in session status request. Expected: %s, got: %s", 65 c.PeerID().ToCommonAddress(), 66 identity.FromAddress(ss.GetConsumerID()), 67 ) 68 } 69 70 log.Debug().Msgf("Received P2P session status message for %q: %s", p2p.TopicSessionStatus, ss.String()) 71 72 entry := connectivity.StatusEntry{ 73 PeerID: identity.FromAddress(ss.GetConsumerID()), 74 StatusCode: connectivity.StatusCode(ss.GetCode()), 75 SessionID: ss.GetSessionID(), 76 Message: ss.GetMessage(), 77 CreatedAtUTC: time.Now().UTC(), 78 } 79 statusStorage.AddStatusEntry(entry) 80 81 return c.OK() 82 }) 83 } 84 85 func subscribeSessionDestroy(mng *SessionManager, ch p2p.ChannelHandler) { 86 ch.Handle(p2p.TopicSessionDestroy, func(c p2p.Context) error { 87 var si pb.SessionInfo 88 if err := c.Request().UnmarshalProto(&si); err != nil { 89 return err 90 } 91 if identity.FromAddress(si.GetConsumerID()) != c.PeerID() { 92 return fmt.Errorf("wrong consumer identity in session destroy request. Expected: %s, got: %s", 93 c.PeerID().ToCommonAddress(), 94 identity.FromAddress(si.GetConsumerID()), 95 ) 96 } 97 98 log.Debug().Msgf("Received P2P message for %q: %s", p2p.TopicSessionDestroy, si.String()) 99 100 go func() { 101 consumerID := identity.FromAddress(si.GetConsumerID()) 102 sessionID := si.GetSessionID() 103 104 err := mng.Destroy(consumerID, sessionID) 105 if err != nil { 106 log.Err(err).Msgf("Could not destroy session %s: %v", sessionID, err) 107 } 108 }() 109 110 return c.OK() 111 }) 112 } 113 114 func subscribeSessionAcknowledge(mng *SessionManager, ch p2p.ChannelHandler) { 115 ch.Handle(p2p.TopicSessionAcknowledge, func(c p2p.Context) error { 116 var si pb.SessionInfo 117 if err := c.Request().UnmarshalProto(&si); err != nil { 118 return err 119 } 120 if identity.FromAddress(si.GetConsumerID()) != c.PeerID() { 121 return fmt.Errorf("wrong consumer identity in session acknowledge request. Expected: %s, got: %s", 122 c.PeerID().ToCommonAddress(), 123 identity.FromAddress(si.GetConsumerID()), 124 ) 125 } 126 127 log.Debug().Msgf("Received P2P message for %q: %s", p2p.TopicSessionAcknowledge, si.String()) 128 consumerID := identity.FromAddress(si.GetConsumerID()) 129 sessionID := si.GetSessionID() 130 131 err := mng.Acknowledge(consumerID, sessionID) 132 if err != nil { 133 return fmt.Errorf("cannot acknowledge session %s: %w", sessionID, err) 134 } 135 136 return c.OK() 137 }) 138 } 139 140 const bigIntBase int = 10 141 142 func subscribeSessionPayments(mng *SessionManager, ch p2p.ChannelHandler) { 143 ch.Handle(p2p.TopicPaymentMessage, func(c p2p.Context) error { 144 var msg pb.ExchangeMessage 145 if err := c.Request().UnmarshalProto(&msg); err != nil { 146 return fmt.Errorf("could not unmarshal exchange message proto: %w", err) 147 } 148 log.Debug().Msgf("Received P2P message for %q: %s", p2p.TopicPaymentMessage, msg.String()) 149 150 amount, ok := new(big.Int).SetString(msg.GetPromise().GetAmount(), bigIntBase) 151 if !ok { 152 return fmt.Errorf("could not unmarshal field amount of value %v", amount) 153 } 154 155 fee, ok := new(big.Int).SetString(msg.GetPromise().GetFee(), bigIntBase) 156 if !ok { 157 return fmt.Errorf("could not unmarshal field fee of value %v", fee) 158 } 159 160 agreementID, ok := new(big.Int).SetString(msg.GetAgreementID(), bigIntBase) 161 if !ok { 162 return fmt.Errorf("could not unmarshal field agreementID of value %v", agreementID) 163 } 164 165 agreementTotal, ok := new(big.Int).SetString(msg.GetAgreementTotal(), bigIntBase) 166 if !ok { 167 return fmt.Errorf("could not unmarshal field agreementTotal of value %v", agreementTotal) 168 } 169 170 mng.paymentEngineChan <- crypto.ExchangeMessage{ 171 Promise: crypto.Promise{ 172 ChannelID: msg.GetPromise().GetChannelID(), 173 Amount: amount, 174 Fee: fee, 175 Hashlock: msg.GetPromise().GetHashlock(), 176 R: msg.GetPromise().GetR(), 177 Signature: msg.GetPromise().GetSignature(), 178 ChainID: msg.GetPromise().GetChainID(), 179 }, 180 AgreementID: agreementID, 181 AgreementTotal: agreementTotal, 182 Provider: msg.GetProvider(), 183 Signature: msg.GetSignature(), 184 HermesID: msg.GetHermesID(), 185 ChainID: msg.GetChainID(), 186 } 187 188 return nil 189 }) 190 }