Merge branch 'cbdc/poc-encrypt-backchain' of github.com:corda/corda into cbdc/poc-encrypt-backchain

This commit is contained in:
adam.houston 2022-03-18 10:54:39 +00:00
commit fbc06d7f57
24 changed files with 197 additions and 170 deletions

View File

@ -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 {

View File

@ -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

View File

@ -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()
}
}

View File

@ -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()
}

View File

@ -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()
}

View File

@ -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()
}

View File

@ -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))

View File

@ -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)

View File

@ -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.

View File

@ -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()
}

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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();
});
});

View File

@ -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)

View File

@ -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()

View File

@ -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"
}

View File

@ -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 {

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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)