mirror of
https://github.com/corda/corda.git
synced 2024-12-19 21:17:58 +00:00
move Cash commands out of the random inner inner inner class structure
This commit is contained in:
parent
aa625ca704
commit
93ae0d939f
@ -14,8 +14,8 @@ import net.corda.deterministic.verifier.SampleCommandData
|
||||
import net.corda.deterministic.verifier.TransactionVerificationRequest
|
||||
import net.corda.finance.POUNDS
|
||||
import net.corda.finance.`issued by`
|
||||
import net.corda.finance.contracts.asset.Cash.Commands.Issue
|
||||
import net.corda.finance.contracts.asset.Cash.Commands.Move
|
||||
import net.corda.finance.contracts.asset.Issue
|
||||
import net.corda.finance.contracts.asset.Move
|
||||
import net.corda.finance.contracts.asset.Cash.Companion.PROGRAM_ID
|
||||
import net.corda.finance.contracts.asset.Cash.State
|
||||
import net.corda.testing.core.DUMMY_NOTARY_NAME
|
||||
@ -51,13 +51,13 @@ object TransactionGenerator {
|
||||
val wtx1 = transaction {
|
||||
attachments(PROGRAM_ID)
|
||||
output(PROGRAM_ID, "c1", State(1000.POUNDS `issued by` DUMMY_CASH_ISSUER, AnonymousParty(MEGA_CORP_PUBKEY)))
|
||||
command(DUMMY_CASH_ISSUER.party.owningKey, Issue())
|
||||
command(DUMMY_CASH_ISSUER.party.owningKey, Issue("issue-123"))
|
||||
verifies()
|
||||
}
|
||||
val wtx2 = transaction {
|
||||
attachments(PROGRAM_ID)
|
||||
output(PROGRAM_ID, "c2", State(2000.POUNDS `issued by` DUMMY_CASH_ISSUER, AnonymousParty(MEGA_CORP_PUBKEY)))
|
||||
command(DUMMY_CASH_ISSUER.party.owningKey, Issue())
|
||||
command(DUMMY_CASH_ISSUER.party.owningKey, Issue("issue-123"))
|
||||
verifies()
|
||||
}
|
||||
val wtx3 = transaction {
|
||||
@ -85,13 +85,13 @@ object TransactionGenerator {
|
||||
val wtx1 = transaction {
|
||||
attachments(PROGRAM_ID)
|
||||
output(PROGRAM_ID, "c1", State(1000.POUNDS `issued by` DUMMY_CASH_ISSUER, AnonymousParty(MEGA_CORP_PUBKEY)))
|
||||
command(DUMMY_CASH_ISSUER.party.owningKey, Issue())
|
||||
command(DUMMY_CASH_ISSUER.party.owningKey, Issue("issue-123"))
|
||||
verifies()
|
||||
}
|
||||
val wtx2 = transaction {
|
||||
attachments(PROGRAM_ID)
|
||||
output(PROGRAM_ID, "c2", State(2000.POUNDS `issued by` DUMMY_CASH_ISSUER, AnonymousParty(MEGA_CORP_PUBKEY)))
|
||||
command(DUMMY_CASH_ISSUER.party.owningKey, Issue())
|
||||
command(DUMMY_CASH_ISSUER.party.owningKey, Issue("issue-123"))
|
||||
verifies()
|
||||
}
|
||||
val wtx3 = transaction {
|
||||
|
@ -3,7 +3,7 @@ package net.corda.deterministic.txverify
|
||||
import net.corda.deterministic.bytesOfResource
|
||||
import net.corda.deterministic.verifier.LocalSerializationRule
|
||||
import net.corda.deterministic.verifier.verifyTransaction
|
||||
import net.corda.finance.contracts.asset.Cash.Commands.*
|
||||
import net.corda.finance.contracts.asset.Move
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.ClassRule
|
||||
import org.junit.Test
|
||||
|
@ -24,6 +24,8 @@ import net.corda.core.transactions.WireTransaction
|
||||
import net.corda.finance.POUNDS
|
||||
import net.corda.finance.`issued by`
|
||||
import net.corda.finance.contracts.asset.Cash
|
||||
import net.corda.finance.contracts.asset.Issue
|
||||
import net.corda.finance.contracts.asset.Move
|
||||
import net.corda.testing.common.internal.testNetworkParameters
|
||||
import net.corda.testing.core.ALICE_NAME
|
||||
import net.corda.testing.core.DUMMY_NOTARY_NAME
|
||||
@ -103,14 +105,14 @@ class ConstraintsPropagationTests {
|
||||
ledgerServices.recordTransaction(transaction {
|
||||
attachment(Cash.PROGRAM_ID, SecureHash.allOnesHash)
|
||||
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, HashAttachmentConstraint(allOnesHash), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
||||
command(ALICE_PUBKEY, Issue("issue-123"))
|
||||
verifies()
|
||||
})
|
||||
transaction {
|
||||
attachment(Cash.PROGRAM_ID, SecureHash.allOnesHash)
|
||||
input("c1")
|
||||
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, HashAttachmentConstraint(allOnesHash), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||
command(ALICE_PUBKEY, Move())
|
||||
verifies()
|
||||
}
|
||||
}
|
||||
@ -145,13 +147,13 @@ class ConstraintsPropagationTests {
|
||||
unverifiedTransaction {
|
||||
attachment(Cash.PROGRAM_ID, unsignedAttachmentId)
|
||||
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, HashAttachmentConstraint(unsignedAttachmentId), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
||||
command(ALICE_PUBKEY, Issue("issue-123"))
|
||||
})
|
||||
unverifiedTransaction {
|
||||
attachment(Cash.PROGRAM_ID, signedAttachmentId)
|
||||
input("c1")
|
||||
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||
command(ALICE_PUBKEY, Move())
|
||||
verifies()
|
||||
}
|
||||
}
|
||||
@ -163,7 +165,7 @@ class ConstraintsPropagationTests {
|
||||
transaction {
|
||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash)
|
||||
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, HashAttachmentConstraint(zeroHash), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
||||
command(ALICE_PUBKEY, Issue("issue-123"))
|
||||
verifies()
|
||||
}
|
||||
assertFailsWith<IllegalArgumentException> {
|
||||
@ -171,7 +173,7 @@ class ConstraintsPropagationTests {
|
||||
attachment(Cash.PROGRAM_ID, SecureHash.allOnesHash)
|
||||
input("c1")
|
||||
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, HashAttachmentConstraint(allOnesHash), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||
command(ALICE_PUBKEY, Move())
|
||||
verifies()
|
||||
}
|
||||
}
|
||||
@ -184,28 +186,28 @@ class ConstraintsPropagationTests {
|
||||
ledgerServices.recordTransaction(transaction {
|
||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash)
|
||||
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, HashAttachmentConstraint(zeroHash), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
||||
command(ALICE_PUBKEY, Issue("issue-123"))
|
||||
verifies()
|
||||
})
|
||||
ledgerServices.recordTransaction(transaction {
|
||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash)
|
||||
input("c1")
|
||||
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, WhitelistedByZoneAttachmentConstraint, Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||
command(ALICE_PUBKEY, Move())
|
||||
failsWith("are not propagated correctly")
|
||||
})
|
||||
ledgerServices.recordTransaction(transaction {
|
||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash)
|
||||
input("c1")
|
||||
output(Cash.PROGRAM_ID, "c3", DUMMY_NOTARY, null, SignatureAttachmentConstraint(ALICE_PUBKEY), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||
command(ALICE_PUBKEY, Move())
|
||||
fails()
|
||||
})
|
||||
transaction {
|
||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash)
|
||||
input("c1")
|
||||
output(Cash.PROGRAM_ID, "c4", DUMMY_NOTARY, null, AlwaysAcceptAttachmentConstraint, Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||
command(ALICE_PUBKEY, Move())
|
||||
fails()
|
||||
}
|
||||
}
|
||||
@ -217,14 +219,14 @@ class ConstraintsPropagationTests {
|
||||
ledgerServices.recordTransaction(transaction {
|
||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash)
|
||||
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, WhitelistedByZoneAttachmentConstraint, Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
||||
command(ALICE_PUBKEY, Issue("issue-123"))
|
||||
verifies()
|
||||
})
|
||||
transaction {
|
||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash)
|
||||
input("c1")
|
||||
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, HashAttachmentConstraint(zeroHash), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||
command(ALICE_PUBKEY, Move())
|
||||
verifies()
|
||||
}
|
||||
}
|
||||
@ -237,7 +239,7 @@ class ConstraintsPropagationTests {
|
||||
ledgerServices.recordTransaction(transaction {
|
||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash)
|
||||
output(Cash.PROGRAM_ID, "w1", DUMMY_NOTARY, null, WhitelistedByZoneAttachmentConstraint, Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
||||
command(ALICE_PUBKEY, Issue("issue-123"))
|
||||
verifies()
|
||||
})
|
||||
|
||||
@ -246,7 +248,7 @@ class ConstraintsPropagationTests {
|
||||
attachment(Cash.PROGRAM_ID, SecureHash.allOnesHash, listOf(hashToSignatureConstraintsKey))
|
||||
input("w1")
|
||||
output(Cash.PROGRAM_ID, "w2", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||
command(ALICE_PUBKEY, Move())
|
||||
verifies()
|
||||
}
|
||||
}
|
||||
@ -258,7 +260,7 @@ class ConstraintsPropagationTests {
|
||||
ledgerServices.recordTransaction(transaction {
|
||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash)
|
||||
output(Cash.PROGRAM_ID, "w1", DUMMY_NOTARY, null, WhitelistedByZoneAttachmentConstraint, Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
||||
command(ALICE_PUBKEY, Issue("issue-123"))
|
||||
verifies()
|
||||
})
|
||||
// the attachment is not signed
|
||||
@ -266,7 +268,7 @@ class ConstraintsPropagationTests {
|
||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash)
|
||||
input("w1")
|
||||
output(Cash.PROGRAM_ID, "w2", DUMMY_NOTARY, null, SignatureAttachmentConstraint(ALICE_PUBKEY), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||
command(ALICE_PUBKEY, Move())
|
||||
// Note that it fails after the constraints propagation check, because the attachment is not signed.
|
||||
fails()
|
||||
}
|
||||
@ -386,14 +388,14 @@ class ConstraintsPropagationTests {
|
||||
ledgerServices.recordTransaction(transaction {
|
||||
attachment(Cash.PROGRAM_ID, SecureHash.allOnesHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "2"))
|
||||
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
||||
command(ALICE_PUBKEY, Issue("issue-123"))
|
||||
verifies()
|
||||
})
|
||||
transaction {
|
||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "1"))
|
||||
input("c1")
|
||||
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||
command(ALICE_PUBKEY, Move())
|
||||
verifies()
|
||||
}
|
||||
}
|
||||
@ -405,14 +407,14 @@ class ConstraintsPropagationTests {
|
||||
ledgerServices.recordTransaction(transaction {
|
||||
attachment(Cash.PROGRAM_ID, SecureHash.allOnesHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "3"))
|
||||
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
||||
command(ALICE_PUBKEY, Issue("issue-123"))
|
||||
verifies()
|
||||
})
|
||||
transaction {
|
||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "3"))
|
||||
input("c1")
|
||||
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||
command(ALICE_PUBKEY, Move())
|
||||
verifies()
|
||||
}
|
||||
}
|
||||
@ -424,14 +426,14 @@ class ConstraintsPropagationTests {
|
||||
ledgerServices.recordTransaction(transaction {
|
||||
attachment(Cash.PROGRAM_ID, SecureHash.allOnesHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "1"))
|
||||
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
||||
command(ALICE_PUBKEY, Issue("issue-123"))
|
||||
verifies()
|
||||
})
|
||||
transaction {
|
||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "2"))
|
||||
input("c1")
|
||||
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||
command(ALICE_PUBKEY, Move())
|
||||
verifies()
|
||||
}
|
||||
}
|
||||
@ -443,20 +445,20 @@ class ConstraintsPropagationTests {
|
||||
ledgerServices.recordTransaction(transaction {
|
||||
attachment(Cash.PROGRAM_ID, SecureHash.allOnesHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "1"))
|
||||
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
||||
command(ALICE_PUBKEY, Issue("issue-123"))
|
||||
verifies()
|
||||
})
|
||||
ledgerServices.recordTransaction(transaction {
|
||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "2"))
|
||||
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
||||
command(ALICE_PUBKEY, Issue("issue-123"))
|
||||
verifies()
|
||||
})
|
||||
transaction {
|
||||
input("c1")
|
||||
input("c2")
|
||||
output(Cash.PROGRAM_ID, "c3", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(2000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||
command(ALICE_PUBKEY, Move())
|
||||
verifies()
|
||||
}
|
||||
}
|
||||
@ -468,14 +470,14 @@ class ConstraintsPropagationTests {
|
||||
ledgerServices.recordTransaction(transaction {
|
||||
attachment(Cash.PROGRAM_ID, SecureHash.allOnesHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "2"))
|
||||
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
||||
command(ALICE_PUBKEY, Issue("issue-123"))
|
||||
verifies()
|
||||
})
|
||||
transaction {
|
||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash, listOf(hashToSignatureConstraintsKey), emptyMap())
|
||||
input("c1")
|
||||
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||
command(ALICE_PUBKEY, Move())
|
||||
verifies()
|
||||
}
|
||||
}
|
||||
@ -487,14 +489,14 @@ class ConstraintsPropagationTests {
|
||||
ledgerServices.recordTransaction(transaction {
|
||||
attachment(Cash.PROGRAM_ID, SecureHash.allOnesHash, listOf(hashToSignatureConstraintsKey), emptyMap())
|
||||
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
||||
command(ALICE_PUBKEY, Issue("issue-123"))
|
||||
verifies()
|
||||
})
|
||||
transaction {
|
||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "2"))
|
||||
input("c1")
|
||||
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||
command(ALICE_PUBKEY, Move())
|
||||
verifies()
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ import net.corda.testing.dsl.LedgerDSL
|
||||
import net.corda.testing.dsl.TestLedgerDSLInterpreter
|
||||
import net.corda.testing.dsl.TestTransactionDSLInterpreter
|
||||
import net.corda.coretesting.internal.TEST_TX_TIME
|
||||
import net.corda.finance.contracts.asset.Move
|
||||
import net.corda.testing.internal.createWireTransaction
|
||||
import net.corda.testing.node.MockServices
|
||||
import net.corda.testing.node.ledger
|
||||
@ -111,7 +112,7 @@ class PartialMerkleTreeTest(private var digestService: DigestService) {
|
||||
input("MEGA_CORP cash")
|
||||
reference("dummy cash 1")
|
||||
output(Cash.PROGRAM_ID, "MEGA_CORP cash".output<Cash.State>().copy(owner = MINI_CORP))
|
||||
command(MEGA_CORP_PUBKEY, Cash.Commands.Move())
|
||||
command(MEGA_CORP_PUBKEY, Move())
|
||||
timeWindow(TEST_TX_TIME)
|
||||
this.verifies()
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ import net.corda.testing.dsl.LedgerDSL
|
||||
import net.corda.testing.dsl.TestLedgerDSLInterpreter
|
||||
import net.corda.testing.dsl.TestTransactionDSLInterpreter
|
||||
import net.corda.coretesting.internal.TEST_TX_TIME
|
||||
import net.corda.finance.contracts.asset.Move
|
||||
import net.corda.testing.internal.createWireTransaction
|
||||
import net.corda.testing.node.MockServices
|
||||
import net.corda.testing.node.ledger
|
||||
@ -116,7 +117,7 @@ class PartialMerkleTreeWithNamedHashMultiAlgTreeTest {
|
||||
input("MEGA_CORP cash")
|
||||
reference("dummy cash 1")
|
||||
output(Cash.PROGRAM_ID, "MEGA_CORP cash".output<Cash.State>().copy(owner = MINI_CORP))
|
||||
command(MEGA_CORP_PUBKEY, Cash.Commands.Move())
|
||||
command(MEGA_CORP_PUBKEY, Move())
|
||||
timeWindow(TEST_TX_TIME)
|
||||
this.verifies()
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ import net.corda.testing.dsl.LedgerDSL
|
||||
import net.corda.testing.dsl.TestLedgerDSLInterpreter
|
||||
import net.corda.testing.dsl.TestTransactionDSLInterpreter
|
||||
import net.corda.coretesting.internal.TEST_TX_TIME
|
||||
import net.corda.finance.contracts.asset.Move
|
||||
import net.corda.testing.internal.createWireTransaction
|
||||
import net.corda.testing.node.MockServices
|
||||
import net.corda.testing.node.ledger
|
||||
@ -116,7 +117,7 @@ class PartialMerkleTreeWithNamedHashTest {
|
||||
input("MEGA_CORP cash")
|
||||
reference("dummy cash 1")
|
||||
output(Cash.PROGRAM_ID, "MEGA_CORP cash".output<Cash.State>().copy(owner = MINI_CORP))
|
||||
command(MEGA_CORP_PUBKEY, Cash.Commands.Move())
|
||||
command(MEGA_CORP_PUBKEY, Move())
|
||||
timeWindow(TEST_TX_TIME)
|
||||
this.verifies()
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ class ContractUpgradeFlowTest : WithContracts, WithFinality {
|
||||
|
||||
override fun withNewOwnerAndAmount(newAmount: Amount<Issued<Currency>>, newOwner: AbstractParty) = copy(amount = amount.copy(newAmount.quantity), owners = listOf(newOwner))
|
||||
override fun toString() = "${Emoji.bagOfCash}New Cash($amount at ${amount.token.issuer} owned by $owner)"
|
||||
override fun withNewOwner(newOwner: AbstractParty) = CommandAndState(Cash.Commands.Move(), copy(owners = listOf(newOwner)))
|
||||
override fun withNewOwner(newOwner: AbstractParty) = CommandAndState(net.corda.finance.contracts.asset.Move(), copy(owners = listOf(newOwner)))
|
||||
}
|
||||
|
||||
override fun upgrade(state: Cash.State) = State(state.amount.times(1000), listOf(state.owner))
|
||||
|
@ -3,7 +3,7 @@ package net.corda.coretests.serialization
|
||||
import net.corda.core.serialization.deserialize
|
||||
import net.corda.core.serialization.serialize
|
||||
import net.corda.finance.contracts.CommercialPaper
|
||||
import net.corda.finance.contracts.asset.Cash
|
||||
import net.corda.finance.contracts.asset.Move
|
||||
import net.corda.testing.core.SerializationEnvironmentRule
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
@ -16,7 +16,7 @@ class CommandsSerializationTests {
|
||||
|
||||
@Test(timeout=300_000)
|
||||
fun `test cash move serialization`() {
|
||||
val command = Cash.Commands.Move(CommercialPaper::class.java)
|
||||
val command = Move(CommercialPaper::class.java)
|
||||
val copiedCommand = command.serialize().deserialize()
|
||||
|
||||
assertEquals(command, copiedCommand)
|
||||
|
@ -16,6 +16,7 @@ import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.finance.DOLLARS
|
||||
import net.corda.finance.`issued by`
|
||||
import net.corda.finance.contracts.asset.Cash
|
||||
import net.corda.finance.contracts.asset.Move
|
||||
import net.corda.testing.common.internal.testNetworkParameters
|
||||
import net.corda.testing.core.DUMMY_NOTARY_NAME
|
||||
import net.corda.testing.core.SerializationEnvironmentRule
|
||||
@ -120,7 +121,7 @@ class ReferenceStateTests {
|
||||
reference("REF DATA")
|
||||
input(Cash.PROGRAM_ID, bobCash)
|
||||
output(Cash.PROGRAM_ID, "ALICE CASH", bobCash.withNewOwner(ALICE_PARTY).ownableState)
|
||||
command(BOB_PUBKEY, Cash.Commands.Move())
|
||||
command(BOB_PUBKEY, Move())
|
||||
verifies()
|
||||
}
|
||||
// Alice can use it too.
|
||||
@ -128,7 +129,7 @@ class ReferenceStateTests {
|
||||
reference("REF DATA")
|
||||
input("ALICE CASH")
|
||||
output(Cash.PROGRAM_ID, "BOB CASH 2", bobCash.withNewOwner(BOB_PARTY).ownableState)
|
||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||
command(ALICE_PUBKEY, Move())
|
||||
verifies()
|
||||
}
|
||||
// Bob can use it again.
|
||||
@ -136,7 +137,7 @@ class ReferenceStateTests {
|
||||
reference("REF DATA")
|
||||
input("BOB CASH 2")
|
||||
output(Cash.PROGRAM_ID, bobCash.withNewOwner(ALICE_PARTY).ownableState)
|
||||
command(BOB_PUBKEY, Cash.Commands.Move())
|
||||
command(BOB_PUBKEY, Move())
|
||||
verifies()
|
||||
}
|
||||
}
|
||||
@ -155,7 +156,7 @@ class ReferenceStateTests {
|
||||
input("REF DATA")
|
||||
input(Cash.PROGRAM_ID, bobCash)
|
||||
output(Cash.PROGRAM_ID, bobCash.withNewOwner(ALICE_PARTY).ownableState)
|
||||
command(BOB_PUBKEY, Cash.Commands.Move())
|
||||
command(BOB_PUBKEY, Move())
|
||||
fails()
|
||||
}
|
||||
}
|
||||
@ -175,7 +176,7 @@ class ReferenceStateTests {
|
||||
reference("REF DATA")
|
||||
input(Cash.PROGRAM_ID, bobCash)
|
||||
output(Cash.PROGRAM_ID, "ALICE CASH", bobCash.withNewOwner(ALICE_PARTY).ownableState)
|
||||
command(BOB_PUBKEY, Cash.Commands.Move())
|
||||
command(BOB_PUBKEY, Move())
|
||||
verifies()
|
||||
}
|
||||
// Update it.
|
||||
@ -190,7 +191,7 @@ class ReferenceStateTests {
|
||||
reference("REF DATA")
|
||||
input("ALICE CASH")
|
||||
output(Cash.PROGRAM_ID, bobCash.withNewOwner(BOB_PARTY).ownableState)
|
||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||
command(ALICE_PUBKEY, Move())
|
||||
verifies()
|
||||
}
|
||||
fails() // "double spend" of ExampleState!! Alice updated it in the 3rd transaction.
|
||||
|
@ -13,6 +13,8 @@ import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.finance.DOLLARS
|
||||
import net.corda.finance.`issued by`
|
||||
import net.corda.finance.contracts.asset.Cash
|
||||
import net.corda.finance.contracts.asset.Issue
|
||||
import net.corda.finance.contracts.asset.Move
|
||||
import net.corda.testing.common.internal.testNetworkParameters
|
||||
import net.corda.testing.core.DUMMY_NOTARY_NAME
|
||||
import net.corda.testing.core.SerializationEnvironmentRule
|
||||
@ -91,7 +93,7 @@ class TransactionEncumbranceTests {
|
||||
input(Cash.PROGRAM_ID, state)
|
||||
output(Cash.PROGRAM_ID, "state encumbered by 5pm time-lock", encumbrance = 1, contractState = stateWithNewOwner)
|
||||
output(TEST_TIMELOCK_ID, "5pm time-lock", 0, timeLock)
|
||||
command(MEGA_CORP.owningKey, Cash.Commands.Move())
|
||||
command(MEGA_CORP.owningKey, Move())
|
||||
verifies()
|
||||
}
|
||||
}
|
||||
@ -107,7 +109,7 @@ class TransactionEncumbranceTests {
|
||||
output(Cash.PROGRAM_ID, "state encumbered by state 2", encumbrance = 2, contractState = stateWithNewOwner)
|
||||
output(Cash.PROGRAM_ID, "state encumbered by state 3", encumbrance = 3, contractState = stateWithNewOwner)
|
||||
output(TEST_TIMELOCK_ID, "5pm time-lock", 0, timeLock)
|
||||
command(MEGA_CORP.owningKey, Cash.Commands.Move())
|
||||
command(MEGA_CORP.owningKey, Move())
|
||||
verifies()
|
||||
}
|
||||
}
|
||||
@ -125,7 +127,7 @@ class TransactionEncumbranceTests {
|
||||
output(TEST_TIMELOCK_ID, "5pm time-lock A", 0, timeLock)
|
||||
output(TEST_TIMELOCK_ID, "5pm time-lock B", 1, timeLock)
|
||||
output(TEST_TIMELOCK_ID, "5pm time-lock C", 2, timeLock)
|
||||
command(MEGA_CORP.owningKey, Cash.Commands.Move())
|
||||
command(MEGA_CORP.owningKey, Move())
|
||||
verifies()
|
||||
}
|
||||
}
|
||||
@ -139,7 +141,7 @@ class TransactionEncumbranceTests {
|
||||
output(Cash.PROGRAM_ID, "state encumbered by state 2", encumbrance = 2, contractState = stateWithNewOwner)
|
||||
output(Cash.PROGRAM_ID, "state encumbered by state 0", encumbrance = 0, contractState = stateWithNewOwner)
|
||||
output(TEST_TIMELOCK_ID, "5pm time-lock", 1, timeLock)
|
||||
command(MEGA_CORP.owningKey, Cash.Commands.Move())
|
||||
command(MEGA_CORP.owningKey, Move())
|
||||
verifies()
|
||||
}
|
||||
}
|
||||
@ -155,7 +157,7 @@ class TransactionEncumbranceTests {
|
||||
input(Cash.PROGRAM_ID, state)
|
||||
output(Cash.PROGRAM_ID, "state encumbered by 5pm time-lock", encumbrance = 1, contractState = stateWithNewOwner)
|
||||
output(TEST_TIMELOCK_ID, "5pm time-lock", timeLock)
|
||||
command(MEGA_CORP.owningKey, Cash.Commands.Move())
|
||||
command(MEGA_CORP.owningKey, Move())
|
||||
verifies()
|
||||
}
|
||||
}
|
||||
@ -172,7 +174,7 @@ class TransactionEncumbranceTests {
|
||||
output(Cash.PROGRAM_ID, "state encumbered by state 3", encumbrance = 3, contractState = stateWithNewOwner)
|
||||
output(Cash.PROGRAM_ID, "state encumbered by state 3 again", encumbrance = 3, contractState = stateWithNewOwner)
|
||||
output(TEST_TIMELOCK_ID, "5pm time-lock", timeLock)
|
||||
command(MEGA_CORP.owningKey, Cash.Commands.Move())
|
||||
command(MEGA_CORP.owningKey, Move())
|
||||
verifies()
|
||||
}
|
||||
}
|
||||
@ -189,7 +191,7 @@ class TransactionEncumbranceTests {
|
||||
output(Cash.PROGRAM_ID, "state encumbered by state 3", encumbrance = 3, contractState = stateWithNewOwner)
|
||||
output(Cash.PROGRAM_ID, "state encumbered by state 0", encumbrance = 0, contractState = stateWithNewOwner)
|
||||
output(TEST_TIMELOCK_ID, "5pm time-lock", timeLock)
|
||||
command(MEGA_CORP.owningKey, Cash.Commands.Move())
|
||||
command(MEGA_CORP.owningKey, Move())
|
||||
verifies()
|
||||
}
|
||||
}
|
||||
@ -207,7 +209,7 @@ class TransactionEncumbranceTests {
|
||||
output(Cash.PROGRAM_ID, "state encumbered by 5pm time-lock B", encumbrance = 3, contractState = stateWithNewOwner)
|
||||
output(TEST_TIMELOCK_ID, "5pm time-lock A", 0, timeLock)
|
||||
output(TEST_TIMELOCK_ID, "5pm time-lock B", timeLock)
|
||||
command(MEGA_CORP.owningKey, Cash.Commands.Move())
|
||||
command(MEGA_CORP.owningKey, Move())
|
||||
verifies()
|
||||
}
|
||||
}
|
||||
@ -228,7 +230,7 @@ class TransactionEncumbranceTests {
|
||||
input("state encumbered by 5pm time-lock")
|
||||
input("5pm time-lock")
|
||||
output(Cash.PROGRAM_ID, stateWithNewOwner)
|
||||
command(MEGA_CORP.owningKey, Cash.Commands.Move())
|
||||
command(MEGA_CORP.owningKey, Move())
|
||||
timeWindow(FIVE_PM)
|
||||
verifies()
|
||||
}
|
||||
@ -249,7 +251,7 @@ class TransactionEncumbranceTests {
|
||||
input("state encumbered by 5pm time-lock")
|
||||
input("5pm time-lock")
|
||||
output(Cash.PROGRAM_ID, state)
|
||||
command(MEGA_CORP.owningKey, Cash.Commands.Move())
|
||||
command(MEGA_CORP.owningKey, Move())
|
||||
timeWindow(FOUR_PM)
|
||||
this `fails with` "the time specified in the time-lock has passed"
|
||||
}
|
||||
@ -268,7 +270,7 @@ class TransactionEncumbranceTests {
|
||||
attachments(Cash.PROGRAM_ID)
|
||||
input("state encumbered by 5pm time-lock")
|
||||
output(Cash.PROGRAM_ID, stateWithNewOwner)
|
||||
command(MEGA_CORP.owningKey, Cash.Commands.Move())
|
||||
command(MEGA_CORP.owningKey, Move())
|
||||
timeWindow(FIVE_PM)
|
||||
this `fails with` "Missing required encumbrance 1 in INPUT"
|
||||
}
|
||||
@ -282,7 +284,7 @@ class TransactionEncumbranceTests {
|
||||
attachments(Cash.PROGRAM_ID)
|
||||
input(Cash.PROGRAM_ID, state)
|
||||
output(Cash.PROGRAM_ID, "state encumbered by itself", encumbrance = 0, contractState = stateWithNewOwner)
|
||||
command(MEGA_CORP.owningKey, Cash.Commands.Move())
|
||||
command(MEGA_CORP.owningKey, Move())
|
||||
this `fails with` "Missing required encumbrance 0 in OUTPUT"
|
||||
}
|
||||
}
|
||||
@ -296,7 +298,7 @@ class TransactionEncumbranceTests {
|
||||
input(Cash.PROGRAM_ID, state)
|
||||
output(TEST_TIMELOCK_ID, "state encumbered by state 2 which does not exist", encumbrance = 2, contractState = stateWithNewOwner)
|
||||
output(TEST_TIMELOCK_ID, timeLock)
|
||||
command(MEGA_CORP.owningKey, Cash.Commands.Move())
|
||||
command(MEGA_CORP.owningKey, Move())
|
||||
this `fails with` "Missing required encumbrance 2 in OUTPUT"
|
||||
}
|
||||
}
|
||||
@ -316,7 +318,7 @@ class TransactionEncumbranceTests {
|
||||
input("state encumbered by some other state")
|
||||
input("5pm time-lock")
|
||||
output(Cash.PROGRAM_ID, stateWithNewOwner)
|
||||
command(MEGA_CORP.owningKey, Cash.Commands.Move())
|
||||
command(MEGA_CORP.owningKey, Move())
|
||||
timeWindow(FIVE_PM)
|
||||
this `fails with` "Missing required encumbrance 1 in INPUT"
|
||||
}
|
||||
@ -330,7 +332,7 @@ class TransactionEncumbranceTests {
|
||||
TransactionBuilder()
|
||||
.addOutputState(stateWithNewOwner, Cash.PROGRAM_ID, DUMMY_NOTARY, 1, AutomaticPlaceholderConstraint)
|
||||
.addOutputState(stateWithNewOwner, Cash.PROGRAM_ID, DUMMY_NOTARY2, 0, AutomaticPlaceholderConstraint)
|
||||
.addCommand(Cash.Commands.Issue(), MEGA_CORP.owningKey)
|
||||
.addCommand(Issue("issue-123"), MEGA_CORP.owningKey)
|
||||
.toLedgerTransaction(ledgerServices)
|
||||
.verify()
|
||||
}
|
||||
@ -345,7 +347,7 @@ class TransactionEncumbranceTests {
|
||||
.addOutputState(stateWithNewOwner, Cash.PROGRAM_ID, DUMMY_NOTARY, 3, AutomaticPlaceholderConstraint)
|
||||
.addOutputState(stateWithNewOwner, Cash.PROGRAM_ID, DUMMY_NOTARY2, 0, AutomaticPlaceholderConstraint)
|
||||
.addOutputState(stateWithNewOwner, Cash.PROGRAM_ID, DUMMY_NOTARY, 2, AutomaticPlaceholderConstraint)
|
||||
.addCommand(Cash.Commands.Issue(), MEGA_CORP.owningKey)
|
||||
.addCommand(Issue("issue-123"), MEGA_CORP.owningKey)
|
||||
.toLedgerTransaction(ledgerServices)
|
||||
.verify()
|
||||
}
|
||||
@ -362,7 +364,7 @@ class TransactionEncumbranceTests {
|
||||
.addOutputState(stateWithNewOwner, Cash.PROGRAM_ID, DUMMY_NOTARY, 0, AutomaticPlaceholderConstraint)
|
||||
.addOutputState(stateWithNewOwner, Cash.PROGRAM_ID, DUMMY_NOTARY, 3, AutomaticPlaceholderConstraint)
|
||||
.addOutputState(stateWithNewOwner, Cash.PROGRAM_ID, DUMMY_NOTARY2, 2, AutomaticPlaceholderConstraint)
|
||||
.addCommand(Cash.Commands.Issue(), MEGA_CORP.owningKey)
|
||||
.addCommand(Issue("issue-123"), MEGA_CORP.owningKey)
|
||||
.toLedgerTransaction(ledgerServices)
|
||||
.verify()
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.corda.core.crypto
|
||||
|
||||
import net.corda.core.KeepForDJVM
|
||||
import net.corda.core.serialization.ConstructorForDeserialization
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
|
||||
/**
|
||||
@ -14,4 +15,4 @@ import net.corda.core.serialization.CordaSerializable
|
||||
*/
|
||||
@CordaSerializable
|
||||
@KeepForDJVM
|
||||
data class SignableData(val txId: SecureHash, val signatureMetadata: SignatureMetadata)
|
||||
data class SignableData @ConstructorForDeserialization constructor(val txId: SecureHash, val signatureMetadata: SignatureMetadata)
|
||||
|
@ -12,6 +12,7 @@ import net.corda.core.internal.Emoji
|
||||
import net.corda.core.schemas.MappedSchema
|
||||
import net.corda.core.schemas.PersistentState
|
||||
import net.corda.core.schemas.QueryableState
|
||||
import net.corda.core.serialization.ConstructorForDeserialization
|
||||
import net.corda.core.transactions.LedgerTransaction
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.finance.contracts.utils.sumCash
|
||||
@ -39,16 +40,15 @@ import java.util.*
|
||||
* At the same time, other contracts that just want money and don't care much who is currently holding it in their
|
||||
* vaults can ignore the issuer/depositRefs and just examine the amount fields.
|
||||
*/
|
||||
class Cash : OnLedgerAsset<Currency, Cash.Commands, Cash.State>() {
|
||||
override fun extractCommands(commands: Collection<CommandWithParties<CommandData>>): List<CommandWithParties<Cash.Commands>>
|
||||
class Cash : OnLedgerAsset<Currency, CommandData, Cash.State>() {
|
||||
override fun extractCommands(commands: Collection<CommandWithParties<CommandData>>): List<CommandWithParties<CommandData>>
|
||||
= commands.select()
|
||||
|
||||
// DOCSTART 1
|
||||
/** A state representing a cash claim against some party. */
|
||||
@BelongsToContract(Cash::class)
|
||||
data class State(
|
||||
data class State @ConstructorForDeserialization constructor(
|
||||
override val amount: Amount<Issued<Currency>>,
|
||||
|
||||
/** There must be a MoveCommand signed by this key to claim the amount. */
|
||||
override val owner: AbstractParty
|
||||
) : FungibleAsset<Currency>, QueryableState {
|
||||
@ -63,7 +63,7 @@ class Cash : OnLedgerAsset<Currency, Cash.Commands, Cash.State>() {
|
||||
|
||||
override fun toString() = "${Emoji.bagOfCash}Cash($amount at ${amount.token.issuer} owned by $owner)"
|
||||
|
||||
override fun withNewOwner(newOwner: AbstractParty) = CommandAndState(Commands.Move(), copy(owner = newOwner))
|
||||
override fun withNewOwner(newOwner: AbstractParty) = CommandAndState(Move(), copy(owner = newOwner))
|
||||
infix fun ownedBy(owner: AbstractParty) = copy(owner = owner)
|
||||
infix fun issuedBy(party: AbstractParty) = copy(amount = Amount(amount.quantity, amount.token.copy(issuer = amount.token.issuer.copy(party = party))))
|
||||
infix fun issuedBy(deposit: PartyAndReference) = copy(amount = Amount(amount.quantity, amount.token.copy(issuer = deposit)))
|
||||
@ -90,29 +90,6 @@ class Cash : OnLedgerAsset<Currency, Cash.Commands, Cash.State>() {
|
||||
}
|
||||
// DOCEND 1
|
||||
|
||||
// Just for grouping
|
||||
interface Commands : CommandData {
|
||||
/**
|
||||
* A command stating that money has been moved, optionally to fulfil another contract.
|
||||
*
|
||||
* @param contract the contract this move is for the attention of. Only that contract's verify function
|
||||
* should take the moved states into account when considering whether it is valid. Typically this will be
|
||||
* null.
|
||||
*/
|
||||
data class Move(override val contract: Class<out Contract>? = null) : MoveCommand
|
||||
|
||||
/**
|
||||
* Allows new cash states to be issued into existence.
|
||||
*/
|
||||
class Issue : TypeOnlyCommandData()
|
||||
|
||||
/**
|
||||
* A command stating that money has been withdrawn from the shared ledger and is now accounted for
|
||||
* in some other way.
|
||||
*/
|
||||
data class Exit(val amount: Amount<Issued<Currency>>) : CommandData
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts together an issuance transaction from the given template, that starts out being owned by the given pubkey.
|
||||
*/
|
||||
@ -123,13 +100,13 @@ class Cash : OnLedgerAsset<Currency, Cash.Commands, Cash.State>() {
|
||||
* Puts together an issuance transaction for the specified amount that starts out being owned by the given pubkey.
|
||||
*/
|
||||
fun generateIssue(tx: TransactionBuilder, amount: Amount<Issued<Currency>>, owner: AbstractParty, notary: Party)
|
||||
= generateIssue(tx, TransactionState(State(amount, owner), PROGRAM_ID, notary), Commands.Issue())
|
||||
= generateIssue(tx, TransactionState(State(amount, owner), PROGRAM_ID, notary), Issue("issue-123"))
|
||||
|
||||
override fun deriveState(txState: TransactionState<State>, amount: Amount<Issued<Currency>>, owner: AbstractParty)
|
||||
= txState.copy(data = txState.data.copy(amount = amount, owner = owner))
|
||||
|
||||
override fun generateExitCommand(amount: Amount<Issued<Currency>>) = Commands.Exit(amount)
|
||||
override fun generateMoveCommand() = Commands.Move()
|
||||
override fun generateExitCommand(amount: Amount<Issued<Currency>>) = Exit(amount)
|
||||
override fun generateMoveCommand() = Move()
|
||||
|
||||
override fun verify(tx: LedgerTransaction) {
|
||||
// Each group is a set of input/output states with distinct (reference, currency) attributes. These types
|
||||
@ -145,7 +122,7 @@ class Cash : OnLedgerAsset<Currency, Cash.Commands, Cash.State>() {
|
||||
"there are no zero sized outputs" using (outputs.none { it.amount.quantity == 0L })
|
||||
}
|
||||
|
||||
val issueCommand = tx.commands.select<Commands.Issue>().firstOrNull()
|
||||
val issueCommand = tx.commands.select<Issue>().firstOrNull()
|
||||
if (issueCommand != null) {
|
||||
verifyIssueCommand(inputs, outputs, tx, issueCommand, currency, issuer)
|
||||
} else {
|
||||
@ -155,7 +132,7 @@ class Cash : OnLedgerAsset<Currency, Cash.Commands, Cash.State>() {
|
||||
// If we want to remove cash from the ledger, that must be signed for by the issuer.
|
||||
// A mis-signed or duplicated exit command will just be ignored here and result in the exit amount being zero.
|
||||
val exitKeys: Set<PublicKey> = inputs.flatMap { it.exitKeys }.toSet()
|
||||
val exitCommand = tx.commands.select<Commands.Exit>(parties = null, signers = exitKeys).singleOrNull { it.value.amount.token == key }
|
||||
val exitCommand = tx.commands.select<Exit>(parties = null, signers = exitKeys).singleOrNull { it.value.amount.token == key }
|
||||
val amountExitingLedger = exitCommand?.value?.amount ?: Amount(0, Issued(issuer, currency))
|
||||
|
||||
requireThat {
|
||||
@ -164,7 +141,7 @@ class Cash : OnLedgerAsset<Currency, Cash.Commands, Cash.State>() {
|
||||
(inputAmount == outputAmount + amountExitingLedger)
|
||||
}
|
||||
|
||||
verifyFlattenedMoveCommand<Commands.Move>(inputs, tx.commands)
|
||||
verifyFlattenedMoveCommand<Move>(inputs, tx.commands)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -172,7 +149,7 @@ class Cash : OnLedgerAsset<Currency, Cash.Commands, Cash.State>() {
|
||||
private fun verifyIssueCommand(inputs: List<State>,
|
||||
outputs: List<State>,
|
||||
tx: LedgerTransaction,
|
||||
issueCommand: CommandWithParties<Commands.Issue>,
|
||||
issueCommand: CommandWithParties<Issue>,
|
||||
currency: Currency,
|
||||
issuer: PartyAndReference) {
|
||||
// If we have an issue command, perform special processing: the group is allowed to have no inputs,
|
||||
@ -187,7 +164,7 @@ class Cash : OnLedgerAsset<Currency, Cash.Commands, Cash.State>() {
|
||||
// The grouping ensures that all outputs have the same deposit reference and currency.
|
||||
val inputAmount = inputs.sumCashOrZero(Issued(issuer, currency))
|
||||
val outputAmount = outputs.sumCash()
|
||||
val cashCommands = tx.commands.select<Commands.Issue>()
|
||||
val cashCommands = tx.commands.select<Issue>()
|
||||
requireThat {
|
||||
// TODO: This doesn't work with the trader demo, so use the underlying key instead
|
||||
// "output states are issued by a command signer" by (issuer.party in issueCommand.signingParties)
|
||||
|
@ -0,0 +1,12 @@
|
||||
package net.corda.finance.contracts.asset
|
||||
|
||||
import net.corda.core.contracts.Amount
|
||||
import net.corda.core.contracts.CommandData
|
||||
import net.corda.core.contracts.Issued
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* A command stating that money has been withdrawn from the shared ledger and is now accounted for
|
||||
* in some other way.
|
||||
*/
|
||||
data class Exit(val amount: Amount<Issued<Currency>>) : CommandData
|
@ -0,0 +1,8 @@
|
||||
package net.corda.finance.contracts.asset
|
||||
|
||||
import net.corda.core.contracts.CommandData
|
||||
|
||||
/**
|
||||
* Allows new cash states to be issued into existence.
|
||||
*/
|
||||
data class Issue(val issueId: String) : CommandData
|
@ -0,0 +1,14 @@
|
||||
package net.corda.finance.contracts.asset
|
||||
|
||||
import net.corda.core.contracts.Contract
|
||||
import net.corda.core.contracts.MoveCommand
|
||||
|
||||
/**
|
||||
* A command stating that money has been moved, optionally to fulfil another contract.
|
||||
*
|
||||
* @param contract the contract this move is for the attention of. Only that contract's verify function
|
||||
* should take the moved states into account when considering whether it is valid. Typically this will be
|
||||
* null.
|
||||
*/
|
||||
|
||||
data class Move(override val contract: Class<out Contract>? = null) : MoveCommand
|
@ -45,7 +45,7 @@ public class CashTestsJava {
|
||||
|
||||
tx.tweak(tw -> {
|
||||
tw.output(Cash.PROGRAM_ID, new Cash.State(issuedBy(DOLLARS(2000), defaultIssuer), new AnonymousParty(MINI_CORP.getPublicKey())));
|
||||
tw.command(MEGA_CORP.getPublicKey(), new Cash.Commands.Move());
|
||||
tw.command(MEGA_CORP.getPublicKey(), new Move());
|
||||
return tw.failsWith("the amounts balance");
|
||||
});
|
||||
|
||||
@ -57,7 +57,7 @@ public class CashTestsJava {
|
||||
});
|
||||
tx.tweak(tw -> {
|
||||
tw.output(Cash.PROGRAM_ID, outState);
|
||||
tw.command(MINI_CORP.getPublicKey(), new Cash.Commands.Move());
|
||||
tw.command(MINI_CORP.getPublicKey(), new Move());
|
||||
return tw.failsWith("the owning keys are a subset of the signing keys");
|
||||
});
|
||||
tx.tweak(tw -> {
|
||||
@ -65,14 +65,14 @@ public class CashTestsJava {
|
||||
// issuedBy() can't be directly imported because it conflicts with other identically named functions
|
||||
// with different overloads (for some reason).
|
||||
tw.output(Cash.PROGRAM_ID, outState.issuedBy(MINI_CORP.getParty()));
|
||||
tw.command(MEGA_CORP.getPublicKey(), new Cash.Commands.Move());
|
||||
tw.command(MEGA_CORP.getPublicKey(), new Move());
|
||||
return tw.failsWith("at least one cash input");
|
||||
});
|
||||
|
||||
// Simple reallocation works.
|
||||
return tx.tweak(tw -> {
|
||||
tw.output(Cash.PROGRAM_ID, outState);
|
||||
tw.command(MEGA_CORP.getPublicKey(), new Cash.Commands.Move());
|
||||
tw.command(MEGA_CORP.getPublicKey(), new Move());
|
||||
return tw.verifies();
|
||||
});
|
||||
});
|
||||
|
@ -23,6 +23,7 @@ import net.corda.testing.dsl.EnforceVerifyOrFail
|
||||
import net.corda.testing.dsl.TransactionDSL
|
||||
import net.corda.testing.dsl.TransactionDSLInterpreter
|
||||
import net.corda.coretesting.internal.TEST_TX_TIME
|
||||
import net.corda.finance.contracts.asset.Move
|
||||
import net.corda.testing.internal.vault.VaultFiller
|
||||
import net.corda.testing.node.MockServices
|
||||
import net.corda.testing.node.MockServices.Companion.makeTestDatabaseAndMockServices
|
||||
@ -144,7 +145,7 @@ class CommercialPaperTestsGeneric {
|
||||
input("alice's $900")
|
||||
output(Cash.PROGRAM_ID, "borrowed $900", 900.DOLLARS.CASH issuedBy megaCorpRef ownedBy megaCorp.party)
|
||||
output(thisTest.getContract(), "alice's paper", "paper".output<ICommercialPaperState>().withOwner(alice.party))
|
||||
command(alice.publicKey, Cash.Commands.Move())
|
||||
command(alice.publicKey, Move())
|
||||
command(megaCorp.publicKey, thisTest.getMoveCommand())
|
||||
this.verifies()
|
||||
}
|
||||
@ -160,7 +161,7 @@ class CommercialPaperTestsGeneric {
|
||||
output(Cash.PROGRAM_ID, "Alice's profit", aliceGetsBack.STATE ownedBy alice.party)
|
||||
output(Cash.PROGRAM_ID, "Change", (someProfits - aliceGetsBack).STATE ownedBy megaCorp.party)
|
||||
}
|
||||
command(megaCorp.publicKey, Cash.Commands.Move())
|
||||
command(megaCorp.publicKey, Move())
|
||||
command(alice.publicKey, thisTest.getRedeemCommand(dummyNotary.party))
|
||||
tweak {
|
||||
outputs(700.DOLLARS `issued by` megaCorpRef)
|
||||
|
@ -135,7 +135,7 @@ class CashTests {
|
||||
input(Cash.PROGRAM_ID, inState)
|
||||
tweak {
|
||||
output(Cash.PROGRAM_ID, outState.copy(amount = 2000.DOLLARS `issued by` defaultIssuer))
|
||||
command(alice.publicKey, Cash.Commands.Move())
|
||||
command(alice.publicKey, Move())
|
||||
this `fails with` "the amounts balance"
|
||||
}
|
||||
tweak {
|
||||
@ -146,19 +146,19 @@ class CashTests {
|
||||
}
|
||||
tweak {
|
||||
output(Cash.PROGRAM_ID, outState)
|
||||
command(bob.publicKey, Cash.Commands.Move())
|
||||
command(bob.publicKey, Move())
|
||||
this `fails with` "the owning keys are a subset of the signing keys"
|
||||
}
|
||||
tweak {
|
||||
output(Cash.PROGRAM_ID, outState)
|
||||
output(Cash.PROGRAM_ID, outState issuedBy miniCorp.party)
|
||||
command(alice.publicKey, Cash.Commands.Move())
|
||||
command(alice.publicKey, Move())
|
||||
this `fails with` "at least one cash input"
|
||||
}
|
||||
// Simple reallocation works.
|
||||
tweak {
|
||||
output(Cash.PROGRAM_ID, outState)
|
||||
command(alice.publicKey, Cash.Commands.Move())
|
||||
command(alice.publicKey, Move())
|
||||
this.verifies()
|
||||
}
|
||||
}
|
||||
@ -171,10 +171,10 @@ class CashTests {
|
||||
input(Cash.PROGRAM_ID, inState)
|
||||
input(Cash.PROGRAM_ID, inState.copy(owner = bob.party))
|
||||
output(Cash.PROGRAM_ID, outState)
|
||||
command(alice.publicKey, Cash.Commands.Move())
|
||||
command(alice.publicKey, Move())
|
||||
tweak {
|
||||
output(Cash.PROGRAM_ID, outState)
|
||||
command(bob.publicKey, Cash.Commands.Move())
|
||||
command(bob.publicKey, Move())
|
||||
this.verifies()
|
||||
}
|
||||
}
|
||||
@ -192,7 +192,7 @@ class CashTests {
|
||||
attachment(Cash.PROGRAM_ID)
|
||||
input(Cash.PROGRAM_ID, DummyState)
|
||||
output(Cash.PROGRAM_ID, outState)
|
||||
command(miniCorp.publicKey, Cash.Commands.Move())
|
||||
command(miniCorp.publicKey, Move())
|
||||
this `fails with` "there is at least one cash input for this group"
|
||||
}
|
||||
}
|
||||
@ -204,7 +204,7 @@ class CashTests {
|
||||
transaction {
|
||||
attachment(Cash.PROGRAM_ID)
|
||||
output(Cash.PROGRAM_ID, outState)
|
||||
command(alice.publicKey, Cash.Commands.Issue())
|
||||
command(alice.publicKey, Issue("issue-123"))
|
||||
this `fails with` "output states are issued by a command signer"
|
||||
}
|
||||
transaction {
|
||||
@ -213,7 +213,7 @@ class CashTests {
|
||||
Cash.State(
|
||||
amount = 1000.DOLLARS `issued by` miniCorp.ref(12, 34),
|
||||
owner = AnonymousParty(alice.publicKey)))
|
||||
command(miniCorp.publicKey, Cash.Commands.Issue())
|
||||
command(miniCorp.publicKey, Issue("issue-123"))
|
||||
this.verifies()
|
||||
}
|
||||
}
|
||||
@ -229,7 +229,7 @@ class CashTests {
|
||||
assertEquals(100.DOLLARS `issued by` miniCorp.ref(12, 34), s.amount)
|
||||
assertEquals(miniCorp.party as AbstractParty, s.amount.token.issuer.party)
|
||||
assertEquals(AnonymousParty(alice.publicKey), s.owner)
|
||||
assertTrue(tx.commands[0].value is Cash.Commands.Issue)
|
||||
assertTrue(tx.commands[0].value is Issue)
|
||||
assertEquals(miniCorp.publicKey, tx.commands[0].signers[0])
|
||||
}
|
||||
|
||||
@ -253,13 +253,13 @@ class CashTests {
|
||||
output(Cash.PROGRAM_ID, inState.copy(amount = inState.amount * 2))
|
||||
// Move fails: not allowed to summon money.
|
||||
tweak {
|
||||
command(alice.publicKey, Cash.Commands.Move())
|
||||
command(alice.publicKey, Move())
|
||||
this `fails with` "the amounts balance"
|
||||
}
|
||||
|
||||
// Issue works.
|
||||
tweak {
|
||||
command(megaCorp.publicKey, Cash.Commands.Issue())
|
||||
command(megaCorp.publicKey, Issue("issue-123"))
|
||||
this.verifies()
|
||||
}
|
||||
}
|
||||
@ -269,7 +269,7 @@ class CashTests {
|
||||
attachment(Cash.PROGRAM_ID)
|
||||
input(Cash.PROGRAM_ID, inState)
|
||||
output(Cash.PROGRAM_ID, inState.copy(amount = inState.amount.splitEvenly(2).first()))
|
||||
command(megaCorp.publicKey, Cash.Commands.Issue())
|
||||
command(megaCorp.publicKey, Issue("issue-123"))
|
||||
this `fails with` "output values sum to more than the inputs"
|
||||
}
|
||||
|
||||
@ -278,7 +278,7 @@ class CashTests {
|
||||
attachment(Cash.PROGRAM_ID)
|
||||
input(Cash.PROGRAM_ID, inState)
|
||||
output(Cash.PROGRAM_ID, inState)
|
||||
command(megaCorp.publicKey, Cash.Commands.Issue())
|
||||
command(megaCorp.publicKey, Issue("issue-123"))
|
||||
this `fails with` "output values sum to more than the inputs"
|
||||
}
|
||||
|
||||
@ -287,9 +287,9 @@ class CashTests {
|
||||
attachment(Cash.PROGRAM_ID)
|
||||
input(Cash.PROGRAM_ID, inState)
|
||||
output(Cash.PROGRAM_ID, inState.copy(amount = inState.amount * 2))
|
||||
command(megaCorp.publicKey, Cash.Commands.Issue())
|
||||
command(megaCorp.publicKey, Issue("issue-123"))
|
||||
tweak {
|
||||
command(megaCorp.publicKey, Cash.Commands.Issue())
|
||||
command(megaCorp.publicKey, Issue("issue-123"))
|
||||
this `fails with` "there is only a single issue command"
|
||||
}
|
||||
this.verifies()
|
||||
@ -319,7 +319,7 @@ class CashTests {
|
||||
// Splitting value works.
|
||||
transaction {
|
||||
attachment(Cash.PROGRAM_ID)
|
||||
command(alice.publicKey, Cash.Commands.Move())
|
||||
command(alice.publicKey, Move())
|
||||
tweak {
|
||||
input(Cash.PROGRAM_ID, inState)
|
||||
val splits4 = inState.amount.splitEvenly(4)
|
||||
@ -350,7 +350,7 @@ class CashTests {
|
||||
attachment(Cash.PROGRAM_ID)
|
||||
input(Cash.PROGRAM_ID, inState)
|
||||
input(Cash.PROGRAM_ID, inState.copy(amount = 0.DOLLARS `issued by` defaultIssuer))
|
||||
command(alice.publicKey, Cash.Commands.Move())
|
||||
command(alice.publicKey, Move())
|
||||
this `fails with` "zero sized inputs"
|
||||
}
|
||||
transaction {
|
||||
@ -358,7 +358,7 @@ class CashTests {
|
||||
input(Cash.PROGRAM_ID, inState)
|
||||
output(Cash.PROGRAM_ID, inState)
|
||||
output(Cash.PROGRAM_ID, inState.copy(amount = 0.DOLLARS `issued by` defaultIssuer))
|
||||
command(alice.publicKey, Cash.Commands.Move())
|
||||
command(alice.publicKey, Move())
|
||||
this `fails with` "zero sized outputs"
|
||||
}
|
||||
}
|
||||
@ -370,7 +370,7 @@ class CashTests {
|
||||
attachment(Cash.PROGRAM_ID)
|
||||
input(Cash.PROGRAM_ID, inState)
|
||||
output(Cash.PROGRAM_ID, outState issuedBy miniCorp.party)
|
||||
command(alice.publicKey, Cash.Commands.Move())
|
||||
command(alice.publicKey, Move())
|
||||
this `fails with` "the amounts balance"
|
||||
}
|
||||
// Can't change deposit reference when splitting.
|
||||
@ -379,7 +379,7 @@ class CashTests {
|
||||
val splits2 = inState.amount.splitEvenly(2)
|
||||
input(Cash.PROGRAM_ID, inState)
|
||||
for (i in 0..1) output(Cash.PROGRAM_ID, outState.copy(amount = splits2[i]).editDepositRef(i.toByte()))
|
||||
command(alice.publicKey, Cash.Commands.Move())
|
||||
command(alice.publicKey, Move())
|
||||
this `fails with` "the amounts balance"
|
||||
}
|
||||
// Can't mix currencies.
|
||||
@ -388,7 +388,7 @@ class CashTests {
|
||||
input(Cash.PROGRAM_ID, inState)
|
||||
output(Cash.PROGRAM_ID, outState.copy(amount = 800.DOLLARS `issued by` defaultIssuer))
|
||||
output(Cash.PROGRAM_ID, outState.copy(amount = 200.POUNDS `issued by` defaultIssuer))
|
||||
command(alice.publicKey, Cash.Commands.Move())
|
||||
command(alice.publicKey, Move())
|
||||
this `fails with` "the amounts balance"
|
||||
}
|
||||
transaction {
|
||||
@ -399,7 +399,7 @@ class CashTests {
|
||||
amount = 150.POUNDS `issued by` defaultIssuer,
|
||||
owner = AnonymousParty(bob.publicKey)))
|
||||
output(Cash.PROGRAM_ID, outState.copy(amount = 1150.DOLLARS `issued by` defaultIssuer))
|
||||
command(alice.publicKey, Cash.Commands.Move())
|
||||
command(alice.publicKey, Move())
|
||||
this `fails with` "the amounts balance"
|
||||
}
|
||||
// Can't have superfluous input states from different issuers.
|
||||
@ -408,7 +408,7 @@ class CashTests {
|
||||
input(Cash.PROGRAM_ID, inState)
|
||||
input(Cash.PROGRAM_ID, inState issuedBy miniCorp.party)
|
||||
output(Cash.PROGRAM_ID, outState)
|
||||
command(alice.publicKey, Cash.Commands.Move())
|
||||
command(alice.publicKey, Move())
|
||||
this `fails with` "the amounts balance"
|
||||
}
|
||||
// Can't combine two different deposits at the same issuer.
|
||||
@ -417,7 +417,7 @@ class CashTests {
|
||||
input(Cash.PROGRAM_ID, inState)
|
||||
input(Cash.PROGRAM_ID, inState.editDepositRef(3))
|
||||
output(Cash.PROGRAM_ID, outState.copy(amount = inState.amount * 2).editDepositRef(3))
|
||||
command(alice.publicKey, Cash.Commands.Move())
|
||||
command(alice.publicKey, Move())
|
||||
this `fails with` "for reference [01]"
|
||||
}
|
||||
}
|
||||
@ -430,17 +430,17 @@ class CashTests {
|
||||
input(Cash.PROGRAM_ID, issuerInState)
|
||||
output(Cash.PROGRAM_ID, issuerInState.copy(amount = issuerInState.amount - (200.DOLLARS `issued by` defaultIssuer)))
|
||||
tweak {
|
||||
command(megaCorp.publicKey, Cash.Commands.Exit(100.DOLLARS `issued by` defaultIssuer))
|
||||
command(megaCorp.publicKey, Cash.Commands.Move())
|
||||
command(megaCorp.publicKey, Exit(100.DOLLARS `issued by` defaultIssuer))
|
||||
command(megaCorp.publicKey, Move())
|
||||
this `fails with` "the amounts balance"
|
||||
}
|
||||
|
||||
tweak {
|
||||
command(megaCorp.publicKey, Cash.Commands.Exit(200.DOLLARS `issued by` defaultIssuer))
|
||||
command(megaCorp.publicKey, Exit(200.DOLLARS `issued by` defaultIssuer))
|
||||
this `fails with` "required net.corda.finance.contracts.asset.Cash.Commands.Move command"
|
||||
|
||||
tweak {
|
||||
command(megaCorp.publicKey, Cash.Commands.Move())
|
||||
command(megaCorp.publicKey, Move())
|
||||
this.verifies()
|
||||
}
|
||||
}
|
||||
@ -456,11 +456,11 @@ class CashTests {
|
||||
input(Cash.PROGRAM_ID, issuerInState.copy(owner = miniCorp.party) issuedBy miniCorp.party)
|
||||
output(Cash.PROGRAM_ID, issuerInState.copy(amount = issuerInState.amount - (200.DOLLARS `issued by` defaultIssuer)) issuedBy miniCorp.party)
|
||||
output(Cash.PROGRAM_ID, issuerInState.copy(owner = miniCorp.party, amount = issuerInState.amount - (200.DOLLARS `issued by` defaultIssuer)))
|
||||
command(listOf(megaCorp.publicKey, miniCorp.publicKey), Cash.Commands.Move())
|
||||
command(listOf(megaCorp.publicKey, miniCorp.publicKey), Move())
|
||||
this `fails with` "the amounts balance"
|
||||
command(megaCorp.publicKey, Cash.Commands.Exit(200.DOLLARS `issued by` defaultIssuer))
|
||||
command(megaCorp.publicKey, Exit(200.DOLLARS `issued by` defaultIssuer))
|
||||
this `fails with` "the amounts balance"
|
||||
command(miniCorp.publicKey, Cash.Commands.Exit(200.DOLLARS `issued by` miniCorp.ref(1)))
|
||||
command(miniCorp.publicKey, Exit(200.DOLLARS `issued by` miniCorp.ref(1)))
|
||||
this.verifies()
|
||||
}
|
||||
}
|
||||
@ -472,8 +472,8 @@ class CashTests {
|
||||
attachment(Cash.PROGRAM_ID)
|
||||
input(Cash.PROGRAM_ID, inState)
|
||||
output(Cash.PROGRAM_ID, outState.copy(amount = inState.amount - (200.DOLLARS `issued by` defaultIssuer)))
|
||||
command(megaCorp.publicKey, Cash.Commands.Exit(200.DOLLARS `issued by` defaultIssuer))
|
||||
command(alice.publicKey, Cash.Commands.Move())
|
||||
command(megaCorp.publicKey, Exit(200.DOLLARS `issued by` defaultIssuer))
|
||||
command(alice.publicKey, Move())
|
||||
this `fails with` "the amounts balance"
|
||||
}
|
||||
}
|
||||
@ -485,7 +485,7 @@ class CashTests {
|
||||
// Gather 2000 dollars from two different issuers.
|
||||
input(Cash.PROGRAM_ID, inState)
|
||||
input(Cash.PROGRAM_ID, inState issuedBy miniCorp.party)
|
||||
command(alice.publicKey, Cash.Commands.Move())
|
||||
command(alice.publicKey, Move())
|
||||
// Can't merge them together.
|
||||
tweak {
|
||||
output(Cash.PROGRAM_ID, inState.copy(owner = AnonymousParty(bob.publicKey), amount = 2000.DOLLARS `issued by` defaultIssuer))
|
||||
@ -515,7 +515,7 @@ class CashTests {
|
||||
input(Cash.PROGRAM_ID, pounds)
|
||||
output(Cash.PROGRAM_ID, inState ownedBy AnonymousParty(bob.publicKey))
|
||||
output(Cash.PROGRAM_ID, pounds ownedBy AnonymousParty(alice.publicKey))
|
||||
command(listOf(alice.publicKey, bob.publicKey), Cash.Commands.Move())
|
||||
command(listOf(alice.publicKey, bob.publicKey), Move())
|
||||
this.verifies()
|
||||
}
|
||||
}
|
||||
@ -558,8 +558,8 @@ class CashTests {
|
||||
assertEquals(cashStates[0].ref, wtx.inputs[0])
|
||||
assertEquals(0, wtx.outputs.size)
|
||||
|
||||
val expectedMove = Cash.Commands.Move()
|
||||
val expectedExit = Cash.Commands.Exit(Amount(10000, Issued(megaCorp.ref(1), USD)))
|
||||
val expectedMove = Move()
|
||||
val expectedExit = Exit(Amount(10000, Issued(megaCorp.ref(1), USD)))
|
||||
|
||||
assertEquals(listOf(expectedMove, expectedExit), wtx.commands.map { it.value })
|
||||
}
|
||||
@ -634,7 +634,7 @@ class CashTests {
|
||||
val vaultState = vaultStatesUnconsumed.elementAt(0)
|
||||
assertEquals(vaultState.ref, wtx.inputs[0])
|
||||
assertEquals(vaultState.state.data.copy(owner = miniCorpAnonymised), wtx.getOutput(0))
|
||||
assertEquals(ourIdentity.owningKey, wtx.commands.single { it.value is Cash.Commands.Move }.signers[0])
|
||||
assertEquals(ourIdentity.owningKey, wtx.commands.single { it.value is Move }.signers[0])
|
||||
}
|
||||
}
|
||||
|
||||
@ -669,7 +669,7 @@ class CashTests {
|
||||
assertEquals(vaultState.ref, wtx.inputs[0])
|
||||
assertEquals(vaultState.state.data.copy(owner = miniCorpAnonymised, amount = 10.DOLLARS `issued by` defaultIssuer), wtx.outputs[0].data)
|
||||
assertEquals(vaultState.state.data.copy(amount = changeAmount, owner = changeOwner), wtx.outputs[1].data)
|
||||
assertEquals(ourIdentity.owningKey, wtx.commands.single { it.value is Cash.Commands.Move }.signers[0])
|
||||
assertEquals(ourIdentity.owningKey, wtx.commands.single { it.value is Move }.signers[0])
|
||||
}
|
||||
}
|
||||
|
||||
@ -685,7 +685,7 @@ class CashTests {
|
||||
assertEquals(vaultState0.ref, wtx.inputs[0])
|
||||
assertEquals(vaultState1.ref, wtx.inputs[1])
|
||||
assertEquals(vaultState0.state.data.copy(owner = miniCorpAnonymised, amount = 500.DOLLARS `issued by` defaultIssuer), wtx.getOutput(0))
|
||||
assertEquals(ourIdentity.owningKey, wtx.commands.single { it.value is Cash.Commands.Move }.signers[0])
|
||||
assertEquals(ourIdentity.owningKey, wtx.commands.single { it.value is Move }.signers[0])
|
||||
}
|
||||
}
|
||||
|
||||
@ -706,7 +706,7 @@ class CashTests {
|
||||
assertEquals(vaultState2.ref, wtx.inputs[2])
|
||||
assertEquals(vaultState0.state.data.copy(owner = miniCorpAnonymised, amount = 500.DOLLARS `issued by` defaultIssuer), wtx.outputs[1].data)
|
||||
assertEquals(vaultState2.state.data.copy(owner = miniCorpAnonymised), wtx.outputs[0].data)
|
||||
assertEquals(ourIdentity.owningKey, wtx.commands.single { it.value is Cash.Commands.Move }.signers[0])
|
||||
assertEquals(ourIdentity.owningKey, wtx.commands.single { it.value is Move }.signers[0])
|
||||
}
|
||||
}
|
||||
|
||||
@ -823,7 +823,7 @@ class CashTests {
|
||||
attachment(Cash.PROGRAM_ID)
|
||||
input("MEGA_CORP cash")
|
||||
output(Cash.PROGRAM_ID, "MEGA_CORP cash 2", "MEGA_CORP cash".output<Cash.State>().copy(owner = AnonymousParty(alice.publicKey)))
|
||||
command(megaCorp.publicKey, Cash.Commands.Move())
|
||||
command(megaCorp.publicKey, Move())
|
||||
this.verifies()
|
||||
}
|
||||
|
||||
@ -833,7 +833,7 @@ class CashTests {
|
||||
input("MEGA_CORP cash")
|
||||
// We send it to another pubkey so that the transaction is not identical to the previous one
|
||||
output(Cash.PROGRAM_ID, "MEGA_CORP cash 3", "MEGA_CORP cash".output<Cash.State>().copy(owner = alice.party))
|
||||
command(megaCorp.publicKey, Cash.Commands.Move())
|
||||
command(megaCorp.publicKey, Move())
|
||||
this.verifies()
|
||||
}
|
||||
this.fails()
|
||||
|
@ -379,7 +379,7 @@ class ObligationTests {
|
||||
|
||||
// Now generate a transaction settling the obligation
|
||||
val settleTx = TransactionBuilder(DUMMY_NOTARY).apply {
|
||||
ObligationUtils.generateSettle(this, listOf(obligationTx.outRef<Obligation.State<Currency>>(0)), listOf(cashTx.outRef(0)), Cash.Commands.Move(), DUMMY_NOTARY)
|
||||
ObligationUtils.generateSettle(this, listOf(obligationTx.outRef<Obligation.State<Currency>>(0)), listOf(cashTx.outRef(0)), Move(), DUMMY_NOTARY)
|
||||
}.toWireTransaction(miniCorpServices)
|
||||
assertEquals(2, settleTx.inputs.size)
|
||||
assertEquals(1, settleTx.outputs.size)
|
||||
@ -518,7 +518,7 @@ class ObligationTests {
|
||||
input("Alice's $1,000,000")
|
||||
output(Cash.PROGRAM_ID, "Bob's $1,000,000", 1000000.DOLLARS.CASH issuedBy defaultIssuer ownedBy BOB)
|
||||
command(ALICE_PUBKEY, Obligation.Commands.Settle(Amount(oneMillionDollars.quantity, inState.amount.token)))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Move(Obligation::class.java))
|
||||
command(ALICE_PUBKEY, Move(Obligation::class.java))
|
||||
attachment(attachment(cashContractBytes.inputStream()))
|
||||
this.verifies()
|
||||
}
|
||||
@ -534,7 +534,7 @@ class ObligationTests {
|
||||
output(Obligation.PROGRAM_ID, "Alice's $500,000 obligation to Bob", halfAMillionDollars.OBLIGATION between Pair(ALICE, BOB))
|
||||
output(Cash.PROGRAM_ID, "Bob's $500,000", 500000.DOLLARS.CASH issuedBy defaultIssuer ownedBy BOB)
|
||||
command(ALICE_PUBKEY, Obligation.Commands.Settle(Amount(oneMillionDollars.quantity / 2, inState.amount.token)))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Move(Obligation::class.java))
|
||||
command(ALICE_PUBKEY, Move(Obligation::class.java))
|
||||
attachment(attachment(cashContractBytes.inputStream()))
|
||||
this.verifies()
|
||||
}
|
||||
@ -549,7 +549,7 @@ class ObligationTests {
|
||||
input(Cash.PROGRAM_ID, 1000000.DOLLARS.CASH issuedBy defaultIssuer ownedBy ALICE)
|
||||
output(Cash.PROGRAM_ID, "Bob's $1,000,000", 1000000.DOLLARS.CASH issuedBy defaultIssuer ownedBy BOB)
|
||||
command(ALICE_PUBKEY, Obligation.Commands.Settle(Amount(oneMillionDollars.quantity, inState.amount.token)))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Move(Obligation::class.java))
|
||||
command(ALICE_PUBKEY, Move(Obligation::class.java))
|
||||
this `fails with` "all inputs are in the normal state"
|
||||
}
|
||||
}
|
||||
@ -563,7 +563,7 @@ class ObligationTests {
|
||||
input("Alice's $1,000,000")
|
||||
output(Cash.PROGRAM_ID, "Bob's $1,000,000", 1000000.DOLLARS.CASH issuedBy defaultIssuer ownedBy BOB)
|
||||
command(ALICE_PUBKEY, Obligation.Commands.Settle(Amount(oneMillionDollars.quantity / 2, inState.amount.token)))
|
||||
command(ALICE_PUBKEY, Cash.Commands.Move(Obligation::class.java))
|
||||
command(ALICE_PUBKEY, Move(Obligation::class.java))
|
||||
attachment(attachment(cashContractBytes.inputStream()))
|
||||
this `fails with` "amount in settle command"
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import net.corda.core.utilities.getOrThrow
|
||||
import net.corda.finance.DOLLARS
|
||||
import net.corda.finance.workflows.asset.selection.AbstractCashSelection
|
||||
import net.corda.finance.contracts.asset.Cash
|
||||
import net.corda.finance.contracts.asset.Issue
|
||||
import net.corda.finance.workflows.getCashBalance
|
||||
import net.corda.finance.issuedBy
|
||||
import net.corda.testing.core.singleIdentity
|
||||
@ -56,7 +57,7 @@ class CashSelectionTest {
|
||||
val exitedAmount = 1.DOLLARS
|
||||
val issuance = TransactionBuilder(null as Party?)
|
||||
issuance.addOutputState(TransactionState(Cash.State(coin, nodeIdentity), Cash.PROGRAM_ID, mockNet.defaultNotaryIdentity))
|
||||
issuance.addCommand(Cash.Commands.Issue(), nodeIdentity.owningKey)
|
||||
issuance.addCommand(Issue("issue-123"), nodeIdentity.owningKey)
|
||||
|
||||
// Insert and select in the same transaction
|
||||
val exitStates = node.database.transaction {
|
||||
@ -85,7 +86,7 @@ class CashSelectionTest {
|
||||
val coin = 1.DOLLARS.issuedBy(issuer)
|
||||
val issuance = TransactionBuilder(null as Party?)
|
||||
issuance.addOutputState(TransactionState(Cash.State(coin, nodeIdentity), Cash.PROGRAM_ID, mockNet.defaultNotaryIdentity))
|
||||
issuance.addCommand(Cash.Commands.Issue(), nodeIdentity.owningKey)
|
||||
issuance.addCommand(Issue("issue-123"), nodeIdentity.owningKey)
|
||||
|
||||
val transaction = node.services.signInitialTransaction(issuance, nodeIdentity.owningKey)
|
||||
|
||||
@ -114,7 +115,7 @@ class CashSelectionTest {
|
||||
coins.forEach {
|
||||
issuance.addOutputState(TransactionState(Cash.State(it, nodeIdentity), "net.corda.finance.contracts.asset.Cash", mockNet.defaultNotaryIdentity))
|
||||
}
|
||||
issuance.addCommand(Cash.Commands.Issue(), nodeIdentity.owningKey)
|
||||
issuance.addCommand(Issue("issue-123"), nodeIdentity.owningKey)
|
||||
|
||||
val transaction = node.services.signInitialTransaction(issuance, nodeIdentity.owningKey)
|
||||
node.database.transaction {
|
||||
|
@ -3,7 +3,7 @@ package net.corda.finance.flows
|
||||
import net.corda.core.serialization.SerializationDefaults
|
||||
import net.corda.core.serialization.SerializedBytes
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.finance.contracts.asset.Cash
|
||||
import net.corda.finance.contracts.asset.Issue
|
||||
import net.corda.serialization.internal.AllWhitelist
|
||||
import net.corda.serialization.internal.amqp.DeserializationInput
|
||||
import net.corda.serialization.internal.amqp.Schema
|
||||
@ -46,7 +46,7 @@ class CompatibilityTest {
|
||||
|
||||
val commands = transaction.tx.commands
|
||||
assertEquals(1, commands.size)
|
||||
assertTrue(commands.first().value is Cash.Commands.Issue)
|
||||
assertTrue(commands.first().value is Issue)
|
||||
|
||||
// Serialize back and check that representation is byte-to-byte identical to what it was originally.
|
||||
val output = SerializationOutput(serializerFactory)
|
||||
|
@ -32,6 +32,8 @@ import net.corda.finance.`issued by`
|
||||
import net.corda.finance.contracts.CommercialPaper
|
||||
import net.corda.finance.contracts.asset.CASH
|
||||
import net.corda.finance.contracts.asset.Cash
|
||||
import net.corda.finance.contracts.asset.Issue
|
||||
import net.corda.finance.contracts.asset.Move
|
||||
import net.corda.finance.flows.TwoPartyTradeFlow.Buyer
|
||||
import net.corda.finance.flows.TwoPartyTradeFlow.Seller
|
||||
import net.corda.node.services.api.CheckpointStorage
|
||||
@ -673,10 +675,10 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
||||
output(Cash.PROGRAM_ID, "elbonian money 1", notary = notary, contractState = 800.DOLLARS.CASH issuedBy issuer ownedBy interimOwner)
|
||||
output(Cash.PROGRAM_ID, "elbonian money 2", notary = notary, contractState = 1000.DOLLARS.CASH issuedBy issuer ownedBy interimOwner)
|
||||
if (!withError) {
|
||||
command(issuer.party.owningKey, Cash.Commands.Issue())
|
||||
command(issuer.party.owningKey, Issue("issue-123"))
|
||||
} else {
|
||||
// Put a broken command on so at least a signature is created
|
||||
command(issuer.party.owningKey, Cash.Commands.Move())
|
||||
command(issuer.party.owningKey, Move())
|
||||
}
|
||||
timeWindow(TEST_TX_TIME)
|
||||
if (withError) {
|
||||
@ -691,7 +693,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
||||
val bc1 = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
|
||||
input("elbonian money 1")
|
||||
output(Cash.PROGRAM_ID, "bob cash 1", notary = notary, contractState = 800.DOLLARS.CASH issuedBy issuer ownedBy owner)
|
||||
command(interimOwner.owningKey, Cash.Commands.Move())
|
||||
command(interimOwner.owningKey, Move())
|
||||
this.verifies()
|
||||
}
|
||||
val eb2Txns = insertFakeTransactions(listOf(bc1), node, identity, notaryNode, *extraSigningNodes)
|
||||
@ -700,7 +702,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
||||
input("elbonian money 2")
|
||||
output(Cash.PROGRAM_ID, "bob cash 2", notary = notary, contractState = 300.DOLLARS.CASH issuedBy issuer ownedBy owner)
|
||||
output(Cash.PROGRAM_ID, notary = notary, contractState = 700.DOLLARS.CASH issuedBy issuer ownedBy interimOwner) // Change output.
|
||||
command(interimOwner.owningKey, Cash.Commands.Move())
|
||||
command(interimOwner.owningKey, Move())
|
||||
this.verifies()
|
||||
}
|
||||
val eb3Txns = insertFakeTransactions(listOf(bc2), node, identity, notaryNode, *extraSigningNodes)
|
||||
|
@ -25,6 +25,8 @@ import net.corda.core.utilities.getOrThrow
|
||||
import net.corda.core.utilities.toNonEmptySet
|
||||
import net.corda.finance.*
|
||||
import net.corda.finance.contracts.asset.Cash
|
||||
import net.corda.finance.contracts.asset.Issue
|
||||
import net.corda.finance.contracts.asset.Move
|
||||
import net.corda.finance.contracts.utils.sumCash
|
||||
import net.corda.finance.schemas.CashSchemaV1
|
||||
import net.corda.finance.workflows.asset.CashUtils
|
||||
@ -758,7 +760,7 @@ class NodeVaultServiceTest {
|
||||
// Send some minimalist dummy transaction.
|
||||
val txb = TransactionBuilder(DUMMY_NOTARY)
|
||||
txb.addOutputState(Cash.State(MEGA_CORP.ref(0), 100.DOLLARS, MINI_CORP), Cash::class.java.name)
|
||||
txb.addCommand(Cash.Commands.Move(), MEGA_CORP_PUBKEY)
|
||||
txb.addCommand(Move(), MEGA_CORP_PUBKEY)
|
||||
val wtx = txb.toWireTransaction(services)
|
||||
database.transaction {
|
||||
vaultService.notify(StatesToRecord.ONLY_RELEVANT, wtx)
|
||||
@ -786,7 +788,7 @@ class NodeVaultServiceTest {
|
||||
//create single transaction with 2 'identical' cash outputs
|
||||
val txb = TransactionBuilder(DUMMY_NOTARY)
|
||||
coins.map { txb.addOutputState(TransactionState(Cash.State(it, nodeIdentity), Cash.PROGRAM_ID, DUMMY_NOTARY)) }
|
||||
txb.addCommand(Cash.Commands.Issue(), nodeIdentity.owningKey)
|
||||
txb.addCommand(Issue("issue-123"), nodeIdentity.owningKey)
|
||||
val issueTx = txb.toWireTransaction(services)
|
||||
|
||||
// ensure transaction contract state is persisted in DBStorage
|
||||
@ -809,7 +811,7 @@ class NodeVaultServiceTest {
|
||||
//create single transaction with 2 'identical' cash outputs
|
||||
val txb = TransactionBuilder(DUMMY_NOTARY)
|
||||
coins.map { txb.addOutputState(TransactionState(Cash.State(it, nodeIdentity), Cash.PROGRAM_ID, DUMMY_NOTARY)) }
|
||||
txb.addCommand(Cash.Commands.Issue(), nodeIdentity.owningKey)
|
||||
txb.addCommand(Issue("issue-123"), nodeIdentity.owningKey)
|
||||
val issueTx = txb.toWireTransaction(services)
|
||||
|
||||
// ensure transaction contract state is persisted in DBStorage
|
||||
|
@ -10,6 +10,7 @@ import net.corda.finance.DOLLARS
|
||||
import net.corda.finance.contracts.Fix
|
||||
import net.corda.finance.contracts.asset.CASH
|
||||
import net.corda.finance.contracts.asset.Cash
|
||||
import net.corda.finance.contracts.asset.Move
|
||||
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
||||
import net.corda.testing.core.*
|
||||
@ -141,7 +142,7 @@ class NodeInterestRatesTest {
|
||||
|
||||
val ftx1 = wtx1.buildFilteredTransaction(Predicate(::filterAllOutputs))
|
||||
assertFailsWith<IllegalArgumentException> { oracle.sign(ftx1) }
|
||||
tx.addCommand(Cash.Commands.Move(), ALICE_PUBKEY)
|
||||
tx.addCommand(Move(), ALICE_PUBKEY)
|
||||
val wtx2 = tx.toWireTransaction(services)
|
||||
val ftx2 = wtx2.buildFilteredTransaction(Predicate { x -> filterCmds(x) })
|
||||
assertFalse(wtx1.id == wtx2.id)
|
||||
|
Loading…
Reference in New Issue
Block a user