diff --git a/mocks/service/mockService.go b/mocks/service/mockService.go index e8a713e..e5e05f4 100644 --- a/mocks/service/mockService.go +++ b/mocks/service/mockService.go @@ -185,6 +185,36 @@ func (mr *MockIServiceMockRecorder) RetrieveMarketUpdates(fromBlock, toBLock int return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RetrieveMarketUpdates", reflect.TypeOf((*MockIService)(nil).RetrieveMarketUpdates), fromBlock, toBLock) } +// RetrieveMarketUpdatesBig mocks base method. +func (m *MockIService) RetrieveMarketUpdatesBig(fromBlock uint64, toBLock *uint64) ([]*models.MarketUpdateBig, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RetrieveMarketUpdatesBig", fromBlock, toBLock) + ret0, _ := ret[0].([]*models.MarketUpdateBig) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// RetrieveMarketUpdatesBig indicates an expected call of RetrieveMarketUpdatesBig. +func (mr *MockIServiceMockRecorder) RetrieveMarketUpdatesBig(fromBlock, toBLock interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RetrieveMarketUpdatesBig", reflect.TypeOf((*MockIService)(nil).RetrieveMarketUpdatesBig), fromBlock, toBLock) +} + +// RetrieveMarketUpdatesBigLimit mocks base method. +func (m *MockIService) RetrieveMarketUpdatesBigLimit(limit uint64) ([]*models.MarketUpdateBig, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RetrieveMarketUpdatesBigLimit", limit) + ret0, _ := ret[0].([]*models.MarketUpdateBig) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// RetrieveMarketUpdatesBigLimit indicates an expected call of RetrieveMarketUpdatesBigLimit. +func (mr *MockIServiceMockRecorder) RetrieveMarketUpdatesBigLimit(limit interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RetrieveMarketUpdatesBigLimit", reflect.TypeOf((*MockIService)(nil).RetrieveMarketUpdatesBigLimit), limit) +} + // RetrieveMarketUpdatesLimit mocks base method. func (m *MockIService) RetrieveMarketUpdatesLimit(limit uint64) ([]*models.MarketUpdate, error) { m.ctrl.T.Helper() diff --git a/models/marketData.go b/models/marketData.go index 4f8a71a..1f779f6 100644 --- a/models/marketData.go +++ b/models/marketData.go @@ -30,6 +30,31 @@ type MarketUpdate struct { TransactionHash string } +// MarketUpdateBig is a MarketUpdate model struct with big.Int value types to return data as it is received from +// the contract +// - MarketID: ID of the market. +// - Price: Price at the time of the event. +// - Skew: Market skew at the time of the event. Positive values indicate more longs. +// - Size: Size of the entire market after settlement. +// - SizeDelta: Change in market size during the update. +// - CurrentFundingRate: Current funding rate of the market. +// - CurrentFundingVelocity: Current rate of change of the funding rate. +// - BlockNumber: Block number at which the market data was fetched. +// - BlockTimestamp: Timestamp of the block at which the market data was fetched. +// - TransactionHash: Hash of the transaction where the market update occurred. +type MarketUpdateBig struct { + MarketID *big.Int + Price *big.Int + Skew *big.Int + Size *big.Int + SizeDelta *big.Int + CurrentFundingRate *big.Int + CurrentFundingVelocity *big.Int + BlockNumber uint64 + BlockTimestamp uint64 + TransactionHash string +} + // MarketMetadata is a market metadata model // - MarketID is a market ID value // - Name is a market name value @@ -114,6 +139,27 @@ func GetMarketUpdateFromEvent(event *perpsMarketGoerli.PerpsMarketGoerliMarketUp } } +// GetMarketUpdateBigFromEvent is used to get MarketUpdateBig model from given event and block timestamp +func GetMarketUpdateBigFromEvent(event *perpsMarketGoerli.PerpsMarketGoerliMarketUpdated, time uint64) *MarketUpdateBig { + if event == nil { + logger.Log().WithField("layer", "Models-GetMarketUpdateBigFromEvent").Warning("nil event received") + return &MarketUpdateBig{BlockTimestamp: time} + } + + return &MarketUpdateBig{ + MarketID: event.MarketId, + Price: event.Price, + Skew: event.Skew, + Size: event.Size, + SizeDelta: event.SizeDelta, + CurrentFundingRate: event.CurrentFundingRate, + CurrentFundingVelocity: event.CurrentFundingVelocity, + BlockNumber: event.Raw.BlockNumber, + BlockTimestamp: time, + TransactionHash: event.Raw.TxHash.Hex(), + } +} + // GetMarketMetadataFromContractResponse is used to get MarketMetadata model from given values func GetMarketMetadataFromContractResponse(id *big.Int, name string, symbol string) *MarketMetadata { return &MarketMetadata{ diff --git a/models/marketData_test.go b/models/marketData_test.go index 075602a..2eecb32 100644 --- a/models/marketData_test.go +++ b/models/marketData_test.go @@ -145,6 +145,59 @@ func TestGetMarketUpdateFromEvent(t *testing.T) { } } +func TestGetMarketUpdateBigFromEvent(t *testing.T) { + timeNow := time.Now() + + testCases := []struct { + name string + event *perpsMarketGoerli.PerpsMarketGoerliMarketUpdated + time uint64 + want *MarketUpdateBig + }{ + { + name: "nil event", + want: &MarketUpdateBig{}, + }, + { + name: "full event", + event: &perpsMarketGoerli.PerpsMarketGoerliMarketUpdated{ + MarketId: big.NewInt(1), + Price: big.NewInt(2), + Skew: big.NewInt(3), + Size: big.NewInt(4), + SizeDelta: big.NewInt(5), + CurrentFundingRate: big.NewInt(6), + CurrentFundingVelocity: big.NewInt(7), + Raw: types.Log{ + BlockNumber: 8, + TxHash: common.BytesToHash([]byte("tx hash")), + }, + }, + time: uint64(timeNow.Unix()), + want: &MarketUpdateBig{ + MarketID: big.NewInt(1), + Price: big.NewInt(2), + Skew: big.NewInt(3), + Size: big.NewInt(4), + SizeDelta: big.NewInt(5), + CurrentFundingRate: big.NewInt(6), + CurrentFundingVelocity: big.NewInt(7), + BlockNumber: 8, + TransactionHash: common.BytesToHash([]byte("tx hash")).Hex(), + BlockTimestamp: uint64(timeNow.Unix()), + }, + }, + } + + for _, tt := range testCases { + t.Run(tt.name, func(t *testing.T) { + res := GetMarketUpdateBigFromEvent(tt.event, tt.time) + + require.Equal(t, tt.want, res) + }) + } +} + func TestGetMarketMetadataFromContractResponse(t *testing.T) { testCases := []struct { name string diff --git a/perpsv3.go b/perpsv3.go index 62a4386..980d057 100644 --- a/perpsv3.go +++ b/perpsv3.go @@ -43,10 +43,22 @@ type IPerpsv3 interface { // - use nil for toBlock to use default value of a last blockchain block RetrieveMarketUpdates(fromBlock uint64, toBLock *uint64) ([]*models.MarketUpdate, error) + // RetrieveMarketUpdatesBig is used to get logs from the "MarketUpdated" event perps market contract within given block + // range + // - use 0 for fromBlock to use default value of a first contract block + // - use nil for toBlock to use default value of a last blockchain block + // It will return a MarketUpdateBig model with big.Int values + RetrieveMarketUpdatesBig(fromBlock uint64, toBLock *uint64) ([]*models.MarketUpdateBig, error) + // RetrieveMarketUpdatesLimit is used to get all "MarketUpdated" events and their additional data from the contract // with given block search limit. If given limit is 0 function will set default value to 20 000 blocks RetrieveMarketUpdatesLimit(limit uint64) ([]*models.MarketUpdate, error) + // RetrieveMarketUpdatesBigLimit is used to get all "MarketUpdated" events and their additional data from the contract + // with given block search limit. If given limit is 0 function will set default value to 20 000 blocks + // It will return a MarketUpdateBig model with big.Int values + RetrieveMarketUpdatesBigLimit(limit uint64) ([]*models.MarketUpdateBig, error) + // RetrieveLiquidations is used to get logs from the "PositionLiquidated" event perps market contract within given block // range // - use 0 for fromBlock to use default value of a first contract block @@ -149,10 +161,18 @@ func (p *Perpsv3) RetrieveMarketUpdates(fromBlock uint64, toBLock *uint64) ([]*m return p.service.RetrieveMarketUpdates(fromBlock, toBLock) } +func (p *Perpsv3) RetrieveMarketUpdatesBig(fromBlock uint64, toBLock *uint64) ([]*models.MarketUpdateBig, error) { + return p.service.RetrieveMarketUpdatesBig(fromBlock, toBLock) +} + func (p *Perpsv3) RetrieveMarketUpdatesLimit(limit uint64) ([]*models.MarketUpdate, error) { return p.service.RetrieveMarketUpdatesLimit(limit) } +func (p *Perpsv3) RetrieveMarketUpdatesBigLimit(limit uint64) ([]*models.MarketUpdateBig, error) { + return p.service.RetrieveMarketUpdatesBigLimit(limit) +} + func (p *Perpsv3) RetrieveLiquidations(fromBlock uint64, toBLock *uint64) ([]*models.Liquidation, error) { return p.service.RetrieveLiquidations(fromBlock, toBLock) } diff --git a/perpsv3_test.go b/perpsv3_test.go index 20ef76e..21a9c60 100644 --- a/perpsv3_test.go +++ b/perpsv3_test.go @@ -779,6 +779,153 @@ func TestPerpsv3_RetrieveMarketUpdatesLimit(t *testing.T) { } } +func TestPerpsv3_RetrieveMarketUpdatesBig(t *testing.T) { + blockN := uint64(10000) + + marketUpdate := &models.MarketUpdateBig{ + MarketID: big.NewInt(200), + Price: big.NewInt(3780527432113118208), + Skew: big.NewInt(527000000000000000), + Size: big.NewInt(1049000000000000000), + SizeDelta: big.NewInt(-255300000000000000), + CurrentFundingRate: big.NewInt(62031943958317), + CurrentFundingVelocity: big.NewInt(47430000000000), + BlockNumber: 13739029, + BlockTimestamp: 1692906126, + TransactionHash: "0x16704162005c11d71c745f7392a71a5ede8eb5f042e7fa917f210748773c57bf", + } + + testCases := []struct { + name string + conf *config.PerpsvConfig + startBlock uint64 + endBlock *uint64 + wantRes []*models.MarketUpdateBig + wantErr error + }{ + { + name: "no error default values", + conf: config.GetGoerliDefaultPerpsvConfig(), + startBlock: 0, + endBlock: nil, + wantRes: []*models.MarketUpdateBig{marketUpdate, marketUpdate, marketUpdate}, + }, + { + name: "no error custom values", + conf: config.GetGoerliDefaultPerpsvConfig(), + startBlock: blockN, + endBlock: &blockN, + wantRes: []*models.MarketUpdateBig{marketUpdate}, + }, + { + name: "no error custom values blank result", + conf: config.GetGoerliDefaultPerpsvConfig(), + startBlock: blockN, + endBlock: &blockN, + wantRes: []*models.MarketUpdateBig{}, + }, + { + name: "error", + conf: config.GetGoerliDefaultPerpsvConfig(), + startBlock: 0, + endBlock: nil, + wantErr: errors.FilterErr, + }, + } + + for _, tt := range testCases { + t.Run(tt.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + mockService := mock_services.NewMockIService(ctrl) + + p, _ := createTest(tt.conf) + p.service = mockService + + mockService.EXPECT().RetrieveMarketUpdatesBig(tt.startBlock, tt.endBlock).Return(tt.wantRes, tt.wantErr) + + res, err := p.RetrieveMarketUpdatesBig(tt.startBlock, tt.endBlock) + + if tt.wantErr == nil { + require.NoError(t, err) + require.Equal(t, tt.wantRes, res) + } else { + require.ErrorIs(t, tt.wantErr, err) + } + }) + } +} + +func TestPerpsv3_RetrieveMarketUpdatesBigLimit(t *testing.T) { + marketUpdate := &models.MarketUpdateBig{ + MarketID: big.NewInt(200), + Price: big.NewInt(3780527432113118208), + Skew: big.NewInt(527000000000000000), + Size: big.NewInt(1049000000000000000), + SizeDelta: big.NewInt(-255300000000000000), + CurrentFundingRate: big.NewInt(62031943958317), + CurrentFundingVelocity: big.NewInt(47430000000000), + BlockNumber: 13739029, + BlockTimestamp: 1692906126, + TransactionHash: "0x16704162005c11d71c745f7392a71a5ede8eb5f042e7fa917f210748773c57bf", + } + + testCases := []struct { + name string + conf *config.PerpsvConfig + limit uint64 + wantRes []*models.MarketUpdateBig + wantErr error + }{ + { + name: "no error default values", + conf: config.GetGoerliDefaultPerpsvConfig(), + limit: 0, + wantRes: []*models.MarketUpdateBig{marketUpdate, marketUpdate, marketUpdate}, + }, + { + name: "no error custom values", + conf: config.GetGoerliDefaultPerpsvConfig(), + limit: 1, + wantRes: []*models.MarketUpdateBig{marketUpdate}, + }, + { + name: "no error custom values blank result", + conf: config.GetGoerliDefaultPerpsvConfig(), + limit: 1, + wantRes: []*models.MarketUpdateBig{}, + }, + { + name: "error", + conf: config.GetGoerliDefaultPerpsvConfig(), + limit: 1, + wantErr: errors.FilterErr, + }, + } + + for _, tt := range testCases { + t.Run(tt.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + mockService := mock_services.NewMockIService(ctrl) + + p, _ := createTest(tt.conf) + p.service = mockService + + mockService.EXPECT().RetrieveMarketUpdatesBigLimit(tt.limit).Return(tt.wantRes, tt.wantErr) + + res, err := p.RetrieveMarketUpdatesBigLimit(tt.limit) + + if tt.wantErr == nil { + require.NoError(t, err) + require.Equal(t, tt.wantRes, res) + } else { + require.ErrorIs(t, tt.wantErr, err) + } + }) + } +} + func TestPerpsv3_ListenTrades(t *testing.T) { testCases := []struct { name string diff --git a/services/marketData.go b/services/marketData.go index 7676017..9704712 100644 --- a/services/marketData.go +++ b/services/marketData.go @@ -54,11 +54,58 @@ func (s *Service) RetrieveMarketUpdatesLimit(limit uint64) ([]*models.MarketUpda return marketUpdates, nil } +func (s *Service) RetrieveMarketUpdatesBigLimit(limit uint64) ([]*models.MarketUpdateBig, error) { + iterations, last, err := s.getIterationsForLimitQuery(limit) + if err != nil { + return nil, err + } + + var marketUpdates []*models.MarketUpdateBig + + logger.Log().WithField("layer", "Service-RetrieveMarketUpdatesBigLimit").Infof( + "fetching market updates with limit: %v to block: %v total iterations: %v...", + limit, last, iterations, + ) + + fromBlock := s.perpsMarketFirstBlock + toBlock := fromBlock + limit + for i := uint64(1); i <= iterations; i++ { + if i%10 == 0 || i == iterations { + logger.Log().WithField("layer", "Service-RetrieveMarketUpdatesBigLimit").Infof("-- iteration %v", i) + } + opts := s.getFilterOptsPerpsMarket(fromBlock, &toBlock) + + res, err := s.retrieveMarketUpdatesBig(opts) + if err != nil { + return nil, err + } + + marketUpdates = append(marketUpdates, res...) + + fromBlock = toBlock + 1 + + if i == iterations-1 { + toBlock = last + } else { + toBlock = fromBlock + limit + } + } + + logger.Log().WithField("layer", "Service-RetrieveMarketUpdatesBigLimit").Infof("task completed successfully") + + return marketUpdates, nil +} + func (s *Service) RetrieveMarketUpdates(fromBlock uint64, toBLock *uint64) ([]*models.MarketUpdate, error) { opts := s.getFilterOptsPerpsMarket(fromBlock, toBLock) return s.retrieveMarketUpdates(opts) } +func (s *Service) RetrieveMarketUpdatesBig(fromBlock uint64, toBLock *uint64) ([]*models.MarketUpdateBig, error) { + opts := s.getFilterOptsPerpsMarket(fromBlock, toBLock) + return s.retrieveMarketUpdatesBig(opts) +} + func (s *Service) GetMarketMetadata(marketID *big.Int) (*models.MarketMetadata, error) { if marketID == nil { logger.Log().WithField("layer", "Service-GetMarketMetadata").Errorf("received nil market id") @@ -134,6 +181,33 @@ func (s *Service) retrieveMarketUpdates(opts *bind.FilterOpts) ([]*models.Market return marketUpdates, nil } +// retrieveMarketUpdates is used to get retrieve market updates with given filter options +func (s *Service) retrieveMarketUpdatesBig(opts *bind.FilterOpts) ([]*models.MarketUpdateBig, error) { + iterator, err := s.perpsMarket.FilterMarketUpdated(opts) + if err != nil { + logger.Log().WithField("layer", "Service-RetrieveMarketUpdates").Errorf("error get iterator: %v", err.Error()) + return nil, errors.GetFilterErr(err, "perps market") + } + + var marketUpdates []*models.MarketUpdateBig + + for iterator.Next() { + if iterator.Error() != nil { + logger.Log().WithField("layer", "Service-RetrieveMarketUpdates").Errorf("iterator error: %v", iterator.Error().Error()) + return nil, errors.GetFilterErr(iterator.Error(), "perps market") + } + + marketUpdate, err := s.getMarketUpdateBig(iterator.Event, iterator.Event.Raw.BlockNumber) + if err != nil { + return nil, err + } + + marketUpdates = append(marketUpdates, marketUpdate) + } + + return marketUpdates, nil +} + // getMarketUpdate is used to get models.MarketUpdate from given event and block number func (s *Service) getMarketUpdate(event *perpsMarketGoerli.PerpsMarketGoerliMarketUpdated, blockN uint64) (*models.MarketUpdate, error) { block, err := s.rpcClient.HeaderByNumber(context.Background(), big.NewInt(int64(blockN))) @@ -146,3 +220,16 @@ func (s *Service) getMarketUpdate(event *perpsMarketGoerli.PerpsMarketGoerliMark return models.GetMarketUpdateFromEvent(event, block.Time), nil } + +// getMarketUpdate is used to get models.MarketUpdate from given event and block number +func (s *Service) getMarketUpdateBig(event *perpsMarketGoerli.PerpsMarketGoerliMarketUpdated, blockN uint64) (*models.MarketUpdateBig, error) { + block, err := s.rpcClient.HeaderByNumber(context.Background(), big.NewInt(int64(blockN))) + if err != nil { + logger.Log().WithField("layer", "Service-getMarketUpdate").Errorf( + "get block:%v by number error: %v", blockN, err.Error(), + ) + return nil, errors.GetRPCProviderErr(err, "HeaderByNumber") + } + + return models.GetMarketUpdateBigFromEvent(event, block.Time), nil +} diff --git a/services/marketData_test.go b/services/marketData_test.go index 251793a..6b7ec33 100644 --- a/services/marketData_test.go +++ b/services/marketData_test.go @@ -80,6 +80,74 @@ func TestService_RetrieveMarketUpdates_OnChain(t *testing.T) { } } +func TestService_RetrieveMarketUpdatesBig_OnChain(t *testing.T) { + rpc := os.Getenv("TEST_RPC") + if rpc == "" { + log.Fatal("no rpc in env vars") + } + + rpcClient, _ := ethclient.Dial(rpc) + + coreC, _ := coreGoerli.NewCoreGoerli(common.HexToAddress("0x76490713314fCEC173f44e99346F54c6e92a8E42"), rpcClient) + spot, _ := spotMarketGoerli.NewSpotMarketGoerli(common.HexToAddress("0x5FF4b3aacdeC86782d8c757FAa638d8790799E83"), rpcClient) + perps, _ := perpsMarketGoerli.NewPerpsMarketGoerli(common.HexToAddress("0xf272382cB3BE898A8CdB1A23BE056fA2Fcf4513b"), rpcClient) + + price := new(big.Int) + price.SetString("26050583159510000000000", 10) + + want := &models.MarketUpdateBig{ + MarketID: big.NewInt(200), + Price: price, + Skew: big.NewInt(527000000000000000), + Size: big.NewInt(1049000000000000000), + SizeDelta: big.NewInt(-255300000000000000), + CurrentFundingRate: big.NewInt(62031943958317), + CurrentFundingVelocity: big.NewInt(47430000000000), + BlockNumber: 13739029, + BlockTimestamp: 1692906126, + TransactionHash: "0x16704162005c11d71c745f7392a71a5ede8eb5f042e7fa917f210748773c57bf", + } + + testCases := []struct { + name string + startBlock uint64 + endBlock uint64 + wantLength int + wantAssert *models.MarketUpdateBig + }{ + { + name: "one event", + startBlock: uint64(13739029), + endBlock: uint64(13739029), + wantLength: 1, + wantAssert: want, + }, + { + name: "five events", + startBlock: uint64(13672986), + endBlock: uint64(13690512), + wantLength: 5, + }, + } + for _, tt := range testCases { + t.Run(tt.name, func(t *testing.T) { + s := NewService(rpcClient, coreC, 11664658, spot, 10875051, perps, 0) + res, err := s.RetrieveMarketUpdatesBig(tt.startBlock, &tt.endBlock) + + require.NoError(t, err) + require.Equal(t, tt.wantLength, len(res)) + + for i := 0; i < tt.wantLength; i++ { + require.NotEqual(t, &models.MarketUpdate{}, res[i]) + } + + if tt.wantAssert != nil { + require.Equal(t, tt.wantAssert, res[0]) + } + }) + } +} + func TestService_RetrieveMarketUpdates_OnChain_Limit(t *testing.T) { rpc := os.Getenv("TEST_RPC") if rpc == "" { @@ -99,6 +167,25 @@ func TestService_RetrieveMarketUpdates_OnChain_Limit(t *testing.T) { require.NoError(t, err) } +func TestService_RetrieveMarketUpdatesBig_OnChain_Limit(t *testing.T) { + rpc := os.Getenv("TEST_RPC") + if rpc == "" { + log.Fatal("no rpc in env vars") + } + + rpcClient, _ := ethclient.Dial(rpc) + + coreC, _ := coreGoerli.NewCoreGoerli(common.HexToAddress("0x76490713314fCEC173f44e99346F54c6e92a8E42"), rpcClient) + spot, _ := spotMarketGoerli.NewSpotMarketGoerli(common.HexToAddress("0x5FF4b3aacdeC86782d8c757FAa638d8790799E83"), rpcClient) + perps, _ := perpsMarketGoerli.NewPerpsMarketGoerli(common.HexToAddress("0xf272382cB3BE898A8CdB1A23BE056fA2Fcf4513b"), rpcClient) + + s := NewService(rpcClient, coreC, 11664658, spot, 10875051, perps, 12708889) + + _, err := s.RetrieveMarketUpdatesBigLimit(20000) + + require.NoError(t, err) +} + func TestService_GetMarketMetadata_OnChain(t *testing.T) { rpc := os.Getenv("TEST_RPC") if rpc == "" { diff --git a/services/service.go b/services/service.go index 3968e31..1d2887d 100644 --- a/services/service.go +++ b/services/service.go @@ -35,10 +35,18 @@ type IService interface { // range RetrieveMarketUpdates(fromBlock uint64, toBLock *uint64) ([]*models.MarketUpdate, error) + // RetrieveMarketUpdatesBig is used to get logs from the "MarketUpdated" event preps market contract within given block + // range and return model with big.Int values + RetrieveMarketUpdatesBig(fromBlock uint64, toBLock *uint64) ([]*models.MarketUpdateBig, error) + // RetrieveMarketUpdatesLimit is used to get all market updates and their additional data from the contract with given block search // limit. For most public RPC providers the value for limit is 20 000 blocks RetrieveMarketUpdatesLimit(limit uint64) ([]*models.MarketUpdate, error) + // RetrieveMarketUpdatesBigLimit is used to get logs from the "MarketUpdated" event preps market contract within given block + // range and return the model with big.Int values + RetrieveMarketUpdatesBigLimit(limit uint64) ([]*models.MarketUpdateBig, error) + // RetrieveLiquidations is used to get logs from the "PositionLiquidated" event preps market contract within given block // range RetrieveLiquidations(fromBlock uint64, toBLock *uint64) ([]*models.Liquidation, error)