Skip to content

Commit 0f4cfe2

Browse files
authored
Merge branch 'main' into range_count_quantifier
2 parents a3c3e0a + d7538ab commit 0f4cfe2

File tree

4 files changed

+85
-40
lines changed

4 files changed

+85
-40
lines changed

crates/move-prover-boogie-backend/src/boogie_backend/boogie_wrapper.rs

Lines changed: 75 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -147,17 +147,31 @@ impl<'env> BoogieWrapper<'env> {
147147
remote_opt: &RemoteOptions,
148148
individual_timeout: Option<u64>,
149149
individual_options: Option<String>,
150-
) -> anyhow::Result<RemoteProverResponse> {
151-
let file_text = fs::read_to_string(boogie_file).map_err(|e| {
152-
anyhow!(format!(
153-
"Failed to read boogie file '{}': {}",
154-
boogie_file, e
155-
))
156-
})?;
150+
) -> RemoteProverResponse {
151+
let err = |msg: String, status: i32| RemoteProverResponse {
152+
out: String::new(),
153+
err: msg,
154+
status,
155+
cached: false,
156+
};
157157

158-
let client = reqwest::Client::builder()
159-
.timeout(Duration::from_secs(individual_timeout.unwrap_or(600))) // 10 minutes timeout
160-
.build()?;
158+
let file_text = match fs::read_to_string(boogie_file) {
159+
Ok(text) => text,
160+
Err(e) => {
161+
return err(
162+
format!("Failed to read boogie file '{}': {}", boogie_file, e),
163+
1,
164+
)
165+
}
166+
};
167+
168+
let client = match reqwest::Client::builder()
169+
.timeout(Duration::from_secs(individual_timeout.unwrap_or(600)))
170+
.build()
171+
{
172+
Ok(client) => client,
173+
Err(e) => return err(format!("Failed to build HTTP client: {}", e), 1),
174+
};
161175

162176
let is_remote = remote_opt.url.as_str().contains("https://");
163177

@@ -184,44 +198,52 @@ impl<'env> BoogieWrapper<'env> {
184198
})
185199
};
186200

187-
let response = client
201+
let response = match client
188202
.post(remote_opt.url.as_str())
189203
.header("Authorization", remote_opt.api_key.as_str())
190204
.json(&request)
191205
.send()
192206
.await
193-
.map_err(|e| {
194-
anyhow!(format!(
195-
"Failed to send HTTP request to '{}': {}",
196-
remote_opt.url, e
197-
))
198-
})?;
207+
{
208+
Ok(resp) => resp,
209+
Err(e) => {
210+
return err(
211+
format!("HTTP request timed out. Status '{}': {}", remote_opt.url, e),
212+
1,
213+
)
214+
}
215+
};
199216

200217
if !response.status().is_success() {
218+
let status_code = response.status().as_u16() as i32;
201219
let error_text = response
202220
.text()
203221
.await
204222
.unwrap_or_else(|_| "Unable to read response body".to_string());
205-
return Err(anyhow!(format!("HTTP request failed: {}", error_text)));
223+
return err(
224+
format!("HTTP request timed out. {}: {}", status_code, error_text),
225+
status_code,
226+
);
206227
}
207228

208-
let response_body = response.text().await?;
229+
let response_body = match response.text().await {
230+
Ok(body) => body,
231+
Err(e) => return err(format!("Failed to read response body: {}", e), 1),
232+
};
209233

210-
let result = if is_remote {
211-
let response: RemoteProverResponse = serde_json::from_str(&response_body)
212-
.map_err(|e| anyhow!(format!("Failed to parse response body JSON: {}", e)))?;
213-
response
234+
if is_remote {
235+
serde_json::from_str(&response_body)
236+
.unwrap_or_else(|e| err(format!("Failed to parse response body JSON: {}", e), 1))
214237
} else {
215238
let response_json: RemoteProverResponseWrapper =
216-
serde_json::from_str(&response_body)
217-
.map_err(|e| anyhow!(format!("Failed to read response body: {}", e)))?;
218-
219-
let response: RemoteProverResponse = serde_json::from_str(&response_json.body)
220-
.map_err(|e| anyhow!(format!("Failed to parse response body JSON: {}", e)))?;
221-
response
222-
};
239+
match serde_json::from_str(&response_body) {
240+
Ok(resp) => resp,
241+
Err(e) => return err(format!("Failed to read response body: {}", e), 1),
242+
};
223243

224-
Ok(result)
244+
serde_json::from_str(&response_json.body)
245+
.unwrap_or_else(|e| err(format!("Failed to parse response body JSON: {}", e), 1))
246+
}
225247
}
226248

227249
pub async fn call_remote_boogie(
@@ -249,7 +271,7 @@ impl<'env> BoogieWrapper<'env> {
249271
individual_timeout,
250272
individual_options,
251273
)
252-
.await?;
274+
.await;
253275
self.analyze_output(&res.out, &res.err, res.status)
254276
}
255277

@@ -346,13 +368,27 @@ impl<'env> BoogieWrapper<'env> {
346368
));
347369
}
348370
if status != 0 {
349-
// Exit here with raw output.
350-
return Err(anyhow!(
351-
"Boogie error ({}): {}\n\nstderr:\n{}",
352-
status,
353-
out,
354-
err
355-
));
371+
let errors = if out.to_lowercase().contains("http request timed out") {
372+
vec![BoogieError {
373+
kind: BoogieErrorKind::Internal,
374+
loc: Loc::default(),
375+
message: format!("Boogie error ({}): {}\n\nstderr:\n{}", status, out, err),
376+
execution_trace: vec![],
377+
model: None,
378+
}]
379+
} else {
380+
vec![BoogieError {
381+
kind: BoogieErrorKind::Inconclusive,
382+
loc: Loc::default(),
383+
message: format!("cloud verification out of resources/timeout"),
384+
execution_trace: vec![],
385+
model: None,
386+
}]
387+
};
388+
return Ok(BoogieOutput {
389+
errors,
390+
all_output: out.to_owned(),
391+
});
356392
}
357393
if out.trim().starts_with("Unable to monomorphize") {
358394
return Err(anyhow!("Boogie error: {}\n\nstderr:\n{}", out, err));

crates/move-prover-boogie-backend/src/boogie_backend/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,13 @@ pub fn add_prelude(
259259
}
260260

261261
context.insert("include_vec_sum", &should_include_vec_sum(env, targets));
262+
context.insert(
263+
"include_vector_iter_range",
264+
&targets.has_target(
265+
&env.get_function(env.prover_range_qid()),
266+
&FunctionVariant::Baseline,
267+
),
268+
);
262269

263270
// let mut table_instances = mono_info
264271
// .table_inst

crates/move-prover-boogie-backend/src/boogie_backend/prelude/prelude.bpl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ procedure {:inline 1} $0_prover_type_inv'$1_integer_Integer'(x: int) returns (y:
4444
y := true;
4545
}
4646

47+
{%- if include_vector_iter_range %}
4748
function $0_vector_iter_range(start: int, end: int) returns (Vec int);
4849
axiom (
4950
forall start, end: int :: {$0_vector_iter_range(start, end)}
@@ -53,6 +54,7 @@ axiom (
5354
(forall i: int :: InRangeVec(res, i) ==> ReadVec(res, i) == i + start)
5455
)
5556
);
57+
{%- endif %}
5658

5759

5860
{%- if options.bv_int_encoding -%}

crates/sui-prover/tests/snapshots/multiple_specs/include_external.fail.move.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ source: crates/sui-prover/tests/integration.rs
33
expression: output
44
---
55
[internal] boogie exited with compilation errors:
6-
output/multiple_specs/include_external.fail/bar_specs_double_foo_imported_module::bar_spec_Assume.bpl(4378,4): Error: call to undeclared procedure: $42_fb_foo
6+
output/multiple_specs/include_external.fail/bar_specs_double_foo_imported_module::bar_spec_Assume.bpl(4368,4): Error: call to undeclared procedure: $42_fb_foo
77
1 name resolution errors detected in output/multiple_specs/include_external.fail/bar_specs_double_foo_imported_module::bar_spec_Assume.bpl

0 commit comments

Comments
 (0)