Skip to content

Commit

Permalink
feat!: add value to voucher
Browse files Browse the repository at this point in the history
  • Loading branch information
mpolitzer committed Jan 29, 2024
1 parent d447123 commit fff9cc9
Show file tree
Hide file tree
Showing 13 changed files with 352 additions and 770 deletions.
7 changes: 3 additions & 4 deletions sys-utils/ioctl-echo-loop/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion sys-utils/ioctl-echo-loop/ioctl-echo-loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -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, destination, 0, NULL, length, data);
if (rc) return rc;
}
return 0;
Expand Down
132 changes: 132 additions & 0 deletions sys-utils/libcmt/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,135 @@ 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

Both @ref libcmt\_rollup and libcmt\_io\_driver have a mock implementation. Run
`make mock.build` to build the mock version of the library. The install
destination can be specified with the `PREFIX` variable. An example:
```
make mock.install PREFIX=_install
```
will install the library and headers on `$PWD/_install` directory.

## testing

Use the environment variable @p CMT\_INPUTS to inject inputs to the mock.
Outputs will be written on files.

example:
```
CMT_INPUTS="0:advance.bin" ./application
```

with syntax:
```
CMT_INPUTS="<reason-number> ':' <filepath> ( ',' <reason-number> ':' <filepath> ) *"
```

In addition to @p CMT\_INPUTS, the 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. The
Recommended way for testing 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 voucher with the same tool:
```
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
```

# binds

Assuming the mock was installed at `_install`:

Go example, compile with `go build main.go`:
```
package main
/*
#cgo CFLAGS: -I../_install/include/
#cgo LDFLAGS: -L../_install/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, &advance.sender[0],
C.uint(size), unsafe.Pointer(&bytes[0]),
advance.length, advance.data)
C.cmt_rollup_emit_report(&rollup, advance.length, advance.data)
}
}
```
2 changes: 1 addition & 1 deletion sys-utils/libcmt/doc/examples/rollup.c
Original file line number Diff line number Diff line change
Expand Up @@ -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, 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;
Expand Down
45 changes: 45 additions & 0 deletions sys-utils/libcmt/include/libcmt/abi.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,39 @@ int cmt_abi_put_funsel(cmt_buf_t *me, uint32_t funsel);
* @note This function takes care of endianess conversions */
int cmt_abi_put_uint(cmt_buf_t *me, size_t n, 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 requested @p n is too large
*
* @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 n, const void *data);

/** Encode a bool into the buffer
*
* @param [in,out] me a initialized buffer working as iterator
Expand Down Expand Up @@ -282,6 +315,18 @@ int cmt_abi_check_funsel(cmt_buf_t *me, uint32_t expected);
* - EDOM value won't fit into @p n 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 value won't fit into @p n 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
Expand Down
10 changes: 5 additions & 5 deletions sys-utils/libcmt/include/libcmt/rollup.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -89,7 +89,7 @@ void cmt_rollup_fini(cmt_rollup_t *me);
* @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);
int cmt_rollup_emit_voucher(cmt_rollup_t *me, uint8_t address[CMT_ADDRESS_LENGTH], uint32_t value_length, const void *value_data, uint32_t length, const void *data);

/** Emit a notice
*
Expand All @@ -99,7 +99,7 @@ int cmt_rollup_emit_voucher(cmt_rollup_t *me, uint8_t address[CMT_ADDRESS_LENGTH
* @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);
int cmt_rollup_emit_notice(cmt_rollup_t *me, uint32_t length, const void *data);

/** Emit a report
* @param [in,out] me initialized cmt_rollup_t instance
Expand All @@ -108,7 +108,7 @@ int cmt_rollup_emit_notice(cmt_rollup_t *me, size_t n, const void *data);
* @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);
int cmt_rollup_emit_report(cmt_rollup_t *me, uint32_t length, const void *data);

/** Emit a exception
* @param [in,out] me initialized cmt_rollup_t instance
Expand All @@ -117,7 +117,7 @@ int cmt_rollup_emit_report(cmt_rollup_t *me, size_t n, const void *data);
* @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);
int cmt_rollup_emit_exception(cmt_rollup_t *me, uint32_t length, const void *data);

/** Read advance state
*
Expand Down
23 changes: 23 additions & 0 deletions sys-utils/libcmt/src/abi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
19 changes: 11 additions & 8 deletions sys-utils/libcmt/src/rollup.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
#include <stdlib.h>
#include <string.h>

// 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)
Expand Down Expand Up @@ -71,7 +71,7 @@ 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, uint8_t address[CMT_ADDRESS_LENGTH], uint32_t value_length, const void *value_data, uint32_t length, const void *data) {
if (!me)
return -EINVAL;
if (!data && length)
Expand All @@ -82,8 +82,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_address(wr, address))
|| 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;
Expand All @@ -99,7 +102,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)
Expand Down Expand Up @@ -127,7 +130,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)
Expand All @@ -148,7 +151,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)
Expand Down
Loading

0 comments on commit fff9cc9

Please sign in to comment.