-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Verifying Reentrant Computation #108
Comments
variant unchanged(&int p)
where old(*p) == *p
map<address,uint256> balances = ...
bool lock = false
public method get_balance(address sender) -> uint256
unchanged(&balances):
...
public method deposit(address sender):
sender.transfer(123) <-
public method main()
always lock ==> unchanged(&balances)
eventually ended The keywords are from temporal logic. These are the transitive and reflexive closures of |
The rough idea is to use a keyword
|
Another aspect of this idea is that we can use it for authorisation as well. For example, we can say something like this:
|
To verify reentrant computation relies on a two state predicate which summarises the effect making one (or more) reentrant calls into a method could have on local state. For example, consider this:
The necessary two-state predicate is actually
old(state) < state
forinc()
since we can callinc()
arbitrarily many times from external code. What we need is a way to either infer such a specification or (perhaps easier) to check such a specification is already transitive.Syntax
There are various ways we could try to encode the logic we need. One approach might be to impose constraints on how global data could be modified. For example:
Actually the
varies
clauses is perhaps similar or identical to Liskov and Wing'sconstraint
clause.References
The text was updated successfully, but these errors were encountered: