From d5ee9b7bb1e852ce2c367d130d818591c1771770 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Fri, 11 Oct 2024 10:28:39 +0200 Subject: [PATCH 1/4] Fix eth_feeHistory rewards when bounded by configuration (#7750) Signed-off-by: Fabio Di Fabio --- CHANGELOG.md | 1 + .../internal/methods/EthFeeHistory.java | 45 ++++++++----- .../jsonrpc/methods/EthJsonRpcMethods.java | 6 +- .../internal/methods/EthFeeHistoryTest.java | 67 +++++++++++++++++-- 4 files changed, 90 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64b6844330..5c26ef6e77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ### Additions and Improvements ### Bug fixes +- Fix eth_feeHistory rewards when bounded by configuration [#7750](https://github.com/hyperledger/besu/pull/7750) ## 24.10.0 diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthFeeHistory.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthFeeHistory.java index b95746dad9..2c5c6afd05 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthFeeHistory.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthFeeHistory.java @@ -14,7 +14,6 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; -import static java.util.stream.Collectors.toUnmodifiableList; import static org.hyperledger.besu.ethereum.mainnet.feemarket.ExcessBlobGasCalculator.calculateExcessBlobGasForParent; import org.hyperledger.besu.datatypes.Hash; @@ -32,6 +31,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSucces import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.FeeHistory; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.ImmutableFeeHistory; +import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.blockcreation.MiningCoordinator; import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.core.Block; @@ -57,9 +57,11 @@ import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Streams; +import org.apache.tuweni.units.bigints.UInt256s; public class EthFeeHistory implements JsonRpcMethod { private final ProtocolSchedule protocolSchedule; + private final BlockchainQueries blockchainQueries; private final Blockchain blockchain; private final MiningCoordinator miningCoordinator; private final ApiConfiguration apiConfiguration; @@ -70,13 +72,14 @@ public class EthFeeHistory implements JsonRpcMethod { public EthFeeHistory( final ProtocolSchedule protocolSchedule, - final Blockchain blockchain, + final BlockchainQueries blockchainQueries, final MiningCoordinator miningCoordinator, final ApiConfiguration apiConfiguration) { this.protocolSchedule = protocolSchedule; - this.blockchain = blockchain; + this.blockchainQueries = blockchainQueries; this.miningCoordinator = miningCoordinator; this.apiConfiguration = apiConfiguration; + this.blockchain = blockchainQueries.getBlockchain(); this.cache = Caffeine.newBuilder().maximumSize(MAXIMUM_CACHE_SIZE).build(); } @@ -136,7 +139,8 @@ public class EthFeeHistory implements JsonRpcMethod { final List gasUsedRatios = getGasUsedRatios(blockHeaderRange); final List blobGasUsedRatios = getBlobGasUsedRatios(blockHeaderRange); final Optional>> maybeRewards = - maybeRewardPercentiles.map(rewards -> getRewards(rewards, blockHeaderRange)); + maybeRewardPercentiles.map( + percentiles -> getRewards(percentiles, blockHeaderRange, nextBaseFee)); return new JsonRpcSuccessResponse( requestId, createFeeHistoryResult( @@ -203,17 +207,19 @@ public class EthFeeHistory implements JsonRpcMethod { } private List> getRewards( - final List rewardPercentiles, final List blockHeaders) { + final List rewardPercentiles, + final List blockHeaders, + final Wei nextBaseFee) { var sortedPercentiles = rewardPercentiles.stream().sorted().toList(); return blockHeaders.stream() .parallel() - .map(blockHeader -> calculateBlockHeaderReward(sortedPercentiles, blockHeader)) + .map(blockHeader -> calculateBlockHeaderReward(sortedPercentiles, blockHeader, nextBaseFee)) .flatMap(Optional::stream) .toList(); } private Optional> calculateBlockHeaderReward( - final List sortedPercentiles, final BlockHeader blockHeader) { + final List sortedPercentiles, final BlockHeader blockHeader, final Wei nextBaseFee) { // Create a new key for the reward cache final RewardCacheKey key = new RewardCacheKey(blockHeader.getBlockHash(), sortedPercentiles); @@ -226,7 +232,7 @@ public class EthFeeHistory implements JsonRpcMethod { Optional block = blockchain.getBlockByHash(blockHeader.getBlockHash()); return block.map( b -> { - List rewards = computeRewards(sortedPercentiles, b); + List rewards = computeRewards(sortedPercentiles, b, nextBaseFee); // Put the computed rewards in the cache for future use cache.put(key, rewards); return rewards; @@ -237,7 +243,8 @@ public class EthFeeHistory implements JsonRpcMethod { record TransactionInfo(Transaction transaction, Long gasUsed, Wei effectivePriorityFeePerGas) {} @VisibleForTesting - public List computeRewards(final List rewardPercentiles, final Block block) { + public List computeRewards( + final List rewardPercentiles, final Block block, final Wei nextBaseFee) { final List transactions = block.getBody().getTransactions(); if (transactions.isEmpty()) { // all 0's for empty block @@ -253,7 +260,7 @@ public class EthFeeHistory implements JsonRpcMethod { // If the priority fee boundary is set, return the bounded rewards. Otherwise, return the real // rewards. if (apiConfiguration.isGasAndPriorityFeeLimitingEnabled()) { - return boundRewards(realRewards); + return boundRewards(realRewards, nextBaseFee); } else { return realRewards; } @@ -292,16 +299,20 @@ public class EthFeeHistory implements JsonRpcMethod { * This method returns a list of bounded rewards. * * @param rewards The list of rewards to be bounded. + * @param nextBaseFee The base fee of the next block. * @return The list of bounded rewards. */ - private List boundRewards(final List rewards) { - Wei minPriorityFee = miningCoordinator.getMinPriorityFeePerGas(); - Wei lowerBound = - minPriorityFee + private List boundRewards(final List rewards, final Wei nextBaseFee) { + final Wei lowerBoundGasPrice = blockchainQueries.gasPriceLowerBound(); + final Wei lowerBoundPriorityFee = lowerBoundGasPrice.subtract(nextBaseFee); + final Wei minPriorityFee = miningCoordinator.getMinPriorityFeePerGas(); + final Wei forcedMinPriorityFee = UInt256s.max(minPriorityFee, lowerBoundPriorityFee); + final Wei lowerBound = + forcedMinPriorityFee .multiply(apiConfiguration.getLowerBoundGasAndPriorityFeeCoefficient()) .divide(100); - Wei upperBound = - minPriorityFee + final Wei upperBound = + forcedMinPriorityFee .multiply(apiConfiguration.getUpperBoundGasAndPriorityFeeCoefficient()) .divide(100); @@ -438,7 +449,7 @@ public class EthFeeHistory implements JsonRpcMethod { .oldestBlock(oldestBlock) .baseFeePerGas( Stream.concat(explicitlyRequestedBaseFees.stream(), Stream.of(nextBaseFee)) - .collect(toUnmodifiableList())) + .toList()) .baseFeePerBlobGas(requestedBlobBaseFees) .gasUsedRatio(gasUsedRatios) .blobGasUsedRatio(blobGasUsedRatio) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/EthJsonRpcMethods.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/EthJsonRpcMethods.java index 5baa110646..de5662692f 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/EthJsonRpcMethods.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/EthJsonRpcMethods.java @@ -132,11 +132,7 @@ public class EthJsonRpcMethods extends ApiGroupJsonRpcMethods { blockchainQueries.getWorldStateArchive(), protocolSchedule, apiConfiguration.getGasCap())), - new EthFeeHistory( - protocolSchedule, - blockchainQueries.getBlockchain(), - miningCoordinator, - apiConfiguration), + new EthFeeHistory(protocolSchedule, blockchainQueries, miningCoordinator, apiConfiguration), new EthGetCode(blockchainQueries), new EthGetLogs(blockchainQueries, apiConfiguration.getMaxLogsRange()), new EthGetProof(blockchainQueries), diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthFeeHistoryTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthFeeHistoryTest.java index a04cb06c67..f34f336e03 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthFeeHistoryTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthFeeHistoryTest.java @@ -39,6 +39,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.FeeHistory; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.ImmutableFeeHistory; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.ImmutableFeeHistoryResult; +import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.blockcreation.MiningCoordinator; import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.chain.MutableBlockchain; @@ -69,6 +70,7 @@ import org.junit.jupiter.api.Test; public class EthFeeHistoryTest { final BlockDataGenerator gen = new BlockDataGenerator(); + private BlockchainQueries blockchainQueries; private MutableBlockchain blockchain; private EthFeeHistory method; private ProtocolSchedule protocolSchedule; @@ -82,14 +84,15 @@ public class EthFeeHistoryTest { gen.blockSequence(genesisBlock, 10) .forEach(block -> blockchain.appendBlock(block, gen.receipts(block))); miningCoordinator = mock(MergeCoordinator.class); - when(miningCoordinator.getMinPriorityFeePerGas()).thenReturn(Wei.ONE); + + blockchainQueries = mockBlockchainQueries(blockchain, Wei.of(7)); mockFork(); method = new EthFeeHistory( protocolSchedule, - blockchain, + blockchainQueries, miningCoordinator, ImmutableApiConfiguration.builder().build()); } @@ -139,11 +142,16 @@ public class EthFeeHistoryTest { Block block = mock(Block.class); Blockchain blockchain = mockBlockchainTransactionsWithPriorityFee(block); + final var blockchainQueries = mockBlockchainQueries(blockchain, Wei.of(7)); + EthFeeHistory ethFeeHistory = new EthFeeHistory( - null, blockchain, miningCoordinator, ImmutableApiConfiguration.builder().build()); + null, + blockchainQueries, + miningCoordinator, + ImmutableApiConfiguration.builder().build()); - List rewards = ethFeeHistory.computeRewards(rewardPercentiles, block); + List rewards = ethFeeHistory.computeRewards(rewardPercentiles, block, Wei.of(7)); // Define the expected rewards for each percentile // The expected rewards match the fees of the transactions at each percentile in the @@ -179,14 +187,51 @@ public class EthFeeHistoryTest { .upperBoundGasAndPriorityFeeCoefficient(500L) .build(); // Max reward = Wei.One * 500L / 100 = 5.0 + final var blockchainQueries = mockBlockchainQueries(blockchain, Wei.of(7)); + when(miningCoordinator.getMinPriorityFeePerGas()).thenReturn(Wei.ONE); + EthFeeHistory ethFeeHistory = - new EthFeeHistory(null, blockchain, miningCoordinator, apiConfiguration); + new EthFeeHistory(null, blockchainQueries, miningCoordinator, apiConfiguration); - List rewards = ethFeeHistory.computeRewards(rewardPercentiles, block); + List rewards = ethFeeHistory.computeRewards(rewardPercentiles, block, Wei.of(7)); // Define the expected bounded rewards for each percentile List expectedBoundedRewards = Stream.of(2, 2, 2, 4, 5, 5, 5, 5, 5).map(Wei::of).toList(); - assertThat(expectedBoundedRewards).isEqualTo(rewards); + assertThat(rewards).isEqualTo(expectedBoundedRewards); + } + + @Test + public void shouldApplyLowerBoundRewardsCorrectly() { + // This test checks that the rewards are correctly bounded by the lower and upper limits, + // when the calculated lower bound for the priority fee is greater than the configured one. + // Configured minPriorityFeePerGas is 0 wei, minGasPrice is 10 wei and baseFee is 8 wei, + // so for a tx to be mined the minPriorityFeePerGas is raised to 2 wei before applying the + // coefficients. + + List rewardPercentiles = + Arrays.asList(0.0, 5.0, 10.0, 27.50, 31.0, 59.0, 60.0, 61.0, 100.0); + + Block block = mock(Block.class); + Blockchain blockchain = mockBlockchainTransactionsWithPriorityFee(block); + + ApiConfiguration apiConfiguration = + ImmutableApiConfiguration.builder() + .isGasAndPriorityFeeLimitingEnabled(true) + .lowerBoundGasAndPriorityFeeCoefficient(200L) // Min reward = 2 * 200L / 100 = 4.0 + .upperBoundGasAndPriorityFeeCoefficient(300L) + .build(); // Max reward = 2 * 300L / 100 = 6.0 + + final var blockchainQueries = mockBlockchainQueries(blockchain, Wei.of(10)); + when(miningCoordinator.getMinPriorityFeePerGas()).thenReturn(Wei.ZERO); + + EthFeeHistory ethFeeHistory = + new EthFeeHistory(null, blockchainQueries, miningCoordinator, apiConfiguration); + + List rewards = ethFeeHistory.computeRewards(rewardPercentiles, block, Wei.of(8)); + + // Define the expected bounded rewards for each percentile + List expectedBoundedRewards = Stream.of(4, 4, 4, 4, 5, 6, 6, 6, 6).map(Wei::of).toList(); + assertThat(rewards).isEqualTo(expectedBoundedRewards); } private Blockchain mockBlockchainTransactionsWithPriorityFee(final Block block) { @@ -399,4 +444,12 @@ public class EthFeeHistoryTest { return method.response( new JsonRpcRequestContext(new JsonRpcRequest("2.0", "eth_feeHistory", params))); } + + private BlockchainQueries mockBlockchainQueries( + final Blockchain blockchain, final Wei gasPriceLowerBound) { + final var blockchainQueries = mock(BlockchainQueries.class); + when(blockchainQueries.getBlockchain()).thenReturn(blockchain); + when(blockchainQueries.gasPriceLowerBound()).thenReturn(gasPriceLowerBound); + return blockchainQueries; + } } From 6c49c734efe4c0aeb35f45977dc8478e7637b6bb Mon Sep 17 00:00:00 2001 From: garyschulte Date: Fri, 11 Oct 2024 08:58:25 -0700 Subject: [PATCH 2/4] Add eip-2537 functions to evmtool benchmark subcommand (#7708) * add bls12 g1/g2 to evmtool benchmark subcommand Signed-off-by: garyschulte --- .../besu/evmtool/BenchmarkSubCommand.java | 5 +- .../evmtool/benchmarks/BLS12Benchmark.java | 390 ++++++++++++++++++ .../AbstractBLS12PrecompiledContract.java | 14 + gradle.properties | 6 +- 4 files changed, 413 insertions(+), 2 deletions(-) create mode 100644 ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BLS12Benchmark.java diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/BenchmarkSubCommand.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/BenchmarkSubCommand.java index 829bf2d58e..5b20912ca1 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/BenchmarkSubCommand.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/BenchmarkSubCommand.java @@ -19,6 +19,7 @@ import static picocli.CommandLine.ScopeType.INHERIT; import org.hyperledger.besu.BesuInfo; import org.hyperledger.besu.evmtool.benchmarks.AltBN128Benchmark; +import org.hyperledger.besu.evmtool.benchmarks.BLS12Benchmark; import org.hyperledger.besu.evmtool.benchmarks.BenchmarkExecutor; import org.hyperledger.besu.evmtool.benchmarks.ECRecoverBenchmark; import org.hyperledger.besu.evmtool.benchmarks.ModExpBenchmark; @@ -56,7 +57,9 @@ public class BenchmarkSubCommand implements Runnable { // blake2f EcRecover(new ECRecoverBenchmark()), ModExp(new ModExpBenchmark()), - Secp256k1(new Secp256k1Benchmark()); + Secp256k1(new Secp256k1Benchmark()), + // bls12 + Bls12(new BLS12Benchmark()); final BenchmarkExecutor benchmarkExecutor; diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BLS12Benchmark.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BLS12Benchmark.java new file mode 100644 index 0000000000..a95f48c0df --- /dev/null +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BLS12Benchmark.java @@ -0,0 +1,390 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * 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.evmtool.benchmarks; + +import org.hyperledger.besu.evm.EvmSpecVersion; +import org.hyperledger.besu.evm.precompile.AbstractBLS12PrecompiledContract; +import org.hyperledger.besu.evm.precompile.BLS12G1AddPrecompiledContract; +import org.hyperledger.besu.evm.precompile.BLS12G1MulPrecompiledContract; +import org.hyperledger.besu.evm.precompile.BLS12G1MultiExpPrecompiledContract; +import org.hyperledger.besu.evm.precompile.BLS12G2AddPrecompiledContract; +import org.hyperledger.besu.evm.precompile.BLS12G2MulPrecompiledContract; +import org.hyperledger.besu.evm.precompile.BLS12G2MultiExpPrecompiledContract; +import org.hyperledger.besu.evm.precompile.BLS12MapFp2ToG2PrecompiledContract; +import org.hyperledger.besu.evm.precompile.BLS12MapFpToG1PrecompiledContract; +import org.hyperledger.besu.evm.precompile.BLS12PairingPrecompiledContract; + +import java.io.PrintStream; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.apache.tuweni.bytes.Bytes; + +/** Benchmark BLS12-381 G1 and G2 MSM */ +public class BLS12Benchmark extends BenchmarkExecutor { + + /** Benchmark BLS12-381 G1 and G2 MSM with default warmup and iterations */ + public BLS12Benchmark() { + super(MATH_WARMUP, MATH_ITERATIONS); + } + + static final String[] scalars = { + "4e826175762bd086135d18ae935fb085ab3e12b0f5aa4ea3aac99a1c41afae34", + "7257faefdb84241d947a02c5d19daee65333d6277dfe7212849528eb7812bede", + "d291f31a5a96f170cc6dc8144562f8c7dbe67afe79c2a2ec53222bc129cbeba4", + "b99e32c244f2de2fc6b462a55584229818c5c4cdfd2c74454d7d85e58d8a4809", + "cdb41b97d135aff1d848c3ee8885073a972cbdb92ab5f1dc79e89840ef51f6a3", + "d4c909fae1c3b026ebcdb4a1885c1f5d8b6cb4aaa9cf8712e8a3add53da55bf0", + "4dd3dd8562816ac0bd72081d2dea42d27078a5618ff525bef4fd2628a6fb4326", + "0c68f33b013b0bc960b4e905e75e225bf27e468692d0f271e7e30af23b905393", + "2c2dd13c6858693241613d34d45cfcf05c5f71fcb5b34483d8ef3133e5af6304", + "0b4fca47643819aeea5fa85035ffa735c0945fbe6e1170f9639ca478b45a41fd", + "1e76ab4951f522acc99225ef30b9b4936d27134e76d86222e8b916c9cde4bc78", + "36b4741673e3f433bf460632c2a89b279e8032d7b236c402f4720b361c865a04", + "e40cded572e8ad87da276d41d08edafe10576b526776b8e71c6d80bdf6239932", + "25ea3392dff756934628f586ada2225f5af0e03078d704cde4da460875698e6b", + "450648e218031d8307ae71a369d95a86ebe14db8f5d394697633a379be496976", + "f03b5f08231c44cedcea848dc18a42bef0895ba4696e8ec7ecaa0615a5158883", + "9fa8482dda8cc2f20cd9b4dc63f72be23a7652e7e5fe1436b90b477adb735ed1", + "0978dda7cb30dd643e472b0a3f8196fc51fad22d30f0f01d7cb570d85d7b353b", + "387b7f3f892cc754b5dc6c724d89b791934f6914778b5c84a6892abe6b999ab1", + "1d2b5094b14b26c9ed3100222f19bbbb289f2638c29f5fbbafd68574873d4287", + "cd7aabd84ffd41b589dec5d4af4b17681218e1fa16a3e9855385d35b18dfd2b2", + "d3c6c9bb36e9d5647eadd40ac68b57e0fa17352f558f270b8f7724f6dd3f19d4", + "7d7f485c07f94d37c80e6710515863b780883e2beee772bc7d7c1cc0f10ed245", + "8d7bd0d7a9ff1fc481fc6b9a6d1c58d6bf01d7017f7a3bd1b826d38076d1c6fd", + "f939c5d735bef50e7d22408012d3bb664179d098a42fa2f2dfe2bdb8f9b6c074", + "b02686dd55be9fc6a791cac72a2c32b5e6f86c0f5b92b52f2efc72ac2043837d", + "11073c2c13655c6802ae8918403d17106d630b7519bc61dc6e592bca5f7392c8", + "fb8130bbf0067026d67d44e464b568db99e0dc02dc48fe8a4753d806cd647d3f", + "a558312bdbefc905932e51cb05eab0cd546a8f9a41a135746eac247840ca434e", + "9b5026e422f16837ca568490bd4ebba629391319b9b076d7c644989991a00c94", + "c480e504a8ca9556770dd3b9cd8d515f505098c0450679c158ed54f75d9224c0", + "8b450d2be25e0f596ef0c1a4fa06fbc044f087704469f499aa8967ce8844f080", + }; + + static final String[] g1PointPairs = { + "0000000000000000000000000000000009f5bf486941d9a9f8c742fa43ee279d75419d4c11d1fbaed1dc19c624e168dcfe50ce4673d7ca6d42051dc7b799d7b3000000000000000000000000000000000aa47f7618e3dbe09730b9d378ac113dd841f7e42dfb390ff486e2820345208e2d7433244eedb233bcb807c08c55919e", + "000000000000000000000000000000000786d2c808ffaa25cc78e484da52b01698ad8eb55846961d2b62fd578432f3466da7e22cc34298fec4e34e33b88243b300000000000000000000000000000000015e8b79f94e318336bc50f0cdc4c9bde81052ffd0fd48c5b915be878a1a1b2f3a71d7587fd9892a44c9ec71fac5bb80", + "0000000000000000000000000000000016206b9006c026c95c2879f2b950a074b2660333962e21d06d3cf1a9d6ff33921349f286a9002b515b384104a32076de0000000000000000000000000000000009b72f249f9037ca7cec181df2f5798d0a8253d86dd61ca6e416cd1652bd4c400a5689e6d29783fa1a8578700470146d", + "00000000000000000000000000000000093f21aaaaf2044cdf9a80ca3afa75db4e32aa2870fb6b9dbb22493956d6e01a7f566d567b67307b1ca91355669b28d100000000000000000000000000000000083b0a9758f5b562b930f24456e56845a87352a9b28367df59f46b570af1b8b3f2a4d4a7e9d272faf2fdb53d5077cf51", + "0000000000000000000000000000000003cc0abeff05a8d78ee0e94d8cf71d6d0a5889968b99e5b9c6a3d283d7fcf44caf8c11619c75020bf9dc8e8fb451407d0000000000000000000000000000000005171356814d04c944564fbe478f1c953c96d5b8b269813d0a31272346c078956103eb2808ae2c83528066a9e54736fd", + "000000000000000000000000000000000437b80cfb19bc01e0050bb3def6da7dcfc7b26c4eb35b2f922685062bfac10d78b02d86ab45025286bb9f3293c2560f000000000000000000000000000000001934da79acc0e74284af492d5fb1f942ac5ff8660f18769f4f241ec724df952c9286eee55683b4c495f1cb4c3e1fbbf4", + "0000000000000000000000000000000006310c85629fe02d094c224f83dbfebd9cb950ccb28832000771663bb93cf4cb8ad8016f0fc4ee42f8584ad8ce00498a0000000000000000000000000000000014264f7c2fe86174729843b3db54cdb76b5a892fc73a5e67083b937448634e516a93e170934c1b8a30c71a8405735bb3", + "000000000000000000000000000000000b6539f785b36fd3dc041676bd37c77033c26e3881b4b47fbd093eb28c7ce9ecef7c9b588850e08ec06793d0e0034d95000000000000000000000000000000000401571cd8ef0289d239bf7b0115708e2ba04a577548c38a5b283cd3bf945185e2f7ba744ba345e60a61b9405865a67a", + "000000000000000000000000000000001861eb880875a3f7bb7a45eb2dd32adffb68abf1682a5268a68fd9691db119c72f7f21cb98884619ec09f4f9a9189816000000000000000000000000000000000233a0e8c1f4c7dc3e4672f7a6a1e226bb07f445790f5d0c5b1437a3030e4b4e95645c9d0aae16e570d79af0830b8ada", + "000000000000000000000000000000000f99c56935dea38c1691645d3ab576a762b5559c31c46edbc8c70b74c3b40f79c84c4623cc72206732a620beec0ed10d000000000000000000000000000000000786714ffa00436d9e53f898e98a5fd3bc799dfe0eac8f7ab4204b2c9b464329aa14bc58aa23ab1606113b8a90a98b81", + "00000000000000000000000000000000005e8658e3105fe051190127fba5db7d2ec47655bed72acc1c4a9b985b1330932b6e339d76d9f56b2b8d6e8b8cba1f420000000000000000000000000000000019e18081a769839b3849222e2f9bef86f50f398409d776e7e5f462bef75e8769a7257139826ae4dab7be8a344e43eb35", + "0000000000000000000000000000000005cdf9c9f5091d495d7c8707505c9051fd6bc2e01899bdb24d8f55e97e0c034b2ea2173c73250acf3814a3751659b653000000000000000000000000000000000adbeed0c8abdd5650502e96a14ec1b0af697d27f1de92e82a4d70dd763a7c83df1e1483a73155a7362ab6e830cb5b60", + "0000000000000000000000000000000006aa3ff84449d8326edc0971e18dd77d06ef2f7214c8849dc9db9e9541f2788e84f1713daa2fd014308321930f474493000000000000000000000000000000000f39da6466995da0227cef277bb50692373896bca7b0c6dad3fa6241e367186fce75cfe67337e59660adea207cf21578", + "0000000000000000000000000000000011079caf8ecad1b7fc8a5e52fa02e2cc54fdeff788ce74d94de474e964736da7bbd48fe103908fdfaf21e618cd8bd570000000000000000000000000000000001391f3f5ac9d63bc769e3462323a25349fb879849966a14c28d7ea4c43656dec785e9c10e600fb2c77960185a25a5a30", + "00000000000000000000000000000000030ada1568c82dbe97fc8b7f3f0119014513ea86a109f76d4e0fab865515c1a2a2f062da5d2fec52585fcbc61b62822700000000000000000000000000000000141e65d12ff426e2a6b665f7860e8dae8d1de1e4e3a3a062032a555d79e820bbfd727cf769980bde73dd181db7b4ef4b", + "000000000000000000000000000000000e17d2ed1881b7513d2323e606c6551036c86f1c455657e8c7d56bd95ab906d9b2cb56a244ddbe59e7552d1eebb1e19400000000000000000000000000000000176bfc0dd0953a54f5c3c162a7b5d30375cfda78da80975757cf9496b9aa015263efb035a0361c794c89478896cd1e82", + "000000000000000000000000000000001560b598256b713e21cb49b0e16849456d555788a93d1bb778ad7f8f4b090cf0aa115a5f0535eac2276fd1d81d10db44000000000000000000000000000000000d6d0b42990da37fd54801164a148adebcf4ed22874ab64f78f6d323a3bf07ce8470214c4bfb4a0a2e5d979d34f8091f", + "000000000000000000000000000000000a17df46b5bb50ed8c065aab3b551a1a174d85758169a57f952c08a6878466efc0faad3439b341f9e863e360fd2450f7000000000000000000000000000000000e20917637b3f270025909ecdc1946aed29389d60af02933b3da348ab6ac5380198c8fc6985547c7438452c7d977ac41", + "00000000000000000000000000000000139e3c560a50d7fb86e3b59fbac5445f9c0ab0978b3cf1d6d51d5dbfd86b8233c1a0d13a3bc3c2f266d1d938519c801a0000000000000000000000000000000014fd5a3ca318171ef34723ee5cf58b4736105cc69e5c3a10da3fb895e45f1569fc5ede086a5737281280f11ad7d77b1d", + "0000000000000000000000000000000006419acd10144ced4f53b8a875f6ff40b777af68ecf3e7245243b9c74037fc128ed2c9e6304e629deac852007695b615000000000000000000000000000000001234916bc5701e0b43af04174cf25b780da79f643f5dcb98748b3ee9c5cd9d39e8c026948745970cc1d7e839616ef649", + "00000000000000000000000000000000105f212197eb701ed73f5c3ef3a6504d10e20ce70de26a76f3f1e5ce444d1a24e2384d63d4dfd3998d6cd938505adaeb0000000000000000000000000000000016e5f4d98bac752563aefee58920392f3db9c24873c42cd7d0ac7f26a412502dafea025fc63a7b45f8ff5f390a76c7e7", + "0000000000000000000000000000000010e3a266c9fe2ef7bd6da2a11ad73466d398177738a69629a55fdd33ec088600d750f4b270213f091b25f67d7d4687d50000000000000000000000000000000016eabfcc65d89e64317145fd2dfd397841a20c54518ce9133cc38768fe8a12aa937b25fb088a0f92cd9de81b45b1ee24", + "00000000000000000000000000000000196205afe922e753f3b9907caedf380fc506bae61e12bf48483560c32f7f62d28c94b3a3661cd8e09f6445893f471e60000000000000000000000000000000000385e8e99fec6bec5a6ca1c1b947317a7f98b9d6860228a752cbf909153a5ab045a9fafc3d0d10f4d38e3e29311fb9e3", + "0000000000000000000000000000000014ca7e56d5209106aed424aa92d8b9a746da0eca913aaf5dbee3cb010fcd7db0a969eb5b8ba56a222d29424db5d2ee43000000000000000000000000000000000df722a8de5dc9333df241f1b8eec12c3c3c34194f065dabe9177c00928279db561ddc648d074975921fd6ca9fe795b2", + "0000000000000000000000000000000017f9ffb90222613c6e03da79ce610a53c10b218ab1a57e3b8c136ea22360f52965f9b1d349f25ea2e7d71a669c8b12d200000000000000000000000000000000150f4c0c65de339cdf44826213be1c5307fe820c80f44729276af0d5e3f1e8c1b7eedba77ab58f742f9f045493a4f583", + "000000000000000000000000000000001643c91e1ea8ead940645595352fb680642deba457b2222b415144fe64d0031b8efc4de5d7c42f63c6e64a7be988514200000000000000000000000000000000143b72204f89fa6fcd6f603e370904e532acbe51930495bce552e3eb2081453806a432a18e52874e495b989111b22435", + "00000000000000000000000000000000165b7fe90a6e39a14a11eb729aae227f35cf9ae240bed66c296e616c7a4912183e985532d5a5e1200cb42a5392b33baa00000000000000000000000000000000056a849e23ffcb32e04a1aa50b3402efe8854173180c8ebca1c55e52a59629e8557c6c8f3914cb03e9088e371ef2f835", + "00000000000000000000000000000000066f0bc365eb53a05bc9561d32af5d32acc0796f5a76eaa1c8f15f1b0a3ac6f3bc911bca630749dcc64ed2f9c4e25d56000000000000000000000000000000000f9ba6af35d2f116f4341b03caf175bc27f007d5645866dc3b3bee8665d45f204f73e0e25cdcfa339b2946773919e804", + "00000000000000000000000000000000104673bac88cbacfd38a26aca0a5435407e2086f2c666c89b5769393bfc247a10937ec3441c6c274760b590d2622a9df0000000000000000000000000000000019cb77c56ad20e574cdd0681bfc1131f069f58ad8e3a5e8898cc100a4c59e503a400e095d44bc5cdffb2ec8c07825ece", + "00000000000000000000000000000000039faa653341ea8e2ddfdf2bdc5de84d8a1a9027abedab3cadf5c1fb69262f0db7ea94ac8bb2abfb132a000d390b58f80000000000000000000000000000000012aadfad64ca2203860ef91a1cb88cbf817be2676ad25c7cd55bc84a6012621a41909fe28325276aa3cad5baf1be6cb0", + "00000000000000000000000000000000004dba2a3ff8eb3ef159ff2e66c65f51016efb2f755ef41089f84960dca19a62d6677ecc59ad1a7ca3abf4d11944d53d00000000000000000000000000000000002a928c7e135f095226050069ea0b219d42b8865cbae0d3ba9f10aa283dfa7c28f1778adc0225356eb2579379b57263", + "0000000000000000000000000000000017979ff6656fc8d015b8b5d486ae947000d277ce55a69b19d63f63ab654aaf0892dda72dfbc082bc3bef59f96af872a20000000000000000000000000000000019ac1fe79cb8a3373f7224d4115beaf742cb3bdafd954aad002c2ba24874392f6a0ba5f5b225d3c3c3cf82979254cbe0" + }; + + String[] g2PointPairs = { + "000000000000000000000000000000000bb1edbc28a9930c190f6f1d49f8964c13c13940242e9d8688717ed57149389453e048e3e43a38ca28fd8a07ac60e5960000000000000000000000000000000016ba918cddac3b49dcf808317f7490e5dd49e6594ee9ee9b584261a1ce43a3882b3e1362863537fe6ca429dc17f28e3c0000000000000000000000000000000017ad94874960ed6d0443ca1b8906f84adec505795684c54e155ee8de878b219bf65ed125f3dbf42e3905fbf985e59764000000000000000000000000000000001782e9b75fea3c4d072bb86858c76cc368a67a1f2597a4724e2c79f7c787b4737c2f642dc32ab10ed66f40ae675b1a6e", + "00000000000000000000000000000000031c2efcc72f74504a2057906f93bef5d47b2482b1eb6d4442563988798b1385010a64f8e1b38a93e6e06283f4bf43d1000000000000000000000000000000000733cfcab23720f699b4c02de7a211482c84e6eeb62a3d901b557fdfdf484ce27c33f56fdcbd542430d72fd78d2ceab400000000000000000000000000000000152daff8a24165368b963d4f4560856a74be3f0dd3879bf4d75e34eb70c201661921460085ca06188371fc9fbfdd8eaf0000000000000000000000000000000008a6c6a920452e4ff0c8de495b93c9e971af127a5c0d0143fb61d0c981883709c64d837f41842729f8ce926f8634a11a", + "00000000000000000000000000000000149c85c410022026a7a89b7f52b9b3e3d3f3629ca7aafb0e21cdb9539856990fa7f8bdbeb19915a072c37f1af35d72e00000000000000000000000000000000002776e9edde84ae38e88cc3bac626066ca752d3f1d381b3919e5f3ee1c15b5b513dae00444cce37c732e1a0b6868207c0000000000000000000000000000000004e5b747b2cdd32bdb52e1fba8138f5e44ac98f365aaff35c99399eb115af904c569995d8ed4d87ceda4407e0c5569d90000000000000000000000000000000015f6a5da3f739d2b9365c6031298cd875a6746b3e866e4605f8b82e20e282f3424cd8bd86ff35652ac3d25a3696bb294", + "00000000000000000000000000000000100f6cc96dcfc630d73141bb8be25ba2256ea81f2d7f55ed0cbe50333715673cc36a8f37a10f3222111afce400bc9ba70000000000000000000000000000000015ad4090a4a27d9939a1f5768dadb247e17cae0f101c5e3b588cfd303e4424a0a937cd02127708af7b1c20eb9405329200000000000000000000000000000000084cc62a4313b2a8d0396d8cbfe0ffa08171062042dfcfd773dd88d83a164c1cc435de4d7e04b36d9146f914e6880efe00000000000000000000000000000000099c27c3a74eb6eab8556fd8861c9a96a7b7032745161fcad09cca9cba13f992d54c3b13e4bce08cba158996ce4dc7e3", + "0000000000000000000000000000000016437f645c71e932c9c62f6076e25adb6e8e2ba2a124d01762a8fef382730352d7b8d0cebefb51d7912c78532ef4cc000000000000000000000000000000000018568a31a5005deeaa6a0750965f856bae2a5fc3f76b5743ee45852a177ab7fc0eabd9c402e53e2ffd3bec7f600e65a40000000000000000000000000000000000312e67aac16d8433565047121cfed6cf8c968e1d090996342d6c417e778407f62be6b73034f855422904b4f0dce31c00000000000000000000000000000000023bd285eaf6a36e8362b0b647d121ed980aeaf4523f65ab587312ec4eac28612637a39a0f05898bdf711b68bd32be79", + "00000000000000000000000000000000195e4ef43e2515cc7d19bfd3aa814b9f9e2ed4913f65fa8edf38e66aa64ab98eed6c0b54d6146d9455059a900b325ae9000000000000000000000000000000001158355772c7af7533a7fd22fefcec6855ebe7ba2a0d74e8f549f64dc363ef00495bd1f363686a8518a118e4a103674f000000000000000000000000000000001670781d5d8c7a080e2dc286347a7036ef8cea3d4a865996e5232c2a6e92b23eb74020c1fb6171bd0045d04e4fa07bce000000000000000000000000000000000eb69584271e1671710581dbb381aa40fad35b28e63578c5fdb1b408d13d5f77654d1aa99c9856ac150ff4824ee7aba7", + "000000000000000000000000000000000e86e03117fb5327c9deac44c0053dcb9956b1d0c6e948a43aef6c07f5ff8c2e3bc3cf8e6e06fa54923ecb8ede6d9ac80000000000000000000000000000000016095c62b00a2297aff748c7c7ae2e48c1e92c8509d05e5cd91af473442f3db56289d5f0078a8af722bede285b244c9a000000000000000000000000000000000399422a0d7d1618f5ad1cdee685d5c91cdb257b4743e7c8504328df81e6a345f073d46477ef2ed27b85f4a87033b5e80000000000000000000000000000000002c8853c746b06ac0bb83ea3444ccd2beb1595e42047a09e9321375ca51cdfd0eabe5c7d4c7e603df44c404af5b84755", + "000000000000000000000000000000000e6d721b7ceb4c026c387fba083484264cdb87c979ab45aceb0c800ef0af7b67ca495b4e8e929077f6b2d70552843551000000000000000000000000000000000076523e8c6900242bfda291399fd6a0900cb0b7745d7c150a27b692ddf047a6bc2b5bd20aefcb38a9550d45beef2ebb0000000000000000000000000000000004eb54c19ed6a4ba9be94d17fa361dd677c5e9c0ac27f15f3da745cc9245ca5114570a8a44570d643ca6fec24c5a8e9a0000000000000000000000000000000001fbd43e2c73b106c9e59ba823a264d5926addf6988e2cc97847bad292359cf77702597c9df33b0251f328da8f209cc0", + "000000000000000000000000000000001557006e7c861c31d73400a9eda26c9bdf064756f557688d65fc6d5655053457db932c4d3db10407a4ae592047ff842d0000000000000000000000000000000019cca0f57689d18ce2161e0930274f6cdf3f6a71f10070e7257a0698e5a9b5d384f52623bbbbdb540d3e9a64c10e921b000000000000000000000000000000000a61fb9a3484336cf570943a7bf1edddd02b73d736cd11fd6032c2fab8194781126d62f4bf23f5dd2c1bbb71659f2b500000000000000000000000000000000017b2533e34dcc2d571b34068b6d3195d15436efa3848d66b108060b5d15e5f285fc22a4aa323a2e3813c82f78dd4cacb", + "0000000000000000000000000000000014a079a52523718313ba0ea828e16f1f7fc053ffd40359e583672b81253ba4e0ce2ee25ff8682bff102780a81f1f5eea00000000000000000000000000000000127944d2093486199de71b90ef794c172eeb1096d0f1690d7338424d96acdfbaac3733c937359e48204860d744778de6000000000000000000000000000000000735d8a013b801883de71f0b942cb138c0ad8a7372412c5c364a1f952664ad3589621021a23a0fe1c961f428d527b53f0000000000000000000000000000000015536982fda409e63704a7b3cf623bfca1bdaf462e906085acded40f299d37ac4614622781310aa1afd82066fdb7beb0", + "000000000000000000000000000000000d0f91fedd8bf219e9abec47875720b58cf95b022bf4eee856df2a0e6fb07504d7ebc9685fe5a95318004833b7f616800000000000000000000000000000000014c82ce968273fc7873cfa4e41ef9933ae3608d2aeb4a278243338022d870b63c65d0f3ee5b434a96a366099f78aa2fb00000000000000000000000000000000198ae019725ab641f7b8b3e24f69d72132a3c90f45708b27b7346ac8949f7d7bb3ae986e7e2c718b58bd79e99143a8ef00000000000000000000000000000000056374901ba836eff22b7c24587e62831e3a088b46f921107598a3f94509b13f6776250f6d011e14d1566cb3e641f22b", + "000000000000000000000000000000000b469b60961ff21ba768adb10a2a64e4782a3ac7e703a7637259a51781308ff6d2837c9fd28be2975ba4211a60a0d88e000000000000000000000000000000000dbe8ca42b9596dd0657d415eb6321c7d32c0e475d97cf25672bb97f3ec375d90d57ae078d3777f279eee381bd66e6b50000000000000000000000000000000007b31b123718b7f235fcee6a78f7a130d4f5d03c22f4869438ff0fb3806c7aecbdce535db9c8b61bf48b3c550fc9404c0000000000000000000000000000000002d982b4bf793d6da748b9a6adee65a7fa093e4175a53c763f2e23dd1fff051e0488fe987887dbd45b194353513898a1", + "0000000000000000000000000000000010b07b05683f03aa5c03681cb0726f72d43e2653d0e1c9538811f6b858755ff9b680f146c573c21a953c753c1519e10f0000000000000000000000000000000018df2ce2418f296e147059ac69b26834a07595ef62d94506b0b7b7b58457e740089cdb6fa7a52e945b6ce28133392779000000000000000000000000000000000aba7561bd4db53d4f5f1f0dcb943ac841604f786712b257dda889962f2e85c55a97410d13bb115409b014927f1e19d70000000000000000000000000000000014f72efe6f6c259c8adecee7027b1707cd141d1507dd266b7e2e7bb287a5f0b71f8decaa1697adee1bf51cf1c4558181", + "000000000000000000000000000000000e0faba97d411f80e2e3b9a6d39d7f8501f2043b3eb8649128f21c530d976ff865b5ff3f5f691a0437b611427de5ec4e000000000000000000000000000000000d65fc0c62ed95528f08997c3b9ec5bbd81cd8bc66d2a9d3090719f851a144165b54ab6e7b8a619a1286fefc856fdd4c0000000000000000000000000000000007422cfcdcb04bf8863d005dd88856ff639e2b94985c0804fc20a939ad70c263d91a45706df9d9c6d7a5b18f801fcafb0000000000000000000000000000000017ca5d23734591abc516172fff615b87e219b478b8d8e64e316ca71a2c64c66f9a526cf7e4a4a63873ca94e63d82cd29", + "000000000000000000000000000000000bd718cd80fe3a576c196b42c5ed99311d32cfed42d66d3a084c719215359d0654dc18bd56a23db6a7fadf9fb08187b10000000000000000000000000000000003b20b43a55669e51f34aac5f1c9c93a8b9f93c3b16ccdb11026fa2fb637ade15bd96b256703454a1c50a8856764f7d30000000000000000000000000000000000545144715836136b237cd5b1355946208c60d2ab03e0db14ed6d0098d14c985d198a65556d71d87a9d5593093259a90000000000000000000000000000000012d88272dc634dd86c47edf10c84c5482063bc9bc194f9cfce16bb75b54338cb3e68bd63ade2e65013513fc827700b6e", + "0000000000000000000000000000000014862df8fb650ae94f6f642b9b494f89dd7adf12e41ae73775ec65e53239eae2f9025340bee6e673071275f215779e160000000000000000000000000000000003170cd693576ec1af09e1b5ef5197a23c83de1d123bf8dd61811a5cb86e251c907154c1e97783ef52812caefb3bb58b000000000000000000000000000000001002d75b4532d5cb5b8d86de02516f80b901290e1143ea098ffd8a1e1a8332f7dc716db3ef22e639e3d01592599abd82000000000000000000000000000000001666c5981bf1de72590e79e0563421e851d404825aeb4b02c12dff618945250affeb42138a6e383b2804abcd586cdd3f", + "0000000000000000000000000000000013be6288dc1ec813dcb80a244c2701cbe65af0185fc5a9fe479979f97ed25805fa6a5e0f9cd1644df8d03288daa24475000000000000000000000000000000001822963965705a42d91ff958bb6a23162b560d3dfbf43b165bfc679dfd765093497e7695e3201e89867b414782e47cd60000000000000000000000000000000019b7376b974d00abcf4a325eb93721e89005ae5b701fa14c4ee063929c6f4e37ffdc3612ec0d5287c4b19c3cb800c1f80000000000000000000000000000000018c899e91c3bd7d52ece713413e2e733be459c53d6e08b62c34140115d9ebf112ce7b1e4969f75408ac50a8f1b057064", + "000000000000000000000000000000000cac21c55ff3d3f836c684c9bd87050101ecbfbf947c1e9aabdd5b8c65643b38034372c5c29a9e31e6bddbb92759dabb00000000000000000000000000000000003da40ca1b9ff45aef983a8fac73051c5ffa5061277354391c08d9a8230eea8190286111a5798825af3d12b1d672b9d000000000000000000000000000000000cdeebb1738c02ff85d19664d1b020f4f1665f507e918584fd9a1d0547401400386426cf40079df25ef30e254d216350000000000000000000000000000000001339d03d31f99756141568b165ec6c6b19247e87c75e58a2cea15fc88f7d2be371e410e0b0eb0b1a12deab13133d13ad", + "0000000000000000000000000000000003b746c6ff13a38d21a02fa1411fd4afebe3b7feaa19d73514ae9db9d1d71209ebd3a882f9bb3d2e281398bb83a66bc5000000000000000000000000000000000d9b460577687f06263d7cb76c222b15b8935790e48b07dd567571e409495da5db324fb107b9a136f17f58660ffaf9530000000000000000000000000000000018c0a41dcb3b48eef7596342d56ca471dd2f34a1fcf44f997b2c6614b45cffc7355d71270b517d873a38a520d32c0b7100000000000000000000000000000000118d21253a52bf38a59303f3eb2c747ff951e6853fced9ecb5e4ebd969d741612d43e552067c001bd3d8630f077907b5", + "00000000000000000000000000000000009c9b846d3b8262703bcd56a584a423f2d6ea0009a242f45d60ac04146206a1fd0bf2d709cebb5276b32a34d08937af0000000000000000000000000000000014485fa2c535058ded72048ae7e3194434f6beabf94bc7048d23949a69f541c3fbfdb4270bf05e128a1d6648c9a59534000000000000000000000000000000000714427d464c715ca5720174ad15540598272fc4b9a5a0657106a4e9abe130935ebf6bce5749df1880000f06bd1922b8000000000000000000000000000000000e8916b52c09791dffb80f221d8868c2af09ace7304cd04de1c7c1a3d593d2be349c106b908e37fba49de0e72688a16d", + "00000000000000000000000000000000008ec6c01d64c02bd587df809ef7d363b415f736080bc76c6440c4fc2a32830e802907ba906c49661964927641866f22000000000000000000000000000000000e8a4da56e0d8f93b3dc6a4f0c8279208758423bfd592d8f4e911f75cf3452ef38ca771b496e26be08314e686a7524e200000000000000000000000000000000031aa3a4b68776131eb25ce44ee3e5d6703207731a5c1e4744a8af4f1e22d272dfb32ab1fa37a93f3fcb3c8cfa63626c0000000000000000000000000000000008270d9d15296d653b3e10ab4147f0a467d0f862629f9d248aefd1ad7ac318cfdcc05319da14cbe9fa475887dbef437b", + "000000000000000000000000000000000d4cf12bc66952beebf74f7720bcac085313954003e9d0b5be9bef06765e499c0f085966a42514dd42249735e1232ca8000000000000000000000000000000000b94b3dcd69b0024624d46bd3caf65a72f497a5317cfa1511c5b11b4b71d2927cd7ad08b8c9e60b81291cdf12b2e2b610000000000000000000000000000000012ae5a383c683e41ece77ecb31a33896efd6d0243b1b5d883e6d7a54f1d5a3dfcbd2257a2c5136e3e50d229854043b4600000000000000000000000000000000069dd28d9abbfe62498f362e1eadbbf92fa7cc8cc82e6c4cfaef68941e3aae3dbe62fc2105bcedb378165d50a64cbd89", + "0000000000000000000000000000000009c798c8f428a12bd81c0b98efe660c4249b2cd2fbbdefaadca483e23c7e7b0dd8a9b2c955dfb8990ba066a3252b5c1200000000000000000000000000000000039247ffd499e097ce042b0e249c6650c366c9a790f8d246271954992aa3d209b7c23962132f1f37b8ba05142312d4c70000000000000000000000000000000010d3e9a11526543ac2bea261a897a248548c4ccca19d63ef4b76d3ee323c9c68f251f01b1ed61af4cdbb1835e7afafc40000000000000000000000000000000002b778080e00200bf874dc37d40f6fa9bc111f066373a3dfde706dbb15c897b1fcac3b4bd5eff354330869f30be74296", + "0000000000000000000000000000000002353771bf8f24b6340365cd7c5fa34e1af4a6d485c6f0d2db82d5f193e649e92d952556b6ea4daf095ac0a9e4e759570000000000000000000000000000000013d62324d07334f3a5b1bf9eb09a0eed954839e43a93599852abea9b39be0d08a82364688067e1689d4457a15fc33d6c0000000000000000000000000000000015f2b988a767cd395d5d3523b93783a1fe615d89eb5b2184a25af1cb4d2b23a40756552c4f5e6a9e4cd09d6bb881791d000000000000000000000000000000000c23f17079a62bf4b73af2b7b4d39c539ab1034b113b89e56e5adf2d3c7d78e5ef1da1fd59878535b9ae56b6928cc22f", + "0000000000000000000000000000000011667822e52fb4ab060f818f9c186cf5014e7abf62ad1376bbd560630fb8ab74c6cf32dc34c258d2472f5469c1d08a760000000000000000000000000000000006520d658fed38850a9d53e40054b717c837d43ce0c7ec26d869f726e39d0f0478f1483ed50555b3277f4db14b9d707300000000000000000000000000000000147429837f309e14de5345c5cdf0b738b85159bab006cfb11d55becc4f99c45f49cf4a4dbd322ac78ef6b0903e186f080000000000000000000000000000000009d29a5195dc5825328bd84e2e01865fcb71b2da240d715032c362d68a3e22009bcf084ec6865134a0435820ac68a69b", + "000000000000000000000000000000001725a9af0c2665b1dbf421f8c219b713e7cf3605b6c263cfa514345c0b3c089efabf04c99bce50d66e76661b1fe197a1000000000000000000000000000000001789a23499b823b093a65bdf31a11c242c95c3dc20580e60724403dd4e26581a73dd14d39b0822241530b98c3bd780a8000000000000000000000000000000000def0588cadc12088d34101bbe503f4dcfe7e1ffbd1b73e8c4366634414f0e92d7c06bc1b63944bc389d9fa8091722d100000000000000000000000000000000121db986bbd7bed4ca3ce10a57b3870e06d3dd5aaef06275e8c9f646779b492a8b2710a4a80201c193f3a7bddb30fd3d", + "0000000000000000000000000000000011e5eef691643dedb64737ec9b7789b4dd882bbd0f8417a6d2d2a3ba3b4f77706883edaed7cceab0b763a0f5a1aab58700000000000000000000000000000000153052c193256204bdc57137b8e57434a051f298fa8865d4cefe79b99c19d536fa1a98a15575920df4e5def869a808f0000000000000000000000000000000000ca8c19e3b556bb24d21d9a3c86b4a22e9d75da7979e53cf60ccab3b10ee428697c468578fa5a091f996fea8b770b8730000000000000000000000000000000005c8a385229f99de9bfdfc72333acfdb1184ebf8c423ef7ff56f765c59dadac6ce879d1a3ebaf01801d525bdf001df53", + "000000000000000000000000000000001244954d9e9a61f1152d6d01f2fbe739bb15a087162560e7aeb075dc2c807883b967aa00ad9e859e9a729872ba5f4ea100000000000000000000000000000000155e743d267f2b81b0b8f632a077dbf046dd9329f7a47963828e3e4ff9a5d2ec7e6f556374ee633a0db8839b74b9f28a0000000000000000000000000000000001b0fb50e9dfb7045df383629b697f0d21cbe2ac5f20a45d8f3a427a40eb2909910cd70fa95f9f35ac2704b3a2d73f870000000000000000000000000000000015340b22b90ba30ee0266e1ce7a68be54b35244b9bf7ce83be16d5f7ecad9ec14357a2d63df7c0555c1e0eaa977fa0a0", + "00000000000000000000000000000000051b3961911aecbd714268edbc881c7461025d999c4e23c12994d676b853f2d02932f26733a4bdf306caa155a915a01a0000000000000000000000000000000015749ff11a27b093f24988c9578460acaffc376b2b7027091174e073ada104ddd56152cefbed70485b59fce651cb0b5200000000000000000000000000000000184cf9f1c1ffe553283c6b30e16c4f6ca2db7a23ae675ffef7d2b0f38c1f491dd0b5f2cbcd2c09f95ae3d9f5977aa7c5000000000000000000000000000000001002d00af1ad50c4cccadc59316dd9c246cb1ad31253d430a5dc4ab9b9a90dc9a5377345badcd367b31b9727a3fb368a", + "00000000000000000000000000000000132b08fe8d911ede6727cc3a519310527ebafb55cb616637f44187b1bae5853773d4b5bca7f58bed803a086d47a9388e0000000000000000000000000000000003be761bd2a8b89a0802c20b4dfffedd4072d699bdd7db97c17f887b5a93c0cfac9c8e57f69649879c59b060e93fe4570000000000000000000000000000000004baa66dde1c1f6500680a955a313fe79172215948989b1daf4f0859d340eef5d70328b9f94c5e5d43d86a9902b55e81000000000000000000000000000000000ce5defbb703c6510e737114194429659d53a9f4011818b5bf35ffbbb281db85f7936f84b40d5a844e2e668a26a2a0d0", + "0000000000000000000000000000000015c253e204c58e012dd3e9f232096d93588d8471e1ad461067c3ed2599d7fd77c8feb23e6f8a18bdb5777f6640b0b3570000000000000000000000000000000010b5b066f7cd958318e56c181b6777e4acdf3e50466d0a8ea3973164f0c57069a4310705112414ba3f8acef50adfe1850000000000000000000000000000000009abf68d5b5171543116c24102869c785d11344518b91c4d40d07d85d2d437fdaa5f693513c436aa92caa4317de29471000000000000000000000000000000000ee58454ba9d19e308791fac39f48a1f6569e1a842184177906e61cfe902d90c6b79ada57298ae1c57cff09c43a6921b", + "000000000000000000000000000000000a2ee22112a95fae9392643ecac169b730198e8917c86297c88cc57581b8b563216f38e27df12e4b76d82cba96a41fc70000000000000000000000000000000003bb647b0edb1d2f058c7942c14f6054317f2e1c280e56dad85a789d302de382049c913837e129957c3b2959f3723957000000000000000000000000000000000817676f2e030a451c12e9241a6ed788f0aae24a3fb9cad323169c7a956bc450cae6ce717306922090493183ef5d447900000000000000000000000000000000091db623c0815f2b9848e1d292203f6adda8ba1b6c6a7bd6bc414e53dd95f3033fd93782a95688de7a8888cd04cd02da", + }; + + @Override + public void runBenchmark( + final PrintStream output, final Boolean attemptNative, final String fork) { + + EvmSpecVersion forkVersion = EvmSpecVersion.fromName(fork); + + if (forkVersion.compareTo(EvmSpecVersion.PRAGUE) < 0) { + output.printf("EIP2537 is not available before Prague\n"); + return; + } + + if (!AbstractBLS12PrecompiledContract.isAvailable()) { + output.printf( + "BLS12-381 not available on this platform %s %s %s\n", + System.getProperty("os.name"), + System.getProperty("os.version"), + System.getProperty("os.arch")); + return; + } + + benchmarkG1Add(output); + benchmarkG1Mul(output); + benchmarkG1MultiExp32Pairs(output); + benchmarkMapFpToG1(output); + benchmarkG2Add(output); + benchmarkG2Mul(output); + benchmarkG2MultiExp32Pairs(output); + benchmarkMapFp2ToG2(output); + benchmarkBlsPairing(output); + } + + private void benchmarkG1Add(final PrintStream output) { + final Map testCases = new LinkedHashMap<>(); + for (int i = 0; i < g1PointPairs.length - 1; i++) { + testCases.put("G1 Add " + i, Bytes.fromHexString(g1PointPairs[i] + g1PointPairs[i + 1])); + } + + BLS12G1AddPrecompiledContract g1addContract = new BLS12G1AddPrecompiledContract(); + warmup = MATH_WARMUP / testCases.size(); + iterations = MATH_ITERATIONS / testCases.size(); + double execTime = Double.MIN_VALUE; // a way to dodge divide by zero + long gasCost = 0; + for (final Map.Entry testCase : testCases.entrySet()) { + execTime += runPrecompileBenchmark(testCase.getValue(), g1addContract); + gasCost += g1addContract.gasRequirement(testCase.getValue()); + } + execTime /= testCases.size(); + gasCost /= testCases.size(); + output.printf( + "Bls12 G1 Add %,6d avg gas @%,7.1f µs /%,8.1f MGps%n", + gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); + } + + private void benchmarkG1Mul(final PrintStream output) { + final Map testCases = new LinkedHashMap<>(); + for (int i = 0; i < g1PointPairs.length; i++) { + testCases.put("G1 Mul " + i, Bytes.fromHexString(g1PointPairs[i] + scalars[i])); + } + + BLS12G1MulPrecompiledContract g1addContract = new BLS12G1MulPrecompiledContract(); + warmup = MATH_WARMUP / testCases.size(); + iterations = MATH_ITERATIONS / testCases.size(); + double execTime = Double.MIN_VALUE; // a way to dodge divide by zero + long gasCost = 0; + for (final Map.Entry testCase : testCases.entrySet()) { + execTime += runPrecompileBenchmark(testCase.getValue(), g1addContract); + gasCost += g1addContract.gasRequirement(testCase.getValue()); + } + execTime /= testCases.size(); + gasCost /= testCases.size(); + output.printf( + "Bls12 G1 Mul %,6d avg gas @%,7.1f µs /%,8.1f MGps%n", + gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); + } + + private void benchmarkG1MultiExp32Pairs(final PrintStream output) { + final Map testCases = new LinkedHashMap<>(); + + // add test cases for 2, 4, 8, 16, and 32 point/scalar pairs + for (int i = 1; i <= 5; i++) { + StringBuilder g1msmPairs = new StringBuilder(); + for (int j = 0; j < 1 << i; j++) { + g1msmPairs.append(g1PointPairs[j]).append(scalars[j]); + } + testCases.put("G1 MSM, " + (1 << i) + " pairs", Bytes.fromHexString(g1msmPairs.toString())); + } + + BLS12G1MultiExpPrecompiledContract g1msmContract = new BLS12G1MultiExpPrecompiledContract(); + warmup = MATH_WARMUP / testCases.size(); + iterations = MATH_ITERATIONS / testCases.size(); + double execTime = Double.MIN_VALUE; // a way to dodge divide by zero + long gasCost = 0; + for (final Map.Entry testCase : testCases.entrySet()) { + execTime += runPrecompileBenchmark(testCase.getValue(), g1msmContract); + gasCost += g1msmContract.gasRequirement(testCase.getValue()); + } + output.printf( + "Bls12 G1 MSM %,9d total gas @%,7.1f µs /%,8.1f MGps%n", + gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); + } + + private void benchmarkMapFpToG1(final PrintStream output) { + final Map testCases = new LinkedHashMap<>(); + for (int i = 0; i < g1PointPairs.length; i++) { + testCases.put("Map Fp to G1 " + i, Bytes.fromHexString(g1PointPairs[i].substring(0, 128))); + } + + BLS12MapFpToG1PrecompiledContract g1MapFpToG1Contract = new BLS12MapFpToG1PrecompiledContract(); + warmup = MATH_WARMUP / testCases.size(); + iterations = MATH_ITERATIONS / testCases.size(); + double execTime = Double.MIN_VALUE; // a way to dodge divide by zero + long gasCost = 0; + for (final Map.Entry testCase : testCases.entrySet()) { + execTime += runPrecompileBenchmark(testCase.getValue(), g1MapFpToG1Contract); + gasCost += g1MapFpToG1Contract.gasRequirement(testCase.getValue()); + } + execTime /= testCases.size(); + gasCost /= testCases.size(); + output.printf( + "Bls12 MapFpToG1 %,6d avg gas @%,7.1f µs /%,8.1f MGps%n", + gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); + } + + private void benchmarkG2Add(final PrintStream output) { + final Map testCases = new LinkedHashMap<>(); + for (int i = 0; i < g2PointPairs.length - 1; i++) { + testCases.put("G2 Add " + i, Bytes.fromHexString(g2PointPairs[i] + g2PointPairs[i + 1])); + } + + BLS12G2AddPrecompiledContract g1addContract = new BLS12G2AddPrecompiledContract(); + warmup = MATH_WARMUP / testCases.size(); + iterations = MATH_ITERATIONS / testCases.size(); + double execTime = Double.MIN_VALUE; // a way to dodge divide by zero + long gasCost = 0; + for (final Map.Entry testCase : testCases.entrySet()) { + execTime += runPrecompileBenchmark(testCase.getValue(), g1addContract); + gasCost += g1addContract.gasRequirement(testCase.getValue()); + } + execTime /= testCases.size(); + gasCost /= testCases.size(); + output.printf( + "Bls12 G2 Add %,6d avg gas @%,7.1f µs /%,8.1f MGps%n", + gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); + } + + private void benchmarkG2Mul(final PrintStream output) { + final Map testCases = new LinkedHashMap<>(); + for (int i = 0; i < g2PointPairs.length; i++) { + testCases.put("G2 Mul " + i, Bytes.fromHexString(g2PointPairs[i] + scalars[i])); + } + + BLS12G2MulPrecompiledContract g1addContract = new BLS12G2MulPrecompiledContract(); + warmup = MATH_WARMUP / testCases.size(); + iterations = MATH_ITERATIONS / testCases.size(); + double execTime = Double.MIN_VALUE; // a way to dodge divide by zero + long gasCost = 0; + for (final Map.Entry testCase : testCases.entrySet()) { + execTime += runPrecompileBenchmark(testCase.getValue(), g1addContract); + gasCost += g1addContract.gasRequirement(testCase.getValue()); + } + execTime /= testCases.size(); + gasCost /= testCases.size(); + output.printf( + "Bls12 G2 Mul %,6d avg gas @%,7.1f µs /%,8.1f MGps%n", + gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); + } + + private void benchmarkG2MultiExp32Pairs(final PrintStream output) { + final Map testCases = new LinkedHashMap<>(); + + // add test cases for 2, 4, 8, 16, and 32 point/scalar pairs + for (int i = 1; i <= 5; i++) { + StringBuilder g2msmPairs = new StringBuilder(); + for (int j = 0; j < 1 << i; j++) { + g2msmPairs.append(g2PointPairs[j]).append(scalars[j]); + } + testCases.put("G2 MSM, " + (1 << i) + " pairs", Bytes.fromHexString(g2msmPairs.toString())); + } + + BLS12G2MultiExpPrecompiledContract g2msmContract = new BLS12G2MultiExpPrecompiledContract(); + warmup = MATH_WARMUP / testCases.size(); + iterations = MATH_ITERATIONS / testCases.size(); + double execTime = Double.MIN_VALUE; // a way to dodge divide by zero + long gasCost = 0; + for (final Map.Entry testCase : testCases.entrySet()) { + execTime += runPrecompileBenchmark(testCase.getValue(), g2msmContract); + gasCost += g2msmContract.gasRequirement(testCase.getValue()); + } + output.printf( + "Bls12 G2 MSM %,9d total gas @%,7.1f µs /%,8.1f MGps%n", + gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); + } + + private void benchmarkMapFp2ToG2(final PrintStream output) { + final Map testCases = new LinkedHashMap<>(); + for (int i = 0; i < g2PointPairs.length; i++) { + testCases.put("Map Fp2 to G2 " + i, Bytes.fromHexString(g2PointPairs[i].substring(0, 256))); + } + + BLS12MapFp2ToG2PrecompiledContract g1MapFp2ToG2Contract = + new BLS12MapFp2ToG2PrecompiledContract(); + warmup = MATH_WARMUP / testCases.size(); + iterations = MATH_ITERATIONS / testCases.size(); + double execTime = Double.MIN_VALUE; // a way to dodge divide by zero + long gasCost = 0; + for (final Map.Entry testCase : testCases.entrySet()) { + execTime += runPrecompileBenchmark(testCase.getValue(), g1MapFp2ToG2Contract); + gasCost += g1MapFp2ToG2Contract.gasRequirement(testCase.getValue()); + } + execTime /= testCases.size(); + gasCost /= testCases.size(); + output.printf( + "Bls12 MapFp2G1 %,6d avg gas @%,7.1f µs /%,8.1f MGps%n", + gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); + } + + private void benchmarkBlsPairing(final PrintStream output) { + final Map testCases = new LinkedHashMap<>(); + + // add test cases for 2, 4, 8, 16, and 32 point/scalar pairs + for (int i = 1; i <= 5; i++) { + StringBuilder pairs = new StringBuilder(); + for (int j = 0; j < 1 << i; j++) { + pairs.append(g1PointPairs[j]).append(g2PointPairs[j]); + } + testCases.put("BLS Pairing, " + (1 << i) + " pairs", Bytes.fromHexString(pairs.toString())); + } + + BLS12PairingPrecompiledContract blsPairingContract = new BLS12PairingPrecompiledContract(); + warmup = MATH_WARMUP / testCases.size(); + iterations = MATH_ITERATIONS / testCases.size(); + double execTime = Double.MIN_VALUE; // a way to dodge divide by zero + long gasCost = 0; + for (final Map.Entry testCase : testCases.entrySet()) { + execTime += runPrecompileBenchmark(testCase.getValue(), blsPairingContract); + gasCost += blsPairingContract.gasRequirement(testCase.getValue()); + } + + output.printf( + "Bls12 Pairing %,9d total gas @%,7.1f µs /%,8.1f MGps%n", + gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); + } +} diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/AbstractBLS12PrecompiledContract.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/AbstractBLS12PrecompiledContract.java index 67fecb92aa..3f0f5bc4cc 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/precompile/AbstractBLS12PrecompiledContract.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/AbstractBLS12PrecompiledContract.java @@ -67,6 +67,20 @@ public abstract class AbstractBLS12PrecompiledContract implements PrecompiledCon this.inputLimit = inputLen + 1; } + /** + * Is bls12 supported on this platform + * + * @return true if the native library was loaded. + */ + public static boolean isAvailable() { + try { + return LibGnarkEIP2537.ENABLED; + } catch (UnsatisfiedLinkError | NoClassDefFoundError ule) { + LOG.info("bls12-381 native precompile not available: {}", ule.getMessage()); + } + return false; + } + @Override public String getName() { return name; diff --git a/gradle.properties b/gradle.properties index 93f56e0137..8a4f06d6d4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,6 +4,10 @@ org.gradle.welcome=never # version=24.5.6-acme # versionappendcommit=true +# Optional, skip dependency verification for dev/debug builds +# org.gradle.dependency.verification=lenient + + # Set exports/opens flags required by Google Java Format and ErrorProne plugins. (JEP-396) org.gradle.jvmargs=-Xmx4g \ --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \ @@ -18,4 +22,4 @@ org.gradle.jvmargs=-Xmx4g \ --add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED \ --add-opens jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED # Could be moved to sonar properties after https://sonarsource.atlassian.net/browse/SONARGRADL-134 -systemProp.sonar.gradle.skipCompile=true \ No newline at end of file +systemProp.sonar.gradle.skipCompile=true From e733452205e54c73fe1ce7f6522ef41e029f79ae Mon Sep 17 00:00:00 2001 From: Matilda Clerke Date: Mon, 14 Oct 2024 08:47:21 +1100 Subject: [PATCH 3/4] 7311: Add javadoc to LabelledGauge.isLabelsObserved Signed-off-by: Matilda Clerke --- .../besu/plugin/services/metrics/LabelledGauge.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/metrics/LabelledGauge.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/metrics/LabelledGauge.java index c2f64c1113..16a2f1e59b 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/metrics/LabelledGauge.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/metrics/LabelledGauge.java @@ -26,5 +26,12 @@ public interface LabelledGauge { */ void labels(final DoubleSupplier valueSupplier, final String... labelValues); + /** + * Checks whether the supplied labelValues are already observed by this LabelledGauge + * + * @param labelValues The labelValues to check + * @return true if the supplied labelValues are already observed by this LabelledGauge, false + * otherwise + */ boolean isLabelsObserved(final String... labelValues); } From b3a252be4337b160d35b883952b228420dbbfc55 Mon Sep 17 00:00:00 2001 From: Matilda Clerke Date: Mon, 14 Oct 2024 08:53:23 +1100 Subject: [PATCH 4/4] 7311: Update plugin-api hash Signed-off-by: Matilda Clerke --- plugin-api/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle index 0b44097b90..5d2d28d196 100644 --- a/plugin-api/build.gradle +++ b/plugin-api/build.gradle @@ -71,7 +71,7 @@ Calculated : ${currentHash} tasks.register('checkAPIChanges', FileStateChecker) { description = "Checks that the API for the Plugin-API project does not change without deliberate thought" files = sourceSets.main.allJava.files - knownHash = 'LBcFfNI00D9oKdnuLo2t5sXZZXfYZQSDB/t58U0PmgI=' + knownHash = 'VN2JB2HPpEUDQaDvd7QcMkmmgedasVChfA8tnSf1GHU=' } check.dependsOn('checkAPIChanges')