public unsafe void RavenDB_15975() { using (var options = StorageEnvironmentOptions.ForPath(DataDir)) { options.Encryption.MasterKey = Sodium.GenerateRandomBuffer((int)Sodium.crypto_aead_xchacha20poly1305_ietf_keybytes()); using (var innerPager = LinuxTestUtils.GetNewPager(options, DataDir, "Raven.Voron")) { AbstractPager cryptoPager; using (cryptoPager = new CryptoPager(innerPager)) { using (var tx = new TempPagerTransaction(isWriteTransaction: true)) { var overflowSize = 4 * Constants.Storage.PageSize + 100; cryptoPager.EnsureContinuous(26, 5); var pagePointer = cryptoPager.AcquirePagePointerForNewPage(tx, 26, 5); var header = (PageHeader *)pagePointer; header->PageNumber = 26; header->Flags = PageFlags.Overflow; header->OverflowSize = overflowSize; Memory.Set(pagePointer + PageHeader.SizeOf, (byte)'X', overflowSize); } using (var tx = new TempPagerTransaction()) { var pagePointer = cryptoPager.AcquirePagePointer(tx, 26); // Making sure that the data was decrypted and still holds those 'X' chars Assert.True(pagePointer[PageHeader.SizeOf] == 'X'); Assert.True(pagePointer[666] == 'X'); Assert.True(pagePointer[1039] == 'X'); } } } } }
public unsafe void WriteAndReadPageUsingCryptoPager() { using (var options = StorageEnvironmentOptions.ForPath(DataDir)) { options.Encryption.MasterKey = Sodium.GenerateRandomBuffer((int)Sodium.crypto_aead_xchacha20poly1305_ietf_keybytes()); using (var innerPager = LinuxTestUtils.GetNewPager(options, DataDir, "Raven.Voron")) { AbstractPager cryptoPager; using (cryptoPager = new CryptoPager(innerPager)) { using (var tx = new TempPagerTransaction(isWriteTransaction: true)) { cryptoPager.EnsureContinuous(17, 1); // We're gonna try to read and write to page 17 var pagePointer = cryptoPager.AcquirePagePointerForNewPage(tx, 17, 1); var header = (PageHeader *)pagePointer; header->PageNumber = 17; header->Flags = PageFlags.Single | PageFlags.FixedSizeTreePage; Memory.Set(pagePointer + PageHeader.SizeOf, (byte)'X', Constants.Storage.PageSize - PageHeader.SizeOf); } using (var tx = new TempPagerTransaction()) { var pagePointer = cryptoPager.AcquirePagePointer(tx, 17); // Making sure that the data was decrypted and still holds those 'X' chars Assert.True(pagePointer[PageHeader.SizeOf] == 'X'); Assert.True(pagePointer[666] == 'X'); Assert.True(pagePointer[1039] == 'X'); } } } } }
public unsafe void ValidatePageChecksumShouldDetectDataCorruption() { // Create some random data var treeNames = new List <string>(); var random = new Random(); var value1 = new byte[random.Next(1024 * 1024 * 2)]; var value2 = new byte[random.Next(1024 * 1024 * 2)]; random.NextBytes(value1); random.NextBytes(value2); const int treeCount = 5; const int recordCount = 6; using (var env = new StorageEnvironment(StorageEnvironmentOptions.ForPath(DataDir))) { env.Options.ManualFlushing = true; for (int i = 0; i < treeCount; i++) { using (var tx = env.WriteTransaction()) { string name = "tree/" + i; treeNames.Add(name); var tree = tx.CreateTree(name); for (int j = 0; j < recordCount; j++) { tree.Add(string.Format("{0}/items/{1}", name, j), j % 2 == 0 ? value1 : value2); } tx.Commit(); } } env.FlushLogToDataFile(); } // Lets corrupt something using (var options = StorageEnvironmentOptions.ForPath(DataDir)) using (var pager = LinuxTestUtils.GetNewPager(options, DataDir, "Raven.Voron")) using (var tempTX = new TempPagerTransaction()) { var writePtr = pager.AcquirePagePointer(tempTX, 2) + PageHeader.SizeOf + 43; // just some random place on page #2 for (byte i = 0; i < 8; i++) { writePtr[i] = i; } } // Now lets try to read it all back and hope we get an exception try { using (var env = new StorageEnvironment(StorageEnvironmentOptions.ForPath(DataDir))) { using (var tx = env.ReadTransaction()) { foreach (var treeName in treeNames) { var tree = tx.CreateTree(treeName); for (int i = 0; i < recordCount; i++) { var readResult = tree.Read(string.Format("{0}/items/{1}", treeName, i)); Assert.NotNull(readResult); if (i % 2 == 0) { var readBytes = new byte[value1.Length]; readResult.Reader.Read(readBytes, 0, readBytes.Length); } else { var readBytes = new byte[value2.Length]; readResult.Reader.Read(readBytes, 0, readBytes.Length); } } } } } } catch (Exception e) { Assert.True(e is InvalidOperationException || e is InvalidDataException); } }