Exemple #1
0
        public void NonEmpty()
        {
            HashDigest <SHA256> blockHash = new Random().NextHashDigest <SHA256>();
            // Note that here Unicode strings are used on purpose:
            IImmutableDictionary <string, IValue> states = ImmutableDictionary <string, IValue> .Empty
                                                           .Add("foo甲", null)
                                                           .Add("bar乙", default(Null))
                                                           .Add("baz丙", new Text("a value 값"));

            var          blockStates = new BlockStates(blockHash, states);
            var          signer      = new PrivateKey();
            NetMQMessage msg         = blockStates.ToNetMQMessage(
                signer,
                new Peer(signer.PublicKey, default),
                new AppProtocolVersion(
                    1,
                    new Bencodex.Types.Integer(0),
                    ImmutableArray <byte> .Empty,
                    default(Address)));

            Assert.Equal(Message.CommonFrames + 2 + 3 * 3, msg.FrameCount);
            TestUtils.AssertBytesEqual(
                blockHash,
                new HashDigest <SHA256>(msg[Message.CommonFrames].Buffer));
            Assert.Equal(
                states.Count,
                msg[Message.CommonFrames + 1].ConvertToInt32());

            var parsed = new BlockStates(msg.Skip(Message.CommonFrames).ToArray());

            TestUtils.AssertBytesEqual(blockHash, parsed.BlockHash);
            Assert.Equal(states, parsed.States);
        }
Exemple #2
0
        public static Message Parse(NetMQMessage raw, bool reply)
        {
            if (raw.FrameCount == 0)
            {
                throw new ArgumentException("Can't parse empty NetMQMessage.");
            }

            // (reply == true)  [type, sign, peer, frames...]
            // (reply == false) [identity, type, sign, peer, frames...]
            int headerCount = reply ? 3 : 4;
            var rawType     = (MessageType)raw[headerCount - 3].ConvertToInt32();
            var peer        = raw[headerCount - 2].ToByteArray();

            byte[] signature = raw[headerCount - 1].ToByteArray();

            NetMQFrame[] body = raw.Skip(headerCount).ToArray();

            var types = new Dictionary <MessageType, Type>
            {
                { MessageType.Ping, typeof(Ping) },
                { MessageType.Pong, typeof(Pong) },
                { MessageType.GetBlockHashes, typeof(GetBlockHashes) },
                { MessageType.BlockHashes, typeof(BlockHashes) },
                { MessageType.TxIds, typeof(TxIds) },
                { MessageType.GetBlocks, typeof(GetBlocks) },
                { MessageType.GetTxs, typeof(GetTxs) },
                { MessageType.Blocks, typeof(Blocks) },
                { MessageType.Tx, typeof(Tx) },
                { MessageType.FindNeighbors, typeof(FindNeighbors) },
                { MessageType.Neighbors, typeof(Neighbors) },
                { MessageType.GetRecentStates, typeof(GetRecentStates) },
                { MessageType.RecentStates, typeof(RecentStates) },
                { MessageType.BlockHeaderMessage, typeof(BlockHeaderMessage) },
            };

            if (!types.TryGetValue(rawType, out Type type))
            {
                throw new InvalidMessageException(
                          $"Can't determine NetMQMessage. [type: {rawType}]");
            }

            var message = (Message)Activator.CreateInstance(
                type, new[] { body });

            message.Remote = DeserializePeer(peer);

            if (!message.Remote.PublicKey.Verify(body.ToByteArray(), signature))
            {
                throw new InvalidMessageException(
                          "The message signature is invalid"
                          );
            }

            if (!reply)
            {
                message.Identity = raw[0].Buffer.ToArray();
            }

            return(message);
        }
Exemple #3
0
        public void Null()
        {
            HashDigest <SHA256> blockHash = new Random().NextHashDigest <SHA256>();
            var          blockStates      = new BlockStates(blockHash, null);
            var          signer           = new PrivateKey();
            NetMQMessage msg = blockStates.ToNetMQMessage(
                signer,
                new Peer(signer.PublicKey, default),
                new AppProtocolVersion(
                    1,
                    new Bencodex.Types.Integer(0),
                    ImmutableArray <byte> .Empty,
                    default(Address)));

            Assert.Equal(Message.CommonFrames + 2, msg.FrameCount);
            TestUtils.AssertBytesEqual(
                blockHash,
                new HashDigest <SHA256>(msg[Message.CommonFrames].Buffer));
            Assert.Equal(-1, msg[Message.CommonFrames + 1].ConvertToInt32());

            var parsed = new BlockStates(msg.Skip(Message.CommonFrames).ToArray());

            TestUtils.AssertBytesEqual(blockHash, parsed.BlockHash);
            Assert.Null(parsed.States);
        }
Exemple #4
0
        public bool TryReceive()
        {
            if (!IsConnected)
            {
                return(false);
            }

            //try to receive something from the network... if that succeeds get the distance from the given Erg
            var message = new NetMQMessage();

            if (subSocket.TryReceiveMultipartMessage(System.TimeSpan.Zero, ref message))
            {
                foreach (var frame in message.Skip(1)) //the first frame is always just the envelope/topic... let's ignore it by using Linq
                {
                    HandleFrame(frame);
                }
                return(true);
            }
            return(false);
        }
    private IList <Erg> ReceiveBoats()
    {
        //try to receive something from the network... return all the ergs we get
        var message = new NetMQMessage();
        IList <EasyErgsocket.Erg> receivedBoats = new List <EasyErgsocket.Erg>();

        while (subSocket.TryReceiveMultipartMessage(System.TimeSpan.Zero, ref message))
        {
            foreach (var frame in message.Skip(1)) //the first frame is always just the envelope/topic... let's ignore it by using Linq
            {
                byte[] rawMessage = frame.Buffer;
                using (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(rawMessage))
                {
                    var givenErg = Serializer.Deserialize <EasyErgsocket.Erg>(memoryStream);
                    receivedBoats.Add(givenErg);
                }
            }
        }

        return(receivedBoats);
    }
Exemple #6
0
        public static Message Parse(NetMQMessage raw)
        {
            if (raw.FrameCount == 0)
            {
                throw new ArgumentException(
                          $"Can't parse {nameof(Message)}, " +
                          $"because ${nameof(raw)} was empty.",
                          nameof(raw));
            }

            var rawType = (MessageType)raw[0].ConvertToInt32();

            if (!TypeMapping.TryGetValue(rawType, out Type type))
            {
                throw new InvalidMessageException(
                          $"Unknown message came. [{nameof(rawType)} == {rawType}]");
            }

            var bodyFrames = raw.Skip(1).ToArray();

            return((Message)Activator.CreateInstance(type, new[] { bodyFrames }));
        }
Exemple #7
0
        public static Message Parse(
            NetMQMessage raw,
            bool reply,
            AppProtocolVersion localVersion,
            IImmutableSet <PublicKey> trustedAppProtocolVersionSigners,
            DifferentAppProtocolVersionEncountered differentAppProtocolVersionEncountered)
        {
            if (raw.FrameCount == 0)
            {
                throw new ArgumentException("Can't parse empty NetMQMessage.");
            }

            // (reply == true)  [version, type, peer, sign, frames...]
            // (reply == false) [identity, version, type, peer, sign, frames...]
            NetMQFrame[] remains = reply ? raw.ToArray() : raw.Skip(1).ToArray();

            var versionToken = remains[(int)MessageFrame.Version].ConvertToString();

            AppProtocolVersion remoteVersion = AppProtocolVersion.FromToken(versionToken);
            Peer remotePeer = null;

            try
            {
                remotePeer = DeserializePeer(remains[(int)MessageFrame.Peer].ToByteArray());
            }
            catch (Exception)
            {
                // If failed to find out remotePeer, leave it null.
            }

            if (!IsAppProtocolVersionValid(
                    remotePeer,
                    localVersion,
                    remoteVersion,
                    trustedAppProtocolVersionSigners,
                    differentAppProtocolVersionEncountered))
            {
                throw new DifferentAppProtocolVersionException(
                          "Received message's version is not valid.",
                          reply ? null : raw[0].Buffer.ToArray(),
                          localVersion,
                          remoteVersion);
            }

            var rawType = (MessageType)remains[(int)MessageFrame.Type].ConvertToInt32();
            var peer    = remains[(int)MessageFrame.Peer].ToByteArray();

            byte[] signature = remains[(int)MessageFrame.Sign].ToByteArray();

            NetMQFrame[] body = remains.Skip(CommonFrames).ToArray();

            // FIXME: The below code is too repetitive and prone to miss to add, which means,
            // when you add a new message type, you adds an enum member to MessageType and
            // a corresponding subclass of Message, but misses to add that correspondence here,
            // you may take a long time to be aware you've missed here, because the code is still
            // built well and it looks like just Swarm<T> silently ignore new messages.
            // At least this correspondence map should not be here.
            var types = new Dictionary <MessageType, Type>
            {
                { MessageType.Ping, typeof(Ping) },
                { MessageType.Pong, typeof(Pong) },
                { MessageType.GetBlockHashes, typeof(GetBlockHashes) },
                { MessageType.BlockHashes, typeof(BlockHashes) },
                { MessageType.TxIds, typeof(TxIds) },
                { MessageType.GetBlocks, typeof(GetBlocks) },
                { MessageType.GetTxs, typeof(GetTxs) },
                { MessageType.Blocks, typeof(Blocks) },
                { MessageType.Tx, typeof(Tx) },
                { MessageType.FindNeighbors, typeof(FindNeighbors) },
                { MessageType.Neighbors, typeof(Neighbors) },
                { MessageType.GetRecentStates, typeof(GetRecentStates) },
                { MessageType.RecentStates, typeof(RecentStates) },
                { MessageType.BlockHeaderMessage, typeof(BlockHeaderMessage) },
                { MessageType.GetChainStatus, typeof(GetChainStatus) },
                { MessageType.ChainStatus, typeof(ChainStatus) },
                { MessageType.GetBlockStates, typeof(GetBlockStates) },
                { MessageType.BlockStates, typeof(BlockStates) },
                { MessageType.DifferentVersion, typeof(DifferentVersion) },
            };

            if (!types.TryGetValue(rawType, out Type type))
            {
                throw new InvalidMessageException(
                          $"Can't determine NetMQMessage. [type: {rawType}]");
            }

            var message = (Message)Activator.CreateInstance(
                type, new[] { body });

            message.Version = remoteVersion;
            message.Remote  = remotePeer;

            if (!message.Remote.PublicKey.Verify(body.ToByteArray(), signature))
            {
                throw new InvalidMessageException(
                          "The message signature is invalid"
                          );
            }

            if (!reply)
            {
                message.Identity = raw[0].Buffer.ToArray();
            }

            return(message);
        }
Exemple #8
0
        public static Message Parse(NetMQMessage raw, bool reply)
        {
            if (raw.FrameCount == 0)
            {
                throw new ArgumentException("Can't parse empty NetMQMessage.");
            }

            // (reply == true)  [type, sign, pubkey, frames...]
            // (reply == false) [identity, type, sign, pubkey, frames...]
            int headerCount = reply ? 3 : 4;
            var type        = (MessageType)raw[headerCount - 3].ConvertToInt32();
            var publicKey   = new PublicKey(raw[headerCount - 2].ToByteArray());

            byte[] signature = raw[headerCount - 1].ToByteArray();

            NetMQFrame[] body = raw.Skip(headerCount).ToArray();

            if (!publicKey.Verify(body.ToByteArray(), signature))
            {
                throw new InvalidMessageException("the message signature is invalid");
            }

            Message message;

            switch (type)
            {
            case MessageType.Ping:
                message = new Ping();
                break;

            case MessageType.Pong:
                message = new Pong();
                break;

            case MessageType.PeerSetDelta:
                message = PeerSetDelta.ParseBody(body);
                break;

            case MessageType.GetBlocks:
                message = GetBlocks.ParseBody(body);
                break;

            case MessageType.Inventory:
                message = Inventory.Parse(body);
                break;

            case MessageType.GetData:
                message = GetData.Parse(body);
                break;

            case MessageType.Block:
                message = Block.Parse(body);
                break;

            default:
                throw new InvalidMessageException(
                          $"Can't determine NetMQMessage. [type: {type}]");
            }

            if (!reply)
            {
                message.Identity = new Address(raw[0].Buffer);
            }

            return(message);
        }