2023-11-01 14:02:29 +02:00
|
|
|
import os
|
|
|
|
|
import logging
|
|
|
|
|
from tenacity import retry, stop_after_delay, wait_fixed
|
2023-11-03 17:01:00 +02:00
|
|
|
from src.node.api_clients.rpc import RPC
|
|
|
|
|
from src.node.api_clients.rest import REST
|
2023-11-01 14:02:29 +02:00
|
|
|
from src.node.docker_mananger import DockerManager
|
2023-11-03 17:01:00 +02:00
|
|
|
from src.env_vars import LOG_DIR, DEFAULT_PUBSUBTOPIC, PROTOCOL
|
2023-11-01 14:02:29 +02:00
|
|
|
from src.data_storage import DS
|
|
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class WakuNode:
|
2023-11-01 16:44:42 +02:00
|
|
|
def __init__(self, docker_image, docker_log_prefix=""):
|
2023-11-01 14:02:29 +02:00
|
|
|
self._image_name = docker_image
|
2023-11-01 16:44:42 +02:00
|
|
|
self._log_path = os.path.join(LOG_DIR, f"{docker_log_prefix}__{self._image_name.replace('/', '_')}.log")
|
2023-11-01 14:02:29 +02:00
|
|
|
self._docker_manager = DockerManager(self._image_name)
|
|
|
|
|
self._container = None
|
|
|
|
|
self._ext_ip = self._docker_manager.generate_random_ext_ip()
|
2023-11-03 17:01:00 +02:00
|
|
|
self._ports = self._docker_manager.generate_ports()
|
|
|
|
|
self._rest_port = self._ports[0]
|
|
|
|
|
self._rpc_port = self._ports[1]
|
|
|
|
|
self._websocket_port = self._ports[2]
|
|
|
|
|
logger.debug("WakuNode instance initialized with log path %s", self._log_path)
|
|
|
|
|
if PROTOCOL == "RPC":
|
|
|
|
|
self._api = RPC(self._rpc_port, self._image_name)
|
|
|
|
|
elif PROTOCOL == "REST":
|
|
|
|
|
self._api = REST(self._rest_port)
|
|
|
|
|
else:
|
|
|
|
|
raise ValueError(f"Unknown protocol: {PROTOCOL}")
|
2023-11-01 14:02:29 +02:00
|
|
|
|
|
|
|
|
@retry(stop=stop_after_delay(5), wait=wait_fixed(0.1), reraise=True)
|
|
|
|
|
def start(self, **kwargs):
|
|
|
|
|
logger.debug("Starting Node...")
|
|
|
|
|
self._docker_manager.create_network()
|
|
|
|
|
|
|
|
|
|
default_args = {
|
|
|
|
|
"listen-address": "0.0.0.0",
|
|
|
|
|
"rpc": "true",
|
|
|
|
|
"rpc-admin": "true",
|
2023-11-03 17:01:00 +02:00
|
|
|
"rest": "true",
|
|
|
|
|
"rest-admin": "true",
|
2023-11-01 14:02:29 +02:00
|
|
|
"websocket-support": "true",
|
|
|
|
|
"log-level": "TRACE",
|
2023-11-03 17:01:00 +02:00
|
|
|
"websocket-port": str(self._ports[3]),
|
|
|
|
|
"rpc-port": self._rpc_port,
|
|
|
|
|
"rest-port": self._rest_port,
|
|
|
|
|
"tcp-port": str(self._ports[2]),
|
|
|
|
|
"discv5-udp-port": str(self._ports[4]),
|
2023-11-01 14:02:29 +02:00
|
|
|
"rpc-address": "0.0.0.0",
|
2023-11-03 17:01:00 +02:00
|
|
|
"rest-address": "0.0.0.0",
|
2023-11-01 14:02:29 +02:00
|
|
|
"nat": f"extip:{self._ext_ip}",
|
2023-11-03 17:01:00 +02:00
|
|
|
"pubsub-topic": DEFAULT_PUBSUBTOPIC,
|
2023-11-01 14:02:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if "go-waku" in self._docker_manager.image:
|
|
|
|
|
go_waku_args = {
|
|
|
|
|
"min-relay-peers-to-publish": "0",
|
|
|
|
|
"legacy-filter": "false",
|
|
|
|
|
"log-level": "DEBUG",
|
|
|
|
|
}
|
|
|
|
|
default_args.update(go_waku_args)
|
|
|
|
|
|
|
|
|
|
for key, value in kwargs.items():
|
|
|
|
|
key = key.replace("_", "-")
|
|
|
|
|
default_args[key] = value
|
|
|
|
|
|
2023-11-03 17:01:00 +02:00
|
|
|
self._container = self._docker_manager.start_container(self._docker_manager.image, self._ports, default_args, self._log_path, self._ext_ip)
|
|
|
|
|
logger.debug(
|
|
|
|
|
"Started container from image %s. RPC: %s REST: %s WebSocket: %s", self._image_name, self._rpc_port, self._rest_port, self._websocket_port
|
|
|
|
|
)
|
2023-11-01 14:02:29 +02:00
|
|
|
DS.waku_nodes.append(self)
|
|
|
|
|
try:
|
2023-11-03 17:01:00 +02:00
|
|
|
self.ensure_ready()
|
2023-11-01 14:02:29 +02:00
|
|
|
except Exception as e:
|
2023-11-03 17:01:00 +02:00
|
|
|
logger.error("%s service did not become ready in time: %s", PROTOCOL, e)
|
2023-11-01 14:02:29 +02:00
|
|
|
raise
|
|
|
|
|
|
|
|
|
|
@retry(stop=stop_after_delay(5), wait=wait_fixed(0.1), reraise=True)
|
|
|
|
|
def stop(self):
|
|
|
|
|
if self._container:
|
|
|
|
|
logger.debug("Stopping container with id %s", self._container.short_id)
|
|
|
|
|
self._container.stop()
|
|
|
|
|
logger.debug("Container stopped.")
|
|
|
|
|
|
|
|
|
|
@retry(stop=stop_after_delay(5), wait=wait_fixed(0.05), reraise=True)
|
2023-11-03 17:01:00 +02:00
|
|
|
def ensure_ready(self):
|
2023-11-01 14:02:29 +02:00
|
|
|
self.info()
|
|
|
|
|
logger.debug("RPC service is ready.")
|
|
|
|
|
|
|
|
|
|
def info(self):
|
2023-11-03 17:01:00 +02:00
|
|
|
return self._api.info()
|
2023-11-01 14:02:29 +02:00
|
|
|
|
|
|
|
|
def set_subscriptions(self, pubsub_topics=[DEFAULT_PUBSUBTOPIC]):
|
2023-11-03 17:01:00 +02:00
|
|
|
return self._api.set_subscriptions(pubsub_topics)
|
2023-11-01 14:02:29 +02:00
|
|
|
|
|
|
|
|
def send_message(self, message, pubsub_topic=DEFAULT_PUBSUBTOPIC):
|
2023-11-03 17:01:00 +02:00
|
|
|
return self._api.send_message(message, pubsub_topic)
|
2023-11-01 14:02:29 +02:00
|
|
|
|
|
|
|
|
def get_messages(self, pubsub_topic=DEFAULT_PUBSUBTOPIC):
|
2023-11-03 17:01:00 +02:00
|
|
|
return self._api.get_messages(pubsub_topic)
|