├── fs ├── Dockerfile.dockerignore ├── third-party │ └── repo-info │ │ ├── Dockerfile.local-dpkg │ │ ├── scan-local.sh │ │ └── gather-dpkg.sh └── Dockerfile ├── rollup-http ├── rollup-http-client │ ├── .gitignore │ ├── src │ │ ├── lib.rs │ │ └── rollup.rs │ └── Cargo.toml ├── .cargo │ └── config.toml ├── rollup-http-server │ ├── src │ │ ├── lib.rs │ │ ├── config.rs │ │ ├── dapp_process.rs │ │ └── main.rs │ ├── Cargo.toml │ ├── README.md │ └── build.rs ├── Makefile ├── rollup-init │ └── rollup-init └── echo-dapp │ ├── Cargo.toml │ ├── src │ └── config.rs │ └── README.md ├── sys-utils ├── libcmt │ ├── .gitignore │ ├── tools │ │ ├── prepare-ffi.sh │ │ ├── libcmt.pc.in │ │ └── funsel.c │ ├── doc │ │ ├── examples │ │ │ ├── abi_decode_000.c │ │ │ ├── abi_encode_000.c │ │ │ ├── abi_decode_001.c │ │ │ ├── abi_encode_001.c │ │ │ ├── abi_decode_002.c │ │ │ ├── abi_encode_002.c │ │ │ ├── io.c │ │ │ ├── abi_multi.c │ │ │ └── rollup.c │ │ └── DoxygenLayout.xml │ ├── .clang-format │ ├── tests │ │ ├── progress.c │ │ ├── gio.c │ │ ├── create-data.sh │ │ ├── io_exception.c │ │ ├── io.c │ │ ├── keccak.c │ │ ├── buf.c │ │ ├── data.h │ │ ├── abi-multi.c │ │ └── merkle.c │ ├── include │ │ └── libcmt │ │ │ ├── util.h │ │ │ ├── buf.h │ │ │ ├── keccak.h │ │ │ ├── merkle.h │ │ │ └── io.h │ ├── src │ │ ├── util.c │ │ ├── buf.c │ │ ├── io.c │ │ └── keccak.c │ ├── .clang-tidy │ ├── README.md │ └── Makefile ├── cartesi-init │ ├── Makefile │ └── cartesi-init ├── misc │ ├── Makefile │ ├── readbe64 │ ├── writebe64 │ └── flashdrive ├── xhalt │ ├── xhalt.c │ └── Makefile ├── hex │ ├── Makefile │ └── hex.cpp ├── yield │ ├── Makefile │ └── yield.c ├── rollup │ └── Makefile ├── Makefile └── ioctl-echo-loop │ ├── Makefile │ └── ioctl-echo-loop.c ├── package.json.in ├── AUTHORS ├── Dockerfile.dockerignore ├── postinst ├── control.in ├── .github ├── ISSUE_TEMPLATE │ ├── update-dependencies.md │ ├── technical-debt.md │ ├── feature-request.md │ └── bug-report.md ├── workflows │ ├── commits.yml │ └── main.yml └── pull_request_template.md ├── .clang-format ├── .gitignore ├── copyright ├── CONTRIBUTING.md ├── README.md ├── Dockerfile ├── CODE_OF_CONDUCT.md ├── Makefile └── CHANGELOG.md /fs/Dockerfile.dockerignore: -------------------------------------------------------------------------------- 1 | third-party 2 | -------------------------------------------------------------------------------- /rollup-http/rollup-http-client/.gitignore: -------------------------------------------------------------------------------- 1 | Cargo.lock 2 | -------------------------------------------------------------------------------- /rollup-http/rollup-http-client/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod client; 2 | pub mod rollup; 3 | -------------------------------------------------------------------------------- /sys-utils/libcmt/.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | compile_flags.txt 3 | */*.clang-tidy* 4 | *.bin 5 | -------------------------------------------------------------------------------- /package.json.in: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cartesi-machine-guest-tools", 3 | "version": "ARG_VERSION" 4 | } 5 | -------------------------------------------------------------------------------- /rollup-http/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [target.riscv64gc-unknown-linux-gnu] 2 | linker = "riscv64-linux-gnu-gcc" 3 | 4 | [net] 5 | git-fetch-with-cli = true 6 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Diego Nehab 2 | Eduardo Barthel 3 | Gabriel de Quadros Ligneul 4 | Marcelo Politzer 5 | Marko Atanasievski 6 | Marcos Pernambuco Motta 7 | Victor Fusco 8 | -------------------------------------------------------------------------------- /sys-utils/cartesi-init/Makefile: -------------------------------------------------------------------------------- 1 | PREFIX ?= /usr 2 | 3 | all: ; 4 | 5 | install: 6 | install -Dm755 cartesi-init $(DESTDIR)$(PREFIX)/sbin/cartesi-init 7 | 8 | clean: ; 9 | -------------------------------------------------------------------------------- /Dockerfile.dockerignore: -------------------------------------------------------------------------------- 1 | *.ext2 2 | *.tar.gz 3 | *.deb 4 | *.tar 5 | *.md 6 | .clang-format 7 | .github 8 | .gitignore 9 | .git 10 | fs 11 | package.json 12 | control 13 | Dockerfile 14 | -------------------------------------------------------------------------------- /sys-utils/libcmt/tools/prepare-ffi.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | sed \ 4 | -e '/\/\*/,/\*\//d' \ 5 | -e '/#if\s/,/#endif/d' \ 6 | -e '/#define/d' \ 7 | -e '/#endif/d' \ 8 | -e '/#ifndef/d' \ 9 | -e '/#include/d' \ 10 | -------------------------------------------------------------------------------- /postinst: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | # Check if the dapp user already exists, otherwise add it 4 | if ! getent passwd dapp > /dev/null; then 5 | useradd --create-home --user-group dapp && chage -d 0 dapp && cp -a /etc/shadow /etc/shadow- 6 | fi 7 | exit 0 8 | -------------------------------------------------------------------------------- /sys-utils/misc/Makefile: -------------------------------------------------------------------------------- 1 | PREFIX ?= /usr 2 | 3 | all: ; 4 | 5 | install: 6 | install -Dm755 flashdrive $(DESTDIR)$(PREFIX)/bin/ 7 | install -Dm755 readbe64 $(DESTDIR)$(PREFIX)/bin/ 8 | install -Dm755 writebe64 $(DESTDIR)$(PREFIX)/bin/ 9 | 10 | clean: ; 11 | -------------------------------------------------------------------------------- /control.in: -------------------------------------------------------------------------------- 1 | Package: machine-guest-tools 2 | Version: ARG_VERSION 3 | Section: utils 4 | Priority: optional 5 | Architecture: riscv64 6 | Maintainer: Cartesi Machine Reference Unit 7 | Depends: busybox-static 8 | Multi-Arch: same 9 | Description: Cartesi Machine guest tools 10 | -------------------------------------------------------------------------------- /sys-utils/libcmt/tools/libcmt.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@PREFIX@ 2 | exec_prefix=${prefix} 3 | includedir=${prefix}/include 4 | libdir=${exec_prefix}/lib 5 | 6 | Name: libcmt 7 | Description: The Cartesi Machine Tools library 8 | Version: 0.0.1 9 | Cflags: -I${includedir} 10 | Libs: -L${libdir} -lcmt 11 | -------------------------------------------------------------------------------- /sys-utils/xhalt/xhalt.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(int argc, char *argv[]) { 7 | const char *halt = argc > 1? argv[1] : "0"; 8 | syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, halt); 9 | } 10 | -------------------------------------------------------------------------------- /sys-utils/libcmt/doc/examples/abi_decode_000.c: -------------------------------------------------------------------------------- 1 | #include "libcmt/abi.h" 2 | #include "libcmt/buf.h" 3 | 4 | int decode_address(cmt_buf_t *tx, uint32_t expected_funsel, cmt_abi_address_t *address) { 5 | cmt_buf_t wr = *tx; 6 | return cmt_abi_check_funsel(&wr, expected_funsel) 7 | || cmt_abi_get_address(&wr, address); 8 | } 9 | -------------------------------------------------------------------------------- /sys-utils/libcmt/doc/examples/abi_encode_000.c: -------------------------------------------------------------------------------- 1 | #include "libcmt/abi.h" 2 | #include "libcmt/buf.h" 3 | 4 | int encode_address(cmt_buf_t *tx, uint32_t funsel, cmt_abi_address_t *address) { 5 | cmt_buf_t wr = *tx; 6 | /* static section */ 7 | return cmt_abi_put_funsel(&wr, funsel) 8 | || cmt_abi_put_address(&wr, address); 9 | } 10 | -------------------------------------------------------------------------------- /fs/third-party/repo-info/Dockerfile.local-dpkg: -------------------------------------------------------------------------------- 1 | # Modified from the original 2 | FROM ubuntu:24.04 3 | 4 | RUN set -eux; \ 5 | apt-get update; \ 6 | apt-get install -y --no-install-recommends \ 7 | ca-certificates \ 8 | gawk \ 9 | wget \ 10 | ; \ 11 | rm -rf /var/lib/apt/lists/* 12 | 13 | COPY gather-dpkg.sh /usr/local/bin/ 14 | 15 | CMD ["gather-dpkg.sh"] 16 | -------------------------------------------------------------------------------- /sys-utils/libcmt/doc/examples/abi_decode_001.c: -------------------------------------------------------------------------------- 1 | #include "libcmt/abi.h" 2 | #include "libcmt/buf.h" 3 | 4 | int decode(cmt_buf_t *rx, uint32_t expected_funsel, cmt_abi_address_t *address, cmt_abi_u256_t *value) { 5 | cmt_buf_t rd = *rx; 6 | return cmt_abi_check_funsel(&rd, expected_funsel) 7 | || cmt_abi_get_address(&rd, address) 8 | || cmt_abi_get_uint256(&rd, value) 9 | ; 10 | } 11 | 12 | -------------------------------------------------------------------------------- /sys-utils/libcmt/doc/examples/abi_encode_001.c: -------------------------------------------------------------------------------- 1 | #include "libcmt/abi.h" 2 | #include "libcmt/buf.h" 3 | 4 | int encode_bytes(cmt_buf_t *tx, uint32_t funsel, cmt_abi_bytes_t *payload) { 5 | cmt_buf_t wr = *tx; 6 | cmt_buf_t of; 7 | cmt_buf_t frame; 8 | 9 | // static section 10 | return cmt_abi_put_funsel(&wr, funsel) 11 | || cmt_abi_mark_frame(&wr, &frame) 12 | || cmt_abi_put_bytes_s(&wr, &of) 13 | // dynamic section 14 | || cmt_abi_put_bytes_d(&wr, &of, &frame, payload); 15 | } 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/update-dependencies.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Update Dependencies 3 | about: Template for updating dependencies 4 | title: '' 5 | labels: chore 6 | assignees: '' 7 | 8 | --- 9 | 10 | | WARNING: Please, read carefully before submitting an issue | 11 | |------------------------------------------------------------| 12 | 13 | ## Context 14 | 15 | Does the dependency have a bug fix? 16 | Does it provide additional features or optimizations? 17 | 18 | ## Subtasks 19 | 20 | - [ ] Verify that the new version is available on all supported platforms. 21 | - [ ] Update build scripts and Dockerfiles 22 | -------------------------------------------------------------------------------- /sys-utils/libcmt/doc/examples/abi_decode_002.c: -------------------------------------------------------------------------------- 1 | #include "libcmt/abi.h" 2 | #include "libcmt/buf.h" 3 | 4 | int decode(cmt_buf_t *rx, uint32_t expected_funsel, cmt_abi_address_t *address, cmt_abi_bytes_t *payload) { 5 | cmt_buf_t rd = *rx; 6 | cmt_buf_t frame; 7 | cmt_buf_t offset; 8 | 9 | /* static section */ 10 | return cmt_abi_check_funsel(&rd, expected_funsel) 11 | || cmt_abi_mark_frame(&rd, &frame) 12 | || cmt_abi_get_address(&rd, address) 13 | || cmt_abi_get_bytes_s(&rd, &offset) 14 | /* dynamic section */ 15 | || cmt_abi_get_bytes_d(&rd, &offset, &payload->length, &payload->data) 16 | ; 17 | } 18 | 19 | -------------------------------------------------------------------------------- /sys-utils/libcmt/.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: LLVM 2 | AccessModifierOffset: -4 3 | AlignAfterOpenBracket: DontAlign 4 | AlignOperands: DontAlign 5 | AllowAllArgumentsOnNextLine: false 6 | AllowAllConstructorInitializersOnNextLine: false 7 | AllowAllParametersOfDeclarationOnNextLine: false 8 | AllowShortFunctionsOnASingleLine: Empty 9 | AlwaysBreakTemplateDeclarations: Yes 10 | BreakInheritanceList: AfterColon 11 | BreakBeforeTernaryOperators: false 12 | BreakConstructorInitializers: AfterColon 13 | ColumnLimit: 120 14 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 15 | IndentCaseLabels: true 16 | IndentWidth: 4 17 | SpaceAfterCStyleCast: true 18 | Standard: Cpp03 19 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | Language: Cpp 2 | BasedOnStyle: LLVM 3 | AccessModifierOffset: -4 4 | AlignAfterOpenBracket: DontAlign 5 | AlignOperands: DontAlign 6 | AllowAllArgumentsOnNextLine: false 7 | AllowAllConstructorInitializersOnNextLine: false 8 | AllowAllParametersOfDeclarationOnNextLine: false 9 | AllowShortFunctionsOnASingleLine: Empty 10 | AlwaysBreakTemplateDeclarations: Yes 11 | BreakInheritanceList: AfterColon 12 | BreakBeforeTernaryOperators: false 13 | BreakConstructorInitializers: AfterColon 14 | ColumnLimit: 120 15 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 16 | IndentCaseLabels: true 17 | IndentWidth: 4 18 | SpaceAfterCStyleCast: true 19 | Standard: c++17 20 | -------------------------------------------------------------------------------- /sys-utils/libcmt/doc/examples/abi_encode_002.c: -------------------------------------------------------------------------------- 1 | #include "libcmt/abi.h" 2 | #include "libcmt/buf.h" 3 | 4 | int encode_bytes(cmt_buf_t *tx, uint32_t funsel, cmt_abi_bytes_t *payload0, cmt_abi_bytes_t *payload1) { 5 | cmt_buf_t wr = *tx; 6 | cmt_buf_t of[2]; 7 | cmt_buf_t frame; 8 | 9 | // static section 10 | return cmt_abi_put_funsel(&wr, funsel) 11 | || cmt_abi_mark_frame(&wr, &frame) 12 | || cmt_abi_put_bytes_s(&wr, &of[0]) 13 | || cmt_abi_put_bytes_s(&wr, &of[1]) 14 | // dynamic section 15 | || cmt_abi_put_bytes_d(&wr, &frame, &of[0], payload0) 16 | || cmt_abi_put_bytes_d(&wr, &frame, &of[1], payload1) 17 | ; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /sys-utils/libcmt/tests/progress.c: -------------------------------------------------------------------------------- 1 | #include "libcmt/rollup.h" 2 | #include 3 | #include 4 | #include 5 | 6 | void test_rollup_progress(void) { 7 | cmt_rollup_t rollup; 8 | 9 | assert(cmt_rollup_init(&rollup) == 0); 10 | assert(cmt_rollup_progress(&rollup, 0) == 0); 11 | assert(cmt_rollup_progress(&rollup, 10) == 0); 12 | assert(cmt_rollup_progress(&rollup, 100) == 0); 13 | assert(cmt_rollup_progress(&rollup, 1000) == 0); 14 | assert(cmt_rollup_progress(&rollup, UINT32_MAX) == 0); 15 | cmt_rollup_fini(&rollup); 16 | 17 | printf("%s passed\n", __FUNCTION__); 18 | } 19 | 20 | int main(void) { 21 | test_rollup_progress(); 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.ext2 2 | *.tar.gz 3 | *.bin 4 | *.tar 5 | *.deb 6 | 7 | package.json 8 | control 9 | 10 | sys-utils/hex/hex 11 | sys-utils/ioctl-echo-loop/ioctl-echo-loop 12 | sys-utils/rollup/rollup 13 | sys-utils/xhalt/xhalt 14 | sys-utils/yield/yield 15 | 16 | # Prerequisites 17 | *.d 18 | 19 | # Compiled Object files 20 | *.slo 21 | *.lo 22 | *.o 23 | *.obj 24 | 25 | # Precompiled Headers 26 | *.gch 27 | *.pch 28 | 29 | # Compiled Dynamic libraries 30 | *.so 31 | *.dylib 32 | *.dll 33 | 34 | # Fortran module files 35 | *.mod 36 | *.smod 37 | 38 | # Compiled Static libraries 39 | *.lai 40 | *.la 41 | *.a 42 | *.lib 43 | 44 | # Executables 45 | *.exe 46 | *.out 47 | *.app 48 | 49 | #Rust 50 | *target 51 | 52 | #VS Code 53 | *.idea 54 | -------------------------------------------------------------------------------- /fs/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:24.04 2 | ARG TOOLS_DEB=machine-guest-tools_riscv64.deb 3 | ADD ${TOOLS_DEB} /tmp/ 4 | RUN apt-get update && \ 5 | apt-get upgrade -y --no-install-recommends && \ 6 | DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ 7 | busybox-static \ 8 | coreutils \ 9 | bash \ 10 | psmisc \ 11 | bc \ 12 | curl \ 13 | device-tree-compiler \ 14 | jq \ 15 | lua5.4 \ 16 | lua-socket \ 17 | xxd \ 18 | file \ 19 | strace \ 20 | stress-ng \ 21 | libatomic1 \ 22 | /tmp/machine-guest-tools_riscv64.deb \ 23 | && \ 24 | rm -rf /var/lib/apt/lists/* /var/cache/* /tmp/${TOOLS_DEB} 25 | -------------------------------------------------------------------------------- /sys-utils/misc/readbe64: -------------------------------------------------------------------------------- 1 | #!/usr/bin/lua 2 | 3 | -- Copyright Cartesi and individual authors (see AUTHORS) 4 | -- SPDX-License-Identifier: Apache-2.0 5 | -- 6 | -- Licensed under the Apache License, Version 2.0 (the "License"); 7 | -- you may not use this file except in compliance with the License. 8 | -- You may obtain a copy of the License at 9 | -- 10 | -- http://www.apache.org/licenses/LICENSE-2.0 11 | -- 12 | -- Unless required by applicable law or agreed to in writing, software 13 | -- distributed under the License is distributed on an "AS IS" BASIS, 14 | -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | -- See the License for the specific language governing permissions and 16 | -- limitations under the License. 17 | -- 18 | 19 | print((string.unpack(">I8", io.read(8)))) 20 | -------------------------------------------------------------------------------- /sys-utils/misc/writebe64: -------------------------------------------------------------------------------- 1 | #!/usr/bin/lua 2 | 3 | -- Copyright Cartesi and individual authors (see AUTHORS) 4 | -- SPDX-License-Identifier: Apache-2.0 5 | -- 6 | -- Licensed under the Apache License, Version 2.0 (the "License"); 7 | -- you may not use this file except in compliance with the License. 8 | -- You may obtain a copy of the License at 9 | -- 10 | -- http://www.apache.org/licenses/LICENSE-2.0 11 | -- 12 | -- Unless required by applicable law or agreed to in writing, software 13 | -- distributed under the License is distributed on an "AS IS" BASIS, 14 | -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | -- See the License for the specific language governing permissions and 16 | -- limitations under the License. 17 | -- 18 | 19 | local arg = {...} 20 | io.write(string.pack(">I8z", arg[1], arg[2] or "")) 21 | -------------------------------------------------------------------------------- /rollup-http/rollup-http-server/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | pub mod config; 18 | pub mod dapp_process; 19 | pub mod http_service; 20 | pub mod rollup; 21 | -------------------------------------------------------------------------------- /rollup-http/rollup-http-client/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rollup-http-client" 3 | version = "0.1.0" 4 | edition = "2021" 5 | authors = ["Marko Atnasievski "] 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | serde = { version = "1.0", features = ["derive"] } 11 | serde_json = "1.0" 12 | env_logger = "0.9" 13 | log = "0.4" 14 | async-trait = "0.1" 15 | hyper = { version = "0.14", features = ["http1", "runtime", "client"] } 16 | getopts = "0.2" 17 | hex = "0.4" 18 | 19 | 20 | [profile.release] 21 | lto = true # Enable Link Time Optimization 22 | opt-level = "z" # Optimize for size. 23 | codegen-units = 1 # Reduce number of codegen units to increase optimizations, but slower build 24 | # panic = "abort" # Abort on panic 25 | -------------------------------------------------------------------------------- /rollup-http/Makefile: -------------------------------------------------------------------------------- 1 | PREFIX ?= /usr 2 | CARGO ?= cargo 3 | CARGO_FLAGS += --release 4 | ARCH = $(shell uname -m) 5 | 6 | ifneq ($(ARCH),riscv64) 7 | RUST_TARGET_DIR ?= target/riscv64gc-unknown-linux-gnu/release 8 | RUST_TARGET = --target riscv64gc-unknown-linux-gnu 9 | else 10 | RUST_TARGET_DIR ?= target/release 11 | endif 12 | 13 | all: 14 | cd rollup-http-server && $(CARGO) build $(CARGO_FLAGS) $(RUST_TARGET) 15 | cd echo-dapp && $(CARGO) build $(CARGO_FLAGS) $(RUST_TARGET) 16 | 17 | install: rollup-http-server echo-dapp 18 | install -Dm755 rollup-http-server/$(RUST_TARGET_DIR)/rollup-http-server $(DESTDIR)$(PREFIX)/bin/rollup-http-server 19 | install -Dm755 echo-dapp/$(RUST_TARGET_DIR)/echo-dapp $(DESTDIR)$(PREFIX)/bin/echo-dapp 20 | install -Dm755 rollup-init/rollup-init $(DESTDIR)$(PREFIX)/bin/rollup-init 21 | 22 | clean: 23 | rm -rf rollup-http-server/target echo-dapp/target 24 | 25 | .PHONY: all install clean 26 | -------------------------------------------------------------------------------- /sys-utils/misc/flashdrive: -------------------------------------------------------------------------------- 1 | #!/bin/busybox sh 2 | 3 | # Copyright Cartesi and individual authors (see AUTHORS) 4 | # SPDX-License-Identifier: Apache-2.0 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | for t in /dev/pmem*; do 20 | name=$(busybox cat /run/drive-label/$(busybox basename $t)) 21 | if [ "$name" = $1 ]; then 22 | echo $t 23 | exit 0 24 | fi 25 | done 26 | exit 1 27 | -------------------------------------------------------------------------------- /.github/workflows/commits.yml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json 2 | name: Conventional Commits Check 3 | on: [push] 4 | jobs: 5 | commit_messages: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - name: Install cocogitto tool 9 | run: | 10 | VERSION=5.6.0 11 | TAR=cocogitto-${VERSION}-x86_64-unknown-linux-musl.tar.gz 12 | curl --output-dir /tmp -OL https://github.com/cocogitto/cocogitto/releases/download/${VERSION}/${TAR} 13 | sudo tar -xzf /tmp/${TAR} -C /usr/local/bin 14 | 15 | - name: Checkout code 16 | uses: actions/checkout@v3 17 | with: 18 | fetch-depth: 0 19 | 20 | - name: Conventional commit check 21 | run: | 22 | # Assuming 'main' is the default base branch 23 | BASE_BRANCH=${{ github.base_ref || 'origin/main' }} 24 | cog check ${BASE_BRANCH}..HEAD 25 | -------------------------------------------------------------------------------- /rollup-http/rollup-init/rollup-init: -------------------------------------------------------------------------------- 1 | #!/bin/busybox sh 2 | 3 | # Copyright Cartesi and individual authors (see AUTHORS) 4 | # SPDX-License-Identifier: Apache-2.0 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | busybox sh -c "/usr/bin/rollup-http-server $*" 20 | MESSAGE="rollup-http-server exited with $? status" 21 | echo "$MESSAGE" 22 | echo "{\"payload\": \"$MESSAGE\"}" | rollup exception 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/technical-debt.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Technical Debt 3 | about: Template for proposing solutions to technical debts 4 | title: '' 5 | labels: refactor 6 | assignees: '' 7 | 8 | --- 9 | 10 | | WARNING: Please, read carefully before submitting an issue | 11 | |------------------------------------------------------------| 12 | 13 | ## Context 14 | 15 | What problem are you trying to solve? 16 | Why is this problem relevant? 17 | How does this problem affect the feature roadmap? 18 | Is it a blocker to implement a new future? 19 | What parts of the architecture and code are affected? 20 | 21 | ## Possible solutions 22 | 23 | What are the possible solutions? 24 | If there are multiple alternatives, what are the benefits and drawbacks of each one? 25 | 26 | ## Subtasks 27 | 28 | *This section is optional.* 29 | 30 | - [ ] What are the subtasks for completing this issue? 31 | 32 | ## Definition of Done 33 | 34 | *This section is optional.* 35 | 36 | - [ ] What are the final deliverables? 37 | -------------------------------------------------------------------------------- /copyright: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: machine-guest-tools 3 | Source: https://github.com/cartesi/machine-guest-tools 4 | 5 | Files: * 6 | Copyright: 2024 Individual contributors 7 | License: Apache-2.0 8 | 9 | License: Apache-2.0 10 | Licensed under the Apache License, Version 2.0 (the "License"); 11 | you may not use this file except in compliance with the License. 12 | You may obtain a copy of the License at 13 | . 14 | http://www.apache.org/licenses/LICENSE-2.0 15 | . 16 | Unless required by applicable law or agreed to in writing, software 17 | distributed under the License is distributed on an "AS IS" BASIS, 18 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | See the License for the specific language governing permissions and 20 | limitations under the License. 21 | . 22 | On Debian systems, the complete text of the Apache version 2.0 license 23 | can be found in "/usr/share/common-licenses/Apache-2.0". -------------------------------------------------------------------------------- /sys-utils/hex/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright Cartesi and individual authors (see AUTHORS) 2 | # SPDX-License-Identifier: Apache-2.0 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | PREFIX ?= /usr 18 | CXX := $(TOOLCHAIN_PREFIX)g++ 19 | CXXFLAGS += -Wall -Wextra -pedantic -O2 -std=c++20 20 | 21 | all: hex 22 | 23 | hex: hex.cpp 24 | $(CXX) $(CFLAGS) -o $@ $< $(LDFLAGS) 25 | 26 | install: hex 27 | install -Dm755 hex $(DESTDIR)$(PREFIX)/bin/hex 28 | 29 | clean: 30 | @rm -f hex 31 | -------------------------------------------------------------------------------- /sys-utils/xhalt/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright Cartesi and individual authors (see AUTHORS) 2 | # SPDX-License-Identifier: Apache-2.0 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | PREFIX ?= /usr 18 | CC := $(TOOLCHAIN_PREFIX)gcc 19 | CFLAGS += -Wall -Wextra -pedantic -O2 20 | 21 | all: xhalt 22 | 23 | xhalt: xhalt.c 24 | $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) 25 | 26 | install: xhalt 27 | install -Dm755 xhalt $(DESTDIR)$(PREFIX)/sbin/xhalt 28 | 29 | clean: 30 | @rm -f xhalt 31 | -------------------------------------------------------------------------------- /rollup-http/echo-dapp/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "echo-dapp" 3 | version = "0.1.0" 4 | edition = "2021" 5 | authors = ["Alex Mikhalevich ", "Marko Atnasievski "] 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | regex = "1.5.5" 11 | actix-web = "4.0.0-rc.2" 12 | serde = { version = "1.0", features = ["derive"] } 13 | serde_json = "1.0" 14 | env_logger = "0.9" 15 | log = "0.4" 16 | async-trait = "0.1" 17 | tokio = { version = "1.14", features = ["macros", "sync", "rt-multi-thread"] } 18 | hyper = { version = "0.14", features = ["http1", "runtime", "client"] } 19 | getopts = "0.2" 20 | hex = "0.4" 21 | rollup-http-client = { path = "../rollup-http-client"} 22 | 23 | 24 | [profile.release] 25 | lto = true # Enable Link Time Optimization 26 | opt-level = "z" # Optimize for size. 27 | codegen-units = 1 # Reduce number of codegen units to increase optimizations, but slower build 28 | # panic = "abort" # Abort on panic 29 | -------------------------------------------------------------------------------- /rollup-http/rollup-http-server/src/config.rs: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | #[derive(Debug, Clone, PartialEq, Eq)] 18 | pub struct Config { 19 | pub http_address: String, 20 | pub http_port: u16, 21 | } 22 | 23 | impl Config { 24 | pub fn new() -> Self { 25 | Self { 26 | http_address: String::from("127.0.0.1"), 27 | http_port: 5004, 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /sys-utils/yield/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright Cartesi and individual authors (see AUTHORS) 2 | # SPDX-License-Identifier: Apache-2.0 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | PREFIX ?= /usr 18 | CC := $(TOOLCHAIN_PREFIX)gcc 19 | CFLAGS += -Wall -Wextra -pedantic -O2 -I../libcmt/include 20 | LDFLAGS += -L../libcmt/build/riscv64 -l:libcmt.a 21 | 22 | all: yield 23 | 24 | yield: yield.c 25 | $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) 26 | 27 | install: yield 28 | install -Dm755 yield $(DESTDIR)$(PREFIX)/bin/yield 29 | 30 | clean: 31 | @rm -f yield 32 | -------------------------------------------------------------------------------- /sys-utils/rollup/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright Cartesi and individual authors (see AUTHORS) 2 | # SPDX-License-Identifier: Apache-2.0 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | PREFIX ?= /usr 18 | CXX := $(TOOLCHAIN_PREFIX)g++ 19 | CXXFLAGS += -Wall -Wextra -pedantic -O2 -std=c++20 -I../libcmt/include 20 | LDFLAGS += -L../libcmt/build/riscv64 -l:libcmt.a 21 | 22 | all: rollup 23 | 24 | rollup: rollup.cpp 25 | $(CXX) $(CXXFLAGS) -o $@ $< $(LDFLAGS) 26 | 27 | install: rollup 28 | install -Dm755 rollup $(DESTDIR)$(PREFIX)/bin/rollup 29 | 30 | clean: 31 | @rm -f rollup 32 | -------------------------------------------------------------------------------- /sys-utils/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright Cartesi and individual authors (see AUTHORS) 2 | # SPDX-License-Identifier: Apache-2.0 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | UTILITIES := hex xhalt yield rollup ioctl-echo-loop misc cartesi-init 18 | 19 | PREFIX ?= /usr 20 | DESTDIR ?= 21 | 22 | all: 23 | @$(MAKE) $(UTILITIES) 24 | 25 | $(UTILITIES): 26 | @$(MAKE) -C $@ 27 | 28 | install: 29 | @$(foreach utility,$(UTILITIES),$(MAKE) -C $(utility) install;) 30 | 31 | clean: 32 | @$(foreach utility,$(UTILITIES),$(MAKE) -C $(utility) clean;) 33 | 34 | .PHONY: all $(UTILITIES) install clean 35 | -------------------------------------------------------------------------------- /sys-utils/ioctl-echo-loop/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright Cartesi and individual authors (see AUTHORS) 2 | # SPDX-License-Identifier: Apache-2.0 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | PREFIX ?= /usr 18 | CC := $(TOOLCHAIN_PREFIX)gcc 19 | CFLAGS += -Wall -Wextra -pedantic -O2 -I../libcmt/include 20 | LDFLAGS += -L../libcmt/build/riscv64 -l:libcmt.a 21 | 22 | all: ioctl-echo-loop 23 | 24 | ioctl-echo-loop: ioctl-echo-loop.c 25 | $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) 26 | 27 | install: ioctl-echo-loop 28 | install -Dm755 ioctl-echo-loop $(DESTDIR)$(PREFIX)/bin/ioctl-echo-loop 29 | 30 | clean: 31 | @rm -f ioctl-echo-loop 32 | -------------------------------------------------------------------------------- /sys-utils/libcmt/include/libcmt/util.h: -------------------------------------------------------------------------------- 1 | #ifndef CMT_UTIL_H 2 | #define CMT_UTIL_H 3 | #include 4 | 5 | /** 6 | */ 7 | bool cmt_util_debug_enabled(void); 8 | 9 | /** Read whole file `name` contents into `data` and set `length`. 10 | * @param name[in] - file path 11 | * @param max[in] - size of `data` in bytes 12 | * @param data[out] - file contents 13 | * @param length[out] - actual size in `bytes` written to `data` 14 | * 15 | * @return 16 | * | | | 17 | * |-----|--------------------| 18 | * | 0 |success | 19 | * | < 0 |negative errno value| */ 20 | int cmt_util_read_whole_file(const char *name, size_t max, void *data, size_t *length); 21 | 22 | /** Write the contents of `data` into file `name`. 23 | * @param name[in] - file path 24 | * @param length[in] - size of `data` in bytes 25 | * @param data[out] - file contents 26 | * 27 | * @return 28 | * | | | 29 | * |-----|--------------------| 30 | * | 0 |success | 31 | * | < 0 |negative errno value| */ 32 | int cmt_util_write_whole_file(const char *name, size_t length, const void *data); 33 | 34 | #endif /* CMT_UTIL_H */ 35 | -------------------------------------------------------------------------------- /sys-utils/libcmt/tests/gio.c: -------------------------------------------------------------------------------- 1 | #include "data.h" 2 | #include "libcmt/rollup.h" 3 | #include "libcmt/util.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int main(void) { 11 | uint8_t buffer[1024]; 12 | size_t buffer_length = 0; 13 | cmt_rollup_t rollup; 14 | 15 | assert(cmt_util_write_whole_file("gio.bin", sizeof valid_gio_reply_0, valid_gio_reply_0) == 0); 16 | assert(setenv("CMT_INPUTS", "42:gio.bin", 1) == 0); 17 | assert(cmt_rollup_init(&rollup) == 0); 18 | 19 | char request[] = "gio-request-0"; 20 | char reply[] = "gio-reply-0"; 21 | 22 | cmt_gio_t req = { 23 | .domain = 0xFEFE, 24 | .id = request, 25 | .id_length = strlen(request), 26 | }; 27 | 28 | assert(cmt_gio_request(&rollup, &req) == 0); 29 | assert(cmt_util_read_whole_file("none.gio-0.bin", sizeof buffer, buffer, &buffer_length) == 0); 30 | assert(req.response_code == 42); 31 | assert(req.response_data_length == strlen(reply)); 32 | assert(memcmp(req.response_data, reply, req.response_data_length) == 0); 33 | 34 | cmt_rollup_fini(&rollup); 35 | printf("%s passed\n", __FUNCTION__); 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /sys-utils/libcmt/doc/examples/io.c: -------------------------------------------------------------------------------- 1 | #include "libcmt/io.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int exception(union cmt_io_driver *io) { 8 | /* init ------------------------------------------------------------- */ 9 | if (cmt_io_init(io)) { 10 | fprintf(stderr, "%s:%d failed to init\n", __FILE__, __LINE__); 11 | return EXIT_FAILURE; 12 | } 13 | 14 | cmt_buf_t tx = cmt_io_get_tx(io); 15 | 16 | /* prepare exception ------------------------------------------------ */ 17 | const char message[] = "exception contents\n"; 18 | size_t n = strlen(message); 19 | memcpy(tx.begin, message, n); 20 | 21 | /* exception -------------------------------------------------------- */ 22 | struct cmt_io_yield req[1] = {{ 23 | .dev = HTIF_DEVICE_YIELD, 24 | .cmd = HTIF_YIELD_CMD_MANUAL, 25 | .reason = HTIF_YIELD_MANUAL_REASON_TX_EXCEPTION, 26 | .data = n, 27 | }}; 28 | if (cmt_io_yield(io, req)) { 29 | fprintf(stderr, "%s:%d failed to yield\n", __FILE__, __LINE__); 30 | return -1; 31 | } 32 | 33 | /* fini ------------------------------------------------------------- */ 34 | cmt_io_fini(io); 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /sys-utils/libcmt/src/util.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | bool cmt_util_debug_enabled(void) { 8 | static bool checked = false; 9 | static bool enabled = false; 10 | 11 | if (!checked) { 12 | enabled = getenv("CMT_DEBUG") != NULL; 13 | checked = true; 14 | } 15 | 16 | return enabled; 17 | } 18 | 19 | int cmt_util_read_whole_file(const char *name, size_t max, void *data, size_t *length) { 20 | int rc = 0; 21 | 22 | FILE *file = fopen(name, "rb"); 23 | if (!file) { 24 | return -errno; 25 | } 26 | *length = fread(data, 1, max, file); 27 | int eof = (fseek(file, 0, SEEK_END) == 0) && (*length == (size_t) ftell(file)); 28 | if (!eof) { 29 | rc = -EIO; 30 | } 31 | if (fclose(file) != 0) { 32 | rc = -errno; 33 | } 34 | return rc; 35 | } 36 | 37 | int cmt_util_write_whole_file(const char *name, size_t length, const void *data) { 38 | int rc = 0; 39 | 40 | FILE *file = fopen(name, "wb"); 41 | if (!file) { 42 | return -errno; 43 | } 44 | 45 | if (fwrite(data, 1, length, file) != length) { 46 | rc = -EIO; 47 | } 48 | if (fclose(file) != 0) { 49 | rc = -errno; 50 | } 51 | return rc; 52 | } 53 | -------------------------------------------------------------------------------- /sys-utils/libcmt/tools/funsel.c: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include "libcmt/keccak.h" 17 | 18 | #include 19 | #include 20 | 21 | int main(int argc, char *argv[]) { 22 | if (argc < 2) { 23 | (void) fprintf(stderr, "usage: %s \"\"\n", argv[0]); 24 | exit(1); 25 | } 26 | 27 | // value encoded as big endian 28 | uint32_t funsel = cmt_keccak_funsel(argv[1]); 29 | printf("// %s\n" 30 | "#define FUNSEL CMT_ABI_FUNSEL(0x%02x, 0x%02x, 0x%02x, 0x%02x)\n", 31 | argv[1], ((uint8_t *) &funsel)[0], ((uint8_t *) &funsel)[1], ((uint8_t *) &funsel)[2], 32 | ((uint8_t *) &funsel)[3]); 33 | } 34 | -------------------------------------------------------------------------------- /rollup-http/rollup-http-server/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rollup-http-server" 3 | version = "0.2.0" 4 | edition = "2021" 5 | authors = ["Marko Atanasievski , Sofia Rodrigues , Alex Mikhalevich "] 6 | 7 | [lib] 8 | name = "rollup_http_server" 9 | path = "src/lib.rs" 10 | 11 | [[bin]] 12 | name = "rollup-http-server" 13 | path = "src/main.rs" 14 | 15 | [dependencies] 16 | getopts = "0.2" 17 | libc = "0.2" 18 | regex = "1.5.5" 19 | actix-web = "4.9.0" 20 | validator = { version = "0.18.1", features = ["derive"] } 21 | actix-server = "2.0" 22 | actix-web-validator = "6.0.0" 23 | lazy_static = "1.4.0" 24 | serde = { version = "1.0", features = ["derive"]} 25 | serde_json = "1.0" 26 | log = "0.4" 27 | tokio = { version = "1.14", features = ["macros", "time", "rt-multi-thread", "process"] } 28 | env_logger = "0.11.5" 29 | async-mutex = "1.4" 30 | hex = "0.4" 31 | rstest = "0.22" 32 | 33 | [build-dependencies] 34 | bindgen = "0.70.1" 35 | pkg-config = "0.3.30" 36 | 37 | [dev-dependencies] 38 | rollup-http-client = {path = "../rollup-http-client"} 39 | rand = "0.8.5" 40 | ethabi = "18.0.0" 41 | 42 | [profile.release] 43 | lto = true # Enable Link Time Optimization 44 | opt-level = "z" # Optimize for size. 45 | codegen-units = 1 # Reduce number of codegen units to increase optimizations, but slower build 46 | -------------------------------------------------------------------------------- /rollup-http/echo-dapp/src/config.rs: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | #[derive(Clone, Debug, PartialEq)] 18 | pub struct TestConfig { 19 | pub vouchers: u32, 20 | pub delegate_call_vouchers: u32, 21 | pub reports: u32, 22 | pub notices: u32, 23 | pub reject: i32, 24 | pub reject_inspects: bool, 25 | pub exception: i32, 26 | } 27 | 28 | /// Application configuration 29 | #[derive(Clone, Debug, PartialEq)] 30 | pub struct Config { 31 | pub rollup_http_server_address: String, 32 | pub test_config: TestConfig, 33 | } 34 | 35 | impl Config { 36 | pub fn new(test_config: TestConfig) -> Self { 37 | Self { 38 | rollup_http_server_address: String::from("127.0.0.1:5001"), 39 | test_config, 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /sys-utils/libcmt/doc/examples/abi_multi.c: -------------------------------------------------------------------------------- 1 | #include "libcmt/abi.h" 2 | #include "libcmt/buf.h" 3 | 4 | // Echo(bytes) 5 | #define ECHO CMT_ABI_FUNSEL(0x5f, 0x88, 0x6b, 0x86) 6 | 7 | static int encode_echo(cmt_buf_t *tx, uint32_t funsel, size_t length, void *data) { 8 | cmt_buf_t wr = *tx; 9 | cmt_buf_t of; 10 | void *params_base = wr.begin + 4; // after funsel 11 | 12 | // static section 13 | return cmt_abi_put_funsel(&wr, funsel) 14 | || cmt_abi_put_bytes_s(&wr, &of) 15 | // dynamic section 16 | || cmt_abi_put_bytes_d(&wr, &of, length, data, params_base) 17 | ; 18 | } 19 | 20 | static int decode_echo(cmt_buf_t *rx, uint32_t funsel, size_t *length, void **data) { 21 | cmt_buf_t rd = *rx; 22 | cmt_buf_t of; 23 | void *params_base = wr.begin + 4; // after funsel 24 | 25 | // static section 26 | return cmt_abi_get_funsel(&wr, funsel) 27 | || cmt_abi_get_bytes_s(&wr, &of) 28 | // dynamic section 29 | || cmt_abi_get_bytes_d(&wr, &of, length, data, params_base) 30 | ; 31 | } 32 | 33 | int f(cmt_buf_t *wr, cmt_buf_t *rd) 34 | { 35 | int rc; 36 | size_t length; 37 | void *data; 38 | 39 | if (cmt_buf_length(rd) < 4) 40 | return -ENOBUFS; 41 | switch (cmt_abi_peek_funsel(rd)) { 42 | case ECHO: 43 | rc = decode_echo(rd, ECHO, &length, &data); 44 | if (rc) return rc; 45 | 46 | rc = encode_echo(wr, ECHO, length, data); 47 | if (rc) return rc; 48 | 49 | break; 50 | } 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature Request 3 | about: Template for requesting new features 4 | title: '' 5 | labels: feature 6 | assignees: '' 7 | 8 | --- 9 | 10 | | WARNING: Please, read carefully before submitting an issue | 11 | |------------------------------------------------------------| 12 | 13 | Do not use issues to seek technical support. 14 | If you need support read the [documentation](https://docs.cartesi.io/) first. 15 | If you still have unanswered questions or need further discussion, join the [Cartesi Discord server](https://discord.gg/cartesi) and use the `#cartesi-machine` channel. 16 | 17 | Before submitting a new issue, please make sure that: 18 | - You are sure the issue manifests itself on the latest release (i.e., in the main branch); 19 | - You have verified that a similar issue has not already been reported; 20 | - You have verified, with your best effort, that your code or use case is not itself at fault. 21 | 22 | ## Context 23 | 24 | What problem are you trying to solve? 25 | Why is this feature relevant? 26 | 27 | (Please try to be clear and concise.) 28 | 29 | ## Possible solutions 30 | 31 | *This section is optional.* 32 | 33 | What are the possible solutions? 34 | If there are multiple alternatives, what are the benefits and drawbacks of each one? 35 | 36 | ## Subtasks 37 | 38 | *This section is optional.* 39 | 40 | - [ ] If there is a solution, what are the subtasks for completing this issue? 41 | 42 | ## Definition of Done 43 | 44 | *This section is optional.* 45 | 46 | - [ ] If there is a solution, what are the final deliverables? 47 | -------------------------------------------------------------------------------- /sys-utils/libcmt/.clang-tidy: -------------------------------------------------------------------------------- 1 | Checks: >- 2 | boost*, 3 | bugprone*, 4 | -bugprone-branch-clone, 5 | -bugprone-easily-swappable-parameters, 6 | cert*, 7 | clang-analyzer*, 8 | -clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling, 9 | cppcoreguidelines*, 10 | -cppcoreguidelines-avoid-magic-numbers, 11 | -cppcoreguidelines-non-private-member-variables-in-classes, 12 | -cppcoreguidelines-owning-memory, 13 | -cppcoreguidelines-pro-bounds*, 14 | -cppcoreguidelines-pro-type-vararg, 15 | -cppcoreguidelines-avoid-c-arrays, 16 | google-readability-*, 17 | misc*, 18 | -misc-include-cleaner, 19 | -misc-no-recursion, 20 | -misc-non-private-member-variables-in-classes, 21 | -misc-use-anonymous-namespace, 22 | modernize*, 23 | -modernize-redundant-void-arg, 24 | -modernize-use-default-member-init, 25 | -modernize-use-nodiscard, 26 | -modernize-use-trailing-return-type, 27 | -modernize-avoid-c-arrays, 28 | -modernize-use-auto, 29 | performance*, 30 | portability*, 31 | readability*, 32 | -readability-else-after-return, 33 | -readability-function-cognitive-complexity, 34 | -readability-implicit-bool-conversion, 35 | -readability-identifier-length, 36 | -readability-magic-numbers, 37 | -readability-named-parameter, 38 | -readability-redundant-member-init 39 | WarningsAsErrors: >- 40 | boost*, 41 | bugprone*, 42 | cert*, 43 | clang-analyzer*, 44 | cppcoreguidelines*, 45 | google*, 46 | misc*, 47 | modernize*, 48 | performance*, 49 | portability*, 50 | readability* 51 | CheckOptions: 52 | - key: performance-move-const-arg.CheckTriviallyCopyableMove 53 | value: 'false' 54 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | | WARNING: Please, read carefully before submitting a pull request | 2 | |------------------------------------------------------------------| 3 | 4 | Although this software is open source and we welcome contributions, 5 | we believe these contributions should be preceded by an open discussion. 6 | Open discussions tend to result in better solutions to any given problem, 7 | and help maintain and improve the quality of the software. 8 | If you would like to see a bug fixed or a new feature implemented, 9 | please open an issue for the discussion rather than directly opening 10 | a pull request. 11 | 12 | If you would like to contribute please read [CONTRIBUTING.md](../blob/main/CONTRIBUTING.md). 13 | 14 | When you finally create a pull request, please follow these guidelines: 15 | 16 | - Make sure the description clearly describes the problem, its solution, and references the associated issue; 17 | - Do not create large pull requests (involving many different changes) because these are difficult to review. Instead, break large changes into smaller ones and create independent pull requests for each one; 18 | - Use different pull requests for different issues. Each pull request should address a single issue; 19 | - When fixing a bug or adding a new feature, make sure to add tests that cover your changes. This will ensure the changes will continue to work in the future; 20 | - Verify that changes do not break the tests. You can check this with `make test`; 21 | - Follow the same coding style rules as the rest of the code base; 22 | - Pull requests for stylistic changes (or even simple typos or grammatical errors) may be rejected. Pull requests should always address worthy issues. 23 | -------------------------------------------------------------------------------- /rollup-http/rollup-http-server/README.md: -------------------------------------------------------------------------------- 1 | # DApp example echo application 2 | 3 | For Cartesi decentralized application to communicate with the client outside of emulator, `/dev/rollup` linux device is used. Rollup HTTP server translates requests read from Linux device to http `advance/inspect` requests and conveys them to the DApp using its HTTP api interface. DApp communicates results of its execution to the outside world by using `voucher/notice/report/finish` API of the Rollup HTTP Server. 4 | 5 | Rollup HTTP Server application implements interface defined [here](https://github.com/cartesi/rollups/blob/develop/openapi/rollup.yaml) and DApp application as http client pools Rollup HTTP Server for new requests, and pushes to it results of request processing voucher/notices/reports. 6 | 7 | 8 | ## Getting Started 9 | This project requires Rust. 10 | To install Rust follow the instructions [here](https://www.rust-lang.org/tools/install). 11 | 12 | ### Build 13 | This service is built within the docker build step when building all other tools: 14 | 15 | ```shell 16 | cd machine-guest-tools 17 | make 18 | ``` 19 | 20 | ### Build using the libcmt mock version (for development and tests) 21 | First build libcmt mock on host: 22 | 23 | ```shell 24 | cd machine-guest-tools/sys-utils/libcmt/ 25 | make host 26 | ``` 27 | 28 | Then build this project with: 29 | ```shell 30 | MOCK_BUILD=true cargo build 31 | ``` 32 | 33 | ### Run tests 34 | ```shell 35 | MOCK_BUILD=true cargo test -- --show-output --test-threads=1 36 | ``` 37 | 38 | 39 | ## License 40 | 41 | The http-dispatcher project and all contributions are licensed under 42 | [APACHE 2.0](https://www.apache.org/licenses/LICENSE-2.0). Please review our [LICENSE](LICENSE) file. 43 | -------------------------------------------------------------------------------- /sys-utils/libcmt/doc/examples/rollup.c: -------------------------------------------------------------------------------- 1 | #include "libcmt/rollup.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int main(void) { 8 | cmt_rollup_t rollup; 9 | if (cmt_rollup_init(&rollup)) 10 | return EXIT_FAILURE; 11 | 12 | for (;;) { 13 | int rc; 14 | cmt_rollup_finish_t finish = {.accept_previous_request = true}; 15 | cmt_rollup_advance_t advance; 16 | // cmt_rollup_inspect_t inspect; 17 | if (cmt_rollup_finish(&rollup, &finish) < 0) 18 | return EXIT_FAILURE; 19 | switch (finish.next_request_type) { 20 | case HTIF_YIELD_REASON_ADVANCE: 21 | rc = cmt_rollup_read_advance_state(&rollup, &advance); 22 | if (rc < 0) { 23 | fprintf(stderr, "%s:%d Error on advance %s (%d)\n", __FILE__, __LINE__, strerror(-rc), (-rc)); 24 | break; 25 | } 26 | 27 | rc = cmt_rollup_emit_voucher(&rollup, &advance.msg_sender, NULL, &advance.payload, NULL); 28 | if (rc < 0) { 29 | fprintf(stderr, "%s:%d Error on voucher %s (%d)\n", __FILE__, __LINE__, strerror(-rc), (-rc)); 30 | break; 31 | } 32 | 33 | rc = cmt_rollup_emit_notice(&rollup, &advance.payload, NULL); 34 | if (rc < 0) { 35 | fprintf(stderr, "%s:%d Error on voucher %s (%d)\n", __FILE__, __LINE__, strerror(-rc), (-rc)); 36 | break; 37 | } 38 | break; 39 | case HTIF_YIELD_REASON_INSPECT: 40 | break; 41 | } 42 | } 43 | 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Cartesi 2 | 3 | Thank you for your interest in Cartesi! We highly appreciate even the smallest of fixes or additions to our project. 4 | 5 | Make sure to review our [Contributing License Agreement](https://forms.gle/k3E9ZNkZY6Vy3mkK9), 6 | sign and send it to info@cartesi.io with the title of "CLA Signed" before taking part in the project. We are happy to automate 7 | this for you via DocuSign upon request in the Google Form as well. 8 | 9 | ## Basic Contributing Guidelines 10 | 11 | We use the same guidelines for contributing code to any of our repositories, any developers wanting to contribute to Cartesi 12 | must create pull requests. This process is described in the [GitHub documentation](https://help.github.com/en/articles/creating-a-pull-request). Each pull request should be started against the master branch 13 | in the respective Cartesi repository. After a pull request is submitted the Cartesi team will review the submission and 14 | give feedback via the comments section of the pull request. After the submission is reviewed and approved, it will be merged 15 | into the master branch of the source. 16 | 17 | Please note the below! We appreciate everyone following the guidelines. 18 | 19 | * No --force pushes or modifying the Git history in any way; 20 | * Use non-master branches, using a short meaningful description, with words separated by dash (e.g. 'fix-this-bug'); 21 | * All modifications must be made in a pull-request to solicit feedback from other contributors. 22 | 23 | ## Get in Touch 24 | 25 | When contributing in a deeper manner to this repository, please first discuss the change you wish to make via our 26 | [Discord channel here](https://discord.gg/Pt2NrnS), or contact us at info@cartesi.io email before working on the change. 27 | -------------------------------------------------------------------------------- /fs/third-party/repo-info/scan-local.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Modified from the original 3 | set -e 4 | 5 | trap 'echo >&2 Ctrl+C captured, exiting; exit 1' SIGINT 6 | 7 | image="$1"; shift 8 | platform="$1"; shift 9 | 10 | docker buildx build --platform $platform --load --pull -t repo-info:local-dpkg -f Dockerfile.local-dpkg . 1>&2 11 | 12 | name="repo-info-local-$$-$RANDOM" 13 | trap "docker rm -vf '$name-data' > /dev/null || :" EXIT 14 | 15 | docker create \ 16 | --platform $platform \ 17 | --name "$name-data" \ 18 | -v /etc \ 19 | -v /lib/apk \ 20 | -v /usr/lib/rpm \ 21 | -v /usr/share/apk \ 22 | -v /usr/share/doc \ 23 | -v /var/lib \ 24 | "$image" \ 25 | bogus > /dev/null 26 | 27 | echo '# `'"$image"'`' 28 | 29 | size="$( 30 | docker inspect -f '{{ .VirtualSize }}' "$image" | awk '{ 31 | oneKb = 1000; 32 | oneMb = 1000 * oneKb; 33 | oneGb = 1000 * oneMb; 34 | if ($1 >= oneGb) { 35 | printf "~ %.2f Gb", $1 / oneGb 36 | } else if ($1 >= oneMb) { 37 | printf "~ %.2f Mb", $1 / oneMb 38 | } else if ($1 >= oneKb) { 39 | printf "~ %.2f Kb", $1 / oneKb 40 | } else { 41 | printf "%d bytes", $1 42 | } 43 | }' 44 | )" 45 | 46 | docker inspect -f ' 47 | ## Docker Metadata 48 | 49 | - Image ID: `{{ .Id }}` 50 | - Created: `{{ .Created }}` 51 | - Virtual Size: '"$size"' 52 | (total size of all layers on-disk) 53 | - Arch: `{{ .Os }}`/`{{ .Architecture }}` 54 | {{ if .Config.Entrypoint }}- Entrypoint: `{{ json .Config.Entrypoint }}` 55 | {{ end }}{{ if .Config.Cmd }}- Command: `{{ json .Config.Cmd }}` 56 | {{ end }}- Environment:{{ range .Config.Env }}{{ "\n" }} - `{{ . }}`{{ end }}{{ if .Config.Labels }} 57 | - Labels:{{ range $k, $v := .Config.Labels }}{{ "\n" }} - `{{ $k }}={{ $v }}`{{ end }}{{ end }}' "$image" 58 | 59 | docker run --platform $platform --rm --volumes-from "$name-data" -v /etc/ssl repo-info:local-dpkg || : 60 | -------------------------------------------------------------------------------- /sys-utils/libcmt/tests/create-data.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | [ ! -d build/data/ ] && mkdir build/data/ 4 | 5 | echo "#ifndef DATA_H" 6 | echo "#define DATA_H" 7 | echo "#include " 8 | echo "uint8_t valid_advance_0[] = {" 9 | cast calldata "EvmAdvance(uint256,address,address,uint256,uint256,uint256,uint256,bytes)" \ 10 | 0x0000000000000000000000000000000000000001 \ 11 | 0x0000000000000000000000000000000000000002 \ 12 | 0x0000000000000000000000000000000000000003 \ 13 | 0x0000000000000000000000000000000000000004 \ 14 | 0x0000000000000000000000000000000000000005 \ 15 | 0x0000000000000000000000000000000000000006 \ 16 | 0x0000000000000000000000000000000000000007 \ 17 | 0x`echo -en "advance-0" | xxd -p -c0` | xxd -r -p | xxd -i 18 | echo "};" 19 | 20 | echo "uint8_t valid_inspect_0[] = {" 21 | echo -en "inspect-0" | xxd -i 22 | echo "};" 23 | 24 | echo "uint8_t valid_report_0[] = {" 25 | echo -en "report-0" | xxd -i 26 | echo "};" 27 | 28 | echo "uint8_t valid_exception_0[] = {" 29 | echo -en "exception-0" | xxd -i 30 | echo "};" 31 | 32 | echo "uint8_t valid_voucher_0[] = {" 33 | cast calldata "Voucher(address,uint256,bytes)" \ 34 | 0x0000000000000000000000000000000000000001 \ 35 | 0x00000000000000000000000000000000deadbeef \ 36 | 0x`echo -en "voucher-0" | xxd -p -c0` | xxd -r -p | xxd -i 37 | echo "};" 38 | 39 | echo "uint8_t valid_notice_0[] = {" 40 | cast calldata "Notice(bytes)" \ 41 | 0x`echo -en "notice-0" | xxd -p -c0` | xxd -r -p | xxd -i 42 | echo "};" 43 | 44 | echo "uint8_t valid_gio_reply_0[] = {" 45 | echo -en "gio-reply-0" | xxd -i 46 | echo "};" 47 | 48 | echo "uint8_t valid_delegate_call_voucher_0[] = {" 49 | cast calldata "DelegateCallVoucher(address,bytes)" \ 50 | 0x0000000000000000000000000000000000000001 \ 51 | 0x`echo -en "delegate-call-voucher-0" | xxd -p -c0` | xxd -r -p | xxd -i 52 | echo "};" 53 | 54 | 55 | echo "#endif /* DATA_H */" 56 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cartesi Machine Guest Tools 2 | 3 | The Cartesi Machine Guest Tools is a repository that contains a set of tools developed for the RISC-V Linux OS. It provides a RISC-V Debian package and a root filesystem for Ubuntu 24.04. 4 | 5 | ## Getting Started 6 | 7 | Users looking to create cartesi-machine applications can use the provided Debian package and root filesystem directly from one of the prepackaged releases, without needing to build this repository themselves. 8 | 9 | ### Requirements 10 | 11 | - Docker >= 18.x 12 | - GNU Make >= 3.81 13 | - xgenext2fs >= 1.5.6 14 | 15 | ### Docker buildx setup 16 | 17 | To set up riscv64 buildx, use the following command: 18 | 19 | ```bash 20 | $ make setup 21 | ``` 22 | 23 | ### Building (from riscv64 environment) 24 | 25 | Assuming you are inside a riscv64 environment, you can build tools and install in the system with: 26 | 27 | ```sh 28 | make 29 | make install PREFIX=/usr 30 | ``` 31 | 32 | ### Building (cross compiling) 33 | 34 | In case you need to patch and develop tools, you can cross compile using Docker with: 35 | 36 | ```sh 37 | make build 38 | ``` 39 | 40 | This creates the `machine-guest-tools_riscv64.tar.gz` archive and the `rootfs-tools.ext2` root filesystem artifacts. 41 | Both should only be use for testing and development purposes, not directly in dapps. 42 | 43 | #### Makefile targets 44 | 45 | Check all targets available with `make help`. 46 | 47 | ## Contributing 48 | 49 | Thank you for your interest in Cartesi! Head over to our [Contributing Guidelines](CONTRIBUTING.md) for instructions on how to sign our Contributors Agreement and get started with 50 | Cartesi! 51 | 52 | Please note we have a [Code of Conduct](CODE_OF_CONDUCT.md), please follow it in all your interactions with the project. 53 | 54 | ## License 55 | 56 | The machine-guest-tools repository and all contributions are licensed under 57 | [APACHE 2.0](https://www.apache.org/licenses/LICENSE-2.0). Please review our [LICENSE](LICENSE) file. 58 | -------------------------------------------------------------------------------- /sys-utils/libcmt/tests/io_exception.c: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include "buf.h" 17 | #include "io.h" 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | int main(void) { 24 | /* init ------------------------------------------------------------- */ 25 | union cmt_io_driver io[1]; 26 | if (cmt_io_init(io)) { 27 | (void) fprintf(stderr, "%s:%d failed to init\n", __FILE__, __LINE__); 28 | return EXIT_FAILURE; 29 | } 30 | 31 | cmt_buf_t tx = cmt_io_get_tx(io); 32 | 33 | /* prepare exception ------------------------------------------------ */ 34 | const char message[] = "exception contents\n"; 35 | size_t n = strlen(message); 36 | tx.begin = (uint8_t *) message; 37 | tx.end = tx.begin + n; 38 | 39 | /* exception -------------------------------------------------------- */ 40 | struct cmt_io_yield req[1] = {{ 41 | .dev = HTIF_DEVICE_YIELD, 42 | .cmd = HTIF_YIELD_CMD_MANUAL, 43 | .reason = HTIF_YIELD_MANUAL_REASON_TX_EXCEPTION, 44 | .data = n, 45 | }}; 46 | if (cmt_io_yield(io, req)) { 47 | (void) fprintf(stderr, "%s:%d failed to yield\n", __FILE__, __LINE__); 48 | return -1; 49 | } 50 | 51 | /* fini ------------------------------------------------------------- */ 52 | cmt_io_fini(io); 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /rollup-http/rollup-http-server/build.rs: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | use std::env; 18 | use std::path::PathBuf; 19 | 20 | extern crate pkg_config; 21 | 22 | fn main() { 23 | let mock_build = env::var("MOCK_BUILD").unwrap_or_else(|_| "false".to_string()) == "true"; 24 | 25 | let lib_dir = if mock_build { 26 | "../../sys-utils/libcmt/build/mock".into() 27 | } else { 28 | "../../sys-utils/libcmt/build/riscv64".to_string() 29 | }; 30 | 31 | let header_path = "../../sys-utils/libcmt/include/libcmt/rollup.h"; 32 | let include_path = "-I../../sys-utils/libcmt/include/libcmt"; 33 | 34 | // link the libcmt shared library 35 | println!("cargo:rustc-link-search=native={}", lib_dir); 36 | println!("cargo:rerun-if-changed={}/libcmt.a", lib_dir); 37 | println!("cargo:rustc-link-lib=static=cmt"); 38 | 39 | let bindings = bindgen::Builder::default() 40 | // the input header we would like to generate bindings for 41 | .header(header_path) 42 | .clang_arg(include_path) 43 | // invalidate the built crate whenever any of the included header files changed 44 | .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) 45 | .generate() 46 | .expect("Unable to generate bindings"); 47 | 48 | let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); 49 | bindings 50 | .write_to_file(out_path.join("bindings.rs")) 51 | .expect("Couldn't write bindings!"); 52 | } 53 | -------------------------------------------------------------------------------- /rollup-http/rollup-http-server/src/dapp_process.rs: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | use std::sync::Arc; 18 | 19 | use async_mutex::Mutex; 20 | use tokio::process::Command; 21 | 22 | use crate::rollup::{self, Exception, RollupFd}; 23 | 24 | /// Execute the dapp command and throw a rollup exception if it fails or exits 25 | pub async fn run(args: Vec, rollup_fd: Arc>) { 26 | log::info!("starting dapp: {}", args.join(" ")); 27 | let task = tokio::task::spawn_blocking(move || Command::new(&args[0]).args(&args[1..]).spawn()); 28 | let message = match task.await { 29 | Ok(command_result) => match command_result { 30 | Ok(mut child) => match child.wait().await { 31 | Ok(status) => format!("dapp exited with {}", status), 32 | Err(e) => format!("dapp wait failed with {}", e), 33 | }, 34 | Err(e) => format!("dapp failed to start with {}", e), 35 | }, 36 | Err(e) => format!("failed to spawn task with {}", e), 37 | }; 38 | log::warn!("throwing exception because {}", message); 39 | let exception = Exception { 40 | payload: String::from("0x") + &hex::encode(message), 41 | }; 42 | match rollup::rollup_throw_exception(&*rollup_fd.lock().await, &exception) { 43 | Ok(_) => { 44 | log::debug!("exception successfully thrown {:#?}", exception); 45 | } 46 | Err(e) => { 47 | log::error!("unable to throw exception, error details: '{}'", e); 48 | } 49 | }; 50 | } 51 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report 3 | about: Template for reporting bugs 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | | WARNING: Please, read carefully before submitting an issue | 11 | |------------------------------------------------------------| 12 | 13 | Do not use issues to seek technical support. 14 | If you need support read the [documentation](https://docs.cartesi.io/) first. 15 | If you still have unanswered questions or need further discussion, join the [Cartesi Discord server](https://discord.gg/cartesi) and use the `#cartesi-machine` channel. 16 | 17 | Before submitting a new issue, please make sure that: 18 | - You are sure the issue manifests itself on the latest release (i.e., in the main branch); 19 | - You have verified that a similar issue has not already been reported; 20 | - You have verified, with your best effort, that your code or use case is not itself at fault. 21 | 22 | ## Context 23 | 24 | What is the bug that you are experiencing? 25 | Why is this bug relevant? 26 | 27 | (Please try to be clear and concise.) 28 | 29 | ## Expected behavior 30 | 31 | What was expected? 32 | 33 | ## Actual behavior 34 | 35 | What happened instead? 36 | 37 | ## Steps to reproduce 38 | 39 | Please describe a minimal set of steps to reproduce the bug. 40 | Try to keep it as simple as possible, focusing exclusively on the bug. 41 | Your description should include the artifacts used and their versions. 42 | Provide the exact commands needed to reproduce the bug, if possible in the form of a script that can be run on other machines. 43 | 44 | ## Environment 45 | 46 | Please describe the environment where the bug happens. 47 | 48 | Include the following (when applicable and/or relevant): 49 | - Emulator version; 50 | - Host operating system (e.g. Ubuntu 22.04, MacOS 13, Cartesi Playground v0.6.0); 51 | - Host architecture (e.g. x86\_64, arm64); 52 | - Docker version (e.g. Docker Desktop 4.19.0); 53 | - Compiler version (e.g. GCC 12.3, Clang 15.0.7). 54 | 55 | ## Possible solutions 56 | 57 | *This section is optional.* 58 | 59 | Is there any workaround for the issue? (This may help others experiencing the same issue.) 60 | 61 | Can you offer any hint on how to solve the issue? 62 | What parts of the code will be affected? 63 | -------------------------------------------------------------------------------- /sys-utils/libcmt/tests/io.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | void invalid_parameters(void) { 10 | assert(cmt_io_init(NULL) == -EINVAL); 11 | cmt_io_fini(NULL); 12 | 13 | cmt_buf_t tx = cmt_io_get_tx(NULL); 14 | assert(tx.begin == NULL && tx.end == NULL); 15 | 16 | cmt_buf_t rx = cmt_io_get_rx(NULL); 17 | assert(rx.begin == NULL && rx.end == NULL); 18 | 19 | setenv("CMT_INPUTS", "invalid", 1); 20 | cmt_io_driver_t io[1]; 21 | assert(cmt_io_init(io) == 0); 22 | 23 | { // invalid cmd + reason 24 | cmt_io_yield_t rr[1] = {{ 25 | .cmd = HTIF_YIELD_CMD_AUTOMATIC, 26 | .reason = UINT16_MAX, 27 | }}; 28 | assert(cmt_io_yield(io, rr) == -EINVAL); 29 | } 30 | 31 | { // invalid cmd 32 | cmt_io_yield_t rr[1] = {{ 33 | .cmd = 0xff, 34 | .reason = 0, 35 | }}; 36 | assert(cmt_io_yield(io, rr) == -EINVAL); 37 | } 38 | 39 | { // invalid args 40 | cmt_io_yield_t rr[1] = {{ 41 | .reason = HTIF_YIELD_MANUAL_REASON_RX_ACCEPTED, 42 | .cmd = HTIF_YIELD_CMD_MANUAL, 43 | .data = 0, 44 | }}; 45 | assert(cmt_io_yield(io, NULL) == -EINVAL); 46 | assert(cmt_io_yield(NULL, rr) == -EINVAL); 47 | assert(cmt_io_yield(io, rr) == -ENODATA); 48 | } 49 | cmt_io_fini(io); 50 | } 51 | 52 | void file_too_large(void) { 53 | // create a 4MB file (any value larger than buffer works) 54 | char valid[] = "/tmp/tmp.XXXXXX"; 55 | assert(mkstemp(valid) > 0); 56 | assert(truncate(valid, 4 << 20) == 0); 57 | 58 | { // setup input 59 | char buf[64]; 60 | (void) snprintf(buf, sizeof buf, "0:%s", valid); 61 | setenv("CMT_DEBUG", "yes", 1); 62 | setenv("CMT_INPUTS", buf, 1); 63 | } 64 | 65 | cmt_io_driver_t io[1]; 66 | cmt_io_yield_t rr[1] = {{ 67 | .cmd = HTIF_YIELD_CMD_MANUAL, 68 | .reason = HTIF_YIELD_MANUAL_REASON_RX_ACCEPTED, 69 | }}; 70 | assert(cmt_io_init(io) == 0); 71 | assert(cmt_io_yield(io, rr) == -ENODATA); 72 | cmt_io_fini(NULL); 73 | 74 | (void) remove(valid); 75 | } 76 | 77 | int main(void) { 78 | invalid_parameters(); 79 | file_too_large(); 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /sys-utils/libcmt/tests/keccak.c: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include "libcmt/keccak.h" 17 | #include "libcmt/abi.h" 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | void test_cmt_keccak_init(void) { 24 | cmt_keccak_t state; 25 | cmt_keccak_init(&state); 26 | printf("Test cmt_keccak_init: Passed\n"); 27 | } 28 | 29 | void test_cmt_keccak_hash_operations(void) { 30 | const char *input = "The quick brown fox jumps over the lazy dog"; 31 | uint8_t result[CMT_KECCAK_LENGTH] = {0}; 32 | uint8_t expected[CMT_KECCAK_LENGTH] = {0x4d, 0x74, 0x1b, 0x6f, 0x1e, 0xb2, 0x9c, 0xb2, 0xa9, 0xb9, 0x91, 0x1c, 0x82, 33 | 0xf5, 0x6f, 0xa8, 0xd7, 0x3b, 0x04, 0x95, 0x9d, 0x3d, 0x9d, 0x22, 0x28, 0x95, 0xdf, 0x6c, 0x0b, 0x28, 0xaa, 34 | 0x15}; 35 | 36 | cmt_keccak_t state; 37 | cmt_keccak_init(&state); 38 | cmt_keccak_update(&state, strlen(input), input); 39 | cmt_keccak_final(&state, result); 40 | 41 | // Compare result with expected 42 | assert(memcmp(result, expected, CMT_KECCAK_LENGTH) == 0); 43 | printf("Test cmt_keccak_update and cmt_keccak_final: Passed\n"); 44 | 45 | cmt_keccak_data(strlen(input), input, result); 46 | 47 | // Compare result with expected 48 | assert(memcmp(result, expected, CMT_KECCAK_LENGTH) == 0); 49 | printf("Test cmt_keccak_data: Passed\n"); 50 | } 51 | 52 | void test_cmt_keccak_funsel(void) { 53 | const char s[] = "baz(uint32,bool)"; 54 | assert(cmt_keccak_funsel(s) == CMT_ABI_FUNSEL(0xcd, 0xcd, 0x77, 0xc0)); 55 | printf("Test cmt_keccak_funsel: Passed\n"); 56 | } 57 | 58 | int main(void) { 59 | test_cmt_keccak_init(); 60 | test_cmt_keccak_hash_operations(); 61 | test_cmt_keccak_funsel(); 62 | printf("All keccak tests passed\n"); 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /rollup-http/echo-dapp/README.md: -------------------------------------------------------------------------------- 1 | # Dapp example echo application 2 | 3 | This is an example of a decentralized application for the Cartesi emulator. It implements the interface defined [here](https://github.com/cartesi/rollups/blob/develop/openapi/dapp.yaml). 4 | Developers can study this codebase to familiarize themselves with how a rollup interaction loop works. 5 | It is also a good starting point for those who want to create their own rust Dapps. 6 | 7 | To communicate with the client outside of emulator, `/dev/rollup` linux device is used. Rollup HTTP server application translates requests read from Linux device to http `advance/inspect` requests and passes them to the DApp when Dapp sends finish request. DApp communicates the results of its execution to the outside world by using `voucher/notice/report/finish/exception` API of the Rollup HTTP server. 8 | 9 | ## Getting Started 10 | 11 | This project requires Rust. 12 | To install Rust follow the instructions [here](https://www.rust-lang.org/tools/install). 13 | 14 | 15 | ## Build for risc-v cpu 16 | 17 | ### Build 18 | This DApp is built during the docker build process: 19 | 20 | ```shell 21 | $ cd machine-guest-tools 22 | $ make 23 | ``` 24 | 25 | ## Execution 26 | 27 | Utility script `rollup-init` is used to start simultaneously DApp application and Rollup HTTP server (available in `linux/utils` folder of the root `machine-guest-tools` project). 28 | 29 | After build copy Dapp and http dispatcher application to the new directory. Create ext2 filesystem image from that directory. 30 | 31 | ```shell 32 | $ xgenext2fs -b 14k -d echo/ echo.ext2 33 | ``` 34 | 35 | Run application with `cartesi-machine` emulator: 36 | ```shell 37 | $ remote-cartesi-machine --server-address=127.0.0.1:10001 38 | ``` 39 | In other terminal send advance request: 40 | ```shell 41 | $ cartesi-machine --rollup --remote-address=127.0.0.1:10001 --checkin-address=127.0.0.1:10003 --flash-drive=label:hello,filename:echo.ext2 --rollup-advance-state=epoch_index:0,input_index_begin:0,input_index_end:1 --remote-shutdown -- PATH=/mnt/echo:$PATH /mnt/echo/rollup-init --rollup-http-server-verbose /mnt/echo/echo-dapp --vouchers=3 --notices=2 --reports=1 42 | ``` 43 | 44 | Inspect request: 45 | ```shell 46 | $ cartesi-machine --rollup --remote-address=127.0.0.1:10001 --checkin-address=127.0.0.1:10003 --flash-drive=label:hello,filename:echo.ext2 --rollup-inspect-state=query:testquery.bin --remote-shutdown -- PATH=/mnt/echo:$PATH /mnt/echo/rollup-init --rollup-http-server-verbose /mnt/echo/echo-dapp --reports=1 47 | ``` 48 | 49 | To generate test input and decode output check `rollup-memory-range.lua` script options from the [emulator](https://github.com/cartesi/machine-emulator) project. 50 | 51 | 52 | ## License 53 | 54 | The echo-dapp project and all contributions are licensed under 55 | [APACHE 2.0](https://www.apache.org/licenses/LICENSE-2.0). Please review our [LICENSE](LICENSE) file. 56 | 57 | -------------------------------------------------------------------------------- /sys-utils/cartesi-init/cartesi-init: -------------------------------------------------------------------------------- 1 | #!/bin/busybox sh 2 | 3 | # disable terminal translation from nl to cr nl 4 | busybox stty -onlcr 5 | 6 | # mount 7 | [ ! -c /dev/zero ] && busybox mkdir -p /dev && busybox mount -o dev -t devtmpfs devtmpfs /dev 8 | busybox mkdir -p /proc /dev/pts /dev/shm /sys /tmp /run 9 | busybox mount -o nosuid,nodev,noexec -t proc proc /proc 10 | busybox mount -o nosuid,noexec,mode=620,gid=5 -t devpts devpts /dev/pts 11 | busybox mount -o nosuid,nodev,mode=1777 -t tmpfs tmpfs /dev/shm 12 | busybox mount -o nosuid,nodev,noexec -t sysfs sys /sys 13 | busybox mount -o nosuid,nodev,mode=1777 -t tmpfs tmpfs /tmp 14 | busybox mount -o nosuid,nodev,mode=0755 -t tmpfs tmpfs /run 15 | 16 | # system config 17 | [ -f /etc/sysctl.conf ] && busybox sysctl -pq 18 | 19 | # net 20 | [ -f /etc/hostname ] && busybox hostname -F /etc/hostname 21 | [ -z "$noloopback" ] && busybox ifconfig lo up 22 | 23 | # source environment 24 | [ -f /etc/environment ] && . /etc/environment 25 | export PATH 26 | 27 | # execute scripts in cartesi-init.d 28 | [ -d /etc/cartesi-init.d ] && for f in /etc/cartesi-init.d/*; do [ -x $f ] && . $f; done 29 | 30 | # execute init from device tree when available 31 | [ -f /proc/device-tree/cartesi-machine/init ] && . /proc/device-tree/cartesi-machine/init 32 | 33 | # use entrypoint from device tree when available, otherwise from command line 34 | if [ -s /proc/device-tree/cartesi-machine/entrypoint ]; then 35 | ENTRYPOINT=". /proc/device-tree/cartesi-machine/entrypoint" 36 | elif [ -n "$*" ]; then 37 | ENTRYPOINT="$*" 38 | fi 39 | 40 | # is entrypoint not empty? 41 | if [ -n "$ENTRYPOINT" ]; then 42 | USER=${USER:-dapp} 43 | HOME=$(eval echo ~$USER) 44 | WORKDIR=${WORKDIR:-"$HOME"} 45 | 46 | # give user group access to cmio device 47 | [ -c /dev/cmio ] && \ 48 | busybox chown :$(busybox id -g $USER) /dev/cmio && \ 49 | busybox chmod g+rw /dev/cmio 50 | 51 | # execute entrypoint 52 | (cd $WORKDIR && 53 | USER=$USER LOGNAME=$USER HOME="$HOME" \ 54 | busybox setsid -c \ 55 | busybox su -p $USER -c "$ENTRYPOINT") 56 | else 57 | echo "Nothing to do." 58 | fi 59 | RC=$? 60 | 61 | # shutdown 62 | busybox mount -o ro,remount / 63 | busybox umount -af 64 | if [ $RC != 0 ] && [ -x /usr/sbin/xhalt ]; then 65 | /usr/sbin/xhalt "$RC" 66 | fi 67 | busybox poweroff -f 68 | 69 | # Copyright Cartesi and individual authors (see AUTHORS) 70 | # SPDX-License-Identifier: Apache-2.0 71 | # 72 | # Licensed under the Apache License, Version 2.0 (the "License"); 73 | # you may not use this file except in compliance with the License. 74 | # You may obtain a copy of the License at 75 | # 76 | # http://www.apache.org/licenses/LICENSE-2.0 77 | # 78 | # Unless required by applicable law or agreed to in writing, software 79 | # distributed under the License is distributed on an "AS IS" BASIS, 80 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 81 | # See the License for the specific language governing permissions and 82 | # limitations under the License. 83 | # 84 | -------------------------------------------------------------------------------- /sys-utils/libcmt/include/libcmt/buf.h: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | /** @file 17 | * @defgroup libcmt_buf buf 18 | * slice of contiguous memory 19 | * 20 | * @ingroup libcmt 21 | * @{ */ 22 | #ifndef CMT_BUF_H 23 | #define CMT_BUF_H 24 | #include 25 | #include 26 | #include 27 | 28 | /** A slice of contiguous memory from @b begin to @b end, as an open range. 29 | * Size can be taken with: `end - begin`. 30 | * 31 | * `begin == end` indicate an empty buffer */ 32 | typedef struct { 33 | uint8_t *begin; /**< begin of memory region */ 34 | uint8_t *end; /**< end of memory region */ 35 | } cmt_buf_t; 36 | 37 | /** Initialize @p me buffer backed by @p data, @p length bytes in size 38 | * 39 | * @param [out] me a uninitialized instance 40 | * @param [in] length size in bytes of @b data 41 | * @param [in] data the backing memory to be used. 42 | * 43 | * @note @p data memory must outlive @p me. 44 | * user must copy the contents otherwise */ 45 | void cmt_buf_init(cmt_buf_t *me, size_t length, void *data); 46 | 47 | /** Split a buffer in two, @b lhs with @b lhs_length bytes and @b rhs with the rest 48 | * 49 | * @param [in,out] me initialized buffer 50 | * @param [in] lhs_length bytes in @b lhs 51 | * @param [out] lhs left hand side 52 | * @param [out] rhs right hand side 53 | * 54 | * @return 55 | * - 0 success 56 | * - negative value on error. -ENOBUFS when length(me) < lhs_length. */ 57 | int cmt_buf_split(const cmt_buf_t *me, size_t lhs_length, cmt_buf_t *lhs, cmt_buf_t *rhs); 58 | 59 | /** Length in bytes of @p me 60 | * 61 | * @param [in] me initialized buffer 62 | * 63 | * @return 64 | * - size in bytes */ 65 | size_t cmt_buf_length(const cmt_buf_t *me); 66 | 67 | /** Print the contents of @b me buffer to stdout 68 | * 69 | * @param [in] begin start of memory region 70 | * @param [in] end end of memory region 71 | * @param [in] bytes_per_line bytes per line (must be a power of 2). */ 72 | void cmt_buf_xxd(void *begin, void *end, int bytes_per_line); 73 | 74 | /** Take the substring @p x from @p xs start to the first @p , (comma). 75 | * @param [out] x substring 76 | * @param [in,out] xs string (iterator) 77 | * 78 | * @note @p x points inside @p xs, make a copy if it outlives @p xs. */ 79 | bool cmt_buf_split_by_comma(cmt_buf_t *x, cmt_buf_t *xs); 80 | 81 | #endif /* CMT_BUF_H */ 82 | /** @} */ 83 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Copyright Cartesi and individual authors (see AUTHORS) 2 | # SPDX-License-Identifier: Apache-2.0 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | FROM ubuntu:24.04 AS tools-env 18 | 19 | # Install dependencies 20 | ARG LINUX_HEADERS_URLPATH= 21 | ARG LINUX_HEADERS_SHA256= 22 | ADD ${LINUX_HEADERS_URLPATH} /tmp/linux-libc-dev-riscv64-cross.deb 23 | RUN <, 57 | pub payload: String, 58 | } 59 | 60 | #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] 61 | pub struct DelegateCallVoucher { 62 | pub destination: String, 63 | pub payload: String, 64 | } 65 | 66 | #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] 67 | pub struct Report { 68 | pub payload: String, 69 | } 70 | 71 | #[derive(Debug, Clone, Serialize, Deserialize)] 72 | pub struct IndexResponse { 73 | index: u64, 74 | } 75 | 76 | #[derive(Debug, Clone, Serialize, Deserialize)] 77 | pub struct GIORequest { 78 | pub domain: u16, 79 | pub id: String, 80 | } 81 | 82 | #[derive(Debug, Clone, Serialize, Deserialize)] 83 | pub struct GIOResponse { 84 | pub response_code: u16, 85 | pub response: String, 86 | } 87 | 88 | #[derive(Debug, Clone, Serialize, Deserialize)] 89 | pub struct Exception { 90 | pub payload: String, 91 | } 92 | 93 | #[derive(Debug, Clone, Serialize, Deserialize)] 94 | pub enum RollupRequest { 95 | Inspect(InspectRequest), 96 | Advance(AdvanceRequest), 97 | } 98 | 99 | pub enum RollupResponse { 100 | Finish(bool), 101 | } 102 | 103 | impl Error for RollupRequestError {} 104 | 105 | impl fmt::Display for RollupRequestError { 106 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 107 | write!(f, "failed to execute rollup request ({})", self.cause) 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /sys-utils/libcmt/src/buf.c: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include "libcmt/buf.h" 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | static inline int is_pow2(int l) { 23 | return !(l & (l - 1)); 24 | } 25 | 26 | void cmt_buf_init(cmt_buf_t *me, size_t length, void *data) { 27 | if (!me) { 28 | return; 29 | } 30 | me->begin = (uint8_t *) data; 31 | me->end = (uint8_t *) data + length; 32 | } 33 | 34 | int cmt_buf_split(const cmt_buf_t *me, size_t lhs_length, cmt_buf_t *lhs, cmt_buf_t *rhs) { 35 | if (!me) { 36 | return -EINVAL; 37 | } 38 | if (!lhs) { 39 | return -EINVAL; 40 | } 41 | if (!rhs) { 42 | return -EINVAL; 43 | } 44 | 45 | uint8_t *begin = me->begin; 46 | uint8_t *split = me->begin + lhs_length; 47 | uint8_t *end = me->end; 48 | 49 | if (split < begin || end < split) { 50 | return -ENOBUFS; 51 | } 52 | 53 | lhs->begin = begin; 54 | lhs->end = split; 55 | rhs->begin = split; 56 | rhs->end = end; 57 | 58 | return 0; 59 | } 60 | 61 | static int comma(const uint8_t *s, const uint8_t *end) { 62 | return s < end && *s == ','; 63 | } 64 | 65 | static bool cmt_buf_split_by(cmt_buf_t *x, cmt_buf_t *xs, int (*nxt)(const uint8_t *s, const uint8_t *end)) { 66 | if (xs->begin == xs->end) { 67 | return false; 68 | } 69 | x->begin = xs->begin; 70 | for (; *xs->begin && xs->begin < xs->end && !nxt(xs->begin, xs->end); ++xs->begin) { 71 | ; 72 | } 73 | x->end = xs->begin; 74 | xs->begin = xs->begin + nxt(xs->begin, xs->end); 75 | return *x->begin; 76 | } 77 | 78 | bool cmt_buf_split_by_comma(cmt_buf_t *x, cmt_buf_t *xs) { 79 | return cmt_buf_split_by(x, xs, comma); 80 | } 81 | 82 | size_t cmt_buf_length(const cmt_buf_t *me) { 83 | if (!me) { 84 | return 0; 85 | } 86 | return me->end - me->begin; 87 | } 88 | 89 | static void xxd(const uint8_t *p, const uint8_t *q, size_t mask) { 90 | if (q < p) { 91 | return; 92 | } 93 | 94 | for (size_t i = 0U, n = q - p; i < n; ++i) { 95 | bool is_line_start = (i & mask) == 0; 96 | bool is_line_end = (i & mask) == mask || (i + 1 == n); 97 | char separator = is_line_end ? '\n' : ' '; 98 | 99 | if (is_line_start) { 100 | printf("%p %4zu: ", (void *) (p + i), i); 101 | } 102 | printf("%02x%c", p[i], separator); 103 | } 104 | } 105 | 106 | void cmt_buf_xxd(void *begin, void *end, int bytes_per_line) { 107 | if (!begin) { 108 | return; 109 | } 110 | if (!end) { 111 | return; 112 | } 113 | if (end <= begin) { 114 | return; 115 | } 116 | if (!is_pow2(bytes_per_line)) { 117 | return; 118 | } 119 | 120 | xxd(begin, end, bytes_per_line - 1); 121 | } 122 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at info@cartesi.io. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /sys-utils/libcmt/tests/buf.c: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include "libcmt/buf.h" 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | static void passing_null(void) { 23 | uint8_t _[8]; 24 | 25 | // just test if it crashes 26 | cmt_buf_init(NULL, sizeof _, _); 27 | assert(cmt_buf_length(NULL) == 0); 28 | } 29 | 30 | static void split_in_bounds_must_succeed(void) { 31 | uint8_t _[8]; 32 | cmt_buf_t b; 33 | cmt_buf_init(&b, sizeof _, _); 34 | assert(cmt_buf_length(&b) == 8); 35 | 36 | { // everything to lhs 37 | cmt_buf_t lhs; 38 | cmt_buf_t rhs; 39 | assert(cmt_buf_split(&b, 8, &lhs, &rhs) == 0); 40 | assert(cmt_buf_length(&lhs) == 8); 41 | assert(cmt_buf_length(&rhs) == 0); 42 | } 43 | 44 | { // everything to rhs 45 | cmt_buf_t lhs; 46 | cmt_buf_t rhs; 47 | assert(cmt_buf_split(&b, 0, &lhs, &rhs) == 0); 48 | assert(cmt_buf_length(&lhs) == 0); 49 | assert(cmt_buf_length(&rhs) == 8); 50 | } 51 | 52 | { // handle alias (lhs) 53 | cmt_buf_t tmp = b; 54 | cmt_buf_t rhs; 55 | assert(cmt_buf_split(&tmp, 8, &tmp, &rhs) == 0); 56 | assert(cmt_buf_length(&tmp) == 8); 57 | assert(cmt_buf_length(&rhs) == 0); 58 | 59 | assert(tmp.begin == b.begin); 60 | } 61 | 62 | { // handle alias (rhs) 63 | cmt_buf_t tmp = b; 64 | cmt_buf_t lhs; 65 | assert(cmt_buf_split(&tmp, 8, &lhs, &tmp) == 0); 66 | assert(cmt_buf_length(&lhs) == 8); 67 | assert(cmt_buf_length(&tmp) == 0); 68 | 69 | assert(tmp.begin == b.end); 70 | } 71 | printf("%s passed\n", __FUNCTION__); 72 | } 73 | 74 | static void split_out_of_bounds_must_fail(void) { 75 | uint8_t _[8]; 76 | cmt_buf_t b; 77 | cmt_buf_t lhs; 78 | cmt_buf_t rhs; 79 | cmt_buf_init(&b, sizeof _, _); 80 | 81 | assert(cmt_buf_split(&b, 9, &lhs, &rhs) == -ENOBUFS); 82 | assert(cmt_buf_split(&b, SIZE_MAX, &lhs, &rhs) == -ENOBUFS); 83 | printf("%s passed\n", __FUNCTION__); 84 | } 85 | 86 | static void split_invalid_parameters(void) { 87 | uint8_t _[8]; 88 | cmt_buf_t b; 89 | cmt_buf_t lhs; 90 | cmt_buf_t rhs; 91 | cmt_buf_init(&b, sizeof _, _); 92 | 93 | assert(cmt_buf_split(NULL, 8, &lhs, &rhs) == -EINVAL); 94 | assert(cmt_buf_split(&b, 8, NULL, &rhs) == -EINVAL); 95 | assert(cmt_buf_split(&b, 8, &lhs, NULL) == -EINVAL); 96 | } 97 | 98 | static void split_by_comma_until_the_end(void) { 99 | uint8_t _[] = "a,b,c"; 100 | cmt_buf_t x; 101 | cmt_buf_t xs; 102 | 103 | cmt_buf_init(&x, sizeof _ - 1, _); 104 | cmt_buf_init(&xs, sizeof _ - 1, _); 105 | assert(cmt_buf_split_by_comma(&x, &xs) == true); 106 | assert(strncmp((char *) x.begin, "a", 1UL) == 0); 107 | assert(cmt_buf_split_by_comma(&x, &xs) == true); 108 | assert(strncmp((char *) x.begin, "b", 1UL) == 0); 109 | assert(cmt_buf_split_by_comma(&x, &xs) == true); 110 | assert(strncmp((char *) x.begin, "c", 1UL) == 0); 111 | assert(cmt_buf_split_by_comma(&x, &xs) == false); 112 | } 113 | 114 | static void xxd(void) { 115 | uint8_t _[] = ""; 116 | cmt_buf_xxd(_, _ + sizeof _, 0); 117 | cmt_buf_xxd(_, _ + sizeof _, 1); 118 | cmt_buf_xxd(_, _ + sizeof _, 3); 119 | cmt_buf_xxd(NULL, _ + sizeof _, 1); 120 | cmt_buf_xxd(_, NULL, 1); 121 | cmt_buf_xxd(_, _, 1); 122 | } 123 | 124 | int main(void) { 125 | passing_null(); 126 | split_in_bounds_must_succeed(); 127 | split_out_of_bounds_must_fail(); 128 | split_invalid_parameters(); 129 | split_by_comma_until_the_end(); 130 | xxd(); 131 | return 0; 132 | } 133 | -------------------------------------------------------------------------------- /sys-utils/libcmt/include/libcmt/keccak.h: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | /** @file 17 | * @defgroup libcmt_keccak keccak 18 | * Keccak 256 digest 19 | * 20 | * Data can be inserted in pieces: 21 | * @code 22 | * ... 23 | * uint8_t h[CMT_KECCAK_LENGTH]; 24 | * cmt_keccak_t st[1]; 25 | * 26 | * cmt_keccak_init(st); 27 | * cmt_keccak_update(st, 1, "h"); 28 | * cmt_keccak_update(st, 1, "e"); 29 | * cmt_keccak_update(st, 1, "l"); 30 | * cmt_keccak_update(st, 1, "l"); 31 | * cmt_keccak_update(st, 1, "o"); 32 | * cmt_keccak_final(st, h); 33 | * ... 34 | * @endcode 35 | * 36 | * all at once: 37 | * @code 38 | * ... 39 | * const char data[] = "hello"; 40 | * uint8_t h[CMT_KECCAK_LENGTH]; 41 | * cmt_keccak_data(h, sizeof(data)-1, data); 42 | * ... 43 | * @endcode 44 | * 45 | * or with a specialized call to generate @ref funsel data: 46 | * @code 47 | * ... 48 | * uint32_t funsel = cmt_keccak_funsel("FunctionCall(address,bytes)"); 49 | * ... 50 | * @endcode 51 | * 52 | * Code based on https://github.com/mjosaarinen/tiny_sha3 with the sha3 to 53 | * keccak change as indicated by this comment: 54 | * https://github.com/mjosaarinen/tiny_sha3#updated-07-aug-15 55 | * 56 | * @ingroup libcmtcmt 57 | * @{ */ 58 | #ifndef CMT_KECCAK_H 59 | #define CMT_KECCAK_H 60 | #include 61 | #include 62 | 63 | enum { 64 | CMT_KECCAK_LENGTH = 32, /**< Bytes in the hash digest */ 65 | }; 66 | 67 | /** Opaque internal keccak state */ 68 | typedef union cmt_keccak_state { 69 | uint8_t b[200]; 70 | uint64_t q[25]; 71 | } cmt_keccak_state_t; 72 | 73 | /** Opaque Keccak state, used to do hash computations, initialize with: 74 | * - @ref cmt_keccak_init 75 | * - @ref CMT_KECCAK_INIT 76 | * - @ref CMT_KECCAK_DECL */ 77 | typedef struct cmt_keccak { 78 | cmt_keccak_state_t st; 79 | int pt, rsiz; 80 | } cmt_keccak_t; 81 | 82 | /** Initialize a @ref cmt_keccak_t hasher state. 83 | * 84 | * @param [out] state uninitialized @ref cmt_keccak_t */ 85 | void cmt_keccak_init(cmt_keccak_t *state); 86 | 87 | /** Hash @b n bytes of @b data 88 | * 89 | * @param [in,out] state initialize the hasher state 90 | * @param [in] length bytes in @b data to process 91 | * @param [in] data data to hash */ 92 | void cmt_keccak_update(cmt_keccak_t *state, size_t n, const void *data); 93 | 94 | /** Finalize the hash calculation from @b state and store it in @b md 95 | * 96 | * @param [in] state initialize the hasher state (with all data already added to it) 97 | * @param [out] md 32bytes to store the computed hash */ 98 | void cmt_keccak_final(cmt_keccak_t *state, void *md); 99 | 100 | /** Hash all @b n bytes of @b data at once 101 | * 102 | * @param [in] length bytes in @b data to process 103 | * @param [in] data data to hash 104 | * @param [out] md 32bytes to store the computed hash 105 | * @return pointer to @b md 106 | * 107 | * Equivalent to: 108 | * @code 109 | * cmt_keccak_t st = CMT_KECCAK_INIT(&st); 110 | * cmt_keccak_update(&st, n, data); 111 | * cmt_keccak_final(&st, md); 112 | * return md; 113 | * @endcode */ 114 | uint8_t *cmt_keccak_data(size_t length, const void *data, uint8_t md[CMT_KECCAK_LENGTH]); 115 | 116 | /** Compute the function selector from the solidity declaration @p decl 117 | * 118 | * @param [in] decl solidity call declaration, without variable names 119 | * @param [out] funsel function selector as described by @ref funsel 120 | * @return A @p funsel value as if defined by @ref CMT_ABI_FUNSEL 121 | * 122 | * Example usage: 123 | * @code 124 | * ... 125 | * uint32_t funsel = cmt_keccak_funsel("FunctionCall(address,bytes)"); 126 | * ... 127 | * @endcode 128 | */ 129 | uint32_t cmt_keccak_funsel(const char *decl); 130 | #endif /* CMT_KECCAK_H */ 131 | /** $@} */ 132 | -------------------------------------------------------------------------------- /sys-utils/libcmt/include/libcmt/merkle.h: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | /** @file 17 | * @defgroup libcmt_merkle merkle 18 | * merkle tree of keccak256 hashes 19 | * 20 | * @ingroup libcmt 21 | * @{ */ 22 | #ifndef CMT_MERKLE_H 23 | #define CMT_MERKLE_H 24 | #include "keccak.h" 25 | 26 | enum { 27 | CMT_MERKLE_TREE_HEIGHT = 63, /**< merkle tree height */ 28 | }; 29 | 30 | /** Opaque Merkle tree state. 31 | * initialize with: @ref cmt_merkle_init */ 32 | typedef struct { 33 | uint64_t leaf_count; /**< number of leaves in tree */ 34 | uint8_t state[CMT_MERKLE_TREE_HEIGHT][CMT_KECCAK_LENGTH]; /**< hashes of complete subtrees */ 35 | } cmt_merkle_t; 36 | 37 | /** Initialize a @ref cmt_merkle_t tree state. 38 | * 39 | * @param [in] me uninitialized state */ 40 | void cmt_merkle_init(cmt_merkle_t *me); 41 | 42 | /** Resets a @ref cmt_merkle_t to pristine conditions. 43 | * 44 | * @param [in] me initialized state */ 45 | void cmt_merkle_reset(cmt_merkle_t *me); 46 | 47 | /** Finalize a @ref cmt_merkle_t tree state. 48 | * 49 | * @param [in] me initialized state 50 | * 51 | * @note use of @p me after this call is undefined behavior. */ 52 | void cmt_merkle_fini(cmt_merkle_t *me); 53 | 54 | /** Load the a @ref cmt_merkle_t tree from a @p file handle. 55 | * 56 | * @param [in] me either a initialized or uninitialized state 57 | * @param [in] filepath which file to save the merkle state 58 | * 59 | * @return 60 | * | | | 61 | * |--:|-----------------------------| 62 | * | 0| success | 63 | * |< 0| failure with a -errno value | */ 64 | int cmt_merkle_load(cmt_merkle_t *me, const char *filepath); 65 | 66 | /** Save the a @ref cmt_merkle_t tree to a @p file handle. 67 | * 68 | * @param [in] me either a initialized or uninitialized state 69 | * @param [in] filepath which file to save the merkle state 70 | * 71 | * @return 72 | * | | | 73 | * |--:|-----------------------------| 74 | * | 0| success | 75 | * |< 0| failure with a -errno value | */ 76 | int cmt_merkle_save(cmt_merkle_t *me, const char *filepath); 77 | 78 | /** Return number of leaves already in tree 79 | * 80 | * @param [in,out] me initialized state 81 | * @return 82 | * - leaf count */ 83 | uint64_t cmt_merkle_get_leaf_count(cmt_merkle_t *me); 84 | 85 | /** Append a leaf node 86 | * 87 | * @param [in,out] me initialized state 88 | * @param [in] hash value of the new leaf 89 | * 90 | * @return 91 | * | | | 92 | * |---------:|---------------------------------| 93 | * | 0| success | 94 | * | -ENOBUFS | indicates that the tree is full | 95 | * | < 0| failure with a -errno value | */ 96 | int cmt_merkle_push_back(cmt_merkle_t *me, const uint8_t hash[CMT_KECCAK_LENGTH]); 97 | 98 | /** Compute the keccak-256 hash of @p data and append it as a leaf node 99 | * 100 | * @param [in,out] me initialized state 101 | * @param [in] length size of @p data in bytes 102 | * @param [in] data array of bytes 103 | * 104 | * @return 105 | * | | | 106 | * |---------:|---------------------------------| 107 | * | 0| success | 108 | * | -ENOBUFS | indicates that the tree is full | 109 | * | < 0| failure with a -errno value | */ 110 | int cmt_merkle_push_back_data(cmt_merkle_t *me, size_t length, const void *data); 111 | 112 | /** Compute the root hash of the merkle tree 113 | * 114 | * @param [in] me initialized state 115 | * @param [out] root root hash of the merkle tree */ 116 | void cmt_merkle_get_root_hash(cmt_merkle_t *me, uint8_t root[CMT_KECCAK_LENGTH]); 117 | 118 | #endif /* CMT_MERKLE_H */ 119 | -------------------------------------------------------------------------------- /sys-utils/libcmt/README.md: -------------------------------------------------------------------------------- 1 | # Cartesi Machine Tools 2 | 3 | Is a C library to facilitate the development of applications running on the cartesi-machine. 4 | It handles the IO and communication protocol with the machine-emulator. 5 | 6 | The high level @ref libcmt\_rollup API provides functions for common operations, such as generating vouchers, notices, retrieving the next input, etc. 7 | Check the [cartesi documentation](https://docs.cartesi.io/) for an explanation of the rollup interaction model. 8 | 9 | In addition to the above mentioned module, we provide @ref libcmt\_io\_driver, a thin abstraction of the linux kernel driver. 10 | 11 | And finally, a couple of utility modules used by the high level API are also exposed. 12 | - @ref libcmt\_abi is a Ethereum Virtual Machine Application Binary Interface (EVM-ABI) encoder / decoder. 13 | - @ref libcmt\_buf is a bounds checking buffer. 14 | - @ref libcmt\_merkle is a sparse merkle tree implementation on top of keccak. 15 | - @ref libcmt\_keccak is the hashing function used extensively by Ethereum. 16 | 17 | The header files and a compiled RISC-V version of this library can be found [here](https://github.com/cartesi/machine-guest-tools/). 18 | We also provide `.pc` (pkg-config) files to facilitate linking. 19 | 20 | # mock and testing 21 | 22 | This library provides a mock implementation of @ref libcmt\_io\_driver that is 23 | able to simulate requests and replies via files on the host machine. 24 | 25 | - Build it with: `make mock`. 26 | - Install it with: `make install-mock`, use `PREFIX` to specify the installation path: 27 | (The command below will install the library and headers on `$PWD/_install` directory) 28 | ``` 29 | make install-mock PREFIX=$PWD/_install 30 | ``` 31 | 32 | ## testing 33 | 34 | Use the environment variable @p CMT\_INPUTS to inject inputs into applications compiled with the mock. 35 | Outputs will be written to files with names derived from the input name. 36 | 37 | example: 38 | ``` 39 | CMT_INPUTS="0:advance.bin" ./application 40 | ``` 41 | 42 | The first output will generate the file: 43 | ``` 44 | advance.output-0.bin 45 | ``` 46 | 47 | The first report will generate the file: 48 | ``` 49 | advance.report-0.bin 50 | ``` 51 | 52 | The first exception will generate the file: 53 | ``` 54 | advance.exception-0.bin 55 | ``` 56 | 57 | The (verifiable) outputs root hash: 58 | ``` 59 | advance.outputs_root_hash.bin 60 | ``` 61 | 62 | Inputs must follow this syntax, a comma separated list of reason number followed by a file path: 63 | ``` 64 | CMT_INPUTS=" ':' ( ',' ':' ) *" 65 | ``` 66 | 67 | For rollup, available reasons are: `0` is advance and `1` is inspect. 68 | 69 | In addition to @p CMT\_INPUTS, there is also the @p CMT\_DEBUG variable. 70 | Enabling it will cause additional debug messages to be displayed. 71 | 72 | ``` 73 | CMT_DEBUG=yes ./application 74 | ``` 75 | 76 | ## generating inputs 77 | 78 | Inputs and Outputs are expected to be EVM-ABI encoded. Encoding and decoding 79 | can be achieved multiple ways, including writing tools with this library. A 80 | simple way to generate testing data is to use the @p cast tool from 81 | [foundry](http://book.getfoundry.sh/reference/cast/cast.html) and `xxd`. 82 | 83 | Encoding an @p EvmAdvance: 84 | ``` 85 | cast calldata "EvmAdvance(uint256,address,address,uint256,uint256,uint256,bytes)" \ 86 | 0x0000000000000000000000000000000000000001 \ 87 | 0x0000000000000000000000000000000000000002 \ 88 | 0x0000000000000000000000000000000000000003 \ 89 | 0x0000000000000000000000000000000000000004 \ 90 | 0x0000000000000000000000000000000000000005 \ 91 | 0x0000000000000000000000000000000000000006 \ 92 | 0x`echo "advance-0" | xxd -p -c0` | xxd -r -p > 0.bin 93 | ``` 94 | 95 | Inspect states require no encoding. 96 | ``` 97 | echo -en "inspect-0" > 1.bin 98 | ``` 99 | 100 | ## parsing outputs 101 | 102 | Decoding a @p Voucher: 103 | ``` 104 | cast calldata-decode "Voucher(address,uint256,bytes)" 0x`xxd -p -c0 "$1"` | ( 105 | read address 106 | read value 107 | read bytes 108 | 109 | echo "{" 110 | printf '\t"address" : "%s",\n' $address 111 | printf '\t"value" : "%s",\n' $value 112 | printf '\t"bytes" : "%s"\n' $bytes 113 | echo "}" 114 | ) 115 | 116 | # sh decode-voucher.sh $1 | jq '.bytes' | xxd -r 117 | ``` 118 | 119 | Decoding a @p Notice: 120 | ``` 121 | cast calldata-decode "Notice(bytes)" 0x`xxd -p -c0 "$1"` | ( 122 | read bytes 123 | 124 | echo "{" 125 | printf '\t"bytes" : "%s"\n' $bytes 126 | echo "}" 127 | ) 128 | 129 | # sh decode-notice.sh $1 | jq '.bytes' | xxd -r 130 | ``` 131 | -------------------------------------------------------------------------------- /sys-utils/yield/yield.c: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include "libcmt/io.h" 24 | 25 | static void help(const char *progname) { 26 | fprintf(stderr, 27 | "Usage: %s []\n" 28 | "Where: \n" 29 | " \"manual\" or \"automatic\"\n" 30 | " \"progress\", \"rx-accepted\", \"rx-rejected\",\n" 31 | " \"tx-voucher\", \"tx-notice\", \"tx-exception\" or\n" 32 | " \"tx-report\"\n" 33 | " 32-bit unsigned integer (decimal, default 0)\n", 34 | progname); 35 | 36 | exit(1); 37 | } 38 | 39 | struct name_value { 40 | const char *name; 41 | uint64_t value; 42 | }; 43 | static int find_value(const struct name_value *pairs, size_t n, const char *s, uint64_t *value) 44 | { 45 | for (size_t i=0; i UINT32_MAX) { 79 | return 0; 80 | } 81 | return 1; 82 | } 83 | 84 | struct parsed_args { 85 | uint64_t mode; 86 | uint64_t reason; 87 | uint64_t data; 88 | }; 89 | 90 | void parse_args(int argc, char *argv[], struct parsed_args *p) { 91 | int i = 0; 92 | const char *progname = argv[0]; 93 | 94 | memset(p, 0, sizeof(*p)); 95 | 96 | i = 1; 97 | if (i >= argc) { 98 | fprintf(stderr, "Too few arguments.\n\n"); 99 | help(progname); 100 | } 101 | 102 | if (!get_mode(argv[i], &p->mode)) { 103 | fprintf(stderr, "Invalid argument.\n\n"); 104 | help(progname); 105 | } 106 | 107 | i++; 108 | if (i >= argc) { 109 | help(progname); 110 | } 111 | 112 | if (!get_reason(argv[i], &p->reason)) { 113 | fprintf(stderr, "Invalid argument.\n\n"); 114 | help(progname); 115 | } 116 | 117 | i++; 118 | if (i < argc) { 119 | if (get_data(argv[i], &p->data)) { 120 | i++; 121 | } else { 122 | fprintf(stderr, "Invalid argument.\n\n"); 123 | help(progname); 124 | } 125 | } 126 | 127 | if (i != argc) { 128 | fprintf(stderr, "Too many arguments.\n\n"); 129 | help(progname); 130 | } 131 | } 132 | 133 | int main(int argc, char *argv[]) { 134 | struct parsed_args args; 135 | cmt_io_driver_t io[1]; 136 | 137 | parse_args(argc, argv, &args); 138 | cmt_io_yield_t req[1] = {{ 139 | .dev = HTIF_DEVICE_YIELD, 140 | .cmd = args.mode, 141 | .reason = args.reason, 142 | .data = args.data, 143 | }}; 144 | 145 | int rc = cmt_io_init(io); 146 | if (rc) 147 | return rc; 148 | 149 | return cmt_io_yield(io, req); 150 | } 151 | -------------------------------------------------------------------------------- /rollup-http/rollup-http-server/src/main.rs: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | use std::io::ErrorKind; 18 | use std::sync::Arc; 19 | 20 | use async_mutex::Mutex; 21 | use getopts::{Options, ParsingStyle}; 22 | use rollup_http_server::{config::Config, dapp_process, http_service, rollup::RollupFd}; 23 | use tokio::sync::Notify; 24 | 25 | fn print_usage(program: &str, opts: Options) { 26 | let brief = format!( 27 | "Usage: {} [options] [args]\n\ 28 | \n\ 29 | Where command and args start the DApp.", 30 | program 31 | ); 32 | print!("{}", opts.usage(&brief)); 33 | } 34 | 35 | #[actix_web::main] 36 | async fn main() -> std::io::Result<()> { 37 | let args: Vec = std::env::args().collect(); 38 | let program = args[0].clone(); 39 | // Process command line arguments 40 | let mut opts = Options::new(); 41 | opts.parsing_style(ParsingStyle::StopAtFirstFree); 42 | opts.optflag("h", "help", "show this help message and exit"); 43 | opts.optopt( 44 | "", 45 | "address", 46 | "Address to listen (default: 127.0.0.1:5004)", 47 | "", 48 | ); 49 | opts.optopt("", "dapp", "Dapp address (default: 127.0.0.1:5003)", ""); 50 | opts.optflag("", "verbose", "print more info about application execution"); 51 | let matches = match opts.parse(&args[1..]) { 52 | Ok(m) => m, 53 | Err(e) => { 54 | eprintln!("error parsing arguments: {}", &e); 55 | return Err(std::io::Error::new(ErrorKind::InvalidInput, e.to_string())); 56 | } 57 | }; 58 | if matches.opt_present("h") { 59 | print_usage(&program, opts); 60 | return Ok(()); 61 | } 62 | 63 | // Set log level of application 64 | let mut log_level = "info"; 65 | if matches.opt_present("verbose") { 66 | log_level = "debug"; 67 | } 68 | // Set the global log level, disable timestamp 69 | env_logger::Builder::from_env(env_logger::Env::default().default_filter_or(log_level)) 70 | .format_timestamp(None) 71 | .init(); 72 | 73 | // Check if there are enough arguments to start the dapp 74 | if matches.free.is_empty() { 75 | return Err(std::io::Error::new( 76 | ErrorKind::InvalidInput, 77 | "expected dapp command after flags", 78 | )); 79 | } 80 | 81 | log::info!("starting http dispatcher service..."); 82 | 83 | // Create config 84 | let mut http_config = Config::new(); 85 | { 86 | // Parse addresses and ports 87 | let address_matches = matches 88 | .opt_get_default("address", "127.0.0.1:5004".to_string()) 89 | .unwrap_or_default(); 90 | let mut address = address_matches.split(':'); 91 | http_config.http_address = address.next().expect("address is not valid").to_string(); 92 | http_config.http_port = address 93 | .next() 94 | .expect("port is not valid") 95 | .to_string() 96 | .parse::() 97 | .unwrap(); 98 | } 99 | 100 | let rollup_fd: Arc> = Arc::new(Mutex::new(RollupFd::create().unwrap())); 101 | let server_ready = Arc::new(Notify::new()); 102 | 103 | // In another thread, wait until the server is ready and then start the dapp 104 | { 105 | let rollup_fd = rollup_fd.clone(); 106 | let server_ready = server_ready.clone(); 107 | tokio::spawn(async move { 108 | server_ready.notified().await; 109 | dapp_process::run(matches.free, rollup_fd).await; 110 | }) 111 | }; 112 | 113 | // Open http service 114 | tokio::select! { 115 | result = http_service::run(&http_config, rollup_fd, server_ready) => { 116 | match result { 117 | Ok(_) => log::info!("http service terminated successfully"), 118 | Err(e) => log::warn!("http service terminated with error: {}", e), 119 | } 120 | } 121 | } 122 | log::info!("ending http dispatcher service!"); 123 | Ok(()) 124 | } 125 | -------------------------------------------------------------------------------- /sys-utils/libcmt/src/io.c: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include "libcmt/io.h" 17 | #include "libcmt/util.h" 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include 31 | 32 | int cmt_io_init(cmt_io_driver_t *_me) { 33 | int rc = 0; 34 | 35 | if (!_me) { 36 | return -EINVAL; 37 | } 38 | cmt_io_driver_ioctl_t *me = &_me->ioctl; 39 | me->fd = open("/dev/cmio", O_RDWR); 40 | 41 | if (me->fd < 0) { 42 | rc = -errno; 43 | return rc; 44 | } 45 | 46 | struct cmio_setup setup; 47 | if (ioctl(me->fd, IOCTL_CMIO_SETUP, &setup)) { 48 | rc = -errno; 49 | goto do_close; 50 | } 51 | 52 | void *tx = mmap((void *) setup.tx.data, setup.tx.length, PROT_READ | PROT_WRITE, MAP_SHARED, me->fd, 0); 53 | if (tx == MAP_FAILED) { 54 | rc = -errno; 55 | goto do_close; 56 | } 57 | 58 | void *rx = mmap((void *) setup.rx.data, setup.rx.length, PROT_READ, MAP_SHARED, me->fd, 0); 59 | if (rx == MAP_FAILED) { 60 | rc = -errno; 61 | goto do_unmap; 62 | } 63 | 64 | cmt_buf_init(me->tx, setup.tx.length, tx); 65 | cmt_buf_init(me->rx, setup.rx.length, rx); 66 | return 0; 67 | 68 | do_unmap: 69 | munmap(tx, setup.tx.length); 70 | do_close: 71 | close(me->fd); 72 | return rc; 73 | } 74 | 75 | void cmt_io_fini(cmt_io_driver_t *_me) { 76 | if (!_me) { 77 | return; 78 | } 79 | cmt_io_driver_ioctl_t *me = &_me->ioctl; 80 | 81 | munmap(me->tx->begin, cmt_buf_length(me->tx)); 82 | munmap(me->rx->begin, cmt_buf_length(me->rx)); 83 | close(me->fd); 84 | 85 | memset(me, 0, sizeof(*me)); 86 | me->fd = -1; 87 | } 88 | 89 | cmt_buf_t cmt_io_get_tx(cmt_io_driver_t *me) { 90 | const cmt_buf_t empty = {NULL, NULL}; 91 | if (!me) { 92 | return empty; 93 | } 94 | return *me->ioctl.tx; 95 | } 96 | 97 | cmt_buf_t cmt_io_get_rx(cmt_io_driver_t *me) { 98 | const cmt_buf_t empty = {NULL, NULL}; 99 | if (!me) { 100 | return empty; 101 | } 102 | return *me->ioctl.rx; 103 | } 104 | 105 | static uint64_t pack(struct cmt_io_yield *rr) { 106 | // clang-format off 107 | return ((uint64_t) rr->dev << 56) 108 | | ((uint64_t) rr->cmd << 56 >> 8) 109 | | ((uint64_t) rr->reason << 48 >> 16) 110 | | ((uint64_t) rr->data << 32 >> 32); 111 | // clang-format on 112 | } 113 | 114 | static struct cmt_io_yield unpack(uint64_t x) { 115 | // clang-format off 116 | struct cmt_io_yield out = { 117 | x >> 56, 118 | x << 8 >> 56, 119 | x << 16 >> 48, 120 | x << 32 >> 32, 121 | }; 122 | // clang-format on 123 | return out; 124 | } 125 | 126 | /* io-mock.c:cmt_io_yield emulates this behavior (go and check it does if you change it) */ 127 | int cmt_io_yield(cmt_io_driver_t *_me, struct cmt_io_yield *rr) { 128 | if (!_me) { 129 | return -EINVAL; 130 | } 131 | if (!rr) { 132 | return -EINVAL; 133 | } 134 | cmt_io_driver_ioctl_t *me = &_me->ioctl; 135 | 136 | bool debug = cmt_util_debug_enabled(); 137 | if (debug) { 138 | (void) fprintf(stderr, 139 | "tohost {\n" 140 | "\t.dev = %d,\n" 141 | "\t.cmd = %d,\n" 142 | "\t.reason = %d,\n" 143 | "\t.data = %d,\n" 144 | "};\n", 145 | rr->dev, rr->cmd, rr->reason, rr->data); 146 | } 147 | uint64_t req = pack(rr); 148 | if (ioctl(me->fd, IOCTL_CMIO_YIELD, &req)) { 149 | return -errno; 150 | } 151 | *rr = unpack(req); 152 | 153 | if (debug) { 154 | (void) fprintf(stderr, 155 | "fromhost {\n" 156 | "\t.dev = %d,\n" 157 | "\t.cmd = %d,\n" 158 | "\t.reason = %d,\n" 159 | "\t.data = %d,\n" 160 | "};\n", 161 | rr->dev, rr->cmd, rr->reason, rr->data); 162 | } 163 | return 0; 164 | } 165 | -------------------------------------------------------------------------------- /fs/third-party/repo-info/gather-dpkg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | IFS=$'\n' 5 | rawPackages=( $(dpkg-query --show --showformat='${db:Status-Abbrev} ${source:Package}=${source:Version} ${binary:Package}=${Version}\n' 2>/dev/null) ) 6 | unset IFS 7 | 8 | declare -A packages=() 9 | for rawPackage in "${rawPackages[@]}"; do 10 | rawPackage=( $rawPackage ) 11 | stat="${rawPackage[0]}" 12 | case "$stat" in 13 | i?|h?) 14 | # "install" or "hold" 15 | ;; 16 | *) 17 | # skip "unknown", "remove", "purge" 18 | continue 19 | ;; 20 | esac 21 | src="${rawPackage[1]}" 22 | bin="${rawPackage[2]}" 23 | [ -z "${packages[$src]}" ] || packages[$src]+=' ' 24 | packages[$src]+="$bin" 25 | done 26 | 27 | if [ "${#packages[@]}" -eq 0 ]; then 28 | # not Debian-based 29 | exit 1 30 | fi 31 | 32 | if [ -e /etc/apt/sources.list ] || [ -d /etc/apt/sources.list.d ]; then 33 | # make sure we have "deb-src" entries for "apt-get source" 34 | find /etc/apt/sources.list* \ 35 | -type f \ 36 | -exec sed -i \ 37 | -e 'p; s/^deb /deb-src /' \ 38 | -e 's/^Types: deb$/Types: deb deb-src/' \ 39 | '{}' + 40 | 41 | # retry a few times if "apt-get update" fails 42 | tries=5 43 | while ! apt-get update -qq; do 44 | (( --tries )) || : 45 | if [ "$tries" -le 0 ]; then 46 | echo >&2 'error: failed to "apt-get update" after multiple attempts' 47 | exit 1 48 | fi 49 | done 50 | fi 51 | 52 | IFS=$'\n' 53 | sortedSources=( $(echo "${!packages[*]}" | sort) ) 54 | unset IFS 55 | 56 | echo 57 | echo '## `dpkg` (`.deb`-based packages)' 58 | 59 | # prints "$2$1$3$1...$N" 60 | join() { 61 | local sep="$1"; shift 62 | local out; printf -v out "${sep//%/%%}%s" "$@" 63 | echo "${out#$sep}" 64 | } 65 | 66 | for src in "${sortedSources[@]}"; do 67 | echo 68 | echo '### `dpkg` source package: `'"$src"'`' 69 | echo 70 | echo 'Binary Packages:' 71 | echo 72 | for bin in ${packages[$src]}; do 73 | echo '- `'"$bin"'`' 74 | done 75 | 76 | # parse /usr/share/doc/BIN/copyright 77 | licenses=() 78 | licenseFiles=() 79 | for bin in ${packages[$src]}; do 80 | # https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 81 | # http://dep.debian.net/deps/dep5/ 82 | binPkg="${bin%%=*}" 83 | binPkgOnly="${binPkg%%:*}" 84 | f= 85 | for try in \ 86 | "/usr/share/doc/$bin/copyright" \ 87 | "/usr/share/doc/$binPkg/copyright" \ 88 | "/usr/share/doc/$binPkgOnly/copyright" \ 89 | ; do 90 | if [ -f "$try" ]; then 91 | f="$try" 92 | break 93 | fi 94 | done 95 | if [ -z "$f" ]; then 96 | echo >&2 97 | echo >&2 "**WARNING:** '/usr/share/doc/$binPkgOnly/copyright' is missing!" 98 | echo >&2 99 | continue 100 | fi 101 | IFS=$'\n' 102 | licenses+=( $(gawk -F ':[ \t]+' '$1 == "License" && NF > 1 { gsub(/^License:[ \t]+/, ""); print }' "$f") ) 103 | licenses+=( $(grep -oE '/usr/share/common-licenses/[0-9a-zA-Z_.+-]+' "$f" | cut -d/ -f5-) ) 104 | unset IFS 105 | licenseFiles+=( "$f" ) 106 | done 107 | if [ "${#licenses[@]}" -gt 0 ]; then 108 | IFS=$'\n' 109 | licenses=( $( 110 | echo "${licenses[*]}" \ 111 | | sed -r \ 112 | -e 's/ (and|or) /\n/g' \ 113 | -e 's/[.,]+$//' \ 114 | | sort -u 115 | ) ) 116 | unset IFS 117 | 118 | echo 119 | echo 'Licenses: (parsed from: `'"$(join '`, `' "${licenseFiles[@]}")"'`)' 120 | echo 121 | for lic in "${licenses[@]}"; do 122 | echo '- `'"$lic"'`' 123 | done 124 | else 125 | echo 126 | echo '**WARNING:** unable to detect licenses! (package likely not compliant with DEP-5) ' 127 | echo 'If source is available (seen below), check the contents of `debian/copyright` within it.' 128 | echo 129 | fi 130 | 131 | sourcesUrl="https://sources.debian.net/src/${src//=//}/" 132 | snapshotUrl="http://snapshot.debian.org/package/${src//=//}/" 133 | 134 | aptSourceArgs=( apt-get source -qq --print-uris "$src" ) 135 | if aptSource="$("${aptSourceArgs[@]}" 2>/dev/null)" && [ -n "$aptSource" ]; then 136 | echo 137 | echo 'Source:' 138 | echo 139 | echo '```console' 140 | echo '$' "${aptSourceArgs[@]}" 141 | echo "$aptSource" 142 | echo '```' 143 | case "$aptSource" in 144 | *.debian.org/*) 145 | # _probably_ Debian -- let's link to sources.debian.net too 146 | echo 147 | echo 'Other potentially useful URLs:' 148 | echo 149 | echo '- '"$sourcesUrl"' (for browsing the source)' 150 | echo '- '"$sourcesUrl"'debian/copyright/ (for direct copyright/license information)' 151 | echo '- '"$snapshotUrl"' (for access to the source package after it no longer exists in the archive)' 152 | ;; 153 | esac 154 | else 155 | echo 156 | echo '**WARNING:** unable to find source (`apt-get source` failed or returned no results)! ' 157 | echo 'This is *usually* due to a new package version being released and the old version being removed.' 158 | echo 159 | if wget --quiet --spider -O /dev/null -o /dev/null "$snapshotUrl"; then 160 | echo 'The source package *may* still be available for download from:' 161 | echo 162 | echo "- $snapshotUrl" 163 | echo 164 | fi 165 | fi 166 | done 167 | -------------------------------------------------------------------------------- /sys-utils/libcmt/tests/data.h: -------------------------------------------------------------------------------- 1 | #ifndef DATA_H 2 | #define DATA_H 3 | #include 4 | uint8_t valid_advance_0[] = { 5 | 0x41, 0x5b, 0xf3, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 6 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 7 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 8 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 9 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 10 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 11 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 12 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13 | 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 14 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 15 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 16 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 17 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 18 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 19 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 20 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 21 | 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 22 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 23 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 24 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 25 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 26 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 27 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 28 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 29 | 0x00, 0x00, 0x00, 0x09, 0x61, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x2d, 30 | 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 31 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 32 | }; 33 | uint8_t valid_inspect_0[] = { 34 | 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x2d, 0x30 35 | }; 36 | uint8_t valid_report_0[] = { 37 | 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2d, 0x30 38 | }; 39 | uint8_t valid_exception_0[] = { 40 | 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x30 41 | }; 42 | uint8_t valid_voucher_0[] = { 43 | 0x23, 0x7a, 0x81, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 44 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 45 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 46 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 47 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 48 | 0x00, 0x00, 0x00, 0x00, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 49 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 50 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51 | 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 52 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 53 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 54 | 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x2d, 0x30, 0x00, 0x00, 0x00, 55 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 56 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 57 | }; 58 | uint8_t valid_notice_0[] = { 59 | 0xc2, 0x58, 0xd6, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 60 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 61 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 62 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 63 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 64 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x6e, 0x6f, 0x74, 0x69, 65 | 0x63, 0x65, 0x2d, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 66 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 67 | 0x00, 0x00, 0x00, 0x00 68 | }; 69 | uint8_t valid_gio_reply_0[] = { 70 | 0x67, 0x69, 0x6f, 0x2d, 0x72, 0x65, 0x70, 0x6c, 0x79, 0x2d, 0x30 71 | }; 72 | uint8_t valid_delegate_call_voucher_0[] = { 73 | 0x10, 0x32, 0x1e, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 74 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 75 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 76 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 77 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 78 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 79 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 80 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 81 | 0x00, 0x00, 0x00, 0x17, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 82 | 0x2d, 0x63, 0x61, 0x6c, 0x6c, 0x2d, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 83 | 0x72, 0x2d, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 84 | }; 85 | #endif /* DATA_H */ 86 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | on: [push] 3 | jobs: 4 | build: 5 | runs-on: ubuntu-latest-8-cores 6 | steps: 7 | - name: Install libarchive-tools 8 | run: | 9 | export DEBIAN_FRONTEND=noninteractive 10 | sudo apt-get update 11 | sudo apt-get install -y --no-install-recommends build-essential autoconf automake libarchive-dev libarchive-tools pandoc 12 | 13 | # Building from source cause the provided debian package is for Debian Bookworm 14 | - name: Download, build and install xgenext2fs 15 | run: | 16 | wget https://github.com/cartesi/genext2fs/archive/refs/tags/v1.5.6.tar.gz 17 | echo "34bfc26a037def23b85b676912462a3d126a87ef15c66c212b3500650da44f9e v1.5.6.tar.gz" | sha256sum -c - 18 | tar -xzf v1.5.6.tar.gz 19 | cd genext2fs-1.5.6 20 | ./autogen.sh 21 | ./configure 22 | make 23 | sudo make install 24 | rm -rf genext2fs-1.5.6 v1.5.6.tar.gz 25 | 26 | - name: Login to GHCR 27 | uses: docker/login-action@v3 28 | with: 29 | registry: ghcr.io 30 | username: ${{ github.actor }} 31 | password: ${{ secrets.GITHUB_TOKEN }} 32 | 33 | - name: Login to Docker Hub 34 | uses: docker/login-action@v3 35 | with: 36 | username: ${{ secrets.DOCKER_USERNAME }} 37 | password: ${{ secrets.DOCKER_PASSWORD }} 38 | 39 | - uses: actions/checkout@v4 40 | with: 41 | submodules: recursive 42 | 43 | - name: Export makefile variables 44 | run: make env >> $GITHUB_ENV 45 | 46 | - name: Create version file 47 | run: make package.json 48 | 49 | - name: Set up QEMU 50 | uses: docker/setup-qemu-action@v3 51 | 52 | - name: Buildx setup 53 | uses: docker/setup-buildx-action@v3 54 | 55 | - name: Build [${{ env.TOOLS_TARGZ }}] and [${{ env.TOOLS_DEB }}] 56 | id: docker_build 57 | uses: docker/build-push-action@v5 58 | with: 59 | context: . 60 | builder: ${{ steps.buildx.outputs.name }} 61 | tags: ${{ env.TOOLS_IMAGE }} 62 | push: false 63 | load: true 64 | build-args: | 65 | TOOLS_TARGZ=${{ env.TOOLS_TARGZ }} 66 | TOOLS_DEB=${{ env.TOOLS_DEB }} 67 | LINUX_HEADERS_URLPATH=${{ env.LINUX_HEADERS_URLPATH }} 68 | LINUX_HEADERS_SHA256=${{ env.LINUX_HEADERS_SHA256 }} 69 | cache-from: type=gha,scope=regular,mode=max 70 | cache-to: type=gha,scope=regular 71 | 72 | - name: Retrieve artifacts 73 | run: make copy 74 | 75 | - name: Build rootfs 76 | run: make fs 77 | 78 | - name: Auto-generate rootfs license information 79 | if: startsWith(github.ref, 'refs/tags/v') 80 | run: make fs-license 81 | 82 | - name: Upload rootfs license information 83 | if: startsWith(github.ref, 'refs/tags/v') 84 | uses: actions/upload-artifact@v4 85 | with: 86 | name: license 87 | if-no-files-found: error 88 | path: | 89 | ${{ env.TOOLS_ROOTFS_EXT2 }}.html 90 | 91 | - name: Upload artifacts 92 | uses: actions/upload-artifact@v4 93 | with: 94 | if-no-files-found: error 95 | path: | 96 | ${{ env.TOOLS_TARGZ }} 97 | ${{ env.TOOLS_ROOTFS_EXT2 }} 98 | 99 | - name: Checksum artifacts 100 | if: startsWith(github.ref, 'refs/tags/v') 101 | run: | 102 | sha512sum ${{ env.TOOLS_TARGZ }} > ${{ env.TOOLS_TARGZ }}.sha512 103 | sha512sum ${{ env.TOOLS_DEB }} > ${{ env.TOOLS_DEB }}.sha512 104 | sha512sum ${{ env.TOOLS_ROOTFS_EXT2 }} > ${{ env.TOOLS_ROOTFS_EXT2 }}.sha512 105 | 106 | - uses: softprops/action-gh-release@v1 107 | if: startsWith(github.ref, 'refs/tags/v') 108 | with: 109 | prerelease: true 110 | files: | 111 | ${{ env.TOOLS_TARGZ }} 112 | ${{ env.TOOLS_TARGZ }}.sha512 113 | ${{ env.TOOLS_DEB }} 114 | ${{ env.TOOLS_DEB }}.sha512 115 | ${{ env.TOOLS_ROOTFS_EXT2 }} 116 | ${{ env.TOOLS_ROOTFS_EXT2 }}.html 117 | ${{ env.TOOLS_ROOTFS_EXT2 }}.sha512 118 | 119 | test: 120 | runs-on: ubuntu-latest-8-cores 121 | steps: 122 | - uses: actions/checkout@v4 123 | with: 124 | submodules: recursive 125 | 126 | - name: Test libcmt mock on host 127 | run: | 128 | make -C sys-utils/libcmt/ -j$(nproc) host test 129 | 130 | - name: Test rollup-http-server and echo-dapp client on host 131 | run: | 132 | cd rollup-http/rollup-http-server 133 | MOCK_BUILD=true cargo test -- --show-output --test-threads=1 134 | 135 | - name: Test rollup-http-server api schema 136 | run: | 137 | sudo apt-get update 138 | sudo apt-get install -y wait-for-it python3 python3-pip 139 | pip3 install schemathesis==3.39.16 140 | cd rollup-http/rollup-http-server 141 | wget https://raw.githubusercontent.com/cartesi/openapi-interfaces/v0.10.0/rollup.yaml 142 | MOCK_BUILD=true cargo run -- "echo 1" & 143 | wait-for-it localhost:5004 --timeout=30 144 | st run rollup.yaml --checks all --validate-schema true --hypothesis-phases explicit --base-url http://localhost:5004 145 | -------------------------------------------------------------------------------- /sys-utils/libcmt/src/keccak.c: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include "libcmt/keccak.h" 17 | #include "libcmt/abi.h" 18 | 19 | #include 20 | 21 | // Helper macros for stringification 22 | #define TO_STRING_HELPER(X) #X 23 | #define TO_STRING(X) TO_STRING_HELPER(X) 24 | 25 | // Define loop unrolling depending on the compiler 26 | #if defined(__clang__) 27 | #define UNROLL_LOOP(n) _Pragma(TO_STRING(unroll(n))) 28 | #elif defined(__GNUC__) && !defined(__clang__) 29 | #define UNROLL_LOOP(n) _Pragma(TO_STRING(GCC unroll(n))) 30 | #else 31 | #define UNROLL_LOOP(n) 32 | #endif 33 | 34 | #define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y)))) 35 | 36 | /** Initialize a keccak state 37 | * @note don't port. use @ref cmt_keccak_init */ 38 | // clang-format off 39 | #define CMT_KECCAK_INIT(STATE) \ 40 | { \ 41 | .st.q = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, \ 42 | .pt = 0, .rsiz = 200 - 2 * CMT_KECCAK_LENGTH, \ 43 | } 44 | 45 | // clang-format on 46 | 47 | static void keccakf(uint64_t st[25]) { 48 | // clang-format off 49 | const uint64_t keccakf_rndc[24] = { 50 | 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 0x8000000080008000, 0x000000000000808b, 51 | 0x0000000080000001, 0x8000000080008081, 0x8000000000008009, 0x000000000000008a, 0x0000000000000088, 52 | 0x0000000080008009, 0x000000008000000a, 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, 53 | 0x8000000000008003, 0x8000000000008002, 0x8000000000000080, 0x000000000000800a, 0x800000008000000a, 54 | 0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008 55 | }; 56 | const int keccakf_rotc[24] = { 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 57 | 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 }; 58 | const int keccakf_piln[24] = { 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 59 | 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 }; 60 | // clang-format on 61 | 62 | #if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ 63 | for (int i = 0; i < 25; i++) { 64 | st[i] = __builtin_bswap64((uint64_t *) (st[i])); 65 | } 66 | #endif 67 | 68 | for (int r = 0; r < 24; r++) { 69 | uint64_t t = 0; 70 | uint64_t bc[5]; 71 | 72 | // Theta 73 | UNROLL_LOOP(5) 74 | for (int i = 0; i < 5; i++) { 75 | bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20]; 76 | } 77 | 78 | UNROLL_LOOP(5) 79 | for (int i = 0; i < 5; i++) { 80 | t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1); 81 | for (int j = 0; j < 25; j += 5) { 82 | st[j + i] ^= t; 83 | } 84 | } 85 | 86 | // Rho Pi 87 | t = st[1]; 88 | UNROLL_LOOP(24) 89 | for (int i = 0; i < 24; i++) { 90 | int j = keccakf_piln[i]; 91 | bc[0] = st[j]; 92 | st[j] = ROTL64(t, keccakf_rotc[i]); 93 | t = bc[0]; 94 | } 95 | 96 | // Chi 97 | UNROLL_LOOP(25) 98 | for (int j = 0; j < 25; j += 5) { 99 | for (int i = 0; i < 5; i++) { 100 | bc[i] = st[j + i]; 101 | } 102 | for (int i = 0; i < 5; i++) { 103 | st[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5]; 104 | } 105 | } 106 | 107 | // Iota 108 | st[0] ^= keccakf_rndc[r]; 109 | } 110 | 111 | #if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ 112 | for (int i = 0; i < 25; i++) { 113 | st[i] = __builtin_bswap64(st[i]); 114 | } 115 | #endif 116 | } 117 | 118 | void cmt_keccak_init(cmt_keccak_t *state) { 119 | *state = (cmt_keccak_t) CMT_KECCAK_INIT(state); 120 | } 121 | 122 | void cmt_keccak_update(cmt_keccak_t *state, size_t n, const void *data) { 123 | int j = state->pt; 124 | for (size_t i = 0; i < n; i++) { 125 | state->st.b[j++] ^= ((const uint8_t *) data)[i]; 126 | if (j >= state->rsiz) { 127 | keccakf(state->st.q); 128 | j = 0; 129 | } 130 | } 131 | state->pt = j; 132 | } 133 | 134 | void cmt_keccak_final(cmt_keccak_t *state, void *md) { 135 | state->st.b[state->pt] ^= 0x01; 136 | state->st.b[state->rsiz - 1] ^= 0x80; 137 | keccakf(state->st.q); 138 | 139 | for (int i = 0; i < CMT_KECCAK_LENGTH; i++) { 140 | ((uint8_t *) md)[i] = state->st.b[i]; 141 | } 142 | } 143 | 144 | uint8_t *cmt_keccak_data(size_t length, const void *data, uint8_t md[CMT_KECCAK_LENGTH]) { 145 | cmt_keccak_t c[1]; 146 | cmt_keccak_init(c); 147 | cmt_keccak_update(c, length, data); 148 | cmt_keccak_final(c, md); 149 | return md; 150 | } 151 | 152 | uint32_t cmt_keccak_funsel(const char *decl) { 153 | uint8_t md[32]; 154 | cmt_keccak_data(strlen(decl), decl, md); 155 | return CMT_ABI_FUNSEL(md[0], md[1], md[2], md[3]); 156 | } 157 | -------------------------------------------------------------------------------- /sys-utils/libcmt/include/libcmt/io.h: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | /** @file 17 | * @defgroup libcmt_io_driver Cartesi Machine Input/Output Driver 18 | * Low level abstraction of the Cartesi Machine kernel driver. 19 | * 20 | * Interaction is as follows: 21 | * - Open the kernel device and mmap the shared memory ranges (tx and rx) with: 22 | * @ref cmt_io_init. 23 | * - Retrieve the memory regions from the library with: @ref cmt_io_get_tx and 24 | * @ref cmt_io_get_rx. 25 | * - Do requests (next input, emit output ...) by yielding the control back to 26 | * the emulator with: @ref cmt_io_yield. 27 | * 28 | * Lets look at some code: 29 | * 30 | * @include examples/io.c 31 | * 32 | * There are two implementations provided: `ioctl` that interacts with the 33 | * cartesi-machine linux driver and `mock` that reads and writes the host 34 | * filesystem, used for testing. 35 | * 36 | * @section Environment variables 37 | * 38 | * this module exposes two environment variables: @p CMT_DEBUG and @p CMT_INPUTS. 39 | * 40 | * @p CMT_DEBUG prints runtime information during application execution. 41 | * 42 | * ``` 43 | * CMT_DEBUG=yes ./application 44 | * ``` 45 | * 46 | * @p CMT_INPUTS feeds inputs to the mock (ignored for ioctl). 47 | * 48 | * ``` 49 | * CMT_INPUTS=0:advance.bin,1:inspect.bin ./application 50 | * ``` 51 | * 52 | * @ingroup libcmt 53 | * @{ */ 54 | #ifndef CMT_IO_H 55 | #define CMT_IO_H 56 | #include "buf.h" 57 | #include 58 | 59 | /** Device */ 60 | enum { 61 | HTIF_DEVICE_YIELD = 2, /**< Yield device */ 62 | }; 63 | 64 | /** Commands */ 65 | enum { 66 | HTIF_YIELD_CMD_AUTOMATIC = 0, /**< Automatic yield */ 67 | HTIF_YIELD_CMD_MANUAL = 1, /**< Manual yield */ 68 | }; 69 | 70 | /** Automatic reasons */ 71 | enum { 72 | HTIF_YIELD_AUTOMATIC_REASON_PROGRESS = 1, /**< Progress */ 73 | HTIF_YIELD_AUTOMATIC_REASON_TX_OUTPUT = 2, /**< emit an output */ 74 | HTIF_YIELD_AUTOMATIC_REASON_TX_REPORT = 4, /**< emit a report */ 75 | }; 76 | 77 | /** Manual reasons */ 78 | enum { 79 | HTIF_YIELD_MANUAL_REASON_RX_ACCEPTED = 1, /**< Accept and load next input */ 80 | HTIF_YIELD_MANUAL_REASON_RX_REJECTED = 2, /**< Reject and revert */ 81 | HTIF_YIELD_MANUAL_REASON_TX_EXCEPTION = 4, /**< emit a exception and halt execution */ 82 | }; 83 | 84 | /** Reply reason when requesting @ref HTIF_YIELD_REASON_RX_ACCEPTED or HTIF_YIELD_REASON_RX_REJECTED */ 85 | enum { 86 | HTIF_YIELD_REASON_ADVANCE = 0, /**< Input is advance */ 87 | HTIF_YIELD_REASON_INSPECT = 1, /**< Input is inspect */ 88 | }; 89 | 90 | typedef struct { 91 | cmt_buf_t tx[1]; 92 | cmt_buf_t rx[1]; 93 | int fd; 94 | } cmt_io_driver_ioctl_t; 95 | 96 | typedef struct { 97 | cmt_buf_t tx[1]; 98 | cmt_buf_t rx[1]; 99 | cmt_buf_t inputs_left; 100 | 101 | int input_type; 102 | char input_filename[128]; 103 | char input_fileext[16]; 104 | 105 | int input_seq; 106 | int output_seq; 107 | int report_seq; 108 | int exception_seq; 109 | int gio_seq; 110 | } cmt_io_driver_mock_t; 111 | 112 | /** Implementation specific cmio state. */ 113 | typedef union cmt_io_driver { 114 | cmt_io_driver_ioctl_t ioctl; 115 | cmt_io_driver_mock_t mock; 116 | } cmt_io_driver_t; 117 | 118 | /** yield struct cmt_io_yield */ 119 | typedef struct cmt_io_yield { 120 | uint8_t dev; 121 | uint8_t cmd; 122 | uint16_t reason; 123 | uint32_t data; 124 | } cmt_io_yield_t; 125 | 126 | /** Open the io device and initialize the driver. Release its resources with @ref cmt_io_fini. 127 | * 128 | * @param [in] me A uninitialized @ref cmt_io_driver state 129 | * 130 | * @return 131 | * | | | 132 | * |--:|-----------------------------| 133 | * | 0| success | 134 | * |< 0| failure with a -errno value | */ 135 | int cmt_io_init(cmt_io_driver_t *me); 136 | 137 | /** Release the driver resources and close the io device. 138 | * 139 | * @param [in] me A successfully initialized state by @ref cmt_io_init 140 | * @note usage of @p me after this call is a BUG and will cause undefined behaviour */ 141 | void cmt_io_fini(cmt_io_driver_t *me); 142 | 143 | /** Retrieve the transmit buffer @p tx 144 | * 145 | * @param [in] me A successfully initialized state by @ref cmt_io_init 146 | * @return 147 | * - writable memory region as defined in the setup structure (check @ref cmt_buf_t) 148 | * @note memory is valid until @ref cmt_io_fini is called. */ 149 | cmt_buf_t cmt_io_get_tx(cmt_io_driver_t *me); 150 | 151 | /** Retrieve the receive buffer @p rx 152 | * 153 | * @param [in] me A successfully initialized state by @ref cmt_io_init 154 | * @return 155 | * - readable memory region as defined in the setup structure (check @ref cmt_buf_t) 156 | * @note memory is valid until @ref cmt_io_fini is called. */ 157 | cmt_buf_t cmt_io_get_rx(cmt_io_driver_t *me); 158 | 159 | /** Perform the yield encoded in @p rr. 160 | * 161 | * @param [in] me A successfully initialized state by @ref cmt_io_init 162 | * @param [in,out] rr Request and Reply 163 | * @return 164 | * - 0 on success 165 | * - negative errno code on error */ 166 | int cmt_io_yield(cmt_io_driver_t *me, cmt_io_yield_t *rr); 167 | 168 | #endif /* CMT_IO_H */ 169 | -------------------------------------------------------------------------------- /sys-utils/libcmt/tests/abi-multi.c: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include "libcmt/abi.h" 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | // Request(address,uint256,uint256,uint256,bytes) 23 | #define REQUEST CMT_ABI_FUNSEL(0xf2, 0xbd, 0x3e, 0x8e) 24 | 25 | // Reply(address,bytes) 26 | #define REPLY CMT_ABI_FUNSEL(0x88, 0x6c, 0xbf, 0xaa) 27 | 28 | static int memeq(uint8_t *x, uint8_t *y, size_t n, const char *file, int line) { 29 | for (size_t i = 0; i < n; ++i) { 30 | if (x[i] != y[i]) { 31 | (void) fprintf(stderr, "%s:%d Mismatch at offset %zu (0x%02x != 0x%02x)\n", file, line, i, x[i], y[i]); 32 | cmt_buf_xxd(x, x + n, 0x20); 33 | cmt_buf_xxd(y, y + n, 0x20); 34 | return -1; 35 | } 36 | } 37 | return 0; 38 | } 39 | 40 | static int test_request(void) { 41 | // cast calldata "Request(address,uint256,uint256,uint256,bytes)" `cast address-zero` 1 2 3 0xdeadbeef | xxd -r -p | xxd -n request -i 42 | unsigned char request[] = { 43 | // clang-format off 44 | 0xf2, 0xbd, 0x3e, 0x8e, 45 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 46 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 47 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 48 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 49 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 50 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 51 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 52 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 53 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 54 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 55 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 56 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 57 | 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 58 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 59 | // clang-format on 60 | }; 61 | uint8_t mem[256]; 62 | cmt_buf_t bb[1] = {{mem, mem + sizeof mem}}; 63 | cmt_buf_t wr[1] = {*bb}; 64 | cmt_buf_t of[1]; 65 | cmt_buf_t frame[1]; 66 | 67 | cmt_abi_address_t address = {0}; 68 | uint8_t bytes[] = {0xde, 0xad, 0xbe, 0xef}; 69 | 70 | cmt_abi_put_funsel(wr, REQUEST); 71 | cmt_abi_mark_frame(wr, frame); 72 | cmt_abi_put_address(wr, &address); 73 | cmt_abi_put_uint(wr, sizeof(int), &(int[]){1}); 74 | cmt_abi_put_uint(wr, sizeof(int), &(int[]){2}); 75 | cmt_abi_put_uint(wr, sizeof(int), &(int[]){3}); 76 | cmt_abi_put_bytes_s(wr, of); 77 | cmt_abi_put_bytes_d(wr, of, frame, &(cmt_abi_bytes_t){sizeof bytes, bytes}); 78 | 79 | return sizeof request != (wr->begin - bb->begin) || memeq(request, bb->begin, sizeof request, __FILE__, __LINE__); 80 | } 81 | 82 | static int test_reply(void) { 83 | // cast calldata "Reply(address,bytes)" `cast address-zero` 0xdeadbeef | xxd -r -p | xxd -n reply -i 84 | unsigned char reply[] = { 85 | // clang-format off 86 | 0x88, 0x6c, 0xbf, 0xaa, 87 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 88 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 89 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 90 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 91 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 92 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 93 | 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 94 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 95 | // clang-format on 96 | }; 97 | 98 | uint8_t mem[256]; 99 | cmt_buf_t bb[1] = {{mem, mem + sizeof mem}}; 100 | cmt_buf_t wr[1] = {*bb}; 101 | cmt_buf_t of[1]; 102 | cmt_buf_t frame[1]; 103 | 104 | cmt_abi_address_t address = {0}; 105 | uint8_t bytes[] = {0xde, 0xad, 0xbe, 0xef}; 106 | 107 | cmt_abi_put_funsel(wr, REPLY); 108 | cmt_abi_mark_frame(wr, frame); 109 | cmt_abi_put_address(wr, &address); 110 | cmt_abi_put_bytes_s(wr, of); 111 | cmt_abi_put_bytes_d(wr, of, frame, &(cmt_abi_bytes_t){sizeof bytes, bytes}); 112 | 113 | return sizeof reply != (wr->begin - bb->begin) || memeq(reply, bb->begin, sizeof reply, __FILE__, __LINE__); 114 | } 115 | 116 | int main(void) { 117 | assert(test_request() == 0); 118 | assert(test_reply() == 0); 119 | return 0; 120 | } 121 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Copyright Cartesi and individual authors (see AUTHORS) 2 | # SPDX-License-Identifier: Apache-2.0 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | MAJOR := 0 18 | MINOR := 17 19 | PATCH := 2 20 | LABEL := 21 | VERSION := $(MAJOR).$(MINOR).$(PATCH)$(LABEL) 22 | 23 | TOOLS_TARGZ := machine-guest-tools_riscv64.tar.gz 24 | TOOLS_DEB := machine-guest-tools_riscv64.deb 25 | TOOLS_IMAGE := cartesi/machine-guest-tools:$(VERSION) 26 | TOOLS_ROOTFS_TAR := rootfs-tools.tar 27 | TOOLS_ROOTFS_EXT2 := rootfs-tools.ext2 28 | TOOLS_ROOTFS_IMAGE := cartesi/rootfs-tools:$(VERSION) 29 | 30 | LINUX_IMAGE_VERSION ?= v0.20.0 31 | LINUX_VERSION ?= 6.5.13-ctsi-1 32 | LINUX_HEADERS_URLPATH := https://github.com/cartesi/machine-linux-image/releases/download/${LINUX_IMAGE_VERSION}/linux-libc-dev-riscv64-cross-${LINUX_VERSION}-${LINUX_IMAGE_VERSION}.deb 33 | LINUX_HEADERS_SHA256 := 2723435e8b45d8fb7a79e9344f6dc517b3dbc08e03ac17baab311300ec475c08 34 | 35 | PREFIX ?= /usr 36 | DESTDIR ?= . 37 | CARGO ?= cargo 38 | ARCH = $(shell uname -m) 39 | 40 | ifneq ($(ARCH),riscv64) 41 | all: build 42 | else 43 | all: build-riscv64 ## Build all tools 44 | endif 45 | 46 | build-riscv64: sys-utils rollup-http package.json ## Build riscv64 tools 47 | 48 | build: targz fs ## Build targz and fs (cross compiling with Docker) 49 | 50 | $(TOOLS_DEB) $(TOOLS_TARGZ) targz deb: ## Build tools .tar.gz and .deb (cross compiling with Docker) 51 | @docker buildx build --load \ 52 | --build-arg TOOLS_TARGZ=$(TOOLS_TARGZ) \ 53 | --build-arg TOOLS_DEB=$(TOOLS_DEB) \ 54 | --build-arg LINUX_HEADERS_URLPATH=$(LINUX_HEADERS_URLPATH) \ 55 | --build-arg LINUX_HEADERS_SHA256=$(LINUX_HEADERS_SHA256) \ 56 | -t $(TOOLS_IMAGE) \ 57 | -f Dockerfile \ 58 | . ; 59 | $(MAKE) copy 60 | 61 | copy: 62 | @ID=`docker create $(TOOLS_IMAGE)` && \ 63 | docker cp $$ID:/work/$(TOOLS_TARGZ) . && \ 64 | docker cp $$ID:/work/$(TOOLS_DEB) . && \ 65 | docker rm $$ID 66 | 67 | control: Makefile control.in 68 | @sed 's|ARG_VERSION|$(VERSION)|g' control.in > control 69 | 70 | package.json: Makefile package.json.in 71 | @sed 's|ARG_VERSION|$(VERSION)|g' package.json.in > package.json 72 | 73 | fs: $(TOOLS_ROOTFS_EXT2) ## Build tools rootfs image (cross compiling with Docker) 74 | 75 | $(TOOLS_ROOTFS_EXT2): $(TOOLS_DEB) fs/Dockerfile 76 | @docker buildx build --platform linux/riscv64 \ 77 | --build-arg TOOLS_DEB=$(TOOLS_DEB) \ 78 | --output type=tar,dest=$(TOOLS_ROOTFS_TAR) \ 79 | --file fs/Dockerfile \ 80 | . && \ 81 | xgenext2fs -fzB 4096 -i 4096 -r +4096 -a $(TOOLS_ROOTFS_TAR) -L rootfs $(TOOLS_ROOTFS_EXT2) && \ 82 | rm -f $(TOOLS_ROOTFS_TAR) 83 | 84 | fs-license: ## Build tools rootfs image HTML with license information 85 | @docker buildx build --load --platform linux/riscv64 \ 86 | --build-arg TOOLS_TARGZ=$(TOOLS_TARGZ) \ 87 | -t $(TOOLS_ROOTFS_IMAGE) \ 88 | --file fs/Dockerfile \ 89 | . 90 | TMPFILE=$$(mktemp) && (cd fs/third-party/repo-info/; ./scan-local.sh $(TOOLS_ROOTFS_IMAGE) linux/riscv64) | tee $$TMPFILE && pandoc -s -f markdown -t html5 -o $(TOOLS_ROOTFS_EXT2).html $$TMPFILE && rm -f $$TMPFILE 91 | 92 | env: ## Print useful Makefile information 93 | @echo VERSION=$(VERSION) 94 | @echo TOOLS_TARGZ=$(TOOLS_TARGZ) 95 | @echo TOOLS_DEB=$(TOOLS_DEB) 96 | @echo TOOLS_ROOTFS_EXT2=$(TOOLS_ROOTFS_EXT2) 97 | @echo TOOLS_IMAGE=$(TOOLS_IMAGE) 98 | @echo TOOLS_ROOTFS_IMAGE=$(TOOLS_ROOTFS_IMAGE) 99 | @echo LINUX_IMAGE_VERSION=$(LINUX_IMAGE_VERSION) 100 | @echo LINUX_VERSION=$(LINUX_VERSION) 101 | @echo LINUX_HEADERS_URLPATH=$(LINUX_HEADERS_URLPATH) 102 | @echo LINUX_HEADERS_SHA256=$(LINUX_HEADERS_SHA256) 103 | 104 | test: ## Test tools using mock builds 105 | make -C sys-utils/libcmt/ test 106 | cd rollup-http/rollup-http-server && \ 107 | MOCK_BUILD=true $(CARGO) test -- --show-output --test-threads=1 108 | 109 | setup: ## Setup riscv64 buildx 110 | @docker run --privileged --rm linuxkit/binfmt:bebbae0c1100ebf7bf2ad4dfb9dfd719cf0ef132 111 | 112 | setup-required: ## Check if riscv64 buildx setup is required 113 | @echo 'riscv64 buildx setup required:' `docker buildx ls | grep -q riscv64 && echo no || echo yes` 114 | 115 | image: ## Build tools cross compilation Docker image 116 | docker build \ 117 | --build-arg LINUX_HEADERS_URLPATH=$(LINUX_HEADERS_URLPATH) \ 118 | --build-arg LINUX_HEADERS_SHA256=$(LINUX_HEADERS_SHA256) \ 119 | --target tools-env -t $(TOOLS_IMAGE)-tools-env -f Dockerfile . 120 | 121 | shell: ## Spawn a cross compilation shell with tools Docker image 122 | @docker run --hostname rust-builder -it --rm \ 123 | -e USER=$$(id -u -n) \ 124 | -e GROUP=$$(id -g -n) \ 125 | -e UID=$$(id -u) \ 126 | -e GID=$$(id -g) \ 127 | -u $$(id -u):$$(id -g) \ 128 | -v `pwd`:/work/machine-guest-tools \ 129 | -w /work/machine-guest-tools \ 130 | $(TOOLS_IMAGE)-tools-env /bin/bash 131 | 132 | libcmt: ## Compile libcmt 133 | @$(MAKE) -C sys-utils/libcmt 134 | 135 | sys-utils: libcmt ## Compile system utilities tools 136 | @$(MAKE) -C sys-utils 137 | 138 | rollup-http: libcmt ## Compile rollup http tools 139 | @$(MAKE) -C rollup-http 140 | 141 | install-share: package.json 142 | install -Dm644 package.json $(DESTDIR)$(PREFIX)/share/package.json 143 | 144 | install: install-share ## Install all tools into ${DESTDIR}/${PREFIX} 145 | @$(MAKE) -C sys-utils/libcmt install 146 | @$(MAKE) -C sys-utils install 147 | @$(MAKE) -C rollup-http install 148 | 149 | clean-image: ## Clean docker images 150 | @(docker rmi $(TOOLS_IMAGE) > /dev/null 2>&1 || true) 151 | 152 | clean: ## Clean built files 153 | @rm -f $(TOOLS_TARGZ) $(TOOLS_DEB) $(TOOLS_ROOTFS_EXT2) $(TOOLS_ROOTFS_TAR) 154 | @$(MAKE) -C sys-utils/libcmt clean 155 | @$(MAKE) -C sys-utils clean 156 | @$(MAKE) -C rollup-http clean 157 | 158 | distclean: clean clean-image ## Clean built files and docker images 159 | 160 | help: ## Show this help 161 | @sed \ 162 | -e '/^[a-zA-Z0-9_\-]*:.*##/!d' \ 163 | -e 's/:.*##\s*/:/' \ 164 | -e 's/^\(.\+\):\(.*\)/$(shell tput setaf 6)\1$(shell tput sgr0):\2/' \ 165 | $(MAKEFILE_LIST) | column -c2 -t -s : 166 | 167 | .PHONY: all build targz deb fs fs-license env test setup setup-required image shell libcmt sys-utils rollup-http install clean-image clean distclean help 168 | -------------------------------------------------------------------------------- /sys-utils/libcmt/tests/merkle.c: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include "libcmt/merkle.h" 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #if 0 // NOLINT 26 | static void print(int m, uint8_t md[CMT_KECCAK_LENGTH]) { 27 | printf("%3d: ", m); 28 | for (int i = 0, n = CMT_KECCAK_LENGTH; i < n; ++i) 29 | printf("0x%02x%s", md[i], i + 1 == n ? "\n" : ", "); 30 | } 31 | #endif 32 | 33 | void test_merkle_init_and_reset(void) { 34 | cmt_merkle_t merkle; 35 | cmt_merkle_init(&merkle); 36 | assert(cmt_merkle_get_leaf_count(&merkle) == 0); 37 | for (int i = 0; i < CMT_MERKLE_TREE_HEIGHT; ++i) { 38 | for (int j = 0; j < CMT_KECCAK_LENGTH; ++j) { 39 | assert(merkle.state[i][j] == 0); 40 | } 41 | } 42 | 43 | uint8_t data[CMT_KECCAK_LENGTH] = {0}; 44 | assert(cmt_merkle_push_back(&merkle, data) == 0); 45 | assert(cmt_merkle_get_leaf_count(&merkle) == 1); 46 | 47 | cmt_merkle_reset(&merkle); 48 | assert(cmt_merkle_get_leaf_count(&merkle) == 0); 49 | for (int i = 0; i < CMT_MERKLE_TREE_HEIGHT; ++i) { 50 | for (int j = 0; j < CMT_KECCAK_LENGTH; ++j) { 51 | assert(merkle.state[i][j] == 0); 52 | } 53 | } 54 | printf("%s passed\n", __FUNCTION__); 55 | } 56 | 57 | void test_merkle_get_root_pristine(void) { 58 | cmt_merkle_t merkle; 59 | cmt_merkle_init(&merkle); 60 | assert(cmt_merkle_get_leaf_count(&merkle) == 0); 61 | 62 | uint8_t root[CMT_KECCAK_LENGTH]; 63 | cmt_merkle_get_root_hash(&merkle, root); 64 | uint8_t expected_root[CMT_KECCAK_LENGTH] = {0x0a, 0x16, 0x29, 0x46, 0xe5, 0x61, 0x58, 0xba, 0xc0, 0x67, 0x3e, 0x6d, 65 | 0xd3, 0xbd, 0xfd, 0xc1, 0xe4, 0xa0, 0xe7, 0x74, 0x4a, 0x12, 0x0f, 0xdb, 0x64, 0x00, 0x50, 0xc8, 0xd7, 0xab, 66 | 0xe1, 0xc6}; 67 | 68 | for (int i = 0; i < CMT_KECCAK_LENGTH; ++i) { 69 | assert(root[i] == expected_root[i]); 70 | } 71 | printf("%s passed\n", __FUNCTION__); 72 | } 73 | 74 | void test_merkle_push_back_and_get_root(void) { 75 | cmt_merkle_t merkle; 76 | cmt_merkle_init(&merkle); 77 | uint8_t data[CMT_KECCAK_LENGTH] = {0}; 78 | assert(cmt_merkle_push_back(&merkle, data) == 0); 79 | assert(cmt_merkle_get_leaf_count(&merkle) == 1); 80 | 81 | uint8_t root[CMT_KECCAK_LENGTH]; 82 | cmt_merkle_get_root_hash(&merkle, root); 83 | uint8_t expected_root[CMT_KECCAK_LENGTH] = {0x0a, 0x16, 0x29, 0x46, 0xe5, 0x61, 0x58, 0xba, 0xc0, 0x67, 0x3e, 0x6d, 84 | 0xd3, 0xbd, 0xfd, 0xc1, 0xe4, 0xa0, 0xe7, 0x74, 0x4a, 0x12, 0x0f, 0xdb, 0x64, 0x00, 0x50, 0xc8, 0xd7, 0xab, 85 | 0xe1, 0xc6}; 86 | for (int i = 0; i < CMT_KECCAK_LENGTH; ++i) { 87 | assert(root[i] == expected_root[i]); 88 | } 89 | printf("%s passed\n", __FUNCTION__); 90 | } 91 | 92 | void test_cmt_merkle_push_back_data_and_get_root(void) { 93 | cmt_merkle_t merkle; 94 | cmt_merkle_init(&merkle); 95 | 96 | const char *data1 = "Cartesi"; 97 | const char *data2 = "Merkle"; 98 | const char *data3 = "Tree"; 99 | assert(cmt_merkle_push_back_data(&merkle, strlen(data1), data1) == 0); 100 | assert(cmt_merkle_push_back_data(&merkle, strlen(data2), data2) == 0); 101 | assert(cmt_merkle_push_back_data(&merkle, strlen(data3), data3) == 0); 102 | 103 | uint8_t root[CMT_KECCAK_LENGTH]; 104 | cmt_merkle_get_root_hash(&merkle, root); 105 | uint8_t expected_root[CMT_KECCAK_LENGTH] = {0x45, 0xa6, 0xfd, 0x68, 0x45, 0xc1, 0x7f, 0xe0, 0x21, 0x7f, 0xf0, 0xfd, 106 | 0x9b, 0x2c, 0x02, 0x1f, 0x2f, 0x2e, 0xe3, 0x9e, 0xe1, 0x99, 0x7d, 0xf3, 0x1f, 0x2d, 0x4c, 0x81, 0x7d, 0x3d, 107 | 0x1b, 0xf7}; 108 | for (int i = 0; i < CMT_KECCAK_LENGTH; ++i) { 109 | assert(root[i] == expected_root[i]); 110 | } 111 | 112 | printf("%s passed\n", __FUNCTION__); 113 | } 114 | 115 | void test_cmt_merkle_push_back(void) { 116 | cmt_merkle_t merkle; 117 | cmt_merkle_init(&merkle); 118 | 119 | uint8_t hash1[CMT_KECCAK_LENGTH] = {0}; 120 | assert(cmt_merkle_push_back(&merkle, hash1) == 0); 121 | assert(cmt_merkle_get_leaf_count(&merkle) == 1); 122 | 123 | uint8_t hash2[CMT_KECCAK_LENGTH] = {1}; 124 | assert(cmt_merkle_push_back(&merkle, hash2) == 0); 125 | assert(cmt_merkle_get_leaf_count(&merkle) == 2); 126 | 127 | printf("%s passed\n", __FUNCTION__); 128 | } 129 | 130 | void test_cmt_merkle_push_back_data(void) { 131 | cmt_merkle_t merkle; 132 | cmt_merkle_init(&merkle); 133 | 134 | const char *data1 = "test data 1"; 135 | assert(cmt_merkle_push_back_data(&merkle, strlen(data1), data1) == 0); 136 | assert(cmt_merkle_get_leaf_count(&merkle) == 1); 137 | 138 | const char *data2 = "test data 2"; 139 | assert(cmt_merkle_push_back_data(&merkle, strlen(data2), data2) == 0); 140 | assert(cmt_merkle_get_leaf_count(&merkle) == 2); 141 | 142 | printf("%s passed\n", __FUNCTION__); 143 | } 144 | 145 | void test_cmt_merkle_save_load(void) { 146 | cmt_merkle_t merkle1; 147 | cmt_merkle_t merkle2; 148 | char valid[] = "/tmp/tmp.XXXXXX"; 149 | char invalid[] = "/tmp/tmp.XXXXXX/invalid.bin"; 150 | 151 | // create a unique file and an invalid file from it. 152 | (void) !mkstemp(valid); 153 | memcpy(invalid, valid, strlen(valid)); 154 | 155 | // Initialize merkle1 and add some data 156 | cmt_merkle_init(&merkle1); 157 | uint8_t data[CMT_KECCAK_LENGTH] = {0}; 158 | for (int i = 0; i < 5; ++i) { 159 | // Fill data with i 160 | memset(data, i, 161 | CMT_KECCAK_LENGTH); // NOLINT(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) 162 | assert(cmt_merkle_push_back_data(&merkle1, CMT_KECCAK_LENGTH, data) == 0); 163 | } 164 | 165 | // succeed with normal usage 166 | assert(cmt_merkle_save(&merkle1, valid) == 0); 167 | assert(cmt_merkle_load(&merkle2, valid) == 0); 168 | assert(memcmp(&merkle1, &merkle2, sizeof(merkle1)) == 0); 169 | 170 | // fail to load smaller file 171 | (void) !truncate(valid, sizeof(merkle1) - 1); 172 | assert(cmt_merkle_load(&merkle2, valid) != 0); 173 | (void) !remove(valid); 174 | 175 | // fail to save/load invalid filepath 176 | assert(cmt_merkle_save(&merkle1, invalid) != 0); 177 | assert(cmt_merkle_load(&merkle2, invalid) != 0); 178 | 179 | // invalid state 180 | assert(cmt_merkle_save(NULL, valid) == -EINVAL); 181 | assert(cmt_merkle_load(NULL, valid) == -EINVAL); 182 | 183 | printf("%s passed\n", __FUNCTION__); 184 | } 185 | 186 | void test_cmt_merkle_full(void) { 187 | const uint64_t max_count = 188 | (CMT_MERKLE_TREE_HEIGHT < 8 * sizeof(uint64_t)) ? (UINT64_C(1) << CMT_MERKLE_TREE_HEIGHT) : UINT64_MAX; 189 | cmt_merkle_t merkle = { 190 | .leaf_count = max_count - 1, 191 | }; 192 | assert(cmt_merkle_get_leaf_count(&merkle) == max_count - 1); 193 | 194 | uint8_t data[] = {0}; 195 | assert(cmt_merkle_push_back_data(&merkle, sizeof(data), data) == 0); 196 | assert(cmt_merkle_push_back_data(&merkle, sizeof(data), data) == -ENOBUFS); 197 | assert(cmt_merkle_get_leaf_count(&merkle) == max_count); 198 | } 199 | 200 | int main(void) { 201 | setenv("CMT_DEBUG", "yes", 1); 202 | test_merkle_init_and_reset(); 203 | test_merkle_push_back_and_get_root(); 204 | test_cmt_merkle_push_back_data_and_get_root(); 205 | test_cmt_merkle_push_back(); 206 | test_cmt_merkle_push_back_data(); 207 | test_cmt_merkle_save_load(); 208 | test_cmt_merkle_full(); 209 | printf("All merkle tests passed!\n"); 210 | return 0; 211 | } 212 | -------------------------------------------------------------------------------- /sys-utils/hex/hex.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | #include 17 | #include 18 | #include 19 | 20 | // clang-format off 21 | static const unsigned char dec[256] = { 22 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 23 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 24 | 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255, 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 25 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 26 | 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 27 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 28 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 29 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 30 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 31 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 32 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 33 | }; 34 | 35 | static const unsigned char enc[512] = { 36 | '0','0', '0','1', '0','2', '0','3', '0','4', '0','5', '0','6', '0','7', '0','8', '0','9', '0','a', '0','b', '0','c', 37 | '0','d', '0','e', '0','f', '1','0', '1','1', '1','2', '1','3', '1','4', '1','5', '1','6', '1','7', '1','8', '1','9', 38 | '1','a', '1','b', '1','c', '1','d', '1','e', '1','f', '2','0', '2','1', '2','2', '2','3', '2','4', '2','5', '2','6', 39 | '2','7', '2','8', '2','9', '2','a', '2','b', '2','c', '2','d', '2','e', '2','f', '3','0', '3','1', '3','2', '3','3', 40 | '3','4', '3','5', '3','6', '3','7', '3','8', '3','9', '3','a', '3','b', '3','c', '3','d', '3','e', '3','f', '4','0', 41 | '4','1', '4','2', '4','3', '4','4', '4','5', '4','6', '4','7', '4','8', '4','9', '4','a', '4','b', '4','c', '4','d', 42 | '4','e', '4','f', '5','0', '5','1', '5','2', '5','3', '5','4', '5','5', '5','6', '5','7', '5','8', '5','9', '5','a', 43 | '5','b', '5','c', '5','d', '5','e', '5','f', '6','0', '6','1', '6','2', '6','3', '6','4', '6','5', '6','6', '6','7', 44 | '6','8', '6','9', '6','a', '6','b', '6','c', '6','d', '6','e', '6','f', '7','0', '7','1', '7','2', '7','3', '7','4', 45 | '7','5', '7','6', '7','7', '7','8', '7','9', '7','a', '7','b', '7','c', '7','d', '7','e', '7','f', '8','0', '8','1', 46 | '8','2', '8','3', '8','4', '8','5', '8','6', '8','7', '8','8', '8','9', '8','a', '8','b', '8','c', '8','d', '8','e', 47 | '8','f', '9','0', '9','1', '9','2', '9','3', '9','4', '9','5', '9','6', '9','7', '9','8', '9','9', '9','a', '9','b', 48 | '9','c', '9','d', '9','e', '9','f', 'a','0', 'a','1', 'a','2', 'a','3', 'a','4', 'a','5', 'a','6', 'a','7', 'a','8', 49 | 'a','9', 'a','a', 'a','b', 'a','c', 'a','d', 'a','e', 'a','f', 'b','0', 'b','1', 'b','2', 'b','3', 'b','4', 'b','5', 50 | 'b','6', 'b','7', 'b','8', 'b','9', 'b','a', 'b','b', 'b','c', 'b','d', 'b','e', 'b','f', 'c','0', 'c','1', 'c','2', 51 | 'c','3', 'c','4', 'c','5', 'c','6', 'c','7', 'c','8', 'c','9', 'c','a', 'c','b', 'c','c', 'c','d', 'c','e', 'c','f', 52 | 'd','0', 'd','1', 'd','2', 'd','3', 'd','4', 'd','5', 'd','6', 'd','7', 'd','8', 'd','9', 'd','a', 'd','b', 'd','c', 53 | 'd','d', 'd','e', 'd','f', 'e','0', 'e','1', 'e','2', 'e','3', 'e','4', 'e','5', 'e','6', 'e','7', 'e','8', 'e','9', 54 | 'e','a', 'e','b', 'e','c', 'e','d', 'e','e', 'e','f', 'f','0', 'f','1', 'f','2', 'f','3', 'f','4', 'f','5', 'f','6', 55 | 'f','7', 'f','8', 'f','9', 'f','a', 'f','b', 'f','c', 'f','d', 'f','e', 'f','f', 56 | }; 57 | // clang-format on 58 | 59 | template 60 | static int encode(unsigned char (&in)[IN], unsigned char (&out)[OUT]) { 61 | static_assert(OUT >= 2 * IN, "output buffer must be at least double of input buffer"); 62 | for (;;) { 63 | auto got = fread(in, 1, std::size(in), stdin); 64 | if (got < 0) { 65 | fprintf(stderr, "error reading stdin\n"); 66 | return 1; 67 | } 68 | decltype(got) j = 0; 69 | for (decltype(got) i = 0; i < got; ++i) { 70 | out[j] = enc[2 * in[i]]; 71 | ++j; 72 | out[j] = enc[2 * in[i] + 1]; 73 | ++j; 74 | } 75 | if (fwrite(out, 1, j, stdout) < 0) { 76 | fprintf(stderr, "error writing to stdout\n"); 77 | return 1; 78 | } 79 | if (got != std::size(in)) { 80 | break; 81 | } 82 | } 83 | return 0; 84 | } 85 | 86 | template 87 | static int decode(unsigned char (&in)[IN], unsigned char (&out)[OUT]) { 88 | static_assert(OUT >= IN / 2, "output buffer must be at least half of input buffer"); 89 | for (;;) { 90 | auto got = fread(in, 1, std::size(in), stdin); 91 | if (got < 0) { 92 | fprintf(stderr, "error reading stdin\n"); 93 | return 1; 94 | } 95 | if (got & 1) { 96 | fprintf(stderr, "invalid encoding\n"); 97 | return 1; 98 | } 99 | decltype(got) j = 0; 100 | for (decltype(got) i = 0; i < got; i += 2) { 101 | unsigned char n0 = dec[in[i]]; 102 | if (n0 > 15) { 103 | fprintf(stderr, "invalid encoding\n"); 104 | return 1; 105 | } 106 | unsigned char n1 = dec[in[i + 1]]; 107 | out[j] = (n0 << 4) + n1; 108 | ++j; 109 | } 110 | if (fwrite(out, 1, j, stdout) < 0) { 111 | fprintf(stderr, "error writing to stdout\n"); 112 | return 1; 113 | } 114 | if (got != std::size(in)) { 115 | break; 116 | } 117 | } 118 | return 0; 119 | } 120 | 121 | // Print help message with program usage 122 | static void print_help(void) { 123 | fprintf(stderr, R"(Usage: 124 | hex [options] 125 | 126 | --encode 127 | encode hex from stdin to stdout 128 | 129 | --decode 130 | decode hex from stdin to stdout 131 | 132 | --prefix 133 | output 0x prefix when encoding and expect it when encoding 134 | 135 | --no-prefix 136 | do not add 0x prefix when encoding or expect 0x when decoding 137 | 138 | --help 139 | print this error message 140 | 141 | )"); 142 | } 143 | 144 | int main(int argc, char *argv[]) { 145 | unsigned char in[1024]; 146 | unsigned char out[2048]; 147 | bool dec = true; 148 | bool pre = true; 149 | for (int i = 1; i < argc; i++) { 150 | if (strcmp(argv[i], "--decode") == 0) { 151 | dec = true; 152 | } else if (strcmp(argv[i], "--encode") == 0) { 153 | dec = false; 154 | } else if (strcmp(argv[i], "--no-prefix") == 0) { 155 | pre = false; 156 | } else if (strcmp(argv[i], "--prefix") == 0) { 157 | pre = true; 158 | } else if (strcmp(argv[i], "--help") == 0) { 159 | print_help(); 160 | return 0; 161 | } 162 | } 163 | static const char *zx = "0x"; 164 | if (dec) { 165 | if (pre) { 166 | if (fread(in, 1, 2, stdin) != 2 || strncmp(reinterpret_cast(in), zx, 2) != 0) { 167 | fprintf(stderr, "expected prefix 0x\n"); 168 | return 1; 169 | } 170 | } 171 | return decode(in, out); 172 | } else { 173 | if (pre) { 174 | fwrite(zx, 1, 2, stdout); 175 | } 176 | return encode(in, out); 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /sys-utils/libcmt/doc/DoxygenLayout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | -------------------------------------------------------------------------------- /sys-utils/ioctl-echo-loop/ioctl-echo-loop.c: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "libcmt/rollup.h" 26 | 27 | static void help(const char *progname) { 28 | fprintf(stderr, 29 | "Usage: %s [options]\n" 30 | "Where options are: \n" 31 | " --vouchers= replicate input in n vouchers (default: 0)\n" 32 | " --delegate-call-vouchers= replicate input in n delegate call vouchers (default: 0)\n" 33 | " --notices= replicate input in n notices (default: 0)\n" 34 | " --reports= replicate input in n reports (default: 1)\n" 35 | " --reject= reject the nth input (default: -1)\n" 36 | " --reject-inspects reject all inspects\n" 37 | " --exception= cause an exception on the nth input (default: -1)\n" 38 | " --verbose= display information of structures (default: 0)\n", 39 | progname); 40 | 41 | exit(1); 42 | } 43 | 44 | struct parsed_args { 45 | unsigned voucher_count; 46 | unsigned delegate_call_vouchers; 47 | unsigned notice_count; 48 | unsigned report_count; 49 | unsigned verbose; 50 | unsigned reject; 51 | bool reject_inspects; 52 | unsigned exception; 53 | }; 54 | 55 | static int parse_token(const char *s, const char *fmt, bool *yes) { 56 | return *yes |= strcmp(fmt, s) == 0; 57 | } 58 | 59 | static int parse_number(const char *s, const char *fmt, unsigned *number) { 60 | int end = 0; 61 | if (sscanf(s, fmt, number, &end) != 1 || s[end] != 0) { 62 | return 0; 63 | } 64 | return 1; 65 | } 66 | 67 | static void parse_args(int argc, char *argv[], struct parsed_args *args) { 68 | int i = 0; 69 | const char *progname = argv[0]; 70 | 71 | memset(args, 0, sizeof(*args)); 72 | args->report_count = 1; 73 | args->reject = -1; 74 | args->reject_inspects = 0; 75 | args->exception = -1; 76 | 77 | for (i = 1; i < argc; i++) { 78 | if (!parse_number(argv[i], "--vouchers=%u%n", &args->voucher_count) && 79 | !parse_number(argv[i], "--delegate-call-vouchers=%u%n", &args->delegate_call_vouchers) && 80 | !parse_number(argv[i], "--notices=%u%n", &args->notice_count) && 81 | !parse_number(argv[i], "--reports=%u%n", &args->report_count) && 82 | !parse_number(argv[i], "--verbose=%u%n", &args->verbose) && 83 | !parse_token(argv[i], "--reject-inspects", &args->reject_inspects) && 84 | !parse_number(argv[i], "--exception=%u%n", &args->exception) && 85 | !parse_number(argv[i], "--reject=%u%n", &args->reject)) { 86 | help(progname); 87 | } 88 | } 89 | } 90 | 91 | static int finish_request(cmt_rollup_t *me, cmt_rollup_finish_t *finish, bool accept) { 92 | finish->accept_previous_request = accept; 93 | return cmt_rollup_finish(me, finish); 94 | } 95 | 96 | static int write_notices(cmt_rollup_t *me, unsigned count, cmt_abi_bytes_t *payload) { 97 | for (unsigned i = 0; i < count; i++) { 98 | int rc = cmt_rollup_emit_notice(me, payload, NULL); 99 | if (rc) 100 | return rc; 101 | } 102 | return 0; 103 | } 104 | 105 | static int write_vouchers(cmt_rollup_t *me, unsigned count, cmt_abi_address_t *destination, cmt_abi_bytes_t *payload) { 106 | cmt_abi_u256_t value = {{ 107 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 108 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xad, 0xbe, 0xef, 109 | }}; 110 | for (unsigned i = 0; i < count; i++) { 111 | int rc = cmt_rollup_emit_voucher(me, destination, &value, payload, NULL); 112 | if (rc) 113 | return rc; 114 | } 115 | return 0; 116 | } 117 | 118 | static int write_delegate_call_vouchers(cmt_rollup_t *me, unsigned count, cmt_abi_address_t *destination, cmt_abi_bytes_t *payload) { 119 | for (unsigned i = 0; i < count; i++) { 120 | int rc = cmt_rollup_emit_delegate_call_voucher(me, destination, payload, NULL); 121 | if (rc) 122 | return rc; 123 | } 124 | return 0; 125 | } 126 | 127 | static int write_reports(cmt_rollup_t *me, unsigned count, cmt_abi_bytes_t *payload) { 128 | for (unsigned i = 0; i < count; i++) { 129 | int rc = cmt_rollup_emit_report(me, payload); 130 | if (rc) 131 | return rc; 132 | } 133 | return 0; 134 | } 135 | 136 | static int handle_advance_state_request(cmt_rollup_t *me, struct parsed_args *args, uint64_t *index) { 137 | cmt_rollup_advance_t advance; 138 | int rc = cmt_rollup_read_advance_state(me, &advance); 139 | if (rc) 140 | return rc; 141 | *index = advance.index; 142 | fprintf(stderr, "advance with index %d\n", (int) advance.index); 143 | if (write_vouchers(me, args->voucher_count, &advance.msg_sender, &advance.payload) != 0) { 144 | return -1; 145 | } 146 | if (write_delegate_call_vouchers(me, args->delegate_call_vouchers, &advance.msg_sender, &advance.payload) != 0) { 147 | return -1; 148 | } 149 | if (write_notices(me, args->notice_count, &advance.payload) != 0) { 150 | return -1; 151 | } 152 | if (write_reports(me, args->report_count, &advance.payload) != 0) { 153 | return -1; 154 | } 155 | return 0; 156 | } 157 | 158 | static int handle_inspect_state_request(cmt_rollup_t *me, struct parsed_args *args) { 159 | cmt_rollup_inspect_t inspect; 160 | int rc = cmt_rollup_read_inspect_state(me, &inspect); 161 | if (rc) 162 | return rc; 163 | 164 | if (write_reports(me, args->report_count, &inspect.payload) != 0) { 165 | return -1; 166 | } 167 | return 0; 168 | } 169 | 170 | static int handle_request(cmt_rollup_t *me, struct parsed_args *args, cmt_rollup_finish_t *finish, uint64_t *index) { 171 | switch (finish->next_request_type) { 172 | case HTIF_YIELD_REASON_ADVANCE: 173 | return handle_advance_state_request(me, args, index); 174 | case HTIF_YIELD_REASON_INSPECT: 175 | return handle_inspect_state_request(me, args); 176 | default: 177 | /* unknown request type */ 178 | fprintf(stderr, "Unknown request type %d\n", finish->next_request_type); 179 | return -1; 180 | } 181 | return 0; 182 | } 183 | 184 | int main(int argc, char *argv[]) { 185 | cmt_rollup_t rollup; 186 | uint64_t advance_index = 0; 187 | 188 | if (cmt_rollup_init(&rollup)) 189 | return EXIT_FAILURE; 190 | 191 | struct parsed_args args; 192 | parse_args(argc, argv, &args); 193 | 194 | fprintf(stderr, "Echoing as %d voucher copies, %d notice copies, and %d report copies\n", args.voucher_count, 195 | args.notice_count, args.report_count); 196 | 197 | /* Accept the initial request */ 198 | cmt_rollup_finish_t finish; 199 | if (finish_request(&rollup, &finish, true) != 0) { 200 | exit(1); 201 | } 202 | 203 | /* handle a request, then wait for next */ 204 | for (;;) { 205 | bool reject_advance, reject_inspect, throw_exception; 206 | if (handle_request(&rollup, &args, &finish, &advance_index) != 0) { 207 | break; 208 | } 209 | reject_advance = (finish.next_request_type == HTIF_YIELD_REASON_ADVANCE) && (args.reject == advance_index); 210 | reject_inspect = (finish.next_request_type == HTIF_YIELD_REASON_INSPECT) && args.reject_inspects; 211 | throw_exception = (finish.next_request_type == HTIF_YIELD_REASON_ADVANCE) && (args.exception == advance_index); 212 | if (throw_exception) { 213 | char message[] = "exception"; 214 | const cmt_abi_bytes_t payload = { 215 | .data = message, 216 | .length = sizeof message - 1, 217 | }; 218 | cmt_rollup_emit_exception(&rollup, &payload); 219 | } 220 | if (finish_request(&rollup, &finish, !(reject_advance || reject_inspect)) != 0) { 221 | break; 222 | } 223 | } 224 | 225 | cmt_rollup_fini(&rollup); 226 | fprintf(stderr, "Exiting...\n"); 227 | return 0; 228 | } 229 | -------------------------------------------------------------------------------- /sys-utils/libcmt/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright Cartesi and individual authors (see AUTHORS) 2 | # 3 | # SPDX-License-Identifier: Apache-2.0 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | PREFIX ?= /usr 18 | CC := $(TOOLCHAIN_PREFIX)gcc 19 | AR := $(TOOLCHAIN_PREFIX)ar 20 | CFLAGS += -Wvla -O2 -g -Wall -Wextra -Iinclude \ 21 | -fno-strict-aliasing -fno-strict-overflow -fPIC 22 | LIBCMT_CFLAGS += -ftrivial-auto-var-init=zero -Wstrict-aliasing=3 23 | 24 | all: libcmt 25 | host: mock tools 26 | #------------------------------------------------------------------------------- 27 | examples_SRC := \ 28 | doc/examples/abi_encode_000.c \ 29 | doc/examples/abi_encode_001.c \ 30 | doc/examples/abi_encode_002.c \ 31 | doc/examples/abi_decode_000.c \ 32 | doc/examples/abi_decode_001.c \ 33 | doc/examples/abi_decode_002.c \ 34 | doc/examples/io.c \ 35 | doc/examples/rollup.c 36 | 37 | examples_OBJDIR := build/examples 38 | examples_OBJ := $(patsubst %.c,$(examples_OBJDIR)/%.o,$(examples_SRC)) 39 | 40 | $(examples_OBJ): $(examples_OBJDIR)/%.o: %.c 41 | @mkdir -p $(@D) 42 | $(CC) $(CFLAGS) -MT $@ -MMD -MP -MF $(@:.o=.d) -c -o $@ $< 43 | 44 | # no need to link, just ensure examples build correctly 45 | examples: $(examples_OBJ) 46 | 47 | #------------------------------------------------------------------------------- 48 | libcmt_SRC := \ 49 | src/buf.c \ 50 | src/abi.c \ 51 | src/keccak.c \ 52 | src/merkle.c \ 53 | src/rollup.c \ 54 | src/util.c \ 55 | src/io.c 56 | 57 | libcmt_OBJDIR := build/riscv64 58 | libcmt_OBJ := $(patsubst %.c,$(libcmt_OBJDIR)/%.o,$(libcmt_SRC)) 59 | libcmt_LIB := $(libcmt_OBJDIR)/libcmt.a 60 | libcmt_SO := $(libcmt_OBJDIR)/libcmt.so 61 | 62 | $(libcmt_OBJ): $(libcmt_OBJDIR)/%.o: %.c 63 | @mkdir -p $(@D) 64 | $(CC) $(CFLAGS) $(LIBCMT_CFLAGS) -MT $@ -MMD -MP -MF $(@:.o=.d) -c -o $@ $< 65 | 66 | $(libcmt_LIB): $(libcmt_OBJ) 67 | $(AR) rcs $@ $^ 68 | 69 | $(libcmt_SO): $(libcmt_OBJ) 70 | $(CC) -shared -o $@ $^ 71 | 72 | libcmt: $(libcmt_LIB) $(libcmt_SO) 73 | install-run: $(libcmt_SO) 74 | mkdir -p $(DESTDIR)$(PREFIX)/lib 75 | cp -f $(libcmt_SO) $(DESTDIR)$(PREFIX)/lib 76 | 77 | install-dev: $(libcmt_LIB) build/ffi.h 78 | mkdir -p $(DESTDIR)$(PREFIX)/lib 79 | cp -f $(libcmt_LIB) $(DESTDIR)$(PREFIX)/lib 80 | mkdir -p $(DESTDIR)$(PREFIX)/include/libcmt/ 81 | cp -f include/libcmt/*.h $(DESTDIR)$(PREFIX)/include/libcmt/ 82 | cp -f build/ffi.h $(DESTDIR)$(PREFIX)/include/libcmt/ 83 | mkdir -p $(DESTDIR)$(PREFIX)/lib/pkgconfig 84 | sed -e 's|@PREFIX@|$(PREFIX)|g' \ 85 | tools/libcmt.pc.in > $(DESTDIR)$(PREFIX)/lib/pkgconfig/libcmt.pc 86 | 87 | install: install-run install-dev 88 | 89 | #------------------------------------------------------------------------------- 90 | mock_SRC := \ 91 | src/abi.c \ 92 | src/buf.c \ 93 | src/keccak.c \ 94 | src/merkle.c \ 95 | src/rollup.c \ 96 | src/util.c \ 97 | src/io-mock.c 98 | 99 | mock_OBJDIR := build/mock 100 | mock_OBJ := $(patsubst %.c,$(mock_OBJDIR)/%.o,$(mock_SRC)) 101 | mock_LIB := $(mock_OBJDIR)/libcmt.a 102 | mock_SO := $(mock_OBJDIR)/libcmt.so 103 | 104 | $(mock_OBJ): $(mock_OBJDIR)/%.o: %.c 105 | @mkdir -p $(@D) 106 | $(CC) $(CFLAGS) -MT $@ -MMD -MP -MF $(@:.o=.d) -c -o $@ $< 107 | 108 | $(mock_LIB): $(mock_OBJ) 109 | $(AR) rcs $@ $^ 110 | 111 | $(mock_SO): $(mock_OBJ) 112 | $(CC) -shared -o $@ $^ 113 | 114 | mock: $(mock_LIB) $(mock_SO) 115 | 116 | install-mock: $(mock_LIB) $(mock_SO) build/ffi.h 117 | mkdir -p $(DESTDIR)$(PREFIX)/lib 118 | cp -f $(mock_LIB) $(mock_SO) $(DESTDIR)$(PREFIX)/lib 119 | mkdir -p $(DESTDIR)$(PREFIX)/include/libcmt/ 120 | cp -f include/libcmt/*.h $(DESTDIR)$(PREFIX)/include/libcmt/ 121 | cp -f build/ffi.h $(DESTDIR)$(PREFIX)/include/libcmt/ 122 | mkdir -p $(DESTDIR)$(PREFIX)/lib/pkgconfig 123 | sed -e 's|@ARG_PREFIX@|$(PREFIX)|g' tools/libcmt.pc.in > $(DESTDIR)$(PREFIX)/lib/pkgconfig/libcmt.pc 124 | 125 | #------------------------------------------------------------------------------- 126 | unittests_BINS := \ 127 | $(mock_OBJDIR)/abi-multi \ 128 | $(mock_OBJDIR)/abi-single \ 129 | $(mock_OBJDIR)/buf \ 130 | $(mock_OBJDIR)/gio \ 131 | $(mock_OBJDIR)/keccak \ 132 | $(mock_OBJDIR)/merkle \ 133 | $(mock_OBJDIR)/progress \ 134 | $(mock_OBJDIR)/rollup 135 | 136 | $(mock_OBJDIR)/abi-multi: tests/abi-multi.c $(mock_LIB) 137 | $(CC) $(CFLAGS) -o $@ $^ 138 | 139 | $(mock_OBJDIR)/abi-single: tests/abi-single.c $(mock_LIB) 140 | $(CC) $(CFLAGS) -o $@ $^ 141 | 142 | $(mock_OBJDIR)/buf: tests/buf.c $(mock_LIB) 143 | $(CC) $(CFLAGS) -o $@ $^ 144 | 145 | $(mock_OBJDIR)/keccak: tests/keccak.c $(mock_LIB) 146 | $(CC) $(CFLAGS) -o $@ $^ 147 | 148 | $(mock_OBJDIR)/merkle: tests/merkle.c $(mock_LIB) 149 | $(CC) $(CFLAGS) -o $@ $^ 150 | 151 | $(mock_OBJDIR)/gio: tests/gio.c tests/data.h $(mock_LIB) 152 | $(CC) -Itests $(CFLAGS) -o $@ $^ 153 | 154 | $(mock_OBJDIR)/rollup: tests/rollup.c tests/data.h $(mock_LIB) 155 | $(CC) -Itests $(CFLAGS) -o $@ $^ 156 | 157 | $(mock_OBJDIR)/progress: tests/progress.c $(mock_LIB) 158 | $(CC) -Itests $(CFLAGS) -o $@ $^ 159 | 160 | test: $(unittests_BINS) 161 | $(foreach test,$(unittests_BINS),$(test) &&) true 162 | 163 | tests/data.h: tests/create-data.sh 164 | $< > $@ 165 | 166 | #------------------------------------------------------------------------------- 167 | tools_OBJDIR := build/tools 168 | tools_BINS := \ 169 | $(tools_OBJDIR)/funsel 170 | 171 | $(tools_OBJDIR)/funsel: tools/funsel.c $(mock_LIB) 172 | @mkdir -p $(@D) 173 | $(CC) $(CFLAGS) -o $@ $^ 174 | 175 | tools: $(tools_BINS) 176 | 177 | HDRS := $(patsubst %,include/libcmt/%, buf.h abi.h keccak.h merkle.h io.h rollup.h) 178 | build/ffi.h: $(HDRS) 179 | cat $^ | sh tools/prepare-ffi.sh > $@ 180 | #------------------------------------------------------------------------------- 181 | LINTER_IGNORE_SOURCES=src/io.c 182 | LINTER_IGNORE_HEADERS= 183 | LINTER_SOURCES=$(filter-out $(LINTER_IGNORE_SOURCES),$(strip $(wildcard src/*.c) $(wildcard tests/*.c) $(wildcard tools/*.c))) 184 | LINTER_HEADERS=$(filter-out $(LINTER_IGNORE_HEADERS),$(strip $(wildcard src/*.h))) 185 | 186 | CLANG_TIDY=clang-tidy 187 | CLANG_TIDY_TARGETS=$(patsubst %.c,%.clang-tidy,$(LINTER_SOURCES)) 188 | 189 | CLANG_FORMAT=clang-format 190 | CLANG_FORMAT_FILES:=$(wildcard src/*.c) $(wildcard src/*.h) $(wildcard tests/*.c) $(wildcard tools/*.c) 191 | CLANG_FORMAT_IGNORE_FILES:= 192 | CLANG_FORMAT_FILES:=$(strip $(CLANG_FORMAT_FILES)) 193 | CLANG_FORMAT_FILES:=$(filter-out $(CLANG_FORMAT_IGNORE_FILES),$(strip $(CLANG_FORMAT_FILES))) 194 | 195 | EMPTY:= 196 | SPACE:=$(EMPTY) $(EMPTY) 197 | CLANG_TIDY_HEADER_FILTER=$(CURDIR)/($(subst $(SPACE),|,$(LINTER_HEADERS))) 198 | 199 | %.clang-tidy: %.c 200 | @$(CLANG_TIDY) --header-filter='$(CLANG_TIDY_HEADER_FILTER)' $< -- $(CFLAGS) 2>/dev/null 201 | @$(CC) $(CFLAGS) $< -MM -MT $@ -MF $@.d > /dev/null 2>&1 202 | @touch $@ 203 | 204 | clangd-config: 205 | @echo "$(CFLAGS)" | sed -e $$'s/ \{1,\}/\\\n/g' | grep -v "MMD" > compile_flags.txt 206 | 207 | format: 208 | @$(CLANG_FORMAT) -i $(CLANG_FORMAT_FILES) 209 | 210 | check-format: 211 | @$(CLANG_FORMAT) -Werror --dry-run $(CLANG_FORMAT_FILES) 212 | 213 | lint: $(CLANG_TIDY_TARGETS) 214 | 215 | #------------------------------------------------------------------------------- 216 | 217 | help: 218 | @echo "Targets: (default: '*')" 219 | @echo "* all - Build libcmt and host targets" 220 | @echo " host - Build mock and tools targets" 221 | @echo " libcmt - Build the library, tools and examples; to run on the cartesi-machine." 222 | @echo " (requires the cartesi Linux headers to build)" 223 | @echo " mock - Build a mocked version of the library, tools and examples; to run on the host system." 224 | @echo " tools - Build tools on top of the mocked library to run on the host system." 225 | @echo " test - Build and run tests on top of the mocked library on the host system." 226 | @echo " doc - Build the documentation and API references as html." 227 | @echo " clean - remove the binaries and objects." 228 | @echo " install - Install the library and C headers; on the host system." 229 | @echo " Use DESTDIR and PREFIX to customize the installation." 230 | @echo " install-mock - Install the mocked version of the library and C headers; on the host system." 231 | @echo " Use DESTDIR and PREFIX to customize the installation." 232 | 233 | doc/theme: 234 | git clone git@github.com:jothepro/doxygen-awesome-css.git $@ 235 | git -C doc/theme checkout 8cea9a073ecd50a5b2c0958a3df100292d6c7374 236 | 237 | doc: doc/theme examples 238 | doxygen doc/Doxyfile 239 | 240 | clean: 241 | @rm -rf build 242 | @rm -rf src/*.clang-tidy src/*.d 243 | @rm -rf tests/*.clang-tidy tests/*.d 244 | @rm -rf tools/*.clang-tidy tools/*.d 245 | @rm -rf *.bin 246 | 247 | distclean: clean 248 | @rm -rf doc/html doc/theme 249 | @rm -rf compile_flags.txt 250 | 251 | OBJ := $(mock_OBJ) $(libcmt_OBJ) $(examples_OBJ) $(tools_OBJ) 252 | 253 | .PHONY: install install-run install-dev 254 | -include $(OBJ:%.o=%.d) 255 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## [Unreleased] 8 | 9 | ## [0.17.2] - 2025-10-21 10 | ### Changed 11 | - Improved advances performance by caching the outputs Merkle hash when no new outputs are added 12 | 13 | ### Fixed 14 | - Fix /etc/shadow- determinism when installing guest tools 15 | 16 | ## [0.17.1] - 2025-05-27 17 | ### Added 18 | - Added strace to guest-tools rootfs 19 | 20 | ### Fixed 21 | - Fixed non-deterministic behavior when creating the dapp user 22 | 23 | ## [0.17.0] - 2025-04-25 24 | ### Added 25 | - Allow compiling inside riscv64 environment without cross compilation 26 | - Allow to install all tools with `make install` 27 | - Added delegate call voucher to rollup tools and libcmt 28 | 29 | ### Changed 30 | - Bump dependencies versions 31 | - Generate `rootfs-tools.ext2.html` with licenses of all installed packages 32 | - Bump Ubuntu to 24.04 LTS 33 | - Rename repository to machine-guest-tools 34 | - Simplified build system to make packaging easier 35 | - Binaries are not automatically stripped anymore, this should be done when packaging 36 | - Remove all references to `cartesi/toolchain` Docker image 37 | - Avoid using `cttyhack` in `cartesi-init` to support Alpine Linux 38 | - Increased JsonConfig limit in `rollup-http-server` 39 | - Removed pinning of package versions from all Dockerfiles 40 | 41 | ## [0.16.1] - 2024-08-12 42 | ### Fixed 43 | - Fixed curl version on rootfs 44 | - Fixed openapi spec dependency version in the CI test 45 | 46 | ## [0.16.0] - 2024-07-26 47 | ### Changed 48 | - Updated xgenext2fs to v1.5.6 49 | - Updated migrated from output unification v1 to v2 50 | - Fixed inconsistencies in the http server api 51 | - Updated CI actions versions 52 | 53 | ## [0.15.0] - 2024-04-19 54 | ### Added 55 | - Implemented a new libcmt library to interface with the Cartesi machine device 56 | - Added generic IO entrypoint to libcmt 57 | - Added generic IO endpoint on rollup-http-server 58 | - Allowed customization of init with `/etc/cartesi-init.d` 59 | - Allowed init to run in empty filesystems 60 | - Introduced a new libcmt development Debian package as a regular artifact in releases 61 | 62 | ### Changed 63 | - Added `stty -onlcr` to cartesi-init 64 | - Set default USER to dapp in init script 65 | - Created dapp user when installing tools package 66 | - Removed unnecessary PATH change from init script 67 | - Added a value field to vouchers 68 | - Updated kernel to v6.5.13-ctsi-1 69 | - Renamed kernel device 70 | - Implemented Rollup-HTTP based on libcmt 71 | - Rewrote yield with libcmt 72 | - Rewrote Rollup with libcmt 73 | - Updated Rollup-HTTP Rust dependencies 74 | - Bumped Rustc to 1.77.2 75 | - Updated the version of some workflow actions 76 | - Added BusyBox dependency to Deb package 77 | - Updated xgenext2fs to v1.5.5 78 | 79 | ### Removed 80 | - Removed old build-with-toolchain script 81 | 82 | ### Fixed 83 | - Fixed a bug where Docker builds would incorrectly succeed even when commands in the `RUN` directive failed. 84 | 85 | ## [0.14.1] - 2023-12-18 86 | ### Fixed 87 | - Fix rootfs.ext2 build, xxd pinned version was not available in the repository 88 | 89 | ## [0.14.0] - 2023-12-13 90 | ### Changed 91 | - Make rootfs the default target 92 | - Reorganized repository structure 93 | - Use image-kernel Linux headers package 94 | - Cross-compiled sys-utils 95 | - Built rust binaries dependencies in a separate stage 96 | - Cleaned up Dockerfile and Makefile 97 | - Update toolchain to 0.16.0 98 | 99 | ### Added 100 | - Added support for building rootfs.ext2 (breaking change) 101 | - Added dhrystone and whetstone benchmarks on fs 102 | - Added extra packages to rootfs 103 | - Cross-compiled rust application binaries 104 | 105 | ### Removed 106 | - Removed example directory 107 | 108 | ## [0.13.0] - 2023-10-10 109 | ### Changed 110 | - Updated tools version in example 111 | 112 | ### Added 113 | - Added new init system using init and entrypoint from device tree 114 | - Added a sha512sums.txt to release artifacts 115 | - Added support for forwarding application exit status 116 | 117 | ## [0.12.0] - 2023-08-14 118 | ### Changed 119 | - Cache build in CI 120 | - Generate binary deb with tools 121 | - Moved sbin/init -> opt/cartesi/sbin/init 122 | - Updated license/copyright notice in all source code 123 | - Update toolchain to 0.15.0 124 | 125 | ## [0.11.0] - 2023-04-19 126 | ### Changed 127 | - Fixed rollups-http-server when it receives an inspect with 0 bytes 128 | - Updated linux-sources to v5.15.63-ctsi-2 129 | - Update toolchain to 0.14.0 130 | - Renamed voucher field: address -> destination 131 | 132 | ## [0.10.0] - 2023-02-15 133 | ### Changed 134 | - Moved skel/ from rootfs to this repository 135 | - Build tools in a riscv64/ubuntu:22.04 image and pack them with skel/ 136 | - Compile tools using compressed instructions 137 | - Updated toolchain to v0.13.0 138 | - Updated CI image to Ubuntu 22.04 139 | 140 | ## [0.9.0] - 2022-11-17 141 | ### Changed 142 | - Compile tools using floating-point instructions 143 | - Update toolchain to v0.12.0 144 | 145 | ## [0.8.0] - 2022-08-29 146 | ### Changed 147 | - Fix rollup-http-server printout 148 | - Remove Dehash command line tool 149 | - Remove timestamp from logs 150 | - Update toolchain to v0.11.0 151 | 152 | ## [0.7.0] - 2022-06-27 153 | ### Changed 154 | - Improved error handling in rollup command line tool 155 | - Fixed indentation in rollup command line tool 156 | - Removed explicit strip feature from Cargo.toml files 157 | - Moved dapp initialization from rollup-init to rollup-http-server 158 | - Simplified rollup-init script to only call rollup-http-server 159 | - Handled rollup-http-server exit status in rollup-init 160 | - Handled dapp exit status in rollup-http-server 161 | - Updated regex crate on rollup-http-server and echo-dapp to address CVE-2022-24713 162 | 163 | ## [0.6.0] - 2022-04-20 164 | ### Added 165 | - Added new rollup command line tool 166 | - Added ioctl-echo-loop and rollup tools to CI 167 | - Added rollup-exception handling to ioctl-echo-loop 168 | - Added --reject-inspects as an option to ioctl-echo-loop and echo dapp 169 | - Added exception to rollup-http-server and echo-dapp 170 | - Added rollup http server and echo dapp CI build 171 | - Added tests for rollup http server and echo dapp client 172 | 173 | ### Changed 174 | - Update toolchain to v0.9.0 175 | - Enabled rollup-exception in rollup 176 | - Updated yield to the new yield\_request format 177 | - Removed --ack from yield 178 | - Rename http-dispatcher to rollup-http-server 179 | - Switch rollup-http-server to server only and echo-dapp to client only implementation 180 | 181 | ## [0.5.1] - 2022-02-22 182 | ### Changed 183 | - Lock dependencies versions using Cargo.lock on http-dispatcher and echo-dapp 184 | - Fix --reject option on ioctl-echo-loop 185 | 186 | ## [0.5.0] - 2022-01-13 187 | ### Changed 188 | - Updated http-dispatcher and echo-dapp according to openapi-interfaces changes 189 | - Remove index from voucher and notice http-requests on http-dispatcher and echo-dapp 190 | - Fixed http-dispatcher payload handling 191 | 192 | ## [0.4.1] - 2021-12-29 193 | ### Changed 194 | - Fixed deadlock on http-dispatcher 195 | 196 | ## [0.4.0] - 2021-12-21 197 | ### Added 198 | - New ioctl-echo-loop tool to test rollups 199 | - New rollup http-dispatcher 200 | - New echo dapp based on the http-dispatcher architecture 201 | 202 | ### Changed 203 | - Updated yield command line tool to be compatible with Linux kernel v5.5.19-ctsi-3 204 | 205 | ## [Previous Versions] 206 | - [0.3.0] 207 | - [0.2.0] 208 | - [0.1.0] 209 | 210 | [Unreleased]: https://github.com/cartesi/machine-guest-tools/compare/v0.17.2...HEAD 211 | [0.17.2]: https://github.com/cartesi/machine-guest-tools/releases/tag/v0.17.2 212 | [0.17.1]: https://github.com/cartesi/machine-guest-tools/releases/tag/v0.17.1 213 | [0.17.0]: https://github.com/cartesi/machine-guest-tools/releases/tag/v0.17.0 214 | [0.16.1]: https://github.com/cartesi/machine-guest-tools/releases/tag/v0.16.1 215 | [0.16.0]: https://github.com/cartesi/machine-guest-tools/releases/tag/v0.16.0 216 | [0.15.0]: https://github.com/cartesi/machine-guest-tools/releases/tag/v0.15.0 217 | [0.14.1]: https://github.com/cartesi/machine-guest-tools/releases/tag/v0.14.1 218 | [0.14.0]: https://github.com/cartesi/machine-guest-tools/releases/tag/v0.14.0 219 | [0.13.0]: https://github.com/cartesi/machine-guest-tools/releases/tag/v0.13.0 220 | [0.12.0]: https://github.com/cartesi/machine-guest-tools/releases/tag/v0.12.0 221 | [0.11.0]: https://github.com/cartesi/machine-guest-tools/releases/tag/v0.11.0 222 | [0.10.0]: https://github.com/cartesi/machine-guest-tools/releases/tag/v0.10.0 223 | [0.9.0]: https://github.com/cartesi/machine-guest-tools/releases/tag/v0.9.0 224 | [0.8.0]: https://github.com/cartesi/machine-guest-tools/releases/tag/v0.8.0 225 | [0.7.0]: https://github.com/cartesi/machine-guest-tools/releases/tag/v0.7.0 226 | [0.6.0]: https://github.com/cartesi/machine-guest-tools/releases/tag/v0.6.0 227 | [0.5.1]: https://github.com/cartesi/machine-guest-tools/releases/tag/v0.5.1 228 | [0.5.0]: https://github.com/cartesi/machine-guest-tools/releases/tag/v0.5.0 229 | [0.4.1]: https://github.com/cartesi/machine-guest-tools/releases/tag/v0.4.1 230 | [0.4.0]: https://github.com/cartesi/machine-guest-tools/releases/tag/v0.4.0 231 | [0.3.0]: https://github.com/cartesi/machine-guest-tools/releases/tag/v0.3.0 232 | [0.2.0]: https://github.com/cartesi/machine-guest-tools/releases/tag/v0.2.0 233 | [0.1.0]: https://github.com/cartesi/machine-guest-tools/releases/tag/v0.1.0 234 | --------------------------------------------------------------------------------