mirror of
https://github.com/vacp2p/linea-besu.git
synced 2026-01-09 21:17:54 -05:00
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:
64
.github/workflows/develop.yml
vendored
64
.github/workflows/develop.yml
vendored
@@ -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}}
|
||||
15
CHANGELOG.md
15
CHANGELOG.md
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -130,6 +130,7 @@ public class CliqueBesuControllerBuilder extends BesuControllerBuilder {
|
||||
privacyParameters,
|
||||
isRevertReasonEnabled,
|
||||
evmConfiguration,
|
||||
miningParameters,
|
||||
badBlockManager);
|
||||
}
|
||||
|
||||
|
||||
@@ -286,6 +286,7 @@ public class IbftBesuControllerBuilder extends BftBesuControllerBuilder {
|
||||
isRevertReasonEnabled,
|
||||
bftExtraDataCodec().get(),
|
||||
evmConfiguration,
|
||||
miningParameters,
|
||||
badBlockManager);
|
||||
}
|
||||
|
||||
|
||||
@@ -95,6 +95,7 @@ public class MainnetBesuControllerBuilder extends BesuControllerBuilder {
|
||||
privacyParameters,
|
||||
isRevertReasonEnabled,
|
||||
evmConfiguration,
|
||||
miningParameters,
|
||||
badBlockManager);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -326,6 +326,7 @@ public class QbftBesuControllerBuilder extends BftBesuControllerBuilder {
|
||||
isRevertReasonEnabled,
|
||||
bftExtraDataCodec().get(),
|
||||
evmConfiguration,
|
||||
miningParameters,
|
||||
badBlockManager);
|
||||
}
|
||||
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
79
build.gradle
79
build.gradle
@@ -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"]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -106,6 +106,7 @@ public class CliqueBlockCreatorTest {
|
||||
proposerNodeKey,
|
||||
false,
|
||||
EvmConfiguration.DEFAULT,
|
||||
MiningParameters.MINING_DISABLED,
|
||||
new BadBlockManager());
|
||||
|
||||
final Address otherAddress = Util.publicKeyToAddress(otherKeyPair.getPublicKey());
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -332,6 +332,7 @@ public class TestContextBuilder {
|
||||
forksSchedule,
|
||||
IBFT_EXTRA_DATA_ENCODER,
|
||||
EvmConfiguration.DEFAULT,
|
||||
MiningParameters.MINING_DISABLED,
|
||||
new BadBlockManager());
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -120,6 +120,7 @@ public class BftBlockCreatorTest {
|
||||
false,
|
||||
bftExtraDataEncoder,
|
||||
EvmConfiguration.DEFAULT,
|
||||
MiningParameters.MINING_DISABLED,
|
||||
new BadBlockManager());
|
||||
final ProtocolContext protContext =
|
||||
new ProtocolContext(
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<>();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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))
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"response": {
|
||||
"jsonrpc": "2.0",
|
||||
"id": 4,
|
||||
"error":{"code":-32603,"message":"Internal error"}
|
||||
"result": "0x0000000000000000000000000000000000000000000000000000000000000001"
|
||||
},
|
||||
"statusCode": 200
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -364,6 +364,7 @@ abstract class AbstractBlockCreatorTest {
|
||||
PrivacyParameters.DEFAULT,
|
||||
false,
|
||||
EvmConfiguration.DEFAULT,
|
||||
MiningParameters.MINING_DISABLED,
|
||||
new BadBlockManager())
|
||||
.createProtocolSchedule())
|
||||
.build();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ public class LondonFeeMarketBlockTransactionSelectorTest
|
||||
new PrivacyParameters(),
|
||||
false,
|
||||
EvmConfiguration.DEFAULT,
|
||||
MiningParameters.MINING_DISABLED,
|
||||
new BadBlockManager())
|
||||
.createProtocolSchedule();
|
||||
}
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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()));
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -140,6 +140,7 @@ public class ExecutionContextTestFixture {
|
||||
new PrivacyParameters(),
|
||||
false,
|
||||
EvmConfiguration.DEFAULT,
|
||||
MiningParameters.MINING_DISABLED,
|
||||
new BadBlockManager())
|
||||
.createProtocolSchedule();
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ public class ProtocolScheduleFixture {
|
||||
PrivacyParameters.DEFAULT,
|
||||
false,
|
||||
EvmConfiguration.DEFAULT,
|
||||
MiningParameters.newDefault(),
|
||||
new BadBlockManager());
|
||||
|
||||
private static GenesisConfigOptions getMainnetConfigOptions() {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user