Ejemplo n.º 1
0
    def test_create_barter_record(self):
        """
        1. Create a single signed barter record
        2. Send signature request from SELF to NODE
        3. Add signature and send barter record from NODE to SELF
        4. Check database for the new record
        """
        community = BarterCommunity.create_community(self._my_member)
        address = self._dispersy.socket.get_address()

        # create node and ensure that SELF knows the node address
        node = BarterNode()
        node.init_socket()
        node.set_community(community)
        node.init_my_member()
        yield 0.11
        assert self.is_database_empty(
            community), "Database should be empty (for this community id)"

        # send single signed barter record
        message = community.create_barter_record(
            Member.get_instance(node.my_member.public_key), 10, 2)
        yield 0.11

        # receive signature request
        _, message = node.receive_message(
            addresses=[address], message_names=[u"dispersy-signature-request"])
        assert message.payload.message.name == u"barter-record"
        assert message.payload.message.authentication.members[
            0].public_key == community.my_member.public_key
        assert message.payload.message.authentication.members[
            1].public_key == node.my_member.public_key
        assert message.payload.message.authentication.signed_members[0][0]
        assert not message.payload.message.authentication.is_signed
        assert not message.payload.message.authentication.signed_members[1][0]
        assert message.payload.message.payload.first_upload == 10
        assert message.payload.message.payload.second_upload == 2

        # create signature and send data back
        message = message.payload.message
        first_signature_offset = len(message.packet) - sum(
            member.signature_length
            for member in message.authentication.members)
        signature = node.my_member.sign(message.packet,
                                        length=first_signature_offset)
        message.authentication.set_signature(
            Member.get_instance(node.my_member.public_key), signature)
        node.send_message(message, address)
        yield 0.11
        try:
            community._database.execute(
                u"SELECT 1 FROM record WHERE community = ? AND global_time = ? AND first_member = ? AND second_member = ? AND upload_first_member = ? AND upload_second_member = ?",
                (community.database_id, message.distribution.global_time,
                 node.my_member.database_id, community._my_member.database_id,
                 10, 2)).next()
        except StopIteration:
            assert False

        # cleanup
        community.create_dispersy_destroy_community(u"hard-kill")
Ejemplo n.º 2
0
    def test_incoming_barter_record(self):
        """
        1. Create a record signed only by NODE
        2. Send signature request from NODE to SELF
        3. Receive signature reply from SELF to NODE
        4. Check the signature
        5. Send double signed record from NODE to SELF
        6. Check that the record is stored in the database at SELF
        """
        community = BarterCommunity.create_community(self._my_member)
        address = self._dispersy.socket.get_address()

        # create node and ensure that SELF knows the node address
        node = BarterNode()
        node.init_socket()
        node.set_community(community)
        node.init_my_member()
        yield 0.11
        assert self.is_database_empty(community), "Database should be empty (for this community id)"

        # 1. Create a record signed only by NODE
        self_member = Member(community._my_member.public_key, sync_with_database=False)
        record = node.create_barter_record(self_member, 10, 2, 1)

        # 2. Send signature request from NODE to SELF
        request = node.create_dispersy_signature_request_message(record, 2, self_member)
        node.send_message(request, address)
        yield 0.11

        # 3. Receive signature reply from SELF to NODE
        # 4. Check the signature
        _, response = node.receive_message(addresses=[address], message_names=[u"dispersy-signature-response"])
        first_signature_offset = len(record.packet) - sum([member.signature_length for member in record.authentication.members])
        identifier = sha1(request.packet).digest()
        assert response.payload.identifier == identifier
        assert self_member.verify(record.packet[:first_signature_offset], response.payload.signature)

        # 5. Send double signed record from NODE to SELF
        second_signature_offset = len(record.packet) - record.authentication.members[1].signature_length
        packet = record.packet[:second_signature_offset] + response.payload.signature
        node.send_packet(packet, address)
        yield 0.11

        # 6. Check that the record is stored in the database at SELF
        try:
            community._database.execute(u"SELECT 1 FROM record WHERE community = ? AND global_time = ? AND first_member = ? AND second_member = ? AND upload_first_member = ? AND upload_second_member = ?",
                                        (community.database_id, 1, node.my_member.database_id, community._my_member.database_id, 10, 2)).next()
        except StopIteration:
            assert False

        # cleanup
        community.create_dispersy_destroy_community(u"hard-kill")
Ejemplo n.º 3
0
    def test_create_barter_record(self):
        """
        1. Create a single signed barter record
        2. Send signature request from SELF to NODE
        3. Add signature and send barter record from NODE to SELF
        4. Check database for the new record
        """
        community = BarterCommunity.create_community(self._my_member)
        address = self._dispersy.socket.get_address()

        # create node and ensure that SELF knows the node address
        node = BarterNode()
        node.init_socket()
        node.set_community(community)
        node.init_my_member()
        yield 0.11
        assert self.is_database_empty(community), "Database should be empty (for this community id)"

        # send single signed barter record
        message = community.create_barter_record(Member.get_instance(node.my_member.public_key), 10, 2)
        yield 0.11

        # receive signature request
        _, message = node.receive_message(addresses=[address], message_names=[u"dispersy-signature-request"])
        assert message.payload.message.name == u"barter-record"
        assert message.payload.message.authentication.members[0].public_key == community.my_member.public_key
        assert message.payload.message.authentication.members[1].public_key == node.my_member.public_key
        assert message.payload.message.authentication.signed_members[0][0]
        assert not message.payload.message.authentication.is_signed
        assert not message.payload.message.authentication.signed_members[1][0]
        assert message.payload.message.payload.first_upload == 10
        assert message.payload.message.payload.second_upload == 2

        # create signature and send data back
        message = message.payload.message
        first_signature_offset = len(message.packet) - sum(member.signature_length for member in message.authentication.members)
        signature = node.my_member.sign(message.packet, length=first_signature_offset)
        message.authentication.set_signature(Member.get_instance(node.my_member.public_key), signature)
        node.send_message(message, address)
        yield 0.11
        try:
            community._database.execute(u"SELECT 1 FROM record WHERE community = ? AND global_time = ? AND first_member = ? AND second_member = ? AND upload_first_member = ? AND upload_second_member = ?",
                                        (community.database_id, message.distribution.global_time, node.my_member.database_id, community._my_member.database_id, 10, 2)).next()
        except StopIteration:
            assert False

        # cleanup
        community.create_dispersy_destroy_community(u"hard-kill")
Ejemplo n.º 4
0
    def test_incoming_barter_record(self):
        """
        1. Create a record signed only by NODE
        2. Send signature request from NODE to SELF
        3. Receive signature reply from SELF to NODE
        4. Check the signature
        5. Send double signed record from NODE to SELF
        6. Check that the record is stored in the database at SELF
        """
        community = BarterCommunity.create_community(self._my_member)
        address = self._dispersy.socket.get_address()

        # create node and ensure that SELF knows the node address
        node = BarterNode()
        node.init_socket()
        node.set_community(community)
        node.init_my_member()
        yield 0.11
        assert self.is_database_empty(
            community), "Database should be empty (for this community id)"

        # 1. Create a record signed only by NODE
        self_member = Member(community._my_member.public_key,
                             sync_with_database=False)
        record = node.create_barter_record(self_member, 10, 2, 1)

        # 2. Send signature request from NODE to SELF
        request = node.create_dispersy_signature_request_message(
            record, 2, self_member)
        node.send_message(request, address)
        yield 0.11

        # 3. Receive signature reply from SELF to NODE
        # 4. Check the signature
        _, response = node.receive_message(
            addresses=[address],
            message_names=[u"dispersy-signature-response"])
        first_signature_offset = len(record.packet) - sum([
            member.signature_length for member in record.authentication.members
        ])
        identifier = sha1(request.packet).digest()
        assert response.payload.identifier == identifier
        assert self_member.verify(record.packet[:first_signature_offset],
                                  response.payload.signature)

        # 5. Send double signed record from NODE to SELF
        second_signature_offset = len(
            record.packet) - record.authentication.members[1].signature_length
        packet = record.packet[:second_signature_offset] + response.payload.signature
        node.send_packet(packet, address)
        yield 0.11

        # 6. Check that the record is stored in the database at SELF
        try:
            community._database.execute(
                u"SELECT 1 FROM record WHERE community = ? AND global_time = ? AND first_member = ? AND second_member = ? AND upload_first_member = ? AND upload_second_member = ?",
                (community.database_id, 1, node.my_member.database_id,
                 community._my_member.database_id, 10, 2)).next()
        except StopIteration:
            assert False

        # cleanup
        community.create_dispersy_destroy_community(u"hard-kill")
Ejemplo n.º 5
0
    def run(self):
        if __debug__: log("barter.log", "start-barter-script")
        # this master key NEEDS to be the same as that in BarterTrackerScript as they work together
        master_key = "3081a7301006072a8648ce3d020106052b81040027038192000403cbbfd2dfb67a7db66c88988df56f93fa6e7f982f9a6a0fa8898492c8b8cae23e10b159ace60b7047012082a5aa4c6e221d7e58107bb550436d57e046c11ab4f51f0ab18fa8f58d0346cc12d1cc2b61fc86fe5ed192309152e11e3f02489e30c7c971dd989e1ce5030ea0fb77d5220a92cceb567cbc94bc39ba246a42e215b55e9315b543ddeff0209e916f77c0d747".decode(
            "HEX")

        # remove all trackers.  this experiment may not be contaminated by outside influences
        self._dispersy.database.execute(
            u"DELETE FROM candidate where community=0")
        assert self._dispersy._total_send == 0
        assert self._dispersy._total_received == 0

        self._members = {}
        self.original_on_incoming_packets = self._dispersy.on_incoming_packets
        self.original_send = self._dispersy._send

        def _select_candidate_addresses(community_id, address_count,
                                        diff_range, age_range):
            addresses = set()
            sql = u"""SELECT host, port
                      FROM candidate
                      WHERE community = ?
                      ORDER BY RANDOM()
                      LIMIT ?"""
            addresses.update([
                (str(host), port)
                for host, port in self._dispersy.database.execute(
                    sql, (community_id, address_count - len(addresses)))
            ])

            # return what we have
            if addresses:
                log("dispersy.log", "found-candidates")
            return addresses
            # return set(["1.1.1.1",1111]) # send UDP packet to nowhere

        self._dispersy._select_candidate_addresses = _select_candidate_addresses

        #
        # Read our configuration from the peer.conf file
        # name, ip, port, public and private key
        #
        with open('data/peer.conf') as fp:
            my_name, ip, port, public_key, private_key = fp.readline().split()
            public_key = public_key.decode("HEX")
            private_key = private_key.decode("HEX")
            my_address = (ip, int(port))
        if __debug__: log("barter.log", "read-config-done")

        # create my member
        my_member = Member(public_key, private_key, sync_with_database=True)
        dprint(my_member)
        my_public_key = public_key

        # populate the candidate and user tables
        if __debug__:
            _peer_counter = 0
        # assume that this will be the ID, check after community is joined that the value is correct
        community_database_id = 1
        _peer_ids = {}
        all_peers = []
        execute = self._dispersy.database.execute
        with open('data/peers') as file:
            for index, line in zip(count(), file):
                name, ip, port, public_key, private_key = line.split(' ')
                if __debug__:
                    _peer_counter += 1
                    log("barter.log",
                        "read-peer-config",
                        position=_peer_counter,
                        name=name,
                        ip=ip,
                        port=port)
                port = int(port)
                public_key = public_key.decode('HEX')
                private_key = private_key.strip().decode(
                    "HEX")  # stip to remove newline character
                _peer_ids[public_key] = int(name)
                all_peers.append((index, (ip, port), public_key, private_key))
                if name == my_name: continue

                #self._dispersy._send([(ip, port)], [message.packet])
                execute(
                    u"INSERT OR IGNORE INTO candidate(community, host, port, incoming_time, outgoing_time) VALUES(?, ?, ?, DATETIME(), '2010-01-01 00:00:00')",
                    (community_database_id, unicode(ip), port))
                # execute(u"INSERT OR IGNORE INTO user(mid, public_key, host, port) VALUES(?, ?, ?, ?)", (buffer(sha1(public_key).digest()), buffer(public_key), unicode(ip), port))
                #if __debug__:
                #    log("barter.log", "mid_add", mid=sha1(public_key).digest())

        # join the barter community with the newly created member
        self._barter = BarterCommunity.join_community(
            sha1(master_key).digest(), master_key, my_member)
        assert self._barter.database_id == community_database_id

        self._barter._peer_ids = _peer_ids  # we set this internally in the BarterCommunity object

        # generate and insert all dispersy-identity messages
        incoming_packets = []
        meta = self._barter.get_meta_message(u"dispersy-identity")
        for index, address, public_key, private_key in all_peers:
            temp_member = Member(public_key,
                                 private_key,
                                 sync_with_database=False)
            message = meta.impl(
                authentication=(temp_member, ),
                distribution=(index + 10, ),  # give it a global time
                payload=(address, ))
            incoming_packets.append((address, message.packet))
        self._barter.dispersy.on_incoming_packets(incoming_packets)

        dprint("Joined barter community ", self._barter._my_member)
        if __debug__:
            log("barter.log", "joined-barter-community")
            log("barter.log",
                "barter-community-property",
                name="candidate_request_initial_delay",
                value=self._barter.dispersy_candidate_request_initial_delay)
            log("barter.log",
                "barter-community-property",
                name="candidate_request_interval",
                value=self._barter.dispersy_candidate_request_interval)
            log("barter.log",
                "barter-community-property",
                name="sync_initial_delay",
                value=self._barter.dispersy_sync_initial_delay.__doc__)
            log("barter.log",
                "barter-community-property",
                name="sync_interval",
                value=self._barter.dispersy_sync_interval.__doc__)
            log("barter.log",
                "barter-community-property",
                name="sync_member_count",
                value=self._barter.dispersy_sync_member_count)
            log("barter.log",
                "barter-community-property",
                name="sync_response_limit",
                value=self._barter.dispersy_sync_response_limit)
            log("barter.log",
                "barter-community-property",
                name="timestep",
                value=self._timestep)
            log("barter.log",
                "barter-community-property",
                name="barter_history_size",
                value="unused_(currently_using_FullSyncDistribution)")
            log("barter.log",
                "barter-community-property",
                name="barter_forward_record_on_creation",
                value=self._barter.barter_forward_record_on_creation)
            log("barter.log",
                "barter-community-property",
                name="barter_push_node_count",
                value=self._barter.get_meta_message(
                    u"barter-record").destination.node_count)
            log("barter.log",
                "barter-community-property",
                name="peer_id",
                value=_peer_ids[my_public_key])

        yield 2.0

        if __debug__:
            log("barter.log", "done-reading-peers")

        yield 2.0

        # open the scenario files, as generated from Mircea's Scenario
        # Generator
        bartercast_fp = open('data/bartercast.log')
        availability_fp = open('data/availability.log')

        self._stepcount = 0

        # wait until we reach the starting time
        yield self.sleep(initial_delay=True)

        self._stepcount = 1

        # start the scenario
        while True:
            # get commands
            barter_cmds = self.get_commands_from_fp(bartercast_fp,
                                                    self._stepcount)
            availability_cmds = self.get_commands_from_fp(
                availability_fp, self._stepcount)

            # if there are no commands exit the while loop
            if barter_cmds == -1 and availability_cmds == -1:
                if __debug__: log("barter.log", "no-commands")
                break
            else:
                # if there is a start in the avaibility_cmds then go
                # online
                if availability_cmds != -1 and 'start' in availability_cmds:
                    self.set_online()

                # if there are barter_cmds then execute them
                if barter_cmds != -1:
                    for cmd in barter_cmds:
                        name, up, down = cmd.split()
                        up, down = map(int, (up, down))
                        # note a peer creates a record when it has
                        # interest (e.g. it's upload is larger than
                        # its download)
                        if up >= down:
                            peer_member, address = self.find_peer_by_name(name)
                            self._barter.create_barter_record(
                                peer_member, up, down)

                # if there is a stop in the availability_cmds then go
                # offline
                if availability_cmds != -1 and 'stop' in availability_cmds:
                    self.set_offline()

            # sleep until the next step
            delay = self.sleep()
            if delay >= 0.0:
                yield delay
            else:
                break
            self._stepcount += 1

        # I finished the scenario execution. I should stay online
        # until killed. Note that I can still sync and exchange
        # messages with other peers.
        delay = self.sleep()
        while delay >= 0.0:
            # wait to be killed
            yield 5.0

        while True:
            now = time.time()
            if now >= self._shutdown_timestamp:
                break
            yield 5.0
Ejemplo n.º 6
0
    def run(self):
        if __debug__: log("barter.log", "start-barter-script")
        # this master key NEEDS to be the same as that in BarterTrackerScript as they work together
        master_key = "3081a7301006072a8648ce3d020106052b81040027038192000403cbbfd2dfb67a7db66c88988df56f93fa6e7f982f9a6a0fa8898492c8b8cae23e10b159ace60b7047012082a5aa4c6e221d7e58107bb550436d57e046c11ab4f51f0ab18fa8f58d0346cc12d1cc2b61fc86fe5ed192309152e11e3f02489e30c7c971dd989e1ce5030ea0fb77d5220a92cceb567cbc94bc39ba246a42e215b55e9315b543ddeff0209e916f77c0d747".decode("HEX")

        # remove all trackers.  this experiment may not be contaminated by outside influences
        self._dispersy.database.execute(u"DELETE FROM candidate where community=0")
        assert self._dispersy._total_send == 0
        assert self._dispersy._total_received == 0

        self._members = {}
        self.original_on_incoming_packets = self._dispersy.on_incoming_packets
        self.original_send = self._dispersy._send

        def _select_candidate_addresses(community_id, address_count, diff_range, age_range):
            addresses = set()
            sql = u"""SELECT host, port
                      FROM candidate
                      WHERE community = ?
                      ORDER BY RANDOM()
                      LIMIT ?"""
            addresses.update([(str(host), port)
                              for host, port
                              in self._dispersy.database.execute(sql, (community_id, address_count - len(addresses)))])

            # return what we have
            if addresses:
                log("dispersy.log","found-candidates")
            return addresses
            # return set(["1.1.1.1",1111]) # send UDP packet to nowhere
        self._dispersy._select_candidate_addresses = _select_candidate_addresses

        #
        # Read our configuration from the peer.conf file
        # name, ip, port, public and private key
        #
        with open('data/peer.conf') as fp:
            my_name, ip, port, public_key, private_key = fp.readline().split()
            public_key = public_key.decode("HEX")
            private_key = private_key.decode("HEX")
            my_address = (ip, int(port))
        if __debug__: log("barter.log", "read-config-done")

        # create my member
        my_member = Member(public_key, private_key, sync_with_database=True)
        dprint(my_member)
        my_public_key = public_key

        # populate the candidate and user tables
        if __debug__:
            _peer_counter = 0
        # assume that this will be the ID, check after community is joined that the value is correct
        community_database_id = 1
        _peer_ids = {}
        all_peers = []
        execute = self._dispersy.database.execute
        with open('data/peers') as file:
            for index, line in zip(count(), file):
                name, ip, port, public_key, private_key = line.split(' ')
                if __debug__:
                    _peer_counter += 1
                    log("barter.log", "read-peer-config", position=_peer_counter, name=name, ip=ip, port=port)
                port = int(port)
                public_key = public_key.decode('HEX')
                private_key = private_key.strip().decode("HEX") # stip to remove newline character
                _peer_ids[public_key] = int(name)
                all_peers.append((index, (ip, port), public_key, private_key))
                if name == my_name: continue

                #self._dispersy._send([(ip, port)], [message.packet])
                execute(u"INSERT OR IGNORE INTO candidate(community, host, port, incoming_time, outgoing_time) VALUES(?, ?, ?, DATETIME(), '2010-01-01 00:00:00')", (community_database_id, unicode(ip), port))
                # execute(u"INSERT OR IGNORE INTO user(mid, public_key, host, port) VALUES(?, ?, ?, ?)", (buffer(sha1(public_key).digest()), buffer(public_key), unicode(ip), port))
                #if __debug__:
                #    log("barter.log", "mid_add", mid=sha1(public_key).digest())

        # join the barter community with the newly created member
        self._barter = BarterCommunity.join_community(sha1(master_key).digest(), master_key, my_member)
        assert self._barter.database_id == community_database_id

        self._barter._peer_ids = _peer_ids # we set this internally in the BarterCommunity object

        # generate and insert all dispersy-identity messages
        incoming_packets = []
        meta = self._barter.get_meta_message(u"dispersy-identity")
        for index, address, public_key, private_key in all_peers:
            temp_member = Member(public_key, private_key, sync_with_database=False)
            message = meta.impl(authentication=(temp_member,),
                                distribution=(index + 10,), # give it a global time
                                payload=(address,))
            incoming_packets.append((address, message.packet))
        self._barter.dispersy.on_incoming_packets(incoming_packets)

        dprint("Joined barter community ", self._barter._my_member)
        if __debug__:
            log("barter.log", "joined-barter-community")
            log("barter.log", "barter-community-property", name="candidate_request_initial_delay", value=self._barter.dispersy_candidate_request_initial_delay)
            log("barter.log", "barter-community-property", name="candidate_request_interval", value=self._barter.dispersy_candidate_request_interval)
            log("barter.log", "barter-community-property", name="sync_initial_delay", value=self._barter.dispersy_sync_initial_delay.__doc__)
            log("barter.log", "barter-community-property", name="sync_interval", value=self._barter.dispersy_sync_interval.__doc__)
            log("barter.log", "barter-community-property", name="sync_member_count", value=self._barter.dispersy_sync_member_count)
            log("barter.log", "barter-community-property", name="sync_response_limit", value=self._barter.dispersy_sync_response_limit)
            log("barter.log", "barter-community-property", name="timestep", value=self._timestep)
            log("barter.log", "barter-community-property", name="barter_history_size", value="unused_(currently_using_FullSyncDistribution)")
            log("barter.log", "barter-community-property", name="barter_forward_record_on_creation", value=self._barter.barter_forward_record_on_creation)
            log("barter.log", "barter-community-property", name="barter_push_node_count", value=self._barter.get_meta_message(u"barter-record").destination.node_count)
            log("barter.log", "barter-community-property", name="peer_id", value=_peer_ids[my_public_key])

        yield 2.0

        if __debug__:
            log("barter.log", "done-reading-peers")

        yield 2.0

        # open the scenario files, as generated from Mircea's Scenario
        # Generator
        bartercast_fp = open('data/bartercast.log')
        availability_fp = open('data/availability.log')

        self._stepcount = 0

        # wait until we reach the starting time
        yield self.sleep(initial_delay=True)

        self._stepcount = 1

        # start the scenario
        while True:
            # get commands
            barter_cmds = self.get_commands_from_fp(bartercast_fp, self._stepcount)
            availability_cmds = self.get_commands_from_fp(availability_fp, self._stepcount)

            # if there are no commands exit the while loop
            if barter_cmds == -1 and availability_cmds == -1:
                if __debug__: log("barter.log", "no-commands")
                break
            else:
                # if there is a start in the avaibility_cmds then go
                # online
                if availability_cmds != -1 and 'start' in availability_cmds:
                    self.set_online()

                # if there are barter_cmds then execute them
                if barter_cmds != -1:
                    for cmd in barter_cmds:
                        name, up, down = cmd.split()
                        up, down = map(int, (up, down))
                        # note a peer creates a record when it has
                        # interest (e.g. it's upload is larger than
                        # its download)
                        if up >= down:
                            peer_member, address = self.find_peer_by_name(name)
                            self._barter.create_barter_record(peer_member, up, down)

                # if there is a stop in the availability_cmds then go
                # offline
                if availability_cmds != -1 and 'stop' in availability_cmds:
                    self.set_offline()

            # sleep until the next step
            delay = self.sleep()
            if delay >= 0.0:
                yield delay
            else:
                break
            self._stepcount += 1

        # I finished the scenario execution. I should stay online
        # until killed. Note that I can still sync and exchange
        # messages with other peers.
        delay = self.sleep()
        while delay >= 0.0:
            # wait to be killed
            yield 5.0

        while True:
            now = time.time()
            if now >= self._shutdown_timestamp:
                break
            yield 5.0