diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/ZkTracer.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/ZkTracer.java index 50d66dca25..1b24b6a8e9 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/ZkTracer.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/ZkTracer.java @@ -39,10 +39,7 @@ import net.consensys.linea.zktracer.types.FiniteList; import net.consensys.linea.zktracer.types.Utils; import org.apache.tuweni.bytes.Bytes; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.datatypes.PendingTransaction; -import org.hyperledger.besu.datatypes.Transaction; +import org.hyperledger.besu.datatypes.*; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.gascalculator.LondonGasCalculator; diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/ext/ExtOperation.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/ext/ExtOperation.java index 53e468f58f..cd4a04bffc 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/ext/ExtOperation.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/ext/ExtOperation.java @@ -152,132 +152,132 @@ void trace(Trace trace, int stamp) { final int accLength = i + 1; trace // Byte A and Acc A - .byteA0(UnsignedByte.of(this.aBytes.get(0).get(i))) - .byteA1(UnsignedByte.of(this.aBytes.get(1).get(i))) - .byteA2(UnsignedByte.of(this.aBytes.get(2).get(i))) - .byteA3(UnsignedByte.of(this.aBytes.get(3).get(i))) - .accA0(this.aBytes.get(0).slice(0, accLength)) - .accA1(this.aBytes.get(1).slice(0, accLength)) - .accA2(this.aBytes.get(2).slice(0, accLength)) - .accA3(this.aBytes.get(3).slice(0, accLength)) + .byteA0(UnsignedByte.of(aBytes.get(0).get(i))) + .byteA1(UnsignedByte.of(aBytes.get(1).get(i))) + .byteA2(UnsignedByte.of(aBytes.get(2).get(i))) + .byteA3(UnsignedByte.of(aBytes.get(3).get(i))) + .accA0(aBytes.get(0).slice(0, accLength)) + .accA1(aBytes.get(1).slice(0, accLength)) + .accA2(aBytes.get(2).slice(0, accLength)) + .accA3(aBytes.get(3).slice(0, accLength)) // Byte B and Acc B - .byteB0(UnsignedByte.of(this.bBytes.get(0).get(i))) - .byteB1(UnsignedByte.of(this.bBytes.get(1).get(i))) - .byteB2(UnsignedByte.of(this.bBytes.get(2).get(i))) - .byteB3(UnsignedByte.of(this.bBytes.get(3).get(i))) - .accB0(this.bBytes.get(0).slice(0, accLength)) - .accB1(this.bBytes.get(1).slice(0, accLength)) - .accB2(this.bBytes.get(2).slice(0, accLength)) - .accB3(this.bBytes.get(3).slice(0, accLength)) + .byteB0(UnsignedByte.of(bBytes.get(0).get(i))) + .byteB1(UnsignedByte.of(bBytes.get(1).get(i))) + .byteB2(UnsignedByte.of(bBytes.get(2).get(i))) + .byteB3(UnsignedByte.of(bBytes.get(3).get(i))) + .accB0(bBytes.get(0).slice(0, accLength)) + .accB1(bBytes.get(1).slice(0, accLength)) + .accB2(bBytes.get(2).slice(0, accLength)) + .accB3(bBytes.get(3).slice(0, accLength)) // Byte C and Acc C - .byteC0(UnsignedByte.of(this.cBytes.get(0).get(i))) - .byteC1(UnsignedByte.of(this.cBytes.get(1).get(i))) - .byteC2(UnsignedByte.of(this.cBytes.get(2).get(i))) - .byteC3(UnsignedByte.of(this.cBytes.get(3).get(i))) - .accC0(this.cBytes.get(0).slice(0, accLength)) - .accC1(this.cBytes.get(1).slice(0, accLength)) - .accC2(this.cBytes.get(2).slice(0, accLength)) - .accC3(this.cBytes.get(3).slice(0, accLength)) + .byteC0(UnsignedByte.of(cBytes.get(0).get(i))) + .byteC1(UnsignedByte.of(cBytes.get(1).get(i))) + .byteC2(UnsignedByte.of(cBytes.get(2).get(i))) + .byteC3(UnsignedByte.of(cBytes.get(3).get(i))) + .accC0(cBytes.get(0).slice(0, accLength)) + .accC1(cBytes.get(1).slice(0, accLength)) + .accC2(cBytes.get(2).slice(0, accLength)) + .accC3(cBytes.get(3).slice(0, accLength)) // Byte Delta and Acc Delta - .byteDelta0(UnsignedByte.of(this.deltaBytes.get(0).get(i))) - .byteDelta1(UnsignedByte.of(this.deltaBytes.get(1).get(i))) - .byteDelta2(UnsignedByte.of(this.deltaBytes.get(2).get(i))) - .byteDelta3(UnsignedByte.of(this.deltaBytes.get(3).get(i))) - .accDelta0(this.deltaBytes.get(0).slice(0, accLength)) - .accDelta1(this.deltaBytes.get(1).slice(0, accLength)) - .accDelta2(this.deltaBytes.get(2).slice(0, accLength)) - .accDelta3(this.deltaBytes.get(3).slice(0, accLength)) + .byteDelta0(UnsignedByte.of(deltaBytes.get(0).get(i))) + .byteDelta1(UnsignedByte.of(deltaBytes.get(1).get(i))) + .byteDelta2(UnsignedByte.of(deltaBytes.get(2).get(i))) + .byteDelta3(UnsignedByte.of(deltaBytes.get(3).get(i))) + .accDelta0(deltaBytes.get(0).slice(0, accLength)) + .accDelta1(deltaBytes.get(1).slice(0, accLength)) + .accDelta2(deltaBytes.get(2).slice(0, accLength)) + .accDelta3(deltaBytes.get(3).slice(0, accLength)) // Byte H and Acc H - .byteH0(UnsignedByte.of(this.hBytes.get(0).get(i))) - .byteH1(UnsignedByte.of(this.hBytes.get(1).get(i))) - .byteH2(UnsignedByte.of(this.hBytes.get(2).get(i))) - .byteH3(UnsignedByte.of(this.hBytes.get(3).get(i))) - .byteH4(UnsignedByte.of(this.hBytes.get(4).get(i))) - .byteH5(UnsignedByte.of(this.hBytes.get(5).get(i))) - .accH0(this.hBytes.get(0).slice(0, accLength)) - .accH1(this.hBytes.get(1).slice(0, accLength)) - .accH2(this.hBytes.get(2).slice(0, accLength)) - .accH3(this.hBytes.get(3).slice(0, accLength)) - .accH4(this.hBytes.get(4).slice(0, accLength)) - .accH5(this.hBytes.get(5).slice(0, accLength)) + .byteH0(UnsignedByte.of(hBytes.get(0).get(i))) + .byteH1(UnsignedByte.of(hBytes.get(1).get(i))) + .byteH2(UnsignedByte.of(hBytes.get(2).get(i))) + .byteH3(UnsignedByte.of(hBytes.get(3).get(i))) + .byteH4(UnsignedByte.of(hBytes.get(4).get(i))) + .byteH5(UnsignedByte.of(hBytes.get(5).get(i))) + .accH0(hBytes.get(0).slice(0, accLength)) + .accH1(hBytes.get(1).slice(0, accLength)) + .accH2(hBytes.get(2).slice(0, accLength)) + .accH3(hBytes.get(3).slice(0, accLength)) + .accH4(hBytes.get(4).slice(0, accLength)) + .accH5(hBytes.get(5).slice(0, accLength)) // Byte I and Acc I - .byteI0(UnsignedByte.of(this.iBytes.get(0).get(i))) - .byteI1(UnsignedByte.of(this.iBytes.get(1).get(i))) - .byteI2(UnsignedByte.of(this.iBytes.get(2).get(i))) - .byteI3(UnsignedByte.of(this.iBytes.get(3).get(i))) - .byteI4(UnsignedByte.of(this.iBytes.get(4).get(i))) - .byteI5(UnsignedByte.of(this.iBytes.get(5).get(i))) - .byteI6(UnsignedByte.of(this.iBytes.get(6).get(i))) - .accI0(this.iBytes.get(0).slice(0, accLength)) - .accI1(this.iBytes.get(1).slice(0, accLength)) - .accI2(this.iBytes.get(2).slice(0, accLength)) - .accI3(this.iBytes.get(3).slice(0, accLength)) - .accI4(this.iBytes.get(4).slice(0, accLength)) - .accI5(this.iBytes.get(5).slice(0, accLength)) - .accI6(this.iBytes.get(6).slice(0, accLength)) + .byteI0(UnsignedByte.of(iBytes.get(0).get(i))) + .byteI1(UnsignedByte.of(iBytes.get(1).get(i))) + .byteI2(UnsignedByte.of(iBytes.get(2).get(i))) + .byteI3(UnsignedByte.of(iBytes.get(3).get(i))) + .byteI4(UnsignedByte.of(iBytes.get(4).get(i))) + .byteI5(UnsignedByte.of(iBytes.get(5).get(i))) + .byteI6(UnsignedByte.of(iBytes.get(6).get(i))) + .accI0(iBytes.get(0).slice(0, accLength)) + .accI1(iBytes.get(1).slice(0, accLength)) + .accI2(iBytes.get(2).slice(0, accLength)) + .accI3(iBytes.get(3).slice(0, accLength)) + .accI4(iBytes.get(4).slice(0, accLength)) + .accI5(iBytes.get(5).slice(0, accLength)) + .accI6(iBytes.get(6).slice(0, accLength)) // Byte J and Acc J - .byteJ0(UnsignedByte.of(this.jBytes.get(0).get(i))) - .byteJ1(UnsignedByte.of(this.jBytes.get(1).get(i))) - .byteJ2(UnsignedByte.of(this.jBytes.get(2).get(i))) - .byteJ3(UnsignedByte.of(this.jBytes.get(3).get(i))) - .byteJ4(UnsignedByte.of(this.jBytes.get(4).get(i))) - .byteJ5(UnsignedByte.of(this.jBytes.get(5).get(i))) - .byteJ6(UnsignedByte.of(this.jBytes.get(6).get(i))) - .byteJ7(UnsignedByte.of(this.jBytes.get(7).get(i))) - .accJ0(this.jBytes.get(0).slice(0, accLength)) - .accJ1(this.jBytes.get(1).slice(0, accLength)) - .accJ2(this.jBytes.get(2).slice(0, accLength)) - .accJ3(this.jBytes.get(3).slice(0, accLength)) - .accJ4(this.jBytes.get(4).slice(0, accLength)) - .accJ5(this.jBytes.get(5).slice(0, accLength)) - .accJ6(this.jBytes.get(6).slice(0, accLength)) - .accJ7(this.jBytes.get(7).slice(0, accLength)) + .byteJ0(UnsignedByte.of(jBytes.get(0).get(i))) + .byteJ1(UnsignedByte.of(jBytes.get(1).get(i))) + .byteJ2(UnsignedByte.of(jBytes.get(2).get(i))) + .byteJ3(UnsignedByte.of(jBytes.get(3).get(i))) + .byteJ4(UnsignedByte.of(jBytes.get(4).get(i))) + .byteJ5(UnsignedByte.of(jBytes.get(5).get(i))) + .byteJ6(UnsignedByte.of(jBytes.get(6).get(i))) + .byteJ7(UnsignedByte.of(jBytes.get(7).get(i))) + .accJ0(jBytes.get(0).slice(0, accLength)) + .accJ1(jBytes.get(1).slice(0, accLength)) + .accJ2(jBytes.get(2).slice(0, accLength)) + .accJ3(jBytes.get(3).slice(0, accLength)) + .accJ4(jBytes.get(4).slice(0, accLength)) + .accJ5(jBytes.get(5).slice(0, accLength)) + .accJ6(jBytes.get(6).slice(0, accLength)) + .accJ7(jBytes.get(7).slice(0, accLength)) // Byte Q and Acc Q - .byteQ0(UnsignedByte.of(this.qBytes.get(0).get(i))) - .byteQ1(UnsignedByte.of(this.qBytes.get(1).get(i))) - .byteQ2(UnsignedByte.of(this.qBytes.get(2).get(i))) - .byteQ3(UnsignedByte.of(this.qBytes.get(3).get(i))) - .byteQ4(UnsignedByte.of(this.qBytes.get(4).get(i))) - .byteQ5(UnsignedByte.of(this.qBytes.get(5).get(i))) - .byteQ6(UnsignedByte.of(this.qBytes.get(6).get(i))) - .byteQ7(UnsignedByte.of(this.qBytes.get(7).get(i))) - .accQ0(this.qBytes.get(0).slice(0, accLength)) - .accQ1(this.qBytes.get(1).slice(0, accLength)) - .accQ2(this.qBytes.get(2).slice(0, accLength)) - .accQ3(this.qBytes.get(3).slice(0, accLength)) - .accQ4(this.qBytes.get(4).slice(0, accLength)) - .accQ5(this.qBytes.get(5).slice(0, accLength)) - .accQ6(this.qBytes.get(6).slice(0, accLength)) - .accQ7(this.qBytes.get(7).slice(0, accLength)) + .byteQ0(UnsignedByte.of(qBytes.get(0).get(i))) + .byteQ1(UnsignedByte.of(qBytes.get(1).get(i))) + .byteQ2(UnsignedByte.of(qBytes.get(2).get(i))) + .byteQ3(UnsignedByte.of(qBytes.get(3).get(i))) + .byteQ4(UnsignedByte.of(qBytes.get(4).get(i))) + .byteQ5(UnsignedByte.of(qBytes.get(5).get(i))) + .byteQ6(UnsignedByte.of(qBytes.get(6).get(i))) + .byteQ7(UnsignedByte.of(qBytes.get(7).get(i))) + .accQ0(qBytes.get(0).slice(0, accLength)) + .accQ1(qBytes.get(1).slice(0, accLength)) + .accQ2(qBytes.get(2).slice(0, accLength)) + .accQ3(qBytes.get(3).slice(0, accLength)) + .accQ4(qBytes.get(4).slice(0, accLength)) + .accQ5(qBytes.get(5).slice(0, accLength)) + .accQ6(qBytes.get(6).slice(0, accLength)) + .accQ7(qBytes.get(7).slice(0, accLength)) // Byte R and Acc R - .byteR0(UnsignedByte.of(this.rBytes.get(0).get(i))) - .byteR1(UnsignedByte.of(this.rBytes.get(1).get(i))) - .byteR2(UnsignedByte.of(this.rBytes.get(2).get(i))) - .byteR3(UnsignedByte.of(this.rBytes.get(3).get(i))) - .accR0(this.rBytes.get(0).slice(0, accLength)) - .accR1(this.rBytes.get(1).slice(0, accLength)) - .accR2(this.rBytes.get(2).slice(0, accLength)) - .accR3(this.rBytes.get(3).slice(0, accLength)) + .byteR0(UnsignedByte.of(rBytes.get(0).get(i))) + .byteR1(UnsignedByte.of(rBytes.get(1).get(i))) + .byteR2(UnsignedByte.of(rBytes.get(2).get(i))) + .byteR3(UnsignedByte.of(rBytes.get(3).get(i))) + .accR0(rBytes.get(0).slice(0, accLength)) + .accR1(rBytes.get(1).slice(0, accLength)) + .accR2(rBytes.get(2).slice(0, accLength)) + .accR3(rBytes.get(3).slice(0, accLength)) // other - .arg1Hi(this.arg1.getHigh()) - .arg1Lo(this.arg1.getLow()) - .arg2Hi(this.arg2.getHigh()) - .arg2Lo(this.arg2.getLow()) - .arg3Hi(this.arg3.getHigh()) - .arg3Lo(this.arg3.getLow()) - .resHi(this.result.getHigh()) - .resLo(this.result.getLow()) - .cmp(this.cmp[i]) - .ofH(this.overflowH[i]) - .ofJ(this.overflowJ[i]) - .ofI(this.overflowI[i]) - .ofRes(this.overflowRes[i]) + .arg1Hi(arg1.getHigh()) + .arg1Lo(arg1.getLow()) + .arg2Hi(arg2.getHigh()) + .arg2Lo(arg2.getLow()) + .arg3Hi(arg3.getHigh()) + .arg3Lo(arg3.getLow()) + .resHi(result.getHigh()) + .resLo(result.getLow()) + .cmp(cmp[i]) + .ofH(overflowH[i]) + .ofJ(overflowJ[i]) + .ofI(overflowI[i]) + .ofRes(overflowRes[i]) .ct(i) - .inst(UnsignedByte.of(this.opCode.byteValue())) - .oli(this.isOneLineInstruction) - .bit1(this.getBit1()) - .bit2(this.getBit2()) - .bit3(this.getBit3()) + .inst(UnsignedByte.of(opCode.byteValue())) + .oli(isOneLineInstruction) + .bit1(getBit1()) + .bit2(getBit2()) + .bit3(getBit3()) .stamp(stamp) .validateRow(); } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/TxFinalizationSection.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/TxFinalizationSection.java index 56116364ef..2ea80ebe51 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/TxFinalizationSection.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/TxFinalizationSection.java @@ -36,9 +36,9 @@ public class TxFinalizationSection extends TraceSection implements PostTransacti private final AccountSnapshot senderSnapshotBeforeFinalization; private final AccountSnapshot recipientSnapshotBeforeFinalization; private final AccountSnapshot coinbaseSnapshotBeforeTxFinalization; - private @Setter AccountSnapshot senderSnapshotAfterTxFinalization; - private @Setter AccountSnapshot recipientSnapshotAfterTxFinalization; - private @Setter AccountSnapshot coinbaseSnapshotAfterFinalization; + @Setter private AccountSnapshot senderSnapshotAfterTxFinalization; + @Setter private AccountSnapshot recipientSnapshotAfterTxFinalization; + @Setter private AccountSnapshot coinbaseSnapshotAfterFinalization; public TxFinalizationSection(Hub hub, WorldView world) { super(hub, (short) 4); @@ -53,13 +53,12 @@ public TxFinalizationSection(Hub hub, WorldView world) { recipientSnapshotBeforeFinalization = AccountSnapshot.canonical(hub, recipientAddress); coinbaseSnapshotBeforeTxFinalization = AccountSnapshot.canonical(hub, coinbaseAddress); - // TODO: re-enable checks - // checkArgument( - // senderSnapshotBeforeFinalization.isWarm(), - // "The sender account ought to be warm during TX_FINL"); - // checkArgument( - // recipientSnapshotBeforeFinalization.isWarm(), - // "The recipient account ought to be warm during TX_FINL"); + checkArgument( + senderSnapshotBeforeFinalization.isWarm(), + "The sender account ought to be warm during TX_FINL"); + checkArgument( + recipientSnapshotBeforeFinalization.isWarm(), + "The recipient account ought to be warm during TX_FINL"); checkArgument( txMetadata.isCoinbaseWarmAtTransactionEnd() == coinbaseSnapshotBeforeTxFinalization.isWarm(), diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/SelfBalanceTest.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/SelfBalanceTest.java new file mode 100644 index 0000000000..e424650253 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/SelfBalanceTest.java @@ -0,0 +1,38 @@ +/* + * 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.BytecodeCompiler; +import net.consensys.linea.testing.BytecodeRunner; +import net.consensys.linea.zktracer.opcode.OpCode; +import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.Test; + +public class SelfBalanceTest { + + @Test + void selfbalanceTest() { + final Bytes bytecode = + BytecodeCompiler.newProgram() + .op(OpCode.ORIGIN) + .op(OpCode.BALANCE) + .push("0dde8be8f613e000") + .op(OpCode.EQ) + .op(OpCode.JUMPDEST) + .compile(); + System.out.println(bytecode.toHexString()); + BytecodeRunner.of(bytecode).run(); + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/module/ext/TestDuplicatedOperations.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/module/ext/TestDuplicatedOperations.java index 79c6099d7b..a2a3a47f56 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/module/ext/TestDuplicatedOperations.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/module/ext/TestDuplicatedOperations.java @@ -24,19 +24,20 @@ import org.junit.jupiter.api.Test; public class TestDuplicatedOperations { + + Bytes maxUint256 = + Bytes.fromHexString("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + Bytes twoToThe128 = Bytes.fromHexString("0100000000000000000000000000000000"); + @Test void testDuplicate() { BytecodeRunner.of( BytecodeCompiler.newProgram() - .push( - Bytes.fromHexString( - "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")) + .push(maxUint256) .push(0) .push(0) .op(OpCode.MULMOD) - .push( - Bytes.fromHexString( - "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")) + .push(maxUint256) .push(0) .push(0) .op(OpCode.MULMOD) @@ -47,4 +48,31 @@ void testDuplicate() { }) .run(); } + + @Test + void testSimpleMulmod() { + BytecodeRunner.of( + BytecodeCompiler.newProgram() + .push(maxUint256) + .push(twoToThe128) + .push(twoToThe128) + .op(OpCode.MULMOD) + .compile()) + .run(); + } + + @Test + void testWcpVsExt() { + BytecodeRunner.of( + BytecodeCompiler.newProgram() + .push(0) + .push(1) + .op(OpCode.LT) // false + .push(maxUint256) + .push(1) + .push(maxUint256) + .op(OpCode.ADDMOD) + .compile()) + .run(); + } } diff --git a/linea-constraints b/linea-constraints index 375917ef0f..5e8250838f 160000 --- a/linea-constraints +++ b/linea-constraints @@ -1 +1 @@ -Subproject commit 375917ef0f3908e68898c67b7f47e47b3244d3ad +Subproject commit 5e8250838fb3f782a6e4eacfa1bc1b016035241c