class SettingMessageFactory(object):
    def __init__(self, signer=None):
        self._asset_addr = Address(Address.FAMILY_ASSET)
        self._setting_addr = Address(Address.FAMILY_SETTING)
        self._factory = MessageFactory(
            family_name=Address.NAMESPACE_SETTING,
            family_version="0.1.0",
            namespace=[self._setting_addr.ns_family],
            signer=signer)

    @property
    def public_key(self):
        return self._factory.get_public_key()

    def create_tp_register(self):
        return self._factory.create_tp_register()

    def create_tp_response(self, status):
        return self._factory.create_tp_response(status)

    def _create_tp_process_request(self, dimension, payload):
        address = self._setting_addr.settings(dimension)
        inputs = [address, self._asset_addr.candidates(dimension)]
        outputs = [address, self._asset_addr.candidates(dimension)]
        return self._factory.create_tp_process_request(
            payload.SerializeToString(), inputs, outputs, [])

    def create_payload_request(self, settings, dimension, action):
        payload = SettingPayload(action=action,
                                 dimension=dimension,
                                 data=settings.SerializeToString())
        return self._create_tp_process_request(dimension, payload)

    def create_setting_transaction(self, auth_keys, thresh, dimension, action):
        setting = Settings(auth_list=auth_keys, threshold=thresh)
        return self.create_payload_request(setting, dimension, action)

    def create_get_request(self, address):
        return self._factory.create_get_request([address])

    def create_get_response(self, address, data=None):
        return self._factory.create_get_response({address: data})

    def create_set_request(self, address, setting=None):
        return self._factory.create_set_request({address: setting})

    def create_set_response(self, address):
        return self._factory.create_set_response([address])

    def create_add_event_request(self, key):
        return self._factory.create_add_event_request(
            "hashblock.setting/update", [("updated", key)])

    def create_add_event_response(self):
        return self._factory.create_add_event_response()
예제 #2
0
class IdentityMessageFactory(object):

    def __init__(self, private=None, public=None):
        self._factory = MessageFactory(
            encoding="application/protobuf",
            family_name="sawtooth_identity",
            family_version="1.0",
            namespace="00001d",
            private=private,
            public=public
        )

    @property
    def public_key(self):
        return self._factory.get_public_key()

    def _to_hash(self, value):
        return hashlib.sha256(value.encode()).hexdigest()

    def _role_to_address(self, role_name):
        # split the key into 4 parts, maximum
        key_parts = role_name.split('.', maxsplit=_MAX_KEY_PARTS - 1)

        # compute the short hash of each part
        addr_parts = [self._to_hash(key_parts[0])[:_FIRST_ADDRESS_PART_SIZE]]
        addr_parts += [self._to_hash(x)[:_ADDRESS_PART_SIZE] for x in
                       key_parts[1:]]
        # pad the parts with the empty hash, if needed
        addr_parts.extend([_EMPTY_PART] * (_MAX_KEY_PARTS - len(addr_parts)))
        return self._factory.namespace + _ROLE_PREFIX + ''.join(addr_parts)

    def _policy_to_address(self, policy_name):
        return self._factory.namespace + _POLICY_PREFIX + \
            self._to_hash(policy_name)[:62]

    def create_tp_register(self):
        return self._factory.create_tp_register()

    def create_tp_response(self, status):
        return self._factory.create_tp_response(status)

    def _create_tp_process_request(self, payload):
        inputs = []
        outputs = []
        if payload.type == IdentityPayload.ROLE:
            role = Role()
            role.ParseFromString(payload.data)
            inputs = [self._role_to_address(role.name),
                      self._policy_to_address(role.policy_name)]

            outputs = [self._role_to_address(role.name)]
        else:
            policy = Policy()
            policy.ParseFromString(payload.data)
            inputs = [self._policy_to_address(policy.name)]

            outputs = [self._role_to_address(policy.name)]

        return self._factory.create_tp_process_request(
            payload.SerializeToString(), inputs, outputs, [])

    def create_policy_transaction(self, name, rules):
        rules_list = rules.split("\n")
        entries = []
        for rule in rules_list:
            rule = rule.split(" ")
            if rule[0] == "PERMIT_KEY":
                entry = Policy.Entry(type=Policy.PERMIT_KEY,
                                     key=rule[1])
                entries.append(entry)
            elif rule[0] == "DENY_KEY":
                entry = Policy.Entry(type=Policy.DENY_KEY,
                                     key=rule[1])
                entries.append(entry)
        policy = Policy(name=name, entries=entries)
        payload = IdentityPayload(type=IdentityPayload.POLICY,
                                  data=policy.SerializeToString())
        return self._create_tp_process_request(payload)

    def create_role_transaction(self, name, policy_name):
        role = Role(name=name, policy_name=policy_name)
        payload = IdentityPayload(type=IdentityPayload.ROLE,
                                  data=role.SerializeToString())
        return self._create_tp_process_request(payload)

    def create_get_policy_request(self, name):
        addresses = [self._policy_to_address(name)]
        return self._factory.create_get_request(addresses)

    def create_get_policy_response(self, name, rules=None):
        data = None
        if rules is not None:
            rules_list = rules.split("\n")
            entries = []
            for rule in rules_list:
                rule = rule.split(" ")
                if rule[0] == "PERMIT_KEY":
                    entry = Policy.Entry(type=Policy.PERMIT_KEY,
                                         key=rule[0])
                    entries.append(entry)
                elif rule[0] == "DENY_KEY":
                    entry = Policy.Entry(type=Policy.DENY_KEY,
                                         key=rule[0])
                    entries.append(entry)
            policy = Policy(name=name, entries=entries)
            policy_list = PolicyList(policies=[policy])
            data = policy_list.SerializeToString()
        return self._factory.create_get_response(
            {self._policy_to_address(name): data})

    def create_get_role_request(self, name):
        addresses = [self._role_to_address(name)]
        return self._factory.create_get_request(addresses)

    def create_get_role_response(self, name, policy_name=None):
        data = None
        if policy_name is not None:
            role = Role(name=name, policy_name=policy_name)
            role_list = RoleList(roles=[role])
            data = role_list.SerializeToString()
        return self._factory.create_get_response({
            self._role_to_address(name): data})

    def create_set_policy_request(self, name, rules=None):
        rules_list = rules.split("\n")
        entries = []
        for rule in rules_list:
            rule = rule.split(" ")
            if rule[0] == "PERMIT_KEY":
                entry = Policy.Entry(type=Policy.PERMIT_KEY,
                                     key=rule[1])
                entries.append(entry)
            elif rule[0] == "DENY_KEY":
                entry = Policy.Entry(type=Policy.DENY_KEY,
                                     key=rule[1])
                entries.append(entry)
        policy = Policy(name=name, entries=entries)
        policy_list = PolicyList(policies=[policy])
        return self._factory.create_set_request({
            self._policy_to_address(name): policy_list.SerializeToString()})

    def create_set_policy_response(self, name):
        addresses = [self._policy_to_address(name)]
        return self._factory.create_set_response(addresses)

    def create_set_role_request(self, name, policy_name):
        role = Role(name=name, policy_name=policy_name)
        role_list = RoleList(roles=[role])
        return self._factory.create_set_request({
            self._role_to_address(name): role_list.SerializeToString()})

    def create_set_role_response(self, name):
        addresses = [self._role_to_address(name)]
        return self._factory.create_set_response(addresses)

    def create_get_setting_request(self, key):
        addresses = [key]
        return self._factory.create_get_request(addresses)

    def create_get_setting_response(self, key, allowed):
        if allowed:
            entry = Setting.Entry(
                key="sawtooth.identity.allowed_keys",
                value=self.public_key)
            data = Setting(entries=[entry]).SerializeToString()
        else:
            entry = Setting.Entry(
                key="sawtooth.identity.allowed_keys",
                value="")
            data = Setting(entries=[entry]).SerializeToString()

        return self._factory.create_get_response({key: data})

    def create_add_event_request(self, key):
        return self._factory.create_add_event_request(
            "identity_update",
            [("updated", key)])

    def create_add_event_response(self):
        return self._factory.create_add_event_response()
class SettingsMessageFactory:
    def __init__(self, signer=None):
        self._factory = MessageFactory(
            family_name="bgx_settings",
            family_version="1.0",
            namespace="000000",
            signer=signer)

    @property
    def public_key(self):
        return self._factory.get_public_key()

    def _key_to_address(self, key):
        key_parts = key.split('.', maxsplit=_MAX_KEY_PARTS - 1)
        key_parts.extend([''] * (_MAX_KEY_PARTS - len(key_parts)))

        def _short_hash(in_str):
            return self._factory.sha256(in_str.encode())[:16]

        return self._factory.namespace + \
            ''.join(_short_hash(x) for x in key_parts)

    def create_tp_register(self):
        return self._factory.create_tp_register()

    def create_tp_response(self, status):
        return self._factory.create_tp_response(status)

    def _create_tp_process_request(self, setting, payload):
        inputs = [
            self._key_to_address('sawtooth.settings.vote.proposals'),
            self._key_to_address('sawtooth.settings.vote.authorized_keys'),
            self._key_to_address('sawtooth.settings.vote.approval_threshold'),
            self._key_to_address(setting)
        ]

        outputs = [
            self._key_to_address('sawtooth.settings.vote.proposals'),
            self._key_to_address(setting)
        ]

        return self._factory.create_tp_process_request(
            payload.SerializeToString(), inputs, outputs, [])

    def create_proposal_transaction(self, setting, value, nonce):
        proposal = SettingProposal(setting=setting, value=value, nonce=nonce)
        payload = SettingsPayload(action=SettingsPayload.PROPOSE,
                                  data=proposal.SerializeToString())

        return self._create_tp_process_request(setting, payload)

    def create_vote_proposal(self, proposal_id, setting, vote):
        vote = SettingVote(proposal_id=proposal_id, vote=vote)
        payload = SettingsPayload(action=SettingsPayload.VOTE,
                                  data=vote.SerializeToString())

        return self._create_tp_process_request(setting, payload)

    def create_get_request(self, setting):
        addresses = [self._key_to_address(setting)]
        return self._factory.create_get_request(addresses)

    def create_get_response(self, setting, value=None):
        address = self._key_to_address(setting)

        if value is not None:
            entry = Setting.Entry(key=setting, value=value)
            data = Setting(entries=[entry]).SerializeToString()
        else:
            data = None

        return self._factory.create_get_response({address: data})

    def create_set_request(self, setting, value=None):
        address = self._key_to_address(setting)

        if value is not None:
            entry = Setting.Entry(key=setting, value=value)
            data = Setting(entries=[entry]).SerializeToString()
        else:
            data = None

        return self._factory.create_set_request({address: data})

    def create_set_response(self, setting):
        addresses = [self._key_to_address(setting)]
        return self._factory.create_set_response(addresses)

    def create_add_event_request(self, key):
        return self._factory.create_add_event_request(
            "settings/update",
            [("updated", key)])

    def create_add_event_response(self):
        return self._factory.create_add_event_response()
예제 #4
0
class UnitMessageFactory(object):
    def __init__(self, signer=None):
        self._factory = MessageFactory(
            family_name="hashblock_units",
            family_version="0.1.0",
            namespace=[MessageFactory.sha512('units'.encode("utf-8"))[0:6]],
            signer=signer)

    @property
    def public_key(self):
        return self._factory.get_public_key()

    def _key_to_address(self, key):
        key_parts = key.split('.', maxsplit=_MAX_KEY_PARTS - 1)
        key_parts.extend([''] * (_MAX_KEY_PARTS - len(key_parts)))

        def _short_hash(in_str):
            return self._factory.sha256(in_str.encode())[:16]

        return self._factory.namespace + \
            ''.join(_short_hash(x) for x in key_parts)

    def create_tp_register(self):
        return self._factory.create_tp_register()

    def create_tp_response(self, status):
        return self._factory.create_tp_response(status)

    def _create_tp_process_request(self, code, payload):
        inputs = [
            self._key_to_address('hashblock.units.vote.proposals'),
            self._key_to_address('hashblock.units.vote.authorized_keys'),
            self._key_to_address('hashblock.units.vote.approval_threshold'),
            self._key_to_address(code)
        ]

        outputs = [
            self._key_to_address('hashblock.units.vote.proposals'),
            self._key_to_address(code)
        ]

        return self._factory.create_tp_process_request(
            payload.SerializeToString(), inputs, outputs, [])

    def create_proposal_transaction(self, code, value, nonce):
        proposal = UnitProposal(code=code, value=value, nonce=nonce)
        payload = UnitPayload(action=UnitPayload.PROPOSE,
                              data=proposal.SerializeToString())

        return self._create_tp_process_request(code, payload)

    def create_vote_proposal(self, proposal_id, code, vote):
        vote = UnitVote(proposal_id=proposal_id, vote=vote)
        payload = UnitPayload(action=UnitPayload.VOTE,
                              data=vote.SerializeToString())

        return self._create_tp_process_request(code, payload)

    def create_get_request(self, code):
        addresses = [self._key_to_address(code)]
        return self._factory.create_get_request(addresses)

    def create_get_response(self, code, value=None):
        address = self._key_to_address(code)

        if value is not None:
            entry = Unit.Entry(key=code, value=value)
            data = Unit(entries=[entry]).SerializeToString()
        else:
            data = None

        return self._factory.create_get_response({address: data})

    def create_set_request(self, code, value=None):
        address = self._key_to_address(code)

        if value is not None:
            entry = Unit.Entry(key=code, value=value)
            data = Unit(entries=[entry]).SerializeToString()
        else:
            data = None

        return self._factory.create_set_request({address: data})

    def create_set_response(self, code):
        addresses = [self._key_to_address(code)]
        return self._factory.create_set_response(addresses)

    def create_add_event_request(self, key):
        return self._factory.create_add_event_request("units/update",
                                                      [("updated", key)])

    def create_add_event_response(self):
        return self._factory.create_add_event_response()
class IdentityMessageFactory:
    def __init__(self, signer=None):
        self._factory = MessageFactory(
            family_name="sawtooth_identity",
            family_version="1.0",
            namespace="00001d",
            signer=signer,
        )

    @property
    def public_key(self):
        return self._factory.get_public_key()

    def _to_hash(self, value):
        return hashlib.sha256(value.encode()).hexdigest()

    def _role_to_address(self, role_name):
        # split the key into 4 parts, maximum
        key_parts = role_name.split('.', maxsplit=_MAX_KEY_PARTS - 1)

        # compute the short hash of each part
        addr_parts = [self._to_hash(key_parts[0])[:_FIRST_ADDRESS_PART_SIZE]]
        addr_parts += [
            self._to_hash(x)[:_ADDRESS_PART_SIZE] for x in key_parts[1:]
        ]
        # pad the parts with the empty hash, if needed
        addr_parts.extend([_EMPTY_PART] * (_MAX_KEY_PARTS - len(addr_parts)))
        return self._factory.namespace + _ROLE_PREFIX + ''.join(addr_parts)

    def _policy_to_address(self, policy_name):
        return self._factory.namespace + _POLICY_PREFIX + \
            self._to_hash(policy_name)[:62]

    def create_tp_register(self):
        return self._factory.create_tp_register()

    def create_tp_response(self, status):
        return self._factory.create_tp_response(status)

    def _create_tp_process_request(self, payload):
        inputs = []
        outputs = []
        if payload.type == IdentityPayload.ROLE:
            role = Role()
            role.ParseFromString(payload.data)
            inputs = [
                self._role_to_address(role.name),
                self._policy_to_address(role.policy_name)
            ]

            outputs = [self._role_to_address(role.name)]
        else:
            policy = Policy()
            policy.ParseFromString(payload.data)
            inputs = [self._policy_to_address(policy.name)]

            outputs = [self._role_to_address(policy.name)]

        return self._factory.create_tp_process_request(
            payload.SerializeToString(), inputs, outputs, [])

    def create_policy_transaction(self, name, rules):
        rules_list = rules.split("\n")
        entries = []
        for rule in rules_list:
            rule = rule.split(" ")
            if rule[0] == "PERMIT_KEY":
                entry = Policy.Entry(type=Policy.PERMIT_KEY,
                                     key=rule[1])
                entries.append(entry)
            elif rule[0] == "DENY_KEY":
                entry = Policy.Entry(type=Policy.DENY_KEY,
                                     key=rule[1])
                entries.append(entry)
        policy = Policy(name=name, entries=entries)
        payload = IdentityPayload(type=IdentityPayload.POLICY,
                                  data=policy.SerializeToString())
        return self._create_tp_process_request(payload)

    def create_role_transaction(self, name, policy_name):
        role = Role(name=name, policy_name=policy_name)
        payload = IdentityPayload(type=IdentityPayload.ROLE,
                                  data=role.SerializeToString())
        return self._create_tp_process_request(payload)

    def create_get_policy_request(self, name):
        addresses = [self._policy_to_address(name)]
        return self._factory.create_get_request(addresses)

    def create_get_policy_response(self, name, rules=None):
        data = None
        if rules is not None:
            rules_list = rules.split("\n")
            entries = []
            for rule in rules_list:
                rule = rule.split(" ")
                if rule[0] == "PERMIT_KEY":
                    entry = Policy.Entry(type=Policy.PERMIT_KEY,
                                         key=rule[0])
                    entries.append(entry)
                elif rule[0] == "DENY_KEY":
                    entry = Policy.Entry(type=Policy.DENY_KEY,
                                         key=rule[0])
                    entries.append(entry)
            policy = Policy(name=name, entries=entries)
            policy_list = PolicyList(policies=[policy])
            data = policy_list.SerializeToString()
        return self._factory.create_get_response(
            {self._policy_to_address(name): data})

    def create_get_role_request(self, name):
        addresses = [self._role_to_address(name)]
        return self._factory.create_get_request(addresses)

    def create_get_role_response(self, name, policy_name=None):
        data = None
        if policy_name is not None:
            role = Role(name=name, policy_name=policy_name)
            role_list = RoleList(roles=[role])
            data = role_list.SerializeToString()
        return self._factory.create_get_response({
            self._role_to_address(name): data})

    def create_set_policy_request(self, name, rules=None):
        rules_list = rules.split("\n")
        entries = []
        for rule in rules_list:
            rule = rule.split(" ")
            if rule[0] == "PERMIT_KEY":
                entry = Policy.Entry(type=Policy.PERMIT_KEY,
                                     key=rule[1])
                entries.append(entry)
            elif rule[0] == "DENY_KEY":
                entry = Policy.Entry(type=Policy.DENY_KEY,
                                     key=rule[1])
                entries.append(entry)
        policy = Policy(name=name, entries=entries)
        policy_list = PolicyList(policies=[policy])
        return self._factory.create_set_request({
            self._policy_to_address(name): policy_list.SerializeToString()})

    def create_set_policy_response(self, name):
        addresses = [self._policy_to_address(name)]
        return self._factory.create_set_response(addresses)

    def create_set_role_request(self, name, policy_name):
        role = Role(name=name, policy_name=policy_name)
        role_list = RoleList(roles=[role])
        return self._factory.create_set_request({
            self._role_to_address(name): role_list.SerializeToString()})

    def create_set_role_response(self, name):
        addresses = [self._role_to_address(name)]
        return self._factory.create_set_response(addresses)

    def create_get_setting_request(self, key):
        addresses = [key]
        return self._factory.create_get_request(addresses)

    def create_get_setting_response(self, key, allowed):
        if allowed:
            entry = Setting.Entry(
                key="sawtooth.identity.allowed_keys",
                value=self.public_key)
            data = Setting(entries=[entry]).SerializeToString()
        else:
            entry = Setting.Entry(
                key="sawtooth.identity.allowed_keys",
                value="")
            data = Setting(entries=[entry]).SerializeToString()

        return self._factory.create_get_response({key: data})

    def create_add_event_request(self, key):
        return self._factory.create_add_event_request(
            "identity/update",
            [("updated", key)])

    def create_add_event_response(self):
        return self._factory.create_add_event_response()
class AssetMessageFactory(object):
    def __init__(self, signer=None):
        self._asset_addr = Address(Address.FAMILY_ASSET)
        self._setting_addr = Address(Address.FAMILY_SETTING)
        self._factory = MessageFactory(family_name=Address.NAMESPACE_ASSET,
                                       family_version="0.1.0",
                                       namespace=[self._asset_addr.ns_family],
                                       signer=signer)

    @property
    def public_key(self):
        return self._factory.get_public_key()

    def create_tp_register(self):
        return self._factory.create_tp_register()

    def create_tp_response(self, status):
        return self._factory.create_tp_response(status)

    def _create_tp_process_request(self, asset, dimension, payload):
        asset_address = self._asset_addr.asset_item(dimension, asset.system,
                                                    asset.key)
        inputs = [
            self._setting_addr.settings(dimension),
            self._asset_addr.candidates(dimension), asset_address
        ]

        outputs = [self._asset_addr.candidates(dimension), asset_address]

        return self._factory.create_tp_process_request(
            payload.SerializeToString(), inputs, outputs, [])

    def create_proposal_transaction(self, asset, dimension, nonce):
        proposal = AssetProposal(
            asset=asset.SerializeToString(),
            type=AssetProposal.UNIT
            if dimension is Address.DIMENSION_UNIT else AssetProposal.RESOURCE,
            nonce=nonce)
        payload = AssetPayload(action=AssetPayload.ACTION_PROPOSE,
                               dimension=dimension,
                               data=proposal.SerializeToString())

        return self._create_tp_process_request(asset, dimension, payload)

    def create_vote_transaction(self, proposal_id, asset, dimension, vote):
        avote = AssetVote(proposal_id=proposal_id, vote=vote)
        payload = AssetPayload(action=AssetPayload.ACTION_VOTE,
                               dimension=dimension,
                               data=avote.SerializeToString())

        return self._create_tp_process_request(asset, dimension, payload)

    def create_unset_vote_transaction(self, proposal_id, asset, dimension,
                                      vote):
        avote = AssetVote(proposal_id=proposal_id, vote=vote)
        payload = AssetPayload(action=AssetPayload.ACTION_UNSET,
                               dimension=dimension,
                               data=avote.SerializeToString())

        return self._create_tp_process_request(asset, dimension, payload)

    def create_get_request(self, address):
        addresses = [address]
        return self._factory.create_get_request(addresses)

    def create_get_response(self, address, data):
        return self._factory.create_get_response({address: data})

    def create_set_request(self, address, data):
        return self._factory.create_set_request({address: data})

    def create_set_response(self, address):
        addresses = [address]
        return self._factory.create_set_response(addresses)

    def create_add_event_request(self, address):
        return self._factory.create_add_event_request("hashbloc.asset/update",
                                                      [("updated", address)])

    def create_add_event_response(self):
        return self._factory.create_add_event_response()
예제 #7
0
class MatchMessageFactory(object):

    def __init__(self, signer=None):
        self._match_addr = Address(Address.FAMILY_MATCH)
        self._factory = MessageFactory(
            family_name=Address.NAMESPACE_MATCH,
            family_version="0.1.0",
            namespace=[self._match_addr.ns_family],
            signer=signer)

    @property
    def public_key(self):
        return self._factory.get_public_key()

    def create_tp_register(self):
        return self._factory.create_tp_register()

    def create_tp_response(self, status):
        return self._factory.create_tp_response(status)

    def _create_tp_process_request(self, payload, ukey, mkey=None):
        if mkey:
            inputs = [ukey]
            outputs = [ukey, mkey]
        else:
            inputs = []
            outputs = [ukey]

        return self._factory.create_tp_process_request(
            payload.SerializeToString(), inputs, outputs, [])

    def create_initiate_transaction(self, initiate_event, ukey, command):
        payload = MatchEvent(
            action=command,
            ukey=ukey,
            data=initiate_event.SerializeToString())
        return self._create_tp_process_request(payload, ukey)

    def create_reciprocate_transaction(
        self,
        reciprocate_event,
        ukey,
        mkey,
            command):
        payload = MatchEvent(
            action=command,
            ukey=ukey,
            mkey=mkey,
            data=reciprocate_event.SerializeToString())
        return self._create_tp_process_request(payload, ukey, mkey)

    def create_get_request(self, address):
        return self._factory.create_get_request([address])

    def create_get_response(self, address, data=None):
        return self._factory.create_get_response({address: data})

    def create_set_request(self, address, data=None):
        return self._factory.create_set_request({address: data})

    def create_set_response(self, address):
        return self._factory.create_set_response([address])

    def create_add_event_request(self, key, attributes):
        return self._factory.create_add_event_request(
            key,
            attributes)

    def create_add_event_response(self):
        return self._factory.create_add_event_response()
class SettingsMessageFactory:
    def __init__(self, signer=None):
        self._factory = MessageFactory(
            family_name="sawtooth_settings",
            family_version="1.0",
            namespace="000000",
            signer=signer)

    @property
    def public_key(self):
        return self._factory.get_public_key()

    def _key_to_address(self, key):
        key_parts = key.split('.', maxsplit=_MAX_KEY_PARTS - 1)
        key_parts.extend([''] * (_MAX_KEY_PARTS - len(key_parts)))

        def _short_hash(in_str):
            return self._factory.sha256(in_str.encode())[:16]

        return self._factory.namespace + \
            ''.join(_short_hash(x) for x in key_parts)

    def create_tp_register(self):
        return self._factory.create_tp_register()

    def create_tp_response(self, status):
        return self._factory.create_tp_response(status)

    def _create_tp_process_request(self, setting, payload):
        inputs = [
            self._key_to_address('sawtooth.settings.vote.proposals'),
            self._key_to_address('sawtooth.settings.vote.authorized_keys'),
            self._key_to_address('sawtooth.settings.vote.approval_threshold'),
            self._key_to_address(setting)
        ]

        outputs = [
            self._key_to_address('sawtooth.settings.vote.proposals'),
            self._key_to_address(setting)
        ]

        return self._factory.create_tp_process_request(
            payload.SerializeToString(), inputs, outputs, [])

    def create_proposal_transaction(self, setting, value, nonce):
        proposal = SettingProposal(setting=setting, value=value, nonce=nonce)
        payload = SettingsPayload(action=SettingsPayload.PROPOSE,
                                  data=proposal.SerializeToString())

        return self._create_tp_process_request(setting, payload)

    def create_vote_proposal(self, proposal_id, setting, vote):
        vote = SettingVote(proposal_id=proposal_id, vote=vote)
        payload = SettingsPayload(action=SettingsPayload.VOTE,
                                  data=vote.SerializeToString())

        return self._create_tp_process_request(setting, payload)

    def create_get_request(self, setting):
        addresses = [self._key_to_address(setting)]
        return self._factory.create_get_request(addresses)

    def create_get_response(self, setting, value=None):
        address = self._key_to_address(setting)

        if value is not None:
            entry = Setting.Entry(key=setting, value=value)
            data = Setting(entries=[entry]).SerializeToString()
        else:
            data = None

        return self._factory.create_get_response({address: data})

    def create_set_request(self, setting, value=None):
        address = self._key_to_address(setting)

        if value is not None:
            entry = Setting.Entry(key=setting, value=value)
            data = Setting(entries=[entry]).SerializeToString()
        else:
            data = None

        return self._factory.create_set_request({address: data})

    def create_set_response(self, setting):
        addresses = [self._key_to_address(setting)]
        return self._factory.create_set_response(addresses)

    def create_add_event_request(self, key):
        return self._factory.create_add_event_request(
            "settings/update",
            [("updated", key)])

    def create_add_event_response(self):
        return self._factory.create_add_event_response()
예제 #9
0
class StakeMessageFactory(object):
    def __init__(self, signer=None):
        self._factory = MessageFactory(
            family_name="stake",
            family_version="1.0",
            namespace="807062",
            signer=signer,
        )

    @property
    def public_key(self):
        return self._factory.get_public_key()

    def _to_hash(self, value):
        return hashlib.sha256(value.encode()).hexdigest()

    # TODO refactor into key_to_address for clarity
    def _stake_to_address(self, owner_pub):
        addr_part = self._to_hash(owner_pub)[:_ADDRESS_PART_SIZE]
        return self._factory.namespace + _DEFAULT_TYPE_PREFIX + addr_part

    def create_tp_register(self):
        return self._factory.create_tp_register()

    def create_tp_response(self, status):
        return self._factory.create_tp_response(status)

    def _create_tp_process_request(self, payload):
        inputs = []
        outputs = []
        if payload.payload_type == StakePayload.SEND_STAKE:
            send = payload.send
            inputs = [
                # the stake address `from`
                self._stake_to_address(self._factory.get_public_key()),
                # the stake address `to`
                self._stake_to_address(send.toPubKey)
            ]
            outputs = [
                # the stake address `from`
                self._stake_to_address(self._factory.get_public_key()),
                # the stake address `to`
                self._stake_to_address(send.toPubKey)
            ]
        elif payload.payload_type == StakePayload.LOCK_STAKE:
            lock = payload.lock
            inputs = [self._stake_to_address(self._factory.get_public_key())]
            outputs = [self._stake_to_address(self._factory.get_public_key())]

        # MINT_STAKE
        else:
            # Extract the payload from create_mint_stake_transaction, will need to extract
            # the pub keys for ICO
            mint = payload.mint
            inputs = [self._stake_to_address(self._factory.get_public_key())]
            outputs = [self._stake_to_address(self._factory.get_public_key())]

        return self._factory.create_tp_process_request(
            payload.SerializeToString(), inputs, outputs, [])

    def create_mint_stake_transaction(self, total_supply: float,
                                      mint_key: str):
        mint = MintStakeTransactionData()
        mint.totalSupply = total_supply
        mint.ico[mint_key] = total_supply

        payload = StakePayload(payload_type=StakePayload.MINT_STAKE, mint=mint)
        return self._create_tp_process_request(payload)

    def create_lock_stake_transaction(self, block_number: int):
        lock = LockStakeTransactionData()
        lock.blockNumber = block_number

        payload = StakePayload(payload_type=StakePayload.LOCK_STAKE, lock=lock)
        return self._create_tp_process_request(payload)

    def create_send_stake_transaction(self, to_public_key, stake_amount):
        send = SendStakeTransactionData()
        send.toPubKey = to_public_key
        send.value = stake_amount

        payload = StakePayload(payload_type=StakePayload.SEND_STAKE, send=send)

        return self._create_tp_process_request(payload)

    def create_mint_stake_request(self, total_supply, public_key):
        stake_list = self.create_stake(owner_key=public_key,
                                       value=total_supply,
                                       block_number=1,
                                       nonce=1)
        return self._factory.create_set_request({
            self._stake_to_address(public_key):
            stake_list.SerializeToString()
        })

    def create_mint_stake_response(self, key):
        stake_addr = [self._stake_to_address(key)]
        return self._factory.create_set_response(stake_addr)

    def create_set_stake_request(self, public_key, stake=None):
        stake_list = self.create_stake(stake=stake)
        return self._factory.create_set_request({
            self._stake_to_address(public_key):
            stake_list.SerializeToString()
        })

    def create_set_stake_response(self, public_key):
        addresses = [self._stake_to_address(public_key)]
        return self._factory.create_set_response(addresses)

    def create_get_stake_request(self, public_key):
        addresses = [self._stake_to_address(public_key)]
        return self._factory.create_get_request(addresses)

    def create_get_stake_response(self, pub_key, stake=None):
        data = None
        if stake is not None:
            data = self.create_stake(stake=stake)
        return self._factory.create_get_response(
            {self._stake_to_address(pub_key): data.SerializeToString()})

    def create_set_lock_request(self, name, policy_name):
        pass

    def create_set_lock_response(self, name):
        pass

    def create_get_setting_request(self, key):
        addresses = [key]
        return self._factory.create_get_request(addresses)

    def create_get_setting_response(self, key, allowed):
        if allowed:
            entry = Setting.Entry(key="sawtooth.stake.allowed_keys",
                                  value=self.public_key)
            data = Setting(entries=[entry]).SerializeToString()
        else:
            entry = Setting.Entry(key="sawtooth.stake.allowed_keys", value="")
            data = Setting(entries=[entry]).SerializeToString()

        return self._factory.create_get_response({key: data})

    def create_add_event_request(self, key):
        return self._factory.create_add_event_request("stake/update",
                                                      [("updated", key)])

    def create_add_event_response(self):
        return self._factory.create_add_event_response()

    def create_config(self,
                      latest_block,
                      oldest_block=None,
                      target_count=DEFAULT_TARGET_COUNT,
                      sync_tolerance=DEFAULT_SYNC_TOLERANCE):
        if oldest_block is None:
            oldest_block = latest_block - DEFAULT_TARGET_COUNT
        return BlockInfoConfig(latest_block=latest_block,
                               oldest_block=oldest_block,
                               target_count=target_count,
                               sync_tolerance=sync_tolerance)

    def create_stake(self,
                     owner_key=None,
                     value=None,
                     block_number=None,
                     nonce=None,
                     stake=None):
        # if there is already a stake list
        if stake is not None:
            return stake
        # there is no state at the address.
        else:
            stake_list = StakeList()
            stake_list.stakeMap.get_or_create(owner_key)
            stake_list.stakeMap[owner_key].ownerPubKey = owner_key
            stake_list.stakeMap[owner_key].nonce = nonce
            stake_list.stakeMap[owner_key].blockNumber = block_number
            stake_list.stakeMap[owner_key].value = value
            return stake_list

    def create_get_block_config_request(self):
        return self._factory.create_get_request(addresses=[CONFIG_ADDRESS])

    def create_get_block_config_response(self, msg):
        if msg:
            # block_config.ParseFromString(bc[0].data)
            config_key = next(iter(msg))
            config_data = BlockInfoConfig()
            config_data.ParseFromString(msg[config_key])
            data = self.create_config(config_data.latest_block, oldest_block=1)
            #conf = self.create_config(config.latest_block, oldest_block=1)
            #data = config.SerializeToString()
        else:
            data = None
        return self._factory.create_get_response(
            {CONFIG_ADDRESS: data.SerializeToString()})
class EventMessageFactory(object):
    def __init__(self, signer=None):
        self._factory = MessageFactory(
            family_name=FAMILY_NAME,
            family_version="0.1.0",
            namespace=[EVENTS_ADDRESS_PREFIX],
            signer=signer)

    @property
    def public_key(self):
        return self._factory.get_public_key()

    def _key_to_address(self, key):
        key_parts = key.split('.', maxsplit=_MAX_KEY_PARTS - 1)
        key_parts.extend([''] * (_MAX_KEY_PARTS - len(key_parts)))

        def _short_hash(in_str):
            return self._factory.sha256(in_str.encode())[:16]

        return self._factory.namespace + \
            ''.join(_short_hash(x) for x in key_parts)

    def create_tp_register(self):
        return self._factory.create_tp_register()

    def create_tp_response(self, status):
        return self._factory.create_tp_response(status)

    def _create_tp_process_request(self, code, payload):
        inputs = [
            self._key_to_address('hashblock.events.initiate'),
            self._key_to_address('hashblock.events.reciprocate'),
            self._key_to_address(code)
        ]

        outputs = [
            self._key_to_address('hashblock.events.initiate'),
            self._key_to_address('hashblock.events.reciprocate'),
            self._key_to_address(code)
        ]

        return self._factory.create_tp_process_request(
            payload.SerializeToString(), inputs, outputs, [])

    def create_initiate_transaction(
        self, code, version, plus,
            minus, quantity, nonce):
        initiate = InitiateEvent(
            version=version, plus=plus,
            minus=minus, nonce=nonce)
        payload = EventPayload(
            action=EventPayload.INITIATE_EVENT,
            data=initiate.SerializeToString())

        return self._create_tp_process_request(code, payload)

    def create_reciprocate_transaction(self, proposal_id, code, vote):
        vote = ReciprocateEvent(proposal_id=proposal_id, vote=vote)
        payload = EventPayload(
            action=EventPayload.RECIPROCATE_EVENT,
            data=vote.SerializeToString())

        return self._create_tp_process_request(code, payload)

    def create_get_request(self, code):
        addresses = [self._key_to_address(code)]
        return self._factory.create_get_request(addresses)

    def create_get_response(self, code, value=None):
        address = self._key_to_address(code)

        if value is not None:
            entry = Unit.Entry(key=code, value=value)
            data = Unit(entries=[entry]).SerializeToString()
        else:
            data = None

        return self._factory.create_get_response({address: data})

    def create_set_request(self, code, value=None):
        address = self._key_to_address(code)

        if value is not None:
            entry = Unit.Entry(key=code, value=value)
            data = Unit(entries=[entry]).SerializeToString()
        else:
            data = None

        return self._factory.create_set_request({address: data})

    def create_set_response(self, code):
        addresses = [self._key_to_address(code)]
        return self._factory.create_set_response(addresses)

    def create_add_event_request(self, key):
        return self._factory.create_add_event_request(
            "events/update",
            [("updated", key)])

    def create_add_event_response(self):
        return self._factory.create_add_event_response()