code.vegaprotocol.io/vega@v0.79.0/core/snapshot/databases/metadata/level_db_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 metadata_test
    17  
    18  import (
    19  	"testing"
    20  
    21  	"code.vegaprotocol.io/vega/core/snapshot/databases/metadata"
    22  	"code.vegaprotocol.io/vega/paths"
    23  
    24  	tmtypes "github.com/cometbft/cometbft/abci/types"
    25  	"github.com/stretchr/testify/assert"
    26  	"github.com/stretchr/testify/require"
    27  )
    28  
    29  func TestLevelDBDatabase(t *testing.T) {
    30  	t.Run("Saving and loading snapshot metadata succeeds", testLevelDBDatabaseSavingAndLoadingSnapshotMetadataSucceeds)
    31  	t.Run("Finding a version by block height succeeds", testLevelDBDatabaseFindingVersionByBlockHeightSucceeds)
    32  	t.Run("Removing a version succeeds", testLevelDBDatabaseRemovingVersionSucceeds)
    33  }
    34  
    35  func testLevelDBDatabaseSavingAndLoadingSnapshotMetadataSucceeds(t *testing.T) {
    36  	db := newLevelDBDatabase(t)
    37  	defer func() {
    38  		// Ensure closing does not have problem of any kind.
    39  		require.NoError(t, db.Close())
    40  	}()
    41  
    42  	snapshotV1 := &tmtypes.Snapshot{Height: 1, Format: 2, Chunks: 7, Hash: []byte{1, 2}, Metadata: []byte{1}}
    43  	snapshotV2 := &tmtypes.Snapshot{Height: 2, Format: 2, Chunks: 7, Hash: []byte{2, 2}, Metadata: []byte{2}}
    44  
    45  	// Verifying a new database is empty.
    46  	assert.True(t, db.IsEmpty(), "the database should not contain data")
    47  
    48  	// Saving 2 snapshots to verify they are properly saved, and do not
    49  	// override each other.
    50  	require.NoError(t, db.Save(1, snapshotV1))
    51  	require.NoError(t, db.Save(2, snapshotV2))
    52  
    53  	// Verifying the database correctly states it's not empty when not.
    54  	assert.False(t, db.IsEmpty(), "the database should contain data")
    55  
    56  	// Verify both snapshot can be retrieve and match the originals.
    57  	loadedSnapshotV1, err := db.Load(1)
    58  	require.NoError(t, err)
    59  	assert.Equal(t, snapshotV1, loadedSnapshotV1)
    60  
    61  	loadedSnapshotV2, err := db.Load(2)
    62  	require.NoError(t, err)
    63  	assert.Equal(t, snapshotV2, loadedSnapshotV2)
    64  
    65  	// Removing the snapshots from the database.
    66  	require.NoError(t, db.Clear())
    67  
    68  	// Verifying the database correctly states it's empty when is.
    69  	assert.True(t, db.IsEmpty(), "the database should not contain data")
    70  
    71  	// Verify both snapshot can no longer be retrieved from the database.
    72  	loadedSnapshotV1AfterClear, err := db.Load(1)
    73  	assert.Error(t, err)
    74  	assert.Nil(t, loadedSnapshotV1AfterClear)
    75  
    76  	loadedSnapshotV2AfterClear, err := db.Load(2)
    77  	assert.Error(t, err)
    78  	assert.Nil(t, loadedSnapshotV2AfterClear)
    79  }
    80  
    81  func testLevelDBDatabaseFindingVersionByBlockHeightSucceeds(t *testing.T) {
    82  	db := newLevelDBDatabase(t)
    83  	defer func() {
    84  		// Ensure closing does not have problem of any kind.
    85  		require.NoError(t, db.Close())
    86  	}()
    87  
    88  	snapshotV1 := &tmtypes.Snapshot{Height: 1, Format: 2, Chunks: 7, Hash: []byte{1, 2}, Metadata: []byte{1}}
    89  	snapshotV2 := &tmtypes.Snapshot{Height: 2, Format: 2, Chunks: 7, Hash: []byte{2, 2}, Metadata: []byte{2}}
    90  
    91  	// Saving 2 snapshots.
    92  	require.NoError(t, db.Save(1, snapshotV1))
    93  	require.NoError(t, db.Save(2, snapshotV2))
    94  
    95  	// Looking for a height that has no match.
    96  	versionNotFound, err := db.FindVersionByBlockHeight(3)
    97  
    98  	require.NoError(t, err)
    99  	assert.Equal(t, int64(-1), versionNotFound)
   100  
   101  	// Looking for a height that has no match.
   102  	versionFound, err := db.FindVersionByBlockHeight(2)
   103  
   104  	require.NoError(t, err)
   105  	assert.Equal(t, int64(2), versionFound)
   106  }
   107  
   108  func testLevelDBDatabaseRemovingVersionSucceeds(t *testing.T) {
   109  	db := newLevelDBDatabase(t)
   110  	defer func() {
   111  		// Ensure closing does not have problem of any kind.
   112  		require.NoError(t, db.Close())
   113  	}()
   114  
   115  	snapshotV1 := &tmtypes.Snapshot{Height: 1, Format: 2, Chunks: 7, Hash: []byte{1, 2}, Metadata: []byte{1}}
   116  	snapshotV2 := &tmtypes.Snapshot{Height: 2, Format: 2, Chunks: 7, Hash: []byte{2, 3}, Metadata: []byte{2}}
   117  	snapshotV3 := &tmtypes.Snapshot{Height: 3, Format: 2, Chunks: 7, Hash: []byte{3, 4}, Metadata: []byte{3}}
   118  	snapshotV4 := &tmtypes.Snapshot{Height: 4, Format: 2, Chunks: 7, Hash: []byte{4, 5}, Metadata: []byte{4}}
   119  	snapshotV5 := &tmtypes.Snapshot{Height: 5, Format: 2, Chunks: 7, Hash: []byte{5, 6}, Metadata: []byte{5}}
   120  
   121  	// Saving 2 snapshots.
   122  	require.NoError(t, db.Save(1, snapshotV1))
   123  	require.NoError(t, db.Save(2, snapshotV2))
   124  	require.NoError(t, db.Save(3, snapshotV3))
   125  	require.NoError(t, db.Save(4, snapshotV4))
   126  	require.NoError(t, db.Save(5, snapshotV5))
   127  
   128  	// Deleting first snapshot
   129  	require.NoError(t, db.Delete(1))
   130  
   131  	// Looking for a height that has no match.
   132  	snapshotNotFound, err := db.Load(1)
   133  
   134  	require.Error(t, err)
   135  	assert.Nil(t, snapshotNotFound)
   136  
   137  	// Deleting first snapshot
   138  	require.NoError(t, db.DeleteRange(2, 5))
   139  
   140  	expectedDeletion := []int64{2, 3, 4}
   141  	for deletedVersion := range expectedDeletion {
   142  		snapshotNotFound, err = db.Load(int64(deletedVersion))
   143  
   144  		require.Error(t, err, "Version %d should have been deleted", deletedVersion)
   145  		assert.Nilf(t, snapshotNotFound, "Version %d should have been deleted", deletedVersion)
   146  	}
   147  
   148  	// Looking for a height that has no match.
   149  	versionFound, err := db.FindVersionByBlockHeight(5)
   150  
   151  	require.NoError(t, err)
   152  	assert.Equal(t, int64(5), versionFound)
   153  }
   154  
   155  func newLevelDBDatabase(t *testing.T) *metadata.LevelDBDatabase {
   156  	t.Helper()
   157  
   158  	db, err := metadata.NewLevelDBDatabase(paths.New(t.TempDir()))
   159  	require.NoError(t, err)
   160  
   161  	return db
   162  }