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

Add PlutusLedgerApi QuickCheck instances #6624

Open
wants to merge 17 commits into
base: master
Choose a base branch
from

Conversation

t4ccer
Copy link
Contributor

@t4ccer t4ccer commented Nov 1, 2024

Closes #6210

Add Arbitrary, CoArbitrary and Function instances from QuickCheck for every PlutusLedgerApi type. This is a port of instances from https://github.com/Plutonomicon/plutarch-plutus

Pre-submit checklist:

  • Branch
    • Tests are provided (if possible)
    • Commit sequence broadly makes sense
    • Key commits have useful messages
    • Changelog fragments have been written (if appropriate)
    • Relevant tickets are mentioned in commit messages
    • Formatting, PNG optimization, etc. are updated
  • PR
    • (For external contributions) Corresponding issue exists and is linked in the description
    • Targeting master unless this is a cherry-pick backport
    • Self-reviewed the diff
    • Useful pull request description
    • Reviewer requested

@kozross
Copy link
Contributor

kozross commented Nov 5, 2024

@effectfully - would you mind taking a look at this?

@effectfully
Copy link
Contributor

It's on my list, but I can't do it this week, sorry, too many commitments. I'll do my best to review it the next week. Thanks for the reminder.

@effectfully effectfully mentioned this pull request Nov 9, 2024
11 tasks
Copy link
Contributor

@effectfully effectfully left a comment

Choose a reason for hiding this comment

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

Shrinking is broken, coverage is poor, invariants aren't respected. 3k lines of code.

Thank you for opening the PR! We'll process it, split into smaller PRs, fix issues etc.

arbitrary =
UnsafeSizedByteString . BS.pack <$> do
let !len = fromIntegral . natVal $ Proxy @n
vectorOf len arbitrary
Copy link
Contributor

Choose a reason for hiding this comment

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

vectorOf has to force len, so you don't really need a bang here, but it's OK to keep it, I'm only saying it as FYI.


instance KnownNat n => Arbitrary (SizedByteString n) where
{-# INLINEABLE arbitrary #-}
arbitrary =
Copy link
Contributor

Choose a reason for hiding this comment

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

Note to self: when we generate ByteStrings normally we use Text.encodeUtf8 <$> arbitrary. Why? Should we do the same here?

Copy link
Contributor

@kozross kozross Nov 13, 2024

Choose a reason for hiding this comment

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

This guarantees that you get ByteStrings that are UTF-8 encodings of text, which is probably what you often want. However, in a lot of situations here, we're generating arbitrary hashes, which most certainly do not follow this rule.

Copy link
Contributor

Choose a reason for hiding this comment

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

Then we should change this rule in our code in the first place. Thanks!

Comment on lines +36 to +40
instance Arbitrary PlutusTx.BuiltinByteString where
{-# INLINEABLE arbitrary #-}
arbitrary = PlutusTx.toBuiltin @ByteString <$> arbitrary
{-# INLINEABLE shrink #-}
shrink = fmap (PlutusTx.toBuiltin @ByteString) . shrink . PlutusTx.fromBuiltin
Copy link
Contributor

Choose a reason for hiding this comment

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

@Unisay once you're done figuring out what we're supposed to do with ByteString, could you just suggest what we should do here? Is it already fine?

Copy link
Contributor

Choose a reason for hiding this comment

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

So this instance delegates to the Arbitrary ByteString instance.
Assuming the latter is fine, this one should be also fine.

{- | This is a very general instance, able to produce 'PlutusTx.BuiltinData' of
basically any shape. You probably want something more focused than this.
-}
instance Arbitrary PlutusTx.BuiltinData where
Copy link
Contributor

Choose a reason for hiding this comment

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

This is just a reimplementation (a likely worse one) of the already existing Arbitrary Data instance.

this can have zero values, and does not treat the Ada symbol or token name
specially.
-}
instance Arbitrary Value where
Copy link
Contributor

Choose a reason for hiding this comment

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

We have that one as well, except more fine-grained.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should we instead use instance that was in plutus-ledger-api/testlib/PlutusLedgerApi/Test/V1/Value.hs?

Copy link
Contributor

Choose a reason for hiding this comment

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

We should merge ours with yours as both have good and bad things about them. I assume MLabs isn't paid by IOG to do this work?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, current Plutarch work is part of Catalyst project

Copy link
Contributor

Choose a reason for hiding this comment

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

Good to know, thanks. It'll probably take us a lot of time to adopt all of this code tbh, due to other things being considered higher priority. We'll tag you on relevant PRs if we have any improvement suggestions over what you have here. Thanks again for creating this PR, we'll keep it open for now and we'll see how it goes with adopting your code.

2. It is difficult to work within the size limit (32 bytes) when generating
UTF-8.
-}
instance Arbitrary TokenName where
Copy link
Contributor

Choose a reason for hiding this comment

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

This one we definitely need to steal.

described above: failing to do so means all guarantees of this type are off
the table.
-}
newtype MintValue = MintValue Value
Copy link
Contributor

Choose a reason for hiding this comment

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

We now have our own MintValue type with its generator.

Copy link
Contributor Author

@t4ccer t4ccer Nov 14, 2024

Choose a reason for hiding this comment

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

Could you point me to that please? This is also "old" mint value, i.e. for V1 and V2 that has zero ADA entry, our V3 MintValue has that omitted

Copy link
Contributor

@effectfully effectfully Nov 14, 2024

Choose a reason for hiding this comment

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

PlutusLedgerApi.V3.MintValue.MintValue and the generator is in PlutusLedgerApi.Test.V3.MintValue. Ours is probably broken though, we need to fix it.

arbitrary = error "No such 'Arbitrary' instance"
shrink _ = []

instance Arbitrary Value where
Copy link
Contributor

Choose a reason for hiding this comment

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

That's bold haha.

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.

QuickCheck Arbitrary instances for Ledger types
4 participants