Add MULMOD to EVMv2#10168
Conversation
Signed-off-by: Ameziane H. <ameziane.hamlat@consensys.net>
Signed-off-by: Ameziane H. <ameziane.hamlat@consensys.net>
Signed-off-by: Ameziane H. <ameziane.hamlat@consensys.net>
Signed-off-by: Ameziane H. <ameziane.hamlat@consensys.net>
Signed-off-by: Ameziane H. <ameziane.hamlat@consensys.net>
Signed-off-by: Ameziane H. <ameziane.hamlat@consensys.net>
Signed-off-by: Ameziane H. <ameziane.hamlat@consensys.net>
Signed-off-by: Ameziane H. <ameziane.hamlat@consensys.net>
Signed-off-by: Simon Dudley <simon.dudley@consensys.net> # Conflicts: # evm/src/main/java/org/hyperledger/besu/evm/v2/StackArithmetic.java
Signed-off-by: Simon Dudley <simon.dudley@consensys.net>
Signed-off-by: Simon Dudley <simon.dudley@consensys.net>
Also update c -> m in benchmarks following (a * b) % m formula Signed-off-by: Simon Dudley <simon.dudley@consensys.net>
|
I might need an additional unit test to cover stack manipulation specifics in MulModOperationV2.staticOperation and StackArithmetic.mulMod |
Tests verify correct stack depth reduction (3→1), result placement, zero-modulus special case, cross-limb arithmetic, and that underflow with 0 or 2 items returns INSUFFICIENT_STACK_ITEMS without mutating the stack. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Simon Dudley <simon.dudley@consensys.net>
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds the MULMOD opcode implementation to the EVMv2 execution path, along with targeted unit tests and JMH benchmarks to validate correctness and measure performance.
Changes:
- Implemented
MULMODas a fixed-cost EVMv2 operation and wired it into the EVMv2 opcode dispatch. - Added
StackArithmetic.mulMod(...)to perform the stack-level limb operation. - Added JUnit tests and new/updated JMH benchmarks for ternary ops and MULMOD.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| evm/src/test/java/org/hyperledger/besu/evm/v2/operation/MulModOperationV2Test.java | Adds correctness + underflow coverage for EVMv2 MULMOD |
| evm/src/main/java/org/hyperledger/besu/evm/v2/operation/MulModOperationV2.java | Introduces the v2 MULMOD operation wrapper + static fast path |
| evm/src/main/java/org/hyperledger/besu/evm/v2/StackArithmetic.java | Adds mulMod stack arithmetic helper for v2 execution |
| evm/src/main/java/org/hyperledger/besu/evm/EVM.java | Wires opcode 0x09 to v2 MULMOD static operation |
| ethereum/core/src/jmh/java/org/hyperledger/besu/ethereum/vm/operations/v2/TernaryOperationBenchmarkV2.java | Adds a v2 base benchmark harness for ternary stack ops |
| ethereum/core/src/jmh/java/org/hyperledger/besu/ethereum/vm/operations/v2/MulModOperationBenchmarkV2.java | Adds v2 MULMOD JMH benchmark scenarios |
| ethereum/core/src/jmh/java/org/hyperledger/besu/ethereum/vm/operations/TernaryOperationBenchmark.java | Renames ternary benchmark pool variable to reflect modulus semantics |
| ethereum/core/src/jmh/java/org/hyperledger/besu/ethereum/vm/operations/MulModOperationBenchmark.java | Fixes benchmark scenario sizing + renames modulus fields |
| ethereum/core/src/jmh/java/org/hyperledger/besu/ethereum/vm/operations/AddModOperationBenchmark.java | Aligns modulus pool naming with shared ternary benchmark base |
| public class MulModOperationV2 extends AbstractFixedCostOperationV2 { | ||
|
|
||
| private static final OperationResult mulModSuccess = new OperationResult(8, null); | ||
|
|
||
| /** | ||
| * Instantiates a new Mul mod operation. | ||
| * | ||
| * @param gasCalculator the gas calculator | ||
| */ | ||
| public MulModOperationV2(final GasCalculator gasCalculator) { | ||
| super(0x09, "MULMOD", 3, 1, gasCalculator, gasCalculator.getMidTierGasCost()); | ||
| } | ||
|
|
||
| @Override | ||
| public Operation.OperationResult executeFixedCostOperation( | ||
| final MessageFrame frame, final EVM evm) { | ||
| return staticOperation(frame, frame.stackDataV2()); | ||
| } | ||
|
|
||
| /** | ||
| * Performs MulMod operation. | ||
| * | ||
| * @param frame the frame | ||
| * @param stack the v2 operand stack ({@code long[]} in big-endian limb order) | ||
| * @return the operation result | ||
| */ | ||
| public static OperationResult staticOperation(final MessageFrame frame, final long[] stack) { | ||
| if (!frame.stackHasItems(3)) return UNDERFLOW_RESPONSE; | ||
| frame.setTopV2(StackArithmetic.mulMod(stack, frame.stackTopV2())); | ||
| return mulModSuccess; | ||
| } |
There was a problem hiding this comment.
OperationResult is referenced unqualified (field and method return type), but this file only imports org.hyperledger.besu.evm.operation.Operation (not Operation.OperationResult). Unless there is a same-package OperationResult type (not shown here), this will not compile. Prefer using Operation.OperationResult consistently (including for mulModSuccess and staticOperation’s return type) or add the specific nested-class import.
| public static int mulMod(final long[] stack, final int top) { | ||
| final int aOffset = (top - 1) << 2; | ||
| final int bOffset = (top - 2) << 2; | ||
| final int mOffset = (top - 3) << 2; | ||
| UInt256 valueA = | ||
| new UInt256(stack[aOffset], stack[aOffset + 1], stack[aOffset + 2], stack[aOffset + 3]); | ||
| UInt256 valueB = | ||
| new UInt256(stack[bOffset], stack[bOffset + 1], stack[bOffset + 2], stack[bOffset + 3]); | ||
| UInt256 modulus = | ||
| new UInt256(stack[mOffset], stack[mOffset + 1], stack[mOffset + 2], stack[mOffset + 3]); | ||
| UInt256 r = modulus.isZero() ? UInt256.ZERO : valueA.mulMod(valueB, modulus); | ||
| stack[mOffset] = r.u3(); | ||
| stack[mOffset + 1] = r.u2(); | ||
| stack[mOffset + 2] = r.u1(); | ||
| stack[mOffset + 3] = r.u0(); | ||
| return top - 2; | ||
| } |
There was a problem hiding this comment.
This implementation allocates 3 UInt256 objects (plus likely intermediates inside mulMod) per opcode execution, which can add noticeable allocation/GC overhead in tight interpreter loops. Consider adding a limb-based mulMod implementation that operates directly on the long[] stack (or a reusable/mutable UInt256 work buffer) to keep EVMv2’s “flat stack” design allocation-free.
Signed-off-by: Simon Dudley <simon.dudley@consensys.net>
| MULMOD_128_64_64(4, 2, 2), | ||
| MULMOD_128_128_32(4, 4, 1), | ||
| MULMOD_128_128_64(4, 4, 2), | ||
| MULMOD_128_128_128(4, 4, 3), |
There was a problem hiding this comment.
damn! maybe that's why I couldn't understand some results with modulus 128...Maybe we should just pass in the # bits as arguments instead of having them in the name 😓
There was a problem hiding this comment.
You're suggesting something like MULMOD(128, 128, 128) I guess, but we'd still need a unique name for the enum. If we don't use an enum then might be harder to run targeted cases, which I have found quite useful.
Signed-off-by: Simon Dudley <simon.dudley@consensys.net>
Signed-off-by: Simon Dudley <simon.dudley@consensys.net>
Signed-off-by: Simon Dudley <simon.dudley@consensys.net>
| assertThat(frame.stackTopV2()).isEqualTo(2); | ||
| } | ||
|
|
||
| private static UInt256 getStackItem(final MessageFrame frame, final int offset) { |
There was a problem hiding this comment.
This can be refactored when this is merged https://github.com/besu-eth/besu/pull/10229/changes#diff-501566ca262d867325b09d7fd057206f9f1a7845baa9095763da7fd2a5464d2fR194-R198
* enable bal parallelization for all blocks and not only head (#10234) Signed-off-by: Karim Taam <karim.t2am@gmail.com> * Add MULMOD to EVMv2 (#10168) - Add MulModOperationV2, tests and benchmarks - Rename c -> m in benchmarks following (a * b) % m formula - Add MulModOperationV2Test covering stack management and underflow Tests verify correct stack depth reduction (3→1), result placement, zero-modulus special case, cross-limb arithmetic, and that underflow with 0 or 2 items returns INSUFFICIENT_STACK_ITEMS without mutating the stack. --------- Signed-off-by: Simon Dudley <simon.dudley@consensys.net> * BlockSimulator fix (#10251) * BlockSimulator fix Signed-off-by: Roman <4833306+Filter94@users.noreply.github.com> Signed-off-by: Roman <4833306+Filter94@users.noreply.github.com> Co-authored-by: garyschulte <garyschulte@gmail.com> * Enable NullAway static null-safety analysis for util module (#10046) * Migrate JSR305 nullness annotations to JSpecify - Replace javax.annotation.Nullable and javax.annotation.CheckForNull with org.jspecify.annotations.Nullable across 18 Java files - Update platform constraint to org.jspecify:jspecify:1.0.0 - Replace compileOnly com.google.code.findbugs:jsr305 with compileOnly org.jspecify:jspecify in affected modules Signed-off-by: Mykim <38449976+Apisapple@users.noreply.github.com> * feat(util): add opt-in NullAway configuration for Error Prone Signed-off-by: mykim <kimminyong2034@gmail.com> * feat(util): enable NullAway with comprehensive nullability fixes - Add NullAway 0.12.4 to util errorprone dependencies - Annotate nullable fields/returns in 6 util classes with @nullable - Fix nullable dereferences: RollingFileWriter, StackTraceMatchFilter, PlatformDetector - Enable NullAway:ERROR for util main compile, OFF for tests - Add optional CI job (run-nullaway label) for gradual monitoring - All util compilation passes with NullAway ERROR by default Fixes: - MemoryBoundCache: mark getIfPresent() return as @nullable - ExceptionUtils: annotate rootCause() for nullable input/output - RollingFileWriter: guard Path.getParent() null dereference - PlatformDetector: make static fields @nullable, add fallback to UNKNOWN - BesuVersionUtils: mark VERSION/COMMIT fields as @nullable - StackTraceMatchFilter: fix nullable message comparison, builder fields Signed-off-by: mykim <kimminyong2034@gmail.com> * style(util): format code for improved readability in StackTraceMatchFilter Signed-off-by: mykim <kimminyong2034@gmail.com> * fix(util): PlatformDetector.normalizeGLibcVersion returns UNKNOWN not null Replace null return with UNKNOWN to satisfy NullAway @nonnull contract. Signed-off-by: mykim <kimminyong2034@gmail.com> * fix(util): update getGlibc to return null instead of UNKNOWN - Return null to account for existing code that expects and handles null values. Signed-off-by: mykim <kimminyong2034@gmail.com> * fix(util): remove NullAway flag from util compile command - Remove the unnecessary -PenableNullAway flag Signed-off-by: mykim <kimminyong2034@gmail.com> * docs(util): update getGlibc Javadoc to clarify return value can be null - Update the Javadoc to reflect the actual behavior of the getGlibc function. Signed-off-by: mykim <kimminyong2034@gmail.com> * docs(util): update NullAway optional check job name for clarity Signed-off-by: mykim <kimminyong2034@gmail.com> * fix(util): update getGlibc to always return a value instead of null Signed-off-by: mykim <kimminyong2034@gmail.com> * fix(util): remove NullAway optional check job from pre-review workflow Signed-off-by: mykim <kimminyong2034@gmail.com> * Fix YAML indentation in pre-review workflow Adjust indentation of GRADLEW_UNIT_TEST_ARGS in .github/workflows/pre-review.yml under unitTests.env to align with surrounding keys. Signed-off-by: mykim <kimminyong2034@gmail.com> * feat: Improve version metadata null-safety and bump NullAway to 0.13.1 Signed-off-by: mykim <kimminyong2034@gmail.com> * chroe: Add jspecify compileOnly dependency Add org.jspecify:jspecify as a compileOnly dependency to util/build.gradle. This brings JSpecify annotations into the module for static nullness/type-checking without introducing a runtime dependency. Signed-off-by: mykim <kimminyong2034@gmail.com> * feat: Use shortVersion() and improve StackTraceMatchFilter Update acceptance tests to call BesuVersionUtils.shortVersion() directly instead of using orElse("unknown"). In StackTraceMatchFilter, mark the Throwable parameter as @nullable and simplify toString() to return stackContains directly. These changes clarify nullability and streamline version usage/representation. Signed-off-by: mykim <kimminyong2034@gmail.com> * docs: Fix Javadoc reference for UNKNOWN constant Update Javadoc in util/src/main/java/org/hyperledger/besu/util/BesuVersionUtils.java to use {@value #UNKNOWN} instead of {@value UNKNOWN} in shortVersion() and commit() docs so the UNKNOWN field is referenced correctly. No behavioral changes. Signed-off-by: mykim <kimminyong2034@gmail.com> * chroe: Remove old verification metadata entries Delete verification-metadata entries for com.uber.nullaway:nullaway:0.12.4 and org.checkerframework:dataflow-nullaway:3.48.0 (their artifact SHA entries were removed). These versions are superseded in the file by nullaway:0.13.1 and dataflow-nullaway:3.53.0, so the stale metadata was cleaned up. Signed-off-by: mykim <kimminyong2034@gmail.com> * Merge pull request #7 from Apisapple/feature/nullaway-util Feature/nullaway util Signed-off-by: mykim <kimminyong2034@gmail.com> * Use UNKNOWN constant in version regex tests Replace hardcoded "UNKNOWN" literal in regex assertions with BesuVersionUtils.UNKNOWN constant in three unit tests (versionStringIsEthstatsFriendly, noIdentityNodeNameIsEthstatsFriendly, userIdentityNodeNameIsEthstatsFriendly) in BesuVersionUtilsTest. This keeps the tests consistent with the source constant and avoids duplicating the literal value; no behavioral change. Signed-off-by: mykim <kimminyong2034@gmail.com> * Use BesuVersionUtils.UNKNOWN constant Remove the local BESU_VERSION_UNKNOWN constant and use BesuVersionUtils.UNKNOWN instead. Simplify getRuntimeVersionString() to return BesuVersionUtils.shortVersion() directly, construct VersionMetadata with BesuVersionUtils.UNKNOWN on FileNotFoundException, and compare metadata versions against BesuVersionUtils.UNKNOWN. Centralizes the unknown-version sentinel in BesuVersionUtils. Signed-off-by: mykim <kimminyong2034@gmail.com> * docs: Clarify rootCause javadoc null behavior Update Javadoc for ExceptionUtils.rootCause to state it returns the root cause or {@code null} when the input throwable is {@code null}. This documents the method's existing behavior, which already returns null for a null input. Signed-off-by: mykim <kimminyong2034@gmail.com> * style: Wrap long regex in BesuVersionUtilsTest Reformat the long regex in userIdentityNodeNameIsEthstatsFriendly test to improve readability by splitting the string across lines. This is a purely formatting change in util/src/test/java/org/hyperledger/besu/util/BesuVersionUtilsTest.java and does not alter test behavior. Signed-off-by: mykim <kimminyong2034@gmail.com> * chore: Use compileOnlyApi for jspecify dependency Replace compileOnly with compileOnlyApi for org.jspecify:jspecify in util/build.gradle so jspecify annotations are exposed on the compile classpath to consumers of this module. This ensures downstream modules compiling against this artifact can see the jspecify types without packaging the dependency. Signed-off-by: mykim <kimminyong2034@gmail.com> * feat: Quote UNKNOWN in version regex tests Use Pattern.quote(BesuVersionUtils.UNKNOWN) in regex assertions to ensure the UNKNOWN token is matched literally and not treated as a regex. Added import java.util.regex.Pattern and updated three assertions in BesuVersionUtilsTest (versionStringIsEthstatsFriendly, noIdentityNodeNameIsEthstatsFriendly, userIdentityNodeNameIsEthstatsFriendly) to avoid accidental regex interpretation and potential test flakiness. Signed-off-by: mykim <kimminyong2034@gmail.com> * style: Apply Spotless formatting Apply Spotless formatting Signed-off-by: mykim <kimminyong2034@gmail.com> --------- Signed-off-by: Mykim <38449976+Apisapple@users.noreply.github.com> Signed-off-by: mykim <kimminyong2034@gmail.com> Co-authored-by: Simon Dudley <simon.dudley@consensys.net> * Layered txpool: enable balance check by default (#10175) Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net> Co-authored-by: Justin Florentine <justin+github@florentine.us> * remove pre EIP8 handshake support (#10257) Signed-off-by: stefan.pingel@consensys.net <stefan.pingel@consensys.net> Co-authored-by: Justin Florentine <justin+github@florentine.us> * Minor Mulmod v2 refactor (#10253) * Refactor stack index logic * Refactor test helper * Remove redundant stack param * Inline mulmod method --------- Signed-off-by: Simon Dudley <simon.dudley@consensys.net> * Increase disconnect await timeout in flaky P2P rejection tests (#10267) Under full test suite load, the multi-hop async disconnect path (local denies inbound → TCP close → remote Netty event loop → subscriber callback) can exceed 5s due to thread pool contention. Raise peerFuture/reasonFuture timeouts to 30s in P2PNetworkTest and P2PPlainNetworkTest to tolerate CI load without masking bugs. Signed-off-by: Simon Dudley <simon.dudley@consensys.net> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * Include slotNumber in payloadIdentifier generation (#10242) Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net> Co-authored-by: Usman Saleem <usman@usmans.info> * Update Gradle plugin for Besu plugin development to 0.2.0 (#10263) Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net> * Change block access list index to uint32 (#10279) Signed-off-by: Karim Taam <karim.t2am@gmail.com> * SystemCallProcessor: remove duplicate logging (#10152) * remove duplicate logging Signed-off-by: Sally MacFarlane <macfarla.github@gmail.com> --------- Signed-off-by: Sally MacFarlane <macfarla.github@gmail.com> * EVMv2 AddOperationV2 (#10255) * AddOperationV2 Signed-off-by: Simon Dudley <simon.dudley@consensys.net> * AddOperationV2Test: structural coverage Drop redundant arithmetic cases (covered by UInt256PropertyBasedTest) and focus on structural concerns: stack arity, limb-level read/write wiring, 256-bit wrap, deep-slot preservation, and gas cost. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: Simon Dudley <simon.dudley@consensys.net> * Optimize for JIT Signed-off-by: Luis Pinto <luis.pinto@consensys.net> * Address review comments Don't mutate top Don't use fromHexStringLenient Signed-off-by: Simon Dudley <simon.dudley@consensys.net> --------- Signed-off-by: Simon Dudley <simon.dudley@consensys.net> Signed-off-by: Luis Pinto <luis.pinto@consensys.net> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> Co-authored-by: Luis Pinto <luis.pinto@consensys.net> * [CHANGELOG] add unreleased section (#10286) Signed-off-by: Sally MacFarlane <macfarla.github@gmail.com> * Enforce that blob_versioned_hashes match blobs (#10278) Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net> * Implement BaseFee, blobBaseFee, CallValue, GasPrice, Balance and SelfBalance for EVM v2 (#10229) * Migrate wei operations to EVM v2 (first commit) Signed-off-by: Ameziane H. <ameziane.hamlat@consensys.net> * Update SelfBalance benchmarks Signed-off-by: Ameziane H. <ameziane.hamlat@consensys.net> * spotless Signed-off-by: Ameziane H. <ameziane.hamlat@consensys.net> * Address comments. Signed-off-by: Ameziane H. <ameziane.hamlat@consensys.net> * Add Javadoc Signed-off-by: Ameziane H. <ameziane.hamlat@consensys.net> * Add unit tests Signed-off-by: Ameziane H. <ameziane.hamlat@consensys.net> * spotless Signed-off-by: Ameziane H. <ameziane.hamlat@consensys.net> * Update datatypes/src/main/java/org/hyperledger/besu/datatypes/Wei.java Co-authored-by: Simon Dudley <simon.dudley@consensys.net> Signed-off-by: ahamlat <ameziane.hamlat@consensys.net> * Update evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java Co-authored-by: Simon Dudley <simon.dudley@consensys.net> Signed-off-by: ahamlat <ameziane.hamlat@consensys.net> * Update evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java Co-authored-by: Simon Dudley <simon.dudley@consensys.net> Signed-off-by: ahamlat <ameziane.hamlat@consensys.net> * Update datatypes/src/main/java/org/hyperledger/besu/datatypes/Wei.java Co-authored-by: Simon Dudley <simon.dudley@consensys.net> Signed-off-by: ahamlat <ameziane.hamlat@consensys.net> * Apply refactoring changes Signed-off-by: Ameziane H. <ameziane.hamlat@consensys.net> * remove basefee field Signed-off-by: Ameziane H. <ameziane.hamlat@consensys.net> * Fix merge issue Signed-off-by: Ameziane H. <ameziane.hamlat@consensys.net> * Address more comments Signed-off-by: Ameziane H. <ameziane.hamlat@consensys.net> * Remove not used field Signed-off-by: Ameziane H. <ameziane.hamlat@consensys.net> * spotless Signed-off-by: Ameziane H. <ameziane.hamlat@consensys.net> * Undo Balance operation change and add more unit tests Signed-off-by: Ameziane H. <ameziane.hamlat@consensys.net> * Update AddOperationV2 after merge with main Signed-off-by: Ameziane H. <ameziane.hamlat@consensys.net> --------- Signed-off-by: Ameziane H. <ameziane.hamlat@consensys.net> Signed-off-by: ahamlat <ameziane.hamlat@consensys.net> Co-authored-by: Simon Dudley <simon.dudley@consensys.net> --------- Signed-off-by: Karim Taam <karim.t2am@gmail.com> Signed-off-by: Simon Dudley <simon.dudley@consensys.net> Signed-off-by: Roman <4833306+Filter94@users.noreply.github.com> Signed-off-by: Mykim <38449976+Apisapple@users.noreply.github.com> Signed-off-by: mykim <kimminyong2034@gmail.com> Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net> Signed-off-by: stefan.pingel@consensys.net <stefan.pingel@consensys.net> Signed-off-by: Sally MacFarlane <macfarla.github@gmail.com> Signed-off-by: Luis Pinto <luis.pinto@consensys.net> Signed-off-by: Ameziane H. <ameziane.hamlat@consensys.net> Signed-off-by: ahamlat <ameziane.hamlat@consensys.net> Co-authored-by: Karim Taam <karim.t2am@gmail.com> Co-authored-by: Simon Dudley <simon.dudley@consensys.net> Co-authored-by: Roman Vaseev <4833306+Filter94@users.noreply.github.com> Co-authored-by: garyschulte <garyschulte@gmail.com> Co-authored-by: Mykim <kimminyong2034@gmail.com> Co-authored-by: Fabio Di Fabio <fabio.difabio@consensys.net> Co-authored-by: Justin Florentine <justin+github@florentine.us> Co-authored-by: Stefan Pingel <16143240+pinges@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Usman Saleem <usman@usmans.info> Co-authored-by: Sally MacFarlane <macfarla.github@gmail.com> Co-authored-by: Luis Pinto <luis.pinto@consensys.net> Co-authored-by: ahamlat <ameziane.hamlat@consensys.net>
(Previously built on #10154 now merged in)
This PR adds the MULMOD (0x09) opcode to the EVM v2 long[]-based stack.
Worst case comparison with V1
V1 Benchmarks
V2 Benchmarks