From 8fe6bf256bc8deb281d4ec898373bbd64a1038e7 Mon Sep 17 00:00:00 2001 From: Amir Khordadi Date: Fri, 4 Sep 2026 21:21:37 -0400 Subject: [PATCH] [execution/vm] Add in-tree monad_message type EXE-172, part of EXE-162. monad_message, with monad_call_kind and monad_call_flags, mirrors the fork's evmc_message field-for-field (no code/code_size, evmc 663a1c2; memory_handle/memory/memory_capacity, evmc 8533622). message.cpp asserts standard layout, sizeof, alignof, the offsetof of all 14 fields, the exact type of the 8 integer/pointer fields and the enumerator values. Purely additive; nothing references the type yet. The call-site migration goes with the vm::Host port (EXE-173), where the runtime builds the message itself and no per-call evmc conversion is needed. Co-Authored-By: Claude Fable 5.1 --- category/vm/evm/CMakeLists.txt | 2 + category/vm/evm/message.cpp | 86 ++++++++++++++++++++++++++++++++++ category/vm/evm/message.hpp | 60 ++++++++++++++++++++++++ 3 files changed, 148 insertions(+) create mode 100644 category/vm/evm/message.cpp create mode 100644 category/vm/evm/message.hpp diff --git a/category/vm/evm/CMakeLists.txt b/category/vm/evm/CMakeLists.txt index ed1c950766..3be0d36e4b 100644 --- a/category/vm/evm/CMakeLists.txt +++ b/category/vm/evm/CMakeLists.txt @@ -21,6 +21,8 @@ target_sources(monad-vm-evm PRIVATE "delegation.cpp" "delegation.hpp" "explicit_traits.hpp" + "message.cpp" + "message.hpp" "opcodes.hpp" "opcodes_xmacro.hpp" "revision.cpp" diff --git a/category/vm/evm/message.cpp b/category/vm/evm/message.cpp new file mode 100644 index 0000000000..1c4a9256cc --- /dev/null +++ b/category/vm/evm/message.cpp @@ -0,0 +1,86 @@ +// Copyright (C) 2025-26 Category Labs, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include + +#include + +#include +#include +#include + +// Value equality with evmc_call_kind / evmc_flags. +static_assert(sizeof(monad_call_kind) == sizeof(evmc_call_kind)); + +#define MONAD_ASSERT_ENUM_EQ(name) \ + static_assert( \ + std::to_underlying(MONAD_##name) == std::to_underlying(EVMC_##name)) + +MONAD_ASSERT_ENUM_EQ(CALL); +MONAD_ASSERT_ENUM_EQ(DELEGATECALL); +MONAD_ASSERT_ENUM_EQ(CALLCODE); +MONAD_ASSERT_ENUM_EQ(CREATE); +MONAD_ASSERT_ENUM_EQ(CREATE2); +MONAD_ASSERT_ENUM_EQ(EOFCREATE); +MONAD_ASSERT_ENUM_EQ(STATIC); +MONAD_ASSERT_ENUM_EQ(DELEGATED); + +#undef MONAD_ASSERT_ENUM_EQ + +// Layout equality with evmc_message. +static_assert(std::is_standard_layout_v); +static_assert(std::is_trivially_copyable_v); +static_assert(sizeof(monad_message) == 192); +static_assert(sizeof(monad_message) == sizeof(evmc_message)); +static_assert(alignof(monad_message) == alignof(evmc_message)); + +#define MONAD_ASSERT_MESSAGE_FIELD_EQ(field) \ + static_assert( \ + offsetof(monad_message, field) == offsetof(evmc_message, field)) + +MONAD_ASSERT_MESSAGE_FIELD_EQ(kind); +MONAD_ASSERT_MESSAGE_FIELD_EQ(flags); +MONAD_ASSERT_MESSAGE_FIELD_EQ(depth); +MONAD_ASSERT_MESSAGE_FIELD_EQ(gas); +MONAD_ASSERT_MESSAGE_FIELD_EQ(recipient); +MONAD_ASSERT_MESSAGE_FIELD_EQ(sender); +MONAD_ASSERT_MESSAGE_FIELD_EQ(input_data); +MONAD_ASSERT_MESSAGE_FIELD_EQ(input_size); +MONAD_ASSERT_MESSAGE_FIELD_EQ(value); +MONAD_ASSERT_MESSAGE_FIELD_EQ(create2_salt); +MONAD_ASSERT_MESSAGE_FIELD_EQ(code_address); +MONAD_ASSERT_MESSAGE_FIELD_EQ(memory_handle); +MONAD_ASSERT_MESSAGE_FIELD_EQ(memory); +MONAD_ASSERT_MESSAGE_FIELD_EQ(memory_capacity); + +#undef MONAD_ASSERT_MESSAGE_FIELD_EQ + +// Same offset does not rule out a narrowed field padded back to the next one; +// the enum is pinned above, Address/bytes32_t in their own headers. +#define MONAD_ASSERT_MESSAGE_FIELD_TYPE_EQ(field) \ + static_assert(std::is_same_v< \ + decltype(monad_message::field), \ + decltype(evmc_message::field)>) + +MONAD_ASSERT_MESSAGE_FIELD_TYPE_EQ(flags); +MONAD_ASSERT_MESSAGE_FIELD_TYPE_EQ(depth); +MONAD_ASSERT_MESSAGE_FIELD_TYPE_EQ(gas); +MONAD_ASSERT_MESSAGE_FIELD_TYPE_EQ(input_data); +MONAD_ASSERT_MESSAGE_FIELD_TYPE_EQ(input_size); +MONAD_ASSERT_MESSAGE_FIELD_TYPE_EQ(memory_handle); +MONAD_ASSERT_MESSAGE_FIELD_TYPE_EQ(memory); +MONAD_ASSERT_MESSAGE_FIELD_TYPE_EQ(memory_capacity); + +#undef MONAD_ASSERT_MESSAGE_FIELD_TYPE_EQ diff --git a/category/vm/evm/message.hpp b/category/vm/evm/message.hpp new file mode 100644 index 0000000000..dd1f7f04d4 --- /dev/null +++ b/category/vm/evm/message.hpp @@ -0,0 +1,60 @@ +// Copyright (C) 2025-26 Category Labs, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once + +#include +#include + +#include +#include + +// Mirrors evmc_call_kind 1:1; values asserted equal in message.cpp. +enum monad_call_kind +{ + MONAD_CALL = 0, + MONAD_DELEGATECALL = 1, + MONAD_CALLCODE = 2, + MONAD_CREATE = 3, + MONAD_CREATE2 = 4, + MONAD_EOFCREATE = 5 +}; + +// Mirrors evmc_flags 1:1; values asserted equal in message.cpp. +enum monad_call_flags +{ + MONAD_STATIC = 1, + MONAD_DELEGATED = 2 +}; + +// Mirrors the category-labs fork's evmc_message field-for-field (no +// code/code_size, memory-pool fields present); layout asserted in message.cpp. +struct monad_message +{ + monad_call_kind kind; + uint32_t flags; + int32_t depth; + int64_t gas; + monad::Address recipient; + monad::Address sender; + uint8_t const *input_data; + size_t input_size; + monad::bytes32_t value; + monad::bytes32_t create2_salt; + monad::Address code_address; + uint8_t *memory_handle; + uint8_t *memory; + uint32_t memory_capacity; +};