Skip to content

Commit

Permalink
Merge branch 'main' of github.com:hyperledger/besu into MakeSnapTasks…
Browse files Browse the repository at this point in the history
…Switching
  • Loading branch information
pinges committed Jul 2, 2024
2 parents ce6c51c + 3a73dcc commit 850084e
Show file tree
Hide file tree
Showing 76 changed files with 2,136 additions and 235 deletions.
22 changes: 21 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
# Changelog

## Next Release
## Next release

### Breaking Changes

### Additions and Improvements

### Bug fixes

## 24.7.0

### Upcoming Breaking Changes
- Receipt compaction will be enabled by default in a future version of Besu. After this change it will not be possible to downgrade to the previous Besu version.
- PKI-backed QBFT will be removed in a future version of Besu. Other forms of QBFT will remain unchanged.
- --Xbonsai-limit-trie-logs-enabled is deprecated, use --bonsai-limit-trie-logs-enabled instead
- --Xbonsai-trie-logs-pruning-window-size is deprecated, use --bonsai-trie-logs-pruning-window-size instead
- `besu storage x-trie-log` subcommand is deprecated, use `besu storage trie-log` instead

### Breaking Changes
- `Xp2p-peer-lower-bound` has been removed. [#7247](https://github.com/hyperledger/besu/pull/7247)
Expand All @@ -15,13 +30,18 @@
- Update Docker base image to Ubuntu 24.04 [#7251](https://github.com/hyperledger/besu/pull/7251)
- Add LUKSO as predefined network name [#7223](https://github.com/hyperledger/besu/pull/7223)
- Refactored how code, initcode, and max stack size are configured in forks. [#7245](https://github.com/hyperledger/besu/pull/7245)
- Nodes in a permissioned chain maintain (and retry) connections to bootnodes [#7257](https://github.com/hyperledger/besu/pull/7257)
- Promote experimental `besu storage x-trie-log` subcommand to production-ready [#7278](https://github.com/hyperledger/besu/pull/7278)
- Enhanced BFT round-change diagnostics [#7271](https://github.com/hyperledger/besu/pull/7271)

### Bug fixes
- Validation errors ignored in accounts-allowlist and empty list [#7138](https://github.com/hyperledger/besu/issues/7138)
- Fix "Invalid block detected" for BFT chains using Bonsai DB [#7204](https://github.com/hyperledger/besu/pull/7204)
- Fix "Could not confirm best peer had pivot block" [#7109](https://github.com/hyperledger/besu/issues/7109)
- Fix "Chain Download Halt" [#6884](https://github.com/hyperledger/besu/issues/6884)



## 24.6.0

### Breaking Changes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,17 @@ public void setUp() {
permissionedCluster.start(bootnode, forbiddenNode, allowedNode, permissionedNode);

// updating permissioning smart contract with allowed nodes

permissionedNode.verify(nodeIsForbidden(bootnode));
permissionedNode.execute(allowNode(bootnode));
permissionedNode.verify(nodeIsAllowed(bootnode));
permissionedNode.verify(admin.hasPeer(bootnode));

permissionedNode.execute(allowNode(allowedNode));
permissionedNode.verify(nodeIsAllowed(allowedNode));

permissionedNode.execute(allowNode(permissionedNode));
permissionedNode.verify(nodeIsAllowed(permissionedNode));

permissionedNode.verify(admin.addPeer(bootnode));
permissionedNode.verify(admin.addPeer(allowedNode));

allowedNode.verify(eth.syncingStatus(false));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public void permissionedNodeShouldPeerOnlyWithAllowedNodes() {

@Test
public void permissionedNodeShouldDisconnectFromNodeNotPermittedAnymore() {
permissionedNode.verify(admin.addPeer(bootnode));
permissionedNode.verify(admin.hasPeer(bootnode));
permissionedNode.verify(admin.addPeer(allowedNode));
permissionedNode.verify(net.awaitPeerCount(2));

Expand All @@ -74,7 +74,7 @@ public void permissionedNodeShouldDisconnectFromNodeNotPermittedAnymore() {

@Test
public void permissionedNodeShouldConnectToNewlyPermittedNode() {
permissionedNode.verify(admin.addPeer(bootnode));
permissionedNode.verify(admin.hasPeer(bootnode));
permissionedNode.verify(admin.addPeer(allowedNode));
permissionedNode.verify(net.awaitPeerCount(2));

Expand All @@ -89,7 +89,7 @@ public void permissionedNodeShouldConnectToNewlyPermittedNode() {

@Test
public void permissioningUpdatesPropagateThroughNetwork() {
permissionedNode.verify(admin.addPeer(bootnode));
permissionedNode.verify(admin.hasPeer(bootnode));
permissionedNode.verify(admin.addPeer(allowedNode));
permissionedNode.verify(net.awaitPeerCount(2));

Expand Down
15 changes: 14 additions & 1 deletion besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -792,7 +792,20 @@ public Runner build() {
LOG.debug("added ethash observer: {}", stratumServer.get());
}

sanitizePeers(network, staticNodes)
final Stream<EnodeURL> maintainedPeers;
if (besuController.getGenesisConfigOptions().isPoa()) {
// In a permissioned chain Besu should maintain connections to both static nodes and
// bootnodes, which includes retries periodically
maintainedPeers =
sanitizePeers(
network,
Stream.concat(staticNodes.stream(), bootnodes.stream()).collect(Collectors.toList()));
LOG.debug("Added bootnodes to the maintained peer list");
} else {
// In a public chain only maintain connections to static nodes
maintainedPeers = sanitizePeers(network, staticNodes);
}
maintainedPeers
.map(DefaultPeer::fromEnodeURL)
.forEach(peerNetwork::addMaintainedConnectionPeer);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@

/** The Trie Log subcommand. */
@Command(
name = "x-trie-log",
name = "trie-log",
aliases = "x-trie-log",
description = "Manipulate trie logs",
mixinStandardHelpOptions = true,
versionProvider = VersionProvider.class,
Expand Down
60 changes: 57 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -365,9 +365,63 @@ allprojects {
options.addBooleanOption('Xdoclint/package:-org.hyperledger.besu.privacy.contracts.generated,' +
'-org.hyperledger.besu.tests.acceptance.*,' +
'-org.hyperledger.besu.tests.web3j.generated,' +
// TODO: these are temporary disabled (ethereum and sub modules), it should be removed in a future PR.
'-org.hyperledger.besu.ethereum.*,' +
'-org.hyperledger.besu.evmtool',
// TODO: these are temporary excluded from lint (ethereum sub modules), it should be removed in a future PR.
// ethereum api module
'-org.hyperledger.besu.ethereum.api.handlers,' +
'-org.hyperledger.besu.ethereum.api.jsonrpc,' +
'-org.hyperledger.besu.ethereum.api.jsonrpc.*,' +
'-org.hyperledger.besu.ethereum.api.query,' +
'-org.hyperledger.besu.ethereum.api.query.*,' +
'-org.hyperledger.besu.ethereum.api.tls,' +
'-org.hyperledger.besu.ethereum.api.util,' +
// ethereum blockcreation module
'-org.hyperledger.besu.ethereum.blockcreation,' +
'-org.hyperledger.besu.ethereum.blockcreation.*,' +
// ethereum core module
'-org.hyperledger.besu.ethereum.chain,' +
'-org.hyperledger.besu.ethereum.core,' +
'-org.hyperledger.besu.ethereum.core.*,' +
'-org.hyperledger.besu.ethereum.debug,' +
'-org.hyperledger.besu.ethereum.difficulty.fixed,' +
'-org.hyperledger.besu.ethereum.forkid,' +
'-org.hyperledger.besu.ethereum.mainnet,' +
'-org.hyperledger.besu.ethereum.mainnet.*,' +
'-org.hyperledger.besu.ethereum.privacy,' +
'-org.hyperledger.besu.ethereum.privacy.*,' +
'-org.hyperledger.besu.ethereum.processing,' +
'-org.hyperledger.besu.ethereum.proof,' +
'-org.hyperledger.besu.ethereum.storage,' +
'-org.hyperledger.besu.ethereum.storage.*,' +
'-org.hyperledger.besu.ethereum.transaction,' +
'-org.hyperledger.besu.ethereum.trie.*,' +
'-org.hyperledger.besu.ethereum.util,' +
'-org.hyperledger.besu.ethereum.vm,' +
'-org.hyperledger.besu.ethereum.worldstate,' +
// ethereum eth module
'-org.hyperledger.besu.ethereum.eth.*,' +
'-org.hyperledger.besu.ethereum.eth,' +
'-org.hyperledger.besu.consensus.merge,' +
// p2p module
'-org.hyperledger.besu.ethereum.p2p,' +
'-org.hyperledger.besu.ethereum.p2p.*,' +
// permissioning module
'-org.hyperledger.besu.ethereum.permissioning,' +
'-org.hyperledger.besu.ethereum.permissioning.*,' +
// referencetests module
'-org.hyperledger.besu.ethereum.referencetests,' +
// retesteth module
'-org.hyperledger.besu.ethereum.retesteth.methods,' +
'-org.hyperledger.besu.ethereum.retesteth,' +
//rlp module
'-org.hyperledger.besu.ethereum.rlp,' +
// stratum module
'-org.hyperledger.besu.ethereum.stratum,' +
// trie module
'-org.hyperledger.besu.ethereum.trie.*,' +
'-org.hyperledger.besu.ethereum.trie,' +
// verkle trie module
'-org.hyperledger.besu.ethereum.verkletrie,' +
'-org.hyperledger.besu.ethereum.verkletrie.*',
true)
options.addStringOption('Xmaxerrs','65535')
options.addStringOption('Xmaxwarns','65535')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,14 @@
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** Class for starting and keeping organised round timers */
public class RoundTimer {

private static final Logger LOG = LoggerFactory.getLogger(RoundTimer.class);

private final BftExecutors bftExecutors;
private Optional<ScheduledFuture<?>> currentTimerTask;
private final BftEventQueue queue;
Expand Down Expand Up @@ -71,6 +77,16 @@ public synchronized void startTimer(final ConsensusRoundIdentifier round) {

final ScheduledFuture<?> newTimerTask =
bftExecutors.scheduleTask(newTimerRunnable, expiryTime, TimeUnit.MILLISECONDS);

// Once we are up to round 2 start logging round expiries
if (round.getRoundNumber() >= 2) {
LOG.info(
"QBFT round {} expired. Moved to round {} which will expire in {} seconds",
round.getRoundNumber() - 1,
round.getRoundNumber(),
(expiryTime / 1000));
}

currentTimerTask = Optional.of(newTimerTask);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -274,17 +274,26 @@ private <P extends Payload, M extends BftMessage<P>> void actionOrBufferMessage(
@Override
public void handleRoundChangePayload(final RoundChange message) {
final ConsensusRoundIdentifier targetRound = message.getRoundIdentifier();
LOG.trace("Received a RoundChange Payload for {}", targetRound);

LOG.debug(
"Round change from {}: block {}, round {}",
message.getAuthor(),
message.getRoundIdentifier().getSequenceNumber(),
message.getRoundIdentifier().getRoundNumber());

// Diagnostic logging (only logs anything if the chain has stalled)
roundChangeManager.storeAndLogRoundChangeSummary(message);

final MessageAge messageAge =
determineAgeOfPayload(message.getRoundIdentifier().getRoundNumber());
if (messageAge == MessageAge.PRIOR_ROUND) {
LOG.trace("Received RoundChange Payload for a prior round. targetRound={}", targetRound);
LOG.debug("Received RoundChange Payload for a prior round. targetRound={}", targetRound);
return;
}

final Optional<Collection<RoundChange>> result =
roundChangeManager.appendRoundChangeMessage(message);

if (result.isPresent()) {
LOG.debug(
"Received sufficient RoundChange messages to change round to targetRound={}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ private BaseQbftBlockHeightManager createFullBlockHeightManager(final BlockHeade
new RoundChangeManager(
BftHelpers.calculateRequiredValidatorQuorum(finalState.getValidators().size()),
messageValidatorFactory.createRoundChangeMessageValidator(
parentHeader.getNumber() + 1L, parentHeader)),
parentHeader.getNumber() + 1L, parentHeader),
finalState.getLocalAddress()),
roundFactory,
finalState.getClock(),
messageValidatorFactory,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,19 +100,51 @@ public Collection<RoundChange> createRoundChangeCertificate() {
@VisibleForTesting
final Map<ConsensusRoundIdentifier, RoundChangeStatus> roundChangeCache = Maps.newHashMap();

/** A summary of the latest round each validator is on, for diagnostic purposes only */
private final Map<Address, ConsensusRoundIdentifier> roundSummary = Maps.newHashMap();

private final long quorum;
private final RoundChangeMessageValidator roundChangeMessageValidator;
private final Address localAddress;

/**
* Instantiates a new Round change manager.
*
* @param quorum the quorum
* @param roundChangeMessageValidator the round change message validator
* @param localAddress this node's address
*/
public RoundChangeManager(
final long quorum, final RoundChangeMessageValidator roundChangeMessageValidator) {
final long quorum,
final RoundChangeMessageValidator roundChangeMessageValidator,
final Address localAddress) {
this.quorum = quorum;
this.roundChangeMessageValidator = roundChangeMessageValidator;
this.localAddress = localAddress;
}

/**
* Store the latest round for a node, and if chain is stalled log a summary of which round each
* address is on
*
* @param message the round-change message that has just been received
*/
public void storeAndLogRoundChangeSummary(final RoundChange message) {
roundSummary.put(message.getAuthor(), message.getRoundIdentifier());
if (roundChangeCache.keySet().stream()
.findFirst()
.orElse(new ConsensusRoundIdentifier(0, 0))
.getRoundNumber()
>= 2) {
LOG.info("BFT round summary (quorum = {})", quorum);
for (Map.Entry<Address, ConsensusRoundIdentifier> nextEntry : roundSummary.entrySet()) {
LOG.info(
"Address: {} Round: {} {}",
nextEntry.getKey(),
nextEntry.getValue().getRoundNumber(),
nextEntry.getKey().equals(localAddress) ? "(Local node)" : "");
}
}
}

/**
Expand Down
Loading

0 comments on commit 850084e

Please sign in to comment.