github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/session/pingpong/hermes_promise_settler_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 package pingpong 18 19 import ( 20 "encoding/hex" 21 "errors" 22 "fmt" 23 "math/big" 24 "strings" 25 "testing" 26 "time" 27 28 "github.com/ethereum/go-ethereum/common" 29 "github.com/ethereum/go-ethereum/core/types" 30 "github.com/mysteriumnetwork/node/identity" 31 "github.com/mysteriumnetwork/node/identity/registry" 32 "github.com/mysteriumnetwork/node/session/pingpong/event" 33 "github.com/mysteriumnetwork/payments/bindings" 34 "github.com/mysteriumnetwork/payments/client" 35 "github.com/mysteriumnetwork/payments/crypto" 36 "github.com/mysteriumnetwork/payments/units" 37 "github.com/stretchr/testify/assert" 38 ) 39 40 func TestPromiseSettler_loadInitialState(t *testing.T) { 41 mrsp := &mockRegistrationStatusProvider{ 42 identities: map[string]mockRegistrationStatus{ 43 mockChainIdentity: { 44 status: registry.Registered, 45 }, 46 }, 47 } 48 ks := identity.NewMockKeystore() 49 lbs := newMockAddressStorage() 50 51 fac := &mockHermesCallerFactory{} 52 53 settler := NewHermesPromiseSettler( 54 &mockTransactor{}, 55 &mockHermesPromiseStorage{}, 56 &mockPayAndSettler{}, 57 &mockAddressProvider{}, 58 fac.Get, 59 &mockHermesURLGetter{}, 60 &mockHermesChannelProvider{}, 61 &mockProviderChannelStatusProvider{}, 62 mrsp, 63 ks, 64 &settlementHistoryStorageMock{}, 65 &mockPublisher{}, 66 &mockObserver{}, 67 lbs, 68 cfg) 69 70 settler.currentState[mockID] = settlementState{} 71 72 // check if existing gets skipped 73 err := settler.loadInitialState(0, mockID) 74 assert.NoError(t, err) 75 76 v := settler.currentState[mockID] 77 assert.EqualValues(t, settlementState{}, v) 78 79 // check if unregistered gets skipped 80 delete(settler.currentState, mockID) 81 82 mrsp.identities[mockChainIdentity] = mockRegistrationStatus{ 83 status: registry.Registered, 84 } 85 86 err = settler.loadInitialState(0, mockID) 87 assert.NoError(t, err) 88 89 v = settler.currentState[mockID] 90 assert.EqualValues(t, settlementState{ 91 registered: true, 92 settleInProgress: map[common.Address]struct{}{}, 93 }, v) 94 95 // check if will resync 96 delete(settler.currentState, mockID) 97 98 mrsp.identities[mockChainIdentity] = mockRegistrationStatus{ 99 status: registry.Registered, 100 } 101 102 err = settler.loadInitialState(0, mockID) 103 assert.NoError(t, err) 104 105 v = settler.currentState[mockID] 106 assert.True(t, v.registered) 107 108 // check if will bubble registration status errors 109 delete(settler.currentState, mockID) 110 111 mrsp.identities[mockChainIdentity] = mockRegistrationStatus{ 112 status: registry.Registered, 113 err: errMock, 114 } 115 116 err = settler.loadInitialState(0, mockID) 117 assert.Equal(t, fmt.Sprintf("could not check registration status for %v: %v", mockID, errMock.Error()), err.Error()) 118 } 119 120 func TestPromiseSettler_handleRegistrationEvent(t *testing.T) { 121 mrsp := &mockRegistrationStatusProvider{ 122 identities: map[string]mockRegistrationStatus{ 123 mockChainIdentity: { 124 status: registry.Registered, 125 }, 126 }, 127 } 128 ks := identity.NewMockKeystore() 129 fac := &mockHermesCallerFactory{} 130 lbs := newMockAddressStorage() 131 132 settler := NewHermesPromiseSettler( 133 &mockTransactor{}, 134 &mockHermesPromiseStorage{}, 135 &mockPayAndSettler{}, 136 &mockAddressProvider{}, 137 fac.Get, 138 &mockHermesURLGetter{}, 139 &mockHermesChannelProvider{}, 140 &mockProviderChannelStatusProvider{}, 141 mrsp, 142 ks, 143 &settlementHistoryStorageMock{}, 144 &mockPublisher{}, 145 &mockObserver{}, 146 lbs, 147 cfg) 148 149 statusesWithNoChangeExpected := []registry.RegistrationStatus{registry.Unregistered, registry.InProgress, registry.RegistrationError} 150 for _, v := range statusesWithNoChangeExpected { 151 settler.handleRegistrationEvent(registry.AppEventIdentityRegistration{ 152 ID: mockID, 153 Status: v, 154 }) 155 156 _, ok := settler.currentState[mockID] 157 158 assert.False(t, ok) 159 } 160 161 settler.handleRegistrationEvent(registry.AppEventIdentityRegistration{ 162 ID: mockID, 163 Status: registry.Registered, 164 }) 165 166 v, ok := settler.currentState[mockID] 167 assert.True(t, ok) 168 assert.True(t, v.registered) 169 } 170 171 func TestPromiseSettler_handleHermesPromiseReceived(t *testing.T) { 172 channelProvider := &mockHermesChannelProvider{} 173 channelStatusProvider := &mockProviderChannelStatusProvider{} 174 mrsp := &mockRegistrationStatusProvider{ 175 identities: map[string]mockRegistrationStatus{ 176 mockChainIdentity: { 177 status: registry.Registered, 178 }, 179 }, 180 } 181 ks := identity.NewMockKeystore() 182 fac := &mockHermesCallerFactory{} 183 tm := &mockTransactor{ 184 feesToReturn: registry.FeesResponse{ 185 Fee: units.FloatEthToBigIntWei(0.05), 186 ValidUntil: time.Now().Add(30 * time.Minute), 187 }, 188 } 189 lbs := newMockAddressStorage() 190 191 settler := NewHermesPromiseSettler(tm, &mockHermesPromiseStorage{}, &mockPayAndSettler{}, &mockAddressProvider{}, fac.Get, &mockHermesURLGetter{}, channelProvider, channelStatusProvider, mrsp, ks, &settlementHistoryStorageMock{}, &mockPublisher{}, &mockObserver{}, lbs, cfg) 192 193 // no receive on unknown provider 194 channelProvider.channelToReturn = NewHermesChannel("1", mockID, hermesID, mockProviderChannel, HermesPromise{}, beneficiaryID) 195 settler.handleHermesPromiseReceived(event.AppEventHermesPromise{ 196 HermesID: hermesID, 197 ProviderID: mockID, 198 }) 199 assertNoReceive(t, settler.settleQueue) 200 201 // no receive should be gotten on a non registered provider 202 settler.currentState[mockID] = settlementState{ 203 registered: false, 204 settleInProgress: map[common.Address]struct{}{}, 205 } 206 channelProvider.channelToReturn = NewHermesChannel("1", mockID, hermesID, mockProviderChannel, HermesPromise{}, beneficiaryID) 207 settler.handleHermesPromiseReceived(event.AppEventHermesPromise{ 208 HermesID: hermesID, 209 ProviderID: mockID, 210 }) 211 assertNoReceive(t, settler.settleQueue) 212 213 // should receive on registered provider. Should also expect a recalculated balance to be added to the settlementState 214 expectedChannel := client.ProviderChannel{Stake: big.NewInt(1000)} 215 expectedPromise := crypto.Promise{Amount: units.FloatEthToBigIntWei(6)} 216 settler.currentState[mockID] = settlementState{ 217 registered: true, 218 settleInProgress: map[common.Address]struct{}{}, 219 } 220 channelProvider.channelToReturn = NewHermesChannel("1", mockID, hermesID, expectedChannel, HermesPromise{Promise: expectedPromise}, beneficiaryID) 221 settler.handleHermesPromiseReceived(event.AppEventHermesPromise{ 222 HermesID: hermesID, 223 ProviderID: mockID, 224 Promise: expectedPromise, 225 }) 226 227 p := <-settler.settleQueue 228 assert.Equal(t, mockID, p.provider) 229 230 // should not receive here due to balance being large and stake being small 231 expectedChannel = client.ProviderChannel{ 232 Stake: big.NewInt(0), 233 Settled: units.FloatEthToBigIntWei(6), 234 } 235 expectedPromise = crypto.Promise{Amount: units.FloatEthToBigIntWei(8)} 236 settler.currentState[mockID] = settlementState{ 237 registered: true, 238 settleInProgress: map[common.Address]struct{}{}, 239 } 240 channelProvider.channelToReturn = NewHermesChannel("1", mockID, hermesID, expectedChannel, HermesPromise{Promise: expectedPromise}, beneficiaryID) 241 settler.handleHermesPromiseReceived(event.AppEventHermesPromise{ 242 HermesID: hermesID, 243 ProviderID: mockID, 244 Promise: expectedPromise, 245 }) 246 assertNoReceive(t, settler.settleQueue) 247 } 248 249 func TestPromiseSettler_handleHermesPromiseReceivedWithLocalBeneficiary(t *testing.T) { 250 channelProvider := &mockHermesChannelProvider{} 251 channelStatusProvider := &mockProviderChannelStatusProvider{} 252 mrsp := &mockRegistrationStatusProvider{ 253 identities: map[string]mockRegistrationStatus{ 254 mockChainIdentity: { 255 status: registry.Registered, 256 }, 257 }, 258 } 259 ks := identity.NewMockKeystore() 260 fac := &mockHermesCallerFactory{} 261 tm := &mockTransactor{ 262 feesToReturn: registry.FeesResponse{ 263 Fee: units.FloatEthToBigIntWei(0.05), 264 ValidUntil: time.Now().Add(30 * time.Minute), 265 }, 266 } 267 lbs := newMockAddressStorage() 268 269 settler := NewHermesPromiseSettler(tm, &mockHermesPromiseStorage{}, &mockPayAndSettler{}, &mockAddressProvider{}, fac.Get, &mockHermesURLGetter{}, channelProvider, channelStatusProvider, mrsp, ks, &settlementHistoryStorageMock{}, &mockPublisher{}, &mockObserver{}, lbs, cfg) 270 271 expectedChannel := client.ProviderChannel{Stake: big.NewInt(1000)} 272 expectedPromise := crypto.Promise{Amount: units.FloatEthToBigIntWei(6)} 273 settler.currentState[mockID] = settlementState{ 274 registered: true, 275 settleInProgress: map[common.Address]struct{}{}, 276 } 277 channelProvider.channelToReturn = NewHermesChannel("1", mockID, hermesID, expectedChannel, HermesPromise{Promise: expectedPromise}, beneficiaryID) 278 settler.handleHermesPromiseReceived(event.AppEventHermesPromise{ 279 HermesID: hermesID, 280 ProviderID: mockID, 281 Promise: expectedPromise, 282 }) 283 284 p := <-settler.settleQueue 285 assert.Equal(t, mockID, p.provider) 286 assert.Equal(t, beneficiaryID, p.beneficiary) 287 288 localBeneficiary := common.HexToAddress("0x00000000000000000000000000000000000000133") 289 err := lbs.Save(mockID.Address, localBeneficiary.Hex()) 290 assert.NoError(t, err) 291 292 settler.handleHermesPromiseReceived(event.AppEventHermesPromise{ 293 HermesID: hermesID, 294 ProviderID: mockID, 295 Promise: expectedPromise, 296 }) 297 p = <-settler.settleQueue 298 assert.Equal(t, mockID, p.provider) 299 } 300 301 func TestPromiseSettler_doNotSettleIfBeneficiaryIsAChannel(t *testing.T) { 302 channelProvider := &mockHermesChannelProvider{} 303 channelStatusProvider := &mockProviderChannelStatusProvider{} 304 mrsp := &mockRegistrationStatusProvider{ 305 identities: map[string]mockRegistrationStatus{ 306 mockChainIdentity: { 307 status: registry.Registered, 308 }, 309 }, 310 } 311 ks := identity.NewMockKeystore() 312 fac := &mockHermesCallerFactory{} 313 tm := &mockTransactor{ 314 feesToReturn: registry.FeesResponse{ 315 Fee: units.FloatEthToBigIntWei(0.05), 316 ValidUntil: time.Now().Add(30 * time.Minute), 317 }, 318 } 319 lbs := newMockAddressStorage() 320 321 mockAddressProvider := newMockAddressProvider() 322 settler := NewHermesPromiseSettler(tm, &mockHermesPromiseStorage{}, &mockPayAndSettler{}, mockAddressProvider, fac.Get, &mockHermesURLGetter{}, channelProvider, channelStatusProvider, mrsp, ks, &settlementHistoryStorageMock{}, &mockPublisher{}, &mockObserver{}, lbs, cfg) 323 324 expectedChannel := client.ProviderChannel{Stake: big.NewInt(1000)} 325 expectedPromise := crypto.Promise{Amount: units.FloatEthToBigIntWei(6)} 326 settler.currentState[mockID] = settlementState{ 327 registered: true, 328 settleInProgress: map[common.Address]struct{}{}, 329 } 330 channelProvider.channelToReturn = NewHermesChannel("1", mockID, hermesID, expectedChannel, HermesPromise{Promise: expectedPromise}, beneficiaryID) 331 settler.handleHermesPromiseReceived(event.AppEventHermesPromise{ 332 HermesID: hermesID, 333 ProviderID: mockID, 334 Promise: expectedPromise, 335 }) 336 337 p := <-settler.settleQueue 338 assert.Equal(t, mockID, p.provider) 339 assert.Equal(t, beneficiaryID, p.beneficiary) 340 341 mockAddressProvider.setChannelAddress(0, mockID.ToCommonAddress(), beneficiaryID) 342 channelProvider.channelToReturn = NewHermesChannel("1", mockID, hermesID, expectedChannel, HermesPromise{Promise: expectedPromise}, beneficiaryID) 343 settler.handleHermesPromiseReceived(event.AppEventHermesPromise{ 344 HermesID: hermesID, 345 ProviderID: mockID, 346 Promise: expectedPromise, 347 }) 348 349 p = <-settler.settleQueue 350 assert.Equal(t, mockID, p.provider) 351 assert.Equal(t, beneficiaryID, p.beneficiary) 352 } 353 354 func assertNoReceive(t *testing.T, ch chan receivedPromise) { 355 // at this point, we should not receive an event on settled queue as we have no info on provider, let's check for that 356 select { 357 case <-ch: 358 assert.Fail(t, "did not expect to receive from settled queue") 359 case <-time.After(time.Millisecond * 2): 360 // we've not received on the channel, continue 361 } 362 } 363 364 func TestPromiseSettler_handleNodeStart(t *testing.T) { 365 ks := identity.NewMockKeystore() 366 367 acc1, err := ks.NewAccount("") 368 assert.NoError(t, err) 369 acc2, err := ks.NewAccount("") 370 assert.NoError(t, err) 371 372 lbs := newMockAddressStorage() 373 374 mrsp := &mockRegistrationStatusProvider{ 375 identities: map[string]mockRegistrationStatus{ 376 "0" + strings.ToLower(acc2.Address.Hex()): { 377 status: registry.Registered, 378 }, 379 "0" + strings.ToLower(acc1.Address.Hex()): { 380 status: registry.Unregistered, 381 }, 382 }, 383 } 384 385 fac := &mockHermesCallerFactory{} 386 settler := NewHermesPromiseSettler( 387 &mockTransactor{}, 388 &mockHermesPromiseStorage{}, 389 &mockPayAndSettler{}, 390 &mockAddressProvider{}, 391 fac.Get, 392 &mockHermesURLGetter{}, 393 &mockHermesChannelProvider{}, 394 &mockProviderChannelStatusProvider{}, 395 mrsp, 396 ks, 397 &settlementHistoryStorageMock{}, 398 &mockPublisher{}, 399 &mockObserver{}, 400 lbs, 401 cfg) 402 403 settler.handleNodeStart() 404 405 // since each address is checked on BC in background, we'll need to wait here until that is complete 406 time.Sleep(time.Millisecond * 10) 407 408 // since we're accessing the current state from outside the setller, lock the settler to prevent race conditions 409 settler.lock.Lock() 410 defer settler.lock.Unlock() 411 412 assert.True(t, settler.currentState[identity.FromAddress(acc2.Address.Hex())].registered) 413 assert.False(t, settler.currentState[identity.FromAddress(acc1.Address.Hex())].registered) 414 } 415 416 func TestPromiseSettler_RejectsIfFeesExceedSettlementAmount(t *testing.T) { 417 fac := &mockHermesCallerFactory{} 418 transactorFee := big.NewInt(5000) 419 hermesFee := big.NewInt(25000) 420 421 promiseSettler := hermesPromiseSettler{ 422 currentState: map[identity.Identity]settlementState{}, 423 transactor: &mockTransactor{ 424 feesToReturn: registry.FeesResponse{ 425 Fee: transactorFee, 426 }, 427 }, 428 hermesCallerFactory: fac.Get, 429 hermesURLGetter: &mockHermesURLGetter{}, 430 bc: &mockProviderChannelStatusProvider{ 431 calculatedFees: hermesFee, 432 }, 433 } 434 435 mockPromise := crypto.Promise{ 436 Fee: transactorFee, 437 Amount: big.NewInt(35000), 438 } 439 440 settled := big.NewInt(6000) 441 442 mockSettler := func(crypto.Promise) (string, error) { return "", nil } 443 err := promiseSettler.settle(mockSettler, identity.Identity{}, common.Address{}, mockPromise, common.Address{}, settled, nil) 444 assert.Equal(t, "settlement fees exceed earning amount. Please provide more service and try again. Current earnings: 29000, current fees: 30000: fee not covered, cannot continue", err.Error()) 445 } 446 447 func TestPromiseSettler_RejectsIfFeesExceedMaxFee(t *testing.T) { 448 fac := &mockHermesCallerFactory{} 449 transactorFee := units.FloatEthToBigIntWei(0.8) 450 hermesFee := big.NewInt(25000) 451 452 promiseSettler := hermesPromiseSettler{ 453 currentState: map[identity.Identity]settlementState{}, 454 transactor: &mockTransactor{ 455 feesToReturn: registry.FeesResponse{ 456 Fee: transactorFee, 457 }, 458 }, 459 hermesCallerFactory: fac.Get, 460 hermesURLGetter: &mockHermesURLGetter{}, 461 bc: &mockProviderChannelStatusProvider{ 462 calculatedFees: hermesFee, 463 }, 464 } 465 466 mockPromise := crypto.Promise{ 467 Fee: transactorFee, 468 Amount: big.NewInt(35000), 469 } 470 471 settled := big.NewInt(6000) 472 473 mockSettler := func(crypto.Promise) (string, error) { return "", nil } 474 err := promiseSettler.settle(mockSettler, identity.Identity{}, common.Address{}, mockPromise, common.Address{}, settled, units.FloatEthToBigIntWei(0.6)) 475 assert.Equal(t, "current fee is more than the max", err.Error()) 476 } 477 478 func TestPromiseSettler_AcceptsIfFeesDoNotExceedSettlementAmount(t *testing.T) { 479 fac := &mockHermesCallerFactory{} 480 transactorFee := big.NewInt(5000) 481 hermesFee := big.NewInt(20000) 482 expectedChannel, err := hex.DecodeString("d0bb35eb0e4a0c972f2c154f91cf676b804762bef69c7fe4cef38642c3ac7ffc") 483 assert.NoError(t, err) 484 485 expectedR, err := hex.DecodeString("d56e23228dc2c7d2cc2e0ee08d7d6e5be6aa196c9f95046d83fab06913d2a9c2") 486 assert.NoError(t, err) 487 488 var arr [32]byte 489 copy(arr[:], expectedChannel) 490 491 var r [32]byte 492 copy(r[:], expectedR) 493 bc := &mockProviderChannelStatusProvider{ 494 calculatedFees: hermesFee, 495 subCancel: func() {}, 496 promiseEventsToReturn: []bindings.HermesImplementationPromiseSettled{ 497 { 498 ChannelId: arr, 499 Lock: r, 500 }, 501 }, 502 headerToReturn: &types.Header{ 503 Number: big.NewInt(0), 504 }, 505 } 506 507 publisher := &mockPublisher{ 508 publicationChan: make(chan testEvent, 10), 509 } 510 promiseSettler := hermesPromiseSettler{ 511 currentState: make(map[identity.Identity]settlementState), 512 transactor: &mockTransactor{ 513 idToReturn: "123", 514 queueToReturn: registry.QueueResponse{ 515 State: "done", 516 }, 517 feesToReturn: registry.FeesResponse{ 518 Fee: transactorFee, 519 }, 520 }, 521 hermesCallerFactory: fac.Get, 522 hermesURLGetter: &mockHermesURLGetter{}, 523 bc: bc, 524 channelProvider: &mockHermesChannelProvider{}, 525 config: HermesPromiseSettlerConfig{ 526 SettlementCheckTimeout: time.Millisecond * 50, 527 }, 528 settlementHistoryStorage: &settlementHistoryStorageMock{}, 529 publisher: publisher, 530 } 531 532 mockPromise := crypto.Promise{ 533 Fee: transactorFee, 534 Amount: big.NewInt(35000), 535 R: r[:], 536 } 537 538 settled := big.NewInt(6000) 539 540 mockSettler := func(crypto.Promise) (string, error) { return "", nil } 541 542 err = promiseSettler.settle(mockSettler, identity.Identity{Address: "0x92fE1c838b08dB4c072DDa805FB4292d9b76B5E7"}, common.HexToAddress("0x07b5fD382b5e375F202184052BeF2C50b3B1404F"), mockPromise, common.Address{}, settled, nil) 543 assert.NoError(t, err) 544 ev := <-publisher.publicationChan 545 assert.Equal(t, event.AppTopicSettlementComplete, ev.name) 546 _, ok := ev.value.(event.AppEventSettlementComplete) 547 assert.True(t, ok) 548 } 549 550 func TestPromiseSettlerState_needsSettling(t *testing.T) { 551 hps := &hermesPromiseSettler{ 552 transactor: &mockTransactor{ 553 feesToReturn: registry.FeesResponse{ 554 Fee: units.FloatEthToBigIntWei(2.0), 555 ValidUntil: time.Now().Add(30 * time.Minute), 556 }, 557 }, 558 } 559 s := settlementState{ 560 registered: true, 561 settleInProgress: map[common.Address]struct{}{}, 562 } 563 channel := NewHermesChannel( 564 "1", 565 mockID, 566 hermesID, 567 client.ProviderChannel{Stake: big.NewInt(0)}, 568 HermesPromise{Promise: crypto.Promise{Amount: units.FloatEthToBigIntWei(10.1)}}, 569 beneficiaryID, 570 ) 571 needs, maxFee := hps.needsSettling(s, 0, 0.1, 5, 10, channel, 1) 572 assert.True(t, needs, "should be true with balance more than max regardless of fees") 573 assert.Nil(t, maxFee, "should be nil") 574 575 hps = &hermesPromiseSettler{ 576 transactor: &mockTransactor{ 577 feesToReturn: registry.FeesResponse{ 578 Fee: units.FloatEthToBigIntWei(0.045), 579 ValidUntil: time.Now().Add(30 * time.Minute), 580 }, 581 }, 582 } 583 s = settlementState{ 584 registered: true, 585 settleInProgress: map[common.Address]struct{}{}, 586 } 587 channel = NewHermesChannel( 588 "1", 589 mockID, 590 hermesID, 591 client.ProviderChannel{Stake: big.NewInt(0)}, 592 HermesPromise{Promise: crypto.Promise{Amount: units.FloatEthToBigIntWei(5)}}, 593 beneficiaryID, 594 ) 595 596 needs, maxFee = hps.needsSettling(s, 0, 0.01, 5, 10, channel, 1) 597 assert.True(t, needs, "should be true if fees are 1%% of unsettled amount") 598 assert.True(t, maxFee.Cmp(units.FloatEthToBigIntWei(0.045)) > 0, "should be bigger than current fee") 599 600 s.registered = false 601 needs, _ = hps.needsSettling(s, 0, 0.01, 5, 10, channel, 1) 602 assert.False(t, needs, "should be false with no registration") 603 604 s.settleInProgress = map[common.Address]struct{}{ 605 hermesID: {}, 606 } 607 needs, _ = hps.needsSettling(s, 0, 0.01, 5, 10, channel, 1) 608 assert.False(t, needs, "should be false with settle in progress") 609 610 hps = &hermesPromiseSettler{ 611 transactor: &mockTransactor{ 612 feesToReturn: registry.FeesResponse{ 613 Fee: units.FloatEthToBigIntWei(0.051), 614 ValidUntil: time.Now().Add(30 * time.Minute), 615 }, 616 }, 617 } 618 s = settlementState{ 619 registered: true, 620 settleInProgress: map[common.Address]struct{}{}, 621 } 622 channel = NewHermesChannel( 623 "1", 624 mockID, 625 hermesID, 626 client.ProviderChannel{Stake: big.NewInt(0)}, 627 HermesPromise{Promise: crypto.Promise{Amount: big.NewInt(8999)}}, 628 beneficiaryID, 629 ) 630 needs, _ = hps.needsSettling(s, 0, 0.01, 5, 10, channel, 1) 631 assert.False(t, needs, "should be false with fee more than 1%% of unsettled amount") 632 633 s = settlementState{ 634 registered: true, 635 settleInProgress: map[common.Address]struct{}{}, 636 } 637 channel = NewHermesChannel( 638 "1", 639 mockID, 640 hermesID, 641 client.ProviderChannel{Stake: big.NewInt(1000)}, 642 HermesPromise{Promise: crypto.Promise{Amount: big.NewInt(1000)}}, 643 beneficiaryID, 644 ) 645 needs, maxFee = hps.needsSettling(s, 0.1, 0.01, 5, 10, channel, 1) 646 assert.True(t, needs, "should be true with zero balance left") 647 assert.Nil(t, maxFee, "should be nil") 648 649 s = settlementState{ 650 registered: true, 651 settleInProgress: map[common.Address]struct{}{}, 652 } 653 channel = NewHermesChannel( 654 "1", 655 mockID, 656 hermesID, 657 client.ProviderChannel{Stake: big.NewInt(1000)}, 658 HermesPromise{Promise: crypto.Promise{Amount: big.NewInt(9000)}}, 659 beneficiaryID, 660 ) 661 needs, maxFee = hps.needsSettling(s, 0.1, 0.01, 5, 10, channel, 1) 662 assert.True(t, needs, "should be true with 10% missing") 663 assert.Nil(t, maxFee, "should be nil") 664 665 s = settlementState{ 666 registered: true, 667 settleInProgress: map[common.Address]struct{}{}, 668 } 669 channel = NewHermesChannel( 670 "1", 671 mockID, 672 hermesID, 673 client.ProviderChannel{Stake: big.NewInt(10000)}, 674 HermesPromise{Promise: crypto.Promise{Amount: big.NewInt(8999)}}, 675 beneficiaryID, 676 ) 677 needs, _ = hps.needsSettling(s, 0.1, 0.01, 5, 10, channel, 1) 678 assert.False(t, needs, "should be false with 10.01% missing") 679 } 680 681 // mocks start here 682 type mockProviderChannelStatusProvider struct { 683 channelToReturn client.ProviderChannel 684 channelReturnError error 685 sinkToReturn chan *bindings.HermesImplementationPromiseSettled 686 subCancel func() 687 subError error 688 feeToReturn uint16 689 feeError error 690 calculatedFees *big.Int 691 calculationError error 692 balanceToReturn *big.Int 693 headerToReturn *types.Header 694 errorToReturn error 695 promiseEventsToReturn []bindings.HermesImplementationPromiseSettled 696 promiseError error 697 } 698 699 func (mpcsp *mockProviderChannelStatusProvider) TransactionReceipt(chainID int64, hash common.Hash) (*types.Receipt, error) { 700 r := &types.Receipt{} 701 r.Status = types.ReceiptStatusSuccessful 702 return r, nil 703 } 704 705 func (mpcsp *mockProviderChannelStatusProvider) GetProviderChannel(chainID int64, hermesAddress common.Address, addressToCheck common.Address, pending bool) (client.ProviderChannel, error) { 706 return mpcsp.channelToReturn, mpcsp.channelReturnError 707 } 708 709 func (mpcsp *mockProviderChannelStatusProvider) GetHermesFee(chainID int64, hermesAddress common.Address) (uint16, error) { 710 return mpcsp.feeToReturn, mpcsp.feeError 711 } 712 713 func (mpcsp *mockProviderChannelStatusProvider) GetBeneficiary(chainID int64, registryAddress, identity common.Address) (common.Address, error) { 714 return common.Address{}, nil 715 } 716 717 func (mpcsp *mockProviderChannelStatusProvider) CalculateHermesFee(chainID int64, hermesAddress common.Address, value *big.Int) (*big.Int, error) { 718 return mpcsp.calculatedFees, mpcsp.calculationError 719 } 720 721 func (mpcsp *mockProviderChannelStatusProvider) GetMystBalance(chainID int64, mystAddress common.Address, address common.Address) (*big.Int, error) { 722 return mpcsp.balanceToReturn, nil 723 } 724 725 func (mpcsp *mockProviderChannelStatusProvider) GetProvidersWithdrawalChannel(chainID int64, hermesAddress common.Address, addressToCheck common.Address, pending bool) (client.ProviderChannel, error) { 726 return client.ProviderChannel{}, nil 727 } 728 729 func (mpcsp *mockProviderChannelStatusProvider) FilterPromiseSettledEventByChannelID(chainID int64, from uint64, to *uint64, hermesID common.Address, providerAddresses [][32]byte) ([]bindings.HermesImplementationPromiseSettled, error) { 730 return mpcsp.promiseEventsToReturn, mpcsp.promiseError 731 } 732 733 func (mpcsp *mockProviderChannelStatusProvider) HeaderByNumber(chainID int64, number *big.Int) (*types.Header, error) { 734 return mpcsp.headerToReturn, mpcsp.errorToReturn 735 } 736 737 var cfg = HermesPromiseSettlerConfig{ 738 MaxFeeThreshold: 0.01, 739 MinAutoSettleAmount: 5, 740 MaxUnSettledAmount: 20, 741 SettlementCheckTimeout: time.Millisecond * 10, 742 SettlementCheckInterval: time.Millisecond * 1, 743 } 744 745 type mockHermesChannelProvider struct { 746 channelToReturn HermesChannel 747 channelReturnError error 748 } 749 750 func (mhcp *mockHermesChannelProvider) Get(chainID int64, _ identity.Identity, _ common.Address) (HermesChannel, bool) { 751 return mhcp.channelToReturn, true 752 } 753 754 func (mhcp *mockHermesChannelProvider) Fetch(chainID int64, _ identity.Identity, _ common.Address) (HermesChannel, error) { 755 return mhcp.channelToReturn, mhcp.channelReturnError 756 } 757 758 type mockRegistrationStatus struct { 759 status registry.RegistrationStatus 760 err error 761 } 762 763 type mockRegistrationStatusProvider struct { 764 identities map[string]mockRegistrationStatus 765 } 766 767 func (mrsp *mockRegistrationStatusProvider) GetRegistrationStatus(chainID int64, id identity.Identity) (registry.RegistrationStatus, error) { 768 if v, ok := mrsp.identities[fmt.Sprintf("%d%s", chainID, id.Address)]; ok { 769 return v.status, v.err 770 } 771 772 return registry.Unregistered, nil 773 } 774 775 var errMock = errors.New("explosions everywhere") 776 var mockID = identity.FromAddress("0x0000000000000000000000000000000000000001") 777 var hermesID = common.HexToAddress("0x00000000000000000000000000000000000000002") 778 var beneficiaryID = common.HexToAddress("0x00000000000000000000000000000000000000132") 779 var mockChainIdentity = "0" + mockID.Address 780 781 var mockProviderChannel = client.ProviderChannel{ 782 Settled: big.NewInt(9000000), 783 Stake: big.NewInt(1000000000000), 784 } 785 786 type mockTransactor struct { 787 feesError error 788 feesToReturn registry.FeesResponse 789 790 statusToReturn registry.TransactorStatusResponse 791 statusError error 792 793 queueToReturn registry.QueueResponse 794 queueError error 795 796 idToReturn string 797 settleError error 798 } 799 800 func (mt *mockTransactor) FetchSettleFees(chainID int64) (registry.FeesResponse, error) { 801 return mt.feesToReturn, mt.feesError 802 } 803 804 func (mt *mockTransactor) SettleAndRebalance(_, _ string, _ crypto.Promise) (string, error) { 805 return mt.idToReturn, mt.settleError 806 } 807 808 func (mt *mockTransactor) SettleWithBeneficiary(_, _, _ string, _ crypto.Promise) (string, error) { 809 return mt.idToReturn, mt.settleError 810 } 811 812 func (mt *mockTransactor) SettleIntoStake(accountantID, providerID string, promise crypto.Promise) (string, error) { 813 return mt.idToReturn, mt.settleError 814 } 815 816 func (mt *mockTransactor) PayAndSettle(hermesID, providerID string, promise crypto.Promise, beneficiary string, beneficiarySignature string) (string, error) { 817 return mt.idToReturn, mt.settleError 818 } 819 820 func (mt *mockTransactor) FetchRegistrationStatus(id string) ([]registry.TransactorStatusResponse, error) { 821 return []registry.TransactorStatusResponse{mt.statusToReturn}, mt.statusError 822 } 823 824 func (mt *mockTransactor) FetchRegistrationFees(chainID int64) (registry.FeesResponse, error) { 825 return mt.feesToReturn, mt.feesError 826 } 827 828 func (mt *mockTransactor) GetQueueStatus(ID string) (registry.QueueResponse, error) { 829 return mt.queueToReturn, mt.queueError 830 } 831 832 type settlementHistoryStorageMock struct{} 833 834 func (shsm *settlementHistoryStorageMock) Store(_ SettlementHistoryEntry) error { 835 return nil 836 } 837 838 type mockPayAndSettler struct{} 839 840 func (mpas *mockPayAndSettler) PayAndSettle(r []byte, em crypto.ExchangeMessage, providerID identity.Identity, sessionID string) <-chan error { 841 return nil 842 } 843 844 type mockAddressStorage struct { 845 data map[string]string 846 } 847 848 func newMockAddressStorage() *mockAddressStorage { 849 return &mockAddressStorage{data: make(map[string]string)} 850 } 851 852 func (m mockAddressStorage) Address(identity string) (string, error) { 853 return m.data[identity], nil 854 } 855 856 func (m mockAddressStorage) Save(identity, address string) error { 857 m.data[identity] = address 858 return nil 859 }