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

fix: implemented update to TXN_DATA #1318

Merged
merged 4 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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 @@ -63,7 +63,7 @@ public static TxnDataComparisonRecord callToLeq(
.build();
}

public static TxnDataComparisonRecord callToIsZero(final Bytes arg1, final boolean result) {
public static TxnDataComparisonRecord callToIszero(final Bytes arg1, final boolean result) {
return TxnDataComparisonRecord.builder()
.wcpFlag(true)
.eucFlag(false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import static net.consensys.linea.zktracer.types.AddressUtils.lowPart;
import static net.consensys.linea.zktracer.types.Conversions.bigIntegerToBytes;
import static net.consensys.linea.zktracer.types.Conversions.booleanToInt;
import static org.web3j.crypto.transaction.type.TransactionType.EIP1559;

import java.math.BigInteger;
import java.util.ArrayList;
Expand All @@ -61,7 +62,7 @@ public class TxndataOperation extends ModuleOperation {
private static final Bytes EIP_2681_MAX_NONCE = Bytes.minimalBytes(EIP2681_MAX_NONCE);
private static final int N_ROWS_TX_MAX =
Math.max(Math.max(NB_ROWS_TYPE_0, NB_ROWS_TYPE_1), NB_ROWS_TYPE_2);
private static final int NB_WCP_EUC_ROWS_FRONTIER_ACCESS_LIST = 6;
private static final int NB_WCP_EUC_ROWS_FRONTIER_ACCESS_LIST = 7;
private final List<TxnDataComparisonRecord> callsToEucAndWcp = new ArrayList<>(N_ROWS_TX_MAX);
private final ArrayList<RlptxnOutgoing> valuesToRlptxn = new ArrayList<>(N_ROWS_TX_MAX);
private final ArrayList<RlptxrcptOutgoing> valuesToRlpTxrcpt = new ArrayList<>(N_ROWS_TX_MAX);
Expand All @@ -75,47 +76,61 @@ public TxndataOperation(Wcp wcp, Euc euc, TransactionProcessingMetadata tx) {
}

private void setCallsToEucAndWcp() {
// i + nonce_row_offset

// row 0: nonce VS. EIP-2681 max nonce
final Bytes nonce = Bytes.minimalBytes(tx.getBesuTransaction().getNonce());
wcp.callLT(nonce, EIP_2681_MAX_NONCE);
callsToEucAndWcp.add(TxnDataComparisonRecord.callToLt(nonce, EIP_2681_MAX_NONCE, true));

// i + initial_balance_row_offset
final Bytes initBalance = bigIntegerToBytes(tx.getInitialBalance());
// row 1: initial balance covers the upfront wei cost
final Bytes initialBalance = bigIntegerToBytes(tx.getInitialBalance());
final BigInteger value = tx.getBesuTransaction().getValue().getAsBigInteger();
final Bytes row0arg2 =
final Bytes upfrontWeiCost =
bigIntegerToBytes(
value.add(
outgoingLowRow6()
.multiply(BigInteger.valueOf(tx.getBesuTransaction().getGasLimit()))));
wcp.callLT(initBalance, row0arg2);
callsToEucAndWcp.add(TxnDataComparisonRecord.callToLt(initBalance, row0arg2, false));
wcp.callLEQ(upfrontWeiCost, initialBalance);
callsToEucAndWcp.add(TxnDataComparisonRecord.callToLeq(upfrontWeiCost, initialBalance, true));

// i + sufficient_gas_row_offset
final Bytes row1arg1 = Bytes.minimalBytes(tx.getBesuTransaction().getGasLimit());
final Bytes row1arg2 = Bytes.minimalBytes(tx.getUpfrontGasCost());
wcp.callLT(row1arg1, row1arg2);
callsToEucAndWcp.add(TxnDataComparisonRecord.callToLt(row1arg1, row1arg2, false));
// row 2: gasLimit covers the upfront gas cost
final Bytes gasLimit = Bytes.minimalBytes(tx.getBesuTransaction().getGasLimit());
final Bytes upfrontGasCost = Bytes.minimalBytes(tx.getUpfrontGasCost());
wcp.callLEQ(upfrontGasCost, gasLimit);
callsToEucAndWcp.add(TxnDataComparisonRecord.callToLeq(upfrontGasCost, gasLimit, true));

// i + upper_limit_refunds_row_offset
final Bytes row2arg1 =
// row 3: computing upper limit for refunds
final Bytes gasConsumedByTransactionExecution =
Bytes.minimalBytes(tx.getBesuTransaction().getGasLimit() - tx.getLeftoverGas());
final Bytes row2arg2 = Bytes.of(MAX_REFUND_QUOTIENT);
final Bytes refundLimit = euc.callEUC(row2arg1, row2arg2).quotient();
callsToEucAndWcp.add(TxnDataComparisonRecord.callToEuc(row2arg1, row2arg2, refundLimit));

// i + effective_refund_row_offset
final Bytes refundCounterMax = Bytes.minimalBytes(tx.getRefundCounterMax());
final boolean getFullRefund = wcp.callLT(refundCounterMax, refundLimit);
final Bytes maxRefundQuotient = Bytes.of(MAX_REFUND_QUOTIENT);
final Bytes refundLimit =
euc.callEUC(gasConsumedByTransactionExecution, maxRefundQuotient).quotient();
callsToEucAndWcp.add(
TxnDataComparisonRecord.callToLt(refundCounterMax, refundLimit, getFullRefund));
TxnDataComparisonRecord.callToEuc(
gasConsumedByTransactionExecution, maxRefundQuotient, refundLimit));

// i + detecting_empty_call_data_row_offset
final Bytes row4arg1 = Bytes.minimalBytes(tx.getBesuTransaction().getPayload().size());
final boolean nonZeroDataSize = wcp.callISZERO(row4arg1);
callsToEucAndWcp.add(TxnDataComparisonRecord.callToIsZero(row4arg1, nonZeroDataSize));
// row 4: comparing accrued refunds to the upper limit of refunds
final Bytes accruedRefunds = Bytes.minimalBytes(tx.getRefundCounterMax());
final boolean getFullRefund = wcp.callLT(accruedRefunds, refundLimit);
callsToEucAndWcp.add(
TxnDataComparisonRecord.callToLt(accruedRefunds, refundLimit, getFullRefund));

// row 5: detecting empty payload
final Bytes payloadSize = Bytes.minimalBytes(tx.getBesuTransaction().getPayload().size());
final boolean payloadIsEmpty = wcp.callISZERO(payloadSize);
callsToEucAndWcp.add(TxnDataComparisonRecord.callToIszero(payloadSize, payloadIsEmpty));

// row 6: comparing the maximal gas price against the base fee
TransactionType type = tx.getBesuTransaction().getType();
final Bytes baseFee = Bytes.minimalBytes(tx.getBaseFee());
if (type == TransactionType.FRONTIER || type == TransactionType.ACCESS_LIST) {
Bytes gasPriceBytes =
bigIntegerToBytes(tx.getBesuTransaction().getGasPrice().get().getAsBigInteger());
wcp.callLEQ(baseFee, gasPriceBytes);
callsToEucAndWcp.add(TxnDataComparisonRecord.callToLeq(baseFee, gasPriceBytes, true));
}

switch (tx.getBesuTransaction().getType()) {
switch (type) {
case FRONTIER -> {
for (int i = NB_WCP_EUC_ROWS_FRONTIER_ACCESS_LIST; i < NB_ROWS_TYPE_0; i++) {
callsToEucAndWcp.add(TxnDataComparisonRecord.empty());
Expand All @@ -127,30 +142,28 @@ private void setCallsToEucAndWcp() {
}
}
case EIP1559 -> {
// i + max_fee_and_basefee_row_offset
final Bytes maxFee =

// row 6: comparing the maximal gas price against the base fee
final Bytes maxFeePerGas =
bigIntegerToBytes(tx.getBesuTransaction().getMaxFeePerGas().get().getAsBigInteger());
final Bytes row5arg2 = Bytes.minimalBytes(tx.getBaseFee());
wcp.callLT(maxFee, row5arg2);
callsToEucAndWcp.add(TxnDataComparisonRecord.callToLt(maxFee, row5arg2, false));

// i + maxfee_and_max_priority_fee_row_offset
final Bytes row6arg2 =
bigIntegerToBytes(
tx.getBesuTransaction().getMaxPriorityFeePerGas().get().getAsBigInteger());
wcp.callLT(maxFee, row6arg2);
callsToEucAndWcp.add(TxnDataComparisonRecord.callToLt(maxFee, row6arg2, false));

// i + computing_effective_gas_price_row_offset
final Bytes row7arg2 =
bigIntegerToBytes(
tx.getBesuTransaction()
.getMaxPriorityFeePerGas()
.get()
.getAsBigInteger()
.add(BigInteger.valueOf(tx.getBaseFee())));
final boolean result = wcp.callLT(maxFee, row7arg2);
callsToEucAndWcp.add(TxnDataComparisonRecord.callToLt(maxFee, row7arg2, result));
wcp.callLEQ(baseFee, maxFeePerGas);
callsToEucAndWcp.add(TxnDataComparisonRecord.callToLeq(baseFee, maxFeePerGas, true));

// row 7: comparing max fee to the max priority fee
final BigInteger maxPriorityFeePerGas =
tx.getBesuTransaction().getMaxPriorityFeePerGas().get().getAsBigInteger();
wcp.callLEQ(bigIntegerToBytes(maxPriorityFeePerGas), maxFeePerGas);
callsToEucAndWcp.add(
TxnDataComparisonRecord.callToLeq(
bigIntegerToBytes(maxPriorityFeePerGas), maxFeePerGas, true));

// row 8: computing the effective gas price
final Bytes maxPriorityFeePerGasPlusBaseFee =
bigIntegerToBytes(maxPriorityFeePerGas.add(BigInteger.valueOf(tx.getBaseFee())));
final boolean getFullTip = wcp.callLEQ(maxPriorityFeePerGasPlusBaseFee, maxFeePerGas);
callsToEucAndWcp.add(
TxnDataComparisonRecord.callToLeq(
maxPriorityFeePerGasPlusBaseFee, maxFeePerGas, getFullTip));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,7 @@ public long computeTotalGasUsed() {

public long feeRateForCoinbase() {
return switch (besuTransaction.getType()) {
case FRONTIER, ACCESS_LIST -> effectiveGasPrice;
case EIP1559 -> effectiveGasPrice - baseFee;
case FRONTIER, ACCESS_LIST, EIP1559 -> effectiveGasPrice - baseFee;
default -> throw new IllegalStateException(
"Transaction Type not supported: " + besuTransaction.getType());
};
Expand Down
2 changes: 1 addition & 1 deletion linea-constraints
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems it doesn't contain Consensys/linea-constraints#406 as it's not merge yet in master ? I'm surprised it passes the constraints then ...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does, see change to arithmetization/src/main/java/net/consensys/linea/zktracer/types/TransactionProcessingMetadata.java

Loading