cmd/recordexec: Also save proposed blocks to filesystem - #1
Draft
hi-im-milan wants to merge 1 commit into
Draft
hi-im-milan wants to merge 1 commit into
hi-im-milan wants to merge 1 commit into
Conversation
We can dump all the proposed blocks to the filesystem in `proposals` subdir and once they get finalised - simply move them to the correct archive directory. Benefit of this approach is that applications ingesting monad events can rely completely on the filesystem operations (including inotify) to detect new blocks, without waiting for block to be verified. This is a RFC commit, there are things that need to be cleaned up + it hasn't been tested. I think this approach shouldn't add much overhead, unless we are expecting to have lot of blocks which are proposed but not verified. rename(2) should be pretty much an instant operation as long as src and dst are on the same filesystem (which should be the case). This feature can also be optionally enabled. Signed-off-by: Milan Pandurov <milan.pandurov@tenderly.co>
kjcamann
pushed a commit
that referenced
this pull request
Sep 5, 2026
dump_result loaded a full uint256_t out of result.output_data whenever
output_size was non-zero. Context::copy_result_data allocates that buffer
with std::malloc(*size) for exactly the size the executed bytecode passes
to RETURN, so any RETURN of 1..31 bytes over-read the allocation by up to
31 bytes and hex-printed adjacent heap into the tool's JSON. The same
load silently truncated results longer than 32 bytes to their first word.
Hex-encode exactly output_size bytes instead, which fixes both.
Bytecode returning a single byte 0x2a, run three times before the fix:
$ printf '602a60005360016000f3' > ret1.hex
$ mce -r ret1.hex
{"result": "2a00099925560000000000000000000030306633000000006102000000000000"}
{"result": "2a46eb64be600000000000000000000030306633000000006102000000000000"}
{"result": "2a731c3e85600000000000000000000030306633000000006102000000000000"}
Only the leading 2a is the result; the other 31 bytes are adjacent heap
and differ per run. The recurring 30306633 is ASCII "00f3", the tail of
the input file's own hex text. After the fix that input prints
{"result": "2a"} on every run.
The truncation is the same defect from the other side - 64 returned
bytes rendered as one digit before the fix:
$ printf '60406000f3' > ret64.hex
$ mce -r ret64.hex
{"result": "0"}
and now prints all 128 hex digits.
Output format changes for results that are not exactly one word wide: a
32-byte RETURN of 42 renders as 64 zero-padded hex digits rather than
"2a". Nothing consumes this output - the only references to mce outside
its own sources are cmd/vm/mce/CMakeLists.txt and cmd/CMakeLists.txt.
category/vm/compiler/types.hpp is dropped alongside the two integer
headers; it was included only for its uint256_t alias, used solely on
the removed line.
Confirmed under gcc-asan. Before, on the one-byte return:
ERROR: AddressSanitizer: heap-buffer-overflow
READ of size 32 at 0x72602abe01f0
category-labs#3 dump_result cmd/vm/mce/mce.cpp:154
0x72602abe01f1 is located 0 bytes after 1-byte region
allocated by:
#1 Context::copy_result_data category/vm/runtime/context.cpp:208
After: no overflow on returns of 0, 1, 32 or 64 bytes.
The pre-existing heap-use-after-free at mce_main scope exit - Binary bin
is declared before asmjit::JitRuntime rt, so rt is destroyed first and
bin's shared_ptr<Nativecode> releases into the freed JitAllocator - is
left untouched for a separate change.
Raised as EXEC-063 in the mythos-review audit batch (EXE-150).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What?
We can dump all the proposed blocks to the filesystem in
proposalssubdir and once they get finalised - simply move them to the correct archive directory. Benefit of this approach is that applications ingesting monad events can rely completely on the filesystem operations (including inotify) to detect new blocks, without waiting for block to be verified.This is a RFC commit, there are things that need to be cleaned up + it hasn't been tested.
I think this approach shouldn't add much overhead, unless we are expecting to have lot of blocks which are proposed but not verified. rename(2) should be pretty much an instant operation as long as src and dst are on the same filesystem (which should be the case). This feature can also be optionally enabled.