During the Hacker it was mentioned that we would like to test some of our prototypes against the anoma/anoma
codebase and see how it sends things through the pipeline.
Because of this Juvix was suggested as being a decent language to test this kind of prototype, with the caveat that the compiler must be changed to accommodate the required changes.
However I believe there is an easier way to test things through anoma/anoma
and will let us use the best language for the job. The key observation is that we don’t need to support whatever this language is for any workflow in a product (in fact our anockma backend and cairo backend are already relegated to this) and so we could just make a new backend! The amount of work that it takes to make a new backend is minimal, as we can bootstrap the new backend by just reusing the anockma backend.
The line that would need to change is:
defmodule Anoma.RM.Transparent.ProvingSystem.RLPS.Instance do
@spec verify(binary(), Instance.t(), <<>>) :: boolean()
def verify(jammed_predicate, instance, <<>>) do
with {:ok, predicate} <- Noun.Jam.cue(jammed_predicate),
{:ok, resource} <- match_resource(instance.tag, instance.flag),
true = Noun.equal?(jammed_predicate, resource.logicref),
{:ok, res} <-
Nock.nock(predicate, [
9,
2,
10,
[6, 1 | to_noun_rl_args(instance)],
0 | 1
]) do
Noun.equal?(res, 0)
else
{:error, msg} ->
Logger.error(msg)
false
end
end
to
@spec verify(binary(), Instance.t(), <<>>) :: boolean()
def verify(jammed_predicate, instance, <<>>) do
with {:ok, predicate} <- Language.decode(jammed_predicate),
{:ok, resource} <- match_resource(instance.tag, instance.flag),
true = Noun.equal?(jammed_predicate, resource.logicref),
{:ok, res} <- Language.eval(predicate, to_args_list(instance)) do
equal?(res, 0)
else
{:error, msg} ->
Logger.error(msg)
false
end
end
The match_resource
will need to change in a minor way as well for the proper encoding format we’ll use for the language.
For submitting transactions/intents the process is much the same, since we already know how to represent these as other data types than just nock cells, we can just output the ur format equivalent and submit that to the mempool meaning that not much work is needed there either.
What languages become easier
If we do this method, the easiest language to support would be any beam
languages, so Erlang
, Elixir
and Gleam
. Since we can just call the native beam eval. Further for Elixir
it has a decent macro system so any language changes can easily be relegated to being a small macro context without much work at all.
The downside of using any of these language is that they lack object systems, so we won’t get to see any of the interactions between an existing object system and what we are accomplishing. This may or may not matter depending what a specific prototype is trying to model.
Other languages can easily be supported as well, even live ones, however doing so may take a bit extra work:
- We will need to bridge these languages to Elixir
- If the language is live we likely will want to make a small
port
So for a language like CL this would mean either:
- Expose eval from the sbcl binary and call that
- This has the upside of calling into shells are trivial
- This has the downside that we always need to supply all definitions to load, making it a bit cumbersome
- Another big downside is that debugging this would be in a batch way since we are spinning up an image every time instead of going through a proper port
- Open a socket on Unix to send data back and forth and serialize the data structures as json
- This has the benefit of being live so you can debug and trace the execution as it goes, and have the full interactive tooling to understand the behaviour and isolate any issues
- The downside is that a quick socket for communication would have to be had, not hard, just a little bit of work
- Make a
port
on Elixir to manage the resource- This is a very erlang way of dealing with outside processes
- I believe this work with every language not just C, however I need to look into this.
This is true for any language, with the caveat that for Rust and C rustler and ports seem like an easy way to do this for quick modeling