mirror of
https://github.com/corda/corda.git
synced 2025-04-07 19:34:41 +00:00
Minor: make commands singletons when they contain no data and are purely type system markers.
This may not be really compatible with sandboxing, later on. But we can always change it back if not.
This commit is contained in:
parent
1b44081880
commit
5b4969d366
@ -51,10 +51,7 @@ object Cash : Contract {
|
||||
|
||||
sealed class Commands {
|
||||
/** A command proving ownership of some input states, the signature covers the output states. */
|
||||
class Move : Command {
|
||||
override fun equals(other: Any?) = other is Move
|
||||
override fun hashCode() = 0
|
||||
}
|
||||
object Move : Command
|
||||
|
||||
/**
|
||||
* A command stating that money has been withdrawn from the shared ledger and is now accounted for
|
||||
@ -181,7 +178,7 @@ object Cash : Contract {
|
||||
} else states
|
||||
|
||||
// Finally, generate the commands. Pretend to sign here, real signatures aren't done yet.
|
||||
val commands = keysUsed.map { VerifiedSigned(listOf(it), emptyList(), Commands.Move()) }
|
||||
val commands = keysUsed.map { VerifiedSigned(listOf(it), emptyList(), Commands.Move) }
|
||||
|
||||
return TransactionForTest(gathered.toArrayList(), outputs.toArrayList(), commands.toArrayList())
|
||||
}
|
||||
|
@ -37,8 +37,8 @@ object ComedyPaper : Contract {
|
||||
}
|
||||
|
||||
sealed class Commands : Command {
|
||||
class Move : Commands()
|
||||
class Redeem : Commands()
|
||||
object Move : Commands()
|
||||
object Redeem : Commands()
|
||||
}
|
||||
|
||||
override fun verify(tx: TransactionForVerification) {
|
||||
|
@ -27,7 +27,6 @@ inline fun <reified T : Command> List<VerifiedSigned<Command>>.requireSingleComm
|
||||
} catch (e: NoSuchElementException) {
|
||||
throw IllegalStateException("Required ${T::class.qualifiedName} command") // Better error message.
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Currencies
|
||||
|
@ -28,6 +28,7 @@ class Institution(
|
||||
override fun toString() = name
|
||||
}
|
||||
|
||||
/** Marker interface for objects that represent commands */
|
||||
interface Command
|
||||
|
||||
/** Provided as an input to a contract; converted to a [VerifiedSigned] by the platform before execution. */
|
||||
|
@ -38,7 +38,7 @@ class CashTests {
|
||||
}
|
||||
transaction {
|
||||
output { outState }
|
||||
arg(DUMMY_PUBKEY_2) { Cash.Commands.Move() }
|
||||
arg(DUMMY_PUBKEY_2) { Cash.Commands.Move }
|
||||
this `fails requirement` "the owning keys are the same as the signing keys"
|
||||
}
|
||||
transaction {
|
||||
@ -49,7 +49,7 @@ class CashTests {
|
||||
// Simple reallocation works.
|
||||
transaction {
|
||||
output { outState }
|
||||
arg(DUMMY_PUBKEY_1) { Cash.Commands.Move() }
|
||||
arg(DUMMY_PUBKEY_1) { Cash.Commands.Move }
|
||||
this.accepts()
|
||||
}
|
||||
}
|
||||
@ -70,7 +70,7 @@ class CashTests {
|
||||
fun testMergeSplit() {
|
||||
// Splitting value works.
|
||||
transaction {
|
||||
arg(DUMMY_PUBKEY_1) { Cash.Commands.Move() }
|
||||
arg(DUMMY_PUBKEY_1) { Cash.Commands.Move }
|
||||
transaction {
|
||||
input { inState }
|
||||
for (i in 1..4) output { inState.copy(amount = inState.amount / 4) }
|
||||
@ -161,7 +161,7 @@ class CashTests {
|
||||
|
||||
transaction {
|
||||
arg(MEGA_CORP_KEY) { Cash.Commands.Exit(100.DOLLARS) }
|
||||
arg(DUMMY_PUBKEY_1) { Cash.Commands.Move() }
|
||||
arg(DUMMY_PUBKEY_1) { Cash.Commands.Move }
|
||||
this `fails requirement` "the amounts balance"
|
||||
}
|
||||
|
||||
@ -170,7 +170,7 @@ class CashTests {
|
||||
this `fails requirement` "required move command"
|
||||
|
||||
transaction {
|
||||
arg(DUMMY_PUBKEY_1) { Cash.Commands.Move() }
|
||||
arg(DUMMY_PUBKEY_1) { Cash.Commands.Move }
|
||||
this.accepts()
|
||||
}
|
||||
}
|
||||
@ -183,7 +183,7 @@ class CashTests {
|
||||
output { inState.copy(amount = inState.amount - 200.DOLLARS).editInstitution(MINI_CORP) }
|
||||
output { inState.copy(amount = inState.amount - 200.DOLLARS) }
|
||||
|
||||
arg(DUMMY_PUBKEY_1) { Cash.Commands.Move() }
|
||||
arg(DUMMY_PUBKEY_1) { Cash.Commands.Move }
|
||||
|
||||
this `fails requirement` "at issuer MegaCorp the amounts balance"
|
||||
|
||||
@ -217,7 +217,7 @@ class CashTests {
|
||||
// This works.
|
||||
output { inState.copy(owner = DUMMY_PUBKEY_2) }
|
||||
output { inState.copy(owner = DUMMY_PUBKEY_2).editInstitution(MINI_CORP) }
|
||||
arg(DUMMY_PUBKEY_1) { Cash.Commands.Move() }
|
||||
arg(DUMMY_PUBKEY_1) { Cash.Commands.Move }
|
||||
this.accepts()
|
||||
}
|
||||
|
||||
@ -246,7 +246,7 @@ class CashTests {
|
||||
transaction {
|
||||
input { WALLET[0] }
|
||||
output { WALLET[0].copy(owner = THEIR_PUBKEY_1) }
|
||||
arg(OUR_PUBKEY_1) { Cash.Commands.Move() }
|
||||
arg(OUR_PUBKEY_1) { Cash.Commands.Move }
|
||||
},
|
||||
Cash.craftSpend(100.DOLLARS, THEIR_PUBKEY_1, WALLET)
|
||||
)
|
||||
@ -259,7 +259,7 @@ class CashTests {
|
||||
input { WALLET[0] }
|
||||
output { WALLET[0].copy(owner = THEIR_PUBKEY_1, amount = 10.DOLLARS) }
|
||||
output { WALLET[0].copy(owner = OUR_PUBKEY_1, amount = 90.DOLLARS) }
|
||||
arg(OUR_PUBKEY_1) { Cash.Commands.Move() }
|
||||
arg(OUR_PUBKEY_1) { Cash.Commands.Move }
|
||||
},
|
||||
Cash.craftSpend(10.DOLLARS, THEIR_PUBKEY_1, WALLET)
|
||||
)
|
||||
@ -272,7 +272,7 @@ class CashTests {
|
||||
input { WALLET[0] }
|
||||
input { WALLET[1] }
|
||||
output { WALLET[0].copy(owner = THEIR_PUBKEY_1, amount = 500.DOLLARS) }
|
||||
arg(OUR_PUBKEY_1) { Cash.Commands.Move() }
|
||||
arg(OUR_PUBKEY_1) { Cash.Commands.Move }
|
||||
},
|
||||
Cash.craftSpend(500.DOLLARS, THEIR_PUBKEY_1, WALLET)
|
||||
)
|
||||
@ -287,7 +287,7 @@ class CashTests {
|
||||
input { WALLET[2] }
|
||||
output { WALLET[0].copy(owner = THEIR_PUBKEY_1, amount = 500.DOLLARS) }
|
||||
output { WALLET[2].copy(owner = THEIR_PUBKEY_1) }
|
||||
arg(OUR_PUBKEY_1) { Cash.Commands.Move() }
|
||||
arg(OUR_PUBKEY_1) { Cash.Commands.Move }
|
||||
},
|
||||
Cash.craftSpend(580.DOLLARS, THEIR_PUBKEY_1, WALLET)
|
||||
)
|
||||
|
@ -30,22 +30,22 @@ class ComedyPaperTests {
|
||||
this.rejects()
|
||||
|
||||
transaction {
|
||||
arg(DUMMY_PUBKEY_2) { ComedyPaper.Commands.Move() }
|
||||
arg(DUMMY_PUBKEY_2) { ComedyPaper.Commands.Move }
|
||||
this `fails requirement` "is signed by the owner"
|
||||
}
|
||||
|
||||
arg(DUMMY_PUBKEY_1) { ComedyPaper.Commands.Move() }
|
||||
arg(DUMMY_PUBKEY_1) { Cash.Commands.Move() }
|
||||
arg(DUMMY_PUBKEY_1) { ComedyPaper.Commands.Move }
|
||||
arg(DUMMY_PUBKEY_1) { Cash.Commands.Move }
|
||||
this.accepts()
|
||||
}.chain("a") {
|
||||
arg(DUMMY_PUBKEY_2, MINI_CORP_KEY) { ComedyPaper.Commands.Redeem() }
|
||||
arg(DUMMY_PUBKEY_2, MINI_CORP_KEY) { ComedyPaper.Commands.Redeem }
|
||||
|
||||
// No cash output, can't redeem like that!
|
||||
this.rejects("no cash being redeemed")
|
||||
|
||||
input { CASH_3 }
|
||||
output { CASH_2 }
|
||||
arg(DUMMY_PUBKEY_1) { Cash.Commands.Move() }
|
||||
arg(DUMMY_PUBKEY_1) { Cash.Commands.Move }
|
||||
|
||||
// Time passes, but not enough. An attempt to redeem is made.
|
||||
this.rejects("must have matured")
|
||||
|
Loading…
x
Reference in New Issue
Block a user