code.vegaprotocol.io/vega@v0.79.0/datanode/sqlstore/blocks_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 "encoding/hex" 21 "testing" 22 "time" 23 24 "code.vegaprotocol.io/vega/datanode/entities" 25 "code.vegaprotocol.io/vega/datanode/sqlstore" 26 27 "github.com/stretchr/testify/assert" 28 "github.com/stretchr/testify/require" 29 ) 30 31 type testBlockSource struct { 32 blockStore *sqlstore.Blocks 33 blockTime time.Time 34 } 35 36 func (bs *testBlockSource) getNextBlock(t *testing.T, ctx context.Context) entities.Block { 37 t.Helper() 38 bs.blockTime = bs.blockTime.Add(1 * time.Second) 39 return addTestBlockForTime(t, ctx, bs.blockStore, bs.blockTime) 40 } 41 42 func addTestBlock(t *testing.T, ctx context.Context, bs *sqlstore.Blocks) entities.Block { 43 t.Helper() 44 return addTestBlockForTime(t, ctx, bs, time.Now()) 45 } 46 47 func addTestBlockForTime(t *testing.T, ctx context.Context, bs *sqlstore.Blocks, vegaTime time.Time) entities.Block { 48 t.Helper() 49 return addTestBlockForHeightAndTime(t, ctx, bs, 2, vegaTime) 50 } 51 52 func addTestBlockForHeightAndTime(t *testing.T, ctx context.Context, bs *sqlstore.Blocks, height int64, vegaTime time.Time) entities.Block { 53 t.Helper() 54 55 hash, err := hex.DecodeString("deadbeef") 56 require.NoError(t, err) 57 58 // Postgres only stores timestamps in microsecond resolution 59 block := entities.Block{ 60 VegaTime: vegaTime.Truncate(time.Microsecond), 61 Height: height, 62 Hash: hash, 63 } 64 65 require.NoError(t, bs.Add(ctx, block)) 66 67 return block 68 } 69 70 func TestBlock(t *testing.T) { 71 ctx := tempTransaction(t) 72 73 bs := sqlstore.NewBlocks(connectionSource) 74 75 // See how many we have right now (it's possible that other tests added some) 76 blocks, err := bs.GetAll(ctx) 77 assert.NoError(t, err) 78 blocksLen := len(blocks) 79 80 block1 := addTestBlock(t, ctx, bs) 81 82 // Query and check we've got back a block the same as the one we put in 83 blocks, err = bs.GetAll(ctx) 84 assert.NoError(t, err) 85 assert.Len(t, blocks, blocksLen+1) 86 assert.Equal(t, blocks[0], block1) 87 88 // Add it again, we should get a primary key violation [do this last as it invalidates tx] 89 err = bs.Add(ctx, block1) 90 assert.Error(t, err) 91 } 92 93 func TestGetLastBlock(t *testing.T) { 94 ctx := tempTransaction(t) 95 96 bs := sqlstore.NewBlocks(connectionSource) 97 98 now := time.Now() 99 100 addTestBlockForTime(t, ctx, bs, now) 101 block2 := addTestBlockForTime(t, ctx, bs, now.Add(1*time.Second)) 102 103 // Query the last block 104 block, err := bs.GetLastBlock(ctx) 105 assert.NoError(t, err) 106 assert.Equal(t, block2, block) 107 } 108 109 func TestGetOldestHistoryBlock(t *testing.T) { 110 ctx := tempTransaction(t) 111 112 bs := sqlstore.NewBlocks(connectionSource) 113 114 now := time.Now() 115 116 block1 := addTestBlockForTime(t, ctx, bs, now) 117 addTestBlockForTime(t, ctx, bs, now.Add(1*time.Second)) 118 119 // Query the first block 120 block, err := bs.GetOldestHistoryBlock(ctx) 121 assert.NoError(t, err) 122 assert.Equal(t, block1, block) 123 } 124 125 func TestGetOldestHistoryBlockWhenNoHistoryBlocks(t *testing.T) { 126 ctx := tempTransaction(t) 127 128 bs := sqlstore.NewBlocks(connectionSource) 129 // Query the first block 130 _, err := bs.GetOldestHistoryBlock(ctx) 131 assert.Equal(t, entities.ErrNotFound, err) 132 } 133 134 func TestGetLastBlockAfterRecovery(t *testing.T) { 135 ctx := tempTransaction(t) 136 137 bs := sqlstore.NewBlocks(connectionSource) 138 139 now := time.Now() 140 141 addTestBlockForTime(t, ctx, bs, now) 142 block2 := addTestBlockForTime(t, ctx, bs, now.Add(1*time.Second)) 143 144 // Recreate the store 145 bs = sqlstore.NewBlocks(connectionSource) 146 147 // Query the last block 148 block, err := bs.GetLastBlock(ctx) 149 assert.NoError(t, err) 150 assert.Equal(t, block2, block) 151 } 152 153 func TestGetLastBlockWhenNoBlocks(t *testing.T) { 154 ctx := tempTransaction(t) 155 156 bs := sqlstore.NewBlocks(connectionSource) 157 158 // Query the last block 159 _, err := bs.GetLastBlock(ctx) 160 assert.Equal(t, entities.ErrNotFound, err) 161 }