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

clean: some cleaning in signals and module triggering #1293

Merged
merged 8 commits into from
Sep 24, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ default void traceContextExit(MessageFrame frame) {}

default void tracePreOpcode(MessageFrame frame) {}

default void tracePostOpcode(MessageFrame frame) {}
letypequividelespoubelles marked this conversation as resolved.
Show resolved Hide resolved

/**
* Called at the eve of a new transaction; intended to create a new modification context for the
* stacked state of the module.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

package net.consensys.linea.zktracer.module.blockhash;

import static com.google.common.base.Preconditions.checkArgument;
import static net.consensys.linea.zktracer.module.constants.GlobalConstants.BLOCKHASH_MAX_HISTORY;
import static net.consensys.linea.zktracer.module.constants.GlobalConstants.LLARGE;

Expand All @@ -29,17 +30,21 @@
import net.consensys.linea.zktracer.ColumnHeader;
import net.consensys.linea.zktracer.container.module.OperationSetModule;
import net.consensys.linea.zktracer.container.stacked.ModuleOperationStackedSet;
import net.consensys.linea.zktracer.module.hub.Hub;
import net.consensys.linea.zktracer.module.hub.defer.PostOpcodeDefer;
import net.consensys.linea.zktracer.module.wcp.Wcp;
import net.consensys.linea.zktracer.opcode.OpCode;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
import org.hyperledger.besu.evm.frame.MessageFrame;
import org.hyperledger.besu.evm.operation.Operation;
import org.hyperledger.besu.evm.worldstate.WorldView;
import org.hyperledger.besu.plugin.data.ProcessableBlockHeader;

@Getter
@Accessors(fluent = true)
public class Blockhash implements OperationSetModule<BlockhashOperation> {
public class Blockhash implements OperationSetModule<BlockhashOperation>, PostOpcodeDefer {
private final Hub hub;
private final Wcp wcp;
private final ModuleOperationStackedSet<BlockhashOperation> operations =
new ModuleOperationStackedSet<>();
Expand All @@ -58,7 +63,8 @@ public class Blockhash implements OperationSetModule<BlockhashOperation> {
private boolean lowerBound;
private boolean upperBound;

public Blockhash(Wcp wcp) {
public Blockhash(Hub hub, Wcp wcp) {
this.hub = hub;
this.wcp = wcp;
this.relativeBlock = 0;
}
Expand All @@ -70,34 +76,36 @@ public String moduleKey() {

@Override
public void traceStartBlock(final ProcessableBlockHeader processableBlockHeader) {
this.relativeBlock += 1;
this.absoluteBlockNumber = processableBlockHeader.getNumber();
relativeBlock += 1;
absoluteBlockNumber = processableBlockHeader.getNumber();
}

@Override
public void tracePreOpcode(MessageFrame frame) {
final OpCode opCode = OpCode.of(frame.getCurrentOperation().getOpcode());
if (opCode == OpCode.BLOCKHASH) {
this.opcodeArgument = Bytes32.leftPad(frame.getStackItem(0));
lowerBound =
this.wcp.callGEQ(
opcodeArgument,
Bytes.ofUnsignedLong(this.absoluteBlockNumber - BLOCKHASH_MAX_HISTORY));
upperBound = this.wcp.callLT(opcodeArgument, Bytes.ofUnsignedLong(this.absoluteBlockNumber));

/* To prove the lex order of BLOCK_NUMBER_HI/LO, we call WCP at endConflation, so we need to add rows in WCP now.
If a BLOCK_NUMBER is already called at least two times, no need for additional rows in WCP*/
final int numberOfCall = this.numberOfCall.getOrDefault(this.opcodeArgument, 0);
if (numberOfCall < 2) {
wcp.additionalRows.add(
Math.max(Math.min(LLARGE, this.opcodeArgument.trimLeadingZeros().size()), 1));
this.numberOfCall.replace(this.opcodeArgument, numberOfCall, numberOfCall + 1);
}
checkArgument(opCode == OpCode.BLOCKHASH, "Expected BLOCKHASH opcode");

opcodeArgument = Bytes32.leftPad(frame.getStackItem(0));
lowerBound =
this.wcp.callGEQ(
opcodeArgument, Bytes.ofUnsignedLong(this.absoluteBlockNumber - BLOCKHASH_MAX_HISTORY));
letypequividelespoubelles marked this conversation as resolved.
Show resolved Hide resolved
upperBound = this.wcp.callLT(opcodeArgument, Bytes.ofUnsignedLong(this.absoluteBlockNumber));

hub.defers().scheduleForPostExecution(this);

/* To prove the lex order of BLOCK_NUMBER_HI/LO, we call WCP at endConflation, so we need to add rows in WCP now.
If a BLOCK_NUMBER is already called at least two times, no need for additional rows in WCP*/
final int numberOfCall = this.numberOfCall.getOrDefault(this.opcodeArgument, 0);
if (numberOfCall < 2) {
wcp.additionalRows.add(
Math.max(Math.min(LLARGE, this.opcodeArgument.trimLeadingZeros().size()), 1));
this.numberOfCall.replace(this.opcodeArgument, numberOfCall, numberOfCall + 1);
}
}

@Override
public void tracePostOpcode(MessageFrame frame) {
public void resolvePostExecution(
Hub hub, MessageFrame frame, Operation.OperationResult operationResult) {
final OpCode opCode = OpCode.of(frame.getCurrentOperation().getOpcode());
if (opCode == OpCode.BLOCKHASH) {
final Bytes32 result = Bytes32.leftPad(frame.getStackItem(0));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ public int lineCount() {

private final Add add = new Add();
private final Bin bin = new Bin();
private final Blockhash blockhash = new Blockhash(wcp);
private final Blockhash blockhash = new Blockhash(this, wcp);
private final Euc euc = new Euc(wcp);
@Getter private final Ext ext = new Ext(this);
private final Gas gas = new Gas();
Expand Down Expand Up @@ -829,35 +829,6 @@ public void tracePostExecution(MessageFrame frame, Operation.OperationResult ope
if (!this.currentFrame().opCode().isCall() && !this.currentFrame().opCode().isCreate()) {
this.unlatchStack(frame);
}

switch (this.opCodeData().instructionFamily()) {
case ADD -> {}
case MOD -> {}
case MUL -> {}
case EXT -> {}
case WCP -> {}
case BIN -> {}
case SHF -> {}
case KEC -> {}
case CONTEXT -> {}
case ACCOUNT -> {}
case COPY -> {}
case TRANSACTION -> {}
case BATCH -> blockhash.tracePostOpcode(frame);
case STACK_RAM -> {}
case STORAGE -> {}
case JUMP -> {}
case MACHINE_STATE -> {}
case PUSH_POP -> {}
case DUP -> {}
case SWAP -> {}
case LOG -> {}
case CREATE -> romLex.tracePostOpcode(frame);
case CALL -> {}
case HALT -> {}
case INVALID -> {}
default -> {}
}
}

public int getCfiByMetaData(
Expand All @@ -880,21 +851,17 @@ public int newChildContextNumber() {
}

public CallFrame currentFrame() {
if (this.callStack().isEmpty()) {
return CallFrame.EMPTY;
}
return callStack.currentCallFrame();
return callStack().isEmpty() ? CallFrame.EMPTY : callStack.currentCallFrame();
}

public final MessageFrame messageFrame() {
final MessageFrame frame = callStack.currentCallFrame().frame();
return frame;
return callStack.currentCallFrame().frame();
}

private void handleStack(MessageFrame frame) {
this.currentFrame()
.stack()
.processInstruction(this, frame, MULTIPLIER___STACK_HEIGHT * state.stamps().hub());
.processInstruction(this, frame, MULTIPLIER___STACK_HEIGHT * stamp());
}

void triggerModules(MessageFrame frame) {
Expand Down Expand Up @@ -922,24 +889,6 @@ void triggerModules(MessageFrame frame) {
if (pch.signals().shf()) {
shf.tracePreOpcode(frame);
}
if (pch.signals().mxp()) {
mxp.tracePreOpcode(frame);
}
if (pch.signals().oob()) {
oob.tracePreOpcode(frame);
}
if (pch.signals().stp()) {
stp.tracePreOpcode(frame);
}
if (pch.signals().exp()) {
exp.tracePreOpcode(frame);
}
if (pch.signals().trm()) {
trm.tracePreOpcode(frame);
}
if (pch.signals().hashInfo()) {
// TODO: this.hashInfo.tracePreOpcode(frame);
}
if (pch.signals().blockhash()) {
blockhash.tracePreOpcode(frame);
}
Expand Down Expand Up @@ -1008,10 +957,8 @@ void processStateExec(MessageFrame frame) {
if (currentFrame().stack().isOk()) {
this.traceOpcode(frame);
} else {

this.squashCurrentFrameOutputData();
this.squashParentFrameReturnData();

new EarlyExceptionSection(this);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ public CreateSection(Hub hub) {
imcFragment.callMmu(mmuCall);
}

this.finalContextFragment = ContextFragment.initializeNewExecutionContext(hub);
finalContextFragment = ContextFragment.initializeNewExecutionContext(hub);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
public class PlatformController {
private final Hub hub;

// TODO: clean up extraneous signals (OOB, MXP, EXP, ...)
/** What other modules should be triggered for the current operation */
@Getter private final Signals signals;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

package net.consensys.linea.zktracer.module.hub.signals;

import java.util.Optional;
import java.util.Set;

import lombok.Getter;
Expand All @@ -24,10 +23,7 @@
import net.consensys.linea.zktracer.module.hub.Hub;
import net.consensys.linea.zktracer.opcode.InstructionFamily;
import net.consensys.linea.zktracer.opcode.OpCode;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.evm.account.AccountState;
import org.hyperledger.besu.evm.frame.MessageFrame;
import org.hyperledger.besu.evm.internal.Words;

/**
* Encodes the signals triggering other components.
Expand All @@ -38,7 +34,7 @@
@Accessors(fluent = true)
@RequiredArgsConstructor
public class Signals {
private final Set<InstructionFamily> AUTOMATIC_GAS_MODULE_TRIGGER =
private static final Set<InstructionFamily> AUTOMATIC_GAS_MODULE_TRIGGER =
Set.of(
InstructionFamily.CREATE,
InstructionFamily.CALL,
Expand All @@ -54,35 +50,23 @@ public class Signals {
@Getter private boolean wcp;
@Getter private boolean shf;

@Getter private boolean gas;
@Getter private boolean mxp;
@Getter private boolean oob;
@Getter private boolean stp;
@Getter private boolean exp;
@Getter private boolean trm;
@Getter private boolean hashInfo;
@Getter private boolean rlpAddr;
@Getter private boolean gas; // TODO: should die
@Getter private boolean rlpAddr; // TODO: should die

private final PlatformController platformController;

public void reset() {
this.add = false;
this.blockhash = false;
this.bin = false;
this.mul = false;
this.ext = false;
this.mod = false;
this.wcp = false;
this.shf = false;

this.gas = false;
this.mxp = false;
this.oob = false;
this.stp = false;
this.exp = false;
this.trm = false;
this.hashInfo = false;
this.rlpAddr = false;
add = false;
blockhash = false;
bin = false;
mul = false;
ext = false;
mod = false;
wcp = false;
shf = false;

gas = false;
rlpAddr = false;
}

public Signals snapshot() {
Expand All @@ -97,12 +81,6 @@ public Signals snapshot() {
r.shf = this.shf;

r.gas = this.gas;
r.mxp = this.mxp;
r.oob = this.oob;
r.stp = this.stp;
r.exp = this.exp;
r.trm = this.trm;
r.hashInfo = this.hashInfo;
r.rlpAddr = this.rlpAddr;

return r;
Expand All @@ -123,64 +101,20 @@ public void prepare(MessageFrame frame, PlatformController platformController, H
// this.gas coincides with CONTEXT_MAY_CHANGE
this.gas =
Exceptions.any(ex)
|| this.AUTOMATIC_GAS_MODULE_TRIGGER.contains(hub.opCodeData().instructionFamily());
|| AUTOMATIC_GAS_MODULE_TRIGGER.contains(hub.opCodeData().instructionFamily());

if (Exceptions.stackException(ex)) {
return;
}

switch (opCode) {
case CALL, DELEGATECALL, STATICCALL, CALLCODE -> {
this.mxp = !Exceptions.staticFault(ex);
this.stp = Exceptions.outOfGasException(ex) || Exceptions.none(ex);
this.oob = opCode.equals(OpCode.CALL) && Exceptions.staticFault(ex) || Exceptions.none(ex);
this.trm = Exceptions.outOfGasException(ex) || Exceptions.none(ex);

final boolean triggersAbortingCondition =
Exceptions.none(ex) && this.platformController.abortingConditions().any();

final Address target = Words.toAddress(frame.getStackItem(1));
final boolean targetAddressHasNonEmptyCode =
Optional.ofNullable(frame.getWorldUpdater().get(target))
.map(AccountState::hasCode)
.orElse(false);

this.exp =
Exceptions.none(ex)
&& this.platformController.abortingConditions().none()
&& target.equals(Address.MODEXP);
}

case REVERT -> this.mxp =
Exceptions.memoryExpansionException(ex)
|| Exceptions.outOfGasException(ex)
|| Exceptions.none(ex);

case EXP -> {
this.exp = true; // TODO: use expCall instead
this.mul = !Exceptions.outOfGasException(ex);
}

// other opcodes
case EXP, MUL -> this.mul = !Exceptions.outOfGasException(ex);
case ADD, SUB -> this.add = !Exceptions.outOfGasException(ex);
case MUL -> this.mul = !Exceptions.outOfGasException(ex);
case DIV, SDIV, MOD, SMOD -> this.mod = !Exceptions.outOfGasException(ex);
case ADDMOD, MULMOD -> this.ext = !Exceptions.outOfGasException(ex);
case LT, GT, SLT, SGT, EQ, ISZERO -> this.wcp = !Exceptions.outOfGasException(ex);
case AND, OR, XOR, NOT, SIGNEXTEND, BYTE -> this.bin = !Exceptions.outOfGasException(ex);
case SHL, SHR, SAR -> this.shf = !Exceptions.outOfGasException(ex);
case SHA3 -> {
this.mxp = true;
this.hashInfo = Exceptions.none(ex) && !frame.getStackItem(1).isZero();
OlivierBBB marked this conversation as resolved.
Show resolved Hide resolved
}
case BALANCE, EXTCODESIZE, EXTCODEHASH, SELFDESTRUCT -> this.trm = true;
case MLOAD, MSTORE, MSTORE8 -> {
this.mxp = true;
}
case CALLDATALOAD -> this.oob = true;
case SLOAD -> {}
case SSTORE, JUMP, JUMPI -> this.oob = true;
case MSIZE -> this.mxp = Exceptions.none(ex);
case BLOCKHASH -> this.blockhash = Exceptions.none(ex);
}
}
Expand Down
Loading
Loading