Minor: tweak the cash/amount API

This commit is contained in:
Mike Hearn 2015-11-12 23:36:46 +01:00
parent 32143160c2
commit 1b44081880
4 changed files with 12 additions and 12 deletions

View File

@ -2,6 +2,7 @@ package contracts
import core.*
import java.security.PublicKey
import java.util.*
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
@ -91,7 +92,7 @@ object Cash : Contract {
val outputs = cashOutputs.filter { it.deposit == deposit }
outputsLeft -= outputs.size
val inputAmount = inputs.map { it.amount }.sum()
val inputAmount = inputs.map { it.amount }.sumOrThrow()
val outputAmount = outputs.map { it.amount }.sumOrZero(currency)
val issuerCommand = args.select<Commands.Exit>(institution = deposit.institution).singleOrNull()
@ -164,7 +165,7 @@ object Cash : Contract {
val states = gathered.groupBy { it.deposit }.map {
val (deposit, coins) = it
val totalAmount = coins.map { it.amount }.sum()
val totalAmount = coins.map { it.amount }.sumOrThrow()
State(deposit, totalAmount, to)
}
@ -187,5 +188,7 @@ object Cash : Contract {
}
// Small DSL extension.
fun Iterable<ContractState>.sumCashBy(owner: PublicKey) = filterIsInstance<Cash.State>().filter { it.owner == owner }.map { it.amount }.sum()
fun Iterable<ContractState>.sumCash() = filterIsInstance<Cash.State>().map { it.amount }.sum()
fun Iterable<ContractState>.sumCashBy(owner: PublicKey) = filterIsInstance<Cash.State>().filter { it.owner == owner }.map { it.amount }.sumOrThrow()
fun Iterable<ContractState>.sumCash() = filterIsInstance<Cash.State>().map { it.amount }.sumOrThrow()
fun Iterable<ContractState>.sumCashOrNull() = filterIsInstance<Cash.State>().map { it.amount }.sumOrNull()
fun Iterable<ContractState>.sumCashOrZero(currency: Currency) = filterIsInstance<Cash.State>().map { it.amount }.sumOrZero(currency)

View File

@ -61,11 +61,7 @@ object ComedyPaper : Contract {
}
is Commands.Redeem -> requireThat {
val received = try {
outStates.sumCash()
} catch (e: UnsupportedOperationException) {
throw IllegalStateException("invalid cash outputs")
}
val received = outStates.sumCashOrNull() ?: throw IllegalStateException("no cash being redeemed")
// Do we need to check the signature of the issuer here too?
"the paper must have matured" by (input.maturityDate < time)
"the received amount equals the face value" by (received == input.faceValue)

View File

@ -110,8 +110,9 @@ data class Amount(val pennies: Int, val currency: Currency) : Comparable<Amount>
}
// Note: this will throw an exception if the iterable is empty.
fun Iterable<Amount>.sum() = reduce { left, right -> left + right }
fun Iterable<Amount>.sumOrZero(currency: Currency) = if (iterator().hasNext()) sum() else Amount(0, currency)
fun Iterable<Amount>.sumOrNull() = if (!iterator().hasNext()) null else sumOrThrow()
fun Iterable<Amount>.sumOrThrow() = reduce { left, right -> left + right }
fun Iterable<Amount>.sumOrZero(currency: Currency) = if (iterator().hasNext()) sumOrThrow() else Amount(0, currency)
// TODO: Think about how positive-only vs positive-or-negative amounts can be represented in the type system.
// endregion

View File

@ -41,7 +41,7 @@ class ComedyPaperTests {
arg(DUMMY_PUBKEY_2, MINI_CORP_KEY) { ComedyPaper.Commands.Redeem() }
// No cash output, can't redeem like that!
this.rejects("invalid cash outputs")
this.rejects("no cash being redeemed")
input { CASH_3 }
output { CASH_2 }