Skip to content
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

Instrumentable spec #100

Merged
merged 14 commits into from
Jun 11, 2024
Merged

Instrumentable spec #100

merged 14 commits into from
Jun 11, 2024

Conversation

Kukovec
Copy link
Collaborator

@Kukovec Kukovec commented Jun 10, 2024

Implements half of #99 (only deposit for now)

Makes the following changes:

  • Adds the two contracts (timelock, token) from soroban_examples under ContractExamples/contracts
  • Adds a monitor based on Investigate reverse reasoning for monitors #37 under docs/timelock, together with a type hints file to use with fetch
  • Adds two scripts which:
    • initialize Docker and populate soroban with aliases
    • Automate the deployment of the two contracts and basic invocations, ending in a deposit call
  • Changes instrumentation, s.t.:
    • env now gets instrumented with two additional fields, tracking which values were set in storage before and after the transaction
    • The order of conjuncts in Next is changed, so that it initializes before calling the method operator, avoiding use-before-assignment in the case where the method operator references primed variables
    • The way Variants!Variant arguments are passed is fixed.

@konnov
Copy link
Contributor

konnov commented Jun 10, 2024

we have to add proper attribution to the files we copy from elsewhere

@Kukovec
Copy link
Collaborator Author

Kukovec commented Jun 10, 2024

Just a heads up regarding the commit you're about to see (TLA noise). Apalache translates UNCHANGED x not into x' = x, but into x' := x (using the assignment operator). This becomes a problem, because x' = x /\ UNCHANGED x triggers an "assigneed twice" exception in Apalache, since left-to-right analysis necessitates that the first conjunct, x' = x, be taken as an assignment as well. Semantically, there is no change, but since I had to change the conjunct order in Next instrumentation, I have to update the current test monitors using UNCHANGED as well.

Copy link
Collaborator

@thpani thpani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First set of comments – I haven't looked at the TLA+ yet

  1. I don't understand why you diverge from the existing scripts in ContractExamples/scripts/ so much. They would be much easier to use if they all follow the same function + style.

  2. There's a LICENSE on solarkraft-examples that we have to comply with.

ContractExamples/scripts/init-timelock.sh Outdated Show resolved Hide resolved
ContractExamples/scripts/init-timelock.sh Outdated Show resolved Hide resolved
ContractExamples/scripts/init-timelock.sh Outdated Show resolved Hide resolved
ContractExamples/scripts/prepare-timelock.sh Outdated Show resolved Hide resolved
ContractExamples/scripts/prepare-timelock.sh Outdated Show resolved Hide resolved
ContractExamples/scripts/prepare-timelock.sh Outdated Show resolved Hide resolved
ContractExamples/scripts/prepare-timelock.sh Outdated Show resolved Hide resolved
ContractExamples/scripts/prepare-timelock.sh Outdated Show resolved Hide resolved
ContractExamples/scripts/prepare-timelock.sh Outdated Show resolved Hide resolved
--token $TOKEN\
--amount 1 \
--claimants "[\"$(soroban keys address bob)\"]"\
--time_bound '{"kind": "After", "timestamp": 0}'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe use a more realistic whitespace here?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I meant more realistic timestamp 😅

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"After 0" should mean that the claimants can claim whenever, which I thought would be easy to follow-up test. If you hardcode any fixed timestamp you either a) functionally get the same thing as 0 if that time has already passed, or b) have to actually wait before calling claim.

@thpani
Copy link
Collaborator

thpani commented Jun 10, 2024

This becomes a problem, because x' = x /\ UNCHANGED x triggers an "assigneed twice" exception in Apalache, since left-to-right analysis necessitates that the first conjunct, x' = x, be taken as an assignment as well. Semantically, there is no change, but since I had to change the conjunct order in Next instrumentation

Looks to me like you should emit UNCHANGED x, not x' = x, in the first place?

Otherwise,

I have to update the current test monitors using UNCHANGED as well.

it sounds like we'd have to discourage use of UNCHANGED in the monitor specs?
Not particularly fond of that idea.

@Kukovec
Copy link
Collaborator Author

Kukovec commented Jun 10, 2024

...
it sounds like we'd have to discourage use of UNCHANGED in the monitor specs? Not particularly fond of that idea.

I'll try do dig up the conversation in the Apalache repo explaining why we translate unchanged as an assignment, but from memory, the TLDR is that x' = x is a regular condition, whereas UNCHANGED x is an actionable declaration of the shape of the successor state, and since Apalache has assignments, which base TLA lacks, the UNCHANGED -> := translation felt like it made sense at the time, even though it's working against us here.

Edit: I found the Apalache issue 1346, but it unfortunately just says "per our discussions"

Copy link
Collaborator

@thpani thpani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

second set of comments

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

empty

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

empty

ContractExamples/scripts/prepare-timelock.sh Outdated Show resolved Hide resolved
ContractExamples/scripts/prepare-timelock.sh Outdated Show resolved Hide resolved
Comment on lines +61 to +62
instance_set(key, env) ==
env.storage_after \ env.storage_before = {key}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idk what the semantics of this are meant to be, but I would expect

key \in (env.storage_after \ env.storage_before)

In any case, the intention seems to be ambiguous and worth adding a comment.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the original code here was

instance_storage' = instance_storage \union {key}

My understanding of the intent here was that the interpretation of this was "exactly key gets set" (since "key is set" could have been tested just via key \in instance_storage'), and I rewrote it that way, because A = B \cup {x} is true iff A differs from B by exactly x or if they both contain x, which I assumed to have been an oversight.
Your suggestion, x \in A\B would evaluate to true if A \ B equaled {x, y, z, ...} too (which may or may not have been the actual intent). Perhaps @andrey-kuprianov can comment best on what the intended semantics here were.


\* @type: ($storageKey, $env) => Bool;
instance_remove(key, env) ==
env.storage_before \ env.storage_after = {key}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

doc/timelock/deposit.tla Outdated Show resolved Hide resolved
doc/timelock/deposit.tla Show resolved Hide resolved
doc/timelock/deposit.tla Outdated Show resolved Hide resolved
doc/timelock/deposit.tla Outdated Show resolved Hide resolved
Copy link
Contributor

@konnov konnov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had a very quick view at the PR:

  1. Why don't we link the soroban examples via git modules? Otherwise, it would be real hard to keep code in sync, when soroban-examples are updated. Also, what's the point of copying the code from another project? We would have to take care of the licenses and other uninteresting stuff.
  2. I don't get the discussion about UNCHANGED. Yes, we thought that forcing UNCHANGED to be an assignment was a good idea, but why do we introduce two assignments in the first place?

@Kukovec
Copy link
Collaborator Author

Kukovec commented Jun 11, 2024

  1. Why don't we link the soroban examples via git modules? Otherwise, it would be real hard to keep code in sync, when soroban-examples are updated. Also, what's the point of copying the code from another project? We would have to take care of the licenses and other uninteresting stuff.

We could, but to my knowledge, there's no way to submodule in only a part of the repository, so we'd have to include all of soroban-examples. If we don't mind that, I'll go ahead and do a submodule

  1. I don't get the discussion about UNCHANGED. Yes, we thought that forcing UNCHANGED to be an assignment was a good idea, but why do we introduce two assignments in the first place?

Assume that you have X in fields, and somewhere inside method there is an UNCHANGED X. Our instrumentation does:

Next ==
 /\ ...
 /\ X' = concrete_value_from_fields
 /\ method(...)

which expands to

X' = a1 /\ ... /\ UNCHANGED X

You have two options:

  1. Next == instrument_fields /\ method(...)
  2. Next == method(...) /\ instrument_fields

If you do (2), you cannot ever reference any primed variable inside your method(...) (i.e. inside any monitor invariant), because you end up with assignment-before-use in Apalache.
If you do (1), which we currently do, you cannot us any manual assignment in the method(...) part, because you end up with assigned-twice in Apalache. UNCHANGED is currenty, besides manually writing in assignments, the only way in which assignments sneak into the monitor(...) part

@konnov
Copy link
Contributor

konnov commented Jun 11, 2024

I don't want to block this PR on UNCHANGED. IMO, let's open an issue on UNCHANGED, maybe we even have to revisit Apalache on that. If we can avoid issues with UNCHANGED in the current examples, let's do that.

Copy link
Collaborator

@thpani thpani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is fine – not the kind of PR I would've liked to review multiple times.

The discussion on UNCHANGED is lost on me, maybe @konnov still wants to comment.

doc/timelock/deposit.tla Outdated Show resolved Hide resolved
.github/workflows/main.yml Outdated Show resolved Hide resolved
Copy link
Collaborator

@thpani thpani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unblocking this given Igors comment

@Kukovec Kukovec merged commit 6ad18f1 into main Jun 11, 2024
3 checks passed
@Kukovec Kukovec deleted the jk/instrumentableSpec branch June 11, 2024 14:22
@konnov konnov added this to the M4: Case study milestone Jun 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants