Beispiel #1
0
        public void TestContainsKey()
        {
            AddTransactions(10);

            var txToAdd = CreateTransaction();

            _unit.TryAdd(txToAdd.Hash, txToAdd);
            _unit.ContainsKey(txToAdd.Hash).Should().BeTrue();
            _unit.InvalidateVerifiedTransactions();
            _unit.ContainsKey(txToAdd.Hash).Should().BeTrue();
        }
        public void TestContainsKey()
        {
            var snapshot = GetSnapshot();

            AddTransactions(10);

            var txToAdd = CreateTransaction();

            _unit.TryAdd(txToAdd, snapshot);
            _unit.ContainsKey(txToAdd.Hash).Should().BeTrue();
            _unit.InvalidateVerifiedTransactions();
            _unit.ContainsKey(txToAdd.Hash).Should().BeTrue();
        }
Beispiel #3
0
        /// <summary>
        /// Allocate a block of memory based upon a best fit policy.
        /// </summary>
        /// <param name="iBlockSizeRequest"></param>
        /// <returns></returns>
        public MemoryBlock Allocate(int iBlockSizeRequest)
        {
            try
            {
                IEnumerable <KeyValuePair <int, List <int> > > availableMemoryBlocks =
                    from entry in MemoryPool
                    where (entry.Key) >= iBlockSizeRequest
                    orderby entry.Key ascending
                    select entry;
                if (0 == availableMemoryBlocks.Count())
                {
                    return(new MemoryBlock());
                }
                KeyValuePair <int, List <int> > smallestBlocks = availableMemoryBlocks.First();
                int iBlockSize    = smallestBlocks.Key;
                int iBlockAddress = smallestBlocks.Value.First();
                smallestBlocks.Value.RemoveAt(0);

                if (0 == smallestBlocks.Value.Count())
                {
                    MemoryPool.Remove(iBlockSize);
                }

                if (iBlockSize > iBlockSizeRequest)
                {
                    int iBlockRemainderSize    = iBlockSize - iBlockSizeRequest;
                    int iBlockRemainderAddress = iBlockAddress + iBlockSizeRequest;
                    if (MemoryPool.ContainsKey(iBlockRemainderSize))
                    {
                        Debug.Assert(!MemoryPool[iBlockRemainderSize].Contains(iBlockRemainderAddress));
                        MemoryPool[iBlockRemainderSize].Add(iBlockRemainderAddress);
                    }
                    else
                    {
                        MemoryPool.Add(iBlockRemainderSize, new List <int>()
                        {
                            iBlockRemainderAddress
                        });
                    }
                }
                return(new MemoryBlock()
                {
                    BlockAddress = iBlockAddress, BlockSize = iBlockSizeRequest
                });
            }
            catch (Exception)
            {
                throw;
            }
        }
Beispiel #4
0
        async Task HandleAdvertise(InventoryMessage message, int peerId)
        {
            // Data should not contain anything. (To prevent DDoS)
            if (!message.Data.IsNull())
            {
                throw new ArgumentException();
            }

            var haveObject = message.IsBlock ?
                             Blocks.ContainsKey(message.ObjectId) :
                             MemoryPool.ContainsKey(message.ObjectId);

            if (haveObject)
            {
                return;
            }

            message.Type = Request;
            await ConnectionManager.SendAsync(message, peerId);
        }
Beispiel #5
0
        bool TryAddTransactionToMemoryPool(ByteString id, byte[] data)
        {
            // Data should not exceed the maximum size.
            if (data.Length > MaximumTransactionSize)
            {
                throw new ArgumentException();
            }

            // Integrity check.
            var computedId = Hash.ComputeDoubleSHA256(data);

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

            if (MemoryPool.ContainsKey(id))
            {
                return(false);
            }

            var tx = BlockchainUtil.DeserializeTransaction(data);

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

            lock (MemoryPool)
            {
                if (MemoryPool.ContainsKey(id))
                {
                    return(false);
                }
                MemoryPool.Add(id, tx);
            }

            return(true);
        }
Beispiel #6
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);
        }//ネットワーク全体にもらったブロックを発信する