Skip to content
This repository was archived by the owner on Mar 12, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions echo-ruby/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.tool-versions
docker-bake.hcl
docker-bake.override.hcl
docker-compose.override.yml
1 change: 1 addition & 0 deletions echo-ruby/.tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ruby 3.0.2
43 changes: 43 additions & 0 deletions echo-ruby/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# syntax=docker.io/docker/dockerfile:1.4

# 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 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 .
6 changes: 6 additions & 0 deletions echo-ruby/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
ruby '3.0.2'

source 'https://rubygems.org'

gem 'json'
gem 'http'
40 changes: 40 additions & 0 deletions echo-ruby/Gemfile.lock
Original file line number Diff line number Diff line change
@@ -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
63 changes: 63 additions & 0 deletions echo-ruby/README.md
Original file line number Diff line number Diff line change
@@ -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).
5 changes: 5 additions & 0 deletions echo-ruby/dapp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"fs": {
"files": ["echo.rb", "entrypoint.sh"]
}
}
1 change: 1 addition & 0 deletions echo-ruby/docker-bake.hcl
23 changes: 23 additions & 0 deletions echo-ruby/docker-bake.override.hcl
Original file line number Diff line number Diff line change
@@ -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"]
}
5 changes: 5 additions & 0 deletions echo-ruby/docker-compose.override.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
version: "3"

services:
server_manager:
image: ${DAPP_IMAGE:-cartesi/dapp:echo-ruby-devel-server}
82 changes: 82 additions & 0 deletions echo-ruby/echo.rb
Original file line number Diff line number Diff line change
@@ -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
18 changes: 18 additions & 0 deletions echo-ruby/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/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.

export GEM_HOME="/opt/cartesi/dapp/bundle"
export PATH=$GEM_HOME/bin:$GEM_HOME/gems/bin:$PATH

set -e
rollup-init bundle exec ruby echo.rb