102 lines
3.4 KiB
Python
102 lines
3.4 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 (
|
|
DHTStore,
|
|
MembershipManager,
|
|
ReplicationManager,
|
|
MetricsAggregator,
|
|
compute_node_id,
|
|
)
|
|
|
|
|
|
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 = DHTStore(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])
|