Skip to content

Commit

Permalink
Skeleton of Elixir monitor (#36)
Browse files Browse the repository at this point in the history
Co-authored-by: Pablo Deymonnaz <[email protected]>
  • Loading branch information
pablodeymo and pablodeymo authored Oct 11, 2023
1 parent 8287413 commit cf0189f
Show file tree
Hide file tree
Showing 18 changed files with 378 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/proof.json
monitor/priv/native/libverifier.so
4 changes: 4 additions & 0 deletions monitor/.formatter.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Used by "mix format"
[
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
]
26 changes: 26 additions & 0 deletions monitor/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# The directory Mix will write compiled artifacts to.
/_build/

# If you run "mix test --cover", coverage assets end up here.
/cover/

# The directory Mix downloads your dependencies sources to.
/deps/

# Where third-party dependencies like ExDoc output generated docs.
/doc/

# Ignore .fetch files in case you like to edit your project deps locally.
/.fetch

# If the VM crashes, it generates a dump, let's ignore it too.
erl_crash.dump

# Also ignore archive artifacts (built via "mix archive.build").
*.ez

# Ignore package tarball (built via "mix hex.build").
monitor-*.tar

# Temporary files, for example, from tests.
/tmp/
13 changes: 13 additions & 0 deletions monitor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Monitor

To run the project, you need to have Elixir installed. Then, run the following commands:

```bash
iex -S mix
```

To update the dependencies, run:

```bash
mix deps.get
```
18 changes: 18 additions & 0 deletions monitor/lib/monitor.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
defmodule Monitor do
@moduledoc """
Documentation for `Monitor`.
"""

@doc """
Hello world.
## Examples
iex> Monitor.hello()
:world
"""
def hello do
:world
end
end
21 changes: 21 additions & 0 deletions monitor/lib/monitor/application.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
defmodule Monitor.Application do
# See https://hexdocs.pm/elixir/Application.html
# for more information on OTP Applications
@moduledoc false

use Application

@impl true
def start(_type, _args) do
children = [
# Starts a worker by calling: Monitor.Worker.start_link(arg)
# {Monitor.Worker, arg}
Monitor.Watcher
]

# See https://hexdocs.pm/elixir/Supervisor.html
# for other strategies and supported options
opts = [strategy: :one_for_one, name: Monitor.Supervisor]
Supervisor.start_link(children, opts)
end
end
5 changes: 5 additions & 0 deletions monitor/lib/verifier.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
defmodule Verifier do
use Rustler, otp_app: :monitor, crate: "verifier"
def add(_a, _b), do: :erlang.nif_error(:nif_not_loaded)
def run_program_and_get_proof(_file_name), do: :erlang.nif_error(:nif_not_loaded)
end
48 changes: 48 additions & 0 deletions monitor/lib/watcher.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
defmodule Monitor.Watcher do
use GenServer
require Logger

@polling_frequency_ms 5_000
@number_of_blocks_for_confirmation 0

def start_link(args) do
GenServer.start_link(__MODULE__, args, name: __MODULE__)
end

@impl true
def init(_opts) do
state = %{
last_confirmed_block_number: 1,
highest_block: 0
}

Process.send_after(self(), :poll, @polling_frequency_ms)
{:ok, state}
end

@doc """
This handler will first poll the chain for the latest block number, check which blocks are confirmed but have not
been proved yet, then run a proof for them and upload it to S3.
"""
@impl true
def handle_info(
:poll,
state = %{
last_confirmed_block_number: last_confirmed_block_number
}
) do
Process.send_after(self(), :poll, @polling_frequency_ms)
current_block_height = 0

Logger.info("Current block height: #{current_block_height}")

result = Verifier.add(1, 5)
Logger.info("Got result from Rust: #{result}")

{:noreply,
%{
state
| last_confirmed_block_number: last_confirmed_block_number
}}
end
end
31 changes: 31 additions & 0 deletions monitor/mix.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
defmodule Monitor.MixProject do
use Mix.Project

def project do
[
app: :monitor,
version: "0.1.0",
elixir: "~> 1.15",
start_permanent: Mix.env() == :prod,
deps: deps()
]
end

# Run "mix help compile.app" to learn about applications.
def application do
[
extra_applications: [:logger],
mod: {Monitor.Application, []}
]
end

# Run "mix help deps" to learn about dependencies.
defp deps do
[
{:rustler, "~> 0.29.0"},
{:absinthe, "~> 1.7"}
# {:dep_from_hexpm, "~> 0.3.0"},
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
]
end
end
8 changes: 8 additions & 0 deletions monitor/mix.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
%{
"absinthe": {:hex, :absinthe, "1.7.5", "a15054f05738e766f7cc7fd352887dfd5e61cec371fb4741cca37c3359ff74ac", [:mix], [{:dataloader, "~> 1.0.0 or ~> 2.0", [hex: :dataloader, repo: "hexpm", optional: true]}, {:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.2.2 or ~> 1.3.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:opentelemetry_process_propagator, "~> 0.2.1", [hex: :opentelemetry_process_propagator, repo: "hexpm", optional: true]}, {:telemetry, "~> 1.0 or ~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "22a9a38adca26294ad0ee91226168f5d215b401efd770b8a1b8fd9c9b21ec316"},
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
"nimble_parsec": {:hex, :nimble_parsec, "1.3.1", "2c54013ecf170e249e9291ed0a62e5832f70a476c61da16f6aac6dca0189f2af", [:mix], [], "hexpm", "2682e3c0b2eb58d90c6375fc0cc30bc7be06f365bf72608804fb9cffa5e1b167"},
"rustler": {:hex, :rustler, "0.29.1", "880f20ae3027bd7945def6cea767f5257bc926f33ff50c0d5d5a5315883c084d", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:toml, "~> 0.6", [hex: :toml, repo: "hexpm", optional: false]}], "hexpm", "109497d701861bfcd26eb8f5801fe327a8eef304f56a5b63ef61151ff44ac9b6"},
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
"toml": {:hex, :toml, "0.7.0", "fbcd773caa937d0c7a02c301a1feea25612720ac3fa1ccb8bfd9d30d822911de", [:mix], [], "hexpm", "0690246a2478c1defd100b0c9b89b4ea280a22be9a7b313a8a058a2408a2fa70"},
}
5 changes: 5 additions & 0 deletions monitor/native/verifier/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[target.'cfg(target_os = "macos")']
rustflags = [
"-C", "link-arg=-undefined",
"-C", "link-arg=dynamic_lookup",
]
1 change: 1 addition & 0 deletions monitor/native/verifier/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/target
149 changes: 149 additions & 0 deletions monitor/native/verifier/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions monitor/native/verifier/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "verifier"
version = "0.1.0"
authors = []
edition = "2021"

[lib]
name = "verifier"
path = "src/lib.rs"
crate-type = ["cdylib"]

[dependencies]
rustler = "0.29.1"
20 changes: 20 additions & 0 deletions monitor/native/verifier/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# NIF for Elixir.Verifier

## To build the NIF module:

- Your NIF will now build along with your project.

## To load the NIF:

```elixir
defmodule Verifier do
use Rustler, otp_app: :monitor, crate: "verifier"

# When your NIF is loaded, it will override this function.
def add(_a, _b), do: :erlang.nif_error(:nif_not_loaded)
end
```

## Examples

[This](https://github.com/rusterlium/NifIo) is a complete example of a NIF written in Rust.
6 changes: 6 additions & 0 deletions monitor/native/verifier/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#[rustler::nif]
fn add(a: i64, b: i64) -> i64 {
a + b
}

rustler::init!("Elixir.Verifier", [add]);
8 changes: 8 additions & 0 deletions monitor/test/monitor_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
defmodule MonitorTest do
use ExUnit.Case
doctest Monitor

test "greets the world" do
assert Monitor.hello() == :world
end
end
1 change: 1 addition & 0 deletions monitor/test/test_helper.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ExUnit.start()

0 comments on commit cf0189f

Please sign in to comment.