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
113
114
115
116
117
use std::{path::PathBuf, str::FromStr};
use crate::{experimental, sandbox::utils::PackageContext, Move};
use anyhow::Result;
use move_core_types::{
language_storage::TypeTag, parser, transaction_argument::TransactionArgument,
};
use std::path::Path;
use clap::{ArgEnum, Parser};
#[derive(Parser)]
pub enum ExperimentalCommand {
#[clap(name = "read-write-set")]
ReadWriteSet {
#[clap(name = "module", parse(from_os_str))]
module_file: PathBuf,
#[clap(name = "function")]
fun_name: String,
#[clap(
long = "signers",
takes_value(true),
multiple_values(true),
multiple_occurrences(true)
)]
signers: Vec<String>,
#[clap(
long = "args",
parse(try_from_str = parser::parse_transaction_argument),
takes_value(true),
multiple_values(true),
multiple_occurrences(true)
)]
args: Vec<TransactionArgument>,
#[clap(
long = "type-args",
parse(try_from_str = parser::parse_type_tag),
takes_value(true),
multiple_values(true),
multiple_occurrences(true)
)]
type_args: Vec<TypeTag>,
#[clap(long = "concretize", possible_values = ConcretizeMode::variants(), ignore_case = true, default_value = "dont")]
concretize: ConcretizeMode,
},
}
#[derive(Debug, Clone, Copy, ArgEnum)]
pub enum ConcretizeMode {
Paths,
Reads,
Writes,
Dont,
}
impl FromStr for ConcretizeMode {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self> {
match s {
"paths" => Ok(ConcretizeMode::Paths),
"reads" => Ok(ConcretizeMode::Reads),
"writes" => Ok(ConcretizeMode::Writes),
"dont" => Ok(ConcretizeMode::Dont),
_ => Err(anyhow::anyhow!("Invalid concretize mode: {}", s)),
}
}
}
impl ConcretizeMode {
fn variants() -> [&'static str; 4] {
["paths", "reads", "writes", "dont"]
}
}
impl ExperimentalCommand {
pub fn handle_command(&self, move_args: &Move, storage_dir: &Path) -> Result<()> {
match self {
ExperimentalCommand::ReadWriteSet {
module_file,
fun_name,
signers,
args,
type_args,
concretize,
} => {
let state = PackageContext::new(&move_args.package_path, &move_args.build_config)?
.prepare_state(storage_dir)?;
experimental::commands::analyze_read_write_set(
&state,
module_file,
fun_name,
signers,
args,
type_args,
*concretize,
move_args.verbose,
)
}
}
}
}