-
Notifications
You must be signed in to change notification settings - Fork 1
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
SCP-4107 MIP for universal validator #1
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
--- | ||
MIP: 3 | ||
Title: Universal Validator | ||
Authors: Brian W Bush <brian.bush@iohk.io> on behalf of Alexander Nemish | ||
Comments-Summary: No comments yet. | ||
Comments-URI: https://github.com/input-output-hk/MIPs/wiki/Comments:MIP-0003 | ||
Status: Draft | ||
Type: Standards | ||
Created: 2022-07-20 | ||
License: CC-BY-4.0 | ||
--- | ||
|
||
|
||
## Abstract | ||
|
||
This document describes a modification to the token-minting process for Marlowe and the unification of the minting of role tokens and the operation of the Marlowe application or payout validators. Although it requires a change to the `Language.Marlowe.Core.V1.Semantics.MarloweParams` datatype that will eliminate some use cases for role tokens, it will enforce certain new guarantees on the role-token usage. | ||
|
||
|
||
## Motivation | ||
|
||
Role tokens are a primary means of authorizing deposits and choices by a party to a Marlowe contract. However, Marlowe currently has no on-chain guarantee for the minting policy of role tokens. On the contrary, any monetary policy (i.e., simple script or Plutus script) may be used for the role tokens in a Marlowe contract. The only on-chain constraint for role tokens is that all of the role tokens in a particular contract have the same monetary policy or currency symbol. | ||
|
||
The lack of an on-chain guarantee for the role-token monetary policy opens Marlowe to several off-chain vulnerabilities: For example, a Marlowe contract might be created for role tokens having an open monetary policy that allows additional role tokens to be created after the contract commences. The controller of that monetary policy could mint duplicate role tokens for parties in the contract and impersonate them, authorizing without consent transactions using the duplicate tokens. | ||
|
||
Thus, enforcing that each role tokens be a minted only once provides a security guarantee that duplicate role tokens will not be later minted and those duplicates used for role-based authorization of Marlowe choices and deposits. It also provides an option for minting true non-fungible native role tokens (that there is provably only ever one minted) if minting is limited to exactly one token per role. | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we take a step back and consider what these "on chain" guarantees mean for the Marlowe users?
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's try to sketch a possible "Marlowe policy tracking" schema. It is a replacement for a unified validator which preserves Scope limitI focus here on the policy tracking so I skipped details regarding Typesdata PolicyParams = PolicyParams
{ ppTxOutRef :: TxOutRef
, ppRoles :: List TokeName -- Left for simplicity.
-- We can probably replace this list by just a `hash`.
}
data MarloweEnv = MarloweEnv
{ marloweData :: MarloweData
, marloweParams :: MarloweParams
, policyParams :: PolicyParams
} Verification flow:Inputs
Verification procedure
ImplementationMinting policyConstant:
Parameters:
Checks:
Marlowe validatorChecks related to "policy tracking"
Execution
Sketch of the proofA proper proof should be provided but the sketch of the reasoning could look like this:
Pros / ConsComming soon... ;-) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So it uses one special token that the validator never lets go of and burns at the end. And we know the special token is unique because that is enforced by the minting policy, and we know that a validator that has it necessarily comes from the minting policy cause that is the only way of getting the token. Very clever :) I cannot see any problems with the idea at the moment, but yes it is going to be tricky to make sure there really aren't subtleties There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure if it has any practical meaning or sens what I'm going to write now so please just ignore it if it doesn't ;-) In merkleized case if we would like to merkleize role distribution as well we probably wanted to have a bit different strategy because roles would be minted throughout the execution of the contract. Side note: I think that this policy driven execution stepper could be generalized further. It can be a base for "a library" of composable constant functions on the chain. Composition would be done through a minting policy which takes a "plan" of the execution as parameter (ordered list of functions representing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a viable approach that solves the same currency-lookup problem that the universal validator does. However, in increase the transaction size (larger validator and extra token) and execute cost (more logic) and memory (larger script context). Is that worth it? The spending validator probably doesn't a need "singleton continuation" check because A variation of this approach (and the DSL) could open possibilities for minting additional role tokens while a contract is running. As you point out, something along these lines could BTW, if we had used a I'm a little concerned about the use of a blank token name There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Of course verification schema gonna change. In such a case we have to just grab the whole history to discover that "non minting policy" was a valid choice. Unfortunately we also need info now about the actual validator address etc. so maybe it is just better to mint the thread token - it is not a significant overhead. Under the table I put few comments. I would like to have really focused discussion which properties from the table are seriously meaningful and estimate more precisely what are the differences for this meaningful properties. I would also like to have some perspective and evaluation of the flexibility and ease of reasoning regarding different approaches. I sketched above on demand minting schema for merkleized role distribution... it would be nice to have a set of solutions to this kind of variations and evaluate them. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @palas At the end I think that having uniform thread token based architecture ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't necessarily think that tracking There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Regarding There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In principle we can reserve for |
||
|
||
## Specification | ||
|
||
### Version | ||
|
||
This change comprises a new version of the Plutus validators for Marlowe. | ||
|
||
|
||
### `MarloweParams` | ||
|
||
The `MarloweParams` that parameterize the universal validator must depend upon the `TxOut` consumed in the minting process, rather than the `CurrencySymbol` as is presently the case. | ||
|
||
|
||
### Plutus Validator | ||
|
||
The same Plutus script that validates Marlowe spending transactions must be also used to mint role tokens. | ||
|
||
|
||
#### Minting | ||
|
||
When used for minting role tokens, this "universal validator" must enforce the following constraints: | ||
1. The validator is parameterized by a `TxOut` that it consumes when minting tokens. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can also consider a hybrid which takes |
||
2. The `Redeemer` for the validator is the list of roles (i.e., token names) that will be minted, along with the number of tokens minted on a role-by-role basis. | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should allow the monetary policy script to burn tokens, without constraint. This would be a simple change to Alex's validator. This doesn't decrease the security of Marlowe contracts because owners are always at risk of losing their private keys to the wallet where the token resides, sending the token into oblivion, etc. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that sounds better than not allowing burning at all. Maybe eventually we can think of a way of requiring the contract to be closed for burning There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We'd need to leave the contract on the chain (just with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess leaving the contract on-chain is pretty similar to not burning the tokens |
||
|
||
### Spending | ||
|
||
When used for spending UTxOs in order to advance a Marlowe contract in a transaction involving role-base authorization for a choice or deposit, the validator must compute the the `CurrencySymbol` for the role tokens from the `MarloweParams`. | ||
|
||
|
||
## Rationale | ||
|
||
Requiring the validator to be parameterized by a `TxOut` that it consumes when minting tokens ensures that each minting transaction creates tokens with a unique monetary policy or currency symbol. | ||
|
||
Requiring the spending validator to compute the the `CurrencySymbol` for the role tokens from the `MarloweParams`, which in turn depends upon the `TxOut` consumed during minting, ensures that the currency symbol is unique to the *spending validator*, which also depends upon `MarloweParams`. | ||
|
||
Thus, having the `MarloweParams` parameterize the universal validator via that `TxOut` consumed in the minting process, rather than the `CurrencySymbol`, inexorably ties the minting validator to the spending validator. The present Marlowe validator's use of `CurrencySymbol` in its `MarloweParams` allows it to accept *any* currency symbol for role tokens, but this MIP's use of the `TxOut` in the `MarloweParams` for the *universal* validator ensures that the spending validator can only use tokens minted by minting validator because both these validators are *one and the same*. | ||
|
||
Note that the MIP forbids three potentiallly important and presently possible use cases: | ||
1. Customized monetary policies. *Some Marlowe dApps (e.g., DAOs or centrally administered applications) would benefit from supervisory control via a sophisticated minting policy.* | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was thinking the same thing, some of Marlowe's limitations due to its static nature could be overcome by using custom monetary policies. At the same time, even if we only maintain/support one particular validator, it doesn't mean that someone could write/fork a validator that follows Marlowe's semantics with a custom monetary policy (although it would be much harder than using the official one) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a potential solution, though I think it's far more likely that we would do this ourselves as part of delivering a system to a large client. This would be expensive though, as we would need to get the forked validator audited and certified separately. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, and if we make a version of the validator we will need a corresponding supporting version of the runtime, etc. From the point of view of the audit, I don't think it makes a difference, because the audit results will at best be subject to the monetary policy (independently of whether it is in or outside of the validator). But from the security point of view, not having the monetary policy fixed by the version of the validator would open the door for attacks that would be pretty tricky to communicate to the user, since the monetary policy can be anything, the best we can do is tell the user it is not standard if its hash doesn't belong to a list (or something like this, I guess). On the other hand, if we extend the validator to be cleverer and handle the monetary policy, we could manually add support in the future for specific behaviours like the ones you suggest, and then we can explain them to the user easily There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
2. Minting of additional role tokens after the original minting. *There may be certain crowd-oriented Marlowe dApps where this is desirable.* | ||
3. Burning of role tokens after a contract completes. *This makes it impossible ever to recover the minimum Ada associated with a role token, thus effectively increasing the up-front cost of Marlowe contracts.* | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need to burn tokens after a contract complete? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unburnable tokens are a waste of ADA. |
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I’m not completely sure that moving Perhaps we should implement SCP-4107 and SCP-4174 at the same time? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you explain why the spending script could not depend on the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
It currently does, but it is desirable for the spending script not to depend upon any parameters because then it could be used as a reference script for every Marlowe contract. If the spending script depends upon a parameters, then we'd need one reference script for each parameter set. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see having a single Marlowe interpreter (per version) across the whole chain a really huge possible optimization strategy. We are now struggling with transaction size limits and this clearly impacts further development of the Language itself. I want to strongly emphasize that we possibly lose a huge benefit of our architecture which is based on a constant language interpreter. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we add There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This method is indeed compatible with a single Marlowe interpreter across the whole chain, if the monetary policy enforces that the |
||
|
||
## Backwards Compatibility | ||
|
||
This alteration to the validator is not backward compatible with the following Marlowe components: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we both maintain backwards compatibility and support custom minting policies if we change data MarloweParams =
MarloweParams -- Previously.
{
rolePayoutValidatorHash :: ValidatorHash
, rolesCurrency :: CurrencySymbol
}
| MarloweUniversalParams -- This MIP.
{
rolePayoutValidatorHash :: ValidatorHash
, uniqueTxOutRef :: (TxId, Integer)
} and make some minor adjustments where There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we care that much about backward compatibility? We do have the advantage that Marlowe isn't currently used in real-world solutions (can we verify this assumption?) which means we can afford to break backwards compatibility without causing significant disruption. I would just make this a clean break at this point, essentially invalidating all legacy Marlowe contracts, as they are all 100% test contracts anyway. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If at some point in the future we want to do this, we could use GADTs and type parameters to carry a witness of validator versions at the type level (like the hard-fork combinator does in Cardano Node): data MarloweParams (version :: ValidatorVersion) where
MarloweParamsV0
:: ValidatorHash
-> CurrencySymbol
-> MarloweParams ValidatorV0
MarloweParamsV1
:: ValidatorHash
-> TxOutRef
-> MarloweParams ValidatorV1
But at least for now, I don't think the added complexity is worth it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I much prefer the GADT approach, though we'd have to make sure this is compatible with the Plutus compiler. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Based on the discussion so far, I propose we not include this flexibility to the old-style |
||
* Marlowe backend, `Language.Marlowe.Client` | ||
* Marlowe CLI, `marlowe-cli` | ||
* Marlowe Run, `marlowe-dashboard-server` | ||
* Marlowe history, `Language.Marlowe.Client.History` | ||
* Marlowe test cases | ||
* Marlowe Pioneer Program lectures | ||
Comment on lines
+76
to
+81
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All of these components are soon going to be superseded by runtime-based versions anyway. And we can still run the legacy code if we need to. |
||
|
||
|
||
## Path to Active | ||
|
||
In implementation is proposed in [marlowe-cardano PR#117](https://github.com/input-output-hk/marlowe-cardano/pull/117). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've merged the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure but maybe it would be valuable to include some summary about the implementation here? From my perspective it is worth mentioning that we are doing here a "unification" of miniting policy script and spending script which have completely different types! We should ask ourselves - is this proper usage of this technology which should provide as guarantees through types? From my perspective this solution requires a lot of "low level hackery" and makes our on chain code pretty hard to understand but of course I'm not proficient plutus coder so my point may be invalid. I wonder how spread this idiom is in the larger plutus community. Are there any other idioms which we can adopt? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point. Are we bypassing any checks by doing this? One thing related to this to consider too is that we may be using an "unintended feature", so maybe in the future, a new version of Plutus or the ledger could prevent us from continuing doing this? We could have this as a temporary hack and liaise with Plutus to potentially get a less hacky way of doing this same thing, or at least making sure it doesn't get disabled There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I carefully reviewed the proposed implementation, and it doesn't by bypass any checks. It may tie the validator to Plutus V1 or V2, because we don't know what Plutus V3+ will contain. |
||
|
||
|
||
## Copyright | ||
|
||
This MIP is licensed under [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/legalcode). |
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 this MIP a requirement for having Universal Validator and being able to utilize reference scripts to reduce the transaction size or is that independent?
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.
This MIP is independent of reference scripts, but we could modify this MIP to better support reference scripts by moving
MarloweParams
into theDatum
.