From 6e64cc24937ddb00b7b58e2da3daa24a368625d8 Mon Sep 17 00:00:00 2001 From: Marcelo Politzer <251334+mpolitzer@users.noreply.github.com> Date: Mon, 29 Jan 2024 11:03:06 -0300 Subject: [PATCH] feat!: add value to voucher --- sys-utils/ioctl-echo-loop/Makefile | 7 +- sys-utils/ioctl-echo-loop/ioctl-echo-loop.c | 2 +- sys-utils/libcmt/README.md | 231 ++++++ sys-utils/libcmt/doc/examples/abi_multi.c | 52 ++ sys-utils/libcmt/doc/examples/rollup.c | 2 +- sys-utils/libcmt/include/libcmt/abi.h | 213 +++-- sys-utils/libcmt/include/libcmt/rollup.h | 119 ++- sys-utils/libcmt/src/abi.c | 23 + sys-utils/libcmt/src/mock/io.c | 27 +- sys-utils/libcmt/src/rollup.c | 22 +- sys-utils/libcmt/src/tests/abi-single.c | 844 +++----------------- sys-utils/libcmt/src/tests/rollup_echo.c | 23 +- sys-utils/rollup/Makefile | 7 +- sys-utils/rollup/rollup.cpp | 27 +- sys-utils/yield/Makefile | 7 +- 15 files changed, 742 insertions(+), 864 deletions(-) create mode 100644 sys-utils/libcmt/doc/examples/abi_multi.c diff --git a/sys-utils/ioctl-echo-loop/Makefile b/sys-utils/ioctl-echo-loop/Makefile index 6319e654..7f03a8ca 100644 --- a/sys-utils/ioctl-echo-loop/Makefile +++ b/sys-utils/ioctl-echo-loop/Makefile @@ -28,10 +28,8 @@ RVCXX = $(TOOLCHAIN_PREFIX)g++ RVCOPY = $(TOOLCHAIN_PREFIX)objcopy RVDUMP = $(TOOLCHAIN_PREFIX)objdump STRIP = $(TOOLCHAIN_PREFIX)strip -CFLAGS :=-Wall -Wextra -pedantic -O2 \ - `PKG_CONFIG_PATH=/usr/riscv64-linux-gnu/lib/pkgconfig pkg-config --cflags libcmt` -LDLIBS := \ - `PKG_CONFIG_PATH=/usr/riscv64-linux-gnu/lib/pkgconfig pkg-config --libs libcmt` +CFLAGS +=-Wall -Wextra -pedantic -O2 `pkg-config --cflags libcmt` +LDLIBS += `pkg-config --libs libcmt` CONTAINER_MAKE := /usr/bin/make CONTAINER_BASE := /opt/cartesi/tools @@ -45,6 +43,7 @@ ioctl-echo-loop.with-toolchain with-toolchain: extra.ext2.with-toolchain: $(MAKE) toolchain-exec CONTAINER_COMMAND="$(CONTAINER_MAKE) $@.toolchain" +ioctl-echo-loop: export PKG_CONFIG_PATH ?= /usr/riscv64-linux-gnu/lib/pkgconfig ioctl-echo-loop: ioctl-echo-loop.c $(RVCC) $(CFLAGS) -o ioctl-echo-loop ioctl-echo-loop.c $(LDLIBS) $(STRIP) ioctl-echo-loop diff --git a/sys-utils/ioctl-echo-loop/ioctl-echo-loop.c b/sys-utils/ioctl-echo-loop/ioctl-echo-loop.c index 00d72dcc..2b3d206e 100644 --- a/sys-utils/ioctl-echo-loop/ioctl-echo-loop.c +++ b/sys-utils/ioctl-echo-loop/ioctl-echo-loop.c @@ -103,7 +103,7 @@ static int write_notices(cmt_rollup_t *me, unsigned count, uint32_t length, cons static int write_vouchers(cmt_rollup_t *me, unsigned count, uint8_t destination[CMT_ADDRESS_LENGTH] ,uint32_t length, const void *data) { for (unsigned i = 0; i < count; i++) { - int rc = cmt_rollup_emit_voucher(me, destination, length, data); + int rc = cmt_rollup_emit_voucher(me, CMT_ADDRESS_LENGTH, destination, 0, NULL, length, data); if (rc) return rc; } return 0; diff --git a/sys-utils/libcmt/README.md b/sys-utils/libcmt/README.md index 2f80b968..582db807 100644 --- a/sys-utils/libcmt/README.md +++ b/sys-utils/libcmt/README.md @@ -14,3 +14,234 @@ And finally, a couple of utility modules used by the high level API are also exp The header files and a compiled RISC-V version of this library can be found [here](https://github.com/cartesi/machine-emulator-tools/). We also provide `.pc` (pkg-config) files to facilitate linking. + +# mock and testing + +This library provides a mock implementation of @ref libcmt\_io\_driver that is +able to simulate requests and replies on the host machine. + +- Build it with: `make mock.build`. +- Install it with: `make mock.install`, use `PREFIX` to specify the installation path: + (The command below will install the library and headers on `$PWD/_install` directory) +``` +make mock.install PREFIX=_install +``` + +## testing + +Use the environment variable @p CMT\_INPUTS to inject inputs into the application compiled with the mock. +Outputs will be written to files with names derived from the input name. + +example: +``` +CMT_INPUTS="0:advance.bin" ./application +``` + +The first output will generate the file: +``` +advance.output-0.bin +``` + +The first report will generate the file: +``` +advance.report-0.bin +``` + +The first exception will generate the file: +``` +advance.exception-0.bin +``` + +The (verifiable) outputs root hash: +``` +advance.outputs_root_hash.bin +``` + +inputs must follow this syntax, a comma separated list of reason number followed by a filepath: +``` +CMT_INPUTS=" ':' ( ',' ':' ) *" +``` + +In addition to @p CMT\_INPUTS, there is also the @p CMT\_DEBUG variable. Enable it +for a verbose version of the low level calls. + +``` +CMT_DEBUG=yes ./application +``` + +## generating inputs + +Inputs and Outputs are expected to be EVM-ABI encoded. Encoding and decoding +can be acheived multiple ways, including writing tools with this library. A +simple way to generate testing data is to use the @p cast tool from +[foundry](http://book.getfoundry.sh/reference/cast/cast.html) and `xxd`. + +Encoding an @p EvmAdvance: +``` +cast calldata "EvmAdvance(address,uint256,uint256,uint256,bytes)" \ + 0x0000000000000000000000000000000000000000 \ + 0x0000000000000000000000000000000000000000 \ + 0x0000000000000000000000000000000000000000 \ + 0x0000000000000000000000000000000000000000 \ + 0x`echo "advance-0" | xxd -p -c0` | xxd -r -p > 0.bin +``` + +Encoding an @p EvmInspect: +``` +cast calldata "EvmInspect(bytes)" \ + 0x`echo "inspect-0" | xxd -p -c0` | xxd -r -p > 1.bin +``` + +## parsing outputs + +Decoding a @p Voucher: +``` +cast calldata-decode "Voucher(address,uint256,bytes)" 0x`xxd -p -c0 "$1"` | ( + read address + read value + read bytes + + echo "{" + printf '\t"address" : "%s",\n' $address + printf '\t"value" : "%s",\n' $value + printf '\t"bytes" : "%s"\n' $bytes + echo "}" +) + +# sh decode-voucher.sh $1 | jq '.bytes' | xxd -r +``` + +Decoding a @p Notice: +``` +cast calldata-decode "Notice(bytes)" 0x`xxd -p -c0 "$1"` | ( + read bytes + + echo "{" + printf '\t"bytes" : "%s"\n' $bytes + echo "}" +) + +# sh decode-notice.sh $1 | jq '.bytes' | xxd -r +``` + +# binds + +This library is intented to be used with programming languages other than C. +They acheive this by different means. + +## Go + +Go is able to include C headers directly. + +The application can be compiled with: `go build main.go`. Assuming that the +mock was installed at `./libcmt-0.1.0`. +(Code below is for demonstration purposes and not intended for production) + +``` +package main + +/* +#cgo CFLAGS: -Ilibcmt-0.1.0/include/ +#cgo LDFLAGS: -Llibcmt-0.1.0/lib/ -lcmt + +#include "libcmt/rollup.h" +*/ +import "C" + +import ( + "math/big" + "fmt" + "unsafe" +) + +func main() { + var rollup C.cmt_rollup_t + err := C.cmt_rollup_init(&rollup) + if err != 0 { + fmt.Printf("initialization failed\n") + } + + bytes_s := []byte{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + } + wei := new(big.Int).SetBytes(bytes_s) + + finish := C.cmt_rollup_finish_t{ + accept_previous_request: true, + } + for { + var advance C.cmt_rollup_advance_t + err = C.cmt_rollup_finish(&rollup, &finish) + if err != 0 { return; } + + err = C.cmt_rollup_read_advance_state(&rollup, &advance); + if err != 0 { return; } + + bytes:= wei.Bytes() + size := len(bytes) + C.cmt_rollup_emit_voucher(&rollup, + C.CMT_ADDRESS_LENGTH, &advance.sender[0], + C.uint(size), unsafe.Pointer(&bytes[0]), + advance.length, advance.data) + C.cmt_rollup_emit_report(&rollup, advance.length, advance.data) + } +} +``` + +## Rust + +Rust interop with C requires bindings to be generated, we'll use bindgen to +accomplish this. + +Create the initial directory layout with `cargo`, then add the library to it: +``` +cargo init --bin cmt +# download the library and extract it into cmt/libcmt-0.1.0 +cd cmt +``` + +Generate the bindings, execute: +``` +# join all header files into one. +cat libcmt-0.1.0/include/libcmt/*.h > src/libcmt.h + +# generate the bindings +bindgen src/libcmt.h -o src/bindings.rs --allowlist-function '^cmt_.*' --allowlist-type '^cmt_.*' --no-doc-comments -- -I libcmt-0.1.0/include/libcmt +``` + +Include the bindings to the project, add the following to: `src/lib.rs` +``` +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] + +include!("bindings.rs"); +``` + +Tell cargo to link with the C library, add the following to: `build.rs` +``` +fn main() { + println!("cargo:rustc-link-search=libcmt-0.1.0/lib"); + println!("cargo:rustc-link-lib=cmt"); +} +``` + +An example of the raw calls to C, add the following to: `src/main.rs` +``` +use std::mem; + +fn main() { + let mut rollup: cmt::cmt_rollup_t = unsafe { mem::zeroed() }; + let rc = unsafe { cmt::cmt_rollup_init(&mut rollup) }; + println!("got return value: {}!", rc); +} +``` + +Messages like the one below most likely mean that cargo didn't find the library +`libcmt.a` or `build.rs` is incomplete: +``` +undefined reference to `cmt_rollup_emit_voucher' +``` diff --git a/sys-utils/libcmt/doc/examples/abi_multi.c b/sys-utils/libcmt/doc/examples/abi_multi.c new file mode 100644 index 00000000..18f5ead5 --- /dev/null +++ b/sys-utils/libcmt/doc/examples/abi_multi.c @@ -0,0 +1,52 @@ +#include "libcmt/abi.h" +#include "libcmt/buf.h" + +// Echo(bytes) +#define ECHO CMT_ABI_FUNSEL(0x5f, 0x88, 0x6b, 0x86) + +static int encode_echo(cmt_buf_t *tx, uint32_t funsel, size_t length, void *data) { + cmt_buf_t wr = *tx; + cmt_buf_t of; + void *params_base = wr.begin + 4; // after funsel + + // static section + return cmt_abi_put_funsel(&wr, funsel) + || cmt_abi_put_bytes_s(&wr, &of) + // dynamic section + || cmt_abi_put_bytes_d(&wr, &of, length, data, params_base) + ; +} + +static int decode_echo(cmt_buf_t *rx, uint32_t funsel, size_t *length, void **data) { + cmt_buf_t rd = *rx; + cmt_buf_t of; + void *params_base = wr.begin + 4; // after funsel + + // static section + return cmt_abi_get_funsel(&wr, funsel) + || cmt_abi_get_bytes_s(&wr, &of) + // dynamic section + || cmt_abi_get_bytes_d(&wr, &of, length, data, params_base) + ; +} + +int f(cmt_buf_t *wr, cmt_buf_t *rd) +{ + int rc; + size_t length; + void *data; + + if (cmt_buf_length(rd) < 4) + return -ENOBUFS; + switch (cmt_abi_peek_funsel(rd)) { + case ECHO: + rc = decode_echo(rd, CALL, &length, &data); + if (rc) return rc; + + rc = encode_echo(wr, CALL, length, data); + if (rc) return rc; + + break; + } + return 0; +} diff --git a/sys-utils/libcmt/doc/examples/rollup.c b/sys-utils/libcmt/doc/examples/rollup.c index 68e7702d..de203230 100644 --- a/sys-utils/libcmt/doc/examples/rollup.c +++ b/sys-utils/libcmt/doc/examples/rollup.c @@ -24,7 +24,7 @@ int main(void) { break; } - rc = cmt_rollup_emit_voucher(&rollup, advance.sender, advance.length, advance.data); + rc = cmt_rollup_emit_voucher(&rollup, sizeof advance.sender, advance.sender, 0, NULL, advance.length, advance.data); if (rc < 0) { fprintf(stderr, "%s:%d Error on voucher %s (%d)\n", __FILE__, __LINE__, strerror(-rc), (-rc)); break; diff --git a/sys-utils/libcmt/include/libcmt/abi.h b/sys-utils/libcmt/include/libcmt/abi.h index 8ab862a1..8a1fd718 100644 --- a/sys-utils/libcmt/include/libcmt/abi.h +++ b/sys-utils/libcmt/include/libcmt/abi.h @@ -98,10 +98,12 @@ * * Lets look at some code on how to tie everything together. We'll build a @b * echo of sorts that decodes the contents of @p rd and re-encodes it into @p - * wr. First we'll take two of the previous encode/decode examples as a - * starting point. We'll add the suffix 000 and 001 to disambiguate them. We'll - * use the @ref cmt_abi_peek_funsel in our new @p decode function to decide - * which of the two message types we got and how to handle it. + * wr. We'll use previous examples as a starting point to implement encode_echo + * and decode_echo. With the entrypoint being @p f. We'll use @ref + * cmt_abi_peek_funsel to switch on the message function selector, only one + * valid case in this example. Decode and if we succeed, encode it back. If the + * caller needs the encoded size, we can compute it by storing @p wr at the + * start and compute the difference. * * @includelineno "examples/abi_multi.c" * @@ -141,8 +143,10 @@ uint32_t cmt_abi_funsel(uint8_t a, uint8_t b, uint8_t c, uint8_t d); * @param [in] funsel function selector * * @return - * - 0 success - * - ENOBUFS no space left in @p me + * | | | + * |--:|-----------------------------| + * | 0| success | + * |< 0| failure with a -errno value | * * @note A function selector can be compute it with: @ref cmt_keccak_funsel. * It is always represented in big endian. */ @@ -155,9 +159,12 @@ int cmt_abi_put_funsel(cmt_buf_t *me, uint32_t funsel); * @param [in] data poiter to a integer * * @return - * - 0 success - * - ENOBUFS no space left in @p me - * - EDOM requested @p n is too large + * | | | + * |-------:|------------------------------------------| + * | 0| success | + * |-ENOBUFS| no space left in @p me | + * | -EDOM| integer not representable in @p 32 bytes | + * * * @code * ... @@ -167,7 +174,42 @@ int cmt_abi_put_funsel(cmt_buf_t *me, uint32_t funsel); * ... * @endcode * @note This function takes care of endianess conversions */ -int cmt_abi_put_uint(cmt_buf_t *me, size_t n, const void *data); +int cmt_abi_put_uint(cmt_buf_t *me, size_t data_length, const void *data); + +/** Encode a big-endian value of up to 32bytes of data into the buffer + * + * @param [in,out] me a initialized buffer working as iterator + * @param [in] length size of @p data in bytes + * @param [in] data poiter to a integer + * + * @return + * | | | + * |-------:|---------------------------------------------------| + * | 0| success | + * |-ENOBUFS| no space left in @p me | + * | -EDOM| integer not representable in @p data_length bytes | + * + * @code + * ... + * cmt_buf_t it = ...; + * uint8_t small[] = { + * 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + * 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + * 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + * 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + * }; + * cmt_abi_put_uint(&it, sizeof small, &small); + * ... + * uint8_t big[] = { + * 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + * 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + * 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + * 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + * }; + * cmt_abi_put_uint(&it, sizeof big, &big); + * @endcode + * @note This function takes care of endianess conversions */ +int cmt_abi_put_uint_be(cmt_buf_t *me, size_t data_length, const void *data); /** Encode a bool into the buffer * @@ -175,8 +217,10 @@ int cmt_abi_put_uint(cmt_buf_t *me, size_t n, const void *data); * @param [in] value boolean value * * @return - * - 0 success - * - ENOBUFS no space left in @p me + * | | | + * |-------:|------------------------| + * | 0| success | + * |-ENOBUFS| no space left in @p me | * * @code * ... @@ -193,8 +237,10 @@ int cmt_abi_put_bool(cmt_buf_t *me, bool value); * @param [in] address exactly @ref CMT_ADDRESS_LENGTH bytes * * @return - * - 0 success - * - ENOBUFS no space left in @p me */ + * | | | + * |-------:|------------------------| + * | 0| success | + * |-ENOBUFS| no space left in @p me | */ int cmt_abi_put_address(cmt_buf_t *me, const uint8_t address[CMT_ADDRESS_LENGTH]); /** Encode the static part of @b bytes into the message, @@ -202,9 +248,12 @@ int cmt_abi_put_address(cmt_buf_t *me, const uint8_t address[CMT_ADDRESS_LENGTH] * * @param [in,out] me initialized buffer * @param [out] offset initialize for @ref cmt_abi_put_bytes_d + * * @return - * - 0 success - * - ENOBUFS no space left in @p me */ + * | | | + * |-------:|------------------------| + * | 0| success | + * |-ENOBUFS| no space left in @p me | */ int cmt_abi_put_bytes_s(cmt_buf_t *me, cmt_buf_t *offset); /** Encode the dynamic part of @b bytes into the message, @@ -215,9 +264,12 @@ int cmt_abi_put_bytes_s(cmt_buf_t *me, cmt_buf_t *offset); * @param [in] n size of @b data * @param [in] data array of bytes * @param [in] start starting point for offset calculation (first byte after funsel) + * * @return - * - 0 success - * - ENOBUFS no space left in @p me */ + * | | | + * |-------:|------------------------| + * | 0| success | + * |-ENOBUFS| no space left in @p me | */ int cmt_abi_put_bytes_d(cmt_buf_t *me, cmt_buf_t *offset, size_t n, const void *data, const void *start); /** Reserve @b n bytes of data from the buffer into @b res to be filled by the @@ -227,9 +279,12 @@ int cmt_abi_put_bytes_d(cmt_buf_t *me, cmt_buf_t *offset, size_t n, const void * * @param [in] n amount of bytes to reserve * @param [out] res slice of bytes extracted from @p me * @param [in] start starting point for offset calculation (first byte after funsel) + * * @return - * - 0 success - * - ENOBUFS no space left in @p me + * | | | + * |-------:|------------------------| + * | 0| success | + * |-ENOBUFS| no space left in @p me | * * @note @p me must outlive @p res. * Create a duplicate otherwise */ @@ -237,11 +292,14 @@ int cmt_abi_reserve_bytes_d(cmt_buf_t *me, cmt_buf_t *of, size_t n, cmt_buf_t *o // get section --------------------------------------------------------------- -/** Read the funsel without consuming it from the buffer @p me +/** Read the funsel without consuming it from the buffer @p me, 0 is returned + * if there are less than 4 bytes in the buffer. * - * @param [in] me initialized buffer * @return - * - The function selector + * | | | + * |-------:|-------------------------| + * | != 0| function selector value | + * | 0| failure | * * @code * ... @@ -253,10 +311,7 @@ int cmt_abi_reserve_bytes_d(cmt_buf_t *me, cmt_buf_t *of, size_t n, cmt_buf_t *o * default: * return EXIT_FAILURE; * } - * @endcode - * - * @note user must ensure there are at least 4 bytes in the buffer. - * This function will fail and return 0 if that is not the case. */ + * @endcode */ uint32_t cmt_abi_peek_funsel(cmt_buf_t *me); /** Consume funsel from the buffer @p me and ensure it matches @p expected_funsel @@ -265,9 +320,11 @@ uint32_t cmt_abi_peek_funsel(cmt_buf_t *me); * @param [in] expected expected function selector * * @return - * - 0 success - * - ENOBUFS no space left in @p me - * - EBADMSG in case of a missmatch */ + * | | | + * |-------:|------------------------| + * | 0| success | + * |-ENOBUFS| no space left in @p me | + * |-EBADMSG| funsel missmatch | */ int cmt_abi_check_funsel(cmt_buf_t *me, uint32_t expected); /** Decode a unsigned integer of up to 32bytes from the buffer @@ -277,28 +334,49 @@ int cmt_abi_check_funsel(cmt_buf_t *me, uint32_t expected); * @param [out] data pointer to a integer * * @return - * - 0 success - * - ENOBUFS no space left in @p me - * - EDOM value won't fit into @p n bytes. */ + * | | | + * |-------:|---------------------------------------------------| + * | 0| success | + * |-ENOBUFS| no space left in @p me | + * | -EDOM| integer not representable in @p data_length bytes | */ int cmt_abi_get_uint(cmt_buf_t *me, size_t n, void *data); +/** Decode @p length big-endian bytes, up to 32, from the buffer into @p data + * + * @param [in,out] me initialized buffer + * @param [in] length size of @p data in bytes + * @param [out] data pointer to a integer + * + * @return + * | | | + * |-------:|---------------------------------------------------| + * | 0| success | + * |-ENOBUFS| no space left in @p me | + * | -EDOM| integer not representable in @p data_length bytes | */ +int cmt_abi_get_uint_be(cmt_buf_t *me, size_t n, void *data); + /** Consume and decode @b address from the buffer * * @param [in,out] me initialized buffer * @param [out] address exactly 20 bytes * * @return - * - 0 success - * - ENOBUFS requested size @b n is not available */ + * | | | + * |-------:|------------------------| + * | 0| success | + * |-ENOBUFS| no space left in @p me | */ int cmt_abi_get_address(cmt_buf_t *me, uint8_t address[CMT_ADDRESS_LENGTH]); /** Consume and decode the offset @p of * * @param [in,out] me initialized buffer * @param [out] of offset to @p bytes data, for use in conjunction with @ref cmt_abi_get_bytes_d + * * @return - * - 0 success - * - ENOBUFS no space left in @p me */ + * | | | + * |-------:|------------------------| + * | 0| success | + * |-ENOBUFS| no space left in @p me | */ int cmt_abi_get_bytes_s(cmt_buf_t *me, cmt_buf_t of[1]); /** Decode @b bytes from the buffer by taking a pointer to its contents. @@ -307,9 +385,13 @@ int cmt_abi_get_bytes_s(cmt_buf_t *me, cmt_buf_t of[1]); * @param [out] of offset to @p bytes data * @param [out] n amount of data available in @b bytes * @param [out] bytes memory range with contents + * * @return - * - 0 success - * - ENOBUFS no space left in @p me + * | | | + * |-------:|------------------------| + * | 0| success | + * |-ENOBUFS| no space left in @p me | + * * @note @p of can be initialized by calling @ref cmt_abi_get_bytes_s */ int cmt_abi_get_bytes_d(const cmt_buf_t *start, cmt_buf_t of[1], size_t *n, void **bytes); @@ -319,9 +401,13 @@ int cmt_abi_get_bytes_d(const cmt_buf_t *start, cmt_buf_t of[1], size_t *n, void * @param [out] of offset to @p bytes data * @param [out] n amount of data available in @b bytes * @param [out] bytes memory range with contents + * * @return - * - 0 success - * - ENOBUFS no space left in @p me + * | | | + * |-------:|------------------------| + * | 0| success | + * |-ENOBUFS| no space left in @p me | + * * @note @p of can be initialized by calling @ref cmt_abi_get_bytes_s */ int cmt_abi_peek_bytes_d(const cmt_buf_t *start, cmt_buf_t of[1], cmt_buf_t *bytes); @@ -332,9 +418,12 @@ int cmt_abi_peek_bytes_d(const cmt_buf_t *start, cmt_buf_t of[1], cmt_buf_t *byt * @param [in] n size of @p data in bytes * @param [in] data integer value to encode into @p out * @param [out] out encoded result + * * @return - * - 0 success - * - EDOM @p n is too large. */ + * | | | + * |-------:|---------------------------------------------------| + * | 0| success | + * | -EDOM| integer not representable in @p data_length bytes | */ int cmt_abi_encode_uint(size_t n, const void *data, uint8_t out[CMT_WORD_LENGTH]); /** Encode @p n bytes of @p data into @p out (up to 32) in reverse order. @@ -342,9 +431,13 @@ int cmt_abi_encode_uint(size_t n, const void *data, uint8_t out[CMT_WORD_LENGTH] * @param [in] n size of @p data in bytes * @param [in] data integer value to encode into @p out * @param [out] out encoded result + * * @return - * - 0 success - * - EDOM @p n is too large. + * | | | + * |-------:|---------------------------------------------------| + * | 0| success | + * | -EDOM| integer not representable in @p data_length bytes | + * * @note use @ref cmt_abi_encode_uint instead */ int cmt_abi_encode_uint_nr(size_t n, const uint8_t *data, uint8_t out[CMT_WORD_LENGTH]); @@ -353,9 +446,13 @@ int cmt_abi_encode_uint_nr(size_t n, const uint8_t *data, uint8_t out[CMT_WORD_L * @param [in] n size of @p data in bytes * @param [in] data integer value to encode into @p out * @param [out] out encoded result + * * @return - * - 0 success - * - EDOM @p n is too large. + * | | | + * |-------:|---------------------------------------------------| + * | 0| success | + * | -EDOM| integer not representable in @p data_length bytes | + * * @note use @ref cmt_abi_encode_uint instead */ int cmt_abi_encode_uint_nn(size_t n, const uint8_t *data, uint8_t out[CMT_WORD_LENGTH]); @@ -363,7 +460,13 @@ int cmt_abi_encode_uint_nn(size_t n, const uint8_t *data, uint8_t out[CMT_WORD_L * * @param [in] data integer value to decode into @p out * @param [in] n size of @p data in bytes - * @param [out] out decoded output */ + * @param [out] out decoded output + * + * @return + * | | | + * |-------:|---------------------------------------------------| + * | 0| success | + * | -EDOM| integer not representable in @p data_length bytes | */ int cmt_abi_decode_uint(const uint8_t data[CMT_WORD_LENGTH], size_t n, uint8_t *out); /** Decode @p n bytes of @p data into @p out (up to 32) in reverse order. @@ -371,6 +474,13 @@ int cmt_abi_decode_uint(const uint8_t data[CMT_WORD_LENGTH], size_t n, uint8_t * * @param [in] data integer value to decode into @p out * @param [in] n size of @p data in bytes * @param [out] out decoded output + * + * @return + * | | | + * |-------:|---------------------------------------------------| + * | 0| success | + * | -EDOM| integer not representable in @p data_length bytes | + * * @note if in doubt, use @ref cmt_abi_decode_uint */ int cmt_abi_decode_uint_nr(const uint8_t data[CMT_WORD_LENGTH], size_t n, uint8_t *out); @@ -379,6 +489,13 @@ int cmt_abi_decode_uint_nr(const uint8_t data[CMT_WORD_LENGTH], size_t n, uint8_ * @param [in] data integer value to decode into @p out * @param [in] n size of @p data in bytes * @param [out] out decoded output + * + * @return + * | | | + * |-------:|---------------------------------------------------| + * | 0| success | + * | -EDOM| integer not representable in @p data_length bytes | + * * @note if in doubt, use @ref cmt_abi_decode_uint */ int cmt_abi_decode_uint_nn(const uint8_t data[CMT_WORD_LENGTH], size_t n, uint8_t *out); diff --git a/sys-utils/libcmt/include/libcmt/rollup.h b/sys-utils/libcmt/include/libcmt/rollup.h index 36852721..c1d86b53 100644 --- a/sys-utils/libcmt/include/libcmt/rollup.h +++ b/sys-utils/libcmt/include/libcmt/rollup.h @@ -18,7 +18,7 @@ * Rollup abstraction layer * * Takes care of @ref libcmt_io_driver interactions, @ref libcmt_abi - * encoding/decoding and @ref libcmt_merkle tree interactions. + * encoding/decoding and @ref libcmt_merkle tree handling. * * Mocked version has support for simulating I/O via environment variables: * @p CMT_INPUTS="0:input.bin,..." and verbose ouput with @p CMT_DEBUG=yes. @@ -66,10 +66,13 @@ typedef struct cmt_rollup_finish { /** Initialize a @ref cmt_rollup_t state. * - * @param [in] me uninitialized state + * @param [in] me uninitialized state * - * - 0 success - * - negative value on error. values from: @ref cmt_rollup_driver_init */ + * @return + * | | | + * |--:|-----------------------------| + * | 0| success | + * |< 0| failure with a -errno value | */ int cmt_rollup_init(cmt_rollup_t *me); /** Finalize a @ref cmt_rollup_t statate previously initialized with @ref @@ -82,55 +85,88 @@ void cmt_rollup_fini(cmt_rollup_t *me); /** Emit a voucher * - * @param [in,out] me initialized cmt_rollup_t instance - * @param [in] address destination - * @param [in] n sizeof @p data in bytes - * @param [in] data message contents + * Equivalent to the `Voucher(address,uint256,bytes)` solidity call. + * + * @param [in,out] me initialized @ref cmt_rollup_t instance + * @param [in] address_length destination length in bytes + * @param [in] address destination data + * @param [in] value_length value length in bytes + * @param [in] value value data + * @param [in] data_length data length in bytes + * @param [in] data message contents + * * @return - * - 0 success - * - -ENOBUFS no space left in @p me */ -int cmt_rollup_emit_voucher(cmt_rollup_t *me, uint8_t address[CMT_ADDRESS_LENGTH], size_t n, const void *data); + * | | | + * |--:|-----------------------------| + * | 0| success | + * |< 0| failure with a -errno value | */ +int cmt_rollup_emit_voucher(cmt_rollup_t *me, + uint32_t address_length, const void *address_data, + uint32_t value_length, const void *value_data, + uint32_t length, const void *data); /** Emit a notice * - * @param [in,out] me initialized cmt_rollup_t instance - * @param [in] n sizeof @p data in bytes - * @param [in] data message contents + * @param [in,out] me initialized cmt_rollup_t instance + * @param [in] data_length data length in bytes + * @param [in] data message contents + * * @return - * - 0 success - * - -ENOBUFS no space left in @p me */ -int cmt_rollup_emit_notice(cmt_rollup_t *me, size_t n, const void *data); + * | | | + * |--:|-----------------------------| + * | 0| success | + * |< 0| failure with a -errno value | */ +int cmt_rollup_emit_notice(cmt_rollup_t *me, + uint32_t data_length, const void *data); /** Emit a report * @param [in,out] me initialized cmt_rollup_t instance * @param [in] n sizeof @p data in bytes * @param [in] data message contents + * * @return - * - 0 success - * - -ENOBUFS no space left in @p me */ -int cmt_rollup_emit_report(cmt_rollup_t *me, size_t n, const void *data); + * | | | + * |--:|-----------------------------| + * | 0| success | + * |< 0| failure with a -errno value | */ +int cmt_rollup_emit_report(cmt_rollup_t *me, + uint32_t data_length, const void *data); /** Emit a exception - * @param [in,out] me initialized cmt_rollup_t instance - * @param [in] n sizeof @p data in bytes - * @param [in] data message contents + * @param [in,out] me initialized cmt_rollup_t instance + * @param [in] data_length data length in bytes + * @param [in] data message contents + * * @return - * - 0 success - * - -ENOBUFS no space left in @p me */ -int cmt_rollup_emit_exception(cmt_rollup_t *me, size_t n, const void *data); + * | | | + * |--:|-----------------------------| + * | 0| success | + * |< 0| failure with a -errno value | */ +int cmt_rollup_emit_exception(cmt_rollup_t *me, + uint32_t data_length, const void *data); /** Read advance state + * + * @param [in,out] me initialized cmt_rollup_t instance + * @param [in,out] advance cmt_rollup_advance_t instance (maybe uninitialized) * * @return - * - 0 success - * - negative value on error. */ + * | | | + * |--:|-----------------------------| + * | 0| success | + * |< 0| failure with a -errno value | */ int cmt_rollup_read_advance_state(cmt_rollup_t *me, cmt_rollup_advance_t *advance); /** Read inspect state + * + * @param [in,out] me initialized cmt_rollup_t instance + * @param [in,out] inspect cmt_rollup_inspect_t instance (maybe uninitialized) * * @return - * - 0 success - * - negative value on error. */ + * | | | + * |--:|-----------------------------| + * | 0| success | + * |< 0| failure with a -errno value | */ int cmt_rollup_read_inspect_state(cmt_rollup_t *me, cmt_rollup_inspect_t *inspect); /** Finish processing of current advance or inspect. @@ -140,20 +176,33 @@ int cmt_rollup_read_inspect_state(cmt_rollup_t *me, cmt_rollup_inspect_t *inspec * @param [in,out] finish initialized cmt_rollup_finish_t instance * * @return - * - 0 success - * - negative value on error - */ + * | | | + * |--:|-----------------------------| + * | 0| success | + * |< 0| failure with a -errno value | */ int cmt_rollup_finish(cmt_rollup_t *me, cmt_rollup_finish_t *finish); /** Retrieve the merkle tree and intermediate state from a file @p path * @param [in,out] me initialized cmt_rollup_t instance - * @param [in] file path to file (parent directories must exist) */ + * @param [in] file path to file (parent directories must exist) + * + * @return + * | | | + * |--:|-----------------------------| + * | 0| success | + * |< 0| failure with a -errno value | */ int cmt_rollup_load_merkle(cmt_rollup_t *me, const char *path); /** Store the merkle tree and intermediate state to a file @p path * * @param [in,out] me initialized cmt_rollup_t instance - * @param [in] file path to file (parent directories must exist) */ + * @param [in] file path to file (parent directories must exist) + * + * @return + * | | | + * |--:|-----------------------------| + * | 0| success | + * |< 0| failure with a -errno value | */ int cmt_rollup_save_merkle(cmt_rollup_t *me, const char *path); #endif /* CMT_ROLLUP_H */ diff --git a/sys-utils/libcmt/src/abi.c b/sys-utils/libcmt/src/abi.c index 1df60b0e..ba8ad11a 100644 --- a/sys-utils/libcmt/src/abi.c +++ b/sys-utils/libcmt/src/abi.c @@ -109,6 +109,17 @@ int cmt_abi_put_uint(cmt_buf_t *me, size_t n, const void *data) { return cmt_abi_encode_uint(n, data, x->begin); } +int cmt_abi_put_uint_be(cmt_buf_t *me, size_t n, const void *data) { + cmt_buf_t x[1]; + + if (n > CMT_WORD_LENGTH) + return -EDOM; + if (cmt_buf_split(me, CMT_WORD_LENGTH, x, me)) + return -ENOBUFS; + + return cmt_abi_encode_uint_nn(n, data, x->begin); +} + int cmt_abi_put_bool(cmt_buf_t *me, bool value) { uint8_t boolean = !!value; return cmt_abi_put_uint(me, sizeof(boolean), &boolean); @@ -188,6 +199,18 @@ int cmt_abi_get_uint(cmt_buf_t *me, size_t n, void *data) { return cmt_abi_decode_uint(x->begin, n, data); } +int cmt_abi_get_uint_be(cmt_buf_t *me, size_t n, void *data) { + cmt_buf_t x[1]; + + if (n > CMT_WORD_LENGTH) + return -EDOM; + int rc = cmt_buf_split(me, CMT_WORD_LENGTH, x, me); + if (rc) + return rc; + + return cmt_abi_decode_uint_nn(x->begin, n, data); +} + int cmt_abi_get_bool(cmt_buf_t *me, bool *value) { uint8_t boolean = 0; int rc = cmt_abi_put_uint(me, sizeof(boolean), &boolean); diff --git a/sys-utils/libcmt/src/mock/io.c b/sys-utils/libcmt/src/mock/io.c index 604a0d65..46f3ab70 100644 --- a/sys-utils/libcmt/src/mock/io.c +++ b/sys-utils/libcmt/src/mock/io.c @@ -86,7 +86,6 @@ static int load_next_input(cmt_io_driver_mock_t *me, struct cmt_io_yield *rr) { rr->reason = me->input_type; rr->data = file_length; - me->input_seq = 0; me->output_seq = 0; me->report_seq = 0; me->exception_seq = 0; @@ -97,12 +96,12 @@ static int load_next_input(cmt_io_driver_mock_t *me, struct cmt_io_yield *rr) { return 0; } -static int store_next_output(cmt_io_driver_mock_t *me, char *ns, int *seq, struct cmt_io_yield *rr) { +static int store_output(cmt_io_driver_mock_t *me, const char *filepath, struct cmt_io_yield *rr) { if (rr->data > cmt_buf_length(me->tx)) return -ENOBUFS; - char filepath[128 + 1 + 8 + 16]; - snprintf(filepath, sizeof filepath, "%s.%s%d%s", me->input_filename, ns, *seq, me->input_fileext); + //char filepath[128 + 1 + 8 + 16]; + //snprintf(filepath, sizeof filepath, "%s.%s%d%s", me->input_filename, ns, *seq, me->input_fileext); int rc = write_whole_file(filepath, rr->data, me->tx->begin); if (rc) { @@ -113,10 +112,16 @@ static int store_next_output(cmt_io_driver_mock_t *me, char *ns, int *seq, struc fprintf(stderr, "wrote filename: \"%s\" (%u)\n", filepath, rr->data); } - seq[0] += 1; + //seq[0] += 1; return 0; } +static int store_next_output(cmt_io_driver_mock_t *me, char *ns, int *seq, struct cmt_io_yield *rr) { + char filepath[128 + 32 + 8 + 16]; + snprintf(filepath, sizeof filepath, "%s.%s%d%s", me->input_filename, ns, *seq++, me->input_fileext); + return store_output(me, filepath, rr); +} + static int mock_progress(cmt_io_driver_mock_t *me, struct cmt_io_yield *rr) { (void) me; if (rr->cmd != CMT_IO_CMD_AUTOMATIC) { @@ -133,7 +138,11 @@ static int mock_rx_accepted(cmt_io_driver_mock_t *me, struct cmt_io_yield *rr) { return -EINVAL; } if (me->input_seq++) { // skip the first - store_next_output(me, "o", &me->input_seq, rr); + char filepath[128 + 32 + 8 + 16]; + snprintf(filepath, sizeof filepath, + "%s.outputs_root_hash%s", me->input_filename, me->input_fileext); + int rc = store_output(me, filepath, rr); + if (rc) return rc; } if (load_next_input(me, rr)) return -ENODATA; @@ -156,7 +165,7 @@ static int mock_tx_output(cmt_io_driver_mock_t *me, struct cmt_io_yield *rr) { fprintf(stderr, "Expected cmd to be AUTOMATIC\n"); return -EINVAL; } - return store_next_output(me, "o", &me->output_seq, rr); + return store_next_output(me, "output-", &me->output_seq, rr); } static int mock_tx_report(cmt_io_driver_mock_t *me, struct cmt_io_yield *rr) { @@ -164,7 +173,7 @@ static int mock_tx_report(cmt_io_driver_mock_t *me, struct cmt_io_yield *rr) { fprintf(stderr, "Expected cmd to be AUTOMATIC\n"); return -EINVAL; } - return store_next_output(me, "r", &me->report_seq, rr); + return store_next_output(me, "report-", &me->report_seq, rr); } static int mock_tx_exception(cmt_io_driver_mock_t *me, struct cmt_io_yield *rr) { @@ -172,7 +181,7 @@ static int mock_tx_exception(cmt_io_driver_mock_t *me, struct cmt_io_yield *rr) fprintf(stderr, "Expected cmd to be MANUAL\n"); return -EINVAL; } - return store_next_output(me, "e", &me->exception_seq, rr); + return store_next_output(me, "exception-", &me->exception_seq, rr); } /* These behaviours are defined by the cartesi-machine emulator */ diff --git a/sys-utils/libcmt/src/rollup.c b/sys-utils/libcmt/src/rollup.c index df894ca9..bee60bbb 100644 --- a/sys-utils/libcmt/src/rollup.c +++ b/sys-utils/libcmt/src/rollup.c @@ -23,8 +23,8 @@ #include #include -// Voucher(address,bytes) -#define VOUCHER CMT_ABI_FUNSEL(0xef, 0x61, 0x5e, 0x2f) +// Voucher(address,uint256,bytes) +#define VOUCHER CMT_ABI_FUNSEL(0x23, 0x7a, 0x81, 0x6f) // Notice(bytes) #define NOTICE CMT_ABI_FUNSEL(0xc2, 0x58, 0xd6, 0xe5) @@ -71,7 +71,10 @@ void cmt_rollup_fini(cmt_rollup_t *me) { cmt_merkle_fini(me->merkle); } -int cmt_rollup_emit_voucher(cmt_rollup_t *me, uint8_t address[20], size_t length, const void *data) { +int cmt_rollup_emit_voucher(cmt_rollup_t *me, + uint32_t address_length, const void *address_data, + uint32_t value_length, const void *value_data, + uint32_t length, const void *data) { if (!me) return -EINVAL; if (!data && length) @@ -82,8 +85,11 @@ int cmt_rollup_emit_voucher(cmt_rollup_t *me, uint8_t address[20], size_t length cmt_buf_t of[1]; void *params_base = tx->begin + 4; // after funsel - if (DBG(cmt_abi_put_funsel(wr, VOUCHER)) || DBG(cmt_abi_put_address(wr, address)) || - DBG(cmt_abi_put_bytes_s(wr, of)) || DBG(cmt_abi_put_bytes_d(wr, of, length, data, params_base))) + if (DBG(cmt_abi_put_funsel(wr, VOUCHER)) + || DBG(cmt_abi_put_uint_be(wr, address_length, address_data)) + || DBG(cmt_abi_put_uint_be(wr, value_length, value_data)) + || DBG(cmt_abi_put_bytes_s(wr, of)) + || DBG(cmt_abi_put_bytes_d(wr, of, length, data, params_base))) return -ENOBUFS; size_t m = wr->begin - tx->begin; @@ -99,7 +105,7 @@ int cmt_rollup_emit_voucher(cmt_rollup_t *me, uint8_t address[20], size_t length return cmt_merkle_push_back_data(me->merkle, m, tx->begin); } -int cmt_rollup_emit_notice(cmt_rollup_t *me, size_t length, const void *data) { +int cmt_rollup_emit_notice(cmt_rollup_t *me, uint32_t length, const void *data) { if (!me) return -EINVAL; if (!data && length) @@ -127,7 +133,7 @@ int cmt_rollup_emit_notice(cmt_rollup_t *me, size_t length, const void *data) { return cmt_merkle_push_back_data(me->merkle, m, tx->begin); } -int cmt_rollup_emit_report(cmt_rollup_t *me, size_t length, const void *data) { +int cmt_rollup_emit_report(cmt_rollup_t *me, uint32_t length, const void *data) { if (!me) return -EINVAL; if (!data && length) @@ -148,7 +154,7 @@ int cmt_rollup_emit_report(cmt_rollup_t *me, size_t length, const void *data) { return DBG(cmt_io_yield(me->io, req)); } -int cmt_rollup_emit_exception(cmt_rollup_t *me, size_t length, const void *data) { +int cmt_rollup_emit_exception(cmt_rollup_t *me, uint32_t length, const void *data) { if (!me) return -EINVAL; if (!data && length) diff --git a/sys-utils/libcmt/src/tests/abi-single.c b/sys-utils/libcmt/src/tests/abi-single.c index 1fc0901b..3406c403 100644 --- a/sys-utils/libcmt/src/tests/abi-single.c +++ b/sys-utils/libcmt/src/tests/abi-single.c @@ -40,38 +40,10 @@ static void encode_u8() { uint8_t x = 0x01; uint8_t en[CMT_WORD_LENGTH]; uint8_t be[CMT_WORD_LENGTH] = { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, }; cmt_abi_encode_uint(sizeof(x), (void *) &x, en); assert(memcmp(en, be, sizeof(be)) == 0); @@ -81,38 +53,10 @@ static void encode_u16() { uint16_t x = UINT16_C(0x0123); uint8_t en[CMT_WORD_LENGTH]; uint8_t be[CMT_WORD_LENGTH] = { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x01, - 0x23, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x23, }; cmt_abi_encode_uint(sizeof(x), (void *) &x, en); assert(memcmp(en, be, sizeof(be)) == 0); @@ -122,38 +66,10 @@ static void encode_u32() { uint32_t x = UINT32_C(0x01234567); uint8_t en[CMT_WORD_LENGTH]; uint8_t be[CMT_WORD_LENGTH] = { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x01, - 0x23, - 0x45, - 0x67, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x23, 0x45, 0x67, }; cmt_abi_encode_uint(sizeof(x), (void *) &x, en); assert(memcmp(en, be, sizeof(be)) == 0); @@ -163,38 +79,10 @@ static void encode_u64() { uint64_t x = UINT64_C(0x0123456789abcdef); uint8_t en[CMT_WORD_LENGTH]; uint8_t be[CMT_WORD_LENGTH] = { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x01, - 0x23, - 0x45, - 0x67, - 0x89, - 0xab, - 0xcd, - 0xef, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, }; cmt_abi_encode_uint(sizeof(x), (void *) &x, en); assert(memcmp(en, be, sizeof(be)) == 0); @@ -202,73 +90,17 @@ static void encode_u64() { static void encode_u256() { uint8_t x[CMT_WORD_LENGTH] = { - 0x1f, - 0x1e, - 0x1d, - 0x1c, - 0x1b, - 0x1a, - 0x19, - 0x18, - 0x17, - 0x16, - 0x15, - 0x14, - 0x13, - 0x12, - 0x11, - 0x10, - 0x0f, - 0x0e, - 0x0d, - 0x0c, - 0x0b, - 0x0a, - 0x09, - 0x08, - 0x07, - 0x06, - 0x05, - 0x04, - 0x03, - 0x02, - 0x01, - 0x00, + 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, + 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, + 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, + 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, }; uint8_t en[CMT_WORD_LENGTH]; uint8_t be[CMT_WORD_LENGTH] = { - 0x00, - 0x01, - 0x02, - 0x03, - 0x04, - 0x05, - 0x06, - 0x07, - 0x08, - 0x09, - 0x0a, - 0x0b, - 0x0c, - 0x0d, - 0x0e, - 0x0f, - 0x10, - 0x11, - 0x12, - 0x13, - 0x14, - 0x15, - 0x16, - 0x17, - 0x18, - 0x19, - 0x1a, - 0x1b, - 0x1c, - 0x1d, - 0x1e, - 0x1f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, }; cmt_abi_encode_uint(sizeof(x), (void *) &x, en); assert(memcmp(en, be, sizeof(be)) == 0); @@ -276,38 +108,10 @@ static void encode_u256() { static void encode_edom() { uint8_t x[CMT_WORD_LENGTH + 1] = { - 0x00, - 0x01, - 0x02, - 0x03, - 0x04, - 0x05, - 0x06, - 0x07, - 0x08, - 0x09, - 0x0a, - 0x0b, - 0x0c, - 0x0d, - 0x0e, - 0x0f, - 0x10, - 0x11, - 0x12, - 0x13, - 0x14, - 0x15, - 0x16, - 0x17, - 0x18, - 0x19, - 0x1a, - 0x1b, - 0x1c, - 0x1d, - 0x1e, - 0x1f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, }; uint8_t en[CMT_WORD_LENGTH]; @@ -318,38 +122,10 @@ static void encode_edom() { static void decode_u8() { uint8_t x, ex = 0x01; uint8_t be[CMT_WORD_LENGTH] = { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, }; assert(cmt_abi_decode_uint(be, sizeof(x), (void *) &x) == 0); assert(x == ex); @@ -358,38 +134,10 @@ static void decode_u8() { static void decode_u16() { uint16_t x, ex = UINT16_C(0x0123); uint8_t be[CMT_WORD_LENGTH] = { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x01, - 0x23, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x23, }; assert(cmt_abi_decode_uint(be, sizeof(x), (void *) &x) == 0); assert(x == ex); @@ -398,38 +146,10 @@ static void decode_u16() { static void decode_u32() { uint32_t x, ex = UINT32_C(0x01234567); uint8_t be[CMT_WORD_LENGTH] = { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x01, - 0x23, - 0x45, - 0x67, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x23, 0x45, 0x67, }; assert(cmt_abi_decode_uint(be, sizeof(x), (void *) &x) == 0); assert(x == ex); @@ -438,38 +158,10 @@ static void decode_u32() { static void decode_u64() { uint64_t x, ex = UINT64_C(0x0123456789abcdef); uint8_t be[CMT_WORD_LENGTH] = { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x01, - 0x23, - 0x45, - 0x67, - 0x89, - 0xab, - 0xcd, - 0xef, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, }; assert(cmt_abi_decode_uint(be, sizeof(x), (void *) &x) == 0); assert(x == ex); @@ -478,72 +170,16 @@ static void decode_u64() { static void decode_u256() { uint8_t x[CMT_WORD_LENGTH], ex[CMT_WORD_LENGTH] = { - 0x1f, - 0x1e, - 0x1d, - 0x1c, - 0x1b, - 0x1a, - 0x19, - 0x18, - 0x17, - 0x16, - 0x15, - 0x14, - 0x13, - 0x12, - 0x11, - 0x10, - 0x0f, - 0x0e, - 0x0d, - 0x0c, - 0x0b, - 0x0a, - 0x09, - 0x08, - 0x07, - 0x06, - 0x05, - 0x04, - 0x03, - 0x02, - 0x01, - 0x00, + 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, + 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, + 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, + 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, }; uint8_t be[CMT_WORD_LENGTH] = { - 0x00, - 0x01, - 0x02, - 0x03, - 0x04, - 0x05, - 0x06, - 0x07, - 0x08, - 0x09, - 0x0a, - 0x0b, - 0x0c, - 0x0d, - 0x0e, - 0x0f, - 0x10, - 0x11, - 0x12, - 0x13, - 0x14, - 0x15, - 0x16, - 0x17, - 0x18, - 0x19, - 0x1a, - 0x1b, - 0x1c, - 0x1d, - 0x1e, - 0x1f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, }; assert(cmt_abi_decode_uint(be, sizeof(x), x) == 0); assert(memcmp(x, ex, sizeof(ex)) == 0); @@ -553,38 +189,10 @@ static void decode_u256() { static void decode_edom() { uint64_t x; uint8_t be[CMT_WORD_LENGTH] = { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0xAA, - 0x01, - 0x23, - 0x45, - 0x67, - 0x89, - 0xab, - 0xcd, - 0xef, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, }; assert(cmt_abi_decode_uint(be, sizeof(x), (void *) &x) == -EDOM); } @@ -602,38 +210,10 @@ static void put_funsel() { static void put_uint() { uint64_t x = UINT64_C(0x0123456789abcdef); uint8_t be[CMT_WORD_LENGTH] = { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x01, - 0x23, - 0x45, - 0x67, - 0x89, - 0xab, - 0xcd, - 0xef, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, }; CMT_BUF_DECL(b, 64); cmt_buf_t it[1] = {*b}; @@ -643,41 +223,16 @@ static void put_uint() { } static void put_address() { - uint8_t x[20] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0x01, 0x23, 0x45, 0x67}; + uint8_t x[20] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0x01, 0x23, 0x45, 0x67 + }; uint8_t be[CMT_WORD_LENGTH] = { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x01, - 0x23, - 0x45, - 0x67, - 0x89, - 0xab, - 0xcd, - 0xef, - 0x01, - 0x23, - 0x45, - 0x67, - 0x89, - 0xab, - 0xcd, - 0xef, - 0x01, - 0x23, - 0x45, - 0x67, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x23, 0x45, 0x67, + 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, + 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, }; CMT_BUF_DECL(b, 64); cmt_buf_t it[1] = {*b}; @@ -689,86 +244,16 @@ static void put_address() { static void put_bytes() { uint64_t x = UINT64_C(0x0123456789abcdef); uint8_t be[] = { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x20, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x08, - 0xef, - 0xcd, - 0xab, - 0x89, - 0x67, - 0x45, - 0x23, - 0x01, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; CMT_BUF_DECL(b, 128); cmt_buf_t it[1] = {*b}, of[1]; @@ -791,38 +276,10 @@ static void get_funsel() { static void get_uint() { uint64_t x, ex = UINT64_C(0x0123456789abcdef); uint8_t be[CMT_WORD_LENGTH] = { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x01, - 0x23, - 0x45, - 0x67, - 0x89, - 0xab, - 0xcd, - 0xef, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, }; CMT_BUF_DECL3(b, sizeof(be), be); cmt_buf_t rd[1] = {*b}; @@ -832,42 +289,17 @@ static void get_uint() { } static void get_address() { - uint8_t x[20], - ex[20] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, - 0x23, 0x45, 0x67}; + uint8_t x[20]; + uint8_t ex[20] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0x01, 0x23, 0x45, 0x67 + }; uint8_t be[CMT_WORD_LENGTH] = { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x01, - 0x23, - 0x45, - 0x67, - 0x89, - 0xab, - 0xcd, - 0xef, - 0x01, - 0x23, - 0x45, - 0x67, - 0x89, - 0xab, - 0xcd, - 0xef, - 0x01, - 0x23, - 0x45, - 0x67, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x23, 0x45, 0x67, + 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, + 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, }; CMT_BUF_DECL3(b, sizeof(be), be); cmt_buf_t it[1] = {*b}; @@ -879,86 +311,16 @@ static void get_address() { static void get_bytes() { uint64_t ex = UINT64_C(0x0123456789abcdef); uint8_t be[] = { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x20, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x08, - 0xef, - 0xcd, - 0xab, - 0x89, - 0x67, - 0x45, - 0x23, - 0x01, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; CMT_BUF_DECL3(b, sizeof(be), be); cmt_buf_t it[1] = {*b}, of[1], bytes[1]; diff --git a/sys-utils/libcmt/src/tests/rollup_echo.c b/sys-utils/libcmt/src/tests/rollup_echo.c index 53ec0435..baf391ec 100644 --- a/sys-utils/libcmt/src/tests/rollup_echo.c +++ b/sys-utils/libcmt/src/tests/rollup_echo.c @@ -1,3 +1,15 @@ +/* Data encoding: + * - cast calldata "EvmAdvance(address,uint256,uint256,uint256,bytes)" \ + * 0x0000000000000000000000000000000000000000 \ + * 0x0000000000000000000000000000000000000001 \ + * 0x0000000000000000000000000000000000000002 \ + * 0x0000000000000000000000000000000000000003 \ + * 0x`echo "hello world" | xxd -r -p -c0` > "" + * + * Data decoding: + * - cast calldata-decode "Voucher(address,uint256,bytes)" 0x`xxd -p -c0 ""` + * + */ #include "libcmt/rollup.h" #include #include @@ -6,10 +18,17 @@ int main(void) { cmt_rollup_t rollup; - if (!cmt_rollup_init(&rollup)) + + if (cmt_rollup_init(&rollup)) return EXIT_FAILURE; // cmt_rollup_load_merkle(rollup, "/tmp/merkle.dat"); + uint8_t small[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + }; for (;;) { int rc; cmt_rollup_finish_t finish = {.accept_previous_request = true}; @@ -27,7 +46,7 @@ int main(void) { break; } - rc = cmt_rollup_emit_voucher(&rollup, advance.sender, advance.length, advance.data); + rc = cmt_rollup_emit_voucher(&rollup, sizeof advance.sender, advance.sender, sizeof small, small, advance.length, advance.data); if (rc < 0) { fprintf(stderr, "%s:%d Error on voucher %s (%d)\n", __FILE__, __LINE__, strerror(-rc), (-rc)); break; diff --git a/sys-utils/rollup/Makefile b/sys-utils/rollup/Makefile index 0b8488ab..c3d25ac7 100644 --- a/sys-utils/rollup/Makefile +++ b/sys-utils/rollup/Makefile @@ -28,10 +28,8 @@ RVCXX = $(TOOLCHAIN_PREFIX)g++ RVCOPY = $(TOOLCHAIN_PREFIX)objcopy RVDUMP = $(TOOLCHAIN_PREFIX)objdump STRIP = $(TOOLCHAIN_PREFIX)strip -CXXFLAGS :=-Wall -Wextra -pedantic -O2 -std=c++17 \ - `PKG_CONFIG_PATH=/usr/riscv64-linux-gnu/lib/pkgconfig pkg-config --cflags libcmt` -LDLIBS := \ - `PKG_CONFIG_PATH=/usr/riscv64-linux-gnu/lib/pkgconfig pkg-config --libs libcmt` +CXXFLAGS := -Wall -Wextra -pedantic -O2 -std=c++17 `pkg-config --cflags libcmt` +LDLIBS := `pkg-config --libs libcmt` CONTAINER_MAKE := /usr/bin/make CONTAINER_BASE := /opt/cartesi/tools @@ -45,6 +43,7 @@ rollup.with-toolchain with-toolchain: extra.ext2.with-toolchain: $(MAKE) toolchain-exec CONTAINER_COMMAND="$(CONTAINER_MAKE) $@.toolchain" +rollup: export PKG_CONFIG_PATH ?= /usr/riscv64-linux-gnu/lib/pkgconfig rollup: rollup.cpp $(RVCXX) $(CXXFLAGS) -O2 -o rollup rollup.cpp $(LDLIBS) $(STRIP) rollup diff --git a/sys-utils/rollup/rollup.cpp b/sys-utils/rollup/rollup.cpp index 1f68de69..6704da81 100644 --- a/sys-utils/rollup/rollup.cpp +++ b/sys-utils/rollup/rollup.cpp @@ -65,7 +65,7 @@ static void print_help(void) { voucher emit a voucher read from stdin as a JSON object in the format - {"destination":
, "payload": } + {"destination":
, "value": , "payload": } where field "destination" contains a 20-byte EVM address in hex. if successful, prints to stdout a JSON object in the format {"index": } @@ -155,9 +155,6 @@ static uint8_t hexbyte(char a, char b) { // Convert an hex string into the corresponding bytes static std::string unhex(const std::string &s) { - if (s.size() != 42) { - throw std::invalid_argument{"incorrect address size"}; - } if (s.find_first_not_of("abcdefABCDEF0123456789", 2) != std::string::npos) { throw std::invalid_argument{"invalid character in address"}; } @@ -169,6 +166,20 @@ static std::string unhex(const std::string &s) { return res; } +static std::string unhex20(const std::string &s) { + if (s.size() != 2+40) { + throw std::invalid_argument{"incorrect address size"}; + } + return unhex(s); +} + +static std::string unhex32(const std::string &s) { + if (s.size() > 2+64) { + throw std::invalid_argument{"incorrect value size"}; + } + return unhex(s); +} + // Convert binary data into hex string static std::string hex(const uint8_t *data, uint64_t length) { static const char t[] = "0123456789abcdef"; @@ -187,11 +198,13 @@ static int write_voucher(void) try { rollup r; auto ji = nlohmann::json::parse(read_input()); auto payload = ji["payload"].get(); - auto destination = unhex(ji["destination"].get()); - if (destination.size() < CMT_ADDRESS_LENGTH) - return 1; + auto destination = unhex20(ji["destination"].get()); + auto value = unhex32(ji["value"].get()); return cmt_rollup_emit_voucher(r, + destination.length(), reinterpret_cast(destination.data()), + value.length(), + reinterpret_cast(value.data()), payload.size(), reinterpret_cast(payload.data())); } catch (std::exception &x) { diff --git a/sys-utils/yield/Makefile b/sys-utils/yield/Makefile index ba6b44e5..f9eb5f21 100644 --- a/sys-utils/yield/Makefile +++ b/sys-utils/yield/Makefile @@ -28,10 +28,8 @@ RVCXX = $(TOOLCHAIN_PREFIX)g++ RVCOPY = $(TOOLCHAIN_PREFIX)objcopy RVDUMP = $(TOOLCHAIN_PREFIX)objdump STRIP = $(TOOLCHAIN_PREFIX)strip -CFLAGS :=-Wall -Wextra -pedantic -O2 \ - `PKG_CONFIG_PATH=/usr/riscv64-linux-gnu/lib/pkgconfig pkg-config --cflags libcmt` -LDLIBS := \ - `PKG_CONFIG_PATH=/usr/riscv64-linux-gnu/lib/pkgconfig pkg-config --libs libcmt` +CFLAGS :=-Wall -Wextra -pedantic -O2 `pkg-config --cflags libcmt` +LDLIBS := `pkg-config --libs libcmt` CONTAINER_MAKE := /usr/bin/make CONTAINER_BASE := /opt/cartesi/tools @@ -45,6 +43,7 @@ yield.with-toolchain with-toolchain: extra.ext2.with-toolchain: $(MAKE) toolchain-exec CONTAINER_COMMAND="$(CONTAINER_MAKE) $@.toolchain" +yield: export PKG_CONFIG_PATH ?= /usr/riscv64-linux-gnu/lib/pkgconfig yield: yield.c $(RVCC) $(CFLAGS) -O2 -o yield yield.c $(LDLIBS) $(STRIP) yield