Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
For the past few months I've been looking at using Prusti to verify the correctness of
ibc-rs
, in particular themodules
andrelayer
crates. The purpose of this PR is just to share a bit of what I've been able to accomplish so far and explain what an integration would look like. Also please let me know if you have any feedback or questions. This PR is not intended to be merged.The Prusti verification operates on entire crates, and is done via an external tool. Prusti verification does not require introducing any new dependencies on the project. Specifications can be encoded as attributes that are only enabled when the "prusti" flag is set, i.e.
#[cfg_attr(feature="prusti", <spec>)]
. The specification syntax is a superset of Rust, with extensions to supportforall
expressions etc.However, Prusti does not currently support all Rust language features and datatypes. So, it is also possible to provide different implementations for Prusti verification only (i.e. to work-around unsupported language features), without changing the actual implementation.
The following describes what I've done so far. A large caveat is that verification required changes to the code to remove unsupported features and datatypes; and some parts of the code containing unsupported features were excluded from verification entirely. The code in this PR only includes the added specifications, without the changes, in order to clearly demonstrate the annotation syntax and invariants. As a result, Prusti won't be able to verify the code in this PR; a version that has removed unsupported features is available here. Note that it is still a bit messy.
Verification of Safety Properties
Prusti was able to verify safety properties on the
modules
andrelayer
crate, with the caveat the properties may not hold for code unsupported by Prusti.No function will trigger
panic!
For example in context.rs:
The annotations ensure that the function
with_height()
will not panic, and introduces an obligation on the caller to ensure preconditions are satisfied.Calls to
Option.unwrap
andResult.unwrap
will not panicFor example, for serialization:
Arithmetic Operations will not overflow
This is useful, for example, operations on
Height
, to ensure that it is monotonically increasing.Functional Correctness
It was also possible to prove domain-specific invariants and correctness properties.
Misbehavior Detection
In tendermint.rs we have proven that:
The invariant is specified as:
This invariant asserts
header_within_trust_period
from the Tendermint crate.Proving these invariants require adding and proving additional invariants of other functions.
Client Keeper
In ibc.rs, we prove that
store_client_result
inClientKeeper
, will correctly maintain an invariant about the stored client data. This is done out of the codebase, because the separation ofClientKeeper
andClientReader
traits.The client invariant corresponds to: