Coder Social home page Coder Social logo

python-p2p-network's Introduction

Badges Badges Badges Badges

Python implementation of a peer-to-peer decentralized network

This project provides a basic and simple peer-to-peer decentralized network classes (framework) to build your own network. Basic functionality of the nodes and the connection to and from these nodes has been implemented. Application specific functionality is up to you to implement yourself. The intention of the module is to provide a good basis, without specific implementation, so everyone is really free to implement like they would like to do.

You can use the project to implement a peer-to-peer decentralized network application, like Bitcoin or file sharing applications. I have used this software to provide my students, during a technical introduction to Blockchain, basic functionality. So, they were able to focus on how they would like to implement the Blockchain functionality and protocols. Without some direction from my side. Some of the students have used the code base to implement their application in C# or C++, for example. That is the freedom I would like to give to everyone.

To install the package for you to use (https://pypi.org/project/p2pnetwork/):

pip install p2pnetwork

See p2pnetwork in action https://github.com/macsnoeren/python-p2p-secure-node. This SecureNode implements a node that communicates securely between the nodes. A good example how a specific application is created by using this framework.

Evolution of the software

While I started this project in the year 2018, it was mainly focussed to provide my students some software to be able to implement a peer-to-peer decentralized network. Without the hassle to design and create everything by themselves. While I did not have any experience with Python yet and there was not much time, I put everything in place in a very large pace. One of my students was annoyed by the camelCase programming style, while the Python community uses PEP-8. So, Christian decided to help me out and structured the software to the PEP style. Two years later, Samuel decided to clean up the code and create a real module from it. From then, I decided to jump in again and made the proposed changes, while maintaining the intention of the software: basic peer-to-peer decentralized functionality without specific implementation of protocols, so the programmer is able to freely implement these on their own. I still think that the software is a good basis and already have a new goal to use this software for a decentralized security application.

On github I was wandering around and noticed that others contributed as well to the code. No pull request, but still nice things. Therefore, I have not transformed the Python software to a package to be available on pypi.org. Anyway, thanks for all the collaboration and I hope you will still help me out and others will join as well. It is possible to develop more specific applications by other modules and classes. Adding these to the repository will create a nice overview about the possibilities of these kind of applications.

Design

At first glance, peer-to-peer decentralized network applications are complex and difficult. While you need to provide some networking functionality on application level, the architecture is really simple. You have a network of the "same" nodes. The "same" means the same application (or an application that implements the same protocol).

Nodes are connected with each other. This means that each node provides a TCP/IP server on a specific port to provide inbound nodes to connect. The same node is able to connect to other nodes; called outbound nodes. When a node has a lot of connections with nodes in the network, the node will get most likely the required messages. You are able to send a message over the TCP/IP channel to the connected (inbound and outbound) nodes. How they react to the messages is in your hands. When you would like to implement discovery, meaning to see which nodes are connected within the network and see if you would like to connect to those, you need to relay this message to the other nodes connected to you. Note that you need to make sure that the messages will not echo around, but that you keep track which messages you have received.

How to optimize these node connections depend on what you would like to solve. When providing file sharing, you would like to have a lot of connections when nodes have a large bandwith. However, when you are running Bitcoin, you would like to have your connections spread over the world to minimize the single identity problem.

You have two options

Because of my lack of Python experience, I started off with an event scheme that is used within C. When an event occurred, a callback function is called with the necessary variables to be able to process the request and implement the network protocol you desire.

However, having a class and being able to extend the class with your own implementation is much nicer. Therefore, I started to change the code towards this new scheme. While maintaining the callback functionality, while my students where already busy. I could not let them be victim from my changes.

So, you have therefore two options:

  1. Implement your p2p application by extending Node and NodeConnection classes
  2. Implement your p2p application with one callback function

Examples have been provided by the package. These files can be found in the examples directory. My preference is to extend the classes, so we could build on each other's ideas in the future.

Option 1: Implement your p2p application by extending Node and NodeConnection classes

This option is preferred and gives the most flexibility. To implement your p2p network application, you could also extend the classes Node and/or NodeConnection. At least you need to extend the class Node with your own implementation. To implement the application specific functionality, you override the methods that represent the events. You are able to create different classes and methods to provide the code to implement the application protocol and functionality. While more files are involved an example is given by the next sections.

Extend class Node

Extending the class Node is easy. Make sure you override at least all the events. Whenever, you extend the class, it is not possible to use the callback function anymore. See the example below. You can also check the file examples/MyOwnPeer2PeerNode.py.

from p2pnetwork.node import Node

class MyOwnPeer2PeerNode (Node):
    # Python class constructor
    def __init__(self, host, port, id=None, callback=None, max_connections=0):
        super(MyOwnPeer2PeerNode, self).__init__(host, port, id, callback, max_connections)

    def outbound_node_connected(self, connected_node):
        print("outbound_node_connected: " + connected_node.id)
        
    def inbound_node_connected(self, connected_node):
        print("inbound_node_connected: " + connected_node.id)

    def inbound_node_disconnected(self, connected_node):
        print("inbound_node_disconnected: " + connected_node.id)

    def outbound_node_disconnected(self, connected_node):
        print("outbound_node_disconnected: " + connected_node.id)

    def node_message(self, connected_node, data):
        print("node_message from " + connected_node.id + ": " + str(data))
        
    def node_disconnect_with_outbound_node(self, connected_node):
        print("node wants to disconnect with oher outbound node: " + connected_node.id)
        
    def node_request_to_stop(self):
        print("node is requested to stop!")

    # OPTIONAL
    # If you need to override the NodeConection as well, you need to
    # override this method! In this method, you can initiate
    # you own NodeConnection class.
    def create_new_connection(self, connection, id, host, port):
        return MyOwnNodeConnection(self, connection, id, host, port)

Extend class NodeConnection

The NodeConnection class only hold the TCP/IP connection with the other node, to manage the different connections to and from the main node. It does not implement application specific elements. Mostly, you will only need to extend the Node class. However, when you would like to create your own NodeConnection class you can do this. Make sure that you override create_new_connection(self, connection, id, host, port) in the class Node, to make sure you initiate your own NodeConnection class. The example below shows some example.

from p2pnetwork.node import Node

class MyOwnPeer2PeerNode (Node):
    # Python class constructor
    def __init__(self, host, port, id=None, callback=None, max_connections=0):
        super(MyOwnPeer2PeerNode, self).__init__(host, port, id, callback, max_connections)

    # Override event functions...

    # Override this method to initiate your own NodeConnection class.
    def create_new_connection(self, connection, id, host, port):
        return MyOwnNodeConnection(self, connection, id, host, port)
from p2pnetwork.nodeconnection import NodeConnection

class MyOwnNodeConnection (NodeConnection):
    # Python class constructor
     def __init__(self, main_node, sock, id, host, port):
        super(MyOwnNodeConnection, self).__init__(main_node, sock, id, host, port)

    # Check yourself what you would like to change and override! See the 
    # documentation and code of the nodeconnection class.

Using your new classes

You have extended the Node class and maybe also the NodeConnection class. The next aspect it to use your new p2p network application by using these classes. You create a new python file and start using your classes. See the example below. Check the file example/my_own_p2p_application.py for this implementation.

import sys
import time

from MyOwnPeer2PeerNode import MyOwnPeer2PeerNode

node = MyOwnPeer2PeerNode("127.0.0.1", 10001)
time.sleep(1)

# Do not forget to start your node!
node.start()
time.sleep(1)

# Connect with another node, otherwise you do not create any network!
node.connect_with_node('127.0.0.1', 10002)
time.sleep(2)

# Example of sending a message to the nodes (dict).
node.send_to_nodes({"message": "Hi there!"})

time.sleep(5) # Create here your main loop of the application

node.stop()

Option 2: Implement your p2p application with one callback function

While this is the least preferable method, you are in the lead! You need to create a callback method and spin off the Node from the module p2pnet. All events that happen within the network will be transferred to the callback function. All application specific functionality can be implemented within this callback and the methods provided by the classes Node and NodeConnection. See below an example of an implementation. You can check the file examples/my_own_p2p_application_callback.py for the full implementation.

import time
from p2pnetwork.node import Node

# node_callback
#  event         : event name
#  node          : the node (Node) that holds the node connections
#  connected_node: the node (NodeConnection) that is involved
#  data          : data that is send by the node (could be empty)
def node_callback(event, node, connected_node, data):
    try:
        if event != 'node_request_to_stop': # node_request_to_stop does not have any connected_node, while it is the main_node that is stopping!
            print('Event: {} from main node {}: connected node {}: {}'.format(event, node.id, connected_node.id, data))

    except Exception as e:
        print(e)

# The main node that is able to make connections to other nodes
# and accept connections from other nodes on port 8001.
node = Node("127.0.0.1", 10001, callback=node_callback)

# Do not forget to start it, it spins off a new thread!
node.start()
time.sleep(1)

# Connect to another node, otherwise you do not have any network.
node.connect_with_node('127.0.0.1', 10002)
time.sleep(2)

# Send some message to the other nodes
node.send_to_nodes('{"message": "hoi from node 1"}')

time.sleep(5) # Replace this sleep with your main loop!

# Gracefully stop the node.
node.stop()

Events that can occur

outbound_node_connected

The node connects with another node - node.connect_with_node('127.0.0.1', 8002) - and the connection is successful. While the basic functionality is to exchange the node id's, no user data is involved.

inbound_node_connected

Another node has made a connection with this node and the connection is successful. While the basic functionality is to exchange the node id's, no user data is involved.

outbound_node_disconnected

A node, to which we had made a connection in the past, is disconnected.

inbound_node_disconnected

A node, that had made a connection with us in the past, is disconnected.

node_message

A node - connected_node - sends a message. At this moment the basic functionality expects JSON format. It tries to decode JSON when the message is received. If it is not possible, the message is rejected.

node_disconnect_with_outbound_node

The application actively wants to disconnect the outbound node, a node with which we had made a connection in the past. You could send some last message to the node, that you are planning to disconnect, for example.

node_request_to_stop

The main node, also the application, is stopping itself. Note that the variable connected_node is empty, while there is no connected node involved.

Debugging

When things go wrong, you could enable debug messages of the Node class. The class shows these messages in the console and shows all the details of what happens within the class. To enable debugging for a node, use the code example below.

node = Node("127.0.0.1", 10001)
node.debug = True

Unit testing

Several unit tests have been implemented to make sure all the functionality of the provided classes are working correctly. The tests can be executed using Tox. This can be easily installed by pip install tox. To run these tests, you can use the following code:

$ tox

Example

Examples are available in the github repository of this project: https://github.com/macsnoeren/python-p2p-network. All examples can be found in the directory examples.

Node and NodeConnection class

See the Python documentation for all the details of these classes.

Show case: SecureNode

As a show case, I have created the SecureNode class that extends the Node class. This node uses JSON, hashing and signing to communicate between the nodes. My main thought with this secure node is to be able to exchange data securely with each other and give others permissions to read the data, for example. You are the owner of your data! Anyway, some project that I am currently working on. See the documentation of this specific class file.

import sys
import time

from p2pnetwork.securenode import SecureNode

node = SecureNode("127.0.0.1", 10001)
time.sleep(1)

node.start()

An example node that uses SecureNode class is found in the example directory on github: secure_node.py.

python-p2p-network's People

Contributors

adrianscott avatar bousmahawassel avatar chrissie avatar ecsbeats avatar eyramcs avatar gasull avatar larsthepenguin avatar macsnoeren avatar nater0214 avatar rdash99 avatar samuelhaidu avatar shaidu-gif avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

python-p2p-network's Issues

how

node_1.send_to_node(node_3,data="message: Hi there from 1!\n")

I have link question between "node.py" and "nodeconnection.py"

Hi!

In nodeconnection.py, we have a Nodeconnection class, it has 5 parameters, respectively are main_node, sock, id, host, port.
But in node.py, "create_new_connection" method in node class has 4 parameters. And it return class that has 4 parameters.
I don't understand this behavior. Or am I missing something?

Thank you!

how to use send_to_node api?

i want to send msg to an specify node with code

node_1.send_to_node(node_3,data="message: Hi there from 1!\n") ,but it not works,while send_to_nodes can works well,is there any demo show how to do?

Possible vulnerability on the node unique ID

MD5 is used on the source code to create the node unique ID, however, md5 is a vulnerable algorithm (collision attacks). To improve the security of the protocol, I suggest to change it to a secure and efficient algorithm (Blake2, for example).

Info about node discovery

Hello,
please can you confirm that the library doesn't have any mechanism for nodes discovery?
If so, do you have any repo or best practice for storing a "global" database containing a list of available nodes?
Is there any other best practice for obtaining the same result (node discovery and connection)

Thank you.
Regards,
Marco

I have question about the "nodeconnection.py"

The Event Flag is initialized in this file.

self.terminate_flag = threading.Event()

And it is false. This means that the thread is in a wait state.
But in run function:

while not self.terminate_flag.is_set(): ...

It mean the program will run when the flag is False, But in fact in this time we want it wait.
I want to say that why not while self.terminate_flag.is_set():.
Because it seems more common sense.

New feature: Plugins

I got the idea to improve the framework with plugins to implement the required functionality instead of extending the class. The main application starts the node and adds the required plugins to the scene that is required to implement the application. Implementation of a discovery methodolgy is than simply done by the implementation of a plugin. Furthermore, sharing is made easier, because these pugins can be easily used by others. Therefore, this functionality will enable the open source creation of the functionality. I am also able to supply basic plugins to the scene like encryption, blockchain and discovery things. I will start developing this functionality and also try to create an example.

Misspelled debug messages

I found misspelled word on nodeconnection.py Its on line 170

self.main_node.debug_print('datatype used is not valid plese use str, dict (will be send as json) or bytes')

Import "p2pnetwork.node" could not be resolved

Hello! I'm trying to use this library but I can't seem to import it. I ran the pip (and pip3 to test) install correctly and no errors were shown, and even if I run pip list it shows p2pnetwork. Does anyone have an idea as to why I'm getting this import error?
Thank you!

Connect to a node already connected to

I was wondering why a node can't connect to a node that is already connected to the former. See this line. Lets say that nodeA has an outbound connection to nodeB. Why can't nodeB have an outbound connection to nodeA?

Perhaps I don't fully understand how connections work. Lets say that we have the following connections: nodeA->nodeB->nodeC, where -> denotes a connection, being the node on the left the outbound one and the right the inbound. Summarised as:

  • nodeA has an outbound connection to nodeB
  • nodeB has an inbound connection to nodeA
  • nodeB has an outbound connection to nodeC
  • nodeC has an inbound connection to nodeB

If in the previous setup a nodeB calls send_to_nodes, will it reach nodeA?

Thanks!

Pip3 version is out of date and unstable

The latest version of p2pnetwork in pip3 is 0.0.3 and has at least one bug in nodeconnection.py. Particularly on line 54 there is a bug that has since been patched on the development and master branches self.info = dict -> self.info = {}, but a project like python-p2p-secure-node that specifies version 0.0.3 can crash when a "pong" is received.

Non UTF-8 messages will throw exception

If a connected client sends non-UTF8 data, run() will throw an uncaught exception. I added a try/except to catch it, but maybe better options?

                    try:
                        connected_node_id   = connection.recv(4096).decode('utf-8')
                    except Exception as e:
                        print(e)
                        connection.close()
                        continue

OS Error when stopping nodes

Firstly, I want to thank everyone involved with this library for the wonderful work that has been done. I am an undergraduate grader for a networking course, and I had planned on writing a library similar to this one to create a peer2peer chat client, but once I had found this lib I decided to implement it instead because of its clear documentation and ease of use.

Secondly, I've noticed an error when I stop a node. My script will crash with an OS error. OS Error: [Errno 9]: Bad file descriptor . I believe this is due to the use of sock.settimeout(None) in the Node class's self.run() method, at line 308. I was curious what the thought process was behind using None, as opposed to an integer or float, for the timeout duration. Would changing the timeout duration to a float, like 0.01 for instance, have a negative impact on the rest of the class?

Crash if node id malformed

If a connecting client sends a malformed id/port message, server will throw an uncaught exception.

In run(), I threw a try/except around the split to catch the error, but maybe there are better solutions?

                   if ":" in connected_node_id:
                        print("Got connected node id", connected_node_id)
                        try:
                                (connected_node_id, connected_node_port) = connected_node_id.split(':') # When a node is connected, it sends it id!
                        except Exception as e:
                                print(e)
                                connection.close()
                                continue

Length protocol instead of EOT

Hey Maurice,

Currently, I'm working on my own cryptocurrency project in Python by using a modified version of this package. Isn't a length protocol between the socket where, the first 4 bytes will be sent to determine the length of the upcoming package, then the end of transmission protocol better than the EOT protocol? If you want to send binary data to the socket isn't there a possibility that the binary contains the byte sequence EOT?

Currently, I'm implementing this in my own project however, I have not tested it fully yet.

implementing compression to transfer large files over socket.

I am adding the functionality of compressing data to send and decompressing it on the other end to reduce bandwidth in the network.
help me to achieve this.
example code is here.

def dataencode(objectToEncode):
    data_out = jsonpickle.encode(objectToEncode, unpicklable=True)
    data_out = data_out.encode("utf-8")
    compressed_data = compress(data_out)
    return jsonpickle.encode(compressed_data, unpicklable=True)

Bug in connect_with_node function in node.py

The connect_with_node function returns None when a connection is successfully established since there is no return statement before the end of the function in that case, however, I would expect it to return True to indicate that the connection was successful.

Am I misunderstanding what the return value represents (in that case an extra line elaborating on this in the function's docstring would help) or is there just a return statement missing?

how to

node_1.send_to_node(node_3,data="message: Hi there from 1!\n")

Issue: unit test test_node_max_connections failed

I could not succeed the unit test test_node_max_connections. The length of the node_1_inbound is not right, seems like a bug of some sort. I have debugged the code and seems the connection is lost between node0 and node1 after sending data from the nodes. Before sending data, the inbound connections of node1 are correct.

node_0.send_to_nodes('hello from node 0')
time.sleep(2)


#place where node seems to lose it's connection
node_1.send_to_nodes('hello from node 1')
time.sleep(2)

node_2.send_to_nodes('hello from node 2')
time.sleep(2)

#test that is false.
self.assertEqual(node_1_inbound, 2, "Node 1 should have two connections from node_0 and node_2!")

After some deeper debugging it seems the node in send_to_node is in self.all_node however the if statement is still false.

if n in self.all_nodes:
  n.send(data, compression=compression)
else:
  self.debug_print("Node send_to_node: Could not send the data, node is not found!")

Besides I also get the following warning however, I get this warning before the connection is lost.

ResourceWarning: unclosed <socket.socket fd=11, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 49489)>

I will continue debugging later this week, will let know if I find something.

"RuntimeError: cannot join current thread" while sending a message to another node

What's should happen
I need a node to send a response to another node. This is how my code looks:

def add_node_to_network(self, node, conn_type):
    super().connect_with_node(node.get_host(), node.get_port())
    if conn_type == 'indirect':
        super().send_to_node(node, {'type' : 'join_request_resp'})
        self.peer_book[self.UUID + 1] = node
        print("Node {} was added to the peer book".format(self.UUID+1))
        print(self.nodesIn)
        super().send_to_nodes({'type' : 'new_peer', 'node' : node, 'UUID' : self.UUID + 1})
        print("Sourcing information about new peer...")

What actually happened
I get this response

connect_with_node(127.0.0.1, 51687)
Node 1 was added to the peer book
[<NodeConnection(Thread-4, started 123145562787840)>]
p2p_event_node_inbound_closed: Thread-4
Exception in thread Thread-4:
Traceback (most recent call last):
  File "/anaconda3/lib/python3.7/threading.py", line 917, in _bootstrap_inner
    self.run()
  File "/Projekty/IPDS-RELATED/IPDS-Python/src/../lib/TcpServerNode.py", line 433, in run
    self.nodeServer.event_node_message(self, data)
  File "src/gateway_server.py", line 48, in event_node_message
    self.add_node_to_network(node, conn_type)
  File "src/gateway_server.py", line 63, in add_node_to_network
    super().send_to_nodes({'type' : 'new_peer', 'node' : node, 'UUID' : self.UUID + 1})
  File "/Projekty/IPDS-RELATED/IPDS-Python/src/../lib/TcpServerNode.py", line 181, in send_to_nodes
    self.send_to_node(n, data)
  File "/Projekty/IPDS-RELATED/IPDS-Python/src/../lib/TcpServerNode.py", line 192, in send_to_node
    self.delete_closed_connections()
  File "/Projekty/IPDS-RELATED/IPDS-Python/src/../lib/TcpServerNode.py", line 153, in delete_closed_connections
    n.join()
  File "/anaconda3/lib/python3.7/threading.py", line 1029, in join
    raise RuntimeError("cannot join current thread")
RuntimeError: cannot join current thread

It seems that there is an error in the send_to_node function. I looked in your code and I didn't find anything. Maybe I'm doing something wrong.

There's more
There is another weird thing I noticed. I tried to use get_port() function you provided in your code, but it returns a different port (in my case 56310 when I specified 4560). I've tried writing the port manually in the code, but it didn't fix the issue.

PS. I see that self and super() both work. I tried both with the same effect.

Unit tests do work on Windows ... not on Linux

The unit tests that are created to test all the functionality of the package do work on Windows. On Linux it fails unfortunately. This should be investigated and solved. The following output is shown when the tests are runned on Linux:

$ python3 setup.py test
running test
Searching for nose
Best match: nose 1.3.7
Processing nose-1.3.7-py3.7.egg

Using /home/maurice/projects/python-p2p-network/.eggs/nose-1.3.7-py3.7.egg
running egg_info
writing p2pnetwork.egg-info/PKG-INFO
writing dependency_links to p2pnetwork.egg-info/dependency_links.txt
writing top-level names to p2pnetwork.egg-info/top_level.txt
reading manifest file 'p2pnetwork.egg-info/SOURCES.txt'
writing manifest file 'p2pnetwork.egg-info/SOURCES.txt'
running build_ext
test_extending_class_of_node (p2pnetwork.tests.test_node.TestNode)
Testing the class implementation of the Node. ... ok
test_node_communication (p2pnetwork.tests.test_node.TestNode)
Test whether the connected nodes are able to send messages to each other. ... ok
test_node_complete (p2pnetwork.tests.test_node.TestNode)
Testing the complete sequence of the Node based on Samuel complete_test.py. ... ERROR
/usr/lib/python3.7/unittest/case.py:643: ResourceWarning: unclosed <socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('0.0.0.0', 0)>
  outcome.errors.clear()
ResourceWarning: Enable tracemalloc to get the object allocation traceback
test_node_connection (p2pnetwork.tests.test_node.TestNode)
Testing whether two Node instances are able to connect with each other. ... ERROR
/usr/lib/python3.7/unittest/case.py:643: ResourceWarning: unclosed <socket.socket fd=4, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('0.0.0.0', 0)>
  outcome.errors.clear()
ResourceWarning: Enable tracemalloc to get the object allocation traceback
/usr/lib/python3.7/unittest/case.py:643: ResourceWarning: unclosed <socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 10001)>
  outcome.errors.clear()
ResourceWarning: Enable tracemalloc to get the object allocation traceback
test_node_events (p2pnetwork.tests.test_node.TestNode)
Testing the events that are triggered by the Node. ... ERROR
test_node_send_data_dict (p2pnetwork.tests.test_nodeconnection.TestNode)
Testing whether NodeConnections handle sending dict well enough. ... ERROR
/usr/lib/python3.7/unittest/case.py:643: ResourceWarning: unclosed <socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8001)>
  outcome.errors.clear()
ResourceWarning: Enable tracemalloc to get the object allocation traceback
test_node_send_data_str (p2pnetwork.tests.test_nodeconnection.TestNode)
Testing whether NodeConnections handle sending str well enough. ... ERROR

======================================================================
ERROR: test_node_complete (p2pnetwork.tests.test_node.TestNode)
Testing the complete sequence of the Node based on Samuel complete_test.py.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/maurice/projects/python-p2p-network/p2pnetwork/tests/test_node.py", line 121, in test_node_complete
    node_0 = Node('127.0.0.1', 8000, node_callback)
  File "/home/maurice/projects/python-p2p-network/p2pnetwork/node.py", line 69, in __init__
    self.init_server()
  File "/home/maurice/projects/python-p2p-network/p2pnetwork/node.py", line 92, in init_server
    self.sock.bind((self.host, self.port))
OSError: [Errno 98] Address already in use
-------------------- >> begin captured stdout << ---------------------
Initialisation of the Node on port: 8000 on node (ed8bab37d7f15e30da8720e96bcad500f2f8025ff06cbee97eb82bba8498baa444b3937d6bcae3945622421f38a27739cbfa91a3a6a22380caba42d7fff3b79d)

--------------------- >> end captured stdout << ----------------------

======================================================================
ERROR: test_node_connection (p2pnetwork.tests.test_node.TestNode)
Testing whether two Node instances are able to connect with each other.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/maurice/projects/python-p2p-network/p2pnetwork/tests/test_node.py", line 21, in test_node_connection
    node2 = Node("localhost", 10002)
  File "/home/maurice/projects/python-p2p-network/p2pnetwork/node.py", line 69, in __init__
    self.init_server()
  File "/home/maurice/projects/python-p2p-network/p2pnetwork/node.py", line 92, in init_server
    self.sock.bind((self.host, self.port))
OSError: [Errno 98] Address already in use
-------------------- >> begin captured stdout << ---------------------
Initialisation of the Node on port: 10001 on node (da332f1ea0d8ef643c9fae02837ee76911d8d4bb0c9edc3ac12ffb7078c69a46cdc1cc61dc2b1f9aa4abe86720dd959a5af6ceb383812bef0c58281c62cc7c90)
Initialisation of the Node on port: 10002 on node (0c265613937e77eb17a9039f3d4c7ac9b11a6b591b5e12077241f197f92f56eabeb23c3ce0b0c925154a3085ef76c0528b8897ddfb115ce3915e574c12923db9)

--------------------- >> end captured stdout << ----------------------

======================================================================
ERROR: test_node_events (p2pnetwork.tests.test_node.TestNode)
Testing the events that are triggered by the Node.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/maurice/projects/python-p2p-network/p2pnetwork/tests/test_node.py", line 207, in test_node_events
    node_0 = Node('127.0.0.1', 8000, node_callback)
  File "/home/maurice/projects/python-p2p-network/p2pnetwork/node.py", line 69, in __init__
    self.init_server()
  File "/home/maurice/projects/python-p2p-network/p2pnetwork/node.py", line 92, in init_server
    self.sock.bind((self.host, self.port))
OSError: [Errno 98] Address already in use
-------------------- >> begin captured stdout << ---------------------
Initialisation of the Node on port: 8000 on node (bcd13e8d7236a4bdb27a1edd3f0d188b1f0122f80891f6977922ff5ce51618e3a8a05f5b47a715b632e58a80185cff967e2a582f4ddef9dabf32ebfc6cefae36)

--------------------- >> end captured stdout << ----------------------

======================================================================
ERROR: test_node_send_data_dict (p2pnetwork.tests.test_nodeconnection.TestNode)
Testing whether NodeConnections handle sending dict well enough.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/maurice/projects/python-p2p-network/p2pnetwork/tests/test_nodeconnection.py", line 100, in test_node_send_data_dict
    node2 = MyTestNode("127.0.0.1", 8002)
  File "/home/maurice/projects/python-p2p-network/p2pnetwork/tests/test_nodeconnection.py", line 88, in __init__
    super(MyTestNode, self).__init__(host, port, None)
  File "/home/maurice/projects/python-p2p-network/p2pnetwork/node.py", line 69, in __init__
    self.init_server()
  File "/home/maurice/projects/python-p2p-network/p2pnetwork/node.py", line 92, in init_server
    self.sock.bind((self.host, self.port))
OSError: [Errno 98] Address already in use
-------------------- >> begin captured stdout << ---------------------
Initialisation of the Node on port: 8001 on node (2fe5423ad2fa43b023063a3a54f3fb6e28768c574ecf14de8621135195d87591327191cdf905d03a05e70c7021e9fe658ae30188cd08939dc201ee029239c6fd)
Initialisation of the Node on port: 8002 on node (aa90124307d53a8e8ed99bbd8d624c1adc5668a78830c58238480fac76762c2be37d55992637c04cd7ae5800f9235777f053a55d365d06a3e7feb2513b236b93)

--------------------- >> end captured stdout << ----------------------

======================================================================
ERROR: test_node_send_data_str (p2pnetwork.tests.test_nodeconnection.TestNode)
Testing whether NodeConnections handle sending str well enough.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/maurice/projects/python-p2p-network/p2pnetwork/tests/test_nodeconnection.py", line 36, in test_node_send_data_str
    node2 = MyTestNode("127.0.0.1", 8002)
  File "/home/maurice/projects/python-p2p-network/p2pnetwork/tests/test_nodeconnection.py", line 26, in __init__
    super(MyTestNode, self).__init__(host, port, None)
  File "/home/maurice/projects/python-p2p-network/p2pnetwork/node.py", line 69, in __init__
    self.init_server()
  File "/home/maurice/projects/python-p2p-network/p2pnetwork/node.py", line 92, in init_server
    self.sock.bind((self.host, self.port))
OSError: [Errno 98] Address already in use
-------------------- >> begin captured stdout << ---------------------
Initialisation of the Node on port: 8001 on node (371fae118c3037f1a2f2cdec60f1f2729a0da7b2b6433f639f43dca722ecd5c928bdb4d1b5de66d5c82b8322d2fc6300caa974ded873e13a1eb7238e98d67ab7)
Initialisation of the Node on port: 8002 on node (752f24de3d4dfaf4ec126ada2f13c278c7992a383cd21b248600df0daac3ea07c7c685810166766ac4b6348b2946ae9d79d2a0dacd324cfdded5d806ca877008)

--------------------- >> end captured stdout << ----------------------

----------------------------------------------------------------------
Ran 7 tests in 28.110s

FAILED (errors=5)
Test failed: <unittest.runner.TextTestResult run=7 errors=5 failures=0>
error: Test failed: <unittest.runner.TextTestResult run=7 errors=5 failures=0>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.