wark 0.2.2

WebAssembly RunKit.
Documentation
# WARK

**W**eb**A**ssembly **R**un**K**it, also known as WARK, is a highly efficient tool designed to execute WebAssembly (w/ WASI) modules within a secure sandboxed environment. It can meticulously calculate and report the precise resource usage of the module, including instruction cost and memory utilization.

You can use WARK as a Command-Line Interface (CLI) tool or as a web service, depending on your needs.

## Table of Contents

- [WARK]#wark
  - [Table of Contents]#table-of-contents
  - [Installation]#installation
    - [Docker]#docker
    - [Cargo]#cargo
  - [Usage]#usage
    - [CLI]#cli
      - [Options]#options
      - [IO]#io
    - [Web Service]#web-service
      - [Run]#run
      - [Judge]#judge
  - [Cost Table]#cost-table

## Installation

### Docker

If you have Docker installed, you can use the following command to run WARK:

```sh
# Run the web service
docker run -it --rm -p 33000:33000 jacoblincool/wark server
```

### Cargo

To install WARK using Cargo, use the following command:

```sh
cargo install wark
```

## Usage

### CLI

To run a WebAssembly module using the CLI, use the following command:

```sh
wark run [OPTIONS] <module>
```

#### Options

You can customize the execution with the following options:

```sh
  -m, --memory <memory>     Define memory limit in MB [default: 512]
  -c, --cost <cost>         Set computational cost limit in instruction count [default: 1000000000]
  -i, --input <input>       Specify input file path for the program [default: stdin]
      --stderr <file>       Redirect program's stderr to a file
  -n, --no-report           Suppress the report of the program's resource usage
```

#### IO

- You can use the `--input` option to specify the input file path for the program. If you want to use stdin as the input, use `-` as the input file path.
- The stdout of the module will be printed to the stdout of the CLI.
- The stderr of the module will **not** be printed to the stderr of the CLI. Instead, use the `--stderr` option to redirect it to a file.
- Unless suppressed with the `--no-report` option, the resource usage of the module will be printed to the stderr of the CLI.

### Web Service

To start the WARK server, use the following command:

```sh
wark server
```

> You can use the `PORT` environment variable to specify the port number. The default port number is `33000`.

#### Run

To run a WebAssembly module, send a `POST` request with a JSON object in the body containing the following fields:

```sh
curl 'http://127.0.0.1:33000/run' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <JWT_TOKEN>' \
--data '{
    "cost": 10000000,
    "memory": 512,
    "input": "I am stdin input",
    "wasm": "<base64 encoded wasm module>"
  }'
```

The server will respond with a JSON object containing the following fields:

```json
{
    "success": true,
    "cost": 1234567,
    "memory": 345,
    "stdout": "I am stdout output",
    "stderr": "I am stderr output",
    "message": "I am message"
}
```

#### Judge

To run the program in judge mode, send a `POST` request with a JSON object in the body containing the following fields:

```sh
curl --location 'http://127.0.0.1:33000/judge' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <JWT_TOKEN>' \
--data '{
    "wasm": "<base64 encoded wasm module>",
    "specs": [
        {
            "judger": "IOFast",
            "input": "Jacob",
            "output_hash": "128783a055c41c0a79ad7376e8e22587cdca53ed1f9c47c46d02a7768992b325",
            "cost": 1000000000,
            "memory": 1024
        },
        {
            "judger": "IOFast",
            "input": "WOJ",
            "output_hash": "75787b1df461d0c48f0229a7769cbcc37c7d96d6613f825b77e76afdd1eb790a",
            "cost": 1000000000,
            "memory": 1024
        },
        {
            "judger": "IOFast",
            "input": "WASM OJ Wonderland",
            "output_hash": "8f02d3283b88d16766cb287090bf59135c873e9175759b73f96ffe674440ff21",
            "cost": 1000000000,
            "memory": 1024
        },
        {
            "judger": "IOFast",
            "input_url": "https://link-to-input.file/input.txt",
            "output_hash": "87c215c4afeaf7ff7684ef90fd44649b2051bc4c68cf58bdad402fa304487b8w",
            "cost": 1000000000,
            "memory": 1024
        }
    ]
}'
```

The server will respond with a JSON object containing the following fields:

```json
{
    "results": [
        {
            "success": true,
            "cost": 3776,
            "memory": 1,
            "message": null,
            "exception": null
        },
        {
            "success": true,
            "cost": 3692,
            "memory": 1,
            "message": null,
            "exception": null
        },
        {
            "success": true,
            "cost": 4421,
            "memory": 1,
            "message": null,
            "exception": null
        },
        {
            "success": false,
            "cost": 5848,
            "memory": 1,
            "message": null,
            "exception": {
                "type": "Output",
                "reason": "Output hash mismatch. Expected 87c215c4afeaf7ff7684ef90fd44649b2051bc4c68cf58bdad402fa304487b8w, got 87c215c4afeaf7ff7684ef90fd44649b2051bc4c68cf58bdad402fa304487b8c"
            }
        }
    ]
}
```

Currently, the server only supports the `IOFast` judger, which is a simple judger that compares the trimmed output of the program with the `output_hash` field. If the output of the program matches the `output_hash` field, indicating that the program has passed the test case. Otherwise, an `Output` exception will be returned.

> Remote inputs will be cached in the `http-cache` directory, the TTL of each cache is respecting the `Cache-Control` header of the response.

## Cost Table

You can find the cost of each instruction in the [src/cost.rs](./src/cost.rs).

> If you see `Penalty Instruction [Instruction Name]`, it means that the specific instruction was not included in the cost table. Therefore, its cost defaults to 1000 points.

---

Feel free to contribute to this project by submitting pull requests or reporting issues. Your help is always welcomed and appreciated!