class ETHUtils: def __init__(self, account, web3_http_provider, ens_contract, erc20_token=None, abi=None): http_provider = HTTPProvider(web3_http_provider) self.ens = ENS(http_provider, addr=ens_contract) self.web3 = Web3(http_provider, ens=self.ens) from web3.middleware import geth_poa_middleware # inject the poa compatibility middleware to the innermost layer self.web3.middleware_stack.inject(geth_poa_middleware, layer=0) self.ens.web3.middleware_stack.inject(geth_poa_middleware, layer=0) if erc20_token is not None and abi is not None: token_address = self.ens.address(erc20_token) self.erc20 = self.web3.eth.contract(token_address, abi=abi) self.erc20_balance_delimiter = (10 ** self.erc20.functions.decimals().call()) self.__account = account @property def erc20Contract(self): return self.erc20 @property def getCurrentBlockNumber(self): return self.web3.eth.blockNumber def getAddressByName(self, name): return self.ens.address(name) def getAccountTransactionCount(self): return self.web3.eth.getTransactionCount(self.__account.address) def signTransaction(self, tx): return self.__account.signTransaction(tx) def sendRawTransaction(self, raw_tx): return self.web3.eth.sendRawTransaction(raw_tx) def signAndSendTransaction(self, tx): signed_tx = self.signTransaction(tx=tx) return self.sendRawTransaction(raw_tx=signed_tx.rawTransaction) def getTransaction(self, tx_hash): return self.web3.eth.getTransaction(tx_hash) def getBalance(self, account): return self.web3.fromWei(self.web3.eth.getBalance(account), 'ether') def getTokenBalance(self, account): return self.erc20.functions.balanceOf(account).call() / self.erc20_balance_delimiter def getAllowance(self, account, address): return self.erc20.functions.allowance(account, address).call()
class Node: def __init__(self): rospy.init_node('erc20_node', anonymous=True) http_provider = HTTPProvider(rospy.get_param('~web3_http_provider')) self.ens = ENS(http_provider, addr=rospy.get_param('~ens_contract', None)) self.web3 = Web3(http_provider, ens=self.ens) from web3.middleware import geth_poa_middleware # inject the poa compatibility middleware to the innermost layer self.web3.middleware_stack.inject(geth_poa_middleware, layer=0) self.ens.web3.middleware_stack.inject(geth_poa_middleware, layer=0) token_address = self.ens.address(rospy.get_param('~token_contract')) self.erc20 = self.web3.eth.contract(token_address, abi=ABI) self.transfer = rospy.Publisher('event/transfer', TransferEvent, queue_size=10) self.approval = rospy.Publisher('event/approval', ApprovalEvent, queue_size=10) rospy.Service( 'transfer', Transfer, lambda m: TransferResponse( self.erc20.functions.transfer(m.to.address, int(m.value.uint256 )).transact())) rospy.Service( 'transfer_from', TransferFrom, lambda m: TransferFromResponse( self.erc20.functions .transferFrom(m.owner.address, m.to.address, int(m.value.uint256)).transact())) rospy.Service( 'approve', Approve, lambda m: ApproveResponse( self.erc20.functions.approve(m.spender.address, int(m.value.uint256)).transact())) rospy.Service( 'accounts', Accounts, lambda m: AccountsResponse( list(map(strToAddress, self.web3.eth.accounts)))) def spin(self): transfer_filter = self.erc20.eventFilter('Transfer') approval_filter = self.erc20.eventFilter('Approval') def filter_thread(): for e in transfer_filter.get_new_entries(): self.transfer.publish(transferEvent(e['args'])) for e in approval_filter.get_new_entries(): self.approval.publish(approvalEvent(e['args'])) Timer(1, filter_thread).start() filter_thread() rospy.spin()
class Signer: def __init__(self): ''' Lighthouse signer initialisation. ''' rospy.init_node('robonomics_signer') ens_contract = rospy.get_param('~ens_contract', None) web3_http_provider = rospy.get_param('~web3_http_provider') http_provider = HTTPProvider(web3_http_provider) self.ens = ENS(http_provider, addr=ens_contract) self.web3 = Web3(http_provider, ens=self.ens) from web3.middleware import geth_poa_middleware # inject the poa compatibility middleware to the innermost layer self.web3.middleware_stack.inject(geth_poa_middleware, layer=0) self.ens.web3.middleware_stack.inject(geth_poa_middleware, layer=0) __factory_contract_abi = rospy.get_param('~factory_contract_abi') __factory_contract = rospy.get_param('~factory_contract') self.factory = None __keyfile = rospy.get_param('~keyfile') __keyfile_password_file = rospy.get_param('~keyfile_password_file') __keyfile_helper = eth_keyfile_helper.KeyfileHelper( __keyfile, keyfile_password_file=__keyfile_password_file) self.__account = __keyfile_helper.get_local_account_from_keyfile() self.signed_demand = rospy.Publisher('sending/demand', Demand, queue_size=10) self.signed_offer = rospy.Publisher('sending/offer', Offer, queue_size=10) self.signed_result = rospy.Publisher('sending/result', Result, queue_size=10) self.__factory_initialization_lock = Lock() def get_initialized_factory(): if self.factory is None: try: factory_abi = json.loads(__factory_contract_abi) factory_address = self.ens.address(__factory_contract) try: self.__factory_initialization_lock.acquire() if self.factory is None: self.factory = self.web3.eth.contract( factory_address, abi=factory_abi) finally: self.__factory_initialization_lock.release() return self.factory except StaleBlockchain as e: rospy.logwarn( "Failed to initialize factory cause exception: %s", e) else: return self.factory def get_nonce_by_address(address): try: nonce = get_initialized_factory().call().nonceOf( address.address) return UInt256(nonce) except Exception as e: rospy.logerr( "Failed to get nonce by address %s with exception: %s", address.address, e) try: self.__factory_initialization_lock.acquire() self.factory = None finally: self.__factory_initialization_lock.release() def sign_demand(msg): msg.sender = Address(self.__account.address) if messageValidator.isDemandFieldsCorrect(msg): msg = robonomicsMessageUtils.convert_msg_ens_names_to_addresses( msg, web3=self.web3) current_nonce = get_nonce_by_address(msg.sender) message_hash = robonomicsMessageUtils.demand_hash( msg, current_nonce) signed_hash = self.__account.signHash( defunct_hash_message(message_hash)) msg.signature = signed_hash.signature msg.nonce = UInt256(uint256=str(current_nonce.uint256)) rospy.loginfo('askhash: %s signature: %s', binascii.hexlify(message_hash), binascii.hexlify(msg.signature)) self.signed_demand.publish(msg) else: rospy.logerr( "Signing demand error: msg %s is not valid Demand message", msg) rospy.Subscriber('signing/demand', Demand, sign_demand) def sign_offer(msg): msg.sender = Address(self.__account.address) if messageValidator.isOfferFieldsCorrect(msg): msg = robonomicsMessageUtils.convert_msg_ens_names_to_addresses( msg, web3=self.web3) current_nonce = get_nonce_by_address(msg.sender) message_hash = robonomicsMessageUtils.offer_hash( msg, current_nonce) signed_hash = self.__account.signHash( defunct_hash_message(message_hash)) msg.signature = signed_hash.signature msg.nonce = UInt256(uint256=str(current_nonce.uint256)) rospy.loginfo('bidhash: %s signature: %s', binascii.hexlify(message_hash), binascii.hexlify(msg.signature)) self.signed_offer.publish(msg) else: rospy.logerr( "Signing offer error: msg %s is not valid Offer message", msg) rospy.Subscriber('signing/offer', Offer, sign_offer) def sign_result(msg): if messageValidator.isResultFieldsCorrect(msg): msg = robonomicsMessageUtils.convert_msg_ens_names_to_addresses( msg, web3=self.web3) message_hash = robonomicsMessageUtils.result_hash(msg) signed_hash = self.__account.signHash( defunct_hash_message(message_hash)) msg.signature = signed_hash.signature rospy.loginfo('reshash: %s signature: %s', binascii.hexlify(message_hash), binascii.hexlify(msg.signature)) self.signed_result.publish(msg) else: rospy.logerr( "Signing result error: msg %s is not valid Result message") rospy.Subscriber('signing/result', Result, sign_result) def spin(self): ''' Waiting for the new messages. ''' rospy.spin()
class Listener: def __init__(self): ''' Robonomics liability tracking node initialisation. ''' rospy.init_node('robonomics_liability_listener') web3_http_provider = rospy.get_param('~web3_http_provider') http_provider = HTTPProvider(web3_http_provider) web3_ws_provider = rospy.get_param('~web3_ws_provider') ws_provider = WebsocketProvider(web3_ws_provider) ens_contract = rospy.get_param('~ens_contract', None) self.ens = ENS(http_provider, addr=ens_contract) self.web3 = Web3(http_provider, ens=self.ens) self.web3ws = Web3(ws_provider, ens=self.ens) from web3.middleware import geth_poa_middleware # inject the poa compatibility middleware to the innermost layer self.web3.middleware_stack.inject(geth_poa_middleware, layer=0) self.ens.web3.middleware_stack.inject(geth_poa_middleware, layer=0) self.poll_interval = rospy.get_param('~poll_interval', 5) self.liability = rospy.Publisher('incoming', Liability, queue_size=10) self.create_liability_filter() self.liability_abi = json.loads( rospy.get_param('~liability_contract_abi')) self.liability_finalization_checker = finalization_checker.FinalizationChecker( self.liability_abi, web3_http_provider=web3_http_provider, ens_contract=ens_contract) self.finalized = rospy.Publisher('finalized', String, queue_size=10) self.liabilities_queue = PersistentQueue( 'robonomics_liability_listener.queue') self.result = rospy.Publisher('infochan/eth/signing/result', Result, queue_size=10) self.persistence_contains_liability = rospy.ServiceProxy( 'persistence/exists', PersistenceContainsLiability) def liability_finalize(msg): rospy.logdebug("liability_finalize: msg is: %s", msg) is_finalized = False while is_finalized is not True: self.result.publish(msg) time.sleep(30) # TODO: move sleep time to rop parameter with 30 seconds by default is_finalized = self.liability_finalization_checker.finalized( msg.liability.address) self.finalized.publish(msg.liability.address) rospy.Subscriber('result', Result, liability_finalize) def create_liability_filter(self): try: factory_abi = json.loads(rospy.get_param('~factory_contract_abi')) factory_address = self.ens.address( rospy.get_param('~factory_contract')) factory = self.web3ws.eth.contract(factory_address, abi=factory_abi) self.liability_filter = factory.eventFilter('NewLiability') except Exception as e: rospy.logwarn( "Failed to create liability filter with exception: \"%s\"", e) def liability_read(self, address): ''' Read liability from blockchain to message. ''' c = self.web3.eth.contract(address, abi=self.liability_abi) msg = Liability() msg.address.address = address msg.model.multihash = multihash.decode( c.call().model()).encode('base58').decode() msg.objective.multihash = multihash.decode( c.call().objective()).encode('base58').decode() msg.promisee.address = c.call().promisee() msg.promisor.address = c.call().promisor() msg.lighthouse.address = c.call().lighthouse() msg.token.address = c.call().token() msg.cost.uint256 = str(c.call().cost()) msg.validator.address = c.call().validator() msg.validatorFee.uint256 = str(c.call().validatorFee()) rospy.logdebug('New liability readed: %s', msg) return msg def spin(self): ''' Waiting for the new liabilities. ''' def liability_filter_thread(): try: for entry in self.liability_filter.get_new_entries(): liability_address = entry['args']['liability'] self.liabilities_queue.push(liability_address) rospy.loginfo( "New liability added to persistence queue: %s", liability_address) except Exception as e: rospy.logerr('listener liability filter exception: %s', e) self.create_liability_filter() Timer(self.poll_interval, liability_filter_thread).start() def liabilities_queue_handler(): entry = self.liabilities_queue.peek() if entry is not None: try: rospy.wait_for_service( self.persistence_contains_liability.resolved_name) liability_already_in_persistence = self.persistence_contains_liability( entry) # TODO: verify that liability for my saved in persistence before pop them from liabilities_queue if not liability_already_in_persistence.exists: self.liability.publish(self.liability_read(entry)) self.liabilities_queue.pop() rospy.loginfo("Liability read successfully: %s", entry) except Exception as e: rospy.logerr('Liability %s read exception: %s', entry, e) Timer(self.poll_interval, liabilities_queue_handler).start() liability_filter_thread() liabilities_queue_handler() rospy.spin()
class Listener: def __init__(self): ''' Robonomics liability tracking node initialisation. ''' rospy.init_node('robonomics_liability_listener') web3_http_provider = rospy.get_param('~web3_http_provider') http_provider = HTTPProvider(web3_http_provider) web3_ws_provider = rospy.get_param('~web3_ws_provider') ws_provider = WebsocketProvider(web3_ws_provider) ens_contract = rospy.get_param('~ens_contract', None) self.ens = ENS(http_provider, addr=ens_contract) self.web3 = Web3(http_provider, ens=self.ens) self.web3ws = Web3(ws_provider, ens=self.ens) from web3.middleware import geth_poa_middleware # inject the poa compatibility middleware to the innermost layer self.web3.middleware_stack.inject(geth_poa_middleware, layer=0) self.ens.web3.middleware_stack.inject(geth_poa_middleware, layer=0) self.poll_interval = rospy.get_param('~poll_interval', 5) self.liability = rospy.Publisher('incoming', Liability, queue_size=10) self.create_liability_filter() self.liability_abi = json.loads( rospy.get_param('~liability_contract_abi')) self.liability_finalization_checker = finalization_checker.FinalizationChecker( self.liability_abi, web3_http_provider=web3_http_provider, ens_contract=ens_contract) self.finalized = rospy.Publisher('finalized', String, queue_size=10) self.result_handler() def create_liability_filter(self): try: factory_abi = json.loads(rospy.get_param('~factory_contract_abi')) factory_address = self.ens.address( rospy.get_param('~factory_contract')) factory = self.web3ws.eth.contract(factory_address, abi=factory_abi) self.liability_filter = factory.eventFilter('NewLiability') except Exception as e: rospy.logwarn( "Failed to create liability filter with exception: \"%s\"", e) def result_handler(self): result = rospy.Publisher('infochan/eth/signing/result', Result, queue_size=10) def liability_finalize(msg): is_finalized = False while is_finalized is not True: result.publish(msg) time.sleep(30) # TODO: move sleep time to rop parameter with 30 seconds by default is_finalized = self.liability_finalization_checker.finalized( msg.liability) self.finalized.publish(msg.liability) rospy.Subscriber('result', Result, liability_finalize) def liability_read(self, address): ''' Read liability from blockchain to message. ''' c = self.web3.eth.contract(address, abi=self.liability_abi) msg = Liability() model_mh = Multihash() model_mh.multihash = multihash.decode( c.call().model()).encode('base58').decode() objective_mh = Multihash() objective_mh.multihash = multihash.decode( c.call().objective()).encode('base58').decode() msg.address = address msg.model = model_mh msg.objective = objective_mh msg.promisee = c.call().promisee() msg.promisor = c.call().promisor() msg.lighthouse = c.call().lighthouse() msg.token = c.call().token() msg.cost = c.call().cost() msg.validator = c.call().validator() msg.validatorFee = c.call().validatorFee() rospy.logdebug('New liability readed: %s', msg) return msg def spin(self): ''' Waiting for the new liabilities. ''' def liability_filter_thread(): try: # TODO: improve error logging for entry in self.liability_filter.get_new_entries(): self.liability.publish( self.liability_read(entry['args']['liability'])) except Exception as e: rospy.logerr('listener liability filter exception: %s', e) self.create_liability_filter() Timer(self.poll_interval, liability_filter_thread).start() liability_filter_thread() rospy.spin()
class TestExecutor(unittest.TestCase): def __init__(self, *args): rospy.init_node(NAME) super(TestExecutor, self).__init__(*args) ipfs_provider = urlparse( rospy.get_param('~ipfs_http_provider')).netloc.split(':') self.ipfs = ipfsapi.connect(ipfs_provider[0], int(ipfs_provider[1])) self.test_token = rospy.get_param('~test_token') self.test_bid_publisher = rospy.Publisher( '/liability/test_executor/o/eth/signing/offer', Offer, queue_size=10) self.test_ask_publisher = rospy.Publisher( '/liability/test_executor/d/eth/signing/demand', Demand, queue_size=10) web3_http_provider = rospy.get_param('~web3_http_provider') http_provider = HTTPProvider(web3_http_provider) ens_contract = rospy.get_param('~ens_contract', None) self.ens = ENS(http_provider, addr=ens_contract) self.web3 = Web3(http_provider, ens=self.ens) from web3.middleware import geth_poa_middleware # inject the poa compatibility middleware to the innermost layer self.web3.middleware_stack.inject(geth_poa_middleware, layer=0) self.ens.web3.middleware_stack.inject(geth_poa_middleware, layer=0) self.lighthouse_address = self.ens.address( rospy.get_param('~lighthouse_contract')) self.test_start_time = time.time() self.success = False self.ready_liability = None self.test_objective = self.create_test_objective() rospy.logwarn("TEST EXECUTOR: CURRENT OBJECTIVE is %s", self.test_objective) def create_test_objective(self): with TemporaryDirectory() as tmpdir: os.chdir(tmpdir) test_objective_bag = rosbag.Bag('output.bag', 'w') email_data = String(data='test@mail') droneid_data = String(data='test_drone_000') test_objective_bag.write('/agent/objective/droneid', droneid_data, rospy.Time().now()) test_objective_bag.write('/agent/objective/email', email_data, rospy.Time().now()) test_objective_bag.close() ipfs_objective = self.ipfs.add(test_objective_bag.filename) rospy.logwarn("TEST_EXECUTOR: ADD TEST OBJECTIVE TO IPFS is %s", ipfs_objective) return ipfs_objective['Hash'] def ready_liability_handler(self, msg): self.ready_liability = msg rospy.logwarn("EXECUTOR: READY LIABILITY address is %s", self.ready_liability.address.address) def result_handler(self, msg): rospy.logwarn("EXECUTOR: liability: %s result %s", msg.liability, msg.result) if self.ready_liability is not None \ and self.ready_liability.address.address == msg.liability.address \ and self.check_rosbag_is_new_and_has_messages(msg): self.success = True def check_rosbag_is_new_and_has_messages(self, msg): with TemporaryDirectory() as tmpdir: os.chdir(tmpdir) self.ipfs.get(msg.result.multihash) bag = rosbag.Bag(msg.result.multihash, 'r') bag_topics = bag.get_type_and_topic_info() bag_topics_dict = {} for topic, topic_info in bag_topics[1].items(): bag_topics_dict[topic] = topic_info[1] rospy.loginfo( "rosbag contains %s messages of type %s in topic %s", topic_info[1], topic_info[0], topic) rospy.loginfo("ROSBAG: result has %s msgs", bag.get_message_count()) rospy.loginfo("ROSBAG: result has start time %s", bag.get_start_time()) return bag.get_message_count() == 2 and \ bag.get_start_time() > self.test_start_time and \ '/liability/eth_{0}/agent/objective/droneid'.format(self.ready_liability.address.address) in bag_topics_dict and \ '/liability/eth_{0}/agent/objective/email'.format(self.ready_liability.address.address) in bag_topics_dict def test_executor(self): rospy.Subscriber('liability/ready', Liability, self.ready_liability_handler) rospy.Subscriber('liability/result', Result, self.result_handler) time.sleep(15) rospy.logwarn("test_executor: publish test offer") self.test_bid_publisher.publish(self.get_test_bid()) rospy.logwarn("test_executor: publish test demand") self.test_ask_publisher.publish(self.get_test_ask()) while self.ready_liability is None: time.sleep(0.1) start_service_proxy = rospy.ServiceProxy('/liability/start', StartLiability) start_service_proxy(self.ready_liability.address.address) time.sleep(5) finish_service_proxy = rospy.ServiceProxy('/liability/finish', FinishLiability) finish_service_proxy(self.ready_liability.address.address, True) while not rospy.is_shutdown() and not self.success: time.sleep(0.1) self.assert_(self.success) def get_test_bid(self): bidDict = { "model": "QmaRmbJtyfMDBfkDETTPAxKUUcSqZKXWwFKKoZ318nrPku", "objective": self.test_objective, "token": self.test_token, "cost": 0, "validator": '0x0000000000000000000000000000000000000000', "lighthouse": self.lighthouse_address, "lighthouseFee": 0, "deadline": 9999999, "sender": "", "signature": "" } return messageValidator.dict2bid(bidDict) def get_test_ask(self): askDict = { "model": "QmaRmbJtyfMDBfkDETTPAxKUUcSqZKXWwFKKoZ318nrPku", "objective": self.test_objective, "token": self.test_token, "cost": "0", "lighthouse": self.lighthouse_address, "validator": "0x0000000000000000000000000000000000000000", "validatorFee": 0, "deadline": 9999999, "sender": "", "signature": "" } return messageValidator.dict2ask(askDict)
class TestExecutor(unittest.TestCase): def __init__(self, *args): rospy.init_node(NAME) super(TestExecutor, self).__init__(*args) ipfs_provider = urlparse( rospy.get_param('~ipfs_http_provider')).netloc.split(':') self.ipfs = ipfsapi.connect(ipfs_provider[0], int(ipfs_provider[1])) self.test_token = rospy.get_param('~test_token') self.test_bid_publisher = rospy.Publisher( '/liability/infochan/eth/signing/offer', Offer, queue_size=10) self.test_ask_publisher = rospy.Publisher( '/liability/infochan/eth/signing/demand', Demand, queue_size=10) web3_http_provider = rospy.get_param('~web3_http_provider') http_provider = HTTPProvider(web3_http_provider) ens_contract = rospy.get_param('~ens_contract', None) self.ens = ENS(http_provider, addr=ens_contract) self.web3 = Web3(http_provider, ens=self.ens) from web3.middleware import geth_poa_middleware # inject the poa compatibility middleware to the innermost layer self.web3.middleware_stack.inject(geth_poa_middleware, layer=0) self.ens.web3.middleware_stack.inject(geth_poa_middleware, layer=0) self.lighthouse_address = self.ens.address( rospy.get_param('~lighthouse_contract')) self.test_start_time = time.time() self.success = False self.ready_liability = None def ready_liability_handler(self, msg): self.ready_liability = msg rospy.loginfo("READY LIABILITY HANDLER: address is %s", self.ready_liability.address) def result_handler(self, result): rospy.loginfo("RESULT HANDLER: liability: %s result %s", result.liability, result.result) if self.ready_liability is not None \ and self.ready_liability.address == result.liability \ and self.check_rosbag_is_new_and_has_messages(result): self.success = True def check_rosbag_is_new_and_has_messages(self, result): with TemporaryDirectory() as tmpdir: os.chdir(tmpdir) self.ipfs.get(result.result.multihash) bag = rosbag.Bag(result.result.multihash, 'r') bag_topics = bag.get_type_and_topic_info() bag_topics_dict = {} for topic, topic_info in bag_topics[1].items(): bag_topics_dict[topic] = topic_info[1] rospy.loginfo( "rosbag contains %s messages of type %s in topic %s", topic_info[1], topic_info[0], topic) rospy.loginfo("ROSBAG: result has %s msgs", bag.get_message_count()) rospy.loginfo("ROSBAG: result has start time %s", bag.get_start_time()) return bag.get_message_count() == 2 and \ bag.get_start_time() > self.test_start_time and \ '/liability/eth_{0}/agent/objective/droneid'.format(self.ready_liability.address) in bag_topics_dict and \ '/liability/eth_{0}/agent/objective/email'.format(self.ready_liability.address) in bag_topics_dict def test_executor(self): rospy.Subscriber('liability/ready', Liability, self.ready_liability_handler) rospy.Subscriber('liability/result', Result, self.result_handler) time.sleep(15) rospy.logwarn("test_executor: publish test offer") self.test_bid_publisher.publish(self.get_test_bid()) rospy.logwarn("test_executor: publish test demand") self.test_ask_publisher.publish(self.get_test_ask()) while self.ready_liability is None: time.sleep(0.1) start_service_proxy = rospy.ServiceProxy('/liability/start', StartLiability) start_service_proxy(self.ready_liability.address) time.sleep(5) finish_service_proxy = rospy.ServiceProxy('/liability/finish', FinishLiability) finish_service_proxy(self.ready_liability.address, True) timeout_t = time.time() + 30.0 while not rospy.is_shutdown( ) and not self.success and time.time() < timeout_t: time.sleep(0.1) self.assert_(self.success) def get_test_bid(self): bidDict = { "model": "QmaRmbJtyfMDBfkDETTPAxKUUcSqZKXWwFKKoZ318nrPku", "objective": "Qmb3H3tHZ1QutcrLq7WEtQWbEWjA11aPqVmeatMSrmFXvE", "token": self.test_token, "cost": 0, "validator": '0x0000000000000000000000000000000000000000', "lighthouse": self.lighthouse_address, "lighthouseFee": 0, "deadline": 9999999 } bid = Offer() model_mh = Multihash() model_mh.multihash = bidDict['model'] objective_mh = Multihash() objective_mh.multihash = bidDict['objective'] bid.model = model_mh bid.objective = objective_mh bid.token = bidDict['token'] bid.cost = bidDict['cost'] bid.validator = bidDict['validator'] bid.lighthouse = bidDict['lighthouse'] bid.lighthouseFee = bidDict['lighthouseFee'] bid.deadline = bidDict['deadline'] return bid def get_test_ask(self): askDict = { "model": "QmaRmbJtyfMDBfkDETTPAxKUUcSqZKXWwFKKoZ318nrPku", "objective": "Qmb3H3tHZ1QutcrLq7WEtQWbEWjA11aPqVmeatMSrmFXvE", "token": self.test_token, "cost": 0, "lighthouse": self.lighthouse_address, "validator": "0x0000000000000000000000000000000000000000", "validatorFee": 0, "deadline": 9999999 } ask = Demand() model_mh = Multihash() model_mh.multihash = askDict['model'] objective_mh = Multihash() objective_mh.multihash = askDict['objective'] ask.model = model_mh ask.objective = objective_mh ask.token = askDict['token'] ask.cost = askDict['cost'] ask.lighthouse = askDict['lighthouse'] ask.validator = askDict['validator'] ask.validatorFee = askDict['validatorFee'] ask.deadline = askDict['deadline'] return ask
class Signer: def __init__(self): ''' Lighthouse signer initialisation. ''' rospy.init_node('robonomics_signer') ens_contract = rospy.get_param('~ens_contract', None) web3_http_provider = rospy.get_param('~web3_http_provider') http_provider = HTTPProvider(web3_http_provider) self.ens = ENS(http_provider, addr=ens_contract) self.web3 = Web3(http_provider, ens=self.ens) __factory_contract_abi = rospy.get_param('~factory_contract_abi') __factory_contract = rospy.get_param('~factory_contract') self.factory = None __keyfile = rospy.get_param('~keyfile') __keyfile_password_file = rospy.get_param('~keyfile_password_file') __keyfile_helper = eth_keyfile_helper.KeyfileHelper(__keyfile, keyfile_password_file=__keyfile_password_file) self.__account = __keyfile_helper.get_local_account_from_keyfile() self.signed_demand = rospy.Publisher('sending/demand', Demand, queue_size=10) self.signed_offer = rospy.Publisher('sending/offer', Offer, queue_size=10) self.signed_result = rospy.Publisher('sending/result', Result, queue_size=10) self.__factory_initialization_lock = Lock() def get_initialized_factory(): if self.factory is None: try: factory_abi = json.loads(__factory_contract_abi) factory_address = self.ens.address(__factory_contract) try: self.__factory_initialization_lock.acquire() if self.factory is None: self.factory = self.web3.eth.contract(factory_address, abi=factory_abi) finally: self.__factory_initialization_lock.release() return self.factory except StaleBlockchain as e: rospy.logwarn("Failed to initialize factory cause exception: %s", e) else: return self.factory def get_nonce_by_address(address): try: nonce = get_initialized_factory().call().nonceOf(address.address) return UInt256(nonce) except Exception as e: rospy.logerr("Failed to get nonce by address %s with exception: %s", address.address, e) try: self.__factory_initialization_lock.acquire() self.factory = None finally: self.__factory_initialization_lock.release() def sign_demand(msg): msg.sender = Address(self.__account.address) current_nonce = get_nonce_by_address(msg.sender) message_hash = robonomicsMessageUtils.demand_hash(msg, current_nonce) signed_hash = self.__account.signHash(defunct_hash_message(message_hash)) msg.signature = signed_hash.signature rospy.loginfo('askhash: %s signature: %s', binascii.hexlify(message_hash), binascii.hexlify(msg.signature)) self.signed_demand.publish(msg) rospy.Subscriber('signing/demand', Demand, sign_demand) def sign_offer(msg): msg.sender = Address(self.__account.address) current_nonce = get_nonce_by_address(msg.sender) message_hash = robonomicsMessageUtils.offer_hash(msg, current_nonce) signed_hash = self.__account.signHash(defunct_hash_message(message_hash)) msg.signature = signed_hash.signature rospy.loginfo('bidhash: %s signature: %s', binascii.hexlify(message_hash), binascii.hexlify(msg.signature)) self.signed_offer.publish(msg) rospy.Subscriber('signing/offer', Offer, sign_offer) def sign_result(msg): message_hash = robonomicsMessageUtils.result_hash(msg) signed_hash = self.__account.signHash(defunct_hash_message(message_hash)) msg.signature = signed_hash.signature rospy.loginfo('reshash: %s signature: %s', binascii.hexlify(message_hash), binascii.hexlify(msg.signature)) self.signed_result.publish(msg) rospy.Subscriber('signing/result', Result, sign_result) def spin(self): ''' Waiting for the new messages. ''' rospy.spin()
def validate_name_has_address(ens: ENS, name: str) -> ChecksumAddress: addr = ens.address(name) if addr: return addr else: raise NameNotFound("Could not find address for name %r" % name)
class Listener: def __init__(self): ''' Robonomics liability tracking node initialisation. ''' rospy.init_node('robonomics_liability_listener') http_provider = HTTPProvider(rospy.get_param('~web3_http_provider')) self.ens = ENS(http_provider, addr=rospy.get_param('~ens_contract', None)) self.web3 = Web3(http_provider, ens=self.ens) from web3.middleware import geth_poa_middleware # inject the poa compatibility middleware to the innermost layer self.web3.middleware_stack.inject(geth_poa_middleware, layer=0) self.ens.web3.middleware_stack.inject(geth_poa_middleware, layer=0) self.poll_interval = rospy.get_param('~poll_interval', 5) self.liability = rospy.Publisher('incoming', Liability, queue_size=10) factory_abi = json.loads(rospy.get_param('~factory_contract_abi')) factory_address = self.ens.address(rospy.get_param('~factory_contract')) self.factory = self.web3.eth.contract(factory_address, abi=factory_abi) self.liability_abi = json.loads(rospy.get_param('~liability_contract_abi')) self.result_handler() def result_handler(self): result = rospy.Publisher('infochan/signing/result', Result, queue_size=10) def liability_finalize(msg): c = self.web3.eth.contract(msg.liability, abi=self.liability_abi) def try_again(): if not c.call().isFinalized(): result.publish(msg) Timer(30, try_again).start() try_again() rospy.Subscriber('result', Result, liability_finalize) def liability_read(self, address): ''' Read liability from blockchain to message. ''' c = self.web3.eth.contract(address, abi=self.liability_abi) msg = Liability() msg.address = address msg.model = b58encode(c.call().model()) msg.objective = b58encode(c.call().objective()) msg.promisee = c.call().promisee() msg.promisor = c.call().promisor() msg.token = c.call().token() msg.cost = c.call().cost() msg.validator = c.call().validator() msg.validatorFee = c.call().validatorFee() rospy.logdebug('New liability readed: %s', msg) return msg def spin(self): ''' Waiting for the new liabilities. ''' liability_filter = self.factory.eventFilter('NewLiability') def liability_filter_thread(): for entry in liability_filter.get_new_entries(): self.liability.publish(self.liability_read(entry['args']['liability'])) Timer(self.poll_interval, liability_filter_thread).start() liability_filter_thread() rospy.spin()