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 e0d4cc7a0d..9a1682570c 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.types.Conversions.bigIntegerToBytes; +import static net.consensys.linea.zktracer.types.Utils.leftPadTo; import static org.apache.tuweni.bytes.Bytes.minimalBytes; import java.util.Optional; @@ -141,7 +142,7 @@ public void dontTraceMe() { } private MmuCall updateExoSum(final int exoValue) { - this.exoSum += exoValue; + exoSum += exoValue; return this; } @@ -173,7 +174,6 @@ final MmuCall setEcData() { return this.exoIsEcData(true).updateExoSum(EXO_SUM_WEIGHT_ECDATA); } - // TODO: make the instruction an enum public MmuCall(final Hub hub, final int instruction) { hub.defers().scheduleForPostTransaction(this); this.instruction = instruction; @@ -445,7 +445,7 @@ public static MmuCall forIdentityExtractCallData( final Hub hub, PrecompileSubsection precompileSubsection) { return new MmuCall(hub, MMU_INST_RAM_TO_RAM_SANS_PADDING) - .sourceId(precompileSubsection.callSection.hubStamp()) + .sourceId(hub.currentFrame().contextNumber()) // called at ContextReEntry .sourceRamBytes(Optional.of(precompileSubsection.callerMemorySnapshot)) .targetId(precompileSubsection.exoModuleOperationId()) .targetRamBytes(Optional.of(Bytes.EMPTY)) @@ -460,7 +460,7 @@ public static MmuCall forIdentityReturnData( return new MmuCall(hub, MMU_INST_RAM_TO_RAM_SANS_PADDING) .sourceId(precompileSubsection.exoModuleOperationId()) .sourceRamBytes(Optional.of(precompileSubsection.returnData())) - .targetId(precompileSubsection.callSection.hubStamp()) + .targetId(hub.currentFrame().contextNumber()) .targetRamBytes(Optional.of(precompileSubsection.callerMemorySnapshot)) .sourceOffset(EWord.ZERO) .targetOffset(EWord.of(precompileSubsection.parentReturnDataTarget.offset())) @@ -706,10 +706,10 @@ public static MmuCall forModexpExtractBase( final Hub hub, final ModexpSubsection modexpSubsection, final ModexpMetadata modExpMetadata) { if (modExpMetadata.extractBase()) { return new MmuCall(hub, MMU_INST_MODEXP_DATA) - .sourceId(modexpSubsection.callSection.hubStamp()) + .sourceId(hub.currentFrame().contextNumber()) // called at ContextReEntry .sourceRamBytes(Optional.of(modexpSubsection.callerMemorySnapshot)) .targetId(modexpSubsection.exoModuleOperationId()) - .exoBytes(Optional.of(modExpMetadata.base())) + .exoBytes(Optional.of(leftPadTo(modExpMetadata.base(), MODEXP_COMPONENT_BYTE_SIZE))) .sourceOffset(EWord.of(BASE_MIN_OFFSET)) .size(modExpMetadata.bbs().toInt()) .referenceOffset(modexpSubsection.callDataMemorySpan.offset()) @@ -728,10 +728,10 @@ public static MmuCall forModexpExtractExponent( final Hub hub, final ModexpSubsection modexpSubsection, final ModexpMetadata modExpMetadata) { if (modExpMetadata.extractExponent()) { return new MmuCall(hub, MMU_INST_MODEXP_DATA) - .sourceId(modexpSubsection.callSection.hubStamp()) + .sourceId(hub.currentFrame().contextNumber()) // called at ContextReEntry .sourceRamBytes(Optional.of(modexpSubsection.callerMemorySnapshot)) .targetId(modexpSubsection.exoModuleOperationId()) - .exoBytes(Optional.of(modExpMetadata.exp())) + .exoBytes(Optional.of(leftPadTo(modExpMetadata.exp(), MODEXP_COMPONENT_BYTE_SIZE))) .sourceOffset(EWord.of(BASE_MIN_OFFSET + modExpMetadata.bbs().toInt())) .size(modExpMetadata.ebs().toInt()) .referenceOffset(modexpSubsection.callDataMemorySpan.offset()) @@ -749,10 +749,10 @@ public static MmuCall forModexpExtractExponent( public static MmuCall forModexpExtractModulus( final Hub hub, final ModexpSubsection modexpSubsection, final ModexpMetadata modExpMetadata) { return new MmuCall(hub, MMU_INST_MODEXP_DATA) - .sourceId(modexpSubsection.callSection.hubStamp()) + .sourceId(hub.currentFrame().contextNumber()) // called at ContextReEntry .sourceRamBytes(Optional.of(modexpSubsection.callerMemorySnapshot)) .targetId(modexpSubsection.exoModuleOperationId()) - .exoBytes(Optional.of(modExpMetadata.mod())) + .exoBytes(Optional.of(leftPadTo(modExpMetadata.mod(), MODEXP_COMPONENT_BYTE_SIZE))) .sourceOffset( EWord.of(BASE_MIN_OFFSET + modExpMetadata.bbs().toInt() + modExpMetadata.ebs().toInt())) .size(modExpMetadata.mbs().toInt()) @@ -766,7 +766,7 @@ public static MmuCall forModexpFullResultCopy( final Hub hub, final ModexpSubsection modexpSubsection, final ModexpMetadata modExpMetadata) { return new MmuCall(hub, MMU_INST_EXO_TO_RAM_TRANSPLANTS) .sourceId(modexpSubsection.exoModuleOperationId()) - .exoBytes(Optional.of(modexpSubsection.returnData())) + .exoBytes(Optional.of(leftPadTo(modexpSubsection.returnData(), MODEXP_COMPONENT_BYTE_SIZE))) .targetId(modexpSubsection.returnDataContextNumber()) .targetRamBytes(Optional.of(Bytes.EMPTY)) .size(MODEXP_COMPONENT_BYTE_SIZE) diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/opcode/CodeCopy.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/opcode/CodeCopy.java index 1ae9b31323..2534e6955f 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/opcode/CodeCopy.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/opcode/CodeCopy.java @@ -38,7 +38,7 @@ public CodeCopy(final Hub hub) { this.hub = hub; this.contract = hub.currentFrame().metadata(); - this.exoBytes(Optional.of(hub.romLex().getCodeByMetadata(contract))) + this.exoBytes(Optional.of(hub.currentFrame().code().bytecode())) .targetId(hub.currentFrame().contextNumber()) .targetRamBytes( Optional.of( @@ -54,6 +54,6 @@ public CodeCopy(final Hub hub) { @Override public int sourceId() { - return this.hub.romLex().getCodeFragmentIndexByMetadata(this.contract); + return hub.romLex().getCodeFragmentIndexByMetadata(contract); } } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/opcode/Create.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/opcode/Create.java index 5a558adc5a..ed65b8ab62 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/opcode/Create.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/opcode/Create.java @@ -24,6 +24,7 @@ import net.consensys.linea.zktracer.module.romlex.ContractMetadata; import net.consensys.linea.zktracer.module.romlex.RomLexDefer; import net.consensys.linea.zktracer.types.EWord; +import org.apache.tuweni.bytes.Bytes; import org.hyperledger.besu.evm.internal.Words; /** @@ -45,7 +46,6 @@ public Create(final Hub hub) { hub.currentFrame() .frame() .shadowReadMemory(0, hub.currentFrame().frame().memoryByteSize()))) - .exoBytes(Optional.of(hub.romLex().getCodeByMetadata(contract))) .sourceOffset(EWord.of(hub.messageFrame().getStackItem(1))) .size(Words.clampedToLong(hub.messageFrame().getStackItem(2))) .referenceSize(Words.clampedToLong(hub.messageFrame().getStackItem(2))) @@ -54,11 +54,16 @@ public Create(final Hub hub) { @Override public int targetId() { - return hub.romLex().getCodeFragmentIndexByMetadata(this.contract); + return hub.romLex().getCodeFragmentIndexByMetadata(contract); + } + + @Override + public Optional exoBytes() { + return Optional.of(hub.romLex().getCodeByMetadata(contract)); } @Override public void updateContractMetadata(ContractMetadata metadata) { - this.contract = metadata; + contract = metadata; } } 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 0f51f61f14..c064e803ef 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 @@ -24,6 +24,7 @@ import net.consensys.linea.zktracer.module.romlex.ContractMetadata; import net.consensys.linea.zktracer.module.romlex.RomLexDefer; import net.consensys.linea.zktracer.types.EWord; +import org.apache.tuweni.bytes.Bytes; import org.hyperledger.besu.evm.internal.Words; /** @@ -45,7 +46,6 @@ public Create2(final Hub hub, final boolean failedCreate) { hub.currentFrame() .frame() .shadowReadMemory(0, hub.currentFrame().frame().memoryByteSize()))) - .exoBytes(Optional.of(hub.romLex().getCodeByMetadata(contract))) .auxId(hub.state().stamps().hub()) .sourceOffset(EWord.of(hub.messageFrame().getStackItem(1))) .size(Words.clampedToLong(hub.messageFrame().getStackItem(2))) @@ -62,8 +62,13 @@ public int targetId() { return exoIsRom ? hub.romLex().getCodeFragmentIndexByMetadata(contract) : 0; } + @Override + public Optional exoBytes() { + return Optional.of(hub.romLex().getCodeByMetadata(contract)); + } + @Override public void updateContractMetadata(ContractMetadata metadata) { - this.contract = metadata; + contract = metadata; } } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/opcode/ExtCodeCopy.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/opcode/ExtCodeCopy.java index a2df01209b..0737faaadf 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/opcode/ExtCodeCopy.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/opcode/ExtCodeCopy.java @@ -24,6 +24,7 @@ import net.consensys.linea.zktracer.module.hub.fragment.imc.mmu.MmuCall; import net.consensys.linea.zktracer.module.romlex.ContractMetadata; import net.consensys.linea.zktracer.types.EWord; +import org.apache.tuweni.bytes.Bytes; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.evm.internal.Words; import org.hyperledger.besu.evm.worldstate.WorldView; @@ -44,8 +45,7 @@ public ExtCodeCopy(final Hub hub) { final Address foreignCodeAddress = Words.toAddress(hub.messageFrame().getStackItem(0)); this.contract = ContractMetadata.canonical(hub, foreignCodeAddress); - this.exoBytes(Optional.of(hub.romLex().getCodeByMetadata(contract))) - .targetId(hub.currentFrame().contextNumber()) + this.targetId(hub.currentFrame().contextNumber()) .targetRamBytes( Optional.of( hub.currentFrame() @@ -57,12 +57,24 @@ public ExtCodeCopy(final Hub hub) { .setRom(); } + @Override + public Optional exoBytes() { + try { + return Optional.of(hub.romLex().getCodeByMetadata(contract)); + } catch (Exception ignored) { + // Can be empty Bytes in case the ext account is empty. In this case, no associated CFI + return Optional.of(Bytes.EMPTY); + } + } + @Override public long referenceSize() { - return hub.romLex() - .getChunkByMetadata(contract) - .map(chunk -> chunk.byteCode().size()) - .orElse(0); + try { + return (hub.romLex().getCodeByMetadata(contract).size()); + } catch (Exception ignored) { + // Can be 0 in case the ext account is empty. In this case, no associated CFI + return 0; + } } @Override diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/opcode/ReturnFromDeploymentMmuCall.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/opcode/ReturnFromDeploymentMmuCall.java index 1356fe5ac5..d950f41f8d 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/opcode/ReturnFromDeploymentMmuCall.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/mmu/opcode/ReturnFromDeploymentMmuCall.java @@ -26,6 +26,7 @@ import net.consensys.linea.zktracer.module.romlex.ContractMetadata; import net.consensys.linea.zktracer.module.shakiradata.ShakiraDataOperation; import net.consensys.linea.zktracer.types.EWord; +import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.evm.internal.Words; @@ -37,7 +38,7 @@ @Accessors(fluent = true) public class ReturnFromDeploymentMmuCall extends MmuCall { private final Hub hub; - private final ContractMetadata contract; + private ContractMetadata contract; @Getter private final Bytes32 hashResult; public ReturnFromDeploymentMmuCall(final Hub hub) { @@ -47,10 +48,10 @@ public ReturnFromDeploymentMmuCall(final Hub hub) { final Address contractAddress = hub.messageFrame().getContractAddress(); final int depNumber = hub.deploymentNumberOf(contractAddress); - contract = ContractMetadata.underDeployment(contractAddress, depNumber); + contract = ContractMetadata.make(contractAddress, depNumber, false); final ShakiraDataOperation shakiraDataOperation = - new ShakiraDataOperation(hub.stamp(), hub.romLex().getCodeByMetadata(contract)); + new ShakiraDataOperation(hub.stamp(), hub.romLex().byteCode()); hub.shakiraData().call(shakiraDataOperation); hashResult = shakiraDataOperation.result(); @@ -61,7 +62,6 @@ public ReturnFromDeploymentMmuCall(final Hub hub) { hub.currentFrame() .frame() .shadowReadMemory(0, hub.currentFrame().frame().memoryByteSize()))) - .exoBytes(Optional.of(hub.romLex().getCodeByMetadata(contract))) .auxId(hub.state().stamps().hub()) .sourceOffset(EWord.of(hub.messageFrame().getStackItem(0))) .size(Words.clampedToLong(hub.messageFrame().getStackItem(1))) @@ -72,6 +72,11 @@ public ReturnFromDeploymentMmuCall(final Hub hub) { @Override public int targetId() { - return this.hub.romLex().getCodeFragmentIndexByMetadata(this.contract); + return hub.romLex().getCodeFragmentIndexByMetadata(contract); + } + + @Override + public Optional exoBytes() { + return Optional.of(hub.romLex().getCodeByMetadata(contract)); } } 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 24aa676b1f..bac4d72b6d 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 @@ -19,6 +19,8 @@ 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; @@ -30,40 +32,33 @@ 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 { - final short exception; - final Bytes callDataRam; - final int currentContextNumber; - final long callDataCN; - final EWord sourceOffset; - - long callDataOffset = -1; - long callDataSize = -1; public CallDataLoadSection(Hub hub) { super(hub, (short) (hub.opCode().equals(OpCode.CALLDATALOAD) ? 4 : 3)); this.addStack(hub); - this.exception = hub.pch().exceptions(); - this.currentContextNumber = hub.currentFrame().contextNumber(); - this.callDataSize = hub.currentFrame().callDataInfo().memorySpan().length(); - this.callDataOffset = hub.currentFrame().callDataInfo().memorySpan().offset(); - this.sourceOffset = EWord.of(hub.currentFrame().frame().getStackItem(0)); - this.callDataCN = hub.currentFrame().callDataInfo().callDataContextNumber(); - this.callDataRam = hub.currentFrame().callDataInfo().data(); + final short exception = hub.pch().exceptions(); final ImcFragment imcFragment = ImcFragment.empty(hub); + this.addFragment(imcFragment); final CallDataLoadOobCall oobCall = new CallDataLoadOobCall(); imcFragment.callOob(oobCall); 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( @@ -73,24 +68,32 @@ public CallDataLoadSection(Hub hub) { 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()) - .sourceRamBytes(Optional.of(callDataRam)); + .limb2(read.lo()); imcFragment.callMmu(call); } } else { + // Sanity check checkArgument(Exceptions.outOfGasException(exception)); } - this.addFragment(imcFragment); - final ContextFragment context = readCurrentContextData(hub); this.addFragment(context); } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/call/CallSection.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/call/CallSection.java index 13047e5607..499a2f2485 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/call/CallSection.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/call/CallSection.java @@ -50,6 +50,7 @@ import net.consensys.linea.zktracer.module.hub.signals.Exceptions; 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; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Transaction; @@ -156,10 +157,11 @@ public CallSection(Hub hub) { "The STP and the HUB have conflicting predictions of an OOGX\n\t\tHUB_STAMP = %s", hubStamp())); - final Address callerAddress = hub.messageFrame().getRecipientAddress(); + final CallFrame currentFrame = hub.currentFrame(); + final Address callerAddress = currentFrame.frame().getRecipientAddress(); preOpcodeCallerSnapshot = canonical(hub, callerAddress); - rawCalleeAddress = hub.currentFrame().frame().getStackItem(1); + rawCalleeAddress = currentFrame.frame().getStackItem(1); final Address calleeAddress = Address.extract(EWord.of(rawCalleeAddress)); // TODO check this preOpcodeCalleeSnapshot = canonical(hub, calleeAddress); @@ -171,11 +173,15 @@ public CallSection(Hub hub) { // The CALL is now unexceptional checkArgument(Exceptions.none(exceptions)); - hub.currentFrame().childSpanningSection(this); + currentFrame.childSpanningSection(this); + + final boolean callCanTransferValue = currentFrame.opCode().callCanTransferValue(); + currentFrame.returnDataTargetInCaller( + returnDataMemorySpan(currentFrame.frame(), callCanTransferValue)); value = - hub.opCode().callCanTransferValue() - ? Wei.of(hub.messageFrame().getStackItem(2).toUnsignedBigInteger()) + callCanTransferValue + ? Wei.of(currentFrame.frame().getStackItem(2).toUnsignedBigInteger()) : Wei.ZERO; final CallOobCall oobCall = new CallOobCall(); @@ -184,7 +190,7 @@ public CallSection(Hub hub) { final boolean aborts = hub.pch().abortingConditions().any(); checkArgument(oobCall.isAbortingCondition() == aborts); - hub.defers().scheduleForPostRollback(this, hub.currentFrame()); + hub.defers().scheduleForPostRollback(this, currentFrame); hub.defers().scheduleForPostTransaction(this); if (aborts) { @@ -195,8 +201,8 @@ public CallSection(Hub hub) { // The CALL is now unexceptional and un-aborted hub.defers().scheduleForImmediateContextEntry(this); - hub.defers().scheduleForContextReEntry(this, hub.currentFrame()); - final WorldUpdater world = hub.messageFrame().getWorldUpdater(); + hub.defers().scheduleForContextReEntry(this, currentFrame); + final WorldUpdater world = currentFrame.frame().getWorldUpdater(); if (isPrecompile(calleeAddress)) { precompileAddress = Optional.of(calleeAddress); @@ -225,7 +231,7 @@ public CallSection(Hub hub) { finalContextFragment = ContextFragment.initializeNewExecutionContext(hub); final boolean isSelfCall = callerAddress.equals(calleeAddress); selfCallWithNonzeroValueTransfer = isSelfCall && !value.isZero(); - hub.romLex().callRomLex(hub.currentFrame().frame()); + hub.romLex().callRomLex(currentFrame.frame()); hub.defers().scheduleForContextExit(this, hub.callStack().futureId()); } @@ -580,4 +586,16 @@ private void emptyCodeFirstCoupleOfAccountFragments(final Hub hub) { this.addFragments(firstCallerAccountFragment, firstCalleeAccountFragment); } + + private MemorySpan returnDataMemorySpan(MessageFrame currentFrame, boolean callCanTransferValue) { + final int returnDataOffset = + callCanTransferValue + ? currentFrame.getStackItem(5).toInt() + : currentFrame.getStackItem(4).toInt(); + final int returnDataLength = + callCanTransferValue + ? currentFrame.getStackItem(6).toInt() + : currentFrame.getStackItem(5).toInt(); + return MemorySpan.fromStartLength(returnDataOffset, returnDataLength); + } } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/call/precompileSubsection/ModexpSubsection.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/call/precompileSubsection/ModexpSubsection.java index a95f7d3fb5..8e8bd305ca 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/call/precompileSubsection/ModexpSubsection.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/call/precompileSubsection/ModexpSubsection.java @@ -16,6 +16,7 @@ package net.consensys.linea.zktracer.module.hub.section.call.precompileSubsection; import static com.google.common.base.Preconditions.*; +import static net.consensys.linea.zktracer.module.blake2fmodexpdata.BlakeModexpDataOperation.MODEXP_COMPONENT_BYTE_SIZE; import static net.consensys.linea.zktracer.module.hub.fragment.imc.mmu.MmuCall.forModexpExtractBase; import static net.consensys.linea.zktracer.module.hub.fragment.imc.mmu.MmuCall.forModexpExtractBbs; import static net.consensys.linea.zktracer.module.hub.fragment.imc.mmu.MmuCall.forModexpExtractEbs; @@ -29,7 +30,6 @@ import static net.consensys.linea.zktracer.module.hub.fragment.imc.oob.precompiles.ModexpXbsCase.OOB_INST_MODEXP_EBS; import static net.consensys.linea.zktracer.module.hub.fragment.imc.oob.precompiles.ModexpXbsCase.OOB_INST_MODEXP_MBS; import static net.consensys.linea.zktracer.module.hub.fragment.scenario.PrecompileScenarioFragment.PrecompileScenario.PRC_FAILURE_KNOWN_TO_RAM; -import static net.consensys.linea.zktracer.module.limits.precompiles.ModexpEffectiveCall.PROVER_MAX_INPUT_BYTE_SIZE; import java.math.BigInteger; @@ -60,17 +60,17 @@ public ModexpSubsection(final Hub hub, final CallSection callSection) { if (modexpMetaData .bbs() .toUnsignedBigInteger() - .compareTo(BigInteger.valueOf(PROVER_MAX_INPUT_BYTE_SIZE)) + .compareTo(BigInteger.valueOf(MODEXP_COMPONENT_BYTE_SIZE)) >= 0 || modexpMetaData .mbs() .toUnsignedBigInteger() - .compareTo(BigInteger.valueOf(PROVER_MAX_INPUT_BYTE_SIZE)) + .compareTo(BigInteger.valueOf(MODEXP_COMPONENT_BYTE_SIZE)) >= 0 || modexpMetaData .ebs() .toUnsignedBigInteger() - .compareTo(BigInteger.valueOf(PROVER_MAX_INPUT_BYTE_SIZE)) + .compareTo(BigInteger.valueOf(MODEXP_COMPONENT_BYTE_SIZE)) >= 0) { hub.modexpEffectiveCall().addPrecompileLimit(Integer.MAX_VALUE); hub.defers().unscheduleForContextReEntry(this, hub.currentFrame()); @@ -145,7 +145,7 @@ public void resolveAtContextReEntry(Hub hub, CallFrame callFrame) { } modexpMetaData.rawResult(returnData); - hub.blakeModexpData().callModexp(modexpMetaData, this.exoModuleOperationId()); + hub.blakeModexpData().callModexp(modexpMetaData, exoModuleOperationId()); fragments().add(seventhImcFragment); if (modexpMetaData.extractModulus()) { diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/copy/CodeCopySection.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/copy/CodeCopySection.java index c56f8b7dbc..abe1df070e 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/copy/CodeCopySection.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/copy/CodeCopySection.java @@ -28,9 +28,6 @@ import net.consensys.linea.zktracer.module.hub.fragment.imc.mmu.MmuCall; import net.consensys.linea.zktracer.module.hub.section.TraceSection; import net.consensys.linea.zktracer.module.hub.signals.Exceptions; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.evm.account.Account; -import org.hyperledger.besu.evm.frame.MessageFrame; public class CodeCopySection extends TraceSection { @@ -66,19 +63,9 @@ public CodeCopySection(Hub hub) { this.addFragment(contextFragment); // Account row - final MessageFrame frame = hub.messageFrame(); - final Address codeAddress = frame.getContractAddress(); - final Account codeAccount = frame.getWorldUpdater().get(codeAddress); - - final boolean warmth = frame.isAddressWarm(codeAddress); - checkArgument(warmth); - final AccountSnapshot codeAccountSnapshot = - AccountSnapshot.fromAccount( - codeAccount, - warmth, - hub.deploymentNumberOf(codeAddress), - hub.deploymentStatusOf(codeAddress)); + AccountSnapshot.canonical(hub, hub.messageFrame().getContractAddress()); + checkArgument(codeAccountSnapshot.isWarm()); final DomSubStampsSubFragment doingDomSubStamps = DomSubStampsSubFragment.standardDomSubStamps(this.hubStamp(), 0); // Specifics for CODECOPY @@ -94,7 +81,7 @@ public CodeCopySection(Hub hub) { final boolean triggerMmu = mxpCall.mayTriggerNontrivialMmuOperation; if (triggerMmu) { - MmuCall mmuCall = MmuCall.codeCopy(hub); + final MmuCall mmuCall = MmuCall.codeCopy(hub); imcFragment.callMmu(mmuCall); } } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/signals/Exceptions.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/signals/Exceptions.java index d7a20dd722..2a30c57010 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/signals/Exceptions.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/signals/Exceptions.java @@ -144,9 +144,9 @@ private static boolean isOutOfGas(MessageFrame frame, OpCode opCode, GasProjecto private static boolean isReturnDataCopyFault(final MessageFrame frame, final OpCode opCode) { if (opCode == OpCode.RETURNDATACOPY) { - long returnDataSize = frame.getReturnData().size(); - long askedOffset = clampedToLong(frame.getStackItem(1)); - long askedSize = clampedToLong(frame.getStackItem(2)); + final long returnDataSize = frame.getReturnData().size(); + final long askedOffset = clampedToLong(frame.getStackItem(1)); + final long askedSize = clampedToLong(frame.getStackItem(2)); return Words.clampedAdd(askedOffset, askedSize) > returnDataSize; } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/limits/precompiles/ModexpEffectiveCall.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/limits/precompiles/ModexpEffectiveCall.java index 231b281e2c..5189b52908 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/limits/precompiles/ModexpEffectiveCall.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/limits/precompiles/ModexpEffectiveCall.java @@ -29,7 +29,6 @@ @Accessors(fluent = true) public class ModexpEffectiveCall implements CountingOnlyModule { private final CountOnlyOperation counts = new CountOnlyOperation(); - public static final int PROVER_MAX_INPUT_BYTE_SIZE = 4096 / 8; @Override public String moduleKey() { diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmio/Mmio.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmio/Mmio.java index 917fc87ddd..114c5eaef2 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmio/Mmio.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmio/Mmio.java @@ -87,26 +87,23 @@ public void commit(List buffers) { Trace trace = new Trace(buffers); int stamp = 0; for (MmuOperation mmuOperation : mmu.operations().getAll()) { - if (mmuOperation.traceMe()) { - - final MmuData currentMmuData = mmuOperation.mmuData(); - - for (int currentMmioInstNumber = 0; - currentMmioInstNumber < currentMmuData.numberMmioInstructions(); - currentMmioInstNumber++) { - stamp++; - - final MmioInstructions mmioInstructions = - new MmioInstructions(currentMmuData, currentMmioInstNumber); - final MmioData mmioData = - mmioInstructions.compute( - currentMmuData - .mmuToMmioInstructions() - .get(currentMmioInstNumber) - .mmioInstruction()); - - trace(trace, mmioData, stamp); - } + + final MmuData currentMmuData = mmuOperation.mmuData(); + + for (int currentMmioInstNumber = 0; + currentMmioInstNumber < currentMmuData.mmuToMmioInstructions().size(); + currentMmioInstNumber++) { + + final MmioInstructions mmioInstructions = + new MmioInstructions(currentMmuData, currentMmioInstNumber); + final MmioData mmioData = + mmioInstructions.compute( + currentMmuData + .mmuToMmioInstructions() + .get(currentMmioInstNumber) + .mmioInstruction()); + + trace(trace, mmioData, ++stamp); } } } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmio/MmioData.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmio/MmioData.java index a40606e99c..11b75f46fb 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmio/MmioData.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmio/MmioData.java @@ -288,15 +288,15 @@ public void twoPartialToOne( final Bytes16 source1, final Bytes16 source2, final Bytes16 target, - final short sourceOffsetTrigger, - final short targetOffsetTrgger, + final short sourceByteOffset, + final short targetByteOffset, final short size) { for (short ct = 0; ct < LLARGE; ct++) { - bit1.add(ct, plateau(sourceOffsetTrigger, ct)); - bit2.add(ct, plateau(sourceOffsetTrigger + size - LLARGE, ct)); - bit3.add(ct, plateau(targetOffsetTrgger, ct)); - bit4.add(ct, plateau(targetOffsetTrgger + size, ct)); + bit1.add(ct, plateau(sourceByteOffset, ct)); + bit2.add(ct, plateau(sourceByteOffset + size - LLARGE, ct)); + bit3.add(ct, plateau(targetByteOffset, ct)); + bit4.add(ct, plateau(targetByteOffset + size, ct)); } acc1 = isolateSuffix(source1, bit1); diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmio/instructions/RamToRamTwoSource.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmio/instructions/RamToRamTwoSource.java index cb601c55ad..87ae8fc4f7 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmio/instructions/RamToRamTwoSource.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmio/instructions/RamToRamTwoSource.java @@ -42,7 +42,7 @@ public MmioData execute() { mmioData.indexX(0); mmioData.valA(readLimb(mmuData.sourceRamBytes(), mmioData.indexA())); - mmioData.valB(readLimb(mmuData.targetRamBytes(), mmioData.indexB())); + mmioData.valB(readLimb(mmuData.sourceRamBytes(), mmioData.indexB())); mmioData.valC(readLimb(mmuData.targetRamBytes(), mmioData.indexC())); mmioData.limb(Bytes16.ZERO); diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/Mmu.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/Mmu.java index c39bbbb5e4..1e7cb9657f 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/Mmu.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/Mmu.java @@ -15,10 +15,11 @@ package net.consensys.linea.zktracer.module.mmu; +import static com.google.common.base.Preconditions.checkState; + import java.nio.MappedByteBuffer; import java.util.List; -import com.google.common.base.Preconditions; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.experimental.Accessors; @@ -58,20 +59,16 @@ public void commit(List buffers) { int mmioStamp = 0; for (MmuOperation mmuOperation : operations.getAll()) { - Preconditions.checkState(mmuOperation.traceMe(), "Cannot compute if traceMe is false"); - if (mmuOperation.traceMe()) { - mmuOperation.getCFI(); - mmuOperation.fillLimb(); + checkState(mmuOperation.traceMe(), "Cannot compute if traceMe is false"); + mmuOperation.getCFI(); + mmuOperation.fillLimb(); - mmuStamp += 1; - mmuOperation.trace(mmuStamp, mmioStamp, trace); - mmioStamp += mmuOperation.mmuData().numberMmioInstructions(); - } + mmioStamp = mmuOperation.trace(++mmuStamp, mmioStamp, trace); } } public void call(final MmuCall mmuCall) { - Preconditions.checkState(mmuCall.traceMe(), "Shouldn't compute if traceMe is false"); + checkState(mmuCall.traceMe(), "Shouldn't compute if traceMe is false"); MmuData mmuData = new MmuData(mmuCall); mmuData.hubToMmuValues( HubToMmuValues.fromMmuCall(mmuCall, mmuData.exoLimbIsSource(), mmuData.exoLimbIsTarget())); diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/MmuData.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/MmuData.java index e9f0df7f86..87e10554b2 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/MmuData.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/MmuData.java @@ -18,6 +18,9 @@ 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_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_RAM_TO_EXO_WITH_PADDING; import java.util.ArrayList; import java.util.List; @@ -26,7 +29,6 @@ import lombok.Getter; import lombok.Setter; import lombok.experimental.Accessors; -import net.consensys.linea.zktracer.module.constants.GlobalConstants; import net.consensys.linea.zktracer.module.hub.fragment.imc.mmu.MmuCall; import net.consensys.linea.zktracer.module.mmu.values.HubToMmuValues; import net.consensys.linea.zktracer.module.mmu.values.MmuEucCallRecord; @@ -62,9 +64,9 @@ public class MmuData { private static final List MMU_INST_EXO_IS_TARGET = List.of( MMU_INST_BLAKE, - GlobalConstants.MMU_INST_MODEXP_DATA, - GlobalConstants.MMU_INST_MODEXP_ZERO, - GlobalConstants.MMU_INST_RAM_TO_EXO_WITH_PADDING); + MMU_INST_MODEXP_DATA, + MMU_INST_MODEXP_ZERO, + MMU_INST_RAM_TO_EXO_WITH_PADDING); public MmuData(final MmuCall mmuCall) { this( 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 4113ebac49..cc38b9783c 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 @@ -20,6 +20,7 @@ import static com.google.common.base.Preconditions.*; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.LLARGE; +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.MMIO_INST_LIMB_VANISHES; 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; @@ -34,6 +35,7 @@ import static net.consensys.linea.zktracer.module.constants.GlobalConstants.MMU_INST_RIGHT_PADDED_WORD_EXTRACTION; import static net.consensys.linea.zktracer.module.mmio.MmioData.lineCountOfMmioInstruction; import static net.consensys.linea.zktracer.types.Bytecodes.readBytes; +import static net.consensys.linea.zktracer.types.Bytecodes.readLimb; import static net.consensys.linea.zktracer.types.Conversions.*; import java.util.ArrayList; @@ -93,7 +95,7 @@ public int mmioLineCount() { return mmioLineCount; } - void trace(final int mmuStamp, final int mmioStamp, Trace trace) { + int trace(final int mmuStamp, final int mmioStamp, Trace trace) { setInstructionFlag(); @@ -104,7 +106,7 @@ void trace(final int mmuStamp, final int mmioStamp, Trace trace) { tracePreprocessingRows(mmuData, mmuStamp, mmioStamp, trace); // Trace Micro Instructions Rows - traceMicroRows(mmuStamp, mmioStamp, trace); + return traceMicroRows(mmuStamp, mmioStamp, trace); } private void setInstructionFlag() { @@ -159,24 +161,28 @@ public void fillLimb() { final boolean exoIsTarget = mmuData.exoLimbIsTarget(); checkArgument(exoIsSource == !exoIsTarget, "ExoLimb is either the source or the target"); - for (MmuToMmioInstruction mmioInst : this.mmuData.mmuToMmioInstructions()) { - final int offset = - (int) - (exoIsSource - ? mmioInst.sourceLimbOffset() * LLARGE + mmioInst.sourceByteOffset() - : mmioInst.targetLimbOffset() * LLARGE + mmioInst.targetByteOffset()); - final int sizeToExtract = mmioInst.size() == 0 ? LLARGE : mmioInst.size(); - final Bytes16 exoLimb = readBytes(mmuData.exoBytes(), offset, sizeToExtract); - mmioInst.limb(exoLimb); + for (MmuToMmioInstruction mmioInst : mmuData.mmuToMmioInstructions()) { + + // Limb remains zero for LIMB_VANISHES instructions + if (mmioInst.mmioInstruction() != MMIO_INST_LIMB_VANISHES) { + + if (exoIsSource) { + mmioInst.limb(readLimb(mmuData.exoBytes(), mmioInst.sourceLimbOffset())); + } else { + final int offset = + (int) mmioInst.targetLimbOffset() * LLARGE + mmioInst.targetByteOffset(); + final int sizeToExtract = mmioInst.size() == 0 ? LLARGE : mmioInst.size(); + final int exoByteOffset = mmioInst.targetByteOffset(); + final Bytes16 exoLimb = + readBytes(mmuData.exoBytes(), offset, sizeToExtract, exoByteOffset); + ; + mmioInst.limb(exoLimb); + } + } } } } - private boolean exoLimbIsSource() { - return List.of(MMU_INST_ANY_TO_RAM_WITH_PADDING, MMU_INST_EXO_TO_RAM_TRANSPLANTS) - .contains(this.mmuData.hubToMmuValues().mmuInstruction()); - } - private void traceFillMmuInstructionFlag(Trace trace) { trace .isMload(isMload) @@ -195,7 +201,7 @@ private void traceFillMmuInstructionFlag(Trace trace) { } private void traceOutAndBin(Trace trace) { - MmuOutAndBinValues mmuOutAndBinRecord = mmuData.outAndBinValues(); + final MmuOutAndBinValues mmuOutAndBinRecord = mmuData.outAndBinValues(); trace .out1(Bytes.minimalBytes(mmuOutAndBinRecord.out1())) @@ -337,7 +343,7 @@ private List generateRowTypeList() { return output; } - private void traceMicroRows(final long mmuStamp, int mmioStamp, Trace trace) { + private int traceMicroRows(final long mmuStamp, int mmioStamp, Trace trace) { final List rowType = generateRowTypeList(); final HubToMmuValues mmuHubInput = mmuData.hubToMmuValues(); @@ -345,7 +351,7 @@ private void traceMicroRows(final long mmuStamp, int mmioStamp, Trace trace) { final MmuToMmioConstantValues mmioConstantValues = mmuData.mmuToMmioConstantValues(); - for (int i = 0; i < mmuData().numberMmioInstructions(); i++) { + for (int i = 0; i < mmuData().mmuToMmioInstructions().size(); i++) { mmioStamp += 1; traceFillMmuInstructionFlag(trace); traceOutAndBin(trace); @@ -390,5 +396,6 @@ private void traceMicroRows(final long mmuStamp, int mmioStamp, Trace trace) { .pMicroTotalSize(Bytes.minimalBytes(mmioConstantValues.totalSize())) .fillAndValidateRow(); } + return mmioStamp; } } 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 a1f900d38e..c3c3406ef0 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 @@ -634,7 +634,7 @@ private void someDataOnlyNonTrivialInstruction(MmuData mmuData) { .targetByteOffset(minTargetByteOffset) // .limb(limb) .targetLimbIsTouchedTwice( - mmioInstNeedsUpdateTemporaryTargetRam(onlyMmioInstruction) + mmioInstTouchesTwoRamTarget(onlyMmioInstruction) || dataToPaddingTransitionTakesTwoMmioInstructions) .build()); } @@ -661,8 +661,9 @@ private void someDataFirstNonTrivialInstruction(MmuData mmuData) { .sourceByteOffset(minSourceByteOffset) .targetLimbOffset(minTargetLimbOffset) .targetByteOffset(minTargetByteOffset) - // .limb(limb) - .targetLimbIsTouchedTwice(mmioInstNeedsUpdateTemporaryTargetRam(firstMmioInstruction)) + .targetLimbIsTouchedTwice( + !targetLimbOffsetIncrementsAfterFirstDataTransfer + || mmioInstTouchesTwoRamTarget(firstMmioInstruction)) .build()); } @@ -684,7 +685,7 @@ private void someDataMiddleNonTrivialInstruction(MmuData mmuData, int rowNumber) .sourceLimbOffset(sourceLimbOffset) .targetLimbOffset(firstMiddleNonTrivialTargetLimbOffset + rowNumber - 1) .targetByteOffset(middleTargetByteOffset) - .targetLimbIsTouchedTwice(mmioInstNeedsUpdateTemporaryTargetRam(middleMmioInstruction)) + .targetLimbIsTouchedTwice(mmioInstTouchesTwoRamTarget(middleMmioInstruction)) .build()); } @@ -710,7 +711,7 @@ private void someDataLastNonTrivialInstruction(MmuData mmuData) { .targetLimbOffset(firstMiddleNonTrivialTargetLimbOffset + totInitialNonTrivial - 2) .targetByteOffset(middleTargetByteOffset) .targetLimbIsTouchedTwice( - mmioInstNeedsUpdateTemporaryTargetRam(lastMmioInstruction) + mmioInstTouchesTwoRamTarget(lastMmioInstruction) || dataToPaddingTransitionTakesTwoMmioInstructions) .build()); } @@ -742,7 +743,7 @@ private void someDataLastPaddingInstruction(MmuData mmuData) { .build()); } - private boolean mmioInstNeedsUpdateTemporaryTargetRam(int mmioInstruction) { + private boolean mmioInstTouchesTwoRamTarget(int mmioInstruction) { return mmioInstruction == MMIO_INST_RAM_TO_RAM_TWO_TARGET || mmioInstruction == MMIO_INST_LIMB_TO_RAM_TWO_TARGET; } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/InvalidCodePrefix.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/InvalidCodePrefix.java index dfa11b6405..42426d776f 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/InvalidCodePrefix.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/InvalidCodePrefix.java @@ -104,7 +104,10 @@ public MmuData setMicroInstructions(MmuData mmuData) { final HubToMmuValues hubToMmuValues = mmuData.hubToMmuValues(); mmuData.mmuToMmioConstantValues( - MmuToMmioConstantValues.builder().sourceContextNumber(hubToMmuValues.sourceId()).build()); + MmuToMmioConstantValues.builder() + .sourceContextNumber(hubToMmuValues.sourceId()) + .successBit(hubToMmuValues.successBit()) + .build()); // First and only micro-instruction. mmuData.mmuToMmioInstruction( diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/ModexpData.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/ModexpData.java index 5789a12090..486ff2f3ae 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/ModexpData.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/ModexpData.java @@ -263,7 +263,9 @@ public MmuData setMicroInstructions(MmuData mmuData) { middleMicroInstruction(mmuData, sourceLimbOffset, targetLimbOffset); } - lastMicroInstruction(mmuData); + if (initialTotalNonTrivial > 1) { + lastMicroInstruction(mmuData); + } // Right Zeroes for (int i = 0; i < initialTotalRightZeroes; i++) { diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/RamToExoWithPadding.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/RamToExoWithPadding.java index 2eb1e9cb33..b215b54048 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/RamToExoWithPadding.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mmu/instructions/RamToExoWithPadding.java @@ -147,7 +147,7 @@ private void row3(final MmuData mmuData) { final Bytes dividend = Bytes.ofUnsignedLong(extractionSize); final EucOperation eucOp = euc.callEUC(dividend, Bytes.of(LLARGE)); - Bytes quotient = eucOp.quotient(); + final Bytes quotient = eucOp.quotient(); eucCallRecords.add( MmuEucCallRecord.builder() .dividend(dividend.toLong()) diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/romlex/RomLex.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/romlex/RomLex.java index 996a13c8be..d7207e4a71 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/romlex/RomLex.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/romlex/RomLex.java @@ -36,7 +36,6 @@ import net.consensys.linea.zktracer.module.hub.Hub; import net.consensys.linea.zktracer.module.hub.defer.ContextExitDefer; import net.consensys.linea.zktracer.module.hub.defer.ImmediateContextEntryDefer; -import net.consensys.linea.zktracer.opcode.OpCode; import net.consensys.linea.zktracer.runtime.callstack.CallFrame; import net.consensys.linea.zktracer.types.TransactionProcessingMetadata; import org.apache.tuweni.bytes.Bytes; @@ -61,7 +60,7 @@ public class RomLex @Getter private List sortedOperations; Map cfiMetadataCorrespondance = new HashMap<>(); - private Bytes byteCode = Bytes.EMPTY; + @Getter private Bytes byteCode = Bytes.EMPTY; private Address address = Address.ZERO; @Getter private final DeferRegistry createDefers = new DeferRegistry(); @@ -82,7 +81,7 @@ public int getCodeFragmentIndexByMetadata(final ContractMetadata metadata) { throw new RuntimeException("Chunks have not been sorted yet"); } - Integer romOps = cfiMetadataCorrespondance.get(metadata); + final Integer romOps = cfiMetadataCorrespondance.get(metadata); if (romOps == null) { throw new RuntimeException( "RomChunk with:" @@ -108,12 +107,16 @@ public Optional getChunkByMetadata(final ContractMetadata metadata return Optional.of(c); } } - - return Optional.empty(); + throw new RuntimeException( + "RomChunk with:" + + String.format("\n\t\taddress = %s", metadata.address()) + + String.format("\n\t\tdeployment number = %s", metadata.deploymentNumber()) + + String.format("\n\t\tdeployment status = %s", metadata.underDeployment()) + + "\n\tnot found"); } public Bytes getCodeByMetadata(final ContractMetadata metadata) { - return getChunkByMetadata(metadata).map(RomOperation::byteCode).orElse(Bytes.EMPTY); + return getChunkByMetadata(metadata).map(RomOperation::byteCode).orElseThrow(); } // TODO: it would maybe make more sense to only implement traceContextEnter @@ -151,7 +154,7 @@ public void traceStartTx(WorldView worldView, TransactionProcessingMetadata txMe } public void callRomLex(final MessageFrame frame) { - switch (OpCode.of(frame.getCurrentOperation().getOpcode())) { + switch (getOpCode(frame)) { case CREATE, CREATE2 -> { final long offset = Words.clampedToLong(frame.getStackItem(1)); final long length = Words.clampedToLong(frame.getStackItem(2)); diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/runtime/callstack/CallFrame.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/runtime/callstack/CallFrame.java index 37abfa00f1..d0f4847cf7 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/runtime/callstack/CallFrame.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/runtime/callstack/CallFrame.java @@ -140,7 +140,7 @@ public void rememberGasNextBeforePausing() { @Getter @Setter private Bytes returnData = Bytes.EMPTY; /** returnData position within the latest callee memory space. */ - @Getter @Setter private MemorySpan returnDataSpan = new MemorySpan(0, 0); + @Getter @Setter private MemorySpan returnDataSpan = MemorySpan.empty(); /** the return data provided by this frame */ @Getter @Setter private Bytes outputData = Bytes.EMPTY; @@ -149,7 +149,7 @@ public void rememberGasNextBeforePausing() { @Getter @Setter private MemorySpan outputDataSpan; /** where this frame is expected to write its outputData within its parent's memory space. */ - @Getter private MemorySpan returnDataTargetInCaller = MemorySpan.empty(); + @Getter @Setter private MemorySpan returnDataTargetInCaller = MemorySpan.empty(); @Getter @Setter private boolean selfReverts = false; @Getter @Setter private boolean getsReverted = false; diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/types/Bytecode.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/types/Bytecode.java index d5c9ad76df..f916ef74be 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/types/Bytecode.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/types/Bytecode.java @@ -18,12 +18,15 @@ import java.util.Objects; import java.util.concurrent.*; +import lombok.Getter; +import lombok.experimental.Accessors; import lombok.extern.slf4j.Slf4j; import org.apache.tuweni.bytes.Bytes; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.evm.Code; @Slf4j +@Accessors(fluent = true) /** This class is intended to store a bytecode and its memoized hash. */ public final class Bytecode { /** initializing the executor service before creating the EMPTY bytecode. */ @@ -33,7 +36,7 @@ public final class Bytecode { public static Bytecode EMPTY = new Bytecode(Bytes.EMPTY); /** The bytecode. */ - private final Bytes bytecode; + @Getter private final Bytes bytecode; /** The bytecode hash; precomputed & memoized asynchronously. */ private Future hash; @@ -67,15 +70,6 @@ public int getSize() { return this.bytecode.size(); } - /** - * Expose the wrapped bytecode as {@link Bytes}. - * - * @return the bytecode - */ - public Bytes getBytes() { - return this.bytecode; - } - /** * Returns whether the bytecode is empty or not. * diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/types/Bytecodes.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/types/Bytecodes.java index 28973a6c61..fb49bbbfea 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/types/Bytecodes.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/types/Bytecodes.java @@ -15,22 +15,27 @@ package net.consensys.linea.zktracer.types; -import net.consensys.linea.zktracer.module.constants.GlobalConstants; +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.LLARGE; +import static net.consensys.linea.zktracer.types.Utils.rightPadTo; + import org.apache.tuweni.bytes.Bytes; public class Bytecodes { - public static Bytes16 readBytes(final Bytes data, final long offset, final int sizeToRead) { - if (offset >= data.size()) { + public static Bytes16 readBytes( + final Bytes data, final long sourceOffset, final int size, final int exoByteOffset) { + if (sourceOffset >= data.size()) { return Bytes16.ZERO; } - final long dataLengthToExtract = Math.min(sizeToRead, data.size() - offset); + final long dataLengthToExtract = Math.min(size, data.size() - sourceOffset); - return Bytes16.rightPad(data.slice((int) offset, (int) dataLengthToExtract)); + return Bytes16.leftPad( + rightPadTo( + data.slice((int) sourceOffset, (int) dataLengthToExtract), LLARGE - exoByteOffset)); } public static Bytes16 readLimb(final Bytes data, final long limbOffset) { - return readBytes(data, GlobalConstants.LLARGE * limbOffset, GlobalConstants.LLARGE); + return readBytes(data, LLARGE * limbOffset, LLARGE, 0); } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/module/precompiles/PrecompileTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/module/precompiles/PrecompileTests.java deleted file mode 100644 index 95d07f6001..0000000000 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/module/precompiles/PrecompileTests.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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.module.precompiles; - -public class PrecompileTests {} diff --git a/linea-constraints b/linea-constraints index f0572d9e9e..cbfd838c14 160000 --- a/linea-constraints +++ b/linea-constraints @@ -1 +1 @@ -Subproject commit f0572d9e9e7515034a8ffea5c32e36e14528d685 +Subproject commit cbfd838c14123c5cf537efd2bb1d9fbd33611ce3 diff --git a/testing/src/main/java/net/consensys/linea/testing/ExecutionEnvironment.java b/testing/src/main/java/net/consensys/linea/testing/ExecutionEnvironment.java index 4cf483da81..9ab41fa3aa 100644 --- a/testing/src/main/java/net/consensys/linea/testing/ExecutionEnvironment.java +++ b/testing/src/main/java/net/consensys/linea/testing/ExecutionEnvironment.java @@ -73,14 +73,6 @@ public static void checkTracer( } catch (IOException e) { throw new RuntimeException(e); } finally { - if (traceFilePath != null) { - if (System.getenv("PRESERVE_TRACE_FILES") == null) { - boolean traceFileDeleted = traceFilePath.toFile().delete(); - final Path finalTraceFilePath = traceFilePath; - logger.ifPresent( - log -> log.debug("trace file {} deleted {}", finalTraceFilePath, traceFileDeleted)); - } - } } }