code.vegaprotocol.io/vega@v0.79.0/datanode/sqlstore/liquidity_provision_test.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package sqlstore_test
    17  
    18  import (
    19  	"context"
    20  	"fmt"
    21  	"testing"
    22  	"time"
    23  
    24  	"code.vegaprotocol.io/vega/datanode/entities"
    25  	"code.vegaprotocol.io/vega/datanode/sqlstore"
    26  	"code.vegaprotocol.io/vega/libs/ptr"
    27  	"code.vegaprotocol.io/vega/logging"
    28  	"code.vegaprotocol.io/vega/protos/vega"
    29  
    30  	"github.com/stretchr/testify/assert"
    31  	"github.com/stretchr/testify/require"
    32  )
    33  
    34  func TestLiquidityProvision(t *testing.T) {
    35  	t.Run("Upsert should insert a liquidity provision record if the id doesn't exist in the current block", testInsertNewInCurrentBlock)
    36  	t.Run("Upsert should update a liquidity provision record if the id already exists in the current block", testUpdateExistingInCurrentBlock)
    37  	t.Run("Get should return all LP for a given party if no market is provided for live orders", testGetLPByPartyOnlyLiveOrders)
    38  	t.Run("Get should return all LP for a given party if no market is provided", testGetLPByPartyOnly)
    39  	t.Run("Get should return all LP for a given party and market if both are provided for live orders", testGetLPByPartyAndMarketLiveOrders)
    40  	t.Run("Get should return all LP for a given party and market if both are provided", testGetLPByPartyAndMarket)
    41  	t.Run("Get should error if no party and market are provided for live and historic orders", testGetLPNoPartyAndMarketErrors)
    42  	t.Run("Get should return all LP for a given market if no party id is provided", testGetLPNoPartyWithMarket)
    43  	t.Run("Get should return all LP for a given market if no party id is provided for live orders", testGetLPNoPartyWithMarketLiveOrders)
    44  	t.Run("Get should return LP with the corresponding reference for live orders", testGetLPByReferenceAndPartyLiveOrders)
    45  	t.Run("Get should return LP with the corresponding reference", testGetLPByReferenceAndParty)
    46  	t.Run("GetByTxHash", testLiquidityProvisionGetByTxHash)
    47  	t.Run("Get should return the current LP and pending LP if the current LP is pending", testGetLPWithPending)
    48  }
    49  
    50  func TestLiquidityProvisionPagination(t *testing.T) {
    51  	t.Run("should return all liquidity provisions if no pagination is specified", testLiquidityProvisionPaginationNoPagination)
    52  	t.Run("should return the first page of results if first is provided", testLiquidityProvisionPaginationFirst)
    53  	t.Run("should return the last page of results if last is provided", testLiquidityProvisionPaginationLast)
    54  	t.Run("should return the specified page of results if first and after are provided", testLiquidityProvisionPaginationFirstAfter)
    55  	t.Run("should return the specified page of results if last and before are provided", testLiquidityProvisionPaginationLastBefore)
    56  }
    57  
    58  func setupLPTests(t *testing.T) (*sqlstore.Blocks, *sqlstore.LiquidityProvision, sqlstore.Connection) {
    59  	t.Helper()
    60  
    61  	bs := sqlstore.NewBlocks(connectionSource)
    62  	lp := sqlstore.NewLiquidityProvision(connectionSource, logging.NewTestLogger())
    63  
    64  	return bs, lp, connectionSource
    65  }
    66  
    67  func testInsertNewInCurrentBlock(t *testing.T) {
    68  	ctx := tempTransaction(t)
    69  
    70  	bs, lp, conn := setupLPTests(t)
    71  
    72  	var rowCount int
    73  	assert.NoError(t, conn.QueryRow(ctx, "select count(*) from liquidity_provisions").Scan(&rowCount))
    74  	assert.Equal(t, 0, rowCount)
    75  
    76  	block := addTestBlock(t, ctx, bs)
    77  	lpProto := getTestLiquidityProvision(false)
    78  
    79  	data, err := entities.LiquidityProvisionFromProto(lpProto[0], generateTxHash(), block.VegaTime)
    80  	require.NoError(t, err)
    81  	assert.NoError(t, lp.Upsert(ctx, data))
    82  	err = lp.Flush(ctx)
    83  	require.NoError(t, err)
    84  
    85  	assert.NoError(t, conn.QueryRow(ctx, "select count(*) from liquidity_provisions").Scan(&rowCount))
    86  	assert.Equal(t, 1, rowCount)
    87  }
    88  
    89  func toCurrentAndPreviousLP(in ...entities.LiquidityProvision) []entities.CurrentAndPreviousLiquidityProvisions {
    90  	out := make([]entities.CurrentAndPreviousLiquidityProvisions, len(in))
    91  	for i, l := range in {
    92  		out[i] = entities.CurrentAndPreviousLiquidityProvisions{
    93  			ID:               l.ID,
    94  			PartyID:          l.PartyID,
    95  			CreatedAt:        l.CreatedAt,
    96  			UpdatedAt:        l.UpdatedAt,
    97  			MarketID:         l.MarketID,
    98  			CommitmentAmount: l.CommitmentAmount,
    99  			Fee:              l.Fee,
   100  			Sells:            l.Sells,
   101  			Buys:             l.Buys,
   102  			Version:          l.Version,
   103  			Status:           l.Status,
   104  			Reference:        l.Reference,
   105  			TxHash:           l.TxHash,
   106  			VegaTime:         l.VegaTime,
   107  		}
   108  	}
   109  	return out
   110  }
   111  
   112  func toCurrentAndPreviousLPWithPrevious(current, previous entities.LiquidityProvision) entities.CurrentAndPreviousLiquidityProvisions {
   113  	lp := toCurrentAndPreviousLP(current)[0]
   114  	lp.PreviousID = previous.ID
   115  	lp.PreviousPartyID = previous.PartyID
   116  	lp.PreviousCreatedAt = &previous.CreatedAt
   117  	lp.PreviousUpdatedAt = &previous.UpdatedAt
   118  	lp.PreviousMarketID = previous.MarketID
   119  	lp.PreviousCommitmentAmount = &previous.CommitmentAmount
   120  	lp.PreviousFee = &previous.Fee
   121  	lp.PreviousSells = previous.Sells
   122  	lp.PreviousBuys = previous.Buys
   123  	lp.PreviousVersion = &previous.Version
   124  	lp.PreviousStatus = &previous.Status
   125  	lp.PreviousReference = &previous.Reference
   126  	lp.PreviousTxHash = previous.TxHash
   127  	lp.PreviousVegaTime = &previous.VegaTime
   128  
   129  	return lp
   130  }
   131  
   132  func testUpdateExistingInCurrentBlock(t *testing.T) {
   133  	ctx := tempTransaction(t)
   134  
   135  	bs, lp, conn := setupLPTests(t)
   136  
   137  	var rowCount int
   138  	assert.NoError(t, conn.QueryRow(ctx, "select count(*) from liquidity_provisions").Scan(&rowCount))
   139  	assert.Equal(t, 0, rowCount)
   140  
   141  	block := addTestBlock(t, ctx, bs)
   142  	lpProto := getTestLiquidityProvision(false)
   143  
   144  	data, err := entities.LiquidityProvisionFromProto(lpProto[0], generateTxHash(), block.VegaTime)
   145  	require.NoError(t, err)
   146  	assert.NoError(t, lp.Upsert(ctx, data))
   147  
   148  	data.Reference = "Updated"
   149  	assert.NoError(t, lp.Upsert(ctx, data))
   150  	err = lp.Flush(ctx)
   151  	require.NoError(t, err)
   152  
   153  	assert.NoError(t, conn.QueryRow(ctx, "select count(*) from liquidity_provisions").Scan(&rowCount))
   154  	assert.Equal(t, 1, rowCount)
   155  }
   156  
   157  func testGetLPByReferenceAndParty(t *testing.T) {
   158  	ctx := tempTransaction(t)
   159  
   160  	bs, lp, conn := setupLPTests(t)
   161  
   162  	var rowCount int
   163  	assert.NoError(t, conn.QueryRow(ctx, "select count(*) from liquidity_provisions").Scan(&rowCount))
   164  	assert.Equal(t, 0, rowCount)
   165  
   166  	// Test with all LP orders
   167  	lpProto := getTestLiquidityProvision(false)
   168  
   169  	source := &testBlockSource{bs, time.Now()}
   170  	for _, lpp := range lpProto {
   171  		block := source.getNextBlock(t, ctx)
   172  
   173  		data, err := entities.LiquidityProvisionFromProto(lpp, generateTxHash(), block.VegaTime)
   174  		require.NoError(t, err)
   175  		assert.NoError(t, lp.Upsert(ctx, data))
   176  		err = lp.Flush(ctx)
   177  		require.NoError(t, err)
   178  
   179  		data.CreatedAt = data.CreatedAt.Truncate(time.Microsecond)
   180  		data.UpdatedAt = data.UpdatedAt.Truncate(time.Microsecond)
   181  	}
   182  
   183  	assert.NoError(t, conn.QueryRow(ctx, "select count(*) from liquidity_provisions").Scan(&rowCount))
   184  	assert.Equal(t, 6, rowCount)
   185  
   186  	partyID := entities.PartyID("deadbaad")
   187  	marketID := entities.MarketID("")
   188  	got, _, err := lp.Get(ctx, partyID, marketID, "TEST1", false, entities.CursorPagination{})
   189  	require.NoError(t, err)
   190  	assert.Equal(t, 1, len(got))
   191  	assert.Equal(t, got[0].Reference, "TEST1")
   192  }
   193  
   194  func testGetLPByReferenceAndPartyLiveOrders(t *testing.T) {
   195  	ctx := tempTransaction(t)
   196  
   197  	bs, lp, conn := setupLPTests(t)
   198  
   199  	var rowCount int
   200  	assert.NoError(t, conn.QueryRow(ctx, "select count(*) from live_liquidity_provisions").Scan(&rowCount))
   201  	assert.Equal(t, 0, rowCount)
   202  
   203  	// Test with live LP orders
   204  	lpProto := getTestLiquidityProvision(true)
   205  
   206  	source := &testBlockSource{bs, time.Now()}
   207  	for _, lpp := range lpProto {
   208  		block := source.getNextBlock(t, ctx)
   209  
   210  		data, err := entities.LiquidityProvisionFromProto(lpp, generateTxHash(), block.VegaTime)
   211  		require.NoError(t, err)
   212  		assert.NoError(t, lp.Upsert(ctx, data))
   213  		err = lp.Flush(ctx)
   214  		require.NoError(t, err)
   215  
   216  		data.CreatedAt = data.CreatedAt.Truncate(time.Microsecond)
   217  		data.UpdatedAt = data.UpdatedAt.Truncate(time.Microsecond)
   218  	}
   219  
   220  	assert.NoError(t, conn.QueryRow(ctx, "select count(*) from live_liquidity_provisions").Scan(&rowCount))
   221  	assert.Equal(t, 4, rowCount)
   222  
   223  	partyID := entities.PartyID("deadbaad")
   224  	marketID := entities.MarketID("")
   225  	got, _, err := lp.Get(ctx, partyID, marketID, "TEST1", true, entities.CursorPagination{})
   226  	require.NoError(t, err)
   227  	assert.Equal(t, 1, len(got))
   228  	assert.Equal(t, got[0].Reference, "TEST1")
   229  }
   230  
   231  func testLiquidityProvisionGetByTxHash(t *testing.T) {
   232  	ctx := tempTransaction(t)
   233  
   234  	bs, lp, conn := setupLPTests(t)
   235  
   236  	var rowCount int
   237  	assert.NoError(t, conn.QueryRow(ctx, "select count(*) from liquidity_provisions").Scan(&rowCount))
   238  	assert.Equal(t, 0, rowCount)
   239  
   240  	lps := []entities.LiquidityProvision{}
   241  	source := &testBlockSource{bs, time.Now()}
   242  	for _, lpp := range getTestLiquidityProvision(true) {
   243  		block := source.getNextBlock(t, ctx)
   244  
   245  		data, err := entities.LiquidityProvisionFromProto(lpp, generateTxHash(), block.VegaTime)
   246  		require.NoError(t, err)
   247  		assert.NoError(t, lp.Upsert(ctx, data))
   248  		err = lp.Flush(ctx)
   249  		require.NoError(t, err)
   250  
   251  		data.CreatedAt = data.CreatedAt.Truncate(time.Microsecond)
   252  		data.UpdatedAt = data.UpdatedAt.Truncate(time.Microsecond)
   253  
   254  		lps = append(lps, data)
   255  	}
   256  
   257  	assert.NoError(t, conn.QueryRow(ctx, "select count(*) from liquidity_provisions").Scan(&rowCount))
   258  	assert.Equal(t, 4, rowCount)
   259  
   260  	assets, err := lp.GetByTxHash(ctx, lps[0].TxHash)
   261  	require.NoError(t, err)
   262  	require.Equal(t, 1, len(assets))
   263  	require.Equal(t, lps[0].Reference, assets[0].Reference)
   264  	require.Equal(t, lps[0].ID, assets[0].ID)
   265  
   266  	assets2, err := lp.GetByTxHash(ctx, lps[1].TxHash)
   267  	require.NoError(t, err)
   268  	require.Equal(t, 1, len(assets2))
   269  	require.Equal(t, lps[1].Reference, assets2[0].Reference)
   270  	require.Equal(t, lps[1].ID, assets2[0].ID)
   271  }
   272  
   273  func testGetLPWithPending(t *testing.T) {
   274  	ctx := tempTransaction(t)
   275  	bs, lp, conn := setupLPTests(t)
   276  
   277  	var rowCount int
   278  	assert.NoError(t, conn.QueryRow(ctx, "select count(*) from liquidity_provisions").Scan(&rowCount))
   279  	assert.Equal(t, 0, rowCount)
   280  
   281  	lps := []entities.LiquidityProvision{}
   282  	for _, lpp := range getTestLiquidityProvisionsWithPendingUpdate(t, ctx, bs) {
   283  		data, err := entities.LiquidityProvisionFromProto(lpp, generateTxHash(), time.Unix(0, lpp.UpdatedAt))
   284  		require.NoError(t, err)
   285  		assert.NoError(t, lp.Upsert(ctx, data))
   286  		err = lp.Flush(ctx)
   287  		require.NoError(t, err)
   288  		lps = append(lps, data)
   289  	}
   290  
   291  	assert.NoError(t, conn.QueryRow(ctx, "select count(*) from liquidity_provisions").Scan(&rowCount))
   292  	assert.Equal(t, 3, rowCount)
   293  
   294  	want := []entities.CurrentAndPreviousLiquidityProvisions{
   295  		toCurrentAndPreviousLP(lps[0])[0],
   296  		toCurrentAndPreviousLP(lps[1])[0],
   297  		toCurrentAndPreviousLPWithPrevious(lps[2], lps[1]),
   298  	}
   299  
   300  	partyID := entities.PartyID("deadbaad")
   301  	marketID := entities.MarketID("")
   302  	got, _, err := lp.Get(ctx, partyID, marketID, "TEST1", false, entities.CursorPagination{})
   303  	require.NoError(t, err)
   304  	assert.Equal(t, want, got)
   305  }
   306  
   307  func testGetLPByPartyOnly(t *testing.T) {
   308  	ctx := tempTransaction(t)
   309  
   310  	bs, lp, conn := setupLPTests(t)
   311  
   312  	var rowCount int
   313  	assert.NoError(t, conn.QueryRow(ctx, "select count(*) from liquidity_provisions").Scan(&rowCount))
   314  	assert.Equal(t, 0, rowCount)
   315  
   316  	// Test with all LP orders
   317  	lpProto := getTestLiquidityProvision(false)
   318  
   319  	want := make([]entities.CurrentAndPreviousLiquidityProvisions, 0)
   320  
   321  	source := &testBlockSource{bs, time.Now()}
   322  	for _, lpp := range lpProto {
   323  		block := source.getNextBlock(t, ctx)
   324  
   325  		data, err := entities.LiquidityProvisionFromProto(lpp, generateTxHash(), block.VegaTime)
   326  		require.NoError(t, err)
   327  		assert.NoError(t, lp.Upsert(ctx, data))
   328  		err = lp.Flush(ctx)
   329  		require.NoError(t, err)
   330  
   331  		data.CreatedAt = data.CreatedAt.Truncate(time.Microsecond)
   332  		data.UpdatedAt = data.UpdatedAt.Truncate(time.Microsecond)
   333  
   334  		want = append(want, toCurrentAndPreviousLP(data)[0])
   335  	}
   336  
   337  	assert.NoError(t, conn.QueryRow(ctx, "select count(*) from liquidity_provisions").Scan(&rowCount))
   338  	assert.Equal(t, 6, rowCount)
   339  
   340  	partyID := entities.PartyID("deadbaad")
   341  	marketID := entities.MarketID("")
   342  	got, _, err := lp.Get(ctx, partyID, marketID, "", false, entities.CursorPagination{})
   343  	require.NoError(t, err)
   344  	assert.Equal(t, len(want), len(got))
   345  	assert.ElementsMatch(t, want, got)
   346  }
   347  
   348  func testGetLPByPartyOnlyLiveOrders(t *testing.T) {
   349  	ctx := tempTransaction(t)
   350  
   351  	bs, lp, conn := setupLPTests(t)
   352  
   353  	var rowCount int
   354  	assert.NoError(t, conn.QueryRow(ctx, "select count(*) from live_liquidity_provisions").Scan(&rowCount))
   355  	assert.Equal(t, 0, rowCount)
   356  
   357  	// Test with live LP orders
   358  	lpProto := getTestLiquidityProvision(true)
   359  
   360  	want := make([]entities.CurrentAndPreviousLiquidityProvisions, 0)
   361  
   362  	source := &testBlockSource{bs, time.Now()}
   363  	for _, lpp := range lpProto {
   364  		block := source.getNextBlock(t, ctx)
   365  
   366  		data, err := entities.LiquidityProvisionFromProto(lpp, generateTxHash(), block.VegaTime)
   367  		require.NoError(t, err)
   368  		assert.NoError(t, lp.Upsert(ctx, data))
   369  		err = lp.Flush(ctx)
   370  		require.NoError(t, err)
   371  
   372  		data.CreatedAt = data.CreatedAt.Truncate(time.Microsecond)
   373  		data.UpdatedAt = data.UpdatedAt.Truncate(time.Microsecond)
   374  
   375  		want = append(want, toCurrentAndPreviousLP(data)[0])
   376  	}
   377  
   378  	assert.NoError(t, conn.QueryRow(ctx, "select count(*) from live_liquidity_provisions").Scan(&rowCount))
   379  	assert.Equal(t, 4, rowCount)
   380  
   381  	partyID := entities.PartyID("deadbaad")
   382  	marketID := entities.MarketID("")
   383  	got, _, err := lp.Get(ctx, partyID, marketID, "", true, entities.CursorPagination{})
   384  	require.NoError(t, err)
   385  	assert.Equal(t, len(want), len(got))
   386  	assert.ElementsMatch(t, want, got)
   387  }
   388  
   389  func testGetLPByPartyAndMarket(t *testing.T) {
   390  	ctx := tempTransaction(t)
   391  
   392  	bs, lp, conn := setupLPTests(t)
   393  
   394  	var rowCount int
   395  	assert.NoError(t, conn.QueryRow(ctx, "select count(*) from liquidity_provisions").Scan(&rowCount))
   396  	assert.Equal(t, 0, rowCount)
   397  
   398  	// Test with all LP orders
   399  	lpProto := getTestLiquidityProvision(false)
   400  
   401  	wantMarketID := "dabbad00"
   402  
   403  	want := make([]entities.CurrentAndPreviousLiquidityProvisions, 0)
   404  
   405  	source := &testBlockSource{bs, time.Now()}
   406  	for _, lpp := range lpProto {
   407  		block := source.getNextBlock(t, ctx)
   408  
   409  		data, err := entities.LiquidityProvisionFromProto(lpp, generateTxHash(), block.VegaTime)
   410  		require.NoError(t, err)
   411  		assert.NoError(t, lp.Upsert(ctx, data))
   412  		err = lp.Flush(ctx)
   413  		require.NoError(t, err)
   414  
   415  		data.CreatedAt = data.CreatedAt.Truncate(time.Microsecond)
   416  		data.UpdatedAt = data.UpdatedAt.Truncate(time.Microsecond)
   417  
   418  		if data.MarketID.String() == wantMarketID {
   419  			want = append(want, toCurrentAndPreviousLP(data)[0])
   420  		}
   421  	}
   422  
   423  	assert.NoError(t, conn.QueryRow(ctx, "select count(*) from liquidity_provisions").Scan(&rowCount))
   424  	assert.Equal(t, 6, rowCount)
   425  
   426  	partyID := entities.PartyID("DEADBAAD")
   427  	marketID := entities.MarketID(wantMarketID)
   428  	got, _, err := lp.Get(ctx, partyID, marketID, "", false, entities.CursorPagination{})
   429  	require.NoError(t, err)
   430  	assert.Equal(t, len(want), len(got))
   431  	assert.ElementsMatch(t, want, got)
   432  }
   433  
   434  func testGetLPByPartyAndMarketLiveOrders(t *testing.T) {
   435  	ctx := tempTransaction(t)
   436  
   437  	bs, lp, conn := setupLPTests(t)
   438  
   439  	var rowCount int
   440  	assert.NoError(t, conn.QueryRow(ctx, "select count(*) from live_liquidity_provisions").Scan(&rowCount))
   441  	assert.Equal(t, 0, rowCount)
   442  
   443  	// Test with live LP orders
   444  	lpProto := getTestLiquidityProvision(true)
   445  
   446  	wantMarketID := "dabbad00"
   447  
   448  	want := make([]entities.CurrentAndPreviousLiquidityProvisions, 0)
   449  
   450  	source := &testBlockSource{bs, time.Now()}
   451  	for _, lpp := range lpProto {
   452  		block := source.getNextBlock(t, ctx)
   453  
   454  		data, err := entities.LiquidityProvisionFromProto(lpp, generateTxHash(), block.VegaTime)
   455  		require.NoError(t, err)
   456  		assert.NoError(t, lp.Upsert(ctx, data))
   457  		err = lp.Flush(ctx)
   458  		require.NoError(t, err)
   459  
   460  		data.CreatedAt = data.CreatedAt.Truncate(time.Microsecond)
   461  		data.UpdatedAt = data.UpdatedAt.Truncate(time.Microsecond)
   462  
   463  		if data.MarketID.String() == wantMarketID {
   464  			want = append(want, toCurrentAndPreviousLP(data)[0])
   465  		}
   466  	}
   467  
   468  	assert.NoError(t, conn.QueryRow(ctx, "select count(*) from live_liquidity_provisions").Scan(&rowCount))
   469  	assert.Equal(t, 4, rowCount)
   470  
   471  	partyID := entities.PartyID("DEADBAAD")
   472  	marketID := entities.MarketID(wantMarketID)
   473  	got, _, err := lp.Get(ctx, partyID, marketID, "", true, entities.CursorPagination{})
   474  	require.NoError(t, err)
   475  	assert.Equal(t, len(want), len(got))
   476  	assert.ElementsMatch(t, want, got)
   477  }
   478  
   479  func testGetLPNoPartyAndMarketErrors(t *testing.T) {
   480  	ctx := tempTransaction(t)
   481  
   482  	_, lp, _ := setupLPTests(t)
   483  	partyID := entities.PartyID("")
   484  	marketID := entities.MarketID("")
   485  	_, _, err := lp.Get(ctx, partyID, marketID, "", false, entities.CursorPagination{})
   486  	assert.Error(t, err)
   487  
   488  	_, _, err = lp.Get(ctx, partyID, marketID, "", true, entities.CursorPagination{})
   489  	assert.Error(t, err)
   490  }
   491  
   492  func testGetLPNoPartyWithMarket(t *testing.T) {
   493  	ctx := tempTransaction(t)
   494  
   495  	bs, lp, conn := setupLPTests(t)
   496  
   497  	var rowCount int
   498  	assert.NoError(t, conn.QueryRow(ctx, "select count(*) from liquidity_provisions").Scan(&rowCount))
   499  	assert.Equal(t, 0, rowCount)
   500  
   501  	// Test for all LP orders
   502  	lpProto := getTestLiquidityProvision(false)
   503  	wantMarketID := "dabbad00"
   504  	want := make([]entities.CurrentAndPreviousLiquidityProvisions, 0)
   505  
   506  	source := &testBlockSource{bs, time.Now()}
   507  	for _, lpp := range lpProto {
   508  		block := source.getNextBlock(t, ctx)
   509  
   510  		data, err := entities.LiquidityProvisionFromProto(lpp, generateTxHash(), block.VegaTime)
   511  		require.NoError(t, err)
   512  		assert.NoError(t, lp.Upsert(ctx, data))
   513  		err = lp.Flush(ctx)
   514  		require.NoError(t, err)
   515  
   516  		data.CreatedAt = data.CreatedAt.Truncate(time.Microsecond)
   517  		data.UpdatedAt = data.UpdatedAt.Truncate(time.Microsecond)
   518  
   519  		if data.MarketID.String() == wantMarketID {
   520  			want = append(want, toCurrentAndPreviousLP(data)[0])
   521  		}
   522  	}
   523  
   524  	assert.NoError(t, conn.QueryRow(ctx, "select count(*) from liquidity_provisions").Scan(&rowCount))
   525  	assert.Equal(t, 6, rowCount)
   526  	partyID := entities.PartyID("")
   527  	marketID := entities.MarketID(wantMarketID)
   528  	got, _, err := lp.Get(ctx, partyID, marketID, "", false, entities.CursorPagination{})
   529  	require.NoError(t, err)
   530  	assert.Equal(t, len(want), len(got))
   531  	assert.ElementsMatch(t, want, got)
   532  }
   533  
   534  func testGetLPNoPartyWithMarketLiveOrders(t *testing.T) {
   535  	ctx := tempTransaction(t)
   536  
   537  	bs, lp, conn := setupLPTests(t)
   538  
   539  	var rowCount int
   540  	assert.NoError(t, conn.QueryRow(ctx, "select count(*) from live_liquidity_provisions").Scan(&rowCount))
   541  	assert.Equal(t, 0, rowCount)
   542  
   543  	// Test for live LP orders
   544  	lpProto := getTestLiquidityProvision(true)
   545  	wantMarketID := "dabbad00"
   546  	want := make([]entities.CurrentAndPreviousLiquidityProvisions, 0)
   547  
   548  	source := &testBlockSource{bs, time.Now()}
   549  	for _, lpp := range lpProto {
   550  		block := source.getNextBlock(t, ctx)
   551  
   552  		data, err := entities.LiquidityProvisionFromProto(lpp, generateTxHash(), block.VegaTime)
   553  		require.NoError(t, err)
   554  		assert.NoError(t, lp.Upsert(ctx, data))
   555  		err = lp.Flush(ctx)
   556  		require.NoError(t, err)
   557  
   558  		data.CreatedAt = data.CreatedAt.Truncate(time.Microsecond)
   559  		data.UpdatedAt = data.UpdatedAt.Truncate(time.Microsecond)
   560  
   561  		if data.MarketID.String() == wantMarketID {
   562  			want = append(want, toCurrentAndPreviousLP(data)[0])
   563  		}
   564  	}
   565  
   566  	assert.NoError(t, conn.QueryRow(ctx, "select count(*) from live_liquidity_provisions").Scan(&rowCount))
   567  	assert.Equal(t, 4, rowCount)
   568  	partyID := entities.PartyID("")
   569  	marketID := entities.MarketID(wantMarketID)
   570  	got, _, err := lp.Get(ctx, partyID, marketID, "", true, entities.CursorPagination{})
   571  	require.NoError(t, err)
   572  	assert.Equal(t, len(want), len(got))
   573  	assert.ElementsMatch(t, want, got)
   574  }
   575  
   576  func getTestLiquidityProvision(live bool) []*vega.LiquidityProvision {
   577  	testres := []*vega.LiquidityProvision{
   578  		{
   579  			Id:               "deadbeef",
   580  			PartyId:          "deadbaad",
   581  			CreatedAt:        time.Now().UnixNano(),
   582  			UpdatedAt:        time.Now().UnixNano(),
   583  			MarketId:         "cafed00d",
   584  			CommitmentAmount: "100000",
   585  			Fee:              "0.3",
   586  			Sells:            nil,
   587  			Buys:             nil,
   588  			Version:          0,
   589  			Status:           vega.LiquidityProvision_STATUS_ACTIVE,
   590  			Reference:        "TEST1",
   591  		},
   592  		{
   593  			Id:               "0d15ea5e",
   594  			PartyId:          "deadbaad",
   595  			CreatedAt:        time.Now().UnixNano(),
   596  			UpdatedAt:        time.Now().UnixNano(),
   597  			MarketId:         "dabbad00",
   598  			CommitmentAmount: "100000",
   599  			Fee:              "0.3",
   600  			Sells:            nil,
   601  			Buys:             nil,
   602  			Version:          0,
   603  			Status:           vega.LiquidityProvision_STATUS_ACTIVE,
   604  			Reference:        "TEST2",
   605  		},
   606  		{
   607  			Id:               "deadc0de",
   608  			PartyId:          "deadbaad",
   609  			CreatedAt:        time.Now().UnixNano(),
   610  			UpdatedAt:        time.Now().UnixNano(),
   611  			MarketId:         "deadd00d",
   612  			CommitmentAmount: "100000",
   613  			Fee:              "0.3",
   614  			Sells:            nil,
   615  			Buys:             nil,
   616  			Version:          0,
   617  			Status:           vega.LiquidityProvision_STATUS_ACTIVE,
   618  			Reference:        "TEST3",
   619  		},
   620  		{
   621  			Id:               "deadc0df",
   622  			PartyId:          "deadbaad",
   623  			CreatedAt:        time.Now().UnixNano(),
   624  			UpdatedAt:        time.Now().UnixNano(),
   625  			MarketId:         "deadd00d",
   626  			CommitmentAmount: "100000",
   627  			Fee:              "0.3",
   628  			Sells:            nil,
   629  			Buys:             nil,
   630  			Version:          0,
   631  			Status:           vega.LiquidityProvision_STATUS_PENDING,
   632  			Reference:        "TEST4",
   633  		},
   634  	}
   635  
   636  	if !live {
   637  		testres = append(
   638  			testres,
   639  			[]*vega.LiquidityProvision{
   640  				{
   641  					Id:               "deadc0ff",
   642  					PartyId:          "deadbaad",
   643  					CreatedAt:        time.Now().UnixNano(),
   644  					UpdatedAt:        time.Now().UnixNano(),
   645  					MarketId:         "deadd00d",
   646  					CommitmentAmount: "100000",
   647  					Fee:              "0.3",
   648  					Sells:            nil,
   649  					Buys:             nil,
   650  					Version:          0,
   651  					Status:           vega.LiquidityProvision_STATUS_STOPPED,
   652  					Reference:        "TEST5",
   653  				},
   654  				{
   655  					Id:               "deadc0ef",
   656  					PartyId:          "deadbaad",
   657  					CreatedAt:        time.Now().UnixNano(),
   658  					UpdatedAt:        time.Now().UnixNano(),
   659  					MarketId:         "deadd00d",
   660  					CommitmentAmount: "100000",
   661  					Fee:              "0.3",
   662  					Sells:            nil,
   663  					Buys:             nil,
   664  					Version:          0,
   665  					Status:           vega.LiquidityProvision_STATUS_CANCELLED,
   666  					Reference:        "TEST6",
   667  				},
   668  			}...)
   669  	}
   670  
   671  	return testres
   672  }
   673  
   674  func getTestLiquidityProvisionsWithPendingUpdate(t *testing.T, ctx context.Context, bs *sqlstore.Blocks) []*vega.LiquidityProvision {
   675  	t.Helper()
   676  	created := addTestBlock(t, ctx, bs)
   677  	testres := []*vega.LiquidityProvision{
   678  		{
   679  			Id:               "deadbeef",
   680  			PartyId:          "deadbaad",
   681  			CreatedAt:        created.VegaTime.UnixNano(),
   682  			UpdatedAt:        created.VegaTime.UnixNano(),
   683  			MarketId:         "cafed00d",
   684  			CommitmentAmount: "100000",
   685  			Fee:              "0.3",
   686  			Sells:            nil,
   687  			Buys:             nil,
   688  			Version:          1,
   689  			Status:           vega.LiquidityProvision_STATUS_PENDING,
   690  			Reference:        "TEST1",
   691  		},
   692  	}
   693  
   694  	updated := addTestBlock(t, ctx, bs)
   695  	testres = append(testres, &vega.LiquidityProvision{
   696  		Id:               "deadbeef",
   697  		PartyId:          "deadbaad",
   698  		CreatedAt:        created.VegaTime.UnixNano(),
   699  		UpdatedAt:        updated.VegaTime.UnixNano(),
   700  		MarketId:         "cafed00d",
   701  		CommitmentAmount: "100000",
   702  		Fee:              "0.3",
   703  		Sells:            nil,
   704  		Buys:             nil,
   705  		Version:          1,
   706  		Status:           vega.LiquidityProvision_STATUS_ACTIVE,
   707  		Reference:        "TEST1",
   708  	})
   709  
   710  	updated = addTestBlock(t, ctx, bs)
   711  	testres = append(testres, &vega.LiquidityProvision{
   712  		Id:               "deadbeef",
   713  		PartyId:          "deadbaad",
   714  		CreatedAt:        created.VegaTime.UnixNano(),
   715  		UpdatedAt:        updated.VegaTime.UnixNano(),
   716  		MarketId:         "cafed00d",
   717  		CommitmentAmount: "100000",
   718  		Fee:              "0.3",
   719  		Sells:            nil,
   720  		Buys:             nil,
   721  		Version:          2,
   722  		Status:           vega.LiquidityProvision_STATUS_PENDING,
   723  		Reference:        "TEST1",
   724  	})
   725  	return testres
   726  }
   727  
   728  func testLiquidityProvisionPaginationNoPagination(t *testing.T) {
   729  	ctx := tempTransaction(t)
   730  
   731  	bs, lpStore, _ := setupLPTests(t)
   732  	testLps := toCurrentAndPreviousLP(addLiquidityProvisions(ctx, t, bs, lpStore)...)
   733  
   734  	pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, false)
   735  	require.NoError(t, err)
   736  	got, pageInfo, err := lpStore.Get(ctx, entities.PartyID("deadbaad"), entities.MarketID(""), "", false, pagination)
   737  
   738  	require.NoError(t, err)
   739  	assert.Equal(t, testLps, got)
   740  	assert.False(t, pageInfo.HasPreviousPage)
   741  	assert.False(t, pageInfo.HasNextPage)
   742  	assert.Equal(t, entities.NewCursor(entities.LiquidityProvisionCursor{
   743  		VegaTime: testLps[0].VegaTime,
   744  		ID:       testLps[0].ID,
   745  	}.String()).Encode(), pageInfo.StartCursor)
   746  	assert.Equal(t, entities.NewCursor(entities.LiquidityProvisionCursor{
   747  		VegaTime: testLps[9].VegaTime,
   748  		ID:       testLps[9].ID,
   749  	}.String()).Encode(), pageInfo.EndCursor)
   750  }
   751  
   752  func testLiquidityProvisionPaginationFirst(t *testing.T) {
   753  	ctx := tempTransaction(t)
   754  
   755  	bs, lpStore, _ := setupLPTests(t)
   756  	testLps := toCurrentAndPreviousLP(addLiquidityProvisions(ctx, t, bs, lpStore)...)
   757  
   758  	first := int32(3)
   759  	pagination, err := entities.NewCursorPagination(&first, nil, nil, nil, false)
   760  	require.NoError(t, err)
   761  	got, pageInfo, err := lpStore.Get(ctx, entities.PartyID("deadbaad"), entities.MarketID(""), "", false, pagination)
   762  
   763  	require.NoError(t, err)
   764  	want := testLps[:3]
   765  	assert.Equal(t, want, got)
   766  	assert.False(t, pageInfo.HasPreviousPage)
   767  	assert.True(t, pageInfo.HasNextPage)
   768  	assert.Equal(t, entities.NewCursor(entities.LiquidityProvisionCursor{
   769  		VegaTime: testLps[0].VegaTime,
   770  		ID:       testLps[0].ID,
   771  	}.String()).Encode(), pageInfo.StartCursor)
   772  	assert.Equal(t, entities.NewCursor(entities.LiquidityProvisionCursor{
   773  		VegaTime: testLps[2].VegaTime,
   774  		ID:       testLps[2].ID,
   775  	}.String()).Encode(), pageInfo.EndCursor)
   776  }
   777  
   778  func testLiquidityProvisionPaginationLast(t *testing.T) {
   779  	ctx := tempTransaction(t)
   780  
   781  	bs, lpStore, _ := setupLPTests(t)
   782  	testLps := toCurrentAndPreviousLP(addLiquidityProvisions(ctx, t, bs, lpStore)...)
   783  
   784  	last := int32(3)
   785  	pagination, err := entities.NewCursorPagination(nil, nil, &last, nil, false)
   786  	require.NoError(t, err)
   787  	got, pageInfo, err := lpStore.Get(ctx, entities.PartyID("deadbaad"), entities.MarketID(""), "", false, pagination)
   788  
   789  	require.NoError(t, err)
   790  	want := testLps[7:]
   791  	assert.Equal(t, want, got)
   792  	assert.True(t, pageInfo.HasPreviousPage)
   793  	assert.False(t, pageInfo.HasNextPage)
   794  	assert.Equal(t, entities.NewCursor(entities.LiquidityProvisionCursor{
   795  		VegaTime: testLps[7].VegaTime,
   796  		ID:       testLps[7].ID,
   797  	}.String()).Encode(), pageInfo.StartCursor)
   798  	assert.Equal(t, entities.NewCursor(entities.LiquidityProvisionCursor{
   799  		VegaTime: testLps[9].VegaTime,
   800  		ID:       testLps[9].ID,
   801  	}.String()).Encode(), pageInfo.EndCursor)
   802  }
   803  
   804  func testLiquidityProvisionPaginationFirstAfter(t *testing.T) {
   805  	ctx := tempTransaction(t)
   806  
   807  	bs, lpStore, _ := setupLPTests(t)
   808  	testLps := toCurrentAndPreviousLP(addLiquidityProvisions(ctx, t, bs, lpStore)...)
   809  
   810  	first := int32(3)
   811  	after := testLps[2].Cursor().Encode()
   812  	pagination, err := entities.NewCursorPagination(&first, &after, nil, nil, false)
   813  	require.NoError(t, err)
   814  	got, pageInfo, err := lpStore.Get(ctx, entities.PartyID("deadbaad"), entities.MarketID(""), "", false, pagination)
   815  
   816  	require.NoError(t, err)
   817  	want := testLps[3:6]
   818  	assert.Equal(t, want, got)
   819  	assert.True(t, pageInfo.HasPreviousPage)
   820  	assert.True(t, pageInfo.HasNextPage)
   821  	assert.Equal(t, entities.NewCursor(entities.LiquidityProvisionCursor{
   822  		VegaTime: testLps[3].VegaTime,
   823  		ID:       testLps[3].ID,
   824  	}.String()).Encode(), pageInfo.StartCursor)
   825  	assert.Equal(t, entities.NewCursor(entities.LiquidityProvisionCursor{
   826  		VegaTime: testLps[5].VegaTime,
   827  		ID:       testLps[5].ID,
   828  	}.String()).Encode(), pageInfo.EndCursor)
   829  }
   830  
   831  func testLiquidityProvisionPaginationLastBefore(t *testing.T) {
   832  	ctx := tempTransaction(t)
   833  
   834  	bs, lsStore, _ := setupLPTests(t)
   835  	testLps := toCurrentAndPreviousLP(addLiquidityProvisions(ctx, t, bs, lsStore)...)
   836  
   837  	last := int32(3)
   838  	before := entities.NewCursor(entities.LiquidityProvisionCursor{
   839  		VegaTime: testLps[7].VegaTime,
   840  		ID:       testLps[7].ID,
   841  	}.String()).Encode()
   842  	pagination, err := entities.NewCursorPagination(nil, nil, &last, &before, false)
   843  	require.NoError(t, err)
   844  	got, pageInfo, err := lsStore.Get(ctx, entities.PartyID("deadbaad"), entities.MarketID(""), "", false, pagination)
   845  
   846  	require.NoError(t, err)
   847  	want := testLps[4:7]
   848  	assert.Equal(t, want, got)
   849  	assert.True(t, pageInfo.HasPreviousPage)
   850  	assert.True(t, pageInfo.HasNextPage)
   851  	assert.Equal(t, entities.NewCursor(entities.LiquidityProvisionCursor{
   852  		VegaTime: testLps[4].VegaTime,
   853  		ID:       testLps[4].ID,
   854  	}.String()).Encode(), pageInfo.StartCursor)
   855  	assert.Equal(t, entities.NewCursor(entities.LiquidityProvisionCursor{
   856  		VegaTime: testLps[6].VegaTime,
   857  		ID:       testLps[6].ID,
   858  	}.String()).Encode(), pageInfo.EndCursor)
   859  }
   860  
   861  func addLiquidityProvisions(ctx context.Context, t *testing.T, bs *sqlstore.Blocks, lpstore *sqlstore.LiquidityProvision) []entities.LiquidityProvision {
   862  	t.Helper()
   863  	vegaTime := time.Now().Truncate(time.Microsecond)
   864  	amount := int64(1000)
   865  	lps := make([]entities.LiquidityProvision, 0, 10)
   866  	for i := 0; i < 10; i++ {
   867  		addTestBlockForTime(t, ctx, bs, vegaTime)
   868  
   869  		lp := &vega.LiquidityProvision{
   870  			Id:               fmt.Sprintf("deadbeef%02d", i+1),
   871  			PartyId:          "deadbaad",
   872  			CreatedAt:        vegaTime.UnixNano(),
   873  			UpdatedAt:        vegaTime.UnixNano(),
   874  			MarketId:         "cafed00d",
   875  			CommitmentAmount: "100000",
   876  			Fee:              "0.3",
   877  			Sells:            nil,
   878  			Buys:             nil,
   879  			Version:          0,
   880  			Status:           vega.LiquidityProvision_STATUS_ACTIVE,
   881  			Reference:        "TEST1",
   882  		}
   883  
   884  		withdrawal, err := entities.LiquidityProvisionFromProto(lp, generateTxHash(), vegaTime)
   885  		require.NoError(t, err, "Converting withdrawal proto to database entity")
   886  		err = lpstore.Upsert(ctx, withdrawal)
   887  		require.NoError(t, err)
   888  		err = lpstore.Flush(ctx)
   889  		require.NoError(t, err)
   890  		lps = append(lps, withdrawal)
   891  
   892  		vegaTime = vegaTime.Add(time.Second)
   893  		amount += 100
   894  	}
   895  
   896  	return lps
   897  }
   898  
   899  func TestLiquidityProvision_ListProviders(t *testing.T) {
   900  	t.Run("ListLiquidityProviders should return all liquidity provider data for active liquidity provisions given a liquidity provider party id", testListLiquidityProviderValidPartyID)
   901  	t.Run("ListLiquidityProviders should return an empty list if the party id does not exist", testListLiquidityProviderInvalidPartyID)
   902  	t.Run("ListLiquidityProviders should return all active liquidity providers for a market if it exists", testListLiquidityProviderValidMarketID)
   903  	t.Run("ListLiquidityProviders should return a empty list if the market does not exist", testListLiquidityProviderInvalidMarketID)
   904  	t.Run("ListLiquidityProviders should return the liquidity providers information for a given market and liquidity provider party id", testListLiquidityProviderValidMarketIDValidPartyID)
   905  	t.Run("ListLiquidityProviders should return an error if the market id and party id is not provided", testListLiquidityProviderNoMarketIDNoPartyID)
   906  }
   907  
   908  func testListLiquidityProviderValidPartyID(t *testing.T) {
   909  	ctx := tempTransaction(t)
   910  
   911  	bs, lpStore, _ := setupLPTests(t)
   912  	mds := sqlstore.NewMarketData(connectionSource)
   913  
   914  	providers := addLiquidityProvisionsMultiProvider(ctx, t, bs, lpStore, mds)
   915  
   916  	lps, pageInfo, err := lpStore.ListProviders(ctx, ptr.From(entities.PartyID("deadbaad")), nil, entities.CursorPagination{})
   917  	require.NoError(t, err)
   918  
   919  	want := []entities.LiquidityProvider{
   920  		providers[0],
   921  		providers[2],
   922  	}
   923  
   924  	assert.Equal(t, want, lps)
   925  	assert.Equal(t, entities.PageInfo{
   926  		StartCursor:     want[0].Cursor().Encode(),
   927  		EndCursor:       want[1].Cursor().Encode(),
   928  		HasNextPage:     false,
   929  		HasPreviousPage: false,
   930  	}, pageInfo)
   931  }
   932  
   933  func testListLiquidityProviderInvalidPartyID(t *testing.T) {
   934  	ctx := tempTransaction(t)
   935  
   936  	bs, lpStore, _ := setupLPTests(t)
   937  	mds := sqlstore.NewMarketData(connectionSource)
   938  
   939  	addLiquidityProvisionsMultiProvider(ctx, t, bs, lpStore, mds)
   940  
   941  	lps, pageInfo, err := lpStore.ListProviders(ctx, ptr.From(entities.PartyID("acacacac")), nil, entities.CursorPagination{})
   942  	require.NoError(t, err)
   943  
   944  	var want []entities.LiquidityProvider
   945  
   946  	assert.Len(t, lps, 0)
   947  	assert.Equal(t, want, lps)
   948  	assert.Equal(t, entities.PageInfo{
   949  		StartCursor:     "",
   950  		EndCursor:       "",
   951  		HasNextPage:     false,
   952  		HasPreviousPage: false,
   953  	}, pageInfo)
   954  }
   955  
   956  func testListLiquidityProviderValidMarketID(t *testing.T) {
   957  	ctx := tempTransaction(t)
   958  
   959  	bs, lpStore, _ := setupLPTests(t)
   960  	mds := sqlstore.NewMarketData(connectionSource)
   961  
   962  	providers := addLiquidityProvisionsMultiProvider(ctx, t, bs, lpStore, mds)
   963  
   964  	lps, pageInfo, err := lpStore.ListProviders(ctx, nil, ptr.From(entities.MarketID("cafed00d")), entities.CursorPagination{})
   965  	require.NoError(t, err)
   966  	want := providers[:2]
   967  
   968  	assert.Equal(t, want, lps)
   969  	assert.Equal(t, entities.PageInfo{
   970  		StartCursor:     want[0].Cursor().Encode(),
   971  		EndCursor:       want[1].Cursor().Encode(),
   972  		HasNextPage:     false,
   973  		HasPreviousPage: false,
   974  	}, pageInfo)
   975  }
   976  
   977  func testListLiquidityProviderInvalidMarketID(t *testing.T) {
   978  	ctx := tempTransaction(t)
   979  
   980  	bs, lpStore, _ := setupLPTests(t)
   981  	mds := sqlstore.NewMarketData(connectionSource)
   982  
   983  	addLiquidityProvisionsMultiProvider(ctx, t, bs, lpStore, mds)
   984  
   985  	lps, pageInfo, err := lpStore.ListProviders(ctx, nil, ptr.From(entities.MarketID("deaddaad")), entities.CursorPagination{})
   986  	require.NoError(t, err)
   987  
   988  	var want []entities.LiquidityProvider
   989  
   990  	assert.Len(t, lps, 0)
   991  	assert.Equal(t, want, lps)
   992  	assert.Equal(t, entities.PageInfo{
   993  		StartCursor:     "",
   994  		EndCursor:       "",
   995  		HasNextPage:     false,
   996  		HasPreviousPage: false,
   997  	}, pageInfo)
   998  }
   999  
  1000  func testListLiquidityProviderValidMarketIDValidPartyID(t *testing.T) {
  1001  	ctx := tempTransaction(t)
  1002  
  1003  	bs, lpStore, _ := setupLPTests(t)
  1004  	mds := sqlstore.NewMarketData(connectionSource)
  1005  
  1006  	providers := addLiquidityProvisionsMultiProvider(ctx, t, bs, lpStore, mds)
  1007  
  1008  	lps, pageInfo, err := lpStore.ListProviders(ctx, ptr.From(entities.PartyID("deadbaad")),
  1009  		ptr.From(entities.MarketID("cafed00d")), entities.CursorPagination{})
  1010  	require.NoError(t, err)
  1011  
  1012  	want := []entities.LiquidityProvider{providers[0]}
  1013  
  1014  	assert.Len(t, lps, 1)
  1015  	assert.Equal(t, want, lps)
  1016  	assert.Equal(t, entities.PageInfo{
  1017  		StartCursor:     want[0].Cursor().Encode(),
  1018  		EndCursor:       want[0].Cursor().Encode(),
  1019  		HasNextPage:     false,
  1020  		HasPreviousPage: false,
  1021  	}, pageInfo)
  1022  }
  1023  
  1024  func testListLiquidityProviderNoMarketIDNoPartyID(t *testing.T) {
  1025  	ctx := tempTransaction(t)
  1026  
  1027  	bs, lpStore, _ := setupLPTests(t)
  1028  	mds := sqlstore.NewMarketData(connectionSource)
  1029  
  1030  	addLiquidityProvisionsMultiProvider(ctx, t, bs, lpStore, mds)
  1031  
  1032  	_, _, err := lpStore.ListProviders(ctx, nil, nil, entities.CursorPagination{})
  1033  	require.Error(t, err)
  1034  }
  1035  
  1036  func addLiquidityProvisionsMultiProvider(ctx context.Context, t *testing.T, bs *sqlstore.Blocks,
  1037  	lpstore *sqlstore.LiquidityProvision, mds *sqlstore.MarketData,
  1038  ) []entities.LiquidityProvider {
  1039  	t.Helper()
  1040  	vegaTime := time.Now().Truncate(time.Microsecond)
  1041  	amount := int64(1000)
  1042  
  1043  	setupProviders := []struct {
  1044  		PartyID string
  1045  		Status  vega.LiquidityProvision_Status
  1046  	}{
  1047  		{
  1048  			PartyID: "deadbaad",
  1049  			Status:  vega.LiquidityProvision_STATUS_ACTIVE,
  1050  		},
  1051  		{
  1052  			PartyID: "deadd00d",
  1053  			Status:  vega.LiquidityProvision_STATUS_ACTIVE,
  1054  		},
  1055  		{
  1056  			PartyID: "deadbeef",
  1057  			Status:  vega.LiquidityProvision_STATUS_STOPPED,
  1058  		},
  1059  	}
  1060  
  1061  	activeProviders := make([]entities.LiquidityProvider, 0)
  1062  	marketData := []entities.MarketData{
  1063  		{
  1064  			MarketTradingMode:          "TRADING_MODE_CONTINUOUS",
  1065  			MarketState:                "STATE_ACTIVE",
  1066  			AuctionTrigger:             "AUCTION_TRIGGER_UNSPECIFIED",
  1067  			ExtensionTrigger:           "AUCTION_TRIGGER_UNSPECIFIED",
  1068  			LiquidityProviderFeeShares: []*vega.LiquidityProviderFeeShare{},
  1069  			TxHash:                     generateTxHash(),
  1070  			SeqNum:                     0,
  1071  			Market:                     entities.MarketID("cafed00d"),
  1072  			MarkPriceType:              "COMPOSITE_PRICE_TYPE_LAST_TRADE",
  1073  		},
  1074  		{
  1075  			MarketTradingMode:          "TRADING_MODE_CONTINUOUS",
  1076  			MarketState:                "STATE_ACTIVE",
  1077  			AuctionTrigger:             "AUCTION_TRIGGER_UNSPECIFIED",
  1078  			ExtensionTrigger:           "AUCTION_TRIGGER_UNSPECIFIED",
  1079  			LiquidityProviderFeeShares: []*vega.LiquidityProviderFeeShare{},
  1080  			TxHash:                     generateTxHash(),
  1081  			SeqNum:                     0,
  1082  			Market:                     entities.MarketID("cafedaad"),
  1083  			MarkPriceType:              "COMPOSITE_PRICE_TYPE_LAST_TRADE",
  1084  		},
  1085  	}
  1086  
  1087  	for _, md := range marketData {
  1088  		var ordinality int64
  1089  		for i, provider := range setupProviders {
  1090  			addTestBlockForTime(t, ctx, bs, vegaTime)
  1091  
  1092  			lp := &vega.LiquidityProvision{
  1093  				Id:               GenerateID(),
  1094  				PartyId:          provider.PartyID,
  1095  				CreatedAt:        vegaTime.UnixNano(),
  1096  				UpdatedAt:        vegaTime.UnixNano(),
  1097  				MarketId:         md.Market.String(),
  1098  				CommitmentAmount: "100000",
  1099  				Fee:              "0.3",
  1100  				Sells:            nil,
  1101  				Buys:             nil,
  1102  				Version:          0,
  1103  				Status:           provider.Status,
  1104  				Reference:        fmt.Sprintf("TEST1%s%00d", provider.PartyID, i),
  1105  			}
  1106  
  1107  			withdrawal, err := entities.LiquidityProvisionFromProto(lp, generateTxHash(), vegaTime)
  1108  			require.NoError(t, err, "Converting withdrawal proto to database entity")
  1109  			err = lpstore.Upsert(ctx, withdrawal)
  1110  			require.NoError(t, err)
  1111  			err = lpstore.Flush(ctx)
  1112  			require.NoError(t, err)
  1113  
  1114  			md.SeqNum = uint64(i)
  1115  			md.LiquidityProviderFeeShares = append(md.LiquidityProviderFeeShares, &vega.LiquidityProviderFeeShare{
  1116  				Party:                 provider.PartyID,
  1117  				EquityLikeShare:       "0",
  1118  				AverageEntryValuation: "0",
  1119  				AverageScore:          "0",
  1120  				VirtualStake:          "0",
  1121  			})
  1122  			md.LiquidityProviderSLA = append(md.LiquidityProviderSLA, &vega.LiquidityProviderSLA{
  1123  				Party:                            provider.PartyID,
  1124  				CurrentEpochFractionOfTimeOnBook: "0.5",
  1125  				LastEpochFractionOfTimeOnBook:    "1",
  1126  				LastEpochFeePenalty:              "0",
  1127  				LastEpochBondPenalty:             "0",
  1128  				HysteresisPeriodFeePenalties:     []string{"0"},
  1129  				RequiredLiquidity:                "1000",
  1130  				NotionalVolumeBuys:               "1010",
  1131  				NotionalVolumeSells:              "1005",
  1132  			})
  1133  			md.SyntheticTime = vegaTime
  1134  			md.VegaTime = vegaTime
  1135  
  1136  			err = mds.Add(&md)
  1137  			require.NoError(t, err)
  1138  
  1139  			_, err = mds.Flush(ctx)
  1140  			require.NoError(t, err)
  1141  
  1142  			vegaTime = vegaTime.Add(time.Second)
  1143  			amount += 100
  1144  
  1145  			if provider.Status == vega.LiquidityProvision_STATUS_ACTIVE {
  1146  				ordinality += 1
  1147  				activeProviders = append(activeProviders, entities.LiquidityProvider{
  1148  					PartyID:    entities.PartyID(provider.PartyID),
  1149  					MarketID:   md.Market,
  1150  					Ordinality: ordinality,
  1151  					FeeShare: &vega.LiquidityProviderFeeShare{
  1152  						Party:                 provider.PartyID,
  1153  						EquityLikeShare:       "0",
  1154  						AverageEntryValuation: "0",
  1155  						AverageScore:          "0",
  1156  						VirtualStake:          "0",
  1157  					},
  1158  					SLA: &vega.LiquidityProviderSLA{
  1159  						Party:                            provider.PartyID,
  1160  						CurrentEpochFractionOfTimeOnBook: "0.5",
  1161  						LastEpochFractionOfTimeOnBook:    "1",
  1162  						LastEpochFeePenalty:              "0",
  1163  						LastEpochBondPenalty:             "0",
  1164  						HysteresisPeriodFeePenalties:     []string{"0"},
  1165  						RequiredLiquidity:                "1000",
  1166  						NotionalVolumeBuys:               "1010",
  1167  						NotionalVolumeSells:              "1005",
  1168  					},
  1169  				})
  1170  			}
  1171  		}
  1172  	}
  1173  
  1174  	return activeProviders
  1175  }
  1176  
  1177  func TestLiquidityProvision_Status(t *testing.T) {
  1178  	var liquidityProvisionStatus vega.LiquidityProvision_Status
  1179  
  1180  	states := getEnums(t, liquidityProvisionStatus)
  1181  	assert.Len(t, states, 7)
  1182  	for s, state := range states {
  1183  		t.Run(state, func(t *testing.T) {
  1184  			ctx := tempTransaction(t)
  1185  			bs, lpStore, _ := setupLPTests(t)
  1186  			block := addTestBlock(t, ctx, bs)
  1187  			lpProto := getTestLiquidityProvision(false)
  1188  			lp := lpProto[0]
  1189  			lp.Status = vega.LiquidityProvision_Status(s)
  1190  
  1191  			txHash := generateTxHash()
  1192  
  1193  			want, err := entities.LiquidityProvisionFromProto(lp, txHash, block.VegaTime)
  1194  			require.NoError(t, err)
  1195  			assert.NoError(t, lpStore.Upsert(ctx, want))
  1196  			require.NoError(t, lpStore.Flush(ctx))
  1197  
  1198  			got, err := lpStore.GetByTxHash(ctx, txHash)
  1199  			require.NoError(t, err)
  1200  			require.Len(t, got, 1)
  1201  			assert.Equal(t, want, got[0])
  1202  		})
  1203  	}
  1204  }