nucypher/scripts/dkg/differing_ferveo_keys.py

113 lines
3.5 KiB
Python

from typing import List, Optional
import click
import requests
from eth_typing import ChecksumAddress
from nucypher_core import NodeMetadata
from urllib3.exceptions import InsecureRequestWarning
from nucypher.blockchain.eth import domains
from nucypher.blockchain.eth.agents import (
ContractAgency,
CoordinatorAgent,
)
from nucypher.blockchain.eth.registry import ContractRegistry
from nucypher.utilities.emitters import StdoutEmitter
from nucypher.utilities.logging import GlobalLoggerSettings
GlobalLoggerSettings.start_console_logging()
emitter = StdoutEmitter(verbosity=2)
def get_node_urls(participants: Optional[List[ChecksumAddress]] = None):
participants_set = set(participants) if participants else None
node_urls = {}
try:
response = requests.get(
"https://mainnet.nucypher.network:9151/status?json=true",
verify=False,
timeout=5,
)
all_nodes = response.json().get("known_nodes", [])
for node in all_nodes:
staker_address = node["staker_address"]
if participants_set and staker_address not in participants_set:
continue
node_urls[node["staker_address"]] = f"https://{node['rest_url']}"
except Exception:
pass
return node_urls
def get_current_ferveo_key(node_url):
try:
response = requests.get(
f"{node_url}/public_information", verify=False, timeout=5
)
node_metadata = NodeMetadata.from_bytes(response.content)
return node_metadata.payload.ferveo_public_key
except Exception:
pass
return None
@click.command()
@click.option(
"--polygon-endpoint",
"polygon_endpoint",
help="Polygon network provider URI",
type=click.STRING,
required=True,
)
@click.option(
"--ritual-id", help="Ritual ID", type=click.INT, required=False, default=None
)
def differing_ferveo_keys(
polygon_endpoint,
ritual_id,
):
# Suppress https verification warnings
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
domain = domains.get_domain(domains.MAINNET.name)
registry = ContractRegistry.from_latest_publication(domain=domain)
emitter.echo(f"NOTICE: Connecting to {domain} domain", color="yellow")
coordinator_agent = ContractAgency.get_agent(
agent_class=CoordinatorAgent,
registry=registry,
blockchain_endpoint=polygon_endpoint,
) # type: CoordinatorAgent
participants = None # None means all nodes
if ritual_id:
ritual = coordinator_agent.get_ritual(ritual_id)
participants = ritual.providers # only nodes for ritual
node_urls = get_node_urls(participants)
ritual_id_for_public_key_check = ritual_id or coordinator_agent.number_of_rituals()
for provider, node_url in node_urls.items():
if not node_url:
print(f"Unable to determine public ip for {provider}")
continue
else:
current_ferveo_key = get_current_ferveo_key(node_url)
if not current_ferveo_key:
print(
f"Unable to obtain current public key from {node_url} for {provider}"
)
continue
reported_ferveo_key = coordinator_agent.get_provider_public_key(
provider, ritual_id_for_public_key_check
)
if bytes(current_ferveo_key) != bytes(reported_ferveo_key):
print(f"[MISMATCH] {provider} is using different key than reported")
if __name__ == "__main__":
differing_ferveo_keys()