diff --git a/CHANGELOG.md b/CHANGELOG.md index 786ddd1e..fdf2d21e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Changelog ## Next release +* feat: Report rejected transactions only due to trace limit overflows to an external service. * feat: Report rejected transactions to an external service for validators used by LineaTransactionPoolValidatorPlugin [#85](https://github.com/Consensys/linea-sequencer/pull/85) * feat: Report rejected transactions to an external service for LineaTransactionSelector used by LineaTransactionSelectorPlugin [#69](https://github.com/Consensys/linea-sequencer/pull/69) diff --git a/sequencer/src/main/java/net/consensys/linea/sequencer/txpoolvalidation/LineaTransactionPoolValidatorFactory.java b/sequencer/src/main/java/net/consensys/linea/sequencer/txpoolvalidation/LineaTransactionPoolValidatorFactory.java index dc5759f1..18bf1193 100644 --- a/sequencer/src/main/java/net/consensys/linea/sequencer/txpoolvalidation/LineaTransactionPoolValidatorFactory.java +++ b/sequencer/src/main/java/net/consensys/linea/sequencer/txpoolvalidation/LineaTransactionPoolValidatorFactory.java @@ -80,11 +80,10 @@ public LineaTransactionPoolValidatorFactory( public PluginTransactionPoolValidator createTransactionValidator() { final var validators = new PluginTransactionPoolValidator[] { - new AllowedAddressValidator(denied, rejectedTxJsonRpcManager), - new GasLimitValidator(txPoolValidatorConf, rejectedTxJsonRpcManager), - new CalldataValidator(txPoolValidatorConf, rejectedTxJsonRpcManager), - new ProfitabilityValidator( - besuConfiguration, blockchainService, profitabilityConf, rejectedTxJsonRpcManager), + new AllowedAddressValidator(denied), + new GasLimitValidator(txPoolValidatorConf), + new CalldataValidator(txPoolValidatorConf), + new ProfitabilityValidator(besuConfiguration, blockchainService, profitabilityConf), new SimulationValidator( blockchainService, transactionSimulationService, diff --git a/sequencer/src/main/java/net/consensys/linea/sequencer/txpoolvalidation/validators/AllowedAddressValidator.java b/sequencer/src/main/java/net/consensys/linea/sequencer/txpoolvalidation/validators/AllowedAddressValidator.java index a272ea7f..a30cab93 100644 --- a/sequencer/src/main/java/net/consensys/linea/sequencer/txpoolvalidation/validators/AllowedAddressValidator.java +++ b/sequencer/src/main/java/net/consensys/linea/sequencer/txpoolvalidation/validators/AllowedAddressValidator.java @@ -14,15 +14,11 @@ */ package net.consensys.linea.sequencer.txpoolvalidation.validators; -import java.time.Instant; -import java.util.List; import java.util.Optional; import java.util.Set; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import net.consensys.linea.jsonrpc.JsonRpcManager; -import net.consensys.linea.jsonrpc.JsonRpcRequestBuilder; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Transaction; import org.hyperledger.besu.plugin.services.txvalidator.PluginTransactionPoolValidator; @@ -48,15 +44,11 @@ public class AllowedAddressValidator implements PluginTransactionPoolValidator { Address.fromHexString("0x000000000000000000000000000000000000000a")); private final Set
denied; - private final Optional rejectedTxJsonRpcManager; @Override public Optional validateTransaction( final Transaction transaction, final boolean isLocal, final boolean hasPriority) { - final Optional errMsg = - validateSender(transaction).or(() -> validateRecipient(transaction)); - errMsg.ifPresent(reason -> reportRejectedTransaction(transaction, reason)); - return errMsg; + return validateSender(transaction).or(() -> validateRecipient(transaction)); } private Optional validateRecipient(final Transaction transaction) { @@ -90,19 +82,4 @@ private Optional validateSender(final Transaction transaction) { } return Optional.empty(); } - - private void reportRejectedTransaction(final Transaction transaction, final String reason) { - rejectedTxJsonRpcManager.ifPresent( - jsonRpcManager -> { - final String jsonRpcCall = - JsonRpcRequestBuilder.generateSaveRejectedTxJsonRpc( - jsonRpcManager.getNodeType(), - transaction, - Instant.now(), - Optional.empty(), // block number is not available - reason, - List.of()); - jsonRpcManager.submitNewJsonRpcCallAsync(jsonRpcCall); - }); - } } diff --git a/sequencer/src/main/java/net/consensys/linea/sequencer/txpoolvalidation/validators/CalldataValidator.java b/sequencer/src/main/java/net/consensys/linea/sequencer/txpoolvalidation/validators/CalldataValidator.java index 7ecaf125..44eba275 100644 --- a/sequencer/src/main/java/net/consensys/linea/sequencer/txpoolvalidation/validators/CalldataValidator.java +++ b/sequencer/src/main/java/net/consensys/linea/sequencer/txpoolvalidation/validators/CalldataValidator.java @@ -14,15 +14,11 @@ */ package net.consensys.linea.sequencer.txpoolvalidation.validators; -import java.time.Instant; -import java.util.List; import java.util.Optional; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import net.consensys.linea.config.LineaTransactionPoolValidatorConfiguration; -import net.consensys.linea.jsonrpc.JsonRpcManager; -import net.consensys.linea.jsonrpc.JsonRpcRequestBuilder; import org.hyperledger.besu.datatypes.Transaction; import org.hyperledger.besu.plugin.services.txvalidator.PluginTransactionPoolValidator; @@ -31,7 +27,6 @@ @RequiredArgsConstructor public class CalldataValidator implements PluginTransactionPoolValidator { final LineaTransactionPoolValidatorConfiguration txPoolValidatorConf; - final Optional rejectedTxJsonRpcManager; @Override public Optional validateTransaction( @@ -41,24 +36,8 @@ public Optional validateTransaction( "Calldata of transaction is greater than the allowed max of " + txPoolValidatorConf.maxTxCalldataSize(); log.debug(errMsg); - reportRejectedTransaction(transaction, errMsg); return Optional.of(errMsg); } return Optional.empty(); } - - private void reportRejectedTransaction(final Transaction transaction, final String reason) { - rejectedTxJsonRpcManager.ifPresent( - jsonRpcManager -> { - final String jsonRpcCall = - JsonRpcRequestBuilder.generateSaveRejectedTxJsonRpc( - jsonRpcManager.getNodeType(), - transaction, - Instant.now(), - Optional.empty(), // block number is not available - reason, - List.of()); - jsonRpcManager.submitNewJsonRpcCallAsync(jsonRpcCall); - }); - } } diff --git a/sequencer/src/main/java/net/consensys/linea/sequencer/txpoolvalidation/validators/GasLimitValidator.java b/sequencer/src/main/java/net/consensys/linea/sequencer/txpoolvalidation/validators/GasLimitValidator.java index 7e2f9042..f86e2844 100644 --- a/sequencer/src/main/java/net/consensys/linea/sequencer/txpoolvalidation/validators/GasLimitValidator.java +++ b/sequencer/src/main/java/net/consensys/linea/sequencer/txpoolvalidation/validators/GasLimitValidator.java @@ -14,15 +14,11 @@ */ package net.consensys.linea.sequencer.txpoolvalidation.validators; -import java.time.Instant; -import java.util.List; import java.util.Optional; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import net.consensys.linea.config.LineaTransactionPoolValidatorConfiguration; -import net.consensys.linea.jsonrpc.JsonRpcManager; -import net.consensys.linea.jsonrpc.JsonRpcRequestBuilder; import org.hyperledger.besu.datatypes.Transaction; import org.hyperledger.besu.plugin.services.txvalidator.PluginTransactionPoolValidator; @@ -34,7 +30,6 @@ @RequiredArgsConstructor public class GasLimitValidator implements PluginTransactionPoolValidator { final LineaTransactionPoolValidatorConfiguration txPoolValidatorConf; - final Optional rejectedTxJsonRpcManager; @Override public Optional validateTransaction( @@ -44,24 +39,8 @@ public Optional validateTransaction( "Gas limit of transaction is greater than the allowed max of " + txPoolValidatorConf.maxTxGasLimit(); log.debug(errMsg); - reportRejectedTransaction(transaction, errMsg); return Optional.of(errMsg); } return Optional.empty(); } - - private void reportRejectedTransaction(final Transaction transaction, final String reason) { - rejectedTxJsonRpcManager.ifPresent( - jsonRpcManager -> { - final String jsonRpcCall = - JsonRpcRequestBuilder.generateSaveRejectedTxJsonRpc( - jsonRpcManager.getNodeType(), - transaction, - Instant.now(), - Optional.empty(), // block number is not available - reason, - List.of()); - jsonRpcManager.submitNewJsonRpcCallAsync(jsonRpcCall); - }); - } } diff --git a/sequencer/src/main/java/net/consensys/linea/sequencer/txpoolvalidation/validators/ProfitabilityValidator.java b/sequencer/src/main/java/net/consensys/linea/sequencer/txpoolvalidation/validators/ProfitabilityValidator.java index 8b91452f..74040fdb 100644 --- a/sequencer/src/main/java/net/consensys/linea/sequencer/txpoolvalidation/validators/ProfitabilityValidator.java +++ b/sequencer/src/main/java/net/consensys/linea/sequencer/txpoolvalidation/validators/ProfitabilityValidator.java @@ -14,15 +14,11 @@ */ package net.consensys.linea.sequencer.txpoolvalidation.validators; -import java.time.Instant; -import java.util.List; import java.util.Optional; import lombok.extern.slf4j.Slf4j; import net.consensys.linea.bl.TransactionProfitabilityCalculator; import net.consensys.linea.config.LineaProfitabilityConfiguration; -import net.consensys.linea.jsonrpc.JsonRpcManager; -import net.consensys.linea.jsonrpc.JsonRpcRequestBuilder; import org.apache.tuweni.units.bigints.UInt256s; import org.hyperledger.besu.datatypes.Transaction; import org.hyperledger.besu.datatypes.Wei; @@ -41,18 +37,15 @@ public class ProfitabilityValidator implements PluginTransactionPoolValidator { final BlockchainService blockchainService; final LineaProfitabilityConfiguration profitabilityConf; final TransactionProfitabilityCalculator profitabilityCalculator; - final Optional rejectedTxJsonRpcManager; public ProfitabilityValidator( final BesuConfiguration besuConfiguration, final BlockchainService blockchainService, - final LineaProfitabilityConfiguration profitabilityConf, - final Optional rejectedTxJsonRpcManager) { + final LineaProfitabilityConfiguration profitabilityConf) { this.besuConfiguration = besuConfiguration; this.blockchainService = blockchainService; this.profitabilityConf = profitabilityConf; this.profitabilityCalculator = new TransactionProfitabilityCalculator(profitabilityConf); - this.rejectedTxJsonRpcManager = rejectedTxJsonRpcManager; } @Override @@ -68,19 +61,16 @@ public Optional validateTransaction( .getNextBlockBaseFee() .orElseThrow(() -> new RuntimeException("We only support a base fee market")); - final Optional errMsg = - profitabilityCalculator.isProfitable( - "Txpool", - transaction, - profitabilityConf.txPoolMinMargin(), - baseFee, - calculateUpfrontGasPrice(transaction, baseFee), - transaction.getGasLimit(), - besuConfiguration.getMinGasPrice()) - ? Optional.empty() - : Optional.of("Gas price too low"); - errMsg.ifPresent(s -> reportRejectedTransaction(transaction, s)); - return errMsg; + return profitabilityCalculator.isProfitable( + "Txpool", + transaction, + profitabilityConf.txPoolMinMargin(), + baseFee, + calculateUpfrontGasPrice(transaction, baseFee), + transaction.getGasLimit(), + besuConfiguration.getMinGasPrice()) + ? Optional.empty() + : Optional.of("Gas price too low"); } return Optional.empty(); @@ -98,19 +88,4 @@ private Wei calculateUpfrontGasPrice(final Transaction transaction, final Wei ba baseFee.add(Wei.fromQuantity(transaction.getMaxPriorityFeePerGas().get())))) .orElseGet(() -> Wei.fromQuantity(transaction.getGasPrice().get())); } - - private void reportRejectedTransaction(final Transaction transaction, final String reason) { - rejectedTxJsonRpcManager.ifPresent( - jsonRpcManager -> { - final String jsonRpcCall = - JsonRpcRequestBuilder.generateSaveRejectedTxJsonRpc( - jsonRpcManager.getNodeType(), - transaction, - Instant.now(), - Optional.empty(), // block number is not available - reason, - List.of()); - jsonRpcManager.submitNewJsonRpcCallAsync(jsonRpcCall); - }); - } } 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 991e40a7..75204eb6 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 @@ -111,7 +111,6 @@ public Optional validateTransaction( "Invalid transaction" + simulationResult.getInvalidReason().map(ir -> ": " + ir).orElse(""); log.debug(errMsg); - reportRejectedTransaction(transaction, errMsg); return Optional.of(errMsg); } } diff --git a/sequencer/src/main/java/net/consensys/linea/sequencer/txselection/selectors/LineaTransactionSelector.java b/sequencer/src/main/java/net/consensys/linea/sequencer/txselection/selectors/LineaTransactionSelector.java index a396b83f..2d6586d4 100644 --- a/sequencer/src/main/java/net/consensys/linea/sequencer/txselection/selectors/LineaTransactionSelector.java +++ b/sequencer/src/main/java/net/consensys/linea/sequencer/txselection/selectors/LineaTransactionSelector.java @@ -14,10 +14,15 @@ */ package net.consensys.linea.sequencer.txselection.selectors; +import static net.consensys.linea.sequencer.txselection.LineaTransactionSelectionResult.TX_MODULE_LINE_COUNT_OVERFLOW; +import static net.consensys.linea.sequencer.txselection.LineaTransactionSelectionResult.TX_MODULE_LINE_COUNT_OVERFLOW_CACHED; + import java.time.Instant; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Set; import lombok.extern.slf4j.Slf4j; import net.consensys.linea.config.LineaProfitabilityConfiguration; @@ -41,6 +46,7 @@ public class LineaTransactionSelector implements PluginTransactionSelector { private TraceLineLimitTransactionSelector traceLineLimitTransactionSelector; private final List selectors; private final Optional rejectedTxJsonRpcManager; + private final Set rejectedTransactionReasonsMap = new HashSet<>(); public LineaTransactionSelector( final BlockchainService blockchainService, @@ -51,6 +57,13 @@ public LineaTransactionSelector( final Map limitsMap, final Optional rejectedTxJsonRpcManager) { this.rejectedTxJsonRpcManager = rejectedTxJsonRpcManager; + + // only report rejected transaction selection result from TraceLineLimitTransactionSelector + if (rejectedTxJsonRpcManager.isPresent()) { + rejectedTransactionReasonsMap.add(TX_MODULE_LINE_COUNT_OVERFLOW.toString()); + rejectedTransactionReasonsMap.add(TX_MODULE_LINE_COUNT_OVERFLOW_CACHED.toString()); + } + selectors = createTransactionSelectors( blockchainService, @@ -163,7 +176,8 @@ public void onTransactionNotSelected( rejectedTxJsonRpcManager.ifPresent( jsonRpcManager -> { - if (transactionSelectionResult.discard()) { + if (transactionSelectionResult.discard() + && rejectedTransactionReasonsMap.contains(transactionSelectionResult.toString())) { jsonRpcManager.submitNewJsonRpcCallAsync( JsonRpcRequestBuilder.generateSaveRejectedTxJsonRpc( jsonRpcManager.getNodeType(), diff --git a/sequencer/src/test/java/net/consensys/linea/sequencer/txpoolvalidation/validators/AllowedAddressValidatorTest.java b/sequencer/src/test/java/net/consensys/linea/sequencer/txpoolvalidation/validators/AllowedAddressValidatorTest.java index 85bc1b3e..c2f25f68 100644 --- a/sequencer/src/test/java/net/consensys/linea/sequencer/txpoolvalidation/validators/AllowedAddressValidatorTest.java +++ b/sequencer/src/test/java/net/consensys/linea/sequencer/txpoolvalidation/validators/AllowedAddressValidatorTest.java @@ -40,7 +40,7 @@ public class AllowedAddressValidatorTest { @BeforeEach public void initialize() { Set
denied = Set.of(DENIED); - allowedAddressValidator = new AllowedAddressValidator(denied, Optional.empty()); + allowedAddressValidator = new AllowedAddressValidator(denied); } @Test diff --git a/sequencer/src/test/java/net/consensys/linea/sequencer/txpoolvalidation/validators/CalldataValidatorTest.java b/sequencer/src/test/java/net/consensys/linea/sequencer/txpoolvalidation/validators/CalldataValidatorTest.java index e30a6d5f..fc775580 100644 --- a/sequencer/src/test/java/net/consensys/linea/sequencer/txpoolvalidation/validators/CalldataValidatorTest.java +++ b/sequencer/src/test/java/net/consensys/linea/sequencer/txpoolvalidation/validators/CalldataValidatorTest.java @@ -38,8 +38,7 @@ public void initialize() { new CalldataValidator( LineaTransactionPoolValidatorCliOptions.create().toDomainObject().toBuilder() .maxTxCalldataSize(MAX_TX_CALLDATA_SIZE) - .build(), - Optional.empty()); + .build()); } @Test diff --git a/sequencer/src/test/java/net/consensys/linea/sequencer/txpoolvalidation/validators/GasLimitValidatorTest.java b/sequencer/src/test/java/net/consensys/linea/sequencer/txpoolvalidation/validators/GasLimitValidatorTest.java index e7c79907..219e62f4 100644 --- a/sequencer/src/test/java/net/consensys/linea/sequencer/txpoolvalidation/validators/GasLimitValidatorTest.java +++ b/sequencer/src/test/java/net/consensys/linea/sequencer/txpoolvalidation/validators/GasLimitValidatorTest.java @@ -38,8 +38,7 @@ public void initialize() { new GasLimitValidator( LineaTransactionPoolValidatorCliOptions.create().toDomainObject().toBuilder() .maxTxGasLimit(MAX_TX_GAS_LIMIT) - .build(), - Optional.empty()); + .build()); } @Test diff --git a/sequencer/src/test/java/net/consensys/linea/sequencer/txpoolvalidation/validators/ProfitabilityValidatorTest.java b/sequencer/src/test/java/net/consensys/linea/sequencer/txpoolvalidation/validators/ProfitabilityValidatorTest.java index de333edb..3178a5ec 100644 --- a/sequencer/src/test/java/net/consensys/linea/sequencer/txpoolvalidation/validators/ProfitabilityValidatorTest.java +++ b/sequencer/src/test/java/net/consensys/linea/sequencer/txpoolvalidation/validators/ProfitabilityValidatorTest.java @@ -87,8 +87,7 @@ public void initialize() { profitabilityConfBuilder .txPoolCheckP2pEnabled(true) .txPoolCheckApiEnabled(true) - .build(), - Optional.empty()); + .build()); profitabilityValidatorNever = new ProfitabilityValidator( @@ -97,8 +96,7 @@ public void initialize() { profitabilityConfBuilder .txPoolCheckP2pEnabled(false) .txPoolCheckApiEnabled(false) - .build(), - Optional.empty()); + .build()); profitabilityValidatorOnlyApi = new ProfitabilityValidator( @@ -107,8 +105,7 @@ public void initialize() { profitabilityConfBuilder .txPoolCheckP2pEnabled(false) .txPoolCheckApiEnabled(true) - .build(), - Optional.empty()); + .build()); profitabilityValidatorOnlyP2p = new ProfitabilityValidator( @@ -117,8 +114,7 @@ public void initialize() { profitabilityConfBuilder .txPoolCheckP2pEnabled(true) .txPoolCheckApiEnabled(false) - .build(), - Optional.empty()); + .build()); } @Test