mirror of
https://github.com/corda/corda.git
synced 2025-01-19 11:16:54 +00:00
Merged in rnicoll-commercial-paper-cleanup (pull request #223)
Tweak conditions on JavaCommercialPaper to match CommercialPaper
This commit is contained in:
commit
910d1932c9
@ -3,8 +3,10 @@ package com.r3corda.contracts;
|
||||
import com.google.common.collect.*;
|
||||
import com.r3corda.contracts.asset.*;
|
||||
import com.r3corda.core.contracts.*;
|
||||
import static com.r3corda.core.contracts.ContractsDSL.requireThat;
|
||||
import com.r3corda.core.contracts.TransactionForContract.*;
|
||||
import com.r3corda.core.crypto.*;
|
||||
import kotlin.Unit;
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
import java.security.*;
|
||||
@ -171,59 +173,52 @@ public class JavaCommercialPaper implements Contract {
|
||||
if (cmd.getValue() instanceof JavaCommercialPaper.Commands.Issue) {
|
||||
Commands.Issue issueCommand = (Commands.Issue) cmd.getValue();
|
||||
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);
|
||||
if (timestampCommand == null)
|
||||
throw new IllegalArgumentException("Failed Requirement: must be timestamped");
|
||||
Instant time = null == timestampCommand
|
||||
? null
|
||||
: timestampCommand.getBefore();
|
||||
|
||||
Instant time = timestampCommand.getBefore();
|
||||
|
||||
if (time == null || !time.isBefore(output.maturityDate)) {
|
||||
throw new IllegalStateException("Failed Requirement: the maturity date is not in the past");
|
||||
}
|
||||
|
||||
if (!cmd.getSigners().contains(output.issuance.getParty().getOwningKey())) {
|
||||
throw new IllegalStateException("Failed Requirement: output states are issued by a command signer");
|
||||
}
|
||||
requireThat(require -> {
|
||||
require.by("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.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()));
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
} else {
|
||||
// Everything else (Move, Redeem) requires inputs (they are not first to be actioned)
|
||||
// There should be only a single input due to aggregation above
|
||||
State input = single(inputs);
|
||||
|
||||
if (!cmd.getSigners().contains(input.getOwner()))
|
||||
throw new IllegalStateException("Failed requirement: the transaction is signed by the owner of the CP");
|
||||
requireThat(require -> {
|
||||
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) {
|
||||
// Check the output CP state is the same as the input state, ignoring the owner field.
|
||||
State output = single(outputs);
|
||||
|
||||
if (!output.getFaceValue().equals(input.getFaceValue()) ||
|
||||
!output.getIssuance().equals(input.getIssuance()) ||
|
||||
!output.getMaturityDate().equals(input.getMaturityDate()))
|
||||
throw new IllegalStateException("Failed requirement: the output state is the same as the input state except for owner");
|
||||
requireThat(require -> {
|
||||
require.by("the state is propagated", outputs.size() == 1);
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
// 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.
|
||||
} else if (cmd.getValue() instanceof JavaCommercialPaper.Commands.Redeem) {
|
||||
TimestampCommand timestampCommand = tx.getTimestampBy(((Commands.Redeem) cmd.getValue()).notary);
|
||||
if (timestampCommand == null)
|
||||
throw new IllegalArgumentException("Failed Requirement: must be timestamped");
|
||||
Instant time = timestampCommand.getBefore();
|
||||
|
||||
Instant time = null == timestampCommand
|
||||
? null
|
||||
: timestampCommand.getBefore();
|
||||
Amount<Issued<Currency>> received = CashKt.sumCashBy(tx.getOutputs(), input.getOwner());
|
||||
|
||||
if (!received.equals(input.getFaceValue()))
|
||||
throw new IllegalStateException("Failed Requirement: received amount equals the face value: "
|
||||
+ received + " vs " + input.getFaceValue());
|
||||
if (time == null || time.isBefore(input.getMaturityDate()))
|
||||
throw new IllegalStateException("Failed requirement: the paper must have matured");
|
||||
if (!input.getFaceValue().equals(received))
|
||||
throw new IllegalStateException("Failed requirement: the received amount equals the face value");
|
||||
if (!outputs.isEmpty())
|
||||
throw new IllegalStateException("Failed requirement: the paper must be destroyed");
|
||||
requireThat(require -> {
|
||||
require.by("must be timestamped", timestampCommand != null);
|
||||
require.by("received amount equals the face value: "
|
||||
+ received + " vs " + input.getFaceValue(), received.equals(input.getFaceValue()));
|
||||
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;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -421,29 +421,34 @@ logic.
|
||||
// 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));
|
||||
|
||||
if (!cmd.getSigners().contains(input.getOwner()))
|
||||
throw new IllegalStateException("Failed requirement: the transaction is signed by the owner of the CP");
|
||||
requireThat(require -> {
|
||||
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) {
|
||||
// Check the output CP state is the same as the input state, ignoring the owner field.
|
||||
State output = single(outputs);
|
||||
|
||||
if (!output.getFaceValue().equals(input.getFaceValue()) ||
|
||||
!output.getIssuance().equals(input.getIssuance()) ||
|
||||
!output.getMaturityDate().equals(input.getMaturityDate()))
|
||||
throw new IllegalStateException("Failed requirement: the output state is the same as the input state except for owner");
|
||||
requireThat(require -> {
|
||||
require.by("the state is propagated", outputs.size() == 1);
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
// 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.
|
||||
} else if (cmd.getValue() instanceof JavaCommercialPaper.Commands.Redeem) {
|
||||
Amount received = CashKt.sumCashOrNull(inputs);
|
||||
if (time == null)
|
||||
throw new IllegalArgumentException("Redemption transactions must be timestamped");
|
||||
if (received == null)
|
||||
throw new IllegalStateException("Failed requirement: no cash being redeemed");
|
||||
if (input.getMaturityDate().isAfter(time))
|
||||
throw new IllegalStateException("Failed requirement: the paper must have matured");
|
||||
if (!input.getFaceValue().equals(received))
|
||||
throw new IllegalStateException("Failed requirement: the received amount equals the face value");
|
||||
if (!outputs.isEmpty())
|
||||
throw new IllegalStateException("Failed requirement: the paper must be destroyed");
|
||||
TimestampCommand timestampCommand = tx.getTimestampBy(((Commands.Redeem) cmd.getValue()).notary);
|
||||
Instant time = null == timestampCommand
|
||||
? null
|
||||
: timestampCommand.getBefore();
|
||||
Amount<Issued<Currency>> received = CashKt.sumCashBy(tx.getOutputs(), input.getOwner());
|
||||
|
||||
requireThat(require -> {
|
||||
require.by("must be timestamped", timestampCommand != null);
|
||||
require.by("received amount equals the face value: "
|
||||
+ received + " vs " + input.getFaceValue(), received.equals(input.getFaceValue()));
|
||||
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) {
|
||||
// .. etc .. (see Kotlin for full definition)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user