diff --git a/ac b/ac new file mode 100644 index 0000000000..8cb4910b9c --- /dev/null +++ b/ac @@ -0,0 +1,35 @@ +# SELFDESTRUCT testing + +- STATICX + - i.e. done in an execution context spawned through STATICCALL +- OOGX + - zero / nonzero balance + - warmth / cold recipient + - self recipient + - new account cost for recipient +- REVERT'ed later or not +- inside of a CREATE / deployment transaction + - leads to early deployment of empty code + - said account will be wiped off the world later + - can still have storage in the mean time + +- carried out several times in the same account, same transaction +- reverted yes or no at the end +- done indirectly (i.e. through DELEGATECALL / CALLCODE) +- interaction with storage + +More involved: +- deploying from an account MARKED_FOR_SELFDESTRUCT +- deploying with CREATE from an account MARKED_FOR_SELFDESTRUCT + +This would be to reproduce CREATE address collisions + + +# PRC calls + +- all 9 precompiles +- testing all possible success / failure paths (some extensive work was already done for EC stuff) +- in particular for gas +- testing variations on CALLDATA +- testing the output RETURNDATA +- interaction with DELEGATECALL / CALLCODE ? diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/Hub.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/Hub.java index f08447d14e..7d20516d3c 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/Hub.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/Hub.java @@ -625,7 +625,7 @@ public void traceContextEnter(MessageFrame frame) { frameType, newChildContextNumber(), this.deploymentStatusOf(frame.getContractAddress()), - frame.getValue(), + frame.getApparentValue(), frame.getRemainingGas(), frame.getRecipientAddress(), this.deploymentNumberOf(frame.getRecipientAddress()), diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/Trace.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/Trace.java index 83e6037fb0..d10c580332 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/Trace.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/Trace.java @@ -41,7 +41,7 @@ public class Trace { private final MappedByteBuffer absoluteTransactionNumber; private final MappedByteBuffer - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize; + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize; private final MappedByteBuffer addressLoXorAccountAddressLoXorExpData1XorHashInfoKeccakHiXorAddressLoXorCoinbaseAddressLo; private final MappedByteBuffer @@ -61,16 +61,16 @@ public class Trace { private final MappedByteBuffer callerContextNumber; private final MappedByteBuffer codeFragmentIndex; private final MappedByteBuffer - codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCallerGasXorDeploymentNumberXorCoinbaseAddressHi; + codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCdsXorDeploymentNumberXorCoinbaseAddressHi; private final MappedByteBuffer codeHashHiNewXorExpData5XorStackItemValueHi1XorValueCurrLoXorValue; private final MappedByteBuffer codeHashHiXorCallValueXorExpData4XorPushValueLoXorValueCurrHiXorToAddressLo; private final MappedByteBuffer codeHashLoNewXorMmuLimb2XorStackItemValueHi3XorValueNextLo; private final MappedByteBuffer codeHashLoXorMmuLimb1XorStackItemValueHi2XorValueNextHi; private final MappedByteBuffer - codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcCdsXorInitCodeSize; + codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcRaoXorInitCodeSize; private final MappedByteBuffer - codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcCdoXorDeploymentNumberInftyXorFromAddressHi; + codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcRacXorDeploymentNumberInftyXorFromAddressHi; private final MappedByteBuffer contextGetsReverted; private final MappedByteBuffer contextMayChange; private final MappedByteBuffer contextNumber; @@ -84,12 +84,10 @@ public class Trace { private final MappedByteBuffer delta; private final MappedByteBuffer deploymentNumberFinalInBlockXorDeploymentNumberFinalInBlock; private final MappedByteBuffer deploymentNumberFirstInBlockXorDeploymentNumberFirstInBlock; + private final MappedByteBuffer deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhase; + private final MappedByteBuffer deploymentNumberNewXorCallerAddressHiXorMmuRefOffset; private final MappedByteBuffer - deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhaseXorPrcRao; - private final MappedByteBuffer - deploymentNumberNewXorCallerAddressHiXorMmuRefOffsetXorPrcReturnGas; - private final MappedByteBuffer - deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorPrcRacXorToAddressHi; + deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorToAddressHi; private final MappedByteBuffer deploymentStatusInftyXorMxpDeploysXorCallExceptionXorCallFlagXorFinalInCnfXorStatusCode; private final MappedByteBuffer @@ -144,8 +142,9 @@ public class Trace { private final MappedByteBuffer mxpWords; private final MappedByteBuffer nonStackRows; private final MappedByteBuffer nonce; - private final MappedByteBuffer nonceNewXorStpGasPaidOutOfPocketXorGasInitiallyAvailable; - private final MappedByteBuffer nonceXorStpGasMxpXorBasefee; + private final MappedByteBuffer + nonceNewXorStpGasPaidOutOfPocketXorPrcCallerGasXorGasInitiallyAvailable; + private final MappedByteBuffer nonceXorStpGasMxpXorPrcCalleeGasXorBasefee; private final MappedByteBuffer oobData1; private final MappedByteBuffer oobData2; private final MappedByteBuffer oobData3; @@ -217,7 +216,7 @@ public class Trace { private final MappedByteBuffer stackItemStamp4; private final MappedByteBuffer stpGasHi; private final MappedByteBuffer stpGasLo; - private final MappedByteBuffer stpGasUpfrontGasCostXorGasLeftover; + private final MappedByteBuffer stpGasUpfrontGasCostXorPrcReturnGasXorGasLeftover; private final MappedByteBuffer stpValueHi; private final MappedByteBuffer stpValueLo; private final MappedByteBuffer subStamp; @@ -240,7 +239,7 @@ static List headers(int length) { headers.add(new ColumnHeader("hub.ABSOLUTE_TRANSACTION_NUMBER", 2, length)); headers.add( new ColumnHeader( - "hub.ADDRESS_HI_xor_ACCOUNT_ADDRESS_HI_xor_CCRS_STAMP_xor_PRC_CALLEE_GAS_xor_STATIC_GAS_xor_ADDRESS_HI_xor_CALL_DATA_SIZE", + "hub.ADDRESS_HI_xor_ACCOUNT_ADDRESS_HI_xor_CCRS_STAMP_xor_PRC_CDO_xor_STATIC_GAS_xor_ADDRESS_HI_xor_CALL_DATA_SIZE", 4, length)); headers.add( @@ -281,7 +280,7 @@ static List headers(int length) { headers.add(new ColumnHeader("hub.CODE_FRAGMENT_INDEX", 4, length)); headers.add( new ColumnHeader( - "hub.CODE_FRAGMENT_INDEX_xor_ACCOUNT_DEPLOYMENT_NUMBER_xor_EXP_INST_xor_PRC_CALLER_GAS_xor_DEPLOYMENT_NUMBER_xor_COINBASE_ADDRESS_HI", + "hub.CODE_FRAGMENT_INDEX_xor_ACCOUNT_DEPLOYMENT_NUMBER_xor_EXP_INST_xor_PRC_CDS_xor_DEPLOYMENT_NUMBER_xor_COINBASE_ADDRESS_HI", 4, length)); headers.add( @@ -306,12 +305,12 @@ static List headers(int length) { length)); headers.add( new ColumnHeader( - "hub.CODE_SIZE_NEW_xor_BYTE_CODE_CODE_FRAGMENT_INDEX_xor_MMU_EXO_SUM_xor_PRC_CDS_xor_INIT_CODE_SIZE", + "hub.CODE_SIZE_NEW_xor_BYTE_CODE_CODE_FRAGMENT_INDEX_xor_MMU_EXO_SUM_xor_PRC_RAO_xor_INIT_CODE_SIZE", 4, length)); headers.add( new ColumnHeader( - "hub.CODE_SIZE_xor_BYTE_CODE_ADDRESS_HI_xor_MMU_AUX_ID_xor_PRC_CDO_xor_DEPLOYMENT_NUMBER_INFTY_xor_FROM_ADDRESS_HI", + "hub.CODE_SIZE_xor_BYTE_CODE_ADDRESS_HI_xor_MMU_AUX_ID_xor_PRC_RAC_xor_DEPLOYMENT_NUMBER_INFTY_xor_FROM_ADDRESS_HI", 4, length)); headers.add(new ColumnHeader("hub.CONTEXT_GETS_REVERTED", 1, length)); @@ -337,17 +336,15 @@ static List headers(int length) { length)); headers.add( new ColumnHeader( - "hub.DEPLOYMENT_NUMBER_INFTY_xor_BYTE_CODE_DEPLOYMENT_STATUS_xor_MMU_PHASE_xor_PRC_RAO", + "hub.DEPLOYMENT_NUMBER_INFTY_xor_BYTE_CODE_DEPLOYMENT_STATUS_xor_MMU_PHASE", 4, length)); headers.add( new ColumnHeader( - "hub.DEPLOYMENT_NUMBER_NEW_xor_CALLER_ADDRESS_HI_xor_MMU_REF_OFFSET_xor_PRC_RETURN_GAS", - 4, - length)); + "hub.DEPLOYMENT_NUMBER_NEW_xor_CALLER_ADDRESS_HI_xor_MMU_REF_OFFSET", 4, length)); headers.add( new ColumnHeader( - "hub.DEPLOYMENT_NUMBER_xor_BYTE_CODE_DEPLOYMENT_NUMBER_xor_MMU_INST_xor_PRC_RAC_xor_TO_ADDRESS_HI", + "hub.DEPLOYMENT_NUMBER_xor_BYTE_CODE_DEPLOYMENT_NUMBER_xor_MMU_INST_xor_TO_ADDRESS_HI", 4, length)); headers.add( @@ -457,8 +454,11 @@ static List headers(int length) { headers.add(new ColumnHeader("hub.NONCE", 8, length)); headers.add( new ColumnHeader( - "hub.NONCE_NEW_xor_STP_GAS_PAID_OUT_OF_POCKET_xor_GAS_INITIALLY_AVAILABLE", 8, length)); - headers.add(new ColumnHeader("hub.NONCE_xor_STP_GAS_MXP_xor_BASEFEE", 8, length)); + "hub.NONCE_NEW_xor_STP_GAS_PAID_OUT_OF_POCKET_xor_PRC_CALLER_GAS_xor_GAS_INITIALLY_AVAILABLE", + 8, + length)); + headers.add( + new ColumnHeader("hub.NONCE_xor_STP_GAS_MXP_xor_PRC_CALLEE_GAS_xor_BASEFEE", 8, length)); headers.add(new ColumnHeader("hub.OOB_DATA_1", 16, length)); headers.add(new ColumnHeader("hub.OOB_DATA_2", 16, length)); headers.add(new ColumnHeader("hub.OOB_DATA_3", 16, length)); @@ -569,7 +569,9 @@ static List headers(int length) { headers.add(new ColumnHeader("hub.STACK_ITEM_STAMP_4", 5, length)); headers.add(new ColumnHeader("hub.STP_GAS_HI", 16, length)); headers.add(new ColumnHeader("hub.STP_GAS_LO", 16, length)); - headers.add(new ColumnHeader("hub.STP_GAS_UPFRONT_GAS_COST_xor_GAS_LEFTOVER", 8, length)); + headers.add( + new ColumnHeader( + "hub.STP_GAS_UPFRONT_GAS_COST_xor_PRC_RETURN_GAS_xor_GAS_LEFTOVER", 8, length)); headers.add(new ColumnHeader("hub.STP_VALUE_HI", 16, length)); headers.add(new ColumnHeader("hub.STP_VALUE_LO", 16, length)); headers.add(new ColumnHeader("hub.SUB_STAMP", 4, length)); @@ -595,8 +597,7 @@ static List headers(int length) { public Trace(List buffers) { this.absoluteTransactionNumber = buffers.get(0); - this - .addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize = + this.addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize = buffers.get(1); this .addressLoXorAccountAddressLoXorExpData1XorHashInfoKeccakHiXorAddressLoXorCoinbaseAddressLo = @@ -620,16 +621,16 @@ public Trace(List buffers) { this.callerContextNumber = buffers.get(12); this.codeFragmentIndex = buffers.get(13); this - .codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCallerGasXorDeploymentNumberXorCoinbaseAddressHi = + .codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCdsXorDeploymentNumberXorCoinbaseAddressHi = buffers.get(14); this.codeHashHiNewXorExpData5XorStackItemValueHi1XorValueCurrLoXorValue = buffers.get(15); this.codeHashHiXorCallValueXorExpData4XorPushValueLoXorValueCurrHiXorToAddressLo = buffers.get(16); this.codeHashLoNewXorMmuLimb2XorStackItemValueHi3XorValueNextLo = buffers.get(17); this.codeHashLoXorMmuLimb1XorStackItemValueHi2XorValueNextHi = buffers.get(18); - this.codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcCdsXorInitCodeSize = + this.codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcRaoXorInitCodeSize = buffers.get(19); - this.codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcCdoXorDeploymentNumberInftyXorFromAddressHi = + this.codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcRacXorDeploymentNumberInftyXorFromAddressHi = buffers.get(20); this.contextGetsReverted = buffers.get(21); this.contextMayChange = buffers.get(22); @@ -644,10 +645,9 @@ public Trace(List buffers) { this.delta = buffers.get(31); this.deploymentNumberFinalInBlockXorDeploymentNumberFinalInBlock = buffers.get(32); this.deploymentNumberFirstInBlockXorDeploymentNumberFirstInBlock = buffers.get(33); - this.deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhaseXorPrcRao = buffers.get(34); - this.deploymentNumberNewXorCallerAddressHiXorMmuRefOffsetXorPrcReturnGas = buffers.get(35); - this.deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorPrcRacXorToAddressHi = - buffers.get(36); + this.deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhase = buffers.get(34); + this.deploymentNumberNewXorCallerAddressHiXorMmuRefOffset = buffers.get(35); + this.deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorToAddressHi = buffers.get(36); this.deploymentStatusInftyXorMxpDeploysXorCallExceptionXorCallFlagXorFinalInCnfXorStatusCode = buffers.get(37); this.deploymentStatusNewXorMxpFlagXorCallPrcFailureXorConFlagXorFinalInTxn = buffers.get(38); @@ -704,8 +704,8 @@ public Trace(List buffers) { this.mxpWords = buffers.get(75); this.nonStackRows = buffers.get(76); this.nonce = buffers.get(77); - this.nonceNewXorStpGasPaidOutOfPocketXorGasInitiallyAvailable = buffers.get(78); - this.nonceXorStpGasMxpXorBasefee = buffers.get(79); + this.nonceNewXorStpGasPaidOutOfPocketXorPrcCallerGasXorGasInitiallyAvailable = buffers.get(78); + this.nonceXorStpGasMxpXorPrcCalleeGasXorBasefee = buffers.get(79); this.oobData1 = buffers.get(80); this.oobData2 = buffers.get(81); this.oobData3 = buffers.get(82); @@ -776,7 +776,7 @@ public Trace(List buffers) { this.stackItemStamp4 = buffers.get(146); this.stpGasHi = buffers.get(147); this.stpGasLo = buffers.get(148); - this.stpGasUpfrontGasCostXorGasLeftover = buffers.get(149); + this.stpGasUpfrontGasCostXorPrcReturnGasXorGasLeftover = buffers.get(149); this.stpValueHi = buffers.get(150); this.stpValueLo = buffers.get(151); this.subStamp = buffers.get(152); @@ -1267,14 +1267,14 @@ public Trace pAccountAddressHi(final long b) { if (b >= 4294967296L) { throw new IllegalArgumentException("hub.account/ADDRESS_HI has invalid value (" + b + ")"); } - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize - .put((byte) (b >> 24)); - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize - .put((byte) (b >> 16)); - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize - .put((byte) (b >> 8)); - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize - .put((byte) b); + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize.put( + (byte) (b >> 24)); + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize.put( + (byte) (b >> 16)); + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize.put( + (byte) (b >> 8)); + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize.put( + (byte) b); return this; } @@ -1413,13 +1413,13 @@ public Trace pAccountCodeFragmentIndex(final long b) { throw new IllegalArgumentException( "hub.account/CODE_FRAGMENT_INDEX has invalid value (" + b + ")"); } - codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCallerGasXorDeploymentNumberXorCoinbaseAddressHi + codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCdsXorDeploymentNumberXorCoinbaseAddressHi .put((byte) (b >> 24)); - codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCallerGasXorDeploymentNumberXorCoinbaseAddressHi + codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCdsXorDeploymentNumberXorCoinbaseAddressHi .put((byte) (b >> 16)); - codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCallerGasXorDeploymentNumberXorCoinbaseAddressHi + codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCdsXorDeploymentNumberXorCoinbaseAddressHi .put((byte) (b >> 8)); - codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCallerGasXorDeploymentNumberXorCoinbaseAddressHi + codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCdsXorDeploymentNumberXorCoinbaseAddressHi .put((byte) b); return this; @@ -1539,13 +1539,13 @@ public Trace pAccountCodeSize(final long b) { if (b >= 4294967296L) { throw new IllegalArgumentException("hub.account/CODE_SIZE has invalid value (" + b + ")"); } - codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcCdoXorDeploymentNumberInftyXorFromAddressHi.put( + codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcRacXorDeploymentNumberInftyXorFromAddressHi.put( (byte) (b >> 24)); - codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcCdoXorDeploymentNumberInftyXorFromAddressHi.put( + codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcRacXorDeploymentNumberInftyXorFromAddressHi.put( (byte) (b >> 16)); - codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcCdoXorDeploymentNumberInftyXorFromAddressHi.put( + codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcRacXorDeploymentNumberInftyXorFromAddressHi.put( (byte) (b >> 8)); - codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcCdoXorDeploymentNumberInftyXorFromAddressHi.put( + codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcRacXorDeploymentNumberInftyXorFromAddressHi.put( (byte) b); return this; @@ -1561,13 +1561,13 @@ public Trace pAccountCodeSizeNew(final long b) { if (b >= 4294967296L) { throw new IllegalArgumentException("hub.account/CODE_SIZE_NEW has invalid value (" + b + ")"); } - codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcCdsXorInitCodeSize.put( + codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcRaoXorInitCodeSize.put( (byte) (b >> 24)); - codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcCdsXorInitCodeSize.put( + codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcRaoXorInitCodeSize.put( (byte) (b >> 16)); - codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcCdsXorInitCodeSize.put( + codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcRaoXorInitCodeSize.put( (byte) (b >> 8)); - codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcCdsXorInitCodeSize.put((byte) b); + codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcRaoXorInitCodeSize.put((byte) b); return this; } @@ -1583,13 +1583,10 @@ public Trace pAccountDeploymentNumber(final long b) { throw new IllegalArgumentException( "hub.account/DEPLOYMENT_NUMBER has invalid value (" + b + ")"); } - deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorPrcRacXorToAddressHi.put( - (byte) (b >> 24)); - deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorPrcRacXorToAddressHi.put( - (byte) (b >> 16)); - deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorPrcRacXorToAddressHi.put( - (byte) (b >> 8)); - deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorPrcRacXorToAddressHi.put((byte) b); + deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorToAddressHi.put((byte) (b >> 24)); + deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorToAddressHi.put((byte) (b >> 16)); + deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorToAddressHi.put((byte) (b >> 8)); + deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorToAddressHi.put((byte) b); return this; } @@ -1639,10 +1636,10 @@ public Trace pAccountDeploymentNumberInfty(final long b) { throw new IllegalArgumentException( "hub.account/DEPLOYMENT_NUMBER_INFTY has invalid value (" + b + ")"); } - deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhaseXorPrcRao.put((byte) (b >> 24)); - deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhaseXorPrcRao.put((byte) (b >> 16)); - deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhaseXorPrcRao.put((byte) (b >> 8)); - deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhaseXorPrcRao.put((byte) b); + deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhase.put((byte) (b >> 24)); + deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhase.put((byte) (b >> 16)); + deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhase.put((byte) (b >> 8)); + deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhase.put((byte) b); return this; } @@ -1658,10 +1655,10 @@ public Trace pAccountDeploymentNumberNew(final long b) { throw new IllegalArgumentException( "hub.account/DEPLOYMENT_NUMBER_NEW has invalid value (" + b + ")"); } - deploymentNumberNewXorCallerAddressHiXorMmuRefOffsetXorPrcReturnGas.put((byte) (b >> 24)); - deploymentNumberNewXorCallerAddressHiXorMmuRefOffsetXorPrcReturnGas.put((byte) (b >> 16)); - deploymentNumberNewXorCallerAddressHiXorMmuRefOffsetXorPrcReturnGas.put((byte) (b >> 8)); - deploymentNumberNewXorCallerAddressHiXorMmuRefOffsetXorPrcReturnGas.put((byte) b); + deploymentNumberNewXorCallerAddressHiXorMmuRefOffset.put((byte) (b >> 24)); + deploymentNumberNewXorCallerAddressHiXorMmuRefOffset.put((byte) (b >> 16)); + deploymentNumberNewXorCallerAddressHiXorMmuRefOffset.put((byte) (b >> 8)); + deploymentNumberNewXorCallerAddressHiXorMmuRefOffset.put((byte) b); return this; } @@ -1886,11 +1883,11 @@ public Trace pAccountNonce(final Bytes b) { } // Write padding (if necessary) for (int i = bs.size(); i < 8; i++) { - nonceXorStpGasMxpXorBasefee.put((byte) 0); + nonceXorStpGasMxpXorPrcCalleeGasXorBasefee.put((byte) 0); } // Write bytes for (int j = 0; j < bs.size(); j++) { - nonceXorStpGasMxpXorBasefee.put(bs.get(j)); + nonceXorStpGasMxpXorPrcCalleeGasXorBasefee.put(bs.get(j)); } return this; @@ -1912,11 +1909,11 @@ public Trace pAccountNonceNew(final Bytes b) { } // Write padding (if necessary) for (int i = bs.size(); i < 8; i++) { - nonceNewXorStpGasPaidOutOfPocketXorGasInitiallyAvailable.put((byte) 0); + nonceNewXorStpGasPaidOutOfPocketXorPrcCallerGasXorGasInitiallyAvailable.put((byte) 0); } // Write bytes for (int j = 0; j < bs.size(); j++) { - nonceNewXorStpGasPaidOutOfPocketXorGasInitiallyAvailable.put(bs.get(j)); + nonceNewXorStpGasPaidOutOfPocketXorPrcCallerGasXorGasInitiallyAvailable.put(bs.get(j)); } return this; @@ -2185,14 +2182,14 @@ public Trace pContextAccountAddressHi(final long b) { throw new IllegalArgumentException( "hub.context/ACCOUNT_ADDRESS_HI has invalid value (" + b + ")"); } - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize - .put((byte) (b >> 24)); - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize - .put((byte) (b >> 16)); - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize - .put((byte) (b >> 8)); - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize - .put((byte) b); + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize.put( + (byte) (b >> 24)); + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize.put( + (byte) (b >> 16)); + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize.put( + (byte) (b >> 8)); + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize.put( + (byte) b); return this; } @@ -2236,13 +2233,13 @@ public Trace pContextAccountDeploymentNumber(final long b) { throw new IllegalArgumentException( "hub.context/ACCOUNT_DEPLOYMENT_NUMBER has invalid value (" + b + ")"); } - codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCallerGasXorDeploymentNumberXorCoinbaseAddressHi + codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCdsXorDeploymentNumberXorCoinbaseAddressHi .put((byte) (b >> 24)); - codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCallerGasXorDeploymentNumberXorCoinbaseAddressHi + codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCdsXorDeploymentNumberXorCoinbaseAddressHi .put((byte) (b >> 16)); - codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCallerGasXorDeploymentNumberXorCoinbaseAddressHi + codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCdsXorDeploymentNumberXorCoinbaseAddressHi .put((byte) (b >> 8)); - codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCallerGasXorDeploymentNumberXorCoinbaseAddressHi + codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCdsXorDeploymentNumberXorCoinbaseAddressHi .put((byte) b); return this; @@ -2259,13 +2256,13 @@ public Trace pContextByteCodeAddressHi(final long b) { throw new IllegalArgumentException( "hub.context/BYTE_CODE_ADDRESS_HI has invalid value (" + b + ")"); } - codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcCdoXorDeploymentNumberInftyXorFromAddressHi.put( + codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcRacXorDeploymentNumberInftyXorFromAddressHi.put( (byte) (b >> 24)); - codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcCdoXorDeploymentNumberInftyXorFromAddressHi.put( + codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcRacXorDeploymentNumberInftyXorFromAddressHi.put( (byte) (b >> 16)); - codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcCdoXorDeploymentNumberInftyXorFromAddressHi.put( + codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcRacXorDeploymentNumberInftyXorFromAddressHi.put( (byte) (b >> 8)); - codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcCdoXorDeploymentNumberInftyXorFromAddressHi.put( + codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcRacXorDeploymentNumberInftyXorFromAddressHi.put( (byte) b); return this; @@ -2310,13 +2307,13 @@ public Trace pContextByteCodeCodeFragmentIndex(final long b) { throw new IllegalArgumentException( "hub.context/BYTE_CODE_CODE_FRAGMENT_INDEX has invalid value (" + b + ")"); } - codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcCdsXorInitCodeSize.put( + codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcRaoXorInitCodeSize.put( (byte) (b >> 24)); - codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcCdsXorInitCodeSize.put( + codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcRaoXorInitCodeSize.put( (byte) (b >> 16)); - codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcCdsXorInitCodeSize.put( + codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcRaoXorInitCodeSize.put( (byte) (b >> 8)); - codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcCdsXorInitCodeSize.put((byte) b); + codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcRaoXorInitCodeSize.put((byte) b); return this; } @@ -2332,13 +2329,10 @@ public Trace pContextByteCodeDeploymentNumber(final long b) { throw new IllegalArgumentException( "hub.context/BYTE_CODE_DEPLOYMENT_NUMBER has invalid value (" + b + ")"); } - deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorPrcRacXorToAddressHi.put( - (byte) (b >> 24)); - deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorPrcRacXorToAddressHi.put( - (byte) (b >> 16)); - deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorPrcRacXorToAddressHi.put( - (byte) (b >> 8)); - deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorPrcRacXorToAddressHi.put((byte) b); + deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorToAddressHi.put((byte) (b >> 24)); + deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorToAddressHi.put((byte) (b >> 16)); + deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorToAddressHi.put((byte) (b >> 8)); + deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorToAddressHi.put((byte) b); return this; } @@ -2354,10 +2348,10 @@ public Trace pContextByteCodeDeploymentStatus(final long b) { throw new IllegalArgumentException( "hub.context/BYTE_CODE_DEPLOYMENT_STATUS has invalid value (" + b + ")"); } - deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhaseXorPrcRao.put((byte) (b >> 24)); - deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhaseXorPrcRao.put((byte) (b >> 16)); - deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhaseXorPrcRao.put((byte) (b >> 8)); - deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhaseXorPrcRao.put((byte) b); + deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhase.put((byte) (b >> 24)); + deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhase.put((byte) (b >> 16)); + deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhase.put((byte) (b >> 8)); + deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhase.put((byte) b); return this; } @@ -2473,10 +2467,10 @@ public Trace pContextCallerAddressHi(final long b) { throw new IllegalArgumentException( "hub.context/CALLER_ADDRESS_HI has invalid value (" + b + ")"); } - deploymentNumberNewXorCallerAddressHiXorMmuRefOffsetXorPrcReturnGas.put((byte) (b >> 24)); - deploymentNumberNewXorCallerAddressHiXorMmuRefOffsetXorPrcReturnGas.put((byte) (b >> 16)); - deploymentNumberNewXorCallerAddressHiXorMmuRefOffsetXorPrcReturnGas.put((byte) (b >> 8)); - deploymentNumberNewXorCallerAddressHiXorMmuRefOffsetXorPrcReturnGas.put((byte) b); + deploymentNumberNewXorCallerAddressHiXorMmuRefOffset.put((byte) (b >> 24)); + deploymentNumberNewXorCallerAddressHiXorMmuRefOffset.put((byte) (b >> 16)); + deploymentNumberNewXorCallerAddressHiXorMmuRefOffset.put((byte) (b >> 8)); + deploymentNumberNewXorCallerAddressHiXorMmuRefOffset.put((byte) b); return this; } @@ -2672,14 +2666,14 @@ public Trace pMiscCcrsStamp(final long b) { if (b >= 4294967296L) { throw new IllegalArgumentException("hub.misc/CCRS_STAMP has invalid value (" + b + ")"); } - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize - .put((byte) (b >> 24)); - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize - .put((byte) (b >> 16)); - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize - .put((byte) (b >> 8)); - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize - .put((byte) b); + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize.put( + (byte) (b >> 24)); + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize.put( + (byte) (b >> 16)); + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize.put( + (byte) (b >> 8)); + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize.put( + (byte) b); return this; } @@ -2856,13 +2850,13 @@ public Trace pMiscExpInst(final long b) { if (b >= 4294967296L) { throw new IllegalArgumentException("hub.misc/EXP_INST has invalid value (" + b + ")"); } - codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCallerGasXorDeploymentNumberXorCoinbaseAddressHi + codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCdsXorDeploymentNumberXorCoinbaseAddressHi .put((byte) (b >> 24)); - codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCallerGasXorDeploymentNumberXorCoinbaseAddressHi + codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCdsXorDeploymentNumberXorCoinbaseAddressHi .put((byte) (b >> 16)); - codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCallerGasXorDeploymentNumberXorCoinbaseAddressHi + codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCdsXorDeploymentNumberXorCoinbaseAddressHi .put((byte) (b >> 8)); - codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCallerGasXorDeploymentNumberXorCoinbaseAddressHi + codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCdsXorDeploymentNumberXorCoinbaseAddressHi .put((byte) b); return this; @@ -2878,13 +2872,13 @@ public Trace pMiscMmuAuxId(final long b) { if (b >= 4294967296L) { throw new IllegalArgumentException("hub.misc/MMU_AUX_ID has invalid value (" + b + ")"); } - codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcCdoXorDeploymentNumberInftyXorFromAddressHi.put( + codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcRacXorDeploymentNumberInftyXorFromAddressHi.put( (byte) (b >> 24)); - codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcCdoXorDeploymentNumberInftyXorFromAddressHi.put( + codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcRacXorDeploymentNumberInftyXorFromAddressHi.put( (byte) (b >> 16)); - codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcCdoXorDeploymentNumberInftyXorFromAddressHi.put( + codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcRacXorDeploymentNumberInftyXorFromAddressHi.put( (byte) (b >> 8)); - codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcCdoXorDeploymentNumberInftyXorFromAddressHi.put( + codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcRacXorDeploymentNumberInftyXorFromAddressHi.put( (byte) b); return this; @@ -2900,13 +2894,13 @@ public Trace pMiscMmuExoSum(final long b) { if (b >= 4294967296L) { throw new IllegalArgumentException("hub.misc/MMU_EXO_SUM has invalid value (" + b + ")"); } - codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcCdsXorInitCodeSize.put( + codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcRaoXorInitCodeSize.put( (byte) (b >> 24)); - codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcCdsXorInitCodeSize.put( + codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcRaoXorInitCodeSize.put( (byte) (b >> 16)); - codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcCdsXorInitCodeSize.put( + codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcRaoXorInitCodeSize.put( (byte) (b >> 8)); - codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcCdsXorInitCodeSize.put((byte) b); + codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcRaoXorInitCodeSize.put((byte) b); return this; } @@ -2934,13 +2928,10 @@ public Trace pMiscMmuInst(final long b) { if (b >= 4294967296L) { throw new IllegalArgumentException("hub.misc/MMU_INST has invalid value (" + b + ")"); } - deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorPrcRacXorToAddressHi.put( - (byte) (b >> 24)); - deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorPrcRacXorToAddressHi.put( - (byte) (b >> 16)); - deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorPrcRacXorToAddressHi.put( - (byte) (b >> 8)); - deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorPrcRacXorToAddressHi.put((byte) b); + deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorToAddressHi.put((byte) (b >> 24)); + deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorToAddressHi.put((byte) (b >> 16)); + deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorToAddressHi.put((byte) (b >> 8)); + deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorToAddressHi.put((byte) b); return this; } @@ -3007,10 +2998,10 @@ public Trace pMiscMmuPhase(final long b) { if (b >= 4294967296L) { throw new IllegalArgumentException("hub.misc/MMU_PHASE has invalid value (" + b + ")"); } - deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhaseXorPrcRao.put((byte) (b >> 24)); - deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhaseXorPrcRao.put((byte) (b >> 16)); - deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhaseXorPrcRao.put((byte) (b >> 8)); - deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhaseXorPrcRao.put((byte) b); + deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhase.put((byte) (b >> 24)); + deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhase.put((byte) (b >> 16)); + deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhase.put((byte) (b >> 8)); + deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhase.put((byte) b); return this; } @@ -3025,10 +3016,10 @@ public Trace pMiscMmuRefOffset(final long b) { if (b >= 4294967296L) { throw new IllegalArgumentException("hub.misc/MMU_REF_OFFSET has invalid value (" + b + ")"); } - deploymentNumberNewXorCallerAddressHiXorMmuRefOffsetXorPrcReturnGas.put((byte) (b >> 24)); - deploymentNumberNewXorCallerAddressHiXorMmuRefOffsetXorPrcReturnGas.put((byte) (b >> 16)); - deploymentNumberNewXorCallerAddressHiXorMmuRefOffsetXorPrcReturnGas.put((byte) (b >> 8)); - deploymentNumberNewXorCallerAddressHiXorMmuRefOffsetXorPrcReturnGas.put((byte) b); + deploymentNumberNewXorCallerAddressHiXorMmuRefOffset.put((byte) (b >> 24)); + deploymentNumberNewXorCallerAddressHiXorMmuRefOffset.put((byte) (b >> 16)); + deploymentNumberNewXorCallerAddressHiXorMmuRefOffset.put((byte) (b >> 8)); + deploymentNumberNewXorCallerAddressHiXorMmuRefOffset.put((byte) b); return this; } @@ -3909,11 +3900,11 @@ public Trace pMiscStpGasMxp(final Bytes b) { } // Write padding (if necessary) for (int i = bs.size(); i < 8; i++) { - nonceXorStpGasMxpXorBasefee.put((byte) 0); + nonceXorStpGasMxpXorPrcCalleeGasXorBasefee.put((byte) 0); } // Write bytes for (int j = 0; j < bs.size(); j++) { - nonceXorStpGasMxpXorBasefee.put(bs.get(j)); + nonceXorStpGasMxpXorPrcCalleeGasXorBasefee.put(bs.get(j)); } return this; @@ -3935,11 +3926,11 @@ public Trace pMiscStpGasPaidOutOfPocket(final Bytes b) { } // Write padding (if necessary) for (int i = bs.size(); i < 8; i++) { - nonceNewXorStpGasPaidOutOfPocketXorGasInitiallyAvailable.put((byte) 0); + nonceNewXorStpGasPaidOutOfPocketXorPrcCallerGasXorGasInitiallyAvailable.put((byte) 0); } // Write bytes for (int j = 0; j < bs.size(); j++) { - nonceNewXorStpGasPaidOutOfPocketXorGasInitiallyAvailable.put(bs.get(j)); + nonceNewXorStpGasPaidOutOfPocketXorPrcCallerGasXorGasInitiallyAvailable.put(bs.get(j)); } return this; @@ -3979,11 +3970,11 @@ public Trace pMiscStpGasUpfrontGasCost(final Bytes b) { } // Write padding (if necessary) for (int i = bs.size(); i < 8; i++) { - stpGasUpfrontGasCostXorGasLeftover.put((byte) 0); + stpGasUpfrontGasCostXorPrcReturnGasXorGasLeftover.put((byte) 0); } // Write bytes for (int j = 0; j < bs.size(); j++) { - stpGasUpfrontGasCostXorGasLeftover.put(bs.get(j)); + stpGasUpfrontGasCostXorPrcReturnGasXorGasLeftover.put(bs.get(j)); } return this; @@ -4393,91 +4384,98 @@ public Trace pScenarioPrcBlake2F(final Boolean b) { return this; } - public Trace pScenarioPrcCalleeGas(final long b) { - if (filled.get(103)) { + public Trace pScenarioPrcCalleeGas(final Bytes b) { + if (filled.get(123)) { throw new IllegalStateException("hub.scenario/PRC_CALLEE_GAS already set"); } else { - filled.set(103); + filled.set(123); } - if (b >= 4294967296L) { + // Trim array to size + Bytes bs = b.trimLeadingZeros(); + // Sanity check against expected width + if (bs.bitLength() > 64) { throw new IllegalArgumentException( - "hub.scenario/PRC_CALLEE_GAS has invalid value (" + b + ")"); + "hub.scenario/PRC_CALLEE_GAS has invalid width (" + bs.bitLength() + "bits)"); + } + // Write padding (if necessary) + for (int i = bs.size(); i < 8; i++) { + nonceXorStpGasMxpXorPrcCalleeGasXorBasefee.put((byte) 0); + } + // Write bytes + for (int j = 0; j < bs.size(); j++) { + nonceXorStpGasMxpXorPrcCalleeGasXorBasefee.put(bs.get(j)); } - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize - .put((byte) (b >> 24)); - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize - .put((byte) (b >> 16)); - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize - .put((byte) (b >> 8)); - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize - .put((byte) b); return this; } - public Trace pScenarioPrcCallerGas(final long b) { - if (filled.get(104)) { + public Trace pScenarioPrcCallerGas(final Bytes b) { + if (filled.get(124)) { throw new IllegalStateException("hub.scenario/PRC_CALLER_GAS already set"); } else { - filled.set(104); + filled.set(124); } - if (b >= 4294967296L) { + // Trim array to size + Bytes bs = b.trimLeadingZeros(); + // Sanity check against expected width + if (bs.bitLength() > 64) { throw new IllegalArgumentException( - "hub.scenario/PRC_CALLER_GAS has invalid value (" + b + ")"); + "hub.scenario/PRC_CALLER_GAS has invalid width (" + bs.bitLength() + "bits)"); + } + // Write padding (if necessary) + for (int i = bs.size(); i < 8; i++) { + nonceNewXorStpGasPaidOutOfPocketXorPrcCallerGasXorGasInitiallyAvailable.put((byte) 0); + } + // Write bytes + for (int j = 0; j < bs.size(); j++) { + nonceNewXorStpGasPaidOutOfPocketXorPrcCallerGasXorGasInitiallyAvailable.put(bs.get(j)); } - codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCallerGasXorDeploymentNumberXorCoinbaseAddressHi - .put((byte) (b >> 24)); - codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCallerGasXorDeploymentNumberXorCoinbaseAddressHi - .put((byte) (b >> 16)); - codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCallerGasXorDeploymentNumberXorCoinbaseAddressHi - .put((byte) (b >> 8)); - codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCallerGasXorDeploymentNumberXorCoinbaseAddressHi - .put((byte) b); return this; } public Trace pScenarioPrcCdo(final long b) { - if (filled.get(105)) { + if (filled.get(103)) { throw new IllegalStateException("hub.scenario/PRC_CDO already set"); } else { - filled.set(105); + filled.set(103); } if (b >= 4294967296L) { throw new IllegalArgumentException("hub.scenario/PRC_CDO has invalid value (" + b + ")"); } - codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcCdoXorDeploymentNumberInftyXorFromAddressHi.put( + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize.put( (byte) (b >> 24)); - codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcCdoXorDeploymentNumberInftyXorFromAddressHi.put( + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize.put( (byte) (b >> 16)); - codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcCdoXorDeploymentNumberInftyXorFromAddressHi.put( + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize.put( (byte) (b >> 8)); - codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcCdoXorDeploymentNumberInftyXorFromAddressHi.put( + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize.put( (byte) b); return this; } public Trace pScenarioPrcCds(final long b) { - if (filled.get(106)) { + if (filled.get(104)) { throw new IllegalStateException("hub.scenario/PRC_CDS already set"); } else { - filled.set(106); + filled.set(104); } if (b >= 4294967296L) { throw new IllegalArgumentException("hub.scenario/PRC_CDS has invalid value (" + b + ")"); } - codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcCdsXorInitCodeSize.put( - (byte) (b >> 24)); - codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcCdsXorInitCodeSize.put( - (byte) (b >> 16)); - codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcCdsXorInitCodeSize.put( - (byte) (b >> 8)); - codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcCdsXorInitCodeSize.put((byte) b); + codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCdsXorDeploymentNumberXorCoinbaseAddressHi + .put((byte) (b >> 24)); + codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCdsXorDeploymentNumberXorCoinbaseAddressHi + .put((byte) (b >> 16)); + codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCdsXorDeploymentNumberXorCoinbaseAddressHi + .put((byte) (b >> 8)); + codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCdsXorDeploymentNumberXorCoinbaseAddressHi + .put((byte) b); return this; } @@ -4579,59 +4577,70 @@ public Trace pScenarioPrcModexp(final Boolean b) { } public Trace pScenarioPrcRac(final long b) { - if (filled.get(107)) { + if (filled.get(105)) { throw new IllegalStateException("hub.scenario/PRC_RAC already set"); } else { - filled.set(107); + filled.set(105); } if (b >= 4294967296L) { throw new IllegalArgumentException("hub.scenario/PRC_RAC has invalid value (" + b + ")"); } - deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorPrcRacXorToAddressHi.put( + codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcRacXorDeploymentNumberInftyXorFromAddressHi.put( (byte) (b >> 24)); - deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorPrcRacXorToAddressHi.put( + codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcRacXorDeploymentNumberInftyXorFromAddressHi.put( (byte) (b >> 16)); - deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorPrcRacXorToAddressHi.put( + codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcRacXorDeploymentNumberInftyXorFromAddressHi.put( (byte) (b >> 8)); - deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorPrcRacXorToAddressHi.put((byte) b); + codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcRacXorDeploymentNumberInftyXorFromAddressHi.put( + (byte) b); return this; } public Trace pScenarioPrcRao(final long b) { - if (filled.get(108)) { + if (filled.get(106)) { throw new IllegalStateException("hub.scenario/PRC_RAO already set"); } else { - filled.set(108); + filled.set(106); } if (b >= 4294967296L) { throw new IllegalArgumentException("hub.scenario/PRC_RAO has invalid value (" + b + ")"); } - deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhaseXorPrcRao.put((byte) (b >> 24)); - deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhaseXorPrcRao.put((byte) (b >> 16)); - deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhaseXorPrcRao.put((byte) (b >> 8)); - deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhaseXorPrcRao.put((byte) b); + codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcRaoXorInitCodeSize.put( + (byte) (b >> 24)); + codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcRaoXorInitCodeSize.put( + (byte) (b >> 16)); + codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcRaoXorInitCodeSize.put( + (byte) (b >> 8)); + codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcRaoXorInitCodeSize.put((byte) b); return this; } - public Trace pScenarioPrcReturnGas(final long b) { - if (filled.get(109)) { + public Trace pScenarioPrcReturnGas(final Bytes b) { + if (filled.get(125)) { throw new IllegalStateException("hub.scenario/PRC_RETURN_GAS already set"); } else { - filled.set(109); + filled.set(125); } - if (b >= 4294967296L) { + // Trim array to size + Bytes bs = b.trimLeadingZeros(); + // Sanity check against expected width + if (bs.bitLength() > 64) { throw new IllegalArgumentException( - "hub.scenario/PRC_RETURN_GAS has invalid value (" + b + ")"); + "hub.scenario/PRC_RETURN_GAS has invalid width (" + bs.bitLength() + "bits)"); + } + // Write padding (if necessary) + for (int i = bs.size(); i < 8; i++) { + stpGasUpfrontGasCostXorPrcReturnGasXorGasLeftover.put((byte) 0); + } + // Write bytes + for (int j = 0; j < bs.size(); j++) { + stpGasUpfrontGasCostXorPrcReturnGasXorGasLeftover.put(bs.get(j)); } - deploymentNumberNewXorCallerAddressHiXorMmuRefOffsetXorPrcReturnGas.put((byte) (b >> 24)); - deploymentNumberNewXorCallerAddressHiXorMmuRefOffsetXorPrcReturnGas.put((byte) (b >> 16)); - deploymentNumberNewXorCallerAddressHiXorMmuRefOffsetXorPrcReturnGas.put((byte) (b >> 8)); - deploymentNumberNewXorCallerAddressHiXorMmuRefOffsetXorPrcReturnGas.put((byte) b); return this; } @@ -5882,14 +5891,14 @@ public Trace pStackStaticGas(final long b) { if (b >= 4294967296L) { throw new IllegalArgumentException("hub.stack/STATIC_GAS has invalid value (" + b + ")"); } - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize - .put((byte) (b >> 24)); - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize - .put((byte) (b >> 16)); - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize - .put((byte) (b >> 8)); - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize - .put((byte) b); + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize.put( + (byte) (b >> 24)); + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize.put( + (byte) (b >> 16)); + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize.put( + (byte) (b >> 8)); + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize.put( + (byte) b); return this; } @@ -5976,14 +5985,14 @@ public Trace pStorageAddressHi(final long b) { if (b >= 4294967296L) { throw new IllegalArgumentException("hub.storage/ADDRESS_HI has invalid value (" + b + ")"); } - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize - .put((byte) (b >> 24)); - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize - .put((byte) (b >> 16)); - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize - .put((byte) (b >> 8)); - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize - .put((byte) b); + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize.put( + (byte) (b >> 24)); + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize.put( + (byte) (b >> 16)); + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize.put( + (byte) (b >> 8)); + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize.put( + (byte) b); return this; } @@ -6066,13 +6075,13 @@ public Trace pStorageDeploymentNumber(final long b) { throw new IllegalArgumentException( "hub.storage/DEPLOYMENT_NUMBER has invalid value (" + b + ")"); } - codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCallerGasXorDeploymentNumberXorCoinbaseAddressHi + codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCdsXorDeploymentNumberXorCoinbaseAddressHi .put((byte) (b >> 24)); - codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCallerGasXorDeploymentNumberXorCoinbaseAddressHi + codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCdsXorDeploymentNumberXorCoinbaseAddressHi .put((byte) (b >> 16)); - codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCallerGasXorDeploymentNumberXorCoinbaseAddressHi + codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCdsXorDeploymentNumberXorCoinbaseAddressHi .put((byte) (b >> 8)); - codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCallerGasXorDeploymentNumberXorCoinbaseAddressHi + codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCdsXorDeploymentNumberXorCoinbaseAddressHi .put((byte) b); return this; @@ -6123,13 +6132,13 @@ public Trace pStorageDeploymentNumberInfty(final long b) { throw new IllegalArgumentException( "hub.storage/DEPLOYMENT_NUMBER_INFTY has invalid value (" + b + ")"); } - codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcCdoXorDeploymentNumberInftyXorFromAddressHi.put( + codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcRacXorDeploymentNumberInftyXorFromAddressHi.put( (byte) (b >> 24)); - codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcCdoXorDeploymentNumberInftyXorFromAddressHi.put( + codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcRacXorDeploymentNumberInftyXorFromAddressHi.put( (byte) (b >> 16)); - codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcCdoXorDeploymentNumberInftyXorFromAddressHi.put( + codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcRacXorDeploymentNumberInftyXorFromAddressHi.put( (byte) (b >> 8)); - codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcCdoXorDeploymentNumberInftyXorFromAddressHi.put( + codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcRacXorDeploymentNumberInftyXorFromAddressHi.put( (byte) b); return this; @@ -6554,11 +6563,11 @@ public Trace pTransactionBasefee(final Bytes b) { } // Write padding (if necessary) for (int i = bs.size(); i < 8; i++) { - nonceXorStpGasMxpXorBasefee.put((byte) 0); + nonceXorStpGasMxpXorPrcCalleeGasXorBasefee.put((byte) 0); } // Write bytes for (int j = 0; j < bs.size(); j++) { - nonceXorStpGasMxpXorBasefee.put(bs.get(j)); + nonceXorStpGasMxpXorPrcCalleeGasXorBasefee.put(bs.get(j)); } return this; @@ -6575,14 +6584,14 @@ public Trace pTransactionCallDataSize(final long b) { throw new IllegalArgumentException( "hub.transaction/CALL_DATA_SIZE has invalid value (" + b + ")"); } - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize - .put((byte) (b >> 24)); - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize - .put((byte) (b >> 16)); - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize - .put((byte) (b >> 8)); - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize - .put((byte) b); + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize.put( + (byte) (b >> 24)); + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize.put( + (byte) (b >> 16)); + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize.put( + (byte) (b >> 8)); + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize.put( + (byte) b); return this; } @@ -6598,13 +6607,13 @@ public Trace pTransactionCoinbaseAddressHi(final long b) { throw new IllegalArgumentException( "hub.transaction/COINBASE_ADDRESS_HI has invalid value (" + b + ")"); } - codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCallerGasXorDeploymentNumberXorCoinbaseAddressHi + codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCdsXorDeploymentNumberXorCoinbaseAddressHi .put((byte) (b >> 24)); - codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCallerGasXorDeploymentNumberXorCoinbaseAddressHi + codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCdsXorDeploymentNumberXorCoinbaseAddressHi .put((byte) (b >> 16)); - codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCallerGasXorDeploymentNumberXorCoinbaseAddressHi + codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCdsXorDeploymentNumberXorCoinbaseAddressHi .put((byte) (b >> 8)); - codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCallerGasXorDeploymentNumberXorCoinbaseAddressHi + codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCdsXorDeploymentNumberXorCoinbaseAddressHi .put((byte) b); return this; @@ -6662,13 +6671,13 @@ public Trace pTransactionFromAddressHi(final long b) { throw new IllegalArgumentException( "hub.transaction/FROM_ADDRESS_HI has invalid value (" + b + ")"); } - codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcCdoXorDeploymentNumberInftyXorFromAddressHi.put( + codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcRacXorDeploymentNumberInftyXorFromAddressHi.put( (byte) (b >> 24)); - codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcCdoXorDeploymentNumberInftyXorFromAddressHi.put( + codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcRacXorDeploymentNumberInftyXorFromAddressHi.put( (byte) (b >> 16)); - codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcCdoXorDeploymentNumberInftyXorFromAddressHi.put( + codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcRacXorDeploymentNumberInftyXorFromAddressHi.put( (byte) (b >> 8)); - codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcCdoXorDeploymentNumberInftyXorFromAddressHi.put( + codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcRacXorDeploymentNumberInftyXorFromAddressHi.put( (byte) b); return this; @@ -6718,11 +6727,11 @@ public Trace pTransactionGasInitiallyAvailable(final Bytes b) { } // Write padding (if necessary) for (int i = bs.size(); i < 8; i++) { - nonceNewXorStpGasPaidOutOfPocketXorGasInitiallyAvailable.put((byte) 0); + nonceNewXorStpGasPaidOutOfPocketXorPrcCallerGasXorGasInitiallyAvailable.put((byte) 0); } // Write bytes for (int j = 0; j < bs.size(); j++) { - nonceNewXorStpGasPaidOutOfPocketXorGasInitiallyAvailable.put(bs.get(j)); + nonceNewXorStpGasPaidOutOfPocketXorPrcCallerGasXorGasInitiallyAvailable.put(bs.get(j)); } return this; @@ -6744,11 +6753,11 @@ public Trace pTransactionGasLeftover(final Bytes b) { } // Write padding (if necessary) for (int i = bs.size(); i < 8; i++) { - stpGasUpfrontGasCostXorGasLeftover.put((byte) 0); + stpGasUpfrontGasCostXorPrcReturnGasXorGasLeftover.put((byte) 0); } // Write bytes for (int j = 0; j < bs.size(); j++) { - stpGasUpfrontGasCostXorGasLeftover.put(bs.get(j)); + stpGasUpfrontGasCostXorPrcReturnGasXorGasLeftover.put(bs.get(j)); } return this; @@ -6817,13 +6826,13 @@ public Trace pTransactionInitCodeSize(final long b) { throw new IllegalArgumentException( "hub.transaction/INIT_CODE_SIZE has invalid value (" + b + ")"); } - codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcCdsXorInitCodeSize.put( + codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcRaoXorInitCodeSize.put( (byte) (b >> 24)); - codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcCdsXorInitCodeSize.put( + codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcRaoXorInitCodeSize.put( (byte) (b >> 16)); - codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcCdsXorInitCodeSize.put( + codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcRaoXorInitCodeSize.put( (byte) (b >> 8)); - codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcCdsXorInitCodeSize.put((byte) b); + codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcRaoXorInitCodeSize.put((byte) b); return this; } @@ -7023,13 +7032,10 @@ public Trace pTransactionToAddressHi(final long b) { throw new IllegalArgumentException( "hub.transaction/TO_ADDRESS_HI has invalid value (" + b + ")"); } - deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorPrcRacXorToAddressHi.put( - (byte) (b >> 24)); - deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorPrcRacXorToAddressHi.put( - (byte) (b >> 16)); - deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorPrcRacXorToAddressHi.put( - (byte) (b >> 8)); - deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorPrcRacXorToAddressHi.put((byte) b); + deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorToAddressHi.put((byte) (b >> 24)); + deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorToAddressHi.put((byte) (b >> 16)); + deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorToAddressHi.put((byte) (b >> 8)); + deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorToAddressHi.put((byte) b); return this; } @@ -7355,7 +7361,7 @@ public Trace validateRow() { if (!filled.get(103)) { throw new IllegalStateException( - "hub.ADDRESS_HI_xor_ACCOUNT_ADDRESS_HI_xor_CCRS_STAMP_xor_PRC_CALLEE_GAS_xor_STATIC_GAS_xor_ADDRESS_HI_xor_CALL_DATA_SIZE has not been filled"); + "hub.ADDRESS_HI_xor_ACCOUNT_ADDRESS_HI_xor_CCRS_STAMP_xor_PRC_CDO_xor_STATIC_GAS_xor_ADDRESS_HI_xor_CALL_DATA_SIZE has not been filled"); } if (!filled.get(132)) { @@ -7415,7 +7421,7 @@ public Trace validateRow() { if (!filled.get(104)) { throw new IllegalStateException( - "hub.CODE_FRAGMENT_INDEX_xor_ACCOUNT_DEPLOYMENT_NUMBER_xor_EXP_INST_xor_PRC_CALLER_GAS_xor_DEPLOYMENT_NUMBER_xor_COINBASE_ADDRESS_HI has not been filled"); + "hub.CODE_FRAGMENT_INDEX_xor_ACCOUNT_DEPLOYMENT_NUMBER_xor_EXP_INST_xor_PRC_CDS_xor_DEPLOYMENT_NUMBER_xor_COINBASE_ADDRESS_HI has not been filled"); } if (!filled.get(136)) { @@ -7440,12 +7446,12 @@ public Trace validateRow() { if (!filled.get(106)) { throw new IllegalStateException( - "hub.CODE_SIZE_NEW_xor_BYTE_CODE_CODE_FRAGMENT_INDEX_xor_MMU_EXO_SUM_xor_PRC_CDS_xor_INIT_CODE_SIZE has not been filled"); + "hub.CODE_SIZE_NEW_xor_BYTE_CODE_CODE_FRAGMENT_INDEX_xor_MMU_EXO_SUM_xor_PRC_RAO_xor_INIT_CODE_SIZE has not been filled"); } if (!filled.get(105)) { throw new IllegalStateException( - "hub.CODE_SIZE_xor_BYTE_CODE_ADDRESS_HI_xor_MMU_AUX_ID_xor_PRC_CDO_xor_DEPLOYMENT_NUMBER_INFTY_xor_FROM_ADDRESS_HI has not been filled"); + "hub.CODE_SIZE_xor_BYTE_CODE_ADDRESS_HI_xor_MMU_AUX_ID_xor_PRC_RAC_xor_DEPLOYMENT_NUMBER_INFTY_xor_FROM_ADDRESS_HI has not been filled"); } if (!filled.get(3)) { @@ -7504,17 +7510,17 @@ public Trace validateRow() { if (!filled.get(108)) { throw new IllegalStateException( - "hub.DEPLOYMENT_NUMBER_INFTY_xor_BYTE_CODE_DEPLOYMENT_STATUS_xor_MMU_PHASE_xor_PRC_RAO has not been filled"); + "hub.DEPLOYMENT_NUMBER_INFTY_xor_BYTE_CODE_DEPLOYMENT_STATUS_xor_MMU_PHASE has not been filled"); } if (!filled.get(109)) { throw new IllegalStateException( - "hub.DEPLOYMENT_NUMBER_NEW_xor_CALLER_ADDRESS_HI_xor_MMU_REF_OFFSET_xor_PRC_RETURN_GAS has not been filled"); + "hub.DEPLOYMENT_NUMBER_NEW_xor_CALLER_ADDRESS_HI_xor_MMU_REF_OFFSET has not been filled"); } if (!filled.get(107)) { throw new IllegalStateException( - "hub.DEPLOYMENT_NUMBER_xor_BYTE_CODE_DEPLOYMENT_NUMBER_xor_MMU_INST_xor_PRC_RAC_xor_TO_ADDRESS_HI has not been filled"); + "hub.DEPLOYMENT_NUMBER_xor_BYTE_CODE_DEPLOYMENT_NUMBER_xor_MMU_INST_xor_TO_ADDRESS_HI has not been filled"); } if (!filled.get(49)) { @@ -7699,11 +7705,12 @@ public Trace validateRow() { if (!filled.get(124)) { throw new IllegalStateException( - "hub.NONCE_NEW_xor_STP_GAS_PAID_OUT_OF_POCKET_xor_GAS_INITIALLY_AVAILABLE has not been filled"); + "hub.NONCE_NEW_xor_STP_GAS_PAID_OUT_OF_POCKET_xor_PRC_CALLER_GAS_xor_GAS_INITIALLY_AVAILABLE has not been filled"); } if (!filled.get(123)) { - throw new IllegalStateException("hub.NONCE_xor_STP_GAS_MXP_xor_BASEFEE has not been filled"); + throw new IllegalStateException( + "hub.NONCE_xor_STP_GAS_MXP_xor_PRC_CALLEE_GAS_xor_BASEFEE has not been filled"); } if (!filled.get(152)) { @@ -8006,7 +8013,7 @@ public Trace validateRow() { if (!filled.get(125)) { throw new IllegalStateException( - "hub.STP_GAS_UPFRONT_GAS_COST_xor_GAS_LEFTOVER has not been filled"); + "hub.STP_GAS_UPFRONT_GAS_COST_xor_PRC_RETURN_GAS_xor_GAS_LEFTOVER has not been filled"); } if (!filled.get(163)) { @@ -8089,9 +8096,9 @@ public Trace fillAndValidateRow() { } if (!filled.get(103)) { - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize .position( - addressHiXorAccountAddressHiXorCcrsStampXorPrcCalleeGasXorStaticGasXorAddressHiXorCallDataSize + addressHiXorAccountAddressHiXorCcrsStampXorPrcCdoXorStaticGasXorAddressHiXorCallDataSize .position() + 4); } @@ -8169,9 +8176,9 @@ public Trace fillAndValidateRow() { } if (!filled.get(104)) { - codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCallerGasXorDeploymentNumberXorCoinbaseAddressHi + codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCdsXorDeploymentNumberXorCoinbaseAddressHi .position( - codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCallerGasXorDeploymentNumberXorCoinbaseAddressHi + codeFragmentIndexXorAccountDeploymentNumberXorExpInstXorPrcCdsXorDeploymentNumberXorCoinbaseAddressHi .position() + 4); } @@ -8198,15 +8205,15 @@ public Trace fillAndValidateRow() { } if (!filled.get(106)) { - codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcCdsXorInitCodeSize.position( - codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcCdsXorInitCodeSize.position() + codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcRaoXorInitCodeSize.position( + codeSizeNewXorByteCodeCodeFragmentIndexXorMmuExoSumXorPrcRaoXorInitCodeSize.position() + 4); } if (!filled.get(105)) { - codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcCdoXorDeploymentNumberInftyXorFromAddressHi + codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcRacXorDeploymentNumberInftyXorFromAddressHi .position( - codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcCdoXorDeploymentNumberInftyXorFromAddressHi + codeSizeXorByteCodeAddressHiXorMmuAuxIdXorPrcRacXorDeploymentNumberInftyXorFromAddressHi .position() + 4); } @@ -8266,19 +8273,18 @@ public Trace fillAndValidateRow() { } if (!filled.get(108)) { - deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhaseXorPrcRao.position( - deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhaseXorPrcRao.position() + 4); + deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhase.position( + deploymentNumberInftyXorByteCodeDeploymentStatusXorMmuPhase.position() + 4); } if (!filled.get(109)) { - deploymentNumberNewXorCallerAddressHiXorMmuRefOffsetXorPrcReturnGas.position( - deploymentNumberNewXorCallerAddressHiXorMmuRefOffsetXorPrcReturnGas.position() + 4); + deploymentNumberNewXorCallerAddressHiXorMmuRefOffset.position( + deploymentNumberNewXorCallerAddressHiXorMmuRefOffset.position() + 4); } if (!filled.get(107)) { - deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorPrcRacXorToAddressHi.position( - deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorPrcRacXorToAddressHi.position() - + 4); + deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorToAddressHi.position( + deploymentNumberXorByteCodeDeploymentNumberXorMmuInstXorToAddressHi.position() + 4); } if (!filled.get(49)) { @@ -8487,12 +8493,13 @@ public Trace fillAndValidateRow() { } if (!filled.get(124)) { - nonceNewXorStpGasPaidOutOfPocketXorGasInitiallyAvailable.position( - nonceNewXorStpGasPaidOutOfPocketXorGasInitiallyAvailable.position() + 8); + nonceNewXorStpGasPaidOutOfPocketXorPrcCallerGasXorGasInitiallyAvailable.position( + nonceNewXorStpGasPaidOutOfPocketXorPrcCallerGasXorGasInitiallyAvailable.position() + 8); } if (!filled.get(123)) { - nonceXorStpGasMxpXorBasefee.position(nonceXorStpGasMxpXorBasefee.position() + 8); + nonceXorStpGasMxpXorPrcCalleeGasXorBasefee.position( + nonceXorStpGasMxpXorPrcCalleeGasXorBasefee.position() + 8); } if (!filled.get(152)) { @@ -8794,8 +8801,8 @@ public Trace fillAndValidateRow() { } if (!filled.get(125)) { - stpGasUpfrontGasCostXorGasLeftover.position( - stpGasUpfrontGasCostXorGasLeftover.position() + 8); + stpGasUpfrontGasCostXorPrcReturnGasXorGasLeftover.position( + stpGasUpfrontGasCostXorPrcReturnGasXorGasLeftover.position() + 8); } if (!filled.get(163)) { diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/common/CommonFragmentValues.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/common/CommonFragmentValues.java index f335d77a18..03d38c928c 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/common/CommonFragmentValues.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/common/CommonFragmentValues.java @@ -257,9 +257,6 @@ public long computeGasNext(short exceptions) { 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 -> gasAfterDeductingCost; case CREATE -> gasAfterDeductingCost; diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/StpCall.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/StpCall.java index 9abc2d4427..8425d41694 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/StpCall.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/StpCall.java @@ -59,16 +59,17 @@ public class StpCall implements TraceSubFragment { @EqualsAndHashCode.Include long gasPaidOutOfPocket; @EqualsAndHashCode.Include long stipend; - public StpCall(Hub hub, long memoryExpansionGas) { - this.memoryExpansionGas = memoryExpansionGas; + public StpCall(Hub hub, MessageFrame frame, long memoryExpansionGas) { this.opCode = hub.opCode(); - this.gasActual = hub.messageFrame().getRemainingGas(); checkArgument(this.opCode.isCall() || this.opCode.isCreate()); + this.memoryExpansionGas = memoryExpansionGas; + this.gasActual = frame.getRemainingGas(); + if (this.opCode.isCall()) { this.stpCallForCalls(hub); } else { - this.stpCallForCreates(hub); + this.stpCallForCreates(frame); } } @@ -114,8 +115,7 @@ private long gasPaidOutOfPocketForCalls() { } } - private void stpCallForCreates(Hub hub) { - MessageFrame frame = hub.messageFrame(); + private void stpCallForCreates(MessageFrame frame) { this.gas = ZERO; // irrelevant this.value = EWord.of(frame.getStackItem(0)); @@ -132,7 +132,7 @@ private long computeGasPaidOutOfPocketForCreates() { return 0; } else { long gasMinusUpfrontCost = gasActual - upfrontGasCost; - return gasMinusUpfrontCost - (gasMinusUpfrontCost >> 6); + return gasMinusUpfrontCost - gasMinusUpfrontCost / 64; } } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/scenario/CreateScenarioFragment.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/scenario/CreateScenarioFragment.java index 3a249c755a..85bfbbb22b 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/scenario/CreateScenarioFragment.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/scenario/CreateScenarioFragment.java @@ -32,7 +32,16 @@ public enum CreateScenario { CREATE_NON_EMPTY_INIT_CODE_FAILURE_WILL_REVERT, CREATE_NON_EMPTY_INIT_CODE_FAILURE_WONT_REVERT, CREATE_NON_EMPTY_INIT_CODE_SUCCESS_WILL_REVERT, - CREATE_NON_EMPTY_INIT_CODE_SUCCESS_WONT_REVERT + CREATE_NON_EMPTY_INIT_CODE_SUCCESS_WONT_REVERT; + + public boolean isAnyOf(CreateScenario... createScenarios) { + for (CreateScenario createScenario : createScenarios) { + if (createScenario.equals(this)) { + return true; + } + } + return false; + } } @Setter @Getter private CreateScenario scenario; diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/scenario/PrecompileScenarioFragment.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/scenario/PrecompileScenarioFragment.java index b9af65d2c8..546069e4dd 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/scenario/PrecompileScenarioFragment.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/scenario/PrecompileScenarioFragment.java @@ -28,6 +28,7 @@ import net.consensys.linea.zktracer.module.hub.Trace; import net.consensys.linea.zktracer.module.hub.fragment.TraceFragment; import net.consensys.linea.zktracer.module.hub.section.call.precompileSubsection.PrecompileSubsection; +import org.apache.tuweni.bytes.Bytes; import org.hyperledger.besu.datatypes.Address; @Getter @@ -169,9 +170,9 @@ public Trace trace(Trace trace) { .pScenarioPrcSuccessCallerWontRevert(scenario == PRC_SUCCESS_WONT_REVERT) .pScenarioPrcFailureKnownToHub(scenario == PRC_FAILURE_KNOWN_TO_HUB) .pScenarioPrcFailureKnownToRam(scenario == PRC_FAILURE_KNOWN_TO_RAM) - .pScenarioPrcCallerGas(precompileSubSection.callerGas()) - .pScenarioPrcCalleeGas(precompileSubSection.calleeGas()) - .pScenarioPrcReturnGas(precompileSubSection.returnGas()) + .pScenarioPrcCallerGas(Bytes.ofUnsignedLong(precompileSubSection.callerGas())) + .pScenarioPrcCalleeGas(Bytes.ofUnsignedLong(precompileSubSection.calleeGas())) + .pScenarioPrcReturnGas(Bytes.ofUnsignedLong(precompileSubSection.returnGas())) .pScenarioPrcCdo(precompileSubSection.callDataOffset()) .pScenarioPrcCds(precompileSubSection.callDataSize()) .pScenarioPrcRao(precompileSubSection.returnAtOffset()) diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/CreateSection.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/CreateSection.java index 5848f62a24..8eb2960104 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/CreateSection.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/CreateSection.java @@ -16,16 +16,7 @@ package net.consensys.linea.zktracer.module.hub.section; import static com.google.common.base.Preconditions.*; -import static net.consensys.linea.zktracer.module.hub.fragment.scenario.CreateScenarioFragment.CreateScenario.CREATE_ABORT; -import static net.consensys.linea.zktracer.module.hub.fragment.scenario.CreateScenarioFragment.CreateScenario.CREATE_EMPTY_INIT_CODE_WILL_REVERT; -import static net.consensys.linea.zktracer.module.hub.fragment.scenario.CreateScenarioFragment.CreateScenario.CREATE_EMPTY_INIT_CODE_WONT_REVERT; -import static net.consensys.linea.zktracer.module.hub.fragment.scenario.CreateScenarioFragment.CreateScenario.CREATE_EXCEPTION; -import static net.consensys.linea.zktracer.module.hub.fragment.scenario.CreateScenarioFragment.CreateScenario.CREATE_FAILURE_CONDITION_WILL_REVERT; -import static net.consensys.linea.zktracer.module.hub.fragment.scenario.CreateScenarioFragment.CreateScenario.CREATE_FAILURE_CONDITION_WONT_REVERT; -import static net.consensys.linea.zktracer.module.hub.fragment.scenario.CreateScenarioFragment.CreateScenario.CREATE_NON_EMPTY_INIT_CODE_FAILURE_WILL_REVERT; -import static net.consensys.linea.zktracer.module.hub.fragment.scenario.CreateScenarioFragment.CreateScenario.CREATE_NON_EMPTY_INIT_CODE_FAILURE_WONT_REVERT; -import static net.consensys.linea.zktracer.module.hub.fragment.scenario.CreateScenarioFragment.CreateScenario.CREATE_NON_EMPTY_INIT_CODE_SUCCESS_WILL_REVERT; -import static net.consensys.linea.zktracer.module.hub.fragment.scenario.CreateScenarioFragment.CreateScenario.CREATE_NON_EMPTY_INIT_CODE_SUCCESS_WONT_REVERT; +import static net.consensys.linea.zktracer.module.hub.fragment.scenario.CreateScenarioFragment.CreateScenario.*; import static net.consensys.linea.zktracer.opcode.OpCode.*; import static net.consensys.linea.zktracer.types.AddressUtils.getDeploymentAddress; @@ -47,6 +38,7 @@ import net.consensys.linea.zktracer.module.hub.signals.AbortingConditions; import net.consensys.linea.zktracer.module.hub.signals.Exceptions; import net.consensys.linea.zktracer.module.shakiradata.ShakiraDataOperation; +import net.consensys.linea.zktracer.opcode.OpCode; import net.consensys.linea.zktracer.runtime.callstack.CallFrame; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.units.bigints.UInt256; @@ -67,17 +59,18 @@ public class CreateSection extends TraceSection ContextReEntryDefer, PostTransactionDefer { - private Address creatorAddress; - private Address createeAddress; - final ImcFragment imcFragment; + private final Address creatorAddress; + private final Address createeAddress; + + private final AccountFragment.AccountFragmentFactory accountFragmentFactory; // Just before create private AccountSnapshot preOpcodeCreatorSnapshot; private AccountSnapshot preOpcodeCreateeSnapshot; // Just at the entry child frame - private AccountSnapshot childEntryCreatorSnapshot; - private AccountSnapshot childEntryCreateeSnapshot; + private AccountSnapshot childContextEntryCreatorSnapshot; + private AccountSnapshot childContextEntryCreateeSnapshot; // Just at the entry child frame private AccountSnapshot reEntryCreatorSnapshot; @@ -85,110 +78,96 @@ public class CreateSection extends TraceSection private RlpAddrSubFragment rlpAddrSubFragment; - // row i+0 - final CreateScenarioFragment scenarioFragment; - // row i+? - private ContextFragment finalContextFragment; + final CreateScenarioFragment scenarioFragment; // row i + 0 + final ContextFragment currentContextFragment; // row i + 1 + final ImcFragment imcFragment; // row i + 2 + private ContextFragment finalContextFragment; // row i+? private boolean requiresRomLex; private Wei value; + private boolean success = false; // TODO: according to our preliminary conclusion in issue #866 // CREATE's that raise a failure condition _do spawn a child context_. public CreateSection(Hub hub, MessageFrame frame) { super(hub, maxNumberOfLines(hub.pch().exceptions(), hub.pch().abortingConditions())); - final short exceptions = hub.pch().exceptions(); + accountFragmentFactory = hub.factories().accountFragment(); - this.addStack(hub); + creatorAddress = frame.getRecipientAddress(); + createeAddress = getDeploymentAddress(frame); + value = Wei.of(UInt256.fromBytes(frame.getStackItem(0))); - // row i+ 0 scenarioFragment = new CreateScenarioFragment(); - this.addFragment(scenarioFragment); + currentContextFragment = ContextFragment.readCurrentContextData(hub); + imcFragment = ImcFragment.empty(hub); - // row i + 1 - final ContextFragment currentContextFragment = ContextFragment.readCurrentContextData(hub); + this.addStack(hub); + this.addFragment(scenarioFragment); this.addFragment(currentContextFragment); - - // row: i + 2 - imcFragment = ImcFragment.empty(hub); this.addFragment(imcFragment); + refineCreateScenario(hub, frame); + scheduleSection(hub); + + final short exceptions = hub.pch().exceptions(); + // STATICX case - // Note: in the static case this imc fragment remains empty if (Exceptions.staticFault(exceptions)) { - scenarioFragment.setScenario(CREATE_EXCEPTION); return; } + // MXPX case final MxpCall mxpCall = new MxpCall(hub); imcFragment.callMxp(mxpCall); checkArgument(mxpCall.mxpx == Exceptions.memoryExpansionException(exceptions)); - - // MXPX case if (mxpCall.mxpx) { - scenarioFragment.setScenario(CREATE_EXCEPTION); return; } - final StpCall stpCall = new StpCall(hub, mxpCall.getGasMxp()); + // OOGX case + final StpCall stpCall = new StpCall(hub, frame, mxpCall.getGasMxp()); imcFragment.callStp(stpCall); - checkArgument(stpCall.outOfGasException() == Exceptions.outOfGasException(exceptions)); - - // OOGX case if (Exceptions.outOfGasException(exceptions)) { - scenarioFragment.setScenario(CREATE_EXCEPTION); return; } // The CREATE(2) is now unexceptional + ///////////////////////////////////// + checkArgument(Exceptions.none(exceptions)); hub.currentFrame().childSpanningSection(this); final CreateOobCall oobCall = new CreateOobCall(); imcFragment.callOob(oobCall); - final AbortingConditions aborts = hub.pch().abortingConditions().snapshot(); - checkArgument(oobCall.isAbortingCondition() == aborts.any()); - - final CallFrame callFrame = hub.currentFrame(); + preOpcodeCreatorSnapshot = + AccountSnapshot.canonical(hub, frame.getWorldUpdater(), creatorAddress); + preOpcodeCreateeSnapshot = + AccountSnapshot.canonical(hub, frame.getWorldUpdater(), createeAddress); - creatorAddress = frame.getRecipientAddress(); - preOpcodeCreatorSnapshot = AccountSnapshot.canonical(hub, creatorAddress); - - createeAddress = getDeploymentAddress(frame); - preOpcodeCreateeSnapshot = AccountSnapshot.canonical(hub, createeAddress); + final boolean aborts = scenarioFragment.getScenario() == CREATE_ABORT; + final boolean failedCreate = + scenarioFragment.getScenario() == CREATE_FAILURE_CONDITION_WONT_REVERT; + final boolean emptyInitCode = + scenarioFragment.getScenario() == CREATE_EMPTY_INIT_CODE_WONT_REVERT; - if (aborts.any()) { - scenarioFragment.setScenario(CREATE_ABORT); - this.finishAbort(hub); - hub.defers().scheduleForPostExecution(this); + checkArgument(oobCall.isAbortingCondition() == aborts); + if (aborts) { + this.traceAbort(hub); return; } - // The CREATE(2) is now unexceptional and unaborted - checkArgument(aborts.none()); - hub.defers().scheduleForContextEntry(this); // when we add the two account fragments - hub.defers().scheduleForPostRollback(this, hub.currentFrame()); // in case of Rollback - hub.defers().scheduleForPostTransaction(this); // when we add the last context row + // The CREATE(2) is now unexceptional, unaborted + //////////////////////////////////////////////// rlpAddrSubFragment = RlpAddrSubFragment.makeFragment(hub, createeAddress); - final Optional deploymentAccount = - Optional.ofNullable(frame.getWorldUpdater().get(createeAddress)); - final boolean createdAddressHasNonZeroNonce = - deploymentAccount.map(a -> a.getNonce() != 0).orElse(false); - final boolean createdAddressHasNonEmptyCode = - deploymentAccount.map(AccountState::hasCode).orElse(false); - - final boolean failedCreate = createdAddressHasNonZeroNonce || createdAddressHasNonEmptyCode; - final boolean emptyInitCode = hub.transients().op().initCodeSegment().isEmpty(); - final long offset = Words.clampedToLong(frame.getStackItem(1)); final long size = Words.clampedToLong(frame.getStackItem(2)); // Trigger MMU & SHAKIRA to hash the (non-empty) InitCode of CREATE2 - even for failed CREATE2 - if (hub.opCode() == CREATE2 && !emptyInitCode) { + if (nontrivialCreate2(hub.opCode(), size)) { final Bytes create2InitCode = frame.shadowReadMemory(offset, size); final MmuCall mmuCall = MmuCall.create2(hub, create2InitCode, failedCreate); @@ -201,32 +180,25 @@ public CreateSection(Hub hub, MessageFrame frame) { writeHashInfoResult(shakiraDataOperation.result()); } - value = failedCreate ? Wei.ZERO : Wei.of(UInt256.fromBytes(frame.getStackItem(0))); - if (failedCreate) { - finalContextFragment = ContextFragment.nonExecutionProvidesEmptyReturnData(hub); - scenarioFragment.setScenario(CREATE_FAILURE_CONDITION_WONT_REVERT); + finalContextFragmentSquashesReturnData(hub); + commonValues.payGasPaidOutOfPocket(hub); hub.failureConditionForCreates = true; return; } if (emptyInitCode) { - finalContextFragment = ContextFragment.nonExecutionProvidesEmptyReturnData(hub); - scenarioFragment.setScenario(CREATE_EMPTY_INIT_CODE_WONT_REVERT); + success = true; + finalContextFragmentSquashesReturnData(hub); hub.transients().conflation().deploymentInfo().newDeploymentSansExecutionAt(createeAddress); return; } - // Finally, non-exceptional, non-aborting, non-failing, non-emptyInitCode create - //////////////////////////////////////////////////////////////////////////////// - - // we capture revert information about the child context: CCSR and CCRS - hub.defers().scheduleForContextReEntry(imcFragment, hub.currentFrame()); + // unexceptional, unaborted, non-failing, non-emptyInitCode CREATE(2) + ///////////////////////////////////////////////////////////////////// - // The current execution context pays (63/64)ths of it current gas to the child context + // we charge for the gas paid out of pocket commonValues.payGasPaidOutOfPocket(hub); - hub.defers() - .scheduleForContextReEntry(this, callFrame); // To get the success bit of the CREATE(2) requiresRomLex = true; hub.romLex().callRomLex(frame); @@ -246,30 +218,27 @@ public CreateSection(Hub hub, MessageFrame frame) { @Override public void resolveUponContextEntry(Hub hub, MessageFrame frame) { - childEntryCreatorSnapshot = - AccountSnapshot.canonical(hub, preOpcodeCreatorSnapshot.address()) + childContextEntryCreatorSnapshot = + AccountSnapshot.canonical(hub, frame.getWorldUpdater(), preOpcodeCreatorSnapshot.address()) // .raiseNonceByOne() // the nonce was already raised .decrementBalanceBy(value); - childEntryCreateeSnapshot = - AccountSnapshot.canonical(hub, preOpcodeCreateeSnapshot.address()) + childContextEntryCreateeSnapshot = + AccountSnapshot.canonical(hub, frame.getWorldUpdater(), preOpcodeCreateeSnapshot.address()) .raiseNonceByOne() .incrementBalanceBy(value); - final AccountFragment.AccountFragmentFactory accountFragmentFactory = - hub.factories().accountFragment(); - final AccountFragment creatorAccountFragment = accountFragmentFactory.make( preOpcodeCreatorSnapshot, - childEntryCreatorSnapshot, + childContextEntryCreatorSnapshot, DomSubStampsSubFragment.standardDomSubStamps(this.hubStamp(), 0)); creatorAccountFragment.rlpAddrSubFragment(rlpAddrSubFragment); final AccountFragment createeAccountFragment = accountFragmentFactory.makeWithTrm( preOpcodeCreateeSnapshot, - childEntryCreateeSnapshot, - preOpcodeCreateeSnapshot.address().trimLeadingZeros(), + childContextEntryCreateeSnapshot, + createeAddress.trimLeadingZeros(), DomSubStampsSubFragment.standardDomSubStamps(this.hubStamp(), 1)); createeAccountFragment.requiresRomlex(requiresRomLex); @@ -279,73 +248,150 @@ public void resolveUponContextEntry(Hub hub, MessageFrame frame) { @Override public void resolveAtContextReEntry(Hub hub, CallFrame frame) { - final boolean deploymentSuccess = !frame.frame().getStackItem(0).isZero(); + success = !frame.frame().getStackItem(0).isZero(); + + CreateScenarioFragment.CreateScenario scenario = scenarioFragment.getScenario(); + + switch (scenario) { + case CREATE_FAILURE_CONDITION_WONT_REVERT -> { + checkState(!success); + reEntryCreatorSnapshot = preOpcodeCreatorSnapshot.deepCopy().raiseNonceByOne(); + reEntryCreateeSnapshot = preOpcodeCreateeSnapshot.deepCopy().turnOnWarmth(); + final AccountFragment firstCreatorFragment = + accountFragmentFactory.make( + preOpcodeCreatorSnapshot, + reEntryCreatorSnapshot, + DomSubStampsSubFragment.standardDomSubStamps(this.hubStamp(), 0)); + firstCreatorFragment.rlpAddrSubFragment(rlpAddrSubFragment); + + final AccountFragment firstCreateeFragment = + accountFragmentFactory.makeWithTrm( + preOpcodeCreateeSnapshot, + reEntryCreateeSnapshot, + createeAddress.trimLeadingZeros(), + DomSubStampsSubFragment.standardDomSubStamps(this.hubStamp(), 1)); + + this.addFragments(firstCreatorFragment, firstCreateeFragment); + return; + } + case CREATE_EMPTY_INIT_CODE_WONT_REVERT -> { + checkState(success); + reEntryCreatorSnapshot = + AccountSnapshot.canonical(hub, frame.frame().getWorldUpdater(), creatorAddress); + reEntryCreateeSnapshot = + AccountSnapshot.canonical(hub, frame.frame().getWorldUpdater(), createeAddress); + final AccountFragment firstCreatorFragment = + accountFragmentFactory.make( + preOpcodeCreatorSnapshot, + reEntryCreatorSnapshot, + DomSubStampsSubFragment.standardDomSubStamps(this.hubStamp(), 0)); + firstCreatorFragment.rlpAddrSubFragment(rlpAddrSubFragment); + + final AccountFragment firstCreateeFragment = + accountFragmentFactory.makeWithTrm( + preOpcodeCreateeSnapshot, + reEntryCreateeSnapshot, + createeAddress.trimLeadingZeros(), + DomSubStampsSubFragment.standardDomSubStamps(this.hubStamp(), 1)); + + this.addFragments(firstCreatorFragment, firstCreateeFragment); + return; + } + default -> {} + } - if (deploymentSuccess) { + if (success) { scenarioFragment.setScenario(CREATE_NON_EMPTY_INIT_CODE_SUCCESS_WONT_REVERT); - } else { - scenarioFragment.setScenario(CREATE_NON_EMPTY_INIT_CODE_FAILURE_WONT_REVERT); - - reEntryCreatorSnapshot = AccountSnapshot.canonical(hub, preOpcodeCreatorSnapshot.address()); - reEntryCreateeSnapshot = AccountSnapshot.canonical(hub, preOpcodeCreateeSnapshot.address()); + return; + } - final AccountFragment.AccountFragmentFactory accountFragmentFactory = - hub.factories().accountFragment(); + reEntryCreatorSnapshot = childContextEntryCreatorSnapshot.deepCopy().incrementBalanceBy(value); + reEntryCreateeSnapshot = + childContextEntryCreateeSnapshot + .deepCopy() + .decrementBalanceBy(value) + .deploymentStatus(false) + .deploymentNumber(hub.deploymentNumberOf(createeAddress)) + .nonce(0); - final int childRevertStamp = hub.getLastChildCallFrame(frame).revertStamp(); + final int childRevertStamp = hub.getLastChildCallFrame(frame).revertStamp(); - final AccountFragment undoCreator = - accountFragmentFactory.make( - childEntryCreatorSnapshot, - reEntryCreatorSnapshot, - DomSubStampsSubFragment.revertsWithChildDomSubStamps( - this.hubStamp(), childRevertStamp, 2)); + final AccountFragment undoCreator = + accountFragmentFactory.make( + childContextEntryCreatorSnapshot, + reEntryCreatorSnapshot, + DomSubStampsSubFragment.revertsWithChildDomSubStamps( + this.hubStamp(), childRevertStamp, 0)); - final AccountFragment undoCreatee = - accountFragmentFactory.make( - childEntryCreateeSnapshot, - reEntryCreateeSnapshot, - DomSubStampsSubFragment.revertsWithChildDomSubStamps( - this.hubStamp(), childRevertStamp, 3)); + final AccountFragment undoCreatee = + accountFragmentFactory.make( + childContextEntryCreateeSnapshot, + reEntryCreateeSnapshot, + DomSubStampsSubFragment.revertsWithChildDomSubStamps( + this.hubStamp(), childRevertStamp, 1)); - this.addFragments(undoCreator, undoCreatee); - } + this.addFragments(undoCreator, undoCreatee); } @Override public void resolveUponRollback(Hub hub, MessageFrame messageFrame, CallFrame callFrame) { - scenarioFragment.setScenario(switchToRevert(scenarioFragment.getScenario())); - final AccountFragment.AccountFragmentFactory accountFragmentFactory = - hub.factories().accountFragment(); + final CreateScenarioFragment.CreateScenario scenario = scenarioFragment.getScenario(); + checkState( + scenario.isAnyOf( + CREATE_FAILURE_CONDITION_WONT_REVERT, + CREATE_EMPTY_INIT_CODE_WONT_REVERT, + CREATE_NON_EMPTY_INIT_CODE_SUCCESS_WONT_REVERT, + CREATE_NON_EMPTY_INIT_CODE_FAILURE_WONT_REVERT)); + scenarioFragment.setScenario(switchToRevertingScenario(scenario)); final int revertStamp = callFrame.revertStamp(); + + switch (scenario) { + case CREATE_FAILURE_CONDITION_WONT_REVERT, CREATE_EMPTY_INIT_CODE_WONT_REVERT -> { + final AccountFragment undoCreator = + accountFragmentFactory.make( + reEntryCreatorSnapshot.deepCopy().setDeploymentInfo(hub), + preOpcodeCreatorSnapshot.deepCopy().setDeploymentInfo(hub), + DomSubStampsSubFragment.revertWithCurrentDomSubStamps( + this.hubStamp(), revertStamp, 0)); + + final AccountFragment undoCreatee = + accountFragmentFactory.make( + reEntryCreateeSnapshot.deepCopy().setDeploymentInfo(hub), + preOpcodeCreateeSnapshot.deepCopy().setDeploymentInfo(hub), + DomSubStampsSubFragment.revertWithCurrentDomSubStamps( + this.hubStamp(), revertStamp, 1)); + this.addFragments(undoCreator, undoCreatee); + return; + } + // case CREATE_NON_EMPTY_INIT_CODE_SUCCESS_WONT_REVERT -> + // revertNonEmptyInitCodeDeploymentSuccessCase(); + // case CREATE_NON_EMPTY_INIT_CODE_SUCCESS_WILL_REVERT -> + // revertNonEmptyInitCodeDeploymentFailureCase(); + default -> {} + } + final boolean firstUndo = scenarioFragment.getScenario() != CREATE_NON_EMPTY_INIT_CODE_FAILURE_WILL_REVERT; final AccountFragment undoCreator = accountFragmentFactory.make( - firstUndo ? childEntryCreatorSnapshot : reEntryCreatorSnapshot, - preOpcodeCreatorSnapshot, + firstUndo ? childContextEntryCreatorSnapshot : reEntryCreatorSnapshot, + preOpcodeCreatorSnapshot.deepCopy().setDeploymentInfo(hub), DomSubStampsSubFragment.revertWithCurrentDomSubStamps( - this.hubStamp(), revertStamp, firstUndo ? 2 : 4)); + this.hubStamp(), revertStamp, firstUndo ? 0 : 2)); final AccountFragment undoCreatee = accountFragmentFactory.make( - firstUndo ? childEntryCreateeSnapshot : reEntryCreateeSnapshot, - preOpcodeCreateeSnapshot, + firstUndo ? childContextEntryCreateeSnapshot : reEntryCreateeSnapshot, + preOpcodeCreateeSnapshot.deepCopy().setDeploymentInfo(hub), DomSubStampsSubFragment.revertWithCurrentDomSubStamps( - this.hubStamp(), revertStamp, firstUndo ? 3 : 5)); + this.hubStamp(), revertStamp, firstUndo ? 1 : 3)); this.addFragments(undoCreator, undoCreatee); } - @Override - public void resolvePostTransaction( - Hub hub, WorldView state, Transaction tx, boolean isSuccessful) { - addFragment(finalContextFragment); - } - private static short maxNumberOfLines(final short exceptions, final AbortingConditions abort) { if (Exceptions.any(exceptions)) { return 6; @@ -356,22 +402,23 @@ private static short maxNumberOfLines(final short exceptions, final AbortingCond return 11; // Note: could be lower for unreverted successful CREATE(s) } - private void finishAbort(final Hub hub) { - final AccountFragment.AccountFragmentFactory accountFragmentFactory = - hub.factories().accountFragment(); + private void traceAbort(final Hub hub) { final AccountFragment creatorAccountFragment = accountFragmentFactory.make( - preOpcodeCreateeSnapshot, - preOpcodeCreateeSnapshot, + preOpcodeCreatorSnapshot, + preOpcodeCreatorSnapshot, DomSubStampsSubFragment.standardDomSubStamps(this.hubStamp(), 0)); - final ContextFragment updatedCurrentContextFragment = - ContextFragment.nonExecutionProvidesEmptyReturnData(hub); + finalContextFragmentSquashesReturnData(hub); + + this.addFragments(creatorAccountFragment, finalContextFragment); + } - this.addFragments(creatorAccountFragment, updatedCurrentContextFragment); + private void finalContextFragmentSquashesReturnData(Hub hub) { + finalContextFragment = ContextFragment.nonExecutionProvidesEmptyReturnData(hub); } - private static CreateScenarioFragment.CreateScenario switchToRevert( + private static CreateScenarioFragment.CreateScenario switchToRevertingScenario( final CreateScenarioFragment.CreateScenario previousScenario) { return switch (previousScenario) { case CREATE_FAILURE_CONDITION_WONT_REVERT -> CREATE_FAILURE_CONDITION_WILL_REVERT; @@ -382,8 +429,69 @@ private static CreateScenarioFragment.CreateScenario switchToRevert( }; } - public boolean isAbortedCreate() { - return scenarioFragment.isAbortedCreate(); + private boolean hasEmptyInitCode(Hub hub) { + return hub.transients().op().initCodeSegment().isEmpty(); + } + + private void refineCreateScenario(Hub hub, MessageFrame frame) { + if (hub.isExceptional()) { + scenarioFragment.setScenario(CREATE_EXCEPTION); + return; + } + + if (hub.pch().abortingConditions().any()) { + scenarioFragment.setScenario(CREATE_ABORT); + return; + } + + if (raisesFailureCondition(frame)) { + scenarioFragment.setScenario(CREATE_FAILURE_CONDITION_WONT_REVERT); + return; + } + + scenarioFragment.setScenario( + hasEmptyInitCode(hub) + ? CREATE_EMPTY_INIT_CODE_WONT_REVERT + : CREATE_NON_EMPTY_INIT_CODE_SUCCESS_WONT_REVERT); + } + + private void scheduleSection(Hub hub) { + CreateScenarioFragment.CreateScenario scenario = scenarioFragment.getScenario(); + final CallFrame currentFrame = hub.currentFrame(); + switch (scenario) { + case CREATE_EXCEPTION -> {} + case CREATE_ABORT -> hub.defers().scheduleForPostExecution(this); // unlatch the stack + case CREATE_FAILURE_CONDITION_WONT_REVERT, CREATE_EMPTY_INIT_CODE_WONT_REVERT -> { + hub.defers().scheduleForContextReEntry(this, currentFrame); + hub.defers().scheduleForPostRollback(this, currentFrame); + hub.defers().scheduleForPostTransaction(this); + } + case CREATE_NON_EMPTY_INIT_CODE_SUCCESS_WONT_REVERT -> { + // The current execution context pays (63/64)ths of it current gas to the child context + // To get the success bit of the CREATE(2) operation + hub.defers().scheduleForContextEntry(this); + hub.defers().scheduleForContextReEntry(this, currentFrame); + hub.defers().scheduleForPostRollback(this, currentFrame); + hub.defers().scheduleForPostTransaction(this); + + // we capture revert information about the child context: CCSR and CCRS + hub.defers().scheduleForContextReEntry(imcFragment, hub.currentFrame()); + } + default -> throw new IllegalStateException( + scenario.name() + " not allowed when defining the schedule"); + } + } + + private boolean raisesFailureCondition(MessageFrame frame) { + + final Optional deploymentAccount = + Optional.ofNullable(frame.getWorldUpdater().get(createeAddress)); + final boolean createdAddressHasNonZeroNonce = + deploymentAccount.map(a -> a.getNonce() != 0).orElse(false); + final boolean createdAddressHasNonEmptyCode = + deploymentAccount.map(AccountState::hasCode).orElse(false); + + return createdAddressHasNonZeroNonce || createdAddressHasNonEmptyCode; } // we unlatched the stack after a CREATE if and only if we don't "contextEnter" the CREATE. @@ -391,7 +499,17 @@ public boolean isAbortedCreate() { @Override public void resolvePostExecution( Hub hub, MessageFrame frame, Operation.OperationResult operationResult) { - checkState(isAbortedCreate()); + checkState(scenarioFragment.isAbortedCreate()); hub.unlatchStack(frame, this); } + + @Override + public void resolvePostTransaction( + Hub hub, WorldView state, Transaction tx, boolean isSuccessful) { + addFragment(finalContextFragment); + } + + private boolean nontrivialCreate2(OpCode opCode, long size) { + return (opCode == CREATE2 && size != 0); + } } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/call/CallSection.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/call/CallSection.java index 7d3b315eec..10337d44b7 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/call/CallSection.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/call/CallSection.java @@ -175,7 +175,7 @@ public CallSection(Hub hub, MessageFrame frame) { return; } - stpCall = new StpCall(hub, mxpCall.gasMxp); + stpCall = new StpCall(hub, frame, mxpCall.gasMxp); firstImcFragment.callStp(stpCall); checkArgument( stpCall.outOfGasException() == Exceptions.outOfGasException(exceptions), diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/halt/SelfdestructSection.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/halt/SelfdestructSection.java index 397c97a514..2e4d5c337c 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/halt/SelfdestructSection.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/section/halt/SelfdestructSection.java @@ -228,10 +228,6 @@ public void resolveUponRollback(Hub hub, MessageFrame messageFrame, CallFrame ca this.addFragment(selfDestroyerUndoingAccountFragment); this.addFragment(recipientUndoingAccountFragment); - ContextFragment squashParentContextReturnData = - ContextFragment.executionProvidesEmptyReturnData(hub); - this.addFragment(squashParentContextReturnData); - selfDestructWasReverted = true; selfdestructScenarioFragment.setScenario( diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/oob/OobOperation.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/oob/OobOperation.java index 737fe1ebe4..75f0a39963 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/oob/OobOperation.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/oob/OobOperation.java @@ -93,6 +93,7 @@ import net.consensys.linea.zktracer.module.hub.fragment.imc.oob.precompiles.ModexpPricingOobCall; import net.consensys.linea.zktracer.module.hub.fragment.imc.oob.precompiles.ModexpXbsOobCall; import net.consensys.linea.zktracer.module.hub.fragment.imc.oob.precompiles.PrecompileCommonOobCall; +import net.consensys.linea.zktracer.module.hub.section.CreateSection; import net.consensys.linea.zktracer.module.mod.Mod; import net.consensys.linea.zktracer.module.wcp.Wcp; import net.consensys.linea.zktracer.opcode.OpCode; @@ -273,8 +274,18 @@ private void populateColumnsForEvmInstruction(MessageFrame frame) { final Address deploymentAddress = getDeploymentAddress(frame); final Account deployedAccount = frame.getWorldUpdater().get(deploymentAddress); - final long nonce = (deployedAccount != null) ? deployedAccount.getNonce() : 0; - final boolean hasCode = deployedAccount != null && deployedAccount.hasCode(); + checkState(hub.currentTraceSection() instanceof CreateSection); + final boolean unexceptional = hub.isUnexceptional(); + final boolean unaborted = hub.pch().abortingConditions().snapshot().none(); + final boolean unexcepationalAndUnabortedCreateAndDeploymentAccountExists = + ((deployedAccount != null) && unexceptional && unaborted); + + final long nonce = + unexcepationalAndUnabortedCreateAndDeploymentAccountExists + ? deployedAccount.getNonce() + : 0; + final boolean hasCode = + unexcepationalAndUnabortedCreateAndDeploymentAccountExists && deployedAccount.hasCode(); final CreateOobCall createOobCall = (CreateOobCall) oobCall; createOobCall.setValue(EWord.of(frame.getStackItem(0))); diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/rlpaddr/RlpAddr.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/rlpaddr/RlpAddr.java index 46980af5f1..3d862b4305 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/rlpaddr/RlpAddr.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/rlpaddr/RlpAddr.java @@ -109,7 +109,13 @@ public void callRlpAddrCreate2(MessageFrame frame, Bytes32 salt, Bytes32 hash) { final Address currentAddress = frame.getRecipientAddress(); final Bytes32 rawCreate2Address = getCreate2RawAddress(currentAddress, salt, hash); final RlpAddrOperation operation = - new RlpAddrOperation(rawCreate2Address, OpCode.CREATE2, currentAddress, salt, hash); + new RlpAddrOperation( + rawCreate2Address, + OpCode.CREATE2, + currentAddress, + salt, + hash, + longToUnsignedBigInteger(frame.getWorldUpdater().get(currentAddress).getNonce())); operations.add(operation); hub.trm().callTrimming(rawCreate2Address); } @@ -118,6 +124,8 @@ private void traceCreate2(int stamp, RlpAddrOperation chunk, Trace trace) { final Bytes rawAddressHi = chunk.rawHash().slice(0, LLARGE); final long depAddressHi = rawAddressHi.slice(12, 4).toLong(); final Bytes depAddressLo = chunk.rawHash().slice(LLARGE, LLARGE); + final BigInteger nonce = chunk.nonce(); + final Bytes nonceBytes = bigIntegerToBytes(nonce); for (int ct = 0; ct <= MAX_CT_CREATE2; ct++) { trace @@ -130,10 +138,11 @@ private void traceCreate2(int stamp, RlpAddrOperation chunk, Trace trace) { .depAddrLo(depAddressLo) .addrHi(chunk.address().slice(0, 4).toLong()) .addrLo(chunk.address().slice(4, LLARGE)) - .saltHi(chunk.salt().orElseThrow().slice(0, LLARGE)) - .saltLo(chunk.salt().orElseThrow().slice(LLARGE, LLARGE)) - .kecHi(chunk.keccak().orElseThrow().slice(0, LLARGE)) - .kecLo(chunk.keccak().orElseThrow().slice(LLARGE, LLARGE)) + .saltHi(chunk.salt().slice(0, LLARGE)) + .saltLo(chunk.salt().slice(LLARGE, LLARGE)) + .kecHi(chunk.keccak().slice(0, LLARGE)) + .kecLo(chunk.keccak().slice(LLARGE, LLARGE)) + .nonce(nonceBytes) .lc(true) .index(UnsignedByte.of(ct)) .counter(UnsignedByte.of(ct)); @@ -149,19 +158,19 @@ private void traceCreate2(int stamp, RlpAddrOperation chunk, Trace trace) { .nBytes(BYTES_LLARGE) .selectorKeccakRes(false); case 2 -> trace - .limb(chunk.salt().orElseThrow().slice(0, LLARGE)) + .limb(chunk.salt().slice(0, LLARGE)) .nBytes(BYTES_LLARGE) .selectorKeccakRes(false); case 3 -> trace - .limb(chunk.salt().orElseThrow().slice(LLARGE, LLARGE)) + .limb(chunk.salt().slice(LLARGE, LLARGE)) .nBytes(BYTES_LLARGE) .selectorKeccakRes(false); case 4 -> trace - .limb(chunk.keccak().orElseThrow().slice(0, LLARGE)) + .limb(chunk.keccak().slice(0, LLARGE)) .nBytes(BYTES_LLARGE) .selectorKeccakRes(false); case 5 -> trace - .limb(chunk.keccak().orElseThrow().slice(LLARGE, LLARGE)) + .limb(chunk.keccak().slice(LLARGE, LLARGE)) .nBytes(BYTES_LLARGE) .selectorKeccakRes(false); } @@ -172,7 +181,7 @@ private void traceCreate2(int stamp, RlpAddrOperation chunk, Trace trace) { } private void traceCreate(int stamp, RlpAddrOperation chunk, Trace trace) { - final BigInteger nonce = chunk.nonce().orElseThrow(); + final BigInteger nonce = chunk.nonce(); Bytes nonceShifted = leftPadTo(bigIntegerToBytes(nonce), recipe1NbRows); Boolean tinyNonZeroNonce = true; diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/rlpaddr/RlpAddrOperation.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/rlpaddr/RlpAddrOperation.java index d54920c1dc..0eda324031 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/rlpaddr/RlpAddrOperation.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/rlpaddr/RlpAddrOperation.java @@ -19,7 +19,6 @@ import static net.consensys.linea.zktracer.module.rlpaddr.Trace.MAX_CT_CREATE2; import java.math.BigInteger; -import java.util.Optional; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -37,20 +36,25 @@ public final class RlpAddrOperation extends ModuleOperation { @EqualsAndHashCode.Include private final Bytes32 rawHash; private final OpCode opCode; - private final Optional nonce; + @EqualsAndHashCode.Include private final BigInteger nonce; private final Address address; - private final Optional salt; - private final Optional keccak; + private final Bytes32 salt; + private final Bytes32 keccak; // CREATE operation public RlpAddrOperation(Bytes32 rawDepAddress, OpCode opCode, BigInteger nonce, Address address) { - this(rawDepAddress, opCode, Optional.of(nonce), address, Optional.empty(), Optional.empty()); + this(rawDepAddress, opCode, nonce, address, Bytes32.ZERO, Bytes32.ZERO); } // CREATE2 operation public RlpAddrOperation( - Bytes32 rawHash, OpCode opCode, Address address, Bytes32 salt, Bytes32 kec) { - this(rawHash, opCode, Optional.empty(), address, Optional.of(salt), Optional.of(kec)); + Bytes32 rawHash, + OpCode opCode, + Address address, + Bytes32 salt, + Bytes32 kec, + BigInteger nonce) { + this(rawHash, opCode, nonce, address, salt, kec); } @Override diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/opcode/gas/projector/Create.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/opcode/gas/projector/Create.java index f4b7ad1332..b53c7a5175 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/opcode/gas/projector/Create.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/opcode/gas/projector/Create.java @@ -52,12 +52,13 @@ public long largestOffset() { @Override public long gasPaidOutOfPocket() { long currentGas = frame.getRemainingGas(); - long gasCost = this.staticGas() + this.memoryExpansion(); + long upfrontGasCost = this.upfrontGasCost(); - if (gasCost > currentGas) { + if (upfrontGasCost > currentGas) { return 0; - } else { - return currentGas - currentGas / 64; } + + long gasMinusUpfront = currentGas - upfrontGasCost; + return gasMinusUpfront - gasMinusUpfront / 64; } } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/opcode/gas/projector/Create2.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/opcode/gas/projector/Create2.java index 52f3ed6a85..ac961ea6a8 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/opcode/gas/projector/Create2.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/opcode/gas/projector/Create2.java @@ -57,13 +57,15 @@ public long linearPerWord() { @Override public long gasPaidOutOfPocket() { long currentGas = frame.getRemainingGas(); - long gasCost = this.staticGas() + this.memoryExpansion() + this.linearPerWord(); + long upfrontGasCost = this.upfrontGasCost(); - if (gasCost > currentGas) { + if (upfrontGasCost > currentGas) { return 0; - } else { - return currentGas - currentGas / 64; } + + final long gasMinusUpfrontGasCost = currentGas - upfrontGasCost; + + return gasMinusUpfrontGasCost - gasMinusUpfrontGasCost / 64; } @Override diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java index 12cb49a107..6f0b353904 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java @@ -62,6 +62,22 @@ public static void simpleCall( program.push(to).push(gas).op(callOpcode); } + public static void callCaller( + BytecodeCompiler program, + OpCode callOpcode, + int gas, + int value, + int cdo, + int cds, + int rao, + int rac) { + program.push(rac).push(rao).push(cds).push(cdo); + if (callOpcode.callHasValueArgument()) { + program.push(value); + } + program.op(CALLER).push(gas).op(callOpcode); + } + public static void appendInsufficientBalanceCall( BytecodeCompiler program, OpCode callOpcode, diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/identity/Tests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/identity/Tests.java index 264b254ce6..3ade253a25 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/identity/Tests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/identity/Tests.java @@ -98,7 +98,7 @@ void nontrivialCallDataIdentityTest(OpCode callOpCode) { * @param program * @param account */ - public void fullCodeCopyOf(BytecodeCompiler program, ToyAccount account) { + public static void fullCodeCopyOf(BytecodeCompiler program, ToyAccount account) { final Address address = account.getAddress(); program .push(address) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/smc/complexTargets/FailureWillRevertTest.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/smc/complexTargets/FailureWillRevertTest.java new file mode 100644 index 0000000000..2560ff8a88 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/smc/complexTargets/FailureWillRevertTest.java @@ -0,0 +1,137 @@ +/* + * 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.callTests.smc.complexTargets; + +import static net.consensys.linea.zktracer.instructionprocessing.utilities.Calls.appendRevert; +import static net.consensys.linea.zktracer.opcode.OpCode.*; + +import net.consensys.linea.testing.BytecodeCompiler; +import net.consensys.linea.testing.BytecodeRunner; +import net.consensys.linea.zktracer.opcode.OpCode; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; + +/** + * The following uses a smart contract that calls itself but stops after one iteration. At which + * point it reverts and its caller reverts, too. + */ +public class FailureWillRevertTest { + + @ParameterizedTest + @EnumSource( + value = OpCode.class, + names = {"CALL", "CALLCODE", "DELEGATECALL", "STATICCALL"}) + public void singleSelfCallFailureWillRevertTest(OpCode callOpCode) { + + BytecodeCompiler program = BytecodeCompiler.newProgram(); + sloadFrom(program, 0x00); + addX(program, 0x01); + duplicateTop(program); + sstoreAt(program, 0x00); + reduceMod2(program); + negateBit(program); + + int currentSize = program.compile().size(); + + jumpToXIfTopIsZero(program, currentSize + 4 + 5); // + 4 + // top is nonzero execution path + appendRevert(program, 13, 9); // + 5 + // top is zero execution path + prepareLanding(program); + selfCall(program, callOpCode, 0xffff, 0x01); + appendRevert(program, 31, 7); + + BytecodeRunner.of(program).run(); + } + + @ParameterizedTest + @EnumSource( + value = OpCode.class, + names = {"CALL", "CALLCODE", "DELEGATECALL", "STATICCALL"}) + public void thirdSelfCallBreaksTriggeringFailureWillRevertTest(OpCode callOpCode) { + + BytecodeCompiler program = BytecodeCompiler.newProgram(); + sloadFrom(program, 0x00); + addX(program, 0x01); + duplicateTop(program); + sstoreAt(program, 0x00); + compareToX(program, 3); + + int currentSize = program.compile().size(); + + jumpToXIfTopIsZero(program, currentSize + 4 + 5); // + 4 + // top is nonzero execution path + appendRevert(program, 13, 9); // + 5 + // top is zero execution path + prepareLanding(program); + selfCall(program, callOpCode, 0xffff, 0x01); + appendRevert(program, 31, 7); + + BytecodeRunner.of(program).run(); + } + + public void sloadFrom(BytecodeCompiler program, int storageKey) { + program.push(storageKey).op(SLOAD); + } + + public void addX(BytecodeCompiler program, int x) { + program.push(x).op(ADD); + } + + public void duplicateTop(BytecodeCompiler program) { + program.op(DUP1); + } + + public void sstoreAt(BytecodeCompiler program, int storageKey) { + program.push(storageKey).op(SSTORE); + } + + public void reduceModX(BytecodeCompiler program, int x) { + program.push(x).op(SWAP1).op(MOD); + } + + public void reduceMod2(BytecodeCompiler program) { + reduceModX(program, 0x02); + } + + public void jumpToXIfTopIsZero(BytecodeCompiler program, int x) { + program.op(ISZERO).push(x).op(JUMPI); + } + + public void prepareLanding(BytecodeCompiler program) { + program.op(JUMPDEST); + } + + public void selfCall(BytecodeCompiler program, OpCode callOpCode, int gas, int value) { + program.push(0x20).push(0x33).push(0x46).push(0x59); // just some random bullshit + if (callOpCode.callHasValueArgument()) { + program.push(value); + } + program.op(ADDRESS).push(gas).op(callOpCode); + } + + /** + * This method assumes that the top of the stack is a boolean value and negates it. + * + * @param program + */ + public void negateBit(BytecodeCompiler program) { + program.push(1).op(XOR); + } + + public void compareToX(BytecodeCompiler program, int x) { + program.push(x).op(EQ); + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/CreateType.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/CreateType.java new file mode 100644 index 0000000000..2129b04df5 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/CreateType.java @@ -0,0 +1,20 @@ +/* + * 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.createTests; + +public enum CreateType { + CREATE, + CREATE2 +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/OffsetParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/OffsetParameter.java new file mode 100644 index 0000000000..1e945e1d96 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/OffsetParameter.java @@ -0,0 +1,24 @@ +/* + * 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.createTests; + +public enum OffsetParameter { + o_ZERO, + o_THREE, + o_SIXTEEN, + o_SIXTEEN_BYTE_INT, + o_THIRTY_TWO_BYTE_INT, + o_MAX, +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/SizeParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/SizeParameter.java new file mode 100644 index 0000000000..e43d5a4dc7 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/SizeParameter.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.createTests; + +public enum SizeParameter { + s_ZERO, + s_TWELVE, // - 3 - 1 + s_THIRTEEN, // - 3 + 0 + s_FOURTEEN, // - 3 + 1 + s_THIRTY_TWO, + s_MSIZE, + s_MAX; + + public boolean isAnyOf(SizeParameter... sizeParameters) { + for (SizeParameter sizeParameter : sizeParameters) { + if (this == sizeParameter) { + return true; + } + } + return false; + } + + public boolean willRaiseException() { + return this.isAnyOf(s_MAX); + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/ValueParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/ValueParameter.java new file mode 100644 index 0000000000..cac86ed7e4 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/ValueParameter.java @@ -0,0 +1,22 @@ +/* + * 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.createTests; + +public enum ValueParameter { + v_ZERO, + v_ONE, + v_SELFBALANCE, + v_SELFBALANCE_PLUS_ONE, +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/WhenToTestParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/WhenToTestParameter.java new file mode 100644 index 0000000000..20ea4d1393 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/WhenToTestParameter.java @@ -0,0 +1,21 @@ +/* + * 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.createTests; + +public enum WhenToTestParameter { + BEFORE, + AFTER, + BEFORE_AND_AFTER +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/abort/Balance.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/abort/Balance.java new file mode 100644 index 0000000000..097a504839 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/abort/Balance.java @@ -0,0 +1,197 @@ +/* + * 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.createTests.abort; + +import static net.consensys.linea.zktracer.instructionprocessing.createTests.SizeParameter.*; +import static net.consensys.linea.zktracer.instructionprocessing.createTests.trivial.RootLevel.*; +import static net.consensys.linea.zktracer.instructionprocessing.utilities.Calls.appendRevert; +import static net.consensys.linea.zktracer.opcode.OpCode.SHA3; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +import net.consensys.linea.testing.BytecodeCompiler; +import net.consensys.linea.zktracer.instructionprocessing.createTests.CreateType; +import net.consensys.linea.zktracer.instructionprocessing.createTests.OffsetParameter; +import net.consensys.linea.zktracer.instructionprocessing.createTests.SizeParameter; +import net.consensys.linea.zktracer.instructionprocessing.createTests.ValueParameter; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class Balance { + + /** The tests below are meant to trigger the "insufficientBalanceAbort" condition. */ + @ParameterizedTest + @MethodSource("rootLevelInsufficientBalanceParameters") + void rootLevelInsufficientBalanceCreateOpcodeTest( + CreateType createType, SizeParameter sizeParameter, OffsetParameter offsetParameter) { + + BytecodeCompiler program = BytecodeCompiler.newProgram(); + + if (sizeParameter == s_MSIZE) { + program.push(513).push(0).op(SHA3); // purely to expand memory to 0 < 512 + 32 bytes + } + + genericCreate( + program, + createType, + ValueParameter.v_SELFBALANCE_PLUS_ONE, + offsetParameter, + sizeParameter, + salt01); + + run(program); + } + + /** + * In the tests {@link #rootLevelAbortThenSuccessCreateTest} we perform two CREATE(2)'s in a row. + * The first one is designed to raise the insufficientBalanceAbort condition, the second one is + * designed to succeed. We optionally REVERT. + */ + @ParameterizedTest + @MethodSource("offsetAndSizeParameters") + void rootLevelAbortThenSuccessCreateTest( + CreateType createType, + OffsetParameter offsetParameter, + SizeParameter sizeParameter, + boolean reverts) { + BytecodeCompiler program = BytecodeCompiler.newProgram(); + genericCreate( + program, + createType, + ValueParameter.v_SELFBALANCE_PLUS_ONE, + offsetParameter, + sizeParameter, + salt01); // aborts + genericCreate( + program, createType, ValueParameter.v_ONE, offsetParameter, sizeParameter, salt01); + + if (reverts) { + appendRevert(program, 2, 13); + } + + run(program); + } + + @Test + void rootLevelAbortThenSuccessCreateTest() { + + // parameters + CreateType createType = CreateType.CREATE; + OffsetParameter offsetParameter = OffsetParameter.o_ZERO; + SizeParameter sizeParameter = SizeParameter.s_ZERO; + boolean reverts = true; + + BytecodeCompiler program = BytecodeCompiler.newProgram(); + genericCreate( + program, + createType, + ValueParameter.v_SELFBALANCE_PLUS_ONE, + offsetParameter, + sizeParameter, + salt01); // aborts + genericCreate( + program, createType, ValueParameter.v_ONE, offsetParameter, sizeParameter, salt01); + + if (reverts) { + appendRevert(program, 2, 13); + } + + run(program); + } + + /** + * In the tests {@link #rootLevelSuccessThenAbortCreateTest} we perform two CREATE(2)'s in a row. + * The first one is designed to succeed, the second one is designed to raise the + * insufficientBalanceAbort condition. We optionally REVERT. + */ + @ParameterizedTest + @MethodSource("offsetAndSizeParameters") + void rootLevelSuccessThenAbortCreateTest( + CreateType createType, + OffsetParameter offsetParameter, + SizeParameter sizeParameter, + boolean reverts) { + BytecodeCompiler program = + rootLevelSuccessThenAbortCreateByteCodeCompiler( + createType, offsetParameter, sizeParameter, reverts); + run(program); + } + + @Test + void specificRootLevelSuccessThenAbortCreateTest() { + BytecodeCompiler program = + rootLevelSuccessThenAbortCreateByteCodeCompiler( + CreateType.CREATE2, OffsetParameter.o_ZERO, SizeParameter.s_ZERO, false); + run(program); + } + + BytecodeCompiler rootLevelSuccessThenAbortCreateByteCodeCompiler( + CreateType createType, + OffsetParameter offsetParameter, + SizeParameter sizeParameter, + boolean reverts) { + BytecodeCompiler program = BytecodeCompiler.newProgram(); + genericCreate( + program, createType, ValueParameter.v_ONE, offsetParameter, sizeParameter, salt01); + genericCreate( + program, + createType, + ValueParameter.v_SELFBALANCE_PLUS_ONE, + offsetParameter, + sizeParameter, + salt01); // aborts + if (reverts) { + appendRevert(program, 2, 13); + } + return program; + } + + private static Stream offsetAndSizeParameters() { + List arguments = new ArrayList<>(); + for (OffsetParameter offsetParameter : OffsetParameter.values()) { + for (SizeParameter sizeParameter : SizeParameter.values()) { + if (sizeParameter.willRaiseException()) continue; + arguments.add(Arguments.of(CreateType.CREATE, offsetParameter, sizeParameter, true)); + arguments.add(Arguments.of(CreateType.CREATE2, offsetParameter, sizeParameter, false)); + } + } + return arguments.stream(); + } + + /** + * {@link #rootLevelInsufficientBalanceParameters} excludes ''large sizes'': we are interested in + * unexceptional but aborted CREATE(2)'s. + */ + private static Stream rootLevelInsufficientBalanceParameters() { + + List arguments = new ArrayList<>(); + List sizeParameters = + List.of(s_ZERO, s_TWELVE, s_THIRTEEN, s_FOURTEEN, s_THIRTY_TWO, s_MSIZE); + + for (CreateType createType : CreateType.values()) { + for (OffsetParameter offsetParameter : OffsetParameter.values()) { + for (SizeParameter sizeParameter : sizeParameters) { + arguments.add(Arguments.of(createType, sizeParameter, offsetParameter)); + } + } + } + + return arguments.stream(); + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/failure/Create2InducedFailureTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/failure/Create2InducedFailureTests.java new file mode 100644 index 0000000000..38409483d6 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/failure/Create2InducedFailureTests.java @@ -0,0 +1,99 @@ +/* + * 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.createTests.failure; + +import static net.consensys.linea.zktracer.instructionprocessing.createTests.trivial.RootLevel.*; +import static net.consensys.linea.zktracer.opcode.OpCode.*; + +import net.consensys.linea.testing.BytecodeCompiler; +import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.Test; + +/** + * The following tests raise the Failure Condition F with the CREATE2 opcode. These + * tests are sequential in nature: one CREATE2 after another. + */ +public class Create2InducedFailureTests { + + @Test + void failureConditionNonceTest() { + + BytecodeCompiler program = BytecodeCompiler.newProgram(); + program + .push(salt01) + .push(0) + .push(0) + .push(1) + .op(CREATE2) + .push(salt01) + .push(0) + .push(0) + .push(1) + .op(CREATE2); + + run(program); + } + + /** + * We first produce init code that, when run, does + * + *

PUSH1 1 + * + *

PUSH1 0 + * + *

RETURN + * + *

i.e. 0x60016000f3. We then (1) store that init code in memory (2) use it for a first CREATE2 + * which deploys a SMC with bytecode of length 1 equal to 0x00 (3) test the (EXT) code size, code + * hash and balance of this new account (4) attempt a second deployment at that same exact + * address, thus raising the Failure Condition F. + */ + @Test + void failureConditionNonceAndCodeTest() { + + BytecodeCompiler initCode = BytecodeCompiler.newProgram(); + initCode + .push(1) // size + .push(0) + .op(RETURN); + Bytes compiledInitCode = initCode.compile(); + + BytecodeCompiler program = BytecodeCompiler.newProgram(); + program + .push(compiledInitCode) + .push(8 * (32 - compiledInitCode.size())) + .op(SHL) + .push(0) + .op(MSTORE); // this puts the init code in memory + + program + .push(salt01) + .push(compiledInitCode.size()) + .push(0) + .push(1) // value + .op(CREATE2); // first deployment, deploys monobyte byte code + + program.op(DUP1).op(DUP1).op(EXTCODEHASH).op(EXTCODESIZE).op(BALANCE); + + program + .push(salt01) + .push(compiledInitCode.size()) + .push(0) + .push(1) // value + .op(CREATE2); // second (attempted) deployment raises failure condition + + run(program); + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/failure/CreateInducedFailureTest.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/failure/CreateInducedFailureTest.java new file mode 100644 index 0000000000..df89da752b --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/failure/CreateInducedFailureTest.java @@ -0,0 +1,276 @@ +/* + * 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.createTests.failure; + +import static net.consensys.linea.zktracer.instructionprocessing.createTests.trivial.RootLevel.salt01; +import static net.consensys.linea.zktracer.instructionprocessing.utilities.MonoOpCodeSmcs.keyPair; +import static net.consensys.linea.zktracer.instructionprocessing.utilities.MonoOpCodeSmcs.userAccount; +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; +import static net.consensys.linea.zktracer.opcode.OpCode.*; +import static net.consensys.linea.zktracer.types.Utils.leftPadTo; + +import java.util.List; + +import net.consensys.linea.testing.BytecodeCompiler; +import net.consensys.linea.testing.ToyAccount; +import net.consensys.linea.testing.ToyExecutionEnvironmentV2; +import net.consensys.linea.testing.ToyTransaction; +import org.apache.tuweni.bytes.Bytes; +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.core.Transaction; +import org.junit.jupiter.api.Test; + +/** + * The present test case tests the ZKEVM's reaction to triggering the Failure Condition F + * with a CREATE opcode. It's not straightforward. The sequence of events is as follows: + * + *

- we start with an account {@link #entryPoint}; + * + *

- in {@link #transactionDeployingDelegateCaller} we call {@link #entryPoint} with empty call + * data which leads to the deployment of {@link #delegateCaller}; + * + *

- in {@link #transactionLeadingDelegateCallerToCreateAnAccount} we call {@link #entryPoint} + * with nonempty call data which leads it calling {@link #delegateCaller} which leads to it doing a + * DELEGATECALL to {@link #simpleCreator} thus deploying a new account with {@link + * #delegateCaller}'s nonce =1; + * + *

- in {@link #transactionLeadingDelegateCallerToSelfDestruct} we call {@link #entryPoint} with + * nonempty call data which leads it calling {@link #delegateCaller} which leads to it doing a + * DELEGATECALL to {@link #simpleSelfDestructor} self destructing; + * + *

- in {@link #transactionDeployingDelegateCallerAgain} we call {@link #entryPoint} with empty + * call data again which leads to the deployment of {@link #delegateCaller} again; + * + *

- in {@link #transactionLeadingDelegateCallerToAttemptCreateAgainThusRaisingFailureConditionF} + * we call {@link #entryPoint} with nonempty call data which leads it calling {@link + * #delegateCaller} which leads to it doing a DELEGATECALL to {@link #simpleCreator} thus + * attempting to redeploy at the same address where it did the first deployment; indeed + * {@link #delegateCaller}'s nonce is again =1; deploying a new account at nonce 1; + */ +public class CreateInducedFailureTest { + + final Bytes tinyAddress1 = Bytes.fromHexString("badd1ec0de"); + final Bytes tinyAddress2 = Bytes.fromHexString("900d1ec0de"); + final Address address1 = Address.wrap(leftPadTo(tinyAddress1, 20)); + final Address address2 = Address.wrap(leftPadTo(tinyAddress2, 20)); + final Bytes leftPaddedAddress1 = leftPadTo(tinyAddress1, WORD_SIZE); + final Bytes leftPaddedAddress2 = leftPadTo(tinyAddress2, WORD_SIZE); + final Address targetAddress = Address.fromHexString("797add7e55"); + + final BytecodeCompiler simpleSelfDestruct = + BytecodeCompiler.newProgram().op(ORIGIN).op(SELFDESTRUCT); + + /** + * Account that can only do one thing: do a SELFDESTRUCT sending the funds to the + * ORIGIN.. Its raison d'ĂȘtre is to be called by the {@link #delegateCaller}. + */ + final ToyAccount simpleSelfDestructor = + ToyAccount.builder() + .code(simpleSelfDestruct.compile()) + .nonce(91) + .balance(Wei.of(1234L)) + .address(address1) + .build(); + + final BytecodeCompiler simpleCreate = + BytecodeCompiler.newProgram() + .push(0) // empty init code + .push(0) + .push(1) // value + .op(CREATE); + + /** + * Account that can only do one thing: do a CREATE with 1 Wei of value. Its raison + * d'ĂȘtre is to be called by the {@link #delegateCaller}. + */ + final ToyAccount simpleCreator = + ToyAccount.builder() + .code(simpleCreate.compile()) + .nonce(512) + .balance(Wei.of(73L)) + .address(address2) + .build(); + + /** Does a DELEGATECALL to an address extracted from the call data. */ + final BytecodeCompiler delegateCaller = + BytecodeCompiler.newProgram() + .push(0) // rac + .push(0) // rao + .push(0) // cds + .push(0) // cdo + .push(0) + .op(CALLDATALOAD) // should be an address + .op(GAS) + .op(DELEGATECALL); + + /** Initialization code that deploys {@link #delegateCaller}. */ + final BytecodeCompiler initCode = + BytecodeCompiler.newProgram() + .push(delegateCaller.compile()) + .push(8 * (32 - delegateCaller.compile().size())) + .op(SHL) + .push(0) + .op(MSTORE) + .push(delegateCaller.compile().size()) // code size + .push(0) + .op(RETURN); + + int keyToDeploymentAddress = 0xad; + int emptyCallDataExecutionPathProgramCounter = 27; + + /** + * This bytecode behaves in two different possible ways: + * + *

- if called with empty call data it performs a predetermined CREATE2 using {@link + * #initCode} as initialization code, which deploys {@link #delegateCaller}, and then stores the + * deployment address at key {@link #keyToDeploymentAddress}; + * + *

- if called with nonempty call data it writes the call data into memory, SLOAD's an + * item from storage (the aforementioned CREATE2 deployment address stored at {@link + * #keyToDeploymentAddress}), and performs a CALL to said address providing it with the + * same call data it was given itself; this assumes that call data fit into a single EVM word; + * + *

Thus the {@link #entryPoint} serves as the entry point for the {@link #delegateCaller} + * account + * + *

N.B. For the SLOAD to work as expected it is necessary that the CREATE2 + * step have been taken first. Otherwise, it will SLOAD the value 0x00 ... 00 which + * is of no use. + */ + final BytecodeCompiler entryPointByteCode = + BytecodeCompiler.newProgram() + .op(CALLDATASIZE) // + 1 + .op(ISZERO) // [CALLDATASIZE == 0] // + 1 + .push(emptyCallDataExecutionPathProgramCounter) // + 2 + .op(JUMPI) // + 1 + //////////////////////////////////////////// + // The nonempty call data execution route // + //////////////////////////////////////////// + .push(0) // + 2 + .op(CALLDATALOAD) // extracts (address) from call data // + 1 + .push(0) // + 2 + .op(MSTORE) // + 1 + .push(0) // rac // + 2 + .push(0) // rao // + 2 + .push(0x20) // cds // + 2 + .push(0) // cdo // + 2 + .push(keyToDeploymentAddress) // + 2 + .op(SLOAD) // extract stored address // + 1 + .push(0xef) // value // + 2 + .op(GAS) // gas // + 1 + .op(CALL) // + 1 + .op(STOP) // + 1 + ///////////////////////////////////////// + // The empty call data execution route // + ///////////////////////////////////////// + .op(JUMPDEST) // PC = 27 + .push(initCode.compile()) + .push(8 * (32 - initCode.compile().size())) + .op(SHL) + .push(0) + .op(MSTORE) + .push(salt01) + .push(initCode.compile().size()) // init code size + .push(0) // offset + .push(0xff) // value + .op(CREATE2) + .push(keyToDeploymentAddress) + .op(SSTORE); + + final ToyAccount entryPoint = + ToyAccount.builder() + .code(entryPointByteCode.compile()) + .nonce(1337) + .balance(Wei.of(73L)) + .address(targetAddress) + .build(); + + final Transaction transactionDeployingDelegateCaller = + ToyTransaction.builder() + .sender(userAccount) + .to(entryPoint) + .keyPair(keyPair) + .value(Wei.of(0xffff)) + .gasLimit(1_000_000L) + .gasPrice(Wei.of(8)) + .build(); + + final Transaction transactionLeadingDelegateCallerToCreateAnAccount = + ToyTransaction.builder() + .sender(userAccount.raiseNonceBy(1)) + .to(entryPoint) + .keyPair(keyPair) + .value(Wei.of(0xeeee)) + .gasLimit(1_000_000L) + .gasPrice(Wei.of(8)) + .payload(leftPaddedAddress1) + .build(); + + final Transaction transactionLeadingDelegateCallerToSelfDestruct = + ToyTransaction.builder() + .sender(userAccount.raiseNonceBy(2)) + .to(entryPoint) + .keyPair(keyPair) + .value(Wei.of(0xdddd)) + .gasLimit(1_000_000L) + .gasPrice(Wei.of(8)) + .payload(leftPaddedAddress2) + .build(); + + final Transaction transactionDeployingDelegateCallerAgain = + ToyTransaction.builder() + .sender(userAccount.raiseNonceBy(3)) + .to(entryPoint) + .keyPair(keyPair) + .value(Wei.of(0xcccc)) + .gasLimit(1_000_000L) + .gasPrice(Wei.of(8)) + .build(); + + final Transaction + transactionLeadingDelegateCallerToAttemptCreateAgainThusRaisingFailureConditionF = + ToyTransaction.builder() + .sender(userAccount.raiseNonceBy(4)) + .to(entryPoint) + .keyPair(keyPair) + .value(Wei.of(0xbbbb)) + .gasLimit(1_000_000L) + .gasPrice(Wei.of(8)) + .payload(leftPaddedAddress1) + .build(); + + final List transactions = + List.of( + transactionDeployingDelegateCaller, + transactionLeadingDelegateCallerToCreateAnAccount, + transactionLeadingDelegateCallerToSelfDestruct, + transactionDeployingDelegateCallerAgain, + transactionLeadingDelegateCallerToAttemptCreateAgainThusRaisingFailureConditionF); + + final List accounts = + List.of(userAccount, entryPoint, simpleSelfDestructor, simpleCreator); + + @Test + void complexFailureConditionTest() { + + ToyExecutionEnvironmentV2.builder() + .accounts(accounts) + .transactions(transactions) + .zkTracerValidator(zkTracer -> {}) + .build() + .run(); + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/failure/NestedFailureTest.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/failure/NestedFailureTest.java new file mode 100644 index 0000000000..f84b07be8e --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/failure/NestedFailureTest.java @@ -0,0 +1,122 @@ +/* + * 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.createTests.failure; + +import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.callCaller; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.identity.Tests.fullCodeCopyOf; +import static net.consensys.linea.zktracer.instructionprocessing.createTests.trivial.RootLevel.salt02; +import static net.consensys.linea.zktracer.instructionprocessing.utilities.MonoOpCodeSmcs.keyPair; +import static net.consensys.linea.zktracer.instructionprocessing.utilities.MonoOpCodeSmcs.userAccount; +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; +import static net.consensys.linea.zktracer.opcode.OpCode.*; + +import java.util.List; + +import net.consensys.linea.testing.BytecodeCompiler; +import net.consensys.linea.testing.ToyAccount; +import net.consensys.linea.testing.ToyExecutionEnvironmentV2; +import net.consensys.linea.testing.ToyTransaction; +import net.consensys.linea.zktracer.opcode.OpCode; +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.core.Transaction; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; + +/** + * The purpose of this class is to tests Failure Condition F's arising from nested + * CREATE2's. + */ +public class NestedFailureTest { + + @ParameterizedTest + @EnumSource( + value = OpCode.class, + names = {"CALL", "CALLCODE", "DELEGATECALL", "STATICCALL"}) + public void nestedFailureTest(OpCode callOpCode) { + + final String deployedCode = "deadbeefc0de"; + final int deployedCodeLengthInBytes = deployedCode.length() / 2; + final String errorString = "0e7707"; + final int errorStringLengthInBytes = errorString.length() / 2; + + BytecodeCompiler initCode = BytecodeCompiler.newProgram(); + callCaller(initCode, callOpCode, 0xffffff, 1, 0xa, 0xb, 0xc, 0xd); + final int sizeUpToCall = initCode.compile().size(); + initCode + .op(ISZERO) + .push(sizeUpToCall + (1 + 2 + 1) + ((1 + deployedCodeLengthInBytes) + 2 + 1 + 2 + 2 + 1)) + .op(JUMPI) + ////////////////////////// + // successful CALL path // + ////////////////////////// + .push(deployedCode) + .push(0) + .op(MSTORE) + .push(deployedCodeLengthInBytes) + .push(WORD_SIZE - deployedCodeLengthInBytes) + .op(RETURN) + //////////////////////////// + // unsuccessful CALL path // + //////////////////////////// + .op(JUMPDEST) + .push(errorString) + .push(0) + .op(MSTORE) + .push(errorStringLengthInBytes) // size + .push(WORD_SIZE - errorStringLengthInBytes) // offset + .op(REVERT); + + ToyAccount accountContainingInitCode = + ToyAccount.builder() + .address(Address.fromHexString("c0ffeec0deadd7")) + .code(initCode.compile()) + .nonce(0xffff) + .balance(Wei.of(0xffffff)) + .build(); + + BytecodeCompiler entryPoint = BytecodeCompiler.newProgram(); + fullCodeCopyOf(entryPoint, accountContainingInitCode); // loading init code into memory + entryPoint + .push(salt02) // salt + .op(MSIZE) // size + .push(0) // offset + .op(SELFBALANCE) // value + .op(CREATE2); + + ToyAccount entryPointAccount = + ToyAccount.builder() + .address(Address.fromHexString("add7e55")) + .balance(Wei.of(0xeeeeee)) + .nonce(0x777777) + .code(entryPoint.compile()) + .build(); + + Transaction transaction = + ToyTransaction.builder() + .sender(userAccount) + .keyPair(keyPair) + .to(entryPointAccount) + .value(Wei.of(7_000_000_000L)) + .gasLimit(0xffffffL) + .build(); + + ToyExecutionEnvironmentV2.builder() + .accounts(List.of(userAccount, entryPointAccount, accountContainingInitCode)) + .transaction(transaction) + .build() + .run(); + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/failure/NoFailure.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/failure/NoFailure.java new file mode 100644 index 0000000000..d29ea21eb6 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/failure/NoFailure.java @@ -0,0 +1,68 @@ +/* + * 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.createTests.failure; + +import static net.consensys.linea.zktracer.instructionprocessing.createTests.trivial.RootLevel.*; +import static net.consensys.linea.zktracer.opcode.OpCode.*; + +import net.consensys.linea.testing.BytecodeCompiler; +import org.junit.jupiter.api.Test; + +public class NoFailure { + + /** + * The following tests runs two separate CREATE2 deployments with different SALT parameters. No + * address collision takes place, no failure condition F is raised. + */ + @Test + void noFailureConditionTest() { + + BytecodeCompiler program = BytecodeCompiler.newProgram(); + program + .push(salt01) + .push(0) + .push(0) + .push(1) + .op(CREATE2) + .push(salt02) + .push(0) + .push(0) + .push(1) + .op(CREATE2); + + run(program); + } + + /** + * The following (1) precomputes a deployment address (2) stores it (3) transfers value to that + * address (4) performs a deployment (CREATE2) at that address + */ + @Test + void noFailureConditionDespiteNonzeroBalanceTest() { + + BytecodeCompiler program = BytecodeCompiler.newProgram(); + + precomputeDeploymentAddressOfEmptyInitCodeCreate2(program, salt01); + storeAt(program, 0xadd7); + program.push(0).push(0).push(0).push(0).push(1); // value + loadFromStorage(program, 0xadd7); // address + program.op(GAS).op(CALL); + program.push(salt01).push(0).push(0).push(1).op(CREATE2); + loadFromStorage(program, 0xadd7); + program.op(EQ); // we expect the result to be true + + run(program); + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/trivial/RootLevel.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/trivial/RootLevel.java new file mode 100644 index 0000000000..b25ddd1690 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/createTests/trivial/RootLevel.java @@ -0,0 +1,195 @@ +/* + * 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.createTests.trivial; + +import static net.consensys.linea.zktracer.instructionprocessing.createTests.WhenToTestParameter.BEFORE; +import static net.consensys.linea.zktracer.instructionprocessing.createTests.WhenToTestParameter.BEFORE_AND_AFTER; +import static net.consensys.linea.zktracer.opcode.OpCode.*; + +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.instructionprocessing.createTests.*; +import net.consensys.linea.zktracer.opcode.OpCode; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.MethodSource; + +public class RootLevel { + + public static String salt01 = "5a1701"; + public static String salt02 = "5a1702"; + + @Test + void basicCreate2Test() { + + BytecodeCompiler program = BytecodeCompiler.newProgram(); + program + .push(0xadd7) // salt + .push(1) // size + .push(0) // offset + .push(1) // value + .op(CREATE2); + + run(program); + } + + @ParameterizedTest + @MethodSource("createParametersForEmptyCreates") + void rootLevelCreateTests( + CreateType createType, + ValueParameter valueParameter, + OffsetParameter offsetParameter, + boolean revert) { + + BytecodeCompiler program = BytecodeCompiler.newProgram(); + genericCreate( + program, createType, valueParameter, offsetParameter, SizeParameter.s_ZERO, salt01); + + if (revert) { + program.push(0).push(0).op(REVERT); + } + + run(program); + } + + @ParameterizedTest + @EnumSource(WhenToTestParameter.class) + void rootLevelCreate2AndExtCodeHash(WhenToTestParameter when) { + + int storageKey = 0; + BytecodeCompiler program = BytecodeCompiler.newProgram(); + precomputeDeploymentAddressOfEmptyInitCodeCreate2(program, salt01); + storeAt(program, storageKey); + + if (when == BEFORE || when == BEFORE_AND_AFTER) { + loadFromStorage(program, storageKey); + program.op(EXTCODEHASH); // we expect to see 0 + } + + genericCreate( + program, + CreateType.CREATE2, + ValueParameter.v_ONE, + OffsetParameter.o_ZERO, + SizeParameter.s_ZERO, + salt01); + + if (when == BEFORE || when == BEFORE_AND_AFTER) { + loadFromStorage(program, storageKey); + program.op(EQ); // we expect to have the result be true here + loadFromStorage(program, storageKey); + program.op(EXTCODEHASH); // we expect to see KECCAK(( )) + } + + run(program); + } + + private static Stream createParametersForEmptyCreates() { + + final List valueParameters = + List.of(ValueParameter.v_ZERO, ValueParameter.v_ONE); + + List arguments = new ArrayList<>(); + + for (CreateType createType : CreateType.values()) { + for (ValueParameter valueParameter : valueParameters) { + for (OffsetParameter offsetParameter : OffsetParameter.values()) { + arguments.add(Arguments.of(createType, valueParameter, offsetParameter, true)); + arguments.add(Arguments.of(createType, valueParameter, offsetParameter, false)); + } + } + } + + return arguments.stream(); + } + + public static void genericCreate( + BytecodeCompiler program, + CreateType type, + ValueParameter valueParameter, + OffsetParameter offsetParameter, + SizeParameter sizeParameter, + String salt) { + + if (type == CreateType.CREATE2) program.push(salt); + + switch (sizeParameter) { + case s_ZERO -> program.push(0); + case s_TWELVE -> program.push(12); + case s_THIRTEEN -> program.push(13); + case s_FOURTEEN -> program.push(14); + case s_THIRTY_TWO -> program.push(0x20); + case s_MSIZE -> program.op(MSIZE); + case s_MAX -> program.push("ff".repeat(32)); + } + switch (offsetParameter) { + case o_ZERO -> program.push(0); + case o_THREE -> program.push(0); + case o_SIXTEEN -> program.push(0x10); + case o_SIXTEEN_BYTE_INT -> program.push("abe1245ffff123a87000a543eff12aaa"); + case o_THIRTY_TWO_BYTE_INT -> program.push( + "abe1245ffff123a87000a543eff12aaa09987582714266effffefaabc76aa758"); + case o_MAX -> program.push("ff".repeat(32)); + } + switch (valueParameter) { + case v_ZERO -> program.push(0); + case v_ONE -> program.push(1); + case v_SELFBALANCE -> program.op(SELFBALANCE); + case v_SELFBALANCE_PLUS_ONE -> program.op(SELFBALANCE).push(1).op(ADD); + } + switch (type) { + case CREATE -> program.op(CREATE); + case CREATE2 -> program.op(CREATE2); + } + } + + public static void precomputeDeploymentAddressOfEmptyInitCodeCreate2( + BytecodeCompiler program, String salt) { + program.push(0xff).push(0).op(MSTORE8); // (255) + program + .op(OpCode.ADDRESS) + .push(12 * 8) + .op(SHL) + .push(1) + .op(MSTORE); // store address left shifted by 12 bytes + program.push(salt).push(21).op(MSTORE); // salt + program.push(0).push(0).op(SHA3).push(53).op(MSTORE); // init code hash = KECCAK(( )) + program + .push(85) // 1 + 20 + 32 + 32 + .push(0) + .op(SHA3); // extract raw address + program + .push("000000000000000000000000ffffffffffffffffffffffffffffffffffffffff") + .op(AND); // computes deployment address + } + + public static void storeAt(BytecodeCompiler program, int storageKey) { + program.push(storageKey).op(SSTORE); + } + + public static void loadFromStorage(BytecodeCompiler program, int storageKey) { + program.push(storageKey).op(SLOAD); + } + + public static void run(BytecodeCompiler program) { + BytecodeRunner.of(program).run(); + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/module/rlptxn/TestRandomTxns.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/module/rlptxn/TestRandomTxns.java index 957142e128..883e84a898 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/module/rlptxn/TestRandomTxns.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/module/rlptxn/TestRandomTxns.java @@ -142,7 +142,7 @@ class TestRandomTxns { // final ToyAccount receiverAccount() { // // return ToyAccount.builder() - // .balance(Wei.ONE) + // .balance(Wei.v_ONE) // .nonce(6) // .address(Address.wrap(Bytes.random(20, rnd))) // .code( diff --git a/arithmetization/src/test/resources/junit-platform.properties b/arithmetization/src/test/resources/junit-platform.properties new file mode 100644 index 0000000000..01457fca69 --- /dev/null +++ b/arithmetization/src/test/resources/junit-platform.properties @@ -0,0 +1,3 @@ +# junit.jupiter.execution.parallel.enabled = true +# junit.jupiter.execution.parallel.mode.default = concurrent +# junit.jupiter.execution.parallel.config.strategy = dynamic diff --git a/linea-constraints b/linea-constraints index c2e381e393..60f65086ae 160000 --- a/linea-constraints +++ b/linea-constraints @@ -1 +1 @@ -Subproject commit c2e381e393e17512b7f1e0758c4abb55cdd4dacc +Subproject commit 60f65086aeba34afa4b086c75ec57e6aa363b31b diff --git a/testing/src/main/java/net/consensys/linea/testing/ToyAccount.java b/testing/src/main/java/net/consensys/linea/testing/ToyAccount.java index d66bf1c0bf..c6d0b5eeec 100644 --- a/testing/src/main/java/net/consensys/linea/testing/ToyAccount.java +++ b/testing/src/main/java/net/consensys/linea/testing/ToyAccount.java @@ -202,4 +202,9 @@ public ReferenceTestWorldState.AccountMock toAccountMock() { return new ReferenceTestWorldState.AccountMock( Long.toHexString(nonce), balance.toHexString(), accountMockStorage, code.toHexString()); } + + public ToyAccount raiseNonceBy(long k) { + long updatedNonce = this.getNonce() + k; + return new ToyAccount(this.parent, this.getAddress(), updatedNonce, this.balance, this.balance); + } }