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

PLT-3564 PLT-6070 PLT-6071 PLT-6072 PLT-6073 PLT-5817 Safety checks for REST and CLI #622

Merged
merged 15 commits into from
Jun 24, 2023

Conversation

bwbush
Copy link
Collaborator

@bwbush bwbush commented Jun 20, 2023

Added safety analysis report to creation of contracts into marlowe-runtime-web and marlowe-runtime-cli.

Pre-submit checklist:

  • Branch
    • Tests are provided (if possible)
    • Test report is updated (if relevant)
    • Commit sequence broadly makes sense
    • Key commits have useful messages
    • Relevant tickets are mentioned in commit messages
    • Formatting, PNG optimization, etc. are updated
  • PR
    • Self-reviewed the diff
    • Useful pull request description
      • Review required
      • Substantial changes to code, test, or documentation
      • Change made to Marlowe validator (@bwbush and @palas must be included as reviewers)
      • Review not required
      • Minor changes to non-critical code, documentation, nix derivations, configuration files, or scripts
      • Formatting, spelling, grammar, or reorganization
    • Reviewer requested

@bwbush bwbush self-assigned this Jun 20, 2023
@bwbush bwbush marked this pull request as ready for review June 21, 2023 14:15
@paluh paluh self-requested a review June 21, 2023 15:30
Comment on lines 190 to 196
(ContractId contractId, safetyErrors) <- run MarloweV1 minting'
liftIO
$ if null safetyErrors
then hPutStrLn stderr "Safety analysis found no errors in the contract."
else do
hPutStrLn stderr "Safety analysis found the following errors in the contract:"
BS8.hPutStrLn stderr $ Yaml.encode safetyErrors
Copy link
Collaborator Author

@bwbush bwbush Jun 21, 2023

Choose a reason for hiding this comment

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

Safety errors are printed as YAML to stderr. Another approach would have been to have these written to a file.

@@ -143,7 +143,7 @@ instance Arbitrary Web.PostTransactionsRequest where
shrink = genericShrink

instance Arbitrary (Web.CreateTxEnvelope tx) where
arbitrary = Web.CreateTxEnvelope <$> arbitrary <*> arbitrary
arbitrary = Web.CreateTxEnvelope <$> arbitrary <*> arbitrary <*> resize 5 arbitrary
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The property-based tests become slow if we let large contracts/transactions be generated in the Arbitrary instance for safety errors. Five seems a good enough size limit here.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, that seems fine

@@ -214,6 +219,14 @@ getOptions = execParser $ info (helper <*> parser) infoMod
, showDefault
]

analysisTimeoutParser = option (fromInteger <$> auto) $ mconcat
[ long "analysis-timeout"
, value 15
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The slow phase of the safety analysis is limited to 15 seconds by default, at the marlowe-tx level.

Comment on lines 238 to 240
. either
(pure . TransactionValidationError transaction . show)
(const $ TransactionWarning transaction <$> V1.txOutWarnings txOutput)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Failures in the analysis of safety are server errors, but the results of successful safety analysis are returned as [SafetyError].

Comment on lines 318 to 319
-- Fast analysis of safety: examines bounds for transactions.
contractSafetyErrors = checkContract networkId roleTokens version contract' continuations
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

There is no time limit on the fast analysis of safety, because that doesn't use z3 to find all paths through the contract and it doesn't execute any Plutus transactions.

Comment on lines +127 to +121
, "detail" .= ("No roles are present in the contract, but a roles currency was specified." :: String)
, "fatal" .= False
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Marked as non-fatal because an extraneous roles policy ID doesn't affect execution.

Comment on lines +140 to +135
, "detail" .= ("This role token was specified for minting, but that role is not present in the contract." :: String)
, "role-name" .= String (T.decodeUtf8 $ fromBuiltin tokenName)
, "fatal" .= False
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Marked as non-fatal because minting an extra role token doesn't affect execution.

Comment on lines 205 to 204
, "detail" .= ("At some point in during its executation, the contract may hold more native tokens than permitted by the ledger rules." :: String)
, "bytes" .= natural
, "fatal" .= False
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Marked as non-fatal because this is an estimate, and the slow analysis would identify if this truly occurs in any transaction.

, "detail" .= ("This transaction's size may exceed the limit permitted by the ledger rules." :: String)
, "transaction" .= transaction
, "bytes" .= natural
, "fatal" .= False
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Marked as non-fatal because this is an estimate, and the slow analysis would identify if this truly occurs in any transaction.

, "detail" .= ("This transaction's Plutus execution cost may exceed the limit permitted by the ledger rules." :: String)
, "transaction" .= transaction
, "cost" .= exBudget
, "fatal" .= False
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Marked as non-fatal because this is an estimate, and the slow analysis would identify if this truly occurs in any transaction.

, "detail" .= ("A Marlowe semantics warning is reported for this transaction." :: String)
, "transaction" .= transaction
, "warning" .= warning
, "fatal" .= False
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Marked as non-fatal because semantics warnings don't prevent execution.

Comment on lines +244 to +243
, "detail" .= ("The contract is missing a continuation that is not present in its map of continuations." :: String)
, "hash" .= toJSON (EncodeBase16 $ fromBuiltin datumHash)
, "fatal" .= False
Copy link
Collaborator Author

@bwbush bwbush Jun 21, 2023

Choose a reason for hiding this comment

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

Should this be fatal or non-fatal? One might choose to not supply the full set of continuations for analysis.

Comment on lines 296 to 297
, "detail" .= ("The safety analysis exceeded the allotted time." :: String)
, "fatal" .= False
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Should this be fatal or non-fatal?

@bwbush bwbush requested review from nhenin, palas and jhbertra June 21, 2023 17:34
@bwbush
Copy link
Collaborator Author

bwbush commented Jun 21, 2023

@palas and @paluh, please comment on which safety errors should be flagged to the user as "fatal" or "non-fatal" in marlowe/src/Language/Marlowe/Analysis/Safety/Types.hs. This seems somewhat subjective.

@bwbush bwbush force-pushed the PLT-5817 branch 2 times, most recently from aec3a6b to 346a17b Compare June 21, 2023 17:48
@@ -360,6 +361,7 @@ in

marlowe-tx = mkOperableWithProbes {
package = marlowe-tx;
runtimeInputs = [ z3 ];
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@jhbertra, is this the only derivation where the new runtime dependency of marlowe-tx on z3 will need to be added?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this needs to be added to compose.nix as well. You could add this to run-local-service:

export PATH="$PATH:${lib.makeBinPath [ z3 ]}"

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 34f1d7e.

, NonPositiveBalance <$> arbitrary <*> arbitrary
, DuplicateAccount <$> arbitrary <*> arbitrary
, DuplicateChoice <$> arbitrary
, DuplicateBoundValue <$> arbitrary
Copy link
Contributor

@nhenin nhenin Jun 22, 2023

Choose a reason for hiding this comment

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

FYI @bwbush :

I don't know if DuplicateChoice, DuplicateBoundValue are the same things but next handles cases where some inputs are shadowed by the previous ones ... next doesn't propose invalid applies...

For Deposit, next also handle Identical Evaluated Deposits... something we can't really check at "compile" time, but is 2 identical deposits in a when regardless their value could be considered as a warning ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

These Duplicate... warnings apply to the state of the contract, not to actions like deposits.

instance ToJSON SafetyError where
toJSON MissingRolesCurrency =
object
[ "error" .= ("MissingRolesCurrency" :: String)
Copy link
Contributor

Choose a reason for hiding this comment

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

It's surprising that you need to help the type inference to serialize here (xxxx:: String)

Copy link
Contributor

@jhbertra jhbertra Jun 22, 2023

Choose a reason for hiding this comment

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

Not at all, with OverloadedStrings the type of a string literal is polymorphic, because it is desugarred as

fromString ("MissingRolesCurrency" :: String)

And in this context, we have

(.= "error") :: forall a. ToJSON a => a ->Pair

So the type a is polymorphic in both its introduction (the output of fromString) and elimination (the input of (.= "error")), thus ambiguous.

@@ -1,3 +1,5 @@
-- editorconfig-checker-disable-file
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we remove this ? now that we disabled the feature ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, can remove

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 34f1d7e.

, containers
, eventuo11y >=0.9 && <0.11
, eventuo11y >=0.9 && <0.11
Copy link
Contributor

@nhenin nhenin Jun 22, 2023

Choose a reason for hiding this comment

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

@bwbush you have confilcts with the cabals you have modified and the main because of the formatter .... maybe you should do a cabal-fmt --inplace --no-tabular **/*.cabal in your commits before rebasing...

Copy link
Contributor

Choose a reason for hiding this comment

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

If you rebase and run pre-commit run --all this should be reverted now.

Copy link
Contributor

Choose a reason for hiding this comment

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

although hlint will fail until #626 is merged.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 34f1d7e.

@@ -1,3 +1,5 @@
-- editorconfig-checker-disable-file
Copy link
Contributor

Choose a reason for hiding this comment

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

You can get rid of this now

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 34f1d7e.

@@ -1,3 +1,5 @@
-- editorconfig-checker-disable-file

Copy link
Contributor

Choose a reason for hiding this comment

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

Can remove

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 34f1d7e.

Added
-----

- Create command outputs results of contract safety analysis.
Copy link
Contributor

Choose a reason for hiding this comment

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

This shouldn't have its own changelog.d folder - this is part of the marlowe-runtime component, not a separate one

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks. We should probably document which folders should not have change logs.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 34f1d7e.

Added
-----

- Fifteen-second timeout for contract safety analysis.
Copy link
Contributor

Choose a reason for hiding this comment

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

We are not doing changelog tracking in this folder

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 34f1d7e.

@@ -1,7 +1,8 @@
-- editorconfig-checker-disable-file

Copy link
Contributor

Choose a reason for hiding this comment

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

can remove

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 34f1d7e.

@@ -1,3 +1,5 @@
-- editorconfig-checker-disable-file

Copy link
Contributor

Choose a reason for hiding this comment

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

can remove

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 34f1d7e.

@@ -1,3 +1,5 @@
-- editorconfig-checker-disable-file

Copy link
Contributor

Choose a reason for hiding this comment

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

can remove

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 34f1d7e.

@@ -1,3 +1,5 @@
-- editorconfig-checker-disable-file

Copy link
Contributor

Choose a reason for hiding this comment

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

can remove

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 34f1d7e.

@@ -1,3 +1,5 @@
-- editorconfig-checker-disable-file

Copy link
Contributor

Choose a reason for hiding this comment

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

can remove

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 34f1d7e.

@@ -1,3 +1,5 @@
-- editorconfig-checker-disable-file

Copy link
Contributor

Choose a reason for hiding this comment

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

can remove

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 34f1d7e.

@@ -1,3 +1,5 @@
-- editorconfig-checker-disable-file

Copy link
Contributor

Choose a reason for hiding this comment

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

can remove

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 34f1d7e.

txInput <- semiArbitrary context
txOutput <- arbitrary
pure Transaction{..}
shrink _ = mempty
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't we shrink this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I was undecided, but it is harmless to shrink this. Fixed in 34f1d7e.

(changeAddress addresses)
(toInteger minAda)
contract'
continuations
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this actually work? Aren't the safety errors lazily computed in checkTransactions? Z3 will run in IO, so that's fine, that will run in the eval thread, but at the end we have

      either throwE (pure . mconcat)
        . forM transactions
        $ checkTransaction solveConstraints version marloweContext rolesCurrency changeAddress

Which is a bit complex to reason about regarding laziness. Ultimately, the final IO action depends on pattern matching the Either returned by forM, and transitively from each call to checkTransaction, so that will force the evaluation of the fake solveConstraints calls. The only unevaluated expressions here would be pure . TransactionValidationError transaction . show and const $ TransactionWarning <$> V1.txOutWarnings txOutput. How slow is txOutWarnings?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The txOutWarnings is fast because it is computed from the semantics, not from executing Plutus. However, I think we should demonstrate this as a test case, so I've created the separate ticket PLT-6362.

Copy link
Contributor

@jhbertra jhbertra left a comment

Choose a reason for hiding this comment

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

Looks great, thanks! Just the one question about the timeout and laziness. And some stuff that needs addressing once rebasing happens on #626

@bwbush bwbush merged commit 9e412eb into main Jun 24, 2023
@bwbush bwbush deleted the PLT-5817 branch June 24, 2023 01:40
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