Lesson 5: Transaction Trees and Testing
Nothing is loaded from YouTube until you press play, and then without tracking cookies.
About this video
For a better learning experience, sign up and enroll in this free course at: daml.talentlms.com/plus/catalog/courses/150
Transcript
1,580 wordsCaptions as YouTube publishes them, usually machine-generated, so names such as Daml and Canton can be misheard.
- 0:00
you can submit a transaction to a ledger to observe the visual representation of the committed transaction as a tree-like structure this lesson revolves around comprehending transaction trees and constructing modularized test scripts to facilitate unit testing first let's clarify some Concepts that might cause confusion in damil the term action can refer to two different things the magnetic action and The Ledger
- 0:34
action the monadic action is a type class with instances like update script optional either Etc among them only update results in one or more Ledger actions script on the other hand can lead to command submissions which executes damil on The Ledger to generate an update which then leads to Ledger actions a ledger action refers to an event that occurs on The Ledger when an update is committed in this lesson you specifically focus on
- 1:08
The Ledger action as in Ledger event distinct from the action type class with that in mind let's talk about what a transaction is a transaction is a sequence of Ledger actions submitted to The Ledger simultaneously if any action within a transaction fails the entire transaction fails when you submit a transaction in a test script use the submit function which takes a party and a commands as
- 1:38
arguments when a transaction is submitted to a ledger this commands is submitted as a set of actions wrapped in a do block there are four types of Ledger actions a create action creates a new contract and sets its status to active an exercise action exercises a choice on a contract resulting in consequences or sub-transactions a fetch action checks the existence and activeness of a contract you can fetch a contract by its
- 2:10
contract ID or its key a key assertion is an assertion that the given key is not assigned to do any active contract on The Ledger you may have noticed that there is no archive action that's because archiving is an implicit consequence of exercising a default consuming choice also archive contract ID is a shorthand for exercise contract ID archive archive is a choice implicitly added to
- 2:42
every template with the signatories as controllers transaction trees are the result of a ledger accepting processing and successfully accepting commands each action is visualized as a tree where the action is the root node and its children are its consequences every consequence may have further consequences to Simply put each tree represents an event and its consequences are shown as a subtree notice that fetch create and key
- 3:15
assertion actions are always Leaf nodes as they have no consequences exercise is the only action that can have consequences the illustration shows that transaction 2 begins with one action leading to a consequence action to one while transaction zero has no consequences there are four transactions corresponding to the four submit statements in the script within each transaction actions have IDs
- 3:47
of the form hashtag TFS number colon action number contract IDs are just the IDS of their create action in the example transactions number two and three contain exercise actions with IDs two zero and three zero the create actions of the updated contact contracts to one and three one are indented below the line children forming a tree structure let's revisit the social network user template the previous lesson explored different types of choices and showed
- 4:27
how converting the follow Choice into a post-consuming choice wouldn't work for this demo now let's test the code and check out the error message when you convert the follow choice to a post-consuming choice first create the Alice and Bob parties then create Alice's social network user contract and bind the result to the variable Alice CID as an ALICE contract ID using the left Arrow then make Alice follow Bob by exercising the follow choice on this Alice C ID
- 5:01
contract without any keyword everything works well however the moment you add the post-consuming keyword you get the unique key violation error this indicates that the create function ran before the current contract was archived thanks to this error you can confirm that your key and maintainer work as expected you can also test a negative scenario without intentionally getting an error thrown
- 5:32
you can use submit must fail to test unhappy scenarios that are expected to result in an error typically you test the scenarios that are expected to occur without any error which is called happy path testing it is crucial to also confirm that no unintended workflow is possible earlier when you tried to create a new contract without archiving the old one you ran into the unique key violation error Let's test this scenario using
- 6:04
submit must fail remove the post-consuming keyword and immediately below the happy path testing add a submit must fail expression just like the submit function it takes a party and a commands as arguments submit must fail is syntactically similar to submit but if you attempt to test a scenario that isn't meant to fail it'll throw an error saying expected submit to fail but it succeeded now you can modularize the test script
- 6:37
to test each of the choices and happy and unhappy scenarios in isolation first create a custom type test parties you can instantiate a record of this type when you allocate parties then Define set of parties which allocates parties then Returns the references to those parties as a test party's record it is important to note that the test party's record is returned using the return function in some languages return is a statement and is used for exiting
- 7:11
out of a function however in damil return is just a function not a statement the return function takes an input value and wraps it in an action as an output since you are trying to allocate the parties in a ledger and output the references to the parties as a record you need to wrap or lift the record in the return function that way set of parties will evaluate to a test party's record wrapped in script
- 7:42
not a pure test party's record without the return function you will get a type check error you can use return and pure interchangeably if the return function in damil is confusing compared to how the return statement Works in other languages you can stick to using pure also Define a helper function to call whenever you need to create a new contract with some default values set a contract takes a party to create a
- 8:14
new Social Network user contract and outputs a new contract ID of social network user as a script notice that you didn't need the return function this time since the submit function evaluates to an action to test the follow choice you need both parties and a contract you can call the set of parties to bind the result of the call to the variable test parties set a parties evaluates to a record of references to the allocated parties such
- 8:45
as Alice and Bob key into Alice and Bob as test parties.alice and testparties.bob or use the type application to extract the keys of the test party's record this allows you to refer to Alice and Bob without having to key into the test party's record to create a default contract pass Alice to the set of contract function and bind the result to the variable Alice C ID using this contract ID and the party
- 9:19
Alice you can test exercising the follow choice return both of the variables test parties and followed C ID using the return or pure expression this way you can continue to use the parties and contract ID in another test script as a reminder do block evaluates to the last expression that is written inside it without the return or pure function can follow will only evaluate to the last
- 9:50
submit expression which is a new contract ID you won't have access to the rest from other test Scripts finally let's define the unhappy path testing to confirm that the key and maintainer ensure uniqueness of a contract you need an existing contract while the existing contract is within the scope of the test script you can try to create a new one which uses the same key to see if the transaction fails to do so call can follow which evaluates to
- 10:24
parties and an existing contract ID then you submit must fail to create another contract with the username Alice note that the return type of the unhappy path testing is an empty script since submit must fail succeeds when the submitting transaction fails and evaluates to an empty script in summary you define a choice with a set of actions which is submitted as a transaction to a ledger and visualized
- 10:54
in a tree structure the lesson also reviewed happy path versus unhappy path testing and how you can test your code in isolation by modularizing the test script just like any other functions a modularized test script can evaluate to an output that can be used in other test Scripts also it is important to remember that in damil return is a function which can be used interchangeably with the pure function the return function takes a value and
- 11:25
evaluates to the value encapsulated in an action you can use the return function to type match or have a function output multiple values as you did in the demo