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 }