def main(): parser = argparse.ArgumentParser( description="Launch a dht node which responds to rpc commands") parser.add_argument( "node_port", help=("The UDP port on which the node will listen for connections " "from other dht nodes"), type=int) parser.add_argument( "rpc_port", help="The TCP port on which the node will listen for rpc commands", type=int) parser.add_argument( "dht_bootstrap_host", help="The IP of a DHT node to be used to bootstrap into the network", nargs='?') parser.add_argument( "dht_bootstrap_port", help="The port of a DHT node to be used to bootstrap into the network", nargs='?', default=4000, type=int) parser.add_argument( "--rpc_ip_address", help="The network interface on which to listen for rpc connections", default="127.0.0.1") args = parser.parse_args() def start_rpc(): rpc_node = RPCNode(node, shut_down) reactor.listenTCP(args.rpc_port, server.Site(rpc_node), interface=args.rpc_ip_address) def shut_down(): d = defer.maybeDeferred(node.stop) d.addBoth(lambda _: reactor.stop()) return d known_nodes = [] if args.dht_bootstrap_host: known_nodes.append((args.dht_bootstrap_host, args.dht_bootstrap_port)) node = Node(udpPort=args.node_port) node.joinNetwork(known_nodes) d = node._joinDeferred d.addCallback(lambda _: start_rpc()) reactor.run()
def join_network(udp_port, known_nodes): lbryid = generate_id() log.info('Creating node') node = Node(udpPort=udp_port, node_id=lbryid) log.info('Joining network') yield node.joinNetwork(known_nodes) defer.returnValue(node)
def join_network(udp_port, known_nodes): lbryid = generate_id() log.info('Creating node') node = Node(udpPort=udp_port, node_id=lbryid) log.info('Joining network') yield node.joinNetwork(known_nodes) defer.returnValue(node)
def main(): parser = argparse.ArgumentParser(description="Launch a dht node which responds to rpc commands") parser.add_argument("node_port", help=("The UDP port on which the node will listen for connections " "from other dht nodes"), type=int) parser.add_argument("rpc_port", help="The TCP port on which the node will listen for rpc commands", type=int) parser.add_argument("dht_bootstrap_host", help="The IP of a DHT node to be used to bootstrap into the network", nargs='?') parser.add_argument("dht_bootstrap_port", help="The port of a DHT node to be used to bootstrap into the network", nargs='?', default=4000, type=int) parser.add_argument("--rpc_ip_address", help="The network interface on which to listen for rpc connections", default="127.0.0.1") args = parser.parse_args() def start_rpc(): rpc_node = RPCNode(node, shut_down) reactor.listenTCP(args.rpc_port, server.Site(rpc_node), interface=args.rpc_ip_address) def shut_down(): d = defer.maybeDeferred(node.stop) d.addBoth(lambda _: reactor.stop()) return d known_nodes = [] if args.dht_bootstrap_host: known_nodes.append((args.dht_bootstrap_host, args.dht_bootstrap_port)) node = Node(udpPort=args.node_port) node.joinNetwork(known_nodes) d = node._joinDeferred d.addCallback(lambda _: start_rpc()) reactor.run()
def join_network(udp_port, known_nodes): lbryid = generate_id() log.info('Creating Node...') node = Node(udpPort=udp_port, lbryid=lbryid) log.info('Joining network...') d = node.joinNetwork(known_nodes) def log_network_size(): log.info("Approximate number of nodes in DHT: %s", str(node.getApproximateTotalDHTNodes())) log.info("Approximate number of blobs in DHT: %s", str(node.getApproximateTotalHashes())) d.addCallback(lambda _: log_network_size()) d.addCallback(lambda _: node) return d
def join_network(udp_port, known_nodes): lbryid = generate_id() log.info('Creating Node') node = Node(udpPort=udp_port, lbryid=lbryid) log.info('Joining network') d = node.joinNetwork(known_nodes) def log_network_size(): log.info("Approximate number of nodes in DHT: %s", str(node.getApproximateTotalDHTNodes())) log.info("Approximate number of blobs in DHT: %s", str(node.getApproximateTotalHashes())) d.addCallback(lambda _: log_network_size()) d.addCallback(lambda _: node) return d
def run(): nodeid = "9648996b4bef3ff41176668a0577f86aba7f1ea2996edd18f9c42430802c8085331345c5f0c44a7f352e2ba8ae59aaaa".decode( "hex") node = Node(node_id=nodeid, externalIP='127.0.0.1', udpPort=21999, peerPort=1234) node.startNetwork() yield node.joinNetwork([("127.0.0.1", 21001)]) print "" print "" print "" print "" print "" print "" yield node.announceHaveBlob( "2bb150cb996b4bef3ff41176648a0577f86abb7f1ea2996edd18f9c42430802c8085331345c5f0c44a7f352e2ba8ae59" .decode("hex")) log.info("Shutting down...") reactor.callLater(1, reactor.stop)
for line in lines: ipAddress, udpPort = line.split() knownNodes.append((ipAddress, int(udpPort))) else: knownNodes = None print '\nNOTE: You have not specified any remote DHT node(s) to connect to' print 'It will thus not be aware of any existing DHT, but will still function as' print ' a self-contained DHT (until another node contacts it).' print 'Run this script without any arguments for info.\n' # Set up SQLite-based data store (you could use an in-memory store instead, for example) # # Create the Entangled node. It extends the functionality of a # basic Kademlia node (but is fully backwards-compatible with a # Kademlia-only network) # # If you wish to have a pure Kademlia network, use the # entangled.kademlia.node.Node class instead print 'Creating Node' node = Node(udpPort=int(sys.argv[1]), lbryid=lbryid) # Schedule the node to join the Kademlia/Entangled DHT node.joinNetwork(knownNodes) # Schedule the "storeValue() call to be invoked after 2.5 seconds, # using KEY and VALUE as arguments twisted.internet.reactor.callLater(2.5, getValue) # Start the Twisted reactor - this fires up all networking, and # allows the scheduled join operation to take place print 'Twisted reactor started (script will commence in 2.5 seconds)' twisted.internet.reactor.run()
class NodeRPC(AuthJSONRPCServer): def __init__(self, lbryid, seeds, node_port, rpc_port): AuthJSONRPCServer.__init__(self, False) self.root = None self.port = None self.seeds = seeds self.node_port = node_port self.rpc_port = rpc_port if lbryid: lbryid = lbryid.decode('hex') else: lbryid = generate_id() self.node_id = lbryid self.external_ip = get_external_ip_and_setup_upnp() self.node_port = node_port @defer.inlineCallbacks def setup(self): self.node = Node(node_id=self.node_id, udpPort=self.node_port, externalIP=self.external_ip) hosts = [] for hostname, hostport in self.seeds: host_ip = yield reactor.resolve(hostname) hosts.append((host_ip, hostport)) log.info("connecting to dht") yield self.node.joinNetwork(tuple(hosts)) log.info("connected to dht") if not self.announced_startup: self.announced_startup = True self.start_api() log.info("lbry id: %s (%i bytes)", self.node.node_id.encode('hex'), len(self.node.node_id)) def start_api(self): root = resource.Resource() root.putChild('', self) self.port = reactor.listenTCP(self.rpc_port, Site(root), interface='localhost') log.info("started jsonrpc server") @defer.inlineCallbacks def jsonrpc_node_id_set(self, node_id): old_id = self.node.node_id self.node.stop() del self.node self.node_id = node_id.decode('hex') yield self.setup() msg = "changed dht id from %s to %s" % ( old_id.encode('hex'), self.node.node_id.encode('hex')) defer.returnValue(msg) def jsonrpc_node_id_get(self): return self._render_response(self.node.node_id.encode('hex')) @defer.inlineCallbacks def jsonrpc_peer_find(self, node_id): node_id = node_id.decode('hex') contact = yield self.node.findContact(node_id) result = None if contact: result = (contact.address, contact.port) defer.returnValue(result) @defer.inlineCallbacks def jsonrpc_peer_list_for_blob(self, blob_hash): peers = yield self.node.getPeersForBlob(blob_hash.decode('hex')) defer.returnValue(peers) @defer.inlineCallbacks def jsonrpc_ping(self, node_id): contact_host = yield self.jsonrpc_peer_find(node_id=node_id) if not contact_host: defer.returnValue("failed to find node") contact_ip, contact_port = contact_host contact = Contact(node_id.decode('hex'), contact_ip, contact_port, self.node._protocol) try: result = yield contact.ping() except TimeoutError: self.node.removeContact(contact.id) self.node._dataStore.removePeer(contact.id) result = {'error': 'timeout'} defer.returnValue(result) def get_routing_table(self): result = {} data_store = deepcopy(self.node._dataStore._dict) datastore_len = len(data_store) hosts = {} missing_contacts = [] if datastore_len: for k, v in data_store.iteritems(): for value, lastPublished, originallyPublished, originalPublisherID in v: try: contact = self.node._routingTable.getContact( originalPublisherID) except ValueError: if originalPublisherID.encode( 'hex') not in missing_contacts: missing_contacts.append( originalPublisherID.encode('hex')) continue if contact in hosts: blobs = hosts[contact] else: blobs = [] blobs.append(k.encode('hex')) hosts[contact] = blobs contact_set = [] blob_hashes = [] result['buckets'] = {} for i in range(len(self.node._routingTable._buckets)): for contact in self.node._routingTable._buckets[i]._contacts: contacts = result['buckets'].get(i, []) if contact in hosts: blobs = hosts[contact] del hosts[contact] else: blobs = [] host = { "address": contact.address, "id": contact.id.encode("hex"), "blobs": blobs, } for blob_hash in blobs: if blob_hash not in blob_hashes: blob_hashes.append(blob_hash) contacts.append(host) result['buckets'][i] = contacts contact_set.append(contact.id.encode("hex")) if hosts: result['datastore extra'] = [{ "id": host.id.encode('hex'), "blobs": hosts[host], } for host in hosts] result['missing contacts'] = missing_contacts result['contacts'] = contact_set result['blob hashes'] = blob_hashes result['node id'] = self.node_id.encode('hex') return result def jsonrpc_routing_table_get(self): return self._render_response(self.get_routing_table())
for line in lines: ipAddress, udpPort = line.split() knownNodes.append((ipAddress, int(udpPort))) else: knownNodes = None print '\nNOTE: You have not specified any remote DHT node(s) to connect to' print 'It will thus not be aware of any existing DHT, but will still function as' print ' a self-contained DHT (until another node contacts it).' print 'Run this script without any arguments for info.\n' # Set up SQLite-based data store (you could use an in-memory store instead, for example) # # Create the Entangled node. It extends the functionality of a # basic Kademlia node (but is fully backwards-compatible with a # Kademlia-only network) # # If you wish to have a pure Kademlia network, use the # entangled.kademlia.node.Node class instead print 'Creating Node' node = Node(udpPort=int(sys.argv[1]), node_id=lbryid) # Schedule the node to join the Kademlia/Entangled DHT node.joinNetwork(knownNodes) # Schedule the "storeValue() call to be invoked after 2.5 seconds, # using KEY and VALUE as arguments twisted.internet.reactor.callLater(2.5, getValue) # Start the Twisted reactor - this fires up all networking, and # allows the scheduled join operation to take place print 'Twisted reactor started (script will commence in 2.5 seconds)' twisted.internet.reactor.run()