Skip to content
Discussions/Outreach/Query and Create Exercise as multiple partiesForum ↗

Query and Create Exercise as multiple parties

Outreach32 posts1,777 views37 likesLast activity Jun 2020
DL
dliakakosOP
May 2020

Have we ever thought of the possibility of having the http json api allowing to query simultaneously as two or more parties and return the union of the result?
Also on the exercise and create path could the json api accept a command where 2 or more parties are authorizers (so we could potentially exercise a conjunction choices)?

Rationale:
Read path - The multiple party read path will help a lot in performing data disclosure on applications that consume the json api. For example if we want to publicly disclose contracts then we can have a special party (ie the public party) that we can add as an observer. Then we mint JWTs that can read as both as Alice and the public party and query using that.

Write path - For the write path of create and exercise, this will help in modeling user groups with specific authorities over the active contracts on the ledger. For example if we want at some point to grant Alice the ability to exercise a choice on an existing contract we would have to have a disjunction choice and explicitly add Alice to the list of disjunction parties before she can exercise that choice. Instead, we make the choice exercisable by a single party (ie some admin) and simply give Alice the token to exercise that. The subtlety here is that Alice is not necessarily a party on the ledger but an actual person that can read and write as multiple parties.

ST
stefanobaghino-da
May 2020

Reading

Reading as multiple parties is not supported but theoretically possible, as there is a support for multi-party subscriptions on the Ledger API. Still, I would discourage it: this is just my opinion, but I believe there is an inherent advantage in keeping streams for separate parties separate, as you can easily reason about a single party at a time and not mix up together data that should have been segregated per party. Even if it’s intended for public disclosure, having something acting as the hub for publicly available contracts is something I would value as an app developer. On the practical side, single party subscription can also be faster than multi-party ones, because multi-party subs require the server to compute who the intended witness is for every event returned (whereas in the single party sub it’s clear that whomever is receiving an event is a witness). This, of course, comes into play when you have to perform at scale.

Writing

Writing as multiple parties is not possible via the Ledger API, so it’s not possible on the HTTP JSON API either, since it runs on top of the Ledger API.

GE
georg
May 2020

@stefanobaghino-da Dimitri also wanted to know if we’ve ever considered the multi-party write flow, and if not, why not :slight_smile:

On the public read party: the problem with this is that you’ll only ever be able to see those contracts’ data, you’ll not be able to interact with them or use them in a choice using your own party. That’s severely limiting the usability of that approach imo.

ST
stefanobaghino-da
May 2020
georg:

@stefanobaghino-da Dimitri also wanted to know if we’ve ever considered the multi-party write flow, and if not, why not :slight_smile:

Unfortunately I’m not aware of this, otherwise I would have included it in my answer.

DL
dliakakos
May 2020

Thanks for the clarification @georg - yes it would be nice to know if the write path was ever considered and dismissed.

On the read path I would argue that it is a major benefit for displaying public data (or groups of data) on your application (even though you can’t fetch them in your choices). It’s not very different from the case where your party is merely an observer on a contract but not a controller. You can still see the choices but if you try to take any you will get rejected.

LE
Leonid_Shlyapnikov
May 2020

Ledger API supports multi-party reads, JSON API does not.

JSON API authentication/authorization was designed a bit a head of Ledger API and we did not have a use case for multi-party reads in JSON API.

Our take on multi-party authentication in JSON API:

  • 1 party - 1 authentication token (JWT), no super users
  • if participant needs to act as multi-party, this participant needs multiple authentication tokens (one per party)
LE
Leonid_Shlyapnikov
May 2020
dliakakos:

Write path - For the write path of create and exercise, this will help in modeling user groups with specific authorities over the active contracts on the ledger. For example if we want at some point to grant Alice the ability to exercise a choice on an existing contract we would have to have a disjunction choice and explicitly add Alice to the list of disjunction parties before she can exercise that choice.

This sounds reasonable to me. A new copy of the contract with Alice added to it has to be created and approved/accepted by all signatories. This is by design. What if one of the signatories does not want Alice exercising a choice on the contract or does not want Alice to be able to read this contract?

dliakakos:

Instead, we make the choice exercisable by a single party (ie some admin) and simply give Alice the token to exercise that.

This does not sound right. Granting Alice admin rights you cannot control what Alice can read and exercise. Alice becomes a super user with access to all contracts that Admin can access. This also means you will end up with multiple counter-parties/entities being admins.

I remember the discussion with @dtanabe when we decided to make it impossible to have super users in JSON API :slight_smile:.

Dimitri, what exact problem are you trying to solve?

DR
drsk
May 2020
dliakakos:

For example if we want to publicly disclose contracts then we can have a special party (ie the public party) that we can add as an observer

Almost in every app I wrote in DAML I run into the need for a way to broadcast data to all parties. If we would allow reads as multiple parties, the above would be a simple solution for this. You could just define a ‘broadcast’ party and give all parties read access as ‘broadcast’.

LE
Leonid_Shlyapnikov
May 2020
drsk:

You could just define a ‘broadcast’ party and give all parties read access as ‘broadcast’.

This would mean that anyone could become an observer without contract signatories approval, which would violate the entire purpose of signatories. I think a flag to enable broadcast to every party on the ledger should be added to the DAML template. We have observers, something like observed-by-everybody: Bool. When signatories are signing a contract they will have to accept the fact that the contract can be broadcasted to every party.

BTW, it is pretty easy to add support for multi-party reads to JSON API, but I think it would open a way to violate contract privacy.

LE
Leonid_Rozenberg
May 2020

@drsk To enable this vision it would be convenient if the react bindings had the ability to specify what party is making a request (within a DamlLedger context), to avoid having to go into the ledger api.

LE
Leonid_Rozenberg
May 2020
If privacy is not a concern (eg. you specifically want global visibility of all aliases) and your lookups are far more frequent than write operations (add, delete, change aliases), then some of the concerns of MapOnLedger are not as grave - so it might be the better option then. The LedgerAsMap option is better for when the disclosure of an alias is considered a business process, and each party has a set of aliases it interacts with that is much smaller than the global population. In this case …

The people have spoken! Universally observable templates for the people!

DR
drsk
May 2020
Leonid_Shlyapnikov:

This would mean that anyone could become an observer without contract signatories approval, which would violate the entire purpose of signatories

I can’t quite follow this. The contract would be designed in a way that you add the ‘broadcast’ party explicitly to the observers, so it’s clear in the DAML code itself that such a contract is broadcasted. So no change to the privacy rules or change to the signatory purpose.

DR
drsk
May 2020
Leonid_Rozenberg:

To enable this vision it would be convenient if the react bindings had the ability to specify what party is making a request (within a DamlLedger context), to avoid having to go into the ledger api.

Actually, for this idea it wouldn’t be necessary. Because a party would get a JWT token where it has the right to read as the broadcast party, so there is no need to switch the acting party context.

LE
Leonid_Rozenberg
May 2020

That’s great and an elegant solution!

LE
Leonid_Shlyapnikov
May 2020
drsk:

I can’t quite follow this. The contract would be designed in a way that you add the ‘broadcast’ party explicitly to the observers, so it’s clear in the DAML code itself that such a contract is broadcasted. So no change to the privacy rules or change to the signatory purpose.

If DLT operator can give Alice permission to read contracts as Broadcast party, technically the same DLT operator, can make a mistake and let Alice read contracts as Bob… contract signatories will not have any control over this, they won’t even be notified about this mistake.

DR
drsk
May 2020

If someone who controls the identity/keys infrastructure of a party makes a mistake, then you’ll be in trouble in any case. I think this observation is independent of the question, whether multiple parties should be allowed in readAs.

LE
Leonid_Shlyapnikov
May 2020
drsk:

If someone who controls the identity/keys infrastructure of a party makes a mistake, then you’ll be in trouble in any case

That is not the point… My personal opinion that canReadAs and canActAs break the ledger privacy model and allow someone else besides signatories to give access to observe and exercise choices on contracts.

If I sign an IOU with Alice, I would NOT like the idea that let’s say the government or a bank can make this contract visible to everyone else. It should be between me and Alice and nobody else.

You can create an issue here: Sign in to GitHub · GitHub

and refer to this doc: https://docs.daml.com/app-dev/authentication.html#access-tokens-and-claims

I will make sure we discuss this issue with the product owners this week.

DL
dliakakos
May 2020

It’s nice to see that this thread has gained some traction. Let me try to clarify a bit more.

I also agree with @drsk that there is no violation of signatories happening just a re-think of what is actually a Party in DAML. DAML in its authorization model never accounted for how parties map to actual users with log in information. It is also not opinionated as to whether a party is an individual or a legal entity or a group of people. It is simply a mechanism for calculating permissions for updating a the active contract set and for disclosing part of that contract set. Mentioning Alice and Bob in our starter example as parties IMO is a good way to start but soon enough falls short when designing a production use-case.

For the read side it has become apparent that we do need a mechanism for reading public data. In DABL we have already introduced the concept of a PublicParty where you can get its Party value from a well known endpoint as well as get a JWT for it without any special permission. Then the app developer is burdened with performing multiple calls (one for the public party and one for the logged in user of the app) in order to properly render the desired state. Therefore a mechanism where a single call can return both public and user authorized data without compromising the principles of the DAML ledger is a win.

For the write side it gets a bit more complicated. As I understand it, the ledger api itself needs to change in order to support multiple submitters. I would have loved all along to be able to do something like submit [alice, bob] create Agreement with .. where agreement has both alice and bob as signatories. This is already the case with conjunction choices that can be taken in the body of other choices as long as the set of authorizers is a superset of the controller parties in the conjunction choice. Having the ability to outright create contracts with multiple signatories or outright exercise conjunction choices will enable faster upgrades and simpler workflows without I THINK (and that’s something that I need a language expert to answer. perhaps @Martin_Huschenbett or @meiersi) compromising the ledger model.

A use case for the write path by using a JWT for multiple parties is that of user groups. Alice has her own token for a Party on the ledger. However she is upgraded to an admin which is a party on the ledger and now can read and write as a both parties.
She can go ahead an exercise a choice that is modeled for the admin party since on every choice she takes she submits a set of authorizers containing her party and the admin party (ie a superset of the controllers that the choice needs).
Another use case is that of fetching ‘public’ contracts (where the public party is the observer or signatory). Think about the case where Alice exercises a choice where she is the controller and that choice needs to make use of some reference data where the public party observes. Since the public party is in the set of authorizers, it can be used for fetching the public contract in the body of the choice that Alice takes.

CO
cocreature
May 2020
dliakakos:

Having the ability to outright create contracts with multiple signatories or outright exercise conjunction choices will enable faster upgrades and simpler workflows without I THINK (and that’s something that I need a language expert to answer. perhaps @Martin_Huschenbett or @meiersi) compromising the ledger model.

The DAML Ledger model already allows multiple requesters on a commit, see Structure — Daml SDK 2.7.6 documentation details. Relevant section:

In the ledger model, a commit is allowed to have multiple requesters, although the current DAML Ledger API offers the request functionality only to individual parties.n

RA
Ratko_Veprek
May 2020
georg:

On the public read party: the problem with this is that you’ll only ever be able to see those contracts’ data, you’ll not be able to interact with them or use them in a choice using your own party. That’s severely limiting the usability of that approach imo

Why can’t you act on them? Isn’t that what flexible controllers would allow you to do?

GE
georg
May 2020

@Ratko_Veprek because it was only disclosed out-of-band via the public party. my own party doesn’t have visibility on that contract in terms of the ledger so I can’t fetch the contract.

RA
Ratko_Veprek
May 2020

@dliakakos so, the ledger-api itself should support what you are looking for. and i do see your point. for quite a while, we have said that we still need to add something like a “public section of the ledger”, which amounts to your broadcast. however, so far, this hasn’t been a top priority, so it was never followed through up to now.

however, if you look at the canton identity management system, it actually already supports public parties in theory.

with respect to the http-json api: i don’t think that the http-json api should try to implement different semantics on the permissioning / how to use parties. in that sense, i would also expect that you can du multi-party subscriptions there.

and btw, multi-party subscriptions were added three years ago because maintaining 100 open subscriptions, one for each party from a single app was a nightmare.

RA
Ratko_Veprek
May 2020
georg:

because it was only disclosed out-of-band via the public party. my own party doesn’t have visibility on that contract in terms of the ledger so I can’t fetch the contract.

Yes, but that’s related to another semantic issue, the fact that a contract-id are opaque. Once the meaning of contract-id is changed such that they also refer to the payload, we solve quite a few issues at once: public parties, out-of-band disclosure, read delegation.

GE
georg
May 2020

Agree. I’d be interested in @bernhard 's stance on what’s planned for the read model overhaul.

MA
MatthiasSchmalz
May 2020

I agree with @cocreature. From a conceptual point of view I expect we should be able to support submitting a command on behalf of multiple parties.

I think we don’t have it, because it has not been a priority. And it could be an expensive change, as it affects many components.

BE
bernhard
May 2020

I agree with all the problems/requirements stated here, and will add a few more. I talk about this topic as a whole as “Read Delegation”

Requirements: Given a contract ct with stakeholder party party_s controlled by user user_s and another party party_a controlled by user user_a

  1. user_s should have a way to make ct available to user_a for both read and write by party_a. Ie user_a can get ct from both the Ledger API and JSON API, and a way to interpret transactions that use ct as inputs.
  2. This mechanism should not require user_s to archive and recreate ct
  3. Nobody other than the signatories of ct and the two involved users and parties should need to know that this sharing has happened.
  4. The mechanism should be in DAML so that “read delegation” can be part of the application logic. E.g. user_s should be able to delegate party_s's the right to make ct available to party_a to another user/party
  5. The mechanism needs to work on any DAML Ledger
  6. The mechanism needs to work independent of Ledger Topology
  7. The mechanism needs to work in a dynamic topology where new parties join.

In addition to this, we have a few constraints that are expensive to lift:

  1. Parties do not have a cryptographic identity on the ledgers, only participants do
  2. Transactions are submitted by a single participant
  3. To interpret and submit a transaction, the submitting user must have access to sufficient information on the submitting Participant to submit the whole transaction. Ie there is not “interactive submission” where the Participant goes around the network to fetch data.
  4. Participants do not communicate “out of band”. ie there is no way for the contract data of ct to make its way from Participant 1 to Participant 2 without a transaction.

Solving this broad topic of “Read Delegation” is tough, and to answer your original question @dliakakos, yes, we have considered special “public” parties and handling this on the auth and API side, but that approach falls short or requires serious work to lift the constraints.

  • Requirement 1: Unless you have foreseen the ability to share a contract, you can’t add it after the fact. Stakeholders can by default not change the set of observers. Thus requirement 1 is not met.
  • Requirement 2: Using parties / observers requires ct to be archived and recreated whenever the set of observers changes. Some changes like adding a user/party to a group can be solved on the IAM/API level, but not all, so Requirement 2 is only partially met.
  • Requirement 3: Anyone that sees the contract sees to who it’s visible. Using “group” parties alleviates this problem, but does not remove it. Thus requirement 3 is only partially met.
  • Requirement 4: Since this mechanism manages read delegation using the IAM system, it’s completely outside of DAML. So requirement 4 is not met.
  • Requirement 5: This mechanism requires a single party like public to be hosted on all Participants. This puts a new requirement on DAML Ledgers (Parties being hosted for read/write on many nodes), that not all currently support. Furthermore, there is a completely open question as to the governance of such parties. In a fully distributed system, who holds the master key to public? For more fine-grained groups, who administers them? In other words, I think this mechanism works just fine for DABL and DAML on SQL where there’s a clear operator, but there are wide-open questions in distributed infrastructures. Ie Requirement 5 is not met.
  • Requirement 6: Due to constraints 2, 3 and 4, being able to read and submit as two or more parties relies on both parties being hosted on the same participant. Thus, this mechanism is highly dependent on ledger topology, meaning Requirement 6 is not met.
  • Requirement 7: Let’s say we have Alice and Bob each on their own Participants, and using a shared public party. Now Chloe comes along and connects her own Participant. Somehow she acquires the master key for public and informs the network that her Participant now has the right to read data for that party. Where’s the data coming from? The only people that have it are Alice and Bob. But by constraint 4, there is no mechanism to get it.

As you can see, the mechanism falls quite short of meeting what we need for “Read Delegation”. Even in simple cases like “public” data, I see problems. Removing those problems would require a lot of expensive work to lift the constraints, but would ultimately still only solve a few of the requirements. Hence, I do not believe that multi-party read/write via the API is the right mechanism.

So what is the right mechanism, I hear you ask? It comes in multiple steps:

First, we add a mechanism that does exactly what’s needed in Requirement 1. A way to get ct into party_a's view in such a way that it’s available for read/write. One way to do that is to just “attach” ct to a contract that party_a observes. This meets Requirements 2, 3, 4, 5, 6, 7 automatically.

This mechanism is quite low level - each “sharing” operation, requires a message contract, and the messages need to be updated whenever ct changes. Thus, you need a lot of app logic to make it happen, and the number of transactions explodes with a public contract and lots of parties.

Hence, the next steps are to optimize. The developer UX can be improved using a standard library of contracts and automation that just make this “broadcasting” happen. My original mock-up for DAML Triggers was actually based on exactly this idea.

Then the traffic problem has to be addressed. Rather than sharing “in band” using message contracts, the sharing has to be moved out of band, removing constraint 4. Some mechanism for the Participant of party_a to subscribe to the participant of party_s to receive any updates that party_a is entitled to. And here you can optimize a lot according to topology. If party_a and party_s are colocated, this sharing can be made near-zero cost.

DR
drsk
May 2020

While I agree that we don’t solve the general delegation problem with multi-party readAs and writeAs permissions, I think it’s still worth implementing this feature on the JSON API under an experimental feature flag. Implementation effort is very low as I understand, and it will allow us to gain more insights and experience into the problematic.

ER
eric_da
May 2020

agree with @drsk here

The general solution is prob far and many iterations away. In the meantime, we have a real & present dev roadblock that we can solve in a relatively straightforward way. My guess is that, over the long run, we will benefit from both the generic daml-level feature and the api-level feature and will find ways to utilize both.

LE
Leonid_Shlyapnikov
May 2020

@gerolf correct me if I am wrong. The multi-parties are discouraged. Support for multi-parties might/will be removed from the Ledger API.

@Martin_Huschenbett agreed (at least he did not oppose the idea suggested by @Stephen) that it makes more sense to implement multi-party support as part of the daml-ui client-side API (or maybe JSON API). The API user will have to provide multiple JWTs (one per party), daml-ui or JSON API will merge multiple requests (one per JWT) based on contract IDs.

That is the summary of the last meeting.

LE
Leonid_Shlyapnikov
May 2020
eric_da:

In the meantime, we have a real & present dev roadblock that we can solve in a relatively straightforward way.

@eric_da here is the ticket: Add multi-party support to JSON API JWT · Issue #5948 · digital-asset/daml · GitHub you can prioritize it.

In the meantime the solution is to send multiple requests, one per party/JWT and merge them on the client-side.

GE
gerolf
May 2020
Ratko_Veprek:

and btw, multi-party subscriptions were added three years ago because maintaining 100 open subscriptions, one for each party from a single app was a nightmare.

That’s not the reason I remember.
Besides that, would you expect a typical application having to manage subscriptions for so many parties at once? Even when filling a local ACS, it’s probably safer from a data segregation point of view to keep separate streams.

eric_da:

In the meantime, we have a real & present dev roadblock that we can solve in a relatively straightforward way.

As mentioned by @stefanobaghino-da already, multi party subscriptions come with a runtime cost (which depends on number of parties in the request and number of events in the transaction). Would an initial client side library solution work as well?

AN
anthony
Jun 2020

Moving this to General as it’s a very involved discussion without a singular answer :slight_smile:

← Back to Discussions