Remove ExercisedEvent in Event oneof. (#1067)

* Remove ExercisedEvent in Event oneof.

The Event message is only used in the Transaction message. Flat
transactions do not contain exercised events, but only created and
archived events. Therefore we can remove the ExercisedEvent from the
Event oneof, without breaking transport compatibility.

HOWEVER: The Java Bindings used to use the data.Event class for both flat
transactions and transaction trees. To properly represent the actual
event types in the two transaction structures,
1) Event is now and interface and is only used in the Transaction class.
2) there is a new interface TreeEvent, which is used in the TransactionTree class.

* CreatedEvent implements Event and TreeEvent
* ExercisedEvent implements TreeEvent
* ArchivedEvent implements Event

Some "pathological" cases where an occurrence of an exercised event
would have resulted only in an exception, are now removed (see change in
LedgerApiV1.scala).

Fixes #960.
This commit is contained in:
Gerolf Seitz 2019-05-13 14:36:13 +02:00 committed by GitHub
parent 2e3a87934b
commit 8158269b7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 156 additions and 167 deletions

View File

@ -9,8 +9,43 @@ This page contains release notes for the SDK.
HEAD — ongoing
--------------
DAML
~~~~
- **DAML Standard Library**: Add ``String`` as a compatibility alias for ``Text``.
Ledger API
~~~~~~~~~~
- **BREAKING** Removed the unused field :ref:`com.digitalasset.ledger.api.v1.ExercisedEvent` from :ref:`com.digitalasset.ledger.api.v1.Event`,
because a :ref:`com.digitalasset.ledger.api.v1.Transaction` never contains exercised events (only created and archived events): `#960 <https://github.com/digital-asset/daml/issues/960>`_
This change is *backwards compatible on the transport level*, meaning:
- new versions of ledger language bindings will work with previous versions of the Sandbox, because the field was never populated
- previous versions of the ledger language bindings will work with new versions of the Sandbox, as the field was removed without any change in observable behavior
How to migrate:
- If you check for the presence of :ref:`com.digitalasset.ledger.api.v1.ExercisedEvent` when handling a :ref:`com.digitalasset.ledger.api.v1.Transaction`, you have to remove this code now.
Java Bindings
~~~~~~~~~~~~~
- **BREAKING** Reflect the breaking change of Ledger API in the event class hierarchy:
- Changed ``data.Event`` from an abstract class to an interface, representing events in a flat transaction.
- Added interface ``data.TreeEvent``, representing events in a transaction tree.
- ``data.CreatedEvent`` and ``data.ArchivedEvent`` now implement ``data.Event``.
- ``data.CreatedEvent`` and ``data.ExercisedEvent`` now implement ``data.TreeEvent``.
- ``data.TransactionTree#eventsById`` is now ``Map<String, TreeEvent>`` (was previously ``Map<String, Event>``).
How to migrate:
- If you are processing ``data.TransactionTree`` objects, you need to change the type of the processed events from ``data.Event`` to ``data.TreeEvent``.
- If you are checking for the presense of exercised events when processing ``data.Transaction`` objects, you can remove that code now.
It would never have triggered in the first place, as transactions do not contain exercised events.
.. _release-0-12-17:
0.12.17 - 2019-05-10

View File

@ -47,9 +47,8 @@ object Event {
final implicit class ApiEventOps(val apiEvent: api.event.Event.Event) extends AnyVal {
def convert: String \/ Event = apiEvent match {
case api.event.Event.Event.Archived(event) =>
s"Unexpected `Archived` event: $event. Only `Created` and `Exercised` events are expected.".left
s"Unexpected `Archived` event: $event. Only `Created` events are expected.".left
case api.event.Event.Event.Created(event) => event.convert
case api.event.Event.Event.Exercised(event) => event.convert
case api.event.Event.Event.Empty => "Unexpected `Empty` event.".left
}
}

View File

@ -3,6 +3,7 @@
package com.daml.ledger.rxjava.components.helpers;
import com.daml.ledger.javaapi.data.Event;
import com.daml.ledger.javaapi.data.Transaction;
import org.checkerframework.checker.nullness.qual.NonNull;
@ -10,7 +11,7 @@ import java.time.Instant;
import java.util.Objects;
/**
* A {@link Transaction} without the {@link com.daml.ledger.javaapi.data.Event}s.
* A {@link Transaction} without the {@link Event}s.
*/
public class TransactionContext implements CreatedContractContext {

View File

@ -10,8 +10,9 @@ import java.util.Collections
import com.daml.ledger.javaapi.data
import com.daml.ledger.testkit.services.TransactionServiceImpl
import com.daml.ledger.testkit.services.TransactionServiceImpl.LedgerItem
import com.digitalasset.ledger.api.v1.event.Event.Event.{Archived, Created, Exercised}
import com.digitalasset.ledger.api.v1.event.Event.Event.{Archived, Created}
import com.digitalasset.ledger.api.v1.event.{ArchivedEvent, CreatedEvent, Event, ExercisedEvent}
import com.digitalasset.ledger.api.v1.transaction.TreeEvent.Kind.Exercised
import com.digitalasset.ledger.api.v1.value
import com.digitalasset.ledger.api.v1.value.Value.Sum
import com.digitalasset.ledger.api.v1.value.{Identifier, Record, RecordField, Value, Variant}
@ -247,7 +248,7 @@ object TransactionGenerator {
)
val eventGen: Gen[(Event, data.Event)] =
Gen.oneOf(createdEventGen, archivedEventGen, exercisedEventGen).map {
Gen.oneOf(createdEventGen, archivedEventGen).map {
case (scalaEvent, javaEvent) => (Event(scalaEvent), javaEvent)
}

View File

@ -9,7 +9,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.List;
import java.util.Objects;
public final class ArchivedEvent extends Event {
public final class ArchivedEvent implements Event {
private final List<String> witnessParties;

View File

@ -9,7 +9,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.List;
import java.util.Objects;
public final class CreatedEvent extends Event {
public final class CreatedEvent implements Event, TreeEvent {
private final @NonNull List<@NonNull String> witnessParties;

View File

@ -4,72 +4,29 @@
package com.daml.ledger.javaapi.data;
import com.digitalasset.ledger.api.v1.EventOuterClass;
import com.digitalasset.ledger.api.v1.TransactionOuterClass;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.List;
import java.util.stream.Collectors;
public abstract class Event {
/**
* This interface represents events in {@link Transaction}s.
*
* @see CreatedEvent
* @see ArchivedEvent
* @see Transaction
*
*/
public interface Event {
public abstract @NonNull List<@NonNull String> getWitnessParties();
@NonNull List<@NonNull String> getWitnessParties();
@NonNull
public abstract String getEventId();
@NonNull String getEventId();
@NonNull
public abstract Identifier getTemplateId();
@NonNull Identifier getTemplateId();
@NonNull
public abstract String getContractId();
@NonNull String getContractId();
public static Event fromProtoEvent(EventOuterClass.Event event) {
if (event.hasCreated()) {
EventOuterClass.CreatedEvent createdEvent = event.getCreated();
return new CreatedEvent(createdEvent.getWitnessPartiesList(), createdEvent.getEventId(),
Identifier.fromProto(createdEvent.getTemplateId()),
createdEvent.getContractId(), Record.fromProto(createdEvent.getCreateArguments()));
} else if (event.hasArchived()) {
EventOuterClass.ArchivedEvent archivedEvent = event.getArchived();
return new ArchivedEvent(archivedEvent.getWitnessPartiesList(), archivedEvent.getEventId(),
Identifier.fromProto(archivedEvent.getTemplateId()),
archivedEvent.getContractId());
} else if (event.hasExercised()) {
EventOuterClass.ExercisedEvent exercisedEvent = event.getExercised();
return new ExercisedEvent(exercisedEvent.getWitnessPartiesList(), exercisedEvent.getEventId(),
Identifier.fromProto(exercisedEvent.getTemplateId()),
exercisedEvent.getContractId(), exercisedEvent.getContractCreatingEventId(),
exercisedEvent.getChoice(), Value.fromProto(exercisedEvent.getChoiceArgument()),
exercisedEvent.getActingPartiesList(), exercisedEvent.getConsuming(),
exercisedEvent.getChildEventIdsList(), Value.fromProto(exercisedEvent.getExerciseResult()));
} else {
throw new UnsupportedEventTypeException(event.toString());
}
}
public static Event fromProtoTreeEvent(TransactionOuterClass.TreeEvent event) {
if (event.hasCreated()) {
EventOuterClass.CreatedEvent createdEvent = event.getCreated();
return new CreatedEvent(createdEvent.getWitnessPartiesList(), createdEvent.getEventId(),
Identifier.fromProto(createdEvent.getTemplateId()),
createdEvent.getContractId(), Record.fromProto(createdEvent.getCreateArguments()));
} else if (event.hasExercised()) {
EventOuterClass.ExercisedEvent exercisedEvent = event.getExercised();
return new ExercisedEvent(exercisedEvent.getWitnessPartiesList(), exercisedEvent.getEventId(),
Identifier.fromProto(exercisedEvent.getTemplateId()),
exercisedEvent.getContractId(), exercisedEvent.getContractCreatingEventId(),
exercisedEvent.getChoice(), Value.fromProto(exercisedEvent.getChoiceArgument()),
exercisedEvent.getActingPartiesList(), exercisedEvent.getConsuming(),
exercisedEvent.getChildEventIdsList(), Value.fromProto(exercisedEvent.getExerciseResult()));
} else {
throw new UnsupportedEventTypeException(event.toString());
}
}
public EventOuterClass.Event toProtoEvent() {
default EventOuterClass.Event toProtoEvent() {
EventOuterClass.Event.Builder eventBuilder = EventOuterClass.Event.newBuilder();
if (this instanceof ArchivedEvent) {
ArchivedEvent event = (ArchivedEvent) this;
@ -77,32 +34,19 @@ public abstract class Event {
} else if (this instanceof CreatedEvent) {
CreatedEvent event = (CreatedEvent) this;
eventBuilder.setCreated(event.toProto());
} else if (this instanceof ExercisedEvent) {
ExercisedEvent event = (ExercisedEvent) this;
eventBuilder.setExercised(event.toProto());
} else {
throw new RuntimeException("this should be ArchivedEvent or CreatedEvent or ExercisedEvent, found " + this.toString());
}
return eventBuilder.build();
}
public TransactionOuterClass.TreeEvent toProtoTreeEvent() {
TransactionOuterClass.TreeEvent.Builder eventBuilder = TransactionOuterClass.TreeEvent.newBuilder();
if (this instanceof CreatedEvent) {
CreatedEvent event = (CreatedEvent) this;
eventBuilder.setCreated(event.toProto());
} else if (this instanceof ExercisedEvent) {
ExercisedEvent event = (ExercisedEvent) this;
eventBuilder.setExercised(event.toProto());
static Event fromProtoEvent(EventOuterClass.Event event) {
if (event.hasCreated()) {
return CreatedEvent.fromProto(event.getCreated());
} else if (event.hasArchived()) {
return ArchivedEvent.fromProto(event.getArchived());
} else {
throw new RuntimeException("this should be CreatedEvent or ExercisedEvent, found " + this.toString());
throw new UnsupportedEventTypeException(event.toString());
}
return eventBuilder.build();
}
}
class UnsupportedEventTypeException extends RuntimeException {
public UnsupportedEventTypeException(String eventStr) {
super("Unsupported event " + eventStr);
}
}

View File

@ -8,9 +8,8 @@ import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public class ExercisedEvent extends Event {
public class ExercisedEvent implements TreeEvent {
private final List<String> witnessParties;

View File

@ -6,7 +6,6 @@ package com.daml.ledger.javaapi.data;
import com.digitalasset.ledger.api.v1.TransactionOuterClass;
import org.checkerframework.checker.nullness.qual.NonNull;
import javax.annotation.Nonnull;
import java.time.Instant;
import java.util.List;
import java.util.Map;
@ -23,13 +22,13 @@ public class TransactionTree {
private final Instant effectiveAt;
private final Map<String, Event> eventsById;
private final Map<String, TreeEvent> eventsById;
private final List<String> rootEventIds;
private final String offset;
public TransactionTree(@NonNull String transactionId, @NonNull String commandId, @NonNull String workflowId, @NonNull Instant effectiveAt, @NonNull Map<@NonNull String, @NonNull Event> eventsById, List<String> rootEventIds, @NonNull String offset) {
public TransactionTree(@NonNull String transactionId, @NonNull String commandId, @NonNull String workflowId, @NonNull Instant effectiveAt, @NonNull Map<@NonNull String, @NonNull TreeEvent> eventsById, List<String> rootEventIds, @NonNull String offset) {
this.transactionId = transactionId;
this.commandId = commandId;
this.workflowId = workflowId;
@ -44,11 +43,11 @@ public class TransactionTree {
String commandId = tree.getCommandId();
String workflowId = tree.getWorkflowId();
Instant effectiveAt = Instant.ofEpochSecond(tree.getEffectiveAt().getSeconds(), tree.getEffectiveAt().getNanos());
Map<String, Event> eventsById = tree.getEventsByIdMap().values().stream().collect(Collectors.toMap(e -> {
Map<String, TreeEvent> eventsById = tree.getEventsByIdMap().values().stream().collect(Collectors.toMap(e -> {
if (e.hasCreated()) return e.getCreated().getEventId();
else if (e.hasExercised()) return e.getExercised().getEventId();
else throw new IllegalArgumentException("Event is neither created not exercied: " + e);
}, Event::fromProtoTreeEvent));
}, TreeEvent::fromProtoTreeEvent));
List<String> rootEventIds = tree.getRootEventIdsList();
String offset = tree.getOffset();
return new TransactionTree(transactionId, commandId, workflowId, effectiveAt, eventsById, rootEventIds, offset);
@ -60,7 +59,7 @@ public class TransactionTree {
.setCommandId(this.commandId)
.setWorkflowId(this.workflowId)
.setEffectiveAt(com.google.protobuf.Timestamp.newBuilder().setSeconds(this.effectiveAt.getEpochSecond()).setNanos(this.effectiveAt.getNano()).build())
.putAllEventsById(this.eventsById.values().stream().collect(Collectors.toMap(Event::getEventId, Event::toProtoTreeEvent)))
.putAllEventsById(this.eventsById.values().stream().collect(Collectors.toMap(TreeEvent::getEventId, TreeEvent::toProtoTreeEvent)))
.addAllRootEventIds(this.rootEventIds)
.setOffset(this.offset)
.build();
@ -87,7 +86,7 @@ public class TransactionTree {
}
@NonNull
public Map<String, Event> getEventsById() {
public Map<String, TreeEvent> getEventsById() {
return eventsById;
}

View File

@ -0,0 +1,52 @@
// Copyright (c) 2019 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
package com.daml.ledger.javaapi.data;
import com.digitalasset.ledger.api.v1.TransactionOuterClass;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.List;
/**
* This interface represents events in {@link TransactionTree}s.
*
* @see CreatedEvent
* @see ExercisedEvent
* @see TransactionTree
*/
public interface TreeEvent {
@NonNull List<@NonNull String> getWitnessParties();
@NonNull String getEventId();
@NonNull Identifier getTemplateId();
@NonNull String getContractId();
default TransactionOuterClass.TreeEvent toProtoTreeEvent() {
TransactionOuterClass.TreeEvent.Builder eventBuilder = TransactionOuterClass.TreeEvent.newBuilder();
if (this instanceof CreatedEvent) {
CreatedEvent event = (CreatedEvent) this;
eventBuilder.setCreated(event.toProto());
} else if (this instanceof ExercisedEvent) {
ExercisedEvent event = (ExercisedEvent) this;
eventBuilder.setExercised(event.toProto());
} else {
throw new RuntimeException("this should be CreatedEvent or ExercisedEvent, found " + this.toString());
}
return eventBuilder.build();
}
static TreeEvent fromProtoTreeEvent(TransactionOuterClass.TreeEvent event) {
if (event.hasCreated()) {
return CreatedEvent.fromProto(event.getCreated());
} else if (event.hasExercised()) {
return ExercisedEvent.fromProto(event.getExercised());
} else {
throw new UnsupportedEventTypeException(event.toString());
}
}
}

View File

@ -0,0 +1,10 @@
// Copyright (c) 2019 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
package com.daml.ledger.javaapi.data;
public class UnsupportedEventTypeException extends RuntimeException {
public UnsupportedEventTypeException(String eventStr) {
super("Unsupported event " + eventStr);
}
}

View File

@ -184,7 +184,6 @@ object Generators {
Gen.oneOf(
createdEventGen.map(e => (b: EventOuterClass.Event.Builder) => b.setCreated(e).build()),
archivedEventGen.map(e => (b: EventOuterClass.Event.Builder) => b.setArchived(e).build()),
exercisedEventGen.map(e => (b: EventOuterClass.Event.Builder) => b.setExercised(e).build())
)
val createdEventGen: Gen[EventOuterClass.CreatedEvent] =

View File

@ -7,7 +7,7 @@ import java.util.concurrent.atomic.AtomicReference
import com.daml.ledger.testkit.services.TransactionServiceImpl.LedgerItem
import com.digitalasset.ledger.api.v1.event.Event
import com.digitalasset.ledger.api.v1.event.Event.Event.{Archived, Created, Empty, Exercised}
import com.digitalasset.ledger.api.v1.event.Event.Event.{Archived, Created, Empty}
import com.digitalasset.ledger.api.v1.ledger_offset.LedgerOffset
import com.digitalasset.ledger.api.v1.ledger_offset.LedgerOffset.LedgerBoundary.{
LEDGER_BEGIN,
@ -153,7 +153,6 @@ object TransactionServiceImpl {
def eventId(event: Event): String = event.event match {
case Archived(archivedEvent) => archivedEvent.eventId
case Created(createdEvent) => createdEvent.eventId
case Exercised(exercisedEvent) => exercisedEvent.eventId
case Empty => ""
}

View File

@ -6,7 +6,7 @@ package com.digitalasset.ledger.client.binding
import akka.NotUsed
import akka.stream.scaladsl.Flow
import com.digitalasset.ledger.api.refinements.ApiTypes._
import com.digitalasset.ledger.api.v1.event.Event.Event.{Archived, Created, Empty, Exercised}
import com.digitalasset.ledger.api.v1.event.Event.Event.{Archived, Created, Empty}
import com.digitalasset.ledger.api.v1.event._
import com.digitalasset.ledger.api.v1.ledger_offset.LedgerOffset
import com.digitalasset.ledger.api.v1.ledger_offset.LedgerOffset.Value.Absolute
@ -30,8 +30,6 @@ object DomainTransactionMapper {
private final case class RequiredFieldDoesNotExistError(field: String)
extends InputValidationError
private final case object EmptyEvent extends InputValidationError
private final case class UnexpectedExercisedEvent(event: ExercisedEvent)
extends InputValidationError
}
class DomainTransactionMapper(decoder: DecoderType) extends LazyLogging {
@ -92,9 +90,6 @@ class DomainTransactionMapper(decoder: DecoderType) extends LazyLogging {
.fold(logAndDiscard(createdEvent), mapCreatedEvent(createdEvent, _).map(Some.apply))
case Archived(archivedEvent) =>
mapArchivedEvent(archivedEvent).map(Some.apply)
case Exercised(exercisedEvent) =>
logger.error("Exercised event should not come from the transactions endpoint")
Left(UnexpectedExercisedEvent(exercisedEvent))
case Empty =>
Left(EmptyEvent)
}

View File

@ -11,30 +11,23 @@ import "com/digitalasset/ledger/api/v1/value.proto";
option java_outer_classname = "EventOuterClass";
option java_package = "com.digitalasset.ledger.api.v1";
// An event on the ledger can either be the creation or the archiving of
// a contract, or the exercise of a choice on a contract.
//
// The ``GetTransactionTrees`` response will only contain create and
// exercise events. Archive events correspond to consuming exercise
// events.
// An event in the flat transaction stream can either be the creation
// or the archiving of a contract.
//
// In the transaction service the events are restricted to the events
// visible for the parties specified in the transaction filter. Each
// event message type below contains a ``witness_parties`` field which
// indicates the subset of the requested parties that can see the event
// in question.
//
// However, note that transaction _trees_ might contain events with
// _no_ witness parties, which were included simply because they were
// children of events which have witnesses. On the other hand, on
// the flat transaction stream you'll only receive events that have
// witnesses.
// in question. In the flat transaction stream you'll only receive events
// that have witnesses.
message Event {
oneof event {
CreatedEvent created = 1;
ExercisedEvent exercised = 2;
ArchivedEvent archived = 3;
}
// see https://github.com/digital-asset/daml/issues/960
reserved 2;
reserved "exercised";
}
// Records that a contract has been created, and choices may now be exercised on it.

View File

@ -54,6 +54,12 @@ message TransactionTree {
}
// Each tree event message type below contains a ``witness_parties`` field which
// indicates the subset of the requested parties that can see the event
// in question.
// Note that transaction trees might contain events with
// _no_ witness parties, which were included simply because they were
// children of events which have witnesses.
message TreeEvent {
oneof kind {
CreatedEvent created = 1;

View File

@ -4,8 +4,8 @@
package com.digitalasset.platform.api.v1.event
import com.digitalasset.ledger.api.domain.{ContractId, EventId}
import com.digitalasset.ledger.api.v1.event.Event.Event.{Archived, Created, Empty}
import com.digitalasset.ledger.api.v1.event.{CreatedEvent, Event, ExercisedEvent}
import com.digitalasset.ledger.api.v1.event.Event.Event.{Archived, Created, Empty, Exercised}
import com.digitalasset.ledger.api.v1.transaction.TreeEvent
import com.digitalasset.ledger.api.v1.transaction.TreeEvent.Kind.{
Created => TreeCreated,
@ -41,20 +41,17 @@ object EventOps {
def eventId: EventId = event match {
case Archived(value) => EventId(value.eventId)
case Created(value) => EventId(value.eventId)
case Exercised(value) => EventId(value.eventId)
case Empty => throw new IllegalArgumentException("Cannot extract Event ID from Empty event.")
}
def witnesses: Seq[String] = event match {
case c: Created => c.value.witnessParties
case e: Exercised => e.value.witnessParties
case a: Archived => a.value.witnessParties
case Empty => Seq.empty
}
def templateId: String = event match {
case c: Created => c.templateId
case e: Exercised => e.templateId
case a: Archived => a.templateId
case Empty =>
throw new IllegalArgumentException("Cannot extract Template ID from Empty event.")
@ -63,14 +60,12 @@ object EventOps {
def contractId: ContractId = event match {
case Archived(value) => ContractId(value.contractId)
case Created(value) => ContractId(value.contractId)
case Exercised(value) => ContractId(value.contractId)
case Empty =>
throw new IllegalArgumentException("Cannot extract contractId from Empty event.")
}
def withWitnesses(witnesses: Seq[String]): Event.Event = event match {
case c: Created => Created(c.value.copy(witnessParties = witnesses))
case e: Exercised => Exercised(e.value.copy(witnessParties = witnesses))
case a: Archived => Archived(a.value.copy(witnessParties = witnesses))
case Empty => Empty
}

View File

@ -4,7 +4,7 @@
package com.digitalasset.platform.server.services.transaction
import com.digitalasset.ledger.api.domain.ContractId
import com.digitalasset.ledger.api.v1.event.Event.Event.{Archived, Created, Empty, Exercised}
import com.digitalasset.ledger.api.v1.event.Event.Event.{Archived, Created, Empty}
import com.digitalasset.ledger.api.v1.event.{CreatedEvent, Event}
import com.digitalasset.platform.api.v1.event.EventOps._
@ -88,9 +88,6 @@ object TransientContractRemover {
}
// Illegal cases
case Exercised(value) =>
throw new IllegalArgumentException(
s"Received unexpected Exercise event ${value.eventId} in transient contract removal. Only Create and Archive are allowed")
case Empty =>
throw new IllegalArgumentException(
s"Received unexpected Empty event in transient contract removal. Only Create and Archive are allowed")

View File

@ -1045,7 +1045,6 @@ class TransactionServiceIT
.map(_.event match {
case Archived(v) => v.eventId
case Created(v) => v.eventId
case Event.Event.Exercised(v) => v.eventId
case Event.Event.Empty => fail(s"Received empty event in $tx")
})
.value
@ -1115,7 +1114,6 @@ class TransactionServiceIT
.map(_.event match {
case Archived(v) => v.eventId
case Created(v) => v.eventId
case Event.Event.Exercised(v) => v.eventId
case Event.Event.Empty => fail(s"Received empty event in $tx")
})
.value
@ -1384,29 +1382,14 @@ class TransactionServiceIT
ledgerBegin,
Some(ledgerEnd),
TransactionFilter(Map("Bob" -> Filters())))
.runWith(Sink.seq)
val txsF = context.transactionClient
.getTransactions(
ledgerBegin,
Some(ledgerEnd),
TransactionFilter(Map("Bob" -> Filters())))
.map(_.eventsById.values)
.mapConcat(context.testingHelpers.exercisedEventsInNodes(_).toList)
.map(_.exerciseResult)
.runWith(Sink.seq)
for {
txs <- txsF
trees <- treesF
_ = txs.map(_.transactionId) shouldEqual trees.map(_.transactionId)
} yield {
for {
tx <- txs
exEvents = context.testingHelpers.exercisedEventsIn(tx)
_ = exEvents should not be empty
exEvent <- exEvents
} yield {
exEvent.exerciseResult should not be empty
}
treesF.map { results =>
all(results) should not be empty
}
succeed
}
}

View File

@ -13,7 +13,7 @@ import com.digitalasset.ledger.api.v1.command_service.{
import com.digitalasset.ledger.api.v1.command_submission_service.SubmitRequest
import com.digitalasset.ledger.api.v1.commands.{CreateCommand, ExerciseCommand}
import com.digitalasset.ledger.api.v1.completion.Completion
import com.digitalasset.ledger.api.v1.event.Event.Event.{Archived, Created, Exercised}
import com.digitalasset.ledger.api.v1.event.Event.Event.{Archived, Created}
import com.digitalasset.ledger.api.v1.event.{ArchivedEvent, CreatedEvent, Event, ExercisedEvent}
import com.digitalasset.ledger.api.v1.ledger_offset.LedgerOffset
import com.digitalasset.ledger.api.v1.transaction.{Transaction, TransactionTree, TreeEvent}
@ -296,11 +296,6 @@ class LedgerTestingHelpers(
case TreeEvent.Kind.Exercised(exercisedEvent) => exercisedEvent
}(breakOut)
def exercisedEventsIn(transaction: Transaction): Seq[ExercisedEvent] =
transaction.events.map(_.event).collect {
case Exercised(exercisedEvent) => exercisedEvent
}
def archivedEventsIn(transaction: Transaction): Seq[ArchivedEvent] =
transaction.events.map(_.event).collect {
case Archived(archivedEvent) => archivedEvent

View File

@ -3,7 +3,7 @@
package com.digitalasset.platform.sandbox.services.transaction
import com.digitalasset.ledger.api.v1.event.Event.Event.{Archived, Created, Exercised}
import com.digitalasset.ledger.api.v1.event.Event.Event.{Archived, Created}
import com.digitalasset.ledger.api.v1.event._
import com.digitalasset.ledger.api.v1.transaction_filter.{
Filters,
@ -64,7 +64,6 @@ class EventFilterSpec extends WordSpec with Matchers with ScalaFutures with Opti
"filtered by TemplateIds" should {
runTemplateFilterAssertions("CreatedEvent")(createdEvent)
runTemplateFilterAssertions("ArchivedEvent")(archivedEvent)
runTemplateFilterAssertions("ExercisedEvent")(exercisedEvent)
"remove non-requesting witnesses from the disclosed event" in {
val resultO = filter(createdEvent(party1, templateId1)).map(_.witnesses)
@ -126,15 +125,4 @@ class EventFilterSpec extends WordSpec with Matchers with ScalaFutures with Opti
witnessParties = Seq(party, otherPartyWhoSeesEvents)
)
))
private def exercisedEvent(party: String, templateId: Identifier) =
Event(
Exercised(
ExercisedEvent(
eventId = eventId,
contractId = contractId,
templateId = Some(templateId),
witnessParties = Seq(party, otherPartyWhoSeesEvents)
)
))
}

View File

@ -133,7 +133,6 @@ case object LedgerApiV1 {
workflowId: ApiTypes.WorkflowId,
parentId: Option[ApiTypes.EventId] = None
): Result[List[Model.Event]] = {
com.digitalasset.ledger.api.v1.event.Event.Event.Exercised
event match {
case V1.transaction.TreeEvent(V1.transaction.TreeEvent.Kind.Created(ev)) =>
readEventCreated(ev, transactionId, workflowId, parentId, ctx).map(List(_))