-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
mock: components can be compiled natively: 1. make mock tests ioctl: require the cartesi headers and a riscv compiler: 1. Build or download a compatible kernel and `.deb` headers 2. Setup a cross compilation debian environment by running the setup[1] script. 3. `make ioctl CROSS_COMPILE=riscv64-linux-gnu-` [1] setup.sh ``` apt update && \ DEBIAN_FRONTEND="noninteractive" apt-get install --no-install-recommends --allow-downgrades -y \ bc \ bison \ build-essential \ flex \ genext2fs \ rsync \ gcc-riscv64-linux-gnu \ libc6-dev-riscv64-cross \ ./linux-libc-dev-riscv64-cross-6.5.9-ctsi-1-v0.0.0.deb ```
- Loading branch information
Showing
44 changed files
with
5,878 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
CC := $(CROSS_COMPILE)gcc | ||
AR := $(CROSS_COMPILE)ar | ||
CFLAGS := -O2 -g -Wall -pedantic | ||
|
||
#all: mock tests | ||
#mock: libmock.a $(mock_BINS) | ||
#ioctl: libioctl.a $(ioctl_BINS) | ||
#tests: tests/abi tests/keccak tests/merkle | ||
#tools: tools/merkle-zero-table tools/funsel | ||
|
||
help: | ||
@echo "Cleaning targets:" | ||
@echo " clean - remove the binaries and objects." | ||
@echo " mock - build a reference mock library and examples for running in host mode." | ||
@echo " ioctl - build the actual ioctl library and examples." | ||
@echo " tools - build additional utilities for development." | ||
@echo " with CROSS_COMPILE=" | ||
|
||
mock: libmock.a mock/yield mock/rollup-driver mock/rollup | ||
ioctl: libioctl.a ioctl/yield ioctl/rollup-driver ioctl/rollup | ||
tests: tests/abi tests/keccak tests/merkle | ||
|
||
base_SRC := \ | ||
base/buf.c \ | ||
base/abi.c \ | ||
base/keccak.c \ | ||
base/merkle.c \ | ||
base/rollup.c | ||
|
||
libmock_SRC := \ | ||
mock/rollup-driver.c \ | ||
mock/yield-driver.c \ | ||
$(base_SRC) | ||
|
||
libioctl_SRC := \ | ||
ioctl/rollup-driver.c \ | ||
ioctl/yield-driver.c \ | ||
$(base_SRC) | ||
|
||
libmock_OBJDIR := build/libmock/ | ||
libioctl_OBJDIR := build/libioctl/ | ||
|
||
libmock_OBJ := $(patsubst %.c,$(libmock_OBJDIR)%.o,$(libmock_SRC)) | ||
libioctl_OBJ := $(patsubst %.c,$(libioctl_OBJDIR)%.o,$(libioctl_SRC)) | ||
|
||
OBJ := $(libmock_OBJ) $(libioctl_OBJ) | ||
|
||
$(libmock_OBJ): $(libmock_OBJDIR)%.o: %.c | ||
@mkdir -p $(@D) | ||
$(CC) $(CFLAGS) -Imock -MT $@ -MMD -MP -MF $(@:.o=.d) -c -o $@ $< | ||
|
||
$(libioctl_OBJ): $(libioctl_OBJDIR)%.o: %.c | ||
@mkdir -p $(@D) | ||
$(CC) $(CFLAGS) -Iioctl -MT $@ -MMD -MP -MF $(@:.o=.d) -c -o $@ $< | ||
|
||
libmock.a: $(libmock_OBJ) | ||
$(AR) rcs $@ $^ | ||
|
||
libioctl.a: $(libioctl_OBJ) | ||
$(AR) rcs $@ $^ | ||
|
||
ioctl/yield-driver: examples/yield-driver.c libioctl.a | ||
$(CC) $(CFLAGS) -Iioctl -o $@ $^ | ||
ioctl/merkle: examples/merkle.c libmock.a | ||
$(CC) $(CFLAGS) -Iioctl -o $@ $^ | ||
ioctl/rollup-driver: examples/rollup-driver.c libioctl.a | ||
$(CC) $(CFLAGS) -Iioctl -o $@ $^ | ||
|
||
mock/yield-driver: examples/yield-driver.c libmock.a | ||
$(CC) $(CFLAGS) -Imock -o $@ $^ | ||
mock/rollup-driver: examples/rollup-driver.c libmock.a | ||
$(CC) $(CFLAGS) -Imock -o $@ $^ | ||
mock/rollup: examples/rollup.c libmock.a | ||
$(CC) $(CFLAGS) -Imock -o $@ $^ | ||
|
||
tests/abi: tests/abi.c libmock.a | ||
$(CC) $(CFLAGS) -Imock -o $@ $^ | ||
tests/keccak: tests/keccak.c libmock.a | ||
$(CC) $(CFLAGS) -Imock -o $@ $^ | ||
tests/merkle: tests/merkle.c libmock.a | ||
$(CC) $(CFLAGS) -Imock -o $@ $^ | ||
|
||
tools/merkle-zero-table: tools/merkle-zero-table.c base/keccak.o | ||
$(CC) $(CFLAGS) -Imock -o $@ $^ | ||
tools/funsel: tools/funsel.c base/keccak.o | ||
$(CC) $(CFLAGS) -Imock -o $@ $^ | ||
|
||
doc: doc/theme | ||
doxygen doc/Doxyfile | ||
doc/theme: | ||
git clone --depth=1 --branch=v2.2.1 \ | ||
[email protected]:jothepro/doxygen-awesome-css.git $@ | ||
clean: | ||
rm -f libmock.a $(mock_BINS) libioctl.a $(ioctl_BINS) $(OBJ) $(OBJ:%.o=%.d) | ||
rm -rf doc/html | ||
distclean: | ||
rm -rf doc/theme | ||
.PHONY: doc | ||
|
||
-include $(OBJ:%.o=%.d) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
Utility functions for rollup interaction. | ||
|
||
- @ref libevm\_rollup | ||
- @ref libevm\_abi | ||
- @ref libevm\_buf | ||
- @ref libevm\_keccak | ||
- @ref libevm\_merkle | ||
|
||
Thin wrappers to the cartesi kernel drivers | ||
|
||
- @ref rollup\_driver | ||
- @ref yield\_driver | ||
|
||
# Getting Started | ||
|
||
Download the static library from [cartesi tools](https://github.com/cartesi/machine-emulator-tools/). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,232 @@ | ||
#include <errno.h> | ||
#include <string.h> | ||
#include "abi.h" | ||
|
||
uintptr_t align(uintptr_t p, size_t a) | ||
{ | ||
return (p + (a-1)) & ~(a-1); | ||
} | ||
|
||
uint32_t evm_abi_funsel(uint8_t a, uint8_t b, uint8_t c, uint8_t d) | ||
{ | ||
return EVM_ABI_FUNSEL(a, b, c, d); | ||
} | ||
|
||
int evm_abi_put_funsel(evm_buf_t *me, uint32_t funsel) | ||
{ | ||
int rc; | ||
evm_buf_t x[1]; | ||
if ((rc = evm_buf_split(me, sizeof(funsel), x, me))) | ||
return rc; | ||
memcpy(x->p, &funsel, sizeof(funsel)); | ||
return 0; | ||
} | ||
|
||
int evm_abi_enc_uint_nr(size_t n, const uint8_t data[n], uint8_t out[EVM_WORD_LEN]) | ||
{ | ||
if (n > EVM_WORD_LEN) return EDOM; | ||
|
||
for (int i=0; i<n; ++i) | ||
out[EVM_WORD_LEN-1-i] = data[i]; | ||
for (int i=n; i<EVM_WORD_LEN; ++i) | ||
out[EVM_WORD_LEN-1-i] = 0; | ||
|
||
return 0; | ||
} | ||
|
||
int evm_abi_enc_uint_nn(size_t n, const uint8_t data[n], uint8_t out[EVM_WORD_LEN]) | ||
{ | ||
if (n > EVM_WORD_LEN) return EDOM; | ||
|
||
for (int i=0; i<EVM_WORD_LEN-n; ++i) | ||
out[i] = 0; | ||
for (int i=EVM_WORD_LEN-n; i<EVM_WORD_LEN; ++i) | ||
out[i] = data[i-EVM_WORD_LEN+n]; | ||
|
||
return 0; | ||
} | ||
|
||
int evm_abi_enc_uint(size_t n, const void *data, uint8_t out[EVM_WORD_LEN]) | ||
{ | ||
#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ | ||
return evm_abi_enc_uint_nn(n, data, out); | ||
#else | ||
return evm_abi_enc_uint_nr(n, data, out); | ||
#endif | ||
} | ||
|
||
int evm_abi_dec_uint_nr(const uint8_t data[EVM_WORD_LEN], size_t n, uint8_t out[n]) | ||
{ | ||
for (int i=0; i<EVM_WORD_LEN-n; ++i) if (data[i]) | ||
return -EDOM; | ||
for (int i=EVM_WORD_LEN-n; i<EVM_WORD_LEN; ++i) | ||
out[EVM_WORD_LEN-1-i] = data[i]; | ||
return 0; | ||
} | ||
|
||
int evm_abi_dec_uint_nn(const uint8_t data[EVM_WORD_LEN], size_t n, uint8_t out[n]) | ||
{ | ||
for (int i=0; i<EVM_WORD_LEN-n; ++i) if (data[i]) | ||
return -EDOM; | ||
for (int i=EVM_WORD_LEN-n; i<EVM_WORD_LEN; ++i) | ||
out[i-EVM_WORD_LEN+n] = data[i]; | ||
return 0; | ||
} | ||
|
||
int evm_abi_dec_uint(const uint8_t data[EVM_WORD_LEN], size_t n, uint8_t out[n]) | ||
{ | ||
#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ | ||
return evm_abi_dec_uint_nn(data, n, out); | ||
#else | ||
return evm_abi_dec_uint_nr(data, n, out); | ||
#endif | ||
} | ||
|
||
int evm_abi_put_uint(evm_buf_t *me, size_t n, const void *data) | ||
{ | ||
evm_buf_t x; | ||
|
||
if (n > EVM_WORD_LEN) | ||
return -EDOM; | ||
if (evm_buf_split(me, EVM_WORD_LEN, &x, me)) | ||
return -ENOBUFS; | ||
|
||
evm_abi_enc_uint(n, data, x.p); | ||
return 0; | ||
} | ||
|
||
int evm_abi_put_bool(evm_buf_t *me, bool value) | ||
{ | ||
uint8_t boolean = !!value; | ||
return evm_abi_put_uint(me, sizeof(boolean), &boolean); | ||
} | ||
|
||
int evm_abi_put_address(evm_buf_t *me, const uint8_t data[20]) | ||
{ | ||
evm_buf_t x; | ||
|
||
if (evm_buf_split(me, EVM_WORD_LEN, &x, me)) | ||
return -ENOBUFS; | ||
|
||
evm_abi_enc_uint_nn(EVM_ADDRESS_LEN, data, x.p); | ||
return 0; | ||
} | ||
|
||
int evm_abi_put_bytes_s(evm_buf_t *me, evm_buf_t *offset) | ||
{ | ||
return evm_buf_split(me, EVM_WORD_LEN, offset, me); | ||
} | ||
|
||
int evm_abi_res_bytes_d(evm_buf_t *me, evm_buf_t *of, size_t n, evm_buf_t *out, const void *start) | ||
{ | ||
int rc; | ||
evm_buf_t sz[1]; | ||
size_t n32 = align(n, EVM_WORD_LEN); | ||
|
||
if ((rc = evm_buf_split(me, EVM_WORD_LEN, sz, me))) | ||
return rc; | ||
if ((rc = evm_buf_split(me, n32, out, me))) | ||
return rc; | ||
|
||
size_t offset = sz->p - (uint8_t *)start; | ||
evm_abi_enc_uint(sizeof(offset), &offset, of->p); | ||
evm_abi_enc_uint(sizeof(n), &n, sz->p); | ||
memset(out->p + n, 0, n32 - n); | ||
return 0; | ||
} | ||
|
||
int evm_abi_put_bytes_d(evm_buf_t *me, evm_buf_t *offset, size_t n, const void *data, const void *start) | ||
{ | ||
int rc; | ||
evm_buf_t res[1]; | ||
|
||
if ((rc = evm_abi_res_bytes_d(me, offset, n, res, start))) | ||
return rc; | ||
|
||
memcpy(res->p, data, n); | ||
return 0; | ||
} | ||
|
||
uint32_t evm_abi_peek_funsel(evm_buf_t *me) | ||
{ | ||
if (evm_buf_length(me) < 4) | ||
return 0; | ||
return EVM_ABI_FUNSEL(me->p[0], me->p[1], me->p[2], me->p[3]); | ||
} | ||
|
||
int evm_abi_check_funsel(evm_buf_t *me, uint32_t expected) | ||
{ | ||
if (evm_buf_length(me) < 4) | ||
return ENOBUFS; | ||
|
||
if (evm_abi_peek_funsel(me) != expected) | ||
return EBADMSG; | ||
|
||
me->p += 4; | ||
return 0; | ||
} | ||
|
||
int evm_abi_get_uint(evm_buf_t *me, size_t n, void *data) | ||
{ | ||
int rc; | ||
evm_buf_t x[1]; | ||
|
||
if (n > EVM_WORD_LEN) | ||
return -EDOM; | ||
if ((rc = evm_buf_split(me, EVM_WORD_LEN, x, me))) | ||
return rc; | ||
|
||
return evm_abi_dec_uint(x->p, n, data); | ||
} | ||
|
||
int evm_abi_get_bool(evm_buf_t *me, bool *value) | ||
{ | ||
int rc; | ||
uint8_t boolean = 0; | ||
if ((rc = evm_abi_put_uint(me, sizeof(boolean), &boolean))) | ||
return rc; | ||
*value = boolean; | ||
return 0; | ||
} | ||
|
||
int evm_abi_get_address(evm_buf_t *me, uint8_t address[EVM_ADDRESS_LEN]) | ||
{ | ||
int rc; | ||
evm_buf_t x[1]; | ||
|
||
if ((rc = evm_buf_split(me, EVM_WORD_LEN, x, me))) | ||
return rc; | ||
|
||
return evm_abi_dec_uint_nn(x->p, EVM_ADDRESS_LEN, address); | ||
} | ||
|
||
int evm_abi_get_bytes_s(evm_buf_t *me, evm_buf_t of[1]) | ||
{ | ||
return evm_buf_split(me, EVM_WORD_LEN, of, me); | ||
} | ||
|
||
int evm_abi_peek_bytes_d(const evm_buf_t *start, evm_buf_t of[1], evm_buf_t *bytes) | ||
{ | ||
int rc; | ||
uint64_t offset, size; | ||
if ((rc = evm_abi_get_uint(of, sizeof(offset), &offset))) | ||
return rc; | ||
|
||
/* from the beginning, after funsel */ | ||
evm_buf_t it[1] = {{start->p + offset, start->q}}; | ||
if ((rc = evm_abi_get_uint(it, sizeof(size), &size))) | ||
return rc; | ||
|
||
return evm_buf_split(it, size, bytes, it); | ||
} | ||
|
||
int evm_abi_get_bytes_d(const evm_buf_t *me, evm_buf_t of[1], size_t *n, void **data) | ||
{ | ||
int rc; | ||
evm_buf_t bytes[1]; | ||
if ((rc = evm_abi_peek_bytes_d(me, of, bytes))) | ||
return rc; | ||
*n = evm_buf_length(bytes); | ||
*data = bytes->p; | ||
return 0; | ||
} |
Oops, something went wrong.