Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Rejected transaction reporting due to trace line limits #111

Merged
merged 5 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -48,15 +44,11 @@ public class AllowedAddressValidator implements PluginTransactionPoolValidator {
Address.fromHexString("0x000000000000000000000000000000000000000a"));

private final Set<Address> denied;
private final Optional<JsonRpcManager> rejectedTxJsonRpcManager;

@Override
public Optional<String> validateTransaction(
final Transaction transaction, final boolean isLocal, final boolean hasPriority) {
final Optional<String> errMsg =
validateSender(transaction).or(() -> validateRecipient(transaction));
errMsg.ifPresent(reason -> reportRejectedTransaction(transaction, reason));
return errMsg;
return validateSender(transaction).or(() -> validateRecipient(transaction));
}

private Optional<String> validateRecipient(final Transaction transaction) {
Expand Down Expand Up @@ -90,19 +82,4 @@ private Optional<String> 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);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -31,7 +27,6 @@
@RequiredArgsConstructor
public class CalldataValidator implements PluginTransactionPoolValidator {
final LineaTransactionPoolValidatorConfiguration txPoolValidatorConf;
final Optional<JsonRpcManager> rejectedTxJsonRpcManager;

@Override
public Optional<String> validateTransaction(
Expand All @@ -41,24 +36,8 @@ public Optional<String> 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);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -34,7 +30,6 @@
@RequiredArgsConstructor
public class GasLimitValidator implements PluginTransactionPoolValidator {
final LineaTransactionPoolValidatorConfiguration txPoolValidatorConf;
final Optional<JsonRpcManager> rejectedTxJsonRpcManager;

@Override
public Optional<String> validateTransaction(
Expand All @@ -44,24 +39,8 @@ public Optional<String> 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);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -41,18 +37,15 @@ public class ProfitabilityValidator implements PluginTransactionPoolValidator {
final BlockchainService blockchainService;
final LineaProfitabilityConfiguration profitabilityConf;
final TransactionProfitabilityCalculator profitabilityCalculator;
final Optional<JsonRpcManager> rejectedTxJsonRpcManager;

public ProfitabilityValidator(
final BesuConfiguration besuConfiguration,
final BlockchainService blockchainService,
final LineaProfitabilityConfiguration profitabilityConf,
final Optional<JsonRpcManager> rejectedTxJsonRpcManager) {
final LineaProfitabilityConfiguration profitabilityConf) {
this.besuConfiguration = besuConfiguration;
this.blockchainService = blockchainService;
this.profitabilityConf = profitabilityConf;
this.profitabilityCalculator = new TransactionProfitabilityCalculator(profitabilityConf);
this.rejectedTxJsonRpcManager = rejectedTxJsonRpcManager;
}

@Override
Expand All @@ -68,19 +61,16 @@ public Optional<String> validateTransaction(
.getNextBlockBaseFee()
.orElseThrow(() -> new RuntimeException("We only support a base fee market"));

final Optional<String> 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();
Expand All @@ -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);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@ public Optional<String> validateTransaction(
"Invalid transaction"
+ simulationResult.getInvalidReason().map(ir -> ": " + ir).orElse("");
log.debug(errMsg);
reportRejectedTransaction(transaction, errMsg);
return Optional.of(errMsg);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,16 @@
*/
package net.consensys.linea.sequencer.txselection.selectors;

import static net.consensys.linea.sequencer.txselection.LineaTransactionSelectionResult.BLOCK_MODULE_LINE_COUNT_FULL;
fab-10 marked this conversation as resolved.
Show resolved Hide resolved
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;
Expand All @@ -41,6 +47,7 @@ public class LineaTransactionSelector implements PluginTransactionSelector {
private TraceLineLimitTransactionSelector traceLineLimitTransactionSelector;
private final List<PluginTransactionSelector> selectors;
private final Optional<JsonRpcManager> rejectedTxJsonRpcManager;
private final Set<String> rejectedTransactionReasonsMap = new HashSet<>();

public LineaTransactionSelector(
final BlockchainService blockchainService,
Expand All @@ -51,6 +58,13 @@ public LineaTransactionSelector(
final Map<String, Integer> limitsMap,
final Optional<JsonRpcManager> 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,
Expand Down Expand Up @@ -163,7 +177,8 @@ public void onTransactionNotSelected(

rejectedTxJsonRpcManager.ifPresent(
jsonRpcManager -> {
if (transactionSelectionResult.discard()) {
if (transactionSelectionResult.discard()
&& rejectedTransactionReasonsMap.contains(transactionSelectionResult.toString())) {
jsonRpcManager.submitNewJsonRpcCallAsync(
JsonRpcRequestBuilder.generateSaveRejectedTxJsonRpc(
jsonRpcManager.getNodeType(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public class AllowedAddressValidatorTest {
@BeforeEach
public void initialize() {
Set<Address> denied = Set.of(DENIED);
allowedAddressValidator = new AllowedAddressValidator(denied, Optional.empty());
allowedAddressValidator = new AllowedAddressValidator(denied);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ public void initialize() {
new CalldataValidator(
LineaTransactionPoolValidatorCliOptions.create().toDomainObject().toBuilder()
.maxTxCalldataSize(MAX_TX_CALLDATA_SIZE)
.build(),
Optional.empty());
.build());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ public void initialize() {
new GasLimitValidator(
LineaTransactionPoolValidatorCliOptions.create().toDomainObject().toBuilder()
.maxTxGasLimit(MAX_TX_GAS_LIMIT)
.build(),
Optional.empty());
.build());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,7 @@ public void initialize() {
profitabilityConfBuilder
.txPoolCheckP2pEnabled(true)
.txPoolCheckApiEnabled(true)
.build(),
Optional.empty());
.build());

profitabilityValidatorNever =
new ProfitabilityValidator(
Expand All @@ -97,8 +96,7 @@ public void initialize() {
profitabilityConfBuilder
.txPoolCheckP2pEnabled(false)
.txPoolCheckApiEnabled(false)
.build(),
Optional.empty());
.build());

profitabilityValidatorOnlyApi =
new ProfitabilityValidator(
Expand All @@ -107,8 +105,7 @@ public void initialize() {
profitabilityConfBuilder
.txPoolCheckP2pEnabled(false)
.txPoolCheckApiEnabled(true)
.build(),
Optional.empty());
.build());

profitabilityValidatorOnlyP2p =
new ProfitabilityValidator(
Expand All @@ -117,8 +114,7 @@ public void initialize() {
profitabilityConfBuilder
.txPoolCheckP2pEnabled(true)
.txPoolCheckApiEnabled(false)
.build(),
Optional.empty());
.build());
}

@Test
Expand Down
Loading