Skip to content

Commit

Permalink
Merge branch 'arith-dev' into 1468-clean-get-rid-of-stacknbadded-stac…
Browse files Browse the repository at this point in the history
…knbremoved
  • Loading branch information
letypequividelespoubelles authored Nov 16, 2024
2 parents 93d2e80 + 44af7e6 commit d463307
Show file tree
Hide file tree
Showing 56 changed files with 1,628 additions and 402 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public void commit(List<MappedByteBuffer> buffers) {
public void resolvePostExecution(
Hub hub, MessageFrame frame, Operation.OperationResult operationResult) {
gasParameters.gasActual(BigInteger.valueOf(commonValues.gasActual));
gasParameters.gasCost(BigInteger.valueOf(commonValues.gasCost()));
gasParameters.gasCost(BigInteger.valueOf(commonValues.gasCostToTrace()));
gasParameters.xahoy(Exceptions.any(commonValues.exceptions));
gasParameters.oogx(commonValues.tracedException() == TracedException.OUT_OF_GAS_EXCEPTION);
this.operations.add(new GasOperation(gasParameters, wcp));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@ public static AccountSnapshot canonical(Hub hub, Address address) {
return canonicalSnapshot;
}

public static AccountSnapshot canonical(Hub hub, WorldView world, Address address) {
return fromArguments(
world,
address,
hub.transients.conflation().deploymentInfo(),
isAddressWarm(hub.messageFrame(), address));
}

public static AccountSnapshot canonical(
Hub hub, WorldView world, Address address, boolean warmth) {
return fromArguments(world, address, hub.transients.conflation().deploymentInfo(), warmth);
Expand Down Expand Up @@ -234,13 +242,17 @@ public AccountSnapshot setWarmthTo(boolean newWarmth) {
* @return {@code this} with nonce++
*/
public AccountSnapshot raiseNonceByOne() {
nonce(nonce + 1);
this.nonce(nonce + 1);
return this;
}

public AccountSnapshot setDeploymentInfo(Hub hub) {
return this.setDeploymentInfo(hub.transients.conflation().deploymentInfo());
}

public AccountSnapshot setDeploymentInfo(DeploymentInfo deploymentInfo) {
deploymentNumber(deploymentInfo.deploymentNumber(address));
deploymentStatus(deploymentInfo.getDeploymentStatus(address));
this.deploymentNumber(deploymentInfo.deploymentNumber(address));
this.deploymentStatus(deploymentInfo.getDeploymentStatus(address));
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ public void traceStartTransaction(final WorldView world, final Transaction tx) {

if (!transactionProcessingMetadata.requiresEvmExecution()) {
state.setProcessingPhase(TX_SKIP);
new TxSkippedSection(this, world, transactionProcessingMetadata, transients);
new TxSkipSection(this, world, transactionProcessingMetadata, transients);
} else {
if (transactionProcessingMetadata.requiresPrewarming()) {
state.setProcessingPhase(TX_WARM);
Expand Down Expand Up @@ -634,7 +634,7 @@ public void traceContextEnter(MessageFrame frame) {

final long callDataContextNumber = callStack.currentCallFrame().contextNumber();

currentFrame().rememberGasNextBeforePausing();
currentFrame().rememberGasNextBeforePausing(this);
currentFrame().pauseCurrentFrame();

MemorySpan returnDataTargetInCaller =
Expand Down Expand Up @@ -690,16 +690,17 @@ public void traceContextExit(MessageFrame frame) {
coinbaseIsWarm,
txStack.getAccumulativeGasUsedInBlockBeforeTxStart());

if (state.getProcessingPhase() != TX_SKIP) {
state.setProcessingPhase(TX_FINL);
new TxFinalizationSection(this, frame.getWorldUpdater());
if (state.getProcessingPhase() != TX_SKIP
&& frame.getState() == MessageFrame.State.COMPLETED_SUCCESS) {
this.state.setProcessingPhase(TX_FINL);
new TxFinalizationSection(this, frame.getWorldUpdater(), false);
}
}

defers.resolveUponContextExit(this, this.currentFrame());
// TODO: verify me please @Olivier
if (this.currentFrame().opCode() == REVERT || Exceptions.any(pch.exceptions())) {
defers.resolvePostRollback(this, frame, this.currentFrame());
defers.resolveUponRollback(this, frame, this.currentFrame());
}

if (frame.getDepth() > 0) {
Expand Down Expand Up @@ -740,7 +741,7 @@ public void tracePostExecution(MessageFrame frame, Operation.OperationResult ope
*/
if (isExceptional()) {
this.currentTraceSection()
.addFragments(ContextFragment.executionProvidesEmptyReturnData(this));
.exceptionalContextFragment(ContextFragment.executionProvidesEmptyReturnData(this));
this.squashCurrentFrameOutputData();
this.squashParentFrameReturnData();
}
Expand All @@ -750,6 +751,11 @@ public void tracePostExecution(MessageFrame frame, Operation.OperationResult ope
if (!this.currentFrame().opCode().isCall() && !this.currentFrame().opCode().isCreate()) {
this.unlatchStack(frame, currentSection);
}

if (frame.getDepth() == 0 && (isExceptional() || opCode() == REVERT)) {
this.state.setProcessingPhase(TX_FINL);
new TxFinalizationSection(this, frame.getWorldUpdater(), true);
}
}

/**
Expand All @@ -771,6 +777,7 @@ private void compareLineaAndBesuGasCosts(
currentSection.commonValues.gasCostExcluduingDeploymentCost();

if (operationResult.getHaltReason() != null) {

return;
}

Expand Down Expand Up @@ -801,11 +808,6 @@ public boolean isExceptional() {
return !isUnexceptional();
}

public boolean raisesOogxOrIsUnexceptional() {
return currentTraceSection().commonValues.tracedException() == OUT_OF_GAS_EXCEPTION
|| isUnexceptional();
}

/**
* If the current execution context is a deployment context the present method "exits" that
* deployment in the sense that it updates the relevant deployment information.
Expand Down Expand Up @@ -1101,7 +1103,8 @@ void traceOpcode(MessageFrame frame) {

case CREATE -> new CreateSection(this);

case CALL -> new CallSection(this);
case CALL -> new CallSection(this, frame);

case INVALID -> new EarlyExceptionSection(this);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
import java.util.List;

import lombok.Getter;
import lombok.Setter;
import net.consensys.linea.zktracer.container.StackedContainer;
import net.consensys.linea.zktracer.module.hub.section.TxInitializationSection;
import net.consensys.linea.zktracer.module.hub.transients.Block;
import net.consensys.linea.zktracer.types.TransactionProcessingMetadata;
import org.hyperledger.besu.datatypes.Transaction;
Expand All @@ -31,6 +33,7 @@ public class TransactionStack implements StackedContainer {
new ArrayList<>(200); // TODO: write the allocated memory from .toml file
private int currentAbsNumber;
private int relativeTransactionNumber;
@Setter @Getter public TxInitializationSection initializationSection;

public TransactionProcessingMetadata current() {
return transactions.getLast();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ public boolean isEmpty() {
* @param section the section to append
*/
public void add(TraceSection section) {
section.parentTrace(this);
// Link the current section with the previous and next one
final TraceSection previousSection = this.trace.isEmpty() ? null : this.trace.getLast();
if (previousSection != null) {
Expand Down Expand Up @@ -112,6 +111,7 @@ public void commit(Trace hubTrace) {
public int lineCount() {
int lineCount = 0;
for (TraceSection s : trace) {
if (s.exceptionalContextFragment != null) s.fragments().add(s.exceptionalContextFragment);
lineCount += s.fragments().size();
}
return lineCount;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,22 +169,22 @@ public void resolvePostExecution(Hub hub, MessageFrame frame, Operation.Operatio
* for the rollback.
*/
@Override
public void resolvePostRollback(
public void resolveUponRollback(
final Hub hub, final MessageFrame messageFrame, CallFrame currentCallFrame) {

Optional.ofNullable(hub.defers().rollbackDefers.get(currentCallFrame))
.ifPresent(
defers -> {
defers.forEach(
defer -> defer.resolvePostRollback(hub, messageFrame, currentCallFrame));
defer -> defer.resolveUponRollback(hub, messageFrame, currentCallFrame));
defers.clear();
});

// recursively roll back child call frames
final CallStack callStack = hub.callStack();
currentCallFrame.childFramesId().stream()
.map(callStack::getById)
.forEach(childCallFrame -> resolvePostRollback(hub, messageFrame, childCallFrame));
.forEach(childCallFrame -> resolveUponRollback(hub, messageFrame, childCallFrame));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@ public interface PostRollbackDefer {
* @param messageFrame access point to world state & accrued state
* @param callFrame reference to call frame whose actions are to be undone
*/
public void resolvePostRollback(Hub hub, MessageFrame messageFrame, CallFrame callFrame);
public void resolveUponRollback(Hub hub, MessageFrame messageFrame, CallFrame callFrame);
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public static ContextFragment executionProvidesEmptyReturnData(final Hub hub) {

public static ContextFragment executionProvidesEmptyReturnData(final Hub hub, int contextNumber) {
CallStack callStack = hub.callStack();
int parentId = callStack.getByContextNumber(contextNumber).callerId();
int parentId = callStack.getByContextNumber(contextNumber).parentId();
return new ContextFragment(
hub, callStack, Either.left(parentId), contextNumber, MemorySpan.empty(), true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,13 @@ private StackFragment(
this.opCode = stack.getCurrentOpcodeData().mnemonic();
this.hashInfoFlag =
switch (this.opCode) {
case SHA3 -> Exceptions.none(exceptions) && gp.messageSize() > 0;
case RETURN -> Exceptions.none(exceptions) && gp.messageSize() > 0 && isDeploying;
case CREATE2 -> Exceptions.none(exceptions) && aborts.none() && gp.messageSize() > 0;
default -> false;
};
case SHA3 -> true;
case RETURN -> isDeploying;
case CREATE2 -> aborts.none();
default -> false;
}
&& Exceptions.none(exceptions)
&& gp.messageSize() > 0;
if (this.hashInfoFlag) {
Bytes memorySegmentToHash;
switch (this.opCode) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public Trace trace(Trace trace) {
.contextNumber(isExec ? frame.contextNumber() : 0)
.contextNumberNew(commonFragmentValues.contextNumberNew)
.callerContextNumber(
commonFragmentValues.callStack.getById(frame.callerId()).contextNumber())
commonFragmentValues.callStack.getById(frame.parentId()).contextNumber())
.contextWillRevert(frame.willRevert() && isExec)
.contextGetsReverted(frame.getsReverted() && isExec)
.contextSelfReverts(frame.selfReverts() && isExec)
Expand All @@ -114,7 +114,7 @@ public Trace trace(Trace trace) {
// peeking flags are traced in the respective fragments
.gasExpected(Bytes.ofUnsignedLong(commonFragmentValues.gasExpected))
.gasActual(Bytes.ofUnsignedLong(commonFragmentValues.gasActual))
.gasCost(gasCostToTrace())
.gasCost(Bytes.ofUnsignedLong(commonFragmentValues.gasCostToTrace()))
.gasNext(
Bytes.ofUnsignedLong(isExec && isUnexceptional() ? commonFragmentValues.gasNext : 0))
.refundCounter(commonFragmentValues.gasRefund)
Expand All @@ -125,24 +125,6 @@ public Trace trace(Trace trace) {
.counterNsr((short) nonStackRowsCounter);
}

private Bytes gasCostToTrace() {

if (commonFragmentValues.hubProcessingPhase != TX_EXEC
|| commonFragmentValues.tracedException() == TracedException.STACK_UNDERFLOW
|| commonFragmentValues.tracedException() == TracedException.STACK_OVERFLOW
|| commonFragmentValues.tracedException() == TracedException.RETURN_DATA_COPY_FAULT
|| commonFragmentValues.tracedException() == TracedException.MEMORY_EXPANSION_EXCEPTION
|| commonFragmentValues.tracedException() == TracedException.STATIC_FAULT
|| commonFragmentValues.tracedException() == TracedException.INVALID_CODE_PREFIX
|| commonFragmentValues.tracedException() == TracedException.MAX_CODE_SIZE_EXCEPTION) {
return Bytes.EMPTY;
}

// TODO @Olivier: special care for CALL's and CREATE's

return Bytes.ofUnsignedLong(commonFragmentValues.gasCost);
}

static long computeGasCost(Hub hub, WorldView world) {

switch (hub.opCodeData().instructionFamily()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import net.consensys.linea.zktracer.module.hub.signals.TracedException;
import net.consensys.linea.zktracer.opcode.InstructionFamily;
import net.consensys.linea.zktracer.opcode.OpCode;
import net.consensys.linea.zktracer.opcode.gas.projector.GasProjection;
import net.consensys.linea.zktracer.runtime.callstack.CallFrame;
import net.consensys.linea.zktracer.runtime.callstack.CallStack;
import net.consensys.linea.zktracer.types.TransactionProcessingMetadata;
Expand All @@ -60,7 +61,7 @@ public class CommonFragmentValues {
public final long gasExpected;
public final long gasActual;
@Getter final long gasCost;
final long gasNext;
@Getter @Setter long gasNext;
@Getter final long gasCostExcluduingDeploymentCost;
@Setter public long refundDelta = 0; // 0 is default Value, can be modified only by SSTORE section
@Setter public long gasRefund; // Set at commit time
Expand Down Expand Up @@ -94,7 +95,7 @@ public CommonFragmentValues(Hub hub) {
this.gasExpected = isExec ? computeGasExpected() : 0;
this.gasActual = isExec ? computeGasRemaining() : 0;
this.gasCost = isExec ? computeGasCost() : 0;
this.gasNext = isExec ? computeGasNext() : 0;
this.gasNext = isExec ? computeGasNext(exceptions) : 0;
this.gasCostExcluduingDeploymentCost = isExec ? computeGasCostExcludingDeploymentCost() : 0;

final InstructionFamily instructionFamily = hub.opCode().getData().instructionFamily();
Expand Down Expand Up @@ -204,7 +205,7 @@ static int computePcNew(final Hub hub, final int pc, boolean stackException, boo
"Instruction not covered " + opCode.getData().mnemonic() + " unable to compute pcNew.");
}

private long computeGasRemaining() {
public long computeGasRemaining() {
return hub.remainingGas();
}

Expand All @@ -230,29 +231,78 @@ private long computeGasCostExcludingDeploymentCost() {
return Hub.GAS_PROJECTOR.of(hub.messageFrame(), hub.opCode()).gasCostExcludingDeploymentCost();
}

public long computeGasNext() {

if (hub.isExceptional()) {
/**
* Returns the value of the GAS_NEXT column. For CALL's and CREATE's it returns
*
* <p><center><b>remainingGas - upfrontGasCost</b></center>
*
* <p>This initial computation has to be amended down the line to account for
*
* <p>- {@link GasProjection#stipend()} for aborted calls / EOA calls
*
* <p>- {@link GasProjection#gasPaidOutOfPocket()} when entering a <b>CALL</b>/<b>CREATE</b>
*
* <p>- precompile specific costs for PRC calls
*
* <p>The stipend is done through {@link CommonFragmentValues#collectChildStipend(Hub)}}
*
* @param exceptions
* @return
*/
public long computeGasNext(short exceptions) {

if (Exceptions.any(exceptions)) {
return 0;
}

final long gasAfterDeductingCost = computeGasRemaining() - computeGasCost();

OpCode opCode = hub.opCode();
GasProjection gasUtility = Hub.GAS_PROJECTOR.of(hub.messageFrame(), opCode);

return switch (hub.opCodeData().instructionFamily()) {
case KEC, COPY, STACK_RAM, STORAGE, LOG, HALT -> (hub.raisesOogxOrIsUnexceptional()
? gasAfterDeductingCost
: 0);
case CREATE -> gasAfterDeductingCost
- Hub.GAS_PROJECTOR.of(hub.messageFrame(), hub.opCode()).gasPaidOutOfPocket();
case CALL -> // TODO: this will not work because of 1. aborts with value transfers 2. EOA
// calls 3. precompile calls
gasAfterDeductingCost
- Hub.GAS_PROJECTOR.of(hub.messageFrame(), hub.opCode()).gasPaidOutOfPocket();
case KEC, COPY, STACK_RAM, STORAGE, LOG, HALT -> gasAfterDeductingCost;
case CREATE -> gasAfterDeductingCost;
// TODO: this is only part of the story because of
// 1. nonempty init code CREATE's where gas is paid out of pocket
case CALL -> gasAfterDeductingCost;
// TODO: this is only part of the story because of
// 1. aborts with value transfers (immediately reapStipend)
// 2. EOA calls with value transfer (immediately reapStipend)
// 3. SMC calls: gas paid out of pocket
// 4. PRC calls: gas paid out of pocket + special PRC cost + returned gas

default -> // ADD, MUL, MOD, EXT, WCP, BIN, SHF, CONTEXT, ACCOUNT, TRANSACTION, BATCH, JUMP,
// MACHINE_STATE, PUSH_POP, DUP, SWAP, INVALID
// TODO: this may not work for EXP, EXTCODEHASH, EXTCODESIZE, BALANCE as they require extra
// care for pricing because of ⒈ warmth and ⒉ log computations
gasAfterDeductingCost;
};
}

public void payGasPaidOutOfPocket(Hub hub) {
this.gasNext -= Hub.GAS_PROJECTOR.of(hub.messageFrame(), hub.opCode()).gasPaidOutOfPocket();
}

public void collectChildStipend(Hub hub) {
this.gasNext += Hub.GAS_PROJECTOR.of(hub.messageFrame(), hub.opCode()).stipend();
}

public long gasCostToTrace() {

if (hubProcessingPhase != TX_EXEC
|| tracedException() == TracedException.STACK_UNDERFLOW
|| tracedException() == TracedException.STACK_OVERFLOW
|| tracedException() == TracedException.RETURN_DATA_COPY_FAULT
|| tracedException() == TracedException.MEMORY_EXPANSION_EXCEPTION
|| tracedException() == TracedException.STATIC_FAULT
|| tracedException() == TracedException.INVALID_CODE_PREFIX
|| tracedException() == TracedException.MAX_CODE_SIZE_EXCEPTION) {
return 0;
}

// TODO @Olivier: special care for CALL's and CREATE's

return gasCost;
}
}
Loading

0 comments on commit d463307

Please sign in to comment.