Exemple #1
0
 def setUp(self):
     self.private_key = SigningKey.generate()
     self.public_keys = tuple(PublicKey.from_signing_key(SigningKey.generate()) for _ in range(2))
     self.operation = Operation(OperationRev(), 'http://example.com', self.public_keys)
     sign_object(PublicKey.from_signing_key(self.private_key), self.private_key, self.operation)
     self.uuid = self.operation.uuid
     self.identifier = Identifier.from_operation(self.operation)
Exemple #2
0
    def test_delete_blocks(self):
        blocks = self.add_blocks(self.add_operations())
        bc = get_blockchain()

        with patch.object(BlockChain, '_get_new_blocks', return_value=blocks):
            bc.update_blocks()

        with self.assertRaisesRegex(Block.ChainOperationBlockedError, "can't remove: blocked by another block"):
            blocks[4].remove()

        self.assertEqual(bc.max_depth, 5)
        self.assertEqual(bc.head, blocks[5].id)

        for block_to_remove, max_depth, heads in (
                (blocks[5], 5, [blocks[6].id]),
                (blocks[6], 4, [blocks[3].id, blocks[4].id]),
                (blocks[4], 4, [blocks[3].id]),
                (blocks[3], 3, [blocks[2].id]),
                (blocks[2], 2, [blocks[1].id]),
                (blocks[1], 1, [blocks[0].id]),
                (blocks[0], 0, [BlockRev().id])
        ):
            block_to_remove.remove()
            self.assertEqual(bc.max_depth, max_depth)
            self.assertIn(bc.head, heads)

        with patch.object(BlockChain, '_get_new_blocks', return_value=blocks):
            bc.update_blocks()

        self.assertEqual(bc.max_depth, 5)
        self.assertEqual(bc.head, blocks[5].id)

        self.assertCountEqual([op.uuid for op in blocks[0].operations + blocks[2].operations[1:2]],
                              Identifier.get_uuid_list())
Exemple #3
0
    def test_no_database(self):
        with self.assertRaisesRegex(pmpi.database.Database.InitialisationError, "initialise database first"):
            Identifier.get_uuid_list()

        with self.assertRaisesRegex(pmpi.database.Database.InitialisationError, "initialise database first"):
            Identifier.get(uuid4())

        operation = Operation(OperationRev(), 'http://example.com/', [])
        sk = SigningKey.generate()
        sign_object(PublicKey.from_signing_key(sk), sk, operation)
        identifier = Identifier.from_operation(operation)

        with self.assertRaisesRegex(pmpi.database.Database.InitialisationError, "initialise database first"):
            identifier.put()

        with self.assertRaisesRegex(pmpi.database.Database.InitialisationError, "initialise database first"):
            identifier.remove()
Exemple #4
0
    def test_2_put_remove(self):
        for identifier in self.identifiers:
            identifier.put()

        uuid_list = Identifier.get_uuid_list()

        self.assertEqual(len(uuid_list), 2)
        self.assertCountEqual(uuid_list, [identifier.uuid for identifier in self.identifiers])

        for identifier in self.identifiers:
            new_id = Identifier.get(identifier.uuid)
            self.assertEqual(new_id.uuid, identifier.uuid)
            self.assertEqual(new_id.operation_rev, identifier.operation_rev)

        self.identifiers[0].remove()

        with self.assertRaises(Identifier.DoesNotExist):
            self.identifiers[0].remove()  # already removed identifier

        self.assertCountEqual(Identifier.get_uuid_list(), [self.identifiers[1].uuid])

        with self.assertRaises(Identifier.DoesNotExist):
            Identifier.get(self.identifiers[0].uuid)
Exemple #5
0
    def __set_head(self, new_head_id):
        lca_id = self.__lowest_common_ancestor(self.head, new_head_id)
        blocks_after_lca = self.backward_blocks_chain(self.head, lca_id)[:-1]

        for identifier in [Identifier.get(uuid) for uuid in Identifier.get_uuid_list()]:
            op = identifier.operation_rev.obj
            containing_blocks = list(filter(lambda bl: bl in blocks_after_lca, op.containing_blocks))
            if len(containing_blocks) == 1:
                while len(containing_blocks) == 1:  # while operation is in a block that belongs to path to the LCA
                    op = op.previous_operation_rev.obj
                    if op is not None:
                        containing_blocks = list(filter(lambda bl: bl in blocks_after_lca, op.containing_blocks))
                    else:
                        break

                identifier.remove()
                if op is not None:
                    identifier.operation_rev = op.get_rev()
                    identifier.put()

        for block_id in reversed(self.backward_blocks_chain(new_head_id, lca_id)[:-1]):
            for op in pmpi.block.Block.get(block_id).operations:
                try:
                    identifier = Identifier.get(op.uuid)
                    if identifier.operation_rev == op.previous_operation_rev:
                        identifier.remove()
                        identifier.operation_rev = op.get_rev()
                        identifier.put()
                    else:
                        raise self.TreeError("inconsistency of operations")
                except Identifier.DoesNotExist:
                    if op.previous_operation_rev.is_none():
                        Identifier(op.uuid, op.get_rev()).put()
                    else:
                        raise self.TreeError("multiple minting of the identifier")

        self.__head = new_head_id
Exemple #6
0
    def new_operation(self):
        print("Choose UUID:")
        uuids_number = self.show_uuids()
        print('\n {}) mint new uuid'.format(uuids_number))

        def send_operation(operation):
            self.user.sign_object(operation)
            x = None
            while x not in ('y', 'n'):
                x = input("Send operation? (y/n) ")
            if x == 'y':
                self.transport.write(b'OP' + operation.raw())  # TODO also -- length of operation?

        try:
            x = int(input("index="))
            if x < uuids_number:
                uuid = Identifier.get_uuid_list()[x]
                operation = Identifier.get(uuid).operation_rev.obj

                if self.user._public_key.der not in operation.owners_der:
                    print("You do not own this identifier!")
                    return
                # TODO show sth

                address = input("address=")
                # TODO owners choose owners
                send_operation(Operation(operation.get_rev(), address, [self.user._public_key]))
            elif x == uuids_number:
                address = input("address=")
                # TODO owners choose owners
                send_operation(Operation(OperationRev(), address, [self.user._public_key]))
            else:
                print("Wrong number.")

        except ValueError:
            print("Value Error, aborting.")
Exemple #7
0
    def setUp(self):
        initialise_database('test_database_file')

        self.operations = [
            Operation(OperationRev(), 'http://example.com/' + url, [PublicKey.from_signing_key(SigningKey.generate())])
            for url in ('first/', 'second/')]

        for op in self.operations:
            sk = SigningKey.generate()
            sign_object(PublicKey.from_signing_key(sk), sk, op)

        block = Block.from_operations_list(BlockRev(), 42, self.operations)
        block.mine()
        sk = SigningKey.generate()
        sign_object(PublicKey.from_signing_key(sk), sk, block)
        block.put()

        self.identifiers = [Identifier.from_operation(op) for op in self.operations]
Exemple #8
0
def test():
    initialise_database('test_database_file')

    private_keys = [SigningKey.generate() for _ in range(3)]
    public_keys = [PublicKey.from_signing_key(private_key) for private_key in private_keys]
    uuids = [uuid4() for _ in range(3)]

    # BUILD    
    # blocks = add_blocks()
    #
    # for block in blocks:
    #     block.put()
    #
    # block_chain = BlockChain()
    #
    # block_chain_records_pattern = [
    #     BlockChain.Record(1, b'\x00'*32, [blocks[1].id]),
    #     BlockChain.Record(2, blocks[0].id, [blocks[2].id]),
    #     BlockChain.Record(3, blocks[1].id, sorted([blocks[3].id, blocks[4].id])),
    #     BlockChain.Record(4, blocks[2].id, [blocks[5].id]),
    #     BlockChain.Record(4, blocks[2].id, [blocks[6].id]),
    #     BlockChain.Record(5, blocks[3].id, []),
    #     BlockChain.Record(5, blocks[4].id, [])
    # ]
    #
    # for i in range(6):
    #     assertEqual(block_chain.get(blocks[i].id), block_chain_records_pattern[i])

    # UPDATE BLOCKS
    # blocks = add_blocks()
    # bc = get_blockchain()
    #
    # with patch.object(BlockChain, '_get_new_blocks', return_value=blocks):
    #     bc.update_blocks()
    #
    # assertEqual(bc.max_depth, 5)
    # assertEqual(bc.head, blocks[5].id)
    #
    # for block in blocks:
    #     assertEqual(bc.get(block.id).previous_id, block.previous_block_rev.id)

    # MULTIPLE UPDATE BLOCKS
    # blocks = add_blocks()
    # bc = get_blockchain()
    #
    # def patched_update_blocks(block_list):
    #     with patch.object(BlockChain, '_get_new_blocks', return_value=block_list):
    #         bc.update_blocks()
    #
    # for blocks_to_add, max_depth, head in (
    #         (blocks[0:2], 2, blocks[1].id),
    #         (blocks[2:3], 3, blocks[2].id),
    #         (blocks[4:5], 4, blocks[4].id),
    #         (blocks[3:4], 4, blocks[4].id),
    #         (blocks[5:6], 5, blocks[5].id),
    #         (blocks[6:7], 5, blocks[5].id)
    # ):
    #     patched_update_blocks(blocks_to_add)
    #     assertEqual(bc.max_depth, max_depth)
    #     assertEqual(bc.head, head)

    # DELETE

    blocks = add_blocks(uuids, private_keys, public_keys)
    bc = get_blockchain()

    with patch.object(BlockChain, '_get_new_blocks', return_value=blocks):
        bc.update_blocks()

    try:
        blocks[4].remove()
        raise AssertionError
    except Block.ChainOperationBlockedError:
        pass

    assert bc.max_depth == 5
    assert bc.head == blocks[5].id

    for block_to_remove, max_depth, heads in (
            (blocks[5], 5, [blocks[6].id]),
            (blocks[6], 4, [blocks[3].id, blocks[4].id]),
            (blocks[4], 4, [blocks[3].id]),
            (blocks[3], 3, [blocks[2].id]),
            (blocks[2], 2, [blocks[1].id]),
            (blocks[1], 1, [blocks[0].id]),
            (blocks[0], 0, [BlockRev().id])
    ):
        block_to_remove.remove()
        assert bc.max_depth == max_depth
        assert bc.head in heads

    with patch.object(BlockChain, '_get_new_blocks', return_value=blocks):
        bc.update_blocks()

    assert bc.max_depth == 5
    assert bc.head == blocks[5].id

    assert sorted([op.uuid for op in blocks[0].operations + blocks[2].operations[1:2]]) == sorted(
        Identifier.get_uuid_list())

    close_database()
    os.remove('test_database_file')
Exemple #9
0
 def test_1_get_from_empty(self):
     with self.assertRaises(Identifier.DoesNotExist):
         Identifier.get(self.identifiers[0].uuid)
Exemple #10
0
 def test_0_empty(self):
     self.assertEqual(len(Identifier.get_uuid_list()), 0)
Exemple #11
0
 def show_uuids():
     uuid_list = Identifier.get_uuid_list()
     digits = len(str(len(uuid_list)))
     for index, identifier in enumerate(Identifier.get_uuid_list()):
         print("{}) {} | {}".format(str(index).rjust(digits), identifier, Identifier.get(identifier).operation_rev.obj.address))
     return len(uuid_list)