spiral_wasm¶

In [ ]:
open rust.rust_operators
open rust
open sm'_operators

spiral_wasm¶

get_args¶

In [ ]:
inl get_args () =
    {
        exception = "exception", 'e'
        trace_level = "trace_level", 't'
        wasm = "wasm", 'w'
    }

get_command¶

In [ ]:
let get_command () =
    ##"command"
    |> runtime.new_command
    |> runtime.command_args_override_self true
    |> runtime.command_init_arg (get_args () .exception) (
        runtime.arg_num_args_range (
            runtime.new_value_range
                true
                (am'.End eval)
                (am'.End fun _ => (1i32 |> convert : unativeint))
        )
        >> runtime.arg_require_equals true
        >> runtime.arg_default_missing_value ""
    )
    |> runtime.command_init_arg (get_args () .trace_level) (
        real runtime.arg_union `trace_level ignore
    )
    |> runtime.command_init_arg (get_args () .wasm) (
        runtime.arg_required true
    )

run¶

In [ ]:
let rec run
    (matches : runtime.arg_matches)
    : async.future_pin (
        resultm.result'
            u8
            resultm.anyhow_error
    )
    =
    fun () =>
        inl wasm_path =
            matches
            |> runtime.matches_get_one (get_args () .wasm |> fst)
            |> optionm'.unbox
            |> optionm.value
            |> sm'.from_std_string

        trace Verbose (fun () => "spiral_wasm.run") fun () => { wasm_path }

        inl wasm = wasm_path |> file_system.read |> resultm.try'

        let fn (retry : u8) =
            fun () =>
                inl worker = near_workspaces.sandbox_worker () |> resultm.try'
                inl contract = worker |> near_workspaces.dev_deploy wasm |> async.await |> resultm.try'

                trace Verbose (fun () => "spiral_wasm.run") fun () => { retry worker contract }

                inl result =
                    contract
                    |> near_workspaces.call "state_main"
                    |> near_workspaces.gas (near_workspaces.from_tgas 300)
                    |> near_workspaces.transact
                    |> async.await
                    |> resultm.try'

                trace Verbose (fun () => "spiral_wasm.run") fun () => { retry result }

                result
                |> near_workspaces.logs
                |> am'.vec_map sm'.ref_to_std_string
                |> am'.vec_for_each console.write_line

                trace_raw Info (fun () => " ")
                result |> near_workspaces.print_usd retry

                inl result2 = result |> near_workspaces.into_result

                trace Verbose (fun () => "spiral_wasm.run") fun () => { result2 }

                inl receipt_failures = result |> near_workspaces.receipt_failures
                inl receipt_failures_len = receipt_failures |> am'.vec_len |> i32

                trace Verbose
                    fun () => "spiral_wasm.run"
                    fun () => { receipt_failures_len receipt_failures }

                inl receipt_outcomes = result |> near_workspaces.receipt_outcomes
                inl receipt_outcomes_len = receipt_outcomes |> am'.vec_len |> i32

                trace Verbose
                    fun () => "spiral_wasm.run"
                    fun () => { receipt_outcomes_len receipt_outcomes }

                inl json = result |> near_workspaces.json

                trace Verbose (fun () => "spiral_wasm.run") fun () => { json }

                inl borsh = result |> near_workspaces.borsh

                trace Verbose (fun () => "spiral_wasm.run") fun () => { borsh }

                inl error = { receipt_outcomes_len retry receipt_failures } |> sm'.format
                if receipt_failures_len > 0
                then (Ok (Some error) : _ _ resultm.anyhow_error) |> resultm.box
                elif receipt_outcomes_len > 1
                then (Ok None : _ _ resultm.anyhow_error) |> resultm.box
                else error |> resultm.anyhow_error |> resultm.err
            |> async.new_future_move

        let rec 루프 (retry : u8) =
            inl max = 15
            inl init (error : _ string) =
                fun () =>
                    { retry error }
                |> async.new_future_move
            fun () =>
                inl result =
                    fn retry
                    |> async.await
                    |> resultm.map_error' sm'.format'
                    |> resultm.unbox
                match result with
                | Ok (None) =>
                    init None
                    |> async.await
                    |> Ok
                | Ok (Some error) =>
                    trace Critical (fun () => "spiral_wasm.run / Ok (Some error)") fun () => { retry error }
                    init (Some error)
                    |> async.await
                    |> Error
                | Error error when retry >= max =>
                    trace Warning (fun () => "spiral_wasm.run / Error error") fun () => { retry error }
                    trace_raw Warning (fun () => "\n")
                    init None
                    |> async.await
                    |> Ok
                | Error error =>
                    trace Warning (fun () => "spiral_wasm.run / Error error") fun () => { retry error }
                    trace_raw Warning (fun () => "\n")
                    루프 (retry + 1) |> async.await
            |> async.new_future_move
        inl retries = 루프 1 |> async.await

        trace Verbose (fun () => "spiral_wasm.run") fun () => { retries }

        match retries with
        | Ok { retry } => Ok retry |> resultm.box
        | Error { retry error } => { retries error } |> sm'.format |> resultm.anyhow_error |> resultm.err

    |> async.new_future_move

main¶

In [ ]:
///! _

inl main (args : array_base string) =
    inl command = get_command ()
    inl arg_matches = command |> runtime.command_get_matches

    inl trace_level =
        arg_matches
        |> runtime.matches_get_one (get_args () .trace_level |> fst)
        |> optionm'.unbox
        |> optionm.map (
            sm'.from_std_string
            >> reflection.union_try_pick
        )
        |> optionm'.flatten
        |> optionm'.default_value Verbose

    inl trace_state = get_trace_state_or_init (Some trace_level)

    trace Verbose
        fun () => "spiral_wasm.main"
        fun () => { args }

    inl exception =
        arg_matches
        |> runtime.matches_get_one (get_args () .exception |> fst)
        |> optionm'.map (sm'.from_std_string >> sm'.trim_start [ '\\' ] >> sm'.trim_end [ '\\' ])
        |> optionm'.unbox

    inl result =
        arg_matches
        |> run
        |> async.block_on_tokio
        |> resultm.map_error' sm'.format'

    match result |> resultm.unbox, exception with
    | Ok retries, Some exception =>
        ($'$"spiral_wasm.main / retries: {!retries} / exception: \'{!exception}\'"' : string)
        |> resultm.err |> resultm.unwrap'
    | Error _error, Some ("") =>
        ()
    | Error error, Some exception when error |> sm'.from_std_string |> sm'.contains exception =>
        ()
    | Error error, Some exception =>
        ($'$"spiral_wasm.main / exception: \'{!exception}\' / error: {!error}"' : string)
        |> resultm.err |> resultm.unwrap'
    | Ok _retries, _ =>
        ()
    | Error _error, _ =>
        result |> resultm.unwrap' |> ignore

    0i32

inl main () =
    $'let main args = !main args' : ()