示例#1
0
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)
示例#3
0
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)
示例#4
0
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))
示例#5
0
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))
示例#6
0
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))
示例#7
0
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
示例#8
0
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