From 918baeb16e6d1e0be87f79d4b692325ac5f3b9fc Mon Sep 17 00:00:00 2001 From: F Bojarski Date: Mon, 4 Nov 2024 15:00:08 +0100 Subject: [PATCH 01/23] constraints Signed-off-by: F Bojarski --- linea-constraints | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linea-constraints b/linea-constraints index 2bba6a0a49..d2fc4982d4 160000 --- a/linea-constraints +++ b/linea-constraints @@ -1 +1 @@ -Subproject commit 2bba6a0a4937bb22dea062ecf9e2f8e538b8cb4f +Subproject commit d2fc4982d4395474023a99485a3707a9abdbb5b6 From 8307f74ebd908712a2bc37414aea304824d97a96 Mon Sep 17 00:00:00 2001 From: F Bojarski Date: Tue, 5 Nov 2024 17:06:00 +0100 Subject: [PATCH 02/23] fix(prc): left padding return data Signed-off-by: F Bojarski --- .../module/hub/fragment/imc/mmu/MmuCall.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java index 24f768a262..8ee1f91928 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java @@ -417,7 +417,7 @@ public static MmuCall fullResultTransferForShaTwoAndRipemd( } else { return new MmuCall(hub, MMU_INST_EXO_TO_RAM_TRANSPLANTS) .sourceId(precompileSubsection.exoModuleOperationId()) - .exoBytes(Optional.of(precompileSubsection.returnData)) + .exoBytes(Optional.of(leftPadTo(precompileSubsection.returnData, WORD_SIZE))) .targetId(precompileSubsection.returnDataContextNumber()) .targetRamBytes(Optional.of(Bytes.EMPTY)) .size(WORD_SIZE) @@ -437,7 +437,7 @@ public static MmuCall partialReturnDataCopyForShaTwoAndRipemd( return new MmuCall(hub, MMU_INST_RAM_TO_RAM_SANS_PADDING) .sourceId(precompileSubsection.returnDataContextNumber()) - .sourceRamBytes(Optional.of(precompileSubsection.returnData)) + .sourceRamBytes(Optional.of(leftPadTo(precompileSubsection.returnData, WORD_SIZE))) .targetId(hub.currentFrame().contextNumber()) .targetRamBytes(Optional.of(precompileSubsection.callerMemorySnapshot)) .sourceOffset(EWord.ZERO) @@ -492,7 +492,7 @@ public static MmuCall fullReturnDataTransferForEcadd( final Hub hub, PrecompileSubsection subsection, boolean successBit) { return new MmuCall(hub, MMU_INST_EXO_TO_RAM_TRANSPLANTS) .sourceId(subsection.exoModuleOperationId()) - .exoBytes(Optional.of(subsection.returnData())) + .exoBytes(Optional.of(leftPadTo(subsection.returnData(), 2 * WORD_SIZE))) .targetId(subsection.exoModuleOperationId()) .targetRamBytes(Optional.of(Bytes.EMPTY)) .size(64) @@ -505,7 +505,7 @@ public static MmuCall partialCopyOfReturnDataForEcadd( final Hub hub, PrecompileSubsection subsection) { return new MmuCall(hub, MMU_INST_RAM_TO_RAM_SANS_PADDING) .sourceId(subsection.exoModuleOperationId()) - .sourceRamBytes(Optional.of(subsection.returnData())) + .sourceRamBytes(Optional.of(leftPadTo(subsection.returnData(), 2 * WORD_SIZE))) .targetId(hub.currentFrame().contextNumber()) .targetRamBytes(Optional.of(subsection.callerMemorySnapshot())) .targetOffset(EWord.of(subsection.parentReturnDataTarget.offset())) @@ -532,7 +532,7 @@ public static MmuCall fullReturnDataTransferForEcmul( final Hub hub, final PrecompileSubsection subsection, boolean successBit) { return new MmuCall(hub, MMU_INST_EXO_TO_RAM_TRANSPLANTS) .sourceId(subsection.exoModuleOperationId()) - .exoBytes(Optional.of(subsection.returnData())) + .exoBytes(Optional.of(leftPadTo(subsection.returnData(), 2 * WORD_SIZE))) .targetId(subsection.exoModuleOperationId()) .targetRamBytes(Optional.of(Bytes.EMPTY)) .size(64) @@ -545,7 +545,7 @@ public static MmuCall partialCopyOfReturnDataForEcmul( final Hub hub, final PrecompileSubsection subsection) { return new MmuCall(hub, MMU_INST_RAM_TO_RAM_SANS_PADDING) .sourceId(subsection.exoModuleOperationId()) - .sourceRamBytes(Optional.of(subsection.returnData())) + .sourceRamBytes(Optional.of(leftPadTo(subsection.returnData(), 2 * WORD_SIZE))) .targetId(hub.currentFrame().contextNumber()) .targetRamBytes(Optional.of(subsection.callerMemorySnapshot())) .targetOffset(EWord.of(subsection.parentReturnDataTarget().offset())) @@ -642,7 +642,7 @@ public static MmuCall fullReturnDataTransferForBlake( final int precompileContextNumber = subsection.exoModuleOperationId(); return new MmuCall(hub, MMU_INST_EXO_TO_RAM_TRANSPLANTS) .sourceId(precompileContextNumber) - .exoBytes(Optional.of(subsection.returnData())) + .exoBytes(Optional.of(leftPadTo(subsection.returnData(), WORD_SIZE))) .targetId(precompileContextNumber) .targetRamBytes(Optional.of(Bytes.EMPTY)) .size(64) @@ -655,7 +655,7 @@ public static MmuCall partialCopyOfReturnDataforBlake( final int precompileContextNumber = subsection.exoModuleOperationId(); return new MmuCall(hub, MMU_INST_RAM_TO_RAM_SANS_PADDING) .sourceId(precompileContextNumber) - .sourceRamBytes(Optional.of(subsection.returnData())) + .sourceRamBytes(Optional.of(leftPadTo(subsection.returnData(), WORD_SIZE))) .targetId(hub.currentFrame().contextNumber()) .targetRamBytes(Optional.of(subsection.callerMemorySnapshot())) .size(64) @@ -786,7 +786,8 @@ public static MmuCall forModexpPartialResultCopy( final Hub hub, final ModexpSubsection modexpSubsection, final ModexpMetadata modExpMetadata) { return new MmuCall(hub, MMU_INST_RAM_TO_RAM_SANS_PADDING) .sourceId(modexpSubsection.exoModuleOperationId()) - .sourceRamBytes(Optional.of(modexpSubsection.returnData())) + .sourceRamBytes( + Optional.of(leftPadTo(modexpSubsection.returnData, MODEXP_COMPONENT_BYTE_SIZE))) .targetId(modexpSubsection.callSection.hubStamp()) .targetRamBytes(Optional.of(modexpSubsection.callerMemorySnapshot)) .sourceOffset(EWord.of(MODEXP_COMPONENT_BYTE_SIZE - modExpMetadata.mbs().toInt())) From c76c97c20c9a2383381b8c8122d0d38788ad5819 Mon Sep 17 00:00:00 2001 From: F Bojarski Date: Tue, 5 Nov 2024 18:59:17 +0100 Subject: [PATCH 03/23] ras Signed-off-by: F Bojarski --- .../precompileSubsection/PrecompileSubsection.java | 13 +++++++------ .../linea/zktracer/precompiles/ModexpTests.java | 3 ++- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/call/precompileSubsection/PrecompileSubsection.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/call/precompileSubsection/PrecompileSubsection.java index 03df956297..fb1e267d23 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/call/precompileSubsection/PrecompileSubsection.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/call/precompileSubsection/PrecompileSubsection.java @@ -96,6 +96,8 @@ public PrecompileSubsection(final Hub hub, final CallSection callSection) { this.callSection = callSection; fragments = new ArrayList<>(maxNumberOfLines()); + final MessageFrame messageFrame = hub.messageFrame(); + hub.defers().scheduleForImmediateContextEntry(this); // gas & input data, ... hub.defers().scheduleForContextExit(this, hub.callStack().futureId()); hub.defers().scheduleForContextReEntry(this, hub.currentFrame()); // success bit & return data @@ -114,16 +116,15 @@ public PrecompileSubsection(final Hub hub, final CallSection callSection) { final long offset = Words.clampedToLong( opCode.callCanTransferValue() - ? hub.messageFrame().getStackItem(3) - : hub.messageFrame().getStackItem(2)); + ? messageFrame.getStackItem(3) + : messageFrame.getStackItem(2)); final long length = Words.clampedToLong( opCode.callCanTransferValue() - ? hub.messageFrame().getStackItem(4) - : hub.messageFrame().getStackItem(3)); + ? messageFrame.getStackItem(4) + : messageFrame.getStackItem(3)); callDataMemorySpan = new MemorySpan(offset, length); - callerMemorySnapshot = - extractContiguousLimbsFromMemory(hub.currentFrame().frame(), callDataMemorySpan); + callerMemorySnapshot = extractContiguousLimbsFromMemory(messageFrame, callDataMemorySpan); final int lengthToExtract = (int) Math.min(length, Math.max(callerMemorySnapshot.size() - offset, 0)); callData = rightPadTo(callerMemorySnapshot.slice((int) offset, lengthToExtract), (int) length); diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/precompiles/ModexpTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/precompiles/ModexpTests.java index 7fcd4e52ce..1a69759ec0 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/precompiles/ModexpTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/precompiles/ModexpTests.java @@ -26,6 +26,7 @@ import net.consensys.linea.testing.BytecodeRunner; import net.consensys.linea.zktracer.opcode.OpCode; import org.apache.tuweni.bytes.Bytes; +import org.hyperledger.besu.datatypes.Address; import org.junit.jupiter.api.Test; public class ModexpTests { @@ -174,7 +175,7 @@ void appendParametrizedModexpCall( .push(Bytes.fromHexString("0100")) // r@o .push(callDataSize) // cds .push(Bytes.fromHexString("")) // cdo - .push(0x04) // address (here: MODEXP) + .push(Address.MODEXP) // address (here: MODEXP) .push(Bytes.fromHexString("ffff")) // gas .op(OpCode.DELEGATECALL) .op(OpCode.POP); From a3ba12c210cb86ee689577a713481f35a8386cda Mon Sep 17 00:00:00 2001 From: F Bojarski Date: Wed, 6 Nov 2024 18:58:41 +0100 Subject: [PATCH 04/23] fix empty ripemd Signed-off-by: F Bojarski --- .../module/hub/fragment/imc/mmu/MmuCall.java | 7 ++++--- .../zktracer/module/mmu/instructions/Blake.java | 13 +++++++------ .../consensys/linea/zktracer/types/Conversions.java | 5 ++--- .../module/oob/OobSha2RipemdIdentityTest.java | 2 +- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java index 8ee1f91928..d31a3f20f0 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java @@ -18,7 +18,6 @@ import static com.google.common.base.Preconditions.*; import static net.consensys.linea.zktracer.module.Util.slice; import static net.consensys.linea.zktracer.module.blake2fmodexpdata.BlakeModexpDataOperation.MODEXP_COMPONENT_BYTE_SIZE; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.EMPTY_RIPEMD_HI; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.EMPTY_RIPEMD_LO; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.EMPTY_SHA2_HI; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.EMPTY_SHA2_LO; @@ -66,7 +65,6 @@ import static net.consensys.linea.zktracer.runtime.callstack.CallFrame.extractContiguousLimbsFromMemory; import static net.consensys.linea.zktracer.types.Conversions.bigIntegerToBytes; import static net.consensys.linea.zktracer.types.Utils.leftPadTo; -import static org.apache.tuweni.bytes.Bytes.minimalBytes; import static org.hyperledger.besu.evm.internal.Words.clampedToLong; import java.util.Optional; @@ -412,7 +410,10 @@ public static MmuCall fullResultTransferForShaTwoAndRipemd( return new MmuCall(hub, MMU_INST_MSTORE) .targetId(precompileSubsection.exoModuleOperationId()) .targetOffset(EWord.ZERO) - .limb1(isShaTwo ? bigIntegerToBytes(EMPTY_SHA2_HI) : minimalBytes(EMPTY_RIPEMD_HI)) + .limb1( + isShaTwo + ? bigIntegerToBytes(EMPTY_SHA2_HI) + : Bytes.fromHexString("0x9c1185a5")) // EMPTY_RIPEMD_LO .limb2(isShaTwo ? bigIntegerToBytes(EMPTY_SHA2_LO) : bigIntegerToBytes(EMPTY_RIPEMD_LO)); } else { return new MmuCall(hub, MMU_INST_EXO_TO_RAM_TRANSPLANTS) diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/Blake.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/Blake.java index b82eaffb93..9125aa7a2c 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/Blake.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/Blake.java @@ -18,6 +18,7 @@ import static net.consensys.linea.zktracer.module.constants.GlobalConstants.LLARGE; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.MMIO_INST_RAM_TO_LIMB_ONE_SOURCE; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.MMIO_INST_RAM_TO_LIMB_TWO_SOURCE; +import static net.consensys.linea.zktracer.module.mmu.Trace.NB_PP_ROWS_BLAKE; import static net.consensys.linea.zktracer.types.Conversions.longToBytes; import java.util.ArrayList; @@ -39,8 +40,8 @@ public class Blake implements MmuInstruction { private final Euc euc; private final Wcp wcp; - private List eucCallRecords; - private List wcpCallRecords; + private final List eucCallRecords; + private final List wcpCallRecords; private long sourceLimbOffsetR; private short sourceByteOffsetR; private long sourceLimbOffsetF; @@ -50,8 +51,8 @@ public class Blake implements MmuInstruction { public Blake(Euc euc, Wcp wcp) { this.euc = euc; this.wcp = wcp; - this.eucCallRecords = new ArrayList<>(Trace.NB_PP_ROWS_BLAKE); - this.wcpCallRecords = new ArrayList<>(Trace.NB_PP_ROWS_BLAKE); + this.eucCallRecords = new ArrayList<>(NB_PP_ROWS_BLAKE); + this.wcpCallRecords = new ArrayList<>(NB_PP_ROWS_BLAKE); } @Override @@ -60,7 +61,7 @@ public MmuData preProcess(MmuData mmuData) { // Preprocessing row n°1 final long dividendRow1 = hubToMmuValues.sourceOffsetLo().longValueExact(); - EucOperation eucOpRow1 = euc.callEUC(longToBytes(dividendRow1), Bytes.of(LLARGE)); + final EucOperation eucOpRow1 = euc.callEUC(longToBytes(dividendRow1), Bytes.of(LLARGE)); sourceLimbOffsetR = eucOpRow1.quotient().toLong(); sourceByteOffsetR = (short) eucOpRow1.remainder().toInt(); eucCallRecords.add( @@ -83,7 +84,7 @@ public MmuData preProcess(MmuData mmuData) { // Preprocessing row n°2 final long dividendRow2 = hubToMmuValues.sourceOffsetLo().longValueExact() + 213 - 1; - EucOperation eucOpRow2 = euc.callEUC(longToBytes(dividendRow2), Bytes.of(LLARGE)); + final EucOperation eucOpRow2 = euc.callEUC(longToBytes(dividendRow2), Bytes.of(LLARGE)); sourceLimbOffsetF = eucOpRow2.quotient().toLong(); sourceByteOffsetF = (short) eucOpRow2.remainder().toInt(); eucCallRecords.add( diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/types/Conversions.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/types/Conversions.java index 1cbfe5ed5b..f15d5330e4 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/types/Conversions.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/types/Conversions.java @@ -45,7 +45,6 @@ public static Bytes bigIntegerToBytes(final BigInteger input) { bytes = Bytes.wrap(byteArray); } } - return bytes; } @@ -137,11 +136,11 @@ public static BigInteger reallyToSignedBigInteger(Bytes a) { } public static Bytes32 longToBytes32(final long input) { - return Bytes32.leftPad(Bytes.minimalBytes(input)); + return Bytes32.leftPad(longToBytes(input)); } public static Bytes longToBytes(final long input) { - return input == 0 ? Bytes.of(0) : Bytes.minimalBytes(input); + return input == 0 ? Bytes.of(0) : Bytes.ofUnsignedLong(input).trimLeadingZeros(); } public static Bytes booleanToBytes(boolean x) { diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/module/oob/OobSha2RipemdIdentityTest.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/module/oob/OobSha2RipemdIdentityTest.java index 5fce76cc19..4b191c6e57 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/module/oob/OobSha2RipemdIdentityTest.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/module/oob/OobSha2RipemdIdentityTest.java @@ -38,7 +38,7 @@ public class OobSha2RipemdIdentityTest { Random random = new Random(1L); static final int[] argSizes = - new int[] {0, 1, 10, 20, 31, 32, 33, 63, 64, 65, 95, 96, 97, 127, 128, 129, 1000, 2000}; + new int[] {0}; // , 1, 10, 20, 31, 32, 33, 63, 64, 65, 95, 96, 97, 127, 128, 129, 1000, 2000}; // https://coderpad.io/blog/development/writing-a-parameterized-test-in-junit-with-examples/ // https://stackoverflow.com/questions/76124016/pass-externally-defined-variable-to-junit-valuesource-annotation-in-a-paramete From a7fb00df47b0916dfff3a9d9e630ee330e2f1e53 Mon Sep 17 00:00:00 2001 From: F Bojarski Date: Wed, 6 Nov 2024 19:16:21 +0100 Subject: [PATCH 05/23] ras Signed-off-by: F Bojarski --- .../linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java | 6 +++--- .../zktracer/module/oob/OobSha2RipemdIdentityTest.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java index d31a3f20f0..6a9fc8ccd1 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java @@ -582,7 +582,7 @@ public static MmuCall fullReturnDataTransferForEcpairing( } else { return new MmuCall(hub, MMU_INST_EXO_TO_RAM_TRANSPLANTS) .sourceId(precompileContextNumber) - .exoBytes(Optional.of(subsection.returnData())) + .exoBytes(Optional.of(leftPadTo(subsection.returnData(), WORD_SIZE))) .targetId(precompileContextNumber) .targetRamBytes(Optional.of(Bytes.EMPTY)) .size(WORD_SIZE) @@ -597,12 +597,12 @@ public static MmuCall partialCopyOfReturnDataForEcpairing( final int precompileContextNumber = subsection.exoModuleOperationId(); return new MmuCall(hub, MMU_INST_RAM_TO_RAM_SANS_PADDING) .sourceId(precompileContextNumber) - .sourceRamBytes(Optional.of(subsection.returnData())) + .sourceRamBytes(Optional.of(leftPadTo(subsection.returnData(), WORD_SIZE))) .targetId(hub.currentFrame().contextNumber()) .targetRamBytes(Optional.of(subsection.callerMemorySnapshot())) .targetOffset(EWord.of(subsection.parentReturnDataTarget.offset())) .size(subsection.parentReturnDataTarget.length()) - .referenceSize(32); + .referenceSize(WORD_SIZE); } public static MmuCall parameterExtractionForBlake( diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/module/oob/OobSha2RipemdIdentityTest.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/module/oob/OobSha2RipemdIdentityTest.java index 4b191c6e57..5fce76cc19 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/module/oob/OobSha2RipemdIdentityTest.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/module/oob/OobSha2RipemdIdentityTest.java @@ -38,7 +38,7 @@ public class OobSha2RipemdIdentityTest { Random random = new Random(1L); static final int[] argSizes = - new int[] {0}; // , 1, 10, 20, 31, 32, 33, 63, 64, 65, 95, 96, 97, 127, 128, 129, 1000, 2000}; + new int[] {0, 1, 10, 20, 31, 32, 33, 63, 64, 65, 95, 96, 97, 127, 128, 129, 1000, 2000}; // https://coderpad.io/blog/development/writing-a-parameterized-test-in-junit-with-examples/ // https://stackoverflow.com/questions/76124016/pass-externally-defined-variable-to-junit-valuesource-annotation-in-a-paramete From b3ff25d289e17a19dfe0d6e035374cc6edb21cb3 Mon Sep 17 00:00:00 2001 From: F Bojarski Date: Fri, 8 Nov 2024 06:29:21 +0100 Subject: [PATCH 06/23] fix returnDataCopy mmu call Signed-off-by: F Bojarski --- .../linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java | 3 ++- linea-constraints | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java index 6a9fc8ccd1..a5d08cb05e 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java @@ -253,7 +253,8 @@ public static MmuCall returnDataCopy(final Hub hub) { return new MmuCall(hub, MMU_INST_ANY_TO_RAM_WITH_PADDING) .sourceId(returnerFrame.contextNumber()) - .sourceRamBytes(Optional.of(currentFrame.frame().getReturnData().copy())) + .sourceRamBytes( + Optional.of(extractContiguousLimbsFromMemory(returnerFrame.frame(), returnDataSegment))) .targetId(currentFrame.contextNumber()) .targetRamBytes( Optional.of( diff --git a/linea-constraints b/linea-constraints index d2fc4982d4..8b3fc7937c 160000 --- a/linea-constraints +++ b/linea-constraints @@ -1 +1 @@ -Subproject commit d2fc4982d4395474023a99485a3707a9abdbb5b6 +Subproject commit 8b3fc7937c20779c33e56b9c656fecc4db4bc7f9 From 544e866ccd4959935945aa3b527b28fe32fdd100 Mon Sep 17 00:00:00 2001 From: F Bojarski Date: Fri, 8 Nov 2024 06:55:22 +0100 Subject: [PATCH 07/23] same for callData Signed-off-by: F Bojarski --- .../module/hub/fragment/imc/mmu/MmuCall.java | 23 +++++++++++-------- .../types/TransactionProcessingMetadata.java | 5 ++++ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java index a5d08cb05e..6a38e89c8b 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java @@ -96,6 +96,7 @@ import net.consensys.linea.zktracer.types.MemorySpan; import org.apache.tuweni.bytes.Bytes; import org.hyperledger.besu.datatypes.Transaction; +import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.worldstate.WorldView; /** @@ -199,20 +200,24 @@ public static MmuCall sha3(final Hub hub, final Bytes hashInput) { } public static MmuCall callDataCopy(final Hub hub) { - final CallDataInfo callDataInfo = hub.currentFrame().callDataInfo(); + final CallFrame currentFrame = hub.currentFrame(); + final CallDataInfo callDataInfo = currentFrame.callDataInfo(); + final MessageFrame parentFrame = hub.callStack().parent().frame(); + final Bytes sourceBytes = + currentFrame.depth() == 0 + ? hub.txStack().current().getTransactionCallData() + : parentFrame.shadowReadMemory(0, parentFrame.memoryByteSize()); return new MmuCall(hub, MMU_INST_ANY_TO_RAM_WITH_PADDING) .sourceId((int) callDataInfo.callDataContextNumber()) - .sourceRamBytes(Optional.ofNullable(callDataInfo.data())) - .targetId(hub.currentFrame().contextNumber()) + .sourceRamBytes(Optional.ofNullable(sourceBytes)) + .targetId(currentFrame.contextNumber()) .targetRamBytes( Optional.of( - hub.currentFrame() - .frame() - .shadowReadMemory(0, hub.currentFrame().frame().memoryByteSize()))) - .sourceOffset(EWord.of(hub.messageFrame().getStackItem(1))) - .targetOffset(EWord.of(hub.messageFrame().getStackItem(0))) - .size(clampedToLong(hub.messageFrame().getStackItem(2))) + currentFrame.frame().shadowReadMemory(0, currentFrame.frame().memoryByteSize()))) + .sourceOffset(EWord.of(currentFrame.frame().getStackItem(1))) + .targetOffset(EWord.of(currentFrame.frame().getStackItem(0))) + .size(clampedToLong(currentFrame.frame().getStackItem(2))) .referenceOffset(callDataInfo.memorySpan().offset()) .referenceSize(callDataInfo.memorySpan().length()); } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/types/TransactionProcessingMetadata.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/types/TransactionProcessingMetadata.java index 9f64b34c6f..77a55d01a6 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/types/TransactionProcessingMetadata.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/types/TransactionProcessingMetadata.java @@ -36,6 +36,7 @@ import net.consensys.linea.zktracer.module.hub.section.halt.EphemeralAccount; import net.consensys.linea.zktracer.module.hub.transients.Block; import net.consensys.linea.zktracer.module.hub.transients.StorageInitialValues; +import org.apache.tuweni.bytes.Bytes; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Transaction; import org.hyperledger.besu.datatypes.Wei; @@ -328,4 +329,8 @@ public void captureUpdatedInitialRecipientAddressDeploymentInfoAtTransactionStar updatedRecipientAddressDeploymentStatusAtTransactionStart = hub.deploymentStatusOf(effectiveRecipient); } + + public Bytes getTransactionCallData() { + return besuTransaction.getData().orElse(Bytes.EMPTY); + } } From ee573c0b01c972ffb24f8c2ba9241054c05aecfc Mon Sep 17 00:00:00 2001 From: F Bojarski Date: Fri, 8 Nov 2024 08:09:48 +0100 Subject: [PATCH 08/23] and for callDataLoad + factorize methode Signed-off-by: F Bojarski --- .../module/hub/fragment/imc/mmu/MmuCall.java | 35 +++++++++++--- .../hub/section/CallDataLoadSection.java | 48 +------------------ .../zktracer/runtime/callstack/CallStack.java | 17 ++++--- 3 files changed, 39 insertions(+), 61 deletions(-) diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java index 6a38e89c8b..2733dd6d38 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java @@ -67,6 +67,7 @@ import static net.consensys.linea.zktracer.types.Utils.leftPadTo; import static org.hyperledger.besu.evm.internal.Words.clampedToLong; +import java.util.Arrays; import java.util.Optional; import lombok.Getter; @@ -96,7 +97,6 @@ import net.consensys.linea.zktracer.types.MemorySpan; import org.apache.tuweni.bytes.Bytes; import org.hyperledger.besu.datatypes.Transaction; -import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.worldstate.WorldView; /** @@ -202,11 +202,7 @@ public static MmuCall sha3(final Hub hub, final Bytes hashInput) { public static MmuCall callDataCopy(final Hub hub) { final CallFrame currentFrame = hub.currentFrame(); final CallDataInfo callDataInfo = currentFrame.callDataInfo(); - final MessageFrame parentFrame = hub.callStack().parent().frame(); - final Bytes sourceBytes = - currentFrame.depth() == 0 - ? hub.txStack().current().getTransactionCallData() - : parentFrame.shadowReadMemory(0, parentFrame.memoryByteSize()); + final Bytes sourceBytes = hub.callStack().getFullMemoryOfCaller(hub); return new MmuCall(hub, MMU_INST_ANY_TO_RAM_WITH_PADDING) .sourceId((int) callDataInfo.callDataContextNumber()) @@ -222,6 +218,33 @@ public static MmuCall callDataCopy(final Hub hub) { .referenceSize(callDataInfo.memorySpan().length()); } + public static MmuCall callDataLoad(final Hub hub) { + final CallFrame currentFrame = hub.currentFrame(); + final long callDataSize = currentFrame.callDataInfo().memorySpan().length(); + final long callDataOffset = currentFrame.callDataInfo().memorySpan().offset(); + final EWord sourceOffset = EWord.of(currentFrame.frame().getStackItem(0)); + final long callDataCN = currentFrame.callDataInfo().callDataContextNumber(); + final Bytes sourceBytes = hub.callStack().getFullMemoryOfCaller(hub); + final int totalSourceOffset = (int) (callDataOffset + clampedToLong(sourceOffset)); + + final EWord read = + EWord.of( + Bytes.wrap( + Arrays.copyOfRange( + sourceBytes.toArrayUnsafe(), + totalSourceOffset, + totalSourceOffset + WORD_SIZE))); + + return new MmuCall(hub, MMU_INST_RIGHT_PADDED_WORD_EXTRACTION) + .sourceId((int) callDataCN) + .sourceRamBytes(Optional.of(sourceBytes)) + .sourceOffset(sourceOffset) + .referenceOffset(callDataOffset) + .referenceSize(callDataSize) + .limb1(read.hi()) + .limb2(read.lo()); + } + public static MmuCall LogX(final Hub hub, final LogData logData) { return new MmuCall(hub, MMU_INST_RAM_TO_EXO_WITH_PADDING) .sourceId(logData.callFrame.contextNumber()) diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/CallDataLoadSection.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/CallDataLoadSection.java index bac4d72b6d..63a78bef71 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/CallDataLoadSection.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/CallDataLoadSection.java @@ -16,14 +16,7 @@ package net.consensys.linea.zktracer.module.hub.section; import static com.google.common.base.Preconditions.checkArgument; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.MMU_INST_RIGHT_PADDED_WORD_EXTRACTION; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; import static net.consensys.linea.zktracer.module.hub.fragment.ContextFragment.readCurrentContextData; -import static net.consensys.linea.zktracer.runtime.callstack.CallFrame.extractContiguousLimbsFromMemory; -import static org.hyperledger.besu.evm.internal.Words.clampedToLong; - -import java.util.Arrays; -import java.util.Optional; import net.consensys.linea.zktracer.module.hub.Hub; import net.consensys.linea.zktracer.module.hub.fragment.ContextFragment; @@ -32,12 +25,6 @@ import net.consensys.linea.zktracer.module.hub.fragment.imc.oob.opcodes.CallDataLoadOobCall; import net.consensys.linea.zktracer.module.hub.signals.Exceptions; import net.consensys.linea.zktracer.opcode.OpCode; -import net.consensys.linea.zktracer.runtime.callstack.CallFrame; -import net.consensys.linea.zktracer.runtime.callstack.CallFrameType; -import net.consensys.linea.zktracer.types.EWord; -import net.consensys.linea.zktracer.types.MemorySpan; -import org.apache.tuweni.bytes.Bytes; -import org.hyperledger.besu.evm.internal.Words; public class CallDataLoadSection extends TraceSection { @@ -55,39 +42,8 @@ public CallDataLoadSection(Hub hub) { if (Exceptions.none(exception)) { if (!oobCall.isCdlOutOfBounds()) { - final long callDataSize = hub.currentFrame().callDataInfo().memorySpan().length(); - final long callDataOffset = hub.currentFrame().callDataInfo().memorySpan().offset(); - final EWord sourceOffset = EWord.of(hub.currentFrame().frame().getStackItem(0)); - final long callDataCN = hub.currentFrame().callDataInfo().callDataContextNumber(); - - final EWord read = - EWord.of( - Bytes.wrap( - Arrays.copyOfRange( - hub.currentFrame().callDataInfo().data().toArray(), - Words.clampedToInt(sourceOffset), - Words.clampedToInt(sourceOffset) + WORD_SIZE))); - - final CallFrame callDataCallFrame = hub.callStack().getByContextNumber(callDataCN); - - final MmuCall call = - new MmuCall(hub, MMU_INST_RIGHT_PADDED_WORD_EXTRACTION) - .sourceId((int) callDataCN) - .sourceRamBytes( - Optional.of( - callDataCallFrame.type() == CallFrameType.TRANSACTION_CALL_DATA_HOLDER - ? callDataCallFrame.callDataInfo().data() - : extractContiguousLimbsFromMemory( - callDataCallFrame.frame(), - MemorySpan.fromStartLength( - clampedToLong(sourceOffset) + callDataOffset, WORD_SIZE)))) - .sourceOffset(sourceOffset) - .referenceOffset(callDataOffset) - .referenceSize(callDataSize) - .limb1(read.hi()) - .limb2(read.lo()); - - imcFragment.callMmu(call); + final MmuCall mmuCall = MmuCall.callDataLoad(hub); + imcFragment.callMmu(mmuCall); } } else { // Sanity check diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/runtime/callstack/CallStack.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/runtime/callstack/CallStack.java index 1bbbf9a145..f0e32c59ee 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/runtime/callstack/CallStack.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/runtime/callstack/CallStack.java @@ -29,6 +29,7 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.evm.Code; +import org.hyperledger.besu.evm.frame.MessageFrame; /** * This class represents the call hierarchy of a transaction. @@ -256,15 +257,6 @@ public boolean isStatic() { return this.currentCallFrame().type() == CallFrameType.STATIC; } - /** - * Get the {@link CallFrame} representing the caller of the current frame - * - * @return the caller of the current frame - */ - public CallFrame caller() { - return this.callFrames.get(this.currentCallFrame().callerId()); - } - /** * Returns the ith {@link CallFrame} in this call stack. * @@ -322,4 +314,11 @@ public CallFrame getParentCallFrameById(int id) { public int getParentContextNumberById(int id) { return this.getParentCallFrameById(id).contextNumber(); } + + public Bytes getFullMemoryOfCaller(Hub hub) { + final MessageFrame parentFrame = parent().frame(); + return currentCallFrame().depth() == 0 + ? hub.txStack().current().getTransactionCallData() + : parentFrame.shadowReadMemory(0, parentFrame.memoryByteSize()); + } } From 170262d4918de45642f2897ec232fbd420ff5337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Fri, 8 Nov 2024 14:32:15 +0700 Subject: [PATCH 09/23] feat: simple test for call data manipulations inside of a CALL --- .../instructionprocessing/CallDataTests.java | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/CallDataTests.java diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/CallDataTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/CallDataTests.java new file mode 100644 index 0000000000..66d4873fbf --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/CallDataTests.java @@ -0,0 +1,116 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing; + +import net.consensys.linea.testing.*; +import net.consensys.linea.zktracer.opcode.OpCode; +import org.apache.tuweni.bytes.Bytes; +import org.hyperledger.besu.crypto.KeyPair; +import org.hyperledger.besu.crypto.SECP256K1; +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.datatypes.TransactionType; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.core.Transaction; +import org.junit.jupiter.api.Test; + +import java.util.List; + +/** + * The tests below are designed to test our handling of call data. + * For deployment transactions, and more generally deployment context's, call data + * is empty and the tests are "trivial" in some sense. They aren't for message calls. + */ +public class CallDataTests { + // @Test + // void transactionCallDataForMessageCallTest() { + // } + + // @Test + // void transactionCallDataForDeploymentTest() { + // } + + @Test + void nonAlignedCallDataInCallTest() { + Bytes bytecode = BytecodeCompiler.newProgram() + .push(callData32) + .push(1) + .op(OpCode.MSTORE) + .push(44) // r@c, shorter than the return data + .push(19) // r@o, deliberately overlaps with call data + .push(32) // cds + .push(1) // cdo + .push("ca11da7ac0de") // address + .op(OpCode.GAS) // gas + .op(OpCode.STATICCALL) + .compile(); + + Transaction transaction = transactionCallingCallDataCodeAccount(); + ToyExecutionEnvironmentV2.builder() + .accounts(accounts) + .transaction(transaction) + .transactionProcessingResultValidator(TransactionProcessingResultValidator.EMPTY_VALIDATOR) + .build() + .run(); + } + + // @Test + // void callDataInCreateTest() { + // } + + private final Bytes callData32 = Bytes.fromHexString("abcdef01234567890000deadbeef0000aa0f517e002024aa9876543210fedcba"); + + Bytes callDataByteCode = BytecodeCompiler.newProgram() + .push(13) // size + .push(29) // sourceOffset + .push(17) // targetOffset + .op(OpCode.CALLDATACOPY) + .push(0) + .op(OpCode.MLOAD) + .push(0) + .op(OpCode.CALLDATALOAD) + .push(28) + .op(OpCode.MSTORE) + .op(OpCode.MSIZE) // size + .push(11) // offset + .op(OpCode.RETURN) // the final instruction will expand memory + .compile(); + + KeyPair keyPair = new SECP256K1().generateKeyPair(); + Address userAddress = Address.extract(Hash.hash(keyPair.getPublicKey().getEncodedBytes())); + ToyAccount userAccount = + ToyAccount.builder().balance(Wei.fromEth(10)).nonce(99).address(userAddress).build(); + ToyAccount callDataCodeAccount = + ToyAccount.builder() + .balance(Wei.fromEth(1)) + .nonce(13) + .address(Address.fromHexString("ca11da7ac0de")) + .code(callDataByteCode) + .build(); + List accounts = List.of( userAccount, callDataCodeAccount); + + Transaction transactionCallingCallDataCodeAccount() { + return ToyTransaction.builder() + .sender(userAccount) + .to(callDataCodeAccount) + .payload(callData32) + .transactionType(TransactionType.FRONTIER) + .value(Wei.ONE) + .keyPair(keyPair) + .gasLimit(100_000L) + .gasPrice(Wei.of(8)) + .build(); + } +} From 4a1f3f398be50e90ac3762bc1bb910ded2f32bf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Fri, 8 Nov 2024 15:03:50 +0700 Subject: [PATCH 10/23] fix: CallDataTests fix --- .../instructionprocessing/CallDataTests.java | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/CallDataTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/CallDataTests.java index 66d4873fbf..a8330a08c4 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/CallDataTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/CallDataTests.java @@ -44,18 +44,6 @@ public class CallDataTests { @Test void nonAlignedCallDataInCallTest() { - Bytes bytecode = BytecodeCompiler.newProgram() - .push(callData32) - .push(1) - .op(OpCode.MSTORE) - .push(44) // r@c, shorter than the return data - .push(19) // r@o, deliberately overlaps with call data - .push(32) // cds - .push(1) // cdo - .push("ca11da7ac0de") // address - .op(OpCode.GAS) // gas - .op(OpCode.STATICCALL) - .compile(); Transaction transaction = transactionCallingCallDataCodeAccount(); ToyExecutionEnvironmentV2.builder() @@ -88,10 +76,30 @@ void nonAlignedCallDataInCallTest() { .op(OpCode.RETURN) // the final instruction will expand memory .compile(); + final Bytes callerCode = BytecodeCompiler.newProgram() + .push(callData32) + .push(1) + .op(OpCode.MSTORE) + .push(44) // r@c, shorter than the return data + .push(19) // r@o, deliberately overlaps with call data + .push(32) // cds + .push(1) // cdo + .push("ca11da7ac0de") // address + .op(OpCode.GAS) // gas + .op(OpCode.STATICCALL) + .compile(); + KeyPair keyPair = new SECP256K1().generateKeyPair(); Address userAddress = Address.extract(Hash.hash(keyPair.getPublicKey().getEncodedBytes())); ToyAccount userAccount = ToyAccount.builder().balance(Wei.fromEth(10)).nonce(99).address(userAddress).build(); + ToyAccount targetOfTransaction = + ToyAccount.builder() + .balance(Wei.fromEth(1)) + .nonce(13) + .address(Address.fromHexString("ca11ee")) + .code(callerCode) + .build(); ToyAccount callDataCodeAccount = ToyAccount.builder() .balance(Wei.fromEth(1)) @@ -99,12 +107,13 @@ void nonAlignedCallDataInCallTest() { .address(Address.fromHexString("ca11da7ac0de")) .code(callDataByteCode) .build(); - List accounts = List.of( userAccount, callDataCodeAccount); + + List accounts = List.of( userAccount, callDataCodeAccount, targetOfTransaction); Transaction transactionCallingCallDataCodeAccount() { return ToyTransaction.builder() .sender(userAccount) - .to(callDataCodeAccount) + .to(targetOfTransaction) .payload(callData32) .transactionType(TransactionType.FRONTIER) .value(Wei.ONE) From 2366a42b181ec0a34411735fe330b421055d86bd Mon Sep 17 00:00:00 2001 From: F Bojarski Date: Fri, 8 Nov 2024 09:30:52 +0100 Subject: [PATCH 11/23] fix when only one mmio inst Signed-off-by: F Bojarski --- .../mmu/instructions/AnyToRamWithPadding.java | 8 +- .../instructionprocessing/CallDataTests.java | 162 +++++++++--------- 2 files changed, 82 insertions(+), 88 deletions(-) diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/AnyToRamWithPadding.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/AnyToRamWithPadding.java index c3c3406ef0..927288679b 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/AnyToRamWithPadding.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/AnyToRamWithPadding.java @@ -564,10 +564,12 @@ private void setMicroInstructionsSomeDataCase(MmuData mmuData) { // Setting padding micro instructions if (totInitialRightZeroes != 0) { someDataOnlyOrFirstPaddingInstruction(mmuData); - for (int i = 1; i < totInitialRightZeroes - 1; i++) { - someDataMiddlePaddingInstruction(mmuData, i); + if (!totalRightZeroIsOne) { + for (int i = 1; i < totInitialRightZeroes - 1; i++) { + someDataMiddlePaddingInstruction(mmuData, i); + } + someDataLastPaddingInstruction(mmuData); } - someDataLastPaddingInstruction(mmuData); } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/CallDataTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/CallDataTests.java index a8330a08c4..a664495cc4 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/CallDataTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/CallDataTests.java @@ -14,6 +14,8 @@ */ package net.consensys.linea.zktracer.instructionprocessing; +import java.util.List; + import net.consensys.linea.testing.*; import net.consensys.linea.zktracer.opcode.OpCode; import org.apache.tuweni.bytes.Bytes; @@ -26,100 +28,90 @@ import org.hyperledger.besu.ethereum.core.Transaction; import org.junit.jupiter.api.Test; -import java.util.List; - /** - * The tests below are designed to test our handling of call data. - * For deployment transactions, and more generally deployment context's, call data - * is empty and the tests are "trivial" in some sense. They aren't for message calls. + * The tests below are designed to test our handling of call data. For deployment transactions, and + * more generally deployment context's, call data is empty and the tests are "trivial" in some + * sense. They aren't for message calls. */ public class CallDataTests { - // @Test - // void transactionCallDataForMessageCallTest() { - // } - - // @Test - // void transactionCallDataForDeploymentTest() { - // } - - @Test - void nonAlignedCallDataInCallTest() { - Transaction transaction = transactionCallingCallDataCodeAccount(); - ToyExecutionEnvironmentV2.builder() - .accounts(accounts) - .transaction(transaction) - .transactionProcessingResultValidator(TransactionProcessingResultValidator.EMPTY_VALIDATOR) - .build() - .run(); - } + @Test + void nonAlignedCallDataInCallTest() { - // @Test - // void callDataInCreateTest() { - // } + Transaction transaction = transactionCallingCallDataCodeAccount(); + ToyExecutionEnvironmentV2.builder() + .accounts(accounts) + .transaction(transaction) + .transactionProcessingResultValidator(TransactionProcessingResultValidator.EMPTY_VALIDATOR) + .build() + .run(); + } - private final Bytes callData32 = Bytes.fromHexString("abcdef01234567890000deadbeef0000aa0f517e002024aa9876543210fedcba"); + private final Bytes callData32 = + Bytes.fromHexString("abcdef01234567890000deadbeef0000aa0f517e002024aa9876543210fedcba"); - Bytes callDataByteCode = BytecodeCompiler.newProgram() - .push(13) // size - .push(29) // sourceOffset - .push(17) // targetOffset - .op(OpCode.CALLDATACOPY) - .push(0) - .op(OpCode.MLOAD) - .push(0) - .op(OpCode.CALLDATALOAD) - .push(28) - .op(OpCode.MSTORE) - .op(OpCode.MSIZE) // size - .push(11) // offset - .op(OpCode.RETURN) // the final instruction will expand memory - .compile(); + Bytes callDataByteCode = + BytecodeCompiler.newProgram() + .push(13) // size + .push(29) // sourceOffset + .push(17) // targetOffset + .op(OpCode.CALLDATACOPY) + .push(0) + .op(OpCode.MLOAD) + .push(0) + .op(OpCode.CALLDATALOAD) + .push(28) + .op(OpCode.MSTORE) + .op(OpCode.MSIZE) // size + .push(11) // offset + .op(OpCode.RETURN) // the final instruction will expand memory + .compile(); - final Bytes callerCode = BytecodeCompiler.newProgram() - .push(callData32) - .push(1) - .op(OpCode.MSTORE) - .push(44) // r@c, shorter than the return data - .push(19) // r@o, deliberately overlaps with call data - .push(32) // cds - .push(1) // cdo - .push("ca11da7ac0de") // address - .op(OpCode.GAS) // gas - .op(OpCode.STATICCALL) - .compile(); + final Bytes callerCode = + BytecodeCompiler.newProgram() + .push(callData32) + .push(1) + .op(OpCode.MSTORE) + .push(44) // r@c, shorter than the return data + .push(19) // r@o, deliberately overlaps with call data + .push(32) // cds + .push(1) // cdo + .push("ca11da7ac0de") // address + .op(OpCode.GAS) // gas + .op(OpCode.STATICCALL) + .compile(); - KeyPair keyPair = new SECP256K1().generateKeyPair(); - Address userAddress = Address.extract(Hash.hash(keyPair.getPublicKey().getEncodedBytes())); - ToyAccount userAccount = - ToyAccount.builder().balance(Wei.fromEth(10)).nonce(99).address(userAddress).build(); - ToyAccount targetOfTransaction = - ToyAccount.builder() - .balance(Wei.fromEth(1)) - .nonce(13) - .address(Address.fromHexString("ca11ee")) - .code(callerCode) - .build(); - ToyAccount callDataCodeAccount = - ToyAccount.builder() - .balance(Wei.fromEth(1)) - .nonce(13) - .address(Address.fromHexString("ca11da7ac0de")) - .code(callDataByteCode) - .build(); + KeyPair keyPair = new SECP256K1().generateKeyPair(); + Address userAddress = Address.extract(Hash.hash(keyPair.getPublicKey().getEncodedBytes())); + ToyAccount userAccount = + ToyAccount.builder().balance(Wei.fromEth(10)).nonce(99).address(userAddress).build(); + ToyAccount targetOfTransaction = + ToyAccount.builder() + .balance(Wei.fromEth(1)) + .nonce(13) + .address(Address.fromHexString("ca11ee")) + .code(callerCode) + .build(); + ToyAccount callDataCodeAccount = + ToyAccount.builder() + .balance(Wei.fromEth(1)) + .nonce(13) + .address(Address.fromHexString("ca11da7ac0de")) + .code(callDataByteCode) + .build(); - List accounts = List.of( userAccount, callDataCodeAccount, targetOfTransaction); + List accounts = List.of(userAccount, callDataCodeAccount, targetOfTransaction); - Transaction transactionCallingCallDataCodeAccount() { - return ToyTransaction.builder() - .sender(userAccount) - .to(targetOfTransaction) - .payload(callData32) - .transactionType(TransactionType.FRONTIER) - .value(Wei.ONE) - .keyPair(keyPair) - .gasLimit(100_000L) - .gasPrice(Wei.of(8)) - .build(); - } + Transaction transactionCallingCallDataCodeAccount() { + return ToyTransaction.builder() + .sender(userAccount) + .to(targetOfTransaction) + .payload(callData32) + .transactionType(TransactionType.FRONTIER) + .value(Wei.ONE) + .keyPair(keyPair) + .gasLimit(100_000L) + .gasPrice(Wei.of(8)) + .build(); + } } From da448e4af81622a7e18457662d32a6681099f7a5 Mon Sep 17 00:00:00 2001 From: F Bojarski Date: Fri, 8 Nov 2024 19:32:06 +0100 Subject: [PATCH 12/23] fix return data when calling a precompile Signed-off-by: F Bojarski --- .../zktracer/module/hub/fragment/imc/mmu/MmuCall.java | 6 +++++- .../call/precompileSubsection/PrecompileSubsection.java | 7 +++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java index 2733dd6d38..7b7d1b3ddd 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java @@ -63,6 +63,7 @@ import static net.consensys.linea.zktracer.module.hub.precompiles.ModexpMetadata.EBS_MIN_OFFSET; import static net.consensys.linea.zktracer.module.hub.precompiles.ModexpMetadata.MBS_MIN_OFFSET; import static net.consensys.linea.zktracer.runtime.callstack.CallFrame.extractContiguousLimbsFromMemory; +import static net.consensys.linea.zktracer.types.AddressUtils.isPrecompile; import static net.consensys.linea.zktracer.types.Conversions.bigIntegerToBytes; import static net.consensys.linea.zktracer.types.Utils.leftPadTo; import static org.hyperledger.besu.evm.internal.Words.clampedToLong; @@ -282,7 +283,10 @@ public static MmuCall returnDataCopy(final Hub hub) { return new MmuCall(hub, MMU_INST_ANY_TO_RAM_WITH_PADDING) .sourceId(returnerFrame.contextNumber()) .sourceRamBytes( - Optional.of(extractContiguousLimbsFromMemory(returnerFrame.frame(), returnDataSegment))) + Optional.of( + isPrecompile(returnerFrame.accountAddress()) + ? returnerFrame.returnData() + : extractContiguousLimbsFromMemory(returnerFrame.frame(), returnDataSegment))) .targetId(currentFrame.contextNumber()) .targetRamBytes( Optional.of( diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/call/precompileSubsection/PrecompileSubsection.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/call/precompileSubsection/PrecompileSubsection.java index fb1e267d23..b8c71472a9 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/call/precompileSubsection/PrecompileSubsection.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/call/precompileSubsection/PrecompileSubsection.java @@ -151,10 +151,13 @@ public void resolveUponContextExit(Hub hub, CallFrame callFrame) { @Override public void resolveAtContextReEntry(Hub hub, CallFrame frame) { - callSuccess = bytesToBoolean(hub.messageFrame().getStackItem(0)); + callSuccess = bytesToBoolean(frame.frame().getStackItem(0)); returnData = frame.frame().getReturnData(); - frame.returnDataContextNumber(exoModuleOperationId()); + final int returnerCn = exoModuleOperationId(); + final CallFrame returnerFrame = hub.callStack().getByContextNumber(returnerCn); + returnerFrame.returnData(returnData); + frame.returnDataContextNumber(returnerCn); frame.returnDataSpan(new MemorySpan(0, returnData.size())); if (callSuccess) { From ad1833c1edf71c487de69cb6e651339fb3e80ade Mon Sep 17 00:00:00 2001 From: F Bojarski Date: Sat, 9 Nov 2024 05:55:29 +0100 Subject: [PATCH 13/23] fix(anyToRam): transition data/padding Signed-off-by: F Bojarski --- .../linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java | 2 +- .../zktracer/module/mmu/instructions/AnyToRamWithPadding.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java index 7b7d1b3ddd..6fa661e320 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java @@ -207,7 +207,7 @@ public static MmuCall callDataCopy(final Hub hub) { return new MmuCall(hub, MMU_INST_ANY_TO_RAM_WITH_PADDING) .sourceId((int) callDataInfo.callDataContextNumber()) - .sourceRamBytes(Optional.ofNullable(sourceBytes)) + .sourceRamBytes(Optional.of(sourceBytes)) .targetId(currentFrame.contextNumber()) .targetRamBytes( Optional.of( diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/AnyToRamWithPadding.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/AnyToRamWithPadding.java index 927288679b..2123c56bf9 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/AnyToRamWithPadding.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/AnyToRamWithPadding.java @@ -534,7 +534,7 @@ private void setMicroInstructionsSomeDataCase(MmuData mmuData) { // Setting if the transition data / padding is made in 1 or 2 mmio instructions dataToPaddingTransitionTakesTwoMmioInstructions = totInitialRightZeroes != 0 - && (onlyDataTransferMaxesOutTarget || lastDataTransferMaxesOutTarget); + && (!onlyDataTransferMaxesOutTarget || !lastDataTransferMaxesOutTarget); // Setting Microinstruction constant values mmuData.mmuToMmioConstantValues( From 5749926c2152011de7bdd55ccef142d1983c7b5d Mon Sep 17 00:00:00 2001 From: F Bojarski Date: Sat, 9 Nov 2024 09:34:32 +0100 Subject: [PATCH 14/23] add returnDataCopy from precompile test Signed-off-by: F Bojarski --- .../ReturnDataCopyTest.java | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/ReturnDataCopyTest.java diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/ReturnDataCopyTest.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/ReturnDataCopyTest.java new file mode 100644 index 0000000000..09150e48fe --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/ReturnDataCopyTest.java @@ -0,0 +1,53 @@ +/* + * Copyright ConsenSys Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package net.consensys.linea.zktracer.instructionprocessing; + +import net.consensys.linea.testing.BytecodeCompiler; +import net.consensys.linea.testing.BytecodeRunner; +import net.consensys.linea.zktracer.opcode.OpCode; +import org.apache.tuweni.bytes.Bytes; +import org.hyperledger.besu.datatypes.Address; +import org.junit.jupiter.api.Test; + +public class ReturnDataCopyTest { + @Test + void testReturnDataCopyFromSha256() { + BytecodeRunner.of( + BytecodeCompiler.newProgram() + .push( + Bytes.fromHexString( + "0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")) + .push(1) + .op(OpCode.MSTORE) + .push(22) // r@c, shorter than the return data + .push(5) // r@o, deliberately overlaps with call data + .push(18) // cds + .push(2) // cdo + .push(Address.SHA256) // address + .op(OpCode.GAS) // gas + .op(OpCode.STATICCALL) + .push(5) + .push(5) + .push(5) + .op(OpCode.RETURNDATACOPY) + .push(0) + .push(0) + .op(OpCode.MLOAD) + .op(OpCode.STOP) + .compile()) + .run(); + } +} From 1f9b6e911c63e589c350966a688cda228b0b127b Mon Sep 17 00:00:00 2001 From: F Bojarski Date: Sat, 9 Nov 2024 14:43:00 +0100 Subject: [PATCH 15/23] spotless Signed-off-by: F Bojarski --- .../mmu/instructions/RightPaddedWordExtraction.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/RightPaddedWordExtraction.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/RightPaddedWordExtraction.java index 92f1da015c..98e6e1b75b 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/RightPaddedWordExtraction.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/RightPaddedWordExtraction.java @@ -46,10 +46,9 @@ public class RightPaddedWordExtraction implements MmuInstruction { private final Euc euc; private final Wcp wcp; - private List eucCallRecords; - private List wcpCallRecords; + private final List eucCallRecords; + private final List wcpCallRecords; - private boolean firstLimbPadded; private short firstLimbByteSize; private boolean secondLimbPadded; private short secondLimbByteSize; @@ -60,8 +59,6 @@ public class RightPaddedWordExtraction implements MmuInstruction { private Bytes sourceLimbOffset; private Bytes sourceByteOffset; private boolean secondLimbVoid; - private int firstMicroInst; - private int secondMicroInst; public RightPaddedWordExtraction(Euc euc, Wcp wcp) { this.euc = euc; @@ -119,7 +116,7 @@ private void row2() { wcpCallRecords.add( MmuWcpCallRecord.instLtBuilder().arg1Lo(wcpArg1).arg2Lo(wcpArg2).result(wcpResult).build()); - firstLimbPadded = wcpResult; + final boolean firstLimbPadded = wcpResult; if (!secondLimbPadded) { secondLimbByteSize = LLARGE; } else { @@ -212,6 +209,7 @@ public MmuData setMicroInstructions(MmuData mmuData) { } private void firstMicroInstruction(MmuData mmuData) { + int firstMicroInst; if (firstLimbSingleSource) { firstMicroInst = firstLimbIsFull ? MMIO_INST_RAM_TO_LIMB_TRANSPLANT : MMIO_INST_RAM_TO_LIMB_ONE_SOURCE; @@ -230,6 +228,7 @@ private void firstMicroInstruction(MmuData mmuData) { } private void secondMicroInstruction(MmuData mmuData) { + int secondMicroInst; if (secondLimbVoid) { secondMicroInst = MMIO_INST_LIMB_VANISHES; } else { From 54a9d6de2613b08bfd56d7532c4398a0966b906e Mon Sep 17 00:00:00 2001 From: F Bojarski Date: Mon, 11 Nov 2024 14:44:48 +0100 Subject: [PATCH 16/23] fix(rightPaddedWordExtraction): now fill limb at defers post exec Signed-off-by: F Bojarski --- .../module/hub/fragment/imc/mmu/MmuCall.java | 75 +------------------ .../fragment/imc/mmu/opcode/CallDataLoad.java | 58 ++++++++++++++ .../hub/section/CallDataLoadSection.java | 3 +- .../module/hub/section/CreateSection.java | 12 ++- .../zktracer/module/mmu/MmuOperation.java | 16 ++-- .../RightPaddedWordExtraction.java | 42 ++++++----- .../linea/replaytests/ReplayTests.java | 2 - 7 files changed, 101 insertions(+), 107 deletions(-) create mode 100644 arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/opcode/CallDataLoad.java diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java index 6fa661e320..f77d191eba 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java @@ -18,44 +18,7 @@ import static com.google.common.base.Preconditions.*; import static net.consensys.linea.zktracer.module.Util.slice; import static net.consensys.linea.zktracer.module.blake2fmodexpdata.BlakeModexpDataOperation.MODEXP_COMPONENT_BYTE_SIZE; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.EMPTY_RIPEMD_LO; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.EMPTY_SHA2_HI; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.EMPTY_SHA2_LO; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.EXO_SUM_WEIGHT_BLAKEMODEXP; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.EXO_SUM_WEIGHT_ECDATA; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.EXO_SUM_WEIGHT_KEC; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.EXO_SUM_WEIGHT_LOG; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.EXO_SUM_WEIGHT_RIPSHA; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.EXO_SUM_WEIGHT_ROM; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.EXO_SUM_WEIGHT_TXCD; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.MMU_INST_ANY_TO_RAM_WITH_PADDING; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.MMU_INST_BLAKE; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.MMU_INST_EXO_TO_RAM_TRANSPLANTS; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.MMU_INST_INVALID_CODE_PREFIX; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.MMU_INST_MLOAD; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.MMU_INST_MODEXP_DATA; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.MMU_INST_MODEXP_ZERO; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.MMU_INST_MSTORE; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.MMU_INST_RAM_TO_EXO_WITH_PADDING; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.MMU_INST_RAM_TO_RAM_SANS_PADDING; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.MMU_INST_RIGHT_PADDED_WORD_EXTRACTION; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.PHASE_BLAKE_DATA; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.PHASE_BLAKE_PARAMS; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.PHASE_BLAKE_RESULT; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.PHASE_ECADD_DATA; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.PHASE_ECADD_RESULT; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.PHASE_ECMUL_DATA; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.PHASE_ECMUL_RESULT; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.PHASE_ECPAIRING_DATA; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.PHASE_ECPAIRING_RESULT; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.PHASE_ECRECOVER_DATA; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.PHASE_ECRECOVER_RESULT; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.PHASE_MODEXP_BASE; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.PHASE_MODEXP_EXPONENT; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.PHASE_MODEXP_MODULUS; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.PHASE_MODEXP_RESULT; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.RLP_TXN_PHASE_DATA; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.*; import static net.consensys.linea.zktracer.module.hub.Hub.newIdentifierFromStamp; import static net.consensys.linea.zktracer.module.hub.fragment.scenario.PrecompileScenarioFragment.PrecompileFlag.PRC_RIPEMD_160; import static net.consensys.linea.zktracer.module.hub.fragment.scenario.PrecompileScenarioFragment.PrecompileFlag.PRC_SHA2_256; @@ -68,7 +31,6 @@ import static net.consensys.linea.zktracer.types.Utils.leftPadTo; import static org.hyperledger.besu.evm.internal.Words.clampedToLong; -import java.util.Arrays; import java.util.Optional; import lombok.Getter; @@ -80,11 +42,7 @@ import net.consensys.linea.zktracer.module.hub.Trace; import net.consensys.linea.zktracer.module.hub.defer.PostTransactionDefer; import net.consensys.linea.zktracer.module.hub.fragment.TraceSubFragment; -import net.consensys.linea.zktracer.module.hub.fragment.imc.mmu.opcode.CodeCopy; -import net.consensys.linea.zktracer.module.hub.fragment.imc.mmu.opcode.Create; -import net.consensys.linea.zktracer.module.hub.fragment.imc.mmu.opcode.Create2; -import net.consensys.linea.zktracer.module.hub.fragment.imc.mmu.opcode.ExtCodeCopy; -import net.consensys.linea.zktracer.module.hub.fragment.imc.mmu.opcode.ReturnFromDeploymentMmuCall; +import net.consensys.linea.zktracer.module.hub.fragment.imc.mmu.opcode.*; import net.consensys.linea.zktracer.module.hub.fragment.scenario.PrecompileScenarioFragment; import net.consensys.linea.zktracer.module.hub.precompiles.ModexpMetadata; import net.consensys.linea.zktracer.module.hub.section.call.precompileSubsection.EllipticCurvePrecompileSubsection; @@ -220,30 +178,7 @@ public static MmuCall callDataCopy(final Hub hub) { } public static MmuCall callDataLoad(final Hub hub) { - final CallFrame currentFrame = hub.currentFrame(); - final long callDataSize = currentFrame.callDataInfo().memorySpan().length(); - final long callDataOffset = currentFrame.callDataInfo().memorySpan().offset(); - final EWord sourceOffset = EWord.of(currentFrame.frame().getStackItem(0)); - final long callDataCN = currentFrame.callDataInfo().callDataContextNumber(); - final Bytes sourceBytes = hub.callStack().getFullMemoryOfCaller(hub); - final int totalSourceOffset = (int) (callDataOffset + clampedToLong(sourceOffset)); - - final EWord read = - EWord.of( - Bytes.wrap( - Arrays.copyOfRange( - sourceBytes.toArrayUnsafe(), - totalSourceOffset, - totalSourceOffset + WORD_SIZE))); - - return new MmuCall(hub, MMU_INST_RIGHT_PADDED_WORD_EXTRACTION) - .sourceId((int) callDataCN) - .sourceRamBytes(Optional.of(sourceBytes)) - .sourceOffset(sourceOffset) - .referenceOffset(callDataOffset) - .referenceSize(callDataSize) - .limb1(read.hi()) - .limb2(read.lo()); + return new CallDataLoad(hub); } public static MmuCall LogX(final Hub hub, final LogData logData) { @@ -290,9 +225,7 @@ public static MmuCall returnDataCopy(final Hub hub) { .targetId(currentFrame.contextNumber()) .targetRamBytes( Optional.of( - currentFrame - .frame() - .shadowReadMemory(0, hub.currentFrame().frame().memoryByteSize()))) + currentFrame.frame().shadowReadMemory(0, currentFrame.frame().memoryByteSize()))) .sourceOffset(EWord.of(currentFrame.frame().getStackItem(1))) .targetOffset(EWord.of(currentFrame.frame().getStackItem(0))) .size(clampedToLong(currentFrame.frame().getStackItem(2))) diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/opcode/CallDataLoad.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/opcode/CallDataLoad.java new file mode 100644 index 0000000000..ed038913c1 --- /dev/null +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/opcode/CallDataLoad.java @@ -0,0 +1,58 @@ +/* + * Copyright ConsenSys Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package net.consensys.linea.zktracer.module.hub.fragment.imc.mmu.opcode; + +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.MMU_INST_RIGHT_PADDED_WORD_EXTRACTION; + +import java.util.Optional; + +import net.consensys.linea.zktracer.module.hub.Hub; +import net.consensys.linea.zktracer.module.hub.defer.PostOpcodeDefer; +import net.consensys.linea.zktracer.module.hub.fragment.imc.mmu.MmuCall; +import net.consensys.linea.zktracer.runtime.callstack.CallFrame; +import net.consensys.linea.zktracer.types.EWord; +import org.apache.tuweni.bytes.Bytes; +import org.hyperledger.besu.evm.frame.MessageFrame; +import org.hyperledger.besu.evm.operation.Operation; + +public class CallDataLoad extends MmuCall implements PostOpcodeDefer { + + public CallDataLoad(final Hub hub) { + super(hub, MMU_INST_RIGHT_PADDED_WORD_EXTRACTION); + hub.defers().scheduleForPostExecution(this); + + final CallFrame currentFrame = hub.currentFrame(); + final long callDataSize = currentFrame.callDataInfo().memorySpan().length(); + final long callDataOffset = currentFrame.callDataInfo().memorySpan().offset(); + final EWord sourceOffset = EWord.of(currentFrame.frame().getStackItem(0)); + final long callDataCN = currentFrame.callDataInfo().callDataContextNumber(); + final Bytes sourceBytes = hub.callStack().getFullMemoryOfCaller(hub); + + this.sourceId((int) callDataCN) + .sourceRamBytes(Optional.of(sourceBytes)) + .sourceOffset(sourceOffset) + .referenceOffset(callDataOffset) + .referenceSize(callDataSize); + } + + @Override + public void resolvePostExecution( + Hub hub, MessageFrame frame, Operation.OperationResult operationResult) { + final EWord stack = EWord.of(frame.getStackItem(0)); + this.limb1(stack.hi()); + this.limb2(stack.lo()); + } +} diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/CallDataLoadSection.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/CallDataLoadSection.java index 63a78bef71..e03d9e64b6 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/CallDataLoadSection.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/CallDataLoadSection.java @@ -22,6 +22,7 @@ import net.consensys.linea.zktracer.module.hub.fragment.ContextFragment; import net.consensys.linea.zktracer.module.hub.fragment.imc.ImcFragment; import net.consensys.linea.zktracer.module.hub.fragment.imc.mmu.MmuCall; +import net.consensys.linea.zktracer.module.hub.fragment.imc.mmu.opcode.CallDataLoad; import net.consensys.linea.zktracer.module.hub.fragment.imc.oob.opcodes.CallDataLoadOobCall; import net.consensys.linea.zktracer.module.hub.signals.Exceptions; import net.consensys.linea.zktracer.opcode.OpCode; @@ -42,7 +43,7 @@ public CallDataLoadSection(Hub hub) { if (Exceptions.none(exception)) { if (!oobCall.isCdlOutOfBounds()) { - final MmuCall mmuCall = MmuCall.callDataLoad(hub); + final CallDataLoad mmuCall = (CallDataLoad) MmuCall.callDataLoad(hub); imcFragment.callMmu(mmuCall); } } else { diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/CreateSection.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/CreateSection.java index 361485fc4a..e03a967c67 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/CreateSection.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/CreateSection.java @@ -181,8 +181,8 @@ public CreateSection(Hub hub) { final boolean failedCreate = createdAddressHasNonZeroNonce || createdAddressHasNonEmptyCode; final boolean emptyInitCode = hub.transients().op().initCodeSegment().isEmpty(); - final long offset = Words.clampedToLong(hub.messageFrame().getStackItem(1)); - final long size = Words.clampedToLong(hub.messageFrame().getStackItem(2)); + final long offset = Words.clampedToLong(messageFrame.getStackItem(1)); + final long size = Words.clampedToLong(messageFrame.getStackItem(2)); // Trigger MMU & SHAKIRA to hash the (non-empty) InitCode of CREATE2 - even for failed CREATE2 if (hub.opCode() == CREATE2 && !emptyInitCode) { @@ -197,7 +197,7 @@ public CreateSection(Hub hub) { triggerHashInfo(shakiraDataOperation.result()); } - value = failedCreate ? Wei.ZERO : Wei.of(UInt256.fromBytes(hub.messageFrame().getStackItem(0))); + value = failedCreate ? Wei.ZERO : Wei.of(UInt256.fromBytes(messageFrame.getStackItem(0))); if (failedCreate || emptyInitCode) { finalContextFragment = ContextFragment.nonExecutionProvidesEmptyReturnData(hub); @@ -219,16 +219,14 @@ public CreateSection(Hub hub) { // Finally, non-exceptional, non-aborting, non-failing, non-emptyInitCode create hub.defers() - .scheduleForContextReEntry( - this, hub.currentFrame()); // To get the success bit of the CREATE(2) + .scheduleForContextReEntry(this, callFrame); // To get the success bit of the CREATE(2) requiresRomLex = true; hub.romLex().callRomLex(messageFrame); hub.transients() .conflation() .deploymentInfo() - .newDeploymentWithExecutionAt( - createeAddress, hub.messageFrame().shadowReadMemory(offset, size)); + .newDeploymentWithExecutionAt(createeAddress, messageFrame.shadowReadMemory(offset, size)); // Note: the case CREATE2 has been set before, we need to do it even in the failure case if (hub.opCode() == CREATE) { diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/MmuOperation.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/MmuOperation.java index 3fcc650172..f5e387df72 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/MmuOperation.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/MmuOperation.java @@ -66,9 +66,12 @@ public boolean traceMe() { return mmuData.mmuCall().traceMe(); } - private final List vanishingLimbMmioInstructions = + private static final List vanishingLimbMmioInstructions = List.of(MMIO_INST_RAM_VANISHES, MMIO_INST_LIMB_VANISHES, MMIO_INST_RAM_EXCISION); + private static final List limbAlreadyKnownMmuInstructions = + List.of(MMU_INST_INVALID_CODE_PREFIX, MMU_INST_BLAKE, MMU_INST_RIGHT_PADDED_WORD_EXTRACTION); + @Override protected int computeLineCount() { checkState(traceMe(), "Cannot compute if traceMe is false"); @@ -129,13 +132,9 @@ public void getCFI() { public void fillLimb() { final int mmuInstruction = mmuData.hubToMmuValues().mmuInstruction(); - // Job already done in the preprocessing only for INVALID_CODE_PREFIX - if (mmuInstruction == MMU_INST_INVALID_CODE_PREFIX) { - return; - } - - // the limb for BLAKE is given by the HUB - if (mmuInstruction == MMU_INST_BLAKE) { + // Limb is already known, either given by MmuCall, or computed in preprocessing + // (INVALID_CODE_PREFIX) + if (limbAlreadyKnownMmuInstructions.contains(mmuInstruction)) { return; } @@ -158,7 +157,6 @@ public void fillLimb() { final int exoByteOffset = mmioInst.targetByteOffset(); final Bytes16 exoLimb = readBytes(mmuData.exoBytes(), offset, sizeToExtract, exoByteOffset); - ; mmioInst.limb(exoLimb); } } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/RightPaddedWordExtraction.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/RightPaddedWordExtraction.java index 98e6e1b75b..4907aa31be 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/RightPaddedWordExtraction.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/RightPaddedWordExtraction.java @@ -49,6 +49,7 @@ public class RightPaddedWordExtraction implements MmuInstruction { private final List eucCallRecords; private final List wcpCallRecords; + private long totalSourceOffset; private short firstLimbByteSize; private boolean secondLimbPadded; private short secondLimbByteSize; @@ -111,12 +112,15 @@ private void row2() { // row n°2 final Bytes wcpArg1 = longToBytes(extractionSize); final Bytes wcpArg2 = Bytes.of(LLARGE); - final boolean wcpResult = wcp.callLT(wcpArg1, wcpArg2); + final boolean firstLimbPadded = wcp.callLT(wcpArg1, wcpArg2); wcpCallRecords.add( - MmuWcpCallRecord.instLtBuilder().arg1Lo(wcpArg1).arg2Lo(wcpArg2).result(wcpResult).build()); + MmuWcpCallRecord.instLtBuilder() + .arg1Lo(wcpArg1) + .arg2Lo(wcpArg2) + .result(firstLimbPadded) + .build()); - final boolean firstLimbPadded = wcpResult; if (!secondLimbPadded) { secondLimbByteSize = LLARGE; } else { @@ -126,7 +130,7 @@ private void row2() { firstLimbByteSize = !firstLimbPadded ? LLARGE : extractionSize; final Bytes dividend = Bytes.of(firstLimbByteSize); - EucOperation eucOp = euc.callEUC(dividend, Bytes.of(LLARGE)); + final EucOperation eucOp = euc.callEUC(dividend, Bytes.of(LLARGE)); firstLimbIsFull = BooleanUtils.toBoolean(eucOp.quotient().toInt()); @@ -141,13 +145,13 @@ private void row2() { private void row3(final HubToMmuValues hubToMmuValues) { // row n°3 - final Bytes dividend = - longToBytes(hubToMmuValues.sourceOffsetLo().longValue() + hubToMmuValues.referenceOffset()); - EucOperation eucOp = euc.callEUC(dividend, Bytes.of(LLARGE)); + totalSourceOffset = + hubToMmuValues.sourceOffsetLo().longValue() + hubToMmuValues.referenceOffset(); + final EucOperation eucOp = euc.callEUC(longToBytes(totalSourceOffset), Bytes.of(LLARGE)); eucCallRecords.add( MmuEucCallRecord.builder() - .dividend(dividend.toLong()) + .dividend(totalSourceOffset) .divisor((short) LLARGE) .quotient(eucOp.quotient().toLong()) .remainder((short) eucOp.remainder().toInt()) @@ -158,12 +162,14 @@ private void row3(final HubToMmuValues hubToMmuValues) { final Bytes wcpArg1 = Bytes.ofUnsignedShort(sourceByteOffset.toInt() + firstLimbByteSize); final Bytes wcpArg2 = Bytes.of(LLARGEPO); - boolean wcpResult = wcp.callLT(wcpArg1, wcpArg2); + firstLimbSingleSource = wcp.callLT(wcpArg1, wcpArg2); wcpCallRecords.add( - MmuWcpCallRecord.instLtBuilder().arg1Lo(wcpArg1).arg2Lo(wcpArg2).result(wcpResult).build()); - - firstLimbSingleSource = wcpResult; + MmuWcpCallRecord.instLtBuilder() + .arg1Lo(wcpArg1) + .arg2Lo(wcpArg2) + .result(firstLimbSingleSource) + .build()); } private void row4() { @@ -172,12 +178,14 @@ private void row4() { final Bytes wcpArg1 = Bytes.ofUnsignedShort(sourceByteOffset.toInt() + secondLimbByteSize); final Bytes wcpArg2 = Bytes.of(LLARGEPO); - boolean wcpResult = wcp.callLT(wcpArg1, wcpArg2); + secondLimbSingleSource = wcp.callLT(wcpArg1, wcpArg2); wcpCallRecords.add( - MmuWcpCallRecord.instLtBuilder().arg1Lo(wcpArg1).arg2Lo(wcpArg2).result(wcpResult).build()); - - secondLimbSingleSource = wcpResult; + MmuWcpCallRecord.instLtBuilder() + .arg1Lo(wcpArg1) + .arg2Lo(wcpArg2) + .result(secondLimbSingleSource) + .build()); } private void row5() { @@ -195,7 +203,7 @@ private void row5() { @Override public MmuData setMicroInstructions(MmuData mmuData) { - HubToMmuValues hubToMmuValues = mmuData.hubToMmuValues(); + final HubToMmuValues hubToMmuValues = mmuData.hubToMmuValues(); // Setting MMIO constant values mmuData.mmuToMmioConstantValues( diff --git a/arithmetization/src/test/java/net/consensys/linea/replaytests/ReplayTests.java b/arithmetization/src/test/java/net/consensys/linea/replaytests/ReplayTests.java index ba0b84e067..861fa82efc 100644 --- a/arithmetization/src/test/java/net/consensys/linea/replaytests/ReplayTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/replaytests/ReplayTests.java @@ -123,8 +123,6 @@ void blockHash2() { // TODO: should be replaced by a unit test triggering AnyToRamWithPadding (mixed case) MMU // instruction - - // @Disabled @Test void negativeNumberOfMmioInstruction() { replay(LINEA_MAINNET, "6029454-6029459.json.gz"); From 15ed434340fe24e09b512253edf3a0318abee7f6 Mon Sep 17 00:00:00 2001 From: F Bojarski Date: Mon, 11 Nov 2024 21:27:59 +0100 Subject: [PATCH 17/23] fix(hub): mmuStamp & mxpStamp Signed-off-by: F Bojarski --- .../module/hub/fragment/common/CommonFragment.java | 14 +++++++++++--- .../hub/fragment/common/CommonFragmentValues.java | 2 +- .../zktracer/module/hub/section/TraceSection.java | 7 ++++++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/common/CommonFragment.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/common/CommonFragment.java index 3e89e38702..a0ad080896 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/common/CommonFragment.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/common/CommonFragment.java @@ -51,12 +51,20 @@ public final class CommonFragment implements TraceFragment { private final CommonFragmentValues commonFragmentValues; private final int nonStackRowsCounter; private final boolean twoLineInstructionCounter; + private final int mmuStamp; + private final int mxpStamp; public CommonFragment( - CommonFragmentValues commonValues, int stackLineCounter, int nonStackLineCounter) { + CommonFragmentValues commonValues, + int stackLineCounter, + int nonStackLineCounter, + int mmuStamp, + int mxpStamp) { this.commonFragmentValues = commonValues; this.twoLineInstructionCounter = stackLineCounter == 1; this.nonStackRowsCounter = nonStackLineCounter; + this.mmuStamp = mmuStamp; + this.mxpStamp = mxpStamp; } private boolean isUnexceptional() { @@ -87,8 +95,8 @@ public Trace trace(Trace trace) { .contextMayChange(commonFragmentValues.contextMayChange) .exceptionAhoy(Exceptions.any(commonFragmentValues.exceptions) && isExec) .logInfoStamp(commonFragmentValues.logStamp) - .mmuStamp(commonFragmentValues.stamps.mmu()) - .mxpStamp(commonFragmentValues.stamps.mxp()) + .mmuStamp(mmuStamp) + .mxpStamp(mxpStamp) // nontrivial dom / sub are traced in storage or account fragments only .contextNumber(isExec ? frame.contextNumber() : 0) .contextNumberNew(commonFragmentValues.contextNumberNew) diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/common/CommonFragmentValues.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/common/CommonFragmentValues.java index 7eda4e6aa7..09204c29c3 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/common/CommonFragmentValues.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/common/CommonFragmentValues.java @@ -47,7 +47,7 @@ public class CommonFragmentValues { public final HubProcessingPhase hubProcessingPhase; public final int hubStamp; public final CallStack callStack; - public final State.TxState.Stamps stamps; // for MMU and MXP stamps + public final State.TxState.Stamps stamps; @Setter public int logStamp = -1; @Getter final CallFrame callFrame; public final short exceptions; diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/TraceSection.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/TraceSection.java index a96079e30c..fd59a8276d 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/TraceSection.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/TraceSection.java @@ -224,7 +224,12 @@ public void trace(Trace hubTrace) { specificFragment.trace(hubTrace); final CommonFragment commonFragment = - new CommonFragment(commonValues, stackLineCounter, nonStackLineCounter); + new CommonFragment( + commonValues, + stackLineCounter, + nonStackLineCounter, + hub.state.stamps().mmu(), + hub.state.stamps().mxp()); commonFragment.trace(hubTrace); hubTrace.fillAndValidateRow(); } From 6bd8e5f1312d915b3a55e82d68fec325e3fe522c Mon Sep 17 00:00:00 2001 From: F Bojarski Date: Tue, 12 Nov 2024 18:21:53 +0100 Subject: [PATCH 18/23] just formatting Signed-off-by: F Bojarski --- .../module/hub/section/StackRamSection.java | 63 +++++++++---------- 1 file changed, 31 insertions(+), 32 deletions(-) diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/StackRamSection.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/StackRamSection.java index 08eb42fa97..b47b905227 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/StackRamSection.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/StackRamSection.java @@ -30,6 +30,7 @@ import net.consensys.linea.zktracer.module.hub.fragment.imc.mmu.MmuCall; import net.consensys.linea.zktracer.module.hub.signals.Exceptions; import net.consensys.linea.zktracer.opcode.OpCode; +import net.consensys.linea.zktracer.runtime.callstack.CallFrame; import net.consensys.linea.zktracer.types.EWord; import net.consensys.linea.zktracer.types.MemorySpan; import org.apache.tuweni.bytes.Bytes; @@ -62,47 +63,45 @@ public StackRamSection(Hub hub) { // the unexceptional case checkArgument(Exceptions.none(exceptions)); - final EWord offset = EWord.of(hub.currentFrame().frame().getStackItem(0)); + final CallFrame currentFrame = hub.currentFrame(); + final EWord offset = EWord.of(currentFrame.frame().getStackItem(0)); final long longOffset = Words.clampedToLong(offset); final Bytes currentRam = extractContiguousLimbsFromMemory( - hub.currentFrame().frame(), new MemorySpan(longOffset, WORD_SIZE)); - final int currentContextNumber = hub.currentFrame().contextNumber(); + currentFrame.frame(), new MemorySpan(longOffset, WORD_SIZE)); + final int currentContextNumber = currentFrame.contextNumber(); final EWord value = instruction.equals(OpCode.MLOAD) - ? EWord.of(hub.messageFrame().shadowReadMemory(Words.clampedToLong(offset), WORD_SIZE)) - : EWord.of(hub.currentFrame().frame().getStackItem(1)); + ? EWord.of(currentFrame.frame().shadowReadMemory(longOffset, WORD_SIZE)) + : EWord.of(currentFrame.frame().getStackItem(1)); MmuCall mmuCall; switch (instruction) { - case MSTORE -> { - mmuCall = - new MmuCall(hub, MMU_INST_MSTORE) - .targetId(currentContextNumber) - .targetOffset(offset) - .limb1(value.hi()) - .limb2(value.lo()) - .targetRamBytes(Optional.of(currentRam)); - } - case MSTORE8 -> { - mmuCall = - new MmuCall(hub, MMU_INST_MSTORE8) - .targetId(currentContextNumber) - .targetOffset(offset) - .limb1(value.hi()) - .limb2(value.lo()) - .targetRamBytes(Optional.of(currentRam)); - } - case MLOAD -> { - mmuCall = - new MmuCall(hub, MMU_INST_MLOAD) - .sourceId(currentContextNumber) - .sourceOffset(offset) - .limb1(value.hi()) - .limb2(value.lo()) - .sourceRamBytes(Optional.of(currentRam)); - } + case MSTORE -> mmuCall = + new MmuCall(hub, MMU_INST_MSTORE) + .targetId(currentContextNumber) + .targetOffset(offset) + .limb1(value.hi()) + .limb2(value.lo()) + .targetRamBytes(Optional.of(currentRam)); + + case MSTORE8 -> mmuCall = + new MmuCall(hub, MMU_INST_MSTORE8) + .targetId(currentContextNumber) + .targetOffset(offset) + .limb1(value.hi()) + .limb2(value.lo()) + .targetRamBytes(Optional.of(currentRam)); + + case MLOAD -> mmuCall = + new MmuCall(hub, MMU_INST_MLOAD) + .sourceId(currentContextNumber) + .sourceOffset(offset) + .limb1(value.hi()) + .limb2(value.lo()) + .sourceRamBytes(Optional.of(currentRam)); + default -> throw new IllegalStateException("Not a STACK_RAM instruction"); } From 8694243ff8051a9b59ab315eadea7b11015d23d7 Mon Sep 17 00:00:00 2001 From: F Bojarski Date: Wed, 13 Nov 2024 08:01:54 +0100 Subject: [PATCH 19/23] tgtOffset instead of refOffset for some prc partial return data copy Signed-off-by: F Bojarski --- .../module/hub/fragment/imc/mmu/MmuCall.java | 6 +++--- .../mmu/instructions/ExoToRamTransplants.java | 8 ++++---- .../mmu/instructions/RamToRamSansPadding.java | 14 +++++++------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java index f77d191eba..af261e3741 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java @@ -475,7 +475,7 @@ public static MmuCall partialCopyOfReturnDataForEcadd( .sourceRamBytes(Optional.of(leftPadTo(subsection.returnData(), 2 * WORD_SIZE))) .targetId(hub.currentFrame().contextNumber()) .targetRamBytes(Optional.of(subsection.callerMemorySnapshot())) - .targetOffset(EWord.of(subsection.parentReturnDataTarget.offset())) + .referenceOffset(subsection.parentReturnDataTarget.offset()) .size(subsection.parentReturnDataTarget.length()) .referenceSize(64); } @@ -515,7 +515,7 @@ public static MmuCall partialCopyOfReturnDataForEcmul( .sourceRamBytes(Optional.of(leftPadTo(subsection.returnData(), 2 * WORD_SIZE))) .targetId(hub.currentFrame().contextNumber()) .targetRamBytes(Optional.of(subsection.callerMemorySnapshot())) - .targetOffset(EWord.of(subsection.parentReturnDataTarget().offset())) + .referenceOffset(subsection.parentReturnDataTarget().offset()) .size(subsection.parentReturnDataTarget().length()) .referenceSize(64); } @@ -566,7 +566,7 @@ public static MmuCall partialCopyOfReturnDataForEcpairing( .sourceRamBytes(Optional.of(leftPadTo(subsection.returnData(), WORD_SIZE))) .targetId(hub.currentFrame().contextNumber()) .targetRamBytes(Optional.of(subsection.callerMemorySnapshot())) - .targetOffset(EWord.of(subsection.parentReturnDataTarget.offset())) + .referenceOffset(subsection.parentReturnDataTarget.offset()) .size(subsection.parentReturnDataTarget.length()) .referenceSize(WORD_SIZE); } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/ExoToRamTransplants.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/ExoToRamTransplants.java index 352f3b6f7e..53ee520567 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/ExoToRamTransplants.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/ExoToRamTransplants.java @@ -34,9 +34,9 @@ import org.apache.tuweni.bytes.Bytes; public class ExoToRamTransplants implements MmuInstruction { - private Euc euc; - private List eucCallRecords; - private List wcpCallRecords; + private final Euc euc; + private final List eucCallRecords; + private final List wcpCallRecords; public ExoToRamTransplants(Euc euc) { this.euc = euc; @@ -73,7 +73,7 @@ public MmuData preProcess(MmuData mmuData) { @Override public MmuData setMicroInstructions(MmuData mmuData) { - HubToMmuValues hubToMmuValues = mmuData.hubToMmuValues(); + final HubToMmuValues hubToMmuValues = mmuData.hubToMmuValues(); // Setting MMIO constant values mmuData.mmuToMmioConstantValues( diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/RamToRamSansPadding.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/RamToRamSansPadding.java index 18a0450551..4abbfe9f7a 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/RamToRamSansPadding.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/RamToRamSansPadding.java @@ -41,8 +41,8 @@ public class RamToRamSansPadding implements MmuInstruction { private final Euc euc; private final Wcp wcp; - private List eucCallRecords; - private List wcpCallRecords; + private final List eucCallRecords; + private final List wcpCallRecords; private short lastLimbByteSize; private short middleSourceByteOffset; private boolean lastLimbSingleSource; @@ -103,7 +103,7 @@ public MmuData preProcess(final MmuData mmuData) { private void row1(final HubToMmuValues hubToMmuValues) { // row n°1 final Bytes dividend = bigIntegerToBytes(hubToMmuValues.sourceOffsetLo()); - EucOperation eucOp = euc.callEUC(dividend, Bytes.of(LLARGE)); + final EucOperation eucOp = euc.callEUC(dividend, Bytes.of(LLARGE)); initialSourceLimbOffset = eucOp.quotient().toLong(); initialSourceByteOffset = (short) eucOp.remainder().toInt(); @@ -129,7 +129,7 @@ private void row1(final HubToMmuValues hubToMmuValues) { private void row2(final HubToMmuValues hubToMmuValues) { // row n°2 final Bytes dividend = longToBytes(hubToMmuValues.referenceOffset()); - EucOperation eucOp = euc.callEUC(dividend, Bytes.of(LLARGE)); + final EucOperation eucOp = euc.callEUC(dividend, Bytes.of(LLARGE)); initialTargetLimbOffset = eucOp.quotient().toLong(); initialTargetByteOffset = (short) eucOp.remainder().toInt(); @@ -153,7 +153,7 @@ private void row2(final HubToMmuValues hubToMmuValues) { private void row3(final HubToMmuValues hubToMmuValues) { // row n°3 final Bytes dividend = longToBytes(hubToMmuValues.referenceOffset() + realSize - 1); - EucOperation eucOp = euc.callEUC(dividend, Bytes.of(LLARGE)); + final EucOperation eucOp = euc.callEUC(dividend, Bytes.of(LLARGE)); finalTargetLimbOffset = eucOp.quotient().toLong(); @@ -206,7 +206,7 @@ private void row4() { } final Bytes dividend = longToBytes(middleSourceByteOffset + lastLimbByteSize - 1); - EucOperation eucOp = euc.callEUC(dividend, Bytes.of(LLARGE)); + final EucOperation eucOp = euc.callEUC(dividend, Bytes.of(LLARGE)); eucCallRecords.add( MmuEucCallRecord.builder() .dividend(dividend.toLong()) @@ -229,7 +229,7 @@ private void row5() { MmuWcpCallRecord.instIsZeroBuilder().arg1Lo(wcpArg1).result(wcpResult).build()); final Bytes dividend = longToBytes(lastLimbByteSize); - EucOperation eucOp = euc.callEUC(dividend, Bytes.of(LLARGE)); + final EucOperation eucOp = euc.callEUC(dividend, Bytes.of(LLARGE)); eucCallRecords.add( MmuEucCallRecord.builder() .dividend(dividend.toLong()) From 75c4bc356eb64d01c646c0d21fce89b0d8dee9a9 Mon Sep 17 00:00:00 2001 From: F Bojarski Date: Wed, 13 Nov 2024 11:12:17 +0100 Subject: [PATCH 20/23] fix(mmuCallCreate2): need exoBytes even if failing CREATE2 and ROM not activated Signed-off-by: F Bojarski --- .../zktracer/module/hub/fragment/imc/mmu/MmuCall.java | 5 +++-- .../module/hub/fragment/imc/mmu/opcode/Create2.java | 8 ++------ .../linea/zktracer/module/hub/section/CreateSection.java | 5 +++-- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java index af261e3741..5343801f1d 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java @@ -245,8 +245,9 @@ public static MmuCall returnFromMessageCall(final Hub hub) { return MmuCall.revert(hub); } - public static MmuCall create2(final Hub hub, boolean failureCondition) { - return new Create2(hub, failureCondition); + public static MmuCall create2( + final Hub hub, final Bytes create2initCode, final boolean failureCondition) { + return new Create2(hub, create2initCode, failureCondition); } public static MmuCall invalidCodePrefix(final Hub hub) { diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/opcode/Create2.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/opcode/Create2.java index 57a78559e5..1c6b70c7e8 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/opcode/Create2.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/opcode/Create2.java @@ -39,7 +39,7 @@ public class Create2 extends MmuCall implements RomLexDefer { private final Hub hub; private ContractMetadata contract; - public Create2(final Hub hub, final boolean failedCreate) { + public Create2(final Hub hub, final Bytes create2initCode, final boolean failedCreate) { super(hub, MMU_INST_RAM_TO_EXO_WITH_PADDING); this.hub = hub; this.hub.romLex().createDefers().register(this); @@ -55,6 +55,7 @@ public Create2(final Hub hub, final boolean failedCreate) { currentFrame.frame(), MemorySpan.fromStartLength(clampedToLong(sourceOffset), size)))) .auxId(newIdentifierFromStamp(hub.stamp())) + .exoBytes(Optional.of(create2initCode)) .sourceOffset(sourceOffset) .size(size) .referenceSize(size) @@ -70,11 +71,6 @@ public int targetId() { return exoIsRom ? hub.romLex().getCodeFragmentIndexByMetadata(contract) : 0; } - @Override - public Optional exoBytes() { - return exoIsRom ? Optional.of(hub.romLex().getCodeByMetadata(contract)) : Optional.empty(); - } - @Override public void updateContractMetadata(ContractMetadata metadata) { contract = metadata; diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/CreateSection.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/CreateSection.java index e03a967c67..685d6f5a24 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/CreateSection.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/CreateSection.java @@ -186,10 +186,11 @@ public CreateSection(Hub hub) { // Trigger MMU & SHAKIRA to hash the (non-empty) InitCode of CREATE2 - even for failed CREATE2 if (hub.opCode() == CREATE2 && !emptyInitCode) { - final MmuCall mmuCall = MmuCall.create2(hub, failedCreate); + final Bytes create2InitCode = messageFrame.shadowReadMemory(offset, size); + + final MmuCall mmuCall = MmuCall.create2(hub, create2InitCode, failedCreate); imcFragment.callMmu(mmuCall); - final Bytes create2InitCode = messageFrame.shadowReadMemory(offset, size); final ShakiraDataOperation shakiraDataOperation = new ShakiraDataOperation(hub.stamp(), create2InitCode); hub.shakiraData().call(shakiraDataOperation); From 759a600dbbf8f2c8ae243455890b41ea35ba2539 Mon Sep 17 00:00:00 2001 From: F Bojarski Date: Wed, 13 Nov 2024 16:12:18 +0100 Subject: [PATCH 21/23] fix partial copy target Id for modexp partial copy Signed-off-by: F Bojarski --- .../module/hub/fragment/imc/mmu/MmuCall.java | 42 +++++++++---------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java index 5343801f1d..dc218190bf 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/MmuCall.java @@ -756,7 +756,7 @@ public static MmuCall forModexpPartialResultCopy( .sourceId(modexpSubsection.exoModuleOperationId()) .sourceRamBytes( Optional.of(leftPadTo(modexpSubsection.returnData, MODEXP_COMPONENT_BYTE_SIZE))) - .targetId(modexpSubsection.callSection.hubStamp()) + .targetId(hub.currentFrame().contextNumber()) .targetRamBytes(Optional.of(modexpSubsection.callerMemorySnapshot)) .sourceOffset(EWord.of(MODEXP_COMPONENT_BYTE_SIZE - modExpMetadata.mbs().toInt())) .size(modExpMetadata.mbs().toInt()) @@ -766,28 +766,24 @@ public static MmuCall forModexpPartialResultCopy( @Override public Trace trace(Trace trace, State.TxState.Stamps stamps) { - if (traceMe) { - stamps.incrementMmuStamp(); - return trace - .pMiscMmuFlag(true) - .pMiscMmuInst(instruction) - .pMiscMmuTgtId(targetId()) - .pMiscMmuSrcId(sourceId()) - .pMiscMmuAuxId(auxId()) - .pMiscMmuSrcOffsetHi(sourceOffset.hi()) - .pMiscMmuSrcOffsetLo(sourceOffset.lo()) - .pMiscMmuTgtOffsetLo(targetOffset.lo()) - .pMiscMmuSize(size) - .pMiscMmuRefOffset(referenceOffset) - .pMiscMmuRefSize(referenceSize) - .pMiscMmuSuccessBit(successBit) - .pMiscMmuLimb1(limb1) - .pMiscMmuLimb2(limb2) - .pMiscMmuExoSum(exoSum) - .pMiscMmuPhase(phase); - } else { - return trace; - } + stamps.incrementMmuStamp(); + return trace + .pMiscMmuFlag(true) + .pMiscMmuInst(instruction) + .pMiscMmuTgtId(targetId()) + .pMiscMmuSrcId(sourceId()) + .pMiscMmuAuxId(auxId()) + .pMiscMmuSrcOffsetHi(sourceOffset.hi()) + .pMiscMmuSrcOffsetLo(sourceOffset.lo()) + .pMiscMmuTgtOffsetLo(targetOffset.lo()) + .pMiscMmuSize(size) + .pMiscMmuRefOffset(referenceOffset) + .pMiscMmuRefSize(referenceSize) + .pMiscMmuSuccessBit(successBit) + .pMiscMmuLimb1(limb1) + .pMiscMmuLimb2(limb2) + .pMiscMmuExoSum(exoSum) + .pMiscMmuPhase(phase); } @Override From e38c9c8499e05f31e08e6d092820b3ce58ade50d Mon Sep 17 00:00:00 2001 From: F Bojarski Date: Wed, 13 Nov 2024 16:14:29 +0100 Subject: [PATCH 22/23] update constraints Signed-off-by: F Bojarski --- linea-constraints | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linea-constraints b/linea-constraints index 8b3fc7937c..1715992779 160000 --- a/linea-constraints +++ b/linea-constraints @@ -1 +1 @@ -Subproject commit 8b3fc7937c20779c33e56b9c656fecc4db4bc7f9 +Subproject commit 17159927794b2f25e96d24fbf7a50d552b257546 From 79ba83c0d92514bb629e65aa079dec7e3debe205 Mon Sep 17 00:00:00 2001 From: F Bojarski Date: Wed, 13 Nov 2024 18:22:48 +0100 Subject: [PATCH 23/23] update to latest master for constraint Signed-off-by: F Bojarski --- linea-constraints | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linea-constraints b/linea-constraints index 1715992779..dcc15ce87c 160000 --- a/linea-constraints +++ b/linea-constraints @@ -1 +1 @@ -Subproject commit 17159927794b2f25e96d24fbf7a50d552b257546 +Subproject commit dcc15ce87cf0b119ce987ab6d806eafa845085c1