Merge pull request #1842 from corda/tlil/reformat-2017-oct

Reformat Oct 2017
This commit is contained in:
Tommy Lillehagen
2017-10-09 15:57:43 +01:00
committed by GitHub
304 changed files with 2696 additions and 2378 deletions

View File

@ -119,12 +119,14 @@ object JacksonSupport {
* match an identity known from the network map. If true, the name is matched more leniently but if the match * match an identity known from the network map. If true, the name is matched more leniently but if the match
* is ambiguous a [JsonParseException] is thrown. * is ambiguous a [JsonParseException] is thrown.
*/ */
@JvmStatic @JvmOverloads @JvmStatic
@JvmOverloads
fun createDefaultMapper(rpc: CordaRPCOps, factory: JsonFactory = JsonFactory(), fun createDefaultMapper(rpc: CordaRPCOps, factory: JsonFactory = JsonFactory(),
fuzzyIdentityMatch: Boolean = false): ObjectMapper = configureMapper(RpcObjectMapper(rpc, factory, fuzzyIdentityMatch)) fuzzyIdentityMatch: Boolean = false): ObjectMapper = configureMapper(RpcObjectMapper(rpc, factory, fuzzyIdentityMatch))
/** For testing or situations where deserialising parties is not required */ /** For testing or situations where deserialising parties is not required */
@JvmStatic @JvmOverloads @JvmStatic
@JvmOverloads
fun createNonRpcMapper(factory: JsonFactory = JsonFactory()): ObjectMapper = configureMapper(NoPartyObjectMapper(factory)) fun createNonRpcMapper(factory: JsonFactory = JsonFactory()): ObjectMapper = configureMapper(NoPartyObjectMapper(factory))
/** /**
@ -134,7 +136,8 @@ object JacksonSupport {
* match an identity known from the network map. If true, the name is matched more leniently but if the match * match an identity known from the network map. If true, the name is matched more leniently but if the match
* is ambiguous a [JsonParseException] is thrown. * is ambiguous a [JsonParseException] is thrown.
*/ */
@JvmStatic @JvmOverloads @JvmStatic
@JvmOverloads
fun createInMemoryMapper(identityService: IdentityService, factory: JsonFactory = JsonFactory(), fun createInMemoryMapper(identityService: IdentityService, factory: JsonFactory = JsonFactory(),
fuzzyIdentityMatch: Boolean = false) = configureMapper(IdentityObjectMapper(identityService, factory, fuzzyIdentityMatch)) fuzzyIdentityMatch: Boolean = false) = configureMapper(IdentityObjectMapper(identityService, factory, fuzzyIdentityMatch))

View File

@ -212,7 +212,8 @@ open class StringToMethodCallParser<in T : Any> @JvmOverloads constructor(
} }
/** Returns a string-to-string map of commands to a string describing available parameter types. */ /** Returns a string-to-string map of commands to a string describing available parameter types. */
val availableCommands: Map<String, String> get() { val availableCommands: Map<String, String>
get() {
return methodMap.entries().map { entry -> return methodMap.entries().map { entry ->
val (name, args) = entry // TODO: Kotlin 1.1 val (name, args) = entry // TODO: Kotlin 1.1
val argStr = if (args.parameterCount == 0) "" else { val argStr = if (args.parameterCount == 0) "" else {

View File

@ -1,4 +1,5 @@
@file:JvmName("ModelsUtils") @file:JvmName("ModelsUtils")
package net.corda.client.jfx.model package net.corda.client.jfx.model
import javafx.beans.property.ObjectProperty import javafx.beans.property.ObjectProperty

View File

@ -38,7 +38,7 @@ class NetworkIdentityModel {
}) })
val notaries: ObservableList<Party> = networkIdentities.map { val notaries: ObservableList<Party> = networkIdentities.map {
it.legalIdentitiesAndCerts.find { it.name.commonName?.let { ServiceType.parse(it).isNotary() } ?: false } it.legalIdentitiesAndCerts.find { it.name.commonName?.let { ServiceType.parse(it).isNotary() } == true }
}.map { it?.party }.filterNotNull() }.map { it?.party }.filterNotNull()
val notaryNodes: ObservableList<NodeInfo> = notaries.map { rpcProxy.value?.nodeInfoFromParty(it) }.filterNotNull() val notaryNodes: ObservableList<NodeInfo> = notaries.map { rpcProxy.value?.nodeInfoFromParty(it) }.filterNotNull()

View File

@ -253,7 +253,8 @@ class ConcatenatedList<A>(sourceList: ObservableList<ObservableList<A>>) : Trans
} }
} }
override val size: Int get() { override val size: Int
get() {
recalculateOffsets() recalculateOffsets()
if (nestedIndexOffsets.size > 0) { if (nestedIndexOffsets.size > 0) {
return nestedIndexOffsets.last() return nestedIndexOffsets.last()

View File

@ -1,4 +1,5 @@
@file:JvmName("ObservableFold") @file:JvmName("ObservableFold")
package net.corda.client.jfx.utils package net.corda.client.jfx.utils
import javafx.application.Platform import javafx.application.Platform

View File

@ -1,4 +1,5 @@
@file:JvmName("ObservableUtilities") @file:JvmName("ObservableUtilities")
package net.corda.client.jfx.utils package net.corda.client.jfx.utils
import javafx.application.Platform import javafx.application.Platform

View File

@ -50,7 +50,8 @@ open class ReadOnlyBackedObservableMapBase<K, A, B> : ObservableMap<K, A> {
override fun isEmpty() = backingMap.isEmpty() override fun isEmpty() = backingMap.isEmpty()
override val entries: MutableSet<MutableMap.MutableEntry<K, A>> get() = backingMap.entries.fold(mutableSetOf()) { set, entry -> override val entries: MutableSet<MutableMap.MutableEntry<K, A>>
get() = backingMap.entries.fold(mutableSetOf()) { set, entry ->
set.add(object : MutableMap.MutableEntry<K, A> { set.add(object : MutableMap.MutableEntry<K, A> {
override var value: A = entry.value.first override var value: A = entry.value.first
override val key = entry.key override val key = entry.key

View File

@ -1,4 +1,5 @@
@file:JvmName("Generators") @file:JvmName("Generators")
package net.corda.client.mock package net.corda.client.mock
import net.corda.core.contracts.Amount import net.corda.core.contracts.Amount

View File

@ -76,10 +76,12 @@ class RPCStabilityTests {
rpcDriver { rpcDriver {
Try.on { startRpcClient<RPCOps>(NetworkHostAndPort("localhost", 9999)).get() } Try.on { startRpcClient<RPCOps>(NetworkHostAndPort("localhost", 9999)).get() }
val server = startRpcServer<RPCOps>(ops = DummyOps) val server = startRpcServer<RPCOps>(ops = DummyOps)
Try.on { startRpcClient<RPCOps>( Try.on {
startRpcClient<RPCOps>(
server.get().broker.hostAndPort!!, server.get().broker.hostAndPort!!,
configuration = RPCClientConfiguration.default.copy(minimumServerProtocolVersion = 1) configuration = RPCClientConfiguration.default.copy(minimumServerProtocolVersion = 1)
).get() } ).get()
}
} }
} }
repeat(5) { repeat(5) {
@ -249,6 +251,7 @@ class RPCStabilityTests {
val trackSubscriberCountObservable = UnicastSubject.create<Unit>().share(). val trackSubscriberCountObservable = UnicastSubject.create<Unit>().share().
doOnSubscribe { subscriberCount.incrementAndGet() }. doOnSubscribe { subscriberCount.incrementAndGet() }.
doOnUnsubscribe { subscriberCount.decrementAndGet() } doOnUnsubscribe { subscriberCount.decrementAndGet() }
override fun subscribe(): Observable<Unit> { override fun subscribe(): Observable<Unit> {
return trackSubscriberCountObservable return trackSubscriberCountObservable
} }
@ -284,6 +287,7 @@ class RPCStabilityTests {
interface SlowConsumerRPCOps : RPCOps { interface SlowConsumerRPCOps : RPCOps {
fun streamAtInterval(interval: Duration, size: Int): Observable<ByteArray> fun streamAtInterval(interval: Duration, size: Int): Observable<ByteArray>
} }
class SlowConsumerRPCOpsImpl : SlowConsumerRPCOps { class SlowConsumerRPCOpsImpl : SlowConsumerRPCOps {
override val protocolVersion = 0 override val protocolVersion = 0
@ -292,6 +296,7 @@ class RPCStabilityTests {
return Observable.interval(interval.toMillis(), TimeUnit.MILLISECONDS).map { chunk } return Observable.interval(interval.toMillis(), TimeUnit.MILLISECONDS).map { chunk }
} }
} }
@Test @Test
fun `slow consumers are kicked`() { fun `slow consumers are kicked`() {
rpcDriver { rpcDriver {

View File

@ -79,6 +79,7 @@ class RPCClientProxyHandler(
STARTED, STARTED,
FINISHED FINISHED
} }
private val lifeCycle = LifeCycle(State.UNSTARTED) private val lifeCycle = LifeCycle(State.UNSTARTED)
private companion object { private companion object {

View File

@ -20,10 +20,13 @@ open class AbstractRPCTest {
} }
companion object { companion object {
@JvmStatic @Parameterized.Parameters(name = "Mode = {0}") @JvmStatic
@Parameterized.Parameters(name = "Mode = {0}")
fun defaultModes() = modes(RPCTestMode.InVm, RPCTestMode.Netty) fun defaultModes() = modes(RPCTestMode.InVm, RPCTestMode.Netty)
fun modes(vararg modes: RPCTestMode) = listOf(*modes).map { arrayOf(it) } fun modes(vararg modes: RPCTestMode) = listOf(*modes).map { arrayOf(it) }
} }
@Parameterized.Parameter @Parameterized.Parameter
lateinit var mode: RPCTestMode lateinit var mode: RPCTestMode

View File

@ -26,9 +26,11 @@ import java.util.concurrent.TimeUnit
@RunWith(Parameterized::class) @RunWith(Parameterized::class)
class RPCPerformanceTests : AbstractRPCTest() { class RPCPerformanceTests : AbstractRPCTest() {
companion object { companion object {
@JvmStatic @Parameterized.Parameters(name = "Mode = {0}") @JvmStatic
@Parameterized.Parameters(name = "Mode = {0}")
fun modes() = modes(RPCTestMode.Netty) fun modes() = modes(RPCTestMode.Netty)
} }
private interface TestOps : RPCOps { private interface TestOps : RPCOps {
fun simpleReply(input: ByteArray, sizeOfReply: Int): ByteArray fun simpleReply(input: ByteArray, sizeOfReply: Int): ByteArray
} }
@ -155,10 +157,12 @@ class RPCPerformanceTests : AbstractRPCTest() {
data class BigMessagesResult( data class BigMessagesResult(
val Mbps: Double val Mbps: Double
) )
@Test @Test
fun `big messages`() { fun `big messages`() {
warmup() warmup()
measure(listOf(1)) { clientParallelism -> // TODO this hangs with more parallelism measure(listOf(1)) { clientParallelism ->
// TODO this hangs with more parallelism
rpcDriver { rpcDriver {
val proxy = testProxy( val proxy = testProxy(
RPCClientConfiguration.default, RPCClientConfiguration.default,

View File

@ -13,6 +13,7 @@ class RepeatingBytesInputStream(val bytesToRepeat: ByteArray, val numberOfBytes:
return bytesToRepeat[(numberOfBytes - bytesLeft) % bytesToRepeat.size].toInt() return bytesToRepeat[(numberOfBytes - bytesLeft) % bytesToRepeat.size].toInt()
} }
} }
override fun read(byteArray: ByteArray, offset: Int, length: Int): Int { override fun read(byteArray: ByteArray, offset: Int, length: Int): Int {
val lastIdx = Math.min(Math.min(offset + length, byteArray.size), offset + bytesLeft) val lastIdx = Math.min(Math.min(offset + length, byteArray.size), offset + bytesLeft)
for (i in offset until lastIdx) { for (i in offset until lastIdx) {

View File

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

View File

@ -85,6 +85,7 @@ abstract class TimeWindow {
init { init {
require(fromTime < untilTime) { "fromTime must be earlier than untilTime" } require(fromTime < untilTime) { "fromTime must be earlier than untilTime" }
} }
override val midpoint: Instant get() = fromTime + (fromTime until untilTime) / 2 override val midpoint: Instant get() = fromTime + (fromTime until untilTime) / 2
override fun contains(instant: Instant): Boolean = instant >= fromTime && instant < untilTime override fun contains(instant: Instant): Boolean = instant >= fromTime && instant < untilTime
override fun toString(): String = "[$fromTime, $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 { object CordaObjectIdentifier {
// UUID-based OID // UUID-based OID
// TODO: Register for an OID space and issue our own shorter OID. // TODO: Register for an OID space and issue our own shorter OID.
@JvmField val COMPOSITE_KEY = ASN1ObjectIdentifier("2.25.30086077608615255153862931087626791002") @JvmField
@JvmField val COMPOSITE_SIGNATURE = ASN1ObjectIdentifier("2.25.30086077608615255153862931087626791003") 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. // 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) val pointQ = FixedPointCombMultiplier().multiply(parameterSpec.g, deterministicD)
// This is unlikely to happen, but we should check for point at infinity. // 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). // Instead of throwing an exception, we retry with SHA256(seed).
return deriveKeyPairECDSA(parameterSpec, privateKey, seed.sha256().bytes) return deriveKeyPairECDSA(parameterSpec, privateKey, seed.sha256().bytes)
}
val publicKeySpec = ECPublicKeySpec(pointQ, parameterSpec) val publicKeySpec = ECPublicKeySpec(pointQ, parameterSpec)
val publicKeyD = BCECPublicKey(privateKey.algorithm, publicKeySpec, BouncyCastleProvider.CONFIGURATION) val publicKeyD = BCECPublicKey(privateKey.algorithm, publicKeySpec, BouncyCastleProvider.CONFIGURATION)
@ -849,6 +850,7 @@ object Crypto {
override fun generatePublic(keyInfo: SubjectPublicKeyInfo?): PublicKey? { override fun generatePublic(keyInfo: SubjectPublicKeyInfo?): PublicKey? {
return keyInfo?.let { decodePublicKey(signatureScheme, it.encoded) } return keyInfo?.let { decodePublicKey(signatureScheme, it.encoded) }
} }
override fun generatePrivate(keyInfo: PrivateKeyInfo?): PrivateKey? { override fun generatePrivate(keyInfo: PrivateKeyInfo?): PrivateKey? {
return keyInfo?.let { decodePrivateKey(signatureScheme, it.encoded) } 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) @Throws(IllegalArgumentException::class, InvalidKeyException::class, SignatureException::class)
fun KeyPair.sign(bytesToSign: ByteArray) = private.sign(bytesToSign, public) fun KeyPair.sign(bytesToSign: ByteArray) = private.sign(bytesToSign, public)
fun KeyPair.sign(bytesToSign: OpaqueBytes) = sign(bytesToSign.bytes) fun KeyPair.sign(bytesToSign: OpaqueBytes) = sign(bytesToSign.bytes)
/** /**
* Helper function for signing a [SignableData] object. * Helper function for signing a [SignableData] object.

View File

@ -23,6 +23,7 @@ open class DigitalSignature(bytes: ByteArray) : OpaqueBytes(bytes) {
*/ */
@Throws(InvalidKeyException::class, SignatureException::class) @Throws(InvalidKeyException::class, SignatureException::class)
fun verify(content: ByteArray) = by.verify(content, this) fun verify(content: ByteArray) = by.verify(content, this)
/** /**
* Utility to simplify the act of verifying a signature. * 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) @Throws(InvalidKeyException::class, SignatureException::class)
fun verify(content: OpaqueBytes) = by.verify(content.bytes, this) 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 * 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 * 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
@JvmStatic fun sha256Twice(bytes: ByteArray) = sha256(sha256(bytes).bytes) fun sha256(bytes: ByteArray) = SHA256(MessageDigest.getInstance("SHA-256").digest(bytes))
@JvmStatic fun sha256(str: String) = sha256(str.toByteArray())
@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 zeroHash = SecureHash.SHA256(ByteArray(32, { 0.toByte() }))
val allOnesHash = SecureHash.SHA256(ByteArray(32, { 255.toByte() })) val allOnesHash = SecureHash.SHA256(ByteArray(32, { 255.toByte() }))
} }

View File

@ -137,6 +137,7 @@ abstract class AbstractStateReplacementFlow {
abstract class Acceptor<in T>(val initiatingSession: FlowSession, abstract class Acceptor<in T>(val initiatingSession: FlowSession,
override val progressTracker: ProgressTracker = Acceptor.tracker()) : FlowLogic<Void?>() { override val progressTracker: ProgressTracker = Acceptor.tracker()) : FlowLogic<Void?>() {
constructor(initiatingSession: FlowSession) : this(initiatingSession, Acceptor.tracker()) constructor(initiatingSession: FlowSession) : this(initiatingSession, Acceptor.tracker())
companion object { companion object {
object VERIFYING : ProgressTracker.Step("Verifying state replacement proposal") object VERIFYING : ProgressTracker.Step("Verifying state replacement proposal")
object APPROVING : ProgressTracker.Step("State replacement approved") object APPROVING : ProgressTracker.Step("State replacement approved")

View File

@ -66,6 +66,7 @@ class CollectSignaturesFlow @JvmOverloads constructor (val partiallySignedTx: Si
val myOptionalKeys: Iterable<PublicKey>?, val myOptionalKeys: Iterable<PublicKey>?,
override val progressTracker: ProgressTracker = CollectSignaturesFlow.tracker()) : FlowLogic<SignedTransaction>() { override val progressTracker: ProgressTracker = CollectSignaturesFlow.tracker()) : FlowLogic<SignedTransaction>() {
@JvmOverloads constructor(partiallySignedTx: SignedTransaction, sessionsToCollectFrom: Collection<FlowSession>, progressTracker: ProgressTracker = CollectSignaturesFlow.tracker()) : this(partiallySignedTx, sessionsToCollectFrom, null, progressTracker) @JvmOverloads constructor(partiallySignedTx: SignedTransaction, sessionsToCollectFrom: Collection<FlowSession>, progressTracker: ProgressTracker = CollectSignaturesFlow.tracker()) : this(partiallySignedTx, sessionsToCollectFrom, null, progressTracker)
companion object { companion object {
object COLLECTING : ProgressTracker.Step("Collecting signatures from counter-parties.") object COLLECTING : ProgressTracker.Step("Collecting signatures from counter-parties.")
object VERIFYING : ProgressTracker.Step("Verifying collected signatures.") 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>>() { class CollectSignatureFlow(val partiallySignedTx: SignedTransaction, val session: FlowSession, val signingKeys: List<PublicKey>) : FlowLogic<List<TransactionSignature>>() {
constructor(partiallySignedTx: SignedTransaction, session: FlowSession, vararg signingKeys: PublicKey) : constructor(partiallySignedTx: SignedTransaction, session: FlowSession, vararg signingKeys: PublicKey) :
this(partiallySignedTx, session, listOf(*signingKeys)) this(partiallySignedTx, session, listOf(*signingKeys))
@Suspendable @Suspendable
override fun call(): List<TransactionSignature> { override fun call(): List<TransactionSignature> {
// SendTransactionFlow allows counterparty to access our data to resolve the transaction. // SendTransactionFlow allows counterparty to access our data to resolve the transaction.

View File

@ -88,7 +88,7 @@ class FinalityFlow(val transaction: SignedTransaction,
private fun hasNoNotarySignature(stx: SignedTransaction): Boolean { private fun hasNoNotarySignature(stx: SignedTransaction): Boolean {
val notaryKey = stx.tx.notary?.owningKey val notaryKey = stx.tx.notary?.owningKey
val signers = stx.sigs.map { it.by }.toSet() val signers = stx.sigs.map { it.by }.toSet()
return !(notaryKey?.isFulfilledBy(signers) ?: false) return notaryKey?.isFulfilledBy(signers) != true
} }
private fun getPartiesToSend(ltx: LedgerTransaction): Set<Party> { private fun getPartiesToSend(ltx: LedgerTransaction): Set<Party> {

View File

@ -16,18 +16,22 @@ sealed class FlowInitiator : Principal {
data class RPC(val username: String) : FlowInitiator() { data class RPC(val username: String) : FlowInitiator() {
override fun getName(): String = username override fun getName(): String = username
} }
/** Started when we get new session initiation request. */ /** Started when we get new session initiation request. */
data class Peer(val party: Party) : FlowInitiator() { data class Peer(val party: Party) : FlowInitiator() {
override fun getName(): String = party.name.toString() override fun getName(): String = party.name.toString()
} }
/** Started by a CordaService. */ /** Started by a CordaService. */
data class Service(val serviceClassName: String) : FlowInitiator() { data class Service(val serviceClassName: String) : FlowInitiator() {
override fun getName(): String = serviceClassName override fun getName(): String = serviceClassName
} }
/** Started as scheduled activity. */ /** Started as scheduled activity. */
data class Scheduled(val scheduledState: ScheduledStateRef) : FlowInitiator() { data class Scheduled(val scheduledState: ScheduledStateRef) : FlowInitiator() {
override fun getName(): String = "Scheduler" override fun getName(): String = "Scheduler"
} }
// TODO When proper ssh access enabled, add username/use RPC? // TODO When proper ssh access enabled, add username/use RPC?
object Shell : FlowInitiator() { object Shell : FlowInitiator() {
override fun getName(): String = "Shell User" 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> { inline fun <reified R : Any> sendAndReceive(payload: Any): UntrustworthyData<R> {
return sendAndReceive(R::class.java, payload) return sendAndReceive(R::class.java, payload)
} }
/** /**
* Serializes and queues the given [payload] object for sending to the [counterparty]. Suspends until a response * 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 * 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> { inline fun <reified R : Any> receive(): UntrustworthyData<R> {
return receive(R::class.java) return receive(R::class.java)
} }
/** /**
* Suspends until [counterparty] sends us a message of type [receiveType]. * Suspends until [counterparty] sends us a message of type [receiveType].
* *

View File

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

View File

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

View File

@ -11,7 +11,9 @@ import java.security.cert.*
*/ */
@CordaSerializable @CordaSerializable
class PartyAndCertificate(val certPath: CertPath) { class PartyAndCertificate(val certPath: CertPath) {
@Transient val certificate: X509Certificate @Transient
val certificate: X509Certificate
init { init {
require(certPath.type == "X.509") { "Only X.509 certificates supported" } require(certPath.type == "X.509") { "Only X.509 certificates supported" }
val certs = certPath.certificates val certs = certPath.certificates
@ -19,7 +21,8 @@ class PartyAndCertificate(val certPath: CertPath) {
certificate = certs[0] as X509Certificate certificate = certs[0] as X509Certificate
} }
@Transient val party: Party = Party(certificate) @Transient
val party: Party = Party(certificate)
val owningKey: PublicKey get() = party.owningKey val owningKey: PublicKey get() = party.owningKey
val name: CordaX500Name get() = party.name 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") (System.getenv("TERM_PROGRAM") == "JediTerm" && System.getProperty("java.vendor") == "JetBrains s.r.o")
} }
@JvmStatic val CODE_SANTA_CLAUS: String = codePointsString(0x1F385) @JvmStatic
@JvmStatic val CODE_DIAMOND: String = codePointsString(0x1F537) val CODE_SANTA_CLAUS: String = codePointsString(0x1F385)
@JvmStatic val CODE_BAG_OF_CASH: String = codePointsString(0x1F4B0) @JvmStatic
@JvmStatic val CODE_NEWSPAPER: String = codePointsString(0x1F4F0) val CODE_DIAMOND: String = codePointsString(0x1F537)
@JvmStatic val CODE_RIGHT_ARROW: String = codePointsString(0x27A1, 0xFE0F) @JvmStatic
@JvmStatic val CODE_LEFT_ARROW: String = codePointsString(0x2B05, 0xFE0F) val CODE_BAG_OF_CASH: String = codePointsString(0x1F4B0)
@JvmStatic val CODE_GREEN_TICK: String = codePointsString(0x2705) @JvmStatic
@JvmStatic val CODE_PAPERCLIP: String = codePointsString(0x1F4CE) val CODE_NEWSPAPER: String = codePointsString(0x1F4F0)
@JvmStatic val CODE_COOL_GUY: String = codePointsString(0x1F60E) @JvmStatic
@JvmStatic val CODE_NO_ENTRY: String = codePointsString(0x1F6AB) val CODE_RIGHT_ARROW: String = codePointsString(0x27A1, 0xFE0F)
@JvmStatic val CODE_SKULL_AND_CROSSBONES: String = codePointsString(0x2620) @JvmStatic
@JvmStatic val CODE_BOOKS: String = codePointsString(0x1F4DA) val CODE_LEFT_ARROW: String = codePointsString(0x2B05, 0xFE0F)
@JvmStatic val CODE_SLEEPING_FACE: String = codePointsString(0x1F634) @JvmStatic
@JvmStatic val CODE_LIGHTBULB: String = codePointsString(0x1F4A1) val CODE_GREEN_TICK: String = codePointsString(0x2705)
@JvmStatic val CODE_FREE: String = codePointsString(0x1F193) @JvmStatic
@JvmStatic val CODE_SOON: String = codePointsString(0x1F51C) 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. * separator problems.
*/ */
operator fun Path.div(other: String): Path = resolve(other) operator fun Path.div(other: String): Path = resolve(other)
operator fun String.div(other: String): Path = Paths.get(this) / 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) Files.copy(this, targetFile, *options)
return targetFile return targetFile
} }
fun Path.moveTo(target: Path, vararg options: CopyOption): Path = Files.move(this, target, *options) 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.isRegularFile(vararg options: LinkOption): Boolean = Files.isRegularFile(this, *options)
fun Path.isDirectory(vararg options: LinkOption): Boolean = Files.isDirectory(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]. */ /** 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) 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]. */ /** 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) 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. */ /** @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) 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 * Returns a [DeclaredField] wrapper around the (possibly non-public) instance field of the receiver object, but declared
* in its superclass [clazz]. * in its superclass [clazz].

View File

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

View File

@ -18,6 +18,7 @@ class LazyStickyPool<A : Any>(
private class InstanceBox<A> { private class InstanceBox<A> {
var instance: LinkedBlockingQueue<A>? = null var instance: LinkedBlockingQueue<A>? = null
} }
private val random = Random() private val random = Random()
private val boxes = Array(size) { InstanceBox<A>() } 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) { constructor(signedTransaction: SignedTransaction, otherSide: FlowSession) : this(dependencyIDs(signedTransaction), otherSide) {
this.signedTransaction = signedTransaction this.signedTransaction = signedTransaction
} }
companion object { companion object {
private fun dependencyIDs(stx: SignedTransaction) = stx.inputs.map { it.txhash }.toSet() private fun dependencyIDs(stx: SignedTransaction) = stx.inputs.map { it.txhash }.toSet()

View File

@ -46,6 +46,7 @@ class X509EdDSAEngine : Signature {
override fun engineSetParameter(params: AlgorithmParameterSpec) = engine.setParameter(params) override fun engineSetParameter(params: AlgorithmParameterSpec) = engine.setParameter(params)
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
override fun engineGetParameter(param: String): Any = engine.getParameter(param) override fun engineGetParameter(param: String): Any = engine.getParameter(param)
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
override fun engineSetParameter(param: String, value: Any?) = engine.setParameter(param, value) 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> { fun <T : ContractState> vaultQuery(contractStateType: Class<out T>): Vault.Page<T> {
return vaultQueryBy(QueryCriteria.VaultQueryCriteria(), PageSpecification(), Sort(emptySet()), contractStateType) return vaultQueryBy(QueryCriteria.VaultQueryCriteria(), PageSpecification(), Sort(emptySet()), contractStateType)
} }
fun <T : ContractState> vaultQueryByCriteria(criteria: QueryCriteria, contractStateType: Class<out T>): Vault.Page<T> { fun <T : ContractState> vaultQueryByCriteria(criteria: QueryCriteria, contractStateType: Class<out T>): Vault.Page<T> {
return vaultQueryBy(criteria, PageSpecification(), Sort(emptySet()), contractStateType) return vaultQueryBy(criteria, PageSpecification(), Sort(emptySet()), contractStateType)
} }
fun <T : ContractState> vaultQueryByWithPagingSpec(contractStateType: Class<out T>, criteria: QueryCriteria, paging: PageSpecification): Vault.Page<T> { fun <T : ContractState> vaultQueryByWithPagingSpec(contractStateType: Class<out T>, criteria: QueryCriteria, paging: PageSpecification): Vault.Page<T> {
return vaultQueryBy(criteria, paging, Sort(emptySet()), contractStateType) return vaultQueryBy(criteria, paging, Sort(emptySet()), contractStateType)
} }
fun <T : ContractState> vaultQueryByWithSorting(contractStateType: Class<out T>, criteria: QueryCriteria, sorting: Sort): Vault.Page<T> { fun <T : ContractState> vaultQueryByWithSorting(contractStateType: Class<out T>, criteria: QueryCriteria, sorting: Sort): Vault.Page<T> {
return vaultQueryBy(criteria, PageSpecification(), sorting, contractStateType) 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>> { fun <T : ContractState> vaultTrack(contractStateType: Class<out T>): DataFeed<Vault.Page<T>, Vault.Update<T>> {
return vaultTrackBy(QueryCriteria.VaultQueryCriteria(), PageSpecification(), Sort(emptySet()), contractStateType) 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>> { fun <T : ContractState> vaultTrackByCriteria(contractStateType: Class<out T>, criteria: QueryCriteria): DataFeed<Vault.Page<T>, Vault.Update<T>> {
return vaultTrackBy(criteria, PageSpecification(), Sort(emptySet()), contractStateType) 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>> { 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) 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>> { 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) return vaultTrackBy(criteria, PageSpecification(), sorting, contractStateType)
} }
@ -250,6 +256,7 @@ interface CordaRPCOps : RPCOps {
* @return well known identity, if found. * @return well known identity, if found.
*/ */
fun wellKnownPartyFromAnonymous(party: AbstractParty): Party? fun wellKnownPartyFromAnonymous(party: AbstractParty): Party?
/** Returns the [Party] corresponding to the given key, if found. */ /** Returns the [Party] corresponding to the given key, if found. */
fun partyFromKey(key: PublicKey): Party? fun partyFromKey(key: PublicKey): Party?

View File

@ -35,7 +35,8 @@ 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 * are porting code from earlier versions of Corda that expected a single party per node, just use the first item
* in the returned list. * in the returned list.
*/ */
val legalIdentities: List<Party> get() { val legalIdentities: List<Party>
get() {
return _legalIdentities ?: legalIdentitiesAndCerts.map { it.party }.also { _legalIdentities = it } return _legalIdentities ?: legalIdentitiesAndCerts.map { it.party }.also { _legalIdentities = it }
} }

View File

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

View File

@ -201,6 +201,7 @@ object Builder {
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) = CriteriaExpression.AggregateFunctionExpression(Column(this), predicate, groupByColumns, orderBy)
fun <R> Field.functionPredicate(predicate: ColumnPredicate<R>, groupByColumns: List<Column<Any, R>>? = null, orderBy: Sort.Direction? = null) 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) = 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?>.`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)) 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
@JvmStatic fun <R> Field.notEqual(value: R) = predicate(ColumnPredicate.EqualityComparison(EqualityComparisonOperator.NOT_EQUAL, value)) fun <R> Field.equal(value: R) = predicate(ColumnPredicate.EqualityComparison(EqualityComparisonOperator.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
@JvmStatic fun <R : Comparable<R>> Field.greaterThan(value: R) = comparePredicate(BinaryComparisonOperator.GREATER_THAN, value) fun <R> Field.notEqual(value: R) = predicate(ColumnPredicate.EqualityComparison(EqualityComparisonOperator.NOT_EQUAL, 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
@JvmStatic fun <R : Comparable<R>> Field.`in`(collection: Collection<R>) = predicate(ColumnPredicate.CollectionExpression(CollectionOperator.IN, collection)) fun <R : Comparable<R>> Field.lessThan(value: R) = comparePredicate(BinaryComparisonOperator.LESS_THAN, value)
@JvmStatic fun <R : Comparable<R>> Field.notIn(collection: Collection<R>) = predicate(ColumnPredicate.CollectionExpression(CollectionOperator.NOT_IN, collection))
@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> equal(value: R) = ColumnPredicate.EqualityComparison(EqualityComparisonOperator.EQUAL, value)
fun <R> notEqual(value: R) = ColumnPredicate.EqualityComparison(EqualityComparisonOperator.NOT_EQUAL, value) fun <R> notEqual(value: R) = ColumnPredicate.EqualityComparison(EqualityComparisonOperator.NOT_EQUAL, value)
@ -238,27 +256,37 @@ object Builder {
fun <R : Comparable<R>> notIn(collection: Collection<R>) = ColumnPredicate.CollectionExpression(CollectionOperator.NOT_IN, collection) 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)) 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)) 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)) 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)) 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 */ /** aggregate functions */
fun <O, R> KProperty1<O, R?>.sum(groupByColumns: List<KProperty1<O, R>>? = null, orderBy: Sort.Direction? = null) = 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) 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) = 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)) 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) = 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) functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.AVG), groupByColumns?.map { Column(it) }, orderBy)
@JvmStatic @JvmStatic
@JvmOverloads @JvmOverloads
fun <R> Field.avg(groupByColumns: List<Field>? = null, orderBy: Sort.Direction? = null) = fun <R> Field.avg(groupByColumns: List<Field>? = null, orderBy: Sort.Direction? = null) =
@ -266,6 +294,7 @@ object Builder {
fun <O, R> KProperty1<O, R?>.min(groupByColumns: List<KProperty1<O, R>>? = null, orderBy: Sort.Direction? = null) = 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) functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.MIN), groupByColumns?.map { Column(it) }, orderBy)
@JvmStatic @JvmStatic
@JvmOverloads @JvmOverloads
fun <R> Field.min(groupByColumns: List<Field>? = null, orderBy: Sort.Direction? = null) = fun <R> Field.min(groupByColumns: List<Field>? = null, orderBy: Sort.Direction? = null) =
@ -273,6 +302,7 @@ object Builder {
fun <O, R> KProperty1<O, R?>.max(groupByColumns: List<KProperty1<O, R>>? = null, orderBy: Sort.Direction? = null) = 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) functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.MAX), groupByColumns?.map { Column(it) }, orderBy)
@JvmStatic @JvmStatic
@JvmOverloads @JvmOverloads
fun <R> Field.max(groupByColumns: List<Field>? = null, orderBy: Sort.Direction? = null) = fun <R> Field.max(groupByColumns: List<Field>? = null, orderBy: Sort.Direction? = null) =

View File

@ -72,6 +72,7 @@ object NodeInfoSchemaV1 : MappedSchema(
PKHostAndPort(hostAndPort.host, hostAndPort.port) PKHostAndPort(hostAndPort.host, hostAndPort.port)
) )
} }
fun toHostAndPort(): NetworkHostAndPort { fun toHostAndPort(): NetworkHostAndPort {
return NetworkHostAndPort(this.pk.host!!, this.pk.port!!) 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 * 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). * [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. * 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]. * The use case we are serializing or deserializing for. See [UseCase].
*/ */
val useCase: UseCase val useCase: UseCase
/** /**
* Helper method to return a new context based on this context with the property added. * Helper method to return a new context based on this context with the property added.
*/ */

View File

@ -79,8 +79,7 @@ data class LedgerTransaction(
// TODO: make contract upgrade transactions have a separate type // TODO: make contract upgrade transactions have a separate type
if (commands.any { it.value is UpgradeCommand }) { if (commands.any { it.value is UpgradeCommand }) {
verifyContractUpgrade() verifyContractUpgrade()
} } else {
else {
verifyContracts() verifyContracts()
} }
} }

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. */ /** 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. */ /** Lazily calculated access to the deserialised/hashed transaction data. */
private val transaction: CoreTransaction get() = cachedTransaction ?: txBits.deserialize().apply { cachedTransaction = this } private val transaction: CoreTransaction get() = cachedTransaction ?: txBits.deserialize().apply { cachedTransaction = this }

View File

@ -179,6 +179,7 @@ open class TransactionBuilder(
// Accessors that yield immutable snapshots. // Accessors that yield immutable snapshots.
fun inputStates(): List<StateRef> = ArrayList(inputs) fun inputStates(): List<StateRef> = ArrayList(inputs)
fun attachments(): List<SecureHash> = ArrayList(attachments) fun attachments(): List<SecureHash> = ArrayList(attachments)
fun outputStates(): List<TransactionState<*>> = ArrayList(outputs) fun outputStates(): List<TransactionState<*>> = ArrayList(outputs)
fun commands(): List<Command<*>> = ArrayList(commands) fun commands(): List<Command<*>> = ArrayList(commands)

View File

@ -63,7 +63,8 @@ class WireTransaction(componentGroups: List<ComponentGroup>, val privacySalt: Pr
override val id: SecureHash get() = merkleTree.hash override val id: SecureHash get() = merkleTree.hash
/** Public keys that need to be fulfilled by signatures in order for the transaction to be valid. */ /** Public keys that need to be fulfilled by signatures in order for the transaction to be valid. */
val requiredSigningKeys: Set<PublicKey> get() { val requiredSigningKeys: Set<PublicKey>
get() {
val commandKeys = commands.flatMap { it.signers }.toSet() val commandKeys = commands.flatMap { it.signers }.toSet()
// TODO: prevent notary field from being set if there are no inputs and no timestamp. // TODO: prevent notary field from being set if there are no inputs and no timestamp.
return if (notary != null && (inputs.isNotEmpty() || timeWindow != null)) { return if (notary != null && (inputs.isNotEmpty() || timeWindow != null)) {

View File

@ -25,6 +25,7 @@ sealed class ByteSequence : Comparable<ByteSequence> {
* The start position of the sequence within the byte array. * The start position of the sequence within the byte array.
*/ */
abstract val offset: Int abstract val offset: Int
/** Returns a [ByteArrayInputStream] of the bytes */ /** Returns a [ByteArrayInputStream] of the bytes */
fun open() = ByteArrayInputStream(bytes, offset, size) 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 // 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). // structure, e.g. mapping a PublicKey to a condition with the specific feature (ED25519).
fun parsePublicKeyBase58(base58String: String): PublicKey = base58String.base58ToByteArray().deserialize<PublicKey>() fun parsePublicKeyBase58(base58String: String): PublicKey = base58String.base58ToByteArray().deserialize<PublicKey>()
fun PublicKey.toBase58String(): String = this.serialize().bytes.toBase58() 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). fun PublicKey.toSHA256Bytes(): ByteArray = this.serialize().bytes.sha256().bytes // TODO: decide on the format of hashed key (encoded Vs serialised).

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. */ /** Returns the first element of the set. */
fun head(): T = elements.iterator().next() fun head(): T = elements.iterator().next()
override fun isEmpty(): Boolean = false override fun isEmpty(): Boolean = false
override fun iterator() = object : Iterator<T> by elements.iterator() {} override fun iterator() = object : Iterator<T> by elements.iterator() {}
// Following methods are not delegated by Kotlin's Class delegation // Following methods are not delegated by Kotlin's Class delegation
override fun forEach(action: Consumer<in T>) = elements.forEach(action) override fun forEach(action: Consumer<in T>) = elements.forEach(action)
override fun stream(): Stream<T> = elements.stream() override fun stream(): Stream<T> = elements.stream()
override fun parallelStream(): Stream<T> = elements.parallelStream() override fun parallelStream(): Stream<T> = elements.parallelStream()
override fun spliterator(): Spliterator<T> = elements.spliterator() override fun spliterator(): Spliterator<T> = elements.spliterator()

View File

@ -199,6 +199,7 @@ class CompatibleTransactionTests : TestDependencyInjectionBase() {
else -> false else -> false
} }
} }
val ftxInputs = wireTransactionA.buildFilteredTransaction(Predicate(::filtering)) // Inputs only filtered. val ftxInputs = wireTransactionA.buildFilteredTransaction(Predicate(::filtering)) // Inputs only filtered.
ftxInputs.verify() ftxInputs.verify()
ftxInputs.checkAllComponentsVisible(INPUTS_GROUP) ftxInputs.checkAllComponentsVisible(INPUTS_GROUP)
@ -210,6 +211,7 @@ class CompatibleTransactionTests : TestDependencyInjectionBase() {
// Filter one input only. // Filter one input only.
fun filteringOneInput(elem: Any) = elem == inputs[0] fun filteringOneInput(elem: Any) = elem == inputs[0]
val ftxOneInput = wireTransactionA.buildFilteredTransaction(Predicate(::filteringOneInput)) // First input only filtered. val ftxOneInput = wireTransactionA.buildFilteredTransaction(Predicate(::filteringOneInput)) // First input only filtered.
ftxOneInput.verify() ftxOneInput.verify()
assertFailsWith<ComponentVisibilityException> { ftxOneInput.checkAllComponentsVisible(INPUTS_GROUP) } assertFailsWith<ComponentVisibilityException> { ftxOneInput.checkAllComponentsVisible(INPUTS_GROUP) }

View File

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

View File

@ -271,6 +271,7 @@ data class PackageTree(val branches: Map<String, PackageTree>) {
val exclude: PackageTree, val exclude: PackageTree,
val globSoFar: List<String> val globSoFar: List<String>
) )
val toExpandList = LinkedList(listOf(State(this, excludeTree, emptyList()))) val toExpandList = LinkedList(listOf(State(this, excludeTree, emptyList())))
val globs = ArrayList<Glob>() val globs = ArrayList<Glob>()
while (true) { while (true) {

View File

@ -43,7 +43,6 @@ public class CandidacyStatus {
} }
/** /**
*
* @param signature * @param signature
* @return true if the input was absent from the underlying map * @return true if the input was absent from the underlying map
*/ */
@ -52,7 +51,6 @@ public class CandidacyStatus {
} }
/** /**
*
* @param methodSignature * @param methodSignature
* @return true if the input was absent from the underlying map * @return true if the input was absent from the underlying map
*/ */

View File

@ -6,15 +6,14 @@ import java.util.Set;
/** /**
* A candidate method that is under evaluation. Candidate methods have one of the following states: * A candidate method that is under evaluation. Candidate methods have one of the following states:
* * <p>
* <ul> * <ul>
* <li>{@link CandidateMethod.State#DETERMINISTIC} - It's deterministic and therefore is allowed to be loaded.</li> * <li>{@link CandidateMethod.State#DETERMINISTIC} - It's deterministic and therefore is allowed to be loaded.</li>
* <li>{@link CandidateMethod.State#DISALLOWED} - It's not deterministic and won't be allowed to be loaded.</li> * <li>{@link CandidateMethod.State#DISALLOWED} - It's not deterministic and won't be allowed to be loaded.</li>
* <li>{@link CandidateMethod.State#SCANNED} - We're not sure if it's deterministic or not.</li> * <li>{@link CandidateMethod.State#SCANNED} - We're not sure if it's deterministic or not.</li>
* </ul> * </ul>
* * <p>
* CandidateMethods themselves reference other CandidateMethods which are be checked for their deterministic state * CandidateMethods themselves reference other CandidateMethods which are be checked for their deterministic state
*
*/ */
public final class CandidateMethod { public final class CandidateMethod {
@ -94,6 +93,7 @@ public final class CandidateMethod {
/** /**
* This factory constructor is only called for methods that are known to be deterministic in advance * This factory constructor is only called for methods that are known to be deterministic in advance
*
* @param methodSignature * @param methodSignature
* @return * @return
*/ */

View File

@ -1,11 +1,11 @@
package net.corda.sandbox; package net.corda.sandbox;
import static net.corda.sandbox.Utils.*; import static net.corda.sandbox.Utils.*;
import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
/** /**
*
* @author ben * @author ben
*/ */
public final class SandboxAwareClassWriter extends ClassWriter { public final class SandboxAwareClassWriter extends ClassWriter {
@ -26,10 +26,8 @@ public final class SandboxAwareClassWriter extends ClassWriter {
* that is currently being generated by this ClassWriter, which can of * that is currently being generated by this ClassWriter, which can of
* course not be loaded since it is under construction. * course not be loaded since it is under construction.
* *
* @param type1 * @param type1 the internal name of a class.
* the internal name of a class. * @param type2 the internal name of another class.
* @param type2
* the internal name of another class.
* @return the internal name of the common super class of the two given * @return the internal name of the common super class of the two given
* classes. * classes.
*/ */

View File

@ -3,7 +3,6 @@ package net.corda.sandbox;
import org.objectweb.asm.commons.Remapper; import org.objectweb.asm.commons.Remapper;
/** /**
*
* @author ben * @author ben
*/ */
public final class SandboxRemapper extends Remapper { public final class SandboxRemapper extends Remapper {

View File

@ -4,7 +4,6 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** /**
*
* @author ben * @author ben
*/ */
public final class Utils { public final class Utils {
@ -43,6 +42,7 @@ public final class Utils {
* Helper method that converts from the internal class name format (as used in the * Helper method that converts from the internal class name format (as used in the
* Constant Pool) to a fully-qualified class name. No obvious library method to do this * Constant Pool) to a fully-qualified class name. No obvious library method to do this
* appears to exist, hence this code. If one exists, rip this out. * appears to exist, hence this code. If one exists, rip this out.
*
* @param classInternalName * @param classInternalName
* @return * @return
*/ */
@ -55,7 +55,6 @@ public final class Utils {
* This method takes in an internal method name but needs to return a qualified * This method takes in an internal method name but needs to return a qualified
* classname (suitable for loading) * classname (suitable for loading)
* *
*
* @param internalMethodName * @param internalMethodName
* @return * @return
*/ */
@ -72,6 +71,7 @@ public final class Utils {
* Helper method that converts from a fully-qualified class name to the internal class * Helper method that converts from a fully-qualified class name to the internal class
* name format (as used in the Constant Pool). No obvious library method to do this * name format (as used in the Constant Pool). No obvious library method to do this
* appears to exist, hence this code. If one exists, rip this out. * appears to exist, hence this code. If one exists, rip this out.
*
* @param qualifiedClassName * @param qualifiedClassName
* @return * @return
*/ */
@ -102,7 +102,6 @@ public final class Utils {
} }
/** /**
*
* @param qualifiedTypeName * @param qualifiedTypeName
* @return * @return
*/ */
@ -131,7 +130,6 @@ public final class Utils {
} }
/** /**
*
* @param desc - internal * @param desc - internal
* @return the rewritten desc string * @return the rewritten desc string
*/ */

View File

@ -2,6 +2,7 @@ package net.corda.sandbox;
import net.corda.sandbox.visitors.CostInstrumentingMethodVisitor; import net.corda.sandbox.visitors.CostInstrumentingMethodVisitor;
import net.corda.sandbox.visitors.WhitelistCheckingClassVisitor; import net.corda.sandbox.visitors.WhitelistCheckingClassVisitor;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URI; import java.net.URI;
@ -9,13 +10,13 @@ import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.nio.file.*; import java.nio.file.*;
import java.util.*; import java.util.*;
import org.objectweb.asm.*; import org.objectweb.asm.*;
import org.objectweb.asm.commons.ClassRemapper; import org.objectweb.asm.commons.ClassRemapper;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
*
* @author ben * @author ben
*/ */
public final class WhitelistClassLoader extends ClassLoader { public final class WhitelistClassLoader extends ClassLoader {
@ -136,7 +137,6 @@ public final class WhitelistClassLoader extends ClassLoader {
} }
/** /**
*
* @param qualifiedClassName * @param qualifiedClassName
* @return a class object that has been whitelist checked and is known to be * @return a class object that has been whitelist checked and is known to be
* deterministic * deterministic
@ -328,6 +328,7 @@ public final class WhitelistClassLoader extends ClassLoader {
/** /**
* Getter method for the reason for failure * Getter method for the reason for failure
*
* @return * @return
*/ */
public WhitelistClassloadingException reason() { public WhitelistClassloadingException reason() {
@ -336,6 +337,7 @@ public final class WhitelistClassLoader extends ClassLoader {
/** /**
* Getter method for the method candidacy status * Getter method for the method candidacy status
*
* @return * @return
*/ */
public CandidacyStatus getCandidacyStatus() { public CandidacyStatus getCandidacyStatus() {

View File

@ -4,7 +4,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
*
* @author ben * @author ben
*/ */
public class RuntimeCostAccounter { public class RuntimeCostAccounter {

View File

@ -2,6 +2,7 @@ package net.corda.sandbox.tools;
import net.corda.sandbox.WhitelistClassLoader; import net.corda.sandbox.WhitelistClassLoader;
import net.corda.sandbox.visitors.SandboxPathVisitor; import net.corda.sandbox.visitors.SandboxPathVisitor;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.net.URISyntaxException; import java.net.URISyntaxException;
@ -18,7 +19,6 @@ import joptsimple.OptionSet;
* This class takes in an exploded set of JRE classes, and a whitelist, and rewrites all * This class takes in an exploded set of JRE classes, and a whitelist, and rewrites all
* classes (note: not methods) that have at least one whitelisted method to create a * classes (note: not methods) that have at least one whitelisted method to create a
* sandboxed version of the class. * sandboxed version of the class.
*
*/ */
// java8.scan.java.lang_and_util java8.interfaces_for_compat java8 sandbox // java8.scan.java.lang_and_util java8.interfaces_for_compat java8 sandbox
public final class SandboxCreator { public final class SandboxCreator {
@ -107,7 +107,6 @@ public final class SandboxCreator {
} }
/** /**
*
* @param basePath * @param basePath
* @param packageName * @param packageName
* @throws IOException * @throws IOException

View File

@ -9,7 +9,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
*
* @author ben * @author ben
*/ */
public final class CostInstrumentingMethodVisitor extends GeneratorAdapter { public final class CostInstrumentingMethodVisitor extends GeneratorAdapter {
@ -36,6 +35,7 @@ public final class CostInstrumentingMethodVisitor extends GeneratorAdapter {
/** /**
* This method replaces MONITORENTER / MONITOREXIT opcodes with POP - basically * This method replaces MONITORENTER / MONITOREXIT opcodes with POP - basically
* stripping the synchronization out of any sandboxed code. * stripping the synchronization out of any sandboxed code.
*
* @param opcode * @param opcode
*/ */
@Override @Override
@ -103,7 +103,7 @@ public final class CostInstrumentingMethodVisitor extends GeneratorAdapter {
/** /**
* This method is called when visiting an opcode with a single operand, that * This method is called when visiting an opcode with a single operand, that
* is a type (represented here as a String). * is a type (represented here as a String).
* * <p>
* For our purposes this is either a NEW opcode or a ANEWARRAY * For our purposes this is either a NEW opcode or a ANEWARRAY
* *
* @param opcode * @param opcode

View File

@ -2,8 +2,10 @@ package net.corda.sandbox.visitors;
import net.corda.sandbox.Utils; import net.corda.sandbox.Utils;
import net.corda.sandbox.WhitelistClassLoader; import net.corda.sandbox.WhitelistClassLoader;
import java.nio.file.*; import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.BasicFileAttributes;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;

View File

@ -2,10 +2,12 @@ package net.corda.sandbox.visitors;
import net.corda.sandbox.WhitelistClassLoader; import net.corda.sandbox.WhitelistClassLoader;
import net.corda.sandbox.CandidacyStatus; import net.corda.sandbox.CandidacyStatus;
import java.util.Arrays; import java.util.Arrays;
import net.corda.sandbox.CandidateMethod; import net.corda.sandbox.CandidateMethod;
import net.corda.sandbox.Utils; import net.corda.sandbox.Utils;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@ -14,6 +16,7 @@ import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import static org.objectweb.asm.Opcodes.*; import static org.objectweb.asm.Opcodes.*;
/** /**
@ -57,7 +60,7 @@ public final class WhitelistCheckingClassVisitor extends ClassVisitor {
/** /**
* We initially take the method passed in and store an internal representation of * We initially take the method passed in and store an internal representation of
* the method signature in the our CandidacyStatus working set. * the method signature in the our CandidacyStatus working set.
* * <p>
* We then get an ASM MethodVisitor (which can read the byte code of the method) and pass that to our * We then get an ASM MethodVisitor (which can read the byte code of the method) and pass that to our
* custom method visitor which perform additional checks. * custom method visitor which perform additional checks.
* *

View File

@ -13,7 +13,6 @@ import org.objectweb.asm.Label;
/** /**
* A MethodVisitor which checks method instructions in order to determine if this * A MethodVisitor which checks method instructions in order to determine if this
* method is deterministic or not * method is deterministic or not
*
*/ */
final class WhitelistCheckingMethodVisitor extends MethodVisitor { final class WhitelistCheckingMethodVisitor extends MethodVisitor {
@ -85,14 +84,14 @@ final class WhitelistCheckingMethodVisitor extends MethodVisitor {
/** /**
* Currently a no-op. * Currently a no-op.
* * <p>
* The JVMspec seems to permit the possibility of using a backwards branch in a * The JVMspec seems to permit the possibility of using a backwards branch in a
* tableswitch to try to create an infinite loop. However, it seems to be * tableswitch to try to create an infinite loop. However, it seems to be
* impossible in practice - the specification of StackMapFrame seems to prevent * impossible in practice - the specification of StackMapFrame seems to prevent
* it in modern classfile formats, and even by explicitly generating a version * it in modern classfile formats, and even by explicitly generating a version
* 49 (Java 5) classfile, the verifier seems to be specifically resistant to a * 49 (Java 5) classfile, the verifier seems to be specifically resistant to a
* backwards branch from a tableswitch. * backwards branch from a tableswitch.
* * <p>
* We could still add a belt-and-braces static instrumentation to protect * We could still add a belt-and-braces static instrumentation to protect
* against this but it currently seems unnecessary - at worse it is a branch that * against this but it currently seems unnecessary - at worse it is a branch that
* should count against the branch limit, or an explicit disallow of a backwards * should count against the branch limit, or an explicit disallow of a backwards

View File

@ -1,10 +1,13 @@
package net.corda.sandbox; package net.corda.sandbox;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import org.junit.Test; import org.junit.Test;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.*; import org.junit.*;
public class WhitelistClassLoaderTest { public class WhitelistClassLoaderTest {

View File

@ -11,7 +11,6 @@ import java.util.*;
import static org.junit.Assert.*; import static org.junit.Assert.*;
/** /**
*
* @author ben * @author ben
*/ */
public class DeterministicClassInstrumenterTest { public class DeterministicClassInstrumenterTest {

View File

@ -1,19 +1,24 @@
package net.corda.sandbox.costing; package net.corda.sandbox.costing;
import net.corda.sandbox.TestUtils; import net.corda.sandbox.TestUtils;
import static net.corda.sandbox.TestUtils.*; import static net.corda.sandbox.TestUtils.*;
import net.corda.sandbox.Utils; import net.corda.sandbox.Utils;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import org.junit.Before; import org.junit.Before;
import org.junit.BeforeClass; import org.junit.BeforeClass;
/** /**
*
* @author ben * @author ben
*/ */
public class SandboxedRewritingTest { public class SandboxedRewritingTest {

View File

@ -1,7 +1,6 @@
package sandbox.greymalkin; package sandbox.greymalkin;
/** /**
*
* @author ben * @author ben
*/ */
// Simple hack for now, generalise to lambdas later... // Simple hack for now, generalise to lambdas later...

View File

@ -101,9 +101,7 @@ public class JavaCommercialPaper implements Contract {
if (issuance != null ? !issuance.equals(state.issuance) : state.issuance != null) return false; if (issuance != null ? !issuance.equals(state.issuance) : state.issuance != null) return false;
if (owner != null ? !owner.equals(state.owner) : state.owner != null) return false; if (owner != null ? !owner.equals(state.owner) : state.owner != null) return false;
if (faceValue != null ? !faceValue.equals(state.faceValue) : state.faceValue != null) return false; if (faceValue != null ? !faceValue.equals(state.faceValue) : state.faceValue != null) return false;
if (maturityDate != null ? !maturityDate.equals(state.maturityDate) : state.maturityDate != null) return maturityDate != null ? maturityDate.equals(state.maturityDate) : state.maturityDate == null;
return false;
return true;
} }
@Override @Override

View File

@ -8,12 +8,18 @@ import net.corda.core.contracts.PartyAndReference
import java.math.BigDecimal import java.math.BigDecimal
import java.util.* import java.util.*
@JvmField val USD: Currency = Currency.getInstance("USD") @JvmField
@JvmField val GBP: Currency = Currency.getInstance("GBP") val USD: Currency = Currency.getInstance("USD")
@JvmField val EUR: Currency = Currency.getInstance("EUR") @JvmField
@JvmField val CHF: Currency = Currency.getInstance("CHF") val GBP: Currency = Currency.getInstance("GBP")
@JvmField val JPY: Currency = Currency.getInstance("JPY") @JvmField
@JvmField val RUB: Currency = Currency.getInstance("RUB") val EUR: Currency = Currency.getInstance("EUR")
@JvmField
val CHF: Currency = Currency.getInstance("CHF")
@JvmField
val JPY: Currency = Currency.getInstance("JPY")
@JvmField
val RUB: Currency = Currency.getInstance("RUB")
fun <T : Any> AMOUNT(amount: Int, token: T): Amount<T> = AMOUNT(amount.toLong(), token) fun <T : Any> AMOUNT(amount: Int, token: T): Amount<T> = AMOUNT(amount.toLong(), token)
fun <T : Any> AMOUNT(amount: Long, token: T): Amount<T> = Amount.fromDecimal(BigDecimal.valueOf(amount), token) fun <T : Any> AMOUNT(amount: Long, token: T): Amount<T> = Amount.fromDecimal(BigDecimal.valueOf(amount), token)

View File

@ -49,6 +49,7 @@ class CommercialPaper : Contract {
companion object { companion object {
const val CP_PROGRAM_ID: ContractClassName = "net.corda.finance.contracts.CommercialPaper" const val CP_PROGRAM_ID: ContractClassName = "net.corda.finance.contracts.CommercialPaper"
} }
data class State( data class State(
val issuance: PartyAndReference, val issuance: PartyAndReference,
override val owner: AbstractParty, override val owner: AbstractParty,
@ -89,7 +90,8 @@ class CommercialPaper : Contract {
} }
} }
/** @suppress */ infix fun `owned by`(owner: AbstractParty) = copy(owner = owner) /** @suppress */
infix fun `owned by`(owner: AbstractParty) = copy(owner = owner)
} }
interface Commands : CommandData { interface Commands : CommandData {

View File

@ -401,10 +401,17 @@ class Cash : OnLedgerAsset<Currency, Cash.Commands, Cash.State>() {
// Small DSL extensions. // Small DSL extensions.
/** @suppress */ infix fun Cash.State.`owned by`(owner: AbstractParty) = ownedBy(owner) /** @suppress */
/** @suppress */ infix fun Cash.State.`issued by`(party: AbstractParty) = issuedBy(party) infix fun Cash.State.`owned by`(owner: AbstractParty) = ownedBy(owner)
/** @suppress */ infix fun Cash.State.`issued by`(deposit: PartyAndReference) = issuedBy(deposit)
/** @suppress */ infix fun Cash.State.`with deposit`(deposit: PartyAndReference): Cash.State = withDeposit(deposit) /** @suppress */
infix fun Cash.State.`issued by`(party: AbstractParty) = issuedBy(party)
/** @suppress */
infix fun Cash.State.`issued by`(deposit: PartyAndReference) = issuedBy(deposit)
/** @suppress */
infix fun Cash.State.`with deposit`(deposit: PartyAndReference): Cash.State = withDeposit(deposit)
// Unit testing helpers. These could go in a separate file but it's hardly worth it for just a few functions. // Unit testing helpers. These could go in a separate file but it's hardly worth it for just a few functions.

View File

@ -44,6 +44,7 @@ class CommodityContract : OnLedgerAsset<Commodity, CommodityContract.Commands, C
) : FungibleAsset<Commodity> { ) : FungibleAsset<Commodity> {
constructor(deposit: PartyAndReference, amount: Amount<Commodity>, owner: AbstractParty) constructor(deposit: PartyAndReference, amount: Amount<Commodity>, owner: AbstractParty)
: this(Amount(amount.quantity, Issued(deposit, amount.token)), owner) : this(Amount(amount.quantity, Issued(deposit, amount.token)), owner)
override val exitKeys: Set<PublicKey> = Collections.singleton(owner.owningKey) override val exitKeys: Set<PublicKey> = Collections.singleton(owner.owningKey)
override val participants = listOf(owner) override val participants = listOf(owner)

View File

@ -73,6 +73,7 @@ class Obligation<P : Any> : Contract {
companion object { companion object {
const val PROGRAM_ID: ContractClassName = "net.corda.finance.contracts.asset.Obligation" const val PROGRAM_ID: ContractClassName = "net.corda.finance.contracts.asset.Obligation"
} }
/** /**
* Represents where in its lifecycle a contract state is, which in turn controls the commands that can be applied * Represents where in its lifecycle a contract state is, which in turn controls the commands that can be applied
* to the state. Most states will not leave the [NORMAL] lifecycle. Note that settled (as an end lifecycle) is * to the state. Most states will not leave the [NORMAL] lifecycle. Note that settled (as an end lifecycle) is
@ -453,7 +454,7 @@ class Obligation<P : Any> : Contract {
requireThat { requireThat {
"there is a time-window from the authority" using (timeWindow != null) "there is a time-window from the authority" using (timeWindow != null)
"the due date has passed" using (timeWindow!!.fromTime?.isAfter(deadline) ?: false) "the due date has passed" using (timeWindow!!.fromTime?.isAfter(deadline) == true)
"input state lifecycle is correct" using (input.lifecycle == expectedInputLifecycle) "input state lifecycle is correct" using (input.lifecycle == expectedInputLifecycle)
"output state corresponds exactly to input state, with lifecycle changed" using (expectedOutput == actualOutput) "output state corresponds exactly to input state, with lifecycle changed" using (expectedOutput == actualOutput)
} }
@ -785,9 +786,11 @@ infix fun <T : Any> Obligation.State<T>.between(parties: Pair<AbstractParty, Abs
infix fun <T : Any> Obligation.State<T>.`owned by`(owner: AbstractParty) = copy(beneficiary = owner) infix fun <T : Any> Obligation.State<T>.`owned by`(owner: AbstractParty) = copy(beneficiary = owner)
infix fun <T : Any> Obligation.State<T>.`issued by`(party: AbstractParty) = copy(obligor = party) infix fun <T : Any> Obligation.State<T>.`issued by`(party: AbstractParty) = copy(obligor = party)
// For Java users: // For Java users:
@Suppress("unused") fun <T : Any> Obligation.State<T>.ownedBy(owner: AbstractParty) = copy(beneficiary = owner) @Suppress("unused")
fun <T : Any> Obligation.State<T>.ownedBy(owner: AbstractParty) = copy(beneficiary = owner)
@Suppress("unused") fun <T : Any> Obligation.State<T>.issuedBy(party: AnonymousParty) = copy(obligor = party) @Suppress("unused")
fun <T : Any> Obligation.State<T>.issuedBy(party: AnonymousParty) = copy(obligor = party)
/** A randomly generated key. */ /** A randomly generated key. */
val DUMMY_OBLIGATION_ISSUER_KEY by lazy { entropyToKeyPair(BigInteger.valueOf(10)) } val DUMMY_OBLIGATION_ISSUER_KEY by lazy { entropyToKeyPair(BigInteger.valueOf(10)) }

View File

@ -32,6 +32,7 @@ class CashIssueAndPaymentFlow(val amount: Amount<Currency>,
recipient: Party, recipient: Party,
anonymous: Boolean, anonymous: Boolean,
notary: Party) : this(amount, issueRef, recipient, anonymous, notary, tracker()) notary: Party) : this(amount, issueRef, recipient, anonymous, notary, tracker())
constructor(request: IssueAndPaymentRequest) : this(request.amount, request.issueRef, request.recipient, request.anonymous, request.notary, tracker()) constructor(request: IssueAndPaymentRequest) : this(request.amount, request.issueRef, request.recipient, request.anonymous, request.notary, tracker())
@Suspendable @Suspendable

View File

@ -31,6 +31,7 @@ class CashIssueFlow(private val amount: Amount<Currency>,
constructor(amount: Amount<Currency>, constructor(amount: Amount<Currency>,
issuerBankPartyRef: OpaqueBytes, issuerBankPartyRef: OpaqueBytes,
notary: Party) : this(amount, issuerBankPartyRef, notary, tracker()) notary: Party) : this(amount, issuerBankPartyRef, notary, tracker())
constructor(request: IssueRequest) : this(request.amount, request.issueRef, request.notary, tracker()) constructor(request: IssueRequest) : this(request.amount, request.issueRef, request.notary, tracker())
@Suspendable @Suspendable

View File

@ -31,8 +31,10 @@ open class CashPaymentFlow(
val issuerConstraint: Set<Party> = emptySet()) : AbstractCashFlow<AbstractCashFlow.Result>(progressTracker) { val issuerConstraint: Set<Party> = emptySet()) : AbstractCashFlow<AbstractCashFlow.Result>(progressTracker) {
/** A straightforward constructor that constructs spends using cash states of any issuer. */ /** A straightforward constructor that constructs spends using cash states of any issuer. */
constructor(amount: Amount<Currency>, recipient: Party) : this(amount, recipient, true, tracker()) constructor(amount: Amount<Currency>, recipient: Party) : this(amount, recipient, true, tracker())
/** A straightforward constructor that constructs spends using cash states of any issuer. */ /** A straightforward constructor that constructs spends using cash states of any issuer. */
constructor(amount: Amount<Currency>, recipient: Party, anonymous: Boolean) : this(amount, recipient, anonymous, tracker()) constructor(amount: Amount<Currency>, recipient: Party, anonymous: Boolean) : this(amount, recipient, anonymous, tracker())
constructor(request: PaymentRequest) : this(request.amount, request.recipient, request.anonymous, tracker(), request.issuerConstraint) constructor(request: PaymentRequest) : this(request.amount, request.recipient, request.anonymous, tracker(), request.issuerConstraint)
@Suspendable @Suspendable

View File

@ -43,6 +43,7 @@ object TwoPartyDealFlow {
companion object { companion object {
object GENERATING_ID : ProgressTracker.Step("Generating anonymous identities") object GENERATING_ID : ProgressTracker.Step("Generating anonymous identities")
object SENDING_PROPOSAL : ProgressTracker.Step("Handshaking and awaiting transaction proposal.") object SENDING_PROPOSAL : ProgressTracker.Step("Handshaking and awaiting transaction proposal.")
fun tracker() = ProgressTracker(GENERATING_ID, SENDING_PROPOSAL) fun tracker() = ProgressTracker(GENERATING_ID, SENDING_PROPOSAL)
} }
@ -148,6 +149,7 @@ object TwoPartyDealFlow {
@Suspendable @Suspendable
protected abstract fun validateHandshake(handshake: Handshake<U>): Handshake<U> protected abstract fun validateHandshake(handshake: Handshake<U>): Handshake<U>
@Suspendable @Suspendable
protected abstract fun assembleSharedTX(handshake: Handshake<U>): Triple<TransactionBuilder, List<PublicKey>, List<TransactionSignature>> protected abstract fun assembleSharedTX(handshake: Handshake<U>): Triple<TransactionBuilder, List<PublicKey>, List<TransactionSignature>>
} }

View File

@ -136,6 +136,7 @@ object TwoPartyTradeFlow {
private val anonymous: Boolean) : FlowLogic<SignedTransaction>() { private val anonymous: Boolean) : FlowLogic<SignedTransaction>() {
constructor(otherSideSession: FlowSession, notary: Party, acceptablePrice: Amount<Currency>, typeToBuy: Class<out OwnableState>) : constructor(otherSideSession: FlowSession, notary: Party, acceptablePrice: Amount<Currency>, typeToBuy: Class<out OwnableState>) :
this(otherSideSession, notary, acceptablePrice, typeToBuy, true) this(otherSideSession, notary, acceptablePrice, typeToBuy, true)
// DOCSTART 2 // DOCSTART 2
object RECEIVING : ProgressTracker.Step("Waiting for seller trading info") object RECEIVING : ProgressTracker.Step("Waiting for seller trading info")

View File

@ -1,4 +1,5 @@
@file:JvmName("StateSumming") @file:JvmName("StateSumming")
package net.corda.finance.utils package net.corda.finance.utils
import net.corda.core.contracts.Amount import net.corda.core.contracts.Amount

View File

@ -80,7 +80,8 @@ class KotlinCommercialPaperLegacyTest : ICommercialPaperTestTemplate {
@RunWith(Parameterized::class) @RunWith(Parameterized::class)
class CommercialPaperTestsGeneric { class CommercialPaperTestsGeneric {
companion object { companion object {
@Parameterized.Parameters @JvmStatic @Parameterized.Parameters
@JvmStatic
fun data() = listOf(JavaCommercialPaperTest(), KotlinCommercialPaperTest(), KotlinCommercialPaperLegacyTest()) fun data() = listOf(JavaCommercialPaperTest(), KotlinCommercialPaperTest(), KotlinCommercialPaperLegacyTest())
} }

View File

@ -1,4 +1,5 @@
@file:JvmName("ConfigUtilities") @file:JvmName("ConfigUtilities")
package net.corda.nodeapi.config package net.corda.nodeapi.config
import com.typesafe.config.Config import com.typesafe.config.Config

View File

@ -1,4 +1,5 @@
@file:JvmName("ClientContexts") @file:JvmName("ClientContexts")
package net.corda.nodeapi.internal.serialization package net.corda.nodeapi.internal.serialization
import net.corda.core.serialization.SerializationContext import net.corda.core.serialization.SerializationContext

View File

@ -140,6 +140,7 @@ object DefaultKryoCustomizer {
// Use this to allow construction of objects using a JVM backdoor that skips invoking the constructors, if there // Use this to allow construction of objects using a JVM backdoor that skips invoking the constructors, if there
// is no no-arg constructor available. // is no no-arg constructor available.
private val defaultStrategy = Kryo.DefaultInstantiatorStrategy(fallbackStrategy) private val defaultStrategy = Kryo.DefaultInstantiatorStrategy(fallbackStrategy)
override fun <T> newInstantiatorOf(type: Class<T>): ObjectInstantiator<T> { override fun <T> newInstantiatorOf(type: Class<T>): ObjectInstantiator<T> {
// However this doesn't work for non-public classes in the java. namespace // However this doesn't work for non-public classes in the java. namespace
val strat = if (type.name.startsWith("java.") && !isPublic(type.modifiers)) fallbackStrategy else defaultStrategy val strat = if (type.name.startsWith("java.") && !isPublic(type.modifiers)) fallbackStrategy else defaultStrategy
@ -151,6 +152,7 @@ object DefaultKryoCustomizer {
override fun write(kryo: Kryo, output: Output, obj: PartyAndCertificate) { override fun write(kryo: Kryo, output: Output, obj: PartyAndCertificate) {
kryo.writeClassAndObject(output, obj.certPath) kryo.writeClassAndObject(output, obj.certPath)
} }
override fun read(kryo: Kryo, input: Input, type: Class<PartyAndCertificate>): PartyAndCertificate { override fun read(kryo: Kryo, input: Input, type: Class<PartyAndCertificate>): PartyAndCertificate {
return PartyAndCertificate(kryo.readClassAndObject(input) as CertPath) return PartyAndCertificate(kryo.readClassAndObject(input) as CertPath)
} }

View File

@ -52,7 +52,7 @@ data class SerializationContextImpl(override val preferredSerializationVersion:
* We need to cache the AttachmentClassLoaders to avoid too many contexts, since the class loader is part of cache key for the context. * We need to cache the AttachmentClassLoaders to avoid too many contexts, since the class loader is part of cache key for the context.
*/ */
override fun withAttachmentsClassLoader(attachmentHashes: List<SecureHash>): SerializationContext { override fun withAttachmentsClassLoader(attachmentHashes: List<SecureHash>): SerializationContext {
properties[attachmentsClassLoaderEnabledPropertyName] as? Boolean ?: false || return this properties[attachmentsClassLoaderEnabledPropertyName] as? Boolean == true || return this
val serializationContext = properties[serializationContextKey] as? SerializeAsTokenContextImpl ?: return this // Some tests don't set one. val serializationContext = properties[serializationContextKey] as? SerializeAsTokenContextImpl ?: return this // Some tests don't set one.
try { try {
return withClassLoader(cache.get(attachmentHashes) { return withClassLoader(cache.get(attachmentHashes) {

View File

@ -1,4 +1,5 @@
@file:JvmName("ServerContexts") @file:JvmName("ServerContexts")
package net.corda.nodeapi.internal.serialization package net.corda.nodeapi.internal.serialization
import net.corda.core.serialization.ClassWhitelist import net.corda.core.serialization.ClassWhitelist

View File

@ -26,8 +26,7 @@ open class ArraySerializer(override val type: Type, factory: SerializerFactory)
private fun calcTypeName(type: Type): String = private fun calcTypeName(type: Type): String =
if (type.componentType().isArray()) { if (type.componentType().isArray()) {
val typeName = calcTypeName(type.componentType()); "$typeName[]" val typeName = calcTypeName(type.componentType()); "$typeName[]"
} } else {
else {
val arrayType = if (type.asClass()!!.componentType.isPrimitive) "[p]" else "[]" val arrayType = if (type.asClass()!!.componentType.isPrimitive) "[p]" else "[]"
"${type.componentType().typeName}$arrayType" "${type.componentType().typeName}$arrayType"
} }

View File

@ -38,8 +38,7 @@ class CollectionSerializer(val declaredType: ParameterizedType, factory: Seriali
if (supportedTypes.containsKey(declaredClass)) { if (supportedTypes.containsKey(declaredClass)) {
// Simple case - it is already known to be a collection. // Simple case - it is already known to be a collection.
return deriveParametrizedType(declaredType, uncheckedCast(declaredClass)) return deriveParametrizedType(declaredType, uncheckedCast(declaredClass))
} } else if (actualClass != null && Collection::class.java.isAssignableFrom(actualClass)) {
else if (actualClass != null && Collection::class.java.isAssignableFrom(actualClass)) {
// Declared class is not collection, but [actualClass] is - represent it accordingly. // Declared class is not collection, but [actualClass] is - represent it accordingly.
val collectionClass = findMostSuitableCollectionType(actualClass) val collectionClass = findMostSuitableCollectionType(actualClass)
return deriveParametrizedType(declaredType, collectionClass) return deriveParametrizedType(declaredType, collectionClass)

View File

@ -151,8 +151,7 @@ abstract class CustomSerializer<T : Any> : AMQPSerializer<T> {
* @param unmake A lambda that extracts the string value for an instance, that defaults to the [toString] method. * @param unmake A lambda that extracts the string value for an instance, that defaults to the [toString] method.
*/ */
abstract class ToString<T : Any>(clazz: Class<T>, withInheritance: Boolean = false, abstract class ToString<T : Any>(clazz: Class<T>, withInheritance: Boolean = false,
private val maker: (String) -> T = clazz.getConstructor(String::class.java).let { private val maker: (String) -> T = clazz.getConstructor(String::class.java).let { `constructor` ->
`constructor` ->
{ string -> `constructor`.newInstance(string) } { string -> `constructor`.newInstance(string) }
}, },
private val unmaker: (T) -> String = { obj -> obj.toString() }) private val unmaker: (T) -> String = { obj -> obj.toString() })

View File

@ -45,8 +45,7 @@ class MapSerializer(private val declaredType: ParameterizedType, factory: Serial
if (supportedTypes.containsKey(declaredClass)) { if (supportedTypes.containsKey(declaredClass)) {
// Simple case - it is already known to be a map. // Simple case - it is already known to be a map.
return deriveParametrizedType(declaredType, uncheckedCast(declaredClass)) return deriveParametrizedType(declaredType, uncheckedCast(declaredClass))
} } else if (actualClass != null && Map::class.java.isAssignableFrom(actualClass)) {
else if (actualClass != null && Map::class.java.isAssignableFrom(actualClass)) {
// Declared class is not map, but [actualClass] is - represent it accordingly. // Declared class is not map, but [actualClass] is - represent it accordingly.
val mapClass = findMostSuitableMapType(actualClass) val mapClass = findMostSuitableMapType(actualClass)
return deriveParametrizedType(declaredType, mapClass) return deriveParametrizedType(declaredType, mapClass)
@ -108,12 +107,10 @@ internal fun Class<*>.checkSupportedMapType() {
if (HashMap::class.java.isAssignableFrom(this) && !LinkedHashMap::class.java.isAssignableFrom(this)) { if (HashMap::class.java.isAssignableFrom(this) && !LinkedHashMap::class.java.isAssignableFrom(this)) {
throw IllegalArgumentException( throw IllegalArgumentException(
"Map type $this is unstable under iteration. Suggested fix: use java.util.LinkedHashMap instead.") "Map type $this is unstable under iteration. Suggested fix: use java.util.LinkedHashMap instead.")
} } else if (WeakHashMap::class.java.isAssignableFrom(this)) {
else if (WeakHashMap::class.java.isAssignableFrom(this)) {
throw IllegalArgumentException("Weak references with map types not supported. Suggested fix: " throw IllegalArgumentException("Weak references with map types not supported. Suggested fix: "
+ "use java.util.LinkedHashMap instead.") + "use java.util.LinkedHashMap instead.")
} } else if (Dictionary::class.java.isAssignableFrom(this)) {
else if (Dictionary::class.java.isAssignableFrom(this)) {
throw IllegalArgumentException( throw IllegalArgumentException(
"Unable to serialise deprecated type $this. Suggested fix: prefer java.util.map implementations") "Unable to serialise deprecated type $this. Suggested fix: prefer java.util.map implementations")
} }

View File

@ -21,8 +21,8 @@ sealed class PropertySerializer(val name: String, val readMethod: Method?, val r
val default: String? = generateDefault() val default: String? = generateDefault()
val mandatory: Boolean = generateMandatory() val mandatory: Boolean = generateMandatory()
private val isInterface: Boolean get() = resolvedType.asClass()?.isInterface ?: false private val isInterface: Boolean get() = resolvedType.asClass()?.isInterface == true
private val isJVMPrimitive: Boolean get() = resolvedType.asClass()?.isPrimitive ?: false private val isJVMPrimitive: Boolean get() = resolvedType.asClass()?.isPrimitive == true
private fun generateType(): String { private fun generateType(): String {
return if (isInterface || resolvedType == Any::class.java) "*" else SerializerFactory.nameForType(resolvedType) return if (isInterface || resolvedType == Any::class.java) "*" else SerializerFactory.nameForType(resolvedType)
@ -45,7 +45,7 @@ sealed class PropertySerializer(val name: String, val readMethod: Method?, val r
} }
private fun generateMandatory(): Boolean { private fun generateMandatory(): Boolean {
return isJVMPrimitive || !(readMethod?.returnsNullable() ?: true) return isJVMPrimitive || readMethod?.returnsNullable() == false
} }
private fun Method.returnsNullable(): Boolean { private fun Method.returnsNullable(): Boolean {

View File

@ -88,8 +88,7 @@ open class SerializationOutput(internal val serializerFactory: SerializerFactory
// assigned to them first as they will be first read from the stream on receiving end. // assigned to them first as they will be first read from the stream on receiving end.
// Skip for primitive types as they are too small and overhead of referencing them will be much higher than their content // Skip for primitive types as they are too small and overhead of referencing them will be much higher than their content
if (suitableForObjectReference(obj.javaClass)) objectHistory.put(obj, objectHistory.size) if (suitableForObjectReference(obj.javaClass)) objectHistory.put(obj, objectHistory.size)
} } else {
else {
data.writeReferencedObject(ReferencedObject(retrievedRefCount)) data.writeReferencedObject(ReferencedObject(retrievedRefCount))
} }
} }

View File

@ -12,10 +12,12 @@ class ZonedDateTimeSerializer(factory: SerializerFactory) : CustomSerializer.Pro
// so that any change to internals of `ZonedDateTime` is detected early. // so that any change to internals of `ZonedDateTime` is detected early.
companion object { companion object {
val ofLenient = ZonedDateTime::class.java.getDeclaredMethod("ofLenient", LocalDateTime::class.java, ZoneOffset::class.java, ZoneId::class.java) val ofLenient = ZonedDateTime::class.java.getDeclaredMethod("ofLenient", LocalDateTime::class.java, ZoneOffset::class.java, ZoneId::class.java)
init { init {
ofLenient.isAccessible = true ofLenient.isAccessible = true
} }
} }
override val additionalSerializers: Iterable<CustomSerializer<out Any>> = listOf(LocalDateTimeSerializer(factory), ZoneIdSerializer(factory)) override val additionalSerializers: Iterable<CustomSerializer<out Any>> = listOf(LocalDateTimeSerializer(factory), ZoneIdSerializer(factory))
override fun toProxy(obj: ZonedDateTime): ZonedDateTimeProxy = ZonedDateTimeProxy(obj.toLocalDateTime(), obj.offset, obj.zone) override fun toProxy(obj: ZonedDateTime): ZonedDateTimeProxy = ZonedDateTimeProxy(obj.toLocalDateTime(), obj.offset, obj.zone)

View File

@ -132,5 +132,10 @@ fun AMQPField.validateType(classloader: ClassLoader) = when (type) {
} }
private fun ClassLoader.exists(clazz: String) = run { private fun ClassLoader.exists(clazz: String) = run {
try { this.loadClass(clazz); true } catch (e: ClassNotFoundException) { false } } try {
this.loadClass(clazz); true
} catch (e: ClassNotFoundException) {
false
}
}

View File

@ -12,7 +12,8 @@ import java.util.List;
public class ListsSerializationJavaTest { public class ListsSerializationJavaTest {
@CordaSerializable @CordaSerializable
interface Parent {} interface Parent {
}
public static class Child implements Parent { public static class Child implements Parent {
private final int value; private final int value;

View File

@ -45,6 +45,7 @@ class AttachmentsClassLoaderTests : TestDependencyInjectionBase() {
whenever(serviceHub.attachments).thenReturn(attachmentStorage) whenever(serviceHub.attachments).thenReturn(attachmentStorage)
return this.withServiceHub(serviceHub) return this.withServiceHub(serviceHub)
} }
private fun SerializationContext.withServiceHub(serviceHub: ServiceHub): SerializationContext { private fun SerializationContext.withServiceHub(serviceHub: ServiceHub): SerializationContext {
return this.withTokenContext(SerializeAsTokenContextImpl(serviceHub) {}).withProperty(attachmentsClassLoaderEnabledPropertyName, true) return this.withTokenContext(SerializeAsTokenContextImpl(serviceHub) {}).withProperty(attachmentsClassLoaderEnabledPropertyName, true)
} }

View File

@ -271,6 +271,7 @@ class CordaClassResolverTests {
} }
open class SubHashSet<E> : HashSet<E>() open class SubHashSet<E> : HashSet<E>()
@Test @Test
fun `Check blacklisted subclass`() { fun `Check blacklisted subclass`() {
expectedEx.expect(IllegalStateException::class.java) expectedEx.expect(IllegalStateException::class.java)
@ -281,6 +282,7 @@ class CordaClassResolverTests {
} }
class SubSubHashSet<E> : SubHashSet<E>() class SubSubHashSet<E> : SubHashSet<E>()
@Test @Test
fun `Check blacklisted subsubclass`() { fun `Check blacklisted subsubclass`() {
expectedEx.expect(IllegalStateException::class.java) expectedEx.expect(IllegalStateException::class.java)
@ -291,6 +293,7 @@ class CordaClassResolverTests {
} }
class ConnectionImpl(private val connection: Connection) : Connection by connection class ConnectionImpl(private val connection: Connection) : Connection by connection
@Test @Test
fun `Check blacklisted interface impl`() { fun `Check blacklisted interface impl`() {
expectedEx.expect(IllegalStateException::class.java) expectedEx.expect(IllegalStateException::class.java)
@ -302,6 +305,7 @@ class CordaClassResolverTests {
interface SubConnection : Connection interface SubConnection : Connection
class SubConnectionImpl(private val subConnection: SubConnection) : SubConnection by subConnection class SubConnectionImpl(private val subConnection: SubConnection) : SubConnection by subConnection
@Test @Test
fun `Check blacklisted super-interface impl`() { fun `Check blacklisted super-interface impl`() {
expectedEx.expect(IllegalStateException::class.java) expectedEx.expect(IllegalStateException::class.java)
@ -320,6 +324,7 @@ class CordaClassResolverTests {
@CordaSerializable @CordaSerializable
class CordaSerializableHashSet<E> : HashSet<E>() class CordaSerializableHashSet<E> : HashSet<E>()
@Test @Test
fun `Check blacklist precedes CordaSerializable`() { fun `Check blacklist precedes CordaSerializable`() {
expectedEx.expect(IllegalStateException::class.java) expectedEx.expect(IllegalStateException::class.java)

View File

@ -105,6 +105,7 @@ class SerializationTokenTest : TestDependencyInjectionBase() {
object UnitSerializationToken : SerializationToken { object UnitSerializationToken : SerializationToken {
override fun fromToken(context: SerializeAsTokenContext): Any = UnitSerializeAsToken() override fun fromToken(context: SerializeAsTokenContext): Any = UnitSerializeAsToken()
} }
override fun toToken(context: SerializeAsTokenContext): SerializationToken = UnitSerializationToken override fun toToken(context: SerializeAsTokenContext): SerializationToken = UnitSerializationToken
} }

View File

@ -17,6 +17,7 @@ class DeserializeMapTests {
@Test @Test
fun mapTest() { fun mapTest() {
data class C(val c: Map<String, Int>) data class C(val c: Map<String, Int>)
val c = C(mapOf("A" to 1, "B" to 2)) val c = C(mapOf("A" to 1, "B" to 2))
val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c) val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c)
@ -26,6 +27,7 @@ class DeserializeMapTests {
@Test(expected = java.io.NotSerializableException::class) @Test(expected = java.io.NotSerializableException::class)
fun abstractMapFromMapOf() { fun abstractMapFromMapOf() {
data class C(val c: AbstractMap<String, Int>) data class C(val c: AbstractMap<String, Int>)
val c = C(mapOf("A" to 1, "B" to 2) as AbstractMap) val c = C(mapOf("A" to 1, "B" to 2) as AbstractMap)
val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c) val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c)
@ -35,6 +37,7 @@ class DeserializeMapTests {
@Test(expected = java.io.NotSerializableException::class) @Test(expected = java.io.NotSerializableException::class)
fun abstractMapFromTreeMap() { fun abstractMapFromTreeMap() {
data class C(val c: AbstractMap<String, Int>) data class C(val c: AbstractMap<String, Int>)
val c = C(TreeMap(mapOf("A" to 1, "B" to 2))) val c = C(TreeMap(mapOf("A" to 1, "B" to 2)))
val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c) val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c)
@ -44,6 +47,7 @@ class DeserializeMapTests {
@Test @Test
fun sortedMapTest() { fun sortedMapTest() {
data class C(val c: SortedMap<String, Int>) data class C(val c: SortedMap<String, Int>)
val c = C(sortedMapOf("A" to 1, "B" to 2)) val c = C(sortedMapOf("A" to 1, "B" to 2))
val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c) val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c)
DeserializationInput(sf).deserialize(serialisedBytes) DeserializationInput(sf).deserialize(serialisedBytes)
@ -52,6 +56,7 @@ class DeserializeMapTests {
@Test @Test
fun navigableMapTest() { fun navigableMapTest() {
data class C(val c: NavigableMap<String, Int>) data class C(val c: NavigableMap<String, Int>)
val c = C(TreeMap(mapOf("A" to 1, "B" to 2)).descendingMap()) val c = C(TreeMap(mapOf("A" to 1, "B" to 2)).descendingMap())
val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c) val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c)
@ -61,6 +66,7 @@ class DeserializeMapTests {
@Test @Test
fun dictionaryTest() { fun dictionaryTest() {
data class C(val c: Dictionary<String, Int>) data class C(val c: Dictionary<String, Int>)
val v: Hashtable<String, Int> = Hashtable() val v: Hashtable<String, Int> = Hashtable()
v.put("a", 1) v.put("a", 1)
v.put("b", 2) v.put("b", 2)
@ -74,6 +80,7 @@ class DeserializeMapTests {
@Test @Test
fun hashtableTest() { fun hashtableTest() {
data class C(val c: Hashtable<String, Int>) data class C(val c: Hashtable<String, Int>)
val v: Hashtable<String, Int> = Hashtable() val v: Hashtable<String, Int> = Hashtable()
v.put("a", 1) v.put("a", 1)
v.put("b", 2) v.put("b", 2)
@ -87,6 +94,7 @@ class DeserializeMapTests {
@Test @Test
fun hashMapTest() { fun hashMapTest() {
data class C(val c: HashMap<String, Int>) data class C(val c: HashMap<String, Int>)
val c = C(HashMap(mapOf("A" to 1, "B" to 2))) val c = C(HashMap(mapOf("A" to 1, "B" to 2)))
// expect this to throw // expect this to throw
@ -97,6 +105,7 @@ class DeserializeMapTests {
@Test @Test
fun weakHashMapTest() { fun weakHashMapTest() {
data class C(val c: WeakHashMap<String, Int>) data class C(val c: WeakHashMap<String, Int>)
val c = C(WeakHashMap(mapOf("A" to 1, "B" to 2))) val c = C(WeakHashMap(mapOf("A" to 1, "B" to 2)))
Assertions.assertThatThrownBy { TestSerializationOutput(VERBOSE, sf).serialize(c) } Assertions.assertThatThrownBy { TestSerializationOutput(VERBOSE, sf).serialize(c) }
@ -106,6 +115,7 @@ class DeserializeMapTests {
@Test @Test
fun concreteTreeMapTest() { fun concreteTreeMapTest() {
data class C(val c: TreeMap<String, Int>) data class C(val c: TreeMap<String, Int>)
val c = C(TreeMap(mapOf("A" to 1, "B" to 3))) val c = C(TreeMap(mapOf("A" to 1, "B" to 3)))
val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c) val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c)
@ -115,6 +125,7 @@ class DeserializeMapTests {
@Test @Test
fun concreteLinkedHashMapTest() { fun concreteLinkedHashMapTest() {
data class C(val c: LinkedHashMap<String, Int>) data class C(val c: LinkedHashMap<String, Int>)
val c = C(LinkedHashMap(mapOf("A" to 1, "B" to 2))) val c = C(LinkedHashMap(mapOf("A" to 1, "B" to 2)))
val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c) val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c)

View File

@ -402,6 +402,7 @@ class DeserializeSimpleTypesTests {
@Test @Test
fun arrayOfArrayOfInt() { fun arrayOfArrayOfInt() {
class C(val c: Array<Array<Int>>) class C(val c: Array<Array<Int>>)
val c = C(arrayOf(arrayOf(1, 2, 3), arrayOf(4, 5, 6))) val c = C(arrayOf(arrayOf(1, 2, 3), arrayOf(4, 5, 6)))
val serialisedC = TestSerializationOutput(VERBOSE, sf1).serialize(c) val serialisedC = TestSerializationOutput(VERBOSE, sf1).serialize(c)
@ -421,6 +422,7 @@ class DeserializeSimpleTypesTests {
@Test @Test
fun arrayOfIntArray() { fun arrayOfIntArray() {
class C(val c: Array<IntArray>) class C(val c: Array<IntArray>)
val c = C(arrayOf(IntArray(3), IntArray(3))) val c = C(arrayOf(IntArray(3), IntArray(3)))
c.c[0][0] = 1; c.c[0][1] = 2; c.c[0][2] = 3 c.c[0][0] = 1; c.c[0][1] = 2; c.c[0][2] = 3
c.c[1][0] = 4; c.c[1][1] = 5; c.c[1][2] = 6 c.c[1][0] = 4; c.c[1][1] = 5; c.c[1][2] = 6
@ -447,14 +449,24 @@ class DeserializeSimpleTypesTests {
arrayOf(IntArray(3), IntArray(3), IntArray(3)), arrayOf(IntArray(3), IntArray(3), IntArray(3)),
arrayOf(IntArray(3), IntArray(3), IntArray(3)))) arrayOf(IntArray(3), IntArray(3), IntArray(3))))
for (i in 0..2) { for (j in 0..2) { for (k in 0..2) { c.c[i][j][k] = i + j + k } } } for (i in 0..2) {
for (j in 0..2) {
for (k in 0..2) {
c.c[i][j][k] = i + j + k
}
}
}
val serialisedC = TestSerializationOutput(VERBOSE, sf1).serialize(c) val serialisedC = TestSerializationOutput(VERBOSE, sf1).serialize(c)
val deserializedC = DeserializationInput(sf1).deserialize(serialisedC) val deserializedC = DeserializationInput(sf1).deserialize(serialisedC)
for (i in 0..2) { for (j in 0..2) { for (k in 0..2) { for (i in 0..2) {
for (j in 0..2) {
for (k in 0..2) {
assertEquals(c.c[i][j][k], deserializedC.c[i][j][k]) assertEquals(c.c[i][j][k], deserializedC.c[i][j][k])
}}} }
}
}
} }
@Test @Test

Some files were not shown because too many files have changed in this diff Show More