Esempio n. 1
0
    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
        tmp_member = self.dispersy.get_new_member(u"curve25519")

        # Create the transaction specification
        transaction = {
            'up': 0, 'down': amount
        }

        # Create the two half blocks that form the transaction
        local_half_block = TriblerChainBlock.create(transaction, self.persistence, self.my_member.public_key,
                                                    link_pk=tmp_member.public_key)
        local_half_block.sign(self.my_member.private_key)
        tmp_half_block = TriblerChainBlock.create(transaction, self.persistence, tmp_member.public_key,
                                                  link=local_half_block, link_pk=self.my_member.public_key)
        tmp_half_block.sign(tmp_member.private_key)

        self.persistence.add_block(local_half_block)
        self.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_member.private_key.key_to_bin().encode('base64'),
                  'transaction': {'up': amount, 'down': 0}, 'block': block}
        return result
Esempio n. 2
0
    def on_balance_request(self, payload):
        """
        We received a balance request from a relay or exit node. Respond with the latest block in our chain.
        """
        if not self.triblerchain_community:
            return

        # Get the latest block
        latest_block = self.triblerchain_community.persistence.get_latest(
            self.my_peer.public_key.key_to_bin())
        if not latest_block:
            latest_block = TriblerChainBlock()
        latest_block.public_key = EMPTY_PK  # We hide the public key

        # We either send the response directly or relay the response to the last verified hop
        circuit = self.circuits[payload.circuit_id]
        if not circuit.hops:
            self.increase_bytes_sent(
                circuit,
                self.send_cell([circuit.sock_addr], u"balance-response",
                               BalanceResponsePayload.from_half_block(
                                   latest_block, circuit.circuit_id)))
        else:
            self.increase_bytes_sent(
                circuit,
                self.send_cell([circuit.sock_addr], u"relay-balance-response",
                               BalanceResponsePayload.from_half_block(
                                   latest_block, circuit.circuit_id)))
    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)
Esempio n. 4
0
 def test_validate_not_sane_zeroes(self):
     db = MockDatabase()
     block1 = TriblerChainBlock()
     # Act
     block1.transaction = {'up': 0, 'down': 0, 'total_up': 30, 'total_down': 40}
     result = block1.validate(db)
     self.assertEqual(result[0], ValidationResult.invalid)
     self.assertIn("Up and down are zero", result[1])
Esempio n. 5
0
 def test_validate_not_sane_negatives(self):
     db = MockDatabase()
     block1 = TriblerChainBlock()
     # Act
     block1.transaction = {'up': -10, 'down': -10, 'total_up': -20, 'total_down': -10}
     result = block1.validate(db)
     self.assertEqual(result[0], ValidationResult.invalid)
     self.assertIn("Up field is negative", result[1])
     self.assertIn("Down field is negative", result[1])
     self.assertIn("Total up field is negative", result[1])
     self.assertIn("Total down field is negative", result[1])
Esempio n. 6
0
 def on_balance_response_cell(self, source_address, data, _):
     _, payload = self._ez_unpack_noauth(BalanceResponsePayload, data)
     block = TriblerChainBlock.from_payload(payload, self.serializer)
     if not block.transaction:
         self.on_token_balance(payload.circuit_id, 0)
     else:
         self.on_token_balance(payload.circuit_id,
                               block.transaction["total_up"] - block.transaction["total_down"])
Esempio n. 7
0
 def test_validate_linked_down(self):
     db = MockDatabase()
     (block1, block2, _, _) = TestBlocks.setup_validate()
     db.add_block(block2)
     # Act
     db.add_block(TriblerChainBlock.create(block1.transaction, db, block1.link_public_key, block1))
     block1.transaction["down"] -= 5
     result = block1.validate(db)
     self.assertEqual(result[0], ValidationResult.invalid)
     self.assertIn("Down/up mismatch on linked block", result[1])
Esempio n. 8
0
    def on_relay_balance_response_cell(self, source_address, data, _):
        _, payload = self._ez_unpack_noauth(BalanceResponsePayload, data)
        block = TriblerChainBlock.from_payload(payload, self.serializer)

        # At this point, we don't have the circuit ID of the follow-up hop. We have to iterate over the items in the
        # request cache and find the link to the next hop.
        for cache in self.request_cache._identifiers.values():
            if isinstance(cache, ExtendRequestCache) and cache.from_circuit_id == payload.circuit_id:
                self.send_cell([cache.to_candidate_sock_addr],
                               u"balance-response",
                               BalanceResponsePayload.from_half_block(block, cache.to_circuit_id))
Esempio n. 9
0
 def test_validate_existing_total_up(self):
     # Arrange
     db = MockDatabase()
     (block1, block2, block3, _) = TestBlocks.setup_validate()
     db.add_block(block1)
     db.add_block(block2)
     db.add_block(block3)
     # Act
     block2 = TriblerChainBlock(block2.pack_db_insert())
     block2.transaction["total_up"] += 10
     block2.sign(db.get(block2.public_key, block2.sequence_number).key)
     result = block2.validate(db)
     # Assert
     self.assertEqual(result[0], ValidationResult.invalid)
     self.assertIn('Total up is higher than expected compared to the next block', result[1])
Esempio n. 10
0
    def test_crawl_request(self):
        """
        Test whether a crawl request is sent when receiving an introduction response
        """
        his_pk = self.nodes[1].overlay.my_peer.public_key.key_to_bin()
        block = TriblerChainBlock.create(
            {
                'up': 20,
                'down': 40
            },
            self.nodes[0].overlay.persistence,
            self.nodes[0].overlay.my_peer.public_key.key_to_bin(),
            link=None,
            link_pk=his_pk)
        block.sign(self.nodes[0].overlay.my_peer.key)
        self.nodes[0].overlay.persistence.add_block(block)

        yield self.introduce_nodes()

        # The block should be available in the databases of both involved parties.
        for node_nr in [0, 1]:
            self.assertIsNotNone(self.nodes[node_nr].overlay.persistence.get(
                self.nodes[0].overlay.my_peer.public_key.key_to_bin(), 1))