def _get_channel_state_from_server(self, grpc_channel, channel_id): # We should simply statically import everything, but it doesn't work because of the following issue in protobuf: https://github.com/protocolbuffers/protobuf/issues/1491 #from snet_cli.resources.proto.state_service_pb2 import ChannelStateRequest as request_class #from snet_cli.resources.proto.state_service_pb2_grpc import PaymentChannelStateServiceStub as stub_class proto_dir = RESOURCES_PATH.joinpath("proto") stub_class, request_class, _ = import_protobuf_from_dir(proto_dir, "GetChannelState") current_block = self.ident.w3.eth.blockNumber mpe_address = self.get_mpe_address() message = self.w3.soliditySha3( ["string", "address", "uint256", "uint256"], ["__get_channel_state", mpe_address, channel_id, current_block]) signature = self.ident.sign_message_after_soliditySha3(message) request = request_class(channel_id = self.w3.toBytes(channel_id), signature = bytes(signature), current_block = current_block) stub = stub_class(grpc_channel) response = getattr(stub, "GetChannelState")(request) # convert bytes to int state = dict() state["current_nonce"] = int.from_bytes(response.current_nonce, byteorder='big') state["current_signed_amount"] = int.from_bytes(response.current_signed_amount, byteorder='big') error_message = "Error in _get_channel_state_from_server. My own signature from the server is not valid." self._assert_validity_of_my_signature_or_zero_amount(bytes(response.current_signature), channel_id, state["current_nonce"], state["current_signed_amount"], error_message) if (hasattr(response, "old_nonce_signed_amount")): state["old_nonce_signed_amount"] = int.from_bytes(response.old_nonce_signed_amount, byteorder='big') self._assert_validity_of_my_signature_or_zero_amount(bytes(response.old_nonce_signature), channel_id, state["current_nonce"] - 1, state["old_nonce_signed_amount"], error_message) return state
def _generate_payment_channel_state_service_client(self): grpc_channel = self._base_grpc_channel with add_to_path(str(RESOURCES_PATH.joinpath("proto"))): state_service_pb2_grpc = importlib.import_module( "state_service_pb2_grpc") return state_service_pb2_grpc.PaymentChannelStateServiceStub( grpc_channel)
def _get_channel_state_from_server(self, grpc_channel, channel_id): proto_dir = RESOURCES_PATH.joinpath("proto") # make PaymentChannelStateService.GetChannelState call to the daemon stub_class, request_class, _ = import_protobuf_from_dir( proto_dir, "GetChannelState") message = self.w3.soliditySha3(["uint256"], [channel_id]) signature = self.ident.sign_message_after_soliditySha3(message) request = request_class(channel_id=self.w3.toBytes(channel_id), signature=bytes(signature)) stub = stub_class(grpc_channel) response = getattr(stub, "GetChannelState")(request) # convert bytes to int state = dict() state["current_nonce"] = int.from_bytes(response.current_nonce, byteorder='big') state["current_signed_amount"] = int.from_bytes( response.current_signed_amount, byteorder='big') if (state["current_signed_amount"] > 0): good = self._verify_my_signature(bytes(response.current_signature), self.get_mpe_address(), channel_id, state["current_nonce"], state["current_signed_amount"]) if (not good): raise Exception( "Error in _get_channel_state_from_server. My own signature from the server is not valid." ) return state
def _get_current_channel_state(self): stub = self.payment_channel_state_service_client current_block_number = self.web3.eth.getBlock("latest").number message = web3.Web3.soliditySha3(["string","address","uint256","uint256"], ["__get_channel_state",web3.Web3.toChecksumAddress(self.mpe_contract.contract.address),self.channel_id,current_block_number]) signature = self.web3.eth.account.signHash(defunct_hash_message(message), self.account.signer_private_key).signature with add_to_path(str(RESOURCES_PATH.joinpath("proto"))): state_service_pb2 = importlib.import_module("state_service_pb2") request = state_service_pb2.ChannelStateRequest(channel_id=web3.Web3.toBytes(self.channel_id), signature=bytes(signature),current_block=current_block_number) response = stub.GetChannelState(request) return int.from_bytes(response.current_nonce, byteorder="big"), int.from_bytes(response.current_signed_amount, byteorder="big")
def _get_stub_and_request_classes(self, service_name): """ import protobuf and return stub and request class """ # Compile protobuf if needed codegen_dir = Path.home().joinpath(".snet", "mpe_client", "control_service") proto_dir = RESOURCES_PATH.joinpath("proto") if (not codegen_dir.joinpath("control_service_pb2.py").is_file()): compile_proto(proto_dir, codegen_dir, proto_file="control_service.proto") stub_class, request_class, _ = import_protobuf_from_dir( codegen_dir, service_name) return stub_class, request_class
def add_contract_options(parser): parser.set_defaults(cmd=ContractCommand) subparsers = parser.add_subparsers(title="contracts", metavar="CONTRACT") subparsers.required = True for path in Path(RESOURCES_PATH.joinpath("contracts", "abi")).glob("*json"): contract_name = re.search(r"([^.]*)\.json", os.path.basename(path)).group(1) contract_p = subparsers.add_parser( contract_name, help="{} contract".format(contract_name)) add_contract_function_options(contract_p, contract_name)
def is_free_call_available(self, email, token_for_free_call, token_expiry_date_block, signature, current_block_number, daemon_endpoint): try: with add_to_path(str(RESOURCES_PATH.joinpath("proto"))): state_service_pb2 = importlib.import_module("state_service_pb2") with add_to_path(str(RESOURCES_PATH.joinpath("proto"))): state_service_pb2_grpc = importlib.import_module("state_service_pb2_grpc") request = state_service_pb2.FreeCallStateRequest() request.user_id = email request.token_for_free_call = token_for_free_call request.token_expiry_date_block = token_expiry_date_block request.signature = signature request.current_block = current_block_number endpoint_object = urlparse(daemon_endpoint) if endpoint_object.port is not None: channel_endpoint = endpoint_object.hostname + ":" + str(endpoint_object.port) else: channel_endpoint = endpoint_object.hostname if endpoint_object.scheme == "http": channel = grpc.insecure_channel(channel_endpoint) elif endpoint_object.scheme == "https": channel = grpc.secure_channel(channel_endpoint, grpc.ssl_channel_credentials()) else: raise ValueError('Unsupported scheme in service metadata ("{}")'.format(endpoint_object.scheme)) stub = state_service_pb2_grpc.FreeCallStateServiceStub(channel) response = stub.GetFreeCallsAvailable(request) if response.free_calls_available > 0: return True return False except Exception as e: return False
def _get_current_channel_state(self): stub = self.payment_channel_state_service_client message = web3.Web3.soliditySha3(["uint256"], [self.channel_id]) signature = self.web3.eth.account.signHash( defunct_hash_message(message), self.account.signer_private_key).signature with add_to_path(str(RESOURCES_PATH.joinpath("proto"))): state_service_pb2 = importlib.import_module("state_service_pb2") request = state_service_pb2.ChannelStateRequest( channel_id=web3.Web3.toBytes(self.channel_id), signature=bytes(signature)) response = stub.GetChannelState(request) return int.from_bytes(response.current_nonce, byteorder="big"), int.from_bytes( response.current_signed_amount, byteorder="big")