Esempio n. 1
0
        public async Task <IEnumerable <HashDigest <SHA256> > > GetBlocksAsync(
            Peer peer,
            IEnumerable <HashDigest <SHA256> > hashes,
            HashDigest <SHA256>?stop,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            CheckEntered();

            if (!_dealers.TryGetValue(peer.Address, out DealerSocket sock))
            {
                throw new PeerNotFoundException(
                          $"The peer[{peer.Address}] could not be found.");
            }

            var request = new GetBlocks(new BlockLocator(hashes), stop);
            await sock.SendMultipartMessageAsync(
                request.ToNetMQMessage(_privateKey),
                cancellationToken : cancellationToken);

            NetMQMessage response = await sock.ReceiveMultipartMessageAsync();

            Message parsedMessage = Message.Parse(response, reply: true);

            if (parsedMessage is Inventory inv)
            {
                return(inv.BlockHashes);
            }

            throw new InvalidMessageException(
                      $"The response of getblock isn't inventory. " +
                      $"but {parsedMessage}");
        }
Esempio n. 2
0
        private void Start()
        {
            towerBuilder = GetComponent <TowerBuilder>();
            blocks       = towerBuilder.BuildTower();

            foreach (var block in blocks)
            {
                block.BulletHit += OnBulletHit;
            }

            GetBlocks?.Invoke(blocks.Count);
        }
Esempio n. 3
0
        private void OnBulletHit(Block hitBlock)
        {
            hitBlock.BulletHit -= OnBulletHit;
            blocks.Remove(hitBlock);

            foreach (var block in blocks)
            {
                block.transform.position = new Vector3(
                    block.transform.position.x,
                    block.transform.position.y - towerBuilder.DistanceBetweenBlocks,
                    block.transform.position.z);
            }
            GetBlocks?.Invoke(blocks.Count);
        }
Esempio n. 4
0
 private async Task TransferBlocks <T>(
     Blockchain <T> blockchain,
     GetBlocks getData,
     CancellationToken cancellationToken)
     where T : IAction
 {
     foreach (HashDigest <SHA256> hash in getData.BlockHashes)
     {
         if (blockchain.Blocks.TryGetValue(hash, out Block <T> block))
         {
             Message response = new Block(block.ToBencodex(true, true))
             {
                 Identity = getData.Identity,
             };
             await ReplyAsync(response, cancellationToken);
         }
     }
 }
Esempio n. 5
0
        internal IAsyncEnumerable <Block <T> > GetBlocksAsync <T>(
            DealerSocket sock,
            IEnumerable <HashDigest <SHA256> > blockHashes,
            CancellationToken cancellationToken)
            where T : IAction
        {
            return(new AsyncEnumerable <Block <T> >(async yield =>
            {
                var request = new GetBlocks(blockHashes);
                await sock.SendMultipartMessageAsync(
                    request.ToNetMQMessage(_privateKey),
                    cancellationToken: cancellationToken);

                int hashCount = blockHashes.Count();
                while (hashCount > 0)
                {
                    NetMQMessage response =
                        await sock.ReceiveMultipartMessageAsync(
                            cancellationToken: cancellationToken);
                    Message parsedMessage = Message.Parse(response, true);
                    if (parsedMessage is Block blockMessage)
                    {
                        Block <T> block = Block <T> .FromBencodex(
                            blockMessage.Payload);
                        await yield.ReturnAsync(block);
                        hashCount--;
                    }
                    else
                    {
                        throw new InvalidMessageException(
                            $"The response of getdata isn't block. " +
                            $"but {parsedMessage}");
                    }
                }
            }));
        }
Esempio n. 6
0
        private void TransferBlocks(GetBlocks getData)
        {
            string identityHex = ByteUtil.Hex(getData.Identity);

            _logger.Verbose(
                $"Preparing a {nameof(Blocks)} message to reply to {{Identity}}...",
                identityHex
                );

            var blocks = new List <byte[]>();

            List <HashDigest <SHA256> > hashes = getData.BlockHashes.ToList();
            int          i      = 1;
            int          total  = hashes.Count;
            const string logMsg =
                "Fetching a block #{Index}/{Total} ({Hash}) to include to " +
                "a reply to {Identity}...";

            foreach (HashDigest <SHA256> hash in hashes)
            {
                _logger.Verbose(logMsg, i, total, hash, identityHex);
                if (_store.ContainsBlock(hash))
                {
                    Block <T> block   = _store.GetBlock <T>(hash);
                    byte[]    payload = block.Serialize();
                    blocks.Add(payload);
                }

                if (blocks.Count == getData.ChunkSize)
                {
                    var response = new Messages.Blocks(blocks)
                    {
                        Identity = getData.Identity,
                    };
                    _logger.Verbose(
                        "Enqueuing a blocks reply (...{Index}/{Total})...",
                        i,
                        total
                        );
                    Transport.ReplyMessage(response);
                    blocks.Clear();
                }

                i++;
            }

            if (blocks.Any())
            {
                var response = new Messages.Blocks(blocks)
                {
                    Identity = getData.Identity,
                };
                _logger.Verbose(
                    "Enqueuing a blocks reply (...{Index}/{Total}) to {Identity}...",
                    total,
                    total,
                    identityHex
                    );
                Transport.ReplyMessage(response);
            }

            _logger.Debug("Blocks were transferred to {Identity}.", identityHex);
        }
Esempio n. 7
0
        public async Task GetMultipleBlocksAtOnce()
        {
            var privateKey = new PrivateKey();

            BlockChain <DumbAction> chainA = _blockchains[0];
            BlockChain <DumbAction> chainB = _blockchains[1];

            Swarm <DumbAction> swarmA = _swarms[0];
            Swarm <DumbAction> swarmB = new Swarm <DumbAction>(
                chainB,
                privateKey,
                1,
                host: IPAddress.Loopback.ToString());

            Block <DumbAction> genesis = chainA.MineBlock(_fx1.Address1);

            chainB.Append(genesis); // chainA and chainB shares genesis block.
            chainA.MineBlock(_fx1.Address1);
            chainA.MineBlock(_fx1.Address1);

            try
            {
                await StartAsync(swarmA);
                await StartAsync(swarmB);

                var peer = swarmA.AsPeer;

                await swarmB.AddPeersAsync(new[] { peer });

                IEnumerable <HashDigest <SHA256> > hashes =
                    await swarmB.GetBlockHashesAsync(
                        peer,
                        new BlockLocator(new[] { genesis.Hash }),
                        null);

                var netMQAddress = $"tcp://{peer.EndPoint.Host}:{peer.EndPoint.Port}";
                using (var socket = new DealerSocket(netMQAddress))
                {
                    var request = new GetBlocks(hashes, 2);
                    await socket.SendMultipartMessageAsync(
                        request.ToNetMQMessage(privateKey));

                    NetMQMessage response = await socket.ReceiveMultipartMessageAsync();

                    Message parsedMessage = Message.Parse(response, true);
                    Libplanet.Net.Messages.Blocks blockMessage =
                        (Libplanet.Net.Messages.Blocks)parsedMessage;

                    Assert.Equal(2, blockMessage.Payloads.Count);

                    response = await socket.ReceiveMultipartMessageAsync();

                    parsedMessage = Message.Parse(response, true);
                    blockMessage  = (Libplanet.Net.Messages.Blocks)parsedMessage;

                    Assert.Single(blockMessage.Payloads);
                }
            }
            finally
            {
                await Task.WhenAll(
                    swarmA.StopAsync(),
                    swarmB.StopAsync());
            }
        }
Esempio n. 8
0
        private async Task TransferBlocksAsync(GetBlocks getData)
        {
            string identityHex = ByteUtil.Hex(getData.Identity);

            _logger.Verbose(
                "Preparing a {MessageType} message to reply to {Identity}...",
                nameof(Messages.Blocks),
                identityHex
                );

            var blocks = new List <byte[]>();

            List <BlockHash> hashes = getData.BlockHashes.ToList();
            int          i          = 1;
            int          total      = hashes.Count;
            const string logMsg     =
                "Fetching block {Index}/{Total} {Hash} to include in " +
                "a reply to {Identity}...";

            foreach (BlockHash hash in hashes)
            {
                _logger.Verbose(logMsg, i, total, hash, identityHex);
                if (_store.GetBlock <T>(BlockChain.Policy.GetHashAlgorithm, hash) is { } block)
                {
                    byte[] payload = Codec.Encode(block.MarshalBlock());
                    blocks.Add(payload);
                }

                if (blocks.Count == getData.ChunkSize)
                {
                    var response = new Messages.Blocks(blocks)
                    {
                        Identity = getData.Identity,
                    };
                    _logger.Verbose(
                        "Enqueuing a blocks reply (...{Index}/{Total})...",
                        i,
                        total
                        );
                    await Transport.ReplyMessageAsync(response, default);

                    blocks.Clear();
                }

                i++;
            }

            if (blocks.Any())
            {
                var response = new Messages.Blocks(blocks)
                {
                    Identity = getData.Identity,
                };
                _logger.Verbose(
                    "Enqueuing a blocks reply (...{Index}/{Total}) to {Identity}...",
                    total,
                    total,
                    identityHex
                    );
                await Transport.ReplyMessageAsync(response, default);
            }

            _logger.Debug("Blocks were transferred to {Identity}.", identityHex);
        }
Esempio n. 9
0
        private async Task ReadStream()
        {
            while (!Closing)
            {
                try
                {
                    //try to read a header
                    var hdata = new byte[24];
                    await Stream.ReadAsyncExact(hdata, 0, hdata.Length);

                    var h = new MessageHeader();
                    h.ReadFromPayload(hdata, 0);
                    if (h != null)
                    {
                        //read the payload
                        var pl = new byte[h.PayloadSize];
                        await Stream.ReadAsyncExact(pl, 0, pl.Length);

                        bool checksumOk = false;

                        //verify hash
                        using (var sha = SHA256.Create())
                        {
                            var h1 = sha.ComputeHash(pl);
                            var h2 = sha.ComputeHash(h1);

                            checksumOk = h2[0] == h.Checksum[0] && h2[1] == h.Checksum[1] && h2[2] == h.Checksum[2] && h2[3] == h.Checksum[3];
                        }

                        if (checksumOk)
                        {
                            switch (h.Command)
                            {
                            case "addr\0\0\0\0\0\0\0\0":
                            {
                                if (OnAddr != null)
                                {
                                    var a = new Addr();
                                    a.ReadFromPayload(pl, 0);

                                    await OnAddr?.Invoke(this, a);
                                }
                                break;
                            }

                            case "alert\0\0\0\0\0\0\0":
                            {
                                if (OnAlert != null)
                                {
                                    var a = new Alert();
                                    a.ReadFromPayload(pl, 0);

                                    await OnAlert?.Invoke(this, a);
                                }
                                break;
                            }

                            case "feefilter\0\0\0":
                            {
                                if (OnFeeFilter != null)
                                {
                                    var f = new FeeFilter();
                                    f.ReadFromPayload(pl, 0);

                                    await OnFeeFilter?.Invoke(this, f);
                                }
                                break;
                            }

                            case "filteradd\0\0\0":
                            {
                                if (OnFilterAdd != null)
                                {
                                    var f = new FilterAdd();
                                    f.ReadFromPayload(pl, 0);

                                    await OnFilterAdd?.Invoke(this, f);
                                }
                                break;
                            }

                            case "filterclear\0":
                            {
                                if (OnFilterClear != null)
                                {
                                    var f = new FilterClear();
                                    f.ReadFromPayload(pl, 0);

                                    await OnFilterClear?.Invoke(this, f);
                                }
                                break;
                            }

                            case "filterload\0\0":
                            {
                                if (OnFilterLoad != null)
                                {
                                    var f = new FilterLoad();
                                    f.ReadFromPayload(pl, 0);

                                    await OnFilterLoad?.Invoke(this, f);
                                }
                                break;
                            }

                            case "getaddr\0\0\0\0\0":
                            {
                                if (OnGetAddr != null)
                                {
                                    var ga = new GetAddr();
                                    ga.ReadFromPayload(pl, 0);

                                    await OnGetAddr?.Invoke(this, ga);
                                }
                                break;
                            }

                            case "getblocks\0\0\0":
                            {
                                if (OnGetBlocks != null)
                                {
                                    var gb = new GetBlocks();
                                    gb.ReadFromPayload(pl, 0);

                                    await OnGetBlocks?.Invoke(this, gb);
                                }
                                break;
                            }

                            case "getdata\0\0\0\0\0":
                            {
                                if (OnGetData != null)
                                {
                                    var gd = new GetData();
                                    gd.ReadFromPayload(pl, 0);

                                    await OnGetData?.Invoke(this, gd);
                                }
                                break;
                            }

                            case "getheaders\0\0":
                            {
                                if (OnGetHeaders != null)
                                {
                                    var gh = new GetHeaders();
                                    gh.ReadFromPayload(pl, 0);

                                    await OnGetHeaders?.Invoke(this, gh);
                                }
                                break;
                            }

                            case "headers\0\0\0\0\0":
                            {
                                if (OnHeaders != null)
                                {
                                    var hd = new Headers();
                                    hd.ReadFromPayload(pl, 0);

                                    await OnHeaders?.Invoke(this, hd);
                                }
                                break;
                            }

                            case "inv\0\0\0\0\0\0\0\0\0":
                            {
                                if (OnInv != null)
                                {
                                    var iv = new Inv();
                                    iv.ReadFromPayload(pl, 0);

                                    await OnInv?.Invoke(this, iv);
                                }
                                break;
                            }

                            case "mempool\0\0\0\0\0":
                            {
                                if (OnMemPool != null)
                                {
                                    var mp = new MemPool();
                                    mp.ReadFromPayload(pl, 0);

                                    await OnMemPool?.Invoke(this, mp);
                                }
                                break;
                            }

                            case "notfound\0\0\0\0":
                            {
                                if (OnNotFound != null)
                                {
                                    var nf = new NotFound();
                                    nf.ReadFromPayload(pl, 0);

                                    await OnNotFound?.Invoke(this, nf);
                                }
                                break;
                            }

                            case "ping\0\0\0\0\0\0\0\0":
                            {
                                if (OnPing != null)
                                {
                                    var ping = new Ping();
                                    ping.ReadFromPayload(pl, 0);

                                    await OnPing?.Invoke(this, ping);
                                }
                                break;
                            }

                            case "pong\0\0\0\0\0\0\0\0":
                            {
                                if (OnPong != null)
                                {
                                    var pong = new Pong();
                                    pong.ReadFromPayload(pl, 0);

                                    await OnPong?.Invoke(this, pong);
                                }
                                break;
                            }

                            case "reject\0\0\0\0\0\0":
                            {
                                if (OnReject != null)
                                {
                                    var re = new Reject();
                                    re.ReadFromPayload(pl, 0);

                                    await OnReject?.Invoke(this, re);
                                }
                                break;
                            }

                            case "sendheaders\0":
                            {
                                if (OnSendHeaders != null)
                                {
                                    var sh = new SendHeaders();
                                    sh.ReadFromPayload(pl, 0);

                                    await OnSendHeaders?.Invoke(this, sh);
                                }
                                break;
                            }

                            case "verack\0\0\0\0\0\0":
                            {
                                if (OnVerAck != null)
                                {
                                    var va = new VerAck();
                                    va.ReadFromPayload(pl, 0);

                                    await OnVerAck.Invoke(this, va);
                                }
                                break;
                            }

                            case "version\0\0\0\0\0":
                            {
                                if (OnVersion != null)
                                {
                                    var v = new bitcoin_lib.P2P.Version("");
                                    v.ReadFromPayload(pl, 0);

                                    await OnVersion?.Invoke(this, v);
                                }
                                break;
                            }

                            default:
                            {
                                //Console.WriteLine($"Got cmd: {h.Command}");
                                break;
                            }
                            }
                        }
                        else
                        {
                            Closing = true;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Closing = true;
                }
            }
        }
Esempio n. 10
0
 private Task Peer_OnGetBlocks(BitcoinPeer s, GetBlocks gb)
 {
     throw new NotImplementedException();
 }