Skip to content

Instantly share code, notes, and snippets.

@Galadrin
Last active January 13, 2026 16:45
Show Gist options
  • Select an option

  • Save Galadrin/c4dbc505310d864e371281dbe6a3ff8f to your computer and use it in GitHub Desktop.

Select an option

Save Galadrin/c4dbc505310d864e371281dbe6a3ff8f to your computer and use it in GitHub Desktop.
peer_comparison.py
#!/usr/bin/env python3
"""
Script to compare connected peers with the reference list
Author: David Pierret <[email protected]>
Copyright (c) 2025 Crosnest. All rights reserved.
"""
import requests
JSON of connected peers
json_data = requests.get("http://localhost:26657/net_info").json()
# Peer reference list
reference_peers = [
("dydx-oegs-node-1", "[email protected]:26656"),
("dydx-oegs-node-2", "[email protected]:26656"),
("dydx-oegs-node-3", "[email protected]:26656"),
("dydx-oegs-node-4", "[email protected]:26656"),
("dydx-full-node", "[email protected]:26656"),
("dydx-full-node-backup", "[email protected]:26656"),
("Pro-Delegator", "[email protected]:35042"),
("Informal", "[email protected]:32001"),
("Crosnest-1", "[email protected]:26656"),
("Crosnest-2", "[email protected]:26656"),
("Crosnest-3", "119f1bbb0779e8e44f0c61effc7bca1ca35e3f2e@[2400:d320:2:3783::2]:26656"),
("Kiln", "[email protected]:32373"),
("CryptoCrew-1", "[email protected]:2000"),
("CryptoCrew-2", "[email protected]:2000"),
("TTT VN", "[email protected]:26656"),
("Rhino-1", "[email protected]:23856"),
("Rhino-2", "[email protected]:23856"),
("Rhino-3", "[email protected]:23856"),
("Rhino-4", "[email protected]:23856"),
("Kingnode-1", "[email protected]:23856"),
("Kingnode-2", "[email protected]:23856"),
]
def parse_peer_address(peer_string):
"""Extract the ID and address of a peer"""
if '@' in peer_string:
parts = peer_string.split('@')
peer_id = parts[0]
address = parts[1]
return peer_id, address
return None, None
def format_duration(nanoseconds):
"""Format the duration in a readable format"""
try:
seconds = int(nanoseconds) / 1_000_000_000
hours = int(seconds // 3600)
minutes = int((seconds % 3600) // 60)
secs = int(seconds % 60)
return f"{hours}h {minutes}m {secs}s"
except:
return "N/A"
def format_bytes(bytes_value):
"""Formats bytes into a readable format"""
try:
bytes_int = int(bytes_value)
if bytes_int < 1024:
return f"{bytes_int} B"
elif bytes_int < 1024 * 1024:
return f"{bytes_int / 1024:.2f} KB"
elif bytes_int < 1024 * 1024 * 1024:
return f"{bytes_int / (1024 * 1024):.2f} MB"
else:
return f"{bytes_int / (1024 * 1024 * 1024):.2f} GB"
except:
return "N/A"
def main():
# Extract connected peers
connected_peers = {}
for peer in json_data['result']['peers']:
peer_id = peer['node_info']['id']
moniker = peer['node_info'].get('moniker', 'Unknown')
remote_ip = peer.get('remote_ip', 'Unknown')
is_outbound = peer.get('is_outbound', False)
# Connexion informations
conn_status = peer.get('connection_status', {})
duration = conn_status.get('Duration', '0')
send_monitor = conn_status.get('SendMonitor', {})
recv_monitor = conn_status.get('RecvMonitor', {})
connected_peers[peer_id] = {
'moniker': moniker,
'remote_ip': remote_ip,
'is_outbound': is_outbound,
'duration': duration,
'bytes_sent': send_monitor.get('Bytes', '0'),
'bytes_recv': recv_monitor.get('Bytes', '0'),
'avg_send_rate': send_monitor.get('AvgRate', '0'),
'avg_recv_rate': recv_monitor.get('AvgRate', '0'),
}
# Create the comparison table
print("\n" + "="*150)
print("DYDX PEERS COMPARISON TABLE")
print("="*150)
print(f"\nNumber of connected peers: {len(connected_peers)}")
print(f"Number of reference peers: {len(reference_peers)}\n")
# table header
header = f"{'Moniker':<25} {'Peer ID':<45} {'Connected':<10} {'IP Remote':<40} {'Direction':<10} {'Duration':<15} {'Sent':<12} {'Received':<12}"
print(header)
print("-" * 150)
# Browse the reference list
for moniker, peer_string in reference_peers:
peer_id, address = parse_peer_address(peer_string)
if peer_id and peer_id in connected_peers:
peer_info = connected_peers[peer_id]
status = "✅"
remote_ip = peer_info['remote_ip']
direction = "OUT" if peer_info['is_outbound'] else "IN"
duration = format_duration(peer_info['duration'])
bytes_sent = format_bytes(peer_info['bytes_sent'])
bytes_recv = format_bytes(peer_info['bytes_recv'])
else:
status = "❌"
remote_ip = "-"
direction = "-"
duration = "-"
bytes_sent = "-"
bytes_recv = "-"
short_id = peer_id[:20] + "..." if peer_id and len(peer_id) > 20 else (peer_id or "N/A")
print(f"{moniker:<25} {short_id:<45} {status:<10} {remote_ip:<40} {direction:<10} {duration:<15} {bytes_sent:<12} {bytes_recv:<12}")
print("-" * 150)
# Statistics
connected_count = sum(1 for moniker, peer_string in reference_peers
if parse_peer_address(peer_string)[0] in connected_peers)
total_count = len(reference_peers)
percentage = (connected_count / total_count * 100) if total_count > 0 else 0
print(f"\nSTATISTICS:")
print(f" - Peers connected: {connected_count}/{total_count} ({percentage:.1f}%)")
print(f" - Peers disconnected: {total_count - connected_count}")
# Connected peers not listed in the reference
reference_ids = {parse_peer_address(peer_string)[0] for _, peer_string in reference_peers}
unknown_peers = [peer_id for peer_id in connected_peers.keys() if peer_id not in reference_ids]
if unknown_peers:
print(f"\n⚠️ CONNECTED PEERS NOT LISTED IN THE REFERENCE ({len(unknown_peers)}):")
for peer_id in unknown_peers:
peer_info = connected_peers[peer_id]
print(f" - {peer_info['moniker']} ({peer_id}) - IP: {peer_info['remote_ip']}")
print("\n" + "="*150 + "\n")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment