-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from daveminer/build-handshake-msg
Build handshake msg
- Loading branch information
Showing
12 changed files
with
319 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
name: Elixir CI | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
pull_request: | ||
branches: | ||
- main | ||
|
||
jobs: | ||
test: | ||
runs-on: ubuntu-latest | ||
|
||
strategy: | ||
matrix: | ||
elixir-version: [1.16, 1.17, 1.18] | ||
otp-version: [24.0, 25.0, 26.0] | ||
|
||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v3 | ||
|
||
- name: Set up Elixir | ||
uses: erlef/setup-beam@v1 | ||
with: | ||
elixir-version: ${{ matrix.elixir-version }} | ||
otp-version: ${{ matrix.otp-version }} | ||
|
||
- name: Cache dependencies | ||
uses: actions/cache@v3 | ||
with: | ||
path: deps | ||
key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }} | ||
restore-keys: | | ||
${{ runner.os }}-mix- | ||
- name: Install dependencies | ||
run: mix deps.get | ||
|
||
- name: Run tests | ||
run: mix test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
defmodule Mix.Tasks.Dev do | ||
use Mix.Task | ||
|
||
alias Rex.Handshake | ||
|
||
def run(_) do | ||
Application.ensure_all_started(:rex) | ||
|
||
msg = Handshake.Proposal.version_message([10, 11, 12, 13, 14, 15, 16], :mainnet) | ||
|
||
dbg(msg) | ||
dbg(CBOR.decode(msg)) | ||
|
||
:ok | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
defmodule Rex.Handshake.Proposal do | ||
@moduledoc """ | ||
Builds handshake messages for node-to-client communication. | ||
""" | ||
|
||
@type network_type :: :mainnet | :preprod | :preview | :sanchonet | ||
|
||
@network_magic [ | ||
mainnet: 764_824_073, | ||
preprod: 1, | ||
preview: 2, | ||
sanchonet: 4 | ||
] | ||
|
||
@version_numbers %{ | ||
9 => 32777, | ||
10 => 32778, | ||
11 => 32779, | ||
12 => 32780, | ||
13 => 32781, | ||
14 => 32782, | ||
15 => 32783, | ||
16 => 32784, | ||
17 => 32785 | ||
} | ||
|
||
@doc """ | ||
Version numbers must be unique and appear in ascending order. | ||
""" | ||
@spec version_message([integer()], network_type) :: binary() | ||
def version_message(versions, network) do | ||
payload = | ||
[ | ||
# msgProposeVersions | ||
0, | ||
build_version_fragments(versions |> Enum.sort(), network) | ||
] | ||
|> CBOR.encode() | ||
|
||
header(payload) <> payload | ||
end | ||
|
||
defp build_version_fragments(versions, network), | ||
do: | ||
Enum.reduce(versions, %{}, fn version, acc -> | ||
Map.merge(acc, version_fragment(version, network)) | ||
end) | ||
|
||
defp version_fragment(version, network) when version >= 15, | ||
do: %{@version_numbers[version] => [@network_magic[network], false]} | ||
|
||
defp version_fragment(version, network), | ||
do: %{@version_numbers[version] => @network_magic[network]} | ||
|
||
# middle 16 bits are: 1 bit == 0 for initiator and 15 bits for the mini protocol ID (0) | ||
defp header(payload), | ||
do: <<header_timestamp()::32>> <> <<0, 0>> <> <<byte_size(payload)::unsigned-16>> | ||
|
||
# Returns the lower 32 bits of the system's monotonic time in microseconds | ||
defp header_timestamp(), | ||
do: | ||
System.monotonic_time(:microsecond) | ||
|> Bitwise.band(0xFFFFFFFF) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
defmodule Rex.Handshake.Response do | ||
defstruct [:type, :version_number, :network_magic, :query] | ||
|
||
alias Rex.Util | ||
|
||
def validate(response) do | ||
%{payload: payload} = Util.plex(response) | ||
|
||
case CBOR.decode(payload) do | ||
# msgAcceptVersion | ||
{:ok, [1, version, [magic, query]], ""} -> | ||
if version in [32783, 32784] do | ||
{:ok, | ||
%__MODULE__{ | ||
network_magic: magic, | ||
query: query, | ||
type: :msg_accept_version, | ||
version_number: version | ||
}} | ||
else | ||
{:error, "Only versions 32783 and 32784 are supported."} | ||
end | ||
|
||
# msgRefuse | ||
{:ok, [2, refuse_reason], ""} -> | ||
case refuse_reason do | ||
# TODO: return accepted versions; reduce to 32783 and 32784 | ||
[0, _version_number_binary] -> | ||
{:refused, %__MODULE__{type: :version_mismatch}} | ||
|
||
[1, _anyVersionNumber, _tstr] -> | ||
{:refused, %__MODULE__{type: :handshake_decode_error}} | ||
|
||
[2, _anyVersionNumber, _tstr] -> | ||
{:refused, %__MODULE__{type: :refused}} | ||
end | ||
|
||
# TODO: parse version_table | ||
# msgQueryReply | ||
{:ok, [3, version_table], ""} -> | ||
{:versions, version_table} | ||
|
||
{:error, reason} -> | ||
{:error, reason} | ||
end | ||
end | ||
end |
Oops, something went wrong.