1use crate::logic::errors::PrepareError;
5use unc_parameters::vm::{Config, VMKind};
6
7mod prepare_v0;
8mod prepare_v1;
9mod prepare_v2;
10
11pub fn prepare_contract(
23 original_code: &[u8],
24 config: &Config,
25 kind: VMKind,
26) -> Result<Vec<u8>, PrepareError> {
27 let prepare = config.limit_config.contract_prepare_version;
28 assert!(
30 (kind != VMKind::UncVm) || (prepare == crate::logic::ContractPrepareVersion::V2),
31 "UncVM only works with contract prepare version V2",
32 );
33 let features = crate::features::WasmFeatures::from(prepare);
34 match prepare {
35 crate::logic::ContractPrepareVersion::V0 => {
36 prepare_v1::validate_contract(original_code, features, config)?;
38 prepare_v0::prepare_contract(original_code, config)
39 }
40 crate::logic::ContractPrepareVersion::V1 => {
41 prepare_v1::validate_contract(original_code, features, config)?;
42 prepare_v1::prepare_contract(original_code, config)
43 }
44 crate::logic::ContractPrepareVersion::V2 => {
45 prepare_v2::prepare_contract(original_code, features, config, kind)
46 }
47 }
48}
49
50#[cfg(test)]
51mod tests {
52 use super::*;
53 use crate::tests::{test_vm_config, with_vm_variants};
54 use assert_matches::assert_matches;
55
56 fn parse_and_prepare_wat(
57 config: &Config,
58 vm_kind: VMKind,
59 wat: &str,
60 ) -> Result<Vec<u8>, PrepareError> {
61 let wasm = wat::parse_str(wat).unwrap();
62 prepare_contract(wasm.as_ref(), &config, vm_kind)
63 }
64
65 #[test]
66 fn internal_memory_declaration() {
67 let config = test_vm_config();
68 with_vm_variants(&config, |kind| {
69 let r = parse_and_prepare_wat(&config, kind, r#"(module (memory 1 1))"#);
70 assert_matches!(r, Ok(_));
71 })
72 }
73
74 #[test]
75 fn memory_imports() {
76 let config = test_vm_config();
77
78 assert_eq!(config.limit_config.max_memory_pages, 2048);
80
81 with_vm_variants(&config, |kind| {
82 let r = parse_and_prepare_wat(
83 &config,
84 kind,
85 r#"(module (import "env" "memory" (memory 1 1)))"#,
86 );
87 assert_matches!(r, Err(PrepareError::Memory));
88
89 let r = parse_and_prepare_wat(&config, kind, r#"(module)"#);
91 assert_matches!(r, Ok(_));
92
93 let r = parse_and_prepare_wat(
95 &config,
96 kind,
97 r#"(module (import "env" "memory" (memory 17 1)))"#,
98 );
99 assert_matches!(r, Err(PrepareError::Deserialization));
100
101 let r = parse_and_prepare_wat(
103 &config,
104 kind,
105 r#"(module (import "env" "memory" (memory 1)))"#,
106 );
107 assert_matches!(r, Err(PrepareError::Memory));
108
109 let r = parse_and_prepare_wat(
111 &config,
112 kind,
113 r#"(module (import "env" "memory" (memory 1 33)))"#,
114 );
115 assert_matches!(r, Err(PrepareError::Memory));
116 })
117 }
118
119 #[test]
120 fn multiple_valid_memory_are_disabled() {
121 let config = test_vm_config();
122 with_vm_variants(&config, |kind| {
123 let r = parse_and_prepare_wat(
126 &config,
127 kind,
128 r#"(module
129 (import "env" "memory" (memory 1 2048))
130 (import "env" "memory" (memory 1 2048))
131 )"#,
132 );
133 assert_matches!(r, Err(_));
134 let r = parse_and_prepare_wat(
135 &config,
136 kind,
137 r#"(module
138 (import "env" "memory" (memory 1 2048))
139 (memory 1)
140 )"#,
141 );
142 assert_matches!(r, Err(_));
143 })
144 }
145
146 #[test]
147 fn imports() {
148 let config = test_vm_config();
149 with_vm_variants(&config, |kind| {
150 let r = parse_and_prepare_wat(
152 &config,
153 kind,
154 r#"(module (import "another_module" "memory" (memory 1 1)))"#,
155 );
156 assert_matches!(r, Err(PrepareError::Instantiate));
157
158 let r = parse_and_prepare_wat(
159 &config,
160 kind,
161 r#"(module (import "env" "gas" (func (param i32))))"#,
162 );
163 assert_matches!(r, Ok(_));
164
165 })
176 }
177}