[engine] Engine support for Consortium Party Primitives
See original GitHub issueSupport for consortium party primitives in Daml, LF and the engine.
Here is the design document.
Overview
A consortium is represented by a Party in the Daml language. The essence of a consortium is that it acts with the combined authority of its members, which are also represented as Parties in Daml. A consortium party will have special rules for validation: say 2/3 of its member parties will be required to validate. Also, the membership of a consortium can change dynamically over time. But neither of these aspects are directly visible or represented at the Daml language level. More importantly, a consortium party is unable to submit to the ledger, because unlike other parties, a consortium party does not reside on any given participant. So without any new functionality it would be impossible to obtain an active-contract signed by a consortium party.
The proposed new functionality is for a Daml-LF builtin which dynamically obtains the authorization of a consortium party when executed in the context of the authorization of the consortium members. From the point of view of the Daml Engine, obtaining the authority of a consortium party requires delegating the question to the enclosing ledger, and recording the answer in the constructed transaction.
Daml
The new functionality will be exposed to the user via a new Daml primitive:
withAuthorityOf : [Party] -> Update a -> Update a
The behaviour of withAuthorityOf parties
will attempt to place the set of authorizing parties to the given parties
, based on the authority of the current authorization context . For more precise behavior, see summary below.
Example
Here is a small example, slightly simplified from the one given in the design document, so that the Accept
and Ratify
stages are made explicit. It assumes a new primitive withAuthorityOf
with the above type.
template HasConsortiumAutority
with
consortiumParty: Party
where
signatory consortiumParty
template ProposeConsortiumAuthority
with
proposer: Party
accepted: [Party]
obs: [Party]
consortiumParty: Party
where
signatory proposer, accepted
observer obs
choice Accept : ContractId ProposeConsortiumAuthority
with who: Party
controller who
do create this with accepted = who :: this.accepted
choice Ratify : ContractId HasConsortiumAutority controller proposer
do
withAuthorityOf accepted $ do
withAuthorityOf [consortiumParty] $ do
create HasConsortiumAutority with consortiumParty
Implementation checklist
- New Daml primitive:
actingAsConsortium
- (Haskell) compilation in
LFConversion.hs
- (Haskell) type checker
- (Haskell)
.dar
encode(decode) - extension of LF
.proto
format - (Scala)
.dar
decode(encode) - New LF update expression form
UpdateActingAsConsortium
inAst.scala
- Internal LF parser
ExprParser.scala
- Scala type checker
Typing.scala
- Scala utils:
AstRewriter
,ExprIterable
etc - Compilation to speedy
PhaseOne.scala
- New speedy builtin:
SBActingAsConsortium
inSBuiltin.scala
- Implementation of
SBActingAsConsortium
- New speedy result/callback in
SResult.scala
- New engine result/callback in
engine/Result.scala
- Support in
PartialTransaction.scala
andTransaction.scala
- TX
.proto
changes
Issue Analytics
- State:
- Created 9 months ago
- Comments:14 (14 by maintainers)
Top GitHub Comments
Thanks you everyone for your input. To summarise…
The new operator is not specific to consortium parties, and so should be named more generally. The consensus seems to be for
withAuthorityOf
.Choices for:
withAuthorityOf
with the semantics as described by Andreas above:
P
are not a subset of the current authorization contextC
, then Daml engine asks the ledger whether C suffices to authorize the parties inP - C
. If the ledger responds no, then interpretation fails with an uncatchable exception.P
are a subset of the current authorization context, then the authorization context is set toP
for the execution of the given Update.C
.Because the semantics are to replace and not extend the current authority context, the operator can also be used to restrict the current authority.
For validation, we wont need a new node type in the transaction tree to capture exactly where calls to
withAuthorityOf
are made. Instead we can just record (on the side; per exercise-node) the set of authority-requests made to the ledger during the construction of this node.An authority-request of the ledger is of the form:
C
suffices forP-C
.Note specifically that in the case that authority is being restricted (
P
is a subset ofC
) then no request will be made to the ledger, and nothing will be recorded in the transaction.Issue description and example updated.