mirror of
https://github.com/corda/corda.git
synced 2024-12-18 20:47:57 +00:00
Add message to uses of require(...) (#4192)
This commit is contained in:
parent
51e66af2fd
commit
8f463c46a9
@ -3,7 +3,7 @@
|
||||
package net.corda.client.jackson.internal
|
||||
|
||||
import com.fasterxml.jackson.annotation.*
|
||||
import com.fasterxml.jackson.annotation.JsonCreator.Mode.*
|
||||
import com.fasterxml.jackson.annotation.JsonCreator.Mode.DISABLED
|
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include
|
||||
import com.fasterxml.jackson.core.JsonGenerator
|
||||
import com.fasterxml.jackson.core.JsonParseException
|
||||
@ -38,7 +38,10 @@ import net.corda.core.utilities.NetworkHostAndPort
|
||||
import net.corda.core.utilities.parseAsHex
|
||||
import net.corda.core.utilities.toHexString
|
||||
import net.corda.serialization.internal.AllWhitelist
|
||||
import net.corda.serialization.internal.amqp.*
|
||||
import net.corda.serialization.internal.amqp.SerializerFactoryBuilder
|
||||
import net.corda.serialization.internal.amqp.constructorForDeserialization
|
||||
import net.corda.serialization.internal.amqp.hasCordaSerializable
|
||||
import net.corda.serialization.internal.amqp.propertiesForSerialization
|
||||
import java.math.BigDecimal
|
||||
import java.security.PublicKey
|
||||
import java.security.cert.CertPath
|
||||
@ -327,11 +330,11 @@ private class PartialTreeJson(val includedLeaf: SecureHash? = null,
|
||||
val right: PartialTreeJson? = null) {
|
||||
init {
|
||||
if (includedLeaf != null) {
|
||||
require(leaf == null && left == null && right == null)
|
||||
require(leaf == null && left == null && right == null) { "Invalid JSON structure" }
|
||||
} else if (leaf != null) {
|
||||
require(left == null && right == null)
|
||||
require(left == null && right == null) { "Invalid JSON structure" }
|
||||
} else {
|
||||
require(left != null && right != null)
|
||||
require(left != null && right != null) { "Invalid JSON structure" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -202,7 +202,7 @@ class NodeMonitorModel : AutoCloseable {
|
||||
val _connection = client.start(username, password)
|
||||
// Check connection is truly operational before returning it.
|
||||
val nodeInfo = _connection.proxy.nodeInfo()
|
||||
require(nodeInfo.legalIdentitiesAndCerts.isNotEmpty())
|
||||
require(nodeInfo.legalIdentitiesAndCerts.isNotEmpty()){"No identity certificates found"}
|
||||
_connection
|
||||
} catch (exception: Exception) {
|
||||
if (shouldRetry) {
|
||||
|
@ -126,7 +126,7 @@ interface Validated<TARGET, ERROR> {
|
||||
*/
|
||||
class Unsuccessful<TARGET, ERROR>(override val errors: Set<ERROR>) : Result<TARGET, ERROR>(), Validated<TARGET, ERROR> {
|
||||
init {
|
||||
require(errors.isNotEmpty())
|
||||
require(errors.isNotEmpty()) { "No errors encountered during validation" }
|
||||
}
|
||||
|
||||
override fun value(exceptionOnErrors: (Set<ERROR>) -> Exception) = throw exceptionOnErrors.invoke(errors)
|
||||
|
@ -40,14 +40,14 @@ class CompositeKey private constructor(val threshold: Int, children: List<NodeAn
|
||||
|
||||
fun getInstance(asn1: ASN1Primitive): PublicKey {
|
||||
val keyInfo = SubjectPublicKeyInfo.getInstance(asn1)
|
||||
require(keyInfo.algorithm.algorithm == CordaObjectIdentifier.COMPOSITE_KEY)
|
||||
require(keyInfo.algorithm.algorithm == CordaObjectIdentifier.COMPOSITE_KEY) { "Key must be composite" }
|
||||
val sequence = ASN1Sequence.getInstance(keyInfo.parsePublicKey())
|
||||
val threshold = ASN1Integer.getInstance(sequence.getObjectAt(0)).positiveValue.toInt()
|
||||
val sequenceOfChildren = ASN1Sequence.getInstance(sequence.getObjectAt(1))
|
||||
val builder = Builder()
|
||||
val listOfChildren = sequenceOfChildren.objects.toList()
|
||||
listOfChildren.forEach { childAsn1 ->
|
||||
require(childAsn1 is ASN1Sequence)
|
||||
require(childAsn1 is ASN1Sequence) { "Child key is not in ASN1 format" }
|
||||
val childSeq = childAsn1 as ASN1Sequence
|
||||
val key = Crypto.decodePublicKey((childSeq.getObjectAt(0) as DERBitString).bytes)
|
||||
val weight = ASN1Integer.getInstance(childSeq.getObjectAt(1))
|
||||
@ -274,7 +274,7 @@ class CompositeKey private constructor(val threshold: Int, children: List<NodeAn
|
||||
* is invalid (for example it would contain no keys).
|
||||
*/
|
||||
fun build(threshold: Int? = null): PublicKey {
|
||||
require(threshold == null || threshold > 0)
|
||||
require(threshold == null || threshold > 0) { "Threshold must not be specified or its value must be greater than zero" }
|
||||
val n = children.size
|
||||
return when {
|
||||
n > 1 -> CompositeKey(threshold ?: children.map { (_, weight) -> weight }.sum(), children)
|
||||
|
@ -19,7 +19,7 @@ sealed class SecureHash(bytes: ByteArray) : OpaqueBytes(bytes) {
|
||||
/** SHA-256 is part of the SHA-2 hash function family. Generated hash is fixed size, 256-bits (32-bytes). */
|
||||
class SHA256(bytes: ByteArray) : SecureHash(bytes) {
|
||||
init {
|
||||
require(bytes.size == 32)
|
||||
require(bytes.size == 32) { "Invalid hash size, must be 32 bytes" }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ val cordaBouncyCastleProvider = BouncyCastleProvider().apply {
|
||||
Security.addProvider(it)
|
||||
}
|
||||
val bouncyCastlePQCProvider = BouncyCastlePQCProvider().apply {
|
||||
require(name == "BCPQC") // The constant it comes from is not final.
|
||||
require(name == "BCPQC") { "Invalid PQCProvider name" }
|
||||
}.also {
|
||||
Security.addProvider(it)
|
||||
}
|
||||
|
@ -5,7 +5,10 @@ package net.corda.core.internal
|
||||
import net.corda.core.DeleteForDJVM
|
||||
import net.corda.core.KeepForDJVM
|
||||
import net.corda.core.crypto.*
|
||||
import net.corda.core.serialization.*
|
||||
import net.corda.core.serialization.SerializationDefaults
|
||||
import net.corda.core.serialization.SerializedBytes
|
||||
import net.corda.core.serialization.deserialize
|
||||
import net.corda.core.serialization.serialize
|
||||
import net.corda.core.utilities.OpaqueBytes
|
||||
import net.corda.core.utilities.UntrustworthyData
|
||||
import org.slf4j.Logger
|
||||
@ -109,7 +112,7 @@ fun <T> List<T>.randomOrNull(): T? {
|
||||
/** Returns the index of the given item or throws [IllegalArgumentException] if not found. */
|
||||
fun <T> List<T>.indexOfOrThrow(item: T): Int {
|
||||
val i = indexOf(item)
|
||||
require(i != -1)
|
||||
require(i != -1){"No such element"}
|
||||
return i
|
||||
}
|
||||
|
||||
@ -219,7 +222,7 @@ data class InputStreamAndHash(val inputStream: InputStream, val sha256: SecureHa
|
||||
*/
|
||||
@DeleteForDJVM
|
||||
fun createInMemoryTestZip(numOfExpectedBytes: Int, content: Byte): InputStreamAndHash {
|
||||
require(numOfExpectedBytes > 0)
|
||||
require(numOfExpectedBytes > 0){"Expected bytes must be greater than zero"}
|
||||
val baos = ByteArrayOutputStream()
|
||||
ZipOutputStream(baos).use { zos ->
|
||||
val arraySize = 1024
|
||||
|
@ -14,8 +14,8 @@ interface NamedCacheFactory {
|
||||
* the name can be used to create a file name or a metric name.
|
||||
*/
|
||||
fun checkCacheName(name: String) {
|
||||
require(!name.isBlank())
|
||||
require(allowedChars.matches(name))
|
||||
require(!name.isBlank()){"Name must not be empty or only whitespace"}
|
||||
require(allowedChars.matches(name)){"Invalid characters in cache name"}
|
||||
}
|
||||
|
||||
fun <K, V> buildNamed(caffeine: Caffeine<in K, in V>, name: String): Cache<K, V>
|
||||
|
@ -9,7 +9,7 @@ class AddressBindingException(val addresses: Set<NetworkHostAndPort>) : CordaRun
|
||||
|
||||
private companion object {
|
||||
private fun message(addresses: Set<NetworkHostAndPort>): String {
|
||||
require(addresses.isNotEmpty())
|
||||
require(addresses.isNotEmpty()) { "Address list must not be empty" }
|
||||
return if (addresses.size > 1) {
|
||||
"Failed to bind on an address in ${addresses.joinToString(", ", "[", "]")}."
|
||||
} else {
|
||||
|
@ -68,8 +68,8 @@ sealed class ByteSequence(private val _bytes: ByteArray, val offset: Int, val si
|
||||
* This method cannot be used to get bytes before [offset] or after [offset]+[size], and never makes a new array.
|
||||
*/
|
||||
fun slice(start: Int = 0, end: Int = size): ByteBuffer {
|
||||
require(start >= 0)
|
||||
require(end >= 0)
|
||||
require(start >= 0) { "Starting index must be greater than or equal to 0" }
|
||||
require(end >= 0){"End index must be greater or equal to 0"}
|
||||
val clampedStart = min(start, size)
|
||||
val clampedEnd = min(end, size)
|
||||
return ByteBuffer.wrap(_bytes, offset + clampedStart, max(0, clampedEnd - clampedStart)).asReadOnlyBuffer()
|
||||
@ -155,7 +155,7 @@ open class OpaqueBytes(bytes: ByteArray) : ByteSequence(bytes, 0, bytes.size) {
|
||||
}
|
||||
|
||||
init {
|
||||
require(bytes.isNotEmpty())
|
||||
require(bytes.isNotEmpty()) { "Byte Array must not be empty" }
|
||||
}
|
||||
|
||||
/**
|
||||
@ -193,7 +193,7 @@ fun String.parseAsHex(): ByteArray = DatatypeConverter.parseHexBinary(this)
|
||||
@KeepForDJVM
|
||||
class OpaqueBytesSubSequence(override val bytes: ByteArray, offset: Int, size: Int) : ByteSequence(bytes, offset, size) {
|
||||
init {
|
||||
require(offset >= 0 && offset < bytes.size)
|
||||
require(size >= 0 && offset + size <= bytes.size)
|
||||
require(offset >= 0 && offset < bytes.size) { "Offset must be greater than or equal to 0, and less than the size of the backing array" }
|
||||
require(size >= 0 && offset + size <= bytes.size) { "Sub-sequence size must be greater than or equal to 0, and less than the size of the backing array" }
|
||||
}
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ class StatusTransitions<out S, in R, T : StatusTrackingContractState<S, R>>(priv
|
||||
// for each combination of in x out which should normally be at most 1...
|
||||
inputStates.forEach { inp ->
|
||||
outputStates.forEach { outp ->
|
||||
require(inp != null || outp != null)
|
||||
require(inp != null || outp != null) { "Input and output states cannot be both left unspecified" }
|
||||
val options = matchingTransitions(inp?.status, outp?.status, cmd.value)
|
||||
|
||||
val signerGroup = options.groupBy { it.signer }.entries.singleOrNull()
|
||||
|
@ -203,7 +203,7 @@ class UniversalContract : Contract {
|
||||
val rest = extractRemainder(arr, action)
|
||||
|
||||
// for now - let's assume not
|
||||
require(rest is Zero)
|
||||
require(rest is Zero) { "Remainder must be zero" }
|
||||
|
||||
requireThat {
|
||||
"action must have a time-window" using (tx.timeWindow != null)
|
||||
|
@ -321,7 +321,7 @@ open class BusinessCalendar(val holidayDates: List<LocalDate>) {
|
||||
* TODO: Make more efficient if necessary
|
||||
*/
|
||||
fun moveBusinessDays(date: LocalDate, direction: DateRollDirection, i: Int): LocalDate {
|
||||
require(i >= 0)
|
||||
require(i >= 0){"Days to add/subtract must be positive"}
|
||||
if (i == 0) return date
|
||||
var retDate = date
|
||||
var ctr = 0
|
||||
|
@ -39,8 +39,8 @@ private fun rowsToAmount(currency: Currency, rows: Vault.Page<FungibleAsset<*>>)
|
||||
return if (rows.otherResults.isEmpty()) {
|
||||
Amount(0L, currency)
|
||||
} else {
|
||||
require(rows.otherResults.size == 2)
|
||||
require(rows.otherResults[1] == currency.currencyCode)
|
||||
require(rows.otherResults.size == 2){"Invalid number of rows returned by query"}
|
||||
require(rows.otherResults[1] == currency.currencyCode){"Currency on rows returned by query does not match expected"}
|
||||
val quantity = rows.otherResults[0] as Long
|
||||
Amount(quantity, currency)
|
||||
}
|
||||
|
@ -298,7 +298,7 @@ abstract class OnLedgerAsset<T : Any, out C : CommandData, S : FungibleAsset<T>>
|
||||
issueCommand: CommandData): Set<PublicKey> {
|
||||
check(tx.inputStates().isEmpty())
|
||||
check(tx.outputStates().map { it.data }.filterIsInstance(transactionState.javaClass).isEmpty())
|
||||
require(transactionState.data.amount.quantity > 0)
|
||||
require(transactionState.data.amount.quantity > 0){"Amount to issue must be greater than zero"}
|
||||
val at = transactionState.data.amount.token.issuer
|
||||
val commandSigner = at.party.owningKey
|
||||
tx.addOutputState(transactionState)
|
||||
|
@ -140,8 +140,8 @@ object TwoPartyDealFlow {
|
||||
// Verify the transaction identities represent the correct parties
|
||||
val wellKnownOtherParty = serviceHub.identityService.wellKnownPartyFromAnonymous(it.primaryIdentity)
|
||||
val wellKnownMe = serviceHub.identityService.wellKnownPartyFromAnonymous(it.secondaryIdentity)
|
||||
require(wellKnownOtherParty == otherSideSession.counterparty)
|
||||
require(wellKnownMe == ourIdentity)
|
||||
require(wellKnownOtherParty == otherSideSession.counterparty){"Well known party for handshake identity ${it.primaryIdentity} does not match counterparty"}
|
||||
require(wellKnownMe == ourIdentity){"Well known party for handshake identity ${it.secondaryIdentity} does not match ourIdentity"}
|
||||
validateHandshake(it)
|
||||
}
|
||||
}
|
||||
|
@ -203,7 +203,7 @@ object TwoPartyTradeFlow {
|
||||
// The asset must either be owned by the well known identity of the counterparty, or we must be able to
|
||||
// prove the owner is a confidential identity of the counterparty.
|
||||
val assetForSaleIdentity = serviceHub.identityService.wellKnownPartyFromAnonymous(asset.owner)
|
||||
require(assetForSaleIdentity == sellerSession.counterparty)
|
||||
require(assetForSaleIdentity == sellerSession.counterparty){"Well known identity lookup returned identity that does not match counterparty"}
|
||||
|
||||
// Register the identity we're about to send payment to. This shouldn't be the same as the asset owner
|
||||
// identity, so that anonymity is enforced.
|
||||
|
@ -9,8 +9,8 @@ data class ScreenCoordinate(val screenX: Double, val screenY: Double)
|
||||
@CordaSerializable
|
||||
data class WorldCoordinate(val latitude: Double, val longitude: Double) {
|
||||
init {
|
||||
require(latitude in -90..90)
|
||||
require(longitude in -180..180)
|
||||
require(latitude in -90..90){"Latitude must be between -90 and +90"}
|
||||
require(longitude in -180..180){"Longitude must be between -180 and +180"}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -24,8 +24,8 @@ data class WorldCoordinate(val latitude: Double, val longitude: Double) {
|
||||
@Suppress("unused") // Used from the visualiser GUI.
|
||||
fun project(screenWidth: Double, screenHeight: Double, topLatitude: Double, bottomLatitude: Double,
|
||||
leftLongitude: Double, rightLongitude: Double): ScreenCoordinate {
|
||||
require(latitude in bottomLatitude..topLatitude)
|
||||
require(longitude in leftLongitude..rightLongitude)
|
||||
require(latitude in bottomLatitude..topLatitude){"Latitude must be between $bottomLatitude and $topLatitude"}
|
||||
require(longitude in leftLongitude..rightLongitude){"Longitude must be between $leftLongitude and $rightLongitude"}
|
||||
|
||||
fun deg2rad(deg: Double) = deg * Math.PI / 180.0
|
||||
val leftLngRad = deg2rad(leftLongitude)
|
||||
|
@ -47,7 +47,7 @@ object DevIdentityGenerator {
|
||||
|
||||
/** Generates a CFT notary identity, where the entire cluster shares a key pair. */
|
||||
fun generateDistributedNotarySingularIdentity(dirs: List<Path>, notaryName: CordaX500Name): Party {
|
||||
require(dirs.isNotEmpty())
|
||||
require(dirs.isNotEmpty()){"At least one directory to generate identity for must be specified"}
|
||||
|
||||
log.trace { "Generating singular identity \"$notaryName\" for nodes: ${dirs.joinToString()}" }
|
||||
|
||||
@ -63,7 +63,7 @@ object DevIdentityGenerator {
|
||||
|
||||
/** Generates a BFT notary identity: individual key pairs for each cluster member, and a shared composite key. */
|
||||
fun generateDistributedNotaryCompositeIdentity(dirs: List<Path>, notaryName: CordaX500Name, threshold: Int = 1): Party {
|
||||
require(dirs.isNotEmpty())
|
||||
require(dirs.isNotEmpty()){"At least one directory to generate identity for must be specified"}
|
||||
|
||||
log.trace { "Generating composite identity \"$notaryName\" for nodes: ${dirs.joinToString()}" }
|
||||
|
||||
|
@ -254,7 +254,7 @@ object X509Utilities {
|
||||
crlIssuer: X500Name? = null): X509Certificate {
|
||||
val builder = createPartialCertificate(certificateType, issuer, issuerPublicKey, subject, subjectPublicKey, validityWindow, nameConstraints, crlDistPoint, crlIssuer)
|
||||
return builder.build(issuerSigner).run {
|
||||
require(isValidOn(Date()))
|
||||
require(isValidOn(Date())){"Certificate is not valid at instant now"}
|
||||
toJca()
|
||||
}
|
||||
}
|
||||
@ -292,8 +292,8 @@ object X509Utilities {
|
||||
crlDistPoint,
|
||||
crlIssuer)
|
||||
return builder.build(signer).run {
|
||||
require(isValidOn(Date()))
|
||||
require(isSignatureValid(JcaContentVerifierProviderBuilder().build(issuerKeyPair.public)))
|
||||
require(isValidOn(Date())){"Certificate is not valid at instant now"}
|
||||
require(isSignatureValid(JcaContentVerifierProviderBuilder().build(issuerKeyPair.public))){"Invalid signature"}
|
||||
toJca()
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ private class MultiplexingReactiveArtemisConsumer(private val queueNames: Set<St
|
||||
override fun start() {
|
||||
|
||||
synchronized(this) {
|
||||
require(!startedFlag)
|
||||
require(!startedFlag) { "Must not be started" }
|
||||
connect()
|
||||
startedFlag = true
|
||||
}
|
||||
@ -59,7 +59,7 @@ private class MultiplexingReactiveArtemisConsumer(private val queueNames: Set<St
|
||||
override fun connect() {
|
||||
|
||||
synchronized(this) {
|
||||
require(!connected)
|
||||
require(!connected) { "Must not be connected" }
|
||||
queueNames.forEach { queue ->
|
||||
createSession().apply {
|
||||
start()
|
||||
|
@ -72,8 +72,9 @@ class ImmutableClassSerializer<T : Any>(val klass: KClass<T>) : Serializer<T>()
|
||||
val constructor = klass.primaryConstructor!!
|
||||
|
||||
init {
|
||||
// Verify that this class is immutable (all properties are final)
|
||||
require(props.none { it is KMutableProperty<*> })
|
||||
props.forEach {
|
||||
require(it !is KMutableProperty<*>) { "$it mutable property of class: ${klass} is unsupported" }
|
||||
}
|
||||
}
|
||||
|
||||
// Just a utility to help us catch cases where nodes are running out of sync versions.
|
||||
|
@ -265,8 +265,8 @@ data class SecurityConfiguration(val authService: SecurityConfiguration.AuthServ
|
||||
val users: List<User>? = null) {
|
||||
init {
|
||||
when (type) {
|
||||
AuthDataSourceType.INMEMORY -> require(users != null && connection == null)
|
||||
AuthDataSourceType.DB -> require(users == null && connection != null)
|
||||
AuthDataSourceType.INMEMORY -> require(users != null && connection == null) { "In-memory authentication must specify a user list, and must not configure a database" }
|
||||
AuthDataSourceType.DB -> require(users == null && connection != null) { "Database-backed authentication must not specify a user list, and must configure a database" }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -569,7 +569,7 @@ private class P2PMessagingConsumer(
|
||||
override fun start() {
|
||||
|
||||
synchronized(this) {
|
||||
require(!startedFlag)
|
||||
require(!startedFlag){"Must not already be started"}
|
||||
drainingModeWasChangedEvents.filter { change -> change.switchedOn() }.doOnNext { initialAndExistingConsumer.switchTo(existingOnlyConsumer) }.subscribe()
|
||||
drainingModeWasChangedEvents.filter { change -> change.switchedOff() }.doOnNext { existingOnlyConsumer.switchTo(initialAndExistingConsumer) }.subscribe()
|
||||
subscriptions += existingOnlyConsumer.messages.doOnNext(messages::onNext).subscribe()
|
||||
|
@ -253,7 +253,7 @@ class RPCServer(
|
||||
private fun bindingRemovalArtemisMessageHandler(artemisMessage: ClientMessage) {
|
||||
lifeCycle.requireState(State.STARTED)
|
||||
val notificationType = artemisMessage.getStringProperty(ManagementHelper.HDR_NOTIFICATION_TYPE)
|
||||
require(notificationType == CoreNotificationType.BINDING_REMOVED.name)
|
||||
require(notificationType == CoreNotificationType.BINDING_REMOVED.name){"Message contained notification type of $notificationType instead of expected ${CoreNotificationType.BINDING_REMOVED.name}"}
|
||||
val clientAddress = artemisMessage.getStringProperty(ManagementHelper.HDR_ROUTING_NAME)
|
||||
log.warn("Detected RPC client disconnect on address $clientAddress, scheduling for reaping")
|
||||
invalidateClient(SimpleString(clientAddress))
|
||||
@ -262,7 +262,7 @@ class RPCServer(
|
||||
private fun bindingAdditionArtemisMessageHandler(artemisMessage: ClientMessage) {
|
||||
lifeCycle.requireState(State.STARTED)
|
||||
val notificationType = artemisMessage.getStringProperty(ManagementHelper.HDR_NOTIFICATION_TYPE)
|
||||
require(notificationType == CoreNotificationType.BINDING_ADDED.name)
|
||||
require(notificationType == CoreNotificationType.BINDING_ADDED.name){"Message contained notification type of $notificationType instead of expected ${CoreNotificationType.BINDING_ADDED.name}"}
|
||||
val clientAddress = SimpleString(artemisMessage.getStringProperty(ManagementHelper.HDR_ROUTING_NAME))
|
||||
log.debug("RPC client queue created on address $clientAddress")
|
||||
|
||||
|
@ -300,7 +300,7 @@ class NodeAttachmentService(
|
||||
private fun import(jar: InputStream, uploader: String?, filename: String?): AttachmentId {
|
||||
return database.transaction {
|
||||
withContractsInJar(jar) { contractClassNames, inputStream ->
|
||||
require(inputStream !is JarInputStream)
|
||||
require(inputStream !is JarInputStream){"Input stream must not be a JarInputStream"}
|
||||
|
||||
// Read the file into RAM and then calculate its hash. The attachment must fit into memory.
|
||||
// TODO: Switch to a two-phase insert so we can handle attachments larger than RAM.
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.corda.node.services.statemachine
|
||||
|
||||
import co.paralleluniverse.strands.concurrent.AbstractQueuedSynchronizer
|
||||
import co.paralleluniverse.fibers.Suspendable
|
||||
import co.paralleluniverse.strands.concurrent.AbstractQueuedSynchronizer
|
||||
|
||||
/**
|
||||
* Quasar-compatible latch that may be incremented.
|
||||
@ -56,7 +56,7 @@ class CountUpDownLatch(initialValue: Int) {
|
||||
}
|
||||
|
||||
fun countDown(number: Int = 1) {
|
||||
require(number > 0)
|
||||
require(number > 0){"Number to count down by must be greater than 0"}
|
||||
sync.releaseShared(number)
|
||||
}
|
||||
|
||||
|
@ -193,7 +193,7 @@ class FlowStateMachineImpl<R>(override val id: StateMachineRunId,
|
||||
"Transaction context is missing. This might happen if a suspendable method is not annotated with @Suspendable annotation."
|
||||
}
|
||||
} else {
|
||||
require(contextTransactionOrNull == null)
|
||||
require(contextTransactionOrNull == null){"Transaction is marked as not present, but is not null"}
|
||||
}
|
||||
}
|
||||
|
||||
@ -388,7 +388,7 @@ class FlowStateMachineImpl<R>(override val id: StateMachineRunId,
|
||||
isDbTransactionOpenOnEntry = true,
|
||||
isDbTransactionOpenOnExit = false
|
||||
)
|
||||
require(continuation == FlowContinuation.ProcessEvents)
|
||||
require(continuation == FlowContinuation.ProcessEvents){"Expected a continuation of type ${FlowContinuation.ProcessEvents}, found $continuation "}
|
||||
unpark(SERIALIZER_BLOCKER)
|
||||
}
|
||||
return uncheckedCast(processEventsUntilFlowIsResumed(
|
||||
|
@ -172,7 +172,7 @@ class SingleThreadedStateMachineManager(
|
||||
* @param allowedUnsuspendedFiberCount Optional parameter is used in some tests.
|
||||
*/
|
||||
override fun stop(allowedUnsuspendedFiberCount: Int) {
|
||||
require(allowedUnsuspendedFiberCount >= 0)
|
||||
require(allowedUnsuspendedFiberCount >= 0){"allowedUnsuspendedFiberCount must be greater than or equal to zero"}
|
||||
mutex.locked {
|
||||
if (stopping) throw IllegalStateException("Already stopping!")
|
||||
stopping = true
|
||||
@ -775,10 +775,10 @@ class SingleThreadedStateMachineManager(
|
||||
) {
|
||||
drainFlowEventQueue(flow)
|
||||
// final sanity checks
|
||||
require(lastState.pendingDeduplicationHandlers.isEmpty())
|
||||
require(lastState.isRemoved)
|
||||
require(lastState.checkpoint.subFlowStack.size == 1)
|
||||
require(flow.fiber.id !in sessionToFlow.values)
|
||||
require(lastState.pendingDeduplicationHandlers.isEmpty()) { "Flow cannot be removed until all pending deduplications have completed" }
|
||||
require(lastState.isRemoved) { "Flow must be in removable state before removal" }
|
||||
require(lastState.checkpoint.subFlowStack.size == 1) { "Checkpointed stack must be empty" }
|
||||
require(flow.fiber.id !in sessionToFlow.values) { "Flow fibre must not be needed by an existing session" }
|
||||
flow.resultFuture.set(removalReason.flowReturnValue)
|
||||
lastState.flowLogic.progressTracker?.currentStep = ProgressTracker.DONE
|
||||
changesPublisher.onNext(StateMachineManager.Change.Removed(lastState.flowLogic, Try.Success(removalReason.flowReturnValue)))
|
||||
|
@ -2,17 +2,11 @@ package net.corda.node.services.statemachine.interceptors
|
||||
|
||||
import co.paralleluniverse.fibers.Suspendable
|
||||
import net.corda.core.flows.StateMachineRunId
|
||||
import net.corda.core.serialization.*
|
||||
import net.corda.core.serialization.SerializedBytes
|
||||
import net.corda.core.serialization.internal.CheckpointSerializationContext
|
||||
import net.corda.core.serialization.internal.checkpointDeserialize
|
||||
import net.corda.core.utilities.contextLogger
|
||||
import net.corda.node.services.statemachine.ActionExecutor
|
||||
import net.corda.node.services.statemachine.Event
|
||||
import net.corda.node.services.statemachine.FlowFiber
|
||||
import net.corda.node.services.statemachine.FlowState
|
||||
import net.corda.node.services.statemachine.FlowStateMachineImpl
|
||||
import net.corda.node.services.statemachine.StateMachineState
|
||||
import net.corda.node.services.statemachine.TransitionExecutor
|
||||
import net.corda.node.services.statemachine.*
|
||||
import net.corda.node.services.statemachine.transitions.FlowContinuation
|
||||
import net.corda.node.services.statemachine.transitions.TransitionResult
|
||||
import java.util.concurrent.LinkedBlockingQueue
|
||||
@ -69,7 +63,7 @@ class FiberDeserializationChecker {
|
||||
private var foundUnrestorableFibers: Boolean = false
|
||||
|
||||
fun start(checkpointSerializationContext: CheckpointSerializationContext) {
|
||||
require(checkerThread == null)
|
||||
require(checkerThread == null){"Checking thread must not already be started"}
|
||||
checkerThread = thread(name = "FiberDeserializationChecker") {
|
||||
while (true) {
|
||||
val job = jobQueue.take()
|
||||
|
@ -372,7 +372,7 @@ class NodeRegistrationHelper(
|
||||
private class FixedPeriodLimitedRetrialStrategy(times: Int, private val period: Duration) : (Duration?) -> Duration? {
|
||||
|
||||
init {
|
||||
require(times > 0)
|
||||
require(times > 0){"Retry attempts must be larger than zero"}
|
||||
}
|
||||
|
||||
private var counter = times
|
||||
|
@ -94,7 +94,7 @@ private fun sender(rpc: CordaRPCOps, inputStream: InputStream, hash: SecureHash.
|
||||
val id = rpc.uploadAttachment(it)
|
||||
require(hash == id) { "Id was '$id' instead of '$hash'" }
|
||||
}
|
||||
require(rpc.attachmentExists(hash))
|
||||
require(rpc.attachmentExists(hash)){"Attachment matching hash: $hash does not exist"}
|
||||
}
|
||||
|
||||
val flowHandle = rpc.startTrackedFlow(::AttachmentDemoFlow, otherSideFuture.get(), notaryFuture.get(), hash)
|
||||
@ -159,7 +159,7 @@ fun recipient(rpc: CordaRPCOps, webPort: Int) {
|
||||
if (wtx.attachments.isNotEmpty()) {
|
||||
if (wtx.outputs.isNotEmpty()) {
|
||||
val state = wtx.outputsOfType<AttachmentContract.State>().single()
|
||||
require(rpc.attachmentExists(state.hash))
|
||||
require(rpc.attachmentExists(state.hash)) {"attachment matching hash: ${state.hash} does not exist"}
|
||||
|
||||
// Download the attachment via the Web endpoint.
|
||||
val connection = URL("http://localhost:$webPort/attachments/${state.hash}").openConnection() as HttpURLConnection
|
||||
@ -207,7 +207,7 @@ class AttachmentContract : Contract {
|
||||
override fun verify(tx: LedgerTransaction) {
|
||||
val state = tx.outputsOfType<AttachmentContract.State>().single()
|
||||
// we check that at least one has the matching hash, the other will be the contract
|
||||
require(tx.attachments.any { it.id == state.hash })
|
||||
require(tx.attachments.any { it.id == state.hash }) {"At least one attachment in transaction must match hash ${state.hash}"}
|
||||
}
|
||||
|
||||
object Command : TypeOnlyCommandData()
|
||||
|
@ -40,7 +40,7 @@ data class PortfolioState(val portfolio: List<StateRef>,
|
||||
}
|
||||
|
||||
override fun generateRevision(notary: Party, oldState: StateAndRef<*>, updatedValue: Update): TransactionBuilder {
|
||||
require(oldState.state.data == this)
|
||||
require(oldState.state.data == this){"Old state data does not match current state data"}
|
||||
val portfolio = updatedValue.portfolio ?: portfolio
|
||||
val valuation = updatedValue.valuation ?: valuation
|
||||
|
||||
|
@ -148,7 +148,9 @@ class ClassCarpenterImpl @JvmOverloads constructor (override val whitelist: Clas
|
||||
}
|
||||
}
|
||||
|
||||
require(schema.name in _loaded)
|
||||
if (schema.name !in _loaded){
|
||||
throw ClassNotFoundException(schema.name)
|
||||
}
|
||||
|
||||
return _loaded[schema.name]!!
|
||||
}
|
||||
|
@ -83,6 +83,7 @@ abstract class MetaCarpenterBase(val schemas: CarpenterMetaSchema, val cc: Class
|
||||
// carpented class existing and remove it from their dependency list, If that
|
||||
// list is now empty we have no impediment to carpenting that class up
|
||||
schemas.dependsOn.remove(newObject.name)?.forEach { dependent ->
|
||||
|
||||
require(newObject.name in schemas.dependencies[dependent]!!.second)
|
||||
|
||||
schemas.dependencies[dependent]?.second?.remove(newObject.name)
|
||||
|
@ -72,8 +72,7 @@ open class NonNullableField(field: Class<out Any?>) : ClassField(field) {
|
||||
}
|
||||
|
||||
override fun nullTest(mv: MethodVisitor, slot: Int) {
|
||||
require(name != unsetName)
|
||||
|
||||
check(name != unsetName) {"Property this.name cannot be $unsetName"}
|
||||
if (!field.isPrimitive) {
|
||||
with(mv) {
|
||||
visitVarInsn(ALOAD, 0) // load this
|
||||
@ -109,7 +108,7 @@ class NullableField(field: Class<out Any?>) : ClassField(field) {
|
||||
}
|
||||
|
||||
override fun nullTest(mv: MethodVisitor, slot: Int) {
|
||||
require(name != unsetName)
|
||||
require(name != unsetName){"Property this.name cannot be $unsetName"}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ data class DummyContract(val blank: Any? = null) : Contract {
|
||||
*/
|
||||
@JvmStatic
|
||||
fun move(priors: List<StateAndRef<SingleOwnerState>>, newOwner: AbstractParty): TransactionBuilder {
|
||||
require(priors.isNotEmpty())
|
||||
require(priors.isNotEmpty()){"States to move to new owner must not be empty"}
|
||||
val priorState = priors[0].state.data
|
||||
val (cmd, state) = priorState.withNewOwner(newOwner)
|
||||
return TransactionBuilder(notary = priors[0].state.notary).withItems(
|
||||
|
Loading…
Reference in New Issue
Block a user