diff --git a/acceptance-tests/src/test/java/linea/plugin/acc/test/LineaPluginTestBase.java b/acceptance-tests/src/test/java/linea/plugin/acc/test/LineaPluginTestBase.java index 4c16d8a1..288f2e00 100644 --- a/acceptance-tests/src/test/java/linea/plugin/acc/test/LineaPluginTestBase.java +++ b/acceptance-tests/src/test/java/linea/plugin/acc/test/LineaPluginTestBase.java @@ -40,6 +40,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; +import linea.plugin.acc.test.tests.web3j.generated.RevertExample; import linea.plugin.acc.test.tests.web3j.generated.SimpleStorage; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.RandomStringUtils; @@ -247,6 +248,17 @@ protected SimpleStorage deploySimpleStorage() throws Exception { return deploy.send(); } + protected RevertExample deployRevertExample() throws Exception { + final Web3j web3j = minerNode.nodeRequests().eth(); + final Credentials credentials = Credentials.create(Accounts.GENESIS_ACCOUNT_ONE_PRIVATE_KEY); + TransactionManager txManager = + new RawTransactionManager(web3j, credentials, CHAIN_ID, createReceiptProcessor(web3j)); + + final RemoteCall deploy = + RevertExample.deploy(web3j, txManager, new DefaultGasProvider()); + return deploy.send(); + } + public static String getResourcePath(String resource) { return Objects.requireNonNull(LineaPluginTestBase.class.getResource(resource)).getPath(); } diff --git a/acceptance-tests/src/test/java/linea/plugin/acc/test/rpc/linea/EthSendRawTransactionSimulationCheckTest.java b/acceptance-tests/src/test/java/linea/plugin/acc/test/rpc/linea/EthSendRawTransactionSimulationCheckTest.java index 5047247e..e8e7ffa4 100644 --- a/acceptance-tests/src/test/java/linea/plugin/acc/test/rpc/linea/EthSendRawTransactionSimulationCheckTest.java +++ b/acceptance-tests/src/test/java/linea/plugin/acc/test/rpc/linea/EthSendRawTransactionSimulationCheckTest.java @@ -22,6 +22,7 @@ import linea.plugin.acc.test.LineaPluginTestBase; import linea.plugin.acc.test.TestCommandLineOptionsBuilder; +import linea.plugin.acc.test.tests.web3j.generated.RevertExample; import linea.plugin.acc.test.tests.web3j.generated.SimpleStorage; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.tests.acceptance.dsl.account.Account; @@ -46,7 +47,7 @@ public List getTestCliOptions() { return new TestCommandLineOptionsBuilder() .set( "--plugin-linea-module-limit-file-path=", - getResourcePath("/txOverflowModuleLimits.toml")) + getResourcePath("/moduleLimits_sendRawTx.toml")) .set("--plugin-linea-tx-pool-simulation-check-api-enabled=", "true") .build(); } @@ -101,4 +102,36 @@ public void transactionOverModuleLineCountNotAccepted() throws Exception { .map(Hash::toHexString) .forEach(hash -> minerNode.verify(eth.expectSuccessfulTransactionReceipt(hash))); } + + @Test + public void transactionsThatRevertAreAccepted() throws Exception { + final RevertExample revertExample = deployRevertExample(); + final Web3j web3j = minerNode.nodeRequests().eth(); + final String contractAddress = revertExample.getContractAddress(); + final String txData = revertExample.setValue(BigInteger.ZERO).encodeFunctionCall(); + + // this tx reverts but nevertheless it is accepted in the pool + final RawTransaction txThatReverts = + RawTransaction.createTransaction( + CHAIN_ID, + BigInteger.ZERO, + GAS_LIMIT.divide(BigInteger.TEN), + contractAddress, + VALUE, + txData, + GAS_PRICE, + GAS_PRICE.multiply(BigInteger.TEN).add(BigInteger.ONE)); + final byte[] signedTxContractInteraction = + TransactionEncoder.signMessage( + txThatReverts, Credentials.create(Accounts.GENESIS_ACCOUNT_TWO_PRIVATE_KEY)); + + final EthSendTransaction signedTxContractInteractionResp = + web3j.ethSendRawTransaction(Numeric.toHexString(signedTxContractInteraction)).send(); + + assertThat(signedTxContractInteractionResp.hasError()).isFalse(); + + final var expectedConfirmedTxHash = signedTxContractInteractionResp.getTransactionHash(); + + minerNode.verify(eth.expectSuccessfulTransactionReceipt(expectedConfirmedTxHash)); + } } diff --git a/acceptance-tests/src/test/resources/moduleLimits_sendRawTx.toml b/acceptance-tests/src/test/resources/moduleLimits_sendRawTx.toml new file mode 100644 index 00000000..c8dec3c8 --- /dev/null +++ b/acceptance-tests/src/test/resources/moduleLimits_sendRawTx.toml @@ -0,0 +1,75 @@ + +## +# This file specifies prover limit by each EVM module +# WARN: The prover/arithmetization team has the owneship of this. +# Changing this values may compromise the system. +# issue: https://github.com/Consensys/zkevm-monorepo/issues/525 +## + +[traces-limits] +# +# Arithmetization module limits +# +ADD = 70 +BIN = 262144 +BLAKE_MODEXP_DATA = 262144 +BLOCK_DATA = 13 +BLOCK_HASH = 1 +EC_DATA = 4096 +EUC = 16384 # can probably be lower +EXP = 32760 +EXT = 20 +GAS = 262144 +HUB = 174 +MMIO = 1048576 +MMU = 524288 +MOD = 20 +MUL = 20 +MXP = 35 +PHONEY_RLP = 65536 # can probably get lower +ROM = 2402 +ROM_LEX = 20 +SHF = 63 +TX_RLP = 131072 +TRM = 120 +WCP = 149 +LOG_DATA = 20 +LOG_INFO = 20 +RLP_ADDR = 20 +RLP_TXN = 1300 +RLP_TXN_RCPT = 100 +TXN_DATA = 30 +SHAKIRA_DATA = 262144 +STP = 20 +OOB = 262144 + +# +# Block-specific limits +# +BLOCK_KECCAK = 8192 +BLOCK_L1_SIZE = 1000000 +BLOCK_L2_L1_LOGS = 16 +BLOCK_TRANSACTIONS = 200 # max number of tx in an L2 block + +# +# Fixed size, static tables +# +BIN_REFERENCE_TABLE = 262144 # contains 3 * 256^2 + 256 data rows + 1 padding row +SHF_REFERENCE_TABLE = 4096 # contains 9 * 256 data rows + 1 padding row +INSTRUCTION_DECODER = 512 # contains 256 data rows + 1 padding row + +# +# Precompiles limits +# +PRECOMPILE_ECRECOVER_EFFECTIVE_CALLS = 10000 +PRECOMPILE_SHA2_BLOCKS = 10000 +PRECOMPILE_RIPEMD_BLOCKS = 10000 +PRECOMPILE_ECPAIRING_MILLER_LOOPS = 10000 +PRECOMPILE_MODEXP_EFFECTIVE_CALLS = 10000 +PRECOMPILE_ECADD_EFFECTIVE_CALLS = 10000 +PRECOMPILE_ECMUL_EFFECTIVE_CALLS = 10000 +PRECOMPILE_ECPAIRING_FINAL_EXPONENTIATIONS = 10000 +PRECOMPILE_ECPAIRING_G2_MEMBERSHIP_CALLS = 10000 +PRECOMPILE_ECPAIRING_MILLER_LOOPS = 10000 +PRECOMPILE_BLAKE_EFFECTIVE_CALLS = 10000 +PRECOMPILE_BLAKE_ROUNDS = 512 \ No newline at end of file diff --git a/acceptance-tests/src/test/solidity/RevertExample.sol b/acceptance-tests/src/test/solidity/RevertExample.sol new file mode 100644 index 00000000..28b97678 --- /dev/null +++ b/acceptance-tests/src/test/solidity/RevertExample.sol @@ -0,0 +1,35 @@ +/* + * 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 + */ +pragma solidity >=0.7.0 <0.9.0; + +contract RevertExample { + uint256 public value; + + function setValue(uint256 _newValue) public { + require(_newValue != 0, "Value cannot be zero"); + value = _newValue; + } + + function forceRevert() public pure { + revert("This function always reverts"); + } + + function conditionalRevert(uint256 _input) public pure returns (uint256) { + if (_input < 10) { + revert("Input must be 10 or greater"); + } + return _input * 2; + } +} \ No newline at end of file diff --git a/sequencer/src/main/java/net/consensys/linea/sequencer/txpoolvalidation/validators/SimulationValidator.java b/sequencer/src/main/java/net/consensys/linea/sequencer/txpoolvalidation/validators/SimulationValidator.java index 86530ab0..991e40a7 100644 --- a/sequencer/src/main/java/net/consensys/linea/sequencer/txpoolvalidation/validators/SimulationValidator.java +++ b/sequencer/src/main/java/net/consensys/linea/sequencer/txpoolvalidation/validators/SimulationValidator.java @@ -114,17 +114,6 @@ public Optional validateTransaction( reportRejectedTransaction(transaction, errMsg); return Optional.of(errMsg); } - if (!simulationResult.isSuccessful()) { - final String errMsg = - "Reverted transaction" - + simulationResult - .getRevertReason() - .map(rr -> ": " + rr.toHexString()) - .orElse(""); - log.debug(errMsg); - reportRejectedTransaction(transaction, errMsg); - return Optional.of(errMsg); - } } } else { log.atTrace()