Handle fetch node actors correctly in scenario-service (#17734)

* Add failing tests

"'bank' fetches" should be "'alice' fetches" in the ledger output when 'alice' is the divulging party

* Handle fetch node actors correctly in scenario-service

* Handle fetch node actors correctly in lf-interpreter pretty printer
This commit is contained in:
Moisés Ackerman 2023-11-10 15:17:23 +01:00 committed by GitHub
parent efbe746554
commit d52a42ff52
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 263 additions and 12 deletions

View File

@ -0,0 +1,123 @@
-- Copyright (c) 2023 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
-- SPDX-License-Identifier: Apache-2.0
-- Regression test for https://github.com/digital-asset/daml/issues/17729
-- The last node in the resulting transaction view should be a fetch node,
-- with the divulging stakeholder as acting party. In particular, when
-- the divulging party is a non-signatory observer of the divulged contract
-- (alice), none of the signatories (bank) should appear as acting parties
-- of the fetch node.
module DivulgeFetchNodeActors where
import Daml.Script
data TestData = TestData
{ alice : Party
, bank : Party
, divulgee : Party
, iou : ContractId Iou
}
data TestCase t c = TestCase
{ divulgeContractCreator : Party
, divulgeContract : t
, divulgeSubmitter : Party
, divulgeChoice : c
}
buildScript : (Choice t c r, HasAgreement t) => (TestData -> TestCase t c) -> Script ()
buildScript mkTestCase = do
alice <- allocateParty "alice"
bank <- allocateParty "bank"
divulgee <- allocateParty "divulgee"
iou <- submit bank do
createCmd Iou with
bank = bank
owner = alice
let TestCase {..} = mkTestCase TestData {..}
divulgeCid <- submit divulgeContractCreator do
createCmd divulgeContract
submit divulgeSubmitter do
exerciseCmd divulgeCid divulgeChoice
pure ()
-- @LEDGER observerDivulges DivulgeFetchNodeActors/observerDivulges.EXPECTED.ledger
observerDivulges : Script ()
observerDivulges =
buildScript \TestData {..} -> TestCase
{ divulgeContractCreator = alice
, divulgeContract = DivulgeTo with stakeholder = alice, divulgee
, divulgeSubmitter = alice
, divulgeChoice = ExeDivulgeTo with cid = iou
}
-- @LEDGER signatoryDivulges DivulgeFetchNodeActors/signatoryDivulges.EXPECTED.ledger
signatoryDivulges : Script ()
signatoryDivulges = do
buildScript \TestData {..} -> TestCase
{ divulgeContractCreator = bank
, divulgeContract = DivulgeTo with stakeholder = bank, divulgee
, divulgeSubmitter = bank
, divulgeChoice = ExeDivulgeTo with cid = iou
}
-- @LEDGER observerAskedToDivulge DivulgeFetchNodeActors/observerAskedToDivulge.EXPECTED.ledger
observerAskedToDivulge : Script ()
observerAskedToDivulge = do
buildScript \TestData {..} -> TestCase
{ divulgeContractCreator = divulgee
, divulgeContract = DivulgeFrom with stakeholder = alice, divulgee
, divulgeSubmitter = alice
, divulgeChoice = ExeDivulgeFrom with cid = iou
}
-- @LEDGER signatoryAskedToDivulge DivulgeFetchNodeActors/signatoryAskedToDivulge.EXPECTED.ledger
signatoryAskedToDivulge : Script ()
signatoryAskedToDivulge = do
buildScript \TestData {..} -> TestCase
{ divulgeContractCreator = divulgee
, divulgeContract = DivulgeFrom with stakeholder = bank, divulgee
, divulgeSubmitter = bank
, divulgeChoice = ExeDivulgeFrom with cid = iou
}
template Iou
with
bank : Party
owner : Party
where
signatory bank
observer owner
template DivulgeTo
with
stakeholder : Party
divulgee : Party
where
signatory stakeholder
observer divulgee
choice ExeDivulgeTo : Iou
with
cid : ContractId Iou
controller stakeholder
do fetch cid
template DivulgeFrom
with
stakeholder : Party
divulgee : Party
where
signatory divulgee
observer stakeholder
choice ExeDivulgeFrom : Iou
with
cid : ContractId Iou
controller stakeholder
do fetch cid

View File

@ -0,0 +1,33 @@
Transactions:
TX 0 1970-01-01T00:00:00Z (DivulgeFetchNodeActors:34:10)
#0:0
│ referenced by #2:1
│ disclosed to (since): 'alice' (0), 'bank' (0)
│ divulged to (since): 'divulgee' (2)
└─> 'bank' creates DivulgeFetchNodeActors:Iou
with
bank = 'bank'; owner = 'alice'
TX 1 1970-01-01T00:00:00Z (DivulgeFetchNodeActors:41:17)
#1:0
│ consumed by: #2:0
│ referenced by #2:0
│ disclosed to (since): 'alice' (1), 'divulgee' (1)
└─> 'divulgee' creates DivulgeFetchNodeActors:DivulgeFrom
with
stakeholder = 'alice'; divulgee = 'divulgee'
TX 2 1970-01-01T00:00:00Z (DivulgeFetchNodeActors:44:3)
#2:0
│ disclosed to (since): 'alice' (2), 'divulgee' (2)
└─> 'alice' exercises ExeDivulgeFrom on #1:0 (DivulgeFetchNodeActors:DivulgeFrom)
with
cid = #0:0
children:
#2:1
│ disclosed to (since): 'alice' (2), 'divulgee' (2), 'bank' (2)
└─> 'alice' fetches #0:0 (DivulgeFetchNodeActors:Iou)
Active contracts: #0:0
Return value: {}

View File

@ -0,0 +1,33 @@
Transactions:
TX 0 1970-01-01T00:00:00Z (DivulgeFetchNodeActors:34:10)
#0:0
│ referenced by #2:1
│ disclosed to (since): 'alice' (0), 'bank' (0)
│ divulged to (since): 'divulgee' (2)
└─> 'bank' creates DivulgeFetchNodeActors:Iou
with
bank = 'bank'; owner = 'alice'
TX 1 1970-01-01T00:00:00Z (DivulgeFetchNodeActors:41:17)
#1:0
│ consumed by: #2:0
│ referenced by #2:0
│ disclosed to (since): 'alice' (1), 'divulgee' (1)
└─> 'alice' creates DivulgeFetchNodeActors:DivulgeTo
with
stakeholder = 'alice'; divulgee = 'divulgee'
TX 2 1970-01-01T00:00:00Z (DivulgeFetchNodeActors:44:3)
#2:0
│ disclosed to (since): 'alice' (2), 'divulgee' (2)
└─> 'alice' exercises ExeDivulgeTo on #1:0 (DivulgeFetchNodeActors:DivulgeTo)
with
cid = #0:0
children:
#2:1
│ disclosed to (since): 'alice' (2), 'divulgee' (2), 'bank' (2)
└─> 'alice' fetches #0:0 (DivulgeFetchNodeActors:Iou)
Active contracts: #0:0
Return value: {}

View File

@ -0,0 +1,33 @@
Transactions:
TX 0 1970-01-01T00:00:00Z (DivulgeFetchNodeActors:34:10)
#0:0
│ referenced by #2:1
│ disclosed to (since): 'alice' (0), 'bank' (0)
│ divulged to (since): 'divulgee' (2)
└─> 'bank' creates DivulgeFetchNodeActors:Iou
with
bank = 'bank'; owner = 'alice'
TX 1 1970-01-01T00:00:00Z (DivulgeFetchNodeActors:41:17)
#1:0
│ consumed by: #2:0
│ referenced by #2:0
│ disclosed to (since): 'bank' (1), 'divulgee' (1)
└─> 'divulgee' creates DivulgeFetchNodeActors:DivulgeFrom
with
stakeholder = 'bank'; divulgee = 'divulgee'
TX 2 1970-01-01T00:00:00Z (DivulgeFetchNodeActors:44:3)
#2:0
│ disclosed to (since): 'bank' (2), 'divulgee' (2)
└─> 'bank' exercises ExeDivulgeFrom on #1:0 (DivulgeFetchNodeActors:DivulgeFrom)
with
cid = #0:0
children:
#2:1
│ disclosed to (since): 'bank' (2), 'divulgee' (2)
└─> 'bank' fetches #0:0 (DivulgeFetchNodeActors:Iou)
Active contracts: #0:0
Return value: {}

View File

@ -0,0 +1,33 @@
Transactions:
TX 0 1970-01-01T00:00:00Z (DivulgeFetchNodeActors:34:10)
#0:0
│ referenced by #2:1
│ disclosed to (since): 'alice' (0), 'bank' (0)
│ divulged to (since): 'divulgee' (2)
└─> 'bank' creates DivulgeFetchNodeActors:Iou
with
bank = 'bank'; owner = 'alice'
TX 1 1970-01-01T00:00:00Z (DivulgeFetchNodeActors:41:17)
#1:0
│ consumed by: #2:0
│ referenced by #2:0
│ disclosed to (since): 'bank' (1), 'divulgee' (1)
└─> 'bank' creates DivulgeFetchNodeActors:DivulgeTo
with
stakeholder = 'bank'; divulgee = 'divulgee'
TX 2 1970-01-01T00:00:00Z (DivulgeFetchNodeActors:44:3)
#2:0
│ disclosed to (since): 'bank' (2), 'divulgee' (2)
└─> 'bank' exercises ExeDivulgeTo on #1:0 (DivulgeFetchNodeActors:DivulgeTo)
with
cid = #0:0
children:
#2:1
│ disclosed to (since): 'bank' (2), 'divulgee' (2)
└─> 'bank' fetches #0:0 (DivulgeFetchNodeActors:Iou)
Active contracts: #0:0
Return value: {}

View File

@ -768,7 +768,7 @@ prettyNodeNode lvl nn = do
)
NodeNodeFetch Node_Fetch{..} -> do
let (parties, kw) = partiesAction node_FetchSignatories "fetches" "fetch"
let (parties, kw) = partiesAction node_FetchActingParties "fetches" "fetch"
pure
$ parties
<-> (

View File

@ -71,8 +71,7 @@ toPtx nodes = case runState (mapM go nodes) (0, []) of
Fetch -> pure $ S.NodeNodeFetch S.Node_Fetch
{ node_FetchContractId = "#0"
, node_FetchTemplateId = Nothing
, node_FetchSignatories = V.empty
, node_FetchStakeholders = V.empty
, node_FetchActingParties = V.empty
, node_FetchFetchByKey = Nothing
}
Lookup -> pure $ S.NodeNodeLookupByKey S.Node_LookupByKey

View File

@ -657,9 +657,8 @@ message Node {
message Fetch {
string contract_id = 1;
Identifier template_id = 2;
repeated Party signatories = 3;
repeated Party stakeholders = 4;
KeyWithMaintainers fetch_by_key = 13; // optional, if non-empty then fetched by key
repeated Party acting_parties = 3;
KeyWithMaintainers fetch_by_key = 4; // optional, if non-empty then fetched by key
}
message Exercise {

View File

@ -640,8 +640,7 @@ final class Conversions(
proto.Node.Fetch.newBuilder
.setContractId(coidToEventId(fetch.coid).toLedgerString)
.setTemplateId(convertIdentifier(fetch.templateId))
.addAllSignatories(fetch.signatories.map(convertParty).asJava)
.addAllStakeholders(fetch.stakeholders.map(convertParty).asJava)
.addAllActingParties(fetch.actingParties.map(convertParty).asJava)
if (fetch.byKey) {
fetch.keyOpt.foreach { key =>
fetchBuilder.setFetchByKey(convertKeyWithMaintainers(key))
@ -739,8 +738,7 @@ final class Conversions(
proto.Node.Fetch.newBuilder
.setContractId(coidToEventId(fetch.coid).toLedgerString)
.setTemplateId(convertIdentifier(fetch.templateId))
.addAllSignatories(fetch.signatories.map(convertParty).asJava)
.addAllStakeholders(fetch.stakeholders.map(convertParty).asJava)
.addAllActingParties(fetch.actingParties.map(convertParty).asJava)
.build
)
case ex: Node.Exercise =>

View File

@ -277,7 +277,7 @@ private[lf] object Pretty {
partiesAction(create.signatories, "creates", "create") &
prettyContractInst(create.coinst)
case fetch: Node.Fetch =>
partiesAction(fetch.signatories, "fetches", "fetch") &
partiesAction(fetch.actingParties, "fetches", "fetch") &
prettyContractId(fetch.coid)
case ex: Node.Exercise =>
partiesAction(ex.actingParties, "exercises", "exercise") &
@ -376,7 +376,7 @@ private[lf] object Pretty {
case Some(key) => d / text("key") & prettyKeyWithMaintainers(key)
}
case ea: Node.Fetch =>
partiesAction(ea.signatories, "fetches", "fetch") &
partiesAction(ea.actingParties, "fetches", "fetch") &
prettyContractId(ea.coid)
case ex: Node.Exercise =>
val children =