Skip to content

Commit b17beaa

Browse files
committed
Refactor VerificationService
1 parent 5719f37 commit b17beaa

File tree

10 files changed

+152
-164
lines changed

10 files changed

+152
-164
lines changed

prusti-common/src/verification_service.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,12 @@ use viper::{self, VerificationBackend};
55
use crate::vir::Program;
66

77
pub trait VerificationService {
8-
fn verify(&self, request: VerificationRequest) -> viper::ProgramVerificationResult;
8+
fn verify(&self, request: VerificationRequest) -> viper::VerificationResult;
99
}
1010

1111
#[derive(Debug, Clone, Serialize, Deserialize)]
1212
pub struct VerificationRequest {
13-
pub programs: Vec<Program>,
14-
pub program_name: String,
13+
pub program: Program,
1514
pub backend_config: ViperBackendConfig,
1615
}
1716

prusti-server/src/driver.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@ use clap::{App, Arg};
1515
use prusti_server::ServerSideService;
1616

1717
fn main() {
18-
env_logger::init_from_env(
19-
env_logger::Env::new().filter_or("RUST_LOG", "info"), // seems to be the cleanest way to set an overridable default for this
20-
);
18+
env_logger::init_from_env(env_logger::Env::new().filter_or("PRUSTI_LOG", "info"));
2119

2220
let matches = App::new("Prusti Server")
2321
.arg(

prusti-server/src/lib.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ use std::{
3232
};
3333
pub use verifier_runner::*;
3434
use verifier_thread::*;
35-
use viper::ProgramVerificationResult;
35+
use viper::VerificationResult;
3636

3737
#[derive(Debug, Serialize, Deserialize)]
3838
pub struct VerifierPanicked;
39-
pub type RemoteVerificationResult = Result<ProgramVerificationResult, VerifierPanicked>;
39+
pub type RemoteVerificationResult = Result<VerificationResult, VerifierPanicked>;
4040

4141
pub struct PrustiServer {
4242
verifier_builder: Arc<VerifierBuilder>,
@@ -75,10 +75,8 @@ impl PrustiServer {
7575
)
7676
});
7777

78-
match thread
79-
.verify(request.programs, request.program_name.clone())
80-
.wait()
81-
{
78+
let program_name = request.program.name.clone();
79+
match thread.verify(request.program).wait() {
8280
Ok(result) => {
8381
// put back the thread for later reuse
8482
let mut threads = self.threads.write().unwrap();
@@ -92,8 +90,8 @@ impl PrustiServer {
9290
Err(_) => {
9391
// canceled—the verifier thread panicked
9492
error!(
95-
"Panic while handling verification request {}",
96-
request.program_name
93+
"Panic while handling verification request for {}",
94+
program_name
9795
);
9896
Err(VerifierPanicked)
9997
}

prusti-server/src/service.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use std::{
1717
thread,
1818
};
1919
use tokio;
20-
use viper::ProgramVerificationResult;
20+
use viper::VerificationResult;
2121
use warp::{self, Buf, Filter};
2222

2323
#[derive(Clone)]
@@ -34,14 +34,11 @@ impl Default for ServerSideService {
3434

3535
impl ServerSideService {
3636
pub fn new() -> Self {
37-
// FIXME: since viper seems to dislike using verifiers in parallel, this is what we're doing to ensure correctness for now.
38-
// Eventually, we should lock only specific parts, instantiate multiple JVMs, or even address the root cause.
39-
let _max_concurrency = config::server_max_concurrency().unwrap_or_else(num_cpus::get);
40-
let max_concurrency = 1;
37+
let max_concurrency = config::server_max_concurrency().unwrap_or_else(num_cpus::get);
4138

4239
let cache_size = config::server_max_stored_verifiers().unwrap_or(max_concurrency);
4340
if cache_size < max_concurrency {
44-
warn!("PRUSTI_SERVER_MAX_STORED_VERIFIERS is lower than PRUSTI_SERVER_MAX_CONCURRENCY—you probably don't want to do this, since it means the server will likely have to keep creating new verifiers, reducing the performance gained from reuse.");
41+
warn!("PRUSTI_SERVER_MAX_STORED_VERIFIERS is lower than PRUSTI_SERVER_MAX_CONCURRENCY. You probably don't want to do this, since it means the server will likely have to keep creating new verifiers, reducing the performance gained from reuse.");
4542
}
4643

4744
Self {
@@ -130,7 +127,7 @@ impl ServerSideService {
130127
}
131128

132129
fn verify(&self, request: VerificationRequest) -> RemoteVerificationResult {
133-
info!("Handling verification request for {}", request.program_name);
130+
info!("Handling verification request for {}", request.program.name);
134131
self.server.run_verifier(request)
135132
}
136133
}
@@ -179,7 +176,7 @@ impl PrustiServerConnection {
179176

180177
impl VerificationService for PrustiServerConnection {
181178
/// panics if the verification request fails
182-
fn verify(&self, request: VerificationRequest) -> ProgramVerificationResult {
179+
fn verify(&self, request: VerificationRequest) -> VerificationResult {
183180
self.verify_checked(request)
184181
.expect("Verification request to server failed!")
185182
.expect("Server panicked while processing request!")

prusti-server/src/verifier_runner.rs

Lines changed: 10 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@ use prusti_common::{
1212
vir::{Program, ToViper},
1313
Stopwatch,
1414
};
15-
use viper::{
16-
self, ConsistencyError, JavaExceptionWithOrigin, ProgramVerificationResult, VerificationResult,
17-
};
1815

1916
pub struct VerifierRunner<'v> {
2017
verifier: viper::Verifier<'v, viper::state::Started>,
@@ -57,43 +54,20 @@ impl<'v> VerifierRunner<'v> {
5754
}
5855
}
5956

60-
pub fn verify(&self, programs: Vec<Program>, program_name: &str) -> ProgramVerificationResult {
61-
let mut results = ProgramVerificationResult::default();
62-
for program in programs {
63-
let mut stopwatch = Stopwatch::start("prusti-server", "construction of JVM objects");
64-
let viper_program = program.to_viper(&self.ast_factory);
65-
if config::dump_viper_program() {
66-
stopwatch.start_next("dumping viper program");
67-
self.dump(viper_program, program_name, &program.name);
68-
}
69-
stopwatch.start_next("verification");
70-
match self.verifier.verify(viper_program) {
71-
VerificationResult::Success => {}
72-
VerificationResult::Failure(errors) => {
73-
results.verification_errors.extend(errors);
74-
}
75-
VerificationResult::ConsistencyErrors(errors) => {
76-
results
77-
.consistency_errors
78-
.extend(errors.into_iter().map(|error| ConsistencyError {
79-
method: program.name.clone(),
80-
error,
81-
}));
82-
}
83-
VerificationResult::JavaException(exception) => {
84-
results.java_exceptions.push(JavaExceptionWithOrigin {
85-
method: program.name.clone(),
86-
exception,
87-
});
88-
}
89-
}
57+
pub fn verify(&self, program: Program) -> viper::VerificationResult {
58+
let mut stopwatch = Stopwatch::start("prusti-server", "construction of JVM objects");
59+
let viper_program = program.to_viper(&self.ast_factory);
60+
if config::dump_viper_program() {
61+
stopwatch.start_next("dumping viper program");
62+
self.dump(viper_program, &program.name);
9063
}
91-
results
64+
stopwatch.start_next("verification");
65+
self.verifier.verify(viper_program)
9266
}
9367

94-
fn dump(&self, program: viper::Program, program_name: &str, method_name: &str) {
68+
fn dump(&self, program: viper::Program, program_name: &str) {
9569
let namespace = "viper_program";
96-
let filename = format!("{}-{}.vpr", program_name, method_name);
70+
let filename = format!("{}.vpr", program_name);
9771
info!("Dumping Viper program to '{}/{}'", namespace, filename);
9872
log::report(namespace, filename, self.ast_utils.pretty_print(program));
9973
}

prusti-server/src/verifier_thread.rs

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,23 @@ use std::{
1313
sync::{mpsc, Arc, Mutex},
1414
thread,
1515
};
16-
use viper::ProgramVerificationResult;
16+
use viper::VerificationResult;
1717

18-
pub type FutVerificationResult =
19-
Box<dyn Future<Item = ProgramVerificationResult, Error = Canceled>>;
18+
pub type FutVerificationResult = Box<dyn Future<Item = VerificationResult, Error = Canceled>>;
2019

21-
struct VerificationRequest {
22-
pub programs: Vec<Program>,
23-
pub program_name: String,
24-
pub sender: oneshot::Sender<ProgramVerificationResult>,
20+
struct SenderVerificationRequest {
21+
pub program: Program,
22+
pub sender: oneshot::Sender<VerificationResult>,
2523
}
2624

2725
pub struct VerifierThread {
2826
pub backend_config: ViperBackendConfig,
29-
request_sender: Mutex<mpsc::Sender<VerificationRequest>>,
27+
request_sender: Mutex<mpsc::Sender<SenderVerificationRequest>>,
3028
}
3129

3230
impl VerifierThread {
3331
pub fn new(verifier_builder: Arc<VerifierBuilder>, backend_config: ViperBackendConfig) -> Self {
34-
let (request_sender, request_receiver) = mpsc::channel::<VerificationRequest>();
32+
let (request_sender, request_receiver) = mpsc::channel::<SenderVerificationRequest>();
3533

3634
let builder = thread::Builder::new().name(format!(
3735
"Verifier thread running {}",
@@ -55,10 +53,10 @@ impl VerifierThread {
5553

5654
fn listen_for_requests(
5755
runner: VerifierRunner,
58-
request_receiver: mpsc::Receiver<VerificationRequest>,
56+
request_receiver: mpsc::Receiver<SenderVerificationRequest>,
5957
) {
6058
while let Ok(request) = request_receiver.recv() {
61-
let result = runner.verify(request.programs, request.program_name.as_str());
59+
let result = runner.verify(request.program);
6260
request.sender.send(result).unwrap_or_else(|err| {
6361
error!(
6462
"verifier thread attempting to send result to dropped receiver: {:?}",
@@ -68,14 +66,13 @@ impl VerifierThread {
6866
}
6967
}
7068

71-
pub fn verify(&self, programs: Vec<Program>, program_name: String) -> FutVerificationResult {
69+
pub fn verify(&self, program: Program) -> FutVerificationResult {
7270
let (tx, rx) = oneshot::channel();
7371
self.request_sender
7472
.lock()
7573
.unwrap()
76-
.send(VerificationRequest {
77-
programs,
78-
program_name,
74+
.send(SenderVerificationRequest {
75+
program,
7976
sender: tx,
8077
})
8178
.unwrap();

prusti-server/tests/basic_requests.rs

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use prusti_common::{
99
vir::*,
1010
};
1111
use prusti_server::{PrustiServerConnection, ServerSideService};
12-
use viper::ProgramVerificationResult;
12+
use viper::VerificationResult;
1313

1414
lazy_static! {
1515
// only start the jvm & server once
@@ -25,43 +25,37 @@ fn consistency_error() {
2525
});
2626
});
2727

28-
let ProgramVerificationResult {
29-
verification_errors,
30-
mut consistency_errors,
31-
java_exceptions,
32-
} = result;
33-
34-
assert!(verification_errors.is_empty());
35-
assert!(java_exceptions.is_empty());
36-
let consistency_error = consistency_errors.pop().unwrap();
37-
assert!(consistency_errors.is_empty());
38-
println!("consistency error: {:?}", consistency_error);
28+
match result {
29+
VerificationResult::ConsistencyErrors(errors) => assert_eq!(errors.len(), 1),
30+
other => panic!(
31+
"consistency errors not identified, instead found {:?}",
32+
other
33+
),
34+
}
3935
}
4036

4137
#[test]
4238
fn empty_program() {
4339
let result = process_program(|_| ());
4440

45-
let ProgramVerificationResult {
46-
verification_errors,
47-
consistency_errors,
48-
java_exceptions,
49-
} = result;
50-
51-
assert!(verification_errors.is_empty());
52-
assert!(java_exceptions.is_empty());
53-
assert!(consistency_errors.is_empty());
41+
match result {
42+
VerificationResult::Success => {}
43+
other => panic!(
44+
"empty program not verified successfully, instead found {:?}",
45+
other
46+
),
47+
}
5448
}
5549

56-
fn process_program<F>(configure: F) -> ProgramVerificationResult
50+
fn process_program<F>(configure: F) -> VerificationResult
5751
where
5852
F: FnOnce(&mut Program),
5953
{
6054
let service =
6155
PrustiServerConnection::new(SERVER_ADDRESS.clone()).expect("Could not connect to server!");
6256

6357
let mut program = Program {
64-
name: "very_dummy".to_string(),
58+
name: "dummy".to_string(),
6559
domains: vec![],
6660
fields: vec![],
6761
builtin_methods: vec![],
@@ -72,8 +66,7 @@ where
7266
configure(&mut program);
7367

7468
let request = VerificationRequest {
75-
programs: vec![program],
76-
program_name: "dummy".to_string(),
69+
program,
7770
backend_config: Default::default(),
7871
};
7972

0 commit comments

Comments
 (0)