lbry-sdk/scripts/tracker.py
2021-01-18 14:20:25 -05:00

125 lines
4 KiB
Python

import asyncio
import logging
import signal
import time
from aioupnp import upnp
import sqlite3
import pickle
from os import path
from pprint import pprint
from lbry.dht import node, peer
log = logging.getLogger("lbry")
log.addHandler(logging.StreamHandler())
log.setLevel(logging.INFO)
async def main():
data_dir = "/home/grin/code/lbry/sdk"
state_file = data_dir + '/nodestate'
loop = asyncio.get_event_loop()
try:
loop.add_signal_handler(signal.SIGINT, shutdown)
loop.add_signal_handler(signal.SIGTERM, shutdown)
except NotImplementedError:
pass # Not implemented on Windows
peer_manager = peer.PeerManager(loop)
u = await upnp.UPnP.discover()
await u.get_next_mapping(4444, "UDP", "lbry dht tracker", 4444)
my_node_id = "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b"
n = node.Node(loop, peer_manager, node_id=bytes.fromhex(my_node_id), external_ip=(await u.get_external_ip()),
udp_port=4444, internal_udp_port=4444, peer_port=4444)
db = sqlite3.connect(data_dir + "/tracker.sqlite3")
db.execute(
'''CREATE TABLE IF NOT EXISTS log (hash TEXT, node_id TEXT, ip TEXT, port INT, timestamp INT)'''
)
# curr = db.cursor()
# res = curr.execute("SELECT 1, 2, 3")
# for items in res:
# print(items)
try:
known_node_urls=[("lbrynet1.lbry.com", 4444), ("lbrynet2.lbry.com", 4444), ("lbrynet3.lbry.com", 4444)]
persisted_peers =[]
if path.exists(state_file):
with open(state_file, 'rb') as f:
state = pickle.load(f)
# pprint(state.routing_table_peers)
# pprint(state.datastore)
print(f'loaded {len(state.routing_table_peers)} rt peers, {len(state.datastore)} in store')
n.load_state(state)
persisted_peers = state.routing_table_peers
n.start("0.0.0.0", known_node_urls, persisted_peers)
await n.started_listening.wait()
print("joined")
# jack = peer.make_kademlia_peer(
# bytes.fromhex("38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95c"),
# "216.19.244.226", udp_port=4444,
# )
# print(await n.protocol.get_rpc_peer(jack).ping())
await dostuff(n, db)
finally:
print("shutting down")
n.stop()
state = n.get_state()
with open(state_file, 'wb') as f:
# pprint(state.routing_table_peers)
# pprint(state.datastore)
print(f'saved {len(state.routing_table_peers)} rt peers, {len(state.datastore)} in store')
pickle.dump(state, f)
db.close()
await u.delete_port_mapping(4444, "UDP")
async def dostuff(n, db):
# gather
# as_completed
# wait
# wait_for
# make a task to loop over the things in the node. those tasks drain into one combined queue
# t = asyncio.create_task for each node
# keep the t
# handle teardown at the end
#
while True:
(node_id, ip, method, args) = await n.protocol.event_queue.get()
if method == b'store':
blob_hash, token, port, original_publisher_id, age = args[:5]
print(f"STORE from {bytes.hex(node_id)} ({ip}) for blob {bytes.hex(blob_hash)}")
try:
cur = db.cursor()
cur.execute('INSERT INTO log (hash, node_id, ip, port, timestamp) VALUES (?,?,?,?,?)',
(bytes.hex(blob_hash), bytes.hex(node_id), ip, port, int(time.time())))
db.commit()
cur.close()
except sqlite3.Error as err:
print("failed insert", err)
else:
pass
# print(f"{method} from {bytes.hex(node_id)} ({ip})")
class ShutdownErr(BaseException):
pass
def shutdown():
print("got interrupt signal...")
raise ShutdownErr()
if __name__ == "__main__":
try:
asyncio.run(main())
except ShutdownErr:
pass