예제 #1
0
class DHT:
    """docstring for Server"""
    def __init__(self, ip_address=BOOSTRAP_IP, port=BOOSTRAP_PORT):
        self.server = Server()
        self.server.listen(UDHT_PORT)

        self.loop = asyncio.get_event_loop()
        self.loop.set_debug(True)

        bootstrap_node = (ip_address, int(port))
        self.loop.run_until_complete(self.server.bootstrap([bootstrap_node]))

    def stop(self):
        self.server.stop()
        self.loop.close()

    def __getitem__(self, key):
        result = Empty()
        try:
            result = loads(self.loop.run_until_complete(self.server.get(key)))
        except TypeError:
            pass
        if isinstance(result, Empty):
            raise KeyError

        return result

    def __setitem__(self, key, item):
        self.loop.run_until_complete(self.server.set(key, dumps(item)))

    def __delitem__(self, key):
        self.loop.run_until_complete(self.server.set(key, dumps(Empty())))
예제 #2
0
        async def run_test():
            server = Server()

            def async_return(result):
                f = asyncio.Future()
                f.set_result(result)
                return f

            get_signed_value = get_signed_value_with_keys(priv_key_path='kademlia/tests/resources/key.der',
                                                          pub_key_path='kademlia/tests/resources/public.der')

            get_signed_message = get_signed_message_with_keys(priv_key_path='kademlia/tests/resources/key.der',
                                                              pub_key_path='kademlia/tests/resources/public.der')

            key_test = 'test key'
            dkey_test = digest(key_test)
            data = json.dumps(get_signed_value(dkey_test, 'data', PersistMode.SECURED).to_json())
            value = get_signed_value(dkey_test, data, PersistMode.SECURED)
            server._call_remote_persist = Mock(return_value=async_return(True))
            server.get = Mock(return_value=async_return(get_signed_message(dkey_test, data)))
            server.set_digest = Mock(return_value=async_return(True))
            Server._get_dtl_record = Mock(return_value=True)

            await server.set('test key', value)

            server.get.assert_called_with('test key')

            server.stop()
예제 #3
0
def kad_server_join(network_port, profile_port, neighbor_ip, neighbor_port,
                    username):
    handler = logging.StreamHandler()
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    handler.setFormatter(formatter)
    log = logging.getLogger('kademlia')
    log.addHandler(handler)
    log.setLevel(logging.DEBUG)

    aio = asyncio.new_event_loop()
    kad = Server()

    aio.run_until_complete(kad.listen(network_port))
    aio.run_until_complete(kad.bootstrap([(neighbor_ip, neighbor_port)]))
    aio.run_until_complete(asyncio.sleep(1))

    # set a value for the key "my-key" on the network
    aio.run_until_complete(
        kad.set(username,
                'http://' + socket.gethostname() + ':' + str(profile_port)))
    aio.run_until_complete(asyncio.sleep(2))

    # run forever since we are the first node
    try:
        main_loop(aio, kad)
    except KeyboardInterrupt:
        pass
    finally:
        kad.stop()
        aio.close()
예제 #4
0
파일: network.py 프로젝트: tarxvftech/pyM17
 async def run():
     server = Server()
     await server.listen(8469)
     bootstrap_node = (sys.argv[2], int(sys.argv[3]))
     await server.bootstrap([bootstrap_node])
     await server.set(sys.argv[4], sys.argv[5])
     server.stop()
예제 #5
0
def send(port, key, message):
    handler = logging.StreamHandler()
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    handler.setFormatter(formatter)
    log = logging.getLogger('kademlia')
    log.addHandler(handler)
    log.setLevel(logging.DEBUG)

    loop = asyncio.get_event_loop()
    loop.set_debug(True)

    server = Server()
    server.listen(8469)
    bootstrap_node = ("0.0.0.0", int(port))
    loop.run_until_complete(server.bootstrap([bootstrap_node]))
    result = loop.run_until_complete(server.get(key))

    loop.run_until_complete(
        server.set(key,
                   str(result) + str(datetime.datetime.now()) + "  " +
                   message))
    result = loop.run_until_complete(server.get(key))

    server.stop()
    #loop.close()

    print("************************************************")
    print(key, "\n", result + "\n")
    print("************************************************")
예제 #6
0
    def test_custom_protocol(self):
        """
        A subclass of Server which overrides the protocol_class attribute will
        have an instance of that class as its protocol after its listen()
        method is called.
        """

        # Make a custom Protocol and Server to go with hit.
        class CoconutProtocol(KademliaProtocol):
            pass

        class HuskServer(Server):
            protocol_class = CoconutProtocol

        # An ordinary server does NOT have a CoconutProtocol as its protocol...
        server = Server()
        server.listen(8469)
        self.assertNotIsInstance(server.protocol, CoconutProtocol)
        server.stop()

        # ...but our custom server does.
        husk_server = HuskServer()
        husk_server.listen(8469)
        self.assertIsInstance(husk_server.protocol, CoconutProtocol)
        husk_server.stop()
예제 #7
0
    def test_custom_protocol(self):
        """
        A subclass of Server which overrides the protocol_class attribute will
        have an instance of that class as its protocol after its listen()
        method is called.
        """

        # Make a custom Protocol and Server to go with hit.
        class CoconutProtocol(KademliaProtocol):
            pass

        class HuskServer(Server):
            protocol_class = CoconutProtocol

        # An ordinary server does NOT have a CoconutProtocol as its protocol...
        loop = asyncio.get_event_loop()
        server = Server()
        loop.run_until_complete(server.listen(8469))
        self.assertNotIsInstance(server.protocol, CoconutProtocol)
        server.stop()

        # ...but our custom server does.
        husk_server = HuskServer()
        loop.run_until_complete(husk_server.listen(8469))
        self.assertIsInstance(husk_server.protocol, CoconutProtocol)
        husk_server.stop()
예제 #8
0
    def test_custom_protocol(self):  # pylint: disable=no-self-use
        """
        A subclass of Server which overrides the protocol_class attribute will
        have an instance of that class as its protocol after its listen()
        method is called.
        """

        # Make a custom Protocol and Server to go with hit.
        class CoconutProtocol(KademliaProtocol):
            pass

        class HuskServer(Server):
            protocol_class = CoconutProtocol

        # An ordinary server does NOT have a CoconutProtocol as its protocol...
        loop = asyncio.get_event_loop()
        server = Server()
        loop.run_until_complete(server.listen(8469))
        assert not isinstance(server.protocol, CoconutProtocol)
        server.stop()

        # ...but our custom server does.
        husk_server = HuskServer()
        loop.run_until_complete(husk_server.listen(8469))
        assert isinstance(husk_server.protocol, CoconutProtocol)
        husk_server.stop()
예제 #9
0
def bootstrap_node(event_loop):
    server = Server()
    event_loop.run_until_complete(server.listen(8468))

    try:
        yield ('127.0.0.1', 8468)
    finally:
        server.stop()
예제 #10
0
def bootstrap_node(event_loop):
    server = Server()
    event_loop.run_until_complete(server.listen(8468))

    try:
        yield ('127.0.0.1', 8468)
    finally:
        server.stop()
예제 #11
0
async def run():
    server = Server()
    await server.listen(8469)
    bootstrap_node = (sys.argv[1], int(sys.argv[2]))
    await server.bootstrap([bootstrap_node])

    result = await server.get(sys.argv[3])
    print("Get result:", result)
    server.stop()
예제 #12
0
async def test_storing(bootstrap_node):
    server = Server()
    await server.listen(bootstrap_node[1] + 1)
    await server.bootstrap([bootstrap_node])
    await server.set('key', 'value')
    result = await server.get('key')

    assert result == 'value'

    server.stop()
예제 #13
0
async def test_storing(bootstrap_node):
    server = Server()
    await server.listen(bootstrap_node[1] + 1)
    await server.bootstrap([bootstrap_node])
    await server.set('key', 'value')
    result = await server.get('key')

    assert result == 'value'

    server.stop()
예제 #14
0
 def test_default_protocol(self):
     """
     An ordinary Server object will initially not have a protocol, but will
     have a KademliaProtocol object as its protocol after its listen()
     method is called.
     """
     server = Server()
     self.assertIsNone(server.protocol)
     server.listen(8469)
     self.assertIsInstance(server.protocol, KademliaProtocol)
     server.stop()
예제 #15
0
파일: test.py 프로젝트: mmurray22/CS244B
async def run():
    server = Server()
    await server.listen(8469)
    bootstrap_node = (sys.argv[1], int(sys.argv[2]))
    await server.bootstrap([bootstrap_node])
    await server.set(sys.argv[3], sys.argv[4])
    print("sleeping for 5 seconds")
    time.sleep(5)
    print("waking up to fetch stored value")
    result = await server.get(sys.argv[3])
    print("Get result:", result)
    server.stop()
예제 #16
0
 def test_default_protocol(self):
     """
     An ordinary Server object will initially not have a protocol, but will
     have a KademliaProtocol object as its protocol after its listen()
     method is called.
     """
     loop = asyncio.get_event_loop()
     server = Server()
     self.assertIsNone(server.protocol)
     loop.run_until_complete(server.listen(8469))
     self.assertIsInstance(server.protocol, KademliaProtocol)
     server.stop()
예제 #17
0
 def test_default_protocol(self):  # pylint: disable=no-self-use
     """
     An ordinary Server object will initially not have a protocol, but will
     have a KademliaProtocol object as its protocol after its listen()
     method is called.
     """
     loop = asyncio.get_event_loop()
     server = Server()
     assert server.protocol is None
     loop.run_until_complete(server.listen(8469))
     assert isinstance(server.protocol, KademliaProtocol)
     server.stop()
예제 #18
0
def chat(port, chatname):

    node = Server()
    node.listen(port)
    loop = asyncio.get_event_loop()
    loop.run_until_complete(node.bootstrap([("0.0.0.0", 8468)]))


    chatlist = loop.run_until_complete(node.get("chatlist"))
    loop.run_until_complete(node.set("chatlist",  str(chatlist) + "\n" + chatname + "\n"))


    node.stop()
예제 #19
0
def user(port, username):

    node = Server()
    node.listen(port)
    loop = asyncio.get_event_loop()
    loop.run_until_complete(node.bootstrap([("0.0.0.0", 8468)]))


    userlist = loop.run_until_complete(node.get("userlist"))
    loop.run_until_complete(node.set("userlist",  str(userlist) + "\n" + username + "\n"))


    node.stop()
예제 #20
0
def master_kademlia_join(loop):
    node = Server()
    loop.run_until_complete(node.listen(5678))
    try:
        msg = stamp("{} has joined the P2P network.".format(master_name))
        send_to_hub(msg)
        print(msg)
        loop.run_forever()
    except KeyboardInterrupt:
        pass
    finally:
        node.stop()
        loop.close()
    return node
예제 #21
0
def launch_bootstrap():

    server = Server()
    server.listen(8469)

    loop = asyncio.get_event_loop()
    loop.set_debug(True)

    try:
        loop.run_forever()
    except KeyboardInterrupt:
        pass
    finally:
        server.stop()
    loop.close()
    def run(self):
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        loop.set_debug(True)

        server = Server()
        loop.run_until_complete(server.listen(self.port))

        if self.bootstrap_port is not None:
            bootstrap_node = (self.bootstrap_address, self.bootstrap_port)
            loop.run_until_complete(server.bootstrap([bootstrap_node]))

        try:
            loop.run_forever()
        except KeyboardInterrupt:
            pass
        finally:
            server.stop()
        loop.close()
예제 #23
0
def send(port, chatname, username, message):

    node = Server()
    node.listen(port)
    loop = asyncio.get_event_loop()
    loop.run_until_complete(node.bootstrap([("0.0.0.0", 8468)]))

    chat = loop.run_until_complete(node.get(chatname))
    loop.run_until_complete(
        node.set(chatname,
                 str(chat) + "\n" + username + ":  " + message + "\n"))
    new_chat = loop.run_until_complete(node.get(chatname))

    node.stop()

    print("************************************************")
    print(chatname)
    print("************************************************")
    print("\n" + new_chat + "\n")
    print("************************************************")
예제 #24
0
def kad_client(neighbor_ip, neighbor_port, username):
    #handler = logging.StreamHandler()
    #formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    #handler.setFormatter(formatter)
    #log = logging.getLogger('kademlia')
    #log.addHandler(handler)
    #log.setLevel(logging.DEBUG)

    aio = asyncio.get_event_loop()
    kad = Server()

    aio.run_until_complete(kad.listen(8889))
    aio.run_until_complete(kad.bootstrap([(neighbor_ip, neighbor_port)]))

    resp = aio.run_until_complete(get_user_profile(kad, username))
    print("resp.json(): " + resp.json())
    # print(resp.json())

    kad.stop()
    aio.close()
예제 #25
0
    def test_custom_event_loop(self):
        custom_loop = asyncio.new_event_loop()
        server = Server()
        server.listen(8468)

        custom_loop = asyncio.new_event_loop()
        server2 = Server(custom_event_loop=custom_loop)

        server_thread = threading.Thread(target=setup_extra_server,
                                         args=[server2, custom_loop])
        server_thread.start()
        # testing using the custom event loop
        loop = asyncio.get_event_loop()
        loop.run_until_complete(server.bootstrap([("localhost", 8469)]))
        loop.run_until_complete(server.set("test", "test1"))
        rec_value = loop.run_until_complete(server.get("test"))
        server.stop()
        stop_extra_server(server2, custom_loop)

        server_thread.join()
        assert rec_value == "test1"
예제 #26
0
def main():
    handler = logging.StreamHandler()
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    handler.setFormatter(formatter)
    log = logging.getLogger('kademlia')
    log.addHandler(handler)
    log.setLevel(logging.DEBUG)

    server = Server()
    server.listen(1111)

    loop = asyncio.get_event_loop()
    loop.set_debug(True)

    try:
        loop.run_forever()
    except KeyboardInterrupt:
        pass
    finally:
        server.stop()
        loop.close()
        sys.exit(0)
예제 #27
0
def main(argv):
    port_given = False
    key_given = False
    set_key = False
    get_key = False
    try:
        opts, args = getopt.getopt(argv, "p:k:s:g:", ["set=", "get="])
    except getopt.GetoptError:
        print(
            "python3 new_node.py -p <port> -k <key> -s <set_value> -g <get_key>"
        )
        sys.exit(2)
    for opt, arg in opts:
        if opt == "-p":
            port_given = True
            port = arg
        elif opt == "-k":
            key_given = True
            key = arg
        elif opt in ("-s", "set="):
            set_key = True
            key_value = arg
        elif opt in ("-g", "get="):
            get_key = True
            gkey = arg

    if port_given is False:
        print(
            "python3 new_node.py -p <port> -k <key> -s <set_value> -g <get_key>"
        )
        sys.exit(1)

    node = Server()
    node.listen(port)

    # Bootstrap the node by connecting to other known nodes, in this case
    # ("0.0.0.0", 1111) is the starting node.
    loop = asyncio.get_event_loop()
    loop.run_until_complete(node.bootstrap([STARTER_NODE]))

    # set a user specified value for the user specified key on the network
    if set_key is True:
        if key_given is True:
            loop.run_until_complete(node.set(key, key_value))
        else:
            print(
                "python3 new_node.py -p <port> -k <key> -s <set_value> -g <get_key>"
            )
            sys.exit(1)

    # get the value associated with the user specified key from the network
    if key_given is True or get_key is True:
        if get_key is True:
            result = loop.run_until_complete(node.get(gkey))
            print(result)
        elif set_key is False:
            result = loop.run_until_complete(node.get(key))
            print(result)

    try:
        loop.run_forever()
    except KeyboardInterrupt:
        pass
    finally:
        node.stop()
        loop.close()
        sys.exit(0)
예제 #28
0
파일: node.py 프로젝트: arakelovaz/dht
import logging
from kademlia.network import Server

import os

rootNodeAddress = os.getenv('ROOTNODEADDRESS')
rootNodePort = int(os.getenv('ROOTNODEPORT'))

loop = asyncio.get_event_loop()

handler = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
log = logging.getLogger('kademlia')
log.addHandler(handler)
log.setLevel(logging.DEBUG)

loop.set_debug(True)
# Create a node and start listening on port 8468
node = Server()
loop.run_until_complete(node.listen(8468))
loop.run_until_complete(node.bootstrap([(rootNodeAddress, rootNodePort)])) #<<<<<< It was 8468

try:
    loop.run_forever()
except KeyboardInterrupt:
    pass
finally:
    node.stop()
    loop.close()
예제 #29
0
rootNodeAddress = os.getenv('ROOTNODEADDRESS')
rootNodePort = int(os.getenv('ROOTNODEPORT'))

handler = logging.StreamHandler()
formatter = logging.Formatter(
    '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
log = logging.getLogger('kademlia')
log.addHandler(handler)
log.setLevel(logging.DEBUG)

loop = asyncio.get_event_loop()
loop.set_debug(True)

persistentStorage = PersistentStorage(mongourl=mongoURL,
                                      db=db,
                                      collection=collection)

storageNode = Server(storage=persistentStorage)
loop.run_until_complete(storageNode.listen(8468))
loop.run_until_complete(
    storageNode.bootstrap([(rootNodeAddress, rootNodePort)]))

try:
    loop.run_forever()
except KeyboardInterrupt:
    pass
finally:
    storageNode.stop()
    loop.close()
예제 #30
0
db = os.getenv('MONGODBNAME')
collection = os.getenv('MONGOCOLLECTION')
#rootNodeAddress = os.getenv('ROOTNODEADDRESS')
rootNodePort = int(os.getenv('ROOTNODEPORT'))

handler = logging.StreamHandler()
formatter = logging.Formatter(
    '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
log = logging.getLogger('kademlia')
log.addHandler(handler)
log.setLevel(logging.DEBUG)

loop = asyncio.get_event_loop()
loop.set_debug(True)

persistentStorage = PersistentStorage(mongourl=mongoURL,
                                      db=db,
                                      collection=collection)

rootNode = Server(node_id=b'ROOT', storage=persistentStorage)
loop.run_until_complete(rootNode.listen(rootNodePort))

try:
    loop.run_forever()
except KeyboardInterrupt:
    pass
finally:
    rootNode.stop()
    loop.close()
예제 #31
0
import logging
import asyncio

from kademlia.network import Server

handler = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
log = logging.getLogger('kademlia')
log.addHandler(handler)
log.setLevel(logging.DEBUG)


loop = asyncio.get_event_loop()
loop.set_debug(True)

server = Server()
loop.run_until_complete(server.listen(8468))

try:
    loop.run_forever()
except KeyboardInterrupt:
    pass
finally:
    server.stop()
    loop.close()
예제 #32
0
class Node:
    """This is the object that should be created to start listening 
    as an active node on the network.

    Attributes:
        connecting_port: The port to connect to
        ip: The ip to connect to
        block_height: The height of the blockchain of the node
        nodes: If other nodes are connected or not
        node: The actual node
        loop: The loop tied to the node
        verified_block: Boolean that check if a block_hash is correct or not
    """
    def __init__(self, connecting_port, ip):
        """
        Create a node instance. This will start listening on the given port.

        Args:
            connecting_port: The port to connect to
            ip: The ip to connect to
        """
        self.connecting_port = connecting_port
        self.opening_port = randint(8800, 9000)
        self.TARGET_MAX = 0x0000FFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000
        self.target = 1
        self.ip = ip
        self.block_height = 0
        self.nodes_connected = None
        self.node = None
        self.loop = None
        self.verified_block = False
        if self.connecting_port is None:
            bootstrap_node = Thread(target=self.bootstrap)
            bootstrap_node.start()
        else:
            self.start_node()
            self.get_blockheight()

    def bootstrap(self):
        """Bootstrap the server by connecting to other known nodes in the network."""
        handler = logging.StreamHandler()
        formatter = logging.Formatter(
            '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        handler.setFormatter(formatter)
        log = logging.getLogger('kademlia')
        log.addHandler(handler)
        log.setLevel(logging.DEBUG)
        print("Node operating at " + str(self.opening_port))
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(self.loop)
        self.loop.set_debug(True)
        self.node = Server()
        self.loop.run_until_complete(self.node.listen(self.opening_port))
        try:
            self.loop.run_forever()
        except KeyboardInterrupt:
            pass
        finally:
            self.node.stop()
            self.loop.close()

    def start_node(self):
        """Each blackbox instance is a node which other nodes can connect to"""
        print("Node operating at " + str(self.opening_port))
        handler = logging.StreamHandler()
        formatter = logging.Formatter(
            '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        handler.setFormatter(formatter)
        log = logging.getLogger('kademlia')
        log.addHandler(handler)
        log.setLevel(logging.DEBUG)
        self.loop = asyncio.get_event_loop()
        self.loop.set_debug(True)
        self.node = Server()
        self.loop.run_until_complete(self.node.listen(self.opening_port))
        bootstrap_node = (self.ip, int(self.connecting_port))
        self.loop.run_until_complete(self.node.bootstrap([bootstrap_node]))
        self.loop.run_until_complete(self.node.set("nodes", True))

    def get_blockheight(self):
        """When other nodes join the network they need to start mining at the most
        up-to-date block"""
        block_height = self.loop.run_until_complete(
            self.node.get("block_height"))
        if self.block_height is None or block_height is None or 0:
            self.get_blockheight()
            return
        if (block_height > self.block_height):
            self.block_height = block_height

    def set_hash(self, block_hash):
        """When a new block is found, sets in the DHT the associated block_hash and block_height
        
        Args:
            block_hash: The hash of the block found by the participating node
        """
        key = "blk" + str(self.block_height)
        if self.connecting_port is None and block_hash is not None:
            asyncio.run_coroutine_threadsafe(
                self.node.set("block_height", self.block_height + 1),
                self.loop)
            asyncio.run_coroutine_threadsafe(self.node.set(key, block_hash),
                                             self.loop)
        elif block_hash is not None and self.block_height is not 0:
            self.loop.run_until_complete(
                self.node.set("block_height", self.block_height + 1))
            self.loop.run_until_complete(self.node.set(key, block_hash))

    def get_last_block(self):
        key = "blk" + str(self.block_height)
        if self.connecting_port is None:
            return asyncio.run_coroutine_threadsafe(self.node.get(key),
                                                    self.loop)
        return self.loop.run_until_complete(self.node.get(key))

    def broadcast(self, hash_broadcasted, difficulty):
        """
        Args:
            hash_broadcasted: The hash that a node broadcasted to the network
            difficulty: The current difficulty on the network
        """
        if self.connecting_port is None:
            hash_broadcasted = hash_broadcasted.result()
        if hash_broadcasted is not None:
            self.target = self.TARGET_MAX / difficulty
            if int(hash_broadcasted, 16) < int(self.target):
                if self.connecting_port is None:
                    asyncio.run_coroutine_threadsafe(
                        self.node.set("verified_block", True), self.loop)
                else:
                    self.loop.run_until_complete(
                        self.node.set("verified_block", True))
                return True
        return False

    def verify(self, difficulty):
        """Verify if a block_hash found by a node is a correct one

        Args:
            difficulty: The current difficulty of the network
        """
        key = "blk" + str(self.block_height)
        if self.connecting_port is None:
            self.nodes_connected = asyncio.run_coroutine_threadsafe(
                self.node.get("nodes"), self.loop)
            if self.nodes_connected.result() is not True:
                asyncio.run_coroutine_threadsafe(
                    self.node.set("verified_block", True), self.loop)
                return True
            else:
                hash_broadcasted = asyncio.run_coroutine_threadsafe(
                    self.node.get(key), self.loop)
                return (self.broadcast(hash_broadcasted, difficulty))
        else:
            hash_broadcasted = self.loop.run_until_complete(self.node.get(key))
            return (self.broadcast(hash_broadcasted, difficulty))
예제 #33
0
class IPFSNode():
    def __init__(self, bootstrapHost: str = 'bootstrap'):
        self.server = Server()
        self.server.listen(8469)
        self.has_list = []

        # Hack to get the "deafult" IP
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(('1.1.1.1', 80))
        self.local_ip = s.getsockname()[0]
        s.close()

        #self.local_ip = socket.gethostbyname(socket.gethostname())
        bootstrap_ip = socket.gethostbyname(bootstrapHost)
        self.bootstrap_node = (bootstrap_ip, 8469)

        self.loop = asyncio.get_event_loop()
        self.loop.set_debug(True)

        self.loop.run_until_complete(
            self.server.bootstrap([self.bootstrap_node]))

        neighbors = self.server.bootstrappableNeighbors()

        for node in neighbors:
            print("DHT Peer found! {0}:{1}".format(node[0], node[1]))

        print("Starting TCP transfer server")
        self.tcpThread = threading.Thread(target=self.startTCPServer)
        self.tcpThread.start()

    def startTCPServer(self):
        host = '0.0.0.0'
        port = 9528
        self.running = True
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        s.bind((host, port))
        s.listen(10)

        while self.running:
            conn, addr = s.accept()
            print("Connection from " + str(addr))
            sys.stdout.flush()
            while 1:
                data = conn.recv(4096)
                if not data:
                    break
                # Check if data is correct format
                data = data.decode('utf-8')
                if (len(data) == 133
                        or len(data) == 134) and data[0:5] == 'hash=':
                    requestedHash = data[5:134]
                    print("looking for hash " + requestedHash)
                    sys.stdout.flush()
                    #Find requested hash in our data
                    found = False
                    for has_chunk in self.has_list:
                        if has_chunk[1] in requestedHash:
                            conn.send(has_chunk[0])  #Send the found data
                            found = True
                            break

                    if not found:
                        conn.send(b"notfound")
                else:
                    conn.send(b"invalid_request")
                print("Request: " + data)
                sys.stdout.flush()

            conn.close()
        s.close()

    def chunkFile(self, data: str):
        chunks = []
        for i in range(0, len(data), block_size):
            chunk = data[i:i + block_size]
            hsh = hashlib.sha512(chunk).hexdigest()
            chunks.append({"data": chunk, "hash": hsh, "size": len(chunk)})
        return chunks

    def setDHTKey(self, key: str, val: str):
        self.loop.run_until_complete(self.server.set(key, val))

    def getDHTKey(self, key: str) -> str:
        return self.loop.run_until_complete(self.server.get(key))

    def addFile(self, filepath: str, compression: bool):
        with open(filepath, 'rb') as f:
            data = f.read()
            fileHash = hashlib.sha512(data).hexdigest()
            fileLen = len(data)

            if compression:  #Compress data if necessary
                data = zlib.compress(data, level=7)

            fileChunks = self.chunkFile(data)
            fileName = os.path.basename(filepath)

            ipfsList = List(fileHash, fileName, fileLen, compression)
            ipfsBlobs = []

            for chunk in fileChunks:
                ipfsBlob = Blob()
                ipfsBlob.setData(chunk['data'], chunk['hash'])
                ipfsBlobs.append(ipfsBlob)

                ipfsList.addLink(chunk['hash'], chunk['size'])

                #Add data to our has list
                self.has_list.append((chunk['data'], chunk['hash']))

            print(ipfsList)
            if debug:
                print(ipfsList.getData())
                print("\n\n\n")
                for blob in ipfsBlobs:
                    print(blob.getData())
            if self.server:
                #Need to add data onto DHT network

                self.setDHTKey(fileHash,
                               str(ipfsList))  #Add master file record to DHT

                for blob in ipfsBlobs:  #Add items onto DHT
                    block = blob.getData()
                    if len(
                            block['data']
                    ) > 1024:  #If the block is bigger than 1k, add to local TCP server
                        self.setDHTKey(block['hash'], 'ip=' + self.local_ip)
                    else:  #Otherwise store directly on DHT
                        self.setDHTKey(blob.getData()['hash'],
                                       blob.getData()['data'])

                return fileHash

    def TCPGet(self, host, hsh):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((host, 9528))
        if not isinstance(hsh, bytes):
            hsh = hsh.encode()

        s.send(b'hash=' + hsh + b'\n')
        data = s.recv(8192)
        s.close()

        return data

    def getFile(self, hsh: str) -> (bytes, dict):
        masterFileRecord = self.getDHTKey(hsh)  #Get metadata
        metadata = None

        #Convert from string dictionary to python dictionary
        if masterFileRecord and len(masterFileRecord) > 1:
            masterFileRecord = masterFileRecord.replace("'", "\"").replace(
                'True', 'true').replace('False',
                                        'false')  #transform into valid JSON
            metadata = json.loads(masterFileRecord)
        else:
            raise Exception("Unable to locate file record on network!")

        fileContents = b''
        for link in metadata['links']:
            DHTData = self.getDHTKey(link['hash'])
            data = None
            if not DHTData:
                raise Exception("Unable to get part of file with hash " +
                                link['hash'])

            if DHTData[0:3] == 'ip=':  #Need to get data via TCP not DHT
                data = self.TCPGet(DHTData[3:], link['hash'])
            else:
                data = DHTData

            if len(data) != link['size']:
                raise Exception(
                    "Hash value ({}) has invalid or corrupted length".format(
                        link['hash']))

            fileContents += data

        if metadata['compression']:
            fileContents = zlib.decompress(fileContents)
        return (fileContents, metadata)

    def __del__(self):
        self.server.stop()
        self.loop.close()
        self.tcpThread.join()
예제 #34
0
import asyncio
import sys

from kademlia.network import Server
from kademlia.routing import RoutingTable

handler = logging.StreamHandler()
formatter = logging.Formatter(
    '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
log = logging.getLogger('kademlia')
log.addHandler(handler)
log.setLevel(logging.DEBUG)

loop = asyncio.get_event_loop()
loop.set_debug(True)

server = Server()
server.listen(8469)
bootstrap_node = ('127.0.0.1', 8468)
loop.run_until_complete(server.bootstrap([bootstrap_node]))

#loop.run_until_complete(server.set("key", "a"*1024*4))

print(server.bootstrappableNeighbors())

result = loop.run_until_complete(server.get('key'))
server.stop()
loop.close()

print("Get result:", result)
class KademliaServer:
    def __init__(self, ip, port):
        self.ip = ip
        self.port = port
        self.loop = None

    def start_server(self, bootstrap_nodes):
        handler = logging.StreamHandler()
        formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s'
                                      '- %(message)s')
        handler.setFormatter(formatter)

        # DEBUG
        if DEBUG:
            log = logging.getLogger('kademlia')
            log.addHandler(handler)
            log.setLevel(logging.DEBUG)

        self.loop = asyncio.get_event_loop()
        if DEBUG:
            self.loop.set_debug(True)

        self.server = Server()
        self.loop.run_until_complete(self.server.listen(self.port))
        self.loop.run_until_complete(self.server.bootstrap(bootstrap_nodes))

        return self.loop

    def close_server(self):
        self.server.stop()

    async def register(self, username):
        result = await self.server.get(username)
        if result is None:
            value = {
                "followers": [],
                "following": {},
                "redirect": {},
                "msg_nr": 0,
                "ip": self.ip,
                "port": self.port
            }
            value_to_set = json.dumps(value)
            await self.server.set(username, value_to_set)
            return value

        else:
            raise Exception("Username already exists")

    async def login(self, username):
        result = await self.server.get(username)
        result = json.loads(result)

        if result is not None:
            value = {
                "followers": result['followers'],
                "following": result['following'],
                "redirect": result['redirect'],
                "msg_nr": result['msg_nr'],
                "ip": self.ip,
                "port": self.port
            }
            value_to_set = json.dumps(value)
            await self.server.set(username, value_to_set)
            return value

        else:
            raise Exception("User doesn't exist! Please register")

    async def get_user_ip(self, username):
        result = await self.server.get(username)
        result = json.loads(result)

        if result is None:
            raise Exception("User doesn't exist!")
        else:
            return (result["ip"], result["port"])

    async def get_user_ip_msgnr(self, username):
        result = await self.server.get(username)
        result = json.loads(result)

        if result is None:
            raise Exception("User doesn't exist!")
        else:
            return (result["ip"], result["port"], result["msg_nr"])

    async def get_location_and_followers(self, usernames):
        res = {}
        for username in usernames:
            result = await self.server.get(username)
            result = json.loads(result)

            if result is not None:
                res[username] = (result["ip"],
                                 result["port"],
                                 result["followers"])

        return res

    async def get_user_followers(self, username):
        followers = {}

        result = await self.get_user(username)

        for follower in result["followers"]:
            result = await self.server.get(follower)
            result = json.loads(result)

            if result is not None:
                followers[follower] = (result["ip"],
                                       result["port"],
                                       result["followers"])

        return followers

    async def get_users_following_user(self, user):
        user = await self.get_user(user)
        user_followers = user['followers']
        return user_followers

    async def get_outdated_user_following(self, following):
        res = []

        for follw, info in following.items():

            user_knowledge = info[0]
            result = await self.server.get(follw)
            result = json.loads(result)
            if (result is not None) and result['msg_nr'] > user_knowledge:
                res.append((follw, result["ip"], result["port"],
                            result["msg_nr"]))

        return res

    async def get_user_following(self, state):
        following = {}

        result = await self.get_user(username)

        for follw in result["following"]:
            result = await self.server.get(follw)
            result = json.loads(result)
            if result is not None:
                following[follw] = (result["ip"],
                                    result["port"])

        return following

    async def get_user(self, username):
        result = await self.server.get(username)
        result = json.loads(result)
        return result

    async def set_user(self, username, value):
        await self.server.set(username, value)