-
Notifications
You must be signed in to change notification settings - Fork 54
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
Equivalence fixes #681
base: main
Are you sure you want to change the base?
Equivalence fixes #681
Conversation
07c494b
to
33b41c7
Compare
Should work this way, cleaner Explain why test is ignored Update changelog Fixing git merge artefact Fixing up git merge Fixing some small bugs
cc374e0
to
90d7155
Compare
9b88719
to
f874dad
Compare
f874dad
to
fa16a9e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice, thanks for this fix!
I had some minor comment. As an overall comment, maybe it is worth adding some more tests for deployment (for example one that covers equal constructors that deploy contracts that are not actually equal).
@@ -480,20 +483,23 @@ instance Eq Prop where | |||
PImpl a b == PImpl c d = a == c && b == d | |||
_ == _ = False | |||
|
|||
-- Note: we cannot compare via `a <= c || b <= d` because then | |||
-- when a==c but b > d, we'd return TRUE, when we should be | |||
-- returning FALSE. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it OK to return TRUE when a > b (and b < d)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If not, you can also consider a lexicographic ordering (a <= c || (a == c && b <= d)
)
CodeHash a@(LitAddr _) -> pure $ fromLazyText "codehash_" <> formatEAddr a | ||
Gas prefix var -> pure $ fromLazyText $ "gas-" <> T.pack (TS.unpack prefix) <> T.pack (show var) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is dash instead of underscore here intentional?
|
||
-- If the original check was for create (i.e. undeployed code), then we must also check that the deployed | ||
-- code is equivalent. The constraints from the undeployed code (aProps,bProps) influence this check. | ||
checkCreatedDiff aOut bOut aProps bProps = do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!!!
Description
This fixes two underlying issues with equivalence checking.
Creation now deploys the code and checks the difference of the deployed code
Firstly, it fixes the issue that we didn't check the deployed contract, as per Zoe's observation. This is because we never deployed the contract that was created and check its difference in behaviour. This is no longer the case, we now distinguish between create/no-create equivalence checking. Some of this code was written by Zoe, and I fixed up the rest.
Equivalence checking no longer assumes overapproximated calls/etc. return the same value
Secondly, during equivalence checking, we actually didn't distinguish the fresh variables added via overapproximation for code A and code B. So the overapproximations were somehow doing the "same thing" which is wrong, they may very well be called with different arguments, at different points of the run, etc. This false equivalence was because the variables were named the same. I now have a function
rewriteFresh
that sticks anA-
orB-
in front of these fresh variables, therefore making them symbolically different. This also means that we potentially return false positives. This is just the way things are with overapproximation. We could add constraints, such as(initial state + calldata) -> symbolic value
and then these false positives will go away. However, for the moment, these are not added. This is future work.Small Things
Currently, we cannot deal with symbolic code. Hence, the test
constructor-diff-deploy
is underignoreTest
. Maybe we could make it work, actually. The deployed code will NEVER have symbolic opcodes, only symbolic values. Hence, it could be possible to change the interpreter to work on this. Future work.Both
parseBlockCtx
andparseTxCtx
have been modified to remove the now very fragilegas
context extraction. This context should pretty much be useless -- code really ought not to depend on gas. We could extract it, but I find that keeping code in that is not tested and not used is just a recipe for later headaches. I'd rather it isn't extracted, and if it really is necessary at a later point, we can extract it.referencedFrameContext
is now usingexprToSMT
, which makes it a lot more standard and less prone to breaking. It was essentially a bug that it wasn't doing that.The
Ord
forProp
was incorrect.POr a b <= POr c d
cannot be compared viaa <= c || b <= d
because in the case tahta == b
andb >d
it will return True, but it should return False. This has been fixed.Git History etc.
Closes #647.
This is an updated version of #650 -- in a way that all commits by Zoe are preserved.
Checklist