code.vegaprotocol.io/vega@v0.79.0/datanode/sqlstore/ethereum_key_rotations_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  
    22  	"code.vegaprotocol.io/vega/datanode/entities"
    23  	"code.vegaprotocol.io/vega/datanode/sqlstore"
    24  	vgcrypto "code.vegaprotocol.io/vega/libs/crypto"
    25  
    26  	"github.com/stretchr/testify/assert"
    27  	"github.com/stretchr/testify/require"
    28  )
    29  
    30  func randomEthAddress() entities.EthereumAddress {
    31  	hash256bit := vgcrypto.RandomHash()
    32  	hash160bit := hash256bit[:40]
    33  	return entities.EthereumAddress("0x" + hash160bit)
    34  }
    35  
    36  func addTestEthereumKeyRotation(t *testing.T,
    37  	ctx context.Context,
    38  	store *sqlstore.EthereumKeyRotations,
    39  	block entities.Block,
    40  	seqNum uint64,
    41  ) entities.EthereumKeyRotation {
    42  	t.Helper()
    43  	kr := entities.EthereumKeyRotation{
    44  		NodeID:      entities.NodeID("beef"),
    45  		OldAddress:  randomEthAddress(),
    46  		NewAddress:  randomEthAddress(),
    47  		VegaTime:    block.VegaTime,
    48  		BlockHeight: 42,
    49  		SeqNum:      seqNum,
    50  		TxHash:      generateTxHash(),
    51  	}
    52  	err := store.Add(ctx, kr)
    53  	require.NoError(t, err)
    54  	return kr
    55  }
    56  
    57  func TestEthereumKeyRotations(t *testing.T) {
    58  	ctx := tempTransaction(t)
    59  
    60  	blockStore := sqlstore.NewBlocks(connectionSource)
    61  	block := addTestBlock(t, ctx, blockStore)
    62  	nodeStore := sqlstore.NewNode(connectionSource)
    63  	node := addTestNode(t, ctx, nodeStore, block, "beef")
    64  
    65  	krStore := sqlstore.NewEthereumKeyRotations(connectionSource)
    66  
    67  	var kr entities.EthereumKeyRotation
    68  	t.Run("adding", func(t *testing.T) {
    69  		kr = addTestEthereumKeyRotation(t, ctx, krStore, block, 0)
    70  	})
    71  
    72  	t.Run("GetByTxHash", func(t *testing.T) {
    73  		fetched, err := krStore.GetByTxHash(ctx, kr.TxHash)
    74  		require.NoError(t, err)
    75  		require.Len(t, fetched, 1)
    76  		assert.Equal(t, fetched[0], kr)
    77  	})
    78  
    79  	t.Run("fetching all", func(t *testing.T) {
    80  		fetched, _, err := krStore.List(ctx, entities.NodeID(""), entities.CursorPagination{})
    81  		require.NoError(t, err)
    82  		require.Len(t, fetched, 1)
    83  		assert.Equal(t, fetched[0], kr)
    84  	})
    85  
    86  	t.Run("fetching all by node", func(t *testing.T) {
    87  		fetched, _, err := krStore.List(ctx, node.ID, entities.CursorPagination{})
    88  		require.NoError(t, err)
    89  		require.Len(t, fetched, 1)
    90  		assert.Equal(t, fetched[0], kr)
    91  	})
    92  
    93  	t.Run("fetching all by bad node", func(t *testing.T) {
    94  		fetched, _, err := krStore.List(ctx, entities.NodeID("baad"), entities.CursorPagination{})
    95  		require.NoError(t, err)
    96  		require.Len(t, fetched, 0)
    97  	})
    98  
    99  	t.Run("adding more", func(t *testing.T) {
   100  		for i := 0; i < 10; i++ {
   101  			addTestEthereumKeyRotation(t, ctx, krStore, block, uint64(i+1))
   102  		}
   103  	})
   104  
   105  	t.Run("with pagination", func(t *testing.T) {
   106  		five := int32(5)
   107  		pagination, err := entities.NewCursorPagination(&five, nil, nil, nil, true)
   108  		require.NoError(t, err)
   109  
   110  		fetched, pageInfo, err := krStore.List(ctx, entities.NodeID(""), pagination)
   111  		require.NoError(t, err)
   112  		require.Len(t, fetched, 5)
   113  		require.True(t, pageInfo.HasNextPage)
   114  
   115  		t.Run("using cursor paging forwards", func(t *testing.T) {
   116  			pagination, err := entities.NewCursorPagination(&five, &pageInfo.StartCursor, nil, nil, true)
   117  			require.NoError(t, err)
   118  
   119  			fetchedAgain, pageInfo, err := krStore.List(ctx, entities.NodeID(""), pagination)
   120  			require.NoError(t, err)
   121  			require.Len(t, fetched, 5)
   122  			require.True(t, pageInfo.HasNextPage)
   123  			// Passing a cursor gets the next element
   124  			require.Equal(t, fetched[1:5], fetchedAgain[0:4])
   125  		})
   126  
   127  		t.Run("using cursor paging back", func(t *testing.T) {
   128  			pagination, err := entities.NewCursorPagination(nil, nil, &five, &pageInfo.EndCursor, true)
   129  			require.NoError(t, err)
   130  
   131  			fetchedAgain, pageInfo, err := krStore.List(ctx, entities.NodeID(""), pagination)
   132  			require.NoError(t, err)
   133  			// The last one won't be included
   134  			require.Len(t, fetchedAgain, 4)
   135  			require.True(t, pageInfo.HasNextPage)
   136  			// But we should get the same 4 first guys
   137  			require.Equal(t, fetched[0:4], fetchedAgain[0:4])
   138  		})
   139  	})
   140  }