From 544e19e277b8bb1c89bee938861e89b02cd14bd3 Mon Sep 17 00:00:00 2001 From: Andrzej Cichocki Date: Mon, 11 Dec 2017 11:44:01 +0000 Subject: [PATCH] CORDA-654 Remove key constants from NodeTestUtils (#2205) * DUMMY_NOTARY was hiding in a couple more places --- .../core/crypto/PartialMerkleTreeTest.kt | 4 +- .../TransactionEncumbranceTests.kt | 22 +++++------ .../tutorial/testdsl/CommercialPaperTest.java | 22 ++++++----- .../docs/tutorial/testdsl/TutorialTestDSL.kt | 23 ++++++------ .../corda/finance/contracts/universal/Cap.kt | 4 +- .../contracts/asset/CashTestsJava.java | 8 +++- .../finance/contracts/CommercialPaperTests.kt | 8 +++- .../finance/contracts/asset/CashTests.kt | 6 ++- .../contracts/asset/ObligationTests.kt | 37 +++++++++++-------- .../node/messaging/TwoPartyTradeFlowTests.kt | 17 ++++----- .../kotlin/net/corda/irs/contract/IRSTests.kt | 12 ++++-- .../kotlin/net/corda/testing/NodeTestUtils.kt | 23 +++++------- .../net/corda/testing/LedgerDSLInterpreter.kt | 23 +++++++----- .../main/kotlin/net/corda/testing/TestDSL.kt | 22 ++++------- .../testing/TransactionDSLInterpreter.kt | 18 +++++---- 15 files changed, 138 insertions(+), 111 deletions(-) diff --git a/core/src/test/kotlin/net/corda/core/crypto/PartialMerkleTreeTest.kt b/core/src/test/kotlin/net/corda/core/crypto/PartialMerkleTreeTest.kt index c0346e30fd..b1d768b2cb 100644 --- a/core/src/test/kotlin/net/corda/core/crypto/PartialMerkleTreeTest.kt +++ b/core/src/test/kotlin/net/corda/core/crypto/PartialMerkleTreeTest.kt @@ -10,6 +10,8 @@ import net.corda.finance.DOLLARS import net.corda.finance.`issued by` import net.corda.finance.contracts.asset.Cash import net.corda.testing.* +import net.corda.testing.node.MockServices +import net.corda.testing.node.makeTestIdentityService import org.junit.Before import org.junit.Rule import org.junit.Test @@ -35,7 +37,7 @@ class PartialMerkleTreeTest { hashed = nodes.map { it.serialize().sha256() } expectedRoot = MerkleTree.getMerkleTree(hashed.toMutableList() + listOf(zeroHash, zeroHash)).hash merkleTree = MerkleTree.getMerkleTree(hashed) - testLedger = ledger { + testLedger = MockServices(makeTestIdentityService(listOf(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, DUMMY_CASH_ISSUER_IDENTITY, DUMMY_NOTARY_IDENTITY)), MEGA_CORP.name).ledger(DUMMY_NOTARY) { unverifiedTransaction { attachments(Cash.PROGRAM_ID) output(Cash.PROGRAM_ID, "MEGA_CORP cash", diff --git a/core/src/test/kotlin/net/corda/core/transactions/TransactionEncumbranceTests.kt b/core/src/test/kotlin/net/corda/core/transactions/TransactionEncumbranceTests.kt index 4cb955faa5..630933cdcc 100644 --- a/core/src/test/kotlin/net/corda/core/transactions/TransactionEncumbranceTests.kt +++ b/core/src/test/kotlin/net/corda/core/transactions/TransactionEncumbranceTests.kt @@ -7,10 +7,9 @@ import net.corda.core.identity.AbstractParty import net.corda.finance.DOLLARS import net.corda.finance.`issued by` import net.corda.finance.contracts.asset.Cash -import net.corda.testing.MEGA_CORP -import net.corda.testing.MINI_CORP -import net.corda.testing.SerializationEnvironmentRule -import net.corda.testing.ledger +import net.corda.testing.* +import net.corda.testing.node.MockServices +import net.corda.testing.node.makeTestIdentityService import org.junit.Rule import org.junit.Test import java.time.Instant @@ -50,9 +49,10 @@ class TransactionEncumbranceTests { } } + private val ledgerServices = MockServices(makeTestIdentityService(listOf(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, DUMMY_CASH_ISSUER_IDENTITY, DUMMY_NOTARY_IDENTITY)), MEGA_CORP.name) @Test fun `state can be encumbered`() { - ledger { + ledgerServices.ledger(DUMMY_NOTARY) { transaction { attachments(Cash.PROGRAM_ID, TEST_TIMELOCK_ID) input(Cash.PROGRAM_ID, state) @@ -66,7 +66,7 @@ class TransactionEncumbranceTests { @Test fun `state can transition if encumbrance rules are met`() { - ledger { + ledgerServices.ledger(DUMMY_NOTARY) { unverifiedTransaction { attachments(Cash.PROGRAM_ID, TEST_TIMELOCK_ID) output(Cash.PROGRAM_ID, "state encumbered by 5pm time-lock", state) @@ -87,7 +87,7 @@ class TransactionEncumbranceTests { @Test fun `state cannot transition if the encumbrance contract fails to verify`() { - ledger { + ledgerServices.ledger(DUMMY_NOTARY) { unverifiedTransaction { attachments(Cash.PROGRAM_ID, TEST_TIMELOCK_ID) output(Cash.PROGRAM_ID, "state encumbered by 5pm time-lock", state) @@ -108,7 +108,7 @@ class TransactionEncumbranceTests { @Test fun `state must be consumed along with its encumbrance`() { - ledger { + ledgerServices.ledger(DUMMY_NOTARY) { unverifiedTransaction { attachments(Cash.PROGRAM_ID, TEST_TIMELOCK_ID) output(Cash.PROGRAM_ID, "state encumbered by 5pm time-lock", encumbrance = 1, contractState = state) @@ -127,7 +127,7 @@ class TransactionEncumbranceTests { @Test fun `state cannot be encumbered by itself`() { - ledger { + ledgerServices.ledger(DUMMY_NOTARY) { transaction { attachments(Cash.PROGRAM_ID) input(Cash.PROGRAM_ID, state) @@ -140,7 +140,7 @@ class TransactionEncumbranceTests { @Test fun `encumbrance state index must be valid`() { - ledger { + ledgerServices.ledger(DUMMY_NOTARY) { transaction { attachments(Cash.PROGRAM_ID, TEST_TIMELOCK_ID) input(Cash.PROGRAM_ID, state) @@ -154,7 +154,7 @@ class TransactionEncumbranceTests { @Test fun `correct encumbrance state must be provided`() { - ledger { + ledgerServices.ledger(DUMMY_NOTARY) { unverifiedTransaction { attachments(Cash.PROGRAM_ID, TEST_TIMELOCK_ID) output(Cash.PROGRAM_ID, "state encumbered by some other state", encumbrance = 1, contractState = state) diff --git a/docs/source/example-code/src/main/java/net/corda/docs/java/tutorial/testdsl/CommercialPaperTest.java b/docs/source/example-code/src/main/java/net/corda/docs/java/tutorial/testdsl/CommercialPaperTest.java index 3a302d09e0..a064678504 100644 --- a/docs/source/example-code/src/main/java/net/corda/docs/java/tutorial/testdsl/CommercialPaperTest.java +++ b/docs/source/example-code/src/main/java/net/corda/docs/java/tutorial/testdsl/CommercialPaperTest.java @@ -7,10 +7,12 @@ import net.corda.finance.contracts.ICommercialPaperState; import net.corda.finance.contracts.JavaCommercialPaper; import net.corda.finance.contracts.asset.Cash; import net.corda.testing.SerializationEnvironmentRule; +import net.corda.testing.node.MockServices; import org.junit.Rule; import org.junit.Test; import java.time.temporal.ChronoUnit; +import java.util.Arrays; import static net.corda.finance.Currencies.DOLLARS; import static net.corda.finance.Currencies.issuedBy; @@ -19,11 +21,13 @@ import static net.corda.testing.CoreTestUtils.*; import static net.corda.testing.NodeTestUtils.ledger; import static net.corda.testing.NodeTestUtils.transaction; import static net.corda.testing.TestConstants.*; +import static net.corda.testing.node.MockServicesKt.makeTestIdentityService; public class CommercialPaperTest { @Rule public final SerializationEnvironmentRule testSerialization = new SerializationEnvironmentRule(); private final OpaqueBytes defaultRef = new OpaqueBytes(new byte[]{123}); + private final MockServices ledgerServices = new MockServices(makeTestIdentityService(Arrays.asList(getMEGA_CORP_IDENTITY(), getMINI_CORP_IDENTITY(), getDUMMY_CASH_ISSUER_IDENTITY(), getDUMMY_NOTARY_IDENTITY())), getMEGA_CORP().getName()); // DOCSTART 1 private ICommercialPaperState getPaper() { @@ -40,7 +44,7 @@ public class CommercialPaperTest { @Test public void simpleCP() { ICommercialPaperState inState = getPaper(); - ledger(l -> { + ledger(ledgerServices, getDUMMY_NOTARY(), l -> { l.transaction(tx -> { tx.attachments(JCP_PROGRAM_ID); tx.input(JCP_PROGRAM_ID, inState); @@ -55,7 +59,7 @@ public class CommercialPaperTest { @Test public void simpleCPMove() { ICommercialPaperState inState = getPaper(); - ledger(l -> { + ledger(ledgerServices, getDUMMY_NOTARY(), l -> { l.transaction(tx -> { tx.input(JCP_PROGRAM_ID, inState); tx.command(getMEGA_CORP_PUBKEY(), new JavaCommercialPaper.Commands.Move()); @@ -71,7 +75,7 @@ public class CommercialPaperTest { @Test public void simpleCPMoveFails() { ICommercialPaperState inState = getPaper(); - ledger(l -> { + ledger(ledgerServices, getDUMMY_NOTARY(), l -> { l.transaction(tx -> { tx.input(JCP_PROGRAM_ID, inState); tx.command(getMEGA_CORP_PUBKEY(), new JavaCommercialPaper.Commands.Move()); @@ -87,7 +91,7 @@ public class CommercialPaperTest { @Test public void simpleCPMoveSuccess() { ICommercialPaperState inState = getPaper(); - ledger(l -> { + ledger(ledgerServices, getDUMMY_NOTARY(), l -> { l.transaction(tx -> { tx.input(JCP_PROGRAM_ID, inState); tx.command(getMEGA_CORP_PUBKEY(), new JavaCommercialPaper.Commands.Move()); @@ -104,7 +108,7 @@ public class CommercialPaperTest { // DOCSTART 6 @Test public void simpleIssuanceWithTweak() { - ledger(l -> { + ledger(ledgerServices, getDUMMY_NOTARY(), l -> { l.transaction(tx -> { tx.output(JCP_PROGRAM_ID, "paper", getPaper()); // Some CP is issued onto the ledger by MegaCorp. tx.attachments(JCP_PROGRAM_ID); @@ -125,7 +129,7 @@ public class CommercialPaperTest { // DOCSTART 7 @Test public void simpleIssuanceWithTweakTopLevelTx() { - transaction(tx -> { + transaction(ledgerServices, getDUMMY_NOTARY(), tx -> { tx.output(JCP_PROGRAM_ID, "paper", getPaper()); // Some CP is issued onto the ledger by MegaCorp. tx.attachments(JCP_PROGRAM_ID); tx.tweak(tw -> { @@ -144,7 +148,7 @@ public class CommercialPaperTest { @Test public void chainCommercialPaper() { PartyAndReference issuer = getMEGA_CORP().ref(defaultRef); - ledger(l -> { + ledger(ledgerServices, getDUMMY_NOTARY(), l -> { l.unverifiedTransaction(tx -> { tx.output(Cash.PROGRAM_ID, "alice's $900", new Cash.State(issuedBy(DOLLARS(900), issuer), getALICE())); @@ -180,7 +184,7 @@ public class CommercialPaperTest { @Test public void chainCommercialPaperDoubleSpend() { PartyAndReference issuer = getMEGA_CORP().ref(defaultRef); - ledger(l -> { + ledger(ledgerServices, getDUMMY_NOTARY(), l -> { l.unverifiedTransaction(tx -> { tx.output(Cash.PROGRAM_ID, "alice's $900", new Cash.State(issuedBy(DOLLARS(900), issuer), getALICE())); @@ -226,7 +230,7 @@ public class CommercialPaperTest { @Test public void chainCommercialPaperTweak() { PartyAndReference issuer = getMEGA_CORP().ref(defaultRef); - ledger(l -> { + ledger(ledgerServices, getDUMMY_NOTARY(), l -> { l.unverifiedTransaction(tx -> { tx.output(Cash.PROGRAM_ID, "alice's $900", new Cash.State(issuedBy(DOLLARS(900), issuer), getALICE())); diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/tutorial/testdsl/TutorialTestDSL.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/tutorial/testdsl/TutorialTestDSL.kt index cfde0084a1..d1da1b3c56 100644 --- a/docs/source/example-code/src/main/kotlin/net/corda/docs/tutorial/testdsl/TutorialTestDSL.kt +++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/tutorial/testdsl/TutorialTestDSL.kt @@ -9,6 +9,8 @@ import net.corda.finance.contracts.ICommercialPaperState import net.corda.finance.contracts.asset.CASH import net.corda.finance.contracts.asset.Cash import net.corda.testing.* +import net.corda.testing.node.MockServices +import net.corda.testing.node.makeTestIdentityService import org.junit.Rule import org.junit.Test @@ -16,7 +18,7 @@ class CommercialPaperTest { @Rule @JvmField val testSerialization = SerializationEnvironmentRule() - + private val ledgerServices = MockServices(makeTestIdentityService(listOf(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, DUMMY_CASH_ISSUER_IDENTITY, DUMMY_NOTARY_IDENTITY)), MEGA_CORP.name) // DOCSTART 1 fun getPaper(): ICommercialPaperState = CommercialPaper.State( issuance = MEGA_CORP.ref(123), @@ -30,7 +32,7 @@ class CommercialPaperTest { @Test fun simpleCP() { val inState = getPaper() - ledger { + ledgerServices.ledger(DUMMY_NOTARY) { transaction { attachments(CP_PROGRAM_ID) input(CP_PROGRAM_ID, inState) @@ -44,7 +46,7 @@ class CommercialPaperTest { @Test fun simpleCPMove() { val inState = getPaper() - ledger { + ledgerServices.ledger(DUMMY_NOTARY) { transaction { input(CP_PROGRAM_ID, inState) command(MEGA_CORP_PUBKEY, CommercialPaper.Commands.Move()) @@ -59,7 +61,7 @@ class CommercialPaperTest { @Test fun simpleCPMoveFails() { val inState = getPaper() - ledger { + ledgerServices.ledger(DUMMY_NOTARY) { transaction { input(CP_PROGRAM_ID, inState) command(MEGA_CORP_PUBKEY, CommercialPaper.Commands.Move()) @@ -74,7 +76,7 @@ class CommercialPaperTest { @Test fun simpleCPMoveSuccess() { val inState = getPaper() - ledger { + ledgerServices.ledger(DUMMY_NOTARY) { transaction { input(CP_PROGRAM_ID, inState) command(MEGA_CORP_PUBKEY, CommercialPaper.Commands.Move()) @@ -90,7 +92,7 @@ class CommercialPaperTest { // DOCSTART 6 @Test fun `simple issuance with tweak`() { - ledger { + ledgerServices.ledger(DUMMY_NOTARY) { transaction { output(CP_PROGRAM_ID, "paper", getPaper()) // Some CP is issued onto the ledger by MegaCorp. attachments(CP_PROGRAM_ID) @@ -111,7 +113,7 @@ class CommercialPaperTest { // DOCSTART 7 @Test fun `simple issuance with tweak and top level transaction`() { - transaction { + ledgerServices.transaction(DUMMY_NOTARY) { output(CP_PROGRAM_ID, "paper", getPaper()) // Some CP is issued onto the ledger by MegaCorp. attachments(CP_PROGRAM_ID) tweak { @@ -131,8 +133,7 @@ class CommercialPaperTest { @Test fun `chain commercial paper`() { val issuer = MEGA_CORP.ref(123) - - ledger { + ledgerServices.ledger(DUMMY_NOTARY) { unverifiedTransaction { attachments(Cash.PROGRAM_ID) output(Cash.PROGRAM_ID, "alice's $900", 900.DOLLARS.CASH issuedBy issuer ownedBy ALICE) @@ -165,7 +166,7 @@ class CommercialPaperTest { @Test fun `chain commercial paper double spend`() { val issuer = MEGA_CORP.ref(123) - ledger { + ledgerServices.ledger(DUMMY_NOTARY) { unverifiedTransaction { attachments(Cash.PROGRAM_ID) output(Cash.PROGRAM_ID, "alice's $900", 900.DOLLARS.CASH issuedBy issuer ownedBy ALICE) @@ -207,7 +208,7 @@ class CommercialPaperTest { @Test fun `chain commercial tweak`() { val issuer = MEGA_CORP.ref(123) - ledger { + ledgerServices.ledger(DUMMY_NOTARY) { unverifiedTransaction { attachments(Cash.PROGRAM_ID) output(Cash.PROGRAM_ID, "alice's $900", 900.DOLLARS.CASH issuedBy issuer ownedBy ALICE) diff --git a/experimental/src/test/kotlin/net/corda/finance/contracts/universal/Cap.kt b/experimental/src/test/kotlin/net/corda/finance/contracts/universal/Cap.kt index 9d683682a6..7ecbfbe906 100644 --- a/experimental/src/test/kotlin/net/corda/finance/contracts/universal/Cap.kt +++ b/experimental/src/test/kotlin/net/corda/finance/contracts/universal/Cap.kt @@ -5,6 +5,8 @@ import net.corda.finance.contracts.FixOf import net.corda.finance.contracts.Frequency import net.corda.finance.contracts.Tenor import net.corda.testing.* +import net.corda.testing.node.MockServices +import net.corda.testing.node.makeTestIdentityService import org.junit.Ignore import org.junit.Rule import org.junit.Test @@ -12,7 +14,7 @@ import java.time.Instant import java.time.LocalDate fun transaction(script: TransactionDSL.() -> EnforceVerifyOrFail) = run { - net.corda.testing.transaction(cordappPackages = listOf("net.corda.finance.contracts.universal"), dsl = script) + MockServices(listOf("net.corda.finance.contracts.universal"), makeTestIdentityService(listOf(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, DUMMY_CASH_ISSUER_IDENTITY, DUMMY_NOTARY_IDENTITY)), MEGA_CORP.name).transaction(DUMMY_NOTARY, script) } class Cap { 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 bfff1987d1..4e010df5b3 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 @@ -5,13 +5,19 @@ import net.corda.core.identity.AnonymousParty; import net.corda.core.utilities.OpaqueBytes; import net.corda.testing.DummyCommandData; import net.corda.testing.SerializationEnvironmentRule; +import net.corda.testing.node.MockServices; import org.junit.Rule; import org.junit.Test; +import java.util.Arrays; + import static net.corda.finance.Currencies.DOLLARS; import static net.corda.finance.Currencies.issuedBy; import static net.corda.testing.CoreTestUtils.*; import static net.corda.testing.NodeTestUtils.transaction; +import static net.corda.testing.TestConstants.getDUMMY_NOTARY; +import static net.corda.testing.TestConstants.getDUMMY_NOTARY_IDENTITY; +import static net.corda.testing.node.MockServicesKt.makeTestIdentityService; /** * This is an incomplete Java replica of CashTests.kt to show how to use the Java test DSL @@ -26,7 +32,7 @@ public class CashTestsJava { @Test public void trivial() { - transaction(tx -> { + transaction(new MockServices(makeTestIdentityService(Arrays.asList(getMEGA_CORP_IDENTITY(), getMINI_CORP_IDENTITY(), getDUMMY_CASH_ISSUER_IDENTITY(), getDUMMY_NOTARY_IDENTITY())), getMEGA_CORP().getName()), getDUMMY_NOTARY(), tx -> { tx.attachment(Cash.PROGRAM_ID); tx.input(Cash.PROGRAM_ID, inState); 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 fc02955c6a..31755d5246 100644 --- a/finance/src/test/kotlin/net/corda/finance/contracts/CommercialPaperTests.kt +++ b/finance/src/test/kotlin/net/corda/finance/contracts/CommercialPaperTests.kt @@ -92,11 +92,11 @@ class CommercialPaperTestsGeneric { @JvmField val testSerialization = SerializationEnvironmentRule() val issuer = MEGA_CORP.ref(123) - + private val ledgerServices = MockServices(makeTestIdentityService(listOf(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, DUMMY_CASH_ISSUER_IDENTITY, DUMMY_NOTARY_IDENTITY)), MEGA_CORP.name) @Test fun `trade lifecycle test`() { val someProfits = 1200.DOLLARS `issued by` issuer - ledger { + ledgerServices.ledger(DUMMY_NOTARY) { unverifiedTransaction { attachment(Cash.PROGRAM_ID) output(Cash.PROGRAM_ID, "alice's $900", 900.DOLLARS.CASH issuedBy issuer ownedBy ALICE) @@ -162,6 +162,10 @@ class CommercialPaperTestsGeneric { } } + private fun transaction(script: TransactionDSL.() -> EnforceVerifyOrFail) = run { + ledgerServices.transaction(DUMMY_NOTARY, script) + } + @Test fun `key mismatch at issue`() { transaction { 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 bb027e880c..23e223fd4c 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 @@ -113,6 +113,10 @@ class CashTests { database.close() } + private fun transaction(script: TransactionDSL.() -> EnforceVerifyOrFail) = run { + MockServices(makeTestIdentityService(listOf(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, DUMMY_CASH_ISSUER_IDENTITY, DUMMY_NOTARY_IDENTITY)), MEGA_CORP.name).transaction(DUMMY_NOTARY, script) + } + @Test fun trivial() { transaction { @@ -779,7 +783,7 @@ class CashTests { val mockService = MockServices(listOf("net.corda.finance.contracts.asset"), rigorousMock().also { doReturn(MEGA_CORP).whenever(it).partyFromKey(MEGA_CORP_PUBKEY) }, MEGA_CORP.name, MEGA_CORP_KEY) - ledger(mockService) { + mockService.ledger(DUMMY_NOTARY) { unverifiedTransaction { attachment(Cash.PROGRAM_ID) output(Cash.PROGRAM_ID, "MEGA_CORP cash", 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 207955b0dd..dec5493225 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 @@ -22,6 +22,7 @@ import net.corda.testing.* import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyState import net.corda.testing.node.MockServices +import net.corda.testing.node.makeTestIdentityService import org.junit.Rule import org.junit.Test import java.time.Instant @@ -61,7 +62,7 @@ class ObligationTests { doReturn(null).whenever(it).partyFromKey(BOB_PUBKEY) doReturn(MEGA_CORP).whenever(it).partyFromKey(MEGA_CORP_PUBKEY) }, MEGA_CORP.name) - + private val ledgerServices get() = MockServices(makeTestIdentityService(listOf(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, DUMMY_CASH_ISSUER_IDENTITY, DUMMY_NOTARY_IDENTITY)), MEGA_CORP.name) private fun cashObligationTestRoots( group: LedgerDSL ) = group.apply { @@ -74,6 +75,10 @@ class ObligationTests { } } + private fun transaction(script: TransactionDSL.() -> EnforceVerifyOrFail) = run { + ledgerServices.transaction(DUMMY_NOTARY, script) + } + @Test fun trivial() { transaction { @@ -347,7 +352,7 @@ class ObligationTests { @Test fun `close-out netting`() { // Try netting out two obligations - ledger(mockService) { + mockService.ledger(DUMMY_NOTARY) { cashObligationTestRoots(this) transaction("Issuance") { attachments(Obligation.PROGRAM_ID) @@ -363,7 +368,7 @@ class ObligationTests { // Try netting out two obligations, with the third uninvolved obligation left // as-is - ledger(mockService) { + mockService.ledger(DUMMY_NOTARY) { cashObligationTestRoots(this) transaction("Issuance") { attachments(Obligation.PROGRAM_ID) @@ -379,7 +384,7 @@ class ObligationTests { } // Try having outputs mis-match the inputs - ledger { + ledgerServices.ledger(DUMMY_NOTARY) { cashObligationTestRoots(this) transaction("Issuance") { attachments(Obligation.PROGRAM_ID) @@ -393,7 +398,7 @@ class ObligationTests { } // Have the wrong signature on the transaction - ledger { + ledgerServices.ledger(DUMMY_NOTARY) { cashObligationTestRoots(this) transaction("Issuance") { attachments(Obligation.PROGRAM_ID) @@ -409,7 +414,7 @@ class ObligationTests { @Test fun `payment netting`() { // Try netting out two obligations - ledger(mockService) { + mockService.ledger(DUMMY_NOTARY) { cashObligationTestRoots(this) transaction("Issuance") { attachments(Obligation.PROGRAM_ID) @@ -424,7 +429,7 @@ class ObligationTests { // Try netting out two obligations, but only provide one signature. Unlike close-out netting, we need both // signatures for payment netting - ledger { + ledgerServices.ledger(DUMMY_NOTARY) { cashObligationTestRoots(this) transaction("Issuance") { attachments(Obligation.PROGRAM_ID) @@ -437,7 +442,7 @@ class ObligationTests { } // Multilateral netting, A -> B -> C which can net down to A -> C - ledger(mockService) { + mockService.ledger(DUMMY_NOTARY) { cashObligationTestRoots(this) transaction("Issuance") { attachments(Obligation.PROGRAM_ID) @@ -452,7 +457,7 @@ class ObligationTests { } // Multilateral netting without the key of the receiving party - ledger(mockService) { + mockService.ledger(DUMMY_NOTARY) { cashObligationTestRoots(this) transaction("Issuance") { attachments(Obligation.PROGRAM_ID) @@ -469,7 +474,7 @@ class ObligationTests { @Test fun `cash settlement`() { // Try settling an obligation - ledger { + ledgerServices.ledger(DUMMY_NOTARY) { cashObligationTestRoots(this) transaction("Settlement") { attachments(Obligation.PROGRAM_ID) @@ -485,7 +490,7 @@ class ObligationTests { // Try partial settling of an obligation val halfAMillionDollars = 500000.DOLLARS `issued by` defaultIssuer - ledger { + ledgerServices.ledger(DUMMY_NOTARY) { transaction("Settlement") { attachments(Obligation.PROGRAM_ID, Cash.PROGRAM_ID) input(Obligation.PROGRAM_ID, oneMillionDollars.OBLIGATION between Pair(ALICE, BOB)) @@ -501,7 +506,7 @@ class ObligationTests { // Make sure we can't settle an obligation that's defaulted val defaultedObligation: Obligation.State = (oneMillionDollars.OBLIGATION between Pair(ALICE, BOB)).copy(lifecycle = Lifecycle.DEFAULTED) - ledger { + ledgerServices.ledger(DUMMY_NOTARY) { transaction("Settlement") { attachments(Obligation.PROGRAM_ID, Cash.PROGRAM_ID) input(Obligation.PROGRAM_ID, defaultedObligation) // Alice's defaulted $1,000,000 obligation to Bob @@ -514,7 +519,7 @@ class ObligationTests { } // Make sure settlement amount must match the amount leaving the ledger - ledger { + ledgerServices.ledger(DUMMY_NOTARY) { cashObligationTestRoots(this) transaction("Settlement") { attachments(Obligation.PROGRAM_ID) @@ -538,7 +543,7 @@ class ObligationTests { val oneUnitFcojObligation = Obligation.State(Obligation.Lifecycle.NORMAL, ALICE, obligationDef, oneUnitFcoj.quantity, NULL_PARTY) // Try settling a simple commodity obligation - ledger { + ledgerServices.ledger(DUMMY_NOTARY) { unverifiedTransaction { attachments(Obligation.PROGRAM_ID) output(Obligation.PROGRAM_ID, "Alice's 1 FCOJ obligation to Bob", oneUnitFcojObligation between Pair(ALICE, BOB)) @@ -560,7 +565,7 @@ class ObligationTests { @Test fun `payment default`() { // Try defaulting an obligation without a time-window. - ledger { + ledgerServices.ledger(DUMMY_NOTARY) { cashObligationTestRoots(this) transaction("Settlement") { attachments(Obligation.PROGRAM_ID) @@ -584,7 +589,7 @@ class ObligationTests { } // Try defaulting an obligation that is now in the past - ledger { + ledgerServices.ledger(DUMMY_NOTARY) { transaction { attachments(Obligation.PROGRAM_ID) input(Obligation.PROGRAM_ID, oneMillionDollars.OBLIGATION between Pair(ALICE, BOB) `at` pastTestTime) diff --git a/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt b/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt index 0daa972cc2..b311425257 100644 --- a/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt +++ b/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt @@ -94,7 +94,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) { // allow interruption half way through. mockNet = MockNetwork(threadPerNode = true, cordappPackages = cordappPackages) val ledgerIdentityService = rigorousMock() - ledger(MockServices(cordappPackages, ledgerIdentityService, MEGA_CORP.name)) { + MockServices(cordappPackages, ledgerIdentityService, MEGA_CORP.name).ledger(DUMMY_NOTARY) { val notaryNode = mockNet.defaultNotaryNode val aliceNode = mockNet.createPartyNode(ALICE_NAME) val bobNode = mockNet.createPartyNode(BOB_NAME) @@ -146,7 +146,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) { fun `trade cash for commercial paper fails using soft locking`() { mockNet = MockNetwork(threadPerNode = true, cordappPackages = cordappPackages) val ledgerIdentityService = rigorousMock() - ledger(MockServices(cordappPackages, ledgerIdentityService, MEGA_CORP.name)) { + MockServices(cordappPackages, ledgerIdentityService, MEGA_CORP.name).ledger(DUMMY_NOTARY) { val notaryNode = mockNet.defaultNotaryNode val aliceNode = mockNet.createPartyNode(ALICE_NAME) val bobNode = mockNet.createPartyNode(BOB_NAME) @@ -204,7 +204,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) { fun `shutdown and restore`() { mockNet = MockNetwork(cordappPackages = cordappPackages) val ledgerIdentityService = rigorousMock() - ledger(MockServices(cordappPackages, ledgerIdentityService, MEGA_CORP.name)) { + MockServices(cordappPackages, ledgerIdentityService, MEGA_CORP.name).ledger(DUMMY_NOTARY) { val notaryNode = mockNet.defaultNotaryNode val aliceNode = mockNet.createPartyNode(ALICE_NAME) var bobNode = mockNet.createPartyNode(BOB_NAME) @@ -325,9 +325,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) { val bob = bobNode.info.singleIdentity() val bank = bankNode.info.singleIdentity() val issuer = bank.ref(1, 2, 3) - - ledger(aliceNode.services) { - + aliceNode.services.ledger(DUMMY_NOTARY) { // Insert a prospectus type attachment into the commercial paper transaction. val stream = ByteArrayOutputStream() JarOutputStream(stream).use { @@ -431,8 +429,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) { val bank: Party = bankNode.info.singleIdentity() val bob = bobNode.info.singleIdentity() val issuer = bank.ref(1, 2, 3) - - ledger(aliceNode.services) { + aliceNode.services.ledger(DUMMY_NOTARY) { // Insert a prospectus type attachment into the commercial paper transaction. val stream = ByteArrayOutputStream() JarOutputStream(stream).use { @@ -501,7 +498,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) { fun `dependency with error on buyer side`() { mockNet = MockNetwork(cordappPackages = cordappPackages) val ledgerIdentityService = rigorousMock() - ledger(MockServices(cordappPackages, ledgerIdentityService, MEGA_CORP.name)) { + MockServices(cordappPackages, ledgerIdentityService, MEGA_CORP.name).ledger(DUMMY_NOTARY) { runWithError(ledgerIdentityService, true, false, "at least one cash input") } } @@ -510,7 +507,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) { fun `dependency with error on seller side`() { mockNet = MockNetwork(cordappPackages = cordappPackages) val ledgerIdentityService = rigorousMock() - ledger(MockServices(cordappPackages, ledgerIdentityService, MEGA_CORP.name)) { + MockServices(cordappPackages, ledgerIdentityService, MEGA_CORP.name).ledger(DUMMY_NOTARY) { runWithError(ledgerIdentityService, false, true, "Issuances have a time-window") } } diff --git a/samples/irs-demo/cordapp/src/test/kotlin/net/corda/irs/contract/IRSTests.kt b/samples/irs-demo/cordapp/src/test/kotlin/net/corda/irs/contract/IRSTests.kt index 9dd3180bd8..b512beba0d 100644 --- a/samples/irs-demo/cordapp/src/test/kotlin/net/corda/irs/contract/IRSTests.kt +++ b/samples/irs-demo/cordapp/src/test/kotlin/net/corda/irs/contract/IRSTests.kt @@ -26,6 +26,7 @@ import net.corda.finance.contracts.Tenor import net.corda.node.services.api.IdentityServiceInternal import net.corda.testing.* import net.corda.testing.node.MockServices +import net.corda.testing.node.makeTestIdentityService import org.junit.Rule import org.junit.Test import java.math.BigDecimal @@ -222,6 +223,7 @@ class IRSTests { private val megaCorpServices = MockServices(listOf("net.corda.irs.contract"), rigorousMock(), MEGA_CORP.name, MEGA_CORP_KEY) private val miniCorpServices = MockServices(listOf("net.corda.irs.contract"), rigorousMock(), MINI_CORP.name, MINI_CORP_KEY) private val notaryServices = MockServices(listOf("net.corda.irs.contract"), rigorousMock(), DUMMY_NOTARY.name, DUMMY_NOTARY_KEY) + private val ledgerServices get() = MockServices(makeTestIdentityService(listOf(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, DUMMY_CASH_ISSUER_IDENTITY, DUMMY_NOTARY_IDENTITY)), MEGA_CORP.name) @Test fun ok() { trade().verifies() @@ -391,8 +393,7 @@ class IRSTests { val ld = LocalDate.of(2016, 3, 8) val bd = BigDecimal("0.0063518") - - return ledger { + return ledgerServices.ledger(DUMMY_NOTARY) { transaction("Agreement") { attachments(IRS_PROGRAM_ID) output(IRS_PROGRAM_ID, "irs post agreement", singleIRS()) @@ -419,6 +420,10 @@ class IRSTests { } } + private fun transaction(script: TransactionDSL.() -> EnforceVerifyOrFail) = run { + ledgerServices.transaction(DUMMY_NOTARY, script) + } + @Test fun `ensure failure occurs when there are inbound states for an agreement command`() { val irs = singleIRS() @@ -656,8 +661,7 @@ class IRSTests { val bd1 = BigDecimal("0.0063518") val irs = singleIRS() - - return ledger { + return ledgerServices.ledger(DUMMY_NOTARY) { transaction("Agreement") { attachments(IRS_PROGRAM_ID) output(IRS_PROGRAM_ID, "irs post agreement1", diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/NodeTestUtils.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/NodeTestUtils.kt index 85fa0eef1f..b2544b3245 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/NodeTestUtils.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/NodeTestUtils.kt @@ -10,6 +10,7 @@ import net.corda.core.context.InvocationContext import net.corda.core.context.Origin import net.corda.core.flows.FlowLogic import net.corda.core.identity.CordaX500Name +import net.corda.core.identity.Party import net.corda.core.internal.FlowStateMachine import net.corda.core.node.ServiceHub import net.corda.core.transactions.TransactionBuilder @@ -21,21 +22,17 @@ import net.corda.nodeapi.internal.persistence.DatabaseConfig import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.config.VerifierType import net.corda.nodeapi.internal.config.User -import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties -import net.corda.testing.node.makeTestIdentityService import java.nio.file.Path /** - * Creates and tests a ledger built by the passed in dsl. The provided services can be customised, otherwise a default - * of a freshly built [MockServices] is used. + * Creates and tests a ledger built by the passed in dsl. */ -@JvmOverloads -fun ledger( - services: ServiceHub = MockServices(makeTestIdentityService(listOf(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, DUMMY_CASH_ISSUER_IDENTITY, DUMMY_NOTARY_IDENTITY)), MEGA_CORP.name), +fun ServiceHub.ledger( + notary: Party, dsl: LedgerDSL.() -> Unit ): LedgerDSL { - return LedgerDSL(TestLedgerDSLInterpreter(services)).also { dsl(it) } + return LedgerDSL(TestLedgerDSLInterpreter(this), notary).apply(dsl) } /** @@ -43,13 +40,11 @@ fun ledger( * * @see LedgerDSLInterpreter._transaction */ -@JvmOverloads -fun transaction( - transactionBuilder: TransactionBuilder = TransactionBuilder(notary = DUMMY_NOTARY), - cordappPackages: List = emptyList(), +fun ServiceHub.transaction( + notary: Party, dsl: TransactionDSL.() -> EnforceVerifyOrFail -) = ledger(services = MockServices(cordappPackages, makeTestIdentityService(listOf(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, DUMMY_CASH_ISSUER_IDENTITY, DUMMY_NOTARY_IDENTITY)), MEGA_CORP.name)) { - dsl(TransactionDSL(TestTransactionDSLInterpreter(this.interpreter, transactionBuilder))) +) = ledger(notary) { + dsl(TransactionDSL(TestTransactionDSLInterpreter(interpreter, TransactionBuilder(notary)), notary)) } fun testNodeConfiguration( diff --git a/testing/test-utils/src/main/kotlin/net/corda/testing/LedgerDSLInterpreter.kt b/testing/test-utils/src/main/kotlin/net/corda/testing/LedgerDSLInterpreter.kt index 9f4f829433..47d3f68b62 100644 --- a/testing/test-utils/src/main/kotlin/net/corda/testing/LedgerDSLInterpreter.kt +++ b/testing/test-utils/src/main/kotlin/net/corda/testing/LedgerDSLInterpreter.kt @@ -4,6 +4,8 @@ import net.corda.core.contracts.ContractState import net.corda.core.contracts.StateAndRef import net.corda.core.contracts.TransactionState import net.corda.core.crypto.SecureHash +import net.corda.core.identity.Party +import net.corda.core.internal.uncheckedCast import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.WireTransaction import java.io.InputStream @@ -14,7 +16,7 @@ import java.io.InputStream */ interface OutputStateLookup { /** - * Retrieves an output previously defined by [TransactionDSLInterpreter._output] with a label passed in. + * Retrieves an output previously defined by [TransactionDSLInterpreter.output] with a label passed in. * @param clazz The class object holding the type of the output state expected. * @param label The label of the to-be-retrieved output state. * @return The output [StateAndRef]. @@ -90,7 +92,7 @@ interface LedgerDSLInterpreter : Verifies, Ou * @return The final [WireTransaction] of the built transaction. */ fun _transaction(transactionLabel: String?, transactionBuilder: TransactionBuilder, - dsl: TransactionDSL.() -> EnforceVerifyOrFail): WireTransaction + dsl: T.() -> EnforceVerifyOrFail): WireTransaction /** * Creates and adds a transaction to the ledger that will not be verified by [verifies]. @@ -100,13 +102,13 @@ interface LedgerDSLInterpreter : Verifies, Ou * @return The final [WireTransaction] of the built transaction. */ fun _unverifiedTransaction(transactionLabel: String?, transactionBuilder: TransactionBuilder, - dsl: TransactionDSL.() -> Unit): WireTransaction + dsl: T.() -> Unit): WireTransaction /** * Creates a local scoped copy of the ledger. * @param dsl The ledger DSL to be interpreted using the copy. */ - fun tweak(dsl: LedgerDSL>.() -> Unit) + fun _tweak(dsl: LedgerDSLInterpreter.() -> Unit) /** * Adds an attachment to the ledger. @@ -123,24 +125,27 @@ interface LedgerDSLInterpreter : Verifies, Ou * functionality then first add your primitive to [LedgerDSLInterpreter] and then add the convenience defaults/extension * methods here. */ -class LedgerDSL>(val interpreter: L) : +class LedgerDSL>(val interpreter: L, private val notary: Party) : LedgerDSLInterpreter by interpreter { /** * Creates and adds a transaction to the ledger. */ @JvmOverloads - fun transaction(label: String? = null, transactionBuilder: TransactionBuilder = TransactionBuilder(notary = DUMMY_NOTARY), + fun transaction(label: String? = null, transactionBuilder: TransactionBuilder = TransactionBuilder(notary = notary), dsl: TransactionDSL.() -> EnforceVerifyOrFail) = - _transaction(label, transactionBuilder, dsl) + _transaction(label, transactionBuilder) { TransactionDSL(this, notary).dsl() } /** * Creates and adds a transaction to the ledger that will not be verified by [verifies]. */ @JvmOverloads - fun unverifiedTransaction(label: String? = null, transactionBuilder: TransactionBuilder = TransactionBuilder(notary = DUMMY_NOTARY), + fun unverifiedTransaction(label: String? = null, transactionBuilder: TransactionBuilder = TransactionBuilder(notary = notary), dsl: TransactionDSL.() -> Unit) = - _unverifiedTransaction(label, transactionBuilder, dsl) + _unverifiedTransaction(label, transactionBuilder) { TransactionDSL(this, notary).dsl() } + + /** Creates a local scoped copy of the ledger. */ + fun tweak(dsl: LedgerDSL.() -> Unit) = _tweak { LedgerDSL(uncheckedCast(this), notary).dsl() } /** * Retrieves an output previously defined by [TransactionDSLInterpreter._output] with a label passed in. 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 3167eb7a38..cf32668002 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 @@ -133,9 +133,7 @@ data class TestTransactionDSLInterpreter private constructor( transactionBuilder.setTimeWindow(data) } - override fun tweak( - dsl: TransactionDSL.() -> EnforceVerifyOrFail - ) = dsl(TransactionDSL(copy())) + override fun _tweak(dsl: TransactionDSLInterpreter.() -> EnforceVerifyOrFail) = copy().dsl() override fun _attachment(contractClassName: ContractClassName) { (services.cordappProvider as MockCordappProvider).addMockCordapp(contractClassName, services.attachments as MockAttachmentStorage) @@ -205,11 +203,9 @@ data class TestLedgerDSLInterpreter private constructor( private fun interpretTransactionDsl( transactionBuilder: TransactionBuilder, - dsl: TransactionDSL.() -> R + dsl: TestTransactionDSLInterpreter.() -> R ): TestTransactionDSLInterpreter { - val transactionInterpreter = TestTransactionDSLInterpreter(this, transactionBuilder) - dsl(TransactionDSL(transactionInterpreter)) - return transactionInterpreter + return TestTransactionDSLInterpreter(this, transactionBuilder).apply { dsl() } } fun transactionName(transactionHash: SecureHash): String? { @@ -227,7 +223,7 @@ data class TestLedgerDSLInterpreter private constructor( private fun recordTransactionWithTransactionMap( transactionLabel: String?, transactionBuilder: TransactionBuilder, - dsl: TransactionDSL.() -> R, + dsl: TestTransactionDSLInterpreter.() -> R, transactionMap: HashMap = HashMap(), /** If set to true, will add dummy components to [transactionBuilder] to make it valid. */ fillTransaction: Boolean = false @@ -267,19 +263,17 @@ data class TestLedgerDSLInterpreter private constructor( override fun _transaction( transactionLabel: String?, transactionBuilder: TransactionBuilder, - dsl: TransactionDSL.() -> EnforceVerifyOrFail + dsl: TestTransactionDSLInterpreter.() -> EnforceVerifyOrFail ) = recordTransactionWithTransactionMap(transactionLabel, transactionBuilder, dsl, transactionWithLocations) override fun _unverifiedTransaction( transactionLabel: String?, transactionBuilder: TransactionBuilder, - dsl: TransactionDSL.() -> Unit + dsl: TestTransactionDSLInterpreter.() -> Unit ) = recordTransactionWithTransactionMap(transactionLabel, transactionBuilder, dsl, nonVerifiedTransactionWithLocations, fillTransaction = true) - override fun tweak( - dsl: LedgerDSL>.() -> Unit) = - dsl(LedgerDSL(copy())) + override fun _tweak(dsl: LedgerDSLInterpreter.() -> Unit) = + copy().dsl() override fun attachment(attachment: InputStream): SecureHash { return services.attachments.importAttachment(attachment) 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 356323f613..8547a1f9a6 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 @@ -65,7 +65,7 @@ interface TransactionDSLInterpreter : Verifies, OutputStateLookup { * Creates a local scoped copy of the transaction. * @param dsl The transaction DSL to be interpreted using the copy. */ - fun tweak(dsl: TransactionDSL.() -> EnforceVerifyOrFail): EnforceVerifyOrFail + fun _tweak(dsl: TransactionDSLInterpreter.() -> EnforceVerifyOrFail): EnforceVerifyOrFail /** * Attaches an attachment containing the named contract to the transaction @@ -74,7 +74,7 @@ interface TransactionDSLInterpreter : Verifies, OutputStateLookup { fun _attachment(contractClassName: ContractClassName) } -class TransactionDSL(interpreter: T) : TransactionDSLInterpreter by interpreter { +class TransactionDSL(interpreter: T, private val notary: Party) : TransactionDSLInterpreter by interpreter { /** * Looks up the output label and adds the found state as an input. * @param stateLabel The label of the output state specified when calling [TransactionDSLInterpreter.output] and friends. @@ -87,7 +87,7 @@ class TransactionDSL(interpreter: T) : Transa * @param state The state to be added. */ fun input(contractClassName: ContractClassName, state: ContractState) { - val transaction = ledgerInterpreter._unverifiedTransaction(null, TransactionBuilder(notary = DUMMY_NOTARY)) { + val transaction = ledgerInterpreter._unverifiedTransaction(null, TransactionBuilder(notary)) { output(contractClassName, null, DUMMY_NOTARY, null, AlwaysAcceptAttachmentConstraint, state) } input(transaction.outRef(0).ref) @@ -103,13 +103,13 @@ class TransactionDSL(interpreter: T) : Transa * Adds a labelled output to the transaction. */ fun output(contractClassName: ContractClassName, label: String, encumbrance: Int, contractState: ContractState) = - output(contractClassName, label, DUMMY_NOTARY, encumbrance, AutomaticHashConstraint, contractState) + output(contractClassName, label, notary, encumbrance, AutomaticHashConstraint, contractState) /** * Adds a labelled output to the transaction. */ fun output(contractClassName: ContractClassName, label: String, contractState: ContractState) = - output(contractClassName, label, DUMMY_NOTARY, null, AutomaticHashConstraint, contractState) + output(contractClassName, label, notary, null, AutomaticHashConstraint, contractState) /** * Adds an output to the transaction. @@ -121,13 +121,13 @@ class TransactionDSL(interpreter: T) : Transa * Adds an output to the transaction. */ fun output(contractClassName: ContractClassName, encumbrance: Int, contractState: ContractState) = - output(contractClassName, null, DUMMY_NOTARY, encumbrance, AutomaticHashConstraint, contractState) + output(contractClassName, null, notary, encumbrance, AutomaticHashConstraint, contractState) /** * Adds an output to the transaction. */ fun output(contractClassName: ContractClassName, contractState: ContractState) = - output(contractClassName, null, DUMMY_NOTARY, null, AutomaticHashConstraint, contractState) + output(contractClassName, null, notary, null, AutomaticHashConstraint, contractState) /** * Adds a command to the transaction. @@ -143,6 +143,10 @@ class TransactionDSL(interpreter: T) : Transa fun timeWindow(time: Instant, tolerance: Duration = 30.seconds) = timeWindow(TimeWindow.withTolerance(time, tolerance)) + /** Creates a local scoped copy of the transaction. */ + fun tweak(dsl: TransactionDSL.() -> EnforceVerifyOrFail) = + _tweak { TransactionDSL(this, notary).dsl() } + /** * @see TransactionDSLInterpreter._attachment */