code.vegaprotocol.io/vega@v0.79.0/datanode/sqlstore/accounts_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  	"encoding/hex"
    20  	"testing"
    21  
    22  	"code.vegaprotocol.io/vega/core/types"
    23  	"code.vegaprotocol.io/vega/datanode/entities"
    24  	"code.vegaprotocol.io/vega/datanode/sqlstore"
    25  	"code.vegaprotocol.io/vega/datanode/sqlstore/helpers"
    26  
    27  	"github.com/shopspring/decimal"
    28  	"github.com/stretchr/testify/assert"
    29  	"github.com/stretchr/testify/require"
    30  )
    31  
    32  func TestAccount(t *testing.T) {
    33  	ctx := tempTransaction(t)
    34  
    35  	blockStore := sqlstore.NewBlocks(connectionSource)
    36  	assetStore := sqlstore.NewAssets(connectionSource)
    37  	accountStore := sqlstore.NewAccounts(connectionSource)
    38  	partyStore := sqlstore.NewParties(connectionSource)
    39  	balanceStore := sqlstore.NewBalances(connectionSource)
    40  
    41  	// Account store should be empty to begin with
    42  	accounts, err := accountStore.GetAll(ctx)
    43  	assert.NoError(t, err)
    44  	assert.Empty(t, accounts)
    45  
    46  	// Add an account
    47  	block := addTestBlock(t, ctx, blockStore)
    48  	asset := addTestAsset(t, ctx, assetStore, block)
    49  	party := addTestParty(t, ctx, partyStore, block)
    50  	accTxHash := entities.TxHash(hex.EncodeToString([]byte("account_hash_1")))
    51  	account := helpers.AddTestAccountWithTxHash(t, ctx, accountStore, party, asset, types.AccountTypeInsurance, block, accTxHash)
    52  
    53  	// Add a second account, same asset - different party
    54  	party2 := addTestParty(t, ctx, partyStore, block)
    55  
    56  	accTxHash2 := entities.TxHash(hex.EncodeToString([]byte("account_hash_2")))
    57  	account2 := helpers.AddTestAccountWithTxHash(t, ctx, accountStore, party2, asset, types.AccountTypeInsurance, block, accTxHash2)
    58  
    59  	// Add a couple of test balances
    60  	balTxHash := txHashFromString("balance_hash_1")
    61  	balTxHash2 := txHashFromString("balance_hash_2")
    62  	addTestBalance(t, balanceStore, block, account, 10, balTxHash)
    63  	addTestBalance(t, balanceStore, block, account2, 100, balTxHash2)
    64  	_, err = balanceStore.Flush(ctx)
    65  	require.NoError(t, err)
    66  
    67  	t.Run("check we get same info back as we put in", func(t *testing.T) {
    68  		fetchedAccount, err := accountStore.GetByID(ctx, account.ID)
    69  		require.NoError(t, err)
    70  		assert.Equal(t, account, fetchedAccount)
    71  	})
    72  
    73  	t.Run("query by asset", func(t *testing.T) {
    74  		// Query by asset, should have 2 accounts
    75  		filter := entities.AccountFilter{AssetID: asset.ID}
    76  		accs, err := accountStore.Query(ctx, filter)
    77  		require.NoError(t, err)
    78  		assert.Len(t, accs, 2)
    79  	})
    80  
    81  	t.Run("query by asset + party", func(t *testing.T) {
    82  		// Query by asset + party should have only 1 account
    83  		filter := entities.AccountFilter{AssetID: asset.ID, PartyIDs: []entities.PartyID{party2.ID}}
    84  		accs, err := accountStore.Query(ctx, filter)
    85  		require.NoError(t, err)
    86  		assert.Len(t, accs, 1)
    87  		assert.Equal(t, accs[0], account2)
    88  	})
    89  
    90  	t.Run("query by asset + invalid type", func(t *testing.T) {
    91  		// Query by asset + invalid type, should have 0 accounts
    92  		filter := entities.AccountFilter{AssetID: asset.ID, AccountTypes: []types.AccountType{100}}
    93  		accs, err := accountStore.Query(ctx, filter)
    94  		require.NoError(t, err)
    95  		assert.Len(t, accs, 0)
    96  	})
    97  
    98  	t.Run("query by asset + invalid market", func(t *testing.T) {
    99  		// Query by asset + invalid market, should have 0 accounts
   100  		filter := entities.AccountFilter{AssetID: asset.ID, MarketIDs: []entities.MarketID{entities.MarketID("ffff")}}
   101  		accs, err := accountStore.Query(ctx, filter)
   102  		require.NoError(t, err)
   103  		assert.Len(t, accs, 0)
   104  	})
   105  
   106  	t.Run("get by tx hash", func(t *testing.T) {
   107  		accounts, err := accountStore.GetByTxHash(ctx, accTxHash)
   108  		require.NoError(t, err)
   109  		require.Len(t, accounts, 1)
   110  		assert.Equal(t, accounts[0], account)
   111  
   112  		accounts2, err := accountStore.GetByTxHash(ctx, accTxHash2)
   113  		require.NoError(t, err)
   114  		require.Len(t, accounts2, 1)
   115  		assert.Equal(t, accounts2[0], account2)
   116  	})
   117  
   118  	accBal1 := entities.AccountBalance{Account: &account, Balance: decimal.NewFromInt(10)}
   119  	accBal2 := entities.AccountBalance{Account: &account2, Balance: decimal.NewFromInt(100)}
   120  
   121  	t.Run("query account balance", func(t *testing.T) {
   122  		filter := entities.AccountFilter{AssetID: asset.ID, MarketIDs: []entities.MarketID{account.MarketID}}
   123  		balances, pageInfo, err := accountStore.QueryBalances(ctx, filter, entities.CursorPagination{})
   124  		require.NoError(t, err)
   125  		require.Len(t, balances, 1)
   126  		require.True(t, accBal1.Equal(balances[0]))
   127  		require.False(t, pageInfo.HasNextPage)
   128  		require.False(t, pageInfo.HasPreviousPage)
   129  	})
   130  
   131  	t.Run("get balances by tx hash", func(t *testing.T) {
   132  		balances1, err := accountStore.GetBalancesByTxHash(ctx, balTxHash)
   133  		require.NoError(t, err)
   134  		require.Len(t, balances1, 1)
   135  		require.True(t, accBal1.Equal(balances1[0]))
   136  
   137  		balances2, err := accountStore.GetBalancesByTxHash(ctx, balTxHash2)
   138  		require.NoError(t, err)
   139  		require.Len(t, balances2, 1)
   140  		require.True(t, accBal2.Equal(balances2[0]))
   141  	})
   142  
   143  	one := int32(1)
   144  	noFilter := entities.AccountFilter{}
   145  	firstPage, err := entities.NewCursorPagination(&one, nil, nil, nil, false)
   146  	require.NoError(t, err)
   147  
   148  	var cursor string
   149  
   150  	t.Run("query account balance first page and last page", func(t *testing.T) {
   151  		balances, pageInfo, err := accountStore.QueryBalances(ctx, noFilter, firstPage)
   152  		require.NoError(t, err)
   153  		require.Len(t, balances, 1)
   154  
   155  		var lastPageAccBal entities.AccountBalance
   156  		if accBal1.Equal(balances[0]) {
   157  			lastPageAccBal = accBal2
   158  		} else {
   159  			lastPageAccBal = accBal1
   160  		}
   161  
   162  		require.True(t, accBal1.Equal(balances[0]) || accBal2.Equal(balances[0]))
   163  		require.True(t, pageInfo.HasNextPage)
   164  		require.False(t, pageInfo.HasPreviousPage)
   165  		cursor = pageInfo.EndCursor
   166  
   167  		lastPage, err := entities.NewCursorPagination(&one, &cursor, nil, nil, false)
   168  		require.NoError(t, err)
   169  
   170  		balances, pageInfo, err = accountStore.QueryBalances(ctx, noFilter, lastPage)
   171  		require.NoError(t, err)
   172  		require.Len(t, balances, 1)
   173  		require.True(t, lastPageAccBal.Equal(balances[0]))
   174  		require.False(t, pageInfo.HasNextPage)
   175  		require.True(t, pageInfo.HasPreviousPage)
   176  	})
   177  
   178  	// Do this last as it will abort the transaction
   179  	t.Run("fails if accounts are not unique", func(t *testing.T) {
   180  		err = accountStore.Add(ctx, &account)
   181  		assert.Error(t, err)
   182  	})
   183  }