Exemple #1
0
        public Block TryLoadBlock(ByteString id, byte[] data)
        {
            // Data should not exceed the maximum size.
            if (data.Length > MaximumBlockSize)
            {
                throw new ArgumentException(nameof(data));
            }

            // Integrity check.
            var computedId = BlockchainUtil.ComputeBlockId(data);

            if (!ByteString.CopyFrom(computedId).Equals(id))
            {
                throw new ArgumentException(nameof(id));
            }

            // Try to deserialize the data for format validity check.
            var block = BlockchainUtil.DeserializeBlock(data);

            lock (Blocks)
            {
                if (Blocks.ContainsKey(id))
                {
                    return(null);
                }
                Blocks.Add(id, data);
            }

            // Schedule the block for execution.
            Executor.ProcessBlock(block);

            return(block);
        }
Exemple #2
0
        async Task HandleBody(InventoryMessage message, int peerId)
        {
            // Data should not exceed the maximum size.
            var data = message.Data;

            if (data.Length > MaximumBlockSize)
            {
                throw new ArgumentException();
            }

            // ハッシュ値正しい?
            var id = message.IsBlock ?
                     BlockchainUtil.ComputeBlockId(data) :
                     Hash.ComputeDoubleSHA256(data);

            if (!ByteString.CopyFrom(id).Equals(message.ObjectId))
            {
                return;
            }

            if (message.IsBlock)
            {
                // ミューテックス
                lock (Blocks)
                {
                    if (Blocks.ContainsKey(message.ObjectId))
                    {
                        return;
                    }
                    // ハッシュテーブルに追加
                    Blocks.Add(message.ObjectId, data);
                }

                var block = BlockchainUtil.DeserializeBlock(data);
                // 前のブロックも知らなかったら前のももらう
                var prevId = block.PreviousHash;
                if (!Blocks.ContainsKey(prevId))
                {
                    await ConnectionManager.SendAsync(new InventoryMessage
                    {
                        Type     = Request,
                        IsBlock  = true,
                        ObjectId = prevId,
                    }, peerId);
                }
                Executor.ProcessBlock(block);
            }
            else
            {
                if (MemoryPool.ContainsKey(message.ObjectId))
                {
                    return;
                }

                var tx = BlockchainUtil.DeserializeTransaction(data);

                // Ignore the coinbase transactions.
                if (tx.InEntries.Count == 0)
                {
                    return;
                }

                lock (MemoryPool)
                {
                    if (MemoryPool.ContainsKey(message.ObjectId))
                    {
                        return;
                    }
                    MemoryPool.Add(message.ObjectId, tx);
                }
            }

            message.Type = Advertise;
            message.Data = null;
            // 他の人に教えてあげる
            await ConnectionManager.BroadcastAsync(message, peerId);
        }
        async Task HandleBody(InventoryMessage message, int peerId)
        {
            // Data should not exceed the maximum size.
            var data = message.Data;

            if (data.Length > MaximumBlockSize)
            {
                throw new ArgumentException();
            }

            var id = message.IsBlock ?
                     BlockchainUtil.ComputeBlockId(data) :
                     Hash.ComputeDoubleSHA256(data);

            if (!ByteString.CopyFrom(id).Equals(message.ObjectId))
            {
                return;
            }

            if (message.IsBlock)
            {
                lock (Blocks)//並列処理を避ける
                {
                    if (Blocks.ContainsKey(message.ObjectId))
                    {
                        return;
                    }
                    Blocks.Add(message.ObjectId, data);
                }

                var prevId = Deserialize <Block>(data).PreviousHash;
                if (!Blocks.ContainsKey(prevId))
                {
                    await ConnectionManager.SendAsync(new InventoryMessage//当該ブロックの前のブロックを持っていない場合はそれもRequestする(前のblockのIDが必要なため
                    {
                        Type     = Request,
                        IsBlock  = true,
                        ObjectId = prevId,
                    }, peerId);
                }
                else
                {
                    Executor.ProcessBlock(data, prevId);
                }
            }
            else
            {
                if (MemoryPool.ContainsKey(message.ObjectId))
                {
                    return;
                }

                var tx = BlockchainUtil.DeserializeTransaction(data);

                // Ignore the coinbase transactions.
                if (tx.InEntries.Count == 0)
                {
                    return;
                }

                lock (MemoryPool)
                {
                    if (MemoryPool.ContainsKey(message.ObjectId))
                    {
                        return;
                    }
                    MemoryPool.Add(message.ObjectId, tx);
                }
            }

            message.Type = Advertise;
            message.Data = null;
            await ConnectionManager.BroadcastAsync(message, peerId);
        }//ネットワーク全体にもらったブロックを発信する