Skip to content

Commit

Permalink
Change Exercise by Key to send ExerciseByKeyCommand (digital-asset#4209)
Browse files Browse the repository at this point in the history
instead of lookup by key + ExerciseCommand with retrieved contract ID.

CHANGELOG_BEGIN
CHANGELOG_END
  • Loading branch information
leo-da authored and mergify[bot] committed Jan 24, 2020
1 parent 40ea33c commit 231b9c6
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import java.time.Instant

import com.digitalasset.api.util.TimeProvider
import com.digitalasset.daml.lf.data.ImmArray.ImmArraySeq
import com.digitalasset.http.CommandService.Error
import com.digitalasset.http.CommandService.{ExerciseCommandRef, Error}
import com.digitalasset.http.domain.{
ActiveContract,
Contract,
Expand Down Expand Up @@ -61,7 +61,7 @@ class CommandService(
def exercise(
jwt: Jwt,
jwtPayload: JwtPayload,
input: ExerciseCommand[lav1.value.Value, (domain.TemplateId.RequiredPkg, domain.ContractId)])
input: ExerciseCommand[lav1.value.Value, ExerciseCommandRef])
: Future[Error \/ ExerciseResponse[lav1.value.Value]] = {

val command = exerciseCommand(input)
Expand All @@ -76,25 +76,6 @@ class CommandService(
et.run
}

@SuppressWarnings(Array("org.wartremover.warts.Any"))
def exerciseWithResult(
jwt: Jwt,
jwtPayload: JwtPayload,
input: ExerciseCommand[lav1.value.Value, (domain.TemplateId.RequiredPkg, domain.ContractId)])
: Future[Error \/ lav1.value.Value] = {

val command = exerciseCommand(input)
val request = submitAndWaitRequest(jwtPayload, input.meta, command)

val et: EitherT[Future, Error, lav1.value.Value] = for {
response <- liftET(
logResult('exerciseWithResult, submitAndWaitForTransactionTree(jwt, request)))
result <- EitherT.either(exerciseResult(response))
} yield result

et.run
}

private def logResult[A](op: Symbol, fa: Future[A]): Future[A] = {
fa.onComplete {
case Failure(e) => logger.error(s"$op failure", e)
Expand All @@ -112,14 +93,21 @@ class CommandService(
}

private def exerciseCommand(
input: ExerciseCommand[lav1.value.Value, (domain.TemplateId.RequiredPkg, domain.ContractId)])
: lav1.commands.Command.Command.Exercise = {
Commands.exercise(
templateId = refApiIdentifier(input.reference._1),
contractId = input.reference._2,
choice = input.choice,
argument = input.argument)
}
input: ExerciseCommand[lav1.value.Value, ExerciseCommandRef]): lav1.commands.Command.Command =
input.reference match {
case -\/((templateId, contractKey)) =>
Commands.exerciseByKey(
templateId = refApiIdentifier(templateId),
contractKey = contractKey,
choice = input.choice,
argument = input.argument)
case \/-((templateId, contractId)) =>
Commands.exercise(
templateId = refApiIdentifier(templateId),
contractId = contractId,
choice = input.choice,
argument = input.argument)
}

private def submitAndWaitRequest(
jwtPayload: JwtPayload,
Expand Down Expand Up @@ -210,4 +198,6 @@ object CommandService {
s"CommandService Error, ${e.id: Symbol}: ${e.message: String}"
}
}

type ExerciseCommandRef = domain.ResolvedContractRef[lav1.value.Value]
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,19 @@ class ContractsService(
)
}

def resolve(jwt: Jwt, jwtPayload: JwtPayload, contractLocator: domain.ContractLocator[LfValue])
: Future[Option[(domain.TemplateId.RequiredPkg, domain.ContractId)]] =
def resolveContractReference(
jwt: Jwt,
jwtPayload: JwtPayload,
contractLocator: domain.ContractLocator[LfValue])
: Future[Option[domain.ResolvedContractRef[LfValue]]] =
contractLocator match {
case domain.EnrichedContractKey(templateId, key) =>
findByContractKey(jwt, jwtPayload.party, templateId, key).map(_.map(a =>
(a.templateId, a.contractId)))
Future.successful(resolveTemplateId(templateId).map(x => -\/(x -> key)))
case domain.EnrichedContractId(Some(templateId), contractId) =>
Future.successful(resolveTemplateId(templateId).map(a => (a, contractId)))
Future.successful(resolveTemplateId(templateId).map(x => \/-(x -> contractId)))
case domain.EnrichedContractId(None, contractId) =>
findByContractId(jwt, jwtPayload.party, None, contractId).map(_.map(a =>
(a.templateId, a.contractId)))
findByContractId(jwt, jwtPayload.party, None, contractId)
.map(_.map(a => \/-(a.templateId -> a.contractId)))
}

def lookup(jwt: Jwt, jwtPayload: JwtPayload, contractLocator: domain.ContractLocator[LfValue])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class Endpoints(

resolvedRef <- eitherT(
resolveReference(jwt, jwtPayload, cmd.reference)
): ET[(domain.TemplateId.RequiredPkg, domain.ContractId)]
): ET[domain.ResolvedContractRef[ApiValue]]

apiArg <- either(lfValueToApiValue(cmd.argument)): ET[ApiValue]

Expand Down Expand Up @@ -314,10 +314,17 @@ class Endpoints(
jwt: Jwt,
jwtPayload: JwtPayload,
reference: domain.ContractLocator[LfValue])
: Future[Error \/ (domain.TemplateId.RequiredPkg, domain.ContractId)] =
: Future[Error \/ domain.ResolvedContractRef[ApiValue]] =
contractsService
.resolve(jwt, jwtPayload, reference)
.map(_.toRightDisjunction(InvalidUserInput(ErrorMessages.cannotResolveTemplateId(reference))))
.resolveContractReference(jwt, jwtPayload, reference)
.map { o: Option[domain.ResolvedContractRef[LfValue]] =>
val a: Error \/ domain.ResolvedContractRef[LfValue] =
o.toRightDisjunction(InvalidUserInput(ErrorMessages.cannotResolveTemplateId(reference)))
a.flatMap {
case -\/((tpId, key)) => lfValueToApiValue(key).map(k => -\/((tpId, k)))
case a @ \/-((_, _)) => \/-(a)
}
}
}

object Endpoints {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ object domain {
type InputContractRef[+LfV] =
(TemplateId.OptionalPkg, LfV) \/ (Option[TemplateId.OptionalPkg], ContractId)

type ResolvedContractRef[+LfV] =
(TemplateId.RequiredPkg, LfV) \/ (TemplateId.RequiredPkg, ContractId)

case class ActiveContract[+LfV](
contractId: ContractId,
templateId: TemplateId.RequiredPkg,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,23 @@ object Commands extends StrictLogging {
)
}

def exerciseByKey(
templateId: lar.TemplateId,
contractKey: lav1.value.Value,
choice: lar.Choice,
argument: lav1.value.Value
): lav1.commands.Command.Command.ExerciseByKey = {

lav1.commands.Command.Command.ExerciseByKey(
lav1.commands.ExerciseByKeyCommand(
templateId = Some(lar.TemplateId.unwrap(templateId)),
contractKey = Some(contractKey),
choice = lar.Choice.unwrap(choice),
choiceArgument = Some(argument)
)
)
}

def submitAndWaitRequest(
ledgerId: lar.LedgerId,
applicationId: lar.ApplicationId,
Expand Down

0 comments on commit 231b9c6

Please sign in to comment.