From 2efd44d46bd6906090a654fd620a9d1b3e2bf80e Mon Sep 17 00:00:00 2001 From: Ross Nicoll Date: Fri, 13 Jan 2017 14:10:54 +0000 Subject: [PATCH] Clean up semantics of composite clauses This deprecates the existing composition clauses and adds new better named versions, as well as changing 'AnyOf' to require at least one matching subclase (better matching the name of the clause). --- .../core/contracts/clauses/AllComposition.kt | 33 +------------ .../net/corda/core/contracts/clauses/AllOf.kt | 38 +++++++++++++++ .../core/contracts/clauses/AnyComposition.kt | 19 +------- .../net/corda/core/contracts/clauses/AnyOf.kt | 28 +++++++++++ .../corda/core/contracts/clauses/Clause.kt | 4 ++ .../core/contracts/clauses/CompositeClause.kt | 8 +++- .../contracts/clauses/FirstComposition.kt | 2 +- .../corda/core/contracts/clauses/FirstOf.kt | 41 ++++++++++++++++ .../{AllCompositionTests.kt => AllOfTests.kt} | 6 +-- .../{AnyCompositionTests.kt => AnyOfTests.kt} | 16 +++---- .../core/contracts/clauses/ClauseTestUtils.kt | 1 + docs/source/clauses.rst | 44 +++++++++--------- ...allCompositionChart.png => allOfChart.png} | Bin ...anyCompositionChart.png => anyOfChart.png} | Bin ...tCompositionChart.png => firstOfChart.png} | Bin docs/source/tutorial-contract-clauses.rst | 12 ++--- .../corda/contracts/JavaCommercialPaper.java | 8 ++-- .../net/corda/contracts/CommercialPaper.kt | 10 ++-- .../kotlin/net/corda/contracts/asset/Cash.kt | 8 ++-- .../contracts/asset/CommodityContract.kt | 4 +- .../net/corda/contracts/asset/Obligation.kt | 10 ++-- .../net/corda/vega/contracts/OGTrade.kt | 4 +- .../net/corda/vega/contracts/PortfolioSwap.kt | 4 +- 23 files changed, 187 insertions(+), 113 deletions(-) create mode 100644 core/src/main/kotlin/net/corda/core/contracts/clauses/AllOf.kt create mode 100644 core/src/main/kotlin/net/corda/core/contracts/clauses/AnyOf.kt create mode 100644 core/src/main/kotlin/net/corda/core/contracts/clauses/FirstOf.kt rename core/src/test/kotlin/net/corda/core/contracts/clauses/{AllCompositionTests.kt => AllOfTests.kt} (85%) rename core/src/test/kotlin/net/corda/core/contracts/clauses/{AnyCompositionTests.kt => AnyOfTests.kt} (73%) rename docs/source/resources/{allCompositionChart.png => allOfChart.png} (100%) rename docs/source/resources/{anyCompositionChart.png => anyOfChart.png} (100%) rename docs/source/resources/{firstCompositionChart.png => firstOfChart.png} (100%) diff --git a/core/src/main/kotlin/net/corda/core/contracts/clauses/AllComposition.kt b/core/src/main/kotlin/net/corda/core/contracts/clauses/AllComposition.kt index 350fb397d4..5be41988e5 100644 --- a/core/src/main/kotlin/net/corda/core/contracts/clauses/AllComposition.kt +++ b/core/src/main/kotlin/net/corda/core/contracts/clauses/AllComposition.kt @@ -1,39 +1,10 @@ package net.corda.core.contracts.clauses -import net.corda.core.contracts.AuthenticatedObject import net.corda.core.contracts.CommandData import net.corda.core.contracts.ContractState -import net.corda.core.contracts.TransactionForContract -import java.util.* /** * Compose a number of clauses, such that all of the clauses must run for verification to pass. */ -// TODO: Rename to AllOf -class AllComposition(firstClause: Clause, vararg remainingClauses: Clause) : CompositeClause() { - override val clauses = ArrayList>() - - init { - clauses.add(firstClause) - clauses.addAll(remainingClauses) - } - - override fun matchedClauses(commands: List>): List> { - clauses.forEach { clause -> - check(clause.matches(commands)) { "Failed to match clause ${clause}" } - } - return clauses - } - - override fun verify(tx: TransactionForContract, - inputs: List, - outputs: List, - commands: List>, - groupingKey: K?): Set { - return matchedClauses(commands).flatMapTo(HashSet()) { clause -> - clause.verify(tx, inputs, outputs, commands, groupingKey) - } - } - - override fun toString() = "All: $clauses.toList()" -} +@Deprecated("Use AllOf") +class AllComposition(firstClause: Clause, vararg remainingClauses: Clause) : AllOf(firstClause, *remainingClauses) \ No newline at end of file diff --git a/core/src/main/kotlin/net/corda/core/contracts/clauses/AllOf.kt b/core/src/main/kotlin/net/corda/core/contracts/clauses/AllOf.kt new file mode 100644 index 0000000000..3c88b8053c --- /dev/null +++ b/core/src/main/kotlin/net/corda/core/contracts/clauses/AllOf.kt @@ -0,0 +1,38 @@ +package net.corda.core.contracts.clauses + +import net.corda.core.contracts.AuthenticatedObject +import net.corda.core.contracts.CommandData +import net.corda.core.contracts.ContractState +import net.corda.core.contracts.TransactionForContract +import java.util.* + +/** + * Compose a number of clauses, such that all of the clauses must run for verification to pass. + */ +open class AllOf(firstClause: Clause, vararg remainingClauses: Clause) : CompositeClause() { + override val clauses = ArrayList>() + + init { + clauses.add(firstClause) + clauses.addAll(remainingClauses) + } + + override fun matchedClauses(commands: List>): List> { + clauses.forEach { clause -> + check(clause.matches(commands)) { "Failed to match clause ${clause}" } + } + return clauses + } + + override fun verify(tx: TransactionForContract, + inputs: List, + outputs: List, + commands: List>, + groupingKey: K?): Set { + return matchedClauses(commands).flatMapTo(HashSet()) { clause -> + clause.verify(tx, inputs, outputs, commands, groupingKey) + } + } + + override fun toString() = "All: $clauses.toList()" +} diff --git a/core/src/main/kotlin/net/corda/core/contracts/clauses/AnyComposition.kt b/core/src/main/kotlin/net/corda/core/contracts/clauses/AnyComposition.kt index ecdd77bd4b..fbad044ca3 100644 --- a/core/src/main/kotlin/net/corda/core/contracts/clauses/AnyComposition.kt +++ b/core/src/main/kotlin/net/corda/core/contracts/clauses/AnyComposition.kt @@ -1,25 +1,10 @@ package net.corda.core.contracts.clauses -import net.corda.core.contracts.AuthenticatedObject import net.corda.core.contracts.CommandData import net.corda.core.contracts.ContractState -import net.corda.core.contracts.TransactionForContract -import java.util.* /** * Compose a number of clauses, such that any number of the clauses can run. */ -// TODO: Rename to AnyOf -class AnyComposition(vararg rawClauses: Clause) : CompositeClause() { - override val clauses: List> = rawClauses.asList() - - override fun matchedClauses(commands: List>): List> = clauses.filter { it.matches(commands) } - - override fun verify(tx: TransactionForContract, inputs: List, outputs: List, commands: List>, groupingKey: K?): Set { - return matchedClauses(commands).flatMapTo(HashSet()) { clause -> - clause.verify(tx, inputs, outputs, commands, groupingKey) - } - } - - override fun toString(): String = "Or: ${clauses.toList()}" -} +@Deprecated("Use AnyOf instead, although note that any of requires at least one matched clause") +class AnyComposition(vararg rawClauses: Clause) : AnyOf(*rawClauses) \ No newline at end of file diff --git a/core/src/main/kotlin/net/corda/core/contracts/clauses/AnyOf.kt b/core/src/main/kotlin/net/corda/core/contracts/clauses/AnyOf.kt new file mode 100644 index 0000000000..ceb732bea2 --- /dev/null +++ b/core/src/main/kotlin/net/corda/core/contracts/clauses/AnyOf.kt @@ -0,0 +1,28 @@ +package net.corda.core.contracts.clauses + +import net.corda.core.contracts.AuthenticatedObject +import net.corda.core.contracts.CommandData +import net.corda.core.contracts.ContractState +import net.corda.core.contracts.TransactionForContract +import java.util.* + +/** + * Compose a number of clauses, such that one or more of the clauses can run. + */ +open class AnyOf(vararg rawClauses: Clause) : CompositeClause() { + override val clauses: List> = rawClauses.toList() + + override fun matchedClauses(commands: List>): List> { + val matched = clauses.filter { it.matches(commands) } + require(matched.isNotEmpty()) { "At least one clause must match" } + return matched + } + + override fun verify(tx: TransactionForContract, inputs: List, outputs: List, commands: List>, groupingKey: K?): Set { + return matchedClauses(commands).flatMapTo(HashSet()) { clause -> + clause.verify(tx, inputs, outputs, commands, groupingKey) + } + } + + override fun toString(): String = "Any: ${clauses.toList()}" +} diff --git a/core/src/main/kotlin/net/corda/core/contracts/clauses/Clause.kt b/core/src/main/kotlin/net/corda/core/contracts/clauses/Clause.kt index 5c3804ca1a..00409ce2c3 100644 --- a/core/src/main/kotlin/net/corda/core/contracts/clauses/Clause.kt +++ b/core/src/main/kotlin/net/corda/core/contracts/clauses/Clause.kt @@ -26,7 +26,11 @@ abstract class Clause { /** * Determine the subclauses which will be verified as a result of verifying this clause. + * + * @throws IllegalStateException if the given commands do not result in a valid execution (for example no match + * with [FirstOf]). */ + @Throws(IllegalStateException::class) open fun getExecutionPath(commands: List>): List> = listOf(this) diff --git a/core/src/main/kotlin/net/corda/core/contracts/clauses/CompositeClause.kt b/core/src/main/kotlin/net/corda/core/contracts/clauses/CompositeClause.kt index 875544ec0c..be0e711731 100644 --- a/core/src/main/kotlin/net/corda/core/contracts/clauses/CompositeClause.kt +++ b/core/src/main/kotlin/net/corda/core/contracts/clauses/CompositeClause.kt @@ -14,6 +14,12 @@ abstract class CompositeClause>): List> = matchedClauses(commands).flatMap { it.getExecutionPath(commands) } - /** Determine which clauses are matched by the supplied commands */ + /** + * Determine which clauses are matched by the supplied commands. + * + * @throws IllegalStateException if the given commands do not result in a valid execution (for example no match + * with [FirstOf]). + */ + @Throws(IllegalStateException::class) abstract fun matchedClauses(commands: List>): List> } diff --git a/core/src/main/kotlin/net/corda/core/contracts/clauses/FirstComposition.kt b/core/src/main/kotlin/net/corda/core/contracts/clauses/FirstComposition.kt index adbf1647a5..0f1e00a72b 100644 --- a/core/src/main/kotlin/net/corda/core/contracts/clauses/FirstComposition.kt +++ b/core/src/main/kotlin/net/corda/core/contracts/clauses/FirstComposition.kt @@ -10,7 +10,7 @@ import java.util.* /** * Compose a number of clauses, such that the first match is run, and it errors if none is run. */ -// TODO: Rename to FirstOf +@Deprecated("Use FirstOf instead") class FirstComposition(val firstClause: Clause, vararg remainingClauses: Clause) : CompositeClause() { companion object { val logger = loggerFor>() diff --git a/core/src/main/kotlin/net/corda/core/contracts/clauses/FirstOf.kt b/core/src/main/kotlin/net/corda/core/contracts/clauses/FirstOf.kt new file mode 100644 index 0000000000..bac08f3f4d --- /dev/null +++ b/core/src/main/kotlin/net/corda/core/contracts/clauses/FirstOf.kt @@ -0,0 +1,41 @@ +package net.corda.core.contracts.clauses + +import net.corda.core.contracts.AuthenticatedObject +import net.corda.core.contracts.CommandData +import net.corda.core.contracts.ContractState +import net.corda.core.contracts.TransactionForContract +import net.corda.core.utilities.loggerFor +import java.util.* + +/** + * Compose a number of clauses, such that the first match is run, and it errors if none is run. + */ +class FirstOf(val firstClause: Clause, vararg remainingClauses: Clause) : CompositeClause() { + companion object { + val logger = loggerFor>() + } + + override val clauses = ArrayList>() + + /** + * Get the single matched clause from the set this composes, based on the given commands. This is provided as + * helper method for internal use, rather than using the exposed [matchedClauses] function which unnecessarily + * wraps the clause in a list. + */ + private fun matchedClause(commands: List>): Clause { + return clauses.firstOrNull { it.matches(commands) } ?: throw IllegalStateException("No delegate clause matched in first composition") + } + + override fun matchedClauses(commands: List>) = listOf(matchedClause(commands)) + + init { + clauses.add(firstClause) + clauses.addAll(remainingClauses) + } + + override fun verify(tx: TransactionForContract, inputs: List, outputs: List, commands: List>, groupingKey: K?): Set { + return matchedClause(commands).verify(tx, inputs, outputs, commands, groupingKey) + } + + override fun toString() = "First: ${clauses.toList()}" +} diff --git a/core/src/test/kotlin/net/corda/core/contracts/clauses/AllCompositionTests.kt b/core/src/test/kotlin/net/corda/core/contracts/clauses/AllOfTests.kt similarity index 85% rename from core/src/test/kotlin/net/corda/core/contracts/clauses/AllCompositionTests.kt rename to core/src/test/kotlin/net/corda/core/contracts/clauses/AllOfTests.kt index fbb0229304..7e2636bcfc 100644 --- a/core/src/test/kotlin/net/corda/core/contracts/clauses/AllCompositionTests.kt +++ b/core/src/test/kotlin/net/corda/core/contracts/clauses/AllOfTests.kt @@ -9,12 +9,12 @@ import java.util.concurrent.atomic.AtomicInteger import kotlin.test.assertEquals import kotlin.test.assertFailsWith -class AllCompositionTests { +class AllOfTests { @Test fun minimal() { val counter = AtomicInteger(0) - val clause = AllComposition(matchedClause(counter), matchedClause(counter)) + val clause = AllOf(matchedClause(counter), matchedClause(counter)) val tx = TransactionForContract(emptyList(), emptyList(), emptyList(), emptyList(), SecureHash.randomSHA256()) verifyClause(tx, clause, emptyList>()) @@ -24,7 +24,7 @@ class AllCompositionTests { @Test fun `not all match`() { - val clause = AllComposition(matchedClause(), unmatchedClause()) + val clause = AllOf(matchedClause(), unmatchedClause()) val tx = TransactionForContract(emptyList(), emptyList(), emptyList(), emptyList(), SecureHash.randomSHA256()) assertFailsWith { verifyClause(tx, clause, emptyList>()) } } diff --git a/core/src/test/kotlin/net/corda/core/contracts/clauses/AnyCompositionTests.kt b/core/src/test/kotlin/net/corda/core/contracts/clauses/AnyOfTests.kt similarity index 73% rename from core/src/test/kotlin/net/corda/core/contracts/clauses/AnyCompositionTests.kt rename to core/src/test/kotlin/net/corda/core/contracts/clauses/AnyOfTests.kt index 1d58b7e85e..fa7d6be9a8 100644 --- a/core/src/test/kotlin/net/corda/core/contracts/clauses/AnyCompositionTests.kt +++ b/core/src/test/kotlin/net/corda/core/contracts/clauses/AnyOfTests.kt @@ -7,12 +7,13 @@ import net.corda.core.crypto.SecureHash import org.junit.Test import java.util.concurrent.atomic.AtomicInteger import kotlin.test.assertEquals +import kotlin.test.assertFailsWith -class AnyCompositionTests { +class AnyOfTests { @Test fun minimal() { val counter = AtomicInteger(0) - val clause = AnyComposition(matchedClause(counter), matchedClause(counter)) + val clause = AnyOf(matchedClause(counter), matchedClause(counter)) val tx = TransactionForContract(emptyList(), emptyList(), emptyList(), emptyList(), SecureHash.randomSHA256()) verifyClause(tx, clause, emptyList>()) @@ -23,7 +24,7 @@ class AnyCompositionTests { @Test fun `not all match`() { val counter = AtomicInteger(0) - val clause = AnyComposition(matchedClause(counter), unmatchedClause(counter)) + val clause = AnyOf(matchedClause(counter), unmatchedClause(counter)) val tx = TransactionForContract(emptyList(), emptyList(), emptyList(), emptyList(), SecureHash.randomSHA256()) verifyClause(tx, clause, emptyList>()) @@ -34,11 +35,10 @@ class AnyCompositionTests { @Test fun `none match`() { val counter = AtomicInteger(0) - val clause = AnyComposition(unmatchedClause(counter), unmatchedClause(counter)) + val clause = AnyOf(unmatchedClause(counter), unmatchedClause(counter)) val tx = TransactionForContract(emptyList(), emptyList(), emptyList(), emptyList(), SecureHash.randomSHA256()) - verifyClause(tx, clause, emptyList>()) - - // Check that we've run the verify() function of neither clause - assertEquals(0, counter.get()) + assertFailsWith(IllegalArgumentException::class) { + verifyClause(tx, clause, emptyList>()) + } } } diff --git a/core/src/test/kotlin/net/corda/core/contracts/clauses/ClauseTestUtils.kt b/core/src/test/kotlin/net/corda/core/contracts/clauses/ClauseTestUtils.kt index 9d023670ae..a21e6d2b08 100644 --- a/core/src/test/kotlin/net/corda/core/contracts/clauses/ClauseTestUtils.kt +++ b/core/src/test/kotlin/net/corda/core/contracts/clauses/ClauseTestUtils.kt @@ -7,6 +7,7 @@ import net.corda.core.contracts.TransactionForContract import java.util.concurrent.atomic.AtomicInteger internal fun matchedClause(counter: AtomicInteger? = null) = object : Clause() { + override val requiredCommands: Set> = emptySet() override fun verify(tx: TransactionForContract, inputs: List, outputs: List, diff --git a/docs/source/clauses.rst b/docs/source/clauses.rst index 1fc210405b..fd8e514aff 100644 --- a/docs/source/clauses.rst +++ b/docs/source/clauses.rst @@ -37,7 +37,7 @@ When writing a contract you need to override the contract's ``verify`` function there is a check if all of transaction's commands were matched. If not, then an exception is raised. This is done to enforce that spurious commands cannot be included in a transaction, ensuring that the transaction is as clear as possible. As an example imagine a transaction with two commands: ``Move`` and ``Issue`` included, with verification written - using ``FirstComposition`` on clauses that require single command set. Thus only one of transaction's commands will match + using ``FirstOf`` on clauses that require single command set. Thus only one of transaction's commands will match leaving the second unprocessed. It should raise an error - we want to ensure that commands set is minimal to simplify analysis of intent of a transaction. @@ -47,14 +47,14 @@ An example ``verify`` from ``Obligation`` contract: .. sourcecode:: kotlin - override fun verify(tx: TransactionForContract) = verifyClause(tx, FirstComposition( + override fun verify(tx: TransactionForContract) = verifyClause(tx, FirstOf( Clauses.Net(), Clauses.Group

() ), tx.commands.select()) It takes transaction to be verified, and passes it along with a top-level clause and commands to the ``verifyClause`` -function. As you can see above we have used ``FirstComposition`` which is a special type of clause, which extends the -``CompositeClause`` abstract class (in that particular case, it ensures that either ``Net`` or ``Group`` will run - for explanation see `FirstComposition`_). +function. As you can see above we have used ``FirstOf`` which is a special type of clause, which extends the +``CompositeClause`` abstract class (in that particular case, it ensures that either ``Net`` or ``Group`` will run - for explanation see `FirstOf`_). It's a type of clause that adds support for encapsulating multiple clauses and defines common behaviour for that composition. There is also a ``GroupClauseVerifier`` special clause, which specifies how to group transaction input/output states together and passes them to adequate clause for further processing. @@ -66,37 +66,37 @@ One of the most important concepts of clauses - composition clauses which extend providing a range of ways of assembling clauses together. They define a logic of verification execution specifying which clauses will be run. -AllComposition -~~~~~~~~~~~~~~ +AllOf +~~~~~ **Description** Composes a number of clauses, such that all of the clauses must run for verification to pass. -.. image:: resources/allCompositionChart.png +.. image:: resources/allOfChart.png Short description: -- ``AllComposition`` holds clauses *Cl1,..,Cl5*. -- Check if all clauses that compose ``AllComposition`` have associated commands in a command set - if not, verification fails. +- ``AllOf`` holds clauses *Cl1,..,Cl5*. +- Check if all clauses that compose ``AllOf`` have associated commands in a command set - if not, verification fails. - After successful check runs verification logic specific for every clause *Cl1,..,Cl5* from that composition. **Usage** See code in `GroupClauseVerifier`_. -AnyComposition -~~~~~~~~~~~~~~ +AnyOf +~~~~~ **Description** -Composes a number of clauses, such that 0 or more of the clauses can be run. +Composes a number of clauses, such that 1 or more of the clauses can be run. -.. image:: resources/anyCompositionChart.png +.. image:: resources/anyOfChart.png Short description: -- Checks if zero or more clauses that compose AnyComposition have associated commands in a command set. +- Checks if one or more clauses that compose AnyOf have associated commands in a command set. - After success runs verification logic specific for every *matched* (in this case *Cl2, Cl4, Cl5*) clause from composition. **Usage** @@ -108,7 +108,7 @@ Example from ``CommercialPaper.kt``: .. sourcecode:: kotlin class Group : GroupClauseVerifier>( - AnyComposition( + AnyOf( Redeem(), Move(), Issue())) { @@ -116,14 +116,14 @@ Example from ``CommercialPaper.kt``: = tx.groupStates> { it.token } } -FirstComposition -~~~~~~~~~~~~~~~~ +FirstOf +~~~~~~~ **Description** Composes a number of clauses, such that the first match is run, and it errors if none is run. -.. image:: resources/firstCompositionChart.png +.. image:: resources/firstOfChart.png Short description: @@ -168,13 +168,13 @@ grouped input and output states with a grouping key used for each group. Example .. sourcecode:: kotlin class Group

: GroupClauseVerifier, Commands, Issued>>( - AllComposition( + AllOf( NoZeroSizedOutputs, Commands, Terms

>(), - FirstComposition( + FirstOf( SetLifecycle

(), - AllComposition( + AllOf( VerifyLifecycle, Commands, Issued>, P>(), - FirstComposition( + FirstOf( Settle

(), Issue(), ConserveAmount() diff --git a/docs/source/resources/allCompositionChart.png b/docs/source/resources/allOfChart.png similarity index 100% rename from docs/source/resources/allCompositionChart.png rename to docs/source/resources/allOfChart.png diff --git a/docs/source/resources/anyCompositionChart.png b/docs/source/resources/anyOfChart.png similarity index 100% rename from docs/source/resources/anyCompositionChart.png rename to docs/source/resources/anyOfChart.png diff --git a/docs/source/resources/firstCompositionChart.png b/docs/source/resources/firstOfChart.png similarity index 100% rename from docs/source/resources/firstCompositionChart.png rename to docs/source/resources/firstOfChart.png diff --git a/docs/source/tutorial-contract-clauses.rst b/docs/source/tutorial-contract-clauses.rst index 725a69fbdb..6f705cb37d 100644 --- a/docs/source/tutorial-contract-clauses.rst +++ b/docs/source/tutorial-contract-clauses.rst @@ -36,20 +36,20 @@ to be considered valid. We refer to a clause as being "matched" when the transac in question to trigger. Meanwhile, we talk about a clause "verifying" when its ``verify()`` function returns ``True``. As an example, let's say we want a transaction to be valid only when every single one of its clauses matches and verifies. We implement this -by wrapping the individual clauses into an ``AllComposition`` composite clause, which ensures that a transaction is +by wrapping the individual clauses into an ``AllOf`` composite clause, which ensures that a transaction is only considered valid if all of its clauses are both matched and verify. There are two other basic composite clauses that you should be aware of: - * ``AnyComposition``, whereby any number of clauses (0+) may match, but each matched clause must verify - * ``FirstComposition``, whereby at least one clause must match, and the first such clause must verify + * ``AnyOf``, whereby 1 or more clauses may match, and every matched clause must verify + * ``FirstOf``, whereby at least one clause must match, and the first such clause must verify In turn, composite clauses are themselves ``Clause`` s, and can, for example, be wrapped in the special ``GroupClauseVerifier`` grouping clause. For ``CommercialPaper``, this would look as follows: .. image:: resources/commPaperClauses.png -For this tutorial, we will be using ``GroupClauseVerifier`` and ``AnyComposition``. Since it's important to understand how these work, +For this tutorial, we will be using ``GroupClauseVerifier`` and ``AnyOf``. Since it's important to understand how these work, charts showing their execution and other details can be found in :doc:`clauses`. .. _verify_ref: @@ -225,7 +225,7 @@ its subclauses (wrapped move, issue, redeem). "Any" in this case means that it w .. sourcecode:: kotlin class Group : GroupClauseVerifier>( - AnyComposition( + AnyOf( Redeem(), Move(), Issue())) { @@ -237,7 +237,7 @@ its subclauses (wrapped move, issue, redeem). "Any" in this case means that it w class Group extends GroupClauseVerifier { public Group() { - super(new AnyComposition<>( + super(new AnyOf<>( new Clauses.Redeem(), new Clauses.Move(), new Clauses.Issue() diff --git a/finance/src/main/java/net/corda/contracts/JavaCommercialPaper.java b/finance/src/main/java/net/corda/contracts/JavaCommercialPaper.java index 2d8d8bbf64..286c1a9f12 100644 --- a/finance/src/main/java/net/corda/contracts/JavaCommercialPaper.java +++ b/finance/src/main/java/net/corda/contracts/JavaCommercialPaper.java @@ -131,10 +131,10 @@ public class JavaCommercialPaper implements Contract { // warning. @SuppressWarnings("unchecked") Group() { - super(new AnyComposition<>( - new Clauses.Redeem(), - new Clauses.Move(), - new Clauses.Issue() + super(new AnyOf<>( + new Clauses.Redeem(), + new Clauses.Move(), + new Clauses.Issue() )); } diff --git a/finance/src/main/kotlin/net/corda/contracts/CommercialPaper.kt b/finance/src/main/kotlin/net/corda/contracts/CommercialPaper.kt index 63582620af..2da1f2d22d 100644 --- a/finance/src/main/kotlin/net/corda/contracts/CommercialPaper.kt +++ b/finance/src/main/kotlin/net/corda/contracts/CommercialPaper.kt @@ -3,7 +3,7 @@ package net.corda.contracts import net.corda.contracts.asset.sumCashBy import net.corda.contracts.clause.AbstractIssue import net.corda.core.contracts.* -import net.corda.core.contracts.clauses.AnyComposition +import net.corda.core.contracts.clauses.AnyOf import net.corda.core.contracts.clauses.Clause import net.corda.core.contracts.clauses.GroupClauseVerifier import net.corda.core.contracts.clauses.verifyClause @@ -103,10 +103,10 @@ class CommercialPaper : Contract { interface Clauses { class Group : GroupClauseVerifier>( - AnyComposition( - Redeem(), - Move(), - Issue())) { + AnyOf( + Redeem(), + Move(), + Issue())) { override fun groupStates(tx: TransactionForContract): List>> = tx.groupStates> { it.token } } diff --git a/finance/src/main/kotlin/net/corda/contracts/asset/Cash.kt b/finance/src/main/kotlin/net/corda/contracts/asset/Cash.kt index 4ca53d34d7..55d195a8fd 100644 --- a/finance/src/main/kotlin/net/corda/contracts/asset/Cash.kt +++ b/finance/src/main/kotlin/net/corda/contracts/asset/Cash.kt @@ -4,8 +4,8 @@ import net.corda.contracts.clause.AbstractConserveAmount import net.corda.contracts.clause.AbstractIssue import net.corda.contracts.clause.NoZeroSizedOutputs import net.corda.core.contracts.* -import net.corda.core.contracts.clauses.AllComposition -import net.corda.core.contracts.clauses.FirstComposition +import net.corda.core.contracts.clauses.AllOf +import net.corda.core.contracts.clauses.FirstOf import net.corda.core.contracts.clauses.GroupClauseVerifier import net.corda.core.contracts.clauses.verifyClause import net.corda.core.crypto.* @@ -56,9 +56,9 @@ class Cash : OnLedgerAsset() { = commands.select() interface Clauses { - class Group : GroupClauseVerifier>(AllComposition>( + class Group : GroupClauseVerifier>(AllOf>( NoZeroSizedOutputs(), - FirstComposition>( + FirstOf>( Issue(), ConserveAmount()) ) diff --git a/finance/src/main/kotlin/net/corda/contracts/asset/CommodityContract.kt b/finance/src/main/kotlin/net/corda/contracts/asset/CommodityContract.kt index 4c4af24ef3..7279cf896a 100644 --- a/finance/src/main/kotlin/net/corda/contracts/asset/CommodityContract.kt +++ b/finance/src/main/kotlin/net/corda/contracts/asset/CommodityContract.kt @@ -4,7 +4,7 @@ import net.corda.contracts.clause.AbstractConserveAmount import net.corda.contracts.clause.AbstractIssue import net.corda.contracts.clause.NoZeroSizedOutputs import net.corda.core.contracts.* -import net.corda.core.contracts.clauses.AnyComposition +import net.corda.core.contracts.clauses.AnyOf import net.corda.core.contracts.clauses.GroupClauseVerifier import net.corda.core.contracts.clauses.verifyClause import net.corda.core.crypto.CompositeKey @@ -62,7 +62,7 @@ class CommodityContract : OnLedgerAsset>(AnyComposition( + class Group : GroupClauseVerifier>(AnyOf( NoZeroSizedOutputs(), Issue(), ConserveAmount())) { diff --git a/finance/src/main/kotlin/net/corda/contracts/asset/Obligation.kt b/finance/src/main/kotlin/net/corda/contracts/asset/Obligation.kt index dce8b8260f..8f946c0b9c 100644 --- a/finance/src/main/kotlin/net/corda/contracts/asset/Obligation.kt +++ b/finance/src/main/kotlin/net/corda/contracts/asset/Obligation.kt @@ -47,13 +47,13 @@ class Obligation

: Contract { * Parent clause for clauses that operate on grouped states (those which are fungible). */ class Group

: GroupClauseVerifier, Commands, Issued>>( - AllComposition( + AllOf( NoZeroSizedOutputs, Commands, Terms

>(), - FirstComposition( + FirstOf( SetLifecycle

(), - AllComposition( + AllOf( VerifyLifecycle, Commands, Issued>, P>(), - FirstComposition( + FirstOf( Settle

(), Issue(), ConserveAmount() @@ -364,7 +364,7 @@ class Obligation

: Contract { data class Exit

(override val amount: Amount>>) : Commands, FungibleAsset.Commands.Exit> } - override fun verify(tx: TransactionForContract) = verifyClause(tx, FirstComposition( + override fun verify(tx: TransactionForContract) = verifyClause(tx, FirstOf( Clauses.Net(), Clauses.Group

() ), tx.commands.select()) diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/OGTrade.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/OGTrade.kt index 68afd7977f..e0f8928a3b 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/OGTrade.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/OGTrade.kt @@ -9,7 +9,7 @@ import java.math.BigDecimal * Specifies the contract between two parties that trade an OpenGamma IRS. Currently can only agree to trade. */ data class OGTrade(override val legalContractReference: SecureHash = SecureHash.sha256("OGTRADE.KT")) : Contract { - override fun verify(tx: TransactionForContract) = verifyClause(tx, AllComposition(Clauses.Timestamped(), Clauses.Group()), tx.commands.select()) + override fun verify(tx: TransactionForContract) = verifyClause(tx, AllOf(Clauses.Timestamped(), Clauses.Group()), tx.commands.select()) interface Commands : CommandData { class Agree : TypeOnlyCommandData(), Commands // Both sides agree to trade @@ -28,7 +28,7 @@ data class OGTrade(override val legalContractReference: SecureHash = SecureHash. } } - class Group : GroupClauseVerifier(AnyComposition(Agree())) { + class Group : GroupClauseVerifier(AnyOf(Agree())) { override fun groupStates(tx: TransactionForContract): List> // Group by Trade ID for in / out states = tx.groupStates() { state -> state.linearId } diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/PortfolioSwap.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/PortfolioSwap.kt index 3c206e8cb6..0fe3028e3f 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/PortfolioSwap.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/PortfolioSwap.kt @@ -10,7 +10,7 @@ import net.corda.core.crypto.SecureHash * of the portfolio arbitrarily. */ data class PortfolioSwap(override val legalContractReference: SecureHash = SecureHash.sha256("swordfish")) : Contract { - override fun verify(tx: TransactionForContract) = verifyClause(tx, AllComposition(Clauses.Timestamped(), Clauses.Group()), tx.commands.select()) + override fun verify(tx: TransactionForContract) = verifyClause(tx, AllOf(Clauses.Timestamped(), Clauses.Group()), tx.commands.select()) interface Commands : CommandData { class Agree : TypeOnlyCommandData(), Commands // Both sides agree to portfolio @@ -30,7 +30,7 @@ data class PortfolioSwap(override val legalContractReference: SecureHash = Secur } } - class Group : GroupClauseVerifier(FirstComposition(Agree(), Update())) { + class Group : GroupClauseVerifier(FirstOf(Agree(), Update())) { override fun groupStates(tx: TransactionForContract): List> // Group by Trade ID for in / out states = tx.groupStates() { state -> state.linearId }