added timestamp check

This commit is contained in:
sofusmortensen 2016-08-18 01:11:05 +02:00
parent c3bf914d30
commit d5172ea2d0
3 changed files with 79 additions and 1 deletions

View File

@ -47,6 +47,7 @@ class UniversalContract : Contract {
val actions = actions(inState.details)
requireThat {
"action must be timestamped" by ( tx.timestamp != null )
"action must be defined" by ( actions.containsKey(value.name) )
"action must be authorized" by ( cmd.signers.any { actions[ value.name ]!!.actors.any { party -> party.owningKey == it } } )
"condition must be met" by ( true ) // todo

View File

@ -2,8 +2,10 @@ package com.r3corda.contracts.universal
import com.r3corda.core.testing.DUMMY_NOTARY
import com.r3corda.core.testing.DUMMY_NOTARY_KEY
import com.r3corda.core.testing.TEST_TX_TIME
import com.r3corda.core.testing.transaction
import org.junit.Test
import java.time.Instant
/**
* Created by sofusmortensen on 01/06/16.
@ -11,6 +13,8 @@ import org.junit.Test
class FXSwap {
val TEST_TX_TIME_1: Instant get() = Instant.parse("2017-09-02T12:00:00.00Z")
val contract =
(roadRunner or wileECoyote).may {
"execute".givenThat(after("01/09/2017")) {
@ -25,6 +29,13 @@ class FXSwap {
val outState1 = UniversalContract.State( listOf(DUMMY_NOTARY.owningKey), transfer1 )
val outState2 = UniversalContract.State( listOf(DUMMY_NOTARY.owningKey), transfer2 )
val transferBad1 = arrange { wileECoyote.gives(roadRunner, 1200.K*GBP) } // wrong currency
val transferBad2 = arrange { roadRunner.gives(wileECoyote, 900.K*EUR) } // wrong amount
val transferBad3 = arrange { wileECoyote.gives(wileECoyote, 1.M*EUR) } // wrong party
val outStateBad1 = UniversalContract.State( listOf(DUMMY_NOTARY.owningKey), transferBad1 )
val outStateBad2 = UniversalContract.State( listOf(DUMMY_NOTARY.owningKey), transferBad2 )
val outStateBad3 = UniversalContract.State( listOf(DUMMY_NOTARY.owningKey), transferBad3 )
val inState = UniversalContract.State( listOf(DUMMY_NOTARY.owningKey), contract)
@ -33,6 +44,7 @@ class FXSwap {
transaction {
output { inState }
timestamp(TEST_TX_TIME_1)
this `fails with` "transaction has a single command"
@ -57,6 +69,26 @@ class FXSwap {
input { inState }
output { outState1 }
output { outState2 }
timestamp(TEST_TX_TIME_1)
tweak {
command(wileECoyote.owningKey) { UniversalContract.Commands.Action("some undefined name") }
this `fails with` "action must be defined"
}
command(wileECoyote.owningKey) { UniversalContract.Commands.Action("execute") }
this.verifies()
}
}
@Test
fun `execute - reversed order`() {
transaction {
input { inState }
output { outState2 }
output { outState1 }
timestamp(TEST_TX_TIME_1)
tweak {
command(wileECoyote.owningKey) { UniversalContract.Commands.Action("some undefined name") }
@ -75,6 +107,7 @@ class FXSwap {
input { inState }
output { outState1 }
output { outState2 }
timestamp(TEST_TX_TIME_1)
command(porkyPig.owningKey) { UniversalContract.Commands.Action("execute") }
this `fails with` "action must be authorized"
@ -82,13 +115,53 @@ class FXSwap {
}
@Test
fun `execute - outState mismatch`() {
fun `execute - outState mismatch 1`() {
transaction {
input { inState }
output { outState1 }
timestamp(TEST_TX_TIME_1)
command(roadRunner.owningKey) { UniversalContract.Commands.Action("execute") }
this `fails with` "output state must match action result state"
}
}
@Test
fun `execute - outState mismatch 2`() {
transaction {
input { inState }
output { outState1 }
output { outStateBad2 }
timestamp(TEST_TX_TIME_1)
command(roadRunner.owningKey) { UniversalContract.Commands.Action("execute") }
this `fails with` "output states must match action result state"
}
}
@Test
fun `execute - outState mismatch 3`() {
transaction {
input { inState }
output { outStateBad1 }
output { outState2 }
timestamp(TEST_TX_TIME_1)
command(roadRunner.owningKey) { UniversalContract.Commands.Action("execute") }
this `fails with` "output states must match action result state"
}
}
@Test
fun `execute - outState mismatch 4`() {
transaction {
input { inState }
output { outState1 }
output { outStateBad3 }
timestamp(TEST_TX_TIME_1)
command(roadRunner.owningKey) { UniversalContract.Commands.Action("execute") }
this `fails with` "output states must match action result state"
}
}
}

View File

@ -1,6 +1,7 @@
package com.r3corda.contracts.universal
import com.r3corda.core.testing.DUMMY_NOTARY
import com.r3corda.core.testing.TEST_TX_TIME
import com.r3corda.core.testing.transaction
import org.junit.Test
@ -65,6 +66,7 @@ class ZeroCouponBond {
transaction {
input { inState }
output { outState }
timestamp(TEST_TX_TIME)
tweak {
command(wileECoyote.owningKey) { UniversalContract.Commands.Action("some undefined name") }
@ -82,6 +84,7 @@ class ZeroCouponBond {
transaction {
input { inState }
output { outState }
timestamp(TEST_TX_TIME)
command(porkyPig.owningKey) { UniversalContract.Commands.Action("execute") }
this `fails with` "action must be authorized"
@ -93,6 +96,7 @@ class ZeroCouponBond {
transaction {
input { inState }
output { outStateWrong }
timestamp(TEST_TX_TIME)
command(roadRunner.owningKey) { UniversalContract.Commands.Action("execute") }
this `fails with` "output state must match action result state"