diff --git a/ledger-api/grpc-definitions/com/daml/ledger/api/v1/event.proto b/ledger-api/grpc-definitions/com/daml/ledger/api/v1/event.proto index 2cf7f8fb87d1..7451d3d97e79 100644 --- a/ledger-api/grpc-definitions/com/daml/ledger/api/v1/event.proto +++ b/ledger-api/grpc-definitions/com/daml/ledger/api/v1/event.proto @@ -71,6 +71,7 @@ message CreatedEvent { repeated string signatories = 8; // The observers for this contract as specified explicitly by the template or implicitly as choice controllers. + // This field never contains parties that are signatories. // Required repeated string observers = 9; diff --git a/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/suites/ActiveContractsServiceIT.scala b/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/suites/ActiveContractsServiceIT.scala index ec0b540f0491..52611f0279fc 100644 --- a/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/suites/ActiveContractsServiceIT.scala +++ b/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/suites/ActiveContractsServiceIT.scala @@ -19,11 +19,13 @@ import com.daml.ledger.test.model.Test.{ Dummy, DummyFactory, DummyWithParam, + WithObservers, Witnesses => TestWitnesses, } import io.grpc.Status import scalaz.syntax.tag._ +import scala.collection.immutable.Seq import scala.concurrent.ExecutionContext class ActiveContractsServiceIT extends LedgerTestSuite { @@ -377,6 +379,21 @@ class ActiveContractsServiceIT extends LedgerTestSuite { } }) + test( + "ACSnoSignatoryObservers", + "The ActiveContractService should not return overlapping signatories and observers", + allocate(TwoParties), + )(implicit ec => { case Participants(Participant(ledger, alice, bob)) => + for { + _ <- ledger.create(alice, WithObservers(alice, Seq(alice, bob))) + contracts <- ledger.activeContracts(alice) + Seq(ce) = contracts + } yield assert( + ce.observers == Seq(bob), + s"Expected observers to only contain $bob, but received ${ce.observers}", + ) + }) + private def createDummyContracts(party: Party, ledger: ParticipantTestContext)(implicit ec: ExecutionContext ) = { diff --git a/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/suites/TransactionServiceIT.scala b/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/suites/TransactionServiceIT.scala index 48b76dc54de3..bbd71e5dba5f 100644 --- a/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/suites/TransactionServiceIT.scala +++ b/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/suites/TransactionServiceIT.scala @@ -38,6 +38,7 @@ import io.grpc.Status import scalaz.Tag import scala.collection.compat._ +import scala.collection.immutable.Seq import scala.collection.mutable import scala.concurrent.Future @@ -1083,6 +1084,31 @@ class TransactionServiceIT extends LedgerTestSuite { } }) + test( + "TXnoSignatoryObservers", + "transactions' created events should not return overlapping signatories and observers", + allocate(TwoParties), + )(implicit ec => { case Participants(Participant(ledger, alice, bob)) => + for { + _ <- ledger.create(alice, WithObservers(alice, Seq(alice, bob))) + flat <- ledger.flatTransactions(alice) + Seq(flatTx) = flat + Seq(flatWo) = createdEvents(flatTx) + tree <- ledger.transactionTrees(alice) + Seq(treeTx) = tree + Seq(treeWo) = createdEvents(treeTx) + } yield { + assert( + flatWo.observers == Seq(bob), + s"Expected observers to only contain $bob, but received ${flatWo.observers}", + ) + assert( + treeWo.observers == Seq(bob), + s"Expected observers to only contain $bob, but received ${treeWo.observers}", + ) + } + }) + test( "TXFlatTransactionsWrongLedgerId", "The getTransactions endpoint should reject calls with the wrong ledger identifier",