Merged in rnicoll-clause-remove-concrete (pull request #316)

Merge ConcreteClause into Clause
This commit is contained in:
Ross Nicoll 2016-09-01 13:42:56 +01:00
commit 102e3f2048
16 changed files with 44 additions and 59 deletions

View File

@ -142,7 +142,7 @@ public class JavaCommercialPaper implements Contract {
}
}
class Move extends ConcreteClause<State, Commands, State> {
class Move extends Clause<State, Commands, State> {
@NotNull
@Override
public Set<Class<? extends CommandData>> getRequiredCommands() {
@ -173,7 +173,7 @@ public class JavaCommercialPaper implements Contract {
}
}
class Redeem extends ConcreteClause<State, Commands, State> {
class Redeem extends Clause<State, Commands, State> {
@NotNull
@Override
public Set<Class<? extends CommandData>> getRequiredCommands() {
@ -215,7 +215,7 @@ public class JavaCommercialPaper implements Contract {
}
}
class Issue extends ConcreteClause<State, Commands, State> {
class Issue extends Clause<State, Commands, State> {
@NotNull
@Override
public Set<Class<? extends CommandData>> getRequiredCommands() {

View File

@ -107,7 +107,7 @@ class CommercialPaper : Contract {
}
}
class Move: ConcreteClause<State, Commands, Issued<Terms>>() {
class Move: Clause<State, Commands, Issued<Terms>>() {
override val requiredCommands: Set<Class<out CommandData>> = setOf(Commands.Move::class.java)
override fun verify(tx: TransactionForContract,
@ -127,7 +127,7 @@ class CommercialPaper : Contract {
}
}
class Redeem(): ConcreteClause<State, Commands, Issued<Terms>>() {
class Redeem(): Clause<State, Commands, Issued<Terms>>() {
override val requiredCommands: Set<Class<out CommandData>> = setOf(Commands.Redeem::class.java)
override fun verify(tx: TransactionForContract,

View File

@ -454,7 +454,7 @@ class InterestRateSwap() : Contract {
* Common superclass for IRS contract clauses, which defines behaviour on match/no-match, and provides
* helper functions for the clauses.
*/
abstract class AbstractIRSClause : ConcreteClause<State, Commands, UniqueIdentifier>() {
abstract class AbstractIRSClause : Clause<State, Commands, UniqueIdentifier>() {
// These functions may make more sense to use for basket types, but for now let's leave them here
fun checkLegDates(legs: List<CommonLeg>) {
requireThat {
@ -502,7 +502,7 @@ class InterestRateSwap() : Contract {
= tx.groupStates() { state -> state.linearId }
}
class Timestamped : ConcreteClause<ContractState, Commands, Unit>() {
class Timestamped : Clause<ContractState, Commands, Unit>() {
override fun verify(tx: TransactionForContract,
inputs: List<ContractState>,
outputs: List<ContractState>,

View File

@ -90,7 +90,7 @@ class Obligation<P> : Contract {
/**
* Obligation-specific clause for changing the lifecycle of one or more states.
*/
class SetLifecycle<P> : ConcreteClause<State<P>, Commands, Issued<Terms<P>>>() {
class SetLifecycle<P> : Clause<State<P>, Commands, Issued<Terms<P>>>() {
override val requiredCommands: Set<Class<out CommandData>> = setOf(Commands.SetLifecycle::class.java)
override fun verify(tx: TransactionForContract,
@ -110,7 +110,7 @@ class Obligation<P> : Contract {
* Obligation-specific clause for settling an outstanding obligation by witnessing
* change of ownership of other states to fulfil
*/
class Settle<P> : ConcreteClause<State<P>, Commands, Issued<Terms<P>>>() {
class Settle<P> : Clause<State<P>, Commands, Issued<Terms<P>>>() {
override val requiredCommands: Set<Class<out CommandData>> = setOf(Commands.Settle::class.java)
override fun verify(tx: TransactionForContract,
inputs: List<State<P>>,
@ -199,7 +199,7 @@ class Obligation<P> : Contract {
* any lifecycle change clause, which is the only clause that involve
* non-standard lifecycle states on input/output.
*/
class VerifyLifecycle<S: ContractState, C: CommandData, T: Any, P> : ConcreteClause<S, C, T>() {
class VerifyLifecycle<S: ContractState, C: CommandData, T: Any, P> : Clause<S, C, T>() {
override fun verify(tx: TransactionForContract,
inputs: List<S>,
outputs: List<S>,

View File

@ -5,7 +5,7 @@ import com.r3corda.contracts.asset.InsufficientBalanceException
import com.r3corda.contracts.asset.sumFungibleOrNull
import com.r3corda.contracts.asset.sumFungibleOrZero
import com.r3corda.core.contracts.*
import com.r3corda.core.contracts.clauses.ConcreteClause
import com.r3corda.core.contracts.clauses.Clause
import com.r3corda.core.crypto.Party
import java.security.PublicKey
import java.util.*
@ -15,7 +15,7 @@ import java.util.*
* Move command is provided, and errors if absent. Must be the last clause under a grouping clause;
* errors on no-match, ends on match.
*/
abstract class AbstractConserveAmount<S : FungibleAsset<T>, C : CommandData, T : Any> : ConcreteClause<S, C, Issued<T>>() {
abstract class AbstractConserveAmount<S : FungibleAsset<T>, C : CommandData, T : Any> : Clause<S, C, Issued<T>>() {
/**
* Gather assets from the given list of states, sufficient to match or exceed the given amount.
*

View File

@ -1,7 +1,7 @@
package com.r3corda.contracts.clause
import com.r3corda.core.contracts.*
import com.r3corda.core.contracts.clauses.ConcreteClause
import com.r3corda.core.contracts.clauses.Clause
/**
* Standard issue clause for contracts that issue fungible assets.
@ -16,7 +16,7 @@ import com.r3corda.core.contracts.clauses.ConcreteClause
abstract class AbstractIssue<in S: ContractState, C: CommandData, T: Any>(
val sum: List<S>.() -> Amount<Issued<T>>,
val sumOrZero: List<S>.(token: Issued<T>) -> Amount<Issued<T>>
) : ConcreteClause<S, C, Issued<T>>() {
) : Clause<S, C, Issued<T>>() {
override fun verify(tx: TransactionForContract,
inputs: List<S>,
outputs: List<S>,

View File

@ -5,7 +5,7 @@ import com.r3corda.contracts.asset.Obligation
import com.r3corda.contracts.asset.extractAmountsDue
import com.r3corda.contracts.asset.sumAmountsDue
import com.r3corda.core.contracts.*
import com.r3corda.core.contracts.clauses.ConcreteClause
import com.r3corda.core.contracts.clauses.Clause
import java.security.PublicKey
/**
@ -42,7 +42,7 @@ data class MultilateralNetState<P>(
* Clause for netting contract states. Currently only supports obligation contract.
*/
// TODO: Make this usable for any nettable contract states
open class NetClause<C: CommandData, P> : ConcreteClause<ContractState, C, Unit>() {
open class NetClause<C: CommandData, P> : Clause<ContractState, C, Unit>() {
override val requiredCommands: Set<Class<out CommandData>> = setOf(Obligation.Commands.Net::class.java)
@Suppress("ConvertLambdaToReference")

View File

@ -2,13 +2,13 @@ package com.r3corda.contracts.clause
import com.r3corda.contracts.asset.FungibleAsset
import com.r3corda.core.contracts.*
import com.r3corda.core.contracts.clauses.ConcreteClause
import com.r3corda.core.contracts.clauses.Clause
/**
* Clause for fungible asset contracts, which enforces that no output state should have
* a balance of zero.
*/
open class NoZeroSizedOutputs<in S : FungibleAsset<T>, C : CommandData, T : Any> : ConcreteClause<S, C, Issued<T>>() {
open class NoZeroSizedOutputs<in S : FungibleAsset<T>, C : CommandData, T : Any> : Clause<S, C, Issued<T>>() {
override fun verify(tx: TransactionForContract,
inputs: List<S>,
outputs: List<S>,

View File

@ -1,6 +1,5 @@
package com.r3corda.core.contracts
import com.r3corda.core.contracts.clauses.ConcreteClause
import com.r3corda.core.contracts.clauses.Clause
import com.r3corda.core.crypto.Party
import com.r3corda.core.crypto.SecureHash
@ -218,7 +217,7 @@ interface LinearState: ContractState {
/**
* Standard clause to verify the LinearState safety properties.
*/
class ClauseVerifier<S : LinearState>(val stateClass: Class<S>) : ConcreteClause<ContractState, CommandData, Unit>() {
class ClauseVerifier<S : LinearState>(val stateClass: Class<S>) : Clause<ContractState, CommandData, Unit>() {
override fun verify(tx: TransactionForContract,
inputs: List<ContractState>,
outputs: List<ContractState>,

View File

@ -7,22 +7,28 @@ import com.r3corda.core.contracts.TransactionForContract
import com.r3corda.core.utilities.loggerFor
/**
* A clause of a contract, containing a chunk of verification logic. That logic may be delegated to other clauses, or
* provided directly by this clause.
*
* @param S the type of contract state this clause operates on.
* @param C a common supertype of commands this clause operates on.
* @param K the type of the grouping key for states this clause operates on. Use [Unit] if not applicable.
*
* @see CompositeClause
*/
interface Clause<in S : ContractState, C: CommandData, in K : Any> {
abstract class Clause<in S : ContractState, C : CommandData, in K : Any> {
companion object {
val log = loggerFor<Clause<*, *, *>>()
}
/** Determine whether this clause runs or not */
val requiredCommands: Set<Class<out CommandData>>
open val requiredCommands: Set<Class<out CommandData>> = emptySet()
/**
* Determine the subclauses which will be verified as a result of verifying this clause.
*/
fun getExecutionPath(commands: List<AuthenticatedObject<C>>): List<Clause<*, *, *>>
open fun getExecutionPath(commands: List<AuthenticatedObject<C>>): List<Clause<*, *, *>>
= listOf(this)
/**
* Verify the transaction matches the conditions from this clause. For example, a "no zero amount output" clause
@ -45,11 +51,11 @@ interface Clause<in S : ContractState, C: CommandData, in K : Any> {
* commands that were not required (for example the Exit command for fungible assets is optional).
*/
@Throws(IllegalStateException::class)
fun verify(tx: TransactionForContract,
inputs: List<S>,
outputs: List<S>,
commands: List<AuthenticatedObject<C>>,
groupingKey: K?): Set<C>
abstract fun verify(tx: TransactionForContract,
inputs: List<S>,
outputs: List<S>,
commands: List<AuthenticatedObject<C>>,
groupingKey: K?): Set<C>
}
/**

View File

@ -6,13 +6,10 @@ import com.r3corda.core.contracts.ContractState
/**
* Abstract supertype for clauses which compose other clauses together in some logical manner.
*
* @see ConcreteClause
*/
abstract class CompositeClause<in S : ContractState, C: CommandData, in K : Any>: Clause<S, C, K> {
abstract class CompositeClause<in S : ContractState, C: CommandData, in K : Any>: Clause<S, C, K>() {
/** List of clauses under this composite clause */
abstract val clauses: List<Clause<S, C, K>>
override val requiredCommands: Set<Class<out CommandData>> = emptySet()
override fun getExecutionPath(commands: List<AuthenticatedObject<C>>): List<Clause<*, *, *>>
= matchedClauses(commands).flatMap { it.getExecutionPath(commands) }
/** Determine which clauses are matched by the supplied commands */

View File

@ -1,17 +0,0 @@
package com.r3corda.core.contracts.clauses
import com.r3corda.core.contracts.AuthenticatedObject
import com.r3corda.core.contracts.CommandData
import com.r3corda.core.contracts.ContractState
/**
* Abstract supertype for clauses which provide their own verification logic, rather than delegating to subclauses.
* By default these clauses are always matched (they have no required commands).
*
* @see CompositeClause
*/
abstract class ConcreteClause<in S : ContractState, C: CommandData, in T : Any>: Clause<S, C, T> {
override fun getExecutionPath(commands: List<AuthenticatedObject<C>>): List<Clause<*, *, *>>
= listOf(this)
override val requiredCommands: Set<Class<out CommandData>> = emptySet()
}

View File

@ -6,7 +6,7 @@ import com.r3corda.core.contracts.ContractState
import com.r3corda.core.contracts.TransactionForContract
import java.util.*
abstract class GroupClauseVerifier<S : ContractState, C : CommandData, K : Any>(val clause: Clause<S, C, K>) : ConcreteClause<ContractState, C, Unit>() {
abstract class GroupClauseVerifier<S : ContractState, C : CommandData, K : Any>(val clause: Clause<S, C, K>) : Clause<ContractState, C, Unit>() {
abstract fun groupStates(tx: TransactionForContract): List<TransactionForContract.InOutGroup<S, K>>
override fun getExecutionPath(commands: List<AuthenticatedObject<C>>): List<Clause<*, *, *>>

View File

@ -6,7 +6,7 @@ import com.r3corda.core.contracts.ContractState
import com.r3corda.core.contracts.TransactionForContract
import java.util.concurrent.atomic.AtomicInteger
internal fun matchedClause(counter: AtomicInteger? = null) = object : ConcreteClause<ContractState, CommandData, Unit>() {
internal fun matchedClause(counter: AtomicInteger? = null) = object : Clause<ContractState, CommandData, Unit>() {
override fun verify(tx: TransactionForContract,
inputs: List<ContractState>,
outputs: List<ContractState>,
@ -17,7 +17,7 @@ internal fun matchedClause(counter: AtomicInteger? = null) = object : ConcreteCl
}
/** A clause that can never be matched */
internal fun unmatchedClause(counter: AtomicInteger? = null) = object : ConcreteClause<ContractState, CommandData, Unit>() {
internal fun unmatchedClause(counter: AtomicInteger? = null) = object : Clause<ContractState, CommandData, Unit>() {
override val requiredCommands: Set<Class<out CommandData>> = setOf(object: CommandData {}.javaClass)
override fun verify(tx: TransactionForContract,
inputs: List<ContractState>,

View File

@ -12,7 +12,7 @@ class VerifyClausesTests {
/** Very simple check that the function doesn't error when given any clause */
@Test
fun minimal() {
val clause = object : ConcreteClause<ContractState, CommandData, Unit>() {
val clause = object : Clause<ContractState, CommandData, Unit>() {
override fun verify(tx: TransactionForContract,
inputs: List<ContractState>,
outputs: List<ContractState>,
@ -24,7 +24,7 @@ class VerifyClausesTests {
@Test
fun errorSuperfluousCommands() {
val clause = object : ConcreteClause<ContractState, CommandData, Unit>() {
val clause = object : Clause<ContractState, CommandData, Unit>() {
override fun verify(tx: TransactionForContract,
inputs: List<ContractState>,
outputs: List<ContractState>,

View File

@ -64,10 +64,10 @@ Clauses
-------
We'll tackle the inner clauses that contain the bulk of the verification logic, first, and the clause which handles
grouping of input/output states later. The clauses must implement the ``Clause`` interface, which defines
grouping of input/output states later. The clauses must extend the ``Clause`` abstract class, which defines
the ``verify`` function, and the ``requiredCommands`` property used to determine the conditions under which a clause
is triggered. Normally clauses would extend ``ConcreteClause`` which provides defaults suitable for a clause which
verifies transactions, rather than delegating to other clauses.
is triggered. Composite clauses should extend the ``CompositeClause`` abstract class, which extends ``Clause`` to
add support for wrapping around multiple clauses.
The ``verify`` function defined in the ``Clause`` interface is similar to the conventional ``Contract`` verification
function, although it adds new parameters and returns the set of commands which it has processed. Normally this returned
@ -80,7 +80,7 @@ The ``Move`` clause for the commercial paper contract is relatively simple, so w
.. sourcecode:: kotlin
class Move: ConcreteClause<State, Commands, Issued<Terms>>() {
class Move: Clause<State, Commands, Issued<Terms>>() {
override val requiredCommands: Set<Class<out CommandData>>
get() = setOf(Commands.Move::class.java)
@ -103,7 +103,7 @@ The ``Move`` clause for the commercial paper contract is relatively simple, so w
.. sourcecode:: java
class Move extends ConcreteClause<State, Commands, State> {
class Move extends Clause<State, Commands, State> {
@NotNull
@Override
public Set<Class<? extends CommandData>> getRequiredCommands() {