public WriteBatch CreateWriteBatch() { var writeBatch = new WriteBatch(); try { foreach (var update in updates) { var txIndex = update.Key; var blockTxNode = update.Value; var key = DbEncoder.EncodeBlockHashTxIndex(blockHash, txIndex); if (blockTxNode != null) { writeBatch.Put(key, DataEncoder.EncodeBlockTxNode(blockTxNode)); } else { writeBatch.Delete(key); } } return(writeBatch); } catch (Exception) { writeBatch.Dispose(); throw; } }
public BlockTxNode ReadNode() { UInt256 recordBlockHash; int txIndex; DbEncoder.DecodeBlockHashTxIndex(iterator.Key().ToArray(), out recordBlockHash, out txIndex); if (this.blockHash != recordBlockHash) { throw new InvalidOperationException(); } BlockTxNode blockTxNode; if (updates.TryGetValue(txIndex, out blockTxNode)) { if (blockTxNode == null) { throw new InvalidOperationException(); } return(blockTxNode); } else { return(DataDecoder.DecodeBlockTxNode(iterator.Value().ToArray(), skipTxBytes: true)); } }
public void DeleteElements(IEnumerable <KeyValuePair <UInt256, IEnumerable <int> > > blockTxIndices) { var writeBatch = new WriteBatch(); try { foreach (var keyPair in blockTxIndices) { var blockHash = keyPair.Key; var txIndices = keyPair.Value; // prune the transactions foreach (var index in txIndices) { writeBatch.Delete(DbEncoder.EncodeBlockHashTxIndex(blockHash, index)); } } db.Write(new WriteOptions(), writeBatch); } finally { writeBatch.Dispose(); } }
private bool TryMove(bool forward) { var moveCount = 0; while (true) { if (forward) { iterator.Next(); } else { iterator.Prev(); } if (iterator.Valid()) { moveCount++; UInt256 recordBlockHash; int txIndex; DbEncoder.DecodeBlockHashTxIndex(iterator.Key().ToArray(), out recordBlockHash, out txIndex); if (blockHash == recordBlockHash) { BlockTxNode blockTxNode; if (updates.TryGetValue(txIndex, out blockTxNode) && blockTxNode == null) { continue; } else { return(true); } } } else if (forward) { iterator.SeekToLast(); } else { iterator.SeekToFirst(); } for (var i = 0; i < moveCount; i++) { if (forward) { iterator.Prev(); } else { iterator.Next(); } } return(false); } }
public void DeleteNode() { UInt256 recordBlockHash; int txIndex; DbEncoder.DecodeBlockHashTxIndex(iterator.Key().ToArray(), out recordBlockHash, out txIndex); updates[txIndex] = null; if (!TryMove(forward: false)) { throw new InvalidOperationException(); } }
public bool TryAddBlockTransactions(UInt256 blockHash, IEnumerable <EncodedTx> blockTxes) { if (ContainsBlock(blockHash)) { return(false); } var writeBatch = new WriteBatch(); try { int txCount; using (var snapshot = db.GetSnapshot()) { var readOptions = new ReadOptions { Snapshot = snapshot }; var txIndex = 0; foreach (var tx in blockTxes) { var key = DbEncoder.EncodeBlockHashTxIndex(blockHash, txIndex); Slice existingValue; if (db.TryGet(readOptions, key, out existingValue)) { return(false); } var blockTx = new BlockTx(txIndex, tx); var value = DataEncoder.EncodeBlockTxNode(blockTx); writeBatch.Put(key, value); txIndex++; } txCount = txIndex; } return(TryAddBlockInner(blockHash, txCount, writeBatch)); } finally { writeBatch.Dispose(); } }
public bool TryRemoveBlockTransactions(UInt256 blockHash) { if (!ContainsBlock(blockHash)) { return(false); } var writeBatch = new WriteBatch(); try { using (var snapshot = db.GetSnapshot()) { var readOptions = new ReadOptions { Snapshot = snapshot }; using (var iterator = db.NewIterator(readOptions)) { iterator.Seek(DbEncoder.EncodeBlockHashTxIndex(blockHash, 0)); while (iterator.Valid()) { var key = iterator.Key().ToArray(); UInt256 iteratorBlockHash; int txIndex; DbEncoder.DecodeBlockHashTxIndex(key, out iteratorBlockHash, out txIndex); if (iteratorBlockHash != blockHash) { break; } writeBatch.Delete(key); iterator.Next(); } } } return(TryRemoveBlockInner(blockHash, writeBatch)); } finally { writeBatch.Dispose(); } }
private IEnumerator <BlockTxNode> ReadBlockTransactions(UInt256 blockHash, bool requireTx) { using (var snapshot = db.GetSnapshot()) { var readOptions = new ReadOptions { Snapshot = snapshot }; using (var iterator = db.NewIterator(readOptions)) { iterator.Seek(DbEncoder.EncodeBlockHashTxIndex(blockHash, 0)); while (iterator.Valid()) { var key = iterator.Key().ToArray(); UInt256 iteratorBlockHash; int txIndex; DbEncoder.DecodeBlockHashTxIndex(key, out iteratorBlockHash, out txIndex); if (iteratorBlockHash != blockHash) { yield break; } var value = iterator.Value().ToArray(); var blockTxNode = DataDecoder.DecodeBlockTxNode(value); if (blockTxNode.Pruned && requireTx) { throw new MissingDataException(blockHash); } yield return(blockTxNode); iterator.Next(); } } } }
public void WriteNode(BlockTxNode node) { if (!node.Pruned) { throw new ArgumentException(); } UInt256 recordBlockHash; int txIndex; DbEncoder.DecodeBlockHashTxIndex(iterator.Key().ToArray(), out recordBlockHash, out txIndex); if (this.blockHash != recordBlockHash) { throw new InvalidOperationException(); } if (node.Index != txIndex) { throw new InvalidOperationException(); } var blockTxNode = new BlockTxNode(node.Index, node.Depth, node.Hash, node.Pruned, (ImmutableArray <byte>?)null); updates[node.Index] = blockTxNode; }
public bool TryGetTransaction(UInt256 blockHash, int txIndex, out BlockTx transaction) { Slice value; if (db.TryGet(new ReadOptions(), DbEncoder.EncodeBlockHashTxIndex(blockHash, txIndex), out value)) { var blockTxNode = DataDecoder.DecodeBlockTxNode(value.ToArray()); if (!blockTxNode.Pruned) { transaction = blockTxNode.ToBlockTx(); return(true); } else { transaction = default(BlockTx); return(false); } } else { transaction = default(BlockTx); return(false); } }
public bool TryMoveToIndex(int index) { iterator.Seek(DbEncoder.EncodeBlockHashTxIndex(blockHash, index)); return(iterator.Valid()); }