uploader-bot/app/core/models/memory.py

102 lines
3.5 KiB
Python

import asyncio
from contextlib import asynccontextmanager
from datetime import datetime
from datetime import timedelta
from aiogram import Bot
from app.core._utils.b58 import b58encode
from app.core._config import TELEGRAM_API_KEY, CLIENT_TELEGRAM_API_KEY
from app.core._crypto.signer import Signer
from app.core._secrets import hot_pubkey, hot_seed
from app.core.logger import make_log
from app.core.network.dht import (
MembershipManager,
ReplicationManager,
MetricsAggregator,
compute_node_id,
)
from app.core.network.dht.store import PersistentDHTStore
class Memory:
def __init__(self):
self._execute_queue = []
self._delayed_queue = {}
self.transactions_disabled = False
self.known_states = {
"uploader_daemon": {
"status": "no status",
"timestamp": None
},
"indexer": {
"status": "no status",
"timestamp": None
},
'licenses': {
'status': 'no status',
'timestamp': None
},
"ton_daemon": {
"status": "no status",
"timestamp": None
},
'convert_service': {
'status': 'no status',
'timestamp': None
}
}
self._telegram_bot = Bot(TELEGRAM_API_KEY)
self._client_telegram_bot = Bot(CLIENT_TELEGRAM_API_KEY)
# Network handshake guards
self._handshake_rl = {"minute": 0, "counts": {}}
self._handshake_nonces = {}
# Decentralised storage components
self.node_id = compute_node_id(hot_pubkey)
self.signer = Signer(hot_seed)
self.dht_store = PersistentDHTStore(self.node_id, self.signer)
self.membership = MembershipManager(self.node_id, self.signer, self.dht_store)
self.replication = ReplicationManager(self.node_id, self.signer, self.dht_store)
self.metrics = MetricsAggregator(self.node_id, self.signer, self.dht_store)
self.membership.register_local(public_key=b58encode(hot_pubkey).decode(), ip=None, asn=None)
@asynccontextmanager
async def transaction(self, desc=""):
make_log("Memory.transaction", f"Starting transaction; {desc}", level='debug')
while self.transactions_disabled:
await asyncio.sleep(.2)
self.transactions_disabled = True
try:
yield None
except BaseException as e:
self.transactions_disabled = False
make_log("Memory.transaction", f"Transaction error: {e}", level='error')
raise e
self.transactions_disabled = False
make_log("Memory.transaction", f"Transaction finished; {desc}", level='debug')
def add_task(self, _fn, *args, **kwargs):
try:
if type(kwargs.get("delay_s")) in [int, float]:
kwargs['execute_ts'] = (datetime.now() + timedelta(seconds=kwargs.pop('delay_s'))).timestamp()
_execute_ts = kwargs.pop('execute_ts')
_execute_ts = int(_execute_ts)
assert _execute_ts > 0
while _execute_ts in self._delayed_queue:
_execute_ts += .01
self._delayed_queue[_execute_ts] = [_fn, args, kwargs]
except (KeyError, ValueError, AssertionError) as e:
if not ("execute_ts" in str(e)):
make_log("Queue.add_task", f"Error when adding task to memory: {e}", level='error')
self._execute_queue.append([_fn, args, kwargs])