Skip to content

Commit

Permalink
feat: Rejected transaction reporting due to trace line limits (#111)
Browse files Browse the repository at this point in the history
- Rejected transaction reporting due to trace line limits
- Remove other rejected transactions reporting
- test fixes
  • Loading branch information
usmansaleem authored Nov 27, 2024
1 parent 0535705 commit 4d925ad
Show file tree
Hide file tree
Showing 12 changed files with 39 additions and 122 deletions.
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,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;
Expand All @@ -41,6 +46,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 +57,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 +176,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

0 comments on commit 4d925ad

Please sign in to comment.