mirror of
https://github.com/corda/corda.git
synced 2024-12-24 07:06:44 +00:00
Replace 'by' with 'using' to avoid overloading Kotlin keyword in contracts DSL. Deprecates 'by' with offered replacement.
This commit is contained in:
parent
36d5d0d7b2
commit
108f171e03
@ -57,9 +57,16 @@ infix fun Amount<Currency>.issuedBy(deposit: PartyAndReference) = Amount(quantit
|
|||||||
|
|
||||||
object Requirements {
|
object Requirements {
|
||||||
@Suppress("NOTHING_TO_INLINE") // Inlining this takes it out of our committed ABI.
|
@Suppress("NOTHING_TO_INLINE") // Inlining this takes it out of our committed ABI.
|
||||||
infix inline fun String.by(expr: Boolean) {
|
infix inline fun String.using(expr: Boolean) {
|
||||||
if (!expr) throw IllegalArgumentException("Failed requirement: $this")
|
if (!expr) throw IllegalArgumentException("Failed requirement: $this")
|
||||||
}
|
}
|
||||||
|
// Avoid overloading Kotlin keywords
|
||||||
|
@Deprecated("This function is deprecated, use 'using' instead",
|
||||||
|
ReplaceWith("using (expr)", "net.corda.core.contracts.Requirements.using"))
|
||||||
|
@Suppress("NOTHING_TO_INLINE") // Inlining this takes it out of our committed ABI.
|
||||||
|
infix inline fun String.by(expr: Boolean) {
|
||||||
|
using(expr)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <R> requireThat(body: Requirements.() -> R) = Requirements.body()
|
inline fun <R> requireThat(body: Requirements.() -> R) = Requirements.body()
|
||||||
@ -124,7 +131,7 @@ inline fun <reified T : MoveCommand> verifyMoveCommand(inputs: List<OwnableState
|
|||||||
val command = commands.requireSingleCommand<T>()
|
val command = commands.requireSingleCommand<T>()
|
||||||
val keysThatSigned = command.signers.toSet()
|
val keysThatSigned = command.signers.toSet()
|
||||||
requireThat {
|
requireThat {
|
||||||
"the owning keys are a subset of the signing keys" by keysThatSigned.containsAll(owningPubKeys)
|
"the owning keys are a subset of the signing keys" using keysThatSigned.containsAll(owningPubKeys)
|
||||||
}
|
}
|
||||||
return command.value
|
return command.value
|
||||||
}
|
}
|
||||||
|
@ -252,8 +252,8 @@ interface LinearState : ContractState {
|
|||||||
val inputIds = inputs.map { it.linearId }.distinct()
|
val inputIds = inputs.map { it.linearId }.distinct()
|
||||||
val outputIds = outputs.map { it.linearId }.distinct()
|
val outputIds = outputs.map { it.linearId }.distinct()
|
||||||
requireThat {
|
requireThat {
|
||||||
"LinearStates are not merged" by (inputIds.count() == inputs.count())
|
"LinearStates are not merged" using (inputIds.count() == inputs.count())
|
||||||
"LinearStates are not split" by (outputIds.count() == outputs.count())
|
"LinearStates are not split" using (outputIds.count() == outputs.count())
|
||||||
}
|
}
|
||||||
return emptySet()
|
return emptySet()
|
||||||
}
|
}
|
||||||
|
@ -33,10 +33,10 @@ object ContractUpgradeFlow {
|
|||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
val upgradedContract = command.upgradedContractClass.newInstance() as UpgradedContract<ContractState, *>
|
val upgradedContract = command.upgradedContractClass.newInstance() as UpgradedContract<ContractState, *>
|
||||||
requireThat {
|
requireThat {
|
||||||
"The signing keys include all participant keys" by keysThatSigned.containsAll(participants)
|
"The signing keys include all participant keys" using keysThatSigned.containsAll(participants)
|
||||||
"Inputs state reference the legacy contract" by (input.contract.javaClass == upgradedContract.legacyContract)
|
"Inputs state reference the legacy contract" using (input.contract.javaClass == upgradedContract.legacyContract)
|
||||||
"Outputs state reference the upgraded contract" by (output.contract.javaClass == command.upgradedContractClass)
|
"Outputs state reference the upgraded contract" using (output.contract.javaClass == command.upgradedContractClass)
|
||||||
"Output state must be an upgraded version of the input state" by (output == upgradedContract.upgrade(input))
|
"Output state must be an upgraded version of the input state" using (output == upgradedContract.upgrade(input))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,9 +74,9 @@ object ContractUpgradeFlow {
|
|||||||
val proposedTx = proposal.stx.tx
|
val proposedTx = proposal.stx.tx
|
||||||
val expectedTx = assembleBareTx(oldStateAndRef, proposal.modification).toWireTransaction()
|
val expectedTx = assembleBareTx(oldStateAndRef, proposal.modification).toWireTransaction()
|
||||||
requireThat {
|
requireThat {
|
||||||
"The instigator is one of the participants" by oldStateAndRef.state.data.participants.contains(otherSide.owningKey)
|
"The instigator is one of the participants" using oldStateAndRef.state.data.participants.contains(otherSide.owningKey)
|
||||||
"The proposed upgrade ${proposal.modification.javaClass} is a trusted upgrade path" by (proposal.modification == authorisedUpgrade)
|
"The proposed upgrade ${proposal.modification.javaClass} is a trusted upgrade path" using (proposal.modification == authorisedUpgrade)
|
||||||
"The proposed tx matches the expected tx for this upgrade" by (proposedTx == expectedTx)
|
"The proposed tx matches the expected tx for this upgrade" using (proposedTx == expectedTx)
|
||||||
}
|
}
|
||||||
ContractUpgradeFlow.verify(oldStateAndRef.state.data, expectedTx.outRef<ContractState>(0).state.data, expectedTx.commands.single())
|
ContractUpgradeFlow.verify(oldStateAndRef.state.data, expectedTx.outRef<ContractState>(0).state.data, expectedTx.commands.single())
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ class TransactionEncumbranceTests {
|
|||||||
val timeLockInput = tx.inputs.filterIsInstance<State>().singleOrNull() ?: return
|
val timeLockInput = tx.inputs.filterIsInstance<State>().singleOrNull() ?: return
|
||||||
val time = tx.timestamp?.before ?: throw IllegalArgumentException("Transactions containing time-locks must be timestamped")
|
val time = tx.timestamp?.before ?: throw IllegalArgumentException("Transactions containing time-locks must be timestamped")
|
||||||
requireThat {
|
requireThat {
|
||||||
"the time specified in the time-lock has passed" by (time >= timeLockInput.validFrom)
|
"the time specified in the time-lock has passed" using (time >= timeLockInput.validFrom)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,13 +79,13 @@ data class TradeApprovalContract(override val legalContractReference: SecureHash
|
|||||||
when (command.value) {
|
when (command.value) {
|
||||||
is Commands.Issue -> {
|
is Commands.Issue -> {
|
||||||
requireThat {
|
requireThat {
|
||||||
"Issue of new WorkflowContract must not include any inputs" by (tx.inputs.isEmpty())
|
"Issue of new WorkflowContract must not include any inputs" using (tx.inputs.isEmpty())
|
||||||
"Issue of new WorkflowContract must be in a unique transaction" by (tx.outputs.size == 1)
|
"Issue of new WorkflowContract must be in a unique transaction" using (tx.outputs.size == 1)
|
||||||
}
|
}
|
||||||
val issued = tx.outputs.get(0) as TradeApprovalContract.State
|
val issued = tx.outputs.get(0) as TradeApprovalContract.State
|
||||||
requireThat {
|
requireThat {
|
||||||
"Issue requires the source Party as signer" by (command.signers.contains(issued.source.owningKey))
|
"Issue requires the source Party as signer" using (command.signers.contains(issued.source.owningKey))
|
||||||
"Initial Issue state must be NEW" by (issued.state == WorkflowState.NEW)
|
"Initial Issue state must be NEW" using (issued.state == WorkflowState.NEW)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is Commands.Completed -> {
|
is Commands.Completed -> {
|
||||||
@ -95,11 +95,11 @@ data class TradeApprovalContract(override val legalContractReference: SecureHash
|
|||||||
val before = group.inputs.single()
|
val before = group.inputs.single()
|
||||||
val after = group.outputs.single()
|
val after = group.outputs.single()
|
||||||
requireThat {
|
requireThat {
|
||||||
"Only a non-final trade can be modified" by (before.state == WorkflowState.NEW)
|
"Only a non-final trade can be modified" using (before.state == WorkflowState.NEW)
|
||||||
"Output must be a final state" by (after.state in setOf(WorkflowState.APPROVED, WorkflowState.REJECTED))
|
"Output must be a final state" using (after.state in setOf(WorkflowState.APPROVED, WorkflowState.REJECTED))
|
||||||
"Completed command can only change state" by (before == after.copy(state = before.state))
|
"Completed command can only change state" using (before == after.copy(state = before.state))
|
||||||
"Completed command requires the source Party as signer" by (command.signers.contains(before.source.owningKey))
|
"Completed command requires the source Party as signer" using (command.signers.contains(before.source.owningKey))
|
||||||
"Completed command requires the counterparty as signer" by (command.signers.contains(before.counterparty.owningKey))
|
"Completed command requires the counterparty as signer" using (command.signers.contains(before.counterparty.owningKey))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ class UniversalContract : Contract {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
is Fixing -> {
|
is Fixing -> {
|
||||||
requireThat { "Fixing must be included" by false }
|
requireThat { "Fixing must be included" using false }
|
||||||
0.0.bd
|
0.0.bd
|
||||||
}
|
}
|
||||||
is Interest -> {
|
is Interest -> {
|
||||||
@ -95,7 +95,7 @@ class UniversalContract : Contract {
|
|||||||
fun validateImmediateTransfers(tx: TransactionForContract, arrangement: Arrangement): Arrangement = when (arrangement) {
|
fun validateImmediateTransfers(tx: TransactionForContract, arrangement: Arrangement): Arrangement = when (arrangement) {
|
||||||
is Obligation -> {
|
is Obligation -> {
|
||||||
val amount = eval(tx, arrangement.amount)
|
val amount = eval(tx, arrangement.amount)
|
||||||
requireThat { "transferred quantity is non-negative" by (amount >= BigDecimal.ZERO) }
|
requireThat { "transferred quantity is non-negative" using (amount >= BigDecimal.ZERO) }
|
||||||
Obligation(const(amount), arrangement.currency, arrangement.from, arrangement.to)
|
Obligation(const(amount), arrangement.currency, arrangement.from, arrangement.to)
|
||||||
}
|
}
|
||||||
is And -> And(arrangement.arrangements.map { validateImmediateTransfers(tx, it) }.toSet())
|
is And -> And(arrangement.arrangements.map { validateImmediateTransfers(tx, it) }.toSet())
|
||||||
@ -180,7 +180,7 @@ class UniversalContract : Contract {
|
|||||||
override fun verify(tx: TransactionForContract) {
|
override fun verify(tx: TransactionForContract) {
|
||||||
|
|
||||||
requireThat {
|
requireThat {
|
||||||
"transaction has a single command".by(tx.commands.size == 1)
|
"transaction has a single command".using(tx.commands.size == 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
val cmd = tx.commands.requireSingleCommand<UniversalContract.Commands>()
|
val cmd = tx.commands.requireSingleCommand<UniversalContract.Commands>()
|
||||||
@ -207,10 +207,10 @@ class UniversalContract : Contract {
|
|||||||
assert(rest is Zero)
|
assert(rest is Zero)
|
||||||
|
|
||||||
requireThat {
|
requireThat {
|
||||||
"action must be timestamped" by (tx.timestamp != null)
|
"action must be timestamped" using (tx.timestamp != null)
|
||||||
// "action must be authorized" by (cmd.signers.any { action.actors.any { party -> party.owningKey == it } })
|
// "action must be authorized" by (cmd.signers.any { action.actors.any { party -> party.owningKey == it } })
|
||||||
// todo perhaps merge these two requirements?
|
// todo perhaps merge these two requirements?
|
||||||
"condition must be met" by (eval(tx, action.condition))
|
"condition must be met" using (eval(tx, action.condition))
|
||||||
}
|
}
|
||||||
|
|
||||||
// verify that any resulting transfers can be resolved
|
// verify that any resulting transfers can be resolved
|
||||||
@ -221,8 +221,8 @@ class UniversalContract : Contract {
|
|||||||
1 -> {
|
1 -> {
|
||||||
val outState = tx.outputs.single() as State
|
val outState = tx.outputs.single() as State
|
||||||
requireThat {
|
requireThat {
|
||||||
"output state must match action result state" by (arrangement.equals(outState.details))
|
"output state must match action result state" using (arrangement.equals(outState.details))
|
||||||
"output state must match action result state" by (rest == zero)
|
"output state must match action result state" using (rest == zero)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
0 -> throw IllegalArgumentException("must have at least one out state")
|
0 -> throw IllegalArgumentException("must have at least one out state")
|
||||||
@ -230,7 +230,7 @@ class UniversalContract : Contract {
|
|||||||
val allContracts = And(tx.outputs.map { (it as State).details }.toSet())
|
val allContracts = And(tx.outputs.map { (it as State).details }.toSet())
|
||||||
|
|
||||||
requireThat {
|
requireThat {
|
||||||
"output states must match action result state" by (arrangement.equals(allContracts))
|
"output states must match action result state" using (arrangement.equals(allContracts))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -239,17 +239,17 @@ class UniversalContract : Contract {
|
|||||||
is Commands.Issue -> {
|
is Commands.Issue -> {
|
||||||
val outState = tx.outputs.single() as State
|
val outState = tx.outputs.single() as State
|
||||||
requireThat {
|
requireThat {
|
||||||
"the transaction is signed by all liable parties" by (liableParties(outState.details).all { it in cmd.signers })
|
"the transaction is signed by all liable parties" using (liableParties(outState.details).all { it in cmd.signers })
|
||||||
"the transaction has no input states" by tx.inputs.isEmpty()
|
"the transaction has no input states" using tx.inputs.isEmpty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is Commands.Move -> {
|
is Commands.Move -> {
|
||||||
val inState = tx.inputs.single() as State
|
val inState = tx.inputs.single() as State
|
||||||
val outState = tx.outputs.single() as State
|
val outState = tx.outputs.single() as State
|
||||||
requireThat {
|
requireThat {
|
||||||
"the transaction is signed by all liable parties" by
|
"the transaction is signed by all liable parties" using
|
||||||
(liableParties(outState.details).all { it in cmd.signers })
|
(liableParties(outState.details).all { it in cmd.signers })
|
||||||
"output state does not reflect move command" by
|
"output state does not reflect move command" using
|
||||||
(replaceParty(inState.details, value.from, value.to).equals(outState.details))
|
(replaceParty(inState.details, value.from, value.to).equals(outState.details))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -267,8 +267,8 @@ class UniversalContract : Contract {
|
|||||||
value.fixes.associateBy({ it.of }, { it.value }), unusedFixes)
|
value.fixes.associateBy({ it.of }, { it.value }), unusedFixes)
|
||||||
|
|
||||||
requireThat {
|
requireThat {
|
||||||
"relevant fixing must be included" by unusedFixes.isEmpty()
|
"relevant fixing must be included" using unusedFixes.isEmpty()
|
||||||
"output state does not reflect fix command" by
|
"output state does not reflect fix command" using
|
||||||
(expectedArr.equals(outState.details))
|
(expectedArr.equals(outState.details))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,12 +208,12 @@ public class JavaCommercialPaper implements Contract {
|
|||||||
Amount<Issued<Currency>> received = CashKt.sumCashBy(tx.getOutputs(), input.getOwner());
|
Amount<Issued<Currency>> received = CashKt.sumCashBy(tx.getOutputs(), input.getOwner());
|
||||||
|
|
||||||
requireThat(require -> {
|
requireThat(require -> {
|
||||||
require.by("must be timestamped", timestamp != null);
|
require.using("must be timestamped", timestamp != null);
|
||||||
require.by("received amount equals the face value: "
|
require.using("received amount equals the face value: "
|
||||||
+ received + " vs " + input.getFaceValue(), received.equals(input.getFaceValue()));
|
+ received + " vs " + input.getFaceValue(), received.equals(input.getFaceValue()));
|
||||||
require.by("the paper must have matured", time != null && !time.isBefore(input.getMaturityDate()));
|
require.using("the paper must have matured", time != null && !time.isBefore(input.getMaturityDate()));
|
||||||
require.by("the received amount equals the face value", input.getFaceValue().equals(received));
|
require.using("the received amount equals the face value", input.getFaceValue().equals(received));
|
||||||
require.by("the paper must be destroyed", outputs.isEmpty());
|
require.using("the paper must be destroyed", outputs.isEmpty());
|
||||||
return Unit.INSTANCE;
|
return Unit.INSTANCE;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -244,11 +244,11 @@ public class JavaCommercialPaper implements Contract {
|
|||||||
: timestampCommand.getBefore();
|
: timestampCommand.getBefore();
|
||||||
|
|
||||||
requireThat(require -> {
|
requireThat(require -> {
|
||||||
require.by("output values sum to more than the inputs", inputs.isEmpty());
|
require.using("output values sum to more than the inputs", inputs.isEmpty());
|
||||||
require.by("output values sum to more than the inputs", output.faceValue.getQuantity() > 0);
|
require.using("output values sum to more than the inputs", output.faceValue.getQuantity() > 0);
|
||||||
require.by("must be timestamped", timestampCommand != null);
|
require.using("must be timestamped", timestampCommand != null);
|
||||||
require.by("the maturity date is not in the past", time != null && time.isBefore(output.getMaturityDate()));
|
require.using("the maturity date is not in the past", time != null && time.isBefore(output.getMaturityDate()));
|
||||||
require.by("output states are issued by a command signer", cmd.getSigners().contains(output.issuance.getParty().getOwningKey()));
|
require.using("output states are issued by a command signer", cmd.getSigners().contains(output.issuance.getParty().getOwningKey()));
|
||||||
return Unit.INSTANCE;
|
return Unit.INSTANCE;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -143,8 +143,8 @@ class CommercialPaper : Contract {
|
|||||||
val command = commands.requireSingleCommand<Commands.Move>()
|
val command = commands.requireSingleCommand<Commands.Move>()
|
||||||
val input = inputs.single()
|
val input = inputs.single()
|
||||||
requireThat {
|
requireThat {
|
||||||
"the transaction is signed by the owner of the CP" by (input.owner in command.signers)
|
"the transaction is signed by the owner of the CP" using (input.owner in command.signers)
|
||||||
"the state is propagated" by (outputs.size == 1)
|
"the state is propagated" using (outputs.size == 1)
|
||||||
// Don't need to check anything else, as if outputs.size == 1 then the output is equal to
|
// Don't need to check anything else, as if outputs.size == 1 then the output is equal to
|
||||||
// the input ignoring the owner field due to the grouping.
|
// the input ignoring the owner field due to the grouping.
|
||||||
}
|
}
|
||||||
@ -169,10 +169,10 @@ class CommercialPaper : Contract {
|
|||||||
val received = tx.outputs.sumCashBy(input.owner)
|
val received = tx.outputs.sumCashBy(input.owner)
|
||||||
val time = timestamp?.after ?: throw IllegalArgumentException("Redemptions must be timestamped")
|
val time = timestamp?.after ?: throw IllegalArgumentException("Redemptions must be timestamped")
|
||||||
requireThat {
|
requireThat {
|
||||||
"the paper must have matured" by (time >= input.maturityDate)
|
"the paper must have matured" using (time >= input.maturityDate)
|
||||||
"the received amount equals the face value" by (received == input.faceValue)
|
"the received amount equals the face value" using (received == input.faceValue)
|
||||||
"the paper must be destroyed" by outputs.isEmpty()
|
"the paper must be destroyed" using outputs.isEmpty()
|
||||||
"the transaction is signed by the owner of the CP" by (input.owner in command.signers)
|
"the transaction is signed by the owner of the CP" using (input.owner in command.signers)
|
||||||
}
|
}
|
||||||
|
|
||||||
return setOf(command.value)
|
return setOf(command.value)
|
||||||
|
@ -69,8 +69,8 @@ class CommercialPaperLegacy : Contract {
|
|||||||
is Commands.Move -> {
|
is Commands.Move -> {
|
||||||
val input = inputs.single()
|
val input = inputs.single()
|
||||||
requireThat {
|
requireThat {
|
||||||
"the transaction is signed by the owner of the CP" by (input.owner in command.signers)
|
"the transaction is signed by the owner of the CP" using (input.owner in command.signers)
|
||||||
"the state is propagated" by (outputs.size == 1)
|
"the state is propagated" using (outputs.size == 1)
|
||||||
// Don't need to check anything else, as if outputs.size == 1 then the output is equal to
|
// Don't need to check anything else, as if outputs.size == 1 then the output is equal to
|
||||||
// the input ignoring the owner field due to the grouping.
|
// the input ignoring the owner field due to the grouping.
|
||||||
}
|
}
|
||||||
@ -82,10 +82,10 @@ class CommercialPaperLegacy : Contract {
|
|||||||
val received = tx.outputs.sumCashBy(input.owner)
|
val received = tx.outputs.sumCashBy(input.owner)
|
||||||
val time = timestamp?.after ?: throw IllegalArgumentException("Redemptions must be timestamped")
|
val time = timestamp?.after ?: throw IllegalArgumentException("Redemptions must be timestamped")
|
||||||
requireThat {
|
requireThat {
|
||||||
"the paper must have matured" by (time >= input.maturityDate)
|
"the paper must have matured" using (time >= input.maturityDate)
|
||||||
"the received amount equals the face value" by (received == input.faceValue)
|
"the received amount equals the face value" using (received == input.faceValue)
|
||||||
"the paper must be destroyed" by outputs.isEmpty()
|
"the paper must be destroyed" using outputs.isEmpty()
|
||||||
"the transaction is signed by the owner of the CP" by (input.owner in command.signers)
|
"the transaction is signed by the owner of the CP" using (input.owner in command.signers)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,14 +94,14 @@ class CommercialPaperLegacy : Contract {
|
|||||||
val time = timestamp?.before ?: throw IllegalArgumentException("Issuances must be timestamped")
|
val time = timestamp?.before ?: throw IllegalArgumentException("Issuances must be timestamped")
|
||||||
requireThat {
|
requireThat {
|
||||||
// Don't allow people to issue commercial paper under other entities identities.
|
// Don't allow people to issue commercial paper under other entities identities.
|
||||||
"output states are issued by a command signer" by
|
"output states are issued by a command signer" using
|
||||||
(output.issuance.party.owningKey in command.signers)
|
(output.issuance.party.owningKey in command.signers)
|
||||||
"output values sum to more than the inputs" by (output.faceValue.quantity > 0)
|
"output values sum to more than the inputs" using (output.faceValue.quantity > 0)
|
||||||
"the maturity date is not in the past" by (time < output.maturityDate)
|
"the maturity date is not in the past" using (time < output.maturityDate)
|
||||||
// Don't allow an existing CP state to be replaced by this issuance.
|
// Don't allow an existing CP state to be replaced by this issuance.
|
||||||
// TODO: this has a weird/incorrect assertion string because it doesn't quite match the logic in the clause version.
|
// TODO: this has a weird/incorrect assertion string because it doesn't quite match the logic in the clause version.
|
||||||
// TODO: Consider how to handle the case of mistaken issuances, or other need to patch.
|
// TODO: Consider how to handle the case of mistaken issuances, or other need to patch.
|
||||||
"output values sum to more than the inputs" by inputs.isEmpty()
|
"output values sum to more than the inputs" using inputs.isEmpty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,8 +160,8 @@ class Obligation<P : Any> : Contract {
|
|||||||
.filter { it.amount.token in template.acceptableIssuedProducts }
|
.filter { it.amount.token in template.acceptableIssuedProducts }
|
||||||
// Catch that there's nothing useful here, so we can dump out a useful error
|
// Catch that there's nothing useful here, so we can dump out a useful error
|
||||||
requireThat {
|
requireThat {
|
||||||
"there are fungible asset state outputs" by (assetStates.size > 0)
|
"there are fungible asset state outputs" using (assetStates.size > 0)
|
||||||
"there are defined acceptable fungible asset states" by (acceptableAssetStates.size > 0)
|
"there are defined acceptable fungible asset states" using (acceptableAssetStates.size > 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
val amountReceivedByOwner = acceptableAssetStates.groupBy { it.owner }
|
val amountReceivedByOwner = acceptableAssetStates.groupBy { it.owner }
|
||||||
@ -184,15 +184,15 @@ class Obligation<P : Any> : Contract {
|
|||||||
requireThat {
|
requireThat {
|
||||||
// Insist that we can be the only contract consuming inputs, to ensure no other contract can think it's being
|
// Insist that we can be the only contract consuming inputs, to ensure no other contract can think it's being
|
||||||
// settled as well
|
// settled as well
|
||||||
"all move commands relate to this contract" by (moveCommands.map { it.value.contractHash }
|
"all move commands relate to this contract" using (moveCommands.map { it.value.contractHash }
|
||||||
.all { it == null || it == Obligation<P>().legalContractReference })
|
.all { it == null || it == Obligation<P>().legalContractReference })
|
||||||
// Settle commands exclude all other commands, so we don't need to check for contracts moving at the same
|
// Settle commands exclude all other commands, so we don't need to check for contracts moving at the same
|
||||||
// time.
|
// time.
|
||||||
"amounts paid must match recipients to settle" by inputs.map { it.owner }.containsAll(amountReceivedByOwner.keys)
|
"amounts paid must match recipients to settle" using inputs.map { it.owner }.containsAll(amountReceivedByOwner.keys)
|
||||||
"amount in settle command ${command.value.amount} matches settled total $totalAmountSettled" by (command.value.amount == totalAmountSettled)
|
"amount in settle command ${command.value.amount} matches settled total $totalAmountSettled" using (command.value.amount == totalAmountSettled)
|
||||||
"signatures are present from all obligors" by command.signers.containsAll(requiredSigners)
|
"signatures are present from all obligors" using command.signers.containsAll(requiredSigners)
|
||||||
"there are no zero sized inputs" by inputs.none { it.amount.quantity == 0L }
|
"there are no zero sized inputs" using inputs.none { it.amount.quantity == 0L }
|
||||||
"at obligor ${obligor} the obligations after settlement balance" by
|
"at obligor ${obligor} the obligations after settlement balance" using
|
||||||
(inputAmount == outputAmount + Amount(totalPenniesSettled, groupingKey))
|
(inputAmount == outputAmount + Amount(totalPenniesSettled, groupingKey))
|
||||||
}
|
}
|
||||||
return setOf(command.value)
|
return setOf(command.value)
|
||||||
@ -216,8 +216,8 @@ class Obligation<P : Any> : Contract {
|
|||||||
private fun verify(inputs: List<State<P>>,
|
private fun verify(inputs: List<State<P>>,
|
||||||
outputs: List<State<P>>): Set<C> {
|
outputs: List<State<P>>): Set<C> {
|
||||||
requireThat {
|
requireThat {
|
||||||
"all inputs are in the normal state " by inputs.all { it.lifecycle == Lifecycle.NORMAL }
|
"all inputs are in the normal state " using inputs.all { it.lifecycle == Lifecycle.NORMAL }
|
||||||
"all outputs are in the normal state " by outputs.all { it.lifecycle == Lifecycle.NORMAL }
|
"all outputs are in the normal state " using outputs.all { it.lifecycle == Lifecycle.NORMAL }
|
||||||
}
|
}
|
||||||
return emptySet()
|
return emptySet()
|
||||||
}
|
}
|
||||||
@ -407,17 +407,17 @@ class Obligation<P : Any> : Contract {
|
|||||||
val expectedOutput = input.copy(lifecycle = expectedOutputLifecycle)
|
val expectedOutput = input.copy(lifecycle = expectedOutputLifecycle)
|
||||||
|
|
||||||
requireThat {
|
requireThat {
|
||||||
"there is a timestamp from the authority" by (timestamp != null)
|
"there is a timestamp from the authority" using (timestamp != null)
|
||||||
"the due date has passed" by (timestamp!!.after?.isAfter(deadline) ?: false)
|
"the due date has passed" using (timestamp!!.after?.isAfter(deadline) ?: false)
|
||||||
"input state lifecycle is correct" by (input.lifecycle == expectedInputLifecycle)
|
"input state lifecycle is correct" using (input.lifecycle == expectedInputLifecycle)
|
||||||
"output state corresponds exactly to input state, with lifecycle changed" by (expectedOutput == actualOutput)
|
"output state corresponds exactly to input state, with lifecycle changed" using (expectedOutput == actualOutput)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val owningPubKeys = inputs.filter { it is State<P> }.map { (it as State<P>).beneficiary }.toSet()
|
val owningPubKeys = inputs.filter { it is State<P> }.map { (it as State<P>).beneficiary }.toSet()
|
||||||
val keysThatSigned = setLifecycleCommand.signers.toSet()
|
val keysThatSigned = setLifecycleCommand.signers.toSet()
|
||||||
requireThat {
|
requireThat {
|
||||||
"the owning keys are a subset of the signing keys" by keysThatSigned.containsAll(owningPubKeys)
|
"the owning keys are a subset of the signing keys" using keysThatSigned.containsAll(owningPubKeys)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -434,10 +434,10 @@ class Obligation<P : Any> : Contract {
|
|||||||
val netState = states.firstOrNull()?.bilateralNetState
|
val netState = states.firstOrNull()?.bilateralNetState
|
||||||
|
|
||||||
requireThat {
|
requireThat {
|
||||||
"at least two states are provided" by (states.size >= 2)
|
"at least two states are provided" using (states.size >= 2)
|
||||||
"all states are in the normal lifecycle state " by (states.all { it.lifecycle == Lifecycle.NORMAL })
|
"all states are in the normal lifecycle state " using (states.all { it.lifecycle == Lifecycle.NORMAL })
|
||||||
"all states must be bilateral nettable" by (states.all { it.bilateralNetState == netState })
|
"all states must be bilateral nettable" using (states.all { it.bilateralNetState == netState })
|
||||||
"signer is in the state parties" by (signer in netState!!.partyKeys)
|
"signer is in the state parties" using (signer in netState!!.partyKeys)
|
||||||
}
|
}
|
||||||
|
|
||||||
val out = states.reduce(State<P>::net)
|
val out = states.reduce(State<P>::net)
|
||||||
@ -484,7 +484,7 @@ class Obligation<P : Any> : Contract {
|
|||||||
notary: Party,
|
notary: Party,
|
||||||
vararg states: State<P>) {
|
vararg states: State<P>) {
|
||||||
requireThat {
|
requireThat {
|
||||||
"all states are in the normal lifecycle state " by (states.all { it.lifecycle == Lifecycle.NORMAL })
|
"all states are in the normal lifecycle state " using (states.all { it.lifecycle == Lifecycle.NORMAL })
|
||||||
}
|
}
|
||||||
val groups = states.groupBy { it.multilateralNetState }
|
val groups = states.groupBy { it.multilateralNetState }
|
||||||
val partyLookup = HashMap<PublicKey, AnonymousParty>()
|
val partyLookup = HashMap<PublicKey, AnonymousParty>()
|
||||||
@ -563,11 +563,11 @@ class Obligation<P : Any> : Contract {
|
|||||||
val obligationOwner = states.first().data.beneficiary
|
val obligationOwner = states.first().data.beneficiary
|
||||||
|
|
||||||
requireThat {
|
requireThat {
|
||||||
"all fungible asset states use the same notary" by (assetStatesAndRefs.all { it.state.notary == notary })
|
"all fungible asset states use the same notary" using (assetStatesAndRefs.all { it.state.notary == notary })
|
||||||
"all obligation states are in the normal state" by (statesAndRefs.all { it.state.data.lifecycle == Lifecycle.NORMAL })
|
"all obligation states are in the normal state" using (statesAndRefs.all { it.state.data.lifecycle == Lifecycle.NORMAL })
|
||||||
"all obligation states use the same notary" by (statesAndRefs.all { it.state.notary == notary })
|
"all obligation states use the same notary" using (statesAndRefs.all { it.state.notary == notary })
|
||||||
"all obligation states have the same obligor" by (statesAndRefs.all { it.state.data.obligor == obligationIssuer })
|
"all obligation states have the same obligor" using (statesAndRefs.all { it.state.data.obligor == obligationIssuer })
|
||||||
"all obligation states have the same beneficiary" by (statesAndRefs.all { it.state.data.beneficiary == obligationOwner })
|
"all obligation states have the same beneficiary" using (statesAndRefs.all { it.state.data.beneficiary == obligationOwner })
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: A much better (but more complex) solution would be to have two iterators, one for obligations,
|
// TODO: A much better (but more complex) solution would be to have two iterators, one for obligations,
|
||||||
|
@ -109,8 +109,8 @@ abstract class AbstractConserveAmount<S : FungibleAsset<T>, C : CommandData, T :
|
|||||||
val amountExitingLedger: Amount<Issued<T>> = exitCommand?.value?.amount ?: Amount(0, groupingKey)
|
val amountExitingLedger: Amount<Issued<T>> = exitCommand?.value?.amount ?: Amount(0, groupingKey)
|
||||||
|
|
||||||
requireThat {
|
requireThat {
|
||||||
"there are no zero sized inputs" by inputs.none { it.amount.quantity == 0L }
|
"there are no zero sized inputs" using inputs.none { it.amount.quantity == 0L }
|
||||||
"for reference ${deposit.reference} at issuer ${deposit.party} the amounts balance: ${inputAmount.quantity} - ${amountExitingLedger.quantity} != ${outputAmount.quantity}" by
|
"for reference ${deposit.reference} at issuer ${deposit.party} the amounts balance: ${inputAmount.quantity} - ${amountExitingLedger.quantity} != ${outputAmount.quantity}" using
|
||||||
(inputAmount == outputAmount + amountExitingLedger)
|
(inputAmount == outputAmount + amountExitingLedger)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,11 +41,11 @@ abstract class AbstractIssue<in S : ContractState, C : CommandData, T : Any>(
|
|||||||
val inputAmount = inputs.sumOrZero(groupingKey)
|
val inputAmount = inputs.sumOrZero(groupingKey)
|
||||||
val outputAmount = outputs.sum()
|
val outputAmount = outputs.sum()
|
||||||
requireThat {
|
requireThat {
|
||||||
"the issue command has a nonce" by (issueCommand.value.nonce != 0L)
|
"the issue command has a nonce" using (issueCommand.value.nonce != 0L)
|
||||||
// TODO: This doesn't work with the trader demo, so use the underlying key instead
|
// TODO: This doesn't work with the trader demo, so use the underlying key instead
|
||||||
// "output states are issued by a command signer" by (issuer in issueCommand.signingParties)
|
// "output states are issued by a command signer" by (issuer in issueCommand.signingParties)
|
||||||
"output states are issued by a command signer" by (issuer.owningKey in issueCommand.signers)
|
"output states are issued by a command signer" using (issuer.owningKey in issueCommand.signers)
|
||||||
"output values sum to more than the inputs" by (outputAmount > inputAmount)
|
"output values sum to more than the inputs" using (outputAmount > inputAmount)
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is safe because we've taken the command from a collection of C objects at the start
|
// This is safe because we've taken the command from a collection of C objects at the start
|
||||||
|
@ -79,9 +79,10 @@ open class NetClause<C : CommandData, P : Any> : Clause<ContractState, C, Unit>(
|
|||||||
// Sum the columns of the matrices. This will yield the net amount payable to/from each party to/from all other participants.
|
// Sum the columns of the matrices. This will yield the net amount payable to/from each party to/from all other participants.
|
||||||
// The two summaries must match, reflecting that the amounts owed match on both input and output.
|
// The two summaries must match, reflecting that the amounts owed match on both input and output.
|
||||||
requireThat {
|
requireThat {
|
||||||
"all input states use the same template" by (inputs.all { it.template == template })
|
"all input states use the same template" using (inputs.all { it.template == template })
|
||||||
"all output states use the same template" by (outputs.all { it.template == template })
|
"all output states use the same template" using (outputs.all { it.template == template })
|
||||||
"amounts owed on input and output must match" by (sumAmountsDue(inputBalances) == sumAmountsDue(outputBalances))
|
"amounts owed on input and output must match" using (sumAmountsDue(inputBalances) == sumAmountsDue
|
||||||
|
(outputBalances))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Handle proxies nominated by parties, i.e. a central clearing service
|
// TODO: Handle proxies nominated by parties, i.e. a central clearing service
|
||||||
|
@ -14,7 +14,7 @@ open class NoZeroSizedOutputs<in S : FungibleAsset<T>, C : CommandData, T : Any>
|
|||||||
commands: List<AuthenticatedObject<C>>,
|
commands: List<AuthenticatedObject<C>>,
|
||||||
groupingKey: Issued<T>?): Set<C> {
|
groupingKey: Issued<T>?): Set<C> {
|
||||||
requireThat {
|
requireThat {
|
||||||
"there are no zero sized outputs" by outputs.none { it.amount.quantity == 0L }
|
"there are no zero sized outputs" using outputs.none { it.amount.quantity == 0L }
|
||||||
}
|
}
|
||||||
return emptySet()
|
return emptySet()
|
||||||
}
|
}
|
||||||
|
@ -479,22 +479,22 @@ class InterestRateSwap : Contract {
|
|||||||
// These functions may make more sense to use for basket types, but for now let's leave them here
|
// These functions may make more sense to use for basket types, but for now let's leave them here
|
||||||
fun checkLegDates(legs: List<CommonLeg>) {
|
fun checkLegDates(legs: List<CommonLeg>) {
|
||||||
requireThat {
|
requireThat {
|
||||||
"Effective date is before termination date" by legs.all { it.effectiveDate < it.terminationDate }
|
"Effective date is before termination date" using legs.all { it.effectiveDate < it.terminationDate }
|
||||||
"Effective dates are in alignment" by legs.all { it.effectiveDate == legs[0].effectiveDate }
|
"Effective dates are in alignment" using legs.all { it.effectiveDate == legs[0].effectiveDate }
|
||||||
"Termination dates are in alignment" by legs.all { it.terminationDate == legs[0].terminationDate }
|
"Termination dates are in alignment" using legs.all { it.terminationDate == legs[0].terminationDate }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkLegAmounts(legs: List<CommonLeg>) {
|
fun checkLegAmounts(legs: List<CommonLeg>) {
|
||||||
requireThat {
|
requireThat {
|
||||||
"The notional is non zero" by legs.any { it.notional.quantity > (0).toLong() }
|
"The notional is non zero" using legs.any { it.notional.quantity > (0).toLong() }
|
||||||
"The notional for all legs must be the same" by legs.all { it.notional == legs[0].notional }
|
"The notional for all legs must be the same" using legs.all { it.notional == legs[0].notional }
|
||||||
}
|
}
|
||||||
for (leg: CommonLeg in legs) {
|
for (leg: CommonLeg in legs) {
|
||||||
if (leg is FixedLeg<*>) {
|
if (leg is FixedLeg<*>) {
|
||||||
requireThat {
|
requireThat {
|
||||||
// TODO: Confirm: would someone really enter a swap with a negative fixed rate?
|
// TODO: Confirm: would someone really enter a swap with a negative fixed rate?
|
||||||
"Fixed leg rate must be positive" by leg.fixedRate.isPositive()
|
"Fixed leg rate must be positive" using leg.fixedRate.isPositive()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -547,21 +547,21 @@ class InterestRateSwap : Contract {
|
|||||||
val command = tx.commands.requireSingleCommand<Commands.Agree>()
|
val command = tx.commands.requireSingleCommand<Commands.Agree>()
|
||||||
val irs = outputs.filterIsInstance<State<*>>().single()
|
val irs = outputs.filterIsInstance<State<*>>().single()
|
||||||
requireThat {
|
requireThat {
|
||||||
"There are no in states for an agreement" by inputs.isEmpty()
|
"There are no in states for an agreement" using inputs.isEmpty()
|
||||||
"There are events in the fix schedule" by (irs.calculation.fixedLegPaymentSchedule.isNotEmpty())
|
"There are events in the fix schedule" using (irs.calculation.fixedLegPaymentSchedule.isNotEmpty())
|
||||||
"There are events in the float schedule" by (irs.calculation.floatingLegPaymentSchedule.isNotEmpty())
|
"There are events in the float schedule" using (irs.calculation.floatingLegPaymentSchedule.isNotEmpty())
|
||||||
"All notionals must be non zero" by (irs.fixedLeg.notional.quantity > 0 && irs.floatingLeg.notional.quantity > 0)
|
"All notionals must be non zero" using (irs.fixedLeg.notional.quantity > 0 && irs.floatingLeg.notional.quantity > 0)
|
||||||
"The fixed leg rate must be positive" by (irs.fixedLeg.fixedRate.isPositive())
|
"The fixed leg rate must be positive" using (irs.fixedLeg.fixedRate.isPositive())
|
||||||
"The currency of the notionals must be the same" by (irs.fixedLeg.notional.token == irs.floatingLeg.notional.token)
|
"The currency of the notionals must be the same" using (irs.fixedLeg.notional.token == irs.floatingLeg.notional.token)
|
||||||
"All leg notionals must be the same" by (irs.fixedLeg.notional == irs.floatingLeg.notional)
|
"All leg notionals must be the same" using (irs.fixedLeg.notional == irs.floatingLeg.notional)
|
||||||
|
|
||||||
"The effective date is before the termination date for the fixed leg" by (irs.fixedLeg.effectiveDate < irs.fixedLeg.terminationDate)
|
"The effective date is before the termination date for the fixed leg" using (irs.fixedLeg.effectiveDate < irs.fixedLeg.terminationDate)
|
||||||
"The effective date is before the termination date for the floating leg" by (irs.floatingLeg.effectiveDate < irs.floatingLeg.terminationDate)
|
"The effective date is before the termination date for the floating leg" using (irs.floatingLeg.effectiveDate < irs.floatingLeg.terminationDate)
|
||||||
"The effective dates are aligned" by (irs.floatingLeg.effectiveDate == irs.fixedLeg.effectiveDate)
|
"The effective dates are aligned" using (irs.floatingLeg.effectiveDate == irs.fixedLeg.effectiveDate)
|
||||||
"The termination dates are aligned" by (irs.floatingLeg.terminationDate == irs.fixedLeg.terminationDate)
|
"The termination dates are aligned" using (irs.floatingLeg.terminationDate == irs.fixedLeg.terminationDate)
|
||||||
"The rates are valid" by checkRates(listOf(irs.fixedLeg, irs.floatingLeg))
|
"The rates are valid" using checkRates(listOf(irs.fixedLeg, irs.floatingLeg))
|
||||||
"The schedules are valid" by checkSchedules(listOf(irs.fixedLeg, irs.floatingLeg))
|
"The schedules are valid" using checkSchedules(listOf(irs.fixedLeg, irs.floatingLeg))
|
||||||
"The fixing period date offset cannot be negative" by (irs.floatingLeg.fixingPeriodOffset >= 0)
|
"The fixing period date offset cannot be negative" using (irs.floatingLeg.fixingPeriodOffset >= 0)
|
||||||
|
|
||||||
// TODO: further tests
|
// TODO: further tests
|
||||||
}
|
}
|
||||||
@ -588,8 +588,8 @@ class InterestRateSwap : Contract {
|
|||||||
// Having both of these tests are "redundant" as far as verify() goes, however, by performing both
|
// Having both of these tests are "redundant" as far as verify() goes, however, by performing both
|
||||||
// we can relay more information back to the user in the case of failure.
|
// we can relay more information back to the user in the case of failure.
|
||||||
requireThat {
|
requireThat {
|
||||||
"There is at least one difference in the IRS floating leg payment schedules" by !paymentDifferences.isEmpty()
|
"There is at least one difference in the IRS floating leg payment schedules" using !paymentDifferences.isEmpty()
|
||||||
"There is only one change in the IRS floating leg payment schedule" by (paymentDifferences.size == 1)
|
"There is only one change in the IRS floating leg payment schedule" using (paymentDifferences.size == 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
val changedRates = paymentDifferences.single().second // Ignore the date of the changed rate (we checked that earlier).
|
val changedRates = paymentDifferences.single().second // Ignore the date of the changed rate (we checked that earlier).
|
||||||
@ -597,19 +597,19 @@ class InterestRateSwap : Contract {
|
|||||||
val fixValue = command.value.fix
|
val fixValue = command.value.fix
|
||||||
// Need to check that everything is the same apart from the new fixed rate entry.
|
// Need to check that everything is the same apart from the new fixed rate entry.
|
||||||
requireThat {
|
requireThat {
|
||||||
"The fixed leg parties are constant" by (irs.fixedLeg.fixedRatePayer == prevIrs.fixedLeg.fixedRatePayer) // Although superseded by the below test, this is included for a regression issue
|
"The fixed leg parties are constant" using (irs.fixedLeg.fixedRatePayer == prevIrs.fixedLeg.fixedRatePayer) // Although superseded by the below test, this is included for a regression issue
|
||||||
"The fixed leg is constant" by (irs.fixedLeg == prevIrs.fixedLeg)
|
"The fixed leg is constant" using (irs.fixedLeg == prevIrs.fixedLeg)
|
||||||
"The floating leg is constant" by (irs.floatingLeg == prevIrs.floatingLeg)
|
"The floating leg is constant" using (irs.floatingLeg == prevIrs.floatingLeg)
|
||||||
"The common values are constant" by (irs.common == prevIrs.common)
|
"The common values are constant" using (irs.common == prevIrs.common)
|
||||||
"The fixed leg payment schedule is constant" by (irs.calculation.fixedLegPaymentSchedule == prevIrs.calculation.fixedLegPaymentSchedule)
|
"The fixed leg payment schedule is constant" using (irs.calculation.fixedLegPaymentSchedule == prevIrs.calculation.fixedLegPaymentSchedule)
|
||||||
"The expression is unchanged" by (irs.calculation.expression == prevIrs.calculation.expression)
|
"The expression is unchanged" using (irs.calculation.expression == prevIrs.calculation.expression)
|
||||||
"There is only one changed payment in the floating leg" by (paymentDifferences.size == 1)
|
"There is only one changed payment in the floating leg" using (paymentDifferences.size == 1)
|
||||||
"There changed payment is a floating payment" by (oldFloatingRatePaymentEvent.rate is ReferenceRate)
|
"There changed payment is a floating payment" using (oldFloatingRatePaymentEvent.rate is ReferenceRate)
|
||||||
"The new payment is a fixed payment" by (newFixedRatePaymentEvent.rate is FixedRate)
|
"The new payment is a fixed payment" using (newFixedRatePaymentEvent.rate is FixedRate)
|
||||||
"The changed payments dates are aligned" by (oldFloatingRatePaymentEvent.date == newFixedRatePaymentEvent.date)
|
"The changed payments dates are aligned" using (oldFloatingRatePaymentEvent.date == newFixedRatePaymentEvent.date)
|
||||||
"The new payment has the correct rate" by (newFixedRatePaymentEvent.rate.ratioUnit!!.value == fixValue.value)
|
"The new payment has the correct rate" using (newFixedRatePaymentEvent.rate.ratioUnit!!.value == fixValue.value)
|
||||||
"The fixing is for the next required date" by (prevIrs.calculation.nextFixingDate() == fixValue.of.forDay)
|
"The fixing is for the next required date" using (prevIrs.calculation.nextFixingDate() == fixValue.of.forDay)
|
||||||
"The fix payment has the same currency as the notional" by (newFixedRatePaymentEvent.flow.token == irs.floatingLeg.notional.token)
|
"The fix payment has the same currency as the notional" using (newFixedRatePaymentEvent.flow.token == irs.floatingLeg.notional.token)
|
||||||
// "The fixing is not in the future " by (fixCommand) // The oracle should not have signed this .
|
// "The fixing is not in the future " by (fixCommand) // The oracle should not have signed this .
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -627,7 +627,7 @@ class InterestRateSwap : Contract {
|
|||||||
groupingKey: UniqueIdentifier?): Set<Commands> {
|
groupingKey: UniqueIdentifier?): Set<Commands> {
|
||||||
val command = tx.commands.requireSingleCommand<Commands.Pay>()
|
val command = tx.commands.requireSingleCommand<Commands.Pay>()
|
||||||
requireThat {
|
requireThat {
|
||||||
"Payments not supported / verifiable yet" by false
|
"Payments not supported / verifiable yet" using false
|
||||||
}
|
}
|
||||||
return setOf(command.value)
|
return setOf(command.value)
|
||||||
}
|
}
|
||||||
@ -644,8 +644,8 @@ class InterestRateSwap : Contract {
|
|||||||
val command = tx.commands.requireSingleCommand<Commands.Mature>()
|
val command = tx.commands.requireSingleCommand<Commands.Mature>()
|
||||||
val irs = inputs.filterIsInstance<State<*>>().single()
|
val irs = inputs.filterIsInstance<State<*>>().single()
|
||||||
requireThat {
|
requireThat {
|
||||||
"No more fixings to be applied" by (irs.calculation.nextFixingDate() == null)
|
"No more fixings to be applied" using (irs.calculation.nextFixingDate() == null)
|
||||||
"The irs is fully consumed and there is no id matched output state" by outputs.isEmpty()
|
"The irs is fully consumed and there is no id matched output state" using outputs.isEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
return setOf(command.value)
|
return setOf(command.value)
|
||||||
|
@ -47,10 +47,10 @@ data class PortfolioSwap(override val legalContractReference: SecureHash = Secur
|
|||||||
val command = tx.commands.requireSingleCommand<Commands.Update>()
|
val command = tx.commands.requireSingleCommand<Commands.Update>()
|
||||||
|
|
||||||
requireThat {
|
requireThat {
|
||||||
"there is only one input" by (inputs.size == 1)
|
"there is only one input" using (inputs.size == 1)
|
||||||
"there is only one output" by (outputs.size == 1)
|
"there is only one output" using (outputs.size == 1)
|
||||||
"the valuer hasn't changed" by (inputs[0].valuer == outputs[0].valuer)
|
"the valuer hasn't changed" using (inputs[0].valuer == outputs[0].valuer)
|
||||||
"the linear id hasn't changed" by (inputs[0].linearId == outputs[0].linearId)
|
"the linear id hasn't changed" using (inputs[0].linearId == outputs[0].linearId)
|
||||||
}
|
}
|
||||||
|
|
||||||
return setOf(command.value)
|
return setOf(command.value)
|
||||||
@ -68,10 +68,10 @@ data class PortfolioSwap(override val legalContractReference: SecureHash = Secur
|
|||||||
val command = tx.commands.requireSingleCommand<Commands.Agree>()
|
val command = tx.commands.requireSingleCommand<Commands.Agree>()
|
||||||
|
|
||||||
requireThat {
|
requireThat {
|
||||||
"there are no inputs" by (inputs.size == 0)
|
"there are no inputs" using (inputs.size == 0)
|
||||||
"there is one output" by (outputs.size == 1)
|
"there is one output" using (outputs.size == 1)
|
||||||
"valuer must be a party" by (outputs[0].parties.contains(outputs[0].valuer))
|
"valuer must be a party" using (outputs[0].parties.contains(outputs[0].valuer))
|
||||||
"all participants must be parties" by (outputs[0].parties.map { it.owningKey }.containsAll(outputs[0].participants))
|
"all participants must be parties" using (outputs[0].parties.map { it.owningKey }.containsAll(outputs[0].participants))
|
||||||
}
|
}
|
||||||
|
|
||||||
return setOf(command.value)
|
return setOf(command.value)
|
||||||
|
Loading…
Reference in New Issue
Block a user