github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/session/pingpong/hermes_caller_test.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 "encoding/json" 22 "errors" 23 "fmt" 24 "math/big" 25 "net/http" 26 "net/http/httptest" 27 "testing" 28 "time" 29 30 "github.com/mysteriumnetwork/node/requests" 31 "github.com/mysteriumnetwork/payments/crypto" 32 "github.com/stretchr/testify/assert" 33 ) 34 35 func TestHermesCaller_RequestPromise_OK(t *testing.T) { 36 promise := crypto.Promise{ 37 ChannelID: []byte("ChannelID"), 38 Amount: big.NewInt(1), 39 Fee: big.NewInt(1), 40 Hashlock: []byte("lock"), 41 R: []byte("R"), 42 Signature: []byte("Signature"), 43 } 44 45 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 46 w.WriteHeader(http.StatusOK) 47 bytes, err := json.Marshal(promise) 48 assert.Nil(t, err) 49 w.Write(bytes) 50 })) 51 defer server.Close() 52 53 c := requests.NewHTTPClient("0.0.0.0", time.Second) 54 caller := NewHermesCaller(c, server.URL) 55 p, err := caller.RequestPromise(RequestPromise{}) 56 assert.Nil(t, err) 57 58 assert.EqualValues(t, promise, p) 59 } 60 61 func TestHermesCaller_RequestPromise_Error(t *testing.T) { 62 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 63 w.WriteHeader(http.StatusBadRequest) 64 })) 65 defer server.Close() 66 67 c := requests.NewHTTPClient("0.0.0.0", time.Second) 68 caller := NewHermesCaller(c, server.URL) 69 _, err := caller.RequestPromise(RequestPromise{}) 70 assert.NotNil(t, err) 71 } 72 73 func TestHermesCaller_RevealR_Error(t *testing.T) { 74 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 75 w.WriteHeader(http.StatusBadRequest) 76 })) 77 defer server.Close() 78 79 c := requests.NewHTTPClient("0.0.0.0", time.Second) 80 caller := NewHermesCaller(c, server.URL) 81 err := caller.RevealR("r", "provider", big.NewInt(1)) 82 assert.NotNil(t, err) 83 } 84 85 func TestHermesCaller_RevealR_OK(t *testing.T) { 86 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 87 w.WriteHeader(http.StatusOK) 88 _, err := w.Write([]byte(`{ 89 "message": "R successfully revealed" 90 }`)) 91 assert.NoError(t, err) 92 })) 93 defer server.Close() 94 95 c := requests.NewHTTPClient("0.0.0.0", time.Second) 96 caller := NewHermesCaller(c, server.URL) 97 err := caller.RevealR("r", "provider", big.NewInt(1)) 98 assert.Nil(t, err) 99 } 100 101 func TestHermesGetConsumerData_Error(t *testing.T) { 102 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 103 w.WriteHeader(http.StatusBadRequest) 104 })) 105 defer server.Close() 106 107 c := requests.NewHTTPClient("0.0.0.0", time.Second) 108 caller := NewHermesCaller(c, server.URL) 109 _, err := caller.GetConsumerData(-1, "something", -1) 110 assert.NotNil(t, err) 111 } 112 113 func TestHermesCaller_UnmarshalsErrors(t *testing.T) { 114 for k, v := range hermesCauseToError { 115 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 116 w.WriteHeader(http.StatusBadRequest) 117 _, err := w.Write([]byte(fmt.Sprintf(`{ 118 "cause": %q, 119 "message": "some message" 120 }`, k))) 121 assert.NoError(t, err) 122 })) 123 defer server.Close() 124 125 c := requests.NewHTTPClient("0.0.0.0", time.Second) 126 caller := NewHermesCaller(c, server.URL) 127 err := caller.RevealR("r", "provider", big.NewInt(1)) 128 assert.EqualError(t, errors.Unwrap(err), v.Error()) 129 server.Close() 130 } 131 } 132 133 func TestHermesGetConsumerData_OK(t *testing.T) { 134 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 135 w.WriteHeader(http.StatusOK) 136 bytes := []byte(mockConsumerDataResponse) 137 w.Write(bytes) 138 })) 139 defer server.Close() 140 141 c := requests.NewHTTPClient("0.0.0.0", time.Second) 142 caller := NewHermesCaller(c, server.URL) 143 data, err := caller.GetConsumerData(defaultChainID, "0x74CbcbBfEd45D7836D270068116440521033EDc7", -time.Second) 144 assert.Nil(t, err) 145 res, err := json.Marshal(data) 146 assert.Nil(t, err) 147 148 assert.JSONEq(t, mockConsumerData, string(res)) 149 } 150 151 func TestHermesGetConsumerData_Caches(t *testing.T) { 152 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 153 w.WriteHeader(http.StatusOK) 154 bytes := []byte(mockConsumerDataResponse) 155 w.Write(bytes) 156 })) 157 158 c := requests.NewHTTPClient("0.0.0.0", time.Second) 159 caller := NewHermesCaller(c, server.URL) 160 data, err := caller.GetConsumerData(defaultChainID, "0x74CbcbBfEd45D7836D270068116440521033EDc7", -time.Second) 161 server.Close() 162 assert.Nil(t, err) 163 res, err := json.Marshal(data) 164 assert.Nil(t, err) 165 assert.JSONEq(t, mockConsumerData, string(res)) 166 167 server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 168 w.WriteHeader(http.StatusBadRequest) 169 })) 170 defer server.Close() 171 172 data, err = caller.GetConsumerData(defaultChainID, "0x74CbcbBfEd45D7836D270068116440521033EDc7", time.Minute) 173 assert.Nil(t, err) 174 res, err = json.Marshal(data) 175 assert.Nil(t, err) 176 assert.JSONEq(t, mockConsumerData, string(res)) 177 178 _, err = caller.GetConsumerData(defaultChainID, "0x74CbcbBfEd45D7836D270068116440521033EDc7", -time.Second) 179 assert.NotNil(t, err) 180 } 181 182 const defaultChainID = 1 183 184 var mockConsumerData = `{"Identity":"0x74CbcbBfEd45D7836D270068116440521033EDc7","Beneficiary":"0x0000000000000000000000000000000000000000","ChannelID":"0xc80A1758A36cf9a0903a9FE37f98B51AEC978CB6","Balance":133,"Settled":0,"Stake":0,"LatestPromise":{"ChannelID":"0xc80a1758a36cf9a0903a9fe37f98b51aec978cb6","Amount":1077,"Fee":0,"Hashlock":"0x528a7340eb740124306c25c53ac7fa27c0d038ac4ab0bb09c0894487b8d1bc5f","Signature":"0xaf3f9e23336513fa75b5a03cb81dbecf8e4b5c61ce14a9479b8d5728970eab1f1d2cf4d22d14f6441d0ae8db06b5ce34eb18000aae9aeedc013e449fc1ced8a31b","ChainID":1},"LatestSettlement":"0001-01-01T00:00:00Z","IsOffchain":false}` 185 var mockConsumerDataResponse = fmt.Sprintf(`{"%d":%v}`, defaultChainID, mockConsumerData) 186 187 func TestLatestPromise_isValid(t *testing.T) { 188 type fields struct { 189 ChannelID string 190 Amount *big.Int 191 Fee *big.Int 192 Hashlock string 193 Signature string 194 ChainID int64 195 } 196 tests := []struct { 197 name string 198 fields fields 199 id string 200 wantErr bool 201 }{ 202 { 203 name: "returns no error for a valid promise", 204 wantErr: false, 205 id: "0xF53aCDd584ccb85eE4EC1590007aD3c16FDFF057", 206 fields: fields{ 207 ChainID: 1, 208 ChannelID: "0xfd34a0a135b9ed5dc11a4780926efccaedb5e50b", 209 Amount: big.NewInt(4030), 210 Fee: new(big.Int), 211 Hashlock: "0xbcfee24a3f12e1b2f37a560b2bf52fedd3a1f1795844229495711fd4405f139e", 212 Signature: "0xf12c79560a9a9463ffdf5a5f12ff2d33c26345ce62cd7b1d324d897f9f6ce65d7eaf113897b48c2e7ae3d38325db68f212d1dd601c36a608ec24ed3d5f94f9171b", 213 }, 214 }, 215 { 216 name: "returns no error for a valid promise with no prefix on identity", 217 wantErr: false, 218 id: "F53aCDd584ccb85eE4EC1590007aD3c16FDFF057", 219 fields: fields{ 220 ChainID: 1, 221 ChannelID: "0xfd34a0a135b9ed5dc11a4780926efccaedb5e50b", 222 Amount: big.NewInt(4030), 223 Fee: new(big.Int), 224 Hashlock: "0xbcfee24a3f12e1b2f37a560b2bf52fedd3a1f1795844229495711fd4405f139e", 225 Signature: "0xf12c79560a9a9463ffdf5a5f12ff2d33c26345ce62cd7b1d324d897f9f6ce65d7eaf113897b48c2e7ae3d38325db68f212d1dd601c36a608ec24ed3d5f94f9171b", 226 }, 227 }, 228 { 229 name: "returns error for a invalid promise", 230 wantErr: true, 231 id: "0x75C2067Ca5B42467FD6CD789d785aafb52a6B95b", 232 fields: fields{ 233 ChannelID: "0x3295502615e5ddfd1fc7bd22ea5b78d65751a835", 234 Amount: big.NewInt(461730032), 235 Fee: new(big.Int), 236 Hashlock: "0x31c88b635e72755012289cd04bf9b34a11a95f5962f8f1b15dc4b6b80d4af34a", 237 Signature: "0x28d4f2a8c1e2a6b8943e3e110b1d5f66cacaee0841dd7e60ed89e02096419b27188b7c74a9fa1e30e29b4fd75877f503c5d2b193d1d64d7d56232a67b0a102261b", 238 }, 239 }, 240 { 241 name: "returns error for a invalid hex value", 242 wantErr: true, 243 id: "0x75C2067Ca5B42467FD6CD789d785aafb52a6B95b", 244 fields: fields{ 245 ChannelID: "0x3295502615e5ddfd1fc7bd22ea5b78d65751a835", 246 Amount: big.NewInt(461730032), 247 Fee: new(big.Int), 248 Hashlock: "0x0x31c88b635e72755012289cd04bf9b34a11a95f5962f8f1b15dc4b6b80d4af34a", 249 Signature: "0x28d4f2a8c1e2a6b8943e3e110b1d5f66cacaee0841dd7e60ed89e02096419b27188b7c74a9fa1e30e29b4fd75877f503c5d2b193d1d64d7d56232a67b0a102261b", 250 }, 251 }, 252 } 253 for _, tt := range tests { 254 t.Run(tt.name, func(t *testing.T) { 255 lp := LatestPromise{ 256 ChannelID: tt.fields.ChannelID, 257 Amount: tt.fields.Amount, 258 Fee: tt.fields.Fee, 259 Hashlock: tt.fields.Hashlock, 260 Signature: tt.fields.Signature, 261 ChainID: tt.fields.ChainID, 262 } 263 err := lp.isValid(tt.id) 264 if (err != nil) != tt.wantErr { 265 t.Errorf("LatestPromise.isValid() error = %v, wantErr %v", err, tt.wantErr) 266 return 267 } 268 }) 269 } 270 }