示例#1
0
        protected LibplanetNodeService <T> CreateLibplanetNodeService <T>(
            Block <T> genesisBlock,
            AppProtocolVersion appProtocolVersion,
            PublicKey appProtocolVersionSigner,
            Progress <PreloadState> preloadProgress = null,
            IEnumerable <Peer> peers = null)
            where T : IAction, new()
        {
            var properties = new LibplanetNodeServiceProperties <T>
            {
                Host = System.Net.IPAddress.Loopback.ToString(),
                AppProtocolVersion   = appProtocolVersion,
                GenesisBlock         = genesisBlock,
                StoreStatesCacheSize = 2,
                PrivateKey           = new PrivateKey(),
                Port = null,
                MinimumDifficulty = 1024,
                NoMiner           = true,
                Render            = false,
                Peers             = peers ?? ImmutableHashSet <Peer> .Empty,
                TrustedAppProtocolVersionSigners = ImmutableHashSet <PublicKey> .Empty.Add(appProtocolVersionSigner),
            };

            return(new LibplanetNodeService <T>(
                       properties,
                       new BlockPolicy <T>(),
                       async(chain, swarm, privateKey, cancellationToken) => { },
                       preloadProgress));
        }
示例#2
0
        public void Decode()
        {
            BlockHash[] blockHashes = GenerateRandomBlockHashes(100L).ToArray();
            var         msg         = new BlockHashes(123, blockHashes);

            Assert.Equal(123, msg.StartIndex);
            Assert.Equal(blockHashes, msg.Hashes);
            var privKey               = new PrivateKey();
            AppProtocolVersion ver    = AppProtocolVersion.Sign(privKey, 3);
            Peer         peer         = new BoundPeer(privKey.PublicKey, new DnsEndPoint("0.0.0.0", 1234));
            var          messageCodec = new NetMQMessageCodec();
            NetMQMessage encoded      = messageCodec.Encode(
                msg,
                privKey,
                peer,
                DateTimeOffset.UtcNow,
                ver);
            BlockHashes restored = (BlockHashes)messageCodec.Decode(
                encoded,
                true,
                (b, p, a) => { },
                null);

            Assert.Equal(msg.StartIndex, restored.StartIndex);
            Assert.Equal(msg.Hashes, restored.Hashes);
        }
示例#3
0
        public void DifferentAppProtocolVersionStructure()
        {
            var privateKey = new PrivateKey();
            var peer       = new Peer(privateKey.PublicKey);
            var apv        = new AppProtocolVersion(
                1,
                new Bencodex.Types.Integer(0),
                ImmutableArray <byte> .Empty,
                default(Address));
            var          message      = new Ping();
            var          codec        = new NetMQMessageCodec();
            NetMQMessage netMQMessage = codec.Encode(
                message,
                privateKey,
                peer,
                DateTimeOffset.UtcNow,
                apv);

            Assert.Throws <DifferentAppProtocolVersionException>(() =>
                                                                 codec.Decode(
                                                                     netMQMessage,
                                                                     true,
                                                                     (i, p, v) => throw new DifferentAppProtocolVersionException(
                                                                         string.Empty,
                                                                         i,
                                                                         v,
                                                                         v),
                                                                     null));
        }
        /// <summary>
        /// Queries <see cref="AppProtocolVersion"/> of given <see cref="BoundPeer"/>.
        /// </summary>
        /// <param name="peer">The <see cref="BoundPeer"/> to query
        /// <see cref="AppProtocolVersion"/>.</param>
        /// <param name="timeout">Timeout value for request.</param>
        /// <returns><see cref="AppProtocolVersion"/> of given peer. </returns>
        public static AppProtocolVersion QueryAppProtocolVersion(
            this BoundPeer peer,
            TimeSpan?timeout = null
            )
        {
            using var dealerSocket = new DealerSocket(ToNetMQAddress(peer));
            var          key  = new PrivateKey();
            var          ping = new Ping();
            var          netMQMessageCodec = new NetMQMessageCodec();
            NetMQMessage request           = netMQMessageCodec.Encode(
                ping,
                key,
                new Peer(key.PublicKey),
                DateTimeOffset.UtcNow,
                default
                );

            TimeSpan timeoutNotNull = timeout ?? TimeSpan.FromSeconds(5);

            if (dealerSocket.TrySendMultipartMessage(timeoutNotNull, request))
            {
                var response = new NetMQMessage();
                if (dealerSocket.TryReceiveMultipartMessage(timeoutNotNull, ref response))
                {
                    return(AppProtocolVersion.FromToken(response.First.ConvertToString()));
                }
            }

            throw new TimeoutException(
                      $"Peer[{peer}] didn't respond within the specified time[{timeout}]."
                      );
        }
示例#5
0
        public void UseInvalidSignature()
        {
            // Victim
            var privateKey = new PrivateKey();
            var peer       = new Peer(privateKey.PublicKey, new IPAddress(1024L));
            var timestamp  = DateTimeOffset.UtcNow;
            var apv        = new AppProtocolVersion(
                1,
                new Bencodex.Types.Integer(0),
                ImmutableArray <byte> .Empty,
                default(Address));
            var ping         = new Ping();
            var codec        = new NetMQMessageCodec(appProtocolVersion: apv);
            var netMqMessage = codec.Encode(ping, privateKey, peer, timestamp).ToArray();

            // Attacker
            var fakePeer    = new Peer(privateKey.PublicKey, new IPAddress(2048L));
            var fakeMessage = codec.Encode(ping, privateKey, fakePeer, timestamp).ToArray();

            var frames = new NetMQMessage();

            frames.Push(netMqMessage[4]);
            frames.Push(netMqMessage[3]);
            frames.Push(fakeMessage[2]);
            frames.Push(netMqMessage[1]);
            frames.Push(netMqMessage[0]);

            Assert.Throws <InvalidMessageSignatureException>(() =>
                                                             codec.Decode(frames, true));
        }
示例#6
0
        public static IEnumerable <object[]> GetPeers()
        {
            var signer              = new PrivateKey();
            AppProtocolVersion ver  = AppProtocolVersion.Sign(signer, 1);
            AppProtocolVersion ver2 = AppProtocolVersion.Sign(
                signer: signer,
                version: 2,
                extra: Bencodex.Types.Dictionary.Empty.Add("foo", 123).Add("bar", 456)
                );

            yield return(new object[]
            {
                new Peer(
                    new PublicKey(new byte[]
                {
                    0x04, 0xb5, 0xa2, 0x4a, 0xa2, 0x11, 0x27, 0x20, 0x42, 0x3b,
                    0xad, 0x39, 0xa0, 0x20, 0x51, 0x82, 0x37, 0x9d, 0x6f, 0x2b,
                    0x33, 0xe3, 0x48, 0x7c, 0x9a, 0xb6, 0xcc, 0x8f, 0xc4, 0x96,
                    0xf8, 0xa5, 0x48, 0x34, 0x40, 0xef, 0xbb, 0xef, 0x06, 0x57,
                    0xac, 0x2e, 0xf6, 0xc6, 0xee, 0x05, 0xdb, 0x06, 0xa9, 0x45,
                    0x32, 0xfd, 0xa7, 0xdd, 0xc4, 0x4a, 0x16, 0x95, 0xe5, 0xce,
                    0x1a, 0x3d, 0x3c, 0x76, 0xdb,
                })),
            });
        }
示例#7
0
        private ITransport CreateTransport(
            PrivateKey privateKey = null,
            AppProtocolVersion appProtocolVersion = default,
            IImmutableSet <PublicKey> trustedAppProtocolVersionSigners = null,
            string host    = null,
            int?listenPort = null,
            IEnumerable <IceServer> iceServers = null,
            DifferentAppProtocolVersionEncountered differentAppProtocolVersionEncountered = null,
            TimeSpan?messageTimestampBuffer = null
            )
        {
            if (TransportConstructor is null)
            {
                throw new XunitException("Transport constructor is not defined.");
            }

            privateKey = privateKey ?? new PrivateKey();
            host       = host ?? IPAddress.Loopback.ToString();

            return(TransportConstructor(
                       privateKey,
                       appProtocolVersion,
                       trustedAppProtocolVersionSigners ?? ImmutableHashSet <PublicKey> .Empty,
                       host,
                       listenPort,
                       iceServers ?? Enumerable.Empty <IceServer>(),
                       differentAppProtocolVersionEncountered,
                       messageTimestampBuffer));
        }
示例#8
0
        public void DifferentAppProtocolVersionStructure()
        {
            var privateKey = new PrivateKey();
            var peer       = new Peer(privateKey.PublicKey);
            var apv1       = new AppProtocolVersion(
                1,
                new Bencodex.Types.Integer(0),
                ImmutableArray <byte> .Empty,
                default(Address));
            var apv2 = new AppProtocolVersion(
                2,
                new Bencodex.Types.Integer(0),
                ImmutableArray <byte> .Empty,
                default(Address));
            var          message      = new Ping();
            var          codec1       = new NetMQMessageCodec(appProtocolVersion: apv1);
            var          codec2       = new NetMQMessageCodec(appProtocolVersion: apv2);
            NetMQMessage netMQMessage = codec1.Encode(
                message,
                privateKey,
                peer,
                DateTimeOffset.UtcNow);

            Assert.Throws <DifferentAppProtocolVersionException>(() =>
                                                                 codec2.Decode(netMQMessage, true));
        }
示例#9
0
        public async Task ReadMessageCancelAsync()
        {
            var cts = new CancellationTokenSource();

            cts.CancelAfter(TimeSpan.FromSeconds(3));
            var listener = new TcpListener(IPAddress.Any, 0);

            listener.Start();
            var client = new TcpClient();
            await client.ConnectAsync("127.0.0.1", ((IPEndPoint)listener.LocalEndpoint).Port);

            TcpClient listenerSocket = await listener.AcceptTcpClientAsync();

            TcpTransport transport = CreateTcpTransport(
                appProtocolVersion: AppProtocolVersion.Sign(new PrivateKey(), 1));

            try
            {
                await Assert.ThrowsAsync <TaskCanceledException>(async() =>
                                                                 await transport.ReadMessageAsync(listenerSocket, cts.Token));
            }
            finally
            {
                listenerSocket.Dispose();
                client.Dispose();
            }
        }
示例#10
0
        public KademliaProtocol(
            ITransport transport,
            Address address,
            AppProtocolVersion appProtocolVersion,
            IImmutableSet <PublicKey> trustedAppProtocolVersionSigners,
            DifferentAppProtocolVersionEncountered differentAppProtocolVersionEncountered,
            ILogger logger,
            int?tableSize,
            int?bucketSize,
            TimeSpan?requestTimeout = null)
        {
            _transport          = transport;
            _appProtocolVersion = appProtocolVersion;
            _trustedAppProtocolVersionSigners       = trustedAppProtocolVersionSigners;
            _differentAppProtocolVersionEncountered = differentAppProtocolVersionEncountered;
            _logger = logger;

            _address        = address;
            _random         = new System.Random();
            _tableSize      = tableSize ?? Kademlia.TableSize;
            _bucketSize     = bucketSize ?? Kademlia.BucketSize;
            _routing        = new RoutingTable(_address, _tableSize, _bucketSize, _random, _logger);
            _requestTimeout =
                requestTimeout ??
                TimeSpan.FromMilliseconds(Kademlia.IdleRequestTimeout);
        }
示例#11
0
        private TcpTransport CreateTcpTransport(
            PrivateKey privateKey = null,
            AppProtocolVersion appProtocolVersion = default,
            IImmutableSet <PublicKey> trustedAppProtocolVersionSigners = null,
            string host    = null,
            int?listenPort = null,
            IEnumerable <IceServer> iceServers = null,
            DifferentAppProtocolVersionEncountered differentAppProtocolVersionEncountered = null,
            TimeSpan?messageTimestampBuffer = null
            )
        {
            privateKey = privateKey ?? new PrivateKey();
            host       = host ?? IPAddress.Loopback.ToString();
            iceServers = iceServers ?? new IceServer[] { };

            return(new TcpTransport(
                       privateKey,
                       appProtocolVersion,
                       trustedAppProtocolVersionSigners,
                       host,
                       listenPort,
                       iceServers,
                       differentAppProtocolVersionEncountered,
                       messageTimestampBuffer));
        }
示例#12
0
        public void InvalidMessageTimestamp()
        {
            var privateKey   = new PrivateKey();
            var peer         = new Peer(privateKey.PublicKey);
            var futureOffset = DateTimeOffset.MaxValue;
            var pastOffset   = DateTimeOffset.MinValue;
            var apv          = new AppProtocolVersion(
                1,
                new Bencodex.Types.Integer(0),
                ImmutableArray <byte> .Empty,
                default(Address));
            var buffer  = TimeSpan.FromSeconds(1);
            var message = new Ping();
            var codec   = new NetMQMessageCodec(
                appProtocolVersion: apv,
                messageTimestampBuffer: buffer);
            NetMQMessage futureRaw =
                codec.Encode(message, privateKey, peer, futureOffset);

            // Messages from the future throws InvalidMessageTimestampException.
            Assert.Throws <InvalidMessageTimestampException>(() =>
                                                             codec.Decode(futureRaw, true));
            NetMQMessage pastRaw =
                codec.Encode(message, privateKey, peer, pastOffset);

            // Messages from the far past throws InvalidMessageTimestampException.
            Assert.Throws <InvalidMessageTimestampException>(() =>
                                                             codec.Decode(pastRaw, true));
        }
        public async Task NodeStatus()
        {
            var cts = new CancellationTokenSource();

            var apvPrivateKey = new PrivateKey();
            var apv           = AppProtocolVersion.Sign(apvPrivateKey, 0);
            var genesisBlock  = BlockChain <EmptyAction> .MakeGenesisBlock(
                HashAlgorithmType.Of <SHA256>()
                );

            // 에러로 인하여 NineChroniclesNodeService 를 사용할 수 없습니다. https://git.io/JfS0M
            // 따라서 LibplanetNodeService로 비슷한 환경을 맞춥니다.
            // 1. 노드를 생성합니다.
            var seedNode = CreateLibplanetNodeService <EmptyAction>(genesisBlock, apv, apvPrivateKey.PublicKey);

            await StartAsync(seedNode.Swarm, cts.Token);

            var service = CreateLibplanetNodeService <EmptyAction>(genesisBlock, apv, apvPrivateKey.PublicKey, peers: new [] { seedNode.Swarm.AsPeer });

            // 2. NineChroniclesNodeService.ConfigureStandaloneContext(standaloneContext)를 호출합니다.
            // BlockChain 객체 공유 및 PreloadEnded, BootstrapEnded 이벤트 훅의 처리를 합니다.
            // BlockChain 객체 공유는 액션 타입이 달라 생략합니다.
            _ = service.BootstrapEnded.WaitAsync()
                .ContinueWith(task => StandaloneContextFx.BootstrapEnded = true);
            _ = service.PreloadEnded.WaitAsync()
                .ContinueWith(task => StandaloneContextFx.PreloadEnded = true);

            var bootstrapEndedTask = service.BootstrapEnded.WaitAsync();
            var preloadEndedTask   = service.PreloadEnded.WaitAsync();

            async Task <Dictionary <string, bool> > QueryNodeStatus()
            {
                var result = await ExecuteQueryAsync("query { nodeStatus { bootstrapEnded preloadEnded } }");

                var data           = (Dictionary <string, object>)result.Data;
                var nodeStatusData = (Dictionary <string, object>)data["nodeStatus"];

                return(nodeStatusData.ToDictionary(pair => pair.Key, pair => (bool)pair.Value));
            }

            var nodeStatus = await QueryNodeStatus();

            Assert.False(nodeStatus["bootstrapEnded"]);
            Assert.False(nodeStatus["preloadEnded"]);

            _ = service.StartAsync(cts.Token);

            await bootstrapEndedTask;
            await preloadEndedTask;

            // ContinueWith으로 넘긴 태스크가 실행되기를 기다립니다.
            await Task.Delay(1000);

            nodeStatus = await QueryNodeStatus();

            Assert.True(nodeStatus["bootstrapEnded"]);
            Assert.True(nodeStatus["preloadEnded"]);

            await seedNode.StopAsync(cts.Token);
        }
示例#14
0
        /// <inheritdoc/>
        public NetMQMessage Encode(
            Message message,
            PrivateKey privateKey,
            Peer peer,
            DateTimeOffset timestamp,
            AppProtocolVersion version)
        {
            var netMqMessage = new NetMQMessage();

            // Write body (by concrete class)
            foreach (byte[] frame in message.DataFrames)
            {
                netMqMessage.Append(frame);
            }

            // Write headers. (inverse order, version-type-peer-timestamp)
            netMqMessage.Push(timestamp.Ticks);
            netMqMessage.Push(_codec.Encode(peer.ToBencodex()));
            netMqMessage.Push((int)message.Type);
            netMqMessage.Push(version.Token);

            // Make and insert signature
            byte[]            signature = privateKey.Sign(netMqMessage.ToByteArray());
            List <NetMQFrame> frames    = netMqMessage.ToList();

            frames.Insert((int)Message.MessageFrame.Sign, new NetMQFrame(signature));
            netMqMessage = new NetMQMessage(frames);

            if (message.Identity is { } to)
            {
                netMqMessage.Push(to);
            }

            return(netMqMessage);
        }
示例#15
0
        private ITransport CreateTransport(
            PrivateKey privateKey = null,
            int tableSize         = 160,
            int bucketSize        = 16,
            AppProtocolVersion appProtocolVersion = default,
            IImmutableSet <PublicKey> trustedAppProtocolVersionSigners = null,
            string host    = null,
            int?listenPort = null,
            IEnumerable <IceServer> iceServers = null,
            DifferentAppProtocolVersionEncountered differentAppProtocolVersionEncountered = null,
            int minimumBroadcastTarget = 10,
            TimeSpan?messageLifespan   = null
            )
        {
            if (TransportConstructor is null)
            {
                throw new XunitException("Transport constructor is not defined.");
            }

            privateKey = privateKey ?? new PrivateKey();
            host       = host ?? IPAddress.Loopback.ToString();
            var routingTable = new RoutingTable(privateKey.ToAddress(), tableSize, bucketSize);

            return(CreateTransport(
                       routingTable,
                       privateKey,
                       appProtocolVersion,
                       trustedAppProtocolVersionSigners ?? ImmutableHashSet <PublicKey> .Empty,
                       host,
                       listenPort,
                       iceServers ?? Enumerable.Empty <IceServer>(),
                       differentAppProtocolVersionEncountered,
                       minimumBroadcastTarget,
                       messageLifespan));
        }
示例#16
0
        public NetMQMessage ToNetMQMessage(PrivateKey key, Peer peer, AppProtocolVersion version)
        {
            if (peer is null)
            {
                throw new ArgumentNullException(nameof(peer));
            }

            var message = new NetMQMessage();

            // Write body (by concrete class)
            foreach (NetMQFrame frame in DataFrames)
            {
                message.Append(frame);
            }

            // Write headers. (inverse order)
            message.Push(key.Sign(message.ToByteArray()));
            message.Push(SerializePeer(peer));
            message.Push((byte)Type);
            message.Push(version.Token);

            if (Identity is byte[] to)
            {
                message.Push(to);
            }

            return(message);
        }
示例#17
0
        public void DifferentAppProtocolVersionWithDifferentStructure()
        {
            var validAppProtocolVersion = new AppProtocolVersion(
                1,
                new Bencodex.Types.Integer(0),
                ImmutableArray <byte> .Empty,
                default(Address));
            var invalidAppProtocolVersion = new AppProtocolVersion(
                2,
                new Bencodex.Types.Integer(0),
                ImmutableArray <byte> .Empty,
                default(Address));
            var netMQMessage = new NetMQMessage();

            netMQMessage.Push(validAppProtocolVersion.Token);

            Assert.Throws <DifferentAppProtocolVersionException>(() =>
                                                                 Message.Parse(
                                                                     netMQMessage,
                                                                     true,
                                                                     invalidAppProtocolVersion,
                                                                     ImmutableHashSet <PublicKey> .Empty,
                                                                     null,
                                                                     null));
        }
示例#18
0
        public void DifferentAppProtocolVersionWithSameStructure()
        {
            var privateKey = new PrivateKey();
            var peer       = new Peer(privateKey.PublicKey);
            var validAppProtocolVersion = new AppProtocolVersion(
                1,
                new Bencodex.Types.Integer(0),
                ImmutableArray <byte> .Empty,
                default(Address));
            var invalidAppProtocolVersion = new AppProtocolVersion(
                2,
                new Bencodex.Types.Integer(0),
                ImmutableArray <byte> .Empty,
                default(Address));
            var message      = new Ping();
            var netMQMessage = message.ToNetMQMessage(privateKey, peer, validAppProtocolVersion);

            Assert.Throws <DifferentAppProtocolVersionException>(() =>
                                                                 Message.Parse(
                                                                     netMQMessage,
                                                                     true,
                                                                     invalidAppProtocolVersion,
                                                                     ImmutableHashSet <PublicKey> .Empty,
                                                                     null));
        }
示例#19
0
        protected LibplanetNodeService <T> CreateLibplanetNodeService <T>(
            Block <T> genesisBlock,
            AppProtocolVersion appProtocolVersion,
            PublicKey appProtocolVersionSigner,
            Progress <PreloadState> preloadProgress = null,
            IEnumerable <Peer> peers = null)
            where T : IAction, new()
        {
            var properties = new LibplanetNodeServiceProperties <T>
            {
                Host = System.Net.IPAddress.Loopback.ToString(),
                AppProtocolVersion   = appProtocolVersion,
                GenesisBlock         = genesisBlock,
                StoreStatesCacheSize = 2,
                PrivateKey           = new PrivateKey(),
                StorePath            = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()),
                Port = null,
                MinimumDifficulty = 1024,
                NoMiner           = true,
                Render            = false,
                Peers             = peers ?? ImmutableHashSet <Peer> .Empty,
                TrustedAppProtocolVersionSigners = ImmutableHashSet <PublicKey> .Empty.Add(appProtocolVersionSigner),
            };

            return(new LibplanetNodeService <T>(
                       properties,
                       blockPolicy: new BlockPolicy <T>(),
                       renderers: new[] { new DummyRenderer <T>() },
                       minerLoopAction: (chain, swarm, privateKey, _) => Task.CompletedTask,
                       preloadProgress: preloadProgress,
                       exceptionHandlerAction: (code, msg) => throw new Exception($"{code}, {msg}"),
                       preloadStatusHandlerAction: isPreloadStart => { }
                       ));
        }
示例#20
0
 private NetMQTransport CreateNetMQTransport(
     RoutingTable table,
     PrivateKey privateKey,
     AppProtocolVersion appProtocolVersion,
     IImmutableSet <PublicKey> trustedAppProtocolVersionSigners,
     int workers,
     string host,
     int?listenPort,
     IEnumerable <IceServer> iceServers,
     DifferentAppProtocolVersionEncountered differentAppProtocolVersionEncountered,
     int minimumBroadcastTarget,
     TimeSpan?messageLifespan
     )
 {
     return(new NetMQTransport(
                table,
                privateKey,
                appProtocolVersion,
                trustedAppProtocolVersionSigners,
                workers,
                host,
                listenPort,
                iceServers,
                differentAppProtocolVersionEncountered,
                minimumBroadcastTarget,
                messageLifespan));
 }
示例#21
0
        private NetMQTransport CreateNetMQTransport(
            PrivateKey privateKey = null,
            int tableSize         = 160,
            int bucketSize        = 16,
            AppProtocolVersion appProtocolVersion = default,
            IImmutableSet <PublicKey> trustedAppProtocolVersionSigners = null,
            int workers    = 50,
            string host    = null,
            int?listenPort = null,
            IEnumerable <IceServer> iceServers = null,
            DifferentAppProtocolVersionEncountered differentAppProtocolVersionEncountered = null,
            int minimumBroadcastTarget = 10,
            TimeSpan?messageLifespan   = null
            )
        {
            privateKey = privateKey ?? new PrivateKey();
            host       = host ?? IPAddress.Loopback.ToString();
            var table = new RoutingTable(privateKey.ToAddress(), tableSize, bucketSize);

            return(new NetMQTransport(
                       table,
                       privateKey,
                       appProtocolVersion,
                       trustedAppProtocolVersionSigners,
                       workers,
                       host,
                       listenPort,
                       iceServers,
                       differentAppProtocolVersionEncountered,
                       minimumBroadcastTarget,
                       messageLifespan));
        }
示例#22
0
        public async Task HandleDifferentAppProtocolVersion()
        {
            var isCalled = false;

            var signer            = new PrivateKey();
            AppProtocolVersion v1 = AppProtocolVersion.Sign(signer, 1);
            AppProtocolVersion v2 = AppProtocolVersion.Sign(signer, 2);
            var a = CreateSwarm(
                appProtocolVersion: v1,
                differentAppProtocolVersionEncountered: (_, ver, __) =>
            {
                isCalled = true;
            }
                );
            var b = CreateSwarm(appProtocolVersion: v2);

            try
            {
                await StartAsync(b);

                await Assert.ThrowsAsync <PeerDiscoveryException>(() => BootstrapAsync(a, b.AsPeer));

                Assert.True(isCalled);
            }
            finally
            {
                await StopAsync(a);
                await StopAsync(b);

                a.Dispose();
                b.Dispose();
            }
        }
示例#23
0
        private static bool IsAppProtocolVersionValid(
            Peer remotePeer,
            AppProtocolVersion localVersion,
            AppProtocolVersion remoteVersion,
            IImmutableSet <PublicKey> trustedAppProtocolVersionSigners,
            DifferentAppProtocolVersionEncountered differentAppProtocolVersionEncountered)
        {
            if (remoteVersion.Equals(localVersion))
            {
                return(true);
            }

            if (!(trustedAppProtocolVersionSigners is null) &&
                !trustedAppProtocolVersionSigners.Any(remoteVersion.Verify))
            {
                return(false);
            }

            if (differentAppProtocolVersionEncountered is null)
            {
                return(false);
            }

            return(differentAppProtocolVersionEncountered(remotePeer, remoteVersion, localVersion));
        }
        GenerateLibplanetNodeServiceProperties(
            string appProtocolVersionToken = null,
            string genesisBlockPath        = null,
            string swarmHost                          = null,
            ushort?swarmPort                          = null,
            int minimumDifficulty                     = 5000000,
            string privateKeyString                   = null,
            string storeType                          = null,
            string storePath                          = null,
            int storeStateCacheSize                   = 100,
            string[] iceServerStrings                 = null,
            string[] peerStrings                      = null,
            bool noTrustedStateValidators             = false,
            string[] trustedAppProtocolVersionSigners = null,
            bool noMiner = false,
            bool render  = false)
        {
            var privateKey = string.IsNullOrEmpty(privateKeyString)
                ? new PrivateKey()
                : new PrivateKey(ByteUtil.ParseHex(privateKeyString));

            peerStrings ??= Array.Empty <string>();
            iceServerStrings ??= Array.Empty <string>();

            var iceServers = iceServerStrings.Select(LoadIceServer).ToImmutableArray();
            var peers      = peerStrings.Select(LoadPeer).ToImmutableArray();

            IImmutableSet <Address> trustedStateValidators;

            if (noTrustedStateValidators)
            {
                trustedStateValidators = ImmutableHashSet <Address> .Empty;
            }
            else
            {
                trustedStateValidators = peers.Select(p => p.Address).ToImmutableHashSet();
            }

            return(new LibplanetNodeServiceProperties <NineChroniclesActionType>
            {
                Host = swarmHost,
                Port = swarmPort,
                AppProtocolVersion = AppProtocolVersion.FromToken(appProtocolVersionToken),
                TrustedAppProtocolVersionSigners = trustedAppProtocolVersionSigners
                                                   ?.Select(s => new PublicKey(ByteUtil.ParseHex(s)))
                                                   ?.ToHashSet(),
                GenesisBlockPath = genesisBlockPath,
                NoMiner = noMiner,
                PrivateKey = privateKey,
                IceServers = iceServers,
                Peers = peers,
                TrustedStateValidators = trustedStateValidators,
                StoreType = storeType,
                StorePath = storePath,
                StoreStatesCacheSize = storeStateCacheSize,
                MinimumDifficulty = minimumDifficulty,
                Render = render
            });
        }
示例#25
0
        /// <summary>
        /// Performs request processing just prior to execution but after the IWebRequest has called.
        /// </summary>
        private HttpRequestMessage PreProcessRequest(ref string relativeUrl, ref HttpMethod method, IList <NameValuePair <string> > additionalHeaders)
        {
            //see if we've ever attempted a request - if not we're going to do some first time things.
            if (m_FirstRequest)
            {
                m_UseCompatibilityMethods = GetUseCompatiblilityMethodsOverride(m_HostName);
                m_UseHttpVersion10        = GetUseHttpVersion10Override(m_HostName);

                m_FirstRequest = false;
            }

            //get rid of any leading slashes
            relativeUrl = (relativeUrl.StartsWith("/") ? relativeUrl.Substring(1) : relativeUrl);

            var request = new HttpRequestMessage(method, relativeUrl);

            //put in any additional headers we got.  By doing them first, if they conflict with one of our headers
            //the conflict will be resolved in favor of the base implementation, forcing the dev to deal with their error first.
            if (additionalHeaders != null)
            {
                foreach (NameValuePair <string> additionalHeader in additionalHeaders)
                {
                    request.Headers.Add(additionalHeader.Name, additionalHeader.Value);
                }
            }

            //see if we need to override the method.  I'm just sick and tired of !@%@ IIS blocking PUT and DELETE.
            if (m_UseCompatibilityMethods)
            {
                if (method == HttpMethod.Put || method == HttpMethod.Delete)
                {
                    request.Headers.Add(HeaderRequestMethod, method.Method);

                    //and override the method back to post, which will work.
                    method         = HttpMethod.Post;
                    request.Method = method;
                }
            }

            request.Version = (m_UseHttpVersion10) ? new Version(1, 0) : new Version(1, 1);

            //add our request timestamp so everyone agrees.
            request.Headers.Add(HeaderRequestTimestamp, DateTimeOffset.UtcNow.ToString("o"));

            //and if we have a protocol version the caller is using specify that so the server knows.
            if (AppProtocolVersion != null)
            {
                request.Headers.Add(HeaderRequestAppProtocolVersion, AppProtocolVersion.ToString());
            }

            //Extension our authentication headers if there is an authentication object
            if (m_AuthenticationProvider != null)
            {
                m_AuthenticationProvider.PreProcessRequest(this, m_Connection, request, relativeUrl, m_RequestSupportsAuthentication);
            }

            return(request);
        }
示例#26
0
        public void DefaultConstructor()
        {
            AppProtocolVersion    defaultValue = default(AppProtocolVersion);
            ImmutableArray <byte> defaultSig   = defaultValue.Signature;

            Assert.False(defaultSig.IsDefault);
            Assert.True(defaultSig.IsEmpty);
            Assert.Equal("0/0000000000000000000000000000000000000000/", defaultValue.Token);
        }
示例#27
0
 /// <summary>
 /// Validates an <see cref="AppProtocolVersion"/> against <see cref="Apv"/>.
 /// Any <see cref="AppProtocolVersion"/> that is different from <see cref="Apv"/> is
 /// considered invalid and an <see cref="DifferentAppProtocolVersionException"/> will be
 /// thrown.
 /// </summary>
 /// <param name="peer">The <see cref="Peer"/> that has sent the <see cref="Message"/>
 /// with <paramref name="peerAppProtocolVersion"/>.</param>
 /// <param name="identity">The <see cref="Message.Identity"/> attached to the
 /// <see cref="Message"/> with <paramref name="peerAppProtocolVersion"/>.</param>
 /// <param name="peerAppProtocolVersion">The <see cref="AppProtocolVersion"/> to validate.
 /// </param>
 /// <exception cref="DifferentAppProtocolVersionException">Thrown when
 /// <paramref name="peerAppProtocolVersion"/> is different from <see cref="Apv"/>.
 /// </exception>
 /// <remarks>
 /// If <paramref name="peerAppProtocolVersion"/> is not valid but is signed by
 /// a trusted signer, then <see cref="DifferentApvEncountered"/> is called.
 /// </remarks>
 /// <seealso cref="Apv"/>
 /// <seealso cref="TrustedApvSigners"/>
 /// <seealso cref="DifferentApvEncountered"/>
 public void ValidateAppProtocolVersion(
     Peer peer, byte[] identity, AppProtocolVersion peerAppProtocolVersion) =>
 ValidateAppProtocolVersionTemplate(
     Apv,
     TrustedApvSigners,
     DifferentApvEncountered,
     peer,
     identity,
     peerAppProtocolVersion);
 public DifferentAppProtocolVersionEncounter(
     Peer peer,
     AppProtocolVersion peerVersion,
     AppProtocolVersion localVersion)
 {
     Peer         = peer;
     PeerVersion  = peerVersion;
     LocalVersion = localVersion;
 }
示例#29
0
 private bool DifferentAppProtocolVersionEncountered(
     Peer peer,
     AppProtocolVersion peerVersion,
     AppProtocolVersion localVersion)
 {
     Debug.LogWarningFormat(
         "Different Version Encountered; expected (local): {0}; actual ({1}): {2}",
         localVersion, peer, peerVersion
         );
     return(false);
 }
示例#30
0
 internal MessageValidator(
     AppProtocolVersion appProtocolVersion,
     IImmutableSet <PublicKey>?trustedAppProtocolVersionSigners,
     DifferentAppProtocolVersionEncountered?differentAppProtocolVersionEncountered,
     TimeSpan?messageTimestampBuffer)
 {
     Apv = appProtocolVersion;
     TrustedApvSigners       = trustedAppProtocolVersionSigners;
     DifferentApvEncountered = differentAppProtocolVersionEncountered;
     MessageTimestampBuffer  = messageTimestampBuffer;
 }