예제 #1
0
        public bool TryAddHeader(ChainedHeader header)
        {
            CheckWriteTransaction();

            try
            {
                using (SetSessionContext())
                    using (var jetUpdate = this.jetSession.BeginUpdate(this.headersTableId, JET_prep.Insert))
                    {
                        Api.SetColumns(this.jetSession, this.headersTableId,
                                       new BytesColumnValue {
                            Columnid = this.headerBlockHashColumnId, Value = DbEncoder.EncodeUInt256(header.Hash)
                        },
                                       new BytesColumnValue {
                            Columnid = this.headerBytesColumnId, Value = DataEncoder.EncodeChainedHeader(header)
                        });

                        jetUpdate.Save();
                    }

                return(true);
            }
            catch (EsentKeyDuplicateException)
            {
                return(false);
            }
        }
예제 #2
0
        private void AddTransaction(int blockIndex, int txIndex, UInt256 txHash, byte[] txBytes, EsentBlockTxesCursor cursor)
        {
            using (var jetUpdate = cursor.jetSession.BeginUpdate(cursor.blocksTableId, JET_prep.Insert))
            {
                Api.SetColumns(cursor.jetSession, cursor.blocksTableId,
                               new Int32ColumnValue {
                    Columnid = cursor.blockIndexColumnId, Value = blockIndex
                },
                               new Int32ColumnValue {
                    Columnid = cursor.txIndexColumnId, Value = txIndex
                },
                               //TODO i'm using -1 depth to mean not pruned, this should be interpreted as depth 0
                               new Int32ColumnValue {
                    Columnid = cursor.blockDepthColumnId, Value = -1
                },
                               new BytesColumnValue {
                    Columnid = cursor.blockTxHashColumnId, Value = DbEncoder.EncodeUInt256(txHash)
                },
                               new BytesColumnValue {
                    Columnid = cursor.blockTxBytesColumnId, Value = txBytes
                });

                jetUpdate.Save();
            }
        }
예제 #3
0
        public bool TryRemoveUnspentTx(UInt256 txHash)
        {
            if (!this.inTransaction)
            {
                throw new InvalidOperationException();
            }

            Api.JetSetCurrentIndex(this.jetSession, this.unspentTxTableId, "IX_TxHash");
            Api.MakeKey(this.jetSession, this.unspentTxTableId, DbEncoder.EncodeUInt256(txHash), MakeKeyGrbit.NewKey);
            if (Api.TrySeek(this.jetSession, this.unspentTxTableId, SeekGrbit.SeekEQ))
            {
                var addedBlockIndex = Api.RetrieveColumnAsInt32(this.jetSession, this.unspentTxTableId, this.blockIndexColumnId).Value;
                var txIndex         = Api.RetrieveColumnAsInt32(this.jetSession, this.unspentTxTableId, this.txIndexColumnId).Value;
                var outputStates    = DataEncoder.DecodeOutputStates(Api.RetrieveColumn(this.jetSession, this.unspentTxTableId, this.outputStatesColumnId));

                Api.JetDelete(this.jetSession, this.unspentTxTableId);

                // decrease unspent tx count
                Api.EscrowUpdate(this.jetSession, this.globalsTableId, this.unspentTxCountColumnId, -1);

                return(true);
            }
            else
            {
                return(false);
            }
        }
예제 #4
0
        public bool TryAddBlockUnmintedTxes(UInt256 blockHash, IImmutableList <UnmintedTx> unmintedTxes)
        {
            CheckWriteTransaction();

            try
            {
                using (SetSessionContext())
                    using (var jetUpdate = this.jetSession.BeginUpdate(this.unmintedTxTableId, JET_prep.Insert))
                    {
                        byte[] unmintedTxesBytes;
                        using (var stream = new MemoryStream())
                            using (var writer = new BinaryWriter(stream))
                            {
                                writer.WriteList(unmintedTxes, unmintedTx => DataEncoder.EncodeUnmintedTx(writer, unmintedTx));
                                unmintedTxesBytes = stream.ToArray();
                            }

                        Api.SetColumns(this.jetSession, this.unmintedTxTableId,
                                       new BytesColumnValue {
                            Columnid = this.unmintedBlockHashColumnId, Value = DbEncoder.EncodeUInt256(blockHash)
                        },
                                       new BytesColumnValue {
                            Columnid = this.unmintedDataColumnId, Value = unmintedTxesBytes
                        });

                        jetUpdate.Save();
                    }

                return(true);
            }
            catch (EsentKeyDuplicateException)
            {
                return(false);
            }
        }
예제 #5
0
        public bool TryUpdateUnspentTx(UnspentTx unspentTx)
        {
            CheckWriteTransaction();

            using (SetSessionContext())
            {
                Api.JetSetCurrentIndex(this.jetSession, this.unspentTxTableId, "IX_TxHash");
                Api.MakeKey(this.jetSession, this.unspentTxTableId, DbEncoder.EncodeUInt256(unspentTx.TxHash), MakeKeyGrbit.NewKey);

                if (Api.TrySeek(this.jetSession, this.unspentTxTableId, SeekGrbit.SeekEQ))
                {
                    using (var jetUpdate = this.jetSession.BeginUpdate(this.unspentTxTableId, JET_prep.Replace))
                    {
                        Api.SetColumn(this.jetSession, this.unspentTxTableId, this.outputStatesColumnId, DataEncoder.EncodeOutputStates(unspentTx.OutputStates));

                        jetUpdate.Save();
                    }

                    return(true);
                }
                else
                {
                    return(false);
                }
            }
        }
예제 #6
0
        public void MarkBlockInvalid(UInt256 blockHash)
        {
            using (var handle = this.cursorCache.TakeItem())
            {
                var cursor = handle.Item;

                using (var jetTx = cursor.jetSession.BeginTransaction())
                {
                    Api.JetSetCurrentIndex(cursor.jetSession, cursor.blockHeadersTableId, "IX_BlockHash");
                    Api.MakeKey(cursor.jetSession, cursor.blockHeadersTableId, DbEncoder.EncodeUInt256(blockHash), MakeKeyGrbit.NewKey);

                    if (!Api.TrySeek(cursor.jetSession, cursor.blockHeadersTableId, SeekGrbit.SeekEQ))
                    {
                        throw new MissingDataException(blockHash);
                    }

                    using (var jetUpdate = cursor.jetSession.BeginUpdate(cursor.blockHeadersTableId, JET_prep.Replace))
                    {
                        Api.SetColumn(cursor.jetSession, cursor.blockHeadersTableId, cursor.blockHeaderValidColumnId, false);

                        jetUpdate.Save();
                    }

                    jetTx.CommitLazy();
                }
            }
        }
예제 #7
0
        public bool TryRemoveChainedHeader(UInt256 blockHash)
        {
            using (var handle = this.cursorCache.TakeItem())
            {
                var cursor = handle.Item;

                using (var jetTx = cursor.jetSession.BeginTransaction())
                {
                    bool removed;

                    Api.JetSetCurrentIndex(cursor.jetSession, cursor.blockHeadersTableId, "IX_BlockHash");
                    Api.MakeKey(cursor.jetSession, cursor.blockHeadersTableId, DbEncoder.EncodeUInt256(blockHash), MakeKeyGrbit.NewKey);
                    if (Api.TrySeek(cursor.jetSession, cursor.blockHeadersTableId, SeekGrbit.SeekEQ))
                    {
                        Api.JetDelete(cursor.jetSession, cursor.blockHeadersTableId);
                        removed = true;
                    }
                    else
                    {
                        removed = false;
                    }

                    jetTx.CommitLazy();
                    return(removed);
                }
            }
        }
예제 #8
0
        public bool ContainsBlockUnmintedTxes(UInt256 blockHash)
        {
            CheckTransaction();

            using (SetSessionContext())
            {
                Api.JetSetCurrentIndex(this.jetSession, this.unmintedTxTableId, "IX_UnmintedBlockHash");
                Api.MakeKey(this.jetSession, this.unmintedTxTableId, DbEncoder.EncodeUInt256(blockHash), MakeKeyGrbit.NewKey);
                return(Api.TrySeek(this.jetSession, this.unmintedTxTableId, SeekGrbit.SeekEQ));
            }
        }
예제 #9
0
        public bool ContainsUnspentTx(UInt256 txHash)
        {
            CheckTransaction();

            using (SetSessionContext())
            {
                Api.JetSetCurrentIndex(this.jetSession, this.unspentTxTableId, "IX_TxHash");
                Api.MakeKey(this.jetSession, this.unspentTxTableId, DbEncoder.EncodeUInt256(txHash), MakeKeyGrbit.NewKey);
                return(Api.TrySeek(this.jetSession, this.unspentTxTableId, SeekGrbit.SeekEQ));
            }
        }
예제 #10
0
        public bool ContainsChainedHeader(UInt256 blockHash)
        {
            using (var handle = this.cursorCache.TakeItem())
            {
                var cursor = handle.Item;

                Api.JetSetCurrentIndex(cursor.jetSession, cursor.blockHeadersTableId, "IX_BlockHash");
                Api.MakeKey(cursor.jetSession, cursor.blockHeadersTableId, DbEncoder.EncodeUInt256(blockHash), MakeKeyGrbit.NewKey);

                return(Api.TrySeek(cursor.jetSession, cursor.blockHeadersTableId, SeekGrbit.SeekEQ));
            }
        }
예제 #11
0
        private void DeleteBlockIndex(EsentBlockTxesCursor cursor, UInt256 blockHash)
        {
            Api.JetSetCurrentIndex(cursor.jetSession, cursor.blockIndexTableId, "IX_BlockHash");
            Api.MakeKey(cursor.jetSession, cursor.blockIndexTableId, DbEncoder.EncodeUInt256(blockHash), MakeKeyGrbit.NewKey);

            if (Api.TrySeek(cursor.jetSession, cursor.blockIndexTableId, SeekGrbit.SeekEQ))
            {
                Api.JetDelete(cursor.jetSession, cursor.blockIndexTableId);
            }
            else
            {
                throw new InvalidOperationException();
            }
        }
예제 #12
0
        public bool ContainsBlock(UInt256 blockHash)
        {
            using (var handle = this.cursorCache.TakeItem())
            {
                var cursor = handle.Item;

                using (var jetTx = cursor.jetSession.BeginTransaction())
                {
                    Api.JetSetCurrentIndex(cursor.jetSession, cursor.blockIndexTableId, "IX_BlockHash");
                    Api.MakeKey(cursor.jetSession, cursor.blockIndexTableId, DbEncoder.EncodeUInt256(blockHash), MakeKeyGrbit.NewKey);

                    return(Api.TrySeek(cursor.jetSession, cursor.blockIndexTableId, SeekGrbit.SeekEQ));
                }
            }
        }
예제 #13
0
        private bool TryGetBlockIndex(EsentBlockTxesCursor cursor, UInt256 blockHash, out int blockIndex)
        {
            Api.JetSetCurrentIndex(cursor.jetSession, cursor.blockIndexTableId, "IX_BlockHash");
            Api.MakeKey(cursor.jetSession, cursor.blockIndexTableId, DbEncoder.EncodeUInt256(blockHash), MakeKeyGrbit.NewKey);

            if (Api.TrySeek(cursor.jetSession, cursor.blockIndexTableId, SeekGrbit.SeekEQ))
            {
                blockIndex = Api.RetrieveColumnAsInt32(cursor.jetSession, cursor.blockIndexTableId, cursor.blockIndexBlockIndexColumnId).Value;
                return(true);
            }
            else
            {
                blockIndex = -1;
                return(false);
            }
        }
예제 #14
0
        public bool TryRemoveBlockTransactions(UInt256 blockHash)
        {
            using (var handle = this.cursorCache.TakeItem())
            {
                var cursor = handle.Item;

                using (var jetTx = cursor.jetSession.BeginTransaction())
                {
                    Api.JetSetCurrentIndex(cursor.jetSession, cursor.blockIdsTableId, "IX_BlockHash");
                    Api.MakeKey(cursor.jetSession, cursor.blockIdsTableId, DbEncoder.EncodeUInt256(blockHash), MakeKeyGrbit.NewKey);

                    if (Api.TrySeek(cursor.jetSession, cursor.blockIdsTableId, SeekGrbit.SeekEQ))
                    {
                        var blockId = Api.RetrieveColumnAsInt32(cursor.jetSession, cursor.blockIdsTableId, cursor.blockIdsIdColumnId).Value;

                        // remove block id
                        Api.JetDelete(cursor.jetSession, cursor.blockIdsTableId);

                        // remove transactions
                        Api.JetSetCurrentIndex(cursor.jetSession, cursor.blocksTableId, "IX_BlockIdTxIndex");
                        Api.MakeKey(cursor.jetSession, cursor.blocksTableId, blockId, MakeKeyGrbit.NewKey);
                        Api.MakeKey(cursor.jetSession, cursor.blocksTableId, -1, MakeKeyGrbit.None);

                        if (Api.TrySeek(cursor.jetSession, cursor.blocksTableId, SeekGrbit.SeekGE) &&
                            blockId == Api.RetrieveColumnAsInt32(cursor.jetSession, cursor.blocksTableId, cursor.blockIdColumnId).Value)
                        {
                            do
                            {
                                Api.JetDelete(cursor.jetSession, cursor.blocksTableId);
                            } while (Api.TryMoveNext(cursor.jetSession, cursor.blocksTableId) &&
                                     blockId == Api.RetrieveColumnAsInt32(cursor.jetSession, cursor.blocksTableId, cursor.blockIdColumnId).Value);
                        }

                        // decrease block count
                        Api.EscrowUpdate(cursor.jetSession, cursor.globalsTableId, cursor.blockCountColumnId, -1);

                        jetTx.CommitLazy();
                        return(true);
                    }
                    else
                    {
                        // transactions are already removed
                        return(false);
                    }
                }
            }
        }
예제 #15
0
        public bool TryGetUnspentTx(UInt256 txHash, out UnspentTx unspentTx)
        {
            Api.JetSetCurrentIndex(this.jetSession, this.unspentTxTableId, "IX_TxHash");
            Api.MakeKey(this.jetSession, this.unspentTxTableId, DbEncoder.EncodeUInt256(txHash), MakeKeyGrbit.NewKey);
            if (Api.TrySeek(this.jetSession, this.unspentTxTableId, SeekGrbit.SeekEQ))
            {
                var blockIndex   = Api.RetrieveColumnAsInt32(this.jetSession, this.unspentTxTableId, this.blockIndexColumnId).Value;
                var txIndex      = Api.RetrieveColumnAsInt32(this.jetSession, this.unspentTxTableId, this.txIndexColumnId).Value;
                var outputStates = DataEncoder.DecodeOutputStates(Api.RetrieveColumn(this.jetSession, this.unspentTxTableId, this.outputStatesColumnId));

                unspentTx = new UnspentTx(txHash, blockIndex, txIndex, outputStates);
                return(true);
            }

            unspentTx = default(UnspentTx);
            return(false);
        }
예제 #16
0
        public bool TryGetUnspentTx(UInt256 txHash, out UnspentTx unspentTx)
        {
            CheckTransaction();

            using (SetSessionContext())
            {
                Api.JetSetCurrentIndex(this.jetSession, this.unspentTxTableId, "IX_TxHash");
                Api.MakeKey(this.jetSession, this.unspentTxTableId, DbEncoder.EncodeUInt256(txHash), MakeKeyGrbit.NewKey);
                if (Api.TrySeek(this.jetSession, this.unspentTxTableId, SeekGrbit.SeekEQ))
                {
                    var blockIndexColumn = new Int32ColumnValue {
                        Columnid = this.blockIndexColumnId
                    };
                    var txIndexColumn = new Int32ColumnValue {
                        Columnid = this.txIndexColumnId
                    };
                    var txVersionColumn = new UInt32ColumnValue {
                        Columnid = this.txVersionColumnId
                    };
                    var isCoinbaseColumn = new BoolColumnValue {
                        Columnid = this.isCoinbaseColumnId
                    };
                    var outputStatesColumn = new BytesColumnValue {
                        Columnid = this.outputStatesColumnId
                    };
                    var txOutputBytesColumn = new BytesColumnValue {
                        Columnid = this.txOutputBytesColumnId
                    };
                    Api.RetrieveColumns(this.jetSession, this.unspentTxTableId, blockIndexColumn, txIndexColumn, txVersionColumn, isCoinbaseColumn, outputStatesColumn, txOutputBytesColumn);

                    var blockIndex   = blockIndexColumn.Value.Value;
                    var txIndex      = txIndexColumn.Value.Value;
                    var txVersion    = txVersionColumn.Value.Value;
                    var isCoinbase   = isCoinbaseColumn.Value.Value;
                    var outputStates = DataDecoder.DecodeOutputStates(outputStatesColumn.Value);

                    unspentTx = new UnspentTx(txHash, blockIndex, txIndex, txVersion, isCoinbase, outputStates);
                    return(true);
                }

                unspentTx = default(UnspentTx);
                return(false);
            }
        }
예제 #17
0
        public bool TryAddChainedHeader(ChainedHeader chainedHeader)
        {
            try
            {
                using (var handle = this.cursorCache.TakeItem())
                {
                    var cursor = handle.Item;

                    using (var jetTx = cursor.jetSession.BeginTransaction())
                    {
                        using (var jetUpdate = cursor.jetSession.BeginUpdate(cursor.blockHeadersTableId, JET_prep.Insert))
                        {
                            Api.SetColumns(cursor.jetSession, cursor.blockHeadersTableId,
                                           new BytesColumnValue {
                                Columnid = cursor.blockHeaderHashColumnId, Value = DbEncoder.EncodeUInt256(chainedHeader.Hash)
                            },
                                           new BytesColumnValue {
                                Columnid = cursor.blockHeaderPreviousHashColumnId, Value = DbEncoder.EncodeUInt256(chainedHeader.PreviousBlockHash)
                            },
                                           new Int32ColumnValue {
                                Columnid = cursor.blockHeaderHeightColumnId, Value = chainedHeader.Height
                            },
                                           new BytesColumnValue {
                                Columnid = cursor.blockHeaderTotalWorkColumnId, Value = DataEncoder.EncodeTotalWork(chainedHeader.TotalWork)
                            },
                                           new BytesColumnValue {
                                Columnid = cursor.blockHeaderBytesColumnId, Value = DataEncoder.EncodeChainedHeader(chainedHeader)
                            });

                            jetUpdate.Save();
                        }

                        jetTx.CommitLazy();
                        return(true);
                    }
                }
            }
            catch (EsentKeyDuplicateException)
            {
                return(false);
            }
        }
예제 #18
0
        public bool TryGetChainedHeader(UInt256 blockHash, out ChainedHeader chainedHeader)
        {
            using (var handle = this.cursorCache.TakeItem())
            {
                var cursor = handle.Item;

                Api.JetSetCurrentIndex(cursor.jetSession, cursor.blockHeadersTableId, "IX_BlockHash");
                Api.MakeKey(cursor.jetSession, cursor.blockHeadersTableId, DbEncoder.EncodeUInt256(blockHash), MakeKeyGrbit.NewKey);
                if (Api.TrySeek(cursor.jetSession, cursor.blockHeadersTableId, SeekGrbit.SeekEQ))
                {
                    chainedHeader = DataDecoder.DecodeChainedHeader(Api.RetrieveColumn(cursor.jetSession, cursor.blockHeadersTableId, cursor.blockHeaderBytesColumnId));
                    return(true);
                }
                else
                {
                    chainedHeader = default(ChainedHeader);
                    return(false);
                }
            }
        }
예제 #19
0
        public bool TryRemoveUnspentTx(UInt256 txHash)
        {
            CheckWriteTransaction();

            using (SetSessionContext())
            {
                Api.JetSetCurrentIndex(this.jetSession, this.unspentTxTableId, "IX_TxHash");
                Api.MakeKey(this.jetSession, this.unspentTxTableId, DbEncoder.EncodeUInt256(txHash), MakeKeyGrbit.NewKey);
                if (Api.TrySeek(this.jetSession, this.unspentTxTableId, SeekGrbit.SeekEQ))
                {
                    Api.JetDelete(this.jetSession, this.unspentTxTableId);

                    return(true);
                }
                else
                {
                    return(false);
                }
            }
        }
예제 #20
0
        public bool TryGetHeader(UInt256 blockHash, out ChainedHeader header)
        {
            CheckTransaction();

            using (SetSessionContext())
            {
                Api.JetSetCurrentIndex(this.jetSession, this.headersTableId, "IX_BlockHash");
                Api.MakeKey(this.jetSession, this.headersTableId, DbEncoder.EncodeUInt256(blockHash), MakeKeyGrbit.NewKey);
                if (Api.TrySeek(this.jetSession, this.headersTableId, SeekGrbit.SeekEQ))
                {
                    var headerBytes = Api.RetrieveColumn(this.jetSession, this.headersTableId, this.headerBytesColumnId);

                    header = DataDecoder.DecodeChainedHeader(headerBytes);
                    return(true);
                }

                header = default(ChainedHeader);
                return(false);
            }
        }
예제 #21
0
        public void WriteNode(BlockTxNode node)
        {
            if (!node.Pruned)
            {
                throw new ArgumentException();
            }

            var recordBlockIndexColumn = new Int32ColumnValue {
                Columnid = cursor.blockIndexColumnId
            };
            var recordTxIndexColumn = new Int32ColumnValue {
                Columnid = cursor.txIndexColumnId
            };

            Api.RetrieveColumns(cursor.jetSession, cursor.blocksTableId, recordBlockIndexColumn, recordTxIndexColumn);

            if (this.blockIndex != recordBlockIndexColumn.Value.Value)
            {
                throw new InvalidOperationException();
            }
            if (node.Index != recordTxIndexColumn.Value.Value)
            {
                throw new InvalidOperationException();
            }

            using (var jetUpdate = cursor.jetSession.BeginUpdate(cursor.blocksTableId, JET_prep.Replace))
            {
                Api.SetColumns(cursor.jetSession, cursor.blocksTableId,
                               new Int32ColumnValue {
                    Columnid = cursor.blockDepthColumnId, Value = node.Depth
                },
                               new BytesColumnValue {
                    Columnid = cursor.blockTxHashColumnId, Value = DbEncoder.EncodeUInt256(node.Hash)
                },
                               new Int32ColumnValue {
                    Columnid = cursor.blockTxBytesColumnId, Value = null
                });

                jetUpdate.Save();
            }
        }
예제 #22
0
        public bool TryAddUnspentTx(UnspentTx unspentTx)
        {
            CheckWriteTransaction();

            using (SetSessionContext())
            {
                try
                {
                    using (var jetUpdate = this.jetSession.BeginUpdate(this.unspentTxTableId, JET_prep.Insert))
                    {
                        Api.SetColumns(this.jetSession, this.unspentTxTableId,
                                       new BytesColumnValue {
                            Columnid = this.txHashColumnId, Value = DbEncoder.EncodeUInt256(unspentTx.TxHash)
                        },
                                       new Int32ColumnValue {
                            Columnid = this.blockIndexColumnId, Value = unspentTx.BlockIndex
                        },
                                       new Int32ColumnValue {
                            Columnid = this.txIndexColumnId, Value = unspentTx.TxIndex
                        },
                                       new UInt32ColumnValue {
                            Columnid = this.txVersionColumnId, Value = unspentTx.TxVersion
                        },
                                       new BoolColumnValue {
                            Columnid = this.isCoinbaseColumnId, Value = unspentTx.IsCoinbase
                        },
                                       new BytesColumnValue {
                            Columnid = this.outputStatesColumnId, Value = DataEncoder.EncodeOutputStates(unspentTx.OutputStates)
                        });

                        jetUpdate.Save();
                    }

                    return(true);
                }
                catch (EsentKeyDuplicateException)
                {
                    return(false);
                }
            }
        }
예제 #23
0
        public bool IsBlockInvalid(UInt256 blockHash)
        {
            using (var handle = this.cursorCache.TakeItem())
            {
                var cursor = handle.Item;

                Api.JetSetCurrentIndex(cursor.jetSession, cursor.blockHeadersTableId, "IX_BlockHash");
                Api.MakeKey(cursor.jetSession, cursor.blockHeadersTableId, DbEncoder.EncodeUInt256(blockHash), MakeKeyGrbit.NewKey);

                if (Api.TrySeek(cursor.jetSession, cursor.blockHeadersTableId, SeekGrbit.SeekEQ))
                {
                    var valid = Api.RetrieveColumnAsBoolean(cursor.jetSession, cursor.blockHeadersTableId, cursor.blockHeaderValidColumnId)
                                ?? true;
                    return(!valid);
                }
                else
                {
                    return(false);
                }
            }
        }
예제 #24
0
        private bool TryGetBlockId(UInt256 blockHash, out int blockId)
        {
            using (var handle = this.cursorCache.TakeItem())
            {
                var cursor = handle.Item;

                using (var jetTx = cursor.jetSession.BeginTransaction())
                {
                    Api.JetSetCurrentIndex(cursor.jetSession, cursor.blockIdsTableId, "IX_BlockHash");
                    Api.MakeKey(cursor.jetSession, cursor.blockIdsTableId, DbEncoder.EncodeUInt256(blockHash), MakeKeyGrbit.NewKey);
                    if (Api.TrySeek(cursor.jetSession, cursor.blockIdsTableId, SeekGrbit.SeekEQ))
                    {
                        blockId = Api.RetrieveColumnAsInt32(cursor.jetSession, cursor.blockIdsTableId, cursor.blockIdsIdColumnId).Value;
                        return(true);
                    }
                    else
                    {
                        blockId = default(int);
                        return(false);
                    }
                }
            }
        }
예제 #25
0
        public bool TryGetBlockUnmintedTxes(UInt256 blockHash, out IImmutableList <UnmintedTx> unmintedTxes)
        {
            CheckTransaction();

            using (SetSessionContext())
            {
                Api.JetSetCurrentIndex(this.jetSession, this.unmintedTxTableId, "IX_UnmintedBlockHash");

                Api.MakeKey(this.jetSession, this.unmintedTxTableId, DbEncoder.EncodeUInt256(blockHash), MakeKeyGrbit.NewKey);

                if (Api.TrySeek(this.jetSession, this.unmintedTxTableId, SeekGrbit.SeekEQ))
                {
                    var unmintedTxesBytes = Api.RetrieveColumn(this.jetSession, this.unmintedTxTableId, this.unmintedDataColumnId);

                    unmintedTxes = DataDecoder.DecodeUnmintedTxList(unmintedTxesBytes);
                    return(true);
                }
                else
                {
                    unmintedTxes = null;
                    return(false);
                }
            }
        }
예제 #26
0
        private int AddBlockIndex(EsentBlockTxesCursor cursor, UInt256 blockHash)
        {
            int blockIndex;

            using (var jetUpdate = cursor.jetSession.BeginUpdate(cursor.blockIndexTableId, JET_prep.Insert))
            {
                Api.SetColumn(cursor.jetSession, cursor.blockIndexTableId, cursor.blockIndexBlockHashColumnId, DbEncoder.EncodeUInt256(blockHash));
                blockIndex = Api.RetrieveColumnAsInt32(cursor.jetSession, cursor.blockIndexTableId, cursor.blockIndexBlockIndexColumnId, RetrieveColumnGrbit.RetrieveCopy).Value;

                jetUpdate.Save();
            }

            return(blockIndex);
        }
예제 #27
0
        public bool TryAddBlockTransactions(UInt256 blockHash, IEnumerable <Transaction> blockTxes)
        {
            if (this.ContainsBlock(blockHash))
            {
                return(false);
            }

            try
            {
                using (var handle = this.cursorCache.TakeItem())
                {
                    var cursor = handle.Item;

                    using (var jetTx = cursor.jetSession.BeginTransaction())
                    {
                        int blockId;
                        using (var jetUpdate = cursor.jetSession.BeginUpdate(cursor.blockIdsTableId, JET_prep.Insert))
                        {
                            blockId = Api.RetrieveColumnAsInt32(cursor.jetSession, cursor.blockIdsTableId, cursor.blockIdsIdColumnId, RetrieveColumnGrbit.RetrieveCopy).Value;
                            Api.SetColumn(cursor.jetSession, cursor.blockIdsTableId, cursor.blockIdsHashColumnId, DbEncoder.EncodeUInt256(blockHash));

                            jetUpdate.Save();
                        }

                        var txIndex = 0;
                        foreach (var tx in blockTxes)
                        {
                            AddTransaction(blockId, txIndex, tx.Hash, DataEncoder.EncodeTransaction(tx), cursor);
                            txIndex++;
                        }

                        // increase block count
                        Api.EscrowUpdate(cursor.jetSession, cursor.globalsTableId, cursor.blockCountColumnId, +1);

                        jetTx.CommitLazy();
                        return(true);
                    }
                }
            }
            catch (EsentKeyDuplicateException)
            {
                return(false);
            }
        }
예제 #28
0
        private void AddTransaction(int blockId, int txIndex, UInt256 txHash, byte[] txBytes, BlockTxesCursor cursor)
        {
            using (var jetUpdate = cursor.jetSession.BeginUpdate(cursor.blocksTableId, JET_prep.Insert))
            {
                Api.SetColumn(cursor.jetSession, cursor.blocksTableId, cursor.blockIdColumnId, blockId);
                Api.SetColumn(cursor.jetSession, cursor.blocksTableId, cursor.blockTxIndexColumnId, txIndex);
                //TODO i'm using -1 depth to mean not pruned, this should be interpreted as depth 0
                Api.SetColumn(cursor.jetSession, cursor.blocksTableId, cursor.blockDepthColumnId, -1);
                Api.SetColumn(cursor.jetSession, cursor.blocksTableId, cursor.blockTxHashColumnId, DbEncoder.EncodeUInt256(txHash));
                Api.SetColumn(cursor.jetSession, cursor.blocksTableId, cursor.blockTxBytesColumnId, txBytes);

                jetUpdate.Save();
            }
        }
예제 #29
0
        public void WriteNode(MerkleTreeNode node)
        {
            if (!node.Pruned)
            {
                throw new ArgumentException();
            }

            if (this.blockId != Api.RetrieveColumnAsInt32(cursor.jetSession, cursor.blocksTableId, cursor.blockIdColumnId).Value)
            {
                throw new InvalidOperationException();
            }

            using (var jetUpdate = cursor.jetSession.BeginUpdate(cursor.blocksTableId, JET_prep.Replace))
            {
                Debug.Assert(node.Index == Api.RetrieveColumnAsInt32(cursor.jetSession, cursor.blocksTableId, cursor.blockTxIndexColumnId).Value);

                Api.SetColumn(cursor.jetSession, cursor.blocksTableId, cursor.blockDepthColumnId, node.Depth);
                Api.SetColumn(cursor.jetSession, cursor.blocksTableId, cursor.blockTxHashColumnId, DbEncoder.EncodeUInt256(node.Hash));
                Api.SetColumn(cursor.jetSession, cursor.blocksTableId, cursor.blockTxBytesColumnId, null);

                jetUpdate.Save();
            }
        }
예제 #30
0
        public bool TryAddUnspentTx(UnspentTx unspentTx)
        {
            if (!this.inTransaction)
            {
                throw new InvalidOperationException();
            }

            try
            {
                using (var jetUpdate = this.jetSession.BeginUpdate(this.unspentTxTableId, JET_prep.Insert))
                {
                    Api.SetColumn(this.jetSession, this.unspentTxTableId, this.txHashColumnId, DbEncoder.EncodeUInt256(unspentTx.TxHash));
                    Api.SetColumn(this.jetSession, this.unspentTxTableId, this.blockIndexColumnId, unspentTx.BlockIndex);
                    Api.SetColumn(this.jetSession, this.unspentTxTableId, this.txIndexColumnId, unspentTx.TxIndex);
                    Api.SetColumn(this.jetSession, this.unspentTxTableId, this.outputStatesColumnId, DataEncoder.EncodeOutputStates(unspentTx.OutputStates));

                    jetUpdate.Save();

                    // increase unspent tx count
                    Api.EscrowUpdate(this.jetSession, this.globalsTableId, this.unspentTxCountColumnId, +1);

                    return(true);
                }
            }
            catch (EsentKeyDuplicateException)
            {
                return(false);
            }
        }