/// <summary> /// Compacts the block and transaction database by recreating the tables without the deleted references. /// </summary> private void CompactDataBase() { Task task = Task.Run(() => { using (DBreeze.Transactions.Transaction dbreezeTransaction = this.blockRepository.DBreeze.GetTransaction()) { dbreezeTransaction.SynchronizeTables(BlockRepository.BlockTableName, BlockRepository.TransactionTableName); var tempBlocks = dbreezeTransaction.SelectDictionary <byte[], byte[]>(BlockRepository.BlockTableName); if (tempBlocks.Count != 0) { this.logger.LogInformation($"{tempBlocks.Count} blocks will be copied to the pruned table."); dbreezeTransaction.RemoveAllKeys(BlockRepository.BlockTableName, true); dbreezeTransaction.InsertDictionary(BlockRepository.BlockTableName, tempBlocks, false); var tempTransactions = dbreezeTransaction.SelectDictionary <byte[], byte[]>(BlockRepository.TransactionTableName); if (tempTransactions.Count != 0) { this.logger.LogInformation($"{tempTransactions.Count} transactions will be copied to the pruned table."); dbreezeTransaction.RemoveAllKeys(BlockRepository.TransactionTableName, true); dbreezeTransaction.InsertDictionary(BlockRepository.TransactionTableName, tempTransactions, false); } // Save the hash and height of where the node was pruned up to. dbreezeTransaction.Insert(BlockRepository.CommonTableName, prunedTipKey, this.dBreezeSerializer.Serialize(this.PrunedTip)); } dbreezeTransaction.Commit(); } return(Task.CompletedTask); }); }
public async Task PutAsync_Inserts_MultipleProvenBlockHeadersAsync() { string folder = CreateTestDir(this); PosBlock posBlock = CreatePosBlockMock(); ProvenBlockHeader header1 = CreateNewProvenBlockHeaderMock(posBlock); ProvenBlockHeader header2 = CreateNewProvenBlockHeaderMock(posBlock); var items = new List <ProvenBlockHeader> { header1, header2 }; // Put the items in the repository. using (IProvenBlockHeaderRepository repo = this.SetupRepository(this.Network, folder)) { await repo.PutAsync(items, new HashHeightPair(header2.GetHash(), items.Count - 1)); } // Check the ProvenBlockHeader exists in the database. using (var engine = new DBreezeEngine(folder)) { DBreeze.Transactions.Transaction txn = engine.GetTransaction(); txn.SynchronizeTables(ProvenBlockHeaderTable); txn.ValuesLazyLoadingIsOn = false; var headersOut = txn.SelectDictionary <byte[], ProvenBlockHeader>(ProvenBlockHeaderTable); headersOut.Keys.Count.Should().Be(2); headersOut.First().Value.GetHash().Should().Be(items[0].GetHash()); headersOut.Last().Value.GetHash().Should().Be(items[1].GetHash()); } }
public void ReIndexAsync_TxIndex_OffToOn() { string dir = CreateTestDir(this); Block block = this.Network.CreateBlock(); Transaction transaction = this.Network.CreateTransaction(); block.Transactions.Add(transaction); // Set up database to mimic that created when TxIndex was off. No transactions stored. using (var engine = new DBreezeEngine(dir)) { DBreeze.Transactions.Transaction dbreezeTransaction = engine.GetTransaction(); dbreezeTransaction.Insert <byte[], byte[]>("Block", block.GetHash().ToBytes(), block.ToBytes()); dbreezeTransaction.Commit(); } // Turn TxIndex on and then reindex database, as would happen on node startup if -txindex and -reindex are set. using (IBlockRepository repository = this.SetupRepository(this.Network, dir)) { Task setIndexTask = repository.SetTxIndexAsync(true); setIndexTask.Wait(); Task reindexTask = repository.ReIndexAsync(); reindexTask.Wait(); } // Check that after indexing database, the transaction inside the block is now indexed. using (var engine = new DBreezeEngine(dir)) { DBreeze.Transactions.Transaction dbreezeTransaction = engine.GetTransaction(); Dictionary <byte[], Block> blockDict = dbreezeTransaction.SelectDictionary <byte[], Block>("Block"); Dictionary <byte[], byte[]> transDict = dbreezeTransaction.SelectDictionary <byte[], byte[]>("Transaction"); // Block stored as expected. Assert.Single(blockDict); Assert.Equal(block.GetHash(), blockDict.FirstOrDefault().Value.GetHash()); // Transaction row in database stored as expected. Assert.Single(transDict); KeyValuePair <byte[], byte[]> savedTransactionRow = transDict.FirstOrDefault(); Assert.Equal(transaction.GetHash().ToBytes(), savedTransactionRow.Key); Assert.Equal(block.GetHash().ToBytes(), savedTransactionRow.Value); } }
public void ReIndexAsync_TxIndex_OnToOff() { string dir = CreateTestDir(this); Block block = this.Network.CreateBlock(); Transaction transaction = this.Network.CreateTransaction(); block.Transactions.Add(transaction); // Set up database to mimic that created when TxIndex was on. Transaction from block is stored. using (var engine = new DBreezeEngine(dir)) { DBreeze.Transactions.Transaction dbreezeTransaction = engine.GetTransaction(); dbreezeTransaction.Insert <byte[], byte[]>("Block", block.GetHash().ToBytes(), block.ToBytes()); dbreezeTransaction.Insert <byte[], byte[]>("Transaction", transaction.GetHash().ToBytes(), block.GetHash().ToBytes()); dbreezeTransaction.Commit(); } // Turn TxIndex off and then reindex database, as would happen on node startup if -txindex=0 and -reindex are set. using (IBlockRepository repository = this.SetupRepository(this.Network, dir)) { Task setIndexTask = repository.SetTxIndexAsync(false); setIndexTask.Wait(); Task reindexTask = repository.ReIndexAsync(); reindexTask.Wait(); } // Check that after indexing database, the transaction is no longer stored. using (var engine = new DBreezeEngine(dir)) { DBreeze.Transactions.Transaction dbreezeTransaction = engine.GetTransaction(); Dictionary <byte[], byte[]> blockDict = dbreezeTransaction.SelectDictionary <byte[], byte[]>("Block"); Dictionary <byte[], byte[]> transDict = dbreezeTransaction.SelectDictionary <byte[], byte[]>("Transaction"); // Block still stored as expected. Assert.Single(blockDict); Assert.Equal(block.GetHash(), this.DBreezeSerializer.Deserialize <Block>(blockDict.FirstOrDefault().Value).GetHash()); // No transactions indexed. Assert.Empty(transDict); } }
/// <summary>Loads all polls from the database.</summary> /// <param name="transaction">See <see cref="DBreeze.Transactions.Transaction"/>.</param> /// <returns>A list of retrieved <see cref="Poll"/> entries.</returns> public List <Poll> GetAllPolls(DBreeze.Transactions.Transaction transaction) { lock (this.lockObject) { Dictionary <byte[], byte[]> data = transaction.SelectDictionary <byte[], byte[]>(DataTable); return(data .Where(d => d.Key.Length == 4) .Select(d => this.dBreezeSerializer.Deserialize <Poll>(d.Value)) .ToList()); } }
public void DeleteAsyncRemovesBlocksAndTransactions() { string dir = CreateTestDir(this); Block block = this.Network.CreateBlock(); block.Transactions.Add(this.Network.CreateTransaction()); using (var engine = new DBreezeEngine(dir)) { DBreeze.Transactions.Transaction transaction = engine.GetTransaction(); transaction.Insert <byte[], byte[]>("Block", block.GetHash().ToBytes(), block.ToBytes()); transaction.Insert <byte[], byte[]>("Transaction", block.Transactions[0].GetHash().ToBytes(), block.GetHash().ToBytes()); transaction.Insert <byte[], bool>("Common", new byte[1], true); transaction.Commit(); } var tip = new HashHeightPair(new uint256(45), 100); using (IBlockRepository repository = this.SetupRepository(this.Network, dir)) { Task task = repository.DeleteAsync(tip, new List <uint256> { block.GetHash() }); task.Wait(); } using (var engine = new DBreezeEngine(dir)) { DBreeze.Transactions.Transaction trans = engine.GetTransaction(); Row <byte[], HashHeightPair> blockHashKeyRow = trans.Select <byte[], HashHeightPair>("Common", new byte[0]); Dictionary <byte[], byte[]> blockDict = trans.SelectDictionary <byte[], byte[]>("Block"); Dictionary <byte[], byte[]> transDict = trans.SelectDictionary <byte[], byte[]>("Transaction"); Assert.Equal(tip, blockHashKeyRow.Value); Assert.Empty(blockDict); Assert.Empty(transDict); } }
public void Initialize() { // Load highest index. lock (this.lockObject) { using (DBreeze.Transactions.Transaction transaction = this.dbreeze.GetTransaction()) { Dictionary <byte[], byte[]> data = transaction.SelectDictionary <byte[], byte[]>(DataTable); Poll[] polls = data .Where(d => d.Key.Length == 4) .Select(d => this.dBreezeSerializer.Deserialize <Poll>(d.Value)) .ToArray(); this.highestPollId = (polls.Length > 0) ? polls.Max(p => p.Id) : -1; Row <byte[], byte[]> rowTip = transaction.Select <byte[], byte[]>(DataTable, RepositoryTipKey); if (rowTip.Exists) { this.CurrentTip = this.dBreezeSerializer.Deserialize <HashHeightPair>(rowTip.Value); if (this.chainIndexer != null && this.chainIndexer.GetHeader(this.CurrentTip.Hash) == null) { this.CurrentTip = null; } } else { this.ResetLocked(transaction); transaction.Commit(); } } } this.logger.LogDebug("Polls repo initialized with highest id: {0}.", this.highestPollId); }
public void PutAsyncWritesBlocksAndTransactionsToDbAndSavesNextBlockHash() { string dir = CreateTestDir(this); var nextBlockHash = new uint256(1241256); var blocks = new List <Block>(); Block block = this.Network.Consensus.ConsensusFactory.CreateBlock(); BlockHeader blockHeader = block.Header; blockHeader.Bits = new Target(12); Transaction transaction = this.Network.CreateTransaction(); transaction.Version = 32; block.Transactions.Add(transaction); transaction = this.Network.CreateTransaction(); transaction.Version = 48; block.Transactions.Add(transaction); blocks.Add(block); Block block2 = this.Network.Consensus.ConsensusFactory.CreateBlock(); transaction = this.Network.CreateTransaction(); transaction.Version = 15; block2.Transactions.Add(transaction); blocks.Add(block2); using (var engine = new DBreezeEngine(dir)) { DBreeze.Transactions.Transaction trans = engine.GetTransaction(); trans.Insert <byte[], HashHeightPair>("Common", new byte[0], new HashHeightPair(uint256.Zero, 1)); trans.Insert <byte[], bool>("Common", new byte[1], true); trans.Commit(); } using (IBlockRepository repository = this.SetupRepository(this.Network, dir)) { Task task = repository.PutAsync(new HashHeightPair(nextBlockHash, 100), blocks); task.Wait(); } using (var engine = new DBreezeEngine(dir)) { DBreeze.Transactions.Transaction trans = engine.GetTransaction(); Row <byte[], HashHeightPair> blockHashKeyRow = trans.Select <byte[], HashHeightPair>("Common", new byte[0]); Dictionary <byte[], byte[]> blockDict = trans.SelectDictionary <byte[], byte[]>("Block"); Dictionary <byte[], byte[]> transDict = trans.SelectDictionary <byte[], byte[]>("Transaction"); Assert.Equal(new HashHeightPair(nextBlockHash, 100), blockHashKeyRow.Value); Assert.Equal(2, blockDict.Count); Assert.Equal(3, transDict.Count); foreach (KeyValuePair <byte[], byte[]> item in blockDict) { Block bl = blocks.Single(b => b.GetHash() == new uint256(item.Key)); Assert.Equal(bl.Header.GetHash(), Block.Load(item.Value, this.Network).Header.GetHash()); } foreach (KeyValuePair <byte[], byte[]> item in transDict) { Block bl = blocks.Single(b => b.Transactions.Any(t => t.GetHash() == new uint256(item.Key))); Assert.Equal(bl.GetHash(), new uint256(item.Value)); } } }