Add basic support for multiaddr addresses and improvement around peer id (#75)

* Improved peer ID construction and usage

* peer id object is directly passed to the network

no need to cast from a string to an ID

* don't base64 encode the peer id when loading from public key

* use proper multiaddr address

- keep multiaddr object into peerstore instead of string
- update network code to use new multiaddr lib
- update tests and example

* don't instanciate peerstore object in constructor

This has side effect where the same peerstore
is used for different instance of Libp2p

* add connect method to basic_host

* use zaibon's fork of sbuss/py-multiaddr

* lint
This commit is contained in:
Christophe de Carvalho
2018-11-29 16:06:40 +01:00
committed by Robert Zajac
parent 7fa674dee2
commit 611de28aca
15 changed files with 279 additions and 74 deletions

View File

@ -1,11 +1,14 @@
import multiaddr
import pytest
from libp2p.libp2p import new_node
from peer.peerinfo import info_from_p2p_addr
@pytest.mark.asyncio
async def test_simple_messages():
node_a = await new_node(transport_opt=["/ip4/127.0.0.1/tcp/8001/ipfs/node_a"])
node_b = await new_node(transport_opt=["/ip4/127.0.0.1/tcp/8000/ipfs/node_b"])
node_a = await new_node(transport_opt=["/ip4/127.0.0.1/tcp/8001"])
node_b = await new_node(transport_opt=["/ip4/127.0.0.1/tcp/8000"])
async def stream_handler(stream):
while True:
@ -19,10 +22,9 @@ async def test_simple_messages():
node_b.set_stream_handler("/echo/1.0.0", stream_handler)
# Associate the peer with local ip address (see default parameters of Libp2p())
node_a.get_peerstore().add_addr("node_b", "/ip4/127.0.0.1/tcp/8000", 10)
node_a.get_peerstore().add_addrs(node_b.get_id(), node_b.get_addrs(), 10)
print("node_a about to open stream")
stream = await node_a.new_stream("node_b", ["/echo/1.0.0"])
stream = await node_a.new_stream(node_b.get_id(), ["/echo/1.0.0"])
messages = ["hello" + str(x) for x in range(10)]
for message in messages:
@ -36,10 +38,11 @@ async def test_simple_messages():
# Success, terminate pending tasks.
return
@pytest.mark.asyncio
async def test_double_response():
node_a = await new_node(transport_opt=["/ip4/127.0.0.1/tcp/8002/ipfs/node_a"])
node_b = await new_node(transport_opt=["/ip4/127.0.0.1/tcp/8003/ipfs/node_b"])
node_a = await new_node(transport_opt=["/ip4/127.0.0.1/tcp/8002"])
node_b = await new_node(transport_opt=["/ip4/127.0.0.1/tcp/8003"])
async def stream_handler(stream):
while True:
@ -57,9 +60,9 @@ async def test_double_response():
node_b.set_stream_handler("/echo/1.0.0", stream_handler)
# Associate the peer with local ip address (see default parameters of Libp2p())
node_a.get_peerstore().add_addr("node_b", "/ip4/127.0.0.1/tcp/8003", 10)
node_a.get_peerstore().add_addrs(node_b.get_id(), node_b.get_addrs(), 10)
print("node_a about to open stream")
stream = await node_a.new_stream("node_b", ["/echo/1.0.0"])
stream = await node_a.new_stream(node_b.get_id(), ["/echo/1.0.0"])
messages = ["hello" + str(x) for x in range(10)]
for message in messages:
await stream.write(message.encode())
@ -76,3 +79,26 @@ async def test_double_response():
# Success, terminate pending tasks.
return
@pytest.mark.asyncio
async def test_host_connect():
node_a = await new_node(transport_opt=["/ip4/127.0.0.1/tcp/8001/"])
node_b = await new_node(transport_opt=["/ip4/127.0.0.1/tcp/8000/"])
assert not node_a.get_peerstore().peers()
addr = node_b.get_addrs()[0]
info = info_from_p2p_addr(addr)
await node_a.connect(info)
assert len(node_a.get_peerstore().peers()) == 1
await node_a.connect(info)
# make sure we don't do double connection
assert len(node_a.get_peerstore().peers()) == 1
assert node_b.get_id() in node_a.get_peerstore().peers()
ma_node_b = multiaddr.Multiaddr('/ipfs/%s' % node_b.get_id().pretty())
for addr in node_a.get_peerstore().addrs(node_b.get_id()):
assert addr.encapsulate(ma_node_b) in node_b.get_addrs()

View File

@ -0,0 +1,9 @@
from Crypto.PublicKey import RSA
from peer.id import id_from_private_key, id_from_public_key
def test_id_from_private_key():
key = RSA.generate(2048, e=65537)
id_from_pub = id_from_public_key(key.publickey())
id_from_priv = id_from_private_key(key)
assert id_from_pub == id_from_priv

View File

@ -0,0 +1,11 @@
import multiaddr
from peer.peerinfo import info_from_p2p_addr
def test_info_from_p2p_addr():
# pylint: disable=line-too-long
m_addr = multiaddr.Multiaddr('/ip4/127.0.0.1/tcp/8000/ipfs/3YgLAeMKSAPcGqZkAt8mREqhQXmJT8SN8VCMN4T6ih4GNX9wvK8mWJnWZ1qA2mLdCQ')
info = info_from_p2p_addr(m_addr)
assert info.peer_id.pretty() == '3YgLAeMKSAPcGqZkAt8mREqhQXmJT8SN8VCMN4T6ih4GNX9wvK8mWJnWZ1qA2mLdCQ'
assert len(info.addrs) == 1
assert str(info.addrs[0]) == '/ip4/127.0.0.1/tcp/8000'

View File

@ -14,8 +14,8 @@ from protocol_muxer.multiselect_client import MultiselectClientError
async def perform_simple_test(expected_selected_protocol, \
protocols_for_client, protocols_with_handlers, \
node_a_port, node_b_port):
transport_opt_a = ["/ip4/127.0.0.1/tcp/" + str(node_a_port) + "/ipfs/node_a"]
transport_opt_b = ["/ip4/127.0.0.1/tcp/" + str(node_b_port) + "/ipfs/node_b"]
transport_opt_a = ["/ip4/127.0.0.1/tcp/" + str(node_a_port)]
transport_opt_b = ["/ip4/127.0.0.1/tcp/" + str(node_b_port)]
node_a = await new_node(\
transport_opt=transport_opt_a)
node_b = await new_node(\
@ -34,9 +34,9 @@ async def perform_simple_test(expected_selected_protocol, \
node_b.set_stream_handler(protocol, stream_handler)
# Associate the peer with local ip address (see default parameters of Libp2p())
node_a.get_peerstore().add_addr("node_b", "/ip4/127.0.0.1/tcp/" + str(node_b_port), 10)
node_a.get_peerstore().add_addrs(node_b.get_id(), node_b.get_addrs(), 10)
stream = await node_a.new_stream("node_b", protocols_for_client)
stream = await node_a.new_stream(node_b.get_id(), protocols_for_client)
messages = ["hello" + str(x) for x in range(10)]
for message in messages:
await stream.write(message.encode())