ex_wire v0.1.1 ExWire.Network

This module will handle the business logic for processing incoming messages from the network. We will, for instance, decide to respond pong to any incoming ping.

Link to this section Summary

Functions

Given the data of an inbound message, we’ll run a quick SHA3 sum to verify the integrity of the message

Function to pass message to the appropriate handler. E.g. for a ping we’ll pass the decoded message to ExWire.Handlers.Ping.handle/1

Top-level receiver function to process an incoming message. We’ll first validate the message, and then pass it to the appropriate handler

Sends a message asynchronously via casting a message to our running gen_server

Link to this section Types

Link to this type handler_action()
handler_action() :: :no_action | {:sent_message, atom}

Link to this section Functions

Link to this function assert_integrity(arg)
assert_integrity(binary) :: :ok

Given the data of an inbound message, we’ll run a quick SHA3 sum to verify the integrity of the message.

Examples

iex> ExWire.Network.assert_integrity(ExWire.Crypto.hash("hi mom") <> "hi mom")
:ok

iex> ExWire.Network.assert_integrity(<<1::256>> <> "hi mom")
** (ExWire.Crypto.HashMismatch) Invalid hash

Function to pass message to the appropriate handler. E.g. for a ping we’ll pass the decoded message to ExWire.Handlers.Ping.handle/1.

Examples

iex> ping_data = [1, [<<1,2,3,4>>, <<>>, <<5>>], [<<5,6,7,8>>, <<6>>, <<>>], 4] |> ExRLP.encode
iex> ExWire.Network.handle(%ExWire.Network.InboundMessage{
...>   data: <<0::256>> <> <<0::512>> <> <<0::8>> <> <<1::8>> <> ping_data,
...>   server_pid: self(),
...>   remote_host: nil,
...>   timestamp: 5,
...> })
{:sent_message, ExWire.Message.Pong}

iex> ExWire.Network.handle(%ExWire.Network.InboundMessage{
...>   data: <<0::256>> <> <<0::512>> <> <<0::8>> <> <<99::8>> <> <<>>,
...>   server_pid: self(),
...>   remote_host: nil,
...>   timestamp: 5,
...> })
:no_action

Top-level receiver function to process an incoming message. We’ll first validate the message, and then pass it to the appropriate handler.

Examples

iex> ping_data = [1, [<<1,2,3,4>>, <<>>, <<5>>], [<<5,6,7,8>>, <<6>>, <<>>], 4] |> ExRLP.encode
iex> payload = <<0::512>> <> <<0::8>> <> <<1::8>> <> ping_data
iex> hash = ExWire.Crypto.hash(payload)
iex> ExWire.Network.receive(%ExWire.Network.InboundMessage{
...>   data: hash <> <<0::512>> <> <<0::8>> <> <<1::8>> <> ping_data,
...>   server_pid: self(),
...>   remote_host: nil,
...>   timestamp: 123,
...> })
{:sent_message, ExWire.Message.Pong}

iex> ping_data = [1, [<<1,2,3,4>>, <<>>, <<5>>], [<<5,6,7,8>>, <<6>>, <<>>], 4] |> ExRLP.encode
iex> payload = <<0::512>> <> <<0::8>> <> <<1::8>> <> ping_data
iex> hash = ExWire.Crypto.hash("hello")
iex> ExWire.Network.receive(%ExWire.Network.InboundMessage{
...>   data: hash <> payload,
...>   server_pid: self(),
...>   remote_host: nil,
...>   timestamp: 123,
...> })
** (ExWire.Crypto.HashMismatch) Invalid hash

Sends a message asynchronously via casting a message to our running gen_server.

Examples

iex> message = %ExWire.Message.Pong{
...>   to: %ExWire.Struct.Endpoint{ip: [1, 2, 3, 4], tcp_port: 5, udp_port: nil},
...>   hash: <<2>>,
...>   timestamp: 3,
...> }
iex> ExWire.Network.send(message, self(), %ExWire.Struct.Endpoint{ip: <<1, 2, 3, 4>>, udp_port: 5})
{:sent_message, ExWire.Message.Pong}
iex> receive do m -> m end
{:"$gen_cast",
  {:send,
    %{
      data: ExWire.Protocol.encode(message, ExWire.Config.private_key()),
      to: %ExWire.Struct.Endpoint{
        ip: <<1, 2, 3, 4>>,
        tcp_port: nil,
        udp_port: 5}
    }
  }
}