Checking a value on an archived contract

G-d willing

Hello,
Let’s say that I have a template with an Int field.
I am required to archive the contract whenever the value of that field is set to zero.
So, when I am testing, using a script, the choice that was exercised, I not only want to verify that the contract does not exist but also verify that the value of that integer field was zero.
How can I do that?

Thanks,
Avraham

How about this?

p <- myParty
cid <- theContractIdInQuestion

-- Get hold of the arguments before archiving
Some args <- queryContractId cid
-- Exercise the tested choice
submit p (exerciseCmd cid MyChoice)
-- Test that the contract is archived
None <- queryContractId cid
-- Check that the value was zero
0.0 === args.foo

G-d willing

Thanks @bernhard for your answer.
However, what you suggested is not possible, because the choice in question does both, and I cannot exercise half of the choice, test it, and then exercise the rest of the choice.

template A
  with
    owner : Party
    id : Int
    value : Int
  where
    signatory owner
    key (owner, id) : (Party, Int)
    maintainer key._1

    choice TestChoice : ()
      controller owner
        a <- create this with value = 0
        archive a

testChoice : Script ()
testChoice = script do
  
  -- allocating alice
  a <- submit alice do
            createCmd A with owner = alice, id = 1, value = 1

  submit alice do
    exerciseCmd a TestChoice

  -- need to check 2 things
  -- 1. Contract of Type A does not exist by ensuring the queryContractKey returns None
  debug $ isNone (queryContractKey alice (alice, 1))

  -- 2. The value of the contract was 0 before archiving it
  -- How do I do that?

  pure ()

The only way to do this anywhere - script or otherwise - is to inspect the transaction tree and make assertions on that. In Script that’s currently early access. You can see the submitTree function that’s needed here. But it’s currently undocumented early access functionality so no guarantees or support on that yet.

Otherwise, write this sort of test in Java for now where you can get the transaction tree from the Ledger API and inspect it.

2 Likes

Thanks again @bernhard
I will test it and see how it goes.
Any idea when this will be officially released?

@bernhard
Can you please give me a simple example of how can I use the submitTree in my case?

Here’s a minimal example, but since this is early access/unsupported, you are more or less on your own with this. I’ll ask the responsible team about timelines.

module Main where

import Daml.Script
import DA.Assert

template A
  with
    owner : Party
    id : Int
    value : Int
  where
    signatory owner
    key (owner, id) : (Party, Int)
    maintainer key._1

    choice TestChoice : ()
      controller owner
      do
        a <- create this with value = 0
        archive a

testChoice : Script ()
testChoice = script do
  alice <- allocateParty "alice"
  -- allocating alice
  a <- submit alice do
            createCmd A with owner = alice, id = 1, value = 1

  -- Pattern match the transaction to get our hands on the created and archived events
  TransactionTree{rootEvents = [ExercisedEvent Exercised{
      childEvents = [CreatedEvent created, ExercisedEvent archived]
    }]} 
    <- submitTree alice do
      exerciseCmd a TestChoice

  -- Make sure we have a matching pair
  (created.contractId === archived.contractId)
  -- cast
  let Some a = fromAnyTemplate @A created.argument
  a.value === 0

  pure ()
1 Like

Hey @cohen.avraham,

Long term plans are to make the functionality of submitTree part of the standard functionality of the Daml Script library. However, do note that as submitTree is part of early access, it is not guaranteed the shape of API as it currently is, will remain.

I do think that is very likely that any switch on your end won’t be much more work than redefining your own submitTree that mirrors the current early access on top of the new function definitions we might provide, as we’re mainly looking to slightly generalise the behaviour.

1 Like