From b12cdda60fb976060dff2b97004697bba7daa63a Mon Sep 17 00:00:00 2001 From: Marcelo Politzer <251334+mpolitzer@users.noreply.github.com> Date: Thu, 16 Nov 2023 10:30:48 -0300 Subject: [PATCH] fixup! feat: add libdriver --- linux/libcmt/.gitignore | 8 ++++ linux/libcmt/Makefile | 8 ++-- linux/libcmt/examples/abi_encode_001.c | 2 +- linux/libcmt/examples/abi_encode_002.c | 4 +- linux/libcmt/examples/abi_multi.c | 2 +- linux/libcmt/examples/yield-driver.c | 12 ++--- linux/libcmt/include/libcmt/abi.h | 10 ++--- linux/libcmt/include/libcmt/buf.h | 20 +-------- .../include/libcmt/ioctl/rollup-driver.h | 2 +- .../include/libcmt/ioctl/yield-driver.h | 2 +- linux/libcmt/include/libcmt/keccak.h | 14 +++--- linux/libcmt/include/libcmt/merkle.h | 10 ++--- .../include/libcmt/mock/rollup-driver.h | 2 +- .../libcmt/include/libcmt/mock/yield-driver.h | 2 +- .../libcmt/include/libcmt/rollup-driver-api.h | 44 ++++++++---------- linux/libcmt/include/libcmt/rollup.h | 45 ++++++++++++------- .../libcmt/include/libcmt/yield-driver-api.h | 20 ++++++--- linux/libcmt/src/abi.c | 10 ++--- linux/libcmt/src/buf.c | 25 +++++++---- linux/libcmt/src/ioctl/rollup-driver.c | 40 +++++++++++++---- linux/libcmt/src/ioctl/yield-driver.c | 14 +++--- linux/libcmt/src/merkle.c | 11 ++--- linux/libcmt/src/mock/rollup-driver.c | 21 ++++++--- linux/libcmt/src/mock/yield-driver.c | 10 ++--- linux/libcmt/src/rollup.c | 4 +- linux/libcmt/tests/abi.c | 16 +++++++ linux/libcmt/tools/templates/libcmt.pc | 10 +++++ linux/libcmt/tools/templates/libcmt_mock.pc | 10 +++++ 28 files changed, 230 insertions(+), 148 deletions(-) create mode 100644 linux/libcmt/.gitignore create mode 100644 linux/libcmt/tools/templates/libcmt.pc create mode 100644 linux/libcmt/tools/templates/libcmt_mock.pc diff --git a/linux/libcmt/.gitignore b/linux/libcmt/.gitignore new file mode 100644 index 00000000..76a61188 --- /dev/null +++ b/linux/libcmt/.gitignore @@ -0,0 +1,8 @@ +build/ +doc/theme +doc/html +*.o +*.d + +tools/funsel +tools/merkle-table diff --git a/linux/libcmt/Makefile b/linux/libcmt/Makefile index 1e82d908..ea888488 100644 --- a/linux/libcmt/Makefile +++ b/linux/libcmt/Makefile @@ -4,16 +4,18 @@ TARGET_PREFIX ?= $(PREFIX) TARGET_CC := $(CROSS_COMPILE)gcc TARGET_AR := $(CROSS_COMPILE)ar -TARGET_CFLAGS := -O2 -g -Wall -pedantic -Wextra -Iinclude -Iinclude/libcmt/ioctl -CFLAGS := -O2 -g -Wall -pedantic -Wextra -fsanitize=address,undefined -Iinclude -Iinclude/libcmt/mock +TARGET_CFLAGS := -Wvla -O2 -g -Wall -pedantic -Wextra -Iinclude -Iinclude/libcmt/ioctl +CFLAGS := -Wvla -O2 -g -Wall -pedantic -Wextra -fsanitize=address,undefined -Iinclude -Iinclude/libcmt/mock mock_BINS := build/libcmt_mock/yield-driver \ build/libcmt_mock/rollup-driver \ build/libcmt_mock/rollup \ + libcmt_mock.a ioctl_BINS := build/libcmt/yield-driver \ build/libcmt/rollup-driver \ - build/libcmt/rollup libcmt.a + build/libcmt/rollup \ + libcmt.a tests_BINS := build/libcmt_mock/abi \ build/libcmt_mock/keccak \ diff --git a/linux/libcmt/examples/abi_encode_001.c b/linux/libcmt/examples/abi_encode_001.c index e8b87b4a..e6a1d147 100644 --- a/linux/libcmt/examples/abi_encode_001.c +++ b/linux/libcmt/examples/abi_encode_001.c @@ -1,7 +1,7 @@ #include #include -int encode(cmt_buf_t wr[1], size_t n, uint8_t data[n]) +int encode(cmt_buf_t wr[1], size_t n, uint8_t *data) { cmt_buf_t of[1]; uint32_t example = cmt_keccak_funsel("Example(bytes)"); diff --git a/linux/libcmt/examples/abi_encode_002.c b/linux/libcmt/examples/abi_encode_002.c index ec46ac07..bdffb561 100644 --- a/linux/libcmt/examples/abi_encode_002.c +++ b/linux/libcmt/examples/abi_encode_002.c @@ -3,8 +3,8 @@ int encode(cmt_buf_t wr[1] ,uint8_t address[CMT_ADDRESS_LENGTH] - ,size_t n0, uint8_t data0[n0] - ,size_t n1, uint8_t data1[n1]) + ,size_t n0, uint8_t *data0 + ,size_t n1, uint8_t *data1) { cmt_buf_t of[2][1]; void *base = wr->begin + 4; // skip function selector diff --git a/linux/libcmt/examples/abi_multi.c b/linux/libcmt/examples/abi_multi.c index 51885566..a0d3b2c5 100644 --- a/linux/libcmt/examples/abi_multi.c +++ b/linux/libcmt/examples/abi_multi.c @@ -41,7 +41,7 @@ int use_000(cmt_buf_t rd[1], cmt_buf_t wr[1]) return encode_000(wr, address); } -int encode_001(cmt_buf_t wr[1], size_t n, uint8_t data[n]) +int encode_001(cmt_buf_t wr[1], size_t n, uint8_t *data) { cmt_buf_t of[1]; void *base = wr->begin + 4; // skip function selector diff --git a/linux/libcmt/examples/yield-driver.c b/linux/libcmt/examples/yield-driver.c index f1ee2e5c..eb7fa373 100644 --- a/linux/libcmt/examples/yield-driver.c +++ b/linux/libcmt/examples/yield-driver.c @@ -1,9 +1,8 @@ -#include -#include -#include -#include -#include -#include"yield-driver.h" +#include +#include +#include +#include +#include "yield-driver.h" int main(int argc, char *argv[]) { @@ -15,6 +14,7 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; if (cmt_yield_driver_progress(Y, progress * 10)) return EXIT_FAILURE; + cmt_yield_driver_fini(Y); } else { fprintf(stderr, "usage: %s --progress=\n", argv[0]); exit(EXIT_FAILURE); diff --git a/linux/libcmt/include/libcmt/abi.h b/linux/libcmt/include/libcmt/abi.h index 4db812c3..8b036565 100644 --- a/linux/libcmt/include/libcmt/abi.h +++ b/linux/libcmt/include/libcmt/abi.h @@ -356,7 +356,7 @@ cmt_abi_encode_uint(size_t n, const void *data, uint8_t out[CMT_WORD_LENGTH]); * - EDOM @p n is too large. * @note use @ref cmt_abi_encode_uint instead */ int -cmt_abi_encode_uint_nr(size_t n, const uint8_t data[n], uint8_t out[CMT_WORD_LENGTH]); +cmt_abi_encode_uint_nr(size_t n, const uint8_t *data, uint8_t out[CMT_WORD_LENGTH]); /** Encode @p n bytes of @p data into @p out (up to 32) in normal order. * @@ -368,7 +368,7 @@ cmt_abi_encode_uint_nr(size_t n, const uint8_t data[n], uint8_t out[CMT_WORD_LEN * - EDOM @p n is too large. * @note use @ref cmt_abi_encode_uint instead */ int -cmt_abi_encode_uint_nn(size_t n, const uint8_t data[n], uint8_t out[CMT_WORD_LENGTH]); +cmt_abi_encode_uint_nn(size_t n, const uint8_t *data, uint8_t out[CMT_WORD_LENGTH]); /** Decode @p n bytes of @p data into @p out (up to 32). * @@ -376,7 +376,7 @@ cmt_abi_encode_uint_nn(size_t n, const uint8_t data[n], uint8_t out[CMT_WORD_LEN * @param [in] n size of @p data in bytes * @param [out] out decoded output */ int -cmt_abi_decode_uint(const uint8_t data[CMT_WORD_LENGTH], size_t n, uint8_t out[n]); +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. * @@ -385,7 +385,7 @@ cmt_abi_decode_uint(const uint8_t data[CMT_WORD_LENGTH], size_t n, uint8_t out[n * @param [out] out decoded output * @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[n]); +cmt_abi_decode_uint_nr(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 normal order. * @@ -394,7 +394,7 @@ cmt_abi_decode_uint_nr(const uint8_t data[CMT_WORD_LENGTH], size_t n, uint8_t ou * @param [out] out decoded output * @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[n]); +cmt_abi_decode_uint_nn(const uint8_t data[CMT_WORD_LENGTH], size_t n, uint8_t *out); #endif /* CMT_ABI_H */ /** @} */ diff --git a/linux/libcmt/include/libcmt/buf.h b/linux/libcmt/include/libcmt/buf.h index 6a822dd3..9462d5a6 100644 --- a/linux/libcmt/include/libcmt/buf.h +++ b/linux/libcmt/include/libcmt/buf.h @@ -9,8 +9,8 @@ #include #include -/** A slice of contiguous memory from @b begin to @b end. - * Size can be taken with: `q - p`. +/** A slice of contiguous memory from @b begin to @b end, as an open range. + * Size can be taken with: `end - begin`. * * `begin == end` indicate an empty buffer */ typedef struct { @@ -18,22 +18,6 @@ typedef struct { uint8_t *end; /**< end of memory region */ } cmt_buf_t; -/** Declare a cmt_buf_t with stack backed memory. - * @param [in] N - size in bytes - * @note don't port */ -#define CMT_BUF_DECL(S, L) cmt_buf_t S[1] = {{ \ - .begin = (uint8_t [L]){0}, \ - .end = (S)->begin + L, \ - }} - -/** Declare a cmt_buf_t with parameters backed memory. - * @param [in] L - size in bytes - * @note don't port */ -#define CMT_BUF_DECL3(S, L, P) cmt_buf_t S[1] = {{ \ - .begin = P, \ - .end = (S)->begin + L, \ - }} - /** Initialize @p me buffer backed by @p data, @p length bytes in size * * @param [out] me a uninitialized instance diff --git a/linux/libcmt/include/libcmt/ioctl/rollup-driver.h b/linux/libcmt/include/libcmt/ioctl/rollup-driver.h index 771b00b4..9f5be3bb 100644 --- a/linux/libcmt/include/libcmt/ioctl/rollup-driver.h +++ b/linux/libcmt/include/libcmt/ioctl/rollup-driver.h @@ -10,5 +10,5 @@ struct cmt_rollup_driver { uint64_t length; } tx[1], rx[1]; }; -#include +#include "libcmt/rollup-driver-api.h" #endif /* EVM_ROLLUP_DRIVER_H */ diff --git a/linux/libcmt/include/libcmt/ioctl/yield-driver.h b/linux/libcmt/include/libcmt/ioctl/yield-driver.h index 03f9fc06..e0810cb8 100644 --- a/linux/libcmt/include/libcmt/ioctl/yield-driver.h +++ b/linux/libcmt/include/libcmt/ioctl/yield-driver.h @@ -4,5 +4,5 @@ struct cmt_yield_driver { int fd; }; -#include +#include "libcmt/yield-driver-api.h" #endif /* CMT_YIELD_DRIVER_H */ diff --git a/linux/libcmt/include/libcmt/keccak.h b/linux/libcmt/include/libcmt/keccak.h index 9bc13b07..f1ccaa70 100644 --- a/linux/libcmt/include/libcmt/keccak.h +++ b/linux/libcmt/include/libcmt/keccak.h @@ -86,9 +86,9 @@ void cmt_keccak_init(cmt_keccak_t *state); /** Hash @b n bytes of @b data * - * @param [in,out] state initialize the hasher state - * @param [in] n bytes in @b data to process - * @param [in] data data to hash */ + * @param [in,out] state initialize the hasher state + * @param [in] length bytes in @b data to process + * @param [in] data data to hash */ void cmt_keccak_update(cmt_keccak_t *state, size_t n, const void *data); /** Finalize the hash calculation from @b state and store it in @b md @@ -99,9 +99,9 @@ void cmt_keccak_final(cmt_keccak_t *state, void *md); /** Hash all @b n bytes of @b data at once * - * @param [in] n - bytes in @b data to process - * @param [in] data - data to hash - * @param [out] md - 32bytes to store the computed hash + * @param [in] length bytes in @b data to process + * @param [in] data data to hash + * @param [out] md 32bytes to store the computed hash * @return pointer to @b md * * Equivalent to: @@ -111,7 +111,7 @@ void cmt_keccak_final(cmt_keccak_t *state, void *md); * cmt_keccak_final(&st, md); * return md; * @endcode */ -uint8_t *cmt_keccak_data(size_t n, const void *data +uint8_t *cmt_keccak_data(size_t length, const void *data ,uint8_t md[CMT_KECCAK_LENGTH]); /** Compute the function selector from the solidity declaration @p decl diff --git a/linux/libcmt/include/libcmt/merkle.h b/linux/libcmt/include/libcmt/merkle.h index b22064ce..0790f15b 100644 --- a/linux/libcmt/include/libcmt/merkle.h +++ b/linux/libcmt/include/libcmt/merkle.h @@ -23,14 +23,14 @@ typedef struct { /** Initialize a @ref cmt_merkle_t tree state. * * @param [in] me uninitialized state */ -void cmt_merkle_init(cmt_merkle_t me[1]); +void cmt_merkle_init(cmt_merkle_t *me); /** Finalize a @ref cmt_merkle_t tree state. * * @param [in] me initialized state * * @note use of @p me after this call is undefined behavior. */ -void cmt_merkle_fini(cmt_merkle_t me[1]); +void cmt_merkle_fini(cmt_merkle_t *me); /** Append a leaf node * @@ -39,7 +39,7 @@ void cmt_merkle_fini(cmt_merkle_t me[1]); * @return * - 0 success * - -ENOBUFS indicates the tree is full */ -int cmt_merkle_push_back(cmt_merkle_t me[1], uint8_t hash[CMT_KECCAK_LENGTH]); +int cmt_merkle_push_back(cmt_merkle_t *me, uint8_t hash[CMT_KECCAK_LENGTH]); /** Compute the keccak-256 hash of @p data and append it as a leaf node * @@ -47,12 +47,12 @@ int cmt_merkle_push_back(cmt_merkle_t me[1], uint8_t hash[CMT_KECCAK_LENGTH]); * @return * - 0 success * - -ENOBUFS indicates that the tree is full */ -int cmt_merkle_push_back_data(cmt_merkle_t me[1], size_t n, void *data); +int cmt_merkle_push_back_data(cmt_merkle_t *me, size_t n, void *data); /** Retrieve the root hash of the merkle tree * * @param [in] me initialized state * @param [out] root root hash of the merkle tree */ -void cmt_merkle_get_root_hash(cmt_merkle_t me[1], uint8_t root[CMT_KECCAK_LENGTH]); +void cmt_merkle_get_root_hash(cmt_merkle_t *me, uint8_t root[CMT_KECCAK_LENGTH]); #endif /* CMT_MERKLE_H */ diff --git a/linux/libcmt/include/libcmt/mock/rollup-driver.h b/linux/libcmt/include/libcmt/mock/rollup-driver.h index 1e89a269..b4b3a998 100644 --- a/linux/libcmt/include/libcmt/mock/rollup-driver.h +++ b/linux/libcmt/include/libcmt/mock/rollup-driver.h @@ -12,5 +12,5 @@ struct cmt_rollup_driver { size_t len; } tx[1], rx[1]; }; -#include +#include "libcmt/rollup-driver-api.h" #endif /* CMT_ROLLUP_DRIVER_H */ diff --git a/linux/libcmt/include/libcmt/mock/yield-driver.h b/linux/libcmt/include/libcmt/mock/yield-driver.h index 4f4a7760..52a354aa 100644 --- a/linux/libcmt/include/libcmt/mock/yield-driver.h +++ b/linux/libcmt/include/libcmt/mock/yield-driver.h @@ -5,5 +5,5 @@ struct cmt_yield_driver { int dummy; }; -#include +#include "libcmt/yield-driver-api.h" #endif /* CMT_YIELD_DRIVER_H */ diff --git a/linux/libcmt/include/libcmt/rollup-driver-api.h b/linux/libcmt/include/libcmt/rollup-driver-api.h index 69bfbfb8..a4878a35 100644 --- a/linux/libcmt/include/libcmt/rollup-driver-api.h +++ b/linux/libcmt/include/libcmt/rollup-driver-api.h @@ -19,13 +19,13 @@ enum { CMT_ROLLUP_INSPECT_STATE = 1, /**< @ref rollup_driver_accept_and_wait_next_input inspect state */ }; -/** contents of @ref rollup_driver_t are implementation specific. +/** contents of @ref cmt_rollup_driver are implementation specific. * Define it in @p */ typedef struct cmt_rollup_driver cmt_rollup_driver_t; /** Open the rollup device and initialize the driver * - * @param [in] me A uninitialized @ref rollup_driver_t state + * @param [in] me A uninitialized @ref cmt_rollup_driver state * @returns * - 0 on success * - negative value on error. Any of -ENOBUFS, or errno values from `open` and `ioctl`. */ @@ -34,46 +34,40 @@ int cmt_rollup_driver_init(struct cmt_rollup_driver *me); /** Release the driver resources and close the rollup device * * @param [in] me A sucessfuly initialized state by @ref rollup_driver_init - * @returns - * - 0 on success - * - Any of `close` errno values to indicate an error - * - negative value on error. errno values from `close`. * @note usage of @p me after this call is a BUG and will cause undefined behaviour */ -int cmt_rollup_driver_fini(struct cmt_rollup_driver *me); +void cmt_rollup_driver_fini(struct cmt_rollup_driver *me); -/** Create a output, with the first @p n bytes of @ref cmt_rollup_driver_t.tx +/** Create a output, with the first @p length bytes of @ref cmt_rollup_driver_t.tx * * @param [in] me A sucessfuly initialized state by @ref rollup_driver_init - * @param [in] n size in bytes of the output, contents from @p tx buffer. + * @param [in] length size in bytes of the output, contents from @p tx buffer. * @return * - 0 on success * - negative value on error. -ENOBUFS, or errno values from `ioctl` */ -int cmt_rollup_driver_write_output(struct cmt_rollup_driver *me, uint64_t n); +int cmt_rollup_driver_write_output(struct cmt_rollup_driver *me, uint64_t length); -/** Create a report, with the first @p n bytes of @ref rollup_driver_t.tx +/** Create a report, with the first @p length bytes of @ref cmt_rollup_driver.tx * * @param [in] me A sucessfuly initialized state by @ref rollup_driver_init - * @param [in] n size in bytes of the output, contents from @p tx buffer. + * @param [in] length size in bytes of the output, contents from @p tx buffer. * @return * - 0 on success * - negative value on error. -ENOBUFS, or errno values from `ioctl` */ -int cmt_rollup_driver_write_report(struct cmt_rollup_driver *me, uint64_t n); +int cmt_rollup_driver_write_report(struct cmt_rollup_driver *me, uint64_t length); -/** Create a exception, with the first @p n bytes of @ref rollup_driver_t.tx +/** Create a exception, with the first @p length bytes of @ref cmt_rollup_driver tx * * @param [in] me A sucessfuly initialized state by @ref rollup_driver_init - * @param [in] verifiable @p true if this output should be verifiable - * @param [in] n size in bytes of the message, contents from @p tx buffer. + * @param [in] length size in bytes of the message, contents from @p tx buffer. * @return * - 0 on success - * - negative value on error. -ENOBUFS, or errno values from `ioctl` */ -int cmt_rollup_driver_write_exception(struct cmt_rollup_driver *me, uint64_t n); + * - negative value on error. -ENOBUFS, or -errno values from `ioctl` */ +int cmt_rollup_driver_write_exception(struct cmt_rollup_driver *me, uint64_t length); /** Accept this input, wait for the next one. * * @param [in] me A sucessfuly initialized state by @ref rollup_driver_init - * @param [in] accept @p true if this input was processed successfuly - * @param [out] n size in bytes of the current input. + * @param [out] length size in bytes of the newly received input. * @return * - ROLLUP_ADVANCE_STATE On advancing state * - ROLLUP_INSPECT_STATE On inspecting state @@ -81,7 +75,7 @@ int cmt_rollup_driver_write_exception(struct cmt_rollup_driver *me, uint64_t n); * * @note This call expects the tx buffer to have the merkle root hash of the * outputs. It as part of its interface. */ -int cmt_rollup_driver_accept_and_wait_next_input(struct cmt_rollup_driver *me, size_t *n); +int cmt_rollup_driver_accept_and_wait_next_input(struct cmt_rollup_driver *me, size_t *length); /** Revert state back to how it was the last time @ref * rollup_driver_accept_and_wait_next_input got called and reject this input @@ -94,21 +88,21 @@ int cmt_rollup_driver_revert(struct cmt_rollup_driver *me); /** Retrieve the writable memory region @p tx * @param [in] me A sucessfuly initialized state by @ref rollup_driver_init - * @param [out] max size of the region in bytes. + * @param [out] max size of the region in bytes (optional). * * @return * - pointer to the buffer. * @note memory is valid until @ref rollup_driver_fini is called. */ -void *cmt_rollup_driver_get_tx(struct cmt_rollup_driver *me, size_t *max); +void *cmt_rollup_driver_get_tx(struct cmt_rollup_driver *me, size_t *length); /** Retrieve the writable memory region @p rx * @param [in] me A sucessfuly initialized state by @ref rollup_driver_init - * @param [out] max size of the region in bytes. + * @param [out] max size of the region in bytes (optional). * * @return * - pointer to the buffer. * @note memory is valid until @ref rollup_driver_fini is called. */ -void *cmt_rollup_driver_get_rx(struct cmt_rollup_driver *me, size_t *max); +void *cmt_rollup_driver_get_rx(struct cmt_rollup_driver *me, size_t *length); #endif /* ROLLUP_API_H */ /** @} */ diff --git a/linux/libcmt/include/libcmt/rollup.h b/linux/libcmt/include/libcmt/rollup.h index 6b1e7e69..65854644 100644 --- a/linux/libcmt/include/libcmt/rollup.h +++ b/linux/libcmt/include/libcmt/rollup.h @@ -8,10 +8,10 @@ * @{ */ #ifndef CMT_ROLLUP_H #define CMT_ROLLUP_H -#include"rollup-driver.h" -#include"buf.h" #include"abi.h" +#include"buf.h" #include"merkle.h" +#include"rollup-driver.h" /** Opaque rollup state, initialize with: * - @ref cmt_rollup_init */ @@ -22,20 +22,23 @@ typedef struct { cmt_merkle_t merkle[1]; } cmt_rollup_t; +/** Public struct with the advance state contents */ typedef struct { - uint8_t sender[CMT_ADDRESS_LENGTH]; - uint64_t blockNumber; - uint64_t blockTimestamp; - uint64_t index; - size_t length; - void *data; + uint8_t sender[CMT_ADDRESS_LENGTH]; /**< the address of the input sender */ + uint64_t block_number; /**< block number of this input */ + uint64_t block_timestamp; /**< block timestamp of this input UNIX epoch format) */ + uint64_t index; /**< input index (in relation to all inputs ever sent to the DApp) */ + size_t length; /**< length in bytes of the data field */ + void *data; /**< advance contents */ } cmt_rollup_advance_t; +/** Public struct with the inspect state contents */ typedef struct { - size_t length; - void *data; + size_t length; /**< length in bytes of the data field */ + void *data; /**< inspect contents */ } cmt_rollup_inspect_t; +/** Public struct with the finish state contents */ typedef struct { bool accept_previous_request; int next_request_type; @@ -45,8 +48,9 @@ typedef struct { /** Initialize a @ref cmt_rollup_t state. * * @param [in] me uninitialized state - * @return - * - 0 success */ + * + * - 0 success + * - negative value on error. values from: @ref cmt_rollup_driver_init */ int cmt_rollup_init(cmt_rollup_t *me); @@ -103,8 +107,7 @@ cmt_rollup_emit_report(cmt_rollup_t *me * * @return * - 0 success - * - -ENOBUFS no space left in @p me - * - -EDOM at least one of the integers is too large to 64bits */ + * - negative value on error. */ int cmt_rollup_read_advance_state(cmt_rollup_t *me ,cmt_rollup_advance_t *advance); @@ -113,14 +116,22 @@ cmt_rollup_read_advance_state(cmt_rollup_t *me * * @return * - 0 success - * - -ENOBUFS no space left in @p me - * - -EDOM at least one of the integers is too large to 64bits */ + * - negative value on error. */ int cmt_rollup_read_inspect_state(cmt_rollup_t *me ,cmt_rollup_inspect_t *inspect); -/** +/* Finishes processing of current advance or inspect. + * Waits for and returns the next advance or inspect query when available. + * + * @param [in,out] me initialized cmt_rollup_t instance + * @param [in,out] finish initialized cmt_rollup_finish_t instance * + * @return + * - 0 success + * - negative value on error. Values from either @ref + * cmt_rollup_driver_accept_and_wait_next_input or @ref + * cmt_rollup_driver_revert. */ int cmt_rollup_finish(cmt_rollup_t *me, cmt_rollup_finish_t *finish); diff --git a/linux/libcmt/include/libcmt/yield-driver-api.h b/linux/libcmt/include/libcmt/yield-driver-api.h index 9951a551..1d014a3b 100644 --- a/linux/libcmt/include/libcmt/yield-driver-api.h +++ b/linux/libcmt/include/libcmt/yield-driver-api.h @@ -3,9 +3,19 @@ * Abstraction of the Cartesi yield driver IOCTL API * * Lets look at some code: + * - Define a yield struct to store the state. + * - retrieve a floating point number from the user. + * - initialize, yield the value, then finalize the state. * * @include examples/yield-driver.c * + * when executed: + * + * @code + * $ yield-driver --progress=100 + * Progress: 100.00 + * @endcode + * * @ingroup driver * @{ */ #ifndef CMT_YIELD_DRIVER_API_H @@ -18,7 +28,7 @@ typedef struct cmt_yield_driver cmt_yield_driver_t; /** Open the rollup device and initialize the driver * - * @param [in] me A uninitialized @ref rollup_driver_t state + * @param [in] me A uninitialized @ref cmt_yield_driver state * @returns * - 0 on success * - negative value on error. errno values from `open`. */ @@ -26,13 +36,9 @@ int cmt_yield_driver_init(struct cmt_yield_driver *me); /** Close the rollup device and un-initialize the driver * - * @param [in] me A uninitialized @ref rollup_driver_t state - * @returns - * - 0 on success - * - negative value on error. errno values from `close`. - * + * @param [in] me A initialized @ref cmt_yield_driver state (with: @ref cmt_yield_driver_init) * @note usage of @p me after this call is a BUG and will cause undefined behaviour */ -int cmt_yield_driver_fini(struct cmt_yield_driver *me); +void cmt_yield_driver_fini(struct cmt_yield_driver *me); /** Report the application progress to the emulator. * diff --git a/linux/libcmt/src/abi.c b/linux/libcmt/src/abi.c index 7ff3a493..a2963f69 100644 --- a/linux/libcmt/src/abi.c +++ b/linux/libcmt/src/abi.c @@ -22,7 +22,7 @@ int cmt_abi_put_funsel(cmt_buf_t *me, uint32_t funsel) return 0; } -int cmt_abi_encode_uint_nr(size_t n, const uint8_t data[n], uint8_t out[CMT_WORD_LENGTH]) +int cmt_abi_encode_uint_nr(size_t n, const uint8_t *data, uint8_t out[CMT_WORD_LENGTH]) { if (n > CMT_WORD_LENGTH) return EDOM; @@ -35,7 +35,7 @@ int cmt_abi_encode_uint_nr(size_t n, const uint8_t data[n], uint8_t out[CMT_WORD return 0; } -int cmt_abi_encode_uint_nn(size_t n, const uint8_t data[n], uint8_t out[CMT_WORD_LENGTH]) +int cmt_abi_encode_uint_nn(size_t n, const uint8_t *data, uint8_t out[CMT_WORD_LENGTH]) { if (n > CMT_WORD_LENGTH) return EDOM; @@ -57,7 +57,7 @@ int cmt_abi_encode_uint(size_t n, const void *data, uint8_t out[CMT_WORD_LENGTH] #endif } -int cmt_abi_decode_uint_nr(const uint8_t data[CMT_WORD_LENGTH], size_t n, uint8_t out[n]) +int cmt_abi_decode_uint_nr(const uint8_t data[CMT_WORD_LENGTH], size_t n, uint8_t *out) { if (n > CMT_WORD_LENGTH) return EDOM; @@ -69,7 +69,7 @@ int cmt_abi_decode_uint_nr(const uint8_t data[CMT_WORD_LENGTH], size_t n, uint8_ return 0; } -int cmt_abi_decode_uint_nn(const uint8_t data[CMT_WORD_LENGTH], size_t n, uint8_t out[n]) +int cmt_abi_decode_uint_nn(const uint8_t data[CMT_WORD_LENGTH], size_t n, uint8_t *out) { if (n > CMT_WORD_LENGTH) return EDOM; @@ -81,7 +81,7 @@ int cmt_abi_decode_uint_nn(const uint8_t data[CMT_WORD_LENGTH], size_t n, uint8_ return 0; } -int cmt_abi_decode_uint(const uint8_t data[CMT_WORD_LENGTH], size_t n, uint8_t out[n]) +int cmt_abi_decode_uint(const uint8_t data[CMT_WORD_LENGTH], size_t n, uint8_t *out) { #if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ return cmt_abi_decode_uint_nn(data, n, out); diff --git a/linux/libcmt/src/buf.c b/linux/libcmt/src/buf.c index 39fa3e45..421290e7 100644 --- a/linux/libcmt/src/buf.c +++ b/linux/libcmt/src/buf.c @@ -1,18 +1,26 @@ -#include #include #include #include #include +static inline int is_pow2(int l) +{ + return l & (l-1); +} + void cmt_buf_init(cmt_buf_t *me, size_t n, void *data) { - assert(me); + if (!me) return; me->begin = (uint8_t *)data; me->end = (uint8_t *)data + n; } + int cmt_buf_split(const cmt_buf_t *me, size_t n, cmt_buf_t *lhs, cmt_buf_t *rhs) { - assert(me); + if (!me) return -EINVAL; + if (!lhs) return -EINVAL; + if (!rhs) return -EINVAL; + lhs->begin = me->begin; lhs->end = rhs->begin = me->begin + n; rhs->end = me->end; @@ -22,7 +30,7 @@ int cmt_buf_split(const cmt_buf_t *me, size_t n, cmt_buf_t *lhs, cmt_buf_t *rhs) size_t cmt_buf_length(const cmt_buf_t *me) { - assert(me); + if (!me) return 0; return me->end - me->begin; } @@ -39,12 +47,13 @@ static void xxd(const uint8_t *p, const uint8_t *q, size_t mask) printf("%02x%c", p[i], separator); } } + void cmt_buf_xxd(void *p, void *q, int l) { - assert(p); - assert(q); - assert(p <= q); - assert((l & (l-1)) == 0 && "l is required to be a power of 2"); + if (!p) return; + if (!q) return; + if (q <= p) return; + if (!is_pow2(l)) return; xxd(p, q, l-1); } diff --git a/linux/libcmt/src/ioctl/rollup-driver.c b/linux/libcmt/src/ioctl/rollup-driver.c index b950b9f0..56691724 100644 --- a/linux/libcmt/src/ioctl/rollup-driver.c +++ b/linux/libcmt/src/ioctl/rollup-driver.c @@ -14,6 +14,7 @@ int cmt_rollup_driver_init(struct cmt_rollup_driver *me) { int rc = 0; + if (!me) return -EINVAL; me->fd = open("/dev/rollup", O_RDWR); if (me->fd < 0) return -errno; @@ -52,30 +53,48 @@ int cmt_rollup_driver_init(struct cmt_rollup_driver *me) return rc; } -int cmt_rollup_driver_fini(struct cmt_rollup_driver *me) +void cmt_rollup_driver_fini(struct cmt_rollup_driver *me) { + if (!me) return -EINVAL; munmap(me->tx->data, me->tx->length); munmap(me->rx->data, me->rx->length); - return close(me->fd); + close(me->fd); + + me->tx->data = NULL; + me->tx->length = 0; + me->rx->data = NULL; + me->rx->length = 0; + me->fd = -1; } int cmt_rollup_driver_write_output(struct cmt_rollup_driver *me, uint64_t n) { - return ioctl(me->fd, IOCTL_ROLLUP_WRITE_OUTPUT, (unsigned long) &n); + if (!me) return -EINVAL; + if (ioctl(me->fd, IOCTL_ROLLUP_WRITE_OUTPUT, (unsigned long) &n)) + return -errno; + return 0; } int cmt_rollup_driver_write_report(struct cmt_rollup_driver *me, uint64_t n) { - return ioctl(me->fd, IOCTL_ROLLUP_WRITE_REPORT, (unsigned long) &n); + if (!me) return -EINVAL; + if (ioctl(me->fd, IOCTL_ROLLUP_WRITE_REPORT, (unsigned long) &n)) + return -errno; + return 0; } int cmt_rollup_driver_write_exception(struct cmt_rollup_driver *me, uint64_t n) { - return ioctl(me->fd, IOCTL_ROLLUP_WRITE_EXCEPTION, (unsigned long) &n); + if (!me) return -EINVAL; + if (ioctl(me->fd, IOCTL_ROLLUP_WRITE_EXCEPTION, (unsigned long) &n)) + return -errno; + return 0; } int cmt_rollup_driver_accept_and_wait_next_input(struct cmt_rollup_driver *me, uint64_t *n) { + if (!me) return -EINVAL; + if (!n) return -EINVAL; switch (ioctl(me->fd, IOCTL_ROLLUP_ACCEPT_AND_WAIT_NEXT_INPUT, (unsigned long) n)) { case ROLLUP_ADVANCE_STATE: return CMT_ROLLUP_ADVANCE_STATE; case ROLLUP_INSPECT_STATE: return CMT_ROLLUP_INSPECT_STATE; @@ -85,17 +104,22 @@ int cmt_rollup_driver_accept_and_wait_next_input(struct cmt_rollup_driver *me, u int cmt_rollup_driver_revert(struct cmt_rollup_driver *me) { - return ioctl(me->fd, IOCTL_ROLLUP_REJECT_INPUT); + if (!me) return -EINVAL; + if (ioctl(me->fd, IOCTL_ROLLUP_REJECT_INPUT)) + return -errno; + return 0; } void *cmt_rollup_driver_get_tx(struct cmt_rollup_driver *me, size_t *max) { - *max = me->tx->length; + if (max) + *max = me->tx->length; return me->tx->data; } void *cmt_rollup_driver_get_rx(struct cmt_rollup_driver *me, size_t *max) { - *max = me->rx->length; + if (max) + *max = me->rx->length; return me->rx->data; } diff --git a/linux/libcmt/src/ioctl/yield-driver.c b/linux/libcmt/src/ioctl/yield-driver.c index 8e56b65c..6d016e18 100644 --- a/linux/libcmt/src/ioctl/yield-driver.c +++ b/linux/libcmt/src/ioctl/yield-driver.c @@ -16,12 +16,12 @@ int cmt_yield_driver_init(struct cmt_yield_driver *me) return 0; } -int cmt_yield_driver_fini(struct cmt_yield_driver *me) +void cmt_yield_driver_fini(struct cmt_yield_driver *me) { - if (!me) return -EINVAL; - if (close(me->fd)) - return -errno; - return 0; + if (!me) return; + close(me->fd); + + me->fd = -1; } int cmt_yield_driver_progress(struct cmt_yield_driver *me, uint32_t progress) @@ -33,5 +33,7 @@ int cmt_yield_driver_progress(struct cmt_yield_driver *me, uint32_t progress) .reason = (uint64_t)HTIF_YIELD_REASON_PROGRESS, .data = progress, }; - return ioctl(me->fd, IOCTL_YIELD, (unsigned long)&req); + if (ioctl(me->fd, IOCTL_YIELD, (unsigned long)&req)) + return -errno; + return 0; } diff --git a/linux/libcmt/src/merkle.c b/linux/libcmt/src/merkle.c index d55accc3..e4b7fd19 100644 --- a/linux/libcmt/src/merkle.c +++ b/linux/libcmt/src/merkle.c @@ -1,6 +1,7 @@ #include #include #include +#include #include extern const uint8_t cmt_merkle_table[][CMT_KECCAK_LENGTH]; @@ -16,20 +17,20 @@ static void hash2 cmt_keccak_final(c, out); } -void cmt_merkle_init(cmt_merkle_t me[1]) +void cmt_merkle_init(cmt_merkle_t *me) { me->n = 0; me->zero = cmt_merkle_table; memcpy(me->state, me->zero, sizeof(me->state)); } -void cmt_merkle_fini(cmt_merkle_t me[1]) +void cmt_merkle_fini(cmt_merkle_t *me) { // noop (void)me; } -int cmt_merkle_push_back(cmt_merkle_t me[1], uint8_t hash[CMT_KECCAK_LENGTH]) +int cmt_merkle_push_back(cmt_merkle_t *me, uint8_t hash[CMT_KECCAK_LENGTH]) { if (me->n == UINT64_MAX) return -ENOBUFS; @@ -41,7 +42,7 @@ int cmt_merkle_push_back(cmt_merkle_t me[1], uint8_t hash[CMT_KECCAK_LENGTH]) return 0; } -void cmt_merkle_get_root_hash(cmt_merkle_t me[1], uint8_t root[CMT_KECCAK_LENGTH]) +void cmt_merkle_get_root_hash(cmt_merkle_t *me, uint8_t root[CMT_KECCAK_LENGTH]) { /* n is bound by CMT_MERKLE_MAX_DEPTH-1u */ unsigned n = ((uint64_t)ffsll(me->n)-1u) & (CMT_MERKLE_MAX_DEPTH-1u); @@ -54,7 +55,7 @@ void cmt_merkle_get_root_hash(cmt_merkle_t me[1], uint8_t root[CMT_KECCAK_LENGTH } } -int cmt_merkle_push_back_data(cmt_merkle_t me[1], size_t n, void *data) +int cmt_merkle_push_back_data(cmt_merkle_t *me, size_t n, void *data) { uint8_t hash[CMT_KECCAK_LENGTH]; CMT_KECCAK_DECL(c); diff --git a/linux/libcmt/src/mock/rollup-driver.c b/linux/libcmt/src/mock/rollup-driver.c index a08a5f6a..f173c015 100644 --- a/linux/libcmt/src/mock/rollup-driver.c +++ b/linux/libcmt/src/mock/rollup-driver.c @@ -8,6 +8,7 @@ int cmt_rollup_driver_init(struct cmt_rollup_driver *me) { + if (!me) return -EINVAL; me->input_seq =-1; me->output_seq = 0; me->report_seq = 0; @@ -24,11 +25,11 @@ int cmt_rollup_driver_init(struct cmt_rollup_driver *me) return 0; } -int cmt_rollup_driver_fini(struct cmt_rollup_driver *me) +void cmt_rollup_driver_fini(struct cmt_rollup_driver *me) { + if (!me) return; free(me->tx->data); free(me->rx->data); - return 0; } static int cmt_rollup_driver_mock_write(struct cmt_rollup_driver *me, size_t n, const char *filename) @@ -53,6 +54,7 @@ static int cmt_rollup_driver_mock_write(struct cmt_rollup_driver *me, size_t n, int cmt_rollup_driver_write_output(struct cmt_rollup_driver *me, size_t n) { char filename[1024]; + if (!me) return -EINVAL; snprintf(filename, sizeof(filename), "input-%u-output-%u.bin", me->input_seq, ++me->output_seq - 1); return cmt_rollup_driver_mock_write(me, n, filename); @@ -61,6 +63,7 @@ int cmt_rollup_driver_write_output(struct cmt_rollup_driver *me, size_t n) int cmt_rollup_driver_write_report(struct cmt_rollup_driver *me, size_t n) { char filename[1024]; + if (!me) return -EINVAL; snprintf(filename, sizeof(filename), "input-%u-report-%u.bin", me->input_seq, ++me->output_seq - 1); return cmt_rollup_driver_mock_write(me, n, filename); @@ -68,8 +71,9 @@ int cmt_rollup_driver_write_report(struct cmt_rollup_driver *me, size_t n) int cmt_rollup_driver_write_exception(cmt_rollup_driver_t *me, uint64_t n) { + if (!me) return -EINVAL; if (me->tx->len < n) - return ENOBUFS; + return -ENOBUFS; fprintf(stderr, "rollup exception with payload: \"%.*s\"\n", (int)me->tx->len, (char *)me->tx->data); @@ -99,7 +103,8 @@ int cmt_rollup_driver_accept_and_wait_next_input(struct cmt_rollup_driver *me, s char b[1024]; FILE *file = NULL; - if (me->input_seq != -1) { /* don't write the first outputs_root_hash */ + if (!me) return -EINVAL; + if (me->input_seq != -1) { /* don't write outputs_root_hash of the first accept */ snprintf(b, sizeof(b), "input-%u-outputs-root-hash.bin", me->input_seq); file = fopen(b, "wb"); @@ -122,18 +127,20 @@ int cmt_rollup_driver_accept_and_wait_next_input(struct cmt_rollup_driver *me, s int cmt_rollup_driver_revert(struct cmt_rollup_driver *me) { - (void)me; + if (!me) return -EINVAL; fprintf(stderr, "%s:%d revert\n", __FILE__, __LINE__); exit(0); // should revert, but this implementation can't deal with it... } void *cmt_rollup_driver_get_tx(struct cmt_rollup_driver *me, size_t *max) { - *max = me->tx->len; + if (max) + *max = me->tx->len; return me->tx->data; } void *cmt_rollup_driver_get_rx(struct cmt_rollup_driver *me, size_t *max) { - *max = me->rx->len; + if (max) + *max = me->rx->len; return me->rx->data; } diff --git a/linux/libcmt/src/mock/yield-driver.c b/linux/libcmt/src/mock/yield-driver.c index e360b52c..a611ae5e 100644 --- a/linux/libcmt/src/mock/yield-driver.c +++ b/linux/libcmt/src/mock/yield-driver.c @@ -1,5 +1,4 @@ #include -#include #include #include "yield-driver.h" @@ -9,15 +8,14 @@ int cmt_yield_driver_init(struct cmt_yield_driver *me) return 0; } -int cmt_yield_driver_progress(struct cmt_yield_driver *me, uint32_t progress) +void cmt_yield_driver_fini(struct cmt_yield_driver *me) { - if (!me) return -EINVAL; - fprintf(stderr, "Progress: %u.%02u\n", progress / 10, progress % 10 * 10); - return 0; + if (!me) return; } -int cmt_yield_driver_fini(struct cmt_yield_driver *me) +int cmt_yield_driver_progress(struct cmt_yield_driver *me, uint32_t progress) { if (!me) return -EINVAL; + fprintf(stderr, "Progress: %u.%02u\n", progress / 10, progress % 10 * 10); return 0; } diff --git a/linux/libcmt/src/rollup.c b/linux/libcmt/src/rollup.c index 739ce768..d40bb7f8 100644 --- a/linux/libcmt/src/rollup.c +++ b/linux/libcmt/src/rollup.c @@ -97,8 +97,8 @@ int cmt_rollup_read_advance_state(cmt_rollup_t *me, cmt_rollup_advance_t *advanc if (cmt_abi_check_funsel(rd, EVM_ADVANCE) || (rc = cmt_abi_get_address(rd, advance->sender)) - || (rc = cmt_abi_get_uint(rd, sizeof(advance->blockNumber), &advance->blockNumber)) - || (rc = cmt_abi_get_uint(rd, sizeof(advance->blockTimestamp), &advance->blockTimestamp)) + || (rc = cmt_abi_get_uint(rd, sizeof(advance->block_number), &advance->block_number)) + || (rc = cmt_abi_get_uint(rd, sizeof(advance->block_timestamp), &advance->block_timestamp)) || (rc = cmt_abi_get_uint(rd, sizeof(advance->index), &advance->index)) || (rc = cmt_abi_get_bytes_s(rd, of)) || (rc = cmt_abi_get_bytes_d(st, of, &advance->length, &advance->data))) diff --git a/linux/libcmt/tests/abi.c b/linux/libcmt/tests/abi.c index 210ddf5b..53cc47cd 100644 --- a/linux/libcmt/tests/abi.c +++ b/linux/libcmt/tests/abi.c @@ -4,6 +4,22 @@ #include #include +/** Declare a cmt_buf_t with stack backed memory. + * @param [in] N - size in bytes + * @note don't port */ +#define CMT_BUF_DECL(S, L) cmt_buf_t S[1] = {{ \ + .begin = (uint8_t [L]){0}, \ + .end = (S)->begin + L, \ + }} + +/** Declare a cmt_buf_t with parameters backed memory. + * @param [in] L - size in bytes + * @note don't port */ +#define CMT_BUF_DECL3(S, L, P) cmt_buf_t S[1] = {{ \ + .begin = P, \ + .end = (S)->begin + L, \ + }} + static void encode_u8() { uint8_t x = 0x01; diff --git a/linux/libcmt/tools/templates/libcmt.pc b/linux/libcmt/tools/templates/libcmt.pc new file mode 100644 index 00000000..3ec01b90 --- /dev/null +++ b/linux/libcmt/tools/templates/libcmt.pc @@ -0,0 +1,10 @@ +prefix=ARG_PREFIX +exec_prefix=${prefix} +includedir=${prefix}/include +libdir=${exec_prefix}/lib + +Name: libcmt +Description: The Cartesi Machine Tools library +Version: 0.0.1 +Cflags: -I${includedir} -I${includedir}/libcmt +Libs: -L${libdir} -lcmt diff --git a/linux/libcmt/tools/templates/libcmt_mock.pc b/linux/libcmt/tools/templates/libcmt_mock.pc new file mode 100644 index 00000000..fb912937 --- /dev/null +++ b/linux/libcmt/tools/templates/libcmt_mock.pc @@ -0,0 +1,10 @@ +prefix=ARG_PREFIX +exec_prefix=${prefix} +includedir=${prefix}/include +libdir=${exec_prefix}/lib + +Name: libcmt_mock +Description: The Cartesi Machine Tools library +Version: 0.0.1 +Cflags: -I${includedir} -I${includedir}/libcmt/mock +Libs: -L${libdir} -lcmt_mock -fsanitize=address,undefined