1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use crate::cannon::*;
use clap::{arg, Parser, Subcommand};

#[derive(Parser, Debug, Clone)]
pub struct MipsVmConfigurationArgs {
    #[arg(
        long,
        value_name = "FILE",
        default_value = "state.json",
        help = "initial state file"
    )]
    input: String,

    #[arg(
        long,
        value_name = "FILE",
        default_value = "out.json",
        help = "output state file"
    )]
    output: String,

    #[arg(
        long,
        value_name = "FILE",
        default_value = "meta.json",
        help = "metadata file"
    )]
    meta: String,

    #[arg(
        long = "proof-at",
        short = 'p',
        long,
        value_name = "FREQ",
        default_value = "never"
    )]
    proof_at: StepFrequency,

    #[arg(
        long = "proof-fmt",
        value_name = "FORMAT",
        default_value = "proof-%d.json"
    )]
    proof_fmt: String,

    #[arg(
        long = "snapshot-fmt",
        value_name = "FORMAT",
        default_value = "state-%d.json"
    )]
    snapshot_fmt: String,

    #[arg(long = "stop-at", value_name = "FREQ", default_value = "never")]
    stop_at: StepFrequency,

    #[arg(long = "info-at", value_name = "FREQ", default_value = "never")]
    info_at: StepFrequency,

    #[arg(long = "pprof.cpu", action = clap::ArgAction::SetTrue)]
    pprof_cpu: bool,

    #[arg(
        long = "snapshot-state-at",
        value_name = "FREQ",
        default_value = "never"
    )]
    snapshot_state_at: StepFrequency,

    #[arg(name = "host", value_name = "HOST", help = "host program specification <host program> [host program arguments]", num_args = 1.., last = true)]
    host: Vec<String>,
}

impl From<MipsVmConfigurationArgs> for VmConfiguration {
    fn from(cfg: MipsVmConfigurationArgs) -> Self {
        VmConfiguration {
            input_state_file: cfg.input,
            output_state_file: cfg.output,
            metadata_file: cfg.meta,
            proof_at: cfg.proof_at,
            stop_at: cfg.stop_at,
            snapshot_state_at: cfg.snapshot_state_at,
            info_at: cfg.info_at,
            proof_fmt: cfg.proof_fmt,
            snapshot_fmt: cfg.snapshot_fmt,
            pprof_cpu: cfg.pprof_cpu,
            host: if cfg.host.is_empty() {
                None
            } else {
                Some(HostProgram {
                    name: cfg.host[0].to_string(),
                    arguments: cfg.host[1..].to_vec(),
                })
            },
        }
    }
}

#[derive(Parser, Debug, Clone)]
pub struct RunArgs {
    #[arg(long = "preimage-db-dir", value_name = "PREIMAGE_DB_DIR")]
    pub preimage_db_dir: Option<String>,
    // it's important that vm_cfg is last in order to properly parse the host field
    #[command(flatten)]
    pub vm_cfg: MipsVmConfigurationArgs,
}

#[derive(Subcommand, Clone, Debug)]
pub enum Cannon {
    Run(RunArgs),
    #[command(name = "test-optimism-preimage-read")]
    TestPreimageRead(RunArgs),
}