def __init__(self, previous=None): super(TriblerTestBlock, self).__init__() crypto = ECCrypto() other = crypto.generate_key(u"curve25519").pub().key_to_bin() transaction = { 'up': random.randint(201, 220), 'down': random.randint(221, 240), 'total_up': 0, 'total_down': 0 } if previous: self.key = previous.key transaction['total_up'] = previous.transaction[ 'total_up'] + transaction['up'] transaction['total_down'] = previous.transaction[ 'total_down'] + transaction['down'] TriblerChainBlock.__init__( self, (encode(transaction), previous.public_key, previous.sequence_number + 1, other, 0, previous.hash, 0, 0)) else: transaction['total_up'] = random.randint(241, 260) transaction['total_down'] = random.randint(261, 280) self.key = crypto.generate_key(u"curve25519") TriblerChainBlock.__init__( self, (encode(transaction), self.key.pub().key_to_bin(), random.randint(50, 100), other, 0, sha256(str(random.randint(0, 100000))).digest(), 0, 0)) self.sign(self.key)
def bootstrap_new_identity(self, amount): """ One-way payment channel. Create a new temporary identity, and transfer funds to the new identity. A different party can then take the result and do a transfer from the temporary identity to itself """ # Create new identity for the temporary identity crypto = ECCrypto() tmp_peer = Peer(crypto.generate_key(u"curve25519")) # Create the transaction specification transaction = {'up': 0, 'down': amount, 'type': 'tribler_bandwidth'} # Create the two half blocks that form the transaction local_half_block = TriblerBandwidthBlock.create( 'tribler_bandwidth', transaction, self.trustchain.persistence, self.trustchain.my_peer.public_key.key_to_bin(), link_pk=tmp_peer.public_key.key_to_bin()) local_half_block.sign(self.trustchain.my_peer.key) tmp_half_block = TriblerBandwidthBlock.create( 'tribler_bandwidth', transaction, self.trustchain.persistence, tmp_peer.public_key.key_to_bin(), link=local_half_block, link_pk=self.trustchain.my_peer.public_key.key_to_bin()) tmp_half_block.sign(tmp_peer.key) self.trustchain.persistence.add_block(local_half_block) self.trustchain.persistence.add_block(tmp_half_block) # Create the bootstrapped identity format block = { 'block_hash': tmp_half_block.hash.encode('base64'), 'sequence_number': tmp_half_block.sequence_number } result = { 'private_key': tmp_peer.key.key_to_bin().encode('base64'), 'transaction': { 'up': amount, 'down': 0 }, 'block': block } return result
def load_tunnel_community_in_session(self, session, exitnode=False): """ Load the tunnel community in a given session. We are using our own tunnel community here instead of the one used in Tribler. """ self.sanitize_network(session) keypair = ECCrypto().generate_key(u"curve25519") tunnel_peer = Peer(keypair) session.config.set_tunnel_community_exitnode_enabled(exitnode) overlay = self.test_class(tunnel_peer, session.lm.ipv8.endpoint, session.lm.ipv8.network, tribler_session=session, dht_provider=MockDHTProvider( session.lm.ipv8.endpoint.get_address()), settings={ "become_exitnode": exitnode, "max_circuits": 1 }) overlay._use_main_thread = False overlay.settings.remove_tunnel_delay = 0 session.lm.ipv8.overlays.append(overlay) return overlay
def load_tunnel_community_in_session(self, session, exitnode=False): """ Load the tunnel community in a given session. We are using our own tunnel community here instead of the one used in Tribler. """ keypair = ECCrypto().generate_key(u"curve25519") tunnel_peer = Peer(keypair) session.config.set_tunnel_community_exitnode_enabled(exitnode) overlay = self.test_class(tunnel_peer, session.lm.ipv8.endpoint, session.lm.ipv8.network, tribler_session=session, dht_provider=MockDHTProvider( session.lm.ipv8.endpoint.get_address())) overlay._use_main_thread = False session.lm.ipv8.overlays.append(overlay) session.lm.ipv8.strategies.append((RandomWalk(overlay), 20)) # We disable the discovery communities in this session since we don't want to walk to the live network for overlay in session.lm.ipv8.overlays: if isinstance(overlay, DiscoveryCommunity): overlay.unload() # Also reset the IPv8 network session.lm.ipv8.network = Network() return overlay
def setUp(self): """ Setup various variables and load the tunnel community in the main downloader session. """ yield TestAsServer.setUp(self) self.seed_tdef = None self.sessions = [] self.session2 = None self.bypass_dht = False self.seed_config = None self.tunnel_community_seeder = None self.eccrypto = ECCrypto() ec = self.eccrypto.generate_key(u"curve25519") self.test_class = TriblerTunnelCommunity self.test_class.master_peer = Peer(ec) self.tunnel_community = self.load_tunnel_community_in_session( self.session, exitnode=True) self.tunnel_communities = []
def __init__(self, crypto_curve, overlay_class, *args, **kwargs): self.endpoint = AutoMockEndpoint() self.endpoint.open() self.network = Network() self.my_peer = Peer(ECCrypto().generate_key(crypto_curve), self.endpoint.wan_address) self.overlay = overlay_class(self.my_peer, self.endpoint, self.network, *args, **kwargs) self.discovery = MockWalk(self.overlay) self.overlay.my_estimated_wan = self.endpoint.wan_address self.overlay.my_estimated_lan = self.endpoint.lan_address
def __init__(self, previous=None): super(TriblerBandwidthTestBlock, self).__init__() crypto = ECCrypto() other = crypto.generate_key(u"curve25519").pub().key_to_bin() transaction = {'up': random.randint(201, 220), 'down': random.randint(221, 240), 'total_up': 0, 'total_down': 0, 'type': 'tribler_bandwidth'} if previous: self.key = previous.key transaction['total_up'] = previous.transaction['total_up'] + transaction['up'] transaction['total_down'] = previous.transaction['total_down'] + transaction['down'] TriblerBandwidthBlock.__init__(self, ('tribler_bandwidth', encode(transaction), previous.public_key, previous.sequence_number + 1, other, 0, previous.hash, 0, 0, 0)) else: transaction['total_up'] = random.randint(241, 260) transaction['total_down'] = random.randint(261, 280) self.key = crypto.generate_key(u"curve25519") TriblerBandwidthBlock.__init__(self, ( 'tribler_bandwidth', encode(transaction), self.key.pub().key_to_bin(), random.randint(50, 100), other, 0, sha256(str(random.randint(0, 100000))).digest(), 0, 0, 0)) self.sign(self.key)
def bootstrap_new_identity(self, amount): """ One-way payment channel. Create a new temporary identity, and transfer funds to the new identity. A different party can then take the result and do a transfer from the temporary identity to itself """ # Create new identity for the temporary identity crypto = ECCrypto() tmp_peer = Peer(crypto.generate_key(u"curve25519")) # Create the transaction specification transaction = { 'up': 0, 'down': amount, 'type': 'tribler_bandwidth' } # Create the two half blocks that form the transaction local_half_block = TriblerBandwidthBlock.create('tribler_bandwidth', transaction, self.trustchain.persistence, self.trustchain.my_peer.public_key.key_to_bin(), link_pk=tmp_peer.public_key.key_to_bin()) local_half_block.sign(self.trustchain.my_peer.key) tmp_half_block = TriblerBandwidthBlock.create('tribler_bandwidth', transaction, self.trustchain.persistence, tmp_peer.public_key.key_to_bin(), link=local_half_block, link_pk=self.trustchain.my_peer.public_key.key_to_bin()) tmp_half_block.sign(tmp_peer.key) self.trustchain.persistence.add_block(local_half_block) self.trustchain.persistence.add_block(tmp_half_block) # Create the bootstrapped identity format block = {'block_hash': tmp_half_block.hash.encode('base64'), 'sequence_number': tmp_half_block.sequence_number} result = {'private_key': tmp_peer.key.key_to_bin().encode('base64'), 'transaction': {'up': amount, 'down': 0}, 'block': block} return result
def setUp(self): """ Setup various variables and load the tunnel community in the main downloader session. """ yield TestAsServer.setUp(self) self.seed_tdef = None self.sessions = [] self.session2 = None self.bypass_dht = False self.seed_config = None self.tunnel_community_seeder = None self.eccrypto = ECCrypto() ec = self.eccrypto.generate_key(u"curve25519") self.test_class = TriblerTunnelCommunity self.test_class.master_peer = Peer(ec) self.tunnel_community = self.load_tunnel_community_in_session(self.session, exitnode=True) self.tunnel_communities = []
class TestTunnelBase(TestAsServer): @inlineCallbacks def setUp(self): """ Setup various variables and load the tunnel community in the main downloader session. """ yield TestAsServer.setUp(self) self.seed_tdef = None self.sessions = [] self.session2 = None self.bypass_dht = False self.seed_config = None self.tunnel_community_seeder = None self.eccrypto = ECCrypto() ec = self.eccrypto.generate_key(u"curve25519") self.test_class = TriblerTunnelCommunity self.test_class.master_peer = Peer(ec) self.tunnel_community = self.load_tunnel_community_in_session(self.session, exitnode=True) self.tunnel_communities = [] def setUpPreSession(self): TestAsServer.setUpPreSession(self) self.config.set_dispersy_enabled(False) self.config.set_ipv8_enabled(True) self.config.set_libtorrent_enabled(True) self.config.set_trustchain_enabled(False) self.config.set_resource_monitor_enabled(False) self.config.set_tunnel_community_socks5_listen_ports(self.get_socks5_ports()) @inlineCallbacks def tearDown(self): if self.session2: yield self.session2.shutdown() for session in self.sessions: yield session.shutdown() yield TestAsServer.tearDown(self) @inlineCallbacks def setup_nodes(self, num_relays=1, num_exitnodes=1, seed_hops=0): """ Setup all required nodes, including the relays, exit nodes and seeder. """ baseindex = 3 for i in xrange(baseindex, baseindex + num_relays): # Normal relays proxy = yield self.create_proxy(i) self.tunnel_communities.append(proxy) baseindex += num_relays + 1 for i in xrange(baseindex, baseindex + num_exitnodes): # Exit nodes proxy = yield self.create_proxy(i, exitnode=True) self.tunnel_communities.append(proxy) # Setup the seeder session yield self.setup_tunnel_seeder(seed_hops) # Add the tunnel community of the downloader session self.tunnel_communities.append(self.tunnel_community) self._logger.info("Introducing all nodes to each other in tests") for community_introduce in self.tunnel_communities + ([self.tunnel_community_seeder] if self.tunnel_community_seeder else []): for community in self.tunnel_communities + ([self.tunnel_community_seeder] if self.tunnel_community_seeder else []): if community != community_introduce: community.walk_to(community_introduce.endpoint.get_address()) yield self.deliver_messages() def sanitize_network(self, session): # We disable the discovery communities in this session since we don't want to walk to the live network for overlay in session.lm.ipv8.overlays: if isinstance(overlay, DiscoveryCommunity): overlay.unload() session.lm.ipv8.overlays = [] session.lm.ipv8.strategies = [] # Also reset the IPv8 network session.lm.ipv8.network = Network() def load_tunnel_community_in_session(self, session, exitnode=False): """ Load the tunnel community in a given session. We are using our own tunnel community here instead of the one used in Tribler. """ self.sanitize_network(session) keypair = ECCrypto().generate_key(u"curve25519") tunnel_peer = Peer(keypair) session.config.set_tunnel_community_exitnode_enabled(exitnode) overlay = self.test_class(tunnel_peer, session.lm.ipv8.endpoint, session.lm.ipv8.network, tribler_session=session, dht_provider=MockDHTProvider(session.lm.ipv8.endpoint.get_address()), settings={"become_exitnode": exitnode, "max_circuits": 1}) overlay._use_main_thread = False overlay.settings.remove_tunnel_delay = 0 session.lm.ipv8.overlays.append(overlay) return overlay @inlineCallbacks def create_proxy(self, index, exitnode=False): """ Create a single proxy and load the tunnel community in the session of that proxy. """ from Tribler.Core.Session import Session self.setUpPreSession() config = self.config.copy() config.set_libtorrent_enabled(True) config.set_dispersy_enabled(False) config.set_state_dir(self.getStateDir(index)) config.set_tunnel_community_socks5_listen_ports(self.get_socks5_ports()) session = Session(config) yield session.start() self.sessions.append(session) returnValue(self.load_tunnel_community_in_session(session, exitnode=exitnode)) def setup_tunnel_seeder(self, hops): """ Setup the seeder. """ from Tribler.Core.Session import Session self.seed_config = self.config.copy() self.seed_config.set_state_dir(self.getStateDir(2)) self.seed_config.set_megacache_enabled(True) self.seed_config.set_tunnel_community_socks5_listen_ports(self.get_socks5_ports()) if self.session2 is None: self.session2 = Session(self.seed_config) self.session2.start() tdef = TorrentDef() tdef.add_content(os.path.join(TESTS_DATA_DIR, "video.avi")) tdef.set_tracker("http://localhost/announce") tdef.finalize() torrentfn = os.path.join(self.session2.config.get_state_dir(), "gen.torrent") tdef.save(torrentfn) self.seed_tdef = tdef if hops > 0: # Safe seeding enabled self.tunnel_community_seeder = self.load_tunnel_community_in_session(self.session2) self.tunnel_community_seeder.build_tunnels(hops) else: self.sanitize_network(self.session2) dscfg = DownloadStartupConfig() dscfg.set_dest_dir(TESTS_DATA_DIR) # basedir of the file we are seeding dscfg.set_hops(hops) d = self.session2.start_download_from_tdef(tdef, dscfg) d.set_state_callback(self.seeder_state_callback) def seeder_state_callback(self, ds): """ The callback of the seeder download. For now, this only logs the state of the download that's seeder and is useful for debugging purposes. """ if self.tunnel_community_seeder: self.tunnel_community_seeder.monitor_downloads([ds]) d = ds.get_download() self._logger.debug("seeder: %s %s %s", repr(d.get_def().get_name()), dlstatus_strings[ds.get_status()], ds.get_progress()) return 5.0 def start_anon_download(self, hops=1): """ Start an anonymous download in the main Tribler session. """ dscfg = DownloadStartupConfig() dscfg.set_dest_dir(self.getDestDir()) dscfg.set_hops(hops) download = self.session.start_download_from_tdef(self.seed_tdef, dscfg) download.add_peer(("127.0.0.1", self.session2.config.get_libtorrent_port())) return download @inlineCallbacks def deliver_messages(self, timeout=.1): """ Allow peers to communicate. The strategy is as follows: 1. Measure the amount of working threads in the threadpool 2. After 10 milliseconds, check if we are down to 0 twice in a row 3. If not, go back to handling calls (step 2) or return, if the timeout has been reached :param timeout: the maximum time to wait for messages to be delivered """ rtime = 0 probable_exit = False while rtime < timeout: yield self.sleep(.01) rtime += .01 if len(reactor.getThreadPool().working) == 0: if probable_exit: break probable_exit = True else: probable_exit = False @inlineCallbacks def sleep(self, time=.05): yield deferLater(reactor, time, lambda: None)
class TestTunnelBase(TestAsServer): @inlineCallbacks def setUp(self): """ Setup various variables and load the tunnel community in the main downloader session. """ yield TestAsServer.setUp(self) self.seed_tdef = None self.sessions = [] self.session2 = None self.bypass_dht = False self.seed_config = None self.tunnel_community_seeder = None self.eccrypto = ECCrypto() ec = self.eccrypto.generate_key(u"curve25519") self.test_class = TriblerTunnelCommunity self.test_class.master_peer = Peer(ec) self.tunnel_community = self.load_tunnel_community_in_session( self.session, exitnode=True) self.tunnel_communities = [] def setUpPreSession(self): TestAsServer.setUpPreSession(self) self.config.set_ipv8_enabled(True) self.config.set_ipv8_port(-1) self.config.set_libtorrent_enabled(True) self.config.set_trustchain_enabled(False) self.config.set_tunnel_community_socks5_listen_ports( self.get_socks5_ports()) @inlineCallbacks def tearDown(self): if self.session2: yield self.session2.shutdown() for session in self.sessions: yield session.shutdown() yield TestAsServer.tearDown(self) @inlineCallbacks def setup_nodes(self, num_relays=1, num_exitnodes=1, seed_hops=0): """ Setup all required nodes, including the relays, exit nodes and seeder. """ baseindex = 3 for i in xrange(baseindex, baseindex + num_relays): # Normal relays proxy = yield self.create_proxy(i) self.tunnel_communities.append(proxy) baseindex += num_relays + 1 for i in xrange(baseindex, baseindex + num_exitnodes): # Exit nodes proxy = yield self.create_proxy(i, exitnode=True) self.tunnel_communities.append(proxy) # Setup the seeder session yield self.setup_tunnel_seeder(seed_hops) # Add the tunnel community of the downloader session self.tunnel_communities.append(self.tunnel_community) self._logger.info("Introducing all nodes to each other in tests") other_tunnel_communities = [self.tunnel_community_seeder ] if self.tunnel_community_seeder else [] for community_introduce in self.tunnel_communities + other_tunnel_communities: for community in self.tunnel_communities + other_tunnel_communities: if community != community_introduce: community.walk_to( community_introduce.endpoint.get_address()) yield self.deliver_messages() def sanitize_network(self, session): # We disable the discovery communities in this session since we don't want to walk to the live network for overlay in session.lm.ipv8.overlays: if isinstance(overlay, DiscoveryCommunity): overlay.unload() session.lm.ipv8.overlays = [] session.lm.ipv8.strategies = [] # Also reset the IPv8 network session.lm.ipv8.network = Network() def load_tunnel_community_in_session(self, session, exitnode=False): """ Load the tunnel community in a given session. We are using our own tunnel community here instead of the one used in Tribler. """ self.sanitize_network(session) keypair = ECCrypto().generate_key(u"curve25519") tunnel_peer = Peer(keypair) session.config.set_tunnel_community_exitnode_enabled(exitnode) overlay = self.test_class(tunnel_peer, session.lm.ipv8.endpoint, session.lm.ipv8.network, tribler_session=session, dht_provider=MockDHTProvider( session.lm.ipv8.endpoint.get_address()), settings={ "become_exitnode": exitnode, "max_circuits": 1 }) overlay._use_main_thread = False overlay.settings.remove_tunnel_delay = 0 session.lm.ipv8.overlays.append(overlay) return overlay @inlineCallbacks def create_proxy(self, index, exitnode=False): """ Create a single proxy and load the tunnel community in the session of that proxy. """ from Tribler.Core.Session import Session self.setUpPreSession() config = self.config.copy() config.set_libtorrent_enabled(True) config.set_state_dir(self.getStateDir(index)) config.set_tunnel_community_socks5_listen_ports( self.get_socks5_ports()) session = Session(config) yield session.start() self.sessions.append(session) returnValue( self.load_tunnel_community_in_session(session, exitnode=exitnode)) def setup_tunnel_seeder(self, hops): """ Setup the seeder. """ from Tribler.Core.Session import Session self.seed_config = self.config.copy() self.seed_config.set_state_dir(self.getStateDir(2)) self.seed_config.set_tunnel_community_socks5_listen_ports( self.get_socks5_ports()) if self.session2 is None: self.session2 = Session(self.seed_config) self.session2.start() tdef = TorrentDef() tdef.add_content(os.path.join(TESTS_DATA_DIR, "video.avi")) tdef.set_tracker("http://localhost/announce") torrentfn = os.path.join(self.session2.config.get_state_dir(), "gen.torrent") tdef.save(torrent_filepath=torrentfn) self.seed_tdef = tdef if hops > 0: # Safe seeding enabled self.tunnel_community_seeder = self.load_tunnel_community_in_session( self.session2) self.tunnel_community_seeder.build_tunnels(hops) else: self.sanitize_network(self.session2) dscfg = DownloadStartupConfig() dscfg.set_dest_dir( TESTS_DATA_DIR) # basedir of the file we are seeding dscfg.set_hops(hops) d = self.session2.start_download_from_tdef(tdef, dscfg) d.set_state_callback(self.seeder_state_callback) def seeder_state_callback(self, ds): """ The callback of the seeder download. For now, this only logs the state of the download that's seeder and is useful for debugging purposes. """ if self.tunnel_community_seeder: self.tunnel_community_seeder.monitor_downloads([ds]) d = ds.get_download() self._logger.debug("seeder: %s %s %s", repr(d.get_def().get_name()), dlstatus_strings[ds.get_status()], ds.get_progress()) return 5.0 def start_anon_download(self, hops=1): """ Start an anonymous download in the main Tribler session. """ dscfg = DownloadStartupConfig() dscfg.set_dest_dir(self.getDestDir()) dscfg.set_hops(hops) download = self.session.start_download_from_tdef(self.seed_tdef, dscfg) tc = self.session.lm.tunnel_community tc.bittorrent_peers[download] = [ ("127.0.0.1", self.session2.config.get_libtorrent_port()) ] return download @inlineCallbacks def deliver_messages(self, timeout=.1): """ Allow peers to communicate. The strategy is as follows: 1. Measure the amount of working threads in the threadpool 2. After 10 milliseconds, check if we are down to 0 twice in a row 3. If not, go back to handling calls (step 2) or return, if the timeout has been reached :param timeout: the maximum time to wait for messages to be delivered """ rtime = 0 probable_exit = False while rtime < timeout: yield self.sleep(.01) rtime += .01 if len(reactor.getThreadPool().working) == 0: if probable_exit: break probable_exit = True else: probable_exit = False @inlineCallbacks def sleep(self, time=.05): yield deferLater(reactor, time, lambda: None)