Skip to content

Commit 3a6deee

Browse files
committed
Merge branch 'release/os/4.9' into shams-4.10-merge-e6a80822
# Conflicts: # .github/workflows/check-pr-title.yml # .snyk # node-api/src/main/kotlin/net/corda/nodeapi/internal/protonwrapper/netty/AMQPClient.kt # node/src/integration-test/kotlin/net/corda/node/amqp/AMQPClientSslErrorsTest.kt # node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt
2 parents 25e7d2f + e6a8082 commit 3a6deee

File tree

67 files changed

+1671
-1188
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+1671
-1188
lines changed

.github/workflows/check-pr-title.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ jobs:
99
steps:
1010
- uses: morrisoncole/pr-lint-action@v1.6.1
1111
with:
12-
title-regex: '^((CORDA|AG|EG|ENT|INFRA|NAAS|ES)-\d+|NOTICK)(.*)'
12+
title-regex: '^((CORDA|AG|EG|ENT|INFRA|ES)-\d+|NOTICK)(.*)'
1313
on-failed-regex-comment: "PR title failed to match regex -> `%regex%`"
1414
repo-token: "${{ secrets.GITHUB_TOKEN }}"

.snyk

+2-2
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ ignore:
159159
assessment. Liquibase is used to apply the database migration changes.
160160
XML files are used here to define the changes not YAML and therefore
161161
the Corda node itself is not exposed to this deserialisation
162-
vulnerability.
162+
vulnerability.
163163
expires: 2023-07-12T17:00:51.957Z
164164
created: 2022-12-29T17:00:51.970Z
165165
SNYK-JAVA-ORGYAML-3016889:
@@ -180,7 +180,7 @@ ignore:
180180
- '*':
181181
reason: >-
182182
H2 console is not enabled for any of the applications we are running.
183-
When it comes to DB connectivity parameters, we do not allow changing
183+
When it comes to DB connectivity parameters, we do not allow changing
184184
them as they are supplied by Corda Node configuration file.
185185
expires: 2023-07-28T11:36:39.068Z
186186
created: 2022-12-29T11:36:39.089Z

client/rpc/src/main/kotlin/net/corda/client/rpc/CordaRPCClient.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package net.corda.client.rpc
22

3+
import io.netty.util.concurrent.DefaultThreadFactory
34
import net.corda.client.rpc.internal.RPCClient
45
import net.corda.client.rpc.internal.ReconnectingCordaRPCOps
56
import net.corda.client.rpc.internal.SerializationEnvironmentHelper
@@ -52,7 +53,7 @@ class CordaRPCConnection private constructor(
5253
sslConfiguration: ClientRpcSslOptions? = null,
5354
classLoader: ClassLoader? = null
5455
): CordaRPCConnection {
55-
val observersPool: ExecutorService = Executors.newCachedThreadPool()
56+
val observersPool: ExecutorService = Executors.newCachedThreadPool(DefaultThreadFactory("RPCObserver"))
5657
return CordaRPCConnection(null, observersPool, ReconnectingCordaRPCOps(
5758
addresses,
5859
username,

client/rpc/src/main/kotlin/net/corda/client/rpc/internal/ReconnectingCordaRPCOps.kt

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package net.corda.client.rpc.internal
22

3+
import io.netty.util.concurrent.DefaultThreadFactory
34
import net.corda.client.rpc.ConnectionFailureException
45
import net.corda.client.rpc.CordaRPCClient
56
import net.corda.client.rpc.CordaRPCClientConfiguration
@@ -99,7 +100,8 @@ class ReconnectingCordaRPCOps private constructor(
99100
ErrorInterceptingHandler(reconnectingRPCConnection)) as CordaRPCOps
100101
}
101102
}
102-
private val retryFlowsPool = Executors.newScheduledThreadPool(1)
103+
private val retryFlowsPool = Executors.newScheduledThreadPool(1, DefaultThreadFactory("FlowRetry"))
104+
103105
/**
104106
* This function runs a flow and retries until it completes successfully.
105107
*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package net.corda.coretests.crypto.internal
2+
3+
import net.corda.coretesting.internal.DEV_ROOT_CA
4+
import net.corda.testing.core.createCRL
5+
import org.assertj.core.api.Assertions.assertThatIllegalArgumentException
6+
import org.junit.Test
7+
8+
class ProviderMapTest {
9+
// https://github.com/corda/corda/pull/3997
10+
@Test(timeout = 300_000)
11+
fun `verify CRL algorithms`() {
12+
val crl = createCRL(
13+
issuer = DEV_ROOT_CA,
14+
revokedCerts = emptyList(),
15+
signatureAlgorithm = "SHA256withECDSA"
16+
)
17+
// This should pass.
18+
crl.verify(DEV_ROOT_CA.keyPair.public)
19+
20+
// Try changing the algorithm to EC will fail.
21+
assertThatIllegalArgumentException().isThrownBy {
22+
createCRL(
23+
issuer = DEV_ROOT_CA,
24+
revokedCerts = emptyList(),
25+
signatureAlgorithm = "EC"
26+
)
27+
}.withMessage("Unknown signature type requested: EC")
28+
}
29+
}

core/src/main/kotlin/net/corda/core/node/ServiceHub.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ interface ServicesForResolution {
6565
/**
6666
* Given a [Set] of [StateRef]'s loads the referenced transaction and looks up the specified output [ContractState].
6767
*
68-
* @throws TransactionResolutionException if [stateRef] points to a non-existent transaction.
68+
* @throws TransactionResolutionException if any of the [stateRefs] point to a non-existent transaction.
6969
*/
7070
// TODO: future implementation to use a Vault state ref -> contract state BLOB table and perform single query bulk load
7171
// as the existing transaction store will become encrypted at some point

core/src/main/kotlin/net/corda/core/node/services/VaultService.kt

+13-12
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@file:Suppress("LongParameterList")
2+
13
package net.corda.core.node.services
24

35
import co.paralleluniverse.fibers.Suspendable
@@ -197,8 +199,7 @@ class Vault<out T : ContractState>(val states: Iterable<StateAndRef<T>>) {
197199
* 4) Status types used in this query: [StateStatus.UNCONSUMED], [StateStatus.CONSUMED], [StateStatus.ALL].
198200
* 5) Other results as a [List] of any type (eg. aggregate function results with/without group by).
199201
*
200-
* Note: currently otherResults are used only for Aggregate Functions (in which case, the states and statesMetadata
201-
* results will be empty).
202+
* Note: currently [otherResults] is used only for aggregate functions (in which case, [states] and [statesMetadata] will be empty).
202203
*/
203204
@CordaSerializable
204205
data class Page<out T : ContractState>(val states: List<StateAndRef<T>>,
@@ -213,19 +214,19 @@ class Vault<out T : ContractState>(val states: Iterable<StateAndRef<T>>) {
213214
val contractStateClassName: String,
214215
val recordedTime: Instant,
215216
val consumedTime: Instant?,
216-
val status: Vault.StateStatus,
217+
val status: StateStatus,
217218
val notary: AbstractParty?,
218219
val lockId: String?,
219220
val lockUpdateTime: Instant?,
220-
val relevancyStatus: Vault.RelevancyStatus? = null,
221+
val relevancyStatus: RelevancyStatus? = null,
221222
val constraintInfo: ConstraintInfo? = null
222223
) {
223224
fun copy(
224225
ref: StateRef = this.ref,
225226
contractStateClassName: String = this.contractStateClassName,
226227
recordedTime: Instant = this.recordedTime,
227228
consumedTime: Instant? = this.consumedTime,
228-
status: Vault.StateStatus = this.status,
229+
status: StateStatus = this.status,
229230
notary: AbstractParty? = this.notary,
230231
lockId: String? = this.lockId,
231232
lockUpdateTime: Instant? = this.lockUpdateTime
@@ -237,21 +238,21 @@ class Vault<out T : ContractState>(val states: Iterable<StateAndRef<T>>) {
237238
contractStateClassName: String = this.contractStateClassName,
238239
recordedTime: Instant = this.recordedTime,
239240
consumedTime: Instant? = this.consumedTime,
240-
status: Vault.StateStatus = this.status,
241+
status: StateStatus = this.status,
241242
notary: AbstractParty? = this.notary,
242243
lockId: String? = this.lockId,
243244
lockUpdateTime: Instant? = this.lockUpdateTime,
244-
relevancyStatus: Vault.RelevancyStatus?
245+
relevancyStatus: RelevancyStatus?
245246
): StateMetadata {
246247
return StateMetadata(ref, contractStateClassName, recordedTime, consumedTime, status, notary, lockId, lockUpdateTime, relevancyStatus, ConstraintInfo(AlwaysAcceptAttachmentConstraint))
247248
}
248249
}
249250

250251
companion object {
251252
@Deprecated("No longer used. The vault does not emit empty updates")
252-
val NoUpdate = Update(emptySet(), emptySet(), type = Vault.UpdateType.GENERAL, references = emptySet())
253+
val NoUpdate = Update(emptySet(), emptySet(), type = UpdateType.GENERAL, references = emptySet())
253254
@Deprecated("No longer used. The vault does not emit empty updates")
254-
val NoNotaryUpdate = Vault.Update(emptySet(), emptySet(), type = Vault.UpdateType.NOTARY_CHANGE, references = emptySet())
255+
val NoNotaryUpdate = Update(emptySet(), emptySet(), type = UpdateType.NOTARY_CHANGE, references = emptySet())
255256
}
256257
}
257258

@@ -302,7 +303,7 @@ interface VaultService {
302303
fun whenConsumed(ref: StateRef): CordaFuture<Vault.Update<ContractState>> {
303304
val query = QueryCriteria.VaultQueryCriteria(
304305
stateRefs = listOf(ref),
305-
status = Vault.StateStatus.CONSUMED
306+
status = StateStatus.CONSUMED
306307
)
307308
val result = trackBy<ContractState>(query)
308309
val snapshot = result.snapshot.states
@@ -358,8 +359,8 @@ interface VaultService {
358359
/**
359360
* Helper function to determine spendable states and soft locking them.
360361
* Currently performance will be worse than for the hand optimised version in
361-
* [Cash.unconsumedCashStatesForSpending]. However, this is fully generic and can operate with custom [FungibleState]
362-
* and [FungibleAsset] states.
362+
* [net.corda.finance.workflows.asset.selection.AbstractCashSelection.unconsumedCashStatesForSpending]. However, this is fully generic
363+
* and can operate with custom [FungibleState] and [FungibleAsset] states.
363364
* @param lockId The [FlowLogic.runId]'s [UUID] of the current flow used to soft lock the states.
364365
* @param eligibleStatesQuery A custom query object that selects down to the appropriate subset of all states of the
365366
* [contractStateType]. e.g. by selecting on account, issuer, etc. The query is internally augmented with the

node-api-tests/src/test/kotlin/net/corda/nodeapitests/internal/crypto/X509UtilitiesTest.kt

+39-36
Original file line numberDiff line numberDiff line change
@@ -21,41 +21,47 @@ import net.corda.core.serialization.deserialize
2121
import net.corda.core.serialization.serialize
2222
import net.corda.core.utilities.days
2323
import net.corda.core.utilities.hours
24-
import net.corda.nodeapi.internal.serialization.amqp.AMQPServerSerializationScheme
25-
import net.corda.nodeapi.internal.config.MutualSslConfiguration
26-
import net.corda.nodeapi.internal.createDevNodeCa
27-
import net.corda.nodeapi.internal.crypto.X509Utilities.DEFAULT_IDENTITY_SIGNATURE_SCHEME
28-
import net.corda.nodeapi.internal.crypto.X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME
29-
import net.corda.nodeapi.internal.installDevNodeCaCertPath
30-
import net.corda.nodeapi.internal.protonwrapper.netty.init
31-
import net.corda.nodeapi.internal.registerDevP2pCertificates
32-
import net.corda.serialization.internal.AllWhitelist
33-
import net.corda.serialization.internal.SerializationContextImpl
34-
import net.corda.serialization.internal.SerializationFactoryImpl
35-
import net.corda.serialization.internal.amqp.amqpMagic
36-
import net.corda.testing.core.ALICE_NAME
37-
import net.corda.testing.core.BOB_NAME
38-
import net.corda.testing.core.TestIdentity
39-
import net.corda.testing.driver.internal.incrementalPortAllocation
4024
import net.corda.coretesting.internal.NettyTestClient
4125
import net.corda.coretesting.internal.NettyTestHandler
4226
import net.corda.coretesting.internal.NettyTestServer
43-
import net.corda.testing.internal.createDevIntermediateCaCertPath
4427
import net.corda.coretesting.internal.stubs.CertificateStoreStubs
28+
import net.corda.nodeapi.internal.config.MutualSslConfiguration
29+
import net.corda.nodeapi.internal.createDevNodeCa
4530
import net.corda.nodeapi.internal.crypto.CertificateType
4631
import net.corda.nodeapi.internal.crypto.X509CertificateFactory
4732
import net.corda.nodeapi.internal.crypto.X509Utilities
33+
import net.corda.nodeapi.internal.crypto.X509Utilities.DEFAULT_IDENTITY_SIGNATURE_SCHEME
34+
import net.corda.nodeapi.internal.crypto.X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME
4835
import net.corda.nodeapi.internal.crypto.checkValidity
4936
import net.corda.nodeapi.internal.crypto.getSupportedKey
5037
import net.corda.nodeapi.internal.crypto.loadOrCreateKeyStore
5138
import net.corda.nodeapi.internal.crypto.save
5239
import net.corda.nodeapi.internal.crypto.toBc
5340
import net.corda.nodeapi.internal.crypto.x509
5441
import net.corda.nodeapi.internal.crypto.x509Certificates
42+
import net.corda.nodeapi.internal.installDevNodeCaCertPath
43+
import net.corda.nodeapi.internal.protonwrapper.netty.keyManagerFactory
44+
import net.corda.nodeapi.internal.protonwrapper.netty.trustManagerFactory
45+
import net.corda.nodeapi.internal.registerDevP2pCertificates
46+
import net.corda.nodeapi.internal.serialization.amqp.AMQPServerSerializationScheme
47+
import net.corda.serialization.internal.AllWhitelist
48+
import net.corda.serialization.internal.SerializationContextImpl
49+
import net.corda.serialization.internal.SerializationFactoryImpl
50+
import net.corda.serialization.internal.amqp.amqpMagic
51+
import net.corda.testing.core.ALICE_NAME
52+
import net.corda.testing.core.BOB_NAME
53+
import net.corda.testing.core.TestIdentity
54+
import net.corda.testing.driver.internal.incrementalPortAllocation
5555
import net.corda.testing.internal.IS_OPENJ9
56+
import net.corda.testing.internal.createDevIntermediateCaCertPath
5657
import net.i2p.crypto.eddsa.EdDSAPrivateKey
5758
import org.assertj.core.api.Assertions.assertThat
58-
import org.bouncycastle.asn1.x509.*
59+
import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier
60+
import org.bouncycastle.asn1.x509.BasicConstraints
61+
import org.bouncycastle.asn1.x509.CRLDistPoint
62+
import org.bouncycastle.asn1.x509.Extension
63+
import org.bouncycastle.asn1.x509.KeyUsage
64+
import org.bouncycastle.asn1.x509.SubjectKeyIdentifier
5965
import org.bouncycastle.jcajce.provider.asymmetric.edec.BCEdDSAPrivateKey
6066
import org.bouncycastle.pqc.jcajce.provider.sphincs.BCSphincs256PrivateKey
6167
import org.junit.Assume
@@ -74,10 +80,19 @@ import java.security.PrivateKey
7480
import java.security.cert.CertPath
7581
import java.security.cert.X509Certificate
7682
import java.util.*
77-
import javax.net.ssl.*
83+
import javax.net.ssl.SSLContext
84+
import javax.net.ssl.SSLParameters
85+
import javax.net.ssl.SSLServerSocket
86+
import javax.net.ssl.SSLSocket
7887
import javax.security.auth.x500.X500Principal
7988
import kotlin.concurrent.thread
80-
import kotlin.test.*
89+
import kotlin.test.assertEquals
90+
import kotlin.test.assertFailsWith
91+
import kotlin.test.assertFalse
92+
import kotlin.test.assertNotNull
93+
import kotlin.test.assertNull
94+
import kotlin.test.assertTrue
95+
import kotlin.test.fail
8196

8297
class X509UtilitiesTest {
8398
private companion object {
@@ -295,15 +310,10 @@ class X509UtilitiesTest {
295310
sslConfig.keyStore.get(true).registerDevP2pCertificates(MEGA_CORP.name, rootCa.certificate, intermediateCa)
296311
sslConfig.createTrustStore(rootCa.certificate)
297312

298-
val keyStore = sslConfig.keyStore.get()
299-
val trustStore = sslConfig.trustStore.get()
300-
301313
val context = SSLContext.getInstance("TLS")
302-
val keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
303-
keyManagerFactory.init(keyStore)
314+
val keyManagerFactory = keyManagerFactory(sslConfig.keyStore.get())
304315
val keyManagers = keyManagerFactory.keyManagers
305-
val trustMgrFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
306-
trustMgrFactory.init(trustStore)
316+
val trustMgrFactory = trustManagerFactory(sslConfig.trustStore.get())
307317
val trustManagers = trustMgrFactory.trustManagers
308318
context.init(keyManagers, trustManagers, newSecureRandom())
309319

@@ -388,15 +398,8 @@ class X509UtilitiesTest {
388398
sslConfig.keyStore.get(true).registerDevP2pCertificates(MEGA_CORP.name, rootCa.certificate, intermediateCa)
389399
sslConfig.createTrustStore(rootCa.certificate)
390400

391-
val keyStore = sslConfig.keyStore.get()
392-
val trustStore = sslConfig.trustStore.get()
393-
394-
val keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
395-
keyManagerFactory.init(keyStore)
396-
397-
val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
398-
trustManagerFactory.init(trustStore)
399-
401+
val keyManagerFactory = keyManagerFactory(sslConfig.keyStore.get())
402+
val trustManagerFactory = trustManagerFactory(sslConfig.trustStore.get())
400403

401404
val sslServerContext = SslContextBuilder
402405
.forServer(keyManagerFactory)

node-api/src/main/kotlin/net/corda/nodeapi/internal/ArtemisMessagingClient.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ class ArtemisMessagingClient(private val config: MutualSslConfiguration,
4242
override fun start(): Started = synchronized(this) {
4343
check(started == null) { "start can't be called twice" }
4444
val tcpTransport = p2pConnectorTcpTransport(serverAddress, config, threadPoolName = threadPoolName, trace = trace)
45-
val backupTransports = backupServerAddressPool.map {
46-
p2pConnectorTcpTransport(it, config, threadPoolName = threadPoolName, trace = trace)
45+
val backupTransports = backupServerAddressPool.mapIndexed { index, address ->
46+
p2pConnectorTcpTransport(address, config, threadPoolName = "$threadPoolName-backup${index+1}", trace = trace)
4747
}
4848

4949
log.info("Connecting to message broker: $serverAddress")

0 commit comments

Comments
 (0)