Merge branch 'main' into zkbesu

# Conflicts:
#	.github/pull_request_template.md
#	.github/workflows/acceptance-tests.yml
#	.github/workflows/artifacts.yml
#	.github/workflows/integration-tests.yml
#	.github/workflows/pre-review.yml
#	.github/workflows/reference-tests.yml
#	.github/workflows/sonarcloud.yml
#	build.gradle
#	ethereum/evmtool/build.gradle
#	gradle.properties
This commit is contained in:
Fabio Di Fabio
2024-03-21 11:03:49 +01:00
123 changed files with 1422 additions and 324 deletions

View File

@@ -1,64 +0,0 @@
name: develop pre-release
on:
push:
branches:
- main
env:
GRADLE_OPTS: "-Dorg.gradle.parallel=true -Dorg.gradle.caching=true"
jobs:
artifacts:
runs-on: ubuntu-22.04
permissions:
contents: write
steps:
- name: checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
- name: Set up JDK 17
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93
with:
distribution: 'temurin'
java-version: '17'
- name: setup gradle
uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1
with:
cache-disabled: true
- name: assemble release
run:
./gradlew assemble
- name: upload tarball
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3
with:
path: 'build/distributions/besu*.tar.gz'
name: besu-develop.tar.gz
compression-level: 0
- name: hashes
id: hashes
run: |
cd build/distributions
echo "zipSha=$(shasum -a 256 besu*.zip)" >> $GITHUB_OUTPUT
echo "tarSha=$(shasum -a 256 besu*.tar.gz)" >> $GITHUB_OUTPUT
- name: upload zipfile
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3
with:
path: 'build/distributions/besu*.zip'
name: besu-develop.zip
compression-level: 0
- name: Upload Release assets
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844
with:
prerelease: true
name: develop
tag_name: develop
fail_on_unmatched_files: true
append_body: false
files: |
build/distributions/besu*.tar.gz
build/distributions/besu*.zip
body: |
This is an automated, bleeding edge build from the tip of ${{ github.ref_name }}. No promises. YOLO.
${{steps.hashes.outputs.tarSha}}
${{steps.hashes.outputs.zipSha}}

View File

@@ -11,16 +11,19 @@
### Deprecations
### Additions and Improvements
- `txpool_besuPendingTransactions`change parameter `numResults` to optional parameter [#6708](https://github.com/hyperledger/besu/pull/6708)
- Extend `Blockchain` service [#6592](https://github.com/hyperledger/besu/pull/6592)
- Add bft-style blockperiodseconds transitions to Clique [#6596](https://github.com/hyperledger/besu/pull/6596)
- Add createemptyblocks transitions to Clique [#6608](https://github.com/hyperledger/besu/pull/6608)
- Add bft-style `blockperiodseconds` transitions to Clique [#6596](https://github.com/hyperledger/besu/pull/6596)
- Add `createemptyblocks` transitions to Clique [#6608](https://github.com/hyperledger/besu/pull/6608)
- RocksDB database metadata refactoring [#6555](https://github.com/hyperledger/besu/pull/6555)
- Make layered txpool aware of minGasPrice and minPriorityFeePerGas dynamic options [#6611](https://github.com/hyperledger/besu/pull/6611)
- Make layered txpool aware of `minGasPrice` and `minPriorityFeePerGas` dynamic options [#6611](https://github.com/hyperledger/besu/pull/6611)
- Update commons-compress to 1.26.0 [#6648](https://github.com/hyperledger/besu/pull/6648)
- Update Vert.x to 4.5.4 [#6666](https://github.com/hyperledger/besu/pull/6666)
- Refactor and extend `TransactionPoolValidatorService` [#6636](https://github.com/hyperledger/besu/pull/6636)
- Transaction call object to accept both `input` and `data` field simultaneously if they are set to equal values [#6702](https://github.com/hyperledger/besu/pull/6702)
- Introduce `TransactionSimulationService` [#6686](https://github.com/hyperledger/besu/pull/6686)
- Transaction call object to accept both `input` and `data` field simultaneously if they are set to equal values [#6702](https://github.com/hyperledger/besu/pull/6702)
- `eth_call` for blob tx allows for empty `maxFeePerBlobGas` [#6731](https://github.com/hyperledger/besu/pull/6731)
- Extend error handling of plugin RPC methods [#6759](https://github.com/hyperledger/besu/pull/6759)
### Bug fixes
- Fix txpool dump/restore race condition [#6665](https://github.com/hyperledger/besu/pull/6665)
@@ -2325,7 +2328,7 @@ Workaround - Limit the number of blocks queried by each `eth_getLogs` call.
- Implemented private contract log filters including JSON-RPC methods to interact with private filters. [\#735](https://github.com/hyperledger/besu/pull/735)
- Implemented EIP-2315: Simple Subroutines for the EVM [\#717](https://github.com/hyperledger/besu/pull/717)
- Implemented Splunk logging. [\#725](https://github.com/hyperledger/besu/pull/725)
- Implemented optional native library encryption. [\#675](https://github.com/hyperledger/besu/pull/675). To enable add `--Xsecp256k1-native-enabled` (for transaciton signatures) and/or `--Xaltbn128-native-enabled` (for altbn128 precomiled contracts) as command line options.
- Implemented optional native library encryption. [\#675](https://github.com/hyperledger/besu/pull/675). To enable add `--Xsecp256k1-native-enabled` (for transaction signatures) and/or `--Xaltbn128-native-enabled` (for altbn128 precomiled contracts) as command line options.
### Bug Fixes
@@ -2507,7 +2510,7 @@ Early access features are available features that are not recommended for produc
have unstable interfaces.
* [Onchain privacy groups](https://besu.hyperledger.org/en/latest/Concepts/Privacy/Onchain-PrivacyGroups/) with add and remove members.
Not being able to to re-add a member to an onchain privacy group is a [known issue](https://github.com/hyperledger/besu/issues/455)
Not being able to re-add a member to an onchain privacy group is a [known issue](https://github.com/hyperledger/besu/issues/455)
with the add and remove functionality.
### Known Issues

View File

@@ -106,7 +106,8 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
final TransactionPoolValidatorServiceImpl transactionPoolValidatorServiceImpl,
final BlockchainServiceImpl blockchainServiceImpl,
final RpcEndpointServiceImpl rpcEndpointServiceImpl,
final BesuConfiguration commonPluginConfiguration) {
final BesuConfiguration commonPluginConfiguration,
final PermissioningServiceImpl permissioningService) {
final CommandLine commandLine = new CommandLine(CommandSpec.create());
final BesuPluginContextImpl besuPluginContext = new BesuPluginContextImpl();
besuPluginContext.addService(StorageService.class, storageService);
@@ -137,7 +138,7 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
}
besuPluginContext.addService(BesuConfiguration.class, commonPluginConfiguration);
besuPluginContext.addService(PermissioningService.class, new PermissioningServiceImpl());
besuPluginContext.addService(PermissioningService.class, permissioningService);
besuPluginContext.addService(PrivacyPluginService.class, new PrivacyPluginServiceImpl());
besuPluginContext.registerPlugins(pluginsPath);
@@ -172,6 +173,8 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
final RpcEndpointServiceImpl rpcEndpointServiceImpl = new RpcEndpointServiceImpl();
final Path dataDir = node.homeDirectory();
final BesuConfigurationImpl commonPluginConfiguration = new BesuConfigurationImpl();
final PermissioningServiceImpl permissioningService = new PermissioningServiceImpl();
final var miningParameters =
ImmutableMiningParameters.builder()
.from(node.getMiningParameters())
@@ -195,7 +198,8 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
transactionPoolValidatorServiceImpl,
blockchainServiceImpl,
rpcEndpointServiceImpl,
commonPluginConfiguration));
commonPluginConfiguration,
permissioningService));
GlobalOpenTelemetry.resetForTest();
final ObservableMetricsSystem metricsSystem =
@@ -283,7 +287,7 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
.jsonRpcIpcConfiguration(node.jsonRpcIpcConfiguration())
.dataDir(node.homeDirectory())
.metricsSystem(metricsSystem)
.permissioningService(new PermissioningServiceImpl())
.permissioningService(permissioningService)
.metricsConfiguration(node.getMetricsConfiguration())
.p2pEnabled(node.isP2pEnabled())
.p2pTLSConfiguration(node.getTLSConfiguration())
@@ -292,15 +296,14 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
node.getStaticNodes().stream()
.map(EnodeURLImpl::fromString)
.collect(Collectors.toList()))
.besuPluginContext(new BesuPluginContextImpl())
.besuPluginContext(besuPluginContext)
.autoLogBloomCaching(false)
.storageProvider(storageProvider)
.rpcEndpointService(rpcEndpointServiceImpl);
node.engineRpcConfiguration().ifPresent(runnerBuilder::engineJsonRpcConfiguration);
final Runner runner = runnerBuilder.build();
besuPluginContext.beforeExternalServices();
final Runner runner = runnerBuilder.build();
runner.startExternalServices();

View File

@@ -25,6 +25,7 @@ import java.math.BigInteger;
import java.util.function.UnaryOperator;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
public class EthSendRawTransactionAcceptanceTest extends AcceptanceTestBase {
@@ -51,12 +52,15 @@ public class EthSendRawTransactionAcceptanceTest extends AcceptanceTestBase {
}
@Test
@Disabled("flaky with timeout")
public void shouldSendSuccessfullyToLenientNodeWithoutChainId() {
final TransferTransaction tx = createTransactionWithoutChainId();
final String rawTx = tx.signedTransactionData();
final String txHash = tx.transactionHash();
lenientNode.verify(eth.expectSuccessfulEthRawTransaction(rawTx));
// this line is where the test is flaky
// Tx should be included on-chain
miningNode.verify(eth.expectSuccessfulTransactionReceipt(txHash));
}

View File

@@ -37,22 +37,13 @@ public class PermissioningPluginTest extends AcceptanceTestBaseJunit5 {
@BeforeEach
public void setUp() throws Exception {
final BesuNodeConfigurationBuilder builder =
new BesuNodeConfigurationBuilder()
.miningEnabled(false)
.plugins(List.of("testPlugins"))
.extraCLIOptions(List.of("--plugin-permissioning-test-enabled=true"))
.jsonRpcEnabled()
.jsonRpcTxPool()
.jsonRpcAdmin();
minerNode = besu.create(createNodeBuilder().name("miner").build());
minerNode = besu.create(builder.name("miner").build());
aliceNode = besu.create(createNodeBuilder().name("alice").keyFilePath("key").build());
aliceNode = besu.create(builder.name("alice").keyFilePath("key").build());
bobNode = besu.create(createNodeBuilder().name("bob").keyFilePath("key1").build());
bobNode = besu.create(builder.name("bob").keyFilePath("key1").build());
charlieNode = besu.create(builder.name("charlie").keyFilePath("key2").build());
charlieNode = besu.create(createNodeBuilder().name("charlie").keyFilePath("key2").build());
cluster.start(minerNode, charlieNode);
@@ -63,6 +54,16 @@ public class PermissioningPluginTest extends AcceptanceTestBaseJunit5 {
bobNode.awaitPeerDiscovery(net.awaitPeerCount(2));
}
private BesuNodeConfigurationBuilder createNodeBuilder() {
return new BesuNodeConfigurationBuilder()
.miningEnabled(false)
.plugins(List.of("testPlugins"))
.extraCLIOptions(List.of("--plugin-permissioning-test-enabled=true"))
.jsonRpcEnabled()
.jsonRpcTxPool()
.jsonRpcAdmin();
}
@Test
public void blockedConnectionNodeCanOnlyConnectToTransactionNode() {
minerNode.verify(admin.hasPeer(aliceNode));

View File

@@ -2598,7 +2598,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
}
/**
* Returns the flag indicating that version compatiblity checks will be made.
* Returns the flag indicating that version compatibility checks will be made.
*
* @return true if compatibility checks should be made, otherwise false
*/

View File

@@ -130,6 +130,7 @@ public class CliqueBesuControllerBuilder extends BesuControllerBuilder {
privacyParameters,
isRevertReasonEnabled,
evmConfiguration,
miningParameters,
badBlockManager);
}

View File

@@ -286,6 +286,7 @@ public class IbftBesuControllerBuilder extends BftBesuControllerBuilder {
isRevertReasonEnabled,
bftExtraDataCodec().get(),
evmConfiguration,
miningParameters,
badBlockManager);
}

View File

@@ -95,6 +95,7 @@ public class MainnetBesuControllerBuilder extends BesuControllerBuilder {
privacyParameters,
isRevertReasonEnabled,
evmConfiguration,
miningParameters,
badBlockManager);
}

View File

@@ -173,7 +173,11 @@ public class MergeBesuControllerBuilder extends BesuControllerBuilder {
@Override
protected ProtocolSchedule createProtocolSchedule() {
return MergeProtocolSchedule.create(
configOptionsSupplier.get(), privacyParameters, isRevertReasonEnabled, badBlockManager);
configOptionsSupplier.get(),
privacyParameters,
isRevertReasonEnabled,
miningParameters,
badBlockManager);
}
@Override

View File

@@ -326,6 +326,7 @@ public class QbftBesuControllerBuilder extends BftBesuControllerBuilder {
isRevertReasonEnabled,
bftExtraDataCodec().get(),
evmConfiguration,
miningParameters,
badBlockManager);
}

View File

@@ -19,7 +19,10 @@ import org.hyperledger.besu.datatypes.Transaction;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.mainnet.ImmutableTransactionValidationParams;
import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams;
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.transaction.CallParameter;
import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
import org.hyperledger.besu.ethereum.transaction.TransactionSimulator;
import org.hyperledger.besu.evm.tracing.OperationTracer;
import org.hyperledger.besu.plugin.Unstable;
@@ -62,14 +65,16 @@ public class TransactionSimulationServiceImpl implements TransactionSimulationSe
final CallParameter callParameter = CallParameter.fromTransaction(transaction);
final var blockHeader =
blockchain
.getBlockHeader(blockHash)
.or(() -> blockchain.getBlockHeaderSafe(blockHash))
.orElseThrow(
() ->
new IllegalStateException(
"Block header not yet present for chain head hash: " + blockHash));
final var maybeBlockHeader =
blockchain.getBlockHeader(blockHash).or(() -> blockchain.getBlockHeaderSafe(blockHash));
if (maybeBlockHeader.isEmpty()) {
return Optional.of(
new TransactionSimulationResult(
transaction,
TransactionProcessingResult.invalid(
ValidationResult.invalid(TransactionInvalidReason.BLOCK_NOT_FOUND))));
}
return transactionSimulator
.process(
@@ -78,7 +83,7 @@ public class TransactionSimulationServiceImpl implements TransactionSimulationSe
? SIMULATOR_ALLOWING_EXCEEDING_BALANCE
: TransactionValidationParams.transactionSimulator(),
operationTracer,
blockHeader)
maybeBlockHeader.get())
.map(res -> new TransactionSimulationResult(transaction, res.result()));
}
}

View File

@@ -33,6 +33,7 @@ import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.chain.GenesisState;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.MilestoneStreamingProtocolSchedule;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.forkid.ForkId;
import org.hyperledger.besu.ethereum.forkid.ForkIdManager;
import org.hyperledger.besu.ethereum.mainnet.DefaultProtocolSchedule;
@@ -188,11 +189,13 @@ public class ForkIdsNetworkConfigTest {
MilestoneStreamingProtocolSchedule preMergeProtocolSchedule =
new MilestoneStreamingProtocolSchedule(
(DefaultProtocolSchedule)
MainnetProtocolSchedule.fromConfig(configOptions, new BadBlockManager()));
MainnetProtocolSchedule.fromConfig(
configOptions, MiningParameters.MINING_DISABLED, new BadBlockManager()));
MilestoneStreamingProtocolSchedule postMergeProtocolSchedule =
new MilestoneStreamingProtocolSchedule(
(DefaultProtocolSchedule)
MergeProtocolSchedule.create(configOptions, false, new BadBlockManager()));
MergeProtocolSchedule.create(
configOptions, false, MiningParameters.MINING_DISABLED, new BadBlockManager()));
final MilestoneStreamingTransitionProtocolSchedule schedule =
new MilestoneStreamingTransitionProtocolSchedule(
preMergeProtocolSchedule, postMergeProtocolSchedule);

View File

@@ -105,7 +105,7 @@ allprojects {
apply plugin: 'net.ltgt.errorprone'
apply from: "${rootDir}/gradle/versions.gradle"
version = rootProject.version
version = calculateVersion()
jacoco {
toolVersion = '0.8.8'
@@ -664,12 +664,30 @@ publishing {
groupId = '.'
version = project.version
artifactId = 'linea-besu'
artifact("$buildDir/distributions/linea-besu-${project.version}.zip")
artifact("$buildDir/distributions/linea-besu-${project.version}.tar.gz") { extension = 'tar.gz' }
}
}
}
def artifactoryUser = project.hasProperty('artifactoryUser') ? project.property('artifactoryUser') : System.getenv('ARTIFACTORY_USER')
def artifactoryKey = project.hasProperty('artifactoryApiKey') ? project.property('artifactoryApiKey') : System.getenv('ARTIFACTORY_KEY')
def artifactoryOrg = System.getenv('ARTIFACTORY_ORG') ?: 'hyperledger'
artifactory {
contextUrl = "https://hyperledger.jfrog.io/${artifactoryOrg}"
publish {
defaults {
publications('distArtifactory')
publishArtifacts = true
publishPom = false
}
}
}
artifactoryPublish {
dependsOn distTar
dependsOn distZip
}
def dockerBuildVersion = project.hasProperty('release.releaseVersion') ? project.property('release.releaseVersion') : "${rootProject.version}"
def dockerOrgName = project.hasProperty('dockerOrgName') ? project.getProperty("dockerOrgName") : "hyperledger"
def dockerArtifactName = project.hasProperty("dockerArtifactName") ? project.getProperty("dockerArtifactName") : "besu"
@@ -720,9 +738,10 @@ task distDocker {
dockerPlatform = "--platform ${project.getProperty('docker-platform')}"
println "Building for platform ${project.getProperty('docker-platform')}"
}
def gitDetails = getGitCommitDetails(10)
executable "sh"
workingDir dockerBuildDir
args "-c", "docker build ${dockerPlatform} --build-arg BUILD_DATE=${buildTime()} --build-arg VERSION=${dockerBuildVersion} --build-arg VCS_REF=${getCheckedOutGitCommitHash()} -t ${image} ."
args "-c", "docker build ${dockerPlatform} --build-arg BUILD_DATE=${buildTime()} --build-arg VERSION=${dockerBuildVersion} --build-arg VCS_REF=${gitDetails.hash} -t ${image} ."
}
}
@@ -992,42 +1011,50 @@ def buildTime() {
return df.format(new Date())
}
// Takes the version, and if -SNAPSHOT is part of it replaces SNAPSHOT
// with the git commit version.
@Memoized
def calculateVersion() {
String version = rootProject.version
if (version.endsWith("-SNAPSHOT")) {
version = version.replace("-SNAPSHOT", "-dev-" + getCheckedOutGitCommitHash())
// Regex pattern for basic calendar versioning, with provision to omit patch rev
def calVerPattern = ~/\d+\.\d+(\.\d+)?(-.*)?/
if (project.hasProperty('version') && (project.version =~ calVerPattern)) {
return "${project.version}"
} else {
// If no version is supplied or it doesn't match the semantic versioning, calculate from git
println("Generating project version as supplied is version not semver: ${project.version}")
def gitDetails = getGitCommitDetails(10) // Adjust length as needed
return "${gitDetails.date}-develop-${gitDetails.hash}"
}
return version
}
def getCheckedOutGitCommitHash(length = 8) {
def getGitCommitDetails(length = 8) {
try {
def gitFolder = "$projectDir/.git/"
if (!file(gitFolder).isDirectory()) {
// We are in a submodule. The file's contents are `gitdir: <gitFolder>\n`.
// Read the file, cut off the front, and trim the whitespace.
gitFolder = file(gitFolder).text.substring(length).trim() + "/"
}
def takeFromHash = length
/*
* '.git/HEAD' contains either
* in case of detached head: the currently checked out commit hash
* otherwise: a reference to a file containing the current commit hash
*/
def head = new File(gitFolder + "HEAD").text.split(":") // .git/HEAD
def isCommit = head.length == 1 // e5a7c79edabbf7dd39888442df081b1c9d8e88fd
def head = new File(gitFolder + "HEAD").text.split(":")
def isCommit = head.length == 1
if (isCommit) return head[0].trim().take(takeFromHash) // e5a7c79edabb
def commitHash, refHeadFile
if (isCommit) {
commitHash = head[0].trim().take(takeFromHash)
refHeadFile = new File(gitFolder + "HEAD")
} else {
refHeadFile = new File(gitFolder + head[1].trim())
commitHash = refHeadFile.text.trim().take(takeFromHash)
}
def refHead = new File(gitFolder + head[1].trim()) // .git/refs/heads/master
refHead.text.trim().take takeFromHash
// Use head file modification time as a proxy for the build date
def lastModified = new Date(refHeadFile.lastModified())
// Format the date as "yy.M" (e.g. 24.3 for March 2024)
def formattedDate = new SimpleDateFormat("yy.M").format(lastModified)
return [hash: commitHash, date: formattedDate]
} catch (Exception e) {
logger.warn('Could not calculate git commit, using "xxxxxxxx" (run with --info for stacktrace)')
logger.info('Error retrieving git commit', e)
return "xxxxxxxx"
logger.warn('Could not calculate git commit details, using defaults (run with --info for stacktrace)')
logger.info('Error retrieving git commit details', e)
return [hash: "xxxxxxxx", date: "00.0"]
}
}

View File

@@ -515,6 +515,13 @@ public interface GenesisConfigOptions {
*/
boolean isZeroBaseFee();
/**
* Force a Base Fee as Gas Price network to used with London/EIP-1559.
*
* @return true, if you want the next block to use the base fee as gas price.
*/
boolean isFixedBaseFee();
/**
* The deposit contract address that should be in the logger field in Receipt of Deposit
* transaction

View File

@@ -47,6 +47,7 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions {
private static final String DISCOVERY_CONFIG_KEY = "discovery";
private static final String CHECKPOINT_CONFIG_KEY = "checkpoint";
private static final String ZERO_BASE_FEE_KEY = "zerobasefee";
private static final String FIXED_BASE_FEE_KEY = "fixedbasefee";
private static final String DEPOSIT_CONTRACT_ADDRESS_KEY = "depositcontractaddress";
private final ObjectNode configRoot;
@@ -431,6 +432,11 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions {
return getOptionalBoolean(ZERO_BASE_FEE_KEY).orElse(false);
}
@Override
public boolean isFixedBaseFee() {
return getOptionalBoolean(FIXED_BASE_FEE_KEY).orElse(false);
}
@Override
public Optional<Address> getDepositContractAddress() {
Optional<String> inputAddress = JsonUtil.getString(configRoot, DEPOSIT_CONTRACT_ADDRESS_KEY);
@@ -505,6 +511,10 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions {
builder.put("zeroBaseFee", true);
}
if (isFixedBaseFee()) {
builder.put("fixedBaseFee", true);
}
return builder.build();
}

View File

@@ -81,6 +81,7 @@ public class StubGenesisConfigOptions implements GenesisConfigOptions, Cloneable
private TransitionsConfigOptions transitions = TransitionsConfigOptions.DEFAULT;
private static final DiscoveryOptions DISCOVERY_OPTIONS = DiscoveryOptions.DEFAULT;
private boolean zeroBaseFee = false;
private boolean fixedBaseFee = false;
@Override
public StubGenesisConfigOptions clone() {
@@ -440,6 +441,11 @@ public class StubGenesisConfigOptions implements GenesisConfigOptions, Cloneable
return zeroBaseFee;
}
@Override
public boolean isFixedBaseFee() {
return fixedBaseFee;
}
@Override
public List<Long> getForkBlockNumbers() {
return Collections.emptyList();
@@ -742,6 +748,17 @@ public class StubGenesisConfigOptions implements GenesisConfigOptions, Cloneable
return this;
}
/**
* Fixed base fee per gas stub genesis config options.
*
* @param fixedBaseFee the zero base fee override
* @return the stub genesis config options
*/
public StubGenesisConfigOptions fixedBaseFee(final boolean fixedBaseFee) {
this.fixedBaseFee = fixedBaseFee;
return this;
}
/**
* Classic fork block stub genesis config options.
*

View File

@@ -295,6 +295,27 @@ class GenesisConfigOptionsTest {
assertThat(config.asMap()).containsOnlyKeys("zeroBaseFee").containsValue(true);
}
@Test
void isFixedBaseFeeShouldDefaultToFalse() {
final GenesisConfigOptions config = GenesisConfigFile.fromConfig("{}").getConfigOptions();
assertThat(config.isFixedBaseFee()).isFalse();
}
@Test
void isFixedBaseFeeParsedCorrectly() {
final GenesisConfigOptions config = fromConfigOptions(Map.of("fixedbasefee", true));
assertThat(config.isFixedBaseFee()).isTrue();
}
@Test
void asMapIncludesFixedBaseFee() {
final GenesisConfigOptions config = fromConfigOptions(Map.of("fixedbasefee", true));
assertThat(config.asMap()).containsOnlyKeys("fixedBaseFee").containsValue(true);
}
@Test
void shouldGetDepositContractAddress() {
final GenesisConfigOptions config =

View File

@@ -22,6 +22,7 @@ import org.hyperledger.besu.cryptoservices.NodeKey;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.core.Util;
import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator;
@@ -58,6 +59,7 @@ public class CliqueProtocolSchedule {
* @param privacyParameters the privacy parameters
* @param isRevertReasonEnabled the is revert reason enabled
* @param evmConfiguration the evm configuration
* @param miningParameters the mining parameters
* @param badBlockManager the cache to use to keep invalid blocks
* @return the protocol schedule
*/
@@ -68,6 +70,7 @@ public class CliqueProtocolSchedule {
final PrivacyParameters privacyParameters,
final boolean isRevertReasonEnabled,
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters,
final BadBlockManager badBlockManager) {
final CliqueConfigOptions cliqueConfig = config.getCliqueConfigOptions();
@@ -103,6 +106,7 @@ public class CliqueProtocolSchedule {
privacyParameters,
isRevertReasonEnabled,
evmConfiguration,
miningParameters,
badBlockManager)
.createProtocolSchedule();
}
@@ -115,6 +119,7 @@ public class CliqueProtocolSchedule {
* @param nodeKey the node key
* @param isRevertReasonEnabled the is revert reason enabled
* @param evmConfiguration the evm configuration
* @param miningParameters the mining parameters
* @param badBlockManager the cache to use to keep invalid blocks
* @return the protocol schedule
*/
@@ -125,6 +130,7 @@ public class CliqueProtocolSchedule {
final NodeKey nodeKey,
final boolean isRevertReasonEnabled,
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters,
final BadBlockManager badBlockManager) {
return create(
config,
@@ -133,6 +139,7 @@ public class CliqueProtocolSchedule {
PrivacyParameters.DEFAULT,
isRevertReasonEnabled,
evmConfiguration,
miningParameters,
badBlockManager);
}

View File

@@ -32,6 +32,7 @@ import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
@@ -66,6 +67,7 @@ public class CliqueProtocolScheduleTest {
NODE_KEY,
false,
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager());
final ProtocolSpec homesteadSpec = protocolSchedule.getByBlockHeader(blockHeader(1));
@@ -89,6 +91,7 @@ public class CliqueProtocolScheduleTest {
NODE_KEY,
false,
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager())
.getByBlockHeader(blockHeader(0));
@@ -112,6 +115,7 @@ public class CliqueProtocolScheduleTest {
NODE_KEY,
false,
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager()))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Epoch length in config must be greater than zero");
@@ -131,6 +135,7 @@ public class CliqueProtocolScheduleTest {
NODE_KEY,
false,
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager()))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Epoch length in config must be greater than zero");
@@ -154,6 +159,7 @@ public class CliqueProtocolScheduleTest {
NODE_KEY,
false,
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager());
BlockHeader emptyFrontierParent =

View File

@@ -106,6 +106,7 @@ public class CliqueBlockCreatorTest {
proposerNodeKey,
false,
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager());
final Address otherAddress = Util.publicKeyToAddress(otherKeyPair.getPublicKey());

View File

@@ -104,6 +104,7 @@ public class CliqueMinerExecutorTest {
proposerNodeKey,
false,
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager());
cliqueEthContext = mock(EthContext.class, RETURNS_DEEP_STUBS);
blockHeaderBuilder = new BlockHeaderTestFixture();

View File

@@ -19,6 +19,7 @@ import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.consensus.common.ForksSchedule;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator;
import org.hyperledger.besu.ethereum.mainnet.DefaultProtocolSchedule;
@@ -52,6 +53,7 @@ public abstract class BaseBftProtocolScheduleBuilder {
* @param isRevertReasonEnabled the is revert reason enabled
* @param bftExtraDataCodec the bft extra data codec
* @param evmConfiguration the evm configuration
* @param miningParameters the mining parameters
* @param badBlockManager the cache to use to keep invalid blocks
* @return the protocol schedule
*/
@@ -62,6 +64,7 @@ public abstract class BaseBftProtocolScheduleBuilder {
final boolean isRevertReasonEnabled,
final BftExtraDataCodec bftExtraDataCodec,
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters,
final BadBlockManager badBlockManager) {
final Map<Long, Function<ProtocolSpecBuilder, ProtocolSpecBuilder>> specMap = new HashMap<>();
@@ -83,6 +86,7 @@ public abstract class BaseBftProtocolScheduleBuilder {
privacyParameters,
isRevertReasonEnabled,
evmConfiguration,
miningParameters,
badBlockManager)
.createProtocolSchedule();
return new BftProtocolSchedule((DefaultProtocolSchedule) protocolSchedule);

View File

@@ -21,6 +21,7 @@ import org.hyperledger.besu.config.StubGenesisConfigOptions;
import org.hyperledger.besu.consensus.common.bft.BftProtocolSchedule;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.MilestoneStreamingProtocolSchedule;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.mainnet.DefaultProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
@@ -175,6 +176,7 @@ public class CombinedProtocolScheduleFactoryTest {
new PrivacyParameters(),
false,
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager());
return new BftProtocolSchedule(

View File

@@ -31,6 +31,7 @@ import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
import org.hyperledger.besu.ethereum.core.MilestoneStreamingProtocolSchedule;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator;
import org.hyperledger.besu.ethereum.mainnet.DefaultProtocolSchedule;
@@ -243,6 +244,7 @@ public class BaseBftProtocolScheduleBuilderTest {
false,
bftExtraDataCodec,
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager());
}

View File

@@ -332,6 +332,7 @@ public class TestContextBuilder {
forksSchedule,
IBFT_EXTRA_DATA_ENCODER,
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager());
/////////////////////////////////////////////////////////////////////////////////////

View File

@@ -21,6 +21,7 @@ import org.hyperledger.besu.consensus.common.bft.BaseBftProtocolScheduleBuilder;
import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec;
import org.hyperledger.besu.consensus.common.bft.BftProtocolSchedule;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator;
import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket;
@@ -41,6 +42,7 @@ public class IbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
* @param isRevertReasonEnabled the is revert reason enabled
* @param bftExtraDataCodec the bft extra data codec
* @param evmConfiguration the evm configuration
* @param miningParameters the mining parameters
* @param badBlockManager the cache to use to keep invalid blocks
* @return the protocol schedule
*/
@@ -51,6 +53,7 @@ public class IbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
final boolean isRevertReasonEnabled,
final BftExtraDataCodec bftExtraDataCodec,
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters,
final BadBlockManager badBlockManager) {
return new IbftProtocolScheduleBuilder()
.createProtocolSchedule(
@@ -60,6 +63,7 @@ public class IbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
isRevertReasonEnabled,
bftExtraDataCodec,
evmConfiguration,
miningParameters,
badBlockManager);
}
@@ -70,6 +74,7 @@ public class IbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
* @param forksSchedule the forks schedule
* @param bftExtraDataCodec the bft extra data codec
* @param evmConfiguration the evm configuration
* @param miningParameters the mining parameters
* @param badBlockManager the cache to use to keep invalid blocks
* @return the protocol schedule
*/
@@ -78,6 +83,7 @@ public class IbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
final ForksSchedule<BftConfigOptions> forksSchedule,
final BftExtraDataCodec bftExtraDataCodec,
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters,
final BadBlockManager badBlockManager) {
return create(
config,
@@ -86,6 +92,7 @@ public class IbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
false,
bftExtraDataCodec,
evmConfiguration,
miningParameters,
badBlockManager);
}

View File

@@ -40,6 +40,7 @@ import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.MilestoneStreamingProtocolSchedule;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.core.Util;
import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode;
@@ -101,6 +102,7 @@ public class IbftProtocolScheduleTest {
false,
bftExtraDataCodec,
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager());
}

View File

@@ -120,6 +120,7 @@ public class BftBlockCreatorTest {
false,
bftExtraDataEncoder,
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager());
final ProtocolContext protContext =
new ProtocolContext(

View File

@@ -69,6 +69,7 @@ import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockBody;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.core.Util;
import org.hyperledger.besu.ethereum.mainnet.DefaultProtocolSchedule;
@@ -179,6 +180,7 @@ public class IbftBlockHeightManagerTest {
new PrivacyParameters(),
false,
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager());
ProtocolSchedule protocolSchedule =

View File

@@ -17,6 +17,7 @@ package org.hyperledger.besu.consensus.merge;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
@@ -43,14 +44,21 @@ public class MergeProtocolSchedule {
*
* @param config the config
* @param isRevertReasonEnabled the is revert reason enabled
* @param miningParameters the mining parameters
* @param badBlockManager the cache to use to keep invalid blocks
* @return the protocol schedule
*/
public static ProtocolSchedule create(
final GenesisConfigOptions config,
final boolean isRevertReasonEnabled,
final MiningParameters miningParameters,
final BadBlockManager badBlockManager) {
return create(config, PrivacyParameters.DEFAULT, isRevertReasonEnabled, badBlockManager);
return create(
config,
PrivacyParameters.DEFAULT,
isRevertReasonEnabled,
miningParameters,
badBlockManager);
}
/**
@@ -59,6 +67,7 @@ public class MergeProtocolSchedule {
* @param config the config
* @param privacyParameters the privacy parameters
* @param isRevertReasonEnabled the is revert reason enabled
* @param miningParameters the mining parameters
* @param badBlockManager the cache to use to keep invalid blocks
* @return the protocol schedule
*/
@@ -66,6 +75,7 @@ public class MergeProtocolSchedule {
final GenesisConfigOptions config,
final PrivacyParameters privacyParameters,
final boolean isRevertReasonEnabled,
final MiningParameters miningParameters,
final BadBlockManager badBlockManager) {
Map<Long, Function<ProtocolSpecBuilder, ProtocolSpecBuilder>> postMergeModifications =
@@ -84,6 +94,7 @@ public class MergeProtocolSchedule {
privacyParameters,
isRevertReasonEnabled,
EvmConfiguration.DEFAULT,
miningParameters,
badBlockManager)
.createProtocolSchedule();
}

View File

@@ -19,6 +19,7 @@ import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.Difficulty;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PermissionTransactionFilter;
import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader;
import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule;
@@ -62,15 +63,19 @@ public class TransitionProtocolSchedule implements ProtocolSchedule {
*
* @param genesisConfigOptions {@link GenesisConfigOptions} containing the config options for the
* milestone starting points
* @param miningParameters the mining parameters
* @param badBlockManager the cache to use to keep invalid blocks
* @return an initialised TransitionProtocolSchedule using post-merge defaults
*/
public static TransitionProtocolSchedule fromConfig(
final GenesisConfigOptions genesisConfigOptions, final BadBlockManager badBlockManager) {
final GenesisConfigOptions genesisConfigOptions,
final MiningParameters miningParameters,
final BadBlockManager badBlockManager) {
ProtocolSchedule preMergeProtocolSchedule =
MainnetProtocolSchedule.fromConfig(genesisConfigOptions, badBlockManager);
MainnetProtocolSchedule.fromConfig(genesisConfigOptions, miningParameters, badBlockManager);
ProtocolSchedule postMergeProtocolSchedule =
MergeProtocolSchedule.create(genesisConfigOptions, false, badBlockManager);
MergeProtocolSchedule.create(
genesisConfigOptions, false, miningParameters, badBlockManager);
return new TransitionProtocolSchedule(
preMergeProtocolSchedule, postMergeProtocolSchedule, PostMergeContext.get());
}

View File

@@ -22,6 +22,7 @@ import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.mainnet.MainnetBlockProcessor;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
@@ -46,7 +47,8 @@ public class MergeProtocolScheduleTest {
final GenesisConfigOptions config = GenesisConfigFile.fromConfig(jsonInput).getConfigOptions();
final ProtocolSchedule protocolSchedule =
MergeProtocolSchedule.create(config, false, new BadBlockManager());
MergeProtocolSchedule.create(
config, false, MiningParameters.MINING_DISABLED, new BadBlockManager());
final ProtocolSpec homesteadSpec = protocolSchedule.getByBlockHeader(blockHeader(1));
final ProtocolSpec londonSpec = protocolSchedule.getByBlockHeader(blockHeader(1559));
@@ -61,7 +63,8 @@ public class MergeProtocolScheduleTest {
final GenesisConfigOptions config = GenesisConfigFile.mainnet().getConfigOptions();
final ProtocolSchedule protocolSchedule =
MergeProtocolSchedule.create(config, false, new BadBlockManager());
MergeProtocolSchedule.create(
config, false, MiningParameters.MINING_DISABLED, new BadBlockManager());
final long lastParisBlockNumber = 17034869L;
final ProtocolSpec parisSpec =
@@ -96,7 +99,8 @@ public class MergeProtocolScheduleTest {
final GenesisConfigOptions config = GenesisConfigFile.fromConfig(jsonInput).getConfigOptions();
final ProtocolSchedule protocolSchedule =
MergeProtocolSchedule.create(config, false, new BadBlockManager());
MergeProtocolSchedule.create(
config, false, MiningParameters.MINING_DISABLED, new BadBlockManager());
final ProtocolSpec parisSpec =
protocolSchedule.getByBlockHeader(
@@ -123,7 +127,8 @@ public class MergeProtocolScheduleTest {
public void mergeSpecificModificationsAreUnappliedForAllMainnetForksAfterParis() {
final GenesisConfigOptions config = GenesisConfigFile.mainnet().getConfigOptions();
final ProtocolSchedule protocolSchedule =
MergeProtocolSchedule.create(config, false, new BadBlockManager());
MergeProtocolSchedule.create(
config, false, MiningParameters.MINING_DISABLED, new BadBlockManager());
final long lastParisBlockNumber = 17034869L;
final ProtocolSpec parisSpec =
@@ -152,7 +157,10 @@ public class MergeProtocolScheduleTest {
public void parametersAlignWithMainnetWithAdjustments() {
final ProtocolSpec london =
MergeProtocolSchedule.create(
GenesisConfigFile.DEFAULT.getConfigOptions(), false, new BadBlockManager())
GenesisConfigFile.DEFAULT.getConfigOptions(),
false,
MiningParameters.MINING_DISABLED,
new BadBlockManager())
.getByBlockHeader(blockHeader(0));
assertThat(london.getName()).isEqualTo("Paris");

View File

@@ -21,6 +21,7 @@ import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.consensus.merge.MergeProtocolSchedule;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import java.io.IOException;
@@ -59,6 +60,9 @@ public interface MergeGenesisConfigHelper {
default ProtocolSchedule getMergeProtocolSchedule() {
return MergeProtocolSchedule.create(
getPosGenesisConfigFile().getConfigOptions(), false, new BadBlockManager());
getPosGenesisConfigFile().getConfigOptions(),
false,
MiningParameters.MINING_DISABLED,
new BadBlockManager());
}
}

View File

@@ -150,6 +150,7 @@ public class TestContextBuilder {
private boolean useLondonMilestone = false;
private boolean useShanghaiMilestone = false;
private boolean useZeroBaseFee = false;
private boolean useFixedBaseFee = false;
public static final int EPOCH_LENGTH = 10_000;
public static final int BLOCK_TIMER_SEC = 3;
public static final int ROUND_TIMER_SEC = 12;
@@ -227,6 +228,11 @@ public class TestContextBuilder {
return this;
}
public TestContextBuilder useFixedBaseFee(final boolean useFixedBaseFee) {
this.useFixedBaseFee = useFixedBaseFee;
return this;
}
public TestContextBuilder qbftForks(final List<QbftFork> qbftForks) {
this.qbftForks = qbftForks;
return this;
@@ -294,6 +300,7 @@ public class TestContextBuilder {
useLondonMilestone,
useShanghaiMilestone,
useZeroBaseFee,
useFixedBaseFee,
qbftForks);
// Add each networkNode to the Multicaster (such that each can receive msgs from local node).
@@ -375,6 +382,7 @@ public class TestContextBuilder {
final boolean useLondonMilestone,
final boolean useShanghaiMilestone,
final boolean useZeroBaseFee,
final boolean useFixedBaseFee,
final List<QbftFork> qbftForks) {
final MiningParameters miningParams =
@@ -407,6 +415,9 @@ public class TestContextBuilder {
if (useZeroBaseFee) {
genesisConfigOptions.zeroBaseFee(true);
}
if (useFixedBaseFee) {
genesisConfigOptions.fixedBaseFee(true);
}
genesisConfigOptions.qbftConfigOptions(
new JsonQbftConfigOptions(JsonUtil.objectNodeFromMap(qbftConfigValues)));
genesisConfigOptions.transitions(TestTransitions.createQbftTestTransitions(qbftForks));
@@ -425,6 +436,7 @@ public class TestContextBuilder {
forksSchedule,
BFT_EXTRA_DATA_ENCODER,
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager());
final BftValidatorOverrides validatorOverrides = convertBftForks(qbftForks);

View File

@@ -167,6 +167,57 @@ public class ValidatorContractTest {
assertThat(validatorProvider.getValidatorsForBlock(block1)).containsExactly(NODE_ADDRESS);
}
@Test
public void retrievesValidatorsFromValidatorContract_LondonFork_FixedBaseFee() {
// Using London on a free gas network
final TestContext context =
new TestContextBuilder()
.indexOfFirstLocallyProposedBlock(0)
.nodeParams(
List.of(new NodeParams(NODE_ADDRESS, NodeKeyUtils.createFrom(NODE_PRIVATE_KEY))))
.clock(TestClock.fixed())
.genesisFile(Resources.getResource("genesis_validator_contract_london.json").getFile())
.useValidatorContract(true)
.useLondonMilestone(true)
.useFixedBaseFee(true)
.buildAndStart();
createNewBlockAsProposer(context, 1);
final ValidatorProvider validatorProvider = context.getValidatorProvider();
final BlockHeader genesisBlock = context.getBlockchain().getBlockHeader(0).get();
final BlockHeader block1 = context.getBlockchain().getBlockHeader(1).get();
assertThat(validatorProvider.getValidatorsForBlock(genesisBlock)).containsExactly(NODE_ADDRESS);
assertThat(validatorProvider.getValidatorsForBlock(block1)).containsExactly(NODE_ADDRESS);
}
@Test
public void retrievesValidatorsFromValidatorContract_ShanghaiFork_FixedBaseFee() {
// Using Shanghai on a free gas network
final TestContext context =
new TestContextBuilder()
.indexOfFirstLocallyProposedBlock(0)
.nodeParams(
List.of(new NodeParams(NODE_ADDRESS, NodeKeyUtils.createFrom(NODE_PRIVATE_KEY))))
.clock(TestClock.fixed())
.genesisFile(
Resources.getResource("genesis_validator_contract_shanghai.json").getFile())
.useValidatorContract(true)
.useShanghaiMilestone(true)
.useFixedBaseFee(true)
.buildAndStart();
createNewBlockAsProposerFixedTime(
context, 1,
266L); // 10s ahead of genesis timestamp in genesis_validator_contract_shanghai.json
final ValidatorProvider validatorProvider = context.getValidatorProvider();
final BlockHeader genesisBlock = context.getBlockchain().getBlockHeader(0).get();
final BlockHeader block1 = context.getBlockchain().getBlockHeader(1).get();
assertThat(validatorProvider.getValidatorsForBlock(genesisBlock)).containsExactly(NODE_ADDRESS);
assertThat(validatorProvider.getValidatorsForBlock(block1)).containsExactly(NODE_ADDRESS);
}
@Test
public void transitionsFromBlockHeaderModeToValidatorContractMode() {
final List<QbftFork> qbftForks =

View File

@@ -24,6 +24,7 @@ import org.hyperledger.besu.consensus.common.bft.BaseBftProtocolScheduleBuilder;
import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec;
import org.hyperledger.besu.consensus.common.bft.BftProtocolSchedule;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
@@ -45,6 +46,7 @@ public class QbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
* @param isRevertReasonEnabled the is revert reason enabled
* @param bftExtraDataCodec the bft extra data codec
* @param evmConfiguration the evm configuration
* @param miningParameters The mining parameters
* @param badBlockManager the cache to use to keep invalid blocks
* @return the protocol schedule
*/
@@ -55,6 +57,7 @@ public class QbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
final boolean isRevertReasonEnabled,
final BftExtraDataCodec bftExtraDataCodec,
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters,
final BadBlockManager badBlockManager) {
return new QbftProtocolScheduleBuilder()
.createProtocolSchedule(
@@ -64,6 +67,7 @@ public class QbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
isRevertReasonEnabled,
bftExtraDataCodec,
evmConfiguration,
miningParameters,
badBlockManager);
}
@@ -74,6 +78,7 @@ public class QbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
* @param qbftForksSchedule the qbft forks schedule
* @param bftExtraDataCodec the bft extra data codec
* @param evmConfiguration the evm configuration
* @param miningParameters The mining parameters
* @param badBlockManager the cache to use to keep invalid blocks
* @return the protocol schedule
*/
@@ -82,6 +87,7 @@ public class QbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
final ForksSchedule<QbftConfigOptions> qbftForksSchedule,
final BftExtraDataCodec bftExtraDataCodec,
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters,
final BadBlockManager badBlockManager) {
return create(
config,
@@ -90,6 +96,7 @@ public class QbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
false,
bftExtraDataCodec,
evmConfiguration,
miningParameters,
badBlockManager);
}
@@ -100,6 +107,7 @@ public class QbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
* @param qbftForksSchedule the qbft forks schedule
* @param isRevertReasonEnabled the is revert reason enabled
* @param bftExtraDataCodec the bft extra data codec
* @param miningParameters The mining parameters
* @param badBlockManager the cache to use to keep invalid blocks
* @return the protocol schedule
*/
@@ -108,6 +116,7 @@ public class QbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
final ForksSchedule<QbftConfigOptions> qbftForksSchedule,
final boolean isRevertReasonEnabled,
final BftExtraDataCodec bftExtraDataCodec,
final MiningParameters miningParameters,
final BadBlockManager badBlockManager) {
return create(
config,
@@ -116,6 +125,7 @@ public class QbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
isRevertReasonEnabled,
bftExtraDataCodec,
EvmConfiguration.DEFAULT,
miningParameters,
badBlockManager);
}

View File

@@ -35,6 +35,7 @@ import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.MilestoneStreamingProtocolSchedule;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.core.Util;
import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode;
@@ -136,6 +137,7 @@ public class QbftProtocolScheduleTest {
false,
bftExtraDataCodec,
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager());
}

View File

@@ -68,6 +68,7 @@ import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockBody;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.core.Util;
import org.hyperledger.besu.ethereum.mainnet.DefaultProtocolSchedule;
@@ -179,6 +180,7 @@ public class QbftBlockHeightManagerTest {
new PrivacyParameters(),
false,
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager());
ProtocolSchedule protocolSchedule =

View File

@@ -188,7 +188,7 @@ public class Address extends DelegatingBytes {
final Bytes value = Bytes.fromHexString(str);
checkArgument(
value.size() == SIZE,
"An account address must be be %s bytes long, got %s",
"An account address must be %s bytes long, got %s",
SIZE,
value.size());
return new Address(value);

View File

@@ -19,6 +19,7 @@ import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.chain.GenesisState;
import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockHeaderFunctions;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ScheduleBasedBlockHeaderFunctions;
@@ -43,7 +44,9 @@ public class BlockchainImporter {
public BlockchainImporter(final URL blocksUrl, final String genesisJson) throws Exception {
protocolSchedule =
MainnetProtocolSchedule.fromConfig(
GenesisConfigFile.fromConfig(genesisJson).getConfigOptions(), new BadBlockManager());
GenesisConfigFile.fromConfig(genesisJson).getConfigOptions(),
MiningParameters.newDefault(),
new BadBlockManager());
final BlockHeaderFunctions blockHeaderFunctions =
ScheduleBasedBlockHeaderFunctions.create(protocolSchedule);
blocks = new ArrayList<>();

View File

@@ -28,7 +28,8 @@ 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.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.mainnet.ValidationResult;
import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
import org.hyperledger.besu.testutil.BlockTestUtil;
import java.util.Map;
@@ -171,11 +172,11 @@ public class EthEstimateGasIntegrationTest {
null,
null);
final JsonRpcRequestContext request = requestWithParams(callParameter);
final RpcErrorType rpcErrorType = RpcErrorType.TRANSACTION_UPFRONT_COST_EXCEEDS_BALANCE;
final JsonRpcError rpcError = new JsonRpcError(rpcErrorType);
rpcError.setReason(
"transaction up-front cost 0x1cc31b3333167018 exceeds transaction sender account balance 0x140");
final ValidationResult<TransactionInvalidReason> validationResult =
ValidationResult.invalid(
TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE,
"transaction up-front cost 0x1cc31b3333167018 exceeds transaction sender account balance 0x140");
final JsonRpcError rpcError = JsonRpcError.from(validationResult);
final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, rpcError);
final JsonRpcResponse response = method.response(request);

View File

@@ -83,6 +83,8 @@ public class JsonRpcErrorConverter {
return RpcErrorType.BLOB_GAS_PRICE_BELOW_CURRENT_BLOB_BASE_FEE;
case EXECUTION_HALTED:
return RpcErrorType.EXECUTION_HALTED;
case BLOCK_NOT_FOUND:
return RpcErrorType.BLOCK_NOT_FOUND;
default:
return RpcErrorType.INTERNAL_ERROR;
}

View File

@@ -111,12 +111,7 @@ public abstract class AbstractEstimateGas implements JsonRpcMethod {
result.getValidationResult();
if (validationResult != null && !validationResult.isValid()) {
if (validationResult.getErrorMessage().length() > 0) {
final RpcErrorType rpcErrorType =
JsonRpcErrorConverter.convertTransactionInvalidReason(
validationResult.getInvalidReason());
final JsonRpcError rpcError = new JsonRpcError(rpcErrorType);
rpcError.setReason(validationResult.getErrorMessage());
return errorResponse(request, rpcError);
return errorResponse(request, JsonRpcError.from(validationResult));
}
return errorResponse(
request,

View File

@@ -164,6 +164,11 @@ public class EthCall extends AbstractBlockParameterOrBlockHashMethod {
callParams.getGasPrice() == null || Wei.ZERO.equals(callParams.getGasPrice());
if (header.getBaseFee().isPresent()) {
if (callParams.getBlobVersionedHashes().isPresent()
&& (callParams.getMaxFeePerBlobGas().isEmpty()
|| callParams.getMaxFeePerBlobGas().get().equals(Wei.ZERO))) {
return true;
}
boolean isZeroMaxFeePerGas = callParams.getMaxFeePerGas().orElse(Wei.ZERO).equals(Wei.ZERO);
boolean isZeroMaxPriorityFeePerGas =
callParams.getMaxPriorityFeePerGas().orElse(Wei.ZERO).equals(Wei.ZERO);

View File

@@ -14,9 +14,6 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods;
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType.INTERNAL_ERROR;
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType.PLUGIN_INTERNAL_ERROR;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
@@ -53,13 +50,9 @@ public class PluginJsonRpcMethod implements JsonRpcMethod {
final Object result = function.apply(() -> request.getRequest().getParams());
return new JsonRpcSuccessResponse(request.getRequest().getId(), result);
} catch (final PluginRpcEndpointException ex) {
final JsonRpcError error = new JsonRpcError(PLUGIN_INTERNAL_ERROR, ex.getMessage());
final JsonRpcError error = new JsonRpcError(ex.getRpcMethodError(), ex.getMessage());
LOG.error("Error calling plugin JSON-RPC endpoint", ex);
return new JsonRpcErrorResponse(request.getRequest().getId(), error);
} catch (final Exception ex) {
LOG.error("Error calling plugin JSON-RPC endpoint", ex);
return new JsonRpcErrorResponse(
request.getRequest().getId(), new JsonRpcError(INTERNAL_ERROR));
}
}
}

View File

@@ -23,6 +23,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.TransactionPen
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.transaction.pool.PendingTransactionFilter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.transaction.pool.PendingTransactionFilter.Filter;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import java.util.Collection;
@@ -49,7 +50,10 @@ public class TxPoolBesuPendingTransactions implements JsonRpcMethod {
@Override
public JsonRpcResponse response(final JsonRpcRequestContext requestContext) {
final Integer limit = requestContext.getRequiredParameter(0, Integer.class);
final Collection<PendingTransaction> pendingTransactions =
transactionPool.getPendingTransactions();
final Integer limit =
requestContext.getOptionalParameter(0, Integer.class).orElse(pendingTransactions.size());
final List<Filter> filters =
requestContext
.getOptionalParameter(1, PendingTransactionsParams.class)
@@ -57,7 +61,7 @@ public class TxPoolBesuPendingTransactions implements JsonRpcMethod {
.orElse(Collections.emptyList());
final Collection<Transaction> pendingTransactionsFiltered =
pendingTransactionFilter.reduce(transactionPool.getPendingTransactions(), filters, limit);
pendingTransactionFilter.reduce(pendingTransactions, filters, limit);
return new JsonRpcSuccessResponse(
requestContext.getRequest().getId(),

View File

@@ -320,7 +320,13 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet
if (executionResult.isSuccessful()) {
logImportedBlockInfo(
block, blobTransactions.size(), (System.currentTimeMillis() - startTimeMs) / 1000.0);
block,
blobTransactions.stream()
.map(Transaction::getVersionedHashes)
.flatMap(Optional::stream)
.mapToInt(List::size)
.sum(),
(System.currentTimeMillis() - startTimeMs) / 1000.0);
return respondWith(reqId, blockParam, newBlockHeader.getHash(), VALID);
} else {
if (executionResult.causedBy().isPresent()) {

View File

@@ -14,6 +14,11 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.response;
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcErrorConverter;
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
import org.hyperledger.besu.plugin.services.rpc.RpcMethodError;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonCreator;
@@ -21,7 +26,6 @@ import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.apache.tuweni.bytes.Bytes;
@JsonInclude(value = JsonInclude.Include.NON_NULL)
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
@@ -41,16 +45,11 @@ public class JsonRpcError {
this.data = data;
}
public JsonRpcError(final RpcErrorType errorType, final String data) {
public JsonRpcError(final RpcMethodError errorType, final String data) {
this(errorType.getCode(), errorType.getMessage(), data);
// For execution reverted errors decode the data (if present)
if (errorType == RpcErrorType.REVERT_ERROR && data != null) {
JsonRpcErrorResponse.decodeRevertReason(Bytes.fromHexString(data))
.ifPresent(
(decodedReason) -> {
this.reason = decodedReason;
});
if (data != null) {
errorType.decodeData(data).ifPresent(decodedData -> this.reason = decodedData);
}
}
@@ -58,6 +57,16 @@ public class JsonRpcError {
this(errorType, null);
}
public static JsonRpcError from(
final ValidationResult<TransactionInvalidReason> validationResult) {
final var jsonRpcError =
new JsonRpcError(
JsonRpcErrorConverter.convertTransactionInvalidReason(
validationResult.getInvalidReason()));
jsonRpcError.reason = validationResult.getErrorMessage();
return jsonRpcError;
}
@JsonGetter("code")
public int getCode() {
return code;
@@ -73,10 +82,6 @@ public class JsonRpcError {
return data;
}
public void setReason(final String reason) {
this.reason = reason;
}
@Override
public boolean equals(final Object o) {
if (this == o) {

View File

@@ -14,7 +14,14 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.response;
public enum RpcErrorType {
import org.hyperledger.besu.plugin.services.rpc.RpcMethodError;
import java.util.Optional;
import java.util.function.Function;
import org.apache.tuweni.bytes.Bytes;
public enum RpcErrorType implements RpcMethodError {
// Standard errors
PARSE_ERROR(-32700, "Parse error"),
INVALID_REQUEST(-32600, "Invalid Request"),
@@ -67,7 +74,10 @@ public enum RpcErrorType {
REPLAY_PROTECTED_SIGNATURES_NOT_SUPPORTED(-32000, "ChainId not supported"),
REPLAY_PROTECTED_SIGNATURE_REQUIRED(-32000, "ChainId is required"),
TX_FEECAP_EXCEEDED(-32000, "Transaction fee cap exceeded"),
REVERT_ERROR(-32000, "Execution reverted"),
REVERT_ERROR(
-32000,
"Execution reverted",
data -> JsonRpcErrorResponse.decodeRevertReason(Bytes.fromHexString(data))),
TRANSACTION_NOT_FOUND(-32000, "Transaction not found"),
MAX_PRIORITY_FEE_PER_GAS_EXCEEDS_MAX_FEE_PER_GAS(
-32000, "Max priority fee per gas exceeds max fee per gas"),
@@ -222,17 +232,31 @@ public enum RpcErrorType {
private final int code;
private final String message;
private final Function<String, Optional<String>> dataDecoder;
RpcErrorType(final int code, final String message) {
this.code = code;
this.message = message;
this(code, message, null);
}
RpcErrorType(
final int code, final String message, Function<String, Optional<String>> dataDecoder) {
this.code = code;
this.message = message;
this.dataDecoder = dataDecoder;
}
@Override
public int getCode() {
return code;
}
@Override
public String getMessage() {
return message;
}
@Override
public Optional<String> decodeData(final String data) {
return dataDecoder == null ? Optional.empty() : dataDecoder.apply(data);
}
}

View File

@@ -108,6 +108,7 @@ public class JsonRpcHttpServiceHostAllowlistTest {
synchronizer,
MainnetProtocolSchedule.fromConfig(
new StubGenesisConfigOptions().constantinopleBlock(0).chainId(CHAIN_ID),
MiningParameters.MINING_DISABLED,
new BadBlockManager()),
mock(ProtocolContext.class),
mock(FilterManager.class),

View File

@@ -137,7 +137,8 @@ public class JsonRpcHttpServiceLoginTest {
peerDiscoveryMock,
blockchainQueries,
synchronizer,
MainnetProtocolSchedule.fromConfig(genesisConfigOptions, new BadBlockManager()),
MainnetProtocolSchedule.fromConfig(
genesisConfigOptions, MiningParameters.MINING_DISABLED, new BadBlockManager()),
mock(ProtocolContext.class),
mock(FilterManager.class),
mock(TransactionPool.class),

View File

@@ -118,6 +118,7 @@ public class JsonRpcHttpServiceTestBase {
MainnetProtocolSchedule.fromConfig(
new StubGenesisConfigOptions().constantinopleBlock(0).chainId(CHAIN_ID),
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager()),
mock(ProtocolContext.class),
mock(FilterManager.class),
@@ -151,8 +152,7 @@ public class JsonRpcHttpServiceTestBase {
baseUrl = service.url();
}
protected static JsonRpcHttpService createJsonRpcHttpService(final JsonRpcConfiguration config)
throws Exception {
protected static JsonRpcHttpService createJsonRpcHttpService(final JsonRpcConfiguration config) {
return new JsonRpcHttpService(
vertx,
folder,
@@ -164,7 +164,7 @@ public class JsonRpcHttpServiceTestBase {
HealthService.ALWAYS_HEALTHY);
}
protected static JsonRpcHttpService createJsonRpcHttpService() throws Exception {
protected static JsonRpcHttpService createJsonRpcHttpService() {
return new JsonRpcHttpService(
vertx,
folder,

View File

@@ -122,6 +122,7 @@ public class JsonRpcHttpServiceTlsClientAuthTest {
synchronizer,
MainnetProtocolSchedule.fromConfig(
new StubGenesisConfigOptions().constantinopleBlock(0).chainId(CHAIN_ID),
MiningParameters.MINING_DISABLED,
new BadBlockManager()),
mock(ProtocolContext.class),
mock(FilterManager.class),

View File

@@ -110,6 +110,7 @@ class JsonRpcHttpServiceTlsMisconfigurationTest {
synchronizer,
MainnetProtocolSchedule.fromConfig(
new StubGenesisConfigOptions().constantinopleBlock(0).chainId(CHAIN_ID),
MiningParameters.MINING_DISABLED,
new BadBlockManager()),
mock(ProtocolContext.class),
mock(FilterManager.class),

View File

@@ -111,6 +111,7 @@ public class JsonRpcHttpServiceTlsTest {
synchronizer,
MainnetProtocolSchedule.fromConfig(
new StubGenesisConfigOptions().constantinopleBlock(0).chainId(CHAIN_ID),
MiningParameters.MINING_DISABLED,
new BadBlockManager()),
mock(ProtocolContext.class),
mock(FilterManager.class),

View File

@@ -0,0 +1,173 @@
/*
* Copyright Hyperledger Besu contributors
*
* 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
*/
package org.hyperledger.besu.ethereum.api.jsonrpc;
import static org.assertj.core.api.Assertions.assertThat;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.PluginJsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
import org.hyperledger.besu.plugin.services.exception.PluginRpcEndpointException;
import org.hyperledger.besu.plugin.services.rpc.PluginRpcRequest;
import org.hyperledger.besu.plugin.services.rpc.RpcMethodError;
import io.vertx.core.json.JsonObject;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
public class PluginJsonRpcMethodTest extends JsonRpcHttpServiceTestBase {
@BeforeAll
public static void setup() throws Exception {
initServerAndClient();
}
/** Tears down the HTTP server. */
@AfterAll
public static void shutdownServer() {
service.stop().join();
}
@Test
public void happyPath() throws Exception {
final var request =
"""
{"jsonrpc":"2.0","id":1,"method":"plugin_echo","params":["hello"]}""";
try (var unused =
addRpcMethod(
"plugin_echo",
new PluginJsonRpcMethod("plugin_echo", PluginJsonRpcMethodTest::echoPluginRpcMethod))) {
final RequestBody body = RequestBody.create(request, JSON);
try (final Response resp = client.newCall(buildPostRequest(body)).execute()) {
assertThat(resp.code()).isEqualTo(200);
final JsonObject json = new JsonObject(resp.body().string());
testHelper.assertValidJsonRpcResult(json, 1);
assertThat(json.getString("result")).isEqualTo("hello");
}
}
}
@Test
public void invalidJsonShouldReturnParseError() throws Exception {
final var malformedRequest =
"""
{"jsonrpc":"2.0","id":1,"method":"plugin_echo","params":}""";
try (var unused =
addRpcMethod(
"plugin_echo",
new PluginJsonRpcMethod("plugin_echo", PluginJsonRpcMethodTest::echoPluginRpcMethod))) {
final RequestBody body = RequestBody.create(malformedRequest, JSON);
try (final Response resp = client.newCall(buildPostRequest(body)).execute()) {
assertThat(resp.code()).isEqualTo(400);
final JsonObject json = new JsonObject(resp.body().string());
final JsonRpcError expectedError = new JsonRpcError(RpcErrorType.PARSE_ERROR);
testHelper.assertValidJsonRpcError(
json, null, expectedError.getCode(), expectedError.getMessage());
}
}
}
@Test
public void invalidParamsShouldReturnInvalidParams() throws Exception {
final var missingRequiredParam =
"""
{"jsonrpc":"2.0","id":1,"method":"plugin_echo","params":[]}""";
try (var unused =
addRpcMethod(
"plugin_echo",
new PluginJsonRpcMethod("plugin_echo", PluginJsonRpcMethodTest::echoPluginRpcMethod))) {
final RequestBody body = RequestBody.create(missingRequiredParam, JSON);
try (final Response resp = client.newCall(buildPostRequest(body)).execute()) {
assertThat(resp.code()).isEqualTo(200);
final JsonObject json = new JsonObject(resp.body().string());
final JsonRpcError expectedError = new JsonRpcError(RpcErrorType.INVALID_PARAMS);
testHelper.assertValidJsonRpcError(
json, 1, expectedError.getCode(), expectedError.getMessage());
}
}
}
@Test
public void methodErrorShouldReturnErrorResponse() throws Exception {
final var wrongParamContent =
"""
{"jsonrpc":"2.0","id":1,"method":"plugin_echo","params":[" "]}""";
try (var unused =
addRpcMethod(
"plugin_echo",
new PluginJsonRpcMethod("plugin_echo", PluginJsonRpcMethodTest::echoPluginRpcMethod))) {
final RequestBody body = RequestBody.create(wrongParamContent, JSON);
try (final Response resp = client.newCall(buildPostRequest(body)).execute()) {
assertThat(resp.code()).isEqualTo(200);
final JsonObject json = new JsonObject(resp.body().string());
testHelper.assertValidJsonRpcError(json, 1, -1, "Blank input not allowed");
}
}
}
@Test
public void unhandledExceptionShouldReturnInternalErrorResponse() throws Exception {
final var nullParam =
"""
{"jsonrpc":"2.0","id":1,"method":"plugin_echo","params":[null]}""";
try (var unused =
addRpcMethod(
"plugin_echo",
new PluginJsonRpcMethod("plugin_echo", PluginJsonRpcMethodTest::echoPluginRpcMethod))) {
final RequestBody body = RequestBody.create(nullParam, JSON);
try (final Response resp = client.newCall(buildPostRequest(body)).execute()) {
assertThat(resp.code()).isEqualTo(200);
final JsonObject json = new JsonObject(resp.body().string());
final JsonRpcError expectedError = new JsonRpcError(RpcErrorType.INTERNAL_ERROR);
testHelper.assertValidJsonRpcError(
json, 1, expectedError.getCode(), expectedError.getMessage());
}
}
}
private static Object echoPluginRpcMethod(final PluginRpcRequest request) {
final var params = request.getParams();
if (params.length == 0) {
throw new InvalidJsonRpcParameters("parameter is mandatory");
}
final var input = params[0];
if (input.toString().isBlank()) {
throw new PluginRpcEndpointException(
new RpcMethodError() {
@Override
public int getCode() {
return -1;
}
@Override
public String getMessage() {
return "Blank input not allowed";
}
});
}
return input;
}
}

View File

@@ -219,9 +219,11 @@ public class EthEstimateGasTest {
TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE,
"transaction up-front cost 10 exceeds transaction sender account balance 5");
final RpcErrorType rpcErrorType = RpcErrorType.TRANSACTION_UPFRONT_COST_EXCEEDS_BALANCE;
final JsonRpcError rpcError = new JsonRpcError(rpcErrorType);
rpcError.setReason("transaction up-front cost 10 exceeds transaction sender account balance 5");
final ValidationResult<TransactionInvalidReason> validationResult =
ValidationResult.invalid(
TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE,
"transaction up-front cost 10 exceeds transaction sender account balance 5");
final JsonRpcError rpcError = JsonRpcError.from(validationResult);
final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, rpcError);
Assertions.assertThat(method.response(request))
@@ -235,10 +237,11 @@ public class EthEstimateGasTest {
mockTransientProcessorResultTxInvalidReason(
TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE,
"transaction up-front cost 10 exceeds transaction sender account balance 5");
final RpcErrorType rpcErrorType = RpcErrorType.TRANSACTION_UPFRONT_COST_EXCEEDS_BALANCE;
final JsonRpcError rpcError = new JsonRpcError(rpcErrorType);
rpcError.setReason("transaction up-front cost 10 exceeds transaction sender account balance 5");
final ValidationResult<TransactionInvalidReason> validationResult =
ValidationResult.invalid(
TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE,
"transaction up-front cost 10 exceeds transaction sender account balance 5");
final JsonRpcError rpcError = JsonRpcError.from(validationResult);
final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, rpcError);
Assertions.assertThat(method.response(request))
@@ -384,9 +387,9 @@ public class EthEstimateGasTest {
mockTransientProcessorResultTxInvalidReason(
TransactionInvalidReason.EXECUTION_HALTED, "INVALID_OPERATION");
final RpcErrorType rpcErrorType = RpcErrorType.EXECUTION_HALTED;
final JsonRpcError rpcError = new JsonRpcError(rpcErrorType);
rpcError.setReason("INVALID_OPERATION");
final ValidationResult<TransactionInvalidReason> validationResult =
ValidationResult.invalid(TransactionInvalidReason.EXECUTION_HALTED, "INVALID_OPERATION");
final JsonRpcError rpcError = JsonRpcError.from(validationResult);
final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, rpcError);
Assertions.assertThat(method.response(request))

View File

@@ -70,7 +70,7 @@ public class TxPoolBesuPendingTransactionsTest {
final JsonRpcRequestContext request =
new JsonRpcRequestContext(
new JsonRpcRequest(
JSON_RPC_VERSION, TXPOOL_PENDING_TRANSACTIONS_METHOD, new Object[] {100}));
JSON_RPC_VERSION, TXPOOL_PENDING_TRANSACTIONS_METHOD, new Object[] {}));
final JsonRpcSuccessResponse actualResponse = (JsonRpcSuccessResponse) method.response(request);
final Set<TransactionPendingResult> result =
@@ -120,6 +120,36 @@ public class TxPoolBesuPendingTransactionsTest {
@Test
public void shouldReturnPendingTransactionsWithFilter() {
final Map<String, String> fromFilter = new HashMap<>();
fromFilter.put(
"eq", listTrx.stream().findAny().get().getTransaction().getSender().toHexString());
final JsonRpcRequestContext request =
new JsonRpcRequestContext(
new JsonRpcRequest(
JSON_RPC_VERSION,
TXPOOL_PENDING_TRANSACTIONS_METHOD,
new Object[] {
null,
new PendingTransactionsParams(
fromFilter,
new HashMap<>(),
new HashMap<>(),
new HashMap<>(),
new HashMap<>(),
new HashMap<>())
}));
final JsonRpcSuccessResponse actualResponse = (JsonRpcSuccessResponse) method.response(request);
final Set<TransactionPendingResult> result =
(Set<TransactionPendingResult>) actualResponse.getResult();
assertThat(result.size()).isEqualTo(1);
}
@Test
public void shouldReturnPendingTransactionsWithLimitAndFilter() {
final Map<String, String> fromFilter = new HashMap<>();
fromFilter.put(
"eq", listTrx.stream().findAny().get().getTransaction().getSender().toHexString());

View File

@@ -173,7 +173,10 @@ public class WebSocketServiceLoginTest {
peerDiscoveryMock,
blockchainQueries,
synchronizer,
MainnetProtocolSchedule.fromConfig(genesisConfigOptions, new BadBlockManager()),
MainnetProtocolSchedule.fromConfig(
genesisConfigOptions,
MiningParameters.MINING_DISABLED,
new BadBlockManager()),
mock(ProtocolContext.class),
mock(FilterManager.class),
mock(TransactionPool.class),

View File

@@ -16,7 +16,7 @@
"response": {
"jsonrpc": "2.0",
"id": 4,
"error":{"code":-32603,"message":"Internal error"}
"result": "0x0000000000000000000000000000000000000000000000000000000000000001"
},
"statusCode": 200
}

View File

@@ -0,0 +1,25 @@
{
"request": {
"id": 4,
"jsonrpc": "2.0",
"method": "eth_call",
"params": [
{
"to": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f",
"from": "a94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"data": "0x12a7b914",
"blobVersionedHashes" : ["0x0100000051c8833cfbaf272e62da1285b183b0405357f62b052a4894ffcdaa2d"],
"gasPrice": "0x000000000000000000000000000000000000000000000000000000003437004a",
"maxFeePerBlobGas": "0x0000000000000000000000000000000000000000000000000000000000000000",
"strict": true
},
"latest"
]
},
"response": {
"jsonrpc": "2.0",
"id": 4,
"error":{"code":-32009,"message":"blob gas price below current blob base fee"}
},
"statusCode": 200
}

View File

@@ -17,7 +17,7 @@
"response": {
"jsonrpc": "2.0",
"id": 4,
"error":{"code":-32009,"message":"blob gas price below current blob base fee"}
"result": "0x0000000000000000000000000000000000000000000000000000000000000001"
},
"statusCode": 200
}

View File

@@ -364,6 +364,7 @@ abstract class AbstractBlockCreatorTest {
PrivacyParameters.DEFAULT,
false,
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager())
.createProtocolSchedule())
.build();

View File

@@ -221,6 +221,7 @@ public abstract class AbstractBlockTransactionSelectorTest {
FixedDifficultyProtocolSchedule.create(
GenesisConfigFile.development().getConfigOptions(),
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager());
final MainnetTransactionProcessor mainnetTransactionProcessor =
protocolSchedule.getByBlockHeader(blockHeader(0)).getTransactionProcessor();

View File

@@ -22,6 +22,7 @@ import static org.mockito.Mockito.when;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.eth.manager.EthContext;
import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration;
@@ -59,6 +60,7 @@ public class LegacyFeeMarketBlockTransactionSelectorTest
new PrivacyParameters(),
false,
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager())
.createProtocolSchedule();
}

View File

@@ -71,6 +71,7 @@ public class LondonFeeMarketBlockTransactionSelectorTest
new PrivacyParameters(),
false,
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager())
.createProtocolSchedule();
}

View File

@@ -93,6 +93,7 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
PrivacyParameters.DEFAULT,
false,
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager())
.createProtocolSchedule())
.build();
@@ -148,6 +149,7 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
PrivacyParameters.DEFAULT,
false,
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager())
.createProtocolSchedule())
.build();
@@ -193,6 +195,7 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
PrivacyParameters.DEFAULT,
false,
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager())
.createProtocolSchedule();
final ExecutionContextTestFixture executionContextTestFixture =
@@ -261,6 +264,7 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
PrivacyParameters.DEFAULT,
false,
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager())
.createProtocolSchedule();
final ExecutionContextTestFixture executionContextTestFixture =

View File

@@ -98,7 +98,7 @@ public class VersionMetadata {
* data directory. Currently this check is limited to checking that the version is >= the previous
* version, to avoid accidentally running a lower version of Besu and potentially corrupting data,
* but the method could be extended to perform any other version-to-version compatibility checks
* necessary. If the --version-compatibility-protection flag is set to true and the compatibilty
* necessary. If the --version-compatibility-protection flag is set to true and the compatibility
* checks pass, the version metadata is updated to the current version of Besu.
*/
public static void versionCompatibilityChecks(

View File

@@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.difficulty.fixed;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder;
@@ -30,6 +31,7 @@ public class FixedDifficultyProtocolSchedule {
final PrivacyParameters privacyParameters,
final boolean isRevertReasonEnabled,
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters,
final BadBlockManager badBlockManager) {
return new ProtocolScheduleBuilder(
config,
@@ -40,6 +42,7 @@ public class FixedDifficultyProtocolSchedule {
privacyParameters,
isRevertReasonEnabled,
evmConfiguration,
miningParameters,
badBlockManager)
.createProtocolSchedule();
}
@@ -48,19 +51,28 @@ public class FixedDifficultyProtocolSchedule {
final GenesisConfigOptions config,
final boolean isRevertReasonEnabled,
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters,
final BadBlockManager badBlockManager) {
return create(
config,
PrivacyParameters.DEFAULT,
isRevertReasonEnabled,
evmConfiguration,
miningParameters,
badBlockManager);
}
public static ProtocolSchedule create(
final GenesisConfigOptions config,
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters,
final BadBlockManager badBlockManager) {
return create(config, PrivacyParameters.DEFAULT, false, evmConfiguration, badBlockManager);
return create(
config,
PrivacyParameters.DEFAULT,
false,
evmConfiguration,
miningParameters,
badBlockManager);
}
}

View File

@@ -40,6 +40,13 @@ public abstract class AbstractGasLimitSpecification {
return Long.divideUnsigned(currentGasLimit, GAS_LIMIT_BOUND_DIVISOR);
}
/**
* Verify that the target gas limit is within the allowed bounds.
*
* @param targetGasLimit the target gas limit to validate
* @return true if within bounds
*/
@SuppressWarnings("ComparisonOutOfRange")
public static boolean isValidTargetGasLimit(final long targetGasLimit) {
return DEFAULT_MIN_GAS_LIMIT <= targetGasLimit && DEFAULT_MAX_GAS_LIMIT >= targetGasLimit;
}

View File

@@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.mainnet;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.difficulty.fixed.FixedDifficultyCalculators;
import org.hyperledger.besu.ethereum.difficulty.fixed.FixedDifficultyProtocolSchedule;
@@ -37,6 +38,7 @@ public class MainnetProtocolSchedule {
* @param privacyParameters the parameters set for private transactions
* @param isRevertReasonEnabled whether storing the revert reason is for failed transactions
* @param evmConfiguration how to configure the EVMs jumpdest cache
* @param miningParameters the mining parameters
* @param badBlockManager the cache to use to keep invalid blocks
* @return A configured mainnet protocol schedule
*/
@@ -45,10 +47,16 @@ public class MainnetProtocolSchedule {
final PrivacyParameters privacyParameters,
final boolean isRevertReasonEnabled,
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters,
final BadBlockManager badBlockManager) {
if (FixedDifficultyCalculators.isFixedDifficultyInConfig(config)) {
return FixedDifficultyProtocolSchedule.create(
config, privacyParameters, isRevertReasonEnabled, evmConfiguration, badBlockManager);
config,
privacyParameters,
isRevertReasonEnabled,
evmConfiguration,
miningParameters,
badBlockManager);
}
return new ProtocolScheduleBuilder(
config,
@@ -57,6 +65,7 @@ public class MainnetProtocolSchedule {
privacyParameters,
isRevertReasonEnabled,
evmConfiguration,
miningParameters,
badBlockManager)
.createProtocolSchedule();
}
@@ -68,6 +77,7 @@ public class MainnetProtocolSchedule {
* starting points
* @param isRevertReasonEnabled whether storing the revert reason is for failed transactions
* @param evmConfiguration how to configure the EVMs jumpdest cache
* @param miningParameters the mining parameters
* @param badBlockManager the cache to use to keep invalid blocks
* @return A configured mainnet protocol schedule
*/
@@ -75,12 +85,14 @@ public class MainnetProtocolSchedule {
final GenesisConfigOptions config,
final boolean isRevertReasonEnabled,
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters,
final BadBlockManager badBlockManager) {
return fromConfig(
config,
PrivacyParameters.DEFAULT,
isRevertReasonEnabled,
evmConfiguration,
miningParameters,
badBlockManager);
}
@@ -90,14 +102,22 @@ public class MainnetProtocolSchedule {
* @param config {@link GenesisConfigOptions} containing the config options for the milestone
* starting points
* @param evmConfiguration size of
* @param miningParameters the mining parameters
* @param badBlockManager the cache to use to keep invalid blocks
* @return A configured mainnet protocol schedule
*/
public static ProtocolSchedule fromConfig(
final GenesisConfigOptions config,
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters,
final BadBlockManager badBlockManager) {
return fromConfig(config, PrivacyParameters.DEFAULT, false, evmConfiguration, badBlockManager);
return fromConfig(
config,
PrivacyParameters.DEFAULT,
false,
evmConfiguration,
miningParameters,
badBlockManager);
}
/**
@@ -105,12 +125,20 @@ public class MainnetProtocolSchedule {
*
* @param config {@link GenesisConfigOptions} containing the config options for the milestone
* starting points
* @param miningParameters the mining parameters
* @param badBlockManager the cache to use to keep invalid blocks
* @return A configured mainnet protocol schedule
*/
public static ProtocolSchedule fromConfig(
final GenesisConfigOptions config, final BadBlockManager badBlockManager) {
final GenesisConfigOptions config,
final MiningParameters miningParameters,
final BadBlockManager badBlockManager) {
return fromConfig(
config, PrivacyParameters.DEFAULT, false, EvmConfiguration.DEFAULT, badBlockManager);
config,
PrivacyParameters.DEFAULT,
false,
EvmConfiguration.DEFAULT,
miningParameters,
badBlockManager);
}
}

View File

@@ -15,6 +15,7 @@
package org.hyperledger.besu.ethereum.mainnet;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.evm.internal.EvmConfiguration;
import java.math.BigInteger;
@@ -30,6 +31,7 @@ public class MainnetProtocolSpecFactory {
private final boolean isRevertReasonEnabled;
private final OptionalLong ecip1017EraRounds;
private final EvmConfiguration evmConfiguration;
private final MiningParameters miningParameters;
public MainnetProtocolSpecFactory(
final Optional<BigInteger> chainId,
@@ -37,13 +39,15 @@ public class MainnetProtocolSpecFactory {
final OptionalInt evmStackSize,
final boolean isRevertReasonEnabled,
final OptionalLong ecip1017EraRounds,
final EvmConfiguration evmConfiguration) {
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters) {
this.chainId = chainId;
this.contractSizeLimit = contractSizeLimit;
this.evmStackSize = evmStackSize;
this.isRevertReasonEnabled = isRevertReasonEnabled;
this.ecip1017EraRounds = ecip1017EraRounds;
this.evmConfiguration = evmConfiguration;
this.miningParameters = miningParameters;
}
public ProtocolSpecBuilder frontierDefinition() {
@@ -113,7 +117,8 @@ public class MainnetProtocolSpecFactory {
evmStackSize,
isRevertReasonEnabled,
genesisConfigOptions,
evmConfiguration);
evmConfiguration,
miningParameters);
}
public ProtocolSpecBuilder arrowGlacierDefinition(
@@ -124,7 +129,8 @@ public class MainnetProtocolSpecFactory {
evmStackSize,
isRevertReasonEnabled,
genesisConfigOptions,
evmConfiguration);
evmConfiguration,
miningParameters);
}
public ProtocolSpecBuilder grayGlacierDefinition(
@@ -135,7 +141,8 @@ public class MainnetProtocolSpecFactory {
evmStackSize,
isRevertReasonEnabled,
genesisConfigOptions,
evmConfiguration);
evmConfiguration,
miningParameters);
}
public ProtocolSpecBuilder parisDefinition(final GenesisConfigOptions genesisConfigOptions) {
@@ -145,7 +152,8 @@ public class MainnetProtocolSpecFactory {
evmStackSize,
isRevertReasonEnabled,
genesisConfigOptions,
evmConfiguration);
evmConfiguration,
miningParameters);
}
public ProtocolSpecBuilder shanghaiDefinition(final GenesisConfigOptions genesisConfigOptions) {
@@ -155,7 +163,8 @@ public class MainnetProtocolSpecFactory {
evmStackSize,
isRevertReasonEnabled,
genesisConfigOptions,
evmConfiguration);
evmConfiguration,
miningParameters);
}
public ProtocolSpecBuilder cancunDefinition(final GenesisConfigOptions genesisConfigOptions) {
@@ -165,7 +174,8 @@ public class MainnetProtocolSpecFactory {
evmStackSize,
isRevertReasonEnabled,
genesisConfigOptions,
evmConfiguration);
evmConfiguration,
miningParameters);
}
public ProtocolSpecBuilder pragueDefinition(final GenesisConfigOptions genesisConfigOptions) {
@@ -175,7 +185,8 @@ public class MainnetProtocolSpecFactory {
evmStackSize,
isRevertReasonEnabled,
genesisConfigOptions,
evmConfiguration);
evmConfiguration,
miningParameters);
}
/**
@@ -196,7 +207,8 @@ public class MainnetProtocolSpecFactory {
evmStackSize,
isRevertReasonEnabled,
genesisConfigOptions,
evmConfiguration);
evmConfiguration,
miningParameters);
}
/**
@@ -217,7 +229,8 @@ public class MainnetProtocolSpecFactory {
evmStackSize,
isRevertReasonEnabled,
genesisConfigOptions,
evmConfiguration);
evmConfiguration,
miningParameters);
}
////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -24,6 +24,7 @@ import org.hyperledger.besu.ethereum.MainnetBlockValidator;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.Deposit;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.TransactionReceipt;
@@ -433,7 +434,8 @@ public abstract class MainnetProtocolSpecs {
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions,
final EvmConfiguration evmConfiguration) {
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters) {
final int contractSizeLimit =
configContractSizeLimit.orElse(SPURIOUS_DRAGON_CONTRACT_SIZE_LIMIT);
final int stackSizeLimit = configStackSizeLimit.orElse(MessageFrame.DEFAULT_MAX_STACK_SIZE);
@@ -442,7 +444,10 @@ public abstract class MainnetProtocolSpecs {
final BaseFeeMarket londonFeeMarket =
genesisConfigOptions.isZeroBaseFee()
? FeeMarket.zeroBaseFee(londonForkBlockNumber)
: FeeMarket.london(londonForkBlockNumber, genesisConfigOptions.getBaseFeePerGas());
: genesisConfigOptions.isFixedBaseFee()
? FeeMarket.fixedBaseFee(
londonForkBlockNumber, miningParameters.getMinTransactionGasPrice())
: FeeMarket.london(londonForkBlockNumber, genesisConfigOptions.getBaseFeePerGas());
return berlinDefinition(
chainId,
configContractSizeLimit,
@@ -515,14 +520,16 @@ public abstract class MainnetProtocolSpecs {
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions,
final EvmConfiguration evmConfiguration) {
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters) {
return londonDefinition(
chainId,
configContractSizeLimit,
configStackSizeLimit,
enableRevertReason,
genesisConfigOptions,
evmConfiguration)
evmConfiguration,
miningParameters)
.difficultyCalculator(MainnetDifficultyCalculators.ARROW_GLACIER)
.name("ArrowGlacier");
}
@@ -533,14 +540,16 @@ public abstract class MainnetProtocolSpecs {
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions,
final EvmConfiguration evmConfiguration) {
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters) {
return arrowGlacierDefinition(
chainId,
configContractSizeLimit,
configStackSizeLimit,
enableRevertReason,
genesisConfigOptions,
evmConfiguration)
evmConfiguration,
miningParameters)
.difficultyCalculator(MainnetDifficultyCalculators.GRAY_GLACIER)
.name("GrayGlacier");
}
@@ -551,7 +560,8 @@ public abstract class MainnetProtocolSpecs {
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions,
final EvmConfiguration evmConfiguration) {
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters) {
return grayGlacierDefinition(
chainId,
@@ -559,7 +569,8 @@ public abstract class MainnetProtocolSpecs {
configStackSizeLimit,
enableRevertReason,
genesisConfigOptions,
evmConfiguration)
evmConfiguration,
miningParameters)
.evmBuilder(
(gasCalculator, jdCacheConfig) ->
MainnetEVMs.paris(gasCalculator, chainId.orElse(BigInteger.ZERO), evmConfiguration))
@@ -577,7 +588,8 @@ public abstract class MainnetProtocolSpecs {
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions,
final EvmConfiguration evmConfiguration) {
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters) {
// extra variables need to support flipping the warm coinbase flag.
final int stackSizeLimit = configStackSizeLimit.orElse(MessageFrame.DEFAULT_MAX_STACK_SIZE);
@@ -588,7 +600,8 @@ public abstract class MainnetProtocolSpecs {
configStackSizeLimit,
enableRevertReason,
genesisConfigOptions,
evmConfiguration)
evmConfiguration,
miningParameters)
// gas calculator has new code to support EIP-3860 limit and meter initcode
.gasCalculator(ShanghaiGasCalculator::new)
// EVM has a new operation for EIP-3855 PUSH0 instruction
@@ -638,14 +651,18 @@ public abstract class MainnetProtocolSpecs {
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions,
final EvmConfiguration evmConfiguration) {
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters) {
final int stackSizeLimit = configStackSizeLimit.orElse(MessageFrame.DEFAULT_MAX_STACK_SIZE);
final long londonForkBlockNumber = genesisConfigOptions.getLondonBlockNumber().orElse(0L);
final BaseFeeMarket cancunFeeMarket =
genesisConfigOptions.isZeroBaseFee()
? FeeMarket.zeroBaseFee(londonForkBlockNumber)
: FeeMarket.cancun(londonForkBlockNumber, genesisConfigOptions.getBaseFeePerGas());
: genesisConfigOptions.isFixedBaseFee()
? FeeMarket.fixedBaseFee(
londonForkBlockNumber, miningParameters.getMinTransactionGasPrice())
: FeeMarket.cancun(londonForkBlockNumber, genesisConfigOptions.getBaseFeePerGas());
return shanghaiDefinition(
chainId,
@@ -653,7 +670,8 @@ public abstract class MainnetProtocolSpecs {
configStackSizeLimit,
enableRevertReason,
genesisConfigOptions,
evmConfiguration)
evmConfiguration,
miningParameters)
.feeMarket(cancunFeeMarket)
// gas calculator for EIP-4844 blob gas
.gasCalculator(CancunGasCalculator::new)
@@ -710,7 +728,8 @@ public abstract class MainnetProtocolSpecs {
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions,
final EvmConfiguration evmConfiguration) {
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters) {
final int contractSizeLimit =
configContractSizeLimit.orElse(SPURIOUS_DRAGON_CONTRACT_SIZE_LIMIT);
@@ -720,7 +739,8 @@ public abstract class MainnetProtocolSpecs {
configStackSizeLimit,
enableRevertReason,
genesisConfigOptions,
evmConfiguration)
evmConfiguration,
miningParameters)
// EVM changes to support EOF EIPs (3670, 4200, 4750, 5450)
.gasCalculator(PragueGasCalculator::new)
.evmBuilder(
@@ -749,7 +769,8 @@ public abstract class MainnetProtocolSpecs {
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions,
final EvmConfiguration evmConfiguration) {
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters) {
final int contractSizeLimit =
configContractSizeLimit.orElse(SPURIOUS_DRAGON_CONTRACT_SIZE_LIMIT);
return pragueDefinition(
@@ -758,7 +779,8 @@ public abstract class MainnetProtocolSpecs {
configStackSizeLimit,
enableRevertReason,
genesisConfigOptions,
evmConfiguration)
evmConfiguration,
miningParameters)
// Use Future EIP configured EVM
.evmBuilder(
(gasCalculator, jdCacheConfig) ->
@@ -786,7 +808,8 @@ public abstract class MainnetProtocolSpecs {
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions,
final EvmConfiguration evmConfiguration) {
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters) {
final Address depositContractAddress =
genesisConfigOptions.getDepositContractAddress().orElse(DEFAULT_DEPOSIT_CONTRACT_ADDRESS);
@@ -797,7 +820,8 @@ public abstract class MainnetProtocolSpecs {
configStackSizeLimit,
enableRevertReason,
genesisConfigOptions,
evmConfiguration)
evmConfiguration,
miningParameters)
.evmBuilder(
(gasCalculator, jdCacheConfig) ->
MainnetEVMs.experimentalEips(

View File

@@ -173,12 +173,13 @@ public class MainnetTransactionValidator implements TransactionValidator {
if (maybeBlobFee.isEmpty()) {
throw new IllegalArgumentException(
"blob fee must be provided from blocks containing blobs");
// tx.getMaxFeePerBlobGas can be empty for eth_call
} else if (!transactionValidationParams.allowUnderpriced()
&& maybeBlobFee.get().compareTo(transaction.getMaxFeePerBlobGas().get()) > 0) {
return ValidationResult.invalid(
TransactionInvalidReason.BLOB_GAS_PRICE_BELOW_CURRENT_BLOB_BASE_FEE,
String.format(
"max fee per blob gas less than block blob gas fee: address %s blobGasFeeCap: %s, blobBaseFee: %s",
"tx max fee per blob gas less than block blob gas fee: address %s blobGasFeeCap: %s, blobBaseFee: %s",
transaction.getSender().toHexString(),
transaction.getMaxFeePerBlobGas().get().toHumanReadableString(),
maybeBlobFee.get().toHumanReadableString()));

View File

@@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.mainnet;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.privacy.PrivateTransactionValidator;
import org.hyperledger.besu.evm.internal.EvmConfiguration;
@@ -40,6 +41,7 @@ public class ProtocolScheduleBuilder {
private final PrivacyParameters privacyParameters;
private final boolean isRevertReasonEnabled;
private final EvmConfiguration evmConfiguration;
private final MiningParameters miningParameters;
private final BadBlockManager badBlockManager;
private DefaultProtocolSchedule protocolSchedule;
@@ -51,6 +53,7 @@ public class ProtocolScheduleBuilder {
final PrivacyParameters privacyParameters,
final boolean isRevertReasonEnabled,
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters,
final BadBlockManager badBlockManager) {
this(
config,
@@ -59,6 +62,7 @@ public class ProtocolScheduleBuilder {
privacyParameters,
isRevertReasonEnabled,
evmConfiguration,
miningParameters,
badBlockManager);
}
@@ -68,6 +72,7 @@ public class ProtocolScheduleBuilder {
final PrivacyParameters privacyParameters,
final boolean isRevertReasonEnabled,
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters,
final BadBlockManager badBlockManager) {
this(
config,
@@ -76,6 +81,7 @@ public class ProtocolScheduleBuilder {
privacyParameters,
isRevertReasonEnabled,
evmConfiguration,
miningParameters,
badBlockManager);
}
@@ -86,6 +92,7 @@ public class ProtocolScheduleBuilder {
final PrivacyParameters privacyParameters,
final boolean isRevertReasonEnabled,
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters,
final BadBlockManager badBlockManager) {
this.config = config;
this.protocolSpecAdapters = protocolSpecAdapters;
@@ -93,6 +100,7 @@ public class ProtocolScheduleBuilder {
this.isRevertReasonEnabled = isRevertReasonEnabled;
this.evmConfiguration = evmConfiguration;
this.defaultChainId = defaultChainId;
this.miningParameters = miningParameters;
this.badBlockManager = badBlockManager;
}
@@ -113,7 +121,8 @@ public class ProtocolScheduleBuilder {
config.getEvmStackSize(),
isRevertReasonEnabled,
config.getEcip1017EraRounds(),
evmConfiguration);
evmConfiguration,
miningParameters);
validateForkOrdering();

View File

@@ -53,6 +53,10 @@ public interface FeeMarket {
return new ZeroBaseFeeMarket(londonForkBlockNumber);
}
static BaseFeeMarket fixedBaseFee(final long londonForkBlockNumber, final Wei fixedBaseFee) {
return new FixedBaseFeeMarket(londonForkBlockNumber, fixedBaseFee);
}
static FeeMarket legacy() {
return new LegacyFeeMarket();
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright Hyperledger Besu Contributors.
*
* 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
*/
package org.hyperledger.besu.ethereum.mainnet.feemarket;
import org.hyperledger.besu.datatypes.Wei;
import java.util.Optional;
public class FixedBaseFeeMarket extends LondonFeeMarket {
public FixedBaseFeeMarket(final long londonForkBlockNumber, final Wei fixedBaseFee) {
super(londonForkBlockNumber, Optional.of(fixedBaseFee));
}
@Override
public Wei computeBaseFee(
final long blockNumber,
final Wei parentBaseFee,
final long parentBlockGasUsed,
final long targetGasUsed) {
return baseFeeInitialValue;
}
@Override
public ValidationMode baseFeeValidationMode(final long blockNumber) {
return ValidationMode.NONE;
}
}

View File

@@ -35,7 +35,7 @@ public class LondonFeeMarket implements BaseFeeMarket {
private static final Wei DEFAULT_BASEFEE_FLOOR = Wei.of(7L);
private final Wei baseFeeInitialValue;
protected final Wei baseFeeInitialValue;
private final long londonForkBlockNumber;
private final TransactionPriceCalculator txPriceCalculator;
private final Wei baseFeeFloor;

View File

@@ -16,22 +16,10 @@ package org.hyperledger.besu.ethereum.mainnet.feemarket;
import org.hyperledger.besu.datatypes.Wei;
import java.util.Optional;
public class ZeroBaseFeeMarket extends LondonFeeMarket {
public class ZeroBaseFeeMarket extends FixedBaseFeeMarket {
public ZeroBaseFeeMarket(final long londonForkBlockNumber) {
super(londonForkBlockNumber, Optional.of(Wei.ZERO));
}
@Override
public Wei computeBaseFee(
final long blockNumber,
final Wei parentBaseFee,
final long parentBlockGasUsed,
final long targetGasUsed) {
return Wei.ZERO;
super(londonForkBlockNumber, Wei.ZERO);
}
@Override

View File

@@ -124,7 +124,7 @@ public class PluginPrivacyController extends AbstractPrivacyController {
@Override
public Optional<PrivacyGroup> findPrivacyGroupByGroupId(
final String privacyGroupId, final String privacyUserId) {
verifyPrivacyGroupContainsPrivacyUserId(privacyUserId, privacyGroupId);
verifyPrivacyGroupContainsPrivacyUserId(privacyGroupId, privacyUserId);
return Optional.of(
new PrivacyGroup(
@@ -155,7 +155,7 @@ public class PluginPrivacyController extends AbstractPrivacyController {
@Override
public void verifyPrivacyGroupContainsPrivacyUserId(
final String privacyUserId, final String privacyGroupId) {
verifyPrivacyGroupContainsPrivacyUserId(privacyUserId, privacyGroupId, Optional.empty());
final String privacyGroupId, final String privacyUserId) {
verifyPrivacyGroupContainsPrivacyUserId(privacyGroupId, privacyUserId, Optional.empty());
}
}

View File

@@ -18,7 +18,6 @@ import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
import org.hyperledger.besu.evm.log.Log;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@@ -56,7 +55,7 @@ public class TransactionProcessingResult
public static TransactionProcessingResult invalid(
final ValidationResult<TransactionInvalidReason> validationResult) {
return new TransactionProcessingResult(
Status.INVALID, new ArrayList<>(), -1, -1, Bytes.EMPTY, validationResult, Optional.empty());
Status.INVALID, List.of(), -1, -1, Bytes.EMPTY, validationResult, Optional.empty());
}
public static TransactionProcessingResult failed(
@@ -66,7 +65,7 @@ public class TransactionProcessingResult
final Optional<Bytes> revertReason) {
return new TransactionProcessingResult(
Status.FAILED,
new ArrayList<>(),
List.of(),
gasUsedByTransaction,
gasRemaining,
Bytes.EMPTY,

View File

@@ -26,7 +26,7 @@ import java.util.Optional;
import org.apache.tuweni.bytes.Bytes;
// Represents parameters for a eth_call or eth_estimateGas JSON-RPC methods.
// Represents parameters for eth_call and eth_estimateGas JSON-RPC methods.
public class CallParameter {
private final Address from;

View File

@@ -32,6 +32,7 @@ public enum TransactionInvalidReason {
TX_SENDER_NOT_AUTHORIZED,
CHAIN_HEAD_NOT_AVAILABLE,
CHAIN_HEAD_WORLD_STATE_NOT_AVAILABLE,
BLOCK_NOT_FOUND,
EXCEEDS_PER_TRANSACTION_GAS_LIMIT,
INVALID_TRANSACTION_FORMAT,
TRANSACTION_PRICE_TOO_LOW,

View File

@@ -247,6 +247,18 @@ public class TransactionSimulator {
final MainnetTransactionProcessor transactionProcessor =
protocolSchedule.getByBlockHeader(blockHeaderToProcess).getTransactionProcessor();
final Optional<BlockHeader> maybeParentHeader =
blockchain.getBlockHeader(blockHeaderToProcess.getParentHash());
final Wei blobGasPrice =
transactionValidationParams.isAllowExceedingBalance()
? Wei.ZERO
: protocolSpec
.getFeeMarket()
.blobGasPricePerGas(
maybeParentHeader
.map(parent -> calculateExcessBlobGasForParent(protocolSpec, parent))
.orElse(BlobGas.ZERO));
final Optional<Transaction> maybeTransaction =
buildTransaction(
callParams,
@@ -256,21 +268,12 @@ public class TransactionSimulator {
nonce,
gasLimit,
value,
payload);
payload,
blobGasPrice);
if (maybeTransaction.isEmpty()) {
return Optional.empty();
}
final Optional<BlockHeader> maybeParentHeader =
blockchain.getBlockHeader(blockHeaderToProcess.getParentHash());
final Wei blobGasPrice =
protocolSpec
.getFeeMarket()
.blobGasPricePerGas(
maybeParentHeader
.map(parent -> calculateExcessBlobGasForParent(protocolSpec, parent))
.orElse(BlobGas.ZERO));
final Transaction transaction = maybeTransaction.get();
final TransactionProcessingResult result =
transactionProcessor.processTransaction(
@@ -298,7 +301,8 @@ public class TransactionSimulator {
final long nonce,
final long gasLimit,
final Wei value,
final Bytes payload) {
final Bytes payload,
final Wei blobGasPrice) {
final Transaction.Builder transactionBuilder =
Transaction.builder()
.nonce(nonce)
@@ -313,20 +317,21 @@ public class TransactionSimulator {
callParams.getAccessList().ifPresent(transactionBuilder::accessList);
// Set versioned hashes if present
callParams.getBlobVersionedHashes().ifPresent(transactionBuilder::versionedHashes);
// Set max fee per blob gas if present
callParams.getMaxFeePerBlobGas().ifPresent(transactionBuilder::maxFeePerBlobGas);
final Wei gasPrice;
final Wei maxFeePerGas;
final Wei maxPriorityFeePerGas;
final Wei maxFeePerBlobGas;
if (transactionValidationParams.isAllowExceedingBalance()) {
gasPrice = Wei.ZERO;
maxFeePerGas = Wei.ZERO;
maxPriorityFeePerGas = Wei.ZERO;
maxFeePerBlobGas = Wei.ZERO;
} else {
gasPrice = callParams.getGasPrice() != null ? callParams.getGasPrice() : Wei.ZERO;
maxFeePerGas = callParams.getMaxFeePerGas().orElse(gasPrice);
maxPriorityFeePerGas = callParams.getMaxPriorityFeePerGas().orElse(gasPrice);
maxFeePerBlobGas = callParams.getMaxFeePerBlobGas().orElse(blobGasPrice);
}
if (header.getBaseFee().isEmpty()) {
transactionBuilder.gasPrice(gasPrice);
@@ -337,6 +342,9 @@ public class TransactionSimulator {
}
transactionBuilder.guessType();
if (transactionBuilder.getTransactionType().supportsBlob()) {
transactionBuilder.maxFeePerBlobGas(maxFeePerBlobGas);
}
if (transactionBuilder.getTransactionType().requiresChainId()) {
transactionBuilder.chainId(
protocolSchedule

View File

@@ -142,7 +142,10 @@ public class BlockchainSetupUtil {
private static ProtocolSchedule mainnetProtocolScheduleProvider(
final GenesisConfigFile genesisConfigFile) {
return MainnetProtocolSchedule.fromConfig(
genesisConfigFile.getConfigOptions(), EvmConfiguration.DEFAULT, new BadBlockManager());
genesisConfigFile.getConfigOptions(),
EvmConfiguration.DEFAULT,
MiningParameters.newDefault(),
new BadBlockManager());
}
private static ProtocolContext mainnetProtocolContextProvider(

View File

@@ -140,6 +140,7 @@ public class ExecutionContextTestFixture {
new PrivacyParameters(),
false,
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager())
.createProtocolSchedule();
}

View File

@@ -39,6 +39,7 @@ public class ProtocolScheduleFixture {
PrivacyParameters.DEFAULT,
false,
EvmConfiguration.DEFAULT,
MiningParameters.newDefault(),
new BadBlockManager());
private static GenesisConfigOptions getMainnetConfigOptions() {

View File

@@ -20,6 +20,7 @@ import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.evm.internal.EvmConfiguration;
@@ -34,6 +35,7 @@ public class FixedProtocolScheduleTest {
FixedDifficultyProtocolSchedule.create(
GenesisConfigFile.development().getConfigOptions(),
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager());
final BlockHeaderTestFixture headerBuilder = new BlockHeaderTestFixture();

View File

@@ -23,6 +23,7 @@ import org.hyperledger.besu.config.StubGenesisConfigOptions;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.evm.internal.EvmConfiguration;
@@ -60,6 +61,7 @@ public class DefaultProtocolScheduleTest {
privacyParameters,
isRevertReasonEnabled,
evmConfiguration,
MiningParameters.MINING_DISABLED,
new BadBlockManager());
}

View File

@@ -18,6 +18,7 @@ import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.ProtocolScheduleFixture;
import org.hyperledger.besu.evm.internal.EvmConfiguration;
@@ -74,6 +75,7 @@ public class MainnetProtocolScheduleTest {
MainnetProtocolSchedule.fromConfig(
GenesisConfigFile.fromConfig("{}").getConfigOptions(),
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager());
Assertions.assertThat(sched.getByBlockHeader(blockHeader(1L)).getName()).isEqualTo("Frontier");
Assertions.assertThat(sched.getByBlockHeader(blockHeader(Long.MAX_VALUE)).getName())
@@ -88,6 +90,7 @@ public class MainnetProtocolScheduleTest {
MainnetProtocolSchedule.fromConfig(
GenesisConfigFile.fromConfig(json).getConfigOptions(),
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager());
Assertions.assertThat(sched.getByBlockHeader(blockHeader(1)).getName()).isEqualTo("Frontier");
Assertions.assertThat(sched.getByBlockHeader(blockHeader(2)).getName()).isEqualTo("Homestead");
@@ -119,6 +122,7 @@ public class MainnetProtocolScheduleTest {
MainnetProtocolSchedule.fromConfig(
GenesisConfigFile.fromConfig(json).getConfigOptions(),
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager()));
}
@@ -131,6 +135,7 @@ public class MainnetProtocolScheduleTest {
this.getClass().getResource("/goerli.json"), StandardCharsets.UTF_8))
.getConfigOptions(),
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager());
Assertions.assertThat(sched.getByBlockHeader(blockHeader(0L)).getName())
.isEqualTo("Petersburg");

View File

@@ -358,7 +358,7 @@ public class MainnetTransactionValidatorTest {
.isEqualTo(ValidationResult.invalid(BLOB_GAS_PRICE_BELOW_CURRENT_BLOB_BASE_FEE));
assertThat(validationResult.getErrorMessage())
.matches(
"max fee per blob gas less than block blob gas fee: address 0x[0-9a-f]+ blobGasFeeCap: 7 wei, blobBaseFee: 10 wei");
"tx max fee per blob gas less than block blob gas fee: address 0x[0-9a-f]+ blobGasFeeCap: 7 wei, blobBaseFee: 10 wei");
}
@Test

View File

@@ -26,6 +26,7 @@ import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
import org.hyperledger.besu.ethereum.core.MilestoneStreamingProtocolSchedule;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.evm.internal.EvmConfiguration;
@@ -59,6 +60,7 @@ class ProtocolScheduleBuilderTest {
new PrivacyParameters(),
false,
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager());
}
@@ -213,6 +215,7 @@ class ProtocolScheduleBuilderTest {
new PrivacyParameters(),
false,
EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED,
new BadBlockManager());
return new MilestoneStreamingProtocolSchedule(

View File

@@ -72,6 +72,12 @@ public class TargetingGasLimitCalculatorTest {
.isFalse();
}
@Test
public void verifyMaxGasLimit() {
assertThat(AbstractGasLimitSpecification.isValidTargetGasLimit(Long.MAX_VALUE - 1)).isTrue();
assertThat(AbstractGasLimitSpecification.isValidTargetGasLimit(Long.MAX_VALUE)).isTrue();
}
@Test
public void verifyWithinGasLimitDelta() {
final long targetGasLimit = 10_000_000L;

View File

@@ -0,0 +1,152 @@
/*
* Copyright Hyperledger Besu Contributors.
*
* 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
*/
package org.hyperledger.besu.ethereum.mainnet.feemarket;
import static org.assertj.core.api.Assertions.assertThat;
import org.hyperledger.besu.crypto.KeyPair;
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
import org.hyperledger.besu.datatypes.BlobGas;
import org.hyperledger.besu.datatypes.TransactionType;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.TransactionTestFixture;
import java.util.Optional;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class FixedBaseFeeMarketTest {
private static final KeyPair KEY_PAIR1 =
SignatureAlgorithmFactory.getInstance().generateKeyPair();
private static final long FORK_BLOCK = 0;
private FixedBaseFeeMarket fixedBaseFeeMarket;
@BeforeEach
public void setUp() throws Exception {
fixedBaseFeeMarket = new FixedBaseFeeMarket(FORK_BLOCK, Wei.ONE);
}
@Test
public void getBasefeeMaxChangeDenominatorShouldUseLondonDefault() {
assertThat(fixedBaseFeeMarket.getBasefeeMaxChangeDenominator())
.isEqualTo(LondonFeeMarket.DEFAULT_BASEFEE_MAX_CHANGE_DENOMINATOR);
}
@Test
public void getInitialBasefeeShouldBeZero() {
assertThat(fixedBaseFeeMarket.getInitialBasefee()).isEqualTo(Wei.ONE);
}
@Test
public void getSlackCoefficientShouldUseLondonDefault() {
assertThat(fixedBaseFeeMarket.getSlackCoefficient())
.isEqualTo(LondonFeeMarket.DEFAULT_SLACK_COEFFICIENT);
}
@Test
public void getTransactionPriceCalculatorShouldBeEIP1559() {
// only eip1559 will read the fee per gas values
final Transaction transaction =
new TransactionTestFixture()
.type(TransactionType.EIP1559)
.maxFeePerGas(Optional.of(Wei.of(8)))
.maxPriorityFeePerGas(Optional.of(Wei.of(8)))
.gasPrice(null)
.createTransaction(KEY_PAIR1);
assertThat(
fixedBaseFeeMarket
.getTransactionPriceCalculator()
.price(transaction, Optional.of(Wei.ZERO)))
.isEqualTo(Wei.of(8));
}
@Test
public void satisfiesFloorTxCostWhenGasFeeIsNonZero() {
final Transaction transaction =
new TransactionTestFixture()
.type(TransactionType.FRONTIER)
.gasPrice(Wei.of(7))
.createTransaction(KEY_PAIR1);
assertThat(fixedBaseFeeMarket.satisfiesFloorTxFee(transaction)).isTrue();
}
@Test
public void satisfiesFloorTxCostWhenGasFeeIsZero() {
final Transaction transaction =
new TransactionTestFixture()
.type(TransactionType.EIP1559)
.maxFeePerGas(Optional.of(Wei.ZERO))
.maxPriorityFeePerGas(Optional.of(Wei.ZERO))
.gasPrice(null)
.createTransaction(KEY_PAIR1);
assertThat(fixedBaseFeeMarket.satisfiesFloorTxFee(transaction)).isFalse();
}
@Test
public void computeBaseFeeReturnsFixedValue() {
assertThat(fixedBaseFeeMarket.computeBaseFee(1L, Wei.of(1), 1L, 2L)).isEqualTo(Wei.ONE);
}
@Test
public void baseFeeValidationModeShouldBeNoneWhenIsForkBlock() {
assertThat(fixedBaseFeeMarket.baseFeeValidationMode(FORK_BLOCK))
.isEqualTo(BaseFeeMarket.ValidationMode.NONE);
}
@Test
public void baseFeeValidationModeShouldBeNoneWhenIsNotForkBlock() {
assertThat(fixedBaseFeeMarket.baseFeeValidationMode(FORK_BLOCK + 1))
.isEqualTo(BaseFeeMarket.ValidationMode.NONE);
}
@Test
public void gasLimitValidationModeShouldBeInitialWhenIsForkBlock() {
assertThat(fixedBaseFeeMarket.gasLimitValidationMode(FORK_BLOCK))
.isEqualTo(BaseFeeMarket.ValidationMode.INITIAL);
}
@Test
public void gasLimitValidationModeShouldBeOngoingWhenIsNotForkBlock() {
assertThat(fixedBaseFeeMarket.gasLimitValidationMode(FORK_BLOCK + 1))
.isEqualTo(BaseFeeMarket.ValidationMode.ONGOING);
}
@Test
public void isBeforeForkBlockShouldBeTrue() {
final FixedBaseFeeMarket fixedBaseFeeMarket = new FixedBaseFeeMarket(10, Wei.ONE);
assertThat(fixedBaseFeeMarket.isBeforeForkBlock(9)).isTrue();
}
@Test
public void isBeforeForkBlockShouldBeFalse() {
final FixedBaseFeeMarket fixedBaseFeeMarket = new FixedBaseFeeMarket(10, Wei.ONE);
assertThat(fixedBaseFeeMarket.isBeforeForkBlock(10)).isFalse();
assertThat(fixedBaseFeeMarket.isBeforeForkBlock(11)).isFalse();
}
@Test
public void implementsDataFeedShouldReturnFalse() {
assertThat(fixedBaseFeeMarket.implementsDataFee()).isFalse();
}
@Test
public void dataPriceShouldReturnsZero() {
assertThat(fixedBaseFeeMarket.blobGasPricePerGas(BlobGas.ONE)).isEqualTo(Wei.ZERO);
}
}

View File

@@ -128,4 +128,29 @@ public class BaseFeeMarketBlockHeaderGasPriceValidationRuleTest {
blockHeader(FORK_BLOCK - 1, 0, Optional.of(londonFeeMarketBaseFee))))
.isTrue();
}
@Test
public void shouldReturnTrueIfUsingFixedBaseFeeMarket() {
final BaseFeeMarket fixedBaseFeeMarket = FeeMarket.fixedBaseFee(FORK_BLOCK, Wei.ONE);
final var validationRule =
new BaseFeeMarketBlockHeaderGasPriceValidationRule(fixedBaseFeeMarket);
assertThat(
validationRule.validate(
blockHeader(FORK_BLOCK + 2, 0, Optional.of(fixedBaseFeeMarket.getInitialBasefee())),
blockHeader(FORK_BLOCK + 1, 0, Optional.of(feeMarket.getInitialBasefee()), 2)))
.isTrue();
}
@Test
public void shouldReturnTrueIfUsingFixedBaseFeeMarketOnNonZeroLondonForkBlock() {
final BaseFeeMarket zeroBaseFeeMarket = FeeMarket.fixedBaseFee(FORK_BLOCK, Wei.ONE);
final var validationRule =
new BaseFeeMarketBlockHeaderGasPriceValidationRule(zeroBaseFeeMarket);
final Wei londonFeeMarketBaseFee = feeMarket.getInitialBasefee();
assertThat(
validationRule.validate(
blockHeader(FORK_BLOCK, 0, Optional.of(londonFeeMarketBaseFee)),
blockHeader(FORK_BLOCK - 1, 0, Optional.of(londonFeeMarketBaseFee))))
.isTrue();
}
}

View File

@@ -0,0 +1,75 @@
/*
* Copyright Hyperledger Besu Contributors.
*
* 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
*/
package org.hyperledger.besu.ethereum.mainnet.headervalidationrules;
import static java.lang.Long.MAX_VALUE;
import static org.assertj.core.api.Assertions.assertThat;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket;
import org.hyperledger.besu.ethereum.mainnet.feemarket.FixedBaseFeeMarket;
import java.util.Optional;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
public class GasLimitElasticityValidationRuleFixedBaseFeeMarketTest {
private static final Optional<BaseFeeMarket> fixedBaseFeeMarket =
Optional.of(new FixedBaseFeeMarket(10, Wei.ONE));
public GasLimitRangeAndDeltaValidationRule uut =
new GasLimitRangeAndDeltaValidationRule(5000, MAX_VALUE, fixedBaseFeeMarket);
@ParameterizedTest
@CsvSource({
"20000000, 10000000, 10, true",
"20019530, 10000000, 10, true",
"20019531, 10000000, 10, false",
"19980470, 10000000, 10, true",
"19980469, 10000000, 10, false",
"20000000, 20000000, 11, true",
"20019530, 20000000, 11, true",
"20019531, 20000000, 11, false",
"19980470, 20000000, 11, true",
"19980469, 20000000, 11, false",
"40039061, 40000000, 11, true",
"40039062, 40000000, 11, false",
"39960939, 40000000, 11, true",
"39960938, 40000000, 11, false",
"4999, 40000000, 11, false"
})
public void test(
final long headerGasLimit,
final long parentGasLimit,
final long headerNumber,
final boolean expectedResult) {
final BlockHeaderTestFixture blockHeaderBuilder = new BlockHeaderTestFixture();
blockHeaderBuilder.number(headerNumber);
blockHeaderBuilder.gasLimit(headerGasLimit);
final BlockHeader header = blockHeaderBuilder.buildHeader();
blockHeaderBuilder.number(headerNumber - 1);
blockHeaderBuilder.gasLimit(parentGasLimit);
final BlockHeader parent = blockHeaderBuilder.buildHeader();
assertThat(uut.validate(header, parent)).isEqualTo(expectedResult);
}
}

View File

@@ -105,7 +105,9 @@ public abstract class AbstractIsolationTests {
.createKeyPair(SECPPrivateKey.create(Bytes32.fromHexString(key), "ECDSA"));
protected final ProtocolSchedule protocolSchedule =
MainnetProtocolSchedule.fromConfig(
GenesisConfigFile.development().getConfigOptions(), new BadBlockManager());
GenesisConfigFile.development().getConfigOptions(),
MiningParameters.MINING_DISABLED,
new BadBlockManager());
protected final GenesisState genesisState =
GenesisState.fromConfig(GenesisConfigFile.development(), protocolSchedule);
protected final MutableBlockchain blockchain = createInMemoryBlockchain(genesisState.getBlock());

View File

@@ -401,6 +401,18 @@ public class EthPeer implements Comparable<EthPeer> {
messageData);
}
/**
* Determines the validity of a message received from a peer. A message is considered valid if
* either of the following conditions are met: 1) The message is a request type message (e.g.
* GET_BLOCK_HEADERS), or 2) The message is a response type message (e.g. BLOCK_HEADERS), the node
* has made at least 1 request for that type of message (i.e. it has sent at least 1
* GET_BLOCK_HEADERS request), and it has at least 1 outstanding request of that type which it
* expects to receive a response for.
*
* @param message The message being validated
* @param protocolName The protocol type of the message
* @return true if the message is valid as per the above logic, otherwise false.
*/
public boolean validateReceivedMessage(final EthMessage message, final String protocolName) {
checkArgument(message.getPeer().equals(this), "Mismatched message sent to peer for dispatch");
return getRequestManager(protocolName, message.getData().getCode())
@@ -442,6 +454,16 @@ public class EthPeer implements Comparable<EthPeer> {
dispatch(ethMessage, protocolName);
}
/**
* Attempt to get a request manager for a received response-type message e.g. BLOCK_HEADERS. If
* the message is a request-type message e.g. GET_BLOCK_HEADERS no request manager will exist so
* Optional.empty() will be returned.
*
* @param protocolName the type of protocol the message is for
* @param code the message code
* @return a request manager for the received response messsage, or Optional.empty() if this is a
* request message
*/
private Optional<RequestManager> getRequestManager(final String protocolName, final int code) {
if (requestManagers.containsKey(protocolName)) {
final Map<Integer, RequestManager> managers = requestManagers.get(protocolName);

View File

@@ -100,12 +100,9 @@ public class StorageRangeDataRequest extends SnapDataRequest {
(location, hash, value) -> {
applyForStrategy(
updater,
onBonsai -> {
onBonsai.putAccountStorageTrieNode(accountHash, location, hash, value);
},
onForest -> {
onForest.putAccountStorageTrieNode(hash, value);
});
onBonsai -> onBonsai.putAccountStorageTrieNode(accountHash, location, hash, value),
onForest -> onForest.putAccountStorageTrieNode(hash, value));
nbNodesSaved.incrementAndGet();
};
final AtomicReference<StackTrie.FlatDatabaseUpdater> flatDatabaseUpdater =

Some files were not shown because too many files have changed in this diff Show More