コード例 #1
0
        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;
            }
        }
コード例 #2
0
        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));
            }
        }
コード例 #3
0
        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();
            }
        }
コード例 #4
0
        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);
            }
        }
コード例 #5
0
        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();
            }
        }
コード例 #6
0
        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();
            }
        }
コード例 #7
0
        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();
            }
        }
コード例 #8
0
        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();
                    }
                }
            }
        }
コード例 #9
0
        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;
        }
コード例 #10
0
        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);
            }
        }
コード例 #11
0
 public bool TryMoveToIndex(int index)
 {
     iterator.Seek(DbEncoder.EncodeBlockHashTxIndex(blockHash, index));
     return(iterator.Valid());
 }