Beispiel #1
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
Beispiel #2
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
Beispiel #3
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
Beispiel #4
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
Beispiel #5
0
 def setUp(self):
     self.credentials = {
         "gas_payer":
         "0x1413862C2B7054CDbfdc181B83962CB0FC11fD92",
         "gas_payer_priv":
         "28e516f1e2f99e96a48a23cea1f94ee5f073403a1c68e818263f0eb898f1c8e5",
     }
     self.rep_oracle_pub_key = b"2dbc2c2c86052702e7c219339514b2e8bd4687ba1236c478ad41b43330b08488c12c8c1797aa181f3a4596a1bd8a0c18344ea44d6655f61fa73e56e743f79e0d"
     self.job = Job(self.credentials, manifest)
Beispiel #6
0
    def test_job_bulk_payout(self):
        self.assertTrue(self.job.launch(self.rep_oracle_pub_key))
        self.assertTrue(self.job.setup())
        payouts = [
            ("0x6b7E3C31F34cF38d1DFC1D9A8A59482028395809", Decimal("20.0")),
            ("0x852023fbb19050B8291a335E5A83Ac9701E7B4E6", Decimal("50.0")),
        ]
        self.assertTrue(
            self.job.bulk_payout(payouts, {}, self.rep_oracle_pub_key))

        # The escrow contract is still in Partial state as there's still balance left.

        self.assertEqual(self.job.balance(), 30000000000000000000)
        self.assertEqual(self.job.status(), Status(3))

        # Trying to pay more than the contract balance results in failure.

        payouts = [("0x9d689b8f50Fd2CAec716Cc5220bEd66E03F07B5f",
                    Decimal("40.0"))]
        self.assertFalse(
            self.job.bulk_payout(payouts, {}, self.rep_oracle_pub_key))

        # Paying the remaining amount empties the escrow and updates the status correctly.

        payouts = [("0x9d689b8f50Fd2CAec716Cc5220bEd66E03F07B5f",
                    Decimal("30.0"))]
        self.assertTrue(
            self.job.bulk_payout(payouts, {}, self.rep_oracle_pub_key))
        self.assertEqual(self.job.balance(), 0)
        self.assertEqual(self.job.status(), Status(4))

        multi_credentials = [
            (
                "0x61F9F0B31eacB420553da8BCC59DC617279731Ac",
                "486a0621e595dd7fcbe5608cbbeec8f5a8b5cabe7637f11eccfc7acd408c3a0e",
            ),
            (
                "0x6b7E3C31F34cF38d1DFC1D9A8A59482028395809",
                "f22d4fc42da79aa5ba839998a0a9f2c2c45f5e55ee7f1504e464d2c71ca199e1",
            ),
        ]
        self.job = Job(self.credentials,
                       manifest,
                       multi_credentials=multi_credentials)
        self.assertTrue(self.job.launch(self.rep_oracle_pub_key))
        self.assertTrue(self.job.setup())
        payouts = [
            ("0x6b7E3C31F34cF38d1DFC1D9A8A59482028395809", Decimal("20.0")),
            ("0x852023fbb19050B8291a335E5A83Ac9701E7B4E6", Decimal("50.0")),
        ]
        self.assertTrue(
            self.job.bulk_payout(payouts, {}, self.rep_oracle_pub_key))
Beispiel #7
0
    def test_complete_job(self):
        """Test case for complete_job

        Complete a given job
        """
        with open(f"{PAYOUTS_PATH}", "r") as payouts_file:
            data = payouts_file.read()
        payouts = [(address, Decimal(amount))
                   for (address, amount) in json.loads(data).items()]
        job = Job({
            "gas_payer": GAS_PAYER,
            "gas_payer_priv": GAS_PAYER_PRIV
        }, manifest, FACTORY_ADDRESS)
        job.launch(REP_ORACLE_PUB_KEY)
        job.setup()
        job.bulk_payout(payouts, {}, REP_ORACLE_PUB_KEY)
        query_string = [('address', job.job_contract.address),
                        ('gasPayer', GAS_PAYER),
                        ('gasPayerPrivate', GAS_PAYER_PRIV)]
        response = self.client.open('/job/complete',
                                    method='GET',
                                    query_string=query_string)
        self.assert200(response,
                       'Response body is: ' + response.data.decode('utf-8'))
        self.assertTrue(
            json.loads(response.data.decode('utf-8')).get("success", False))
Beispiel #8
0
    def test_download(self):
        credentials = {
            "gas_payer": "0x1413862C2B7054CDbfdc181B83962CB0FC11fD92",
            "gas_payer_priv": "28e516f1e2f99e96a48a23cea1f94ee5f073403a1c68e818263f0eb898f1c8e5",
        }
        pub_key = b"2dbc2c2c86052702e7c219339514b2e8bd4687ba1236c478ad41b43330b08488c12c8c1797aa181f3a4596a1bd8a0c18344ea44d6655f61fa73e56e743f79e0d"
        job = Job(credentials=credentials, escrow_manifest=manifest)
        (_, manifest_url) = upload(job.serialized_manifest, pub_key)
        manifest_dict = download(manifest_url, job.gas_payer_priv)
        self.assertEqual(manifest_dict, job.serialized_manifest)

        job = Job(credentials=credentials, escrow_manifest=manifest)
        (_, manifest_url) = upload(job.serialized_manifest, pub_key)
        manifest_dict = download(manifest_url, job.gas_payer_priv)
        self.assertEqual(manifest_dict, job.serialized_manifest)
Beispiel #9
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
Beispiel #10
0
    def test_get_job_status(self):
        """Test case for get_job_status

        Status of a given job address
        """
        job = Job({
            "gas_payer": GAS_PAYER,
            "gas_payer_priv": GAS_PAYER_PRIV
        }, manifest, FACTORY_ADDRESS)
        job.launch(REP_ORACLE_PUB_KEY)
        query_string = [('address', job.job_contract.address),
                        ('gasPayer', GAS_PAYER),
                        ('gasPayerPrivate', GAS_PAYER_PRIV)]
        response = self.client.open('/job/status',
                                    method='GET',
                                    query_string=query_string)
        self.assert200(response,
                       'Response body is: ' + response.data.decode('utf-8'))
Beispiel #11
0
    def test_job_setup(self):
        # A Job can't be setup without deploying it first.

        self.assertFalse(self.job.setup())
        multi_credentials = [
            (
                "0x61F9F0B31eacB420553da8BCC59DC617279731Ac",
                "28e516f1e2f99e96a48a23cea1f94ee5f073403a1c68e818263f0eb898f1c8e5",
            ),
            (
                "0x6b7E3C31F34cF38d1DFC1D9A8A59482028395809",
                "f22d4fc42da79aa5ba839998a0a9f2c2c45f5e55ee7f1504e464d2c71ca199e1",
            ),
        ]
        self.job = Job(self.credentials,
                       manifest,
                       multi_credentials=multi_credentials)
        self.assertTrue(self.job.launch(self.rep_oracle_pub_key))
        self.assertTrue(self.job.setup())
Beispiel #12
0
    def test_job_launch(self):
        self.assertTrue(self.job.launch(self.rep_oracle_pub_key))
        self.assertEqual(self.job.status(), Status(1))
        multi_credentials = [
            (
                "0x61F9F0B31eacB420553da8BCC59DC617279731Ac",
                "486a0621e595dd7fcbe5608cbbeec8f5a8b5cabe7637f11eccfc7acd408c3a0e",
            ),
            (
                "0x6b7E3C31F34cF38d1DFC1D9A8A59482028395809",
                "f22d4fc42da79aa5ba839998a0a9f2c2c45f5e55ee7f1504e464d2c71ca199e1",
            ),
        ]
        self.job = Job(self.credentials,
                       manifest,
                       multi_credentials=multi_credentials)

        # Inject wrong credentials on purpose to test out raffling

        self.job.gas_payer_priv = (
            "657b6497a355a3982928d5515d48a84870f057c4d16923eb1d104c0afada9aa8")
        self.job.multi_credentials = [
            (
                "0x61F9F0B31eacB420553da8BCC59DC617279731Ac",
                "28e516f1e2f99e96a48a23cea1f94ee5f073403a1c68e818263f0eb898f1c8e5",
            ),
            (
                "0x6b7E3C31F34cF38d1DFC1D9A8A59482028395809",
                "f22d4fc42da79aa5ba839998a0a9f2c2c45f5e55ee7f1504e464d2c71ca199e1",
            ),
        ]
        self.assertTrue(self.job.launch(self.rep_oracle_pub_key))
        self.assertEqual(self.job.status(), Status(1))

        # Make sure we launched with raffled credentials

        self.assertEqual(self.job.gas_payer,
                         "0x6b7E3C31F34cF38d1DFC1D9A8A59482028395809")
        self.assertEqual(
            self.job.gas_payer_priv,
            "f22d4fc42da79aa5ba839998a0a9f2c2c45f5e55ee7f1504e464d2c71ca199e1",
        )
Beispiel #13
0
    def test_ipns(self, mocked_ipfs_client, _):
        """
        Test storage: upload, download, create_new_ipns_link, etc
        """

        credentials = {
            "gas_payer":
            "0x1413862C2B7054CDbfdc181B83962CB0FC11fD92",
            "gas_payer_priv":
            "28e516f1e2f99e96a48a23cea1f94ee5f073403a1c68e818263f0eb898f1c8e5"
        }
        pub_key = b"2dbc2c2c86052702e7c219339514b2e8bd4687ba1236c478ad41b43330b08488c12c8c1797aa181f3a4596a1bd8a0c18344ea44d6655f61fa73e56e743f79e0d"
        job = Job(credentials=credentials,
                  escrow_manifest=Manifest({
                      'task_bid_price': 9,
                      'request_type': 'image_label_binary',
                      'job_total_tasks': 10
                  }))
        name = 'abc'

        mocked_ipfs_client.key.list.side_effect = MI.key_list
        mocked_ipfs_client.key.gen.side_effect = MI.key_gen
        mocked_ipfs_client.name.publish.side_effect = MI.publish
        mocked_ipfs_client.add_bytes.side_effect = MI.add_bytes
        mocked_ipfs_client.resolve.side_effect = MI.resolve
        mocked_ipfs_client.cat.side_effect = MI.cat

        ipns_id = create_new_ipns_link(name)

        # Upload 1
        (hash_, manifest_url) = upload(job.serialized_manifest, pub_key, name)
        manifest_dict = download(ipns_id, job.gas_payer_priv)
        dl_equals_up = manifest_dict == job.serialized_manifest
        link_exist = ipns_link_exists(name)
        ipns_urls_match = ipns_id == get_ipns_link(name).split('/')[-1]
        self.assertTrue(dl_equals_up)
        self.assertTrue(link_exist)
        self.assertTrue(ipns_urls_match)

        # Upload 2
        data2 = dict(
            Manifest({
                'task_bid_price': 999999,
                'request_type': 'image_label_binary',
                'job_total_tasks': 30010
            }).serialize())
        (hash_, manifest_url) = upload(data2, pub_key, name)
        manifest_dict = download(ipns_id, job.gas_payer_priv)
        dl_equals_up = manifest_dict == data2
        link_exist = ipns_link_exists(name)
        ipns_urls_match = ipns_id == get_ipns_link(name).split('/')[-1]
        self.assertTrue(dl_equals_up)
        self.assertTrue(link_exist)
        self.assertTrue(ipns_urls_match)
Beispiel #14
0
    def test_add_job_trusted_handlers(self):
        """Test case for add_job_trusted_handlers

        Add trusted handlers that can freely transact with the contract
        """
        trusted_handlers = [
            '0x61F9F0B31eacB420553da8BCC59DC617279731Ac',
            '0xD979105297fB0eee83F7433fC09279cb5B94fFC6'
        ]
        job = Job({
            "gas_payer": GAS_PAYER,
            "gas_payer_priv": GAS_PAYER_PRIV
        }, manifest, FACTORY_ADDRESS)
        job.launch(REP_ORACLE_PUB_KEY)
        job.setup()
        body = AddJobTrustedHandlersBody(GAS_PAYER, GAS_PAYER_PRIV,
                                         job.job_contract.address,
                                         trusted_handlers)
        response = self.client.open('/job/addTrustedHandlers',
                                    method='POST',
                                    data=json.dumps(body),
                                    content_type='application/json')
        self.assert200(response,
                       'Response body is: ' + response.data.decode('utf-8'))
        self.assertTrue(
            json.loads(response.data.decode('utf-8')).get("success", False))
Beispiel #15
0
    def test_bulk_payout_job(self):
        """Test case for bulk_payout_job

        Performs a payout to multiple ethereum addresses.
        """
        results_url = f"file://{RESULTS_PATH}"
        payouts_url = f"file://{PAYOUTS_PATH}"
        job = Job({
            "gas_payer": GAS_PAYER,
            "gas_payer_priv": GAS_PAYER_PRIV
        }, manifest, FACTORY_ADDRESS)
        job.launch(REP_ORACLE_PUB_KEY)
        job.setup()
        body = BulkPayoutJobBody(GAS_PAYER, GAS_PAYER_PRIV,
                                 job.job_contract.address,
                                 REP_ORACLE_PUB_KEY.decode("utf-8"),
                                 results_url, payouts_url)
        response = self.client.open('/job/bulkPayout',
                                    method='POST',
                                    data=json.dumps(body),
                                    content_type='application/json')
        self.assert200(response,
                       'Response body is: ' + response.data.decode('utf-8'))
        self.assertTrue(
            json.loads(response.data.decode('utf-8')).get("success", False))
Beispiel #16
0
def create_job(manifest: Optional[Manifest] = None,
               gas_payer: Optional[str] = None,
               gas_payer_priv: Optional[str] = None) -> Job:
    """ Creates sample Job instance """
    manifest = manifest or sample_manifest
    credentials = {
        "gas_payer":
        gas_payer or "0x1413862C2B7054CDbfdc181B83962CB0FC11fD92",
        "gas_payer_priv":
        gas_payer_priv
        or "28e516f1e2f99e96a48a23cea1f94ee5f073403a1c68e818263f0eb898f1c8e5",
    }
    return Job(credentials=credentials, escrow_manifest=manifest)
Beispiel #17
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
Beispiel #18
0
    def test_job_abort(self):
        """
        The escrow contract is in Paid state after the full bulk payout, and
            it can't be aborted.
        """

        self.assertTrue(self.job.launch(self.rep_oracle_pub_key))
        self.assertTrue(self.job.setup())
        payouts = [("0x852023fbb19050B8291a335E5A83Ac9701E7B4E6",
                    Decimal("100.0"))]
        self.assertTrue(
            self.job.bulk_payout(payouts, {"results": 0},
                                 self.rep_oracle_pub_key))
        self.assertFalse(self.job.abort())
        self.assertEqual(self.job.status(), Status(4))

        # Trusted handler should be able to abort an existing contract

        self.job = Job(self.credentials, manifest)
        self.assertTrue(self.job.launch(self.rep_oracle_pub_key))
        self.assertTrue(self.job.setup())
        trusted_handler = "0x6b7E3C31F34cF38d1DFC1D9A8A59482028395809"
        self.assertTrue(self.job.add_trusted_handlers([trusted_handler]))

        handler_credentials = {
            "gas_payer":
            "0x6b7E3C31F34cF38d1DFC1D9A8A59482028395809",
            "gas_payer_priv":
            "f22d4fc42da79aa5ba839998a0a9f2c2c45f5e55ee7f1504e464d2c71ca199e1",
            "rep_oracle_priv_key":
            b"28e516f1e2f99e96a48a23cea1f94ee5f073403a1c68e818263f0eb898f1c8e5",
        }
        access_job = Job(
            credentials=handler_credentials,
            factory_addr=self.job.factory_contract.address,
            escrow_addr=self.job.job_contract.address,
        )
        self.assertTrue(access_job.abort())
Beispiel #19
0
    def test_job_bulk_payout_with_encryption_option(self):
        """Tests whether final results must be persisted in storage encrypted
        or plain.
        """
        job = Job(self.credentials, manifest)
        self.assertEqual(job.launch(self.rep_oracle_pub_key), True)
        self.assertEqual(job.setup(), True)

        payouts = [("0x852023fbb19050B8291a335E5A83Ac9701E7B4E6",
                    Decimal("100.0"))]

        final_results = {'results': 0}

        mock_upload = MagicMock(return_value=('hash', 'url'))

        # Testing option as: do not encrypt final results: encrypt_final_results=False
        with patch('hmt_escrow.job.upload', mock_upload):
            # Bulk payout with final results as plain (not encrypted)
            job.bulk_payout(payouts=payouts,
                            results=final_results,
                            pub_key=self.rep_oracle_pub_key,
                            encrypt_final_results=False)

            mock_upload.assert_called_once_with(
                msg=final_results,
                public_key=self.rep_oracle_pub_key,
                encrypt_data=False)
            mock_upload.reset_mock()

        # Testing option as: encrypt final results: encrypt_final_results=True
        with patch("hmt_escrow.job.upload", mock_upload):
            # Bulk payout with final results as plain (not encrypted)
            job.bulk_payout(payouts=payouts,
                            results={"results": 0},
                            pub_key=self.rep_oracle_pub_key,
                            encrypt_final_results=True)

            mock_upload.assert_called_once_with(
                msg=final_results,
                public_key=self.rep_oracle_pub_key,
                encrypt_data=True)
Beispiel #20
0
    def test_intermediate_results_job(self):
        """Test case for intermediate_results_job

        Retrieve the intermediate results stored by the Recording Oracle
        """
        job = Job({
            "gas_payer": GAS_PAYER,
            "gas_payer_priv": GAS_PAYER_PRIV
        }, manifest, FACTORY_ADDRESS)
        job.launch(REP_ORACLE_PUB_KEY)
        job.setup()
        job.store_intermediate_results({"results": True}, REP_ORACLE_PUB_KEY)
        query_string = [('address', job.job_contract.address),
                        ('gasPayer', GAS_PAYER),
                        ('gasPayerPrivate', GAS_PAYER_PRIV),
                        ('repOraclePrivate', GAS_PAYER_PRIV.lstrip("0x"))]
        response = self.client.open('/job/intermediateResults',
                                    method='GET',
                                    query_string=query_string)
        self.assert200(response,
                       'Response body is: ' + response.data.decode('utf-8'))
Beispiel #21
0
    def test_final_results_job(self):
        """Test case for final_results_job

        Retrieve the final results stored by the Recording Oracle
        """
        job = Job({
            "gas_payer": GAS_PAYER,
            "gas_payer_priv": GAS_PAYER_PRIV
        }, manifest, FACTORY_ADDRESS)
        job.launch(REP_ORACLE_PUB_KEY)
        job.setup()
        payouts = [("0x852023fbb19050B8291a335E5A83Ac9701E7B4E6",
                    Decimal('100.0'))]
        job.bulk_payout(payouts, {'results': 0}, REP_ORACLE_PUB_KEY)
        query_string = [('address', job.job_contract.address),
                        ('gasPayer', GAS_PAYER),
                        ('gasPayerPrivate', GAS_PAYER_PRIV),
                        ('repOraclePrivate', GAS_PAYER_PRIV.lstrip("0x"))]
        response = self.client.open('/job/finalResults',
                                    method='GET',
                                    query_string=query_string)
        self.assert200(response,
                       'Response body is: ' + response.data.decode('utf-8'))
Beispiel #22
0
    def test_store_job_intermediate_results_job(self):
        """Test case for store_job_intermediate_results_job

        Store intermediate results to S3 for the given escrow
        """
        results_url = f"file://{RESULTS_PATH}"
        job = Job({
            "gas_payer": GAS_PAYER,
            "gas_payer_priv": GAS_PAYER_PRIV
        }, manifest, FACTORY_ADDRESS)
        job.launch(REP_ORACLE_PUB_KEY)
        job.setup()
        body = StoreJobIntermediateResultsBody(
            GAS_PAYER, GAS_PAYER_PRIV, job.job_contract.address,
            REP_ORACLE_PUB_KEY.decode("utf-8"), results_url)
        response = self.client.open('/job/storeIntermediateResults',
                                    method='POST',
                                    data=json.dumps(body),
                                    content_type='application/json')
        self.assert200(response,
                       'Response body is: ' + response.data.decode('utf-8'))
        self.assertTrue(
            json.loads(response.data.decode('utf-8')).get("success", False))
Beispiel #23
0
    def test_job_init(self):
        # Creating a new Job instance initializes the critical attributes correctly.
        self.assertEqual(self.job.gas_payer, self.credentials["gas_payer"])
        self.assertEqual(self.job.gas_payer_priv,
                         self.credentials["gas_payer_priv"])
        self.assertEqual(self.job.serialized_manifest["oracle_stake"], "0.05")
        self.assertEqual(self.job.amount, Decimal("100.0"))

        # Initializing a new Job instance with a factory address succeeds.
        factory_addr = deploy_factory(**(self.credentials))
        self.job = Job(self.credentials, manifest, factory_addr)
        self.assertTrue(self.job.factory_contract.address, factory_addr)
        self.assertTrue(self.job.launch(self.rep_oracle_pub_key))
        self.assertTrue(self.job.setup())
        self.assertTrue(
            launcher(self.job.job_contract,
                     self.credentials["gas_payer"]).lower(),
            self.job.factory_contract.address.lower(),
        )

        # Initializing an existing Job instance with a factory and escrow address succeeds.
        self.credentials[
            "rep_oracle_priv_key"] = b"28e516f1e2f99e96a48a23cea1f94ee5f073403a1c68e818263f0eb898f1c8e5"
        escrow_addr = self.job.job_contract.address
        factory_addr = self.job.factory_contract.address
        manifest_url = self.job.manifest_url
        new_job = Job(
            credentials=self.credentials,
            factory_addr=factory_addr,
            escrow_addr=escrow_addr,
        )
        self.assertEqual(new_job.manifest_url, manifest_url)
        self.assertEqual(new_job.job_contract.address, escrow_addr)
        self.assertEqual(new_job.factory_contract.address, factory_addr)
        with self.assertRaises(AttributeError):
            new_job.launch(self.rep_oracle_pub_key)
Beispiel #24
0
def new_job(body=None):  # noqa: E501
    """Creates a new Job and returns the address

    Creates a new job and returns the address # noqa: E501

    :param body: 
    :type body: dict | bytes

    :rtype: StringDataResponse
    """
    if connexion.request.is_json:
        body = JobCreateBody.from_dict(
            connexion.request.get_json())  # noqa: E501
        try:
            req = Request(body.manifest_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()
            manifest = json.loads(data)
            job = Job(
                {
                    "gas_payer": body.gas_payer,
                    "gas_payer_priv": body.gas_payer_private
                }, Manifest(manifest), body.factory_address)
        except Exception as e:
            return ErrorParameterResponse(
                str(e), "manifest_url or gas_payer_private"), 401
        try:
            job.launch(bytes(body.rep_oracle_pub, encoding="utf-8"))
            job.setup()
            return StringDataResponse(job.job_contract.address), 200
        except Exception as e:
            return ErrorParameterResponse(str(e), "rep_oracle_pub_key"), 401
Beispiel #25
0
class JobTestCase(unittest.TestCase):
    def setUp(self):
        self.credentials = {
            "gas_payer":
            "0x1413862C2B7054CDbfdc181B83962CB0FC11fD92",
            "gas_payer_priv":
            "28e516f1e2f99e96a48a23cea1f94ee5f073403a1c68e818263f0eb898f1c8e5",
        }
        self.rep_oracle_pub_key = b"2dbc2c2c86052702e7c219339514b2e8bd4687ba1236c478ad41b43330b08488c12c8c1797aa181f3a4596a1bd8a0c18344ea44d6655f61fa73e56e743f79e0d"
        self.job = Job(self.credentials, manifest)

    def test_lauch(self):
        """ Tests job launch """
        lauched = self.job.launch(self.rep_oracle_pub_key)
        self.assertEqual(lauched, True)

        next_status = status(self.job.job_contract, self.job.gas_payer)
        self.assertEqual(next_status, Status.Launched)

    def test_status(self):
        lauched = self.job.launch(self.rep_oracle_pub_key)
        self.assertEqual(lauched, True)

        next_status = status(self.job.job_contract, self.job.gas_payer)
        self.assertEqual(next_status, Status.Launched)

    def test_manifest_url(self):
        self.assertTrue(self.job.launch(self.rep_oracle_pub_key))
        self.assertTrue(self.job.setup())
        self.assertEqual(
            manifest_hash(self.job.job_contract, self.job.gas_payer),
            self.job.manifest_hash,
        )

    def test_job_init(self):
        # Creating a new Job instance initializes the critical attributes correctly.
        self.assertEqual(self.job.gas_payer, self.credentials["gas_payer"])
        self.assertEqual(self.job.gas_payer_priv,
                         self.credentials["gas_payer_priv"])
        self.assertEqual(self.job.serialized_manifest["oracle_stake"], "0.05")
        self.assertEqual(self.job.amount, Decimal("100.0"))

        # Initializing a new Job instance with a factory address succeeds.
        factory_addr = deploy_factory(**(self.credentials))
        self.job = Job(self.credentials, manifest, factory_addr)
        self.assertTrue(self.job.factory_contract.address, factory_addr)
        self.assertTrue(self.job.launch(self.rep_oracle_pub_key))
        self.assertTrue(self.job.setup())
        self.assertTrue(
            launcher(self.job.job_contract,
                     self.credentials["gas_payer"]).lower(),
            self.job.factory_contract.address.lower(),
        )

        # Initializing an existing Job instance with a factory and escrow address succeeds.
        self.credentials[
            "rep_oracle_priv_key"] = b"28e516f1e2f99e96a48a23cea1f94ee5f073403a1c68e818263f0eb898f1c8e5"
        escrow_addr = self.job.job_contract.address
        factory_addr = self.job.factory_contract.address
        manifest_url = self.job.manifest_url
        new_job = Job(
            credentials=self.credentials,
            factory_addr=factory_addr,
            escrow_addr=escrow_addr,
        )
        self.assertEqual(new_job.manifest_url, manifest_url)
        self.assertEqual(new_job.job_contract.address, escrow_addr)
        self.assertEqual(new_job.factory_contract.address, factory_addr)
        with self.assertRaises(AttributeError):
            new_job.launch(self.rep_oracle_pub_key)

    def test_job_launch(self):
        self.assertTrue(self.job.launch(self.rep_oracle_pub_key))
        self.assertEqual(self.job.status(), Status(1))
        multi_credentials = [
            (
                "0x61F9F0B31eacB420553da8BCC59DC617279731Ac",
                "486a0621e595dd7fcbe5608cbbeec8f5a8b5cabe7637f11eccfc7acd408c3a0e",
            ),
            (
                "0x6b7E3C31F34cF38d1DFC1D9A8A59482028395809",
                "f22d4fc42da79aa5ba839998a0a9f2c2c45f5e55ee7f1504e464d2c71ca199e1",
            ),
        ]
        self.job = Job(self.credentials,
                       manifest,
                       multi_credentials=multi_credentials)

        # Inject wrong credentials on purpose to test out raffling

        self.job.gas_payer_priv = (
            "657b6497a355a3982928d5515d48a84870f057c4d16923eb1d104c0afada9aa8")
        self.job.multi_credentials = [
            (
                "0x61F9F0B31eacB420553da8BCC59DC617279731Ac",
                "28e516f1e2f99e96a48a23cea1f94ee5f073403a1c68e818263f0eb898f1c8e5",
            ),
            (
                "0x6b7E3C31F34cF38d1DFC1D9A8A59482028395809",
                "f22d4fc42da79aa5ba839998a0a9f2c2c45f5e55ee7f1504e464d2c71ca199e1",
            ),
        ]
        self.assertTrue(self.job.launch(self.rep_oracle_pub_key))
        self.assertEqual(self.job.status(), Status(1))

        # Make sure we launched with raffled credentials

        self.assertEqual(self.job.gas_payer,
                         "0x6b7E3C31F34cF38d1DFC1D9A8A59482028395809")
        self.assertEqual(
            self.job.gas_payer_priv,
            "f22d4fc42da79aa5ba839998a0a9f2c2c45f5e55ee7f1504e464d2c71ca199e1",
        )

    def test_job_setup(self):
        # A Job can't be setup without deploying it first.

        self.assertFalse(self.job.setup())
        multi_credentials = [
            (
                "0x61F9F0B31eacB420553da8BCC59DC617279731Ac",
                "28e516f1e2f99e96a48a23cea1f94ee5f073403a1c68e818263f0eb898f1c8e5",
            ),
            (
                "0x6b7E3C31F34cF38d1DFC1D9A8A59482028395809",
                "f22d4fc42da79aa5ba839998a0a9f2c2c45f5e55ee7f1504e464d2c71ca199e1",
            ),
        ]
        self.job = Job(self.credentials,
                       manifest,
                       multi_credentials=multi_credentials)
        self.assertTrue(self.job.launch(self.rep_oracle_pub_key))
        self.assertTrue(self.job.setup())

    def test_job_add_trusted_handlers(self):
        # Make sure we se set our gas payer as a trusted handler by default.

        self.assertTrue(self.job.launch(self.rep_oracle_pub_key))
        self.assertTrue(
            is_trusted_handler(self.job.job_contract, self.job.gas_payer,
                               self.job.gas_payer))
        trusted_handlers = [
            "0x61F9F0B31eacB420553da8BCC59DC617279731Ac",
            "0xD979105297fB0eee83F7433fC09279cb5B94fFC6",
        ]
        self.assertTrue(self.job.add_trusted_handlers(trusted_handlers))
        self.assertTrue(
            is_trusted_handler(
                self.job.job_contract,
                "0x61F9F0B31eacB420553da8BCC59DC617279731Ac",
                self.job.gas_payer,
            ))
        self.assertTrue(
            is_trusted_handler(
                self.job.job_contract,
                "0xD979105297fB0eee83F7433fC09279cb5B94fFC6",
                self.job.gas_payer,
            ))

    def test_job_bulk_payout(self):
        self.assertTrue(self.job.launch(self.rep_oracle_pub_key))
        self.assertTrue(self.job.setup())
        payouts = [
            ("0x6b7E3C31F34cF38d1DFC1D9A8A59482028395809", Decimal("20.0")),
            ("0x852023fbb19050B8291a335E5A83Ac9701E7B4E6", Decimal("50.0")),
        ]
        self.assertTrue(
            self.job.bulk_payout(payouts, {}, self.rep_oracle_pub_key))

        # The escrow contract is still in Partial state as there's still balance left.

        self.assertEqual(self.job.balance(), 30000000000000000000)
        self.assertEqual(self.job.status(), Status(3))

        # Trying to pay more than the contract balance results in failure.

        payouts = [("0x9d689b8f50Fd2CAec716Cc5220bEd66E03F07B5f",
                    Decimal("40.0"))]
        self.assertFalse(
            self.job.bulk_payout(payouts, {}, self.rep_oracle_pub_key))

        # Paying the remaining amount empties the escrow and updates the status correctly.

        payouts = [("0x9d689b8f50Fd2CAec716Cc5220bEd66E03F07B5f",
                    Decimal("30.0"))]
        self.assertTrue(
            self.job.bulk_payout(payouts, {}, self.rep_oracle_pub_key))
        self.assertEqual(self.job.balance(), 0)
        self.assertEqual(self.job.status(), Status(4))

        multi_credentials = [
            (
                "0x61F9F0B31eacB420553da8BCC59DC617279731Ac",
                "486a0621e595dd7fcbe5608cbbeec8f5a8b5cabe7637f11eccfc7acd408c3a0e",
            ),
            (
                "0x6b7E3C31F34cF38d1DFC1D9A8A59482028395809",
                "f22d4fc42da79aa5ba839998a0a9f2c2c45f5e55ee7f1504e464d2c71ca199e1",
            ),
        ]
        self.job = Job(self.credentials,
                       manifest,
                       multi_credentials=multi_credentials)
        self.assertTrue(self.job.launch(self.rep_oracle_pub_key))
        self.assertTrue(self.job.setup())
        payouts = [
            ("0x6b7E3C31F34cF38d1DFC1D9A8A59482028395809", Decimal("20.0")),
            ("0x852023fbb19050B8291a335E5A83Ac9701E7B4E6", Decimal("50.0")),
        ]
        self.assertTrue(
            self.job.bulk_payout(payouts, {}, self.rep_oracle_pub_key))

    def test_job_bulk_payout_with_encryption_option(self):
        """Tests whether final results must be persisted in storage encrypted
        or plain.
        """
        job = Job(self.credentials, manifest)
        self.assertEqual(job.launch(self.rep_oracle_pub_key), True)
        self.assertEqual(job.setup(), True)

        payouts = [("0x852023fbb19050B8291a335E5A83Ac9701E7B4E6",
                    Decimal("100.0"))]

        final_results = {'results': 0}

        mock_upload = MagicMock(return_value=('hash', 'url'))

        # Testing option as: do not encrypt final results: encrypt_final_results=False
        with patch('hmt_escrow.job.upload', mock_upload):
            # Bulk payout with final results as plain (not encrypted)
            job.bulk_payout(payouts=payouts,
                            results=final_results,
                            pub_key=self.rep_oracle_pub_key,
                            encrypt_final_results=False)

            mock_upload.assert_called_once_with(
                msg=final_results,
                public_key=self.rep_oracle_pub_key,
                encrypt_data=False)
            mock_upload.reset_mock()

        # Testing option as: encrypt final results: encrypt_final_results=True
        with patch("hmt_escrow.job.upload", mock_upload):
            # Bulk payout with final results as plain (not encrypted)
            job.bulk_payout(payouts=payouts,
                            results={"results": 0},
                            pub_key=self.rep_oracle_pub_key,
                            encrypt_final_results=True)

            mock_upload.assert_called_once_with(
                msg=final_results,
                public_key=self.rep_oracle_pub_key,
                encrypt_data=True)

    def test_job_abort(self):
        """
        The escrow contract is in Paid state after the full bulk payout, and
            it can't be aborted.
        """

        self.assertTrue(self.job.launch(self.rep_oracle_pub_key))
        self.assertTrue(self.job.setup())
        payouts = [("0x852023fbb19050B8291a335E5A83Ac9701E7B4E6",
                    Decimal("100.0"))]
        self.assertTrue(
            self.job.bulk_payout(payouts, {"results": 0},
                                 self.rep_oracle_pub_key))
        self.assertFalse(self.job.abort())
        self.assertEqual(self.job.status(), Status(4))

        # Trusted handler should be able to abort an existing contract

        self.job = Job(self.credentials, manifest)
        self.assertTrue(self.job.launch(self.rep_oracle_pub_key))
        self.assertTrue(self.job.setup())
        trusted_handler = "0x6b7E3C31F34cF38d1DFC1D9A8A59482028395809"
        self.assertTrue(self.job.add_trusted_handlers([trusted_handler]))

        handler_credentials = {
            "gas_payer":
            "0x6b7E3C31F34cF38d1DFC1D9A8A59482028395809",
            "gas_payer_priv":
            "f22d4fc42da79aa5ba839998a0a9f2c2c45f5e55ee7f1504e464d2c71ca199e1",
            "rep_oracle_priv_key":
            b"28e516f1e2f99e96a48a23cea1f94ee5f073403a1c68e818263f0eb898f1c8e5",
        }
        access_job = Job(
            credentials=handler_credentials,
            factory_addr=self.job.factory_contract.address,
            escrow_addr=self.job.job_contract.address,
        )
        self.assertTrue(access_job.abort())

    def test_job_cancel(self):
        self.assertTrue(self.job.launch(self.rep_oracle_pub_key))
        self.assertTrue(self.job.setup())
        payouts = [("0x6b7E3C31F34cF38d1DFC1D9A8A59482028395809",
                    Decimal("20.0"))]
        self.assertTrue(
            self.job.bulk_payout(payouts, {}, self.rep_oracle_pub_key))
        self.assertEqual(self.job.status(), Status(3))

        # The escrow contract is in Paid state after the second payout and it can't be cancelled.

        payouts = [("0x852023fbb19050B8291a335E5A83Ac9701E7B4E6",
                    Decimal("80.0"))]
        self.assertTrue(
            self.job.bulk_payout(payouts, {"results": 0},
                                 self.rep_oracle_pub_key))
        self.assertFalse(self.job.cancel())
        self.assertEqual(self.job.status(), Status(4))

    def test_job_status(self):
        self.assertTrue(self.job.launch(self.rep_oracle_pub_key))
        self.assertEqual(self.job.status(), Status(1))

    def test_job_balance(self):
        self.assertTrue(self.job.launch(self.rep_oracle_pub_key))
        self.assertTrue(self.job.setup())
        self.assertEqual(self.job.balance(), 100000000000000000000)

    def test_launch_failure(self):
        """ Test _launch raises error on failure to create contract """

        handler_mock = MagicMock()
        handler_mock.side_effect = Exception("")

        e = None
        with self.assertRaises(Exception) as e:
            with patch("hmt_escrow.eth_bridge.handle_transaction",
                       handler_mock):
                self.job.launch(b"")

        self.assertIsNotNone(e)
        self.assertEqual(str(e.exception), "Unable to create escrow")

    def test__raffle_txn_retry(self):
        """ Test general retry logic """

        retries = 4
        delay = 0.01
        backoff = 2
        self.job.retry = Retry(retries=retries, delay=delay, backoff=backoff)

        txn_mock = MagicMock()
        handler_mock = MagicMock(side_effect=Exception)
        sleep_mock = MagicMock()

        with patch("hmt_escrow.eth_bridge.handle_transaction",
                   handler_mock), patch("hmt_escrow.eth_bridge.sleep",
                                        sleep_mock):
            success = self.job._raffle_txn(
                multi_creds=[("1", "11")],
                txn_func=txn_mock,
                txn_args=[],
                txn_event="Transfer",
            )

            self.assertFalse(success)

            self.assertEqual(
                handler_mock.call_args_list,
                [
                    call(txn_mock,
                         gas_payer="1",
                         gas_payer_priv="11",
                         gas=6700000) for i in range(5)
                ],
            )
            self.assertEqual(
                sleep_mock.call_args_list,
                [call(delay * backoff**i) for i in range(retries)],
            )

            sleep_mock.reset_mock()
            handler_mock.reset_mock()
            handler_mock.side_effect = Exception

            # no retries
            self.job.retry = Retry()

            success = self.job._raffle_txn(
                multi_creds=[("1", "11")],
                txn_func=txn_mock,
                txn_args=[],
                txn_event="Transfer",
            )

            self.assertFalse(success)
            self.assertEqual(
                handler_mock.call_args_list,
                [
                    call(txn_mock,
                         gas_payer="1",
                         gas_payer_priv="11",
                         gas=6700000)
                ],
            )
            self.assertEqual(sleep_mock.call_args_list, [])

    def test_get_hmt_balance(self):
        """ Test wallet HMT balance is OK """
        amount = utils.get_hmt_balance(
            "0x1413862C2B7054CDbfdc181B83962CB0FC11fD92",
            "0x56B532F1D090E4edb1c92F30d3087771AE6B6992",
            get_w3(),
        )
        print(amount)
        self.assertGreater(amount, 10000)