Пример #1
0
        public void RequestBlocks(BlockHeader[] headers)
        {
            MemoryStream stream = new MemoryStream();
            BinaryWriter bw = new BinaryWriter(stream);

            int count = headers.Length;
            Program.WriteVarInt(bw, (ulong)count);
            foreach (BlockHeader b in headers)
            {
                const int blockType = 2;
                bw.Write(blockType);
                bw.Write(b.mHash);
            }
            SendPacket("getdata", stream.ToArray());

            bw.Close();
        }
Пример #2
0
        public void Load(BinaryReader br)
        {
            int version = br.ReadInt32();
            mCurrentHeight = br.ReadUInt32();

            mBlockLock.WaitOne();
            mBlocks.Clear();
            int blockCount = br.ReadInt32();
            for (int i = 0; i < blockCount; i++)
            {
                BlockHeader h = new BlockHeader();
                h.Load(br);
                Block b = new Block();
                b.mHeader = h;
                b.mHash = Program.HashToString(h.mHash);
                mBlocks.Add(b);
            }
            mBlockLock.ReleaseMutex();
        }
Пример #3
0
        public void HandleBlockPacket(NodeConnection node, byte[] payload)
        {
            MemoryStream stream = new MemoryStream(payload);
            BinaryReader br = new BinaryReader(stream);

            uint version = br.ReadUInt32();
            byte[] prevBlock = br.ReadBytes(32);
            byte[] merkle = br.ReadBytes(32);
            uint time = br.ReadUInt32();
            uint bits = br.ReadUInt32();
            uint nonce = br.ReadUInt32();
            ulong txn = Program.ReadVarInt(br);

            BlockHeader h = new BlockHeader(version, prevBlock, merkle, time, bits, nonce);
            h.ComputeHash(mScryptBlockHash);
            string hash = Program.HashToString(h.mHash);

            Block block = FindBlock(hash);
            if( block == null )
            {
                // Create a new block
                block = new Block();
                block.mHeader = h;
                mBlockLock.WaitOne();
                mBlocks.Add(block);
                mBlockLock.ReleaseMutex();
            }

            block.mTransactions.Clear();
            if (mWantsTransactionData)
            {
                for (ulong j = 0; j < txn; j++)
                {
                    Transaction tx = new Transaction();
                    tx.mVersion = br.ReadUInt32();
                    tx.mTimestamp = br.ReadUInt32();

                    ulong inCount = Program.ReadVarInt(br);
                    for (ulong k = 0; k < inCount; k++)
                    {
                        TransactionInput ti = new TransactionInput();
                        ti.mPrevOuptutHash = br.ReadBytes(32);
                        ti.mPrevOutputIndex = br.ReadUInt32();

                        ulong scriptLen = Program.ReadVarInt(br);
                        ti.mScript = br.ReadBytes((int)scriptLen);

                        ti.mSequence = br.ReadUInt32();

                        tx.mInputs.Add(ti);
                    }

                    ulong outCount = Program.ReadVarInt(br);
                    for (ulong k = 0; k < outCount; k++)
                    {
                        TransactionOutput to = new TransactionOutput();
                        to.mValue = br.ReadUInt64();
                        to.mRealValue = (double)to.mValue / 1000000.0;

                        ulong scriptLen = Program.ReadVarInt(br);
                        to.mScript = br.ReadBytes((int)scriptLen);

                        tx.mOutputs.Add(to);
                    }
                    tx.mLockTime = br.ReadUInt32();
                    if (tx.mVersion > 1)
                    {
                        ulong commentLen = Program.ReadVarInt(br);
                        tx.mComment = br.ReadBytes((int)commentLen);
                    }

                    block.mTransactions.Add(tx);
                }
            }
            br.Close();
        }
Пример #4
0
        public void HandleHeadersPacket(NodeConnection node, byte[] payload)
        {
            MemoryStream stream = new MemoryStream(payload);
            BinaryReader br = new BinaryReader(stream);

            List<BlockHeader> headers = new List<BlockHeader>();

            ulong count = Program.ReadVarInt(br);
            if (count == 0)
            {
                mPullingHeaders = false;
                return;
            }
            for (ulong i = 0; i < count; i++)
            {
                uint version = br.ReadUInt32();
                byte[] prevBlock = br.ReadBytes(32);
                byte[] merkle = br.ReadBytes(32);
                uint time = br.ReadUInt32();
                uint bits = br.ReadUInt32();
                uint nonce = br.ReadUInt32();
                ulong txn = Program.ReadVarInt(br);

                if( !mIgnoreSigLen )
                {
                    ulong siglen = Program.ReadVarInt(br);
                }

                BlockHeader header = new BlockHeader(version, prevBlock, merkle, time, bits, nonce);
                if (headers.Count > 0)
                    headers[headers.Count - 1].mHash = prevBlock;
                headers.Add(header);
            }
            br.Close();

            if( headers[0].mHash != null )
                headers[0].ValidateHash();

            mBlockLock.WaitOne();
            foreach (BlockHeader h in headers)
            {
                Block b = new Block();
                b.mHeader = h;
                if (b.mHeader.mHash == null)
                    b.mHeader.ComputeHash(mScryptBlockHash);
                b.mHash = Program.HashToString(b.mHeader.mHash);
                mBlocks.Add(b);
            }
            mCurrentHeight += (uint)headers.Count;

            if (count < 2000)
            {
                // End of the list
                // Remove all blocks that are older than we care about
                RemoveOldBlocks();

                // If we want transaction data, request the full blocks
                if (mWantsTransactionData)
                {
                    headers.Clear();
                    mBlockLock.WaitOne();
                    foreach( Block b in mBlocks )
                    {
                        if( b.mTransactions.Count < 1)
                            headers.Add(b.mHeader);
                    }
                    mBlockLock.ReleaseMutex();
                    node.RequestBlocks(headers.ToArray());
                }
                mPullingHeaders = false;
            }
            else
            {
                // Request again til we get all of them
                node.RequestHeaders(mBlocks[mBlocks.Count - 1].mHeader.mHash);
            }
            mBlockLock.ReleaseMutex();

            Console.WriteLine("Blocks: " + mCurrentHeight);
        }