diff --git a/.mockery.yml b/.mockery.yml new file mode 100644 index 0000000..6995f07 --- /dev/null +++ b/.mockery.yml @@ -0,0 +1,34 @@ +all: false +dir: "mocks/{{.SrcPackageName}}" +pkgname: "mocks" +filename: "mock_{{.InterfaceName}}.go" +structname: "{{.Mock}}{{.InterfaceName}}" + +force-file-write: true +formatter: goimports +generate: true +include-auto-generated: false +log-level: info +recursive: false +require-template-schema-exists: true +template: testify +template-schema: "{{.Template}}.schema.json" + +packages: + github.com/wealdtech/comptrollerd/services/comptrollerdb: + interfaces: + ReceivedBidsSetter: + DeliveredBidsSetter: + github.com/wealdtech/comptrollerd/services/scheduler: + interfaces: + Service: + github.com/wealdtech/comptrollerd/services/chaintime: + interfaces: + Service: + github.com/wealdtech/comptrollerd/services/bids: + interfaces: + ReceivedHandler: + github.com/attestantio/go-relay-client: + interfaces: + ReceivedBidTracesProvider: + DeliveredBidTraceProvider: diff --git a/go.mod b/go.mod index c7847a3..ae1d578 100644 --- a/go.mod +++ b/go.mod @@ -86,6 +86,7 @@ require ( github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.12.0 // indirect github.com/spf13/cast v1.7.1 // indirect + github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/ybbus/jsonrpc/v2 v2.1.7 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect diff --git a/go.sum b/go.sum index 7e3e084..bb59378 100644 --- a/go.sum +++ b/go.sum @@ -74,20 +74,12 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/attestantio/go-builder-client v0.5.3 h1:4YFT0u823JvF4Uesj7SEG8f0De1uxLrVioOgKZYPl3I= -github.com/attestantio/go-builder-client v0.5.3/go.mod h1:RaWc8K2SjyU19sL5UinOQ8n4vTZBrEQzsNuMWpNmwK4= github.com/attestantio/go-builder-client v0.7.0 h1:Kxf5eTKQlU4syv3Uzt8v3vKKm7im1W4CjRAZiPYoqTQ= github.com/attestantio/go-builder-client v0.7.0/go.mod h1:wGZ0U3QX8/F4lWwieJpqCPgXIl8gbfBxm8iViznrTFQ= -github.com/attestantio/go-eth2-client v0.26.1-0.20250829122455-ff89a2135a43 h1:v5l00W4U5WuYz6+Cux0URjN/VBKCupwzG6gCgRdn6Wo= -github.com/attestantio/go-eth2-client v0.26.1-0.20250829122455-ff89a2135a43/go.mod h1:fvULSL9WtNskkOB4i+Yyr6BKpNHXvmpGZj9969fCrfY= github.com/attestantio/go-eth2-client v0.27.1 h1:g7bm+gG/p+gfzYdEuxuAepVWYb8EO+2KojV5/Lo2BxM= github.com/attestantio/go-eth2-client v0.27.1/go.mod h1:fvULSL9WtNskkOB4i+Yyr6BKpNHXvmpGZj9969fCrfY= -github.com/attestantio/go-execution-client v0.9.4 h1:wgFy0ISTaYl2Xxj2PHHUrwfAlSK4BHZudJs5P1GLeI8= -github.com/attestantio/go-execution-client v0.9.4/go.mod h1:tUsr7Y0DgYfSIOhAwDrE+k3wV8IqmkFjyOvqr7BJ9Uk= github.com/attestantio/go-execution-client v0.10.2 h1:plfOAROLXVE//Yz8Ujp8s8PAr8rzXTnVKrsULt8+OuA= github.com/attestantio/go-execution-client v0.10.2/go.mod h1:ppLo3duaOxEpZYM/N6L7Kg/Ks931JKTY9YZnWBdtWSc= -github.com/attestantio/go-relay-client v0.2.7 h1:qlRh+zdMjA3uqU12fpsxJwLME5L5uO84I4ElJCO6oLQ= -github.com/attestantio/go-relay-client v0.2.7/go.mod h1:INcPeI0HNb4AGaFPvPDmAz8HUveh91g2XA9GMPhsftw= github.com/attestantio/go-relay-client v0.3.0 h1:VcVO2yB9HvM5JdMNbBRYSpMA7b6MF/2I7l9bXiINV4g= github.com/attestantio/go-relay-client v0.3.0/go.mod h1:c1lBJ/UxEIWTDbfpM8C9F7330YT/WX++//PLq2G3IyU= github.com/aws/aws-sdk-go v1.44.81/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= @@ -324,9 +316,6 @@ github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= -github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= -github.com/petermattis/goid v0.0.0-20250121172306-05bcfb9a85dc h1:Xz/LkK9AJRY5QTkA1uE1faB8yeqRFjeKgwDtI13ogcY= -github.com/petermattis/goid v0.0.0-20250121172306-05bcfb9a85dc/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/petermattis/goid v0.0.0-20250813065127-a731cc31b4fe h1:vHpqOnPlnkba8iSxU4j/CvDSS9J4+F4473esQsYLGoE= github.com/petermattis/goid v0.0.0-20250813065127-a731cc31b4fe/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pk910/dynamic-ssz v0.0.5 h1:VP9heGYUwzlpyhk28P2nCAzhvGsePJOOOO5vQMDh2qQ= @@ -364,8 +353,6 @@ github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsF github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= -github.com/sasha-s/go-deadlock v0.3.5 h1:tNCOEEDG6tBqrNDOX35j/7hL5FcFViG6awUGROb2NsU= -github.com/sasha-s/go-deadlock v0.3.5/go.mod h1:bugP6EGbdGYObIlx7pUZtWqlvo8k9H6vCBBsiChJQ5U= github.com/sasha-s/go-deadlock v0.3.6 h1:TR7sfOnZ7x00tWPfD397Peodt57KzMDo+9Ae9rMiUmw= github.com/sasha-s/go-deadlock v0.3.6/go.mod h1:CUqNyyvMxTyjFqDT7MRg9mb4Dv/btmGTqSR+rky/UXo= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= @@ -383,6 +370,8 @@ github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= @@ -448,8 +437,6 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= -golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= diff --git a/mocks/bids/mock_ReceivedHandler.go b/mocks/bids/mock_ReceivedHandler.go new file mode 100644 index 0000000..f4b8ee5 --- /dev/null +++ b/mocks/bids/mock_ReceivedHandler.go @@ -0,0 +1,85 @@ +// Code generated by mockery; DO NOT EDIT. +// github.com/vektra/mockery +// template: testify + +package mocks + +import ( + "context" + + "github.com/attestantio/go-eth2-client/spec/phase0" + mock "github.com/stretchr/testify/mock" +) + +// NewMockReceivedHandler creates a new instance of MockReceivedHandler. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockReceivedHandler(t interface { + mock.TestingT + Cleanup(func()) +}) *MockReceivedHandler { + mock := &MockReceivedHandler{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} + +// MockReceivedHandler is an autogenerated mock type for the ReceivedHandler type +type MockReceivedHandler struct { + mock.Mock +} + +type MockReceivedHandler_Expecter struct { + mock *mock.Mock +} + +func (_m *MockReceivedHandler) EXPECT() *MockReceivedHandler_Expecter { + return &MockReceivedHandler_Expecter{mock: &_m.Mock} +} + +// BidsReceived provides a mock function for the type MockReceivedHandler +func (_mock *MockReceivedHandler) BidsReceived(ctx context.Context, slot phase0.Slot) { + _mock.Called(ctx, slot) + return +} + +// MockReceivedHandler_BidsReceived_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'BidsReceived' +type MockReceivedHandler_BidsReceived_Call struct { + *mock.Call +} + +// BidsReceived is a helper method to define mock.On call +// - ctx context.Context +// - slot phase0.Slot +func (_e *MockReceivedHandler_Expecter) BidsReceived(ctx interface{}, slot interface{}) *MockReceivedHandler_BidsReceived_Call { + return &MockReceivedHandler_BidsReceived_Call{Call: _e.mock.On("BidsReceived", ctx, slot)} +} + +func (_c *MockReceivedHandler_BidsReceived_Call) Run(run func(ctx context.Context, slot phase0.Slot)) *MockReceivedHandler_BidsReceived_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 phase0.Slot + if args[1] != nil { + arg1 = args[1].(phase0.Slot) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockReceivedHandler_BidsReceived_Call) Return() *MockReceivedHandler_BidsReceived_Call { + _c.Call.Return() + return _c +} + +func (_c *MockReceivedHandler_BidsReceived_Call) RunAndReturn(run func(ctx context.Context, slot phase0.Slot)) *MockReceivedHandler_BidsReceived_Call { + _c.Run(run) + return _c +} diff --git a/mocks/chaintime/mock_Service.go b/mocks/chaintime/mock_Service.go new file mode 100644 index 0000000..0a46ac1 --- /dev/null +++ b/mocks/chaintime/mock_Service.go @@ -0,0 +1,477 @@ +// Code generated by mockery; DO NOT EDIT. +// github.com/vektra/mockery +// template: testify + +package mocks + +import ( + "time" + + "github.com/attestantio/go-eth2-client/spec/phase0" + mock "github.com/stretchr/testify/mock" +) + +// NewMockService creates a new instance of MockService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockService(t interface { + mock.TestingT + Cleanup(func()) +}) *MockService { + mock := &MockService{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} + +// MockService is an autogenerated mock type for the Service type +type MockService struct { + mock.Mock +} + +type MockService_Expecter struct { + mock *mock.Mock +} + +func (_m *MockService) EXPECT() *MockService_Expecter { + return &MockService_Expecter{mock: &_m.Mock} +} + +// CurrentEpoch provides a mock function for the type MockService +func (_mock *MockService) CurrentEpoch() phase0.Epoch { + ret := _mock.Called() + + if len(ret) == 0 { + panic("no return value specified for CurrentEpoch") + } + + var r0 phase0.Epoch + if returnFunc, ok := ret.Get(0).(func() phase0.Epoch); ok { + r0 = returnFunc() + } else { + r0 = ret.Get(0).(phase0.Epoch) + } + return r0 +} + +// MockService_CurrentEpoch_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CurrentEpoch' +type MockService_CurrentEpoch_Call struct { + *mock.Call +} + +// CurrentEpoch is a helper method to define mock.On call +func (_e *MockService_Expecter) CurrentEpoch() *MockService_CurrentEpoch_Call { + return &MockService_CurrentEpoch_Call{Call: _e.mock.On("CurrentEpoch")} +} + +func (_c *MockService_CurrentEpoch_Call) Run(run func()) *MockService_CurrentEpoch_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockService_CurrentEpoch_Call) Return(epoch phase0.Epoch) *MockService_CurrentEpoch_Call { + _c.Call.Return(epoch) + return _c +} + +func (_c *MockService_CurrentEpoch_Call) RunAndReturn(run func() phase0.Epoch) *MockService_CurrentEpoch_Call { + _c.Call.Return(run) + return _c +} + +// CurrentSlot provides a mock function for the type MockService +func (_mock *MockService) CurrentSlot() phase0.Slot { + ret := _mock.Called() + + if len(ret) == 0 { + panic("no return value specified for CurrentSlot") + } + + var r0 phase0.Slot + if returnFunc, ok := ret.Get(0).(func() phase0.Slot); ok { + r0 = returnFunc() + } else { + r0 = ret.Get(0).(phase0.Slot) + } + return r0 +} + +// MockService_CurrentSlot_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CurrentSlot' +type MockService_CurrentSlot_Call struct { + *mock.Call +} + +// CurrentSlot is a helper method to define mock.On call +func (_e *MockService_Expecter) CurrentSlot() *MockService_CurrentSlot_Call { + return &MockService_CurrentSlot_Call{Call: _e.mock.On("CurrentSlot")} +} + +func (_c *MockService_CurrentSlot_Call) Run(run func()) *MockService_CurrentSlot_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockService_CurrentSlot_Call) Return(slot phase0.Slot) *MockService_CurrentSlot_Call { + _c.Call.Return(slot) + return _c +} + +func (_c *MockService_CurrentSlot_Call) RunAndReturn(run func() phase0.Slot) *MockService_CurrentSlot_Call { + _c.Call.Return(run) + return _c +} + +// FirstSlotOfEpoch provides a mock function for the type MockService +func (_mock *MockService) FirstSlotOfEpoch(epoch phase0.Epoch) phase0.Slot { + ret := _mock.Called(epoch) + + if len(ret) == 0 { + panic("no return value specified for FirstSlotOfEpoch") + } + + var r0 phase0.Slot + if returnFunc, ok := ret.Get(0).(func(phase0.Epoch) phase0.Slot); ok { + r0 = returnFunc(epoch) + } else { + r0 = ret.Get(0).(phase0.Slot) + } + return r0 +} + +// MockService_FirstSlotOfEpoch_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FirstSlotOfEpoch' +type MockService_FirstSlotOfEpoch_Call struct { + *mock.Call +} + +// FirstSlotOfEpoch is a helper method to define mock.On call +// - epoch phase0.Epoch +func (_e *MockService_Expecter) FirstSlotOfEpoch(epoch interface{}) *MockService_FirstSlotOfEpoch_Call { + return &MockService_FirstSlotOfEpoch_Call{Call: _e.mock.On("FirstSlotOfEpoch", epoch)} +} + +func (_c *MockService_FirstSlotOfEpoch_Call) Run(run func(epoch phase0.Epoch)) *MockService_FirstSlotOfEpoch_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 phase0.Epoch + if args[0] != nil { + arg0 = args[0].(phase0.Epoch) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockService_FirstSlotOfEpoch_Call) Return(slot phase0.Slot) *MockService_FirstSlotOfEpoch_Call { + _c.Call.Return(slot) + return _c +} + +func (_c *MockService_FirstSlotOfEpoch_Call) RunAndReturn(run func(epoch phase0.Epoch) phase0.Slot) *MockService_FirstSlotOfEpoch_Call { + _c.Call.Return(run) + return _c +} + +// GenesisTime provides a mock function for the type MockService +func (_mock *MockService) GenesisTime() time.Time { + ret := _mock.Called() + + if len(ret) == 0 { + panic("no return value specified for GenesisTime") + } + + var r0 time.Time + if returnFunc, ok := ret.Get(0).(func() time.Time); ok { + r0 = returnFunc() + } else { + r0 = ret.Get(0).(time.Time) + } + return r0 +} + +// MockService_GenesisTime_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GenesisTime' +type MockService_GenesisTime_Call struct { + *mock.Call +} + +// GenesisTime is a helper method to define mock.On call +func (_e *MockService_Expecter) GenesisTime() *MockService_GenesisTime_Call { + return &MockService_GenesisTime_Call{Call: _e.mock.On("GenesisTime")} +} + +func (_c *MockService_GenesisTime_Call) Run(run func()) *MockService_GenesisTime_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockService_GenesisTime_Call) Return(time1 time.Time) *MockService_GenesisTime_Call { + _c.Call.Return(time1) + return _c +} + +func (_c *MockService_GenesisTime_Call) RunAndReturn(run func() time.Time) *MockService_GenesisTime_Call { + _c.Call.Return(run) + return _c +} + +// SlotToEpoch provides a mock function for the type MockService +func (_mock *MockService) SlotToEpoch(slot phase0.Slot) phase0.Epoch { + ret := _mock.Called(slot) + + if len(ret) == 0 { + panic("no return value specified for SlotToEpoch") + } + + var r0 phase0.Epoch + if returnFunc, ok := ret.Get(0).(func(phase0.Slot) phase0.Epoch); ok { + r0 = returnFunc(slot) + } else { + r0 = ret.Get(0).(phase0.Epoch) + } + return r0 +} + +// MockService_SlotToEpoch_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SlotToEpoch' +type MockService_SlotToEpoch_Call struct { + *mock.Call +} + +// SlotToEpoch is a helper method to define mock.On call +// - slot phase0.Slot +func (_e *MockService_Expecter) SlotToEpoch(slot interface{}) *MockService_SlotToEpoch_Call { + return &MockService_SlotToEpoch_Call{Call: _e.mock.On("SlotToEpoch", slot)} +} + +func (_c *MockService_SlotToEpoch_Call) Run(run func(slot phase0.Slot)) *MockService_SlotToEpoch_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 phase0.Slot + if args[0] != nil { + arg0 = args[0].(phase0.Slot) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockService_SlotToEpoch_Call) Return(epoch phase0.Epoch) *MockService_SlotToEpoch_Call { + _c.Call.Return(epoch) + return _c +} + +func (_c *MockService_SlotToEpoch_Call) RunAndReturn(run func(slot phase0.Slot) phase0.Epoch) *MockService_SlotToEpoch_Call { + _c.Call.Return(run) + return _c +} + +// StartOfEpoch provides a mock function for the type MockService +func (_mock *MockService) StartOfEpoch(epoch phase0.Epoch) time.Time { + ret := _mock.Called(epoch) + + if len(ret) == 0 { + panic("no return value specified for StartOfEpoch") + } + + var r0 time.Time + if returnFunc, ok := ret.Get(0).(func(phase0.Epoch) time.Time); ok { + r0 = returnFunc(epoch) + } else { + r0 = ret.Get(0).(time.Time) + } + return r0 +} + +// MockService_StartOfEpoch_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'StartOfEpoch' +type MockService_StartOfEpoch_Call struct { + *mock.Call +} + +// StartOfEpoch is a helper method to define mock.On call +// - epoch phase0.Epoch +func (_e *MockService_Expecter) StartOfEpoch(epoch interface{}) *MockService_StartOfEpoch_Call { + return &MockService_StartOfEpoch_Call{Call: _e.mock.On("StartOfEpoch", epoch)} +} + +func (_c *MockService_StartOfEpoch_Call) Run(run func(epoch phase0.Epoch)) *MockService_StartOfEpoch_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 phase0.Epoch + if args[0] != nil { + arg0 = args[0].(phase0.Epoch) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockService_StartOfEpoch_Call) Return(time1 time.Time) *MockService_StartOfEpoch_Call { + _c.Call.Return(time1) + return _c +} + +func (_c *MockService_StartOfEpoch_Call) RunAndReturn(run func(epoch phase0.Epoch) time.Time) *MockService_StartOfEpoch_Call { + _c.Call.Return(run) + return _c +} + +// StartOfSlot provides a mock function for the type MockService +func (_mock *MockService) StartOfSlot(slot phase0.Slot) time.Time { + ret := _mock.Called(slot) + + if len(ret) == 0 { + panic("no return value specified for StartOfSlot") + } + + var r0 time.Time + if returnFunc, ok := ret.Get(0).(func(phase0.Slot) time.Time); ok { + r0 = returnFunc(slot) + } else { + r0 = ret.Get(0).(time.Time) + } + return r0 +} + +// MockService_StartOfSlot_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'StartOfSlot' +type MockService_StartOfSlot_Call struct { + *mock.Call +} + +// StartOfSlot is a helper method to define mock.On call +// - slot phase0.Slot +func (_e *MockService_Expecter) StartOfSlot(slot interface{}) *MockService_StartOfSlot_Call { + return &MockService_StartOfSlot_Call{Call: _e.mock.On("StartOfSlot", slot)} +} + +func (_c *MockService_StartOfSlot_Call) Run(run func(slot phase0.Slot)) *MockService_StartOfSlot_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 phase0.Slot + if args[0] != nil { + arg0 = args[0].(phase0.Slot) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockService_StartOfSlot_Call) Return(time1 time.Time) *MockService_StartOfSlot_Call { + _c.Call.Return(time1) + return _c +} + +func (_c *MockService_StartOfSlot_Call) RunAndReturn(run func(slot phase0.Slot) time.Time) *MockService_StartOfSlot_Call { + _c.Call.Return(run) + return _c +} + +// TimestampToEpoch provides a mock function for the type MockService +func (_mock *MockService) TimestampToEpoch(timestamp time.Time) phase0.Epoch { + ret := _mock.Called(timestamp) + + if len(ret) == 0 { + panic("no return value specified for TimestampToEpoch") + } + + var r0 phase0.Epoch + if returnFunc, ok := ret.Get(0).(func(time.Time) phase0.Epoch); ok { + r0 = returnFunc(timestamp) + } else { + r0 = ret.Get(0).(phase0.Epoch) + } + return r0 +} + +// MockService_TimestampToEpoch_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TimestampToEpoch' +type MockService_TimestampToEpoch_Call struct { + *mock.Call +} + +// TimestampToEpoch is a helper method to define mock.On call +// - timestamp time.Time +func (_e *MockService_Expecter) TimestampToEpoch(timestamp interface{}) *MockService_TimestampToEpoch_Call { + return &MockService_TimestampToEpoch_Call{Call: _e.mock.On("TimestampToEpoch", timestamp)} +} + +func (_c *MockService_TimestampToEpoch_Call) Run(run func(timestamp time.Time)) *MockService_TimestampToEpoch_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 time.Time + if args[0] != nil { + arg0 = args[0].(time.Time) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockService_TimestampToEpoch_Call) Return(epoch phase0.Epoch) *MockService_TimestampToEpoch_Call { + _c.Call.Return(epoch) + return _c +} + +func (_c *MockService_TimestampToEpoch_Call) RunAndReturn(run func(timestamp time.Time) phase0.Epoch) *MockService_TimestampToEpoch_Call { + _c.Call.Return(run) + return _c +} + +// TimestampToSlot provides a mock function for the type MockService +func (_mock *MockService) TimestampToSlot(timestamp time.Time) phase0.Slot { + ret := _mock.Called(timestamp) + + if len(ret) == 0 { + panic("no return value specified for TimestampToSlot") + } + + var r0 phase0.Slot + if returnFunc, ok := ret.Get(0).(func(time.Time) phase0.Slot); ok { + r0 = returnFunc(timestamp) + } else { + r0 = ret.Get(0).(phase0.Slot) + } + return r0 +} + +// MockService_TimestampToSlot_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TimestampToSlot' +type MockService_TimestampToSlot_Call struct { + *mock.Call +} + +// TimestampToSlot is a helper method to define mock.On call +// - timestamp time.Time +func (_e *MockService_Expecter) TimestampToSlot(timestamp interface{}) *MockService_TimestampToSlot_Call { + return &MockService_TimestampToSlot_Call{Call: _e.mock.On("TimestampToSlot", timestamp)} +} + +func (_c *MockService_TimestampToSlot_Call) Run(run func(timestamp time.Time)) *MockService_TimestampToSlot_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 time.Time + if args[0] != nil { + arg0 = args[0].(time.Time) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockService_TimestampToSlot_Call) Return(slot phase0.Slot) *MockService_TimestampToSlot_Call { + _c.Call.Return(slot) + return _c +} + +func (_c *MockService_TimestampToSlot_Call) RunAndReturn(run func(timestamp time.Time) phase0.Slot) *MockService_TimestampToSlot_Call { + _c.Call.Return(run) + return _c +} diff --git a/mocks/client/mock_DeliveredBidTraceProvider.go b/mocks/client/mock_DeliveredBidTraceProvider.go new file mode 100644 index 0000000..e05d26c --- /dev/null +++ b/mocks/client/mock_DeliveredBidTraceProvider.go @@ -0,0 +1,242 @@ +// Code generated by mockery; DO NOT EDIT. +// github.com/vektra/mockery +// template: testify + +package mocks + +import ( + "context" + + "github.com/attestantio/go-eth2-client/spec/phase0" + "github.com/attestantio/go-relay-client/api/v1" + mock "github.com/stretchr/testify/mock" +) + +// NewMockDeliveredBidTraceProvider creates a new instance of MockDeliveredBidTraceProvider. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockDeliveredBidTraceProvider(t interface { + mock.TestingT + Cleanup(func()) +}) *MockDeliveredBidTraceProvider { + mock := &MockDeliveredBidTraceProvider{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} + +// MockDeliveredBidTraceProvider is an autogenerated mock type for the DeliveredBidTraceProvider type +type MockDeliveredBidTraceProvider struct { + mock.Mock +} + +type MockDeliveredBidTraceProvider_Expecter struct { + mock *mock.Mock +} + +func (_m *MockDeliveredBidTraceProvider) EXPECT() *MockDeliveredBidTraceProvider_Expecter { + return &MockDeliveredBidTraceProvider_Expecter{mock: &_m.Mock} +} + +// Address provides a mock function for the type MockDeliveredBidTraceProvider +func (_mock *MockDeliveredBidTraceProvider) Address() string { + ret := _mock.Called() + + if len(ret) == 0 { + panic("no return value specified for Address") + } + + var r0 string + if returnFunc, ok := ret.Get(0).(func() string); ok { + r0 = returnFunc() + } else { + r0 = ret.Get(0).(string) + } + return r0 +} + +// MockDeliveredBidTraceProvider_Address_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Address' +type MockDeliveredBidTraceProvider_Address_Call struct { + *mock.Call +} + +// Address is a helper method to define mock.On call +func (_e *MockDeliveredBidTraceProvider_Expecter) Address() *MockDeliveredBidTraceProvider_Address_Call { + return &MockDeliveredBidTraceProvider_Address_Call{Call: _e.mock.On("Address")} +} + +func (_c *MockDeliveredBidTraceProvider_Address_Call) Run(run func()) *MockDeliveredBidTraceProvider_Address_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockDeliveredBidTraceProvider_Address_Call) Return(s string) *MockDeliveredBidTraceProvider_Address_Call { + _c.Call.Return(s) + return _c +} + +func (_c *MockDeliveredBidTraceProvider_Address_Call) RunAndReturn(run func() string) *MockDeliveredBidTraceProvider_Address_Call { + _c.Call.Return(run) + return _c +} + +// DeliveredBidTrace provides a mock function for the type MockDeliveredBidTraceProvider +func (_mock *MockDeliveredBidTraceProvider) DeliveredBidTrace(ctx context.Context, slot phase0.Slot) (*v1.BidTrace, error) { + ret := _mock.Called(ctx, slot) + + if len(ret) == 0 { + panic("no return value specified for DeliveredBidTrace") + } + + var r0 *v1.BidTrace + var r1 error + if returnFunc, ok := ret.Get(0).(func(context.Context, phase0.Slot) (*v1.BidTrace, error)); ok { + return returnFunc(ctx, slot) + } + if returnFunc, ok := ret.Get(0).(func(context.Context, phase0.Slot) *v1.BidTrace); ok { + r0 = returnFunc(ctx, slot) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1.BidTrace) + } + } + if returnFunc, ok := ret.Get(1).(func(context.Context, phase0.Slot) error); ok { + r1 = returnFunc(ctx, slot) + } else { + r1 = ret.Error(1) + } + return r0, r1 +} + +// MockDeliveredBidTraceProvider_DeliveredBidTrace_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeliveredBidTrace' +type MockDeliveredBidTraceProvider_DeliveredBidTrace_Call struct { + *mock.Call +} + +// DeliveredBidTrace is a helper method to define mock.On call +// - ctx context.Context +// - slot phase0.Slot +func (_e *MockDeliveredBidTraceProvider_Expecter) DeliveredBidTrace(ctx interface{}, slot interface{}) *MockDeliveredBidTraceProvider_DeliveredBidTrace_Call { + return &MockDeliveredBidTraceProvider_DeliveredBidTrace_Call{Call: _e.mock.On("DeliveredBidTrace", ctx, slot)} +} + +func (_c *MockDeliveredBidTraceProvider_DeliveredBidTrace_Call) Run(run func(ctx context.Context, slot phase0.Slot)) *MockDeliveredBidTraceProvider_DeliveredBidTrace_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 phase0.Slot + if args[1] != nil { + arg1 = args[1].(phase0.Slot) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockDeliveredBidTraceProvider_DeliveredBidTrace_Call) Return(bidTrace *v1.BidTrace, err error) *MockDeliveredBidTraceProvider_DeliveredBidTrace_Call { + _c.Call.Return(bidTrace, err) + return _c +} + +func (_c *MockDeliveredBidTraceProvider_DeliveredBidTrace_Call) RunAndReturn(run func(ctx context.Context, slot phase0.Slot) (*v1.BidTrace, error)) *MockDeliveredBidTraceProvider_DeliveredBidTrace_Call { + _c.Call.Return(run) + return _c +} + +// Name provides a mock function for the type MockDeliveredBidTraceProvider +func (_mock *MockDeliveredBidTraceProvider) Name() string { + ret := _mock.Called() + + if len(ret) == 0 { + panic("no return value specified for Name") + } + + var r0 string + if returnFunc, ok := ret.Get(0).(func() string); ok { + r0 = returnFunc() + } else { + r0 = ret.Get(0).(string) + } + return r0 +} + +// MockDeliveredBidTraceProvider_Name_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Name' +type MockDeliveredBidTraceProvider_Name_Call struct { + *mock.Call +} + +// Name is a helper method to define mock.On call +func (_e *MockDeliveredBidTraceProvider_Expecter) Name() *MockDeliveredBidTraceProvider_Name_Call { + return &MockDeliveredBidTraceProvider_Name_Call{Call: _e.mock.On("Name")} +} + +func (_c *MockDeliveredBidTraceProvider_Name_Call) Run(run func()) *MockDeliveredBidTraceProvider_Name_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockDeliveredBidTraceProvider_Name_Call) Return(s string) *MockDeliveredBidTraceProvider_Name_Call { + _c.Call.Return(s) + return _c +} + +func (_c *MockDeliveredBidTraceProvider_Name_Call) RunAndReturn(run func() string) *MockDeliveredBidTraceProvider_Name_Call { + _c.Call.Return(run) + return _c +} + +// Pubkey provides a mock function for the type MockDeliveredBidTraceProvider +func (_mock *MockDeliveredBidTraceProvider) Pubkey() *phase0.BLSPubKey { + ret := _mock.Called() + + if len(ret) == 0 { + panic("no return value specified for Pubkey") + } + + var r0 *phase0.BLSPubKey + if returnFunc, ok := ret.Get(0).(func() *phase0.BLSPubKey); ok { + r0 = returnFunc() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*phase0.BLSPubKey) + } + } + return r0 +} + +// MockDeliveredBidTraceProvider_Pubkey_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Pubkey' +type MockDeliveredBidTraceProvider_Pubkey_Call struct { + *mock.Call +} + +// Pubkey is a helper method to define mock.On call +func (_e *MockDeliveredBidTraceProvider_Expecter) Pubkey() *MockDeliveredBidTraceProvider_Pubkey_Call { + return &MockDeliveredBidTraceProvider_Pubkey_Call{Call: _e.mock.On("Pubkey")} +} + +func (_c *MockDeliveredBidTraceProvider_Pubkey_Call) Run(run func()) *MockDeliveredBidTraceProvider_Pubkey_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockDeliveredBidTraceProvider_Pubkey_Call) Return(bLSPubKey *phase0.BLSPubKey) *MockDeliveredBidTraceProvider_Pubkey_Call { + _c.Call.Return(bLSPubKey) + return _c +} + +func (_c *MockDeliveredBidTraceProvider_Pubkey_Call) RunAndReturn(run func() *phase0.BLSPubKey) *MockDeliveredBidTraceProvider_Pubkey_Call { + _c.Call.Return(run) + return _c +} diff --git a/mocks/client/mock_ReceivedBidTracesProvider.go b/mocks/client/mock_ReceivedBidTracesProvider.go new file mode 100644 index 0000000..99cb015 --- /dev/null +++ b/mocks/client/mock_ReceivedBidTracesProvider.go @@ -0,0 +1,242 @@ +// Code generated by mockery; DO NOT EDIT. +// github.com/vektra/mockery +// template: testify + +package mocks + +import ( + "context" + + "github.com/attestantio/go-eth2-client/spec/phase0" + "github.com/attestantio/go-relay-client/api/v1" + mock "github.com/stretchr/testify/mock" +) + +// NewMockReceivedBidTracesProvider creates a new instance of MockReceivedBidTracesProvider. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockReceivedBidTracesProvider(t interface { + mock.TestingT + Cleanup(func()) +}) *MockReceivedBidTracesProvider { + mock := &MockReceivedBidTracesProvider{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} + +// MockReceivedBidTracesProvider is an autogenerated mock type for the ReceivedBidTracesProvider type +type MockReceivedBidTracesProvider struct { + mock.Mock +} + +type MockReceivedBidTracesProvider_Expecter struct { + mock *mock.Mock +} + +func (_m *MockReceivedBidTracesProvider) EXPECT() *MockReceivedBidTracesProvider_Expecter { + return &MockReceivedBidTracesProvider_Expecter{mock: &_m.Mock} +} + +// Address provides a mock function for the type MockReceivedBidTracesProvider +func (_mock *MockReceivedBidTracesProvider) Address() string { + ret := _mock.Called() + + if len(ret) == 0 { + panic("no return value specified for Address") + } + + var r0 string + if returnFunc, ok := ret.Get(0).(func() string); ok { + r0 = returnFunc() + } else { + r0 = ret.Get(0).(string) + } + return r0 +} + +// MockReceivedBidTracesProvider_Address_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Address' +type MockReceivedBidTracesProvider_Address_Call struct { + *mock.Call +} + +// Address is a helper method to define mock.On call +func (_e *MockReceivedBidTracesProvider_Expecter) Address() *MockReceivedBidTracesProvider_Address_Call { + return &MockReceivedBidTracesProvider_Address_Call{Call: _e.mock.On("Address")} +} + +func (_c *MockReceivedBidTracesProvider_Address_Call) Run(run func()) *MockReceivedBidTracesProvider_Address_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockReceivedBidTracesProvider_Address_Call) Return(s string) *MockReceivedBidTracesProvider_Address_Call { + _c.Call.Return(s) + return _c +} + +func (_c *MockReceivedBidTracesProvider_Address_Call) RunAndReturn(run func() string) *MockReceivedBidTracesProvider_Address_Call { + _c.Call.Return(run) + return _c +} + +// Name provides a mock function for the type MockReceivedBidTracesProvider +func (_mock *MockReceivedBidTracesProvider) Name() string { + ret := _mock.Called() + + if len(ret) == 0 { + panic("no return value specified for Name") + } + + var r0 string + if returnFunc, ok := ret.Get(0).(func() string); ok { + r0 = returnFunc() + } else { + r0 = ret.Get(0).(string) + } + return r0 +} + +// MockReceivedBidTracesProvider_Name_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Name' +type MockReceivedBidTracesProvider_Name_Call struct { + *mock.Call +} + +// Name is a helper method to define mock.On call +func (_e *MockReceivedBidTracesProvider_Expecter) Name() *MockReceivedBidTracesProvider_Name_Call { + return &MockReceivedBidTracesProvider_Name_Call{Call: _e.mock.On("Name")} +} + +func (_c *MockReceivedBidTracesProvider_Name_Call) Run(run func()) *MockReceivedBidTracesProvider_Name_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockReceivedBidTracesProvider_Name_Call) Return(s string) *MockReceivedBidTracesProvider_Name_Call { + _c.Call.Return(s) + return _c +} + +func (_c *MockReceivedBidTracesProvider_Name_Call) RunAndReturn(run func() string) *MockReceivedBidTracesProvider_Name_Call { + _c.Call.Return(run) + return _c +} + +// Pubkey provides a mock function for the type MockReceivedBidTracesProvider +func (_mock *MockReceivedBidTracesProvider) Pubkey() *phase0.BLSPubKey { + ret := _mock.Called() + + if len(ret) == 0 { + panic("no return value specified for Pubkey") + } + + var r0 *phase0.BLSPubKey + if returnFunc, ok := ret.Get(0).(func() *phase0.BLSPubKey); ok { + r0 = returnFunc() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*phase0.BLSPubKey) + } + } + return r0 +} + +// MockReceivedBidTracesProvider_Pubkey_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Pubkey' +type MockReceivedBidTracesProvider_Pubkey_Call struct { + *mock.Call +} + +// Pubkey is a helper method to define mock.On call +func (_e *MockReceivedBidTracesProvider_Expecter) Pubkey() *MockReceivedBidTracesProvider_Pubkey_Call { + return &MockReceivedBidTracesProvider_Pubkey_Call{Call: _e.mock.On("Pubkey")} +} + +func (_c *MockReceivedBidTracesProvider_Pubkey_Call) Run(run func()) *MockReceivedBidTracesProvider_Pubkey_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockReceivedBidTracesProvider_Pubkey_Call) Return(bLSPubKey *phase0.BLSPubKey) *MockReceivedBidTracesProvider_Pubkey_Call { + _c.Call.Return(bLSPubKey) + return _c +} + +func (_c *MockReceivedBidTracesProvider_Pubkey_Call) RunAndReturn(run func() *phase0.BLSPubKey) *MockReceivedBidTracesProvider_Pubkey_Call { + _c.Call.Return(run) + return _c +} + +// ReceivedBidTraces provides a mock function for the type MockReceivedBidTracesProvider +func (_mock *MockReceivedBidTracesProvider) ReceivedBidTraces(ctx context.Context, slot phase0.Slot) ([]*v1.BidTraceWithTimestamp, error) { + ret := _mock.Called(ctx, slot) + + if len(ret) == 0 { + panic("no return value specified for ReceivedBidTraces") + } + + var r0 []*v1.BidTraceWithTimestamp + var r1 error + if returnFunc, ok := ret.Get(0).(func(context.Context, phase0.Slot) ([]*v1.BidTraceWithTimestamp, error)); ok { + return returnFunc(ctx, slot) + } + if returnFunc, ok := ret.Get(0).(func(context.Context, phase0.Slot) []*v1.BidTraceWithTimestamp); ok { + r0 = returnFunc(ctx, slot) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*v1.BidTraceWithTimestamp) + } + } + if returnFunc, ok := ret.Get(1).(func(context.Context, phase0.Slot) error); ok { + r1 = returnFunc(ctx, slot) + } else { + r1 = ret.Error(1) + } + return r0, r1 +} + +// MockReceivedBidTracesProvider_ReceivedBidTraces_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReceivedBidTraces' +type MockReceivedBidTracesProvider_ReceivedBidTraces_Call struct { + *mock.Call +} + +// ReceivedBidTraces is a helper method to define mock.On call +// - ctx context.Context +// - slot phase0.Slot +func (_e *MockReceivedBidTracesProvider_Expecter) ReceivedBidTraces(ctx interface{}, slot interface{}) *MockReceivedBidTracesProvider_ReceivedBidTraces_Call { + return &MockReceivedBidTracesProvider_ReceivedBidTraces_Call{Call: _e.mock.On("ReceivedBidTraces", ctx, slot)} +} + +func (_c *MockReceivedBidTracesProvider_ReceivedBidTraces_Call) Run(run func(ctx context.Context, slot phase0.Slot)) *MockReceivedBidTracesProvider_ReceivedBidTraces_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 phase0.Slot + if args[1] != nil { + arg1 = args[1].(phase0.Slot) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockReceivedBidTracesProvider_ReceivedBidTraces_Call) Return(bidTraceWithTimestamps []*v1.BidTraceWithTimestamp, err error) *MockReceivedBidTracesProvider_ReceivedBidTraces_Call { + _c.Call.Return(bidTraceWithTimestamps, err) + return _c +} + +func (_c *MockReceivedBidTracesProvider_ReceivedBidTraces_Call) RunAndReturn(run func(ctx context.Context, slot phase0.Slot) ([]*v1.BidTraceWithTimestamp, error)) *MockReceivedBidTracesProvider_ReceivedBidTraces_Call { + _c.Call.Return(run) + return _c +} diff --git a/mocks/comptrollerdb/mock_DeliveredBidsSetter.go b/mocks/comptrollerdb/mock_DeliveredBidsSetter.go new file mode 100644 index 0000000..225b1d8 --- /dev/null +++ b/mocks/comptrollerdb/mock_DeliveredBidsSetter.go @@ -0,0 +1,348 @@ +// Code generated by mockery; DO NOT EDIT. +// github.com/vektra/mockery +// template: testify + +package mocks + +import ( + "context" + + mock "github.com/stretchr/testify/mock" + "github.com/wealdtech/comptrollerd/services/comptrollerdb" +) + +// NewMockDeliveredBidsSetter creates a new instance of MockDeliveredBidsSetter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockDeliveredBidsSetter(t interface { + mock.TestingT + Cleanup(func()) +}) *MockDeliveredBidsSetter { + mock := &MockDeliveredBidsSetter{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} + +// MockDeliveredBidsSetter is an autogenerated mock type for the DeliveredBidsSetter type +type MockDeliveredBidsSetter struct { + mock.Mock +} + +type MockDeliveredBidsSetter_Expecter struct { + mock *mock.Mock +} + +func (_m *MockDeliveredBidsSetter) EXPECT() *MockDeliveredBidsSetter_Expecter { + return &MockDeliveredBidsSetter_Expecter{mock: &_m.Mock} +} + +// BeginTx provides a mock function for the type MockDeliveredBidsSetter +func (_mock *MockDeliveredBidsSetter) BeginTx(ctx context.Context) (context.Context, context.CancelFunc, error) { + ret := _mock.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for BeginTx") + } + + var r0 context.Context + var r1 context.CancelFunc + var r2 error + if returnFunc, ok := ret.Get(0).(func(context.Context) (context.Context, context.CancelFunc, error)); ok { + return returnFunc(ctx) + } + if returnFunc, ok := ret.Get(0).(func(context.Context) context.Context); ok { + r0 = returnFunc(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(context.Context) + } + } + if returnFunc, ok := ret.Get(1).(func(context.Context) context.CancelFunc); ok { + r1 = returnFunc(ctx) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(context.CancelFunc) + } + } + if returnFunc, ok := ret.Get(2).(func(context.Context) error); ok { + r2 = returnFunc(ctx) + } else { + r2 = ret.Error(2) + } + return r0, r1, r2 +} + +// MockDeliveredBidsSetter_BeginTx_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'BeginTx' +type MockDeliveredBidsSetter_BeginTx_Call struct { + *mock.Call +} + +// BeginTx is a helper method to define mock.On call +// - ctx context.Context +func (_e *MockDeliveredBidsSetter_Expecter) BeginTx(ctx interface{}) *MockDeliveredBidsSetter_BeginTx_Call { + return &MockDeliveredBidsSetter_BeginTx_Call{Call: _e.mock.On("BeginTx", ctx)} +} + +func (_c *MockDeliveredBidsSetter_BeginTx_Call) Run(run func(ctx context.Context)) *MockDeliveredBidsSetter_BeginTx_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockDeliveredBidsSetter_BeginTx_Call) Return(context1 context.Context, cancelFunc context.CancelFunc, err error) *MockDeliveredBidsSetter_BeginTx_Call { + _c.Call.Return(context1, cancelFunc, err) + return _c +} + +func (_c *MockDeliveredBidsSetter_BeginTx_Call) RunAndReturn(run func(ctx context.Context) (context.Context, context.CancelFunc, error)) *MockDeliveredBidsSetter_BeginTx_Call { + _c.Call.Return(run) + return _c +} + +// CommitTx provides a mock function for the type MockDeliveredBidsSetter +func (_mock *MockDeliveredBidsSetter) CommitTx(ctx context.Context) error { + ret := _mock.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for CommitTx") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = returnFunc(ctx) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockDeliveredBidsSetter_CommitTx_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CommitTx' +type MockDeliveredBidsSetter_CommitTx_Call struct { + *mock.Call +} + +// CommitTx is a helper method to define mock.On call +// - ctx context.Context +func (_e *MockDeliveredBidsSetter_Expecter) CommitTx(ctx interface{}) *MockDeliveredBidsSetter_CommitTx_Call { + return &MockDeliveredBidsSetter_CommitTx_Call{Call: _e.mock.On("CommitTx", ctx)} +} + +func (_c *MockDeliveredBidsSetter_CommitTx_Call) Run(run func(ctx context.Context)) *MockDeliveredBidsSetter_CommitTx_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockDeliveredBidsSetter_CommitTx_Call) Return(err error) *MockDeliveredBidsSetter_CommitTx_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockDeliveredBidsSetter_CommitTx_Call) RunAndReturn(run func(ctx context.Context) error) *MockDeliveredBidsSetter_CommitTx_Call { + _c.Call.Return(run) + return _c +} + +// Metadata provides a mock function for the type MockDeliveredBidsSetter +func (_mock *MockDeliveredBidsSetter) Metadata(ctx context.Context, key string) ([]byte, error) { + ret := _mock.Called(ctx, key) + + if len(ret) == 0 { + panic("no return value specified for Metadata") + } + + var r0 []byte + var r1 error + if returnFunc, ok := ret.Get(0).(func(context.Context, string) ([]byte, error)); ok { + return returnFunc(ctx, key) + } + if returnFunc, ok := ret.Get(0).(func(context.Context, string) []byte); ok { + r0 = returnFunc(ctx, key) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + if returnFunc, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = returnFunc(ctx, key) + } else { + r1 = ret.Error(1) + } + return r0, r1 +} + +// MockDeliveredBidsSetter_Metadata_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Metadata' +type MockDeliveredBidsSetter_Metadata_Call struct { + *mock.Call +} + +// Metadata is a helper method to define mock.On call +// - ctx context.Context +// - key string +func (_e *MockDeliveredBidsSetter_Expecter) Metadata(ctx interface{}, key interface{}) *MockDeliveredBidsSetter_Metadata_Call { + return &MockDeliveredBidsSetter_Metadata_Call{Call: _e.mock.On("Metadata", ctx, key)} +} + +func (_c *MockDeliveredBidsSetter_Metadata_Call) Run(run func(ctx context.Context, key string)) *MockDeliveredBidsSetter_Metadata_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockDeliveredBidsSetter_Metadata_Call) Return(bytes []byte, err error) *MockDeliveredBidsSetter_Metadata_Call { + _c.Call.Return(bytes, err) + return _c +} + +func (_c *MockDeliveredBidsSetter_Metadata_Call) RunAndReturn(run func(ctx context.Context, key string) ([]byte, error)) *MockDeliveredBidsSetter_Metadata_Call { + _c.Call.Return(run) + return _c +} + +// SetDeliveredBid provides a mock function for the type MockDeliveredBidsSetter +func (_mock *MockDeliveredBidsSetter) SetDeliveredBid(ctx context.Context, bid *comptrollerdb.DeliveredBid) error { + ret := _mock.Called(ctx, bid) + + if len(ret) == 0 { + panic("no return value specified for SetDeliveredBid") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(context.Context, *comptrollerdb.DeliveredBid) error); ok { + r0 = returnFunc(ctx, bid) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockDeliveredBidsSetter_SetDeliveredBid_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetDeliveredBid' +type MockDeliveredBidsSetter_SetDeliveredBid_Call struct { + *mock.Call +} + +// SetDeliveredBid is a helper method to define mock.On call +// - ctx context.Context +// - bid *comptrollerdb.DeliveredBid +func (_e *MockDeliveredBidsSetter_Expecter) SetDeliveredBid(ctx interface{}, bid interface{}) *MockDeliveredBidsSetter_SetDeliveredBid_Call { + return &MockDeliveredBidsSetter_SetDeliveredBid_Call{Call: _e.mock.On("SetDeliveredBid", ctx, bid)} +} + +func (_c *MockDeliveredBidsSetter_SetDeliveredBid_Call) Run(run func(ctx context.Context, bid *comptrollerdb.DeliveredBid)) *MockDeliveredBidsSetter_SetDeliveredBid_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 *comptrollerdb.DeliveredBid + if args[1] != nil { + arg1 = args[1].(*comptrollerdb.DeliveredBid) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockDeliveredBidsSetter_SetDeliveredBid_Call) Return(err error) *MockDeliveredBidsSetter_SetDeliveredBid_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockDeliveredBidsSetter_SetDeliveredBid_Call) RunAndReturn(run func(ctx context.Context, bid *comptrollerdb.DeliveredBid) error) *MockDeliveredBidsSetter_SetDeliveredBid_Call { + _c.Call.Return(run) + return _c +} + +// SetMetadata provides a mock function for the type MockDeliveredBidsSetter +func (_mock *MockDeliveredBidsSetter) SetMetadata(ctx context.Context, key string, value []byte) error { + ret := _mock.Called(ctx, key, value) + + if len(ret) == 0 { + panic("no return value specified for SetMetadata") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(context.Context, string, []byte) error); ok { + r0 = returnFunc(ctx, key, value) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockDeliveredBidsSetter_SetMetadata_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetMetadata' +type MockDeliveredBidsSetter_SetMetadata_Call struct { + *mock.Call +} + +// SetMetadata is a helper method to define mock.On call +// - ctx context.Context +// - key string +// - value []byte +func (_e *MockDeliveredBidsSetter_Expecter) SetMetadata(ctx interface{}, key interface{}, value interface{}) *MockDeliveredBidsSetter_SetMetadata_Call { + return &MockDeliveredBidsSetter_SetMetadata_Call{Call: _e.mock.On("SetMetadata", ctx, key, value)} +} + +func (_c *MockDeliveredBidsSetter_SetMetadata_Call) Run(run func(ctx context.Context, key string, value []byte)) *MockDeliveredBidsSetter_SetMetadata_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 []byte + if args[2] != nil { + arg2 = args[2].([]byte) + } + run( + arg0, + arg1, + arg2, + ) + }) + return _c +} + +func (_c *MockDeliveredBidsSetter_SetMetadata_Call) Return(err error) *MockDeliveredBidsSetter_SetMetadata_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockDeliveredBidsSetter_SetMetadata_Call) RunAndReturn(run func(ctx context.Context, key string, value []byte) error) *MockDeliveredBidsSetter_SetMetadata_Call { + _c.Call.Return(run) + return _c +} diff --git a/mocks/comptrollerdb/mock_ReceivedBidsSetter.go b/mocks/comptrollerdb/mock_ReceivedBidsSetter.go new file mode 100644 index 0000000..e90b93b --- /dev/null +++ b/mocks/comptrollerdb/mock_ReceivedBidsSetter.go @@ -0,0 +1,405 @@ +// Code generated by mockery; DO NOT EDIT. +// github.com/vektra/mockery +// template: testify + +package mocks + +import ( + "context" + + mock "github.com/stretchr/testify/mock" + "github.com/wealdtech/comptrollerd/services/comptrollerdb" +) + +// NewMockReceivedBidsSetter creates a new instance of MockReceivedBidsSetter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockReceivedBidsSetter(t interface { + mock.TestingT + Cleanup(func()) +}) *MockReceivedBidsSetter { + mock := &MockReceivedBidsSetter{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} + +// MockReceivedBidsSetter is an autogenerated mock type for the ReceivedBidsSetter type +type MockReceivedBidsSetter struct { + mock.Mock +} + +type MockReceivedBidsSetter_Expecter struct { + mock *mock.Mock +} + +func (_m *MockReceivedBidsSetter) EXPECT() *MockReceivedBidsSetter_Expecter { + return &MockReceivedBidsSetter_Expecter{mock: &_m.Mock} +} + +// BeginTx provides a mock function for the type MockReceivedBidsSetter +func (_mock *MockReceivedBidsSetter) BeginTx(ctx context.Context) (context.Context, context.CancelFunc, error) { + ret := _mock.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for BeginTx") + } + + var r0 context.Context + var r1 context.CancelFunc + var r2 error + if returnFunc, ok := ret.Get(0).(func(context.Context) (context.Context, context.CancelFunc, error)); ok { + return returnFunc(ctx) + } + if returnFunc, ok := ret.Get(0).(func(context.Context) context.Context); ok { + r0 = returnFunc(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(context.Context) + } + } + if returnFunc, ok := ret.Get(1).(func(context.Context) context.CancelFunc); ok { + r1 = returnFunc(ctx) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(context.CancelFunc) + } + } + if returnFunc, ok := ret.Get(2).(func(context.Context) error); ok { + r2 = returnFunc(ctx) + } else { + r2 = ret.Error(2) + } + return r0, r1, r2 +} + +// MockReceivedBidsSetter_BeginTx_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'BeginTx' +type MockReceivedBidsSetter_BeginTx_Call struct { + *mock.Call +} + +// BeginTx is a helper method to define mock.On call +// - ctx context.Context +func (_e *MockReceivedBidsSetter_Expecter) BeginTx(ctx interface{}) *MockReceivedBidsSetter_BeginTx_Call { + return &MockReceivedBidsSetter_BeginTx_Call{Call: _e.mock.On("BeginTx", ctx)} +} + +func (_c *MockReceivedBidsSetter_BeginTx_Call) Run(run func(ctx context.Context)) *MockReceivedBidsSetter_BeginTx_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockReceivedBidsSetter_BeginTx_Call) Return(context1 context.Context, cancelFunc context.CancelFunc, err error) *MockReceivedBidsSetter_BeginTx_Call { + _c.Call.Return(context1, cancelFunc, err) + return _c +} + +func (_c *MockReceivedBidsSetter_BeginTx_Call) RunAndReturn(run func(ctx context.Context) (context.Context, context.CancelFunc, error)) *MockReceivedBidsSetter_BeginTx_Call { + _c.Call.Return(run) + return _c +} + +// CommitTx provides a mock function for the type MockReceivedBidsSetter +func (_mock *MockReceivedBidsSetter) CommitTx(ctx context.Context) error { + ret := _mock.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for CommitTx") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = returnFunc(ctx) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockReceivedBidsSetter_CommitTx_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CommitTx' +type MockReceivedBidsSetter_CommitTx_Call struct { + *mock.Call +} + +// CommitTx is a helper method to define mock.On call +// - ctx context.Context +func (_e *MockReceivedBidsSetter_Expecter) CommitTx(ctx interface{}) *MockReceivedBidsSetter_CommitTx_Call { + return &MockReceivedBidsSetter_CommitTx_Call{Call: _e.mock.On("CommitTx", ctx)} +} + +func (_c *MockReceivedBidsSetter_CommitTx_Call) Run(run func(ctx context.Context)) *MockReceivedBidsSetter_CommitTx_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockReceivedBidsSetter_CommitTx_Call) Return(err error) *MockReceivedBidsSetter_CommitTx_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockReceivedBidsSetter_CommitTx_Call) RunAndReturn(run func(ctx context.Context) error) *MockReceivedBidsSetter_CommitTx_Call { + _c.Call.Return(run) + return _c +} + +// Metadata provides a mock function for the type MockReceivedBidsSetter +func (_mock *MockReceivedBidsSetter) Metadata(ctx context.Context, key string) ([]byte, error) { + ret := _mock.Called(ctx, key) + + if len(ret) == 0 { + panic("no return value specified for Metadata") + } + + var r0 []byte + var r1 error + if returnFunc, ok := ret.Get(0).(func(context.Context, string) ([]byte, error)); ok { + return returnFunc(ctx, key) + } + if returnFunc, ok := ret.Get(0).(func(context.Context, string) []byte); ok { + r0 = returnFunc(ctx, key) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + if returnFunc, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = returnFunc(ctx, key) + } else { + r1 = ret.Error(1) + } + return r0, r1 +} + +// MockReceivedBidsSetter_Metadata_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Metadata' +type MockReceivedBidsSetter_Metadata_Call struct { + *mock.Call +} + +// Metadata is a helper method to define mock.On call +// - ctx context.Context +// - key string +func (_e *MockReceivedBidsSetter_Expecter) Metadata(ctx interface{}, key interface{}) *MockReceivedBidsSetter_Metadata_Call { + return &MockReceivedBidsSetter_Metadata_Call{Call: _e.mock.On("Metadata", ctx, key)} +} + +func (_c *MockReceivedBidsSetter_Metadata_Call) Run(run func(ctx context.Context, key string)) *MockReceivedBidsSetter_Metadata_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockReceivedBidsSetter_Metadata_Call) Return(bytes []byte, err error) *MockReceivedBidsSetter_Metadata_Call { + _c.Call.Return(bytes, err) + return _c +} + +func (_c *MockReceivedBidsSetter_Metadata_Call) RunAndReturn(run func(ctx context.Context, key string) ([]byte, error)) *MockReceivedBidsSetter_Metadata_Call { + _c.Call.Return(run) + return _c +} + +// SetMetadata provides a mock function for the type MockReceivedBidsSetter +func (_mock *MockReceivedBidsSetter) SetMetadata(ctx context.Context, key string, value []byte) error { + ret := _mock.Called(ctx, key, value) + + if len(ret) == 0 { + panic("no return value specified for SetMetadata") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(context.Context, string, []byte) error); ok { + r0 = returnFunc(ctx, key, value) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockReceivedBidsSetter_SetMetadata_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetMetadata' +type MockReceivedBidsSetter_SetMetadata_Call struct { + *mock.Call +} + +// SetMetadata is a helper method to define mock.On call +// - ctx context.Context +// - key string +// - value []byte +func (_e *MockReceivedBidsSetter_Expecter) SetMetadata(ctx interface{}, key interface{}, value interface{}) *MockReceivedBidsSetter_SetMetadata_Call { + return &MockReceivedBidsSetter_SetMetadata_Call{Call: _e.mock.On("SetMetadata", ctx, key, value)} +} + +func (_c *MockReceivedBidsSetter_SetMetadata_Call) Run(run func(ctx context.Context, key string, value []byte)) *MockReceivedBidsSetter_SetMetadata_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 []byte + if args[2] != nil { + arg2 = args[2].([]byte) + } + run( + arg0, + arg1, + arg2, + ) + }) + return _c +} + +func (_c *MockReceivedBidsSetter_SetMetadata_Call) Return(err error) *MockReceivedBidsSetter_SetMetadata_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockReceivedBidsSetter_SetMetadata_Call) RunAndReturn(run func(ctx context.Context, key string, value []byte) error) *MockReceivedBidsSetter_SetMetadata_Call { + _c.Call.Return(run) + return _c +} + +// SetReceivedBid provides a mock function for the type MockReceivedBidsSetter +func (_mock *MockReceivedBidsSetter) SetReceivedBid(ctx context.Context, bid *comptrollerdb.ReceivedBid) error { + ret := _mock.Called(ctx, bid) + + if len(ret) == 0 { + panic("no return value specified for SetReceivedBid") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(context.Context, *comptrollerdb.ReceivedBid) error); ok { + r0 = returnFunc(ctx, bid) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockReceivedBidsSetter_SetReceivedBid_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetReceivedBid' +type MockReceivedBidsSetter_SetReceivedBid_Call struct { + *mock.Call +} + +// SetReceivedBid is a helper method to define mock.On call +// - ctx context.Context +// - bid *comptrollerdb.ReceivedBid +func (_e *MockReceivedBidsSetter_Expecter) SetReceivedBid(ctx interface{}, bid interface{}) *MockReceivedBidsSetter_SetReceivedBid_Call { + return &MockReceivedBidsSetter_SetReceivedBid_Call{Call: _e.mock.On("SetReceivedBid", ctx, bid)} +} + +func (_c *MockReceivedBidsSetter_SetReceivedBid_Call) Run(run func(ctx context.Context, bid *comptrollerdb.ReceivedBid)) *MockReceivedBidsSetter_SetReceivedBid_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 *comptrollerdb.ReceivedBid + if args[1] != nil { + arg1 = args[1].(*comptrollerdb.ReceivedBid) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockReceivedBidsSetter_SetReceivedBid_Call) Return(err error) *MockReceivedBidsSetter_SetReceivedBid_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockReceivedBidsSetter_SetReceivedBid_Call) RunAndReturn(run func(ctx context.Context, bid *comptrollerdb.ReceivedBid) error) *MockReceivedBidsSetter_SetReceivedBid_Call { + _c.Call.Return(run) + return _c +} + +// SetReceivedBids provides a mock function for the type MockReceivedBidsSetter +func (_mock *MockReceivedBidsSetter) SetReceivedBids(ctx context.Context, bids []*comptrollerdb.ReceivedBid) error { + ret := _mock.Called(ctx, bids) + + if len(ret) == 0 { + panic("no return value specified for SetReceivedBids") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(context.Context, []*comptrollerdb.ReceivedBid) error); ok { + r0 = returnFunc(ctx, bids) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockReceivedBidsSetter_SetReceivedBids_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetReceivedBids' +type MockReceivedBidsSetter_SetReceivedBids_Call struct { + *mock.Call +} + +// SetReceivedBids is a helper method to define mock.On call +// - ctx context.Context +// - bids []*comptrollerdb.ReceivedBid +func (_e *MockReceivedBidsSetter_Expecter) SetReceivedBids(ctx interface{}, bids interface{}) *MockReceivedBidsSetter_SetReceivedBids_Call { + return &MockReceivedBidsSetter_SetReceivedBids_Call{Call: _e.mock.On("SetReceivedBids", ctx, bids)} +} + +func (_c *MockReceivedBidsSetter_SetReceivedBids_Call) Run(run func(ctx context.Context, bids []*comptrollerdb.ReceivedBid)) *MockReceivedBidsSetter_SetReceivedBids_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 []*comptrollerdb.ReceivedBid + if args[1] != nil { + arg1 = args[1].([]*comptrollerdb.ReceivedBid) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockReceivedBidsSetter_SetReceivedBids_Call) Return(err error) *MockReceivedBidsSetter_SetReceivedBids_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockReceivedBidsSetter_SetReceivedBids_Call) RunAndReturn(run func(ctx context.Context, bids []*comptrollerdb.ReceivedBid) error) *MockReceivedBidsSetter_SetReceivedBids_Call { + _c.Call.Return(run) + return _c +} diff --git a/mocks/scheduler/mock_Service.go b/mocks/scheduler/mock_Service.go new file mode 100644 index 0000000..8d2a339 --- /dev/null +++ b/mocks/scheduler/mock_Service.go @@ -0,0 +1,570 @@ +// Code generated by mockery; DO NOT EDIT. +// github.com/vektra/mockery +// template: testify + +package mocks + +import ( + "context" + "time" + + mock "github.com/stretchr/testify/mock" + "github.com/wealdtech/comptrollerd/services/scheduler" +) + +// NewMockService creates a new instance of MockService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockService(t interface { + mock.TestingT + Cleanup(func()) +}) *MockService { + mock := &MockService{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} + +// MockService is an autogenerated mock type for the Service type +type MockService struct { + mock.Mock +} + +type MockService_Expecter struct { + mock *mock.Mock +} + +func (_m *MockService) EXPECT() *MockService_Expecter { + return &MockService_Expecter{mock: &_m.Mock} +} + +// CancelJob provides a mock function for the type MockService +func (_mock *MockService) CancelJob(ctx context.Context, name string) error { + ret := _mock.Called(ctx, name) + + if len(ret) == 0 { + panic("no return value specified for CancelJob") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(context.Context, string) error); ok { + r0 = returnFunc(ctx, name) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockService_CancelJob_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CancelJob' +type MockService_CancelJob_Call struct { + *mock.Call +} + +// CancelJob is a helper method to define mock.On call +// - ctx context.Context +// - name string +func (_e *MockService_Expecter) CancelJob(ctx interface{}, name interface{}) *MockService_CancelJob_Call { + return &MockService_CancelJob_Call{Call: _e.mock.On("CancelJob", ctx, name)} +} + +func (_c *MockService_CancelJob_Call) Run(run func(ctx context.Context, name string)) *MockService_CancelJob_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockService_CancelJob_Call) Return(err error) *MockService_CancelJob_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockService_CancelJob_Call) RunAndReturn(run func(ctx context.Context, name string) error) *MockService_CancelJob_Call { + _c.Call.Return(run) + return _c +} + +// CancelJobIfExists provides a mock function for the type MockService +func (_mock *MockService) CancelJobIfExists(ctx context.Context, name string) { + _mock.Called(ctx, name) + return +} + +// MockService_CancelJobIfExists_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CancelJobIfExists' +type MockService_CancelJobIfExists_Call struct { + *mock.Call +} + +// CancelJobIfExists is a helper method to define mock.On call +// - ctx context.Context +// - name string +func (_e *MockService_Expecter) CancelJobIfExists(ctx interface{}, name interface{}) *MockService_CancelJobIfExists_Call { + return &MockService_CancelJobIfExists_Call{Call: _e.mock.On("CancelJobIfExists", ctx, name)} +} + +func (_c *MockService_CancelJobIfExists_Call) Run(run func(ctx context.Context, name string)) *MockService_CancelJobIfExists_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockService_CancelJobIfExists_Call) Return() *MockService_CancelJobIfExists_Call { + _c.Call.Return() + return _c +} + +func (_c *MockService_CancelJobIfExists_Call) RunAndReturn(run func(ctx context.Context, name string)) *MockService_CancelJobIfExists_Call { + _c.Run(run) + return _c +} + +// CancelJobs provides a mock function for the type MockService +func (_mock *MockService) CancelJobs(ctx context.Context, prefix string) { + _mock.Called(ctx, prefix) + return +} + +// MockService_CancelJobs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CancelJobs' +type MockService_CancelJobs_Call struct { + *mock.Call +} + +// CancelJobs is a helper method to define mock.On call +// - ctx context.Context +// - prefix string +func (_e *MockService_Expecter) CancelJobs(ctx interface{}, prefix interface{}) *MockService_CancelJobs_Call { + return &MockService_CancelJobs_Call{Call: _e.mock.On("CancelJobs", ctx, prefix)} +} + +func (_c *MockService_CancelJobs_Call) Run(run func(ctx context.Context, prefix string)) *MockService_CancelJobs_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockService_CancelJobs_Call) Return() *MockService_CancelJobs_Call { + _c.Call.Return() + return _c +} + +func (_c *MockService_CancelJobs_Call) RunAndReturn(run func(ctx context.Context, prefix string)) *MockService_CancelJobs_Call { + _c.Run(run) + return _c +} + +// JobExists provides a mock function for the type MockService +func (_mock *MockService) JobExists(ctx context.Context, name string) bool { + ret := _mock.Called(ctx, name) + + if len(ret) == 0 { + panic("no return value specified for JobExists") + } + + var r0 bool + if returnFunc, ok := ret.Get(0).(func(context.Context, string) bool); ok { + r0 = returnFunc(ctx, name) + } else { + r0 = ret.Get(0).(bool) + } + return r0 +} + +// MockService_JobExists_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'JobExists' +type MockService_JobExists_Call struct { + *mock.Call +} + +// JobExists is a helper method to define mock.On call +// - ctx context.Context +// - name string +func (_e *MockService_Expecter) JobExists(ctx interface{}, name interface{}) *MockService_JobExists_Call { + return &MockService_JobExists_Call{Call: _e.mock.On("JobExists", ctx, name)} +} + +func (_c *MockService_JobExists_Call) Run(run func(ctx context.Context, name string)) *MockService_JobExists_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockService_JobExists_Call) Return(b bool) *MockService_JobExists_Call { + _c.Call.Return(b) + return _c +} + +func (_c *MockService_JobExists_Call) RunAndReturn(run func(ctx context.Context, name string) bool) *MockService_JobExists_Call { + _c.Call.Return(run) + return _c +} + +// ListJobs provides a mock function for the type MockService +func (_mock *MockService) ListJobs(ctx context.Context) []string { + ret := _mock.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for ListJobs") + } + + var r0 []string + if returnFunc, ok := ret.Get(0).(func(context.Context) []string); ok { + r0 = returnFunc(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]string) + } + } + return r0 +} + +// MockService_ListJobs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListJobs' +type MockService_ListJobs_Call struct { + *mock.Call +} + +// ListJobs is a helper method to define mock.On call +// - ctx context.Context +func (_e *MockService_Expecter) ListJobs(ctx interface{}) *MockService_ListJobs_Call { + return &MockService_ListJobs_Call{Call: _e.mock.On("ListJobs", ctx)} +} + +func (_c *MockService_ListJobs_Call) Run(run func(ctx context.Context)) *MockService_ListJobs_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockService_ListJobs_Call) Return(strings []string) *MockService_ListJobs_Call { + _c.Call.Return(strings) + return _c +} + +func (_c *MockService_ListJobs_Call) RunAndReturn(run func(ctx context.Context) []string) *MockService_ListJobs_Call { + _c.Call.Return(run) + return _c +} + +// RunJob provides a mock function for the type MockService +func (_mock *MockService) RunJob(ctx context.Context, name string) error { + ret := _mock.Called(ctx, name) + + if len(ret) == 0 { + panic("no return value specified for RunJob") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(context.Context, string) error); ok { + r0 = returnFunc(ctx, name) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockService_RunJob_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RunJob' +type MockService_RunJob_Call struct { + *mock.Call +} + +// RunJob is a helper method to define mock.On call +// - ctx context.Context +// - name string +func (_e *MockService_Expecter) RunJob(ctx interface{}, name interface{}) *MockService_RunJob_Call { + return &MockService_RunJob_Call{Call: _e.mock.On("RunJob", ctx, name)} +} + +func (_c *MockService_RunJob_Call) Run(run func(ctx context.Context, name string)) *MockService_RunJob_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockService_RunJob_Call) Return(err error) *MockService_RunJob_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockService_RunJob_Call) RunAndReturn(run func(ctx context.Context, name string) error) *MockService_RunJob_Call { + _c.Call.Return(run) + return _c +} + +// RunJobIfExists provides a mock function for the type MockService +func (_mock *MockService) RunJobIfExists(ctx context.Context, name string) { + _mock.Called(ctx, name) + return +} + +// MockService_RunJobIfExists_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RunJobIfExists' +type MockService_RunJobIfExists_Call struct { + *mock.Call +} + +// RunJobIfExists is a helper method to define mock.On call +// - ctx context.Context +// - name string +func (_e *MockService_Expecter) RunJobIfExists(ctx interface{}, name interface{}) *MockService_RunJobIfExists_Call { + return &MockService_RunJobIfExists_Call{Call: _e.mock.On("RunJobIfExists", ctx, name)} +} + +func (_c *MockService_RunJobIfExists_Call) Run(run func(ctx context.Context, name string)) *MockService_RunJobIfExists_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockService_RunJobIfExists_Call) Return() *MockService_RunJobIfExists_Call { + _c.Call.Return() + return _c +} + +func (_c *MockService_RunJobIfExists_Call) RunAndReturn(run func(ctx context.Context, name string)) *MockService_RunJobIfExists_Call { + _c.Run(run) + return _c +} + +// ScheduleJob provides a mock function for the type MockService +func (_mock *MockService) ScheduleJob(ctx context.Context, class string, name string, runtime time.Time, job scheduler.JobFunc, data any) error { + ret := _mock.Called(ctx, class, name, runtime, job, data) + + if len(ret) == 0 { + panic("no return value specified for ScheduleJob") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(context.Context, string, string, time.Time, scheduler.JobFunc, any) error); ok { + r0 = returnFunc(ctx, class, name, runtime, job, data) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockService_ScheduleJob_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ScheduleJob' +type MockService_ScheduleJob_Call struct { + *mock.Call +} + +// ScheduleJob is a helper method to define mock.On call +// - ctx context.Context +// - class string +// - name string +// - runtime time.Time +// - job scheduler.JobFunc +// - data any +func (_e *MockService_Expecter) ScheduleJob(ctx interface{}, class interface{}, name interface{}, runtime interface{}, job interface{}, data interface{}) *MockService_ScheduleJob_Call { + return &MockService_ScheduleJob_Call{Call: _e.mock.On("ScheduleJob", ctx, class, name, runtime, job, data)} +} + +func (_c *MockService_ScheduleJob_Call) Run(run func(ctx context.Context, class string, name string, runtime time.Time, job scheduler.JobFunc, data any)) *MockService_ScheduleJob_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + var arg3 time.Time + if args[3] != nil { + arg3 = args[3].(time.Time) + } + var arg4 scheduler.JobFunc + if args[4] != nil { + arg4 = args[4].(scheduler.JobFunc) + } + var arg5 any + if args[5] != nil { + arg5 = args[5].(any) + } + run( + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + ) + }) + return _c +} + +func (_c *MockService_ScheduleJob_Call) Return(err error) *MockService_ScheduleJob_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockService_ScheduleJob_Call) RunAndReturn(run func(ctx context.Context, class string, name string, runtime time.Time, job scheduler.JobFunc, data any) error) *MockService_ScheduleJob_Call { + _c.Call.Return(run) + return _c +} + +// SchedulePeriodicJob provides a mock function for the type MockService +func (_mock *MockService) SchedulePeriodicJob(ctx context.Context, class string, name string, runtime scheduler.RuntimeFunc, runtimeData any, job scheduler.JobFunc, jobData any) error { + ret := _mock.Called(ctx, class, name, runtime, runtimeData, job, jobData) + + if len(ret) == 0 { + panic("no return value specified for SchedulePeriodicJob") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(context.Context, string, string, scheduler.RuntimeFunc, any, scheduler.JobFunc, any) error); ok { + r0 = returnFunc(ctx, class, name, runtime, runtimeData, job, jobData) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockService_SchedulePeriodicJob_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SchedulePeriodicJob' +type MockService_SchedulePeriodicJob_Call struct { + *mock.Call +} + +// SchedulePeriodicJob is a helper method to define mock.On call +// - ctx context.Context +// - class string +// - name string +// - runtime scheduler.RuntimeFunc +// - runtimeData any +// - job scheduler.JobFunc +// - jobData any +func (_e *MockService_Expecter) SchedulePeriodicJob(ctx interface{}, class interface{}, name interface{}, runtime interface{}, runtimeData interface{}, job interface{}, jobData interface{}) *MockService_SchedulePeriodicJob_Call { + return &MockService_SchedulePeriodicJob_Call{Call: _e.mock.On("SchedulePeriodicJob", ctx, class, name, runtime, runtimeData, job, jobData)} +} + +func (_c *MockService_SchedulePeriodicJob_Call) Run(run func(ctx context.Context, class string, name string, runtime scheduler.RuntimeFunc, runtimeData any, job scheduler.JobFunc, jobData any)) *MockService_SchedulePeriodicJob_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + var arg3 scheduler.RuntimeFunc + if args[3] != nil { + arg3 = args[3].(scheduler.RuntimeFunc) + } + var arg4 any + if args[4] != nil { + arg4 = args[4].(any) + } + var arg5 scheduler.JobFunc + if args[5] != nil { + arg5 = args[5].(scheduler.JobFunc) + } + var arg6 any + if args[6] != nil { + arg6 = args[6].(any) + } + run( + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + ) + }) + return _c +} + +func (_c *MockService_SchedulePeriodicJob_Call) Return(err error) *MockService_SchedulePeriodicJob_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockService_SchedulePeriodicJob_Call) RunAndReturn(run func(ctx context.Context, class string, name string, runtime scheduler.RuntimeFunc, runtimeData any, job scheduler.JobFunc, jobData any) error) *MockService_SchedulePeriodicJob_Call { + _c.Call.Return(run) + return _c +} diff --git a/services/bids/standard/handler_test.go b/services/bids/standard/handler_test.go new file mode 100644 index 0000000..7a6f04b --- /dev/null +++ b/services/bids/standard/handler_test.go @@ -0,0 +1,776 @@ +package standard + +import ( + "math/big" + "sync" + "testing" + "time" + + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + "github.com/wealdtech/comptrollerd/services/bids" + "github.com/wealdtech/comptrollerd/services/comptrollerdb" + + "github.com/attestantio/go-eth2-client/spec/phase0" + relayclient "github.com/attestantio/go-relay-client" + v1 "github.com/attestantio/go-relay-client/api/v1" + + bidsMocks "github.com/wealdtech/comptrollerd/mocks/bids" + chaintimeMocks "github.com/wealdtech/comptrollerd/mocks/chaintime" + clientMocks "github.com/wealdtech/comptrollerd/mocks/client" + comptrollerdbMocks "github.com/wealdtech/comptrollerd/mocks/comptrollerdb" +) + +func TestHandleDeliveredBids_Success(t *testing.T) { + ctx := t.Context() + provider := "test-relay" + providerIndex := 0 + slot := phase0.Slot(100) + + mockDeliveredBidTraceProvider := clientMocks.NewMockDeliveredBidTraceProvider(t) + mockDeliveredBidsSetter := comptrollerdbMocks.NewMockDeliveredBidsSetter(t) + + bidTrace := &v1.BidTrace{ + Slot: slot, + ParentHash: [32]byte{1}, + BlockHash: [32]byte{2}, + BuilderPubkey: [48]byte{3}, + ProposerPubkey: [48]byte{4}, + ProposerFeeRecipient: [20]byte{5}, + GasLimit: 30000000, + GasUsed: 15000000, + Value: big.NewInt(1234567890), + } + + mockDeliveredBidTraceProvider.EXPECT().DeliveredBidTrace(mock.Anything, slot).Return(bidTrace, nil) + mockDeliveredBidsSetter.EXPECT().SetDeliveredBid(mock.Anything, mock.MatchedBy(func(bid *comptrollerdb.DeliveredBid) bool { + return bid.Slot == uint32(slot) && bid.Relay == provider + })).Return(nil) + + s := &Service{ + deliveredBidTraceProviders: []relayclient.DeliveredBidTraceProvider{mockDeliveredBidTraceProvider}, + deliveredBidsSetter: mockDeliveredBidsSetter, + } + + err := s.handleDeliveredBids(ctx, provider, providerIndex, slot) + require.NoError(t, err) + mockDeliveredBidTraceProvider.AssertExpectations(t) + mockDeliveredBidsSetter.AssertExpectations(t) +} + +func TestHandleDeliveredBids_NilBidTrace(t *testing.T) { + ctx := t.Context() + provider := "test-relay" + providerIndex := 0 + slot := phase0.Slot(100) + + mockDeliveredBidTraceProvider := clientMocks.NewMockDeliveredBidTraceProvider(t) + mockDeliveredBidTraceProvider.EXPECT().DeliveredBidTrace(mock.Anything, slot).Return(nil, nil) + + s := &Service{ + deliveredBidTraceProviders: []relayclient.DeliveredBidTraceProvider{mockDeliveredBidTraceProvider}, + } + + err := s.handleDeliveredBids(ctx, provider, providerIndex, slot) + require.NoError(t, err) + mockDeliveredBidTraceProvider.AssertExpectations(t) +} + +func TestHandleDeliveredBids_ProviderError(t *testing.T) { + ctx := t.Context() + provider := "test-relay" + providerIndex := 0 + slot := phase0.Slot(100) + + mockDeliveredBidTraceProvider := clientMocks.NewMockDeliveredBidTraceProvider(t) + mockDeliveredBidTraceProvider.EXPECT().DeliveredBidTrace(mock.Anything, slot).Return(nil, errors.New("provider error")) + + s := &Service{ + deliveredBidTraceProviders: []relayclient.DeliveredBidTraceProvider{mockDeliveredBidTraceProvider}, + } + + err := s.handleDeliveredBids(ctx, provider, providerIndex, slot) + require.Error(t, err) + assert.Contains(t, err.Error(), "failed to obtain delivered bid trace") + mockDeliveredBidTraceProvider.AssertExpectations(t) +} + +func TestHandleDeliveredBids_SetDeliveredBidError(t *testing.T) { + ctx := t.Context() + provider := "test-relay" + providerIndex := 0 + slot := phase0.Slot(100) + + mockDeliveredBidTraceProvider := clientMocks.NewMockDeliveredBidTraceProvider(t) + mockDeliveredBidsSetter := comptrollerdbMocks.NewMockDeliveredBidsSetter(t) + + bidTrace := &v1.BidTrace{ + Slot: slot, + ParentHash: [32]byte{1}, + BlockHash: [32]byte{2}, + BuilderPubkey: [48]byte{3}, + ProposerPubkey: [48]byte{4}, + ProposerFeeRecipient: [20]byte{5}, + GasLimit: 30000000, + GasUsed: 15000000, + Value: big.NewInt(1234567890), + } + + mockDeliveredBidTraceProvider.EXPECT().DeliveredBidTrace(mock.Anything, slot).Return(bidTrace, nil) + mockDeliveredBidsSetter.EXPECT().SetDeliveredBid(mock.Anything, mock.Anything).Return(errors.New("db error")) + + s := &Service{ + deliveredBidTraceProviders: []relayclient.DeliveredBidTraceProvider{mockDeliveredBidTraceProvider}, + deliveredBidsSetter: mockDeliveredBidsSetter, + } + + err := s.handleDeliveredBids(ctx, provider, providerIndex, slot) + require.Error(t, err) + assert.Contains(t, err.Error(), "failed to set delivered bid") +} +func TestHandleReceivedBids_Success(t *testing.T) { + ctx := t.Context() + provider := "test-relay" + providerIndex := 0 + slot := phase0.Slot(100) + + mockReceivedBidTraceProvider := clientMocks.NewMockReceivedBidTracesProvider(t) + mockReceivedBidsSetter := comptrollerdbMocks.NewMockReceivedBidsSetter(t) + + bidTraces := []*v1.BidTraceWithTimestamp{ + { + Slot: slot, + ParentHash: [32]byte{1}, + BlockHash: [32]byte{2}, + BuilderPubkey: [48]byte{3}, + ProposerPubkey: [48]byte{4}, + ProposerFeeRecipient: [20]byte{5}, + GasLimit: 30000000, + GasUsed: 15000000, + Value: big.NewInt(1234567890), + Timestamp: time.Unix(1000, 0), + }, + } + + mockReceivedBidTraceProvider.EXPECT().ReceivedBidTraces(mock.Anything, slot).Return(bidTraces, nil) + mockReceivedBidsSetter.EXPECT().SetReceivedBids(mock.Anything, mock.MatchedBy(func(bids []*comptrollerdb.ReceivedBid) bool { + return len(bids) == 1 && bids[0].Slot == uint32(slot) && bids[0].Relay == provider + })).Return(nil) + + s := &Service{ + receivedBidTracesProviders: []relayclient.ReceivedBidTracesProvider{mockReceivedBidTraceProvider}, + receivedBidsSetter: mockReceivedBidsSetter, + } + + err := s.handleReceivedBids(ctx, provider, providerIndex, slot) + require.NoError(t, err) + mockReceivedBidTraceProvider.AssertExpectations(t) + mockReceivedBidsSetter.AssertExpectations(t) +} + +func TestHandleReceivedBids_DeduplicateBids(t *testing.T) { + ctx := t.Context() + provider := "test-relay" + providerIndex := 0 + slot := phase0.Slot(100) + + mockReceivedBidTraceProvider := clientMocks.NewMockReceivedBidTracesProvider(t) + mockReceivedBidsSetter := comptrollerdbMocks.NewMockReceivedBidsSetter(t) + + // Same bid returned twice + bidTrace := &v1.BidTraceWithTimestamp{ + Slot: slot, + ParentHash: [32]byte{1}, + BlockHash: [32]byte{2}, + BuilderPubkey: [48]byte{3}, + ProposerPubkey: [48]byte{4}, + ProposerFeeRecipient: [20]byte{5}, + GasLimit: 30000000, + GasUsed: 15000000, + Value: big.NewInt(1234567890), + Timestamp: time.Unix(1000, 0), + } + + bidTraces := []*v1.BidTraceWithTimestamp{bidTrace, bidTrace} + + mockReceivedBidTraceProvider.EXPECT().ReceivedBidTraces(mock.Anything, slot).Return(bidTraces, nil) + mockReceivedBidsSetter.EXPECT().SetReceivedBids(mock.Anything, mock.MatchedBy(func(bids []*comptrollerdb.ReceivedBid) bool { + return len(bids) == 1 + })).Return(nil) + + s := &Service{ + receivedBidTracesProviders: []relayclient.ReceivedBidTracesProvider{mockReceivedBidTraceProvider}, + receivedBidsSetter: mockReceivedBidsSetter, + } + + err := s.handleReceivedBids(ctx, provider, providerIndex, slot) + require.NoError(t, err) + mockReceivedBidTraceProvider.AssertExpectations(t) + mockReceivedBidsSetter.AssertExpectations(t) +} + +func TestHandleReceivedBids_ProviderError(t *testing.T) { + ctx := t.Context() + provider := "test-relay" + providerIndex := 0 + slot := phase0.Slot(100) + + mockReceivedBidTraceProvider := clientMocks.NewMockReceivedBidTracesProvider(t) + mockReceivedBidTraceProvider.EXPECT().ReceivedBidTraces(mock.Anything, slot).Return(nil, errors.New("provider error")) + + s := &Service{ + receivedBidTracesProviders: []relayclient.ReceivedBidTracesProvider{mockReceivedBidTraceProvider}, + } + + err := s.handleReceivedBids(ctx, provider, providerIndex, slot) + require.Error(t, err) + assert.Contains(t, err.Error(), "failed to obtain received bid traces") + mockReceivedBidTraceProvider.AssertExpectations(t) +} + +func TestHandleReceivedBids_SetError(t *testing.T) { + ctx := t.Context() + provider := "test-relay" + providerIndex := 0 + slot := phase0.Slot(100) + + mockReceivedBidTraceProvider := clientMocks.NewMockReceivedBidTracesProvider(t) + mockReceivedBidsSetter := comptrollerdbMocks.NewMockReceivedBidsSetter(t) + + bidTraces := []*v1.BidTraceWithTimestamp{ + { + Slot: slot, + ParentHash: [32]byte{1}, + BlockHash: [32]byte{2}, + BuilderPubkey: [48]byte{3}, + ProposerPubkey: [48]byte{4}, + ProposerFeeRecipient: [20]byte{5}, + GasLimit: 30000000, + GasUsed: 15000000, + Value: big.NewInt(1234567890), + Timestamp: time.Unix(1000, 0), + }, + } + + mockReceivedBidTraceProvider.EXPECT().ReceivedBidTraces(mock.Anything, slot).Return(bidTraces, nil) + mockReceivedBidsSetter.EXPECT().SetReceivedBids(mock.Anything, mock.Anything).Return(errors.New("db error")) + + s := &Service{ + receivedBidTracesProviders: []relayclient.ReceivedBidTracesProvider{mockReceivedBidTraceProvider}, + receivedBidsSetter: mockReceivedBidsSetter, + } + + err := s.handleReceivedBids(ctx, provider, providerIndex, slot) + require.Error(t, err) + assert.Contains(t, err.Error(), "failed to set received bids") + mockReceivedBidTraceProvider.AssertExpectations(t) + mockReceivedBidsSetter.AssertExpectations(t) +} + +func TestHandleReceivedBids_EmptyBidTraces(t *testing.T) { + ctx := t.Context() + provider := "test-relay" + providerIndex := 0 + slot := phase0.Slot(100) + + mockReceivedBidTraceProvider := clientMocks.NewMockReceivedBidTracesProvider(t) + mockReceivedBidsSetter := comptrollerdbMocks.NewMockReceivedBidsSetter(t) + + mockReceivedBidTraceProvider.EXPECT().ReceivedBidTraces(mock.Anything, slot).Return([]*v1.BidTraceWithTimestamp{}, nil) + mockReceivedBidsSetter.EXPECT().SetReceivedBids(mock.Anything, mock.MatchedBy(func(bids []*comptrollerdb.ReceivedBid) bool { + return len(bids) == 0 + })).Return(nil) + + s := &Service{ + receivedBidTracesProviders: []relayclient.ReceivedBidTracesProvider{mockReceivedBidTraceProvider}, + receivedBidsSetter: mockReceivedBidsSetter, + } + + err := s.handleReceivedBids(ctx, provider, providerIndex, slot) + require.NoError(t, err) + mockReceivedBidTraceProvider.AssertExpectations(t) + mockReceivedBidsSetter.AssertExpectations(t) +} +func TestHandleSlot_Success(t *testing.T) { + ctx := t.Context() + provider := "test-relay" + providerIndex := 0 + slot := phase0.Slot(100) + + mockReceivedBidTraceProvider := clientMocks.NewMockReceivedBidTracesProvider(t) + mockDeliveredBidTraceProvider := clientMocks.NewMockDeliveredBidTraceProvider(t) + mockReceivedBidsSetter := comptrollerdbMocks.NewMockReceivedBidsSetter(t) + mockDeliveredBidsSetter := comptrollerdbMocks.NewMockDeliveredBidsSetter(t) + + mockReceivedBidTraceProvider.EXPECT().ReceivedBidTraces(mock.Anything, slot).Return([]*v1.BidTraceWithTimestamp{}, nil) + mockReceivedBidsSetter.EXPECT().SetReceivedBids(mock.Anything, mock.Anything).Return(nil) + + mockDeliveredBidTraceProvider.EXPECT().DeliveredBidTrace(mock.Anything, slot).Return(nil, nil) + + s := &Service{ + receivedBidTracesProviders: []relayclient.ReceivedBidTracesProvider{mockReceivedBidTraceProvider}, + deliveredBidTraceProviders: []relayclient.DeliveredBidTraceProvider{mockDeliveredBidTraceProvider}, + receivedBidsSetter: mockReceivedBidsSetter, + deliveredBidsSetter: mockDeliveredBidsSetter, + } + + err := s.handleSlot(ctx, provider, providerIndex, slot) + require.NoError(t, err) + mockReceivedBidTraceProvider.AssertExpectations(t) + mockDeliveredBidTraceProvider.AssertExpectations(t) + mockReceivedBidsSetter.AssertExpectations(t) +} + +func TestHandleSlot_ReceivedBidsError(t *testing.T) { + ctx := t.Context() + provider := "test-relay" + providerIndex := 0 + slot := phase0.Slot(100) + + mockReceivedBidTraceProvider := clientMocks.NewMockReceivedBidTracesProvider(t) + mockReceivedBidTraceProvider.EXPECT().ReceivedBidTraces(mock.Anything, slot).Return(nil, errors.New("provider error")) + + s := &Service{ + receivedBidTracesProviders: []relayclient.ReceivedBidTracesProvider{mockReceivedBidTraceProvider}, + } + + err := s.handleSlot(ctx, provider, providerIndex, slot) + require.Error(t, err) + assert.Contains(t, err.Error(), "failed to handle received bids") + mockReceivedBidTraceProvider.AssertExpectations(t) +} + +func TestHandleSlot_DeliveredBidsError(t *testing.T) { + ctx := t.Context() + provider := "test-relay" + providerIndex := 0 + slot := phase0.Slot(100) + + mockReceivedBidTraceProvider := clientMocks.NewMockReceivedBidTracesProvider(t) + mockDeliveredBidTraceProvider := clientMocks.NewMockDeliveredBidTraceProvider(t) + mockReceivedBidsSetter := comptrollerdbMocks.NewMockReceivedBidsSetter(t) + + mockReceivedBidTraceProvider.EXPECT().ReceivedBidTraces(mock.Anything, slot).Return([]*v1.BidTraceWithTimestamp{}, nil) + mockReceivedBidsSetter.EXPECT().SetReceivedBids(mock.Anything, mock.Anything).Return(nil) + + mockDeliveredBidTraceProvider.EXPECT().DeliveredBidTrace(mock.Anything, slot).Return(nil, errors.New("provider error")) + + s := &Service{ + receivedBidTracesProviders: []relayclient.ReceivedBidTracesProvider{mockReceivedBidTraceProvider}, + deliveredBidTraceProviders: []relayclient.DeliveredBidTraceProvider{mockDeliveredBidTraceProvider}, + receivedBidsSetter: mockReceivedBidsSetter, + } + + err := s.handleSlot(ctx, provider, providerIndex, slot) + require.Error(t, err) + assert.Contains(t, err.Error(), "failed to handle delivered bid") + mockReceivedBidTraceProvider.AssertExpectations(t) + mockDeliveredBidTraceProvider.AssertExpectations(t) + mockReceivedBidsSetter.AssertExpectations(t) +} +func TestCatchupProviderSlot_Success(t *testing.T) { + ctx := t.Context() + provider := "test-relay" + providerIndex := 0 + slot := phase0.Slot(100) + + mockReceivedBidsSetter := comptrollerdbMocks.NewMockReceivedBidsSetter(t) + mockReceivedBidTraceProvider := clientMocks.NewMockReceivedBidTracesProvider(t) + mockDeliveredBidTraceProvider := clientMocks.NewMockDeliveredBidTraceProvider(t) + + mockReceivedBidsSetter.EXPECT().BeginTx(mock.Anything).Return(ctx, func() {}, nil) + mockReceivedBidTraceProvider.EXPECT().ReceivedBidTraces(mock.Anything, slot).Return([]*v1.BidTraceWithTimestamp{}, nil) + mockReceivedBidsSetter.EXPECT().SetReceivedBids(mock.Anything, mock.Anything).Return(nil) + mockDeliveredBidTraceProvider.EXPECT().DeliveredBidTrace(mock.Anything, slot).Return(nil, nil) + mockReceivedBidsSetter.EXPECT().SetMetadata(mock.Anything, metadataKey, mock.Anything).Return(nil) + mockReceivedBidsSetter.EXPECT().CommitTx(mock.Anything).Return(nil) + + md := &metadata{ + LatestSlots: make(map[string]int64), + } + + s := &Service{ + receivedBidTracesProviders: []relayclient.ReceivedBidTracesProvider{mockReceivedBidTraceProvider}, + deliveredBidTraceProviders: []relayclient.DeliveredBidTraceProvider{mockDeliveredBidTraceProvider}, + receivedBidsSetter: mockReceivedBidsSetter, + bidsReceivedHandlers: []bids.ReceivedHandler{}, + } + + err := s.catchupProviderSlot(ctx, md, provider, providerIndex, slot) + require.NoError(t, err) + assert.Equal(t, int64(slot), md.LatestSlots[provider]) + mockReceivedBidsSetter.AssertExpectations(t) + mockReceivedBidTraceProvider.AssertExpectations(t) + mockDeliveredBidTraceProvider.AssertExpectations(t) +} + +func TestCatchupProviderSlot_BeginTxError(t *testing.T) { + ctx := t.Context() + provider := "test-relay" + providerIndex := 0 + slot := phase0.Slot(100) + + mockReceivedBidsSetter := comptrollerdbMocks.NewMockReceivedBidsSetter(t) + mockReceivedBidsSetter.EXPECT().BeginTx(mock.Anything).Return(ctx, nil, errors.New("tx error")) + + md := &metadata{ + LatestSlots: make(map[string]int64), + } + + s := &Service{ + receivedBidsSetter: mockReceivedBidsSetter, + } + + err := s.catchupProviderSlot(ctx, md, provider, providerIndex, slot) + require.Error(t, err) + assert.Contains(t, err.Error(), "failed to begin transaction") +} + +func TestCatchupProviderSlot_HandleSlotError(t *testing.T) { + ctx := t.Context() + provider := "test-relay" + providerIndex := 0 + slot := phase0.Slot(100) + + mockReceivedBidsSetter := comptrollerdbMocks.NewMockReceivedBidsSetter(t) + mockReceivedBidTraceProvider := clientMocks.NewMockReceivedBidTracesProvider(t) + + cancelCalled := false + cancel := func() { cancelCalled = true } + + mockReceivedBidsSetter.EXPECT().BeginTx(mock.Anything).Return(ctx, cancel, nil) + mockReceivedBidTraceProvider.EXPECT().ReceivedBidTraces(mock.Anything, slot).Return(nil, errors.New("provider error")) + + md := &metadata{ + LatestSlots: make(map[string]int64), + } + + s := &Service{ + receivedBidTracesProviders: []relayclient.ReceivedBidTracesProvider{mockReceivedBidTraceProvider}, + receivedBidsSetter: mockReceivedBidsSetter, + } + + err := s.catchupProviderSlot(ctx, md, provider, providerIndex, slot) + require.Error(t, err) + assert.Contains(t, err.Error(), "failed to handle slot") + assert.True(t, cancelCalled) +} + +func TestCatchupProviderSlot_SetMetadataError(t *testing.T) { + ctx := t.Context() + provider := "test-relay" + providerIndex := 0 + slot := phase0.Slot(100) + + mockReceivedBidsSetter := comptrollerdbMocks.NewMockReceivedBidsSetter(t) + mockReceivedBidTraceProvider := clientMocks.NewMockReceivedBidTracesProvider(t) + mockDeliveredBidTraceProvider := clientMocks.NewMockDeliveredBidTraceProvider(t) + + cancelCalled := false + cancel := func() { cancelCalled = true } + + mockReceivedBidsSetter.EXPECT().BeginTx(mock.Anything).Return(ctx, cancel, nil) + mockReceivedBidTraceProvider.EXPECT().ReceivedBidTraces(mock.Anything, slot).Return([]*v1.BidTraceWithTimestamp{}, nil) + mockReceivedBidsSetter.EXPECT().SetReceivedBids(mock.Anything, mock.Anything).Return(nil) + mockDeliveredBidTraceProvider.EXPECT().DeliveredBidTrace(mock.Anything, slot).Return(nil, nil) + mockReceivedBidsSetter.EXPECT().SetMetadata(mock.Anything, metadataKey, mock.Anything).Return(errors.New("metadata error")) + + md := &metadata{ + LatestSlots: make(map[string]int64), + } + + s := &Service{ + receivedBidTracesProviders: []relayclient.ReceivedBidTracesProvider{mockReceivedBidTraceProvider}, + deliveredBidTraceProviders: []relayclient.DeliveredBidTraceProvider{mockDeliveredBidTraceProvider}, + receivedBidsSetter: mockReceivedBidsSetter, + } + + err := s.catchupProviderSlot(ctx, md, provider, providerIndex, slot) + require.Error(t, err) + assert.Contains(t, err.Error(), "failed to set metadata") + assert.True(t, cancelCalled) +} + +func TestCatchupProviderSlot_CommitTxError(t *testing.T) { + ctx := t.Context() + provider := "test-relay" + providerIndex := 0 + slot := phase0.Slot(100) + + mockReceivedBidsSetter := comptrollerdbMocks.NewMockReceivedBidsSetter(t) + mockReceivedBidTraceProvider := clientMocks.NewMockReceivedBidTracesProvider(t) + mockDeliveredBidTraceProvider := clientMocks.NewMockDeliveredBidTraceProvider(t) + + cancelCalled := false + cancel := func() { cancelCalled = true } + + mockReceivedBidsSetter.EXPECT().BeginTx(mock.Anything).Return(ctx, cancel, nil) + mockReceivedBidTraceProvider.EXPECT().ReceivedBidTraces(mock.Anything, slot).Return([]*v1.BidTraceWithTimestamp{}, nil) + mockReceivedBidsSetter.EXPECT().SetReceivedBids(mock.Anything, mock.Anything).Return(nil) + mockDeliveredBidTraceProvider.EXPECT().DeliveredBidTrace(mock.Anything, slot).Return(nil, nil) + mockReceivedBidsSetter.EXPECT().SetMetadata(mock.Anything, metadataKey, mock.Anything).Return(nil) + mockReceivedBidsSetter.EXPECT().CommitTx(mock.Anything).Return(errors.New("commit error")) + + md := &metadata{ + LatestSlots: make(map[string]int64), + } + + s := &Service{ + receivedBidTracesProviders: []relayclient.ReceivedBidTracesProvider{mockReceivedBidTraceProvider}, + deliveredBidTraceProviders: []relayclient.DeliveredBidTraceProvider{mockDeliveredBidTraceProvider}, + receivedBidsSetter: mockReceivedBidsSetter, + } + + err := s.catchupProviderSlot(ctx, md, provider, providerIndex, slot) + require.Error(t, err) + assert.Contains(t, err.Error(), "failed to commit transaction") + assert.True(t, cancelCalled) +} + +func TestCatchupProviderSlot_WithHandlers(t *testing.T) { + ctx := t.Context() + provider := "test-relay" + providerIndex := 0 + slot := phase0.Slot(100) + + mockReceivedBidsSetter := comptrollerdbMocks.NewMockReceivedBidsSetter(t) + mockReceivedBidTraceProvider := clientMocks.NewMockReceivedBidTracesProvider(t) + mockDeliveredBidTraceProvider := clientMocks.NewMockDeliveredBidTraceProvider(t) + mockHandler := bidsMocks.NewMockReceivedHandler(t) + + mockReceivedBidsSetter.EXPECT().BeginTx(mock.Anything).Return(ctx, func() {}, nil) + mockReceivedBidTraceProvider.EXPECT().ReceivedBidTraces(mock.Anything, slot).Return([]*v1.BidTraceWithTimestamp{}, nil) + mockReceivedBidsSetter.EXPECT().SetReceivedBids(mock.Anything, mock.Anything).Return(nil) + mockDeliveredBidTraceProvider.EXPECT().DeliveredBidTrace(mock.Anything, slot).Return(nil, nil) + mockReceivedBidsSetter.EXPECT().SetMetadata(mock.Anything, metadataKey, mock.Anything).Return(nil) + mockReceivedBidsSetter.EXPECT().CommitTx(mock.Anything).Return(nil) + mockHandler.EXPECT().BidsReceived(mock.Anything, slot).Maybe() + + md := &metadata{ + LatestSlots: map[string]int64{provider: int64(slot)}, + } + + s := &Service{ + receivedBidTracesProviders: []relayclient.ReceivedBidTracesProvider{mockReceivedBidTraceProvider}, + deliveredBidTraceProviders: []relayclient.DeliveredBidTraceProvider{mockDeliveredBidTraceProvider}, + receivedBidsSetter: mockReceivedBidsSetter, + bidsReceivedHandlers: []bids.ReceivedHandler{mockHandler}, + } + + err := s.catchupProviderSlot(ctx, md, provider, providerIndex, slot) + require.NoError(t, err) + mockHandler.AssertExpectations(t) +} + +func TestCatchupProvider_Success(t *testing.T) { + ctx := t.Context() + provider := "test-relay" + providerIndex := 0 + + const targetSlot = 103 + + mockChainTime := chaintimeMocks.NewMockService(t) + mockChainTime.EXPECT().CurrentSlot().Return(phase0.Slot(targetSlot)) + + mockReceivedBidsSetter := comptrollerdbMocks.NewMockReceivedBidsSetter(t) + mockReceivedBidTraceProvider := clientMocks.NewMockReceivedBidTracesProvider(t) + mockDeliveredBidTraceProvider := clientMocks.NewMockDeliveredBidTraceProvider(t) + + for slot := phase0.Slot(1); slot < targetSlot; slot++ { + mockReceivedBidsSetter.EXPECT().BeginTx(mock.Anything).Return(ctx, func() {}, nil) + mockReceivedBidTraceProvider.EXPECT().ReceivedBidTraces(mock.Anything, slot).Return([]*v1.BidTraceWithTimestamp{}, nil) + mockReceivedBidsSetter.EXPECT().SetReceivedBids(mock.Anything, mock.Anything).Return(nil) + mockDeliveredBidTraceProvider.EXPECT().DeliveredBidTrace(mock.Anything, slot).Return(nil, nil) + mockReceivedBidsSetter.EXPECT().SetMetadata(mock.Anything, metadataKey, mock.Anything).Return(nil) + mockReceivedBidsSetter.EXPECT().CommitTx(mock.Anything).Return(nil) + } + + md := &metadata{ + LatestSlots: map[string]int64{provider: 0}, + } + + s := &Service{ + chainTime: mockChainTime, + receivedBidTracesProviders: []relayclient.ReceivedBidTracesProvider{mockReceivedBidTraceProvider}, + deliveredBidTraceProviders: []relayclient.DeliveredBidTraceProvider{mockDeliveredBidTraceProvider}, + receivedBidsSetter: mockReceivedBidsSetter, + bidsReceivedHandlers: []bids.ReceivedHandler{}, + } + + var wg sync.WaitGroup + wg.Add(1) + s.catchupProvider(ctx, &wg, md, provider, providerIndex) + assert.Equal(t, int64(targetSlot-1), md.LatestSlots[provider]) +} + +func TestCatchupProvider_NoSlotsToProcess(t *testing.T) { + ctx := t.Context() + provider := "test-relay" + providerIndex := 0 + + mockChainTime := chaintimeMocks.NewMockService(t) + mockChainTime.EXPECT().CurrentSlot().Return(phase0.Slot(100)) + + md := &metadata{ + LatestSlots: map[string]int64{provider: 99}, + } + + s := &Service{ + chainTime: mockChainTime, + bidsReceivedHandlers: []bids.ReceivedHandler{}, + } + + var wg sync.WaitGroup + wg.Add(1) + s.catchupProvider(ctx, &wg, md, provider, providerIndex) + assert.Equal(t, int64(99), md.LatestSlots[provider]) +} + +func TestCatchup_Success(t *testing.T) { + ctx := t.Context() + provider1 := "relay-1" + provider2 := "relay-2" + + mockChainTime := chaintimeMocks.NewMockService(t) + mockChainTime.EXPECT().CurrentSlot().Return(phase0.Slot(100)).Maybe() + + mockReceivedBidsSetter := comptrollerdbMocks.NewMockReceivedBidsSetter(t) + mockProvider1 := clientMocks.NewMockReceivedBidTracesProvider(t) + mockProvider2 := clientMocks.NewMockReceivedBidTracesProvider(t) + mockDeliveredBidTraceProvider1 := clientMocks.NewMockDeliveredBidTraceProvider(t) + mockDeliveredBidTraceProvider2 := clientMocks.NewMockDeliveredBidTraceProvider(t) + + mockProvider1.EXPECT().Name().Return(provider1) + mockProvider2.EXPECT().Name().Return(provider2) + + mockReceivedBidsSetter.EXPECT().BeginTx(mock.Anything).Return(ctx, func() {}, nil).Maybe() + mockProvider1.EXPECT().ReceivedBidTraces(mock.Anything, mock.Anything).Return([]*v1.BidTraceWithTimestamp{}, nil).Maybe() + mockProvider2.EXPECT().ReceivedBidTraces(mock.Anything, mock.Anything).Return([]*v1.BidTraceWithTimestamp{}, nil).Maybe() + mockReceivedBidsSetter.EXPECT().SetReceivedBids(mock.Anything, mock.Anything).Return(nil).Maybe() + mockDeliveredBidTraceProvider1.EXPECT().DeliveredBidTrace(mock.Anything, mock.Anything).Return(nil, nil).Maybe() + mockDeliveredBidTraceProvider2.EXPECT().DeliveredBidTrace(mock.Anything, mock.Anything).Return(nil, nil).Maybe() + mockReceivedBidsSetter.EXPECT().SetMetadata(mock.Anything, metadataKey, mock.Anything).Return(nil).Maybe() + mockReceivedBidsSetter.EXPECT().CommitTx(mock.Anything).Return(nil).Maybe() + + md := &metadata{ + LatestSlots: map[string]int64{provider1: 0, provider2: 0}, + mu: sync.RWMutex{}, + } + + s := &Service{ + chainTime: mockChainTime, + receivedBidTracesProviders: []relayclient.ReceivedBidTracesProvider{mockProvider1, mockProvider2}, + deliveredBidTraceProviders: []relayclient.DeliveredBidTraceProvider{mockDeliveredBidTraceProvider1, mockDeliveredBidTraceProvider2}, + receivedBidsSetter: mockReceivedBidsSetter, + bidsReceivedHandlers: []bids.ReceivedHandler{}, + } + + s.catchup(ctx, md) + mockProvider1.AssertExpectations(t) + mockProvider2.AssertExpectations(t) +} + +func TestCatchup_SingleProvider(t *testing.T) { + ctx := t.Context() + provider := "relay-1" + + mockChainTime := chaintimeMocks.NewMockService(t) + mockChainTime.EXPECT().CurrentSlot().Return(phase0.Slot(50)).Maybe() + + mockReceivedBidsSetter := comptrollerdbMocks.NewMockReceivedBidsSetter(t) + mockProvider := clientMocks.NewMockReceivedBidTracesProvider(t) + mockDeliveredBidTraceProvider := clientMocks.NewMockDeliveredBidTraceProvider(t) + + mockProvider.EXPECT().Name().Return(provider) + mockReceivedBidsSetter.EXPECT().BeginTx(mock.Anything).Return(ctx, func() {}, nil).Maybe() + mockProvider.EXPECT().ReceivedBidTraces(mock.Anything, mock.Anything).Return([]*v1.BidTraceWithTimestamp{}, nil).Maybe() + mockReceivedBidsSetter.EXPECT().SetReceivedBids(mock.Anything, mock.Anything).Return(nil).Maybe() + mockDeliveredBidTraceProvider.EXPECT().DeliveredBidTrace(mock.Anything, mock.Anything).Return(nil, nil).Maybe() + mockReceivedBidsSetter.EXPECT().SetMetadata(mock.Anything, metadataKey, mock.Anything).Return(nil).Maybe() + mockReceivedBidsSetter.EXPECT().CommitTx(mock.Anything).Return(nil).Maybe() + + md := &metadata{ + LatestSlots: map[string]int64{provider: 0}, + mu: sync.RWMutex{}, + } + + s := &Service{ + chainTime: mockChainTime, + receivedBidTracesProviders: []relayclient.ReceivedBidTracesProvider{mockProvider}, + deliveredBidTraceProviders: []relayclient.DeliveredBidTraceProvider{mockDeliveredBidTraceProvider}, + receivedBidsSetter: mockReceivedBidsSetter, + bidsReceivedHandlers: []bids.ReceivedHandler{}, + } + + s.catchup(ctx, md) + mockProvider.AssertExpectations(t) +} + +func TestCatchup_NoProviders(t *testing.T) { + ctx := t.Context() + + md := &metadata{ + LatestSlots: make(map[string]int64), + mu: sync.RWMutex{}, + } + + s := &Service{ + receivedBidTracesProviders: []relayclient.ReceivedBidTracesProvider{}, + bidsReceivedHandlers: []bids.ReceivedHandler{}, + } + + s.catchup(ctx, md) +} + +func TestCatchup_MultipleProvidersParallel(t *testing.T) { + ctx := t.Context() + provider1 := "relay-1" + provider2 := "relay-2" + provider3 := "relay-3" + + mockChainTime := chaintimeMocks.NewMockService(t) + mockChainTime.EXPECT().CurrentSlot().Return(phase0.Slot(100)).Maybe() + + mockReceivedBidsSetter := comptrollerdbMocks.NewMockReceivedBidsSetter(t) + mockProvider1 := clientMocks.NewMockReceivedBidTracesProvider(t) + mockProvider2 := clientMocks.NewMockReceivedBidTracesProvider(t) + mockProvider3 := clientMocks.NewMockReceivedBidTracesProvider(t) + mockDeliveredBidTraceProvider1 := clientMocks.NewMockDeliveredBidTraceProvider(t) + mockDeliveredBidTraceProvider2 := clientMocks.NewMockDeliveredBidTraceProvider(t) + mockDeliveredBidTraceProvider3 := clientMocks.NewMockDeliveredBidTraceProvider(t) + + mockProvider1.EXPECT().Name().Return(provider1) + mockProvider2.EXPECT().Name().Return(provider2) + mockProvider3.EXPECT().Name().Return(provider3) + + mockReceivedBidsSetter.EXPECT().BeginTx(mock.Anything).Return(ctx, func() {}, nil).Maybe() + mockProvider1.EXPECT().ReceivedBidTraces(mock.Anything, mock.Anything).Return([]*v1.BidTraceWithTimestamp{}, nil).Maybe() + mockProvider2.EXPECT().ReceivedBidTraces(mock.Anything, mock.Anything).Return([]*v1.BidTraceWithTimestamp{}, nil).Maybe() + mockProvider3.EXPECT().ReceivedBidTraces(mock.Anything, mock.Anything).Return([]*v1.BidTraceWithTimestamp{}, nil).Maybe() + mockReceivedBidsSetter.EXPECT().SetReceivedBids(mock.Anything, mock.Anything).Return(nil).Maybe() + mockDeliveredBidTraceProvider1.EXPECT().DeliveredBidTrace(mock.Anything, mock.Anything).Return(nil, nil).Maybe() + mockDeliveredBidTraceProvider2.EXPECT().DeliveredBidTrace(mock.Anything, mock.Anything).Return(nil, nil).Maybe() + mockDeliveredBidTraceProvider3.EXPECT().DeliveredBidTrace(mock.Anything, mock.Anything).Return(nil, nil).Maybe() + mockReceivedBidsSetter.EXPECT().SetMetadata(mock.Anything, metadataKey, mock.Anything).Return(nil).Maybe() + mockReceivedBidsSetter.EXPECT().CommitTx(mock.Anything).Return(nil).Maybe() + + md := &metadata{ + LatestSlots: map[string]int64{provider1: 0, provider2: 0, provider3: 0}, + mu: sync.RWMutex{}, + } + + s := &Service{ + chainTime: mockChainTime, + receivedBidTracesProviders: []relayclient.ReceivedBidTracesProvider{mockProvider1, mockProvider2, mockProvider3}, + deliveredBidTraceProviders: []relayclient.DeliveredBidTraceProvider{mockDeliveredBidTraceProvider1, mockDeliveredBidTraceProvider2, mockDeliveredBidTraceProvider3}, + receivedBidsSetter: mockReceivedBidsSetter, + bidsReceivedHandlers: []bids.ReceivedHandler{}, + } + + s.catchup(ctx, md) + mockProvider1.AssertExpectations(t) + mockProvider2.AssertExpectations(t) + mockProvider3.AssertExpectations(t) +} diff --git a/services/bids/standard/metadata_test.go b/services/bids/standard/metadata_test.go new file mode 100644 index 0000000..f51c513 --- /dev/null +++ b/services/bids/standard/metadata_test.go @@ -0,0 +1,159 @@ +// Copyright © 2022, 2024 Weald Technology Trading. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package standard + +import ( + "context" + "encoding/json" + "fmt" + "testing" + + relayclient "github.com/attestantio/go-relay-client" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + clientMocks "github.com/wealdtech/comptrollerd/mocks/client" + comptrollerdbMocks "github.com/wealdtech/comptrollerd/mocks/comptrollerdb" +) + +func TestGetMetadataNotFound(t *testing.T) { + mockSetter := comptrollerdbMocks.NewMockReceivedBidsSetter(t) + mockSetter.EXPECT().Metadata(mock.Anything, metadataKey).Return(nil, nil).Once() + + s := &Service{ + receivedBidsSetter: mockSetter, + } + + md, err := s.getMetadata(t.Context()) + require.NoError(t, err) + assert.NotNil(t, md) + assert.Empty(t, md.LatestSlots) + assert.Equal(t, int64(0), md.LatestSlot) +} + +func TestGetMetadataMetadataError(t *testing.T) { + mockSetter := comptrollerdbMocks.NewMockReceivedBidsSetter(t) + mockSetter.EXPECT().Metadata(mock.Anything, metadataKey).Return(nil, assert.AnError).Once() + + s := &Service{ + receivedBidsSetter: mockSetter, + } + + md, err := s.getMetadata(context.Background()) + require.Error(t, err) + assert.Nil(t, md) +} + +func TestGetMetadataUnmarshalError(t *testing.T) { + mockSetter := comptrollerdbMocks.NewMockReceivedBidsSetter(t) + mockSetter.EXPECT().Metadata(mock.Anything, metadataKey).Return([]byte("invalid json"), nil).Once() + + s := &Service{ + receivedBidsSetter: mockSetter, + } + + md, err := s.getMetadata(context.Background()) + require.Error(t, err) + assert.Nil(t, md) +} + +func TestGetMetadata_Success(t *testing.T) { + mdData := &metadata{ + LatestSlots: map[string]int64{"provider1": int64(100)}, + LatestSlot: 0, + } + mdJSON, _ := json.Marshal(mdData) + + mockSetter := comptrollerdbMocks.NewMockReceivedBidsSetter(t) + mockSetter.EXPECT().Metadata(mock.Anything, metadataKey).Return(mdJSON, nil).Once() + + s := &Service{ + receivedBidsSetter: mockSetter, + } + + md, err := s.getMetadata(context.Background()) + require.NoError(t, err) + assert.NotNil(t, md) + assert.Equal(t, int64(100), md.LatestSlots["provider1"]) +} + +func TestGetMetadata_Upgrade(t *testing.T) { + const numTestProviders = 2 + + mdData := &metadata{ + LatestSlots: map[string]int64{}, + LatestSlot: 50, + } + mdJSON, _ := json.Marshal(mdData) + + mockSetter := comptrollerdbMocks.NewMockReceivedBidsSetter(t) + mockSetter.On("Metadata", mock.Anything, metadataKey).Return(mdJSON, nil) + + providers := make([]relayclient.ReceivedBidTracesProvider, 0, numTestProviders) + for i := range numTestProviders { + provider := clientMocks.NewMockReceivedBidTracesProvider(t) + provider.EXPECT().Name().Return(fmt.Sprintf("relay_%d", i)).Maybe() + providers = append(providers, provider) + } + + s := &Service{ + receivedBidsSetter: mockSetter, + receivedBidTracesProviders: providers, + } + + md, err := s.getMetadata(context.Background()) + require.NoError(t, err) + assert.NotNil(t, md) + for i := range numTestProviders { + assert.Equal(t, int64(50), md.LatestSlots[fmt.Sprintf("relay_%d", i)]) + } + assert.Equal(t, int64(0), md.LatestSlot) +} + +func TestSetMetadataSuccess(t *testing.T) { + mdData := &metadata{ + LatestSlots: map[string]int64{"provider1": int64(100)}, + LatestSlot: 0, + } + mdJSON, _ := json.Marshal(mdData) + + mockSetter := comptrollerdbMocks.NewMockReceivedBidsSetter(t) + mockSetter.EXPECT().SetMetadata(mock.Anything, metadataKey, mdJSON).Return(nil).Once() + + s := &Service{ + receivedBidsSetter: mockSetter, + } + + err := s.setMetadata(context.Background(), mdData) + require.NoError(t, err) +} +func TestSetMetadataSetMetadataError(t *testing.T) { + mdData := &metadata{ + LatestSlots: map[string]int64{"provider1": int64(100)}, + LatestSlot: 0, + } + mdJSON, _ := json.Marshal(mdData) + + mockSetter := comptrollerdbMocks.NewMockReceivedBidsSetter(t) + mockSetter.EXPECT().SetMetadata(mock.Anything, metadataKey, mdJSON).Return(assert.AnError).Once() + + s := &Service{ + receivedBidsSetter: mockSetter, + } + + err := s.setMetadata(context.Background(), mdData) + require.Error(t, err) + assert.Contains(t, err.Error(), "failed to update metadata") +} diff --git a/services/bids/standard/parameters_test.go b/services/bids/standard/parameters_test.go new file mode 100644 index 0000000..f568463 --- /dev/null +++ b/services/bids/standard/parameters_test.go @@ -0,0 +1,142 @@ +// Copyright © 2022, 2024 Weald Technology Trading. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package standard + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" + + relayclient "github.com/attestantio/go-relay-client" + + chaintimeMocks "github.com/wealdtech/comptrollerd/mocks/chaintime" + clientMocks "github.com/wealdtech/comptrollerd/mocks/client" + comptrollerdbMocks "github.com/wealdtech/comptrollerd/mocks/comptrollerdb" + schedulerMocks "github.com/wealdtech/comptrollerd/mocks/scheduler" +) + +func TestParseAndCheckParametersValid(t *testing.T) { + params, err := parseAndCheckParameters( + WithScheduler(schedulerMocks.NewMockService(t)), + WithChainTime(chaintimeMocks.NewMockService(t)), + WithReceivedBidTracesProviders([]relayclient.ReceivedBidTracesProvider{clientMocks.NewMockReceivedBidTracesProvider(t)}), + WithReceivedBidsSetter(comptrollerdbMocks.NewMockReceivedBidsSetter(t)), + WithDeliveredBidTraceProviders([]relayclient.DeliveredBidTraceProvider{clientMocks.NewMockDeliveredBidTraceProvider(t)}), + WithDeliveredBidsSetter(comptrollerdbMocks.NewMockDeliveredBidsSetter(t)), + WithInterval(time.Second), + ) + require.NoError(t, err) + require.NotNil(t, params) +} + +func TestParseAndCheckParametersMissingScheduler(t *testing.T) { + _, err := parseAndCheckParameters( + WithChainTime(chaintimeMocks.NewMockService(t)), + WithReceivedBidTracesProviders([]relayclient.ReceivedBidTracesProvider{clientMocks.NewMockReceivedBidTracesProvider(t)}), + WithReceivedBidsSetter(comptrollerdbMocks.NewMockReceivedBidsSetter(t)), + WithDeliveredBidTraceProviders([]relayclient.DeliveredBidTraceProvider{clientMocks.NewMockDeliveredBidTraceProvider(t)}), + WithDeliveredBidsSetter(comptrollerdbMocks.NewMockDeliveredBidsSetter(t)), + WithInterval(time.Second), + ) + require.EqualError(t, err, "no scheduler specified") +} + +func TestParseAndCheckParametersMissingChainTime(t *testing.T) { + _, err := parseAndCheckParameters( + WithScheduler(schedulerMocks.NewMockService(t)), + WithReceivedBidTracesProviders([]relayclient.ReceivedBidTracesProvider{clientMocks.NewMockReceivedBidTracesProvider(t)}), + WithReceivedBidsSetter(comptrollerdbMocks.NewMockReceivedBidsSetter(t)), + WithDeliveredBidTraceProviders([]relayclient.DeliveredBidTraceProvider{clientMocks.NewMockDeliveredBidTraceProvider(t)}), + WithDeliveredBidsSetter(comptrollerdbMocks.NewMockDeliveredBidsSetter(t)), + WithInterval(time.Second), + ) + require.EqualError(t, err, "no chain time specified") +} + +func TestParseAndCheckParametersMissingReceivedBidTracesProviders(t *testing.T) { + _, err := parseAndCheckParameters( + WithScheduler(schedulerMocks.NewMockService(t)), + WithChainTime(chaintimeMocks.NewMockService(t)), + WithReceivedBidsSetter(comptrollerdbMocks.NewMockReceivedBidsSetter(t)), + WithDeliveredBidTraceProviders([]relayclient.DeliveredBidTraceProvider{clientMocks.NewMockDeliveredBidTraceProvider(t)}), + WithDeliveredBidsSetter(comptrollerdbMocks.NewMockDeliveredBidsSetter(t)), + WithInterval(time.Second), + ) + require.EqualError(t, err, "no received bid traces providers specified") +} + +func TestParseAndCheckParametersMissingReceivedBidsSetter(t *testing.T) { + _, err := parseAndCheckParameters( + WithScheduler(schedulerMocks.NewMockService(t)), + WithChainTime(chaintimeMocks.NewMockService(t)), + WithReceivedBidTracesProviders([]relayclient.ReceivedBidTracesProvider{clientMocks.NewMockReceivedBidTracesProvider(t)}), + WithDeliveredBidTraceProviders([]relayclient.DeliveredBidTraceProvider{clientMocks.NewMockDeliveredBidTraceProvider(t)}), + WithDeliveredBidsSetter(comptrollerdbMocks.NewMockDeliveredBidsSetter(t)), + WithInterval(time.Second), + ) + require.EqualError(t, err, "no received bids setter specified") +} + +func TestParseAndCheckParametersMissingDeliveredBidTraceProviders(t *testing.T) { + _, err := parseAndCheckParameters( + WithScheduler(schedulerMocks.NewMockService(t)), + WithChainTime(chaintimeMocks.NewMockService(t)), + WithReceivedBidTracesProviders([]relayclient.ReceivedBidTracesProvider{clientMocks.NewMockReceivedBidTracesProvider(t)}), + WithReceivedBidsSetter(comptrollerdbMocks.NewMockReceivedBidsSetter(t)), + WithDeliveredBidsSetter(comptrollerdbMocks.NewMockDeliveredBidsSetter(t)), + WithInterval(time.Second), + ) + require.EqualError(t, err, "no delivered bid trace providers specified") +} + +func TestParseAndCheckParametersMissingDeliveredBidsSetter(t *testing.T) { + _, err := parseAndCheckParameters( + WithScheduler(schedulerMocks.NewMockService(t)), + WithChainTime(chaintimeMocks.NewMockService(t)), + WithReceivedBidTracesProviders([]relayclient.ReceivedBidTracesProvider{clientMocks.NewMockReceivedBidTracesProvider(t)}), + WithReceivedBidsSetter(comptrollerdbMocks.NewMockReceivedBidsSetter(t)), + WithDeliveredBidTraceProviders([]relayclient.DeliveredBidTraceProvider{clientMocks.NewMockDeliveredBidTraceProvider(t)}), + WithInterval(time.Second), + ) + require.EqualError(t, err, "no delivered bids setter specified") +} + +func TestParseAndCheckParametersMissingInterval(t *testing.T) { + _, err := parseAndCheckParameters( + WithScheduler(schedulerMocks.NewMockService(t)), + WithChainTime(chaintimeMocks.NewMockService(t)), + WithReceivedBidTracesProviders([]relayclient.ReceivedBidTracesProvider{clientMocks.NewMockReceivedBidTracesProvider(t)}), + WithReceivedBidsSetter(comptrollerdbMocks.NewMockReceivedBidsSetter(t)), + WithDeliveredBidTraceProviders([]relayclient.DeliveredBidTraceProvider{clientMocks.NewMockDeliveredBidTraceProvider(t)}), + WithDeliveredBidsSetter(comptrollerdbMocks.NewMockDeliveredBidsSetter(t)), + ) + require.EqualError(t, err, "no interval specified") +} + +func TestParseAndCheckParametersWithStartSlot(t *testing.T) { + params, err := parseAndCheckParameters( + WithScheduler(schedulerMocks.NewMockService(t)), + WithChainTime(chaintimeMocks.NewMockService(t)), + WithReceivedBidTracesProviders([]relayclient.ReceivedBidTracesProvider{clientMocks.NewMockReceivedBidTracesProvider(t)}), + WithReceivedBidsSetter(comptrollerdbMocks.NewMockReceivedBidsSetter(t)), + WithDeliveredBidTraceProviders([]relayclient.DeliveredBidTraceProvider{clientMocks.NewMockDeliveredBidTraceProvider(t)}), + WithDeliveredBidsSetter(comptrollerdbMocks.NewMockDeliveredBidsSetter(t)), + WithInterval(time.Second), + WithStartSlot(1000), + ) + require.NoError(t, err) + require.NotNil(t, params) + require.Equal(t, int64(1000), params.startSlot) +} diff --git a/services/bids/standard/service.go b/services/bids/standard/service.go index c9fff49..fb48b72 100644 --- a/services/bids/standard/service.go +++ b/services/bids/standard/service.go @@ -84,8 +84,12 @@ func (s *Service) onStart(ctx context.Context, if err != nil { return errors.Wrap(err, "failed to obtain metadata") } + if startSlot >= 0 { - md.LatestSlot = startSlot - 1 + err := updateStartSlot(ctx, s, md, startSlot) + if err != nil { + return err + } } log.Trace().Msg("Running initial catchup") @@ -110,6 +114,34 @@ func (s *Service) onStart(ctx context.Context, return nil } +func updateStartSlot(ctx context.Context, s *Service, md *metadata, startSlot int64) error { + md.mu.Lock() + defer md.mu.Unlock() + + opCtx, cancel, err := s.receivedBidsSetter.BeginTx(ctx) + if err != nil { + return errors.Wrap(err, "failed to begin transaction for metadata update") + } + + for _, prov := range s.receivedBidTracesProviders { + name := prov.Name() + if cur, ok := md.LatestSlots[name]; !ok || cur < startSlot-1 { + md.LatestSlots[name] = startSlot - 1 + } + } + + if err := s.setMetadata(ctx, md); err != nil { + return errors.Wrap(err, "failed to set metadata") + } + + if err := s.receivedBidsSetter.CommitTx(opCtx); err != nil { + cancel() + return errors.Wrap(err, "failed to commit metadata transaction") + } + + return nil +} + func (s *Service) onTick(ctx context.Context, _ any) { // Only allow 1 handler to be active. acquired := s.activitySem.TryAcquire(1) diff --git a/services/bids/standard/service_test.go b/services/bids/standard/service_test.go new file mode 100644 index 0000000..406caa2 --- /dev/null +++ b/services/bids/standard/service_test.go @@ -0,0 +1,268 @@ +// Copyright © 2022, 2024 Weald Technology Trading. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package standard + +import ( + "context" + "fmt" + "testing" + "time" + + relayclient "github.com/attestantio/go-relay-client" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + bidsSvc "github.com/wealdtech/comptrollerd/services/bids" + chaintimeSvc "github.com/wealdtech/comptrollerd/services/chaintime" + comptrollerdbSvc "github.com/wealdtech/comptrollerd/services/comptrollerdb" + schedulerSvc "github.com/wealdtech/comptrollerd/services/scheduler" + + chaintimeMocks "github.com/wealdtech/comptrollerd/mocks/chaintime" + clientMocks "github.com/wealdtech/comptrollerd/mocks/client" + comptrollerdbMocks "github.com/wealdtech/comptrollerd/mocks/comptrollerdb" + schedulerMocks "github.com/wealdtech/comptrollerd/mocks/scheduler" +) + +// TestNewWithoutStartSlot verifies that startSlot < 0 skips metadata update +func TestNewWithoutStartSlot(t *testing.T) { + const numTestProviders = 2 + + receivedSetter := comptrollerdbMocks.NewMockReceivedBidsSetter(t) + receivedSetter.EXPECT().Metadata(mock.Anything, metadataKey).Return(nil, nil).Maybe() + + providers := make([]relayclient.ReceivedBidTracesProvider, 0, numTestProviders) + for i := range numTestProviders { + provider := clientMocks.NewMockReceivedBidTracesProvider(t) + provider.EXPECT().Name().Return(fmt.Sprintf("relay_%d", i)).Maybe() + providers = append(providers, provider) + } + + deliveredProviders := make([]relayclient.DeliveredBidTraceProvider, 0, numTestProviders) + for i := range numTestProviders { + deliveredProvider := clientMocks.NewMockDeliveredBidTraceProvider(t) + deliveredProvider.EXPECT().Name().Return(fmt.Sprintf("relay_%d", i)).Maybe() + deliveredProviders = append(deliveredProviders, deliveredProvider) + } + + svc, err := newTestService(t, -1, providers, deliveredProviders, receivedSetter, nil, nil, nil, nil) + require.NoError(t, err) + require.NotNil(t, svc) + +} + +// TestNewWithStartSlot_Success verifies that startSlot >= 0 sets LatestSlots for each provider. +func TestNewWithStartSlot_Success(t *testing.T) { + const numTestProviders = 2 + + receivedSetter := comptrollerdbMocks.NewMockReceivedBidsSetter(t) + receivedSetter.EXPECT().Metadata(mock.Anything, metadataKey).Return(nil, nil).Maybe() + receivedSetter.EXPECT().BeginTx(mock.Anything).Return(t.Context(), func() {}, nil).Once() + receivedSetter.EXPECT().SetMetadata(mock.Anything, metadataKey, mock.Anything).Return(nil).Once() + receivedSetter.EXPECT().CommitTx(mock.Anything).Return(nil).Once() + + providers := make([]relayclient.ReceivedBidTracesProvider, 0, numTestProviders) + for i := range numTestProviders { + provider := clientMocks.NewMockReceivedBidTracesProvider(t) + provider.EXPECT().Name().Return(fmt.Sprintf("relay_%d", i)).Maybe() + providers = append(providers, provider) + } + + deliveredProviders := make([]relayclient.DeliveredBidTraceProvider, 0, numTestProviders) + for i := range numTestProviders { + deliveredProvider := clientMocks.NewMockDeliveredBidTraceProvider(t) + deliveredProvider.EXPECT().Name().Return(fmt.Sprintf("relay_%d", i)).Maybe() + deliveredProviders = append(deliveredProviders, deliveredProvider) + } + + svc, err := newTestService(t, 100, providers, deliveredProviders, receivedSetter, nil, nil, nil, nil) + require.NoError(t, err) + require.NotNil(t, svc) +} + +// TestNewWithStartSlot_BeginTxError verifies error handling when BeginTx fails. +func TestNewWithStartSlot_BeginTxError(t *testing.T) { + schedMock := schedulerMocks.NewMockService(t) + chainTime := chaintimeMocks.NewMockService(t) + + provider := clientMocks.NewMockReceivedBidTracesProvider(t) + provider.EXPECT().Name().Return("relay1").Maybe() + providers := []relayclient.ReceivedBidTracesProvider{provider} + + deliveredProvider := clientMocks.NewMockDeliveredBidTraceProvider(t) + deliveredProvider.EXPECT().Name().Return("relay1").Maybe() + deliveredProviders := []relayclient.DeliveredBidTraceProvider{deliveredProvider} + + receivedSetter := comptrollerdbMocks.NewMockReceivedBidsSetter(t) + receivedSetter.EXPECT().Metadata(mock.Anything, metadataKey).Return(nil, nil).Maybe() + receivedSetter.EXPECT().BeginTx(mock.Anything).Return(t.Context(), nil, assert.AnError).Once() + + svc, err := newTestService(t, 100, providers, deliveredProviders, receivedSetter, nil, schedMock, chainTime, nil) + require.Error(t, err) + require.Nil(t, svc) + assert.Contains(t, err.Error(), "failed to begin transaction") +} + +// TestNewWithStartSlot_SetMetadataError verifies error handling when SetMetadata fails. +func TestNewWithStartSlot_SetMetadataError(t *testing.T) { + schedMock := schedulerMocks.NewMockService(t) + chainTime := chaintimeMocks.NewMockService(t) + + provider := clientMocks.NewMockReceivedBidTracesProvider(t) + provider.EXPECT().Name().Return("relay1").Maybe() + providers := []relayclient.ReceivedBidTracesProvider{provider} + + deliveredProvider := clientMocks.NewMockDeliveredBidTraceProvider(t) + deliveredProvider.EXPECT().Name().Return("relay1").Maybe() + deliveredProviders := []relayclient.DeliveredBidTraceProvider{deliveredProvider} + + receivedSetter := comptrollerdbMocks.NewMockReceivedBidsSetter(t) + receivedSetter.EXPECT().Metadata(mock.Anything, metadataKey).Return(nil, nil) + receivedSetter.EXPECT().BeginTx(mock.Anything).Return(t.Context(), func() {}, nil) + receivedSetter.EXPECT().SetMetadata(mock.Anything, metadataKey, mock.Anything).Return(assert.AnError) + + svc, err := newTestService(t, 100, providers, deliveredProviders, receivedSetter, nil, schedMock, chainTime, nil) + require.Error(t, err) + require.Nil(t, svc) + assert.Contains(t, err.Error(), "failed to set metadata") +} + +// TestNewWithStartSlot_CommitTxError verifies error handling when CommitTx fails. +func TestNewWithStartSlot_CommitTxError(t *testing.T) { + schedMock := schedulerMocks.NewMockService(t) + chainTime := chaintimeMocks.NewMockService(t) + + provider := clientMocks.NewMockReceivedBidTracesProvider(t) + provider.EXPECT().Name().Return("relay1").Maybe() + providers := []relayclient.ReceivedBidTracesProvider{provider} + + deliveredProvider := clientMocks.NewMockDeliveredBidTraceProvider(t) + deliveredProvider.EXPECT().Name().Return("relay1").Maybe() + deliveredProviders := []relayclient.DeliveredBidTraceProvider{deliveredProvider} + + receivedSetter := comptrollerdbMocks.NewMockReceivedBidsSetter(t) + receivedSetter.EXPECT().Metadata(mock.Anything, metadataKey).Return(nil, nil) + receivedSetter.EXPECT().BeginTx(mock.Anything).Return(t.Context(), func() {}, nil) + receivedSetter.EXPECT().SetMetadata(mock.Anything, metadataKey, mock.Anything).Return(nil) + receivedSetter.EXPECT().CommitTx(mock.Anything).Return(assert.AnError) + + svc, err := newTestService(t, 100, providers, deliveredProviders, receivedSetter, nil, schedMock, chainTime, nil) + require.Error(t, err) + require.Nil(t, svc) + assert.Contains(t, err.Error(), "failed to commit metadata transaction") +} + +// TestNewSchedulesPeriodicJob verifies that SchedulePeriodicJob is called correctly. +func TestNewSchedulesPeriodicJob(t *testing.T) { + mockScheduler := schedulerMocks.NewMockService(t) + mockScheduler.EXPECT().SchedulePeriodicJob(mock.Anything, "bids", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil).Once() + + mockChainTime := chaintimeMocks.NewMockService(t) + mockChainTime.EXPECT().CurrentSlot().Return(0).Maybe() + + provider := clientMocks.NewMockReceivedBidTracesProvider(t) + provider.EXPECT().Name().Return("relay1").Maybe() + provider.EXPECT().ReceivedBidTraces(mock.Anything, mock.Anything).Return(nil, nil).Maybe() + providers := []relayclient.ReceivedBidTracesProvider{provider} + + deliveredProvider := clientMocks.NewMockDeliveredBidTraceProvider(t) + deliveredProvider.EXPECT().Name().Return("relay1").Maybe() + deliveredProviders := []relayclient.DeliveredBidTraceProvider{deliveredProvider} + + receivedSetter := comptrollerdbMocks.NewMockReceivedBidsSetter(t) + receivedSetter.EXPECT().Metadata(mock.Anything, metadataKey).Return(nil, nil).Maybe() + + svc, err := newTestService(t, -1, providers, deliveredProviders, receivedSetter, nil, mockScheduler, mockChainTime, nil) + require.NoError(t, err) + require.NotNil(t, svc) +} + +// newTestService creates a Service instance for testing purposes. +// Parameters that are nil will be initialized with mock implementations: +// - schedulerSvc: mocked to accept SchedulePeriodicJob calls +// - chainTimeSvc: mocked to return incrementing slot numbers on each CurrentSlot() call +// Other parameters (providers, deliveredProviders, receivedSetter, handlers) can be nil or provided as needed. +// Returns the initialized Service and any error encountered during creation. +func newTestService(t *testing.T, + startSlot int64, + providers []relayclient.ReceivedBidTracesProvider, + deliveredProviders []relayclient.DeliveredBidTraceProvider, + receivedSetter comptrollerdbSvc.ReceivedBidsSetter, + deliveredSetter comptrollerdbSvc.DeliveredBidsSetter, + schedulerSvc schedulerSvc.Service, + chainTimeSvc chaintimeSvc.Service, + handlers []bidsSvc.ReceivedHandler, +) (*Service, error) { + if deliveredSetter == nil { + deliveredSetter = &noopDeliveredBidsSetter{} + } + + if schedulerSvc == nil { + schedulerMock := schedulerMocks.NewMockService(t) + schedulerMock.EXPECT().SchedulePeriodicJob( + t.Context(), // context + mock.Anything, // class + mock.Anything, // name + mock.Anything, // runtime + mock.Anything, // runtimeData + mock.Anything, // job + mock.Anything, // jobData + ).Return(nil).Once() + schedulerSvc = schedulerMock + } + + if chainTimeSvc == nil { + mockChainTime := chaintimeMocks.NewMockService(t) + mockChainTime.EXPECT().CurrentSlot().Return(0).Maybe() + chainTimeSvc = mockChainTime + } + + params := []Parameter{ + WithScheduler(schedulerSvc), + WithChainTime(chainTimeSvc), + WithReceivedBidTracesProviders(providers), + WithDeliveredBidTraceProviders(deliveredProviders), + WithReceivedBidsSetter(receivedSetter), + WithDeliveredBidsSetter(deliveredSetter), + WithBidsReceivedHandlers(handlers), + WithInterval(1 * time.Second), + WithStartSlot(startSlot), + } + + return New(t.Context(), params...) +} + +// noopDeliveredBidsSetter is a minimal, in-test implementation of +// comptrollerdb.DeliveredBidsSetter used where tests do not need DB writes. +type noopDeliveredBidsSetter struct{} + +func (n *noopDeliveredBidsSetter) BeginTx(ctx context.Context) (context.Context, context.CancelFunc, error) { + return ctx, func() {}, nil +} + +func (n *noopDeliveredBidsSetter) CommitTx(ctx context.Context) error { + return nil +} + +func (n *noopDeliveredBidsSetter) SetMetadata(ctx context.Context, key string, value []byte) error { + return nil +} + +func (n *noopDeliveredBidsSetter) Metadata(ctx context.Context, key string) ([]byte, error) { + return nil, nil +} + +func (n *noopDeliveredBidsSetter) SetDeliveredBid(ctx context.Context, bid *comptrollerdbSvc.DeliveredBid) error { + return nil +}