Пример #1
0
        public async Task Put_Informs_Bitswap()
        {
            _dfs = TestDfs.GetTestDfs(null, "sha2-256");
            await _dfs.StartAsync();

            try
            {
                var data = Guid.NewGuid().ToByteArray();
                var cid  = new Cid
                {
                    Hash = MultiHash.ComputeHash(data)
                };

                var cts = new CancellationTokenSource();
                cts.CancelAfter(20000);

                var wantTask = _dfs.BitSwapApi.GetAsync(cid, cts.Token);
                var cid1     = await _dfs.BlockApi.PutAsync(data, cancel : cts.Token);

                Assert.AreEqual(cid, cid1);
                Assert.AreEqual(cid, wantTask.Result.Id);
                Assert.AreEqual(data.Length, wantTask.Result.Size);
                Assert.AreEqual(data, wantTask.Result.DataBytes);
            }
            finally
            {
                await _dfs.StopAsync();
            }
        }
        public async Task Can_Process_DeltaHeightRequest_Correctly()
        {
            var deltaHeightRequestMessage = new LatestDeltaHashRequest();

            var fakeContext  = Substitute.For <IChannelHandlerContext>();
            var channeledAny = new ObserverDto(fakeContext,
                                               deltaHeightRequestMessage.ToProtocolMessage(PeerIdHelper.GetPeerId(),
                                                                                           CorrelationId.GenerateCorrelationId()));
            var observableStream = new[] { channeledAny }.ToObservable(_testScheduler);

            _deltaHeightRequestObserver.StartObserving(observableStream);

            _testScheduler.Start();

            var hash = MultiHash.ComputeHash(new byte[32]);
            var cid = new Cid {
                Hash = hash
            };

            await fakeContext.Channel.ReceivedWithAnyArgs(1)
            .WriteAndFlushAsync(new LatestDeltaHashResponse
            {
                DeltaIndex = new DeltaIndex {
                    Cid = cid.ToArray().ToByteString(), Height = 100
                }
            }.ToProtocolMessage(PeerIdHelper.GetPeerId(), CorrelationId.GenerateCorrelationId()))
            .ConfigureAwait(false);

            _subbedLogger.ReceivedWithAnyArgs(1);
        }
Пример #3
0
        /// <summary>
        ///   Create a key ID for the key.
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        /// <remarks>
        ///   The key id is the SHA-256 multihash of its public key. The public key is
        ///   a protobuf encoding containing a type and
        ///   the DER encoding of the PKCS SubjectPublicKeyInfo.
        /// </remarks>
        MultiHash CreateKeyId(AsymmetricKeyParameter key)
        {
            var spki = SubjectPublicKeyInfoFactory
                       .CreateSubjectPublicKeyInfo(key)
                       .GetDerEncoded();

            // Add protobuf cruft.
            var publicKey = new Proto.PublicKey
            {
                Data = spki
            };

            if (key is RsaKeyParameters)
            {
                publicKey.Type = Proto.KeyType.RSA;
            }
            else if (key is ECPublicKeyParameters)
            {
                publicKey.Type = Proto.KeyType.Secp256k1;
            }
            else
            {
                throw new NotSupportedException($"The key type {key.GetType().Name} is not supported.");
            }

            using (var ms = new MemoryStream())
            {
                ProtoBuf.Serializer.Serialize(ms, publicKey);
                ms.Position = 0;
                return(MultiHash.ComputeHash(ms, "sha2-256"));
            }
        }
Пример #4
0
        /// <summary>
        ///   Read the identify message and update the peer information.
        /// </summary>
        /// <param name="remote"></param>
        /// <param name="stream"></param>
        /// <param name="cancel"></param>
        /// <returns></returns>
        public async Task UpdateRemotePeerAsync(Peer remote, Stream stream, CancellationToken cancel)
        {
            var info = await ProtoBufHelper.ReadMessageAsync <Identify>(stream, cancel).ConfigureAwait(false);

            remote.AgentVersion    = info.AgentVersion;
            remote.ProtocolVersion = info.ProtocolVersion;
            if (info.PublicKey == null || info.PublicKey.Length == 0)
            {
                throw new InvalidDataException("Public key is missing.");
            }
            remote.PublicKey = Convert.ToBase64String(info.PublicKey);
            if (remote.Id == null)
            {
                remote.Id = MultiHash.ComputeHash(info.PublicKey);
            }

            if (info.ListenAddresses != null)
            {
                remote.Addresses = info.ListenAddresses
                                   .Select(b => MultiAddress.TryCreate(b))
                                   .Where(a => a != null)
                                   .Select(a => a.WithPeerId(remote.Id))
                                   .ToList();
            }
            if (remote.Addresses.Count() == 0)
            {
                log.Warn($"No listen address for {remote}");
            }

            if (!remote.IsValid())
            {
                throw new InvalidDataException($"Invalid peer {remote}.");
            }
        }
Пример #5
0
        /// <summary>
        ///   Gets the identity information of the remote peer.
        /// </summary>
        /// <param name="connection">
        ///   The currenty connection to the remote peer.
        /// </param>
        /// <param name="cancel"></param>
        /// <returns></returns>
        public async Task <Peer> GetRemotePeer(PeerConnection connection, CancellationToken cancel)
        {
            var muxer = await connection.MuxerEstablished.Task;

            log.Debug("Get remote identity");
            Peer remote = connection.RemotePeer;

            using (var stream = await muxer.CreateStreamAsync("id", cancel))
            {
                await connection.EstablishProtocolAsync("/multistream/", stream, cancel);

                await connection.EstablishProtocolAsync("/ipfs/id/", stream, cancel);

                var info = await ProtoBufHelper.ReadMessageAsync <Identify>(stream, cancel);

                if (remote == null)
                {
                    remote = new Peer();
                    connection.RemotePeer = remote;
                }

                remote.AgentVersion    = info.AgentVersion;
                remote.ProtocolVersion = info.ProtocolVersion;
                if (info.PublicKey == null || info.PublicKey.Length == 0)
                {
                    throw new InvalidDataException("Public key is missing.");
                }
                remote.PublicKey = Convert.ToBase64String(info.PublicKey);
                if (remote.Id == null)
                {
                    remote.Id = MultiHash.ComputeHash(info.PublicKey);
                }

                if (info.ListenAddresses != null)
                {
                    remote.Addresses = info.ListenAddresses
                                       .Select(b =>
                    {
                        try
                        {
                            return(new MultiAddress(b));
                        }
                        catch
                        {
                            return(null);
                        }
                    })
                                       .Where(a => a != null)
                                       .ToList();
                }
            }

            // TODO: Verify the Peer ID

            connection.IdentityEstablished.TrySetResult(remote);

            log.Debug($"Peer id '{remote}' of {connection.RemoteAddress}");
            return(remote);
        }
Пример #6
0
        //Give the same TransactionId everytime.
        public MultiHash GetId(string algorithmName)
        {
            var publicEntryClone = new PublicEntry(this);

            publicEntryClone.Amount   = ByteString.CopyFrom(TrimEnd(publicEntryClone.Amount.ToByteArray()));
            publicEntryClone.GasPrice = ByteString.CopyFrom(TrimEnd(publicEntryClone.GasPrice.ToByteArray()));
            return(MultiHash.ComputeHash(publicEntryClone.ToByteArray(), algorithmName));
        }
Пример #7
0
        public void Compute_Hash_Array()
        {
            var hello = Encoding.UTF8.GetBytes("Hello, world.");
            var mh    = MultiHash.ComputeHash(hello);

            Assert.Equal(MultiHash.DefaultAlgorithmName, mh.Algorithm.Name);
            Assert.NotNull(mh.Digest);
        }
Пример #8
0
        public void Compute_Hash_Stream()
        {
            var hello = new MemoryStream(Encoding.UTF8.GetBytes("Hello, world."));

            hello.Position = 0;
            var mh = MultiHash.ComputeHash(hello);

            Assert.Equal(MultiHash.DefaultAlgorithmName, mh.Algorithm.Name);
            Assert.NotNull(mh.Digest);
        }
Пример #9
0
 private void ComputeHash()
 {
     using (var ms = new MemoryStream())
     {
         Write(ms);
         _size       = ms.Position;
         ms.Position = 0;
         _id         = MultiHash.ComputeHash(ms, _hashAlgorithm);
     }
 }
Пример #10
0
        /// <summary>
        ///   Process a find node request.
        /// </summary>
        public DhtMessage ProcessFindNode(DhtMessage request, DhtMessage response)
        {
            // Some random walkers generate a random Key that is not hashed.
            MultiHash peerId;

            try
            {
                peerId = new MultiHash(request.Key);
            }
            catch (Exception)
            {
                log.Error($"Bad FindNode request key {request.Key.ToHexString()}");
                peerId = MultiHash.ComputeHash(request.Key);
            }

            // Do we know the peer?.
            Peer found = null;

            if (Swarm.LocalPeer.Id == peerId)
            {
                found = Swarm.LocalPeer;
            }
            else
            {
                found = Swarm.KnownPeers.FirstOrDefault(p => p.Id == peerId);
            }

            // Find the closer peers.
            var closerPeers = new List <Peer>();

            if (found != null)
            {
                closerPeers.Add(found);
            }
            else
            {
                closerPeers.AddRange(RoutingTable.NearestPeers(peerId).Take(CloserPeerCount));
            }

            // Build the response.
            response.CloserPeers = closerPeers
                                   .Select(peer => new DhtPeerMessage
            {
                Id        = peer.Id.ToArray(),
                Addresses = peer.Addresses.Select(a => a.WithoutPeerId().ToArray()).ToArray()
            })
                                   .ToArray();

            if (log.IsDebugEnabled)
            {
                log.Debug($"returning {response.CloserPeers.Length} closer peers");
            }
            return(response);
        }
Пример #11
0
        public async Task Remove_Inline_CID()
        {
            var cid = new Cid
            {
                ContentType = "raw",
                Hash        = MultiHash.ComputeHash(blob, "identity")
            };
            var removedCid = await ipfs.Block.RemoveAsync(cid);

            Assert.AreEqual(cid.Encode(), removedCid.Encode());
        }
Пример #12
0
        public void MultiHash_is_Cid_V1()
        {
            var hello = Encoding.UTF8.GetBytes("Hello, world.");
            var mh    = MultiHash.ComputeHash(hello, "sha2-512");
            Cid cid   = mh;

            Assert.AreEqual(1, cid.Version);
            Assert.AreEqual("dag-pb", cid.ContentType);
            Assert.AreEqual("base32", cid.Encoding);
            Assert.AreSame(mh, cid.Hash);
        }
Пример #13
0
        public Block GetGenesisBlock()
        {
            var block = new Block();

            block.Head                  = 0;
            block.Header.BlockTime      = new DateTimeOffset(2017, 4, 1, 0, 0, 0, TimeSpan.Zero);
            block.Header.HashPrevBlock  = MultiHash.ComputeHash(Enumerable.Range(0, 256).Select(i => (byte)0).ToArray());
            block.Header.HashMerkleRoot = Enumerable.Range(0, 256).Select(i => (byte)0).ToArray();
            block.Data                  = null;

            return(block);
        }
Пример #14
0
        public async Task Can_Receive_Query_Response_On_Observer()
        {
            var recipientPeerId  = PeerIdHelper.GetPeerId();
            var tipQueryResponse = new PeerQueryTipResponse(PeerIdHelper.GetPeerId(),
                                                            MultiHash.ComputeHash(ByteUtil.GenerateRandomByteArray(32))
                                                            );

            _peerQueryTipRequest.QueryTipResponseMessageStreamer.OnNext(tipQueryResponse);
            var response = await _peerQueryTipRequest.QueryPeerTipAsync(recipientPeerId).ConfigureAwait(false);

            response.Should().BeTrue();
        }
Пример #15
0
        public void Example()
        {
            var hello = Encoding.UTF8.GetBytes("Hello world");
            var mh    = MultiHash.ComputeHash(hello);

            Console.WriteLine($"| hash code | 0x{mh.Algorithm.Code.ToString("x")} |");
            Console.WriteLine($"| digest length | 0x{mh.Digest.Length.ToString("x")} |");
            Console.WriteLine($"| digest value | {mh.Digest.ToHexString()} |");
            Console.WriteLine($"| binary | {mh.ToArray().ToHexString()} |");
            Console.WriteLine($"| base 58 | {mh.ToBase58()} |");
            Console.WriteLine($"| base 32 | {mh.ToBase32()} |");
        }
Пример #16
0
        public async Task Stat_Inline_CID()
        {
            var cts = new CancellationTokenSource(300);
            var cid = new Cid
            {
                ContentType = "raw",
                Hash        = MultiHash.ComputeHash(blob, "identity")
            };
            var info = await ipfs.Block.StatAsync(cid, cts.Token);

            Assert.AreEqual(cid.Encode(), (string)info.Id);
            Assert.AreEqual(5, info.Size);
        }
Пример #17
0
 public void CheckMultiHash()
 {
     foreach (var v in TestVectors)
     {
         if (v.Ignore)
         {
             continue;
         }
         var bytes = Encoding.UTF8.GetBytes(v.Input);
         var mh    = MultiHash.ComputeHash(bytes, v.Algorithm);
         Assert.Equal(v.Output, mh.ToArray().ToHexString());
     }
 }
Пример #18
0
        public async Task OnConnect_Sends_WantList()
        {
            _dfsService.Options.Discovery.DisableMdns    = true;
            _dfsService.Options.Discovery.BootstrapPeers = new MultiAddress[0];
            await _dfsService.StartAsync();

            _dfsServiceOther.Options.Discovery.DisableMdns    = true;
            _dfsServiceOther.Options.Discovery.BootstrapPeers = new MultiAddress[0];
            await _dfsServiceOther.StartAsync();

            try
            {
                var local  = _dfsService.LocalPeer;
                var remote = _dfsServiceOther.LocalPeer;
                TestContext.WriteLine($"this at {local.Addresses.First()}");
                TestContext.WriteLine($"other at {remote.Addresses.First()}");

                var data = Guid.NewGuid().ToByteArray();
                var cid  = new Cid
                {
                    Hash = MultiHash.ComputeHash(data)
                };

                var _ = _dfsService.BlockApi.GetAsync(cid);
                await _dfsService.SwarmApi.ConnectAsync(remote.Addresses.First());

                var endTime = DateTime.Now.AddSeconds(10);
                while (DateTime.Now < endTime)
                {
                    var wants = await _dfsServiceOther.BitSwapApi.WantsAsync(local.Id);

                    if (wants.Contains(cid))
                    {
                        return;
                    }

                    await Task.Delay(200);
                }

                throw new Exception("want list not sent");
            }
            finally
            {
                await _dfsServiceOther.StopAsync();

                await _dfsService.StopAsync();

                _dfsService.Options.Discovery      = new DiscoveryOptions();
                _dfsServiceOther.Options.Discovery = new DiscoveryOptions();
            }
        }
Пример #19
0
        public async Task <Cid> PutAsync(Stream data, string contentType = "dag-pb", string multiHash = "sha2-256", CancellationToken cancel = default(CancellationToken))
        {
            var cid = new Cid
            {
                ContentType = contentType,
                Hash        = MultiHash.ComputeHash(data, multiHash),
                Version     = (contentType == "dag-pb" && multiHash == "sha2-256") ? 0 : 1
            };

            // Store the key in the repository.
            using (var repo = await ipfs.Repository(cancel))
            {
                var block = await repo.BlockInfos
                            .Where(b => b.Cid == cid.Encode())
                            .FirstOrDefaultAsync(cancel);

                if (block != null)
                {
                    log.DebugFormat("Block '{0}' already present", cid);
                    return(cid);
                }

                // TODO: Ineffecient in memory usage.  Might be better to do all
                // the work in the byte[] method.
                var bytes = new byte[data.Length];
                data.Position = 0;
                data.Read(bytes, 0, (int)data.Length);
                var blockInfo = new Repository.BlockInfo
                {
                    Cid      = cid,
                    Pinned   = false,
                    DataSize = data.Length
                };
                var blockValue = new Repository.BlockValue
                {
                    Cid  = cid,
                    Data = bytes
                };
                await repo.AddAsync(blockInfo, cancel);

                await repo.AddAsync(blockValue, cancel);

                await repo.SaveChangesAsync(cancel);

                log.DebugFormat("Added block '{0}'", cid);
            }

            // TODO: Send to bitswap
            return(cid);
        }
Пример #20
0
        public async Task Get_Inline_CID()
        {
            var cts = new CancellationTokenSource(300);
            var cid = new Cid
            {
                ContentType = "raw",
                Hash        = MultiHash.ComputeHash(blob, "identity")
            };
            var block = await ipfs.Block.GetAsync(cid, cts.Token);

            Assert.AreEqual(cid.Encode(), block.Id.Encode());
            Assert.AreEqual(blob.Length, block.Size);
            CollectionAssert.AreEqual(blob, block.DataBytes);
        }
Пример #21
0
        public void Compute_Not_Implemented_Hash_Array()
        {
            var alg = HashingAlgorithm.Register("not-implemented", 0x0F, 32);

            try
            {
                var hello = Encoding.UTF8.GetBytes("Hello, world.");
                Assert.Throws <NotImplementedException>(() => MultiHash.ComputeHash(hello, "not-implemented"));
            }
            finally
            {
                HashingAlgorithm.Deregister(alg);
            }
        }
Пример #22
0
        public void Matches_Stream()
        {
            var hello  = new MemoryStream(Encoding.UTF8.GetBytes("Hello, world."));
            var hello1 = new MemoryStream(Encoding.UTF8.GetBytes("Hello, world"));

            hello.Position = 0;
            var mh = MultiHash.ComputeHash(hello);

            hello.Position = 0;
            Assert.True(mh.Matches(hello));

            hello1.Position = 0;
            Assert.False(mh.Matches(hello1));
        }
Пример #23
0
        public void Encode_Upgrade_to_V1_Hash()
        {
            var hello = Encoding.UTF8.GetBytes("Hello, world.");
            var mh    = MultiHash.ComputeHash(hello, "sha2-512");
            var cid   = new Cid
            {
                Hash = mh
            };

            Assert.AreEqual(1, cid.Version);
            Assert.AreEqual("base32", cid.Encoding);
            Assert.AreEqual(
                "bafybgqfnbq34ghljwmk7hka7cpem3zybbffnsfzfxinq3qyztsuxcntbxaua23xx42hrgptcchrolkndcucelv3pc4eoarjbwdxagtylboxsm",
                cid.Encode());
        }
Пример #24
0
        public async Task OnConnect_Sends_WantList()
        {
            ipfs.Options.Discovery.DisableMdns    = true;
            ipfs.Options.Discovery.BootstrapPeers = new MultiAddress[0];
            await ipfs.StartAsync();

            ipfsOther.Options.Discovery.DisableMdns    = true;
            ipfsOther.Options.Discovery.BootstrapPeers = new MultiAddress[0];
            await ipfsOther.StartAsync();

            try
            {
                var local  = await ipfs.LocalPeer;
                var remote = await ipfsOther.LocalPeer;
                Console.WriteLine($"this at {local.Addresses.First()}");
                Console.WriteLine($"othr at {remote.Addresses.First()}");

                var data = Guid.NewGuid().ToByteArray();
                var cid  = new Cid {
                    Hash = MultiHash.ComputeHash(data)
                };
                var _ = ipfs.Block.GetAsync(cid);
                await ipfs.Swarm.ConnectAsync(remote.Addresses.First());

                var endTime = DateTime.Now.AddSeconds(10);
                while (DateTime.Now < endTime)
                {
                    var wants = await ipfsOther.Bitswap.WantsAsync(local.Id);

                    if (wants.Contains(cid))
                    {
                        return;
                    }
                    await Task.Delay(200);
                }

                Assert.Fail("want list not sent");
            }
            finally
            {
                await ipfsOther.StopAsync();

                await ipfs.StopAsync();

                ipfs.Options.Discovery      = new DiscoveryOptions();
                ipfsOther.Options.Discovery = new DiscoveryOptions();
            }
        }
Пример #25
0
        public async Task Put_Informs_Bitswap()
        {
            var data = Guid.NewGuid().ToByteArray();
            var cid  = new Cid {
                Hash = MultiHash.ComputeHash(data)
            };
            var wantTask = ipfs.Bitswap.GetAsync(cid);

            var cid1 = await ipfs.Block.PutAsync(data);

            Assert.AreEqual(cid, cid1);
            Assert.IsTrue(wantTask.IsCompleted);
            Assert.AreEqual(cid, wantTask.Result.Id);
            Assert.AreEqual(data.Length, wantTask.Result.Size);
            CollectionAssert.AreEqual(data, wantTask.Result.DataBytes);
        }
Пример #26
0
        void RunQuery()
        {
            log.Debug("Running a query");

            // Get a random peer id.
            byte[] x = new byte[32];
            rng.NextBytes(x);
            var id = MultiHash.ComputeHash(x);

            // Run the query for a while.
            using (var timeout = new CancellationTokenSource(QueryTime))
                using (var cts = CancellationTokenSource.CreateLinkedTokenSource(timeout.Token, cancel.Token))
                {
                    var _ = Dht.FindPeerAsync(id, cts.Token).Result;
                }
        }
Пример #27
0
        /// <param name="deltaHeightRequest"></param>
        /// <param name="channelHandlerContext"></param>
        /// <param name="senderPeerId"></param>
        /// <param name="correlationId"></param>
        /// <returns></returns>
        protected override LatestDeltaHashResponse HandleRequest(LatestDeltaHashRequest deltaHeightRequest,
                                                                 IChannelHandlerContext channelHandlerContext,
                                                                 PeerId senderPeerId,
                                                                 ICorrelationId correlationId)
        {
            Guard.Argument(deltaHeightRequest, nameof(deltaHeightRequest)).NotNull();
            Guard.Argument(channelHandlerContext, nameof(channelHandlerContext)).NotNull();
            Guard.Argument(senderPeerId, nameof(senderPeerId)).NotNull();

            Logger.Debug("PeerId: {0} wants to know your current chain height", senderPeerId);

            return(new LatestDeltaHashResponse
            {
                DeltaHash = MultiHash.ComputeHash(new byte[32]).Digest.ToByteString()
            });
        }
Пример #28
0
 public void CheckMultiHash_Stream()
 {
     foreach (var v in TestVectors)
     {
         if (v.Ignore)
         {
             continue;
         }
         var bytes = Encoding.UTF8.GetBytes(v.Input);
         using (var ms = new MemoryStream(bytes, false))
         {
             var mh = MultiHash.ComputeHash(ms, v.Algorithm);
             Assert.AreEqual(v.Output, mh.ToArray().ToHexString(), v.Algorithm);
         }
     }
 }
Пример #29
0
            public Task <Cid> PutAsync(byte[] data,
                                       string contentType       = Cid.DefaultContentType,
                                       string multiHash         = MultiHash.DefaultAlgorithmName,
                                       string encoding          = MultiBase.DefaultAlgorithmName,
                                       bool pin                 = false,
                                       CancellationToken cancel = default)
            {
                var cid = new Cid
                {
                    ContentType = contentType,
                    Encoding    = encoding,
                    Hash        = MultiHash.ComputeHash(data, multiHash),
                    Version     = (contentType == "dag-pb" && multiHash == "sha2-256") ? 0 : 1
                };

                return(Task.FromResult(cid));
            }
Пример #30
0
        async Task RunQueryAsync(CancellationToken cancel = default(CancellationToken))
        {
            // Tests may not set a DHT.
            if (Dht == null)
            {
                return;
            }
            log.Debug("Running a query");

            // Get a random peer id.
            var x   = new byte[32];
            var rng = new Random();

            rng.NextBytes(x);
            var id = MultiHash.ComputeHash(x);

            await Dht.FindPeerAsync(id, cancel).ConfigureAwait(false);
        }