Ejemplo n.º 1
0
        private IEnumerable <BlockTx> ReadBlockTransactions(UInt256 blockHash, int blockId)
        {
            using (var handle = this.cursorCache.TakeItem())
            {
                var cursor = handle.Item;

                using (var jetTx = cursor.jetSession.BeginTransaction())
                {
                    var sha256 = new SHA256Managed();

                    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))
                    {
                        yield break;
                    }

                    do
                    {
                        if (blockId != Api.RetrieveColumnAsInt32(cursor.jetSession, cursor.blocksTableId, cursor.blockIdColumnId).Value)
                        {
                            yield break;
                        }

                        var txIndex = Api.RetrieveColumnAsInt32(cursor.jetSession, cursor.blocksTableId, cursor.blockTxIndexColumnId).Value;
                        var depth   = Api.RetrieveColumnAsInt32(cursor.jetSession, cursor.blocksTableId, cursor.blockDepthColumnId).Value;
                        var txHash  = DbEncoder.DecodeUInt256(Api.RetrieveColumn(cursor.jetSession, cursor.blocksTableId, cursor.blockTxHashColumnId));
                        var txBytes = Api.RetrieveColumn(cursor.jetSession, cursor.blocksTableId, cursor.blockTxBytesColumnId);

                        // determine if transaction is pruned by its depth
                        var pruned = depth >= 0;
                        depth = Math.Max(0, depth);

                        Transaction tx;
                        if (!pruned)
                        {
                            // verify transaction is not corrupt
                            if (txHash != new UInt256(sha256.ComputeDoubleHash(txBytes)))
                            {
                                throw new MissingDataException(blockHash);
                            }

                            tx = DataEncoder.DecodeTransaction(txBytes);
                        }
                        else
                        {
                            tx = null;
                        }

                        var blockTx = new BlockTx(txIndex, depth, txHash, pruned, tx);

                        yield return(blockTx);
                    } while (Api.TryMoveNext(cursor.jetSession, cursor.blocksTableId));
                }
            }
        }
Ejemplo n.º 2
0
        public bool TryGetTransaction(UInt256 blockHash, int txIndex, out Transaction transaction)
        {
            int blockId;

            if (!this.TryGetBlockId(blockHash, out blockId))
            {
                transaction = default(Transaction);
                return(false);
            }

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

                using (var jetTx = cursor.jetSession.BeginTransaction())
                {
                    Api.JetSetCurrentIndex(cursor.jetSession, cursor.blocksTableId, "IX_BlockIdTxIndex");
                    Api.MakeKey(cursor.jetSession, cursor.blocksTableId, blockId, MakeKeyGrbit.NewKey);
                    Api.MakeKey(cursor.jetSession, cursor.blocksTableId, txIndex, MakeKeyGrbit.None);
                    if (Api.TrySeek(cursor.jetSession, cursor.blocksTableId, SeekGrbit.SeekEQ))
                    {
                        var txBytes = Api.RetrieveColumn(cursor.jetSession, cursor.blocksTableId, cursor.blockTxBytesColumnId);
                        if (txBytes != null)
                        {
                            transaction = DataEncoder.DecodeTransaction(txBytes);
                            return(true);
                        }
                        else
                        {
                            transaction = default(Transaction);
                            return(false);
                        }
                    }
                    else
                    {
                        transaction = default(Transaction);
                        return(false);
                    }
                }
            }
        }
Ejemplo n.º 3
0
 public TransactionStorage(string baseDirectory)
     : base(baseDirectory, "Transactions",
            tx => DataEncoder.EncodeTransaction(tx),
            (txHash, bytes) => DataEncoder.DecodeTransaction(bytes, txHash))
 {
 }
Ejemplo n.º 4
0
        private Message WireDecodeMessage(UInt32 magic, Stream stream)
        {
            byte[]  payload;
            Message message;

            using (var reader = new BinaryReader(stream, Encoding.ASCII, leaveOpen: true))
            {
                var command         = reader.ReadFixedString(12);
                var payloadSize     = reader.ReadUInt32();
                var payloadChecksum = reader.ReadUInt32();

                payload = reader.ReadBytes(payloadSize.ToIntChecked());

                if (!Messaging.VerifyPayloadChecksum(payloadChecksum, payload))
                {
                    throw new Exception(string.Format("Checksum failed for {0}", command));
                }

                message = new Message
                          (
                    Magic: magic,
                    Command: command,
                    PayloadSize: payloadSize,
                    PayloadChecksum: payloadChecksum,
                    Payload: payload.ToImmutableArray()
                          );
            }

            switch (message.Command)
            {
            case "addr":
            {
                var addressPayload = NodeEncoder.DecodeAddressPayload(payload);

                var handler = this.OnReceivedAddresses;
                if (handler != null)
                {
                    handler(addressPayload.NetworkAddresses);
                }
            }
            break;

            case "alert":
            {
                var alertPayload = NodeEncoder.DecodeAlertPayload(payload);
            }
            break;

            case "block":
            {
                var block = DataEncoder.DecodeBlock(payload);

                var handler = this.OnBlock;
                if (handler != null)
                {
                    handler(this.owner, block);
                }
            }
            break;

            case "getblocks":
            {
                var getBlocksPayload = NodeEncoder.DecodeGetBlocksPayload(payload);

                var handler = this.OnGetBlocks;
                if (handler != null)
                {
                    handler(getBlocksPayload);
                }
            }
            break;

            case "getheaders":
            {
                var getHeadersPayload = NodeEncoder.DecodeGetBlocksPayload(payload);

                var handler = this.OnGetHeaders;
                if (handler != null)
                {
                    handler(getHeadersPayload);
                }
            }
            break;

            case "getdata":
            {
                var invPayload = NodeEncoder.DecodeInventoryPayload(payload);

                var handler = this.OnGetData;
                if (handler != null)
                {
                    handler(invPayload);
                }
            }
            break;

            case "headers":
            {
                var blockHeaders = ImmutableList.CreateBuilder <BlockHeader>();

                using (var headerStream = new MemoryStream(payload))
                    using (var reader = new BinaryReader(headerStream))
                    {
                        var headerCount = reader.ReadVarInt().ToIntChecked();

                        for (var i = 0; i < headerCount; i++)
                        {
                            var blockHeader = DataEncoder.DecodeBlockHeader(headerStream);
                            //TODO wiki says this is a byte and a var int, which is it?
                            var txCount = reader.ReadVarInt();

                            blockHeaders.Add(blockHeader);
                        }
                    }

                var handler = this.OnBlockHeaders;
                if (handler != null)
                {
                    handler(this.owner, blockHeaders.ToImmutable());
                }
            }
            break;

            case "inv":
            {
                var invPayload = NodeEncoder.DecodeInventoryPayload(payload);

                var handler = this.OnInventoryVectors;
                if (handler != null)
                {
                    handler(invPayload.InventoryVectors);
                }
            }
            break;

            case "notfound":
            {
                var invPayload = NodeEncoder.DecodeInventoryPayload(payload);

                var handler = this.OnNotFound;
                if (handler != null)
                {
                    handler(invPayload.InventoryVectors);
                }
            }
            break;

            case "ping":
            {
                var handler = this.OnPing;
                if (handler != null)
                {
                    handler(payload.ToImmutableArray());
                }
            }
            break;

            case "tx":
            {
                var tx = DataEncoder.DecodeTransaction(payload);

                var handler = this.OnTransaction;
                if (handler != null)
                {
                    handler(tx);
                }
            }
            break;

            case "version":
            {
                var versionPayload = NodeEncoder.DecodeVersionPayload(payload, payload.Length);

                var handler = this.OnVersion;
                if (handler != null)
                {
                    handler(versionPayload);
                }
            }
            break;

            case "verack":
            {
                var handler = this.OnVersionAcknowledged;
                if (handler != null)
                {
                    handler();
                }
            }
            break;

            default:
            {
                this.logger.Warn("Unhandled incoming message: {0}".Format2(message.Command));
            }
            break;
            }

            //TODO
            //if (payloadStream.Position != payloadStream.Length)
            //{
            //    var exMessage = string.Format("Wrong number of bytes read for {0}, parser error: read {1} bytes from a {2} byte payload", message.Command, payloadStream.Position, payloadStream.Length);
            //    Debug.WriteLine(exMessage);
            //    throw new Exception(exMessage);
            //}

            return(message);
        }
Ejemplo n.º 5
0
        public void TestWireDecodeTransaction()
        {
            var actual = DataEncoder.EncodeTransaction(DataEncoder.DecodeTransaction(TRANSACTION_1_BYTES.ToArray()));

            CollectionAssert.AreEqual(TRANSACTION_1_BYTES.ToList(), actual.ToList());
        }