diff --git a/Makefile b/Makefile index 72b61c96..a43ae01f 100644 --- a/Makefile +++ b/Makefile @@ -43,6 +43,7 @@ genmocks: mockgen -source=./api/handlers/signing.go -destination=./api/handlers/mock/signing.go mockgen -package mock_message -destination=./chains/evm/message/mock/pricing.go github.com/sprintertech/lifi-solver/pkg/pricing OrderPricer mockgen -source=./chains/lighter/message/lighter.go -destination=./chains/lighter/message/mock/lighter.go + mockgen -source=./protocol/lifi/event.go -destination=./protocol/lifi/mock/event.go diff --git a/app/app.go b/app/app.go index 82cdd953..5bff102d 100644 --- a/app/app.go +++ b/app/app.go @@ -304,7 +304,10 @@ func Run() error { resolver := token.NewTokenResolver(solverConfig, usdPricer) orderPricer := pricing.NewStandardPricer(resolver) - lifiApi := lifi.NewLifiAPI() + lifiApi := lifi.NewLifiEventFetcher( + client, + common.HexToAddress(c.LifiInputSettlerEscrow), + ) lifiValidator := validation.NewLifiEscrowOrderValidator(solverConfig, resolver) lifiMh := evmMessage.NewLifiEscrowMessageHandler( diff --git a/chains/evm/config.go b/chains/evm/config.go index 28042b85..9449fd24 100644 --- a/chains/evm/config.go +++ b/chains/evm/config.go @@ -21,11 +21,12 @@ type EVMConfig struct { GeneralChainConfig chain.GeneralChainConfig Admin string - AcrossPool string - AcrossHubPool string - MayanSwift string - LifiOutputSettler string - Repayer string + AcrossPool string + AcrossHubPool string + MayanSwift string + LifiOutputSettler string + LifiInputSettlerEscrow string + Repayer string // Liquidator contract per token address Liquidators map[common.Address]common.Address @@ -102,14 +103,15 @@ func NewEVMConfig(chainConfig map[string]interface{}, solverConfig solverConfig. c.ParseFlags() config := &EVMConfig{ - GeneralChainConfig: c.GeneralChainConfig, - Admin: c.Admin, - Repayer: solverConfig.ProtocolsMetadata.Sprinter.Repayer[id], - AcrossPool: solverConfig.ProtocolsMetadata.Across.SpokePools[id], - AcrossHubPool: solverConfig.ProtocolsMetadata.Across.HubPools[id], - MayanSwift: solverConfig.ProtocolsMetadata.Mayan.SwiftContracts[id], - LifiOutputSettler: solverConfig.ProtocolsMetadata.Lifi.OutputSettler, - Liquidators: liquidators, + GeneralChainConfig: c.GeneralChainConfig, + Admin: c.Admin, + Repayer: solverConfig.ProtocolsMetadata.Sprinter.Repayer[id], + AcrossPool: solverConfig.ProtocolsMetadata.Across.SpokePools[id], + AcrossHubPool: solverConfig.ProtocolsMetadata.Across.HubPools[id], + MayanSwift: solverConfig.ProtocolsMetadata.Mayan.SwiftContracts[id], + LifiOutputSettler: solverConfig.ProtocolsMetadata.Lifi.OutputSettler, + LifiInputSettlerEscrow: solverConfig.ProtocolsMetadata.Lifi.InputSettlerEscrow, + Liquidators: liquidators, // nolint:gosec BlockRetryInterval: time.Duration(c.BlockRetryInterval) * time.Second, diff --git a/chains/evm/config_test.go b/chains/evm/config_test.go index b66f41d3..597e7a04 100644 --- a/chains/evm/config_test.go +++ b/chains/evm/config_test.go @@ -109,7 +109,8 @@ func (s *NewEVMConfigTestSuite) Test_ValidConfig() { }, }, Lifi: &solverConfig.LifiMetadata{ - OutputSettler: "settler", + OutputSettler: "settler", + InputSettlerEscrow: "escrowSettler", }, SprinterCredit: map[string][]solverConfig.SprinterCredit{ "eip155:1": { @@ -133,16 +134,17 @@ func (s *NewEVMConfigTestSuite) Test_ValidConfig() { BlockConfirmations: 5, Blocktime: 12, }, - BlockInterval: big.NewInt(5), - BlockRetryInterval: time.Duration(5) * time.Second, - Admin: "adminAddress", - Repayer: "repayer", - AcrossPool: "acrossPool", - AcrossHubPool: "acrossHubPool", - MayanSwift: "mayanSwift", - LifiOutputSettler: "settler", - ConfirmationsByValue: make(map[uint64]uint64), - Tokens: make(map[string]config.TokenConfig), + BlockInterval: big.NewInt(5), + BlockRetryInterval: time.Duration(5) * time.Second, + Admin: "adminAddress", + Repayer: "repayer", + AcrossPool: "acrossPool", + AcrossHubPool: "acrossHubPool", + MayanSwift: "mayanSwift", + LifiOutputSettler: "settler", + LifiInputSettlerEscrow: "escrowSettler", + ConfirmationsByValue: make(map[uint64]uint64), + Tokens: make(map[string]config.TokenConfig), Liquidators: map[common.Address]common.Address{ common.HexToAddress("0x12"): common.HexToAddress(liquidator), }, diff --git a/chains/evm/message/lifiEscrow.go b/chains/evm/message/lifiEscrow.go index 59cbd9f8..73e6c0a0 100644 --- a/chains/evm/message/lifiEscrow.go +++ b/chains/evm/message/lifiEscrow.go @@ -27,7 +27,7 @@ import ( ) type OrderFetcher interface { - GetOrder(orderID string) (*lifi.LifiOrder, error) + Order(ctx context.Context, hash common.Hash, orderID common.Hash) (*lifi.LifiOrder, error) } type OrderValidator interface { @@ -97,7 +97,10 @@ func (h *LifiEscrowMessageHandler) HandleMessage(m *message.Message) (*proposal. log.Warn().Msgf("Failed to notify relayers because of %s", err) } - order, err := h.orderFetcher.GetOrder(data.OrderID) + order, err := h.orderFetcher.Order( + context.Background(), + common.HexToHash(data.DepositTxHash), + common.HexToHash(data.OrderID)) if err != nil { data.ErrChn <- err return nil, err diff --git a/chains/evm/message/mock/lifiEscrow.go b/chains/evm/message/mock/lifiEscrow.go index 0ed4beac..69d693e8 100644 --- a/chains/evm/message/mock/lifiEscrow.go +++ b/chains/evm/message/mock/lifiEscrow.go @@ -10,8 +10,10 @@ package mock_message import ( + context "context" reflect "reflect" + common "github.com/ethereum/go-ethereum/common" lifi "github.com/sprintertech/lifi-solver/pkg/protocols/lifi" gomock "go.uber.org/mock/gomock" ) @@ -40,19 +42,19 @@ func (m *MockOrderFetcher) EXPECT() *MockOrderFetcherMockRecorder { return m.recorder } -// GetOrder mocks base method. -func (m *MockOrderFetcher) GetOrder(orderID string) (*lifi.LifiOrder, error) { +// Order mocks base method. +func (m *MockOrderFetcher) Order(ctx context.Context, hash, orderID common.Hash) (*lifi.LifiOrder, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetOrder", orderID) + ret := m.ctrl.Call(m, "Order", ctx, hash, orderID) ret0, _ := ret[0].(*lifi.LifiOrder) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetOrder indicates an expected call of GetOrder. -func (mr *MockOrderFetcherMockRecorder) GetOrder(orderID any) *gomock.Call { +// Order indicates an expected call of Order. +func (mr *MockOrderFetcherMockRecorder) Order(ctx, hash, orderID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOrder", reflect.TypeOf((*MockOrderFetcher)(nil).GetOrder), orderID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Order", reflect.TypeOf((*MockOrderFetcher)(nil).Order), ctx, hash, orderID) } // MockOrderValidator is a mock of OrderValidator interface. diff --git a/go.mod b/go.mod index 4ca77c12..e1fa1f31 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/rs/zerolog v1.25.0 github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.9.0 - github.com/sprintertech/lifi-solver v1.1.4-0.20251216105438-52c952a498e2 + github.com/sprintertech/lifi-solver v1.2.1-0.20260126164352-681ba9dbe72f github.com/sprintertech/solver-config/go v0.0.0-20260122113136-6411c27edf48 github.com/stretchr/testify v1.10.0 github.com/sygmaprotocol/sygma-core v0.0.0-20250304150334-bd39ac4f7b82 @@ -75,7 +75,8 @@ require ( github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect github.com/holiman/uint256 v1.3.2 // indirect - github.com/mattn/go-runewidth v0.0.13 // indirect + github.com/lmittmann/w3 v0.20.2 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/onsi/ginkgo/v2 v2.22.0 // indirect @@ -100,7 +101,7 @@ require ( github.com/quic-go/qpack v0.5.1 // indirect github.com/quic-go/quic-go v0.48.2 // indirect github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 // indirect - github.com/rivo/uniseg v0.2.0 // indirect + github.com/rivo/uniseg v0.4.7 // indirect github.com/supranational/blst v0.3.14 // indirect github.com/tmaxmax/go-sse v0.11.0 // indirect github.com/vedhavyas/go-subkey/v2 v2.0.0 // indirect @@ -108,6 +109,7 @@ require ( go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 // indirect go.uber.org/dig v1.18.0 // indirect go.uber.org/fx v1.23.0 // indirect + golang.org/x/time v0.12.0 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/go.sum b/go.sum index 73c41570..9e8be811 100644 --- a/go.sum +++ b/go.sum @@ -427,8 +427,8 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -635,6 +635,8 @@ github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQsc github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU= github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCypkQ= github.com/libp2p/go-yamux/v4 v4.0.1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= +github.com/lmittmann/w3 v0.20.2 h1:1IGdZOaRCa00xVcugFuj+xw177iGm+0eDk0h0gh79jI= +github.com/lmittmann/w3 v0.20.2/go.mod h1:iRHUwrimSYgRBSQ0QatEP7BUItCL3ahs0J4YXOI9IAI= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= @@ -666,8 +668,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= -github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -876,8 +878,9 @@ github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66/go.mod h github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= -github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -952,12 +955,8 @@ github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.9.0 h1:yR6EXjTp0y0cLN8OZg1CRZmOBdI88UcGkhgyJhu6nZk= github.com/spf13/viper v1.9.0/go.mod h1:+i6ajR7OX2XaiBkrcZJFK21htRk7eDeLg7+O6bhUPP4= -github.com/sprintertech/lifi-solver v1.1.4-0.20251216105438-52c952a498e2 h1:NJP6kfbXjpOSd5a5LLJSDrN4Ea+cIpyPvqXEQ9UONps= -github.com/sprintertech/lifi-solver v1.1.4-0.20251216105438-52c952a498e2/go.mod h1:gWq6P8ajreJGz+oyh9PtoknQecBSvTI+EM/gowq19XA= -github.com/sprintertech/solver-config/go v0.0.0-20251210120259-9f98635b2dfd h1:hWqUgnuGWYMYLWk3bE8uz2Uwq+hVicBP+FlGs86Smig= -github.com/sprintertech/solver-config/go v0.0.0-20251210120259-9f98635b2dfd/go.mod h1:MrIGW6M815PSYKtWSeOd1Z7eiSeOIk/uA/6E2PhlQVQ= -github.com/sprintertech/solver-config/go v0.0.0-20260121161259-f3ffe27d5139 h1:gXxMRapBaoWgE7bGwqD/5TPhd2yuRnF12cJnTMXeXVI= -github.com/sprintertech/solver-config/go v0.0.0-20260121161259-f3ffe27d5139/go.mod h1:MrIGW6M815PSYKtWSeOd1Z7eiSeOIk/uA/6E2PhlQVQ= +github.com/sprintertech/lifi-solver v1.2.1-0.20260126164352-681ba9dbe72f h1:sNi18dKEwrsDbTB6XztGYzYdu2j8AfV0rUn6mZvv+hs= +github.com/sprintertech/lifi-solver v1.2.1-0.20260126164352-681ba9dbe72f/go.mod h1:xi+WZBEV3MnISw3u1TtMrcQiy6BIqUvzkn/OuBdWiCM= github.com/sprintertech/solver-config/go v0.0.0-20260122113136-6411c27edf48 h1:Id4+gLztZsi7tHZLq5Nx7Dt5z6MpLWAIMz6VFCCAxy0= github.com/sprintertech/solver-config/go v0.0.0-20260122113136-6411c27edf48/go.mod h1:MrIGW6M815PSYKtWSeOd1Z7eiSeOIk/uA/6E2PhlQVQ= github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= diff --git a/protocol/lifi/api_test.go b/protocol/lifi/api_test.go index 4ddb2883..d5ed3ae7 100644 --- a/protocol/lifi/api_test.go +++ b/protocol/lifi/api_test.go @@ -13,7 +13,7 @@ import ( lifiProtocol "github.com/sprintertech/lifi-solver/pkg/protocols/lifi" "github.com/sprintertech/sprinter-signing/protocol/lifi" - "github.com/sprintertech/sprinter-signing/protocol/lifi/mock" + mock_lifi "github.com/sprintertech/sprinter-signing/protocol/lifi/mock" ) type roundTripperFunc func(*http.Request) (*http.Response, error) @@ -35,9 +35,9 @@ func Test_LifiAPI_GetOrder(t *testing.T) { { name: "successful response", id: "testhash", - mockResponse: []byte(mock.LifiMockResponse), + mockResponse: []byte(mock_lifi.LifiMockResponse), statusCode: http.StatusOK, - wantResult: []byte(mock.ExpectedLifiResponse), + wantResult: []byte(mock_lifi.ExpectedLifiResponse), }, { name: "HTTP error", diff --git a/protocol/lifi/event.go b/protocol/lifi/event.go new file mode 100644 index 00000000..0cc4a802 --- /dev/null +++ b/protocol/lifi/event.go @@ -0,0 +1,81 @@ +package lifi + +import ( + "context" + "fmt" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/sprintertech/lifi-solver/pkg/protocols/lifi" + contracts "github.com/sprintertech/lifi-solver/pkg/protocols/lifi/contracts" +) + +const ( + TRANSACTION_TIMEOUT = 30 * time.Second + OpenEventTopic = "0x9ff74bd56d00785b881ef9fa3f03d7b598686a39a9bcff89a6008db588b18a7b" +) + +type ReceiptFetcher interface { + TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) +} + +type LifiEventFetcher struct { + client ReceiptFetcher + inputSettler common.Address +} + +func NewLifiEventFetcher( + client ReceiptFetcher, + inputSettler common.Address, +) *LifiEventFetcher { + return &LifiEventFetcher{ + client: client, + inputSettler: inputSettler, + } +} + +func (h *LifiEventFetcher) Order(ctx context.Context, hash common.Hash, orderID common.Hash) (*lifi.LifiOrder, error) { + ctx, cancel := context.WithTimeout(ctx, TRANSACTION_TIMEOUT) + defer cancel() + + log, err := h.fetchOpenEvent(ctx, hash, orderID) + if err != nil { + return nil, err + } + + return contracts.ParseOpenEvent(log, h.inputSettler.Hex()) +} + +func (h *LifiEventFetcher) fetchOpenEvent(ctx context.Context, hash common.Hash, orderID common.Hash) (*types.Log, error) { + receipt, err := h.client.TransactionReceipt(ctx, hash) + if err != nil { + return nil, err + } + + for _, l := range receipt.Logs { + if l.Removed { + continue + } + + if len(l.Topics) < 2 { + continue + } + + if l.Address != h.inputSettler { + continue + } + + if l.Topics[0] != common.HexToHash(OpenEventTopic) { + continue + } + + if l.Topics[1] != orderID { + continue + } + + return l, nil + } + + return nil, fmt.Errorf("order with id %s not found", orderID.Hex()) +} diff --git a/protocol/lifi/event_test.go b/protocol/lifi/event_test.go new file mode 100644 index 00000000..94f8dc46 --- /dev/null +++ b/protocol/lifi/event_test.go @@ -0,0 +1,93 @@ +package lifi_test + +import ( + "context" + "fmt" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/sprintertech/sprinter-signing/protocol/lifi" + mock_lifi "github.com/sprintertech/sprinter-signing/protocol/lifi/mock" + "github.com/stretchr/testify/suite" + "go.uber.org/mock/gomock" +) + +type OrderTestSuite struct { + suite.Suite + fetcher *lifi.LifiEventFetcher + mockClient *mock_lifi.MockReceiptFetcher + inputSettler common.Address +} + +func TestRunOrderTestSuite(t *testing.T) { + suite.Run(t, new(OrderTestSuite)) +} + +func (s *OrderTestSuite) SetupTest() { + ctrl := gomock.NewController(s.T()) + s.mockClient = mock_lifi.NewMockReceiptFetcher(ctrl) + s.inputSettler = common.HexToAddress("0x000025c3226C00B2Cdc200005a1600509f4e00C0") + s.fetcher = lifi.NewLifiEventFetcher(s.mockClient, s.inputSettler) +} + +func (s *OrderTestSuite) Test_Order_FetchingTxFails() { + s.mockClient.EXPECT().TransactionReceipt(gomock.Any(), gomock.Any()).Return(nil, fmt.Errorf("error")) + + _, err := s.fetcher.Order(context.Background(), common.Hash{}, common.Hash{}) + + s.NotNil(err) +} + +func (s *OrderTestSuite) Test_Order_NoEvents() { + s.mockClient.EXPECT().TransactionReceipt(gomock.Any(), gomock.Any()).Return(&types.Receipt{ + Logs: make([]*types.Log, 0), + }, nil) + + _, err := s.fetcher.Order(context.Background(), common.Hash{}, common.Hash{}) + + s.NotNil(err) +} + +func (s *OrderTestSuite) Test_Order_InvalidLogs() { + validID := common.HexToHash("0x696838617ea58d56a209e54b87240778a70fb6eb0a9da7ac6d0d9de1b1a5b775") + invalidID := common.HexToHash("0x706838617ea58d56a209e54b87240778a70fb6eb0a9da7ac6d0d9de1b1a5b775") + invalidTopic := common.HexToHash("invalid") + + s.mockClient.EXPECT().TransactionReceipt(gomock.Any(), gomock.Any()).Return(&types.Receipt{ + Logs: []*types.Log{ + { + Topics: []common.Hash{ + invalidTopic, + validID, + }, + Address: s.inputSettler, + }, + { + Topics: []common.Hash{ + common.HexToHash(lifi.OpenEventTopic), + validID, + }, + Address: s.inputSettler, + }, + { + Topics: []common.Hash{ + common.HexToHash(lifi.OpenEventTopic), + validID, + }, + Address: common.HexToAddress(""), + }, + { + Topics: []common.Hash{ + common.HexToHash(lifi.OpenEventTopic), + invalidID, + }, + Address: s.inputSettler, + }, + }, + }, nil) + + _, err := s.fetcher.Order(context.Background(), common.Hash{}, common.Hash{}) + + s.NotNil(err) +} diff --git a/protocol/lifi/mock/event.go b/protocol/lifi/mock/event.go new file mode 100644 index 00000000..c0e8b0d8 --- /dev/null +++ b/protocol/lifi/mock/event.go @@ -0,0 +1,58 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: ./protocol/lifi/event.go +// +// Generated by this command: +// +// mockgen -source=./protocol/lifi/event.go -destination=./protocol/lifi/mock/event.go +// + +// Package mock_lifi is a generated GoMock package. +package mock_lifi + +import ( + context "context" + reflect "reflect" + + common "github.com/ethereum/go-ethereum/common" + types "github.com/ethereum/go-ethereum/core/types" + gomock "go.uber.org/mock/gomock" +) + +// MockReceiptFetcher is a mock of ReceiptFetcher interface. +type MockReceiptFetcher struct { + ctrl *gomock.Controller + recorder *MockReceiptFetcherMockRecorder + isgomock struct{} +} + +// MockReceiptFetcherMockRecorder is the mock recorder for MockReceiptFetcher. +type MockReceiptFetcherMockRecorder struct { + mock *MockReceiptFetcher +} + +// NewMockReceiptFetcher creates a new mock instance. +func NewMockReceiptFetcher(ctrl *gomock.Controller) *MockReceiptFetcher { + mock := &MockReceiptFetcher{ctrl: ctrl} + mock.recorder = &MockReceiptFetcherMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockReceiptFetcher) EXPECT() *MockReceiptFetcherMockRecorder { + return m.recorder +} + +// TransactionReceipt mocks base method. +func (m *MockReceiptFetcher) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TransactionReceipt", ctx, txHash) + ret0, _ := ret[0].(*types.Receipt) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// TransactionReceipt indicates an expected call of TransactionReceipt. +func (mr *MockReceiptFetcherMockRecorder) TransactionReceipt(ctx, txHash any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TransactionReceipt", reflect.TypeOf((*MockReceiptFetcher)(nil).TransactionReceipt), ctx, txHash) +} diff --git a/protocol/lifi/mock/mockData.go b/protocol/lifi/mock/mockData.go index ec9cc3fd..c4116a37 100644 --- a/protocol/lifi/mock/mockData.go +++ b/protocol/lifi/mock/mockData.go @@ -1,4 +1,4 @@ -package mock +package mock_lifi const LifiMockResponse = ` {