diff --git a/client/src/integration-test/kotlin/com/r3corda/client/NodeMonitorModelTest.kt b/client/src/integration-test/kotlin/com/r3corda/client/NodeMonitorModelTest.kt index cba036b9c5..115ad655a9 100644 --- a/client/src/integration-test/kotlin/com/r3corda/client/NodeMonitorModelTest.kt +++ b/client/src/integration-test/kotlin/com/r3corda/client/NodeMonitorModelTest.kt @@ -44,7 +44,7 @@ class NodeMonitorModelTest { thread { driver { val aliceNodeFuture = startNode("Alice") - val notaryNodeFuture = startNode("Notary", advertisedServices = setOf(ServiceInfo(SimpleNotaryService.Type))) + val notaryNodeFuture = startNode("Notary", advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type))) aliceNode = aliceNodeFuture.get() notaryNode = notaryNodeFuture.get() @@ -79,8 +79,8 @@ class NodeMonitorModelTest { clientToService.onNext(ClientToServiceCommand.IssueCash( amount = Amount(100, USD), issueRef = OpaqueBytes(ByteArray(1, { 1 })), - recipient = aliceNode.identity, - notary = notaryNode.identity + recipient = aliceNode.legalIdentity, + notary = notaryNode.notaryIdentity )) vaultUpdates.expectEvents(isStrict = false) { @@ -105,13 +105,13 @@ class NodeMonitorModelTest { clientToService.onNext(ClientToServiceCommand.IssueCash( amount = Amount(100, USD), issueRef = OpaqueBytes(ByteArray(1, { 1 })), - recipient = aliceNode.identity, - notary = notaryNode.identity + recipient = aliceNode.legalIdentity, + notary = notaryNode.notaryIdentity )) clientToService.onNext(ClientToServiceCommand.PayCash( - amount = Amount(100, Issued(PartyAndReference(aliceNode.identity, OpaqueBytes(ByteArray(1, { 1 }))), USD)), - recipient = aliceNode.identity + amount = Amount(100, Issued(PartyAndReference(aliceNode.legalIdentity, OpaqueBytes(ByteArray(1, { 1 }))), USD)), + recipient = aliceNode.legalIdentity )) var issueSmId: StateMachineRunId? = null @@ -146,7 +146,7 @@ class NodeMonitorModelTest { val signaturePubKeys = tx.sigs.map { it.by }.toSet() // Only Alice signed require(signaturePubKeys.size == 1) - require(signaturePubKeys.contains(aliceNode.identity.owningKey)) + require(signaturePubKeys.contains(aliceNode.legalIdentity.owningKey)) issueTx = tx }, // MOVE @@ -156,8 +156,8 @@ class NodeMonitorModelTest { val signaturePubKeys = tx.sigs.map { it.by }.toSet() // Alice and Notary signed require(signaturePubKeys.size == 2) - require(signaturePubKeys.contains(aliceNode.identity.owningKey)) - require(signaturePubKeys.contains(notaryNode.identity.owningKey)) + require(signaturePubKeys.contains(aliceNode.legalIdentity.owningKey)) + require(signaturePubKeys.contains(notaryNode.notaryIdentity.owningKey)) moveTx = tx } ) diff --git a/contracts/src/main/kotlin/com/r3corda/contracts/IRS.kt b/contracts/src/main/kotlin/com/r3corda/contracts/IRS.kt index 54342c20bc..60ac9f07a5 100644 --- a/contracts/src/main/kotlin/com/r3corda/contracts/IRS.kt +++ b/contracts/src/main/kotlin/com/r3corda/contracts/IRS.kt @@ -188,7 +188,9 @@ class FloatingRatePaymentEvent(date: LocalDate, class InterestRateSwap() : Contract { override val legalContractReference = SecureHash.sha256("is_this_the_text_of_the_contract ? TBD") - object OracleType : ServiceType("corda.interest_rates") + companion object { + val oracleType = ServiceType.corda.getSubType("interest_rates") + } /** * This Common area contains all the information that is not leg specific. @@ -657,7 +659,7 @@ class InterestRateSwap() : Contract { override val contract = IRS_PROGRAM_ID override val oracleType: ServiceType - get() = OracleType + get() = InterestRateSwap.oracleType override val ref = common.tradeID diff --git a/contracts/src/main/kotlin/com/r3corda/contracts/testing/VaultFiller.kt b/contracts/src/main/kotlin/com/r3corda/contracts/testing/VaultFiller.kt index 93f75b052d..21e2e2ee4c 100644 --- a/contracts/src/main/kotlin/com/r3corda/contracts/testing/VaultFiller.kt +++ b/contracts/src/main/kotlin/com/r3corda/contracts/testing/VaultFiller.kt @@ -37,7 +37,7 @@ fun ServiceHub.fillWithSomeTestCash(howMuch: Amount, ownedBy: PublicKey? = null): Vault { val amounts = calculateRandomlySizedAmounts(howMuch, atLeastThisManyStates, atMostThisManyStates, rng) - val myKey: PublicKey = ownedBy ?: storageService.myLegalIdentityKey.public + val myKey: PublicKey = ownedBy ?: myInfo.legalIdentity.owningKey // We will allocate one state to one transaction, for simplicities sake. val cash = Cash() diff --git a/contracts/src/main/kotlin/com/r3corda/protocols/TwoPartyTradeProtocol.kt b/contracts/src/main/kotlin/com/r3corda/protocols/TwoPartyTradeProtocol.kt index ccb6a33302..5ada377942 100644 --- a/contracts/src/main/kotlin/com/r3corda/protocols/TwoPartyTradeProtocol.kt +++ b/contracts/src/main/kotlin/com/r3corda/protocols/TwoPartyTradeProtocol.kt @@ -8,6 +8,7 @@ import com.r3corda.core.crypto.DigitalSignature import com.r3corda.core.crypto.Party import com.r3corda.core.crypto.signWithECDSA import com.r3corda.core.node.NodeInfo +import com.r3corda.core.node.services.ServiceType import com.r3corda.core.protocols.ProtocolLogic import com.r3corda.core.seconds import com.r3corda.core.transactions.SignedTransaction @@ -113,7 +114,7 @@ object TwoPartyTradeProtocol { progressTracker.nextStep() // Check that the tx proposed by the buyer is valid. - val wtx: WireTransaction = it.verifySignatures(myKeyPair.public, notaryNode.identity.owningKey) + val wtx: WireTransaction = it.verifySignatures(myKeyPair.public, notaryNode.notaryIdentity.owningKey) logger.trace { "Received partially signed transaction: ${it.id}" } // Download and check all the things that this transaction depends on and verify it is contract-valid, diff --git a/contracts/src/test/kotlin/com/r3corda/contracts/CommercialPaperTests.kt b/contracts/src/test/kotlin/com/r3corda/contracts/CommercialPaperTests.kt index 7c1340c9de..8c4e3ec3c6 100644 --- a/contracts/src/test/kotlin/com/r3corda/contracts/CommercialPaperTests.kt +++ b/contracts/src/test/kotlin/com/r3corda/contracts/CommercialPaperTests.kt @@ -211,7 +211,7 @@ class CommercialPaperTestsGeneric { // BigCorpâ„¢ issues $10,000 of commercial paper, to mature in 30 days, owned initially by itself. val faceValue = 10000.DOLLARS `issued by` DUMMY_CASH_ISSUER - val issuance = bigCorpServices.storageService.myLegalIdentity.ref(1) + val issuance = bigCorpServices.myInfo.legalIdentity.ref(1) val issueTX: SignedTransaction = CommercialPaper().generateIssue(issuance, faceValue, TEST_TX_TIME + 30.days, DUMMY_NOTARY).apply { setTime(TEST_TX_TIME, 30.seconds) diff --git a/core/src/main/kotlin/com/r3corda/core/node/NodeInfo.kt b/core/src/main/kotlin/com/r3corda/core/node/NodeInfo.kt index 3e2d837db1..f0e0ef8000 100644 --- a/core/src/main/kotlin/com/r3corda/core/node/NodeInfo.kt +++ b/core/src/main/kotlin/com/r3corda/core/node/NodeInfo.kt @@ -3,10 +3,21 @@ package com.r3corda.core.node import com.r3corda.core.crypto.Party import com.r3corda.core.messaging.SingleMessageRecipient import com.r3corda.core.node.services.ServiceInfo +import com.r3corda.core.node.services.ServiceType + +/** + * Information for an advertised service including the service specific identity information. + * The identity can be used in protocols and is distinct from the Node's legalIdentity + */ +data class ServiceEntry(val info: ServiceInfo, val identity: Party) /** * Info about a network node that acts on behalf of some form of contract party. */ -data class NodeInfo(val address: SingleMessageRecipient, val identity: Party, - var advertisedServices: Set = emptySet(), - val physicalLocation: PhysicalLocation? = null) +data class NodeInfo(val address: SingleMessageRecipient, + val legalIdentity: Party, + var advertisedServices: List = emptyList(), + val physicalLocation: PhysicalLocation? = null) { + val notaryIdentity: Party get() = advertisedServices.single { it.info.type.isNotary() }.identity + fun serviceIdentities(type: ServiceType): List = advertisedServices.filter { it.info.type.isSubTypeOf(type) }.map { it.identity } +} diff --git a/core/src/main/kotlin/com/r3corda/core/node/ServiceHub.kt b/core/src/main/kotlin/com/r3corda/core/node/ServiceHub.kt index 78b4b13f3b..58c1acdf4f 100644 --- a/core/src/main/kotlin/com/r3corda/core/node/ServiceHub.kt +++ b/core/src/main/kotlin/com/r3corda/core/node/ServiceHub.kt @@ -8,6 +8,7 @@ import com.r3corda.core.contracts.TransactionState import com.r3corda.core.messaging.MessagingService import com.r3corda.core.node.services.* import com.r3corda.core.protocols.ProtocolLogic +import java.security.KeyPair import java.time.Clock /** @@ -27,6 +28,7 @@ interface ServiceHub { val networkMapCache: NetworkMapCache val schedulerService: SchedulerService val clock: Clock + val myInfo: NodeInfo /** * Given a list of [SignedTransaction]s, writes them to the local storage for validated transactions and then @@ -52,6 +54,23 @@ interface ServiceHub { * @throws IllegalProtocolLogicException or IllegalArgumentException if there are problems with the [logicType] or [args]. */ fun invokeProtocolAsync(logicType: Class>, vararg args: Any?): ListenableFuture + + /** + * Helper property to shorten code for fetching the Node's KeyPair associated with the + * public legalIdentity Party from the key management service. + * Typical use is during signing in protocols and for unit test signing. + */ + val legalIdentityKey: KeyPair get() = this.keyManagementService.toKeyPair(this.myInfo.legalIdentity.owningKey) + + /** + * Helper property to shorten code for fetching the Node's KeyPair associated with the + * public notaryIdentity Party from the key management service. It is assumed that this is only + * used in contexts where the Node knows it is hosting a Notary Service. Otherwise, it will throw + * an IllegalArgumentException. + * Typical use is during signing in protocols and for unit test signing. + */ + val notaryIdentityKey: KeyPair get() = this.keyManagementService.toKeyPair(this.myInfo.notaryIdentity.owningKey) + } /** * Given some [SignedTransaction]s, writes them to the local storage for validated transactions and then @@ -59,4 +78,4 @@ interface ServiceHub { * * @param txs The transactions to record. */ -fun ServiceHub.recordTransactions(vararg txs: SignedTransaction) = recordTransactions(txs.toList()) +fun ServiceHub.recordTransactions(vararg txs: SignedTransaction) = recordTransactions(txs.toList()) \ No newline at end of file diff --git a/core/src/main/kotlin/com/r3corda/core/node/services/ServiceInfo.kt b/core/src/main/kotlin/com/r3corda/core/node/services/ServiceInfo.kt index c1797ab7dc..688fb86828 100644 --- a/core/src/main/kotlin/com/r3corda/core/node/services/ServiceInfo.kt +++ b/core/src/main/kotlin/com/r3corda/core/node/services/ServiceInfo.kt @@ -3,7 +3,7 @@ package com.r3corda.core.node.services /** * A container for additional information for an advertised service. * - * @param ServiceType the service type identifier + * @param type the ServiceType identifier * @param name the service name, used for differentiating multiple services of the same type. Can also be used as a * grouping identifier for nodes collectively running a distributed service. */ @@ -12,7 +12,7 @@ data class ServiceInfo(val type: ServiceType, val name: String? = null) { fun parse(encoded: String): ServiceInfo { val parts = encoded.split("|") require(parts.size > 0 && parts.size <= 2) { "Invalid number of elements found" } - val type = object : ServiceType(parts[0]) {} + val type = ServiceType.parse(parts[0]) val name = parts.getOrNull(1) return ServiceInfo(type, name) } diff --git a/core/src/main/kotlin/com/r3corda/core/node/services/ServiceType.kt b/core/src/main/kotlin/com/r3corda/core/node/services/ServiceType.kt index 7759e8b643..19d1c46a4e 100644 --- a/core/src/main/kotlin/com/r3corda/core/node/services/ServiceType.kt +++ b/core/src/main/kotlin/com/r3corda/core/node/services/ServiceType.kt @@ -5,7 +5,7 @@ package com.r3corda.core.node.services * map advertisements. Services that are purely local and are not providing functionality to other parts of the network * don't need a declared service type. */ -abstract class ServiceType(val id: String) { +sealed class ServiceType(val id: String) { init { // Enforce: // @@ -14,14 +14,41 @@ abstract class ServiceType(val id: String) { require(id.matches(Regex("[a-z][a-zA-Z0-9._]+"))) } - override operator fun equals(other: Any?): Boolean = - if (other is ServiceType) { - id == other.id - } else { - false + private class ServiceTypeImpl(baseId: String, subTypeId: String) : ServiceType("$baseId.$subTypeId") { + init { + // only allowed one level of subtype + require(subTypeId.matches(Regex("[a-z]\\w+"))) + } + } + + private class ServiceTypeDirect(id: String) : ServiceType(id) + + companion object { + val corda: ServiceType + get() { + val stack = Throwable().stackTrace + val caller = stack.first().className + require(caller.startsWith("com.r3corda.")) { "Corda ServiceType namespace is reserved for Corda core components" } + return ServiceTypeDirect("corda") } + val notary: ServiceType = corda.getSubType("notary") + val regulator: ServiceType = corda.getSubType("regulator") + + fun getServiceType(namespace: String, typeId: String): ServiceType { + require(!namespace.startsWith("corda")) { "Corda namespace is protected" } + return ServiceTypeImpl(namespace, typeId) + } + + fun parse(id: String): ServiceType = ServiceTypeDirect(id) + } + + fun getSubType(subTypeId: String): ServiceType = ServiceTypeImpl(id, subTypeId) + + override operator fun equals(other: Any?): Boolean = (other is ServiceType) && (other.id == this.id) + fun isSubTypeOf(superType: ServiceType) = (id == superType.id) || id.startsWith(superType.id + ".") + fun isNotary() = isSubTypeOf(notary) override fun hashCode(): Int = id.hashCode() override fun toString(): String = id.toString() diff --git a/core/src/main/kotlin/com/r3corda/core/node/services/Services.kt b/core/src/main/kotlin/com/r3corda/core/node/services/Services.kt index 16a73d585c..f1939180dd 100644 --- a/core/src/main/kotlin/com/r3corda/core/node/services/Services.kt +++ b/core/src/main/kotlin/com/r3corda/core/node/services/Services.kt @@ -191,14 +191,6 @@ interface StorageService { val attachments: AttachmentStorage val stateMachineRecordedTransactionMapping: StateMachineRecordedTransactionMappingStorage - - /** - * Returns the legal identity that this node is configured with. Assumed to be initialised when the node is - * first installed. - */ - //TODO this should be in the IdentityService, or somewhere not here - val myLegalIdentity: Party - val myLegalIdentityKey: KeyPair } /** diff --git a/core/src/main/kotlin/com/r3corda/protocols/AbstractStateReplacementProtocol.kt b/core/src/main/kotlin/com/r3corda/protocols/AbstractStateReplacementProtocol.kt index 247f0422b5..5c0da0b656 100644 --- a/core/src/main/kotlin/com/r3corda/protocols/AbstractStateReplacementProtocol.kt +++ b/core/src/main/kotlin/com/r3corda/protocols/AbstractStateReplacementProtocol.kt @@ -52,7 +52,7 @@ abstract class AbstractStateReplacementProtocol { progressTracker.currentStep = SIGNING - val myKey = serviceHub.storageService.myLegalIdentity.owningKey + val myKey = serviceHub.myInfo.legalIdentity.owningKey val me = listOf(myKey) val signatures = if (participants == me) { @@ -74,7 +74,7 @@ abstract class AbstractStateReplacementProtocol { val parties = participants.map { val participantNode = serviceHub.networkMapCache.getNodeByPublicKey(it) ?: throw IllegalStateException("Participant $it to state $originalState not found on the network") - participantNode.identity + participantNode.legalIdentity } val participantSignatures = parties.map { getParticipantSignature(it, stx) } @@ -134,7 +134,7 @@ abstract class AbstractStateReplacementProtocol { // TODO: catch only specific exceptions. However, there are numerous validation exceptions // that might occur (tx validation/resolution, invalid proposal). Need to rethink how // we manage exceptions and maybe introduce some platform exception hierarchy - val myIdentity = serviceHub.storageService.myLegalIdentity + val myIdentity = serviceHub.myInfo.legalIdentity val state = maybeProposal.unwrap { it.stateRef } val reason = StateReplacementRefused(myIdentity, state, e.message) @@ -186,7 +186,7 @@ abstract class AbstractStateReplacementProtocol { private fun checkMySignatureRequired(tx: WireTransaction) { // TODO: use keys from the keyManagementService instead - val myKey = serviceHub.storageService.myLegalIdentity.owningKey + val myKey = serviceHub.myInfo.legalIdentity.owningKey require(myKey in tx.mustSign) { "Party is not a participant for any of the input states of transaction ${tx.id}" } } @@ -195,7 +195,10 @@ abstract class AbstractStateReplacementProtocol { subProtocol(ResolveTransactionsProtocol(stx.tx, otherSide)) } - private fun sign(stx: SignedTransaction) = serviceHub.storageService.myLegalIdentityKey.signWithECDSA(stx.txBits) + private fun sign(stx: SignedTransaction): DigitalSignature.WithKey { + val myKey = serviceHub.legalIdentityKey + return myKey.signWithECDSA(stx.txBits) + } } // TODO: similar classes occur in other places (NotaryProtocol), need to consolidate diff --git a/core/src/main/kotlin/com/r3corda/protocols/BroadcastTransactionProtocol.kt b/core/src/main/kotlin/com/r3corda/protocols/BroadcastTransactionProtocol.kt index 1c405442e0..f61071dbd8 100644 --- a/core/src/main/kotlin/com/r3corda/protocols/BroadcastTransactionProtocol.kt +++ b/core/src/main/kotlin/com/r3corda/protocols/BroadcastTransactionProtocol.kt @@ -34,7 +34,7 @@ class BroadcastTransactionProtocol(val notarisedTransaction: SignedTransaction, // TODO: Messaging layer should handle this broadcast for us val msg = NotifyTxRequest(notarisedTransaction, events) - participants.filter { it != serviceHub.storageService.myLegalIdentity }.forEach { participant -> + participants.filter { it != serviceHub.myInfo.legalIdentity }.forEach { participant -> send(participant, msg) } } diff --git a/core/src/main/kotlin/com/r3corda/protocols/NotaryChangeProtocol.kt b/core/src/main/kotlin/com/r3corda/protocols/NotaryChangeProtocol.kt index 618888922e..481e5625ea 100644 --- a/core/src/main/kotlin/com/r3corda/protocols/NotaryChangeProtocol.kt +++ b/core/src/main/kotlin/com/r3corda/protocols/NotaryChangeProtocol.kt @@ -41,7 +41,8 @@ object NotaryChangeProtocol: AbstractStateReplacementProtocol() { val newState = state.withNotary(modification) val participants = state.data.participants val tx = TransactionType.NotaryChange.Builder(originalState.state.notary).withItems(originalState, newState) - tx.signWith(serviceHub.storageService.myLegalIdentityKey) + val myKey = serviceHub.legalIdentityKey + tx.signWith(myKey) val stx = tx.toSignedTransaction(false) return Pair(stx, participants) @@ -63,7 +64,7 @@ object NotaryChangeProtocol: AbstractStateReplacementProtocol() { override fun verifyProposal(maybeProposal: UntrustworthyData>): AbstractStateReplacementProtocol.Proposal { return maybeProposal.unwrap { proposal -> val newNotary = proposal.modification - val isNotary = serviceHub.networkMapCache.notaryNodes.any { it.identity == newNotary } + val isNotary = serviceHub.networkMapCache.notaryNodes.any { it.notaryIdentity == newNotary } require(isNotary) { "The proposed node $newNotary does not run a Notary service " } val state = proposal.stateRef diff --git a/core/src/main/kotlin/com/r3corda/protocols/NotaryProtocol.kt b/core/src/main/kotlin/com/r3corda/protocols/NotaryProtocol.kt index 74f6cca462..feb7c56dbc 100644 --- a/core/src/main/kotlin/com/r3corda/protocols/NotaryProtocol.kt +++ b/core/src/main/kotlin/com/r3corda/protocols/NotaryProtocol.kt @@ -49,7 +49,7 @@ object NotaryProtocol { "Input states must have the same Notary" } - val request = SignRequest(stx, serviceHub.storageService.myLegalIdentity) + val request = SignRequest(stx, serviceHub.myInfo.legalIdentity) val response = sendAndReceive(notaryParty, request) return validateResponse(response) @@ -141,8 +141,9 @@ object NotaryProtocol { } private fun sign(bits: SerializedBytes): DigitalSignature.LegallyIdentifiable { - val mySigningKey = serviceHub.storageService.myLegalIdentityKey - val myIdentity = serviceHub.storageService.myLegalIdentity + val myNodeInfo = serviceHub.myInfo + val myIdentity = myNodeInfo.notaryIdentity + val mySigningKey = serviceHub.notaryIdentityKey return mySigningKey.signWithECDSA(bits, myIdentity) } } diff --git a/core/src/main/kotlin/com/r3corda/protocols/TwoPartyDealProtocol.kt b/core/src/main/kotlin/com/r3corda/protocols/TwoPartyDealProtocol.kt index c8caa8d2e1..6f60937379 100644 --- a/core/src/main/kotlin/com/r3corda/protocols/TwoPartyDealProtocol.kt +++ b/core/src/main/kotlin/com/r3corda/protocols/TwoPartyDealProtocol.kt @@ -78,7 +78,7 @@ object TwoPartyDealProtocol { abstract val myKeyPair: KeyPair override fun getCounterpartyMarker(party: Party): Class<*> { - return if (serviceHub.networkMapCache.regulators.any { it.identity == party }) { + return if (serviceHub.networkMapCache.regulators.any { it.legalIdentity == party }) { MarkerForBogusRegulatorProtocol::class.java } else { super.getCounterpartyMarker(party) @@ -104,7 +104,7 @@ object TwoPartyDealProtocol { progressTracker.nextStep() // Check that the tx proposed by the buyer is valid. - val wtx: WireTransaction = stx.verifySignatures(myKeyPair.public, notaryNode.identity.owningKey) + val wtx: WireTransaction = stx.verifySignatures(myKeyPair.public, notaryNode.notaryIdentity.owningKey) logger.trace { "Received partially signed transaction: ${stx.id}" } checkDependencies(stx) @@ -155,7 +155,7 @@ object TwoPartyDealProtocol { if (regulators.isNotEmpty()) { // Copy the transaction to every regulator in the network. This is obviously completely bogus, it's // just for demo purposes. - regulators.forEach { send(it.identity, fullySigned) } + regulators.forEach { send(it.serviceIdentities(ServiceType.regulator).first(), fullySigned) } } return fullySigned @@ -277,7 +277,7 @@ object TwoPartyDealProtocol { override val progressTracker: ProgressTracker = Primary.tracker()) : Primary() { override val notaryNode: NodeInfo get() = - serviceHub.networkMapCache.notaryNodes.filter { it.identity == payload.notary }.single() + serviceHub.networkMapCache.notaryNodes.filter { it.notaryIdentity == payload.notary }.single() } /** @@ -301,7 +301,7 @@ object TwoPartyDealProtocol { // And add a request for timestamping: it may be that none of the contracts need this! But it can't hurt // to have one. ptx.setTime(serviceHub.clock.instant(), 30.seconds) - return Pair(ptx, arrayListOf(deal.parties.single { it.name == serviceHub.storageService.myLegalIdentity.name }.owningKey)) + return Pair(ptx, arrayListOf(deal.parties.single { it.name == serviceHub.myInfo.legalIdentity.name }.owningKey)) } } @@ -326,7 +326,7 @@ object TwoPartyDealProtocol { // validate the party that initiated is the one on the deal and that the recipient corresponds with it. // TODO: this is in no way secure and will be replaced by general session initiation logic in the future - val myName = serviceHub.storageService.myLegalIdentity.name + val myName = serviceHub.myInfo.legalIdentity.name // Also check we are one of the parties deal.parties.filter { it.name == myName }.single() @@ -339,7 +339,7 @@ object TwoPartyDealProtocol { val fixOf = deal.nextFixingOf()!! // TODO Do we need/want to substitute in new public keys for the Parties? - val myName = serviceHub.storageService.myLegalIdentity.name + val myName = serviceHub.myInfo.legalIdentity.name val myOldParty = deal.parties.single { it.name == myName } val newDeal = deal @@ -348,7 +348,7 @@ object TwoPartyDealProtocol { val oracle = serviceHub.networkMapCache.get(handshake.payload.oracleType).first() - val addFixing = object : RatesFixProtocol(ptx, oracle.identity, fixOf, BigDecimal.ZERO, BigDecimal.ONE) { + val addFixing = object : RatesFixProtocol(ptx, oracle.serviceIdentities(handshake.payload.oracleType).first(), fixOf, BigDecimal.ZERO, BigDecimal.ONE) { @Suspendable override fun beforeSigning(fix: Fix) { newDeal.generateFix(ptx, StateAndRef(txState, handshake.payload.ref), fix) @@ -381,13 +381,13 @@ object TwoPartyDealProtocol { } override val myKeyPair: KeyPair get() { - val myName = serviceHub.storageService.myLegalIdentity.name + val myName = serviceHub.myInfo.legalIdentity.name val publicKey = dealToFix.state.data.parties.filter { it.name == myName }.single().owningKey return serviceHub.keyManagementService.toKeyPair(publicKey) } override val notaryNode: NodeInfo get() = - serviceHub.networkMapCache.notaryNodes.filter { it.identity == dealToFix.state.notary }.single() + serviceHub.networkMapCache.notaryNodes.filter { it.notaryIdentity == dealToFix.state.notary }.single() } @@ -419,7 +419,7 @@ object TwoPartyDealProtocol { // TODO: this is not the eventual mechanism for identifying the parties val fixableDeal = (dealToFix.data as FixableDealState) val sortedParties = fixableDeal.parties.sortedBy { it.name } - if (sortedParties[0].name == serviceHub.storageService.myLegalIdentity.name) { + if (sortedParties[0].name == serviceHub.myInfo.legalIdentity.name) { val fixing = FixingSession(ref, fixableDeal.oracleType) // Start the Floater which will then kick-off the Fixer subProtocol(Floater(sortedParties[1], fixing)) diff --git a/core/src/main/kotlin/com/r3corda/protocols/ValidatingNotaryProtocol.kt b/core/src/main/kotlin/com/r3corda/protocols/ValidatingNotaryProtocol.kt index 533f4b716c..2347b3545d 100644 --- a/core/src/main/kotlin/com/r3corda/protocols/ValidatingNotaryProtocol.kt +++ b/core/src/main/kotlin/com/r3corda/protocols/ValidatingNotaryProtocol.kt @@ -38,7 +38,7 @@ class ValidatingNotaryProtocol(otherSide: Party, private fun checkSignatures(stx: SignedTransaction) { try { - stx.verifySignatures(serviceHub.storageService.myLegalIdentity.owningKey) + stx.verifySignatures(serviceHub.myInfo.legalIdentity.owningKey) } catch(e: SignedTransaction.SignaturesMissingException) { throw NotaryException(NotaryError.SignaturesMissing(e.missing)) } diff --git a/core/src/test/kotlin/com/r3corda/core/node/ServiceInfoTests.kt b/core/src/test/kotlin/com/r3corda/core/node/ServiceInfoTests.kt index 25ea8de559..afa259814b 100644 --- a/core/src/test/kotlin/com/r3corda/core/node/ServiceInfoTests.kt +++ b/core/src/test/kotlin/com/r3corda/core/node/ServiceInfoTests.kt @@ -7,7 +7,7 @@ import kotlin.test.assertEquals import kotlin.test.assertFailsWith class ServiceInfoTests { - val serviceType = object : ServiceType("corda.service.subservice") {} + val serviceType = ServiceType.getServiceType("test", "service").getSubType("subservice") val name = "service.name" @Test diff --git a/core/src/test/kotlin/com/r3corda/core/protocols/ResolveTransactionsProtocolTest.kt b/core/src/test/kotlin/com/r3corda/core/protocols/ResolveTransactionsProtocolTest.kt index 3f28acbbc4..4d942158e9 100644 --- a/core/src/test/kotlin/com/r3corda/core/protocols/ResolveTransactionsProtocolTest.kt +++ b/core/src/test/kotlin/com/r3corda/core/protocols/ResolveTransactionsProtocolTest.kt @@ -32,7 +32,7 @@ class ResolveTransactionsProtocolTest { val nodes = net.createSomeNodes() a = nodes.partyNodes[0] b = nodes.partyNodes[1] - notary = nodes.notaryNode.info.identity + notary = nodes.notaryNode.info.notaryIdentity net.runNetwork() } @@ -44,7 +44,7 @@ class ResolveTransactionsProtocolTest { @Test fun `resolve from two hashes`() { val (stx1, stx2) = makeTransactions() - val p = ResolveTransactionsProtocol(setOf(stx2.id), a.info.identity) + val p = ResolveTransactionsProtocol(setOf(stx2.id), a.info.legalIdentity) val future = b.services.startProtocol("resolve", p) net.runNetwork() val results = future.get() @@ -56,7 +56,7 @@ class ResolveTransactionsProtocolTest { @Test fun `dependency with an error`() { val stx = makeTransactions(signFirstTX = false).second - val p = ResolveTransactionsProtocol(setOf(stx.id), a.info.identity) + val p = ResolveTransactionsProtocol(setOf(stx.id), a.info.legalIdentity) val future = b.services.startProtocol("resolve", p) net.runNetwork() assertFailsWith(SignatureException::class) { @@ -67,7 +67,7 @@ class ResolveTransactionsProtocolTest { @Test fun `resolve from a signed transaction`() { val (stx1, stx2) = makeTransactions() - val p = ResolveTransactionsProtocol(stx2, a.info.identity) + val p = ResolveTransactionsProtocol(stx2, a.info.legalIdentity) val future = b.services.startProtocol("resolve", p) net.runNetwork() future.get() @@ -89,7 +89,7 @@ class ResolveTransactionsProtocolTest { a.services.recordTransactions(stx) cursor = stx } - val p = ResolveTransactionsProtocol(setOf(cursor.id), a.info.identity) + val p = ResolveTransactionsProtocol(setOf(cursor.id), a.info.legalIdentity) p.transactionCountLimit = 40 val future = b.services.startProtocol("resolve", p) net.runNetwork() @@ -116,7 +116,7 @@ class ResolveTransactionsProtocolTest { a.services.recordTransactions(stx2, stx3) - val p = ResolveTransactionsProtocol(setOf(stx3.id), a.info.identity) + val p = ResolveTransactionsProtocol(setOf(stx3.id), a.info.legalIdentity) val future = b.services.startProtocol("resolve", p) net.runNetwork() future.get() @@ -126,7 +126,7 @@ class ResolveTransactionsProtocolTest { fun attachment() { val id = a.services.storageService.attachments.importAttachment("Some test file".toByteArray().opaque().open()) val stx2 = makeTransactions(withAttachment = id).second - val p = ResolveTransactionsProtocol(stx2, a.info.identity) + val p = ResolveTransactionsProtocol(stx2, a.info.legalIdentity) val future = b.services.startProtocol("resolve", p) net.runNetwork() future.get() diff --git a/explorer/src/main/kotlin/com/r3corda/explorer/Main.kt b/explorer/src/main/kotlin/com/r3corda/explorer/Main.kt index 79a9293916..59b0bf6200 100644 --- a/explorer/src/main/kotlin/com/r3corda/explorer/Main.kt +++ b/explorer/src/main/kotlin/com/r3corda/explorer/Main.kt @@ -37,22 +37,22 @@ class Main : App() { driver(portAllocation = portAllocation) { val aliceNodeFuture = startNode("Alice") - val notaryNodeFuture = startNode("Notary", advertisedServices = setOf(ServiceInfo(SimpleNotaryService.Type))) + val notaryNodeFuture = startNode("Notary", advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type))) val aliceNode = aliceNodeFuture.get() val notaryNode = notaryNodeFuture.get() val aliceClient = startClient(aliceNode).get() - Models.get(Main::class).myIdentity.set(aliceNode.identity) + Models.get(Main::class).myIdentity.set(aliceNode.legalIdentity) Models.get(Main::class).register(aliceNode, aliceClient.config.certificatesPath) for (i in 0 .. 10000) { Thread.sleep(500) val eventGenerator = EventGenerator( - parties = listOf(aliceNode.identity), - notary = notaryNode.identity + parties = listOf(aliceNode.legalIdentity), + notary = notaryNode.notaryIdentity ) eventGenerator.clientToServiceCommandGenerator.map { command -> diff --git a/network-simulator/src/main/kotlin/com/r3cev/corda/netmap/NetworkMapVisualiser.kt b/network-simulator/src/main/kotlin/com/r3cev/corda/netmap/NetworkMapVisualiser.kt index 2cc862ab6c..a62239c82b 100644 --- a/network-simulator/src/main/kotlin/com/r3cev/corda/netmap/NetworkMapVisualiser.kt +++ b/network-simulator/src/main/kotlin/com/r3cev/corda/netmap/NetworkMapVisualiser.kt @@ -236,7 +236,7 @@ class NetworkMapVisualiser : Application() { if (change.tracker == tracker) { // Protocol done; schedule it for removal in a few seconds. We batch them up to make nicer // animations. - println("Protocol done for ${node.info.identity.name}") + println("Protocol done for ${node.info.legalIdentity.name}") viewModel.doneTrackers += tracker } else { // Subprotocol is done; ignore it. @@ -244,7 +244,7 @@ class NetworkMapVisualiser : Application() { } else if (!viewModel.trackerBoxes.containsKey(tracker)) { // New protocol started up; add. val extraLabel = viewModel.simulation.extraNodeLabels[node] - val label = if (extraLabel != null) "${node.storage.myLegalIdentity.name}: $extraLabel" else node.storage.myLegalIdentity.name + val label = if (extraLabel != null) "${node.info.legalIdentity.name}: $extraLabel" else node.info.legalIdentity.name val widget = view.buildProgressTrackerWidget(label, tracker.topLevelTracker) bindProgressTracketWidget(tracker.topLevelTracker, widget) println("Added: ${tracker}, ${widget}") diff --git a/network-simulator/src/main/kotlin/com/r3cev/corda/netmap/VisualiserViewModel.kt b/network-simulator/src/main/kotlin/com/r3cev/corda/netmap/VisualiserViewModel.kt index 1964097dc2..b15b728cf1 100644 --- a/network-simulator/src/main/kotlin/com/r3cev/corda/netmap/VisualiserViewModel.kt +++ b/network-simulator/src/main/kotlin/com/r3cev/corda/netmap/VisualiserViewModel.kt @@ -85,7 +85,7 @@ class VisualiserViewModel { try { return node.place.coordinate.project(view.mapImage.fitWidth, view.mapImage.fitHeight, 64.3209, 29.8406, -23.2031, 33.0469) } catch(e: Exception) { - throw Exception("Cannot project ${node.info.identity}", e) + throw Exception("Cannot project ${node.info.legalIdentity}", e) } } diff --git a/node/src/integration-test/kotlin/com/r3corda/node/driver/DriverTests.kt b/node/src/integration-test/kotlin/com/r3corda/node/driver/DriverTests.kt index 82bfbcb2ed..28799d4b7e 100644 --- a/node/src/integration-test/kotlin/com/r3corda/node/driver/DriverTests.kt +++ b/node/src/integration-test/kotlin/com/r3corda/node/driver/DriverTests.kt @@ -16,7 +16,7 @@ class DriverTests { // Check that the node is registered in the network map poll("network map cache for $nodeName") { networkMapCache.get().firstOrNull { - it.identity.name == nodeName + it.legalIdentity.name == nodeName } } // Check that the port is bound @@ -33,8 +33,8 @@ class DriverTests { @Test fun simpleNodeStartupShutdownWorks() { val (notary, regulator) = driver { - val notary = startNode("TestNotary", setOf(ServiceInfo(SimpleNotaryService.Type))) - val regulator = startNode("Regulator", setOf(ServiceInfo(RegulatorService.Type))) + val notary = startNode("TestNotary", setOf(ServiceInfo(SimpleNotaryService.type))) + val regulator = startNode("Regulator", setOf(ServiceInfo(RegulatorService.type))) nodeMustBeUp(networkMapCache, notary.get(), "TestNotary") nodeMustBeUp(networkMapCache, regulator.get(), "Regulator") diff --git a/node/src/main/kotlin/com/r3corda/node/driver/Driver.kt b/node/src/main/kotlin/com/r3corda/node/driver/Driver.kt index 4073148e91..ac228d1c61 100644 --- a/node/src/main/kotlin/com/r3corda/node/driver/Driver.kt +++ b/node/src/main/kotlin/com/r3corda/node/driver/Driver.kt @@ -77,7 +77,7 @@ fun DriverDSLExposedInterface.startClient(localServer: ArtemisMessagingServer) = fun DriverDSLExposedInterface.startClient(remoteNodeInfo: NodeInfo, providedName: String? = null) = startClient( - providedName = providedName ?: "${remoteNodeInfo.identity.name}-client", + providedName = providedName ?: "${remoteNodeInfo.legalIdentity.name}-client", serverAddress = ArtemisMessagingComponent.toHostAndPort(remoteNodeInfo.address) ) @@ -309,7 +309,7 @@ class DriverDSL( registerProcess(DriverDSL.startNode(config, quasarJarPath, debugPort)) poll("network map cache for $name") { networkMapCache.partyNodes.forEach { - if (it.identity.name == name) { + if (it.legalIdentity.name == name) { return@poll it } } @@ -383,7 +383,7 @@ class DriverDSL( networkMapCache.addMapService(networkMapClient, networkMapAddr, true) networkMapNodeInfo = poll("network map cache for $networkMapName") { networkMapCache.partyNodes.forEach { - if (it.identity.name == networkMapName) { + if (it.legalIdentity.name == networkMapName) { return@poll it } } diff --git a/node/src/main/kotlin/com/r3corda/node/internal/AbstractNode.kt b/node/src/main/kotlin/com/r3corda/node/internal/AbstractNode.kt index 8ee2885299..69174bf752 100644 --- a/node/src/main/kotlin/com/r3corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/com/r3corda/node/internal/AbstractNode.kt @@ -8,10 +8,7 @@ import com.r3corda.core.RunOnCallerThread import com.r3corda.core.crypto.Party import com.r3corda.core.crypto.X509Utilities import com.r3corda.core.messaging.SingleMessageRecipient -import com.r3corda.core.node.CityDatabase -import com.r3corda.core.node.CordaPluginRegistry -import com.r3corda.core.node.NodeInfo -import com.r3corda.core.node.PhysicalLocation +import com.r3corda.core.node.* import com.r3corda.core.node.services.* import com.r3corda.core.node.services.NetworkMapCache.MapChangeType import com.r3corda.core.protocols.ProtocolLogic @@ -96,6 +93,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo val servicesThatAcceptUploads: List = _servicesThatAcceptUploads private val protocolFactories = ConcurrentHashMap, (Party) -> ProtocolLogic<*>>() + protected val partyKeys = mutableSetOf() val services = object : ServiceHubInternal() { override val networkService: MessagingServiceInternal get() = net @@ -106,6 +104,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo override val identityService: IdentityService get() = identity override val schedulerService: SchedulerService get() = scheduler override val clock: Clock = platformClock + override val myInfo: NodeInfo get() = info override val schemaService: SchemaService get() = schemas // Internal only @@ -130,7 +129,13 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo } val info: NodeInfo by lazy { - NodeInfo(net.myAddress, storage.myLegalIdentity, advertisedServices, findMyLocation()) + val services = mutableListOf() + for (service in advertisedServices) { + val identity = obtainKeyPair(configuration.basedir, service.type.id + "-private-key", service.type.id + "-public", service.type.id).first + services += ServiceEntry(service, identity) + } + val legalIdentity = obtainLegalIdentity() + NodeInfo(net.myAddress, legalIdentity, services, findMyLocation()) } open fun findMyLocation(): PhysicalLocation? = CityDatabase[configuration.nearestCity] @@ -214,7 +219,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo // TODO: uniquenessProvider creation should be inside makeNotaryService(), but notary service initialisation // depends on smm, while smm depends on tokenizableServices, which uniquenessProvider is part of - advertisedServices.singleOrNull { it.type.isSubTypeOf(NotaryService.Type) }?.let { + advertisedServices.singleOrNull { it.type.isNotary() }?.let { uniquenessProvider = makeUniquenessProvider() tokenizableServices.add(uniquenessProvider!!) } @@ -321,10 +326,10 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo } private fun buildAdvertisedServices() { - val serviceTypes = info.advertisedServices.map { it.type } - if (NetworkMapService.Type in serviceTypes) makeNetworkMapService() + val serviceTypes = info.advertisedServices.map { it.info.type } + if (NetworkMapService.type in serviceTypes) makeNetworkMapService() - val notaryServiceType = serviceTypes.singleOrNull { it.isSubTypeOf(NotaryService.Type) } + val notaryServiceType = serviceTypes.singleOrNull { it.isNotary() } if (notaryServiceType != null) { inNodeNotaryService = makeNotaryService(notaryServiceType) } @@ -335,7 +340,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo * updates) if one has been supplied. */ private fun registerWithNetworkMap(): ListenableFuture { - require(networkMapService != null || NetworkMapService.Type in advertisedServices.map { it.type }) { + require(networkMapService != null || NetworkMapService.type in advertisedServices.map { it.type }) { "Initial network map address must indicate a node that provides a network map service" } services.networkMapCache.addNode(info) @@ -365,11 +370,12 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo val instant = platformClock.instant() val expires = instant + NetworkMapService.DEFAULT_EXPIRATION_PERIOD val reg = NodeRegistration(info, instant.toEpochMilli(), type, expires) - val request = NetworkMapService.RegistrationRequest(reg.toWire(storage.myLegalIdentityKey.private), net.myAddress) + val legalIdentityKey = obtainLegalIdentityKey() + val request = NetworkMapService.RegistrationRequest(reg.toWire(legalIdentityKey.private), net.myAddress) return net.sendRequest(REGISTER_PROTOCOL_TOPIC, request, networkMapAddr, RunOnCallerThread) } - protected open fun makeKeyManagementService(): KeyManagementService = PersistentKeyManagementService(setOf(storage.myLegalIdentityKey)) + protected open fun makeKeyManagementService(): KeyManagementService = PersistentKeyManagementService(partyKeys) open protected fun makeNetworkMapService() { inNodeNetworkMapService = PersistentNetworkMapService(services) @@ -379,8 +385,8 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo val timestampChecker = TimestampChecker(platformClock, 30.seconds) return when (type) { - SimpleNotaryService.Type -> SimpleNotaryService(services, timestampChecker, uniquenessProvider!!) - ValidatingNotaryService.Type -> ValidatingNotaryService(services, timestampChecker, uniquenessProvider!!) + SimpleNotaryService.type -> SimpleNotaryService(services, timestampChecker, uniquenessProvider!!) + ValidatingNotaryService.type -> ValidatingNotaryService(services, timestampChecker, uniquenessProvider!!) else -> { throw IllegalArgumentException("Notary type ${type.id} is not handled by makeNotaryService.") } @@ -392,13 +398,14 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo protected open fun makeIdentityService(): IdentityService { val service = InMemoryIdentityService() - service.registerIdentity(storage.myLegalIdentity) + service.registerIdentity(info.legalIdentity) - services.networkMapCache.partyNodes.forEach { service.registerIdentity(it.identity) } + services.networkMapCache.partyNodes.forEach { service.registerIdentity(it.legalIdentity) } netMapCache.changed.subscribe { mapChange -> + // TODO how should we handle network map removal if (mapChange.type == MapChangeType.Added) { - service.registerIdentity(mapChange.node.identity) + service.registerIdentity(mapChange.node.legalIdentity) } } @@ -437,35 +444,42 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo val checkpointStorage = initialiseCheckpointService(dir) val transactionStorage = PerFileTransactionStorage(dir.resolve("transactions")) _servicesThatAcceptUploads += attachments - val (identity, keyPair) = obtainKeyPair(dir) + // Populate the partyKeys set. + obtainKeyPair(dir, PRIVATE_KEY_FILE_NAME, PUBLIC_IDENTITY_FILE_NAME) + for (service in advertisedServices) { + // Ensure all required keys exist. + obtainKeyPair(configuration.basedir, service.type.id + "-private-key", service.type.id + "-public", service.type.id) + } val stateMachineTransactionMappingStorage = InMemoryStateMachineRecordedTransactionMappingStorage() return Pair( - constructStorageService(attachments, transactionStorage, stateMachineTransactionMappingStorage, keyPair, identity), + constructStorageService(attachments, transactionStorage, stateMachineTransactionMappingStorage), checkpointStorage ) } protected open fun constructStorageService(attachments: NodeAttachmentService, transactionStorage: TransactionStorage, - stateMachineRecordedTransactionMappingStorage: StateMachineRecordedTransactionMappingStorage, - keyPair: KeyPair, - identity: Party) = - StorageServiceImpl(attachments, transactionStorage, stateMachineRecordedTransactionMappingStorage, keyPair, identity) + stateMachineRecordedTransactionMappingStorage: StateMachineRecordedTransactionMappingStorage) = + StorageServiceImpl(attachments, transactionStorage, stateMachineRecordedTransactionMappingStorage) - private fun obtainKeyPair(dir: Path): Pair { + protected fun obtainLegalIdentity(): Party = obtainKeyPair(configuration.basedir, PRIVATE_KEY_FILE_NAME, PUBLIC_IDENTITY_FILE_NAME).first + protected fun obtainLegalIdentityKey(): KeyPair = obtainKeyPair(configuration.basedir, PRIVATE_KEY_FILE_NAME, PUBLIC_IDENTITY_FILE_NAME).second + + private fun obtainKeyPair(dir: Path, privateKeyFileName: String, publicKeyFileName: String, serviceName: String? = null): Pair { // Load the private identity key, creating it if necessary. The identity key is a long term well known key that // is distributed to other peers and we use it (or a key signed by it) when we need to do something // "permissioned". The identity file is what gets distributed and contains the node's legal name along with // the public key. Obviously in a real system this would need to be a certificate chain of some kind to ensure // the legal name is actually validated in some way. - val privKeyFile = dir.resolve(PRIVATE_KEY_FILE_NAME) - val pubIdentityFile = dir.resolve(PUBLIC_IDENTITY_FILE_NAME) + val privKeyFile = dir.resolve(privateKeyFileName) + val pubIdentityFile = dir.resolve(publicKeyFileName) + val identityName = if (serviceName == null) configuration.myLegalName else configuration.myLegalName + "|" + serviceName - return if (!Files.exists(privKeyFile)) { + val identityAndKey = if (!Files.exists(privKeyFile)) { log.info("Identity key not found, generating fresh key!") val keyPair: KeyPair = generateKeyPair() keyPair.serialize().writeToFile(privKeyFile) - val myIdentity = Party(configuration.myLegalName, keyPair.public) + val myIdentity = Party(identityName, keyPair.public) // We include the Party class with the file here to help catch mixups when admins provide files of the // wrong type by mistake. myIdentity.serialize().writeToFile(pubIdentityFile) @@ -475,13 +489,15 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo // This is just a sanity check. It shouldn't fail unless the admin has fiddled with the files and messed // things up for us. val myIdentity = Files.readAllBytes(pubIdentityFile).deserialize() - if (myIdentity.name != configuration.myLegalName) + if (myIdentity.name != identityName) throw ConfigurationException("The legal name in the config file doesn't match the stored identity file:" + - "${configuration.myLegalName} vs ${myIdentity.name}") + "${identityName} vs ${myIdentity.name}") // Load the private key. val keyPair = Files.readAllBytes(privKeyFile).deserialize() Pair(myIdentity, keyPair) } + partyKeys += identityAndKey.second + return identityAndKey } protected open fun generateKeyPair() = com.r3corda.core.crypto.generateKeyPair() diff --git a/node/src/main/kotlin/com/r3corda/node/internal/Node.kt b/node/src/main/kotlin/com/r3corda/node/internal/Node.kt index 98674024b3..b86dd5b92d 100644 --- a/node/src/main/kotlin/com/r3corda/node/internal/Node.kt +++ b/node/src/main/kotlin/com/r3corda/node/internal/Node.kt @@ -117,7 +117,8 @@ class Node(override val configuration: FullNodeConfiguration, networkMapAddress: artemisAddress }() } - val myIdentityOrNullIfNetworkMapService = if (networkMapService != null) services.storageService.myLegalIdentityKey.public else null + val legalIdentity = obtainLegalIdentity() + val myIdentityOrNullIfNetworkMapService = if (networkMapService != null) legalIdentity.owningKey else null return NodeMessagingClient(configuration, serverAddr, myIdentityOrNullIfNetworkMapService, serverThread, persistenceTx = { body: () -> Unit -> databaseTransaction(database) { body() } }) } diff --git a/node/src/main/kotlin/com/r3corda/node/internal/ServerRPCOps.kt b/node/src/main/kotlin/com/r3corda/node/internal/ServerRPCOps.kt index 84a3e315d1..59ecfd9cf6 100644 --- a/node/src/main/kotlin/com/r3corda/node/internal/ServerRPCOps.kt +++ b/node/src/main/kotlin/com/r3corda/node/internal/ServerRPCOps.kt @@ -8,7 +8,6 @@ import com.r3corda.core.crypto.toStringShort import com.r3corda.core.node.ServiceHub import com.r3corda.core.node.services.Vault import com.r3corda.core.transactions.TransactionBuilder -import com.r3corda.node.services.api.ServiceHubInternal import com.r3corda.node.services.messaging.CordaRPCOps import com.r3corda.node.services.messaging.StateMachineInfo import com.r3corda.node.services.messaging.StateMachineUpdate @@ -93,10 +92,11 @@ class ServerRPCOps( private fun exitCash(req: ClientToServiceCommand.ExitCash): TransactionBuildResult { val builder: TransactionBuilder = TransactionType.General.Builder(null) try { - val issuer = PartyAndReference(services.storageService.myLegalIdentity, req.issueRef) + val issuer = PartyAndReference(services.myInfo.legalIdentity, req.issueRef) Cash().generateExit(builder, req.amount.issuedBy(issuer), services.vaultService.currentVault.statesOfType().filter { it.state.data.owner == issuer.party.owningKey }) - builder.signWith(services.storageService.myLegalIdentityKey) + val myKey = services.legalIdentityKey + builder.signWith(myKey) // Work out who the owners of the burnt states were val inputStatesNullable = services.vaultService.statesForRefs(builder.inputStates()) @@ -126,9 +126,10 @@ class ServerRPCOps( // TODO: Make a lightweight protocol that manages this workflow, rather than embedding it directly in the service private fun issueCash(req: ClientToServiceCommand.IssueCash): TransactionBuildResult { val builder: TransactionBuilder = TransactionType.General.Builder(notary = null) - val issuer = PartyAndReference(services.storageService.myLegalIdentity, req.issueRef) + val issuer = PartyAndReference(services.myInfo.legalIdentity, req.issueRef) Cash().generateIssue(builder, req.amount.issuedBy(issuer), req.recipient.owningKey, req.notary) - builder.signWith(services.storageService.myLegalIdentityKey) + val myKey = services.legalIdentityKey + builder.signWith(myKey) val tx = builder.toSignedTransaction(checkSufficientSignatures = true) // Issuance transactions do not need to be notarised, so we can skip directly to broadcasting it val protocol = BroadcastTransactionProtocol(tx, setOf(req), setOf(req.recipient)) diff --git a/node/src/main/kotlin/com/r3corda/node/services/api/RegulatorService.kt b/node/src/main/kotlin/com/r3corda/node/services/api/RegulatorService.kt index 12aeb5023f..e5f9785f87 100644 --- a/node/src/main/kotlin/com/r3corda/node/services/api/RegulatorService.kt +++ b/node/src/main/kotlin/com/r3corda/node/services/api/RegulatorService.kt @@ -6,6 +6,7 @@ import com.r3corda.core.node.services.ServiceType * Placeholder interface for regulator services. */ interface RegulatorService { - object Type : ServiceType("corda.regulator") - + companion object { + val type = ServiceType.regulator + } } \ No newline at end of file diff --git a/node/src/main/kotlin/com/r3corda/node/services/config/NodeConfiguration.kt b/node/src/main/kotlin/com/r3corda/node/services/config/NodeConfiguration.kt index cc449c2d19..cfd9c4398b 100644 --- a/node/src/main/kotlin/com/r3corda/node/services/config/NodeConfiguration.kt +++ b/node/src/main/kotlin/com/r3corda/node/services/config/NodeConfiguration.kt @@ -54,7 +54,7 @@ class FullNodeConfiguration(config: Config) : NodeConfiguration { advertisedServices.add(ServiceInfo.parse(serviceId)) } } - if (networkMapAddress == null) advertisedServices.add(ServiceInfo(NetworkMapService.Type)) + if (networkMapAddress == null) advertisedServices.add(ServiceInfo(NetworkMapService.type)) val networkMapMessageAddress: SingleMessageRecipient? = if (networkMapAddress == null) null else NodeMessagingClient.makeNetworkMapAddress(networkMapAddress!!) return Node(this, networkMapMessageAddress, advertisedServices) } diff --git a/node/src/main/kotlin/com/r3corda/node/services/network/InMemoryNetworkMapCache.kt b/node/src/main/kotlin/com/r3corda/node/services/network/InMemoryNetworkMapCache.kt index 2db67fd825..9b918de662 100644 --- a/node/src/main/kotlin/com/r3corda/node/services/network/InMemoryNetworkMapCache.kt +++ b/node/src/main/kotlin/com/r3corda/node/services/network/InMemoryNetworkMapCache.kt @@ -41,11 +41,11 @@ import javax.annotation.concurrent.ThreadSafe @ThreadSafe open class InMemoryNetworkMapCache : SingletonSerializeAsToken(), NetworkMapCache { override val networkMapNodes: List - get() = get(NetworkMapService.Type) + get() = get(NetworkMapService.type) override val regulators: List - get() = get(RegulatorService.Type) + get() = get(ServiceType.regulator) override val notaryNodes: List - get() = get(NotaryService.Type) + get() = get(ServiceType.notary) override val partyNodes: List get() = registeredNodes.map { it.value } private val _changed = PublishSubject.create() @@ -58,10 +58,13 @@ open class InMemoryNetworkMapCache : SingletonSerializeAsToken(), NetworkMapCach protected var registeredNodes = Collections.synchronizedMap(HashMap()) override fun get() = registeredNodes.map { it.value } - override fun get(serviceType: ServiceType) = registeredNodes.filterValues { it.advertisedServices.any { it.type.isSubTypeOf(serviceType) } }.map { it.value } + override fun get(serviceType: ServiceType) = registeredNodes.filterValues { it.advertisedServices.any { it.info.type.isSubTypeOf(serviceType) } }.map { it.value } override fun getRecommended(type: ServiceType, contract: Contract, vararg party: Party): NodeInfo? = get(type).firstOrNull() - override fun getNodeByLegalName(name: String) = get().singleOrNull { it.identity.name == name } - override fun getNodeByPublicKey(publicKey: PublicKey) = get().singleOrNull { it.identity.owningKey == publicKey } + override fun getNodeByLegalName(name: String) = get().singleOrNull { it.legalIdentity.name == name } + override fun getNodeByPublicKey(publicKey: PublicKey) = get().singleOrNull { + (it.legalIdentity.owningKey == publicKey) + || it.advertisedServices.any { it.identity.owningKey == publicKey } + } override fun addMapService(net: MessagingService, networkMapAddress: SingleMessageRecipient, subscribe: Boolean, ifChangedSinceVer: Int?): ListenableFuture { @@ -96,7 +99,7 @@ open class InMemoryNetworkMapCache : SingletonSerializeAsToken(), NetworkMapCach } override fun addNode(node: NodeInfo) { - val oldValue = registeredNodes.put(node.identity, node) + val oldValue = registeredNodes.put(node.legalIdentity, node) if (oldValue == null) { _changed.onNext(MapChange(node, oldValue, MapChangeType.Added)) } else if(oldValue != node) { @@ -105,7 +108,7 @@ open class InMemoryNetworkMapCache : SingletonSerializeAsToken(), NetworkMapCach } override fun removeNode(node: NodeInfo) { - val oldValue = registeredNodes.remove(node.identity) + val oldValue = registeredNodes.remove(node.legalIdentity) _changed.onNext(MapChange(node, oldValue, MapChangeType.Removed)) } diff --git a/node/src/main/kotlin/com/r3corda/node/services/network/NetworkMapService.kt b/node/src/main/kotlin/com/r3corda/node/services/network/NetworkMapService.kt index 4a045c3356..4b6a68455e 100644 --- a/node/src/main/kotlin/com/r3corda/node/services/network/NetworkMapService.kt +++ b/node/src/main/kotlin/com/r3corda/node/services/network/NetworkMapService.kt @@ -48,7 +48,6 @@ import javax.annotation.concurrent.ThreadSafe // a concept of identity changes over time, should that include the node for an identity? If so, that is likely to // replace this service. interface NetworkMapService { - object Type : ServiceType("corda.network_map") companion object { val DEFAULT_EXPIRATION_PERIOD = Period.ofWeeks(4) @@ -63,6 +62,8 @@ interface NetworkMapService { val PUSH_ACK_PROTOCOL_TOPIC = "platform.network_map.push_ack" val logger = loggerFor() + + val type = ServiceType.corda.getSubType("network_map") } val nodes: List @@ -270,7 +271,7 @@ abstract class AbstractNetworkMapService // Update the current value atomically, so that if multiple updates come // in on different threads, there is no risk of a race condition while checking // sequence numbers. - val registrationInfo = registeredNodes.compute(node.identity, { mapKey: Party, existing: NodeRegistrationInfo? -> + val registrationInfo = registeredNodes.compute(node.legalIdentity, { mapKey: Party, existing: NodeRegistrationInfo? -> changed = existing == null || existing.reg.serial < change.serial if (changed) { when (change.type) { @@ -332,7 +333,7 @@ class NodeRegistration(val node: NodeInfo, val serial: Long, val type: AddOrRemo */ fun toWire(privateKey: PrivateKey): WireNodeRegistration { val regSerialized = this.serialize() - val regSig = privateKey.signWithECDSA(regSerialized.bits, node.identity.owningKey) + val regSig = privateKey.signWithECDSA(regSerialized.bits, node.legalIdentity.owningKey) return WireNodeRegistration(regSerialized, regSig) } @@ -346,7 +347,7 @@ class NodeRegistration(val node: NodeInfo, val serial: Long, val type: AddOrRemo class WireNodeRegistration(raw: SerializedBytes, sig: DigitalSignature.WithKey) : SignedData(raw, sig) { @Throws(IllegalArgumentException::class) override fun verifyData(data: NodeRegistration) { - require(data.node.identity.owningKey == sig.by) + require(data.node.legalIdentity.owningKey == sig.by) } } diff --git a/node/src/main/kotlin/com/r3corda/node/services/persistence/StorageServiceImpl.kt b/node/src/main/kotlin/com/r3corda/node/services/persistence/StorageServiceImpl.kt index 6a6705c06b..4fd26b2e43 100644 --- a/node/src/main/kotlin/com/r3corda/node/services/persistence/StorageServiceImpl.kt +++ b/node/src/main/kotlin/com/r3corda/node/services/persistence/StorageServiceImpl.kt @@ -1,16 +1,12 @@ package com.r3corda.node.services.persistence -import com.r3corda.core.crypto.Party import com.r3corda.core.node.services.AttachmentStorage import com.r3corda.core.node.services.StateMachineRecordedTransactionMappingStorage import com.r3corda.core.node.services.TransactionStorage import com.r3corda.core.node.services.TxWritableStorageService import com.r3corda.core.serialization.SingletonSerializeAsToken -import java.security.KeyPair open class StorageServiceImpl(override val attachments: AttachmentStorage, override val validatedTransactions: TransactionStorage, - override val stateMachineRecordedTransactionMapping: StateMachineRecordedTransactionMappingStorage, - override val myLegalIdentityKey: KeyPair, - override val myLegalIdentity: Party = Party("Unit test party", myLegalIdentityKey.public)) + override val stateMachineRecordedTransactionMapping: StateMachineRecordedTransactionMappingStorage) : SingletonSerializeAsToken(), TxWritableStorageService diff --git a/node/src/main/kotlin/com/r3corda/node/services/statemachine/ProtocolStateMachineImpl.kt b/node/src/main/kotlin/com/r3corda/node/services/statemachine/ProtocolStateMachineImpl.kt index bb4d1dda2a..b763b40197 100644 --- a/node/src/main/kotlin/com/r3corda/node/services/statemachine/ProtocolStateMachineImpl.kt +++ b/node/src/main/kotlin/com/r3corda/node/services/statemachine/ProtocolStateMachineImpl.kt @@ -187,7 +187,7 @@ class ProtocolStateMachineImpl(override val id: StateMachineRunId, val session = ProtocolSession(sessionProtocol, otherParty, random63BitValue(), null) openSessions[Pair(sessionProtocol, otherParty)] = session val counterpartyProtocol = sessionProtocol.getCounterpartyMarker(otherParty).name - val sessionInit = SessionInit(session.ourSessionId, serviceHub.storageService.myLegalIdentity, counterpartyProtocol) + val sessionInit = SessionInit(session.ourSessionId, serviceHub.myInfo.legalIdentity, counterpartyProtocol) val sessionInitResponse = sendAndReceiveInternal(session, sessionInit, SessionInitResponse::class.java) if (sessionInitResponse is SessionConfirm) { session.otherPartySessionId = sessionInitResponse.initiatedSessionId diff --git a/node/src/main/kotlin/com/r3corda/node/services/statemachine/StateMachineManager.kt b/node/src/main/kotlin/com/r3corda/node/services/statemachine/StateMachineManager.kt index bc7141c7d2..3a75fb61b0 100644 --- a/node/src/main/kotlin/com/r3corda/node/services/statemachine/StateMachineManager.kt +++ b/node/src/main/kotlin/com/r3corda/node/services/statemachine/StateMachineManager.kt @@ -386,7 +386,7 @@ class StateMachineManager(val serviceHub: ServiceHubInternal, } private fun sendSessionMessage(party: Party, message: SessionMessage, psm: ProtocolStateMachineImpl<*>?) { - val node = serviceHub.networkMapCache.getNodeByLegalName(party.name) + val node = serviceHub.networkMapCache.getNodeByPublicKey(party.owningKey) ?: throw IllegalArgumentException("Don't know about party $party") val logger = psm?.logger ?: logger logger.trace { "${psm?.id} sending $message to party $party" } diff --git a/node/src/main/kotlin/com/r3corda/node/services/transactions/NotaryService.kt b/node/src/main/kotlin/com/r3corda/node/services/transactions/NotaryService.kt index d0688a265e..1b9a1937b7 100644 --- a/node/src/main/kotlin/com/r3corda/node/services/transactions/NotaryService.kt +++ b/node/src/main/kotlin/com/r3corda/node/services/transactions/NotaryService.kt @@ -5,6 +5,7 @@ import com.r3corda.core.node.services.ServiceType import com.r3corda.core.serialization.SingletonSerializeAsToken import com.r3corda.node.services.api.ServiceHubInternal import com.r3corda.protocols.NotaryProtocol +import kotlin.reflect.KClass /** * A Notary service acts as the final signer of a transaction ensuring two things: @@ -16,9 +17,6 @@ import com.r3corda.protocols.NotaryProtocol * This is the base implementation that can be customised with specific Notary transaction commit protocol. */ abstract class NotaryService(services: ServiceHubInternal) : SingletonSerializeAsToken() { - // Do not specify this as an advertised service. Use a concrete implementation. - // TODO: We do not want a service type that cannot be used. Fix the type system abuse here. - object Type : ServiceType("corda.notary") init { services.registerProtocolInitiator(NotaryProtocol.Client::class) { createProtocol(it) } diff --git a/node/src/main/kotlin/com/r3corda/node/services/transactions/SimpleNotaryService.kt b/node/src/main/kotlin/com/r3corda/node/services/transactions/SimpleNotaryService.kt index 2f0fc51e0f..e36d016422 100644 --- a/node/src/main/kotlin/com/r3corda/node/services/transactions/SimpleNotaryService.kt +++ b/node/src/main/kotlin/com/r3corda/node/services/transactions/SimpleNotaryService.kt @@ -12,7 +12,9 @@ import com.r3corda.protocols.NotaryProtocol class SimpleNotaryService(services: ServiceHubInternal, val timestampChecker: TimestampChecker, val uniquenessProvider: UniquenessProvider) : NotaryService(services) { - object Type : ServiceType("corda.notary.simple") + companion object { + val type = ServiceType.notary.getSubType("simple") + } override fun createProtocol(otherParty: Party): NotaryProtocol.Service { return NotaryProtocol.Service(otherParty, timestampChecker, uniquenessProvider) diff --git a/node/src/main/kotlin/com/r3corda/node/services/transactions/ValidatingNotaryService.kt b/node/src/main/kotlin/com/r3corda/node/services/transactions/ValidatingNotaryService.kt index 01ae4ad02b..82f00b1051 100644 --- a/node/src/main/kotlin/com/r3corda/node/services/transactions/ValidatingNotaryService.kt +++ b/node/src/main/kotlin/com/r3corda/node/services/transactions/ValidatingNotaryService.kt @@ -11,7 +11,9 @@ import com.r3corda.protocols.ValidatingNotaryProtocol class ValidatingNotaryService(services: ServiceHubInternal, val timestampChecker: TimestampChecker, val uniquenessProvider: UniquenessProvider) : NotaryService(services) { - object Type : ServiceType("corda.notary.validating") + companion object { + val type = ServiceType.notary.getSubType("validating") + } override fun createProtocol(otherParty: Party): ValidatingNotaryProtocol { return ValidatingNotaryProtocol(otherParty, timestampChecker, uniquenessProvider) diff --git a/node/src/test/kotlin/com/r3corda/node/ServerRPCTest.kt b/node/src/test/kotlin/com/r3corda/node/ServerRPCTest.kt index 419a763181..fc6acf55b7 100644 --- a/node/src/test/kotlin/com/r3corda/node/ServerRPCTest.kt +++ b/node/src/test/kotlin/com/r3corda/node/ServerRPCTest.kt @@ -38,9 +38,9 @@ class ServerRPCTest { @Before fun setup() { network = MockNetwork() - val networkMap = network.createNode(advertisedServices = ServiceInfo(NetworkMapService.Type)) + val networkMap = network.createNode(advertisedServices = ServiceInfo(NetworkMapService.type)) aliceNode = network.createNode(networkMapAddress = networkMap.info.address) - notaryNode = network.createNode(advertisedServices = ServiceInfo(SimpleNotaryService.Type), networkMapAddress = networkMap.info.address) + notaryNode = network.createNode(advertisedServices = ServiceInfo(SimpleNotaryService.type), networkMapAddress = networkMap.info.address) rpc = ServerRPCOps(aliceNode.services, aliceNode.smm, aliceNode.database) stateMachineUpdates = rpc.stateMachinesAndUpdates().second @@ -57,13 +57,13 @@ class ServerRPCTest { assertFalse(aliceNode.services.vaultService.currentVault.states.iterator().hasNext()) // Tell the monitoring service node to issue some cash - val recipient = aliceNode.services.storageService.myLegalIdentity - val outEvent = ClientToServiceCommand.IssueCash(Amount(quantity, GBP), ref, recipient, DUMMY_NOTARY) + val recipient = aliceNode.info.legalIdentity + val outEvent = ClientToServiceCommand.IssueCash(Amount(quantity, GBP), ref, recipient, notaryNode.info.notaryIdentity) rpc.executeCommand(outEvent) network.runNetwork() val expectedState = Cash.State(Amount(quantity, - Issued(aliceNode.services.storageService.myLegalIdentity.ref(ref), GBP)), + Issued(aliceNode.info.legalIdentity.ref(ref), GBP)), recipient.owningKey) var issueSmId: StateMachineRunId? = null @@ -99,15 +99,15 @@ class ServerRPCTest { rpc.executeCommand(ClientToServiceCommand.IssueCash( amount = Amount(100, USD), issueRef = OpaqueBytes(ByteArray(1, { 1 })), - recipient = aliceNode.services.storageService.myLegalIdentity, - notary = notaryNode.services.storageService.myLegalIdentity + recipient = aliceNode.info.legalIdentity, + notary = notaryNode.info.notaryIdentity )) network.runNetwork() rpc.executeCommand(ClientToServiceCommand.PayCash( - amount = Amount(100, Issued(PartyAndReference(aliceNode.services.storageService.myLegalIdentity, OpaqueBytes(ByteArray(1, { 1 }))), USD)), - recipient = aliceNode.services.storageService.myLegalIdentity + amount = Amount(100, Issued(PartyAndReference(aliceNode.info.legalIdentity, OpaqueBytes(ByteArray(1, { 1 }))), USD)), + recipient = aliceNode.info.legalIdentity )) network.runNetwork() @@ -142,7 +142,7 @@ class ServerRPCTest { val signaturePubKeys = tx.sigs.map { it.by }.toSet() // Only Alice signed require(signaturePubKeys.size == 1) - require(signaturePubKeys.contains(aliceNode.services.storageService.myLegalIdentity.owningKey)) + require(signaturePubKeys.contains(aliceNode.info.legalIdentity.owningKey)) }, // MOVE expect { tx -> @@ -151,8 +151,8 @@ class ServerRPCTest { val signaturePubKeys = tx.sigs.map { it.by }.toSet() // Alice and Notary signed require(signaturePubKeys.size == 2) - require(signaturePubKeys.contains(aliceNode.services.storageService.myLegalIdentity.owningKey)) - require(signaturePubKeys.contains(notaryNode.services.storageService.myLegalIdentity.owningKey)) + require(signaturePubKeys.contains(aliceNode.info.legalIdentity.owningKey)) + require(signaturePubKeys.contains(notaryNode.info.notaryIdentity.owningKey)) } ) } diff --git a/node/src/test/kotlin/com/r3corda/node/messaging/AttachmentTests.kt b/node/src/test/kotlin/com/r3corda/node/messaging/AttachmentTests.kt index d4da41bda0..95cbc6a742 100644 --- a/node/src/test/kotlin/com/r3corda/node/messaging/AttachmentTests.kt +++ b/node/src/test/kotlin/com/r3corda/node/messaging/AttachmentTests.kt @@ -54,7 +54,7 @@ class AttachmentTests { // Get node one to run a protocol to fetch it and insert it. network.runNetwork() - val f1 = n1.services.startProtocol("tests.fetch1", FetchAttachmentsProtocol(setOf(id), n0.info.identity)) + val f1 = n1.services.startProtocol("tests.fetch1", FetchAttachmentsProtocol(setOf(id), n0.info.legalIdentity)) network.runNetwork() assertEquals(0, f1.get().fromDisk.size) @@ -65,7 +65,7 @@ class AttachmentTests { // Shut down node zero and ensure node one can still resolve the attachment. n0.stop() - val response: FetchDataProtocol.Result = n1.services.startProtocol("tests.fetch1", FetchAttachmentsProtocol(setOf(id), n0.info.identity)).get() + val response: FetchDataProtocol.Result = n1.services.startProtocol("tests.fetch1", FetchAttachmentsProtocol(setOf(id), n0.info.legalIdentity)).get() assertEquals(attachment, response.fromDisk[0]) } @@ -76,7 +76,7 @@ class AttachmentTests { // Get node one to fetch a non-existent attachment. val hash = SecureHash.randomSHA256() network.runNetwork() - val f1 = n1.services.startProtocol("tests.fetch2", FetchAttachmentsProtocol(setOf(hash), n0.info.identity)) + val f1 = n1.services.startProtocol("tests.fetch2", FetchAttachmentsProtocol(setOf(hash), n0.info.legalIdentity)) network.runNetwork() val e = assertFailsWith { rootCauseExceptions { f1.get() } } assertEquals(hash, e.requested) @@ -96,7 +96,7 @@ class AttachmentTests { } } } - }, true, null, null, ServiceInfo(NetworkMapService.Type), ServiceInfo(SimpleNotaryService.Type)) + }, true, null, null, ServiceInfo(NetworkMapService.type), ServiceInfo(SimpleNotaryService.type)) val n1 = network.createNode(n0.info.address) // Insert an attachment into node zero's store directly. @@ -109,7 +109,7 @@ class AttachmentTests { // Get n1 to fetch the attachment. Should receive corrupted bytes. network.runNetwork() - val f1 = n1.services.startProtocol("tests.fetch1", FetchAttachmentsProtocol(setOf(id), n0.info.identity)) + val f1 = n1.services.startProtocol("tests.fetch1", FetchAttachmentsProtocol(setOf(id), n0.info.legalIdentity)) network.runNetwork() assertFailsWith { rootCauseExceptions { f1.get() } diff --git a/node/src/test/kotlin/com/r3corda/node/messaging/InMemoryMessagingTests.kt b/node/src/test/kotlin/com/r3corda/node/messaging/InMemoryMessagingTests.kt index 49f1fc36ab..f14850173c 100644 --- a/node/src/test/kotlin/com/r3corda/node/messaging/InMemoryMessagingTests.kt +++ b/node/src/test/kotlin/com/r3corda/node/messaging/InMemoryMessagingTests.kt @@ -41,7 +41,7 @@ class InMemoryMessagingTests { @Test fun basics() { - val node1 = network.createNode(advertisedServices = ServiceInfo(NetworkMapService.Type)) + val node1 = network.createNode(advertisedServices = ServiceInfo(NetworkMapService.type)) val node2 = network.createNode(networkMapAddress = node1.info.address) val node3 = network.createNode(networkMapAddress = node1.info.address) @@ -70,7 +70,7 @@ class InMemoryMessagingTests { @Test fun broadcast() { - val node1 = network.createNode(advertisedServices = ServiceInfo(NetworkMapService.Type)) + val node1 = network.createNode(advertisedServices = ServiceInfo(NetworkMapService.type)) val node2 = network.createNode(networkMapAddress = node1.info.address) val node3 = network.createNode(networkMapAddress = node1.info.address) @@ -89,7 +89,7 @@ class InMemoryMessagingTests { */ @Test fun `skip unhandled messages`() { - val node1 = network.createNode(advertisedServices = ServiceInfo(NetworkMapService.Type)) + val node1 = network.createNode(advertisedServices = ServiceInfo(NetworkMapService.type)) val node2 = network.createNode(networkMapAddress = node1.info.address) var received: Int = 0 diff --git a/node/src/test/kotlin/com/r3corda/node/messaging/TwoPartyTradeProtocolTests.kt b/node/src/test/kotlin/com/r3corda/node/messaging/TwoPartyTradeProtocolTests.kt index 76d79d4869..2b455bb1a2 100644 --- a/node/src/test/kotlin/com/r3corda/node/messaging/TwoPartyTradeProtocolTests.kt +++ b/node/src/test/kotlin/com/r3corda/node/messaging/TwoPartyTradeProtocolTests.kt @@ -8,11 +8,11 @@ import com.r3corda.core.crypto.Party import com.r3corda.core.crypto.SecureHash import com.r3corda.core.days import com.r3corda.core.messaging.SingleMessageRecipient -import com.r3corda.core.node.ServiceHub import com.r3corda.core.node.services.* import com.r3corda.core.protocols.ProtocolStateMachine import com.r3corda.core.protocols.StateMachineRunId import com.r3corda.core.transactions.SignedTransaction +import com.r3corda.core.transactions.TransactionBuilder import com.r3corda.core.transactions.WireTransaction import com.r3corda.core.utilities.DUMMY_NOTARY import com.r3corda.core.utilities.DUMMY_NOTARY_KEY @@ -85,16 +85,20 @@ class TwoPartyTradeProtocolTests { notaryNode = net.createNotaryNode(DUMMY_NOTARY.name, DUMMY_NOTARY_KEY) aliceNode = net.createPartyNode(notaryNode.info.address, ALICE.name, ALICE_KEY) bobNode = net.createPartyNode(notaryNode.info.address, BOB.name, BOB_KEY) + val aliceKey = aliceNode.services.legalIdentityKey + val notaryKey = notaryNode.services.notaryIdentityKey aliceNode.disableDBCloseOnStop() bobNode.disableDBCloseOnStop() databaseTransaction(bobNode.database) { - bobNode.services.fillWithSomeTestCash(2000.DOLLARS) + bobNode.services.fillWithSomeTestCash(2000.DOLLARS, outputNotary = notaryNode.info.notaryIdentity) } - val alicesFakePaper = fillUpForSeller(false, aliceNode.storage.myLegalIdentity.owningKey, - 1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, null).second - insertFakeTransactions(alicesFakePaper, aliceNode, aliceNode.storage.myLegalIdentityKey, notaryNode.storage.myLegalIdentityKey) + val alicesFakePaper = fillUpForSeller(false, aliceNode.info.legalIdentity.owningKey, + 1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, null, notaryNode.info.notaryIdentity).second + + insertFakeTransactions(alicesFakePaper, aliceNode, aliceKey, notaryKey) + val (bobPsm, aliceResult) = runBuyerAndSeller("alice's paper".outputStateAndRef()) // TODO: Verify that the result was inserted into the transaction database. @@ -121,6 +125,8 @@ class TwoPartyTradeProtocolTests { notaryNode = net.createNotaryNode(DUMMY_NOTARY.name, DUMMY_NOTARY_KEY) aliceNode = net.createPartyNode(notaryNode.info.address, ALICE.name, ALICE_KEY) bobNode = net.createPartyNode(notaryNode.info.address, BOB.name, BOB_KEY) + val aliceKey = aliceNode.services.legalIdentityKey + val notaryKey = notaryNode.services.notaryIdentityKey val bobAddr = bobNode.net.myAddress as InMemoryMessagingNetwork.Handle val networkMapAddr = notaryNode.info.address @@ -128,11 +134,11 @@ class TwoPartyTradeProtocolTests { net.runNetwork() // Clear network map registration messages databaseTransaction(bobNode.database) { - bobNode.services.fillWithSomeTestCash(2000.DOLLARS) + bobNode.services.fillWithSomeTestCash(2000.DOLLARS, outputNotary = notaryNode.info.notaryIdentity) } - val alicesFakePaper = fillUpForSeller(false, aliceNode.storage.myLegalIdentity.owningKey, - 1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, null).second - insertFakeTransactions(alicesFakePaper, aliceNode, aliceNode.storage.myLegalIdentityKey) + val alicesFakePaper = fillUpForSeller(false, aliceNode.info.legalIdentity.owningKey, + 1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, null, notaryNode.info.notaryIdentity).second + insertFakeTransactions(alicesFakePaper, aliceNode, aliceKey, notaryKey) val aliceFuture = runBuyerAndSeller("alice's paper".outputStateAndRef()).sellerResult // Everything is on this thread so we can now step through the protocol one step at a time. @@ -200,11 +206,9 @@ class TwoPartyTradeProtocolTests { override fun constructStorageService( attachments: NodeAttachmentService, transactionStorage: TransactionStorage, - stateMachineRecordedTransactionMappingStorage: StateMachineRecordedTransactionMappingStorage, - keyPair: KeyPair, - identity: Party + stateMachineRecordedTransactionMappingStorage: StateMachineRecordedTransactionMappingStorage ): StorageServiceImpl { - return StorageServiceImpl(attachments, RecordingTransactionStorage(transactionStorage), stateMachineRecordedTransactionMappingStorage, keyPair, identity) + return StorageServiceImpl(attachments, RecordingTransactionStorage(transactionStorage), stateMachineRecordedTransactionMappingStorage) } } } @@ -216,6 +220,7 @@ class TwoPartyTradeProtocolTests { notaryNode = net.createNotaryNode(DUMMY_NOTARY.name, DUMMY_NOTARY_KEY) aliceNode = makeNodeWithTracking(notaryNode.info.address, ALICE.name, ALICE_KEY) bobNode = makeNodeWithTracking(notaryNode.info.address, BOB.name, BOB_KEY) + val aliceKey = aliceNode.services.legalIdentityKey ledger(aliceNode.services) { @@ -228,11 +233,11 @@ class TwoPartyTradeProtocolTests { } val attachmentID = attachment(ByteArrayInputStream(stream.toByteArray())) - val bobsFakeCash = fillUpForBuyer(false, bobNode.keyManagement.freshKey().public).second + val bobsFakeCash = fillUpForBuyer(false, bobNode.keyManagement.freshKey().public, notaryNode.info.notaryIdentity).second val bobsSignedTxns = insertFakeTransactions(bobsFakeCash, bobNode) - val alicesFakePaper = fillUpForSeller(false, aliceNode.storage.myLegalIdentity.owningKey, - 1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, attachmentID).second - val alicesSignedTxns = insertFakeTransactions(alicesFakePaper, aliceNode, aliceNode.storage.myLegalIdentityKey) + val alicesFakePaper = fillUpForSeller(false, aliceNode.info.legalIdentity.owningKey, + 1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, attachmentID, notaryNode.info.notaryIdentity).second + val alicesSignedTxns = insertFakeTransactions(alicesFakePaper, aliceNode, aliceKey) net.runNetwork() // Clear network map registration messages @@ -307,6 +312,7 @@ class TwoPartyTradeProtocolTests { notaryNode = net.createNotaryNode(DUMMY_NOTARY.name, DUMMY_NOTARY_KEY) aliceNode = makeNodeWithTracking(notaryNode.info.address, ALICE.name, ALICE_KEY) bobNode = makeNodeWithTracking(notaryNode.info.address, BOB.name, BOB_KEY) + val aliceKey = aliceNode.services.legalIdentityKey ledger(aliceNode.services) { @@ -319,11 +325,11 @@ class TwoPartyTradeProtocolTests { } val attachmentID = attachment(ByteArrayInputStream(stream.toByteArray())) - val bobsFakeCash = fillUpForBuyer(false, bobNode.keyManagement.freshKey().public).second + val bobsFakeCash = fillUpForBuyer(false, bobNode.keyManagement.freshKey().public, notaryNode.info.notaryIdentity).second insertFakeTransactions(bobsFakeCash, bobNode) - val alicesFakePaper = fillUpForSeller(false, aliceNode.storage.myLegalIdentity.owningKey, - 1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, attachmentID).second - insertFakeTransactions(alicesFakePaper, aliceNode, aliceNode.storage.myLegalIdentityKey) + val alicesFakePaper = fillUpForSeller(false, aliceNode.info.legalIdentity.owningKey, + 1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, attachmentID, notaryNode.info.notaryIdentity).second + insertFakeTransactions(alicesFakePaper, aliceNode, aliceKey) net.runNetwork() // Clear network map registration messages @@ -387,9 +393,9 @@ class TwoPartyTradeProtocolTests { private fun runBuyerAndSeller(assetToSell: StateAndRef) : RunResult { val buyerFuture = bobNode.initiateSingleShotProtocol(Seller::class) { otherParty -> - Buyer(otherParty, notaryNode.info.identity, 1000.DOLLARS, CommercialPaper.State::class.java) + Buyer(otherParty, notaryNode.info.notaryIdentity, 1000.DOLLARS, CommercialPaper.State::class.java) } - val seller = Seller(bobNode.info.identity, notaryNode.info, assetToSell, 1000.DOLLARS, ALICE_KEY) + val seller = Seller(bobNode.info.legalIdentity, notaryNode.info, assetToSell, 1000.DOLLARS, ALICE_KEY) val sellerResultFuture = aliceNode.smm.add("seller", seller).resultFuture return RunResult(buyerFuture, sellerResultFuture, seller.psm.id) } @@ -402,15 +408,16 @@ class TwoPartyTradeProtocolTests { notaryNode = net.createNotaryNode(DUMMY_NOTARY.name, DUMMY_NOTARY_KEY) aliceNode = net.createPartyNode(notaryNode.info.address, ALICE.name, ALICE_KEY) bobNode = net.createPartyNode(notaryNode.info.address, BOB.name, BOB_KEY) + val aliceKey = aliceNode.services.legalIdentityKey + val bobKey = bobNode.services.legalIdentityKey val issuer = MEGA_CORP.ref(1, 2, 3) - val bobKey = bobNode.keyManagement.freshKey() - val bobsBadCash = fillUpForBuyer(bobError, bobKey.public).second - val alicesFakePaper = fillUpForSeller(aliceError, aliceNode.storage.myLegalIdentity.owningKey, - 1200.DOLLARS `issued by` issuer, null).second + val bobsBadCash = fillUpForBuyer(bobError, bobKey.public, notaryNode.info.notaryIdentity).second + val alicesFakePaper = fillUpForSeller(aliceError, aliceNode.info.legalIdentity.owningKey, + 1200.DOLLARS `issued by` issuer, null, notaryNode.info.notaryIdentity).second - insertFakeTransactions(bobsBadCash, bobNode, bobNode.storage.myLegalIdentityKey, bobNode.storage.myLegalIdentityKey) - insertFakeTransactions(alicesFakePaper, aliceNode, aliceNode.storage.myLegalIdentityKey) + insertFakeTransactions(bobsBadCash, bobNode, bobKey) + insertFakeTransactions(alicesFakePaper, aliceNode, aliceKey) net.runNetwork() // Clear network map registration messages @@ -452,14 +459,15 @@ class TwoPartyTradeProtocolTests { private fun LedgerDSL.fillUpForBuyer( withError: Boolean, - owner: PublicKey = BOB_PUBKEY): Pair> { + owner: PublicKey = BOB_PUBKEY, + notary: Party): Pair> { val issuer = DUMMY_CASH_ISSUER // Bob (Buyer) has some cash he got from the Bank of Elbonia, Alice (Seller) has some commercial paper she // wants to sell to Bob. - val eb1 = transaction { + val eb1 = transaction(transactionBuilder = TransactionBuilder(notary = notary)) { // Issued money to itself. - output("elbonian money 1") { 800.DOLLARS.CASH `issued by` issuer `owned by` MEGA_CORP_PUBKEY } - output("elbonian money 2") { 1000.DOLLARS.CASH `issued by` issuer `owned by` MEGA_CORP_PUBKEY } + output("elbonian money 1", notary = notary) { 800.DOLLARS.CASH `issued by` issuer `owned by` MEGA_CORP_PUBKEY } + output("elbonian money 2", notary = notary) { 1000.DOLLARS.CASH `issued by` issuer `owned by` MEGA_CORP_PUBKEY } if (!withError) command(DUMMY_CASH_ISSUER_KEY.public) { Cash.Commands.Issue() } else @@ -474,17 +482,17 @@ class TwoPartyTradeProtocolTests { } // Bob gets some cash onto the ledger from BoE - val bc1 = transaction { + val bc1 = transaction(transactionBuilder = TransactionBuilder(notary = notary)) { input("elbonian money 1") - output("bob cash 1") { 800.DOLLARS.CASH `issued by` issuer `owned by` owner } + output("bob cash 1", notary = notary) { 800.DOLLARS.CASH `issued by` issuer `owned by` owner } command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() } this.verifies() } - val bc2 = transaction { + val bc2 = transaction(transactionBuilder = TransactionBuilder(notary = notary)) { input("elbonian money 2") - output("bob cash 2") { 300.DOLLARS.CASH `issued by` issuer `owned by` owner } - output { 700.DOLLARS.CASH `issued by` issuer `owned by` MEGA_CORP_PUBKEY } // Change output. + output("bob cash 2", notary = notary) { 300.DOLLARS.CASH `issued by` issuer `owned by` owner } + output(notary = notary) { 700.DOLLARS.CASH `issued by` issuer `owned by` MEGA_CORP_PUBKEY } // Change output. command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() } this.verifies() } @@ -497,9 +505,10 @@ class TwoPartyTradeProtocolTests { withError: Boolean, owner: PublicKey, amount: Amount>, - attachmentID: SecureHash?): Pair> { - val ap = transaction { - output("alice's paper") { + attachmentID: SecureHash?, + notary: Party): Pair> { + val ap = transaction(transactionBuilder = TransactionBuilder(notary = notary)) { + output("alice's paper", notary = notary) { CommercialPaper.State(MEGA_CORP.ref(1, 2, 3), owner, amount, TEST_TX_TIME + 7.days) } command(MEGA_CORP_PUBKEY) { CommercialPaper.Commands.Issue() } diff --git a/node/src/test/kotlin/com/r3corda/node/services/InMemoryNetworkMapServiceTest.kt b/node/src/test/kotlin/com/r3corda/node/services/InMemoryNetworkMapServiceTest.kt index 6550da4fc3..b3373edd05 100644 --- a/node/src/test/kotlin/com/r3corda/node/services/InMemoryNetworkMapServiceTest.kt +++ b/node/src/test/kotlin/com/r3corda/node/services/InMemoryNetworkMapServiceTest.kt @@ -41,19 +41,19 @@ abstract class AbstractNetworkMapServiceTest { // Confirm the service contains no nodes as own node only registered if network is run. assertEquals(0, service().nodes.count()) - assertNull(service().processQueryRequest(NetworkMapService.QueryIdentityRequest(registerNode.info.identity, mapServiceNode.info.address, Long.MIN_VALUE)).node) + assertNull(service().processQueryRequest(NetworkMapService.QueryIdentityRequest(registerNode.info.legalIdentity, mapServiceNode.info.address, Long.MIN_VALUE)).node) // Register the new node val instant = Instant.now() val expires = instant + NetworkMapService.DEFAULT_EXPIRATION_PERIOD - val nodeKey = registerNode.storage.myLegalIdentityKey + val nodeKey = registerNode.services.legalIdentityKey val addChange = NodeRegistration(registerNode.info, instant.toEpochMilli(), AddOrRemove.ADD, expires) val addWireChange = addChange.toWire(nodeKey.private) service().processRegistrationChangeRequest(RegistrationRequest(addWireChange, mapServiceNode.info.address, Long.MIN_VALUE)) swizzle() assertEquals(1, service().nodes.count()) - assertEquals(registerNode.info, service().processQueryRequest(NetworkMapService.QueryIdentityRequest(registerNode.info.identity, mapServiceNode.info.address, Long.MIN_VALUE)).node) + assertEquals(registerNode.info, service().processQueryRequest(NetworkMapService.QueryIdentityRequest(registerNode.info.legalIdentity, mapServiceNode.info.address, Long.MIN_VALUE)).node) // Re-registering should be a no-op service().processRegistrationChangeRequest(RegistrationRequest(addWireChange, mapServiceNode.info.address, Long.MIN_VALUE)) @@ -67,7 +67,7 @@ abstract class AbstractNetworkMapServiceTest { assert(service().processRegistrationChangeRequest(RegistrationRequest(removeWireChange, mapServiceNode.info.address, Long.MIN_VALUE)).success) swizzle() - assertNull(service().processQueryRequest(NetworkMapService.QueryIdentityRequest(registerNode.info.identity, mapServiceNode.info.address, Long.MIN_VALUE)).node) + assertNull(service().processQueryRequest(NetworkMapService.QueryIdentityRequest(registerNode.info.legalIdentity, mapServiceNode.info.address, Long.MIN_VALUE)).node) swizzle() // Trying to de-register a node that doesn't exist should fail @@ -88,7 +88,7 @@ abstract class AbstractNetworkMapServiceTest { assertEquals(2, fetchPsm.get()?.count()) // Forcibly deregister the second node - val nodeKey = registerNode.storage.myLegalIdentityKey + val nodeKey = registerNode.services.legalIdentityKey val instant = Instant.now() val expires = instant + NetworkMapService.DEFAULT_EXPIRATION_PERIOD val reg = NodeRegistration(registerNode.info, instant.toEpochMilli()+1, AddOrRemove.REMOVE, expires) @@ -126,7 +126,7 @@ abstract class AbstractNetworkMapServiceTest { assertEquals(0, service().getUnacknowledgedCount(registerNode.info.address, startingMapVersion)) // Fire off an update - val nodeKey = registerNode.storage.myLegalIdentityKey + val nodeKey = registerNode.services.legalIdentityKey var seq = 0L val expires = Instant.now() + NetworkMapService.DEFAULT_EXPIRATION_PERIOD var reg = NodeRegistration(registerNode.info, seq++, AddOrRemove.ADD, expires) diff --git a/node/src/test/kotlin/com/r3corda/node/services/MockServiceHubInternal.kt b/node/src/test/kotlin/com/r3corda/node/services/MockServiceHubInternal.kt index 1f67a3726a..76e59bd383 100644 --- a/node/src/test/kotlin/com/r3corda/node/services/MockServiceHubInternal.kt +++ b/node/src/test/kotlin/com/r3corda/node/services/MockServiceHubInternal.kt @@ -3,6 +3,7 @@ package com.r3corda.node.services import com.codahale.metrics.MetricRegistry import com.google.common.util.concurrent.ListenableFuture import com.r3corda.core.crypto.Party +import com.r3corda.core.node.NodeInfo import com.r3corda.core.node.services.* import com.r3corda.core.protocols.ProtocolLogic import com.r3corda.core.protocols.ProtocolLogicRefFactory @@ -51,6 +52,8 @@ open class MockServiceHubInternal( get() = scheduler ?: throw UnsupportedOperationException() override val clock: Clock get() = overrideClock ?: throw UnsupportedOperationException() + override val myInfo: NodeInfo + get() = throw UnsupportedOperationException() override val monitoringService: MonitoringService = MonitoringService(MetricRegistry()) override val protocolLogicRefFactory: ProtocolLogicRefFactory diff --git a/node/src/test/kotlin/com/r3corda/node/services/NodeSchedulerServiceTest.kt b/node/src/test/kotlin/com/r3corda/node/services/NodeSchedulerServiceTest.kt index 3fdfb28195..d941efe38e 100644 --- a/node/src/test/kotlin/com/r3corda/node/services/NodeSchedulerServiceTest.kt +++ b/node/src/test/kotlin/com/r3corda/node/services/NodeSchedulerServiceTest.kt @@ -259,7 +259,7 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() { private fun scheduleTX(instant: Instant, increment: Int = 1): ScheduledStateRef? { var scheduledRef: ScheduledStateRef? = null apply { - val freshKey = services.storageService.myLegalIdentityKey + val freshKey = services.keyManagementService.freshKey() val state = TestState(factory.create(TestProtocolLogic::class.java, increment), instant) val usefulTX = TransactionType.General.Builder(null).apply { addOutputState(state, DUMMY_NOTARY) diff --git a/node/src/test/kotlin/com/r3corda/node/services/NotaryChangeTests.kt b/node/src/test/kotlin/com/r3corda/node/services/NotaryChangeTests.kt index 2e126891e1..a037cff3e5 100644 --- a/node/src/test/kotlin/com/r3corda/node/services/NotaryChangeTests.kt +++ b/node/src/test/kotlin/com/r3corda/node/services/NotaryChangeTests.kt @@ -36,18 +36,18 @@ class NotaryChangeTests { oldNotaryNode = net.createNode( legalName = DUMMY_NOTARY.name, keyPair = DUMMY_NOTARY_KEY, - advertisedServices = *arrayOf(ServiceInfo(NetworkMapService.Type), ServiceInfo(SimpleNotaryService.Type))) + advertisedServices = *arrayOf(ServiceInfo(NetworkMapService.type), ServiceInfo(SimpleNotaryService.type))) clientNodeA = net.createNode(networkMapAddress = oldNotaryNode.info.address) clientNodeB = net.createNode(networkMapAddress = oldNotaryNode.info.address) - newNotaryNode = net.createNode(networkMapAddress = oldNotaryNode.info.address, advertisedServices = ServiceInfo(SimpleNotaryService.Type)) + newNotaryNode = net.createNode(networkMapAddress = oldNotaryNode.info.address, advertisedServices = ServiceInfo(SimpleNotaryService.type)) net.runNetwork() // Clear network map registration messages } @Test fun `should change notary for a state with single participant`() { - val state = issueState(clientNodeA) - val newNotary = newNotaryNode.info.identity + val state = issueState(clientNodeA, oldNotaryNode) + val newNotary = newNotaryNode.info.notaryIdentity val protocol = Instigator(state, newNotary) val future = clientNodeA.services.startProtocol("notary-change", protocol) @@ -59,8 +59,8 @@ class NotaryChangeTests { @Test fun `should change notary for a state with multiple participants`() { - val state = issueMultiPartyState(clientNodeA, clientNodeB) - val newNotary = newNotaryNode.info.identity + val state = issueMultiPartyState(clientNodeA, clientNodeB, oldNotaryNode) + val newNotary = newNotaryNode.info.notaryIdentity val protocol = Instigator(state, newNotary) val future = clientNodeA.services.startProtocol("notary-change", protocol) @@ -75,7 +75,7 @@ class NotaryChangeTests { @Test fun `should throw when a participant refuses to change Notary`() { - val state = issueMultiPartyState(clientNodeA, clientNodeB) + val state = issueMultiPartyState(clientNodeA, clientNodeB, oldNotaryNode) val newEvilNotary = Party("Evil Notary", generateKeyPair().public) val protocol = Instigator(state, newEvilNotary) val future = clientNodeA.services.startProtocol("notary-change", protocol) @@ -96,22 +96,27 @@ class NotaryChangeTests { // - The transaction type is not a notary change transaction at all. } -fun issueState(node: AbstractNode): StateAndRef<*> { - val tx = DummyContract.generateInitial(node.info.identity.ref(0), Random().nextInt(), DUMMY_NOTARY) - tx.signWith(node.storage.myLegalIdentityKey) - tx.signWith(DUMMY_NOTARY_KEY) +fun issueState(node: AbstractNode, notaryNode: AbstractNode): StateAndRef<*> { + val tx = DummyContract.generateInitial(node.info.legalIdentity.ref(0), Random().nextInt(), notaryNode.info.notaryIdentity) + val nodeKey = node.services.legalIdentityKey + tx.signWith(nodeKey) + val notaryKeyPair = notaryNode.services.notaryIdentityKey + tx.signWith(notaryKeyPair) val stx = tx.toSignedTransaction() node.services.recordTransactions(listOf(stx)) return StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0)) } -fun issueMultiPartyState(nodeA: AbstractNode, nodeB: AbstractNode): StateAndRef { +fun issueMultiPartyState(nodeA: AbstractNode, nodeB: AbstractNode, notaryNode: AbstractNode): StateAndRef { val state = TransactionState(DummyContract.MultiOwnerState(0, - listOf(nodeA.info.identity.owningKey, nodeB.info.identity.owningKey)), DUMMY_NOTARY) - val tx = TransactionType.NotaryChange.Builder(DUMMY_NOTARY).withItems(state) - tx.signWith(nodeA.storage.myLegalIdentityKey) - tx.signWith(nodeB.storage.myLegalIdentityKey) - tx.signWith(DUMMY_NOTARY_KEY) + listOf(nodeA.info.legalIdentity.owningKey, nodeB.info.legalIdentity.owningKey)), notaryNode.info.notaryIdentity) + val tx = TransactionType.NotaryChange.Builder(notaryNode.info.notaryIdentity).withItems(state) + val nodeAKey = nodeA.services.legalIdentityKey + val nodeBKey = nodeB.services.legalIdentityKey + tx.signWith(nodeAKey) + tx.signWith(nodeBKey) + val notaryKeyPair = notaryNode.services.notaryIdentityKey + tx.signWith(notaryKeyPair) val stx = tx.toSignedTransaction() nodeA.services.recordTransactions(listOf(stx)) nodeB.services.recordTransactions(listOf(stx)) @@ -119,11 +124,12 @@ fun issueMultiPartyState(nodeA: AbstractNode, nodeB: AbstractNode): StateAndRef< return stateAndRef } -fun issueInvalidState(node: AbstractNode, notary: Party = DUMMY_NOTARY): StateAndRef<*> { - val tx = DummyContract.generateInitial(node.info.identity.ref(0), Random().nextInt(), notary) +fun issueInvalidState(node: AbstractNode, notary: Party): StateAndRef<*> { + val tx = DummyContract.generateInitial(node.info.legalIdentity.ref(0), Random().nextInt(), notary) tx.setTime(Instant.now(), 30.seconds) - tx.signWith(node.storage.myLegalIdentityKey) + val nodeKey = node.services.legalIdentityKey + tx.signWith(nodeKey) val stx = tx.toSignedTransaction(false) node.services.recordTransactions(listOf(stx)) return StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0)) -} +} \ No newline at end of file diff --git a/node/src/test/kotlin/com/r3corda/node/services/NotaryServiceTests.kt b/node/src/test/kotlin/com/r3corda/node/services/NotaryServiceTests.kt index 11be246277..bf49cf7018 100644 --- a/node/src/test/kotlin/com/r3corda/node/services/NotaryServiceTests.kt +++ b/node/src/test/kotlin/com/r3corda/node/services/NotaryServiceTests.kt @@ -1,6 +1,9 @@ package com.r3corda.node.services import com.google.common.util.concurrent.ListenableFuture +import com.r3corda.core.contracts.DummyContract +import com.r3corda.core.contracts.StateAndRef +import com.r3corda.core.contracts.StateRef import com.r3corda.core.contracts.TransactionType import com.r3corda.core.node.services.ServiceInfo import com.r3corda.core.crypto.DigitalSignature @@ -8,6 +11,7 @@ import com.r3corda.core.seconds import com.r3corda.core.transactions.SignedTransaction import com.r3corda.core.utilities.DUMMY_NOTARY import com.r3corda.core.utilities.DUMMY_NOTARY_KEY +import com.r3corda.node.internal.AbstractNode import com.r3corda.node.services.network.NetworkMapService import com.r3corda.node.services.transactions.SimpleNotaryService import com.r3corda.protocols.NotaryError @@ -18,6 +22,7 @@ import com.r3corda.testing.node.MockNetwork import org.junit.Before import org.junit.Test import java.time.Instant +import java.util.* import java.util.concurrent.ExecutionException import kotlin.test.assertEquals import kotlin.test.assertFailsWith @@ -33,7 +38,7 @@ class NotaryServiceTests { notaryNode = net.createNode( legalName = DUMMY_NOTARY.name, keyPair = DUMMY_NOTARY_KEY, - advertisedServices = *arrayOf(ServiceInfo(NetworkMapService.Type), ServiceInfo(SimpleNotaryService.Type))) + advertisedServices = *arrayOf(ServiceInfo(NetworkMapService.type), ServiceInfo(SimpleNotaryService.type))) clientNode = net.createNode(networkMapAddress = notaryNode.info.address, keyPair = MINI_CORP_KEY) net.runNetwork() // Clear network map registration messages } @@ -41,7 +46,7 @@ class NotaryServiceTests { @Test fun `should sign a unique transaction with a valid timestamp`() { val stx = run { val inputState = issueState(clientNode) - val tx = TransactionType.General.Builder(DUMMY_NOTARY).withItems(inputState) + val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState) tx.setTime(Instant.now(), 30.seconds) tx.signWith(clientNode.keyPair!!) tx.toSignedTransaction(false) @@ -55,7 +60,7 @@ class NotaryServiceTests { @Test fun `should sign a unique transaction without a timestamp`() { val stx = run { val inputState = issueState(clientNode) - val tx = TransactionType.General.Builder(DUMMY_NOTARY).withItems(inputState) + val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState) tx.signWith(clientNode.keyPair!!) tx.toSignedTransaction(false) } @@ -68,7 +73,7 @@ class NotaryServiceTests { @Test fun `should report error for transaction with an invalid timestamp`() { val stx = run { val inputState = issueState(clientNode) - val tx = TransactionType.General.Builder(DUMMY_NOTARY).withItems(inputState) + val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState) tx.setTime(Instant.now().plusSeconds(3600), 30.seconds) tx.signWith(clientNode.keyPair!!) tx.toSignedTransaction(false) @@ -84,7 +89,7 @@ class NotaryServiceTests { @Test fun `should report conflict for a duplicate transaction`() { val stx = run { val inputState = issueState(clientNode) - val tx = TransactionType.General.Builder(DUMMY_NOTARY).withItems(inputState) + val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState) tx.signWith(clientNode.keyPair!!) tx.toSignedTransaction(false) } @@ -109,4 +114,15 @@ class NotaryServiceTests { net.runNetwork() return future } + + fun issueState(node: AbstractNode): StateAndRef<*> { + val tx = DummyContract.generateInitial(node.info.legalIdentity.ref(0), Random().nextInt(), notaryNode.info.notaryIdentity) + val nodeKey = node.services.legalIdentityKey + tx.signWith(nodeKey) + val notaryKeyPair = notaryNode.services.notaryIdentityKey + tx.signWith(notaryKeyPair) + val stx = tx.toSignedTransaction() + node.services.recordTransactions(listOf(stx)) + return StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0)) + } } \ No newline at end of file diff --git a/node/src/test/kotlin/com/r3corda/node/services/ValidatingNotaryServiceTests.kt b/node/src/test/kotlin/com/r3corda/node/services/ValidatingNotaryServiceTests.kt index 7ac20e3557..cd4464c613 100644 --- a/node/src/test/kotlin/com/r3corda/node/services/ValidatingNotaryServiceTests.kt +++ b/node/src/test/kotlin/com/r3corda/node/services/ValidatingNotaryServiceTests.kt @@ -1,14 +1,13 @@ package com.r3corda.node.services import com.google.common.util.concurrent.ListenableFuture -import com.r3corda.core.contracts.Command -import com.r3corda.core.contracts.DummyContract -import com.r3corda.core.contracts.TransactionType +import com.r3corda.core.contracts.* import com.r3corda.core.crypto.DigitalSignature import com.r3corda.core.node.services.ServiceInfo import com.r3corda.core.transactions.SignedTransaction import com.r3corda.core.utilities.DUMMY_NOTARY import com.r3corda.core.utilities.DUMMY_NOTARY_KEY +import com.r3corda.node.internal.AbstractNode import com.r3corda.node.services.network.NetworkMapService import com.r3corda.node.services.transactions.ValidatingNotaryService import com.r3corda.protocols.NotaryError @@ -20,6 +19,7 @@ import com.r3corda.testing.node.MockNetwork import org.assertj.core.api.Assertions.assertThat import org.junit.Before import org.junit.Test +import java.util.* import java.util.concurrent.ExecutionException import kotlin.test.assertEquals import kotlin.test.assertFailsWith @@ -34,7 +34,7 @@ class ValidatingNotaryServiceTests { notaryNode = net.createNode( legalName = DUMMY_NOTARY.name, keyPair = DUMMY_NOTARY_KEY, - advertisedServices = *arrayOf(ServiceInfo(NetworkMapService.Type), ServiceInfo(ValidatingNotaryService.Type)) + advertisedServices = *arrayOf(ServiceInfo(NetworkMapService.type), ServiceInfo(ValidatingNotaryService.type)) ) clientNode = net.createNode(networkMapAddress = notaryNode.info.address, keyPair = MINI_CORP_KEY) net.runNetwork() // Clear network map registration messages @@ -42,8 +42,8 @@ class ValidatingNotaryServiceTests { @Test fun `should report error for invalid transaction dependency`() { val stx = run { - val inputState = issueInvalidState(clientNode) - val tx = TransactionType.General.Builder(DUMMY_NOTARY).withItems(inputState) + val inputState = issueInvalidState(clientNode, notaryNode.info.notaryIdentity) + val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState) tx.signWith(clientNode.keyPair!!) tx.toSignedTransaction(false) } @@ -61,7 +61,7 @@ class ValidatingNotaryServiceTests { val inputState = issueState(clientNode) val command = Command(DummyContract.Commands.Move(), expectedMissingKey) - val tx = TransactionType.General.Builder(DUMMY_NOTARY).withItems(inputState, command) + val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState, command) tx.signWith(clientNode.keyPair!!) tx.toSignedTransaction(false) } @@ -82,4 +82,15 @@ class ValidatingNotaryServiceTests { net.runNetwork() return future } + + fun issueState(node: AbstractNode): StateAndRef<*> { + val tx = DummyContract.generateInitial(node.info.legalIdentity.ref(0), Random().nextInt(), notaryNode.info.notaryIdentity) + val nodeKey = node.services.legalIdentityKey + tx.signWith(nodeKey) + val notaryKeyPair = notaryNode.services.notaryIdentityKey + tx.signWith(notaryKeyPair) + val stx = tx.toSignedTransaction() + node.services.recordTransactions(listOf(stx)) + return StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0)) + } } \ No newline at end of file diff --git a/node/src/test/kotlin/com/r3corda/node/services/VaultWithCashTest.kt b/node/src/test/kotlin/com/r3corda/node/services/VaultWithCashTest.kt index 77bfa26815..957ab779fb 100644 --- a/node/src/test/kotlin/com/r3corda/node/services/VaultWithCashTest.kt +++ b/node/src/test/kotlin/com/r3corda/node/services/VaultWithCashTest.kt @@ -84,7 +84,7 @@ class VaultWithCashTest { fun `issue and spend total correctly and irrelevant ignored`() { databaseTransaction(database) { // A tx that sends us money. - val freshKey = services.storageService.myLegalIdentityKey + val freshKey = services.keyManagementService.freshKey() val usefulTX = TransactionType.General.Builder(null).apply { Cash().generateIssue(this, 100.DOLLARS `issued by` MEGA_CORP.ref(1), freshKey.public, DUMMY_NOTARY) signWith(MEGA_CORP_KEY) @@ -122,7 +122,7 @@ class VaultWithCashTest { @Test fun `branching LinearStates fails to verify`() { databaseTransaction(database) { - val freshKey = services.storageService.myLegalIdentityKey + val freshKey = services.keyManagementService.freshKey() val linearId = UniqueIdentifier() // Issue a linear state @@ -142,7 +142,7 @@ class VaultWithCashTest { @Test fun `sequencing LinearStates works`() { databaseTransaction(database) { - val freshKey = services.storageService.myLegalIdentityKey + val freshKey = services.keyManagementService.freshKey() val linearId = UniqueIdentifier() diff --git a/node/src/test/kotlin/com/r3corda/node/services/persistence/DataVendingServiceTests.kt b/node/src/test/kotlin/com/r3corda/node/services/persistence/DataVendingServiceTests.kt index 3a5c32c58a..511df2a146 100644 --- a/node/src/test/kotlin/com/r3corda/node/services/persistence/DataVendingServiceTests.kt +++ b/node/src/test/kotlin/com/r3corda/node/services/persistence/DataVendingServiceTests.kt @@ -33,8 +33,8 @@ class DataVendingServiceTests { @Test fun `notify of transaction`() { val (vaultServiceNode, registerNode) = network.createTwoNodes() - val beneficiary = vaultServiceNode.services.storageService.myLegalIdentityKey.public - val deposit = registerNode.services.storageService.myLegalIdentity.ref(1) + val beneficiary = vaultServiceNode.info.legalIdentity.owningKey + val deposit = registerNode.info.legalIdentity.ref(1) network.runNetwork() // Generate an issuance transaction @@ -42,7 +42,8 @@ class DataVendingServiceTests { Cash().generateIssue(ptx, Amount(100, Issued(deposit, USD)), beneficiary, DUMMY_NOTARY) // Complete the cash transaction, and then manually relay it - ptx.signWith(registerNode.services.storageService.myLegalIdentityKey) + val registerKey = registerNode.services.legalIdentityKey + ptx.signWith(registerKey) val tx = ptx.toSignedTransaction() assertEquals(0, vaultServiceNode.services.vaultService.currentVault.states.toList().size) @@ -61,7 +62,7 @@ class DataVendingServiceTests { @Test fun `notify failure`() { val (vaultServiceNode, registerNode) = network.createTwoNodes() - val beneficiary = vaultServiceNode.services.storageService.myLegalIdentityKey.public + val beneficiary = vaultServiceNode.info.legalIdentity.owningKey val deposit = MEGA_CORP.ref(1) network.runNetwork() @@ -70,7 +71,8 @@ class DataVendingServiceTests { Cash().generateIssue(ptx, Amount(100, Issued(deposit, USD)), beneficiary, DUMMY_NOTARY) // The transaction tries issuing MEGA_CORP cash, but we aren't the issuer, so it's invalid - ptx.signWith(registerNode.services.storageService.myLegalIdentityKey) + val registerKey = registerNode.services.legalIdentityKey + ptx.signWith(registerKey) val tx = ptx.toSignedTransaction(false) assertEquals(0, vaultServiceNode.services.vaultService.currentVault.states.toList().size) @@ -82,7 +84,7 @@ class DataVendingServiceTests { private fun MockNode.sendNotifyTx(tx: SignedTransaction, walletServiceNode: MockNode) { walletServiceNode.services.registerProtocolInitiator(NotifyTxProtocol::class, ::NotifyTransactionHandler) - services.startProtocol("notify-tx", NotifyTxProtocol(walletServiceNode.info.identity, tx)) + services.startProtocol("notify-tx", NotifyTxProtocol(walletServiceNode.info.legalIdentity, tx)) network.runNetwork() } diff --git a/node/src/test/kotlin/com/r3corda/node/services/statemachine/StateMachineManagerTests.kt b/node/src/test/kotlin/com/r3corda/node/services/statemachine/StateMachineManagerTests.kt index ad4db9413b..f512d1c5ce 100644 --- a/node/src/test/kotlin/com/r3corda/node/services/statemachine/StateMachineManagerTests.kt +++ b/node/src/test/kotlin/com/r3corda/node/services/statemachine/StateMachineManagerTests.kt @@ -60,7 +60,7 @@ class StateMachineManagerTests { fun `protocol restarted just after receiving payload`() { node2.services.registerProtocolInitiator(SendProtocol::class) { ReceiveThenSuspendProtocol(it) } val payload = random63BitValue() - node1.smm.add("test", SendProtocol(payload, node2.info.identity)) + node1.smm.add("test", SendProtocol(payload, node2.info.legalIdentity)) // We push through just enough messages to get only the SessionData sent // TODO We should be able to give runNetwork a predicate for when to stop @@ -108,7 +108,7 @@ class StateMachineManagerTests { fun `protocol loaded from checkpoint will respond to messages from before start`() { val payload = random63BitValue() node1.services.registerProtocolInitiator(ReceiveThenSuspendProtocol::class) { SendProtocol(payload, it) } - val receiveProtocol = ReceiveThenSuspendProtocol(node1.info.identity) + val receiveProtocol = ReceiveThenSuspendProtocol(node1.info.legalIdentity) node2.smm.add("test", receiveProtocol) // Prepare checkpointed receive protocol node2.stop() // kill receiver val restoredProtocol = node2.restartAndGetRestoredProtocol(node1.info.address) @@ -135,7 +135,7 @@ class StateMachineManagerTests { } // Kick off first send and receive - node2.smm.add("test", PingPongProtocol(node3.info.identity, payload)) + node2.smm.add("test", PingPongProtocol(node3.info.legalIdentity, payload)) assertEquals(1, node2.checkpointStorage.checkpoints().count()) // Restart node and thus reload the checkpoint and resend the message with same UUID node2.stop() @@ -165,7 +165,7 @@ class StateMachineManagerTests { node2.services.registerProtocolInitiator(SendProtocol::class) { ReceiveThenSuspendProtocol(it) } node3.services.registerProtocolInitiator(SendProtocol::class) { ReceiveThenSuspendProtocol(it) } val payload = random63BitValue() - node1.smm.add("multiple-send", SendProtocol(payload, node2.info.identity, node3.info.identity)) + node1.smm.add("multiple-send", SendProtocol(payload, node2.info.legalIdentity, node3.info.legalIdentity)) net.runNetwork() val node2Protocol = node2.getSingleProtocol().first val node3Protocol = node3.getSingleProtocol().first @@ -181,7 +181,7 @@ class StateMachineManagerTests { val node3Payload = random63BitValue() node2.services.registerProtocolInitiator(ReceiveThenSuspendProtocol::class) { SendProtocol(node2Payload, it) } node3.services.registerProtocolInitiator(ReceiveThenSuspendProtocol::class) { SendProtocol(node3Payload, it) } - val multiReceiveProtocol = ReceiveThenSuspendProtocol(node2.info.identity, node3.info.identity) + val multiReceiveProtocol = ReceiveThenSuspendProtocol(node2.info.legalIdentity, node3.info.legalIdentity) node1.smm.add("multiple-receive", multiReceiveProtocol) net.runNetwork(1) // session handshaking // have the messages arrive in reverse order of receive @@ -195,7 +195,7 @@ class StateMachineManagerTests { @Test fun `exception thrown on other side`() { node2.services.registerProtocolInitiator(ReceiveThenSuspendProtocol::class) { ExceptionProtocol } - val future = node1.smm.add("exception", ReceiveThenSuspendProtocol(node2.info.identity)).resultFuture + val future = node1.smm.add("exception", ReceiveThenSuspendProtocol(node2.info.legalIdentity)).resultFuture net.runNetwork() assertThatThrownBy { future.get() }.hasCauseInstanceOf(ProtocolSessionException::class.java) } diff --git a/src/main/kotlin/com/r3corda/demos/IRSDemo.kt b/src/main/kotlin/com/r3corda/demos/IRSDemo.kt index a3a95bb509..5c4cca863d 100644 --- a/src/main/kotlin/com/r3corda/demos/IRSDemo.kt +++ b/src/main/kotlin/com/r3corda/demos/IRSDemo.kt @@ -406,11 +406,11 @@ private fun startNode(params: CliParams.RunNode, networkMap: SingleMessageRecipi val networkMapId = when (params.node) { IRSDemoNode.NodeA -> { - advertisedServices = setOf(ServiceInfo(NetworkMapService.Type), ServiceInfo(SimpleNotaryService.Type)) + advertisedServices = setOf(ServiceInfo(NetworkMapService.type), ServiceInfo(SimpleNotaryService.type)) null } IRSDemoNode.NodeB -> { - advertisedServices = setOf(ServiceInfo(NodeInterestRates.Type)) + advertisedServices = setOf(ServiceInfo(NodeInterestRates.type)) networkMap } } @@ -475,7 +475,7 @@ private fun loadConfigFile(baseDir: Path, configFile: Path, configOverrides: Map private fun createIdentities(nodeConf: NodeConfiguration) { val mockNetwork = MockNetwork(false) - val node = MockNetwork.MockNode(nodeConf, mockNetwork, null, setOf(ServiceInfo(NetworkMapService.Type), ServiceInfo(SimpleNotaryService.Type)), 0, null) + val node = MockNetwork.MockNode(nodeConf, mockNetwork, null, setOf(ServiceInfo(NetworkMapService.type), ServiceInfo(SimpleNotaryService.type)), 0, null) node.start() node.stop() } diff --git a/src/main/kotlin/com/r3corda/demos/RateFixDemo.kt b/src/main/kotlin/com/r3corda/demos/RateFixDemo.kt index 99d59ae42b..5b3d996711 100644 --- a/src/main/kotlin/com/r3corda/demos/RateFixDemo.kt +++ b/src/main/kotlin/com/r3corda/demos/RateFixDemo.kt @@ -78,12 +78,12 @@ fun main(args: Array) { } node.networkMapRegistrationFuture.get() val notaryNode = node.services.networkMapCache.notaryNodes[0] - val rateOracle = node.services.networkMapCache.get(InterestRateSwap.OracleType).first() + val rateOracle = node.services.networkMapCache.get(InterestRateSwap.oracleType).first() // Make a garbage transaction that includes a rate fix. - val tx = TransactionType.General.Builder(notaryNode.identity) - tx.addOutputState(TransactionState(Cash.State(1500.DOLLARS `issued by` node.storage.myLegalIdentity.ref(1), node.storage.myLegalIdentityKey.public), notaryNode.identity)) - val protocol = RatesFixProtocol(tx, rateOracle.identity, fixOf, expectedRate, rateTolerance) + val tx = TransactionType.General.Builder(notaryNode.notaryIdentity) + tx.addOutputState(TransactionState(Cash.State(1500.DOLLARS `issued by` node.info.legalIdentity.ref(1), node.info.legalIdentity.owningKey), notaryNode.notaryIdentity)) + val protocol = RatesFixProtocol(tx, rateOracle.serviceIdentities(InterestRateSwap.oracleType).first(), fixOf, expectedRate, rateTolerance) node.services.startProtocol("demo.ratefix", protocol).get() node.stop() diff --git a/src/main/kotlin/com/r3corda/demos/TraderDemo.kt b/src/main/kotlin/com/r3corda/demos/TraderDemo.kt index bdb31dd9f8..65e425b91d 100644 --- a/src/main/kotlin/com/r3corda/demos/TraderDemo.kt +++ b/src/main/kotlin/com/r3corda/demos/TraderDemo.kt @@ -141,7 +141,7 @@ fun main(args: Array) { // the map is not very helpful, but we need one anyway. So just make the buyer side run the network map as it's // the side that sticks around waiting for the seller. val networkMapId = if (role == Role.BUYER) { - advertisedServices = setOf(ServiceInfo(NetworkMapService.Type), ServiceInfo(SimpleNotaryService.Type)) + advertisedServices = setOf(ServiceInfo(NetworkMapService.type), ServiceInfo(SimpleNotaryService.type)) null } else { advertisedServices = emptySet() @@ -160,7 +160,7 @@ fun main(args: Array) { runBuyer(node, amount) } else { node.networkMapRegistrationFuture.success { - val party = node.netMapCache.getNodeByLegalName("Bank A")?.identity ?: throw IllegalStateException("Cannot find other node?!") + val party = node.netMapCache.getNodeByLegalName("Bank A")?.legalIdentity ?: throw IllegalStateException("Cannot find other node?!") runSeller(node, amount, party) } } @@ -211,8 +211,8 @@ private fun runBuyer(node: Node, amount: Amount) { // TODO: At some point this demo should be extended to have a central bank node. databaseTransaction(node.database) { node.services.fillWithSomeTestCash(300000.DOLLARS, - outputNotary = node.info.identity, // In this demo, the buyer and notary are the same. - ownedBy = node.storage.myLegalIdentityKey.public) + outputNotary = node.info.notaryIdentity, // In this demo, the buyer and notary are on the same node, but need to use right key. + ownedBy = node.info.legalIdentity.owningKey) } // Wait around until a node asks to start a trade with us. In a real system, this part would happen out of band @@ -241,7 +241,7 @@ private class TraderDemoProtocolBuyer(val otherSide: Party, val notary: NodeInfo = serviceHub.networkMapCache.notaryNodes[0] val buyer = TwoPartyTradeProtocol.Buyer( otherSide, - notary.identity, + notary.notaryIdentity, amount, CommercialPaper.State::class.java) @@ -304,7 +304,7 @@ private class TraderDemoProtocolSeller(val otherSide: Party, progressTracker.currentStep = SELF_ISSUING val notary: NodeInfo = serviceHub.networkMapCache.notaryNodes[0] - val cpOwnerKey = serviceHub.storageService.myLegalIdentityKey + val cpOwnerKey = serviceHub.legalIdentityKey val commercialPaper = selfIssueSomeCommercialPaper(cpOwnerKey.public, notary) progressTracker.currentStep = TRADING @@ -330,7 +330,7 @@ private class TraderDemoProtocolSeller(val otherSide: Party, val issuance: SignedTransaction = run { val tx = CommercialPaper().generateIssue(party.ref(1, 2, 3), 1100.DOLLARS `issued by` DUMMY_CASH_ISSUER, - Instant.now() + 10.days, notaryNode.identity) + Instant.now() + 10.days, notaryNode.notaryIdentity) // TODO: Consider moving these two steps below into generateIssue. @@ -356,7 +356,7 @@ private class TraderDemoProtocolSeller(val otherSide: Party, // Now make a dummy transaction that moves it to a new key, just to show that resolving dependencies works. val move: SignedTransaction = run { - val builder = TransactionType.General.Builder(notaryNode.identity) + val builder = TransactionType.General.Builder(notaryNode.notaryIdentity) CommercialPaper().generateMove(builder, issuance.tx.outRef(0), ownedBy) builder.signWith(keyPair) val notarySignature = subProtocol(NotaryProtocol.Client(builder.toSignedTransaction(false))) diff --git a/src/main/kotlin/com/r3corda/demos/api/NodeInterestRates.kt b/src/main/kotlin/com/r3corda/demos/api/NodeInterestRates.kt index b2c797476f..c9d193293e 100644 --- a/src/main/kotlin/com/r3corda/demos/api/NodeInterestRates.kt +++ b/src/main/kotlin/com/r3corda/demos/api/NodeInterestRates.kt @@ -42,7 +42,7 @@ import javax.annotation.concurrent.ThreadSafe * for signing. */ object NodeInterestRates { - object Type : ServiceType("corda.interest_rates") + val type = ServiceType.corda.getSubType("interest_rates") /** * Register the protocol that is used with the Fixing integration tests. @@ -55,25 +55,31 @@ object NodeInterestRates { /** * The Service that wraps [Oracle] and handles messages/network interaction/request scrubbing. */ - class Service(services: ServiceHubInternal) : AcceptsFileUpload, SingletonSerializeAsToken() { - val ss = services.storageService - val oracle = Oracle(ss.myLegalIdentity, ss.myLegalIdentityKey, services.clock) - - init { - services.registerProtocolInitiator(FixSignProtocol::class) { FixSignHandler(it, oracle) } - services.registerProtocolInitiator(FixQueryProtocol::class) { FixQueryHandler(it, oracle) } + class Service(val services: ServiceHubInternal) : AcceptsFileUpload, SingletonSerializeAsToken() { + val oracle: Oracle by lazy { + val myNodeInfo = services.myInfo + val myIdentity = myNodeInfo.serviceIdentities(type).first() + val mySigningKey = services.keyManagementService.toKeyPair(myIdentity.owningKey) + Oracle(myIdentity, mySigningKey, services.clock) } + init { + // Note access to the singleton oracle property is via the registered SingletonSerializeAsToken Service. + // Otherwise the Kryo serialisation of the call stack in the Quasar Fiber extends to include + // the framework Oracle and the protocol will crash. + services.registerProtocolInitiator(FixSignProtocol::class) { FixSignHandler(it, this) } + services.registerProtocolInitiator(FixQueryProtocol::class) { FixQueryHandler(it, this) } + } - private class FixSignHandler(val otherParty: Party, val oracle: Oracle) : ProtocolLogic() { + private class FixSignHandler(val otherParty: Party, val service: Service) : ProtocolLogic() { @Suspendable override fun call() { val request = receive(otherParty).unwrap { it } - send(otherParty, oracle.sign(request.tx)) + send(otherParty, service.oracle.sign(request.tx)) } } - private class FixQueryHandler(val otherParty: Party, val oracle: Oracle) : ProtocolLogic() { + private class FixQueryHandler(val otherParty: Party, val service: Service) : ProtocolLogic() { companion object { object RECEIVED : ProgressTracker.Step("Received fix request") @@ -89,7 +95,7 @@ object NodeInterestRates { @Suspendable override fun call(): Unit { val request = receive(otherParty).unwrap { it } - val answers = oracle.query(request.queries, request.deadline) + val answers = service.oracle.query(request.queries, request.deadline) progressTracker.currentStep = SENDING send(otherParty, answers) } diff --git a/src/main/kotlin/com/r3corda/demos/attachment/AttachmentDemo.kt b/src/main/kotlin/com/r3corda/demos/attachment/AttachmentDemo.kt index 14fc1a19c9..f39b8a2648 100644 --- a/src/main/kotlin/com/r3corda/demos/attachment/AttachmentDemo.kt +++ b/src/main/kotlin/com/r3corda/demos/attachment/AttachmentDemo.kt @@ -111,7 +111,7 @@ fun main(args: Array) { // the map is not very helpful, but we need one anyway. So just make the recipient side run the network map as it's // the side that sticks around waiting for the sender. val networkMapId = if (role == Role.SENDER) { - advertisedServices = setOf(ServiceInfo(NetworkMapService.Type), ServiceInfo(SimpleNotaryService.Type)) + advertisedServices = setOf(ServiceInfo(NetworkMapService.type), ServiceInfo(SimpleNotaryService.type)) null } else { advertisedServices = emptySet() @@ -131,7 +131,7 @@ fun main(args: Array) { node.networkMapRegistrationFuture.success { // Pause a moment to give the network map time to update Thread.sleep(100L) - val party = node.netMapCache.getNodeByLegalName(Role.RECIPIENT.legalName)?.identity ?: throw IllegalStateException("Cannot find other node?!") + val party = node.netMapCache.getNodeByLegalName(Role.RECIPIENT.legalName)?.legalIdentity ?: throw IllegalStateException("Cannot find other node?!") runSender(node, party) } } diff --git a/src/main/kotlin/com/r3corda/demos/protocols/AutoOfferProtocol.kt b/src/main/kotlin/com/r3corda/demos/protocols/AutoOfferProtocol.kt index c9674a7de3..4ee8da873f 100644 --- a/src/main/kotlin/com/r3corda/demos/protocols/AutoOfferProtocol.kt +++ b/src/main/kotlin/com/r3corda/demos/protocols/AutoOfferProtocol.kt @@ -62,14 +62,15 @@ object AutoOfferProtocol { @Suspendable override fun call(): SignedTransaction { require(serviceHub.networkMapCache.notaryNodes.isNotEmpty()) { "No notary nodes registered" } - val notary = serviceHub.networkMapCache.notaryNodes.first().identity + val notary = serviceHub.networkMapCache.notaryNodes.first().notaryIdentity // need to pick which ever party is not us val otherParty = notUs(dealToBeOffered.parties).single() progressTracker.currentStep = DEALING + val myKey = serviceHub.legalIdentityKey val instigator = Instigator( otherParty, AutoOffer(notary, dealToBeOffered), - serviceHub.storageService.myLegalIdentityKey, + myKey, progressTracker.getChildProgressTracker(DEALING)!! ) val stx = subProtocol(instigator) @@ -79,7 +80,7 @@ object AutoOfferProtocol { private fun notUs(parties: List): List { val notUsParties: MutableList = arrayListOf() for (party in parties) { - if (serviceHub.storageService.myLegalIdentity != party) { + if (serviceHub.myInfo.legalIdentity != party) { notUsParties.add(party) } } diff --git a/src/main/kotlin/com/r3corda/demos/protocols/ExitServerProtocol.kt b/src/main/kotlin/com/r3corda/demos/protocols/ExitServerProtocol.kt index 8a8b750f9a..49ac326493 100644 --- a/src/main/kotlin/com/r3corda/demos/protocols/ExitServerProtocol.kt +++ b/src/main/kotlin/com/r3corda/demos/protocols/ExitServerProtocol.kt @@ -66,7 +66,7 @@ object ExitServerProtocol { if (recipient.address is MockNetworkMapCache.MockAddress) { // Ignore } else { - send(recipient.identity, ExitMessage(exitCode)) + send(recipient.legalIdentity, ExitMessage(exitCode)) } } } diff --git a/src/main/kotlin/com/r3corda/demos/protocols/UpdateBusinessDayProtocol.kt b/src/main/kotlin/com/r3corda/demos/protocols/UpdateBusinessDayProtocol.kt index b3c3e92a66..69c6e02c89 100644 --- a/src/main/kotlin/com/r3corda/demos/protocols/UpdateBusinessDayProtocol.kt +++ b/src/main/kotlin/com/r3corda/demos/protocols/UpdateBusinessDayProtocol.kt @@ -60,7 +60,7 @@ object UpdateBusinessDayProtocol { if (recipient.address is MockNetworkMapCache.MockAddress) { // Ignore } else { - send(recipient.identity, UpdateBusinessDayMessage(date)) + send(recipient.legalIdentity, UpdateBusinessDayMessage(date)) } } } diff --git a/src/main/kotlin/com/r3corda/simulation/IRSSimulation.kt b/src/main/kotlin/com/r3corda/simulation/IRSSimulation.kt index 64cd030afb..9292114463 100644 --- a/src/main/kotlin/com/r3corda/simulation/IRSSimulation.kt +++ b/src/main/kotlin/com/r3corda/simulation/IRSSimulation.kt @@ -108,15 +108,15 @@ class IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, laten // have the convenient copy() method that'd let us make small adjustments. Instead they're partly mutable. // TODO: We should revisit this in post-Excalibur cleanup and fix, e.g. by introducing an interface. val irs = om.readValue(javaClass.getResource("trade.json")) - irs.fixedLeg.fixedRatePayer = node1.info.identity - irs.floatingLeg.floatingRatePayer = node2.info.identity + irs.fixedLeg.fixedRatePayer = node1.info.legalIdentity + irs.floatingLeg.floatingRatePayer = node2.info.legalIdentity val acceptorTx = node2.initiateSingleShotProtocol(Instigator::class) { Acceptor(it) }.flatMap { it.resultFuture } showProgressFor(listOf(node1, node2)) showConsensusFor(listOf(node1, node2, regulators[0])) - val instigator = Instigator(node2.info.identity, AutoOffer(notary.info.identity, irs), node1.keyPair!!) + val instigator = Instigator(node2.info.legalIdentity, AutoOffer(notary.info.notaryIdentity, irs), node1.keyPair!!) val instigatorTx = node1.services.startProtocol("instigator", instigator) return Futures.allAsList(instigatorTx, acceptorTx).flatMap { instigatorTx } diff --git a/src/main/kotlin/com/r3corda/simulation/Simulation.kt b/src/main/kotlin/com/r3corda/simulation/Simulation.kt index b7a2aa5e02..6f868144a1 100644 --- a/src/main/kotlin/com/r3corda/simulation/Simulation.kt +++ b/src/main/kotlin/com/r3corda/simulation/Simulation.kt @@ -87,7 +87,7 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, object NetworkMapNodeFactory : MockNetwork.Factory { override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, advertisedServices: Set, id: Int, keyPair: KeyPair?): MockNetwork.MockNode { - require(advertisedServices.containsType(NetworkMapService.Type)) + require(advertisedServices.containsType(NetworkMapService.type)) // TODO: create a base class that provides a default implementation val cfg = object : NodeConfiguration { @@ -109,7 +109,7 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, object NotaryNodeFactory : MockNetwork.Factory { override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, advertisedServices: Set, id: Int, keyPair: KeyPair?): MockNetwork.MockNode { - require(advertisedServices.containsType(SimpleNotaryService.Type)) + require(advertisedServices.containsType(SimpleNotaryService.type)) // TODO: create a base class that provides a default implementation val cfg = object : NodeConfiguration { @@ -130,7 +130,7 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, object RatesOracleFactory : MockNetwork.Factory { override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, advertisedServices: Set, id: Int, keyPair: KeyPair?): MockNetwork.MockNode { - require(advertisedServices.containsType(NodeInterestRates.Type)) + require(advertisedServices.containsType(NodeInterestRates.type)) // TODO: create a base class that provides a default implementation val cfg = object : NodeConfiguration { @@ -188,12 +188,12 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, val network = MockNetwork(networkSendManuallyPumped, runAsync) // This one must come first. val networkMap: SimulatedNode - = network.createNode(null, nodeFactory = NetworkMapNodeFactory, advertisedServices = ServiceInfo(NetworkMapService.Type)) as SimulatedNode + = network.createNode(null, nodeFactory = NetworkMapNodeFactory, advertisedServices = ServiceInfo(NetworkMapService.type)) as SimulatedNode val notary: SimulatedNode - = network.createNode(networkMap.info.address, nodeFactory = NotaryNodeFactory, advertisedServices = ServiceInfo(SimpleNotaryService.Type)) as SimulatedNode + = network.createNode(networkMap.info.address, nodeFactory = NotaryNodeFactory, advertisedServices = ServiceInfo(SimpleNotaryService.type)) as SimulatedNode val regulators: List = listOf(network.createNode(networkMap.info.address, start = false, nodeFactory = RegulatorFactory) as SimulatedNode) val ratesOracle: SimulatedNode - = network.createNode(networkMap.info.address, start = false, nodeFactory = RatesOracleFactory, advertisedServices = ServiceInfo(NodeInterestRates.Type)) as SimulatedNode + = network.createNode(networkMap.info.address, start = false, nodeFactory = RatesOracleFactory, advertisedServices = ServiceInfo(NodeInterestRates.type)) as SimulatedNode // All nodes must be in one of these two lists for the purposes of the visualiser tool. val serviceProviders: List = listOf(notary, ratesOracle, networkMap) diff --git a/src/main/kotlin/com/r3corda/simulation/TradeSimulation.kt b/src/main/kotlin/com/r3corda/simulation/TradeSimulation.kt index ff9e8e3913..2fec17455f 100644 --- a/src/main/kotlin/com/r3corda/simulation/TradeSimulation.kt +++ b/src/main/kotlin/com/r3corda/simulation/TradeSimulation.kt @@ -33,14 +33,16 @@ class TradeSimulation(runAsync: Boolean, latencyInjector: InMemoryMessagingNetwo val buyer = banks[buyerBankIndex] val seller = banks[sellerBankIndex] - buyer.services.fillWithSomeTestCash(1500.DOLLARS, notary.info.identity) + buyer.services.fillWithSomeTestCash(1500.DOLLARS, notary.info.notaryIdentity) val issuance = run { - val tx = CommercialPaper().generateIssue(seller.info.identity.ref(1, 2, 3), 1100.DOLLARS `issued by` DUMMY_CASH_ISSUER, - Instant.now() + 10.days, notary.info.identity) + val tx = CommercialPaper().generateIssue(seller.info.legalIdentity.ref(1, 2, 3), 1100.DOLLARS `issued by` DUMMY_CASH_ISSUER, + Instant.now() + 10.days, notary.info.notaryIdentity) tx.setTime(Instant.now(), 30.seconds) - tx.signWith(notary.storage.myLegalIdentityKey) - tx.signWith(seller.storage.myLegalIdentityKey) + val notaryKey = notary.services.notaryIdentityKey + val sellerKey = seller.services.legalIdentityKey + tx.signWith(notaryKey) + tx.signWith(sellerKey) tx.toSignedTransaction(true) } seller.services.recordTransactions(issuance) @@ -48,15 +50,16 @@ class TradeSimulation(runAsync: Boolean, latencyInjector: InMemoryMessagingNetwo val amount = 1000.DOLLARS val buyerFuture = buyer.initiateSingleShotProtocol(Seller::class) { - Buyer(it, notary.info.identity, amount, CommercialPaper.State::class.java) + Buyer(it, notary.info.notaryIdentity, amount, CommercialPaper.State::class.java) }.flatMap { it.resultFuture } + val sellerKey = seller.services.legalIdentityKey val sellerProtocol = Seller( - buyer.info.identity, + buyer.info.legalIdentity, notary.info, issuance.tx.outRef(0), amount, - seller.storage.myLegalIdentityKey) + sellerKey) showConsensusFor(listOf(buyer, seller, notary)) showProgressFor(listOf(buyer, seller)) diff --git a/src/test/kotlin/com/r3corda/core/testing/NodeInterestRatesTest.kt b/src/test/kotlin/com/r3corda/core/testing/NodeInterestRatesTest.kt index bfa48353fb..ed991749ed 100644 --- a/src/test/kotlin/com/r3corda/core/testing/NodeInterestRatesTest.kt +++ b/src/test/kotlin/com/r3corda/core/testing/NodeInterestRatesTest.kt @@ -11,6 +11,7 @@ import com.r3corda.core.contracts.TransactionType import com.r3corda.core.contracts.`with notary` import com.r3corda.core.crypto.Party import com.r3corda.core.crypto.generateKeyPair +import com.r3corda.core.node.services.ServiceInfo import com.r3corda.core.utilities.DUMMY_NOTARY import com.r3corda.core.utilities.LogHelper import com.r3corda.testing.node.MockNetwork @@ -141,13 +142,14 @@ class NodeInterestRatesTest { @Test fun network() { val net = MockNetwork() - val (n1, n2) = net.createTwoNodes() + val n1 = net.createNotaryNode() + val n2 = net.createNode(n1.info.address, advertisedServices = ServiceInfo(NodeInterestRates.type)) databaseTransaction(n2.database) { n2.findService().oracle.knownFixes = TEST_DATA } val tx = TransactionType.General.Builder(null) val fixOf = NodeInterestRates.parseFixOf("LIBOR 2016-03-16 1M") - val protocol = RatesFixProtocol(tx, n2.info.identity, fixOf, "0.675".bd, "0.1".bd) + val protocol = RatesFixProtocol(tx, n2.info.serviceIdentities(NodeInterestRates.type).first(), fixOf, "0.675".bd, "0.1".bd) LogHelper.setLevel("rates") net.runNetwork() val future = n1.services.startProtocol("rates", protocol) diff --git a/test-utils/src/main/kotlin/com/r3corda/testing/node/MockNetworkMapCache.kt b/test-utils/src/main/kotlin/com/r3corda/testing/node/MockNetworkMapCache.kt index a72a2069d8..c1c1274266 100644 --- a/test-utils/src/main/kotlin/com/r3corda/testing/node/MockNetworkMapCache.kt +++ b/test-utils/src/main/kotlin/com/r3corda/testing/node/MockNetworkMapCache.kt @@ -20,8 +20,8 @@ class MockNetworkMapCache() : com.r3corda.node.services.network.InMemoryNetworkM init { val mockNodeA = NodeInfo(MockAddress("bankC:8080"), Party("Bank C", DummyPublicKey("Bank C"))) val mockNodeB = NodeInfo(MockAddress("bankD:8080"), Party("Bank D", DummyPublicKey("Bank D"))) - registeredNodes[mockNodeA.identity] = mockNodeA - registeredNodes[mockNodeB.identity] = mockNodeB + registeredNodes[mockNodeA.legalIdentity] = mockNodeA + registeredNodes[mockNodeB.legalIdentity] = mockNodeB runWithoutMapService() } @@ -31,7 +31,7 @@ class MockNetworkMapCache() : com.r3corda.node.services.network.InMemoryNetworkM */ @VisibleForTesting fun addRegistration(node: NodeInfo) { - registeredNodes[node.identity] = node + registeredNodes[node.legalIdentity] = node } /** @@ -39,7 +39,7 @@ class MockNetworkMapCache() : com.r3corda.node.services.network.InMemoryNetworkM * not a change being received. */ @VisibleForTesting - fun deleteRegistration(identity: Party) : Boolean { - return registeredNodes.remove(identity) != null + fun deleteRegistration(legalIdentity: Party) : Boolean { + return registeredNodes.remove(legalIdentity) != null } } \ No newline at end of file diff --git a/test-utils/src/main/kotlin/com/r3corda/testing/node/MockNode.kt b/test-utils/src/main/kotlin/com/r3corda/testing/node/MockNode.kt index a122f78b31..fe3548adca 100644 --- a/test-utils/src/main/kotlin/com/r3corda/testing/node/MockNode.kt +++ b/test-utils/src/main/kotlin/com/r3corda/testing/node/MockNode.kt @@ -107,7 +107,7 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false, override fun makeVaultService(): VaultService = InMemoryVaultService(services) - override fun makeKeyManagementService(): KeyManagementService = E2ETestKeyManagementService(setOf(storage.myLegalIdentityKey)) + override fun makeKeyManagementService(): KeyManagementService = E2ETestKeyManagementService(partyKeys) override fun startMessagingService(cordaRPCOps: CordaRPCOps?) { // Nothing to do @@ -129,7 +129,7 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false, override fun start(): MockNode { super.start() - mockNet.identities.add(storage.myLegalIdentity) + mockNet.identities.add(info.legalIdentity) return this } @@ -212,7 +212,7 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false, fun createTwoNodes(nodeFactory: Factory = defaultFactory, notaryKeyPair: KeyPair? = null): Pair { require(nodes.isEmpty()) return Pair( - createNode(null, -1, nodeFactory, true, null, notaryKeyPair, ServiceInfo(NetworkMapService.Type), ServiceInfo(SimpleNotaryService.Type)), + createNode(null, -1, nodeFactory, true, null, notaryKeyPair, ServiceInfo(NetworkMapService.type), ServiceInfo(SimpleNotaryService.type)), createNode(nodes[0].info.address, -1, nodeFactory, true, null) ) } @@ -229,9 +229,9 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false, */ fun createSomeNodes(numPartyNodes: Int = 2, nodeFactory: Factory = defaultFactory, notaryKeyPair: KeyPair? = DUMMY_NOTARY_KEY): BasketOfNodes { require(nodes.isEmpty()) - val mapNode = createNode(null, nodeFactory = nodeFactory, advertisedServices = ServiceInfo(NetworkMapService.Type)) + val mapNode = createNode(null, nodeFactory = nodeFactory, advertisedServices = ServiceInfo(NetworkMapService.type)) val notaryNode = createNode(mapNode.info.address, nodeFactory = nodeFactory, keyPair = notaryKeyPair, - advertisedServices = ServiceInfo(SimpleNotaryService.Type)) + advertisedServices = ServiceInfo(SimpleNotaryService.type)) val nodes = ArrayList() repeat(numPartyNodes) { nodes += createPartyNode(mapNode.info.address) @@ -240,7 +240,7 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false, } fun createNotaryNode(legalName: String? = null, keyPair: KeyPair? = null): MockNode { - return createNode(null, -1, defaultFactory, true, legalName, keyPair, ServiceInfo(NetworkMapService.Type), ServiceInfo(SimpleNotaryService.Type)) + return createNode(null, -1, defaultFactory, true, legalName, keyPair, ServiceInfo(NetworkMapService.type), ServiceInfo(SimpleNotaryService.type)) } fun createPartyNode(networkMapAddr: SingleMessageRecipient, legalName: String? = null, keyPair: KeyPair? = null): MockNode { diff --git a/test-utils/src/main/kotlin/com/r3corda/testing/node/MockServices.kt b/test-utils/src/main/kotlin/com/r3corda/testing/node/MockServices.kt index 262a9d59bc..531eb3d6a0 100644 --- a/test-utils/src/main/kotlin/com/r3corda/testing/node/MockServices.kt +++ b/test-utils/src/main/kotlin/com/r3corda/testing/node/MockServices.kt @@ -7,6 +7,8 @@ import com.r3corda.core.crypto.SecureHash import com.r3corda.core.crypto.generateKeyPair import com.r3corda.core.crypto.sha256 import com.r3corda.core.messaging.MessagingService +import com.r3corda.core.messaging.SingleMessageRecipient +import com.r3corda.core.node.NodeInfo import com.r3corda.core.node.ServiceHub import com.r3corda.core.node.services.* import com.r3corda.core.protocols.ProtocolLogic @@ -52,7 +54,7 @@ open class MockServices(val key: KeyPair = generateKeyPair()) : ServiceHub { } } - override val storageService: TxWritableStorageService = MockStorageService(myLegalIdentityKey = key) + override val storageService: TxWritableStorageService = MockStorageService() override val identityService: MockIdentityService = MockIdentityService(listOf(MEGA_CORP, MINI_CORP, DUMMY_NOTARY)) override val keyManagementService: MockKeyManagementService = MockKeyManagementService(key) @@ -61,6 +63,7 @@ open class MockServices(val key: KeyPair = generateKeyPair()) : ServiceHub { override val networkMapCache: NetworkMapCache get() = throw UnsupportedOperationException() override val clock: Clock get() = throw UnsupportedOperationException() override val schedulerService: SchedulerService get() = throw UnsupportedOperationException() + override val myInfo: NodeInfo get() = NodeInfo(object : SingleMessageRecipient {} , Party("MegaCorp", key.public)) } @ThreadSafe @@ -150,8 +153,6 @@ open class MockTransactionStorage : TransactionStorage { @ThreadSafe class MockStorageService(override val attachments: AttachmentStorage = MockAttachmentStorage(), override val validatedTransactions: TransactionStorage = MockTransactionStorage(), - override val myLegalIdentityKey: KeyPair = generateKeyPair(), - override val myLegalIdentity: Party = Party("Unit test party", myLegalIdentityKey.public), override val stateMachineRecordedTransactionMapping: StateMachineRecordedTransactionMappingStorage = MockStateMachineRecordedTransactionMappingStorage()) : SingletonSerializeAsToken(), TxWritableStorageService