Merge branch 'main' into zkbesu

# Conflicts:
#	.github/workflows/sonarcloud.yml
#	build.gradle
This commit is contained in:
Fabio Di Fabio
2024-10-08 17:16:51 +02:00
22 changed files with 560 additions and 234 deletions

View File

@@ -18,7 +18,8 @@
- Add configuration of Consolidation Request Contract Address via genesis configuration [#7647](https://github.com/hyperledger/besu/pull/7647)
- Interrupt pending transaction processing on block creation timeout [#7673](https://github.com/hyperledger/besu/pull/7673)
- Align gas cap calculation for transaction simulation to Geth approach [#7703](https://github.com/hyperledger/besu/pull/7703)
- Expose chainId in the `BlockchainService` [#7702](https://github.com/hyperledger/besu/pull/7702)
- Expose chainId in the `BlockchainService` [7702](https://github.com/hyperledger/besu/pull/7702)
- Use head block instead of safe block for snap sync [7536](https://github.com/hyperledger/besu/issues/7536)
- Add support for `chainId` in `CallParameters` [#7720](https://github.com/hyperledger/besu/pull/7720)
### Bug fixes

View File

@@ -2701,7 +2701,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
builder
.setDataStorage(dataStorageOptions.normalizeDataStorageFormat())
.setSyncMode(syncMode.normalize());
.setSyncMode(syncMode.normalize())
.setSyncMinPeers(syncMinPeerCount);
if (jsonRpcConfiguration != null && jsonRpcConfiguration.isEnabled()) {
builder
@@ -2738,6 +2739,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
builder.setSnapServerEnabled(this.unstableSynchronizerOptions.isSnapsyncServerEnabled());
builder.setSnapSyncBftEnabled(this.unstableSynchronizerOptions.isSnapSyncBftEnabled());
builder.setSnapSyncToHeadEnabled(this.unstableSynchronizerOptions.isSnapSyncToHeadEnabled());
builder.setTxPoolImplementation(buildTransactionPoolConfiguration().getTxPoolImplementation());
builder.setWorldStateUpdateMode(unstableEvmOptions.toDomainObject().worldUpdaterMode());

View File

@@ -46,6 +46,7 @@ public class ConfigurationOverviewBuilder {
private String customGenesisFileName;
private String dataStorage;
private String syncMode;
private Integer syncMinPeers;
private Integer rpcPort;
private Collection<String> rpcHttpApis;
private Integer enginePort;
@@ -57,6 +58,7 @@ public class ConfigurationOverviewBuilder {
private Integer trieLogsPruningWindowSize = null;
private boolean isSnapServerEnabled = false;
private boolean isSnapSyncBftEnabled = false;
private boolean isSnapSyncToHeadEnabled = true;
private TransactionPoolConfiguration.Implementation txPoolImplementation;
private EvmConfiguration.WorldUpdaterMode worldStateUpdateMode;
private Map<String, String> environment;
@@ -148,6 +150,17 @@ public class ConfigurationOverviewBuilder {
return this;
}
/**
* Sets sync min peers.
*
* @param syncMinPeers number of min peers for sync
* @return the builder
*/
public ConfigurationOverviewBuilder setSyncMinPeers(final int syncMinPeers) {
this.syncMinPeers = syncMinPeers;
return this;
}
/**
* Sets rpc port.
*
@@ -245,6 +258,18 @@ public class ConfigurationOverviewBuilder {
return this;
}
/**
* Sets snap sync to head enabled/disabled
*
* @param snapSyncToHeadEnabled bool to indicate if snap sync to head is enabled
* @return the builder
*/
public ConfigurationOverviewBuilder setSnapSyncToHeadEnabled(
final boolean snapSyncToHeadEnabled) {
isSnapSyncToHeadEnabled = snapSyncToHeadEnabled;
return this;
}
/**
* Sets trie logs pruning window size
*
@@ -340,6 +365,10 @@ public class ConfigurationOverviewBuilder {
lines.add("Sync mode: " + syncMode);
}
if (syncMinPeers != null) {
lines.add("Sync min peers: " + syncMinPeers);
}
if (rpcHttpApis != null) {
lines.add("RPC HTTP APIs: " + String.join(",", rpcHttpApis));
}
@@ -373,6 +402,10 @@ public class ConfigurationOverviewBuilder {
lines.add("Experimental Snap Sync for BFT enabled");
}
if (isSnapSyncToHeadEnabled) {
lines.add("Snap Sync to Head enabled");
}
if (isBonsaiLimitTrieLogsEnabled) {
final StringBuilder trieLogPruningString = new StringBuilder();
trieLogPruningString

View File

@@ -15,6 +15,7 @@
package org.hyperledger.besu.cli.options.stable;
import static java.util.Arrays.asList;
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration.DEFAULT_JSON_RPC_HOST;
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration.DEFAULT_JSON_RPC_PORT;
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration.DEFAULT_PRETTY_JSON_ENABLED;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.DEFAULT_RPC_APIS;
@@ -65,7 +66,7 @@ public class JsonRpcHttpOptions {
paramLabel = DefaultCommandValues.MANDATORY_HOST_FORMAT_HELP,
description = "Host for JSON-RPC HTTP to listen on (default: ${DEFAULT-VALUE})",
arity = "1")
private String rpcHttpHost;
private String rpcHttpHost = DEFAULT_JSON_RPC_HOST;
@CommandLine.Option(
names = {"--rpc-http-port"},

View File

@@ -87,6 +87,8 @@ public class SynchronizerOptions implements CLIOptions<SynchronizerConfiguration
private static final String SNAP_SYNC_BFT_ENABLED_FLAG = "--Xsnapsync-bft-enabled";
private static final String SNAP_SYNC_TO_HEAD_ENABLED_FLAG = "--Xsnapsync-to-head-enabled";
/**
* Parse block propagation range.
*
@@ -314,6 +316,15 @@ public class SynchronizerOptions implements CLIOptions<SynchronizerConfiguration
description = "Snap sync enabled for BFT chains (default: ${DEFAULT-VALUE})")
private Boolean snapsyncBftEnabled = SnapSyncConfiguration.DEFAULT_SNAP_SYNC_BFT_ENABLED;
@CommandLine.Option(
names = SNAP_SYNC_TO_HEAD_ENABLED_FLAG,
hidden = true,
paramLabel = "<Boolean>",
arity = "0..1",
description = "Snap sync to head enabled (default: ${DEFAULT-VALUE})")
private Boolean snapsyncToHeadEnabled =
SnapSyncConfiguration.DEFAULT_SNAP_SYNC_TO_HEAD_ENABLED_FLAG;
@CommandLine.Option(
names = {"--Xpeertask-system-enabled"},
hidden = true,
@@ -341,6 +352,15 @@ public class SynchronizerOptions implements CLIOptions<SynchronizerConfiguration
return snapsyncBftEnabled;
}
/**
* Flag to know if Snap sync should sync to head instead of safe block
*
* @return true if snap sync should sync to head
*/
public boolean isSnapSyncToHeadEnabled() {
return snapsyncToHeadEnabled;
}
/**
* Flag to indicate whether the peer task system should be used where available
*
@@ -401,6 +421,7 @@ public class SynchronizerOptions implements CLIOptions<SynchronizerConfiguration
options.checkpointPostMergeSyncEnabled = config.isCheckpointPostMergeEnabled();
options.snapsyncServerEnabled = config.getSnapSyncConfiguration().isSnapServerEnabled();
options.snapsyncBftEnabled = config.getSnapSyncConfiguration().isSnapSyncBftEnabled();
options.snapsyncToHeadEnabled = config.getSnapSyncConfiguration().isSnapSyncToHeadEnabled();
return options;
}
@@ -434,6 +455,7 @@ public class SynchronizerOptions implements CLIOptions<SynchronizerConfiguration
.localFlatStorageCountToHealPerRequest(snapsyncFlatStorageHealedCountPerRequest)
.isSnapServerEnabled(snapsyncServerEnabled)
.isSnapSyncBftEnabled(snapsyncBftEnabled)
.isSnapSyncToHeadEnabled(snapsyncToHeadEnabled)
.build());
builder.checkpointPostMergeEnabled(checkpointPostMergeSyncEnabled);
builder.isPeerTaskSystemEnabled(isPeerTaskSystemEnabled);
@@ -493,7 +515,9 @@ public class SynchronizerOptions implements CLIOptions<SynchronizerConfiguration
SNAP_SERVER_ENABLED_FLAG,
OptionParser.format(snapsyncServerEnabled),
SNAP_SYNC_BFT_ENABLED_FLAG,
OptionParser.format(snapsyncBftEnabled));
OptionParser.format(snapsyncBftEnabled),
SNAP_SYNC_TO_HEAD_ENABLED_FLAG,
OptionParser.format(snapsyncToHeadEnabled));
return value;
}
}

View File

@@ -65,6 +65,7 @@ import org.hyperledger.besu.ethereum.eth.sync.DefaultSynchronizer;
import org.hyperledger.besu.ethereum.eth.sync.PivotBlockSelector;
import org.hyperledger.besu.ethereum.eth.sync.SyncMode;
import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
import org.hyperledger.besu.ethereum.eth.sync.fastsync.PivotSelectorFromHeadBlock;
import org.hyperledger.besu.ethereum.eth.sync.fastsync.PivotSelectorFromPeers;
import org.hyperledger.besu.ethereum.eth.sync.fastsync.PivotSelectorFromSafeBlock;
import org.hyperledger.besu.ethereum.eth.sync.fastsync.checkpoint.Checkpoint;
@@ -890,14 +891,27 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
LOG.info("Initial sync done, unsubscribe forkchoice supplier");
};
return new PivotSelectorFromSafeBlock(
protocolContext,
protocolSchedule,
ethContext,
metricsSystem,
genesisConfigOptions,
unverifiedForkchoiceSupplier,
unsubscribeForkchoiceListener);
if (syncConfig.getSnapSyncConfiguration().isSnapSyncToHeadEnabled()) {
LOG.info("Using head block for sync.");
return new PivotSelectorFromHeadBlock(
protocolContext,
protocolSchedule,
ethContext,
metricsSystem,
genesisConfigOptions,
unverifiedForkchoiceSupplier,
unsubscribeForkchoiceListener);
} else {
LOG.info("Using safe block for sync.");
return new PivotSelectorFromSafeBlock(
protocolContext,
protocolSchedule,
ethContext,
metricsSystem,
genesisConfigOptions,
unverifiedForkchoiceSupplier,
unsubscribeForkchoiceListener);
}
} else {
LOG.info("TTD difficulty is not present, creating initial sync phase for PoW");
return new PivotSelectorFromPeers(ethContext, syncConfig, syncState, metricsSystem);

View File

@@ -1029,6 +1029,12 @@ public class BesuCommandTest extends CommandTestAbstract {
assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
// rpc host should remain default ie 127.0.0.1
verify(mockRunnerBuilder).jsonRpcConfiguration(jsonRpcConfigArgumentCaptor.capture());
verify(mockRunnerBuilder).build();
assertThat(jsonRpcConfigArgumentCaptor.getValue().getHost()).isEqualTo("127.0.0.1");
}
@Test

View File

@@ -95,6 +95,16 @@ class ConfigurationOverviewBuilderTest {
assertThat(syncModeSet).contains("Sync mode: fast");
}
@Test
void setSyncMinPeers() {
final String noSyncMinPeersSet = builder.build();
assertThat(noSyncMinPeersSet).doesNotContain("Sync min peers:");
builder.setSyncMinPeers(3);
final String syncMinPeersSet = builder.build();
assertThat(syncMinPeersSet).contains("Sync min peers: 3");
}
@Test
void setRpcPort() {
final String noRpcPortSet = builder.build();

View File

@@ -45,6 +45,8 @@ import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration;
import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
import org.hyperledger.besu.ethereum.eth.sync.fastsync.PivotSelectorFromHeadBlock;
import org.hyperledger.besu.ethereum.eth.sync.fastsync.PivotSelectorFromSafeBlock;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions;
import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket;
@@ -74,12 +76,15 @@ import com.google.common.collect.Range;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
import org.apache.tuweni.units.bigints.UInt256;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.io.TempDir;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockedConstruction;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
@@ -90,7 +95,10 @@ public class MergeBesuControllerBuilderTest {
@Mock GenesisConfigFile genesisConfigFile;
@Mock GenesisConfigOptions genesisConfigOptions;
@Mock SynchronizerConfiguration synchronizerConfiguration;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
SynchronizerConfiguration synchronizerConfiguration;
@Mock EthProtocolConfiguration ethProtocolConfiguration;
@Mock CheckpointConfigOptions checkpointConfigOptions;
@@ -146,6 +154,9 @@ public class MergeBesuControllerBuilderTest {
lenient().when(synchronizerConfiguration.getDownloaderParallelism()).thenReturn(1);
lenient().when(synchronizerConfiguration.getTransactionsParallelism()).thenReturn(1);
lenient().when(synchronizerConfiguration.getComputationParallelism()).thenReturn(1);
lenient()
.when(synchronizerConfiguration.getSnapSyncConfiguration().isSnapSyncToHeadEnabled())
.thenReturn(false);
lenient()
.when(synchronizerConfiguration.getBlockPropagationRange())
@@ -291,6 +302,32 @@ public class MergeBesuControllerBuilderTest {
assertThat(mergeContext.getFinalized().get()).isEqualTo(finalizedHeader);
}
@Test
public void assertPivotSelectorFromSafeBlockIsCreated() {
MockedConstruction<PivotSelectorFromSafeBlock> mocked =
Mockito.mockConstruction(PivotSelectorFromSafeBlock.class);
lenient()
.when(synchronizerConfiguration.getSnapSyncConfiguration().isSnapSyncToHeadEnabled())
.thenReturn(false);
visitWithMockConfigs(new MergeBesuControllerBuilder()).build();
Assertions.assertEquals(1, mocked.constructed().size());
}
@Test
public void assertPivotSelectorFromHeadBlockIsCreated() {
MockedConstruction<PivotSelectorFromHeadBlock> mocked =
Mockito.mockConstruction(PivotSelectorFromHeadBlock.class);
lenient()
.when(synchronizerConfiguration.getSnapSyncConfiguration().isSnapSyncToHeadEnabled())
.thenReturn(true);
visitWithMockConfigs(new MergeBesuControllerBuilder()).build();
Assertions.assertEquals(1, mocked.constructed().size());
}
private BlockHeader finalizedBlockHeader() {
final long blockNumber = 42;
final Hash magicHash = Hash.wrap(Bytes32.leftPad(Bytes.ofUnsignedInt(42)));

View File

@@ -937,19 +937,6 @@ jacocoTestReport {
}
}
task jacocoRootReport(type: org.gradle.testing.jacoco.tasks.JacocoReport) {
additionalSourceDirs.from files(subprojects.sourceSets.main.allSource.srcDirs)
sourceDirectories.from files(subprojects.sourceSets.main.allSource.srcDirs)
classDirectories.from files(subprojects.sourceSets.main.output).asFileTree.matching { exclude 'org/hyperledger/besu/tests/acceptance/**' }
executionData.from fileTree(dir: '.', includes: ['**/jacoco/*.exec'])
reports {
xml.required = true
csv.required = true
html.destination file("build/reports/jacocoHtml")
}
onlyIf = { true }
}
// http://label-schema.org/rc1/
// using the RFC3339 format "2016-04-12T23:20:50.52Z"
def buildTime() {

View File

@@ -130,41 +130,44 @@ artifacts { testSupportArtifacts testSupportJar }
tasks.register('generateTestBlockchain') {
def srcFiles = 'src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/chain-data'
def dataPath = "$buildDir/generated/data"
def dataPath = new File("$buildDir/generated/data")
def blocksBin = "$buildDir/resources/test/org/hyperledger/besu/ethereum/api/jsonrpc/trace/chain-data/blocks.bin"
inputs.dir(srcFiles)
outputs.file(blocksBin)
dependsOn(configurations.testResourceGeneration)
dependsOn(processTestResources)
doLast {
mkdir(dataPath)
javaexec {
main = 'org.hyperledger.besu.Besu'
classpath = configurations.testResourceGeneration
args = [
"--logging=ERROR",
"--data-path=$dataPath",
"--genesis-file=$srcFiles/genesis.json",
"blocks",
"import",
"--format=JSON",
"--from=$srcFiles/blocks.json",
"--start-time=1438269971"
]
}
javaexec {
main = 'org.hyperledger.besu.Besu'
classpath = configurations.testResourceGeneration
args = [
"--logging=ERROR",
"--data-path=$dataPath",
"--genesis-file=$srcFiles/genesis.json",
"blocks",
"export",
"--format=RLP",
"--start-block=0",
"--to=$blocksBin"
]
if(!dataPath.exists()) {
mkdir(dataPath)
javaexec {
main = 'org.hyperledger.besu.Besu'
classpath = configurations.testResourceGeneration
args = [
"--logging=ERROR",
"--data-path=$dataPath",
"--genesis-file=$srcFiles/genesis.json",
"blocks",
"import",
"--format=JSON",
"--from=$srcFiles/blocks.json",
"--start-time=1438269971"
]
}
javaexec {
main = 'org.hyperledger.besu.Besu'
classpath = configurations.testResourceGeneration
args = [
"--logging=ERROR",
"--data-path=$dataPath",
"--genesis-file=$srcFiles/genesis.json",
"blocks",
"export",
"--format=RLP",
"--start-block=0",
"--to=$blocksBin"
]
}
}
}
}

View File

@@ -32,7 +32,7 @@ import java.util.Optional;
import com.google.common.base.MoreObjects;
public class JsonRpcConfiguration {
private static final String DEFAULT_JSON_RPC_HOST = "127.0.0.1";
public static final String DEFAULT_JSON_RPC_HOST = "127.0.0.1";
public static final int DEFAULT_JSON_RPC_PORT = 8545;
public static final int DEFAULT_ENGINE_JSON_RPC_PORT = 8551;
public static final int DEFAULT_MAX_ACTIVE_CONNECTIONS = 80;

View File

@@ -0,0 +1,167 @@
/*
* 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.ethereum.eth.sync.fastsync;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.consensus.merge.ForkchoiceEvent;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.eth.manager.EthContext;
import org.hyperledger.besu.ethereum.eth.manager.task.WaitForPeersTask;
import org.hyperledger.besu.ethereum.eth.sync.PivotBlockSelector;
import org.hyperledger.besu.ethereum.eth.sync.tasks.RetryingGetHeaderFromPeerByHashTask;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class PivotSelectorFromBlock implements PivotBlockSelector {
private static final Logger LOG = LoggerFactory.getLogger(PivotSelectorFromBlock.class);
private final ProtocolContext protocolContext;
private final ProtocolSchedule protocolSchedule;
private final EthContext ethContext;
private final MetricsSystem metricsSystem;
private final GenesisConfigOptions genesisConfig;
private final Supplier<Optional<ForkchoiceEvent>> forkchoiceStateSupplier;
private final Runnable cleanupAction;
private long lastNoFcuReceivedInfoLog = System.currentTimeMillis();
private static final long NO_FCU_RECEIVED_LOGGING_THRESHOLD = 60000L;
private volatile Optional<BlockHeader> maybeCachedHeadBlockHeader = Optional.empty();
public PivotSelectorFromBlock(
final ProtocolContext protocolContext,
final ProtocolSchedule protocolSchedule,
final EthContext ethContext,
final MetricsSystem metricsSystem,
final GenesisConfigOptions genesisConfig,
final Supplier<Optional<ForkchoiceEvent>> forkchoiceStateSupplier,
final Runnable cleanupAction) {
this.protocolContext = protocolContext;
this.protocolSchedule = protocolSchedule;
this.ethContext = ethContext;
this.metricsSystem = metricsSystem;
this.genesisConfig = genesisConfig;
this.forkchoiceStateSupplier = forkchoiceStateSupplier;
this.cleanupAction = cleanupAction;
}
@Override
public CompletableFuture<Void> prepareRetry() {
// nothing to do
return CompletableFuture.completedFuture(null);
}
@Override
public void close() {
cleanupAction.run();
}
@Override
public long getMinRequiredBlockNumber() {
return genesisConfig.getTerminalBlockNumber().orElse(0L);
}
@Override
public long getBestChainHeight() {
final long localChainHeight = protocolContext.getBlockchain().getChainHeadBlockNumber();
return Math.max(
forkchoiceStateSupplier
.get()
.map(ForkchoiceEvent::getHeadBlockHash)
.map(
headBlockHash ->
maybeCachedHeadBlockHeader
.filter(
cachedBlockHeader -> cachedBlockHeader.getHash().equals(headBlockHash))
.map(BlockHeader::getNumber)
.orElseGet(
() -> {
LOG.debug(
"Downloading chain head block header by hash {}", headBlockHash);
try {
return waitForPeers(1)
.thenCompose(unused -> downloadBlockHeader(headBlockHash))
.thenApply(
blockHeader -> {
maybeCachedHeadBlockHeader = Optional.of(blockHeader);
return blockHeader.getNumber();
})
.get(20, TimeUnit.SECONDS);
} catch (Throwable t) {
LOG.debug(
"Error trying to download chain head block header by hash {}",
headBlockHash,
t);
}
return null;
}))
.orElse(0L),
localChainHeight);
}
@Override
public Optional<FastSyncState> selectNewPivotBlock() {
final Optional<ForkchoiceEvent> maybeForkchoice = forkchoiceStateSupplier.get();
if (maybeForkchoice.isPresent()) {
Optional<Hash> pivotHash = getPivotHash(maybeForkchoice.get());
if (pivotHash.isPresent()) {
LOG.info("Selecting new pivot block: {}", pivotHash);
return Optional.of(new FastSyncState(pivotHash.get()));
}
}
if (lastNoFcuReceivedInfoLog + NO_FCU_RECEIVED_LOGGING_THRESHOLD < System.currentTimeMillis()) {
lastNoFcuReceivedInfoLog = System.currentTimeMillis();
LOG.info(
"Waiting for consensus client, this may be because your consensus client is still syncing");
}
LOG.debug("No finalized block hash announced yet");
return Optional.empty();
}
private CompletableFuture<BlockHeader> downloadBlockHeader(final Hash hash) {
return RetryingGetHeaderFromPeerByHashTask.byHash(
protocolSchedule, ethContext, hash, 0, metricsSystem)
.getHeader()
.whenComplete(
(blockHeader, throwable) -> {
if (throwable != null) {
LOG.debug("Error downloading block header by hash {}", hash);
} else {
LOG.atDebug()
.setMessage("Successfully downloaded pivot block header by hash {}")
.addArgument(blockHeader::toLogString)
.log();
}
});
}
private CompletableFuture<Void> waitForPeers(final int count) {
final WaitForPeersTask waitForPeersTask =
WaitForPeersTask.create(ethContext, count, metricsSystem);
return waitForPeersTask.run();
}
protected abstract Optional<Hash> getPivotHash(final ForkchoiceEvent forkchoiceEvent);
}

View File

@@ -0,0 +1,58 @@
/*
* 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.ethereum.eth.sync.fastsync;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.consensus.merge.ForkchoiceEvent;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.eth.manager.EthContext;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import java.util.Optional;
import java.util.function.Supplier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PivotSelectorFromHeadBlock extends PivotSelectorFromBlock {
private static final Logger LOG = LoggerFactory.getLogger(PivotSelectorFromHeadBlock.class);
public PivotSelectorFromHeadBlock(
final ProtocolContext protocolContext,
final ProtocolSchedule protocolSchedule,
final EthContext ethContext,
final MetricsSystem metricsSystem,
final GenesisConfigOptions genesisConfig,
final Supplier<Optional<ForkchoiceEvent>> forkchoiceStateSupplier,
final Runnable cleanupAction) {
super(
protocolContext,
protocolSchedule,
ethContext,
metricsSystem,
genesisConfig,
forkchoiceStateSupplier,
cleanupAction);
}
@Override
protected Optional<Hash> getPivotHash(final ForkchoiceEvent forkchoiceEvent) {
Hash hash = forkchoiceEvent.getHeadBlockHash();
LOG.info("Returning head block hash {} as pivot", hash);
return Optional.of(hash);
}
}

View File

@@ -18,36 +18,18 @@ import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.consensus.merge.ForkchoiceEvent;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.eth.manager.EthContext;
import org.hyperledger.besu.ethereum.eth.manager.task.WaitForPeersTask;
import org.hyperledger.besu.ethereum.eth.sync.PivotBlockSelector;
import org.hyperledger.besu.ethereum.eth.sync.tasks.RetryingGetHeaderFromPeerByHashTask;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PivotSelectorFromSafeBlock implements PivotBlockSelector {
public class PivotSelectorFromSafeBlock extends PivotSelectorFromBlock {
private static final Logger LOG = LoggerFactory.getLogger(PivotSelectorFromSafeBlock.class);
private final ProtocolContext protocolContext;
private final ProtocolSchedule protocolSchedule;
private final EthContext ethContext;
private final MetricsSystem metricsSystem;
private final GenesisConfigOptions genesisConfig;
private final Supplier<Optional<ForkchoiceEvent>> forkchoiceStateSupplier;
private final Runnable cleanupAction;
private long lastNoFcuReceivedInfoLog = System.currentTimeMillis();
private static final long NO_FCU_RECEIVED_LOGGING_THRESHOLD = 60000L;
private volatile Optional<BlockHeader> maybeCachedHeadBlockHeader = Optional.empty();
public PivotSelectorFromSafeBlock(
final ProtocolContext protocolContext,
@@ -57,111 +39,25 @@ public class PivotSelectorFromSafeBlock implements PivotBlockSelector {
final GenesisConfigOptions genesisConfig,
final Supplier<Optional<ForkchoiceEvent>> forkchoiceStateSupplier,
final Runnable cleanupAction) {
this.protocolContext = protocolContext;
this.protocolSchedule = protocolSchedule;
this.ethContext = ethContext;
this.metricsSystem = metricsSystem;
this.genesisConfig = genesisConfig;
this.forkchoiceStateSupplier = forkchoiceStateSupplier;
this.cleanupAction = cleanupAction;
super(
protocolContext,
protocolSchedule,
ethContext,
metricsSystem,
genesisConfig,
forkchoiceStateSupplier,
cleanupAction);
}
@Override
public Optional<FastSyncState> selectNewPivotBlock() {
final Optional<ForkchoiceEvent> maybeForkchoice = forkchoiceStateSupplier.get();
if (maybeForkchoice.isPresent() && maybeForkchoice.get().hasValidSafeBlockHash()) {
return Optional.of(selectLastSafeBlockAsPivot(maybeForkchoice.get().getSafeBlockHash()));
protected Optional<Hash> getPivotHash(final ForkchoiceEvent forkchoiceEvent) {
if (forkchoiceEvent.hasValidSafeBlockHash()) {
Hash hash = forkchoiceEvent.getSafeBlockHash();
LOG.debug("Returning safe block hash {} as pivot.", hash);
return Optional.of(hash);
} else {
LOG.debug("No safe block hash found.");
return Optional.empty();
}
if (lastNoFcuReceivedInfoLog + NO_FCU_RECEIVED_LOGGING_THRESHOLD < System.currentTimeMillis()) {
lastNoFcuReceivedInfoLog = System.currentTimeMillis();
LOG.info(
"Waiting for consensus client, this may be because your consensus client is still syncing");
}
LOG.debug("No finalized block hash announced yet");
return Optional.empty();
}
@Override
public CompletableFuture<Void> prepareRetry() {
// nothing to do
return CompletableFuture.completedFuture(null);
}
private FastSyncState selectLastSafeBlockAsPivot(final Hash safeHash) {
LOG.debug("Returning safe block hash {} as pivot", safeHash);
return new FastSyncState(safeHash);
}
@Override
public void close() {
cleanupAction.run();
}
@Override
public long getMinRequiredBlockNumber() {
return genesisConfig.getTerminalBlockNumber().orElse(0L);
}
@Override
public long getBestChainHeight() {
final long localChainHeight = protocolContext.getBlockchain().getChainHeadBlockNumber();
return Math.max(
forkchoiceStateSupplier
.get()
.map(ForkchoiceEvent::getHeadBlockHash)
.map(
headBlockHash ->
maybeCachedHeadBlockHeader
.filter(
cachedBlockHeader -> cachedBlockHeader.getHash().equals(headBlockHash))
.map(BlockHeader::getNumber)
.orElseGet(
() -> {
LOG.debug(
"Downloading chain head block header by hash {}", headBlockHash);
try {
return waitForPeers(1)
.thenCompose(unused -> downloadBlockHeader(headBlockHash))
.thenApply(
blockHeader -> {
maybeCachedHeadBlockHeader = Optional.of(blockHeader);
return blockHeader.getNumber();
})
.get(20, TimeUnit.SECONDS);
} catch (Throwable t) {
LOG.debug(
"Error trying to download chain head block header by hash {}",
headBlockHash,
t);
}
return null;
}))
.orElse(0L),
localChainHeight);
}
private CompletableFuture<BlockHeader> downloadBlockHeader(final Hash hash) {
return RetryingGetHeaderFromPeerByHashTask.byHash(
protocolSchedule, ethContext, hash, 0, metricsSystem)
.getHeader()
.whenComplete(
(blockHeader, throwable) -> {
if (throwable != null) {
LOG.debug("Error downloading block header by hash {}", hash);
} else {
LOG.atDebug()
.setMessage("Successfully downloaded pivot block header by hash {}")
.addArgument(blockHeader::toLogString)
.log();
}
});
}
private CompletableFuture<Void> waitForPeers(final int count) {
final WaitForPeersTask waitForPeersTask =
WaitForPeersTask.create(ethContext, count, metricsSystem);
return waitForPeersTask.run();
}
}

View File

@@ -47,6 +47,7 @@ public class SyncTargetManager extends AbstractSyncTargetManager {
private static final int LOG_INFO_REPEAT_DELAY = 120;
private static final int SECONDS_PER_REQUEST = 6; // 5s per request + 1s wait between retries
private final SynchronizerConfiguration config;
private final WorldStateStorageCoordinator worldStateStorageCoordinator;
private final ProtocolSchedule protocolSchedule;
private final ProtocolContext protocolContext;
@@ -65,6 +66,7 @@ public class SyncTargetManager extends AbstractSyncTargetManager {
final MetricsSystem metricsSystem,
final FastSyncState fastSyncState) {
super(config, protocolSchedule, protocolContext, ethContext, metricsSystem);
this.config = config;
this.worldStateStorageCoordinator = worldStateStorageCoordinator;
this.protocolSchedule = protocolSchedule;
this.protocolContext = protocolContext;
@@ -82,15 +84,17 @@ public class SyncTargetManager extends AbstractSyncTargetManager {
throttledLog(
LOG::debug,
String.format(
"Unable to find sync target. Currently checking %d peers for usefulness. Pivot block: %d",
ethContext.getEthPeers().peerCount(), pivotBlockHeader.getNumber()),
"Unable to find sync target. Waiting for %d peers minimum. Currently checking %d peers for usefulness. Pivot block: %d",
config.getSyncMinimumPeerCount(),
ethContext.getEthPeers().peerCount(),
pivotBlockHeader.getNumber()),
logDebug,
LOG_DEBUG_REPEAT_DELAY);
throttledLog(
LOG::info,
String.format(
"Unable to find sync target. Currently checking %d peers for usefulness.",
ethContext.getEthPeers().peerCount()),
"Unable to find sync target. Waiting for %d peers minimum. Currently checking %d peers for usefulness.",
config.getSyncMinimumPeerCount(), ethContext.getEthPeers().peerCount()),
logInfo,
LOG_INFO_REPEAT_DELAY);
return completedFuture(Optional.empty());

View File

@@ -37,6 +37,7 @@ import org.slf4j.LoggerFactory;
class FullSyncTargetManager extends AbstractSyncTargetManager {
private static final Logger LOG = LoggerFactory.getLogger(FullSyncTargetManager.class);
private final SynchronizerConfiguration config;
private final ProtocolContext protocolContext;
private final EthContext ethContext;
private final SyncTerminationCondition terminationCondition;
@@ -49,6 +50,7 @@ class FullSyncTargetManager extends AbstractSyncTargetManager {
final MetricsSystem metricsSystem,
final SyncTerminationCondition terminationCondition) {
super(config, protocolSchedule, protocolContext, ethContext, metricsSystem);
this.config = config;
this.protocolContext = protocolContext;
this.ethContext = ethContext;
this.terminationCondition = terminationCondition;
@@ -77,7 +79,8 @@ class FullSyncTargetManager extends AbstractSyncTargetManager {
final Optional<EthPeer> maybeBestPeer = ethContext.getEthPeers().bestPeerWithHeightEstimate();
if (!maybeBestPeer.isPresent()) {
LOG.info(
"Unable to find sync target. Currently checking {} peers for usefulness",
"Unable to find sync target. Waiting for {} peers minimum. Currently checking {} peers for usefulness",
config.getSyncMinimumPeerCount(),
ethContext.getEthPeers().peerCount());
return completedFuture(Optional.empty());
} else {

View File

@@ -40,6 +40,8 @@ public class SnapSyncConfiguration {
public static final Boolean DEFAULT_SNAP_SYNC_BFT_ENABLED = Boolean.FALSE;
public static final Boolean DEFAULT_SNAP_SYNC_TO_HEAD_ENABLED_FLAG = Boolean.TRUE;
public static SnapSyncConfiguration getDefault() {
return ImmutableSnapSyncConfiguration.builder().build();
}
@@ -88,4 +90,9 @@ public class SnapSyncConfiguration {
public Boolean isSnapSyncBftEnabled() {
return DEFAULT_SNAP_SYNC_BFT_ENABLED;
}
@Value.Default
public Boolean isSnapSyncToHeadEnabled() {
return DEFAULT_SNAP_SYNC_TO_HEAD_ENABLED_FLAG;
}
}

View File

@@ -218,11 +218,13 @@ public class SnapSyncMetricsManager {
public void notifySnapSyncCompleted() {
final Duration duration = Duration.ofMillis(System.currentTimeMillis() - startSyncTime);
final long hours = (duration.toDaysPart() * 24) + duration.toHoursPart();
LOG.info(
"Finished worldstate snapsync with nodes {} (healed={}) duration {}{}:{},{}.",
nbTrieNodesGenerated.addAndGet(nbTrieNodesHealed.get()),
nbTrieNodesHealed,
duration.toHoursPart() > 0 ? (duration.toHoursPart() + ":") : "",
hours > 0 ? (hours + ":") : "",
duration.toMinutesPart(),
duration.toSecondsPart(),
duration.toMillisPart());

View File

@@ -38,6 +38,7 @@ import org.hyperledger.besu.ethereum.eth.peervalidation.PeerValidator;
import org.hyperledger.besu.ethereum.eth.sync.PivotBlockSelector;
import org.hyperledger.besu.ethereum.eth.sync.SyncMode;
import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
import org.hyperledger.besu.ethereum.eth.sync.snapsync.ImmutableSnapSyncConfiguration;
import org.hyperledger.besu.ethereum.eth.sync.state.SyncState;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator;
@@ -487,7 +488,7 @@ public class FastSyncActionsTest {
@ParameterizedTest
@ArgumentsSource(FastSyncActionsTest.FastSyncActionsTestArguments.class)
public void downloadPivotBlockHeaderShouldRetrievePivotBlockHash(
public void downloadPivotBlockHeaderShouldRetrieveSafePivotBlockHash(
final DataStorageFormat storageFormat) {
setUp(storageFormat);
syncConfig = SynchronizerConfiguration.builder().syncMinimumPeerCount(1).build();
@@ -525,6 +526,55 @@ public class FastSyncActionsTest {
assertThat(result).isCompletedWithValue(new FastSyncState(blockchain.getBlockHeader(3).get()));
}
@ParameterizedTest
@ArgumentsSource(FastSyncActionsTest.FastSyncActionsTestArguments.class)
public void downloadPivotBlockHeaderShouldRetrieveHeadPivotBlockHash(
final DataStorageFormat storageFormat) {
setUp(storageFormat);
syncConfig =
SynchronizerConfiguration.builder()
.syncMinimumPeerCount(1)
.snapSyncConfiguration(
ImmutableSnapSyncConfiguration.builder().isSnapSyncToHeadEnabled(true).build())
.build();
GenesisConfigOptions genesisConfig = mock(GenesisConfigOptions.class);
when(genesisConfig.getTerminalBlockNumber()).thenReturn(OptionalLong.of(10L));
final Optional<ForkchoiceEvent> finalizedEvent =
Optional.of(
new ForkchoiceEvent(
blockchain.getChainHeadHash(),
blockchain.getBlockHashByNumber(3L).get(),
blockchain.getBlockHashByNumber(2L).get()));
fastSyncActions =
createFastSyncActions(
syncConfig,
new PivotSelectorFromHeadBlock(
blockchainSetupUtil.getProtocolContext(),
blockchainSetupUtil.getProtocolSchedule(),
ethContext,
metricsSystem,
genesisConfig,
() -> finalizedEvent,
() -> {}));
final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1001);
final CompletableFuture<FastSyncState> result =
fastSyncActions.downloadPivotBlockHeader(
new FastSyncState(finalizedEvent.get().getHeadBlockHash()));
assertThat(result).isNotCompleted();
final RespondingEthPeer.Responder responder = RespondingEthPeer.blockchainResponder(blockchain);
peer.respond(responder);
assertThat(result)
.isCompletedWithValue(
new FastSyncState(
blockchain.getBlockHeader(blockchain.getChainHeadBlockNumber()).get()));
}
private FastSyncActions createFastSyncActions(
final SynchronizerConfiguration syncConfig, final PivotBlockSelector pivotBlockSelector) {
final ProtocolSchedule protocolSchedule = blockchainSetupUtil.getProtocolSchedule();

View File

@@ -4816,16 +4816,19 @@
<sha256 value="6d535f94efb663bdb682c9f27a50335394688009642ba7a9677504bc1be4129b" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.hyperledger.besu" name="arithmetic" version="0.9.6">
<artifact name="arithmetic-0.9.6.jar">
<sha256 value="549ead60719547fb4995bdfd60abddf64c0fb115c7262e4daa72bb49d1a02d9c" origin="Generated by Gradle"/>
</artifact>
<artifact name="arithmetic-0.9.6.module">
<sha256 value="8d997bd701f57f540b7d1b129698d075004e98cc081da6e511b79813a001b789" origin="Generated by Gradle"/>
</artifact>
<component group="org.hyperledger.besu" name="arithmetic" version="0.9.7">
<artifact name="arithmetic-0.9.6.pom">
<sha256 value="700a538eed1840ce0af27c804f42ee11e9ee69429fbc6b75ec124d7a20aaf5a4" origin="Generated by Gradle"/>
</artifact>
<artifact name="arithmetic-0.9.7.jar">
<sha256 value="54b1f4edbbc06bd974c5b3aad5acc21c85213997c8b91b051fe240f90d674f93" origin="Generated by Gradle"/>
</artifact>
<artifact name="arithmetic-0.9.7.module">
<sha256 value="96d8a26b967d7baa88d1f0916485471e94bd0938e5aafd8f7948dd48b308d48c" origin="Generated by Gradle"/>
</artifact>
<artifact name="arithmetic-0.9.7.pom">
<sha256 value="85dba02684aedda439410441c86dbb485f3fe5315f971e2dff3f021e66cc35d1" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.hyperledger.besu" name="besu-errorprone-checks" version="1.0.0">
<artifact name="besu-errorprone-checks-1.0.0.jar">
@@ -4835,71 +4838,89 @@
<sha256 value="c273525c9f23a0bd5b9cf6830b4bebd9d81e355b7f2ed3a22f23f76c2a2313d5" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.hyperledger.besu" name="blake2bf" version="0.9.6">
<artifact name="blake2bf-0.9.6.jar">
<sha256 value="33c4d366345592fb365e59b155814f665dfd43b4093b0895943ac2a4ed320617" origin="Generated by Gradle"/>
</artifact>
<artifact name="blake2bf-0.9.6.module">
<sha256 value="703e98ea5c457b5d7c09c01a2ba8ec86edd7aa83b2b61051bbb302496ca08e86" origin="Generated by Gradle"/>
</artifact>
<component group="org.hyperledger.besu" name="blake2bf" version="0.9.7">
<artifact name="blake2bf-0.9.6.pom">
<sha256 value="6434b83abf67dea2aa25530ec6444dc42d4b2cb0b61f73bc721879fd8ea06e66" origin="Generated by Gradle"/>
</artifact>
<artifact name="blake2bf-0.9.7.jar">
<sha256 value="855acac6367e185ffbc88c816888e123ef582c12e80a2bb01b920e0db2542890" origin="Generated by Gradle"/>
</artifact>
<artifact name="blake2bf-0.9.7.module">
<sha256 value="70b962c1f1c16b7bd54c5d5bcabbf5258fef3ba72973d73d1abc8fb5e11ddc25" origin="Generated by Gradle"/>
</artifact>
<artifact name="blake2bf-0.9.7.pom">
<sha256 value="57153f8f29bfa576b32f7ddc46fd51afde03cb9742a54450915ebd347f880ba0" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.hyperledger.besu" name="bls12-381" version="0.9.6">
<artifact name="bls12-381-0.9.6.jar">
<sha256 value="13e04180d2a7e640604c03491626c3824fa0345c84dadcfef381d14fb854a4ba" origin="Generated by Gradle"/>
</artifact>
<artifact name="bls12-381-0.9.6.module">
<sha256 value="3e60be55414b9ce979c53e2814ca78e05a0b4746e6e0d9a9d15056efa932d335" origin="Generated by Gradle"/>
</artifact>
<component group="org.hyperledger.besu" name="bls12-381" version="0.9.7">
<artifact name="bls12-381-0.9.6.pom">
<sha256 value="7448bc47acc7c02e41cb19a7464ea4b08783088ae4a179b10efcf8f6ec6e776a" origin="Generated by Gradle"/>
</artifact>
<artifact name="bls12-381-0.9.7.jar">
<sha256 value="74ccf0160698c539f084057e3eee6f1a42ccadf570667ed06c8770b164bc972b" origin="Generated by Gradle"/>
</artifact>
<artifact name="bls12-381-0.9.7.module">
<sha256 value="e2ba91e9de0f9699e8469372bf5fdc3faef5e373e705f977a94b5c3a90b92a7e" origin="Generated by Gradle"/>
</artifact>
<artifact name="bls12-381-0.9.7.pom">
<sha256 value="5d432385cdbe0fe272fdf5d9ef3426fbf4aebb924fddab1a9c7f7a59588d658d" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.hyperledger.besu" name="gnark" version="0.9.6">
<artifact name="gnark-0.9.6.jar">
<sha256 value="284c025cb35fe76690d8e3cb7b35d6ae6a8523f5e0f65b9c8d6e7368d880d741" origin="Generated by Gradle"/>
</artifact>
<artifact name="gnark-0.9.6.module">
<sha256 value="63ca5d2c03f7ce22105d2f6818b8c39b2feaee1088f82fb3667713b4503a852f" origin="Generated by Gradle"/>
</artifact>
<component group="org.hyperledger.besu" name="gnark" version="0.9.7">
<artifact name="gnark-0.9.6.pom">
<sha256 value="529015a3aff91112aba1a31b61372b0244ee5d3d07af98d3ef3d94b67fd9049a" origin="Generated by Gradle"/>
</artifact>
<artifact name="gnark-0.9.7.jar">
<sha256 value="fd3b4d5acd31d193b00329d935a9752f95484da8824a3f86cf5709fa9d2da846" origin="Generated by Gradle"/>
</artifact>
<artifact name="gnark-0.9.7.module">
<sha256 value="485c0d98325aedc4c66d59e52735953e66caed3937490712dd28954fabd5ef1d" origin="Generated by Gradle"/>
</artifact>
<artifact name="gnark-0.9.7.pom">
<sha256 value="c1d2759bbc27ed9d9124b193492d86e66faa7ca69c0e8299ad35f4b66af627db" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.hyperledger.besu" name="ipa-multipoint" version="0.9.6">
<artifact name="ipa-multipoint-0.9.6.jar">
<sha256 value="7fd70a8ba7cff2feb9c5308f7a276634f5b11210c63d8c2bc78ca6710ff395f8" origin="Generated by Gradle"/>
</artifact>
<artifact name="ipa-multipoint-0.9.6.module">
<sha256 value="30c3f3d567d54b23735a0abc4f7216576c4aa238fdd4a517db840eab963fe86e" origin="Generated by Gradle"/>
</artifact>
<component group="org.hyperledger.besu" name="ipa-multipoint" version="0.9.7">
<artifact name="ipa-multipoint-0.9.6.pom">
<sha256 value="e96caed06849bd0cf8a2a7d53c974d0816aa2c2192086b023385abb5f2299493" origin="Generated by Gradle"/>
</artifact>
<artifact name="ipa-multipoint-0.9.7.jar">
<sha256 value="426783770512da361b1cdbcc3c7c70b6f69fbf7b79588d39a3a1de4bcb14fc34" origin="Generated by Gradle"/>
</artifact>
<artifact name="ipa-multipoint-0.9.7.module">
<sha256 value="b7bd007ba40242c09e932dadee8271402a3cd44756cbbcec8b1cf993d3d5803a" origin="Generated by Gradle"/>
</artifact>
<artifact name="ipa-multipoint-0.9.7.pom">
<sha256 value="a390073c8d19cb9ebc9ddad36427ecbb63d6d42cde6d09671b736356aad0cd5e" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.hyperledger.besu" name="secp256k1" version="0.9.6">
<artifact name="secp256k1-0.9.6.jar">
<sha256 value="976e270dea4fb86b42b075f81ccf7cdb3f545d77608627a46cff8be7b1b8b0e4" origin="Generated by Gradle"/>
</artifact>
<artifact name="secp256k1-0.9.6.module">
<sha256 value="73dfa511badef9c334bf95d6f4b15870673bb2b7906b61fc2710a2438326a121" origin="Generated by Gradle"/>
</artifact>
<component group="org.hyperledger.besu" name="secp256k1" version="0.9.7">
<artifact name="secp256k1-0.9.6.pom">
<sha256 value="c1089bd11e8c07c320ef4c1772538292dcb2007a88401b4b2ee25d68ad8ff467" origin="Generated by Gradle"/>
</artifact>
<artifact name="secp256k1-0.9.7.jar">
<sha256 value="e3953351c5bceed7fe4ded784f69485b32ee689e27011738d0543e98af49186f" origin="Generated by Gradle"/>
</artifact>
<artifact name="secp256k1-0.9.7.module">
<sha256 value="84a037db020fe83b02d176bd7588759ca700d52959393c6d24eb99696db0ed79" origin="Generated by Gradle"/>
</artifact>
<artifact name="secp256k1-0.9.7.pom">
<sha256 value="39a5454f459e16634d65b48f68aca0129f594cf838b70c15aeccced65159674c" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.hyperledger.besu" name="secp256r1" version="0.9.6">
<artifact name="secp256r1-0.9.6.jar">
<sha256 value="97f124cd2971eb4ca43724061cc7142bd2d969f76910a1b18f6930f5c3ba2666" origin="Generated by Gradle"/>
</artifact>
<artifact name="secp256r1-0.9.6.module">
<sha256 value="173d9c3d9b3f835454a67ff258cfc200822f46750bdb917e0f247c61dd19c899" origin="Generated by Gradle"/>
</artifact>
<component group="org.hyperledger.besu" name="secp256r1" version="0.9.7">
<artifact name="secp256r1-0.9.6.pom">
<sha256 value="dad5fc99fecccbff3714cbc45c4e408a4d492780293c168bea907336bbf86f45" origin="Generated by Gradle"/>
</artifact>
<artifact name="secp256r1-0.9.7.jar">
<sha256 value="36e805e65cb8d2eece17dcdf5c785f7e1b43d5778427deb80a3c0fac04f4eb08" origin="Generated by Gradle"/>
</artifact>
<artifact name="secp256r1-0.9.7.module">
<sha256 value="7ffa9739208ede60d20703ee78342be760ccc4ca766724dabdc3410fe02b3051" origin="Generated by Gradle"/>
</artifact>
<artifact name="secp256r1-0.9.7.pom">
<sha256 value="e8083ed2c95503f7c6fbb634e47183ea48aa879d84b6fba77a8552736a3f0b82" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.immutables" name="immutables" version="2.10.1">
<artifact name="immutables-2.10.1.pom">

View File

@@ -157,7 +157,7 @@ dependencyManagement {
dependency 'org.fusesource.jansi:jansi:2.4.1'
dependencySet(group: 'org.hyperledger.besu', version: '0.9.6') {
dependencySet(group: 'org.hyperledger.besu', version: '0.9.7') {
entry 'arithmetic'
entry 'ipa-multipoint'
entry 'bls12-381'