def run(): server_address = get_server_address() print("Connecting to cartesi-machine-server at " + server_address) with grpc.insecure_channel(server_address) as channel: stub = cartesi_machine_pb2_grpc.MachineStub(channel) content = bytes("Hello World!", "iso8859-1") mem_address = TEST_DRIVES[0][START] try: request(stub, "Machine", make_new_machine_request()) request(stub, "GetRootHash", cartesi_machine_pb2.Void()) request(stub, "Run", cartesi_machine_pb2.RunRequest(limit=500000000)) request(stub, "Step", cartesi_machine_pb2.Void()) request( stub, "ReadMemory", cartesi_machine_pb2.ReadMemoryRequest(address=mem_address, length=len(content))) request( stub, "WriteMemory", cartesi_machine_pb2.WriteMemoryRequest(address=mem_address, data=content)) request( stub, "GetProof", cartesi_machine_pb2.GetProofRequest(address=mem_address, log2_size=3)) request(stub, "Shutdown", cartesi_machine_pb2.Void()) except Exception as e: print("An exception occurred:") print(e) print(type(e))
def CommunicateAddress(self, request, context): try: address = request.address session_id = request.session_id LOGGER.info( "Received a CommunicateAddress request for session_id {} and address {}" .format(session_id, address)) self.session_registry_manager.register_address_for_session( session_id, address) #Returning return cartesi_machine_pb2.Void() #No session with provided id except SessionIdException as e: LOGGER.error(e) context.set_details("{}".format(e)) context.set_code(grpc.StatusCode.INVALID_ARGUMENT) #Generic error catch except Exception as e: LOGGER.error("An exception occurred: {}\nTraceback: {}".format( e, traceback.format_exc())) context.set_details( 'An exception with message "{}" was raised!'.format(e)) context.set_code(grpc.StatusCode.UNKNOWN)
def wait_for_server_availability(session_id, address): LOGGER.debug( "Connecting to cartesi machine server from session '{}' in address '{}'" .format(session_id, address)) with grpc.insecure_channel(address) as channel: retry = 0 while retry < MAX_CONNECTION_ATTEMPTS: try: stub = cartesi_machine_pb2_grpc.MachineStub(channel) response = stub.GetVersion(cartesi_machine_pb2.Void()) LOGGER.debug( "Cartesi machine server version for session_id '{}' is '{}'" .format(session_id, response)) break except Exception: LOGGER.warning( "Cartesi machine server for session_id '{}' is not yet ready" .format(session_id)) retry += 1 time.sleep(SLEEP_TIME) if retry == MAX_CONNECTION_ATTEMPTS: err_msg = "Cartesi machine server for session_id '{}' reached max connection attempts {}".format( session_id, MAX_CONNECTION_ATTEMPTS) LOGGER.error(err_msg) raise CartesiMachineServerException(err_msg)
def rollback_machine(session_id, address): LOGGER.debug( "Connecting to cartesi machine server from session '{}' in address '{}'" .format(session_id, address)) with grpc.insecure_channel(address) as channel: stub = cartesi_machine_pb2_grpc.MachineStub(channel) stub.Rollback(cartesi_machine_pb2.Void()) LOGGER.debug("Cartesi machine rolledback for session_id '{}'".format( session_id))
def create_machine_snapshot(session_id, address): LOGGER.debug( "Connecting to cartesi machine server from session '{}' in address '{}'" .format(session_id, address)) with grpc.insecure_channel(address) as channel: stub = cartesi_machine_pb2_grpc.MachineStub(channel) stub.Snapshot(cartesi_machine_pb2.Void()) LOGGER.debug( "Cartesi machine snapshot created for session_id '{}'".format( session_id))
def shutdown_cartesi_machine_server(session_id, address): LOGGER.debug( "Connecting to cartesi machine server from session '{}' in address '{}'" .format(session_id, address)) with grpc.insecure_channel(address) as channel: stub = cartesi_machine_pb2_grpc.MachineStub(channel) response = stub.Shutdown(cartesi_machine_pb2.Void()) LOGGER.debug( "Cartesi machine server shutdown for session_id '{}'".format( session_id))
def get_machine_hash(session_id, address): LOGGER.debug( "Connecting to cartesi machine server from session '{}' in address '{}'" .format(session_id, address)) with grpc.insecure_channel(address) as channel: stub = cartesi_machine_pb2_grpc.MachineStub(channel) LOGGER.debug( "Asking for cartesi machine root hash for session_id '{}'".format( session_id)) response = stub.GetRootHash(cartesi_machine_pb2.Void()) LOGGER.debug( "Cartesi machine root hash retrieved for session_id '{}'".format( session_id)) return response.hash
def run_machine(session_id, session_context, desired_cycle): ''' This function must be called only when the lock for the given session is held by the caller ''' current_cycle = session_context.cycle LOGGER.debug("Current cycle: {}\nDesired cycle: {}".format( current_cycle, desired_cycle)) if (desired_cycle < current_cycle): raise ValueError( "The given desired_cycle must not be smaller than the current_cycle" ) response = None LOGGER.debug( "Connecting to cartesi machine server from session '{}' in address '{}'" .format(session_id, session_context.address)) with grpc.insecure_channel(session_context.address) as channel: stub = cartesi_machine_pb2_grpc.MachineStub(channel) #Setting cycle for run batch target_cycle = session_context.cycle + RUN_CYCLES_BATCH_SIZE #If it`s beyond the desired cycle, truncate if (target_cycle > desired_cycle): target_cycle = desired_cycle #Run loop while (True): #Run LOGGER.debug( "Running cartesi machine for session id {} with target cycle of {}, current cycle is {}" .format(session_id, target_cycle, session_context.cycle)) response = stub.Run( cartesi_machine_pb2.RunRequest(limit=target_cycle)) #Update tracked cycle and updated_at timestamp in the session context session_context.cycle = response.mcycle session_context.updated_at = time.time() LOGGER.debug("Updated cycle of session '{}' to {}".format( session_id, response.mcycle)) #Checking if machine halted if response.iflags_h: #Storing the halting cycle in session context to use in progress calculations session_context.halt_cycle = session_context.cycle LOGGER.debug("Session {} halted with payload {}".format( session_id, int.from_bytes(response.tohost.to_bytes(8, 'big')[2:], byteorder='big'))) break #Checking if the machine yielded elif response.iflags_y: #Parsing tohost to see if a progress command was given #The command is the second byte in the tohost 8bytes register cmd = response.tohost.to_bytes(8, 'big')[1] payload = int.from_bytes(response.tohost.to_bytes(8, 'big')[2:], byteorder='big') if (cmd == 0): #It was a progress command, storing the progress session_context.app_progress = payload LOGGER.debug("New progress for session {}: {}".format( session_id, payload)) #Reset IflagsY to resume stub.ResetIflagsY(cartesi_machine_pb2.Void()) else: #Wasn't a progress command, just logging LOGGER.debug( "Session {} yielded with command {} and payload {}". format(session_id, cmd, payload)) else: #The machine reached the target_cycle, setting next one if it wasn't the desired cycle if target_cycle == desired_cycle: #It was, break the loop break #It wasn't, set the next target cycle target_cycle += RUN_CYCLES_BATCH_SIZE #If it`s beyond the desired cycle, truncate if (target_cycle > desired_cycle): target_cycle = desired_cycle LOGGER.debug( "Cartesi machine ran for session_id '{}' and desired final cycle of {}, current cycle is {}" .format(session_id, desired_cycle, session_context.cycle)) return response