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); }
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); }
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); }
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); }
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 })); }
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); }
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); }