mirror of
https://github.com/corda/corda.git
synced 2024-12-24 07:06:44 +00:00
CORDA-654 Simplify TransactionDSL API (#2152)
This commit is contained in:
parent
5a6f2a19b3
commit
a314a6a125
@ -38,24 +38,20 @@ class PartialMerkleTreeTest {
|
|||||||
testLedger = ledger {
|
testLedger = ledger {
|
||||||
unverifiedTransaction {
|
unverifiedTransaction {
|
||||||
attachments(Cash.PROGRAM_ID)
|
attachments(Cash.PROGRAM_ID)
|
||||||
output(Cash.PROGRAM_ID, "MEGA_CORP cash") {
|
output(Cash.PROGRAM_ID, "MEGA_CORP cash",
|
||||||
Cash.State(
|
Cash.State(
|
||||||
amount = 1000.DOLLARS `issued by` MEGA_CORP.ref(1, 1),
|
amount = 1000.DOLLARS `issued by` MEGA_CORP.ref(1, 1),
|
||||||
owner = MEGA_CORP
|
owner = MEGA_CORP))
|
||||||
)
|
output(Cash.PROGRAM_ID, "dummy cash 1",
|
||||||
}
|
|
||||||
output(Cash.PROGRAM_ID, "dummy cash 1") {
|
|
||||||
Cash.State(
|
Cash.State(
|
||||||
amount = 900.DOLLARS `issued by` MEGA_CORP.ref(1, 1),
|
amount = 900.DOLLARS `issued by` MEGA_CORP.ref(1, 1),
|
||||||
owner = MINI_CORP
|
owner = MINI_CORP))
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
transaction {
|
transaction {
|
||||||
attachments(Cash.PROGRAM_ID)
|
attachments(Cash.PROGRAM_ID)
|
||||||
input("MEGA_CORP cash")
|
input("MEGA_CORP cash")
|
||||||
output(Cash.PROGRAM_ID, "MEGA_CORP cash".output<Cash.State>().copy(owner = MINI_CORP))
|
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, Cash.Commands.Move())
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
|
@ -55,10 +55,10 @@ class TransactionEncumbranceTests {
|
|||||||
ledger {
|
ledger {
|
||||||
transaction {
|
transaction {
|
||||||
attachments(Cash.PROGRAM_ID, TEST_TIMELOCK_ID)
|
attachments(Cash.PROGRAM_ID, TEST_TIMELOCK_ID)
|
||||||
input(Cash.PROGRAM_ID) { state }
|
input(Cash.PROGRAM_ID, state)
|
||||||
output(Cash.PROGRAM_ID, encumbrance = 1) { stateWithNewOwner }
|
output(Cash.PROGRAM_ID, encumbrance = 1, contractState = stateWithNewOwner)
|
||||||
output(TEST_TIMELOCK_ID, "5pm time-lock") { timeLock }
|
output(TEST_TIMELOCK_ID, "5pm time-lock", timeLock)
|
||||||
command(MEGA_CORP.owningKey) { Cash.Commands.Move() }
|
command(MEGA_CORP.owningKey, Cash.Commands.Move())
|
||||||
verifies()
|
verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -69,16 +69,16 @@ class TransactionEncumbranceTests {
|
|||||||
ledger {
|
ledger {
|
||||||
unverifiedTransaction {
|
unverifiedTransaction {
|
||||||
attachments(Cash.PROGRAM_ID, TEST_TIMELOCK_ID)
|
attachments(Cash.PROGRAM_ID, TEST_TIMELOCK_ID)
|
||||||
output(Cash.PROGRAM_ID, "state encumbered by 5pm time-lock") { state }
|
output(Cash.PROGRAM_ID, "state encumbered by 5pm time-lock", state)
|
||||||
output(TEST_TIMELOCK_ID, "5pm time-lock") { timeLock }
|
output(TEST_TIMELOCK_ID, "5pm time-lock", timeLock)
|
||||||
}
|
}
|
||||||
// Un-encumber the output if the time of the transaction is later than the timelock.
|
// Un-encumber the output if the time of the transaction is later than the timelock.
|
||||||
transaction {
|
transaction {
|
||||||
attachments(Cash.PROGRAM_ID, TEST_TIMELOCK_ID)
|
attachments(Cash.PROGRAM_ID, TEST_TIMELOCK_ID)
|
||||||
input("state encumbered by 5pm time-lock")
|
input("state encumbered by 5pm time-lock")
|
||||||
input("5pm time-lock")
|
input("5pm time-lock")
|
||||||
output(Cash.PROGRAM_ID) { stateWithNewOwner }
|
output(Cash.PROGRAM_ID, stateWithNewOwner)
|
||||||
command(MEGA_CORP.owningKey) { Cash.Commands.Move() }
|
command(MEGA_CORP.owningKey, Cash.Commands.Move())
|
||||||
timeWindow(FIVE_PM)
|
timeWindow(FIVE_PM)
|
||||||
verifies()
|
verifies()
|
||||||
}
|
}
|
||||||
@ -90,16 +90,16 @@ class TransactionEncumbranceTests {
|
|||||||
ledger {
|
ledger {
|
||||||
unverifiedTransaction {
|
unverifiedTransaction {
|
||||||
attachments(Cash.PROGRAM_ID, TEST_TIMELOCK_ID)
|
attachments(Cash.PROGRAM_ID, TEST_TIMELOCK_ID)
|
||||||
output(Cash.PROGRAM_ID, "state encumbered by 5pm time-lock") { state }
|
output(Cash.PROGRAM_ID, "state encumbered by 5pm time-lock", state)
|
||||||
output(TEST_TIMELOCK_ID, "5pm time-lock") { timeLock }
|
output(TEST_TIMELOCK_ID, "5pm time-lock", timeLock)
|
||||||
}
|
}
|
||||||
// The time of the transaction is earlier than the time specified in the encumbering timelock.
|
// The time of the transaction is earlier than the time specified in the encumbering timelock.
|
||||||
transaction {
|
transaction {
|
||||||
attachments(Cash.PROGRAM_ID, TEST_TIMELOCK_ID)
|
attachments(Cash.PROGRAM_ID, TEST_TIMELOCK_ID)
|
||||||
input("state encumbered by 5pm time-lock")
|
input("state encumbered by 5pm time-lock")
|
||||||
input("5pm time-lock")
|
input("5pm time-lock")
|
||||||
output(Cash.PROGRAM_ID) { state }
|
output(Cash.PROGRAM_ID, state)
|
||||||
command(MEGA_CORP.owningKey) { Cash.Commands.Move() }
|
command(MEGA_CORP.owningKey, Cash.Commands.Move())
|
||||||
timeWindow(FOUR_PM)
|
timeWindow(FOUR_PM)
|
||||||
this `fails with` "the time specified in the time-lock has passed"
|
this `fails with` "the time specified in the time-lock has passed"
|
||||||
}
|
}
|
||||||
@ -111,14 +111,14 @@ class TransactionEncumbranceTests {
|
|||||||
ledger {
|
ledger {
|
||||||
unverifiedTransaction {
|
unverifiedTransaction {
|
||||||
attachments(Cash.PROGRAM_ID, TEST_TIMELOCK_ID)
|
attachments(Cash.PROGRAM_ID, TEST_TIMELOCK_ID)
|
||||||
output(Cash.PROGRAM_ID, "state encumbered by 5pm time-lock", encumbrance = 1) { state }
|
output(Cash.PROGRAM_ID, "state encumbered by 5pm time-lock", encumbrance = 1, contractState = state)
|
||||||
output(TEST_TIMELOCK_ID, "5pm time-lock") { timeLock }
|
output(TEST_TIMELOCK_ID, "5pm time-lock", timeLock)
|
||||||
}
|
}
|
||||||
transaction {
|
transaction {
|
||||||
attachments(Cash.PROGRAM_ID)
|
attachments(Cash.PROGRAM_ID)
|
||||||
input("state encumbered by 5pm time-lock")
|
input("state encumbered by 5pm time-lock")
|
||||||
output(Cash.PROGRAM_ID) { stateWithNewOwner }
|
output(Cash.PROGRAM_ID, stateWithNewOwner)
|
||||||
command(MEGA_CORP.owningKey) { Cash.Commands.Move() }
|
command(MEGA_CORP.owningKey, Cash.Commands.Move())
|
||||||
timeWindow(FIVE_PM)
|
timeWindow(FIVE_PM)
|
||||||
this `fails with` "Missing required encumbrance 1 in INPUT"
|
this `fails with` "Missing required encumbrance 1 in INPUT"
|
||||||
}
|
}
|
||||||
@ -130,9 +130,9 @@ class TransactionEncumbranceTests {
|
|||||||
ledger {
|
ledger {
|
||||||
transaction {
|
transaction {
|
||||||
attachments(Cash.PROGRAM_ID)
|
attachments(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { state }
|
input(Cash.PROGRAM_ID, state)
|
||||||
output(Cash.PROGRAM_ID, encumbrance = 0) { stateWithNewOwner }
|
output(Cash.PROGRAM_ID, encumbrance = 0, contractState = stateWithNewOwner)
|
||||||
command(MEGA_CORP.owningKey) { Cash.Commands.Move() }
|
command(MEGA_CORP.owningKey, Cash.Commands.Move())
|
||||||
this `fails with` "Missing required encumbrance 0 in OUTPUT"
|
this `fails with` "Missing required encumbrance 0 in OUTPUT"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -143,10 +143,10 @@ class TransactionEncumbranceTests {
|
|||||||
ledger {
|
ledger {
|
||||||
transaction {
|
transaction {
|
||||||
attachments(Cash.PROGRAM_ID, TEST_TIMELOCK_ID)
|
attachments(Cash.PROGRAM_ID, TEST_TIMELOCK_ID)
|
||||||
input(Cash.PROGRAM_ID) { state }
|
input(Cash.PROGRAM_ID, state)
|
||||||
output(TEST_TIMELOCK_ID, encumbrance = 2) { stateWithNewOwner }
|
output(TEST_TIMELOCK_ID, encumbrance = 2, contractState = stateWithNewOwner)
|
||||||
output(TEST_TIMELOCK_ID) { timeLock }
|
output(TEST_TIMELOCK_ID, timeLock)
|
||||||
command(MEGA_CORP.owningKey) { Cash.Commands.Move() }
|
command(MEGA_CORP.owningKey, Cash.Commands.Move())
|
||||||
this `fails with` "Missing required encumbrance 2 in OUTPUT"
|
this `fails with` "Missing required encumbrance 2 in OUTPUT"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -157,16 +157,16 @@ class TransactionEncumbranceTests {
|
|||||||
ledger {
|
ledger {
|
||||||
unverifiedTransaction {
|
unverifiedTransaction {
|
||||||
attachments(Cash.PROGRAM_ID, TEST_TIMELOCK_ID)
|
attachments(Cash.PROGRAM_ID, TEST_TIMELOCK_ID)
|
||||||
output(Cash.PROGRAM_ID, "state encumbered by some other state", encumbrance = 1) { state }
|
output(Cash.PROGRAM_ID, "state encumbered by some other state", encumbrance = 1, contractState = state)
|
||||||
output(Cash.PROGRAM_ID, "some other state") { state }
|
output(Cash.PROGRAM_ID, "some other state", state)
|
||||||
output(TEST_TIMELOCK_ID, "5pm time-lock") { timeLock }
|
output(TEST_TIMELOCK_ID, "5pm time-lock", timeLock)
|
||||||
}
|
}
|
||||||
transaction {
|
transaction {
|
||||||
attachments(Cash.PROGRAM_ID, TEST_TIMELOCK_ID)
|
attachments(Cash.PROGRAM_ID, TEST_TIMELOCK_ID)
|
||||||
input("state encumbered by some other state")
|
input("state encumbered by some other state")
|
||||||
input("5pm time-lock")
|
input("5pm time-lock")
|
||||||
output(Cash.PROGRAM_ID) { stateWithNewOwner }
|
output(Cash.PROGRAM_ID, stateWithNewOwner)
|
||||||
command(MEGA_CORP.owningKey) { Cash.Commands.Move() }
|
command(MEGA_CORP.owningKey, Cash.Commands.Move())
|
||||||
timeWindow(FIVE_PM)
|
timeWindow(FIVE_PM)
|
||||||
this `fails with` "Missing required encumbrance 1 in INPUT"
|
this `fails with` "Missing required encumbrance 1 in INPUT"
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ class CommercialPaperTest {
|
|||||||
ledger {
|
ledger {
|
||||||
transaction {
|
transaction {
|
||||||
attachments(CP_PROGRAM_ID)
|
attachments(CP_PROGRAM_ID)
|
||||||
input(CP_PROGRAM_ID) { inState }
|
input(CP_PROGRAM_ID, inState)
|
||||||
verifies()
|
verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -46,8 +46,8 @@ class CommercialPaperTest {
|
|||||||
val inState = getPaper()
|
val inState = getPaper()
|
||||||
ledger {
|
ledger {
|
||||||
transaction {
|
transaction {
|
||||||
input(CP_PROGRAM_ID) { inState }
|
input(CP_PROGRAM_ID, inState)
|
||||||
command(MEGA_CORP_PUBKEY) { CommercialPaper.Commands.Move() }
|
command(MEGA_CORP_PUBKEY, CommercialPaper.Commands.Move())
|
||||||
attachments(CP_PROGRAM_ID)
|
attachments(CP_PROGRAM_ID)
|
||||||
verifies()
|
verifies()
|
||||||
}
|
}
|
||||||
@ -61,8 +61,8 @@ class CommercialPaperTest {
|
|||||||
val inState = getPaper()
|
val inState = getPaper()
|
||||||
ledger {
|
ledger {
|
||||||
transaction {
|
transaction {
|
||||||
input(CP_PROGRAM_ID) { inState }
|
input(CP_PROGRAM_ID, inState)
|
||||||
command(MEGA_CORP_PUBKEY) { CommercialPaper.Commands.Move() }
|
command(MEGA_CORP_PUBKEY, CommercialPaper.Commands.Move())
|
||||||
attachments(CP_PROGRAM_ID)
|
attachments(CP_PROGRAM_ID)
|
||||||
`fails with`("the state is propagated")
|
`fails with`("the state is propagated")
|
||||||
}
|
}
|
||||||
@ -76,11 +76,11 @@ class CommercialPaperTest {
|
|||||||
val inState = getPaper()
|
val inState = getPaper()
|
||||||
ledger {
|
ledger {
|
||||||
transaction {
|
transaction {
|
||||||
input(CP_PROGRAM_ID) { inState }
|
input(CP_PROGRAM_ID, inState)
|
||||||
command(MEGA_CORP_PUBKEY) { CommercialPaper.Commands.Move() }
|
command(MEGA_CORP_PUBKEY, CommercialPaper.Commands.Move())
|
||||||
attachments(CP_PROGRAM_ID)
|
attachments(CP_PROGRAM_ID)
|
||||||
`fails with`("the state is propagated")
|
`fails with`("the state is propagated")
|
||||||
output(CP_PROGRAM_ID, "alice's paper") { inState.withOwner(ALICE) }
|
output(CP_PROGRAM_ID, "alice's paper", inState.withOwner(ALICE))
|
||||||
verifies()
|
verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,15 +92,15 @@ class CommercialPaperTest {
|
|||||||
fun `simple issuance with tweak`() {
|
fun `simple issuance with tweak`() {
|
||||||
ledger {
|
ledger {
|
||||||
transaction {
|
transaction {
|
||||||
output(CP_PROGRAM_ID, "paper") { getPaper() } // Some CP is issued onto the ledger by MegaCorp.
|
output(CP_PROGRAM_ID, "paper", getPaper()) // Some CP is issued onto the ledger by MegaCorp.
|
||||||
attachments(CP_PROGRAM_ID)
|
attachments(CP_PROGRAM_ID)
|
||||||
tweak {
|
tweak {
|
||||||
// The wrong pubkey.
|
// The wrong pubkey.
|
||||||
command(BIG_CORP_PUBKEY) { CommercialPaper.Commands.Issue() }
|
command(BIG_CORP_PUBKEY, CommercialPaper.Commands.Issue())
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
`fails with`("output states are issued by a command signer")
|
`fails with`("output states are issued by a command signer")
|
||||||
}
|
}
|
||||||
command(MEGA_CORP_PUBKEY) { CommercialPaper.Commands.Issue() }
|
command(MEGA_CORP_PUBKEY, CommercialPaper.Commands.Issue())
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
verifies()
|
verifies()
|
||||||
}
|
}
|
||||||
@ -112,15 +112,15 @@ class CommercialPaperTest {
|
|||||||
@Test
|
@Test
|
||||||
fun `simple issuance with tweak and top level transaction`() {
|
fun `simple issuance with tweak and top level transaction`() {
|
||||||
transaction {
|
transaction {
|
||||||
output(CP_PROGRAM_ID, "paper") { getPaper() } // Some CP is issued onto the ledger by MegaCorp.
|
output(CP_PROGRAM_ID, "paper", getPaper()) // Some CP is issued onto the ledger by MegaCorp.
|
||||||
attachments(CP_PROGRAM_ID)
|
attachments(CP_PROGRAM_ID)
|
||||||
tweak {
|
tweak {
|
||||||
// The wrong pubkey.
|
// The wrong pubkey.
|
||||||
command(BIG_CORP_PUBKEY) { CommercialPaper.Commands.Issue() }
|
command(BIG_CORP_PUBKEY, CommercialPaper.Commands.Issue())
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
`fails with`("output states are issued by a command signer")
|
`fails with`("output states are issued by a command signer")
|
||||||
}
|
}
|
||||||
command(MEGA_CORP_PUBKEY) { CommercialPaper.Commands.Issue() }
|
command(MEGA_CORP_PUBKEY, CommercialPaper.Commands.Issue())
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
verifies()
|
verifies()
|
||||||
}
|
}
|
||||||
@ -140,8 +140,8 @@ class CommercialPaperTest {
|
|||||||
|
|
||||||
// Some CP is issued onto the ledger by MegaCorp.
|
// Some CP is issued onto the ledger by MegaCorp.
|
||||||
transaction("Issuance") {
|
transaction("Issuance") {
|
||||||
output(CP_PROGRAM_ID, "paper") { getPaper() }
|
output(CP_PROGRAM_ID, "paper", getPaper())
|
||||||
command(MEGA_CORP_PUBKEY) { CommercialPaper.Commands.Issue() }
|
command(MEGA_CORP_PUBKEY, CommercialPaper.Commands.Issue())
|
||||||
attachments(CP_PROGRAM_ID)
|
attachments(CP_PROGRAM_ID)
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
verifies()
|
verifies()
|
||||||
@ -151,10 +151,10 @@ class CommercialPaperTest {
|
|||||||
transaction("Trade") {
|
transaction("Trade") {
|
||||||
input("paper")
|
input("paper")
|
||||||
input("alice's $900")
|
input("alice's $900")
|
||||||
output(Cash.PROGRAM_ID, "borrowed $900") { 900.DOLLARS.CASH issuedBy issuer ownedBy MEGA_CORP }
|
output(Cash.PROGRAM_ID, "borrowed $900", 900.DOLLARS.CASH issuedBy issuer ownedBy MEGA_CORP)
|
||||||
output(CP_PROGRAM_ID, "alice's paper") { "paper".output<ICommercialPaperState>().withOwner(ALICE) }
|
output(CP_PROGRAM_ID, "alice's paper", "paper".output<ICommercialPaperState>().withOwner(ALICE))
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
command(MEGA_CORP_PUBKEY) { CommercialPaper.Commands.Move() }
|
command(MEGA_CORP_PUBKEY, CommercialPaper.Commands.Move())
|
||||||
verifies()
|
verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -173,8 +173,8 @@ class CommercialPaperTest {
|
|||||||
|
|
||||||
// Some CP is issued onto the ledger by MegaCorp.
|
// Some CP is issued onto the ledger by MegaCorp.
|
||||||
transaction("Issuance") {
|
transaction("Issuance") {
|
||||||
output(CP_PROGRAM_ID, "paper") { getPaper() }
|
output(CP_PROGRAM_ID, "paper", getPaper())
|
||||||
command(MEGA_CORP_PUBKEY) { CommercialPaper.Commands.Issue() }
|
command(MEGA_CORP_PUBKEY, CommercialPaper.Commands.Issue())
|
||||||
attachments(CP_PROGRAM_ID)
|
attachments(CP_PROGRAM_ID)
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
verifies()
|
verifies()
|
||||||
@ -183,18 +183,18 @@ class CommercialPaperTest {
|
|||||||
transaction("Trade") {
|
transaction("Trade") {
|
||||||
input("paper")
|
input("paper")
|
||||||
input("alice's $900")
|
input("alice's $900")
|
||||||
output(Cash.PROGRAM_ID, "borrowed $900") { 900.DOLLARS.CASH issuedBy issuer ownedBy MEGA_CORP }
|
output(Cash.PROGRAM_ID, "borrowed $900", 900.DOLLARS.CASH issuedBy issuer ownedBy MEGA_CORP)
|
||||||
output(CP_PROGRAM_ID, "alice's paper") { "paper".output<ICommercialPaperState>().withOwner(ALICE) }
|
output(CP_PROGRAM_ID, "alice's paper", "paper".output<ICommercialPaperState>().withOwner(ALICE))
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
command(MEGA_CORP_PUBKEY) { CommercialPaper.Commands.Move() }
|
command(MEGA_CORP_PUBKEY, CommercialPaper.Commands.Move())
|
||||||
verifies()
|
verifies()
|
||||||
}
|
}
|
||||||
|
|
||||||
transaction {
|
transaction {
|
||||||
input("paper")
|
input("paper")
|
||||||
// We moved a paper to another pubkey.
|
// We moved a paper to another pubkey.
|
||||||
output(CP_PROGRAM_ID, "bob's paper") { "paper".output<ICommercialPaperState>().withOwner(BOB) }
|
output(CP_PROGRAM_ID, "bob's paper", "paper".output<ICommercialPaperState>().withOwner(BOB))
|
||||||
command(MEGA_CORP_PUBKEY) { CommercialPaper.Commands.Move() }
|
command(MEGA_CORP_PUBKEY, CommercialPaper.Commands.Move())
|
||||||
verifies()
|
verifies()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,8 +215,8 @@ class CommercialPaperTest {
|
|||||||
|
|
||||||
// Some CP is issued onto the ledger by MegaCorp.
|
// Some CP is issued onto the ledger by MegaCorp.
|
||||||
transaction("Issuance") {
|
transaction("Issuance") {
|
||||||
output(CP_PROGRAM_ID, "paper") { getPaper() }
|
output(CP_PROGRAM_ID, "paper", getPaper())
|
||||||
command(MEGA_CORP_PUBKEY) { CommercialPaper.Commands.Issue() }
|
command(MEGA_CORP_PUBKEY, CommercialPaper.Commands.Issue())
|
||||||
attachments(CP_PROGRAM_ID)
|
attachments(CP_PROGRAM_ID)
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
verifies()
|
verifies()
|
||||||
@ -225,10 +225,10 @@ class CommercialPaperTest {
|
|||||||
transaction("Trade") {
|
transaction("Trade") {
|
||||||
input("paper")
|
input("paper")
|
||||||
input("alice's $900")
|
input("alice's $900")
|
||||||
output(Cash.PROGRAM_ID, "borrowed $900") { 900.DOLLARS.CASH issuedBy issuer ownedBy MEGA_CORP }
|
output(Cash.PROGRAM_ID, "borrowed $900", 900.DOLLARS.CASH issuedBy issuer ownedBy MEGA_CORP)
|
||||||
output(CP_PROGRAM_ID, "alice's paper") { "paper".output<ICommercialPaperState>().withOwner(ALICE) }
|
output(CP_PROGRAM_ID, "alice's paper", "paper".output<ICommercialPaperState>().withOwner(ALICE))
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
command(MEGA_CORP_PUBKEY) { CommercialPaper.Commands.Move() }
|
command(MEGA_CORP_PUBKEY, CommercialPaper.Commands.Move())
|
||||||
verifies()
|
verifies()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,8 +236,8 @@ class CommercialPaperTest {
|
|||||||
transaction {
|
transaction {
|
||||||
input("paper")
|
input("paper")
|
||||||
// We moved a paper to another pubkey.
|
// We moved a paper to another pubkey.
|
||||||
output(CP_PROGRAM_ID, "bob's paper") { "paper".output<ICommercialPaperState>().withOwner(BOB) }
|
output(CP_PROGRAM_ID, "bob's paper", "paper".output<ICommercialPaperState>().withOwner(BOB))
|
||||||
command(MEGA_CORP_PUBKEY) { CommercialPaper.Commands.Move() }
|
command(MEGA_CORP_PUBKEY, CommercialPaper.Commands.Move())
|
||||||
verifies()
|
verifies()
|
||||||
}
|
}
|
||||||
fails()
|
fails()
|
||||||
|
@ -172,16 +172,14 @@ class Cap {
|
|||||||
@Test
|
@Test
|
||||||
fun issue() {
|
fun issue() {
|
||||||
transaction {
|
transaction {
|
||||||
output(UNIVERSAL_PROGRAM_ID) { stateInitial }
|
output(UNIVERSAL_PROGRAM_ID, stateInitial)
|
||||||
timeWindow(TEST_TX_TIME_1)
|
timeWindow(TEST_TX_TIME_1)
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(acmeCorp.owningKey) { UniversalContract.Commands.Issue() }
|
command(acmeCorp.owningKey, UniversalContract.Commands.Issue())
|
||||||
this `fails with` "the transaction is signed by all liable parties"
|
this `fails with` "the transaction is signed by all liable parties"
|
||||||
}
|
}
|
||||||
|
command(highStreetBank.owningKey, UniversalContract.Commands.Issue())
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Issue() }
|
|
||||||
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -189,44 +187,38 @@ class Cap {
|
|||||||
@Test
|
@Test
|
||||||
fun `first fixing`() {
|
fun `first fixing`() {
|
||||||
transaction {
|
transaction {
|
||||||
input(UNIVERSAL_PROGRAM_ID) { stateInitial }
|
input(UNIVERSAL_PROGRAM_ID, stateInitial)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { stateAfterFixingFirst }
|
output(UNIVERSAL_PROGRAM_ID, stateAfterFixingFirst)
|
||||||
timeWindow(TEST_TX_TIME_1)
|
timeWindow(TEST_TX_TIME_1)
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("some undefined name") }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Action("some undefined name"))
|
||||||
this `fails with` "action must be defined"
|
this `fails with` "action must be defined"
|
||||||
}
|
}
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
// wrong source
|
// wrong source
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBORx", tradeDate, Tenor("3M")), 1.0.bd))) }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBORx", tradeDate, Tenor("3M")), 1.0.bd))))
|
||||||
|
|
||||||
this `fails with` "relevant fixing must be included"
|
this `fails with` "relevant fixing must be included"
|
||||||
}
|
}
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
// wrong date
|
// wrong date
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", tradeDate.plusYears(1), Tenor("3M")), 1.0.bd))) }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", tradeDate.plusYears(1), Tenor("3M")), 1.0.bd))))
|
||||||
|
|
||||||
this `fails with` "relevant fixing must be included"
|
this `fails with` "relevant fixing must be included"
|
||||||
}
|
}
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
// wrong tenor
|
// wrong tenor
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", tradeDate, Tenor("9M")), 1.0.bd))) }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", tradeDate, Tenor("9M")), 1.0.bd))))
|
||||||
|
|
||||||
this `fails with` "relevant fixing must be included"
|
this `fails with` "relevant fixing must be included"
|
||||||
}
|
}
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", tradeDate, Tenor("3M")), 1.5.bd))) }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", tradeDate, Tenor("3M")), 1.5.bd))))
|
||||||
|
|
||||||
this `fails with` "output state does not reflect fix command"
|
this `fails with` "output state does not reflect fix command"
|
||||||
}
|
}
|
||||||
|
command(highStreetBank.owningKey, UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", tradeDate, Tenor("3M")), 1.0.bd))))
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", tradeDate, Tenor("3M")), 1.0.bd))) }
|
|
||||||
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -234,19 +226,16 @@ class Cap {
|
|||||||
@Test
|
@Test
|
||||||
fun `first execute`() {
|
fun `first execute`() {
|
||||||
transaction {
|
transaction {
|
||||||
input(UNIVERSAL_PROGRAM_ID) { stateAfterFixingFirst }
|
input(UNIVERSAL_PROGRAM_ID, stateAfterFixingFirst)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { stateAfterExecutionFirst }
|
output(UNIVERSAL_PROGRAM_ID, stateAfterExecutionFirst)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { statePaymentFirst }
|
output(UNIVERSAL_PROGRAM_ID, statePaymentFirst)
|
||||||
|
|
||||||
timeWindow(TEST_TX_TIME_1)
|
timeWindow(TEST_TX_TIME_1)
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("some undefined name") }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Action("some undefined name"))
|
||||||
this `fails with` "action must be defined"
|
this `fails with` "action must be defined"
|
||||||
}
|
}
|
||||||
|
command(highStreetBank.owningKey, UniversalContract.Commands.Action("exercise"))
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("exercise") }
|
|
||||||
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -254,18 +243,15 @@ class Cap {
|
|||||||
@Test
|
@Test
|
||||||
fun `final execute`() {
|
fun `final execute`() {
|
||||||
transaction {
|
transaction {
|
||||||
input(UNIVERSAL_PROGRAM_ID) { stateAfterFixingFinal }
|
input(UNIVERSAL_PROGRAM_ID, stateAfterFixingFinal)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { statePaymentFinal }
|
output(UNIVERSAL_PROGRAM_ID, statePaymentFinal)
|
||||||
|
|
||||||
timeWindow(TEST_TX_TIME_1)
|
timeWindow(TEST_TX_TIME_1)
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("some undefined name") }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Action("some undefined name"))
|
||||||
this `fails with` "action must be defined"
|
this `fails with` "action must be defined"
|
||||||
}
|
}
|
||||||
|
command(highStreetBank.owningKey, UniversalContract.Commands.Action("exercise"))
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("exercise") }
|
|
||||||
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -273,44 +259,38 @@ class Cap {
|
|||||||
@Test
|
@Test
|
||||||
fun `second fixing`() {
|
fun `second fixing`() {
|
||||||
transaction {
|
transaction {
|
||||||
input(UNIVERSAL_PROGRAM_ID) { stateAfterExecutionFirst }
|
input(UNIVERSAL_PROGRAM_ID, stateAfterExecutionFirst)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { stateAfterFixingFinal }
|
output(UNIVERSAL_PROGRAM_ID, stateAfterFixingFinal)
|
||||||
timeWindow(TEST_TX_TIME_1)
|
timeWindow(TEST_TX_TIME_1)
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("some undefined name") }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Action("some undefined name"))
|
||||||
this `fails with` "action must be defined"
|
this `fails with` "action must be defined"
|
||||||
}
|
}
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
// wrong source
|
// wrong source
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBORx", BusinessCalendar.parseDateFromString("2017-03-01"), Tenor("3M")), 1.0.bd))) }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBORx", BusinessCalendar.parseDateFromString("2017-03-01"), Tenor("3M")), 1.0.bd))))
|
||||||
|
|
||||||
this `fails with` "relevant fixing must be included"
|
this `fails with` "relevant fixing must be included"
|
||||||
}
|
}
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
// wrong date
|
// wrong date
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", BusinessCalendar.parseDateFromString("2017-03-01").plusYears(1), Tenor("3M")), 1.0.bd))) }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", BusinessCalendar.parseDateFromString("2017-03-01").plusYears(1), Tenor("3M")), 1.0.bd))))
|
||||||
|
|
||||||
this `fails with` "relevant fixing must be included"
|
this `fails with` "relevant fixing must be included"
|
||||||
}
|
}
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
// wrong tenor
|
// wrong tenor
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", BusinessCalendar.parseDateFromString("2017-03-01"), Tenor("9M")), 1.0.bd))) }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", BusinessCalendar.parseDateFromString("2017-03-01"), Tenor("9M")), 1.0.bd))))
|
||||||
|
|
||||||
this `fails with` "relevant fixing must be included"
|
this `fails with` "relevant fixing must be included"
|
||||||
}
|
}
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", BusinessCalendar.parseDateFromString("2017-03-01"), Tenor("3M")), 1.5.bd))) }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", BusinessCalendar.parseDateFromString("2017-03-01"), Tenor("3M")), 1.5.bd))))
|
||||||
|
|
||||||
this `fails with` "output state does not reflect fix command"
|
this `fails with` "output state does not reflect fix command"
|
||||||
}
|
}
|
||||||
|
command(highStreetBank.owningKey, UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", BusinessCalendar.parseDateFromString("2017-03-01"), Tenor("3M")), 1.0.bd))))
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", BusinessCalendar.parseDateFromString("2017-03-01"), Tenor("3M")), 1.0.bd))) }
|
|
||||||
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,16 +55,14 @@ class Caplet {
|
|||||||
@Test
|
@Test
|
||||||
fun issue() {
|
fun issue() {
|
||||||
transaction {
|
transaction {
|
||||||
output(UNIVERSAL_PROGRAM_ID) { stateStart }
|
output(UNIVERSAL_PROGRAM_ID, stateStart)
|
||||||
timeWindow(TEST_TX_TIME_1)
|
timeWindow(TEST_TX_TIME_1)
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(acmeCorp.owningKey) { UniversalContract.Commands.Issue() }
|
command(acmeCorp.owningKey, UniversalContract.Commands.Issue())
|
||||||
this `fails with` "the transaction is signed by all liable parties"
|
this `fails with` "the transaction is signed by all liable parties"
|
||||||
}
|
}
|
||||||
|
command(highStreetBank.owningKey, UniversalContract.Commands.Issue())
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Issue() }
|
|
||||||
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -72,17 +70,15 @@ class Caplet {
|
|||||||
@Test
|
@Test
|
||||||
fun `execute`() {
|
fun `execute`() {
|
||||||
transaction {
|
transaction {
|
||||||
input(UNIVERSAL_PROGRAM_ID) { stateFixed }
|
input(UNIVERSAL_PROGRAM_ID, stateFixed)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { stateFinal }
|
output(UNIVERSAL_PROGRAM_ID, stateFinal)
|
||||||
timeWindow(TEST_TX_TIME_1)
|
timeWindow(TEST_TX_TIME_1)
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("some undefined name") }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Action("some undefined name"))
|
||||||
this `fails with` "action must be defined"
|
this `fails with` "action must be defined"
|
||||||
}
|
}
|
||||||
|
command(highStreetBank.owningKey, UniversalContract.Commands.Action("exercise"))
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("exercise") }
|
|
||||||
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -90,44 +86,38 @@ class Caplet {
|
|||||||
@Test
|
@Test
|
||||||
fun `fixing`() {
|
fun `fixing`() {
|
||||||
transaction {
|
transaction {
|
||||||
input(UNIVERSAL_PROGRAM_ID) { stateStart }
|
input(UNIVERSAL_PROGRAM_ID, stateStart)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { stateFixed }
|
output(UNIVERSAL_PROGRAM_ID, stateFixed)
|
||||||
timeWindow(TEST_TX_TIME_1)
|
timeWindow(TEST_TX_TIME_1)
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("some undefined name") }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Action("some undefined name"))
|
||||||
this `fails with` "action must be defined"
|
this `fails with` "action must be defined"
|
||||||
}
|
}
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
// wrong source
|
// wrong source
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBORx", tradeDate, Tenor("6M")), 1.0.bd))) }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBORx", tradeDate, Tenor("6M")), 1.0.bd))))
|
||||||
|
|
||||||
this `fails with` "relevant fixing must be included"
|
this `fails with` "relevant fixing must be included"
|
||||||
}
|
}
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
// wrong date
|
// wrong date
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", tradeDate.plusYears(1), Tenor("6M")), 1.0.bd))) }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", tradeDate.plusYears(1), Tenor("6M")), 1.0.bd))))
|
||||||
|
|
||||||
this `fails with` "relevant fixing must be included"
|
this `fails with` "relevant fixing must be included"
|
||||||
}
|
}
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
// wrong tenor
|
// wrong tenor
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", tradeDate, Tenor("3M")), 1.0.bd))) }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", tradeDate, Tenor("3M")), 1.0.bd))))
|
||||||
|
|
||||||
this `fails with` "relevant fixing must be included"
|
this `fails with` "relevant fixing must be included"
|
||||||
}
|
}
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", tradeDate, Tenor("6M")), 1.5.bd))) }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", tradeDate, Tenor("6M")), 1.5.bd))))
|
||||||
|
|
||||||
this `fails with` "output state does not reflect fix command"
|
this `fails with` "output state does not reflect fix command"
|
||||||
}
|
}
|
||||||
|
command(highStreetBank.owningKey, UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", tradeDate, Tenor("6M")), 1.0.bd))))
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", tradeDate, Tenor("6M")), 1.0.bd))) }
|
|
||||||
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,20 +52,18 @@ class FXFwdTimeOption {
|
|||||||
@Test
|
@Test
|
||||||
fun `issue - signature`() {
|
fun `issue - signature`() {
|
||||||
transaction {
|
transaction {
|
||||||
output(UNIVERSAL_PROGRAM_ID) { inState }
|
output(UNIVERSAL_PROGRAM_ID, inState)
|
||||||
timeWindow(TEST_TX_TIME_1)
|
timeWindow(TEST_TX_TIME_1)
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(acmeCorp.owningKey) { UniversalContract.Commands.Issue() }
|
command(acmeCorp.owningKey, UniversalContract.Commands.Issue())
|
||||||
this `fails with` "the transaction is signed by all liable parties"
|
this `fails with` "the transaction is signed by all liable parties"
|
||||||
}
|
}
|
||||||
tweak {
|
tweak {
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Issue() }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Issue())
|
||||||
this `fails with` "the transaction is signed by all liable parties"
|
this `fails with` "the transaction is signed by all liable parties"
|
||||||
}
|
}
|
||||||
|
command(listOf(highStreetBank.owningKey, acmeCorp.owningKey), UniversalContract.Commands.Issue())
|
||||||
command(highStreetBank.owningKey, acmeCorp.owningKey) { UniversalContract.Commands.Issue() }
|
|
||||||
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -73,31 +71,28 @@ class FXFwdTimeOption {
|
|||||||
@Test
|
@Test
|
||||||
fun `maturity, bank exercise`() {
|
fun `maturity, bank exercise`() {
|
||||||
transaction {
|
transaction {
|
||||||
input(UNIVERSAL_PROGRAM_ID) { inState }
|
input(UNIVERSAL_PROGRAM_ID, inState)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { outState1 }
|
output(UNIVERSAL_PROGRAM_ID, outState1)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { outState2 }
|
output(UNIVERSAL_PROGRAM_ID, outState2)
|
||||||
|
|
||||||
timeWindow(TEST_TX_TIME_AFTER_MATURITY)
|
timeWindow(TEST_TX_TIME_AFTER_MATURITY)
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("some undefined name") }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Action("some undefined name"))
|
||||||
this `fails with` "action must be defined"
|
this `fails with` "action must be defined"
|
||||||
}
|
}
|
||||||
tweak {
|
tweak {
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("exercise") }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Action("exercise"))
|
||||||
this `fails with` "condition must be met"
|
this `fails with` "condition must be met"
|
||||||
}
|
}
|
||||||
tweak {
|
tweak {
|
||||||
command(acmeCorp.owningKey) { UniversalContract.Commands.Action("exercise") }
|
command(acmeCorp.owningKey, UniversalContract.Commands.Action("exercise"))
|
||||||
this `fails with` "condition must be met"
|
this `fails with` "condition must be met"
|
||||||
}
|
}
|
||||||
tweak {
|
tweak {
|
||||||
command(acmeCorp.owningKey) { UniversalContract.Commands.Action("expire") }
|
command(acmeCorp.owningKey, UniversalContract.Commands.Action("expire"))
|
||||||
this `fails with` "condition must be met"
|
this `fails with` "condition must be met"
|
||||||
}
|
}
|
||||||
|
command(highStreetBank.owningKey, UniversalContract.Commands.Action("expire"))
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("expire") }
|
|
||||||
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,31 +100,28 @@ class FXFwdTimeOption {
|
|||||||
@Test
|
@Test
|
||||||
fun `maturity, corp exercise`() {
|
fun `maturity, corp exercise`() {
|
||||||
transaction {
|
transaction {
|
||||||
input(UNIVERSAL_PROGRAM_ID) { inState }
|
input(UNIVERSAL_PROGRAM_ID, inState)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { outState1 }
|
output(UNIVERSAL_PROGRAM_ID, outState1)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { outState2 }
|
output(UNIVERSAL_PROGRAM_ID, outState2)
|
||||||
|
|
||||||
timeWindow(TEST_TX_TIME_BEFORE_MATURITY)
|
timeWindow(TEST_TX_TIME_BEFORE_MATURITY)
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(acmeCorp.owningKey) { UniversalContract.Commands.Action("some undefined name") }
|
command(acmeCorp.owningKey, UniversalContract.Commands.Action("some undefined name"))
|
||||||
this `fails with` "action must be defined"
|
this `fails with` "action must be defined"
|
||||||
}
|
}
|
||||||
tweak {
|
tweak {
|
||||||
command(acmeCorp.owningKey) { UniversalContract.Commands.Action("expire") }
|
command(acmeCorp.owningKey, UniversalContract.Commands.Action("expire"))
|
||||||
this `fails with` "condition must be met"
|
this `fails with` "condition must be met"
|
||||||
}
|
}
|
||||||
tweak {
|
tweak {
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("expire") }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Action("expire"))
|
||||||
this `fails with` "condition must be met"
|
this `fails with` "condition must be met"
|
||||||
}
|
}
|
||||||
tweak {
|
tweak {
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("exercise") }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Action("exercise"))
|
||||||
this `fails with` "condition must be met"
|
this `fails with` "condition must be met"
|
||||||
}
|
}
|
||||||
|
command(acmeCorp.owningKey, UniversalContract.Commands.Action("exercise"))
|
||||||
command(acmeCorp.owningKey) { UniversalContract.Commands.Action("exercise") }
|
|
||||||
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,20 +44,18 @@ class FXSwap {
|
|||||||
fun `issue - signature`() {
|
fun `issue - signature`() {
|
||||||
|
|
||||||
transaction {
|
transaction {
|
||||||
output(UNIVERSAL_PROGRAM_ID) { inState }
|
output(UNIVERSAL_PROGRAM_ID, inState)
|
||||||
timeWindow(TEST_TX_TIME_1)
|
timeWindow(TEST_TX_TIME_1)
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(acmeCorp.owningKey) { UniversalContract.Commands.Issue() }
|
command(acmeCorp.owningKey, UniversalContract.Commands.Issue())
|
||||||
this `fails with` "the transaction is signed by all liable parties"
|
this `fails with` "the transaction is signed by all liable parties"
|
||||||
}
|
}
|
||||||
tweak {
|
tweak {
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Issue() }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Issue())
|
||||||
this `fails with` "the transaction is signed by all liable parties"
|
this `fails with` "the transaction is signed by all liable parties"
|
||||||
}
|
}
|
||||||
|
command(listOf(highStreetBank.owningKey, acmeCorp.owningKey), UniversalContract.Commands.Issue())
|
||||||
command(highStreetBank.owningKey, acmeCorp.owningKey) { UniversalContract.Commands.Issue() }
|
|
||||||
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,18 +63,16 @@ class FXSwap {
|
|||||||
@Test
|
@Test
|
||||||
fun `execute`() {
|
fun `execute`() {
|
||||||
transaction {
|
transaction {
|
||||||
input(UNIVERSAL_PROGRAM_ID) { inState }
|
input(UNIVERSAL_PROGRAM_ID, inState)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { outState1 }
|
output(UNIVERSAL_PROGRAM_ID, outState1)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { outState2 }
|
output(UNIVERSAL_PROGRAM_ID, outState2)
|
||||||
timeWindow(TEST_TX_TIME_1)
|
timeWindow(TEST_TX_TIME_1)
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("some undefined name") }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Action("some undefined name"))
|
||||||
this `fails with` "action must be defined"
|
this `fails with` "action must be defined"
|
||||||
}
|
}
|
||||||
|
command(highStreetBank.owningKey, UniversalContract.Commands.Action("execute"))
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("execute") }
|
|
||||||
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,18 +80,16 @@ class FXSwap {
|
|||||||
@Test
|
@Test
|
||||||
fun `execute - reversed order`() {
|
fun `execute - reversed order`() {
|
||||||
transaction {
|
transaction {
|
||||||
input(UNIVERSAL_PROGRAM_ID) { inState }
|
input(UNIVERSAL_PROGRAM_ID, inState)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { outState2 }
|
output(UNIVERSAL_PROGRAM_ID, outState2)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { outState1 }
|
output(UNIVERSAL_PROGRAM_ID, outState1)
|
||||||
timeWindow(TEST_TX_TIME_1)
|
timeWindow(TEST_TX_TIME_1)
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("some undefined name") }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Action("some undefined name"))
|
||||||
this `fails with` "action must be defined"
|
this `fails with` "action must be defined"
|
||||||
}
|
}
|
||||||
|
command(highStreetBank.owningKey, UniversalContract.Commands.Action("execute"))
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("execute") }
|
|
||||||
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -103,12 +97,11 @@ class FXSwap {
|
|||||||
@Test
|
@Test
|
||||||
fun `execute - not authorized`() {
|
fun `execute - not authorized`() {
|
||||||
transaction {
|
transaction {
|
||||||
input(UNIVERSAL_PROGRAM_ID) { inState }
|
input(UNIVERSAL_PROGRAM_ID, inState)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { outState1 }
|
output(UNIVERSAL_PROGRAM_ID, outState1)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { outState2 }
|
output(UNIVERSAL_PROGRAM_ID, outState2)
|
||||||
timeWindow(TEST_TX_TIME_1)
|
timeWindow(TEST_TX_TIME_1)
|
||||||
|
command(momAndPop.owningKey, UniversalContract.Commands.Action("execute"))
|
||||||
command(momAndPop.owningKey) { UniversalContract.Commands.Action("execute") }
|
|
||||||
this `fails with` "condition must be met"
|
this `fails with` "condition must be met"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,12 +109,11 @@ class FXSwap {
|
|||||||
@Test
|
@Test
|
||||||
fun `execute - before maturity`() {
|
fun `execute - before maturity`() {
|
||||||
transaction {
|
transaction {
|
||||||
input(UNIVERSAL_PROGRAM_ID) { inState }
|
input(UNIVERSAL_PROGRAM_ID, inState)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { outState1 }
|
output(UNIVERSAL_PROGRAM_ID, outState1)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { outState2 }
|
output(UNIVERSAL_PROGRAM_ID, outState2)
|
||||||
timeWindow(TEST_TX_TIME_TOO_EARLY)
|
timeWindow(TEST_TX_TIME_TOO_EARLY)
|
||||||
|
command(acmeCorp.owningKey, UniversalContract.Commands.Action("execute"))
|
||||||
command(acmeCorp.owningKey) { UniversalContract.Commands.Action("execute") }
|
|
||||||
this `fails with` "condition must be met"
|
this `fails with` "condition must be met"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -129,11 +121,10 @@ class FXSwap {
|
|||||||
@Test
|
@Test
|
||||||
fun `execute - outState mismatch 1`() {
|
fun `execute - outState mismatch 1`() {
|
||||||
transaction {
|
transaction {
|
||||||
input(UNIVERSAL_PROGRAM_ID) { inState }
|
input(UNIVERSAL_PROGRAM_ID, inState)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { outState1 }
|
output(UNIVERSAL_PROGRAM_ID, outState1)
|
||||||
timeWindow(TEST_TX_TIME_1)
|
timeWindow(TEST_TX_TIME_1)
|
||||||
|
command(acmeCorp.owningKey, UniversalContract.Commands.Action("execute"))
|
||||||
command(acmeCorp.owningKey) { UniversalContract.Commands.Action("execute") }
|
|
||||||
this `fails with` "output state must match action result state"
|
this `fails with` "output state must match action result state"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -141,12 +132,11 @@ class FXSwap {
|
|||||||
@Test
|
@Test
|
||||||
fun `execute - outState mismatch 2`() {
|
fun `execute - outState mismatch 2`() {
|
||||||
transaction {
|
transaction {
|
||||||
input(UNIVERSAL_PROGRAM_ID) { inState }
|
input(UNIVERSAL_PROGRAM_ID, inState)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { outState1 }
|
output(UNIVERSAL_PROGRAM_ID, outState1)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { outStateBad2 }
|
output(UNIVERSAL_PROGRAM_ID, outStateBad2)
|
||||||
timeWindow(TEST_TX_TIME_1)
|
timeWindow(TEST_TX_TIME_1)
|
||||||
|
command(acmeCorp.owningKey, UniversalContract.Commands.Action("execute"))
|
||||||
command(acmeCorp.owningKey) { UniversalContract.Commands.Action("execute") }
|
|
||||||
this `fails with` "output states must match action result state"
|
this `fails with` "output states must match action result state"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -154,12 +144,11 @@ class FXSwap {
|
|||||||
@Test
|
@Test
|
||||||
fun `execute - outState mismatch 3`() {
|
fun `execute - outState mismatch 3`() {
|
||||||
transaction {
|
transaction {
|
||||||
input(UNIVERSAL_PROGRAM_ID) { inState }
|
input(UNIVERSAL_PROGRAM_ID, inState)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { outStateBad1 }
|
output(UNIVERSAL_PROGRAM_ID, outStateBad1)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { outState2 }
|
output(UNIVERSAL_PROGRAM_ID, outState2)
|
||||||
timeWindow(TEST_TX_TIME_1)
|
timeWindow(TEST_TX_TIME_1)
|
||||||
|
command(acmeCorp.owningKey, UniversalContract.Commands.Action("execute"))
|
||||||
command(acmeCorp.owningKey) { UniversalContract.Commands.Action("execute") }
|
|
||||||
this `fails with` "output states must match action result state"
|
this `fails with` "output states must match action result state"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -167,12 +156,11 @@ class FXSwap {
|
|||||||
@Test
|
@Test
|
||||||
fun `execute - outState mismatch 4`() {
|
fun `execute - outState mismatch 4`() {
|
||||||
transaction {
|
transaction {
|
||||||
input(UNIVERSAL_PROGRAM_ID) { inState }
|
input(UNIVERSAL_PROGRAM_ID, inState)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { outState1 }
|
output(UNIVERSAL_PROGRAM_ID, outState1)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { outStateBad3 }
|
output(UNIVERSAL_PROGRAM_ID, outStateBad3)
|
||||||
timeWindow(TEST_TX_TIME_1)
|
timeWindow(TEST_TX_TIME_1)
|
||||||
|
command(acmeCorp.owningKey, UniversalContract.Commands.Action("execute"))
|
||||||
command(acmeCorp.owningKey) { UniversalContract.Commands.Action("execute") }
|
|
||||||
this `fails with` "output states must match action result state"
|
this `fails with` "output states must match action result state"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,16 +134,14 @@ class IRS {
|
|||||||
@Test
|
@Test
|
||||||
fun issue() {
|
fun issue() {
|
||||||
transaction {
|
transaction {
|
||||||
output(UNIVERSAL_PROGRAM_ID) { stateInitial }
|
output(UNIVERSAL_PROGRAM_ID, stateInitial)
|
||||||
timeWindow(TEST_TX_TIME_1)
|
timeWindow(TEST_TX_TIME_1)
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(acmeCorp.owningKey) { UniversalContract.Commands.Issue() }
|
command(acmeCorp.owningKey, UniversalContract.Commands.Issue())
|
||||||
this `fails with` "the transaction is signed by all liable parties"
|
this `fails with` "the transaction is signed by all liable parties"
|
||||||
}
|
}
|
||||||
|
command(highStreetBank.owningKey, UniversalContract.Commands.Issue())
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Issue() }
|
|
||||||
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -151,44 +149,38 @@ class IRS {
|
|||||||
@Test
|
@Test
|
||||||
fun `first fixing`() {
|
fun `first fixing`() {
|
||||||
transaction {
|
transaction {
|
||||||
input(UNIVERSAL_PROGRAM_ID) { stateInitial }
|
input(UNIVERSAL_PROGRAM_ID, stateInitial)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { stateAfterFixingFirst }
|
output(UNIVERSAL_PROGRAM_ID, stateAfterFixingFirst)
|
||||||
timeWindow(TEST_TX_TIME_1)
|
timeWindow(TEST_TX_TIME_1)
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("some undefined name") }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Action("some undefined name"))
|
||||||
this `fails with` "action must be defined"
|
this `fails with` "action must be defined"
|
||||||
}
|
}
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
// wrong source
|
// wrong source
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBORx", tradeDate, Tenor("3M")), 1.0.bd))) }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBORx", tradeDate, Tenor("3M")), 1.0.bd))))
|
||||||
|
|
||||||
this `fails with` "relevant fixing must be included"
|
this `fails with` "relevant fixing must be included"
|
||||||
}
|
}
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
// wrong date
|
// wrong date
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", tradeDate.plusYears(1), Tenor("3M")), 1.0.bd))) }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", tradeDate.plusYears(1), Tenor("3M")), 1.0.bd))))
|
||||||
|
|
||||||
this `fails with` "relevant fixing must be included"
|
this `fails with` "relevant fixing must be included"
|
||||||
}
|
}
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
// wrong tenor
|
// wrong tenor
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", tradeDate, Tenor("9M")), 1.0.bd))) }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", tradeDate, Tenor("9M")), 1.0.bd))))
|
||||||
|
|
||||||
this `fails with` "relevant fixing must be included"
|
this `fails with` "relevant fixing must be included"
|
||||||
}
|
}
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", tradeDate, Tenor("3M")), 1.5.bd))) }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", tradeDate, Tenor("3M")), 1.5.bd))))
|
||||||
|
|
||||||
this `fails with` "output state does not reflect fix command"
|
this `fails with` "output state does not reflect fix command"
|
||||||
}
|
}
|
||||||
|
command(highStreetBank.owningKey, UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", tradeDate, Tenor("3M")), 1.0.bd))))
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(net.corda.finance.contracts.Fix(FixOf("LIBOR", tradeDate, Tenor("3M")), 1.0.bd))) }
|
|
||||||
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -196,19 +188,16 @@ class IRS {
|
|||||||
@Test
|
@Test
|
||||||
fun `first execute`() {
|
fun `first execute`() {
|
||||||
transaction {
|
transaction {
|
||||||
input(UNIVERSAL_PROGRAM_ID) { stateAfterFixingFirst }
|
input(UNIVERSAL_PROGRAM_ID, stateAfterFixingFirst)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { stateAfterExecutionFirst }
|
output(UNIVERSAL_PROGRAM_ID, stateAfterExecutionFirst)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { statePaymentFirst }
|
output(UNIVERSAL_PROGRAM_ID, statePaymentFirst)
|
||||||
|
|
||||||
timeWindow(TEST_TX_TIME_1)
|
timeWindow(TEST_TX_TIME_1)
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("some undefined name") }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Action("some undefined name"))
|
||||||
this `fails with` "action must be defined"
|
this `fails with` "action must be defined"
|
||||||
}
|
}
|
||||||
|
command(highStreetBank.owningKey, UniversalContract.Commands.Action("pay floating"))
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("pay floating") }
|
|
||||||
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,16 +145,14 @@ class RollOutTests {
|
|||||||
@Test
|
@Test
|
||||||
fun issue() {
|
fun issue() {
|
||||||
transaction {
|
transaction {
|
||||||
output(UNIVERSAL_PROGRAM_ID) { stateStart }
|
output(UNIVERSAL_PROGRAM_ID, stateStart)
|
||||||
timeWindow(TEST_TX_TIME_1)
|
timeWindow(TEST_TX_TIME_1)
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(acmeCorp.owningKey) { UniversalContract.Commands.Issue() }
|
command(acmeCorp.owningKey, UniversalContract.Commands.Issue())
|
||||||
this `fails with` "the transaction is signed by all liable parties"
|
this `fails with` "the transaction is signed by all liable parties"
|
||||||
}
|
}
|
||||||
|
command(highStreetBank.owningKey, UniversalContract.Commands.Issue())
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Issue() }
|
|
||||||
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -162,18 +160,16 @@ class RollOutTests {
|
|||||||
@Test
|
@Test
|
||||||
fun `execute`() {
|
fun `execute`() {
|
||||||
transaction {
|
transaction {
|
||||||
input(UNIVERSAL_PROGRAM_ID) { stateStart }
|
input(UNIVERSAL_PROGRAM_ID, stateStart)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { stateStep1a }
|
output(UNIVERSAL_PROGRAM_ID, stateStep1a)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { stateStep1b }
|
output(UNIVERSAL_PROGRAM_ID, stateStep1b)
|
||||||
timeWindow(TEST_TX_TIME_1)
|
timeWindow(TEST_TX_TIME_1)
|
||||||
|
|
||||||
/* tweak {
|
/* tweak {
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("some undefined name") }
|
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("some undefined name") }
|
||||||
this `fails with` "action must be defined"
|
this `fails with` "action must be defined"
|
||||||
}*/
|
}*/
|
||||||
|
command(highStreetBank.owningKey, UniversalContract.Commands.Action("transfer"))
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("transfer") }
|
|
||||||
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,16 +61,14 @@ class Swaption {
|
|||||||
@Test
|
@Test
|
||||||
fun issue() {
|
fun issue() {
|
||||||
transaction {
|
transaction {
|
||||||
output(UNIVERSAL_PROGRAM_ID) { stateInitial }
|
output(UNIVERSAL_PROGRAM_ID, stateInitial)
|
||||||
timeWindow(TEST_TX_TIME_1)
|
timeWindow(TEST_TX_TIME_1)
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(acmeCorp.owningKey) { UniversalContract.Commands.Issue() }
|
command(acmeCorp.owningKey, UniversalContract.Commands.Issue())
|
||||||
this `fails with` "the transaction is signed by all liable parties"
|
this `fails with` "the transaction is signed by all liable parties"
|
||||||
}
|
}
|
||||||
|
command(highStreetBank.owningKey, UniversalContract.Commands.Issue())
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Issue() }
|
|
||||||
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,15 +51,12 @@ class ZeroCouponBond {
|
|||||||
@Test
|
@Test
|
||||||
fun `issue - signature`() {
|
fun `issue - signature`() {
|
||||||
transaction {
|
transaction {
|
||||||
output(UNIVERSAL_PROGRAM_ID) { inState }
|
output(UNIVERSAL_PROGRAM_ID, inState)
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(acmeCorp.owningKey) { UniversalContract.Commands.Issue() }
|
command(acmeCorp.owningKey, UniversalContract.Commands.Issue())
|
||||||
this `fails with` "the transaction is signed by all liable parties"
|
this `fails with` "the transaction is signed by all liable parties"
|
||||||
}
|
}
|
||||||
|
command(highStreetBank.owningKey, UniversalContract.Commands.Issue())
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Issue() }
|
|
||||||
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -67,17 +64,15 @@ class ZeroCouponBond {
|
|||||||
@Test
|
@Test
|
||||||
fun `execute`() {
|
fun `execute`() {
|
||||||
transaction {
|
transaction {
|
||||||
input(UNIVERSAL_PROGRAM_ID) { inState }
|
input(UNIVERSAL_PROGRAM_ID, inState)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { outState }
|
output(UNIVERSAL_PROGRAM_ID, outState)
|
||||||
timeWindow(TEST_TX_TIME_1)
|
timeWindow(TEST_TX_TIME_1)
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("some undefined name") }
|
command(highStreetBank.owningKey, UniversalContract.Commands.Action("some undefined name"))
|
||||||
this `fails with` "action must be defined"
|
this `fails with` "action must be defined"
|
||||||
}
|
}
|
||||||
|
command(highStreetBank.owningKey, UniversalContract.Commands.Action("execute"))
|
||||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("execute") }
|
|
||||||
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,11 +80,10 @@ class ZeroCouponBond {
|
|||||||
@Test
|
@Test
|
||||||
fun `execute - not authorized`() {
|
fun `execute - not authorized`() {
|
||||||
transaction {
|
transaction {
|
||||||
input(UNIVERSAL_PROGRAM_ID) { inState }
|
input(UNIVERSAL_PROGRAM_ID, inState)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { outState }
|
output(UNIVERSAL_PROGRAM_ID, outState)
|
||||||
timeWindow(TEST_TX_TIME_1)
|
timeWindow(TEST_TX_TIME_1)
|
||||||
|
command(momAndPop.owningKey, UniversalContract.Commands.Action("execute"))
|
||||||
command(momAndPop.owningKey) { UniversalContract.Commands.Action("execute") }
|
|
||||||
this `fails with` "condition must be met"
|
this `fails with` "condition must be met"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,11 +91,10 @@ class ZeroCouponBond {
|
|||||||
@Test
|
@Test
|
||||||
fun `execute - outState mismatch`() {
|
fun `execute - outState mismatch`() {
|
||||||
transaction {
|
transaction {
|
||||||
input(UNIVERSAL_PROGRAM_ID) { inState }
|
input(UNIVERSAL_PROGRAM_ID, inState)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { outStateWrong }
|
output(UNIVERSAL_PROGRAM_ID, outStateWrong)
|
||||||
timeWindow(TEST_TX_TIME_1)
|
timeWindow(TEST_TX_TIME_1)
|
||||||
|
command(acmeCorp.owningKey, UniversalContract.Commands.Action("execute"))
|
||||||
command(acmeCorp.owningKey) { UniversalContract.Commands.Action("execute") }
|
|
||||||
this `fails with` "output state must match action result state"
|
this `fails with` "output state must match action result state"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,29 +102,23 @@ class ZeroCouponBond {
|
|||||||
@Test
|
@Test
|
||||||
fun move() {
|
fun move() {
|
||||||
transaction {
|
transaction {
|
||||||
input(UNIVERSAL_PROGRAM_ID) { inState }
|
input(UNIVERSAL_PROGRAM_ID, inState)
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
output(UNIVERSAL_PROGRAM_ID) { outStateMove }
|
output(UNIVERSAL_PROGRAM_ID, outStateMove)
|
||||||
command(acmeCorp.owningKey) {
|
command(acmeCorp.owningKey,
|
||||||
UniversalContract.Commands.Move(acmeCorp, momAndPop)
|
UniversalContract.Commands.Move(acmeCorp, momAndPop))
|
||||||
}
|
|
||||||
this `fails with` "the transaction is signed by all liable parties"
|
this `fails with` "the transaction is signed by all liable parties"
|
||||||
}
|
}
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
output(UNIVERSAL_PROGRAM_ID) { inState }
|
output(UNIVERSAL_PROGRAM_ID, inState)
|
||||||
command(acmeCorp.owningKey, momAndPop.owningKey, highStreetBank.owningKey) {
|
command(listOf(acmeCorp.owningKey, momAndPop.owningKey, highStreetBank.owningKey),
|
||||||
UniversalContract.Commands.Move(acmeCorp, momAndPop)
|
UniversalContract.Commands.Move(acmeCorp, momAndPop))
|
||||||
}
|
|
||||||
this `fails with` "output state does not reflect move command"
|
this `fails with` "output state does not reflect move command"
|
||||||
}
|
}
|
||||||
|
output(UNIVERSAL_PROGRAM_ID, outStateMove)
|
||||||
output(UNIVERSAL_PROGRAM_ID) { outStateMove }
|
command(listOf(acmeCorp.owningKey, momAndPop.owningKey, highStreetBank.owningKey),
|
||||||
|
UniversalContract.Commands.Move(acmeCorp, momAndPop))
|
||||||
command(acmeCorp.owningKey, momAndPop.owningKey, highStreetBank.owningKey) {
|
|
||||||
UniversalContract.Commands.Move(acmeCorp, momAndPop)
|
|
||||||
}
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,34 +32,34 @@ public class CashTestsJava {
|
|||||||
tx.input(Cash.PROGRAM_ID, inState);
|
tx.input(Cash.PROGRAM_ID, inState);
|
||||||
|
|
||||||
tx.tweak(tw -> {
|
tx.tweak(tw -> {
|
||||||
tw.output(Cash.PROGRAM_ID, () -> new Cash.State(issuedBy(DOLLARS(2000), defaultIssuer), new AnonymousParty(getMINI_CORP_PUBKEY())));
|
tw.output(Cash.PROGRAM_ID, new Cash.State(issuedBy(DOLLARS(2000), defaultIssuer), new AnonymousParty(getMINI_CORP_PUBKEY())));
|
||||||
tw.command(getMEGA_CORP_PUBKEY(), new Cash.Commands.Move());
|
tw.command(getMEGA_CORP_PUBKEY(), new Cash.Commands.Move());
|
||||||
return tw.failsWith("the amounts balance");
|
return tw.failsWith("the amounts balance");
|
||||||
});
|
});
|
||||||
|
|
||||||
tx.tweak(tw -> {
|
tx.tweak(tw -> {
|
||||||
tw.output(Cash.PROGRAM_ID, () -> outState);
|
tw.output(Cash.PROGRAM_ID, outState);
|
||||||
tw.command(getMEGA_CORP_PUBKEY(), DummyCommandData.INSTANCE);
|
tw.command(getMEGA_CORP_PUBKEY(), DummyCommandData.INSTANCE);
|
||||||
// Invalid command
|
// Invalid command
|
||||||
return tw.failsWith("required net.corda.finance.contracts.asset.Cash.Commands.Move command");
|
return tw.failsWith("required net.corda.finance.contracts.asset.Cash.Commands.Move command");
|
||||||
});
|
});
|
||||||
tx.tweak(tw -> {
|
tx.tweak(tw -> {
|
||||||
tw.output(Cash.PROGRAM_ID, () -> outState);
|
tw.output(Cash.PROGRAM_ID, outState);
|
||||||
tw.command(getMINI_CORP_PUBKEY(), new Cash.Commands.Move());
|
tw.command(getMINI_CORP_PUBKEY(), new Cash.Commands.Move());
|
||||||
return tw.failsWith("the owning keys are a subset of the signing keys");
|
return tw.failsWith("the owning keys are a subset of the signing keys");
|
||||||
});
|
});
|
||||||
tx.tweak(tw -> {
|
tx.tweak(tw -> {
|
||||||
tw.output(Cash.PROGRAM_ID, () -> outState);
|
tw.output(Cash.PROGRAM_ID, outState);
|
||||||
// issuedBy() can't be directly imported because it conflicts with other identically named functions
|
// issuedBy() can't be directly imported because it conflicts with other identically named functions
|
||||||
// with different overloads (for some reason).
|
// with different overloads (for some reason).
|
||||||
tw.output(Cash.PROGRAM_ID, () -> outState.issuedBy(getMINI_CORP()));
|
tw.output(Cash.PROGRAM_ID, outState.issuedBy(getMINI_CORP()));
|
||||||
tw.command(getMEGA_CORP_PUBKEY(), new Cash.Commands.Move());
|
tw.command(getMEGA_CORP_PUBKEY(), new Cash.Commands.Move());
|
||||||
return tw.failsWith("at least one cash input");
|
return tw.failsWith("at least one cash input");
|
||||||
});
|
});
|
||||||
|
|
||||||
// Simple reallocation works.
|
// Simple reallocation works.
|
||||||
return tx.tweak(tw -> {
|
return tx.tweak(tw -> {
|
||||||
tw.output(Cash.PROGRAM_ID, () -> outState);
|
tw.output(Cash.PROGRAM_ID, outState);
|
||||||
tw.command(getMEGA_CORP_PUBKEY(), new Cash.Commands.Move());
|
tw.command(getMEGA_CORP_PUBKEY(), new Cash.Commands.Move());
|
||||||
return tw.verifies();
|
return tw.verifies();
|
||||||
});
|
});
|
||||||
|
@ -106,8 +106,8 @@ class CommercialPaperTestsGeneric {
|
|||||||
// Some CP is issued onto the ledger by MegaCorp.
|
// Some CP is issued onto the ledger by MegaCorp.
|
||||||
transaction("Issuance") {
|
transaction("Issuance") {
|
||||||
attachments(CP_PROGRAM_ID, JavaCommercialPaper.JCP_PROGRAM_ID)
|
attachments(CP_PROGRAM_ID, JavaCommercialPaper.JCP_PROGRAM_ID)
|
||||||
output(thisTest.getContract(), "paper") { thisTest.getPaper() }
|
output(thisTest.getContract(), "paper", thisTest.getPaper())
|
||||||
command(MEGA_CORP_PUBKEY) { thisTest.getIssueCommand(DUMMY_NOTARY) }
|
command(MEGA_CORP_PUBKEY, thisTest.getIssueCommand(DUMMY_NOTARY))
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
@ -118,10 +118,10 @@ class CommercialPaperTestsGeneric {
|
|||||||
attachments(Cash.PROGRAM_ID, JavaCommercialPaper.JCP_PROGRAM_ID)
|
attachments(Cash.PROGRAM_ID, JavaCommercialPaper.JCP_PROGRAM_ID)
|
||||||
input("paper")
|
input("paper")
|
||||||
input("alice's $900")
|
input("alice's $900")
|
||||||
output(Cash.PROGRAM_ID, "borrowed $900") { 900.DOLLARS.CASH issuedBy issuer ownedBy MEGA_CORP }
|
output(Cash.PROGRAM_ID, "borrowed $900", 900.DOLLARS.CASH issuedBy issuer ownedBy MEGA_CORP)
|
||||||
output(thisTest.getContract(), "alice's paper") { "paper".output<ICommercialPaperState>().withOwner(ALICE) }
|
output(thisTest.getContract(), "alice's paper", "paper".output<ICommercialPaperState>().withOwner(ALICE))
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
command(MEGA_CORP_PUBKEY) { thisTest.getMoveCommand() }
|
command(MEGA_CORP_PUBKEY, thisTest.getMoveCommand())
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,13 +133,11 @@ class CommercialPaperTestsGeneric {
|
|||||||
input("some profits")
|
input("some profits")
|
||||||
|
|
||||||
fun TransactionDSL<TransactionDSLInterpreter>.outputs(aliceGetsBack: Amount<Issued<Currency>>) {
|
fun TransactionDSL<TransactionDSLInterpreter>.outputs(aliceGetsBack: Amount<Issued<Currency>>) {
|
||||||
output(Cash.PROGRAM_ID, "Alice's profit") { aliceGetsBack.STATE ownedBy ALICE }
|
output(Cash.PROGRAM_ID, "Alice's profit", aliceGetsBack.STATE ownedBy ALICE)
|
||||||
output(Cash.PROGRAM_ID, "Change") { (someProfits - aliceGetsBack).STATE ownedBy MEGA_CORP }
|
output(Cash.PROGRAM_ID, "Change", (someProfits - aliceGetsBack).STATE ownedBy MEGA_CORP)
|
||||||
}
|
}
|
||||||
|
command(MEGA_CORP_PUBKEY, Cash.Commands.Move())
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, thisTest.getRedeemCommand(DUMMY_NOTARY))
|
||||||
command(ALICE_PUBKEY) { thisTest.getRedeemCommand(DUMMY_NOTARY) }
|
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
outputs(700.DOLLARS `issued by` issuer)
|
outputs(700.DOLLARS `issued by` issuer)
|
||||||
timeWindow(TEST_TX_TIME + 8.days)
|
timeWindow(TEST_TX_TIME + 8.days)
|
||||||
@ -155,7 +153,7 @@ class CommercialPaperTestsGeneric {
|
|||||||
timeWindow(TEST_TX_TIME + 8.days)
|
timeWindow(TEST_TX_TIME + 8.days)
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
output(thisTest.getContract()) { "paper".output<ICommercialPaperState>() }
|
output(thisTest.getContract(), "paper".output<ICommercialPaperState>())
|
||||||
this `fails with` "must be destroyed"
|
this `fails with` "must be destroyed"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,8 +167,8 @@ class CommercialPaperTestsGeneric {
|
|||||||
transaction {
|
transaction {
|
||||||
attachment(CP_PROGRAM_ID)
|
attachment(CP_PROGRAM_ID)
|
||||||
attachment(JavaCommercialPaper.JCP_PROGRAM_ID)
|
attachment(JavaCommercialPaper.JCP_PROGRAM_ID)
|
||||||
output(thisTest.getContract()) { thisTest.getPaper() }
|
output(thisTest.getContract(), thisTest.getPaper())
|
||||||
command(MINI_CORP_PUBKEY) { thisTest.getIssueCommand(DUMMY_NOTARY) }
|
command(MINI_CORP_PUBKEY, thisTest.getIssueCommand(DUMMY_NOTARY))
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this `fails with` "output states are issued by a command signer"
|
this `fails with` "output states are issued by a command signer"
|
||||||
}
|
}
|
||||||
@ -181,8 +179,8 @@ class CommercialPaperTestsGeneric {
|
|||||||
transaction {
|
transaction {
|
||||||
attachment(CP_PROGRAM_ID)
|
attachment(CP_PROGRAM_ID)
|
||||||
attachment(JavaCommercialPaper.JCP_PROGRAM_ID)
|
attachment(JavaCommercialPaper.JCP_PROGRAM_ID)
|
||||||
output(thisTest.getContract()) { thisTest.getPaper().withFaceValue(0.DOLLARS `issued by` issuer) }
|
output(thisTest.getContract(), thisTest.getPaper().withFaceValue(0.DOLLARS `issued by` issuer))
|
||||||
command(MEGA_CORP_PUBKEY) { thisTest.getIssueCommand(DUMMY_NOTARY) }
|
command(MEGA_CORP_PUBKEY, thisTest.getIssueCommand(DUMMY_NOTARY))
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this `fails with` "output values sum to more than the inputs"
|
this `fails with` "output values sum to more than the inputs"
|
||||||
}
|
}
|
||||||
@ -193,8 +191,8 @@ class CommercialPaperTestsGeneric {
|
|||||||
transaction {
|
transaction {
|
||||||
attachment(CP_PROGRAM_ID)
|
attachment(CP_PROGRAM_ID)
|
||||||
attachment(JavaCommercialPaper.JCP_PROGRAM_ID)
|
attachment(JavaCommercialPaper.JCP_PROGRAM_ID)
|
||||||
output(thisTest.getContract()) { thisTest.getPaper().withMaturityDate(TEST_TX_TIME - 10.days) }
|
output(thisTest.getContract(), thisTest.getPaper().withMaturityDate(TEST_TX_TIME - 10.days))
|
||||||
command(MEGA_CORP_PUBKEY) { thisTest.getIssueCommand(DUMMY_NOTARY) }
|
command(MEGA_CORP_PUBKEY, thisTest.getIssueCommand(DUMMY_NOTARY))
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this `fails with` "maturity date is not in the past"
|
this `fails with` "maturity date is not in the past"
|
||||||
}
|
}
|
||||||
@ -206,8 +204,8 @@ class CommercialPaperTestsGeneric {
|
|||||||
attachment(CP_PROGRAM_ID)
|
attachment(CP_PROGRAM_ID)
|
||||||
attachment(JavaCommercialPaper.JCP_PROGRAM_ID)
|
attachment(JavaCommercialPaper.JCP_PROGRAM_ID)
|
||||||
input(thisTest.getContract(), thisTest.getPaper())
|
input(thisTest.getContract(), thisTest.getPaper())
|
||||||
output(thisTest.getContract()) { thisTest.getPaper() }
|
output(thisTest.getContract(), thisTest.getPaper())
|
||||||
command(MEGA_CORP_PUBKEY) { thisTest.getIssueCommand(DUMMY_NOTARY) }
|
command(MEGA_CORP_PUBKEY, thisTest.getIssueCommand(DUMMY_NOTARY))
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this `fails with` "output values sum to more than the inputs"
|
this `fails with` "output values sum to more than the inputs"
|
||||||
}
|
}
|
||||||
|
@ -111,34 +111,33 @@ class CashTests {
|
|||||||
fun trivial() {
|
fun trivial() {
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
output(Cash.PROGRAM_ID) { outState.copy(amount = 2000.DOLLARS `issued by` defaultIssuer) }
|
output(Cash.PROGRAM_ID, outState.copy(amount = 2000.DOLLARS `issued by` defaultIssuer))
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
tweak {
|
tweak {
|
||||||
output(Cash.PROGRAM_ID) { outState }
|
output(Cash.PROGRAM_ID, outState)
|
||||||
command(ALICE_PUBKEY) { DummyCommandData }
|
command(ALICE_PUBKEY, DummyCommandData)
|
||||||
// Invalid command
|
// Invalid command
|
||||||
this `fails with` "required net.corda.finance.contracts.asset.Cash.Commands.Move command"
|
this `fails with` "required net.corda.finance.contracts.asset.Cash.Commands.Move command"
|
||||||
}
|
}
|
||||||
tweak {
|
tweak {
|
||||||
output(Cash.PROGRAM_ID) { outState }
|
output(Cash.PROGRAM_ID, outState)
|
||||||
command(BOB_PUBKEY) { Cash.Commands.Move() }
|
command(BOB_PUBKEY, Cash.Commands.Move())
|
||||||
this `fails with` "the owning keys are a subset of the signing keys"
|
this `fails with` "the owning keys are a subset of the signing keys"
|
||||||
}
|
}
|
||||||
tweak {
|
tweak {
|
||||||
output(Cash.PROGRAM_ID) { outState }
|
output(Cash.PROGRAM_ID, outState)
|
||||||
output(Cash.PROGRAM_ID) { outState issuedBy MINI_CORP }
|
output(Cash.PROGRAM_ID, outState issuedBy MINI_CORP)
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
this `fails with` "at least one cash input"
|
this `fails with` "at least one cash input"
|
||||||
}
|
}
|
||||||
// Simple reallocation works.
|
// Simple reallocation works.
|
||||||
tweak {
|
tweak {
|
||||||
output(Cash.PROGRAM_ID) { outState }
|
output(Cash.PROGRAM_ID, outState)
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -149,10 +148,9 @@ class CashTests {
|
|||||||
// Check we can't "move" money into existence.
|
// Check we can't "move" money into existence.
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { DummyState() }
|
input(Cash.PROGRAM_ID, DummyState())
|
||||||
output(Cash.PROGRAM_ID) { outState }
|
output(Cash.PROGRAM_ID, outState)
|
||||||
command(MINI_CORP_PUBKEY) { Cash.Commands.Move() }
|
command(MINI_CORP_PUBKEY, Cash.Commands.Move())
|
||||||
|
|
||||||
this `fails with` "there is at least one cash input for this group"
|
this `fails with` "there is at least one cash input for this group"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -163,19 +161,17 @@ class CashTests {
|
|||||||
// institution is allowed to issue as much cash as they want.
|
// institution is allowed to issue as much cash as they want.
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
output(Cash.PROGRAM_ID) { outState }
|
output(Cash.PROGRAM_ID, outState)
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Issue() }
|
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
||||||
this `fails with` "output states are issued by a command signer"
|
this `fails with` "output states are issued by a command signer"
|
||||||
}
|
}
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
output(Cash.PROGRAM_ID) {
|
output(Cash.PROGRAM_ID,
|
||||||
Cash.State(
|
Cash.State(
|
||||||
amount = 1000.DOLLARS `issued by` MINI_CORP.ref(12, 34),
|
amount = 1000.DOLLARS `issued by` MINI_CORP.ref(12, 34),
|
||||||
owner = AnonymousParty(ALICE_PUBKEY)
|
owner = AnonymousParty(ALICE_PUBKEY)))
|
||||||
)
|
command(MINI_CORP_PUBKEY, Cash.Commands.Issue())
|
||||||
}
|
|
||||||
command(MINI_CORP_PUBKEY) { Cash.Commands.Issue() }
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -211,18 +207,17 @@ class CashTests {
|
|||||||
// We can consume $1000 in a transaction and output $2000 as long as it's signed by an issuer.
|
// We can consume $1000 in a transaction and output $2000 as long as it's signed by an issuer.
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { issuerInState }
|
input(Cash.PROGRAM_ID, issuerInState)
|
||||||
output(Cash.PROGRAM_ID) { inState.copy(amount = inState.amount * 2) }
|
output(Cash.PROGRAM_ID, inState.copy(amount = inState.amount * 2))
|
||||||
|
|
||||||
// Move fails: not allowed to summon money.
|
// Move fails: not allowed to summon money.
|
||||||
tweak {
|
tweak {
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Issue works.
|
// Issue works.
|
||||||
tweak {
|
tweak {
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() }
|
command(MEGA_CORP_PUBKEY, Cash.Commands.Issue())
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -230,29 +225,29 @@ class CashTests {
|
|||||||
// Can't use an issue command to lower the amount.
|
// Can't use an issue command to lower the amount.
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
output(Cash.PROGRAM_ID) { inState.copy(amount = inState.amount.splitEvenly(2).first()) }
|
output(Cash.PROGRAM_ID, inState.copy(amount = inState.amount.splitEvenly(2).first()))
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() }
|
command(MEGA_CORP_PUBKEY, Cash.Commands.Issue())
|
||||||
this `fails with` "output values sum to more than the inputs"
|
this `fails with` "output values sum to more than the inputs"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can't have an issue command that doesn't actually issue money.
|
// Can't have an issue command that doesn't actually issue money.
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
output(Cash.PROGRAM_ID) { inState }
|
output(Cash.PROGRAM_ID, inState)
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() }
|
command(MEGA_CORP_PUBKEY, Cash.Commands.Issue())
|
||||||
this `fails with` "output values sum to more than the inputs"
|
this `fails with` "output values sum to more than the inputs"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can't have any other commands if we have an issue command (because the issue command overrules them)
|
// Can't have any other commands if we have an issue command (because the issue command overrules them)
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
output(Cash.PROGRAM_ID) { inState.copy(amount = inState.amount * 2) }
|
output(Cash.PROGRAM_ID, inState.copy(amount = inState.amount * 2))
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() }
|
command(MEGA_CORP_PUBKEY, Cash.Commands.Issue())
|
||||||
tweak {
|
tweak {
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() }
|
command(MEGA_CORP_PUBKEY, Cash.Commands.Issue())
|
||||||
this `fails with` "there is only a single issue command"
|
this `fails with` "there is only a single issue command"
|
||||||
}
|
}
|
||||||
this.verifies()
|
this.verifies()
|
||||||
@ -282,26 +277,26 @@ class CashTests {
|
|||||||
// Splitting value works.
|
// Splitting value works.
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
tweak {
|
tweak {
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
val splits4 = inState.amount.splitEvenly(4)
|
val splits4 = inState.amount.splitEvenly(4)
|
||||||
for (i in 0..3) output(Cash.PROGRAM_ID) { inState.copy(amount = splits4[i]) }
|
for (i in 0..3) output(Cash.PROGRAM_ID, inState.copy(amount = splits4[i]))
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
// Merging 4 inputs into 2 outputs works.
|
// Merging 4 inputs into 2 outputs works.
|
||||||
tweak {
|
tweak {
|
||||||
val splits2 = inState.amount.splitEvenly(2)
|
val splits2 = inState.amount.splitEvenly(2)
|
||||||
val splits4 = inState.amount.splitEvenly(4)
|
val splits4 = inState.amount.splitEvenly(4)
|
||||||
for (i in 0..3) input(Cash.PROGRAM_ID) { inState.copy(amount = splits4[i]) }
|
for (i in 0..3) input(Cash.PROGRAM_ID, inState.copy(amount = splits4[i]))
|
||||||
for (i in 0..1) output(Cash.PROGRAM_ID) { inState.copy(amount = splits2[i]) }
|
for (i in 0..1) output(Cash.PROGRAM_ID, inState.copy(amount = splits2[i]))
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
// Merging 2 inputs into 1 works.
|
// Merging 2 inputs into 1 works.
|
||||||
tweak {
|
tweak {
|
||||||
val splits2 = inState.amount.splitEvenly(2)
|
val splits2 = inState.amount.splitEvenly(2)
|
||||||
for (i in 0..1) input(Cash.PROGRAM_ID) { inState.copy(amount = splits2[i]) }
|
for (i in 0..1) input(Cash.PROGRAM_ID, inState.copy(amount = splits2[i]))
|
||||||
output(Cash.PROGRAM_ID) { inState }
|
output(Cash.PROGRAM_ID, inState)
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -311,17 +306,17 @@ class CashTests {
|
|||||||
fun zeroSizedValues() {
|
fun zeroSizedValues() {
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
input(Cash.PROGRAM_ID) { inState.copy(amount = 0.DOLLARS `issued by` defaultIssuer) }
|
input(Cash.PROGRAM_ID, inState.copy(amount = 0.DOLLARS `issued by` defaultIssuer))
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
this `fails with` "zero sized inputs"
|
this `fails with` "zero sized inputs"
|
||||||
}
|
}
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
output(Cash.PROGRAM_ID) { inState }
|
output(Cash.PROGRAM_ID, inState)
|
||||||
output(Cash.PROGRAM_ID) { inState.copy(amount = 0.DOLLARS `issued by` defaultIssuer) }
|
output(Cash.PROGRAM_ID, inState.copy(amount = 0.DOLLARS `issued by` defaultIssuer))
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
this `fails with` "zero sized outputs"
|
this `fails with` "zero sized outputs"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -331,58 +326,56 @@ class CashTests {
|
|||||||
// Can't change issuer.
|
// Can't change issuer.
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
output(Cash.PROGRAM_ID) { outState issuedBy MINI_CORP }
|
output(Cash.PROGRAM_ID, outState issuedBy MINI_CORP)
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
// Can't change deposit reference when splitting.
|
// Can't change deposit reference when splitting.
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
val splits2 = inState.amount.splitEvenly(2)
|
val splits2 = inState.amount.splitEvenly(2)
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
for (i in 0..1) output(Cash.PROGRAM_ID) { outState.copy(amount = splits2[i]).editDepositRef(i.toByte()) }
|
for (i in 0..1) output(Cash.PROGRAM_ID, outState.copy(amount = splits2[i]).editDepositRef(i.toByte()))
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
// Can't mix currencies.
|
// Can't mix currencies.
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
output(Cash.PROGRAM_ID) { outState.copy(amount = 800.DOLLARS `issued by` defaultIssuer) }
|
output(Cash.PROGRAM_ID, outState.copy(amount = 800.DOLLARS `issued by` defaultIssuer))
|
||||||
output(Cash.PROGRAM_ID) { outState.copy(amount = 200.POUNDS `issued by` defaultIssuer) }
|
output(Cash.PROGRAM_ID, outState.copy(amount = 200.POUNDS `issued by` defaultIssuer))
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
input(Cash.PROGRAM_ID) {
|
input(Cash.PROGRAM_ID,
|
||||||
inState.copy(
|
inState.copy(
|
||||||
amount = 150.POUNDS `issued by` defaultIssuer,
|
amount = 150.POUNDS `issued by` defaultIssuer,
|
||||||
owner = AnonymousParty(BOB_PUBKEY)
|
owner = AnonymousParty(BOB_PUBKEY)))
|
||||||
)
|
output(Cash.PROGRAM_ID, outState.copy(amount = 1150.DOLLARS `issued by` defaultIssuer))
|
||||||
}
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
output(Cash.PROGRAM_ID) { outState.copy(amount = 1150.DOLLARS `issued by` defaultIssuer) }
|
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
// Can't have superfluous input states from different issuers.
|
// Can't have superfluous input states from different issuers.
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
input(Cash.PROGRAM_ID) { inState issuedBy MINI_CORP }
|
input(Cash.PROGRAM_ID, inState issuedBy MINI_CORP)
|
||||||
output(Cash.PROGRAM_ID) { outState }
|
output(Cash.PROGRAM_ID, outState)
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
// Can't combine two different deposits at the same issuer.
|
// Can't combine two different deposits at the same issuer.
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
input(Cash.PROGRAM_ID) { inState.editDepositRef(3) }
|
input(Cash.PROGRAM_ID, inState.editDepositRef(3))
|
||||||
output(Cash.PROGRAM_ID) { outState.copy(amount = inState.amount * 2).editDepositRef(3) }
|
output(Cash.PROGRAM_ID, outState.copy(amount = inState.amount * 2).editDepositRef(3))
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
this `fails with` "for reference [01]"
|
this `fails with` "for reference [01]"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -392,21 +385,20 @@ class CashTests {
|
|||||||
// Single input/output straightforward case.
|
// Single input/output straightforward case.
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { issuerInState }
|
input(Cash.PROGRAM_ID, issuerInState)
|
||||||
output(Cash.PROGRAM_ID) { issuerInState.copy(amount = issuerInState.amount - (200.DOLLARS `issued by` defaultIssuer)) }
|
output(Cash.PROGRAM_ID, issuerInState.copy(amount = issuerInState.amount - (200.DOLLARS `issued by` defaultIssuer)))
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Exit(100.DOLLARS `issued by` defaultIssuer) }
|
command(MEGA_CORP_PUBKEY, Cash.Commands.Exit(100.DOLLARS `issued by` defaultIssuer))
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() }
|
command(MEGA_CORP_PUBKEY, Cash.Commands.Move())
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Exit(200.DOLLARS `issued by` defaultIssuer) }
|
command(MEGA_CORP_PUBKEY, Cash.Commands.Exit(200.DOLLARS `issued by` defaultIssuer))
|
||||||
this `fails with` "required net.corda.finance.contracts.asset.Cash.Commands.Move command"
|
this `fails with` "required net.corda.finance.contracts.asset.Cash.Commands.Move command"
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() }
|
command(MEGA_CORP_PUBKEY, Cash.Commands.Move())
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -418,20 +410,15 @@ class CashTests {
|
|||||||
// Multi-issuer case.
|
// Multi-issuer case.
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { issuerInState }
|
input(Cash.PROGRAM_ID, issuerInState)
|
||||||
input(Cash.PROGRAM_ID) { issuerInState.copy(owner = MINI_CORP) issuedBy MINI_CORP }
|
input(Cash.PROGRAM_ID, issuerInState.copy(owner = MINI_CORP) issuedBy MINI_CORP)
|
||||||
|
output(Cash.PROGRAM_ID, issuerInState.copy(amount = issuerInState.amount - (200.DOLLARS `issued by` defaultIssuer)) issuedBy MINI_CORP)
|
||||||
output(Cash.PROGRAM_ID) { issuerInState.copy(amount = issuerInState.amount - (200.DOLLARS `issued by` defaultIssuer)) issuedBy MINI_CORP }
|
output(Cash.PROGRAM_ID, issuerInState.copy(owner = MINI_CORP, amount = issuerInState.amount - (200.DOLLARS `issued by` defaultIssuer)))
|
||||||
output(Cash.PROGRAM_ID) { issuerInState.copy(owner = MINI_CORP, amount = issuerInState.amount - (200.DOLLARS `issued by` defaultIssuer)) }
|
command(listOf(MEGA_CORP_PUBKEY, MINI_CORP_PUBKEY), Cash.Commands.Move())
|
||||||
|
|
||||||
command(MEGA_CORP_PUBKEY, MINI_CORP_PUBKEY) { Cash.Commands.Move() }
|
|
||||||
|
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
|
command(MEGA_CORP_PUBKEY, Cash.Commands.Exit(200.DOLLARS `issued by` defaultIssuer))
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Exit(200.DOLLARS `issued by` defaultIssuer) }
|
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
|
command(MINI_CORP_PUBKEY, Cash.Commands.Exit(200.DOLLARS `issued by` MINI_CORP.ref(defaultRef)))
|
||||||
command(MINI_CORP_PUBKEY) { Cash.Commands.Exit(200.DOLLARS `issued by` MINI_CORP.ref(defaultRef)) }
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -441,10 +428,10 @@ class CashTests {
|
|||||||
// Single input/output straightforward case.
|
// Single input/output straightforward case.
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
output(Cash.PROGRAM_ID) { outState.copy(amount = inState.amount - (200.DOLLARS `issued by` defaultIssuer)) }
|
output(Cash.PROGRAM_ID, outState.copy(amount = inState.amount - (200.DOLLARS `issued by` defaultIssuer)))
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Exit(200.DOLLARS `issued by` defaultIssuer) }
|
command(MEGA_CORP_PUBKEY, Cash.Commands.Exit(200.DOLLARS `issued by` defaultIssuer))
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -454,25 +441,24 @@ class CashTests {
|
|||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
// Gather 2000 dollars from two different issuers.
|
// Gather 2000 dollars from two different issuers.
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
input(Cash.PROGRAM_ID) { inState issuedBy MINI_CORP }
|
input(Cash.PROGRAM_ID, inState issuedBy MINI_CORP)
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
|
|
||||||
// Can't merge them together.
|
// Can't merge them together.
|
||||||
tweak {
|
tweak {
|
||||||
output(Cash.PROGRAM_ID) { inState.copy(owner = AnonymousParty(BOB_PUBKEY), amount = 2000.DOLLARS `issued by` defaultIssuer) }
|
output(Cash.PROGRAM_ID, inState.copy(owner = AnonymousParty(BOB_PUBKEY), amount = 2000.DOLLARS `issued by` defaultIssuer))
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
// Missing MiniCorp deposit
|
// Missing MiniCorp deposit
|
||||||
tweak {
|
tweak {
|
||||||
output(Cash.PROGRAM_ID) { inState.copy(owner = AnonymousParty(BOB_PUBKEY)) }
|
output(Cash.PROGRAM_ID, inState.copy(owner = AnonymousParty(BOB_PUBKEY)))
|
||||||
output(Cash.PROGRAM_ID) { inState.copy(owner = AnonymousParty(BOB_PUBKEY)) }
|
output(Cash.PROGRAM_ID, inState.copy(owner = AnonymousParty(BOB_PUBKEY)))
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
|
|
||||||
// This works.
|
// This works.
|
||||||
output(Cash.PROGRAM_ID) { inState.copy(owner = AnonymousParty(BOB_PUBKEY)) }
|
output(Cash.PROGRAM_ID, inState.copy(owner = AnonymousParty(BOB_PUBKEY)))
|
||||||
output(Cash.PROGRAM_ID) { inState.copy(owner = AnonymousParty(BOB_PUBKEY)) issuedBy MINI_CORP }
|
output(Cash.PROGRAM_ID, inState.copy(owner = AnonymousParty(BOB_PUBKEY)) issuedBy MINI_CORP)
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -483,12 +469,11 @@ class CashTests {
|
|||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
val pounds = Cash.State(658.POUNDS `issued by` MINI_CORP.ref(3, 4, 5), AnonymousParty(BOB_PUBKEY))
|
val pounds = Cash.State(658.POUNDS `issued by` MINI_CORP.ref(3, 4, 5), AnonymousParty(BOB_PUBKEY))
|
||||||
input(Cash.PROGRAM_ID) { inState ownedBy AnonymousParty(ALICE_PUBKEY) }
|
input(Cash.PROGRAM_ID, inState ownedBy AnonymousParty(ALICE_PUBKEY))
|
||||||
input(Cash.PROGRAM_ID) { pounds }
|
input(Cash.PROGRAM_ID, pounds)
|
||||||
output(Cash.PROGRAM_ID) { inState ownedBy AnonymousParty(BOB_PUBKEY) }
|
output(Cash.PROGRAM_ID, inState ownedBy AnonymousParty(BOB_PUBKEY))
|
||||||
output(Cash.PROGRAM_ID) { pounds ownedBy AnonymousParty(ALICE_PUBKEY) }
|
output(Cash.PROGRAM_ID, pounds ownedBy AnonymousParty(ALICE_PUBKEY))
|
||||||
command(ALICE_PUBKEY, BOB_PUBKEY) { Cash.Commands.Move() }
|
command(listOf(ALICE_PUBKEY, BOB_PUBKEY), Cash.Commands.Move())
|
||||||
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -792,19 +777,17 @@ class CashTests {
|
|||||||
ledger(mockService) {
|
ledger(mockService) {
|
||||||
unverifiedTransaction {
|
unverifiedTransaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
output(Cash.PROGRAM_ID, "MEGA_CORP cash") {
|
output(Cash.PROGRAM_ID, "MEGA_CORP cash",
|
||||||
Cash.State(
|
Cash.State(
|
||||||
amount = 1000.DOLLARS `issued by` MEGA_CORP.ref(1, 1),
|
amount = 1000.DOLLARS `issued by` MEGA_CORP.ref(1, 1),
|
||||||
owner = MEGA_CORP
|
owner = MEGA_CORP))
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input("MEGA_CORP cash")
|
input("MEGA_CORP cash")
|
||||||
output(Cash.PROGRAM_ID, "MEGA_CORP cash 2", "MEGA_CORP cash".output<Cash.State>().copy(owner = AnonymousParty(ALICE_PUBKEY)))
|
output(Cash.PROGRAM_ID, "MEGA_CORP cash 2", "MEGA_CORP cash".output<Cash.State>().copy(owner = AnonymousParty(ALICE_PUBKEY)))
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() }
|
command(MEGA_CORP_PUBKEY, Cash.Commands.Move())
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -814,7 +797,7 @@ class CashTests {
|
|||||||
input("MEGA_CORP cash")
|
input("MEGA_CORP cash")
|
||||||
// We send it to another pubkey so that the transaction is not identical to the previous one
|
// 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))
|
output(Cash.PROGRAM_ID, "MEGA_CORP cash 3", "MEGA_CORP cash".output<Cash.State>().copy(owner = ALICE))
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() }
|
command(MEGA_CORP_PUBKEY, Cash.Commands.Move())
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
this.fails()
|
this.fails()
|
||||||
|
@ -71,34 +71,33 @@ class ObligationTests {
|
|||||||
fun trivial() {
|
fun trivial() {
|
||||||
transaction {
|
transaction {
|
||||||
attachments(Obligation.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID)
|
||||||
input(Obligation.PROGRAM_ID) { inState }
|
input(Obligation.PROGRAM_ID, inState)
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
output(Obligation.PROGRAM_ID) { outState.copy(quantity = 2000.DOLLARS.quantity) }
|
output(Obligation.PROGRAM_ID, outState.copy(quantity = 2000.DOLLARS.quantity))
|
||||||
command(CHARLIE.owningKey) { Obligation.Commands.Move() }
|
command(CHARLIE.owningKey, Obligation.Commands.Move())
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
tweak {
|
tweak {
|
||||||
output(Obligation.PROGRAM_ID) { outState }
|
output(Obligation.PROGRAM_ID, outState)
|
||||||
command(CHARLIE.owningKey) { DummyCommandData }
|
command(CHARLIE.owningKey, DummyCommandData)
|
||||||
// Invalid command
|
// Invalid command
|
||||||
this `fails with` "required net.corda.finance.contracts.asset.Obligation.Commands.Move command"
|
this `fails with` "required net.corda.finance.contracts.asset.Obligation.Commands.Move command"
|
||||||
}
|
}
|
||||||
tweak {
|
tweak {
|
||||||
output(Obligation.PROGRAM_ID) { outState }
|
output(Obligation.PROGRAM_ID, outState)
|
||||||
command(BOB_PUBKEY) { Obligation.Commands.Move() }
|
command(BOB_PUBKEY, Obligation.Commands.Move())
|
||||||
this `fails with` "the owning keys are a subset of the signing keys"
|
this `fails with` "the owning keys are a subset of the signing keys"
|
||||||
}
|
}
|
||||||
tweak {
|
tweak {
|
||||||
output(Obligation.PROGRAM_ID) { outState }
|
output(Obligation.PROGRAM_ID, outState)
|
||||||
output(Obligation.PROGRAM_ID) { outState `issued by` MINI_CORP }
|
output(Obligation.PROGRAM_ID, outState `issued by` MINI_CORP)
|
||||||
command(CHARLIE.owningKey) { Obligation.Commands.Move() }
|
command(CHARLIE.owningKey, Obligation.Commands.Move())
|
||||||
this `fails with` "at least one obligation input"
|
this `fails with` "at least one obligation input"
|
||||||
}
|
}
|
||||||
// Simple reallocation works.
|
// Simple reallocation works.
|
||||||
tweak {
|
tweak {
|
||||||
output(Obligation.PROGRAM_ID) { outState }
|
output(Obligation.PROGRAM_ID, outState)
|
||||||
command(CHARLIE.owningKey) { Obligation.Commands.Move() }
|
command(CHARLIE.owningKey, Obligation.Commands.Move())
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,10 +108,9 @@ class ObligationTests {
|
|||||||
// Check we can't "move" debt into existence.
|
// Check we can't "move" debt into existence.
|
||||||
transaction {
|
transaction {
|
||||||
attachments(DummyContract.PROGRAM_ID, Obligation.PROGRAM_ID)
|
attachments(DummyContract.PROGRAM_ID, Obligation.PROGRAM_ID)
|
||||||
input(DummyContract.PROGRAM_ID) { DummyState() }
|
input(DummyContract.PROGRAM_ID, DummyState())
|
||||||
output(Obligation.PROGRAM_ID) { outState }
|
output(Obligation.PROGRAM_ID, outState)
|
||||||
command(MINI_CORP_PUBKEY) { Obligation.Commands.Move() }
|
command(MINI_CORP_PUBKEY, Obligation.Commands.Move())
|
||||||
|
|
||||||
this `fails with` "at least one obligation input"
|
this `fails with` "at least one obligation input"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,21 +118,19 @@ class ObligationTests {
|
|||||||
// institution is allowed to issue as much cash as they want.
|
// institution is allowed to issue as much cash as they want.
|
||||||
transaction {
|
transaction {
|
||||||
attachments(Obligation.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID)
|
||||||
output(Obligation.PROGRAM_ID) { outState }
|
output(Obligation.PROGRAM_ID, outState)
|
||||||
command(CHARLIE.owningKey) { Obligation.Commands.Issue() }
|
command(CHARLIE.owningKey, Obligation.Commands.Issue())
|
||||||
this `fails with` "output states are issued by a command signer"
|
this `fails with` "output states are issued by a command signer"
|
||||||
}
|
}
|
||||||
transaction {
|
transaction {
|
||||||
attachments(Obligation.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID)
|
||||||
output(Obligation.PROGRAM_ID) {
|
output(Obligation.PROGRAM_ID,
|
||||||
Obligation.State(
|
Obligation.State(
|
||||||
obligor = MINI_CORP,
|
obligor = MINI_CORP,
|
||||||
quantity = 1000.DOLLARS.quantity,
|
quantity = 1000.DOLLARS.quantity,
|
||||||
beneficiary = CHARLIE,
|
beneficiary = CHARLIE,
|
||||||
template = megaCorpDollarSettlement
|
template = megaCorpDollarSettlement))
|
||||||
)
|
command(MINI_CORP_PUBKEY, Obligation.Commands.Issue())
|
||||||
}
|
|
||||||
command(MINI_CORP_PUBKEY) { Obligation.Commands.Issue() }
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
run {
|
run {
|
||||||
@ -157,18 +153,17 @@ class ObligationTests {
|
|||||||
// We can consume $1000 in a transaction and output $2000 as long as it's signed by an issuer.
|
// We can consume $1000 in a transaction and output $2000 as long as it's signed by an issuer.
|
||||||
transaction {
|
transaction {
|
||||||
attachments(Obligation.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID)
|
||||||
input(Obligation.PROGRAM_ID) { inState }
|
input(Obligation.PROGRAM_ID, inState)
|
||||||
output(Obligation.PROGRAM_ID) { inState.copy(quantity = inState.amount.quantity * 2) }
|
output(Obligation.PROGRAM_ID, inState.copy(quantity = inState.amount.quantity * 2))
|
||||||
|
|
||||||
// Move fails: not allowed to summon money.
|
// Move fails: not allowed to summon money.
|
||||||
tweak {
|
tweak {
|
||||||
command(CHARLIE.owningKey) { Obligation.Commands.Move() }
|
command(CHARLIE.owningKey, Obligation.Commands.Move())
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Issue works.
|
// Issue works.
|
||||||
tweak {
|
tweak {
|
||||||
command(MEGA_CORP_PUBKEY) { Obligation.Commands.Issue() }
|
command(MEGA_CORP_PUBKEY, Obligation.Commands.Issue())
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -176,29 +171,29 @@ class ObligationTests {
|
|||||||
// Can't use an issue command to lower the amount.
|
// Can't use an issue command to lower the amount.
|
||||||
transaction {
|
transaction {
|
||||||
attachments(Obligation.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID)
|
||||||
input(Obligation.PROGRAM_ID) { inState }
|
input(Obligation.PROGRAM_ID, inState)
|
||||||
output(Obligation.PROGRAM_ID) { inState.copy(quantity = inState.amount.quantity / 2) }
|
output(Obligation.PROGRAM_ID, inState.copy(quantity = inState.amount.quantity / 2))
|
||||||
command(MEGA_CORP_PUBKEY) { Obligation.Commands.Issue() }
|
command(MEGA_CORP_PUBKEY, Obligation.Commands.Issue())
|
||||||
this `fails with` "output values sum to more than the inputs"
|
this `fails with` "output values sum to more than the inputs"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can't have an issue command that doesn't actually issue money.
|
// Can't have an issue command that doesn't actually issue money.
|
||||||
transaction {
|
transaction {
|
||||||
attachments(Obligation.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID)
|
||||||
input(Obligation.PROGRAM_ID) { inState }
|
input(Obligation.PROGRAM_ID, inState)
|
||||||
output(Obligation.PROGRAM_ID) { inState }
|
output(Obligation.PROGRAM_ID, inState)
|
||||||
command(MEGA_CORP_PUBKEY) { Obligation.Commands.Issue() }
|
command(MEGA_CORP_PUBKEY, Obligation.Commands.Issue())
|
||||||
this `fails with` ""
|
this `fails with` ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can't have any other commands if we have an issue command (because the issue command overrules them).
|
// Can't have any other commands if we have an issue command (because the issue command overrules them).
|
||||||
transaction {
|
transaction {
|
||||||
attachments(Obligation.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID)
|
||||||
input(Obligation.PROGRAM_ID) { inState }
|
input(Obligation.PROGRAM_ID, inState)
|
||||||
output(Obligation.PROGRAM_ID) { inState.copy(quantity = inState.amount.quantity * 2) }
|
output(Obligation.PROGRAM_ID, inState.copy(quantity = inState.amount.quantity * 2))
|
||||||
command(MEGA_CORP_PUBKEY) { Obligation.Commands.Issue() }
|
command(MEGA_CORP_PUBKEY, Obligation.Commands.Issue())
|
||||||
tweak {
|
tweak {
|
||||||
command(MEGA_CORP_PUBKEY) { Obligation.Commands.Issue() }
|
command(MEGA_CORP_PUBKEY, Obligation.Commands.Issue())
|
||||||
this `fails with` "there is only a single issue command"
|
this `fails with` "there is only a single issue command"
|
||||||
}
|
}
|
||||||
this.verifies()
|
this.verifies()
|
||||||
@ -352,7 +347,7 @@ class ObligationTests {
|
|||||||
input("Alice's $1,000,000 obligation to Bob")
|
input("Alice's $1,000,000 obligation to Bob")
|
||||||
input("Bob's $1,000,000 obligation to Alice")
|
input("Bob's $1,000,000 obligation to Alice")
|
||||||
// Note we can sign with either key here
|
// Note we can sign with either key here
|
||||||
command(ALICE_PUBKEY) { Obligation.Commands.Net(NetType.CLOSE_OUT) }
|
command(ALICE_PUBKEY, Obligation.Commands.Net(NetType.CLOSE_OUT))
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
@ -368,8 +363,8 @@ class ObligationTests {
|
|||||||
input("Alice's $1,000,000 obligation to Bob")
|
input("Alice's $1,000,000 obligation to Bob")
|
||||||
input("Bob's $1,000,000 obligation to Alice")
|
input("Bob's $1,000,000 obligation to Alice")
|
||||||
input("MegaCorp's $1,000,000 obligation to Bob")
|
input("MegaCorp's $1,000,000 obligation to Bob")
|
||||||
output(Obligation.PROGRAM_ID, "change") { oneMillionDollars.OBLIGATION between Pair(MEGA_CORP, BOB) }
|
output(Obligation.PROGRAM_ID, "change", oneMillionDollars.OBLIGATION between Pair(MEGA_CORP, BOB))
|
||||||
command(BOB_PUBKEY, MEGA_CORP_PUBKEY) { Obligation.Commands.Net(NetType.CLOSE_OUT) }
|
command(listOf(BOB_PUBKEY, MEGA_CORP_PUBKEY), Obligation.Commands.Net(NetType.CLOSE_OUT))
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
@ -383,8 +378,8 @@ class ObligationTests {
|
|||||||
attachments(Obligation.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID)
|
||||||
input("Alice's $1,000,000 obligation to Bob")
|
input("Alice's $1,000,000 obligation to Bob")
|
||||||
input("Bob's $1,000,000 obligation to Alice")
|
input("Bob's $1,000,000 obligation to Alice")
|
||||||
output(Obligation.PROGRAM_ID, "change") { (oneMillionDollars.splitEvenly(2).first()).OBLIGATION between Pair(ALICE, BOB) }
|
output(Obligation.PROGRAM_ID, "change", oneMillionDollars.splitEvenly(2).first().OBLIGATION between Pair(ALICE, BOB))
|
||||||
command(BOB_PUBKEY) { Obligation.Commands.Net(NetType.CLOSE_OUT) }
|
command(BOB_PUBKEY, Obligation.Commands.Net(NetType.CLOSE_OUT))
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this `fails with` "amounts owed on input and output must match"
|
this `fails with` "amounts owed on input and output must match"
|
||||||
}
|
}
|
||||||
@ -397,7 +392,7 @@ class ObligationTests {
|
|||||||
attachments(Obligation.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID)
|
||||||
input("Alice's $1,000,000 obligation to Bob")
|
input("Alice's $1,000,000 obligation to Bob")
|
||||||
input("Bob's $1,000,000 obligation to Alice")
|
input("Bob's $1,000,000 obligation to Alice")
|
||||||
command(MEGA_CORP_PUBKEY) { Obligation.Commands.Net(NetType.CLOSE_OUT) }
|
command(MEGA_CORP_PUBKEY, Obligation.Commands.Net(NetType.CLOSE_OUT))
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this `fails with` "any involved party has signed"
|
this `fails with` "any involved party has signed"
|
||||||
}
|
}
|
||||||
@ -413,7 +408,7 @@ class ObligationTests {
|
|||||||
attachments(Obligation.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID)
|
||||||
input("Alice's $1,000,000 obligation to Bob")
|
input("Alice's $1,000,000 obligation to Bob")
|
||||||
input("Bob's $1,000,000 obligation to Alice")
|
input("Bob's $1,000,000 obligation to Alice")
|
||||||
command(ALICE_PUBKEY, BOB_PUBKEY) { Obligation.Commands.Net(NetType.PAYMENT) }
|
command(listOf(ALICE_PUBKEY, BOB_PUBKEY), Obligation.Commands.Net(NetType.PAYMENT))
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
@ -428,7 +423,7 @@ class ObligationTests {
|
|||||||
attachments(Obligation.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID)
|
||||||
input("Alice's $1,000,000 obligation to Bob")
|
input("Alice's $1,000,000 obligation to Bob")
|
||||||
input("Bob's $1,000,000 obligation to Alice")
|
input("Bob's $1,000,000 obligation to Alice")
|
||||||
command(BOB_PUBKEY) { Obligation.Commands.Net(NetType.PAYMENT) }
|
command(BOB_PUBKEY, Obligation.Commands.Net(NetType.PAYMENT))
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this `fails with` "all involved parties have signed"
|
this `fails with` "all involved parties have signed"
|
||||||
}
|
}
|
||||||
@ -441,8 +436,8 @@ class ObligationTests {
|
|||||||
attachments(Obligation.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID)
|
||||||
input("Bob's $1,000,000 obligation to Alice")
|
input("Bob's $1,000,000 obligation to Alice")
|
||||||
input("MegaCorp's $1,000,000 obligation to Bob")
|
input("MegaCorp's $1,000,000 obligation to Bob")
|
||||||
output(Obligation.PROGRAM_ID, "MegaCorp's $1,000,000 obligation to Alice") { oneMillionDollars.OBLIGATION between Pair(MEGA_CORP, ALICE) }
|
output(Obligation.PROGRAM_ID, "MegaCorp's $1,000,000 obligation to Alice", oneMillionDollars.OBLIGATION between Pair(MEGA_CORP, ALICE))
|
||||||
command(ALICE_PUBKEY, BOB_PUBKEY, MEGA_CORP_PUBKEY) { Obligation.Commands.Net(NetType.PAYMENT) }
|
command(listOf(ALICE_PUBKEY, BOB_PUBKEY, MEGA_CORP_PUBKEY), Obligation.Commands.Net(NetType.PAYMENT))
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
@ -456,8 +451,8 @@ class ObligationTests {
|
|||||||
attachments(Obligation.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID)
|
||||||
input("Bob's $1,000,000 obligation to Alice")
|
input("Bob's $1,000,000 obligation to Alice")
|
||||||
input("MegaCorp's $1,000,000 obligation to Bob")
|
input("MegaCorp's $1,000,000 obligation to Bob")
|
||||||
output(Obligation.PROGRAM_ID, "MegaCorp's $1,000,000 obligation to Alice") { oneMillionDollars.OBLIGATION between Pair(MEGA_CORP, ALICE) }
|
output(Obligation.PROGRAM_ID, "MegaCorp's $1,000,000 obligation to Alice", oneMillionDollars.OBLIGATION between Pair(MEGA_CORP, ALICE))
|
||||||
command(ALICE_PUBKEY, BOB_PUBKEY) { Obligation.Commands.Net(NetType.PAYMENT) }
|
command(listOf(ALICE_PUBKEY, BOB_PUBKEY), Obligation.Commands.Net(NetType.PAYMENT))
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this `fails with` "all involved parties have signed"
|
this `fails with` "all involved parties have signed"
|
||||||
}
|
}
|
||||||
@ -473,9 +468,9 @@ class ObligationTests {
|
|||||||
attachments(Obligation.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID)
|
||||||
input("Alice's $1,000,000 obligation to Bob")
|
input("Alice's $1,000,000 obligation to Bob")
|
||||||
input("Alice's $1,000,000")
|
input("Alice's $1,000,000")
|
||||||
output(Obligation.PROGRAM_ID, "Bob's $1,000,000") { 1000000.DOLLARS.CASH issuedBy defaultIssuer ownedBy BOB }
|
output(Obligation.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, Obligation.Commands.Settle(Amount(oneMillionDollars.quantity, inState.amount.token)))
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move(Obligation::class.java) }
|
command(ALICE_PUBKEY, Cash.Commands.Move(Obligation::class.java))
|
||||||
attachment(attachment(cashContractBytes.inputStream()))
|
attachment(attachment(cashContractBytes.inputStream()))
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
@ -488,10 +483,10 @@ class ObligationTests {
|
|||||||
attachments(Obligation.PROGRAM_ID, Cash.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID, Cash.PROGRAM_ID)
|
||||||
input(Obligation.PROGRAM_ID, oneMillionDollars.OBLIGATION between Pair(ALICE, BOB))
|
input(Obligation.PROGRAM_ID, oneMillionDollars.OBLIGATION between Pair(ALICE, BOB))
|
||||||
input(Cash.PROGRAM_ID, 500000.DOLLARS.CASH issuedBy defaultIssuer ownedBy ALICE)
|
input(Cash.PROGRAM_ID, 500000.DOLLARS.CASH issuedBy defaultIssuer ownedBy ALICE)
|
||||||
output(Obligation.PROGRAM_ID, "Alice's $500,000 obligation to Bob") { halfAMillionDollars.OBLIGATION between Pair(ALICE, BOB) }
|
output(Obligation.PROGRAM_ID, "Alice's $500,000 obligation to Bob", halfAMillionDollars.OBLIGATION between Pair(ALICE, BOB))
|
||||||
output(Obligation.PROGRAM_ID, "Bob's $500,000") { 500000.DOLLARS.CASH issuedBy defaultIssuer ownedBy BOB }
|
output(Obligation.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, Obligation.Commands.Settle(Amount(oneMillionDollars.quantity / 2, inState.amount.token)))
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move(Obligation::class.java) }
|
command(ALICE_PUBKEY, Cash.Commands.Move(Obligation::class.java))
|
||||||
attachment(attachment(cashContractBytes.inputStream()))
|
attachment(attachment(cashContractBytes.inputStream()))
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
@ -504,9 +499,9 @@ class ObligationTests {
|
|||||||
attachments(Obligation.PROGRAM_ID, Cash.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID, Cash.PROGRAM_ID)
|
||||||
input(Obligation.PROGRAM_ID, defaultedObligation) // Alice's defaulted $1,000,000 obligation to Bob
|
input(Obligation.PROGRAM_ID, defaultedObligation) // Alice's defaulted $1,000,000 obligation to Bob
|
||||||
input(Cash.PROGRAM_ID, 1000000.DOLLARS.CASH issuedBy defaultIssuer ownedBy ALICE)
|
input(Cash.PROGRAM_ID, 1000000.DOLLARS.CASH issuedBy defaultIssuer ownedBy ALICE)
|
||||||
output(Obligation.PROGRAM_ID, "Bob's $1,000,000") { 1000000.DOLLARS.CASH issuedBy defaultIssuer ownedBy BOB }
|
output(Obligation.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, Obligation.Commands.Settle(Amount(oneMillionDollars.quantity, inState.amount.token)))
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move(Obligation::class.java) }
|
command(ALICE_PUBKEY, Cash.Commands.Move(Obligation::class.java))
|
||||||
this `fails with` "all inputs are in the normal state"
|
this `fails with` "all inputs are in the normal state"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -518,9 +513,9 @@ class ObligationTests {
|
|||||||
attachments(Obligation.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID)
|
||||||
input("Alice's $1,000,000 obligation to Bob")
|
input("Alice's $1,000,000 obligation to Bob")
|
||||||
input("Alice's $1,000,000")
|
input("Alice's $1,000,000")
|
||||||
output(Obligation.PROGRAM_ID, "Bob's $1,000,000") { 1000000.DOLLARS.CASH issuedBy defaultIssuer ownedBy BOB }
|
output(Obligation.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, Obligation.Commands.Settle(Amount(oneMillionDollars.quantity / 2, inState.amount.token)))
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move(Obligation::class.java) }
|
command(ALICE_PUBKEY, Cash.Commands.Move(Obligation::class.java))
|
||||||
attachment(attachment(cashContractBytes.inputStream()))
|
attachment(attachment(cashContractBytes.inputStream()))
|
||||||
this `fails with` "amount in settle command"
|
this `fails with` "amount in settle command"
|
||||||
}
|
}
|
||||||
@ -546,9 +541,9 @@ class ObligationTests {
|
|||||||
attachments(Obligation.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID)
|
||||||
input("Alice's 1 FCOJ obligation to Bob")
|
input("Alice's 1 FCOJ obligation to Bob")
|
||||||
input("Alice's 1 FCOJ")
|
input("Alice's 1 FCOJ")
|
||||||
output(Obligation.PROGRAM_ID, "Bob's 1 FCOJ") { CommodityContract.State(oneUnitFcoj, BOB) }
|
output(Obligation.PROGRAM_ID, "Bob's 1 FCOJ", CommodityContract.State(oneUnitFcoj, BOB))
|
||||||
command(ALICE_PUBKEY) { Obligation.Commands.Settle(Amount(oneUnitFcoj.quantity, oneUnitFcojObligation.amount.token)) }
|
command(ALICE_PUBKEY, Obligation.Commands.Settle(Amount(oneUnitFcoj.quantity, oneUnitFcojObligation.amount.token)))
|
||||||
command(ALICE_PUBKEY) { CommodityContract.Commands.Move(Obligation::class.java) }
|
command(ALICE_PUBKEY, CommodityContract.Commands.Move(Obligation::class.java))
|
||||||
attachment(attachment(commodityContractBytes.inputStream()))
|
attachment(attachment(commodityContractBytes.inputStream()))
|
||||||
verifies()
|
verifies()
|
||||||
}
|
}
|
||||||
@ -563,8 +558,8 @@ class ObligationTests {
|
|||||||
transaction("Settlement") {
|
transaction("Settlement") {
|
||||||
attachments(Obligation.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID)
|
||||||
input("Alice's $1,000,000 obligation to Bob")
|
input("Alice's $1,000,000 obligation to Bob")
|
||||||
output(Obligation.PROGRAM_ID, "Alice's defaulted $1,000,000 obligation to Bob") { (oneMillionDollars.OBLIGATION between Pair(ALICE, BOB)).copy(lifecycle = Lifecycle.DEFAULTED) }
|
output(Obligation.PROGRAM_ID, "Alice's defaulted $1,000,000 obligation to Bob", (oneMillionDollars.OBLIGATION between Pair(ALICE, BOB)).copy(lifecycle = Lifecycle.DEFAULTED))
|
||||||
command(BOB_PUBKEY) { Obligation.Commands.SetLifecycle(Lifecycle.DEFAULTED) }
|
command(BOB_PUBKEY, Obligation.Commands.SetLifecycle(Lifecycle.DEFAULTED))
|
||||||
this `fails with` "there is a time-window from the authority"
|
this `fails with` "there is a time-window from the authority"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -575,8 +570,8 @@ class ObligationTests {
|
|||||||
transaction {
|
transaction {
|
||||||
attachments(Obligation.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID)
|
||||||
input(Obligation.PROGRAM_ID, oneMillionDollars.OBLIGATION between Pair(ALICE, BOB) `at` futureTestTime)
|
input(Obligation.PROGRAM_ID, oneMillionDollars.OBLIGATION between Pair(ALICE, BOB) `at` futureTestTime)
|
||||||
output(Obligation.PROGRAM_ID, "Alice's defaulted $1,000,000 obligation to Bob") { (oneMillionDollars.OBLIGATION between Pair(ALICE, BOB) `at` futureTestTime).copy(lifecycle = Lifecycle.DEFAULTED) }
|
output(Obligation.PROGRAM_ID, "Alice's defaulted $1,000,000 obligation to Bob", (oneMillionDollars.OBLIGATION between Pair(ALICE, BOB) `at` futureTestTime).copy(lifecycle = Lifecycle.DEFAULTED))
|
||||||
command(BOB_PUBKEY) { Obligation.Commands.SetLifecycle(Lifecycle.DEFAULTED) }
|
command(BOB_PUBKEY, Obligation.Commands.SetLifecycle(Lifecycle.DEFAULTED))
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this `fails with` "the due date has passed"
|
this `fails with` "the due date has passed"
|
||||||
}
|
}
|
||||||
@ -586,8 +581,8 @@ class ObligationTests {
|
|||||||
transaction {
|
transaction {
|
||||||
attachments(Obligation.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID)
|
||||||
input(Obligation.PROGRAM_ID, oneMillionDollars.OBLIGATION between Pair(ALICE, BOB) `at` pastTestTime)
|
input(Obligation.PROGRAM_ID, oneMillionDollars.OBLIGATION between Pair(ALICE, BOB) `at` pastTestTime)
|
||||||
output(Obligation.PROGRAM_ID, "Alice's defaulted $1,000,000 obligation to Bob") { (oneMillionDollars.OBLIGATION between Pair(ALICE, BOB) `at` pastTestTime).copy(lifecycle = Lifecycle.DEFAULTED) }
|
output(Obligation.PROGRAM_ID, "Alice's defaulted $1,000,000 obligation to Bob", (oneMillionDollars.OBLIGATION between Pair(ALICE, BOB) `at` pastTestTime).copy(lifecycle = Lifecycle.DEFAULTED))
|
||||||
command(BOB_PUBKEY) { Obligation.Commands.SetLifecycle(Lifecycle.DEFAULTED) }
|
command(BOB_PUBKEY, Obligation.Commands.SetLifecycle(Lifecycle.DEFAULTED))
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
@ -600,24 +595,24 @@ class ObligationTests {
|
|||||||
// Splitting value works.
|
// Splitting value works.
|
||||||
transaction {
|
transaction {
|
||||||
attachments(Obligation.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID)
|
||||||
command(CHARLIE.owningKey) { Obligation.Commands.Move() }
|
command(CHARLIE.owningKey, Obligation.Commands.Move())
|
||||||
tweak {
|
tweak {
|
||||||
input(Obligation.PROGRAM_ID) { inState }
|
input(Obligation.PROGRAM_ID, inState)
|
||||||
repeat(4) { output(Obligation.PROGRAM_ID) { inState.copy(quantity = inState.quantity / 4) } }
|
repeat(4) { output(Obligation.PROGRAM_ID, inState.copy(quantity = inState.quantity / 4)) }
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
// Merging 4 inputs into 2 outputs works.
|
// Merging 4 inputs into 2 outputs works.
|
||||||
tweak {
|
tweak {
|
||||||
repeat(4) { input(Obligation.PROGRAM_ID) { inState.copy(quantity = inState.quantity / 4) } }
|
repeat(4) { input(Obligation.PROGRAM_ID, inState.copy(quantity = inState.quantity / 4)) }
|
||||||
output(Obligation.PROGRAM_ID) { inState.copy(quantity = inState.quantity / 2) }
|
output(Obligation.PROGRAM_ID, inState.copy(quantity = inState.quantity / 2))
|
||||||
output(Obligation.PROGRAM_ID) { inState.copy(quantity = inState.quantity / 2) }
|
output(Obligation.PROGRAM_ID, inState.copy(quantity = inState.quantity / 2))
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
// Merging 2 inputs into 1 works.
|
// Merging 2 inputs into 1 works.
|
||||||
tweak {
|
tweak {
|
||||||
input(Obligation.PROGRAM_ID) { inState.copy(quantity = inState.quantity / 2) }
|
input(Obligation.PROGRAM_ID, inState.copy(quantity = inState.quantity / 2))
|
||||||
input(Obligation.PROGRAM_ID) { inState.copy(quantity = inState.quantity / 2) }
|
input(Obligation.PROGRAM_ID, inState.copy(quantity = inState.quantity / 2))
|
||||||
output(Obligation.PROGRAM_ID) { inState }
|
output(Obligation.PROGRAM_ID, inState)
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -627,18 +622,16 @@ class ObligationTests {
|
|||||||
fun zeroSizedValues() {
|
fun zeroSizedValues() {
|
||||||
transaction {
|
transaction {
|
||||||
attachments(Obligation.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID)
|
||||||
command(CHARLIE.owningKey) { Obligation.Commands.Move() }
|
command(CHARLIE.owningKey, Obligation.Commands.Move())
|
||||||
tweak {
|
tweak {
|
||||||
input(Obligation.PROGRAM_ID) { inState }
|
input(Obligation.PROGRAM_ID, inState)
|
||||||
input(Obligation.PROGRAM_ID) { inState.copy(quantity = 0L) }
|
input(Obligation.PROGRAM_ID, inState.copy(quantity = 0L))
|
||||||
|
|
||||||
this `fails with` "zero sized inputs"
|
this `fails with` "zero sized inputs"
|
||||||
}
|
}
|
||||||
tweak {
|
tweak {
|
||||||
input(Obligation.PROGRAM_ID) { inState }
|
input(Obligation.PROGRAM_ID, inState)
|
||||||
output(Obligation.PROGRAM_ID) { inState }
|
output(Obligation.PROGRAM_ID, inState)
|
||||||
output(Obligation.PROGRAM_ID) { inState.copy(quantity = 0L) }
|
output(Obligation.PROGRAM_ID, inState.copy(quantity = 0L))
|
||||||
|
|
||||||
this `fails with` "zero sized outputs"
|
this `fails with` "zero sized outputs"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -649,41 +642,39 @@ class ObligationTests {
|
|||||||
// Can't change issuer.
|
// Can't change issuer.
|
||||||
transaction {
|
transaction {
|
||||||
attachments(Obligation.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID)
|
||||||
input(Obligation.PROGRAM_ID) { inState }
|
input(Obligation.PROGRAM_ID, inState)
|
||||||
output(Obligation.PROGRAM_ID) { outState `issued by` MINI_CORP }
|
output(Obligation.PROGRAM_ID, outState `issued by` MINI_CORP)
|
||||||
command(MINI_CORP_PUBKEY) { Obligation.Commands.Move() }
|
command(MINI_CORP_PUBKEY, Obligation.Commands.Move())
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
// Can't mix currencies.
|
// Can't mix currencies.
|
||||||
transaction {
|
transaction {
|
||||||
attachments(Obligation.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID)
|
||||||
input(Obligation.PROGRAM_ID) { inState }
|
input(Obligation.PROGRAM_ID, inState)
|
||||||
output(Obligation.PROGRAM_ID) { outState.copy(quantity = 80000, template = megaCorpDollarSettlement) }
|
output(Obligation.PROGRAM_ID, outState.copy(quantity = 80000, template = megaCorpDollarSettlement))
|
||||||
output(Obligation.PROGRAM_ID) { outState.copy(quantity = 20000, template = megaCorpPoundSettlement) }
|
output(Obligation.PROGRAM_ID, outState.copy(quantity = 20000, template = megaCorpPoundSettlement))
|
||||||
command(MINI_CORP_PUBKEY) { Obligation.Commands.Move() }
|
command(MINI_CORP_PUBKEY, Obligation.Commands.Move())
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
transaction {
|
transaction {
|
||||||
attachments(Obligation.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID)
|
||||||
input(Obligation.PROGRAM_ID) { inState }
|
input(Obligation.PROGRAM_ID, inState)
|
||||||
input(Obligation.PROGRAM_ID) {
|
input(Obligation.PROGRAM_ID,
|
||||||
inState.copy(
|
inState.copy(
|
||||||
quantity = 15000,
|
quantity = 15000,
|
||||||
template = megaCorpPoundSettlement,
|
template = megaCorpPoundSettlement,
|
||||||
beneficiary = AnonymousParty(BOB_PUBKEY)
|
beneficiary = AnonymousParty(BOB_PUBKEY)))
|
||||||
)
|
output(Obligation.PROGRAM_ID, outState.copy(quantity = 115000))
|
||||||
}
|
command(MINI_CORP_PUBKEY, Obligation.Commands.Move())
|
||||||
output(Obligation.PROGRAM_ID) { outState.copy(quantity = 115000) }
|
|
||||||
command(MINI_CORP_PUBKEY) { Obligation.Commands.Move() }
|
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
// Can't have superfluous input states from different issuers.
|
// Can't have superfluous input states from different issuers.
|
||||||
transaction {
|
transaction {
|
||||||
attachments(Obligation.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID)
|
||||||
input(Obligation.PROGRAM_ID) { inState }
|
input(Obligation.PROGRAM_ID, inState)
|
||||||
input(Obligation.PROGRAM_ID) { inState `issued by` MINI_CORP }
|
input(Obligation.PROGRAM_ID, inState `issued by` MINI_CORP)
|
||||||
output(Obligation.PROGRAM_ID) { outState }
|
output(Obligation.PROGRAM_ID, outState)
|
||||||
command(CHARLIE.owningKey) { Obligation.Commands.Move() }
|
command(CHARLIE.owningKey, Obligation.Commands.Move())
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -693,21 +684,20 @@ class ObligationTests {
|
|||||||
// Single input/output straightforward case.
|
// Single input/output straightforward case.
|
||||||
transaction {
|
transaction {
|
||||||
attachments(Obligation.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID)
|
||||||
input(Obligation.PROGRAM_ID) { inState }
|
input(Obligation.PROGRAM_ID, inState)
|
||||||
output(Obligation.PROGRAM_ID) { outState.copy(quantity = inState.quantity - 200.DOLLARS.quantity) }
|
output(Obligation.PROGRAM_ID, outState.copy(quantity = inState.quantity - 200.DOLLARS.quantity))
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(CHARLIE.owningKey) { Obligation.Commands.Exit(Amount(100.DOLLARS.quantity, inState.amount.token)) }
|
command(CHARLIE.owningKey, Obligation.Commands.Exit(Amount(100.DOLLARS.quantity, inState.amount.token)))
|
||||||
command(CHARLIE.owningKey) { Obligation.Commands.Move() }
|
command(CHARLIE.owningKey, Obligation.Commands.Move())
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(CHARLIE.owningKey) { Obligation.Commands.Exit(Amount(200.DOLLARS.quantity, inState.amount.token)) }
|
command(CHARLIE.owningKey, Obligation.Commands.Exit(Amount(200.DOLLARS.quantity, inState.amount.token)))
|
||||||
this `fails with` "required net.corda.finance.contracts.asset.Obligation.Commands.Move command"
|
this `fails with` "required net.corda.finance.contracts.asset.Obligation.Commands.Move command"
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(CHARLIE.owningKey) { Obligation.Commands.Move() }
|
command(CHARLIE.owningKey, Obligation.Commands.Move())
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -720,21 +710,15 @@ class ObligationTests {
|
|||||||
// Multi-product case.
|
// Multi-product case.
|
||||||
transaction {
|
transaction {
|
||||||
attachments(Obligation.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID)
|
||||||
|
input(Obligation.PROGRAM_ID, inState.copy(template = inState.template.copy(acceptableIssuedProducts = megaIssuedPounds)))
|
||||||
input(Obligation.PROGRAM_ID) { inState.copy(template = inState.template.copy(acceptableIssuedProducts = megaIssuedPounds)) }
|
input(Obligation.PROGRAM_ID, inState.copy(template = inState.template.copy(acceptableIssuedProducts = megaIssuedDollars)))
|
||||||
input(Obligation.PROGRAM_ID) { inState.copy(template = inState.template.copy(acceptableIssuedProducts = megaIssuedDollars)) }
|
output(Obligation.PROGRAM_ID, inState.copy(template = inState.template.copy(acceptableIssuedProducts = megaIssuedPounds), quantity = inState.quantity - 200.POUNDS.quantity))
|
||||||
|
output(Obligation.PROGRAM_ID, inState.copy(template = inState.template.copy(acceptableIssuedProducts = megaIssuedDollars), quantity = inState.quantity - 200.DOLLARS.quantity))
|
||||||
output(Obligation.PROGRAM_ID) { inState.copy(template = inState.template.copy(acceptableIssuedProducts = megaIssuedPounds), quantity = inState.quantity - 200.POUNDS.quantity) }
|
command(CHARLIE.owningKey, Obligation.Commands.Move())
|
||||||
output(Obligation.PROGRAM_ID) { inState.copy(template = inState.template.copy(acceptableIssuedProducts = megaIssuedDollars), quantity = inState.quantity - 200.DOLLARS.quantity) }
|
|
||||||
|
|
||||||
command(CHARLIE.owningKey) { Obligation.Commands.Move() }
|
|
||||||
|
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
|
command(CHARLIE.owningKey, Obligation.Commands.Exit(Amount(200.DOLLARS.quantity, inState.amount.token.copy(product = megaCorpDollarSettlement))))
|
||||||
command(CHARLIE.owningKey) { Obligation.Commands.Exit(Amount(200.DOLLARS.quantity, inState.amount.token.copy(product = megaCorpDollarSettlement))) }
|
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
|
command(CHARLIE.owningKey, Obligation.Commands.Exit(Amount(200.POUNDS.quantity, inState.amount.token.copy(product = megaCorpPoundSettlement))))
|
||||||
command(CHARLIE.owningKey) { Obligation.Commands.Exit(Amount(200.POUNDS.quantity, inState.amount.token.copy(product = megaCorpPoundSettlement))) }
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -745,27 +729,26 @@ class ObligationTests {
|
|||||||
attachments(Obligation.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID)
|
||||||
|
|
||||||
// Gather 2000 dollars from two different issuers.
|
// Gather 2000 dollars from two different issuers.
|
||||||
input(Obligation.PROGRAM_ID) { inState }
|
input(Obligation.PROGRAM_ID, inState)
|
||||||
input(Obligation.PROGRAM_ID) { inState `issued by` MINI_CORP }
|
input(Obligation.PROGRAM_ID, inState `issued by` MINI_CORP)
|
||||||
|
|
||||||
// Can't merge them together.
|
// Can't merge them together.
|
||||||
tweak {
|
tweak {
|
||||||
output(Obligation.PROGRAM_ID) { inState.copy(beneficiary = AnonymousParty(BOB_PUBKEY), quantity = 200000L) }
|
output(Obligation.PROGRAM_ID, inState.copy(beneficiary = AnonymousParty(BOB_PUBKEY), quantity = 200000L))
|
||||||
command(CHARLIE.owningKey) { Obligation.Commands.Move() }
|
command(CHARLIE.owningKey, Obligation.Commands.Move())
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
// Missing MiniCorp deposit
|
// Missing MiniCorp deposit
|
||||||
tweak {
|
tweak {
|
||||||
output(Obligation.PROGRAM_ID) { inState.copy(beneficiary = AnonymousParty(BOB_PUBKEY)) }
|
output(Obligation.PROGRAM_ID, inState.copy(beneficiary = AnonymousParty(BOB_PUBKEY)))
|
||||||
output(Obligation.PROGRAM_ID) { inState.copy(beneficiary = AnonymousParty(BOB_PUBKEY)) }
|
output(Obligation.PROGRAM_ID, inState.copy(beneficiary = AnonymousParty(BOB_PUBKEY)))
|
||||||
command(CHARLIE.owningKey) { Obligation.Commands.Move() }
|
command(CHARLIE.owningKey, Obligation.Commands.Move())
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
|
|
||||||
// This works.
|
// This works.
|
||||||
output(Obligation.PROGRAM_ID) { inState.copy(beneficiary = AnonymousParty(BOB_PUBKEY)) }
|
output(Obligation.PROGRAM_ID, inState.copy(beneficiary = AnonymousParty(BOB_PUBKEY)))
|
||||||
output(Obligation.PROGRAM_ID) { inState.copy(beneficiary = AnonymousParty(BOB_PUBKEY)) `issued by` MINI_CORP }
|
output(Obligation.PROGRAM_ID, inState.copy(beneficiary = AnonymousParty(BOB_PUBKEY)) `issued by` MINI_CORP)
|
||||||
command(CHARLIE.owningKey) { Obligation.Commands.Move() }
|
command(CHARLIE.owningKey, Obligation.Commands.Move())
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -776,12 +759,11 @@ class ObligationTests {
|
|||||||
transaction {
|
transaction {
|
||||||
attachments(Obligation.PROGRAM_ID)
|
attachments(Obligation.PROGRAM_ID)
|
||||||
val pounds = Obligation.State(Lifecycle.NORMAL, MINI_CORP, megaCorpPoundSettlement, 658.POUNDS.quantity, AnonymousParty(BOB_PUBKEY))
|
val pounds = Obligation.State(Lifecycle.NORMAL, MINI_CORP, megaCorpPoundSettlement, 658.POUNDS.quantity, AnonymousParty(BOB_PUBKEY))
|
||||||
input(Obligation.PROGRAM_ID) { inState `owned by` CHARLIE }
|
input(Obligation.PROGRAM_ID, inState `owned by` CHARLIE)
|
||||||
input(Obligation.PROGRAM_ID) { pounds }
|
input(Obligation.PROGRAM_ID, pounds)
|
||||||
output(Obligation.PROGRAM_ID) { inState `owned by` AnonymousParty(BOB_PUBKEY) }
|
output(Obligation.PROGRAM_ID, inState `owned by` AnonymousParty(BOB_PUBKEY))
|
||||||
output(Obligation.PROGRAM_ID) { pounds `owned by` CHARLIE }
|
output(Obligation.PROGRAM_ID, pounds `owned by` CHARLIE)
|
||||||
command(CHARLIE.owningKey, BOB_PUBKEY) { Obligation.Commands.Move() }
|
command(listOf(CHARLIE.owningKey, BOB_PUBKEY), Obligation.Commands.Move())
|
||||||
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -653,13 +653,13 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
|||||||
// wants to sell to Bob.
|
// wants to sell to Bob.
|
||||||
val eb1 = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
|
val eb1 = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
|
||||||
// Issued money to itself.
|
// Issued money to itself.
|
||||||
output(Cash.PROGRAM_ID, "elbonian money 1", notary = notary) { 800.DOLLARS.CASH issuedBy issuer ownedBy interimOwner }
|
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) { 1000.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) {
|
if (!withError) {
|
||||||
command(issuer.party.owningKey) { Cash.Commands.Issue() }
|
command(issuer.party.owningKey, Cash.Commands.Issue())
|
||||||
} else {
|
} else {
|
||||||
// Put a broken command on so at least a signature is created
|
// Put a broken command on so at least a signature is created
|
||||||
command(issuer.party.owningKey) { Cash.Commands.Move() }
|
command(issuer.party.owningKey, Cash.Commands.Move())
|
||||||
}
|
}
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
if (withError) {
|
if (withError) {
|
||||||
@ -672,16 +672,16 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
|||||||
// Bob gets some cash onto the ledger from BoE
|
// Bob gets some cash onto the ledger from BoE
|
||||||
val bc1 = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
|
val bc1 = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
|
||||||
input("elbonian money 1")
|
input("elbonian money 1")
|
||||||
output(Cash.PROGRAM_ID, "bob cash 1", notary = notary) { 800.DOLLARS.CASH issuedBy issuer ownedBy owner }
|
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, Cash.Commands.Move())
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
|
|
||||||
val bc2 = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
|
val bc2 = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
|
||||||
input("elbonian money 2")
|
input("elbonian money 2")
|
||||||
output(Cash.PROGRAM_ID, "bob cash 2", notary = notary) { 300.DOLLARS.CASH issuedBy issuer ownedBy owner }
|
output(Cash.PROGRAM_ID, "bob cash 2", notary = notary, contractState = 300.DOLLARS.CASH issuedBy issuer ownedBy owner)
|
||||||
output(Cash.PROGRAM_ID, notary = notary) { 700.DOLLARS.CASH issuedBy issuer ownedBy interimOwner } // Change output.
|
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, Cash.Commands.Move())
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -697,10 +697,9 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
|||||||
attachmentID: SecureHash?,
|
attachmentID: SecureHash?,
|
||||||
notary: Party): Pair<Vault<ContractState>, List<WireTransaction>> {
|
notary: Party): Pair<Vault<ContractState>, List<WireTransaction>> {
|
||||||
val ap = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
|
val ap = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
|
||||||
output(CommercialPaper.CP_PROGRAM_ID, "alice's paper", notary = notary) {
|
output(CommercialPaper.CP_PROGRAM_ID, "alice's paper", notary = notary,
|
||||||
CommercialPaper.State(issuer, owner, amount, TEST_TX_TIME + 7.days)
|
contractState = CommercialPaper.State(issuer, owner, amount, TEST_TX_TIME + 7.days))
|
||||||
}
|
command(issuer.party.owningKey, CommercialPaper.Commands.Issue())
|
||||||
command(issuer.party.owningKey) { CommercialPaper.Commands.Issue() }
|
|
||||||
if (!withError)
|
if (!withError)
|
||||||
timeWindow(time = TEST_TX_TIME)
|
timeWindow(time = TEST_TX_TIME)
|
||||||
if (attachmentID != null)
|
if (attachmentID != null)
|
||||||
|
@ -385,8 +385,8 @@ class IRSTests {
|
|||||||
return ledger {
|
return ledger {
|
||||||
transaction("Agreement") {
|
transaction("Agreement") {
|
||||||
attachments(IRS_PROGRAM_ID)
|
attachments(IRS_PROGRAM_ID)
|
||||||
output(IRS_PROGRAM_ID, "irs post agreement") { singleIRS() }
|
output(IRS_PROGRAM_ID, "irs post agreement", singleIRS())
|
||||||
command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() }
|
command(MEGA_CORP_PUBKEY, InterestRateSwap.Commands.Agree())
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
@ -395,17 +395,14 @@ class IRSTests {
|
|||||||
attachments(IRS_PROGRAM_ID)
|
attachments(IRS_PROGRAM_ID)
|
||||||
input("irs post agreement")
|
input("irs post agreement")
|
||||||
val postAgreement = "irs post agreement".output<InterestRateSwap.State>()
|
val postAgreement = "irs post agreement".output<InterestRateSwap.State>()
|
||||||
output(IRS_PROGRAM_ID, "irs post first fixing") {
|
output(IRS_PROGRAM_ID, "irs post first fixing",
|
||||||
postAgreement.copy(
|
postAgreement.copy(
|
||||||
postAgreement.fixedLeg,
|
postAgreement.fixedLeg,
|
||||||
postAgreement.floatingLeg,
|
postAgreement.floatingLeg,
|
||||||
postAgreement.calculation.applyFixing(ld, FixedRate(RatioUnit(bd))),
|
postAgreement.calculation.applyFixing(ld, FixedRate(RatioUnit(bd))),
|
||||||
postAgreement.common
|
postAgreement.common))
|
||||||
)
|
command(ORACLE_PUBKEY,
|
||||||
}
|
InterestRateSwap.Commands.Refix(Fix(FixOf("ICE LIBOR", ld, Tenor("3M")), bd)))
|
||||||
command(ORACLE_PUBKEY) {
|
|
||||||
InterestRateSwap.Commands.Refix(Fix(FixOf("ICE LIBOR", ld, Tenor("3M")), bd))
|
|
||||||
}
|
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
@ -419,7 +416,7 @@ class IRSTests {
|
|||||||
attachments(IRS_PROGRAM_ID)
|
attachments(IRS_PROGRAM_ID)
|
||||||
input(IRS_PROGRAM_ID, irs)
|
input(IRS_PROGRAM_ID, irs)
|
||||||
output(IRS_PROGRAM_ID, "irs post agreement", irs)
|
output(IRS_PROGRAM_ID, "irs post agreement", irs)
|
||||||
command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() }
|
command(MEGA_CORP_PUBKEY, InterestRateSwap.Commands.Agree())
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this `fails with` "There are no in states for an agreement"
|
this `fails with` "There are no in states for an agreement"
|
||||||
}
|
}
|
||||||
@ -432,7 +429,7 @@ class IRSTests {
|
|||||||
transaction {
|
transaction {
|
||||||
attachments(IRS_PROGRAM_ID)
|
attachments(IRS_PROGRAM_ID)
|
||||||
output(IRS_PROGRAM_ID, irs.copy(calculation = irs.calculation.copy(fixedLegPaymentSchedule = emptySchedule)))
|
output(IRS_PROGRAM_ID, irs.copy(calculation = irs.calculation.copy(fixedLegPaymentSchedule = emptySchedule)))
|
||||||
command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() }
|
command(MEGA_CORP_PUBKEY, InterestRateSwap.Commands.Agree())
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this `fails with` "There are events in the fix schedule"
|
this `fails with` "There are events in the fix schedule"
|
||||||
}
|
}
|
||||||
@ -445,7 +442,7 @@ class IRSTests {
|
|||||||
transaction {
|
transaction {
|
||||||
attachments(IRS_PROGRAM_ID)
|
attachments(IRS_PROGRAM_ID)
|
||||||
output(IRS_PROGRAM_ID, irs.copy(calculation = irs.calculation.copy(floatingLegPaymentSchedule = emptySchedule)))
|
output(IRS_PROGRAM_ID, irs.copy(calculation = irs.calculation.copy(floatingLegPaymentSchedule = emptySchedule)))
|
||||||
command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() }
|
command(MEGA_CORP_PUBKEY, InterestRateSwap.Commands.Agree())
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this `fails with` "There are events in the float schedule"
|
this `fails with` "There are events in the float schedule"
|
||||||
}
|
}
|
||||||
@ -457,7 +454,7 @@ class IRSTests {
|
|||||||
transaction {
|
transaction {
|
||||||
attachments(IRS_PROGRAM_ID)
|
attachments(IRS_PROGRAM_ID)
|
||||||
output(IRS_PROGRAM_ID, irs.copy(irs.fixedLeg.copy(notional = irs.fixedLeg.notional.copy(quantity = 0))))
|
output(IRS_PROGRAM_ID, irs.copy(irs.fixedLeg.copy(notional = irs.fixedLeg.notional.copy(quantity = 0))))
|
||||||
command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() }
|
command(MEGA_CORP_PUBKEY, InterestRateSwap.Commands.Agree())
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this `fails with` "All notionals must be non zero"
|
this `fails with` "All notionals must be non zero"
|
||||||
}
|
}
|
||||||
@ -465,7 +462,7 @@ class IRSTests {
|
|||||||
transaction {
|
transaction {
|
||||||
attachments(IRS_PROGRAM_ID)
|
attachments(IRS_PROGRAM_ID)
|
||||||
output(IRS_PROGRAM_ID, irs.copy(irs.fixedLeg.copy(notional = irs.floatingLeg.notional.copy(quantity = 0))))
|
output(IRS_PROGRAM_ID, irs.copy(irs.fixedLeg.copy(notional = irs.floatingLeg.notional.copy(quantity = 0))))
|
||||||
command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() }
|
command(MEGA_CORP_PUBKEY, InterestRateSwap.Commands.Agree())
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this `fails with` "All notionals must be non zero"
|
this `fails with` "All notionals must be non zero"
|
||||||
}
|
}
|
||||||
@ -478,7 +475,7 @@ class IRSTests {
|
|||||||
transaction {
|
transaction {
|
||||||
attachments(IRS_PROGRAM_ID)
|
attachments(IRS_PROGRAM_ID)
|
||||||
output(IRS_PROGRAM_ID, modifiedIRS)
|
output(IRS_PROGRAM_ID, modifiedIRS)
|
||||||
command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() }
|
command(MEGA_CORP_PUBKEY, InterestRateSwap.Commands.Agree())
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this `fails with` "The fixed leg rate must be positive"
|
this `fails with` "The fixed leg rate must be positive"
|
||||||
}
|
}
|
||||||
@ -494,7 +491,7 @@ class IRSTests {
|
|||||||
transaction {
|
transaction {
|
||||||
attachments(IRS_PROGRAM_ID)
|
attachments(IRS_PROGRAM_ID)
|
||||||
output(IRS_PROGRAM_ID, modifiedIRS)
|
output(IRS_PROGRAM_ID, modifiedIRS)
|
||||||
command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() }
|
command(MEGA_CORP_PUBKEY, InterestRateSwap.Commands.Agree())
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this `fails with` "The currency of the notionals must be the same"
|
this `fails with` "The currency of the notionals must be the same"
|
||||||
}
|
}
|
||||||
@ -507,7 +504,7 @@ class IRSTests {
|
|||||||
transaction {
|
transaction {
|
||||||
attachments(IRS_PROGRAM_ID)
|
attachments(IRS_PROGRAM_ID)
|
||||||
output(IRS_PROGRAM_ID, modifiedIRS)
|
output(IRS_PROGRAM_ID, modifiedIRS)
|
||||||
command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() }
|
command(MEGA_CORP_PUBKEY, InterestRateSwap.Commands.Agree())
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this `fails with` "All leg notionals must be the same"
|
this `fails with` "All leg notionals must be the same"
|
||||||
}
|
}
|
||||||
@ -520,7 +517,7 @@ class IRSTests {
|
|||||||
transaction {
|
transaction {
|
||||||
attachments(IRS_PROGRAM_ID)
|
attachments(IRS_PROGRAM_ID)
|
||||||
output(IRS_PROGRAM_ID, modifiedIRS1)
|
output(IRS_PROGRAM_ID, modifiedIRS1)
|
||||||
command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() }
|
command(MEGA_CORP_PUBKEY, InterestRateSwap.Commands.Agree())
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this `fails with` "The effective date is before the termination date for the fixed leg"
|
this `fails with` "The effective date is before the termination date for the fixed leg"
|
||||||
}
|
}
|
||||||
@ -529,7 +526,7 @@ class IRSTests {
|
|||||||
transaction {
|
transaction {
|
||||||
attachments(IRS_PROGRAM_ID)
|
attachments(IRS_PROGRAM_ID)
|
||||||
output(IRS_PROGRAM_ID, modifiedIRS2)
|
output(IRS_PROGRAM_ID, modifiedIRS2)
|
||||||
command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() }
|
command(MEGA_CORP_PUBKEY, InterestRateSwap.Commands.Agree())
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this `fails with` "The effective date is before the termination date for the floating leg"
|
this `fails with` "The effective date is before the termination date for the floating leg"
|
||||||
}
|
}
|
||||||
@ -543,7 +540,7 @@ class IRSTests {
|
|||||||
transaction {
|
transaction {
|
||||||
attachments(IRS_PROGRAM_ID)
|
attachments(IRS_PROGRAM_ID)
|
||||||
output(IRS_PROGRAM_ID, modifiedIRS3)
|
output(IRS_PROGRAM_ID, modifiedIRS3)
|
||||||
command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() }
|
command(MEGA_CORP_PUBKEY, InterestRateSwap.Commands.Agree())
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this `fails with` "The termination dates are aligned"
|
this `fails with` "The termination dates are aligned"
|
||||||
}
|
}
|
||||||
@ -553,7 +550,7 @@ class IRSTests {
|
|||||||
transaction {
|
transaction {
|
||||||
attachments(IRS_PROGRAM_ID)
|
attachments(IRS_PROGRAM_ID)
|
||||||
output(IRS_PROGRAM_ID, modifiedIRS4)
|
output(IRS_PROGRAM_ID, modifiedIRS4)
|
||||||
command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() }
|
command(MEGA_CORP_PUBKEY, InterestRateSwap.Commands.Agree())
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this `fails with` "The effective dates are aligned"
|
this `fails with` "The effective dates are aligned"
|
||||||
}
|
}
|
||||||
@ -567,8 +564,8 @@ class IRSTests {
|
|||||||
|
|
||||||
transaction {
|
transaction {
|
||||||
attachments(IRS_PROGRAM_ID)
|
attachments(IRS_PROGRAM_ID)
|
||||||
output(IRS_PROGRAM_ID, "irs post agreement") { singleIRS() }
|
output(IRS_PROGRAM_ID, "irs post agreement", singleIRS())
|
||||||
command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() }
|
command(MEGA_CORP_PUBKEY, InterestRateSwap.Commands.Agree())
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
@ -585,9 +582,8 @@ class IRSTests {
|
|||||||
|
|
||||||
// Templated tweak for reference. A corrent fixing applied should be ok
|
// Templated tweak for reference. A corrent fixing applied should be ok
|
||||||
tweak {
|
tweak {
|
||||||
command(ORACLE_PUBKEY) {
|
command(ORACLE_PUBKEY,
|
||||||
InterestRateSwap.Commands.Refix(Fix(FixOf("ICE LIBOR", ld, Tenor("3M")), bd))
|
InterestRateSwap.Commands.Refix(Fix(FixOf("ICE LIBOR", ld, Tenor("3M")), bd)))
|
||||||
}
|
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
output(IRS_PROGRAM_ID, newIRS)
|
output(IRS_PROGRAM_ID, newIRS)
|
||||||
this.verifies()
|
this.verifies()
|
||||||
@ -595,7 +591,7 @@ class IRSTests {
|
|||||||
|
|
||||||
// This test makes sure that verify confirms the fixing was applied and there is a difference in the old and new
|
// This test makes sure that verify confirms the fixing was applied and there is a difference in the old and new
|
||||||
tweak {
|
tweak {
|
||||||
command(ORACLE_PUBKEY) { InterestRateSwap.Commands.Refix(Fix(FixOf("ICE LIBOR", ld, Tenor("3M")), bd)) }
|
command(ORACLE_PUBKEY, InterestRateSwap.Commands.Refix(Fix(FixOf("ICE LIBOR", ld, Tenor("3M")), bd)))
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
output(IRS_PROGRAM_ID, oldIRS)
|
output(IRS_PROGRAM_ID, oldIRS)
|
||||||
this `fails with` "There is at least one difference in the IRS floating leg payment schedules"
|
this `fails with` "There is at least one difference in the IRS floating leg payment schedules"
|
||||||
@ -603,42 +599,36 @@ class IRSTests {
|
|||||||
|
|
||||||
// This tests tries to sneak in a change to another fixing (which may or may not be the latest one)
|
// This tests tries to sneak in a change to another fixing (which may or may not be the latest one)
|
||||||
tweak {
|
tweak {
|
||||||
command(ORACLE_PUBKEY) { InterestRateSwap.Commands.Refix(Fix(FixOf("ICE LIBOR", ld, Tenor("3M")), bd)) }
|
command(ORACLE_PUBKEY, InterestRateSwap.Commands.Refix(Fix(FixOf("ICE LIBOR", ld, Tenor("3M")), bd)))
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
|
|
||||||
val firstResetKey = newIRS.calculation.floatingLegPaymentSchedule.keys.toList()[1]
|
val firstResetKey = newIRS.calculation.floatingLegPaymentSchedule.keys.toList()[1]
|
||||||
val firstResetValue = newIRS.calculation.floatingLegPaymentSchedule[firstResetKey]
|
val firstResetValue = newIRS.calculation.floatingLegPaymentSchedule[firstResetKey]
|
||||||
val modifiedFirstResetValue = firstResetValue!!.copy(notional = Amount(firstResetValue.notional.quantity, Currency.getInstance("JPY")))
|
val modifiedFirstResetValue = firstResetValue!!.copy(notional = Amount(firstResetValue.notional.quantity, Currency.getInstance("JPY")))
|
||||||
|
output(IRS_PROGRAM_ID,
|
||||||
output(IRS_PROGRAM_ID) {
|
|
||||||
newIRS.copy(
|
newIRS.copy(
|
||||||
newIRS.fixedLeg,
|
newIRS.fixedLeg,
|
||||||
newIRS.floatingLeg,
|
newIRS.floatingLeg,
|
||||||
newIRS.calculation.copy(floatingLegPaymentSchedule = newIRS.calculation.floatingLegPaymentSchedule.plus(
|
newIRS.calculation.copy(floatingLegPaymentSchedule = newIRS.calculation.floatingLegPaymentSchedule.plus(
|
||||||
Pair(firstResetKey, modifiedFirstResetValue))),
|
Pair(firstResetKey, modifiedFirstResetValue))),
|
||||||
newIRS.common
|
newIRS.common))
|
||||||
)
|
|
||||||
}
|
|
||||||
this `fails with` "There is only one change in the IRS floating leg payment schedule"
|
this `fails with` "There is only one change in the IRS floating leg payment schedule"
|
||||||
}
|
}
|
||||||
|
|
||||||
// This tests modifies the payment currency for the fixing
|
// This tests modifies the payment currency for the fixing
|
||||||
tweak {
|
tweak {
|
||||||
command(ORACLE_PUBKEY) { InterestRateSwap.Commands.Refix(Fix(FixOf("ICE LIBOR", ld, Tenor("3M")), bd)) }
|
command(ORACLE_PUBKEY, InterestRateSwap.Commands.Refix(Fix(FixOf("ICE LIBOR", ld, Tenor("3M")), bd)))
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
|
|
||||||
val latestReset = newIRS.calculation.floatingLegPaymentSchedule.filter { it.value.rate is FixedRate }.maxBy { it.key }
|
val latestReset = newIRS.calculation.floatingLegPaymentSchedule.filter { it.value.rate is FixedRate }.maxBy { it.key }
|
||||||
val modifiedLatestResetValue = latestReset!!.value.copy(notional = Amount(latestReset.value.notional.quantity, Currency.getInstance("JPY")))
|
val modifiedLatestResetValue = latestReset!!.value.copy(notional = Amount(latestReset.value.notional.quantity, Currency.getInstance("JPY")))
|
||||||
|
output(IRS_PROGRAM_ID,
|
||||||
output(IRS_PROGRAM_ID) {
|
|
||||||
newIRS.copy(
|
newIRS.copy(
|
||||||
newIRS.fixedLeg,
|
newIRS.fixedLeg,
|
||||||
newIRS.floatingLeg,
|
newIRS.floatingLeg,
|
||||||
newIRS.calculation.copy(floatingLegPaymentSchedule = newIRS.calculation.floatingLegPaymentSchedule.plus(
|
newIRS.calculation.copy(floatingLegPaymentSchedule = newIRS.calculation.floatingLegPaymentSchedule.plus(
|
||||||
Pair(latestReset.key, modifiedLatestResetValue))),
|
Pair(latestReset.key, modifiedLatestResetValue))),
|
||||||
newIRS.common
|
newIRS.common))
|
||||||
)
|
|
||||||
}
|
|
||||||
this `fails with` "The fix payment has the same currency as the notional"
|
this `fails with` "The fix payment has the same currency as the notional"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -660,31 +650,27 @@ class IRSTests {
|
|||||||
return ledger {
|
return ledger {
|
||||||
transaction("Agreement") {
|
transaction("Agreement") {
|
||||||
attachments(IRS_PROGRAM_ID)
|
attachments(IRS_PROGRAM_ID)
|
||||||
output(IRS_PROGRAM_ID, "irs post agreement1") {
|
output(IRS_PROGRAM_ID, "irs post agreement1",
|
||||||
irs.copy(
|
irs.copy(
|
||||||
irs.fixedLeg,
|
irs.fixedLeg,
|
||||||
irs.floatingLeg,
|
irs.floatingLeg,
|
||||||
irs.calculation,
|
irs.calculation,
|
||||||
irs.common.copy(tradeID = "t1")
|
irs.common.copy(tradeID = "t1")))
|
||||||
)
|
command(MEGA_CORP_PUBKEY, InterestRateSwap.Commands.Agree())
|
||||||
}
|
|
||||||
command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() }
|
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
|
|
||||||
transaction("Agreement") {
|
transaction("Agreement") {
|
||||||
attachments(IRS_PROGRAM_ID)
|
attachments(IRS_PROGRAM_ID)
|
||||||
output(IRS_PROGRAM_ID, "irs post agreement2") {
|
output(IRS_PROGRAM_ID, "irs post agreement2",
|
||||||
irs.copy(
|
irs.copy(
|
||||||
linearId = UniqueIdentifier("t2"),
|
linearId = UniqueIdentifier("t2"),
|
||||||
fixedLeg = irs.fixedLeg,
|
fixedLeg = irs.fixedLeg,
|
||||||
floatingLeg = irs.floatingLeg,
|
floatingLeg = irs.floatingLeg,
|
||||||
calculation = irs.calculation,
|
calculation = irs.calculation,
|
||||||
common = irs.common.copy(tradeID = "t2")
|
common = irs.common.copy(tradeID = "t2")))
|
||||||
)
|
command(MEGA_CORP_PUBKEY, InterestRateSwap.Commands.Agree())
|
||||||
}
|
|
||||||
command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() }
|
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
@ -694,27 +680,21 @@ class IRSTests {
|
|||||||
input("irs post agreement1")
|
input("irs post agreement1")
|
||||||
input("irs post agreement2")
|
input("irs post agreement2")
|
||||||
val postAgreement1 = "irs post agreement1".output<InterestRateSwap.State>()
|
val postAgreement1 = "irs post agreement1".output<InterestRateSwap.State>()
|
||||||
output(IRS_PROGRAM_ID, "irs post first fixing1") {
|
output(IRS_PROGRAM_ID, "irs post first fixing1",
|
||||||
postAgreement1.copy(
|
postAgreement1.copy(
|
||||||
postAgreement1.fixedLeg,
|
postAgreement1.fixedLeg,
|
||||||
postAgreement1.floatingLeg,
|
postAgreement1.floatingLeg,
|
||||||
postAgreement1.calculation.applyFixing(ld1, FixedRate(RatioUnit(bd1))),
|
postAgreement1.calculation.applyFixing(ld1, FixedRate(RatioUnit(bd1))),
|
||||||
postAgreement1.common.copy(tradeID = "t1")
|
postAgreement1.common.copy(tradeID = "t1")))
|
||||||
)
|
|
||||||
}
|
|
||||||
val postAgreement2 = "irs post agreement2".output<InterestRateSwap.State>()
|
val postAgreement2 = "irs post agreement2".output<InterestRateSwap.State>()
|
||||||
output(IRS_PROGRAM_ID, "irs post first fixing2") {
|
output(IRS_PROGRAM_ID, "irs post first fixing2",
|
||||||
postAgreement2.copy(
|
postAgreement2.copy(
|
||||||
postAgreement2.fixedLeg,
|
postAgreement2.fixedLeg,
|
||||||
postAgreement2.floatingLeg,
|
postAgreement2.floatingLeg,
|
||||||
postAgreement2.calculation.applyFixing(ld1, FixedRate(RatioUnit(bd1))),
|
postAgreement2.calculation.applyFixing(ld1, FixedRate(RatioUnit(bd1))),
|
||||||
postAgreement2.common.copy(tradeID = "t2")
|
postAgreement2.common.copy(tradeID = "t2")))
|
||||||
)
|
command(ORACLE_PUBKEY,
|
||||||
}
|
InterestRateSwap.Commands.Refix(Fix(FixOf("ICE LIBOR", ld1, Tenor("3M")), bd1)))
|
||||||
|
|
||||||
command(ORACLE_PUBKEY) {
|
|
||||||
InterestRateSwap.Commands.Refix(Fix(FixOf("ICE LIBOR", ld1, Tenor("3M")), bd1))
|
|
||||||
}
|
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ data class TestTransactionDSLInterpreter private constructor(
|
|||||||
transactionBuilder.addInputState(StateAndRef(state, stateRef))
|
transactionBuilder.addInputState(StateAndRef(state, stateRef))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun _output(contractClassName: ContractClassName,
|
override fun output(contractClassName: ContractClassName,
|
||||||
label: String?,
|
label: String?,
|
||||||
notary: Party,
|
notary: Party,
|
||||||
encumbrance: Int?,
|
encumbrance: Int?,
|
||||||
@ -115,7 +115,7 @@ data class TestTransactionDSLInterpreter private constructor(
|
|||||||
transactionBuilder.addAttachment(attachmentId)
|
transactionBuilder.addAttachment(attachmentId)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun _command(signers: List<PublicKey>, commandData: CommandData) {
|
override fun command(signers: List<PublicKey>, commandData: CommandData) {
|
||||||
val command = Command(commandData, signers)
|
val command = Command(commandData, signers)
|
||||||
transactionBuilder.addCommand(command)
|
transactionBuilder.addCommand(command)
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ interface TransactionDSLInterpreter : Verifies, OutputStateLookup {
|
|||||||
* @param contractState The state itself.
|
* @param contractState The state itself.
|
||||||
* @param contractClassName The class name of the contract that verifies this state.
|
* @param contractClassName The class name of the contract that verifies this state.
|
||||||
*/
|
*/
|
||||||
fun _output(contractClassName: ContractClassName,
|
fun output(contractClassName: ContractClassName,
|
||||||
label: String?,
|
label: String?,
|
||||||
notary: Party,
|
notary: Party,
|
||||||
encumbrance: Int?,
|
encumbrance: Int?,
|
||||||
@ -53,7 +53,7 @@ interface TransactionDSLInterpreter : Verifies, OutputStateLookup {
|
|||||||
* @param signers The signer public keys.
|
* @param signers The signer public keys.
|
||||||
* @param commandData The contents of the command.
|
* @param commandData The contents of the command.
|
||||||
*/
|
*/
|
||||||
fun _command(signers: List<PublicKey>, commandData: CommandData)
|
fun command(signers: List<PublicKey>, commandData: CommandData)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the time-window of the transaction.
|
* Sets the time-window of the transaction.
|
||||||
@ -74,10 +74,10 @@ interface TransactionDSLInterpreter : Verifies, OutputStateLookup {
|
|||||||
fun _attachment(contractClassName: ContractClassName)
|
fun _attachment(contractClassName: ContractClassName)
|
||||||
}
|
}
|
||||||
|
|
||||||
class TransactionDSL<out T : TransactionDSLInterpreter>(val interpreter: T) : TransactionDSLInterpreter by interpreter {
|
class TransactionDSL<out T : TransactionDSLInterpreter>(interpreter: T) : TransactionDSLInterpreter by interpreter {
|
||||||
/**
|
/**
|
||||||
* Looks up the output label and adds the found state as an input.
|
* Looks up the output label and adds the found state as an input.
|
||||||
* @param stateLabel The label of the output state specified when calling [TransactionDSLInterpreter._output] and friends.
|
* @param stateLabel The label of the output state specified when calling [TransactionDSLInterpreter.output] and friends.
|
||||||
*/
|
*/
|
||||||
fun input(stateLabel: String) = input(retrieveOutputStateAndRef(ContractState::class.java, stateLabel).ref)
|
fun input(stateLabel: String) = input(retrieveOutputStateAndRef(ContractState::class.java, stateLabel).ref)
|
||||||
|
|
||||||
@ -88,49 +88,51 @@ class TransactionDSL<out T : TransactionDSLInterpreter>(val interpreter: T) : Tr
|
|||||||
*/
|
*/
|
||||||
fun input(contractClassName: ContractClassName, state: ContractState) {
|
fun input(contractClassName: ContractClassName, state: ContractState) {
|
||||||
val transaction = ledgerInterpreter._unverifiedTransaction(null, TransactionBuilder(notary = DUMMY_NOTARY)) {
|
val transaction = ledgerInterpreter._unverifiedTransaction(null, TransactionBuilder(notary = DUMMY_NOTARY)) {
|
||||||
output(contractClassName, attachmentConstraint = AlwaysAcceptAttachmentConstraint) { state }
|
output(contractClassName, null, DUMMY_NOTARY, null, AlwaysAcceptAttachmentConstraint, state)
|
||||||
}
|
}
|
||||||
input(transaction.outRef<ContractState>(0).ref)
|
input(transaction.outRef<ContractState>(0).ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun input(contractClassName: ContractClassName, stateClosure: () -> ContractState) = input(contractClassName, stateClosure())
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an output to the transaction.
|
* Adds a labelled output to the transaction.
|
||||||
*/
|
*/
|
||||||
@JvmOverloads
|
fun output(contractClassName: ContractClassName, label: String, notary: Party, contractState: ContractState) =
|
||||||
fun output(contractClassName: ContractClassName,
|
output(contractClassName, label, notary, null, AutomaticHashConstraint, contractState)
|
||||||
label: String? = null,
|
|
||||||
notary: Party = DUMMY_NOTARY,
|
|
||||||
encumbrance: Int? = null,
|
|
||||||
attachmentConstraint: AttachmentConstraint = AutomaticHashConstraint,
|
|
||||||
contractStateClosure: () -> ContractState) =
|
|
||||||
_output(contractClassName, label, notary, encumbrance, attachmentConstraint, contractStateClosure())
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a labelled output to the transaction.
|
* Adds a labelled output to the transaction.
|
||||||
*/
|
*/
|
||||||
@JvmOverloads
|
fun output(contractClassName: ContractClassName, label: String, encumbrance: Int, contractState: ContractState) =
|
||||||
fun output(contractClassName: ContractClassName, label: String, contractState: ContractState, attachmentConstraint: AttachmentConstraint = AutomaticHashConstraint) =
|
output(contractClassName, label, DUMMY_NOTARY, encumbrance, AutomaticHashConstraint, contractState)
|
||||||
_output(contractClassName, label, DUMMY_NOTARY, null, attachmentConstraint, contractState)
|
|
||||||
|
/**
|
||||||
|
* Adds a labelled output to the transaction.
|
||||||
|
*/
|
||||||
|
fun output(contractClassName: ContractClassName, label: String, contractState: ContractState) =
|
||||||
|
output(contractClassName, label, DUMMY_NOTARY, null, AutomaticHashConstraint, contractState)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an output to the transaction.
|
* Adds an output to the transaction.
|
||||||
*/
|
*/
|
||||||
@JvmOverloads
|
fun output(contractClassName: ContractClassName, notary: Party, contractState: ContractState) =
|
||||||
fun output(contractClassName: ContractClassName, contractState: ContractState, attachmentConstraint: AttachmentConstraint = AutomaticHashConstraint) =
|
output(contractClassName, null, notary, null, AutomaticHashConstraint, contractState)
|
||||||
_output(contractClassName, null, DUMMY_NOTARY, null, attachmentConstraint, contractState)
|
|
||||||
|
/**
|
||||||
|
* Adds an output to the transaction.
|
||||||
|
*/
|
||||||
|
fun output(contractClassName: ContractClassName, encumbrance: Int, contractState: ContractState) =
|
||||||
|
output(contractClassName, null, DUMMY_NOTARY, encumbrance, AutomaticHashConstraint, contractState)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an output to the transaction.
|
||||||
|
*/
|
||||||
|
fun output(contractClassName: ContractClassName, contractState: ContractState) =
|
||||||
|
output(contractClassName, null, DUMMY_NOTARY, null, AutomaticHashConstraint, contractState)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a command to the transaction.
|
* Adds a command to the transaction.
|
||||||
*/
|
*/
|
||||||
fun command(vararg signers: PublicKey, commandDataClosure: () -> CommandData) =
|
fun command(signer: PublicKey, commandData: CommandData) = command(listOf(signer), commandData)
|
||||||
_command(listOf(*signers), commandDataClosure())
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a command to the transaction.
|
|
||||||
*/
|
|
||||||
fun command(signer: PublicKey, commandData: CommandData) = _command(listOf(signer), commandData)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the [TimeWindow] of the transaction.
|
* Sets the [TimeWindow] of the transaction.
|
||||||
@ -142,7 +144,7 @@ class TransactionDSL<out T : TransactionDSLInterpreter>(val interpreter: T) : Tr
|
|||||||
timeWindow(TimeWindow.withTolerance(time, tolerance))
|
timeWindow(TimeWindow.withTolerance(time, tolerance))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see TransactionDSLInterpreter._contractAttachment
|
* @see TransactionDSLInterpreter._attachment
|
||||||
*/
|
*/
|
||||||
fun attachment(contractClassName: ContractClassName) = _attachment(contractClassName)
|
fun attachment(contractClassName: ContractClassName) = _attachment(contractClassName)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user