Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
import org.hyperledger.besu.ethereum.mainnet.BalConfiguration;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.p2p.config.SubProtocolConfiguration;
import org.hyperledger.besu.ethereum.p2p.network.ProtocolManager;
import org.hyperledger.besu.ethereum.p2p.rlpx.wire.SubProtocol;
import org.hyperledger.besu.ethereum.storage.StorageProvider;
import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
Expand Down Expand Up @@ -225,9 +227,37 @@ protected JsonRpcMethods createAdditionalJsonRpcMethodFactory(
protected SubProtocolConfiguration createSubProtocolConfiguration(
final EthProtocolManager ethProtocolManager,
final Optional<SnapProtocolManager> maybeSnapProtocolManager) {
return besuControllerBuilderSchedule
.get(besuControllerBuilderSchedule.keySet().stream().skip(1).findFirst().orElseThrow())
.createSubProtocolConfiguration(ethProtocolManager, maybeSnapProtocolManager);
// During consensus migration, we need BOTH wire protocols registered.
// This allows nodes to communicate before AND after the migration block.
// Previously used .skip(1) which was non-deterministic with HashMap ordering.
//
// We merge all sub-protocol configurations, which registers both:
// - IBF/1 (IBFT2) for pre-migration communication
// - istanbul/100 (QBFT) for post-migration communication
final SubProtocolConfiguration mergedConfig = new SubProtocolConfiguration();
Comment thread
SaeeDawod marked this conversation as resolved.
final java.util.Set<String> addedProtocolNames = new java.util.HashSet<>();

// Add sub-protocols from each consensus builder (sorted by block number for determinism)
besuControllerBuilderSchedule.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.forEach(
entry -> {
final SubProtocolConfiguration builderConfig =
entry.getValue().createSubProtocolConfiguration(ethProtocolManager, maybeSnapProtocolManager);
final List<SubProtocol> subProtocols = builderConfig.getSubProtocols();
final List<ProtocolManager> protocolManagers = builderConfig.getProtocolManagers();
for (int i = 0; i < subProtocols.size(); i++) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The code assumes that subProtocols and protocolManagers lists have the same size. This is a common pattern with parallel collections and can be fragile. If protocolManagers were ever shorter than subProtocols, this would cause an IndexOutOfBoundsException. To make the code more robust, I recommend adding a precondition check to validate that the lists are of equal length before iterating, for example:

if (subProtocols.size() != protocolManagers.size()) {
  throw new IllegalStateException("Sub-protocols and protocol managers lists must have the same size.");
}

final SubProtocol subProtocol = subProtocols.get(i);
final ProtocolManager protocolManager = protocolManagers.get(i);
// Only add if not already present (avoid duplicates like EthProtocol)
if (!addedProtocolNames.contains(subProtocol.getName())) {
mergedConfig.withSubProtocol(subProtocol, protocolManager);
addedProtocolNames.add(subProtocol.getName());
}
Comment on lines +253 to +256
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The logic to check for an element's presence in a Set before adding it can be made more concise. The Set.add() method returns true if the element was not already in the set, so you can perform the check and the addition in a single step within the if condition. This is a common Java idiom that improves readability.

                if (addedProtocolNames.add(subProtocol.getName())) {
                  mergedConfig.withSubProtocol(subProtocol, protocolManager);
                }

}
});

return mergedConfig;
}

@Override
Expand Down