-
Notifications
You must be signed in to change notification settings - Fork 1
feat(net): support domain names in peer configuration #75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
f040f31
cbf1222
b3706ef
1483681
aadffe7
10e1cb4
678cc89
b348ac4
634f111
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -4,13 +4,18 @@ | |||||||||||||||||||||||||||||
| import static org.tron.common.backup.BackupManager.BackupStatusEnum.MASTER; | ||||||||||||||||||||||||||||||
| import static org.tron.common.backup.BackupManager.BackupStatusEnum.SLAVER; | ||||||||||||||||||||||||||||||
| import static org.tron.common.backup.message.UdpMessageTypeEnum.BACKUP_KEEP_ALIVE; | ||||||||||||||||||||||||||||||
| import static org.tron.core.config.args.InetUtil.resolveInetAddress; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| import io.netty.util.internal.ConcurrentSet; | ||||||||||||||||||||||||||||||
| import java.net.InetAddress; | ||||||||||||||||||||||||||||||
| import java.net.InetSocketAddress; | ||||||||||||||||||||||||||||||
| import java.util.Map; | ||||||||||||||||||||||||||||||
| import java.util.Set; | ||||||||||||||||||||||||||||||
| import java.util.concurrent.ConcurrentHashMap; | ||||||||||||||||||||||||||||||
| import java.util.concurrent.ScheduledExecutorService; | ||||||||||||||||||||||||||||||
| import java.util.concurrent.TimeUnit; | ||||||||||||||||||||||||||||||
| import lombok.Getter; | ||||||||||||||||||||||||||||||
| import lombok.Setter; | ||||||||||||||||||||||||||||||
| import lombok.extern.slf4j.Slf4j; | ||||||||||||||||||||||||||||||
| import org.springframework.stereotype.Component; | ||||||||||||||||||||||||||||||
| import org.tron.common.backup.message.KeepAliveMessage; | ||||||||||||||||||||||||||||||
|
|
@@ -20,46 +25,46 @@ | |||||||||||||||||||||||||||||
| import org.tron.common.backup.socket.UdpEvent; | ||||||||||||||||||||||||||||||
| import org.tron.common.es.ExecutorServiceManager; | ||||||||||||||||||||||||||||||
| import org.tron.common.parameter.CommonParameter; | ||||||||||||||||||||||||||||||
| import org.tron.p2p.utils.NetUtil; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| @Slf4j(topic = "backup") | ||||||||||||||||||||||||||||||
| @Component | ||||||||||||||||||||||||||||||
| public class BackupManager implements EventHandler { | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| private CommonParameter parameter = CommonParameter.getInstance(); | ||||||||||||||||||||||||||||||
| private final CommonParameter parameter = CommonParameter.getInstance(); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| private int priority = parameter.getBackupPriority(); | ||||||||||||||||||||||||||||||
| private final int priority = parameter.getBackupPriority(); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| private int port = parameter.getBackupPort(); | ||||||||||||||||||||||||||||||
| private final int port = parameter.getBackupPort(); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| private int keepAliveInterval = parameter.getKeepAliveInterval(); | ||||||||||||||||||||||||||||||
| private final int keepAliveInterval = parameter.getKeepAliveInterval(); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| private int keepAliveTimeout = keepAliveInterval * 6; | ||||||||||||||||||||||||||||||
| private final int keepAliveTimeout = keepAliveInterval * 6; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| private String localIp = ""; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| private Set<String> members = new ConcurrentSet<>(); | ||||||||||||||||||||||||||||||
| private final Set<String> members = new ConcurrentSet<>(); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| private final String esName = "backup-manager"; | ||||||||||||||||||||||||||||||
| private final Map<String, String> domainIpCache = new ConcurrentHashMap<>(); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| private ScheduledExecutorService executorService = | ||||||||||||||||||||||||||||||
| private final String esName = "backup-manager"; | ||||||||||||||||||||||||||||||
| private final ScheduledExecutorService executorService = | ||||||||||||||||||||||||||||||
| ExecutorServiceManager.newSingleThreadScheduledExecutor(esName); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| private final String dnsEsName = "backup-dns-refresh"; | ||||||||||||||||||||||||||||||
| private final ScheduledExecutorService dnsExecutorService = | ||||||||||||||||||||||||||||||
| ExecutorServiceManager.newSingleThreadScheduledExecutor(dnsEsName); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| @Setter | ||||||||||||||||||||||||||||||
| private MessageHandler messageHandler; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| @Getter | ||||||||||||||||||||||||||||||
| private BackupStatusEnum status = MASTER; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| private volatile long lastKeepAliveTime; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| private volatile boolean isInit = false; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| public void setMessageHandler(MessageHandler messageHandler) { | ||||||||||||||||||||||||||||||
| this.messageHandler = messageHandler; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| public BackupStatusEnum getStatus() { | ||||||||||||||||||||||||||||||
| return status; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| public void setStatus(BackupStatusEnum status) { | ||||||||||||||||||||||||||||||
| logger.info("Change backup status to {}", status); | ||||||||||||||||||||||||||||||
| this.status = status; | ||||||||||||||||||||||||||||||
|
|
@@ -78,10 +83,20 @@ public void init() { | |||||||||||||||||||||||||||||
| logger.warn("Failed to get local ip"); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| for (String member : parameter.getBackupMembers()) { | ||||||||||||||||||||||||||||||
| if (!localIp.equals(member)) { | ||||||||||||||||||||||||||||||
| members.add(member); | ||||||||||||||||||||||||||||||
| for (String ipOrDomain : parameter.getBackupMembers()) { | ||||||||||||||||||||||||||||||
| InetAddress inetAddress = resolveInetAddress(ipOrDomain); | ||||||||||||||||||||||||||||||
| if (inetAddress == null) { | ||||||||||||||||||||||||||||||
| logger.warn("Failed to resolve backup member domain: {}", ipOrDomain); | ||||||||||||||||||||||||||||||
| continue; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| String ip = inetAddress.getHostAddress(); | ||||||||||||||||||||||||||||||
| if (localIp.equals(ip)) { | ||||||||||||||||||||||||||||||
| continue; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| if (!NetUtil.validIpV4(ipOrDomain) && !NetUtil.validIpV6(ipOrDomain)) { | ||||||||||||||||||||||||||||||
| domainIpCache.put(ipOrDomain, ip); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| members.add(ip); | ||||||||||||||||||||||||||||||
|
Comment on lines
+93
to
+99
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P1: Domains resolving to Prompt for AI agents
Suggested change
|
||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
Comment on lines
+86
to
100
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Domains resolving to When a configured backup member is a domain name that currently resolves to Unless that's intentional, cache the domain first and only skip adding it to 🛠️ Suggested fix for (String ipOrDomain : parameter.getBackupMembers()) {
InetAddress inetAddress = resolveInetAddress(ipOrDomain);
if (inetAddress == null) {
logger.warn("Failed to resolve backup member domain: {}", ipOrDomain);
continue;
}
String ip = inetAddress.getHostAddress();
- if (localIp.equals(ip)) {
- continue;
- }
if (!NetUtil.validIpV4(ipOrDomain) && !NetUtil.validIpV6(ipOrDomain)) {
domainIpCache.put(ipOrDomain, ip);
}
+ if (localIp.equals(ip)) {
+ continue;
+ }
members.add(ip);
}🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| logger.info("Backup localIp:{}, members: size= {}, {}", localIp, members.size(), members); | ||||||||||||||||||||||||||||||
|
|
@@ -111,6 +126,16 @@ public void init() { | |||||||||||||||||||||||||||||
| logger.error("Exception in send keep alive", t); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| }, 1000, keepAliveInterval, TimeUnit.MILLISECONDS); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| if (!domainIpCache.isEmpty()) { | ||||||||||||||||||||||||||||||
| dnsExecutorService.scheduleWithFixedDelay(() -> { | ||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||
| refreshMemberIps(); | ||||||||||||||||||||||||||||||
| } catch (Throwable t) { | ||||||||||||||||||||||||||||||
| logger.error("Exception in backup DNS refresh", t); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| }, 60_000L, 60_000L, TimeUnit.MILLISECONDS); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| @Override | ||||||||||||||||||||||||||||||
|
|
@@ -149,6 +174,7 @@ public void handleEvent(UdpEvent udpEvent) { | |||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| public void stop() { | ||||||||||||||||||||||||||||||
| ExecutorServiceManager.shutdownAndAwaitTermination(executorService, esName); | ||||||||||||||||||||||||||||||
| ExecutorServiceManager.shutdownAndAwaitTermination(dnsExecutorService, dnsEsName); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| @Override | ||||||||||||||||||||||||||||||
|
|
@@ -162,4 +188,28 @@ public enum BackupStatusEnum { | |||||||||||||||||||||||||||||
| MASTER | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||
| * Re-resolves all tracked domain entries. If an IP has changed, the old IP is | ||||||||||||||||||||||||||||||
| * removed from {@link #members} and the new IP is added. | ||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||
| private void refreshMemberIps() { | ||||||||||||||||||||||||||||||
| for (Map.Entry<String, String> entry : domainIpCache.entrySet()) { | ||||||||||||||||||||||||||||||
| String domain = entry.getKey(); | ||||||||||||||||||||||||||||||
| String oldIp = entry.getValue(); | ||||||||||||||||||||||||||||||
| InetAddress inetAddress = resolveInetAddress(domain); | ||||||||||||||||||||||||||||||
| if (inetAddress == null) { | ||||||||||||||||||||||||||||||
| logger.warn("DNS refresh: failed to re-resolve backup member domain {}, keep it", domain); | ||||||||||||||||||||||||||||||
| continue; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| String newIp = inetAddress.getHostAddress(); | ||||||||||||||||||||||||||||||
| if (!newIp.equals(oldIp)) { | ||||||||||||||||||||||||||||||
| logger.info("DNS refresh: backup member {} IP changed {} -> {}", domain, oldIp, newIp); | ||||||||||||||||||||||||||||||
| members.remove(oldIp); | ||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P1: Removing Prompt for AI agents
Suggested change
|
||||||||||||||||||||||||||||||
| if (!localIp.equals(newIp)) { | ||||||||||||||||||||||||||||||
| members.add(newIp); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| domainIpCache.put(domain, newIp); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
Comment on lines
+195
to
+214
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Consider keeping 🛠️ Sketch if (!newIp.equals(oldIp)) {
logger.info("DNS refresh: backup member {} IP changed {} -> {}", domain, oldIp, newIp);
- members.remove(oldIp);
+ boolean stillReferenced = domainIpCache.entrySet().stream()
+ .anyMatch(e -> !e.getKey().equals(domain) && oldIp.equals(e.getValue()));
+ if (!stillReferenced) {
+ members.remove(oldIp);
+ }
if (!localIp.equals(newIp)) {
members.add(newIp);
}
domainIpCache.put(domain, newIp);
}🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
Does the io.github.tronprotocol:libp2p Maven artifact have a 2.2.8 release that exposes LookUpTxt.lookUpIp?💡 Result:
No, the io.github.tronprotocol:libp2p Maven artifact does not have a 2.2.8 release. The latest available version is 2.2.7, released on November 12, 2025. No sources mention a 2.2.8 release on Maven Central, Sonatype Central, mvnrepository.com, or the project's GitHub releases page. No evidence was found for a class or method named LookUpTxt.lookUpIp in the libp2p codebase or documentation across all versions.
Citations:
🏁 Script executed:
Repository: 317787106/java-tron
Length of output: 2290
Do not ship a personal JitPack fork of libp2p as the production dependency.
This replaces the official
io.github.tronprotocol:libp2p:2.2.7withcom.github.317787106:libp2p:v0.10.0. The new group coordinatecom.github.317787106is a JitPack path that resolves to a personal GitHub account (user id317787106), not thetronprotocolorganization. Several critical problems:PR summary is incorrect. The PR description states the bump is
libp2p 2.2.7 -> 2.2.8to acquireLookUpTxt.lookUpIp, but this is misleading:io.github.tronprotocol:libp2phas no 2.2.8 release (latest is 2.2.7), andLookUpTxt.lookUpIpdoes not exist in the official libp2p codebase. The method exists only in the fork (com.github.317787106). The actual change is2.2.7 -> v0.10.0from a personal account — this is a material difference from what the commit message promises.The fork is not optional, making supply chain risk acute. Because
LookUpTxt.lookUpIpis used in this codebase (seeframework/src/main/java/org/tron/core/config/args/InetUtil.javalines 112, 114, 141, 143) and exists nowhere else, the fork dependency is not a temporary workaround—it is a production requirement for a mainnet node's core P2P configuration. This means the trust anchor is permanently anchored to an individual contributor's GitHub account rather than the Tron Protocol organization.Commented-out coordinate. Line 25 retains the old
io.github.tronprotocoldependency as a comment. Dead config should not be merged. Its presence is a strong signal that this change was a development workaround that was never properly resolved upstream.Recommended: Coordinate with the libp2p maintainers to release
LookUpTxt.lookUpIpunder the officialio.github.tronprotocolorg (e.g., as 2.2.8 or later), then revert to the official dependency. If that is not feasible in the release timeline, gate the fork behind a clearly labeled non-default profile and document the limitation and timeline for resolution in the PR. Do not merge commented-out code.🤖 Prompt for AI Agents