# Extending Ensure for non Templates

**URL:** <https://forum.canton.network/t/extending-ensure-for-non-templates/2472>\
**Category:** App Development\
**Created:** [April 19, 2021, 1:12am UTC](https://forum.canton.network/t/extending-ensure-for-non-templates/2472 "2021-04-19T01:12:47Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![Leonid\_Rozenberg](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/leonid_rozenberg/32/48_2.png) [@Leonid\_Rozenberg](https://forum.canton.network/u/Leonid_Rozenberg)\
**Post date:** [April 19, 2021, 1:12am UTC](https://forum.canton.network/t/extending-ensure-for-non-templates/2472/1 "2021-04-19T01:12:47Z")

</div>

There have been previous questions on the forum around smart constructors and the use of [newtype](https://wiki.haskell.org/Newtype)’s to have fine grain control over types without the extra boxing burden. One way to verify that one’s on ledger data complies is wrap the check for validity into the precondition [ensure](https://docs.daml.com/daml/reference/templates.html#preconditions) clause of a `Template`.

That is easy enough with a custom type class, ex

```haskell
newtype Price = Price { p : Decimal }
  deriving (Eq, Ord, Show)

class Ensurable a where
  valid : a -> Bool

instance Ensurable Price where
  valid Price { p } = p >= 0.0

```

and then

```haskell
template Good
  with
    seller : Party
    asset : Text
    price : Price
  where
    signatory seller
    ensure valid price

```

Three related questions:

1. It seems that one cannot reuse the `HasEnsure` type class for this purpose as:

```haskell
instance HasEnsure Price where
  ensure Price { p } = p >= 0.0

```

leads to

> $ daml build  
> Compiling training to a DAR.  
> File: daml/Ensureable.daml  
> Hidden: no  
> Range: 1:1-2:1  
> Source: Core to DAML-LF  
> Severity: DsError  
> Message:  
> Failure to process DAML program, this feature is not currently supported.  
> Missing required instances in template definition. with (:).  
> [T, y, p, e, C, o, n, N, a, m, e, , {, u, n, T, y, p, e, C, o, n,  
> N, a, m, e, , =, , [, ", P, r, i, c, e, ",], }]  
> ERROR: Creation of DAR file failed.

Is this intentional? I could imagine that if we were to reuse it for non Template, data that it could be confusing as the default semantics would not execute the `ensure` check on `price` (assuming it has a `HasEnsure` instance) unless specifically asked.

1. On the flip side, if the check was automatic it could extend the usefulness of the type class. And the broad notion of a precondition check would not need to be separated into different type classes. This automatic behavior could be particularly useful as one would not have to nest all of your data in `Ensurable`, just the “leaf” element where one defines custom types. But at the surprise of performing computation that is not explicitly defined in a template.

2. Are there other considerations to adopting these precondition checks to data types? I can see that it could hinder performance (or at least lead to surprising behavior), as that check gets called on every creation. For example, a consuming choice that updates another field but does not modify a `Price` in this example would lead to another check of the Price’s validity on the creation of the choice’s output. Furthermore, I assume the nesting `Ensurable`’s would incur a cost that has to be paid at construction. For example, if I were to have a `type Inventory = TextMap Price`, no way around walking the map?

---

<div class="post-metadata">

**Author:** ![Luciano](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/luciano/32/319_2.png) [@Luciano](https://forum.canton.network/u/Luciano)\
**Post date:** [April 19, 2021, 6:53am UTC](https://forum.canton.network/t/extending-ensure-for-non-templates/2472/2 "2021-04-19T06:53:05Z")

</div>

> [@Leonid\_Rozenberg](#):
>
> There have been previous questions on the forum around smart constructors and the use of [newtype](https://wiki.haskell.org/Newtype)’s to have fine grain control over types without the extra boxing burden.

An aside here: to the best of my knowledge, `newtype` just de-sugars into plain old `data`, at the time of writing (meaning types are still ‘boxed’). I don’t know if there’s any plan to change that.

---

<div class="post-metadata">

**Author:** ![cocreature](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/cocreature/32/36_2.png) [@cocreature](https://forum.canton.network/u/cocreature)\
**Post date:** [April 19, 2021, 6:59am UTC](https://forum.canton.network/t/extending-ensure-for-non-templates/2472/3 "2021-04-19T06:59:48Z")

</div>

1. Starting with the easy question: Yes it is intentional that hand-written `HasEnsure` instances don’t work. The same is true for a lot of other `Has*` classes. We use those internally in the compiler to translate templates.

For 2 and 3, see [Should runtime/API respect namespace scopes?](https://discuss.daml.com/t/should-runtime-api-respect-namespace-scopes/2114) for some related discussion. I think you can make this work but it needs a whole bunch of changes across the stack.

---

<div class="post-metadata">

**Author:** ![Gary\_Verhaegen](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/gary_verhaegen/32/81_2.png) [@Gary\_Verhaegen](https://forum.canton.network/u/Gary_Verhaegen)\
**Post date:** [April 19, 2021, 8:56am UTC](https://forum.canton.network/t/extending-ensure-for-non-templates/2472/4 "2021-04-19T08:56:13Z")

</div>

> [@Leonid\_Rozenberg](#):
>
> ```haskell
> template Good
> with
> seller : Party
> asset : Text
> price : Price
> where
> signatory seller
> ensure valid price
> 
> ```

Isn’t that validation purely client-side when there’s only one signatory anyway?

---

<div class="post-metadata">

**Author:** ![Leonid\_Rozenberg](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/leonid_rozenberg/32/48_2.png) [@Leonid\_Rozenberg](https://forum.canton.network/u/Leonid_Rozenberg)\
**Post date:** [April 19, 2021, 1:56pm UTC](https://forum.canton.network/t/extending-ensure-for-non-templates/2472/5 "2021-04-19T13:56:07Z")

</div>

@Luciano Thanks, you’re right!

---

<div class="post-metadata">

**Author:** ![Leonid\_Rozenberg](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/leonid_rozenberg/32/48_2.png) [@Leonid\_Rozenberg](https://forum.canton.network/u/Leonid_Rozenberg)\
**Post date:** [April 19, 2021, 1:59pm UTC](https://forum.canton.network/t/extending-ensure-for-non-templates/2472/6 "2021-04-19T13:59:55Z")

</div>

@Gary_Verhaegen I don’t fully understand. The `ensure` is validated by the Daml driver, how would it happen on the client-side? Or by “client-side” did you mean exclusively visible to the `seller`?

I created a single signatory template for ease of demonstration.

---

<div class="post-metadata">

**Author:** ![Gary\_Verhaegen](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/gary_verhaegen/32/81_2.png) [@Gary\_Verhaegen](https://forum.canton.network/u/Gary_Verhaegen)\
**Post date:** [April 19, 2021, 2:23pm UTC](https://forum.canton.network/t/extending-ensure-for-non-templates/2472/7 "2021-04-19T14:23:58Z")

</div>

Cursory testing shows this is indeed validated server-side upon submission of a `create` command, so it’s not as bad as I thought. I believe there can still be issues with dishonest participants in a distributed context, but that’s way to far outside my comfort zone for me to make any specific pronouncement.

---

<div class="post-metadata">

**Author:** ![bernhard](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/bernhard/32/356_2.png) [@bernhard](https://forum.canton.network/u/bernhard)\
**Post date:** [April 20, 2021, 8:25am UTC](https://forum.canton.network/t/extending-ensure-for-non-templates/2472/8 "2021-04-20T08:25:54Z")

</div>

`ensure` clauses are fully validated by all Daml integrations. The only thing a dishonest participant can do is to “create” a contract instance violating the `ensure` clause locally, involving only parties hosted exclusively on that participant, and then use the contract in that same context.  
As soon as another participant sees a transaction involving a contract with an invalid `ensure` clause, they will reject that transaction as invalid.

---

<div class="post-metadata">

**Author:** ![Gary\_Verhaegen](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/gary_verhaegen/32/81_2.png) [@Gary\_Verhaegen](https://forum.canton.network/u/Gary_Verhaegen)\
**Post date:** [April 20, 2021, 9:37am UTC](https://forum.canton.network/t/extending-ensure-for-non-templates/2472/9 "2021-04-20T09:37:38Z")

</div>

Thanks for the clarification!

---

<div class="post-metadata">

**Author:** ![Leonid\_Rozenberg](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/leonid_rozenberg/32/48_2.png) [@Leonid\_Rozenberg](https://forum.canton.network/u/Leonid_Rozenberg)\
**Post date:** [April 20, 2021, 2:17pm UTC](https://forum.canton.network/t/extending-ensure-for-non-templates/2472/10 "2021-04-20T14:17:14Z")

</div>

> [@bernhard](#):
>
> with an invalid `ensure` clause,

For clarification, this would be an entirely different contract?

---

<div class="post-metadata">

**Author:** ![bernhard](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/bernhard/32/356_2.png) [@bernhard](https://forum.canton.network/u/bernhard)\
**Post date:** [April 20, 2021, 2:51pm UTC](https://forum.canton.network/t/extending-ensure-for-non-templates/2472/11 "2021-04-20T14:51:44Z")

</div>

What I mean is this:

1. I submit `create Good with seller = Bernhard; asset = "An original drawing by me"; price = -9000.0` on my dishonest participant. Depending on the driver I’m running on, this may not get validated by anyone else because in fact nobody else even learns of this.
2. Now suppose I’ve got some way of “offering” that `Good` to you. Eg by divulging the contract as part of the creation of a `GoodOffer`. Your participant will validate the ensure clause of the `Good` contract it receives and reject the transaction as invalid. Except in circumstances where my participant is a trusted “VIP”, that means the consensus will be to reject the transaction. If you participant decides to record it anyway, it can do so, but what good is that… Like the original `Good` contract, any outputs from the `GoodOffer` will be unusable since everyone else has rejected it.

---

<div class="post-metadata">

**Author:** ![Leonid\_Rozenberg](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/leonid_rozenberg/32/48_2.png) [@Leonid\_Rozenberg](https://forum.canton.network/u/Leonid_Rozenberg)\
**Post date:** [April 20, 2021, 3:10pm UTC](https://forum.canton.network/t/extending-ensure-for-non-templates/2472/12 "2021-04-20T15:10:24Z")

</div>

Sorry, I miswrote, that `Good` would an entirely different `template` so I would be able to tell.

---

<div class="post-metadata">

**Author:** ![bernhard](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/bernhard/32/356_2.png) [@bernhard](https://forum.canton.network/u/bernhard)\
**Post date:** [April 20, 2021, 3:12pm UTC](https://forum.canton.network/t/extending-ensure-for-non-templates/2472/13 "2021-04-20T15:12:22Z")

</div>

With a dishonest participant I can ignore `ensure` clauses on existing templates… So you write `Good`, I can create invalid instances on my participant. But again, I gain nothing from it…

---

<div class="post-metadata">

**Author:** ![Leonid\_Rozenberg](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/leonid_rozenberg/32/48_2.png) [@Leonid\_Rozenberg](https://forum.canton.network/u/Leonid_Rozenberg)\
**Post date:** [April 20, 2021, 3:19pm UTC](https://forum.canton.network/t/extending-ensure-for-non-templates/2472/14 "2021-04-20T15:19:41Z")

</div>

How does one create a dishonest participant, create a fork of daml and ignore the `ensure` clause validation?

---

<div class="post-metadata">

**Author:** ![bernhard](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/bernhard/32/356_2.png) [@bernhard](https://forum.canton.network/u/bernhard)\
**Post date:** [April 20, 2021, 3:20pm UTC](https://forum.canton.network/t/extending-ensure-for-non-templates/2472/15 "2021-04-20T15:20:53Z")

</div>

That’s the obvious way to go about it, yes. Not a supported feature 😉
