From b4135956b34a2576ecec848de4461de57e4ec077 Mon Sep 17 00:00:00 2001 From: Marcelo Politzer <251334+mpolitzer@users.noreply.github.com> Date: Wed, 8 Jan 2025 12:25:20 -0300 Subject: [PATCH] feat: add delegate call voucher to libcmt --- sys-utils/libcmt/include/libcmt/rollup.h | 16 +++++++ sys-utils/libcmt/src/rollup.c | 53 ++++++++++++++++++++++++ sys-utils/libcmt/tests/create-data.sh | 6 +++ sys-utils/libcmt/tests/data.h | 13 ++++++ sys-utils/libcmt/tests/rollup.c | 8 ++++ 5 files changed, 96 insertions(+) diff --git a/sys-utils/libcmt/include/libcmt/rollup.h b/sys-utils/libcmt/include/libcmt/rollup.h index d50e726..1ba2cc8 100644 --- a/sys-utils/libcmt/include/libcmt/rollup.h +++ b/sys-utils/libcmt/include/libcmt/rollup.h @@ -111,6 +111,22 @@ void cmt_rollup_fini(cmt_rollup_t *me); * |< 0| failure with a -errno value | */ int cmt_rollup_emit_voucher(cmt_rollup_t *me, const cmt_abi_address_t *address, const cmt_abi_u256_t *value, const cmt_abi_bytes_t *data, uint64_t *index); +/** Emit a voucher + * + * Equivalent to the `DelegateCallVoucher(address,bytes)` solidity call. + * + * @param [in,out] me initialized @ref cmt_rollup_t instance + * @param [in] address destination data + * @param [in] data message contents + * @param [out] index index of emitted voucher, if successful + * + * @return + * | | | + * |--:|-----------------------------| + * | 0| success | + * |< 0| failure with a -errno value | */ +int cmt_rollup_emit_delegate_call_voucher(cmt_rollup_t *me, const cmt_abi_address_t *address, const cmt_abi_bytes_t *data, uint64_t *index); + /** Emit a notice * * @param [in,out] me initialized cmt_rollup_t instance diff --git a/sys-utils/libcmt/src/rollup.c b/sys-utils/libcmt/src/rollup.c index 0cc3c34..84b0973 100644 --- a/sys-utils/libcmt/src/rollup.c +++ b/sys-utils/libcmt/src/rollup.c @@ -25,6 +25,9 @@ // Voucher(address,uint256,bytes) #define VOUCHER CMT_ABI_FUNSEL(0x23, 0x7a, 0x81, 0x6f) +// DelegateCallVoucher(address,bytes) +#define DELEGATE_CALL_VOUCHER CMT_ABI_FUNSEL(0x10, 0x32, 0x1e, 0x8b) + // Notice(bytes) #define NOTICE CMT_ABI_FUNSEL(0xc2, 0x58, 0xd6, 0xe5) @@ -117,6 +120,56 @@ int cmt_rollup_emit_voucher(cmt_rollup_t *me, const cmt_abi_address_t *address, return 0; } +int cmt_rollup_emit_delegate_call_voucher(cmt_rollup_t *me, + const cmt_abi_address_t *address, const cmt_abi_bytes_t *payload, uint64_t *index) { + if (!me) { + return -EINVAL; + } + if (!payload || (!payload->data && payload->length)) { + return -EINVAL; + } + + cmt_buf_t tx[1] = {cmt_io_get_tx(me->io)}; + cmt_buf_t wr[1] = {*tx}; + cmt_buf_t of[1]; + cmt_buf_t frame[1]; + + // clang-format off + if (DBG(cmt_abi_put_funsel(wr, DELEGATE_CALL_VOUCHER)) + || DBG(cmt_abi_mark_frame(wr, frame)) + || DBG(cmt_abi_put_address(wr, address)) + || DBG(cmt_abi_put_bytes_s(wr, of)) + || DBG(cmt_abi_put_bytes_d(wr, of, frame, payload))) { + return -ENOBUFS; + } + // clang-format on + + size_t used_space = wr->begin - tx->begin; + struct cmt_io_yield req[1] = {{ + .dev = HTIF_DEVICE_YIELD, + .cmd = HTIF_YIELD_CMD_AUTOMATIC, + .reason = HTIF_YIELD_AUTOMATIC_REASON_TX_OUTPUT, + .data = used_space, + }}; + int rc = DBG(cmt_io_yield(me->io, req)); + if (rc) { + return rc; + } + + uint64_t count = cmt_merkle_get_leaf_count(me->merkle); + + rc = cmt_merkle_push_back_data(me->merkle, used_space, tx->begin); + if (rc) { + return rc; + } + + if (index) { + *index = count; + } + + return 0; +} + int cmt_rollup_emit_notice(cmt_rollup_t *me, const cmt_abi_bytes_t *payload, uint64_t *index) { if (!me) { return -EINVAL; diff --git a/sys-utils/libcmt/tests/create-data.sh b/sys-utils/libcmt/tests/create-data.sh index d98096c..6f0290d 100755 --- a/sys-utils/libcmt/tests/create-data.sh +++ b/sys-utils/libcmt/tests/create-data.sh @@ -45,5 +45,11 @@ echo "uint8_t valid_gio_reply_0[] = {" echo -en "gio-reply-0" | xxd -i echo "};" +echo "uint8_t valid_delegate_call_voucher_0[] = {" +cast calldata "DelegateCallVoucher(address,bytes)" \ + 0x0000000000000000000000000000000000000001 \ + 0x`echo -en "delegate-call-voucher-0" | xxd -p -c0` | xxd -r -p | xxd -i +echo "};" + echo "#endif /* DATA_H */" diff --git a/sys-utils/libcmt/tests/data.h b/sys-utils/libcmt/tests/data.h index eb7d44b..ca68f31 100644 --- a/sys-utils/libcmt/tests/data.h +++ b/sys-utils/libcmt/tests/data.h @@ -69,4 +69,17 @@ uint8_t valid_notice_0[] = { uint8_t valid_gio_reply_0[] = { 0x67, 0x69, 0x6f, 0x2d, 0x72, 0x65, 0x70, 0x6c, 0x79, 0x2d, 0x30 }; +uint8_t valid_delegate_call_voucher_0[] = { + 0x10, 0x32, 0x1e, 0x8b, 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, 0x40, 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, 0x17, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, + 0x2d, 0x63, 0x61, 0x6c, 0x6c, 0x2d, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, + 0x72, 0x2d, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; #endif /* DATA_H */ diff --git a/sys-utils/libcmt/tests/rollup.c b/sys-utils/libcmt/tests/rollup.c index ec34b68..bc81da8 100644 --- a/sys-utils/libcmt/tests/rollup.c +++ b/sys-utils/libcmt/tests/rollup.c @@ -205,6 +205,14 @@ void test_rollup_outputs_reports_and_exceptions(void) { assert(cmt_rollup_emit_exception(&rollup, &(cmt_abi_bytes_t){strlen(exception_data), NULL}) == -EINVAL); assert(cmt_rollup_emit_exception(&rollup, &(cmt_abi_bytes_t){UINT32_MAX, exception_data}) == -ENOBUFS); + // delegate voucher + char delegate_call_voucher_data[] = "delegate-call-voucher-0"; + assert(cmt_rollup_emit_delegate_call_voucher(&rollup, &address, &(cmt_abi_bytes_t){strlen(delegate_call_voucher_data), delegate_call_voucher_data}, &index) == 0); + assert(cmt_util_read_whole_file("none.output-2.bin", sizeof buffer, buffer, &read_size) == 0); + assert(sizeof valid_delegate_call_voucher_0 == read_size); + assert(memcmp(valid_delegate_call_voucher_0, buffer, sizeof valid_delegate_call_voucher_0) == 0); + assert(index == 2); + cmt_rollup_fini(&rollup); printf("test_rollup_outputs_reports_and_exceptions passed!\n"); }