code.vegaprotocol.io/vega@v0.79.0/datanode/sqlstore/erc20_multisig_added_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  	vgcrypto "code.vegaprotocol.io/vega/libs/crypto"
    27  	eventspb "code.vegaprotocol.io/vega/protos/vega/events/v1"
    28  
    29  	"github.com/stretchr/testify/assert"
    30  	"github.com/stretchr/testify/require"
    31  )
    32  
    33  func TestERC20MultiSigEvent(t *testing.T) {
    34  	t.Run("Adding a single bundle", testAddSigner)
    35  	t.Run("Get with filters", testGetWithFilters)
    36  	t.Run("Get with add and removed events", testGetWithAddAndRemoveEvents)
    37  	t.Run("Get by tx hash with add and removed events", testGetByTxHashWithAddAndRemoveEvents)
    38  }
    39  
    40  func setupERC20MultiSigEventStoreTests(t *testing.T) (*sqlstore.ERC20MultiSigSignerEvent, sqlstore.Connection) {
    41  	t.Helper()
    42  	ms := sqlstore.NewERC20MultiSigSignerEvent(connectionSource)
    43  	return ms, connectionSource
    44  }
    45  
    46  func testAddSigner(t *testing.T) {
    47  	ctx := tempTransaction(t)
    48  
    49  	ms, conn := setupERC20MultiSigEventStoreTests(t)
    50  
    51  	var rowCount int
    52  
    53  	err := conn.QueryRow(ctx, `select count(*) from erc20_multisig_signer_events`).Scan(&rowCount)
    54  	require.NoError(t, err)
    55  	assert.Equal(t, 0, rowCount)
    56  
    57  	sa := getTestSignerEvent(t, vgcrypto.RandomHash(), "fc677151d0c93726", generateEthereumAddress(), "12", true)
    58  	err = ms.Add(ctx, sa)
    59  	require.NoError(t, err)
    60  
    61  	err = conn.QueryRow(ctx, `select count(*) from erc20_multisig_signer_events`).Scan(&rowCount)
    62  	require.NoError(t, err)
    63  	assert.Equal(t, 1, rowCount)
    64  
    65  	// now add a duplicate and check we still remain with one
    66  	err = ms.Add(ctx, sa)
    67  	require.NoError(t, err)
    68  
    69  	err = conn.QueryRow(ctx, `select count(*) from erc20_multisig_signer_events`).Scan(&rowCount)
    70  	require.NoError(t, err)
    71  	assert.Equal(t, 1, rowCount)
    72  }
    73  
    74  func testGetWithFilters(t *testing.T) {
    75  	ctx := tempTransaction(t)
    76  
    77  	ms, conn := setupERC20MultiSigEventStoreTests(t)
    78  
    79  	var rowCount int
    80  	vID1 := "fc677151d0c93726"
    81  	vID2 := "15d1d5fefa8988eb"
    82  
    83  	err := conn.QueryRow(ctx, `select count(*) from erc20_multisig_signer_events`).Scan(&rowCount)
    84  	require.NoError(t, err)
    85  	assert.Equal(t, 0, rowCount)
    86  
    87  	vgcrypto.RandomHash()
    88  	err = ms.Add(ctx, getTestSignerEvent(t, vgcrypto.RandomHash(), vID1, generateEthereumAddress(), "12", true))
    89  	require.NoError(t, err)
    90  
    91  	// same validator different epoch
    92  	err = ms.Add(ctx, getTestSignerEvent(t, vgcrypto.RandomHash(), vID1, generateEthereumAddress(), "24", true))
    93  	require.NoError(t, err)
    94  
    95  	// same epoch different validator
    96  	err = ms.Add(ctx, getTestSignerEvent(t, vgcrypto.RandomHash(), vID2, generateEthereumAddress(), "12", true))
    97  	require.NoError(t, err)
    98  
    99  	res, _, err := ms.GetAddedEvents(ctx, vID1, "", nil, nil, entities.CursorPagination{})
   100  	require.NoError(t, err)
   101  	require.Len(t, res, 2)
   102  	assert.Equal(t, vID1, res[0].ValidatorID.String())
   103  	assert.Equal(t, vID1, res[1].ValidatorID.String())
   104  	assert.Equal(t, "1450", res[0].ChainID)
   105  	assert.Equal(t, "1450", res[1].ChainID)
   106  
   107  	epoch := int64(12)
   108  	res, _, err = ms.GetAddedEvents(ctx, vID1, "", &epoch, nil, entities.CursorPagination{})
   109  	require.NoError(t, err)
   110  	require.Len(t, res, 1)
   111  	assert.Equal(t, vID1, res[0].ValidatorID.String())
   112  	assert.Equal(t, int64(12), res[0].EpochID)
   113  	assert.Equal(t, "1450", res[0].ChainID)
   114  }
   115  
   116  func testGetWithAddAndRemoveEvents(t *testing.T) {
   117  	ctx := tempTransaction(t)
   118  
   119  	ms, conn := setupERC20MultiSigEventStoreTests(t)
   120  
   121  	var rowCount int
   122  	vID1 := "fc677151d0c93726"
   123  	vID2 := "15d1d5fefa8988eb"
   124  	submitter := generateEthereumAddress()
   125  	wrongSubmitter := generateEthereumAddress()
   126  
   127  	err := conn.QueryRow(ctx, `select count(*) from erc20_multisig_signer_events`).Scan(&rowCount)
   128  	require.NoError(t, err)
   129  	assert.Equal(t, 0, rowCount)
   130  
   131  	err = ms.Add(ctx, getTestSignerEvent(t, vgcrypto.RandomHash(), vID1, generateEthereumAddress(), "12", true))
   132  	require.NoError(t, err)
   133  
   134  	// same validator different epoch
   135  	err = ms.Add(ctx, getTestSignerEvent(t, vgcrypto.RandomHash(), vID1, submitter, "24", false))
   136  	require.NoError(t, err)
   137  
   138  	// same epoch different validator
   139  	err = ms.Add(ctx, getTestSignerEvent(t, vgcrypto.RandomHash(), vID2, generateEthereumAddress(), "12", true))
   140  	require.NoError(t, err)
   141  
   142  	res, _, err := ms.GetAddedEvents(ctx, vID1, "", nil, nil, entities.CursorPagination{})
   143  	require.NoError(t, err)
   144  	require.Len(t, res, 1)
   145  	assert.Equal(t, vID1, res[0].ValidatorID.String())
   146  	assert.Equal(t, "1450", res[0].ChainID)
   147  
   148  	res, _, err = ms.GetRemovedEvents(ctx, vID1, submitter, nil, nil, entities.CursorPagination{})
   149  	require.NoError(t, err)
   150  	require.Len(t, res, 1)
   151  	assert.Equal(t, vID1, res[0].ValidatorID.String())
   152  	assert.Equal(t, "1450", res[0].ChainID)
   153  
   154  	res, _, err = ms.GetRemovedEvents(ctx, vID1, wrongSubmitter, nil, nil, entities.CursorPagination{})
   155  	require.NoError(t, err)
   156  	require.Len(t, res, 0)
   157  }
   158  
   159  func testGetByTxHashWithAddAndRemoveEvents(t *testing.T) {
   160  	ctx := tempTransaction(t)
   161  
   162  	ms, conn := setupERC20MultiSigEventStoreTests(t)
   163  
   164  	var rowCount int
   165  	vID1 := "fc677151d0c93726"
   166  	submitter := generateEthereumAddress()
   167  
   168  	err := conn.QueryRow(ctx, `select count(*) from erc20_multisig_signer_events`).Scan(&rowCount)
   169  	require.NoError(t, err)
   170  	assert.Equal(t, 0, rowCount)
   171  
   172  	event1 := getTestSignerEvent(t, vgcrypto.RandomHash(), vID1, submitter, "12", true)
   173  	err = ms.Add(ctx, event1)
   174  	require.NoError(t, err)
   175  
   176  	event2 := getTestSignerEvent(t, vgcrypto.RandomHash(), vID1, submitter, "24", false)
   177  	err = ms.Add(ctx, event2)
   178  	require.NoError(t, err)
   179  
   180  	res, err := ms.GetAddedByTxHash(ctx, event1.TxHash)
   181  	require.NoError(t, err)
   182  	require.Len(t, res, 1)
   183  	assert.Equal(t, event1.TxHash, res[0].TxHash)
   184  	assert.Equal(t, event1.Event, res[0].Event)
   185  
   186  	res2, err := ms.GetRemovedByTxHash(ctx, event2.TxHash)
   187  	require.NoError(t, err)
   188  	require.Len(t, res2, 1)
   189  	assert.Equal(t, event2.TxHash, res2[0].TxHash)
   190  	assert.Equal(t, event2.Event, res2[0].Event)
   191  }
   192  
   193  func getTestSignerEvent(t *testing.T, signatureID string, validatorID string, submitter string, epochSeq string, addedEvent bool) *entities.ERC20MultiSigSignerEvent {
   194  	t.Helper()
   195  
   196  	var err error
   197  	var evt *entities.ERC20MultiSigSignerEvent
   198  	switch addedEvent {
   199  	case true:
   200  		evt, err = entities.ERC20MultiSigSignerEventFromAddedProto(
   201  			&eventspb.ERC20MultiSigSignerAdded{
   202  				SignatureId: signatureID,
   203  				ValidatorId: validatorID,
   204  				NewSigner:   generateEthereumAddress(),
   205  				Submitter:   submitter,
   206  				Nonce:       "nonce",
   207  				EpochSeq:    epochSeq,
   208  				Timestamp:   time.Unix(10000000, 13000).UnixNano(),
   209  				ChainId:     "1450",
   210  			},
   211  			generateTxHash(),
   212  		)
   213  		require.NoError(t, err)
   214  	case false:
   215  		evts, err := entities.ERC20MultiSigSignerEventFromRemovedProto(
   216  			&eventspb.ERC20MultiSigSignerRemoved{
   217  				SignatureSubmitters: []*eventspb.ERC20MultiSigSignerRemovedSubmitter{
   218  					{
   219  						SignatureId: signatureID,
   220  						Submitter:   submitter,
   221  					},
   222  				},
   223  				ValidatorId: validatorID,
   224  				OldSigner:   generateEthereumAddress(),
   225  				Nonce:       "nonce",
   226  				EpochSeq:    epochSeq,
   227  				Timestamp:   time.Unix(10000000, 13000).UnixNano(),
   228  				ChainId:     "1450",
   229  			},
   230  			generateTxHash(),
   231  		)
   232  		require.NoError(t, err)
   233  		evt = evts[0]
   234  	}
   235  
   236  	require.NoError(t, err)
   237  	return evt
   238  }
   239  
   240  func TestERC20MultiSigEventPagination(t *testing.T) {
   241  	t.Run("should return all added events if no pagination is specified", testERC20MultiSigAddedEventPaginationNoPagination)
   242  	t.Run("should return first page of added events if first pagination is specified", testERC20MultiSigAddedEventPaginationFirst)
   243  	t.Run("should return last page of added events if last pagination is specified", testERC20MultiSigAddedEventPaginationLast)
   244  	t.Run("should return specified page of added events if first and after pagination is specified", testERC20MultiSigAddedEventPaginationFirstAfter)
   245  	t.Run("should return specified page of added events if last and before pagination is specified", testERC20MultiSigAddedEventPaginationLastBefore)
   246  
   247  	t.Run("should return all added events if no pagination is specified - newest first", testERC20MultiSigAddedEventPaginationNoPaginationNewestFirst)
   248  	t.Run("should return first page of added events if first pagination is specified - newest first", testERC20MultiSigAddedEventPaginationFirstNewestFirst)
   249  	t.Run("should return last page of added events if last pagination is specified - newest first", testERC20MultiSigAddedEventPaginationLastNewestFirst)
   250  	t.Run("should return specified page of added events if first and after pagination is specified - newest first", testERC20MultiSigAddedEventPaginationFirstAfterNewestFirst)
   251  	t.Run("should return specified page of added events if last and before pagination is specified - newest first", testERC20MultiSigAddedEventPaginationLastBeforeNewestFirst)
   252  
   253  	t.Run("should return all removed events if no pagination is specified", testERC20MultiSigRemovedEventPaginationNoPagination)
   254  	t.Run("should return first page of removed events if first pagination is specified", testERC20MultiSigRemovedEventPaginationFirst)
   255  	t.Run("should return last page of removed events if last pagination is specified", testERC20MultiSigRemovedEventPaginationLast)
   256  	t.Run("should return specified page of removed events if first and after pagination is specified", testERC20MultiSigRemovedEventPaginationFirstAfter)
   257  	t.Run("should return specified page of removed events if last and before pagination is specified", testERC20MultiSigRemovedEventPaginationLastBefore)
   258  
   259  	t.Run("should return all removed events if no pagination is specified - newest first", testERC20MultiSigRemovedEventPaginationNoPaginationNewestFirst)
   260  	t.Run("should return first page of removed events if first pagination is specified - newest first", testERC20MultiSigRemovedEventPaginationFirstNewestFirst)
   261  	t.Run("should return last page of removed events if last pagination is specified - newest first", testERC20MultiSigRemovedEventPaginationLastNewestFirst)
   262  	t.Run("should return specified page of removed events if first and after pagination is specified - newest first", testERC20MultiSigRemovedEventPaginationFirstAfterNewestFirst)
   263  	t.Run("should return specified page of removed events if last and before pagination is specified - newest first", testERC20MultiSigRemovedEventPaginationLastBeforeNewestFirst)
   264  }
   265  
   266  func testERC20MultiSigAddedEventPaginationNoPagination(t *testing.T) {
   267  	ctx := tempTransaction(t)
   268  
   269  	es, events, _ := setupERC20MultiSigEventStorePaginationTests(t, ctx)
   270  	pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, false)
   271  	require.NoError(t, err)
   272  
   273  	validator := "fc677151d0c93726"
   274  	got, pageInfo, err := es.GetAddedEvents(ctx, validator, "", nil, nil, pagination)
   275  	require.NoError(t, err)
   276  	want := events[:10]
   277  	assert.Equal(t, want, got)
   278  	assert.Equal(t, entities.PageInfo{
   279  		HasNextPage:     false,
   280  		HasPreviousPage: false,
   281  		StartCursor:     want[0].Cursor().Encode(),
   282  		EndCursor:       want[9].Cursor().Encode(),
   283  	}, pageInfo)
   284  }
   285  
   286  func testERC20MultiSigAddedEventPaginationFirst(t *testing.T) {
   287  	ctx := tempTransaction(t)
   288  
   289  	es, events, _ := setupERC20MultiSigEventStorePaginationTests(t, ctx)
   290  	first := int32(3)
   291  	pagination, err := entities.NewCursorPagination(&first, nil, nil, nil, false)
   292  	require.NoError(t, err)
   293  
   294  	validator := "fc677151d0c93726"
   295  	got, pageInfo, err := es.GetAddedEvents(ctx, validator, "", nil, nil, pagination)
   296  	require.NoError(t, err)
   297  	want := events[:3]
   298  	assert.Equal(t, want, got)
   299  	assert.Equal(t, entities.PageInfo{
   300  		HasNextPage:     true,
   301  		HasPreviousPage: false,
   302  		StartCursor:     want[0].Cursor().Encode(),
   303  		EndCursor:       want[2].Cursor().Encode(),
   304  	}, pageInfo)
   305  }
   306  
   307  func testERC20MultiSigAddedEventPaginationLast(t *testing.T) {
   308  	ctx := tempTransaction(t)
   309  
   310  	es, events, _ := setupERC20MultiSigEventStorePaginationTests(t, ctx)
   311  	last := int32(3)
   312  	pagination, err := entities.NewCursorPagination(nil, nil, &last, nil, false)
   313  	require.NoError(t, err)
   314  
   315  	validator := "fc677151d0c93726"
   316  	got, pageInfo, err := es.GetAddedEvents(ctx, validator, "", nil, nil, pagination)
   317  	require.NoError(t, err)
   318  	want := events[7:10]
   319  	assert.Equal(t, want, got)
   320  	assert.Equal(t, entities.PageInfo{
   321  		HasNextPage:     false,
   322  		HasPreviousPage: true,
   323  		StartCursor:     want[0].Cursor().Encode(),
   324  		EndCursor:       want[2].Cursor().Encode(),
   325  	}, pageInfo)
   326  }
   327  
   328  func testERC20MultiSigAddedEventPaginationFirstAfter(t *testing.T) {
   329  	ctx := tempTransaction(t)
   330  
   331  	es, events, _ := setupERC20MultiSigEventStorePaginationTests(t, ctx)
   332  	first := int32(3)
   333  	after := events[2].Cursor().Encode()
   334  	pagination, err := entities.NewCursorPagination(&first, &after, nil, nil, false)
   335  	require.NoError(t, err)
   336  
   337  	validator := "fc677151d0c93726"
   338  	got, pageInfo, err := es.GetAddedEvents(ctx, validator, "", nil, nil, pagination)
   339  	require.NoError(t, err)
   340  	want := events[3:6]
   341  	assert.Equal(t, want, got)
   342  	assert.Equal(t, entities.PageInfo{
   343  		HasNextPage:     true,
   344  		HasPreviousPage: true,
   345  		StartCursor:     want[0].Cursor().Encode(),
   346  		EndCursor:       want[2].Cursor().Encode(),
   347  	}, pageInfo)
   348  }
   349  
   350  func testERC20MultiSigAddedEventPaginationLastBefore(t *testing.T) {
   351  	ctx := tempTransaction(t)
   352  
   353  	es, events, _ := setupERC20MultiSigEventStorePaginationTests(t, ctx)
   354  	last := int32(3)
   355  	before := events[7].Cursor().Encode()
   356  	pagination, err := entities.NewCursorPagination(nil, nil, &last, &before, false)
   357  	require.NoError(t, err)
   358  
   359  	validator := "fc677151d0c93726"
   360  	got, pageInfo, err := es.GetAddedEvents(ctx, validator, "", nil, nil, pagination)
   361  	require.NoError(t, err)
   362  	want := events[4:7]
   363  	assert.Equal(t, want, got)
   364  	assert.Equal(t, entities.PageInfo{
   365  		HasNextPage:     true,
   366  		HasPreviousPage: true,
   367  		StartCursor:     want[0].Cursor().Encode(),
   368  		EndCursor:       want[2].Cursor().Encode(),
   369  	}, pageInfo)
   370  }
   371  
   372  func testERC20MultiSigAddedEventPaginationNoPaginationNewestFirst(t *testing.T) {
   373  	ctx := tempTransaction(t)
   374  
   375  	es, events, _ := setupERC20MultiSigEventStorePaginationTests(t, ctx)
   376  	pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, true)
   377  	require.NoError(t, err)
   378  
   379  	validator := "fc677151d0c93726"
   380  	got, pageInfo, err := es.GetAddedEvents(ctx, validator, "", nil, nil, pagination)
   381  	require.NoError(t, err)
   382  	want := entities.ReverseSlice(events[:10])
   383  	assert.Equal(t, want, got)
   384  	assert.Equal(t, entities.PageInfo{
   385  		HasNextPage:     false,
   386  		HasPreviousPage: false,
   387  		StartCursor:     want[0].Cursor().Encode(),
   388  		EndCursor:       want[9].Cursor().Encode(),
   389  	}, pageInfo)
   390  }
   391  
   392  func testERC20MultiSigAddedEventPaginationFirstNewestFirst(t *testing.T) {
   393  	ctx := tempTransaction(t)
   394  
   395  	es, events, _ := setupERC20MultiSigEventStorePaginationTests(t, ctx)
   396  	first := int32(3)
   397  	pagination, err := entities.NewCursorPagination(&first, nil, nil, nil, true)
   398  	require.NoError(t, err)
   399  
   400  	validator := "fc677151d0c93726"
   401  	got, pageInfo, err := es.GetAddedEvents(ctx, validator, "", nil, nil, pagination)
   402  	require.NoError(t, err)
   403  	want := entities.ReverseSlice(events[:10])[:3]
   404  	assert.Equal(t, want, got)
   405  	assert.Equal(t, entities.PageInfo{
   406  		HasNextPage:     true,
   407  		HasPreviousPage: false,
   408  		StartCursor:     want[0].Cursor().Encode(),
   409  		EndCursor:       want[2].Cursor().Encode(),
   410  	}, pageInfo)
   411  }
   412  
   413  func testERC20MultiSigAddedEventPaginationLastNewestFirst(t *testing.T) {
   414  	ctx := tempTransaction(t)
   415  
   416  	es, events, _ := setupERC20MultiSigEventStorePaginationTests(t, ctx)
   417  	last := int32(3)
   418  	pagination, err := entities.NewCursorPagination(nil, nil, &last, nil, true)
   419  	require.NoError(t, err)
   420  
   421  	validator := "fc677151d0c93726"
   422  	got, pageInfo, err := es.GetAddedEvents(ctx, validator, "", nil, nil, pagination)
   423  	require.NoError(t, err)
   424  	want := entities.ReverseSlice(events[:10])[7:]
   425  	assert.Equal(t, want, got)
   426  	assert.Equal(t, entities.PageInfo{
   427  		HasNextPage:     false,
   428  		HasPreviousPage: true,
   429  		StartCursor:     want[0].Cursor().Encode(),
   430  		EndCursor:       want[2].Cursor().Encode(),
   431  	}, pageInfo)
   432  }
   433  
   434  func testERC20MultiSigAddedEventPaginationFirstAfterNewestFirst(t *testing.T) {
   435  	ctx := tempTransaction(t)
   436  
   437  	es, events, _ := setupERC20MultiSigEventStorePaginationTests(t, ctx)
   438  	first := int32(3)
   439  	after := events[7].Cursor().Encode()
   440  	pagination, err := entities.NewCursorPagination(&first, &after, nil, nil, true)
   441  	require.NoError(t, err)
   442  
   443  	validator := "fc677151d0c93726"
   444  	got, pageInfo, err := es.GetAddedEvents(ctx, validator, "", nil, nil, pagination)
   445  	require.NoError(t, err)
   446  	want := entities.ReverseSlice(events[:10])[3:6]
   447  	assert.Equal(t, want, got)
   448  	assert.Equal(t, entities.PageInfo{
   449  		HasNextPage:     true,
   450  		HasPreviousPage: true,
   451  		StartCursor:     want[0].Cursor().Encode(),
   452  		EndCursor:       want[2].Cursor().Encode(),
   453  	}, pageInfo)
   454  }
   455  
   456  func testERC20MultiSigAddedEventPaginationLastBeforeNewestFirst(t *testing.T) {
   457  	ctx := tempTransaction(t)
   458  
   459  	es, events, _ := setupERC20MultiSigEventStorePaginationTests(t, ctx)
   460  	last := int32(3)
   461  	before := events[2].Cursor().Encode()
   462  	pagination, err := entities.NewCursorPagination(nil, nil, &last, &before, true)
   463  	require.NoError(t, err)
   464  
   465  	validator := "fc677151d0c93726"
   466  	got, pageInfo, err := es.GetAddedEvents(ctx, validator, "", nil, nil, pagination)
   467  	require.NoError(t, err)
   468  	want := entities.ReverseSlice(events[:10])[4:7]
   469  	assert.Equal(t, want, got)
   470  	assert.Equal(t, entities.PageInfo{
   471  		HasNextPage:     true,
   472  		HasPreviousPage: true,
   473  		StartCursor:     want[0].Cursor().Encode(),
   474  		EndCursor:       want[2].Cursor().Encode(),
   475  	}, pageInfo)
   476  }
   477  
   478  func testERC20MultiSigRemovedEventPaginationNoPagination(t *testing.T) {
   479  	ctx := tempTransaction(t)
   480  
   481  	es, events, submitter := setupERC20MultiSigEventStorePaginationTests(t, ctx)
   482  	pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, false)
   483  	require.NoError(t, err)
   484  
   485  	validator := "fc677151d0c93726"
   486  	got, pageInfo, err := es.GetRemovedEvents(ctx, validator, submitter, nil, nil, pagination)
   487  	require.NoError(t, err)
   488  	want := events[10:]
   489  	assert.Equal(t, want, got)
   490  	assert.Equal(t, entities.PageInfo{
   491  		HasNextPage:     false,
   492  		HasPreviousPage: false,
   493  		StartCursor:     want[0].Cursor().Encode(),
   494  		EndCursor:       want[9].Cursor().Encode(),
   495  	}, pageInfo)
   496  }
   497  
   498  func testERC20MultiSigRemovedEventPaginationFirst(t *testing.T) {
   499  	ctx := tempTransaction(t)
   500  
   501  	es, events, submitter := setupERC20MultiSigEventStorePaginationTests(t, ctx)
   502  	first := int32(3)
   503  	pagination, err := entities.NewCursorPagination(&first, nil, nil, nil, false)
   504  	require.NoError(t, err)
   505  
   506  	validator := "fc677151d0c93726"
   507  	got, pageInfo, err := es.GetRemovedEvents(ctx, validator, submitter, nil, nil, pagination)
   508  	require.NoError(t, err)
   509  	want := events[10:13]
   510  	assert.Equal(t, want, got)
   511  	assert.Equal(t, entities.PageInfo{
   512  		HasNextPage:     true,
   513  		HasPreviousPage: false,
   514  		StartCursor:     want[0].Cursor().Encode(),
   515  		EndCursor:       want[2].Cursor().Encode(),
   516  	}, pageInfo)
   517  }
   518  
   519  func testERC20MultiSigRemovedEventPaginationLast(t *testing.T) {
   520  	ctx := tempTransaction(t)
   521  
   522  	es, events, submitter := setupERC20MultiSigEventStorePaginationTests(t, ctx)
   523  	last := int32(3)
   524  	pagination, err := entities.NewCursorPagination(nil, nil, &last, nil, false)
   525  	require.NoError(t, err)
   526  
   527  	validator := "fc677151d0c93726"
   528  	got, pageInfo, err := es.GetRemovedEvents(ctx, validator, submitter, nil, nil, pagination)
   529  	require.NoError(t, err)
   530  	want := events[17:]
   531  	assert.Equal(t, want, got)
   532  	assert.Equal(t, entities.PageInfo{
   533  		HasNextPage:     false,
   534  		HasPreviousPage: true,
   535  		StartCursor:     want[0].Cursor().Encode(),
   536  		EndCursor:       want[2].Cursor().Encode(),
   537  	}, pageInfo)
   538  }
   539  
   540  func testERC20MultiSigRemovedEventPaginationFirstAfter(t *testing.T) {
   541  	ctx := tempTransaction(t)
   542  
   543  	es, events, submitter := setupERC20MultiSigEventStorePaginationTests(t, ctx)
   544  	first := int32(3)
   545  	after := events[12].Cursor().Encode()
   546  	pagination, err := entities.NewCursorPagination(&first, &after, nil, nil, false)
   547  	require.NoError(t, err)
   548  
   549  	validator := "fc677151d0c93726"
   550  	got, pageInfo, err := es.GetRemovedEvents(ctx, validator, submitter, nil, nil, pagination)
   551  	require.NoError(t, err)
   552  	want := events[13:16]
   553  	assert.Equal(t, want, got)
   554  	assert.Equal(t, entities.PageInfo{
   555  		HasNextPage:     true,
   556  		HasPreviousPage: true,
   557  		StartCursor:     want[0].Cursor().Encode(),
   558  		EndCursor:       want[2].Cursor().Encode(),
   559  	}, pageInfo)
   560  }
   561  
   562  func testERC20MultiSigRemovedEventPaginationLastBefore(t *testing.T) {
   563  	ctx := tempTransaction(t)
   564  
   565  	es, events, submitter := setupERC20MultiSigEventStorePaginationTests(t, ctx)
   566  	last := int32(3)
   567  	before := events[17].Cursor().Encode()
   568  	pagination, err := entities.NewCursorPagination(nil, nil, &last, &before, false)
   569  	require.NoError(t, err)
   570  
   571  	validator := "fc677151d0c93726"
   572  	got, pageInfo, err := es.GetRemovedEvents(ctx, validator, submitter, nil, nil, pagination)
   573  	require.NoError(t, err)
   574  	want := events[14:17]
   575  	assert.Equal(t, want, got)
   576  	assert.Equal(t, entities.PageInfo{
   577  		HasNextPage:     true,
   578  		HasPreviousPage: true,
   579  		StartCursor:     want[0].Cursor().Encode(),
   580  		EndCursor:       want[2].Cursor().Encode(),
   581  	}, pageInfo)
   582  }
   583  
   584  func testERC20MultiSigRemovedEventPaginationNoPaginationNewestFirst(t *testing.T) {
   585  	ctx := tempTransaction(t)
   586  
   587  	es, events, submitter := setupERC20MultiSigEventStorePaginationTests(t, ctx)
   588  	pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, true)
   589  	require.NoError(t, err)
   590  
   591  	validator := "fc677151d0c93726"
   592  	got, pageInfo, err := es.GetRemovedEvents(ctx, validator, submitter, nil, nil, pagination)
   593  	require.NoError(t, err)
   594  	want := entities.ReverseSlice(events[10:])
   595  	assert.Equal(t, want, got)
   596  	assert.Equal(t, entities.PageInfo{
   597  		HasNextPage:     false,
   598  		HasPreviousPage: false,
   599  		StartCursor:     want[0].Cursor().Encode(),
   600  		EndCursor:       want[9].Cursor().Encode(),
   601  	}, pageInfo)
   602  }
   603  
   604  func testERC20MultiSigRemovedEventPaginationFirstNewestFirst(t *testing.T) {
   605  	ctx := tempTransaction(t)
   606  
   607  	es, events, submitter := setupERC20MultiSigEventStorePaginationTests(t, ctx)
   608  	first := int32(3)
   609  	pagination, err := entities.NewCursorPagination(&first, nil, nil, nil, true)
   610  	require.NoError(t, err)
   611  
   612  	validator := "fc677151d0c93726"
   613  	got, pageInfo, err := es.GetRemovedEvents(ctx, validator, submitter, nil, nil, pagination)
   614  	require.NoError(t, err)
   615  	want := entities.ReverseSlice(events[10:])[:3]
   616  	assert.Equal(t, want, got)
   617  	assert.Equal(t, entities.PageInfo{
   618  		HasNextPage:     true,
   619  		HasPreviousPage: false,
   620  		StartCursor:     want[0].Cursor().Encode(),
   621  		EndCursor:       want[2].Cursor().Encode(),
   622  	}, pageInfo)
   623  }
   624  
   625  func testERC20MultiSigRemovedEventPaginationLastNewestFirst(t *testing.T) {
   626  	ctx := tempTransaction(t)
   627  
   628  	es, events, submitter := setupERC20MultiSigEventStorePaginationTests(t, ctx)
   629  	last := int32(3)
   630  	pagination, err := entities.NewCursorPagination(nil, nil, &last, nil, true)
   631  	require.NoError(t, err)
   632  
   633  	validator := "fc677151d0c93726"
   634  	got, pageInfo, err := es.GetRemovedEvents(ctx, validator, submitter, nil, nil, pagination)
   635  	require.NoError(t, err)
   636  	want := entities.ReverseSlice(events[10:])[7:]
   637  	assert.Equal(t, want, got)
   638  	assert.Equal(t, entities.PageInfo{
   639  		HasNextPage:     false,
   640  		HasPreviousPage: true,
   641  		StartCursor:     want[0].Cursor().Encode(),
   642  		EndCursor:       want[2].Cursor().Encode(),
   643  	}, pageInfo)
   644  }
   645  
   646  func testERC20MultiSigRemovedEventPaginationFirstAfterNewestFirst(t *testing.T) {
   647  	ctx := tempTransaction(t)
   648  
   649  	es, events, submitter := setupERC20MultiSigEventStorePaginationTests(t, ctx)
   650  	first := int32(3)
   651  	after := events[17].Cursor().Encode()
   652  	pagination, err := entities.NewCursorPagination(&first, &after, nil, nil, true)
   653  	require.NoError(t, err)
   654  
   655  	validator := "fc677151d0c93726"
   656  	got, pageInfo, err := es.GetRemovedEvents(ctx, validator, submitter, nil, nil, pagination)
   657  	require.NoError(t, err)
   658  	want := entities.ReverseSlice(events[10:])[3:6]
   659  	assert.Equal(t, want, got)
   660  	assert.Equal(t, entities.PageInfo{
   661  		HasNextPage:     true,
   662  		HasPreviousPage: true,
   663  		StartCursor:     want[0].Cursor().Encode(),
   664  		EndCursor:       want[2].Cursor().Encode(),
   665  	}, pageInfo)
   666  }
   667  
   668  func testERC20MultiSigRemovedEventPaginationLastBeforeNewestFirst(t *testing.T) {
   669  	ctx := tempTransaction(t)
   670  
   671  	es, events, submitter := setupERC20MultiSigEventStorePaginationTests(t, ctx)
   672  	last := int32(3)
   673  	before := events[12].Cursor().Encode()
   674  	pagination, err := entities.NewCursorPagination(nil, nil, &last, &before, true)
   675  	require.NoError(t, err)
   676  
   677  	validator := "fc677151d0c93726"
   678  	got, pageInfo, err := es.GetRemovedEvents(ctx, validator, submitter, nil, nil, pagination)
   679  	require.NoError(t, err)
   680  	want := entities.ReverseSlice(events[10:])[4:7]
   681  	assert.Equal(t, want, got)
   682  	assert.Equal(t, entities.PageInfo{
   683  		HasNextPage:     true,
   684  		HasPreviousPage: true,
   685  		StartCursor:     want[0].Cursor().Encode(),
   686  		EndCursor:       want[2].Cursor().Encode(),
   687  	}, pageInfo)
   688  }
   689  
   690  func setupERC20MultiSigEventStorePaginationTests(t *testing.T, ctx context.Context) (*sqlstore.ERC20MultiSigSignerEvent, []entities.ERC20MultiSigSignerEvent, string) {
   691  	t.Helper()
   692  
   693  	es := sqlstore.NewERC20MultiSigSignerEvent(connectionSource)
   694  
   695  	validator := "fc677151d0c93726"
   696  	submitter := generateEthereumAddress()
   697  
   698  	events := make([]entities.ERC20MultiSigSignerEvent, 20)
   699  	for i := 0; i < 10; i++ {
   700  		e := getTestSignerEvent(t, fmt.Sprintf("deadbeef%02d", i+1), validator, submitter, fmt.Sprintf("%d", i+1), true)
   701  		err := es.Add(ctx, e)
   702  		require.NoError(t, err)
   703  		events[i] = *e
   704  	}
   705  
   706  	for i := 0; i < 10; i++ {
   707  		e := getTestSignerEvent(t, fmt.Sprintf("deadbeef%02d", 10+i+1), validator, submitter, fmt.Sprintf("%d", 10+i+1), false)
   708  		err := es.Add(ctx, e)
   709  		require.NoError(t, err)
   710  		events[10+i] = *e
   711  	}
   712  
   713  	return es, events, submitter
   714  }