Minor: auto-format of module: core

This commit is contained in:
Mike Hearn 2017-04-11 12:37:21 +02:00
parent ba902f1549
commit d9391b3d29
44 changed files with 130 additions and 106 deletions

View File

@ -317,7 +317,7 @@ fun extractZipFile(inputStream: InputStream, toDirectory: Path) {
* Note that a slightly bigger than numOfExpectedBytes size is expected. * Note that a slightly bigger than numOfExpectedBytes size is expected.
*/ */
@Throws(IllegalArgumentException::class) @Throws(IllegalArgumentException::class)
fun sizedInputStreamAndHash(numOfExpectedBytes : Int) : InputStreamAndHash { fun sizedInputStreamAndHash(numOfExpectedBytes: Int): InputStreamAndHash {
if (numOfExpectedBytes <= 0) throw IllegalArgumentException("A positive number of numOfExpectedBytes is required.") if (numOfExpectedBytes <= 0) throw IllegalArgumentException("A positive number of numOfExpectedBytes is required.")
val baos = ByteArrayOutputStream() val baos = ByteArrayOutputStream()
ZipOutputStream(baos).use({ zos -> ZipOutputStream(baos).use({ zos ->
@ -335,7 +335,7 @@ fun sizedInputStreamAndHash(numOfExpectedBytes : Int) : InputStreamAndHash {
} }
/** Convert a [ByteArrayOutputStream] to [InputStreamAndHash]. */ /** Convert a [ByteArrayOutputStream] to [InputStreamAndHash]. */
fun getInputStreamAndHashFromOutputStream(baos: ByteArrayOutputStream) : InputStreamAndHash { fun getInputStreamAndHashFromOutputStream(baos: ByteArrayOutputStream): InputStreamAndHash {
// TODO: Consider converting OutputStream to InputStream without creating a ByteArray, probably using piped streams. // TODO: Consider converting OutputStream to InputStream without creating a ByteArray, probably using piped streams.
val bytes = baos.toByteArray() val bytes = baos.toByteArray()
// TODO: Consider calculating sha256 on the fly using a DigestInputStream. // TODO: Consider calculating sha256 on the fly using a DigestInputStream.

View File

@ -32,8 +32,8 @@ fun commodity(code: String) = Commodity.getInstance(code)!!
@JvmField val RUB = currency("RUB") @JvmField val RUB = currency("RUB")
@JvmField val FCOJ = commodity("FCOJ") // Frozen concentrated orange juice, yum! @JvmField val FCOJ = commodity("FCOJ") // Frozen concentrated orange juice, yum!
fun <T: Any>AMOUNT(amount: Int, token: T): Amount<T> = Amount.fromDecimal(BigDecimal.valueOf(amount.toLong()), token) fun <T : Any> AMOUNT(amount: Int, token: T): Amount<T> = Amount.fromDecimal(BigDecimal.valueOf(amount.toLong()), token)
fun <T: Any>AMOUNT(amount: Double, token: T): Amount<T> = Amount.fromDecimal(BigDecimal.valueOf(amount), token) fun <T : Any> AMOUNT(amount: Double, token: T): Amount<T> = Amount.fromDecimal(BigDecimal.valueOf(amount), token)
fun DOLLARS(amount: Int): Amount<Currency> = AMOUNT(amount, USD) fun DOLLARS(amount: Int): Amount<Currency> = AMOUNT(amount, USD)
fun DOLLARS(amount: Double): Amount<Currency> = AMOUNT(amount, USD) fun DOLLARS(amount: Double): Amount<Currency> = AMOUNT(amount, USD)
fun POUNDS(amount: Int): Amount<Currency> = AMOUNT(amount, GBP) fun POUNDS(amount: Int): Amount<Currency> = AMOUNT(amount, GBP)

View File

@ -19,7 +19,7 @@ class InsufficientBalanceException(val amountMissing: Amount<*>) : FlowException
* @param T a type that represents the asset in question. This should describe the basic type of the asset * @param T a type that represents the asset in question. This should describe the basic type of the asset
* (GBP, USD, oil, shares in company <X>, etc.) and any additional metadata (issuer, grade, class, etc.). * (GBP, USD, oil, shares in company <X>, etc.) and any additional metadata (issuer, grade, class, etc.).
*/ */
interface FungibleAsset<T: Any> : OwnableState { interface FungibleAsset<T : Any> : OwnableState {
val amount: Amount<Issued<T>> val amount: Amount<Issued<T>>
/** /**
* There must be an ExitCommand signed by these keys to destroy the amount. While all states require their * There must be an ExitCommand signed by these keys to destroy the amount. While all states require their
@ -45,7 +45,7 @@ interface FungibleAsset<T: Any> : OwnableState {
* A command stating that money has been withdrawn from the shared ledger and is now accounted for * A command stating that money has been withdrawn from the shared ledger and is now accounted for
* in some other way. * in some other way.
*/ */
interface Exit<T: Any> : Commands { interface Exit<T : Any> : Commands {
val amount: Amount<Issued<T>> val amount: Amount<Issued<T>>
} }
} }
@ -54,8 +54,8 @@ interface FungibleAsset<T: Any> : OwnableState {
// Small DSL extensions. // Small DSL extensions.
/** Sums the asset states in the list, returning null if there are none. */ /** Sums the asset states in the list, returning null if there are none. */
fun <T: Any> Iterable<ContractState>.sumFungibleOrNull() = filterIsInstance<FungibleAsset<T>>().map { it.amount }.sumOrNull() fun <T : Any> Iterable<ContractState>.sumFungibleOrNull() = filterIsInstance<FungibleAsset<T>>().map { it.amount }.sumOrNull()
/** Sums the asset states in the list, returning zero of the given token if there are none. */ /** Sums the asset states in the list, returning zero of the given token if there are none. */
fun <T: Any> Iterable<ContractState>.sumFungibleOrZero(token: Issued<T>) = filterIsInstance<FungibleAsset<T>>().map { it.amount }.sumOrZero(token) fun <T : Any> Iterable<ContractState>.sumFungibleOrZero(token: Issued<T>) = filterIsInstance<FungibleAsset<T>>().map { it.amount }.sumOrZero(token)

View File

@ -173,7 +173,7 @@ interface IssuanceDefinition
* @param P the type of product underlying the definition, for example [Currency]. * @param P the type of product underlying the definition, for example [Currency].
*/ */
@CordaSerializable @CordaSerializable
data class Issued<out P: Any>(val issuer: PartyAndReference, val product: P) { data class Issued<out P : Any>(val issuer: PartyAndReference, val product: P) {
override fun toString() = "$product issued by $issuer" override fun toString() = "$product issued by $issuer"
} }
@ -182,7 +182,7 @@ data class Issued<out P: Any>(val issuer: PartyAndReference, val product: P) {
* cares about specific issuers with code that will accept any, or which is imposing issuer constraints via some * cares about specific issuers with code that will accept any, or which is imposing issuer constraints via some
* other mechanism and the additional type safety is not wanted. * other mechanism and the additional type safety is not wanted.
*/ */
fun <T: Any> Amount<Issued<T>>.withoutIssuer(): Amount<T> = Amount(quantity, token.product) fun <T : Any> Amount<Issued<T>>.withoutIssuer(): Amount<T> = Amount(quantity, token.product)
/** /**
* A contract state that can have a single owner. * A contract state that can have a single owner.
@ -360,6 +360,7 @@ inline fun <reified T : ContractState> Iterable<StateAndRef<ContractState>>.filt
@CordaSerializable @CordaSerializable
data class PartyAndReference(val party: AnonymousParty, val reference: OpaqueBytes) { data class PartyAndReference(val party: AnonymousParty, val reference: OpaqueBytes) {
constructor(party: Party, reference: OpaqueBytes) : this(party.toAnonymous(), reference) constructor(party: Party, reference: OpaqueBytes) : this(party.toAnonymous(), reference)
override fun toString() = "${party}$reference" override fun toString() = "${party}$reference"
} }

View File

@ -91,7 +91,7 @@ class TransactionResolutionException(val hash: SecureHash) : FlowException() {
override fun toString(): String = "Transaction resolution failure for $hash" override fun toString(): String = "Transaction resolution failure for $hash"
} }
class AttachmentResolutionException(val hash : SecureHash) : FlowException() { class AttachmentResolutionException(val hash: SecureHash) : FlowException() {
override fun toString(): String = "Attachment resolution failure for $hash" override fun toString(): String = "Attachment resolution failure for $hash"
} }
@ -104,6 +104,7 @@ sealed class TransactionVerificationException(val tx: LedgerTransaction, cause:
class SignersMissing(tx: LedgerTransaction, val missing: List<CompositeKey>) : TransactionVerificationException(tx, null) { class SignersMissing(tx: LedgerTransaction, val missing: List<CompositeKey>) : TransactionVerificationException(tx, null) {
override fun toString(): String = "Signers missing: ${missing.joinToString()}" override fun toString(): String = "Signers missing: ${missing.joinToString()}"
} }
class DuplicateInputStates(tx: LedgerTransaction, val duplicates: Set<StateRef>) : TransactionVerificationException(tx, null) { class DuplicateInputStates(tx: LedgerTransaction, val duplicates: Set<StateRef>) : TransactionVerificationException(tx, null) {
override fun toString(): String = "Duplicate inputs: ${duplicates.joinToString()}" override fun toString(): String = "Duplicate inputs: ${duplicates.joinToString()}"
} }

View File

@ -9,7 +9,7 @@ import java.util.*
/** /**
* Compose a number of clauses, such that all of the clauses must run for verification to pass. * Compose a number of clauses, such that all of the clauses must run for verification to pass.
*/ */
open class AllOf<S : ContractState, C : CommandData, K : Any>(firstClause: Clause<S, C, K>, vararg remainingClauses: Clause<S, C, K>) : CompositeClause<S, C, K>() { open class AllOf<S : ContractState, C : CommandData, K : Any>(firstClause: Clause<S, C, K>, vararg remainingClauses: Clause<S, C, K>) : CompositeClause<S, C, K>() {
override val clauses = ArrayList<Clause<S, C, K>>() override val clauses = ArrayList<Clause<S, C, K>>()
init { init {

View File

@ -16,9 +16,10 @@ abstract class AbstractParty(val owningKey: CompositeKey) {
/** Anonymised parties do not include any detail apart from owning key, so equality is dependent solely on the key */ /** Anonymised parties do not include any detail apart from owning key, so equality is dependent solely on the key */
override fun equals(other: Any?): Boolean = other is AbstractParty && this.owningKey == other.owningKey override fun equals(other: Any?): Boolean = other is AbstractParty && this.owningKey == other.owningKey
override fun hashCode(): Int = owningKey.hashCode() override fun hashCode(): Int = owningKey.hashCode()
abstract fun toAnonymous() : AnonymousParty abstract fun toAnonymous(): AnonymousParty
abstract fun nameOrNull() : String? abstract fun nameOrNull(): String?
abstract fun ref(bytes: OpaqueBytes): PartyAndReference abstract fun ref(bytes: OpaqueBytes): PartyAndReference
fun ref(vararg bytes: Byte) = ref(OpaqueBytes.of(*bytes)) fun ref(vararg bytes: Byte) = ref(OpaqueBytes.of(*bytes))

View File

@ -12,7 +12,10 @@ import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable
import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec
import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec
import java.math.BigInteger import java.math.BigInteger
import java.security.* import java.security.KeyPair
import java.security.PrivateKey
import java.security.PublicKey
import java.security.SignatureException
/** A wrapper around a digital signature. */ /** A wrapper around a digital signature. */
@CordaSerializable @CordaSerializable

View File

@ -7,6 +7,6 @@ import java.security.KeyFactory
* This is required as a [SignatureScheme] requires a [java.security.KeyFactory] property, but i2p has * This is required as a [SignatureScheme] requires a [java.security.KeyFactory] property, but i2p has
* its own KeyFactory for EdDSA, thus this actually a Proxy Pattern over i2p's KeyFactory. * its own KeyFactory for EdDSA, thus this actually a Proxy Pattern over i2p's KeyFactory.
*/ */
class EdDSAKeyFactory: KeyFactory { class EdDSAKeyFactory : KeyFactory {
constructor() : super(net.i2p.crypto.eddsa.KeyFactory(), null, "EDDSA_ED25519_SHA512") constructor() : super(net.i2p.crypto.eddsa.KeyFactory(), null, "EDDSA_ED25519_SHA512")
} }

View File

@ -18,7 +18,7 @@ sealed class MerkleTree {
data class Node(override val hash: SecureHash, val left: MerkleTree, val right: MerkleTree) : MerkleTree() data class Node(override val hash: SecureHash, val left: MerkleTree, val right: MerkleTree) : MerkleTree()
companion object { companion object {
private fun isPow2(num: Int): Boolean = num and (num-1) == 0 private fun isPow2(num: Int): Boolean = num and (num - 1) == 0
/** /**
* Merkle tree building using hashes, with zero hash padding to full power of 2. * Merkle tree building using hashes, with zero hash padding to full power of 2.
@ -54,9 +54,9 @@ sealed class MerkleTree {
val newLevelHashes: MutableList<MerkleTree> = ArrayList() val newLevelHashes: MutableList<MerkleTree> = ArrayList()
val n = lastNodesList.size val n = lastNodesList.size
require((n and 1) == 0) { "Sanity check: number of nodes should be even." } require((n and 1) == 0) { "Sanity check: number of nodes should be even." }
for (i in 0..n-2 step 2) { for (i in 0..n - 2 step 2) {
val left = lastNodesList[i] val left = lastNodesList[i]
val right = lastNodesList[i+1] val right = lastNodesList[i + 1]
val newHash = left.hash.hashConcat(right.hash) val newHash = left.hash.hashConcat(right.hash)
val combined = Node(newHash, left, right) val combined = Node(newHash, left, right)
newLevelHashes.add(combined) newLevelHashes.add(combined)

View File

@ -82,8 +82,8 @@ class PartialMerkleTree(val root: PartialTree) {
return when (tree) { return when (tree) {
is MerkleTree.Leaf -> level is MerkleTree.Leaf -> level
is MerkleTree.Node -> { is MerkleTree.Node -> {
val l1 = checkFull(tree.left, level+1) val l1 = checkFull(tree.left, level + 1)
val l2 = checkFull(tree.right, level+1) val l2 = checkFull(tree.right, level + 1)
if (l1 != l2) throw MerkleTreeException("Got not full binary tree.") if (l1 != l2) throw MerkleTreeException("Got not full binary tree.")
l1 l1
} }

View File

@ -25,6 +25,7 @@ import java.security.PublicKey
class Party(val name: String, owningKey: CompositeKey) : AbstractParty(owningKey) { class Party(val name: String, owningKey: CompositeKey) : AbstractParty(owningKey) {
/** A helper constructor that converts the given [PublicKey] in to a [CompositeKey] with a single node */ /** A helper constructor that converts the given [PublicKey] in to a [CompositeKey] with a single node */
constructor(name: String, owningKey: PublicKey) : this(name, owningKey.composite) constructor(name: String, owningKey: PublicKey) : this(name, owningKey.composite)
override fun toAnonymous(): AnonymousParty = AnonymousParty(owningKey) override fun toAnonymous(): AnonymousParty = AnonymousParty(owningKey)
override fun toString() = "${owningKey.toBase58String()} (${name})" override fun toString() = "${owningKey.toBase58String()} (${name})"
override fun nameOrNull(): String? = name override fun nameOrNull(): String? = name

View File

@ -1,6 +1,8 @@
package net.corda.core.crypto package net.corda.core.crypto
import java.security.* import java.security.KeyFactory
import java.security.KeyPairGeneratorSpi
import java.security.Signature
import java.security.spec.AlgorithmParameterSpec import java.security.spec.AlgorithmParameterSpec
/** /**

View File

@ -1,8 +1,6 @@
package net.corda.core.crypto package net.corda.core.crypto
import net.corda.core.serialization.opaque
import java.security.InvalidKeyException import java.security.InvalidKeyException
import java.security.PublicKey
import java.security.SignatureException import java.security.SignatureException
/** /**

View File

@ -23,11 +23,10 @@ import org.bouncycastle.pkcs.PKCS10CertificationRequest
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder
import org.bouncycastle.util.IPAddress import org.bouncycastle.util.IPAddress
import org.bouncycastle.util.io.pem.PemReader import org.bouncycastle.util.io.pem.PemReader
import java.io.ByteArrayInputStream
import java.io.FileReader import java.io.FileReader
import java.io.FileWriter import java.io.FileWriter
import java.io.InputStream
import java.io.IOException import java.io.IOException
import java.io.InputStream
import java.math.BigInteger import java.math.BigInteger
import java.net.InetAddress import java.net.InetAddress
import java.nio.file.Path import java.nio.file.Path

View File

@ -196,7 +196,9 @@ abstract class FlowLogic<out T> {
*/ */
var stateMachine: FlowStateMachine<*> var stateMachine: FlowStateMachine<*>
get() = _stateMachine ?: throw IllegalStateException("This can only be done after the flow has been started.") get() = _stateMachine ?: throw IllegalStateException("This can only be done after the flow has been started.")
set(value) { _stateMachine = value } set(value) {
_stateMachine = value
}
// This points to the outermost flow and is changed when a subflow is invoked. // This points to the outermost flow and is changed when a subflow is invoked.
private var sessionFlow: FlowLogic<*> = this private var sessionFlow: FlowLogic<*> = this

View File

@ -112,7 +112,7 @@ interface CordaRPCOps : RPCOps {
* Checks whether an attachment with the given hash is stored on the node. * Checks whether an attachment with the given hash is stored on the node.
*/ */
fun attachmentExists(id: SecureHash): Boolean fun attachmentExists(id: SecureHash): Boolean
/** /**
* Download an attachment JAR by ID * Download an attachment JAR by ID
*/ */
@ -221,7 +221,7 @@ inline fun <T : Any, A, B, C, D, reified R : FlowLogic<T>> CordaRPCOps.startFlow
* @param returnValue A [ListenableFuture] of the flow's return value. * @param returnValue A [ListenableFuture] of the flow's return value.
*/ */
@CordaSerializable @CordaSerializable
data class FlowHandle<A> ( data class FlowHandle<A>(
val id: StateMachineRunId, val id: StateMachineRunId,
val progress: Observable<String>, val progress: Observable<String>,
val returnValue: ListenableFuture<A>) : AutoCloseable { val returnValue: ListenableFuture<A>) : AutoCloseable {

View File

@ -39,13 +39,13 @@ abstract class CordaPluginRegistry(
*/ */
open val servicePlugins: List<Function<PluginServiceHub, out Any>> = emptyList() open val servicePlugins: List<Function<PluginServiceHub, out Any>> = emptyList()
) { ) {
/** /**
* Optionally whitelist types for use in object serialization, as we lock down the types that can be serialized. * Optionally whitelist types for use in object serialization, as we lock down the types that can be serialized.
* *
* For example, if you add a new [ContractState] it needs to be whitelisted. You can do that either by * For example, if you add a new [ContractState] it needs to be whitelisted. You can do that either by
* adding the @CordaSerializable annotation or via this method. * adding the @CordaSerializable annotation or via this method.
** **
* @return true if you register types, otherwise you will be filtered out of the list of plugins considered in future. * @return true if you register types, otherwise you will be filtered out of the list of plugins considered in future.
*/ */
open fun customizeSerialization(custom: SerializationCustomization): Boolean = false open fun customizeSerialization(custom: SerializationCustomization): Boolean = false
} }

View File

@ -19,7 +19,7 @@ data class WorldCoordinate(val latitude: Double, val longitude: Double) {
* to infinity. Google Maps, for example, uses a square map image, and square maps yield latitude extents * to infinity. Google Maps, for example, uses a square map image, and square maps yield latitude extents
* of 85.0511 to -85.0511 = arctan(sinh(π)). * of 85.0511 to -85.0511 = arctan(sinh(π)).
*/ */
@Suppress("unused") // Used from the visualiser GUI. @Suppress("unused") // Used from the visualiser GUI.
fun project(screenWidth: Double, screenHeight: Double, topLatitude: Double, bottomLatitude: Double, fun project(screenWidth: Double, screenHeight: Double, topLatitude: Double, bottomLatitude: Double,
leftLongitude: Double, rightLongitude: Double): Pair<Double, Double> { leftLongitude: Double, rightLongitude: Double): Pair<Double, Double> {
require(latitude in bottomLatitude..topLatitude) require(latitude in bottomLatitude..topLatitude)

View File

@ -81,7 +81,7 @@ interface ServiceHub : ServicesForResolution {
* @throws IllegalProtocolLogicException or IllegalArgumentException if there are problems with the [logicType] or [args]. * @throws IllegalProtocolLogicException or IllegalArgumentException if there are problems with the [logicType] or [args].
*/ */
fun <T : ContractState> toStateAndRef(ref: StateRef): StateAndRef<T> { fun <T : ContractState> toStateAndRef(ref: StateRef): StateAndRef<T> {
val definingTx = storageService.validatedTransactions.getTransaction(ref.txhash) ?: throw TransactionResolutionException(ref.txhash) val definingTx = storageService.validatedTransactions.getTransaction(ref.txhash) ?: throw TransactionResolutionException(ref.txhash)
return definingTx.tx.outRef<T>(ref.index) return definingTx.tx.outRef<T>(ref.index)
} }

View File

@ -14,8 +14,8 @@ interface AttachmentStorage {
* human browsing convenience: the attachment itself will still be the file (that is, edits to the extracted directory * human browsing convenience: the attachment itself will still be the file (that is, edits to the extracted directory
* will not have any effect). * will not have any effect).
*/ */
var automaticallyExtractAttachments : Boolean var automaticallyExtractAttachments: Boolean
var storePath : Path var storePath: Path
/** /**
* Returns a handle to a locally stored attachment, or null if it's not known. The handle can be used to open * Returns a handle to a locally stored attachment, or null if it's not known. The handle can be used to open

View File

@ -13,6 +13,7 @@ sealed class PartyInfo {
data class Node(val node: NodeInfo) : PartyInfo() { data class Node(val node: NodeInfo) : PartyInfo() {
override val party get() = node.legalIdentity override val party get() = node.legalIdentity
} }
data class Service(val service: ServiceEntry) : PartyInfo() { data class Service(val service: ServiceEntry) : PartyInfo() {
override val party get() = service.identity override val party get() = service.identity
} }

View File

@ -257,10 +257,10 @@ interface VaultService {
fun <T : ContractState> unconsumedStatesForSpending(amount: Amount<Currency>, onlyFromIssuerParties: Set<AbstractParty>? = null, notary: Party? = null, lockId: UUID, withIssuerRefs: Set<OpaqueBytes>? = null): List<StateAndRef<T>> fun <T : ContractState> unconsumedStatesForSpending(amount: Amount<Currency>, onlyFromIssuerParties: Set<AbstractParty>? = null, notary: Party? = null, lockId: UUID, withIssuerRefs: Set<OpaqueBytes>? = null): List<StateAndRef<T>>
} }
inline fun <reified T: ContractState> VaultService.unconsumedStates(includeSoftLockedStates: Boolean = true): Iterable<StateAndRef<T>> = inline fun <reified T : ContractState> VaultService.unconsumedStates(includeSoftLockedStates: Boolean = true): Iterable<StateAndRef<T>> =
states(setOf(T::class.java), EnumSet.of(Vault.StateStatus.UNCONSUMED), includeSoftLockedStates) states(setOf(T::class.java), EnumSet.of(Vault.StateStatus.UNCONSUMED), includeSoftLockedStates)
inline fun <reified T: ContractState> VaultService.consumedStates(): Iterable<StateAndRef<T>> = inline fun <reified T : ContractState> VaultService.consumedStates(): Iterable<StateAndRef<T>> =
states(setOf(T::class.java), EnumSet.of(Vault.StateStatus.CONSUMED)) states(setOf(T::class.java), EnumSet.of(Vault.StateStatus.CONSUMED))
/** Returns the [linearState] heads only when the type of the state would be considered an 'instanceof' the given type. */ /** Returns the [linearState] heads only when the type of the state would be considered an 'instanceof' the given type. */

View File

@ -1,9 +1,8 @@
package net.corda.core.schemas.requery.converters package net.corda.core.schemas.requery.converters
import io.requery.Converter import io.requery.Converter
import java.sql.Timestamp
import java.sql.* import java.time.Instant
import java.time.*
/** /**
* Converts from a [Instant] to a [java.sql.Timestamp] for Java 8. Note that * Converts from a [Instant] to a [java.sql.Timestamp] for Java 8. Note that
@ -12,19 +11,29 @@ import java.time.*
*/ */
class InstantConverter : Converter<Instant, Timestamp> { class InstantConverter : Converter<Instant, Timestamp> {
override fun getMappedType(): Class<Instant> { return Instant::class.java } override fun getMappedType(): Class<Instant> {
return Instant::class.java
}
override fun getPersistedType(): Class<Timestamp> { return Timestamp::class.java } override fun getPersistedType(): Class<Timestamp> {
return Timestamp::class.java
}
override fun getPersistedSize(): Int? { return null } override fun getPersistedSize(): Int? {
return null
}
override fun convertToPersisted(value: Instant?): Timestamp? { override fun convertToPersisted(value: Instant?): Timestamp? {
if (value == null) { return null } if (value == null) {
return null
}
return Timestamp.from(value) return Timestamp.from(value)
} }
override fun convertToMapped(type: Class<out Instant>, value: Timestamp?): Instant? { override fun convertToMapped(type: Class<out Instant>, value: Timestamp?): Instant? {
if (value == null) { return null } if (value == null) {
return null
}
return value.toInstant() return value.toInstant()
} }
} }

View File

@ -9,20 +9,30 @@ import net.corda.core.crypto.SecureHash
*/ */
class StateRefConverter : Converter<StateRef, Pair<String, Int>> { class StateRefConverter : Converter<StateRef, Pair<String, Int>> {
override fun getMappedType(): Class<StateRef> { return StateRef::class.java } override fun getMappedType(): Class<StateRef> {
return StateRef::class.java
}
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
override fun getPersistedType(): Class<Pair<String,Int>> { return Pair::class.java as Class<Pair<String,Int>> } override fun getPersistedType(): Class<Pair<String, Int>> {
return Pair::class.java as Class<Pair<String, Int>>
}
override fun getPersistedSize(): Int? { return null } override fun getPersistedSize(): Int? {
return null
}
override fun convertToPersisted(value: StateRef?): Pair<String,Int>? { override fun convertToPersisted(value: StateRef?): Pair<String, Int>? {
if (value == null) { return null } if (value == null) {
return null
}
return Pair(value.txhash.toString(), value.index) return Pair(value.txhash.toString(), value.index)
} }
override fun convertToMapped(type: Class<out StateRef>, value: Pair<String,Int>?): StateRef? { override fun convertToMapped(type: Class<out StateRef>, value: Pair<String, Int>?): StateRef? {
if (value == null) { return null } if (value == null) {
return null
}
return StateRef(SecureHash.parse(value.first), value.second) return StateRef(SecureHash.parse(value.first), value.second)
} }
} }

View File

@ -1,14 +1,8 @@
package net.corda.core.schemas.requery.converters package net.corda.core.schemas.requery.converters
import io.requery.Converter
import io.requery.converter.EnumOrdinalConverter import io.requery.converter.EnumOrdinalConverter
import io.requery.sql.Mapping
import net.corda.core.contracts.ContractState
import net.corda.core.node.services.Vault import net.corda.core.node.services.Vault
import java.sql.*
import java.time.*
/** /**
* Converter which persists a [Vault.StateStatus] enum using its enum ordinal representation * Converter which persists a [Vault.StateStatus] enum using its enum ordinal representation
*/ */

View File

@ -47,9 +47,9 @@ class CordaClassResolver(val whitelist: ClassWhitelist) : DefaultClassResolver()
private fun checkClass(type: Class<*>): Registration? { private fun checkClass(type: Class<*>): Registration? {
/** If call path has disabled whitelisting (see [CordaKryo.register]), just return without checking. */ /** If call path has disabled whitelisting (see [CordaKryo.register]), just return without checking. */
if(!whitelistEnabled) return null if (!whitelistEnabled) return null
// Allow primitives, abstracts and interfaces // Allow primitives, abstracts and interfaces
if (type.isPrimitive || type == Any::class.java || Modifier.isAbstract(type.modifiers) || type==String::class.java) return null if (type.isPrimitive || type == Any::class.java || Modifier.isAbstract(type.modifiers) || type == String::class.java) return null
// If array, recurse on element type // If array, recurse on element type
if (type.isArray) { if (type.isArray) {
return checkClass(type.componentType) return checkClass(type.componentType)
@ -98,7 +98,7 @@ class CordaClassResolver(val whitelist: ClassWhitelist) : DefaultClassResolver()
super.reset() super.reset()
// Kryo creates a cache of class name to Class<*> which does not work so well with multiple class loaders. // Kryo creates a cache of class name to Class<*> which does not work so well with multiple class loaders.
// TODO: come up with a more efficient way. e.g. segregate the name space by class loader. // TODO: come up with a more efficient way. e.g. segregate the name space by class loader.
if(nameToClass != null) { if (nameToClass != null) {
val classesToRemove: MutableList<String> = ArrayList(nameToClass.size) val classesToRemove: MutableList<String> = ArrayList(nameToClass.size)
for (entry in nameToClass.entries()) { for (entry in nameToClass.entries()) {
if (entry.value.classLoader is AttachmentsClassLoader) { if (entry.value.classLoader is AttachmentsClassLoader) {

View File

@ -14,7 +14,6 @@ import net.corda.core.serialization.p2PKryo
import net.corda.core.serialization.serialize import net.corda.core.serialization.serialize
import net.corda.core.utilities.Emoji import net.corda.core.utilities.Emoji
import java.security.PublicKey import java.security.PublicKey
import java.util.*
/** /**
* A transaction ready for serialisation, without any signatures attached. A WireTransaction is usually wrapped * A transaction ready for serialisation, without any signatures attached. A WireTransaction is usually wrapped
@ -123,7 +122,7 @@ class WireTransaction(
* @returns FilteredLeaves used in PartialMerkleTree calculation and verification. * @returns FilteredLeaves used in PartialMerkleTree calculation and verification.
*/ */
fun filterWithFun(filtering: (Any) -> Boolean): FilteredLeaves { fun filterWithFun(filtering: (Any) -> Boolean): FilteredLeaves {
fun notNullFalse(elem: Any?): Any? = if(elem == null || !filtering(elem)) null else elem fun notNullFalse(elem: Any?): Any? = if (elem == null || !filtering(elem)) null else elem
return FilteredLeaves( return FilteredLeaves(
inputs.filter { filtering(it) }, inputs.filter { filtering(it) },
attachments.filter { filtering(it) }, attachments.filter { filtering(it) },

View File

@ -43,7 +43,7 @@ class NonEmptySet<T>(initial: T) : MutableSet<T> {
if (size > elements.size) if (size > elements.size)
set.removeAll(elements) set.removeAll(elements)
else if (!containsAll(elements)) else if (!containsAll(elements))
// Remove the common elements // Remove the common elements
set.removeAll(elements) set.removeAll(elements)
else else
throw IllegalStateException() throw IllegalStateException()

View File

@ -128,7 +128,7 @@ class ProgressTracker(vararg steps: Step) {
curChangeSubscription?.unsubscribe() curChangeSubscription?.unsubscribe()
stepIndex = index stepIndex = index
_changes.onNext(Change.Position(this, steps[index])) _changes.onNext(Change.Position(this, steps[index]))
curChangeSubscription = currentStep.changes.subscribe( { _changes.onNext(it) }, { _changes.onError(it) }) curChangeSubscription = currentStep.changes.subscribe({ _changes.onNext(it) }, { _changes.onError(it) })
if (currentStep == DONE) _changes.onCompleted() if (currentStep == DONE) _changes.onCompleted()
} }

View File

@ -23,7 +23,7 @@ class FetchAttachmentsFlow(requests: Set<SecureHash>,
} }
} }
private class ByteArrayAttachment(private val wire : ByteArray) : Attachment { private class ByteArrayAttachment(private val wire: ByteArray) : Attachment {
override val id: SecureHash by lazy { wire.sha256() } override val id: SecureHash by lazy { wire.sha256() }
override fun open(): InputStream = wire.inputStream() override fun open(): InputStream = wire.inputStream()
override fun equals(other: Any?) = other === this || other is Attachment && other.id == this.id override fun equals(other: Any?) = other === this || other is Attachment && other.id == this.id

View File

@ -41,6 +41,7 @@ class FinalityFlow(val transactions: Iterable<SignedTransaction>,
object NOTARISING : ProgressTracker.Step("Requesting signature by notary service") { object NOTARISING : ProgressTracker.Step("Requesting signature by notary service") {
override fun childProgressTracker() = NotaryFlow.Client.tracker() override fun childProgressTracker() = NotaryFlow.Client.tracker()
} }
object BROADCASTING : ProgressTracker.Step("Broadcasting transaction to participants") object BROADCASTING : ProgressTracker.Step("Broadcasting transaction to participants")
// TODO: Make all tracker() methods @JvmStatic // TODO: Make all tracker() methods @JvmStatic
@ -90,6 +91,7 @@ class FinalityFlow(val transactions: Iterable<SignedTransaction>,
return needsNotarisation && hasNoNotarySignature(stx) return needsNotarisation && hasNoNotarySignature(stx)
} }
private fun hasNoNotarySignature(stx: SignedTransaction): Boolean { private fun hasNoNotarySignature(stx: SignedTransaction): Boolean {
val notaryKey = stx.tx.notary?.owningKey val notaryKey = stx.tx.notary?.owningKey
val signers = stx.sigs.map { it.by }.toSet() val signers = stx.sigs.map { it.by }.toSet()

View File

@ -5,7 +5,6 @@ import net.corda.core.crypto.CompositeKey
import net.corda.core.crypto.Party import net.corda.core.crypto.Party
import net.corda.core.crypto.composite import net.corda.core.crypto.composite
import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowLogic
import net.corda.core.node.ServiceHub
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
import net.corda.core.utilities.unwrap import net.corda.core.utilities.unwrap
import java.security.cert.Certificate import java.security.cert.Certificate

View File

@ -1,15 +1,13 @@
package net.corda.core.flows; package net.corda.core.flows;
import co.paralleluniverse.fibers.Suspendable; import co.paralleluniverse.fibers.*;
import net.corda.core.crypto.Party; import net.corda.core.crypto.*;
import net.corda.testing.node.MockNetwork; import net.corda.testing.node.*;
import org.junit.After; import org.junit.*;
import org.junit.Before;
import org.junit.Test;
import java.util.concurrent.Future; import java.util.concurrent.*;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.assertj.core.api.AssertionsForClassTypes.*;
public class FlowsInJavaTest { public class FlowsInJavaTest {

View File

@ -143,7 +143,7 @@ class AmountTests {
SourceAndAmount(partyA, POUNDS(256), 5), SourceAndAmount(partyA, POUNDS(256), 5),
SourceAndAmount(partyB, POUNDS(256), 6) SourceAndAmount(partyB, POUNDS(256), 6)
) )
val collector = Collectors.toMap<SourceAndAmount<Currency, String>, Pair<String, Currency>, BigDecimal>({ Pair(it.source, it.amount.token)}, {it.amount.toDecimal()}, { x,y -> x + y}) val collector = Collectors.toMap<SourceAndAmount<Currency, String>, Pair<String, Currency>, BigDecimal>({ Pair(it.source, it.amount.token) }, { it.amount.toDecimal() }, { x, y -> x + y })
val originalTotals = sourceAccounts.stream().collect(collector) val originalTotals = sourceAccounts.stream().collect(collector)
val smallTransfer = AmountTransfer.fromDecimal(BigDecimal("10"), USD, partyA, partyB) val smallTransfer = AmountTransfer.fromDecimal(BigDecimal("10"), USD, partyA, partyB)

View File

@ -17,9 +17,13 @@ import org.junit.Assert.assertNotEquals
import org.junit.Test import org.junit.Test
import java.security.KeyFactory import java.security.KeyFactory
import java.security.Security import java.security.Security
import java.security.spec.PKCS8EncodedKeySpec
import java.security.spec.X509EncodedKeySpec
import java.util.* import java.util.*
import java.security.spec.* import kotlin.test.assertEquals
import kotlin.test.* import kotlin.test.assertNotNull
import kotlin.test.assertTrue
import kotlin.test.fail
/** /**
* Run tests for cryptographic algorithms * Run tests for cryptographic algorithms
@ -356,9 +360,9 @@ class CryptoUtilsTest {
// test list of supported algorithms // test list of supported algorithms
@Test @Test
fun `Check supported algorithms`() { fun `Check supported algorithms`() {
val algList : List<String> = Crypto.listSupportedSignatureSchemes() val algList: List<String> = Crypto.listSupportedSignatureSchemes()
val expectedAlgSet = setOf("RSA_SHA256","ECDSA_SECP256K1_SHA256", "ECDSA_SECP256R1_SHA256", "EDDSA_ED25519_SHA512","SPHINCS-256_SHA512") val expectedAlgSet = setOf("RSA_SHA256", "ECDSA_SECP256K1_SHA256", "ECDSA_SECP256R1_SHA256", "EDDSA_ED25519_SHA512", "SPHINCS-256_SHA512")
assertTrue { Sets.symmetricDifference(expectedAlgSet,algList.toSet()).isEmpty(); } assertTrue { Sets.symmetricDifference(expectedAlgSet, algList.toSet()).isEmpty(); }
} }
// Unfortunately, there isn't a standard way to encode/decode keys, so we need to test per case // Unfortunately, there isn't a standard way to encode/decode keys, so we need to test per case
@ -453,13 +457,13 @@ class CryptoUtilsTest {
//2nd method for encoding/decoding //2nd method for encoding/decoding
// Encode and decode private key. // Encode and decode private key.
val privKeyInfo : PrivateKeyInfo = PrivateKeyInfo.getInstance(privKey.encoded) val privKeyInfo: PrivateKeyInfo = PrivateKeyInfo.getInstance(privKey.encoded)
val decodedPrivKey = BCSphincs256PrivateKey(privKeyInfo) val decodedPrivKey = BCSphincs256PrivateKey(privKeyInfo)
// Check that decoded private key is equal to the initial one. // Check that decoded private key is equal to the initial one.
assertEquals(decodedPrivKey, privKey) assertEquals(decodedPrivKey, privKey)
// Encode and decode public key. // Encode and decode public key.
val pubKeyInfo : SubjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(pubKey.encoded) val pubKeyInfo: SubjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(pubKey.encoded)
val extractedPubKey = BCSphincs256PublicKey(pubKeyInfo) val extractedPubKey = BCSphincs256PublicKey(pubKeyInfo)
// Check that decoded private key is equal to the initial one. // Check that decoded private key is equal to the initial one.
assertEquals(extractedPubKey, pubKey) assertEquals(extractedPubKey, pubKey)
@ -601,7 +605,7 @@ class CryptoUtilsTest {
@Test @Test
fun `Failure test between K1 and R1 keys`() { fun `Failure test between K1 and R1 keys`() {
val keyPairK1 = Crypto.generateKeyPair("ECDSA_SECP256K1_SHA256") val keyPairK1 = Crypto.generateKeyPair("ECDSA_SECP256K1_SHA256")
val privK1= keyPairK1.private val privK1 = keyPairK1.private
val encodedPrivK1 = privK1.encoded val encodedPrivK1 = privK1.encoded
val decodedPrivK1 = Crypto.decodePrivateKey(encodedPrivK1) val decodedPrivK1 = Crypto.decodePrivateKey(encodedPrivK1)

View File

@ -27,6 +27,7 @@ class EncodingUtilsTest {
assertEquals("", emptyByteArray.toBase64()) assertEquals("", emptyByteArray.toBase64())
assertEquals("", emptyByteArray.toHex()) assertEquals("", emptyByteArray.toHex())
} }
@Test @Test
fun `encoding 7 zero bytes`() { fun `encoding 7 zero bytes`() {
val sevenZeroByteArray = ByteArray(7) val sevenZeroByteArray = ByteArray(7)

View File

@ -83,7 +83,7 @@ class PartialMerkleTreeTest {
fun `check full tree`() { fun `check full tree`() {
val h = SecureHash.randomSHA256() val h = SecureHash.randomSHA256()
val left = MerkleTree.Node(h, MerkleTree.Node(h, MerkleTree.Leaf(h), MerkleTree.Leaf(h)), val left = MerkleTree.Node(h, MerkleTree.Node(h, MerkleTree.Leaf(h), MerkleTree.Leaf(h)),
MerkleTree.Node(h, MerkleTree.Leaf(h), MerkleTree.Leaf(h))) MerkleTree.Node(h, MerkleTree.Leaf(h), MerkleTree.Leaf(h)))
val right = MerkleTree.Node(h, MerkleTree.Leaf(h), MerkleTree.Leaf(h)) val right = MerkleTree.Node(h, MerkleTree.Leaf(h), MerkleTree.Leaf(h))
val tree = MerkleTree.Node(h, left, right) val tree = MerkleTree.Node(h, left, right)
assertFailsWith<MerkleTreeException> { PartialMerkleTree.build(tree, listOf(h)) } assertFailsWith<MerkleTreeException> { PartialMerkleTree.build(tree, listOf(h)) }
@ -103,6 +103,7 @@ class PartialMerkleTreeTest {
else -> false else -> false
} }
} }
val mt = testTx.buildFilteredTransaction(::filtering) val mt = testTx.buildFilteredTransaction(::filtering)
val leaves = mt.filteredLeaves val leaves = mt.filteredLeaves
val d = WireTransaction.deserialize(testTx.serialized) val d = WireTransaction.deserialize(testTx.serialized)
@ -127,7 +128,7 @@ class PartialMerkleTreeTest {
@Test @Test
fun `nothing filtered`() { fun `nothing filtered`() {
val mt = testTx.buildFilteredTransaction( {false} ) val mt = testTx.buildFilteredTransaction({ false })
assertTrue(mt.filteredLeaves.attachments.isEmpty()) assertTrue(mt.filteredLeaves.attachments.isEmpty())
assertTrue(mt.filteredLeaves.commands.isEmpty()) assertTrue(mt.filteredLeaves.commands.isEmpty())
assertTrue(mt.filteredLeaves.inputs.isEmpty()) assertTrue(mt.filteredLeaves.inputs.isEmpty())

View File

@ -7,7 +7,6 @@ import java.security.Security
import java.security.SignatureException import java.security.SignatureException
import java.time.Instant import java.time.Instant
import kotlin.test.assertTrue import kotlin.test.assertTrue
import kotlin.test.fail
/** /**
* Digital signature MetaData tests * Digital signature MetaData tests

View File

@ -68,7 +68,7 @@ class X509UtilitiesTest {
if (typeId == GeneralName.iPAddress) { if (typeId == GeneralName.iPAddress) {
assertEquals("10.0.0.54", value) assertEquals("10.0.0.54", value)
} else if (value == "alias name") { } else if (value == "alias name") {
foundAliasDnsName = true foundAliasDnsName = true
} }
} }
assertTrue(foundAliasDnsName) assertTrue(foundAliasDnsName)

View File

@ -19,7 +19,7 @@ object TxKeyFlow {
} }
class Requester(val otherSide: Party, class Requester(val otherSide: Party,
override val progressTracker: ProgressTracker): FlowLogic<Pair<CompositeKey, Certificate?>>() { override val progressTracker: ProgressTracker) : FlowLogic<Pair<CompositeKey, Certificate?>>() {
constructor(otherSide: Party) : this(otherSide, tracker()) constructor(otherSide: Party) : this(otherSide, tracker())
companion object { companion object {
@ -40,7 +40,7 @@ object TxKeyFlow {
* counterparty and as the result from the flow. * counterparty and as the result from the flow.
*/ */
class Provider(val otherSide: Party, class Provider(val otherSide: Party,
override val progressTracker: ProgressTracker): FlowLogic<CompositeKey>() { override val progressTracker: ProgressTracker) : FlowLogic<CompositeKey>() {
constructor(otherSide: Party) : this(otherSide, tracker()) constructor(otherSide: Party) : this(otherSide, tracker())
companion object { companion object {

View File

@ -12,7 +12,6 @@ import net.corda.core.utilities.DUMMY_NOTARY
import net.corda.testing.MEGA_CORP import net.corda.testing.MEGA_CORP
import net.corda.testing.node.MockAttachmentStorage import net.corda.testing.node.MockAttachmentStorage
import org.apache.commons.io.IOUtils import org.apache.commons.io.IOUtils
import org.junit.After
import org.junit.Assert import org.junit.Assert
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test

View File

@ -4,6 +4,7 @@ import com.esotericsoftware.kryo.Kryo
import com.google.common.primitives.Ints import com.google.common.primitives.Ints
import net.corda.core.crypto.* import net.corda.core.crypto.*
import net.corda.core.messaging.Ack import net.corda.core.messaging.Ack
import net.corda.node.services.persistence.NodeAttachmentService
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy import org.assertj.core.api.Assertions.assertThatThrownBy
import org.bouncycastle.jce.provider.BouncyCastleProvider import org.bouncycastle.jce.provider.BouncyCastleProvider
@ -11,14 +12,13 @@ import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import java.io.ByteArrayInputStream
import java.io.InputStream import java.io.InputStream
import java.security.Security import java.security.Security
import java.time.Instant import java.time.Instant
import java.util.* import java.util.*
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertTrue import kotlin.test.assertTrue
import net.corda.node.services.persistence.NodeAttachmentService
import java.io.ByteArrayInputStream
class KryoTests { class KryoTests {
@ -102,7 +102,7 @@ class KryoTests {
fun `InputStream serialisation`() { fun `InputStream serialisation`() {
val rubbish = ByteArray(12345, { (it * it * 0.12345).toByte() }) val rubbish = ByteArray(12345, { (it * it * 0.12345).toByte() })
val readRubbishStream: InputStream = rubbish.inputStream().serialize(kryo).deserialize(kryo) val readRubbishStream: InputStream = rubbish.inputStream().serialize(kryo).deserialize(kryo)
for (i in 0 .. 12344) { for (i in 0..12344) {
assertEquals(rubbish[i], readRubbishStream.read().toByte()) assertEquals(rubbish[i], readRubbishStream.read().toByte())
} }
assertEquals(-1, readRubbishStream.read()) assertEquals(-1, readRubbishStream.read())
@ -135,8 +135,8 @@ class KryoTests {
@Test @Test
fun `HashCheckingStream (de)serialize`() { fun `HashCheckingStream (de)serialize`() {
val rubbish = ByteArray(12345, { (it * it * 0.12345).toByte() }) val rubbish = ByteArray(12345, { (it * it * 0.12345).toByte() })
val readRubbishStream : InputStream = NodeAttachmentService.HashCheckingStream(SecureHash.sha256(rubbish), rubbish.size, ByteArrayInputStream(rubbish)).serialize(kryo).deserialize(kryo) val readRubbishStream: InputStream = NodeAttachmentService.HashCheckingStream(SecureHash.sha256(rubbish), rubbish.size, ByteArrayInputStream(rubbish)).serialize(kryo).deserialize(kryo)
for (i in 0 .. 12344) { for (i in 0..12344) {
assertEquals(rubbish[i], readRubbishStream.read().toByte()) assertEquals(rubbish[i], readRubbishStream.read().toByte())
} }
assertEquals(-1, readRubbishStream.read()) assertEquals(-1, readRubbishStream.read())

View File

@ -83,14 +83,14 @@ class TransactionStateGenerator<T : ContractState>(val stateGenerator: Generator
} }
@Suppress("CAST_NEVER_SUCCEEDS", "UNCHECKED_CAST") @Suppress("CAST_NEVER_SUCCEEDS", "UNCHECKED_CAST")
class IssuedGenerator<T: Any>(val productGenerator: Generator<T>) : Generator<Issued<T>>(Issued::class.java as Class<Issued<T>>) { class IssuedGenerator<T : Any>(val productGenerator: Generator<T>) : Generator<Issued<T>>(Issued::class.java as Class<Issued<T>>) {
override fun generate(random: SourceOfRandomness, status: GenerationStatus): Issued<T> { override fun generate(random: SourceOfRandomness, status: GenerationStatus): Issued<T> {
return Issued(PartyAndReferenceGenerator().generate(random, status), productGenerator.generate(random, status)) return Issued(PartyAndReferenceGenerator().generate(random, status), productGenerator.generate(random, status))
} }
} }
@Suppress("CAST_NEVER_SUCCEEDS", "UNCHECKED_CAST") @Suppress("CAST_NEVER_SUCCEEDS", "UNCHECKED_CAST")
class AmountGenerator<T: Any>(val tokenGenerator: Generator<T>) : Generator<Amount<T>>(Amount::class.java as Class<Amount<T>>) { class AmountGenerator<T : Any>(val tokenGenerator: Generator<T>) : Generator<Amount<T>>(Amount::class.java as Class<Amount<T>>) {
override fun generate(random: SourceOfRandomness, status: GenerationStatus): Amount<T> { override fun generate(random: SourceOfRandomness, status: GenerationStatus): Amount<T> {
return Amount(random.nextLong(0, 1000000), tokenGenerator.generate(random, status)) return Amount(random.nextLong(0, 1000000), tokenGenerator.generate(random, status))
} }