diff --git a/client/rpc/src/main/kotlin/net/corda/client/rpc/internal/RPCClientProxyHandler.kt b/client/rpc/src/main/kotlin/net/corda/client/rpc/internal/RPCClientProxyHandler.kt index 98a9e221ff..47a20df007 100644 --- a/client/rpc/src/main/kotlin/net/corda/client/rpc/internal/RPCClientProxyHandler.kt +++ b/client/rpc/src/main/kotlin/net/corda/client/rpc/internal/RPCClientProxyHandler.kt @@ -19,6 +19,7 @@ import net.corda.core.messaging.RPCOps import net.corda.core.serialization.SerializationContext import net.corda.core.utilities.* import net.corda.nodeapi.* +import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration import org.apache.activemq.artemis.api.core.SimpleString import org.apache.activemq.artemis.api.core.client.ActiveMQClient.DEFAULT_ACK_BATCH_SIZE import org.apache.activemq.artemis.api.core.client.ClientMessage @@ -164,7 +165,7 @@ class RPCClientProxyHandler( TimeUnit.MILLISECONDS ) sessionAndProducerPool.run { - it.session.createTemporaryQueue(clientAddress, clientAddress) + it.session.createTemporaryQueue(clientAddress, ActiveMQDefaultConfiguration.getDefaultRoutingType(), clientAddress) } val sessionFactory = serverLocator.createSessionFactory() val session = sessionFactory.createSession(rpcUsername, rpcPassword, false, true, true, false, DEFAULT_ACK_BATCH_SIZE) diff --git a/client/rpc/src/smoke-test/java/net/corda/java/rpc/StandaloneCordaRPCJavaClientTest.java b/client/rpc/src/smoke-test/java/net/corda/java/rpc/StandaloneCordaRPCJavaClientTest.java index 4d5a250ef6..6c18e31053 100644 --- a/client/rpc/src/smoke-test/java/net/corda/java/rpc/StandaloneCordaRPCJavaClientTest.java +++ b/client/rpc/src/smoke-test/java/net/corda/java/rpc/StandaloneCordaRPCJavaClientTest.java @@ -65,8 +65,8 @@ public class StandaloneCordaRPCJavaClientTest { } private NodeInfo fetchNotaryIdentity() { - DataFeed, NetworkMapCache.MapChange> nodeDataFeed = rpcProxy.networkMapFeed(); - return nodeDataFeed.getSnapshot().get(0); + List nodeDataSnapshot = rpcProxy.networkMapSnapshot(); + return nodeDataSnapshot.get(0); } @Test diff --git a/client/rpc/src/smoke-test/kotlin/net/corda/kotlin/rpc/StandaloneCordaRPClientTest.kt b/client/rpc/src/smoke-test/kotlin/net/corda/kotlin/rpc/StandaloneCordaRPClientTest.kt index f26ea31ff8..064db6fc7d 100644 --- a/client/rpc/src/smoke-test/kotlin/net/corda/kotlin/rpc/StandaloneCordaRPClientTest.kt +++ b/client/rpc/src/smoke-test/kotlin/net/corda/kotlin/rpc/StandaloneCordaRPClientTest.kt @@ -202,8 +202,7 @@ class StandaloneCordaRPClientTest { } private fun fetchNotaryIdentity(): NodeInfo { - val (nodeInfo, nodeUpdates) = rpcProxy.networkMapFeed() - nodeUpdates.notUsed() + val nodeInfo = rpcProxy.networkMapSnapshot() assertEquals(1, nodeInfo.size) return nodeInfo[0] } diff --git a/core/src/main/kotlin/net/corda/core/flows/CollectSignaturesFlow.kt b/core/src/main/kotlin/net/corda/core/flows/CollectSignaturesFlow.kt index 6d9a2d1b8e..390f5aaec1 100644 --- a/core/src/main/kotlin/net/corda/core/flows/CollectSignaturesFlow.kt +++ b/core/src/main/kotlin/net/corda/core/flows/CollectSignaturesFlow.kt @@ -49,7 +49,7 @@ import java.security.PublicKey * builder.toWireTransaction().toLedgerTransaction(serviceHub).verify() * * // Transaction creator signs transaction. - * val ptx = builder.signWith(serviceHub.legalIdentityKey).toSignedTransaction(false) + * val ptx = serviceHub.signInitialTransaction(builder) * * // Call to CollectSignaturesFlow. * // The returned signed transaction will have all signatures appended apart from the notary's. @@ -58,7 +58,7 @@ import java.security.PublicKey * @param partiallySignedTx Transaction to collect the remaining signatures for */ // TODO: AbstractStateReplacementFlow needs updating to use this flow. -// TODO: Update this flow to handle randomly generated keys when that works is complete. +// TODO: Update this flow to handle randomly generated keys when that work is complete. class CollectSignaturesFlow(val partiallySignedTx: SignedTransaction, override val progressTracker: ProgressTracker = CollectSignaturesFlow.tracker()) : FlowLogic() { diff --git a/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt b/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt index 84e30e9140..601e8c6b11 100644 --- a/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt +++ b/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt @@ -60,6 +60,11 @@ interface CordaRPCOps : RPCOps { */ override val protocolVersion: Int get() = nodeIdentity().platformVersion + /** + * Returns a list of currently in-progress state machine infos. + */ + fun stateMachinesSnapshot(): List + /** * Returns a data feed of currently in-progress state machine infos and an observable of future state machine adds/removes. */ @@ -151,12 +156,22 @@ interface CordaRPCOps : RPCOps { } // DOCEND VaultTrackAPIHelpers + /** + * Returns a list of all recorded transactions. + */ + fun verifiedTransactionsSnapshot(): List + /** * Returns a data feed of all recorded transactions and an observable of future recorded ones. */ @RPCReturnsObservables fun verifiedTransactionsFeed(): DataFeed, SignedTransaction> + /** + * Returns a snapshot list of existing state machine id - recorded transaction hash mappings. + */ + fun stateMachineRecordedTransactionMappingSnapshot(): List + /** * Returns a snapshot list of existing state machine id - recorded transaction hash mappings, and a stream of future * such mappings as well. @@ -164,6 +179,11 @@ interface CordaRPCOps : RPCOps { @RPCReturnsObservables fun stateMachineRecordedTransactionMappingFeed(): DataFeed, StateMachineTransactionMapping> + /** + * Returns all parties currently visible on the network with their advertised services. + */ + fun networkMapSnapshot(): List + /** * Returns all parties currently visible on the network with their advertised services and an observable of future updates to the network. */ diff --git a/core/src/main/kotlin/net/corda/core/node/services/IdentityService.kt b/core/src/main/kotlin/net/corda/core/node/services/IdentityService.kt index 18084c66d9..008d114ebc 100644 --- a/core/src/main/kotlin/net/corda/core/node/services/IdentityService.kt +++ b/core/src/main/kotlin/net/corda/core/node/services/IdentityService.kt @@ -16,6 +16,7 @@ import java.security.cert.* interface IdentityService { val trustRoot: X509Certificate val trustRootHolder: X509CertificateHolder + val trustAnchor: TrustAnchor val caCertStore: CertStore /** @@ -31,11 +32,12 @@ interface IdentityService { /** * Verify and then store an identity. * - * @param identity a party representing a legal entity and the certificate path linking them to the network trust root. + * @param identity a party and the certificate path linking them to the network trust root. + * @return the issuing entity, if known. * @throws IllegalArgumentException if the certificate path is invalid. */ @Throws(CertificateExpiredException::class, CertificateNotYetValidException::class, InvalidAlgorithmParameterException::class) - fun verifyAndRegisterIdentity(identity: PartyAndCertificate) + fun verifyAndRegisterIdentity(identity: PartyAndCertificate): PartyAndCertificate? /** * Asserts that an anonymous party maps to the given full party, by looking up the certificate chain associated with @@ -62,9 +64,11 @@ interface IdentityService { /** * Get the certificate and path for a well known identity. * - * @return the party and certificate, or null if unknown. + * @return the party and certificate. + * @throws IllegalArgumentException if the certificate and path are unknown. This should never happen for a well + * known identity. */ - fun certificateFromParty(party: Party): PartyAndCertificate? + fun certificateFromParty(party: Party): PartyAndCertificate // There is no method for removing identities, as once we are made aware of a Party we want to keep track of them // indefinitely. It may be that in the long term we need to drop or archive very old Party information for space, diff --git a/docs/source/example-code/build.gradle b/docs/source/example-code/build.gradle index fe708b84ad..215bd08b61 100644 --- a/docs/source/example-code/build.gradle +++ b/docs/source/example-code/build.gradle @@ -33,9 +33,9 @@ sourceSets { compileTestJava.dependsOn tasks.getByPath(':node:capsule:buildCordaJAR') dependencies { - compile project(':core') - compile project(':client:jfx') - compile project(':test-utils') + cordaCompile project(':core') + cordaCompile project(':client:jfx') + cordaCompile project(':test-utils') testCompile project(':verifier') compile "org.graphstream:gs-core:1.3" @@ -43,8 +43,8 @@ dependencies { exclude group: "bouncycastle" } - compile project(path: ":node:capsule", configuration: 'runtimeArtifacts') - compile project(path: ":webserver:webcapsule", configuration: 'runtimeArtifacts') + cordaCompile project(path: ":node:capsule", configuration: 'runtimeArtifacts') + cordaCompile project(path: ":webserver:webcapsule", configuration: 'runtimeArtifacts') } mainClassName = "net.corda.docs.ClientRpcTutorialKt" diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt index ddf115389d..fe2255b3e7 100644 --- a/docs/source/example-code/src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt +++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt @@ -112,8 +112,7 @@ fun generateTransactions(proxy: CordaRPCOps) { sum + state.state.data.amount.quantity } val issueRef = OpaqueBytes.of(0) - val (parties, partyUpdates) = proxy.networkMapFeed() - partyUpdates.notUsed() + val parties = proxy.networkMapSnapshot() val notary = parties.first { it.advertisedServices.any { it.info.type.isNotary() } }.notaryIdentity val me = proxy.nodeIdentity().legalIdentity while (true) { diff --git a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt index 71848d1616..2206df75ba 100644 --- a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt @@ -67,6 +67,7 @@ import net.corda.node.utilities.* import net.corda.node.utilities.AddOrRemove.ADD import org.apache.activemq.artemis.utils.ReusableLatch import org.bouncycastle.asn1.x500.X500Name +import org.bouncycastle.cert.X509CertificateHolder import org.slf4j.Logger import rx.Observable import java.io.IOException @@ -298,7 +299,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, .map { (initiatingFlow, initiatedFlows) -> val sorted = initiatedFlows.sortedWith(FlowTypeHierarchyComparator(initiatingFlow)) if (sorted.size > 1) { - log.warn("${initiatingFlow.name} has been specified as the inititating flow by multiple flows " + + log.warn("${initiatingFlow.name} has been specified as the initiating flow by multiple flows " + "in the same type hierarchy: ${sorted.joinToString { it.name }}. Choosing the most " + "specific sub-type for registration: ${sorted[0].name}.") } @@ -657,11 +658,11 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, .filterNotNull() .toTypedArray() val service = InMemoryIdentityService(setOf(info.legalIdentityAndCert), trustRoot = trustRoot, caCertificates = *caCertificates) - services.networkMapCache.partyNodes.forEach { service.registerIdentity(it.legalIdentityAndCert) } + services.networkMapCache.partyNodes.forEach { service.verifyAndRegisterIdentity(it.legalIdentityAndCert) } services.networkMapCache.changed.subscribe { mapChange -> // TODO how should we handle network map removal if (mapChange is MapChange.Added) { - service.registerIdentity(mapChange.node.legalIdentityAndCert) + service.verifyAndRegisterIdentity(mapChange.node.legalIdentityAndCert) } } return service @@ -718,24 +719,26 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, } } - val (cert, keyPair) = keyStore.certificateAndKeyPair(privateKeyAlias) - + val (cert, keys) = keyStore.certificateAndKeyPair(privateKeyAlias) // Get keys from keystore. val loadedServiceName = cert.subject if (loadedServiceName != serviceName) throw ConfigurationException("The legal name in the config file doesn't match the stored identity keystore:$serviceName vs $loadedServiceName") - val certPath = CertificateFactory.getInstance("X509").generateCertPath(keyStore.getCertificateChain(privateKeyAlias).toList()) // Use composite key instead if exists // TODO: Use configuration to indicate composite key should be used instead of public key for the identity. - val publicKey = if (keyStore.containsAlias(compositeKeyAlias)) { - Crypto.toSupportedPublicKey(keyStore.getCertificate(compositeKeyAlias).publicKey) + val (keyPair, certs) = if (keyStore.containsAlias(compositeKeyAlias)) { + val compositeKey = Crypto.toSupportedPublicKey(keyStore.getCertificate(compositeKeyAlias).publicKey) + val compositeKeyCert = keyStore.getCertificate(compositeKeyAlias) + // We have to create the certificate chain for the composite key manually, this is because in order to store + // the chain in keystore we need a private key, however there are no corresponding private key for composite key. + Pair(KeyPair(compositeKey, keys.private), listOf(compositeKeyCert, *keyStore.getCertificateChain(X509Utilities.CORDA_CLIENT_CA))) } else { - keyPair.public + Pair(keys, keyStore.getCertificateChain(privateKeyAlias).toList()) } - - partyKeys += keyPair - return Pair(PartyAndCertificate(loadedServiceName, publicKey, cert, certPath), keyPair) + val certPath = CertificateFactory.getInstance("X509").generateCertPath(certs) + partyKeys += keys + return Pair(PartyAndCertificate(loadedServiceName, keyPair.public, X509CertificateHolder(certs.first().encoded), certPath), keyPair) } private fun migrateKeysFromFile(keyStore: KeyStoreWrapper, serviceName: X500Name, diff --git a/node/src/main/kotlin/net/corda/node/internal/CordaRPCOpsImpl.kt b/node/src/main/kotlin/net/corda/node/internal/CordaRPCOpsImpl.kt index d934483095..8b604c0940 100644 --- a/node/src/main/kotlin/net/corda/node/internal/CordaRPCOpsImpl.kt +++ b/node/src/main/kotlin/net/corda/node/internal/CordaRPCOpsImpl.kt @@ -1,5 +1,6 @@ package net.corda.node.internal +import net.corda.client.rpc.notUsed import net.corda.core.contracts.ContractState import net.corda.core.contracts.StateAndRef import net.corda.core.contracts.UpgradedContract @@ -39,6 +40,12 @@ class CordaRPCOpsImpl( private val smm: StateMachineManager, private val database: CordaPersistence ) : CordaRPCOps { + override fun networkMapSnapshot(): List { + val (snapshot, updates) = networkMapFeed() + updates.notUsed() + return snapshot + } + override fun networkMapFeed(): DataFeed, NetworkMapCache.MapChange> { return database.transaction { services.networkMapCache.track() @@ -64,12 +71,24 @@ class CordaRPCOpsImpl( } } + override fun verifiedTransactionsSnapshot(): List { + val (snapshot, updates) = verifiedTransactionsFeed() + updates.notUsed() + return snapshot + } + override fun verifiedTransactionsFeed(): DataFeed, SignedTransaction> { return database.transaction { services.validatedTransactions.track() } } + override fun stateMachinesSnapshot(): List { + val (snapshot, updates) = stateMachinesFeed() + updates.notUsed() + return snapshot + } + override fun stateMachinesFeed(): DataFeed, StateMachineUpdate> { return database.transaction { val (allStateMachines, changes) = smm.track() @@ -80,6 +99,12 @@ class CordaRPCOpsImpl( } } + override fun stateMachineRecordedTransactionMappingSnapshot(): List { + val (snapshot, updates) = stateMachineRecordedTransactionMappingFeed() + updates.notUsed() + return snapshot + } + override fun stateMachineRecordedTransactionMappingFeed(): DataFeed, StateMachineTransactionMapping> { return database.transaction { services.stateMachineRecordedTransactionMapping.track() diff --git a/node/src/main/kotlin/net/corda/node/internal/Node.kt b/node/src/main/kotlin/net/corda/node/internal/Node.kt index a59560cf3b..fbe201cb4f 100644 --- a/node/src/main/kotlin/net/corda/node/internal/Node.kt +++ b/node/src/main/kotlin/net/corda/node/internal/Node.kt @@ -24,6 +24,7 @@ import net.corda.node.services.messaging.MessagingService import net.corda.node.services.messaging.NodeMessagingClient import net.corda.node.utilities.AddressUtils import net.corda.node.utilities.AffinityExecutor +import net.corda.node.utilities.TestClock import net.corda.nodeapi.ArtemisMessagingComponent import net.corda.nodeapi.ArtemisMessagingComponent.Companion.IP_REQUEST_PREFIX import net.corda.nodeapi.ArtemisMessagingComponent.Companion.PEER_USER @@ -58,8 +59,8 @@ import kotlin.system.exitProcess open class Node(override val configuration: FullNodeConfiguration, advertisedServices: Set, val versionInfo: VersionInfo, - clock: Clock = NodeClock(), - val initialiseSerialization: Boolean = true) : AbstractNode(configuration, advertisedServices, clock) { + val initialiseSerialization: Boolean = true +) : AbstractNode(configuration, advertisedServices, createClock(configuration)) { companion object { private val logger = loggerFor() var renderBasicInfoToConsole = true @@ -76,6 +77,10 @@ open class Node(override val configuration: FullNodeConfiguration, println("Corda will now exit...") exitProcess(1) } + + private fun createClock(configuration: FullNodeConfiguration): Clock { + return if (configuration.useTestClock) TestClock() else NodeClock() + } } override val log: Logger get() = logger diff --git a/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt b/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt index eab65b579a..68e9292e3a 100644 --- a/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt +++ b/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt @@ -97,7 +97,7 @@ open class NodeStartup(val args: Array) { open protected fun preNetworkRegistration(conf: FullNodeConfiguration) = Unit open protected fun createNode(conf: FullNodeConfiguration, versionInfo: VersionInfo, services: Set): Node { - return Node(conf, services, versionInfo, if (conf.useTestClock) TestClock() else NodeClock()) + return Node(conf, services, versionInfo) } open protected fun startNode(conf: FullNodeConfiguration, versionInfo: VersionInfo, startTime: Long, cmdlineOptions: CmdLineOptions) { diff --git a/node/src/main/kotlin/net/corda/node/services/identity/InMemoryIdentityService.kt b/node/src/main/kotlin/net/corda/node/services/identity/InMemoryIdentityService.kt index ff786afd95..a19ae3698a 100644 --- a/node/src/main/kotlin/net/corda/node/services/identity/InMemoryIdentityService.kt +++ b/node/src/main/kotlin/net/corda/node/services/identity/InMemoryIdentityService.kt @@ -44,9 +44,8 @@ class InMemoryIdentityService(identities: Iterable = emptyS */ override val caCertStore: CertStore override val trustRootHolder = X509CertificateHolder(trustRoot.encoded) - private val trustAnchor: TrustAnchor = TrustAnchor(trustRoot, null) + override val trustAnchor: TrustAnchor = TrustAnchor(trustRoot, null) private val keyToParties = ConcurrentHashMap() - private val keyToIssuingParty = ConcurrentHashMap() private val principalToParties = ConcurrentHashMap() init { @@ -56,16 +55,17 @@ class InMemoryIdentityService(identities: Iterable = emptyS principalToParties.putAll(identities.associateBy { it.name }) confidentialIdentities.forEach { identity -> require(identity.certPath.certificates.size >= 2) { "Certificate path must at least include subject and issuing certificates" } - keyToIssuingParty[identity.owningKey] = keyToParties[identity.certPath.certificates[1].publicKey]!! principalToParties.computeIfAbsent(identity.name) { identity } } } - override fun registerIdentity(party: PartyAndCertificate) = verifyAndRegisterIdentity(party) + override fun registerIdentity(party: PartyAndCertificate) { + verifyAndRegisterIdentity(party) + } // TODO: Check the certificate validation logic @Throws(CertificateExpiredException::class, CertificateNotYetValidException::class, InvalidAlgorithmParameterException::class) - override fun verifyAndRegisterIdentity(identity: PartyAndCertificate) { + override fun verifyAndRegisterIdentity(identity: PartyAndCertificate): PartyAndCertificate? { require(identity.certPath.certificates.size >= 2) { "Certificate path must at least include subject and issuing certificates" } // Validate the chain first, before we do anything clever with it identity.verify(trustAnchor) @@ -74,25 +74,32 @@ class InMemoryIdentityService(identities: Iterable = emptyS require(Arrays.equals(identity.certificate.subjectPublicKeyInfo.encoded, identity.owningKey.encoded)) { "Party certificate must end with party's public key" } keyToParties[identity.owningKey] = identity - // TODO: This map should only be deanonymised parties, not all issuers, but we have no good way of checking for - // confidential vs anonymous identities - val issuer = keyToParties[identity.certPath.certificates[1].publicKey] - if (issuer != null) { - keyToIssuingParty[identity.owningKey] = issuer - } // Always keep the first party we registered, as that's the well known identity principalToParties.computeIfAbsent(identity.name) { identity } + return keyToParties[identity.certPath.certificates[1].publicKey] } override fun certificateFromKey(owningKey: PublicKey): PartyAndCertificate? = keyToParties[owningKey] - override fun certificateFromParty(party: Party): PartyAndCertificate? = principalToParties[party.name] + override fun certificateFromParty(party: Party): PartyAndCertificate = principalToParties[party.name] ?: throw IllegalArgumentException("Unknown identity ${party.name}") // We give the caller a copy of the data set to avoid any locking problems override fun getAllIdentities(): Iterable = java.util.ArrayList(keyToParties.values) override fun partyFromKey(key: PublicKey): Party? = keyToParties[key]?.party override fun partyFromX500Name(principal: X500Name): Party? = principalToParties[principal]?.party - override fun partyFromAnonymous(party: AbstractParty) = party as? Party ?: keyToIssuingParty[party.owningKey]?.party + override fun partyFromAnonymous(party: AbstractParty): Party? { + // Expand the anonymous party to a full party (i.e. has a name) if possible + val candidate = party as? Party ?: keyToParties[party.owningKey]?.party + // TODO: This should be done via the network map cache, which is the authoritative source of well known identities + // Look up the well known identity for that name + return if (candidate != null) { + // If we have a well known identity by that name, use it in preference to the candidate. Otherwise default + // back to the candidate. + principalToParties[candidate.name]?.party ?: candidate + } else { + null + } + } override fun partyFromAnonymous(partyRef: PartyAndReference) = partyFromAnonymous(partyRef.party) override fun requirePartyFromAnonymous(party: AbstractParty): Party { return partyFromAnonymous(party) ?: throw IllegalStateException("Could not deanonymise party ${party.owningKey.toStringShort()}") diff --git a/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt b/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt index f86adff8c3..8f415beb52 100644 --- a/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt +++ b/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt @@ -200,8 +200,8 @@ class TwoPartyTradeFlowTests { val cashIssuer = bankNode.info.legalIdentity.ref(1) val cpIssuer = bankNode.info.legalIdentity.ref(1, 2, 3) - aliceNode.services.identityService.registerIdentity(bobNode.info.legalIdentityAndCert) - bobNode.services.identityService.registerIdentity(aliceNode.info.legalIdentityAndCert) + aliceNode.services.identityService.verifyAndRegisterIdentity(bobNode.info.legalIdentityAndCert) + bobNode.services.identityService.verifyAndRegisterIdentity(aliceNode.info.legalIdentityAndCert) aliceNode.disableDBCloseOnStop() bobNode.disableDBCloseOnStop() diff --git a/samples/irs-demo/src/integration-test/kotlin/net/corda/irs/IRSDemoTest.kt b/samples/irs-demo/src/integration-test/kotlin/net/corda/irs/IRSDemoTest.kt index 309490c07d..dc4c021c4b 100644 --- a/samples/irs-demo/src/integration-test/kotlin/net/corda/irs/IRSDemoTest.kt +++ b/samples/irs-demo/src/integration-test/kotlin/net/corda/irs/IRSDemoTest.kt @@ -7,6 +7,7 @@ import net.corda.core.toFuture import net.corda.core.internal.concurrent.transpose import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.getOrThrow +import net.corda.core.utilities.loggerFor import net.corda.core.utilities.seconds import net.corda.irs.api.NodeInterestRates import net.corda.irs.contract.InterestRateSwap @@ -29,6 +30,11 @@ import java.time.Duration import java.time.LocalDate class IRSDemoTest : IntegrationTestCategory { + + companion object { + val log = loggerFor() + } + val rpcUser = User("user", "password", emptySet()) val currentDate: LocalDate = LocalDate.now() val futureDate: LocalDate = currentDate.plusMonths(6) @@ -43,7 +49,7 @@ class IRSDemoTest : IntegrationTestCategory { startNode(DUMMY_BANK_B.name) ).transpose().getOrThrow() - println("All nodes started") + log.info("All nodes started") val (controllerAddr, nodeAAddr, nodeBAddr) = listOf( startWebserver(controller), @@ -51,7 +57,7 @@ class IRSDemoTest : IntegrationTestCategory { startWebserver(nodeB) ).transpose().getOrThrow().map { it.listenAddress } - println("All webservers started") + log.info("All webservers started") val (_, nodeAApi, nodeBApi) = listOf(controller, nodeA, nodeB).zip(listOf(controllerAddr, nodeAAddr, nodeBAddr)).map { val mapper = net.corda.jackson.JacksonSupport.createDefaultMapper(it.first.rpc) @@ -85,25 +91,25 @@ class IRSDemoTest : IntegrationTestCategory { val vaultUpdates = proxy.vaultTrackBy().updates return vaultUpdates.map { update -> - val irsStates = update.produced.map { it.state.data }.filterIsInstance() + val irsStates = update.produced.map { it.state.data } irsStates.mapNotNull { it.calculation.nextFixingDate() }.max() }.cache() } private fun runDateChange(nodeApi: HttpApi) { - println("Running date change against ${nodeApi.root}") + log.info("Running date change against ${nodeApi.root}") assertThat(nodeApi.putJson("demodate", "\"$futureDate\"")).isTrue() } private fun runTrade(nodeApi: HttpApi) { - println("Running trade against ${nodeApi.root}") + log.info("Running trade against ${nodeApi.root}") val fileContents = loadResourceFile("net/corda/irs/simulation/example-irs-trade.json") val tradeFile = fileContents.replace("tradeXXX", "trade1") assertThat(nodeApi.postJson("deals", tradeFile)).isTrue() } private fun runUploadRates(host: NetworkHostAndPort) { - println("Running upload rates against $host") + log.info("Running upload rates against $host") val fileContents = loadResourceFile("net/corda/irs/simulation/example.rates.txt") val url = URL("http://$host/api/irs/fixes") assertThat(uploadFile(url, fileContents)).isTrue() @@ -114,13 +120,13 @@ class IRSDemoTest : IntegrationTestCategory { } private fun getTradeCount(nodeApi: HttpApi): Int { - println("Getting trade count from ${nodeApi.root}") + log.info("Getting trade count from ${nodeApi.root}") val deals = nodeApi.getJson>("deals") return deals.size } private fun getTrades(nodeApi: HttpApi): Array { - println("Getting trades from ${nodeApi.root}") + log.info("Getting trades from ${nodeApi.root}") val deals = nodeApi.getJson>("deals") return deals } diff --git a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/Notarise.kt b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/Notarise.kt index 8c7d7afd61..d648ce6d71 100644 --- a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/Notarise.kt +++ b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/Notarise.kt @@ -27,15 +27,13 @@ fun main(args: Array) { /** Interface for using the notary demo API from a client. */ private class NotaryDemoClientApi(val rpc: CordaRPCOps) { private val notary by lazy { - val (parties, partyUpdates) = rpc.networkMapFeed() - partyUpdates.notUsed() + val parties = rpc.networkMapSnapshot() val id = parties.stream().filter { it.advertisedServices.any { it.info.type.isNotary() } }.map { it.notaryIdentity }.distinct().asSequence().singleOrNull() checkNotNull(id) { "No unique notary identity, try cleaning the node directories." } } private val counterpartyNode by lazy { - val (parties, partyUpdates) = rpc.networkMapFeed() - partyUpdates.notUsed() + val parties = rpc.networkMapSnapshot() parties.single { it.legalIdentity.name == BOB.name } } diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/PortfolioApi.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/PortfolioApi.kt index 001f57261f..2dcb81f3fb 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/PortfolioApi.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/PortfolioApi.kt @@ -253,8 +253,7 @@ class PortfolioApi(val rpc: CordaRPCOps) { @Path("whoami") @Produces(MediaType.APPLICATION_JSON) fun getWhoAmI(): AvailableParties { - val (parties, partyUpdates) = rpc.networkMapFeed() - partyUpdates.notUsed() + val parties = rpc.networkMapSnapshot() val counterParties = parties.filterNot { it.advertisedServices.any { it.info.type in setOf(ServiceType.networkMap, ServiceType.notary) } || it.legalIdentity == ownParty diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/OGTrade.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/OGTrade.kt index 9d6cfa56d9..1e7b788be6 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/OGTrade.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/OGTrade.kt @@ -13,7 +13,7 @@ data class OGTrade(override val legalContractReference: SecureHash = SecureHash. requireNotNull(tx.timeWindow) { "must have a time-window" } val groups: List> = tx.groupStates { state -> state.linearId } var atLeastOneCommandProcessed = false - for ((inputs, outputs, key) in groups) { + for ((inputs, outputs, _) in groups) { val command = tx.commands.select().firstOrNull() if (command != null) { require(inputs.isEmpty()) { "Inputs must be empty" } diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/PortfolioSwap.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/PortfolioSwap.kt index d417111e7d..38aa7a8acb 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/PortfolioSwap.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/PortfolioSwap.kt @@ -13,7 +13,7 @@ data class PortfolioSwap(override val legalContractReference: SecureHash = Secur override fun verify(tx: LedgerTransaction) { requireNotNull(tx.timeWindow) { "must have a time-window)" } val groups: List> = tx.groupStates { state -> state.linearId } - for ((inputs, outputs, key) in groups) { + for ((inputs, outputs, _) in groups) { val agreeCommand = tx.commands.select().firstOrNull() if (agreeCommand != null) { requireThat { diff --git a/test-utils/src/main/kotlin/net/corda/testing/driver/Driver.kt b/test-utils/src/main/kotlin/net/corda/testing/driver/Driver.kt index 3a14d967e0..44f3ad88e3 100644 --- a/test-utils/src/main/kotlin/net/corda/testing/driver/Driver.kt +++ b/test-utils/src/main/kotlin/net/corda/testing/driver/Driver.kt @@ -772,9 +772,8 @@ class DriverDSL( log.info("Starting in-process Node ${nodeConf.myLegalName.commonName}") // Write node.conf writeConfig(nodeConf.baseDirectory, "node.conf", config) - val clock: Clock = if (nodeConf.useTestClock) TestClock() else NodeClock() // TODO pass the version in? - val node = Node(nodeConf, nodeConf.calculateServices(), MOCK_VERSION_INFO, clock, initialiseSerialization = false) + val node = Node(nodeConf, nodeConf.calculateServices(), MOCK_VERSION_INFO, initialiseSerialization = false) node.start() val nodeThread = thread(name = nodeConf.myLegalName.commonName) { node.run() diff --git a/test-utils/src/main/kotlin/net/corda/testing/node/MockNode.kt b/test-utils/src/main/kotlin/net/corda/testing/node/MockNode.kt index addd075e7e..af092dd5f0 100644 --- a/test-utils/src/main/kotlin/net/corda/testing/node/MockNode.kt +++ b/test-utils/src/main/kotlin/net/corda/testing/node/MockNode.kt @@ -356,7 +356,7 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false, nodes += createPartyNode(mapAddress) } nodes.forEach { itNode -> - nodes.map { it.info.legalIdentityAndCert }.forEach(itNode.services.identityService::verifyAndRegisterIdentity) + nodes.map { it.info.legalIdentityAndCert }.map(itNode.services.identityService::verifyAndRegisterIdentity) } return BasketOfNodes(nodes, notaryNode, mapNode) } diff --git a/test-utils/src/main/kotlin/net/corda/testing/node/NodeBasedTest.kt b/test-utils/src/main/kotlin/net/corda/testing/node/NodeBasedTest.kt index 7e8d3bedd1..7958a39c50 100644 --- a/test-utils/src/main/kotlin/net/corda/testing/node/NodeBasedTest.kt +++ b/test-utils/src/main/kotlin/net/corda/testing/node/NodeBasedTest.kt @@ -164,7 +164,7 @@ abstract class NodeBasedTest : TestDependencyInjectionBase() { val parsedConfig = config.parseAs() val node = Node(parsedConfig, parsedConfig.calculateServices(), MOCK_VERSION_INFO.copy(platformVersion = platformVersion), - if (parsedConfig.useTestClock) TestClock() else NodeClock(), initialiseSerialization = false) + initialiseSerialization = false) node.start() nodes += node thread(name = legalName.commonName) { diff --git a/tools/demobench/build.gradle b/tools/demobench/build.gradle index 1eb6b3a8d8..86d1af4f6a 100644 --- a/tools/demobench/build.gradle +++ b/tools/demobench/build.gradle @@ -8,7 +8,7 @@ buildscript { ext.pkg_source = "$buildDir/packagesrc" ext.pkg_outDir = "$buildDir/javapackage" ext.dist_source = "$pkg_source/demobench-$version" - ext.pkg_version = "$version".indexOf('-') >= 0 ? "$version".substring(0, "$version".indexOf('-')) : version + ext.pkg_version = version.indexOf('-') >= 0 ? version.substring(0, version.indexOf('-')) : version ext.pkg_macosxKeyUserName = 'R3CEV' repositories { @@ -25,8 +25,8 @@ evaluationDependsOn(':tools:explorer:capsule') mainClassName = 'net.corda.demobench.DemoBench' applicationDefaultJvmArgs = [ - '-Djava.util.logging.config.class=net.corda.demobench.config.LoggingConfig', - '-Dorg.jboss.logging.provider=slf4j' + '-Djava.util.logging.config.class=net.corda.demobench.config.LoggingConfig', + '-Dorg.jboss.logging.provider=slf4j' ] repositories { @@ -78,7 +78,7 @@ jar { manifest { attributes( 'Main-Class': mainClassName, - 'Class-Path': configurations.compile.collect { it.getName() }.join(' ') + 'Class-Path': configurations.runtime.collect { it.getName() }.join(' ') ) } } @@ -165,13 +165,14 @@ task javapackage(dependsOn: distZip) { } ant.taskdef( - resource: 'com/sun/javafx/tools/ant/antlib.xml', - classpath: "$pkg_source:$java_home/../lib/ant-javafx.jar" + resource: 'com/sun/javafx/tools/ant/antlib.xml', + classpath: "$pkg_source:$java_home/../lib/ant-javafx.jar" ) ant.deploy(nativeBundles: packageType, outdir: pkg_outDir, outfile: 'DemoBench', verbose: 'true') { application(name: 'Corda DemoBench', version: pkg_version, mainClass: mainClassName) info(title: 'Corda DemoBench', vendor: 'R3', description: 'A sales and educational tool for demonstrating Corda.') + //noinspection GroovyAssignabilityCheck resources { fileset(dir: "$dist_source/lib", type: 'jar') { include(name: '*.jar') @@ -199,7 +200,9 @@ task javapackage(dependsOn: distZip) { bundleArgument(arg: 'mac.signing-key-user-name', value: pkg_macosxKeyUserName) platform { + //noinspection GroovyAssignabilityCheck property(name: 'java.util.logging.config.class', value: 'net.corda.demobench.config.LoggingConfig') + //noinspection GroovyAssignabilityCheck property(name: 'org.jboss.logging.provider', value: 'slf4j') } diff --git a/tools/demobench/package/bugfixes/apply.bat b/tools/demobench/package/bugfixes/apply.bat index f770222122..747dc67852 100644 --- a/tools/demobench/package/bugfixes/apply.bat +++ b/tools/demobench/package/bugfixes/apply.bat @@ -19,6 +19,12 @@ if not exist %1 ( exit /b 1 ) +rem Bugfixes: +rem ========= +rem +rem sun.swing.JLightweightFrame:473 +rem https://bugs.openjdk.java.net/browse/JDK-8185890 + if exist "%BUILDDIR%" rmdir /s /q "%BUILDDIR%" mkdir "%BUILDDIR%" diff --git a/tools/demobench/package/bugfixes/apply.sh b/tools/demobench/package/bugfixes/apply.sh index 560f83abc7..f4d4290e6d 100755 --- a/tools/demobench/package/bugfixes/apply.sh +++ b/tools/demobench/package/bugfixes/apply.sh @@ -20,8 +20,7 @@ fi # ========= # # sun.swing.JLightweightFrame:473 -# https://github.com/JetBrains/jdk8u_jdk/issues/6 -# https://github.com/JetBrains/jdk8u/issues/8 +# https://bugs.openjdk.java.net/browse/JDK-8185890 rm -rf $BUILDDIR && mkdir $BUILDDIR if (javac -O -d $BUILDDIR $(find $SOURCEDIR -name "*.java")); then diff --git a/tools/loadtest/src/main/kotlin/net/corda/loadtest/LoadTest.kt b/tools/loadtest/src/main/kotlin/net/corda/loadtest/LoadTest.kt index 1a31342c1e..7ae88f528f 100644 --- a/tools/loadtest/src/main/kotlin/net/corda/loadtest/LoadTest.kt +++ b/tools/loadtest/src/main/kotlin/net/corda/loadtest/LoadTest.kt @@ -181,8 +181,7 @@ fun runLoadTests(configuration: LoadTestConfiguration, tests: List