2019-09-09 15:45:35 +08:00
|
|
|
import asyncio
|
|
|
|
from typing import Dict, Tuple
|
2019-08-29 21:38:06 +08:00
|
|
|
|
2019-08-01 00:09:09 +08:00
|
|
|
import factory
|
2019-08-16 07:26:59 +08:00
|
|
|
|
2019-08-29 21:38:06 +08:00
|
|
|
from libp2p import generate_new_rsa_identity, initialize_default_swarm
|
|
|
|
from libp2p.crypto.keys import KeyPair
|
2019-08-01 00:09:09 +08:00
|
|
|
from libp2p.host.basic_host import BasicHost
|
2019-09-17 23:38:11 +08:00
|
|
|
from libp2p.network.connection.swarm_connection import SwarmConn
|
2019-09-09 15:45:35 +08:00
|
|
|
from libp2p.network.stream.net_stream_interface import INetStream
|
2019-09-14 23:37:01 +08:00
|
|
|
from libp2p.network.swarm import Swarm
|
2019-08-01 00:09:09 +08:00
|
|
|
from libp2p.pubsub.floodsub import FloodSub
|
|
|
|
from libp2p.pubsub.gossipsub import GossipSub
|
|
|
|
from libp2p.pubsub.pubsub import Pubsub
|
2019-08-29 21:38:06 +08:00
|
|
|
from libp2p.security.base_transport import BaseSecureTransport
|
|
|
|
from libp2p.security.insecure.transport import PLAINTEXT_PROTOCOL_ID, InsecureTransport
|
2019-08-31 22:38:46 +08:00
|
|
|
import libp2p.security.secio.transport as secio
|
2019-08-29 21:38:06 +08:00
|
|
|
from libp2p.typing import TProtocol
|
2019-09-09 15:45:35 +08:00
|
|
|
from tests.configs import LISTEN_MADDR
|
2019-08-16 07:40:31 +08:00
|
|
|
from tests.pubsub.configs import (
|
2019-08-03 09:36:58 +08:00
|
|
|
FLOODSUB_PROTOCOL_ID,
|
|
|
|
GOSSIPSUB_PARAMS,
|
|
|
|
GOSSIPSUB_PROTOCOL_ID,
|
|
|
|
)
|
2019-09-14 23:37:01 +08:00
|
|
|
from tests.utils import connect, connect_swarm
|
2019-08-01 00:09:09 +08:00
|
|
|
|
|
|
|
|
2019-08-29 21:38:06 +08:00
|
|
|
def security_transport_factory(
|
|
|
|
is_secure: bool, key_pair: KeyPair
|
|
|
|
) -> Dict[TProtocol, BaseSecureTransport]:
|
|
|
|
if not is_secure:
|
2019-08-31 22:38:46 +08:00
|
|
|
return {PLAINTEXT_PROTOCOL_ID: InsecureTransport(key_pair)}
|
2019-08-29 21:38:06 +08:00
|
|
|
else:
|
2019-08-31 22:38:46 +08:00
|
|
|
return {secio.ID: secio.Transport(key_pair)}
|
2019-08-29 21:38:06 +08:00
|
|
|
|
|
|
|
|
2019-09-15 14:59:59 +08:00
|
|
|
def SwarmFactory(is_secure: bool) -> Swarm:
|
|
|
|
key_pair = generate_new_rsa_identity()
|
|
|
|
sec_opt = security_transport_factory(False, key_pair)
|
|
|
|
return initialize_default_swarm(key_pair, sec_opt=sec_opt)
|
|
|
|
|
|
|
|
|
|
|
|
class ListeningSwarmFactory(factory.Factory):
|
2019-09-14 23:37:01 +08:00
|
|
|
class Meta:
|
|
|
|
model = Swarm
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
async def create_and_listen(cls, is_secure: bool) -> Swarm:
|
2019-09-15 14:59:59 +08:00
|
|
|
swarm = SwarmFactory(is_secure)
|
2019-09-14 23:37:01 +08:00
|
|
|
await swarm.listen(LISTEN_MADDR)
|
|
|
|
return swarm
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
async def create_batch_and_listen(
|
|
|
|
cls, is_secure: bool, number: int
|
|
|
|
) -> Tuple[Swarm, ...]:
|
|
|
|
return await asyncio.gather(
|
|
|
|
*[cls.create_and_listen(is_secure) for _ in range(number)]
|
|
|
|
)
|
2019-08-01 00:09:09 +08:00
|
|
|
|
|
|
|
|
|
|
|
class HostFactory(factory.Factory):
|
|
|
|
class Meta:
|
|
|
|
model = BasicHost
|
|
|
|
|
2019-08-29 21:38:06 +08:00
|
|
|
class Params:
|
|
|
|
is_secure = False
|
|
|
|
|
2019-09-14 23:37:01 +08:00
|
|
|
network = factory.LazyAttribute(lambda o: SwarmFactory(o.is_secure))
|
2019-08-01 00:09:09 +08:00
|
|
|
|
2019-09-09 15:45:35 +08:00
|
|
|
@classmethod
|
2019-09-15 14:59:59 +08:00
|
|
|
async def create_and_listen(cls, is_secure: bool) -> BasicHost:
|
|
|
|
swarms = await ListeningSwarmFactory.create_batch_and_listen(is_secure, 1)
|
|
|
|
return BasicHost(swarms[0])
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
async def create_batch_and_listen(
|
|
|
|
cls, is_secure: bool, number: int
|
|
|
|
) -> Tuple[BasicHost, ...]:
|
|
|
|
swarms = await ListeningSwarmFactory.create_batch_and_listen(is_secure, number)
|
|
|
|
return tuple(BasicHost(swarm) for swarm in range(swarms))
|
2019-09-09 15:45:35 +08:00
|
|
|
|
2019-08-01 00:09:09 +08:00
|
|
|
|
|
|
|
class FloodsubFactory(factory.Factory):
|
|
|
|
class Meta:
|
|
|
|
model = FloodSub
|
|
|
|
|
|
|
|
protocols = (FLOODSUB_PROTOCOL_ID,)
|
|
|
|
|
|
|
|
|
|
|
|
class GossipsubFactory(factory.Factory):
|
|
|
|
class Meta:
|
|
|
|
model = GossipSub
|
|
|
|
|
|
|
|
protocols = (GOSSIPSUB_PROTOCOL_ID,)
|
|
|
|
degree = GOSSIPSUB_PARAMS.degree
|
|
|
|
degree_low = GOSSIPSUB_PARAMS.degree_low
|
|
|
|
degree_high = GOSSIPSUB_PARAMS.degree_high
|
|
|
|
time_to_live = GOSSIPSUB_PARAMS.time_to_live
|
|
|
|
gossip_window = GOSSIPSUB_PARAMS.gossip_window
|
2019-08-01 21:38:14 +08:00
|
|
|
gossip_history = GOSSIPSUB_PARAMS.gossip_history
|
2019-08-01 00:09:09 +08:00
|
|
|
heartbeat_interval = GOSSIPSUB_PARAMS.heartbeat_interval
|
|
|
|
|
|
|
|
|
|
|
|
class PubsubFactory(factory.Factory):
|
|
|
|
class Meta:
|
|
|
|
model = Pubsub
|
|
|
|
|
|
|
|
host = factory.SubFactory(HostFactory)
|
|
|
|
router = None
|
|
|
|
my_id = factory.LazyAttribute(lambda obj: obj.host.get_id())
|
|
|
|
cache_size = None
|
2019-09-09 15:45:35 +08:00
|
|
|
|
|
|
|
|
2019-09-14 23:37:01 +08:00
|
|
|
async def swarm_pair_factory(is_secure: bool) -> Tuple[Swarm, Swarm]:
|
2019-09-15 20:44:48 +08:00
|
|
|
swarms = await ListeningSwarmFactory.create_batch_and_listen(is_secure, 2)
|
2019-09-14 23:37:01 +08:00
|
|
|
await connect_swarm(swarms[0], swarms[1])
|
|
|
|
return swarms[0], swarms[1]
|
|
|
|
|
|
|
|
|
|
|
|
async def host_pair_factory(is_secure) -> Tuple[BasicHost, BasicHost]:
|
2019-09-09 15:45:35 +08:00
|
|
|
hosts = await asyncio.gather(
|
2019-09-14 23:37:01 +08:00
|
|
|
*[
|
|
|
|
HostFactory.create_and_listen(is_secure),
|
|
|
|
HostFactory.create_and_listen(is_secure),
|
|
|
|
]
|
2019-09-09 15:45:35 +08:00
|
|
|
)
|
|
|
|
await connect(hosts[0], hosts[1])
|
|
|
|
return hosts[0], hosts[1]
|
|
|
|
|
|
|
|
|
2019-09-17 23:38:11 +08:00
|
|
|
async def swarm_conn_pair_factory(
|
|
|
|
is_secure
|
|
|
|
) -> Tuple[SwarmConn, Swarm, SwarmConn, Swarm]:
|
|
|
|
swarms = await swarm_pair_factory(is_secure)
|
|
|
|
conn_0 = swarms[0].connections[swarms[1].get_peer_id()]
|
|
|
|
conn_1 = swarms[1].connections[swarms[0].get_peer_id()]
|
|
|
|
return conn_0, swarms[0], conn_1, swarms[1]
|
2019-09-09 15:45:35 +08:00
|
|
|
|
|
|
|
|
2019-09-14 23:37:01 +08:00
|
|
|
async def net_stream_pair_factory(
|
|
|
|
is_secure: bool
|
|
|
|
) -> Tuple[INetStream, BasicHost, INetStream, BasicHost]:
|
2019-09-09 15:45:35 +08:00
|
|
|
protocol_id = "/example/id/1"
|
|
|
|
|
|
|
|
stream_1: INetStream
|
|
|
|
|
|
|
|
# Just a proxy, we only care about the stream
|
|
|
|
def handler(stream: INetStream) -> None:
|
|
|
|
nonlocal stream_1
|
|
|
|
stream_1 = stream
|
|
|
|
|
2019-09-14 23:37:01 +08:00
|
|
|
host_0, host_1 = await host_pair_factory(is_secure)
|
2019-09-09 15:45:35 +08:00
|
|
|
host_1.set_stream_handler(protocol_id, handler)
|
|
|
|
|
|
|
|
stream_0 = await host_0.new_stream(host_1.get_id(), [protocol_id])
|
|
|
|
return stream_0, host_0, stream_1, host_1
|