Skip to content

Commit 1da3a35

Browse files
mixed LF versions tests (#20497)
* reproduce #20468 * test user defined 1.15 tuple * add tests for non-dynamic choices * add type tetris test * upgrade payload of mixed lf versions * fix bug * rename package
1 parent 33fcd02 commit 1da3a35

File tree

2 files changed

+303
-3
lines changed

2 files changed

+303
-3
lines changed

Diff for: sdk/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Speedy.scala

+5-3
Original file line numberDiff line numberDiff line change
@@ -1453,8 +1453,11 @@ private[lf] object Speedy {
14531453
val lookupResult = assertRight(
14541454
compiledPackages.pkgInterface.lookupDataRecord(tyCon)
14551455
)
1456-
val targetFieldsAndTypes: ImmArray[(Name, Type)] = lookupResult.dataRecord.fields
14571456
lazy val subst = lookupResult.subst(argTypes)
1457+
val targetFieldsAndTypes: ImmArray[(Name, Type)] =
1458+
lookupResult.dataRecord.fields.map { case (name, typ) =>
1459+
(name, AstUtil.substitute(typ, subst))
1460+
}
14581461

14591462
// This code implements the compatibility transformation used for up/down-grading
14601463
// And handles the cases:
@@ -1480,8 +1483,7 @@ private[lf] object Speedy {
14801483
// value is not normalized; check field names match
14811484
assert(sourceField == targetField)
14821485
}
1483-
val typ: Type = AstUtil.substitute(targetFieldType, subst)
1484-
val sv: SValue = go(typ, v)
1486+
val sv: SValue = go(targetFieldType, v)
14851487
List(sv)
14861488
case None => { // DOWNGRADE
14871489
// i ranges from 0 to numS-1. So i >= numT implies numS > numT
+298
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
-- Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
2+
-- SPDX-License-Identifier: Apache-2.0
3+
4+
module MixedLfVersions (main) where
5+
6+
import UpgradeTestLib
7+
import qualified V1.MixedLfVersionsInterfaceLF117 as I117
8+
import qualified V1.MixedLfVersionsInterfaceLF115 as I115
9+
import qualified V1.MixedLfVersionsTemplate as T117
10+
import qualified V1.MixedLfVersionsDep as D115
11+
import qualified V1.MixedLfVersionsRecord as RV1
12+
import qualified V2.MixedLfVersionsRecord as RV2
13+
import qualified V1.MixedLfVersionsPayload as PV1
14+
import qualified V2.MixedLfVersionsPayload as PV2
15+
import qualified V1.MixedLfVersionsPayloadClient as PC
16+
17+
{- PACKAGE
18+
name: mixed-lf-versions-dep
19+
versions: 1
20+
lf-version: "1.15"
21+
-}
22+
23+
{- MODULE
24+
package: mixed-lf-versions-dep
25+
contents: |
26+
module MixedLfVersionsDep where
27+
28+
data MyPair a b = MyPair { fst : a, snd : b }
29+
deriving (Eq, Show)
30+
-}
31+
32+
{- PACKAGE
33+
name: mixed-lf-versions-interface-lf117
34+
depends: mixed-lf-versions-dep-1.0.0
35+
versions: 1
36+
lf-version: "1.17"
37+
-}
38+
39+
{- MODULE
40+
package: mixed-lf-versions-interface-lf117
41+
contents: |
42+
module MixedLfVersionsInterfaceLF117 where
43+
44+
import MixedLfVersionsDep
45+
46+
data IV = IV { u : () }
47+
48+
interface I where
49+
viewtype IV
50+
51+
getTupleWithTrailingOption : (Int, Optional Int)
52+
getUserDefinedTupleWithTrailingOption : MyPair Int (Optional Int)
53+
54+
nonconsuming choice GetTupleWithTrailingOption : (Int, Optional Int)
55+
with ctl: Party
56+
controller ctl
57+
do
58+
pure $ getTupleWithTrailingOption this
59+
60+
nonconsuming choice GetUserDefinedTupleWithTrailingOption : MyPair Int (Optional Int)
61+
with ctl: Party
62+
controller ctl
63+
do
64+
pure $ getUserDefinedTupleWithTrailingOption this
65+
-}
66+
67+
{- PACKAGE
68+
name: mixed-lf-versions-interface-lf115
69+
depends: mixed-lf-versions-dep-1.0.0
70+
versions: 1
71+
lf-version: "1.17"
72+
-}
73+
74+
{- MODULE
75+
package: mixed-lf-versions-interface-lf115
76+
contents: |
77+
module MixedLfVersionsInterfaceLF115 where
78+
79+
import MixedLfVersionsDep
80+
81+
data IV = IV { u : () }
82+
83+
interface I where
84+
viewtype IV
85+
86+
getTupleWithTrailingOption : (Int, Optional Int)
87+
getUserDefinedTupleWithTrailingOption : MyPair Int (Optional Int)
88+
89+
nonconsuming choice GetTupleWithTrailingOption : (Int, Optional Int)
90+
with ctl: Party
91+
controller ctl
92+
do
93+
pure $ getTupleWithTrailingOption this
94+
95+
nonconsuming choice GetUserDefinedTupleWithTrailingOption : MyPair Int (Optional Int)
96+
with ctl: Party
97+
controller ctl
98+
do
99+
pure $ getUserDefinedTupleWithTrailingOption this
100+
-}
101+
102+
{- PACKAGE
103+
name: mixed-lf-versions-template
104+
versions: 1
105+
depends: |
106+
mixed-lf-versions-interface-lf117-1.0.0
107+
mixed-lf-versions-interface-lf115-1.0.0
108+
mixed-lf-versions-dep-1.0.0
109+
lf-version: "1.17"
110+
-}
111+
112+
{- MODULE
113+
package: mixed-lf-versions-template
114+
contents: |
115+
module MixedLfVersionsTemplate where
116+
117+
import qualified MixedLfVersionsInterfaceLF117 as I117
118+
import qualified MixedLfVersionsInterfaceLF115 as I115
119+
import MixedLfVersionsDep
120+
121+
template T with
122+
party : Party
123+
where
124+
signatory party
125+
126+
nonconsuming choice TGetTupleWithTrailingOption : (Int, Optional Int)
127+
with ctl: Party
128+
controller ctl
129+
do pure (117, None)
130+
131+
nonconsuming choice TGetUserDefinedTupleWithTrailingOption : MyPair Int (Optional Int)
132+
with ctl: Party
133+
controller ctl
134+
do pure (MyPair 117 None)
135+
136+
interface instance I117.I for T where
137+
view = I117.IV ()
138+
getTupleWithTrailingOption = (117, None)
139+
getUserDefinedTupleWithTrailingOption = MyPair 117 None
140+
141+
interface instance I115.I for T where
142+
view = I115.IV ()
143+
getTupleWithTrailingOption = (115, None)
144+
getUserDefinedTupleWithTrailingOption = MyPair 115 None
145+
-}
146+
147+
{- PACKAGE
148+
name: mixed-lf-versions-record
149+
versions: 2
150+
lf-version: "1.17"
151+
-}
152+
153+
{- MODULE
154+
package: mixed-lf-versions-record
155+
contents: |
156+
module MixedLfVersionsRecord where
157+
158+
data R = R with
159+
n : Int
160+
m : Optional Int -- @V 2
161+
deriving (Eq, Show)
162+
-}
163+
164+
{- PACKAGE
165+
name: mixed-lf-versions-payload
166+
versions: 2
167+
depends: |
168+
mixed-lf-versions-dep-1.0.0
169+
mixed-lf-versions-record-1.0.0 -- @V 1
170+
mixed-lf-versions-record-2.0.0 -- @V 2
171+
lf-version: "1.17"
172+
-}
173+
174+
{- MODULE
175+
package: mixed-lf-versions-payload
176+
contents: |
177+
module MixedLfVersionsPayload where
178+
179+
import MixedLfVersionsDep
180+
import MixedLfVersionsRecord
181+
182+
template T with
183+
party : Party
184+
tuple : (R, Optional Int)
185+
userDefinedTuple : MyPair R (Optional Int)
186+
where
187+
signatory party
188+
-}
189+
190+
{- PACKAGE
191+
name: mixed-lf-versions-payload-client
192+
versions: 1
193+
depends: |
194+
mixed-lf-versions-dep-1.0.0
195+
mixed-lf-versions-record-1.0.0
196+
mixed-lf-versions-record-2.0.0
197+
mixed-lf-versions-payload-1.0.0
198+
mixed-lf-versions-payload-2.0.0
199+
lf-version: "1.17"
200+
-}
201+
202+
{- MODULE
203+
package: mixed-lf-versions-payload-client
204+
contents: |
205+
module MixedLfVersionsPayloadClient where
206+
207+
import MixedLfVersionsDep
208+
import qualified V1.MixedLfVersionsRecord as V1
209+
import qualified V2.MixedLfVersionsRecord as V2
210+
import qualified V1.MixedLfVersionsPayload as V1
211+
import qualified V2.MixedLfVersionsPayload as V2
212+
213+
template Client with
214+
party : Party
215+
where
216+
signatory party
217+
218+
nonconsuming choice UpgradePayload : V2.T
219+
with ctl: Party
220+
controller ctl
221+
do
222+
cid <- create V1.T { party = party, tuple = (V1.R 1, None), userDefinedTuple = MyPair (V1.R 1) None }
223+
let v2Cid = coerceContractId @V1.T @V2.T cid
224+
fetch v2Cid
225+
-}
226+
227+
main : TestTree
228+
main = tests
229+
[ ("Call a LF 1.17 dynamic choice that returns a tuple with a trailing None", call117DynamicChoiceThatReturnsTupleWithTrailingNone)
230+
, ("Call a LF 1.17 dynamic choice that returns a user-defined LF 1.15 tuple with a trailing None", call117DynamicChoiceThatReturnsUserDefinedTupleWithTrailingNone)
231+
, ("Call a LF 1.15 dynamic choice that returns a tuple with a trailing None", call115DynamicChoiceThatReturnsTupleWithTrailingNone)
232+
, ("Call a LF 1.15 dynamic choice that returns a user-defined LF 1.15 tuple with a trailing None", call115DynamicChoiceThatReturnsUserDefinedTupleWithTrailingNone)
233+
, ("Call a LF 1.17 choice that returns a tuple with a trailing None", callChoiceThatReturnsTupleWithTrailingNone)
234+
, ("Call a LF 1.17 choice that returns a user-defined LF 1.15 tuple with a trailing None", callChoiceThatReturnsUserDefinedTupleWithTrailingNone)
235+
, ("Have daml-script upgrade a LF 1.17 contract that has builtin and user-defined pairs of upgradable types as fields", upgradePairsOfUpgradableTypesDamlScriptRunner)
236+
, ("Have the engine upgrade a LF 1.17 contract that has builtin and user-defined pairs of upgradable types as fields", upgradePairsOfUpgradableTypesEngine)
237+
]
238+
239+
call117DynamicChoiceThatReturnsTupleWithTrailingNone : Test
240+
call117DynamicChoiceThatReturnsTupleWithTrailingNone = test $ do
241+
alice <- allocateParty "alice"
242+
cid <- alice `submit` createExactCmd T117.T { party = alice }
243+
let icid = toInterfaceContractId @I117.I cid
244+
res <- alice `submit` exerciseExactCmd @I117.I icid (I117.GetTupleWithTrailingOption { ctl = alice })
245+
res === (117, None)
246+
247+
call117DynamicChoiceThatReturnsUserDefinedTupleWithTrailingNone : Test
248+
call117DynamicChoiceThatReturnsUserDefinedTupleWithTrailingNone = test $ do
249+
alice <- allocateParty "alice"
250+
cid <- alice `submit` createExactCmd T117.T { party = alice }
251+
let icid = toInterfaceContractId @I117.I cid
252+
res <- alice `submit` exerciseExactCmd @I117.I icid (I117.GetUserDefinedTupleWithTrailingOption { ctl = alice })
253+
res === D115.MyPair 117 None
254+
255+
call115DynamicChoiceThatReturnsTupleWithTrailingNone : Test
256+
call115DynamicChoiceThatReturnsTupleWithTrailingNone = test $ do
257+
alice <- allocateParty "alice"
258+
cid <- alice `submit` createExactCmd T117.T { party = alice }
259+
let icid = toInterfaceContractId @I115.I cid
260+
res <- alice `submit` exerciseExactCmd @I115.I icid (I115.GetTupleWithTrailingOption { ctl = alice })
261+
res === (115, None)
262+
263+
call115DynamicChoiceThatReturnsUserDefinedTupleWithTrailingNone : Test
264+
call115DynamicChoiceThatReturnsUserDefinedTupleWithTrailingNone = test $ do
265+
alice <- allocateParty "alice"
266+
cid <- alice `submit` createExactCmd T117.T { party = alice }
267+
let icid = toInterfaceContractId @I115.I cid
268+
res <- alice `submit` exerciseExactCmd @I115.I icid (I115.GetUserDefinedTupleWithTrailingOption { ctl = alice })
269+
res === D115.MyPair 115 None
270+
271+
callChoiceThatReturnsTupleWithTrailingNone : Test
272+
callChoiceThatReturnsTupleWithTrailingNone = test $ do
273+
alice <- allocateParty "alice"
274+
cid <- alice `submit` createExactCmd T117.T { party = alice }
275+
res <- alice `submit` exerciseExactCmd @T117.T cid (T117.TGetTupleWithTrailingOption { ctl = alice })
276+
res === (117, None)
277+
278+
callChoiceThatReturnsUserDefinedTupleWithTrailingNone : Test
279+
callChoiceThatReturnsUserDefinedTupleWithTrailingNone = test $ do
280+
alice <- allocateParty "alice"
281+
cid <- alice `submit` createExactCmd T117.T { party = alice }
282+
res <- alice `submit` exerciseExactCmd @T117.T cid (T117.TGetUserDefinedTupleWithTrailingOption { ctl = alice })
283+
res === D115.MyPair 117 None
284+
285+
upgradePairsOfUpgradableTypesDamlScriptRunner : Test
286+
upgradePairsOfUpgradableTypesDamlScriptRunner = test $ do
287+
alice <- allocateParty "alice"
288+
cid <- alice `submit` createExactCmd (PV1.T alice (RV1.R 1, None) (D115.MyPair (RV1.R 1) None))
289+
let v2Cid = coerceContractId @PV1.T @PV2.T cid
290+
res <- alice `queryContractId` v2Cid
291+
res === Some (PV2.T alice (RV2.R 1 None, None) (D115.MyPair (RV2.R 1 None) None))
292+
293+
upgradePairsOfUpgradableTypesEngine : Test
294+
upgradePairsOfUpgradableTypesEngine = test $ do
295+
alice <- allocateParty "alice"
296+
cid <- alice `submit` createExactCmd (PC.Client alice)
297+
res <- alice `submit` exerciseExactCmd @PC.Client cid (PC.UpgradePayload alice)
298+
res === PV2.T alice (RV2.R 1 None, None) (D115.MyPair (RV2.R 1 None) None)

0 commit comments

Comments
 (0)