Merged in rnicoll-commercial-paper-cleanup (pull request #223)

Tweak conditions on JavaCommercialPaper to match CommercialPaper
This commit is contained in:
Ross Nicoll 2016-07-12 14:51:08 +01:00
commit 910d1932c9
2 changed files with 60 additions and 60 deletions

View File

@ -3,8 +3,10 @@ package com.r3corda.contracts;
import com.google.common.collect.*; import com.google.common.collect.*;
import com.r3corda.contracts.asset.*; import com.r3corda.contracts.asset.*;
import com.r3corda.core.contracts.*; import com.r3corda.core.contracts.*;
import static com.r3corda.core.contracts.ContractsDSL.requireThat;
import com.r3corda.core.contracts.TransactionForContract.*; import com.r3corda.core.contracts.TransactionForContract.*;
import com.r3corda.core.crypto.*; import com.r3corda.core.crypto.*;
import kotlin.Unit;
import org.jetbrains.annotations.*; import org.jetbrains.annotations.*;
import java.security.*; import java.security.*;
@ -171,59 +173,52 @@ public class JavaCommercialPaper implements Contract {
if (cmd.getValue() instanceof JavaCommercialPaper.Commands.Issue) { if (cmd.getValue() instanceof JavaCommercialPaper.Commands.Issue) {
Commands.Issue issueCommand = (Commands.Issue) cmd.getValue(); Commands.Issue issueCommand = (Commands.Issue) cmd.getValue();
State output = single(outputs); State output = single(outputs);
if (!inputs.isEmpty()) {
throw new IllegalStateException("Failed Requirement: output values sum to more than the inputs");
}
if (output.faceValue.getQuantity() == 0) {
throw new IllegalStateException("Failed Requirement: output values sum to more than the inputs");
}
TimestampCommand timestampCommand = tx.getTimestampBy(issueCommand.notary); TimestampCommand timestampCommand = tx.getTimestampBy(issueCommand.notary);
if (timestampCommand == null) Instant time = null == timestampCommand
throw new IllegalArgumentException("Failed Requirement: must be timestamped"); ? null
: timestampCommand.getBefore();
Instant time = timestampCommand.getBefore(); requireThat(require -> {
require.by("output values sum to more than the inputs", inputs.isEmpty());
if (time == null || !time.isBefore(output.maturityDate)) { require.by("output values sum to more than the inputs", output.faceValue.getQuantity() > 0);
throw new IllegalStateException("Failed Requirement: the maturity date is not in the past"); require.by("must be timestamped", timestampCommand != null);
} require.by("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()));
if (!cmd.getSigners().contains(output.issuance.getParty().getOwningKey())) { return Unit.INSTANCE;
throw new IllegalStateException("Failed Requirement: output states are issued by a command signer"); });
}
} else { } else {
// Everything else (Move, Redeem) requires inputs (they are not first to be actioned) // Everything else (Move, Redeem) requires inputs (they are not first to be actioned)
// There should be only a single input due to aggregation above // There should be only a single input due to aggregation above
State input = single(inputs); State input = single(inputs);
if (!cmd.getSigners().contains(input.getOwner())) requireThat(require -> {
throw new IllegalStateException("Failed requirement: the transaction is signed by the owner of the CP"); require.by("the transaction is signed by the owner of the CP", cmd.getSigners().contains(input.getOwner()));
return Unit.INSTANCE;
});
if (cmd.getValue() instanceof JavaCommercialPaper.Commands.Move) { if (cmd.getValue() instanceof JavaCommercialPaper.Commands.Move) {
// Check the output CP state is the same as the input state, ignoring the owner field. requireThat(require -> {
State output = single(outputs); require.by("the state is propagated", outputs.size() == 1);
return Unit.INSTANCE;
if (!output.getFaceValue().equals(input.getFaceValue()) || });
!output.getIssuance().equals(input.getIssuance()) || // Don't need to check anything else, as if outputs.size == 1 then the output is equal to
!output.getMaturityDate().equals(input.getMaturityDate())) // the input ignoring the owner field due to the grouping.
throw new IllegalStateException("Failed requirement: the output state is the same as the input state except for owner");
} else if (cmd.getValue() instanceof JavaCommercialPaper.Commands.Redeem) { } else if (cmd.getValue() instanceof JavaCommercialPaper.Commands.Redeem) {
TimestampCommand timestampCommand = tx.getTimestampBy(((Commands.Redeem) cmd.getValue()).notary); TimestampCommand timestampCommand = tx.getTimestampBy(((Commands.Redeem) cmd.getValue()).notary);
if (timestampCommand == null) Instant time = null == timestampCommand
throw new IllegalArgumentException("Failed Requirement: must be timestamped"); ? null
Instant time = timestampCommand.getBefore(); : timestampCommand.getBefore();
Amount<Issued<Currency>> received = CashKt.sumCashBy(tx.getOutputs(), input.getOwner()); Amount<Issued<Currency>> received = CashKt.sumCashBy(tx.getOutputs(), input.getOwner());
if (!received.equals(input.getFaceValue())) requireThat(require -> {
throw new IllegalStateException("Failed Requirement: received amount equals the face value: " require.by("must be timestamped", timestampCommand != null);
+ received + " vs " + input.getFaceValue()); require.by("received amount equals the face value: "
if (time == null || time.isBefore(input.getMaturityDate())) + received + " vs " + input.getFaceValue(), received.equals(input.getFaceValue()));
throw new IllegalStateException("Failed requirement: the paper must have matured"); require.by("the paper must have matured", time != null && !time.isBefore(input.getMaturityDate()));
if (!input.getFaceValue().equals(received)) require.by("the received amount equals the face value", input.getFaceValue().equals(received));
throw new IllegalStateException("Failed requirement: the received amount equals the face value"); require.by("the paper must be destroyed", outputs.isEmpty());
if (!outputs.isEmpty()) return Unit.INSTANCE;
throw new IllegalStateException("Failed requirement: the paper must be destroyed"); });
} }
} }
} }

View File

@ -421,29 +421,34 @@ logic.
// For now do not allow multiple pieces of CP to trade in a single transaction. Study this more! // For now do not allow multiple pieces of CP to trade in a single transaction. Study this more!
State input = single(filterIsInstance(inputs, State.class)); State input = single(filterIsInstance(inputs, State.class));
if (!cmd.getSigners().contains(input.getOwner())) requireThat(require -> {
throw new IllegalStateException("Failed requirement: the transaction is signed by the owner of the CP"); require.by("the transaction is signed by the owner of the CP", cmd.getSigners().contains(input.getOwner()));
return Unit.INSTANCE;
});
if (cmd.getValue() instanceof JavaCommercialPaper.Commands.Move) { if (cmd.getValue() instanceof JavaCommercialPaper.Commands.Move) {
// Check the output CP state is the same as the input state, ignoring the owner field. requireThat(require -> {
State output = single(outputs); require.by("the state is propagated", outputs.size() == 1);
return Unit.INSTANCE;
if (!output.getFaceValue().equals(input.getFaceValue()) || });
!output.getIssuance().equals(input.getIssuance()) || // Don't need to check anything else, as if outputs.size == 1 then the output is equal to
!output.getMaturityDate().equals(input.getMaturityDate())) // the input ignoring the owner field due to the grouping.
throw new IllegalStateException("Failed requirement: the output state is the same as the input state except for owner");
} else if (cmd.getValue() instanceof JavaCommercialPaper.Commands.Redeem) { } else if (cmd.getValue() instanceof JavaCommercialPaper.Commands.Redeem) {
Amount received = CashKt.sumCashOrNull(inputs); TimestampCommand timestampCommand = tx.getTimestampBy(((Commands.Redeem) cmd.getValue()).notary);
if (time == null) Instant time = null == timestampCommand
throw new IllegalArgumentException("Redemption transactions must be timestamped"); ? null
if (received == null) : timestampCommand.getBefore();
throw new IllegalStateException("Failed requirement: no cash being redeemed"); Amount<Issued<Currency>> received = CashKt.sumCashBy(tx.getOutputs(), input.getOwner());
if (input.getMaturityDate().isAfter(time))
throw new IllegalStateException("Failed requirement: the paper must have matured"); requireThat(require -> {
if (!input.getFaceValue().equals(received)) require.by("must be timestamped", timestampCommand != null);
throw new IllegalStateException("Failed requirement: the received amount equals the face value"); require.by("received amount equals the face value: "
if (!outputs.isEmpty()) + received + " vs " + input.getFaceValue(), received.equals(input.getFaceValue()));
throw new IllegalStateException("Failed requirement: the paper must be destroyed"); require.by("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.by("the paper must be destroyed", outputs.isEmpty());
return Unit.INSTANCE;
});
} else if (cmd.getValue() instanceof JavaCommercialPaper.Commands.Issue) { } else if (cmd.getValue() instanceof JavaCommercialPaper.Commands.Issue) {
// .. etc .. (see Kotlin for full definition) // .. etc .. (see Kotlin for full definition)
} }