mirror of
https://github.com/corda/corda.git
synced 2025-02-21 09:51:57 +00:00
test dsl: LastLineShouldTestForVerifiesOrFails->EnforceVerifyOrFail
This commit is contained in:
parent
e31b769fef
commit
f177b1ffaa
@ -97,7 +97,7 @@ class CommercialPaperTestsGeneric {
|
|||||||
input("alice's paper")
|
input("alice's paper")
|
||||||
input("some profits")
|
input("some profits")
|
||||||
|
|
||||||
fun TransactionDSL<LastLineShouldTestForVerifiesOrFails, TransactionDSLInterpreter<LastLineShouldTestForVerifiesOrFails>>.outputs(aliceGetsBack: Amount<Issued<Currency>>) {
|
fun TransactionDSL<EnforceVerifyOrFail, TransactionDSLInterpreter<EnforceVerifyOrFail>>.outputs(aliceGetsBack: Amount<Issued<Currency>>) {
|
||||||
output("Alice's profit") { aliceGetsBack.STATE `owned by` ALICE_PUBKEY }
|
output("Alice's profit") { aliceGetsBack.STATE `owned by` ALICE_PUBKEY }
|
||||||
output("Change") { (someProfits - aliceGetsBack).STATE `owned by` MEGA_CORP_PUBKEY }
|
output("Change") { (someProfits - aliceGetsBack).STATE `owned by` MEGA_CORP_PUBKEY }
|
||||||
}
|
}
|
||||||
|
@ -360,7 +360,7 @@ class IRSTests {
|
|||||||
/**
|
/**
|
||||||
* Generates a typical transactional history for an IRS.
|
* Generates a typical transactional history for an IRS.
|
||||||
*/
|
*/
|
||||||
fun trade(): LedgerDSL<LastLineShouldTestForVerifiesOrFails, TestTransactionDSLInterpreter, TestLedgerDSLInterpreter> {
|
fun trade(): LedgerDSL<EnforceVerifyOrFail, TestTransactionDSLInterpreter, TestLedgerDSLInterpreter> {
|
||||||
|
|
||||||
val ld = LocalDate.of(2016, 3, 8)
|
val ld = LocalDate.of(2016, 3, 8)
|
||||||
val bd = BigDecimal("0.0063518")
|
val bd = BigDecimal("0.0063518")
|
||||||
@ -555,96 +555,93 @@ class IRSTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `various fixing tests`() {
|
fun `various fixing tests`() {
|
||||||
ledger {
|
val ld = LocalDate.of(2016, 3, 8)
|
||||||
|
val bd = BigDecimal("0.0063518")
|
||||||
|
|
||||||
val ld = LocalDate.of(2016, 3, 8)
|
transaction {
|
||||||
val bd = BigDecimal("0.0063518")
|
output("irs post agreement") { singleIRS() }
|
||||||
|
command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() }
|
||||||
|
timestamp(TEST_TX_TIME)
|
||||||
|
this.verifies()
|
||||||
|
}
|
||||||
|
|
||||||
transaction {
|
val oldIRS = singleIRS(1)
|
||||||
output("irs post agreement") { singleIRS() }
|
val newIRS = oldIRS.copy(oldIRS.fixedLeg,
|
||||||
command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() }
|
oldIRS.floatingLeg,
|
||||||
|
oldIRS.calculation.applyFixing(ld, FixedRate(RatioUnit(bd))),
|
||||||
|
oldIRS.common)
|
||||||
|
|
||||||
|
transaction {
|
||||||
|
input() {
|
||||||
|
oldIRS
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Templated tweak for reference. A corrent fixing applied should be ok
|
||||||
|
tweak {
|
||||||
|
command(ORACLE_PUBKEY) {
|
||||||
|
InterestRateSwap.Commands.Fix()
|
||||||
|
}
|
||||||
timestamp(TEST_TX_TIME)
|
timestamp(TEST_TX_TIME)
|
||||||
|
command(ORACLE_PUBKEY) {
|
||||||
|
Fix(FixOf("ICE LIBOR", ld, Tenor("3M")), bd)
|
||||||
|
}
|
||||||
|
output() { newIRS }
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
|
|
||||||
val oldIRS = singleIRS(1)
|
// This test makes sure that verify confirms the fixing was applied and there is a difference in the old and new
|
||||||
val newIRS = oldIRS.copy(oldIRS.fixedLeg,
|
tweak {
|
||||||
oldIRS.floatingLeg,
|
command(ORACLE_PUBKEY) { InterestRateSwap.Commands.Fix() }
|
||||||
oldIRS.calculation.applyFixing(ld, FixedRate(RatioUnit(bd))),
|
timestamp(TEST_TX_TIME)
|
||||||
oldIRS.common)
|
command(ORACLE_PUBKEY) { Fix(FixOf("ICE LIBOR", ld, Tenor("3M")), bd) }
|
||||||
|
output() { oldIRS }
|
||||||
transaction {
|
this `fails with` "There is at least one difference in the IRS floating leg payment schedules"
|
||||||
input() {
|
}
|
||||||
oldIRS
|
|
||||||
|
|
||||||
|
// This tests tries to sneak in a change to another fixing (which may or may not be the latest one)
|
||||||
|
tweak {
|
||||||
|
command(ORACLE_PUBKEY) { InterestRateSwap.Commands.Fix() }
|
||||||
|
timestamp(TEST_TX_TIME)
|
||||||
|
command(ORACLE_PUBKEY) {
|
||||||
|
Fix(FixOf("ICE LIBOR", ld, Tenor("3M")), bd)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Templated tweak for reference. A corrent fixing applied should be ok
|
val firstResetKey = newIRS.calculation.floatingLegPaymentSchedule.keys.first()
|
||||||
tweak {
|
val firstResetValue = newIRS.calculation.floatingLegPaymentSchedule[firstResetKey]
|
||||||
command(ORACLE_PUBKEY) {
|
val modifiedFirstResetValue = firstResetValue!!.copy(notional = Amount(firstResetValue.notional.quantity, Currency.getInstance("JPY")))
|
||||||
InterestRateSwap.Commands.Fix()
|
|
||||||
}
|
output() {
|
||||||
timestamp(TEST_TX_TIME)
|
newIRS.copy(
|
||||||
command(ORACLE_PUBKEY) {
|
newIRS.fixedLeg,
|
||||||
Fix(FixOf("ICE LIBOR", ld, Tenor("3M")), bd)
|
newIRS.floatingLeg,
|
||||||
}
|
newIRS.calculation.copy(floatingLegPaymentSchedule = newIRS.calculation.floatingLegPaymentSchedule.plus(
|
||||||
output() { newIRS }
|
Pair(firstResetKey, modifiedFirstResetValue))),
|
||||||
this.verifies()
|
newIRS.common
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
this `fails with` "There is only one change in the IRS floating leg payment schedule"
|
||||||
|
}
|
||||||
|
|
||||||
// This test makes sure that verify confirms the fixing was applied and there is a difference in the old and new
|
// This tests modifies the payment currency for the fixing
|
||||||
tweak {
|
tweak {
|
||||||
command(ORACLE_PUBKEY) { InterestRateSwap.Commands.Fix() }
|
command(ORACLE_PUBKEY) { InterestRateSwap.Commands.Fix() }
|
||||||
timestamp(TEST_TX_TIME)
|
timestamp(TEST_TX_TIME)
|
||||||
command(ORACLE_PUBKEY) { Fix(FixOf("ICE LIBOR", ld, Tenor("3M")), bd) }
|
command(ORACLE_PUBKEY) { Fix(FixOf("ICE LIBOR", ld, Tenor("3M")), bd) }
|
||||||
output() { oldIRS }
|
|
||||||
this `fails with` "There is at least one difference in the IRS floating leg payment schedules"
|
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")))
|
||||||
|
|
||||||
// This tests tries to sneak in a change to another fixing (which may or may not be the latest one)
|
output() {
|
||||||
tweak {
|
newIRS.copy(
|
||||||
command(ORACLE_PUBKEY) { InterestRateSwap.Commands.Fix() }
|
newIRS.fixedLeg,
|
||||||
timestamp(TEST_TX_TIME)
|
newIRS.floatingLeg,
|
||||||
command(ORACLE_PUBKEY) {
|
newIRS.calculation.copy(floatingLegPaymentSchedule = newIRS.calculation.floatingLegPaymentSchedule.plus(
|
||||||
Fix(FixOf("ICE LIBOR", ld, Tenor("3M")), bd)
|
Pair(latestReset.key, modifiedLatestResetValue))),
|
||||||
}
|
newIRS.common
|
||||||
|
)
|
||||||
val firstResetKey = newIRS.calculation.floatingLegPaymentSchedule.keys.first()
|
|
||||||
val firstResetValue = newIRS.calculation.floatingLegPaymentSchedule[firstResetKey]
|
|
||||||
val modifiedFirstResetValue = firstResetValue!!.copy(notional = Amount(firstResetValue.notional.quantity, Currency.getInstance("JPY")))
|
|
||||||
|
|
||||||
output() {
|
|
||||||
newIRS.copy(
|
|
||||||
newIRS.fixedLeg,
|
|
||||||
newIRS.floatingLeg,
|
|
||||||
newIRS.calculation.copy(floatingLegPaymentSchedule = newIRS.calculation.floatingLegPaymentSchedule.plus(
|
|
||||||
Pair(firstResetKey, modifiedFirstResetValue))),
|
|
||||||
newIRS.common
|
|
||||||
)
|
|
||||||
}
|
|
||||||
this `fails with` "There is only one change in the IRS floating leg payment schedule"
|
|
||||||
}
|
|
||||||
|
|
||||||
// This tests modifies the payment currency for the fixing
|
|
||||||
tweak {
|
|
||||||
command(ORACLE_PUBKEY) { InterestRateSwap.Commands.Fix() }
|
|
||||||
timestamp(TEST_TX_TIME)
|
|
||||||
command(ORACLE_PUBKEY) { Fix(FixOf("ICE LIBOR", ld, Tenor("3M")), bd) }
|
|
||||||
|
|
||||||
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() {
|
|
||||||
newIRS.copy(
|
|
||||||
newIRS.fixedLeg,
|
|
||||||
newIRS.floatingLeg,
|
|
||||||
newIRS.calculation.copy(floatingLegPaymentSchedule = newIRS.calculation.floatingLegPaymentSchedule.plus(
|
|
||||||
Pair(latestReset.key, modifiedLatestResetValue))),
|
|
||||||
newIRS.common
|
|
||||||
)
|
|
||||||
}
|
|
||||||
this `fails with` "The fix payment has the same currency as the notional"
|
|
||||||
}
|
}
|
||||||
|
this `fails with` "The fix payment has the same currency as the notional"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -656,7 +653,7 @@ class IRSTests {
|
|||||||
* result and the grouping won't work either.
|
* result and the grouping won't work either.
|
||||||
* In reality, the only fields that should be in common will be the next fixing date and the reference rate.
|
* In reality, the only fields that should be in common will be the next fixing date and the reference rate.
|
||||||
*/
|
*/
|
||||||
fun tradegroups(): LedgerDSL<LastLineShouldTestForVerifiesOrFails, TestTransactionDSLInterpreter, TestLedgerDSLInterpreter> {
|
fun tradegroups(): LedgerDSL<EnforceVerifyOrFail, TestTransactionDSLInterpreter, TestLedgerDSLInterpreter> {
|
||||||
val ld1 = LocalDate.of(2016, 3, 8)
|
val ld1 = LocalDate.of(2016, 3, 8)
|
||||||
val bd1 = BigDecimal("0.0063518")
|
val bd1 = BigDecimal("0.0063518")
|
||||||
|
|
||||||
|
@ -29,146 +29,142 @@ class CashTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun trivial() {
|
fun trivial() {
|
||||||
ledger {
|
transaction {
|
||||||
transaction {
|
input { inState }
|
||||||
input { inState }
|
this `fails with` "the amounts balance"
|
||||||
this `fails with` "the amounts balance"
|
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
output { outState.copy(amount = 2000.DOLLARS `issued by` defaultIssuer) }
|
output { outState.copy(amount = 2000.DOLLARS `issued by` defaultIssuer) }
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
tweak {
|
tweak {
|
||||||
output { outState }
|
output { outState }
|
||||||
// No command commanduments
|
// No command commanduments
|
||||||
this `fails with` "required com.r3corda.contracts.asset.FungibleAsset.Commands.Move command"
|
this `fails with` "required com.r3corda.contracts.asset.FungibleAsset.Commands.Move command"
|
||||||
}
|
}
|
||||||
tweak {
|
tweak {
|
||||||
output { outState }
|
output { outState }
|
||||||
command(DUMMY_PUBKEY_2) { Cash.Commands.Move() }
|
command(DUMMY_PUBKEY_2) { Cash.Commands.Move() }
|
||||||
this `fails with` "the owning keys are the same as the signing keys"
|
this `fails with` "the owning keys are the same as the signing keys"
|
||||||
}
|
}
|
||||||
tweak {
|
tweak {
|
||||||
output { outState }
|
output { outState }
|
||||||
output { outState `issued by` MINI_CORP }
|
output { outState `issued by` MINI_CORP }
|
||||||
command(DUMMY_PUBKEY_1) { Cash.Commands.Move() }
|
command(DUMMY_PUBKEY_1) { Cash.Commands.Move() }
|
||||||
this `fails with` "at least one asset input"
|
this `fails with` "at least one asset input"
|
||||||
}
|
}
|
||||||
// Simple reallocation works.
|
// Simple reallocation works.
|
||||||
tweak {
|
tweak {
|
||||||
output { outState }
|
output { outState }
|
||||||
command(DUMMY_PUBKEY_1) { Cash.Commands.Move() }
|
command(DUMMY_PUBKEY_1) { Cash.Commands.Move() }
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun issueMoney() {
|
fun issueMoney() {
|
||||||
ledger {
|
// Check we can't "move" money into existence.
|
||||||
// Check we can't "move" money into existence.
|
transaction {
|
||||||
transaction {
|
input { DummyState() }
|
||||||
input { DummyState() }
|
output { outState }
|
||||||
output { outState }
|
command(MINI_CORP_PUBKEY) { Cash.Commands.Move() }
|
||||||
command(MINI_CORP_PUBKEY) { Cash.Commands.Move() }
|
|
||||||
|
|
||||||
this `fails with` "there is at least one asset input"
|
this `fails with` "there is at least one asset input"
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 }
|
||||||
|
command(DUMMY_PUBKEY_1) { Cash.Commands.Issue() }
|
||||||
|
this `fails with` "output deposits are owned by a command signer"
|
||||||
|
}
|
||||||
|
transaction {
|
||||||
|
output {
|
||||||
|
Cash.State(
|
||||||
|
amount = 1000.DOLLARS `issued by` MINI_CORP.ref(12, 34),
|
||||||
|
owner = DUMMY_PUBKEY_1
|
||||||
|
)
|
||||||
|
}
|
||||||
|
tweak {
|
||||||
|
command(MINI_CORP_PUBKEY) { Cash.Commands.Issue(0) }
|
||||||
|
this `fails with` "has a nonce"
|
||||||
|
}
|
||||||
|
command(MINI_CORP_PUBKEY) { Cash.Commands.Issue() }
|
||||||
|
this.verifies()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test generation works.
|
||||||
|
val ptx = TransactionType.General.Builder()
|
||||||
|
Cash().generateIssue(ptx, 100.DOLLARS `issued by` MINI_CORP.ref(12, 34), owner = DUMMY_PUBKEY_1, notary = DUMMY_NOTARY)
|
||||||
|
assertTrue(ptx.inputStates().isEmpty())
|
||||||
|
val s = ptx.outputStates()[0].data as Cash.State
|
||||||
|
assertEquals(100.DOLLARS `issued by` MINI_CORP.ref(12, 34), s.amount)
|
||||||
|
assertEquals(MINI_CORP, s.deposit.party)
|
||||||
|
assertEquals(DUMMY_PUBKEY_1, s.owner)
|
||||||
|
assertTrue(ptx.commands()[0].value is Cash.Commands.Issue)
|
||||||
|
assertEquals(MINI_CORP_PUBKEY, ptx.commands()[0].signers[0])
|
||||||
|
|
||||||
|
// Test issuance from the issuance definition
|
||||||
|
val amount = 100.DOLLARS `issued by` MINI_CORP.ref(12, 34)
|
||||||
|
val templatePtx = TransactionType.General.Builder()
|
||||||
|
Cash().generateIssue(templatePtx, amount, owner = DUMMY_PUBKEY_1, notary = DUMMY_NOTARY)
|
||||||
|
assertTrue(templatePtx.inputStates().isEmpty())
|
||||||
|
assertEquals(ptx.outputStates()[0], templatePtx.outputStates()[0])
|
||||||
|
|
||||||
|
// 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(amount = inState.amount * 2) }
|
||||||
|
|
||||||
|
// Move fails: not allowed to summon money.
|
||||||
|
tweak {
|
||||||
|
command(DUMMY_PUBKEY_1) { Cash.Commands.Move() }
|
||||||
|
this `fails with` "at issuer MegaCorp the amounts balance"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check we can issue money only as long as the issuer institution is a command signer, i.e. any recognised
|
// Issue works.
|
||||||
// institution is allowed to issue as much cash as they want.
|
tweak {
|
||||||
transaction {
|
command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() }
|
||||||
output { outState }
|
|
||||||
command(DUMMY_PUBKEY_1) { Cash.Commands.Issue() }
|
|
||||||
this `fails with` "output deposits are owned by a command signer"
|
|
||||||
}
|
|
||||||
transaction {
|
|
||||||
output {
|
|
||||||
Cash.State(
|
|
||||||
amount = 1000.DOLLARS `issued by` MINI_CORP.ref(12, 34),
|
|
||||||
owner = DUMMY_PUBKEY_1
|
|
||||||
)
|
|
||||||
}
|
|
||||||
tweak {
|
|
||||||
command(MINI_CORP_PUBKEY) { Cash.Commands.Issue(0) }
|
|
||||||
this `fails with` "has a nonce"
|
|
||||||
}
|
|
||||||
command(MINI_CORP_PUBKEY) { Cash.Commands.Issue() }
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Test generation works.
|
// Can't use an issue command to lower the amount.
|
||||||
val ptx = TransactionType.General.Builder()
|
transaction {
|
||||||
Cash().generateIssue(ptx, 100.DOLLARS `issued by` MINI_CORP.ref(12, 34), owner = DUMMY_PUBKEY_1, notary = DUMMY_NOTARY)
|
input { inState }
|
||||||
assertTrue(ptx.inputStates().isEmpty())
|
output { inState.copy(amount = inState.amount / 2) }
|
||||||
val s = ptx.outputStates()[0].data as Cash.State
|
command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() }
|
||||||
assertEquals(100.DOLLARS `issued by` MINI_CORP.ref(12, 34), s.amount)
|
this `fails with` "output values sum to more than the inputs"
|
||||||
assertEquals(MINI_CORP, s.deposit.party)
|
}
|
||||||
assertEquals(DUMMY_PUBKEY_1, s.owner)
|
|
||||||
assertTrue(ptx.commands()[0].value is Cash.Commands.Issue)
|
|
||||||
assertEquals(MINI_CORP_PUBKEY, ptx.commands()[0].signers[0])
|
|
||||||
|
|
||||||
// Test issuance from the issuance definition
|
// Can't have an issue command that doesn't actually issue money.
|
||||||
val amount = 100.DOLLARS `issued by` MINI_CORP.ref(12, 34)
|
transaction {
|
||||||
val templatePtx = TransactionType.General.Builder()
|
input { inState }
|
||||||
Cash().generateIssue(templatePtx, amount, owner = DUMMY_PUBKEY_1, notary = DUMMY_NOTARY)
|
output { inState }
|
||||||
assertTrue(templatePtx.inputStates().isEmpty())
|
command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() }
|
||||||
assertEquals(ptx.outputStates()[0], templatePtx.outputStates()[0])
|
this `fails with` "output values sum to more than the inputs"
|
||||||
|
}
|
||||||
|
|
||||||
// We can consume $1000 in a transaction and output $2000 as long as it's signed by an issuer.
|
// Can't have any other commands if we have an issue command (because the issue command overrules them)
|
||||||
transaction {
|
transaction {
|
||||||
input { inState }
|
input { inState }
|
||||||
output { inState.copy(amount = inState.amount * 2) }
|
output { inState.copy(amount = inState.amount * 2) }
|
||||||
|
command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() }
|
||||||
// Move fails: not allowed to summon money.
|
tweak {
|
||||||
tweak {
|
|
||||||
command(DUMMY_PUBKEY_1) { Cash.Commands.Move() }
|
|
||||||
this `fails with` "at issuer MegaCorp the amounts balance"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Issue works.
|
|
||||||
tweak {
|
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() }
|
|
||||||
this.verifies()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Can't use an issue command to lower the amount.
|
|
||||||
transaction {
|
|
||||||
input { inState }
|
|
||||||
output { inState.copy(amount = inState.amount / 2) }
|
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() }
|
command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() }
|
||||||
this `fails with` "output values sum to more than the inputs"
|
this `fails with` "there is only a single issue command"
|
||||||
}
|
}
|
||||||
|
tweak {
|
||||||
// Can't have an issue command that doesn't actually issue money.
|
command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() }
|
||||||
transaction {
|
this `fails with` "there is only a single issue command"
|
||||||
input { inState }
|
|
||||||
output { inState }
|
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() }
|
|
||||||
this `fails with` "output values sum to more than the inputs"
|
|
||||||
}
|
}
|
||||||
|
tweak {
|
||||||
// Can't have any other commands if we have an issue command (because the issue command overrules them)
|
command(MEGA_CORP_PUBKEY) { Cash.Commands.Exit(inState.amount / 2) }
|
||||||
transaction {
|
this `fails with` "there is only a single issue command"
|
||||||
input { inState }
|
|
||||||
output { inState.copy(amount = inState.amount * 2) }
|
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() }
|
|
||||||
tweak {
|
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() }
|
|
||||||
this `fails with` "there is only a single issue command"
|
|
||||||
}
|
|
||||||
tweak {
|
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() }
|
|
||||||
this `fails with` "there is only a single issue command"
|
|
||||||
}
|
|
||||||
tweak {
|
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Exit(inState.amount / 2) }
|
|
||||||
this `fails with` "there is only a single issue command"
|
|
||||||
}
|
|
||||||
this.verifies()
|
|
||||||
}
|
}
|
||||||
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,190 +189,178 @@ class CashTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testMergeSplit() {
|
fun testMergeSplit() {
|
||||||
ledger {
|
// Splitting value works.
|
||||||
// Splitting value works.
|
transaction {
|
||||||
transaction {
|
command(DUMMY_PUBKEY_1) { Cash.Commands.Move() }
|
||||||
command(DUMMY_PUBKEY_1) { Cash.Commands.Move() }
|
tweak {
|
||||||
tweak {
|
input { inState }
|
||||||
input { inState }
|
for (i in 1..4) output { inState.copy(amount = inState.amount / 4) }
|
||||||
for (i in 1..4) output { inState.copy(amount = inState.amount / 4) }
|
this.verifies()
|
||||||
this.verifies()
|
}
|
||||||
}
|
// Merging 4 inputs into 2 outputs works.
|
||||||
// Merging 4 inputs into 2 outputs works.
|
tweak {
|
||||||
tweak {
|
for (i in 1..4) input { inState.copy(amount = inState.amount / 4) }
|
||||||
for (i in 1..4) input { inState.copy(amount = inState.amount / 4) }
|
output { inState.copy(amount = inState.amount / 2) }
|
||||||
output { inState.copy(amount = inState.amount / 2) }
|
output { inState.copy(amount = inState.amount / 2) }
|
||||||
output { inState.copy(amount = inState.amount / 2) }
|
this.verifies()
|
||||||
this.verifies()
|
}
|
||||||
}
|
// Merging 2 inputs into 1 works.
|
||||||
// Merging 2 inputs into 1 works.
|
tweak {
|
||||||
tweak {
|
input { inState.copy(amount = inState.amount / 2) }
|
||||||
input { inState.copy(amount = inState.amount / 2) }
|
input { inState.copy(amount = inState.amount / 2) }
|
||||||
input { inState.copy(amount = inState.amount / 2) }
|
output { inState }
|
||||||
output { inState }
|
this.verifies()
|
||||||
this.verifies()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun zeroSizedValues() {
|
fun zeroSizedValues() {
|
||||||
ledger {
|
transaction {
|
||||||
transaction {
|
input { inState }
|
||||||
input { inState }
|
input { inState.copy(amount = 0.DOLLARS `issued by` defaultIssuer) }
|
||||||
input { inState.copy(amount = 0.DOLLARS `issued by` defaultIssuer) }
|
this `fails with` "zero sized inputs"
|
||||||
this `fails with` "zero sized inputs"
|
}
|
||||||
}
|
transaction {
|
||||||
transaction {
|
input { inState }
|
||||||
input { inState }
|
output { inState }
|
||||||
output { inState }
|
output { inState.copy(amount = 0.DOLLARS `issued by` defaultIssuer) }
|
||||||
output { inState.copy(amount = 0.DOLLARS `issued by` defaultIssuer) }
|
this `fails with` "zero sized outputs"
|
||||||
this `fails with` "zero sized outputs"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun trivialMismatches() {
|
fun trivialMismatches() {
|
||||||
ledger {
|
// Can't change issuer.
|
||||||
// Can't change issuer.
|
transaction {
|
||||||
transaction {
|
input { inState }
|
||||||
input { inState }
|
output { outState `issued by` MINI_CORP }
|
||||||
output { outState `issued by` MINI_CORP }
|
this `fails with` "at issuer MegaCorp the amounts balance"
|
||||||
this `fails with` "at issuer MegaCorp the amounts balance"
|
}
|
||||||
}
|
// Can't change deposit reference when splitting.
|
||||||
// Can't change deposit reference when splitting.
|
transaction {
|
||||||
transaction {
|
input { inState }
|
||||||
input { inState }
|
output { outState.copy(amount = inState.amount / 2).editDepositRef(0) }
|
||||||
output { outState.copy(amount = inState.amount / 2).editDepositRef(0) }
|
output { outState.copy(amount = inState.amount / 2).editDepositRef(1) }
|
||||||
output { outState.copy(amount = inState.amount / 2).editDepositRef(1) }
|
this `fails with` "for deposit [01] at issuer MegaCorp the amounts balance"
|
||||||
this `fails with` "for deposit [01] at issuer MegaCorp the amounts balance"
|
}
|
||||||
}
|
// Can't mix currencies.
|
||||||
// Can't mix currencies.
|
transaction {
|
||||||
transaction {
|
input { inState }
|
||||||
input { inState }
|
output { outState.copy(amount = 800.DOLLARS `issued by` defaultIssuer) }
|
||||||
output { outState.copy(amount = 800.DOLLARS `issued by` defaultIssuer) }
|
output { outState.copy(amount = 200.POUNDS `issued by` defaultIssuer) }
|
||||||
output { outState.copy(amount = 200.POUNDS `issued by` defaultIssuer) }
|
this `fails with` "the amounts balance"
|
||||||
this `fails with` "the amounts balance"
|
}
|
||||||
}
|
transaction {
|
||||||
transaction {
|
input { inState }
|
||||||
input { inState }
|
input {
|
||||||
input {
|
inState.copy(
|
||||||
inState.copy(
|
amount = 150.POUNDS `issued by` defaultIssuer,
|
||||||
amount = 150.POUNDS `issued by` defaultIssuer,
|
owner = DUMMY_PUBKEY_2
|
||||||
owner = DUMMY_PUBKEY_2
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
output { outState.copy(amount = 1150.DOLLARS `issued by` defaultIssuer) }
|
|
||||||
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 }
|
|
||||||
command(DUMMY_PUBKEY_1) { Cash.Commands.Move() }
|
|
||||||
this `fails with` "at issuer MiniCorp 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) }
|
|
||||||
this `fails with` "for deposit [01]"
|
|
||||||
}
|
}
|
||||||
|
output { outState.copy(amount = 1150.DOLLARS `issued by` defaultIssuer) }
|
||||||
|
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 }
|
||||||
|
command(DUMMY_PUBKEY_1) { Cash.Commands.Move() }
|
||||||
|
this `fails with` "at issuer MiniCorp 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) }
|
||||||
|
this `fails with` "for deposit [01]"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun exitLedger() {
|
fun exitLedger() {
|
||||||
ledger {
|
// Single input/output straightforward case.
|
||||||
// Single input/output straightforward case.
|
transaction {
|
||||||
transaction {
|
input { inState }
|
||||||
input { inState }
|
output { outState.copy(amount = inState.amount - (200.DOLLARS `issued by` defaultIssuer)) }
|
||||||
output { outState.copy(amount = inState.amount - (200.DOLLARS `issued by` defaultIssuer)) }
|
|
||||||
|
|
||||||
tweak {
|
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Exit(100.DOLLARS `issued by` defaultIssuer) }
|
|
||||||
command(DUMMY_PUBKEY_1) { Cash.Commands.Move() }
|
|
||||||
this `fails with` "the amounts balance"
|
|
||||||
}
|
|
||||||
|
|
||||||
tweak {
|
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Exit(200.DOLLARS `issued by` defaultIssuer) }
|
|
||||||
this `fails with` "required com.r3corda.contracts.asset.FungibleAsset.Commands.Move command"
|
|
||||||
|
|
||||||
tweak {
|
|
||||||
command(DUMMY_PUBKEY_1) { Cash.Commands.Move() }
|
|
||||||
this.verifies()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Multi-issuer case.
|
|
||||||
transaction {
|
|
||||||
input { inState }
|
|
||||||
input { inState `issued by` MINI_CORP }
|
|
||||||
|
|
||||||
output { inState.copy(amount = inState.amount - (200.DOLLARS `issued by` defaultIssuer)) `issued by` MINI_CORP }
|
|
||||||
output { inState.copy(amount = inState.amount - (200.DOLLARS `issued by` defaultIssuer)) }
|
|
||||||
|
|
||||||
|
tweak {
|
||||||
|
command(MEGA_CORP_PUBKEY) { Cash.Commands.Exit(100.DOLLARS `issued by` defaultIssuer) }
|
||||||
command(DUMMY_PUBKEY_1) { Cash.Commands.Move() }
|
command(DUMMY_PUBKEY_1) { Cash.Commands.Move() }
|
||||||
|
this `fails with` "the amounts balance"
|
||||||
this `fails with` "at issuer MegaCorp the amounts balance"
|
|
||||||
|
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Exit(200.DOLLARS `issued by` defaultIssuer) }
|
|
||||||
this `fails with` "at issuer MiniCorp the amounts balance"
|
|
||||||
|
|
||||||
command(MINI_CORP_PUBKEY) { Cash.Commands.Exit(200.DOLLARS `issued by` MINI_CORP.ref(defaultRef)) }
|
|
||||||
this.verifies()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tweak {
|
||||||
|
command(MEGA_CORP_PUBKEY) { Cash.Commands.Exit(200.DOLLARS `issued by` defaultIssuer) }
|
||||||
|
this `fails with` "required com.r3corda.contracts.asset.FungibleAsset.Commands.Move command"
|
||||||
|
|
||||||
|
tweak {
|
||||||
|
command(DUMMY_PUBKEY_1) { Cash.Commands.Move() }
|
||||||
|
this.verifies()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Multi-issuer case.
|
||||||
|
transaction {
|
||||||
|
input { inState }
|
||||||
|
input { inState `issued by` MINI_CORP }
|
||||||
|
|
||||||
|
output { inState.copy(amount = inState.amount - (200.DOLLARS `issued by` defaultIssuer)) `issued by` MINI_CORP }
|
||||||
|
output { inState.copy(amount = inState.amount - (200.DOLLARS `issued by` defaultIssuer)) }
|
||||||
|
|
||||||
|
command(DUMMY_PUBKEY_1) { Cash.Commands.Move() }
|
||||||
|
|
||||||
|
this `fails with` "at issuer MegaCorp the amounts balance"
|
||||||
|
|
||||||
|
command(MEGA_CORP_PUBKEY) { Cash.Commands.Exit(200.DOLLARS `issued by` defaultIssuer) }
|
||||||
|
this `fails with` "at issuer MiniCorp the amounts balance"
|
||||||
|
|
||||||
|
command(MINI_CORP_PUBKEY) { Cash.Commands.Exit(200.DOLLARS `issued by` MINI_CORP.ref(defaultRef)) }
|
||||||
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun multiIssuer() {
|
fun multiIssuer() {
|
||||||
ledger {
|
transaction {
|
||||||
transaction {
|
// Gather 2000 dollars from two different issuers.
|
||||||
// Gather 2000 dollars from two different issuers.
|
input { inState }
|
||||||
input { inState }
|
input { inState `issued by` MINI_CORP }
|
||||||
input { inState `issued by` MINI_CORP }
|
|
||||||
|
|
||||||
// Can't merge them together.
|
// Can't merge them together.
|
||||||
tweak {
|
tweak {
|
||||||
output { inState.copy(owner = DUMMY_PUBKEY_2, amount = 2000.DOLLARS `issued by` defaultIssuer) }
|
output { inState.copy(owner = DUMMY_PUBKEY_2, amount = 2000.DOLLARS `issued by` defaultIssuer) }
|
||||||
this `fails with` "at issuer MegaCorp the amounts balance"
|
this `fails with` "at issuer MegaCorp the amounts balance"
|
||||||
}
|
|
||||||
// Missing MiniCorp deposit
|
|
||||||
tweak {
|
|
||||||
output { inState.copy(owner = DUMMY_PUBKEY_2) }
|
|
||||||
output { inState.copy(owner = DUMMY_PUBKEY_2) }
|
|
||||||
this `fails with` "at issuer MegaCorp the amounts balance"
|
|
||||||
}
|
|
||||||
|
|
||||||
// This works.
|
|
||||||
output { inState.copy(owner = DUMMY_PUBKEY_2) }
|
|
||||||
output { inState.copy(owner = DUMMY_PUBKEY_2) `issued by` MINI_CORP }
|
|
||||||
command(DUMMY_PUBKEY_1) { Cash.Commands.Move() }
|
|
||||||
this.verifies()
|
|
||||||
}
|
}
|
||||||
|
// Missing MiniCorp deposit
|
||||||
|
tweak {
|
||||||
|
output { inState.copy(owner = DUMMY_PUBKEY_2) }
|
||||||
|
output { inState.copy(owner = DUMMY_PUBKEY_2) }
|
||||||
|
this `fails with` "at issuer MegaCorp the amounts balance"
|
||||||
|
}
|
||||||
|
|
||||||
|
// This works.
|
||||||
|
output { inState.copy(owner = DUMMY_PUBKEY_2) }
|
||||||
|
output { inState.copy(owner = DUMMY_PUBKEY_2) `issued by` MINI_CORP }
|
||||||
|
command(DUMMY_PUBKEY_1) { Cash.Commands.Move() }
|
||||||
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun multiCurrency() {
|
fun multiCurrency() {
|
||||||
ledger {
|
// Check we can do an atomic currency trade tx.
|
||||||
// Check we can do an atomic currency trade tx.
|
transaction {
|
||||||
transaction {
|
val pounds = Cash.State(658.POUNDS `issued by` MINI_CORP.ref(3, 4, 5), DUMMY_PUBKEY_2)
|
||||||
val pounds = Cash.State(658.POUNDS `issued by` MINI_CORP.ref(3, 4, 5), DUMMY_PUBKEY_2)
|
input { inState `owned by` DUMMY_PUBKEY_1 }
|
||||||
input { inState `owned by` DUMMY_PUBKEY_1 }
|
input { pounds }
|
||||||
input { pounds }
|
output { inState `owned by` DUMMY_PUBKEY_2 }
|
||||||
output { inState `owned by` DUMMY_PUBKEY_2 }
|
output { pounds `owned by` DUMMY_PUBKEY_1 }
|
||||||
output { pounds `owned by` DUMMY_PUBKEY_1 }
|
command(DUMMY_PUBKEY_1, DUMMY_PUBKEY_2) { Cash.Commands.Move() }
|
||||||
command(DUMMY_PUBKEY_1, DUMMY_PUBKEY_2) { Cash.Commands.Move() }
|
|
||||||
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ class ObligationTests {
|
|||||||
val outState = inState.copy(beneficiary = DUMMY_PUBKEY_2)
|
val outState = inState.copy(beneficiary = DUMMY_PUBKEY_2)
|
||||||
|
|
||||||
private fun obligationTestRoots(
|
private fun obligationTestRoots(
|
||||||
group: LedgerDSL<LastLineShouldTestForVerifiesOrFails, TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>
|
group: LedgerDSL<EnforceVerifyOrFail, TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>
|
||||||
) = group.apply {
|
) = group.apply {
|
||||||
unverifiedTransaction {
|
unverifiedTransaction {
|
||||||
output("Alice's $1,000,000 obligation to Bob", oneMillionDollars.OBLIGATION `between` Pair(ALICE, BOB_PUBKEY))
|
output("Alice's $1,000,000 obligation to Bob", oneMillionDollars.OBLIGATION `between` Pair(ALICE, BOB_PUBKEY))
|
||||||
|
@ -17,15 +17,15 @@ import java.util.*
|
|||||||
fun transaction(
|
fun transaction(
|
||||||
transactionLabel: String? = null,
|
transactionLabel: String? = null,
|
||||||
dsl: TransactionDSL<
|
dsl: TransactionDSL<
|
||||||
LastLineShouldTestForVerifiesOrFails,
|
EnforceVerifyOrFail,
|
||||||
TransactionDSLInterpreter<LastLineShouldTestForVerifiesOrFails>
|
TransactionDSLInterpreter<EnforceVerifyOrFail>
|
||||||
>.() -> LastLineShouldTestForVerifiesOrFails
|
>.() -> EnforceVerifyOrFail
|
||||||
) = JavaTestHelpers.transaction(transactionLabel, dsl)
|
) = JavaTestHelpers.transaction(transactionLabel, dsl)
|
||||||
|
|
||||||
fun ledger(
|
fun ledger(
|
||||||
identityService: IdentityService = MOCK_IDENTITY_SERVICE,
|
identityService: IdentityService = MOCK_IDENTITY_SERVICE,
|
||||||
storageService: StorageService = MockStorageService(),
|
storageService: StorageService = MockStorageService(),
|
||||||
dsl: LedgerDSL<LastLineShouldTestForVerifiesOrFails, TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.() -> Unit
|
dsl: LedgerDSL<EnforceVerifyOrFail, TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.() -> Unit
|
||||||
) = JavaTestHelpers.ledger(identityService, storageService, dsl)
|
) = JavaTestHelpers.ledger(identityService, storageService, dsl)
|
||||||
|
|
||||||
@Deprecated(
|
@Deprecated(
|
||||||
@ -33,8 +33,8 @@ fun ledger(
|
|||||||
replaceWith = ReplaceWith("tweak"),
|
replaceWith = ReplaceWith("tweak"),
|
||||||
level = DeprecationLevel.ERROR)
|
level = DeprecationLevel.ERROR)
|
||||||
@Suppress("UNUSED_PARAMETER")
|
@Suppress("UNUSED_PARAMETER")
|
||||||
fun TransactionDSLInterpreter<LastLineShouldTestForVerifiesOrFails>.ledger(
|
fun TransactionDSLInterpreter<EnforceVerifyOrFail>.ledger(
|
||||||
dsl: LedgerDSL<LastLineShouldTestForVerifiesOrFails, TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.() -> Unit) {
|
dsl: LedgerDSL<EnforceVerifyOrFail, TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.() -> Unit) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated(
|
@Deprecated(
|
||||||
@ -42,11 +42,11 @@ fun TransactionDSLInterpreter<LastLineShouldTestForVerifiesOrFails>.ledger(
|
|||||||
replaceWith = ReplaceWith("tweak"),
|
replaceWith = ReplaceWith("tweak"),
|
||||||
level = DeprecationLevel.ERROR)
|
level = DeprecationLevel.ERROR)
|
||||||
@Suppress("UNUSED_PARAMETER")
|
@Suppress("UNUSED_PARAMETER")
|
||||||
fun TransactionDSLInterpreter<LastLineShouldTestForVerifiesOrFails>.transaction(
|
fun TransactionDSLInterpreter<EnforceVerifyOrFail>.transaction(
|
||||||
dsl: TransactionDSL<
|
dsl: TransactionDSL<
|
||||||
LastLineShouldTestForVerifiesOrFails,
|
EnforceVerifyOrFail,
|
||||||
TransactionDSLInterpreter<LastLineShouldTestForVerifiesOrFails>
|
TransactionDSLInterpreter<EnforceVerifyOrFail>
|
||||||
>.() -> LastLineShouldTestForVerifiesOrFails) {
|
>.() -> EnforceVerifyOrFail) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated(
|
@Deprecated(
|
||||||
@ -54,8 +54,8 @@ fun TransactionDSLInterpreter<LastLineShouldTestForVerifiesOrFails>.transaction(
|
|||||||
replaceWith = ReplaceWith("tweak"),
|
replaceWith = ReplaceWith("tweak"),
|
||||||
level = DeprecationLevel.ERROR)
|
level = DeprecationLevel.ERROR)
|
||||||
@Suppress("UNUSED_PARAMETER")
|
@Suppress("UNUSED_PARAMETER")
|
||||||
fun LedgerDSLInterpreter<LastLineShouldTestForVerifiesOrFails, TransactionDSLInterpreter<LastLineShouldTestForVerifiesOrFails>>.ledger(
|
fun LedgerDSLInterpreter<EnforceVerifyOrFail, TransactionDSLInterpreter<EnforceVerifyOrFail>>.ledger(
|
||||||
dsl: LedgerDSL<LastLineShouldTestForVerifiesOrFails, TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.() -> Unit) {
|
dsl: LedgerDSL<EnforceVerifyOrFail, TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.() -> Unit) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -64,8 +64,8 @@ fun LedgerDSLInterpreter<LastLineShouldTestForVerifiesOrFails, TransactionDSLInt
|
|||||||
* will have as the last line either an accept or a failure test. The name is deliberately long to help make sense of
|
* will have as the last line either an accept or a failure test. The name is deliberately long to help make sense of
|
||||||
* the triggered diagnostic.
|
* the triggered diagnostic.
|
||||||
*/
|
*/
|
||||||
sealed class LastLineShouldTestForVerifiesOrFails {
|
sealed class EnforceVerifyOrFail {
|
||||||
internal object Token: LastLineShouldTestForVerifiesOrFails()
|
internal object Token: EnforceVerifyOrFail()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -80,7 +80,7 @@ data class TestTransactionDSLInterpreter(
|
|||||||
private val commands: ArrayList<Command> = arrayListOf(),
|
private val commands: ArrayList<Command> = arrayListOf(),
|
||||||
private val signers: LinkedHashSet<PublicKey> = LinkedHashSet(),
|
private val signers: LinkedHashSet<PublicKey> = LinkedHashSet(),
|
||||||
private val transactionType: TransactionType = TransactionType.General()
|
private val transactionType: TransactionType = TransactionType.General()
|
||||||
) : TransactionDSLInterpreter<LastLineShouldTestForVerifiesOrFails>, OutputStateLookup by ledgerInterpreter {
|
) : TransactionDSLInterpreter<EnforceVerifyOrFail>, OutputStateLookup by ledgerInterpreter {
|
||||||
private fun copy(): TestTransactionDSLInterpreter =
|
private fun copy(): TestTransactionDSLInterpreter =
|
||||||
TestTransactionDSLInterpreter(
|
TestTransactionDSLInterpreter(
|
||||||
ledgerInterpreter = ledgerInterpreter,
|
ledgerInterpreter = ledgerInterpreter,
|
||||||
@ -121,13 +121,13 @@ data class TestTransactionDSLInterpreter(
|
|||||||
commands.add(Command(commandData, signers))
|
commands.add(Command(commandData, signers))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun verifies(): LastLineShouldTestForVerifiesOrFails {
|
override fun verifies(): EnforceVerifyOrFail {
|
||||||
val resolvedTransaction = ledgerInterpreter.resolveWireTransaction(toWireTransaction())
|
val resolvedTransaction = ledgerInterpreter.resolveWireTransaction(toWireTransaction())
|
||||||
resolvedTransaction.verify()
|
resolvedTransaction.verify()
|
||||||
return LastLineShouldTestForVerifiesOrFails.Token
|
return EnforceVerifyOrFail.Token
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun failsWith(expectedMessage: String?): LastLineShouldTestForVerifiesOrFails {
|
override fun failsWith(expectedMessage: String?): EnforceVerifyOrFail {
|
||||||
val exceptionThrown = try {
|
val exceptionThrown = try {
|
||||||
this.verifies()
|
this.verifies()
|
||||||
false
|
false
|
||||||
@ -151,14 +151,14 @@ data class TestTransactionDSLInterpreter(
|
|||||||
throw AssertionError("Expected exception but didn't get one")
|
throw AssertionError("Expected exception but didn't get one")
|
||||||
}
|
}
|
||||||
|
|
||||||
return LastLineShouldTestForVerifiesOrFails.Token
|
return EnforceVerifyOrFail.Token
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun tweak(
|
override fun tweak(
|
||||||
dsl: TransactionDSL<
|
dsl: TransactionDSL<
|
||||||
LastLineShouldTestForVerifiesOrFails,
|
EnforceVerifyOrFail,
|
||||||
TransactionDSLInterpreter<LastLineShouldTestForVerifiesOrFails>
|
TransactionDSLInterpreter<EnforceVerifyOrFail>
|
||||||
>.() -> LastLineShouldTestForVerifiesOrFails
|
>.() -> EnforceVerifyOrFail
|
||||||
) = dsl(TransactionDSL(copy()))
|
) = dsl(TransactionDSL(copy()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,7 +171,7 @@ data class TestLedgerDSLInterpreter private constructor (
|
|||||||
internal val labelToOutputStateAndRefs: HashMap<String, StateAndRef<ContractState>> = HashMap(),
|
internal val labelToOutputStateAndRefs: HashMap<String, StateAndRef<ContractState>> = HashMap(),
|
||||||
private val transactionWithLocations: HashMap<SecureHash, WireTransactionWithLocation> = HashMap(),
|
private val transactionWithLocations: HashMap<SecureHash, WireTransactionWithLocation> = HashMap(),
|
||||||
private val nonVerifiedTransactionWithLocations: HashMap<SecureHash, WireTransactionWithLocation> = HashMap()
|
private val nonVerifiedTransactionWithLocations: HashMap<SecureHash, WireTransactionWithLocation> = HashMap()
|
||||||
) : LedgerDSLInterpreter<LastLineShouldTestForVerifiesOrFails, TestTransactionDSLInterpreter> {
|
) : LedgerDSLInterpreter<EnforceVerifyOrFail, TestTransactionDSLInterpreter> {
|
||||||
|
|
||||||
val wireTransactions: List<WireTransaction> get() = transactionWithLocations.values.map { it.transaction }
|
val wireTransactions: List<WireTransaction> get() = transactionWithLocations.values.map { it.transaction }
|
||||||
|
|
||||||
@ -243,7 +243,7 @@ data class TestLedgerDSLInterpreter private constructor (
|
|||||||
storageService.attachments.openAttachment(attachmentId) ?: throw AttachmentResolutionException(attachmentId)
|
storageService.attachments.openAttachment(attachmentId) ?: throw AttachmentResolutionException(attachmentId)
|
||||||
|
|
||||||
private fun <Return> interpretTransactionDsl(
|
private fun <Return> interpretTransactionDsl(
|
||||||
dsl: TransactionDSL<LastLineShouldTestForVerifiesOrFails, TestTransactionDSLInterpreter>.() -> Return
|
dsl: TransactionDSL<EnforceVerifyOrFail, TestTransactionDSLInterpreter>.() -> Return
|
||||||
): TestTransactionDSLInterpreter {
|
): TestTransactionDSLInterpreter {
|
||||||
val transactionInterpreter = TestTransactionDSLInterpreter(this)
|
val transactionInterpreter = TestTransactionDSLInterpreter(this)
|
||||||
dsl(TransactionDSL(transactionInterpreter))
|
dsl(TransactionDSL(transactionInterpreter))
|
||||||
@ -274,7 +274,7 @@ data class TestLedgerDSLInterpreter private constructor (
|
|||||||
|
|
||||||
private fun <R> recordTransactionWithTransactionMap(
|
private fun <R> recordTransactionWithTransactionMap(
|
||||||
transactionLabel: String?,
|
transactionLabel: String?,
|
||||||
dsl: TransactionDSL<LastLineShouldTestForVerifiesOrFails, TestTransactionDSLInterpreter>.() -> R,
|
dsl: TransactionDSL<EnforceVerifyOrFail, TestTransactionDSLInterpreter>.() -> R,
|
||||||
transactionMap: HashMap<SecureHash, WireTransactionWithLocation> = HashMap()
|
transactionMap: HashMap<SecureHash, WireTransactionWithLocation> = HashMap()
|
||||||
): WireTransaction {
|
): WireTransaction {
|
||||||
val transactionLocation = getCallerLocation(3)
|
val transactionLocation = getCallerLocation(3)
|
||||||
@ -296,17 +296,17 @@ data class TestLedgerDSLInterpreter private constructor (
|
|||||||
|
|
||||||
override fun transaction(
|
override fun transaction(
|
||||||
transactionLabel: String?,
|
transactionLabel: String?,
|
||||||
dsl: TransactionDSL<LastLineShouldTestForVerifiesOrFails, TestTransactionDSLInterpreter>.() -> LastLineShouldTestForVerifiesOrFails
|
dsl: TransactionDSL<EnforceVerifyOrFail, TestTransactionDSLInterpreter>.() -> EnforceVerifyOrFail
|
||||||
) = recordTransactionWithTransactionMap(transactionLabel, dsl, transactionWithLocations)
|
) = recordTransactionWithTransactionMap(transactionLabel, dsl, transactionWithLocations)
|
||||||
|
|
||||||
override fun unverifiedTransaction(
|
override fun unverifiedTransaction(
|
||||||
transactionLabel: String?,
|
transactionLabel: String?,
|
||||||
dsl: TransactionDSL<LastLineShouldTestForVerifiesOrFails, TestTransactionDSLInterpreter>.() -> Unit
|
dsl: TransactionDSL<EnforceVerifyOrFail, TestTransactionDSLInterpreter>.() -> Unit
|
||||||
) = recordTransactionWithTransactionMap(transactionLabel, dsl, nonVerifiedTransactionWithLocations)
|
) = recordTransactionWithTransactionMap(transactionLabel, dsl, nonVerifiedTransactionWithLocations)
|
||||||
|
|
||||||
override fun tweak(
|
override fun tweak(
|
||||||
dsl: LedgerDSL<LastLineShouldTestForVerifiesOrFails, TestTransactionDSLInterpreter,
|
dsl: LedgerDSL<EnforceVerifyOrFail, TestTransactionDSLInterpreter,
|
||||||
LedgerDSLInterpreter<LastLineShouldTestForVerifiesOrFails, TestTransactionDSLInterpreter>>.() -> Unit) =
|
LedgerDSLInterpreter<EnforceVerifyOrFail, TestTransactionDSLInterpreter>>.() -> Unit) =
|
||||||
dsl(LedgerDSL(copy()))
|
dsl(LedgerDSL(copy()))
|
||||||
|
|
||||||
override fun attachment(attachment: InputStream): SecureHash {
|
override fun attachment(attachment: InputStream): SecureHash {
|
||||||
@ -349,6 +349,6 @@ fun signAll(transactionsToSign: List<WireTransaction>, extraKeys: Array<out KeyP
|
|||||||
SignedTransaction(bits, signatures)
|
SignedTransaction(bits, signatures)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun LedgerDSL<LastLineShouldTestForVerifiesOrFails, TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.signAll(
|
fun LedgerDSL<EnforceVerifyOrFail, TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.signAll(
|
||||||
transactionsToSign: List<WireTransaction> = this.interpreter.wireTransactions, vararg extraKeys: KeyPair) =
|
transactionsToSign: List<WireTransaction> = this.interpreter.wireTransactions, vararg extraKeys: KeyPair) =
|
||||||
signAll(transactionsToSign, extraKeys)
|
signAll(transactionsToSign, extraKeys)
|
||||||
|
@ -93,8 +93,8 @@ object JavaTestHelpers {
|
|||||||
@JvmStatic @JvmOverloads fun ledger(
|
@JvmStatic @JvmOverloads fun ledger(
|
||||||
identityService: IdentityService = MOCK_IDENTITY_SERVICE,
|
identityService: IdentityService = MOCK_IDENTITY_SERVICE,
|
||||||
storageService: StorageService = MockStorageService(),
|
storageService: StorageService = MockStorageService(),
|
||||||
dsl: LedgerDSL<LastLineShouldTestForVerifiesOrFails, TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.() -> Unit
|
dsl: LedgerDSL<EnforceVerifyOrFail, TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.() -> Unit
|
||||||
): LedgerDSL<LastLineShouldTestForVerifiesOrFails, TestTransactionDSLInterpreter, TestLedgerDSLInterpreter> {
|
): LedgerDSL<EnforceVerifyOrFail, TestTransactionDSLInterpreter, TestLedgerDSLInterpreter> {
|
||||||
val ledgerDsl = LedgerDSL(TestLedgerDSLInterpreter(identityService, storageService))
|
val ledgerDsl = LedgerDSL(TestLedgerDSLInterpreter(identityService, storageService))
|
||||||
dsl(ledgerDsl)
|
dsl(ledgerDsl)
|
||||||
return ledgerDsl
|
return ledgerDsl
|
||||||
@ -103,9 +103,9 @@ object JavaTestHelpers {
|
|||||||
@JvmStatic @JvmOverloads fun transaction(
|
@JvmStatic @JvmOverloads fun transaction(
|
||||||
transactionLabel: String? = null,
|
transactionLabel: String? = null,
|
||||||
dsl: TransactionDSL<
|
dsl: TransactionDSL<
|
||||||
LastLineShouldTestForVerifiesOrFails,
|
EnforceVerifyOrFail,
|
||||||
TransactionDSLInterpreter<LastLineShouldTestForVerifiesOrFails>
|
TransactionDSLInterpreter<EnforceVerifyOrFail>
|
||||||
>.() -> LastLineShouldTestForVerifiesOrFails
|
>.() -> EnforceVerifyOrFail
|
||||||
) = ledger { transaction(transactionLabel, dsl) }
|
) = ledger { transaction(transactionLabel, dsl) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,7 +366,7 @@ class TwoPartyTradeProtocolTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun LedgerDSL<LastLineShouldTestForVerifiesOrFails, TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.runWithError(
|
private fun LedgerDSL<EnforceVerifyOrFail, TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.runWithError(
|
||||||
bobError: Boolean,
|
bobError: Boolean,
|
||||||
aliceError: Boolean,
|
aliceError: Boolean,
|
||||||
expectedMessageSubstring: String
|
expectedMessageSubstring: String
|
||||||
@ -431,7 +431,7 @@ class TwoPartyTradeProtocolTests {
|
|||||||
return signed.associateBy { it.id }
|
return signed.associateBy { it.id }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun LedgerDSL<LastLineShouldTestForVerifiesOrFails, TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.fillUpForBuyer(
|
private fun LedgerDSL<EnforceVerifyOrFail, TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.fillUpForBuyer(
|
||||||
withError: Boolean,
|
withError: Boolean,
|
||||||
owner: PublicKey = BOB_PUBKEY,
|
owner: PublicKey = BOB_PUBKEY,
|
||||||
issuer: PartyAndReference = MEGA_CORP.ref(1)): Pair<Wallet, List<WireTransaction>> {
|
issuer: PartyAndReference = MEGA_CORP.ref(1)): Pair<Wallet, List<WireTransaction>> {
|
||||||
@ -472,7 +472,7 @@ class TwoPartyTradeProtocolTests {
|
|||||||
return Pair(wallet, listOf(eb1, bc1, bc2))
|
return Pair(wallet, listOf(eb1, bc1, bc2))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun LedgerDSL<LastLineShouldTestForVerifiesOrFails, TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.fillUpForSeller(
|
private fun LedgerDSL<EnforceVerifyOrFail, TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.fillUpForSeller(
|
||||||
withError: Boolean,
|
withError: Boolean,
|
||||||
owner: PublicKey,
|
owner: PublicKey,
|
||||||
amount: Amount<Issued<Currency>>,
|
amount: Amount<Issued<Currency>>,
|
||||||
|
@ -9,7 +9,7 @@ import org.graphstream.graph.Node
|
|||||||
import org.graphstream.graph.implementations.SingleGraph
|
import org.graphstream.graph.implementations.SingleGraph
|
||||||
import kotlin.reflect.memberProperties
|
import kotlin.reflect.memberProperties
|
||||||
|
|
||||||
class GraphVisualiser(val dsl: LedgerDSL<LastLineShouldTestForVerifiesOrFails, TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>) {
|
class GraphVisualiser(val dsl: LedgerDSL<EnforceVerifyOrFail, TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>) {
|
||||||
companion object {
|
companion object {
|
||||||
val css = GraphVisualiser::class.java.getResourceAsStream("graph.css").bufferedReader().readText()
|
val css = GraphVisualiser::class.java.getResourceAsStream("graph.css").bufferedReader().readText()
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user