mirror of
https://github.com/corda/corda.git
synced 2024-12-18 20:47:57 +00:00
Cleaned up TimeWindow and added a bit more docs.
This commit is contained in:
parent
bf98f64269
commit
e702025f62
2
.gitignore
vendored
2
.gitignore
vendored
@ -67,7 +67,7 @@ lib/dokka.jar
|
|||||||
## Plugin-specific files:
|
## Plugin-specific files:
|
||||||
|
|
||||||
# IntelliJ
|
# IntelliJ
|
||||||
/out/
|
**/out/
|
||||||
/classes/
|
/classes/
|
||||||
|
|
||||||
# mpeltonen/sbt-idea plugin
|
# mpeltonen/sbt-idea plugin
|
||||||
|
@ -21,7 +21,6 @@ import java.math.BigDecimal
|
|||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.time.temporal.Temporal
|
|
||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
import java.util.concurrent.ExecutionException
|
import java.util.concurrent.ExecutionException
|
||||||
import java.util.concurrent.Future
|
import java.util.concurrent.Future
|
||||||
@ -95,9 +94,6 @@ fun <A> ListenableFuture<out A>.toObservable(): Observable<A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simple infix function to add back null safety that the JDK lacks: timeA until timeB
|
|
||||||
infix fun Temporal.until(endExclusive: Temporal): Duration = Duration.between(this, endExclusive)
|
|
||||||
|
|
||||||
/** Returns the index of the given item or throws [IllegalArgumentException] if not found. */
|
/** Returns the index of the given item or throws [IllegalArgumentException] if not found. */
|
||||||
fun <T> List<T>.indexOfOrThrow(item: T): Int {
|
fun <T> List<T>.indexOfOrThrow(item: T): Int {
|
||||||
val i = indexOf(item)
|
val i = indexOf(item)
|
||||||
|
@ -17,7 +17,6 @@ import java.io.IOException
|
|||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
import java.time.Duration
|
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.util.jar.JarInputStream
|
import java.util.jar.JarInputStream
|
||||||
|
|
||||||
@ -328,63 +327,6 @@ data class AuthenticatedObject<out T : Any>(
|
|||||||
)
|
)
|
||||||
// DOCEND 6
|
// DOCEND 6
|
||||||
|
|
||||||
/**
|
|
||||||
* A time-window is required for validation/notarization purposes.
|
|
||||||
* If present in a transaction, contains a time that was verified by the uniqueness service. The true time must be
|
|
||||||
* between (fromTime, untilTime).
|
|
||||||
* Usually, a time-window is required to have both sides set (fromTime, untilTime).
|
|
||||||
* However, some apps may require that a time-window has a start [Instant] (fromTime), but no end [Instant] (untilTime) and vice versa.
|
|
||||||
* TODO: Consider refactoring using TimeWindow abstraction like TimeWindow.From, TimeWindow.Until, TimeWindow.Between.
|
|
||||||
*/
|
|
||||||
@CordaSerializable
|
|
||||||
class TimeWindow private constructor(
|
|
||||||
/** The time at which this transaction is said to have occurred is after this moment. */
|
|
||||||
val fromTime: Instant?,
|
|
||||||
/** The time at which this transaction is said to have occurred is before this moment. */
|
|
||||||
val untilTime: Instant?
|
|
||||||
) {
|
|
||||||
companion object {
|
|
||||||
/** Use when the left-side [fromTime] of a [TimeWindow] is only required and we don't need an end instant (untilTime). */
|
|
||||||
@JvmStatic
|
|
||||||
fun fromOnly(fromTime: Instant) = TimeWindow(fromTime, null)
|
|
||||||
|
|
||||||
/** Use when the right-side [untilTime] of a [TimeWindow] is only required and we don't need a start instant (fromTime). */
|
|
||||||
@JvmStatic
|
|
||||||
fun untilOnly(untilTime: Instant) = TimeWindow(null, untilTime)
|
|
||||||
|
|
||||||
/** Use when both sides of a [TimeWindow] must be set ([fromTime], [untilTime]). */
|
|
||||||
@JvmStatic
|
|
||||||
fun between(fromTime: Instant, untilTime: Instant): TimeWindow {
|
|
||||||
require(fromTime < untilTime) { "fromTime should be earlier than untilTime" }
|
|
||||||
return TimeWindow(fromTime, untilTime)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Use when we have a start time and a period of validity. */
|
|
||||||
@JvmStatic
|
|
||||||
fun fromStartAndDuration(fromTime: Instant, duration: Duration): TimeWindow = between(fromTime, fromTime + duration)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When we need to create a [TimeWindow] based on a specific time [Instant] and some tolerance in both sides of this instant.
|
|
||||||
* The result will be the following time-window: ([time] - [tolerance], [time] + [tolerance]).
|
|
||||||
*/
|
|
||||||
@JvmStatic
|
|
||||||
fun withTolerance(time: Instant, tolerance: Duration) = between(time - tolerance, time + tolerance)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The midpoint is calculated as fromTime + (untilTime - fromTime)/2. Note that it can only be computed if both sides are set. */
|
|
||||||
val midpoint: Instant get() = fromTime!! + Duration.between(fromTime, untilTime!!).dividedBy(2)
|
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
|
||||||
if (this === other) return true
|
|
||||||
if (other !is TimeWindow) return false
|
|
||||||
return (fromTime == other.fromTime && untilTime == other.untilTime)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun hashCode() = 31 * (fromTime?.hashCode() ?: 0) + (untilTime?.hashCode() ?: 0)
|
|
||||||
|
|
||||||
override fun toString() = "TimeWindow(fromTime=$fromTime, untilTime=$untilTime)"
|
|
||||||
}
|
|
||||||
|
|
||||||
// DOCSTART 5
|
// DOCSTART 5
|
||||||
/**
|
/**
|
||||||
* Implemented by a program that implements business logic on the shared ledger. All participants run this code for
|
* Implemented by a program that implements business logic on the shared ledger. All participants run this code for
|
||||||
|
87
core/src/main/kotlin/net/corda/core/contracts/TimeWindow.kt
Normal file
87
core/src/main/kotlin/net/corda/core/contracts/TimeWindow.kt
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
package net.corda.core.contracts
|
||||||
|
|
||||||
|
import net.corda.core.internal.div
|
||||||
|
import net.corda.core.internal.until
|
||||||
|
import net.corda.core.serialization.CordaSerializable
|
||||||
|
import java.time.Duration
|
||||||
|
import java.time.Instant
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A time-window is required for validation/notarization purposes. If present in a transaction, contains a time that was
|
||||||
|
* verified by the uniqueness service. The true time must be in the time interval `[fromTime, untilTime)`.
|
||||||
|
*
|
||||||
|
* Usually a time-window is required to have both sides defined. However some apps may require a time-window which is
|
||||||
|
* open-ended on one of the two sides.
|
||||||
|
*/
|
||||||
|
@CordaSerializable
|
||||||
|
abstract class TimeWindow {
|
||||||
|
companion object {
|
||||||
|
/** Creates a [TimeWindow] with null [untilTime], i.e. the time interval `[fromTime, ∞]`. [midpoint] will return null. */
|
||||||
|
@JvmStatic
|
||||||
|
fun fromOnly(fromTime: Instant): TimeWindow = From(fromTime)
|
||||||
|
|
||||||
|
/** Creates a [TimeWindow] with null [fromTime], i.e. the time interval `[∞, untilTime)`. [midpoint] will return null. */
|
||||||
|
@JvmStatic
|
||||||
|
fun untilOnly(untilTime: Instant): TimeWindow = Until(untilTime)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a [TimeWindow] with the time interval `[fromTime, untilTime)`. [midpoint] will return
|
||||||
|
* `fromTime + (untilTime - fromTime) / 2`.
|
||||||
|
* @throws IllegalArgumentException If [fromTime] ≥ [untilTime]
|
||||||
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
fun between(fromTime: Instant, untilTime: Instant): TimeWindow = Between(fromTime, untilTime)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a [TimeWindow] with the time interval `[fromTime, fromTime + duration)`. [midpoint] will return
|
||||||
|
* `fromTime + duration / 2`
|
||||||
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
fun fromStartAndDuration(fromTime: Instant, duration: Duration): TimeWindow = between(fromTime, fromTime + duration)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a [TimeWindow] which is centered around [instant] with the given [tolerance] on both sides, i.e the
|
||||||
|
* time interval `[instant - tolerance, instant + tolerance)`. [midpoint] will return [instant].
|
||||||
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
fun withTolerance(instant: Instant, tolerance: Duration) = between(instant - tolerance, instant + tolerance)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the inclusive lower-bound of this [TimeWindow]'s interval, with null implying infinity. */
|
||||||
|
abstract val fromTime: Instant?
|
||||||
|
|
||||||
|
/** Returns the exclusive upper-bound of this [TimeWindow]'s interval, with null implying infinity. */
|
||||||
|
abstract val untilTime: Instant?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the midpoint of [fromTime] and [untilTime] if both are non-null, calculated as
|
||||||
|
* `fromTime + (untilTime - fromTime)/2`, otherwise returns null.
|
||||||
|
*/
|
||||||
|
abstract val midpoint: Instant?
|
||||||
|
|
||||||
|
/** Returns true iff the given [instant] is within the time interval of this [TimeWindow]. */
|
||||||
|
abstract operator fun contains(instant: Instant): Boolean
|
||||||
|
|
||||||
|
private data class From(override val fromTime: Instant) : TimeWindow() {
|
||||||
|
override val untilTime: Instant? get() = null
|
||||||
|
override val midpoint: Instant? get() = null
|
||||||
|
override fun contains(instant: Instant): Boolean = instant >= fromTime
|
||||||
|
override fun toString(): String = "[$fromTime, ∞]"
|
||||||
|
}
|
||||||
|
|
||||||
|
private data class Until(override val untilTime: Instant) : TimeWindow() {
|
||||||
|
override val fromTime: Instant? get() = null
|
||||||
|
override val midpoint: Instant? get() = null
|
||||||
|
override fun contains(instant: Instant): Boolean = instant < untilTime
|
||||||
|
override fun toString(): String = "[∞, $untilTime)"
|
||||||
|
}
|
||||||
|
|
||||||
|
private data class Between(override val fromTime: Instant, override val untilTime: Instant) : TimeWindow() {
|
||||||
|
init {
|
||||||
|
require(fromTime < untilTime) { "fromTime must be earlier than untilTime" }
|
||||||
|
}
|
||||||
|
override val midpoint: Instant get() = fromTime + (fromTime until untilTime) / 2
|
||||||
|
override fun contains(instant: Instant): Boolean = instant >= fromTime && instant < untilTime
|
||||||
|
override fun toString(): String = "[$fromTime, $untilTime)"
|
||||||
|
}
|
||||||
|
}
|
@ -7,9 +7,16 @@ import java.nio.charset.Charset
|
|||||||
import java.nio.charset.StandardCharsets.UTF_8
|
import java.nio.charset.StandardCharsets.UTF_8
|
||||||
import java.nio.file.*
|
import java.nio.file.*
|
||||||
import java.nio.file.attribute.FileAttribute
|
import java.nio.file.attribute.FileAttribute
|
||||||
|
import java.time.Duration
|
||||||
|
import java.time.temporal.Temporal
|
||||||
import java.util.stream.Stream
|
import java.util.stream.Stream
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
infix fun Temporal.until(endExclusive: Temporal): Duration = Duration.between(this, endExclusive)
|
||||||
|
|
||||||
|
operator fun Duration.div(divider: Long): Duration = dividedBy(divider)
|
||||||
|
operator fun Duration.times(multiplicand: Long): Duration = multipliedBy(multiplicand)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows you to write code like: Paths.get("someDir") / "subdir" / "filename" but using the Paths API to avoid platform
|
* Allows you to write code like: Paths.get("someDir") / "subdir" / "filename" but using the Paths API to avoid platform
|
||||||
* separator problems.
|
* separator problems.
|
||||||
|
@ -7,16 +7,5 @@ import java.time.Clock
|
|||||||
* Checks if the current instant provided by the input clock falls within the provided time-window.
|
* Checks if the current instant provided by the input clock falls within the provided time-window.
|
||||||
*/
|
*/
|
||||||
class TimeWindowChecker(val clock: Clock = Clock.systemUTC()) {
|
class TimeWindowChecker(val clock: Clock = Clock.systemUTC()) {
|
||||||
fun isValid(timeWindow: TimeWindow): Boolean {
|
fun isValid(timeWindow: TimeWindow): Boolean = clock.instant() in timeWindow
|
||||||
val fromTime = timeWindow.fromTime
|
|
||||||
val untilTime = timeWindow.untilTime
|
|
||||||
|
|
||||||
val now = clock.instant()
|
|
||||||
|
|
||||||
// We don't need to test for (fromTime == null && untilTime == null) or backwards bounds because the TimeWindow
|
|
||||||
// constructor already checks that.
|
|
||||||
if (fromTime != null && now < fromTime) return false
|
|
||||||
if (untilTime != null && now > untilTime) return false
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,67 @@
|
|||||||
|
package net.corda.core.contracts
|
||||||
|
|
||||||
|
import net.corda.core.utilities.millis
|
||||||
|
import net.corda.core.utilities.minutes
|
||||||
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
|
import org.junit.Test
|
||||||
|
import java.time.Instant
|
||||||
|
import java.time.LocalDate
|
||||||
|
import java.time.ZoneOffset.UTC
|
||||||
|
|
||||||
|
class TimeWindowTest {
|
||||||
|
private val now = Instant.now()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun fromOnly() {
|
||||||
|
val timeWindow = TimeWindow.fromOnly(now)
|
||||||
|
assertThat(timeWindow.fromTime).isEqualTo(now)
|
||||||
|
assertThat(timeWindow.untilTime).isNull()
|
||||||
|
assertThat(timeWindow.midpoint).isNull()
|
||||||
|
assertThat(timeWindow.contains(now - 1.millis)).isFalse()
|
||||||
|
assertThat(timeWindow.contains(now)).isTrue()
|
||||||
|
assertThat(timeWindow.contains(now + 1.millis)).isTrue()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun untilOnly() {
|
||||||
|
val timeWindow = TimeWindow.untilOnly(now)
|
||||||
|
assertThat(timeWindow.fromTime).isNull()
|
||||||
|
assertThat(timeWindow.untilTime).isEqualTo(now)
|
||||||
|
assertThat(timeWindow.midpoint).isNull()
|
||||||
|
assertThat(timeWindow.contains(now - 1.millis)).isTrue()
|
||||||
|
assertThat(timeWindow.contains(now)).isFalse()
|
||||||
|
assertThat(timeWindow.contains(now + 1.millis)).isFalse()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun between() {
|
||||||
|
val today = LocalDate.now()
|
||||||
|
val fromTime = today.atTime(12, 0).toInstant(UTC)
|
||||||
|
val untilTime = today.atTime(12, 30).toInstant(UTC)
|
||||||
|
val timeWindow = TimeWindow.between(fromTime, untilTime)
|
||||||
|
assertThat(timeWindow.fromTime).isEqualTo(fromTime)
|
||||||
|
assertThat(timeWindow.untilTime).isEqualTo(untilTime)
|
||||||
|
assertThat(timeWindow.midpoint).isEqualTo(today.atTime(12, 15).toInstant(UTC))
|
||||||
|
assertThat(timeWindow.contains(fromTime - 1.millis)).isFalse()
|
||||||
|
assertThat(timeWindow.contains(fromTime)).isTrue()
|
||||||
|
assertThat(timeWindow.contains(fromTime + 1.millis)).isTrue()
|
||||||
|
assertThat(timeWindow.contains(untilTime)).isFalse()
|
||||||
|
assertThat(timeWindow.contains(untilTime + 1.millis)).isFalse()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun fromStartAndDuration() {
|
||||||
|
val timeWindow = TimeWindow.fromStartAndDuration(now, 10.minutes)
|
||||||
|
assertThat(timeWindow.fromTime).isEqualTo(now)
|
||||||
|
assertThat(timeWindow.untilTime).isEqualTo(now + 10.minutes)
|
||||||
|
assertThat(timeWindow.midpoint).isEqualTo(now + 5.minutes)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun withTolerance() {
|
||||||
|
val timeWindow = TimeWindow.withTolerance(now, 10.minutes)
|
||||||
|
assertThat(timeWindow.fromTime).isEqualTo(now - 10.minutes)
|
||||||
|
assertThat(timeWindow.untilTime).isEqualTo(now + 10.minutes)
|
||||||
|
assertThat(timeWindow.midpoint).isEqualTo(now)
|
||||||
|
}
|
||||||
|
}
|
@ -5,12 +5,12 @@ import net.corda.core.utilities.seconds
|
|||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.time.Clock
|
import java.time.Clock
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.time.ZoneId
|
import java.time.ZoneOffset
|
||||||
import kotlin.test.assertFalse
|
import kotlin.test.assertFalse
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
class TimeWindowCheckerTests {
|
class TimeWindowCheckerTests {
|
||||||
val clock = Clock.fixed(Instant.now(), ZoneId.systemDefault())
|
val clock: Clock = Clock.fixed(Instant.now(), ZoneOffset.UTC)
|
||||||
val timeWindowChecker = TimeWindowChecker(clock)
|
val timeWindowChecker = TimeWindowChecker(clock)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -72,7 +72,7 @@ data class TradeApprovalContract(override val legalContractReference: SecureHash
|
|||||||
*/
|
*/
|
||||||
override fun verify(tx: LedgerTransaction) {
|
override fun verify(tx: LedgerTransaction) {
|
||||||
val command = tx.commands.requireSingleCommand<TradeApprovalContract.Commands>()
|
val command = tx.commands.requireSingleCommand<TradeApprovalContract.Commands>()
|
||||||
require(tx.timeWindow?.midpoint != null) { "must have a time-window" }
|
requireNotNull(tx.timeWindow) { "must have a time-window" }
|
||||||
when (command.value) {
|
when (command.value) {
|
||||||
is Commands.Issue -> {
|
is Commands.Issue -> {
|
||||||
requireThat {
|
requireThat {
|
||||||
|
@ -2,8 +2,10 @@ package net.corda.services.messaging
|
|||||||
|
|
||||||
import com.google.common.util.concurrent.Futures
|
import com.google.common.util.concurrent.Futures
|
||||||
import com.google.common.util.concurrent.ListenableFuture
|
import com.google.common.util.concurrent.ListenableFuture
|
||||||
import net.corda.core.*
|
|
||||||
import net.corda.core.crypto.random63BitValue
|
import net.corda.core.crypto.random63BitValue
|
||||||
|
import net.corda.core.elapsedTime
|
||||||
|
import net.corda.core.getOrThrow
|
||||||
|
import net.corda.core.internal.times
|
||||||
import net.corda.core.messaging.MessageRecipients
|
import net.corda.core.messaging.MessageRecipients
|
||||||
import net.corda.core.messaging.SingleMessageRecipient
|
import net.corda.core.messaging.SingleMessageRecipient
|
||||||
import net.corda.core.node.services.ServiceInfo
|
import net.corda.core.node.services.ServiceInfo
|
||||||
@ -43,7 +45,7 @@ class P2PMessagingTest : NodeBasedTest() {
|
|||||||
// Start the network map a second time - this will restore message queues from the journal.
|
// Start the network map a second time - this will restore message queues from the journal.
|
||||||
// This will hang and fail prior the fix. https://github.com/corda/corda/issues/37
|
// This will hang and fail prior the fix. https://github.com/corda/corda/issues/37
|
||||||
stopAllNodes()
|
stopAllNodes()
|
||||||
startNodes().getOrThrow(timeout = startUpDuration.multipliedBy(3))
|
startNodes().getOrThrow(timeout = startUpDuration * 3)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/corda/corda/issues/71
|
// https://github.com/corda/corda/issues/71
|
||||||
|
@ -3,12 +3,12 @@ package net.corda.node.utilities
|
|||||||
import co.paralleluniverse.fibers.Suspendable
|
import co.paralleluniverse.fibers.Suspendable
|
||||||
import co.paralleluniverse.strands.SettableFuture
|
import co.paralleluniverse.strands.SettableFuture
|
||||||
import com.google.common.util.concurrent.ListenableFuture
|
import com.google.common.util.concurrent.ListenableFuture
|
||||||
|
import net.corda.core.internal.until
|
||||||
import net.corda.core.then
|
import net.corda.core.then
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import rx.Subscriber
|
import rx.Subscriber
|
||||||
import rx.subscriptions.Subscriptions
|
import rx.subscriptions.Subscriptions
|
||||||
import java.time.Clock
|
import java.time.Clock
|
||||||
import java.time.Duration
|
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.util.concurrent.*
|
import java.util.concurrent.*
|
||||||
import java.util.concurrent.atomic.AtomicLong
|
import java.util.concurrent.atomic.AtomicLong
|
||||||
@ -80,7 +80,7 @@ fun Clock.awaitWithDeadline(deadline: Instant, future: Future<*> = GuavaSettable
|
|||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
nanos = Duration.between(this.instant(), deadline).toNanos()
|
nanos = (instant() until deadline).toNanos()
|
||||||
if (nanos > 0) {
|
if (nanos > 0) {
|
||||||
try {
|
try {
|
||||||
// This will return when it times out, or when the clock mutates or when when the original future completes.
|
// This will return when it times out, or when the clock mutates or when when the original future completes.
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
package net.corda.node.utilities
|
package net.corda.node.utilities
|
||||||
|
|
||||||
|
import net.corda.core.internal.until
|
||||||
import net.corda.core.serialization.SerializeAsToken
|
import net.corda.core.serialization.SerializeAsToken
|
||||||
import net.corda.core.serialization.SerializeAsTokenContext
|
import net.corda.core.serialization.SerializeAsTokenContext
|
||||||
import net.corda.core.serialization.SingletonSerializationToken
|
|
||||||
import net.corda.core.serialization.SingletonSerializationToken.Companion.singletonSerializationToken
|
import net.corda.core.serialization.SingletonSerializationToken.Companion.singletonSerializationToken
|
||||||
import java.time.*
|
import java.time.Clock
|
||||||
|
import java.time.Instant
|
||||||
|
import java.time.LocalDate
|
||||||
|
import java.time.ZoneId
|
||||||
import javax.annotation.concurrent.ThreadSafe
|
import javax.annotation.concurrent.ThreadSafe
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -21,7 +24,7 @@ class TestClock(private var delegateClock: Clock = Clock.systemUTC()) : MutableC
|
|||||||
val currentDate = LocalDate.now(this)
|
val currentDate = LocalDate.now(this)
|
||||||
if (currentDate.isBefore(date)) {
|
if (currentDate.isBefore(date)) {
|
||||||
// It's ok to increment
|
// It's ok to increment
|
||||||
delegateClock = Clock.offset(delegateClock, Duration.between(currentDate.atStartOfDay(), date.atStartOfDay()))
|
delegateClock = Clock.offset(delegateClock, currentDate.atStartOfDay() until date.atStartOfDay())
|
||||||
notifyMutationObservers()
|
notifyMutationObservers()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -522,7 +522,7 @@ class InterestRateSwap : Contract {
|
|||||||
outputs: List<ContractState>,
|
outputs: List<ContractState>,
|
||||||
commands: List<AuthenticatedObject<Commands>>,
|
commands: List<AuthenticatedObject<Commands>>,
|
||||||
groupingKey: Unit?): Set<Commands> {
|
groupingKey: Unit?): Set<Commands> {
|
||||||
require(tx.timeWindow?.midpoint != null) { "must be have a time-window)" }
|
requireNotNull(tx.timeWindow) { "must be have a time-window)" }
|
||||||
// We return an empty set because we don't process any commands
|
// We return an empty set because we don't process any commands
|
||||||
return emptySet()
|
return emptySet()
|
||||||
}
|
}
|
||||||
@ -584,8 +584,7 @@ class InterestRateSwap : Contract {
|
|||||||
"There is only one change in the IRS floating leg payment schedule" using (paymentDifferences.size == 1)
|
"There is only one change in the IRS floating leg payment schedule" using (paymentDifferences.size == 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
val changedRates = paymentDifferences.single().second // Ignore the date of the changed rate (we checked that earlier).
|
val (oldFloatingRatePaymentEvent, newFixedRatePaymentEvent) = paymentDifferences.single().second // Ignore the date of the changed rate (we checked that earlier).
|
||||||
val (oldFloatingRatePaymentEvent, newFixedRatePaymentEvent) = changedRates
|
|
||||||
val fixValue = command.value.fix
|
val fixValue = command.value.fix
|
||||||
// Need to check that everything is the same apart from the new fixed rate entry.
|
// Need to check that everything is the same apart from the new fixed rate entry.
|
||||||
requireThat {
|
requireThat {
|
||||||
|
@ -23,7 +23,7 @@ data class OGTrade(override val legalContractReference: SecureHash = SecureHash.
|
|||||||
outputs: List<ContractState>,
|
outputs: List<ContractState>,
|
||||||
commands: List<AuthenticatedObject<Commands>>,
|
commands: List<AuthenticatedObject<Commands>>,
|
||||||
groupingKey: Unit?): Set<Commands> {
|
groupingKey: Unit?): Set<Commands> {
|
||||||
require(tx.timeWindow?.midpoint != null) { "must have a time-window" }
|
requireNotNull(tx.timeWindow) { "must have a time-window" }
|
||||||
// We return an empty set because we don't process any commands
|
// We return an empty set because we don't process any commands
|
||||||
return emptySet()
|
return emptySet()
|
||||||
}
|
}
|
||||||
@ -43,7 +43,7 @@ data class OGTrade(override val legalContractReference: SecureHash = SecureHash.
|
|||||||
groupingKey: UniqueIdentifier?): Set<Commands> {
|
groupingKey: UniqueIdentifier?): Set<Commands> {
|
||||||
val command = tx.commands.requireSingleCommand<Commands.Agree>()
|
val command = tx.commands.requireSingleCommand<Commands.Agree>()
|
||||||
|
|
||||||
require(inputs.size == 0) { "Inputs must be empty" }
|
require(inputs.isEmpty()) { "Inputs must be empty" }
|
||||||
require(outputs.size == 1) { "" }
|
require(outputs.size == 1) { "" }
|
||||||
require(outputs[0].buyer != outputs[0].seller)
|
require(outputs[0].buyer != outputs[0].seller)
|
||||||
require(outputs[0].participants.containsAll(outputs[0].participants))
|
require(outputs[0].participants.containsAll(outputs[0].participants))
|
||||||
|
@ -25,7 +25,7 @@ data class PortfolioSwap(override val legalContractReference: SecureHash = Secur
|
|||||||
outputs: List<ContractState>,
|
outputs: List<ContractState>,
|
||||||
commands: List<AuthenticatedObject<Commands>>,
|
commands: List<AuthenticatedObject<Commands>>,
|
||||||
groupingKey: Unit?): Set<Commands> {
|
groupingKey: Unit?): Set<Commands> {
|
||||||
require(tx.timeWindow?.midpoint != null) { "must have a time-window)" }
|
requireNotNull(tx.timeWindow) { "must have a time-window)" }
|
||||||
// We return an empty set because we don't process any commands
|
// We return an empty set because we don't process any commands
|
||||||
return emptySet()
|
return emptySet()
|
||||||
}
|
}
|
||||||
@ -69,7 +69,7 @@ data class PortfolioSwap(override val legalContractReference: SecureHash = Secur
|
|||||||
val command = tx.commands.requireSingleCommand<Commands.Agree>()
|
val command = tx.commands.requireSingleCommand<Commands.Agree>()
|
||||||
|
|
||||||
requireThat {
|
requireThat {
|
||||||
"there are no inputs" using (inputs.size == 0)
|
"there are no inputs" using (inputs.isEmpty())
|
||||||
"there is one output" using (outputs.size == 1)
|
"there is one output" using (outputs.size == 1)
|
||||||
"valuer must be a party" using (outputs[0].participants.contains(outputs[0].valuer))
|
"valuer must be a party" using (outputs[0].participants.contains(outputs[0].valuer))
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import net.corda.core.crypto.appendToCommonName
|
|||||||
import net.corda.core.crypto.commonName
|
import net.corda.core.crypto.commonName
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
import net.corda.core.internal.div
|
import net.corda.core.internal.div
|
||||||
|
import net.corda.core.internal.times
|
||||||
import net.corda.core.messaging.CordaRPCOps
|
import net.corda.core.messaging.CordaRPCOps
|
||||||
import net.corda.core.node.NodeInfo
|
import net.corda.core.node.NodeInfo
|
||||||
import net.corda.core.node.services.ServiceInfo
|
import net.corda.core.node.services.ServiceInfo
|
||||||
@ -348,7 +349,7 @@ fun <A> poll(
|
|||||||
override fun run() {
|
override fun run() {
|
||||||
if (resultFuture.isCancelled) return // Give up, caller can no longer get the result.
|
if (resultFuture.isCancelled) return // Give up, caller can no longer get the result.
|
||||||
if (++counter == warnCount) {
|
if (++counter == warnCount) {
|
||||||
log.warn("Been polling $pollName for ${pollInterval.multipliedBy(warnCount.toLong()).seconds} seconds...")
|
log.warn("Been polling $pollName for ${(pollInterval * warnCount.toLong()).seconds} seconds...")
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
val checkResult = check()
|
val checkResult = check()
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package net.corda.testing.node
|
package net.corda.testing.node
|
||||||
|
|
||||||
|
import net.corda.core.internal.until
|
||||||
import net.corda.core.serialization.SerializeAsToken
|
import net.corda.core.serialization.SerializeAsToken
|
||||||
import net.corda.core.serialization.SerializeAsTokenContext
|
import net.corda.core.serialization.SerializeAsTokenContext
|
||||||
import net.corda.core.serialization.SingletonSerializationToken
|
|
||||||
import net.corda.core.serialization.SingletonSerializationToken.Companion.singletonSerializationToken
|
import net.corda.core.serialization.SingletonSerializationToken.Companion.singletonSerializationToken
|
||||||
import net.corda.node.utilities.MutableClock
|
import net.corda.node.utilities.MutableClock
|
||||||
import java.time.Clock
|
import java.time.Clock
|
||||||
@ -35,7 +35,7 @@ class TestClock(private var delegateClock: Clock = Clock.systemUTC()) : MutableC
|
|||||||
*
|
*
|
||||||
* This will only be approximate due to the time ticking away, but will be some time shortly after the requested [Instant].
|
* This will only be approximate due to the time ticking away, but will be some time shortly after the requested [Instant].
|
||||||
*/
|
*/
|
||||||
@Synchronized fun setTo(newInstant: Instant) = advanceBy(Duration.between(instant(), newInstant))
|
@Synchronized fun setTo(newInstant: Instant) = advanceBy(instant() until newInstant)
|
||||||
|
|
||||||
@Synchronized override fun instant(): Instant {
|
@Synchronized override fun instant(): Instant {
|
||||||
return delegateClock.instant()
|
return delegateClock.instant()
|
||||||
|
@ -5,7 +5,7 @@ import com.google.common.util.concurrent.RateLimiter
|
|||||||
import com.google.common.util.concurrent.SettableFuture
|
import com.google.common.util.concurrent.SettableFuture
|
||||||
import net.corda.core.catch
|
import net.corda.core.catch
|
||||||
import net.corda.core.utilities.minutes
|
import net.corda.core.utilities.minutes
|
||||||
import net.corda.core.until
|
import net.corda.core.internal.until
|
||||||
import net.corda.core.utilities.loggerFor
|
import net.corda.core.utilities.loggerFor
|
||||||
import net.corda.demobench.model.NodeConfig
|
import net.corda.demobench.model.NodeConfig
|
||||||
import net.corda.demobench.readErrorLines
|
import net.corda.demobench.readErrorLines
|
||||||
|
Loading…
Reference in New Issue
Block a user