diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/Hub.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/Hub.java index cc8d20533..4651b316e 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/Hub.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/Hub.java @@ -37,6 +37,7 @@ import java.util.stream.Stream; import lombok.Getter; +import lombok.Setter; import lombok.experimental.Accessors; import lombok.extern.slf4j.Slf4j; import net.consensys.linea.zktracer.ColumnHeader; @@ -753,6 +754,8 @@ public void tracePostExecution(MessageFrame frame, Operation.OperationResult ope } } + @Getter @Setter public long gasCostAccumulator = 0; + /** * Compares the gas costs between Linea and Besu. The total cost should be the same for both, but * it is batched/split differently. This is especially true for opcodes requiring memory @@ -771,6 +774,19 @@ private void compareLineaAndBesuGasCosts( long lineaGasCostExcludingDeploymentCost = currentSection.commonValues.gasCostExcluduingDeploymentCost(); + gasCostAccumulator += besuGasCost; + + System.out.println( + "Retrieved in the Hub: " + + "opCode: " + + opCode().name() + + " ,besuGasCost: " + + besuGasCost + + " ,OOGX: " + + (besuGasCost > frame.getRemainingGas()) + + " ,remainingGas: " + + frame.getRemainingGas()); + if (operationResult.getHaltReason() != null) { return; 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 cac3f3d74..1536aaa2c 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 @@ -141,7 +141,8 @@ private static boolean isMemoryExpansionFault( private static boolean isOutOfGas(MessageFrame frame, OpCode opCode, GasProjector gp) { final long required = gp.of(frame, opCode).upfrontGasCost(); System.out.println( - "opCode: " + "Retrieved in the Exceptions: " + + "opCode: " + opCode.name() + " ,required: " + required @@ -149,8 +150,6 @@ private static boolean isOutOfGas(MessageFrame frame, OpCode opCode, GasProjecto + (required > frame.getRemainingGas()) + " ,remainingGas: " + frame.getRemainingGas()); - GasCostSingleton gasCostSingleton = GasCostSingleton.getInstance(); - gasCostSingleton.incrementGasCost(required); return required > frame.getRemainingGas(); } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/signals/GasCostSingleton.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/signals/GasCostSingleton.java deleted file mode 100644 index 0aaebe64d..000000000 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/signals/GasCostSingleton.java +++ /dev/null @@ -1,26 +0,0 @@ -package net.consensys.linea.zktracer.module.hub.signals; - -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -public class GasCostSingleton { - private static GasCostSingleton instance; - private long gasCost = 0; - - private GasCostSingleton() { - // private constructor to prevent instantiation - } - - public void incrementGasCost(long gasCost) { - this.gasCost += gasCost; - } - - public static GasCostSingleton getInstance() { - if (instance == null) { - instance = new GasCostSingleton(); - } - return instance; - } -} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/exceptions/OutOfGasExceptionTest.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/exceptions/OutOfGasExceptionTest.java index d1f3c86da..8acacac98 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/exceptions/OutOfGasExceptionTest.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/exceptions/OutOfGasExceptionTest.java @@ -38,10 +38,8 @@ import net.consensys.linea.testing.BytecodeCompiler; import net.consensys.linea.testing.BytecodeRunner; import net.consensys.linea.testing.ToyAccount; -import net.consensys.linea.zktracer.module.hub.signals.GasCostSingleton; import net.consensys.linea.zktracer.opcode.OpCode; import net.consensys.linea.zktracer.opcode.OpCodeData; -import org.apache.tuweni.bytes.Bytes; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; import org.junit.jupiter.api.extension.ExtendWith; @@ -94,11 +92,9 @@ void outOfGasExceptionWithEmptyAccountsAndNoMemoryExpansionCostTest( + opCodeDynamicCost; bytecodeRunner.run(gasCost + cornerCase); - // TODO: understand why the gas cost is not the same as the one calculated - // if the two programs start from the same state, then the gas cost should be the same - // and we can use getGastCost to obtain the gas cost without computing it explicitly - // we may create another instance of the tracer to run programs just to estimate the gas cost - // assertEquals(gasCost, getGasCost(program.compile())); + // TODO: this is just to check if the gasCostAccumulator works + // it seems inconsistent only in the case of SSTORE at the moment + assertEquals(gasCost, GAS_CONST_G_TRANSACTION + bytecodeRunner.getHub().gasCostAccumulator()); if (cornerCase == -1) { assertEquals( @@ -235,7 +231,7 @@ void outOfGasExceptionSStore(int cornerCase) { BytecodeRunner bytecodeRunner = BytecodeRunner.of(program.compile()); - bytecodeRunner.run( + long gasCost = (long) GAS_CONST_G_TRANSACTION + (long) 2 * GAS_CONST_G_VERY_LOW // 2 PUSH + GAS_CONST_G_SSET @@ -243,8 +239,9 @@ void outOfGasExceptionSStore(int cornerCase) { // and original_value == 0 (20000) + GAS_CONST_G_COLD_SLOAD // SSTORE cost since slot is cold (2100) + (long) GAS_CONST_G_VERY_LOW // PUSH - + GAS_CONST_G_WARM_ACCESS - + cornerCase); // SLOAD (100) + + GAS_CONST_G_WARM_ACCESS; // SLOAD (100) + + bytecodeRunner.run(gasCost + cornerCase); if (cornerCase == -1) { assertEquals( @@ -256,17 +253,4 @@ void outOfGasExceptionSStore(int cornerCase) { bytecodeRunner.getHub().previousTraceSection().commonValues.tracedException()); } } - - public static long getGasCost(Bytes program) { - // Retrieve singleton instance - GasCostSingleton gasCostSingleton = GasCostSingleton.getInstance(); - // Set gas cost to 0 - gasCostSingleton.setGasCost(0); - - BytecodeRunner bytecodeRunner = BytecodeRunner.of(program); - bytecodeRunner.run(); - - // Return gas cost - return GAS_CONST_G_TRANSACTION + gasCostSingleton.getGasCost(); - } }