tweag / cooked-validators

MIT License
39 stars 11 forks source link

Split mockchain tweaks #210

Closed carlhammann closed 1 year ago

carlhammann commented 1 year ago

This PR brings back the tweaks and attacks in the context of a MonadBlockChainWithoutValidation. This was the motivation to split MonadBlockChain in the first place (see PR #212).

The new tweak interface

The split allows us to define the interface for tweaks like so:

class (MonadPlus m, MonadBlockChainWithoutValidation m) => MonadTweak m where
  getTxSkel :: m TxSkel
  putTxSkel :: TxSkel -> m ()

That means:

For any monad m that is a MonadBlockChainWithoutValidation, the type

type Tweak m = StateT TxSkel (ListT m)

will have an obvious implementation of MonadTweak, and that's what we'll use in the implementation of the staged monad.

It's worth noting that, while this is quite a substantial low-level change, the higher levels of the tweak language are relatively unaffected. The changes in the bigger attacks like addTokenAttack, datumHijackingAttack, doubleSatAttack, and dupTokenAttack, as well as their tests, are mostly syntactical.

There's one problem with the new interface: Since awaitTime and awaitSlot are part of MonadBlockChainWithoutValidation, we can now have tweaks that alter a transaction by waiting before submitting it. This feature is useful, but sometimes it's too powerful. As this comment in the doubleSatAttack illustrates, there are situations when the ability to wait (and therefore alter the state of the chain) is too powerful. In principle, this problem could be solved by introducing another level "MonadBlockChainWithoutValidationAndWaiting" and have some tweaks live on that lowest level, where only lookups are possible. The power of these tweaks would not be greater than what we already have, but the common interface with MonadBlockChain would still be nice to have.

Clean-up of the "optic tweaks"

You'll see quite a substantial reduction in the size of Cooked.Attack.Tweak.Common. Most of that has to do with the fact that I threw out mkTweak and its more cumbersome friends (like mkAccumLTweak) in favour of a few variations on the theme "go through all foci and (optionally) change something about them".

What you'll also find in this PR

This PR incorporates many commits from #207, because I needed a proper pretty-printer while debugging the attack language. So, it might make sense to compare it with that work.

It also incorporates many "convenience functions" for querying the state of the chain. Almost all of the changes in Cooked.MockChain.Monad and Cooked.Tx.Constraints.Type can be understood as such.