forked from hyperledger/besu
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Node discovery via DNS (hyperledger#7129)
- Node discovery via DNS module as a vertex verticle (code adapted from Tuweni) - Mock DNS server in unit tests. --------- Signed-off-by: Usman Saleem <usman@usmans.info> Co-authored-by: Sally MacFarlane <macfarla.github@gmail.com>
- Loading branch information
1 parent
9d8c191
commit e4902af
Showing
18 changed files
with
1,376 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
Hyperledger Besu | ||
Copyright contributors to Hyperledger Besu. | ||
|
||
This product includes software adapted from Tuweni. (https://tuweni.tmio.io/) | ||
Copyright 2023-2024 The Machine Consultancy LLC | ||
Licensed under Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0) | ||
|
||
The following NOTICE file content is provided by Tuweni: | ||
------------------------------------------------------------ | ||
This product includes code developed under the Apache Tuweni incubation project. | ||
|
||
Copyright 2019-2023 The Apache Software Foundation | ||
|
||
This product includes software developed at | ||
The Apache Software Foundation (http://www.apache.org/). | ||
|
||
In addition, this product includes software developed by | ||
Copyright 2018-2019 ConsenSys, Inc. | ||
------------------------------------------------------------ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
107 changes: 107 additions & 0 deletions
107
ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSDaemon.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
/* | ||
* 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.p2p.discovery.dns; | ||
|
||
import java.util.List; | ||
import java.util.Optional; | ||
|
||
import io.vertx.core.AbstractVerticle; | ||
import org.apache.tuweni.devp2p.EthereumNodeRecord; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
// Adapted from https://github.com/tmio/tuweni and licensed under Apache 2.0 | ||
/** | ||
* Resolves DNS records over time, refreshing records. This is written as a Vertx Verticle which | ||
* allows to run outside the Vertx event loop | ||
*/ | ||
public class DNSDaemon extends AbstractVerticle { | ||
private static final Logger LOG = LoggerFactory.getLogger(DNSDaemon.class); | ||
private final String enrLink; | ||
private final long seq; | ||
private final long initialDelay; | ||
private final long delay; | ||
private final Optional<DNSDaemonListener> listener; | ||
private final Optional<String> dnsServer; | ||
private Optional<Long> periodicTaskId = Optional.empty(); | ||
private DNSResolver dnsResolver; | ||
|
||
/** | ||
* Creates a new DNSDaemon. | ||
* | ||
* @param enrLink the ENR link to start with, of the form enrtree://PUBKEY@domain | ||
* @param listener Listener notified when records are read and whenever they are updated. | ||
* @param seq the sequence number of the root record. If the root record seq is higher, proceed | ||
* with visit. | ||
* @param initialDelay the delay in milliseconds before the first poll of DNS records. | ||
* @param delay the delay in milliseconds at which to poll DNS records. If negative or zero, it | ||
* runs only once. | ||
* @param dnsServer the DNS server to use for DNS query. If null, the default DNS server will be | ||
* used. | ||
*/ | ||
public DNSDaemon( | ||
final String enrLink, | ||
final DNSDaemonListener listener, | ||
final long seq, | ||
final long initialDelay, | ||
final long delay, | ||
final String dnsServer) { | ||
this.enrLink = enrLink; | ||
this.listener = Optional.ofNullable(listener); | ||
this.seq = seq; | ||
this.initialDelay = initialDelay; | ||
this.delay = delay; | ||
this.dnsServer = Optional.ofNullable(dnsServer); | ||
} | ||
|
||
/** Starts the DNSDaemon. */ | ||
@Override | ||
public void start() { | ||
if (vertx == null) { | ||
throw new IllegalStateException("DNSDaemon must be deployed as a vertx verticle."); | ||
} | ||
|
||
LOG.info("Starting DNSDaemon for {}, using {} DNS host.", enrLink, dnsServer.orElse("default")); | ||
dnsResolver = new DNSResolver(vertx, enrLink, seq, dnsServer); | ||
if (delay > 0) { | ||
periodicTaskId = Optional.of(vertx.setPeriodic(initialDelay, delay, this::refreshENRRecords)); | ||
} else { | ||
// do one-shot resolution | ||
refreshENRRecords(0L); | ||
} | ||
} | ||
|
||
/** Stops the DNSDaemon. */ | ||
@Override | ||
public void stop() { | ||
LOG.info("Stopping DNSDaemon for {}", enrLink); | ||
periodicTaskId.ifPresent(vertx::cancelTimer); | ||
dnsResolver.close(); | ||
} | ||
|
||
/** | ||
* Refresh enr records by calling dnsResolver and updating the listeners. | ||
* | ||
* @param taskId the task id of the periodic task | ||
*/ | ||
void refreshENRRecords(final Long taskId) { | ||
LOG.debug("Refreshing DNS records"); | ||
final long startTime = System.nanoTime(); | ||
final List<EthereumNodeRecord> ethereumNodeRecords = dnsResolver.collectAll(); | ||
final long endTime = System.nanoTime(); | ||
LOG.debug("Time taken to DNSResolver.collectAll: {} ms", (endTime - startTime) / 1_000_000); | ||
listener.ifPresent(it -> it.newRecords(dnsResolver.sequence(), ethereumNodeRecords)); | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
.../p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSDaemonListener.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/* | ||
* 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.p2p.discovery.dns; | ||
|
||
import java.util.List; | ||
|
||
import org.apache.tuweni.devp2p.EthereumNodeRecord; | ||
|
||
// Adapted from https://github.com/tmio/tuweni and licensed under Apache 2.0 | ||
/** Callback listening to updates of the DNS records. */ | ||
@FunctionalInterface | ||
public interface DNSDaemonListener { | ||
/** | ||
* Callback called when the seq is updated on the DNS server | ||
* | ||
* @param seq the update identifier of the records | ||
* @param records the records stored on the server | ||
*/ | ||
void newRecords(long seq, List<EthereumNodeRecord> records); | ||
} |
Oops, something went wrong.