Skip to content
Merged
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

### Additions and Improvements
- Add IPv6 dual-stack support for DiscV5 peer discovery (enabled via `--Xv5-discovery-enabled`): new `--p2p-host-ipv6`, `--p2p-interface-ipv6`, and `--p2p-port-ipv6` CLI options enable a second UDP discovery socket; `--p2p-ipv6-outbound-enabled` controls whether IPv6 is preferred for outbound connections when a peer advertises both address families [#9763](https://github.com/hyperledger/besu/pull/9763); RLPx now also binds a second TCP socket on the IPv6 interface so IPv6-only peers can establish connections [#9873](https://github.com/hyperledger/besu/pull/9873)
- Stop EngineQosTimer as part of shutdown [#9903](https://github.com/hyperledger/besu/pull/9903)
- Add blockTimestamp to transaction RPC results [#9887](https://github.com/hyperledger/besu/pull/9887)

## 26.2.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.hyperledger.besu.ethereum.api.jsonrpc.execution.TracedJsonRpcProcessor;
import org.hyperledger.besu.ethereum.api.jsonrpc.health.HealthService;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.Logging403ErrorHandler;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.WebSocketConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.WebSocketMessageHandler;
Expand Down Expand Up @@ -276,6 +277,8 @@ public CompletableFuture<Void> start() {
}

public CompletableFuture<Void> stop() {
stopEngineCallListener();

if (httpServer == null) {
return CompletableFuture.completedFuture(null);
}
Expand All @@ -293,6 +296,15 @@ public CompletableFuture<Void> stop() {
return resultFuture;
}

private void stopEngineCallListener() {
// all engine rpc methods share one listener interface
rpcMethods.values().stream()
.filter(ExecutionEngineJsonRpcMethod.class::isInstance)
.map(ExecutionEngineJsonRpcMethod.class::cast)
.findFirst()
.ifPresent(method -> method.getEngineCallListener().stop());
}

private Handler<HttpConnection> connectionHandler() {

return connection -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public class QosTimer {
private final Vertx timerVertx;
private final AtomicLong timerId = new AtomicLong(Long.MAX_VALUE);
private final AtomicLong lastReset = new AtomicLong(System.currentTimeMillis());
private volatile boolean stopped = false;

private final long periodMillis;
private final Consumer<Long> consumerTask;
Expand All @@ -38,17 +39,30 @@ public QosTimer(
}

public void resetTimer() {
if (stopped) {
return;
}
lastReset.set(System.currentTimeMillis());
resetTimerHandler(timerHandler());
}

public void stop() {
stopped = true;
timerVertx.cancelTimer(timerId.get());
}

void resetTimerHandler(final Handler<Long> timerHandler) {
timerVertx.cancelTimer(timerId.get());
timerId.set(timerVertx.setTimer(periodMillis, timerHandler));
if (!stopped) {
timerId.set(timerVertx.setTimer(periodMillis, timerHandler));
}
}

Handler<Long> timerHandler() {
return z -> {
if (stopped) {
return;
}
var lastCall = getLastCallMillis();
var now = System.currentTimeMillis();
if (lastCall + periodMillis < now) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ public final JsonRpcResponse response(final JsonRpcRequestContext request) {

public abstract JsonRpcResponse syncResponse(final JsonRpcRequestContext request);

public EngineCallListener getEngineCallListener() {
return engineCallListener;
}

protected ValidationResult<RpcErrorType> validateForkSupported(final long blockTimestamp) {
return ValidationResult.valid();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@

public interface EngineCallListener {
void executionEngineCalled();

default void stop() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ public void logTimeoutWarning() {
QOS_TIMEOUT_MILLIS / 1000L);
}

@Override
public void stop() {
qosTimer.stop();
}

@VisibleForTesting
public QosTimer getQosTimer() {
return qosTimer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,16 @@ public void shouldNotExecuteBeforeTimeout() throws InterruptedException {
assertThat(latch.await(50L, TimeUnit.MILLISECONDS)).isFalse();
}

@Test
public void shouldNotRescheduleAfterStop() throws InterruptedException {
final long TEST_QOS_TIMEOUT = 50L;
final CountDownLatch latch = new CountDownLatch(1);
final var timer = new QosTimer(vertx, TEST_QOS_TIMEOUT, z -> latch.countDown());
timer.stop();
// wait long enough for the timer to have fired if it weren't stopped
assertThat(latch.await(200L, TimeUnit.MILLISECONDS)).isFalse();
}

@Test
public void shouldNotExecuteWhenReset() throws InterruptedException {
final long TEST_QOS_TIMEOUT = 50L;
Expand Down