From cf1bc745f5d11340076d40388a9b5b9471d45885 Mon Sep 17 00:00:00 2001 From: web3melk Date: Wed, 24 May 2023 00:00:03 -0300 Subject: [PATCH 1/3] Add echo-ruby --- echo-ruby/.dockerignore | 4 ++ echo-ruby/.tool-versions | 1 + echo-ruby/Dockerfile | 12 ++++ echo-ruby/README.md | 63 ++++++++++++++++++++ echo-ruby/dapp.json | 5 ++ echo-ruby/docker-bake.hcl | 42 ++++++++++++++ echo-ruby/docker-bake.override.hcl | 23 ++++++++ echo-ruby/docker-compose.override.yml | 5 ++ echo-ruby/echo.rb | 82 +++++++++++++++++++++++++++ echo-ruby/entrypoint.sh | 15 +++++ 10 files changed, 252 insertions(+) create mode 100644 echo-ruby/.dockerignore create mode 100644 echo-ruby/.tool-versions create mode 100644 echo-ruby/Dockerfile create mode 100644 echo-ruby/README.md create mode 100644 echo-ruby/dapp.json create mode 100644 echo-ruby/docker-bake.hcl create mode 100644 echo-ruby/docker-bake.override.hcl create mode 100644 echo-ruby/docker-compose.override.yml create mode 100644 echo-ruby/echo.rb create mode 100755 echo-ruby/entrypoint.sh diff --git a/echo-ruby/.dockerignore b/echo-ruby/.dockerignore new file mode 100644 index 00000000..2235026f --- /dev/null +++ b/echo-ruby/.dockerignore @@ -0,0 +1,4 @@ +.tool-versions +docker-bake.hcl +docker-bake.override.hcl +docker-compose.override.yml \ No newline at end of file diff --git a/echo-ruby/.tool-versions b/echo-ruby/.tool-versions new file mode 100644 index 00000000..a2e77829 --- /dev/null +++ b/echo-ruby/.tool-versions @@ -0,0 +1 @@ +ruby 3.0.2 diff --git a/echo-ruby/Dockerfile b/echo-ruby/Dockerfile new file mode 100644 index 00000000..98745a52 --- /dev/null +++ b/echo-ruby/Dockerfile @@ -0,0 +1,12 @@ +# syntax=docker.io/docker/dockerfile:1.4 +FROM --platform=linux/riscv64 cartesi/toolchain:0.13.0 + +WORKDIR /opt/cartesi/dapp +COPY . . + +RUN apt-get update \ + && apt-get install -y ruby ruby-dev \ + && gem install json http \ + && gem cleanup \ + && rm -rf /usr/lib/ruby/gems/*/cache/* \ + && rm -rf /var/apt/lists/* \ No newline at end of file diff --git a/echo-ruby/README.md b/echo-ruby/README.md new file mode 100644 index 00000000..b2dec35b --- /dev/null +++ b/echo-ruby/README.md @@ -0,0 +1,63 @@ +# Echo Ruby DApp + +This example represents a minimalistic Cartesi Rollups application that simply copies (or "echoes") each input received as a corresponding output notice. This DApp's back-end is written in Ruby. + +## Interacting with the application + +We can use the [frontend-console](../frontend-console) application to interact with the DApp. +Ensure that the [application has already been built](../frontend-console/README.md#building) before using it. + +First, go to a separate terminal window and switch to the `frontend-console` directory: + +```shell +cd frontend-console +``` + +Then, send an input as follows: + +```shell +yarn start input send --payload "Hello there" +``` + +In order to verify the notices generated by your inputs, run the command: + +```shell +yarn start notice list +``` + +The response should be something like this: + +```json +[{"epoch":"0","input":"1","notice":"0","payload":"Hello there"}] +``` + +## Running the back-end in host mode + +When developing an application, it is often important to easily test and debug it. For that matter, it is possible to run the Cartesi Rollups environment in [host mode](../README.md#host-mode), so that the DApp's back-end can be executed directly on the host machine, allowing it to be debugged using regular development tools such as an IDE. + +This DApp's back-end is written in Ruby and expects version 2.6.6 or higher to be available in the host machine. + +In order to start the back-end, run the following commands in a dedicated terminal: + +```shell +cd echo-ruby/ +ruby echo.rb +``` + +The final command will effectively run the back-end and send corresponding outputs to port `5004`. +It can optionally be configured in an IDE to allow interactive debugging using features like breakpoints. + +You can also use a tool like [entr](https://eradman.com/entrproject/) to restart the back-end automatically when the code changes. For example: + +```shell +ls *.rb | entr -r ruby echo.rb +``` + +After the back-end successfully starts, it should print an output like the following: + +```log +HTTP rollup_server url is http://127.0.0.1:5004 +Sending finish +``` + +After that, you can interact with the application normally [as explained above](#interacting-with-the-application). diff --git a/echo-ruby/dapp.json b/echo-ruby/dapp.json new file mode 100644 index 00000000..89868f87 --- /dev/null +++ b/echo-ruby/dapp.json @@ -0,0 +1,5 @@ +{ + "fs": { + "files": ["echo.rb", "entrypoint.sh"] + } +} diff --git a/echo-ruby/docker-bake.hcl b/echo-ruby/docker-bake.hcl new file mode 100644 index 00000000..a58c7b2a --- /dev/null +++ b/echo-ruby/docker-bake.hcl @@ -0,0 +1,42 @@ +group "default" { + targets = ["dapp", "server", "console"] +} + +# crossenv toolchain for python dapps +target "toolchain-python" { + context = "../build/std-rootfs" + target = "toolchain-python" + tags = ["cartesi/toolchain-python"] +} + +target "fs" { + context = "../build/std-rootfs" + target = "fs-stage" + contexts = { + dapp = "target:dapp" + } +} + +target "server" { + context = "../build/std-rootfs" + target = "server-stage" + contexts = { + dapp = "target:dapp" + } +} + +target "console" { + context = "../build/std-rootfs" + target = "console-stage" + contexts = { + dapp = "target:dapp" + } +} + +target "machine" { + context = "../build/std-rootfs" + target = "machine-stage" + contexts = { + dapp = "target:dapp" + } +} \ No newline at end of file diff --git a/echo-ruby/docker-bake.override.hcl b/echo-ruby/docker-bake.override.hcl new file mode 100644 index 00000000..33a5f60c --- /dev/null +++ b/echo-ruby/docker-bake.override.hcl @@ -0,0 +1,23 @@ + +variable "TAG" { + default = "devel" +} + +variable "DOCKER_ORGANIZATION" { + default = "cartesi" +} + +target "dapp" { +} + +target "server" { + tags = ["${DOCKER_ORGANIZATION}/dapp:echo-ruby-${TAG}-server"] +} + +target "console" { + tags = ["${DOCKER_ORGANIZATION}/dapp:echo-ruby-${TAG}-console"] +} + +target "machine" { + tags = ["${DOCKER_ORGANIZATION}/dapp:echo-ruby-${TAG}-machine"] +} diff --git a/echo-ruby/docker-compose.override.yml b/echo-ruby/docker-compose.override.yml new file mode 100644 index 00000000..ae2d01f1 --- /dev/null +++ b/echo-ruby/docker-compose.override.yml @@ -0,0 +1,5 @@ +version: "3" + +services: + server_manager: + image: ${DAPP_IMAGE:-cartesi/dapp:echo-ruby-devel-server} diff --git a/echo-ruby/echo.rb b/echo-ruby/echo.rb new file mode 100644 index 00000000..e39abe96 --- /dev/null +++ b/echo-ruby/echo.rb @@ -0,0 +1,82 @@ +# Copyright 2022 Cartesi Pte. Ltd. +# +# SPDX-License-Identifier: Apache-2.0 +# Licensed under the Apache License, Version 2.0 (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +require 'json' +require 'http' + +def log(message) + puts message +end + +def handle_advance(data) + log("Received advance request data #{data}") + payload = data['payload'] + log("Adding notice \"#{payload}\"") + response = HTTP.post(ROLLUP_SERVER + '/notice', { + headers: { + 'Content-Type': 'application/json' + }, + json: { payload: payload } + }) + log("Received notice status #{response.status} with body #{response}") + return "accept"; +end + +def handle_inspect(data) + log("Received inspect request data #{data}"); + payload = data['payload'] + log("Adding report \"#{payload}\"") + response = HTTP.post(ROLLUP_SERVER + '/report', { + headers: { + 'Content-Type': 'application/json' + }, + json: { payload: payload } + }) + log("Received report status #{response.status}") + return "accept" +end + +ROLLUP_SERVER = ENV.fetch('ROLLUP_HTTP_SERVER_URL', 'http://127.0.0.1:5004') +log("HTTP rollup_server url is #{ROLLUP_SERVER}") + +finish = { status: "accept" } + +while (true) do + log("Sending finish") + + response = HTTP.post(ROLLUP_SERVER + '/finish', { + headers: { + 'Content-Type': 'application/json' + }, + json: { status: 'accept' } + }); + + log("Received finish status #{response.status}") + + if response.status == 202 + log("No pending rollup request, trying again") + else + rollup_req = response.parse + metadata = rollup_req['data']['metadata'] + if (metadata && metadata['epoch_index'] == 0 && metadata['input_index'] == 0) + rollup_address = metadata['msg_sender']; + log("Captured rollup address: #{rollup_address}") + else + case rollup_req['request_type'] + when 'advance_state' + finish[:status] = handle_advance(rollup_req['data']) + when 'inspect_state' + finish[:status] = handle_inspect(rollup_req['data']) + end + end + end +end \ No newline at end of file diff --git a/echo-ruby/entrypoint.sh b/echo-ruby/entrypoint.sh new file mode 100755 index 00000000..158bf65f --- /dev/null +++ b/echo-ruby/entrypoint.sh @@ -0,0 +1,15 @@ +#!/bin/sh +# Copyright 2022 Cartesi Pte. Ltd. +# +# SPDX-License-Identifier: Apache-2.0 +# Licensed under the Apache License, Version 2.0 (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +set -e +rollup-init ruby ./echo.rb From 533e41ce6d3b81ae56f809ecfba61ace121d5cb0 Mon Sep 17 00:00:00 2001 From: web3melk Date: Wed, 24 May 2023 18:26:10 -0300 Subject: [PATCH 2/3] Fix Dockerfile and rollback entrypoint of echo-ruby --- echo-ruby/Dockerfile | 10 ++++++---- echo-ruby/entrypoint.sh | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/echo-ruby/Dockerfile b/echo-ruby/Dockerfile index 98745a52..d21e6bda 100644 --- a/echo-ruby/Dockerfile +++ b/echo-ruby/Dockerfile @@ -1,12 +1,14 @@ # syntax=docker.io/docker/dockerfile:1.4 -FROM --platform=linux/riscv64 cartesi/toolchain:0.13.0 +FROM --platform=linux/riscv64 riscv64/ubuntu:22.04 WORKDIR /opt/cartesi/dapp -COPY . . RUN apt-get update \ - && apt-get install -y ruby ruby-dev \ + && apt-get install -y ruby ruby-dev build-essential \ && gem install json http \ && gem cleanup \ && rm -rf /usr/lib/ruby/gems/*/cache/* \ - && rm -rf /var/apt/lists/* \ No newline at end of file + && rm -rf /var/apt/lists/* + +COPY echo.rb . +COPY entrypoint.sh . \ No newline at end of file diff --git a/echo-ruby/entrypoint.sh b/echo-ruby/entrypoint.sh index 158bf65f..c69a70d1 100755 --- a/echo-ruby/entrypoint.sh +++ b/echo-ruby/entrypoint.sh @@ -12,4 +12,4 @@ # specific language governing permissions and limitations under the License. set -e -rollup-init ruby ./echo.rb +rollup-init ruby echo.rb From 37771c23c24488156434ed804e591697b88ba3c4 Mon Sep 17 00:00:00 2001 From: web3melk Date: Mon, 29 May 2023 23:23:04 -0300 Subject: [PATCH 3/3] Fixes reproducibility and small images --- echo-ruby/Dockerfile | 39 ++++++++++++++++++++++++++++++----- echo-ruby/Gemfile | 6 ++++++ echo-ruby/Gemfile.lock | 40 ++++++++++++++++++++++++++++++++++++ echo-ruby/docker-bake.hcl | 43 +-------------------------------------- echo-ruby/entrypoint.sh | 5 ++++- 5 files changed, 85 insertions(+), 48 deletions(-) create mode 100644 echo-ruby/Gemfile create mode 100644 echo-ruby/Gemfile.lock mode change 100644 => 120000 echo-ruby/docker-bake.hcl diff --git a/echo-ruby/Dockerfile b/echo-ruby/Dockerfile index d21e6bda..14e6a05e 100644 --- a/echo-ruby/Dockerfile +++ b/echo-ruby/Dockerfile @@ -1,14 +1,43 @@ # syntax=docker.io/docker/dockerfile:1.4 -FROM --platform=linux/riscv64 riscv64/ubuntu:22.04 + +# build stage: includes resources necessary for installing dependencies + +# Here the image's platform does not necessarily have to be riscv64. +# If any needed dependencies rely on native binaries, you must use +# a riscv64 image such as riscv64/ubuntu:22.04 for the build stage, +# to ensure that the appropriate binaries will be generated. +FROM --platform=linux/riscv64 riscv64/ubuntu:22.04 as build-stage WORKDIR /opt/cartesi/dapp +COPY Gemfile . +COPY Gemfile.lock . + +ENV GEM_HOME="/opt/cartesi/dapp/bundle" +ENV PATH=$GEM_HOME/bin:$GEM_HOME/gems/bin:$PATH + RUN apt-get update \ && apt-get install -y ruby ruby-dev build-essential \ - && gem install json http \ - && gem cleanup \ - && rm -rf /usr/lib/ruby/gems/*/cache/* \ - && rm -rf /var/apt/lists/* + && gem install bundler \ + && bundle install \ + && rm -rf /opt/cartesi/dapp/bundle/cache/* + +# runtime stage: produces final image that will be executed + +# Here the image's platform must be riscv64. +# Give preference to small base images, which lead to better start-up +# performance when loading the Cartesi Machine. +FROM --platform=linux/riscv64 riscv64/ubuntu:jammy +WORKDIR /opt/cartesi/dapp + +ENV GEM_HOME="/opt/cartesi/dapp/bundle" +ENV PATH=$GEM_HOME/bin:$GEM_HOME/gems/bin:$PATH + +RUN apt-get update \ + && apt-get install -y ruby \ + && rm -rf /var/apt/lists/* \ + && rm -rf /usr/lib/ruby/gems/*/cache/* +COPY --from=build-stage /opt/cartesi/dapp ./ COPY echo.rb . COPY entrypoint.sh . \ No newline at end of file diff --git a/echo-ruby/Gemfile b/echo-ruby/Gemfile new file mode 100644 index 00000000..e2e9250d --- /dev/null +++ b/echo-ruby/Gemfile @@ -0,0 +1,6 @@ +ruby '3.0.2' + +source 'https://rubygems.org' + +gem 'json' +gem 'http' diff --git a/echo-ruby/Gemfile.lock b/echo-ruby/Gemfile.lock new file mode 100644 index 00000000..1281945c --- /dev/null +++ b/echo-ruby/Gemfile.lock @@ -0,0 +1,40 @@ +GEM + remote: https://rubygems.org/ + specs: + addressable (2.8.1) + public_suffix (>= 2.0.2, < 6.0) + domain_name (0.5.20190701) + unf (>= 0.0.5, < 1.0.0) + ffi (1.15.5) + ffi-compiler (1.0.1) + ffi (>= 1.0.0) + rake + http (4.4.1) + addressable (~> 2.3) + http-cookie (~> 1.0) + http-form_data (~> 2.2) + http-parser (~> 1.2.0) + http-cookie (1.0.5) + domain_name (~> 0.5) + http-form_data (2.3.0) + http-parser (1.2.3) + ffi-compiler (>= 1.0, < 2.0) + json (2.6.3) + public_suffix (5.0.1) + rake (13.0.6) + unf (0.1.4) + unf_ext + unf_ext (0.0.8.2) + +PLATFORMS + arm64-darwin-21 + +DEPENDENCIES + http + json + +RUBY VERSION + ruby 3.0.2p107 + +BUNDLED WITH + 2.2.22 diff --git a/echo-ruby/docker-bake.hcl b/echo-ruby/docker-bake.hcl deleted file mode 100644 index a58c7b2a..00000000 --- a/echo-ruby/docker-bake.hcl +++ /dev/null @@ -1,42 +0,0 @@ -group "default" { - targets = ["dapp", "server", "console"] -} - -# crossenv toolchain for python dapps -target "toolchain-python" { - context = "../build/std-rootfs" - target = "toolchain-python" - tags = ["cartesi/toolchain-python"] -} - -target "fs" { - context = "../build/std-rootfs" - target = "fs-stage" - contexts = { - dapp = "target:dapp" - } -} - -target "server" { - context = "../build/std-rootfs" - target = "server-stage" - contexts = { - dapp = "target:dapp" - } -} - -target "console" { - context = "../build/std-rootfs" - target = "console-stage" - contexts = { - dapp = "target:dapp" - } -} - -target "machine" { - context = "../build/std-rootfs" - target = "machine-stage" - contexts = { - dapp = "target:dapp" - } -} \ No newline at end of file diff --git a/echo-ruby/docker-bake.hcl b/echo-ruby/docker-bake.hcl new file mode 120000 index 00000000..bc81cc07 --- /dev/null +++ b/echo-ruby/docker-bake.hcl @@ -0,0 +1 @@ +../build/docker-riscv/base.hcl \ No newline at end of file diff --git a/echo-ruby/entrypoint.sh b/echo-ruby/entrypoint.sh index c69a70d1..c5928fed 100755 --- a/echo-ruby/entrypoint.sh +++ b/echo-ruby/entrypoint.sh @@ -11,5 +11,8 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. +export GEM_HOME="/opt/cartesi/dapp/bundle" +export PATH=$GEM_HOME/bin:$GEM_HOME/gems/bin:$PATH + set -e -rollup-init ruby echo.rb +rollup-init bundle exec ruby echo.rb