Exemple #1
0
def _handle_role_state_set(create_role, state):
    role_container = role_state_pb2.RoleAttributesContainer()
    role = role_container.role_attributes.add()
    role.role_id = create_role.role_id
    role.name = create_role.name
    role.metadata = create_role.metadata

    entries_to_set = [
        StateEntry(address=addresser.make_role_attributes_address(
            create_role.role_id),
                   data=role_container.SerializeToString())
    ]

    pubkeys_by_address = {}

    for admin in list(create_role.admins):
        admin_address = addresser.make_role_admins_address(
            role_id=create_role.role_id, user_id=admin)

        if admin_address in pubkeys_by_address:
            pubkeys_by_address[admin_address].append(admin)
        else:
            pubkeys_by_address[admin_address] = [admin]

    for owner in list(create_role.owners):
        owner_address = addresser.make_role_owners_address(
            role_id=create_role.role_id, user_id=owner)

        if owner_address in pubkeys_by_address:
            pubkeys_by_address[owner_address].append(owner)
        else:
            pubkeys_by_address[owner_address] = [owner]

    state_returns = get_state(state, [
        addresser.make_role_admins_address(role_id=create_role.role_id,
                                           user_id=a)
        for a in create_role.admins
    ] + [
        addresser.make_role_owners_address(role_id=create_role.role_id,
                                           user_id=o)
        for o in create_role.owners
    ])

    for addr, pubkeys in pubkeys_by_address.items():
        try:
            state_entry = get_state_entry(state_returns, addr)
            container = role_state_pb2.RoleRelationshipContainer()
            container.ParseFromString(state_entry.data)
        except KeyError:
            container = role_state_pb2.RoleRelationshipContainer()

        _add_role_rel_to_container(container, create_role.role_id, pubkeys)

        entries_to_set.append(
            StateEntry(address=addr, data=container.SerializeToString()))
    set_state(state, entries_to_set)
def _store_state_data(addr, new_state, context):
    LOGGER.debug('Storing Upadated State....\nUPDATED STATE:\n%s', new_state)
    addresses = context.set_state(
        [StateEntry(address=addr, data=json.dumps(new_state).encode())])

    if len(addresses) < 1:
        raise InternalError("State Error")
Exemple #3
0
def _set_setting_value(context, key, value):
    address = _make_settings_key(key)
    setting = _get_setting_entry(context, address)

    old_value = None
    old_entry_index = None
    for i, entry in enumerate(setting.entries):
        if key == entry.key:
            old_value = entry.value
            old_entry_index = i

    if old_entry_index is not None:
        setting.entries[old_entry_index].value = value
    else:
        setting.entries.add(key=key, value=value)

    try:
        addresses = list(
            context.set_state([
                StateEntry(address=address, data=setting.SerializeToString())
            ],
                              timeout=STATE_TIMEOUT_SEC))
    except FutureTimeoutError:
        LOGGER.warning('Timeout occured on context.set_state([%s, <value>])',
                       address)
        raise InternalError('Unable to set {}'.format(key))

    if len(addresses) != 1:
        LOGGER.warning('Failed to save value on address %s', address)
        raise InternalError('Unable to save config value {}'.format(key))
    if setting != 'sawtooth.settings.vote.proposals':
        LOGGER.info('Setting setting %s changed from %s to %s', key, old_value,
                    value)
def handle_propose_state_set(state_entries,
                             header,
                             payload,
                             address,
                             proposal_type,
                             state,
                             related_type='user_id'):

    try:

        entry = get_state_entry(state_entries, address=address)
        proposal_container = return_prop_container(entry)
    except KeyError:
        proposal_container = proposal_state_pb2.ProposalsContainer()

    proposal = proposal_container.proposals.add()

    proposal.proposal_id = payload.proposal_id
    proposal.object_id = payload.task_id
    proposal.target_id = getattr(payload, related_type)
    proposal.proposal_type = proposal_type
    proposal.status = proposal_state_pb2.Proposal.OPEN
    proposal.opener = header.signer_pubkey
    proposal.open_reason = payload.reason
    proposal.metadata = payload.metadata

    set_state(state, [
        StateEntry(address=address,
                   data=proposal_container.SerializeToString())
    ])
Exemple #5
0
def handle_state_set(proposal_state_entries, header, user_proposal, state):
    proposal_address = addresser.make_proposal_address(
        user_proposal.user_id, user_proposal.new_manager_id)
    try:

        state_entry = get_state_entry(proposal_state_entries, proposal_address)
        proposal_container = return_prop_container(state_entry)

    except KeyError:
        proposal_container = proposal_state_pb2.ProposalsContainer()

    proposal = proposal_container.proposals.add()
    proposal.proposal_id = user_proposal.proposal_id
    proposal.proposal_type = proposal_state_pb2.Proposal.UPDATE_USER_MANAGER
    proposal.object_id = user_proposal.user_id
    proposal.target_id = user_proposal.new_manager_id
    proposal.opener = header.signer_pubkey
    proposal.status = proposal_state_pb2.Proposal.OPEN
    proposal.open_reason = user_proposal.reason
    proposal.metadata = user_proposal.metadata

    set_state(state, [
        StateEntry(address=proposal_address,
                   data=proposal_container.SerializeToString())
    ])
Exemple #6
0
def _set_container(state, address, container):
    addresses = state.set(
        [StateEntry(
            address=address,
            data=container.SerializeToString(),
        )])

    if not addresses:
        raise InternalError('State error -- failed to set state entries')
def handle_create_task(state_entries, payload, state):
    try:
        entry = get_state_entry(
            state_entries,
            addresser.make_task_attributes_address(payload.task_id))
        container = return_task_container(entry)

    except KeyError:
        container = task_state_pb2.TaskAttributesContainer()

    task = container.task_attributes.add()

    task.task_id = payload.task_id
    task.name = payload.name
    task.metadata = payload.metadata

    address_values = []

    pubkeys_by_address = {}
    for pubkey in payload.admins:
        address = addresser.make_task_admins_address(
            task_id=payload.task_id,
            user_id=pubkey)
        if address in pubkeys_by_address:
            pubkeys_by_address[address].append(pubkey)
        else:
            pubkeys_by_address[address] = [pubkey]

    address_values += _handle_task_rel_container(
        state_entries=state_entries,
        create_task=payload,
        pubkeys_by_address=pubkeys_by_address,
        state=state)

    pubkeys_by_address = {}
    for pubkey in payload.owners:
        address = addresser.make_task_owners_address(
            task_id=payload.task_id,
            user_id=pubkey)
        if address in pubkeys_by_address:
            pubkeys_by_address[address].append(pubkey)
        else:
            pubkeys_by_address[address] = [pubkey]

    address_values += _handle_task_rel_container(
        state_entries=state_entries,
        create_task=payload,
        pubkeys_by_address=pubkeys_by_address,
        state=state)

    address_values += [StateEntry(
        address=addresser.make_task_attributes_address(payload.task_id),
        data=container.SerializeToString())]

    set_state(
        state,
        address_values)
Exemple #8
0
def _set_role(data, context):
    role = Role()
    role.ParseFromString(data)

    if not role.name:
        raise InvalidTransaction("The name must be set in a role")
    if not role.policy_name:
        raise InvalidTransaction("A role must contain a policy name.")

    # Check that the policy refernced exists
    policy_address = _get_policy_address(role.policy_name)
    entries_list = _get_data(policy_address, context)

    if entries_list == []:
        raise InvalidTransaction(
            "Cannot set Role: {}, the Policy: {} is not set.".format(
                role.name, role.policy_name))
    else:
        policy_list = PolicyList()
        policy_list.ParseFromString(entries_list[0].data)
        exist = False
        for policy in policy_list.policies:
            if policy.name == role.policy_name:
                exist = True
                break

        if not exist:
            raise InvalidTransaction(
                "Cannot set Role {}, the Policy {} is not set.".format(
                    role.name, role.policy_name))

    address = _get_role_address(role.name)
    entries_list = _get_data(address, context)

    # Store role in a Roleist incase of hash collisions
    role_list = RoleList()
    if entries_list != []:
        role_list.ParseFromString(entries_list[0].data)

    # sort all roles by using sorted(roles, Role.name)
    roles = [x for x in role_list.roles if x.name != role.name]
    roles.append(role)
    roles = sorted(roles, key=lambda role: role.name)

    # set RoleList at the address above.
    addresses = context.set_state([
        StateEntry(address=address,
                   data=RoleList(roles=roles).SerializeToString())
    ])

    if not addresses:
        LOGGER.warning('Failed to set role %s at %s', role.name, address)
        raise InternalError('Unable to save role {}'.format(role.name))

    context.add_event(event_type="identity_update",
                      attributes=[("updated", role.name)])
    LOGGER.debug("Set role: \n%s", role)
Exemple #9
0
def _set_state_data(name, state, state_store):
    address = make_intkey_address(name)

    encoded = cbor.dumps(state)

    addresses = state_store.set([StateEntry(address=address, data=encoded)])

    if not addresses:
        raise InternalError('State error')
Exemple #10
0
def handle_reject_state_set(container, proposal, closer, reason, address,
                            state):

    proposal.status = proposal_state_pb2.Proposal.REJECTED
    proposal.closer = closer
    proposal.close_reason = reason

    set_state(
        state,
        [StateEntry(address=address, data=container.SerializeToString())])
def handle_confirm_add(state_entries,
                       header,
                       confirm,
                       role_rel_address,
                       state,
                       rel_type='user_id'):
    proposal_address = addresser.make_proposal_address(
        object_id=confirm.role_id, related_id=getattr(confirm, rel_type))

    proposal_entry = get_state_entry(state_entries, proposal_address)
    proposal_container = return_prop_container(proposal_entry)
    proposal = get_prop_from_container(proposal_container,
                                       proposal_id=confirm.proposal_id)

    proposal.status = proposal_state_pb2.Proposal.CONFIRMED
    proposal.closer = header.signer_pubkey
    proposal.close_reason = confirm.reason

    address_values = [
        StateEntry(address=proposal_address,
                   data=proposal_container.SerializeToString())
    ]

    try:
        role_rel_entry = get_state_entry(state_entries, role_rel_address)
        role_rel_container = return_role_rel_container(role_rel_entry)
    except KeyError:
        role_rel_container = role_state_pb2.RoleRelationshipContainer()

    try:
        role_rel = get_role_rel(role_rel_container, confirm.role_id)

    except KeyError:
        role_rel = role_rel_container.relationships.add()
        role_rel.role_id = confirm.role_id

    role_rel.identifiers.append(getattr(confirm, rel_type))

    address_values.append(
        StateEntry(address=role_rel_address,
                   data=role_rel_container.SerializeToString()))

    set_state(state, address_values)
Exemple #12
0
def handle_confirm_state_set(container, proposal, closer, reason, address,
                             user_id, new_manager_id, state):
    proposal.status = proposal_state_pb2.Proposal.CONFIRMED
    proposal.closer = closer
    proposal.close_reason = reason

    set_state(
        state,
        [StateEntry(address=address, data=container.SerializeToString())])
    user_address = addresser.make_user_address(user_id)
    state_entries = get_state(state, [user_address])
    state_entry = get_state_entry(state_entries=state_entries,
                                  address=user_address)
    user_container = return_user_container(state_entry)
    user = get_user_from_container(user_container, user_id)
    user.manager_id = new_manager_id

    set_state(state, [
        StateEntry(address=user_address,
                   data=user_container.SerializeToString())
    ])
def handle_confirm_add(state_entries, header, confirm, task_rel_address,
                       state):
    proposal_address = addresser.make_proposal_address(
        object_id=confirm.task_id, related_id=confirm.user_id)

    proposal_entry = get_state_entry(state_entries, proposal_address)
    proposal_container = return_prop_container(proposal_entry)
    proposal = get_prop_from_container(proposal_container,
                                       proposal_id=confirm.proposal_id)

    proposal.status = proposal_state_pb2.Proposal.CONFIRMED
    proposal.closer = header.signer_pubkey
    proposal.close_reason = confirm.reason

    address_values = [
        StateEntry(address=proposal_address,
                   data=proposal_container.SerializeToString())
    ]

    try:
        task_rel_entry = get_state_entry(state_entries, task_rel_address)
        task_rel_container = return_task_rel_container(task_rel_entry)
    except KeyError:
        task_rel_container = task_state_pb2.TaskRelationshipContainer()

    try:
        task_rel = get_task_rel_from_container(container=task_rel_container,
                                               task_id=confirm.task_id,
                                               identifier=confirm.user_id)
    except KeyError:
        task_rel = task_rel_container.relationships.add()
        task_rel.task_id = confirm.task_id

    task_rel.identifiers.append(confirm.user_id)

    address_values.append(
        StateEntry(address=task_rel_address,
                   data=task_rel_container.SerializeToString()))

    set_state(state, address_values)
Exemple #14
0
 def _set(state, items):
     entries = []
     for (addr, container) in items:
         entries.append(
             StateEntry(address=addr, data=container.SerializeToString()))
     result_addresses = state.set(entries)
     if result_addresses:
         for (addr, _) in items:
             if addr not in result_addresses:
                 raise InternalError(
                     "Error setting state, " + "address %s not set.", addr)
     else:
         raise InternalError("Error setting state nothing updated?")
Exemple #15
0
def _set_policy(data, context):
    new_policy = Policy()
    new_policy.ParseFromString(data)

    if not new_policy.entries:
        raise InvalidTransaction("Atleast one entry must be in a policy.")

    if not new_policy.name:
        raise InvalidTransaction("The name must be set in a policy.")

    # check entries in the policy
    for entry in new_policy.entries:
        if not entry.key:
            raise InvalidTransaction("Every policy entry must have a key.")

    address = _get_policy_address(new_policy.name)
    entries_list = _get_data(address, context)

    policy_list = PolicyList()
    policies = []

    if entries_list != []:
        policy_list.ParseFromString(entries_list[0].data)

        # sort all roles by using sorted(roles, policy.name)
        # if a policy with the same name exists, replace that policy
        policies = [
            x for x in policy_list.policies if x.name != new_policy.name
        ]
        policies.append(new_policy)
        policies = sorted(policies, key=lambda role: role.name)
    else:
        policies.append(new_policy)

    address = _get_policy_address(new_policy.name)

    # Store policy in a PolicyList incase of hash collisions
    new_policy_list = PolicyList(policies=policies)
    addresses = context.set_state([
        StateEntry(address=address, data=new_policy_list.SerializeToString())
    ])

    if not addresses:
        LOGGER.warning('Failed to set policy %s at %s', new_policy.name,
                       address)
        raise InternalError('Unable to save policy {}'.format(new_policy.name))

    context.add_event(event_type="identity_update",
                      attributes=[("updated", new_policy.name)])
    LOGGER.debug("Set policy : \n%s", new_policy)
def handle_user_state_set(header, create_user, state, manager_id=None):
    user_container = user_state_pb2.UserContainer()
    user = user_state_pb2.User(user_id=create_user.user_id,
                               name=create_user.name,
                               metadata=create_user.metadata)
    if manager_id:
        user.manager_id = manager_id

    user_container.users.extend([user])

    set_state(state, [
        StateEntry(address=addresser.make_user_address(create_user.user_id),
                   data=user_container.SerializeToString())
    ])
Exemple #17
0
def _set_data(state, address, data):
    try:
        addresses = list(
            state.set([StateEntry(address=address, data=data)],
                      timeout=STATE_TIMEOUT_SEC))

    except FutureTimeoutError:
        LOGGER.warning('Timeout occurred on state.set([%s, <value>])', address)
        raise InternalError(
            'Failed to save value on address {}'.format(address))

    if len(addresses) != 1:
        LOGGER.warning('Failed to save value on address %s', address)
        raise InternalError(
            'Failed to save value on address {}'.format(address))
Exemple #18
0
def _store_state_data(context, game_list, namespace_prefix, name, board, state,
                      player1, player2):

    game_list[name] = board, state, player1, player2

    state_data = '|'.join(
        sorted([
            ','.join([name, board, state, player1, player2])
            for name, (board, state, player1, player2) in game_list.items()
        ])).encode()

    addresses = context.set_state([
        StateEntry(address=_make_xo_address(namespace_prefix, name),
                   data=state_data)
    ])

    if len(addresses) < 1:
        raise InternalError("State Error")
def handle_reject(state_entries, header, reject, state):
    proposal_address = addresser.make_proposal_address(
        object_id=reject.task_id, related_id=reject.user_id)

    proposal_entry = get_state_entry(state_entries, proposal_address)
    proposal_container = return_prop_container(proposal_entry)
    proposal = get_prop_from_container(proposal_container,
                                       proposal_id=reject.proposal_id)

    proposal.status = proposal_state_pb2.Proposal.REJECTED
    proposal.closer = header.signer_pubkey
    proposal.close_reason = reject.reason

    address_values = [
        StateEntry(address=proposal_address,
                   data=proposal_container.SerializeToString())
    ]

    set_state(state, address_values)
def _handle_task_rel_container(state_entries,
                               create_task,
                               pubkeys_by_address,
                               state):

    entries_to_set = []
    for addr, pubkeys in pubkeys_by_address.items():
        try:
            state_entry = get_state_entry(state_entries, addr)
            container = task_state_pb2.TaskRelationshipContainer()
            container.ParseFromString(state_entry.data)
        except KeyError:
            container = task_state_pb2.TaskRelationshipContainer()

        _add_task_rel_to_container(container, create_task.task_id, pubkeys)

        entries_to_set.append(
            StateEntry(
                address=addr,
                data=container.SerializeToString()))

    return entries_to_set
Exemple #21
0
 def _make_entries(self, protobuf=True):
     if protobuf:
         return [Entry(address=a, data=d)
                 for a, d in zip(self.addresses, self.data)]
     return [StateEntry(address=a, data=d)
             for a, d in zip(self.addresses, self.data)]
Exemple #22
0
    def apply(self, transaction, context):
        # Unpack payload
        txn = BlockInfoTxn()
        txn.ParseFromString(transaction.payload)
        next_block = txn.block

        # Validate block info fields
        if next_block.block_num < 0:
            raise InvalidTransaction(
                "Invalid block num '{}'".format(next_block.block_num))

        if not (validate_hex(next_block.previous_block_id, 128)
                or next_block.previous_block_id == "0000000000000000"):
            raise InvalidTransaction("Invalid previous block id '{}'".format(
                next_block.previous_block_id))

        if not validate_hex(next_block.signer_pubkey, 66):
            raise InvalidTransaction("Invalid signer pubkey '{}'".format(
                next_block.signer_pubkey))

        if not validate_hex(next_block.header_signature, 128):
            raise InvalidTransaction("Invalid header signature '{}'".format(
                next_block.header_signature))

        if next_block.timestamp <= 0:
            raise InvalidTransaction(
                "Invalid timestamp '{}'".format(next_block.timestamp))

        # Get config and previous block (according to the block info in the
        # transaction) from state
        entries = context.get_state([CONFIG_ADDRESS])

        deletes = []
        sets = []
        config = BlockInfoConfig()

        # If there is no config in state, we don't know anything about what's
        # in state, so we have to treat this as the first entry
        if not entries:
            # If sync tolerance or target count were not specified in the txn,
            # use default values.
            config.sync_tolerance = \
                DEFAULT_SYNC_TOLERANCE if txn.sync_tolerance == 0 \
                else txn.sync_tolerance

            config.target_count = \
                DEFAULT_TARGET_COUNT if txn.target_count == 0 \
                else txn.target_count

            config.latest_block = next_block.block_num
            config.oldest_block = next_block.block_num

            validate_timestamp(next_block.timestamp, config.sync_tolerance)

            sets.append((CONFIG_ADDRESS, config.SerializeToString()))
            sets.append((
                create_block_address(next_block.block_num),
                next_block.SerializeToString()))

        else:
            config.ParseFromString(entries[0].data)

            # If the config was changed in this transaction
            if txn.sync_tolerance != 0:
                config.sync_tolerance = txn.sync_tolerance
            if txn.target_count != 0:
                config.target_count = txn.target_count

            if next_block.block_num - 1 != config.latest_block:
                raise InvalidTransaction(
                    "Block number must be one more than previous block's."
                    " Got {} expected {}".format(
                        next_block.block_num, config.latest_block + 1))

            validate_timestamp(next_block.timestamp, config.sync_tolerance)

            entries = context.get_state(
                [create_block_address(config.latest_block)])
            if not entries:
                raise InternalError(
                    "Config and state out of sync. Latest block not found in"
                    " state.")

            prev_block = BlockInfo()
            prev_block.ParseFromString(entries[0].data)
            if prev_block.block_num != config.latest_block:
                raise InternalError(
                    "Block info stored at latest block has incorrect block"
                    " num.")

            if next_block.previous_block_id != prev_block.header_signature:
                raise InvalidTransaction(
                    "Previous block id must match header signature of previous"
                    " block. Go {} expected {}".format(
                        next_block.previous_block_id,
                        prev_block.header_signature))

            if next_block.timestamp < prev_block.timestamp:
                raise InvalidTransaction(
                    "Timestamp must be greater than previous block's."
                    " Got {}, expected >{}".format(
                        next_block.timestamp, prev_block.timestamp))

            config.latest_block = next_block.block_num
            while (config.latest_block - config.oldest_block) \
                    > config.target_count:
                deletes.append(create_block_address(config.oldest_block))
                config.oldest_block = config.oldest_block + 1

            sets.append((CONFIG_ADDRESS, config.SerializeToString()))
            sets.append((
                create_block_address(next_block.block_num),
                next_block.SerializeToString()))

        # If this is not true, something else has modified global state
        if deletes:
            if set(deletes) != set(context.delete(deletes)):
                raise InternalError(
                    "Blocks should have been in state but weren't: {}".format(
                        deletes))

        if sets:
            addresses = set([k for k, _ in sets])
            addresses_set = set(context.set_state([
                StateEntry(address=k, data=v) for k, v in sets]))
            if addresses != addresses_set:
                raise InternalError("Failed to set addresses.")

        return None