Skip to content

Update Netty 4.1→4.2 and companion dependency upgrades#237

Open
usmansaleem wants to merge 1 commit into
Consensys:masterfrom
usmansaleem:update-netty-4.2
Open

Update Netty 4.1→4.2 and companion dependency upgrades#237
usmansaleem wants to merge 1 commit into
Consensys:masterfrom
usmansaleem:update-netty-4.2

Conversation

@usmansaleem

@usmansaleem usmansaleem commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Bumps Netty 4.1.115.Final → 4.2.15.Final, plus companion upgrades: Guava 33.2→33.6, Log4j 2.23→2.26, BouncyCastle 1.78→1.84, Vert.x 4.5.9→4.5.28, Tuweni 2.7.0→2.7.2
  • Adds org.jspecify:jspecify:1.0.0 (compileOnly) to replace javax.annotation.Nonnull which was previously provided transitively by Netty 4.1 but dropped in 4.2 (aligns with Besu's migration to JSpecify)
  • Resolves all deprecation warnings introduced by these upgrades (Reactor ReplayProcessorSinks, Netty NioEventLoopGroupMultiThreadIoEventLoopGroup, InternetProtocolFamilyjava.net.StandardProtocolFamily, Guava CacheBuilder duration overload)

Details

Netty 4.2 deprecations

  • NioEventLoopGroupMultiThreadIoEventLoopGroup(1, NioIoHandler.newFactory()) in NettyDiscoveryServerImpl
  • InternetProtocolFamilyjava.net.StandardProtocolFamily in NettyDiscoveryClientImpl, DiscoveryManagerImpl, DiscoverySystemBuilder

Reactor Sinks migration (ReplayProcessor/FluxProcessor/FluxSink deprecated since Reactor 3.5)

  • ReplayProcessor.cacheLast() + FluxSinkSinks.many().replay().latest() across NettyDiscoveryServerImpl, DiscoveryManagerImpl, PipelineImpl, SimpleProcessor, IncomingMessageSink, OutgoingParcelHandler
  • PipelineImpl.push() uses emitNext with FAIL_NON_SERIALIZED retry rather than tryEmitNext — necessary because incomingPipeline can receive concurrent pushes from IPv4 and IPv6 Netty event-loop threads; the old ReplayProcessor.FluxSink serialized these internally, the new safe Sinks.Many does not
  • DelegatingReactorScheduler.start(): suppress deprecated override (preserves delegation behaviour for downstream schedulers)

Other

  • CacheBuilder.expireAfterWrite(long, TimeUnit)expireAfterWrite(Duration) in ExpirationSet
  • @Nonnull@NonNull (JSpecify) in DelegatingReactorScheduler, ErrorHandlingScheduler

Test plan

  • ./gradlew build passes (all 16 integration tests green)
  • ./gradlew compileJava --rerun-tasks with -Xlint:deprecation produces zero deprecation warnings

Note

Medium Risk
Touches discovery UDP I/O and reactive pipelines with concurrency-sensitive PipelineImpl emit behavior; dependency major bumps (Netty 4.2) increase regression risk in networking despite targeted API migrations.

Overview
Upgrades Netty 4.1 → 4.2.15 and bumps Guava, Log4j, BouncyCastle, Vert.x, and Tuweni. Adds org.jspecify:jspecify (compileOnly) because Netty 4.2 no longer brings javax.annotation transitively.

Netty 4.2: NettyDiscoveryServerImpl uses MultiThreadIoEventLoopGroup + NioIoHandler instead of NioEventLoopGroup. IPv4/IPv6 channel maps and listen validation use java.net.StandardProtocolFamily (with a shared protocolFamilyOf helper) instead of Netty’s InternetProtocolFamily.

Reactor: Deprecated ReplayProcessor / FluxSink paths are replaced with Sinks.many().replay().latest() for incoming/outgoing UDP streams, pipelines, and SimpleProcessor. PipelineImpl.push() uses emitNext with FAIL_NON_SERIALIZED retry so concurrent pushes from dual-stack Netty event loops stay safe. Emit sites use tryEmitNext / asFlux() where appropriate.

Misc: ExpirationSet uses Guava’s expireAfterWrite(Duration); scheduler wrappers use JSpecify @NonNull; tests mock Sinks.Many and verify tryEmitNext.

Reviewed by Cursor Bugbot for commit f1ed571. Bugbot is set up for automated code reviews on this repo. Configure here.

Dependency version bumps:
- Netty 4.1.115.Final → 4.2.15.Final
- Guava 33.2.1-jre → 33.6.0-jre
- Log4j 2.23.1 → 2.26.0
- BouncyCastle 1.78.1 → 1.84
- Vert.x 4.5.9 → 4.5.28
- Tuweni 2.7.0 → 2.7.2
- Add org.jspecify:jspecify:1.0.0 (compileOnly)

Fix deprecations introduced by these upgrades:

Netty 4.2:
- Replace NioEventLoopGroup with MultiThreadIoEventLoopGroup + NioIoHandler
- Replace InternetProtocolFamily with java.net.StandardProtocolFamily

Reactor 3.5+:
- Migrate ReplayProcessor/FluxProcessor/FluxSink to Sinks.many().replay().latest()
- PipelineImpl.push() uses emitNext with FAIL_NON_SERIALIZED retry to handle
  concurrent emissions from IPv4 and IPv6 Netty event-loop threads
- Suppress deprecated Scheduler.start() override in DelegatingReactorScheduler

JSpecify (replacing javax.annotation removed by Netty 4.2 transitive dep):
- Replace @nonnull with @nonnull from org.jspecify.annotations

Guava:
- Replace CacheBuilder.expireAfterWrite(long, TimeUnit) with expireAfterWrite(Duration)

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR upgrades core networking and supporting dependencies (notably Netty 4.1→4.2) and updates the discovery networking/reactive plumbing to match new APIs and remove deprecations, including the migration from Reactor ReplayProcessor/FluxSink to Sinks.Many and adoption of JSpecify annotations.

Changes:

  • Upgrade Netty (4.1→4.2) and companion libraries (Guava, Log4j, BouncyCastle, Vert.x, Tuweni), plus add org.jspecify:jspecify as compileOnly.
  • Replace deprecated Reactor processors/sinks with Sinks.many().replay().latest() across pipeline, networking, and scheduler utilities.
  • Replace Netty InternetProtocolFamily usage with java.net.StandardProtocolFamily mapping helpers.

Reviewed changes

Copilot reviewed 13 out of 14 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/test/java/org/ethereum/beacon/discovery/pipeline/handler/OutgoingParcelHandlerTest.java Updates test to mock Sinks.Many instead of FluxSink and verify emission via Reactor sinks API.
src/main/java/org/ethereum/beacon/discovery/scheduler/SimpleProcessor.java Migrates from ReplayProcessor/FluxSink to Sinks.Many for a lightweight processor abstraction.
src/main/java/org/ethereum/beacon/discovery/scheduler/ErrorHandlingScheduler.java Switches @Nonnull to JSpecify @NonNull on scheduler APIs.
src/main/java/org/ethereum/beacon/discovery/scheduler/DelegatingReactorScheduler.java Switches @Nonnull to JSpecify @NonNull and suppresses deprecated start() override.
src/main/java/org/ethereum/beacon/discovery/pipeline/PipelineImpl.java Migrates pipeline source from ReplayProcessor to Sinks.Many with non-serialized emission retry.
src/main/java/org/ethereum/beacon/discovery/pipeline/handler/OutgoingParcelHandler.java Migrates outgoing parcel emission from FluxSink.next to Sinks.Many.tryEmitNext.
src/main/java/org/ethereum/beacon/discovery/network/NettyDiscoveryServerImpl.java Updates Netty event loop initialization for Netty 4.2 and replaces inbound processor with Sinks.Many.
src/main/java/org/ethereum/beacon/discovery/network/NettyDiscoveryClientImpl.java Replaces InternetProtocolFamily channel selection with StandardProtocolFamily helper.
src/main/java/org/ethereum/beacon/discovery/network/IncomingMessageSink.java Updates inbound Netty handler to emit into Sinks.Many instead of FluxSink.
src/main/java/org/ethereum/beacon/discovery/DiscoverySystemBuilder.java Updates listen-address validation to use StandardProtocolFamily instead of Netty’s InternetProtocolFamily.
src/main/java/org/ethereum/beacon/discovery/DiscoveryManagerImpl.java Migrates outgoing message stream to Sinks.Many, updates client wiring, and uses StandardProtocolFamily for channel map keys.
src/main/java/org/ethereum/beacon/discovery/database/ExpirationSet.java Migrates Guava cache expiration API to Duration overload.
gradle/versions.gradle Bumps Netty/Guava/Log4j/BouncyCastle/Vert.x/Tuweni versions and adds managed JSpecify dependency.
build.gradle Adds compileOnly org.jspecify:jspecify to support JSpecify annotations.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +53 to 54
outgoingSink.tryEmitNext(parcel);
envelope.remove(Field.INCOMING);
protected void channelRead0(ChannelHandlerContext ctx, Envelope msg) {
LOG.trace(() -> String.format("Incoming packet %s in session %s", msg, ctx));
messageSink.next(msg);
messageSink.tryEmitNext(msg);
Comment on lines 69 to 72
@Override
public void onNext(T t) {
sink.next(t);
sinks.tryEmitNext(t);
}
Comment on lines 75 to 77
public void onError(Throwable throwable) {
sink.error(throwable);
sinks.tryEmitError(throwable);
}
Comment on lines 79 to 82
@Override
public void onComplete() {
sink.complete();
sinks.tryEmitComplete();
}
Comment on lines 56 to +58
handler.handle(envelope);

verify(outgoingSink).next(parcel);
verify(outgoingSink).tryEmitNext(parcel);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants