code.vegaprotocol.io/vega@v0.79.0/datanode/sqlstore/margin_level_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  	"testing"
    21  	"time"
    22  
    23  	"code.vegaprotocol.io/vega/datanode/entities"
    24  	"code.vegaprotocol.io/vega/datanode/sqlstore"
    25  	"code.vegaprotocol.io/vega/protos/vega"
    26  
    27  	"github.com/shopspring/decimal"
    28  	"github.com/stretchr/testify/assert"
    29  	"github.com/stretchr/testify/require"
    30  )
    31  
    32  const testAssetID = "deadbeef"
    33  
    34  func TestMarginLevels(t *testing.T) {
    35  	t.Run("Add should insert margin levels that don't exist in the current block", testInsertMarginLevels)
    36  	t.Run("Add should insert margin levels that already exist in the same block", testDuplicateMarginLevelInSameBlock)
    37  	t.Run("GetMarginLevelsByID should return the latest state of margin levels for all markets if only party ID is provided", testGetMarginLevelsByPartyID)
    38  	t.Run("GetMarginLevelsByID should return the latest state of margin levels for all parties if only market ID is provided", testGetMarginLevelsByMarketID)
    39  	t.Run("GetMarginLevelsByID should return the latest state of margin levels for the given party/market ID", testGetMarginLevelsByID)
    40  	t.Run("GetByTxHash", testGetMarginByTxHash)
    41  
    42  	t.Run("GetMarginLevelsByIDWithCursorPagination should return all margin levels for a given party if no pagination is provided", testGetMarginLevelsByIDPaginationWithPartyNoCursor)
    43  	t.Run("GetMarginLevelsByIDWithCursorPagination should return all margin levels for a given market if no pagination is provided", testGetMarginLevelsByIDPaginationWithMarketNoCursor)
    44  	t.Run("GetMarginLevelsByIDWithCursorPagination should return the first page of margin levels for a given party if first is set with no after cursor", testGetMarginLevelsByIDPaginationWithPartyFirstNoAfterCursor)
    45  	t.Run("GetMarginLevelsByIDWithCursorPagination should return the first page of margin levels for a given market if first is set with no after cursor", testGetMarginLevelsByIDPaginationWithMarketFirstNoAfterCursor)
    46  	t.Run("GetMarginLevelsByIDWithCursorPagination should return the last page of margin levels for a given party if last is set with no before cursor", testGetMarginLevelsByIDPaginationWithPartyLastNoBeforeCursor)
    47  	t.Run("GetMarginLevelsByIDWithCursorPagination should return the last page of margin levels for a given market if last is set with no before cursor", testGetMarginLevelsByIDPaginationWithMarketLastNoBeforeCursor)
    48  	t.Run("GetMarginLevelsByIDWithCursorPagination should return the requested page of margin levels for a given party if first is set with after cursor", testGetMarginLevelsByIDPaginationWithPartyFirstAndAfterCursor)
    49  	t.Run("GetMarginLevelsByIDWithCursorPagination should return the requested page of margin levels for a given market if first is set with after cursor", testGetMarginLevelsByIDPaginationWithMarketFirstAndAfterCursor)
    50  	t.Run("GetMarginLevelsByIDWithCursorPagination should return the requested page of margin levels for a given party if last is set with before cursor", testGetMarginLevelsByIDPaginationWithPartyLastAndBeforeCursor)
    51  	t.Run("GetMarginLevelsByIDWithCursorPagination should return the requested page of margin levels for a given market if last is set with before cursor", testGetMarginLevelsByIDPaginationWithMarketLastAndBeforeCursor)
    52  
    53  	t.Run("GetMarginLevelsByIDWithCursorPagination should return all margin levels for a given party if no pagination is provided - Newest First", testGetMarginLevelsByIDPaginationWithPartyNoCursorNewestFirst)
    54  	t.Run("GetMarginLevelsByIDWithCursorPagination should return all margin levels for a given market if no pagination is provided - Newest First", testGetMarginLevelsByIDPaginationWithMarketNoCursorNewestFirst)
    55  	t.Run("GetMarginLevelsByIDWithCursorPagination should return the first page of margin levels for a given party if first is set with no after cursor - Newest First", testGetMarginLevelsByIDPaginationWithPartyFirstNoAfterCursorNewestFirst)
    56  	t.Run("GetMarginLevelsByIDWithCursorPagination should return the first page of margin levels for a given market if first is set with no after cursor - Newest First", testGetMarginLevelsByIDPaginationWithMarketFirstNoAfterCursorNewestFirst)
    57  	t.Run("GetMarginLevelsByIDWithCursorPagination should return the last page of margin levels for a given party if last is set with no before cursor - Newest First", testGetMarginLevelsByIDPaginationWithPartyLastNoBeforeCursorNewestFirst)
    58  	t.Run("GetMarginLevelsByIDWithCursorPagination should return the last page of margin levels for a given market if last is set with no before cursor - Newest First", testGetMarginLevelsByIDPaginationWithMarketLastNoBeforeCursorNewestFirst)
    59  	t.Run("GetMarginLevelsByIDWithCursorPagination should return the requested page of margin levels for a given party if first is set with after cursor - Newest First", testGetMarginLevelsByIDPaginationWithPartyFirstAndAfterCursorNewestFirst)
    60  	t.Run("GetMarginLevelsByIDWithCursorPagination should return the requested page of margin levels for a given market if first is set with after cursor - Newest First", testGetMarginLevelsByIDPaginationWithMarketFirstAndAfterCursorNewestFirst)
    61  	t.Run("GetMarginLevelsByIDWithCursorPagination should return the requested page of margin levels for a given party if last is set with before cursor - Newest First", testGetMarginLevelsByIDPaginationWithPartyLastAndBeforeCursorNewestFirst)
    62  	t.Run("GetMarginLevelsByIDWithCursorPagination should return the requested page of margin levels for a given market if last is set with before cursor - Newest First", testGetMarginLevelsByIDPaginationWithMarketLastAndBeforeCursorNewestFirst)
    63  }
    64  
    65  func setupMarginLevelTests(t *testing.T, ctx context.Context) (*testBlockSource, *sqlstore.MarginLevels, *sqlstore.Accounts, sqlstore.Connection) {
    66  	t.Helper()
    67  
    68  	bs := sqlstore.NewBlocks(connectionSource)
    69  	testBlockSource := &testBlockSource{bs, time.Now()}
    70  
    71  	block := testBlockSource.getNextBlock(t, ctx)
    72  
    73  	assets := sqlstore.NewAssets(connectionSource)
    74  
    75  	testAsset := entities.Asset{
    76  		ID:            testAssetID,
    77  		Name:          "testAssetName",
    78  		Symbol:        "tan",
    79  		Decimals:      1,
    80  		Quantum:       decimal.NewFromInt(1),
    81  		Source:        "TS",
    82  		ERC20Contract: "ET",
    83  		VegaTime:      block.VegaTime,
    84  	}
    85  
    86  	err := assets.Add(ctx, testAsset)
    87  	if err != nil {
    88  		t.Fatalf("failed to add test asset:%s", err)
    89  	}
    90  
    91  	accountStore := sqlstore.NewAccounts(connectionSource)
    92  	ml := sqlstore.NewMarginLevels(connectionSource)
    93  
    94  	return testBlockSource, ml, accountStore, connectionSource
    95  }
    96  
    97  func testInsertMarginLevels(t *testing.T) {
    98  	ctx := tempTransaction(t)
    99  
   100  	blockSource, ml, accountStore, conn := setupMarginLevelTests(t, ctx)
   101  	block := blockSource.getNextBlock(t, ctx)
   102  
   103  	var rowCount int
   104  	err := conn.QueryRow(ctx, `select count(*) from margin_levels`).Scan(&rowCount)
   105  	assert.NoError(t, err)
   106  
   107  	marginLevelProto := getMarginLevelProto()
   108  	marginLevel, err := entities.MarginLevelsFromProto(ctx, marginLevelProto, accountStore, generateTxHash(), block.VegaTime)
   109  	require.NoError(t, err, "Converting margin levels proto to database entity")
   110  
   111  	err = ml.Add(marginLevel)
   112  	require.NoError(t, err)
   113  
   114  	err = conn.QueryRow(ctx, `select count(*) from margin_levels`).Scan(&rowCount)
   115  	assert.NoError(t, err)
   116  	assert.Equal(t, 0, rowCount)
   117  
   118  	_, err = ml.Flush(ctx)
   119  	assert.NoError(t, err)
   120  
   121  	err = conn.QueryRow(ctx, `select count(*) from margin_levels`).Scan(&rowCount)
   122  	assert.NoError(t, err)
   123  	assert.Equal(t, 1, rowCount)
   124  }
   125  
   126  func testDuplicateMarginLevelInSameBlock(t *testing.T) {
   127  	ctx := tempTransaction(t)
   128  
   129  	blockSource, ml, accountStore, conn := setupMarginLevelTests(t, ctx)
   130  	block := blockSource.getNextBlock(t, ctx)
   131  
   132  	var rowCount int
   133  	err := conn.QueryRow(ctx, `select count(*) from margin_levels`).Scan(&rowCount)
   134  	assert.NoError(t, err)
   135  
   136  	marginLevelProto := getMarginLevelProto()
   137  	marginLevel, err := entities.MarginLevelsFromProto(ctx, marginLevelProto, accountStore, generateTxHash(), block.VegaTime)
   138  	require.NoError(t, err, "Converting margin levels proto to database entity")
   139  
   140  	err = ml.Add(marginLevel)
   141  	require.NoError(t, err)
   142  
   143  	err = ml.Add(marginLevel)
   144  	require.NoError(t, err)
   145  
   146  	err = conn.QueryRow(ctx, `select count(*) from margin_levels`).Scan(&rowCount)
   147  	assert.NoError(t, err)
   148  	assert.Equal(t, 0, rowCount)
   149  
   150  	_, err = ml.Flush(ctx)
   151  	assert.NoError(t, err)
   152  
   153  	err = conn.QueryRow(ctx, `select count(*) from margin_levels`).Scan(&rowCount)
   154  	assert.NoError(t, err)
   155  	assert.Equal(t, 1, rowCount)
   156  }
   157  
   158  func getMarginLevelProto() *vega.MarginLevels {
   159  	return getMarginLevelWithMaintenanceProto("1000", "deadbeef", "deadbeef", time.Now().UnixNano())
   160  }
   161  
   162  func getMarginLevelWithMaintenanceProto(maintenanceMargin, partyID, marketID string, timestamp int64) *vega.MarginLevels {
   163  	return &vega.MarginLevels{
   164  		MaintenanceMargin:      maintenanceMargin,
   165  		SearchLevel:            "1000",
   166  		InitialMargin:          "1000",
   167  		CollateralReleaseLevel: "1000",
   168  		OrderMargin:            "0",
   169  		PartyId:                partyID,
   170  		MarketId:               marketID,
   171  		Asset:                  testAssetID,
   172  		Timestamp:              timestamp,
   173  		MarginMode:             vega.MarginMode_MARGIN_MODE_CROSS_MARGIN,
   174  		MarginFactor:           "0",
   175  	}
   176  }
   177  
   178  func testGetMarginLevelsByPartyID(t *testing.T) {
   179  	ctx := tempTransaction(t)
   180  
   181  	blockSource, ml, accountStore, conn := setupMarginLevelTests(t, ctx)
   182  	block := blockSource.getNextBlock(t, ctx)
   183  
   184  	var rowCount int
   185  	err := conn.QueryRow(ctx, `select count(*) from margin_levels`).Scan(&rowCount)
   186  	assert.NoError(t, err)
   187  	assert.Equal(t, 0, rowCount)
   188  
   189  	ml1 := getMarginLevelProto()
   190  	ml2 := getMarginLevelProto()
   191  	ml3 := getMarginLevelProto()
   192  	ml4 := getMarginLevelProto()
   193  
   194  	ml2.MarketId = "deadbaad"
   195  
   196  	ml3.Timestamp = ml2.Timestamp + 1000000000
   197  	ml3.MaintenanceMargin = "2000"
   198  	ml3.SearchLevel = "2000"
   199  
   200  	ml4.Timestamp = ml2.Timestamp + 1000000000
   201  	ml4.MaintenanceMargin = "2000"
   202  	ml4.SearchLevel = "2000"
   203  	ml4.MarketId = "deadbaad"
   204  
   205  	marginLevel1, err := entities.MarginLevelsFromProto(ctx, ml1, accountStore, generateTxHash(), block.VegaTime)
   206  	require.NoError(t, err, "Converting margin levels proto to database entity")
   207  
   208  	marginLevel2, err := entities.MarginLevelsFromProto(ctx, ml2, accountStore, generateTxHash(), block.VegaTime)
   209  	require.NoError(t, err, "Converting margin levels proto to database entity")
   210  
   211  	err = ml.Add(marginLevel1)
   212  	require.NoError(t, err)
   213  	err = ml.Add(marginLevel2)
   214  	require.NoError(t, err)
   215  
   216  	_, err = ml.Flush(ctx)
   217  	require.NoError(t, err)
   218  
   219  	err = conn.QueryRow(ctx, `select count(*) from margin_levels`).Scan(&rowCount)
   220  	assert.NoError(t, err)
   221  	assert.Equal(t, 2, rowCount)
   222  
   223  	block = blockSource.getNextBlock(t, ctx)
   224  	marginLevel3, err := entities.MarginLevelsFromProto(ctx, ml3, accountStore, generateTxHash(), block.VegaTime)
   225  	require.NoError(t, err, "Converting margin levels proto to database entity")
   226  
   227  	marginLevel4, err := entities.MarginLevelsFromProto(ctx, ml4, accountStore, generateTxHash(), block.VegaTime)
   228  	require.NoError(t, err, "Converting margin levels proto to database entity")
   229  
   230  	err = ml.Add(marginLevel3)
   231  	require.NoError(t, err)
   232  	err = ml.Add(marginLevel4)
   233  	require.NoError(t, err)
   234  
   235  	_, err = ml.Flush(ctx)
   236  	require.NoError(t, err)
   237  
   238  	err = conn.QueryRow(ctx, `select count(*) from margin_levels`).Scan(&rowCount)
   239  	assert.NoError(t, err)
   240  	assert.Equal(t, 4, rowCount)
   241  
   242  	got, _, err := ml.GetMarginLevelsByIDWithCursorPagination(ctx, "DEADBEEF", "", entities.CursorPagination{})
   243  	assert.NoError(t, err)
   244  	assert.Equal(t, 2, len(got))
   245  
   246  	// We have to truncate the time because Postgres only supports time to microsecond granularity.
   247  	want1 := marginLevel3
   248  	want1.Timestamp = want1.Timestamp.Truncate(time.Microsecond)
   249  	want1.VegaTime = want1.VegaTime.Truncate(time.Microsecond)
   250  
   251  	want2 := marginLevel4
   252  	want2.Timestamp = want2.Timestamp.Truncate(time.Microsecond)
   253  	want2.VegaTime = want2.VegaTime.Truncate(time.Microsecond)
   254  
   255  	want := []entities.MarginLevels{want1, want2}
   256  
   257  	assert.ElementsMatch(t, want, got)
   258  }
   259  
   260  func testGetMarginLevelsByMarketID(t *testing.T) {
   261  	ctx := tempTransaction(t)
   262  
   263  	blockSource, ml, accountStore, conn := setupMarginLevelTests(t, ctx)
   264  	block := blockSource.getNextBlock(t, ctx)
   265  
   266  	var rowCount int
   267  	err := conn.QueryRow(ctx, `select count(*) from margin_levels`).Scan(&rowCount)
   268  	assert.NoError(t, err)
   269  	assert.Equal(t, 0, rowCount)
   270  
   271  	ml1 := getMarginLevelProto()
   272  	ml2 := getMarginLevelProto()
   273  	ml3 := getMarginLevelProto()
   274  	ml4 := getMarginLevelProto()
   275  
   276  	ml2.PartyId = "deadbaad"
   277  
   278  	ml3.Timestamp = ml2.Timestamp + 1000000000
   279  	ml3.MaintenanceMargin = "2000"
   280  	ml3.SearchLevel = "2000"
   281  
   282  	ml4.Timestamp = ml2.Timestamp + 1000000000
   283  	ml4.MaintenanceMargin = "2000"
   284  	ml4.SearchLevel = "2000"
   285  	ml4.PartyId = "deadbaad"
   286  
   287  	marginLevel1, err := entities.MarginLevelsFromProto(ctx, ml1, accountStore, generateTxHash(), block.VegaTime)
   288  	require.NoError(t, err, "Converting margin levels proto to database entity")
   289  
   290  	marginLevel2, err := entities.MarginLevelsFromProto(ctx, ml2, accountStore, generateTxHash(), block.VegaTime)
   291  	require.NoError(t, err, "Converting margin levels proto to database entity")
   292  
   293  	err = ml.Add(marginLevel1)
   294  	require.NoError(t, err)
   295  	err = ml.Add(marginLevel2)
   296  	require.NoError(t, err)
   297  
   298  	_, err = ml.Flush(ctx)
   299  	assert.NoError(t, err)
   300  
   301  	err = conn.QueryRow(ctx, `select count(*) from margin_levels`).Scan(&rowCount)
   302  	assert.NoError(t, err)
   303  	assert.Equal(t, 2, rowCount)
   304  
   305  	block = blockSource.getNextBlock(t, ctx)
   306  	marginLevel3, err := entities.MarginLevelsFromProto(ctx, ml3, accountStore, generateTxHash(), block.VegaTime)
   307  	require.NoError(t, err, "Converting margin levels proto to database entity")
   308  
   309  	marginLevel4, err := entities.MarginLevelsFromProto(ctx, ml4, accountStore, generateTxHash(), block.VegaTime)
   310  	require.NoError(t, err, "Converting margin levels proto to database entity")
   311  
   312  	err = ml.Add(marginLevel3)
   313  	require.NoError(t, err)
   314  	err = ml.Add(marginLevel4)
   315  	require.NoError(t, err)
   316  
   317  	_, err = ml.Flush(ctx)
   318  	assert.NoError(t, err)
   319  
   320  	err = conn.QueryRow(ctx, `select count(*) from margin_levels`).Scan(&rowCount)
   321  	assert.NoError(t, err)
   322  	assert.Equal(t, 4, rowCount)
   323  
   324  	got, _, err := ml.GetMarginLevelsByIDWithCursorPagination(ctx, "", "DEADBEEF", entities.CursorPagination{})
   325  	assert.NoError(t, err)
   326  	assert.Equal(t, 2, len(got))
   327  
   328  	// We have to truncate the time because Postgres only supports time to microsecond granularity.
   329  	want1 := marginLevel3
   330  	want1.Timestamp = want1.Timestamp.Truncate(time.Microsecond)
   331  	want1.VegaTime = want1.VegaTime.Truncate(time.Microsecond)
   332  
   333  	want2 := marginLevel4
   334  	want2.Timestamp = want2.Timestamp.Truncate(time.Microsecond)
   335  	want2.VegaTime = want2.VegaTime.Truncate(time.Microsecond)
   336  
   337  	want := []entities.MarginLevels{want1, want2}
   338  
   339  	assert.ElementsMatch(t, want, got)
   340  }
   341  
   342  func testGetMarginLevelsByID(t *testing.T) {
   343  	ctx := tempTransaction(t)
   344  
   345  	blockSource, ml, accountStore, conn := setupMarginLevelTests(t, ctx)
   346  	block := blockSource.getNextBlock(t, ctx)
   347  
   348  	var rowCount int
   349  	err := conn.QueryRow(ctx, `select count(*) from margin_levels`).Scan(&rowCount)
   350  	assert.NoError(t, err)
   351  	assert.Equal(t, 0, rowCount)
   352  
   353  	ml1 := getMarginLevelProto()
   354  	ml2 := getMarginLevelProto()
   355  	ml3 := getMarginLevelProto()
   356  	ml4 := getMarginLevelProto()
   357  
   358  	ml2.PartyId = "DEADBAAD"
   359  
   360  	ml3.Timestamp = ml2.Timestamp + 1000000000
   361  	ml3.MaintenanceMargin = "2000"
   362  	ml3.SearchLevel = "2000"
   363  
   364  	ml4.Timestamp = ml2.Timestamp + 1000000000
   365  	ml4.MaintenanceMargin = "2000"
   366  	ml4.SearchLevel = "2000"
   367  	ml4.PartyId = "DEADBAAD"
   368  
   369  	marginLevel1, err := entities.MarginLevelsFromProto(ctx, ml1, accountStore, generateTxHash(), block.VegaTime)
   370  	require.NoError(t, err, "Converting margin levels proto to database entity")
   371  
   372  	marginLevel2, err := entities.MarginLevelsFromProto(ctx, ml2, accountStore, generateTxHash(), block.VegaTime)
   373  	require.NoError(t, err, "Converting margin levels proto to database entity")
   374  
   375  	err = ml.Add(marginLevel1)
   376  	require.NoError(t, err)
   377  	err = ml.Add(marginLevel2)
   378  	require.NoError(t, err)
   379  
   380  	_, err = ml.Flush(ctx)
   381  	assert.NoError(t, err)
   382  
   383  	err = conn.QueryRow(ctx, `select count(*) from margin_levels`).Scan(&rowCount)
   384  	assert.NoError(t, err)
   385  	assert.Equal(t, 2, rowCount)
   386  
   387  	block = blockSource.getNextBlock(t, ctx)
   388  	marginLevel3, err := entities.MarginLevelsFromProto(ctx, ml3, accountStore, generateTxHash(), block.VegaTime)
   389  	require.NoError(t, err, "Converting margin levels proto to database entity")
   390  
   391  	marginLevel4, err := entities.MarginLevelsFromProto(ctx, ml4, accountStore, generateTxHash(), block.VegaTime)
   392  	require.NoError(t, err, "Converting margin levels proto to database entity")
   393  
   394  	err = ml.Add(marginLevel3)
   395  	require.NoError(t, err)
   396  	err = ml.Add(marginLevel4)
   397  	require.NoError(t, err)
   398  
   399  	_, err = ml.Flush(ctx)
   400  	assert.NoError(t, err)
   401  
   402  	err = conn.QueryRow(ctx, `select count(*) from margin_levels`).Scan(&rowCount)
   403  	assert.NoError(t, err)
   404  	assert.Equal(t, 4, rowCount)
   405  
   406  	got, _, err := ml.GetMarginLevelsByIDWithCursorPagination(ctx, "DEADBEEF", "DEADBEEF", entities.CursorPagination{})
   407  	assert.NoError(t, err)
   408  	assert.Equal(t, 1, len(got))
   409  
   410  	// We have to truncate the time because Postgres only supports time to microsecond granularity.
   411  	want1 := marginLevel3
   412  	want1.Timestamp = want1.Timestamp.Truncate(time.Microsecond)
   413  	want1.VegaTime = want1.VegaTime.Truncate(time.Microsecond)
   414  
   415  	want := []entities.MarginLevels{want1}
   416  
   417  	assert.ElementsMatch(t, want, got)
   418  }
   419  
   420  func testGetMarginByTxHash(t *testing.T) {
   421  	ctx := tempTransaction(t)
   422  
   423  	blockSource, ml, accountStore, conn := setupMarginLevelTests(t, ctx)
   424  	block := blockSource.getNextBlock(t, ctx)
   425  
   426  	var rowCount int
   427  	err := conn.QueryRow(ctx, `select count(*) from margin_levels`).Scan(&rowCount)
   428  	assert.NoError(t, err)
   429  	assert.Equal(t, 0, rowCount)
   430  
   431  	ml1 := getMarginLevelProto()
   432  	ml2 := getMarginLevelProto()
   433  	ml2.PartyId = "DEADBAAD"
   434  
   435  	marginLevel1, err := entities.MarginLevelsFromProto(ctx, ml1, accountStore, generateTxHash(), block.VegaTime)
   436  	require.NoError(t, err, "Converting margin levels proto to database entity")
   437  
   438  	marginLevel2, err := entities.MarginLevelsFromProto(ctx, ml2, accountStore, generateTxHash(), block.VegaTime)
   439  	require.NoError(t, err, "Converting margin levels proto to database entity")
   440  
   441  	err = ml.Add(marginLevel1)
   442  	require.NoError(t, err)
   443  	err = ml.Add(marginLevel2)
   444  	require.NoError(t, err)
   445  
   446  	_, err = ml.Flush(ctx)
   447  	assert.NoError(t, err)
   448  
   449  	err = conn.QueryRow(ctx, `select count(*) from margin_levels`).Scan(&rowCount)
   450  	assert.NoError(t, err)
   451  	assert.Equal(t, 2, rowCount)
   452  
   453  	got, err := ml.GetByTxHash(ctx, marginLevel1.TxHash)
   454  	assert.NoError(t, err)
   455  	assert.Equal(t, 1, len(got))
   456  
   457  	// We have to truncate the time because Postgres only supports time to microsecond granularity.
   458  	want1 := marginLevel1
   459  	want1.Timestamp = want1.Timestamp.Truncate(time.Microsecond)
   460  	want1.VegaTime = want1.VegaTime.Truncate(time.Microsecond)
   461  
   462  	want := []entities.MarginLevels{want1}
   463  	assert.ElementsMatch(t, want, got)
   464  
   465  	got2, err := ml.GetByTxHash(ctx, marginLevel2.TxHash)
   466  	assert.NoError(t, err)
   467  	assert.Equal(t, 1, len(got2))
   468  
   469  	// We have to truncate the time because Postgres only supports time to microsecond granularity.
   470  	want2 := marginLevel2
   471  	want2.Timestamp = want2.Timestamp.Truncate(time.Microsecond)
   472  	want2.VegaTime = want2.VegaTime.Truncate(time.Microsecond)
   473  
   474  	want = []entities.MarginLevels{want2}
   475  	assert.ElementsMatch(t, want, got2)
   476  }
   477  
   478  func populateMarginLevelPaginationTestData(t *testing.T, ctx context.Context) (*sqlstore.MarginLevels, map[int]entities.Block, map[int]entities.MarginLevels) {
   479  	t.Helper()
   480  
   481  	blockSource, mlStore, accountStore, _ := setupMarginLevelTests(t, ctx)
   482  
   483  	margins := []struct {
   484  		maintenanceMargin string
   485  		partyID           string
   486  		marketID          string
   487  	}{
   488  		{
   489  			// 0
   490  			maintenanceMargin: "1000",
   491  			partyID:           "DEADBEEF",
   492  			marketID:          "DEADBAAD",
   493  		},
   494  		{
   495  			// 1
   496  			maintenanceMargin: "1001",
   497  			partyID:           "DEADBEEF",
   498  			marketID:          "0FF1CE",
   499  		},
   500  		{
   501  			// 2
   502  			maintenanceMargin: "1002",
   503  			partyID:           "DEADBAAD",
   504  			marketID:          "DEADBEEF",
   505  		},
   506  		{
   507  			// 3
   508  			maintenanceMargin: "1003",
   509  			partyID:           "DEADBAAD",
   510  			marketID:          "DEADBAAD",
   511  		},
   512  		{
   513  			// 4
   514  			maintenanceMargin: "1004",
   515  			partyID:           "DEADBEEF",
   516  			marketID:          "DEADC0DE",
   517  		},
   518  		{
   519  			// 5
   520  			maintenanceMargin: "1005",
   521  			partyID:           "0FF1CE",
   522  			marketID:          "DEADBEEF",
   523  		},
   524  		{
   525  			// 6
   526  			maintenanceMargin: "1006",
   527  			partyID:           "DEADC0DE",
   528  			marketID:          "DEADBEEF",
   529  		},
   530  		{
   531  			// 7
   532  			maintenanceMargin: "1007",
   533  			partyID:           "DEADBEEF",
   534  			marketID:          "CAFED00D",
   535  		},
   536  		{
   537  			// 8
   538  			maintenanceMargin: "1008",
   539  			partyID:           "CAFED00D",
   540  			marketID:          "DEADBEEF",
   541  		},
   542  		{
   543  			// 9
   544  			maintenanceMargin: "1009",
   545  			partyID:           "DEADBAAD",
   546  			marketID:          "DEADBAAD",
   547  		},
   548  		{
   549  			// 10
   550  			maintenanceMargin: "1010",
   551  			partyID:           "DEADBEEF",
   552  			marketID:          "CAFEB0BA",
   553  		},
   554  		{
   555  			// 11
   556  			maintenanceMargin: "1011",
   557  			partyID:           "CAFEB0BA",
   558  			marketID:          "DEADBEEF",
   559  		},
   560  		{
   561  			// 12
   562  			maintenanceMargin: "1012",
   563  			partyID:           "DEADBAAD",
   564  			marketID:          "DEADBAAD",
   565  		},
   566  		{
   567  			// 13
   568  			maintenanceMargin: "1013",
   569  			partyID:           "0D15EA5E",
   570  			marketID:          "DEADBEEF",
   571  		},
   572  		{
   573  			// 14
   574  			maintenanceMargin: "1014",
   575  			partyID:           "DEADBEEF",
   576  			marketID:          "0D15EA5E",
   577  		},
   578  	}
   579  
   580  	blocks := make(map[int]entities.Block)
   581  	marginLevels := make(map[int]entities.MarginLevels)
   582  
   583  	for i, ml := range margins {
   584  		block := blockSource.getNextBlock(t, ctx)
   585  		mlProto := getMarginLevelWithMaintenanceProto(ml.maintenanceMargin, ml.partyID, ml.marketID, block.VegaTime.UnixNano())
   586  		mlEntity, err := entities.MarginLevelsFromProto(ctx, mlProto, accountStore, generateTxHash(), block.VegaTime)
   587  		require.NoError(t, err, "Converting margin levels proto to database entity")
   588  		err = mlStore.Add(mlEntity)
   589  		require.NoError(t, err)
   590  
   591  		blocks[i] = block
   592  		marginLevels[i] = mlEntity
   593  	}
   594  
   595  	_, err := mlStore.Flush(ctx)
   596  	require.NoError(t, err)
   597  
   598  	return mlStore, blocks, marginLevels
   599  }
   600  
   601  func testGetMarginLevelsByIDPaginationWithPartyNoCursor(t *testing.T) {
   602  	ctx := tempTransaction(t)
   603  
   604  	t.Logf("DB Port: %d", testDBPort)
   605  	mls, blocks, marginLevels := populateMarginLevelPaginationTestData(t, ctx)
   606  	pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, false)
   607  	require.NoError(t, err)
   608  	got, pageInfo, err := mls.GetMarginLevelsByIDWithCursorPagination(ctx, "DEADBEEF", "", pagination)
   609  	require.NoError(t, err)
   610  	assert.Len(t, got, 6)
   611  	wantMarginLevels := []entities.MarginLevels{
   612  		marginLevels[0],
   613  		marginLevels[1],
   614  		marginLevels[4],
   615  		marginLevels[7],
   616  		marginLevels[10],
   617  		marginLevels[14],
   618  	}
   619  	assert.Equal(t, wantMarginLevels, got)
   620  	assert.False(t, pageInfo.HasNextPage)
   621  	assert.False(t, pageInfo.HasPreviousPage)
   622  	wantStartCursor := entities.MarginCursor{
   623  		VegaTime:  blocks[0].VegaTime,
   624  		AccountID: marginLevels[0].AccountID,
   625  	}
   626  	wantEndCursor := entities.MarginCursor{
   627  		VegaTime:  blocks[14].VegaTime,
   628  		AccountID: marginLevels[14].AccountID,
   629  	}
   630  	assert.Equal(t, entities.PageInfo{
   631  		HasNextPage:     false,
   632  		HasPreviousPage: false,
   633  		StartCursor:     entities.NewCursor(wantStartCursor.String()).Encode(),
   634  		EndCursor:       entities.NewCursor(wantEndCursor.String()).Encode(),
   635  	}, pageInfo)
   636  }
   637  
   638  func testGetMarginLevelsByIDPaginationWithPartyNoCursorNewestFirst(t *testing.T) {
   639  	ctx := tempTransaction(t)
   640  
   641  	t.Logf("DB Port: %d", testDBPort)
   642  	mls, blocks, marginLevels := populateMarginLevelPaginationTestData(t, ctx)
   643  	pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, true)
   644  	require.NoError(t, err)
   645  	got, pageInfo, err := mls.GetMarginLevelsByIDWithCursorPagination(ctx, "DEADBEEF", "", pagination)
   646  	require.NoError(t, err)
   647  	assert.Len(t, got, 6)
   648  	wantMarginLevels := []entities.MarginLevels{
   649  		marginLevels[14],
   650  		marginLevels[10],
   651  		marginLevels[7],
   652  		marginLevels[4],
   653  		marginLevels[1],
   654  		marginLevels[0],
   655  	}
   656  	assert.Equal(t, wantMarginLevels, got)
   657  	wantStartCursor := entities.MarginCursor{
   658  		VegaTime:  blocks[14].VegaTime,
   659  		AccountID: marginLevels[14].AccountID,
   660  	}
   661  	wantEndCursor := entities.MarginCursor{
   662  		VegaTime:  blocks[0].VegaTime,
   663  		AccountID: marginLevels[0].AccountID,
   664  	}
   665  	assert.Equal(t, entities.PageInfo{
   666  		HasNextPage:     false,
   667  		HasPreviousPage: false,
   668  		StartCursor:     entities.NewCursor(wantStartCursor.String()).Encode(),
   669  		EndCursor:       entities.NewCursor(wantEndCursor.String()).Encode(),
   670  	}, pageInfo)
   671  }
   672  
   673  func testGetMarginLevelsByIDPaginationWithMarketNoCursor(t *testing.T) {
   674  	ctx := tempTransaction(t)
   675  
   676  	t.Logf("DB Port: %d", testDBPort)
   677  	mls, blocks, marginLevels := populateMarginLevelPaginationTestData(t, ctx)
   678  	pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, false)
   679  	require.NoError(t, err)
   680  	got, pageInfo, err := mls.GetMarginLevelsByIDWithCursorPagination(ctx, "", "DEADBEEF", pagination)
   681  	require.NoError(t, err)
   682  	assert.Len(t, got, 6)
   683  	wantMarginLevels := []entities.MarginLevels{
   684  		marginLevels[2],
   685  		marginLevels[5],
   686  		marginLevels[6],
   687  		marginLevels[8],
   688  		marginLevels[11],
   689  		marginLevels[13],
   690  	}
   691  	assert.Equal(t, wantMarginLevels, got)
   692  	wantStartCursor := entities.MarginCursor{
   693  		VegaTime:  blocks[2].VegaTime,
   694  		AccountID: marginLevels[2].AccountID,
   695  	}
   696  	wantEndCursor := entities.MarginCursor{
   697  		VegaTime:  blocks[13].VegaTime,
   698  		AccountID: marginLevels[13].AccountID,
   699  	}
   700  	assert.Equal(t, entities.PageInfo{
   701  		HasNextPage:     false,
   702  		HasPreviousPage: false,
   703  		StartCursor:     entities.NewCursor(wantStartCursor.String()).Encode(),
   704  		EndCursor:       entities.NewCursor(wantEndCursor.String()).Encode(),
   705  	}, pageInfo)
   706  }
   707  
   708  func testGetMarginLevelsByIDPaginationWithMarketNoCursorNewestFirst(t *testing.T) {
   709  	ctx := tempTransaction(t)
   710  
   711  	t.Logf("DB Port: %d", testDBPort)
   712  	mls, blocks, marginLevels := populateMarginLevelPaginationTestData(t, ctx)
   713  	pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, true)
   714  	require.NoError(t, err)
   715  	got, pageInfo, err := mls.GetMarginLevelsByIDWithCursorPagination(ctx, "", "DEADBEEF", pagination)
   716  	require.NoError(t, err)
   717  	assert.Len(t, got, 6)
   718  	wantMarginLevels := []entities.MarginLevels{
   719  		marginLevels[13],
   720  		marginLevels[11],
   721  		marginLevels[8],
   722  		marginLevels[6],
   723  		marginLevels[5],
   724  		marginLevels[2],
   725  	}
   726  	assert.Equal(t, wantMarginLevels, got)
   727  	wantStartCursor := entities.MarginCursor{
   728  		VegaTime:  blocks[13].VegaTime,
   729  		AccountID: marginLevels[13].AccountID,
   730  	}
   731  	wantEndCursor := entities.MarginCursor{
   732  		VegaTime:  blocks[2].VegaTime,
   733  		AccountID: marginLevels[2].AccountID,
   734  	}
   735  	assert.Equal(t, entities.PageInfo{
   736  		HasNextPage:     false,
   737  		HasPreviousPage: false,
   738  		StartCursor:     entities.NewCursor(wantStartCursor.String()).Encode(),
   739  		EndCursor:       entities.NewCursor(wantEndCursor.String()).Encode(),
   740  	}, pageInfo)
   741  }
   742  
   743  func testGetMarginLevelsByIDPaginationWithPartyFirstNoAfterCursor(t *testing.T) {
   744  	ctx := tempTransaction(t)
   745  
   746  	t.Logf("DB Port: %d", testDBPort)
   747  	mls, blocks, marginLevels := populateMarginLevelPaginationTestData(t, ctx)
   748  	first := int32(3)
   749  	pagination, err := entities.NewCursorPagination(&first, nil, nil, nil, false)
   750  	require.NoError(t, err)
   751  	got, pageInfo, err := mls.GetMarginLevelsByIDWithCursorPagination(ctx, "DEADBEEF", "", pagination)
   752  	require.NoError(t, err)
   753  	assert.Len(t, got, 3)
   754  	wantMarginLevels := []entities.MarginLevels{
   755  		marginLevels[0],
   756  		marginLevels[1],
   757  		marginLevels[4],
   758  	}
   759  	assert.Equal(t, wantMarginLevels, got)
   760  	wantStartCursor := entities.MarginCursor{
   761  		VegaTime:  blocks[0].VegaTime,
   762  		AccountID: marginLevels[0].AccountID,
   763  	}
   764  	wantEndCursor := entities.MarginCursor{
   765  		VegaTime:  blocks[4].VegaTime,
   766  		AccountID: marginLevels[4].AccountID,
   767  	}
   768  	assert.Equal(t, entities.PageInfo{
   769  		HasNextPage:     true,
   770  		HasPreviousPage: false,
   771  		StartCursor:     entities.NewCursor(wantStartCursor.String()).Encode(),
   772  		EndCursor:       entities.NewCursor(wantEndCursor.String()).Encode(),
   773  	}, pageInfo)
   774  }
   775  
   776  func testGetMarginLevelsByIDPaginationWithPartyFirstNoAfterCursorNewestFirst(t *testing.T) {
   777  	ctx := tempTransaction(t)
   778  
   779  	t.Logf("DB Port: %d", testDBPort)
   780  	mls, blocks, marginLevels := populateMarginLevelPaginationTestData(t, ctx)
   781  	first := int32(3)
   782  	pagination, err := entities.NewCursorPagination(&first, nil, nil, nil, true)
   783  	require.NoError(t, err)
   784  	got, pageInfo, err := mls.GetMarginLevelsByIDWithCursorPagination(ctx, "DEADBEEF", "", pagination)
   785  	require.NoError(t, err)
   786  	assert.Len(t, got, 3)
   787  	wantMarginLevels := []entities.MarginLevels{
   788  		marginLevels[14],
   789  		marginLevels[10],
   790  		marginLevels[7],
   791  	}
   792  	assert.Equal(t, wantMarginLevels, got)
   793  	wantStartCursor := entities.MarginCursor{
   794  		VegaTime:  blocks[14].VegaTime,
   795  		AccountID: marginLevels[14].AccountID,
   796  	}
   797  	wantEndCursor := entities.MarginCursor{
   798  		VegaTime:  blocks[7].VegaTime,
   799  		AccountID: marginLevels[7].AccountID,
   800  	}
   801  	assert.Equal(t, entities.PageInfo{
   802  		HasNextPage:     true,
   803  		HasPreviousPage: false,
   804  		StartCursor:     entities.NewCursor(wantStartCursor.String()).Encode(),
   805  		EndCursor:       entities.NewCursor(wantEndCursor.String()).Encode(),
   806  	}, pageInfo)
   807  }
   808  
   809  func testGetMarginLevelsByIDPaginationWithMarketFirstNoAfterCursor(t *testing.T) {
   810  	ctx := tempTransaction(t)
   811  
   812  	t.Logf("DB Port: %d", testDBPort)
   813  	mls, blocks, marginLevels := populateMarginLevelPaginationTestData(t, ctx)
   814  	first := int32(3)
   815  	pagination, err := entities.NewCursorPagination(&first, nil, nil, nil, false)
   816  	require.NoError(t, err)
   817  	got, pageInfo, err := mls.GetMarginLevelsByIDWithCursorPagination(ctx, "", "DEADBEEF", pagination)
   818  	require.NoError(t, err)
   819  	assert.Len(t, got, 3)
   820  	wantMarginLevels := []entities.MarginLevels{
   821  		marginLevels[2],
   822  		marginLevels[5],
   823  		marginLevels[6],
   824  	}
   825  	assert.Equal(t, wantMarginLevels, got)
   826  	wantStartCursor := entities.MarginCursor{
   827  		VegaTime:  blocks[2].VegaTime,
   828  		AccountID: marginLevels[2].AccountID,
   829  	}
   830  	wantEndCursor := entities.MarginCursor{
   831  		VegaTime:  blocks[6].VegaTime,
   832  		AccountID: marginLevels[6].AccountID,
   833  	}
   834  	assert.Equal(t, entities.PageInfo{
   835  		HasNextPage:     true,
   836  		HasPreviousPage: false,
   837  		StartCursor:     entities.NewCursor(wantStartCursor.String()).Encode(),
   838  		EndCursor:       entities.NewCursor(wantEndCursor.String()).Encode(),
   839  	}, pageInfo)
   840  }
   841  
   842  func testGetMarginLevelsByIDPaginationWithMarketFirstNoAfterCursorNewestFirst(t *testing.T) {
   843  	ctx := tempTransaction(t)
   844  
   845  	t.Logf("DB Port: %d", testDBPort)
   846  	mls, blocks, marginLevels := populateMarginLevelPaginationTestData(t, ctx)
   847  	first := int32(3)
   848  	pagination, err := entities.NewCursorPagination(&first, nil, nil, nil, true)
   849  	require.NoError(t, err)
   850  	got, pageInfo, err := mls.GetMarginLevelsByIDWithCursorPagination(ctx, "", "DEADBEEF", pagination)
   851  	require.NoError(t, err)
   852  	assert.Len(t, got, 3)
   853  	wantMarginLevels := []entities.MarginLevels{
   854  		marginLevels[13],
   855  		marginLevels[11],
   856  		marginLevels[8],
   857  	}
   858  	assert.Equal(t, wantMarginLevels, got)
   859  	wantStartCursor := entities.MarginCursor{
   860  		VegaTime:  blocks[13].VegaTime,
   861  		AccountID: marginLevels[13].AccountID,
   862  	}
   863  	wantEndCursor := entities.MarginCursor{
   864  		VegaTime:  blocks[8].VegaTime,
   865  		AccountID: marginLevels[8].AccountID,
   866  	}
   867  	assert.Equal(t, entities.PageInfo{
   868  		HasNextPage:     true,
   869  		HasPreviousPage: false,
   870  		StartCursor:     entities.NewCursor(wantStartCursor.String()).Encode(),
   871  		EndCursor:       entities.NewCursor(wantEndCursor.String()).Encode(),
   872  	}, pageInfo)
   873  }
   874  
   875  func testGetMarginLevelsByIDPaginationWithPartyLastNoBeforeCursor(t *testing.T) {
   876  	ctx := tempTransaction(t)
   877  
   878  	t.Logf("DB Port: %d", testDBPort)
   879  	mls, blocks, marginLevels := populateMarginLevelPaginationTestData(t, ctx)
   880  	last := int32(3)
   881  	pagination, err := entities.NewCursorPagination(nil, nil, &last, nil, false)
   882  	require.NoError(t, err)
   883  	got, pageInfo, err := mls.GetMarginLevelsByIDWithCursorPagination(ctx, "DEADBEEF", "", pagination)
   884  	require.NoError(t, err)
   885  	assert.Len(t, got, 3)
   886  	wantMarginLevels := []entities.MarginLevels{
   887  		marginLevels[7],
   888  		marginLevels[10],
   889  		marginLevels[14],
   890  	}
   891  	assert.Equal(t, wantMarginLevels, got)
   892  	wantStartCursor := entities.MarginCursor{
   893  		VegaTime:  blocks[7].VegaTime,
   894  		AccountID: marginLevels[7].AccountID,
   895  	}
   896  	wantEndCursor := entities.MarginCursor{
   897  		VegaTime:  blocks[14].VegaTime,
   898  		AccountID: marginLevels[14].AccountID,
   899  	}
   900  	assert.Equal(t, entities.PageInfo{
   901  		HasNextPage:     false,
   902  		HasPreviousPage: true,
   903  		StartCursor:     entities.NewCursor(wantStartCursor.String()).Encode(),
   904  		EndCursor:       entities.NewCursor(wantEndCursor.String()).Encode(),
   905  	}, pageInfo)
   906  }
   907  
   908  func testGetMarginLevelsByIDPaginationWithPartyLastNoBeforeCursorNewestFirst(t *testing.T) {
   909  	ctx := tempTransaction(t)
   910  
   911  	t.Logf("DB Port: %d", testDBPort)
   912  	mls, blocks, marginLevels := populateMarginLevelPaginationTestData(t, ctx)
   913  	last := int32(3)
   914  	pagination, err := entities.NewCursorPagination(nil, nil, &last, nil, true)
   915  	require.NoError(t, err)
   916  	got, pageInfo, err := mls.GetMarginLevelsByIDWithCursorPagination(ctx, "DEADBEEF", "", pagination)
   917  	require.NoError(t, err)
   918  	assert.Len(t, got, 3)
   919  	wantMarginLevels := []entities.MarginLevels{
   920  		marginLevels[4],
   921  		marginLevels[1],
   922  		marginLevels[0],
   923  	}
   924  	assert.Equal(t, wantMarginLevels, got)
   925  	wantStartCursor := entities.MarginCursor{
   926  		VegaTime:  blocks[4].VegaTime,
   927  		AccountID: marginLevels[4].AccountID,
   928  	}
   929  	wantEndCursor := entities.MarginCursor{
   930  		VegaTime:  blocks[0].VegaTime,
   931  		AccountID: marginLevels[0].AccountID,
   932  	}
   933  	assert.Equal(t, entities.PageInfo{
   934  		HasNextPage:     false,
   935  		HasPreviousPage: true,
   936  		StartCursor:     entities.NewCursor(wantStartCursor.String()).Encode(),
   937  		EndCursor:       entities.NewCursor(wantEndCursor.String()).Encode(),
   938  	}, pageInfo)
   939  }
   940  
   941  func testGetMarginLevelsByIDPaginationWithMarketLastNoBeforeCursor(t *testing.T) {
   942  	ctx := tempTransaction(t)
   943  
   944  	t.Logf("DB Port: %d", testDBPort)
   945  	mls, blocks, marginLevels := populateMarginLevelPaginationTestData(t, ctx)
   946  	last := int32(3)
   947  	pagination, err := entities.NewCursorPagination(nil, nil, &last, nil, false)
   948  	require.NoError(t, err)
   949  	got, pageInfo, err := mls.GetMarginLevelsByIDWithCursorPagination(ctx, "", "DEADBEEF", pagination)
   950  	require.NoError(t, err)
   951  	assert.Len(t, got, 3)
   952  	wantMarginLevels := []entities.MarginLevels{
   953  		marginLevels[8],
   954  		marginLevels[11],
   955  		marginLevels[13],
   956  	}
   957  	assert.Equal(t, wantMarginLevels, got)
   958  	wantStartCursor := entities.MarginCursor{
   959  		VegaTime:  blocks[8].VegaTime,
   960  		AccountID: marginLevels[8].AccountID,
   961  	}
   962  	wantEndCursor := entities.MarginCursor{
   963  		VegaTime:  blocks[13].VegaTime,
   964  		AccountID: marginLevels[13].AccountID,
   965  	}
   966  	assert.Equal(t, entities.PageInfo{
   967  		HasNextPage:     false,
   968  		HasPreviousPage: true,
   969  		StartCursor:     entities.NewCursor(wantStartCursor.String()).Encode(),
   970  		EndCursor:       entities.NewCursor(wantEndCursor.String()).Encode(),
   971  	}, pageInfo)
   972  }
   973  
   974  func testGetMarginLevelsByIDPaginationWithMarketLastNoBeforeCursorNewestFirst(t *testing.T) {
   975  	ctx := tempTransaction(t)
   976  
   977  	t.Logf("DB Port: %d", testDBPort)
   978  	mls, blocks, marginLevels := populateMarginLevelPaginationTestData(t, ctx)
   979  	last := int32(3)
   980  	pagination, err := entities.NewCursorPagination(nil, nil, &last, nil, true)
   981  	require.NoError(t, err)
   982  	got, pageInfo, err := mls.GetMarginLevelsByIDWithCursorPagination(ctx, "", "DEADBEEF", pagination)
   983  	require.NoError(t, err)
   984  	assert.Len(t, got, 3)
   985  	wantMarginLevels := []entities.MarginLevels{
   986  		marginLevels[6],
   987  		marginLevels[5],
   988  		marginLevels[2],
   989  	}
   990  	assert.Equal(t, wantMarginLevels, got)
   991  	wantStartCursor := entities.MarginCursor{
   992  		VegaTime:  blocks[6].VegaTime,
   993  		AccountID: marginLevels[6].AccountID,
   994  	}
   995  	wantEndCursor := entities.MarginCursor{
   996  		VegaTime:  blocks[2].VegaTime,
   997  		AccountID: marginLevels[2].AccountID,
   998  	}
   999  	assert.Equal(t, entities.PageInfo{
  1000  		HasNextPage:     false,
  1001  		HasPreviousPage: true,
  1002  		StartCursor:     entities.NewCursor(wantStartCursor.String()).Encode(),
  1003  		EndCursor:       entities.NewCursor(wantEndCursor.String()).Encode(),
  1004  	}, pageInfo)
  1005  }
  1006  
  1007  func testGetMarginLevelsByIDPaginationWithPartyFirstAndAfterCursor(t *testing.T) {
  1008  	ctx := tempTransaction(t)
  1009  
  1010  	t.Logf("DB Port: %d", testDBPort)
  1011  	mls, blocks, marginLevels := populateMarginLevelPaginationTestData(t, ctx)
  1012  	first := int32(3)
  1013  	after := entities.NewCursor(entities.MarginCursor{
  1014  		VegaTime:  blocks[1].VegaTime,
  1015  		AccountID: marginLevels[1].AccountID,
  1016  	}.String()).Encode()
  1017  	pagination, err := entities.NewCursorPagination(&first, &after, nil, nil, false)
  1018  	require.NoError(t, err)
  1019  	got, pageInfo, err := mls.GetMarginLevelsByIDWithCursorPagination(ctx, "DEADBEEF", "", pagination)
  1020  	require.NoError(t, err)
  1021  	assert.Len(t, got, 3)
  1022  	wantMarginLevels := []entities.MarginLevels{
  1023  		marginLevels[4],
  1024  		marginLevels[7],
  1025  		marginLevels[10],
  1026  	}
  1027  	assert.Equal(t, wantMarginLevels, got)
  1028  	wantStartCursor := entities.MarginCursor{
  1029  		VegaTime:  blocks[4].VegaTime,
  1030  		AccountID: marginLevels[4].AccountID,
  1031  	}
  1032  	wantEndCursor := entities.MarginCursor{
  1033  		VegaTime:  blocks[10].VegaTime,
  1034  		AccountID: marginLevels[10].AccountID,
  1035  	}
  1036  	assert.Equal(t, entities.PageInfo{
  1037  		HasNextPage:     true,
  1038  		HasPreviousPage: true,
  1039  		StartCursor:     entities.NewCursor(wantStartCursor.String()).Encode(),
  1040  		EndCursor:       entities.NewCursor(wantEndCursor.String()).Encode(),
  1041  	}, pageInfo)
  1042  }
  1043  
  1044  func testGetMarginLevelsByIDPaginationWithPartyFirstAndAfterCursorNewestFirst(t *testing.T) {
  1045  	ctx := tempTransaction(t)
  1046  
  1047  	t.Logf("DB Port: %d", testDBPort)
  1048  	mls, blocks, marginLevels := populateMarginLevelPaginationTestData(t, ctx)
  1049  	first := int32(3)
  1050  	after := entities.NewCursor(entities.MarginCursor{
  1051  		VegaTime:  blocks[10].VegaTime,
  1052  		AccountID: marginLevels[10].AccountID,
  1053  	}.String()).Encode()
  1054  	pagination, err := entities.NewCursorPagination(&first, &after, nil, nil, true)
  1055  	require.NoError(t, err)
  1056  	got, pageInfo, err := mls.GetMarginLevelsByIDWithCursorPagination(ctx, "DEADBEEF", "", pagination)
  1057  	require.NoError(t, err)
  1058  	assert.Len(t, got, 3)
  1059  	wantMarginLevels := []entities.MarginLevels{
  1060  		marginLevels[7],
  1061  		marginLevels[4],
  1062  		marginLevels[1],
  1063  	}
  1064  	assert.Equal(t, wantMarginLevels, got)
  1065  	wantStartCursor := entities.MarginCursor{
  1066  		VegaTime:  blocks[7].VegaTime,
  1067  		AccountID: marginLevels[7].AccountID,
  1068  	}
  1069  	wantEndCursor := entities.MarginCursor{
  1070  		VegaTime:  blocks[1].VegaTime,
  1071  		AccountID: marginLevels[1].AccountID,
  1072  	}
  1073  	assert.Equal(t, entities.PageInfo{
  1074  		HasNextPage:     true,
  1075  		HasPreviousPage: true,
  1076  		StartCursor:     entities.NewCursor(wantStartCursor.String()).Encode(),
  1077  		EndCursor:       entities.NewCursor(wantEndCursor.String()).Encode(),
  1078  	}, pageInfo)
  1079  }
  1080  
  1081  func testGetMarginLevelsByIDPaginationWithMarketFirstAndAfterCursor(t *testing.T) {
  1082  	ctx := tempTransaction(t)
  1083  
  1084  	t.Logf("DB Port: %d", testDBPort)
  1085  	mls, blocks, marginLevels := populateMarginLevelPaginationTestData(t, ctx)
  1086  	first := int32(3)
  1087  	after := entities.NewCursor(entities.MarginCursor{
  1088  		VegaTime:  blocks[5].VegaTime,
  1089  		AccountID: marginLevels[5].AccountID,
  1090  	}.String()).Encode()
  1091  	pagination, err := entities.NewCursorPagination(&first, &after, nil, nil, false)
  1092  	require.NoError(t, err)
  1093  	got, pageInfo, err := mls.GetMarginLevelsByIDWithCursorPagination(ctx, "", "DEADBEEF", pagination)
  1094  	require.NoError(t, err)
  1095  	assert.Len(t, got, 3)
  1096  	wantMarginLevels := []entities.MarginLevels{
  1097  		marginLevels[6],
  1098  		marginLevels[8],
  1099  		marginLevels[11],
  1100  	}
  1101  	assert.Equal(t, wantMarginLevels, got)
  1102  	wantStartCursor := entities.MarginCursor{
  1103  		VegaTime:  blocks[6].VegaTime,
  1104  		AccountID: marginLevels[6].AccountID,
  1105  	}
  1106  	wantEndCursor := entities.MarginCursor{
  1107  		VegaTime:  blocks[11].VegaTime,
  1108  		AccountID: marginLevels[11].AccountID,
  1109  	}
  1110  	assert.Equal(t, entities.PageInfo{
  1111  		HasNextPage:     true,
  1112  		HasPreviousPage: true,
  1113  		StartCursor:     entities.NewCursor(wantStartCursor.String()).Encode(),
  1114  		EndCursor:       entities.NewCursor(wantEndCursor.String()).Encode(),
  1115  	}, pageInfo)
  1116  }
  1117  
  1118  func testGetMarginLevelsByIDPaginationWithMarketFirstAndAfterCursorNewestFirst(t *testing.T) {
  1119  	ctx := tempTransaction(t)
  1120  
  1121  	t.Logf("DB Port: %d", testDBPort)
  1122  	mls, blocks, marginLevels := populateMarginLevelPaginationTestData(t, ctx)
  1123  	first := int32(3)
  1124  	after := entities.NewCursor(entities.MarginCursor{
  1125  		VegaTime:  blocks[11].VegaTime,
  1126  		AccountID: marginLevels[11].AccountID,
  1127  	}.String()).Encode()
  1128  	pagination, err := entities.NewCursorPagination(&first, &after, nil, nil, true)
  1129  	require.NoError(t, err)
  1130  	got, pageInfo, err := mls.GetMarginLevelsByIDWithCursorPagination(ctx, "", "DEADBEEF", pagination)
  1131  	require.NoError(t, err)
  1132  	assert.Len(t, got, 3)
  1133  	wantMarginLevels := []entities.MarginLevels{
  1134  		marginLevels[8],
  1135  		marginLevels[6],
  1136  		marginLevels[5],
  1137  	}
  1138  	assert.Equal(t, wantMarginLevels, got)
  1139  	wantStartCursor := entities.MarginCursor{
  1140  		VegaTime:  blocks[8].VegaTime,
  1141  		AccountID: marginLevels[8].AccountID,
  1142  	}
  1143  	wantEndCursor := entities.MarginCursor{
  1144  		VegaTime:  blocks[5].VegaTime,
  1145  		AccountID: marginLevels[5].AccountID,
  1146  	}
  1147  	assert.Equal(t, entities.PageInfo{
  1148  		HasNextPage:     true,
  1149  		HasPreviousPage: true,
  1150  		StartCursor:     entities.NewCursor(wantStartCursor.String()).Encode(),
  1151  		EndCursor:       entities.NewCursor(wantEndCursor.String()).Encode(),
  1152  	}, pageInfo)
  1153  }
  1154  
  1155  func testGetMarginLevelsByIDPaginationWithPartyLastAndBeforeCursor(t *testing.T) {
  1156  	ctx := tempTransaction(t)
  1157  
  1158  	t.Logf("DB Port: %d", testDBPort)
  1159  	mls, blocks, marginLevels := populateMarginLevelPaginationTestData(t, ctx)
  1160  	last := int32(3)
  1161  	before := entities.NewCursor(entities.MarginCursor{
  1162  		VegaTime:  blocks[10].VegaTime,
  1163  		AccountID: marginLevels[10].AccountID,
  1164  	}.String()).Encode()
  1165  	pagination, err := entities.NewCursorPagination(nil, nil, &last, &before, false)
  1166  	require.NoError(t, err)
  1167  	got, pageInfo, err := mls.GetMarginLevelsByIDWithCursorPagination(ctx, "DEADBEEF", "", pagination)
  1168  	require.NoError(t, err)
  1169  	assert.Len(t, got, 3)
  1170  	wantMarginLevels := []entities.MarginLevels{
  1171  		marginLevels[1],
  1172  		marginLevels[4],
  1173  		marginLevels[7],
  1174  	}
  1175  	assert.Equal(t, wantMarginLevels, got)
  1176  	wantStartCursor := entities.MarginCursor{
  1177  		VegaTime:  blocks[1].VegaTime,
  1178  		AccountID: marginLevels[1].AccountID,
  1179  	}
  1180  	wantEndCursor := entities.MarginCursor{
  1181  		VegaTime:  blocks[7].VegaTime,
  1182  		AccountID: marginLevels[7].AccountID,
  1183  	}
  1184  	assert.Equal(t, entities.PageInfo{
  1185  		HasNextPage:     true,
  1186  		HasPreviousPage: true,
  1187  		StartCursor:     entities.NewCursor(wantStartCursor.String()).Encode(),
  1188  		EndCursor:       entities.NewCursor(wantEndCursor.String()).Encode(),
  1189  	}, pageInfo)
  1190  }
  1191  
  1192  func testGetMarginLevelsByIDPaginationWithPartyLastAndBeforeCursorNewestFirst(t *testing.T) {
  1193  	ctx := tempTransaction(t)
  1194  
  1195  	t.Logf("DB Port: %d", testDBPort)
  1196  	mls, blocks, marginLevels := populateMarginLevelPaginationTestData(t, ctx)
  1197  	last := int32(3)
  1198  	before := entities.NewCursor(entities.MarginCursor{
  1199  		VegaTime:  blocks[1].VegaTime,
  1200  		AccountID: marginLevels[1].AccountID,
  1201  	}.String()).Encode()
  1202  	pagination, err := entities.NewCursorPagination(nil, nil, &last, &before, true)
  1203  	require.NoError(t, err)
  1204  	got, pageInfo, err := mls.GetMarginLevelsByIDWithCursorPagination(ctx, "DEADBEEF", "", pagination)
  1205  	require.NoError(t, err)
  1206  	assert.Len(t, got, 3)
  1207  	wantMarginLevels := []entities.MarginLevels{
  1208  		marginLevels[10],
  1209  		marginLevels[7],
  1210  		marginLevels[4],
  1211  	}
  1212  	assert.Equal(t, wantMarginLevels, got)
  1213  	wantStartCursor := entities.MarginCursor{
  1214  		VegaTime:  blocks[10].VegaTime,
  1215  		AccountID: marginLevels[10].AccountID,
  1216  	}
  1217  	wantEndCursor := entities.MarginCursor{
  1218  		VegaTime:  blocks[4].VegaTime,
  1219  		AccountID: marginLevels[4].AccountID,
  1220  	}
  1221  	assert.Equal(t, entities.PageInfo{
  1222  		HasNextPage:     true,
  1223  		HasPreviousPage: true,
  1224  		StartCursor:     entities.NewCursor(wantStartCursor.String()).Encode(),
  1225  		EndCursor:       entities.NewCursor(wantEndCursor.String()).Encode(),
  1226  	}, pageInfo)
  1227  }
  1228  
  1229  func testGetMarginLevelsByIDPaginationWithMarketLastAndBeforeCursor(t *testing.T) {
  1230  	ctx := tempTransaction(t)
  1231  
  1232  	t.Logf("DB Port: %d", testDBPort)
  1233  	mls, blocks, marginLevels := populateMarginLevelPaginationTestData(t, ctx)
  1234  	last := int32(3)
  1235  	before := entities.NewCursor(entities.MarginCursor{
  1236  		VegaTime:  blocks[11].VegaTime,
  1237  		AccountID: marginLevels[11].AccountID,
  1238  	}.String()).Encode()
  1239  	pagination, err := entities.NewCursorPagination(nil, nil, &last, &before, false)
  1240  	require.NoError(t, err)
  1241  	got, pageInfo, err := mls.GetMarginLevelsByIDWithCursorPagination(ctx, "", "DEADBEEF", pagination)
  1242  	require.NoError(t, err)
  1243  	assert.Len(t, got, 3)
  1244  	wantMarginLevels := []entities.MarginLevels{
  1245  		marginLevels[5],
  1246  		marginLevels[6],
  1247  		marginLevels[8],
  1248  	}
  1249  	assert.Equal(t, wantMarginLevels, got)
  1250  	wantStartCursor := entities.MarginCursor{
  1251  		VegaTime:  blocks[5].VegaTime,
  1252  		AccountID: marginLevels[5].AccountID,
  1253  	}
  1254  	wantEndCursor := entities.MarginCursor{
  1255  		VegaTime:  blocks[8].VegaTime,
  1256  		AccountID: marginLevels[8].AccountID,
  1257  	}
  1258  	assert.Equal(t, entities.PageInfo{
  1259  		HasNextPage:     true,
  1260  		HasPreviousPage: true,
  1261  		StartCursor:     entities.NewCursor(wantStartCursor.String()).Encode(),
  1262  		EndCursor:       entities.NewCursor(wantEndCursor.String()).Encode(),
  1263  	}, pageInfo)
  1264  }
  1265  
  1266  func testGetMarginLevelsByIDPaginationWithMarketLastAndBeforeCursorNewestFirst(t *testing.T) {
  1267  	ctx := tempTransaction(t)
  1268  
  1269  	t.Logf("DB Port: %d", testDBPort)
  1270  	mls, blocks, marginLevels := populateMarginLevelPaginationTestData(t, ctx)
  1271  	last := int32(3)
  1272  	before := entities.NewCursor(entities.MarginCursor{
  1273  		VegaTime:  blocks[5].VegaTime,
  1274  		AccountID: marginLevels[5].AccountID,
  1275  	}.String()).Encode()
  1276  	pagination, err := entities.NewCursorPagination(nil, nil, &last, &before, true)
  1277  	require.NoError(t, err)
  1278  	got, pageInfo, err := mls.GetMarginLevelsByIDWithCursorPagination(ctx, "", "DEADBEEF", pagination)
  1279  	require.NoError(t, err)
  1280  	assert.Len(t, got, 3)
  1281  	wantMarginLevels := []entities.MarginLevels{
  1282  		marginLevels[11],
  1283  		marginLevels[8],
  1284  		marginLevels[6],
  1285  	}
  1286  	assert.Equal(t, wantMarginLevels, got)
  1287  	wantStartCursor := entities.MarginCursor{
  1288  		VegaTime:  blocks[11].VegaTime,
  1289  		AccountID: marginLevels[11].AccountID,
  1290  	}
  1291  	wantEndCursor := entities.MarginCursor{
  1292  		VegaTime:  blocks[6].VegaTime,
  1293  		AccountID: marginLevels[6].AccountID,
  1294  	}
  1295  	assert.Equal(t, entities.PageInfo{
  1296  		HasNextPage:     true,
  1297  		HasPreviousPage: true,
  1298  		StartCursor:     entities.NewCursor(wantStartCursor.String()).Encode(),
  1299  		EndCursor:       entities.NewCursor(wantEndCursor.String()).Encode(),
  1300  	}, pageInfo)
  1301  }
  1302  
  1303  func TestMarginLevels_MarginMode(t *testing.T) {
  1304  	var marginMode vega.MarginMode
  1305  	modes := getEnums(t, marginMode)
  1306  	assert.Len(t, modes, 3)
  1307  
  1308  	for m, mode := range modes {
  1309  		t.Run(mode, func(t *testing.T) {
  1310  			ctx := tempTransaction(t)
  1311  
  1312  			blockSource, ml, accountStore, _ := setupMarginLevelTests(t, ctx)
  1313  			block := blockSource.getNextBlock(t, ctx)
  1314  
  1315  			marginLevelProto := getMarginLevelProto()
  1316  			marginLevelProto.MarginMode = vega.MarginMode(m)
  1317  			want, err := entities.MarginLevelsFromProto(ctx, marginLevelProto, accountStore, generateTxHash(), block.VegaTime)
  1318  			require.NoError(t, err, "Converting margin levels proto to database entity")
  1319  
  1320  			require.NoError(t, ml.Add(want))
  1321  
  1322  			_, err = ml.Flush(ctx)
  1323  			require.NoError(t, err)
  1324  
  1325  			got, err := ml.GetByTxHash(ctx, want.TxHash)
  1326  			require.NoError(t, err)
  1327  			assert.Len(t, got, 1)
  1328  			assert.Equal(t, want, got[0])
  1329  		})
  1330  	}
  1331  }