Merged in rnicoll-obligation-settle-amount (pull request #252)

Add missing checks on settled amount
This commit is contained in:
Ross Nicoll 2016-08-01 14:26:00 +01:00
commit 7aef03baab
2 changed files with 19 additions and 4 deletions

View File

@ -182,14 +182,16 @@ class Obligation<P> : ClauseVerifier() {
}
}
val totalAmountSettled = Amount(totalPenniesSettled, command.value.amount.token)
requireThat {
// Insist that we can be the only contract consuming inputs, to ensure no other contract can think it's being
// settled as well
requireThat {
"all move commands relate to this contract" by (moveCommands.map { it.value.contractHash }
.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
// time.
"amounts paid must match recipients to settle" by inputs.map { it.owner }.containsAll(amountReceivedByOwner.keys)
"amount in settle command ${command.value.amount} matches settled total ${totalAmountSettled}" by (command.value.amount == totalAmountSettled)
"signatures are present from all obligors" by command.signers.containsAll(requiredSigners)
"there are no zero sized inputs" by inputs.none { it.amount.quantity == 0L }
"at obligor ${obligor.name} the obligations after settlement balance" by

View File

@ -462,9 +462,9 @@ class ObligationTests {
transaction("Settlement") {
input(oneMillionDollars.OBLIGATION between Pair(ALICE, BOB_PUBKEY))
input(500000.DOLLARS.CASH `issued by` defaultIssuer `owned by` ALICE_PUBKEY)
output("Alice's $5,000,000 obligation to Bob") { halfAMillionDollars.OBLIGATION between Pair(ALICE, BOB_PUBKEY) }
output("Alice's $500,000 obligation to Bob") { halfAMillionDollars.OBLIGATION between Pair(ALICE, BOB_PUBKEY) }
output("Bob's $500,000") { 500000.DOLLARS.CASH `issued by` defaultIssuer `owned by` BOB_PUBKEY }
command(ALICE_PUBKEY) { Obligation.Commands.Settle<Currency>(Amount(oneMillionDollars.quantity, inState.issuanceDef)) }
command(ALICE_PUBKEY) { Obligation.Commands.Settle<Currency>(Amount(oneMillionDollars.quantity / 2, inState.issuanceDef)) }
command(ALICE_PUBKEY) { Cash.Commands.Move(Obligation<Currency>().legalContractReference) }
this.verifies()
}
@ -482,6 +482,19 @@ class ObligationTests {
this `fails with` "all inputs are in the normal state"
}
}
// Make sure settlement amount must match the amount leaving the ledger
ledger {
obligationTestRoots(this)
transaction("Settlement") {
input("Alice's $1,000,000 obligation to Bob")
input("Alice's $1,000,000")
output("Bob's $1,000,000") { 1000000.DOLLARS.CASH `issued by` defaultIssuer `owned by` BOB_PUBKEY }
command(ALICE_PUBKEY) { Obligation.Commands.Settle<Currency>(Amount(oneMillionDollars.quantity / 2, inState.issuanceDef)) }
command(ALICE_PUBKEY) { Cash.Commands.Move(Obligation<Currency>().legalContractReference) }
this `fails with` "amount in settle command"
}
}
}
@Test