mirror of
https://github.com/digital-asset/daml.git
synced 2024-09-17 15:57:21 +03:00
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:
parent
2e3a87934b
commit
8158269b7d
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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] =
|
||||
|
@ -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 => ""
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
)
|
||||
))
|
||||
}
|
||||
|
@ -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(_))
|
||||
|
Loading…
Reference in New Issue
Block a user