Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mega "simple exceptions testing" issue #1450

Open
wants to merge 7 commits into
base: arith-dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -950,10 +950,18 @@ public OpCode opCode() {
return this.currentFrame().opCode();
}

TraceSection currentTraceSection() {
public TraceSection currentTraceSection() {
return state.currentTxTrace().currentSection();
}

public TraceSection previousTraceSection() {
return state.currentTxTrace().previousSection();
}

public TraceSection previousTraceSection(int n) {
return state.currentTxTrace().previousSection(n);
}

public void addTraceSection(TraceSection section) {
state.currentTxTrace().add(section);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.util.ArrayList;
import java.util.List;

import com.google.common.base.Preconditions;
import lombok.Getter;
import lombok.experimental.Accessors;
import net.consensys.linea.zktracer.module.hub.section.TraceSection;
Expand All @@ -44,6 +45,29 @@ public TraceSection currentSection() {
return this.trace.get(this.size() - 1);
}

/**
* Returns the previous trace section, i.e., the one before the most recent.
*
* @return the previous trace section
* @throws IllegalArgumentException if there are fewer than two sections in the trace
*/
public TraceSection previousSection() {
Preconditions.checkArgument(trace.size() > 1);
return this.trace.get(this.size() - 2);
}

/**
* Returns the trace section that is `n` positions before the most recent one.
*
* @param n the number of positions before the most recent trace section
* @return the trace section that is `n` positions before the most recent one
* @throws IllegalArgumentException if there are fewer than `n + 1` sections in the trace
*/
public TraceSection previousSection(int n) {
Preconditions.checkArgument(trace.size() > n);
return this.trace.get(this.size() - 1 - n);
}

/**
* @return whether this trace is empty
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,13 @@ private static boolean isInvalidOpcode(final OpCode opCode) {
}

private static boolean isStackUnderflow(final MessageFrame frame, OpCodeData opCodeData) {
return frame.stackSize() < opCodeData.stackSettings().nbRemoved();
return frame.stackSize() < opCodeData.stackSettings().delta();
}

private static boolean isStackOverflow(final MessageFrame frame, OpCodeData opCodeData) {
return frame.stackSize()
+ opCodeData.stackSettings().nbAdded()
- opCodeData.stackSettings().nbRemoved()
- opCodeData.stackSettings().delta()
+ opCodeData.stackSettings().alpha()
> 1024;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
public class OpCodes {
private static final JsonConverter YAML_CONVERTER = JsonConverter.builder().enableYaml().build();

private static Map<Integer, OpCodeData> valueToOpCodeDataMap;
private static Map<OpCode, OpCodeData> opCodeToOpCodeDataMap;
static Map<Integer, OpCodeData> valueToOpCodeDataMap;
public static Map<OpCode, OpCodeData> opCodeToOpCodeDataMap;

static {
init();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* 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.exceptions;

import static org.junit.jupiter.api.Assertions.assertEquals;

import net.consensys.linea.testing.BytecodeCompiler;
import net.consensys.linea.testing.BytecodeRunner;
import net.consensys.linea.zktracer.module.hub.signals.TracedException;
import net.consensys.linea.zktracer.opcode.OpCode;
import org.junit.jupiter.api.Test;

public class InvalidOpcodeExceptionTest {

@Test
void invalidOpcodeExceptionTest() {
BytecodeCompiler program = BytecodeCompiler.newProgram();
program.op(OpCode.INVALID);
BytecodeRunner bytecodeRunner = BytecodeRunner.of(program.compile());
bytecodeRunner.run();
assertEquals(
TracedException.INVALID_OPCODE,
bytecodeRunner.getHub().previousTraceSection().commonValues.tracedException());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* 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.exceptions;

import static net.consensys.linea.zktracer.module.hub.signals.TracedException.OUT_OF_SSTORE;
import static org.junit.jupiter.api.Assertions.assertEquals;

import net.consensys.linea.testing.BytecodeCompiler;
import net.consensys.linea.testing.BytecodeRunner;
import net.consensys.linea.zktracer.module.constants.GlobalConstants;
import net.consensys.linea.zktracer.opcode.OpCode;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

public class OutOfSStoreExceptionTest {

@ParameterizedTest
@ValueSource(
longs = {
0,
GlobalConstants.GAS_CONST_G_CALL_STIPEND - 1,
GlobalConstants.GAS_CONST_G_CALL_STIPEND,
GlobalConstants.GAS_CONST_G_CALL_STIPEND + 1
})
void outOfSStoreExceptionTest(long remainingGasAfterPushes) {
BytecodeCompiler program = BytecodeCompiler.newProgram();

program.push(0).push(0).op(OpCode.SSTORE);
BytecodeRunner bytecodeRunner = BytecodeRunner.of(program.compile());
bytecodeRunner.run(21000L + 3L + 3L + remainingGasAfterPushes);
// 21000L is the intrinsic gas cost of a transaction and 3L is the gas cost of PUSH1

if (remainingGasAfterPushes <= GlobalConstants.GAS_CONST_G_CALL_STIPEND) {
assertEquals(
OUT_OF_SSTORE,
bytecodeRunner.getHub().previousTraceSection().commonValues.tracedException());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* 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.exceptions;

import static net.consensys.linea.zktracer.module.hub.signals.TracedException.STACK_OVERFLOW;
import static net.consensys.linea.zktracer.opcode.OpCodes.opCodeToOpCodeDataMap;
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

import net.consensys.linea.testing.BytecodeCompiler;
import net.consensys.linea.testing.BytecodeRunner;
import net.consensys.linea.zktracer.opcode.OpCode;
import net.consensys.linea.zktracer.opcode.OpCodeData;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

public class StackOverflowExceptionTest {

@ParameterizedTest
@MethodSource("stackOverflowExceptionSource")
void stackOverflowExceptionTest(OpCode opCode, int alpha, int delta) {
BytecodeCompiler program = BytecodeCompiler.newProgram();
for (int i = 0; i < 1024; i++) {
program.push(0);
}
program.op(opCode);
BytecodeRunner bytecodeRunner = BytecodeRunner.of(program.compile());
bytecodeRunner.run();

// the opcode pushes more arguments than the stack can handle

assertEquals(
STACK_OVERFLOW,
bytecodeRunner.getHub().previousTraceSection().commonValues.tracedException());
}

static Stream<Arguments> stackOverflowExceptionSource() {
List<Arguments> arguments = new ArrayList<>();
for (OpCodeData opCodeData : opCodeToOpCodeDataMap.values()) {
OpCode opCode = opCodeData.mnemonic();
int alpha = opCodeData.stackSettings().alpha(); // number of items pushed onto the stack
int delta = opCodeData.stackSettings().delta(); // number of items popped from the stack
if (alpha > delta) {
arguments.add(Arguments.of(opCode, alpha, delta));
}
}
return arguments.stream();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* 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.exceptions;

import static net.consensys.linea.zktracer.module.hub.signals.TracedException.STACK_UNDERFLOW;
import static net.consensys.linea.zktracer.opcode.OpCodes.opCodeToOpCodeDataMap;
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

import net.consensys.linea.testing.BytecodeCompiler;
import net.consensys.linea.testing.BytecodeRunner;
import net.consensys.linea.zktracer.opcode.OpCode;
import net.consensys.linea.zktracer.opcode.OpCodeData;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

public class StackUnderflowExceptionTest {

@ParameterizedTest
@MethodSource("stackUnderflowExceptionSource")
void stackUnderflowExceptionTest(
OpCode opCode, int nPushes, boolean triggersStackUnderflowExceptions) {
BytecodeCompiler program = BytecodeCompiler.newProgram();
for (int i = 0; i < nPushes; i++) {
program.push(0);
}
program.op(opCode);
BytecodeRunner bytecodeRunner = BytecodeRunner.of(program.compile());
bytecodeRunner.run();

// the number of pushed arguments is less than the number of arguments required by the opcode

if (triggersStackUnderflowExceptions) {
assertEquals(
STACK_UNDERFLOW,
bytecodeRunner.getHub().previousTraceSection().commonValues.tracedException());
}
}

static Stream<Arguments> stackUnderflowExceptionSource() {
List<Arguments> arguments = new ArrayList<>();
for (OpCodeData opCodeData : opCodeToOpCodeDataMap.values()) {
OpCode opCode = opCodeData.mnemonic();
int delta = opCodeData.stackSettings().delta(); // number of items popped from the stack
for (int nPushes = 0; nPushes <= delta; nPushes++) {
arguments.add(Arguments.of(opCode, nPushes, nPushes < delta));
}
}
return arguments.stream();
}
}
Loading
Loading