mirror of
https://github.com/corda/corda.git
synced 2025-06-18 15:18:16 +00:00
Minor: core: fix static analysis warnings.
One actual bug was found this way, albeit a harmless one.
This commit is contained in:
@ -80,9 +80,6 @@ dependencies {
|
|||||||
// JPA 2.1 annotations.
|
// JPA 2.1 annotations.
|
||||||
compile "org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.0.Final"
|
compile "org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.0.Final"
|
||||||
|
|
||||||
// RS API: Response type and codes for ApiUtils.
|
|
||||||
compile "javax.ws.rs:javax.ws.rs-api:2.0.1"
|
|
||||||
|
|
||||||
// Requery: SQL based query & persistence for Kotlin
|
// Requery: SQL based query & persistence for Kotlin
|
||||||
compile "io.requery:requery-kotlin:$requery_version"
|
compile "io.requery:requery-kotlin:$requery_version"
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ infix fun <T> ListenableFuture<T>.then(body: () -> Unit): ListenableFuture<T> =
|
|||||||
infix fun <T> ListenableFuture<T>.success(body: (T) -> Unit): ListenableFuture<T> = apply { success(RunOnCallerThread, body) }
|
infix fun <T> ListenableFuture<T>.success(body: (T) -> Unit): ListenableFuture<T> = apply { success(RunOnCallerThread, body) }
|
||||||
infix fun <T> ListenableFuture<T>.failure(body: (Throwable) -> Unit): ListenableFuture<T> = apply { failure(RunOnCallerThread, body) }
|
infix fun <T> ListenableFuture<T>.failure(body: (Throwable) -> Unit): ListenableFuture<T> = apply { failure(RunOnCallerThread, body) }
|
||||||
@Suppress("UNCHECKED_CAST") // We need the awkward cast because otherwise F cannot be nullable, even though it's safe.
|
@Suppress("UNCHECKED_CAST") // We need the awkward cast because otherwise F cannot be nullable, even though it's safe.
|
||||||
infix fun <F, T> ListenableFuture<F>.map(mapper: (F) -> T): ListenableFuture<T> = Futures.transform(this, Function { (mapper as (F?) -> T)(it) })
|
infix fun <F, T> ListenableFuture<F>.map(mapper: (F) -> T): ListenableFuture<T> = Futures.transform(this, { (mapper as (F?) -> T)(it) })
|
||||||
|
|
||||||
infix fun <F, T> ListenableFuture<F>.flatMap(mapper: (F) -> ListenableFuture<T>): ListenableFuture<T> = Futures.transformAsync(this) { mapper(it!!) }
|
infix fun <F, T> ListenableFuture<F>.flatMap(mapper: (F) -> ListenableFuture<T>): ListenableFuture<T> = Futures.transformAsync(this) { mapper(it!!) }
|
||||||
/** Executes the given block and sets the future to either the result, or any exception that was thrown. */
|
/** Executes the given block and sets the future to either the result, or any exception that was thrown. */
|
||||||
@ -156,7 +156,7 @@ fun Path.writeLines(lines: Iterable<CharSequence>, charset: Charset = UTF_8, var
|
|||||||
fun InputStream.copyTo(target: Path, vararg options: CopyOption): Long = Files.copy(this, target, *options)
|
fun InputStream.copyTo(target: Path, vararg options: CopyOption): Long = Files.copy(this, target, *options)
|
||||||
|
|
||||||
// Simple infix function to add back null safety that the JDK lacks: timeA until timeB
|
// Simple infix function to add back null safety that the JDK lacks: timeA until timeB
|
||||||
infix fun Temporal.until(endExclusive: Temporal) = Duration.between(this, endExclusive)
|
infix fun Temporal.until(endExclusive: Temporal): Duration = Duration.between(this, endExclusive)
|
||||||
|
|
||||||
/** Returns the index of the given item or throws [IllegalArgumentException] if not found. */
|
/** Returns the index of the given item or throws [IllegalArgumentException] if not found. */
|
||||||
fun <T> List<T>.indexOfOrThrow(item: T): Int {
|
fun <T> List<T>.indexOfOrThrow(item: T): Int {
|
||||||
@ -349,6 +349,7 @@ data class InputStreamAndHash(val inputStream: InputStream, val sha256: SecureHa
|
|||||||
val Throwable.rootCause: Throwable get() = Throwables.getRootCause(this)
|
val Throwable.rootCause: Throwable get() = Throwables.getRootCause(this)
|
||||||
|
|
||||||
/** Representation of an operation that may have thrown an error. */
|
/** Representation of an operation that may have thrown an error. */
|
||||||
|
@Suppress("DataClassPrivateConstructor")
|
||||||
@CordaSerializable
|
@CordaSerializable
|
||||||
data class ErrorOr<out A> private constructor(val value: A?, val error: Throwable?) {
|
data class ErrorOr<out A> private constructor(val value: A?, val error: Throwable?) {
|
||||||
// The ErrorOr holds a value iff error == null
|
// The ErrorOr holds a value iff error == null
|
||||||
|
@ -103,18 +103,6 @@ inline fun <reified T : CommandData> Collection<AuthenticatedObject<CommandData>
|
|||||||
fun <C : CommandData> Collection<AuthenticatedObject<CommandData>>.requireSingleCommand(klass: Class<C>) =
|
fun <C : CommandData> Collection<AuthenticatedObject<CommandData>>.requireSingleCommand(klass: Class<C>) =
|
||||||
mapNotNull { @Suppress("UNCHECKED_CAST") if (klass.isInstance(it.value)) it as AuthenticatedObject<C> else null }.single()
|
mapNotNull { @Suppress("UNCHECKED_CAST") if (klass.isInstance(it.value)) it as AuthenticatedObject<C> else null }.single()
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple functionality for verifying a move command. Verifies that each input has a signature from its owning key.
|
|
||||||
*
|
|
||||||
* @param T the type of the move command.
|
|
||||||
*/
|
|
||||||
@Throws(IllegalArgumentException::class)
|
|
||||||
// TODO: Can we have a common Move command for all contracts and avoid the reified type parameter here?
|
|
||||||
inline fun <reified T : MoveCommand> verifyMoveCommand(inputs: List<OwnableState>,
|
|
||||||
tx: TransactionForContract)
|
|
||||||
: MoveCommand
|
|
||||||
= verifyMoveCommand<T>(inputs, tx.commands)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple functionality for verifying a move command. Verifies that each input has a signature from its owning key.
|
* Simple functionality for verifying a move command. Verifies that each input has a signature from its owning key.
|
||||||
*
|
*
|
||||||
|
@ -267,7 +267,7 @@ fun <T : Any> Iterable<Amount<T>>.sumOrZero(token: T) = if (iterator().hasNext()
|
|||||||
* @see SourceAndAmount.apply which processes a list of SourceAndAmount objects
|
* @see SourceAndAmount.apply which processes a list of SourceAndAmount objects
|
||||||
* and calculates the resulting Amount distribution as a new list of SourceAndAmount objects.
|
* and calculates the resulting Amount distribution as a new list of SourceAndAmount objects.
|
||||||
*/
|
*/
|
||||||
data class SourceAndAmount<T : Any, P : Any>(val source: P, val amount: Amount<T>, val ref: Any? = null)
|
data class SourceAndAmount<T : Any, out P : Any>(val source: P, val amount: Amount<T>, val ref: Any? = null)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class represents a possibly negative transfer of tokens from one vault state to another, possibly at a future date.
|
* This class represents a possibly negative transfer of tokens from one vault state to another, possibly at a future date.
|
||||||
@ -516,7 +516,7 @@ data class Tenor(val name: String) {
|
|||||||
val adjustedMaturityDate = calendar.applyRollConvention(maturityDate, DateRollConvention.ModifiedFollowing)
|
val adjustedMaturityDate = calendar.applyRollConvention(maturityDate, DateRollConvention.ModifiedFollowing)
|
||||||
val daysToMaturity = calculateDaysBetween(startDate, adjustedMaturityDate, DayCountBasisYear.Y360, DayCountBasisDay.DActual)
|
val daysToMaturity = calculateDaysBetween(startDate, adjustedMaturityDate, DayCountBasisYear.Y360, DayCountBasisDay.DActual)
|
||||||
|
|
||||||
return daysToMaturity.toInt()
|
return daysToMaturity
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String = name
|
override fun toString(): String = name
|
||||||
@ -645,7 +645,7 @@ open class BusinessCalendar private constructor(val holidayDates: List<LocalDate
|
|||||||
}.toMap()
|
}.toMap()
|
||||||
|
|
||||||
/** Parses a date of the form YYYY-MM-DD, like 2016-01-10 for 10th Jan. */
|
/** Parses a date of the form YYYY-MM-DD, like 2016-01-10 for 10th Jan. */
|
||||||
fun parseDateFromString(it: String) = LocalDate.parse(it, DateTimeFormatter.ISO_LOCAL_DATE)
|
fun parseDateFromString(it: String): LocalDate = LocalDate.parse(it, DateTimeFormatter.ISO_LOCAL_DATE)
|
||||||
|
|
||||||
/** Returns a business calendar that combines all the named holiday calendars into one list of holiday dates. */
|
/** Returns a business calendar that combines all the named holiday calendars into one list of holiday dates. */
|
||||||
fun getInstance(vararg calname: String) = BusinessCalendar(
|
fun getInstance(vararg calname: String) = BusinessCalendar(
|
||||||
|
@ -52,7 +52,7 @@ interface MultilateralNettableState<out T : Any> {
|
|||||||
val multilateralNetState: T
|
val multilateralNetState: T
|
||||||
}
|
}
|
||||||
|
|
||||||
interface NettableState<N : BilateralNettableState<N>, T : Any> : BilateralNettableState<N>,
|
interface NettableState<N : BilateralNettableState<N>, out T : Any> : BilateralNettableState<N>,
|
||||||
MultilateralNettableState<T>
|
MultilateralNettableState<T>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -145,26 +145,13 @@ data class TransactionState<out T : ContractState> @JvmOverloads constructor(
|
|||||||
* Note that an encumbered state that is being consumed must have its encumbrance consumed in the same transaction,
|
* Note that an encumbered state that is being consumed must have its encumbrance consumed in the same transaction,
|
||||||
* otherwise the transaction is not valid.
|
* otherwise the transaction is not valid.
|
||||||
*/
|
*/
|
||||||
val encumbrance: Int? = null) {
|
val encumbrance: Int? = null)
|
||||||
|
|
||||||
/**
|
|
||||||
* Copies the underlying state, replacing the notary field with the new value.
|
|
||||||
* To replace the notary, we need an approval (signature) from _all_ participants of the [ContractState].
|
|
||||||
*/
|
|
||||||
fun withNotary(newNotary: Party) = TransactionState(this.data, newNotary, encumbrance)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Wraps the [ContractState] in a [TransactionState] object */
|
/** Wraps the [ContractState] in a [TransactionState] object */
|
||||||
infix fun <T : ContractState> T.`with notary`(newNotary: Party) = withNotary(newNotary)
|
infix fun <T : ContractState> T.`with notary`(newNotary: Party) = withNotary(newNotary)
|
||||||
|
|
||||||
infix fun <T : ContractState> T.withNotary(newNotary: Party) = TransactionState(this, newNotary)
|
infix fun <T : ContractState> T.withNotary(newNotary: Party) = TransactionState(this, newNotary)
|
||||||
|
|
||||||
/**
|
|
||||||
* Marker interface for data classes that represent the issuance state for a contract. These are intended as templates
|
|
||||||
* from which the state object is initialised.
|
|
||||||
*/
|
|
||||||
interface IssuanceDefinition
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Definition for an issued product, which can be cash, a cash-like thing, assets, or generally anything else that's
|
* Definition for an issued product, which can be cash, a cash-like thing, assets, or generally anything else that's
|
||||||
* quantifiable with integer quantities.
|
* quantifiable with integer quantities.
|
||||||
@ -243,7 +230,7 @@ interface LinearState : ContractState {
|
|||||||
* Standard clause to verify the LinearState safety properties.
|
* Standard clause to verify the LinearState safety properties.
|
||||||
*/
|
*/
|
||||||
@CordaSerializable
|
@CordaSerializable
|
||||||
class ClauseVerifier<S : LinearState, C : CommandData> : Clause<S, C, Unit>() {
|
class ClauseVerifier<in S : LinearState, C : CommandData> : Clause<S, C, Unit>() {
|
||||||
override fun verify(tx: TransactionForContract,
|
override fun verify(tx: TransactionForContract,
|
||||||
inputs: List<S>,
|
inputs: List<S>,
|
||||||
outputs: List<S>,
|
outputs: List<S>,
|
||||||
@ -360,7 +347,7 @@ inline fun <reified T : ContractState> Iterable<StateAndRef<ContractState>>.filt
|
|||||||
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"
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Marker interface for classes that represent commands */
|
/** Marker interface for classes that represent commands */
|
||||||
|
@ -95,9 +95,6 @@ class AttachmentResolutionException(val hash: SecureHash) : FlowException() {
|
|||||||
override fun toString(): String = "Attachment resolution failure for $hash"
|
override fun toString(): String = "Attachment resolution failure for $hash"
|
||||||
}
|
}
|
||||||
|
|
||||||
@CordaSerializable
|
|
||||||
class TransactionConflictException(val conflictRef: StateRef, val tx1: LedgerTransaction, val tx2: LedgerTransaction) : Exception()
|
|
||||||
|
|
||||||
sealed class TransactionVerificationException(val tx: LedgerTransaction, cause: Throwable?) : FlowException(cause) {
|
sealed class TransactionVerificationException(val tx: LedgerTransaction, cause: Throwable?) : FlowException(cause) {
|
||||||
class ContractRejection(tx: LedgerTransaction, val contract: Contract, cause: Throwable?) : TransactionVerificationException(tx, cause)
|
class ContractRejection(tx: LedgerTransaction, val contract: Contract, cause: Throwable?) : TransactionVerificationException(tx, cause)
|
||||||
class MoreThanOneNotary(tx: LedgerTransaction) : TransactionVerificationException(tx, null)
|
class MoreThanOneNotary(tx: LedgerTransaction) : TransactionVerificationException(tx, null)
|
||||||
|
@ -19,7 +19,7 @@ open class AllOf<S : ContractState, C : CommandData, K : Any>(firstClause: Claus
|
|||||||
|
|
||||||
override fun matchedClauses(commands: List<AuthenticatedObject<C>>): List<Clause<S, C, K>> {
|
override fun matchedClauses(commands: List<AuthenticatedObject<C>>): List<Clause<S, C, K>> {
|
||||||
clauses.forEach { clause ->
|
clauses.forEach { clause ->
|
||||||
check(clause.matches(commands)) { "Failed to match clause ${clause}" }
|
check(clause.matches(commands)) { "Failed to match clause $clause" }
|
||||||
}
|
}
|
||||||
return clauses
|
return clauses
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ fun <C : CommandData> verifyClause(tx: TransactionForContract,
|
|||||||
commands: List<AuthenticatedObject<C>>) {
|
commands: List<AuthenticatedObject<C>>) {
|
||||||
if (Clause.log.isTraceEnabled) {
|
if (Clause.log.isTraceEnabled) {
|
||||||
clause.getExecutionPath(commands).forEach {
|
clause.getExecutionPath(commands).forEach {
|
||||||
Clause.log.trace("Tx ${tx.origHash} clause: ${clause}")
|
Clause.log.trace("Tx ${tx.origHash} clause: $clause")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val matchedCommands = clause.verify(tx, tx.inputs, tx.outputs, commands, null)
|
val matchedCommands = clause.verify(tx, tx.inputs, tx.outputs, commands, null)
|
||||||
|
@ -8,7 +8,7 @@ import net.corda.core.contracts.TransactionForContract
|
|||||||
/**
|
/**
|
||||||
* Filter the states that are passed through to the wrapped clause, to restrict them to a specific type.
|
* Filter the states that are passed through to the wrapped clause, to restrict them to a specific type.
|
||||||
*/
|
*/
|
||||||
class FilterOn<S : ContractState, C : CommandData, K : Any>(val clause: Clause<S, C, K>,
|
class FilterOn<S : ContractState, C : CommandData, in K : Any>(val clause: Clause<S, C, K>,
|
||||||
val filterStates: (List<ContractState>) -> List<S>) : Clause<ContractState, C, K>() {
|
val filterStates: (List<ContractState>) -> List<S>) : Clause<ContractState, C, K>() {
|
||||||
override val requiredCommands: Set<Class<out CommandData>>
|
override val requiredCommands: Set<Class<out CommandData>>
|
||||||
= clause.requiredCommands
|
= clause.requiredCommands
|
||||||
|
@ -10,7 +10,7 @@ import java.util.*
|
|||||||
/**
|
/**
|
||||||
* Compose a number of clauses, such that the first match is run, and it errors if none is run.
|
* Compose a number of clauses, such that the first match is run, and it errors if none is run.
|
||||||
*/
|
*/
|
||||||
class FirstOf<S : ContractState, C : CommandData, K : Any>(val firstClause: Clause<S, C, K>, vararg remainingClauses: Clause<S, C, K>) : CompositeClause<S, C, K>() {
|
class FirstOf<S : ContractState, C : CommandData, K : Any>(firstClause: Clause<S, C, K>, vararg remainingClauses: Clause<S, C, K>) : CompositeClause<S, C, K>() {
|
||||||
companion object {
|
companion object {
|
||||||
val logger = loggerFor<FirstOf<*, *, *>>()
|
val logger = loggerFor<FirstOf<*, *, *>>()
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ object Crypto {
|
|||||||
* @return a currently supported SignatureScheme.
|
* @return a currently supported SignatureScheme.
|
||||||
* @throws IllegalArgumentException if the requested signature scheme is not supported.
|
* @throws IllegalArgumentException if the requested signature scheme is not supported.
|
||||||
*/
|
*/
|
||||||
private fun findSignatureScheme(schemeCodeName: String): SignatureScheme = supportedSignatureSchemes[schemeCodeName] ?: throw IllegalArgumentException("Unsupported key/algorithm for metadata schemeCodeName: ${schemeCodeName}")
|
private fun findSignatureScheme(schemeCodeName: String): SignatureScheme = supportedSignatureSchemes[schemeCodeName] ?: throw IllegalArgumentException("Unsupported key/algorithm for metadata schemeCodeName: $schemeCodeName")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the corresponding [SignatureScheme] based on the type of the input [KeyPair].
|
* Retrieve the corresponding [SignatureScheme] based on the type of the input [KeyPair].
|
||||||
|
@ -10,6 +10,7 @@ import net.i2p.crypto.eddsa.EdDSAEngine
|
|||||||
import net.i2p.crypto.eddsa.EdDSAPrivateKey
|
import net.i2p.crypto.eddsa.EdDSAPrivateKey
|
||||||
import net.i2p.crypto.eddsa.EdDSAPublicKey
|
import net.i2p.crypto.eddsa.EdDSAPublicKey
|
||||||
import net.i2p.crypto.eddsa.KeyPairGenerator
|
import net.i2p.crypto.eddsa.KeyPairGenerator
|
||||||
|
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveSpec
|
||||||
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable
|
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
|
||||||
@ -72,7 +73,7 @@ fun PrivateKey.signWithECDSA(bytesToSign: ByteArray, publicKey: PublicKey): Digi
|
|||||||
return DigitalSignature.WithKey(publicKey, signWithECDSA(bytesToSign).bytes)
|
return DigitalSignature.WithKey(publicKey, signWithECDSA(bytesToSign).bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
val ed25519Curve = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.CURVE_ED25519_SHA512)
|
val ed25519Curve: EdDSANamedCurveSpec = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.CURVE_ED25519_SHA512)
|
||||||
|
|
||||||
// TODO We use for both CompositeKeys and EdDSAPublicKey custom Kryo serializers and deserializers. We need to specify encoding.
|
// TODO We use for both CompositeKeys and EdDSAPublicKey custom Kryo serializers and deserializers. We need to specify encoding.
|
||||||
// TODO: follow the crypto-conditions ASN.1 spec, some changes are needed to be compatible with the condition
|
// TODO: follow the crypto-conditions ASN.1 spec, some changes are needed to be compatible with the condition
|
||||||
@ -106,7 +107,7 @@ fun PublicKey.verifyWithECDSA(content: ByteArray, signature: DigitalSignature) {
|
|||||||
val verifier = EdDSAEngine()
|
val verifier = EdDSAEngine()
|
||||||
verifier.initVerify(pubKey)
|
verifier.initVerify(pubKey)
|
||||||
verifier.update(content)
|
verifier.update(content)
|
||||||
if (verifier.verify(signature.bytes) == false)
|
if (!verifier.verify(signature.bytes))
|
||||||
throw SignatureException("Signature did not match")
|
throw SignatureException("Signature did not match")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,9 +139,9 @@ fun PublicKey.containsAny(otherKeys: Iterable<PublicKey>): Boolean {
|
|||||||
fun Iterable<DigitalSignature.WithKey>.byKeys() = map { it.by }.toSet()
|
fun Iterable<DigitalSignature.WithKey>.byKeys() = map { it.by }.toSet()
|
||||||
|
|
||||||
// Allow Kotlin destructuring: val (private, public) = keyPair
|
// Allow Kotlin destructuring: val (private, public) = keyPair
|
||||||
operator fun KeyPair.component1() = this.private
|
operator fun KeyPair.component1(): PrivateKey = this.private
|
||||||
|
|
||||||
operator fun KeyPair.component2() = this.public
|
operator fun KeyPair.component2(): PublicKey = this.public
|
||||||
|
|
||||||
/** A simple wrapper that will make it easier to swap out the EC algorithm we use in future */
|
/** A simple wrapper that will make it easier to swap out the EC algorithm we use in future */
|
||||||
fun generateKeyPair(): KeyPair = KeyPairGenerator().generateKeyPair()
|
fun generateKeyPair(): KeyPair = KeyPairGenerator().generateKeyPair()
|
||||||
|
@ -7,6 +7,4 @@ 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(net.i2p.crypto.eddsa.KeyFactory(), null, "EDDSA_ED25519_SHA512")
|
||||||
constructor() : super(net.i2p.crypto.eddsa.KeyFactory(), null, "EDDSA_ED25519_SHA512")
|
|
||||||
}
|
|
||||||
|
@ -24,7 +24,7 @@ import java.security.PublicKey
|
|||||||
*/
|
*/
|
||||||
class Party(val name: String, owningKey: PublicKey) : AbstractParty(owningKey) {
|
class Party(val name: String, owningKey: PublicKey) : AbstractParty(owningKey) {
|
||||||
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
|
||||||
|
|
||||||
override fun ref(bytes: OpaqueBytes): PartyAndReference = PartyAndReference(this.toAnonymous(), bytes)
|
override fun ref(bytes: OpaqueBytes): PartyAndReference = PartyAndReference(this.toAnonymous(), bytes)
|
||||||
|
@ -16,10 +16,9 @@ import java.util.*
|
|||||||
* has at least one flow, but that flow may also invoke sub-flows: they all share the same run id.
|
* has at least one flow, but that flow may also invoke sub-flows: they all share the same run id.
|
||||||
*/
|
*/
|
||||||
@CordaSerializable
|
@CordaSerializable
|
||||||
data class StateMachineRunId private constructor(val uuid: UUID) {
|
data class StateMachineRunId(val uuid: UUID) {
|
||||||
companion object {
|
companion object {
|
||||||
fun createRandom(): StateMachineRunId = StateMachineRunId(UUID.randomUUID())
|
fun createRandom(): StateMachineRunId = StateMachineRunId(UUID.randomUUID())
|
||||||
fun wrap(uuid: UUID): StateMachineRunId = StateMachineRunId(uuid)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String = "[$uuid]"
|
override fun toString(): String = "[$uuid]"
|
||||||
|
@ -14,7 +14,7 @@ data class ServiceInfo(val type: ServiceType, val name: String? = null) {
|
|||||||
companion object {
|
companion object {
|
||||||
fun parse(encoded: String): ServiceInfo {
|
fun parse(encoded: String): ServiceInfo {
|
||||||
val parts = encoded.split("|")
|
val parts = encoded.split("|")
|
||||||
require(parts.size > 0 && parts.size <= 2) { "Invalid number of elements found" }
|
require(parts.size in 1..2) { "Invalid number of elements found" }
|
||||||
val type = ServiceType.parse(parts[0])
|
val type = ServiceType.parse(parts[0])
|
||||||
val name = parts.getOrNull(1)
|
val name = parts.getOrNull(1)
|
||||||
return ServiceInfo(type, name)
|
return ServiceInfo(type, name)
|
||||||
|
@ -57,15 +57,10 @@ abstract class MappedSchema(schemaFamily: Class<*>,
|
|||||||
@Embeddable
|
@Embeddable
|
||||||
data class PersistentStateRef(
|
data class PersistentStateRef(
|
||||||
@Column(name = "transaction_id", length = 64)
|
@Column(name = "transaction_id", length = 64)
|
||||||
var txId: String?,
|
var txId: String? = null,
|
||||||
|
|
||||||
@Column(name = "output_index")
|
@Column(name = "output_index")
|
||||||
var index: Int?
|
var index: Int? = null
|
||||||
) : Serializable {
|
) : Serializable {
|
||||||
constructor(stateRef: StateRef) : this(stateRef.txhash.bytes.toHexString(), stateRef.index)
|
constructor(stateRef: StateRef) : this(stateRef.txhash.bytes.toHexString(), stateRef.index)
|
||||||
/*
|
|
||||||
JPA Query requirement:
|
|
||||||
@Entity classes should have a default (non-arg) constructor to instantiate the objects when retrieving them from the database.
|
|
||||||
*/
|
|
||||||
constructor() : this(null, null)
|
|
||||||
}
|
}
|
||||||
|
@ -35,5 +35,5 @@ open class OpaqueBytes(val bytes: ByteArray) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun ByteArray.opaque(): OpaqueBytes = OpaqueBytes(this)
|
fun ByteArray.opaque(): OpaqueBytes = OpaqueBytes(this)
|
||||||
fun ByteArray.toHexString() = BaseEncoding.base16().encode(this)
|
fun ByteArray.toHexString(): String = BaseEncoding.base16().encode(this)
|
||||||
fun String.parseAsHex() = BaseEncoding.base16().decode(this)
|
fun String.parseAsHex(): ByteArray = BaseEncoding.base16().decode(this)
|
||||||
|
@ -26,10 +26,6 @@ fun makeNoWhitelistClassResolver(): ClassResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class CordaClassResolver(val whitelist: ClassWhitelist) : DefaultClassResolver() {
|
class CordaClassResolver(val whitelist: ClassWhitelist) : DefaultClassResolver() {
|
||||||
companion object {
|
|
||||||
private val logger = loggerFor<CordaClassResolver>()
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the registration for the specified class, or null if the class is not registered. */
|
/** Returns the registration for the specified class, or null if the class is not registered. */
|
||||||
override fun getRegistration(type: Class<*>): Registration? {
|
override fun getRegistration(type: Class<*>): Registration? {
|
||||||
return super.getRegistration(type) ?: checkClass(type)
|
return super.getRegistration(type) ?: checkClass(type)
|
||||||
@ -147,10 +143,14 @@ class GlobalTransientClassWhiteList(val delegate: ClassWhitelist) : MutableClass
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is not currently used, but can be installed to log a large number of missing entries from the whitelist
|
* This class is not currently used, but can be installed to log a large number of missing entries from the whitelist
|
||||||
* and was used to track down the initial set.
|
* and was used to track down the initial set.
|
||||||
|
*
|
||||||
|
* @suppress
|
||||||
*/
|
*/
|
||||||
|
@Suppress("unused")
|
||||||
class LoggingWhitelist(val delegate: ClassWhitelist, val global: Boolean = true) : MutableClassWhitelist {
|
class LoggingWhitelist(val delegate: ClassWhitelist, val global: Boolean = true) : MutableClassWhitelist {
|
||||||
companion object {
|
companion object {
|
||||||
val log = loggerFor<LoggingWhitelist>()
|
val log = loggerFor<LoggingWhitelist>()
|
||||||
@ -178,9 +178,7 @@ class LoggingWhitelist(val delegate: ClassWhitelist, val global: Boolean = true)
|
|||||||
alreadySeen += type.name
|
alreadySeen += type.name
|
||||||
val className = Util.className(type)
|
val className = Util.className(type)
|
||||||
log.warn("Dynamically whitelisted class $className")
|
log.warn("Dynamically whitelisted class $className")
|
||||||
if (journalWriter != null) {
|
journalWriter?.println(className)
|
||||||
journalWriter.println(className)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -72,10 +72,12 @@ fun p2PKryo(): KryoPool = kryoPool
|
|||||||
// Same again, but this has whitelisting turned off for internal storage use only.
|
// Same again, but this has whitelisting turned off for internal storage use only.
|
||||||
fun storageKryo(): KryoPool = internalKryoPool
|
fun storageKryo(): KryoPool = internalKryoPool
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A type safe wrapper around a byte array that contains a serialised object. You can call [SerializedBytes.deserialize]
|
* A type safe wrapper around a byte array that contains a serialised object. You can call [SerializedBytes.deserialize]
|
||||||
* to get the original object back.
|
* to get the original object back.
|
||||||
*/
|
*/
|
||||||
|
@Suppress("unused") // Type parameter is just for documentation purposes.
|
||||||
class SerializedBytes<T : Any>(bytes: ByteArray, val internalOnly: Boolean = false) : OpaqueBytes(bytes) {
|
class SerializedBytes<T : Any>(bytes: ByteArray, val internalOnly: Boolean = false) : OpaqueBytes(bytes) {
|
||||||
// It's OK to use lazy here because SerializedBytes is configured to use the ImmutableClassSerializer.
|
// It's OK to use lazy here because SerializedBytes is configured to use the ImmutableClassSerializer.
|
||||||
val hash: SecureHash by lazy { bytes.sha256() }
|
val hash: SecureHash by lazy { bytes.sha256() }
|
||||||
@ -542,25 +544,6 @@ fun <T> Kryo.withAttachmentStorage(attachmentStorage: AttachmentStorage?, block:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object OrderedSerializer : Serializer<HashMap<Any, Any>>() {
|
|
||||||
override fun write(kryo: Kryo, output: Output, obj: HashMap<Any, Any>) {
|
|
||||||
//Change a HashMap to LinkedHashMap.
|
|
||||||
val linkedMap = LinkedHashMap<Any, Any>()
|
|
||||||
val sorted = obj.toList().sortedBy { it.first.hashCode() }
|
|
||||||
for ((k, v) in sorted) {
|
|
||||||
linkedMap.put(k, v)
|
|
||||||
}
|
|
||||||
kryo.writeClassAndObject(output, linkedMap)
|
|
||||||
}
|
|
||||||
|
|
||||||
//It will be deserialized as a LinkedHashMap.
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
override fun read(kryo: Kryo, input: Input, type: Class<HashMap<Any, Any>>): HashMap<Any, Any> {
|
|
||||||
val hm = kryo.readClassAndObject(input) as HashMap<Any, Any>
|
|
||||||
return hm
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** For serialising a MetaData object. */
|
/** For serialising a MetaData object. */
|
||||||
@ThreadSafe
|
@ThreadSafe
|
||||||
object MetaDataSerializer : Serializer<MetaData>() {
|
object MetaDataSerializer : Serializer<MetaData>() {
|
||||||
|
@ -103,7 +103,6 @@ class SerializeAsTokenContext(toBeTokenized: Any, kryoPool: KryoPool) {
|
|||||||
*/
|
*/
|
||||||
@CordaSerializable
|
@CordaSerializable
|
||||||
data class SingletonSerializationToken private constructor(private val className: String) : SerializationToken {
|
data class SingletonSerializationToken private constructor(private val className: String) : SerializationToken {
|
||||||
|
|
||||||
constructor(toBeTokenized: SerializeAsToken) : this(toBeTokenized.javaClass.name)
|
constructor(toBeTokenized: SerializeAsToken) : this(toBeTokenized.javaClass.name)
|
||||||
|
|
||||||
override fun fromToken(context: SerializeAsTokenContext): Any = context.tokenToTokenized[this] ?:
|
override fun fromToken(context: SerializeAsTokenContext): Any = context.tokenToTokenized[this] ?:
|
||||||
|
@ -147,7 +147,7 @@ open class TransactionBuilder(
|
|||||||
open fun addInputState(stateAndRef: StateAndRef<*>) {
|
open fun addInputState(stateAndRef: StateAndRef<*>) {
|
||||||
check(currentSigs.isEmpty())
|
check(currentSigs.isEmpty())
|
||||||
val notary = stateAndRef.state.notary
|
val notary = stateAndRef.state.notary
|
||||||
require(notary == this.notary) { "Input state requires notary \"${notary}\" which does not match the transaction notary \"${this.notary}\"." }
|
require(notary == this.notary) { "Input state requires notary \"$notary\" which does not match the transaction notary \"${this.notary}\"." }
|
||||||
signers.add(notary.owningKey)
|
signers.add(notary.owningKey)
|
||||||
inputs.add(stateAndRef.ref)
|
inputs.add(stateAndRef.ref)
|
||||||
}
|
}
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
package net.corda.core.utilities
|
|
||||||
|
|
||||||
import net.corda.core.ErrorOr
|
|
||||||
import net.corda.core.crypto.Party
|
|
||||||
import net.corda.core.crypto.parsePublicKeyBase58
|
|
||||||
import net.corda.core.messaging.CordaRPCOps
|
|
||||||
import javax.ws.rs.core.Response
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility functions to reduce boilerplate when developing HTTP APIs
|
|
||||||
*/
|
|
||||||
class ApiUtils(val rpc: CordaRPCOps) {
|
|
||||||
private val defaultNotFound = { msg: String -> Response.status(Response.Status.NOT_FOUND).entity(msg).build() }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a party and then execute the passed function with the party public key as a parameter.
|
|
||||||
* Usage: withParty(key) { doSomethingWith(it) }
|
|
||||||
*/
|
|
||||||
fun withParty(partyKeyStr: String, notFound: (String) -> Response = defaultNotFound, found: (Party) -> Response): Response {
|
|
||||||
val party = try {
|
|
||||||
val partyKey = parsePublicKeyBase58(partyKeyStr)
|
|
||||||
ErrorOr(rpc.partyFromKey(partyKey))
|
|
||||||
} catch (e: IllegalArgumentException) {
|
|
||||||
ErrorOr.of(Exception("Invalid base58 key passed for party key $e"))
|
|
||||||
}
|
|
||||||
return party.bind { if (it == null) ErrorOr.of(Exception("Unknown party")) else ErrorOr(found(it)) }.match(
|
|
||||||
onValue = { it },
|
|
||||||
onError = { notFound(it.toString()) }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
@ -57,20 +57,6 @@ class ProgressTracker(vararg steps: Step) {
|
|||||||
open fun childProgressTracker(): ProgressTracker? = null
|
open fun childProgressTracker(): ProgressTracker? = null
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: There's no actual way to create these steps anymore!
|
|
||||||
/** This class makes it easier to relabel a step on the fly, to provide transient information. */
|
|
||||||
open inner class RelabelableStep(currentLabel: String) : Step(currentLabel) {
|
|
||||||
override val changes: BehaviorSubject<Change> = BehaviorSubject.create()
|
|
||||||
|
|
||||||
var currentLabel: String = currentLabel
|
|
||||||
set(value) {
|
|
||||||
field = value
|
|
||||||
changes.onNext(ProgressTracker.Change.Rendering(this@ProgressTracker, this@RelabelableStep))
|
|
||||||
}
|
|
||||||
|
|
||||||
override val label: String get() = currentLabel
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sentinel objects. Overrides equals() to survive process restarts and serialization.
|
// Sentinel objects. Overrides equals() to survive process restarts and serialization.
|
||||||
object UNSTARTED : Step("Unstarted") {
|
object UNSTARTED : Step("Unstarted") {
|
||||||
override fun equals(other: Any?) = other is UNSTARTED
|
override fun equals(other: Any?) = other is UNSTARTED
|
||||||
|
@ -31,17 +31,6 @@ import java.security.PublicKey
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
object TwoPartyDealFlow {
|
object TwoPartyDealFlow {
|
||||||
|
|
||||||
@CordaSerializable
|
|
||||||
class DealMismatchException(val expectedDeal: ContractState, val actualDeal: ContractState) : Exception() {
|
|
||||||
override fun toString() = "The submitted deal didn't match the expected: $expectedDeal vs $actualDeal"
|
|
||||||
}
|
|
||||||
|
|
||||||
@CordaSerializable
|
|
||||||
class DealRefMismatchException(val expectedDeal: StateRef, val actualDeal: StateRef) : Exception() {
|
|
||||||
override fun toString() = "The submitted deal didn't match the expected: $expectedDeal vs $actualDeal"
|
|
||||||
}
|
|
||||||
|
|
||||||
// This object is serialised to the network and is the first flow message the seller sends to the buyer.
|
// This object is serialised to the network and is the first flow message the seller sends to the buyer.
|
||||||
@CordaSerializable
|
@CordaSerializable
|
||||||
data class Handshake<out T>(val payload: T, val publicKey: PublicKey)
|
data class Handshake<out T>(val payload: T, val publicKey: PublicKey)
|
||||||
|
@ -19,7 +19,7 @@ class FinanceTypesTest {
|
|||||||
@Test
|
@Test
|
||||||
fun `valid tenor tests`() {
|
fun `valid tenor tests`() {
|
||||||
val exampleTenors = ("ON,1D,2D,3D,4D,5D,6D,7D,1W,2W,3W,1M,3M,6M,1Y,2Y,3Y,5Y,10Y,12Y,20Y").split(",")
|
val exampleTenors = ("ON,1D,2D,3D,4D,5D,6D,7D,1W,2W,3W,1M,3M,6M,1Y,2Y,3Y,5Y,10Y,12Y,20Y").split(",")
|
||||||
exampleTenors.all { Tenor(it).name.length > 0 } // Slightly obtuse way of ensuring no exception thrown in construction.
|
exampleTenors.all { Tenor(it).name.isNotEmpty() } // Slightly obtuse way of ensuring no exception thrown in construction.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -23,8 +23,8 @@ class TransactionEncumbranceTests {
|
|||||||
)
|
)
|
||||||
val stateWithNewOwner = state.copy(owner = DUMMY_PUBKEY_2)
|
val stateWithNewOwner = state.copy(owner = DUMMY_PUBKEY_2)
|
||||||
|
|
||||||
val FOUR_PM = Instant.parse("2015-04-17T16:00:00.00Z")
|
val FOUR_PM: Instant = Instant.parse("2015-04-17T16:00:00.00Z")
|
||||||
val FIVE_PM = FOUR_PM.plus(1, ChronoUnit.HOURS)
|
val FIVE_PM: Instant = FOUR_PM.plus(1, ChronoUnit.HOURS)
|
||||||
val timeLock = DummyTimeLock.State(FIVE_PM)
|
val timeLock = DummyTimeLock.State(FIVE_PM)
|
||||||
|
|
||||||
class DummyTimeLock : Contract {
|
class DummyTimeLock : Contract {
|
||||||
|
@ -51,7 +51,7 @@ object TxKeyFlow {
|
|||||||
|
|
||||||
@Suspendable
|
@Suspendable
|
||||||
override fun call(): PublicKey {
|
override fun call(): PublicKey {
|
||||||
progressTracker.currentStep == SENDING_KEY
|
progressTracker.currentStep = SENDING_KEY
|
||||||
return TxKeyFlowUtilities.provideKey(this, otherSide)
|
return TxKeyFlowUtilities.provideKey(this, otherSide)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import org.junit.Before
|
|||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.io.ByteArrayInputStream
|
import java.io.ByteArrayInputStream
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
|
import java.net.URL
|
||||||
import java.net.URLClassLoader
|
import java.net.URLClassLoader
|
||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
import java.util.jar.JarOutputStream
|
import java.util.jar.JarOutputStream
|
||||||
@ -33,7 +34,7 @@ val ATTACHMENT_TEST_PROGRAM_ID = AttachmentClassLoaderTests.AttachmentDummyContr
|
|||||||
|
|
||||||
class AttachmentClassLoaderTests {
|
class AttachmentClassLoaderTests {
|
||||||
companion object {
|
companion object {
|
||||||
val ISOLATED_CONTRACTS_JAR_PATH = AttachmentClassLoaderTests::class.java.getResource("isolated.jar")
|
val ISOLATED_CONTRACTS_JAR_PATH: URL = AttachmentClassLoaderTests::class.java.getResource("isolated.jar")
|
||||||
}
|
}
|
||||||
|
|
||||||
class AttachmentDummyContract : Contract {
|
class AttachmentDummyContract : Contract {
|
||||||
|
@ -31,7 +31,7 @@ class DBTransactionMappingStorage : StateMachineRecordedTransactionMappingStorag
|
|||||||
private class TransactionMappingsMap : AbstractJDBCHashMap<SecureHash, StateMachineRunId, Table>(Table, loadOnInit = false) {
|
private class TransactionMappingsMap : AbstractJDBCHashMap<SecureHash, StateMachineRunId, Table>(Table, loadOnInit = false) {
|
||||||
override fun keyFromRow(row: ResultRow): SecureHash = row[table.txId]
|
override fun keyFromRow(row: ResultRow): SecureHash = row[table.txId]
|
||||||
|
|
||||||
override fun valueFromRow(row: ResultRow): StateMachineRunId = StateMachineRunId.wrap(row[table.stateMachineRunId])
|
override fun valueFromRow(row: ResultRow): StateMachineRunId = StateMachineRunId(row[table.stateMachineRunId])
|
||||||
|
|
||||||
override fun addKeyToInsert(insert: InsertStatement, entry: Map.Entry<SecureHash, StateMachineRunId>, finalizables: MutableList<() -> Unit>) {
|
override fun addKeyToInsert(insert: InsertStatement, entry: Map.Entry<SecureHash, StateMachineRunId>, finalizables: MutableList<() -> Unit>) {
|
||||||
insert[table.txId] = entry.key
|
insert[table.txId] = entry.key
|
||||||
|
Reference in New Issue
Block a user