예제 #1
0
def bulk_payout_job(body=None):  # noqa: E501
    """Performs a payout to multiple ethereum addresses.

    When the payout happens, final results are uploaded to S3 and contract's state is updated to Partial or Paid depending on contract's balance.

    :param body: 
    :type body: dict | bytes

    :rtype: BoolDataResponse
    """
    if connexion.request.is_json:
        body = BulkPayoutJobBody.from_dict(
            connexion.request.get_json())  # noqa: E501
        try:
            factory_addr = launcher(get_escrow(body.address), body.gas_payer)
        except Exception as e:
            return ErrorNotexistResponse(str(e)), 404
        try:
            req = Request(body.results_url)
            req.add_header(
                "User-Agent",
                "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.75 Safari/537.36"
            )
            req.add_header("X-Requested-With", "XMLHttpRequest")
            data = urlopen(req).read()
            results = json.loads(data)
        except Exception as e:
            return ErrorParameterResponse(str(e), "results_url"), 400
        try:
            req = Request(body.payouts_url)
            req.add_header(
                "User-Agent",
                "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.75 Safari/537.36"
            )
            req.add_header("X-Requested-With", "XMLHttpRequest")
            data = urlopen(req).read()
            payouts = [(address, Decimal(amount))
                       for (address, amount) in json.loads(data).items()]
        except Exception as e:
            return ErrorParameterResponse(str(e), "payouts_url"), 400
        try:
            job = Job(credentials={
                "gas_payer":
                body.gas_payer,
                "gas_payer_priv":
                body.gas_payer_private,
                "rep_oracle_priv_key":
                bytes(body.gas_payer_private.lstrip("0x"), encoding="utf-8")
            },
                      factory_addr=factory_addr,
                      escrow_addr=body.address)
        except Exception as e:
            return ErrorUnauthorizedResponse(str(e)), 401
        try:
            return BoolDataResponse(
                job.bulk_payout(payouts, results,
                                bytes(body.rep_oracle_pub,
                                      encoding="utf-8"))), 200
        except Exception as e:
            return ErrorParameterResponse(str(e), "rep_oracle_pub_key"), 400
예제 #2
0
def complete_job(address, gas_payer, gas_payer_private):  # noqa: E501
    """Complete a given job

    Complete a given job  # noqa: E501

    :param address: Deployed Job address
    :type address: str
    :param gas_payer: address paying which started the job or a trusted handler
    :type gas_payer: str
    :param gas_payer_private: Private Key for the address paying for the gas costs
    :type gas_payer_private: str

    :rtype: BoolDataResponse
    """
    try:
        factory_addr = launcher(get_escrow(address), gas_payer)
    except Exception as e:
        return ErrorNotexistResponse(str(e)), 404
    try:
        job = Job(credentials={
            "gas_payer":
            gas_payer,
            "gas_payer_priv":
            gas_payer_private,
            "rep_oracle_priv_key":
            bytes(gas_payer_private.lstrip("0x"), encoding="utf-8")
        },
                  factory_addr=factory_addr,
                  escrow_addr=address)
        return BoolDataResponse(job.complete()), 200
    except Exception as e:
        return ErrorUnauthorizedResponse(str(e)), 401
예제 #3
0
def add_job_trusted_handlers(body=None):  # noqa: E501
    """Add trusted handlers that can freely transact with the contract

    A trusted handler can perform aborts and cancels, for example

    :param body: 
    :type body: dict | bytes

    :rtype: BoolDataResponse
    """
    if connexion.request.is_json:
        body = AddJobTrustedHandlersBody.from_dict(
            connexion.request.get_json())  # noqa: E501
        try:
            factory_addr = launcher(get_escrow(body.address), body.gas_payer)
        except Exception as e:
            return ErrorNotexistResponse(str(e)), 404
        try:
            job = Job(credentials={
                "gas_payer":
                body.gas_payer,
                "gas_payer_priv":
                body.gas_payer_private,
                "rep_oracle_priv_key":
                bytes(body.gas_payer_private.lstrip("0x"), encoding="utf-8")
            },
                      factory_addr=factory_addr,
                      escrow_addr=body.address)
        except Exception as e:
            return ErrorUnauthorizedResponse(str(e)), 401
        try:
            return BoolDataResponse(job.add_trusted_handlers(
                body.handlers)), 200
        except Exception as e:
            return ErrorParameterResponse(str(e), "handlers"), 400
예제 #4
0
def get_job_balanace(address, gas_payer, gas_payer_private):  # noqa: E501
    """Balance in HMT of a given job address

    Balance in HMT of a given job address  # noqa: E501

    :param address: Deployed Job address
    :type address: str
    :param gas_payer: address paying for the gas costs
    :type gas_payer: str
    :param gas_payer_private: Private Key for the address paying for the gas costs
    :type gas_payer_private: str

    :rtype: IntDataResponse
    """
    try:
        factory_addr = launcher(get_escrow(address), gas_payer)
        job = Job(credentials={
            "gas_payer":
            gas_payer,
            "gas_payer_priv":
            gas_payer_private,
            "rep_oracle_priv_key":
            bytes(gas_payer_private.lstrip("0x"), encoding="utf-8")
        },
                  factory_addr=factory_addr,
                  escrow_addr=address)
        return IntDataResponse(job.balance()), 200
    except Exception as e:
        return ErrorNotexistResponse(str(e)), 404
예제 #5
0
def store_job_intermediate_results(body=None):  # noqa: E501
    """Store intermediate results to S3 for the given escrow

    Given an escrow address, a URL where the results can be found in the form of a JSON file, and a public key will upload to S3 these intermediate results and will emit an event on the escrow contract # noqa: E501

    :param body: 
    :type body: dict | bytes

    :rtype: BoolDataResponse
    """
    if connexion.request.is_json:
        body = StoreJobIntermediateResultsBody.from_dict(
            connexion.request.get_json())  # noqa: E501
        try:
            factory_addr = launcher(get_escrow(body.address), body.gas_payer)
        except Exception as e:
            return ErrorNotexistResponse(str(e)), 404
        try:
            req = Request(body.results_url)
            req.add_header(
                "User-Agent",
                "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.75 Safari/537.36"
            )
            req.add_header("X-Requested-With", "XMLHttpRequest")
            data = urlopen(req).read()
            results = json.loads(data)
        except Exception as e:
            return ErrorParameterResponse(str(e), "results_url"), 400
        try:
            job = Job(credentials={
                "gas_payer":
                body.gas_payer,
                "gas_payer_priv":
                body.gas_payer_private,
                "rep_oracle_priv_key":
                bytes(body.gas_payer_private.lstrip("0x"), encoding="utf-8")
            },
                      factory_addr=factory_addr,
                      escrow_addr=body.address)
        except Exception as e:
            return ErrorUnauthorizedResponse(str(e)), 401
        try:
            return BoolDataResponse(
                job.store_intermediate_results(
                    results, bytes(body.rep_oracle_pub,
                                   encoding="utf-8"))), 200
        except Exception as e:
            return ErrorParameterResponse(str(e), "rep_oracle_pub_key"), 400
예제 #6
0
def get_job_status(address, gas_payer, gas_payer_private):  # noqa: E501
    """Status of a given job address

    Receive the status of a given job address  # noqa: E501

    :param address: Deployed Job address
    :type address: str
    :param gas_payer: address paying for the gas costs
    :type gas_payer: str
    :param gas_payer_private: Private Key for the address paying for the gas costs
    :type gas_payer_private: str

    :rtype: JobStatusResponse
    """
    try:
        return JobStatusResponse(str(status(get_escrow(address),
                                            gas_payer))), 200
    except Exception as e:
        return ErrorNotexistResponse(str(e)), 404
예제 #7
0
def get_job_manifest_url(address, gas_payer, gas_payer_private):  # noqa: E501
    """Manifest URL of a given job address

    Receive the Manifest URL of a given job address  # noqa: E501

    :param address: Deployed Job address
    :type address: str
    :param gas_payer: address paying for the gas costs
    :type gas_payer: str
    :param gas_payer_private: Private Key for the address paying for the gas costs
    :type gas_payer_private: str

    :rtype: StringDataResponse
    """
    try:
        return StringDataResponse(manifest_url(get_escrow(address),
                                               gas_payer)), 200
    except Exception as e:
        return ErrorNotexistResponse(str(e)), 404
예제 #8
0
파일: job.py 프로젝트: bxabi/hmt-escrow
    def _access_job(self, factory_addr: str, escrow_addr: str, **credentials):
        """Given a factory and escrow address and credentials, access an already
        launched manifest of an already deployed escrow contract.

        Args:
            factory_addr (str): an ethereum address of the escrow factory contract.
            escrow_addr (str): an ethereum address of the escrow contract.
            **credentials: an unpacked dict of an ethereum address and its private key.

        """
        gas_payer = credentials["gas_payer"]
        rep_oracle_priv_key = credentials["rep_oracle_priv_key"]

        self.factory_contract = get_factory(factory_addr)
        self.job_contract = get_escrow(escrow_addr)
        self.manifest_url = manifest_url(self.job_contract, gas_payer)
        self.manifest_hash = manifest_hash(self.job_contract, gas_payer)

        manifest_dict = self.manifest(rep_oracle_priv_key)
        escrow_manifest = Manifest(manifest_dict)
        self._init_job(escrow_manifest)
예제 #9
0
    def launch(self, pub_key: bytes) -> bool:
        """Launches an escrow contract to the network, uploads the manifest
        to IPFS with the public key of the Reputation Oracle and stores
        the IPFS url to the escrow contract.

        Args:
            pub_key (bytes): the public key of the Reputation Oracle.

        Returns:
            bool: returns True if Job initialization and Ethereum and IPFS transactions succeed.

        >>> credentials = {
        ... 	"gas_payer": "0x1413862C2B7054CDbfdc181B83962CB0FC11fD92",
        ... 	"gas_payer_priv": "28e516f1e2f99e96a48a23cea1f94ee5f073403a1c68e818263f0eb898f1c8e5"
        ... }
        >>> rep_oracle_pub_key = b"2dbc2c2c86052702e7c219339514b2e8bd4687ba1236c478ad41b43330b08488c12c8c1797aa181f3a4596a1bd8a0c18344ea44d6655f61fa73e56e743f79e0d"
        >>> job = Job(credentials, manifest)

        Deploying a new Job to the ethereum network succeeds.
        >>> job.launch(rep_oracle_pub_key)
        True
        >>> job.status()
        <Status.Launched: 1>
        """
        if hasattr(self, "job_contract"):
            raise AttributeError("The escrow has been already deployed.")

        # Use factory to deploy a new escrow contract.
        self._create_escrow()
        job_addr = self._last_escrow_addr()

        LOG.info("Job's escrow contract deployed to:{}".format(job_addr))
        self.job_contract = get_escrow(job_addr)

        # Upload the manifest to IPFS.
        (hash_, manifest_url) = upload(self.serialized_manifest, pub_key)

        self.manifest_url = manifest_url
        self.manifest_hash = hash_
        return self.status() == Status.Launched and self.balance() == 0
예제 #10
0
def job_final_results(address, gas_payer, gas_payer_private,
                      rep_oracle_private):  # noqa: E501
    """Retrieve the final results

    Retrieve the final results  # noqa: E501

    :param address: Deployed Job address
    :type address: str
    :param gas_payer: address paying which started the job or a trusted handler
    :type gas_payer: str
    :param gas_payer_private: Private Key for the address paying for the gas costs
    :type gas_payer_private: str
    :param rep_oracle_private: Private Key for the reputation oracle
    :type rep_oracle_private: str

    :rtype: StringDataResponse
    """
    try:
        factory_addr = launcher(get_escrow(address), gas_payer)
    except Exception as e:
        return ErrorNotexistResponse(str(e)), 404
    try:
        job = Job(credentials={
            "gas_payer":
            gas_payer,
            "gas_payer_priv":
            gas_payer_private,
            "rep_oracle_priv_key":
            bytes(rep_oracle_private, encoding="utf-8")
        },
                  factory_addr=factory_addr,
                  escrow_addr=address)
        return StringDataResponse(
            json.dumps(
                job.final_results(bytes(rep_oracle_private,
                                        encoding="utf-8")))), 200
    except Exception as e:
        return ErrorUnauthorizedResponse(str(e)), 401
예제 #11
0
 def test_get_escrow(self):
     self.job.launch(self.rep_oracle_pub_key)
     self.assertIsNotNone(get_escrow(self.job.job_contract.address))