Skip to content

Commit

Permalink
merge main
Browse files Browse the repository at this point in the history
Signed-off-by: stefan.pingel@consensys.net <stefan.pingel@consensys.net>
  • Loading branch information
pinges committed Sep 5, 2024
2 parents a066ed7 + f0d2a66 commit 5797063
Show file tree
Hide file tree
Showing 37 changed files with 3,028 additions and 2,153 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@
### Breaking Changes

### Additions and Improvements
- Update Java and Gradle dependecies [#7571](https://github.com/hyperledger/besu/pull/7571)
- Layered txpool: new options `--tx-pool-min-score` to remove a tx from pool when its score is lower than the specified value [#7576](https://github.com/hyperledger/besu/pull/7576)
- Add `engine_getBlobsV1` method to the Engine API [#7553](https://github.com/hyperledger/besu/pull/7553)

### Bug fixes
- Layered txpool: do not send notifications when moving tx between layers [#7539](https://github.com/hyperledger/besu/pull/7539)
- Layered txpool: fix for unsent drop notifications on remove [#7538](https://github.com/hyperledger/besu/pull/7538)
- Honor block number or tag parameter in eth_estimateGas and eth_createAccessList [#7502](https://github.com/hyperledger/besu/pull/7502)

## 24.9.0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ static class Layered {
private static final String TX_POOL_MAX_PRIORITIZED_BY_TYPE =
"--tx-pool-max-prioritized-by-type";
private static final String TX_POOL_MAX_FUTURE_BY_SENDER = "--tx-pool-max-future-by-sender";
private static final String TX_POOL_MIN_SCORE = "--tx-pool-min-score";

@CommandLine.Option(
names = {TX_POOL_LAYER_MAX_CAPACITY},
Expand Down Expand Up @@ -196,6 +197,15 @@ static class Layered {
"Max number of future pending transactions allowed for a single sender (default: ${DEFAULT-VALUE})",
arity = "1")
Integer txPoolMaxFutureBySender = TransactionPoolConfiguration.DEFAULT_MAX_FUTURE_BY_SENDER;

@CommandLine.Option(
names = {TX_POOL_MIN_SCORE},
paramLabel = "<Byte>",
description =
"Remove a pending transaction from the txpool if its score is lower than this value."
+ "Accepts values between -128 and 127 (default: ${DEFAULT-VALUE})",
arity = "1")
Byte minScore = TransactionPoolConfiguration.DEFAULT_TX_POOL_MIN_SCORE;
}

@CommandLine.ArgGroup(
Expand Down Expand Up @@ -314,6 +324,7 @@ public static TransactionPoolOptions fromConfig(final TransactionPoolConfigurati
options.layeredOptions.txPoolMaxPrioritizedByType =
config.getMaxPrioritizedTransactionsByType();
options.layeredOptions.txPoolMaxFutureBySender = config.getMaxFutureBySender();
options.layeredOptions.minScore = config.getMinScore();
options.sequencedOptions.txPoolLimitByAccountPercentage =
config.getTxPoolLimitByAccountPercentage();
options.sequencedOptions.txPoolMaxSize = config.getTxPoolMaxSize();
Expand Down Expand Up @@ -372,6 +383,7 @@ public TransactionPoolConfiguration toDomainObject() {
.maxPrioritizedTransactions(layeredOptions.txPoolMaxPrioritized)
.maxPrioritizedTransactionsByType(layeredOptions.txPoolMaxPrioritizedByType)
.maxFutureBySender(layeredOptions.txPoolMaxFutureBySender)
.minScore(layeredOptions.minScore)
.txPoolLimitByAccountPercentage(sequencedOptions.txPoolLimitByAccountPercentage)
.txPoolMaxSize(sequencedOptions.txPoolMaxSize)
.pendingTxRetentionPeriod(sequencedOptions.pendingTxRetentionPeriod)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,24 @@ public void maxPrioritizedTxsPerTypeWrongTxType() {
"WRONG_TYPE=1");
}

@Test
public void minScoreWorks() {
final byte minScore = -10;
internalTestSuccess(
config -> assertThat(config.getMinScore()).isEqualTo(minScore),
"--tx-pool-min-score",
Byte.toString(minScore));
}

@Test
public void minScoreNonByteValueReturnError() {
final var overflowMinScore = Integer.toString(-300);
internalTestFailure(
"Invalid value for option '--tx-pool-min-score': '" + overflowMinScore + "' is not a byte",
"--tx-pool-min-score",
overflowMinScore);
}

@Override
protected TransactionPoolConfiguration createDefaultDomainObject() {
return TransactionPoolConfiguration.DEFAULT;
Expand Down
1 change: 1 addition & 0 deletions besu/src/test/resources/everything_config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ tx-pool-retention-hours=999
tx-pool-max-size=1234
tx-pool-limit-by-account-percentage=0.017
tx-pool-min-gas-price=1000
tx-pool-min-score=100

# Revert Reason
revert-reason-enabled=false
Expand Down
10 changes: 5 additions & 5 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ import java.util.regex.Pattern
plugins {
id 'com.diffplug.spotless' version '6.25.0'
id 'com.github.ben-manes.versions' version '0.51.0'
id 'com.github.jk1.dependency-license-report' version '2.7'
id 'com.jfrog.artifactory' version '5.2.0'
id 'io.spring.dependency-management' version '1.1.5'
id 'com.github.jk1.dependency-license-report' version '2.9'
id 'com.jfrog.artifactory' version '5.2.5'
id 'io.spring.dependency-management' version '1.1.6'
id 'me.champeau.jmh' version '0.7.2' apply false
id 'net.ltgt.errorprone' version '3.1.0'
id 'net.ltgt.errorprone' version '4.0.1'
id 'maven-publish'
id 'org.sonarqube' version '4.4.1.3373'
id 'org.sonarqube' version '5.1.0.4882'
}

sonarqube {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,12 @@ private void assertAccessListExpectedResult(
new JsonRpcSuccessResponse(null, new CreateAccessListResult(accessList, gasUsed));

final JsonRpcResponse response = method.response(request);
assertThat(response).usingRecursiveComparison().isEqualTo(expectedResponse);
assertThat(response)
.usingRecursiveComparison()
// customize the comparison for the type that lazy compute the hashCode
.withEqualsForType(UInt256::equals, UInt256.class)
.withEqualsForType(Address::equals, Address.class)
.isEqualTo(expectedResponse);
}

private JsonRpcRequestContext requestWithParams(final Object... params) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,19 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods;

import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonCallParameterUtil.validateAndGetCallParams;

import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcErrorConverter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonCallParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
Expand All @@ -34,32 +38,68 @@

import java.util.Optional;

public abstract class AbstractEstimateGas implements JsonRpcMethod {
public abstract class AbstractEstimateGas extends AbstractBlockParameterMethod {

private static final double SUB_CALL_REMAINING_GAS_RATIO = 65D / 64D;

protected final BlockchainQueries blockchainQueries;
protected final TransactionSimulator transactionSimulator;

public AbstractEstimateGas(
final BlockchainQueries blockchainQueries, final TransactionSimulator transactionSimulator) {
this.blockchainQueries = blockchainQueries;
super(blockchainQueries);
this.transactionSimulator = transactionSimulator;
}

protected BlockHeader blockHeader() {
final Blockchain theChain = blockchainQueries.getBlockchain();

// Optimistically get the block header for the chain head without taking a lock,
// but revert to the safe implementation if it returns an empty optional. (It's
// possible the chain head has been updated but the block is still being persisted
// to storage/cache under the lock).
return theChain
.getBlockHeader(theChain.getChainHeadHash())
.or(() -> theChain.getBlockHeaderSafe(theChain.getChainHeadHash()))
.orElse(null);
@Override
protected BlockParameter blockParameter(final JsonRpcRequestContext request) {
try {
return request.getOptionalParameter(1, BlockParameter.class).orElse(BlockParameter.LATEST);
} catch (JsonRpcParameter.JsonRpcParameterException e) {
throw new InvalidJsonRpcParameters(
"Invalid block parameter (index 1)", RpcErrorType.INVALID_BLOCK_PARAMS, e);
}
}

protected Optional<BlockHeader> blockHeader(final long blockNumber) {
if (getBlockchainQueries().headBlockNumber() == blockNumber) {
// chain head header if cached, and we can return it form memory
return Optional.of(getBlockchainQueries().getBlockchain().getChainHeadHeader());
}
return getBlockchainQueries().getBlockHeaderByNumber(blockNumber);
}

protected Optional<RpcErrorType> validateBlockHeader(
final Optional<BlockHeader> maybeBlockHeader) {
if (maybeBlockHeader.isEmpty()) {
return Optional.of(RpcErrorType.BLOCK_NOT_FOUND);
}

final var blockHeader = maybeBlockHeader.get();
if (!getBlockchainQueries()
.getWorldStateArchive()
.isWorldStateAvailable(blockHeader.getStateRoot(), blockHeader.getHash())) {
return Optional.of(RpcErrorType.WORLD_STATE_UNAVAILABLE);
}
return Optional.empty();
}

@Override
protected Object resultByBlockNumber(
final JsonRpcRequestContext requestContext, final long blockNumber) {
final JsonCallParameter jsonCallParameter = validateAndGetCallParams(requestContext);
final Optional<BlockHeader> maybeBlockHeader = blockHeader(blockNumber);
final Optional<RpcErrorType> jsonRpcError = validateBlockHeader(maybeBlockHeader);
if (jsonRpcError.isPresent()) {
return errorResponse(requestContext, jsonRpcError.get());
}
return resultByBlockHeader(requestContext, jsonCallParameter, maybeBlockHeader.get());
}

protected abstract Object resultByBlockHeader(
final JsonRpcRequestContext requestContext,
final JsonCallParameter jsonCallParameter,
final BlockHeader blockHeader);

protected CallParameter overrideGasLimitAndPrice(
final JsonCallParameter callParams, final long gasLimit) {
return new CallParameter(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,11 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods;

import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonCallParameterUtil.validateAndGetCallParams;

import org.hyperledger.besu.datatypes.AccessListEntry;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonCallParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.CreateAccessListResult;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
Expand Down Expand Up @@ -52,44 +48,29 @@ public String getName() {
}

@Override
public JsonRpcResponse response(final JsonRpcRequestContext requestContext) {
final JsonCallParameter jsonCallParameter = validateAndGetCallParams(requestContext);
final BlockHeader blockHeader = blockHeader();
final Optional<RpcErrorType> jsonRpcError = validateBlockHeader(blockHeader);
if (jsonRpcError.isPresent()) {
return errorResponse(requestContext, jsonRpcError.get());
}
protected Object resultByBlockHeader(
final JsonRpcRequestContext requestContext,
final JsonCallParameter jsonCallParameter,
final BlockHeader blockHeader) {
final AccessListSimulatorResult maybeResult =
processTransaction(jsonCallParameter, blockHeader);
// if the call accessList is different from the simulation result, calculate gas and return
if (shouldProcessWithAccessListOverride(jsonCallParameter, maybeResult.getTracer())) {
if (shouldProcessWithAccessListOverride(jsonCallParameter, maybeResult.tracer())) {
final AccessListSimulatorResult result =
processTransactionWithAccessListOverride(
jsonCallParameter, blockHeader, maybeResult.getTracer().getAccessList());
jsonCallParameter, blockHeader, maybeResult.tracer().getAccessList());
return createResponse(requestContext, result);
} else {
return createResponse(requestContext, maybeResult);
}
}

private Optional<RpcErrorType> validateBlockHeader(final BlockHeader blockHeader) {
if (blockHeader == null) {
return Optional.of(RpcErrorType.INTERNAL_ERROR);
}
if (!blockchainQueries
.getWorldStateArchive()
.isWorldStateAvailable(blockHeader.getStateRoot(), blockHeader.getHash())) {
return Optional.of(RpcErrorType.WORLD_STATE_UNAVAILABLE);
}
return Optional.empty();
}

private JsonRpcResponse createResponse(
private Object createResponse(
final JsonRpcRequestContext requestContext, final AccessListSimulatorResult result) {
return result
.getResult()
.map(createResponse(requestContext, result.getTracer()))
.orElse(errorResponse(requestContext, RpcErrorType.INTERNAL_ERROR));
.result()
.map(createResponse(requestContext, result.tracer()))
.orElseGet(() -> errorResponse(requestContext, RpcErrorType.INTERNAL_ERROR));
}

private TransactionValidationParams transactionValidationParams(
Expand Down Expand Up @@ -117,14 +98,12 @@ private boolean shouldProcessWithAccessListOverride(
return !Objects.equals(tracer.getAccessList(), parameters.getAccessList().get());
}

private Function<TransactionSimulatorResult, JsonRpcResponse> createResponse(
private Function<TransactionSimulatorResult, Object> createResponse(
final JsonRpcRequestContext request, final AccessListOperationTracer operationTracer) {
return result ->
result.isSuccessful()
? new JsonRpcSuccessResponse(
request.getRequest().getId(),
new CreateAccessListResult(
operationTracer.getAccessList(), processEstimateGas(result, operationTracer)))
? new CreateAccessListResult(
operationTracer.getAccessList(), processEstimateGas(result, operationTracer))
: errorResponse(request, result);
}

Expand All @@ -138,8 +117,7 @@ private AccessListSimulatorResult processTransaction(

final AccessListOperationTracer tracer = AccessListOperationTracer.create();
final Optional<TransactionSimulatorResult> result =
transactionSimulator.process(
callParams, transactionValidationParams, tracer, blockHeader.getNumber());
transactionSimulator.process(callParams, transactionValidationParams, tracer, blockHeader);
return new AccessListSimulatorResult(result, tracer);
}

Expand All @@ -156,7 +134,7 @@ private AccessListSimulatorResult processTransactionWithAccessListOverride(

final Optional<TransactionSimulatorResult> result =
transactionSimulator.process(
callParameter, transactionValidationParams, tracer, blockHeader.getNumber());
callParameter, transactionValidationParams, tracer, blockHeader);
return new AccessListSimulatorResult(result, tracer);
}

Expand All @@ -176,22 +154,6 @@ protected CallParameter overrideAccessList(
Optional.ofNullable(accessListEntries));
}

private static class AccessListSimulatorResult {
final Optional<TransactionSimulatorResult> result;
final AccessListOperationTracer tracer;

public AccessListSimulatorResult(
final Optional<TransactionSimulatorResult> result, final AccessListOperationTracer tracer) {
this.result = result;
this.tracer = tracer;
}

public Optional<TransactionSimulatorResult> getResult() {
return result;
}

public AccessListOperationTracer getTracer() {
return tracer;
}
}
private record AccessListSimulatorResult(
Optional<TransactionSimulatorResult> result, AccessListOperationTracer tracer) {}
}
Loading

0 comments on commit 5797063

Please sign in to comment.