Reformat files in core

This commit is contained in:
Tommy Lillehagen 2017-10-06 14:35:27 +01:00
parent f6e5d2385a
commit a633f8dada
55 changed files with 262 additions and 156 deletions

View File

@ -1,4 +1,5 @@
@file:JvmName("ConcurrencyUtils")
package net.corda.core.concurrent
import net.corda.core.internal.concurrent.openFuture

View File

@ -167,7 +167,7 @@ data class Amount<T : Any>(val quantity: Long, val displayTokenSize: BigDecimal,
}
}
}
} catch(e: Exception) {
} catch (e: Exception) {
throw IllegalArgumentException("Could not parse $input as a currency", e)
}
throw IllegalArgumentException("Did not recognise the currency in $input or could not parse")

View File

@ -34,7 +34,7 @@ inline fun <R> requireThat(body: Requirements.() -> R) = Requirements.body()
/** Filters the command list by type, party and public key all at once. */
inline fun <reified T : CommandData> Collection<CommandWithParties<CommandData>>.select(signer: PublicKey? = null,
party: AbstractParty? = null) =
party: AbstractParty? = null) =
filter { it.value is T }.
filter { if (signer == null) true else signer in it.signers }.
filter { if (party == null) true else party in it.signingParties }.
@ -44,7 +44,7 @@ inline fun <reified T : CommandData> Collection<CommandWithParties<CommandData>>
/** Filters the command list by type, parties and public keys all at once. */
inline fun <reified T : CommandData> Collection<CommandWithParties<CommandData>>.select(signers: Collection<PublicKey>?,
parties: Collection<Party>?) =
parties: Collection<Party>?) =
filter { it.value is T }.
filter { if (signers == null) true else it.signers.containsAll(signers) }.
filter { if (parties == null) true else it.signingParties.containsAll(parties) }.

View File

@ -85,6 +85,7 @@ abstract class 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)"

View File

@ -31,6 +31,8 @@ class CordaSecurityProvider : Provider(PROVIDER_NAME, 0.1, "$PROVIDER_NAME secur
object CordaObjectIdentifier {
// UUID-based OID
// TODO: Register for an OID space and issue our own shorter OID.
@JvmField val COMPOSITE_KEY = ASN1ObjectIdentifier("2.25.30086077608615255153862931087626791002")
@JvmField val COMPOSITE_SIGNATURE = ASN1ObjectIdentifier("2.25.30086077608615255153862931087626791003")
@JvmField
val COMPOSITE_KEY = ASN1ObjectIdentifier("2.25.30086077608615255153862931087626791002")
@JvmField
val COMPOSITE_SIGNATURE = ASN1ObjectIdentifier("2.25.30086077608615255153862931087626791003")
}

View File

@ -774,9 +774,10 @@ object Crypto {
// it forms, by itself, the new private key, which in turn is used to compute the new public key.
val pointQ = FixedPointCombMultiplier().multiply(parameterSpec.g, deterministicD)
// This is unlikely to happen, but we should check for point at infinity.
if (pointQ.isInfinity)
if (pointQ.isInfinity) {
// Instead of throwing an exception, we retry with SHA256(seed).
return deriveKeyPairECDSA(parameterSpec, privateKey, seed.sha256().bytes)
}
val publicKeySpec = ECPublicKeySpec(pointQ, parameterSpec)
val publicKeyD = BCECPublicKey(privateKey.algorithm, publicKeySpec, BouncyCastleProvider.CONFIGURATION)
@ -849,6 +850,7 @@ object Crypto {
override fun generatePublic(keyInfo: SubjectPublicKeyInfo?): PublicKey? {
return keyInfo?.let { decodePublicKey(signatureScheme, it.encoded) }
}
override fun generatePrivate(keyInfo: PrivateKeyInfo?): PrivateKey? {
return keyInfo?.let { decodePrivateKey(signatureScheme, it.encoded) }
}

View File

@ -35,6 +35,7 @@ fun PrivateKey.sign(bytesToSign: ByteArray, publicKey: PublicKey) = DigitalSigna
*/
@Throws(IllegalArgumentException::class, InvalidKeyException::class, SignatureException::class)
fun KeyPair.sign(bytesToSign: ByteArray) = private.sign(bytesToSign, public)
fun KeyPair.sign(bytesToSign: OpaqueBytes) = sign(bytesToSign.bytes)
/**
* Helper function for signing a [SignableData] object.
@ -72,18 +73,18 @@ fun PublicKey.verify(content: ByteArray, signature: DigitalSignature) = Crypto.d
* @return whether the signature is correct for this key.
*/
@Throws(IllegalStateException::class, SignatureException::class, IllegalArgumentException::class)
fun PublicKey.isValid(content: ByteArray, signature: DigitalSignature) : Boolean {
fun PublicKey.isValid(content: ByteArray, signature: DigitalSignature): Boolean {
if (this is CompositeKey)
throw IllegalStateException("Verification of CompositeKey signatures currently not supported.") // TODO CompositeSignature verification.
return Crypto.isValid(this, signature.bytes, content)
}
/** Render a public key to its hash (in Base58) of its serialised form using the DL prefix. */
fun PublicKey.toStringShort(): String = "DL" + this.toSHA256Bytes().toBase58()
fun PublicKey.toStringShort(): String = "DL" + this.toSHA256Bytes().toBase58()
val PublicKey.keys: Set<PublicKey> get() = (this as? CompositeKey)?.leafKeys ?: setOf(this)
fun PublicKey.isFulfilledBy(otherKey: PublicKey): Boolean = isFulfilledBy(setOf(otherKey))
fun PublicKey.isFulfilledBy(otherKey: PublicKey): Boolean = isFulfilledBy(setOf(otherKey))
fun PublicKey.isFulfilledBy(otherKeys: Iterable<PublicKey>): Boolean = (this as? CompositeKey)?.isFulfilledBy(otherKeys) ?: (this in otherKeys)
/** Checks whether any of the given [keys] matches a leaf on the [CompositeKey] tree or a single [PublicKey]. */

View File

@ -23,6 +23,7 @@ open class DigitalSignature(bytes: ByteArray) : OpaqueBytes(bytes) {
*/
@Throws(InvalidKeyException::class, SignatureException::class)
fun verify(content: ByteArray) = by.verify(content, this)
/**
* Utility to simplify the act of verifying a signature.
*
@ -32,6 +33,7 @@ open class DigitalSignature(bytes: ByteArray) : OpaqueBytes(bytes) {
*/
@Throws(InvalidKeyException::class, SignatureException::class)
fun verify(content: OpaqueBytes) = by.verify(content.bytes, this)
/**
* Utility to simplify the act of verifying a signature. In comparison to [verify] doesn't throw an
* exception, making it more suitable where a boolean is required, but normally you should use the function

View File

@ -34,11 +34,18 @@ sealed class SecureHash(bytes: ByteArray) : OpaqueBytes(bytes) {
}
}
@JvmStatic fun sha256(bytes: ByteArray) = SHA256(MessageDigest.getInstance("SHA-256").digest(bytes))
@JvmStatic fun sha256Twice(bytes: ByteArray) = sha256(sha256(bytes).bytes)
@JvmStatic fun sha256(str: String) = sha256(str.toByteArray())
@JvmStatic
fun sha256(bytes: ByteArray) = SHA256(MessageDigest.getInstance("SHA-256").digest(bytes))
@JvmStatic
fun sha256Twice(bytes: ByteArray) = sha256(sha256(bytes).bytes)
@JvmStatic
fun sha256(str: String) = sha256(str.toByteArray())
@JvmStatic
fun randomSHA256() = sha256(newSecureRandom().generateSeed(32))
@JvmStatic fun randomSHA256() = sha256(newSecureRandom().generateSeed(32))
val zeroHash = SecureHash.SHA256(ByteArray(32, { 0.toByte() }))
val allOnesHash = SecureHash.SHA256(ByteArray(32, { 255.toByte() }))
}

View File

@ -11,7 +11,7 @@ import java.util.*
* This is similar to [DigitalSignature.WithKey], but targeted to DLT transaction signatures.
*/
@CordaSerializable
class TransactionSignature(bytes: ByteArray, val by: PublicKey, val signatureMetadata: SignatureMetadata): DigitalSignature(bytes) {
class TransactionSignature(bytes: ByteArray, val by: PublicKey, val signatureMetadata: SignatureMetadata) : DigitalSignature(bytes) {
/**
* Function to verify a [SignableData] object's signature.
* Note that [SignableData] contains the id of the transaction and extra metadata, such as DLT's platform version.

View File

@ -136,7 +136,8 @@ abstract class AbstractStateReplacementFlow {
// We use Void? instead of Unit? as that's what you'd use in Java.
abstract class Acceptor<in T>(val initiatingSession: FlowSession,
override val progressTracker: ProgressTracker = Acceptor.tracker()) : FlowLogic<Void?>() {
constructor(initiatingSession: FlowSession) : this(initiatingSession, Acceptor.tracker())
constructor(initiatingSession: FlowSession) : this(initiatingSession, Acceptor.tracker())
companion object {
object VERIFYING : ProgressTracker.Step("Verifying state replacement proposal")
object APPROVING : ProgressTracker.Step("State replacement approved")

View File

@ -61,11 +61,12 @@ import java.security.PublicKey
* just in the states. If null, the default well known identity of the node is used.
*/
// TODO: AbstractStateReplacementFlow needs updating to use this flow.
class CollectSignaturesFlow @JvmOverloads constructor (val partiallySignedTx: SignedTransaction,
val sessionsToCollectFrom: Collection<FlowSession>,
val myOptionalKeys: Iterable<PublicKey>?,
override val progressTracker: ProgressTracker = CollectSignaturesFlow.tracker()) : FlowLogic<SignedTransaction>() {
class CollectSignaturesFlow @JvmOverloads constructor(val partiallySignedTx: SignedTransaction,
val sessionsToCollectFrom: Collection<FlowSession>,
val myOptionalKeys: Iterable<PublicKey>?,
override val progressTracker: ProgressTracker = CollectSignaturesFlow.tracker()) : FlowLogic<SignedTransaction>() {
@JvmOverloads constructor(partiallySignedTx: SignedTransaction, sessionsToCollectFrom: Collection<FlowSession>, progressTracker: ProgressTracker = CollectSignaturesFlow.tracker()) : this(partiallySignedTx, sessionsToCollectFrom, null, progressTracker)
companion object {
object COLLECTING : ProgressTracker.Step("Collecting signatures from counter-parties.")
object VERIFYING : ProgressTracker.Step("Verifying collected signatures.")
@ -134,6 +135,7 @@ class CollectSignaturesFlow @JvmOverloads constructor (val partiallySignedTx: Si
class CollectSignatureFlow(val partiallySignedTx: SignedTransaction, val session: FlowSession, val signingKeys: List<PublicKey>) : FlowLogic<List<TransactionSignature>>() {
constructor(partiallySignedTx: SignedTransaction, session: FlowSession, vararg signingKeys: PublicKey) :
this(partiallySignedTx, session, listOf(*signingKeys))
@Suspendable
override fun call(): List<TransactionSignature> {
// SendTransactionFlow allows counterparty to access our data to resolve the transaction.
@ -224,7 +226,7 @@ abstract class SignTransactionFlow(val otherSideSession: FlowSession,
// Perform some custom verification over the transaction.
try {
checkTransaction(stx)
} catch(e: Exception) {
} catch (e: Exception) {
if (e is IllegalStateException || e is IllegalArgumentException || e is AssertionError)
throw FlowException(e)
else

View File

@ -28,7 +28,7 @@ object ContractUpgradeFlow {
val stateAndRef: StateAndRef<*>,
private val upgradedContractClass: Class<out UpgradedContract<*, *>>
) : FlowLogic<Void?>() {
// DOCEND 1
// DOCEND 1
@Suspendable
override fun call(): Void? {
val upgrade = upgradedContractClass.newInstance()
@ -50,7 +50,7 @@ object ContractUpgradeFlow {
class Deauthorise(val stateRef: StateRef) : FlowLogic<Void?>() {
@Suspendable
override fun call(): Void? {
//DOCEND 2
//DOCEND 2
serviceHub.contractUpgradeService.removeAuthorisedContractUpgrade(stateRef)
return null
}

View File

@ -26,8 +26,8 @@ import net.corda.core.utilities.ProgressTracker
*/
@InitiatingFlow
class FinalityFlow(val transaction: SignedTransaction,
private val extraRecipients: Set<Party>,
override val progressTracker: ProgressTracker) : FlowLogic<SignedTransaction>() {
private val extraRecipients: Set<Party>,
override val progressTracker: ProgressTracker) : FlowLogic<SignedTransaction>() {
constructor(transaction: SignedTransaction, extraParticipants: Set<Party>) : this(transaction, extraParticipants, tracker())
constructor(transaction: SignedTransaction) : this(transaction, emptySet(), tracker())
constructor(transaction: SignedTransaction, progressTracker: ProgressTracker) : this(transaction, emptySet(), progressTracker)

View File

@ -16,18 +16,22 @@ sealed class FlowInitiator : Principal {
data class RPC(val username: String) : FlowInitiator() {
override fun getName(): String = username
}
/** Started when we get new session initiation request. */
data class Peer(val party: Party) : FlowInitiator() {
override fun getName(): String = party.name.toString()
}
/** Started by a CordaService. */
data class Service(val serviceClassName: String) : FlowInitiator() {
override fun getName(): String = serviceClassName
}
/** Started as scheduled activity. */
data class Scheduled(val scheduledState: ScheduledStateRef) : FlowInitiator() {
override fun getName(): String = "Scheduler"
}
// TODO When proper ssh access enabled, add username/use RPC?
object Shell : FlowInitiator() {
override fun getName(): String = "Shell User"

View File

@ -75,6 +75,7 @@ abstract class FlowSession {
inline fun <reified R : Any> sendAndReceive(payload: Any): UntrustworthyData<R> {
return sendAndReceive(R::class.java, payload)
}
/**
* Serializes and queues the given [payload] object for sending to the [counterparty]. Suspends until a response
* is received, which must be of the given [receiveType]. Remember that when receiving data from other parties the data
@ -100,6 +101,7 @@ abstract class FlowSession {
inline fun <reified R : Any> receive(): UntrustworthyData<R> {
return receive(R::class.java)
}
/**
* Suspends until [counterparty] sends us a message of type [receiveType].
*

View File

@ -173,5 +173,5 @@ sealed class NotaryError {
override fun toString() = cause.toString()
}
object WrongNotary: NotaryError()
object WrongNotary : NotaryError()
}

View File

@ -13,7 +13,7 @@ import java.security.SignatureException
* This flow is a combination of [FlowSession.receive], resolve and [SignedTransaction.verify]. This flow will receive the
* [SignedTransaction] and perform the resolution back-and-forth required to check the dependencies and download any missing
* attachments. The flow will return the [SignedTransaction] after it is resolved and then verified using [SignedTransaction.verify].
*
*
* @param otherSideSession session to the other side which is calling [SendTransactionFlow].
* @param checkSufficientSignatures if true checks all required signatures are present. See [SignedTransaction.verify].
*/

View File

@ -13,6 +13,7 @@ import java.security.PublicKey
abstract class AbstractParty(val owningKey: PublicKey) {
/** 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 === this || other is AbstractParty && other.owningKey == owningKey
override fun hashCode(): Int = owningKey.hashCode()
abstract fun nameOrNull(): CordaX500Name?

View File

@ -81,7 +81,7 @@ data class CordaX500Name(val commonName: String?,
private val countryCodes: Set<String> = ImmutableSet.copyOf(Locale.getISOCountries())
@JvmStatic
fun build(principal: X500Principal) : CordaX500Name {
fun build(principal: X500Principal): CordaX500Name {
val x500Name = X500Name.getInstance(principal.encoded)
val attrsMap: Map<ASN1ObjectIdentifier, ASN1Encodable> = x500Name.rdNs
.flatMap { it.typesAndValues.asList() }
@ -109,7 +109,7 @@ data class CordaX500Name(val commonName: String?,
}
@JvmStatic
fun parse(name: String) : CordaX500Name = build(X500Principal(name))
fun parse(name: String): CordaX500Name = build(X500Principal(name))
}
@Transient

View File

@ -29,6 +29,7 @@ import java.security.cert.X509Certificate
class Party(val name: CordaX500Name, owningKey: PublicKey) : AbstractParty(owningKey) {
constructor(certificate: X509Certificate)
: this(CordaX500Name.build(certificate.subjectX500Principal), Crypto.toSupportedPublicKey(certificate.publicKey))
override fun nameOrNull(): CordaX500Name = name
fun anonymise(): AnonymousParty = AnonymousParty(owningKey)
override fun ref(bytes: OpaqueBytes): PartyAndReference = PartyAndReference(this, bytes)

View File

@ -11,7 +11,9 @@ import java.security.cert.*
*/
@CordaSerializable
class PartyAndCertificate(val certPath: CertPath) {
@Transient val certificate: X509Certificate
@Transient
val certificate: X509Certificate
init {
require(certPath.type == "X.509") { "Only X.509 certificates supported" }
val certs = certPath.certificates
@ -19,7 +21,8 @@ class PartyAndCertificate(val certPath: CertPath) {
certificate = certs[0] as X509Certificate
}
@Transient val party: Party = Party(certificate)
@Transient
val party: Party = Party(certificate)
val owningKey: PublicKey get() = party.owningKey
val name: CordaX500Name get() = party.name

View File

@ -13,22 +13,38 @@ object Emoji {
(System.getenv("TERM_PROGRAM") == "JediTerm" && System.getProperty("java.vendor") == "JetBrains s.r.o")
}
@JvmStatic val CODE_SANTA_CLAUS: String = codePointsString(0x1F385)
@JvmStatic val CODE_DIAMOND: String = codePointsString(0x1F537)
@JvmStatic val CODE_BAG_OF_CASH: String = codePointsString(0x1F4B0)
@JvmStatic val CODE_NEWSPAPER: String = codePointsString(0x1F4F0)
@JvmStatic val CODE_RIGHT_ARROW: String = codePointsString(0x27A1, 0xFE0F)
@JvmStatic val CODE_LEFT_ARROW: String = codePointsString(0x2B05, 0xFE0F)
@JvmStatic val CODE_GREEN_TICK: String = codePointsString(0x2705)
@JvmStatic val CODE_PAPERCLIP: String = codePointsString(0x1F4CE)
@JvmStatic val CODE_COOL_GUY: String = codePointsString(0x1F60E)
@JvmStatic val CODE_NO_ENTRY: String = codePointsString(0x1F6AB)
@JvmStatic val CODE_SKULL_AND_CROSSBONES: String = codePointsString(0x2620)
@JvmStatic val CODE_BOOKS: String = codePointsString(0x1F4DA)
@JvmStatic val CODE_SLEEPING_FACE: String = codePointsString(0x1F634)
@JvmStatic val CODE_LIGHTBULB: String = codePointsString(0x1F4A1)
@JvmStatic val CODE_FREE: String = codePointsString(0x1F193)
@JvmStatic val CODE_SOON: String = codePointsString(0x1F51C)
@JvmStatic
val CODE_SANTA_CLAUS: String = codePointsString(0x1F385)
@JvmStatic
val CODE_DIAMOND: String = codePointsString(0x1F537)
@JvmStatic
val CODE_BAG_OF_CASH: String = codePointsString(0x1F4B0)
@JvmStatic
val CODE_NEWSPAPER: String = codePointsString(0x1F4F0)
@JvmStatic
val CODE_RIGHT_ARROW: String = codePointsString(0x27A1, 0xFE0F)
@JvmStatic
val CODE_LEFT_ARROW: String = codePointsString(0x2B05, 0xFE0F)
@JvmStatic
val CODE_GREEN_TICK: String = codePointsString(0x2705)
@JvmStatic
val CODE_PAPERCLIP: String = codePointsString(0x1F4CE)
@JvmStatic
val CODE_COOL_GUY: String = codePointsString(0x1F60E)
@JvmStatic
val CODE_NO_ENTRY: String = codePointsString(0x1F6AB)
@JvmStatic
val CODE_SKULL_AND_CROSSBONES: String = codePointsString(0x2620)
@JvmStatic
val CODE_BOOKS: String = codePointsString(0x1F4DA)
@JvmStatic
val CODE_SLEEPING_FACE: String = codePointsString(0x1F634)
@JvmStatic
val CODE_LIGHTBULB: String = codePointsString(0x1F4A1)
@JvmStatic
val CODE_FREE: String = codePointsString(0x1F193)
@JvmStatic
val CODE_SOON: String = codePointsString(0x1F51C)
/**

View File

@ -49,6 +49,7 @@ operator fun Duration.times(multiplicand: Long): Duration = multipliedBy(multipl
* separator problems.
*/
operator fun Path.div(other: String): Path = resolve(other)
operator fun String.div(other: String): Path = Paths.get(this) / other
/**
@ -104,6 +105,7 @@ fun Path.copyToDirectory(targetDir: Path, vararg options: CopyOption): Path {
Files.copy(this, targetFile, *options)
return targetFile
}
fun Path.moveTo(target: Path, vararg options: CopyOption): Path = Files.move(this, target, *options)
fun Path.isRegularFile(vararg options: LinkOption): Boolean = Files.isRegularFile(this, *options)
fun Path.isDirectory(vararg options: LinkOption): Boolean = Files.isDirectory(this, *options)
@ -238,10 +240,13 @@ fun <T> Class<T>.castIfPossible(obj: Any): T? = if (isInstance(obj)) cast(obj) e
/** Returns a [DeclaredField] wrapper around the declared (possibly non-public) static field of the receiver [Class]. */
fun <T> Class<*>.staticField(name: String): DeclaredField<T> = DeclaredField(this, name, null)
/** Returns a [DeclaredField] wrapper around the declared (possibly non-public) static field of the receiver [KClass]. */
fun <T> KClass<*>.staticField(name: String): DeclaredField<T> = DeclaredField(java, name, null)
/** @suppress Returns a [DeclaredField] wrapper around the declared (possibly non-public) instance field of the receiver object. */
fun <T> Any.declaredField(name: String): DeclaredField<T> = DeclaredField(javaClass, name, this)
/**
* Returns a [DeclaredField] wrapper around the (possibly non-public) instance field of the receiver object, but declared
* in its superclass [clazz].
@ -250,7 +255,7 @@ fun <T> Any.declaredField(name: String): DeclaredField<T> = DeclaredField(javaCl
fun <T> Any.declaredField(clazz: KClass<*>, name: String): DeclaredField<T> = DeclaredField(clazz.java, name, this)
/** creates a new instance if not a Kotlin object */
fun <T: Any> KClass<T>.objectOrNewInstance(): T {
fun <T : Any> KClass<T>.objectOrNewInstance(): T {
return this.objectInstance ?: this.createInstance()
}

View File

@ -27,6 +27,7 @@ class LazyPool<A>(
STARTED,
FINISHED
}
private val lifeCycle = LifeCycle(State.STARTED)
private fun clearIfNeeded(instance: A): A {

View File

@ -18,6 +18,7 @@ class LazyStickyPool<A : Any>(
private class InstanceBox<A> {
var instance: LinkedBlockingQueue<A>? = null
}
private val random = Random()
private val boxes = Array(size) { InstanceBox<A>() }

View File

@ -28,6 +28,7 @@ class ResolveTransactionsFlow(private val txHashes: Set<SecureHash>,
constructor(signedTransaction: SignedTransaction, otherSide: FlowSession) : this(dependencyIDs(signedTransaction), otherSide) {
this.signedTransaction = signedTransaction
}
companion object {
private fun dependencyIDs(stx: SignedTransaction) = stx.inputs.map { it.txhash }.toSet()

View File

@ -6,7 +6,7 @@ import kotlin.reflect.KProperty
* A write-once property to be used as delegate for Kotlin var properties. The expectation is that this is initialised
* prior to the spawning of any threads that may access it and so there's no need for it to be volatile.
*/
class WriteOnceProperty<T : Any>(private val defaultValue:T? = null) {
class WriteOnceProperty<T : Any>(private val defaultValue: T? = null) {
private var v: T? = defaultValue
operator fun getValue(thisRef: Any?, property: KProperty<*>) = v ?: throw IllegalStateException("Write-once property $property not set.")

View File

@ -46,6 +46,7 @@ class X509EdDSAEngine : Signature {
override fun engineSetParameter(params: AlgorithmParameterSpec) = engine.setParameter(params)
@Suppress("DEPRECATION")
override fun engineGetParameter(param: String): Any = engine.getParameter(param)
@Suppress("DEPRECATION")
override fun engineSetParameter(param: String, value: Any?) = engine.setParameter(param, value)
}

View File

@ -104,12 +104,15 @@ interface CordaRPCOps : RPCOps {
fun <T : ContractState> vaultQuery(contractStateType: Class<out T>): Vault.Page<T> {
return vaultQueryBy(QueryCriteria.VaultQueryCriteria(), PageSpecification(), Sort(emptySet()), contractStateType)
}
fun <T : ContractState> vaultQueryByCriteria(criteria: QueryCriteria, contractStateType: Class<out T>): Vault.Page<T> {
return vaultQueryBy(criteria, PageSpecification(), Sort(emptySet()), contractStateType)
}
fun <T : ContractState> vaultQueryByWithPagingSpec(contractStateType: Class<out T>, criteria: QueryCriteria, paging: PageSpecification): Vault.Page<T> {
return vaultQueryBy(criteria, paging, Sort(emptySet()), contractStateType)
}
fun <T : ContractState> vaultQueryByWithSorting(contractStateType: Class<out T>, criteria: QueryCriteria, sorting: Sort): Vault.Page<T> {
return vaultQueryBy(criteria, PageSpecification(), sorting, contractStateType)
}
@ -142,12 +145,15 @@ interface CordaRPCOps : RPCOps {
fun <T : ContractState> vaultTrack(contractStateType: Class<out T>): DataFeed<Vault.Page<T>, Vault.Update<T>> {
return vaultTrackBy(QueryCriteria.VaultQueryCriteria(), PageSpecification(), Sort(emptySet()), contractStateType)
}
fun <T : ContractState> vaultTrackByCriteria(contractStateType: Class<out T>, criteria: QueryCriteria): DataFeed<Vault.Page<T>, Vault.Update<T>> {
return vaultTrackBy(criteria, PageSpecification(), Sort(emptySet()), contractStateType)
}
fun <T : ContractState> vaultTrackByWithPagingSpec(contractStateType: Class<out T>, criteria: QueryCriteria, paging: PageSpecification): DataFeed<Vault.Page<T>, Vault.Update<T>> {
return vaultTrackBy(criteria, paging, Sort(emptySet()), contractStateType)
}
fun <T : ContractState> vaultTrackByWithSorting(contractStateType: Class<out T>, criteria: QueryCriteria, sorting: Sort): DataFeed<Vault.Page<T>, Vault.Update<T>> {
return vaultTrackBy(criteria, PageSpecification(), sorting, contractStateType)
}
@ -250,6 +256,7 @@ interface CordaRPCOps : RPCOps {
* @return well known identity, if found.
*/
fun wellKnownPartyFromAnonymous(party: AbstractParty): Party?
/** Returns the [Party] corresponding to the given key, if found. */
fun partyFromKey(key: PublicKey): Party?
@ -310,7 +317,7 @@ inline fun <T, reified R : FlowLogic<T>> CordaRPCOps.startFlow(
flowConstructor: () -> R
): FlowHandle<T> = startFlowDynamic(R::class.java)
inline fun <T , A, reified R : FlowLogic<T>> CordaRPCOps.startFlow(
inline fun <T, A, reified R : FlowLogic<T>> CordaRPCOps.startFlow(
@Suppress("UNUSED_PARAMETER")
flowConstructor: (A) -> R,
arg0: A

View File

@ -43,7 +43,7 @@ data class FlowHandleImpl<A>(
override val id: StateMachineRunId,
override val returnValue: CordaFuture<A>) : FlowHandle<A> {
// Remember to add @Throws to FlowHandle.close() if this throws an exception.
// Remember to add @Throws to FlowHandle.close() if this throws an exception.
override fun close() {
returnValue.cancel(false)
}

View File

@ -35,9 +35,10 @@ data class NodeInfo(val addresses: List<NetworkHostAndPort>,
* are porting code from earlier versions of Corda that expected a single party per node, just use the first item
* in the returned list.
*/
val legalIdentities: List<Party> get() {
return _legalIdentities ?: legalIdentitiesAndCerts.map { it.party }.also { _legalIdentities = it }
}
val legalIdentities: List<Party>
get() {
return _legalIdentities ?: legalIdentitiesAndCerts.map { it.party }.also { _legalIdentities = it }
}
/** Returns true if [party] is one of the identities of this node, else false. */
fun isLegalIdentity(party: Party): Boolean = party in legalIdentities

View File

@ -8,6 +8,7 @@ import net.corda.core.utilities.NetworkHostAndPort
*/
sealed class PartyInfo {
abstract val party: Party
data class SingleNode(override val party: Party, val addresses: List<NetworkHostAndPort>): PartyInfo()
data class DistributedNode(override val party: Party): PartyInfo()
data class SingleNode(override val party: Party, val addresses: List<NetworkHostAndPort>) : PartyInfo()
data class DistributedNode(override val party: Party) : PartyInfo()
}

View File

@ -99,7 +99,7 @@ class Vault<out T : ContractState>(val states: Iterable<StateAndRef<T>>) {
companion object {
val NoUpdate = Update(emptySet(), emptySet(), type = Vault.UpdateType.GENERAL)
val NoNotaryUpdate = Vault.Update(emptySet(), emptySet(), type = Vault.UpdateType.NOTARY_CHANGE)
val NoNotaryUpdate = Vault.Update(emptySet(), emptySet(), type = Vault.UpdateType.NOTARY_CHANGE)
}
@CordaSerializable

View File

@ -49,12 +49,12 @@ sealed class QueryCriteria {
/**
* VaultQueryCriteria: provides query by attributes defined in [VaultSchema.VaultStates]
*/
data class VaultQueryCriteria @JvmOverloads constructor (override val status: Vault.StateStatus = Vault.StateStatus.UNCONSUMED,
override val contractStateTypes: Set<Class<out ContractState>>? = null,
val stateRefs: List<StateRef>? = null,
val notary: List<AbstractParty>? = null,
val softLockingCondition: SoftLockingCondition? = null,
val timeCondition: TimeCondition? = null) : CommonQueryCriteria() {
data class VaultQueryCriteria @JvmOverloads constructor(override val status: Vault.StateStatus = Vault.StateStatus.UNCONSUMED,
override val contractStateTypes: Set<Class<out ContractState>>? = null,
val stateRefs: List<StateRef>? = null,
val notary: List<AbstractParty>? = null,
val softLockingCondition: SoftLockingCondition? = null,
val timeCondition: TimeCondition? = null) : CommonQueryCriteria() {
override fun visit(parser: IQueryCriteriaParser): Collection<Predicate> {
super.visit(parser)
return parser.parseCriteria(this)
@ -69,10 +69,10 @@ sealed class QueryCriteria {
val externalId: List<String>? = null,
override val status: Vault.StateStatus = Vault.StateStatus.UNCONSUMED,
override val contractStateTypes: Set<Class<out ContractState>>? = null) : CommonQueryCriteria() {
constructor(participants: List<AbstractParty>? = null,
linearId: List<UniqueIdentifier>? = null,
status: Vault.StateStatus = Vault.StateStatus.UNCONSUMED,
contractStateTypes: Set<Class<out ContractState>>? = null) : this(participants, linearId?.map { it.id }, linearId?.mapNotNull { it.externalId }, status, contractStateTypes)
constructor(participants: List<AbstractParty>? = null,
linearId: List<UniqueIdentifier>? = null,
status: Vault.StateStatus = Vault.StateStatus.UNCONSUMED,
contractStateTypes: Set<Class<out ContractState>>? = null) : this(participants, linearId?.map { it.id }, linearId?.mapNotNull { it.externalId }, status, contractStateTypes)
override fun visit(parser: IQueryCriteriaParser): Collection<Predicate> {
super.visit(parser)
@ -80,13 +80,13 @@ sealed class QueryCriteria {
}
}
/**
* FungibleStateQueryCriteria: provides query by attributes defined in [VaultSchema.VaultFungibleState]
*
* Valid TokenType implementations defined by Amount<T> are
* [Currency] as used in [Cash] contract state
* [Commodity] as used in [CommodityContract] state
*/
/**
* FungibleStateQueryCriteria: provides query by attributes defined in [VaultSchema.VaultFungibleState]
*
* Valid TokenType implementations defined by Amount<T> are
* [Currency] as used in [Cash] contract state
* [Commodity] as used in [CommodityContract] state
*/
data class FungibleAssetQueryCriteria @JvmOverloads constructor(val participants: List<AbstractParty>? = null,
val owner: List<AbstractParty>? = null,
val quantity: ColumnPredicate<Long>? = null,
@ -94,11 +94,11 @@ sealed class QueryCriteria {
val issuerRef: List<OpaqueBytes>? = null,
override val status: Vault.StateStatus = Vault.StateStatus.UNCONSUMED,
override val contractStateTypes: Set<Class<out ContractState>>? = null) : CommonQueryCriteria() {
override fun visit(parser: IQueryCriteriaParser): Collection<Predicate> {
super.visit(parser)
return parser.parseCriteria(this)
}
}
override fun visit(parser: IQueryCriteriaParser): Collection<Predicate> {
super.visit(parser)
return parser.parseCriteria(this)
}
}
/**
* VaultCustomQueryCriteria: provides query by custom attributes defined in a contracts
@ -111,9 +111,9 @@ sealed class QueryCriteria {
* Refer to [CommercialPaper.State] for a concrete example.
*/
data class VaultCustomQueryCriteria<L : PersistentState> @JvmOverloads constructor
(val expression: CriteriaExpression<L, Boolean>,
override val status: Vault.StateStatus = Vault.StateStatus.UNCONSUMED,
override val contractStateTypes: Set<Class<out ContractState>>? = null) : CommonQueryCriteria() {
(val expression: CriteriaExpression<L, Boolean>,
override val status: Vault.StateStatus = Vault.StateStatus.UNCONSUMED,
override val contractStateTypes: Set<Class<out ContractState>>? = null) : CommonQueryCriteria() {
override fun visit(parser: IQueryCriteriaParser): Collection<Predicate> {
super.visit(parser)
return parser.parseCriteria(this)
@ -121,13 +121,13 @@ sealed class QueryCriteria {
}
// enable composition of [QueryCriteria]
private data class AndComposition(val a: QueryCriteria, val b: QueryCriteria): QueryCriteria() {
private data class AndComposition(val a: QueryCriteria, val b: QueryCriteria) : QueryCriteria() {
override fun visit(parser: IQueryCriteriaParser): Collection<Predicate> {
return parser.parseAnd(this.a, this.b)
}
}
private data class OrComposition(val a: QueryCriteria, val b: QueryCriteria): QueryCriteria() {
private data class OrComposition(val a: QueryCriteria, val b: QueryCriteria) : QueryCriteria() {
override fun visit(parser: IQueryCriteriaParser): Collection<Predicate> {
return parser.parseOr(this.a, this.b)
}
@ -148,9 +148,9 @@ interface IQueryCriteriaParser {
fun parseCriteria(criteria: QueryCriteria.CommonQueryCriteria): Collection<Predicate>
fun parseCriteria(criteria: QueryCriteria.FungibleAssetQueryCriteria): Collection<Predicate>
fun parseCriteria(criteria: QueryCriteria.LinearStateQueryCriteria): Collection<Predicate>
fun <L: PersistentState> parseCriteria(criteria: QueryCriteria.VaultCustomQueryCriteria<L>): Collection<Predicate>
fun <L : PersistentState> parseCriteria(criteria: QueryCriteria.VaultCustomQueryCriteria<L>): Collection<Predicate>
fun parseCriteria(criteria: QueryCriteria.VaultQueryCriteria): Collection<Predicate>
fun parseOr(left: QueryCriteria, right: QueryCriteria): Collection<Predicate>
fun parseAnd(left: QueryCriteria, right: QueryCriteria): Collection<Predicate>
fun parse(criteria: QueryCriteria, sorting: Sort? = null) : Collection<Predicate>
fun parse(criteria: QueryCriteria, sorting: Sort? = null): Collection<Predicate>
}

View File

@ -170,8 +170,8 @@ data class Sort(val columns: Collection<SortColumn>) {
@CordaSerializable
data class SortColumn(
val sortAttribute: SortAttribute,
val direction: Sort.Direction = Sort.Direction.ASC)
val sortAttribute: SortAttribute,
val direction: Sort.Direction = Sort.Direction.ASC)
}
@CordaSerializable
@ -199,8 +199,9 @@ object Builder {
fun <R> Field.predicate(predicate: ColumnPredicate<R>) = CriteriaExpression.ColumnPredicateExpression(Column<Any, R>(this), predicate)
fun <O, R> KProperty1<O, R?>.functionPredicate(predicate: ColumnPredicate<R>, groupByColumns: List<Column<O, R>>? = null, orderBy: Sort.Direction? = null)
fun <O, R> KProperty1<O, R?>.functionPredicate(predicate: ColumnPredicate<R>, groupByColumns: List<Column<O, R>>? = null, orderBy: Sort.Direction? = null)
= CriteriaExpression.AggregateFunctionExpression(Column(this), predicate, groupByColumns, orderBy)
fun <R> Field.functionPredicate(predicate: ColumnPredicate<R>, groupByColumns: List<Column<Any, R>>? = null, orderBy: Sort.Direction? = null)
= CriteriaExpression.AggregateFunctionExpression(Column<Any, R>(this), predicate, groupByColumns, orderBy)
@ -217,15 +218,32 @@ object Builder {
fun <O, R : Comparable<R>> KProperty1<O, R?>.`in`(collection: Collection<R>) = predicate(ColumnPredicate.CollectionExpression(CollectionOperator.IN, collection))
fun <O, R : Comparable<R>> KProperty1<O, R?>.notIn(collection: Collection<R>) = predicate(ColumnPredicate.CollectionExpression(CollectionOperator.NOT_IN, collection))
@JvmStatic fun <R> Field.equal(value: R) = predicate(ColumnPredicate.EqualityComparison(EqualityComparisonOperator.EQUAL, value))
@JvmStatic fun <R> Field.notEqual(value: R) = predicate(ColumnPredicate.EqualityComparison(EqualityComparisonOperator.NOT_EQUAL, value))
@JvmStatic fun <R : Comparable<R>> Field.lessThan(value: R) = comparePredicate(BinaryComparisonOperator.LESS_THAN, value)
@JvmStatic fun <R : Comparable<R>> Field.lessThanOrEqual(value: R) = comparePredicate(BinaryComparisonOperator.LESS_THAN_OR_EQUAL, value)
@JvmStatic fun <R : Comparable<R>> Field.greaterThan(value: R) = comparePredicate(BinaryComparisonOperator.GREATER_THAN, value)
@JvmStatic fun <R : Comparable<R>> Field.greaterThanOrEqual(value: R) = comparePredicate(BinaryComparisonOperator.GREATER_THAN_OR_EQUAL, value)
@JvmStatic fun <R : Comparable<R>> Field.between(from: R, to: R) = predicate(ColumnPredicate.Between(from, to))
@JvmStatic fun <R : Comparable<R>> Field.`in`(collection: Collection<R>) = predicate(ColumnPredicate.CollectionExpression(CollectionOperator.IN, collection))
@JvmStatic fun <R : Comparable<R>> Field.notIn(collection: Collection<R>) = predicate(ColumnPredicate.CollectionExpression(CollectionOperator.NOT_IN, collection))
@JvmStatic
fun <R> Field.equal(value: R) = predicate(ColumnPredicate.EqualityComparison(EqualityComparisonOperator.EQUAL, value))
@JvmStatic
fun <R> Field.notEqual(value: R) = predicate(ColumnPredicate.EqualityComparison(EqualityComparisonOperator.NOT_EQUAL, value))
@JvmStatic
fun <R : Comparable<R>> Field.lessThan(value: R) = comparePredicate(BinaryComparisonOperator.LESS_THAN, value)
@JvmStatic
fun <R : Comparable<R>> Field.lessThanOrEqual(value: R) = comparePredicate(BinaryComparisonOperator.LESS_THAN_OR_EQUAL, value)
@JvmStatic
fun <R : Comparable<R>> Field.greaterThan(value: R) = comparePredicate(BinaryComparisonOperator.GREATER_THAN, value)
@JvmStatic
fun <R : Comparable<R>> Field.greaterThanOrEqual(value: R) = comparePredicate(BinaryComparisonOperator.GREATER_THAN_OR_EQUAL, value)
@JvmStatic
fun <R : Comparable<R>> Field.between(from: R, to: R) = predicate(ColumnPredicate.Between(from, to))
@JvmStatic
fun <R : Comparable<R>> Field.`in`(collection: Collection<R>) = predicate(ColumnPredicate.CollectionExpression(CollectionOperator.IN, collection))
@JvmStatic
fun <R : Comparable<R>> Field.notIn(collection: Collection<R>) = predicate(ColumnPredicate.CollectionExpression(CollectionOperator.NOT_IN, collection))
fun <R> equal(value: R) = ColumnPredicate.EqualityComparison(EqualityComparisonOperator.EQUAL, value)
fun <R> notEqual(value: R) = ColumnPredicate.EqualityComparison(EqualityComparisonOperator.NOT_EQUAL, value)
@ -238,45 +256,57 @@ object Builder {
fun <R : Comparable<R>> notIn(collection: Collection<R>) = ColumnPredicate.CollectionExpression(CollectionOperator.NOT_IN, collection)
fun <O> KProperty1<O, String?>.like(string: String) = predicate(ColumnPredicate.Likeness(LikenessOperator.LIKE, string))
@JvmStatic fun Field.like(string: String) = predicate(ColumnPredicate.Likeness(LikenessOperator.LIKE, string))
@JvmStatic
fun Field.like(string: String) = predicate(ColumnPredicate.Likeness(LikenessOperator.LIKE, string))
fun <O> KProperty1<O, String?>.notLike(string: String) = predicate(ColumnPredicate.Likeness(LikenessOperator.NOT_LIKE, string))
@JvmStatic fun Field.notLike(string: String) = predicate(ColumnPredicate.Likeness(LikenessOperator.NOT_LIKE, string))
@JvmStatic
fun Field.notLike(string: String) = predicate(ColumnPredicate.Likeness(LikenessOperator.NOT_LIKE, string))
fun <O, R> KProperty1<O, R?>.isNull() = predicate(ColumnPredicate.NullExpression(NullOperator.IS_NULL))
@JvmStatic fun Field.isNull() = predicate(ColumnPredicate.NullExpression<Any>(NullOperator.IS_NULL))
@JvmStatic
fun Field.isNull() = predicate(ColumnPredicate.NullExpression<Any>(NullOperator.IS_NULL))
fun <O, R> KProperty1<O, R?>.notNull() = predicate(ColumnPredicate.NullExpression(NullOperator.NOT_NULL))
@JvmStatic fun Field.notNull() = predicate(ColumnPredicate.NullExpression<Any>(NullOperator.NOT_NULL))
@JvmStatic
fun Field.notNull() = predicate(ColumnPredicate.NullExpression<Any>(NullOperator.NOT_NULL))
/** aggregate functions */
fun <O, R> KProperty1<O, R?>.sum(groupByColumns: List<KProperty1<O, R>>? = null, orderBy: Sort.Direction? = null) =
functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.SUM), groupByColumns?.map { Column(it) }, orderBy)
@JvmStatic @JvmOverloads
@JvmStatic
@JvmOverloads
fun <R> Field.sum(groupByColumns: List<Field>? = null, orderBy: Sort.Direction? = null) =
functionPredicate(ColumnPredicate.AggregateFunction<R>(AggregateFunctionType.SUM), groupByColumns?.map { Column<Any,R>(it) }, orderBy)
functionPredicate(ColumnPredicate.AggregateFunction<R>(AggregateFunctionType.SUM), groupByColumns?.map { Column<Any, R>(it) }, orderBy)
fun <O, R> KProperty1<O, R?>.count() = functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.COUNT))
@JvmStatic fun Field.count() = functionPredicate(ColumnPredicate.AggregateFunction<Any>(AggregateFunctionType.COUNT))
@JvmStatic
fun Field.count() = functionPredicate(ColumnPredicate.AggregateFunction<Any>(AggregateFunctionType.COUNT))
fun <O, R> KProperty1<O, R?>.avg(groupByColumns: List<KProperty1<O, R>>? = null, orderBy: Sort.Direction? = null) =
functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.AVG), groupByColumns?.map { Column(it) }, orderBy)
@JvmStatic
@JvmOverloads
fun <R> Field.avg(groupByColumns: List<Field>? = null, orderBy: Sort.Direction? = null) =
functionPredicate(ColumnPredicate.AggregateFunction<R>(AggregateFunctionType.AVG), groupByColumns?.map { Column<Any,R>(it) }, orderBy)
functionPredicate(ColumnPredicate.AggregateFunction<R>(AggregateFunctionType.AVG), groupByColumns?.map { Column<Any, R>(it) }, orderBy)
fun <O, R> KProperty1<O, R?>.min(groupByColumns: List<KProperty1<O, R>>? = null, orderBy: Sort.Direction? = null) =
functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.MIN), groupByColumns?.map { Column(it) }, orderBy)
@JvmStatic
@JvmOverloads
fun <R> Field.min(groupByColumns: List<Field>? = null, orderBy: Sort.Direction? = null) =
functionPredicate(ColumnPredicate.AggregateFunction<R>(AggregateFunctionType.MIN), groupByColumns?.map { Column<Any,R>(it) }, orderBy)
functionPredicate(ColumnPredicate.AggregateFunction<R>(AggregateFunctionType.MIN), groupByColumns?.map { Column<Any, R>(it) }, orderBy)
fun <O, R> KProperty1<O, R?>.max(groupByColumns: List<KProperty1<O, R>>? = null, orderBy: Sort.Direction? = null) =
functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.MAX), groupByColumns?.map { Column(it) }, orderBy)
@JvmStatic
@JvmOverloads
fun <R> Field.max(groupByColumns: List<Field>? = null, orderBy: Sort.Direction? = null) =
functionPredicate(ColumnPredicate.AggregateFunction<R>(AggregateFunctionType.MAX), groupByColumns?.map { Column<Any,R>(it) }, orderBy)
functionPredicate(ColumnPredicate.AggregateFunction<R>(AggregateFunctionType.MAX), groupByColumns?.map { Column<Any, R>(it) }, orderBy)
}
inline fun <A> builder(block: Builder.() -> A) = block(Builder)

View File

@ -38,9 +38,9 @@ object CommonSchemaV1 : MappedSchema(schemaFamily = CommonSchema.javaClass, vers
) : PersistentState() {
constructor(uid: UniqueIdentifier, _participants: Set<AbstractParty>)
: this(participants = _participants.toMutableSet(),
externalId = uid.externalId,
uuid = uid.id)
: this(participants = _participants.toMutableSet(),
externalId = uid.externalId,
uuid = uid.id)
}
@MappedSuperclass

View File

@ -31,8 +31,8 @@ object NodeInfoSchemaV1 : MappedSchema(
@Column(name = "legal_identities_certs")
@ManyToMany(cascade = arrayOf(CascadeType.ALL))
@JoinTable(name = "link_nodeinfo_party",
joinColumns = arrayOf(JoinColumn(name="node_info_id")),
inverseJoinColumns = arrayOf(JoinColumn(name="party_name")))
joinColumns = arrayOf(JoinColumn(name = "node_info_id")),
inverseJoinColumns = arrayOf(JoinColumn(name = "party_name")))
val legalIdentitiesAndCerts: List<DBPartyAndCertificate>,
@Column(name = "platform_version")
@ -64,14 +64,15 @@ object NodeInfoSchemaV1 : MappedSchema(
@Entity
data class DBHostAndPort(
@EmbeddedId
private val pk: PKHostAndPort
@EmbeddedId
private val pk: PKHostAndPort
) {
companion object {
fun fromHostAndPort(hostAndPort: NetworkHostAndPort) = DBHostAndPort(
PKHostAndPort(hostAndPort.host, hostAndPort.port)
)
}
fun toHostAndPort(): NetworkHostAndPort {
return NetworkHostAndPort(this.pk.host!!, this.pk.port!!)
}

View File

@ -49,7 +49,8 @@ open class MappedSchema(schemaFamily: Class<*>,
* A super class for all mapped states exported to a schema that ensures the [StateRef] appears on the database row. The
* [StateRef] will be set to the correct value by the framework (there's no need to set during mapping generation by the state itself).
*/
@MappedSuperclass @CordaSerializable open class PersistentState(@EmbeddedId var stateRef: PersistentStateRef? = null) : StatePersistable
@MappedSuperclass
@CordaSerializable open class PersistentState(@EmbeddedId var stateRef: PersistentStateRef? = null) : StatePersistable
/**
* Embedded [StateRef] representation used in state mapping.

View File

@ -115,6 +115,7 @@ interface SerializationContext {
* The use case we are serializing or deserializing for. See [UseCase].
*/
val useCase: UseCase
/**
* Helper method to return a new context based on this context with the property added.
*/

View File

@ -57,7 +57,7 @@ data class LedgerTransaction(
}
private val contracts: Map<ContractClassName, Try<Contract>> = (inputs.map { it.state.contract } + outputs.map { it.contract })
.toSet().map { it to createContractFor(it) }.toMap()
.toSet().map { it to createContractFor(it) }.toMap()
val inputStates: List<ContractState> get() = inputs.map { it.state.data }
@ -79,8 +79,7 @@ data class LedgerTransaction(
// TODO: make contract upgrade transactions have a separate type
if (commands.any { it.value is UpgradeCommand }) {
verifyContractUpgrade()
}
else {
} else {
verifyContracts()
}
}

View File

@ -48,7 +48,7 @@ abstract class TraversableTransaction(open val componentGroups: List<ComponentGr
* - list of each attachment that is present
* - The notary [Party], if present (list with one element)
* - The time-window of the transaction, if present (list with one element)
*/
*/
val availableComponentGroups: List<List<Any>>
get() {
val result = mutableListOf(inputs, outputs, commands, attachments)
@ -138,7 +138,7 @@ class FilteredTransaction private constructor(
fun updateFilteredComponents() {
wtx.inputs.forEachIndexed { internalIndex, it -> filter(it, ComponentGroupEnum.INPUTS_GROUP.ordinal, internalIndex) }
wtx.outputs.forEachIndexed { internalIndex, it -> filter(it, ComponentGroupEnum.OUTPUTS_GROUP.ordinal, internalIndex) }
wtx.commands.forEachIndexed { internalIndex, it -> filter(it, ComponentGroupEnum.COMMANDS_GROUP.ordinal, internalIndex) }
wtx.commands.forEachIndexed { internalIndex, it -> filter(it, ComponentGroupEnum.COMMANDS_GROUP.ordinal, internalIndex) }
wtx.attachments.forEachIndexed { internalIndex, it -> filter(it, ComponentGroupEnum.ATTACHMENTS_GROUP.ordinal, internalIndex) }
if (wtx.notary != null) filter(wtx.notary, ComponentGroupEnum.NOTARY_GROUP.ordinal, 0)
if (wtx.timeWindow != null) filter(wtx.timeWindow, ComponentGroupEnum.TIMEWINDOW_GROUP.ordinal, 0)
@ -147,7 +147,7 @@ class FilteredTransaction private constructor(
// we decide to filter and attach this field to a FilteredTransaction.
// An example would be to redact certain contract state types, but otherwise leave a transaction alone,
// including the unknown new components.
wtx.componentGroups.filter { it.groupIndex >= ComponentGroupEnum.values().size }.forEach { componentGroup -> componentGroup.components.forEachIndexed { internalIndex, component-> filter(component, componentGroup.groupIndex, internalIndex) }}
wtx.componentGroups.filter { it.groupIndex >= ComponentGroupEnum.values().size }.forEach { componentGroup -> componentGroup.components.forEachIndexed { internalIndex, component -> filter(component, componentGroup.groupIndex, internalIndex) } }
}
fun createPartialMerkleTree(componentGroupIndex: Int) = PartialMerkleTree.build(MerkleTree.getMerkleTree(wtx.availableComponentHashes[componentGroupIndex]!!), filteredComponentHashes[componentGroupIndex]!!)
@ -156,7 +156,7 @@ class FilteredTransaction private constructor(
updateFilteredComponents()
val filteredComponentGroups: MutableList<FilteredComponentGroup> = mutableListOf()
filteredSerialisedComponents.forEach { (groupIndex, value) ->
filteredComponentGroups.add(FilteredComponentGroup(groupIndex, value, filteredComponentNonces[groupIndex]!!, createPartialMerkleTree(groupIndex) ))
filteredComponentGroups.add(FilteredComponentGroup(groupIndex, value, filteredComponentNonces[groupIndex]!!, createPartialMerkleTree(groupIndex)))
}
return filteredComponentGroups
}
@ -183,7 +183,7 @@ class FilteredTransaction private constructor(
// Compute partial Merkle roots for each filtered component and verify each of the partial Merkle trees.
filteredComponentGroups.forEach { (groupIndex, components, nonces, groupPartialTree) ->
verificationCheck(groupIndex < groupHashes.size ) { "There is no matching component group hash for group $groupIndex" }
verificationCheck(groupIndex < groupHashes.size) { "There is no matching component group hash for group $groupIndex" }
val groupMerkleRoot = groupHashes[groupIndex]
verificationCheck(groupMerkleRoot == PartialMerkleTree.rootAndUsedHashes(groupPartialTree.root, mutableListOf())) { "Partial Merkle tree root and advertised full Merkle tree root for component group $groupIndex do not match" }
verificationCheck(groupPartialTree.verify(groupMerkleRoot, components.mapIndexed { index, component -> componentHash(nonces[index], component) })) { "Visible components in group $groupIndex cannot be verified against their partial Merkle tree" }
@ -226,7 +226,7 @@ class FilteredTransaction private constructor(
"Did not receive components for group ${componentGroupEnum.ordinal} and cannot verify they didn't exist in the original wire transaction"
}
} else {
visibilityCheck(group.groupIndex < groupHashes.size ) { "There is no matching component group hash for group ${group.groupIndex}" }
visibilityCheck(group.groupIndex < groupHashes.size) { "There is no matching component group hash for group ${group.groupIndex}" }
val groupPartialRoot = groupHashes[group.groupIndex]
val groupFullRoot = MerkleTree.getMerkleTree(group.components.mapIndexed { index, component -> componentHash(group.nonces[index], component) }).hash
visibilityCheck(groupPartialRoot == groupFullRoot) { "The partial Merkle tree root does not match with the received root for group ${group.groupIndex}" }
@ -253,7 +253,7 @@ class FilteredTransaction private constructor(
* This is similar to [ComponentGroup], but it also includes the corresponding nonce per component.
*/
@CordaSerializable
data class FilteredComponentGroup(override val groupIndex: Int, override val components: List<OpaqueBytes>, val nonces: List<SecureHash>, val partialMerkleTree: PartialMerkleTree): ComponentGroup(groupIndex, components) {
data class FilteredComponentGroup(override val groupIndex: Int, override val components: List<OpaqueBytes>, val nonces: List<SecureHash>, val partialMerkleTree: PartialMerkleTree) : ComponentGroup(groupIndex, components) {
init {
check(components.size == nonces.size) { "Size of transaction components and nonces do not match" }
}

View File

@ -12,4 +12,4 @@ import net.corda.core.serialization.CordaSerializable
*/
@CordaSerializable
class MissingContractAttachments(val states: List<TransactionState<ContractState>>)
: FlowException("Cannot find contract attachments for ${states.map { it.contract }.distinct() }")
: FlowException("Cannot find contract attachments for ${states.map { it.contract }.distinct()}")

View File

@ -47,7 +47,8 @@ data class SignedTransaction(val txBits: SerializedBytes<CoreTransaction>,
}
/** Cache the deserialized form of the transaction. This is useful when building a transaction or collecting signatures. */
@Volatile @Transient private var cachedTransaction: CoreTransaction? = null
@Volatile
@Transient private var cachedTransaction: CoreTransaction? = null
/** Lazily calculated access to the deserialised/hashed transaction data. */
private val transaction: CoreTransaction get() = cachedTransaction ?: txBits.deserialize().apply { cachedTransaction = this }

View File

@ -38,8 +38,8 @@ open class TransactionBuilder(
protected val commands: MutableList<Command<*>> = arrayListOf(),
protected var window: TimeWindow? = null,
protected var privacySalt: PrivacySalt = PrivacySalt()
) {
constructor(notary: Party) : this (notary, (Strand.currentStrand() as? FlowStateMachine<*>)?.id?.uuid ?: UUID.randomUUID())
) {
constructor(notary: Party) : this(notary, (Strand.currentStrand() as? FlowStateMachine<*>)?.id?.uuid ?: UUID.randomUUID())
/**
* Creates a copy of the builder.
@ -179,6 +179,7 @@ open class TransactionBuilder(
// Accessors that yield immutable snapshots.
fun inputStates(): List<StateRef> = ArrayList(inputs)
fun attachments(): List<SecureHash> = ArrayList(attachments)
fun outputStates(): List<TransactionState<*>> = ArrayList(outputs)
fun commands(): List<Command<*>> = ArrayList(commands)

View File

@ -63,15 +63,16 @@ class WireTransaction(componentGroups: List<ComponentGroup>, val privacySalt: Pr
override val id: SecureHash get() = merkleTree.hash
/** Public keys that need to be fulfilled by signatures in order for the transaction to be valid. */
val requiredSigningKeys: Set<PublicKey> get() {
val commandKeys = commands.flatMap { it.signers }.toSet()
// TODO: prevent notary field from being set if there are no inputs and no timestamp.
return if (notary != null && (inputs.isNotEmpty() || timeWindow != null)) {
commandKeys + notary.owningKey
} else {
commandKeys
val requiredSigningKeys: Set<PublicKey>
get() {
val commandKeys = commands.flatMap { it.signers }.toSet()
// TODO: prevent notary field from being set if there are no inputs and no timestamp.
return if (notary != null && (inputs.isNotEmpty() || timeWindow != null)) {
commandKeys + notary.owningKey
} else {
commandKeys
}
}
}
/**
* Looks up identities and attachments from storage to generate a [LedgerTransaction]. A transaction is expected to
@ -84,7 +85,7 @@ class WireTransaction(componentGroups: List<ComponentGroup>, val privacySalt: Pr
fun toLedgerTransaction(services: ServicesForResolution): LedgerTransaction {
return toLedgerTransaction(
resolveIdentity = { services.identityService.partyFromKey(it) },
resolveAttachment = { services.attachments.openAttachment(it)},
resolveAttachment = { services.attachments.openAttachment(it) },
resolveStateRef = { services.loadState(it) },
resolveContractAttachment = { services.cordappProvider.getContractAttachmentID(it.contract) }
)
@ -123,7 +124,7 @@ class WireTransaction(componentGroups: List<ComponentGroup>, val privacySalt: Pr
* Build filtered transaction using provided filtering functions.
*/
fun buildFilteredTransaction(filtering: Predicate<Any>): FilteredTransaction =
FilteredTransaction.buildFilteredTransaction(this, filtering)
FilteredTransaction.buildFilteredTransaction(this, filtering)
/**
* Builds whole Merkle tree for a transaction.
@ -236,7 +237,7 @@ class WireTransaction(componentGroups: List<ComponentGroup>, val privacySalt: Pr
): List<Attachment> {
val contractAttachments = (outputs + resolvedInputs.map { it.state }).map { Pair(it, resolveContractAttachment(it)) }
val missingAttachments = contractAttachments.filter { it.second == null }
return if(missingAttachments.isEmpty()) {
return if (missingAttachments.isEmpty()) {
contractAttachments.map { ContractAttachment(resolveAttachment(it.second!!) ?: throw AttachmentResolutionException(it.second!!), it.first.contract) }
} else {
throw MissingContractAttachments(missingAttachments.map { it.first })

View File

@ -25,6 +25,7 @@ sealed class ByteSequence : Comparable<ByteSequence> {
* The start position of the sequence within the byte array.
*/
abstract val offset: Int
/** Returns a [ByteArrayInputStream] of the bytes */
fun open() = ByteArrayInputStream(bytes, offset, size)

View File

@ -66,5 +66,6 @@ fun String.hexToBase64(): String = hexToByteArray().toBase64()
// TODO: follow the crypto-conditions ASN.1 spec, some changes are needed to be compatible with the condition
// structure, e.g. mapping a PublicKey to a condition with the specific feature (ED25519).
fun parsePublicKeyBase58(base58String: String): PublicKey = base58String.base58ToByteArray().deserialize<PublicKey>()
fun PublicKey.toBase58String(): String = this.serialize().bytes.toBase58()
fun PublicKey.toSHA256Bytes(): ByteArray = this.serialize().bytes.sha256().bytes // TODO: decide on the format of hashed key (encoded Vs serialised).

View File

@ -27,7 +27,7 @@ data class NetworkHostAndPort(val host: String, val port: Int) {
fun parse(str: String): NetworkHostAndPort {
val uri = try {
URI(null, str, null, null, null)
} catch(ex: URISyntaxException) {
} catch (ex: URISyntaxException) {
throw IllegalArgumentException("Host and port syntax is invalid, expected host:port")
}
require(uri.host != null) { NetworkHostAndPort.UNPARSEABLE_ADDRESS_FORMAT.format(str) }

View File

@ -48,11 +48,13 @@ class NonEmptySet<T> private constructor(private val elements: Set<T>) : Set<T>
/** Returns the first element of the set. */
fun head(): T = elements.iterator().next()
override fun isEmpty(): Boolean = false
override fun iterator() = object : Iterator<T> by elements.iterator() {}
// Following methods are not delegated by Kotlin's Class delegation
override fun forEach(action: Consumer<in T>) = elements.forEach(action)
override fun stream(): Stream<T> = elements.stream()
override fun parallelStream(): Stream<T> = elements.parallelStream()
override fun spliterator(): Spliterator<T> = elements.spliterator()

View File

@ -45,11 +45,11 @@ class CompatibleTransactionTests : TestDependencyInjectionBase() {
// Do not add attachments (empty list).
private val componentGroupsA by lazy {
listOf(
inputGroup,
outputGroup,
commandGroup,
notaryGroup,
timeWindowGroup
inputGroup,
outputGroup,
commandGroup,
notaryGroup,
timeWindowGroup
)
}
private val wireTransactionA by lazy { WireTransaction(componentGroups = componentGroupsA, privacySalt = privacySalt) }
@ -199,6 +199,7 @@ class CompatibleTransactionTests : TestDependencyInjectionBase() {
else -> false
}
}
val ftxInputs = wireTransactionA.buildFilteredTransaction(Predicate(::filtering)) // Inputs only filtered.
ftxInputs.verify()
ftxInputs.checkAllComponentsVisible(INPUTS_GROUP)
@ -210,6 +211,7 @@ class CompatibleTransactionTests : TestDependencyInjectionBase() {
// Filter one input only.
fun filteringOneInput(elem: Any) = elem == inputs[0]
val ftxOneInput = wireTransactionA.buildFilteredTransaction(Predicate(::filteringOneInput)) // First input only filtered.
ftxOneInput.verify()
assertFailsWith<ComponentVisibilityException> { ftxOneInput.checkAllComponentsVisible(INPUTS_GROUP) }

View File

@ -20,7 +20,7 @@ class X509NameConstraintsTest {
private fun makeKeyStores(subjectName: X500Name, nameConstraints: NameConstraints): Pair<KeyStore, KeyStore> {
val rootKeys = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
val rootCACert = X509Utilities.createSelfSignedCACertificate(CordaX500Name(commonName = "Corda Root CA", organisation = "R3 Ltd", locality= "London", country = "GB"), rootKeys)
val rootCACert = X509Utilities.createSelfSignedCACertificate(CordaX500Name(commonName = "Corda Root CA", organisation = "R3 Ltd", locality = "London", country = "GB"), rootKeys)
val intermediateCAKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
val intermediateCACert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, rootCACert, rootKeys, CordaX500Name(commonName = "Corda Intermediate CA", organisation = "R3 Ltd", locality = "London", country = "GB"), intermediateCAKeyPair.public)

View File

@ -161,14 +161,14 @@ class ContractUpgradeFlowTest {
assertFailsWith(UnexpectedFlowEndException::class) { rejectedFuture.getOrThrow() }
// Party B authorise the contract state upgrade, and immediately deauthorise the same.
rpcB.startFlow( { stateAndRef, upgrade -> ContractUpgradeFlow.Authorise(stateAndRef, upgrade ) },
rpcB.startFlow({ stateAndRef, upgrade -> ContractUpgradeFlow.Authorise(stateAndRef, upgrade) },
btx!!.tx.outRef<ContractState>(0),
DummyContractV2::class.java).returnValue
rpcB.startFlow( { stateRef -> ContractUpgradeFlow.Deauthorise(stateRef) },
rpcB.startFlow({ stateRef -> ContractUpgradeFlow.Deauthorise(stateRef) },
btx.tx.outRef<ContractState>(0).ref).returnValue
// The request is expected to be rejected because party B has subsequently deauthorised and a previously authorised upgrade.
val deauthorisedFuture = rpcA.startFlow( {stateAndRef, upgrade -> ContractUpgradeFlow.Initiate(stateAndRef, upgrade) },
val deauthorisedFuture = rpcA.startFlow({ stateAndRef, upgrade -> ContractUpgradeFlow.Initiate(stateAndRef, upgrade) },
atx.tx.outRef<DummyContract.State>(0),
DummyContractV2::class.java).returnValue
@ -176,7 +176,7 @@ class ContractUpgradeFlowTest {
assertFailsWith(UnexpectedFlowEndException::class) { deauthorisedFuture.getOrThrow() }
// Party B authorise the contract state upgrade.
rpcB.startFlow( { stateAndRef, upgrade -> ContractUpgradeFlow.Authorise(stateAndRef, upgrade ) },
rpcB.startFlow({ stateAndRef, upgrade -> ContractUpgradeFlow.Authorise(stateAndRef, upgrade) },
btx.tx.outRef<ContractState>(0),
DummyContractV2::class.java).returnValue

View File

@ -15,11 +15,11 @@ import kotlin.test.assertFailsWith
import kotlin.test.assertTrue
class TestX509Key(algorithmId: AlgorithmId, key: BitArray) : X509Key() {
init {
this.algid = algorithmId
this.setKey(key)
this.encode()
}
init {
this.algid = algorithmId
this.setKey(key)
this.encode()
}
}
class X509EdDSAEngineTest {

View File

@ -45,6 +45,7 @@ private fun Attachment.extractContent() = ByteArrayOutputStream().apply { extrac
private fun StartedNode<*>.saveAttachment(content: String) = database.transaction {
attachments.importAttachment(createAttachmentData(content).inputStream())
}
private fun StartedNode<*>.hackAttachment(attachmentId: SecureHash, content: String) = database.transaction {
updateAttachment(attachmentId, createAttachmentData(content))
}