def test_trip_to_core(w3, contract, token_contract, dapp_contract): core_socket.connect() results_json = core_socket.get_report() address = results_json['address'] quote = Quote.from_enigma_proxy(results_json['quote'], server='https://sgx.enigma.co/api') worker = Worker(account=w3.personal.listAccounts[0], contract=contract, token=token_contract, ecdsa_address=address, quote=quote) tx = worker.register(report=json.dumps(quote.report), sig=quote.sig, report_cert=quote.cert) w3.eth.waitForTransactionReceipt(tx) info = worker.info() # print(info) tx = worker.trigger_compute_task( dapp_contract=dapp_contract.address, callable=callable, callable_args=callable_args, callback=callback, preprocessors=preprocessors, fee=1, block_number=w3.eth.blockNumber, ) w3.eth.waitForTransactionReceipt(tx) event = event_data(contract, tx, 'ComputeTask') bytecode = contract.web3.eth.getCode( contract.web3.toChecksumAddress(dapp_contract.address)) sig, result = core_socket.exec_evm( bytecode=bytecode.hex(), callable=event.args.callable, callable_args=event.args.callableArgs.hex(), preprocessors=event.args.preprocessors, callback=event.args.callback) print("sig: ", sig) print("result: ", result) k_hash = sha3.keccak_256() k_hash.update(event.args.callableArgs) k_hash.update(bytes.fromhex(result)) k_hash.update(bytecode) print('Combined hash: ', k_hash.hexdigest()) tx = worker.commit_results(event.args.taskId, result, sig, event.blockNumber) w3.eth.waitForTransactionReceipt(tx) event = event_data(contract, tx, 'CommitResults') print(event) assert event['args']['_success']
def test_register_principal(w3, principal, contract, principal_data): tx = principal.register(principal_data['report'], principal_data['cert'], principal_data['report_sig']) w3.eth.waitForTransactionReceipt(tx) event = event_data(contract, tx, 'Register') assert event['args']['_success']
def watch(self): """ Query each block for a ComputeTask Event :yield: A ComputeTask dictionary """ # I was not able to make an event filter work so I'm using a block # filter and querying each block for the kind of event which we are # looking for. block_filter = self.contract.web3.eth.filter('latest') while True: for block_hash in block_filter.get_new_entries(): block = self.contract.web3.eth.getBlock(block_hash) for tx in block['transactions']: try: event = event_data(self.contract, tx, 'ComputeTask') if event.address == self.contract.address: task = event['args'] yield task, event.blockNumber except ValueError: pass sleep(self.POLLING_INTERVAL)
def test_register(w3, worker, contract, workers_data): # This will fail if already registered # Redeploy the contract to clear the state worker_data = workers_data[0] tx = worker.register(worker_data['report'], worker_data['cert'], worker_data['report_sig']) w3.eth.waitForTransactionReceipt(tx) event = event_data(contract, tx, 'Register') assert event['args']['_success']
def test_set_worker_params(w3, principal, principal_data): seed = randint(1, 1000000) hash = Web3.soliditySha3( abi_types=['uint256'], values=[seed], ) priv = get_private_key(principal_data) priv_bytes = bytes.fromhex(priv) sig = w3.eth.account.signHash(hash, private_key=priv_bytes) tx = principal.contract.functions.setWorkersParams( seed, sig['signature']).transact({'from': principal.account}) w3.eth.waitForTransactionReceipt(tx) event = event_data(principal.contract, tx, 'WorkersParameterized') assert event['args']['_success']
def task(w3, request, dapp_contract, worker, contract): """ Creating a new task for testing. This fixture reliably emulates the `task` object emitted by the listener """ tx = worker.trigger_compute_task( dapp_contract=dapp_contract.address, callable=request.param['callable'], callable_args=request.param['args'], callback=request.param['callback'], preprocessors=request.param['preprocessors'], fee=request.param['fee'], block_number=w3.eth.blockNumber, ) w3.eth.waitForTransactionReceipt(tx) event = event_data(contract, tx, 'ComputeTask') assert event['args']['_success'] yield event['args']
def handle_task(w3, worker, task, block, core_socket): log.debug('TaskId: {}'.format(task.taskId.hex())) # TODO: this is hard to unit test # I think that we should allow a mock core with the same properties of core # but returning mock results. We should be able to decouple unit testing of # surface from core. selected_worker = worker.find_selected_worker(task) if selected_worker != worker.account: log.info('skipping task {} assign to: {}'.format( task['taskId'], selected_worker)) return False # 3. Compute the task bytecode = w3.eth.getCode(w3.toChecksumAddress(task.dappContract)) bytecode = bytecode.hex() log.info('the bytecode: {}'.format(bytecode)) # The arguments are now RLP encoded # args = worker.encode_call(task['callable'], task['callable_args']) # args = Listener.parse_args(task['callable'], task['callable_args']) # log.info('the callable functin arguments: {}'.format(args)) # TODO: what happens if this worker rejects a task? # TODO: how does the worker know if he is selected to perform the task? sig, results = core_socket.exec_evm(bytecode=bytecode, callable=task.callable, callable_args=task.callableArgs.hex(), preprocessors=task.preprocessors, callback=task.callback) print(results) # 4. Commit the output back to the contract tx = worker.commit_results(task.taskId, results, sig, block) w3.eth.waitForTransactionReceipt(tx) event = utils.event_data(worker.contract, tx, 'CommitResults') # TODO: Handle failure assert event['args']['_success']
def test_commit_results(w3, task, worker, dapp_contract, contract, results, workers_data): # Code from here an below normally belong to Core bytecode = contract.web3.eth.getCode( contract.web3.toChecksumAddress(dapp_contract.address)) data = Worker.encode_call(task['callback'], results) callableArgs = task['callableArgs'] hash = Web3.soliditySha3(abi_types=['bytes', 'bytes', 'bytes'], values=[callableArgs, data, bytecode]) # TODO: improve to support multiple workers worker_data = workers_data[0] priv = get_private_key(worker_data) priv_bytes = bytes.fromhex(priv) sig = w3.eth.account.signHash(hash, private_key=priv_bytes) # Code from here and below belongs to Surface tx = worker.commit_results(task.taskId, data, sig['signature'], task['blockNumber']) w3.eth.waitForTransactionReceipt(tx) event = event_data(contract, tx, 'CommitResults') assert event['args']['_success']
def trigger_compute_task(self, dapp_contract, callable, callable_args, callback, preprocessors, fee, block_number): """ Send a computation tasks. :param dapp_contract: :param callable: :param callable_args: :param callback: :param preprocessors: :param fee: :return: """ log.info('executing computation on contract: {}'.format(dapp_contract)) balance = self.token.functions.balanceOf(self.account).call( {'from': self.account}) if balance < fee: raise ValueError('ENG balance to low to cover fee.') approved_tx = self.token.functions.approve( self.contract.address, fee).transact({'from': self.account}) event = event_data(self.token, approved_tx, 'Approval') log.debug('the approval event: {}'.format(event)) allowance = self.token.functions.allowance( self.account, self.contract.address).call({'from': self.account}) if allowance < fee: raise ValueError('Could not approve enough ENG to cover fee.') msg = rlp.encode(callable_args) tx = self.contract.functions.compute( dapp_contract, callable, msg, callback, fee, preprocessors, block_number).transact({'from': self.account}) return tx