コード例 #1
0
def test_addressing_key():
    """Tests making a blockchain address for a public key and that it:
    1. is a 35-byte non-zero hexadecimal string
    2. is unique - a different public key yields a different address
    3. is deterministic - same public key yields same address
    4. the addresser recognizes the address as a public key
    5. the addresser can parse the address into its components
    6. the identifier is a hash of the public key"""
    key = helper.user.key().public_key
    address = addresser.key.address(key)

    assert assert_is_address(address)
    assert address != addresser.key.address(helper.user.key().public_key)
    assert address == addresser.key.address(key)
    assert address == addresser.key.address(key.upper())

    assert addresser.get_address_type(address) == addresser.AddressSpace.KEY
    assert addresser.get_address_type(address) == addresser.AddressSpace.KEY

    parsed = addresser.parse(address)

    assert parsed.object_type == addresser.ObjectType.KEY
    assert parsed.related_type == addresser.ObjectType.NONE
    assert parsed.relationship_type == addresser.RelationshipType.NONE
    assert assert_is_identifier(parsed.object_id)
    assert not parsed.related_id

    assert parsed.object_id == addresser.key.hash(key)
コード例 #2
0
def test_addressing_user_key():
    """Tests making a blockchain address that is a user-key assignment:
    1. is a 35-byte non-zero hexadecimal string
    2. is unique - a different public user-key yields a different address
    3. is deterministic - same public user-key yields same address
    4. the addresser recognizes the address as a user-key
    5. the addresser can parse the address into its components
    6. the identifier is a hash of the user id
    7. the related identifier is a hash of the public key
    """
    key = helper.user.key().public_key
    user_id = helper.user.id()
    address = addresser.user.key.address(user_id, key)

    assert assert_is_address(address)
    assert address != addresser.user.key.address(user_id,
                                                 helper.user.key().public_key)
    assert address != addresser.user.key.address(helper.user.id(), key)
    assert address == addresser.user.key.address(user_id, key)

    assert addresser.get_address_type(
        address) == addresser.AddressSpace.USER_KEY
    assert addresser.get_address_type(
        address) == addresser.AddressSpace.USER_KEY

    parsed = addresser.parse(address)

    assert parsed.object_type == addresser.ObjectType.USER
    assert parsed.related_type == addresser.ObjectType.KEY
    assert parsed.relationship_type == addresser.RelationshipType.OWNER
    assert assert_is_identifier(parsed.object_id)

    assert parsed.object_id == addresser.user.hash(user_id)
    assert parsed.related_id == addresser.key.hash(key)
コード例 #3
0
def _remove_state(conn, address):
    """ Update the state, state_history and metadata tables
    """
    try:
        # update state table
        address_parts = addresser.parse(address)
        address_binary = bytes_from_hex(address)
        bytes_from_hex(address_parts.object_id)
        related_id = bytes_from_hex(address_parts.related_id)

        query = r.table("state").get(address_binary).delete(
            return_changes=True)
        result = query.run(conn)
        if result["errors"] > 0:
            LOGGER.warning("error deleting from state table:\n%s\n%s", result,
                           query)
        if result["deleted"] and "changes" in result and result["changes"]:
            result = (r.table("state_history").insert(
                result["changes"][0]["old_val"]).run(conn))
            if result["errors"] > 0:
                LOGGER.warning(
                    "error inserting into state_history table:\n%s\n%s",
                    result, query)

        if not related_id:
            query = r.table("metadata").get(address_binary).delete()
            result = query.run(conn)
            if result["errors"] > 0:
                LOGGER.warning("error removing metadata record:\n%s\n%s",
                               result, query)

    except Exception as err:  # pylint: disable=broad-except
        LOGGER.warning("remove_state %s error:", type(err))
        LOGGER.warning(err)
コード例 #4
0
def test_addressing_user():
    """Tests making a blockchain address for an next_id and that it:
    1. is a 35-byte non-zero hexadecimal string
    2. is unique - a different next_id yields a different address
    3. is deterministic - same next_id yields same address, even if different case
    4. the addresser recognizes the address as an next_id
    5. the addresser can parse the address into its components
    6. the identifier is a hash of the next_id"""
    next_id = helper.user.id()
    address = addresser.user.address(next_id)

    assert assert_is_address(address)
    assert address != addresser.user.address(helper.user.id())
    assert address == addresser.user.address(next_id)
    assert address == addresser.user.address(next_id.upper())

    assert addresser.get_address_type(address) == addresser.AddressSpace.USER

    parsed = addresser.parse(address)

    assert parsed.object_type == addresser.ObjectType.USER
    assert parsed.related_type == addresser.ObjectType.NONE
    assert parsed.relationship_type == addresser.RelationshipType.ATTRIBUTES
    assert assert_is_identifier(parsed.object_id)
    assert not parsed.related_id

    assert parsed.object_id == addresser.user.hash(next_id)
コード例 #5
0
def test_addressing_email():
    """Tests making a blockchain address for an email and that it:
    1. is a 35-byte non-zero hexadecimal string
    2. is unique - a different email yields a different address
    3. is deterministic - same email yields same address, even if different case
    4. the addresser recognizes the address as an email
    5. the addresser can parse the address into its components
    6. the identifier is a hash of the email"""
    email = helper.user.email()
    address = addresser.email.address(email)

    assert assert_is_address(address)
    assert address != addresser.email.address(helper.user.email())
    assert address == addresser.email.address(email)
    assert address == addresser.email.address(email.upper())

    assert addresser.get_address_type(address) == addresser.AddressSpace.EMAIL

    parsed = addresser.parse(address)

    assert parsed.object_type == addresser.ObjectType.EMAIL
    assert parsed.related_type == addresser.ObjectType.NONE
    assert parsed.relationship_type == addresser.RelationshipType.NONE
    assert assert_is_identifier(parsed.object_id)
    assert not parsed.related_id

    assert parsed.object_id == addresser.email.hash(email)
コード例 #6
0
def _update_state(database, block_num, address, resource):
    try:
        # update state table
        address_parts = addresser.parse(address)
        address_binary = bytes_from_hex(address)
        key = address_binary
        keys = {"address": address_binary}
        object_id = bytes_from_hex(address_parts.object_id)
        object_type = address_parts.object_type.value
        related_id = bytes_from_hex(address_parts.related_id)
        related_type = address_parts.related_type.value
        relationship_type = address_parts.relationship_type.value
        data = {
            "block_updated": int(block_num),
            "updated_at": r.now(),
            "object_type": object_type,
            "object_id": object_id,
            "related_type": related_type,
            "relationship_type": relationship_type,
            "related_id": related_id,
            **resource,
        }
        table_query = database.get_table("state")
        query = table_query.get(key).replace(
            lambda doc: r.branch(
                # pylint: disable=singleton-comparison
                (doc == None),  # noqa
                r.expr(data).merge(
                    {
                        "address": key,
                        "block_created": int(block_num),
                        "created_at": r.now(),
                    }
                ),
                doc.merge(data),
            )
        )
        result = database.run_query(query)
        if not result["inserted"] == 1 and not result["replaced"]:
            LOGGER.warning("error updating state table:\n%s\n%s", result, query)

        key = [address_binary, int(block_num)]
        data["address"] = key
        if result["inserted"] == 1:
            data["block_created"] = int(block_num)
            data["created_at"] = r.now()
        elif result["replaced"] == 1:
            LOGGER.warning(result)

        table_query = database.get_table("state_history")
        query = table_query.get(key).replace(data)
        result = database.run_query(query)
        if not result["inserted"] == 1 and not result["replaced"]:
            LOGGER.warning("error updating state_history table:\n%s\n%s", result, query)

    except Exception as err:  # pylint: disable=broad-except
        LOGGER.warning("update_state %s error:", type(err))
        LOGGER.warning(err)
コード例 #7
0
 def set_state(self, context, message, outputs, object_id, related_id=None):
     """Creates a new address in the blockchain state"""
     store = self.message_to_storage(message=message)
     # pylint: disable=no-member,not-callable
     container = self._state_container()
     getattr(container, self._state_container_list_name).extend([store])
     address = self.address(object_id=object_id, related_id=related_id)
     if address not in outputs:
         raise ValueError(
             "Address {} not in listed outputs".format(addresser.parse(address))
         )
     state_client.set_address(context=context, address=address, container=container)
コード例 #8
0
    def test_addresser_parse(self):
        """Test addresser.parse returns a parsed address"""
        user_id = addresser.user.unique_id()
        user_address = addresser.user.address(user_id)
        parsed = addresser.parse(user_address)

        self.assertEqual(parsed.object_type, addresser.ObjectType.USER)
        self.assertEqual(parsed.related_type, addresser.ObjectType.NONE)
        self.assertEqual(parsed.relationship_type,
                         addresser.RelationshipType.ATTRIBUTES)
        self.assertEqual(parsed.address_type, addresser.AddressSpace.USER)
        self.assertEqual(parsed.object_id, user_id)
        self.assertEqual(parsed.related_id, None)
コード例 #9
0
    def test_addresser_parse(self):
        """Test addresser.parse returns a parsed address"""
        role_id = addresser.sysadmin.address()
        user_id = addresser.user.unique_id()
        rel_address = addresser.sysadmin.admin.address(user_id)

        parsed = addresser.parse(rel_address)

        self.assertEqual(parsed.object_type, addresser.ObjectType.SYSADMIN)
        self.assertEqual(parsed.related_type, addresser.ObjectType.USER)
        self.assertEqual(parsed.relationship_type, addresser.RelationshipType.ADMIN)
        self.assertEqual(parsed.address_type, addresser.AddressSpace.SYSADMIN_ADMINS)
        self.assertEqual(parsed.object_id, user_id)
        self.assertEqual(parsed.related_id, None)
コード例 #10
0
    def test_addresser_parse(self):
        """Test addresser.parse returns a parsed address"""
        task_id = addresser.task.unique_id()
        user_id = addresser.user.unique_id()
        rel_address = addresser.task.owner.address(task_id, user_id)

        parsed = addresser.parse(rel_address)

        self.assertEqual(parsed.object_type, addresser.ObjectType.TASK)
        self.assertEqual(parsed.related_type, addresser.ObjectType.USER)
        self.assertEqual(parsed.relationship_type, addresser.RelationshipType.OWNER)
        self.assertEqual(parsed.address_type, addresser.AddressSpace.TASKS_OWNERS)
        self.assertEqual(parsed.object_id, task_id)
        self.assertEqual(parsed.related_id, user_id)
コード例 #11
0
    def test_addresser_parse(self):
        """Test addresser.parse returns a parsed address"""
        proposal_id = addresser.proposal.unique_id()
        proposal_address = addresser.proposal.address(proposal_id)

        parsed = addresser.parse(proposal_address)

        self.assertEqual(parsed.object_type, addresser.ObjectType.PROPOSAL)
        self.assertEqual(parsed.related_type, addresser.ObjectType.NONE)
        self.assertEqual(parsed.relationship_type,
                         addresser.RelationshipType.ATTRIBUTES)
        self.assertEqual(parsed.address_type, addresser.AddressSpace.PROPOSALS)
        self.assertEqual(parsed.object_id, proposal_id)
        self.assertEqual(parsed.related_id, None)
コード例 #12
0
    def test_addresser_parse(self):
        """Test addresser.parse returns a parsed address"""
        role_id = addresser.role.unique_id()
        role_address = addresser.role.address(role_id)

        parsed = addresser.parse(role_address)

        self.assertEqual(parsed.object_type, addresser.ObjectType.ROLE)
        self.assertEqual(parsed.related_type, addresser.ObjectType.NONE)
        self.assertEqual(parsed.relationship_type,
                         addresser.RelationshipType.ATTRIBUTES)
        self.assertEqual(parsed.address_type,
                         addresser.AddressSpace.ROLES_ATTRIBUTES)
        self.assertEqual(parsed.object_id, role_id)
        self.assertEqual(parsed.related_id, None)
コード例 #13
0
 def save_state(self, context, outputs, output_state):
     """Save the output state to the blockchain"""
     changed = [
         address
         for address in output_state.keys()
         if address in output_state["changed"]
     ]
     entries = {}
     for address in changed:
         if address not in outputs:
             raise ValueError(
                 "Address {} not in listed outputs".format(addresser.parse(address))
             )
         entries[address] = output_state[address].SerializeToString()
     state_client.set_state(context=context, entries=entries)
コード例 #14
0
    def test_addresser_parse(self):
        """Test addresser.parse returns a parsed address"""
        task_id = addresser.task.unique_id()
        task_address = addresser.task.address(task_id)

        parsed = addresser.parse(task_address)

        self.assertEqual(parsed.object_type, addresser.ObjectType.TASK)
        self.assertEqual(parsed.related_type, addresser.ObjectType.NONE)
        self.assertEqual(parsed.relationship_type,
                         addresser.RelationshipType.ATTRIBUTES)
        self.assertEqual(parsed.address_type,
                         addresser.AddressSpace.TASKS_ATTRIBUTES)
        self.assertEqual(parsed.object_id, task_id)
        self.assertEqual(parsed.related_id, None)
コード例 #15
0
 def _get_store(self, object_id, related_id, outputs, output_state):
     """Gets the store object to store data for this message"""
     address = self.address(object_id=object_id, related_id=related_id)
     container = None
     if address not in outputs and address in output_state:
         raise ValueError("Address {} not in listed outputs".format(
             addresser.parse(address)))
     if address in output_state:
         container = output_state[address]
         # TODO: is getting the first item in the container... may not be correct!
         store = getattr(container, self._state_container_list_name)[0]
     if not container:
         container, store = self._get_new_state()
         output_state[address] = container
     return store
コード例 #16
0
    def test_addresser_parse(self):
        """Test addresser.parse returns a parsed address"""
        sysadmin_address = addresser.sysadmin.address()

        parsed = addresser.parse(sysadmin_address)

        self.assertEqual(parsed.object_type, addresser.ObjectType.SYSADMIN)
        self.assertEqual(parsed.related_type, addresser.ObjectType.NONE)
        self.assertEqual(
            parsed.relationship_type, addresser.RelationshipType.ATTRIBUTES
        )
        self.assertEqual(
            parsed.address_type, addresser.AddressSpace.SYSADMIN_ATTRIBUTES
        )
        self.assertEqual(parsed.object_id, "000000000000000000000000")
        self.assertEqual(parsed.related_id, None)
コード例 #17
0
    def test_addresser_parse(self):
        """Test addresser.parse returns a parsed address"""
        role_id = addresser.role.unique_id()
        next_id = addresser.user.unique_id()
        rel_address = addresser.role.member.address(role_id, next_id)

        parsed = addresser.parse(rel_address)

        self.assertEqual(parsed.object_type, addresser.ObjectType.ROLE)
        self.assertEqual(parsed.related_type, addresser.ObjectType.USER)
        self.assertEqual(parsed.relationship_type,
                         addresser.RelationshipType.MEMBER)
        self.assertEqual(parsed.address_type,
                         addresser.AddressSpace.ROLES_MEMBERS)
        self.assertEqual(parsed.object_id, role_id)
        self.assertEqual(parsed.related_id, next_id)
コード例 #18
0
    def test_addresser_parse(self):
        """Test addresser.parse returns a parsed address"""
        role_id = addresser.role.unique_id()
        task_id = addresser.task.unique_id()
        rel_address = addresser.role.task.address(role_id, task_id)

        parsed = addresser.parse(rel_address)

        self.assertEqual(parsed.object_type, addresser.ObjectType.ROLE)
        self.assertEqual(parsed.related_type, addresser.ObjectType.TASK)
        self.assertEqual(parsed.relationship_type,
                         addresser.RelationshipType.MEMBER)
        self.assertEqual(parsed.address_type,
                         addresser.AddressSpace.ROLES_TASKS)
        self.assertEqual(parsed.object_id, role_id)
        self.assertEqual(parsed.related_id, task_id)
コード例 #19
0
def _remove_state(database, block_num, address):
    """ Update the state, state_history and metadata tables
    """
    try:
        # update state table
        now = r.now()
        address_parts = addresser.parse(address)
        address_binary = bytes_from_hex(address)
        object_id = bytes_from_hex(address_parts.object_id)
        object_type = address_parts.object_type.value
        related_id = bytes_from_hex(address_parts.related_id)
        related_type = address_parts.related_type.value
        relationship_type = address_parts.relationship_type.value

        state = database.get_table("state")
        state_history = database.get_table("state_history")

        query = state.get(address_binary).delete(return_changes=True)
        result = database.run_query(query)
        if result["errors"] > 0:
            LOGGER.warning("error deleting from state table:\n%s\n%s", result, query)
        if result["deleted"] and "changes" in result and result["changes"]:
            query = state_history.insert(result["changes"][0]["old_val"])
            result = database.run_query(query)
            if result["errors"] > 0:
                LOGGER.warning(
                    "error inserting into state_history table:\n%s\n%s", result, query
                )

        if not related_id:
            query = database.get_table("metadata").get(address_binary).delete()
            result = database.run_query(query)
            if result["errors"] > 0:
                LOGGER.warning("error removing metadata record:\n%s\n%s", result, query)

    except Exception as err:  # pylint: disable=broad-except
        LOGGER.warning("remove_state %s error:", type(err))
        LOGGER.warning(err)
コード例 #20
0
def _update_state(conn, block_num, address, resource):
    """ Update the state, state_history and metadata tables
    """
    try:
        # update state table
        now = r.now()
        address_parts = addresser.parse(address)
        address_binary = bytes_from_hex(address)
        object_id = bytes_from_hex(address_parts.object_id)
        object_type = address_parts.object_type.value
        related_id = bytes_from_hex(address_parts.related_id)
        related_type = address_parts.related_type.value
        relationship_type = address_parts.relationship_type.value

        data = {
            "address": address_binary,
            "object_type": object_type,
            "object_id": object_id,
            "related_type": related_type,
            "relationship_type": relationship_type,
            "related_id": related_id,
            "block_created": int(block_num),
            "block_num": int(block_num),
            "updated_date": now,
            **resource,
        }
        delta = {"block_num": int(block_num), "updated_at": now, **resource}

        query = (
            r.table("state").get(address_binary).replace(
                lambda doc: r.branch(
                    # pylint: disable=singleton-comparison
                    (doc == None),  # noqa
                    r.expr(data),
                    doc.merge(delta),
                ),
                return_changes=True,
            ))

        result = query.run(conn)

        if result["errors"] > 0:
            LOGGER.warning("error updating state table:\n%s\n%s", result,
                           query)
        if result["replaced"] and "changes" in result and result["changes"]:
            query = r.table("state_history").insert(
                result["changes"][0]["old_val"])
            result = query.run(conn)
            # data["address"] = [address_binary, int(block_num)]
            if result["errors"] > 0:
                LOGGER.warning("error updating state_history table:\n%s\n%s",
                               result, query)

        if not related_id:
            data["address"] = address_binary
            del data["related_type"]
            del data["relationship_type"]
            del data["related_id"]
            query = (
                r.table("metadata").get(address_binary).replace(
                    lambda doc: r.branch(
                        # pylint: disable=singleton-comparison
                        (doc == None),  # noqa
                        r.expr(data),
                        doc.merge(delta),
                    )))
            result = query.run(conn)
            if result["errors"] > 0:
                LOGGER.warning("error updating metadata record:\n%s\n%s",
                               result, query)

    except Exception as err:  # pylint: disable=broad-except
        LOGGER.warning("update_state %s error:", type(err))
        LOGGER.warning(err)