= listOf(obligor, beneficiary)
@@ -491,7 +490,7 @@ class Obligation : Contract {
tx.withItems(*inputs)
val out = states.reduce(State
::net)
if (out.quantity > 0L)
- tx.addOutputState(out)
+ tx.addOutputState(out, OBLIGATION_PROGRAM_ID)
tx.addCommand(Commands.Net(NetType.PAYMENT), signer.owningKey)
}
@@ -534,7 +533,7 @@ class Obligation
: Contract {
beneficiary: AbstractParty,
notary: Party) {
val issuanceDef = Terms(NonEmptySet.of(acceptableContract), NonEmptySet.of(amount.token), dueBefore)
- OnLedgerAsset.generateIssue(tx, TransactionState(State(Lifecycle.NORMAL, obligor, issuanceDef, amount.quantity, beneficiary), notary), Commands.Issue())
+ OnLedgerAsset.generateIssue(tx, TransactionState(State(Lifecycle.NORMAL, obligor, issuanceDef, amount.quantity, beneficiary), OBLIGATION_PROGRAM_ID, notary), Commands.Issue())
}
/**
@@ -554,7 +553,7 @@ class Obligation
: Contract {
pennies: Long,
beneficiary: AbstractParty,
notary: Party)
- = OnLedgerAsset.generateIssue(tx, TransactionState(State(Lifecycle.NORMAL, obligor, issuanceDef, pennies, beneficiary), notary), Commands.Issue())
+ = OnLedgerAsset.generateIssue(tx, TransactionState(State(Lifecycle.NORMAL, obligor, issuanceDef, pennies, beneficiary), OBLIGATION_PROGRAM_ID, notary), Commands.Issue())
fun generatePaymentNetting(tx: TransactionBuilder,
issued: Issued>,
@@ -587,7 +586,7 @@ class Obligation : Contract {
netState.template, entry.value.quantity, entry.key.second)
}
// Add the new states to the TX
- .forEach { tx.addOutputState(it, notary) }
+ .forEach { tx.addOutputState(it, OBLIGATION_PROGRAM_ID, notary) }
tx.addCommand(Commands.Net(NetType.PAYMENT), signers.map { it.owningKey })
}
@@ -618,7 +617,7 @@ class Obligation
: Contract {
stateAndRefs.forEach { stateAndRef ->
val outState = stateAndRef.state.data.copy(lifecycle = lifecycle)
tx.addInputState(stateAndRef)
- tx.addOutputState(outState, notary)
+ tx.addOutputState(outState, OBLIGATION_PROGRAM_ID, notary)
partiesUsed.add(stateAndRef.state.data.beneficiary)
}
tx.addCommand(Commands.SetLifecycle(lifecycle), partiesUsed.map { it.owningKey }.distinct())
@@ -671,13 +670,13 @@ class Obligation
: Contract {
val assetState = ref.state.data
val amount = Amount(assetState.amount.quantity, assetState.amount.token.product)
if (obligationRemaining >= amount) {
- tx.addOutputState(assetState.withNewOwnerAndAmount(assetState.amount, obligationOwner), notary)
+ tx.addOutputState(assetState.withNewOwnerAndAmount(assetState.amount, obligationOwner), OBLIGATION_PROGRAM_ID, notary)
obligationRemaining -= amount
} else {
val change = Amount(obligationRemaining.quantity, assetState.amount.token)
// Split the state in two, sending the change back to the previous beneficiary
- tx.addOutputState(assetState.withNewOwnerAndAmount(change, obligationOwner), notary)
- tx.addOutputState(assetState.withNewOwnerAndAmount(assetState.amount - change, assetState.owner), notary)
+ tx.addOutputState(assetState.withNewOwnerAndAmount(change, obligationOwner), OBLIGATION_PROGRAM_ID, notary)
+ tx.addOutputState(assetState.withNewOwnerAndAmount(assetState.amount - change, assetState.owner), OBLIGATION_PROGRAM_ID, notary)
obligationRemaining -= Amount(0L, obligationRemaining.token)
}
assetSigners.add(assetState.owner)
@@ -686,7 +685,7 @@ class Obligation
: Contract {
// If we haven't cleared the full obligation, add the remainder as an output
if (obligationRemaining.quantity > 0L) {
- tx.addOutputState(State(Lifecycle.NORMAL, obligationIssuer, template, obligationRemaining.quantity, obligationOwner), notary)
+ tx.addOutputState(State(Lifecycle.NORMAL, obligationIssuer, template, obligationRemaining.quantity, obligationOwner), OBLIGATION_PROGRAM_ID, notary)
} else {
// Destroy all of the states
}
diff --git a/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt b/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt
index bac6013f74..6d49e057b2 100644
--- a/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt
+++ b/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt
@@ -224,7 +224,7 @@ object TwoPartyTradeFlow {
tx.addInputState(assetForSale)
val (command, state) = assetForSale.state.data.withNewOwner(buyerAnonymousIdentity.party)
- tx.addOutputState(state, assetForSale.state.notary)
+ tx.addOutputState(state, assetForSale.state.contract, assetForSale.state.notary)
tx.addCommand(command, assetForSale.state.data.owner.owningKey)
// We set the transaction's time-window: it may be that none of the contracts need this!
diff --git a/finance/src/test/java/net/corda/finance/contracts/asset/CashTestsJava.java b/finance/src/test/java/net/corda/finance/contracts/asset/CashTestsJava.java
index fabf51ef34..a84067082c 100644
--- a/finance/src/test/java/net/corda/finance/contracts/asset/CashTestsJava.java
+++ b/finance/src/test/java/net/corda/finance/contracts/asset/CashTestsJava.java
@@ -19,41 +19,42 @@ public class CashTestsJava {
private final PartyAndReference defaultIssuer = getMEGA_CORP().ref(defaultRef);
private final Cash.State inState = new Cash.State(issuedBy(DOLLARS(1000), defaultIssuer), new AnonymousParty(getMEGA_CORP_PUBKEY()));
private final Cash.State outState = new Cash.State(inState.getAmount(), new AnonymousParty(getMINI_CORP_PUBKEY()));
+ private final String CASH_PROGRAM_ID = CashUtilities.getCASH_PROGRAM_ID();
@Test
public void trivial() {
transaction(tx -> {
- tx.input(inState);
+ tx.input(CASH_PROGRAM_ID, inState);
tx.tweak(tw -> {
- tw.output(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());
return tw.failsWith("the amounts balance");
});
tx.tweak(tw -> {
- tw.output(outState);
+ tw.output(CASH_PROGRAM_ID, outState);
tw.command(getMEGA_CORP_PUBKEY(), DummyCommandData.INSTANCE);
// Invalid command
return tw.failsWith("required net.corda.finance.contracts.asset.Cash.Commands.Move command");
});
tx.tweak(tw -> {
- tw.output(outState);
+ tw.output(CASH_PROGRAM_ID, outState);
tw.command(getMINI_CORP_PUBKEY(), new Cash.Commands.Move());
return tw.failsWith("the owning keys are a subset of the signing keys");
});
tx.tweak(tw -> {
- tw.output(outState);
+ tw.output(CASH_PROGRAM_ID, outState);
// issuedBy() can't be directly imported because it conflicts with other identically named functions
// with different overloads (for some reason).
- tw.output(outState.issuedBy(getMINI_CORP()));
+ tw.output(CASH_PROGRAM_ID, outState.issuedBy(getMINI_CORP()));
tw.command(getMEGA_CORP_PUBKEY(), new Cash.Commands.Move());
return tw.failsWith("at least one cash input");
});
// Simple reallocation works.
return tx.tweak(tw -> {
- tw.output(outState);
+ tw.output(CASH_PROGRAM_ID, outState);
tw.command(getMEGA_CORP_PUBKEY(), new Cash.Commands.Move());
return tw.verifies();
});
diff --git a/finance/src/test/kotlin/net/corda/finance/contracts/CommercialPaperTests.kt b/finance/src/test/kotlin/net/corda/finance/contracts/CommercialPaperTests.kt
index e72638806f..104c7d802a 100644
--- a/finance/src/test/kotlin/net/corda/finance/contracts/CommercialPaperTests.kt
+++ b/finance/src/test/kotlin/net/corda/finance/contracts/CommercialPaperTests.kt
@@ -31,6 +31,7 @@ interface ICommercialPaperTestTemplate {
fun getIssueCommand(notary: Party): CommandData
fun getRedeemCommand(notary: Party): CommandData
fun getMoveCommand(): CommandData
+ fun getContract(): ContractClassName
}
class JavaCommercialPaperTest : ICommercialPaperTestTemplate {
@@ -44,6 +45,7 @@ class JavaCommercialPaperTest : ICommercialPaperTestTemplate {
override fun getIssueCommand(notary: Party): CommandData = JavaCommercialPaper.Commands.Issue()
override fun getRedeemCommand(notary: Party): CommandData = JavaCommercialPaper.Commands.Redeem()
override fun getMoveCommand(): CommandData = JavaCommercialPaper.Commands.Move()
+ override fun getContract() = JavaCommercialPaper.JCP_PROGRAM_ID
}
class KotlinCommercialPaperTest : ICommercialPaperTestTemplate {
@@ -57,6 +59,7 @@ class KotlinCommercialPaperTest : ICommercialPaperTestTemplate {
override fun getIssueCommand(notary: Party): CommandData = CommercialPaper.Commands.Issue()
override fun getRedeemCommand(notary: Party): CommandData = CommercialPaper.Commands.Redeem()
override fun getMoveCommand(): CommandData = CommercialPaper.Commands.Move()
+ override fun getContract() = CommercialPaper.CP_PROGRAM_ID
}
class KotlinCommercialPaperLegacyTest : ICommercialPaperTestTemplate {
@@ -70,6 +73,7 @@ class KotlinCommercialPaperLegacyTest : ICommercialPaperTestTemplate {
override fun getIssueCommand(notary: Party): CommandData = CommercialPaper.Commands.Issue()
override fun getRedeemCommand(notary: Party): CommandData = CommercialPaper.Commands.Redeem()
override fun getMoveCommand(): CommandData = CommercialPaper.Commands.Move()
+ override fun getContract() = CommercialPaper.CP_PROGRAM_ID
}
@RunWith(Parameterized::class)
@@ -89,13 +93,13 @@ class CommercialPaperTestsGeneric {
val someProfits = 1200.DOLLARS `issued by` issuer
ledger {
unverifiedTransaction {
- output("alice's $900", 900.DOLLARS.CASH `issued by` issuer `owned by` ALICE)
- output("some profits", someProfits.STATE `owned by` MEGA_CORP)
+ output(CASH_PROGRAM_ID, "alice's $900", 900.DOLLARS.CASH `issued by` issuer `owned by` ALICE)
+ output(CASH_PROGRAM_ID, "some profits", someProfits.STATE `owned by` MEGA_CORP)
}
// Some CP is issued onto the ledger by MegaCorp.
transaction("Issuance") {
- output("paper") { thisTest.getPaper() }
+ output(thisTest.getContract(), "paper") { thisTest.getPaper() }
command(MEGA_CORP_PUBKEY) { thisTest.getIssueCommand(DUMMY_NOTARY) }
timeWindow(TEST_TX_TIME)
this.verifies()
@@ -106,8 +110,8 @@ class CommercialPaperTestsGeneric {
transaction("Trade") {
input("paper")
input("alice's $900")
- output("borrowed $900") { 900.DOLLARS.CASH `issued by` issuer `owned by` MEGA_CORP }
- output("alice's paper") { "paper".output().withOwner(ALICE) }
+ output(CASH_PROGRAM_ID, "borrowed $900") { 900.DOLLARS.CASH `issued by` issuer `owned by` MEGA_CORP }
+ output(thisTest.getContract(), "alice's paper") { "paper".output().withOwner(ALICE) }
command(ALICE_PUBKEY) { Cash.Commands.Move() }
command(MEGA_CORP_PUBKEY) { thisTest.getMoveCommand() }
this.verifies()
@@ -120,8 +124,8 @@ class CommercialPaperTestsGeneric {
input("some profits")
fun TransactionDSL.outputs(aliceGetsBack: Amount>) {
- output("Alice's profit") { aliceGetsBack.STATE `owned by` ALICE }
- output("Change") { (someProfits - aliceGetsBack).STATE `owned by` MEGA_CORP }
+ output(CASH_PROGRAM_ID, "Alice's profit") { aliceGetsBack.STATE `owned by` ALICE }
+ output(CASH_PROGRAM_ID, "Change") { (someProfits - aliceGetsBack).STATE `owned by` MEGA_CORP }
}
command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() }
@@ -142,7 +146,7 @@ class CommercialPaperTestsGeneric {
timeWindow(TEST_TX_TIME + 8.days)
tweak {
- output { "paper".output() }
+ output(thisTest.getContract()) { "paper".output() }
this `fails with` "must be destroyed"
}
@@ -154,7 +158,7 @@ class CommercialPaperTestsGeneric {
@Test
fun `key mismatch at issue`() {
transaction {
- output { thisTest.getPaper() }
+ output(thisTest.getContract()) { thisTest.getPaper() }
command(MINI_CORP_PUBKEY) { thisTest.getIssueCommand(DUMMY_NOTARY) }
timeWindow(TEST_TX_TIME)
this `fails with` "output states are issued by a command signer"
@@ -164,7 +168,7 @@ class CommercialPaperTestsGeneric {
@Test
fun `face value is not zero`() {
transaction {
- output { 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) }
timeWindow(TEST_TX_TIME)
this `fails with` "output values sum to more than the inputs"
@@ -174,7 +178,7 @@ class CommercialPaperTestsGeneric {
@Test
fun `maturity date not in the past`() {
transaction {
- output { 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) }
timeWindow(TEST_TX_TIME)
this `fails with` "maturity date is not in the past"
@@ -184,8 +188,8 @@ class CommercialPaperTestsGeneric {
@Test
fun `issue cannot replace an existing state`() {
transaction {
- input(thisTest.getPaper())
- output { thisTest.getPaper() }
+ input(thisTest.getContract(), thisTest.getPaper())
+ output(thisTest.getContract()) { thisTest.getPaper() }
command(MEGA_CORP_PUBKEY) { thisTest.getIssueCommand(DUMMY_NOTARY) }
timeWindow(TEST_TX_TIME)
this `fails with` "output values sum to more than the inputs"
diff --git a/finance/src/test/kotlin/net/corda/finance/contracts/asset/CashTests.kt b/finance/src/test/kotlin/net/corda/finance/contracts/asset/CashTests.kt
index 4d7843f707..410d8a4823 100644
--- a/finance/src/test/kotlin/net/corda/finance/contracts/asset/CashTests.kt
+++ b/finance/src/test/kotlin/net/corda/finance/contracts/asset/CashTests.kt
@@ -84,33 +84,33 @@ class CashTests : TestDependencyInjectionBase() {
@Test
fun trivial() {
transaction {
- input { inState }
+ input(CASH_PROGRAM_ID) { inState }
tweak {
- output { 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() }
this `fails with` "the amounts balance"
}
tweak {
- output { outState }
+ output(CASH_PROGRAM_ID) { outState }
command(ALICE_PUBKEY) { DummyCommandData }
// Invalid command
this `fails with` "required net.corda.finance.contracts.asset.Cash.Commands.Move command"
}
tweak {
- output { outState }
+ output(CASH_PROGRAM_ID) { outState }
command(BOB_PUBKEY) { Cash.Commands.Move() }
this `fails with` "the owning keys are a subset of the signing keys"
}
tweak {
- output { outState }
- output { outState `issued by` MINI_CORP }
+ output(CASH_PROGRAM_ID) { outState }
+ output(CASH_PROGRAM_ID) { outState `issued by` MINI_CORP }
command(ALICE_PUBKEY) { Cash.Commands.Move() }
this `fails with` "at least one cash input"
}
// Simple reallocation works.
tweak {
- output { outState }
+ output(CASH_PROGRAM_ID) { outState }
command(ALICE_PUBKEY) { Cash.Commands.Move() }
this.verifies()
}
@@ -121,8 +121,8 @@ class CashTests : TestDependencyInjectionBase() {
fun `issue by move`() {
// Check we can't "move" money into existence.
transaction {
- input { DummyState() }
- output { outState }
+ input(CASH_PROGRAM_ID) { DummyState() }
+ output(CASH_PROGRAM_ID) { outState }
command(MINI_CORP_PUBKEY) { Cash.Commands.Move() }
this `fails with` "there is at least one cash input for this group"
@@ -134,12 +134,12 @@ class CashTests : TestDependencyInjectionBase() {
// Check we can issue money only as long as the issuer institution is a command signer, i.e. any recognised
// institution is allowed to issue as much cash as they want.
transaction {
- output { outState }
+ output(CASH_PROGRAM_ID) { outState }
command(ALICE_PUBKEY) { Cash.Commands.Issue() }
this `fails with` "output states are issued by a command signer"
}
transaction {
- output {
+ output(CASH_PROGRAM_ID) {
Cash.State(
amount = 1000.DOLLARS `issued by` MINI_CORP.ref(12, 34),
owner = AnonymousParty(ALICE_PUBKEY)
@@ -182,8 +182,8 @@ class CashTests : TestDependencyInjectionBase() {
fun `extended issue examples`() {
// We can consume $1000 in a transaction and output $2000 as long as it's signed by an issuer.
transaction {
- input { issuerInState }
- output { inState.copy(amount = inState.amount * 2) }
+ input(CASH_PROGRAM_ID) { issuerInState }
+ output(CASH_PROGRAM_ID) { inState.copy(amount = inState.amount * 2) }
// Move fails: not allowed to summon money.
tweak {
@@ -200,24 +200,24 @@ class CashTests : TestDependencyInjectionBase() {
// Can't use an issue command to lower the amount.
transaction {
- input { inState }
- output { inState.copy(amount = inState.amount.splitEvenly(2).first()) }
+ input(CASH_PROGRAM_ID) { inState }
+ output(CASH_PROGRAM_ID) { inState.copy(amount = inState.amount.splitEvenly(2).first()) }
command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() }
this `fails with` "output values sum to more than the inputs"
}
// Can't have an issue command that doesn't actually issue money.
transaction {
- input { inState }
- output { inState }
+ input(CASH_PROGRAM_ID) { inState }
+ output(CASH_PROGRAM_ID) { inState }
command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() }
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)
transaction {
- input { inState }
- output { inState.copy(amount = inState.amount * 2) }
+ input(CASH_PROGRAM_ID) { inState }
+ output(CASH_PROGRAM_ID) { inState.copy(amount = inState.amount * 2) }
command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() }
tweak {
command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() }
@@ -252,24 +252,24 @@ class CashTests : TestDependencyInjectionBase() {
transaction {
command(ALICE_PUBKEY) { Cash.Commands.Move() }
tweak {
- input { inState }
+ input(CASH_PROGRAM_ID) { inState }
val splits4 = inState.amount.splitEvenly(4)
- for (i in 0..3) output { inState.copy(amount = splits4[i]) }
+ for (i in 0..3) output(CASH_PROGRAM_ID) { inState.copy(amount = splits4[i]) }
this.verifies()
}
// Merging 4 inputs into 2 outputs works.
tweak {
val splits2 = inState.amount.splitEvenly(2)
val splits4 = inState.amount.splitEvenly(4)
- for (i in 0..3) input { inState.copy(amount = splits4[i]) }
- for (i in 0..1) output { inState.copy(amount = splits2[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]) }
this.verifies()
}
// Merging 2 inputs into 1 works.
tweak {
val splits2 = inState.amount.splitEvenly(2)
- for (i in 0..1) input { inState.copy(amount = splits2[i]) }
- output { inState }
+ for (i in 0..1) input(CASH_PROGRAM_ID) { inState.copy(amount = splits2[i]) }
+ output(CASH_PROGRAM_ID) { inState }
this.verifies()
}
}
@@ -278,15 +278,15 @@ class CashTests : TestDependencyInjectionBase() {
@Test
fun zeroSizedValues() {
transaction {
- input { inState }
- input { inState.copy(amount = 0.DOLLARS `issued by` defaultIssuer) }
+ input(CASH_PROGRAM_ID) { inState }
+ input(CASH_PROGRAM_ID) { inState.copy(amount = 0.DOLLARS `issued by` defaultIssuer) }
command(ALICE_PUBKEY) { Cash.Commands.Move() }
this `fails with` "zero sized inputs"
}
transaction {
- input { inState }
- output { inState }
- output { inState.copy(amount = 0.DOLLARS `issued by` defaultIssuer) }
+ input(CASH_PROGRAM_ID) { inState }
+ output(CASH_PROGRAM_ID) { inState }
+ output(CASH_PROGRAM_ID) { inState.copy(amount = 0.DOLLARS `issued by` defaultIssuer) }
command(ALICE_PUBKEY) { Cash.Commands.Move() }
this `fails with` "zero sized outputs"
}
@@ -296,52 +296,52 @@ class CashTests : TestDependencyInjectionBase() {
fun trivialMismatches() {
// Can't change issuer.
transaction {
- input { inState }
- output { outState `issued by` MINI_CORP }
+ input(CASH_PROGRAM_ID) { inState }
+ output(CASH_PROGRAM_ID) { outState `issued by` MINI_CORP }
command(ALICE_PUBKEY) { Cash.Commands.Move() }
this `fails with` "the amounts balance"
}
// Can't change deposit reference when splitting.
transaction {
val splits2 = inState.amount.splitEvenly(2)
- input { inState }
- for (i in 0..1) output { outState.copy(amount = splits2[i]).editDepositRef(i.toByte()) }
+ input(CASH_PROGRAM_ID) { inState }
+ for (i in 0..1) output(CASH_PROGRAM_ID) { outState.copy(amount = splits2[i]).editDepositRef(i.toByte()) }
command(ALICE_PUBKEY) { Cash.Commands.Move() }
this `fails with` "the amounts balance"
}
// Can't mix currencies.
transaction {
- input { inState }
- output { outState.copy(amount = 800.DOLLARS `issued by` defaultIssuer) }
- output { outState.copy(amount = 200.POUNDS `issued by` defaultIssuer) }
+ input(CASH_PROGRAM_ID) { inState }
+ output(CASH_PROGRAM_ID) { outState.copy(amount = 800.DOLLARS `issued by` defaultIssuer) }
+ output(CASH_PROGRAM_ID) { outState.copy(amount = 200.POUNDS `issued by` defaultIssuer) }
command(ALICE_PUBKEY) { Cash.Commands.Move() }
this `fails with` "the amounts balance"
}
transaction {
- input { inState }
- input {
+ input(CASH_PROGRAM_ID) { inState }
+ input(CASH_PROGRAM_ID) {
inState.copy(
amount = 150.POUNDS `issued by` defaultIssuer,
owner = AnonymousParty(BOB_PUBKEY)
)
}
- output { outState.copy(amount = 1150.DOLLARS `issued by` defaultIssuer) }
+ output(CASH_PROGRAM_ID) { outState.copy(amount = 1150.DOLLARS `issued by` defaultIssuer) }
command(ALICE_PUBKEY) { Cash.Commands.Move() }
this `fails with` "the amounts balance"
}
// Can't have superfluous input states from different issuers.
transaction {
- input { inState }
- input { inState `issued by` MINI_CORP }
- output { outState }
+ input(CASH_PROGRAM_ID) { inState }
+ input(CASH_PROGRAM_ID) { inState `issued by` MINI_CORP }
+ output(CASH_PROGRAM_ID) { outState }
command(ALICE_PUBKEY) { Cash.Commands.Move() }
this `fails with` "the amounts balance"
}
// Can't combine two different deposits at the same issuer.
transaction {
- input { inState }
- input { inState.editDepositRef(3) }
- output { outState.copy(amount = inState.amount * 2).editDepositRef(3) }
+ input(CASH_PROGRAM_ID) { inState }
+ input(CASH_PROGRAM_ID) { inState.editDepositRef(3) }
+ output(CASH_PROGRAM_ID) { outState.copy(amount = inState.amount * 2).editDepositRef(3) }
command(ALICE_PUBKEY) { Cash.Commands.Move() }
this `fails with` "for reference [01]"
}
@@ -351,8 +351,8 @@ class CashTests : TestDependencyInjectionBase() {
fun exitLedger() {
// Single input/output straightforward case.
transaction {
- input { issuerInState }
- output { issuerInState.copy(amount = issuerInState.amount - (200.DOLLARS `issued by` defaultIssuer)) }
+ input(CASH_PROGRAM_ID) { issuerInState }
+ output(CASH_PROGRAM_ID) { issuerInState.copy(amount = issuerInState.amount - (200.DOLLARS `issued by` defaultIssuer)) }
tweak {
command(MEGA_CORP_PUBKEY) { Cash.Commands.Exit(100.DOLLARS `issued by` defaultIssuer) }
@@ -376,11 +376,11 @@ class CashTests : TestDependencyInjectionBase() {
fun `exit ledger with multiple issuers`() {
// Multi-issuer case.
transaction {
- input { issuerInState }
- input { issuerInState.copy(owner = MINI_CORP) `issued by` MINI_CORP }
+ input(CASH_PROGRAM_ID) { issuerInState }
+ input(CASH_PROGRAM_ID) { issuerInState.copy(owner = MINI_CORP) `issued by` MINI_CORP }
- output { issuerInState.copy(amount = issuerInState.amount - (200.DOLLARS `issued by` defaultIssuer)) `issued by` MINI_CORP }
- output { issuerInState.copy(owner = MINI_CORP, amount = issuerInState.amount - (200.DOLLARS `issued by` defaultIssuer)) }
+ output(CASH_PROGRAM_ID) { issuerInState.copy(amount = issuerInState.amount - (200.DOLLARS `issued by` defaultIssuer)) `issued by` MINI_CORP }
+ output(CASH_PROGRAM_ID) { issuerInState.copy(owner = MINI_CORP, amount = issuerInState.amount - (200.DOLLARS `issued by` defaultIssuer)) }
command(MEGA_CORP_PUBKEY, MINI_CORP_PUBKEY) { Cash.Commands.Move() }
@@ -398,8 +398,8 @@ class CashTests : TestDependencyInjectionBase() {
fun `exit cash not held by its issuer`() {
// Single input/output straightforward case.
transaction {
- input { inState }
- output { outState.copy(amount = inState.amount - (200.DOLLARS `issued by` defaultIssuer)) }
+ input(CASH_PROGRAM_ID) { inState }
+ 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(ALICE_PUBKEY) { Cash.Commands.Move() }
this `fails with` "the amounts balance"
@@ -410,25 +410,25 @@ class CashTests : TestDependencyInjectionBase() {
fun multiIssuer() {
transaction {
// Gather 2000 dollars from two different issuers.
- input { inState }
- input { inState `issued by` MINI_CORP }
+ input(CASH_PROGRAM_ID) { inState }
+ input(CASH_PROGRAM_ID) { inState `issued by` MINI_CORP }
command(ALICE_PUBKEY) { Cash.Commands.Move() }
// Can't merge them together.
tweak {
- output { 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"
}
// Missing MiniCorp deposit
tweak {
- output { inState.copy(owner = AnonymousParty(BOB_PUBKEY)) }
- output { 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 works.
- output { inState.copy(owner = AnonymousParty(BOB_PUBKEY)) }
- output { inState.copy(owner = AnonymousParty(BOB_PUBKEY)) `issued by` MINI_CORP }
+ output(CASH_PROGRAM_ID) { inState.copy(owner = AnonymousParty(BOB_PUBKEY)) }
+ output(CASH_PROGRAM_ID) { inState.copy(owner = AnonymousParty(BOB_PUBKEY)) `issued by` MINI_CORP }
this.verifies()
}
}
@@ -438,10 +438,10 @@ class CashTests : TestDependencyInjectionBase() {
// Check we can do an atomic currency trade tx.
transaction {
val pounds = Cash.State(658.POUNDS `issued by` MINI_CORP.ref(3, 4, 5), AnonymousParty(BOB_PUBKEY))
- input { inState `owned by` AnonymousParty(ALICE_PUBKEY) }
- input { pounds }
- output { inState `owned by` AnonymousParty(BOB_PUBKEY) }
- output { pounds `owned by` AnonymousParty(ALICE_PUBKEY) }
+ input(CASH_PROGRAM_ID) { inState `owned by` AnonymousParty(ALICE_PUBKEY) }
+ input(CASH_PROGRAM_ID) { pounds }
+ output(CASH_PROGRAM_ID) { inState `owned by` AnonymousParty(BOB_PUBKEY) }
+ output(CASH_PROGRAM_ID) { pounds `owned by` AnonymousParty(ALICE_PUBKEY) }
command(ALICE_PUBKEY, BOB_PUBKEY) { Cash.Commands.Move() }
this.verifies()
@@ -460,7 +460,7 @@ class CashTests : TestDependencyInjectionBase() {
fun makeCash(amount: Amount, corp: Party, depositRef: Byte = 1) =
StateAndRef(
- Cash.State(amount `issued by` corp.ref(depositRef), OUR_IDENTITY_1) `with notary` DUMMY_NOTARY,
+ TransactionState(Cash.State(amount `issued by` corp.ref(depositRef), OUR_IDENTITY_1), CASH_PROGRAM_ID, DUMMY_NOTARY),
StateRef(SecureHash.randomSHA256(), Random().nextInt(32))
)
@@ -753,7 +753,7 @@ class CashTests : TestDependencyInjectionBase() {
fun chainCashDoubleSpendFailsWith() {
ledger {
unverifiedTransaction {
- output("MEGA_CORP cash") {
+ output(CASH_PROGRAM_ID, "MEGA_CORP cash") {
Cash.State(
amount = 1000.DOLLARS `issued by` MEGA_CORP.ref(1, 1),
owner = MEGA_CORP
@@ -763,7 +763,7 @@ class CashTests : TestDependencyInjectionBase() {
transaction {
input("MEGA_CORP cash")
- output("MEGA_CORP cash".output().copy(owner = AnonymousParty(ALICE_PUBKEY)))
+ output(CASH_PROGRAM_ID, "MEGA_CORP cash".output().copy(owner = AnonymousParty(ALICE_PUBKEY)))
command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() }
this.verifies()
}
@@ -772,7 +772,7 @@ class CashTests : TestDependencyInjectionBase() {
transaction {
input("MEGA_CORP cash")
// We send it to another pubkey so that the transaction is not identical to the previous one
- output("MEGA_CORP cash".output().copy(owner = ALICE))
+ output(CASH_PROGRAM_ID, "MEGA_CORP cash".output().copy(owner = ALICE))
command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() }
this.verifies()
}
diff --git a/finance/src/test/kotlin/net/corda/finance/contracts/asset/DummyFungibleContract.kt b/finance/src/test/kotlin/net/corda/finance/contracts/asset/DummyFungibleContract.kt
index be5ff9a189..da55397e23 100644
--- a/finance/src/test/kotlin/net/corda/finance/contracts/asset/DummyFungibleContract.kt
+++ b/finance/src/test/kotlin/net/corda/finance/contracts/asset/DummyFungibleContract.kt
@@ -30,7 +30,6 @@ class DummyFungibleContract : OnLedgerAsset>, newOwner: AbstractParty): FungibleAsset
diff --git a/finance/src/test/kotlin/net/corda/finance/contracts/asset/ObligationTests.kt b/finance/src/test/kotlin/net/corda/finance/contracts/asset/ObligationTests.kt
index 7bd7fbe4e6..85a4b64a7a 100644
--- a/finance/src/test/kotlin/net/corda/finance/contracts/asset/ObligationTests.kt
+++ b/finance/src/test/kotlin/net/corda/finance/contracts/asset/ObligationTests.kt
@@ -16,6 +16,7 @@ import net.corda.finance.contracts.Commodity
import net.corda.finance.contracts.NetType
import net.corda.finance.contracts.asset.Obligation.Lifecycle
import net.corda.testing.*
+import net.corda.testing.contracts.DUMMY_PROGRAM_ID
import net.corda.testing.contracts.DummyState
import net.corda.testing.node.MockServices
import org.junit.After
@@ -54,10 +55,10 @@ class ObligationTests {
group: LedgerDSL
) = group.apply {
unverifiedTransaction {
- output("Alice's $1,000,000 obligation to Bob", oneMillionDollars.OBLIGATION between Pair(ALICE, BOB))
- output("Bob's $1,000,000 obligation to Alice", oneMillionDollars.OBLIGATION between Pair(BOB, ALICE))
- output("MegaCorp's $1,000,000 obligation to Bob", oneMillionDollars.OBLIGATION between Pair(MEGA_CORP, BOB))
- output("Alice's $1,000,000", 1000000.DOLLARS.CASH `issued by` defaultIssuer `owned by` ALICE)
+ output(OBLIGATION_PROGRAM_ID, "Alice's $1,000,000 obligation to Bob", oneMillionDollars.OBLIGATION between Pair(ALICE, BOB))
+ output(OBLIGATION_PROGRAM_ID, "Bob's $1,000,000 obligation to Alice", oneMillionDollars.OBLIGATION between Pair(BOB, ALICE))
+ output(OBLIGATION_PROGRAM_ID, "MegaCorp's $1,000,000 obligation to Bob", oneMillionDollars.OBLIGATION between Pair(MEGA_CORP, BOB))
+ output(OBLIGATION_PROGRAM_ID, "Alice's $1,000,000", 1000000.DOLLARS.CASH `issued by` defaultIssuer `owned by` ALICE)
}
}
@@ -69,33 +70,33 @@ class ObligationTests {
@Test
fun trivial() {
transaction {
- input { inState }
+ input(OBLIGATION_PROGRAM_ID) { inState }
tweak {
- output { outState.copy(quantity = 2000.DOLLARS.quantity) }
+ output(OBLIGATION_PROGRAM_ID) { outState.copy(quantity = 2000.DOLLARS.quantity) }
command(CHARLIE.owningKey) { Obligation.Commands.Move() }
this `fails with` "the amounts balance"
}
tweak {
- output { outState }
+ output(OBLIGATION_PROGRAM_ID) { outState }
command(CHARLIE.owningKey) { DummyCommandData }
// Invalid command
this `fails with` "required net.corda.finance.contracts.asset.Obligation.Commands.Move command"
}
tweak {
- output { outState }
+ output(OBLIGATION_PROGRAM_ID) { outState }
command(BOB_PUBKEY) { Obligation.Commands.Move() }
this `fails with` "the owning keys are a subset of the signing keys"
}
tweak {
- output { outState }
- output { outState `issued by` MINI_CORP }
+ output(OBLIGATION_PROGRAM_ID) { outState }
+ output(OBLIGATION_PROGRAM_ID) { outState `issued by` MINI_CORP }
command(CHARLIE.owningKey) { Obligation.Commands.Move() }
this `fails with` "at least one obligation input"
}
// Simple reallocation works.
tweak {
- output { outState }
+ output(OBLIGATION_PROGRAM_ID) { outState }
command(CHARLIE.owningKey) { Obligation.Commands.Move() }
this.verifies()
}
@@ -106,8 +107,8 @@ class ObligationTests {
fun `issue debt`() {
// Check we can't "move" debt into existence.
transaction {
- input { DummyState() }
- output { outState }
+ input(DUMMY_PROGRAM_ID) { DummyState() }
+ output(OBLIGATION_PROGRAM_ID) { outState }
command(MINI_CORP_PUBKEY) { Obligation.Commands.Move() }
this `fails with` "at least one obligation input"
@@ -116,12 +117,12 @@ class ObligationTests {
// Check we can issue money only as long as the issuer institution is a command signer, i.e. any recognised
// institution is allowed to issue as much cash as they want.
transaction {
- output { outState }
+ output(OBLIGATION_PROGRAM_ID) { outState }
command(CHARLIE.owningKey) { Obligation.Commands.Issue() }
this `fails with` "output states are issued by a command signer"
}
transaction {
- output {
+ output(OBLIGATION_PROGRAM_ID) {
Obligation.State(
obligor = MINI_CORP,
quantity = 1000.DOLLARS.quantity,
@@ -153,8 +154,8 @@ class ObligationTests {
// We can consume $1000 in a transaction and output $2000 as long as it's signed by an issuer.
transaction {
- input { inState }
- output { inState.copy(quantity = inState.amount.quantity * 2) }
+ input(OBLIGATION_PROGRAM_ID) { inState }
+ output(OBLIGATION_PROGRAM_ID) { inState.copy(quantity = inState.amount.quantity * 2) }
// Move fails: not allowed to summon money.
tweak {
@@ -171,24 +172,24 @@ class ObligationTests {
// Can't use an issue command to lower the amount.
transaction {
- input { inState }
- output { inState.copy(quantity = inState.amount.quantity / 2) }
+ input(OBLIGATION_PROGRAM_ID) { inState }
+ output(OBLIGATION_PROGRAM_ID) { inState.copy(quantity = inState.amount.quantity / 2) }
command(MEGA_CORP_PUBKEY) { Obligation.Commands.Issue() }
this `fails with` "output values sum to more than the inputs"
}
// Can't have an issue command that doesn't actually issue money.
transaction {
- input { inState }
- output { inState }
+ input(OBLIGATION_PROGRAM_ID) { inState }
+ output(OBLIGATION_PROGRAM_ID) { inState }
command(MEGA_CORP_PUBKEY) { Obligation.Commands.Issue() }
this `fails with` ""
}
// Can't have any other commands if we have an issue command (because the issue command overrules them).
transaction {
- input { inState }
- output { inState.copy(quantity = inState.amount.quantity * 2) }
+ input(OBLIGATION_PROGRAM_ID) { inState }
+ output(OBLIGATION_PROGRAM_ID) { inState.copy(quantity = inState.amount.quantity * 2) }
command(MEGA_CORP_PUBKEY) { Obligation.Commands.Issue() }
tweak {
command(MEGA_CORP_PUBKEY) { Obligation.Commands.Issue() }
@@ -223,8 +224,8 @@ class ObligationTests {
@Test
fun `generate close-out net transaction`() {
initialiseTestSerialization()
- val obligationAliceToBob = getStateAndRef(oneMillionDollars.OBLIGATION between Pair(ALICE, BOB))
- val obligationBobToAlice = getStateAndRef(oneMillionDollars.OBLIGATION between Pair(BOB, ALICE))
+ val obligationAliceToBob = getStateAndRef(oneMillionDollars.OBLIGATION between Pair(ALICE, BOB), OBLIGATION_PROGRAM_ID)
+ val obligationBobToAlice = getStateAndRef(oneMillionDollars.OBLIGATION between Pair(BOB, ALICE), OBLIGATION_PROGRAM_ID)
val tx = TransactionBuilder(DUMMY_NOTARY).apply {
Obligation().generateCloseOutNetting(this, ALICE, obligationAliceToBob, obligationBobToAlice)
}.toWireTransaction()
@@ -235,8 +236,8 @@ class ObligationTests {
@Test
fun `generate close-out net transaction with remainder`() {
initialiseTestSerialization()
- val obligationAliceToBob = getStateAndRef((2000000.DOLLARS `issued by` defaultIssuer).OBLIGATION between Pair(ALICE, BOB))
- val obligationBobToAlice = getStateAndRef(oneMillionDollars.OBLIGATION between Pair(BOB, ALICE))
+ val obligationAliceToBob = getStateAndRef((2000000.DOLLARS `issued by` defaultIssuer).OBLIGATION between Pair(ALICE, BOB), OBLIGATION_PROGRAM_ID)
+ val obligationBobToAlice = getStateAndRef(oneMillionDollars.OBLIGATION between Pair(BOB, ALICE), OBLIGATION_PROGRAM_ID)
val tx = TransactionBuilder(DUMMY_NOTARY).apply {
Obligation().generateCloseOutNetting(this, ALICE, obligationAliceToBob, obligationBobToAlice)
}.toWireTransaction()
@@ -250,8 +251,8 @@ class ObligationTests {
@Test
fun `generate payment net transaction`() {
initialiseTestSerialization()
- val obligationAliceToBob = getStateAndRef(oneMillionDollars.OBLIGATION between Pair(ALICE, BOB))
- val obligationBobToAlice = getStateAndRef(oneMillionDollars.OBLIGATION between Pair(BOB, ALICE))
+ val obligationAliceToBob = getStateAndRef(oneMillionDollars.OBLIGATION between Pair(ALICE, BOB), OBLIGATION_PROGRAM_ID)
+ val obligationBobToAlice = getStateAndRef(oneMillionDollars.OBLIGATION between Pair(BOB, ALICE), OBLIGATION_PROGRAM_ID)
val tx = TransactionBuilder(DUMMY_NOTARY).apply {
Obligation().generatePaymentNetting(this, obligationAliceToBob.state.data.amount.token, DUMMY_NOTARY, obligationAliceToBob, obligationBobToAlice)
}.toWireTransaction()
@@ -262,9 +263,9 @@ class ObligationTests {
@Test
fun `generate payment net transaction with remainder`() {
initialiseTestSerialization()
- val obligationAliceToBob = getStateAndRef(oneMillionDollars.OBLIGATION between Pair(ALICE, BOB))
+ val obligationAliceToBob = getStateAndRef(oneMillionDollars.OBLIGATION between Pair(ALICE, BOB), OBLIGATION_PROGRAM_ID)
val obligationAliceToBobState = obligationAliceToBob.state.data
- val obligationBobToAlice = getStateAndRef((2000000.DOLLARS `issued by` defaultIssuer).OBLIGATION between Pair(BOB, ALICE))
+ val obligationBobToAlice = getStateAndRef((2000000.DOLLARS `issued by` defaultIssuer).OBLIGATION between Pair(BOB, ALICE), OBLIGATION_PROGRAM_ID)
val obligationBobToAliceState = obligationBobToAlice.state.data
val tx = TransactionBuilder(DUMMY_NOTARY).apply {
Obligation().generatePaymentNetting(this, obligationAliceToBobState.amount.token, DUMMY_NOTARY, obligationAliceToBob, obligationBobToAlice)
@@ -275,8 +276,8 @@ class ObligationTests {
assertEquals(expected, actual)
}
- private inline fun getStateAndRef(state: T): StateAndRef {
- val txState = TransactionState(state, DUMMY_NOTARY)
+ private inline fun getStateAndRef(state: T, contractClassName: ContractClassName): StateAndRef {
+ val txState = TransactionState(state, contractClassName, DUMMY_NOTARY)
return StateAndRef(txState, StateRef(SecureHash.randomSHA256(), 0))
}
@@ -366,7 +367,7 @@ class ObligationTests {
input("Alice's $1,000,000 obligation to Bob")
input("Bob's $1,000,000 obligation to Alice")
input("MegaCorp's $1,000,000 obligation to Bob")
- output("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) }
timeWindow(TEST_TX_TIME)
this.verifies()
@@ -380,7 +381,7 @@ class ObligationTests {
transaction("Issuance") {
input("Alice's $1,000,000 obligation to Bob")
input("Bob's $1,000,000 obligation to Alice")
- output("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) }
timeWindow(TEST_TX_TIME)
this `fails with` "amounts owed on input and output must match"
@@ -434,7 +435,7 @@ class ObligationTests {
transaction("Issuance") {
input("Bob's $1,000,000 obligation to Alice")
input("MegaCorp's $1,000,000 obligation to Bob")
- output("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) }
timeWindow(TEST_TX_TIME)
this.verifies()
@@ -464,7 +465,7 @@ class ObligationTests {
transaction("Settlement") {
input("Alice's $1,000,000 obligation to Bob")
input("Alice's $1,000,000")
- output("Bob's $1,000,000") { 1000000.DOLLARS.CASH `issued by` defaultIssuer `owned by` BOB }
+ output(OBLIGATION_PROGRAM_ID, "Bob's $1,000,000") { 1000000.DOLLARS.CASH `issued by` defaultIssuer `owned by` BOB }
command(ALICE_PUBKEY) { Obligation.Commands.Settle(Amount(oneMillionDollars.quantity, inState.amount.token)) }
command(ALICE_PUBKEY) { Cash.Commands.Move(Obligation::class.java) }
attachment(attachment(cashContractBytes.inputStream()))
@@ -476,10 +477,10 @@ class ObligationTests {
val halfAMillionDollars = 500000.DOLLARS `issued by` defaultIssuer
ledger {
transaction("Settlement") {
- input(oneMillionDollars.OBLIGATION between Pair(ALICE, BOB))
- input(500000.DOLLARS.CASH `issued by` defaultIssuer `owned by` ALICE)
- output("Alice's $500,000 obligation to Bob") { halfAMillionDollars.OBLIGATION between Pair(ALICE, BOB) }
- output("Bob's $500,000") { 500000.DOLLARS.CASH `issued by` defaultIssuer `owned by` BOB }
+ input(OBLIGATION_PROGRAM_ID, oneMillionDollars.OBLIGATION between Pair(ALICE, BOB))
+ input(CASH_PROGRAM_ID, 500000.DOLLARS.CASH `issued by` defaultIssuer `owned by` ALICE)
+ 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 `issued by` defaultIssuer `owned by` BOB }
command(ALICE_PUBKEY) { Obligation.Commands.Settle(Amount(oneMillionDollars.quantity / 2, inState.amount.token)) }
command(ALICE_PUBKEY) { Cash.Commands.Move(Obligation::class.java) }
attachment(attachment(cashContractBytes.inputStream()))
@@ -491,9 +492,9 @@ class ObligationTests {
val defaultedObligation: Obligation.State = (oneMillionDollars.OBLIGATION between Pair(ALICE, BOB)).copy(lifecycle = Lifecycle.DEFAULTED)
ledger {
transaction("Settlement") {
- input(defaultedObligation) // Alice's defaulted $1,000,000 obligation to Bob
- input(1000000.DOLLARS.CASH `issued by` defaultIssuer `owned by` ALICE)
- output("Bob's $1,000,000") { 1000000.DOLLARS.CASH `issued by` defaultIssuer `owned by` BOB }
+ input(OBLIGATION_PROGRAM_ID, defaultedObligation) // Alice's defaulted $1,000,000 obligation to Bob
+ input(CASH_PROGRAM_ID, 1000000.DOLLARS.CASH `issued by` defaultIssuer `owned by` ALICE)
+ output(OBLIGATION_PROGRAM_ID, "Bob's $1,000,000") { 1000000.DOLLARS.CASH `issued by` defaultIssuer `owned by` BOB }
command(ALICE_PUBKEY) { Obligation.Commands.Settle(Amount(oneMillionDollars.quantity, inState.amount.token)) }
command(ALICE_PUBKEY) { Cash.Commands.Move(Obligation::class.java) }
this `fails with` "all inputs are in the normal state"
@@ -506,7 +507,7 @@ class ObligationTests {
transaction("Settlement") {
input("Alice's $1,000,000 obligation to Bob")
input("Alice's $1,000,000")
- output("Bob's $1,000,000") { 1000000.DOLLARS.CASH `issued by` defaultIssuer `owned by` BOB }
+ output(OBLIGATION_PROGRAM_ID, "Bob's $1,000,000") { 1000000.DOLLARS.CASH `issued by` defaultIssuer `owned by` BOB }
command(ALICE_PUBKEY) { Obligation.Commands.Settle(Amount(oneMillionDollars.quantity / 2, inState.amount.token)) }
command(ALICE_PUBKEY) { Cash.Commands.Move(Obligation::class.java) }
attachment(attachment(cashContractBytes.inputStream()))
@@ -526,13 +527,13 @@ class ObligationTests {
// Try settling a simple commodity obligation
ledger {
unverifiedTransaction {
- output("Alice's 1 FCOJ obligation to Bob", oneUnitFcojObligation between Pair(ALICE, BOB))
- output("Alice's 1 FCOJ", CommodityContract.State(oneUnitFcoj, ALICE))
+ output(OBLIGATION_PROGRAM_ID, "Alice's 1 FCOJ obligation to Bob", oneUnitFcojObligation between Pair(ALICE, BOB))
+ output(OBLIGATION_PROGRAM_ID, "Alice's 1 FCOJ", CommodityContract.State(oneUnitFcoj, ALICE))
}
transaction("Settlement") {
input("Alice's 1 FCOJ obligation to Bob")
input("Alice's 1 FCOJ")
- output("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) { CommodityContract.Commands.Move(Obligation::class.java) }
attachment(attachment(commodityContractBytes.inputStream()))
@@ -548,7 +549,7 @@ class ObligationTests {
cashObligationTestRoots(this)
transaction("Settlement") {
input("Alice's $1,000,000 obligation to Bob")
- output("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) }
this `fails with` "there is a time-window from the authority"
}
@@ -558,8 +559,8 @@ class ObligationTests {
val pastTestTime = TEST_TX_TIME - 7.days
val futureTestTime = TEST_TX_TIME + 7.days
transaction("Settlement") {
- input(oneMillionDollars.OBLIGATION between Pair(ALICE, BOB) `at` futureTestTime)
- output("Alice's defaulted $1,000,000 obligation to Bob") { (oneMillionDollars.OBLIGATION between Pair(ALICE, BOB) `at` futureTestTime).copy(lifecycle = Lifecycle.DEFAULTED) }
+ 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) }
command(BOB_PUBKEY) { Obligation.Commands.SetLifecycle(Lifecycle.DEFAULTED) }
timeWindow(TEST_TX_TIME)
this `fails with` "the due date has passed"
@@ -568,8 +569,8 @@ class ObligationTests {
// Try defaulting an obligation that is now in the past
ledger {
transaction("Settlement") {
- input(oneMillionDollars.OBLIGATION between Pair(ALICE, BOB) `at` pastTestTime)
- output("Alice's defaulted $1,000,000 obligation to Bob") { (oneMillionDollars.OBLIGATION between Pair(ALICE, BOB) `at` pastTestTime).copy(lifecycle = Lifecycle.DEFAULTED) }
+ 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) }
command(BOB_PUBKEY) { Obligation.Commands.SetLifecycle(Lifecycle.DEFAULTED) }
timeWindow(TEST_TX_TIME)
this.verifies()
@@ -584,22 +585,22 @@ class ObligationTests {
transaction {
command(CHARLIE.owningKey) { Obligation.Commands.Move() }
tweak {
- input { inState }
- repeat(4) { output { inState.copy(quantity = inState.quantity / 4) } }
+ input(OBLIGATION_PROGRAM_ID) { inState }
+ repeat(4) { output(OBLIGATION_PROGRAM_ID) { inState.copy(quantity = inState.quantity / 4) } }
this.verifies()
}
// Merging 4 inputs into 2 outputs works.
tweak {
- repeat(4) { input { inState.copy(quantity = inState.quantity / 4) } }
- output { inState.copy(quantity = inState.quantity / 2) }
- output { inState.copy(quantity = inState.quantity / 2) }
+ 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) }
this.verifies()
}
// Merging 2 inputs into 1 works.
tweak {
- input { inState.copy(quantity = inState.quantity / 2) }
- input { inState.copy(quantity = inState.quantity / 2) }
- output { inState }
+ 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 }
this.verifies()
}
}
@@ -610,15 +611,15 @@ class ObligationTests {
transaction {
command(CHARLIE.owningKey) { Obligation.Commands.Move() }
tweak {
- input { inState }
- input { inState.copy(quantity = 0L) }
+ input(OBLIGATION_PROGRAM_ID) { inState }
+ input(OBLIGATION_PROGRAM_ID) { inState.copy(quantity = 0L) }
this `fails with` "zero sized inputs"
}
tweak {
- input { inState }
- output { inState }
- output { inState.copy(quantity = 0L) }
+ input(OBLIGATION_PROGRAM_ID) { inState }
+ output(OBLIGATION_PROGRAM_ID) { inState }
+ output(OBLIGATION_PROGRAM_ID) { inState.copy(quantity = 0L) }
this `fails with` "zero sized outputs"
}
@@ -629,37 +630,37 @@ class ObligationTests {
fun trivialMismatches() {
// Can't change issuer.
transaction {
- input { inState }
- output { outState `issued by` MINI_CORP }
+ input(OBLIGATION_PROGRAM_ID) { inState }
+ output(OBLIGATION_PROGRAM_ID) { outState `issued by` MINI_CORP }
command(MINI_CORP_PUBKEY) { Obligation.Commands.Move() }
this `fails with` "the amounts balance"
}
// Can't mix currencies.
transaction {
- input { inState }
- output { outState.copy(quantity = 80000, template = megaCorpDollarSettlement) }
- output { outState.copy(quantity = 20000, template = megaCorpPoundSettlement) }
+ input(OBLIGATION_PROGRAM_ID) { inState }
+ output(OBLIGATION_PROGRAM_ID) { outState.copy(quantity = 80000, template = megaCorpDollarSettlement) }
+ output(OBLIGATION_PROGRAM_ID) { outState.copy(quantity = 20000, template = megaCorpPoundSettlement) }
command(MINI_CORP_PUBKEY) { Obligation.Commands.Move() }
this `fails with` "the amounts balance"
}
transaction {
- input { inState }
- input {
+ input(OBLIGATION_PROGRAM_ID) { inState }
+ input(OBLIGATION_PROGRAM_ID) {
inState.copy(
quantity = 15000,
template = megaCorpPoundSettlement,
beneficiary = AnonymousParty(BOB_PUBKEY)
)
}
- output { outState.copy(quantity = 115000) }
+ output(OBLIGATION_PROGRAM_ID) { outState.copy(quantity = 115000) }
command(MINI_CORP_PUBKEY) { Obligation.Commands.Move() }
this `fails with` "the amounts balance"
}
// Can't have superfluous input states from different issuers.
transaction {
- input { inState }
- input { inState `issued by` MINI_CORP }
- output { outState }
+ input(OBLIGATION_PROGRAM_ID) { inState }
+ input(OBLIGATION_PROGRAM_ID) { inState `issued by` MINI_CORP }
+ output(OBLIGATION_PROGRAM_ID) { outState }
command(CHARLIE.owningKey) { Obligation.Commands.Move() }
this `fails with` "the amounts balance"
}
@@ -669,8 +670,8 @@ class ObligationTests {
fun `exit single product obligation`() {
// Single input/output straightforward case.
transaction {
- input { inState }
- output { outState.copy(quantity = inState.quantity - 200.DOLLARS.quantity) }
+ input(OBLIGATION_PROGRAM_ID) { inState }
+ output(OBLIGATION_PROGRAM_ID) { outState.copy(quantity = inState.quantity - 200.DOLLARS.quantity) }
tweak {
command(CHARLIE.owningKey) { Obligation.Commands.Exit(Amount(100.DOLLARS.quantity, inState.amount.token)) }
@@ -695,11 +696,11 @@ class ObligationTests {
fun `exit multiple product obligations`() {
// Multi-product case.
transaction {
- input { inState.copy(template = inState.template.copy(acceptableIssuedProducts = megaIssuedPounds)) }
- input { inState.copy(template = inState.template.copy(acceptableIssuedProducts = megaIssuedDollars)) }
+ input(OBLIGATION_PROGRAM_ID) { inState.copy(template = inState.template.copy(acceptableIssuedProducts = megaIssuedPounds)) }
+ input(OBLIGATION_PROGRAM_ID) { inState.copy(template = inState.template.copy(acceptableIssuedProducts = megaIssuedDollars)) }
- output { inState.copy(template = inState.template.copy(acceptableIssuedProducts = megaIssuedPounds), quantity = inState.quantity - 200.POUNDS.quantity) }
- output { 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) }
+ output(OBLIGATION_PROGRAM_ID) { inState.copy(template = inState.template.copy(acceptableIssuedProducts = megaIssuedDollars), quantity = inState.quantity - 200.DOLLARS.quantity) }
command(CHARLIE.owningKey) { Obligation.Commands.Move() }
@@ -717,26 +718,26 @@ class ObligationTests {
fun multiIssuer() {
transaction {
// Gather 2000 dollars from two different issuers.
- input { inState }
- input { inState `issued by` MINI_CORP }
+ input(OBLIGATION_PROGRAM_ID) { inState }
+ input(OBLIGATION_PROGRAM_ID) { inState `issued by` MINI_CORP }
// Can't merge them together.
tweak {
- output { 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() }
this `fails with` "the amounts balance"
}
// Missing MiniCorp deposit
tweak {
- output { inState.copy(beneficiary = AnonymousParty(BOB_PUBKEY)) }
- output { 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() }
this `fails with` "the amounts balance"
}
// This works.
- output { inState.copy(beneficiary = AnonymousParty(BOB_PUBKEY)) }
- output { inState.copy(beneficiary = AnonymousParty(BOB_PUBKEY)) `issued by` MINI_CORP }
+ output(OBLIGATION_PROGRAM_ID) { inState.copy(beneficiary = AnonymousParty(BOB_PUBKEY)) }
+ output(OBLIGATION_PROGRAM_ID) { inState.copy(beneficiary = AnonymousParty(BOB_PUBKEY)) `issued by` MINI_CORP }
command(CHARLIE.owningKey) { Obligation.Commands.Move() }
this.verifies()
}
@@ -747,10 +748,10 @@ class ObligationTests {
// Check we can do an atomic currency trade tx.
transaction {
val pounds = Obligation.State(Lifecycle.NORMAL, MINI_CORP, megaCorpPoundSettlement, 658.POUNDS.quantity, AnonymousParty(BOB_PUBKEY))
- input { inState `owned by` CHARLIE }
- input { pounds }
- output { inState `owned by` AnonymousParty(BOB_PUBKEY) }
- output { pounds `owned by` CHARLIE }
+ input(OBLIGATION_PROGRAM_ID) { inState `owned by` CHARLIE }
+ input(OBLIGATION_PROGRAM_ID) { pounds }
+ output(OBLIGATION_PROGRAM_ID) { inState `owned by` AnonymousParty(BOB_PUBKEY) }
+ output(OBLIGATION_PROGRAM_ID) { pounds `owned by` CHARLIE }
command(CHARLIE.owningKey, BOB_PUBKEY) { Obligation.Commands.Move() }
this.verifies()
diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/AttachmentClassLoaderTests.kt b/node-api/src/test/kotlin/net/corda/nodeapi/AttachmentClassLoaderTests.kt
index fdd79cfee5..0ae01652a3 100644
--- a/node-api/src/test/kotlin/net/corda/nodeapi/AttachmentClassLoaderTests.kt
+++ b/node-api/src/test/kotlin/net/corda/nodeapi/AttachmentClassLoaderTests.kt
@@ -41,11 +41,11 @@ interface DummyContractBackdoor {
fun inspectState(state: ContractState): Int
}
-val ATTACHMENT_TEST_PROGRAM_ID = AttachmentClassLoaderTests.AttachmentDummyContract()
-
class AttachmentClassLoaderTests : TestDependencyInjectionBase() {
companion object {
val ISOLATED_CONTRACTS_JAR_PATH: URL = AttachmentClassLoaderTests::class.java.getResource("isolated.jar")
+ private val ISOLATED_CONTRACT_CLASS_NAME = "net.corda.finance.contracts.isolated.AnotherDummyContract"
+ private val ATTACHMENT_PROGRAM_ID = "net.corda.nodeapi.AttachmentClassLoaderTests.AttachmentDummyContract"
private fun SerializationContext.withAttachmentStorage(attachmentStorage: AttachmentStorage): SerializationContext {
val serviceHub = mock()
@@ -56,7 +56,6 @@ class AttachmentClassLoaderTests : TestDependencyInjectionBase() {
class AttachmentDummyContract : Contract {
data class State(val magicNumber: Int = 0) : ContractState {
- override val contract = ATTACHMENT_TEST_PROGRAM_ID
override val participants: List
get() = listOf()
}
@@ -71,7 +70,7 @@ class AttachmentClassLoaderTests : TestDependencyInjectionBase() {
fun generateInitial(owner: PartyAndReference, magicNumber: Int, notary: Party): TransactionBuilder {
val state = State(magicNumber)
- return TransactionBuilder(notary).withItems(state, Command(Commands.Create(), owner.party.owningKey))
+ return TransactionBuilder(notary).withItems(StateAndContract(state, ATTACHMENT_PROGRAM_ID), Command(Commands.Create(), owner.party.owningKey))
}
}
@@ -96,10 +95,10 @@ class AttachmentClassLoaderTests : TestDependencyInjectionBase() {
fun `dynamically load AnotherDummyContract from isolated contracts jar`() {
val child = ClassLoaderForTests()
- val contractClass = Class.forName("net.corda.contracts.isolated.AnotherDummyContract", true, child)
+ val contractClass = Class.forName(ISOLATED_CONTRACT_CLASS_NAME, true, child)
val contract = contractClass.newInstance() as Contract
- assertEquals(SecureHash.sha256("https://anotherdummy.org"), contract.declaredField("legalContractReference").value)
+ assertEquals("helloworld", contract.declaredField("magicString").value)
}
fun fakeAttachment(filepath: String, content: String): ByteArray {
@@ -187,10 +186,10 @@ class AttachmentClassLoaderTests : TestDependencyInjectionBase() {
val att2 = storage.importAttachment(ByteArrayInputStream(fakeAttachment("file2.txt", "some other data")))
val cl = AttachmentsClassLoader(arrayOf(att0, att1, att2).map { storage.openAttachment(it)!! }, FilteringClassLoader)
- val contractClass = Class.forName("net.corda.contracts.isolated.AnotherDummyContract", true, cl)
+ val contractClass = Class.forName(ISOLATED_CONTRACT_CLASS_NAME, true, cl)
val contract = contractClass.newInstance() as Contract
assertEquals(cl, contract.javaClass.classLoader)
- assertEquals(SecureHash.sha256("https://anotherdummy.org"), contract.declaredField("legalContractReference").value)
+ assertEquals("helloworld", contract.declaredField("magicString").value)
}
@@ -204,7 +203,7 @@ class AttachmentClassLoaderTests : TestDependencyInjectionBase() {
fun createContract2Cash(): Contract {
val cl = ClassLoaderForTests()
- val contractClass = Class.forName("net.corda.contracts.isolated.AnotherDummyContract", true, cl)
+ val contractClass = Class.forName(ISOLATED_CONTRACT_CLASS_NAME, true, cl)
return contractClass.newInstance() as Contract
}
@@ -250,7 +249,7 @@ class AttachmentClassLoaderTests : TestDependencyInjectionBase() {
val cl = AttachmentsClassLoader(arrayOf(att0, att1, att2).map { storage.openAttachment(it)!! }, FilteringClassLoader)
- val context = SerializationFactory.defaultFactory.defaultContext.withClassLoader(cl).withWhitelisted(Class.forName("net.corda.contracts.isolated.AnotherDummyContract", true, cl))
+ val context = SerializationFactory.defaultFactory.defaultContext.withClassLoader(cl).withWhitelisted(Class.forName(ISOLATED_CONTRACT_CLASS_NAME, true, cl))
val state2 = bytes.deserialize(context = context)
assertEquals(cl, state2.contract.javaClass.classLoader)
@@ -259,7 +258,7 @@ class AttachmentClassLoaderTests : TestDependencyInjectionBase() {
// We should be able to load same class from a different class loader and have them be distinct.
val cl2 = AttachmentsClassLoader(arrayOf(att0, att1, att2).map { storage.openAttachment(it)!! }, FilteringClassLoader)
- val context3 = SerializationFactory.defaultFactory.defaultContext.withClassLoader(cl2).withWhitelisted(Class.forName("net.corda.contracts.isolated.AnotherDummyContract", true, cl2))
+ val context3 = SerializationFactory.defaultFactory.defaultContext.withClassLoader(cl2).withWhitelisted(Class.forName(ISOLATED_CONTRACT_CLASS_NAME, true, cl2))
val state3 = bytes.deserialize(context = context3)
assertEquals(cl2, state3.contract.javaClass.classLoader)
@@ -295,7 +294,7 @@ class AttachmentClassLoaderTests : TestDependencyInjectionBase() {
@Test
fun `test serialization of WireTransaction with statically loaded contract`() {
- val tx = ATTACHMENT_TEST_PROGRAM_ID.generateInitial(MEGA_CORP.ref(0), 42, DUMMY_NOTARY)
+ val tx = AttachmentDummyContract().generateInitial(MEGA_CORP.ref(0), 42, DUMMY_NOTARY)
val wireTransaction = tx.toWireTransaction()
val bytes = wireTransaction.serialize()
val copiedWireTransaction = bytes.deserialize()
@@ -307,13 +306,13 @@ class AttachmentClassLoaderTests : TestDependencyInjectionBase() {
@Test
fun `test serialization of WireTransaction with dynamically loaded contract`() {
val child = ClassLoaderForTests()
- val contractClass = Class.forName("net.corda.contracts.isolated.AnotherDummyContract", true, child)
+ val contractClass = Class.forName(ISOLATED_CONTRACT_CLASS_NAME, true, child)
val contract = contractClass.newInstance() as DummyContractBackdoor
val tx = contract.generateInitial(MEGA_CORP.ref(0), 42, DUMMY_NOTARY)
val storage = MockAttachmentStorage()
val context = SerializationFactory.defaultFactory.defaultContext.withWhitelisted(contract.javaClass)
- .withWhitelisted(Class.forName("net.corda.contracts.isolated.AnotherDummyContract\$State", true, child))
- .withWhitelisted(Class.forName("net.corda.contracts.isolated.AnotherDummyContract\$Commands\$Create", true, child))
+ .withWhitelisted(Class.forName("$ISOLATED_CONTRACT_CLASS_NAME\$State", true, child))
+ .withWhitelisted(Class.forName("$ISOLATED_CONTRACT_CLASS_NAME\$Commands\$Create", true, child))
.withAttachmentStorage(storage)
// todo - think about better way to push attachmentStorage down to serializer
@@ -325,14 +324,17 @@ class AttachmentClassLoaderTests : TestDependencyInjectionBase() {
}
val copiedWireTransaction = bytes.deserialize(context = context)
assertEquals(1, copiedWireTransaction.outputs.size)
- val contract2 = copiedWireTransaction.getOutput(0).contract as DummyContractBackdoor
+ // Contracts need to be loaded by the same classloader as the ContractState itself
+ val contractClassloader = copiedWireTransaction.getOutput(0).javaClass.classLoader
+ val contract2 = contractClassloader.loadClass(copiedWireTransaction.outputs.first().contract).newInstance() as DummyContractBackdoor
+ assertEquals(contract2.javaClass.classLoader, copiedWireTransaction.outputs[0].data.javaClass.classLoader)
assertEquals(42, contract2.inspectState(copiedWireTransaction.outputs[0].data))
}
@Test
fun `test deserialize of WireTransaction where contract cannot be found`() = kryoSpecific("Kryo verifies/loads attachments on deserialization, whereas AMQP currently does not") {
val child = ClassLoaderForTests()
- val contractClass = Class.forName("net.corda.contracts.isolated.AnotherDummyContract", true, child)
+ val contractClass = Class.forName(ISOLATED_CONTRACT_CLASS_NAME, true, child)
val contract = contractClass.newInstance() as DummyContractBackdoor
val tx = contract.generateInitial(MEGA_CORP.ref(0), 42, DUMMY_NOTARY)
val storage = MockAttachmentStorage()
@@ -363,7 +365,7 @@ class AttachmentClassLoaderTests : TestDependencyInjectionBase() {
@Test
fun `test loading a class from attachment during deserialization`() {
val child = ClassLoaderForTests()
- val contractClass = Class.forName("net.corda.contracts.isolated.AnotherDummyContract", true, child)
+ val contractClass = Class.forName(ISOLATED_CONTRACT_CLASS_NAME, true, child)
val contract = contractClass.newInstance() as DummyContractBackdoor
val storage = MockAttachmentStorage()
val attachmentRef = importJar(storage)
@@ -380,7 +382,7 @@ class AttachmentClassLoaderTests : TestDependencyInjectionBase() {
@Test
fun `test loading a class with attachment missing during deserialization`() {
val child = ClassLoaderForTests()
- val contractClass = Class.forName("net.corda.contracts.isolated.AnotherDummyContract", true, child)
+ val contractClass = Class.forName(ISOLATED_CONTRACT_CLASS_NAME, true, child)
val contract = contractClass.newInstance() as DummyContractBackdoor
val storage = MockAttachmentStorage()
val attachmentRef = SecureHash.randomSHA256()
@@ -396,4 +398,4 @@ class AttachmentClassLoaderTests : TestDependencyInjectionBase() {
}
assertEquals(attachmentRef, e.ids.single())
}
-}
\ No newline at end of file
+}
diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/CordaClassResolverTests.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/CordaClassResolverTests.kt
index c3f0ab3aaf..05bc015fad 100644
--- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/CordaClassResolverTests.kt
+++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/CordaClassResolverTests.kt
@@ -163,7 +163,7 @@ class CordaClassResolverTests {
val storage = MockAttachmentStorage()
val attachmentHash = importJar(storage)
val classLoader = AttachmentsClassLoader(arrayOf(attachmentHash).map { storage.openAttachment(it)!! })
- val attachedClass = Class.forName("net.corda.contracts.isolated.AnotherDummyContract", true, classLoader)
+ val attachedClass = Class.forName("net.corda.finance.contracts.isolated.AnotherDummyContract", true, classLoader)
CordaClassResolver(emptyWhitelistContext).getRegistration(attachedClass)
}
diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/SerializationOutputTests.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/SerializationOutputTests.kt
index 2584b160be..5121b3124d 100644
--- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/SerializationOutputTests.kt
+++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/SerializationOutputTests.kt
@@ -531,16 +531,14 @@ class SerializationOutputTests {
}
}
+ val FOO_PROGRAM_ID = "net.corda.nodeapi.internal.serialization.amqp.SerializationOutputTests.FooContract"
class FooState : ContractState {
- override val contract: Contract
- get() = FooContract
- override val participants: List
- get() = emptyList()
+ override val participants: List = emptyList()
}
@Test
fun `test transaction state`() {
- val state = TransactionState(FooState(), MEGA_CORP)
+ val state = TransactionState(FooState(), FOO_PROGRAM_ID, MEGA_CORP)
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
AbstractAMQPSerializationScheme.registerCustomSerializers(factory)
diff --git a/node-api/src/test/resources/net/corda/nodeapi/isolated.jar b/node-api/src/test/resources/net/corda/nodeapi/isolated.jar
index 567a93ed9c..ce003bd76d 100644
Binary files a/node-api/src/test/resources/net/corda/nodeapi/isolated.jar and b/node-api/src/test/resources/net/corda/nodeapi/isolated.jar differ
diff --git a/node/src/integration-test/kotlin/net/corda/node/services/BFTNotaryServiceTests.kt b/node/src/integration-test/kotlin/net/corda/node/services/BFTNotaryServiceTests.kt
index eaa4fcb2a2..211bc84fb2 100644
--- a/node/src/integration-test/kotlin/net/corda/node/services/BFTNotaryServiceTests.kt
+++ b/node/src/integration-test/kotlin/net/corda/node/services/BFTNotaryServiceTests.kt
@@ -23,6 +23,7 @@ import net.corda.node.services.transactions.BFTNonValidatingNotaryService
import net.corda.node.services.transactions.minClusterSize
import net.corda.node.services.transactions.minCorrectReplicas
import net.corda.node.utilities.ServiceIdentityGenerator
+import net.corda.testing.contracts.DUMMY_PROGRAM_ID
import net.corda.testing.contracts.DummyContract
import net.corda.testing.dummyCommand
import net.corda.testing.node.MockNetwork
@@ -72,7 +73,7 @@ class BFTNotaryServiceTests {
val notary = bftNotaryCluster(minClusterSize(1), true) // This true adds a sleep to expose the race.
val f = node.run {
val trivialTx = signInitialTransaction(notary) {
- addOutputState(DummyContract.SingleOwnerState(owner = info.legalIdentity))
+ addOutputState(DummyContract.SingleOwnerState(owner = info.legalIdentity), DUMMY_PROGRAM_ID)
}
// Create a new consensus while the redundant replica is sleeping:
services.startFlow(NotaryFlow.Client(trivialTx)).resultFuture
@@ -96,7 +97,7 @@ class BFTNotaryServiceTests {
val notary = bftNotaryCluster(clusterSize)
node.run {
val issueTx = signInitialTransaction(notary) {
- addOutputState(DummyContract.SingleOwnerState(owner = info.legalIdentity))
+ addOutputState(DummyContract.SingleOwnerState(owner = info.legalIdentity), DUMMY_PROGRAM_ID)
}
database.transaction {
services.recordTransactions(issueTx)
diff --git a/node/src/integration-test/kotlin/net/corda/node/services/RaftNotaryServiceTests.kt b/node/src/integration-test/kotlin/net/corda/node/services/RaftNotaryServiceTests.kt
index f975a1225a..76ba4ae494 100644
--- a/node/src/integration-test/kotlin/net/corda/node/services/RaftNotaryServiceTests.kt
+++ b/node/src/integration-test/kotlin/net/corda/node/services/RaftNotaryServiceTests.kt
@@ -13,6 +13,7 @@ import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.getX500Name
import net.corda.node.internal.AbstractNode
import net.corda.testing.DUMMY_BANK_A
+import net.corda.testing.contracts.DUMMY_PROGRAM_ID
import net.corda.testing.contracts.DummyContract
import net.corda.testing.dummyCommand
import net.corda.testing.node.NodeBasedTest
@@ -45,7 +46,7 @@ class RaftNotaryServiceTests : NodeBasedTest() {
val secondSpendBuilder = TransactionBuilder(notaryParty).withItems(inputState).run {
val dummyState = DummyContract.SingleOwnerState(0, bankA.info.legalIdentity)
- addOutputState(dummyState)
+ addOutputState(dummyState, DUMMY_PROGRAM_ID)
addCommand(dummyCommand(bankA.services.legalIdentityKey))
this
}
diff --git a/node/src/integration-test/kotlin/net/corda/node/services/statemachine/LargeTransactionsTest.kt b/node/src/integration-test/kotlin/net/corda/node/services/statemachine/LargeTransactionsTest.kt
index cf0e136b88..c1d1a0a586 100644
--- a/node/src/integration-test/kotlin/net/corda/node/services/statemachine/LargeTransactionsTest.kt
+++ b/node/src/integration-test/kotlin/net/corda/node/services/statemachine/LargeTransactionsTest.kt
@@ -10,6 +10,7 @@ import net.corda.core.transactions.TransactionBuilder
import net.corda.testing.BOB
import net.corda.testing.DUMMY_NOTARY
import net.corda.testing.aliceBobAndNotary
+import net.corda.testing.contracts.DUMMY_PROGRAM_ID
import net.corda.testing.contracts.DummyState
import net.corda.testing.driver.driver
import net.corda.testing.dummyCommand
@@ -26,7 +27,7 @@ class LargeTransactionsTest {
@Suspendable
override fun call() {
val tx = TransactionBuilder(notary = DUMMY_NOTARY)
- .addOutputState(DummyState())
+ .addOutputState(DummyState(), DUMMY_PROGRAM_ID)
.addCommand(dummyCommand(serviceHub.legalIdentityKey))
.addAttachment(hash1)
.addAttachment(hash2)
diff --git a/node/src/integration-test/kotlin/net/corda/test/node/NodeStatePersistenceTests.kt b/node/src/integration-test/kotlin/net/corda/test/node/NodeStatePersistenceTests.kt
index b6389806de..54d11abf56 100644
--- a/node/src/integration-test/kotlin/net/corda/test/node/NodeStatePersistenceTests.kt
+++ b/node/src/integration-test/kotlin/net/corda/test/node/NodeStatePersistenceTests.kt
@@ -1,13 +1,7 @@
package net.corda.test.node
import co.paralleluniverse.fibers.Suspendable
-import net.corda.core.contracts.Command
-import net.corda.core.contracts.CommandData
-import net.corda.core.contracts.Contract
-import net.corda.core.contracts.LinearState
-import net.corda.core.contracts.UniqueIdentifier
-import net.corda.core.contracts.requireSingleCommand
-import net.corda.core.contracts.requireThat
+import net.corda.core.contracts.*
import net.corda.core.flows.FinalityFlow
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.StartableByRPC
@@ -71,7 +65,6 @@ fun isQuasarAgentSpecified(): Boolean {
data class Message(val value: String)
data class MessageState(val message: Message, val by: Party, override val linearId: UniqueIdentifier = UniqueIdentifier()) : LinearState, QueryableState {
- override val contract = MessageContract()
override val participants: List = listOf(by)
override fun generateMappedObject(schema: MappedSchema): PersistentState {
@@ -104,6 +97,8 @@ object MessageSchemaV1 : MappedSchema(
) : PersistentState()
}
+val MESSAGE_CONTRACT_PROGRAM_ID = "net.corda.test.node.MessageContract"
+
open class MessageContract : Contract {
override fun verify(tx: LedgerTransaction) {
val command = tx.commands.requireSingleCommand()
@@ -146,7 +141,7 @@ class SendMessageFlow(private val message: Message) : FlowLogic, List> {
val ap = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
- output("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)
}
command(issuer.party.owningKey) { CommercialPaper.Commands.Issue() }
diff --git a/node/src/test/kotlin/net/corda/node/services/NotaryChangeTests.kt b/node/src/test/kotlin/net/corda/node/services/NotaryChangeTests.kt
index 696e27ee96..75ec51150a 100644
--- a/node/src/test/kotlin/net/corda/node/services/NotaryChangeTests.kt
+++ b/node/src/test/kotlin/net/corda/node/services/NotaryChangeTests.kt
@@ -15,6 +15,7 @@ import net.corda.node.internal.AbstractNode
import net.corda.node.services.network.NetworkMapService
import net.corda.node.services.transactions.SimpleNotaryService
import net.corda.testing.DUMMY_NOTARY
+import net.corda.testing.contracts.DUMMY_PROGRAM_ID
import net.corda.testing.contracts.DummyContract
import net.corda.testing.dummyCommand
import net.corda.testing.getTestPartyAndCertificate
@@ -142,9 +143,9 @@ class NotaryChangeTests {
val tx = TransactionBuilder(null).apply {
addCommand(Command(DummyContract.Commands.Create(), owner.party.owningKey))
- addOutputState(stateA, notary, encumbrance = 2) // Encumbered by stateB
- addOutputState(stateC, notary)
- addOutputState(stateB, notary, encumbrance = 1) // Encumbered by stateC
+ addOutputState(stateA, DUMMY_PROGRAM_ID, notary, encumbrance = 2) // Encumbered by stateB
+ addOutputState(stateC, DUMMY_PROGRAM_ID, notary)
+ addOutputState(stateB, DUMMY_PROGRAM_ID, notary, encumbrance = 1) // Encumbered by stateC
}
val stx = node.services.signInitialTransaction(tx)
node.services.recordTransactions(stx)
@@ -170,7 +171,7 @@ fun issueState(node: AbstractNode, notaryNode: AbstractNode): StateAndRef<*> {
fun issueMultiPartyState(nodeA: AbstractNode, nodeB: AbstractNode, notaryNode: AbstractNode): StateAndRef {
val state = TransactionState(DummyContract.MultiOwnerState(0,
- listOf(nodeA.info.legalIdentity, nodeB.info.legalIdentity)), notaryNode.info.notaryIdentity)
+ listOf(nodeA.info.legalIdentity, nodeB.info.legalIdentity)), DUMMY_PROGRAM_ID, notaryNode.info.notaryIdentity)
val tx = TransactionBuilder(notary = notaryNode.info.notaryIdentity).withItems(state, dummyCommand())
val signedByA = nodeA.services.signInitialTransaction(tx)
val signedByAB = nodeB.services.addSignature(signedByA)
diff --git a/node/src/test/kotlin/net/corda/node/services/events/NodeSchedulerServiceTest.kt b/node/src/test/kotlin/net/corda/node/services/events/NodeSchedulerServiceTest.kt
index e89aa57f8c..afe591c168 100644
--- a/node/src/test/kotlin/net/corda/node/services/events/NodeSchedulerServiceTest.kt
+++ b/node/src/test/kotlin/net/corda/node/services/events/NodeSchedulerServiceTest.kt
@@ -23,6 +23,7 @@ import net.corda.node.utilities.AffinityExecutor
import net.corda.node.utilities.CordaPersistence
import net.corda.node.utilities.configureDatabase
import net.corda.testing.*
+import net.corda.testing.contracts.DUMMY_PROGRAM_ID
import net.corda.testing.node.InMemoryMessagingNetwork
import net.corda.testing.node.MockKeyManagementService
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
@@ -131,9 +132,6 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
override fun nextScheduledActivity(thisStateRef: StateRef, flowLogicRefFactory: FlowLogicRefFactory): ScheduledActivity? {
return ScheduledActivity(flowLogicRef, instant)
}
-
- override val contract: Contract
- get() = throw UnsupportedOperationException()
}
class TestFlowLogic(val increment: Int = 1) : FlowLogic() {
@@ -282,7 +280,7 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
val freshKey = services.keyManagementService.freshKey()
val state = TestState(FlowLogicRefFactoryImpl.createForRPC(TestFlowLogic::class.java, increment), instant, services.myInfo.legalIdentity)
val builder = TransactionBuilder(null).apply {
- addOutputState(state, DUMMY_NOTARY)
+ addOutputState(state, DUMMY_PROGRAM_ID, DUMMY_NOTARY)
addCommand(Command(), freshKey)
}
val usefulTX = services.signInitialTransaction(builder, freshKey)
diff --git a/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt b/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt
index a567ce1464..8bbe3f5643 100644
--- a/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt
+++ b/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt
@@ -21,6 +21,7 @@ import net.corda.node.services.network.NetworkMapService
import net.corda.node.services.statemachine.StateMachineManager
import net.corda.node.services.transactions.ValidatingNotaryService
import net.corda.testing.DUMMY_NOTARY
+import net.corda.testing.contracts.DUMMY_PROGRAM_ID
import net.corda.testing.contracts.DummyContract
import net.corda.testing.dummyCommand
import net.corda.testing.node.MockNetwork
@@ -46,8 +47,7 @@ class ScheduledFlowTests {
val source: Party,
val destination: Party,
val processed: Boolean = false,
- override val linearId: UniqueIdentifier = UniqueIdentifier(),
- override val contract: Contract = DummyContract()) : SchedulableState, LinearState {
+ override val linearId: UniqueIdentifier = UniqueIdentifier()) : SchedulableState, LinearState {
override fun nextScheduledActivity(thisStateRef: StateRef, flowLogicRefFactory: FlowLogicRefFactory): ScheduledActivity? {
if (!processed) {
val logicRef = flowLogicRefFactory.create(ScheduledFlow::class.java, thisStateRef)
@@ -68,7 +68,7 @@ class ScheduledFlowTests {
val notary = serviceHub.networkMapCache.getAnyNotary()
val builder = TransactionBuilder(notary)
- .addOutputState(scheduledState)
+ .addOutputState(scheduledState, DUMMY_PROGRAM_ID)
.addCommand(dummyCommand(serviceHub.legalIdentityKey))
val tx = serviceHub.signInitialTransaction(builder)
subFlow(FinalityFlow(tx, setOf(serviceHub.myInfo.legalIdentity)))
@@ -90,7 +90,7 @@ class ScheduledFlowTests {
val newStateOutput = scheduledState.copy(processed = true)
val builder = TransactionBuilder(notary)
.addInputState(state)
- .addOutputState(newStateOutput)
+ .addOutputState(newStateOutput, DUMMY_PROGRAM_ID)
.addCommand(dummyCommand(serviceHub.legalIdentityKey))
val tx = serviceHub.signInitialTransaction(builder)
subFlow(FinalityFlow(tx, setOf(scheduledState.source, scheduledState.destination)))
diff --git a/node/src/test/kotlin/net/corda/node/services/schema/HibernateObserverTests.kt b/node/src/test/kotlin/net/corda/node/services/schema/HibernateObserverTests.kt
index bbade152b5..336b7a24e7 100644
--- a/node/src/test/kotlin/net/corda/node/services/schema/HibernateObserverTests.kt
+++ b/node/src/test/kotlin/net/corda/node/services/schema/HibernateObserverTests.kt
@@ -12,6 +12,7 @@ import net.corda.node.services.api.SchemaService
import net.corda.node.utilities.DatabaseTransactionManager
import net.corda.node.utilities.configureDatabase
import net.corda.testing.MEGA_CORP
+import net.corda.testing.contracts.DUMMY_PROGRAM_ID
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
import net.corda.testing.node.MockServices.Companion.makeTestDatabaseProperties
import net.corda.testing.node.MockServices.Companion.makeTestIdentityService
@@ -72,9 +73,6 @@ class HibernateObserverTests {
throw UnsupportedOperationException()
}
- override val contract: Contract
- get() = throw UnsupportedOperationException()
-
override val participants: List
get() = throw UnsupportedOperationException()
}
@@ -101,7 +99,7 @@ class HibernateObserverTests {
@Suppress("UNUSED_VARIABLE")
val observer = HibernateObserver(rawUpdatesPublisher, database.hibernateConfig)
database.transaction {
- rawUpdatesPublisher.onNext(Vault.Update(emptySet(), setOf(StateAndRef(TransactionState(TestState(), MEGA_CORP), StateRef(SecureHash.sha256("dummy"), 0)))))
+ rawUpdatesPublisher.onNext(Vault.Update(emptySet(), setOf(StateAndRef(TransactionState(TestState(), DUMMY_PROGRAM_ID, MEGA_CORP), StateRef(SecureHash.sha256("dummy"), 0)))))
val parentRowCountResult = DatabaseTransactionManager.current().connection.prepareStatement("select count(*) from Parents").executeQuery()
parentRowCountResult.next()
val parentRows = parentRowCountResult.getInt(1)
diff --git a/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt b/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt
index 04aa485186..dda7feed32 100644
--- a/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt
+++ b/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt
@@ -31,6 +31,7 @@ import net.corda.node.services.network.NetworkMapService
import net.corda.node.services.persistence.checkpoints
import net.corda.node.services.transactions.ValidatingNotaryService
import net.corda.testing.*
+import net.corda.testing.contracts.DUMMY_PROGRAM_ID
import net.corda.testing.contracts.DummyState
import net.corda.testing.node.InMemoryMessagingNetwork
import net.corda.testing.node.InMemoryMessagingNetwork.MessageTransfer
@@ -599,7 +600,7 @@ class FlowFrameworkTests {
@Test
fun `wait for transaction`() {
val ptx = TransactionBuilder(notary = notary1.info.notaryIdentity)
- .addOutputState(DummyState())
+ .addOutputState(DummyState(), DUMMY_PROGRAM_ID)
.addCommand(dummyCommand(node1.services.legalIdentityKey))
val stx = node1.services.signInitialTransaction(ptx)
@@ -614,7 +615,7 @@ class FlowFrameworkTests {
@Test
fun `committer throws exception before calling the finality flow`() {
val ptx = TransactionBuilder(notary = notary1.info.notaryIdentity)
- .addOutputState(DummyState())
+ .addOutputState(DummyState(), DUMMY_PROGRAM_ID)
.addCommand(dummyCommand())
val stx = node1.services.signInitialTransaction(ptx)
@@ -631,7 +632,7 @@ class FlowFrameworkTests {
@Test
fun `verify vault query service is tokenizable by force checkpointing within a flow`() {
val ptx = TransactionBuilder(notary = notary1.info.notaryIdentity)
- .addOutputState(DummyState())
+ .addOutputState(DummyState(), DUMMY_PROGRAM_ID)
.addCommand(dummyCommand(node1.services.legalIdentityKey))
val stx = node1.services.signInitialTransaction(ptx)
diff --git a/node/src/test/kotlin/net/corda/node/services/vault/VaultWithCashTest.kt b/node/src/test/kotlin/net/corda/node/services/vault/VaultWithCashTest.kt
index 250b4fab5f..2197a3371a 100644
--- a/node/src/test/kotlin/net/corda/node/services/vault/VaultWithCashTest.kt
+++ b/node/src/test/kotlin/net/corda/node/services/vault/VaultWithCashTest.kt
@@ -231,8 +231,8 @@ class VaultWithCashTest : TestDependencyInjectionBase() {
// Issue a linear state
val dummyIssueBuilder = TransactionBuilder(notary = DUMMY_NOTARY).apply {
- addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)))
- addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)))
+ addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)), DUMMY_LINEAR_CONTRACT_PROGRAM_ID)
+ addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)), DUMMY_LINEAR_CONTRACT_PROGRAM_ID)
addCommand(dummyCommand(notaryServices.legalIdentityKey))
}
val dummyIssue = notaryServices.signInitialTransaction(dummyIssueBuilder)
@@ -252,7 +252,8 @@ class VaultWithCashTest : TestDependencyInjectionBase() {
val dummyIssue =
database.transaction { // Issue a linear state
val dummyIssueBuilder = TransactionBuilder(notary = DUMMY_NOTARY)
- .addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity))).addCommand(dummyCommand(notaryServices.legalIdentityKey))
+ .addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)), DUMMY_LINEAR_CONTRACT_PROGRAM_ID)
+ .addCommand(dummyCommand(notaryServices.legalIdentityKey))
val dummyIssuePtx = notaryServices.signInitialTransaction(dummyIssueBuilder)
val dummyIssue = services.addSignature(dummyIssuePtx)
@@ -266,7 +267,7 @@ class VaultWithCashTest : TestDependencyInjectionBase() {
// Move the same state
val dummyMoveBuilder = TransactionBuilder(notary = DUMMY_NOTARY)
- .addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)))
+ .addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)), DUMMY_LINEAR_CONTRACT_PROGRAM_ID)
.addInputState(dummyIssue.tx.outRef(0))
.addCommand(dummyCommand(notaryServices.legalIdentityKey))
@@ -340,8 +341,8 @@ class VaultWithCashTest : TestDependencyInjectionBase() {
// Create a txn consuming different contract types
val dummyMoveBuilder = TransactionBuilder(notary = DUMMY_NOTARY).apply {
- addOutputState(DummyLinearContract.State(participants = listOf(freshIdentity)))
- addOutputState(DummyDealContract.State(ref = "999", participants = listOf(freshIdentity)))
+ addOutputState(DummyLinearContract.State(participants = listOf(freshIdentity)), DUMMY_LINEAR_CONTRACT_PROGRAM_ID)
+ addOutputState(DummyDealContract.State(ref = "999", participants = listOf(freshIdentity)), DUMMY_DEAL_PROGRAM_ID)
addInputState(linearStates.first())
addInputState(deals.first())
addCommand(dummyCommand(notaryServices.legalIdentityKey))
diff --git a/samples/attachment-demo/src/main/kotlin/net/corda/attachmentdemo/AttachmentDemo.kt b/samples/attachment-demo/src/main/kotlin/net/corda/attachmentdemo/AttachmentDemo.kt
index 1b24d48640..b8eec13bb7 100644
--- a/samples/attachment-demo/src/main/kotlin/net/corda/attachmentdemo/AttachmentDemo.kt
+++ b/samples/attachment-demo/src/main/kotlin/net/corda/attachmentdemo/AttachmentDemo.kt
@@ -116,7 +116,7 @@ class AttachmentDemoFlow(val otherSide: Party, val notary: Party, val hash: Secu
override fun call(): SignedTransaction {
// Create a trivial transaction with an output that describes the attachment, and the attachment itself
val ptx = TransactionBuilder(notary)
- .addOutputState(AttachmentContract.State(hash))
+ .addOutputState(AttachmentContract.State(hash), ATTACHMENT_PROGRAM_ID)
.addCommand(AttachmentContract.Command, serviceHub.legalIdentityKey)
.addAttachment(hash)
@@ -178,6 +178,8 @@ private fun printHelp(parser: OptionParser) {
parser.printHelpOn(System.out)
}
+val ATTACHMENT_PROGRAM_ID = "net.corda.attachmentdemo.AttachmentContract"
+
class AttachmentContract : Contract {
override fun verify(tx: LedgerTransaction) {
val state = tx.outputsOfType().single()
@@ -188,7 +190,6 @@ class AttachmentContract : Contract {
object Command : TypeOnlyCommandData()
data class State(val hash: SecureHash.SHA256) : ContractState {
- override val contract: Contract = AttachmentContract()
override val participants: List = emptyList()
}
}
diff --git a/samples/irs-demo/src/main/kotlin/net/corda/irs/contract/IRS.kt b/samples/irs-demo/src/main/kotlin/net/corda/irs/contract/IRS.kt
index 8a3d074e24..fa73c2571e 100644
--- a/samples/irs-demo/src/main/kotlin/net/corda/irs/contract/IRS.kt
+++ b/samples/irs-demo/src/main/kotlin/net/corda/irs/contract/IRS.kt
@@ -20,7 +20,7 @@ import java.math.RoundingMode
import java.time.LocalDate
import java.util.*
-val IRS_PROGRAM_ID = InterestRateSwap()
+val IRS_PROGRAM_ID = "net.corda.irs.contract.InterestRateSwap"
// This is a placeholder for some types that we haven't identified exactly what they are just yet for things still in discussion
@CordaSerializable
@@ -605,9 +605,6 @@ class InterestRateSwap : Contract {
val common: Common,
override val linearId: UniqueIdentifier = UniqueIdentifier(common.tradeID)
) : FixableDealState, SchedulableState {
-
- override val contract = IRS_PROGRAM_ID
-
override val oracleType: ServiceType
get() = NodeInterestRates.Oracle.type
@@ -627,7 +624,7 @@ class InterestRateSwap : Contract {
override fun generateAgreement(notary: Party): TransactionBuilder = InterestRateSwap().generateAgreement(floatingLeg, fixedLeg, calculation, common, notary)
override fun generateFix(ptx: TransactionBuilder, oldState: StateAndRef<*>, fix: Fix) {
- InterestRateSwap().generateFix(ptx, StateAndRef(TransactionState(this, oldState.state.notary), oldState.ref), fix)
+ InterestRateSwap().generateFix(ptx, StateAndRef(TransactionState(this, IRS_PROGRAM_ID, oldState.state.notary), oldState.ref), fix)
}
override fun nextFixingOf(): FixOf? {
@@ -721,7 +718,7 @@ class InterestRateSwap : Contract {
// Put all the above into a new State object.
val state = State(fixedLeg, floatingLeg, newCalculation, common)
- return TransactionBuilder(notary).withItems(state, Command(Commands.Agree(), listOf(state.floatingLeg.floatingRatePayer.owningKey, state.fixedLeg.fixedRatePayer.owningKey)))
+ return TransactionBuilder(notary).withItems(StateAndContract(state, IRS_PROGRAM_ID), Command(Commands.Agree(), listOf(state.floatingLeg.floatingRatePayer.owningKey, state.fixedLeg.fixedRatePayer.owningKey)))
}
private fun calcFixingDate(date: LocalDate, fixingPeriodOffset: Int, calendar: BusinessCalendar): LocalDate {
@@ -736,6 +733,7 @@ class InterestRateSwap : Contract {
val fixedRate = FixedRate(RatioUnit(fixing.value))
tx.addOutputState(
irs.state.data.copy(calculation = irs.state.data.calculation.applyFixing(fixing.of.forDay, fixedRate)),
+ irs.state.contract,
irs.state.notary
)
tx.addCommand(Commands.Refix(fixing), listOf(irs.state.data.floatingLeg.floatingRatePayer.owningKey, irs.state.data.fixedLeg.fixedRatePayer.owningKey))
diff --git a/samples/irs-demo/src/test/kotlin/net/corda/irs/api/NodeInterestRatesTest.kt b/samples/irs-demo/src/test/kotlin/net/corda/irs/api/NodeInterestRatesTest.kt
index 714840f777..f7ef2df219 100644
--- a/samples/irs-demo/src/test/kotlin/net/corda/irs/api/NodeInterestRatesTest.kt
+++ b/samples/irs-demo/src/test/kotlin/net/corda/irs/api/NodeInterestRatesTest.kt
@@ -3,7 +3,6 @@ package net.corda.irs.api
import net.corda.core.contracts.Command
import net.corda.core.contracts.ContractState
import net.corda.core.contracts.TransactionState
-import net.corda.core.contracts.`with notary`
import net.corda.core.crypto.MerkleTreeException
import net.corda.core.crypto.generateKeyPair
import net.corda.core.identity.Party
@@ -15,10 +14,7 @@ import net.corda.core.utilities.getX500Name
import net.corda.finance.DOLLARS
import net.corda.finance.contracts.Fix
import net.corda.finance.contracts.FixOf
-import net.corda.finance.contracts.asset.CASH
-import net.corda.finance.contracts.asset.Cash
-import net.corda.finance.contracts.asset.`issued by`
-import net.corda.finance.contracts.asset.`owned by`
+import net.corda.finance.contracts.asset.*
import net.corda.irs.flows.RatesFixFlow
import net.corda.node.utilities.CordaPersistence
import net.corda.node.utilities.configureDatabase
@@ -246,7 +242,7 @@ class NodeInterestRatesTest : TestDependencyInjectionBase() {
}
private fun makePartialTX() = TransactionBuilder(DUMMY_NOTARY).withItems(
- 1000.DOLLARS.CASH `issued by` DUMMY_CASH_ISSUER `owned by` ALICE `with notary` DUMMY_NOTARY)
+ TransactionState(1000.DOLLARS.CASH `issued by` DUMMY_CASH_ISSUER `owned by` ALICE, CASH_PROGRAM_ID, DUMMY_NOTARY))
private fun makeFullTx() = makePartialTX().withItems(dummyCommand())
}
diff --git a/samples/irs-demo/src/test/kotlin/net/corda/irs/contract/IRSTests.kt b/samples/irs-demo/src/test/kotlin/net/corda/irs/contract/IRSTests.kt
index 338f723668..7fa0595e06 100644
--- a/samples/irs-demo/src/test/kotlin/net/corda/irs/contract/IRSTests.kt
+++ b/samples/irs-demo/src/test/kotlin/net/corda/irs/contract/IRSTests.kt
@@ -15,6 +15,7 @@ import java.math.BigDecimal
import java.time.LocalDate
import java.util.*
import kotlin.test.assertEquals
+import net.corda.irs.contract.IRS_PROGRAM_ID
fun createDummyIRS(irsSelect: Int): InterestRateSwap.State {
return when (irsSelect) {
@@ -369,7 +370,7 @@ class IRSTests : TestDependencyInjectionBase() {
return ledger(initialiseSerialization = false) {
transaction("Agreement") {
- output("irs post agreement") { singleIRS() }
+ output(IRS_PROGRAM_ID, "irs post agreement") { singleIRS() }
command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() }
timeWindow(TEST_TX_TIME)
this.verifies()
@@ -378,7 +379,7 @@ class IRSTests : TestDependencyInjectionBase() {
transaction("Fix") {
input("irs post agreement")
val postAgreement = "irs post agreement".output()
- output("irs post first fixing") {
+ output(IRS_PROGRAM_ID, "irs post first fixing") {
postAgreement.copy(
postAgreement.fixedLeg,
postAgreement.floatingLeg,
@@ -399,8 +400,8 @@ class IRSTests : TestDependencyInjectionBase() {
fun `ensure failure occurs when there are inbound states for an agreement command`() {
val irs = singleIRS()
transaction(initialiseSerialization = false) {
- input { irs }
- output("irs post agreement") { irs }
+ input(IRS_PROGRAM_ID, irs)
+ output(IRS_PROGRAM_ID, "irs post agreement", irs)
command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() }
timeWindow(TEST_TX_TIME)
this `fails with` "There are no in states for an agreement"
@@ -412,9 +413,7 @@ class IRSTests : TestDependencyInjectionBase() {
val irs = singleIRS()
val emptySchedule = mutableMapOf()
transaction(initialiseSerialization = false) {
- output {
- 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() }
timeWindow(TEST_TX_TIME)
this `fails with` "There are events in the fix schedule"
@@ -426,9 +425,7 @@ class IRSTests : TestDependencyInjectionBase() {
val irs = singleIRS()
val emptySchedule = mutableMapOf()
transaction(initialiseSerialization = false) {
- output {
- 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() }
timeWindow(TEST_TX_TIME)
this `fails with` "There are events in the float schedule"
@@ -439,18 +436,14 @@ class IRSTests : TestDependencyInjectionBase() {
fun `ensure notionals are non zero`() {
val irs = singleIRS()
transaction(initialiseSerialization = false) {
- output {
- 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() }
timeWindow(TEST_TX_TIME)
this `fails with` "All notionals must be non zero"
}
transaction(initialiseSerialization = false) {
- output {
- 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() }
timeWindow(TEST_TX_TIME)
this `fails with` "All notionals must be non zero"
@@ -462,9 +455,7 @@ class IRSTests : TestDependencyInjectionBase() {
val irs = singleIRS()
val modifiedIRS = irs.copy(fixedLeg = irs.fixedLeg.copy(fixedRate = FixedRate(PercentageRatioUnit("-0.1"))))
transaction(initialiseSerialization = false) {
- output {
- modifiedIRS
- }
+ output(IRS_PROGRAM_ID, modifiedIRS)
command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() }
timeWindow(TEST_TX_TIME)
this `fails with` "The fixed leg rate must be positive"
@@ -479,9 +470,7 @@ class IRSTests : TestDependencyInjectionBase() {
val irs = singleIRS()
val modifiedIRS = irs.copy(fixedLeg = irs.fixedLeg.copy(notional = Amount(irs.fixedLeg.notional.quantity, Currency.getInstance("JPY"))))
transaction(initialiseSerialization = false) {
- output {
- modifiedIRS
- }
+ output(IRS_PROGRAM_ID, modifiedIRS)
command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() }
timeWindow(TEST_TX_TIME)
this `fails with` "The currency of the notionals must be the same"
@@ -493,9 +482,7 @@ class IRSTests : TestDependencyInjectionBase() {
val irs = singleIRS()
val modifiedIRS = irs.copy(fixedLeg = irs.fixedLeg.copy(notional = Amount(irs.floatingLeg.notional.quantity + 1, irs.floatingLeg.notional.token)))
transaction(initialiseSerialization = false) {
- output {
- modifiedIRS
- }
+ output(IRS_PROGRAM_ID, modifiedIRS)
command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() }
timeWindow(TEST_TX_TIME)
this `fails with` "All leg notionals must be the same"
@@ -507,9 +494,7 @@ class IRSTests : TestDependencyInjectionBase() {
val irs = singleIRS()
val modifiedIRS1 = irs.copy(fixedLeg = irs.fixedLeg.copy(terminationDate = irs.fixedLeg.effectiveDate.minusDays(1)))
transaction(initialiseSerialization = false) {
- output {
- modifiedIRS1
- }
+ output(IRS_PROGRAM_ID, modifiedIRS1)
command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() }
timeWindow(TEST_TX_TIME)
this `fails with` "The effective date is before the termination date for the fixed leg"
@@ -517,9 +502,7 @@ class IRSTests : TestDependencyInjectionBase() {
val modifiedIRS2 = irs.copy(floatingLeg = irs.floatingLeg.copy(terminationDate = irs.floatingLeg.effectiveDate.minusDays(1)))
transaction(initialiseSerialization = false) {
- output {
- modifiedIRS2
- }
+ output(IRS_PROGRAM_ID, modifiedIRS2)
command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() }
timeWindow(TEST_TX_TIME)
this `fails with` "The effective date is before the termination date for the floating leg"
@@ -532,9 +515,7 @@ class IRSTests : TestDependencyInjectionBase() {
val modifiedIRS3 = irs.copy(floatingLeg = irs.floatingLeg.copy(terminationDate = irs.fixedLeg.terminationDate.minusDays(1)))
transaction(initialiseSerialization = false) {
- output {
- modifiedIRS3
- }
+ output(IRS_PROGRAM_ID, modifiedIRS3)
command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() }
timeWindow(TEST_TX_TIME)
this `fails with` "The termination dates are aligned"
@@ -543,9 +524,7 @@ class IRSTests : TestDependencyInjectionBase() {
val modifiedIRS4 = irs.copy(floatingLeg = irs.floatingLeg.copy(effectiveDate = irs.fixedLeg.effectiveDate.minusDays(1)))
transaction(initialiseSerialization = false) {
- output {
- modifiedIRS4
- }
+ output(IRS_PROGRAM_ID, modifiedIRS4)
command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() }
timeWindow(TEST_TX_TIME)
this `fails with` "The effective dates are aligned"
@@ -559,7 +538,7 @@ class IRSTests : TestDependencyInjectionBase() {
val bd = BigDecimal("0.0063518")
transaction(initialiseSerialization = false) {
- output("irs post agreement") { singleIRS() }
+ output(IRS_PROGRAM_ID, "irs post agreement") { singleIRS() }
command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() }
timeWindow(TEST_TX_TIME)
this.verifies()
@@ -572,10 +551,7 @@ class IRSTests : TestDependencyInjectionBase() {
oldIRS.common)
transaction(initialiseSerialization = false) {
- input {
- oldIRS
-
- }
+ input(IRS_PROGRAM_ID, oldIRS)
// Templated tweak for reference. A corrent fixing applied should be ok
tweak {
@@ -583,7 +559,7 @@ class IRSTests : TestDependencyInjectionBase() {
InterestRateSwap.Commands.Refix(Fix(FixOf("ICE LIBOR", ld, Tenor("3M")), bd))
}
timeWindow(TEST_TX_TIME)
- output { newIRS }
+ output(IRS_PROGRAM_ID, newIRS)
this.verifies()
}
@@ -591,7 +567,7 @@ class IRSTests : TestDependencyInjectionBase() {
tweak {
command(ORACLE_PUBKEY) { InterestRateSwap.Commands.Refix(Fix(FixOf("ICE LIBOR", ld, Tenor("3M")), bd)) }
timeWindow(TEST_TX_TIME)
- output { oldIRS }
+ output(IRS_PROGRAM_ID, oldIRS)
this `fails with` "There is at least one difference in the IRS floating leg payment schedules"
}
@@ -604,7 +580,7 @@ class IRSTests : TestDependencyInjectionBase() {
val firstResetValue = newIRS.calculation.floatingLegPaymentSchedule[firstResetKey]
val modifiedFirstResetValue = firstResetValue!!.copy(notional = Amount(firstResetValue.notional.quantity, Currency.getInstance("JPY")))
- output {
+ output(IRS_PROGRAM_ID) {
newIRS.copy(
newIRS.fixedLeg,
newIRS.floatingLeg,
@@ -624,7 +600,7 @@ class IRSTests : TestDependencyInjectionBase() {
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")))
- output {
+ output(IRS_PROGRAM_ID) {
newIRS.copy(
newIRS.fixedLeg,
newIRS.floatingLeg,
@@ -653,7 +629,7 @@ class IRSTests : TestDependencyInjectionBase() {
return ledger(initialiseSerialization = false) {
transaction("Agreement") {
- output("irs post agreement1") {
+ output(IRS_PROGRAM_ID, "irs post agreement1") {
irs.copy(
irs.fixedLeg,
irs.floatingLeg,
@@ -667,7 +643,7 @@ class IRSTests : TestDependencyInjectionBase() {
}
transaction("Agreement") {
- output("irs post agreement2") {
+ output(IRS_PROGRAM_ID, "irs post agreement2") {
irs.copy(
linearId = UniqueIdentifier("t2"),
fixedLeg = irs.fixedLeg,
@@ -685,7 +661,7 @@ class IRSTests : TestDependencyInjectionBase() {
input("irs post agreement1")
input("irs post agreement2")
val postAgreement1 = "irs post agreement1".output()
- output("irs post first fixing1") {
+ output(IRS_PROGRAM_ID, "irs post first fixing1") {
postAgreement1.copy(
postAgreement1.fixedLeg,
postAgreement1.floatingLeg,
@@ -694,7 +670,7 @@ class IRSTests : TestDependencyInjectionBase() {
)
}
val postAgreement2 = "irs post agreement2".output()
- output("irs post first fixing2") {
+ output(IRS_PROGRAM_ID, "irs post first fixing2") {
postAgreement2.copy(
postAgreement2.fixedLeg,
postAgreement2.floatingLeg,
diff --git a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/flows/DummyIssueAndMove.kt b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/flows/DummyIssueAndMove.kt
index 82e62ba997..af3c44c451 100644
--- a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/flows/DummyIssueAndMove.kt
+++ b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/flows/DummyIssueAndMove.kt
@@ -14,22 +14,21 @@ import net.corda.core.transactions.TransactionBuilder
@StartableByRPC
class DummyIssueAndMove(private val notary: Party, private val counterpartyNode: Party, private val discriminator: Int) : FlowLogic() {
+ val DO_NOTHING_PROGRAM_ID = "net.corda.notarydemo.flows.DummyIssueAndMove.DoNothingContract"
object DoNothingContract : Contract {
override fun verify(tx: LedgerTransaction) {}
}
data class DummyCommand(val dummy: Int = 0): CommandData
- data class State(override val participants: List, private val discriminator: Int) : ContractState {
- override val contract = DoNothingContract
- }
+ data class State(override val participants: List, private val discriminator: Int) : ContractState
@Suspendable
override fun call(): SignedTransaction {
// Self issue an asset
val state = State(listOf(serviceHub.myInfo.legalIdentity), discriminator)
val issueTx = serviceHub.signInitialTransaction(TransactionBuilder(notary).apply {
- addOutputState(state)
+ addOutputState(state, DO_NOTHING_PROGRAM_ID)
addCommand(DummyCommand(),listOf(serviceHub.myInfo.legalIdentity.owningKey))
})
serviceHub.recordTransactions(issueTx)
@@ -37,7 +36,7 @@ class DummyIssueAndMove(private val notary: Party, private val counterpartyNode:
// We don't check signatures because we know that the notary's signature is missing
return serviceHub.signInitialTransaction(TransactionBuilder(notary).apply {
addInputState(issueTx.tx.outRef(0))
- addOutputState(state.copy(participants = listOf(counterpartyNode)))
+ addOutputState(state.copy(participants = listOf(counterpartyNode)), DO_NOTHING_PROGRAM_ID)
addCommand(DummyCommand(),listOf(serviceHub.myInfo.legalIdentity.owningKey))
})
}
diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/IRSState.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/IRSState.kt
index db1eff6755..e42c2653b8 100644
--- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/IRSState.kt
+++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/IRSState.kt
@@ -1,6 +1,7 @@
package net.corda.vega.contracts
import net.corda.core.contracts.Command
+import net.corda.core.contracts.StateAndContract
import net.corda.core.contracts.UniqueIdentifier
import net.corda.core.crypto.keys
import net.corda.core.identity.AbstractParty
@@ -9,6 +10,8 @@ import net.corda.core.transactions.TransactionBuilder
import net.corda.finance.contracts.DealState
import java.security.PublicKey
+val IRS_PROGRAM_ID = "net.corda.vega.contracts.OGTrade"
+
/**
* Represents an OpenGamma IRS between two parties. Does not implement any fixing functionality.
*
@@ -17,13 +20,12 @@ import java.security.PublicKey
data class IRSState(val swap: SwapData,
val buyer: AbstractParty,
val seller: AbstractParty,
- override val contract: OGTrade,
override val linearId: UniqueIdentifier = UniqueIdentifier(swap.id.first + swap.id.second)) : DealState {
val ref: String get() = linearId.externalId!! // Same as the constructor for UniqueIdentified
override val participants: List get() = listOf(buyer, seller)
override fun generateAgreement(notary: Party): TransactionBuilder {
- val state = IRSState(swap, buyer, seller, OGTrade())
- return TransactionBuilder(notary).withItems(state, Command(OGTrade.Commands.Agree(), participants.map { it.owningKey }))
+ val state = IRSState(swap, buyer, seller)
+ return TransactionBuilder(notary).withItems(StateAndContract(state, IRS_PROGRAM_ID), Command(OGTrade.Commands.Agree(), participants.map { it.owningKey }))
}
}
diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/PortfolioState.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/PortfolioState.kt
index 02b1367d14..d98a414791 100644
--- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/PortfolioState.kt
+++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/PortfolioState.kt
@@ -14,12 +14,13 @@ import java.time.LocalDate
import java.time.ZoneOffset
import java.time.temporal.ChronoUnit
+val PORTFOLIO_SWAP_PROGRAM_ID = "net.corda.vega.contracts.PortfolioSwap"
+
/**
* Represents an aggregate set of trades agreed between two parties and a possible valuation of that portfolio at a
* given point in time. This state can be consumed to create a new state with a mutated valuation or portfolio.
*/
data class PortfolioState(val portfolio: List,
- override val contract: PortfolioSwap,
private val _parties: Pair,
val valuationDate: LocalDate,
val valuation: PortfolioValuation? = null,
@@ -38,7 +39,7 @@ data class PortfolioState(val portfolio: List,
}
override fun generateAgreement(notary: Party): TransactionBuilder {
- return TransactionBuilder(notary).withItems(copy(), Command(PortfolioSwap.Commands.Agree(), participants.map { it.owningKey }))
+ return TransactionBuilder(notary).withItems(StateAndContract(copy(), PORTFOLIO_SWAP_PROGRAM_ID), Command(PortfolioSwap.Commands.Agree(), participants.map { it.owningKey }))
}
override fun generateRevision(notary: Party, oldState: StateAndRef<*>, updatedValue: Update): TransactionBuilder {
@@ -48,7 +49,7 @@ data class PortfolioState(val portfolio: List,
val tx = TransactionBuilder(notary)
tx.addInputState(oldState)
- tx.addOutputState(copy(portfolio = portfolio, valuation = valuation))
+ tx.addOutputState(copy(portfolio = portfolio, valuation = valuation), PORTFOLIO_SWAP_PROGRAM_ID)
tx.addCommand(PortfolioSwap.Commands.Update(), participants.map { it.owningKey })
return tx
}
diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/IRSTradeFlow.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/IRSTradeFlow.kt
index d167e347ae..1c317ea4f2 100644
--- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/IRSTradeFlow.kt
+++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/IRSTradeFlow.kt
@@ -32,7 +32,7 @@ object IRSTradeFlow {
} else {
Pair(otherParty, myIdentity)
}
- val offer = IRSState(swap, buyer, seller, OGTrade())
+ val offer = IRSState(swap, buyer, seller)
logger.info("Handshake finished, sending IRS trade offer message")
val otherPartyAgreeFlag = sendAndReceive(otherParty, OfferMessage(notary, offer)).unwrap { it }
diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt
index e8565f65ec..7edd90048f 100644
--- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt
+++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt
@@ -84,7 +84,7 @@ object SimmFlow {
private fun agreePortfolio(portfolio: Portfolio) {
logger.info("Agreeing portfolio")
val parties = Pair(myIdentity, otherParty)
- val portfolioState = PortfolioState(portfolio.refs, PortfolioSwap(), parties, valuationDate)
+ val portfolioState = PortfolioState(portfolio.refs, parties, valuationDate)
send(otherParty, OfferMessage(notary, portfolioState, existing?.ref, valuationDate))
logger.info("Awaiting two party deal acceptor")
diff --git a/samples/trader-demo/src/test/kotlin/net/corda/traderdemo/TransactionGraphSearchTests.kt b/samples/trader-demo/src/test/kotlin/net/corda/traderdemo/TransactionGraphSearchTests.kt
index b39ad233a5..afcb0e37ac 100644
--- a/samples/trader-demo/src/test/kotlin/net/corda/traderdemo/TransactionGraphSearchTests.kt
+++ b/samples/trader-demo/src/test/kotlin/net/corda/traderdemo/TransactionGraphSearchTests.kt
@@ -6,6 +6,7 @@ import net.corda.core.transactions.SignedTransaction
import net.corda.core.transactions.TransactionBuilder
import net.corda.core.transactions.WireTransaction
import net.corda.testing.*
+import net.corda.testing.contracts.DUMMY_PROGRAM_ID
import net.corda.testing.contracts.DummyContract
import net.corda.testing.contracts.DummyState
import net.corda.testing.node.MockServices
@@ -35,7 +36,7 @@ class TransactionGraphSearchTests : TestDependencyInjectionBase() {
val notaryServices = MockServices(DUMMY_NOTARY_KEY)
val originBuilder = TransactionBuilder(DUMMY_NOTARY)
- .addOutputState(DummyState(random31BitValue()))
+ .addOutputState(DummyState(random31BitValue()), DUMMY_PROGRAM_ID)
.addCommand(command, MEGA_CORP_PUBKEY)
val originPtx = megaCorpServices.signInitialTransaction(originBuilder)
diff --git a/testing/test-utils/src/main/kotlin/net/corda/testing/TestDSL.kt b/testing/test-utils/src/main/kotlin/net/corda/testing/TestDSL.kt
index c641c69b67..480f13ec34 100644
--- a/testing/test-utils/src/main/kotlin/net/corda/testing/TestDSL.kt
+++ b/testing/test-utils/src/main/kotlin/net/corda/testing/TestDSL.kt
@@ -9,6 +9,7 @@ import net.corda.core.node.ServiceHub
import net.corda.core.transactions.SignedTransaction
import net.corda.core.transactions.TransactionBuilder
import net.corda.core.transactions.WireTransaction
+import net.corda.testing.contracts.DUMMY_PROGRAM_ID
import net.corda.testing.contracts.DummyContract
import java.io.InputStream
import java.security.KeyPair
@@ -119,8 +120,8 @@ data class TestTransactionDSLInterpreter private constructor(
transactionBuilder.addInputState(StateAndRef(state, stateRef))
}
- override fun _output(label: String?, notary: Party, encumbrance: Int?, contractState: ContractState) {
- transactionBuilder.addOutputState(contractState, notary, encumbrance)
+ override fun _output(contractClassName: ContractClassName, label: String?, notary: Party, encumbrance: Int?, contractState: ContractState) {
+ transactionBuilder.addOutputState(contractState, contractClassName, notary, encumbrance)
if (label != null) {
if (label in labelToIndexMap) {
throw DuplicateOutputLabel(label)
@@ -276,7 +277,7 @@ data class TestLedgerDSLInterpreter private constructor(
private fun fillTransaction(transactionBuilder: TransactionBuilder) {
if (transactionBuilder.commands().isEmpty()) transactionBuilder.addCommand(dummyCommand())
if (transactionBuilder.inputStates().isEmpty() && transactionBuilder.outputStates().isEmpty()) {
- transactionBuilder.addOutputState(DummyContract.SingleOwnerState(owner = ALICE))
+ transactionBuilder.addOutputState(DummyContract.SingleOwnerState(owner = ALICE), DUMMY_PROGRAM_ID)
}
}
diff --git a/testing/test-utils/src/main/kotlin/net/corda/testing/TransactionDSLInterpreter.kt b/testing/test-utils/src/main/kotlin/net/corda/testing/TransactionDSLInterpreter.kt
index 544d050f54..8b7d382c3c 100644
--- a/testing/test-utils/src/main/kotlin/net/corda/testing/TransactionDSLInterpreter.kt
+++ b/testing/test-utils/src/main/kotlin/net/corda/testing/TransactionDSLInterpreter.kt
@@ -34,8 +34,9 @@ interface TransactionDSLInterpreter : Verifies, OutputStateLookup {
* @param notary The associated notary.
* @param encumbrance The position of the encumbrance state.
* @param contractState The state itself.
+ * @params contractClassName The class name of the contract that verifies this state.
*/
- fun _output(label: String?, notary: Party, encumbrance: Int?, contractState: ContractState)
+ fun _output(contractClassName: ContractClassName, label: String?, notary: Party, encumbrance: Int?, contractState: ContractState)
/**
* Adds an [Attachment] reference to the transaction.
@@ -75,30 +76,30 @@ class TransactionDSL(val interpreter: T) : Tr
* input to the current transaction.
* @param state The state to be added.
*/
- fun input(state: ContractState) {
+ fun input(contractClassName: ContractClassName, state: ContractState) {
val transaction = ledgerInterpreter._unverifiedTransaction(null, TransactionBuilder(notary = DUMMY_NOTARY)) {
- output { state }
+ output(contractClassName) { state }
}
input(transaction.outRef(0).ref)
}
- fun input(stateClosure: () -> ContractState) = input(stateClosure())
+ fun input(contractClassName: ContractClassName, stateClosure: () -> ContractState) = input(contractClassName, stateClosure())
/**
* @see TransactionDSLInterpreter._output
*/
@JvmOverloads
- fun output(label: String? = null, notary: Party = DUMMY_NOTARY, encumbrance: Int? = null, contractStateClosure: () -> ContractState) =
- _output(label, notary, encumbrance, contractStateClosure())
+ fun output(contractClassName: ContractClassName, label: String? = null, notary: Party = DUMMY_NOTARY, encumbrance: Int? = null, contractStateClosure: () -> ContractState) =
+ _output(contractClassName, label, notary, encumbrance, contractStateClosure())
/**
* @see TransactionDSLInterpreter._output
*/
- fun output(label: String, contractState: ContractState) =
- _output(label, DUMMY_NOTARY, null, contractState)
+ fun output(contractClassName: ContractClassName, label: String, contractState: ContractState) =
+ _output(contractClassName, label, DUMMY_NOTARY, null, contractState)
- fun output(contractState: ContractState) =
- _output(null, DUMMY_NOTARY, null, contractState)
+ fun output(contractClassName: ContractClassName, contractState: ContractState) =
+ _output(contractClassName,null, DUMMY_NOTARY, null, contractState)
/**
* @see TransactionDSLInterpreter._command
diff --git a/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyContract.kt b/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyContract.kt
index 14f80dee98..9657ca997d 100644
--- a/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyContract.kt
+++ b/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyContract.kt
@@ -8,7 +8,7 @@ import net.corda.core.transactions.TransactionBuilder
// The dummy contract doesn't do anything useful. It exists for testing purposes, but has to be serializable
-val DUMMY_PROGRAM_ID = DummyContract()
+val DUMMY_PROGRAM_ID = "net.corda.testing.contracts.DummyContract"
data class DummyContract(val blank: Any? = null) : Contract {
interface State : ContractState {
@@ -16,7 +16,6 @@ data class DummyContract(val blank: Any? = null) : Contract {
}
data class SingleOwnerState(override val magicNumber: Int = 0, override val owner: AbstractParty) : OwnableState, State {
- override val contract = DUMMY_PROGRAM_ID
override val participants: List
get() = listOf(owner)
@@ -30,7 +29,6 @@ data class DummyContract(val blank: Any? = null) : Contract {
*/
data class MultiOwnerState(override val magicNumber: Int = 0,
val owners: List) : ContractState, State {
- override val contract = DUMMY_PROGRAM_ID
override val participants: List get() = owners
}
@@ -49,10 +47,10 @@ data class DummyContract(val blank: Any? = null) : Contract {
val owners = listOf(owner) + otherOwners
return if (owners.size == 1) {
val state = SingleOwnerState(magicNumber, owners.first().party)
- TransactionBuilder(notary).withItems(state, Command(Commands.Create(), owners.first().party.owningKey))
+ TransactionBuilder(notary).withItems(StateAndContract(state, DUMMY_PROGRAM_ID), Command(Commands.Create(), owners.first().party.owningKey))
} else {
val state = MultiOwnerState(magicNumber, owners.map { it.party })
- TransactionBuilder(notary).withItems(state, Command(Commands.Create(), owners.map { it.party.owningKey }))
+ TransactionBuilder(notary).withItems(StateAndContract(state, DUMMY_PROGRAM_ID), Command(Commands.Create(), owners.map { it.party.owningKey }))
}
}
@@ -64,7 +62,7 @@ data class DummyContract(val blank: Any? = null) : Contract {
return TransactionBuilder(notary = priors[0].state.notary).withItems(
/* INPUTS */ *priors.toTypedArray(),
/* COMMAND */ Command(cmd, priorState.owner.owningKey),
- /* OUTPUT */ state
+ /* OUTPUT */ StateAndContract(state, DUMMY_PROGRAM_ID)
)
}
}
diff --git a/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyContractV2.kt b/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyContractV2.kt
index f8103acecc..1452e72a03 100644
--- a/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyContractV2.kt
+++ b/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyContractV2.kt
@@ -8,17 +8,16 @@ import net.corda.core.transactions.TransactionBuilder
import net.corda.core.transactions.WireTransaction
// The dummy contract doesn't do anything useful. It exists for testing purposes.
-val DUMMY_V2_PROGRAM_ID = DummyContractV2()
+val DUMMY_V2_PROGRAM_ID = "net.corda.testing.contracts.DummyContractV2"
/**
* Dummy contract state for testing of the upgrade process.
*/
// DOCSTART 1
class DummyContractV2 : UpgradedContract {
- override val legacyContract = DummyContract::class.java
+ override val legacyContract = DummyContract::class.java.name
data class State(val magicNumber: Int = 0, val owners: List) : ContractState {
- override val contract = DUMMY_V2_PROGRAM_ID
override val participants: List = owners
}
@@ -51,8 +50,8 @@ class DummyContractV2 : UpgradedContract,
override val linearId: UniqueIdentifier) : DealState, QueryableState
{
- constructor(contract: Contract = DummyDealContract(),
- participants: List = listOf(),
- ref: String) : this(contract, participants, UniqueIdentifier(ref))
+ constructor(participants: List = listOf(),
+ ref: String) : this(participants, UniqueIdentifier(ref))
override fun generateAgreement(notary: Party): TransactionBuilder {
throw UnsupportedOperationException("not implemented")
diff --git a/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyLinearContract.kt b/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyLinearContract.kt
index 408fefffd3..451e285114 100644
--- a/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyLinearContract.kt
+++ b/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyLinearContract.kt
@@ -16,6 +16,8 @@ import net.corda.testing.schemas.DummyLinearStateSchemaV2
import java.time.LocalDateTime
import java.time.ZoneOffset.UTC
+val DUMMY_LINEAR_CONTRACT_PROGRAM_ID = "net.corda.testing.contracts.DummyLinearContract"
+
class DummyLinearContract : Contract {
override fun verify(tx: LedgerTransaction) {
val inputs = tx.inputs.map { it.state.data }.filterIsInstance()
@@ -31,16 +33,13 @@ class DummyLinearContract : Contract {
data class State(
override val linearId: UniqueIdentifier = UniqueIdentifier(),
- override val contract: Contract = DummyLinearContract(),
override val participants: List = listOf(),
val linearString: String = "ABC",
val linearNumber: Long = 123L,
val linearTimestamp: java.time.Instant = LocalDateTime.now().toInstant(UTC),
val linearBoolean: Boolean = true,
val nonce: SecureHash = SecureHash.randomSHA256()) : LinearState, QueryableState {
-
override fun supportedSchemas(): Iterable = listOf(DummyLinearStateSchemaV1, DummyLinearStateSchemaV2)
-
override fun generateMappedObject(schema: MappedSchema): PersistentState {
return when (schema) {
is DummyLinearStateSchemaV1 -> DummyLinearStateSchemaV1.PersistentDummyLinearState(
diff --git a/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyState.kt b/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyState.kt
index c2e0696889..e1047cb2e3 100644
--- a/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyState.kt
+++ b/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyState.kt
@@ -7,6 +7,5 @@ import net.corda.core.identity.AbstractParty
* Dummy state for use in testing. Not part of any contract, not even the [DummyContract].
*/
data class DummyState(val magicNumber: Int = 0) : ContractState {
- override val contract = DUMMY_PROGRAM_ID
override val participants: List get() = emptyList()
}
diff --git a/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/VaultFiller.kt b/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/VaultFiller.kt
index aeec13aca4..78c19f58ab 100644
--- a/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/VaultFiller.kt
+++ b/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/VaultFiller.kt
@@ -41,7 +41,7 @@ fun ServiceHub.fillWithSomeTestDeals(dealIds: List,
val transactions: List = dealIds.map {
// Issue a deal state
val dummyIssue = TransactionBuilder(notary = notary).apply {
- addOutputState(DummyDealContract.State(ref = it, participants = participants.plus(me)))
+ addOutputState(DummyDealContract.State(ref = it, participants = participants.plus(me)), DUMMY_DEAL_PROGRAM_ID)
addCommand(dummyCommand())
}
val stx = signInitialTransaction(dummyIssue)
@@ -80,7 +80,7 @@ fun ServiceHub.fillWithSomeTestLinearStates(numberToCreate: Int,
linearString = linearString,
linearNumber = linearNumber,
linearBoolean = linearBoolean,
- linearTimestamp = linearTimestamp))
+ linearTimestamp = linearTimestamp), DUMMY_LINEAR_CONTRACT_PROGRAM_ID)
addCommand(dummyCommand())
}
@@ -221,7 +221,7 @@ fun ServiceHub.consumeAndProduce(stateAndRef: StateAndRef,
// Create a txn consuming different contract types
builder = TransactionBuilder(notary = notary).apply {
addOutputState(DummyLinearContract.State(linearId = stateAndRef.state.data.linearId,
- participants = stateAndRef.state.data.participants))
+ participants = stateAndRef.state.data.participants), DUMMY_LINEAR_CONTRACT_PROGRAM_ID)
addCommand(dummyCommand(notary.owningKey))
}
val producedTx = signInitialTransaction(builder, notary.owningKey)
diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/views/TransactionViewer.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/views/TransactionViewer.kt
index 83d1e69f0c..4a94ec7555 100644
--- a/tools/explorer/src/main/kotlin/net/corda/explorer/views/TransactionViewer.kt
+++ b/tools/explorer/src/main/kotlin/net/corda/explorer/views/TransactionViewer.kt
@@ -134,8 +134,8 @@ class TransactionViewer : CordaView("Transactions") {
val searchField = SearchField(transactions,
"Transaction ID" to { tx, s -> "${tx.id}".contains(s, true) },
- "Input" to { tx, s -> tx.inputs.resolved.any { it.state.data.contract.javaClass.simpleName.contains(s, true) } },
- "Output" to { tx, s -> tx.outputs.any { it.state.data.contract.javaClass.simpleName.contains(s, true) } },
+ "Input" to { tx, s -> tx.inputs.resolved.any { it.state.contract.contains(s, true) } },
+ "Output" to { tx, s -> tx.outputs.any { it.state.contract.contains(s, true) } },
"Input Party" to { tx, s -> tx.inputParties.any { it.any { it.value?.name?.organisation?.contains(s, true) ?: false } } },
"Output Party" to { tx, s -> tx.outputParties.any { it.any { it.value?.name?.organisation?.contains(s, true) ?: false } } },
"Command Type" to { tx, s -> tx.commandTypes.any { it.simpleName.contains(s, true) } }
@@ -207,7 +207,7 @@ class TransactionViewer : CordaView("Transactions") {
}
private fun ObservableList>.getParties() = map { it.state.data.participants.map { it.owningKey.toKnownParty() } }
- private fun ObservableList>.toText() = map { it.contract().javaClass.simpleName }.groupBy { it }.map { "${it.key} (${it.value.size})" }.joinToString()
+ private fun ObservableList>.toText() = map { it.contract() }.groupBy { it }.map { "${it.key} (${it.value.size})" }.joinToString()
private class TransactionWidget : BorderPane() {
private val partiallyResolvedTransactions by observableListReadOnly(TransactionDataModel::partiallyResolvedTransactions)
@@ -299,7 +299,7 @@ class TransactionViewer : CordaView("Transactions") {
}
}
- private fun StateAndRef.contract() = this.state.data.contract
+ private fun StateAndRef.contract() = this.state.contract
}
diff --git a/verifier/src/integration-test/kotlin/net/corda/verifier/GeneratedLedger.kt b/verifier/src/integration-test/kotlin/net/corda/verifier/GeneratedLedger.kt
index 21f576a7c3..86359414d8 100644
--- a/verifier/src/integration-test/kotlin/net/corda/verifier/GeneratedLedger.kt
+++ b/verifier/src/integration-test/kotlin/net/corda/verifier/GeneratedLedger.kt
@@ -11,6 +11,7 @@ import net.corda.core.identity.Party
import net.corda.core.internal.AbstractAttachment
import net.corda.core.transactions.LedgerTransaction
import net.corda.core.transactions.WireTransaction
+import net.corda.testing.contracts.DUMMY_PROGRAM_ID
import net.corda.core.utilities.getX500Name
import net.corda.testing.contracts.DummyContract
import java.math.BigInteger
@@ -62,7 +63,7 @@ data class GeneratedLedger(
Generator.sequence(
outputs.map { output ->
pickOneOrMaybeNew(identities, partyGenerator).map { notary ->
- TransactionState(output, notary, null)
+ TransactionState(output, DUMMY_PROGRAM_ID, notary, null)
}
}
)
@@ -127,7 +128,7 @@ data class GeneratedLedger(
fun regularTransactionGenerator(inputNotary: Party, inputsToChooseFrom: List>): Generator> {
val outputsGen = outputsGenerator.map { outputs ->
outputs.map { output ->
- TransactionState(output, inputNotary, null)
+ TransactionState(output, DUMMY_PROGRAM_ID, inputNotary, null)
}
}
val inputsGen = Generator.sampleBernoulli(inputsToChooseFrom)
@@ -180,9 +181,7 @@ data class GeneratedLedger(
data class GeneratedState(
val nonce: Long,
override val participants: List
-) : ContractState {
- override val contract = DummyContract()
-}
+) : ContractState
class GeneratedAttachment(bytes: ByteArray) : AbstractAttachment({ bytes }) {
override val id = bytes.sha256()